Starsector API
Loading...
Searching...
No Matches
ElectronicWarfareScript.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.skills;
2
3import java.util.HashSet;
4import java.util.List;
5import java.util.Set;
6
7import com.fs.starfarer.api.Global;
8import com.fs.starfarer.api.characters.PersonAPI;
9import com.fs.starfarer.api.combat.BaseEveryFrameCombatPlugin;
10import com.fs.starfarer.api.combat.BattleObjectiveAPI;
11import com.fs.starfarer.api.combat.CombatEngineAPI;
12import com.fs.starfarer.api.combat.CombatFleetManagerAPI;
13import com.fs.starfarer.api.combat.DeployedFleetMemberAPI;
14import com.fs.starfarer.api.combat.ShipAPI;
15import com.fs.starfarer.api.combat.ViewportAPI;
16import com.fs.starfarer.api.impl.campaign.ids.BattleObjectives;
17import com.fs.starfarer.api.impl.campaign.ids.Stats;
18import com.fs.starfarer.api.input.InputEventAPI;
19
20public class ElectronicWarfareScript extends BaseEveryFrameCombatPlugin {
21 public static Object KEY_STATUS = new Object();
22 public static Object KEY_STATUS_ENEMY_RATING = new Object();
23 public static Object KEY_STATUS2 = new Object();
24
25 public static float BASE_MAXIMUM = 10;
26
27 public static float PER_JAMMER = 5;
28
29 public static String PENALTY_ID = "electronic_warfare_penalty";
30
31 private CombatEngineAPI engine;
32 public void init(CombatEngineAPI engine) {
33 this.engine = engine;
34 }
35
36
37// public ElectronicWarfareScript() {
38// System.out.println("WEFWEGWGWEGF124");
39// }
40
41 private ShipAPI prevPlayerShip = null;
42 private int skipFrames = 0;
43 private Set<CombatFleetManagerAPI> needsCleanup = new HashSet<CombatFleetManagerAPI>();
44 public void advance(float amount, List<InputEventAPI> events) {
45 if (engine == null) return;
46 if (engine.isPaused()) return;
47
48
49 // if the player changed flagships:
50 // skip a few frames to make sure the status ends up on top of the status list
51 ShipAPI playerShip = engine.getPlayerShip();
52 if (playerShip != prevPlayerShip) {
53 prevPlayerShip = playerShip;
54 skipFrames = 20;
55 }
56
57 if (skipFrames > 0) {
58 skipFrames--;
59 return;
60 }
61
62
63 int [] player = getTotalAndMaximum(engine.getFleetManager(0));
64 int [] enemy = getTotalAndMaximum(engine.getFleetManager(1));
65
66
67 if (player == null || enemy == null) {
68 cleanUpIfNeeded(engine.getFleetManager(0));
69 cleanUpIfNeeded(engine.getFleetManager(1));
70 return;
71 }
72
73 if (engine.getFleetManager(0) == null || engine.getFleetManager(1) == null) {
74 cleanUpIfNeeded(engine.getFleetManager(0));
75 cleanUpIfNeeded(engine.getFleetManager(1));
76 return;
77 }
78
79 //player[0] = 20;
80
81 float pTotal = player[0];
82 float pMax = player[1];
83
84 float eTotal = enemy[0];
85 float eMax = enemy[1];
86
87// float origEMax = eMax;
88// if (player[2] > 0) {
89// float pExcess = pTotal - pMax * 2f;
90// if (pExcess > 0) {
91// eMax -= pExcess * 0.5f;
92// if (eMax < 0) eMax = 0;
93// }
94// }
95//
96// if (enemy[2] > 0) {
97// float eExcess = eTotal - origEMax * 2f;
98// if (eExcess > 0) {
99// pMax -= eExcess * 0.5f;
100// if (pMax < 0) pMax = 0;
101// }
102// }
103
104 if (pTotal <= 0) cleanUpIfNeeded(engine.getFleetManager(1));
105 if (eTotal <= 0) cleanUpIfNeeded(engine.getFleetManager(0));
106
107
108 int totalPenalty = (int) Math.round(Math.min(BASE_MAXIMUM, pTotal + eTotal));
109 if (totalPenalty <= 0f) return;
110
111 float ecmRatingToPenaltyMult = 1f;
112
113 float playerPenalty = (int) Math.min(eTotal * ecmRatingToPenaltyMult, eMax);
114 if (pTotal > 0 && playerPenalty > 0) {
115 float pMult = eTotal / (eTotal + pTotal);
116 playerPenalty *= pMult;
117 }
118
119 float enemyPenalty = (int) Math.min(pTotal * ecmRatingToPenaltyMult, pMax);
120 if (eTotal > 0 && enemyPenalty > 0) {
121 float eMult = pTotal / (eTotal + pTotal);
122 enemyPenalty *= eMult;
123 }
124
125 playerPenalty = Math.round(playerPenalty);
126 enemyPenalty = Math.round(enemyPenalty);
127
128
129 String icon = Global.getSettings().getSpriteName("ui", "icon_tactical_electronic_warfare");
130
131 if (playerPenalty > 0) {
132 applyPenalty(engine.getFleetManager(0), playerPenalty, eMax);
133
134 String sMax = "";
135 if (eMax <= playerPenalty) sMax = " (max)";
136 String title = "Enemy ECM rating:" + " " + (int) eTotal + "%";
137 String data = "-" + (int)playerPenalty + "% weapon range" + sMax;
138 if (eMax <= 0) {
139 data = "fully neutralized";
140 }
141 engine.maintainStatusForPlayerShip(KEY_STATUS_ENEMY_RATING, icon, title, data, eMax > 0);
142 }
143
144 if (enemyPenalty > 0) {
145 applyPenalty(engine.getFleetManager(1), enemyPenalty, pMax);
146
147 String sMax = "";
148 if (pMax <= enemyPenalty) sMax = " (max)";
149 String title = "ECM rating:" + " " + (int) pTotal + "%";
150 String data = "-" + (int)enemyPenalty + "% enemy weapon range" + sMax;
151 if (pMax <= 0) {
152 data = "fully neutralized";
153 }
154 engine.maintainStatusForPlayerShip(KEY_STATUS, icon, title, data, false);
155 }
156
157 if (playerPenalty > 0 && eMax > 0 && engine.getPlayerShip() != null) {
158 int eccm = 100 - (int) Math.round(engine.getPlayerShip().getMutableStats().getDynamic().getValue(Stats.ELECTRONIC_WARFARE_PENALTY_MOD, 100f));
159 if (eccm > 100) eccm = 100;
160 if (eccm < 0) eccm = 0;
161 //eccm = -eccm;
162 if (eccm != 0) {
163 //engine.maintainStatusForPlayerShip(KEY_STATUS2, icon, "On-board ECCM", "up to " + eccm + "% ecm neutralized", false);
164 engine.maintainStatusForPlayerShip(KEY_STATUS2, icon, "On-board ECCM", "" + eccm + "% enemy ecm neutralized", false);
165 }
166 }
167
168/*
169 //KEY_STATUS_ENEMY_RATING
170 float diff = pTotal - eTotal;
171
172 if (diff == 0) {
173 cleanUpIfNeeded(engine.getFleetManager(0));
174 cleanUpIfNeeded(engine.getFleetManager(1));
175 return;
176 }
177
178
179 CombatFleetManagerAPI winner = engine.getFleetManager(0);
180 CombatFleetManagerAPI loser = engine.getFleetManager(1);
181
182 float max = pMax;
183 if (diff < 0) {
184 CombatFleetManagerAPI temp = winner;
185 winner = loser;
186 loser = temp;
187 max = eMax;
188 }
189
190 float penalty = Math.min(Math.abs(diff), max);
191
192 cleanUpIfNeeded(winner);
193 applyPenalty(loser, penalty, max);
194
195
196 boolean playerWon = winner.getOwner() == engine.getPlayerShip().getOwner();
197
198 String title = "ECM rating:" + " " + (int) pTotal + "% vs " + (int)eTotal + "%";
199 String data = "-" + (int)penalty + "% weapon range";
200 if (playerWon) {
201 data = "-" + (int)penalty + "% enemy weapon range";
202 }
203
204 String icon = Global.getSettings().getSpriteName("ui", "icon_tactical_electronic_warfare");
205
206 if (engine.getPlayerShip() != null && !playerWon) {
207 int eccm = 100 - (int) Math.round(engine.getPlayerShip().getMutableStats().getDynamic().getValue(Stats.ELECTRONIC_WARFARE_PENALTY_MOD, 100f));
208 if (eccm > 100) eccm = 100;
209 if (eccm < 0) eccm = 0;
210 //eccm = -eccm;
211 if (eccm != 0) {
212 //engine.maintainStatusForPlayerShip(KEY_STATUS2, icon, "On-board ECCM", "up to " + eccm + "% ecm neutralized", false);
213 engine.maintainStatusForPlayerShip(KEY_STATUS2, icon, "On-board ECCM", "" + eccm + "% ecm neutralized", false);
214 }
215 }
216
217 engine.maintainStatusForPlayerShip(KEY_STATUS, icon, title, data, !playerWon);
218 */
219 }
220
221 private void applyPenalty(CombatFleetManagerAPI manager, float penalty, float maxPenalty) {
222 List<DeployedFleetMemberAPI> deployed = manager.getDeployedCopyDFM();
223 for (DeployedFleetMemberAPI member : deployed) {
224 if (member.isFighterWing()) continue;
225 if (member.getShip() == null) continue;
226
227 float currPenalty = penalty * member.getShip().getMutableStats().getDynamic().getValue(Stats.ELECTRONIC_WARFARE_PENALTY_MULT);
228 currPenalty = member.getShip().getMutableStats().getDynamic().getValue(Stats.ELECTRONIC_WARFARE_PENALTY_MOD, currPenalty);
229 if (currPenalty < 0) currPenalty = 0;
230
231 float maxMod = penalty * member.getShip().getMutableStats().getDynamic().getValue(Stats.ELECTRONIC_WARFARE_PENALTY_MAX_FOR_SHIP_MOD, 0);
232 float currMax = maxPenalty + maxMod;
233 if (currPenalty > currMax) {
234 currPenalty = currMax;
235 }
236
237 member.getShip().getMutableStats().getBallisticWeaponRangeBonus().modifyMult(PENALTY_ID, 1f - currPenalty/100f);
238 member.getShip().getMutableStats().getEnergyWeaponRangeBonus().modifyMult(PENALTY_ID, 1f - currPenalty/100f);
239 member.getShip().getMutableStats().getMissileWeaponRangeBonus().modifyMult(PENALTY_ID, 1f - currPenalty/100f);
240 }
241
242 needsCleanup.add(manager);
243 }
244
245 protected void cleanUpIfNeeded(CombatFleetManagerAPI manager) {
246 if (needsCleanup.contains(manager)) {
247 needsCleanup.remove(manager);
248 List<DeployedFleetMemberAPI> deployed = manager.getDeployedCopyDFM();
249 for (DeployedFleetMemberAPI member : deployed) {
250 if (member.isFighterWing()) continue;
251 if (member.getShip() == null) continue;
252
253 member.getShip().getMutableStats().getBallisticWeaponRangeBonus().unmodify(PENALTY_ID);
254 member.getShip().getMutableStats().getEnergyWeaponRangeBonus().unmodify(PENALTY_ID);
255 member.getShip().getMutableStats().getMissileWeaponRangeBonus().unmodify(PENALTY_ID);
256 }
257 }
258 }
259
260 private int [] getTotalAndMaximum(CombatFleetManagerAPI manager) {
261// PersonAPI commander = manager.getFleetCommander();
262// if (commander == null) {
263// return null;
264// }
265// float max = BASE_MAXIMUM + commander.getStats().getDynamic().getValue(Stats.ELECTRONIC_WARFARE_MAX, 0f);
266
267 float max = 0f;
268 for (PersonAPI commander : manager.getAllFleetCommanders()) {
269 max = Math.max(max, BASE_MAXIMUM + commander.getStats().getDynamic().getValue(Stats.ELECTRONIC_WARFARE_MAX, 0f));
270 }
271
272
273 float total = 0f;
274 List<DeployedFleetMemberAPI> deployed = manager.getDeployedCopyDFM();
275 float canCounter = 0f;
276 for (DeployedFleetMemberAPI member : deployed) {
277 if (member.isFighterWing()) continue;
278 if (member.isStationModule()) continue;
279 float curr = member.getShip().getMutableStats().getDynamic().getValue(Stats.ELECTRONIC_WARFARE_FLAT, 0f);
280 total += curr;
281
282 canCounter += member.getShip().getMutableStats().getDynamic().getValue(Stats.SHIP_BELONGS_TO_FLEET_THAT_CAN_COUNTER_EW, 0f);
283 }
284
285 for (BattleObjectiveAPI obj : engine.getObjectives()) {
286 if (obj.getOwner() == manager.getOwner() && BattleObjectives.SENSOR_JAMMER.equals(obj.getType())) {
287 total += PER_JAMMER;
288 }
289 }
290
291 int counter = 0;
292 if (canCounter > 0) counter = 1;
293
294 return new int [] {(int) total, (int) max, counter};
295 }
296
297
298
299
300
301 public void renderInUICoords(ViewportAPI viewport) {
302 }
303
304 public void renderInWorldCoords(ViewportAPI viewport) {
305 }
306
307}
static SettingsAPI getSettings()
Definition Global.java:51
String getSpriteName(String category, String id)