//--------- Begin of function Unit::resign ---------// // // Resign the unit. // void Unit::resign(int remoteAction) { if( !remoteAction && remote.is_enable() ) { // packet structure : <unit recno> <nation recno> short *shortPtr = (short *)remote.new_send_queue_msg(MSG_UNIT_RESIGN, 2*sizeof(short)); *shortPtr = sprite_recno; shortPtr[1] = nation_array.player_recno; return; } //---- increase the wandering count when a unit is disbanded ----// if( is_human() ) town_array.race_wander_pop_array[race_id-1] += 2; // disbanding one resulted in two wandering units to make the effect more significant //--- if the unit is visible, stop the current order ----// if( is_visible() ) stop_order(); //--- if the spy is resigned by an enemy, display a message ---// if( spy_recno && true_nation_recno() != nation_recno ) // the spy is cloaked in an enemy nation when it is resigned { //------ decrease reputation ------// nation_array[true_nation_recno()]->change_reputation((float)-SPY_KILLED_REPUTATION_DECREASE); //------- add news message -------// // #### begin Gilbert 24/12 ######// // if( nation_recno == nation_array.player_recno ) // display when the player has revealed an enemy spy // info.spy_execute = 1; // #### end Gilbert 24/12 ######// if( true_nation_recno() == nation_array.player_recno || // display when the player's spy is revealed or the player has revealed an enemy spy nation_recno == nation_array.player_recno ) { //--- If a spy is caught, the spy's nation's reputation wil decrease ---// news_array.spy_killed(spy_recno); } } //----------------------------------------------// if( rank_id == RANK_GENERAL ) // if this is a general, news_array.general_die() will be called, set news_add_flag to 0 to suppress the display of thew news news_array.news_add_flag=0; unit_array.del( sprite_recno ); news_array.news_add_flag=1; }
void Unit::deinit_unit_id() { if( sys.signal_exit_flag ) return; //-----------------------------------------// UnitInfo *unitInfo = unit_res[unit_id]; if( nation_recno ) { if( rank_id != RANK_KING ) unitInfo->dec_nation_unit_count(nation_recno); if( rank_id == RANK_GENERAL ) unitInfo->dec_nation_general_count(nation_recno); } //--------- if the unit is a spy ----------// // // A spy has double identity and is counted // by both the true controlling nation and // the deceiving nation. // //-----------------------------------------// if( spy_recno && true_nation_recno() != nation_recno ) { err_when( !race_id ); int trueNationRecno = true_nation_recno(); if( rank_id != RANK_KING ) unitInfo->dec_nation_unit_count(trueNationRecno); if( rank_id == RANK_GENERAL ) unitInfo->dec_nation_general_count(trueNationRecno); } //--------- decrease monster count ----------// // ####### begin Gilbert 24/3 #########// // if( unit_res[unit_id]->unit_class == UNIT_CLASS_MONSTER ) if( unit_res[unit_id]->class_info.monster_side ) // ####### end Gilbert 24/3 #########// { unit_res.mobile_monster_count--; err_when( unit_res.mobile_monster_count < 0 ); } }
//--------- Begin of function Unit::can_spy_change_nation ---------// // // Whether the spy unit can change its spy cloak now or not. // // If there are enemy nearby, the unit cannot change its cloak. // int Unit::can_spy_change_nation() { if( !spy_recno ) return 0; //--------------------------------------------// int xLoc1=cur_x_loc()-SPY_ENEMY_RANGE, yLoc1=cur_y_loc()-SPY_ENEMY_RANGE; int xLoc2=cur_x_loc()+SPY_ENEMY_RANGE, yLoc2=cur_y_loc()+SPY_ENEMY_RANGE; xLoc1 = max(0, xLoc1); yLoc1 = max(0, yLoc1); xLoc2 = min(MAX_WORLD_X_LOC-1, xLoc2); yLoc2 = min(MAX_WORLD_Y_LOC-1, yLoc2); int xLoc, yLoc; int unitRecno, trueNationRecno = true_nation_recno(); Location* locPtr; for( yLoc=yLoc1 ; yLoc<=yLoc2 ; yLoc++ ) { locPtr = world.get_loc(xLoc1, yLoc); for( xLoc=xLoc1 ; xLoc<=xLoc2 ; xLoc++, locPtr++ ) { if( locPtr->unit_recno(UNIT_LAND) ) unitRecno = locPtr->unit_recno(UNIT_LAND); else if( locPtr->unit_recno(UNIT_SEA) ) unitRecno = locPtr->unit_recno(UNIT_SEA); else if( locPtr->unit_recno(UNIT_AIR) ) unitRecno = locPtr->unit_recno(UNIT_AIR); else continue; if( unit_array.is_deleted(unitRecno) ) // the unit is dying, its recno is still in the location continue; Unit* unitPtr = unit_array[unitRecno]; if( unitPtr->true_nation_recno() != trueNationRecno && unitPtr->nation_recno != trueNationRecno ) { return 0; } } } return 1; }
//--------- Begin of function Unit::spy_menu_height ---------// // // Return the height of the spy menu. // int Unit::spy_menu_height() { if( !can_spy_change_nation() ) return 27; int cloakCount=1; Nation* nationPtr = nation_array[true_nation_recno()]; for( int i=1 ; i<=nation_array.size() ; i++ ) { if( nation_array.is_deleted(i) ) continue; if( i==nation_recno || nationPtr->get_relation(i)->has_contact ) cloakCount++; } if( cloakCount > 4 ) return 47; else return 27; }
//--------- Begin of function Unit::reward ---------// // // <int> rewardNationRecno - the nation which does this reward. // void Unit::reward(int rewardNationRecno) { if( nation_array[rewardNationRecno]->cash < REWARD_COST ) return; //--------- if this is a spy ---------// if( spy_recno && true_nation_recno() == rewardNationRecno ) // if the spy's owning nation rewards the spy { spy_array[spy_recno]->change_loyalty(REWARD_LOYALTY_INCREASE); } //--- if this spy's nation_recno & true_nation_recno() are both == rewardNationRecno, it's true loyalty and cloaked loyalty will both be increased ---// if( nation_recno == rewardNationRecno ) { total_reward += REWARD_COST; change_loyalty(REWARD_LOYALTY_INCREASE); } nation_array[rewardNationRecno]->add_expense(EXPENSE_REWARD_UNIT, (float)REWARD_COST); }
int Unit::think_reward() { Nation* ownNation = nation_array[nation_recno]; //----------------------------------------------------------// // The need to secure high loyalty on this unit is based on: // -its skill // -its combat level // -soldiers commanded by this unit //----------------------------------------------------------// if( spy_recno && true_nation_recno() == nation_recno ) // if this is a spy of ours { return 0; // Spy::think_reward() will handle this. } int curLoyalty = loyalty; int neededLoyalty; //----- if this unit is on a mission ------/ if( ai_action_id ) { neededLoyalty = UNIT_BETRAY_LOYALTY+10; } //----- otherwise only reward soldiers and generals ------// else if( skill.skill_id == SKILL_LEADING ) { //----- calculate the needed loyalty --------// neededLoyalty = commanded_soldier_count()*5 + skill.skill_level; if( unit_mode == UNIT_MODE_OVERSEE ) // if this unit is an overseer { if( loyalty < UNIT_BETRAY_LOYALTY ) // if this unit's loyalty is < betrayel level, reward immediately { reward(nation_recno); // reward it immediatley if it's an overseer, don't check ai_should_spend() return 1; } neededLoyalty += 30; } neededLoyalty = MAX( UNIT_BETRAY_LOYALTY+10, neededLoyalty ); // 10 points above the betray loyalty level to prevent betrayal neededLoyalty = MIN( 100, neededLoyalty ); } else { return 0; } //------- if the loyalty is already high enough ------// if( curLoyalty >= neededLoyalty ) return 0; //---------- see how many cash & profit we have now ---------// int rewardNeedRating = neededLoyalty - curLoyalty; if( curLoyalty < UNIT_BETRAY_LOYALTY+5 ) rewardNeedRating += 50; if( ownNation->ai_should_spend(rewardNeedRating) ) { reward(nation_recno); return 1; } return 0; }
//--------- Begin of function Unit::process_ai --------// // // [int] forceExecute - whether force execute all AI functions // without checking day interavals. // (default: 0) // void Unit::process_ai() { err_when( !nation_recno ); //-*********** simulate aat ************-// #ifdef DEBUG if(debug_sim_game_type) return; #endif //-*********** simulate aat ************-// //------ the aggressive_mode of AI units is always 1 ------// aggressive_mode = 1; //------- handle Seek Path failures ------// if( ai_handle_seek_path_fail() ) return; //--- if it's a spy from other nation, don't control it ---// if( spy_recno && true_nation_recno() != nation_recno ) { //--- a random chance of the AI catching the spy and resign it ---// if( is_visible() && misc.random(365 * FRAMES_PER_DAY)==0 ) // if the unit stay outside for one year, it will get caught { stop2(); resign(COMMAND_AI); return; } if( !spy_array[spy_recno]->notify_cloaked_nation_flag ) // if notify_cloaked_nation_flag is 1, the nation will take it as its own spies return; } //----- think about rewarding this unit -----// if( race_id && rank_id != RANK_KING && info.game_date%5 == sprite_recno%5 ) { think_reward(); } //-----------------------------------------// if( !is_visible() ) return; //--- if the unit has stopped, but ai_action_id hasn't been reset ---// if( cur_action==SPRITE_IDLE && action_mode==ACTION_STOP && action_mode2==ACTION_STOP && ai_action_id ) { nation_array[nation_recno]->action_failure(ai_action_id, sprite_recno); err_when( ai_action_id ); // it should have been reset } //---- King flees under attack or surrounded by enemy ---// if( race_id && rank_id==RANK_KING ) { if( think_king_flee() ) return; } //---- General flees under attack or surrounded by enemy ---// if( race_id && rank_id==RANK_GENERAL && info.game_date%7 == sprite_recno%7 ) { if( think_general_flee() ) return; } //-- let Unit::next_day() process it process original_action_mode --// if( original_action_mode ) return; //------ if the unit is not stop right now ------// if( !is_ai_all_stop() ) { think_stop_chase(); return; } //-----------------------------------------// if( mobile_type==UNIT_LAND ) { if( ai_escape_fire() ) return; } //---------- if this is your spy --------// if( spy_recno && true_nation_recno()==nation_recno ) think_spy_action(); //------ if this unit is from a camp --------// if( home_camp_firm_recno ) { Firm* firmCamp = firm_array[home_camp_firm_recno]; int rc; if( rank_id == RANK_SOLDIER ) rc = firmCamp->worker_count < MAX_WORKER; else rc = !firmCamp->overseer_recno; if( rc ) { if( return_camp() ) return; } home_camp_firm_recno = 0; // the camp is already occupied by somebody } //----------------------------------------// if( race_id && rank_id==RANK_KING ) { think_king_action(); } else if( race_id && rank_id==RANK_GENERAL ) { think_general_action(); } else { if( unit_res[unit_id]->unit_class == UNIT_CLASS_WEAPON ) { if( info.game_date%15 == sprite_recno%15 ) // don't call too often as the action may fail and it takes a while to call the function each time { think_weapon_action(); //-- ships AI are called in UnitMarine --// } } else if( race_id ) { //--- if previous attempts for new action failed, don't call think_normal_human_action() so frequently then ---// if( ai_no_suitable_action ) { if( info.game_date%15 != sprite_recno%15 ) // don't call too often as the action may fail and it takes a while to call the function each time return; } //---------------------------------// if( !think_normal_human_action() ) { ai_no_suitable_action = 1; // set this flag so think_normal_human_action() won't be called continously if( !leader_unit_recno ) // only when the unit is not led by a commander { resign(COMMAND_AI); } else { ai_move_to_nearby_town(); } } } } }
//--------- Begin of function Unit::pay_expense ---------// // void Unit::pay_expense() { if( game.game_mode == GAME_TEST ) // no deduction in testing game return; if( !nation_recno ) return; //--- if it's a mobile spy or the spy is in its own firm, no need to pay salary here as Spy::pay_expense() will do that ---// // // -If your spies are mobile: // >your nation pays them 1 food and $5 dollars per month // // -If your spies are in an enemy's town or firm: // >the enemy pays them 1 food and the normal salary of their jobs. // // >your nation pays them $5 dollars per month. (your nation pays them no food) // // -If your spies are in your own town or firm: // >your nation pays them 1 food and $5 dollars per month // //------------------------------------------------------// if( spy_recno ) { if( is_visible() ) // the cost will be deducted in spy_array return; if( unit_mode == UNIT_MODE_OVERSEE && firm_array[unit_mode_para]->nation_recno == true_nation_recno() ) { return; } } //---------- if it's a human unit -----------// // // The unit is paid even during its training period in a town // //-------------------------------------------// Nation* nationPtr = nation_array[nation_recno]; if( unit_res[unit_id]->race_id > 0 ) { if( rank_id != RANK_KING ) { //---------- reduce cash -----------// if( nationPtr->cash > 0 ) { if( rank_id == RANK_SOLDIER ) nationPtr->add_expense( EXPENSE_MOBILE_UNIT, (float) SOLDIER_YEAR_SALARY / 365, 1 ); if( rank_id == RANK_GENERAL ) nationPtr->add_expense( EXPENSE_GENERAL, (float) GENERAL_YEAR_SALARY / 365, 1 ); } //---------- reduce food -----------// if( nationPtr->food > 0 ) nationPtr->consume_food((float) UNIT_FOOD_YEAR_CONSUMPTION / 365); else { if( info.game_date%NO_FOOD_LOYALTY_DECREASE_INTERVAL == 0 ) // decrease 1 loyalty point every 2 days change_loyalty(-1); } } } else if( unit_res[unit_id]->is_monster() ) { //--- currently not cost for monsters ----// } else //----- it's a non-human unit ------// { if( nationPtr->cash > 0 ) { int expenseType; switch(unit_res[unit_id]->unit_class) { case UNIT_CLASS_WEAPON: expenseType = EXPENSE_WEAPON; break; case UNIT_CLASS_SHIP: err_here(); // expenseType = EXPENSE_SHIP; break; case UNIT_CLASS_CARAVAN: expenseType = EXPENSE_CARAVAN; break; default: expenseType = EXPENSE_MOBILE_UNIT; } nationPtr->add_expense( expenseType, (float) unit_res[unit_id]->year_cost / 365, 1 ); } else // decrease hit points if the nation cannot pay the unit { if( unit_res[unit_id]->unit_class != UNIT_CLASS_CARAVAN ) // Even when caravans are not paid, they still stay in your service. { if( hit_points > 0 ) { hit_points--; if( hit_points < 0 ) hit_points = (float) 0; //--- when the hit points drop to zero and the unit is destroyed ---// if( hit_points==0 ) { if( nation_recno == nation_array.player_recno ) { int unitClass = unit_res[unit_id]->unit_class; // ###### begin Gilbert 24/3 #######// if( unitClass==UNIT_CLASS_WEAPON || unitClass==UNIT_CLASS_MONS_WEAPON ) news_array.weapon_ship_worn_out(unit_id, get_weapon_version()); // ###### end Gilbert 24/3 #######// else if( unitClass==UNIT_CLASS_SHIP ) news_array.weapon_ship_worn_out(unit_id, 0); } } } } } } }
//--------- Begin of function Unit::disp_button ---------// // void Unit::disp_button(int dispY1) { int x=INFO_X1; //---- if currently in the mode of selecting a unit to succeed the king ----// if( nation_array.player_recno && nation_recno == nation_array.player_recno && (~nation_array)->king_unit_recno == 0 ) { if( race_id ) button_succeed_king.paint( x, dispY1, 'A', "SUCCEED" ); return; } //------- display aggressive mode button ------// button_aggressive_mode.paint( x, dispY1, 'A', aggressive_mode ? (char*)"AGGRESS1" : (char*)"AGGRESS0" ); x += BUTTON_ACTION_WIDTH; //---------- only for human units ---------// // Reset all buttons, and activate them as-needed button_build.reset(); button_settle.reset(); button_promote.reset(); button_demote.reset(); button_reward.reset(); button_return_camp.reset(); // button_burn.reset(); // button_assign.reset(); if( unit_res[unit_id]->unit_class == UNIT_CLASS_HUMAN && race_id ) { int firmId; for( firmId=1; firmId<=MAX_FIRM_TYPE ; firmId++ ) { if( firm_res[firmId]->can_build(sprite_recno) ) break; } if( firmId<=MAX_FIRM_TYPE && nation_recno == nation_array.player_recno ) // a spy cannot build structure for another nation { button_build.paint( x, dispY1, 'A', "BUILD" ); x += BUTTON_ACTION_WIDTH; } //-------- settle button ----------// if( mobile_type==UNIT_LAND && rank_id != RANK_KING ) { button_settle.paint( x, dispY1, 'A', "SETTLE" ); x += BUTTON_ACTION_WIDTH; } //-------- promote/demote button --------// if( nation_recno == nation_array.player_recno ) // you can't promote your spy in other nation { if( rank_id==RANK_SOLDIER && skill.skill_id==SKILL_LEADING ) { if(unit_array.selected_count==1) { button_promote.paint( x, dispY1, 'A', "PROMOTE" ); x += BUTTON_ACTION_WIDTH; } } else if( rank_id == RANK_GENERAL ) { if( unit_array.selected_count==1 ) { button_demote.paint( x, dispY1, 'A', "DEMOTE" ); x += BUTTON_ACTION_WIDTH; } } } if( x+BUTTON_ACTION_WIDTH-5 > INFO_X2 ) { x = INFO_X1; dispY1 += BUTTON_ACTION_HEIGHT; } //------------ "reward" button ---------// if( nation_array.player_recno && is_own() && // Can only reward if the player is still alive. Can reward own spies (even when cloaked). rank_id != RANK_KING ) { button_reward.paint( x, dispY1, 'A', "REWARD" ); x += BUTTON_ACTION_WIDTH; if( x+BUTTON_ACTION_WIDTH-5 > INFO_X2 ) { x = INFO_X1; dispY1 += BUTTON_ACTION_HEIGHT; } } /* //-------- burn button ----------// if( skill.combat_level > BURN_COMBAT_LEVEL && mobile_type==UNIT_LAND ) { button_burn.paint_text( x, dispY1, "Burn" ); x += 60; } //-------- assign to firm button --------// if( mobile_type==UNIT_LAND ) { button_assign.paint_text( x, dispY1, "Assign" ); x+=60; } */ } //------ "Return Camp" button -------// if( home_camp_firm_recno && (unit_res[unit_id]->unit_class == UNIT_CLASS_HUMAN || unit_res[unit_id]->unit_class == UNIT_CLASS_WEAPON) && firm_array[home_camp_firm_recno]->region_id == region_id() ) { button_return_camp.paint( x, dispY1, 'A', "RETCAMP" ); x += BUTTON_ACTION_WIDTH; if( x+BUTTON_ACTION_WIDTH-5 > INFO_X2 ) { x = INFO_X1; dispY1 += BUTTON_ACTION_HEIGHT; } } //------- spy notify button ------// if( spy_recno && true_nation_recno() == nation_array.player_recno ) { int notifyFlag = spy_array[spy_recno]->notify_cloaked_nation_flag; button_spy_notify.paint( x, dispY1, 'A', notifyFlag ? (char*)"SPYNOTI1" : (char*)"SPYNOTI0" ); x += BUTTON_ACTION_WIDTH; if( x+BUTTON_ACTION_WIDTH-5 > INFO_X2 ) { x = INFO_X1; dispY1 += BUTTON_ACTION_HEIGHT; } button_spy_drop_identity.paint( x, dispY1, 'A', "NOSPY" ); } else { button_spy_notify.reset(); button_spy_drop_identity.reset(); } //---- display button for changing nation color scheme ----// if( sys.debug_session ) button_change_color.paint_text( INFO_X1, INFO_Y2-20, "Change Nation Color" ); }
//--------- Begin of function Unit::detect_spy_menu ---------// // void Unit::detect_spy_menu(int dispY1) { Nation* nationPtr = nation_array[true_nation_recno()]; int x=INFO_X1+80, y=dispY1+4, nationRecno, changeFlag=0; char canChangeAnyCloak = can_spy_change_nation(); char canChangeOwnCloak = canChangeAnyCloak; // change back to its own cloak if( true_nation_recno() != nation_recno ) canChangeOwnCloak = 1; if( !canChangeOwnCloak ) return; int i; for( i=1 ; i<=nation_array.size()+1 ; i++ ) { if( i > nation_array.size() ) { nationRecno = 0; } else { if( canChangeAnyCloak ) { if( nation_array.is_deleted(i) || !nationPtr->get_relation(i)->has_contact ) continue; } else { if( i!=nation_recno && i!=true_nation_recno() ) // only display the current cloaked nation and its true nation continue; } nationRecno = i; } //---------------------------// if( mouse.single_click(x, y, x+SPY_CLOAK_WIDTH-1, y+22) ) { changeFlag=1; break; } x+=SPY_CLOAK_WIDTH+4; if( x+SPY_CLOAK_WIDTH > INFO_X2 ) { x = INFO_X1+80; y += 22; } } if( !changeFlag ) return; //--- group changing the cloaks of all of your spies currently selected ---// Unit* unitPtr; for( i=unit_array.size() ; i>0 ; i-- ) { if( unit_array.is_deleted(i) ) continue; unitPtr = unit_array[i]; if( unitPtr->is_own_spy() && unitPtr->selected_flag ) unitPtr->spy_change_nation(nationRecno, COMMAND_PLAYER); } disp_spy_menu(dispY1, INFO_UPDATE); }
//--------- Begin of function Unit::disp_spy_menu ---------// // void Unit::disp_spy_menu(int dispY1, int refreshFlag) { err_when( !spy_recno ); static char lastCanChangeCloak; static short lastSpyMenuHeight, lastNationCount; char canChangeAnyCloak = can_spy_change_nation(); short spyMenuHeight = spy_menu_height(); //-- if the spy can always change back to its original color. So if it is currently cloaked as another nation, it should be able to revert back any time ---// char canChangeOwnCloak = canChangeAnyCloak; // change back to its own cloak if( true_nation_recno() != nation_recno ) canChangeOwnCloak = 1; //---------------------------------------------// if( canChangeOwnCloak != lastCanChangeCloak || spyMenuHeight != lastSpyMenuHeight || nation_array.nation_count != lastNationCount ) { lastCanChangeCloak = canChangeOwnCloak; lastSpyMenuHeight = spyMenuHeight; lastNationCount = nation_array.nation_count; info.disp(); return; } //---- if enemy nearby and cannot change cloak right now ---// if( !canChangeOwnCloak ) { if( refreshFlag==INFO_REPAINT ) { vga_util.d3_panel_up( INFO_X1, dispY1, INFO_X2, dispY1+26 ); font_san.center_put( INFO_X1, dispY1, INFO_X2-2, dispY1+26, _("Enemies Nearby") ); } return; } //---------------------------------------------// if( refreshFlag==INFO_REPAINT ) { vga_util.d3_panel_up( INFO_X1, dispY1, INFO_X2, dispY1+spyMenuHeight-1 ); font_san.put( INFO_X1+6, dispY1+6, _("Spy Cloak:") ); } Nation* nationPtr = nation_array[true_nation_recno()]; int x=INFO_X1+80, y=dispY1+4, nationColor; for( int i=1 ; i<=nation_array.size()+1 ; i++ ) { if( canChangeAnyCloak ) { if( i <= nation_array.size() ) // exclude independent town { if( nation_array.is_deleted(i) || !nationPtr->get_relation(i)->has_contact ) continue; } } else if( canChangeOwnCloak ) { if( i!=nation_recno && i!=true_nation_recno() ) // only display the current cloaked nation and its true nation continue; } else err_here(); //-----------------------------------// if( i>nation_array.size() ) // independent { nationColor = nation_array.nation_color_array[0]; } else { nationColor = nation_array[i]->nation_color; } vga_front.bar( x+2, y+2, x+SPY_CLOAK_WIDTH-3, y+16, nationColor ); if( i == nation_recno || (i==nation_array.size()+1 && nation_recno==0) ) { vga_front.rect( x, y, x+SPY_CLOAK_WIDTH-1, y+18, 2, V_YELLOW ); } else vga_front.rect( x, y, x+SPY_CLOAK_WIDTH-1, y+18, 2, VGA_GRAY+8 ); x+=SPY_CLOAK_WIDTH+4; if( x+SPY_CLOAK_WIDTH > INFO_X2 ) { x = INFO_X1+80; y += 22; } } }
//--------- Begin of function Unit::disp_unit_info ---------// // // Display the skill information of the people in the town. // // <int> dispY1 - the top y coordination of the info area // <int> refreshFlag - refresh flag // void Unit::disp_unit_info(int dispY1, int refreshFlag) { #ifdef DEBUG if(debug2_enable_flag) { if(unit_res[unit_id]->unit_class == UNIT_CLASS_MONSTER) { int x=INFO_X1+4, y=dispY1+20; y+=20; font_san.field( x, y, " " , x+2, sprite_recno, 1, INFO_X2-2, refreshFlag); font_san.field( x+20, y, " " , x+22, next_x_loc(), 1, INFO_X2-2, refreshFlag); font_san.field( x+50, y, " " , x+52, next_y_loc(), 1, INFO_X2-2, refreshFlag); font_san.field( x+70, y, " " , x+72, nation_recno, 1, INFO_X2-2, refreshFlag); font_san.field( x+100, y, " " , x+102, action_mode, 1, INFO_X2-2, refreshFlag); font_san.field( x+120, y, " " , x+122, action_para, 1, INFO_X2-2, refreshFlag); font_san.field( x+140, y, " " , x+142, action_x_loc, 1, INFO_X2-2, refreshFlag); font_san.field( x+160, y, " " , x+162, action_y_loc, 1, INFO_X2-2, refreshFlag); y-=20; font_san.field( x+100, y, " " , x+102, action_mode2, 1, INFO_X2-2, refreshFlag); font_san.field( x+120, y, " " , x+122, action_para2, 1, INFO_X2-2, refreshFlag); font_san.field( x+140, y, " " , x+142, action_x_loc2, 1, INFO_X2-2, refreshFlag); font_san.field( x+160, y, " " , x+162, action_y_loc2, 1, INFO_X2-2, refreshFlag); y-=20; font_san.field( x+160, y, " " , x+162, cur_action, 1, INFO_X2-2, refreshFlag); } } #endif //--------------------------------------------// if( !race_id ) // if it's not a human unit, don't display anything return; if( refreshFlag==INFO_REPAINT ) vga_util.d3_panel_up( INFO_X1, dispY1, INFO_X2, dispY1+87 ); int x=INFO_X1+4, y=dispY1+4; String str; //--------- display loyalty ---------// if( rank_id != RANK_KING && (nation_recno || spy_recno) ) { if( spy_recno && // only display spy loyalty instead of unit loyalty if this is a spy and this spy is ours true_nation_recno() == nation_array.player_recno ) { font_san.field( x, y, _("Loyalty"), x+92, spy_array[spy_recno]->spy_loyalty, 1, INFO_X2-2, refreshFlag); } else if( nation_recno ) { info.disp_loyalty( x, y, x+92, loyalty, target_loyalty, nation_recno, refreshFlag ); } y+=16; } //--------- display combat level ----------// font_san.field( x, y, _("Combat") , x+92, skill.combat_level, 1, INFO_X2-2, refreshFlag); y+=16; //-------- display skill level ---------// if( skill.skill_id ) { if( refreshFlag == INFO_REPAINT ) font_san.field( x, y, skill.skill_des(), x+92, skill.skill_level , 1, INFO_X2-2, refreshFlag); else font_san.field( x, y, skill.skill_des(), x+92, skill.skill_level , 1, INFO_X2-2, refreshFlag); y+=16; } //------- display spying skill if the unit is a spy -----// if( spy_recno && spy_array[spy_recno]->true_nation_recno == nation_array.player_recno ) // only spies of the player's nation can see the spy skill details { font_san.field( x, y, _("Spying"), x+92, spy_array[spy_recno]->spy_skill, 1, INFO_X2-2, refreshFlag); y+=16; } //--------- display debug info ---------// if( !is_civilian() && rank_id != RANK_KING ) font_san.field( x, y, _("Contribution"), x+92, nation_contribution, 1, INFO_X2-2, refreshFlag); }
//--------- Begin of function Unit::process_ai --------// // // [int] forceExecute - whether force execute all AI functions // without checking day interavals. // (default: 0) // void Unit::process_ai() { if( unit_mode ) // let functions in OUN_MODE.CPP process units in specific modes return; err_when( !nation_recno ); //------ the behavior_mode of AI units is aggressive ------// behavior_mode = UNIT_AGGRESSIVE; //------- handle Seek Path failures ------// if( ai_handle_seek_path_fail() ) return; //--- if it's a spy from other nation, don't control it ---// if( spy_recno && true_nation_recno() != nation_recno ) { //--- a random chance of the AI catching the spy and resign it ---// if( is_visible() && misc.random(365 * FRAMES_PER_DAY)==0 ) // if the unit stay outside for one year, it will get caught { resign(COMMAND_AI); return; } if( !spy_array[spy_recno]->notify_cloaked_nation_flag ) // if notify_cloaked_nation_flag is 1, the nation will take it as its own spies return; } //----- think about rewarding this unit -----// if( race_id && rank_id != RANK_KING && info.game_date%5 == sprite_recno%5 ) { think_reward(); } //-----------------------------------------// if( !is_visible() ) return; //----- think about using items -------// if( think_use_item() ) return; //---- King flees under attack or surrounded by enemy ---// if( race_id && rank_id==RANK_KING ) { if( think_king_flee() ) return; } //---- General flees under attack or surrounded by enemy ---// if( race_id && rank_id==RANK_GENERAL && info.game_date%7 == sprite_recno%7 ) { if( think_general_flee() ) return; } //---- stop attacking a town with zero resistance ----// if( cur_order.mode==UNIT_ATTACK && nation_recno) { if( !base_obj_array.is_deleted(cur_order.para) ) { BaseObj* baseObj = base_obj_array[cur_order.para]; if( baseObj->cast_to_Town() && baseObj->cast_to_Town()->nation_recno==0 && baseObj->cast_to_Town()->resistance(nation_recno) < 1 ) { stop_order(); return; } } } //------ if the unit is not stop right now ------// if( !is_all_stop() ) { think_stop_chase(); return; } //-----------------------------------------// if( mobile_type==UNIT_LAND ) { if( ai_escape_fire() ) return; } //---------- if this is your spy --------// if( spy_recno && true_nation_recno()==nation_recno ) think_spy_action(); //----- if this unit is on a attack mission ----// if( is_all_stop() && in_ai_attack_mission ) { if( ai_attack_next_target() ) return; } //------ if this unit is from a camp --------// if( home_camp_firm_recno ) { FirmCamp* firmCamp; FirmMonsterFortress* firmMonsterFortress; int rc = 0; if( firm_array.is_deleted(home_camp_firm_recno) ) { rc = 0; } if( (firmCamp = firm_array[home_camp_firm_recno]->cast_to_FirmCamp()) ) { if( rank_id == RANK_SOLDIER ) rc = firmCamp->soldier_count < MAX_SOLDIER; else rc = !firmCamp->overseer_recno; } else if( (firmMonsterFortress = firm_array[home_camp_firm_recno]->cast_to_FirmMonsterFortress()) ) { rc = (unit_id == firmMonsterFortress->support_unit_id && !firmMonsterFortress->is_extra_builder_full()) || !firmMonsterFortress->is_soldier_full(); } else { err_here(); } if( rc ) { if( return_camp() ) return; } home_camp_firm_recno = 0; // the camp is already occupied by somebody } //------- if the unit is idle ------------// if( is_all_stop() ) { if( race_id && rank_id==RANK_KING ) { if( is_human() ) think_king_action(); else think_normal_monster_action(); } else if( race_id && rank_id==RANK_GENERAL ) { think_general_action(); } else { int unitClass = unit_res[unit_id]->unit_class; //------ if this unit is a weapon ------// // ######### begin Gilbert 24/3 ########// // BUGHERE : monster weapon was UNIT_CLASS_MONSTER but now UNIT_CLASS_MONS_WEAPON if( unitClass == UNIT_CLASS_WEAPON || unitClass == UNIT_CLASS_MONS_WEAPON ) // ######### end Gilbert 24/3 ########// { if( info.game_date%15 == sprite_recno%15 ) // don't call too often as the action may fail and it takes a while to call the function each time { think_weapon_action(); //-- ships AI are called in UnitMarine --// } } //------ if this unit is a monster ------// else if( unitClass == UNIT_CLASS_MONSTER || unitClass == UNIT_CLASS_INSECT || unitClass == UNIT_CLASS_ANIMAL ) { //--- if previous attempts for new action failed, don't call think_normal_human_action() so frequently then ---// if( ai_no_suitable_action ) { if( info.game_date%15 != sprite_recno%15 ) // don't call too often as the action may fail and it takes a while to call the function each time return; } if( !think_normal_monster_action() ) { ai_no_suitable_action = true; // set this flag so think_normal_human_action() won't be called continously ai_move_to_nearby_firm(FIRM_LAIR); } } //------ if this unit is a human ------// else if( unitClass == UNIT_CLASS_HUMAN ) { //--- if previous attempts for new action failed, don't call think_normal_human_action() so frequently then ---// if( ai_no_suitable_action ) { if( info.game_date%15 != sprite_recno%15 ) // don't call too often as the action may fail and it takes a while to call the function each time return; } if( !think_normal_human_action() ) { ai_no_suitable_action = true; // set this flag so think_normal_human_action() won't be called continously // if( !leader_unit_recno ) // only when the unit is not led by a commander // resign(COMMAND_AI); // else ai_move_to_nearby_town(); } } //---- if this unit is a wagon -----// else if( unitClass == UNIT_CLASS_WAGON ) { think_assign_human_to_town(); } } } }