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); } } }
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; }
// 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; }
// 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; }