173 if (fleets.isEmpty())
return;
185 for (CampaignFleetAPI fleet : fleets) {
186 if (!fleet.hasScriptOfClass(WarfleetAssignmentAI.class)) {
187 WarfleetAssignmentAI script =
new WarfleetAssignmentAI(fleet,
true,
true);
188 script.setDelegate(
this);
189 fleet.addScript(script);
191 fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_WAR_FLEET,
true);
192 fleet.getMemoryWithoutUpdate().unset(MemFlags.FLEET_BUSY);
196 List<MarketAPI> sortedTargetMarkets =
new ArrayList<MarketAPI>();
197 for (MarketAPI market : Misc.getMarketsInLocation(
params.where)) {
198 if (!
params.allowAnyHostileMarket && !
params.allowedTargets.contains(market))
continue;
199 if (!
params.allowNonHostileTargets && !
intel.
getFaction().isHostileTo(market.getFaction()))
continue;
201 sortedTargetMarkets.add(market);
204 final Vector2f sortLoc =
new Vector2f(fleets.get(0).getLocation());
205 Collections.sort(sortedTargetMarkets,
new Comparator<MarketAPI>() {
206 public int compare(MarketAPI o1, MarketAPI o2) {
207 float d1 = Misc.getDistance(sortLoc, o1.getPrimaryEntity().getLocation());
208 float d2 = Misc.getDistance(sortLoc, o2.getPrimaryEntity().getLocation());
209 return (
int) Math.signum(d1 - d2);
215 for (SectorEntityToken objective :
params.where.getEntitiesWithTag(Tags.OBJECTIVE)) {
216 WarSimScript.setNoFightingForObjective(objective,
intel.
getFaction(), 1000f);
219 List<SectorEntityToken> objectives =
new ArrayList<SectorEntityToken>();
220 float minDist = Float.MAX_VALUE;
221 SectorEntityToken closest =
null;
222 for (SectorEntityToken objective :
params.where.getEntitiesWithTag(Tags.NAV_BUOY)) {
223 float dist = Misc.getDistance(sortLoc, objective.getLocation());
224 if (dist < minDist) {
229 if (closest !=
null) {
230 objectives.add(closest);
234 minDist = Float.MAX_VALUE;
236 for (SectorEntityToken objective :
params.where.getEntitiesWithTag(Tags.SENSOR_ARRAY)) {
237 float dist = Misc.getDistance(sortLoc, objective.getLocation());
238 if (dist < minDist) {
243 if (closest !=
null) {
244 objectives.add(closest);
247 if (!
params.tryToCaptureObjectives) {
251 if (
params.type == FGRaidType.CONCURRENT) {
252 RaidSubstage stage =
new RaidSubstage();
253 stage.maxDuration =
params.maxDurationIfSpawnedFleetsConcurrent;
254 stage.objectives.addAll(objectives);
255 for (MarketAPI market : sortedTargetMarkets) {
256 stage.markets.add(market.getPrimaryEntity());
260 if (!objectives.isEmpty()) {
261 RaidSubstage stage =
new RaidSubstage();
262 stage.maxDuration =
params.maxDurationIfSpawnedFleetsPerSequentialStage;
263 stage.objectives.addAll(objectives);
267 for (MarketAPI market : sortedTargetMarkets) {
268 RaidSubstage stage =
new RaidSubstage();
269 stage.maxDuration =
params.maxDurationIfSpawnedFleetsConcurrent;
270 stage.markets.add(market.getPrimaryEntity());
276 for (RaidSubstage stage :
stages) {
277 totalDur += stage.maxDuration;
283 float responseFraction = 1f / Math.max(1f, sortedTargetMarkets.size());
284 for (MarketAPI market : sortedTargetMarkets) {
285 MilitaryResponseParams defParams =
new MilitaryResponseParams(ActionType.HOSTILE,
286 "defRaid_" + market.getId(),
288 market.getPrimaryEntity(),
292 params.where.addScript(defScript);
343 super.directFleets(amount);
349 if (fleets.isEmpty()) {
365 RaidSubstage stage =
stages.get(0);
366 if (!stage.started) {
367 stage.started =
true;
371 List<SectorEntityToken> targets =
new ArrayList<SectorEntityToken>(stage.objectives);
372 targets.addAll(stage.markets);
378 stage.maxDuration -= days;
379 if (stage.maxDuration <= 0 || stage.allGoalsAchieved(
this)) {
385 if (!
interval.intervalElapsed())
return;
387 boolean inSpawnRange = RouteManager.isPlayerInSpawnRange(
params.where.getCenter());
394 for (SectorEntityToken obj : stage.objectives) {
400 boolean someRaidsFinished =
false;
401 for (SectorEntityToken e : stage.markets) {
402 if (stage.finishedRaiding.contains(e))
continue;
403 if (!
canRaid(
null, e.getMarket())) {
404 someRaidsFinished =
true;
405 stage.finishedRaiding.add(e);
409 if (someRaidsFinished) {
410 for (SectorEntityToken e : stage.markets) {
413 List<SectorEntityToken> remaining =
new ArrayList<SectorEntityToken>();
414 remaining.addAll(stage.markets);
415 remaining.removeAll(stage.finishedRaiding);
419 if (!remaining.isEmpty()) {
426 for (CampaignFleetAPI fleet : fleets) {
427 if (
params.doNotGetSidetracked) {
428 boolean battleNear =
false;
429 for (CampaignFleetAPI other : fleets) {
430 if (other == fleet || other.getBattle() ==
null)
continue;
431 if (other.getContainingLocation() != fleet.getContainingLocation());
432 float dist = Misc.getDistance(fleet, other);
434 CampaignFleetAIAPI ai = fleet.getAI();
435 if (ai !=
null && ai.wantsToJoin(other.getBattle(), other.getBattle().isPlayerInvolved())) {
442 fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_FLEET_DO_NOT_GET_SIDETRACKED,
true, 0.4f);
450 float responseFraction = 1f / Math.max(1f, targets.size());
452 for (SectorEntityToken target : targets) {
453 if (!target.hasTag(Tags.OBJECTIVE) &&!
canRaid(
null, target.getMarket())) {
457 float rf = responseFraction;
458 MilitaryResponseParams aggroParams =
new MilitaryResponseParams(ActionType.HOSTILE,
459 "raid_" + target.getId(),
464 if (
params.appendTargetNameToTravelText) {
465 aggroParams.travelText =
466 (params.targetTravelText !=
null ? params.targetTravelText +
" " :
"traveling to ") + target.getName();
467 }
else if (
params.targetTravelText !=
null) {
468 aggroParams.travelText =
params.targetTravelText;
471 if (
params.inSystemActionText !=
null) {
472 aggroParams.actionText =
params.inSystemActionText;
474 aggroParams.actionText =
"raiding system";
478 params.where.addScript(script);
488 public boolean canRaid(CampaignFleetAPI fleet, MarketAPI market) {
489 if (market ==
null)
return false;
490 if (!market.isInEconomy()) {
493 if (!
params.allowedTargets.contains(market) && !
params.allowedTargets.isEmpty() && !
params.allowAnyHostileMarket) {
504 if (
params.bombardment !=
null && fleet !=
null) {
505 float fp = fleet.getFleetPoints();
507 if (other == fleet)
continue;
508 if (other.getContainingLocation() != fleet.getContainingLocation())
continue;
509 float dist = Misc.getDistance(fleet, other);
510 if (dist > 1000)
continue;
511 float otherFP = other.getFleetPoints();
512 if (otherFP > fp * 1.2f) {
520 faction = fleet.getFaction();
522 boolean hostile = market.getFaction().isHostileTo(faction);
524 hostile |= Misc.isFleetMadeHostileToFaction(fleet, market.getFaction());
530 public void performRaid(CampaignFleetAPI fleet, MarketAPI market) {
535 faction = fleet.getFaction();
538 if (
params.bombardment !=
null) {
539 float cost = MarketCMD.getBombardmentCost(market, fleet);
541 Misc.FP_TO_BOMBARD_COST_APPROX_MULT;
543 bombardStr = fleet.getCargo().getMaxFuel() * 0.5f;
546 if (cost <= bombardStr) {
550 Misc.setFlagWithReason(market.getMemoryWithoutUpdate(), MemFlags.RECENTLY_BOMBARDED,
555 Misc.FP_TO_GROUND_RAID_STR_APPROX_MULT;
557 raidStr = MarketCMD.getRaidStr(fleet);
560 Industry industry =
null;
561 int index =
raidCount.getCount(market) - 1;
562 if (index < 0) index = 0;
563 if (
params.disrupt !=
null && index <
params.disrupt.size()) {
565 for (String industryId :
params.disrupt) {
566 if (market.hasIndustry(industryId)) {
567 if (count >= index) {
568 industry = market.getIndustry(industryId);
580 Misc.setFlagWithReason(market.getMemoryWithoutUpdate(), MemFlags.RECENTLY_RAIDED,
581 faction.getId(),
true, 30f);
582 Misc.setRaidedTimestamp(market);
583 }
else if (industry !=
null) {
585 new MarketCMD(market.getPrimaryEntity()).doIndustryRaid(faction, raidStr, industry, durMult);
587 new MarketCMD(market.getPrimaryEntity()).doGenericRaid(faction,
588 raidStr,
params.maxStabilityLostPerRaid,
params.raidsPerColony > 1);
602 if (data !=
null) str += data.getStrengthModifiedByDamage();
605 boolean playerTargeted =
false;
613 for (MarketAPI target : Misc.getMarketsInLocation(
params.where)) {
614 if (!
params.allowAnyHostileMarket && !
params.allowedTargets.contains(target))
continue;
615 if (!
params.allowNonHostileTargets && !
intel.
getFaction().isHostileTo(target.getFaction()))
continue;
617 float defensiveStr = enemyStr + WarSimScript.getStationStrength(target.getFaction(),
params.where, target.getPrimaryEntity());
619 float damage = 0.5f * defensiveStr / Math.max(str, 1f);
620 if (damage > 0.75f) damage = 0.75f;
621 strMult *= (1f - damage);
623 if (defensiveStr >= str) {
627 Industry station = Misc.getStationIndustry(target);
628 if (station !=
null) {
629 OrbitalStation.disrupt(station);
633 for (
int i = 0; i <
params.raidsPerColony; i++) {
638 str = origStr * strMult;
643 FleetFactoryV3.applyDamageToFleet(fleet, 1f - strMult,
false,
intel.
getRandom());
650 if (extra.damage ==
null) {
653 extra.damage = 1f - (1f - extra.damage) * strMult;
655 if (extra.damage > 1f) extra.damage = 1f;