void CTFBotVision::Update()
{
	if (TFGameRules()->IsMannVsMachineMode()) {
		if (!this->m_ctUpdate.IsElapsed()) {
			return;
		}
		
		this->m_ctUpdate.Start(RandomFloat(0.9f, 1.1f));
	}
	
	IVision::Update();
	
	CTFBot *actor = static_cast<CTFBot *>(this->GetBot()->GetEntity());
	if (actor == nullptr) {
		return;
	}
	
	CUtlVector<CTFPlayer *> enemies;
	CollectPlayers<CTFPlayer>(enemies, GetEnemyTeam(actor), true, false);
	
	FOR_EACH_VEC(enemies, i) {
		CTFPlayer *enemy = enemies[i];
		
		if (enemy->IsPlayerClass(TF_CLASS_SPY)) {
			const CKnownEntity *known = this->GetKnown(enemy);
			
			if (known != nullptr && (known->IsVisibleRecently() ||
				!player->m_Shared.InCond(TF_COND_DISGUISING))) {
				actor->ForgetSpy(enemy);
			}
		}
	}
Esempio n. 2
0
int SquadronClass::MoveUnit (CampaignTime time)
	{
	GridIndex       x,y,nx,ny;
	VuGridIterator*	myit = NULL;
	Objective		o,bo=NULL;
	float			fd;
	int				range,score,i,want_alert=0,bs=-999;
	CampEntity		ab;
	
/*  Don't recall squadrons - per Gilman
	if (GetTotalVehicles() < GetFullstrengthVehicles() / 4)
		{
		if (this == FalconLocalSession->GetPlayerSquadron())
			PostMessage(FalconDisplay.appWin,FM_SQUADRON_RECALLED,0,0);
		KillUnit();
		}
*/


//TJL 11/02/03 Enable Scramble missions

	if (g_bScramble)
	{
	// Set up an alert bird for this squadron
	if (rating[ARO_CA] > 4)
		{
		// KCK: Check if we have available aircraft 
		// NOTE: We might want to make sure we always ask for at least one
		// alert flight.
		for (i=0; i<VEHICLES_PER_UNIT/2; i++)
			{
			if (!schedule[i])
				want_alert = 1;
			}

		if (want_alert)
			{
//#ifdef DEBUG
			MonoPrint("Requesting alert bird for squadron #%d.\n",GetCampID());
//#endif
			MissionRequestClass	mis;
			// JB 010728 Make the wait time configurable
			// MN 020102 This is not the relocation timer - check above
//			mis.tot = Camp_GetCurrentTime() + g_nRelocationWait * CampaignHours;			// hang around for a few hours
			mis.tot = Camp_GetCurrentTime() + 3 * CampaignHours;
			mis.requesterID = Id();
			mis.who = GetTeam();
			mis.vs = GetEnemyTeam(mis.who);
			mis.tot_type = TYPE_NE;
			GetLocation(&mis.tx,&mis.ty);
			mis.targetID = FalconNullId;
			mis.mission = AMIS_ALERT;
			mis.roe_check = ROE_AIR_ENGAGE;
			mis.flags = REQF_ONETRY	| REQF_USE_REQ_SQUAD | REQF_USERESERVES;
			mis.priority = 255;											// High priority
			mis.RequestMission();
			}
		}
	}
	else
	{
	}

//TJL 11/02/03 End Scramble


	// OW AB Relocation fix
	if(g_bEnableABRelocation)
	{
		if(SimLibElapsedTime < 32450000.0f)
			return 0; //me123 dont relocate before the campaign has begun
	}

	ab = FindEntity(airbase_id);

// A.S. begin
	CampEntity		ab_old;  // A.S. new variable
	if (g_bHelosReloc)
		{
		ab_old = ab;  
		}
// A.S. end



	ShiAssert (!ab || ab->IsObjective() || ab->IsTaskForce() || (ab == this && DontPlan()));

	if (!ab || ab->IsObjective() || ab == this)
		{
		// Don't plan flag used to mean don't rebase for squadrons
		if (DontPlan())
			{
// 2001-08-06 MODIFIED BY S.G. FRIENDLY BASE WILL DO THE JOB ALL RIGHT. NO NEED TO LIMIT IT TO OUR TEAM.
//			if (ab->GetTeam() != GetTeam())
			if (!ab || !GetRoE(ab->GetTeam(), GetTeam(), ROE_AIR_USE_BASES))
				{
				if (this == FalconLocalSession->GetPlayerSquadron())
					PostMessage(FalconDisplay.appWin,FM_SQUADRON_RECALLED,0,0);
				KillUnit();
				}
			return 0;
			}

		// If airbase is non-functional, force a rebase
// 2001-08-03 MODIFIED BY S.G. ONLY IF CAPTURED SHOULD IT RELOCATE. DESTROYED AIRBASE STILL OWN BY US WILL REPAIR EVENTUALLY.
//		if (ab && ab->IsObjective() && ((Objective)ab)->GetAdjustedDataRate() < 1)
		if (ab && ab->IsObjective() && !GetRoE(ab->GetTeam(), GetTeam(), ROE_AIR_USE_BASES))
			ab = NULL;
// Added by A.S. 1.1.2002.  Helos will be reallocated if armybase is destoyed. 
		if (g_bHelosReloc) 
			{
			if (ab && ab->IsObjective() && IsHelicopter() && ((Objective)ab)->GetAdjustedDataRate() < 1) 
				{  
				ab = NULL;																
			//	FILE *deb;
			//	deb = fopen("c:\\temp\\realloc.txt", "a");
			//	fprintf(deb, "ArmyBase  ID = %d  team = %x  type = %x  TIME = %d\n",  ab_old, ab_old->GetTeam, ab_old->GetType, TheCampaign.CurrentTime/(3600*1000));
			//	fclose(deb);
				}
			}
// A.S. end
		// Check airbase location - if to near or far from front, relocate
		GetLocation(&x,&y);
		fd = DistanceToFront(x,y);
		range = GetUnitRange();
// 2001-07-05 MODIFIED BY S.G. DON'T RELOCATE IF TOO FAR FROM FLOT IF GLOBALLY SET TO ACT THAT WAY
//		if (fd < 999.0F && (fd < range/30 || fd > range/3 || !ab))		// We're to close or to far from the front or don't have an airbase
		if (fd < 999.0F && (fd < range/30 || (!(g_nAirbaseReloc & AirBaseRelocNoFar) && fd > range/3) || !ab))		// We're to close or to far from the front or don't have an airbase
			{
			// Find a better base for us
			UnitClassDataType	*uc = GetUnitClassData();
			ATMAirbaseClass		*atmbase;
			Team				us = GetTeam();
			CAMPREGLIST_ITERATOR		myit(AllObjList);
			o = (Objective) myit.GetFirst();
			while (o)
				{
// 2001-07-05 MODIFIED BY S.G. ONLY USE YOUR OWN AIRBASE IF GLOBALLY SET TO ACT THAT WAY
//				if ((o->GetType() == TYPE_AIRBASE && !IsHelicopter() && GetRoE(o->GetTeam(),us,ROE_AIR_USE_BASES)) ||
//					(o->GetType() == TYPE_ARMYBASE && IsHelicopter() && GetRoE(o->GetTeam(),us,ROE_AIR_USE_BASES)))
				int enter = FALSE;
				if (g_nAirbaseReloc & AirBaseRelocTeamOnly) {
					if ((o->GetType() == TYPE_AIRBASE && !IsHelicopter() && o->GetTeam() == us) ||
						(o->GetType() == TYPE_ARMYBASE && IsHelicopter() && o->GetTeam() == us))
						enter = TRUE;
				}
				else {
					if ((o->GetType() == TYPE_AIRBASE && !IsHelicopter() && GetRoE(o->GetTeam(),us,ROE_AIR_USE_BASES)) ||
						(o->GetType() == TYPE_ARMYBASE && IsHelicopter() && GetRoE(o->GetTeam(),us,ROE_AIR_USE_BASES)))
						enter = TRUE;
				}
				if (enter)
// END OF MODIFIED SECTION
					{
					o->GetLocation(&nx,&ny);
					fd = DistanceToFront(nx,ny);
					if (fd > range/15 && o->GetAdjustedDataRate() > 0)
						{
						score = o->GetObjectiveStatus()*5 - FloatToInt32(fd);
						// Adjust by number of squadrons already based here.
						atmbase = TeamInfo[us]->atm->FindATMAirbase (o->Id());
						if (atmbase && atmbase->usage)
						// JB 010328 from Mad__Max
							//score /= atmbase->usage;
						{
							if (o != ab)  score /= (atmbase->usage+1);
							if (o == ab) score /= atmbase->usage;
						}
						// JB 010328 from Mad__Max

						if (score > bs)
							{
							bo = o;
							bs = score;
							}
						}
					}
				o = (Objective) myit.GetNext();
				}
			if (bo)
				{
				if (bo != ab)
					{
					bo->GetLocation(&nx,&ny);
					SetLocation(nx,ny);
					SetUnitAirbase(bo->Id());
					TeamInfo[us]->atm->AddToAirbaseList(bo);
					if (this == FalconLocalSession->GetPlayerSquadron())
						PostMessage(FalconDisplay.appWin,FM_SQUADRON_REBASED,0,0);
// 2001-07-05 MODIFIED BY S.G. RETASK IN ONE DAY ONLY
// 020102 M.N. Variable relocate time
					squadronRetaskAt = Camp_GetCurrentTime() + CampaignHours * g_nRelocationWait;
// A.S.  begin: retask time for Helos only 1 hour 
					if (g_bHelosReloc) 
						{
						if (ab_old && ab_old->IsObjective() && ((Objective)ab_old)->GetAdjustedDataRate() < 1)  
							{
							if ( IsHelicopter() ) 
								{
								squadronRetaskAt = Camp_GetCurrentTime() + CampaignHours * 1;
							//	FILE *deb;
							//	deb = fopen("c:\\temp\\realloc.txt", "a");
							//	fprintf(deb, "====> squadronRetaskAt ID = %d  ID_neu %d  team = %x  type = %x  TIME = %d\n\n", ab_old, bo, ab_old->GetTeam, ab_old->GetType, TheCampaign.CurrentTime/(3600*1000));
							//	fclose(deb);
								}
							}
						}
// A.S. end +++++++++++++++++
					}
				}
			else
				{
				// We're lost
				if (this == FalconLocalSession->GetPlayerSquadron())
					PostMessage(FalconDisplay.appWin,FM_SQUADRON_RECALLED,0,0);
				KillUnit();
				return 0;
				}
			}
		}
	

	// Set up an alert bird for this squadron
	//TJL 10/31/03 Move This
/*	if (rating[ARO_CA] > 5)
		{
		// KCK: Check if we have available aircraft 
		// NOTE: We might want to make sure we always ask for at least one
		// alert flight.
		for (i=0; i<VEHICLES_PER_UNIT/2; i++)
			{
			if (!schedule[i])
				want_alert = 1;
			}

		if (want_alert)
			{
#ifdef DEBUG
//			MonoPrint("Requesting alert bird for squadron #%d.\n",GetCampID());
#endif
			MissionRequestClass	mis;
			// JB 010728 Make the wait time configurable
			// MN 020102 This is not the relocation timer - check above
//			mis.tot = Camp_GetCurrentTime() + g_nRelocationWait * CampaignHours;			// hang around for a few hours
			mis.tot = Camp_GetCurrentTime() + 3 * CampaignHours;
			mis.requesterID = Id();
			mis.who = GetTeam();
			mis.vs = GetEnemyTeam(mis.who);
			mis.tot_type = TYPE_NE;
			GetLocation(&mis.tx,&mis.ty);
			mis.targetID = FalconNullId;
			mis.mission = AMIS_ALERT;
			mis.roe_check = ROE_AIR_ENGAGE;
			mis.flags = REQF_ONETRY	| REQF_USE_REQ_SQUAD | REQF_USERESERVES;
			mis.priority = 255;											// High priority
			mis.RequestMission();
			}
		} */

	return 0;
	}
Esempio n. 3
0
// Supplies units - must be called by Campaign Master
int SupplyUnits (Team who, CampaignTime deltaTime)
{
	Objective		o,s;
	Unit			unit;
	int				supply,fuel,replacements,gots,gotf,type;
	int				sneeded=0,fneeded=0,rneeded=0;
	float			sratio,fratio,rratio;
	GridIndex		x,y;
	MissionRequestClass	mis;
	// A.S. begin additional variables 2001-12-09
	// A.S. We now distinguish between aircrafts and ground vehicles 
	int				rneeded_a=0, rneeded_v=0, repl_a=0, repl_v=0;	
	float			rratio_a, rratio_v,	a_v_nratio, repl; 			// A.S. 
	float			sqnbonus, lambda;								// A.S. 
	int				repl_a_s = 0, repl_v_s = 0, repl_s = 0, repl_sa = 0, prob = 0;	// A.S. debug variables
	// end added section

	if (!TeamInfo[who] || !(TeamInfo[who]->flags & TEAM_ACTIVE))
		return 0;

	sratio = fratio = rratio = 0.0F;

	// A.S. begin, 2001-12-09.
	rratio_a = rratio_v = a_v_nratio = repl = lambda = 0.0F;		// A.S.
	sqnbonus = RelSquadBonus;									    // A.S. gives Sqn relative (!) more repl. than Bde.
	// end added section

	// zero supply values
	{
		VuListIterator objit(AllObjList);
		o = GetFirstObjective(&objit);
		while (o){
			if (o->GetTeam() == who)
				o->static_data.local_data = 0;
			o = GetNextObjective(&objit);
		}
	}

	// Calculate needs
	{
		VuListIterator myit(AllUnitList);
		unit = GetFirstUnit(&myit);
		while (unit)
		{
			if (unit->GetTeam() == who && (unit->IsBattalion() || unit->IsSquadron()))
			{
				sneeded += unit->GetUnitSupplyNeed(FALSE);
				fneeded += unit->GetUnitFuelNeed(FALSE);
				rneeded += unit->GetFullstrengthVehicles() - unit->GetTotalVehicles();
				// A.S. begin
				if (unit->IsSquadron() && NoTypeBonusRepl)		// A.S. extra calculation for squadrons 
				{
					rneeded_a += unit->GetFullstrengthVehicles() - unit->GetTotalVehicles(); 
				}														

				// end added section
			}
			unit = GetNextUnit(&myit);
		}
	}


	// A.S. begin, 2001-12-09.
	if (NoTypeBonusRepl) { 
		rneeded_v = rneeded - rneeded_a;						//A.S. calculation for groud vehicles
		if (rneeded > 0)
			a_v_nratio = ( (float)rneeded_a ) / rneeded;
		else
			a_v_nratio = 1;
		repl = (float)TeamInfo[who]->GetReplacementsAvail();    // aggregate replacements available
		lambda =  a_v_nratio * sqnbonus;
		if (lambda > 1)
			lambda = 1;
	}
	// end added section
	

	// Calculate the maximum ratio of supply we can give out
	if (sneeded > 0)
		sratio = (float)TeamInfo[who]->GetSupplyAvail() / sneeded;
	if (sratio > MAX_SUPPLY_RATIO)
		sratio = MAX_SUPPLY_RATIO;
	if (fneeded > 0)
		fratio = (float)TeamInfo[who]->GetFuelAvail() / fneeded;
	if (fratio > MAX_SUPPLY_RATIO)
		fratio = MAX_SUPPLY_RATIO;
	if (rneeded > 0)
		rratio = (float)TeamInfo[who]->GetReplacementsAvail() / rneeded;

	if (!NoTypeBonusRepl) // A.S. added if-condiion 2001-12-09 
	{
		if (rratio > 0.25F)	
			rratio = 0.25F;		
	}

	// A.S. begin, 2001-12-09
	if  (NoTypeBonusRepl) 
	{ 
		if (rratio > MAX_SUPPLY_RATIO) {		
			rratio = MAX_SUPPLY_RATIO;
		}
		if (rneeded_a > 0)
			rratio_a = repl / rneeded_a;			
		else
			rratio_a = MAX_SUPPLY_RATIO;
		if (rneeded_v > 0)
			rratio_v = repl / rneeded_v;
		else
			rratio_v = MAX_SUPPLY_RATIO;
		
		if (rratio_a > MAX_SUPPLY_RATIO)
			rratio_a = MAX_SUPPLY_RATIO;
		if (rratio_v > MAX_SUPPLY_RATIO)
			rratio_v = MAX_SUPPLY_RATIO;
		if (repl == 0) {							// to handle situations like 0/0 !
			rratio_a = 0;
			rratio_v = 0;
		}
	}
	// end added section


	// Supply units
	{
		VuListIterator myit(AllUnitList);
		unit = GetFirstUnit(&myit);
		while (unit)
		{
			// We only supply/repair Battalions and Squadrons
			if (
				unit->GetTeam() == who && (unit->IsBattalion() || unit->IsSquadron()) &&
				TheCampaign.CurrentTime - unit->GetLastResupplyTime() > unit->GetUnitSupplyTime()
			){
				float			typeBonus = 1.0F;

				if (unit->GetUnitCurrentRole() == GRO_ATTACK)
					typeBonus = 6.0F;
				if (unit->IsSquadron())
				{
					((SquadronClass*)unit)->ReinforcePilots(2);
					typeBonus = 2.0F;
				}
				// Add some randomness
				typeBonus += ((rand()%50)-25.0F)/100.0F;
				if (typeBonus < 0.0F)
					typeBonus = 0.0F;

				supply = FloatToInt32(unit->GetUnitSupplyNeed(FALSE) * sratio * typeBonus);
				fuel = FloatToInt32(unit->GetUnitFuelNeed(FALSE) * fratio * typeBonus);

				// A.S.  2001-12-09. No Type Bonus for replacements. This helps fixing the bug that units can get more replacements than available.
				if (NoTypeBonusRepl)
					typeBonus = 1.0F;		
				// end added section
				
				replacements = FloatToInt32((unit->GetFullstrengthVehicles() - unit->GetTotalVehicles()) * rratio * typeBonus);

				// A.S. begin, 2001-12-09
				repl_s += replacements;				// debug
				if (NoTypeBonusRepl) 	// New code for distinguishing between aircrafts and ground vehicles 
				{
					if (unit->IsSquadron())				// this algorithm guarantees that no team can get more repl than available
					{
						prob = rand() % 100;
						repl_a = FloatToInt32((unit->GetFullstrengthVehicles() - unit->GetTotalVehicles()) * (lambda) * rratio_a);
						if ( TeamInfo[who]->GetReplacementsAvail() >= 1  && prob < 51  &&  ( ((float)unit->GetTotalVehicles())/unit->GetFullstrengthVehicles() <= 0.8F)) // rounding up with probability 0.5
							repl_a = FloatToInt32( (float) ceil( (unit->GetFullstrengthVehicles() - unit->GetTotalVehicles()) * (lambda) * rratio_a) );
						if (repl_a > 0) 
						{
							TeamInfo[who]->SetReplacementsAvail( TeamInfo[who]->GetReplacementsAvail() - repl_a );
							unit->ChangeVehicles( min(repl_a, TeamInfo[who]->GetReplacementsAvail()) );
							repl_a_s += min(repl_a, TeamInfo[who]->GetReplacementsAvail()); // debug
						}
					}	
					else {
						prob = rand() % 100;
						repl_v = FloatToInt32((unit->GetFullstrengthVehicles() - unit->GetTotalVehicles()) * (1 - lambda) * rratio_v);
						if ( TeamInfo[who]->GetReplacementsAvail() > 12  && prob < 51  &&  ( ((float)unit->GetTotalVehicles())/unit->GetFullstrengthVehicles() <= 0.85F)) // rounding up
							repl_v = FloatToInt32( (float) ceil( (unit->GetFullstrengthVehicles() - unit->GetTotalVehicles()) * (1 - lambda) * rratio_v) );
						if (repl_v > 0) 
						{
							TeamInfo[who]->SetReplacementsAvail(TeamInfo[who]->GetReplacementsAvail() - repl_v);
							unit->ChangeVehicles( min(repl_v, TeamInfo[who]->GetReplacementsAvail()) );
							repl_v_s += min(repl_v, TeamInfo[who]->GetReplacementsAvail()); // debug
						}
					}
					// prob = rand() % 100;
				}
				else 
				{							
					if (replacements)	// ++++++ old code begin ++++++
					{
					TeamInfo[who]->SetReplacementsAvail(TeamInfo[who]->GetReplacementsAvail() - replacements);
					if (unit->IsSquadron())
						{
						repl_sa += replacements; // A.S. debug
						TeamInfo[who]->SetReplacementsAvail(TeamInfo[who]->GetReplacementsAvail() - replacements);
						unit->SetLastResupply(replacements);
						}
					unit->ChangeVehicles(replacements);
					}
				}	// end added section  (important: this section replaces(!) the section marked with ++++++ old code ++++++ !)
				
				if (fuel || supply)
				{
					unit->GetLocation(&x,&y);
					o = FindNearestFriendlyObjective(who, &x, &y, 0);
					if (o)
					{
						s = FindNearestSupplySource(o);
						if (s)
						{
							TeamInfo[who]->SetSupplyAvail(TeamInfo[who]->GetSupplyAvail() - supply);
							TeamInfo[who]->SetFuelAvail(TeamInfo[who]->GetFuelAvail() - fuel);
							gots = supply;
							gotf = fuel;
							if (SendSupply(s,o,&gots,&gotf))
								SupplyUnit(unit,supply,gots,fuel,gotf);
						}
					}
				}
				unit->SetLastResupplyTime(TheCampaign.CurrentTime);
			}
			unit = GetNextUnit(&myit);
		}
	}

	// A.S. debug begin
	//if (NoTypeBonusRepl) {
	//	if (who == 2 || who==6) {	
	//		FILE *deb;
	//		deb = fopen("c:\\temp\\deb1.txt", "a");
	//		fprintf(deb, "Team %2d  ReplaAvail = %3d  A_Needed = %3d  V_Needed %4d  Aircraft = %2d  Vehicle = %3d  TIME = %d\n", who, (int)repl, rneeded_a, rneeded_v, repl_a_s, repl_v_s, TheCampaign.CurrentTime );   
	//		fclose(deb);
	//	}
	//}
	//else {
	//	if (who == 2 || who==6) {	// A.S. debug
	//		FILE *deb;
	//		deb = fopen("c:\\temp\\deb1.txt", "a");
	//		fprintf(deb, "Team %2d  ReplaAvail = %3d  Needed = %3d | Repl_a = %2d repl_v = %3d | TIME = %d\n", who, TeamInfo[who]->GetReplacementsAvail(), rneeded, repl_sa, (repl_s-repl_sa) , TheCampaign.CurrentTime % CampaignHours );   
	//		fclose(deb);
	//	}
	//}
	// A.S. debug end

	// Reset loss values, set supply values, and request missions
	{
		VuListIterator objit(AllObjList);
		o = GetFirstObjective(&objit);
		while (o){
			if (o->GetTeam() == who){
				supply = LOBYTE(o->static_data.local_data);
				fuel = HIBYTE(o->static_data.local_data);
				if (supply > 5 || fuel > 5){
					o->SendObjMessage(o->Id(),FalconObjectiveMessage::objSetSupply,(short)(supply),(short)(fuel),0);
					type = o->GetType();
					if (type == TYPE_ROAD || type == TYPE_INTERSECT)
					{
						// Request an interdiction mission
						mis.requesterID = o->Id();
						o->GetLocation(&mis.tx,&mis.ty);
						mis.vs = o->GetTeam();
						mis.who = GetEnemyTeam(mis.vs);
						mis.tot = Camp_GetCurrentTime() + (30+rand()%480)*CampaignMinutes;
						mis.tot_type = TYPE_NE;
						mis.targetID = FalconNullId;
						mis.mission = AMIS_INT;
						mis.roe_check = ROE_AIR_ATTACK;
						mis.context = enemySupplyInterdictionZone;
						mis.RequestMission();
					}
					// RV - Biker - Do something special for bridges
					//if (type == TYPE_BRIDGE || type == TYPE_DEPOT || type == TYPE_PORT)
					if (type == TYPE_DEPOT || type == TYPE_PORT)
					{
						// Request an interdiction strike mission
						mis.requesterID = o->Id();
						o->GetLocation(&mis.tx,&mis.ty);
						mis.vs = o->GetTeam();
						mis.who = GetEnemyTeam(mis.vs);
						mis.tot = Camp_GetCurrentTime() + (30+rand()%480)*CampaignMinutes;
						mis.tot_type = TYPE_NE;
						mis.targetID = o->Id();
						mis.mission = AMIS_INTSTRIKE;
						mis.roe_check = ROE_AIR_ATTACK;

						if (type == TYPE_DEPOT)
								mis.context = enemySupplyInterdictionDepot;
						if (type == TYPE_PORT)
								mis.context = enemySupplyInterdictionPort;
						mis.RequestMission();
					}
					if (type == TYPE_BRIDGE) {
						// Check distance to FLOT
						GridIndex ox = 0, oy = 0;
						o->GetLocation(&ox, &oy);
						float dist = DistanceToFront(ox,oy);

						if (dist >= 50.0f) {
							mis.requesterID = o->Id();
							mis.tx = ox;
							mis.ty = oy;
							mis.vs = o->GetTeam();
							mis.who = GetEnemyTeam(mis.vs);
							mis.tot = Camp_GetCurrentTime() + (30+rand()%480)*CampaignMinutes;
							mis.tot_type = TYPE_NE;
							mis.targetID = o->Id();
							mis.mission = AMIS_INTSTRIKE;
							mis.roe_check = ROE_AIR_ATTACK;
							mis.context = enemySupplyInterdictionBridge;
							mis.RequestMission();
						}
					}
				}
			}
			o = GetNextObjective(&objit);
		}
	}
	return 1;
}
Esempio n. 4
0
// This function collects supply from all producers and adds it to the team's totals.
// This should be called by the Campaign Master only
int ProduceSupplies (CampaignTime deltaTime)
	{
	Objective		o, po;
	Team			who;
	float			rate;
	int				type;
	ulong			supply[NUM_TEAMS]={0},fuel[NUM_TEAMS]={0},s,f, power;
	ulong			replacements[NUM_TEAMS]={0};
	MissionRequestClass	mis;
	GridIndex x, y;

	// Produce supplies, fuel and reinforcements (factories and refineries)
	{
		VuListIterator	myit(AllObjList);
		o = GetFirstObjective(&myit);
		while (o)
		{
			type = o->GetType();
			//Cobra Added Army, depot, and port per JimG
			if ((type == TYPE_FACTORY || type == TYPE_ARMYBASE || type == TYPE_DEPOT || type == TYPE_PORT) 
				&& o->GetObjectiveOldown() == o->GetOwner())		// Supply
			{
			if (g_bPowerGrid) {
				o->GetLocation(&x, &y);
				po = FindNearestFriendlyPowerStation(AllObjList, o->GetTeam(), x, y);
				if (po) 
				power = po->GetObjectiveStatus();
				else power = 0;
			}
			else power = 100;
			
			s = o->GetObjectiveDataRate() * power / 100;
			if (s)
			{
				who = o->GetTeam(); 

				supply[who] += FloatToInt32( (s * DataRateModSup) );        // A.S.  2001-12-09 DataRateModification for supply and fuel only 
				replacements[who] += FloatToInt32( (s * DataRateModRepl) ); // A.S.  2001-12-09 DataRateModification for replacements only 

				// *** old code ***
	//				supply[who] += s;
	//			    replacements[who] += s;

			
				// Request an interdiction stike mission
				mis.requesterID = o->Id();
				o->GetLocation(&mis.tx,&mis.ty);
				mis.vs = who;
				mis.who = GetEnemyTeam(mis.vs);
				mis.tot = Camp_GetCurrentTime() + rand()%deltaTime + 30*CampaignMinutes;
				mis.tot_type = TYPE_NE;
				mis.targetID = o->Id();
				mis.mission = AMIS_INTSTRIKE;
				mis.roe_check = ROE_AIR_ATTACK;
				mis.context = enemyProductionSource;
				mis.priority = 0;
				mis.RequestEnemyMission();
				if (g_bPowerGrid) {
				// Request an interdiction stike mission against the power station
				mis.requesterID = po->Id();
				po->GetLocation(&mis.tx,&mis.ty);
				mis.vs = who;
				mis.who = GetEnemyTeam(mis.vs);
				mis.tot = Camp_GetCurrentTime() + rand()%deltaTime + 30*CampaignMinutes;
				mis.tot_type = TYPE_NE;
				mis.targetID = po->Id();
				mis.mission = AMIS_INTSTRIKE;
				mis.roe_check = ROE_AIR_ATTACK;
				mis.context = enemyFuelSource;
				mis.priority = 0;
				mis.RequestMission();
				}
			}
			}
			else if (type == TYPE_REFINERY && o->GetObjectiveOldown() == o->GetOwner())	// Fuel
			{
			if (g_bPowerGrid) {
				o->GetLocation(&x, &y);
				po = FindNearestFriendlyPowerStation(AllObjList, o->GetTeam(), x, y);
				if (po) 
				power = po->GetObjectiveStatus();
				else power = 0;
			}
			else power = 100;
			f = o->GetObjectiveDataRate() * power / 100;
			if (f)
			{
				who = o->GetTeam(); 
				fuel[who] += f;
				// Request an interdiction stike mission
				mis.requesterID = o->Id();
				o->GetLocation(&mis.tx,&mis.ty);
				mis.vs = who;
				mis.who = GetEnemyTeam(mis.vs);
				mis.tot = Camp_GetCurrentTime() + rand()%deltaTime + 30*CampaignMinutes;
				mis.tot_type = TYPE_NE;
				mis.targetID = o->Id();
				mis.mission = AMIS_INTSTRIKE;
				mis.roe_check = ROE_AIR_ATTACK;
				mis.context = enemyFuelSource;
				mis.priority = 0;
				mis.RequestMission();
				if (g_bPowerGrid) {
				// Request an interdiction stike mission against the power station
				mis.requesterID = po->Id();
				po->GetLocation(&mis.tx,&mis.ty);
				mis.vs = who;
				mis.who = GetEnemyTeam(mis.vs);
				mis.tot = Camp_GetCurrentTime() + rand()%deltaTime + 30*CampaignMinutes;
				mis.tot_type = TYPE_NE;
				mis.targetID = po->Id();
				mis.mission = AMIS_INTSTRIKE;
				mis.roe_check = ROE_AIR_ATTACK;
				mis.context = enemyFuelSource;
				mis.priority = 0;
				mis.RequestMission();
				}
			}
			}
		    
			// NOTE: IF WE WANT SPECIAL SUPPLY SOURCES (OFF-MAP SUPPLY SOURCES), ADD THE
			// BONUS HERE.
			// if (o->IsBonusSupplySource())
			//		supply += 1000;
		    
			o = GetNextObjective(&myit);
		}

	}
	// rates are per day - convert to this interval
	rate = (float)deltaTime/(float)CampaignDay;

	for (who = 0; who < NUM_TEAMS; who++)
		{
		int			actionBonus = TeamInfo[who]->GetGroundAction()->actionType;

		// A.S. 2001-12-09  No Action Type Bonus for production of supply, fuel and replacements
		if (NoActionBonusProd)
			actionBonus = 1;   
		// end added section
		
		supply[who] = AUTOMATIC_SUPPLY + FloatToInt32((supply[who]/5) * rate * actionBonus);
		fuel[who] = AUTOMATIC_SUPPLY + FloatToInt32(fuel[who] * rate * actionBonus);
		replacements[who] = AUTOMATIC_REPLACEMENTS + FloatToInt32((replacements[who]/40) * rate * actionBonus);

#ifdef DEBUG
		gSupplyFromProduction[who] += supply[who];
		gFuelFromProduction[who] += fuel[who];
		gReplacmentsFromProduction[who] += replacements[who];
#endif

		// Deplete unused extra supplies and move supplies to team supply pools
		supply[who] = (TeamInfo[who]->GetSupplyAvail()/2) + supply[who];
		fuel[who] = (TeamInfo[who]->GetFuelAvail()/2) + fuel[who];
		replacements[who] = TeamInfo[who]->GetReplacementsAvail() + replacements[who];

		if (supply[who] > MAX_SUPPLIES)
			supply[who] = MAX_SUPPLIES;
		TeamInfo[who]->SetSupplyAvail(supply[who]);
		if (fuel[who] > MAX_SUPPLIES)
			fuel[who] = MAX_SUPPLIES;
		TeamInfo[who]->SetFuelAvail(fuel[who]);
		TeamInfo[who]->SetReplacementsAvail(replacements[who]);
		}
	return 1;
	}
int FalconCampWeaponsFire::Process(uchar autodisp)
	{
	CampEntity	target = (CampEntity)vuDatabase->Find(EntityId());
	CampEntity	shooter = (CampEntity)vuDatabase->Find(dataBlock.shooterID);
	int			losses,shooterAc=255,i;
	FalconDeathMessage	*dtm = NULL;

	if (autodisp || !shooter || !target || !shooter->IsUnit())
		return -1;

	if (!target->IsAggregate())
		{
		// Whoops, this thing deaggregated out from under us.
		// If we're the host, actually start firing the stuff.
		if (shooter->IsLocal())
			FireOnSimEntity(shooter, target, dataBlock.weapon, dataBlock.shots, dataBlock.dPilotId);
		return 0;
		}

	shooter->ReturnToSearch();

	if (shooter->IsFlight()) {
	// Pick a pilot to get the kill
	if (dataBlock.fPilotId == 255)
		shooterAc = dataBlock.fPilotId = (uchar)((Flight)shooter)->PickRandomPilot(target->Id().num_);
	if (dataBlock.fPilotId >= PILOTS_PER_FLIGHT)
		shooterAc = ((Flight)shooter)->GetAdjustedPlayerSlot(dataBlock.fPilotId);
	else
		shooterAc = dataBlock.fPilotId;
	}
	else {
	    shooterAc = 0; // something
	}

	if (shooter->IsAggregate())
		{
		// Send a radio chatter message to LOCAL MACHINE if shooter is a flight
		if (shooter->IsFlight() && !SimDriver.InSim() && !(rand() % 20) )
			{
			// Send the chatter message;
			FalconRadioChatterMessage *msg = new FalconRadioChatterMessage(shooter->Id(), FalconLocalSession);
			msg->dataBlock.from = shooter->Id();
			msg->dataBlock.to = MESSAGE_FOR_TEAM;
			msg->dataBlock.voice_id = (uchar)((Flight)shooter)->GetPilotVoiceID(shooterAc);
			if (target->IsFlight())
				{
				msg->dataBlock.message = rcFIRING;
				// JWFU: Need callsign data stuff
				msg->dataBlock.edata[0] = WeaponDataTable[dataBlock.weapon[0]].Index;
				}
			else
				{
				msg->dataBlock.message = rcATTACKINGA;
				msg->dataBlock.edata[0] = ((Flight)shooter)->callsign_id;
				msg->dataBlock.edata[1] = (short)((Flight)shooter)->GetPilotCallNumber(shooterAc);
				target->GetLocation(&msg->dataBlock.edata[2],&msg->dataBlock.edata[3]);
				}
			FalconSendMessage(msg, FALSE);
			}

		// Synthisize a shot message for flight shooters in our package
		if (shooter->IsFlight() && (shooter->InPackage()||g_bLogEvents))
			{
			FalconWeaponsFire	wfm(FalconNullId,FalconLocalSession);
			wfm.dataBlock.fCampID = shooter->GetCampID();
			wfm.dataBlock.fPilotID = dataBlock.fPilotId;
			wfm.dataBlock.fIndex = (unsigned short)(((Unit)shooter)->GetVehicleID(0) + VU_LAST_ENTITY_TYPE);
			wfm.dataBlock.fSide = (unsigned char)shooter->GetOwner();
			wfm.dataBlock.fWeaponID = (unsigned short)(WeaponDataTable[dataBlock.weapon[0]].Index + VU_LAST_ENTITY_TYPE);
			// KCK: Since we don't really have a real weapon, use the current time for matching
			wfm.dataBlock.fWeaponUID.num_ = dataBlock.fWeaponUID.num_ = TheCampaign.CurrentTime;
			TheCampaign.MissionEvaluator->RegisterShot(&wfm);
			}

		// Do visual Effects (Aggregate shooters only)
		if (InterestingSFX(target->XPos(), target->YPos()))
			{
			for (i=0; i<MAX_TYPES_PER_CAMP_FIRE_MESSAGE && dataBlock.weapon[i] && dataBlock.shots[i]; i++)
				DoDistanceVisualEffects (shooter, target, dataBlock.weapon[i], dataBlock.shots[i]);
			}
		}

	// Synthisize a death message if either shooter or target is in our package
	if (shooter->InPackage() || target->InPackage())
		{
		dtm = new FalconDeathMessage(FalconNullId,FalconLocalSession);
		dtm->dataBlock.damageType = 0;
		if (target->IsFlight())
			dtm->dataBlock.dPilotID = (uchar)((Flight)target)->PickRandomPilot(target->GetCampID());
		dtm->dataBlock.dCampID = target->GetCampID();
		dtm->dataBlock.dSide = target->GetOwner();
		dtm->dataBlock.fCampID = shooter->GetCampID();
		dtm->dataBlock.fPilotID = dataBlock.fPilotId;
		dtm->dataBlock.fIndex = (unsigned short)(((Unit)shooter)->GetVehicleID(0) + VU_LAST_ENTITY_TYPE);
		dtm->dataBlock.fSide = shooter->GetOwner();
		dtm->dataBlock.fWeaponID = (unsigned short)(WeaponDataTable[dataBlock.weapon[0]].Index + VU_LAST_ENTITY_TYPE);
		dtm->dataBlock.fWeaponUID = dataBlock.fWeaponUID;
		}

	// Apply the damage data
	losses = target->DecodeDamageData(dataBlock.data, (Unit)shooter, dtm);

	// add some additional fire effects if losses were taken, the target is
	// a battalion and the target is in the sim lists
	if ( losses &&
		 target->InSimLists() &&
		 OTWDriver.IsActive() )
	{
		int i;
		Tpoint pos;

		// ground losses
		if ( target->IsBattalion() || target->IsObjective() )
		{
			pos.z = 40.0f;
	
			for ( i = 0; i < losses; i++ )
			{
				pos.x = target->XPos() + 800.0f * PRANDFloat();
				pos.y = target->YPos() + 800.0f * PRANDFloat();
				OTWDriver.AddSfxRequest( new SfxClass( SFX_CAMP_FIRE,
					 &pos,
					 60.0f,
					 90.0f ) );

				pos.x = target->XPos() + 800.0f * PRANDFloat();
				pos.y = target->YPos() + 800.0f * PRANDFloat();
				OTWDriver.AddSfxRequest( new SfxClass( SFX_CAMP_HIT_EXPLOSION_DEBRISTRAIL,
					 &pos,
					 2.0f,
					 200.0f ) );
			}
		}
		// air losses
		else
		{
	
			for ( i = 0; i < losses; i++ )
			{
				pos.x = target->XPos() + 800.0f * PRANDFloat();
				pos.y = target->YPos() + 800.0f * PRANDFloat();
				pos.z = target->ZPos() + 300.0f * PRANDFloat();
				OTWDriver.AddSfxRequest( new SfxClass( SFX_CAMP_HIT_EXPLOSION_DEBRISTRAIL,
					 &pos,
					 2.0f,
					 200.0f ) );
			}
		}

	}

	if (dtm)
		delete dtm;

	// Send a RadioChatter message to LOCAL MACHINE if shooter is a flight and scored a kill
	if (losses && shooter->IsFlight())
		{
		FalconRadioChatterMessage *msg = new FalconRadioChatterMessage(target->Id(), FalconLocalSession);
		msg->dataBlock.from = shooter->Id();
		msg->dataBlock.to = MESSAGE_FOR_TEAM;
		msg->dataBlock.voice_id = (uchar)((Flight)shooter)->GetPilotVoiceID(shooterAc);
		if (target->IsFlight())
			{
			msg->dataBlock.message = rcAIRBDA;
			msg->dataBlock.edata[0] = ((Flight)shooter)->callsign_id;
			msg->dataBlock.edata[1] = (short)((Flight)shooter)->GetPilotCallNumber(shooterAc);
			//MI uncommented the line below and outcommented the lines 
			//M.N. changed to 32767 which flexibly uses randomized values of available eval indexes
			msg->dataBlock.edata[2] = 32767; // couldn't stand the Hollywood kill calls
			/*if(rand()%2)
				  msg->dataBlock.edata[2] = 1;
			  else
				  msg->dataBlock.edata[2] = 9;*/
			}
		else if (target->IsTaskForce())
			{
			msg->dataBlock.message = rcMOVERBDA;
			msg->dataBlock.edata[0] = 32767;
			}
		else
			{
			if (target->IsUnit())
				{
				msg->dataBlock.message = rcMOVERBDA;
				msg->dataBlock.edata[0] = 32767;
				}
			else
				{
				msg->dataBlock.message = rcSTATICBDA;
				msg->dataBlock.edata[0] = ((Flight)shooter)->callsign_id;
				msg->dataBlock.edata[1] = (short)((Flight)shooter)->GetPilotCallNumber(shooterAc);
				msg->dataBlock.edata[2] = 32767;
				}
			}
		FalconSendMessage(msg, FALSE);
		}

	// Send a CampEvent message for weapon fire to the LOCAL MACHINE
	FalconCampEventMessage	*newEvent = new FalconCampEventMessage(shooter->Id(),FalconLocalSession);
	newEvent->dataBlock.flags = 0;
	newEvent->dataBlock.team = shooter->GetTeam();
	if (shooter->GetDomain() == DOMAIN_AIR)
		{
		if (target->IsObjective())
			newEvent->dataBlock.eventType = FalconCampEventMessage::campStrike;
		else if (target->GetDomain() == DOMAIN_AIR)
			newEvent->dataBlock.eventType = FalconCampEventMessage::campAirCombat;
		else if (target->GetDomain() == DOMAIN_LAND)
			newEvent->dataBlock.eventType = FalconCampEventMessage::campGroundAttack;
		else
			newEvent->dataBlock.eventType = FalconCampEventMessage::campCombat;
		}
	else
		newEvent->dataBlock.eventType = FalconCampEventMessage::campCombat;
	newEvent->dataBlock.data.vuIds[0] = shooter->Id();
	newEvent->dataBlock.data.vuIds[1] = target->Id();
	newEvent->dataBlock.data.owners[0] = shooter->GetOwner();
	newEvent->dataBlock.data.owners[1] = target->GetOwner();
	target->GetLocation(&newEvent->dataBlock.data.xLoc,&newEvent->dataBlock.data.yLoc);
	if (shooter->GetDomain() == DOMAIN_AIR)
		{
		// 2002-02-21 ADDED BY S.G. If it's not spotted and it's NOT the player, use the 'Bandit' vehicle so we don't warn the player on the identity of the shooter
		if (!shooter->GetIdentified(target->GetTeam()) && FalconLocalSession->GetTeam() != shooter->GetTeam())
			newEvent->dataBlock.data.textIds[0] = (short)(-1 * BANDIT_VEH);
		else
		// END OF ADDED SECTION 2002-02-21
			newEvent->dataBlock.data.textIds[0] = (short)(-1 * ((Unit)shooter)->GetVehicleID(0));

		if (target->IsObjective())
			{
			// Air Strikes
			newEvent->dataBlock.data.formatId = 1804;
			}
		else if (target->GetDomain() == DOMAIN_AIR)
			{
			// Air to air combat
			newEvent->dataBlock.data.formatId = 1805;
			// 2002-02-21 ADDED BY S.G. If it's not spotted and it's NOT the player, use the 'Bandit' vehicle so we don't warn the player on the identity of the shooter
			if (!target->GetIdentified(shooter->GetTeam()) && FalconLocalSession->GetTeam() != target->GetTeam())
				newEvent->dataBlock.data.textIds[1] = (short)(-1 * BANDIT_VEH);
			else
			// END OF ADDED SECTION 2002-02-21
				newEvent->dataBlock.data.textIds[1] = (short)(-1 * ((Unit)target)->GetVehicleID(0));
			}
		else
			{
			// Air attack
			newEvent->dataBlock.data.formatId = 1803;
			}
		}
	else if (shooter->GetDomain() == DOMAIN_SEA)
		{
		// Naval engagement
		newEvent->dataBlock.data.formatId = 1802;
		}
	else
		{
		if (target->IsObjective())
			{
			// Ground assault
			newEvent->dataBlock.data.formatId = 1806;
			}
		else if (target->GetDomain() == DOMAIN_AIR)
			{
			// Air defenses firing
			newEvent->dataBlock.data.formatId = 1801;
			}
		else
			{
			// Ground engagement (artillery or regular)
			if (shooter->GetSType() == STYPE_UNIT_ROCKET || shooter->GetSType() == STYPE_UNIT_SP_ARTILLERY || shooter->GetSType() == STYPE_UNIT_TOWED_ARTILLERY)
				newEvent->dataBlock.data.formatId = 1807;
			else
				newEvent->dataBlock.data.formatId = 1800;
			}
		}
	SendCampUIMessage(newEvent);

	// Send a CampEvent message for losses to the LOCAL MACHINE
	if (target->IsFlight() && losses)
		{
		FalconCampEventMessage	*newEvent = new FalconCampEventMessage(target->Id(),FalconLocalGame);
		newEvent->dataBlock.team = GetEnemyTeam(target->GetTeam());
		newEvent->dataBlock.eventType = FalconCampEventMessage::campLosses;
		target->GetLocation(&newEvent->dataBlock.data.xLoc,&newEvent->dataBlock.data.yLoc);
		newEvent->dataBlock.data.formatId = 1825;
		// 2002-02-21 ADDED BY S.G. If it's not spotted and it's NOT the player, use the 'Bandit' vehicle so we don't warn the player on the identity of the shooter
		if (!target->GetIdentified(shooter->GetTeam()) && FalconLocalSession->GetTeam() != target->GetTeam())
			newEvent->dataBlock.data.textIds[0] = (short)(-1 * BANDIT_VEH);
		else
		// END OF ADDED SECTION 2002-02-21
			newEvent->dataBlock.data.textIds[0] = (short)(-1 * ((Unit)target)->GetVehicleID(0));
		newEvent->dataBlock.data.owners[0] = target->GetOwner();
		SendCampUIMessage(newEvent);
		}

	if(gMainHandler && FalconLocalSession->GetPlayerSquadron() && target->Id() == FalconLocalSession->GetPlayerSquadron()->GetUnitAirbaseID())
		PostMessage(FalconDisplay.appWin,FM_AIRBASE_ATTACK,0,0);

	return 0;
	}