Starsector API
Loading...
Searching...
No Matches
InterdictorArrayStats.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.combat;
2
3import java.awt.Color;
4import java.util.ArrayList;
5import java.util.Collections;
6import java.util.List;
7
8import com.fs.starfarer.api.Global;
9import com.fs.starfarer.api.combat.CombatEngineAPI;
10import com.fs.starfarer.api.combat.MutableShipStatsAPI;
11import com.fs.starfarer.api.combat.ShipAPI;
12import com.fs.starfarer.api.combat.ShipEngineControllerAPI;
13import com.fs.starfarer.api.combat.ShipSystemAPI;
14import com.fs.starfarer.api.combat.ShipAPI.HullSize;
15import com.fs.starfarer.api.combat.ShipEngineControllerAPI.ShipEngineAPI;
16import com.fs.starfarer.api.combat.ShipSystemAPI.SystemState;
17import com.fs.starfarer.api.combat.ShipwideAIFlags.AIFlags;
18import com.fs.starfarer.api.util.Misc;
19import com.fs.starfarer.api.util.Misc.FindShipFilter;
20
22 public static final Object SHIP_KEY = new Object();
23 public static final Object TARGET_KEY = new Object();
24
25 public static final float WING_EFFECT_RANGE = 200f;
26
27 public static final float RANGE = 1000f;
28 public static final Color EFFECT_COLOR = new Color(100,165,255,75);
29
30
31 public static class TargetData {
32 public ShipAPI target;
33 public float sinceLastAfterimage = 0f;
34 public boolean lastAbove = false;
35 public TargetData(ShipAPI target) {
36 this.target = target;
37 }
38 }
39
40 public void apply(MutableShipStatsAPI stats, final String id, State state, float effectLevel) {
41 ShipAPI ship = null;
42 if (stats.getEntity() instanceof ShipAPI) {
43 ship = (ShipAPI) stats.getEntity();
44 } else {
45 return;
46 }
47
48 final String targetDataKey = ship.getId() + "_interdictor_target_data";
49
50 Object targetDataObj = Global.getCombatEngine().getCustomData().get(targetDataKey);
51 if (state == State.IN && targetDataObj == null) {
52 ShipAPI target = findTarget(ship);
53 Global.getCombatEngine().getCustomData().put(targetDataKey, new TargetData(target));
54 } else if (state == State.IDLE && targetDataObj != null) {
55 Global.getCombatEngine().getCustomData().remove(targetDataKey);
56 }
57 if (targetDataObj == null || ((TargetData) targetDataObj).target == null) return;
58
59 final TargetData targetData = (TargetData) targetDataObj;
60
61 //ShipAPI target = targetData.target;
62 List<ShipAPI> targets = new ArrayList<ShipAPI>();
63 if (targetData.target.isFighter() || targetData.target.isDrone()) {
65 List<ShipAPI> ships = engine.getShips();
66 for (ShipAPI other : ships) {
67 if (other.isShuttlePod()) continue;
68 if (other.isHulk()) continue;
69 if (!other.isDrone() && !other.isFighter()) continue;
70 if (other.getOriginalOwner() != targetData.target.getOriginalOwner()) continue;
71
72 float dist = Misc.getDistance(other.getLocation(), targetData.target.getLocation());
73 if (dist > WING_EFFECT_RANGE) continue;
74
75 targets.add(other);
76 }
77 } else {
78 targets.add(targetData.target);
79 }
80
81 boolean first = true;
82 for (ShipAPI target : targets) {
83 if (effectLevel >= 1) {
84 Color color = getEffectColor(target);
85 color = Misc.setAlpha(color, 255);
86
87 if (first) {
88 if (target.getFluxTracker().showFloaty() ||
90 target == Global.getCombatEngine().getPlayerShip()) {
91 target.getFluxTracker().showOverloadFloatyIfNeeded("Drive Interdicted!", color, 4f, true);
92 }
93 first = false;
94 }
95
96 ShipEngineControllerAPI ec = target.getEngineController();
97 float limit = ec.getFlameoutFraction();
98 if (target.isDrone() || target.isFighter()) {
99 limit = 1f;
100 }
101
102 float disabledSoFar = 0f;
103 boolean disabledAnEngine = false;
104 List<ShipEngineAPI> engines = new ArrayList<ShipEngineAPI>(ec.getShipEngines());
105 Collections.shuffle(engines);
106
107 for (ShipEngineAPI engine : engines) {
108 if (engine.isDisabled()) continue;
109 float contrib = engine.getContribution();
110 if (disabledSoFar + contrib <= limit) {
111 engine.disable();
112 disabledSoFar += contrib;
113 disabledAnEngine = true;
114 }
115 }
116 if (!disabledAnEngine) {
117 for (ShipEngineAPI engine : engines) {
118 if (engine.isDisabled()) continue;
119 engine.disable();
120 break;
121 }
122 }
124 }
125
126 if (effectLevel > 0) {
127 float jitterLevel = effectLevel;
128 float maxRangeBonus = 20f + target.getCollisionRadius() * 0.25f;
129 float jitterRangeBonus = jitterLevel * maxRangeBonus;
130 if (state == State.OUT) {
131 jitterRangeBonus = maxRangeBonus + (1f - jitterLevel) * maxRangeBonus;
132 }
133 target.setJitter(this,
134 //target.getSpriteAPI().getAverageColor(),
135 getEffectColor(target),
136 jitterLevel, 6, 0f, 0 + jitterRangeBonus);
137
138 if (first) {
139 ship.setJitter(this,
140 //target.getSpriteAPI().getAverageColor(),
141 getEffectColor(targetData.target),
142 jitterLevel, 6, 0f, 0 + jitterRangeBonus);
143 }
144 }
145 }
146 }
147
148
149 protected Color getEffectColor(ShipAPI ship) {
150 if (ship.getEngineController().getShipEngines().isEmpty()) {
151 return EFFECT_COLOR;
152 }
153 return Misc.setAlpha(ship.getEngineController().getShipEngines().get(0).getEngineColor(), EFFECT_COLOR.getAlpha());
154 }
155
156
157 public void unapply(MutableShipStatsAPI stats, String id) {
158
159 }
160
161 protected ShipAPI findTarget(ShipAPI ship) {
162 FindShipFilter filter = new FindShipFilter() {
163 public boolean matches(ShipAPI ship) {
164 return !ship.getEngineController().isFlamedOut();
165 }
166 };
167
168 float range = getMaxRange(ship);
169 boolean player = ship == Global.getCombatEngine().getPlayerShip();
170 ShipAPI target = ship.getShipTarget();
171 if (target != null) {
172 float dist = Misc.getDistance(ship.getLocation(), target.getLocation());
173 float radSum = ship.getCollisionRadius() + target.getCollisionRadius();
174 if (dist > range + radSum) target = null;
175 } else {
176 if (target == null || target.getOwner() == ship.getOwner()) {
177 if (player) {
178 target = Misc.findClosestShipEnemyOf(ship, ship.getMouseTarget(), HullSize.FIGHTER, range, true, filter);
179 } else {
180 Object test = ship.getAIFlags().getCustom(AIFlags.MANEUVER_TARGET);
181 if (test instanceof ShipAPI) {
182 target = (ShipAPI) test;
183 float dist = Misc.getDistance(ship.getLocation(), target.getLocation());
184 float radSum = ship.getCollisionRadius() + target.getCollisionRadius();
185 if (dist > range + radSum) target = null;
186 }
187 }
188 }
189 if (target == null) {
190 target = Misc.findClosestShipEnemyOf(ship, ship.getLocation(), HullSize.FIGHTER, range, true, filter);
191 }
192 }
193
194 return target;
195 }
196
197
198 protected float getMaxRange(ShipAPI ship) {
199 return RANGE;
200 }
201
202
203 public StatusData getStatusData(int index, State state, float effectLevel) {
204// if (effectLevel > 0) {
205// if (index == 0) {
206// float damMult = 1f + (DAM_MULT - 1f) * effectLevel;
207// return new StatusData("" + (int)((damMult - 1f) * 100f) + "% more damage to target", false);
208// }
209// }
210 return null;
211 }
212
213
214 @Override
215 public String getInfoText(ShipSystemAPI system, ShipAPI ship) {
216 if (system.isOutOfAmmo()) return null;
217 if (system.getState() != SystemState.IDLE) return null;
218
219 ShipAPI target = findTarget(ship);
220 if (target != null && target != ship) {
221 return "READY";
222 }
223 if (target == null && ship.getShipTarget() != null) {
224 return "OUT OF RANGE";
225 }
226 return "NO TARGET";
227 }
228
229
230 @Override
231 public boolean isUsable(ShipSystemAPI system, ShipAPI ship) {
232 if (system.isActive()) return true;
233 ShipAPI target = findTarget(ship);
234 return target != null && target != ship;
235 }
236
237}
238
239
240
241
242
243
244
245
static CombatEngineAPI getCombatEngine()
Definition Global.java:69
void apply(MutableShipStatsAPI stats, final String id, State state, float effectLevel)
String getInfoText(ShipSystemAPI system, ShipAPI ship)
boolean isUsable(ShipSystemAPI system, ShipAPI ship)
StatusData getStatusData(int index, State state, float effectLevel)
static ShipAPI findClosestShipEnemyOf(ShipAPI ship, Vector2f locFromForSorting, HullSize smallestToNote, float maxRange, boolean considerShipRadius)
Definition Misc.java:2497
static Color setAlpha(Color color, int alpha)
Definition Misc.java:1316
static float getDistance(SectorEntityToken from, SectorEntityToken to)
Definition Misc.java:599
void setJitter(Object source, Color color, float intensity, int copies, float range)
ShipEngineControllerAPI getEngineController()
void computeEffectiveStats(boolean forceShowFloaty)