//--------- 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::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::spy_change_nation ---------// // // Change the deceiving nation recno of a spy unit which you control. // // <int> newNationRecno - the new nation the spy changes its cloack to // <char> remoteAction - remote action type // void Unit::spy_change_nation(int newNationRecno, char remoteAction) { if( newNationRecno == nation_recno ) return; if( newNationRecno && nation_array.is_deleted(newNationRecno) ) // this can happen in a multiplayer message return; //------- if this is a remote action -------// if( !remoteAction && remote.is_enable() ) { // packet structure <unit recno> <new nation Recno> short *shortPtr = (short *)remote.new_send_queue_msg(MSG_UNIT_SPY_NATION, 2*sizeof(short) ); *shortPtr = sprite_recno; shortPtr[1] = newNationRecno; return; } //----- update the var in Spy ------// Spy* spyPtr = spy_array[spy_recno]; //--- when a spy change cloak to another nation, he can't cloak as a general, he must become a soldier first ---// if( is_visible() && // if the spy is a commander in a camp, don't set its rank to soldier rank_id == RANK_GENERAL && newNationRecno != spyPtr->true_nation_recno ) { set_rank(RANK_SOLDIER); } //---------------------------------------------------// // // If this spy unit is a general or an overseer of the // cloaked nation, when he changes nation, that will // inevitably be noticed by the cloaked nation. // //---------------------------------------------------// if( spyPtr->true_nation_recno != nation_array.player_recno ) // only send news message if he is not the player's own spy { if( rank_id == RANK_GENERAL || unit_mode == UNIT_MODE_OVERSEE || spyPtr->notify_cloaked_nation_flag ) { //-- if this spy's cloaked nation is the player's nation, the player will be notified --// if( nation_recno == nation_array.player_recno ) news_array.unit_betray(sprite_recno, newNationRecno); } //---- send news to the cloaked nation if notify flag is on ---// if( spyPtr->notify_cloaked_nation_flag ) { if( newNationRecno == nation_array.player_recno ) // cloaked as the player's nation news_array.unit_betray(sprite_recno, newNationRecno); } } //--------- change nation recno now --------// spyPtr->cloaked_nation_recno = newNationRecno; betray(newNationRecno); // call the betray function to change natino. There is no difference between a spy changing nation and a unit truly betrays }