Exemplo n.º 1
0
//--------- 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;
}
Exemplo n.º 2
0
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 );
	}
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
//--------- 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;
}
Exemplo n.º 5
0
//--------- 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);
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
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();
				}
			}
		}
	}
}
Exemplo n.º 8
0
//--------- 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);
						}
					}
				}
			}
      }
   }
}
Exemplo n.º 9
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" );
}
Exemplo n.º 10
0
//--------- 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);
}
Exemplo n.º 11
0
//--------- 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;
		}
	}
}
Exemplo n.º 12
0
//--------- 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);
}
Exemplo n.º 13
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()
{
	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();
			}
		}
	}
}