1package com.fs.starfarer.api.impl.campaign.procgen.themes;
3import org.lwjgl.util.vector.Vector2f;
5import com.fs.starfarer.api.EveryFrameScript;
6import com.fs.starfarer.api.Global;
7import com.fs.starfarer.api.Script;
8import com.fs.starfarer.api.campaign.CampaignFleetAPI;
9import com.fs.starfarer.api.campaign.CustomCampaignEntityAPI;
10import com.fs.starfarer.api.campaign.CustomEntitySpecAPI;
11import com.fs.starfarer.api.campaign.FleetAssignment;
12import com.fs.starfarer.api.campaign.SectorEntityToken;
13import com.fs.starfarer.api.campaign.SectorEntityToken.VisibilityLevel;
14import com.fs.starfarer.api.campaign.ai.FleetAIFlags;
15import com.fs.starfarer.api.campaign.ai.FleetAssignmentDataAPI;
16import com.fs.starfarer.api.campaign.ai.ModularFleetAIAPI;
17import com.fs.starfarer.api.campaign.econ.MarketAPI;
18import com.fs.starfarer.api.campaign.rules.MemoryAPI;
19import com.fs.starfarer.api.impl.campaign.fleets.RouteManager;
20import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
21import com.fs.starfarer.api.impl.campaign.ids.Tags;
22import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.MarketCMD;
23import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.Objectives;
24import com.fs.starfarer.api.plugins.BuildObjectiveTypePicker;
25import com.fs.starfarer.api.plugins.BuildObjectiveTypePicker.BuildObjectiveParams;
26import com.fs.starfarer.api.util.IntervalUtil;
27import com.fs.starfarer.api.util.Misc;
42 protected CampaignFleetAPI
fleet;
43 protected Boolean
done =
null;
67 if (
fleet.getCurrentAssignment() ==
null) {
91 if (
fleet.isInHyperspace())
return;
103 if (
fleet.isInHyperspace())
return;
115 if (
fleet.isInHyperspace())
return;
137 SectorEntityToken closest =
null;
138 float minDist = Float.MAX_VALUE;
141 for (SectorEntityToken objective :
fleet.getContainingLocation().getEntitiesWithTag(Tags.STABLE_LOCATION)) {
142 if (objective.hasTag(Tags.NON_CLICKABLE))
continue;
143 if (objective.hasTag(Tags.FADING_OUT_AND_EXPIRING))
continue;
146 if (objective.getMemoryWithoutUpdate().getBoolean(MemFlags.RECENTLY_SALVAGED))
continue;
148 float dist = Misc.getDistance(
fleet, objective);
149 if (dist < minDist) {
155 for (SectorEntityToken objective :
fleet.getContainingLocation().getEntitiesWithTag(Tags.OBJECTIVE)) {
156 if (objective.getFaction() ==
fleet.getFaction())
continue;
157 if (!objective.getFaction().isHostileTo(
fleet.getFaction()) &&
158 !Misc.isFleetMadeHostileToFaction(
fleet, objective.getFaction())) {
159 boolean ownerHasColonyInSystem =
false;
160 for (MarketAPI curr : Misc.getMarketsInLocation(objective.getContainingLocation())) {
161 if (curr.getFaction() == objective.getFaction() &&
162 !curr.getFaction().isNeutralFaction()) {
163 ownerHasColonyInSystem =
true;
167 if (ownerHasColonyInSystem)
continue;
170 float dist = Misc.getDistance(
fleet, objective);
171 if (dist < minDist) {
178 if (closest ==
null || minDist > 2000f)
return;
180 for (CampaignFleetAPI other : Misc.getNearbyFleets(closest, 2000f)) {
181 if (other ==
fleet)
continue;
183 if (other.isHostileTo(
fleet)) {
184 if (other.getFleetPoints() >
fleet.getFleetPoints() * 0.25f)
return;
187 if (other.getFaction() ==
fleet.getFaction()) {
188 float dist = Misc.getDistance(other, closest);
189 if (dist < minDist)
return;
194 BuildObjectiveParams params =
new BuildObjectiveParams();
195 params.faction =
fleet.getFaction();
196 params.fleet =
fleet;
197 params.stableLoc = closest;
198 BuildObjectiveTypePicker pick =
Global.
getSector().getGenericPlugins().pickPlugin(BuildObjectiveTypePicker.class, params);
201 type = pick.pickObjectiveToBuild(params);
219 Misc.setFlagWithReason(
fleet.getMemoryWithoutUpdate(),
220 MemFlags.FLEET_BUSY,
TEMP_BUSY_REASON,
true, (1.5f + (
float) Math.random()));
222 String name = ((CustomCampaignEntityAPI)target).getCustomEntitySpec().getNameInText();
223 String capText =
"taking control of " + name;
224 String moveText =
"moving to take control of " + name;
226 Vector2f loc = Misc.getUnitVectorAtDegreeAngle(
227 Misc.getAngleInDegrees(target.getLocation(),
fleet.getLocation()));
228 float holdRadius =
fleet.getRadius() + target.getRadius() - 10;
229 loc.scale(holdRadius);
230 Vector2f.add(loc, target.getLocation(), loc);
231 SectorEntityToken holdLoc = target.getContainingLocation().createToken(loc);
233 holdLoc.setCircularOrbit(target,
234 Misc.getAngleInDegrees(target.getLocation(),
fleet.getLocation()),
235 holdRadius, 1000000f);
236 fleet.getContainingLocation().addEntity(holdLoc);
237 Misc.fadeAndExpire(holdLoc, 5f);
239 fleet.addAssignmentAtStart(FleetAssignment.HOLD, holdLoc, 0.5f, capText,
new Script() {
241 if (target.isAlive()) {
242 Objectives o =
new Objectives(target);
243 o.control(
fleet.getFaction().getId());
248 FleetAssignmentDataAPI curr =
fleet.getCurrentAssignment();
253 float dist = Misc.getDistance(target,
fleet);
254 if (dist >
fleet.getRadius() + target.getRadius() + 300f) {
256 fleet.addAssignmentAtStart(FleetAssignment.DELIVER_CREW, target, 3f, moveText,
null);
257 curr =
fleet.getCurrentAssignment();
270 Misc.setFlagWithReason(
fleet.getMemoryWithoutUpdate(),
271 MemFlags.FLEET_BUSY,
TEMP_BUSY_REASON,
true, (1.5f + (
float) Math.random()));
273 String name = spec.getNameInText();
274 String capText =
"constructing " + name;
275 String moveText =
"moving to construct " + name;
277 Vector2f loc = Misc.getUnitVectorAtDegreeAngle(
278 Misc.getAngleInDegrees(target.getLocation(),
fleet.getLocation()));
279 float holdRadius =
fleet.getRadius() + target.getRadius();
280 loc.scale(holdRadius);
281 Vector2f.add(loc, target.getLocation(), loc);
282 SectorEntityToken holdLoc = target.getContainingLocation().createToken(loc);
284 holdLoc.setCircularOrbit(target,
285 Misc.getAngleInDegrees(target.getLocation(),
fleet.getLocation()),
286 holdRadius, 1000000f);
287 fleet.getContainingLocation().addEntity(holdLoc);
288 Misc.fadeAndExpire(holdLoc, 5f);
290 fleet.addAssignmentAtStart(FleetAssignment.HOLD, holdLoc, 0.5f, capText,
new Script() {
292 if (target.isAlive()) {
294 BuildObjectiveParams params =
new BuildObjectiveParams();
295 params.faction =
fleet.getFaction();
296 params.fleet =
fleet;
297 params.stableLoc = target;
298 BuildObjectiveTypePicker pick =
Global.
getSector().getGenericPlugins().pickPlugin(BuildObjectiveTypePicker.class, params);
301 type = pick.pickObjectiveToBuild(params);
304 Objectives o =
new Objectives(target);
305 o.build(type,
fleet.getFaction().getId());
310 FleetAssignmentDataAPI curr =
fleet.getCurrentAssignment();
315 float dist = Misc.getDistance(target,
fleet);
316 if (dist >
fleet.getRadius() + target.getRadius() + 300f) {
318 fleet.addAssignmentAtStart(FleetAssignment.DELIVER_CREW, target, 3f, moveText,
null);
319 curr =
fleet.getCurrentAssignment();
332 Misc.setFlagWithReason(
fleet.getMemoryWithoutUpdate(),
334 for (FleetAssignmentDataAPI curr :
fleet.getAI().getAssignmentsCopy()) {
336 fleet.getAI().removeAssignment(curr);
348 if (!RouteManager.isPlayerInSpawnRange(
fleet))
return false;
350 if (
fleet.getBattle() !=
null)
return false;
351 if (
fleet.getMemoryWithoutUpdate().getBoolean(MemFlags.FLEET_BUSY)) {
355 if (
fleet.isCurrentAssignment(FleetAssignment.GO_TO_LOCATION_AND_DESPAWN))
return false;
357 MemoryAPI mem =
fleet.getMemoryWithoutUpdate();
358 if (Misc.flagHasReason(mem, MemFlags.FLEET_BUSY,
TEMP_BUSY_REASON))
return false;
361 if (
fleet.getAI() instanceof ModularFleetAIAPI) {
362 ModularFleetAIAPI ai = (ModularFleetAIAPI)
fleet.getAI();
363 if (ai.getAssignmentModule().areAssignmentsFrozen())
return false;
366 CampaignFleetAPI pursueTarget = mem.getFleet(FleetAIFlags.PURSUIT_TARGET);
367 CampaignFleetAPI fleeingFrom = mem.getFleet(FleetAIFlags.NEAREST_FLEEING_FROM);
369 if (pursueTarget !=
null || fleeingFrom !=
null) {
381 if (
fleet.getMemoryWithoutUpdate().getBoolean(MemFlags.RECENTLY_PERFORMED_RAID)) {
385 MarketAPI closest =
null;
386 float minDist = Float.MAX_VALUE;
392 for (MarketAPI market : Misc.getMarketsInLocation(
fleet.getContainingLocation())) {
396 if (!market.getFaction().isHostileTo(
fleet.getFaction()) &&
397 !Misc.isFleetMadeHostileToFaction(
fleet, market.getFaction()))
continue;
400 float dist = Misc.getDistance(
fleet, market.getPrimaryEntity());
401 if (dist < minDist) {
407 if (closest ==
null || minDist > 2000f)
return;
409 for (CampaignFleetAPI other : Misc.getNearbyFleets(closest.getPrimaryEntity(), 2000f)) {
410 if (other ==
fleet)
continue;
412 if (other.isHostileTo(
fleet)) {
413 VisibilityLevel vis = other.getVisibilityLevelTo(
fleet);
414 boolean canSee = vis == VisibilityLevel.COMPOSITION_AND_FACTION_DETAILS || vis == VisibilityLevel.COMPOSITION_DETAILS;
415 if (!canSee && other.getFaction() !=
fleet.getFaction())
continue;
417 if (other.getAI() instanceof ModularFleetAIAPI) {
418 ModularFleetAIAPI ai = (ModularFleetAIAPI) other.getAI();
419 if (ai.isFleeing())
continue;
420 if (ai.isMaintainingContact())
continue;
422 if (ai.getTacticalModule().getTarget() ==
fleet)
return;
424 MemoryAPI mem = other.getMemoryWithoutUpdate();
425 boolean smuggler = mem.getBoolean(MemFlags.MEMORY_KEY_SMUGGLER);
426 boolean trader = mem.getBoolean(MemFlags.MEMORY_KEY_TRADE_FLEET);
427 if (smuggler || trader)
continue;
429 if (other.getFleetPoints() >
fleet.getFleetPoints() * 0.25f || other.isStationMode())
return;
432 if (other.getFaction() ==
fleet.getFaction()) {
433 if (other.isStationMode())
continue;
436 if (!(Misc.isRaider(other) && !Misc.isWarFleet(other) && !otherFromSameRaid))
continue;
438 if (other.getFleetPoints() >
fleet.getFleetPoints())
return;
439 if (other.getFleetPoints() ==
fleet.getFleetPoints()) {
440 float dist = Misc.getDistance(other, closest.getPrimaryEntity());
441 if (dist < minDist)
return;
453 Misc.setFlagWithReason(
fleet.getMemoryWithoutUpdate(),
454 MemFlags.FLEET_BUSY,
TEMP_BUSY_REASON,
true, (1.5f + (
float) Math.random()));
456 String name = target.getName();
457 String capText =
"raiding " + name;
458 String moveText =
"moving to raid " + name;
461 if (s !=
null) moveText = s;
464 if (s !=
null) capText = s;
467 Vector2f loc = Misc.getUnitVectorAtDegreeAngle(
468 Misc.getAngleInDegrees(target.getPrimaryEntity().getLocation(),
fleet.getLocation()));
469 float holdRadius =
fleet.getRadius() * 0.5f + target.getPrimaryEntity().getRadius();
470 loc.scale(holdRadius);
471 Vector2f.add(loc, target.getPrimaryEntity().getLocation(), loc);
472 SectorEntityToken holdLoc = target.getContainingLocation().createToken(loc);
473 holdLoc.setCircularOrbit(target.getPrimaryEntity(),
474 Misc.getAngleInDegrees(target.getPrimaryEntity().getLocation(),
fleet.getLocation()),
475 holdRadius, 1000000f);
476 fleet.getContainingLocation().addEntity(holdLoc);
477 Misc.fadeAndExpire(holdLoc, 5f);
479 final int fpAtStart =
fleet.getFleetPoints();
481 fleet.addAssignmentAtStart(FleetAssignment.HOLD, holdLoc, 0.5f, capText,
new Script() {
483 if (fpAtStart ==
fleet.getFleetPoints()) {
484 boolean raided =
false;
491 new MarketCMD(target.getPrimaryEntity()).doGenericRaid(
fleet.getFaction(),
492 MarketCMD.getRaidStr(
fleet));
497 fleet.getMemoryWithoutUpdate().set(MemFlags.RECENTLY_PERFORMED_RAID,
true, 3f);
503 FleetAssignmentDataAPI curr =
fleet.getCurrentAssignment();
508 float dist = Misc.getDistance(target.getPrimaryEntity(),
fleet);
510 if (dist >
fleet.getRadius() + target.getPrimaryEntity().getRadius()) {
511 fleet.addAssignmentAtStart(FleetAssignment.DELIVER_CREW, holdLoc, 3f, moveText,
null);
512 curr =
fleet.getCurrentAssignment();
static SettingsAPI getSettings()
static SectorAPI getSector()
void checkRaid(float amount)
void giveRaidOrder(final MarketAPI target)
void checkObjectiveAction(boolean build)
void advance(float amount)
static String TEMP_BUSY_REASON
abstract void giveInitialAssignments()
void giveCaptureOrder(final SectorEntityToken target)
void giveBuildOrder(final SectorEntityToken target, String type)
FleetActionDelegate getDelegate()
void checkCapture(float amount)
IntervalUtil buildTracker
FleetActionDelegate delegate
static String TEMP_ASSIGNMENT
BaseAssignmentAI(CampaignFleetAPI fleet)
void setDelegate(FleetActionDelegate delegate)
void checkBuild(float amount)
void clearTempAssignments(CampaignFleetAPI fleet)
CustomEntitySpecAPI getCustomEntitySpec(String id)
String getRaidActionText(CampaignFleetAPI fleet, MarketAPI market)
String getRaidApproachText(CampaignFleetAPI fleet, MarketAPI market)
String getRaidInSystemText(CampaignFleetAPI fleet)
String getRaidDefaultText(CampaignFleetAPI fleet)
void performRaid(CampaignFleetAPI fleet, MarketAPI market)
boolean canRaid(CampaignFleetAPI fleet, MarketAPI market)
String getRaidPrepText(CampaignFleetAPI fleet, SectorEntityToken from)