31 public static class DroneMissileScript
extends BaseCombatLayeredRenderingPlugin {
32 protected ShipAPI drone;
33 protected MissileAPI missile;
34 protected boolean done;
36 public DroneMissileScript(ShipAPI drone, MissileAPI missile) {
39 this.missile = missile;
40 missile.setNoFlameoutOnFizzling(
true);
45 public void advance(
float amount) {
46 super.advance(amount);
52 missile.setEccmChanceOverride(1f);
53 missile.setOwner(drone.getOriginalOwner());
55 drone.getLocation().set(missile.getLocation());
56 drone.getVelocity().set(missile.getVelocity());
57 drone.setCollisionClass(CollisionClass.FIGHTER);
58 drone.setFacing(missile.getFacing());
59 drone.getEngineController().fadeToOtherColor(
this,
new Color(0,0,0,0),
new Color(0,0,0,0), 1f, 1f);
62 float dist = Misc.getDistance(missile.getLocation(), missile.getStart());
63 float jitterFraction = dist / missile.getMaxRange();
64 jitterFraction = Math.max(jitterFraction, missile.getFlightTime() / missile.getMaxFlightTime());
66 missile.setSpriteAlphaOverride(0f);
67 float jitterMax = 1f + 10f * jitterFraction;
68 drone.setJitter(
this,
new Color(255,100,50, (
int)(25 + 50 * jitterFraction)), 1f, 10, 1f, jitterMax);
77 boolean droneDestroyed = drone.isHulk() || drone.getHitpoints() <= 0;
78 if (missile.isFizzling() || (missile.getHitpoints() <= 0 && !missile.didDamage()) || droneDestroyed) {
79 drone.getVelocity().set(0, 0);
80 missile.getVelocity().set(0, 0);
82 if (!droneDestroyed) {
83 Vector2f damageFrom =
new Vector2f(drone.getLocation());
84 damageFrom = Misc.getPointWithinRadius(damageFrom, 20);
85 engine.applyDamage(drone, damageFrom, 1000000f, DamageType.ENERGY, 0,
true,
false, drone,
false);
87 missile.interruptContrail();
88 engine.removeEntity(drone);
89 engine.removeEntity(missile);
96 if (missile.didDamage()) {
97 drone.getVelocity().set(0, 0);
98 missile.getVelocity().set(0, 0);
100 Vector2f damageFrom =
new Vector2f(drone.getLocation());
101 damageFrom = Misc.getPointWithinRadius(damageFrom, 20);
102 engine.applyDamage(drone, damageFrom, 1000000f, DamageType.ENERGY, 0,
true,
false, drone,
false);
103 missile.interruptContrail();
104 engine.removeEntity(drone);
105 engine.removeEntity(missile);
113 public boolean isExpired() {
123 return "terminator_missile";
132 public void apply(MutableShipStatsAPI stats, String
id, State state,
float effectLevel) {
135 if (stats.getEntity() instanceof ShipAPI) {
136 ship = (ShipAPI) stats.getEntity();
147 drone.setExplosionScale(0.67f);
148 drone.setExplosionVelocityOverride(
new Vector2f());
149 drone.setExplosionFlashColorOverride(
new Color(255, 100, 50, 255));
152 if (effectLevel > 0 && !
fired) {
157 }
else if (state == State.IDLE){
169 if (target !=
null) {
170 Collections.sort(drones,
new Comparator<ShipAPI>() {
171 public int compare(ShipAPI o1, ShipAPI o2) {
172 float d1 = Misc.getDistance(o1.getLocation(), target.getLocation());
173 float d2 = Misc.getDistance(o2.getLocation(), target.getLocation());
174 return (
int)Math.signum(d1 - d2);
178 Collections.shuffle(drones);
181 for (ShipAPI drone : drones) {
183 MissileAPI missile = (MissileAPI) engine.spawnProjectile(
185 new Vector2f(drone.getLocation()), drone.getFacing(),
new Vector2f(drone.getVelocity()));
186 if (target !=
null && missile.getAI() instanceof GuidedMissileAI) {
187 GuidedMissileAI ai = (GuidedMissileAI) missile.getAI();
188 ai.setTarget(target);
191 missile.setEmpResistance(10000);
193 float base = missile.getMaxRange();
195 missile.setMaxRange(max);
196 missile.setMaxFlightTime(missile.getMaxFlightTime() * max/base);
198 drone.getWing().removeMember(drone);
200 drone.setExplosionFlashColorOverride(
new Color(255, 100, 50, 255));
201 engine.addLayeredRenderingPlugin(
new DroneMissileScript(drone, missile));
209 float thickness = 26f;
210 float coreWidthMult = 0.67f;
211 EmpArcEntityAPI arc = engine.spawnEmpArcVisual(ship.getLocation(), ship,
212 missile.getLocation(), missile, thickness,
new Color(255,100,100,255), Color.white);
213 arc.setCoreWidthOverride(thickness * coreWidthMult);
214 arc.setSingleFlickerMode();
216 if (drone.getShipAI() !=
null) {
217 drone.getShipAI().cancelCurrentManeuver();
225 public void unapply(MutableShipStatsAPI stats, String
id) {
241 ShipAPI target = ship.getShipTarget();
249 Object test = ship.getAIFlags().getCustom(AIFlags.MANEUVER_TARGET);
250 if (test instanceof ShipAPI) {
251 target = (ShipAPI) test;
252 float dist = Misc.getDistance(ship.getLocation(), target.getLocation());
253 float radSum = ship.getCollisionRadius() + target.getCollisionRadius();
254 if (dist > range + radSum) target =
null;
256 if (target ==
null) {
257 target = Misc.findClosestShipEnemyOf(ship, ship.getMouseTarget(), HullSize.FRIGATE, range,
true);
264 if (target !=
null)
return target;
268 target = Misc.findClosestShipEnemyOf(ship, ship.getMouseTarget(), HullSize.FIGHTER, Float.MAX_VALUE,
true);
269 if (target !=
null && target.isFighter()) {
270 ShipAPI nearbyShip = Misc.findClosestShipEnemyOf(ship, target.getLocation(), HullSize.FRIGATE, 100,
false);
271 if (nearbyShip !=
null) target = nearbyShip;
273 if (target ==
null) {
274 target = Misc.findClosestShipEnemyOf(ship, ship.getLocation(), HullSize.FIGHTER, range,
true);
281 public StatusData
getStatusData(
int index, State state,
float effectLevel) {
286 List<ShipAPI> result =
new ArrayList<ShipAPI>();
287 for (FighterLaunchBayAPI bay : ship.getLaunchBaysCopy()) {
288 if (bay.getWing() ==
null)
continue;
289 for (ShipAPI drone : bay.getWing().getWingMembers()) {
298 if (system.isOutOfAmmo())
return null;
299 if (system.getState() != SystemState.IDLE)
return null;
308 if (target ==
null) {
309 if (ship.getMouseTarget() !=
null) {
310 float dist = Misc.getDistance(ship.getLocation(), ship.getMouseTarget());
311 float radSum = ship.getCollisionRadius();
312 if (dist + radSum > range) {
313 return "OUT OF RANGE";
319 float dist = Misc.getDistance(ship.getLocation(), target.getLocation());
320 float radSum = ship.getCollisionRadius() + target.getCollisionRadius();
321 if (dist > range + radSum) {
322 return "OUT OF RANGE";
330 public boolean isUsable(ShipSystemAPI system, ShipAPI ship) {
331 if (ship !=
null && ship.getSystem() !=
null && ship.getSystem().getState() != SystemState.IDLE) {
345 return ship.getMutableStats().getSystemRangeBonus().computeEffective(
weapon.getRange());
357 return weapon.getProjectileSpeed();