1package com.fs.starfarer.api.impl.combat.dem;
3import java.util.ArrayList;
8import org.json.JSONArray;
9import org.json.JSONException;
10import org.json.JSONObject;
11import org.lwjgl.util.vector.Vector2f;
13import com.fs.starfarer.api.Global;
14import com.fs.starfarer.api.combat.BaseEveryFrameCombatPlugin;
15import com.fs.starfarer.api.combat.CollisionClass;
16import com.fs.starfarer.api.combat.CombatEngineLayers;
17import com.fs.starfarer.api.combat.CombatEntityAPI;
18import com.fs.starfarer.api.combat.DamageType;
19import com.fs.starfarer.api.combat.GuidedMissileAI;
20import com.fs.starfarer.api.combat.MissileAIPlugin;
21import com.fs.starfarer.api.combat.MissileAPI;
22import com.fs.starfarer.api.combat.ShipAPI;
23import com.fs.starfarer.api.combat.ShipCommand;
24import com.fs.starfarer.api.combat.ShipHullSpecAPI;
25import com.fs.starfarer.api.combat.ShipVariantAPI;
26import com.fs.starfarer.api.combat.ShipwideAIFlags.AIFlags;
27import com.fs.starfarer.api.combat.WeaponAPI;
28import com.fs.starfarer.api.input.InputEventAPI;
29import com.fs.starfarer.api.loading.WeaponGroupSpec;
30import com.fs.starfarer.api.loading.WeaponGroupType;
31import com.fs.starfarer.api.util.Misc;
38 public static enum State {
46 protected State
state = State.WAIT;
92 protected ShapedExplosionParams
p;
108 if (json.optBoolean(
"withShapedExplosion")) {
109 p =
new ShapedExplosionParams();
112 }
catch (Exception e) {
113 throw new RuntimeException(e);
118 if (json.has(
"triggerAngle")) {
125 if (json.has(
"targetingLaserRange")) {
130 turnRateBoost = (float) json.optDouble(
"turnRateBoost", 100f);
134 firingTime = (float) json.optDouble(
"firingTime", 1.25f);
139 bombPumped = json.optBoolean(
"bombPumped",
false);
145 if (json.has(
"destroyedExplosionColor")) {
148 }
catch (Exception e) {
149 throw new RuntimeException(e);
153 JSONArray arr = json.optJSONArray(
"targetingLaserFireOffset");
155 for (
int i = 0; i < arr.length(); i += 2) {
156 Vector2f v =
new Vector2f((
float) arr.optDouble(i), (
float) arr.optDouble(i + 1));
160 arr = json.optJSONArray(
"targetingLaserSweepAngles");
162 for (
int i = 0; i < arr.length(); i += 2) {
163 Vector2f v =
new Vector2f((
float) arr.optDouble(i), (
float) arr.optDouble(i + 1));
167 arr = json.optJSONArray(
"payloadSweepAngles");
169 for (
int i = 0; i < arr.length(); i += 2) {
170 Vector2f v =
new Vector2f((
float) arr.optDouble(i), (
float) arr.optDouble(i + 1));
191 public static float getValue(JSONObject json, String key,
float defaultValue) {
192 JSONArray arr = json.optJSONArray(key);
194 Vector2f v =
new Vector2f((
float) arr.optDouble(0), (
float) arr.optDouble(1));
195 return v.x + (v.y - v.x) * (
float) Math.random();
197 return (
float) json.optDouble(key, defaultValue);
202 public void advance(
float amount, List<InputEventAPI> events) {
212 boolean doCleanup =
state == State.DONE ||
234 if (target instanceof
ShipAPI) {
235 from = ((
ShipAPI) target).getShieldCenterEvenIfNoShield();
253 state = State.TURN_TO_TARGET;
307 }
else if (
state == State.TURN_TO_TARGET) {
314 state = State.SIGNAL;
316 }
else if (
state == State.SIGNAL) {
325 if (progress < 0.5f) {
326 angle = curr.x + (curr.y - curr.x) * progress * 2f;
328 angle = curr.x + (curr.y - curr.x) * (1f - progress) * 2f;
354 }
else if (
state == State.FIRE) {
390 if (progress > 1f) progress = 1f;
402 if (progress < 0.5f) {
403 angle = curr.x + (curr.y - curr.x) * progress * 2f;
405 angle = curr.x + (curr.y - curr.x) * (1f - progress) * 2f;
410 progress = Math.abs(progress);
412 angle = curr.x + (curr.y - curr.x) * progress;
483 if (
state == State.TURN_TO_TARGET ||
state == State.SIGNAL ||
500 boolean turningTowardsDesiredFacing =
true;
513 float r = (float) Math.random();
518 }
else if (r < 0.8f) {
531 strafeDur = 0.5f + (float) Math.random() * 0.5f;
541 if (dist > shipToFireTarget) extra = dist - shipToFireTarget;
551 if (speedInDir < maxDrift) {
571 public static class ShapedExplosionParams {
572 public float shapedExplosionEndSizeMin = 1f;
573 public float shapedExplosionEndSizeMax = 2f;
574 public Color shapedExplosionColor =
new Color(255,150,130,155);
575 public int shapedExplosionNumParticles = 200;
576 public float shapedExplosionMinParticleSize = 80;
577 public float shapedExplosionMaxParticleSize = 100;
578 public float shapedExplosionScatter = 100f;
579 public float shapedExplosionMinParticleVel = 100;
580 public float shapedExplosionMaxParticleVel = 350f;
581 public float shapedExplosionMinParticleDur = 1f;
582 public float shapedExplosionMaxParticleDur = 2f;
583 public float shapedExplosionArc = 90f;
585 public void load(JSONObject json)
throws JSONException {
586 shapedExplosionEndSizeMin = (float)json.optDouble(
"shapedExplosionEndSizeMin", 1f);
587 shapedExplosionEndSizeMax = (float)json.optDouble(
"shapedExplosionEndSizeMax", 2f);
588 shapedExplosionNumParticles = json.optInt(
"shapedExplosionNumParticles");
589 shapedExplosionMinParticleSize = (float)json.optDouble(
"shapedExplosionMinParticleSize", 80f);
590 shapedExplosionMaxParticleSize = (float)json.optDouble(
"shapedExplosionMaxParticleSize", 100f);
591 shapedExplosionScatter = (float)json.optDouble(
"shapedExplosionScatter", 100f);
592 shapedExplosionMinParticleVel = (float)json.optDouble(
"shapedExplosionMinParticleVel", 100f);
593 shapedExplosionMaxParticleVel = (float)json.optDouble(
"shapedExplosionMaxParticleVel", 350f);
594 shapedExplosionMinParticleDur = (float)json.optDouble(
"shapedExplosionMinParticleDur", 1f);
595 shapedExplosionMaxParticleDur = (float)json.optDouble(
"shapedExplosionMaxParticleDur", 2f);
596 shapedExplosionArc = (float)json.optDouble(
"shapedExplosionArc", 90f);
597 shapedExplosionColor =
Misc.
optColor(json,
"shapedExplosionColor",
null);
604 int numParticles =
p.shapedExplosionNumParticles;
605 float minSize =
p.shapedExplosionMinParticleSize;
606 float maxSize =
p.shapedExplosionMaxParticleSize;
607 Color pc =
p.shapedExplosionColor;
609 float minDur =
p.shapedExplosionMinParticleDur;
610 float maxDur =
p.shapedExplosionMaxParticleDur;
612 float arc =
p.shapedExplosionArc;
613 float scatter =
p.shapedExplosionScatter;
614 float minVel =
p.shapedExplosionMinParticleVel;
615 float maxVel =
p.shapedExplosionMaxParticleVel;
617 float endSizeMin =
p.shapedExplosionEndSizeMin;
618 float endSizeMax =
p.shapedExplosionEndSizeMax;
620 Vector2f spawnPoint =
new Vector2f(loc);
621 for (
int i = 0; i < numParticles; i++) {
623 float angleOffset = (float) Math.random();
624 if (angleOffset > 0.2f) {
625 angleOffset *= angleOffset;
627 float speedMult = 1f - angleOffset;
628 speedMult = 0.5f + speedMult * 0.5f;
629 angleOffset *= Math.signum((
float) Math.random() - 0.5f);
630 angleOffset *= arc/2f;
631 float theta = (float) Math.toRadians(angle + angleOffset);
632 float r = (float) (Math.random() * Math.random() * scatter);
633 float x = (float)Math.cos(theta) * r;
634 float y = (float)Math.sin(theta) * r;
635 Vector2f pLoc =
new Vector2f(spawnPoint.x + x, spawnPoint.y + y);
637 float speed = minVel + (maxVel - minVel) * (
float) Math.random();
643 float pSize = minSize + (maxSize - minSize) * (
float) Math.random();
644 float pDur = minDur + (maxDur - minDur) * (
float) Math.random();
645 float endSize = endSizeMin + (endSizeMax - endSizeMin) * (
float) Math.random();
static SettingsAPI getSettings()
static CombatEngineAPI getCombatEngine()
void modifyFlat(String source, float value)
void applyMods(MutableStat other)
void modifyMult(String source, float value)
void setFlag(AIFlags flag)
void modifyFlat(String source, float value)
void unmodifyFlat(String source)
float minDelayBeforeTriggering
float preferredMaxFireDistance
List< Vector2f > payloadSweepAngles
List< Vector2f > targetingLaserSweepAngles
boolean payloadCenterSweepOnOriginalOffset
float turnRateMultOnSignal
float allowedDriftFraction
void updateDroneState(float amount)
float preferredMinFireDistance
float payloadSweepRateMult
List< Vector2f > targetingLaserFireOffset
boolean destroyMissleWhenDoneFiring
CombatEntityAPI fireTarget
static float getValue(JSONObject json, String key, float defaultValue)
float targetingLaserRange
void spawnShapedExplosion(Vector2f loc, float angle, ShapedExplosionParams p)
void doMissileControl(float amount)
boolean randomPayloadSweepPhaseShift
void advance(float amount, List< InputEventAPI > events)
boolean fadeOutEngineWhenFiring
DEMScript(MissileAPI missile, ShipAPI ship, WeaponAPI weapon)
Color destroyedExplosionColor
boolean snapFacingToTargetIfCloseEnough
List< Float > payloadSweepPhaseShift
void advance(float amount)
void addSlot(String slotId)
static boolean turnTowardsPointV2(MissileAPI missile, Vector2f point, float angVel)
static Vector2f getUnitVectorAtDegreeAngle(float degrees)
static float getAngleDiff(float from, float to)
static float getDistance(SectorEntityToken from, SectorEntityToken to)
static float getClosestTurnDirection(float facing, float desired)
static Color optColor(JSONObject json, String key, Color defaultValue)
static boolean isInArc(float direction, float arc, Vector2f from, Vector2f to)
static float getAngleInDegrees(Vector2f v)
ABOVE_SHIPS_AND_MISSILES_LAYER
float getTargetingRadius(Vector2f from, CombatEntityAPI target, boolean considerShield)
ShipHullSpecAPI getHullSpec(String hullId)
ShipVariantAPI createEmptyVariant(String hullVariantId, ShipHullSpecAPI hullSpec)
WeaponSpecAPI getWeaponSpec(String weaponId)
ShipAPI createFXDrone(ShipVariantAPI variant)
ViewportAPI getViewport()
void applyDamage(CombatEntityAPI entity, Vector2f point, float damageAmount, DamageType damageType, float empAmount, boolean bypassShields, boolean dealsSoftFlux, Object source, boolean playSound)
void removeEntity(CombatEntityAPI entity)
void removePlugin(EveryFrameCombatPlugin plugin)
boolean isEntityInPlay(CombatEntityAPI entity)
void addEntity(CombatEntityAPI entity)
void addNebulaParticle(Vector2f loc, Vector2f vel, float size, float endSizeMult, float rampUpFraction, float fullBrightnessFraction, float totalDuration, Color color)
void setCollisionClass(CollisionClass collisionClass)
float getCollisionRadius()
void setAngularVelocity(float angVel)
float getAngularVelocity()
void setFacing(float facing)
Vector2f getSpawnLocation()
CombatEntityAPI getTarget()
void setNoFlameoutOnFizzling(boolean noFlameoutOnFizzling)
void setFizzleTime(float fizzleTime)
void giveCommand(ShipCommand command)
void setNoGlowTime(float noGlowTime)
void setEtaModifier(float etaModifier)
ShipEngineControllerAPI getEngineController()
void setFlightTime(float flightTime)
MutableShipStatsAPI getEngineStats()
DamagingProjectileAPI explode()
void setArmedWhileFizzling(boolean armedWhileFizzling)
void setMissileAI(MissileAIPlugin ai)
void setDestroyedExplosionColorOverride(Color destroyedExplosionColorOverride)
void setMaxFlightTime(float maxFlightTime)
void setFadeTime(float fadeTime)
MutableStat getMissileWeaponDamageMult()
MutableStat getDamageToTargetEnginesMult()
MutableStat getDamageToMissiles()
MutableStat getDamageToTargetShieldsMult()
MutableStat getDamageToTargetWeaponsMult()
MutableStat getDamageToCapital()
MutableStat getHullDamageTakenMult()
MutableStat getDamageToFrigates()
MutableStat getDamageToDestroyers()
MutableStat getDamageToTargetHullMult()
MutableStat getBallisticWeaponDamageMult()
MutableStat getDamageToFighters()
MutableStat getDamageToCruisers()
StatBonus getBeamWeaponRangeBonus()
MutableStat getTurnAcceleration()
MutableStat getMaxTurnRate()
MutableStat getEnergyWeaponDamageMult()
MutableShipStatsAPI getMutableStats()
List< WeaponGroupAPI > getWeaponGroupsCopy()
void setDrone(boolean isDrone)
Vector2f getMouseTarget()
void setLayer(CombatEngineLayers layer)
ShipwideAIFlags getAIFlags()
void giveCommand(ShipCommand command, Object param, int groupNumber)
void fadeToOtherColor(Object key, Color other, Color contrailColor, float effectLevel, float maxBlend)
void addWeapon(String slotId, String weaponId)
void addWeaponGroup(WeaponGroupSpec group)
boolean isNearViewport(Vector2f loc, float nearDistance)
void updateBeamFromPoints()
void setKeepBeamTargetWhileChargingDown(boolean keepTargetWhileChargingDown)
void setFacing(float facing)
void setScaleBeamGlowBasedOnDamageEffectiveness(boolean scaleGlowBasedOnDamageEffectiveness)
JSONObject getBehaviorJSON()
List< Vector2f > getTurretFireOffsets()
List< Float > getTurretAngleOffsets()