Exemple #1
0
//----------- 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;
}
Exemple #2
0
//--------- 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;
}
Exemple #3
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;
}
Exemple #4
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;
}
Exemple #5
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);
}
Exemple #6
0
//--------- 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;
}
Exemple #7
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" );
}