Example #1
0
//------- Begin of function Tornado::hit_building -----//
//	building means firm or town
//
void Tornado::hit_building()
{
	short damageXLoc = damage_x_loc();
	short damageYLoc = damage_y_loc();
	if( damageXLoc < 0 || damageXLoc >= world.max_x_loc ||
		damageYLoc < 0 || damageYLoc >= world.max_y_loc)
		return;

	Location* locPtr = world.get_loc(damageXLoc, damageYLoc);

	// ##### begin Gilbert 30/10 #####//
	if(locPtr->is_firm() )
//		&& firm_res[(firmPtr=firm_array[locPtr->firm_recno()])->firm_id]->buildable )
	{
		Firm *firmPtr = firm_array[locPtr->firm_recno()];
		firmPtr->hit_points -= attack_damage*2;
		if( firmPtr->hit_points <= 0)
		{
			firmPtr->hit_points = (float) 0;

			se_res.sound(firmPtr->center_x, firmPtr->center_y, 1,
				'F', firmPtr->firm_id, "DIE" );

			firm_array.del_firm(locPtr->firm_recno());
		}
	}

	if( locPtr->is_town() )
	{
		Town *townPtr = town_array[locPtr->town_recno()];
		if( (life_time % 30) == 0 ) 
			townPtr->kill_town_people(0);
	}
	// ##### end Gilbert 30/10 #####//
}
Example #2
0
void CampaignEastWest::plot_d1_create_game()
{
	// reduce cash

	(~nation_array)->cash = (~nation_array)->cash / 4;

	// reduce mineral if the mine is owned by the player

	for( int i = 1; i <= site_array.size(); ++i )
	{
		if( site_array.is_deleted(i) )
			continue;

		Site *sitePtr = site_array[i];
		if( sitePtr->site_type == SITE_RAW && sitePtr->has_mine )
		{
			Location *locPtr = world.get_loc(sitePtr->map_x_loc, sitePtr->map_y_loc);
			err_when( !locPtr->is_firm() );
			Firm *firmPtr = firm_array[locPtr->firm_recno()];
			if( firmPtr->is_own() )
			{
				sitePtr->reserve_qty = sitePtr->reserve_qty / 10;

				if( firmPtr->cast_to_FirmMine() )
				{
					firmPtr->cast_to_FirmMine()->reserve_qty = (float)sitePtr->reserve_qty;
				}
				else if( firmPtr->cast_to_FirmMonsterAlchemy() )
				{
					firmPtr->cast_to_FirmMonsterAlchemy()->reserve_qty = (float)sitePtr->reserve_qty;
				}
			}
		}
	}
}
Example #3
0
//------- Begin of function Bullet::hit_building -----//
//	building means firm or town
//
// ###### begin Gilbert 14/5 #########//
void Bullet::hit_building(short x, short y)
{
	Location* locPtr = world.get_loc(x, y);

	if(locPtr->is_firm())
	{
		Firm *firmPtr = firm_array[locPtr->firm_recno()];
		// ##### begin Gilbert 3/9 #########//
		if( !firmPtr || !nation_array.should_attack(nation_recno, firmPtr->nation_recno) )
		// ##### end Gilbert 3/9 #########//
			return;
	}
	else if(locPtr->is_town())
	{
		Town *townPtr = town_array[locPtr->town_recno()];
		// ##### begin Gilbert 3/9 #########//
		if( !townPtr || !nation_array.should_attack(nation_recno, townPtr->nation_recno) )
		// ##### end Gilbert 3/9 #########//
			return;
	}
	else
		return;

	float attackDamage = attenuated_damage(x * ZOOM_LOC_WIDTH, y * ZOOM_LOC_HEIGHT );
	// BUGHERE : hit building of same nation?
	if( attackDamage == 0)
		return;

	Unit *virtualUnit = NULL, *parentUnit;
	if(unit_array.is_deleted(parent_recno))
	{
		parentUnit = NULL;
		//### begin alex 26/9 ###//
		if(nation_array.is_deleted(nation_recno))
			return;
		//#### end alex 26/9 ####//

		for(int i=unit_array.size(); i>0; i--)
		{
			if(unit_array.is_deleted(i))
				continue;

			virtualUnit = unit_array[i];
			break;
		}

		if(!virtualUnit)
			return; //**** BUGHERE
	}
	else
		virtualUnit = parentUnit = unit_array[parent_recno];

	virtualUnit->hit_building(parentUnit, target_x_loc, target_y_loc, attackDamage);
	// ####### end Gilbert 14/5 ########//
}
Example #4
0
// --------- begin of function BulletHoming::init --------//
void BulletHoming::init(char parentType, short parentRecno, short targetXLoc, short targetYLoc, char targetMobileType)
{
	Bullet::init(parentType, parentRecno, targetXLoc, targetYLoc, targetMobileType);

	// ------- find the maximum range --------//

	//**** BUGHERE, using parentType and parentRecno to allow bullet by firm, town, etc.
	//**** BUGHERE, only allow bullet by unit for this version
	err_when(parent_type!=BULLET_BY_UNIT);
	Unit *parentUnit = unit_array[parentRecno];

	//---------- copy attack info from the parent unit --------//

	AttackInfo* attackInfo = parentUnit->attack_info_array+parentUnit->cur_attack;
	speed = attackInfo->bullet_speed;
	max_step = char((attackInfo->attack_range * ZOOM_LOC_WIDTH + speed-1)/ speed);

	//--------- keep backup of centre of the bullet ---------//
	SpriteFrame *spriteFrame = cur_sprite_frame();

	// origin_x/y and origin2_x/y are pointing at the centre of the bullet bitmap //
	origin_x += spriteFrame->offset_x + spriteFrame->width/2;
	origin_y += spriteFrame->offset_y + spriteFrame->height/2;
	origin2_x = origin_x; 
	origin2_y = origin_y;
	go_x += spriteFrame->offset_x + spriteFrame->width/2;
	go_y += spriteFrame->offset_y + spriteFrame->height/2;

	// ------- find the target_type and target_recno ------//
	Location *locPtr = world.get_loc(targetXLoc, targetYLoc);
	//### begin alex 16/5 ###//
	//if( locPtr->has_unit(mobile_type) )
	if(locPtr->has_unit(targetMobileType))
	{
		target_type = BULLET_TARGET_UNIT;
		//target_recno = locPtr->unit_recno(mobile_type);
		target_recno = locPtr->unit_recno(targetMobileType);
	}
	//#### end alex 16/5 ####//
	else if( locPtr->is_town() )
	{
		target_type = BULLET_TARGET_TOWN;
		target_recno = locPtr->town_recno();
	}
	else if( locPtr->is_firm() )
	{
		target_type = BULLET_TARGET_FIRM;
		target_recno = locPtr->firm_recno();
	}
	else if( locPtr->is_wall() )
	{
		target_type = BULLET_TARGET_WALL;
	}
}
Example #5
0
//------- Begin of function FirmMonster::think_attack_neighbor -------//
//
int FirmMonster::think_attack_neighbor()
{
	//-- don't attack new target if some mobile monsters are already attacking somebody --//

	if( patrol_unit_count > 0 )
		return 0;

	//-------- only attack if we have enough generals ---------//

	int generalCount=0;

	MonsterInFirm* monsterInFirm = monster_general_array;
	int				totalCombatLevel=0;

	//--- count the number of generals commanding at least 5 soldiers ---//

	int i;
	for( i=0 ; i<monster_general_count ; i++, monsterInFirm++ )
	{
		if( monsterInFirm->soldier_count >= 5 )
			generalCount++;
	}

	if( generalCount<=1 )	// don't attack if there is only one general in the firm
		return 0;

	//------ look for neighbors to attack ------//

	int		 xOffset, yOffset;
	int		 xLoc, yLoc;
	int		 attackFlag=0;
	FirmInfo* firmInfo = firm_res[firm_id];
	Location* locPtr;

	int scanLocWidth  = MONSTER_ATTACK_NEIGHBOR_RANGE*2;
	int scanLocHeight = MONSTER_ATTACK_NEIGHBOR_RANGE*2;
	int scanLimit = scanLocWidth * scanLocHeight;
	short targetNation;

	for(i=firmInfo->loc_width*firmInfo->loc_height+1; i<=scanLimit; i++)
	{
		m.cal_move_around_a_point(i, scanLocWidth, scanLocHeight, xOffset, yOffset);

		xLoc = center_x + xOffset;
		yLoc = center_y + yOffset;

		xLoc = max(0, xLoc);
		xLoc = min(MAX_WORLD_X_LOC-1, xLoc);

		yLoc = max(0, yLoc);
		yLoc = min(MAX_WORLD_Y_LOC-1, yLoc);

		locPtr = world.get_loc(xLoc, yLoc);

		if(locPtr->is_firm())
		{
			Firm *firmPtr = firm_array[locPtr->firm_recno()];
			if(firmPtr->nation_recno)
			{
				targetNation = firmPtr->nation_recno;
				attackFlag = 1;
				xLoc = firmPtr->loc_x1;
				yLoc = firmPtr->loc_y1;
				break;
			}
		}
		else if(locPtr->is_town())
		{
			Town *townPtr = town_array[locPtr->town_recno()];
			if(townPtr->nation_recno)
			{
				targetNation = townPtr->nation_recno;
				attackFlag = 1;
				xLoc = townPtr->loc_x1;
				yLoc = townPtr->loc_y1;
				break;
			}
		}
	}

	if( !attackFlag )
		return 0;

	//------- attack the civilian now --------//
	current_monster_action_mode = MONSTER_ACTION_ATTACK;

	mobilize_general( m.random(monster_general_count)+1 );

	if( patrol_unit_count > 0 )
	{
		//### begin alex 16/9 ###//
		set_hostile_nation(targetNation);
		//#### end alex 16/9 ####//
		// ##### patch begin Gilbert 5/8 #######//
		unit_array.attack(xLoc, yLoc, 0, patrol_unit_array, patrol_unit_count, COMMAND_AI, 0);
		// ##### patch end Gilbert 5/8 #######//
		return 1;
	}
	else
		return 0;
}
Example #6
0
//------- Begin of function Tornado::hit_building -----//
//	building means firm or town
//
void Tornado::hit_building()
{
	short damageXLoc = damage_x_loc();
	short damageYLoc = damage_y_loc();
	if( damageXLoc < 0 || damageXLoc >= world.max_x_loc ||
		damageYLoc < 0 || damageYLoc >= world.max_y_loc)
		return;

	Location* locPtr = world.get_loc(damageXLoc, damageYLoc);

	if(locPtr->is_firm() )
//		&& firm_res[(firmPtr=firm_array[locPtr->firm_recno()])->firm_id]->buildable )
	{
		Firm *firmPtr = firm_array[locPtr->firm_recno()];
		firmPtr->hit_points -= attack_damage*2;

		if( !damage_player_flag && firmPtr->is_own() )
		{
			damage_player_flag = 1;
			// add news message
			news_array.tornado_hit(sprite_recno);
		}

		if( firmPtr->hit_points <= 0)
		{
			firmPtr->hit_points = (float) 0;

			se_res.sound(firmPtr->center_x, firmPtr->center_y, 1,
				'F', firmPtr->firm_id, "DIE" );

			firm_array.del_firm(locPtr->firm_recno());
		}
	}

	if( locPtr->is_town() )
	{
		Town *townPtr = town_array[locPtr->town_recno()];

		if( !damage_player_flag && townPtr->is_own() )
		{
			damage_player_flag = 1;
			// add news message
			news_array.tornado_hit(sprite_recno);
		}

		if( townPtr->hit_points > 0.0f )
		{
			townPtr->hit_points -= attack_damage*2;
			if( townPtr->hit_points <= 0 )
			{
				townPtr->hit_points = (float) 0;
			}
		}
		else
		{
			// ###### begin Gilbert 10/2 #######//
			if( (life_time % 10) == 0 ) 
				townPtr->kill_town_people(0);
			// ###### end Gilbert 10/2 #######//
		}
	}
}
Example #7
0
//--------- Begin of function Nation::ai_assign_spy --------//
//
// Try to locate an existing spy for use.
//
// <int> targetXLoc, targetYLoc - the target location
// [int] spyRaceId			  - if specified, only spies of this race
//											 will be located. (default:0)
// [int] mobileOnly 				  - get mobile spies only. (default:0)
//
int Nation::ai_assign_spy(int targetXLoc, int targetYLoc, int spyRaceId, int mobileOnly)
{
	int unitRecno=0;

	//---- try to find an existing spy ----//

	Spy* spyPtr = ai_find_spy( targetXLoc, targetYLoc, spyRaceId, mobileOnly );

	if( spyPtr )
		unitRecno = spyPtr->mobilize_spy();

	//--- if not successful, then try to hire one ---//

	if( !unitRecno )
		unitRecno = hire_unit(SKILL_SPYING, spyRaceId, targetXLoc, targetYLoc);

	//--- if cannot hire one, try to train one ----//

	int trainTownRecno=0;

	if( !unitRecno )
		unitRecno = train_unit(SKILL_SPYING, spyRaceId, targetXLoc, targetYLoc, trainTownRecno);

	if( !unitRecno )
		return 0;

	//------ get the spy object of the unit ------//

	Unit* unitPtr = unit_array[unitRecno];

	err_when( !unitPtr->spy_recno );

	spyPtr = spy_array[unitPtr->spy_recno];

	//------- get the nation of the assign destination -----//

	Location* locPtr = world.get_loc(targetXLoc, targetYLoc);
	int 		 cloakedNationRecno;

	if( locPtr->is_firm() )
	{
		Firm* firmPtr = firm_array[locPtr->firm_recno()];

		err_when( firmPtr->nation_recno==0 );		// cannot assign to a monster firm

		cloakedNationRecno = firmPtr->nation_recno;
	}
	else if( locPtr->is_town() )
	{
		Town* townPtr = town_array[locPtr->town_recno()];

		cloakedNationRecno = townPtr->nation_recno;
	}
	else
	{
		return 0;		// the original firm or town has been destroyed or sold
	}

	//------- Add the assign spy action --------//

	int actionRecno = add_action( targetXLoc, targetYLoc,
							-1, -1, ACTION_AI_ASSIGN_SPY, cloakedNationRecno, 1, unitRecno );

	if( !actionRecno )
		return 0;

	//------ if the unit is under training ------//

	if( trainTownRecno )
		town_array[trainTownRecno]->train_unit_action_id = get_action(actionRecno)->action_id;

	return 1;
}
Example #8
0
// ----- begin of function ScenarioEditor::detect_human_view ------//
//
int ScenarioEditor::detect_human_view()
{
	if( power.command_id )
		return 0;

	// detect map area

	if( mouse.double_click( ZOOM_X1, ZOOM_Y1, ZOOM_X2, ZOOM_Y2, 0 ) )	// left click
	{
		int xLoc, yLoc;
		if( world.zoom_matrix->get_detect_location(mouse.click_x(0), mouse.click_y(0),
			&xLoc, &yLoc, NULL) )
		{
			if( unit_or_struct == 0 && !vbrowse_unit_id.none_record )
			{
				// put unit human_unit_id_array[human_unit_id_browse_recno-1]
				// on (xLoc, yLoc)
				int unitId = human_unit_id_array[human_unit_id_browse_recno-1];
				UnitInfo *unitInfo = unit_res[unitId];
				SpriteInfo *spriteInfo = sprite_res[unitInfo->sprite_id];
				if( world.check_unit_space(xLoc, yLoc, 
					xLoc+spriteInfo->loc_width-1, yLoc+spriteInfo->loc_height-1, unitInfo->mobile_type) )
				{
					int unitRecno = unit_array.add_unit( unitId, brush_player_recno, RANK_SOLDIER, 100, xLoc, yLoc );

					if( unitRecno && unitId == UNIT_WAGON )
					{
						err_when( !human_race_filter );
						UnitWagon* unitPtr = (UnitWagon *)unit_array[unitRecno];
						unitPtr->race_id = human_race_filter;
						unitPtr->set_pop( MAX_WAGON_POPULATION );
					}
				}
			}
			else if( unit_or_struct == 1 && !vbrowse_firm_build.none_record )
			{
				err_when( human_firm_group_array[human_firm_group_browse_recno] == 0 );
				if( human_firm_group_array[human_firm_group_browse_recno-1] < 0 )
				{
					// put town of race -human_firm_group_array[human_firm_group_browse_recno]
					// (xLoc, yLoc)

					if( world.can_build_town(xLoc, yLoc, 0) )
					{
						int raceId = -human_firm_group_array[human_firm_group_browse_recno-1];
						int townRecno = town_array.generate_town(brush_player_recno, raceId, xLoc, yLoc);
						if( townRecno )
						{
							Town *townPtr = town_array[townRecno];
							townPtr->construction_completion_percent = 100;
							townPtr->under_construction = 0;

							// init_pop
							if( brush_player_recno )
								townPtr->init_pop( 0, 100, 0, 1 );
							else
								townPtr->init_pop( 0, town_array.independent_town_resistance(), 0, 1 );

							townPtr->auto_set_layout();
						}
					}
				}
				else
				{
					// put firm group human_firm_group_array[human_firm_group_browse_recno-1]
					// on (xLoc, yLoc)

					FirmGroup *firmGroup = firm_res.get_group(human_firm_group_array[human_firm_group_browse_recno-1]);
					if( world.can_build_firm( xLoc, yLoc, firmGroup->firm_id, 0) )
					{
						if (brush_player_recno == 0)
						{
							box.msg( text_editor.str_no_independent() ); // "Cannot add any Independent structures" );
						}
						else
						{
							if( firmGroup->firm_id == FIRM_BASE )		// if it's a seat of power, give the nation a scroll of power first
								god_res[firmGroup->race_id]->enable_know(brush_player_recno);

							firm_array.generate_firm( xLoc, yLoc, brush_player_recno, firmGroup->firm_id, firmGroup->race_code );
						}
					}
				}
			}
		}
		return 1;
	}

	if( mouse.double_click( ZOOM_X1, ZOOM_Y1, ZOOM_X2, ZOOM_Y2, 1) )	// right click to remove
	{
		int xLoc, yLoc;
		char mobileType;
		Location* locPtr = power.test_detect(mouse.click_x(1), mouse.click_y(1), &mobileType, &xLoc, &yLoc );
		if( locPtr )
		{
			if( locPtr->unit_recno(mobileType) )		// remove unit
			{
				int unitRecno = locPtr->unit_recno(mobileType);
				if( !unit_array.is_deleted(unitRecno) )
				{
					unit_array[unitRecno]->hit_points = 0.0f;
				}
			}
			else if( locPtr->is_firm() )			// remove firm
			{
				int firmRecno = locPtr->firm_recno();
				if( !firm_array.is_deleted(firmRecno) )
				{
					firm_array.del_firm( firmRecno );
				}
			}
			else if( locPtr->is_town() )			// remove town
			{
				int townRecno = locPtr->town_recno();
				if( !town_array.is_deleted(townRecno) )
				{
					town_array.del_town(townRecno);
				}
			}
		}
		return 1;
	}

	return 0;
}
Example #9
0
//----------- Begin of function Nation::find_best_place_loc ----------//
//
// Determine the location of a new firm. It's best to have the
// new firm within the refective range of: towns, factories and
// mines.
//
// <short> buildFirmId		 - >0 id. of the firm to be built
//										0 if the place to be built is a town
// <short> refXLoc, refYLoc - either the location of a town or a firm,
//									   the market must be built next to it.
// <short&> resultXLoc, resultYLoc - result location of the firm.
// [short] distance 			 - the distance between the given place and
//										new place.
//
// return: <int> 1 - succeed, 0 - fail
//
int Nation::find_best_place_loc(short buildFirmId, short refXLoc, short refYLoc, short& resultXLoc, short& resultYLoc, short distance)
{
	#define IDEAL_INTER_PLACE_SPACE 		3

	if (distance == 0)
		distance = IDEAL_INTER_PLACE_SPACE;

	Location *locPtr = world.get_loc(refXLoc, refYLoc);
	short centerX, centerY, refX1, refY1, refX2, refY2;

	//-------- get the refective area ---------//

	int   originFirmRecno=0, originTownRecno=0;
	Firm* firmPtr;
	Town* townPtr;

	BYTE buildRegionId  = locPtr->region_id;
	int  buildIsPlateau = locPtr->is_plateau();
	int  effectiveDis;

	//-----------------------------------------//

	if( locPtr->is_firm() )
	{
		originFirmRecno = locPtr->firm_recno();

		firmPtr = firm_array[originFirmRecno];

		centerX = firmPtr->center_x;
		centerY = firmPtr->center_y;

		effectiveDis = world.effective_distance(buildFirmId, firmPtr->firm_id);

//		if( firmPtr->firm_id == FIRM_HARBOR )
//		{
//			buildRegionId  = ((FirmHarbor*)firmPtr)->land_region_id;
//			buildIsPlateau = 0;
//		}
	}
	else if( locPtr->is_town() )
	{
		originTownRecno = locPtr->town_recno();

		townPtr = town_array[originTownRecno];

		centerX = townPtr->center_x;
		centerY = townPtr->center_y;

		effectiveDis = world.effective_distance(buildFirmId, 0);
	}
	else
		err_here();

	refX1 = centerX - effectiveDis;
	refY1 = centerY - effectiveDis;
	refX2 = centerX + effectiveDis;
	refY2 = centerY + effectiveDis;

	//------------------------------------------------------//

	int placeLocWidth, placeLocHeight;

	if( buildFirmId )
	{
		placeLocWidth  = firm_res[buildFirmId]->loc_width;
		placeLocHeight = firm_res[buildFirmId]->loc_height;
	}
	else
	{
		placeLocWidth  = STD_TOWN_LOC_WIDTH;
		placeLocHeight = STD_TOWN_LOC_HEIGHT;
	}

	refX1 -= placeLocWidth/2;		// since we use loc_x1 as the building reference, we need to shift it so it will match the use of center_x in effective distance
	refY1 -= placeLocHeight/2;
	refX1 = max(0, refX1);
	refY1 = max(0, refY1);
	refX2 = min(MAX_WORLD_X_LOC-1, refX2);
	refY2 = min(MAX_WORLD_Y_LOC-1, refY2);

	//-------- build a matrix on the refective area ---------//

	int 	 refWidth=refX2-refX1+1, refHeight=refY2-refY1+1;
	short* refMatrix = (short*) mem_add( sizeof(short) * refWidth * refHeight );
	short* refMatrixPtr;

	//------ initialize the weights of the matrix ------//

	int xLoc, yLoc;   	// inner locations in the matrix receives more weights than outer locations do
	int t1, t2;

	for( yLoc=refY1 ; yLoc<=refY2 ; yLoc++ )
	{
		refMatrixPtr = refMatrix + (yLoc-refY1)*refWidth;
		locPtr		 = world.get_loc( refX1, yLoc );

		for( xLoc=refX1 ; xLoc<=refX2 ; xLoc++, refMatrixPtr++, locPtr++ )
		{
			t1 = abs(xLoc-centerX);
			t2 = abs(yLoc-centerY);

			if( locPtr->region_id != buildRegionId ||
				 locPtr->is_plateau() != buildIsPlateau ||
				 locPtr->is_power_off() )
			{
				*refMatrixPtr = -1000;
			}
			else
			{
				*refMatrixPtr = 10-max(t1, t2);		// it's negative value, and the value is lower for the outer ones
			}
		}
	}

	//----- calculate weights of the locations in the matrix ----//

	int   xLocB, yLocB, weightAdd, weightReduce;
	short refBX1, refBY1, refBX2, refBY2;
	short refCX1, refCY1, refCX2, refCY2;

	for( yLoc=refY1 ; yLoc<=refY2 ; yLoc++ )
	{
		locPtr = world.get_loc(refX1, yLoc);

		for( xLoc=refX1 ; xLoc<=refX2 ; xLoc++, locPtr++ )
		{
			if( locPtr->region_id != buildRegionId ||
				 locPtr->is_plateau() != buildIsPlateau ||
				 locPtr->is_power_off() )
			{
				continue;
			}

			//------- if there is a firm on the location ------//

			weightAdd = 0;
			weightReduce = 0;

			if( locPtr->is_firm() )
			{
				firmPtr = firm_array[locPtr->firm_recno()];

				if( buildFirmId==FIRM_MARKET || buildFirmId==FIRM_FACTORY )		// only factories & market places need building close to other firms
				{
					int rc = 1;

					if( firmPtr->nation_recno != nation_recno )
						rc = 0;

					//----- check if the firm is of the right type ----//

					if( buildFirmId==FIRM_MARKET )		// build a market place close to mines and factories
					{
						if( firmPtr->firm_id!=FIRM_MINE && firmPtr->firm_id!=FIRM_FACTORY )	// market places should be built close to factories and mines and they are the only two firms that influence the location of the market place
							rc = 0;
					}
					else if( buildFirmId==FIRM_FACTORY )	// build a factory close to mines and market places
					{
						if( firmPtr->firm_id!=FIRM_MINE && firmPtr->firm_id!=FIRM_MARKET )	// market places should be built close to factories and mines and they are the only two firms that influence the location of the market place
							rc = 0;
					}

					//------------------------------------------/

					if( rc )
					{
						effectiveDis = world.effective_distance(firmPtr->firm_id, buildFirmId);

						refBX1 = firmPtr->center_x - effectiveDis;
						refBY1 = firmPtr->center_y - effectiveDis;
						refBX2 = firmPtr->center_x + effectiveDis;
						refBY2 = firmPtr->center_y + effectiveDis;

						weightAdd = 40;
					}
				}

				refCX1 = firmPtr->loc_x1-distance ;		// add negative weights on space around this firm
				refCY1 = firmPtr->loc_y1-distance ;		// so to prevent firms from building right next to the firm
				refCX2 = firmPtr->loc_x2+distance ;		// and leave some space for walking path.
				refCY2 = firmPtr->loc_y2+distance ;

				weightReduce = 20;
			}

			//------- if there is a town on the location ------//

			else if( locPtr->is_town() )
			{
				townPtr = town_array[locPtr->town_recno()];

				effectiveDis = world.effective_distance(0, buildFirmId);

				refBX1 = townPtr->center_x - effectiveDis;
				refBY1 = townPtr->center_y - effectiveDis;
				refBX2 = townPtr->center_x + effectiveDis;
				refBY2 = townPtr->center_y + effectiveDis;

				weightAdd = townPtr->population*2;

				//----- if the town is not our own -----//

				if(townPtr->nation_recno != nation_recno)
				{
					if( townPtr->nation_recno==0 )  		// it's an independent town
						weightAdd = weightAdd * ( 100-(int)townPtr->resistance(nation_recno) ) / 100;
					else											// more friendly nations get higher weights
					{
						int relationStatus = get_relation_status(townPtr->nation_recno);

						if( relationStatus >= RELATION_NEUTRAL )
							weightAdd = weightAdd * (relationStatus-RELATION_NEUTRAL+1) / 4;
					}
				}

				refCX1 = townPtr->loc_x1-distance ;		// add negative weights on space around this firm
				refCY1 = townPtr->loc_y1-distance ;		// so to prevent firms from building right next to the firm
				refCX2 = townPtr->loc_x2+distance ;		// and leave some space for walking path.
				refCY2 = townPtr->loc_y2+distance ;

				weightReduce = 100;
			}
			else
				continue;

			//------ add weights to the matrix ------//

			if( weightAdd )
			{
				for( yLocB=max(refY1,refBY1) ; yLocB<=min(refY2,refBY2) ; yLocB++ )
				{
					xLocB = max(refX1,refBX1);
					refMatrixPtr = refMatrix + (yLocB-refY1)*refWidth + (xLocB-refX1);

					for( ; xLocB<=min(refX2,refBX2) ; xLocB++ )
					{
						*refMatrixPtr++ += weightAdd;
					}
				}
			}

			//------ reduce weights from the matrix ------//

			if( weightReduce )
			{
				for( yLocB=max(refY1,refCY1) ; yLocB<=min(refY2,refCY2) ; yLocB++ )
				{
					xLocB = max(refX1,refCX1);
					refMatrixPtr = refMatrix + (yLocB-refY1)*refWidth + (xLocB-refX1);

					for( ; xLocB<=min(refX2,refCX2) ; xLocB++ )
					{
						*refMatrixPtr++ -= weightReduce;
					}
				}
			}
		}
	}

	//------ select the best building site in the matrix -------//

	resultXLoc = -1;
	resultYLoc = -1;

	short thisWeight, bestWeight=0;

	refX2 -= placeLocWidth-1;			// do not scan beyond the border
	refY2 -= placeLocHeight-1;

	for( yLoc=refY1 ; yLoc<=refY2 ; yLoc++ )
	{
		for( xLoc=refX1 ; xLoc<=refX2 ; xLoc++ )
		{
			if( world.get_region_id(xLoc, yLoc) != buildRegionId )
				continue;

			if( buildFirmId )
			{
				if( !world.can_build_firm(xLoc, yLoc, buildFirmId) )
					continue;
			}
			else
			{
				if( !world.can_build_town(xLoc, yLoc) )
					continue;
			}

			//---- calculate the average weight of a firm area ----//

			int totalWeight=0;

			refMatrixPtr = refMatrix + (yLoc-refY1)*refWidth + (xLoc-refX1);

			for( int yCount=0 ; yCount<placeLocHeight ; yCount++ )
			{
				for( int xCount=0 ; xCount<placeLocWidth ; xCount++ )
				{
					totalWeight += *refMatrixPtr++;
				}

				refMatrixPtr += refWidth-placeLocWidth;
			}

			//------- compare the weights --------//

			thisWeight = totalWeight / (placeLocWidth*placeLocHeight);

			if( thisWeight > bestWeight )
			{
				bestWeight = thisWeight;

				resultXLoc = xLoc;
				resultYLoc = yLoc;
			}
		}
	}

	//------ release the refective matrix -----//

	mem_del( refMatrix );

	return resultXLoc >= 0;
}
Example #10
0
//--------- Begin of function UnitMonster::random_attack --------//
//
// Randomly pick an object to attack.
//
int UnitMonster::random_attack()
{
	#define ATTACK_SCAN_RANGE	100

	int		 xOffset, yOffset;
	int		 xLoc, yLoc;
	Location* locPtr;
	int		 curXLoc = next_x_loc(), curYLoc = next_y_loc();
	BYTE	 	 regionId = world.get_region_id(curXLoc, curYLoc);
	int		 rc;

	for( int i=2 ; i<ATTACK_SCAN_RANGE*ATTACK_SCAN_RANGE ; i++ )
	{
		m.cal_move_around_a_point(i, ATTACK_SCAN_RANGE, ATTACK_SCAN_RANGE, xOffset, yOffset);

		xLoc = curXLoc + xOffset;
		yLoc = curYLoc + yOffset;

		xLoc = max(0, xLoc);
		xLoc = min(MAX_WORLD_X_LOC-1, xLoc);

		yLoc = max(0, yLoc);
		yLoc = min(MAX_WORLD_Y_LOC-1, yLoc);

		locPtr = world.get_loc(xLoc, yLoc);

		if( locPtr->region_id != regionId )
			continue;

		rc = 0;

		//----- if there is a unit on the location ------//

		if( locPtr->has_unit(UNIT_LAND) )
		{
			int unitRecno = locPtr->unit_recno(UNIT_LAND);

			if( unit_array.is_deleted(unitRecno) )
				continue;

			rc = 1;
		}

		//----- if there is a firm on the location ------//

		if( !rc && locPtr->is_firm() )
		{
			int firmRecno = locPtr->firm_recno();

			if( firm_array.is_deleted(firmRecno) )
				continue;

			rc = 1;
		}

		//----- if there is a town on the location ------//

		if( !rc && locPtr->is_town() )
		{
			int townRecno = locPtr->town_recno();

			if( town_array.is_deleted(townRecno) )
				continue;

			rc = 1;
		}

		//-------------------------------------//

		if( rc )
		{
			group_order_monster(xLoc, yLoc, 1);		// 1-the action is attack
			return 1;
		}
	}

	return 0;
}
Example #11
0
//----------- Begin of function Unit::resume_original_attack_action -------//
//
void Unit::resume_original_attack_action()
{
	if( !original_action_mode )
		return;

	if( original_action_mode != ACTION_ATTACK_UNIT &&
		 original_action_mode != ACTION_ATTACK_FIRM &&
		 original_action_mode != ACTION_ATTACK_TOWN )
	{
		original_action_mode = 0;
		return;
	}

	//--------------------------------------------//

	err_when( original_action_x_loc<0 || original_action_x_loc>=MAX_WORLD_X_LOC );
	err_when( original_action_y_loc<0 || original_action_y_loc>=MAX_WORLD_Y_LOC );

	Location* locPtr = world.get_loc(original_action_x_loc, original_action_y_loc);
	int		 targetNationRecno = -1;

	if( original_action_mode == ACTION_ATTACK_UNIT && locPtr->has_unit(UNIT_LAND) )
	{
		int unitRecno = locPtr->unit_recno(UNIT_LAND);

		if( unitRecno == original_action_para )
			targetNationRecno = unit_array[unitRecno]->nation_recno;
	}
	else if( original_action_mode == ACTION_ATTACK_FIRM && locPtr->is_firm() )
	{
		int firmRecno = locPtr->firm_recno();

		if( firmRecno == original_action_para )
			targetNationRecno = firm_array[firmRecno]->nation_recno;
	}
	else if( original_action_mode == ACTION_ATTACK_TOWN && locPtr->is_town() )
	{
		int townRecno = locPtr->town_recno();

		if( townRecno == original_action_para )
			targetNationRecno = town_array[townRecno]->nation_recno;
	}

	//----- the original target is no longer valid ----//

	if( targetNationRecno == -1 )
	{
		original_action_mode = 0;
		return;
	}

	//---- only resume attacking the target if the target nation is at war with us currently ---//

	if( !targetNationRecno || (targetNationRecno &&
		 targetNationRecno != nation_recno &&
		 nation_array[nation_recno]->get_relation_status(targetNationRecno) == NATION_HOSTILE ))
	{
		short selectedArray[1];
		selectedArray[0] = sprite_recno;		// use unit_array.attack() instead of unit.attack_???() as we are unsure about what type of object the target is.

		// #### begin Gilbert 5/8 ########//
		unit_array.attack(original_action_x_loc, original_action_y_loc, 0, selectedArray, 1, COMMAND_AI, 0 );
		// #### end Gilbert 5/8 ########//
	}

	original_action_mode = 0;
}
Example #12
0
void Unit::resume_original_action()
{
	if( !original_action_mode )
		return;

	//--------- If it is an attack action ---------//

	if( original_action_mode == ACTION_ATTACK_UNIT ||
		 original_action_mode == ACTION_ATTACK_FIRM ||
		 original_action_mode == ACTION_ATTACK_TOWN )
	{
		resume_original_attack_action();
		return;
	}

	//--------------------------------------------//

	if( original_action_x_loc<0 || original_action_x_loc>=MAX_WORLD_X_LOC ||
		 original_action_y_loc<0 || original_action_y_loc>=MAX_WORLD_Y_LOC )
	{
		original_action_mode = 0;
		return;
	}

	short selectedArray[1];
	selectedArray[0] = sprite_recno;		// use unit_array.attack() instead of unit.attack_???() as we are unsure about what type of object the target is.

	Location* locPtr = world.get_loc(original_action_x_loc, original_action_y_loc);

	//--------- resume assign to town -----------//

	if( original_action_mode == ACTION_ASSIGN_TO_TOWN && locPtr->is_town() )
	{
		if( locPtr->town_recno() == original_action_para &&
			 town_array[original_action_para]->nation_recno == nation_recno )
		{
			unit_array.assign( original_action_x_loc, original_action_y_loc, 0,
									 COMMAND_AUTO, selectedArray, 1 );
		}
	}

	//--------- resume assign to firm ----------//

	else if( original_action_mode == ACTION_ASSIGN_TO_FIRM && locPtr->is_firm() )
	{
		if( locPtr->firm_recno() == original_action_para &&
			 firm_array[original_action_para]->nation_recno == nation_recno )
		{
			unit_array.assign( original_action_x_loc, original_action_y_loc, 0,
									 COMMAND_AUTO, selectedArray, 1 );
		}
	}

	//--------- resume build firm ---------//

	else if( original_action_mode == ACTION_BUILD_FIRM )
	{
		if( world.can_build_firm( original_action_x_loc, original_action_y_loc,
										  original_action_para, sprite_recno ) )
		{
			build_firm( original_action_x_loc, original_action_y_loc,
							original_action_para, COMMAND_AUTO );
		}
	}

	//--------- resume settle ---------//

	else if( original_action_mode == ACTION_SETTLE )
	{
		if( world.can_build_town( original_action_x_loc, original_action_y_loc, sprite_recno ) )
		{
			unit_array.settle( original_action_x_loc, original_action_y_loc,
									 0, COMMAND_AUTO, selectedArray, 1 );
		}
	}

	//--------- resume move ----------//

	else if( original_action_mode == ACTION_MOVE )
	{
		unit_array.move_to( original_action_x_loc, original_action_y_loc, 0,
								  selectedArray, 1, COMMAND_AUTO );
	}

	original_action_mode = 0;
}
Example #13
0
File: osite.cpp Project: 112212/7k2
//--------- Begin of function SiteArray::next_day ----------//
//
void SiteArray::next_day()
{
	if( info.game_date%30 == 0 )
	{
		generate_raw_site();		// check if we need to generate existing raw sites are being used up and if we need to generate new ones
	}

	//-- if there is any scroll or gold coins available, ask AI to get them --//

	// #### begin Gilbert 3/11 ######//
	if(scroll_count || gold_coin_count || item_count || weapon_blueprint_count )
	// #### end Gilbert 3/11 ######//
	{
		int aiGetSiteObject = (info.game_date%5 == 0);

		Site* sitePtr;
		Location *locPtr;

		for(int i=size(); i; i--)
		{
			if(is_deleted(i))
				continue;

			sitePtr = site_array[i];

			switch(sitePtr->site_type)
			{
				case SITE_SCROLL:
				case SITE_GOLD_COIN:
				case SITE_ITEM:
				case SITE_WEAPON_BLUEPRINT:
					locPtr = world.get_loc(sitePtr->map_x_loc, sitePtr->map_y_loc);

					//---- if the unit is standing on a scroll site -----//

					if(locPtr->unit_recno(UNIT_LAND))
					{
						// ####### begin Gilbert 25/5 ##########//
						int unitRecno = locPtr->unit_recno(UNIT_LAND);
						if( !unit_array.is_deleted(unitRecno) )
							sitePtr->get_site_object( unitRecno );
						// ####### end Gilbert 25/5 ##########//
					}
					else if(aiGetSiteObject)
					{
						sitePtr->ai_get_site_object();
               }
					break;
			}
		}
	}

	//-------- debug testing --------//

#ifdef DEBUG

	if( info.game_date%10 == 0 )
	{
		Site* sitePtr;
		Location* locPtr;

		for( int i=1 ; i<=size() ; i++ )
		{
			if( site_array.is_deleted(i) )
				continue;

			sitePtr = site_array[i];

			locPtr = world.get_loc( sitePtr->map_x_loc, sitePtr->map_y_loc );

			err_when( !locPtr->has_site() );
			err_when( locPtr->site_recno() != i );

			if( sitePtr->has_mine )
			{
				err_when( !locPtr->is_firm() );
				err_when( firm_array[locPtr->firm_recno()]->firm_id != FIRM_MINE
					&& firm_array[locPtr->firm_recno()]->firm_id != FIRM_ALCHEMY );
			}
			else
			{
				// disable because a mine can be upon more than one mine
				// err_when( locPtr->is_firm() || locPtr->is_town() );
			}
		}
	}
#endif
}
Example #14
0
//------- Begin of function Town::think_attack_nearby_enemy -------//
//
// Think about attacking enemies near the town.
//
int Town::think_attack_nearby_enemy()
{
	enum { SCAN_X_RANGE = 6,
			 SCAN_Y_RANGE = 6  };

	int xLoc1 = loc_x1 - SCAN_X_RANGE;
	int yLoc1 = loc_y1 - SCAN_Y_RANGE;
	int xLoc2 = loc_x2 + SCAN_X_RANGE;
	int yLoc2 = loc_y2 + SCAN_Y_RANGE;

	xLoc1 = max( xLoc1, 0 );
	yLoc1 = max( yLoc1, 0 );
	xLoc2 = min( xLoc2, MAX_WORLD_X_LOC-1 );
	yLoc2 = min( yLoc2, MAX_WORLD_Y_LOC-1 );

	//------------------------------------------//

	int		enemyCombatLevel=0;		// the higher the rating, the easier we can attack the target town.
	int 		xLoc, yLoc;
	int		enemyXLoc= -1, enemyYLoc;
	Unit* 	unitPtr;
	Nation* 	nationPtr = nation_array[nation_recno];
	Firm*		firmPtr;
	Location* locPtr;

	for( yLoc=yLoc1 ; yLoc<=yLoc2 ; yLoc++ )
	{
		locPtr = world.get_loc(xLoc1, yLoc);

		for( xLoc=xLoc1 ; xLoc<=xLoc2 ; xLoc++, locPtr++ )
		{
         //--- if there is an enemy unit here ---// 

			if( locPtr->has_unit(UNIT_LAND) )
			{
				unitPtr = unit_array[ locPtr->unit_recno(UNIT_LAND) ];

				if( !unitPtr->nation_recno )
					continue;

				//--- if the unit is idle and he is our enemy ---//

				if( unitPtr->cur_action == SPRITE_IDLE &&
					 nationPtr->get_relation_status(unitPtr->nation_recno) == NATION_HOSTILE )
				{
					err_when( unitPtr->nation_recno == nation_recno );

					enemyCombatLevel += (int) unitPtr->hit_points;

					if( enemyXLoc == -1 || m.random(5)==0 )
					{
						enemyXLoc = xLoc;
						enemyYLoc = yLoc;
					}
				}
			}

			//--- if there is an enemy firm here ---//

			else if( locPtr->is_firm() )
			{
				firmPtr = firm_array[locPtr->firm_recno()];

				//------- if this is a monster firm ------//

				if( firmPtr->firm_id == FIRM_MONSTER )		// don't attack monster here, OAI_MONS.CPP will handle that
					continue;

				//------- if this is a firm of our enemy -------//

				if( nationPtr->get_relation_status(firmPtr->nation_recno) == NATION_HOSTILE )
				{
					err_when( firmPtr->nation_recno == nation_recno );

					if( firmPtr->worker_count == 0 )
						enemyCombatLevel += 50;			// empty firm
					else
					{
						Worker* workerPtr = firmPtr->worker_array;

						for( int i=firmPtr->worker_count ; i>0 ; i--, workerPtr++ )
							enemyCombatLevel += workerPtr->hit_points;
					}

					if( enemyXLoc == -1 || m.random(5)==0 )
					{
						enemyXLoc = firmPtr->loc_x1;
						enemyYLoc = firmPtr->loc_y1;
					}
				}
			}
		}
	}

	//--------- attack the target now -----------//

	if( enemyCombatLevel > 0 )
	{
		err_when( enemyXLoc < 0 );

		nationPtr->ai_attack_target( enemyXLoc, enemyYLoc, enemyCombatLevel );
		return 1;
	}

	return 0;
}
Example #15
0
//--------- Begin of function Bullet::check_hit -------//
// check if the bullet hit a target
// return true if hit
int Bullet::check_hit()
{
	err_when(SCAN_RANGE != 5);
	
	short x,y;
	short townHit[SCAN_RANGE*SCAN_RANGE];
	short firmHit[SCAN_RANGE*SCAN_RANGE];
	int hitCount = 0;
	int townHitCount = 0;
	int firmHitCount = 0;

	for( int c = 0; c < SCAN_RANGE*SCAN_RANGE; ++c )
	{
		x = target_x_loc + spiral_x[c];
		y = target_y_loc + spiral_y[c];
		if( x >= 0 && x < world.max_x_loc && y >= 0 && y < world.max_y_loc )
		{
			Location *locPtr = world.get_loc(x, y);
			if(target_mobile_type==UNIT_AIR)
			{
				if(locPtr->has_unit(UNIT_AIR))
				{
					hit_target(x,y);
					hitCount++;
				}
			}
			else
			{
				if(locPtr->is_firm())
				{
					short firmRecno = locPtr->firm_recno();
					// check this firm has not been attacked
					short *firmHitPtr;
					for( firmHitPtr = firmHit+firmHitCount-1; firmHitPtr >= firmHit; --firmHitPtr )
					{
						if( *firmHitPtr == firmRecno )
							break;
					}
					if( firmHitPtr < firmHit )				// not found
					{
						firmHit[firmHitCount++] = firmRecno;
						hit_building(x,y);
						hitCount++;
					}
				}
				else if( locPtr->is_town() )
				{
					short townRecno = locPtr->town_recno();
					// check this town has not been attacked
					short *townHitPtr;
					for( townHitPtr = townHit+townHitCount-1; townHitPtr >= townHit; --townHitPtr )
					{
						if( *townHitPtr == townRecno )
							break;
					}
					if( townHitPtr < townHit )				// not found
					{
						townHit[townHitCount++] = townRecno;
						hit_building(x,y);
						hitCount++;
					}
				}
				else if(locPtr->is_wall())
				{
					hit_wall(x,y);
					hitCount++;
				}
				else
				{
					hit_target(x,y);	// note: no error checking here because mobile_type should be taken into account
					hitCount++;
				}
			}
		}
	}

	return hitCount;
}
Example #16
0
//--------- Begin of function SiteArray::next_day ----------//
//
void SiteArray::next_day()
{
	if( info.game_date%30 == 0 )
	{
		generate_raw_site();		// check if we need to generate existing raw sites are being used up and if we need to generate new ones
	}

	//-- if there is any scroll or gold coins available, ask AI to get them --//

	if(scroll_count || gold_coin_count)
	{
		int aiGetSiteObject = (info.game_date%5 == 0);

		Site* sitePtr;
		Location *locPtr;

		for(int i=size(); i; i--)
		{
			if(is_deleted(i))
				continue;

			sitePtr = site_array[i];

			switch(sitePtr->site_type)
			{
				case SITE_SCROLL:
				case SITE_GOLD_COIN:
						locPtr = world.get_loc(sitePtr->map_x_loc, sitePtr->map_y_loc);

						//---- if the unit is standing on a scroll site -----//

						if(locPtr->has_unit(UNIT_LAND))
						{
							sitePtr->get_site_object( locPtr->unit_recno(UNIT_LAND) );
						}
						else if(aiGetSiteObject)
						{
							sitePtr->ai_get_site_object();
                  }
						break;
			}
		}
	}

	//-------- debug testing --------//

#ifdef DEBUG

	if( info.game_date%10 == 0 )
	{
		Site* sitePtr;
		Location* locPtr;

		for( int i=1 ; i<=size() ; i++ )
		{
			if( site_array.is_deleted(i) )
				continue;

			sitePtr = site_array[i];

			locPtr = world.get_loc( sitePtr->map_x_loc, sitePtr->map_y_loc );

			err_when( !locPtr->has_site() );
			err_when( locPtr->site_recno() != i );

			if( sitePtr->has_mine )
			{
				err_when( !locPtr->is_firm() );
				err_when( firm_array[locPtr->firm_recno()]->firm_id != FIRM_MINE );
			}
			else
			{
				err_when( locPtr->is_firm() || locPtr->is_town() );
			}
		}
	}
#endif
}
Example #17
0
// ----- begin of function ScenarioEditor::detect_monster_view ------//
//
int ScenarioEditor::detect_monster_view()
{
	if( power.command_id )
		return 0;

	// detect map area

	if( mouse.double_click( ZOOM_X1, ZOOM_Y1, ZOOM_X2, ZOOM_Y2, 0 ) )	// left click
	{
		int xLoc, yLoc;
		if( world.zoom_matrix->get_detect_location(mouse.click_x(0), mouse.click_y(0),
			&xLoc, &yLoc, NULL) )
		{
			if( unit_or_struct == 0 && !vbrowse_unit_id.none_record )
			{
				// put unit monster_unit_id_array[monster_unit_id_browse_recno-1]
				// on (xLoc, yLoc)
				int unitId = monster_unit_id_array[monster_unit_id_browse_recno-1];
				UnitInfo *unitInfo = unit_res[unitId];
				SpriteInfo *spriteInfo = sprite_res[unitInfo->sprite_id];
				if( world.check_unit_space(xLoc, yLoc, 
					xLoc+spriteInfo->loc_width-1, yLoc+spriteInfo->loc_height-1, unitInfo->mobile_type) )
				{
					unit_array.add_unit( unitId, brush_player_recno, RANK_SOLDIER, 100, xLoc, yLoc );
				}
			}
			else if( unit_or_struct == 1 && !vbrowse_firm_build.none_record )
			{
				err_when( monster_firm_group_array[monster_firm_group_browse_recno-1] == 0 );
				// put firm group monster_firm_group_array[monster_firm_group_browse_recno]
				// on (xLoc, yLoc)

				FirmGroup *firmGroup = firm_res.get_group(monster_firm_group_array[monster_firm_group_browse_recno-1]);
				if( world.can_build_firm( xLoc, yLoc, firmGroup->firm_id, 0) )
				{
					if( brush_player_recno && nation_array[brush_player_recno]->is_human() 
						&& firm_res[firmGroup->firm_id]->setup_live_points_cost > 0 )
					{
						box.msg( text_editor.str_no_human() ); // "Human Kingdom cannot possess Fryhtan structure" );
					}
					else if (brush_player_recno == 0 && firmGroup->firm_id != FIRM_LAIR)
					{
						box.msg( text_editor.str_no_independent() ); // "Cannot add any Independent structures" );
					}
					else
					{
						firm_array.generate_firm( xLoc, yLoc, brush_player_recno, firmGroup->firm_id, firmGroup->race_code );
					}
				}
			}
		}
		return 1;
	}

	// ------ remove object -------//

	if( mouse.double_click( ZOOM_X1, ZOOM_Y1, ZOOM_X2, ZOOM_Y2, 1) )	// right click to remove
	{
		int xLoc, yLoc;
		char mobileType;
		Location* locPtr = power.test_detect(mouse.click_x(1), mouse.click_y(1), &mobileType, &xLoc, &yLoc );
		if( locPtr )
		{
			if( locPtr->unit_recno(mobileType) )		// remove unit
			{
				int unitRecno = locPtr->unit_recno(mobileType);
				if( !unit_array.is_deleted(unitRecno) )
					unit_array[unitRecno]->hit_points = 0.0f;
			}
			else if( locPtr->is_firm() )				// remove firm
			{
				int firmRecno = locPtr->firm_recno();
				if( !firm_array.is_deleted(firmRecno) )
				{
					firm_array.del_firm( firmRecno );
				}
			}
			else if( locPtr->is_town() )				// remove town
			{
				int townRecno = locPtr->town_recno();
				if( !town_array.is_deleted(townRecno) )
				{
					town_array.del_town(townRecno);
				}
			}
		}
		return 1;
	}
	return 0;
}
Example #18
0
//--------- Begin of function UnitGod::cast_on_loc ---------//
//
void UnitGod::cast_on_loc(int castXLoc, int castYLoc)
{
	Location* locPtr = world.get_loc( castXLoc, castYLoc );

	//--- if there is any unit on the location ---//

	if( locPtr->has_unit(UNIT_LAND) )
	{
		cast_on_unit( locPtr->unit_recno(UNIT_LAND), 1 );
	}
	else if( locPtr->has_unit(UNIT_SEA) )
	{
		Unit* unitPtr = unit_array[ locPtr->unit_recno(UNIT_SEA) ];

		//-- only heal human units belonging to our nation in ships --//

		if( unitPtr->nation_recno == nation_recno &&
			 unit_res[unitPtr->unit_id]->unit_class == UNIT_CLASS_SHIP )
		{
			UnitMarine* unitMarine = (UnitMarine*) unitPtr;

			for( int i=0 ; i<unitMarine->unit_count ; i++ )
			{
				int divider = 4;		// the size of a ship is 4 locations (2x2)

				cast_on_unit( unitMarine->unit_recno_array[i], divider );		// the effects are weaken on ship units, only 50% of the original effects
			}
		}
	}

	//--------- on firms ---------//

	else if( locPtr->is_firm() )
	{
		Firm* firmPtr = firm_array[ locPtr->firm_recno() ];
		int	divider = (firmPtr->loc_x2-firmPtr->loc_x1+1) * (firmPtr->loc_y2-firmPtr->loc_y1+1);
		if( god_id == GOD_ZULU )
			divider = 1;		// range of zulu god is 1, no need to divide

		if( firmPtr->overseer_recno )
		{
			cast_on_unit( firmPtr->overseer_recno, divider );
		}

		if( firmPtr->worker_array && firm_res[firmPtr->firm_id]->live_in_town==0 )
		{
			Worker* workerPtr = firmPtr->worker_array;

			for( int i=0 ; i<firmPtr->worker_count ; i++, workerPtr++ )
			{
				cast_on_worker(workerPtr, firmPtr->nation_recno, divider);
			}
		}
	}

	//--------- on towns ----------//

	else if( locPtr->is_town() )
	{
		Town* townPtr = town_array[ locPtr->town_recno() ];

		if( god_id == GOD_JAPANESE && townPtr->nation_recno != nation_recno)
		{
			int divider = STD_TOWN_LOC_WIDTH * STD_TOWN_LOC_HEIGHT;

			for( int i=0 ; i<MAX_RACE ; i++ )
			{
				if( townPtr->race_pop_array[i]==0 )
					continue;

				float changePoints = (float)7 + misc.random(8);		// decrease 7 to 15 loyalty points instantly

				if( townPtr->nation_recno )
					townPtr->change_loyalty(i+1, -changePoints/divider);
				else
					townPtr->change_resistance(i+1, nation_recno, -changePoints/divider);
			}
		}
		else if( god_id == GOD_EGYPTIAN && townPtr->nation_recno == nation_recno)
		{
			int headCount;
			int raceId;

			for( headCount = 5; headCount > 0 && townPtr->population < MAX_TOWN_GROWTH_POPULATION
				&& (raceId = townPtr->pick_random_race(1,1)); --headCount )
			{
				townPtr->inc_pop(raceId, 0, (int)townPtr->race_loyalty_array[raceId-1]);
			}
		}
	}
}