void RegionStat::update_stat() { //------ save useful constant info ------// int regionId = region_id; RegionPath reachableRegionArray[MAX_REACHABLE_REGION_PER_STAT]; char reachableRegionCount = reachable_region_count; err_when( sizeof(reachable_region_array) != sizeof(reachableRegionArray) ); memcpy( reachableRegionArray, reachable_region_array, sizeof(reachable_region_array) ); memset( this, 0, sizeof(RegionStat) ); // reset all data region_id = regionId; reachable_region_count = reachableRegionCount; memcpy( reachable_region_array, reachableRegionArray, sizeof(reachable_region_array) ); //--------- update firm stat ---------// Firm* firmPtr; int i; for( i=firm_array.size() ; i>0 ; i-- ) { if( firm_array.is_deleted(i) ) continue; firmPtr = firm_array[i]; if( firmPtr->region_id != region_id ) continue; if( firmPtr->nation_recno==0 ) // monster firms continue; err_when( firmPtr->firm_id < 1 || firmPtr->firm_id > MAX_FIRM_TYPE ); err_when( firmPtr->nation_recno < 1 || firmPtr->nation_recno > MAX_NATION ); firm_type_count_array[firmPtr->firm_id-1]++; firm_nation_count_array[firmPtr->nation_recno-1]++; total_firm_count++; if( firmPtr->firm_id == FIRM_CAMP ) camp_nation_count_array[firmPtr->nation_recno-1]++; if( firmPtr->firm_id == FIRM_HARBOR ) harbor_nation_count_array[firmPtr->nation_recno-1]++; if( firmPtr->firm_id == FIRM_MINE ) mine_nation_count_array[firmPtr->nation_recno-1]++; } //--------- update town stat ---------// Town* townPtr; for( i=town_array.size() ; i>0 ; i-- ) { if( town_array.is_deleted(i) ) continue; townPtr = town_array[i]; if( townPtr->region_id != region_id ) continue; if( townPtr->nation_recno ) { err_when( townPtr->nation_recno < 1 || townPtr->nation_recno > MAX_NATION ); town_nation_count_array[townPtr->nation_recno-1]++; if( townPtr->is_base_town ) base_town_nation_count_array[townPtr->nation_recno-1]++; nation_population_array[townPtr->nation_recno-1] += townPtr->population; nation_jobless_population_array[townPtr->nation_recno-1] += townPtr->jobless_population; } else independent_town_count++; total_town_count++; } //--------- update unit stat ---------// Unit* unitPtr; for( i=unit_array.size() ; i>0 ; i-- ) { if( unit_array.is_deleted(i) ) continue; unitPtr = unit_array[i]; if( unitPtr->region_id() != region_id ) continue; if( unitPtr->nation_recno ) unit_nation_count_array[unitPtr->nation_recno-1]++; else independent_unit_count++; total_unit_count++; } //--------- update site count --------// Site* sitePtr; for( i=site_array.size() ; i>0 ; i-- ) { if( site_array.is_deleted(i) ) continue; sitePtr = site_array[i]; if( sitePtr->region_id != region_id ) continue; if( sitePtr->site_type == SITE_RAW ) raw_count++; site_count++; } //----- update each nation's presence on the region -----// for( i=0 ; i<nation_array.size() ; i++ ) { if( nation_array.is_deleted(i+1) ) continue; if( firm_nation_count_array[i] > 0 || town_nation_count_array[i] > 0 || unit_nation_count_array[i] > 0 ) { nation_is_present_array[i] = 1; nation_presence_count++; } } }
//------------ Begin of function Tutor::load -------------// // // <int> tutorId - id. of the tutorial // void Tutor::load(int tutorId) { cur_tutor_id = tutorId; //------- get the tutor msgs from the resource file -------// int dataSize; File* filePtr = res_tutor_text.get_file( tutor[tutorId]->code, dataSize); if( !filePtr ) // if error getting the tutor resource { err_here(); return; } //------ Open the file and allocate buffer -----// FileTxt fileTxt( filePtr, dataSize ); // initialize fileTxt with an existing file stream if( dataSize > tutor_text_buf_size ) { tutor_text_buf = mem_resize( tutor_text_buf, dataSize ); // allocate a buffer larger than we need for the largest size possible tutor_text_buf_size = dataSize; } //-------- read in tutor info one by one --------// TutorTextBlock* tutorTextBlock = text_block_array; char* textPtr = tutor_text_buf; int readLen, totalReadLen=0; // total length of text read into the tutor_text_buf int loopCount=0; char* tokenStr; text_block_count=0; fileTxt.next_line(); // by pass the first two lines of file description fileTxt.next_line(); while( !fileTxt.is_eof() ) { err_when( loopCount++ > 10000 ); tokenStr = fileTxt.get_token(0); // don't advance the pointer if( !tokenStr ) break; //------ read in the display button code of the tutorial segment -------// if( strcmpi( tokenStr, "Button" ) == 0 ) { fileTxt.get_token(1); // advance the pointer tokenStr = fileTxt.get_token(1); strncpy( tutorTextBlock->button_code, tokenStr, tutorTextBlock->BUTTON_CODE_LEN ); tutorTextBlock->button_code[tutorTextBlock->BUTTON_CODE_LEN] = '\0'; } else { tutorTextBlock->button_code[0] = '\0'; } //------- read in the tutorial text -------// readLen = fileTxt.read_paragraph(textPtr, tutor_text_buf_size-totalReadLen); tutorTextBlock->text_ptr = textPtr; tutorTextBlock->text_len = readLen; textPtr += readLen; totalReadLen += readLen; err_when( totalReadLen>tutor_text_buf_size ); //----------- next tutor block -------------// fileTxt.next_line(); // pass the page break line text_block_count++; tutorTextBlock++; err_when( text_block_count >= MAX_TUTOR_TEXT_BLOCK ); } cur_text_block_id = 1; last_text_block_id = 0; }
//--------- Begin of function FirmWar::disp_build_menu ---------// // void FirmWar::disp_build_menu(int refreshFlag) { int x1 = INFO_X1+13; int y1 = INFO_Y1+5; vga.active_buf->put_bitmap( INFO_X1, INFO_Y1, image_gameif.read("BLDGWEAP") ); if( refreshFlag == INFO_REPAINT ) { added_count=0; } int b = 0; TechClass *techClass = tech_res.tech_class(war_tech_class); // war_tech_class is set the which tech class of weapon to build // int x=INFO_X1+2, y=INFO_Y1; for( int techId = techClass->first_tech_id; techId<techClass->first_tech_id+techClass->tech_count; ++techId ) { short unitId = tech_res[techId]->unit_id; if( !unitId ) continue; UnitInfo* unitInfo = unit_res[unitId]; if( unitInfo->unit_class != UNIT_CLASS_WEAPON ) continue; if( refreshFlag == INFO_REPAINT ) { err_when( b != added_count); button_queue_weapon[added_count].create(x1+20, y1+5, x1+49, y1+34, i_disp_queue_button, ButtonCustomPara(this, unitId) ); button_queue_weapon[added_count].set_help_code( "WEAPNUM" ); button_weapon[added_count].create(x1, y1+35, x1+67, y1+114, i_disp_build_button, ButtonCustomPara(&button_queue_weapon[added_count], unitId) ); added_count++; x1 += 68; if (added_count == 3) { x1 = INFO_X1+13; y1 = INFO_Y1+121; } err_when(added_count > MAX_WEAPON_TYPE); } if( unitInfo->get_nation_tech_level(nation_recno) > 0 ) button_queue_weapon[b].visible_flag = button_weapon[b].visible_flag = 1; else button_queue_weapon[b].visible_flag = button_weapon[b].visible_flag = 0; button_queue_weapon[b].paint(); button_weapon[b].paint(); ++b; } if( refreshFlag==INFO_REPAINT ) { // ##### begin Gilbert 8/2 ######// int x1 = INFO_X1 +13 +BUTTON_DISTANCE*3; int y1 = INFO_Y1 +281; // button_cancel.create( x1+7, y1+9, "OK-U", "OK-D" ); button_cancel.create( x1, y1, 'A', "CANCEL" ); // ##### end Gilbert 8/2 ######// } button_cancel.paint(); }
//--------- Begin of function FirmCamp::disp_camp_info ---------// // void FirmCamp::disp_camp_info(int dispY1, int refreshFlag) { if( is_own() ) { int x1 = INFO_X1 +13; int y1 = INFO_Y1 +235; int x2 = INFO_X1 +13; int y2 = INFO_Y1 +281; if( refreshFlag==INFO_REPAINT ) { // ##### begin Gilbert 31/12 #######// // button_patrol.create( INFO_X1+13, INFO_Y1+235, 'A', "PATROL" ); // button_reward.create( INFO_X1+13+BUTTON_DISTANCE, INFO_Y1+235, 'A', "REWARDCB" ); // button_defense.create( INFO_X1+13+2*BUTTON_DISTANCE, INFO_Y1+235, 'A', defense_flag ? "DEFENSE1" : "DEFENSE0" ); if (!is_monster()) button_patrol.create( INFO_X1+13+BUTTON_DISTANCE, INFO_Y1+281, 'A', "PATROL" ); else button_patrol.create( INFO_X1+13+BUTTON_DISTANCE, INFO_Y1+281, 'A', "F_PATROL" ); if (!is_monster()) button_reward.create( INFO_X1+13, INFO_Y1+235, 'A', "REWARD" ); else button_reward.create( INFO_X1+13, INFO_Y1+235, 'A', "F_REWARD" ); if (!is_monster()) button_defense.create( INFO_X1+13+2*BUTTON_DISTANCE, INFO_Y1+281, 'A', defense_flag ? "DEFENSE1" : "DEFENSE0" ); else button_defense.create( INFO_X1+13+2*BUTTON_DISTANCE, INFO_Y1+281, 'A', defense_flag ? "F_DEFEN1" : "F_DEFEN0" ); if (!is_monster()) button_promote.create( INFO_X1+13+2*BUTTON_DISTANCE , INFO_Y1+235, 'A', "PROMOTE" ); else button_promote.create( INFO_X1+13+2*BUTTON_DISTANCE , INFO_Y1+235, 'A', "F_PROMOT" ); // ##### end Gilbert 31/12 #######// } if( overseer_recno ) { button_patrol.enable_flag = 1; } else { for( int i = 0; i < soldier_count && soldier_array[i].is_under_training(); ++i ); button_patrol.enable_flag = i < soldier_count; } String str; switch(patrol_state) { case PATROL_ALL: // str = "Sortie All"; str = ""; break; case PATROL_NO_GENERAL: str = "Sortie No Leader"; break; case PATROL_NO_INJURED_SOILDER: str = "Sortie No Injured"; break; default: break; } button_patrol.paint(); // vga.active_buf->bar_alpha( button_patrol.x1, button_patrol.y1+15, button_patrol.x1+BUTTON_ACTION_WIDTH-1, button_patrol.y1+BUTTON_ACTION_HEIGHT-16, 1, 0 ); font_whbl.center_put_paragraph( button_patrol.x1, button_patrol.y1, button_patrol.x1+BUTTON_ACTION_WIDTH-1, button_patrol.y1+BUTTON_ACTION_HEIGHT-1, str ); // ###### begin Gilbert 15/4 ########// if( nation_array[nation_recno]->cash >= REWARD_COST && ( (overseer_recno && unit_array[overseer_recno]->rank_id != RANK_KING && unit_res[unit_array[overseer_recno]->unit_id]->class_info.has_loyalty) || (selected_soldier_id && selected_soldier_id <= soldier_count && unit_res[soldier_array[selected_soldier_id-1].unit_id]->class_info.has_loyalty)) ) button_reward.enable_flag = 1; // call paint // ###### end Gilbert 15/4 ########// else button_reward.enable_flag = 0; // call paint button_reward.paint(); if (!is_monster()) button_defense.update_bitmap( defense_flag ? "DEFENSE1" : "DEFENSE0" ); // call paint else button_defense.update_bitmap( defense_flag ? "F_DEFEN1" : "F_DEFEN0" ); if( (button_promote.visible_flag = !overseer_recno) ) { button_promote.enable_flag = 0; if( selected_soldier_id > 0 && selected_soldier_id <= soldier_count ) { Soldier *soldierPtr = soldier_array + selected_soldier_id - 1; // ##### begin Gilbert 24/3 ######// err_when( soldierPtr->unit_id == UNIT_WAGON ); if( soldierPtr->race_id != 0 && soldierPtr->rank_id == RANK_SOLDIER && !soldierPtr->is_under_training() && soldierPtr->skill_level() > 0 ) // ##### end Gilbert 24/3 ######// { button_promote.enable_flag = 1; } } button_promote.paint(); } } disp_spy_button( INFO_X1+13+BUTTON_DISTANCE, INFO_Y1+281, refreshFlag); }
//--------- Begin of function FirmCamp::put_info ---------// // void FirmCamp::put_info(int refreshFlag) { // ##### begin Gilbert 21/9 ######// if( refreshFlag == INFO_REPAINT ) { last_menu_mode = firm_menu_mode = FIRM_MENU_MAIN; disp_combat_or_skill = 0; // display combat } // ##### end Gilbert 21/9 ######// else { if( last_menu_mode != firm_menu_mode ) // if changing menu mode pass repaint to sub-menu { refreshFlag = INFO_REPAINT; last_menu_mode = firm_menu_mode; } } Firm::put_info(refreshFlag); switch( firm_menu_mode ) { case FIRM_MENU_MAIN: if( should_show_info() ) { vga.active_buf->put_bitmap( INFO_X1, INFO_Y1, image_gameif.read("FORTBASE") ); disp_camp_info(INFO_Y1, refreshFlag); Firm *firmPtr = firm_array[firm_recno]; if( firm_id == FIRM_CAMP ) disp_camp_upgrade(INFO_Y1, refreshFlag); disp_soldier_list(INFO_Y1, refreshFlag, 0); disp_soldier_info(INFO_Y1+178, refreshFlag); // disp_debug_info(this, refreshFlag); } break; case FIRM_MENU_TRAIN: vga.active_buf->put_bitmap( INFO_X1, INFO_Y1, image_gameif.read("FORTBASE") ); disp_train_menu(refreshFlag); break; case FIRM_MENU_SPY: case FIRM_MENU_SELECT_BRIBER: vga.active_buf->put_bitmap( INFO_X1, INFO_Y1, image_gameif.read("FORTBASE") ); disp_spy_menu(refreshFlag); break; case FIRM_MENU_SET_BRIBE_AMOUNT: // vga.active_buf->put_bitmap( INFO_X1, INFO_Y1, image_gameif.read("FORTBASE") ); vga.active_buf->put_bitmap( INFO_X1, INFO_Y1, image_gameif.read("BLDGBASE") ); disp_bribe_menu(refreshFlag); break; case FIRM_MENU_BRIBE_RESULT: // vga.active_buf->put_bitmap( INFO_X1, INFO_Y1, image_gameif.read("FORTBASE") ); vga.active_buf->put_bitmap( INFO_X1, INFO_Y1, image_gameif.read("BLDGBASE") ); disp_bribe_result(refreshFlag); break; case FIRM_MENU_VIEW_SECRET: spy_array.disp_view_secret_menu(action_spy_recno, refreshFlag); break; case FIRM_MENU_ASSASSINATE_CONFIRM: vga.active_buf->put_bitmap( INFO_X1, INFO_Y1, image_gameif.read("BLDGBASE") ); disp_assassinate_confirm(refreshFlag); break; case FIRM_MENU_ASSASSINATE_RESULT: vga.active_buf->put_bitmap( INFO_X1, INFO_Y1, image_gameif.read("BLDGBASE") ); disp_assassinate_result(refreshFlag); break; case FIRM_MENU_STEAL_TECH_CONFIRM: vga.active_buf->put_bitmap( INFO_X1, INFO_Y1, image_gameif.read("BLDGBASE") ); disp_steal_tech_confirm(refreshFlag); break; case FIRM_MENU_STEAL_TECH_RESULT: vga.active_buf->put_bitmap( INFO_X1, INFO_Y1, image_gameif.read("BLDGBASE") ); disp_steal_tech_result(refreshFlag); break; case FIRM_MENU_INCIDENT_NATION: vga.active_buf->put_bitmap( INFO_X1, INFO_Y1, image_gameif.read("BLDGBASE") ); disp_incident_nation(refreshFlag); break; case FIRM_MENU_INCIDENT_CONFIRM: vga.active_buf->put_bitmap( INFO_X1, INFO_Y1, image_gameif.read("BLDGBASE") ); disp_incident_confirm(refreshFlag); break; case FIRM_MENU_INCIDENT_RESULT: vga.active_buf->put_bitmap( INFO_X1, INFO_Y1, image_gameif.read("BLDGBASE") ); disp_incident_result(refreshFlag); break; default: err_when( firm_menu_mode < FIRM_MENU_CAMP_LAST ); // if firm_menu_mode >= FIRM_MENU_CAMP_LAST, handled by sub-class } }
//--------- Begin of function Firm::spy_birbe_succeed_chance ---------// // // The money the spy offers to bribe the unit. // // <int> bribeAmount - the amount offered // <short> birberSpyRecno - spy recno of the briber // <short> workerId - if 0, then bribe the overseer, // if >0, then bribe a worker. // // return: <int> 1 - bribing succeeded // 0 - bribing failed // int Firm::spy_bribe_succeed_chance(int bribeAmount, short briberSpyRecno, short workerId) { Spy* spyPtr = spy_array[briberSpyRecno]; err_when( spyPtr->spy_place != SPY_FIRM ); err_when( spyPtr->spy_place_para != firm_recno ); //---- if the bribing target is a worker ----// int unitLoyalty, unitRaceId, targetSpyRecno, unitCommandPower; if( workerId ) { Worker* workerPtr = worker_array+workerId-1; unitLoyalty = workerPtr->loyalty(); unitRaceId = workerPtr->race_id; unitCommandPower = 0; targetSpyRecno = workerPtr->spy_recno; } else if( overseer_recno ) { Unit* unitPtr = unit_array[overseer_recno]; unitLoyalty = unitPtr->loyalty; unitRaceId = unitPtr->race_id; unitCommandPower = unitPtr->commander_power(); targetSpyRecno = unitPtr->spy_recno; } else err_here(); err_when( unitRaceId < 1 || unitRaceId > MAX_RACE ); //---- determine whether the bribe will be successful ----// int succeedChance; if( targetSpyRecno ) // if the bribe target is also a spy { err_when( spy_array[targetSpyRecno]->true_nation_recno == spyPtr->true_nation_recno ); // the player shouldn't be able to bribe units of his own succeedChance = 0; } else { succeedChance = spyPtr->spy_skill - unitLoyalty - unitCommandPower + (int) nation_array[spyPtr->true_nation_recno]->reputation + 200 * bribeAmount / MAX_BRIBE_AMOUNT; //-- the chance is higher if the spy or the spy's king is racially homongenous to the bribe target, int spyKingRaceId = nation_array[ spyPtr->true_nation_recno ]->race_id; succeedChance += race_res.is_same_race(spyPtr->race_id, unitRaceId) * 10 + race_res.is_same_race(spyKingRaceId, unitRaceId) * 10; if( unitLoyalty > 60 ) // harder for bribe units with over 60 loyalty succeedChance -= (unitLoyalty-60); if( unitLoyalty > 70 ) // harder for bribe units with over 70 loyalty succeedChance -= (unitLoyalty-70); if( unitLoyalty > 80 ) // harder for bribe units with over 80 loyalty succeedChance -= (unitLoyalty-80); if( unitLoyalty > 90 ) // harder for bribe units with over 90 loyalty succeedChance -= (unitLoyalty-90); if( unitLoyalty == 100 ) succeedChance = 0; } return succeedChance; }
//--------- Begin of function FirmCamp::disp_overseer_info ---------// // void FirmCamp::disp_overseer_info(int dispY1, int refreshFlag) { disp_soldier_info_y1 = dispY1; if( !overseer_recno ) return; Unit* unitPtr = unit_array[overseer_recno]; UnitInfo *unitInfo = unit_res[unitPtr->unit_id]; int x=INFO_X1+20, y=dispY1; int x2; // --- display name_id, can spot spy ----- // String str; str = unitPtr->unit_name(); str += " ("; if( unitPtr->is_human() ) str += race_res[unitPtr->race_id]->name; else str += monster_res[unitPtr->monster_id()]->name; str += ")"; font_snds.put( x, y, str, 0, INFO_X2-8, 1 ); // line spacing 24 // ------- display loyalty ---------// if( unitInfo->class_info.has_loyalty && unitPtr->rank_id != RANK_KING && unitPtr->nation_recno ) { err_when( unitPtr->unit_id == UNIT_WAGON ); if (unitPtr->loyalty != unitPtr->target_loyalty) info.disp_loyalty( x, y+12, INFO_X2-99 - font_snds.text_width(m.format(unitPtr->loyalty, 4)) - font_snds.text_width(m.format(unitPtr->target_loyalty, 4)) - font_snds.text_width("11"), unitPtr->loyalty, unitPtr->target_loyalty, nation_recno, refreshFlag, disp_combat_or_skill==4 ); else info.disp_loyalty( x, y+12, INFO_X2-99 - font_snds.text_width(m.format(unitPtr->loyalty, 4)), unitPtr->loyalty, unitPtr->target_loyalty, nation_recno, refreshFlag, disp_combat_or_skill==4 ); } // ------- display combat ----------// if( unitInfo->class_info.has_combat_level ) { x2 = (disp_combat_or_skill==1?font_blu2:font_snds).put( x+110, y+12, "Combat" ) + 10; font_snds.right_put( INFO_X2-10, y+12, m.format(unitPtr->combat_level(),4) ); } // ------- display leadership -------// if( unitInfo->class_info.has_skill_level && unitPtr->skill_level() > 0 ) { x2 = (disp_combat_or_skill==2?font_blu2:font_snds).put( x+110, y+26, "Leadership" ) + 10; font_snds.right_put( INFO_X2-10, y+26, m.format(unitPtr->skill_level(),4) ); } // ----- display hit point ---------// x2 = font_snds.put( x, y+26, "Hit Points" ) + 10; str = m.format((int)unitPtr->hit_points, 4); str += "/"; str += m.format(unitPtr->max_hit_points(), 4); font_snds.right_put( INFO_X2-100, y+26, str ); }
//------- Begin of function Firm::change_nation ---------// // void Firm::change_nation(int newNationRecno) { if( nation_recno == newNationRecno ) return; //---------- stop all attack actions to this firm ----------// unit_array.stop_attack_obj(base_obj_recno); rebel_array.stop_attack_firm(firm_recno); Nation *oldNationPtr = NULL; Nation *newNationPtr = NULL; if( nation_recno ) oldNationPtr = nation_array[nation_recno]; if( newNationRecno ) newNationPtr = nation_array[newNationRecno]; //------ if there is a builder in this firm, change its nation also ----// if( builder_recno ) { Unit* unitPtr = unit_array[builder_recno]; unitPtr->change_nation(newNationRecno); //--- if this is a spy, chance its cloak ----// if( unitPtr->spy_recno ) spy_array[unitPtr->spy_recno]->cloaked_nation_recno = newNationRecno; } //---------- stop all actions attacking this firm --------// unit_array.stop_attack_obj(base_obj_recno); //---- update nation_unit_count_array[] ----// FirmInfo* firmInfo = firm_res[firm_id]; if( nation_recno ) firmInfo->dec_nation_firm_count(nation_recno); if( newNationRecno ) firmInfo->inc_nation_firm_count(newNationRecno); //---- reset should_close_flag -----// if( is_ai ) { if( should_close_flag ) { if( oldNationPtr ) { oldNationPtr->firm_should_close_array[firm_id-1]--; err_when( oldNationPtr->firm_should_close_array[firm_id-1] < 0 ); } should_close_flag = 0; } } //------- update player_spy_count -------// spy_array.update_firm_spy_count(firm_recno); //--- update the cloaked_nation_recno of all spies in the firm ---// spy_array.change_cloaked_nation(SPY_FIRM, firm_recno, nation_recno, newNationRecno); // check the cloaked nation recno of all spies in the firm //-----------------------------------------// if( oldNationPtr ) oldNationPtr->del_firm_info(firm_id, firm_recno); //------ update power nation recno ----------// if( should_set_power ) world.restore_power(loc_x1, loc_y1, loc_x2, loc_y2, 0, firm_recno); should_set_power = get_should_set_power(); if( should_set_power ) world.set_power(loc_x1, loc_y1, loc_x2, loc_y2, newNationRecno); // set power of the new nation //------------ update link --------------// release_link(); // need to update link because firms are only linked to firms of the same nation nation_recno = newNationRecno; setup_link(); //---------------------------------------// if (!newNationRecno) is_ai = 1; else { is_ai = nation_array[nation_recno]->is_ai(); newNationPtr->add_firm_info(firm_id, firm_recno); } //--- if a nation set up a town in a location that the player has explored, contact between the nation and the player is established ---// establish_contact_with_player(); //---- reset the action mode of all spies in this town ----// spy_array.set_action_mode( SPY_FIRM, firm_recno, SPY_IDLE ); // we need to reset it. e.g. when we have captured an enemy town, SPY_SOW_DISSENT action must be reset to SPY_IDLE //-- refresh display if this firm is currently selected --// if( firm_array.selected_recno == firm_recno ) info.disp(); // ####### begin Gilbert 5/7 ########// if( explore_for_player() ) { world.unveil( loc_x1, loc_y1, loc_x2, loc_y2 ); world.visit( loc_x1, loc_y1, loc_x2, loc_y2, EXPLORE_RANGE-1 ); } // ####### end Gilbert 5/7 ########// }
//--------- Begin of function Firm::deinit --------// // void Firm::deinit() { if( !firm_recno ) // already deleted return; if( power.command_firm_recno == firm_recno ) power.reset_command(); // ##### begin Gilbert 30/10 ######// // mem_del(firm_cur_frame); // firm_cur_frame = NULL; // mem_del(firm_remain_frame_delay); // firm_remain_frame_delay = NULL; // ##### end Gilbert 30/10 ######// is_being_deleted = 1; // whether the place is currently being deleted, if it is set to true, some functions will be executed in an exceptional way, it is set in deinit() Place::deinit(); // parent class deinit() deinit_derived(); //------- delete AI info ----------// if( nation_recno ) { Nation* nationPtr = nation_array[nation_recno]; nationPtr->del_firm_info(firm_id, firm_recno); if(is_ai) { if( should_close_flag ) nationPtr->firm_should_close_array[firm_id-1]--; err_when( nationPtr->firm_should_close_array[firm_id-1] < 0 ); } } //--------- clean up related stuff -----------// restore_world_matrix(); release_link(); //-------- dynamic unloading of firm bitmaps ---------// FirmBuild* firmBuild = firm_res.get_build(firm_build_id); firmBuild->free_bitmap_res(); //------ all workers and the overseer resign ------// if( !sys.signal_exit_flag ) { // char* name1 = "Wilde Lishorr"; // char* name2 = "Lishorr"; // if( !under_construction && hit_points < 1 && strcmp(name1, firm_name()) && strcmp(name2, firm_name()) ) if( !under_construction && hit_points < 1 ) { // -------- create a firm die record ------// // can be called as soon as restore_world_matrix static int effectId = sprite_res.search_sprite( "FIRE_EFF" ); err_when( !effectId ); Effect::create(effectId, loc_x1 *LOCATE_WIDTH, loc_y1 *LOCATE_HEIGHT, SPRITE_IDLE, 1, 8, 0); FirmDie firmDie3; if (firmBuild->loc_width == 3 && firmBuild->loc_height == 3) firmDie3.init(this, 6); else if (firmBuild->loc_width == 6 && firmBuild->loc_height == 6) firmDie3.init(this, 5); else firmDie3.init(this, 4); firm_die_array.add(&firmDie3); } } free_all_people(); //--------- decrease firm counter -----------// if( nation_recno ) nation_array[nation_recno]->nation_firm_count--; //------ update firm counter -------// FirmInfo* firmInfo = firm_res[firm_id]; firmInfo->total_firm_count--; if( nation_recno ) firmInfo->dec_nation_firm_count(nation_recno); //------- update town border ---------// loc_x1 = -1; // mark deleted //------- if the current firm is the selected -----// if( firm_array.selected_recno == firm_recno ) { firm_array.selected_recno = 0; info.disp(); } //-------------------------------------------------// firm_recno = 0; is_being_deleted = 0; //-------- dynamic unloading of firm bitmaps ---------// // FirmBuild* firmBuild = firm_res.get_build(firm_build_id); if( firm_id ) { // firmBuild->free_bitmap_res(); firm_id = 0; } }
//---------- Begin of function Game::scenario_editor_menu ----------// // void Game::scenario_editor_menu() { int refreshFlag = SPOPTION_ALL; mouse_cursor.set_icon(CURSOR_NORMAL); { VgaFrontLock vgaLock; while(1) { #if 0 // FIXME MSG msg; if (PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE)) { if (!GetMessage( &msg, NULL, 0, 0)) { sys.signal_exit_flag = 1; // BUGHERE : vga_front is unlocked return; } TranslateMessage(&msg); DispatchMessage(&msg); continue; } else if( sys.paused_flag || !sys.active_flag ) { WaitMessage(); continue; } #endif if( sys.need_redraw_flag ) { refreshFlag = SPOPTION_ALL; sys.need_redraw_flag = 0; } VgaFrontReLock vgaReLock; // -------- display ----------// if( refreshFlag ) { if( refreshFlag & SPOPTION_PAGE ) { vga.use_back(); vga_util.disp_image_file("M_MAIN"); // ------ display button ------// font_thin_black.center_put_paragraph( BUTTON2_X1, BUTTON2_Y1, BUTTON2_X2, BUTTON2_Y2, text_game_menu.str_new_game(), 0 ); font_thin_black.center_put_paragraph( BUTTON4_X1, BUTTON4_Y1, BUTTON4_X2, BUTTON4_Y2, text_game_menu.str_load_game(), 0 ); font_thin_black.center_put_paragraph( BUTTON8_X1, BUTTON8_Y1, BUTTON8_X2, BUTTON8_Y2, text_game_menu.str_cancel(), 0 ); vga_util.blt_buf( 0, 0, VGA_WIDTH-1, VGA_HEIGHT-1, 0 ); vga.use_front(); } refreshFlag = 0; } sys.blt_virtual_buf(); // blt the virtual front buffer to the screen sys.yield(); mouse.get_event(); if( config.music_flag ) { if( !music.is_playing(3) ) music.play(3, sys.cdrom_drive ? MUSIC_CD_THEN_WAV : 0 ); } else { music.stop(); } // --------- detect -------// // detect new if( mouse.single_click( BUTTON2_X1, BUTTON2_Y1, BUTTON2_X2, BUTTON2_Y2) ) { game_file_array.init( DIR_SCENARIO, "*.SCN" ); // necessary to set the path and extension single_player_game(0); break; } // detect load game else if( mouse.single_click( BUTTON4_X1, BUTTON4_Y1, BUTTON4_X2, BUTTON4_Y2) ) { err_when( MAX_SCENARIO_PATH <= 1 ); game_file_array.init( DIR_SCENARIO, "*.SCN" ); // necessary to set the path and extension // ##### begin Gilbert 20/1 #######// // if( game_file_array.menu(2) == 1) if( game_file_array.menu(3) == 1) // ##### begin Gilbert 20/1 #######// { battle.run_loaded(); // ###### begin Gilbert 22/3 ######// deinit_all(); // ###### end Gilbert 22/3 ######// } { char signalExitFlagBackup = sys.signal_exit_flag; sys.signal_exit_flag = 2; game.deinit(); // game.deinit() is needed if game_file_array.menu fails sys.signal_exit_flag = signalExitFlagBackup; } break; } // cancel else if( mouse.single_click(BUTTON8_X1, BUTTON8_Y1, BUTTON8_X2, BUTTON8_Y2) ) { break; } } // end while } // end scope of vgaLock }
//--------- Begin of function Firm::init --------// // // It will initialize vars, and set the world matrix. // Before calling init(), firm_recno should be set // // Note : it will set world matrix regardless the existing location content, // so you must ensure that the location is clean by calling // world.zoom_matrix->add_firm_test() // // <int> xLoc, yLoc = the location of firm in the world map // <int> nationRecno = the recno of nation which build this firm // <int> firmId = id(type) of the firm // [char*] buildCode = the build code of the firm, no need to give if the firm just have one build type // [short] builderRecno = recno of the builder unit // void Firm::init(int xLoc, int yLoc, int nationRecno, int firmId, char* buildCode, short builderRecno) { FirmInfo* firmInfo = firm_res[firmId]; firm_id = firmId; if( buildCode ) firm_build_id = firmInfo->get_build_id(buildCode); if( !buildCode || !firm_build_id ) // some buildings like human offensive structures do not have different buildings for different nationality, so firm_build_id will be 0 firm_build_id = firmInfo->first_build_id; //----------- set vars -------------// nation_recno = nationRecno; setup_date = info.game_date; //----- set the firm's absolute positions on the map -----// FirmBuild* firmBuild = firm_res.get_build(firm_build_id); FirmBitmap* firmBitmap; race_id = firmInfo->get_race_id(buildCode); if( !race_id ) // some firms like human offensive structures do not have race_id. race_id = nation_array[nation_recno]->race_id; err_when( is_human() == (firmId >= FIRM_LAIR && firmId <= FIRM_MAGIC) ); // error when a human attempts to build a monster firm or a mosnter attempts to build a human firm loc_x1 = xLoc; loc_y1 = yLoc; loc_x2 = loc_x1 + firmBuild->loc_width - 1; loc_y2 = loc_y1 + firmBuild->loc_height - 1; center_x = (loc_x1 + loc_x2) / 2; center_y = (loc_y1 + loc_y2) / 2; region_id = world.get_region_id( center_x, center_y ); // get the height of the top left corner // altitude = world.get_corner(xLoc, yLoc)->get_altitude(); altitude = world.get_corner(loc_x2+1, loc_y2+1)->get_altitude(); abs_x1 = world.zoom_matrix->calc_abs_x(xLoc * LOCATE_WIDTH, yLoc * LOCATE_HEIGHT, altitude) + firmBuild->min_offset_x; abs_y1 = world.zoom_matrix->calc_abs_y(xLoc * LOCATE_WIDTH, yLoc * LOCATE_HEIGHT, altitude) + firmBuild->min_offset_y; abs_x2 = abs_x1 + firmBuild->max_bitmap_width - 1; abs_y2 = abs_y1 + firmBuild->max_bitmap_height - 1; //--------- set animation frame vars ---------// int bitmapCount; int firstBitmap; int frameCount = firmBuild->frame_count; int aniPartCount = firmBuild->ani_part_count; // ##### begin Gilbert 30/10 ######// err_when( aniPartCount < 0 ); err_when( aniPartCount > MAX_FRAME_COUNTERS ); // firm_cur_frame = (char*) mem_add( sizeof(char) *aniPartCount); // firm_remain_frame_delay = (char*) mem_add( sizeof(char) *aniPartCount); // ##### end Gilbert 30/10 ######// // even not animation_full_size will have aniPartCount = 1 (set in firmres.cpp) for (int i = 0; i < aniPartCount ; i++) { firm_cur_frame[i] = 1; if( firmBuild->animate_full_size ) // animate_full_size only supports animation of looping // it does not support random animation and in fact // it is now only used for no animation buildings firm_remain_frame_delay[i] = (char) firmBuild->frame_delay(1); else { // not animate_full_size supports animation of looping and // random animation and partial animation // unlike the animate_full_size animation, it search starting // from the 2nd frame for bitmaps (since now 1 frame may has more // than 1 bitmap) with same animation part no. of the currently // searching part no., i. Then assign this animation part's delay and // set its current_frame to the first found frame for ( int k=1; k <frameCount; k++ ) { firstBitmap = firmBuild->first_bitmap(k+1); bitmapCount = firmBuild->bitmap_count(k+1); int j; for ( j=0; j <bitmapCount; j++ ) { firmBitmap = firm_res.get_bitmap(firstBitmap + j); if( firmBitmap ) { if (firmBitmap->ani_part == (i + 1)) { firm_remain_frame_delay[i] = firmBitmap->delay; firm_cur_frame[i] = k + 1; break; } } } if (j < bitmapCount) break; } } } //--------- initialize gaming vars ----------// hit_points = (float) 0; place_max_hit_points = firmInfo->max_hit_points; // #### begin Gilbert 6/11 ######// defense_attribute = firmBuild->defense_attribute; // #### end Gilbert 6/11 ######// //------ set construction and builder -------// under_construction = firmInfo->buildable; // whether the firm is under construction, if the firm is not buildable it is completed in the first place if( !under_construction ) // if this firm doesn't been to be constructed, set its hit points to the maximum hit_points = place_max_hit_points; if( builderRecno ) set_builder(builderRecno); else builder_recno = 0; //------ update firm counter -------// firmInfo->total_firm_count++; if( nation_recno ) firmInfo->inc_nation_firm_count(nation_recno); //-------------------------------------------// if( nation_recno > 0 ) { Nation* nationPtr = nation_array[nation_recno]; is_ai = nationPtr->is_ai(); ai_processed = 1; //--------- increase firm counter -----------// nationPtr->nation_firm_count++; //-------- update last build date ------------// nationPtr->last_build_firm_date = info.game_date; } else { is_ai = 0; ai_processed = 0; } ai_status = FIRM_WITHOUT_ACTION; ai_link_checked = 1; // check the connected firms if ai_link_checked = 0; //--------------------------------------------// active_link_town_recno = 0; setup_link(); set_world_matrix(); init_name(); //----------- init AI -----------// if( nation_recno ) nation_array[nation_recno]->add_firm_info(firm_id, firm_recno); //-------- init derived ---------// init_derived(); // init_derived() before set_world_matrix() so that init_derived has access to the original land info. //-------- dynamic loading of firm bitmaps ---------// firmBuild->load_bitmap_res(); }
//#ifndef DISABLE_MULTI_PLAYER //---------- Begin of function Game::multi_player_menu ----------// // void Game::multi_player_menu(char *cmdLine) { mouse_cursor.set_icon(CURSOR_NORMAL); if( cmdLine != NULL && mp_obj.init_flag && mp_obj.is_lobbied() ) { // find player profile char* lobbiedName = mp_obj.get_lobbied_name(); // find profile with the same login name if( lobbiedName && player_profile.load_by_login_name(lobbiedName) ) { if( player_profile.mp_new_game_flag == 1 ) // new game { player_profile.mp_new_game_flag = 0; player_profile.save(); game_file_array.init( player_profile.save_game_path(NULL), "*.SVM" ); // necessary to set the path and extension multi_player_game(cmdLine); return; } else if ( player_profile.mp_new_game_flag == 2 ) // load game { player_profile.mp_new_game_flag = 0; // if load file is specified in the profile game_file_array.init( player_profile.save_game_path(NULL), "*.SVM" ); // necessary to set the path and extension char loadFileName[16]; if( player_profile.mp_load_file_name[0] ) { strcpy(loadFileName, player_profile.mp_load_file_name); strcat( loadFileName, ".SVM" ), // append extension player_profile.mp_load_file_name[0] = '\0'; } else { loadFileName[0] = '\0'; } player_profile.save(); if( loadFileName[0] && game_file.load_game(player_profile.save_game_path(NULL), loadFileName) ) { load_mp_game( loadFileName, cmdLine ); } else { // conventional choose load game int loadedRecno; if( game_file_array.menu(3, &loadedRecno) == 1 ) { err_when( !loadedRecno ); load_mp_game(game_file_array[loadedRecno]->file_name, cmdLine); } } { char signalExitFlagBackup = sys.signal_exit_flag; sys.signal_exit_flag = 2; game.deinit(); // game.deinit() is needed if game_file_array.menu fails sys.signal_exit_flag = signalExitFlagBackup; } return; } else { return; // quit // player_profile.mp_new_game_flag not specified // continue to interface } } // end if load by login name #ifdef DEBUG else { if( lobbiedName ) err.msg( "Cannot find profile" ); } #endif } // end if launchMode // char optionFlag[5] = { 1, 1, 1, 1, 1, }; int refreshFlag = SPOPTION_ALL; bool launchMode = (cmdLine != NULL); { VgaFrontLock vgaLock; while(1) { #if 0 // FIXME MSG msg; if (PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE)) { if (!GetMessage( &msg, NULL, 0, 0)) { sys.signal_exit_flag = 1; // BUGHERE : vga_front is unlocked return; } TranslateMessage(&msg); DispatchMessage(&msg); continue; } else if( sys.paused_flag || !sys.active_flag ) { WaitMessage(); continue; } #endif if( sys.need_redraw_flag ) { refreshFlag = SPOPTION_ALL; sys.need_redraw_flag = 0; } VgaFrontReLock vgaReLock; // -------- display ----------// if( refreshFlag ) { if( refreshFlag & SPOPTION_PAGE ) { vga.use_back(); vga_util.disp_image_file("M_MAIN"); // ------ display button ------// if( player_profile.is_registered() ) { font_thin_black.center_put_paragraph( BUTTON2_X1, BUTTON2_Y1, BUTTON2_X2, BUTTON2_Y2, text_game_menu.str_new_game(), 0 ); font_thin_black.center_put_paragraph( BUTTON4_X1, BUTTON4_Y1, BUTTON4_X2, BUTTON4_Y2, text_game_menu.str_load_game(), 0 ); } if( launchMode ) { font_thin_black.center_put_paragraph( BUTTON6_X1, BUTTON6_Y1, BUTTON6_X2, BUTTON6_Y2, text_game_menu.str_player_register(), 0); } // display quit in launch mode, // display cancel otherwise font_thin_black.center_put_paragraph( BUTTON8_X1, BUTTON8_Y1, BUTTON8_X2, BUTTON8_Y2, !launchMode ? text_game_menu.str_cancel() : text_game_menu.str_quit(), 0 ); vga_util.blt_buf( 0, 0, VGA_WIDTH-1, VGA_HEIGHT-1, 0 ); vga.use_front(); } refreshFlag = 0; } sys.blt_virtual_buf(); // blt the virtual front buffer to the screen sys.yield(); mouse.get_event(); if( config.music_flag ) { if( !music.is_playing(3) ) music.play(3, sys.cdrom_drive ? MUSIC_CD_THEN_WAV : 0 ); } else { music.stop(); } // --------- detect -------// // detect player register if( launchMode && mouse.single_click( BUTTON6_X1, BUTTON6_Y1, BUTTON6_X2, BUTTON6_Y2) ) { player_profile.register_menu(); if( player_profile.is_registered() ) { refreshFlag = SPOPTION_ALL; // to display new/load game button } } // detect new game else if( player_profile.is_registered() && mouse.single_click( BUTTON2_X1, BUTTON2_Y1, BUTTON2_X2, BUTTON2_Y2) ) { game_file_array.init( player_profile.save_game_path(NULL), "*.SVM" ); // necessary to set the path and extension multi_player_game(cmdLine); if (launchMode && !sys.signal_exit_flag ) { // if exit from main game, signal_exit_flag is non-zero // signal_exit_flag is zero usually means exit from multiplayer setup menu refreshFlag = SPOPTION_ALL; continue; } break; } // detect load game else if( player_profile.is_registered() && mouse.single_click( BUTTON4_X1, BUTTON4_Y1, BUTTON4_X2, BUTTON4_Y2) ) { int loadedRecno = 0; game_file_array.init( player_profile.save_game_path(NULL), "*.SVM" ); // necessary to set the path and extension // ##### begin Gilbert 20/1 #######// // if( game_file_array.menu(2, &loadedRecno) == 1 ) if( game_file_array.menu(3, &loadedRecno) == 1 ) // ##### begin Gilbert 20/1 #######// { err_when( !loadedRecno ); load_mp_game(game_file_array[loadedRecno]->file_name, cmdLine); } { char signalExitFlagBackup = sys.signal_exit_flag; sys.signal_exit_flag = 2; game.deinit(); // game.deinit() is needed if game_file_array.menu fails sys.signal_exit_flag = signalExitFlagBackup; if (launchMode && !sys.signal_exit_flag ) { // if exit from main game, signal_exit_flag is non-zero // signal_exit_flag is zero usually means exit from multiplayer setup menu refreshFlag = SPOPTION_ALL; continue; } } break; } // cancel else if( mouse.single_click(BUTTON8_X1, BUTTON8_Y1, BUTTON8_X2, BUTTON8_Y2) ) { break; } } // end while } // end scope of vgaLock }
//------- Begin of function FirmMarket::ai_create_new_trade ------// // int FirmMarket::ai_create_new_trade(Firm* firmPtr, int stop1PickUpType, int stop2PickUpType) { //---- see if there is already a caravan moving along the route -----// Nation* ownNation = nation_array[nation_recno]; UnitCaravan* unitCaravan; int rc, stop1Id, stop2Id; int caravanInRouteCount=0; for( int i=ownNation->ai_caravan_count-1 ; i>=0 ; i-- ) { unitCaravan = (UnitCaravan*) unit_array[ ownNation->ai_caravan_array[i] ]; err_when( unitCaravan->nation_recno != nation_recno ); err_when( unitCaravan->unit_id != UNIT_CARAVAN ); if( unitCaravan->stop_defined_num < 2 ) continue; if( unitCaravan->stop_array[0].firm_recno == firm_recno && unitCaravan->stop_array[1].firm_recno == firmPtr->firm_recno ) { stop1Id = 1; stop2Id = 2; } else if( unitCaravan->stop_array[1].firm_recno == firm_recno && unitCaravan->stop_array[0].firm_recno == firmPtr->firm_recno ) { stop1Id = 2; stop2Id = 1; } else { continue; } //------- add the goods to the pick up list ----// rc = 0; if( stop1PickUpType && !unitCaravan->has_pick_up_type(stop1Id, stop1PickUpType) ) { if( unitCaravan->is_visible() ) // can't set stop when the caravan is in a firm unitCaravan->set_stop_pick_up(stop1Id, stop1PickUpType, COMMAND_AI); rc = 1; } if( stop2PickUpType && !unitCaravan->has_pick_up_type(stop2Id, stop2PickUpType) ) { if( unitCaravan->is_visible() ) // can't set stop when the caravan is in a firm unitCaravan->set_stop_pick_up(stop2Id, stop2PickUpType, COMMAND_AI); rc = 1; } if( rc ) // don't add one if we can utilize an existing one. return 1; caravanInRouteCount++; } if( caravanInRouteCount >= 2 ) // don't have more than 2 caravans on a single route return 0; //----------- hire a new caravan -----------// int unitRecno = hire_caravan(COMMAND_AI); if( !unitRecno ) return 0; //----------- set up the trade route ----------// unitCaravan = (UnitCaravan*) unit_array[unitRecno]; unitCaravan->set_stop(2, firmPtr->loc_x1, firmPtr->loc_y1, COMMAND_AI); err_when( unitCaravan->stop_array[0].firm_recno == firmPtr->firm_recno ); // cannot set both stops to the same firm unitCaravan->set_stop_pick_up(1, NO_PICK_UP, COMMAND_AI); unitCaravan->set_stop_pick_up(2, NO_PICK_UP, COMMAND_AI); if( stop1PickUpType ) unitCaravan->set_stop_pick_up(1, stop1PickUpType, COMMAND_AI); if( stop2PickUpType ) unitCaravan->set_stop_pick_up(2, stop2PickUpType, COMMAND_AI); return 1; }
//------- Begin of function FirmMarket::think_import_new_product ------// // // Think about importing goods to sell in this market place. // int FirmMarket::think_import_new_product() { //--- update what products are needed for this market place ---// int i, j; Town* townPtr; short needProductSupplyPop[MAX_PRODUCT]; // the total population in the towns linked to the market that needs the supply of the product Nation* nationPtr = nation_array[nation_recno]; memset( needProductSupplyPop, 0, sizeof(needProductSupplyPop) ); for( i=0; i<linked_town_count; i++ ) { err_when(!linked_town_array[i] || town_array.is_deleted(linked_town_array[i])); if( linked_town_enable_array[i] != LINK_EE ) continue; townPtr = town_array[linked_town_array[i]]; if( townPtr->region_id != region_id ) continue; if( !townPtr->is_base_town ) // don't import if it isn't a base town continue; //------------------------------------------------// // // Only if the population of the town is equal or // larger than minTradePop, the AI will try to do trade. // The minTradePop is between 10 to 20 depending on the // pref_trading_tendency. // //------------------------------------------------// townPtr->update_product_supply(); for( j=0 ; j<MAX_PRODUCT ; j++ ) { if( !townPtr->has_product_supply[j] ) needProductSupplyPop[j] += townPtr->population; } } //---- think about importing the products that need supply ----// int minTradePop = 10; for( int productId=1 ; productId<=MAX_PRODUCT ; productId++ ) { if( needProductSupplyPop[productId-1] >= minTradePop ) { if( think_import_specific_product(productId) ) { last_import_new_goods_date = info.game_date; return 1; } } } //----------------------------------------------------------// // Think about importing the raw materials of the needed // products and build factories to manufacture them ourselves //----------------------------------------------------------// //--- first check if we can build a new factory to manufacture the products ---// if( is_market_linked_to_town(1) ) // 1-only count towns that are our own and are base towns { if( !no_neighbor_space && nationPtr->total_jobless_population >= MAX_WORKER*2 && can_hire_caravan() >= 2 ) // if there is a shortage of caravan supplies, use it for transporting finished products instead of raw materials { if( nationPtr->can_ai_build(FIRM_FACTORY) ) { for( int productId=1 ; productId<=MAX_PRODUCT ; productId++ ) { if( needProductSupplyPop[productId-1] >= minTradePop ) { if( think_mft_specific_product(productId) ) { last_import_new_goods_date = info.game_date; return 1; } } } } } } return 0; }
//--------- Begin of function SiteArray::next_day ----------// // void SiteArray::next_day() { if( info.game_date%30 == 0 ) { generate_raw_site(); // check if we need to generate existing raw sites are being used up and if we need to generate new ones } //-- if there is any scroll or gold coins available, ask AI to get them --// // #### begin Gilbert 3/11 ######// if(scroll_count || gold_coin_count || item_count || weapon_blueprint_count ) // #### end Gilbert 3/11 ######// { int aiGetSiteObject = (info.game_date%5 == 0); Site* sitePtr; Location *locPtr; for(int i=size(); i; i--) { if(is_deleted(i)) continue; sitePtr = site_array[i]; switch(sitePtr->site_type) { case SITE_SCROLL: case SITE_GOLD_COIN: case SITE_ITEM: case SITE_WEAPON_BLUEPRINT: locPtr = world.get_loc(sitePtr->map_x_loc, sitePtr->map_y_loc); //---- if the unit is standing on a scroll site -----// if(locPtr->unit_recno(UNIT_LAND)) { // ####### begin Gilbert 25/5 ##########// int unitRecno = locPtr->unit_recno(UNIT_LAND); if( !unit_array.is_deleted(unitRecno) ) sitePtr->get_site_object( unitRecno ); // ####### end Gilbert 25/5 ##########// } else if(aiGetSiteObject) { sitePtr->ai_get_site_object(); } break; } } } //-------- debug testing --------// #ifdef DEBUG if( info.game_date%10 == 0 ) { Site* sitePtr; Location* locPtr; for( int i=1 ; i<=size() ; i++ ) { if( site_array.is_deleted(i) ) continue; sitePtr = site_array[i]; locPtr = world.get_loc( sitePtr->map_x_loc, sitePtr->map_y_loc ); err_when( !locPtr->has_site() ); err_when( locPtr->site_recno() != i ); if( sitePtr->has_mine ) { err_when( !locPtr->is_firm() ); err_when( firm_array[locPtr->firm_recno()]->firm_id != FIRM_MINE && firm_array[locPtr->firm_recno()]->firm_id != FIRM_ALCHEMY ); } else { // disable because a mine can be upon more than one mine // err_when( locPtr->is_firm() || locPtr->is_town() ); } } } #endif }
//---------- Begin of function Firm::next_day --------// // void Firm::next_day() { if( !nation_recno ) return; #ifdef DEBUG //BUGHERE err_when( is_human() == (firm_id >= FIRM_LAIR && firm_id <= FIRM_MAGIC) ); // error when a human attempts to build a monster firm or a mosnter attempts to build a human firm //------ validate linked towns ------// int lastLinkedTown=0; for( int i=0 ; i<linked_town_count ; i++ ) { Town* townPtr = town_array[linked_town_array[i]]; err_when( townPtr->town_recno == lastLinkedTown ); lastLinkedTown = townPtr->town_recno; int j; for( j=0; j<townPtr->linked_firm_count ; j++ ) { if( townPtr->linked_firm_array[j] == firm_recno ) break; } err_when( j==townPtr->linked_firm_count ); // the link is brokwn, only one side has it } #endif //------ think about updating link status -------// // // This part must be done here instead of in // process_ai() because it will be too late to do // it in process_ai() as the next_day() will call // first and some wrong goods may be input to markets. // //-----------------------------------------------// if( is_ai ) { if( info.game_date%30==firm_recno%30 || !ai_link_checked ) // once 30 days or when the link has been changed. { ai_update_link_status(); ai_link_checked = 1; } } //-------- pay expenses ----------// pay_expense(); //--------- repairing ----------// process_repair(); //------ catching spies -------// if( info.game_date%30 == firm_recno%30 ) spy_array.catch_spy(SPY_FIRM, firm_recno); //--- recheck no_neighbor_space after a period, there may be new space available now ---// if( no_neighbor_space && info.game_date%180 == firm_recno%180 ) { short buildXLoc, buildYLoc; if( nation_array[nation_recno]->find_best_place_loc(FIRM_INN, loc_x1, loc_y1, buildXLoc, buildYLoc) ) // whether it's FIRM_INN or not really doesn't matter, just any firm type will do no_neighbor_space = 0; } // ##### begin Gilbert 16/11 #######// // ------ reset active_link_town_recno if deleted --------// if( town_array.is_deleted(active_link_town_recno) ) { active_link_town_recno = 0; } // ##### end Gilbert 16/11 #######// // ####### begin Gilbert 4/3 ########// // ------ clear rally destination if deleted -------// if( rally_enable_flag && rally_dest_base_obj_recno && base_obj_array.is_deleted(rally_dest_base_obj_recno) ) { clear_rally_point(COMMAND_AUTO); } // ####### end Gilbert 4/3 ########// if( hit_points < (max_hit_points() * 0.1)) { if (m.random(100) > 20) { FirmDie firmDieFire1; firmDieFire1.init(this, 3, m.random(100)); firm_die_array.add(&firmDieFire1); } if (m.random(100) > 40) { FirmDie firmDieFire2; firmDieFire2.init(this, 3, m.random(100)); firm_die_array.add(&firmDieFire2); } // if (m.random(100) > 30) // bullet_array.add_bullet(this, this); } else if( hit_points < (max_hit_points() * 0.3)) { if (m.random(100) > 30) { FirmDie firmDieFire3; firmDieFire3.init(this, 3, m.random(100)); firm_die_array.add(&firmDieFire3); } // if (m.random(100) > 20) // bullet_array.add_bullet(this, this); } }
//--------- Begin of function Firm::spy_bribe ---------// // // The money the spy offers to bribe the unit. // // <int> bribeAmount - the amount offered // <short> birberSpyRecno - spy recno of the briber // <short> workerId - if 0, then bribe the overseer, // if >0, then bribe a worker. // // return: <int> >0 - bribing succeeded, return the spy recno of the bribed unit (as it has been turned into a spy) // 0 - bribing failed // int Firm::spy_bribe(int bribeAmount, short briberSpyRecno, short workerId) { if( !can_spy_bribe(workerId, spy_array[briberSpyRecno]->true_nation_recno) ) // this can happen in multiplayer as there is a one frame delay when the message is sent and when it is processed return 0; //---------------------------------------// int succeedChance = spy_bribe_succeed_chance(bribeAmount, briberSpyRecno, workerId); Spy* spyPtr = spy_array[briberSpyRecno]; nation_array[spyPtr->true_nation_recno]->add_expense( EXPENSE_BRIBE, (float) bribeAmount, 0 ); //------ if the bribe succeeds ------// if( succeedChance > 0 && misc.random(100) < succeedChance ) { int spyRecno = spy_array.add_spy(); // add a new Spy record Spy* newSpy = spy_array[spyRecno]; newSpy->spy_skill = 10; newSpy->action_mode = SPY_IDLE; newSpy->spy_loyalty = MIN( 100, MAX(30,succeedChance) ); // within the 30-100 range newSpy->true_nation_recno = spyPtr->true_nation_recno; newSpy->cloaked_nation_recno = spyPtr->cloaked_nation_recno; if( workerId ) { Worker* workerPtr = worker_array+workerId-1; workerPtr->spy_recno = spyRecno; newSpy->race_id = workerPtr->race_id; newSpy->name_id = workerPtr->name_id; err_when( newSpy->race_id < 1 || newSpy->race_id > MAX_RACE ); if( !newSpy->name_id ) // if this worker does not have a name, give him one now as a spy must reserve a name (see below on use_name_id() for reasons) newSpy->name_id = race_res[newSpy->race_id]->get_new_name_id(); } else if( overseer_recno ) { Unit* unitPtr = unit_array[overseer_recno]; unitPtr->spy_recno = spyRecno; newSpy->race_id = unitPtr->race_id; newSpy->name_id = unitPtr->name_id; err_when( newSpy->race_id < 1 || newSpy->race_id > MAX_RACE ); } else err_here(); newSpy->set_place( SPY_FIRM, firm_recno ); //-- Spy always registers its name twice as his name will be freed up in deinit(). Keep an additional right because when a spy is assigned to a town, the normal program will free up the name id., so we have to keep an additional copy race_res[newSpy->race_id]->use_name_id(newSpy->name_id); bribe_result = BRIBE_SUCCEED; if( firm_recno == firm_array.selected_recno ) info.disp(); return newSpy->spy_recno; } else //------- if the bribe fails --------// { spyPtr->get_killed(0); // the spy gets killed when the action failed. // 0 - don't display new message for the spy being killed, so we already display the msg on the interface bribe_result = BRIBE_FAIL; if( firm_recno == firm_array.selected_recno ) info.disp(); return 0; } }
//---------- Begin of function Student::think_graduate -----------// //! //! graduate (use cummulative passed courses in general and grad prob for doctor); //! int Student::think_graduate() { //----- a student graduate when he/she has completed all the required number of courses ----// int requiredCourseCount; switch( student_level ) { case UG_TRADITION: case UG_NONTRADITION: case DISTANCE_LEARN: //32 requiredCourseCount = COURSE_COUNT_REQUIRED_FOR_BACHELOR; break; case MASTER: //8 requiredCourseCount = COURSE_COUNT_REQUIRED_FOR_MASTER; break; case DOCTOR: //16 requiredCourseCount = COURSE_COUNT_REQUIRED_FOR_DOCTOR; break; } //##### begin fred 980915 #####// //Department* deptPtr = department_recno?department_array[department_recno] : department_res.general_dept; if( total_course_all < requiredCourseCount ) { // info.debug_enroll++; //## chea 281099 return 0; } err_when(department_recno == 0); Department* deptPtr = department_array[department_recno]; if ( student_level == DOCTOR ) { err_when(department_recno == 0); char yearIn = min(year_in_program-1, MAX_GRADUATE_YEARS-1); float gradProb = department_res[deptPtr->department_id]->doctor_graduate_trans_prob[yearIn]; // float input[2]; float multiplier = 1; //0223 input[0] = math.dual_response_func(0.80f, 1.02f, 1.30f, 0.891f, 1.295f, 0.557f, 2.326f, 0); //0223 input[1] = math.dual_response_func(0.80f, 1.00f, 1.30f, -0.912f, -0.863f, 2.502f, 0.489f, 0); multiplier = 0.5f * input[0] + 0.5f * input[1]; // response_func var 28: multiplier = math.latency_func(0.33f, multiplier, lastMultiplier); if ( math.get_random_float() > gradProb * multiplier ) { // info.debug_enroll++; return 0; } } //##### end fred 980915 #####// //-------- graduate now ----------------// //----- update the graduation count -----// switch( student_level ) { case UG_TRADITION: case UG_NONTRADITION: if ( student_level == UG_TRADITION ) { deptPtr->student_array.cur_bachelor_degree++; deptPtr->student_array.last_year_degree[0]++; } else { deptPtr->student_array.cur_non_ug_bachelor_degree++; deptPtr->student_array.last_year_degree[1]++; } deptPtr->student_array.time_to_degree_cumm[BACHELOR_DEGREE] += year_in_program; break; case MASTER: deptPtr->student_array.cur_master_degree++; deptPtr->student_array.last_year_degree[2]++; deptPtr->student_array.time_to_degree_cumm[MASTER_DEGREE] += year_in_program; break; case DOCTOR: deptPtr->student_array.cur_doctor_degree++; deptPtr->student_array.last_year_degree[3]++; deptPtr->student_array.time_to_degree_cumm[DOCTOR_DEGREE] += year_in_program; break; } //-- update average time to graduation for traditional undergraduates --// if( student_level == UG_TRADITION ) { int graduationTime = info.game_date - date_admitted; deptPtr->student_array.ave_time_to_graduation_for_ug = ( deptPtr->student_array.ave_time_to_graduation_for_ug * (deptPtr->student_array.cur_bachelor_degree - 1) + graduationTime ) / deptPtr->student_array.cur_bachelor_degree; #ifdef DEBUG static int grad4Year[2] = { 0, 0 }; if( graduationTime > 1461 ) { // 4 year grad4Year[1]++; } else { grad4Year[0]++; } #endif } if ( audit_flag ) { File file; char fileName[123]; switch( student_level ) { case UG_TRADITION: strcpy( fileName, "TRADITION" ); break; case UG_NONTRADITION: strcpy( fileName, "NONTRADITION" ); break; case MASTER: strcpy( fileName, "MASTER" ); break; case DOCTOR: strcpy( fileName, "DOCTOR" ); break; } strcat( fileName, m.format(old_student_recno) ); strcat( fileName, ".txt" ); file.file_append( fileName ); file.file_seek(0, FILE_END); // Cohet if ( info.prerun_year ) { WRITE_NUM_FIELD( (&file), -1 ); } else { WRITE_NUM_FIELD( (&file), info.financial_year() ); } WRITE_FIELD_SEPARATOR( (&file) ); // Trimester switch( player_school.cur_trimester ) { case AUTUMN: WRITE_STR_FIELD( (&file), "A" ); break; case WINTER: WRITE_STR_FIELD( (&file), "W" ); break; case SUMMER: WRITE_STR_FIELD( (&file), "S" ); break; } // ID file_course_id++; WRITE_FIELD_SEPARATOR( (&file) ); WRITE_FIELD_SEPARATOR( (&file) ); WRITE_NUM_FIELD( (&file), file_course_id ); WRITE_FIELD_SEPARATOR( (&file) ); WRITE_STR_FIELD( (&file), "Status" ); WRITE_FIELD_SEPARATOR( (&file) ); WRITE_FIELD_SEPARATOR( (&file) ); if ( department_recno ) { WRITE_STR_FIELD( (&file), "Grad" ); } file.file_close(); } //----- remove the student from student_array -----// deptPtr->student_array.del(student_recno); // info.debug_enroll++; // info.debug_enroll2++; return 1; }
//--------- Begin of function Firm::disp_bribe_menu ---------// // void Firm::disp_bribe_menu(int refreshFlag) { //---- if the briber or bribe target is no longer valid -----// if( bribe_result == BRIBE_NONE ) { if( !validate_cur_bribe() ) { firm_menu_mode = FIRM_MENU_MAIN; bribe_result = BRIBE_NONE; info.disp(); return; } } //------------------------------------// if( refreshFlag != INFO_REPAINT ) return; //------ display the bribe menu ------// if( bribe_result == BRIBE_NONE ) { int y=INFO_Y1; font_san.d3_put( INFO_X1, y, INFO_X2, y+19, _("Bribe") ); y+=22; disp_bribe_unit( y ); y+=49; for( int i=0 ; i<BRIBE_AMOUNT_COUNT ; i++ ) { disp_bribe_button( y, bribe_amount_array[i], 1); err_when( bribe_amount_array[i] > MAX_BRIBE_AMOUNT ); y += BRIBE_OPTION_HEIGHT+2; } disp_bribe_button( y, 0, 1); } //------ display the bribe result -----// else { int x=INFO_X1+4, y=INFO_Y1+4, y2=y+font_san.height()-1; if( bribe_result == BRIBE_SUCCEED ) { vga_util.d3_panel_up( INFO_X1, INFO_Y1, INFO_X2, INFO_Y1+24 ); font_san.center_put( INFO_X1, y, INFO_X2, y2, _("Bribing Succeeded.") ); } else { vga_util.d3_panel_up( INFO_X1, INFO_Y1, INFO_X2, INFO_Y1+62 ); font_san.center_put( INFO_X1, y , INFO_X2, y2, _("Bribing Failed.") ); font_san.center_put( INFO_X1, y+=18, INFO_X2, y2+=18, _("Your Spy Was Caught") ); font_san.center_put( INFO_X1, y+=18, INFO_X2, y2+=18, _("And Executed.") ); } y+=26; button_cancel.paint( INFO_X1, y, 'A', "CONTINUE" ); } }
//##### begin fred 980915 #####// //---------- Begin of function Student::think_dropout -----------// //! //! //! called only by pschool's next_day() at the end of trimester; //! //! called before optimization and after the end of the last trimester //! int Student::think_dropout() { calc_multiplier_on_dropout_prob(); //-------- find dropout_prob ----------------// err_when(year_in_program<1); float dropProb = 0; char yearIn = min(year_in_program-1, MAX_GRADUATE_YEARS-1); GeneralDepartment* deptPtr = department_recno ? (GeneralDepartment *) department_array[department_recno] : &department_res.general_dept; // 0118 if ( deptPtr->student_array.student_count <= 10 ) { // info.debug_enroll3++; //## chea 281099 stu total return 0; } switch( student_level ) { case UG_NONTRADITION: dropProb = 0.5f * player_school.dropout_trans_prob[student_level][yearIn]; break; case UG_TRADITION: case MASTER: // float dropout_trans_prob[MASTER_ARRAY_SIZE][MAX_GRADUATE_YEARS]; dropProb = player_school.dropout_trans_prob[student_level][yearIn]; break; case DOCTOR: err_when(&department_res.general_dept == deptPtr); dropProb = 0.5f * department_res[deptPtr->department_id]->doctor_dropout_trans_prob[yearIn]; break; case DISTANCE_LEARN: dropProb = player_school.dropout_trans_prob[UG_NONTRADITION][yearIn]; break; } // min & max bug chea dropProb = max(0.0f, min(1.0f, dropProb * multiplier_on_dropout_prob)); if ( math.get_random_float() > dropProb ) { // info.debug_enroll3++; //## chea 281099 student total return 0; } //---------// else dropout! //---------// //----- remove the student from student_array -----// char level2Degree[] = {BACHELOR_DEGREE, BACHELOR_DEGREE, MASTER_DEGREE, DOCTOR_DEGREE, -1}; if ( level2Degree[student_level] >=0 ) { deptPtr->student_array.last_year_dropout[student_level]++; deptPtr->student_array.cur_dropout[level2Degree[student_level]]++; } if ( audit_flag ) { File file; char fileName[123]; switch( student_level ) { case UG_TRADITION: strcpy( fileName, "TRADITION" ); break; case UG_NONTRADITION: strcpy( fileName, "NONTRADITION" ); break; case MASTER: strcpy( fileName, "MASTER" ); break; case DOCTOR: strcpy( fileName, "DOCTOR" ); break; } strcat( fileName, m.format(old_student_recno) ); strcat( fileName, ".txt" ); file.file_append( fileName ); file.file_seek(0, FILE_END); // Cohet if ( info.prerun_year ) { WRITE_NUM_FIELD( (&file), -1 ); } else { WRITE_NUM_FIELD( (&file), info.financial_year() ); } WRITE_FIELD_SEPARATOR( (&file) ); // Trimester switch( player_school.cur_trimester ) { case AUTUMN: WRITE_STR_FIELD( (&file), "A" ); break; case WINTER: WRITE_STR_FIELD( (&file), "W" ); break; case SUMMER: WRITE_STR_FIELD( (&file), "S" ); break; } // ID file_course_id++; WRITE_FIELD_SEPARATOR( (&file) ); WRITE_FIELD_SEPARATOR( (&file) ); WRITE_NUM_FIELD( (&file), file_course_id ); WRITE_FIELD_SEPARATOR( (&file) ); WRITE_STR_FIELD( (&file), "Status" ); WRITE_FIELD_SEPARATOR( (&file) ); WRITE_FIELD_SEPARATOR( (&file) ); if ( department_recno ) { WRITE_STR_FIELD( (&file), "Drop" ); } file.file_close(); } deptPtr->student_array.del(student_recno); // info.debug_enroll3++; // info.debug_enroll4++; return 1; }
//--------- Begin of function FirmCamp::detect_info ---------// // void FirmCamp::detect_info() { Firm::detect_info(); switch( firm_menu_mode ) { case FIRM_MENU_MAIN: if( should_show_info() ) { detect_camp_info(); detect_soldier_list(0); detect_soldier_info(); detect_spy_button(); } break; case FIRM_MENU_TRAIN: detect_train_menu(); break; case FIRM_MENU_SPY: case FIRM_MENU_SELECT_BRIBER: detect_spy_menu(); break; case FIRM_MENU_SET_BRIBE_AMOUNT: detect_bribe_menu(); break; case FIRM_MENU_BRIBE_RESULT: detect_bribe_result(); break; case FIRM_MENU_VIEW_SECRET: if( spy_array.detect_view_secret_menu(action_spy_recno, nation_recno) ) { firm_menu_mode = FIRM_MENU_MAIN; // info.disp(); } break; case FIRM_MENU_ASSASSINATE_CONFIRM: detect_assassinate_confirm(); break; case FIRM_MENU_ASSASSINATE_RESULT: detect_assassinate_result(); break; case FIRM_MENU_STEAL_TECH_CONFIRM: detect_steal_tech_confirm(); break; case FIRM_MENU_STEAL_TECH_RESULT: detect_steal_tech_result(); break; case FIRM_MENU_INCIDENT_NATION: detect_incident_nation(); break; case FIRM_MENU_INCIDENT_CONFIRM: detect_incident_confirm(); break; case FIRM_MENU_INCIDENT_RESULT: detect_incident_result(); break; default: err_when( firm_menu_mode < FIRM_MENU_CAMP_LAST ); // if firm_menu_mode >= FIRM_MENU_CAMP_LAST, handled by sub-class } }
//##### begin fred 980916 #####// //---------- Begin of function Student::init -----------// //! void Student::init(char studentLevel, char yearInProgram, char genderEthnicGroup, char stuSeg, char major, int finAid, float* talentArr) { memset( this, 0, sizeof(Student) ); //--- vars that will remain constant once initialized ---// department_recno = major; // =0 if UNDECIDED student_level = studentLevel; gender_ethnic_group = genderEthnicGroup; student_segment = stuSeg; date_admitted = info.game_date-(yearInProgram-1)*365; //------- vars that will change over time ------// year_in_program = yearInProgram; financial_aid = finAid; academic_achievement = 0; // 0 means nil, it is updated after completion of each trimester //--- initialize the number courses to take per trimester ---// if ( student_level != UG_NONTRADITION ) { course_per_trimester[AUTUMN] = STD_COURSE_PER_TRIMESTER; course_per_trimester[WINTER] = STD_COURSE_PER_TRIMESTER; } else { course_per_trimester[AUTUMN] = STD_COURSE_NUG_PER_TRIMESTER; course_per_trimester[WINTER] = STD_COURSE_NUG_PER_TRIMESTER; } off_quarter = SUMMER; // newly matriculated if ( student_level == UG_TRADITION && year_in_program == 1 ) { if( m.random(4)==0 ) // select 2/8 sample { off_quarter = m.random(1) + AUTUMN; // select autumn or winter err_when(AUTUMN!=0); course_per_trimester[off_quarter] = 0; // this is determined by summer teaching policy course_per_trimester[SUMMER] = STD_COURSE_PER_TRIMESTER; } } //-- to update these three from enrollres.talen_array ---// //## 071299 chea 1.12.1 // min & max bug chea talent_academic = (char) max(0.0f,min(100.0f, talentArr[ACADEMIC] * 10)); // talent_academic = 33; //##200100 chea // min & max bug chea talent_extracurricular = (char) max(0.0f,min(100.0f, talentArr[EXTRA_CURRI] * 10)); // min & max bug chea talent_athletics = (char) max(0.0f,min(100.0f, talentArr[ATHLETIC] * 10)); //------ refer to techdoc3.3 section 4.10 -----// satisfaction_academic = 0; satisfaction_student_life = 0; satisfaction_athletics = 0; err_when( studentLevel < 0 || studentLevel >= MAX_STUDENT_LEVEL ); err_when( genderEthnicGroup < 0 || genderEthnicGroup >= GENDER_ETHNIC_TYPE_COUNT ); err_when( major < 0 || major > department_array.department_count ); // ug yr1 student registered in General Education Department with dept_recno=0 err_when( major==0 && student_level != UG_TRADITION && !is_nontradition_ug_group(student_level) ); }
//--------- Begin of function FirmCamp::disp_soldier_list ---------// // void FirmCamp::disp_soldier_list(int dispY1, int refreshFlag, int dispSpyMenu) { disp_soldier_list_y1 = dispY1; for( int inc = -1; inc <= 1; inc += 2 ) { err_when( inc == 0 ); // first round is descending draw to icon // second round is ascending to draw the frame int inAreaFlag = 4; for( int i = inc>=0?0:soldier_count; i >= 0 && i <= soldier_count; i +=inc ) { // display soldier i int row = i/SOLDIER_PER_ROW; int x = INFO_X1 + 18 + (i % SOLDIER_PER_ROW) * SOLDIER_X_SPACING; int y = INFO_Y1 + 50 + row * SOLDIER_Y_SPACING; int yHp = INFO_Y1 + 7 + row * SOLDIER_Y_SPACING; int windowX1 = INFO_X1 + 16; int windowX2 = INFO_X1 + 220; int windowY1 = INFO_Y1 + 5 + row * 84; // 5,89 int windowY2 = windowY1 + 80 - 1 ; int unitId; int hp; int maxHp; // ##### begin Gilbert 21/9 ######// int combatLevel; int skillLevel; int loyalty; // ##### end Gilbert 21/9 ######// int ownSpy; int itemId; if( i==0 ) { if( !overseer_recno ) continue; // overseer Unit *overseer = unit_array[overseer_recno]; unitId = overseer->unit_id; hp = (int) overseer->hit_points; maxHp = overseer->max_hit_points(); combatLevel = (int) overseer->combat_level(); skillLevel = (int) overseer->skill_level(); if( overseer->rank_id != RANK_GENERAL ) loyalty = -1; // king or other(?) else loyalty = overseer->loyalty; ownSpy = overseer->is_own_spy() ? overseer->spy_recno : 0; itemId = overseer->item.id; } else { // soldier Soldier *soldierPtr = &soldier_array[i-1]; unitId = soldierPtr->unit_id; hp = soldierPtr->hit_points; maxHp = soldierPtr->max_hit_points(); combatLevel = (int) soldierPtr->combat_level(); skillLevel = (int) soldierPtr->skill_level(); // ####### begin Gilbert 24/3 #########// if( unit_res[soldierPtr->unit_id]->class_info.has_loyalty && nation_recno ) // ####### end Gilbert 24/3 #########// loyalty = soldierPtr->loyalty; else loyalty = -1; ownSpy = soldierPtr->is_own_spy() ? soldierPtr->spy_recno : 0; itemId = soldierPtr->item.id; } if( dispSpyMenu && !ownSpy ) // skip displaying spy continue; UnitInfo *unitInfo = unit_res[unitId]; // display that solider icon at x+SOLDIER_X_SPACING/2, y // draw a frame if selected if( inc < 0 ) { // first round is descending draw to icon Soldier *soldierPtr = &soldier_array[i-1]; info.draw_unit_icon( x+SOLDIER_X_SPACING/2, y, unitId, nation_recno, windowX1, windowY1, windowX2, windowY2, (i>0 && soldierPtr->combat_level() < 20) ? (((20 - soldierPtr->combat_level()) <<6)+ 33) : 1); } else { // second round is ascending to draw the frame if( info.draw_unit_icon( x+SOLDIER_X_SPACING/2, y, unitId, nation_recno, windowX1, windowY1, windowX2, windowY2, inAreaFlag | (i==selected_soldier_id?3:0) ) & 4 ) { inAreaFlag = 0; // frame for mouse cursor is drawn, disable the frame } // display combat skill // ######## begin Gilbert 21/9 #######// Font *font = &font_whbl; if( !dispSpyMenu ) { if( disp_combat_or_skill ) // display skill level { font = &font_blue; int attribute = -1; switch( disp_combat_or_skill ) { case 1: if( unitInfo->class_info.has_combat_level ) attribute = combatLevel; break; case 2: if( unitInfo->class_info.has_skill_level && skillLevel > 0 ) attribute = skillLevel; break; case 4: if( unitInfo->class_info.has_loyalty && nation_recno ) attribute = loyalty; break; default: err_here(); } if( attribute >= 0 ) // hide attribute on some cases font->center_put( x, yHp, x+SOLDIER_X_SPACING, yHp+font->max_font_height, m.format(attribute) ); } else if( ownSpy ) // display spy icon { vga.active_buf->put_bitmap_trans( x+SOLDIER_X_SPACING/2-8, yHp-5, image_icon.read("U_SPY") ); } else if( unitInfo->class_info.has_combat_level ) // display combat skill { font->center_put( x, yHp, x+SOLDIER_X_SPACING, yHp+font->max_font_height, m.format(combatLevel) ); } if( itemId ) { char *iconPtr = item_res.item_unit_interface(itemId); if( iconPtr ) vga.active_buf->put_bitmap_trans( x+SOLDIER_X_SPACING/2-((Bitmap *)iconPtr)->get_width()/2, yHp +53, iconPtr ); } } else { // display spy skill err_when( !ownSpy ); font_whbl.center_put( x, yHp, x+SOLDIER_X_SPACING, yHp+font->max_font_height, m.format(spy_array[ownSpy]->spy_skill) ); } // display hit points bar if( i > 0 && soldier_array[i-1].is_under_training() ) disp_training_bar( x, yHp+font->max_font_height+2, x+SOLDIER_X_SPACING*7/8-1, soldier_array[i-1].skill_level(), BASIC_COMBAT_TRAIN ); else disp_soldier_hit_points( x, yHp+font->max_font_height+2, x+SOLDIER_X_SPACING*7/8-1, hp, maxHp ); } } } /* //---------------- paint the panel --------------// if( overseer_recno ) { //------------ display overseer info -------------// Unit* overseerUnit = unit_array[overseer_recno]; int x=INFO_X1+6, y=dispY1+4, x1=x+UNIT_LARGE_ICON_WIDTH+8; if( selected_soldier_id == 0 ) { vga_front.rect( x-2, y-2, x+UNIT_LARGE_ICON_WIDTH+1, y+UNIT_LARGE_ICON_HEIGHT+1, 2, V_YELLOW ); } else { vga.blt_buf( x-2, y-2, x+UNIT_LARGE_ICON_WIDTH+1, y-1, 0 ); vga.blt_buf( x-2, y+UNIT_LARGE_ICON_HEIGHT+1, x+UNIT_LARGE_ICON_WIDTH+1, y+UNIT_LARGE_ICON_HEIGHT+2, 0 ); vga.blt_buf( x-2, y-2, x-1, y+UNIT_LARGE_ICON_HEIGHT+2, 0 ); vga.blt_buf( x+UNIT_LARGE_ICON_WIDTH, y-2, x+UNIT_LARGE_ICON_WIDTH+1, y+UNIT_LARGE_ICON_HEIGHT+2, 0 ); } //-------------------------------------// if( refreshFlag == INFO_REPAINT ) { vga_front.put_bitmap(x, y, unit_res[overseerUnit->unit_id]->get_large_icon_ptr(overseerUnit->rank_id) ); } //-------- set help parameters --------// if( mouse.in_area(x, y, x+UNIT_LARGE_ICON_WIDTH+3, y+UNIT_LARGE_ICON_HEIGHT+3) ) help.set_unit_help( overseerUnit->unit_id, overseerUnit->rank_id, x, y, x+UNIT_LARGE_ICON_WIDTH+3, y+UNIT_LARGE_ICON_HEIGHT+3); //-------------------------------------// if( overseerUnit->rank_id == RANK_KING ) { if( refreshFlag == INFO_REPAINT ) font_san.put( x1, y, "King" ); y+=14; } if( refreshFlag == INFO_REPAINT ) font_san.put( x1, y, overseerUnit->unit_name(0), 0, INFO_X2-2 ); // 0-ask unit_name() not to return the title of the unit y+=14; //------- display leadership -------// String str; str = translate.process("Leadership"); str += ": "; str += overseerUnit->skill.skill_level; font_san.disp( x1, y, str, INFO_X2-10 ); y+=14; //--------- display loyalty ----------// if( overseerUnit->rank_id != RANK_KING ) { x1 = font_san.put( x1, y, "Loyalty:" ); int x2 = info.disp_loyalty( x1, y-1, x1, overseerUnit->loyalty, overseerUnit->target_loyalty, nation_recno, refreshFlag ); if( overseerUnit->spy_recno ) { //------ if this is the player's spy -------// if( overseerUnit->is_own_spy() ) { vga_front.put_bitmap( x2+5, y+1, image_icon.get_ptr("U_SPY") ); x2 += 15; } } vga.blt_buf( x2, y-1, INFO_X2-2, dispY1+44, 0 ); } } pop_disp_y1 = dispY1; //---------------- paint the panel --------------// if( refreshFlag == INFO_REPAINT ) vga.d3_panel_up( INFO_X1, dispY1, INFO_X2, dispY1+60 ); //----------- display populatin distribution ---------// int overseerRaceId=0; if( overseer_recno ) overseerRaceId = unit_array[overseer_recno]->race_id; if( selected_soldier_id > soldier_count ) selected_soldier_id = soldier_count; //------ display population composition -------// int x, y; Soldier* soldierPtr = soldier_array; static char last_race_id_array[MAX_SOLDIER]; static char last_unit_id_array[MAX_SOLDIER]; dispY1+=1; for( int i=0 ; i<MAX_SOLDIER ; i++, soldierPtr++ ) { x = INFO_X1+4+i%4*50; y = dispY1+i/4*29; if( i<soldier_count ) { if( refreshFlag==INFO_REPAINT || last_race_id_array[i] != soldierPtr->race_id || last_unit_id_array[i] != soldierPtr->unit_id ) { vga_front.put_bitmap(x+2, y+2, soldierPtr->small_icon_ptr()); } //----- highlight the selected soldier -------// if( selected_soldier_id == i+1 ) vga_front.rect( x, y, x+27, y+23, 2, V_YELLOW ); else vga_front.rect( x, y, x+27, y+23, 2, vga_front.color_up ); //------ display hit points bar --------// disp_soldier_hit_points( x+2, y+24, x+25, soldierPtr->shown_hit_points(), soldierPtr->max_hit_points() ); //----- display combat or skill level ------// char* spyIconName=NULL; if( soldierPtr->spy_recno ) { Spy* spyPtr = spy_array[soldierPtr->spy_recno]; //------ if this is the player's spy -------// if( nation_array.player_recno && spyPtr->true_nation_recno == nation_array.player_recno ) { spyIconName = "U_SPY"; } //--------------------------------------------// // // If this is an enemy spy and this firm belongs // to the player and there is a player's phoenix // over this firm and the spying skill of the spy // is low (below 40) // //--------------------------------------------// // else if( spyPtr->spy_skill < 40 && // nation_recno == nation_array.player_recno && // nation_array.player_recno && // (~nation_array)->revealed_by_phoenix(loc_x1, loc_y1) ) // { // spyIconName = "ENEMYSPY"; // } } //--------------------------------------// if( spyIconName ) { vga_front.put_bitmap( x+30, y+6, image_icon.get_ptr(spyIconName) ); vga.blt_buf( x+40, y+6, x+49, y+15, 0 ); vga.blt_buf( x+30, y+16, x+49, y+26, 0 ); } else { font_san.disp(x+30, y+6, soldierPtr->skill.combat_level, 1, x+49); } last_race_id_array[i] = soldierPtr->race_id; last_unit_id_array[i] = soldierPtr->unit_id; //------- set help parameters ---------// if( mouse.in_area(x, y, x+27, y+23) ) help.set_unit_help( soldierPtr->unit_id, 0, x, y, x+27, y+23 ); } else { if( last_race_id_array[i] != 0 || last_unit_id_array[i] != 0 ) { vga.blt_buf( x, y, x+49, y+27, 0 ); last_race_id_array[i] = 0; last_unit_id_array[i] = 0; } } } */ }
//## chea begin 170699 //---------- Begin of function Student::change_major -----------// //! //! courseCompleted = 0 by default //! int Student::change_major(int couCompleted) { //if 1 is passed to courseCompleted then the student must change major. //----- relocate the student from student_array -----// int major = player_school.get_random_major(student_level); // ug yr1 student registered in General Education Department if ( couCompleted ) { // go selected the major above err_when(major == 0 ); } else if ( department_recno==0 ) { err_when( student_level != UG_TRADITION && !is_nontradition_ug_group(student_level)); if ( year_in_program == 1 ) // change major after 1st year return 0; err_when(year_in_program!=2); // this student should be just promoted to yr2 } if ( department_recno == major ) return 0; // don't change err_when(major == 0); GeneralDepartment* oldDeptPtr = department_recno ? (GeneralDepartment *) department_array[department_recno] : &department_res.general_dept; Department* newDeptPtr = department_array[major]; int ods = oldDeptPtr->student_array.packed_size(); int nds = newDeptPtr->student_array.packed_size(); int oldStudentRecno = student_recno; if (student_recno <=0 ) { // info.debug_enroll++; oldDeptPtr->student_array.del(student_recno); return 0; } // add department_recno = major; newDeptPtr->student_array.linkin(this); // update ((Student*)(newDeptPtr->student_array.get()))->student_recno = newDeptPtr->student_array.recno(); newDeptPtr->student_array.student_count++; if ( audit_flag ) { File file; char fileName[123]; switch( student_level ) { case UG_TRADITION: strcpy( fileName, "TRADITION" ); break; case UG_NONTRADITION: strcpy( fileName, "NONTRADITION" ); break; case MASTER: strcpy( fileName, "MASTER" ); break; case DOCTOR: strcpy( fileName, "DOCTOR" ); break; } strcat( fileName, m.format(old_student_recno) ); strcat( fileName, ".txt" ); file.file_append( fileName ); file.file_seek(0, FILE_END); // Cohet if ( info.prerun_year ) { WRITE_NUM_FIELD( (&file), -1 ); } else { WRITE_NUM_FIELD( (&file), info.financial_year() ); } WRITE_FIELD_SEPARATOR( (&file) ); // Trimester switch( player_school.cur_trimester ) { case AUTUMN: WRITE_STR_FIELD( (&file), "A" ); break; case WINTER: WRITE_STR_FIELD( (&file), "W" ); break; case SUMMER: WRITE_STR_FIELD( (&file), "S" ); break; } // ID file_course_id++; WRITE_FIELD_SEPARATOR( (&file) ); WRITE_FIELD_SEPARATOR( (&file) ); WRITE_NUM_FIELD( (&file), 0 ); WRITE_FIELD_SEPARATOR( (&file) ); WRITE_STR_FIELD( (&file), "Status" ); WRITE_FIELD_SEPARATOR( (&file) ); WRITE_FIELD_SEPARATOR( (&file) ); WRITE_STR_FIELD( (&file), department_res[newDeptPtr->department_id]->name ); WRITE_RECORD_SEPARATOR( (&file) ); file.file_close(); } // remove oldDeptPtr->student_array.del(oldStudentRecno); int oods = oldDeptPtr->student_array.packed_size(); int onds = newDeptPtr->student_array.packed_size(); err_when(ods-1 != oods); err_when(nds+1 != onds); err_when( newDeptPtr->student_array[newDeptPtr->student_array.recno()]->department_recno != major); // this->department_recno = major; // for think_change_major(1) this->department_recno = major; // for think_change_major(1) //##testing return 1; }
//--------- Begin of function UnitB::get_object_range ---------// // // Get the full range of the area occupied by the object. // // <int> objXLoc, objYLoc - the location of the object // <int&> rangeX1, rangeY1, rangeX2, rangeY2 - vars for returning the range // void UnitB::get_object_range(int objXLoc, int objYLoc, int &rangeX1, int &rangeY1, int &rangeX2, int &rangeY2) { Location* locPtr; if(can_move(objXLoc, objYLoc)) { rangeX1 = objXLoc; rangeY1 = objYLoc; rangeX2 = objXLoc + loc_width - 1; rangeY2 = objYLoc + loc_height - 1; return; } //---------------------------------------// int* objLocFlag = (int*) mem_add_clear(loc_width*loc_height*sizeof(int)); int* objCargoRecno = (int*) mem_add_clear(loc_width*loc_height*sizeof(int)); int is, js; is = 0; int ind = 0; while(is<obj_loc_width()) { js = 0; while(js < obj_loc_height()) { locPtr = world.get_loc(objXLoc+is, objYLoc+js); ind = is*loc_height+js; if(mobile_type == UNIT_AIR) objCargoRecno[ind] = locPtr->air_cargo_recno; else objCargoRecno[ind] = locPtr->cargo_recno; objLocFlag[ind] = locPtr->loc_flag; if(!objLocFlag[ind] && objCargoRecno[ind] == sprite_recno) //it is myself objCargoRecno[ind] = 0; js++; } is++; } #ifdef DEBUG int checkCargo = 0; int checkFlag = 0; int index = 0; while(!checkCargo && !checkFlag && index < (loc_width*loc_height)) { checkCargo = objCargoRecno[index]; checkFlag = objLocFlag[index]; index++; } err_when(!checkCargo && !checkFlag); #endif //------ scan up -------// if(loc_width == 1 && loc_height == 1) { for( rangeY1=((objYLoc>=1)?(objYLoc-1):0) ; rangeY1>=0 ; rangeY1-- ) { if((world.get_loc(objXLoc, rangeY1)->loc_flag) != objLocFlag[0] || (mobile_type == UNIT_AIR ? (world.get_loc(objXLoc, rangeY1)->air_cargo_recno != objCargoRecno[0]) : (world.get_loc(objXLoc, rangeY1)->cargo_recno != objCargoRecno[0]))) { rangeY1++; // go back to the last one which is valid break; } } //------ scan down -------// for( rangeY2=((objYLoc<MAX_WORLD_Y_LOC-1)?(objYLoc+1):(MAX_WORLD_Y_LOC-1)) ; rangeY2<MAX_WORLD_Y_LOC ; rangeY2++ ) { if((world.get_loc(objXLoc, rangeY2)->loc_flag ) != objLocFlag[0] || (mobile_type == UNIT_AIR ? (world.get_loc(objXLoc, rangeY2)->air_cargo_recno != objCargoRecno[0]) : (world.get_loc(objXLoc, rangeY2)->cargo_recno != objCargoRecno[0]))) { rangeY2--; // go back to the last one which is valid break; } } //------ scan left -------// for( rangeX1=((objXLoc>=1)?(objXLoc-1):0) ; rangeX1>=0 ; rangeX1-- ) { if((world.get_loc(rangeX1, objYLoc)->loc_flag ) != objLocFlag[0] || (mobile_type == UNIT_AIR ? (world.get_loc(rangeX1, objYLoc)->air_cargo_recno != objCargoRecno[0]) : (world.get_loc(rangeX1, objYLoc)->cargo_recno != objCargoRecno[0]))) { rangeX1++; // go back to the last one which is valid break; } } //------ scan right -------// for( rangeX2=((objXLoc<MAX_WORLD_X_LOC-1)?(objXLoc+1):(MAX_WORLD_X_LOC-1)) ; rangeX2<MAX_WORLD_X_LOC ; rangeX2++ ) { if((world.get_loc(rangeX2, objYLoc)->loc_flag ) != objLocFlag[0] || (mobile_type == UNIT_AIR ? (world.get_loc(rangeX2, objYLoc)->air_cargo_recno != objCargoRecno[0]) : (world.get_loc(rangeX2, objYLoc)->cargo_recno != objCargoRecno[0]))) { rangeX2--; // go back to the last one which is valid break; } } } else //2 x 2 BUGHERE: only for 2x2 but not for other size other than 2x2 and 1x1 ( 3x3 may not work) { //it is very hard coded ! //scan up// if(objCargoRecno[0] == objCargoRecno[(loc_width-1)*loc_height] && objLocFlag[0] == objLocFlag[(loc_width-1)*loc_height]) { if(objCargoRecno[0] && (objLocFlag[0] & LOCATE_BLOCK_MASK)) { for(rangeY1=((objYLoc>=1)?(objYLoc-1):0); rangeY1 >= 0; rangeY1--) { if((world.get_loc(objXLoc, rangeY1)->loc_flag ) != objLocFlag[0] || (mobile_type == UNIT_AIR ? (world.get_loc(objXLoc, rangeY1)->air_cargo_recno != objCargoRecno[0]) : (world.get_loc(objXLoc, rangeY1)->cargo_recno != objCargoRecno[0]))) { rangeY1++; break; } } } else rangeY1 = objYLoc; } else { int tmpRangeY1, tmpRangeY2; if(objCargoRecno[0] && (objLocFlag[0] & LOCATE_BLOCK_MASK)) { for(tmpRangeY1=((objYLoc>=1)?(objYLoc-1):0); tmpRangeY1 >= 0; tmpRangeY1--) { if((world.get_loc(objXLoc, tmpRangeY1)->loc_flag ) != objLocFlag[0] || (mobile_type == UNIT_AIR ? (world.get_loc(objXLoc, tmpRangeY1)->air_cargo_recno != objCargoRecno[0]) : (world.get_loc(objXLoc, tmpRangeY1)->cargo_recno != objCargoRecno[0]))) { tmpRangeY1++; break; } } } else tmpRangeY1 = objYLoc; if(objCargoRecno[(loc_width-1)*loc_height] && (objLocFlag[(loc_width-1)*loc_height] & LOCATE_BLOCK_MASK)) { for(tmpRangeY2=((objYLoc>=1)?(objYLoc-1):0); tmpRangeY2 >= 0; tmpRangeY2--) { if((world.get_loc(objXLoc+loc_width-1, tmpRangeY2)->loc_flag ) != objLocFlag[(loc_width-1)*loc_height] || (mobile_type == UNIT_AIR ? (world.get_loc(objXLoc+loc_width-1, tmpRangeY2)->air_cargo_recno != objCargoRecno[(loc_width-1)*loc_height]) : (world.get_loc(objXLoc+loc_width-1, tmpRangeY2)->cargo_recno != objCargoRecno[(loc_width-1)*loc_height]))) { tmpRangeY2++; break; } } } else tmpRangeY2 = objYLoc; rangeY1 = min(tmpRangeY1, tmpRangeY2); } //scan down// if(objCargoRecno[loc_height-1] == objCargoRecno[loc_width*loc_height-1] && objLocFlag[loc_height-1] == objLocFlag[loc_width*loc_height-1]) { if(objCargoRecno[loc_height-1] && (objLocFlag[loc_height-1] & LOCATE_BLOCK_MASK)) { for(rangeY2=((objYLoc+loc_height<MAX_WORLD_Y_LOC)?objYLoc+loc_height:MAX_WORLD_Y_LOC-1); rangeY2<MAX_WORLD_Y_LOC; rangeY2++) { if((world.get_loc(objXLoc, rangeY2)->loc_flag ) != objLocFlag[loc_height-1] || (mobile_type == UNIT_AIR ? (world.get_loc(objXLoc, rangeY2)->air_cargo_recno != objCargoRecno[loc_height-1]) : (world.get_loc(objXLoc, rangeY2)->cargo_recno != objCargoRecno[loc_height-1]))) { rangeY2--; break; } } } else rangeY2 = objYLoc+loc_height-1; } else { int tmpRangeY1, tmpRangeY2; if(objCargoRecno[loc_height-1] && (objLocFlag[loc_height-1] & LOCATE_BLOCK_MASK)) { for(tmpRangeY1=((objYLoc+loc_height<MAX_WORLD_Y_LOC)?objYLoc+loc_height:MAX_WORLD_Y_LOC-1); tmpRangeY1<MAX_WORLD_Y_LOC; tmpRangeY1++) { if((world.get_loc(objXLoc, tmpRangeY1)->loc_flag ) != objLocFlag[loc_height-1] || (mobile_type == UNIT_AIR ? (world.get_loc(objXLoc, tmpRangeY1)->air_cargo_recno != objCargoRecno[loc_height-1]) : (world.get_loc(objXLoc, tmpRangeY1)->cargo_recno != objCargoRecno[loc_height-1]))) { tmpRangeY1--; break; } } } else tmpRangeY1 = objYLoc+loc_height-1; if(objCargoRecno[loc_width*loc_height-1] && (objLocFlag[loc_width*loc_height-1] & LOCATE_BLOCK_MASK)) { for(tmpRangeY2=((objYLoc+loc_height<MAX_WORLD_Y_LOC)?objYLoc+loc_height:MAX_WORLD_Y_LOC-1); tmpRangeY2<MAX_WORLD_Y_LOC; tmpRangeY2++) { if((world.get_loc(objXLoc+loc_width-1, tmpRangeY2)->loc_flag ) != objLocFlag[loc_width*loc_height-1] || (mobile_type == UNIT_AIR ? (world.get_loc(objXLoc+loc_width-1, tmpRangeY2)->air_cargo_recno != objCargoRecno[loc_width*loc_height-1]) : (world.get_loc(objXLoc+loc_width-1, tmpRangeY2)->cargo_recno != objCargoRecno[loc_width*loc_height-1]))) { tmpRangeY2--; break; } } } else tmpRangeY2 = objYLoc+loc_height-1; rangeY2 = max(tmpRangeY1, tmpRangeY2); } //scan left// if(objCargoRecno[0] == objCargoRecno[loc_height-1] && objLocFlag[0] == objLocFlag[loc_height-1]) { if(objCargoRecno[0] && (objLocFlag[0] & LOCATE_BLOCK_MASK)) { for(rangeX1=((objXLoc>=1)?(objXLoc-1):0); rangeX1 >= 0; rangeX1--) { if((world.get_loc(rangeX1, objYLoc)->loc_flag ) != objLocFlag[0] || (mobile_type == UNIT_AIR ? (world.get_loc(rangeX1, objYLoc)->air_cargo_recno != objCargoRecno[0]) : (world.get_loc(rangeX1, objYLoc)->cargo_recno != objCargoRecno[0]))) { rangeX1++; break; } } } else rangeX1 = objXLoc; } else { int tmpRangeX1, tmpRangeX2; if(objCargoRecno[0] && (objLocFlag[0] & LOCATE_BLOCK_MASK)) { for(tmpRangeX1=((objXLoc>=1)?(objXLoc-1):0); tmpRangeX1>=0; tmpRangeX1--) { if((world.get_loc(tmpRangeX1, objYLoc)->loc_flag ) != objLocFlag[0] || (mobile_type == UNIT_AIR ? (world.get_loc(tmpRangeX1, objYLoc)->air_cargo_recno != objCargoRecno[0]): (world.get_loc(tmpRangeX1, objYLoc)->cargo_recno != objCargoRecno[0]))) { tmpRangeX1++; break; } } } else tmpRangeX1 = objXLoc; if(objCargoRecno[loc_height-1] && (objLocFlag[loc_height-1] & LOCATE_BLOCK_MASK)) { for(tmpRangeX2=((objXLoc>=1)?(objXLoc-1):0); tmpRangeX2>=0; tmpRangeX2--) { if((world.get_loc(tmpRangeX2, objYLoc+loc_height-1)->loc_flag ) != objLocFlag[loc_height-1] || (mobile_type == UNIT_AIR ? (world.get_loc(tmpRangeX2, objYLoc+loc_height-1)->air_cargo_recno != objCargoRecno[loc_height-1]):(world.get_loc(tmpRangeX2, objYLoc+loc_height-1)->cargo_recno != objCargoRecno[loc_height-1]))) { tmpRangeX2++; break; } } } else tmpRangeX2 = objXLoc; rangeX1 = min(tmpRangeX1, tmpRangeX2); } //scan right// if(objCargoRecno[(loc_width-1)*loc_height] == objCargoRecno[loc_width*loc_height-1] && objLocFlag[(loc_width-1)*loc_height] == objLocFlag[loc_width*loc_height-1]) { if(objCargoRecno[(loc_width-1)*loc_height] && (objLocFlag[(loc_width-1)*loc_height] & LOCATE_BLOCK_MASK)) { for(rangeX2=((objXLoc+loc_width<MAX_WORLD_X_LOC)?objXLoc+loc_width:MAX_WORLD_X_LOC-1); rangeX2<MAX_WORLD_X_LOC; rangeX2++) { if((world.get_loc(rangeX2, objYLoc)->loc_flag ) != objLocFlag[(loc_width-1)*loc_height] || (mobile_type == UNIT_AIR ? (world.get_loc(rangeX2, objYLoc)->air_cargo_recno != objCargoRecno[(loc_width-1)*loc_height]):(world.get_loc(rangeX2, objYLoc)->cargo_recno != objCargoRecno[(loc_width-1)*loc_height]))) { rangeX2--; break; } } } else rangeX2 = objXLoc+loc_width-1; } else { int tmpRangeX1, tmpRangeX2; if(objCargoRecno[(loc_width-1)*loc_height] && (objLocFlag[(loc_width-1)*loc_height] & LOCATE_BLOCK_MASK)) { for(tmpRangeX1 = ((objXLoc+loc_width<MAX_WORLD_X_LOC)?objXLoc+loc_width:MAX_WORLD_X_LOC-1); tmpRangeX1<MAX_WORLD_X_LOC; tmpRangeX1++) { if((world.get_loc(tmpRangeX1, objYLoc)->loc_flag ) != objLocFlag[(loc_width-1)*loc_height] || (mobile_type == UNIT_AIR ? (world.get_loc(tmpRangeX1, objYLoc)->air_cargo_recno != objCargoRecno[(loc_width-1)*loc_height]):(world.get_loc(tmpRangeX1, objYLoc)->cargo_recno != objCargoRecno[(loc_width-1)*loc_height]))) { tmpRangeX1--; break; } } } else tmpRangeX1 = objXLoc+loc_width-1; if(objCargoRecno[loc_width*loc_height-1] && (objLocFlag[loc_width*loc_height-1] & LOCATE_BLOCK_MASK)) { for(tmpRangeX2 = ((objXLoc+loc_width<MAX_WORLD_X_LOC)?objXLoc+loc_width:MAX_WORLD_X_LOC-1); tmpRangeX2<MAX_WORLD_X_LOC; tmpRangeX2++) { if((world.get_loc(tmpRangeX2, objYLoc+loc_height-1)->loc_flag ) != objLocFlag[loc_width*loc_height-1] || world.get_loc(tmpRangeX2, objYLoc+loc_height-1)->cargo_recno != objCargoRecno[loc_width*loc_height-1]) { tmpRangeX2--; break; } } } else tmpRangeX2 = objXLoc+loc_width-1; rangeX2 = max(tmpRangeX1, tmpRangeX2); } } rangeX1=max(rangeX1, 0); rangeY1=max(rangeY1, 0); rangeX2=min(rangeX2, MAX_WORLD_X_LOC-1); rangeY2=min(rangeY2, MAX_WORLD_Y_LOC-1); err_when((rangeX2-rangeX1+1) > 30); err_when((rangeY2-rangeY1+1) > 30); mem_del(objLocFlag); mem_del(objCargoRecno); }
//--------- Begin of function SiteArray::generate_raw_site ----------// // // Generate raw sites. This function is both called at the beginning // of a game and when existing raw sites are being used up. // // [int] rawGenCount - no. of raw sites to be generated. // (if this is not given, it will use the existing std_raw_site_count) // void SiteArray::generate_raw_site(int rawGenCount) { if( rawGenCount ) std_raw_site_count = rawGenCount; // use this number for determing whether new sites should emerge in the future #define MAX_RAW_REGION 3 // maximum no. of regions that has raw sites #define SMALLEST_RAW_REGION 50 // only put raw on the region if its size is larger than this #define REGION_SIZE_PER_RAW 100 //----- count the no. of existing raw sites -------// Site* sitePtr; int existRawSiteCount=0; int i; for( i=size() ; i>0 ; i-- ) { if( site_array.is_deleted(i) ) continue; sitePtr = site_array[i]; if( sitePtr->site_type == SITE_RAW && sitePtr->reserve_qty >= EXIST_RAW_RESERVE_QTY ) { existRawSiteCount++; } } if( existRawSiteCount >= std_raw_site_count ) return; //----- check which regions are valid for raw sites -----// int regionCount = MIN( MAX_RAW_REGION, region_array.region_info_count ); int validRegionCount, totalValidSize=0; RegionInfo* regionInfo; for( validRegionCount=0 ; validRegionCount<regionCount ; validRegionCount++ ) { regionInfo = region_array.get_sorted_region(validRegionCount+1); if( regionInfo->region_type != REGION_LAND ) continue; if( regionInfo->region_size < SMALLEST_RAW_REGION ) break; totalValidSize += regionInfo->region_size; } if( validRegionCount==0 ) // valid regions are those that are big enough to put raw sites return; //----- count the no. of existing raw sites in each ragion ------// int regionId; char regionRawCountArray[MAX_REGION]; memset( regionRawCountArray, 0, sizeof(regionRawCountArray) ); for( i=size() ; i>0 ; i-- ) { if( site_array.is_deleted(i) ) continue; sitePtr = site_array[i]; if( sitePtr->site_type == SITE_RAW && sitePtr->reserve_qty >= EXIST_RAW_RESERVE_QTY ) { regionId = world.get_region_id(sitePtr->map_x_loc, sitePtr->map_y_loc); regionRawCountArray[regionId-1]++; } } //--------- generate raw sites now ----------// int avgValidSize = MIN( 10000, totalValidSize / std_raw_site_count ); int j, createCount; err_when( validRegionCount > region_array.region_info_count || validRegionCount > MAX_RAW_REGION ); for( int k=0 ; k<10 ; k++ ) // one loop may not be enough to generate all raw sites, have more loops to make sure all are generated { for( i=0 ; i<regionCount ; i++ ) { regionInfo = region_array.get_sorted_region(i+1); if( regionInfo->region_type != REGION_LAND ) continue; if( regionInfo->region_size < SMALLEST_RAW_REGION ) break; createCount = regionInfo->region_size / avgValidSize; createCount = MAX(1, createCount); //--------- create now --------// for( j=regionRawCountArray[regionInfo->region_id-1] ; j<createCount ; j++ ) // if currently there are already some, don't create new ones { if( create_raw_site(regionInfo->region_id) ) { if( ++existRawSiteCount == std_raw_site_count ) return; } } } } }
TutorInfo* Tutor::operator[](int recNo) { err_when( recNo < 1 || recNo > tutor_count ); return tutor_info_array + recNo - 1; }
//--------- Begin of function SiteArray::create_raw_site ----------// // // <int> regionId - if this parameter is given, the raw site // will be built on this region. // [int] townRecno - if this parameter is given, the raw site // will be built near this town. // // return: <int> >0 - the recno of the site // 0 - no site is added // int SiteArray::create_raw_site(int regionId, int townRecno) { //-------- count the no. of each raw material -------// Site* sitePtr; short rawCountArray[MAX_RAW]; memset( rawCountArray, 0, sizeof(rawCountArray) ); int i; for( i=size(); i>0 ; i-- ) { if( site_array.is_deleted(i) ) continue; sitePtr = site_array[i]; if( sitePtr->site_type == SITE_RAW ) { err_when( sitePtr->object_id < 1 || sitePtr->object_id > MAX_RAW ); rawCountArray[ sitePtr->object_id-1 ]++; } } //---- find the minimum raw count ----// int minCount=0xFFFF; for( i=0 ; i<MAX_RAW ; i++ ) { if( rawCountArray[i] < minCount ) minCount = rawCountArray[i]; } //----- pick a raw material type -----// int rawId = misc.random(MAX_RAW)+1; for( i=0 ; i<MAX_RAW ; i++ ) { if( ++rawId > MAX_RAW ) rawId = 1; if( rawCountArray[rawId-1] == minCount ) // don't use this raw type unless it is one of the less available ones. break; } //--------- create the raw site now ------// int locX1, locY1, locX2, locY2; int maxTries; int siteWidth = raw_res[rawId]->map_loc_width; int siteHeight = raw_res[rawId]->map_loc_height; if( townRecno ) { // ####### begin Gilbert 26/5 ########// // #define MAX_TOWN_SITE_DISTANCE (MAX_LINKED_FIRM_TOWN-STD_TOWN_LOC_WIDTH) const int maxTownSiteDistance = world.effective_distance(FIRM_MINE, 0); Town* townPtr = town_array[townRecno]; locX1 = townPtr->center_x - maxTownSiteDistance - (siteWidth-1)/2; // (siteWidth-1)/2 is the distance from mine center_x to mine loc_x1 locX2 = townPtr->center_x + maxTownSiteDistance + (siteWidth+1)/2; locY1 = townPtr->center_y - maxTownSiteDistance - (siteHeight-1)/2; locY2 = townPtr->center_y + maxTownSiteDistance + (siteHeight+1)/2; // ####### end Gilbert 26/5 ########// if(locX1<0) locX1 = 0; else if(locX2>=MAX_WORLD_X_LOC) locX2 = MAX_WORLD_X_LOC-1; if(locY1<0) locY1 = 0; else if(locY2>=MAX_WORLD_Y_LOC) locY2 = MAX_WORLD_Y_LOC-1; maxTries = (locX2-locX1+1)*(locY2-locY1+1); regionId = townPtr->region_id; } else { locX1 = 0; locY1 = 0; locX2 = MAX_WORLD_X_LOC-1; locY2 = MAX_WORLD_Y_LOC-1; maxTries = 10000; } //----- randomly locate a space to add the site -----// int mineSize = firm_res[FIRM_MINE]->loc_width; err_when( firm_res[FIRM_MINE]->loc_height > mineSize ); // assume square size if( world.locate_space_random(locX1, locY1, locX2, locY2, mineSize+INTER_PLACE_SPACE*2, mineSize+INTER_PLACE_SPACE*2, maxTries, regionId, 1) ) { if( world.can_build_firm( locX1+INTER_PLACE_SPACE, locY1+INTER_PLACE_SPACE, FIRM_MINE) ) { int reserveQty = MAX_RAW_RESERVE_QTY * (60 + misc.random(40)) / 100; return add_site( locX1+INTER_PLACE_SPACE, locY1+INTER_PLACE_SPACE, SITE_RAW, rawId, reserveQty ); // xLoc+1 & yLoc+1 as the located size is 3x3, the raw site is at the center of it } } return 0; }
unsigned GetA::detect_key() { if( !enable_flag ) return 0; err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); if( mouse.is_key_event() ) { unsigned keyCode = mouse.key_code; unsigned shiftPressed = mouse.event_skey_state & SHIFT_KEY_MASK; // printable character if( keyCode >= ' ' && keyCode <= 0xff ) { if( strlen(input_field)-(mark_end() - mark_begin()) < field_len) { // insert character memmove( input_field+mark_begin()+1, input_field+mark_end(), strlen(input_field)-mark_end()+1); input_field[mark_begin()] = keyCode; cursor_pos = mark_begin()+1; clear_select(); } err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); if( hide_flag && strlen(input_field) ) { hide_field[strlen(input_field)-1] = HIDE_CHAR; hide_field[strlen(input_field)] = 0; } return keyCode; } else if( keyCode == KEY_DEL ) { if( is_select() ) { err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); // erase selected area memmove( input_field+mark_begin(), input_field+mark_end(), strlen(input_field)-mark_end()+1); cursor_pos = mark_begin(); clear_select(); } else { if(strlen(input_field) > cursor_pos) { err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); memmove( input_field+cursor_pos, input_field+cursor_pos+1, strlen(input_field)-cursor_pos); err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); } } err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); if( hide_flag ) { hide_field[strlen(input_field)] = 0; } return keyCode; } else if( keyCode == KEY_BACK_SPACE ) { if( is_select() ) { err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); // erase selected area memmove( input_field+mark_begin(), input_field+mark_end(), strlen(input_field)-mark_end()+1); cursor_pos = mark_begin(); clear_select(); } else { if(cursor_pos > 0) { err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); memmove( input_field+cursor_pos-1, input_field+cursor_pos, strlen(input_field)-cursor_pos+1); cursor_pos--; err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); clear_select(); } } err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); if( hide_flag ) { hide_field[strlen(input_field)] = 0; } return keyCode; } if( keyCode == KEY_LEFT ) { if(cursor_pos > 0) cursor_pos--; if( !shiftPressed ) clear_select(); err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); return keyCode; } if( keyCode == KEY_RIGHT ) { if(cursor_pos < strlen(input_field)) cursor_pos++; if( !shiftPressed ) clear_select(); err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); return keyCode; } if( keyCode == KEY_HOME) { cursor_pos = 0; if( !shiftPressed ) clear_select(); err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); return keyCode; } if( keyCode == KEY_END) { cursor_pos = strlen(input_field); if( !shiftPressed ) clear_select(); err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); return keyCode; } if( esc_key_flag && keyCode == KEY_ESC ) { // if esc_key_flag is 0 and ESC key pressed, still return 0 clear(); return keyCode; } if( keyCode == KEY_RETURN || keyCode == KEY_UP || keyCode == KEY_DOWN || keyCode == KEY_TAB ) { return keyCode; } } return 0; }
// ------------ begin of function RockRes::get_bitmap_info -----------// RockBitmapInfo *RockRes::get_bitmap_info(short rockBitmapRecno) { err_when( rockBitmapRecno <= 0 || rockBitmapRecno > rock_bitmap_count); return rock_bitmap_array + rockBitmapRecno - 1; }