//----------- Begin of function Unit::return_camp -----------// // // Order this unit to return to the camp. For ordering many // units to return to a camp, UnitArray::return_camp() should // be called instead. // int Unit::return_camp() { if( !home_camp_firm_recno ) return 0; err_when( firm_array.is_deleted(home_camp_firm_recno) ); Firm* firmPtr = firm_array[home_camp_firm_recno]; if( firmPtr->region_id != region_id() ) return 0; err_when( !firmPtr->cast_to_FirmCamp() && !firmPtr->cast_to_FirmMonsterFortress() ); err_when( firmPtr->nation_recno != nation_recno ); //--------- assign now ---------// // ##### begin Gilbert 2/6 #########// assign(firmPtr->loc_x1, firmPtr->loc_y1, -1, true); // force_move_flag = 1; // ##### end Gilbert 2/6 #########// return cur_action != SPRITE_IDLE; }
//--------- Begin of function Unit::ai_build_camp --------// // // Order this unit to build a camp in its region. // int Unit::ai_build_camp() { //--- to prevent building more than one camp at the same time ---// int curRegionId = region_id(); Nation* ownNation = nation_array[nation_recno]; if( ownNation->is_action_exist( ACTION_AI_BUILD_FIRM, FIRM_CAMP, curRegionId ) ) return 0; //------- locate a place for the camp --------// FirmInfo* firmInfo = firm_res[FIRM_CAMP]; int xLoc=0, yLoc=0; char teraMask = UnitRes::mobile_type_to_mask(UNIT_LAND); if( world.locate_space_random(xLoc, yLoc, MAX_WORLD_X_LOC-1, MAX_WORLD_Y_LOC-1, firmInfo->loc_width+2, firmInfo->loc_height+2, // leave at least one location space around the building MAX_WORLD_X_LOC*MAX_WORLD_Y_LOC, curRegionId, 1, teraMask) ) { return ownNation->add_action( xLoc, yLoc, -1, -1, ACTION_AI_BUILD_FIRM, FIRM_CAMP, 1, sprite_recno ); } return 0; }
//--------- Begin of function Unit::ai_settle_new_town --------// // // Settle a new village next to one of the camps in this region. // int Unit::ai_settle_new_town() { //----- locate a suitable camp for the new town to settle next to ----// Nation* ownNation = nation_array[nation_recno]; FirmCamp* firmCamp, *bestCamp=NULL; int curRegionId = region_id(); int curRating, bestRating=0; for( int i=ownNation->ai_camp_count-1 ; i>=0 ; i-- ) { firmCamp = (FirmCamp*) firm_array[ ownNation->ai_camp_array[i] ]; if( firmCamp->region_id != curRegionId ) continue; curRating = firmCamp->total_combat_level(); if( curRating > bestRating ) { bestRating = curRating; bestCamp = firmCamp; } } if( !bestCamp ) return 0; //--------- settle a new town now ---------// int xLoc=bestCamp->loc_x1; int yLoc=bestCamp->loc_y1; int townWidth = STD_TOWN_LOC_WIDTH + INTER_PLACE_SPACE*2; int townHeight = STD_TOWN_LOC_HEIGHT + INTER_PLACE_SPACE*2; if( world.locate_space(xLoc, yLoc, bestCamp->loc_x2, bestCamp->loc_y2, townWidth, townHeight, UNIT_LAND, curRegionId, 1 ) ) // 1-build flag { settle_town( xLoc+INTER_PLACE_SPACE, yLoc+INTER_PLACE_SPACE, COMMAND_AI ); return 1; } return 0; }
//--------- Begin of function Unit::ai_build_firm --------// // // Order this unit to build a camp in its region. // int Unit::ai_build_firm() { //--- don't build if the race of the nation and the unit is different ----// if( nation_array[nation_recno]->is_human() != is_human() ) return 0; //---------------------------------------------------------------// int firmId; if( is_human() ) firmId = FIRM_FORT; else firmId = FIRM_LAIR; if( !firm_res[firmId]->can_build(sprite_recno) ) return 0; //--- to prevent building more than one camp at the same time ---// int curRegionId = region_id(); Nation* ownNation = nation_array[nation_recno]; if( ownNation->is_action_exist( ACTION_AI_BUILD_FIRM, firmId, curRegionId ) ) return 0; //------- locate a place for the camp --------// FirmInfo* firmInfo = firm_res[firmId]; char teraMask = UnitRes::mobile_type_to_mask(UNIT_LAND); int xLoc=next_x_loc(), yLoc=next_y_loc(); if( world.locate_space(xLoc, yLoc, xLoc, yLoc, firmInfo->loc_width+INTER_PLACE_SPACE*2, firmInfo->loc_height+INTER_PLACE_SPACE*2, // leave at least one location space around the building UNIT_LAND, curRegionId, 1) ) { return ownNation->add_action( xLoc, yLoc, -1, -1, ACTION_AI_BUILD_FIRM, firmId, 1, sprite_recno ); } return 0; }
//--------- Begin of function Unit::think_independent_hero --------// // void Unit::think_independent_hero() { //------ think about go to serve a kingdom -------// int bestNationRecno=0, curRating; int bestRating = (skill_level() + combat_level()/2) / 3; if( item.id ) bestRating += (item_res.rareness(item.id)+1) * 10; //------------------------------------------------// int i; for( i=nation_array.size() ; i>0 ; i-- ) { if( nation_array.is_deleted(i) ) continue; Nation* nationPtr = nation_array[i]; curRating = (int) nationPtr->reputation + nationPtr->overall_rating; if( sprite_recno%2==0 ) // some heroes look at kill_monster_score, but some don't curRating += (int) nationPtr->kill_monster_score/10; if( race_id == nationPtr->race_id ) curRating += 10; if( curRating > bestRating ) { bestRating = curRating; bestNationRecno = i; } } if( bestNationRecno ) { //------ change nation now --------// if( !betray(bestNationRecno) ) return; //---- the unit moves close to the newly joined nation ----// ai_move_to_nearby_town(); return; } //---- randomly locate a destination to walk to ----// int xLoc, yLoc, regionId = region_id(); for( i=100 ; i>0 ; i-- ) { xLoc = m.random(MAX_WORLD_X_LOC); yLoc = m.random(MAX_WORLD_Y_LOC); Location* locPtr = world.get_loc(xLoc, yLoc); if( locPtr->walkable() && locPtr->region_id == regionId ) break; } if( i==0 ) return; move(xLoc, yLoc); }
//--------- Begin of function Unit::think_betray ---------// // int Unit::think_betray() { int unitRecno = sprite_recno; err_when( unit_array.is_deleted(unitRecno) ); if( !race_id ) return 0; if( unit_mode==UNIT_MODE_TOWN_DEFENDER || unit_mode==UNIT_MODE_CAMP_DEFENDER ) return 0; if( spy_recno ) // spies do not betray here, spy has its own functions for betrayal return 0; //----- if the unit is in training or is constructing a building, do not rebel -------// if( !is_visible() && unit_mode != UNIT_MODE_OVERSEE ) return 0; if( loyalty >= UNIT_BETRAY_LOYALTY ) // you when unit is return 0; if( !unit_res[unit_id]->race_id || !nation_recno || rank_id==RANK_KING || spy_recno ) { return 0; } err_when(unit_res[unit_id]->unit_class == UNIT_CLASS_GOD); err_when(unit_id==UNIT_CARAVAN); //------ turn towards other nation --------// int i, bestNationRecno=0, nationScore, bestScore=loyalty; // the score must be larger than the current loyalty Nation *curNation, *nationPtr; int unitRegionId = region_id(); if( loyalty==0 ) // if the loyalty is 0, it will definitely betray bestScore = -100; curNation = nation_array[nation_recno]; for( i=nation_array.size() ; i>0 ; i-- ) { if( nation_array.is_deleted(i) ) continue; if( !curNation->get_relation(i)->has_contact || i==nation_recno ) continue; nationPtr = nation_array[i]; if( nationPtr->is_human() != is_human() ) continue; //--- only if the nation has a base town in the region where the unit stands ---// if( !region_array.nation_has_base_town(unitRegionId, i) ) continue; //------------------------------------------------// nationScore = (int) nationPtr->reputation + (nationPtr->overall_rating - curNation->overall_rating); if( race_res.is_same_race(nationPtr->race_id, race_id) ) nationScore += 30; if( nationScore > bestScore ) { bestScore = nationScore; bestNationRecno = i; } } err_when( unit_array.is_deleted(unitRecno) ); if( bestNationRecno ) { return betray(bestNationRecno); } else if( loyalty==0 ) { //----------------------------------------------// // If there is no good nation to turn towards to and // the loyalty has dropped to 0, resign itself and // leave the nation. // // However, if the unit is spy, it will stay with the // nation as it has never been really loyal to the nation. //---------------------------------------------// if( rank_id != RANK_KING && is_visible() && !spy_recno ) { resign(COMMAND_AUTO); return 1; } } return 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" ); }