1package com.fs.starfarer.api.impl.campaign.ghosts;
3import java.util.ArrayList;
5import java.util.Random;
7import org.lwjgl.util.vector.Vector2f;
9import com.fs.starfarer.api.Global;
10import com.fs.starfarer.api.campaign.CampaignFleetAPI;
11import com.fs.starfarer.api.campaign.CustomCampaignEntityAPI;
12import com.fs.starfarer.api.campaign.LocationAPI;
13import com.fs.starfarer.api.campaign.SectorEntityToken;
14import com.fs.starfarer.api.impl.campaign.abilities.InterdictionPulseAbility;
15import com.fs.starfarer.api.impl.campaign.ids.Entities;
16import com.fs.starfarer.api.impl.campaign.ids.Factions;
17import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
18import com.fs.starfarer.api.impl.campaign.ids.Tags;
19import com.fs.starfarer.api.util.Misc;
20import com.fs.starfarer.api.util.SmoothMovementUtil;
24 public static enum DespawnReason {
29 protected CustomCampaignEntityAPI
entity;
38 protected SmoothMovementUtil
movement =
new SmoothMovementUtil();
40 protected List<GhostBehavior>
script =
new ArrayList<GhostBehavior>();
60 if (
script.isEmpty())
return;
73 Random random = Misc.random;
79 return 700f +
getRandom().nextFloat() * 300f;
82 return 1000f +
getRandom().nextFloat() * 500f;
85 return 1500f +
getRandom().nextFloat() * 500f;
89 return 2500f +
getRandom().nextFloat() * 1000f;
93 return 10f +
getRandom().nextFloat() * 5f;
96 return 20f +
getRandom().nextFloat() * 10f;
99 return 22f +
getRandom().nextFloat() * 28f;
102 return 50f +
getRandom().nextFloat() * 25f;
105 return 75f +
getRandom().nextFloat() * 25f;
109 return min + (max - min) *
getRandom().nextFloat();
112 return min +
getRandom().nextInt(max - min + 1);
121 return base * (0.75f + 0.5f *
getRandom().nextFloat());
132 Vector2f loc =
new Vector2f();
134 for (
int i = 0; i < 20; i++) {
135 float r = minDist + random.nextFloat() * (maxDist - minDist);
136 loc = Misc.getPointAtRadius(pf.getLocation(), r, random);
137 if (!Misc.isInsideSlipstream(loc, 500f, pf.getContainingLocation())) {
141 if (Misc.isInsideSlipstream(loc, 500f, pf.getContainingLocation())) {
154 Vector2f loc =
new Vector2f();
156 float r = minDist + random.nextFloat() * (maxDist - minDist);
157 loc = Misc.getPointAtRadius(
entity.getLocation(), r, random);
176 if (radius > maxFleetRadius) {
177 extraInds = (int) Math.round((radius - maxFleetRadius) / 20f);
181 public void initEntity(
float sensorProfile,
float radius,
int extraSensorInds) {
184 public void initEntity(
float sensorProfile,
float radius,
int extraSensorInds, LocationAPI where) {
185 entity = where.addCustomEntity(
null,
null,
186 Entities.SENSOR_GHOST, Factions.NEUTRAL);
187 entity.setDiscoverable(
true);
188 entity.setSensorProfile(sensorProfile);
189 entity.setDiscoveryXP(0f);
190 entity.setDetectionRangeDetailsOverrideMult(-100f);
192 entity.forceSensorFaderOut();
198 if (extraSensorInds > 0) {
199 entity.getMemoryWithoutUpdate().set(MemFlags.EXTRA_SENSOR_INDICATORS, extraSensorInds);
204 if (random ==
null) random = Misc.random;
205 int num = min + random.nextInt(max - min + 1);
206 entity.getMemoryWithoutUpdate().set(MemFlags.SENSOR_INDICATORS_OVERRIDE, num);
217 if (!
entity.hasTag(Tags.FADING_OUT_AND_EXPIRING)) {
222 Misc.fadeAndExpire(
entity, 1f);
227 for (CampaignFleetAPI fleet :
entity.getContainingLocation().getFleets()) {
228 float dist = Misc.getDistance(
entity, fleet);
229 dist -=
entity.getRadius() + fleet.getRadius();
231 Misc.fadeAndExpire(
entity, 1f);
241 Global.
getSector().getMemoryWithoutUpdate().getBoolean(MemFlags.GLOBAL_INTERDICTION_PULSE_JUST_USED_IN_CURRENT_LOCATION)) {
242 if (
entity.getContainingLocation() !=
null) {
243 for (CampaignFleetAPI fleet :
entity.getContainingLocation().getFleets()) {
244 float range = InterdictionPulseAbility.getRange(fleet);
245 float dist = Misc.getDistance(fleet.getLocation(),
entity.getLocation());
246 if (dist > range)
continue;
247 if (fleet.getMemoryWithoutUpdate().getBoolean(MemFlags.JUST_DID_INTERDICTION_PULSE)) {
294 public void moveTo(Vector2f dest,
float maxBurn) {
295 moveTo(dest,
null, maxBurn);
298 public void moveTo(Vector2f dest, Vector2f destVel,
float maxBurn) {
299 float speed = Misc.getSpeedForBurnLevel(maxBurn);
300 float accelMult = speed / Misc.getSpeedForBurnLevel(20f);;
309 return (
int) Misc.getBurnLevelForSpeed(
movement.getMaxSpeed());
312 return (
int) Misc.getBurnLevelForSpeed(
entity.getVelocity().length());
356 this.creationFailed =
true;
357 if (
entity !=
null &&
entity.getContainingLocation() !=
null) {
static SettingsAPI getSettings()
static SectorAPI getSector()
void addBehavior(GhostBehavior b)
float genFloat(float min, float max)
void setNumSensorIndicators(int min, int max, Random random)
transient boolean creationFailed
List< GhostBehavior > getScript()
void initEntity(float sensorProfile, float radius, int extraSensorInds, LocationAPI where)
float genSmallSensorProfile()
SmoothMovementUtil movement
boolean isDespawnOutsideSector()
float genInt(int min, int max)
void setLoc(Vector2f loc)
List< GhostBehavior > script
float genLargeSensorProfile()
boolean despawnOutsideSector
float genDelay(float base)
void setVel(Vector2f vel)
void setDespawnRange(float despawnRange)
void advance(float amount)
void setDespawnOutsideSector(boolean despawnOutsideSector)
SmoothMovementUtil getMovement()
BaseSensorGhost(SensorGhostManager manager, int fleeBurnLevel)
float genMediumSensorProfile()
void setAccelMult(float accelMult)
void moveTo(Vector2f dest, float maxBurn)
void placeNearEntity(SectorEntityToken entity, float minDist, float maxDist)
boolean placeNearPlayer(float minDist, float maxDist)
float genVerySmallRadius()
float genHugeSensorProfile()
boolean placeNearPlayer()
void moveTo(Vector2f dest, Vector2f destVel, float maxBurn)
CustomCampaignEntityAPI getEntity()
boolean isDespawnInAbyss()
void initEntity(float sensorProfile, float radius)
void addInterrupt(GhostBehaviorInterrupt interrupt)
void setDespawnInAbyss(boolean despawnInAbyss)
SensorGhostManager manager
void reportDespawning(DespawnReason reason, Object param)
void initEntity(float sensorProfile, float radius, int extraSensorInds)
CustomCampaignEntityAPI entity
boolean isCreationFailed()
float getFloat(String key)
void advance(float amount, SensorGhost ghost)