Starsector API
Loading...
Searching...
No Matches
Misc.java
Go to the documentation of this file.
1package com.fs.starfarer.api.util;
2
3import java.io.IOException;
4import java.lang.reflect.Method;
5import java.nio.Buffer;
6import java.text.DecimalFormat;
7import java.text.DecimalFormatSymbols;
8import java.util.ArrayList;
9import java.util.Arrays;
10import java.util.Collection;
11import java.util.Collections;
12import java.util.Comparator;
13import java.util.HashMap;
14import java.util.HashSet;
15import java.util.LinkedHashMap;
16import java.util.LinkedHashSet;
17import java.util.List;
18import java.util.Locale;
19import java.util.Map;
20import java.util.Random;
21import java.util.Set;
22import java.util.UUID;
23import java.util.concurrent.atomic.AtomicLong;
24import java.util.regex.Matcher;
25import java.util.regex.Pattern;
26
27import java.awt.Color;
28import java.awt.image.BufferedImage;
29import java.awt.image.Raster;
30
31import javax.imageio.ImageIO;
32
33import org.json.JSONArray;
34import org.json.JSONException;
35import org.json.JSONObject;
36import org.lwjgl.opengl.ATIMeminfo;
37import org.lwjgl.opengl.GL11;
38import org.lwjgl.opengl.NVXGpuMemoryInfo;
39import org.lwjgl.util.vector.Vector2f;
40import org.lwjgl.util.vector.Vector3f;
41
42import com.fs.starfarer.api.EveryFrameScript;
43import com.fs.starfarer.api.Global;
44import com.fs.starfarer.api.MusicPlayerPlugin;
45import com.fs.starfarer.api.campaign.AICoreAdminPlugin;
46import com.fs.starfarer.api.campaign.AICoreOfficerPlugin;
47import com.fs.starfarer.api.campaign.BattleAPI;
48import com.fs.starfarer.api.campaign.CampaignClockAPI;
49import com.fs.starfarer.api.campaign.CampaignFleetAPI;
50import com.fs.starfarer.api.campaign.CampaignTerrainAPI;
51import com.fs.starfarer.api.campaign.CampaignUIAPI.CoreUITradeMode;
52import com.fs.starfarer.api.campaign.CargoAPI;
53import com.fs.starfarer.api.campaign.CargoAPI.CargoItemType;
54import com.fs.starfarer.api.campaign.CargoStackAPI;
55import com.fs.starfarer.api.campaign.CommDirectoryEntryAPI;
56import com.fs.starfarer.api.campaign.CommDirectoryEntryAPI.EntryType;
57import com.fs.starfarer.api.campaign.CustomCampaignEntityAPI;
58import com.fs.starfarer.api.campaign.FactionAPI;
59import com.fs.starfarer.api.campaign.FactionAPI.ShipPickMode;
60import com.fs.starfarer.api.campaign.FleetAssignment;
61import com.fs.starfarer.api.campaign.FleetInflater;
62import com.fs.starfarer.api.campaign.InteractionDialogAPI;
63import com.fs.starfarer.api.campaign.JumpPointAPI;
64import com.fs.starfarer.api.campaign.JumpPointAPI.JumpDestination;
65import com.fs.starfarer.api.campaign.LocationAPI;
66import com.fs.starfarer.api.campaign.ParticleControllerAPI;
67import com.fs.starfarer.api.campaign.PlanetAPI;
68import com.fs.starfarer.api.campaign.PlanetSpecAPI;
69import com.fs.starfarer.api.campaign.RepLevel;
70import com.fs.starfarer.api.campaign.ReputationActionResponsePlugin.ReputationAdjustmentResult;
71import com.fs.starfarer.api.campaign.ResourceCostPanelAPI;
72import com.fs.starfarer.api.campaign.SectorEntityToken;
73import com.fs.starfarer.api.campaign.SectorEntityToken.VisibilityLevel;
74import com.fs.starfarer.api.campaign.StarSystemAPI;
75import com.fs.starfarer.api.campaign.SubmarketPlugin;
76import com.fs.starfarer.api.campaign.SubmarketPlugin.OnClickAction;
77import com.fs.starfarer.api.campaign.TextPanelAPI;
78import com.fs.starfarer.api.campaign.ai.CampaignFleetAIAPI.EncounterOption;
79import com.fs.starfarer.api.campaign.ai.FleetAIFlags;
80import com.fs.starfarer.api.campaign.ai.ModularFleetAIAPI;
81import com.fs.starfarer.api.campaign.comm.CommMessageAPI.MessageClickAction;
82import com.fs.starfarer.api.campaign.econ.AbandonMarketPlugin;
83import com.fs.starfarer.api.campaign.econ.CommodityOnMarketAPI;
84import com.fs.starfarer.api.campaign.econ.CommoditySpecAPI;
85import com.fs.starfarer.api.campaign.econ.ImmigrationPlugin;
86import com.fs.starfarer.api.campaign.econ.Industry;
87import com.fs.starfarer.api.campaign.econ.MarketAPI;
88import com.fs.starfarer.api.campaign.econ.MarketAPI.SurveyLevel;
89import com.fs.starfarer.api.campaign.econ.MarketConditionAPI;
90import com.fs.starfarer.api.campaign.econ.StabilizeMarketPlugin;
91import com.fs.starfarer.api.campaign.econ.SubmarketAPI;
92import com.fs.starfarer.api.campaign.events.CampaignEventManagerAPI;
93import com.fs.starfarer.api.campaign.events.CampaignEventPlugin;
94import com.fs.starfarer.api.campaign.events.CampaignEventTarget;
95import com.fs.starfarer.api.campaign.rules.MemKeys;
96import com.fs.starfarer.api.campaign.rules.MemoryAPI;
97import com.fs.starfarer.api.characters.AbilityPlugin;
98import com.fs.starfarer.api.characters.MarketConditionSpecAPI;
99import com.fs.starfarer.api.characters.MutableCharacterStatsAPI;
100import com.fs.starfarer.api.characters.MutableCharacterStatsAPI.SkillLevelAPI;
101import com.fs.starfarer.api.characters.OfficerDataAPI;
102import com.fs.starfarer.api.characters.PersonAPI;
103import com.fs.starfarer.api.combat.CombatEngineAPI;
104import com.fs.starfarer.api.combat.CombatEntityAPI;
105import com.fs.starfarer.api.combat.DamageType;
106import com.fs.starfarer.api.combat.MissileAPI;
107import com.fs.starfarer.api.combat.MutableShipStatsAPI;
108import com.fs.starfarer.api.combat.ShipAPI;
109import com.fs.starfarer.api.combat.ShipAPI.HullSize;
110import com.fs.starfarer.api.combat.ShipCommand;
111import com.fs.starfarer.api.combat.ShipHullSpecAPI;
112import com.fs.starfarer.api.combat.ShipHullSpecAPI.ShipTypeHints;
113import com.fs.starfarer.api.combat.ShipVariantAPI;
114import com.fs.starfarer.api.combat.WeaponAPI;
115import com.fs.starfarer.api.combat.listeners.ApplyDamageResultAPI;
116import com.fs.starfarer.api.combat.listeners.CombatListenerUtil;
117import com.fs.starfarer.api.fleet.FleetMemberAPI;
118import com.fs.starfarer.api.graphics.SpriteAPI;
119import com.fs.starfarer.api.impl.SharedUnlockData;
120import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.CustomRepImpact;
121import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActionEnvelope;
122import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActions;
123import com.fs.starfarer.api.impl.campaign.DModManager;
124import com.fs.starfarer.api.impl.campaign.JumpPointInteractionDialogPluginImpl;
125import com.fs.starfarer.api.impl.campaign.RuleBasedInteractionDialogPluginImpl;
126import com.fs.starfarer.api.impl.campaign.WarningBeaconEntityPlugin;
127import com.fs.starfarer.api.impl.campaign.abilities.ReversePolarityToggle;
128import com.fs.starfarer.api.impl.campaign.econ.impl.ConstructionQueue.ConstructionQueueItem;
129import com.fs.starfarer.api.impl.campaign.econ.impl.ShipQuality;
130import com.fs.starfarer.api.impl.campaign.econ.impl.ShipQuality.QualityData;
131import com.fs.starfarer.api.impl.campaign.events.BaseEventPlugin.MarketFilter;
132import com.fs.starfarer.api.impl.campaign.fleets.FleetFactoryV3;
133import com.fs.starfarer.api.impl.campaign.ids.Conditions;
134import com.fs.starfarer.api.impl.campaign.ids.Difficulties;
135import com.fs.starfarer.api.impl.campaign.ids.Drops;
136import com.fs.starfarer.api.impl.campaign.ids.Entities;
137import com.fs.starfarer.api.impl.campaign.ids.Factions;
138import com.fs.starfarer.api.impl.campaign.ids.HullMods;
139import com.fs.starfarer.api.impl.campaign.ids.Industries;
140import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
141import com.fs.starfarer.api.impl.campaign.ids.Personalities;
142import com.fs.starfarer.api.impl.campaign.ids.Stats;
143import com.fs.starfarer.api.impl.campaign.ids.Strings;
144import com.fs.starfarer.api.impl.campaign.ids.Submarkets;
145import com.fs.starfarer.api.impl.campaign.ids.Tags;
146import com.fs.starfarer.api.impl.campaign.ids.Terrain;
147import com.fs.starfarer.api.impl.campaign.intel.FactionCommissionIntel;
148import com.fs.starfarer.api.impl.campaign.intel.MessageIntel;
149import com.fs.starfarer.api.impl.campaign.intel.contacts.ContactIntel;
150import com.fs.starfarer.api.impl.campaign.plog.PlaythroughLog;
151import com.fs.starfarer.api.impl.campaign.plog.SModRecord;
152import com.fs.starfarer.api.impl.campaign.population.CoreImmigrationPluginImpl;
153import com.fs.starfarer.api.impl.campaign.procgen.ConditionGenDataSpec;
154import com.fs.starfarer.api.impl.campaign.procgen.DefenderDataOverride;
155import com.fs.starfarer.api.impl.campaign.procgen.PlanetConditionGenerator;
156import com.fs.starfarer.api.impl.campaign.procgen.PlanetGenDataSpec;
157import com.fs.starfarer.api.impl.campaign.procgen.SalvageEntityGenDataSpec.DropData;
158import com.fs.starfarer.api.impl.campaign.procgen.StarAge;
159import com.fs.starfarer.api.impl.campaign.procgen.StarGenDataSpec;
160import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator;
161import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseThemeGenerator.OrbitGap;
162import com.fs.starfarer.api.impl.campaign.rulecmd.AddRemoveCommodity;
163import com.fs.starfarer.api.impl.campaign.rulecmd.unsetAll;
164import com.fs.starfarer.api.impl.campaign.submarkets.BaseSubmarketPlugin;
165import com.fs.starfarer.api.impl.campaign.submarkets.StoragePlugin;
166import com.fs.starfarer.api.impl.campaign.terrain.AsteroidSource;
167import com.fs.starfarer.api.impl.campaign.terrain.BaseTiledTerrain.TileParams;
168import com.fs.starfarer.api.impl.campaign.terrain.DebrisFieldTerrainPlugin;
169import com.fs.starfarer.api.impl.campaign.terrain.DebrisFieldTerrainPlugin.DebrisFieldParams;
170import com.fs.starfarer.api.impl.campaign.terrain.HyperspaceTerrainPlugin;
171import com.fs.starfarer.api.impl.campaign.terrain.MagneticFieldTerrainPlugin;
172import com.fs.starfarer.api.impl.campaign.terrain.NebulaTerrainPlugin;
173import com.fs.starfarer.api.impl.campaign.terrain.PulsarBeamTerrainPlugin;
174import com.fs.starfarer.api.impl.campaign.terrain.StarCoronaTerrainPlugin;
175import com.fs.starfarer.api.impl.campaign.velfield.SlipstreamTerrainPlugin2;
176import com.fs.starfarer.api.impl.campaign.velfield.SlipstreamTerrainPlugin2.SlipstreamSegment;
177import com.fs.starfarer.api.impl.codex.CodexUnlocker;
178import com.fs.starfarer.api.loading.HullModSpecAPI;
179import com.fs.starfarer.api.loading.IndustrySpecAPI;
180import com.fs.starfarer.api.plugins.FactionPersonalityPickerPlugin;
181import com.fs.starfarer.api.plugins.SimulatorPlugin;
182import com.fs.starfarer.api.plugins.SurveyPlugin;
183import com.fs.starfarer.api.ui.Alignment;
184import com.fs.starfarer.api.ui.LabelAPI;
185import com.fs.starfarer.api.ui.TooltipMakerAPI;
186
187
188public class Misc {
189
190 public static boolean CAN_SMOD_BUILT_IN = true;
191
192 public static String SIR = "Sir";
193 public static String MAAM = "Ma'am";
194 public static String CAPTAIN = "Captain";
195
196 public static float FLUX_PER_CAPACITOR = Global.getSettings().getFloat("fluxPerCapacitor");
197 public static float DISSIPATION_PER_VENT = Global.getSettings().getFloat("dissipationPerVent");
198
199 private static boolean cbMode = Global.getSettings().getBoolean("colorblindMode");
200
201 public static Color MOUNT_BALLISTIC = Global.getSettings().getColor("mountYellowColor");
202 public static Color MOUNT_MISSILE = Global.getSettings().getColor("mountGreenColor");
203 public static Color MOUNT_ENERGY = cbMode ? new Color(155,155,155,255) : Global.getSettings().getColor("mountBlueColor");
204 public static Color MOUNT_UNIVERSAL = Global.getSettings().getColor("mountGrayColor");
205 public static Color MOUNT_HYBRID = Global.getSettings().getColor("mountOrangeColor");
206 public static Color MOUNT_SYNERGY = Global.getSettings().getColor("mountCyanColor");
207 public static Color MOUNT_COMPOSITE = Global.getSettings().getColor("mountCompositeColor");
208
209 // for combat entities
210 public static final int OWNER_NEUTRAL = 100;
211 public static final int OWNER_PLAYER = 0;
212
213 public static Color FLOATY_EMP_DAMAGE_COLOR = new Color(255,255,255,255);
214 public static Color FLOATY_ARMOR_DAMAGE_COLOR = new Color(255,255,0,220);
215 public static Color FLOATY_SHIELD_DAMAGE_COLOR = new Color(200,200,255,220);
216 public static Color FLOATY_HULL_DAMAGE_COLOR = new Color(255,50,0,220);
217
218// public static final String SUPPLY_ACCESSIBILITY = "Supply Accessibility";
219
220 public static float GATE_FUEL_COST_MULT = Global.getSettings().getFloat("gateTransitFuelCostMult");
221
222 public static int MAX_COLONY_SIZE = Global.getSettings().getInt("maxColonySize");
223 public static int OVER_MAX_INDUSTRIES_PENALTY = Global.getSettings().getInt("overMaxIndustriesPenalty");
224
225
226 public static float FP_TO_BOMBARD_COST_APPROX_MULT = 12f;
227 public static float FP_TO_GROUND_RAID_STR_APPROX_MULT = 6f;
228
229 public static String UNKNOWN = " ";
230 public static String UNSURVEYED = "??";
231 public static String PRELIMINARY = "?";
232 public static String FULL = "X";
233
237 public static String STORY = "story";
238
239 public static float MAX_OFFICER_LEVEL = Global.getSettings().getFloat("officerMaxLevel");
240
241 public static Random random = new Random();
242
243 public static enum TokenType {
244 VARIABLE,
245 LITERAL,
246 OPERATOR,
247 }
248
249 public static final Vector2f ZERO = new Vector2f(0, 0);
250
251 public static class VarAndMemory {
252 public String name;
253 public MemoryAPI memory;
254 }
255 public static class Token {
256 public String string;
257 public TokenType type;
258 public String varNameWithoutMemoryKeyIfKeyIsValid = null;
259 public String varMemoryKey = null;
260 public Token(String string, TokenType type) {
261 this.string = string;
262 this.type = type;
263
264 if (isVariable()) {
265 int index = string.indexOf(".");
266 if (index > 0 && index < string.length() - 1) {
267 varMemoryKey = string.substring(1, index);
268 varNameWithoutMemoryKeyIfKeyIsValid = "$" + string.substring(index + 1);
269 }
270 }
271 }
272
273 public VarAndMemory getVarNameAndMemory(Map<String, MemoryAPI> memoryMap) {
274 String varName = varNameWithoutMemoryKeyIfKeyIsValid;
275 MemoryAPI memory = memoryMap.get(varMemoryKey);
276 if (memory == null) {
277 varName = string;
278 memory = memoryMap.get(MemKeys.LOCAL);
279 }
280 if (memory == null) {
281 throw new RuleException("No memory found for keys: " + varMemoryKey + ", " + MemKeys.LOCAL);
282 }
283
284 VarAndMemory result = new VarAndMemory();
285 result.name = varName;
286 result.memory = memory;
287 return result;
288 }
289
290 public String getStringWithTokenReplacement(String ruleId, InteractionDialogAPI dialog, Map<String, MemoryAPI> memoryMap) {
291 String text = getString(memoryMap);
292 if (text == null) return null;
293 text = Global.getSector().getRules().performTokenReplacement(ruleId, text, dialog.getInteractionTarget(), memoryMap);
294// Map<String, String> tokens = Global.getSector().getRules().getTokenReplacements(ruleId, dialog.getInteractionTarget(), memoryMap);
295// for (String token : tokens.keySet()) {
296// String value = tokens.get(token);
297// text = text.replaceAll("(?s)\\" + token, value);
298// }
299// text = Misc.replaceTokensFromMemory(text, memoryMap);
300 return text;
301 }
302 public String getString(Map<String, MemoryAPI> memoryMap) {
303 String string = null;
304 if (isVariable()) {
305 VarAndMemory var = getVarNameAndMemory(memoryMap);
306 string = var.memory.getString(var.name);
307 } else {
308 string = this.string;
309 }
310 return string;
311 }
312
313 public Object getObject(Map<String, MemoryAPI> memoryMap) {
314 Object o = null;
315 if (isVariable()) {
316 VarAndMemory var = getVarNameAndMemory(memoryMap);
317 o = var.memory.get(var.name);
318 }
319 return o;
320 }
321
322 public boolean getBoolean(Map<String, MemoryAPI> memoryMap) {
323 String str = getString(memoryMap);
324 return Boolean.parseBoolean(str);
325 }
326
327 public boolean isBoolean(Map<String, MemoryAPI> memoryMap) {
328 String str = getString(memoryMap);
329 return str.toLowerCase().equals("true") || str.toLowerCase().equals("false");
330 }
331
332 public boolean isFloat(Map<String, MemoryAPI> memoryMap) {
333 String str = null;
334 if (isVariable()) {
335 VarAndMemory var = getVarNameAndMemory(memoryMap);
336 str = var.memory.getString(var.name);
337 } else {
338 str = string;
339 }
340 try {
341 Float.parseFloat(str);
342 return true;
343 } catch (NumberFormatException e) {
344 return false;
345 }
346 }
347
348 public float getFloat(Map<String, MemoryAPI> memoryMap) {
349 float result = 0f;
350 if (isVariable()) {
351 VarAndMemory var = getVarNameAndMemory(memoryMap);
352 result = var.memory.getFloat(var.name);
353 } else {
354 result = Float.parseFloat(string);
355 }
356 return result;
357 }
358
359 public int getInt(Map<String, MemoryAPI> memoryMap) {
360 return (int) Math.round(getFloat(memoryMap));
361 }
362
363 public Color getColor(Map<String, MemoryAPI> memoryMap) {
364 Object object = null;
365 if (isVariable()) {
366 VarAndMemory var = getVarNameAndMemory(memoryMap);
367 object = var.memory.get(var.name);
368 }
369 if (object instanceof Color) {
370 return (Color) object;
371 }
372
373 String string = getString(memoryMap);
374 try {
375 String [] parts = string.split(Pattern.quote(","));
376 return new Color(Integer.parseInt(parts[0]),
377 Integer.parseInt(parts[1]),
378 Integer.parseInt(parts[2]),
379 Integer.parseInt(parts[3]));
380 } catch (Exception e) {
381 if ("bad".equals(string)) {
382 string = "textEnemyColor";
383 } else if ("good".equals(string)) {
384 string = "textFriendColor";
385 } else if ("highlight".equals(string)) {
386 string = "buttonShortcut";
387 } else if ("h".equals(string)) {
388 string = "buttonShortcut";
389 } else if ("story".equals(string)) {
390 return Misc.getStoryOptionColor();
391 } else if ("gray".equals(string)) {
392 return Misc.getGrayColor();
393 } else if ("grey".equals(string)) {
394 return Misc.getGrayColor();
395 } else {
396 FactionAPI faction = Global.getSector().getFaction(string);
397 if (faction != null) {
398 return faction.getBaseUIColor();
399 }
400 }
401
402 return Global.getSettings().getColor(string);
403 }
404 }
405
406 public boolean isLiteral() {
407 return type == TokenType.LITERAL;
408 }
409 public boolean isVariable() {
410 return type == TokenType.VARIABLE;
411 }
412 public boolean isOperator() {
413 return type == TokenType.OPERATOR;
414 }
415 @Override
416 public String toString() {
417 if (isVariable()) {
418 return string + " (" + type.name() + ", memkey: " + varMemoryKey + ", name: " + varNameWithoutMemoryKeyIfKeyIsValid + ")";
419 } else {
420 return string + " (" + type.name() + ")";
421 }
422 }
423 }
424
425 public static List<Token> tokenize(String string) {
426 List<Token> result = new ArrayList<Token>();
427 boolean inQuote = false;
428 boolean inOperator = false;
429
430 StringBuffer currToken = new StringBuffer();
431 for (int i = 0; i < string.length(); i++) {
432 char curr = string.charAt(i);
433 char next = 0;
434 if (i + 1 < string.length()) next = string.charAt(i + 1);
435 boolean charEscaped = false;
436 if (curr == '\\') {
437 i++;
438 if (i >= string.length()) {
439 throw new RuleException("Escape character at end of string in: [" + string + "]");
440 }
441 curr = string.charAt(i);
442 if (i + 1 < string.length()) next = string.charAt(i + 1);
443 charEscaped = true;
444 }
445// if (charEscaped) {
446// System.out.println("dfsdfs");
447// }
448
449 if (curr == '"' && !charEscaped) {
450 inQuote = !inQuote;
451 if (!inQuote && currToken.length() <= 0) {
452 result.add(new Token("", TokenType.LITERAL));
453 } else if (currToken.length() > 0) {
454 String str = currToken.toString();
455 if (!inQuote) {
456 result.add(new Token(str, TokenType.LITERAL));
457 } else {
458 if (str.startsWith("$")) {
459 result.add(new Token(str, TokenType.VARIABLE));
460 } else if (inOperator) {
461 result.add(new Token(str, TokenType.OPERATOR));
462 } else {
463 result.add(new Token(str, TokenType.LITERAL));
464 }
465 }
466 }
467 inOperator = false;
468 currToken.delete(0, 1000000);
469 continue;
470 }
471
472 if (!inQuote && (curr == ' ' || curr == '\t')) {
473 if (currToken.length() > 0) {
474 String str = currToken.toString();
475 if (str.startsWith("$")) {
476 result.add(new Token(str, TokenType.VARIABLE));
477 } else if (inOperator) {
478 result.add(new Token(str, TokenType.OPERATOR));
479 } else {
480 result.add(new Token(str, TokenType.LITERAL));
481 }
482 }
483 inOperator = false;
484 currToken.delete(0, 1000000);
485 continue;
486 }
487
488 if (!inQuote && !inOperator && isOperatorChar(curr) && (curr != '-' || !isDigit(next))) {
489 if (currToken.length() > 0) {
490 String str = currToken.toString();
491 if (str.startsWith("$")) {
492 result.add(new Token(str, TokenType.VARIABLE));
493 } else {
494 result.add(new Token(str, TokenType.LITERAL));
495 }
496 }
497 currToken.delete(0, 1000000);
498 inOperator = true;
499 if (charEscaped && curr == 'n') {
500 currToken.append("\n");
501 } else {
502 currToken.append(curr);
503 }
504 continue;
505 }
506
507 if (!inQuote && inOperator && !isOperatorChar(curr)) {
508 if (currToken.length() > 0) {
509 String str = currToken.toString();
510 result.add(new Token(str, TokenType.OPERATOR));
511 }
512 currToken.delete(0, 1000000);
513 inOperator = false;
514 if (charEscaped && curr == 'n') {
515 currToken.append("\n");
516 } else {
517 currToken.append(curr);
518 }
519 continue;
520 }
521
522 if (charEscaped && curr == 'n') {
523 currToken.append("\n");
524 } else {
525 currToken.append(curr);
526 }
527 }
528
529 if (inQuote) {
530 throw new RuleException("Unmatched quotes in string: " + string + "]");
531 }
532
533 if (currToken.length() > 0) {
534 String str = currToken.toString();
535 if (str.startsWith("$")) {
536 result.add(new Token(str, TokenType.VARIABLE));
537 } else if (inOperator) {
538 result.add(new Token(str, TokenType.OPERATOR));
539 } else {
540 result.add(new Token(str, TokenType.LITERAL));
541 }
542 }
543
544 return result;
545 }
546
547
548 private static boolean isDigit(char c) {
549 if (c == 0) return false;
550 String digits = "1234567890";
551 return digits.contains("" + c);
552 }
553 private static boolean isOperatorChar(char c) {
554 String operatorChars = "=<>!+-";
555 return operatorChars.contains("" + c);
556 }
557
558
559 public static String ucFirst(String str) {
560 if (str == null) return "Null";
561 if (str.isEmpty()) return "";
562 return ("" + str.charAt(0)).toUpperCase() + str.substring(1);
563 }
564
565 public static String lcFirst(String str) {
566 if (str == null) return "Null";
567 if (str.isEmpty()) return "";
568 return ("" + str.charAt(0)).toLowerCase() + str.substring(1);
569 }
570
571
572 public static String replaceTokensFromMemory(String text, Map<String, MemoryAPI> memoryMap) {
573 List<String> keySet = new ArrayList<String>(memoryMap.keySet());
574 if (keySet.contains(MemKeys.LOCAL)) {
575 keySet.remove(MemKeys.LOCAL);
576 keySet.add(0, MemKeys.LOCAL);
577 }
578 for (String key : keySet) {
579 MemoryAPI memory = memoryMap.get(key);
580 List<String> keys = new ArrayList<String>(memory.getKeys());
581 Collections.sort(keys, new Comparator<String>() {
582 public int compare(String o1, String o2) {
583 return o2.length() - o1.length();
584 }
585 });
586 for (String token : keys) {
587 Object value = memory.get(token);
588 if (value == null) value = "null";
589 if (value instanceof String || value instanceof Boolean || value instanceof Float || value instanceof Integer) {
590 text = text.replaceAll("(?s)\\$" + Pattern.quote(key) + "\\." + Pattern.quote(token.substring(1)), value.toString());
591 text = text.replaceAll("(?s)\\$" + Pattern.quote(token.substring(1)), value.toString());
592 }
593 }
594 }
595 return text;
596 }
597
598
599 public static float getDistance(SectorEntityToken from, SectorEntityToken to) {
600 return getDistance(from.getLocation(), to.getLocation());
601 }
605
606
607 private static Vector2f temp3 = new Vector2f();
608 public static float getDistance(Vector2f v1, Vector2f v2) {
609 //return Vector2f.sub(v1, v2, temp3).length();
610 return (float) Math.sqrt((v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y));
611 }
612
613 public static float getDistanceSq(Vector2f v1, Vector2f v2) {
614 //return Vector2f.sub(v1, v2, temp3).lengthSquared();
615 return (v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y);
616 }
617
618 public static float getDistance(float x1, float y1, float x2, float y2) {
619// float xDiff = Math.abs(x1 - x2);
620// float yDiff = Math.abs(y1 - y2);
621// return (float) Math.sqrt(xDiff * xDiff + yDiff * yDiff);
622 return (float) Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
623
624 }
625
626 public static float getDistanceToPlayerLY(Vector2f locInHyper) {
627 if (Global.getSector().getPlayerFleet() == null) return 100000f;
629 }
630 public static float getDistanceToPlayerLY(SectorEntityToken other) {
631 if (Global.getSector().getPlayerFleet() == null) return 100000f;
633 }
634
635 public static float getDistanceLY(Vector2f v1, Vector2f v2) {
636 return Vector2f.sub(v1, v2, temp3).length() / getUnitsPerLightYear();
637 }
638
639 public static float getRounded(float in) {
640 if (in <= 10) return Math.max(1, (int) in);
641 float pow = (int) Math.log10(in);
642 float div = (float) Math.pow(10, Math.max(0, pow - 1));
643 if (pow == 1) div = 10;
644 return (int) Math.round(in / div) * div;
645 }
646
647 public static String getRoundedValue(float value) {
648 if (Math.abs((float)Math.round(value) - value) < 0.0001f) {
649 //if (value > 10 || value < -10) {
650 return String.format("%d", (int) Math.round(value));
651 //} else {
652 //return String.format("%.1f", value);
653 //}
654 } else if ((int) Math.round((value * 100f)) == (int) Math.round((value * 10f)) * 10) {
655 return (value > 10 || value < -10) ? "" + (int) Math.round(value) : String.format("%.1f", value);
656 } else {
657 return (value > 10 || value < -10) ? "" + (int) Math.round(value) : String.format("%.2f", value);
658 }
659 }
660
661 public static float getRoundedValueFloat(float value) {
662 if (Math.abs((float)Math.round(value) - value) < 0.0001f) {
663 return (int) Math.round(value);
664 } else if ((int) Math.round((value * 100f)) == (int) Math.round((value * 10f)) * 10) {
665 return (value > 10 || value < -10) ? (int) Math.round(value) :
666 (Math.round(value * 10f) / 10f);
667 } else {
668 return (value > 10 || value < -10) ? (int) Math.round(value) :
669 (Math.round(value * 100f) / 100f);
670 }
671 }
672
673 public static String getRoundedValueMaxOneAfterDecimal(float value) {
674 if (Math.abs((float)Math.round(value) - value) < 0.0001f) {
675 return String.format("%d", (int) Math.round(value));
676 } else if ((int) Math.round((value * 100f)) == (int) Math.round((value * 10f)) * 10) {
677 return (value >= 10 || value <= -10) ? "" + (int) Math.round(value) : String.format("%.1f", value);
678 } else {
679 return (value >= 10 || value <= -10) ? "" + (int) Math.round(value) : String.format("%.1f", value);
680 }
681 }
682
683 public static String getRoundedValueOneAfterDecimalIfNotWhole(float value) {
684 if (Math.abs((float)Math.round(value) - value) < 0.0001f) {
685 return String.format("%d", (int) Math.round(value));
686 } else {
687 return String.format("%.1f", value);
688 }
689 }
690
691
692
693 public static float logOfBase(float base, float num) {
694 return (float) (Math.log(num) / Math.log(base));
695 }
696
697 public static Vector2f getPointAtRadius(Vector2f from, float r) {
698 float angle = (float) ((float) Math.random() * Math.PI * 2f);
699 float x = (float) (Math.cos(angle) * r) + from.x;
700 float y = (float) (Math.sin(angle) * r) + from.y;
701 return new Vector2f(x, y);
702 }
703
704 public static Vector2f getPointAtRadius(Vector2f from, float r, Random random) {
705 float angle = (float) (random.nextFloat() * Math.PI * 2f);
706 float x = (float) (Math.cos(angle) * r) + from.x;
707 float y = (float) (Math.sin(angle) * r) + from.y;
708 return new Vector2f(x, y);
709 }
710
711 public static Vector2f getPointWithinRadius(Vector2f from, float r) {
712 return getPointWithinRadius(from, r, random);
713 }
714 public static Vector2f getPointWithinRadius(Vector2f from, float r, Random random) {
715 r = r * random.nextFloat();
716 float angle = (float) (random.nextFloat() * Math.PI * 2f);
717 float x = (float) (Math.cos(angle) * r) + from.x;
718 float y = (float) (Math.sin(angle) * r) + from.y;
719 return new Vector2f(x, y);
720 }
721
722 public static Vector2f getPointWithinRadiusUniform(Vector2f from, float r, Random random) {
723 r = (float) (r * Math.sqrt(random.nextFloat()));
724 float angle = (float) (random.nextFloat() * Math.PI * 2f);
725 float x = (float) (Math.cos(angle) * r) + from.x;
726 float y = (float) (Math.sin(angle) * r) + from.y;
727 return new Vector2f(x, y);
728 }
729
730 public static Vector2f getPointWithinRadiusUniform(Vector2f from, float minR, float maxR, Random random) {
731 float r = (float) (minR + (maxR - minR) * Math.sqrt(random.nextFloat()));
732 float angle = (float) (random.nextFloat() * Math.PI * 2f);
733 float x = (float) (Math.cos(angle) * r) + from.x;
734 float y = (float) (Math.sin(angle) * r) + from.y;
735 return new Vector2f(x, y);
736 }
737
738 public static float getSnapshotFPLost(CampaignFleetAPI fleet) {
739 float fp = fleet.getFleetPoints();
740 float before = 0;
741 for (FleetMemberAPI member : fleet.getFleetData().getSnapshot()) {
742 before += member.getFleetPointCost();
743 }
744
745 return before - fp;
746 }
747
748 public static List<FleetMemberAPI> getSnapshotMembersLost(CampaignFleetAPI fleet) {
749 List<FleetMemberAPI> lost = new ArrayList<FleetMemberAPI>();
750 List<FleetMemberAPI> curr = fleet.getFleetData().getMembersListCopy();
751 for (FleetMemberAPI member : fleet.getFleetData().getSnapshot()) {
752 if (!curr.contains(member)) {
753 lost.add(member);
754 }
755 }
756
757 return lost;
758 }
759
760
761 public static CampaignEventPlugin startEvent(CampaignEventTarget eventTarget, String eventId, Object params) {
763 CampaignEventPlugin event = manager.getOngoingEvent(eventTarget, eventId);
764 if (event == null) {
765 event = manager.startEvent(eventTarget, eventId, params);
766 }
767 return event;
768 }
769
770 public static Color getStoryDarkBrighterColor() {
771 return setAlpha(scaleColorOnly(getStoryOptionColor(), 0.65f), 255);
772 }
773 public static Color getStoryDarkColor() {
774 return setAlpha(scaleColorOnly(getStoryOptionColor(), 0.4f), 175);
775 }
776 public static Color getStoryBrightColor() {
777 Color bright = interpolateColor(getStoryOptionColor(),
778 setAlpha(Color.white, 255),
779 0.35f);
780 return bright;
781 }
782 public static Color getStoryOptionColor() {
783 //return Misc.interpolateColor(Misc.getButtonTextColor(), Misc.getPositiveHighlightColor(), 0.5f);
784 return Global.getSettings().getColor("storyOptionColor");
785 //return Global.getSettings().getColor("tooltipTitleAndLightHighlightColor");
786 }
787
788 public static Color getHighlightedOptionColor() {
789 return Global.getSettings().getColor("buttonShortcut");
790 }
791
792 public static Color getHighlightColor() {
793 return Global.getSettings().getColor("buttonShortcut");
794 }
795 public static Color getDarkHighlightColor() {
796 Color hc = Misc.getHighlightColor();
797 return Misc.setAlpha(hc, 255);
798 }
800 return Global.getSettings().getColor("tooltipTitleAndLightHighlightColor");
801 }
802 public static Color getNegativeHighlightColor() {
803 if (Global.getSettings().getBoolean("colorblindMode")) {
804 return new Color(0, 100, 255);
805 }
806 return Global.getSettings().getColor("textEnemyColor");
807 }
808
809 public static Color getBallisticMountColor() {
810 return Global.getSettings().getColor("mountYellowColor");
811 }
812 public static Color getMissileMountColor() {
813 return Global.getSettings().getColor("mountGreenColor");
814 }
815 public static Color getEnergyMountColor() {
816 if (Global.getSettings().getBoolean("colorblindMode")) {
817 return new Color(155,155,155,255);
818 }
819 return Global.getSettings().getColor("mountBlueColor");
820 }
821
822 public static Color getPositiveHighlightColor() {
823 return Global.getSettings().getColor("textFriendColor");
824 }
825
826 public static Color getGrayColor() {
827 return Global.getSettings().getColor("textGrayColor");
828 }
829
830 public static Color getBrightPlayerColor() {
832 }
833 public static Color getBasePlayerColor() {
835 }
836 public static Color getDarkPlayerColor() {
838 }
839 public static Color getTextColor() {
840 return Global.getSettings().getColor("standardTextColor");
841 }
842 public static Color getButtonTextColor() {
843 return Global.getSettings().getColor("buttonText");
844 }
845
846 public static float getUnitsPerLightYear() {
847 return Global.getSettings().getFloat("unitsPerLightYear");
848 }
849
850 public static float getProfitMarginFlat() {
851 return Global.getSettings().getFloat("profitMarginFlat");
852 }
853
854 public static float getProfitMarginMult() {
855 return Global.getSettings().getFloat("profitMarginMult");
856 }
857
858 public static float getEconomyInterval() {
859 return Global.getSettings().getFloat("economyIntervalnGameDays");
860 }
861
862 public static float getGenericRollingAverageFactor() {
863 return Global.getSettings().getFloat("genericRollingAverageFactor");
864 }
865
867 float interval = getEconomyInterval();
868 return new IntervalUtil(interval * 0.75f, interval * 1.25f);
869 }
870
871 public static String getAndJoined(List<String> strings) {
872 return getAndJoined(strings.toArray(new String [0]));
873 }
874
875 public static String getAndJoined(String ... strings) {
876 return getJoined("and", strings);
877 }
878
879 public static String getJoined(String joiner, List<String> strings) {
880 return getJoined(joiner, strings.toArray(new String [0]));
881 }
882 public static String getJoined(String joiner, String ... strings) {
883 if (strings.length == 1) return strings[0];
884
885 String result = "";
886 for (int i = 0; i < strings.length - 1; i++) {
887 result += strings[i] + ", ";
888 }
889 if (!result.isEmpty()) {
890 result = result.substring(0, result.length() - 2);
891 }
892 if (strings.length > 2) {
893 if (joiner.isEmpty()) {
894 result += ", " + strings[strings.length - 1];
895 } else {
896 result += ", " + joiner + " " + strings[strings.length - 1];
897 }
898 } else if (strings.length == 2) {
899 if (joiner.isEmpty()) {
900 result += ", " + strings[strings.length - 1];
901 } else {
902 result += " " + joiner + " " + strings[strings.length - 1];
903 }
904 }
905 return result;
906 }
907
908 public static interface FleetFilter {
909 boolean accept(CampaignFleetAPI curr);
910 }
911
912 public static List<CampaignFleetAPI> findNearbyFleets(SectorEntityToken from, float maxRange, FleetFilter filter) {
913 List<CampaignFleetAPI> result = new ArrayList<CampaignFleetAPI>();
914 for (CampaignFleetAPI fleet : from.getContainingLocation().getFleets()) {
915 if (fleet == from) continue;
916 float dist = Misc.getDistance(fleet.getLocation(), from.getLocation());
917 if (dist > maxRange) continue;
918
919 if (filter == null || filter.accept(fleet)) {
920 result.add(fleet);
921 }
922 }
923 return result;
924 }
925
926 public static List<CampaignFleetAPI> getFleetsInOrNearSystem(StarSystemAPI system) {
927 List<CampaignFleetAPI> result = new ArrayList<CampaignFleetAPI>(system.getFleets());
929 if (!fleet.isInOrNearSystem(system)) continue;
930 result.add(fleet);
931 }
932 return result;
933 }
934
935
936 public static List<MarketAPI> getMarketsInLocation(LocationAPI location, String factionId) {
937 List<MarketAPI> result = new ArrayList<MarketAPI>();
938 for (MarketAPI curr : getMarketsInLocation(location)) {
939 if (curr.getFactionId().equals(factionId)) {
940 result.add(curr);
941 }
942 }
943 return result;
944 }
945
947 int max = 0;
948 MarketAPI best = null;
949 for (MarketAPI curr : getMarketsInLocation(location)) {
950 int size = curr.getSize();
951 if (size > max || (size == max && curr.getFaction().isPlayerFaction())) {
952 max = size;
953 best = curr;
954 }
955 }
956 return best;
957 }
958
959
960 public static List<MarketAPI> getMarketsInLocation(LocationAPI location) {
961 if (location == null) return new ArrayList<MarketAPI>();
962 return Global.getSector().getEconomy().getMarkets(location);
963// List<MarketAPI> result = new ArrayList<MarketAPI>();
964// for (MarketAPI market : Global.getSector().getEconomy().getMarketsCopy()) {
965// if (market.getContainingLocation() != location) continue;
966// result.add(market);
967// }
968// return result;
969 }
970
971 public static List<MarketAPI> getFactionMarkets(FactionAPI faction, String econGroup) {
972 List<MarketAPI> result = new ArrayList<MarketAPI>();
973 for (MarketAPI market : Global.getSector().getEconomy().getMarketsInGroup(econGroup)) {
974 if (market.getFaction() == faction) {
975 result.add(market);
976 }
977 }
978 return result;
979 }
980 public static List<MarketAPI> getPlayerMarkets(boolean includeNonPlayerFaction) {
982 List<MarketAPI> result = new ArrayList<MarketAPI>();
983 for (MarketAPI market : Global.getSector().getEconomy().getMarketsCopy()) {
984 if (market.getFaction() == player) {
985 result.add(market);
986 } else if (includeNonPlayerFaction && market.isPlayerOwned()) {
987 result.add(market);
988 }
989 }
990 return result;
991 }
992
993 public static List<StarSystemAPI> getPlayerSystems(boolean includeNonPlayerFaction) {
994 return getSystemsWithPlayerColonies(includeNonPlayerFaction);
995 }
996 public static List<StarSystemAPI> getSystemsWithPlayerColonies(boolean includeNonPlayerFaction) {
997 List<MarketAPI> markets = Misc.getPlayerMarkets(includeNonPlayerFaction);
998 List<StarSystemAPI> systems = new ArrayList<StarSystemAPI>();
999 for (MarketAPI market : markets) {
1000 StarSystemAPI system = market.getStarSystem();
1001 if (system != null && !systems.contains(system)) {
1002 systems.add(system);
1003 }
1004 }
1005 return systems;
1006 }
1007
1008 public static List<MarketAPI> getFactionMarkets(String factionId) {
1009 return getFactionMarkets(Global.getSector().getFaction(factionId));
1010 }
1011 public static List<MarketAPI> getFactionMarkets(FactionAPI faction) {
1012 //Global.getSector().getEconomy().get
1013 List<MarketAPI> result = new ArrayList<MarketAPI>();
1014 for (MarketAPI market : Global.getSector().getEconomy().getMarketsCopy()) {
1015 if (market.getFaction() == faction) {
1016 result.add(market);
1017 }
1018 }
1019 return result;
1020 }
1021
1022 public static List<MarketAPI> getNearbyMarkets(Vector2f locInHyper, float distLY) {
1023 List<MarketAPI> result = new ArrayList<MarketAPI>();
1024 for (MarketAPI market : Global.getSector().getEconomy().getMarketsCopy()) {
1025 float dist = getDistanceLY(market.getLocationInHyperspace(), locInHyper);
1026 if (dist > distLY) continue;
1027 result.add(market);
1028 }
1029 return result;
1030 }
1031
1032 public static int getNumHostileMarkets(FactionAPI faction, SectorEntityToken from, float maxDist) {
1033 int hostileMarketsNearPoint = 0;
1035 SectorEntityToken primary = market.getPrimaryEntity();
1036 float dist = getDistance(primary.getLocation(), from.getLocation());
1037 if (dist > maxDist) continue;
1038 if (market.getFaction() != null && market.getFaction().isHostileTo(faction)) {
1039 hostileMarketsNearPoint ++;
1040 }
1041 }
1042 return hostileMarketsNearPoint;
1043 }
1044
1045 public static List<StarSystemAPI> getNearbyStarSystems(SectorEntityToken token, float maxRangeLY) {
1046 List<StarSystemAPI> result = new ArrayList<StarSystemAPI>();
1047
1048 for (StarSystemAPI system : Global.getSector().getStarSystems()) {
1049 float dist = Misc.getDistanceLY(token.getLocationInHyperspace(), system.getLocation());
1050 if (dist > maxRangeLY) continue;
1051 result.add(system);
1052 }
1053 return result;
1054 }
1055
1056 public static StarSystemAPI getNearbyStarSystem(SectorEntityToken token, float maxRangeLY) {
1057 if (token.getContainingLocation() instanceof StarSystemAPI) {
1058 return (StarSystemAPI) token.getContainingLocation();
1059 }
1060
1061 StarSystemAPI closest = null;
1062 float minDist = Float.MAX_VALUE;
1063 for (StarSystemAPI system : Global.getSector().getStarSystems()) {
1064 float dist = Misc.getDistanceLY(token.getLocationInHyperspace(), system.getLocation());
1065 if (dist > maxRangeLY) continue;
1066 if (dist < minDist) {
1067 minDist = dist;
1068 closest = system;
1069 }
1070 //return system;
1071 }
1072 return closest;
1073 }
1074
1076 if (token.getContainingLocation() instanceof StarSystemAPI) {
1077 return (StarSystemAPI) token.getContainingLocation();
1078 }
1079
1080 float minDist = Float.MAX_VALUE;
1081 StarSystemAPI closest = null;
1082 for (StarSystemAPI system : Global.getSector().getStarSystems()) {
1083 float dist = Misc.getDistanceLY(token.getLocationInHyperspace(), system.getLocation());
1084 if (dist < minDist) {
1085 minDist = dist;
1086 closest = system;
1087 }
1088 }
1089 return closest;
1090 }
1091
1093 if (token.getContainingLocation() instanceof StarSystemAPI) {
1094 return (StarSystemAPI) token.getContainingLocation();
1095 }
1096 for (StarSystemAPI system : Global.getSector().getStarSystems()) {
1097 if (token.isInOrNearSystem(system)) return system;
1098 }
1099 return null;
1100 }
1101
1102
1103 public static boolean showRuleDialog(SectorEntityToken entity, String initialTrigger) {
1105 if (initialTrigger != null) {
1106 plugin = new RuleBasedInteractionDialogPluginImpl(initialTrigger);
1107 } else {
1109 }
1110 return Global.getSector().getCampaignUI().showInteractionDialog(plugin, entity);
1111 }
1112
1113 public static float DEG_PER_RAD = 180f / 3.1415926f;
1114
1115 public static float getAngleInDegreesStrict(Vector2f v) {
1116 float angle = (float) Math.atan2(v.y, v.x) * DEG_PER_RAD;
1117 return angle;
1118 }
1119
1120 public static float getAngleInDegreesStrict(Vector2f from, Vector2f to) {
1121 float dx = to.x - from.x;
1122 float dy = to.y - from.y;
1123 float angle = (float) Math.atan2(dy, dx) * DEG_PER_RAD;
1124 return angle;
1125 }
1126 public static float getAngleInDegrees(Vector2f v) {
1128 }
1129
1130 public static float getAngleInDegrees(Vector2f from, Vector2f to) {
1131 return Global.getSettings().getAngleInDegreesFast(from, to);
1132 }
1133
1134 public static Vector2f normalise(Vector2f v) {
1135 if (v.lengthSquared() > Float.MIN_VALUE) {
1136 return (Vector2f)v.normalise();
1137 }
1138 //return v;
1139 return new Vector2f(1, 0);
1140 }
1141
1142 public static float normalizeAngle(float angleDeg) {
1143 return (angleDeg % 360f + 360f) % 360f;
1144 }
1145
1146 public static MarketAPI findNearestLocalMarket(SectorEntityToken token, float maxDist, MarketFilter filter) {
1147 List<MarketAPI> localMarkets = getMarketsInLocation(token.getContainingLocation());
1148 float distToLocalMarket = Float.MAX_VALUE;
1149 MarketAPI closest = null;
1150 for (MarketAPI market : localMarkets) {
1151 if (filter != null && !filter.acceptMarket(market)) continue;
1152
1153 if (market.getPrimaryEntity() == null) continue;
1154 if (market.getPrimaryEntity().getContainingLocation() != token.getContainingLocation()) continue;
1155
1156 float currDist = Misc.getDistance(market.getPrimaryEntity().getLocation(), token.getLocation());
1157 if (currDist > maxDist) continue;
1158 if (currDist < distToLocalMarket) {
1159 distToLocalMarket = currDist;
1160 closest = market;
1161 }
1162 }
1163 return closest;
1164 }
1165 public static List<MarketAPI> findNearbyLocalMarkets(SectorEntityToken token, float maxDist, MarketFilter filter) {
1166 List<MarketAPI> localMarkets = getMarketsInLocation(token.getContainingLocation());
1167 List<MarketAPI> result = new ArrayList<MarketAPI>();
1168
1169 for (MarketAPI market : localMarkets) {
1170 if (filter != null && !filter.acceptMarket(market)) continue;
1171 if (market.getPrimaryEntity() == null) continue;
1172 if (market.getPrimaryEntity().getContainingLocation() != token.getContainingLocation()) continue;
1173
1174 float currDist = Misc.getDistance(market.getPrimaryEntity().getLocation(), token.getLocation());
1175 if (currDist > maxDist) continue;
1176
1177 result.add(market);
1178
1179 }
1180 return result;
1181 }
1182
1183 public static MarketAPI findNearestLocalMarketWithSameFaction(final SectorEntityToken token, float maxDist) {
1184 return findNearestLocalMarket(token, maxDist, new MarketFilter() {
1185 public boolean acceptMarket(MarketAPI curr) {
1186 return curr.getFaction() == token.getFaction();
1187 }
1188 });
1189 }
1190
1191 public static Vector2f getUnitVector(Vector2f from, Vector2f to) {
1193 }
1194
1195 public static float RAD_PER_DEG = 0.01745329251f;
1196 public static Vector2f getUnitVectorAtDegreeAngle(float degrees) {
1197 Vector2f result = new Vector2f();
1198 float radians = degrees * RAD_PER_DEG;
1199 result.x = (float)Math.cos(radians);
1200 result.y = (float)Math.sin(radians);
1201
1202 return result;
1203 }
1204
1205 public static Vector2f rotateAroundOrigin(Vector2f v, float angle) {
1206 float cos = (float) Math.cos(angle * RAD_PER_DEG);
1207 float sin = (float) Math.sin(angle * RAD_PER_DEG);
1208 Vector2f r = new Vector2f();
1209 r.x = v.x * cos - v.y * sin;
1210 r.y = v.x * sin + v.y * cos;
1211 return r;
1212 }
1213
1214 public static Vector2f rotateAroundOrigin(Vector2f v, float angle, Vector2f origin) {
1215 float cos = (float) Math.cos(angle * RAD_PER_DEG);
1216 float sin = (float) Math.sin(angle * RAD_PER_DEG);
1217 Vector2f r = Vector2f.sub(v, origin, new Vector2f());
1218 Vector2f r2 = new Vector2f();
1219 r2.x = r.x * cos - r.y * sin;
1220 r2.y = r.x * sin + r.y * cos;
1221 Vector2f.add(r2, origin, r2);
1222 return r2;
1223 }
1224
1232 public static boolean isBetween(float one, float two, float check) {
1233 one = normalizeAngle(one);
1234 two = normalizeAngle(two);
1235 check = normalizeAngle(check);
1236
1237 //System.out.println(one + "," + two + "," + check);
1238 if (check >= one && check <= two) return true;
1239
1240 if (one > two) {
1241 if (check <= two) return true;
1242 if (check >= one) return true;
1243 }
1244 return false;
1245 }
1246
1247 public static float getShieldedCargoFraction(CampaignFleetAPI fleet) {
1248 float shielded = 0f;
1249 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
1250 if (member.isMothballed()) continue;
1251 if (member.getVariant().hasHullMod(HullMods.SHIELDED_CARGO_HOLDS)) {
1252 shielded += member.getCargoCapacity();
1253 }
1254 }
1255 float max = fleet.getCargo().getMaxCapacity();
1256 if (max < 1) return 0f;
1257 return shielded / max;
1258 }
1259
1260
1261 public static Color interpolateColor(Color from, Color to, float progress) {
1262 float red = (float)from.getRed() + ((float)to.getRed() - (float)from.getRed()) * progress;
1263 float green = (float)from.getGreen() + ((float)to.getGreen() - (float)from.getGreen()) * progress;
1264 float blue = (float)from.getBlue() + ((float)to.getBlue() - (float)from.getBlue()) * progress;
1265 float alpha = (float)from.getAlpha() + ((float)to.getAlpha() - (float)from.getAlpha()) * progress;
1266 red = Math.round(red);
1267 green = Math.round(green);
1268 blue = Math.round(blue);
1269 alpha = Math.round(alpha);
1270 return new Color((int)red, (int)green, (int)blue, (int)alpha);
1271 }
1272
1273 public static Color genColor(Color min, Color max, Random random) {
1274 Color color = new Color((int) (min.getRed() + (max.getRed() - min.getRed()) * random.nextDouble()),
1275 (int) (min.getGreen() + (max.getGreen() - min.getGreen()) * random.nextDouble()),
1276 (int) (min.getBlue() + (max.getBlue() - min.getBlue()) * random.nextDouble()),
1277 255);
1278
1279 return color;
1280 }
1281
1282 public static Vector2f interpolateVector(Vector2f from, Vector2f to, float progress) {
1283 Vector2f v = new Vector2f(from);
1284
1285 v.x += (to.x - from.x) * progress;
1286 v.y += (to.y - from.y) * progress;
1287
1288 return v;
1289 }
1290
1291 public static float interpolate(float from, float to, float progress) {
1292 to = from + (to - from) * progress;
1293 return to;
1294 }
1295
1296 public static Color scaleColor(Color color, float factor) {
1297 return new Color((int) (color.getRed() * factor),
1298 (int) (color.getGreen() * factor),
1299 (int) (color.getBlue() * factor),
1300 (int) (color.getAlpha() * factor));
1301 }
1302 public static Color scaleColorOnly(Color color, float factor) {
1303 return new Color((int) (color.getRed() * factor),
1304 (int) (color.getGreen() * factor),
1305 (int) (color.getBlue() * factor),
1306 (int) (color.getAlpha()));
1307 }
1308
1309 public static Color scaleAlpha(Color color, float factor) {
1310 return new Color((int) (color.getRed() * 1f),
1311 (int) (color.getGreen() * 1f),
1312 (int) (color.getBlue() * 1f),
1313 (int) (color.getAlpha() * factor));
1314 }
1315
1316 public static Color setAlpha(Color color, int alpha) {
1317 if (alpha < 0) alpha = 0;
1318 if (alpha > 255) alpha = 255;
1319 return new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha);
1320 }
1321
1322 public static float getSizeNum(HullSize size) {
1323 if (size == null) {
1324 return 1;
1325 }
1326 switch (size) {
1327 case CAPITAL_SHIP:
1328 return 5;
1329 case CRUISER:
1330 return 3;
1331 case DESTROYER:
1332 return 2;
1333 case FIGHTER:
1334 case FRIGATE:
1335 case DEFAULT:
1336 return 1;
1337 }
1338 return 1;
1339 }
1340
1341 public static void unsetAll(String prefix, String memKey, MemoryAPI memory) {
1342 Map<String, MemoryAPI> memoryMap = new HashMap<String, MemoryAPI>();
1343 memoryMap.put(memKey, memory);
1344 new unsetAll().execute(null, null, Misc.tokenize(prefix), memoryMap);
1345 }
1346
1347
1348
1349 public static float getTargetingRadius(Vector2f from, CombatEntityAPI target, boolean considerShield) {
1350 return Global.getSettings().getTargetingRadius(from, target, considerShield);
1351 }
1352
1353
1354 public static float getClosingSpeed(Vector2f p1, Vector2f p2, Vector2f v1, Vector2f v2) {
1355 // direction from target to shooter
1356 Vector2f dir = Vector2f.sub(p1, p2, new Vector2f());
1357 normalise(dir);
1358 // velocity of target relative to shooter
1359 Vector2f relVel = Vector2f.sub(v2, v1, new Vector2f());
1360 float closingSpeed = Vector2f.dot(dir, relVel);
1361 return closingSpeed;
1362 }
1363
1364
1365 protected static DecimalFormat format = null;
1366 public static DecimalFormat getFormat() {
1367 if (format == null) {
1368 DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.getDefault());
1369// symbols.setDecimalSeparator('.');
1370// symbols.setGroupingSeparator(',');
1371 format = new DecimalFormat("###,###,###,###,###", symbols);
1372 }
1373 return format;
1374 }
1375
1381 public static String getWithDGS(float num) {
1382 return getFormat().format(num);
1383 }
1384
1390 public static String getDGSCredits(float num) {
1391 return getFormat().format((int)num) + Strings.C;
1392 }
1393
1394
1395
1397 float dist = getDistance(from.getLocation(), to.getLocation()) - from.getRadius() - to.getRadius();
1398 if (dist <= 0) return new Vector2f(to.getLocation());
1399
1400 float closingSpeed = getClosingSpeed(from.getLocation(), to.getLocation(), from.getVelocity(), to.getVelocity());
1401 if (closingSpeed <= 10) return new Vector2f(to.getLocation());
1402
1403 Vector2f toTarget = getUnitVectorAtDegreeAngle(Misc.getAngleInDegrees(from.getLocation(), to.getLocation()));
1404 Vector2f vel = new Vector2f(from.getVelocity());
1405 normalise(vel);
1406 float dot = Vector2f.dot(toTarget, vel);
1407 if (dot < 0) return new Vector2f(to.getLocation());
1408// if (to.isPlayerFleet()) {
1409// System.out.println("23rwefe");
1410// }
1411 float time = dist / closingSpeed;
1412
1413 Vector2f point = new Vector2f(to.getVelocity());
1414 point.scale(time);
1415 Vector2f.add(point, to.getLocation(), point);
1416 return point;
1417 }
1418
1419
1420
1439 public static boolean setFlagWithReason(MemoryAPI memory, String flagKey, String reason, boolean value, float expire) {
1440 String requiredKey = flagKey + "_" + reason;
1441
1442 if (value) {
1443 memory.set(flagKey, true);
1444 memory.set(requiredKey, value, expire);
1445 memory.addRequired(flagKey, requiredKey);
1446 } else {
1447 memory.unset(requiredKey);
1448 }
1449
1450 return memory.contains(flagKey);
1451 }
1452
1453 public static boolean flagHasReason(MemoryAPI memory, String flagKey, String reason) {
1454 String requiredKey = flagKey + "_" + reason;
1455
1456 return memory.getBoolean(requiredKey);
1457 }
1458
1459 public static void clearFlag(MemoryAPI memory, String flagKey) {
1460 for (String req : memory.getRequired(flagKey)) {
1461 memory.unset(req);
1462 }
1463 }
1464
1465 public static void makeLowRepImpact(CampaignFleetAPI fleet, String reason) {
1467 }
1468 public static void makeNoRepImpact(CampaignFleetAPI fleet, String reason) {
1471 }
1472
1473 public static void makeHostile(CampaignFleetAPI fleet) {
1475 }
1476
1480
1484
1485 public static void makeNonHostileToFaction(CampaignFleetAPI fleet, String factionId, float dur) {
1486 makeNonHostileToFaction(fleet, factionId, true, dur);
1487 }
1488 public static void makeNonHostileToFaction(CampaignFleetAPI fleet, String factionId, boolean nonHostile, float dur) {
1489 String flag = MemFlags.MEMORY_KEY_MAKE_NON_HOSTILE + "_" + factionId;
1490 if (!nonHostile) {
1491 fleet.getMemoryWithoutUpdate().unset(flag);
1492 } else {
1493 fleet.getMemoryWithoutUpdate().set(flag, true, dur);
1494 }
1495 }
1496 public static void makeHostileToFaction(CampaignFleetAPI fleet, String factionId, float dur) {
1497 makeHostileToFaction(fleet, factionId, true, dur);
1498 }
1499 public static void makeHostileToFaction(CampaignFleetAPI fleet, String factionId, boolean hostile, float dur) {
1500 String flag = MemFlags.MEMORY_KEY_MAKE_HOSTILE + "_" + factionId;
1501 if (!hostile) {
1502 fleet.getMemoryWithoutUpdate().unset(flag);
1503 } else {
1504 fleet.getMemoryWithoutUpdate().set(flag, true, dur);
1505 }
1506 }
1507
1508 public static boolean isFleetMadeHostileToFaction(CampaignFleetAPI fleet, FactionAPI faction) {
1509 return isFleetMadeHostileToFaction(fleet, faction.getId());
1510 }
1511 public static boolean isFleetMadeHostileToFaction(CampaignFleetAPI fleet, String factionId) {
1512 if (Factions.PLAYER.equals(factionId) &&
1514 return true;
1515 }
1516 String flag = MemFlags.MEMORY_KEY_MAKE_HOSTILE + "_" + factionId;
1517 return fleet.getMemoryWithoutUpdate().getBoolean(flag);
1518 }
1519
1520 public static void makeNotLowRepImpact(CampaignFleetAPI fleet, String reason) {
1523 }
1524
1525
1526 public static String getAgoStringForTimestamp(long timestamp) {
1528 float days = clock.getElapsedDaysSince(timestamp);
1529
1530 if (days <= 1f) {
1531 return "Today";
1532 } else if (days <= 6f) {
1533 return (int)Math.ceil(days) + " days ago";
1534 } else if (days <= 7) {
1535 return "1 week ago";
1536 } else if (days <= 14) {
1537 return "2 weeks ago";
1538 } else if (days <= 21) {
1539 return "3 weeks ago";
1540 } else if (days <= 30 + 14) {
1541 return "1 month ago";
1542 } else if (days < 30 * 2 + 14) {
1543 return "2 months ago";
1544 } else if (days < 30 * 3 + 14) {
1545 return "3 months ago";
1546 } else {
1547 return "Over 3 months ago";
1548 }
1549 }
1550
1551 public static String getDetailedAgoString(long timestamp) {
1553 int days = (int) clock.getElapsedDaysSince(timestamp);
1554
1555 if (days == 0) {
1556 return "0 days ago";
1557 } else if (days == 1) {
1558 return "1 day ago";
1559 } else if (days <= 6) {
1560 return (int)Math.ceil(days) + " days ago";
1561 } else if (days <= 7) {
1562 return "1 week ago";
1563 } else if (days <= 14) {
1564 return "2 weeks ago";
1565 } else if (days <= 21) {
1566 return "3 weeks ago";
1567 } else {
1568 int months = days / 30;
1569 if (months <= 12) {
1570 if (months <= 1) {
1571 return "1 month ago";
1572 } else {
1573 return "" + months + " months ago";
1574 }
1575 } else {
1576 int years = months / 12;
1577 if (years <= 1) {
1578 return "1 cycle ago";
1579 } else {
1580 return "" + years + " cycles ago";
1581 }
1582 }
1583 }
1584 }
1585
1586 public static String getAtLeastStringForDays(int days) {
1587 if (days <= 1f) {
1588 return "at least a day";
1589 } else if (days <= 6f) {
1590 return "at least a few days";
1591 } else if (days <= 7 + 6) {
1592 return "at least a week";
1593 } else if (days <= 14 + 6) {
1594 return "at least two weeks";
1595 } else if (days <= 21 + 8) {
1596 return "at least three weeks";
1597 } else if (days <= 30 + 29) {
1598 return "at least a month";
1599 } else if (days < 30 * 2 + 29) {
1600 return "at least two months";
1601 } else if (days < 30 * 3 + 29) {
1602 return "at least three months";
1603 } else {
1604 return "many months";
1605 }
1606 }
1607
1608 public static String getStringForDays(int days) {
1609 if (days <= 1f) {
1610 return "a day";
1611 } else if (days <= 6f) {
1612 return "a few days";
1613 } else if (days <= 7 + 6) {
1614 return "a week";
1615 } else if (days <= 14 + 6) {
1616 return "two weeks";
1617 } else if (days <= 21 + 8) {
1618 return "three weeks";
1619 } else if (days <= 30 + 29) {
1620 return "a month";
1621 } else if (days < 30 * 2 + 29) {
1622 return "two months";
1623 } else if (days < 30 * 3 + 29) {
1624 return "three months";
1625 } else {
1626 return "many months";
1627 }
1628 }
1629
1630// public static String getTimeStringForDays(int days) {
1631// if (days <= 1f) {
1632// return "1 day";
1633// } else if (days <= 6f) {
1634// return "at least a few days";
1635// } else if (days <= 7) {
1636// return "at least a week";
1637// } else if (days <= 14) {
1638// return "at least 2 weeks";
1639// } else if (days <= 21) {
1640// return "at least 3 weeks";
1641// } else if (days <= 30 + 14) {
1642// return "at least a month";
1643// } else if (days < 30 * 2 + 14) {
1644// return "at least 2 months";
1645// } else if (days < 30 * 3 + 14) {
1646// return "at least 3 months";
1647// } else {
1648// return "many months";
1649// }
1650// }
1651
1652 public static float getBurnLevelForSpeed(float speed) {
1654 if (speed < 0 || speed <= Global.getSettings().getFloat("minTravelSpeed") + 1f) speed = 0;
1655 float currBurn = speed / Global.getSettings().getSpeedPerBurnLevel();
1656 // 1/1/20: changed to not add +0.01f; not sure why it was there but could cause issues w/ isSlowMoving(), maybe?
1657 //return Math.round(currBurn + 0.01f);
1658 return Math.round(currBurn);
1659 }
1660
1661 public static float getFractionalBurnLevelForSpeed(float speed) {
1662// System.out.println("Speed: " + Global.getSector().getPlayerFleet().getVelocity().length());
1663// System.out.println("Max: " + Global.getSector().getPlayerFleet().getTravelSpeed());
1665 if (speed < 0 || speed <= Global.getSettings().getFloat("minTravelSpeed") + 1f) speed = 0;
1666 float currBurn = speed / Global.getSettings().getSpeedPerBurnLevel();
1667 //System.out.println("ADFSDF: " +Math.round(currBurn));
1668 return currBurn;
1669 }
1670
1671 public static float getSpeedForBurnLevel(float burnLevel) {
1672 float speed = Global.getSettings().getBaseTravelSpeed() + burnLevel * Global.getSettings().getSpeedPerBurnLevel();
1673 return speed;
1674 }
1675
1676 public static float getFuelPerDay(CampaignFleetAPI fleet, float burnLevel) {
1677 float speed = Global.getSettings().getBaseTravelSpeed() + Global.getSettings().getSpeedPerBurnLevel() * burnLevel;
1678 return getFuelPerDayAtSpeed(fleet, speed);
1679 }
1680
1681 public static float getFuelPerDayAtSpeed(CampaignFleetAPI fleet, float speed) {
1682 float perLY = fleet.getLogistics().getFuelCostPerLightYear();
1683
1684 // this is potentially evil - currently, the velocity is in units per SECOND, not per day
1685 speed = speed * Global.getSector().getClock().getSecondsPerDay();
1686 // now, speed is in units per day
1687
1688 speed = speed / Global.getSettings().getUnitsPerLightYear();
1689 // ly/day now
1690
1691
1692 return speed * perLY;
1693 }
1694
1695 public static float getLYPerDayAtBurn(CampaignFleetAPI fleet, float burnLevel) {
1696 float speed = Global.getSettings().getBaseTravelSpeed() + Global.getSettings().getSpeedPerBurnLevel() * burnLevel;
1697 return getLYPerDayAtSpeed(fleet, speed);
1698 }
1699 public static float getLYPerDayAtSpeed(CampaignFleetAPI fleet, float speed) {
1700 // this is potentially evil - currently, the velocity is in units per SECOND, not per day
1701 speed = speed * Global.getSector().getClock().getSecondsPerDay();
1702 // now, speed is in units per day
1703 speed = speed / Global.getSettings().getUnitsPerLightYear();
1704 // ly/day now
1705
1706 return speed * 1f; // 1f days
1707 }
1708
1709 private static Vector3f temp4 = new Vector3f();
1710 public static Color zeroColor = new Color(0,0,0,0);
1711 public static float getDistance(Vector3f v1, Vector3f v2)
1712 {
1713 return Vector3f.sub(v1, v2, temp4).length();
1714 }
1715
1716 public static float getAngleDiff(float from, float to) {
1717 float diff = normalizeAngle(from - to);
1718 if (diff > 180) return 360 - diff;
1719 else return diff;
1720 }
1721
1722 public static boolean isInArc(float direction, float arc, Vector2f from, Vector2f to) {
1723 direction = normalizeAngle(direction);
1724 if (arc >= 360) return true;
1725 if (direction < 0) direction = 360 + direction;
1726 Vector2f towardsTo = new Vector2f(to.x - from.x, to.y - from.y);
1727 if (towardsTo.lengthSquared() == 0) return false;
1728 float dir = Misc.getAngleInDegrees(towardsTo);
1729 if (dir < 0) dir = 360 + dir;
1730 float arcFrom = direction - arc/2f;
1731 if (arcFrom < 0) arcFrom = 360 + arcFrom;
1732 if (arcFrom > 360) arcFrom -= 360;
1733 float arcTo = direction + arc/2f;
1734 if (arcTo < 0) arcTo = 360 + arcTo;
1735 if (arcTo > 360) arcTo -= 360;
1736
1737 if (dir >= arcFrom && dir <= arcTo) return true;
1738 if (dir >= arcFrom && arcFrom > arcTo) return true;
1739 if (dir <= arcTo && arcFrom > arcTo) return true;
1740 return false;
1741 }
1742
1743 public static boolean isInArc(float direction, float arc, float test) {
1744 test = normalizeAngle(test);
1745
1746 if (arc >= 360) return true;
1747 if (direction < 0) direction = 360 + direction;
1748 float dir = test;
1749 if (dir < 0) dir = 360 + dir;
1750 float arcFrom = direction - arc/2f;
1751 if (arcFrom < 0) arcFrom = 360 + arcFrom;
1752 if (arcFrom > 360) arcFrom -= 360;
1753 float arcTo = direction + arc/2f;
1754 if (arcTo < 0) arcTo = 360 + arcTo;
1755 if (arcTo > 360) arcTo -= 360;
1756
1757 if (dir >= arcFrom && dir <= arcTo) return true;
1758 if (dir >= arcFrom && arcFrom > arcTo) return true;
1759 if (dir <= arcTo && arcFrom > arcTo) return true;
1760 return false;
1761 }
1762
1763
1764 public static SectorEntityToken addNebulaFromPNG(String image, float centerX, float centerY, LocationAPI location,
1765 String category, String key, int tilesWide, int tilesHigh, StarAge age) {
1766 return addNebulaFromPNG(image, centerX, centerY, location, category, key, tilesWide, tilesHigh, Terrain.NEBULA, age);
1767 }
1768
1769
1770 public static SectorEntityToken addNebulaFromPNG(String image, float centerX, float centerY, LocationAPI location,
1771 String category, String key, int tilesWide, int tilesHigh,
1772 String terrainType, StarAge age) {
1773 try {
1774 BufferedImage img = null;
1775 //img = ImageIO.read(new File("../starfarer.res/res/data/campaign/terrain/nebula_test.png"));
1776 img = ImageIO.read(Global.getSettings().openStream(image));
1777
1778 int chunkSize = 10000;
1779 int w = img.getWidth();
1780 int h = img.getHeight();
1781 Raster data = img.getData();
1782 for (int i = 0; i < w; i += chunkSize) {
1783 for (int j = 0; j < h; j += chunkSize) {
1784
1785 int chunkWidth = chunkSize;
1786 if (i + chunkSize > w) chunkWidth = w - i;
1787 int chunkHeight = chunkSize;
1788 if (j + chunkSize > h) chunkHeight = h - i;
1789
1790// boolean hasAny = false;
1791// for (int x = i; x < i + chunkWidth; x++) {
1792// for (int y = j; y < j + chunkHeight; y++) {
1793// int [] pixel = data.getPixel(i, h - j - 1, (int []) null);
1794// int total = pixel[0] + pixel[1] + pixel[2];
1795// if (total > 0) {
1796// hasAny = true;
1797// break;
1798// }
1799// }
1800// }
1801// if (!hasAny) continue;
1802
1803 StringBuilder string = new StringBuilder();
1804 for (int y = j + chunkHeight - 1; y >= j; y--) {
1805 for (int x = i; x < i + chunkWidth; x++) {
1806 int [] pixel = data.getPixel(x, h - y - 1, (int []) null);
1807 int total = pixel[0] + pixel[1] + pixel[2];
1808 if (total > 0) {
1809 string.append("x");
1810 } else {
1811 string.append(" ");
1812 }
1813 }
1814 }
1815
1816 float tileSize = NebulaTerrainPlugin.TILE_SIZE;
1817 float x = centerX - tileSize * (float) w / 2f + (float) i * tileSize + chunkWidth / 2f * tileSize;
1818 float y = centerY - tileSize * (float) h / 2f + (float) j * tileSize + chunkHeight / 2f * tileSize;
1819
1820 SectorEntityToken curr = location.addTerrain(terrainType, new TileParams(string.toString(),
1821 chunkWidth, chunkHeight,
1822 category, key, tilesWide, tilesHigh, null));
1823 curr.getLocation().set(x, y);
1824
1825 if (location instanceof StarSystemAPI) {
1826 StarSystemAPI system = (StarSystemAPI) location;
1827
1828 system.setAge(age);
1829 system.setHasSystemwideNebula(true);
1830 }
1831
1832 return curr;
1833 }
1834 }
1835 return null;
1836 } catch (IOException e) {
1837 throw new RuntimeException(e);
1838 }
1839 }
1840
1841
1842 public static void renderQuad(float x, float y, float width, float height, Color color, float alphaMult) {
1843 GL11.glColor4ub((byte)color.getRed(),
1844 (byte)color.getGreen(),
1845 (byte)color.getBlue(),
1846 (byte)((float)color.getAlpha() * alphaMult));
1847
1848 GL11.glBegin(GL11.GL_QUADS);
1849 {
1850 GL11.glVertex2f(x, y);
1851 GL11.glVertex2f(x, y + height);
1852 GL11.glVertex2f(x + width, y + height);
1853 GL11.glVertex2f(x + width, y);
1854 }
1855 GL11.glEnd();
1856 }
1857
1865 public static float distanceFromLineToPoint(Vector2f p1, Vector2f p2, Vector2f p3) {
1866 float u = (p3.x - p1.x) * (p2.x - p1.x) + (p3.y - p1.y) * (p2.y - p1.y);
1867 float denom = Vector2f.sub(p2, p1, new Vector2f()).length();
1868 denom *= denom;
1869 //if (denom == 0) return 0;
1870 u /= denom;
1871 Vector2f i = new Vector2f();
1872 i.x = p1.x + u * (p2.x - p1.x);
1873 i.y = p1.y + u * (p2.y - p1.y);
1874 return Vector2f.sub(i, p3, new Vector2f()).length();
1875 }
1876
1877 public static Vector2f closestPointOnLineToPoint(Vector2f p1, Vector2f p2, Vector2f p3) {
1878 float u = (p3.x - p1.x) * (p2.x - p1.x) + (p3.y - p1.y) * (p2.y - p1.y);
1879 float denom = Vector2f.sub(p2, p1, new Vector2f()).length();
1880 denom *= denom;
1881 if (denom == 0) return p1;
1882 u /= denom;
1883 Vector2f i = new Vector2f();
1884 i.x = p1.x + u * (p2.x - p1.x);
1885 i.y = p1.y + u * (p2.y - p1.y);
1886 return i;
1887 }
1888
1889 public static Vector2f closestPointOnSegmentToPoint(Vector2f p1, Vector2f p2, Vector2f p3) {
1890 float u = (p3.x - p1.x) * (p2.x - p1.x) + (p3.y - p1.y) * (p2.y - p1.y);
1891 float denom = Vector2f.sub(p2, p1, new Vector2f()).length();
1892 denom *= denom;
1893
1894 u /= denom;
1895
1896 // if closest point on line is outside the segment, clamp to on the segment
1897 if (u < 0) u = 0;
1898 if (u > 1) u = 1;
1899
1900 Vector2f i = new Vector2f();
1901 i.x = p1.x + u * (p2.x - p1.x);
1902 i.y = p1.y + u * (p2.y - p1.y);
1903 return i;
1904 }
1905
1906 public static boolean isPointInBounds(Vector2f p1, List<Vector2f> bounds) {
1907 Vector2f p2 = new Vector2f(p1);
1908 p2.x += 10000;
1909 int count = 0;
1910 for (int i = 0; i < 2; i++) {
1911 for (int j = 0; j < bounds.size() - 1; j++) {
1912 Vector2f s1 = bounds.get(j);
1913 Vector2f s2 = bounds.get(j + 1);
1914 Vector2f p = intersectSegments(p1, p2, s1, s2);
1915 if (p != null) {
1916 if (Math.abs(p.x - s1.x) < 0.001f &&
1917 Math.abs(p.y - s1.y) < 0.001f) {
1918 continue; // JUST the first point, (p1, p2]
1919 }
1920 if (areSegmentsCoincident(p1, p2, s1, s2)) {
1921 continue;
1922 }
1923 count++;
1924 }
1925 }
1926 if (i == 0 && count % 2 == 1) {
1927 count = 0;
1928 p2.y += 100;
1929 } else {
1930 break;
1931 }
1932 }
1933 return count % 2 == 1;
1934 }
1935
1936 public static Vector2f intersectSegments(Vector2f a1, Vector2f a2, Vector2f b1, Vector2f b2) {
1937 float denom = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);
1938 float numUa = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x);
1939 float numUb = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x);
1940
1941 if (denom == 0 && !(numUa == 0 && numUb == 0)) { // parallel, not coincident
1942 return null;
1943 }
1944
1945 if (denom == 0 && numUa == 0 && numUb == 0) { // coincident
1946 float minX, minY, maxX, maxY;
1947 if (a1.x < a2.x) {
1948 minX = a1.x;
1949 maxX = a2.x;
1950 } else {
1951 minX = a2.x;
1952 maxX = a1.x;
1953 }
1954 if (a1.y < a2.y) {
1955 minY = a1.y;
1956 maxY = a2.y;
1957 } else {
1958 minY = a2.y;
1959 maxY = a1.y;
1960 }
1961 // if either one of the endpoints in segment b is between the points in segment a,
1962 // return that endpoint as the intersection. Otherwise, no intersection.
1963 if (b1.x >= minX && b1.x <= maxX && b1.y >= minY && b1.y <= maxY) {
1964 return new Vector2f(b1);
1965 } else if (b2.x >= minX && b2.x <= maxX && b2.y >= minY && b2.y <= maxY) {
1966 return new Vector2f(b2);
1967 } else {
1968 return null;
1969 }
1970 }
1971
1972 float Ua = numUa / denom;
1973 float Ub = numUb / denom;
1974 if (Ua >=0 && Ua <= 1 && Ub >= 0 && Ub <= 1) { // segments intersect
1975 Vector2f result = new Vector2f();
1976// if (Ua <= 0.001f) {
1977// result.x = a1.x;
1978// result.y = a1.y;
1979// } else if (Ua >= 0.999f) {
1980// result.x = a2.x;
1981// result.y = a2.y;
1982// } else {
1983 result.x = a1.x + Ua * (a2.x - a1.x);
1984 result.y = a1.y + Ua * (a2.y - a1.y);
1985// }
1986 return result;
1987 } else { // lines intersect, but segments do not
1988 return null;
1989 }
1990
1991 }
1992
1993
1994 public static Vector2f intersectLines(Vector2f a1, Vector2f a2, Vector2f b1, Vector2f b2) {
1995 float denom = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);
1996 float numUa = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x);
1997 float numUb = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x);
1998
1999 if (denom == 0 && !(numUa == 0 && numUb == 0)) { // parallel, not coincident
2000 return null;
2001 }
2002
2003 if (denom == 0 && numUa == 0 && numUb == 0) { // coincident
2004 return new Vector2f(a1);
2005 }
2006
2007 float Ua = numUa / denom;
2008 float Ub = numUb / denom;
2009 Vector2f result = new Vector2f();
2010 result.x = a1.x + Ua * (a2.x - a1.x);
2011 result.y = a1.y + Ua * (a2.y - a1.y);
2012 return result;
2013 }
2014
2015
2016
2017
2026 public static Vector2f intersectSegmentAndCircle(Vector2f p1, Vector2f p2, Vector2f p3, float r) {
2027
2028 float uNom = (p3.x - p1.x) * (p2.x - p1.x) + (p3.y - p1.y) * (p2.y - p1.y);
2029 float uDenom = (p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y);
2030
2031 Vector2f closest = new Vector2f();
2032 if (uDenom == 0) { // p1 and p2 are coincident
2033 closest.set(p1);
2034 } else {
2035 float u = uNom / uDenom;
2036 closest.x = p1.x + u * (p2.x - p1.x);
2037 closest.y = p1.y + u * (p2.y - p1.y);
2038 }
2039
2040 float distSq = (closest.x - p3.x) * (closest.x - p3.x) + (closest.y - p3.y) * (closest.y - p3.y);
2041 if (distSq > r * r) { // closest point is farther than radius
2042 //System.out.println("shorted");
2043 return null;
2044 } else if (uDenom == 0) {
2045 return closest; // in the case where p1==p2 and they're inside the circle, return p1.
2046 }
2047
2048 float a = (p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y);
2049 float b = 2f * ( (p2.x - p1.x) * (p1.x - p3.x) + (p2.y - p1.y) *
2050 (p1.y - p3.y) );
2051 float c = p3.x * p3.x + p3.y * p3.y + p1.x * p1.x + p1.y * p1.y - 2f
2052 * (p3.x * p1.x + p3.y * p1.y) - r * r;
2053
2054 float bb4ac = b * b - 4f * a * c;
2055
2056 if (bb4ac < 0) return null;
2057
2058 float mu1 = (-b + (float) Math.sqrt(bb4ac)) / (2 * a);
2059 float mu2 = (-b - (float) Math.sqrt(bb4ac)) / (2 * a);
2060
2061 float minMu = mu1;
2062 if ((mu2 < minMu && mu2 >= 0) || minMu < 0) minMu = mu2;
2063
2064 if (minMu < 0 || minMu > 1) {
2065 float p2DistSq = (p2.x - p3.x) * (p2.x - p3.x) + (p2.y - p3.y) * (p2.y - p3.y);
2066 if (p2DistSq <= r * r) return p2;
2067 else return null;
2068 }
2069 //System.out.println("mu1: " + mu1 + ", mu2: " + mu2);
2070
2071 Vector2f result = new Vector2f();
2072 result.x = p1.x + minMu * (p2.x - p1.x);
2073 result.y = p1.y + minMu * (p2.y - p1.y);
2074
2075 return result;
2076 }
2077
2078
2079 public static boolean areSegmentsCoincident(Vector2f a1, Vector2f a2, Vector2f b1, Vector2f b2) {
2080 float denom = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);
2081 float numUa = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x);
2082 float numUb = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) *(a1.x - b1.x);
2083
2084 if (denom == 0 && !(numUa == 0 && numUb == 0)) { // parallel, not coincident
2085 return false;
2086 }
2087
2088 if (denom == 0 && numUa == 0 && numUb == 0) { // coincident
2089 return true;
2090 }
2091
2092 return false;
2093 }
2094
2095 public static Vector2f getPerp(Vector2f v) {
2096 Vector2f perp = new Vector2f();
2097 perp.x = v.y;
2098 perp.y = -v.x;
2099 return perp;
2100 }
2101
2102 public static float getClosestTurnDirection(float facing, float desired) {
2103 float diff = Misc.normalizeAngle(desired) - Misc.normalizeAngle(facing);
2104 if (diff < 0) diff += 360;
2105
2106 if (diff == 0 || diff == 360f) {
2107 return 0f;
2108 } else if (diff > 180) {
2109 return -1f;
2110 } else {
2111 return 1f;
2112 }
2113// facing = normalizeAngle(facing);
2114// desired = normalizeAngle(desired);
2115// if (facing == desired) return 0;
2116//
2117// Vector2f desiredVec = getUnitVectorAtDegreeAngle(desired);
2118// //if (desiredVec.lengthSquared() == 0) return 0;
2119// Vector2f more = getUnitVectorAtDegreeAngle(facing + 1);
2120// Vector2f less = getUnitVectorAtDegreeAngle(facing - 1);
2121//
2122// float fromMore = Vector2f.angle(more, desiredVec);
2123// float fromLess = Vector2f.angle(less, desiredVec);
2124// if (fromMore > fromLess) return -1f;
2125// return 1f;
2126 }
2127
2128 public static float getClosestTurnDirection(float facing, Vector2f from, Vector2f to) {
2129 float diff = Misc.normalizeAngle(getAngleInDegrees(from, to)) - Misc.normalizeAngle(facing);
2130 if (diff < 0) diff += 360;
2131
2132 if (diff == 0 || diff == 360f) {
2133 return 0f;
2134 } else if (diff > 180) {
2135 return -1f;
2136 } else {
2137 return 1f;
2138 }
2139// Vector2f desired = getDiff(to, from);
2140// if (desired.lengthSquared() == 0) return 0;
2141// //float angle = getAngleInDegrees(desired);
2142// Vector2f more = getUnitVectorAtDegreeAngle(facing + 1);
2143// Vector2f less = getUnitVectorAtDegreeAngle(facing - 1);
2144//
2145// float fromMore = Vector2f.angle(more, desired);
2146// float fromLess = Vector2f.angle(less, desired);
2147// if (fromMore == fromLess) return 0f;
2148// if (fromMore > fromLess) return -1f;
2149// return 1f;
2150 }
2151
2152 public static float getClosestTurnDirection(Vector2f one, Vector2f two) {
2153 return getClosestTurnDirection(getAngleInDegrees(one), new Vector2f(0, 0), two);
2154 }
2155
2156 public static Vector2f getDiff(Vector2f v1, Vector2f v2)
2157 {
2158 //Vector2f result = new Vector2f();
2159 return Vector2f.sub(v1, v2, new Vector2f());
2160 }
2161
2164 if (id == null) return null;
2166 return market;
2167 }
2168
2171 if (id == null) return null;
2173 if (market != null && market.getPrimaryEntity() != null) {
2174 return market.getPrimaryEntity();
2175 }
2177 return entity;
2178 }
2179
2180 public static float getSpawnChanceMult(Vector2f locInHyper) {
2181 if (Global.getSector().getPlayerFleet() == null) return 1f;
2182
2183 float min = Global.getSettings().getFloat("minFleetSpawnChanceMult");
2184 float range = Global.getSettings().getFloat("minFleetSpawnChanceRangeLY");
2185
2186 Vector2f playerLoc = Global.getSector().getPlayerFleet().getLocationInHyperspace();
2187 float distLY = getDistanceLY(playerLoc, locInHyper);
2188
2189 float f = (1f - Math.min(1f, distLY/range));
2190 return min + (1f - min) * f * f;
2191 }
2192
2193 public static Vector2f pickHyperLocationNotNearPlayer(Vector2f from, float minDist) {
2195 float r = 2000f;
2196 if (player == null || !player.isInHyperspace()) {
2197 return getPointWithinRadius(from, r);
2198 }
2199 float dist = Misc.getDistance(player.getLocation(), from);
2200 if (dist > minDist + r) {
2201 return getPointWithinRadius(from, r);
2202 }
2203 float dir = Misc.getAngleInDegrees(player.getLocation(), from);
2204 Vector2f v = Misc.getUnitVectorAtDegreeAngle(dir);
2205 v.scale(minDist + 2000 - dist);
2206 Vector2f.add(v, from, v);
2207 return getPointWithinRadius(v, r);
2208 }
2209
2210 public static Vector2f pickLocationNotNearPlayer(LocationAPI where, Vector2f from, float minDist) {
2212 float r = 2000f;
2213 if (player == null || player.getContainingLocation() != where) {
2214 return getPointWithinRadius(from, r);
2215 }
2216 float dist = Misc.getDistance(player.getLocation(), from);
2217 if (dist > minDist + r) {
2218 return getPointWithinRadius(from, r);
2219 }
2220 float dir = Misc.getAngleInDegrees(player.getLocation(), from);
2221 Vector2f v = Misc.getUnitVectorAtDegreeAngle(dir);
2222 v.scale(minDist + 2000 - dist);
2223 Vector2f.add(v, from, v);
2224 return getPointWithinRadius(v, r);
2225 }
2226
2227 public static float getBattleJoinRange() {
2228 return Global.getSettings().getFloat("battleJoinRange");
2229 }
2230
2231 public static void wiggle(Vector2f v, float max) {
2232 v.x += (max * 2f * ((float) Math.random() - 0.5f));
2233 v.y += (max * 2f * ((float) Math.random() - 0.5f));
2234 if (v.length() == 0 || v.lengthSquared() == 0) {
2235 v.x += max * 0.25f;
2236 }
2237 }
2238
2239
2241 if (fleet.isPlayerFleet()) return true;
2242
2243 if (fleet.getBattle() != null && fleet.getBattle().isOnPlayerSide(fleet) &&
2244 fleet.getBattle().isPlayerPrimary()) {
2245 return true;
2246 }
2247 return false;
2248 }
2249
2251 if (fleet.isPlayerFleet()) return true;
2252
2253 if (fleet.getBattle() != null && fleet.getBattle().isOnPlayerSide(fleet)) {
2254 return true;
2255 }
2256 return false;
2257 }
2258
2259 public static final String ASTEROID_SOURCE = "misc_astrdSource";
2260
2262 if (asteroid.getCustomData().containsKey(ASTEROID_SOURCE)) {
2263 return (AsteroidSource) asteroid.getCustomData().get(ASTEROID_SOURCE);
2264 }
2265 return null;
2266 }
2267 public static void setAsteroidSource(SectorEntityToken asteroid, AsteroidSource source) {
2268 asteroid.getCustomData().put(ASTEROID_SOURCE, source);
2269 }
2270 public static void clearAsteroidSource(SectorEntityToken asteroid) {
2271 asteroid.getCustomData().remove(ASTEROID_SOURCE);
2272 }
2273
2274 public static boolean isFastStart() {
2275 return Global.getSector().getMemoryWithoutUpdate().getBoolean("$fastStart");
2276 }
2277 public static boolean isFastStartExplorer() {
2278 return Global.getSector().getMemoryWithoutUpdate().getBoolean("$fastStartExplorer");
2279 }
2280 public static boolean isFastStartMerc() {
2281 return Global.getSector().getMemoryWithoutUpdate().getBoolean("$fastStartMerc");
2282 }
2283
2284 public static boolean isEasy() {
2285 return Difficulties.EASY.equals(Global.getSector().getDifficulty());
2286 }
2287
2288 public static boolean isNormal() {
2290 }
2291
2292
2293// public static void main(String[] args) {
2294// System.out.println("TEST");
2295// String s = "te\\\"st==$global.one $player.a $>=$sdfdsf\"++++dfdsf0---\"\"quoted \\\"=+!<>param\" one two 1234 1 2342 24 \t\t234234";
2296// //String s = "menuState sdfsdf sdfsdf \"\"= \"main \\\" 1234\"";
2297// //s = "!sdfsdAKJKFHD";
2298// List<Token> result = tokenize(s);
2299// for (Token str : result) {
2300// System.out.println(str);
2301// }
2302 //addNebulaFromPNG();
2303// String s = "ffff0000";
2304// System.out.println(Long.parseLong(s, 16));
2305 //System.out.println(Long.parseLong("aa0F245C", 16));
2306// }
2307
2310 if (curr.getPlugin() instanceof HyperspaceTerrainPlugin) {
2311 return curr;
2312 }
2313 }
2314 return null;
2315 }
2318 if (hyper != null) {
2319 return (HyperspaceTerrainPlugin) hyper.getPlugin();
2320 }
2321 return null;
2322 }
2323
2324 public static boolean isInAbyss(Vector2f loc) {
2325 return getAbyssalDepth(loc) > 0;
2326 }
2327 public static boolean isInAbyss(SectorEntityToken entity) {
2328 return getAbyssalDepth(entity) > 0;
2329 }
2330 public static float getAbyssalDepth(Vector2f loc) {
2331 return getAbyssalDepth(loc, false);
2332 }
2333 public static float getAbyssalDepth(Vector2f loc, boolean uncapped) {
2335 if (plugin == null) return 0f;
2336 return plugin.getAbyssalDepth(loc, uncapped);
2337 }
2338
2339 public static List<StarSystemAPI> getAbyssalSystems() {
2341 if (plugin == null) return new ArrayList<StarSystemAPI>();
2342 return plugin.getAbyssalSystems();
2343 }
2344
2345 public static float getAbyssalDepthOfPlayer() {
2347 }
2348 public static float getAbyssalDepthOfPlayer(boolean uncapped) {
2349 return getAbyssalDepth(Global.getSector().getPlayerFleet(), uncapped);
2350 }
2351 public static float getAbyssalDepth(SectorEntityToken entity) {
2352 return getAbyssalDepth(entity, false);
2353 }
2354 public static float getAbyssalDepth(SectorEntityToken entity, boolean uncapped) {
2355 if (entity == null || !entity.isInHyperspace()) return 0f;
2356 return getAbyssalDepth(entity.getLocation());
2357 }
2358
2359 public static boolean isInsideBlackHole(CampaignFleetAPI fleet, boolean includeEventHorizon) {
2360 for (PlanetAPI planet : fleet.getContainingLocation().getPlanets()) {
2361 if (planet.isStar() && planet.getSpec() != null && planet.getSpec().isBlackHole()) {
2362 float dist = Misc.getDistance(fleet, planet);
2363 if (dist < planet.getRadius() + fleet.getRadius()) {
2364 return true;
2365 } else if (includeEventHorizon) {
2366 StarCoronaTerrainPlugin corona = getCoronaFor(planet);
2367 if (corona != null && corona.containsEntity(fleet)) {
2368 return true;
2369 }
2370 }
2371 }
2372 }
2373 return false;
2374 }
2375
2376
2378 if (star == null) return null;
2379
2381 if (curr.getPlugin() instanceof StarCoronaTerrainPlugin) {
2382 StarCoronaTerrainPlugin corona = (StarCoronaTerrainPlugin) curr.getPlugin();
2383 if (corona.getRelatedEntity() == star) return corona;
2384 }
2385 }
2386 return null;
2387 }
2388
2390 if (planet == null || planet.getContainingLocation() == null) return null;
2391
2393 if (curr.getPlugin() instanceof MagneticFieldTerrainPlugin) {
2394 MagneticFieldTerrainPlugin field = (MagneticFieldTerrainPlugin) curr.getPlugin();
2395 if (field.getRelatedEntity() == planet) return field;
2396 }
2397 }
2398 return null;
2399 }
2400
2403 if (curr.getPlugin() instanceof PulsarBeamTerrainPlugin) {
2404 PulsarBeamTerrainPlugin corona = (PulsarBeamTerrainPlugin) curr.getPlugin();
2405 if (corona.getRelatedEntity() == star) return corona;
2406 }
2407 }
2408 return null;
2409 }
2410
2411 public static boolean hasPulsar(StarSystemAPI system) {
2412 return system != null && system.hasPulsar();
2413// if (system.getStar() != null && system.getStar().getSpec().isPulsar()) return true;
2414// if (system.getSecondary() != null && system.getSecondary().getSpec().isPulsar()) return true;
2415// if (system.getTertiary() != null && system.getTertiary().getSpec().isPulsar()) return true;
2416// return false;
2417 }
2418
2419 public static String getCommissionFactionId() {
2421 return str;
2422 }
2423
2425 String id = getCommissionFactionId();
2426 if (id != null) {
2427 return Global.getSector().getFaction(id);
2428 }
2429 return null;
2430 }
2431
2434 if (obj instanceof FactionCommissionIntel) {
2435 return (FactionCommissionIntel) obj;
2436 }
2437 return null;
2438 }
2439
2440
2441 public static boolean caresAboutPlayerTransponder(CampaignFleetAPI fleet) {
2442// if (fleet.isInCurrentLocation()) {
2443// System.out.println("efwefew");
2444// }
2445 if (fleet.getFaction().isPlayerFaction()) return false;
2446
2447 boolean caresAboutTransponder = true;
2449 caresAboutTransponder = false;
2450 }
2451 MarketAPI source = Misc.getSourceMarket(fleet);
2452 if (source != null && source.hasCondition(Conditions.FREE_PORT)) {
2453 caresAboutTransponder = false;
2454 }
2455
2457 caresAboutTransponder = false;
2458 }
2459
2460 // prevents "infinitely chase player, re-interact, and don't demand anything or act hostile" scenario
2462 caresAboutTransponder = false;
2463 }
2464
2465 if (caresAboutTransponder && source != null && source.getPrimaryEntity() != null) {
2467 if (player == null || player.isInHyperspace()) {
2468 caresAboutTransponder = false;
2469 } else {
2470 caresAboutTransponder = source.getPrimaryEntity().getContainingLocation() == player.getContainingLocation();
2471// boolean alreadyTargetingPlayer = false;
2472// if (fleet.getAI() instanceof ModularFleetAIAPI) {
2473// ModularFleetAIAPI ai = (ModularFleetAIAPI) fleet.getAI();
2474// SectorEntityToken target = ai.getTacticalModule().getTarget();
2475// alreadyTargetingPlayer = target == player;
2476// }
2477// if (!alreadyTargetingPlayer) {
2480// float max = Global.getSettings().getFloat("maxTransponderRequiredRangeAroundMarketSystem");
2481// float dist = getDistanceLY(player.getLocationInHyperspace(), source.getLocationInHyperspace());
2482// if (dist > max) {
2483// caresAboutTransponder = false;
2484// }
2485// }
2486 }
2487 }
2488
2489 return caresAboutTransponder;
2490 }
2491
2492
2493 public static interface FindShipFilter {
2494 public boolean matches(ShipAPI ship);
2495 }
2496
2497 public static ShipAPI findClosestShipEnemyOf(ShipAPI ship, Vector2f locFromForSorting, HullSize smallestToNote, float maxRange, boolean considerShipRadius) {
2498 return findClosestShipEnemyOf(ship, locFromForSorting, smallestToNote, maxRange, considerShipRadius, null);
2499 }
2500 public static ShipAPI findClosestShipEnemyOf(ShipAPI ship, Vector2f locFromForSorting, HullSize smallestToNote, float maxRange, boolean considerShipRadius, FindShipFilter filter) {
2502 List<ShipAPI> ships = engine.getShips();
2503 float minDist = Float.MAX_VALUE;
2504 ShipAPI closest = null;
2505 for (ShipAPI other : ships) {
2506 if (other.getHullSize().ordinal() < smallestToNote.ordinal()) continue;
2507 if (other.isShuttlePod()) continue;
2508 if (other.isHulk()) continue;
2509 if (ship.getOwner() != other.getOwner() && other.getOwner() != 100) {
2510 if (filter != null && !filter.matches(other)) continue;
2511
2512 float dist = getDistance(ship.getLocation(), other.getLocation());
2513 float distSort = getDistance(locFromForSorting, other.getLocation());
2514 float radSum = ship.getCollisionRadius() + other.getCollisionRadius();
2515 if (!considerShipRadius) radSum = 0;
2516 if (dist > maxRange + radSum) continue;
2517 if (distSort < minDist) {
2518 closest = other;
2519 minDist = distSort;
2520 }
2521 }
2522 }
2523 return closest;
2524 }
2525
2526 public static ShipAPI findClosestShipTo(ShipAPI ship, Vector2f locFromForSorting, HullSize smallestToNote, float maxRange, boolean considerShipRadius, boolean allowHulks, FindShipFilter filter) {
2528 List<ShipAPI> ships = engine.getShips();
2529 float minDist = Float.MAX_VALUE;
2530 ShipAPI closest = null;
2531 for (ShipAPI other : ships) {
2532 if (other == ship) continue;
2533 if (other.getHullSize().ordinal() < smallestToNote.ordinal()) continue;
2534 if (other.isShuttlePod()) continue;
2535 if (other.isHulk()) continue;
2536 if (allowHulks || other.getOwner() != 100) {
2537 if (filter != null && !filter.matches(other)) continue;
2538
2539 float dist = getDistance(ship.getLocation(), other.getLocation());
2540 float distSort = getDistance(locFromForSorting, other.getLocation());
2541 float radSum = ship.getCollisionRadius() + other.getCollisionRadius();
2542 if (!considerShipRadius) radSum = 0;
2543 if (dist > maxRange + radSum) continue;
2544 if (distSort < minDist) {
2545 closest = other;
2546 minDist = distSort;
2547 }
2548 }
2549 }
2550 return closest;
2551 }
2552
2553
2554 public static <T extends Enum<T>> T mapToEnum(JSONObject json, String key, Class<T> enumType, T defaultOption) throws JSONException {
2555 return mapToEnum(json, key, enumType, defaultOption, true);
2556 }
2557 public static <T extends Enum<T>> T mapToEnum(JSONObject json, String key, Class<T> enumType, T defaultOption, boolean required) throws JSONException {
2558 String val = json.optString(key);
2559 if (val == null || val.equals("")) {
2560 if (defaultOption == null && required) {
2561 throw new RuntimeException("Key [" + key + "] is required");
2562 }
2563 return defaultOption;
2564 }
2565 try {
2566 return (T) Enum.valueOf(enumType, val);
2567 } catch (IllegalArgumentException e) {
2568 throw new RuntimeException("Key [" + key + "] has invalid value [" + val + "] in [" + json.toString() + "]");
2569 }
2570 }
2571
2572 public static Color getColor(JSONObject json, String key) throws JSONException {
2573 if (!json.has(key)) return Color.white;
2574 JSONArray arr = json.getJSONArray(key);
2575 return new Color(arr.getInt(0), arr.getInt(1), arr.getInt(2), arr.getInt(3));
2576 }
2577
2578 public static Color optColor(JSONObject json, String key, Color defaultValue) throws JSONException {
2579 if (!json.has(key)) return defaultValue;
2580 JSONArray arr = json.getJSONArray(key);
2581 return new Color(arr.getInt(0), arr.getInt(1), arr.getInt(2), arr.getInt(3));
2582 }
2583
2584 public static Vector2f getVector(JSONObject json, String arrayKey, Vector2f def) throws JSONException {
2585 if (!json.has(arrayKey)) return def;
2586 return getVector(json, arrayKey);
2587 }
2588 public static Vector2f getVector(JSONObject json, String arrayKey) throws JSONException {
2589 Vector2f v = new Vector2f();
2590 JSONArray arr = json.getJSONArray(arrayKey);
2591 v.set((float) arr.getDouble(0), (float) arr.getDouble(1));
2592 return v;
2593 }
2594
2595 public static Vector3f getVector3f(JSONObject json, String arrayKey) throws JSONException {
2596 Vector3f v = new Vector3f();
2597 JSONArray arr = json.getJSONArray(arrayKey);
2598 v.set((float) arr.getDouble(0), (float) arr.getDouble(1), (float) arr.getDouble(1));
2599 return v;
2600 }
2601
2602 public static Vector2f optVector(JSONObject json, String arrayKey) {
2603 Vector2f v = new Vector2f();
2604 JSONArray arr = json.optJSONArray(arrayKey);
2605 if (arr == null) return null;
2606 v.set((float) arr.optDouble(0), (float) arr.optDouble(1));
2607 return v;
2608 }
2609
2610 public static Vector3f optVector3f(JSONObject json, String arrayKey) throws JSONException {
2611 Vector3f v = new Vector3f();
2612 JSONArray arr = json.optJSONArray(arrayKey);
2613 if (arr == null) return new Vector3f();
2614 v.set((float) arr.getDouble(0), (float) arr.getDouble(1), (float) arr.getDouble(2));
2615 return v;
2616 }
2617
2618 public static Vector2f getVector(JSONObject json, String arrayKey, int index) throws JSONException {
2619 Vector2f v = new Vector2f();
2620 JSONArray arr = json.getJSONArray(arrayKey);
2621 v.set((float) arr.getDouble(index * 2 + 0), (float) arr.getDouble(index * 2 + 1));
2622 return v;
2623 }
2624
2625 public static void normalizeNoise(float[][] noise) {
2626 float minNoise = 1;
2627 float maxNoise = 0;
2628 for (int i = 0; i < noise.length; i++) {
2629 for (int j = 0; j < noise[0].length; j++) {
2630 if (noise[i][j] != -1) {
2631 if (noise[i][j] > maxNoise)
2632 maxNoise = noise[i][j];
2633 if (noise[i][j] < minNoise)
2634 minNoise = noise[i][j];
2635 }
2636 }
2637 }
2638
2639 if (minNoise >= maxNoise) return;
2640
2641 float range = maxNoise - minNoise;
2642
2643 for (int i = 0; i < noise.length; i++) {
2644 for (int j = 0; j < noise[0].length; j++) {
2645 if (noise[i][j] != -1) {
2646 float newNoise = (noise[i][j] - minNoise) / range;
2647 noise[i][j] = newNoise;
2648 } else {
2649 if (i > 0)
2650 noise[i][j] = noise[i - 1][j];
2651 else if (i < noise.length - 1)
2652 noise[i][j] = noise[i + 1][j];
2653 else
2654 noise[i][j] = .5f;
2655 }
2656 }
2657 }
2658 }
2659
2660 public static float [][] initNoise(Random random, int w, int h, float spikes) {
2661 if (random == null) random = Misc.random;
2662 float [][] noise = new float [w][h];
2663 for (int i = 0; i < noise.length; i++) {
2664 for (int j = 0; j < noise[0].length; j++) {
2665 noise[i][j] = -1f;
2666 }
2667 }
2668 noise[0][0] = random.nextFloat() * spikes;
2669 noise[0][noise[0].length - 1] = random.nextFloat() * spikes;
2670 noise[noise.length - 1][0] = random.nextFloat() * spikes;
2671 noise[noise.length - 1][noise[0].length - 1] = random.nextFloat() * spikes;
2672 return noise;
2673 }
2674
2675 public static void genFractalNoise(Random random, float[][] noise, int x1, int y1,
2676 int x2, int y2, int iter, float spikes) {
2677 if (x1 + 1 >= x2 || y1 + 1 >= y2) return; // no more values to fill
2678
2679 int midX = (x1 + x2) / 2;
2680 int midY = (y1 + y2) / 2;
2681
2682 fill(random, noise, midX, y1, x1, y1, x2, y1, iter, spikes);
2683 fill(random, noise, midX, y2, x1, y2, x2, y2, iter, spikes);
2684 fill(random, noise, x1, midY, x1, y1, x1, y2, iter, spikes);
2685 fill(random, noise, x2, midY, x2, y1, x2, y2, iter, spikes);
2686
2687 // averaging 4 neighboring values
2688 fill(random, noise, midX, midY, midX, y1, midX, y2, iter, spikes);
2689 float midValue1 = noise[midX][midY];
2690 fill(random, noise, midX, midY, x1, midY, x2, midY, iter, spikes);
2691 float midValue2 = noise[midX][midY];
2692 noise[midX][midY] = (midValue1 + midValue2)/2f;
2693
2694 genFractalNoise(random, noise, x1, y1, midX, midY, iter + 1, spikes);
2695 genFractalNoise(random, noise, x1, midY, midX, y2, iter + 1, spikes);
2696 genFractalNoise(random, noise, midX, y1, x2, midY, iter + 1, spikes);
2697 genFractalNoise(random, noise, midX, midY, x2, y2, iter + 1, spikes);
2698 }
2699
2700 private static void fill(Random random, float[][] noise, int x, int y, int x1, int y1,
2701 int x2, int y2, int iter, float spikes) {
2702 if (noise[x][y] == -1) {
2703 float avg = (noise[x1][y1] + noise[x2][y2]) / 2f;
2704 noise[x][y] = avg + ((float) Math.pow(spikes, (iter)) * (float) (random.nextFloat() - .5));
2705 }
2706 }
2707
2708
2709 public static float computeAngleSpan(float radius, float range) {
2710 if (range <= 1) return 180f;
2711 return (2f * radius) / (2f * (float) Math.PI * range) * 360f;
2712 }
2713
2714 public static float computeAngleRadius(float angle, float range) {
2715 float rad = (float) Math.toRadians(angle);
2716 return rad * range;
2717 }
2718
2719 public static float approach(float curr, float dest, float minSpeed, float diffSpeedMult, float amount) {
2720 float diff = dest - curr;
2721 float delta = (Math.signum(diff) * minSpeed + (diff * diffSpeedMult)) * amount;
2722
2723 if (Math.abs(delta) > Math.abs(diff)) delta = diff;
2724 return curr + delta;
2725 }
2726
2727 public static Map<Class, Method> cleanerCache = new LinkedHashMap<>();
2728 public static Map<Class, Method> cleanCache = new LinkedHashMap<>();
2729
2730 public static void cleanBuffer(Buffer toBeDestroyed) {
2731 try {
2732
2733 Method cleanerMethod = cleanerCache.get(toBeDestroyed.getClass());
2734 if (cleanerMethod == null) {
2735 cleanerMethod = toBeDestroyed.getClass().getMethod("cleaner");
2736 if (cleanerMethod != null) {
2737 cleanerMethod.setAccessible(true);
2738 cleanerCache.put(toBeDestroyed.getClass(), cleanerMethod);
2739 }
2740 }
2741 if (cleanerMethod != null) {
2742 Object cleaner = cleanerMethod.invoke(toBeDestroyed);
2743 if (cleaner != null) {
2744 Method cleanMethod = cleanCache.get(cleaner.getClass());
2745 if (cleanMethod == null) {
2746 cleanMethod = cleaner.getClass().getMethod("clean");
2747 if (cleanMethod != null) {
2748 cleanMethod.setAccessible(true);
2749 cleanCache.put(cleaner.getClass(), cleanMethod);
2750 }
2751 }
2752 if (cleanMethod != null) {
2753 cleanMethod.invoke(cleaner);
2754 Global.getLogger(Misc.class).info(String.format("Cleaned buffer (using reflection)"));
2755 } else {
2756 Global.getLogger(Misc.class).warn(String.format("Buffer can not be cleaned"));
2757 }
2758 } else {
2759 Global.getLogger(Misc.class).warn(String.format("Buffer can not be cleaned"));
2760 }
2761 } else {
2762 Global.getLogger(Misc.class).warn(String.format("Buffer can not be cleaned"));
2763 }
2764 } catch (Exception e) {
2765 Global.getLogger(Misc.class).warn(e.getMessage(), e);
2766 }
2767 }
2768
2769
2770 public static float getFleetwideTotalStat(CampaignFleetAPI fleet, String dynamicMemberStatId) {
2771 float total = 0;
2772 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
2773 if (member.isMothballed()) continue;
2774 total += member.getStats().getDynamic().getValue(dynamicMemberStatId);
2775 }
2776 return total;
2777 }
2778
2779 public static float getFleetwideTotalMod(CampaignFleetAPI fleet, String dynamicMemberStatId, float base) {
2780 return getFleetwideTotalMod(fleet, dynamicMemberStatId, base, null);
2781 }
2782 public static float getFleetwideTotalMod(CampaignFleetAPI fleet, String dynamicMemberStatId, float base, ShipAPI ship) {
2783 float total = 0;
2784 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
2785 if (member.isMothballed()) continue;
2786 if (ship != null && ship.getFleetMember() == member) {
2787 total += ship.getMutableStats().getDynamic().getValue(dynamicMemberStatId, base);
2788 } else {
2789 total += member.getStats().getDynamic().getValue(dynamicMemberStatId, base);
2790 }
2791 }
2792 return total;
2793 }
2794
2795 public static String getStarId(PlanetAPI planet) {
2796 String starId = planet.getContainingLocation().getId();
2797 if (planet.getContainingLocation() instanceof StarSystemAPI) {
2799 if (system.getStar() != null) {
2800 starId = system.getStar().getId();
2801 }
2802 }
2803 if (planet.getOrbitFocus() instanceof PlanetAPI) {
2804 PlanetAPI parent = (PlanetAPI) planet.getOrbitFocus();
2805 if (parent.isStar()) {
2806 starId = parent.getId();
2807 } else {
2808 if (parent.getOrbitFocus() instanceof PlanetAPI) {
2809 parent = (PlanetAPI) parent.getOrbitFocus();
2810 if (parent.isStar()) {
2811 starId = parent.getId();
2812 }
2813 }
2814 }
2815 }
2816 return starId;
2817 }
2818
2819
2820// public static enum PlanetDataForSystem {
2821// NONE,
2822// SEEN,
2823// PRELIMINARY,
2824// //PARTIAL,
2825// FULL,
2826// }
2827
2828 public static SurveyLevel getMinSystemSurveyLevel(StarSystemAPI system) {
2829 //boolean some = false, all = true;
2830 SurveyLevel minLevel = SurveyLevel.FULL;
2831 boolean empty = true;
2832 for (PlanetAPI planet : system.getPlanets()) {
2833 if (planet.isStar()) continue;
2834 MarketAPI market = planet.getMarket();
2835 if (market == null) continue;
2836
2837 empty = false;
2838 SurveyLevel level = market.getSurveyLevel();
2839 if (level.ordinal() < minLevel.ordinal()) {
2840 minLevel = level;
2841 }
2842 }
2843
2844 if (!system.isEnteredByPlayer() && empty) minLevel = SurveyLevel.NONE;
2845 if (system.isEnteredByPlayer() && empty) minLevel = SurveyLevel.FULL;
2846
2847 return minLevel;
2848
2849
2850// if (all && system.isEnteredByPlayer()) return PlanetDataForSystem.FULL;
2851// if (some) return PlanetDataForSystem.PARTIAL;
2852// return PlanetDataForSystem.NONE;
2853 }
2854
2855 public static boolean hasAnySurveyDataFor(StarSystemAPI system) {
2856 for (PlanetAPI planet : system.getPlanets()) {
2857 if (planet.isStar()) continue;
2858 MarketAPI market = planet.getMarket();
2859 if (market == null) continue;
2860
2861 SurveyLevel level = market.getSurveyLevel();
2862 if (level != SurveyLevel.NONE) return true;
2863 }
2864 return false;
2865 }
2866
2867
2868
2869 public static void setAllPlanetsKnown(String systemName) {
2870 StarSystemAPI system = Global.getSector().getStarSystem(systemName);
2871 if (system != null) {
2872 setAllPlanetsKnown(system);
2873 } else {
2874 throw new RuntimeException("Star system [" + systemName + "] not found");
2875 }
2876 }
2877
2878 public static void setAllPlanetsKnown(StarSystemAPI system) {
2879 for (PlanetAPI planet : system.getPlanets()) {
2880 if (planet.isStar()) continue;
2881
2882 MarketAPI market = planet.getMarket();
2883 if (market == null) continue;
2884 if (!market.isPlanetConditionMarketOnly()) {
2885 market.setSurveyLevel(SurveyLevel.FULL);
2886 } else if (market.getSurveyLevel() == SurveyLevel.NONE) {
2887 market.setSurveyLevel(SurveyLevel.SEEN);
2888 }
2889 }
2890 }
2891
2892 public static void setAllPlanetsSurveyed(StarSystemAPI system, boolean setRuinsExplored) {
2893 for (PlanetAPI planet : system.getPlanets()) {
2894 if (planet.isStar()) continue;
2895
2896 MarketAPI market = planet.getMarket();
2897 if (market == null) continue;
2898
2899 market.setSurveyLevel(SurveyLevel.FULL);
2900 for (MarketConditionAPI mc : market.getConditions()) {
2901 mc.setSurveyed(true);
2902 }
2903
2904 if (setRuinsExplored && Misc.hasRuins(market)) {
2905 market.getMemoryWithoutUpdate().set("$ruinsExplored", true);
2906 }
2907 }
2908 }
2909
2910 public static void generatePlanetConditions(String systemName, StarAge age) {
2911 StarSystemAPI system = Global.getSector().getStarSystem(systemName);
2912 if (system != null) {
2913 generatePlanetConditions(system, age);
2914 } else {
2915 throw new RuntimeException("Star system [" + systemName + "] not found");
2916 }
2917 }
2918
2919 public static void generatePlanetConditions(StarSystemAPI system, StarAge age) {
2920 for (PlanetAPI planet : system.getPlanets()) {
2921 if (planet.isStar()) continue;
2922
2923 if (planet.getMarket() != null && !planet.getMarket().getConditions().isEmpty()) continue;
2924
2926 }
2927 }
2928
2929
2930 public static int getEstimatedOrbitIndex(PlanetAPI planet) {
2931 Vector2f centerLoc = new Vector2f();
2932 float centerRadius = 0;
2933
2934// if (planet.getId().toLowerCase().equals("asharu")) {
2935// System.out.println("sdfwefe");
2936// }
2937
2938 float planetRadius = planet.getRadius();
2939 PlanetAPI parent = null;
2940 PlanetAPI parentParent = null;
2941 if (planet.getOrbitFocus() instanceof PlanetAPI) {
2942 parent = (PlanetAPI) planet.getOrbitFocus();
2943 if (parent.getOrbitFocus() instanceof PlanetAPI) {
2944 parentParent = (PlanetAPI) parent.getOrbitFocus();
2945 }
2946 if (parent.isStar()) {
2947 centerLoc = parent.getLocation();
2948 centerRadius = parent.getRadius();
2949 } else if (parentParent != null && parentParent.isStar()) {
2950 centerLoc = parentParent.getLocation();
2951 centerRadius = parentParent.getRadius();
2952 planetRadius = parent.getRadius();
2953 }
2954 }
2955
2956 float approximateExtraRadiusPerOrbit = 400f;
2957
2958 float dist = Misc.getDistance(centerLoc, planet.getLocation());
2959 int orbitIndex = (int) ((dist - centerRadius - planetRadius -
2961 (StarSystemGenerator.BASE_INCR * 1.25f + approximateExtraRadiusPerOrbit));
2962 if (orbitIndex == 0) {
2963 orbitIndex = (int) ((dist - centerRadius - planetRadius -
2965 (StarSystemGenerator.BASE_INCR * 1.25f));
2966 }
2967 if (orbitIndex < 0) orbitIndex = 0;
2968
2969 return orbitIndex;
2970 }
2971
2972
2973 public static Random getRandom(long seed, int level) {
2974 if (seed == 0) return random;
2975
2976 Random r = new Random(seed);
2977 for (int i = 0; i < level; i++) {
2978 r.nextLong();
2979 }
2980 return new Random(r.nextLong());
2981 }
2982
2983
2984 public static void addSurveyDataFor(PlanetAPI planet, TextPanelAPI text) {
2986 plugin.init(Global.getSector().getPlayerFleet(), planet);
2987
2988 String dataType = plugin.getSurveyDataType(planet);
2989 if (dataType != null) {
2991 if (text != null) {
2992 AddRemoveCommodity.addCommodityGainText(dataType, 1, text);
2993 }
2994 }
2995
2996 if (planet.getSpec().hasTag(Tags.CODEX_UNLOCKABLE)) {
2998 }
2999
3001 }
3002
3003 public static void setFullySurveyed(MarketAPI market, TextPanelAPI text, boolean withNotification) {
3004 //if (true) return;
3005
3006 for (MarketConditionAPI mc : market.getConditions()) {
3007 mc.setSurveyed(true);
3008 }
3009 market.setSurveyLevel(SurveyLevel.FULL);
3010
3011 if (withNotification && market.getPrimaryEntity() instanceof PlanetAPI) {
3012 PlanetAPI planet = (PlanetAPI) market.getPrimaryEntity();
3013 String string = "Acquired full survey data for " + planet.getName() + ", " + planet.getTypeNameWithWorld().toLowerCase();
3014 if (text != null) {
3015 text.setFontSmallInsignia();
3016 text.addParagraph(string, planet.getSpec().getIconColor());
3017 text.setFontInsignia();
3018 } else {
3019 //Global.getSector().getCampaignUI().addMessage(string, planet.getSpec().getIconColor());
3020
3021 MessageIntel intel = new MessageIntel("Full survey data: " + planet.getName() + ", " + planet.getTypeNameWithWorld(),
3022 Misc.getBasePlayerColor());//, new String[] {"" + points}, Misc.getHighlightColor());
3023 intel.setIcon(Global.getSettings().getSpriteName("intel", "new_planet_info"));
3024 Global.getSector().getCampaignUI().addMessage(intel, MessageClickAction.INTEL_TAB, planet);
3025
3026// CommMessageAPI message = Global.getFactory().createMessage();
3027// message.setSubject(string);
3028// //message.setSubjectColor(planet.getSpec().getIconColor());
3029// message.setAction(MessageClickAction.INTEL_TAB);
3030// message.setCustomData(planet);
3031// message.setAddToIntelTab(false);
3032// message.setSmallIcon(Global.getSettings().getSpriteName("intel_categories", "star_systems"));
3033// Global.getSector().getCampaignUI().addMessage(message);
3034 }
3035 }
3036 }
3037
3038 public static void setPreliminarySurveyed(MarketAPI market, TextPanelAPI text, boolean withNotification) {
3039 market.setSurveyLevel(SurveyLevel.PRELIMINARY);
3040
3041 if (withNotification && market.getPrimaryEntity() instanceof PlanetAPI) {
3042 PlanetAPI planet = (PlanetAPI) market.getPrimaryEntity();
3043 String string = "Acquired preliminary survey data for " + planet.getName() + ", " + planet.getTypeNameWithWorld().toLowerCase();
3044 if (text != null) {
3045 text.setFontSmallInsignia();
3046 text.addParagraph(string, planet.getSpec().getIconColor());
3047 text.setFontInsignia();
3048 } else {
3049 //Global.getSector().getCampaignUI().addMessage(string, planet.getSpec().getIconColor());
3050
3051 MessageIntel intel = new MessageIntel("Preliminary survey data: " + planet.getName() + ", " + planet.getTypeNameWithWorld(),
3052 Misc.getBasePlayerColor());//, new String[] {"" + points}, Misc.getHighlightColor());
3053 intel.setIcon(Global.getSettings().getSpriteName("intel", "new_planet_info"));
3054 Global.getSector().getCampaignUI().addMessage(intel, MessageClickAction.INTEL_TAB, planet);
3055
3056// CommMessageAPI message = Global.getFactory().createMessage();
3057// message.setSubject(string);
3058// //message.setSubjectColor(planet.getSpec().getIconColor());
3059// message.setAction(MessageClickAction.INTEL_TAB);
3060// message.setCustomData(planet);
3061// message.setAddToIntelTab(false);
3062// message.setSmallIcon(Global.getSettings().getSpriteName("intel_categories", "star_systems"));
3063// Global.getSector().getCampaignUI().addMessage(message);
3064 //Global.getSector().getCampaignUI().addMessage(string, planet.getSpec().getIconColor());
3065 }
3066 }
3067 }
3068
3069 public static void setSeen(MarketAPI market, TextPanelAPI text, boolean withNotification) {
3070 market.setSurveyLevel(SurveyLevel.SEEN);
3071
3072 if (withNotification && market.getPrimaryEntity() instanceof PlanetAPI) {
3073 PlanetAPI planet = (PlanetAPI) market.getPrimaryEntity();
3074 //String string = "Acquired preliminary survey data for " + planet.getName() + ", " + planet.getTypeNameWithWorld().toLowerCase();
3075 String type = planet.getSpec().getName();
3076 if (!planet.isGasGiant()) type += " World";
3077 String string = "New planet data: " + planet.getName() + ", " + type;
3078 if (text != null) {
3079 text.setFontSmallInsignia();
3080 text.addParagraph(string, planet.getSpec().getIconColor());
3081 text.setFontInsignia();
3082 } else {
3083
3084 MessageIntel intel = new MessageIntel(string,
3085 Misc.getBasePlayerColor());//, new String[] {"" + points}, Misc.getHighlightColor());
3086 intel.setIcon(Global.getSettings().getSpriteName("intel", "new_planet_info"));
3087 Global.getSector().getCampaignUI().addMessage(intel, MessageClickAction.INTEL_TAB, planet);
3088
3089// CommMessageAPI message = Global.getFactory().createMessage();
3090// message.setSubject(string);
3091// message.setSubjectColor(planet.getSpec().getIconColor());
3092// message.setAction(MessageClickAction.INTEL_TAB);
3093// message.setCustomData(planet);
3094// message.setAddToIntelTab(false);
3095// message.setSmallIcon(Global.getSettings().getSpriteName("intel_categories", "star_systems"));
3096// Global.getSector().getCampaignUI().addMessage(message);
3097 //Global.getSector().getCampaignUI().addMessage(string, planet.getSpec().getIconColor());
3098 }
3099 }
3100 }
3101
3102
3103
3104 public static String getStringWithTokenReplacement(String format, SectorEntityToken entity, Map<String, MemoryAPI> memoryMap) {
3106 null, format,
3107 entity, memoryMap);
3108 }
3109
3110
3111 public static void renderQuadAlpha(float x, float y, float width, float height, Color color, float alphaMult) {
3112
3113 GL11.glDisable(GL11.GL_TEXTURE_2D);
3114 GL11.glEnable(GL11.GL_BLEND);
3115 GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ZERO);
3116
3117 GL11.glColor4ub((byte)color.getRed(),
3118 (byte)color.getGreen(),
3119 (byte)color.getBlue(),
3120 (byte)(color.getAlpha() * alphaMult));
3121
3122 GL11.glBegin(GL11.GL_QUADS);
3123 {
3124 GL11.glVertex2f(x, y);
3125 GL11.glVertex2f(x, y + height);
3126 GL11.glVertex2f(x + width, y + height);
3127 GL11.glVertex2f(x + width, y);
3128 }
3129 GL11.glEnd();
3130 }
3131
3132
3133 public static void fadeAndExpire(SectorEntityToken entity) {
3134 fadeAndExpire(entity, 1f);
3135 }
3136 public static void fadeAndExpire(final SectorEntityToken entity, final float seconds) {
3137 if (entity.hasTag(Tags.FADING_OUT_AND_EXPIRING)) return;
3138
3139 entity.addTag(Tags.NON_CLICKABLE);
3141 //entity.getContainingLocation().addScript(new EveryFrameScript() {
3142 entity.addScript(new EveryFrameScript() {
3143 float elapsed = 0f;
3144 public boolean runWhilePaused() {
3145 return false;
3146 }
3147 public boolean isDone() {
3148 return entity.isExpired();
3149 }
3150 public void advance(float amount) {
3151 elapsed += amount;
3152 if (elapsed > seconds) {
3153 entity.setExpired(true);
3154 }
3155 float b = 1f - elapsed / seconds;
3156 if (b < 0) b = 0;
3157 if (b > 1) b = 1;
3158 entity.forceSensorFaderBrightness(Math.min(entity.getSensorFaderBrightness(), b));
3160 }
3161 });
3162 }
3163 public static void fadeInOutAndExpire(final SectorEntityToken entity, final float in, final float dur, final float out) {
3164 entity.addTag(Tags.NON_CLICKABLE);
3165 entity.forceSensorFaderBrightness(0f);
3167 //entity.getContainingLocation().addScript(new EveryFrameScript() {
3168 entity.addScript(new EveryFrameScript() {
3169 float elapsed = 0f;
3170 public boolean runWhilePaused() {
3171 return false;
3172 }
3173 public boolean isDone() {
3174 return entity.isExpired();
3175 }
3176 public void advance(float amount) {
3177 elapsed += amount;
3178 if (elapsed > in + dur + out) {
3179 entity.setExpired(true);
3180 }
3181 float b = 1f;
3182 if (elapsed < in) {
3183 b = elapsed / in;
3184 } else if (elapsed > in + dur) {
3185 b = 1f - (elapsed - in - dur) / out;
3186 }
3187 if (b < 0) b = 0;
3188 if (b > 1) b = 1;
3189 entity.forceSensorFaderBrightness(Math.min(entity.getSensorFaderBrightness(), b));
3191 }
3192 });
3193 }
3194
3195 public static void fadeIn(final SectorEntityToken entity, final float in) {
3196 entity.forceSensorFaderBrightness(0f);
3198 entity.addScript(new EveryFrameScript() {
3199 float elapsed = 0f;
3200 public boolean runWhilePaused() {
3201 return false;
3202 }
3203 public boolean isDone() {
3204 return elapsed > in;
3205 }
3206 public void advance(float amount) {
3207 elapsed += amount;
3208 if (elapsed > in) {
3210 return;
3211 }
3212 float b = elapsed / in;
3213 if (b < 0) b = 0;
3214 if (b > 1) b = 1;
3215 entity.forceSensorFaderBrightness(Math.min(entity.getSensorFaderBrightness(), b));
3217 }
3218 });
3219 }
3220// public static void fadeSensorContactAndExpire(final SectorEntityToken entity, final float seconds) {
3221// entity.addTag(Tags.NON_CLICKABLE);
3222// entity.addTag(Tags.FADING_OUT_AND_EXPIRING);
3223// //entity.getContainingLocation().addScript(new EveryFrameScript() {
3224// entity.addScript(new EveryFrameScript() {
3225// float elapsed = 0f;
3226// public boolean runWhilePaused() {
3227// return false;
3228// }
3229// public boolean isDone() {
3230// return entity.isExpired();
3231// }
3232// public void advance(float amount) {
3233// elapsed += amount;
3234// if (elapsed > seconds) {
3235// entity.setExpired(true);
3236// }
3237// float b = 1f - elapsed / seconds;
3238// if (b < 0) b = 0;
3239// if (b > 1) b = 1;
3240// entity.forceSensorContactFaderBrightness(Math.min(entity.getSensorContactFaderBrightness(), b));
3241// }
3242// });
3243// }
3244
3245 public static CustomCampaignEntityAPI addCargoPods(LocationAPI where, Vector2f loc) {
3247 pods.getLocation().x = loc.x;
3248 pods.getLocation().y = loc.y;
3249
3250 Vector2f vel = Misc.getUnitVectorAtDegreeAngle((float) Math.random() * 360f);
3251 vel.scale(5f + 10f * (float) Math.random());
3252 pods.getVelocity().set(vel);
3253
3254 pods.setDiscoverable(null);
3255 pods.setDiscoveryXP(null);
3256 pods.setSensorProfile(1f);
3257
3258 return pods;
3259 }
3260
3261
3262 public static SectorEntityToken addDebrisField(LocationAPI loc, DebrisFieldParams params, Random random) {
3263 if (random == null) random = Misc.random;
3264 SectorEntityToken debris = loc.addTerrain(Terrain.DEBRIS_FIELD, params);
3265 debris.setSensorProfile(1f);
3266 debris.setDiscoverable(true);
3267 debris.setName(((CampaignTerrainAPI)debris).getPlugin().getTerrainName());
3268
3269// float range = 300f + params.bandWidthInEngine * 5;
3270// if (range > 2000) range = 2000;
3271// debris.getDetectedRangeMod().modifyFlat("gen", range);
3272
3273 float range = DebrisFieldTerrainPlugin.computeDetectionRange(params.bandWidthInEngine);
3274 debris.getDetectedRangeMod().modifyFlat("gen", range);
3275
3277
3278 // add some default salvage
3279 // most uses of this will want to clear that out and add something more specific
3280 DropData data = new DropData();
3281 data.group = Drops.BASIC;
3282 data.value = (int) ((1000 + params.bandWidthInEngine) * 5);
3283 debris.addDropValue(data);
3284
3285 debris.setDiscoveryXP((float)((int)(params.bandWidthInEngine * 0.2f)));
3286 if (params.baseSalvageXP <= 0) {
3287 debris.setSalvageXP((float)((int)(params.bandWidthInEngine * 0.6f)));
3288 }
3289
3290 return debris;
3291 }
3292
3293 public static boolean isUnboardable(FleetMemberAPI member) {
3294 if (member.getVariant() != null && member.getVariant().hasTag(Tags.VARIANT_UNBOARDABLE)) {
3295 return true;
3296 }
3297 return isUnboardable(member.getHullSpec());
3298 }
3299
3300 public static boolean isUnboardable(ShipHullSpecAPI hullSpec) {
3301 if (hullSpec.getHints().contains(ShipTypeHints.UNBOARDABLE)) {
3302 for (String tag : getAllowedRecoveryTags()) {
3303 if (hullSpec.hasTag(tag)) return false;
3304 }
3305 if (hullSpec.isDefaultDHull()) {
3306 ShipHullSpecAPI parent = hullSpec.getDParentHull();
3307 for (String tag : getAllowedRecoveryTags()) {
3308 if (parent.hasTag(tag)) return false;
3309 }
3310 }
3311 return true;
3312 }
3313 return false;
3314 }
3315
3316
3317 public static boolean isShipRecoverable(FleetMemberAPI member, CampaignFleetAPI recoverer, boolean own, boolean useOfficerRecovery, float chanceMult) {
3318 //Random rand = new Random(1000000 * (member.getId().hashCode() + seed + Global.getSector().getClock().getDay()));
3319 //Random rand = new Random(1000000 * (member.getId().hashCode() + Global.getSector().getClock().getDay()));
3320 if (own) {
3321 if (!member.getVariant().getSMods().isEmpty()) {
3322 return true;
3323 }
3324 if (!member.getVariant().getSModdedBuiltIns().isEmpty()) {
3325 return true;
3326 }
3327 if (member.getCaptain() != null && !member.getCaptain().isDefault()) {
3328 return true;
3329 }
3330 }
3332 return true;
3333 }
3334 Random rand = new Random(1000000 * member.getId().hashCode() + Global.getSector().getPlayerBattleSeed());
3335 //rand = new Random();
3336 float chance = Global.getSettings().getFloat("baseShipRecoveryChance");
3337 if (own) {
3338 chance = Global.getSettings().getFloat("baseOwnShipRecoveryChance");
3339 }
3341 if (recoverer != null) {
3342 chance = recoverer.getStats().getDynamic().getMod(Stats.SHIP_RECOVERY_MOD).computeEffective(chance);
3343 if (useOfficerRecovery) {
3345 }
3346 }
3347 chance *= chanceMult;
3348
3349 if (chance < 0) chance = 0;
3350 if (chance > 1f) chance = 1f;
3351 boolean recoverable = rand.nextFloat() < chance;
3352
3353// System.out.println("Recovery for " + member.getHullSpec().getHullId() +
3354// "(" + member.getId().hashCode() + "): " + chance + " (" + recoverable + ")");
3355 return recoverable;
3356 }
3357
3358// public static float computeDetectionRangeForEntity(float radius) {
3359// float range = 300f + radius * 5f;
3360// if (range > 2000) range = 2000;
3361// return radius;
3362// }
3363
3364
3365
3367 return findNearestJumpPointTo(entity, false);
3368 }
3369 public static JumpPointAPI findNearestJumpPointTo(SectorEntityToken entity, boolean allowWormhole) {
3370 float min = Float.MAX_VALUE;
3371 JumpPointAPI result = null;
3372 List<JumpPointAPI> points = entity.getContainingLocation().getEntities(JumpPointAPI.class);
3373
3374 for (JumpPointAPI curr : points) {
3375 if (!allowWormhole && curr.isWormhole()) continue;
3376 if (curr.getMemoryWithoutUpdate().getBoolean(JumpPointInteractionDialogPluginImpl.UNSTABLE_KEY)) {
3377 continue;
3378 }
3379 float dist = Misc.getDistance(entity.getLocation(), curr.getLocation());
3380 if (dist < min) {
3381 min = dist;
3382 result = curr;
3383 }
3384 }
3385 return result;
3386 }
3387
3389 float min = Float.MAX_VALUE;
3390 JumpPointAPI result = null;
3391 List<JumpPointAPI> points = entity.getContainingLocation().getEntities(JumpPointAPI.class);
3392
3393 for (JumpPointAPI curr : points) {
3394 if (curr.isGasGiantAnchor() || curr.isStarAnchor()) continue;
3395 float dist = Misc.getDistance(entity.getLocation(), curr.getLocation());
3396 if (dist < min) {
3397 min = dist;
3398 result = curr;
3399 }
3400 }
3401 return result;
3402 }
3403
3404 public static SectorEntityToken findNearestPlanetTo(SectorEntityToken entity, boolean requireGasGiant, boolean allowStars) {
3405 float min = Float.MAX_VALUE;
3406 SectorEntityToken result = null;
3407 List<PlanetAPI> planets = entity.getContainingLocation().getPlanets();
3408
3409 for (PlanetAPI curr : planets) {
3410 if (requireGasGiant && !curr.isGasGiant()) continue;
3411 if (!allowStars && curr.isStar()) continue;
3412 float dist = Misc.getDistance(entity.getLocation(), curr.getLocation());
3413 if (dist < min) {
3414 min = dist;
3415 result = curr;
3416 }
3417 }
3418 return result;
3419 }
3420
3421
3422
3423 public static final boolean shouldConvertFromStub(LocationAPI containingLocation, Vector2f location) {
3424 //if (true) return false;
3425 if (Global.getSector().getPlayerFleet() == null) return false;
3426
3427// if (containingLocation == null ||
3428// containingLocation != Global.getSector().getPlayerFleet().getContainingLocation()) return false;
3429
3430 Vector2f stubLocInHyper = null;
3431 if (containingLocation == null || containingLocation.isHyperspace()) {
3432 stubLocInHyper = location;
3433 } else {
3434 stubLocInHyper = containingLocation.getLocation();
3435 }
3436
3437 Vector2f playerLoc = Global.getSector().getPlayerFleet().getLocationInHyperspace();
3438
3439 boolean sameLoc = containingLocation != null &&
3440 Global.getSector().getPlayerFleet().getContainingLocation() == containingLocation;
3441
3442 float maxDist = 6000;
3443 if (!sameLoc) maxDist = 3000;
3444
3445 float dist = Misc.getDistance(playerLoc, stubLocInHyper);
3446 return dist < maxDist;
3447 }
3448
3449// public static final boolean shouldConvertFromStub(FleetStubAPI stub) {
3450// if (Global.getSector().getPlayerFleet() == null) return false;
3451//
3452// return shouldConvertFromStub(stub.getContainingLocation(), stub.getLocation());
3453// }
3454//
3455//
3456// public static final boolean shouldConvertToStub(CampaignFleetAPI fleet) {
3457// if (fleet.getStub() == null || !fleet.isConvertToStub()) return false;
3458//
3459// if (Global.getSector().getPlayerFleet() == null) return true;
3460//
3461// Vector2f fleetLocInHyper = fleet.getLocationInHyperspace();
3462// Vector2f playerLoc = Global.getSector().getPlayerFleet().getLocationInHyperspace();
3463//
3464// boolean sameLoc = fleet.getContainingLocation() != null &&
3465// Global.getSector().getPlayerFleet().getContainingLocation() == fleet.getContainingLocation();
3466//
3467// float maxDist = 8000;
3468// if (!sameLoc) maxDist = 4000;
3469//
3470// float dist = Misc.getDistance(playerLoc, fleetLocInHyper);
3471// return dist > maxDist;
3472// }
3473
3474
3475 private static final AtomicLong seedUniquifier = new AtomicLong(8682522807148012L);
3476
3481 public static long genRandomSeed() {
3482 return seedUniquifier() ^ System.nanoTime();
3483 }
3484 public static long seedUniquifier() {
3485 // L'Ecuyer, "Tables of Linear Congruential Generators of
3486 // Different Sizes and Good Lattice Structure", 1999
3487 for (;;) {
3488 long current = seedUniquifier.get();
3489 long next = current * 181783497276652981L;
3490 //long next = current * 1181783497276652981L; // actual correct number?
3491 if (seedUniquifier.compareAndSet(current, next)) {
3492 return next;
3493 }
3494 }
3495 }
3496
3497
3498 public static String genUID() {
3499 if (Global.getSettings() != null && Global.getSettings().isInGame() &&
3501 return Global.getSector().genUID();
3502 }
3503 return UUID.randomUUID().toString();
3504 }
3505
3506
3507 public static String colorsToString(List<Color> colors) {
3508 String result = "";
3509 for (Color c : colors) {
3510 result += Integer.toHexString(c.getRGB()) + "|";
3511 }
3512 if (result.length() > 0) {
3513 result = result.substring(0, result.length() - 1);
3514 }
3515 return result;
3516 }
3517
3518 public static List<Color> colorsFromString(String in) {
3519 List<Color> result = new ArrayList<Color>();
3520 for (String p : in.split("\\|")) {
3521 //result.add(new Color(Integer.parseInt(p, 16)));
3522 result.add(new Color((int)Long.parseLong(p, 16)));
3523 }
3524 return result;
3525 }
3526
3528 for (Object entity : Global.getSector().getHyperspace().getEntities(JumpPointAPI.class)) {
3529 JumpPointAPI jp = (JumpPointAPI) entity;
3530 if (jp.getDestinationVisualEntity() == star) return jp;
3531 }
3532 return null;
3533 }
3534
3535 @SuppressWarnings("unchecked")
3537 float min = Float.MAX_VALUE;
3538 JumpPointAPI result = null;
3539 LocationAPI location = from.getContainingLocation();
3540 List<JumpPointAPI> points = location.getEntities(JumpPointAPI.class);
3541 for (JumpPointAPI curr : points) {
3542 float dist = Misc.getDistance(from.getLocation(), curr.getLocation());
3543 if (dist < min) {
3544 min = dist;
3545 result = curr;
3546 }
3547 }
3548 return result;
3549 }
3550
3551
3552 public static final String D_HULL_SUFFIX = "_default_D";
3553 public static String getDHullId(ShipHullSpecAPI spec) {
3554 String base = spec.getHullId();
3555 if (base.endsWith(D_HULL_SUFFIX)) return base;
3556 return base + D_HULL_SUFFIX;
3557 }
3558
3559
3560 public static HullModSpecAPI getMod(String id) {
3561 return Global.getSettings().getHullModSpec(id);
3562 }
3563
3564 public static float getDistanceFromArc(float direction, float arc, float angle) {
3565 direction = normalizeAngle(direction);
3566 angle = normalizeAngle(angle);
3567
3568 float dist1 = Math.abs(angle - direction) - arc/2f;
3569 float dist2 = Math.abs(360 - Math.abs(angle - direction)) - arc/2f;
3570
3571 if (dist1 <= 0 || dist2 <= 0) return 0;
3572
3573 return dist1 > dist2 ? dist2 : dist1;
3574 }
3575
3576 public static void initConditionMarket(PlanetAPI planet) {
3577 if (planet.getMarket() != null) {
3579 }
3580
3581 MarketAPI market = Global.getFactory().createMarket("market_" + planet.getId(), planet.getName(), 1);
3582 market.setPlanetConditionMarketOnly(true);
3583 market.setPrimaryEntity(planet);
3585 planet.setMarket(market);
3586
3587 long seed = StarSystemGenerator.random.nextLong();
3589 }
3590
3591 public static void initEconomyMarket(PlanetAPI planet) {
3592 if (planet.getMarket() != null) {
3594 }
3595
3596 MarketAPI market = Global.getFactory().createMarket("market_" + planet.getId(), planet.getName(), 1);
3597 //market.setPlanetConditionMarketOnly(true);
3598 market.setPrimaryEntity(planet);
3600 planet.setMarket(market);
3601 Global.getSector().getEconomy().addMarket(market, true);
3602 }
3603
3604 public static String getSurveyLevelString(SurveyLevel level, boolean withBrackets) {
3605 String str = " ";
3606 if (level == SurveyLevel.NONE) str = UNKNOWN;
3607 else if (level == SurveyLevel.SEEN) str = UNSURVEYED;
3608 else if (level == SurveyLevel.PRELIMINARY) str = PRELIMINARY;
3609 else if (level == SurveyLevel.FULL) str = FULL;
3610
3611 if (withBrackets) {
3612 str = "[" + str + "]";
3613 }
3614 return str;
3615 }
3616
3617 public static String getPlanetSurveyClass(PlanetAPI planet) {
3619 String type = plugin.getSurveyDataType(planet);
3620 if (type != null) {
3622 String classStr = spec.getName().replaceFirst(" Survey Data", "");
3623 return classStr;
3624 }
3625 return "Class N";
3626 }
3627
3628
3629 public static void setDefenderOverride(SectorEntityToken entity, DefenderDataOverride override) {
3631 }
3632
3633 public static void setSalvageSpecial(SectorEntityToken entity, Object data) {
3635// if (data instanceof ShipRecoverySpecialData) {
3636// BaseSalvageSpecial.clearExtraSalvage(entity);
3637// }
3638 }
3639
3640 public static void setPrevSalvageSpecial(SectorEntityToken entity, Object data) {
3642 }
3643
3644 public static Object getSalvageSpecial(SectorEntityToken entity) {
3646 }
3647 public static Object getPrevSalvageSpecial(SectorEntityToken entity) {
3649 }
3650
3651
3652
3653
3654 public static List<StarSystemAPI> getSystemsInRange(SectorEntityToken from, Set<StarSystemAPI> exclude, boolean nonEmpty, float maxRange) {
3655 List<StarSystemAPI> systems = new ArrayList<StarSystemAPI>();
3656
3657 for (StarSystemAPI system : Global.getSector().getStarSystems()) {
3658 if (exclude != null && exclude.contains(system)) continue;
3659
3660 float dist = Misc.getDistance(from.getLocationInHyperspace(), system.getLocation());
3661 if (dist > maxRange) continue;
3662 if (nonEmpty && !systemHasPlanets(system)) continue;
3663
3664 systems.add(system);
3665 }
3666
3667 return systems;
3668 }
3669
3670// public static boolean systemHasPulsar(StarSystemAPI system) {
3671// return hasPulsar(system);
3676// }
3678 if (system.getStar() != null && system.getStar().getSpec().isPulsar()) {
3679 return system.getStar();
3680 }
3681 if (system.getSecondary() != null && system.getSecondary().getSpec().isPulsar()) {
3682 return system.getSecondary();
3683 }
3684 if (system.getTertiary() != null && system.getTertiary().getSpec().isPulsar()) {
3685 return system.getTertiary();
3686 }
3687 return null;
3688 }
3689 public static boolean systemHasPlanets(StarSystemAPI system) {
3690 for (PlanetAPI p : system.getPlanets()) {
3691 if (!p.isStar()) return true;
3692 }
3693 return false;
3694 }
3695
3696 public static float getCampaignShipScaleMult(HullSize size) {
3697 switch (size) {
3698 case CAPITAL_SHIP:
3699 return 0.07f;
3700 case CRUISER:
3701 return 0.08f;
3702 case DESTROYER:
3703 return 0.09f;
3704 case FRIGATE:
3705 return 0.11f;
3706 case FIGHTER:
3707 return 0.15f;
3708 case DEFAULT:
3709 return 0.1f;
3710 }
3711 return 0.1f;
3712 }
3713
3714 public static WeightedRandomPicker<String> createStringPicker(Object ... params) {
3716 }
3717
3718 public static WeightedRandomPicker<String> createStringPicker(Random random, Object ... params) {
3720 for (int i = 0; i < params.length; i += 2) {
3721 String item = (String) params[i];
3722 float weight = 0f;
3723 if (params[i+1] instanceof Float) {
3724 weight = (Float) params[i+1];
3725 } else if (params[i+1] instanceof Integer) {
3726 weight = (Integer) params[i+1];
3727 }
3728 picker.add(item, weight);
3729 }
3730 return picker;
3731 }
3732
3733 public static void setWarningBeaconGlowColor(SectorEntityToken beacon, Color color) {
3735 }
3736
3737 public static void setWarningBeaconPingColor(SectorEntityToken beacon, Color color) {
3739 }
3740
3741 public static void setWarningBeaconColors(SectorEntityToken beacon, Color glow, Color ping) {
3742 if (glow != null) setWarningBeaconGlowColor(beacon, glow);
3743 if (ping != null) setWarningBeaconPingColor(beacon, ping);
3744 }
3745
3746
3747 public static List<CampaignFleetAPI> getNearbyFleets(SectorEntityToken from, float maxDist) {
3748 List<CampaignFleetAPI> result = new ArrayList<CampaignFleetAPI>();
3749 for (CampaignFleetAPI other : from.getContainingLocation().getFleets()) {
3750 if (from == other) continue;
3751 float dist = getDistance(from.getLocation(), other.getLocation());
3752 if (dist <= maxDist) {
3753 result.add(other);
3754 }
3755 }
3756 return result;
3757 }
3758
3759 public static List<CampaignFleetAPI> getVisibleFleets(SectorEntityToken from, boolean includeSensorContacts) {
3760 List<CampaignFleetAPI> result = new ArrayList<CampaignFleetAPI>();
3761 for (CampaignFleetAPI other : from.getContainingLocation().getFleets()) {
3762 if (from == other) continue;
3763 VisibilityLevel level = other.getVisibilityLevelTo(from);
3764 if (level == VisibilityLevel.COMPOSITION_AND_FACTION_DETAILS || level == VisibilityLevel.COMPOSITION_DETAILS) {
3765 result.add(other);
3766 } else if (level == VisibilityLevel.SENSOR_CONTACT && includeSensorContacts) {
3767 result.add(other);
3768 }
3769 }
3770 return result;
3771 }
3772
3773 public static boolean isSameCargo(CargoAPI baseOne, CargoAPI baseTwo) {
3774 CargoAPI one = Global.getFactory().createCargo(true);
3775 one.addAll(baseOne);
3776 one.sort();
3777
3778 CargoAPI two = Global.getFactory().createCargo(true);
3779 two.addAll(baseTwo);
3780 two.sort();
3781
3782
3783 if (one.getStacksCopy().size() != two.getStacksCopy().size()) return false;
3784
3785 List<CargoStackAPI> stacks1 = one.getStacksCopy();
3786 List<CargoStackAPI> stacks2 = two.getStacksCopy();
3787 for (int i = 0; i < stacks1.size(); i++) {
3788 CargoStackAPI s1 = stacks1.get(i);
3789 CargoStackAPI s2 = stacks2.get(i);
3790
3791 if ((s1 == null || s2 == null) && s1 != s2) return false;
3792 if (s1.getSize() != s2.getSize()) return false;
3793 if (s1.getType() != s2.getType()) return false;
3794 if ((s1.getData() == null || s2.getData() == null) && s1.getData() != s2.getData()) return false;
3795 if (!s1.getData().equals(s2.getData())) return false;
3796 }
3797
3798
3799 return true;
3800 }
3801
3802
3804 SectorEntityToken jumpPoint = null;
3805 float minDist = Float.MAX_VALUE;
3806 for (SectorEntityToken curr : system.getJumpPoints()) {
3807 if (curr instanceof JumpPointAPI && ((JumpPointAPI)curr).isWormhole()) {
3808 continue;
3809 }
3810
3811 float dist = Misc.getDistance(system.getCenter().getLocation(), curr.getLocation());
3812 if (dist < minDist) {
3813 jumpPoint = curr;
3814 minDist = dist;
3815 }
3816 }
3817 if (jumpPoint instanceof JumpPointAPI) {
3818 return (JumpPointAPI) jumpPoint;
3819 }
3820 return null;
3821 }
3822
3823
3824 public static void clearTarget(CampaignFleetAPI fleet, boolean forgetTransponder) {
3825 fleet.setInteractionTarget(null);
3826 if (fleet.getAI() instanceof ModularFleetAIAPI) {
3828 ai.getTacticalModule().setTarget(null);
3829 ai.getTacticalModule().setPriorityTarget(null, 0f, false);
3830 }
3831 if (forgetTransponder) {
3833 }
3834 }
3835
3839
3840 public static String FLEET_RETURNING_TO_DESPAWN = "$core_fleetReturningToDespawn";
3841
3845
3846 public static void giveStandardReturnToSourceAssignments(CampaignFleetAPI fleet, boolean withClear) {
3847 if (withClear) {
3848 fleet.clearAssignments();
3849 }
3851 MarketAPI source = Misc.getSourceMarket(fleet);
3852 if (source != null) {
3853 fleet.addAssignment(FleetAssignment.GO_TO_LOCATION, source.getPrimaryEntity(), 1000f, "returning to " + source.getName());
3854 fleet.addAssignment(FleetAssignment.ORBIT_PASSIVE, source.getPrimaryEntity(), 1f + 1f * (float) Math.random());
3856 } else {
3857 SectorEntityToken entity = getSourceEntity(fleet);
3858 if (entity != null) {
3859 fleet.addAssignment(FleetAssignment.GO_TO_LOCATION, entity, 1000f, "returning to " + entity.getName());
3860 fleet.addAssignment(FleetAssignment.ORBIT_PASSIVE, entity, 1f + 1f * (float) Math.random());
3862 } else {
3865 }
3866 }
3867 }
3868
3869 public static void giveStandardReturnAssignments(CampaignFleetAPI fleet, SectorEntityToken where, String text, boolean withClear) {
3870 if (withClear) {
3871 fleet.clearAssignments();
3872 }
3874 if (text == null) {
3875 fleet.addAssignment(FleetAssignment.GO_TO_LOCATION, where, 1000f, "returning to " + where.getName());
3876 } else {
3877 fleet.addAssignment(FleetAssignment.GO_TO_LOCATION, where, 1000f, text + " " + where.getName());
3878 }
3879 fleet.addAssignment(FleetAssignment.ORBIT_PASSIVE, where, 5f + 5f * (float) Math.random());
3881 }
3882
3883
3884 public static void adjustRep(float repChangeFaction, RepLevel limit, String factionId,
3885 float repChangePerson, RepLevel personLimit, PersonAPI person,
3886 TextPanelAPI text) {
3887 if (repChangeFaction != 0) {
3888 CustomRepImpact impact = new CustomRepImpact();
3889 impact.delta = repChangeFaction;
3890 impact.limit = limit;
3892 new RepActionEnvelope(RepActions.CUSTOM, impact,
3893 null, text, true),
3894 factionId);
3895
3896 if (person != null) {
3897 impact.delta = repChangePerson;
3898 impact.limit = personLimit;
3900 new RepActionEnvelope(RepActions.CUSTOM, impact,
3901 null, text, true), person);
3902 }
3903 }
3904 }
3905
3906
3907 public static void interruptAbilitiesWithTag(CampaignFleetAPI fleet, String tag) {
3908 for (AbilityPlugin curr : fleet.getAbilities().values()) {
3909 if (curr.isActive()) {
3910 for (String t : curr.getSpec().getTags()) {
3911 if (t.equals(tag)) {
3912 curr.deactivate();
3913 break;
3914 }
3915 }
3916 }
3917 }
3918 }
3919
3920
3921 public static Vector2f getInterceptPoint(CampaignFleetAPI from, SectorEntityToken to) {
3922
3923 //if (true) return new Vector2f(to.getLocation());
3924 //Vector2f v1 = new Vector2f(from.getVelocity());
3925 //Vector2f v2 = new Vector2f(to.getVelocity());
3926 Vector2f v2 = Vector2f.sub(to.getVelocity(), from.getVelocity(), new Vector2f());
3927
3928 float s1 = from.getTravelSpeed();
3929 float s2 = v2.length();
3930
3931 if (s1 < 10) s1 = 10;
3932 if (s2 < 10) s2 = 10;
3933
3934 Vector2f p1 = new Vector2f(from.getLocation());
3935 Vector2f p2 = new Vector2f(to.getLocation());
3936
3937 float dist = getDistance(p1, p2);
3938 float time = dist / s1;
3939 float maxTime = dist / s2 * 0.75f;
3940 if (time > maxTime) time = maxTime; // to ensure intercept point is never behind the from fleet
3941
3943
3944 p3.scale(time * s2);
3945 Vector2f.add(p2, p3, p3);
3946
3947 Vector2f overshoot = getUnitVectorAtDegreeAngle(getAngleInDegrees(p1, p3));
3948 overshoot.scale(3000f);
3949 Vector2f.add(p3, overshoot, p3);
3950
3951 return p3;
3952 }
3953
3954 public static Vector2f getInterceptPoint(SectorEntityToken from, SectorEntityToken to, float maxSpeedFrom) {
3955
3956 //if (true) return new Vector2f(to.getLocation());
3957 //Vector2f v1 = new Vector2f(from.getVelocity());
3958 //Vector2f v2 = new Vector2f(to.getVelocity());
3959 Vector2f v2 = Vector2f.sub(to.getVelocity(), from.getVelocity(), new Vector2f());
3960
3961 float s1 = maxSpeedFrom;
3962 float s2 = v2.length();
3963
3964 if (s1 < 10) s1 = 10;
3965 if (s2 < 10) s2 = 10;
3966
3967 Vector2f p1 = new Vector2f(from.getLocation());
3968 Vector2f p2 = new Vector2f(to.getLocation());
3969
3970 float dist = getDistance(p1, p2);
3971 float time = dist / s1;
3972 float maxTime = dist / s2 * 0.75f;
3973 if (time > maxTime) time = maxTime; // to ensure intercept point is never behind the from fleet
3974
3976
3977 p3.scale(time * s2);
3978 Vector2f.add(p2, p3, p3);
3979
3980 Vector2f overshoot = getUnitVectorAtDegreeAngle(getAngleInDegrees(p1, p3));
3981 overshoot.scale(3000f);
3982 Vector2f.add(p3, overshoot, p3);
3983
3984 return p3;
3985 }
3986
3987 public static void stopPlayerFleet() {
3989 if (player != null) {
3990 player.setVelocity(0, 0);
3991 }
3992 }
3993
3994 public static String getListOfResources(Map<String, Integer> res, List<String> quantities) {
3995 List<String> list = new ArrayList<String>();
3996 for (String con : res.keySet()) {
3998 int qty = res.get(con);
3999 list.add("" + qty + " " + spec.getName().toLowerCase());
4000 quantities.add("" + qty);
4001 }
4002 return Misc.getAndJoined(list);
4003 }
4004
4005
4006 public static void setColor(Color color) {
4007 GL11.glColor4ub((byte)color.getRed(),
4008 (byte)color.getGreen(),
4009 (byte)color.getBlue(),
4010 (byte)color.getAlpha());
4011 }
4012
4013 public static void setColor(Color color, float alphaMult) {
4014 GL11.glColor4ub((byte)color.getRed(),
4015 (byte)color.getGreen(),
4016 (byte)color.getBlue(),
4017 (byte)((float)color.getAlpha() * alphaMult));
4018 }
4019
4020
4021 public static void setColor(Color color, int alpha) {
4022 GL11.glColor4ub((byte)color.getRed(),
4023 (byte)color.getGreen(),
4024 (byte)color.getBlue(),
4025 (byte)alpha);
4026 }
4027
4028
4030 MarketAPI market = entity.getMarket();
4031 if (market == null) return false;
4032 if (market.getPrimaryEntity() != entity) return false;
4033
4035
4036 if (market != null && market.getCommDirectory() != null) {
4037 for (CommDirectoryEntryAPI entry : market.getCommDirectory().getEntriesCopy()) {
4038 if (entry.getType() == EntryType.PERSON && entry.getEntryData() instanceof PersonAPI) {
4039 PersonAPI person = (PersonAPI) entry.getEntryData();
4041 return true;
4042 }
4043 }
4044 }
4045 }
4046 return false;
4047 }
4048
4049
4050
4051 public static void makeImportant(SectorEntityToken entity, String reason) {
4052 makeImportant(entity.getMemoryWithoutUpdate(), reason, -1);
4053 }
4054 public static void makeImportant(SectorEntityToken entity, String reason, float dur) {
4055 makeImportant(entity.getMemoryWithoutUpdate(), reason, dur);
4056 }
4057 public static void makeImportant(PersonAPI person, String reason) {
4058 makeImportant(person.getMemoryWithoutUpdate(), reason, -1);
4059 }
4060 public static void makeImportant(PersonAPI person, String reason, float dur) {
4061 makeImportant(person.getMemoryWithoutUpdate(), reason, dur);
4062 }
4063 public static void makeImportant(MemoryAPI memory, String reason) {
4065 reason, true, -1);
4066 }
4067 public static void makeImportant(MemoryAPI memory, String reason, float dur) {
4069 reason, true, dur);
4070 }
4071
4072 public static boolean isImportantForReason(MemoryAPI memory, String reason) {
4073 String flagKey = MemFlags.ENTITY_MISSION_IMPORTANT;
4074 return flagHasReason(memory, flagKey, reason);
4075 }
4076
4077 public static void makeUnimportant(SectorEntityToken entity, String reason) {
4078 makeUnimportant(entity.getMemoryWithoutUpdate(), reason);
4079 }
4080 public static void makeUnimportant(PersonAPI person, String reason) {
4081 makeUnimportant(person.getMemoryWithoutUpdate(), reason);
4082 }
4083 public static void makeUnimportant(MemoryAPI memory, String reason) {
4085 reason, false, 0);
4086 }
4087
4088 public static void cleanUpMissionMemory(MemoryAPI memory, String prefix) {
4089 List<String> unset = new ArrayList<String>();
4090 for (String key : memory.getKeys()) {
4091 if (key.startsWith("$" + prefix)) {
4092 unset.add(key);
4093 }
4094 }
4095 for (String key : unset) {
4096 memory.unset(key);
4097 }
4098
4099 if (prefix.endsWith("_")) {
4100 prefix = prefix.substring(0, prefix.length() - 1);
4101 }
4102
4104 prefix, false, 0f);
4105 }
4106
4107
4108 public static void clearAreaAroundPlayer(float minDist) {
4110 if (player == null) return;
4111
4112 for (CampaignFleetAPI other : player.getContainingLocation().getFleets()) {
4113 if (player == other) continue;
4114 if (other.getBattle() != null) continue;
4115 if (other.getOrbit() != null) continue;
4116 if (!other.isHostileTo(player)) continue;
4117
4118 float dist = Misc.getDistance(player.getLocation(), other.getLocation());
4119 if (dist < minDist) {
4120 float angle = Misc.getAngleInDegrees(player.getLocation(), other.getLocation());
4121 Vector2f v = Misc.getUnitVectorAtDegreeAngle(angle);
4122 v.scale(minDist);
4123 Vector2f.add(v, other.getLocation(), v);
4124 other.setLocation(v.x, v.y);
4125 }
4126 }
4127 }
4128
4129 public static long getSalvageSeed(SectorEntityToken entity) {
4130 return getSalvageSeed(entity, false);
4131 }
4132 public static long getSalvageSeed(SectorEntityToken entity, boolean nonRandom) {
4134 if (seed == 0) {
4135 //seed = new Random().nextLong();
4136 String id = entity.getId();
4137 if (id == null) id = genUID();
4138 if (nonRandom) {
4139 seed = (entity.getId().hashCode() * 17000) * 1181783497276652981L;
4140 } else {
4141 seed = seedUniquifier() ^ (entity.getId().hashCode() * 17000);
4142 }
4143 Random r = new Random(seed);
4144 for (int i = 0; i < 5; i++) {
4145 r.nextLong();
4146 }
4147 long result = r.nextLong();
4149 return result;
4150 }
4151 return seed;
4152 }
4153
4154
4155 public static long getNameBasedSeed(SectorEntityToken entity) {
4156 String id = entity.getName();
4157 if (id == null) id = genUID();
4158
4159 long seed = (entity.getId().hashCode() * 17000);
4160 Random r = new Random(seed);
4161 for (int i = 0; i < 53; i++) {
4162 r.nextLong();
4163 }
4164 long result = r.nextLong();
4165 return result;
4166 }
4167
4176
4177 public static void setAbandonedStationMarket(String marketId, SectorEntityToken station) {
4178 station.getMemoryWithoutUpdate().set("$abandonedStation", true);
4179 MarketAPI market = Global.getFactory().createMarket(marketId, station.getName(), 0);
4180 market.setSurveyLevel(SurveyLevel.FULL);
4181 market.setPrimaryEntity(station);
4182 market.setFactionId(station.getFaction().getId());
4185 market.setPlanetConditionMarketOnly(false);
4186 ((StoragePlugin)market.getSubmarket(Submarkets.SUBMARKET_STORAGE).getPlugin()).setPlayerPaidToUnlock(true);
4187 station.setMarket(market);
4188 station.getMemoryWithoutUpdate().unset("$tradeMode");
4189 }
4190
4191 public static float getDesiredMoveDir(CampaignFleetAPI fleet) {
4192 if (fleet.getMoveDestination() == null) return 0f;
4193
4194 if (fleet.wasSlowMoving()) {
4195 Vector2f vel = fleet.getVelocity();
4196 Vector2f neg = new Vector2f(vel);
4197 neg.negate();
4198 return getAngleInDegrees(neg);
4199 }
4200
4201 return getAngleInDegrees(fleet.getLocation(), fleet.getMoveDestination());
4202 }
4203
4204 public static boolean isPermaKnowsWhoPlayerIs(CampaignFleetAPI fleet) {
4205 MemoryAPI mem = fleet.getMemoryWithoutUpdate();
4208 return true;
4209 }
4210 return false;
4211 }
4212
4214 return (SimulatorPlugin) Global.getSettings().getPlugin("simulatorPlugin");
4215 }
4216
4219 if (plugin == null) {
4220 plugin = new CoreImmigrationPluginImpl(market);
4221 }
4222 return plugin;
4223 }
4224
4225 public static AICoreAdminPlugin getAICoreAdminPlugin(String commodityId) {
4227 return plugin;
4228 }
4229
4230 public static AICoreOfficerPlugin getAICoreOfficerPlugin(String commodityId) {
4232 return plugin;
4233 }
4234
4237 return plugin;
4238 }
4239
4244
4245
4246 public static FleetInflater getInflater(CampaignFleetAPI fleet, Object params) {
4248 return plugin;
4249 }
4250
4251// public static float getIncomingRate(MarketAPI market, float weight) {
4252// ImmigrationPlugin plugin = getImmigrationPlugin(market);
4253// float diff = plugin.getWeightForMarketSize(market.getSize() + 1) -
4254// plugin.getWeightForMarketSize(market.getSize());
4255// if (diff <= 0) return 0f;
4256//
4257// //PopulationComposition incoming = market.getIncoming();
4258// return weight / diff;
4259//
4260// }
4261
4262 public static boolean playerHasStorageAccess(MarketAPI market) {
4264 if (storage != null && storage.getPlugin().getOnClickAction(null) == OnClickAction.OPEN_SUBMARKET) {
4265 return true;
4266 }
4267 return false;
4268 }
4269
4270 public static float getMarketSizeProgress(MarketAPI market) {
4271 ImmigrationPlugin plugin = getImmigrationPlugin(market);
4272 float min = plugin.getWeightForMarketSize(market.getSize());
4273 float max = plugin.getWeightForMarketSize(market.getSize() + 1);
4274
4275 float curr = market.getPopulation().getWeightValue();
4276
4277 if (max <= min) return 0f;
4278
4279 float f = (curr - min) / (max - min);
4280 if (f < 0) f = 0;
4281 if (f > 1) f = 1;
4282 return f;
4283 }
4284
4285
4286 public static float getStorageFeeFraction() {
4287 float storageFreeFraction = Global.getSettings().getFloat("storageFreeFraction");
4288 return storageFreeFraction;
4289 }
4290
4291 public static int getStorageCostPerMonth(MarketAPI market) {
4292 return (int) (getStorageTotalValue(market) * getStorageFeeFraction());
4293 }
4294
4295 public static SubmarketPlugin getStorage(MarketAPI market) {
4296 if (market == null) return null;
4298 if (submarket == null) return null;
4299 return (StoragePlugin) submarket.getPlugin();
4300 }
4301
4304 if (submarket == null) return null;
4305 return submarket.getPlugin();
4306 }
4307 public static CargoAPI getStorageCargo(MarketAPI market) {
4308 if (market == null) return null;
4310 if (submarket == null) return null;
4311 return submarket.getCargo();
4312 }
4313
4316 if (submarket == null) return null;
4317 return submarket.getCargo();
4318 }
4319
4320 public static float getStorageTotalValue(MarketAPI market) {
4321 return getStorageCargoValue(market) + getStorageShipValue(market);
4322 }
4323 public static float getStorageCargoValue(MarketAPI market) {
4324 SubmarketPlugin plugin = getStorage(market);
4325 if (plugin == null) return 0f;
4326 float value = 0f;
4327 for (CargoStackAPI stack : plugin.getCargo().getStacksCopy()) {
4328 value += stack.getSize() * stack.getBaseValuePerUnit();
4329 }
4330 return value;
4331 }
4332
4333 public static float getStorageShipValue(MarketAPI market) {
4334 SubmarketPlugin plugin = getStorage(market);
4335 if (plugin == null) return 0f;
4336 float value = 0f;
4337
4338 for (FleetMemberAPI member : plugin.getCargo().getMothballedShips().getMembersListCopy()) {
4339 value += member.getBaseValue();
4340 }
4341 return value;
4342 }
4343
4344
4349 public static boolean addStorageInfo(TooltipMakerAPI tooltip, Color color, Color dark, MarketAPI market,
4350 //boolean showFees,
4351 boolean includeLocalResources, boolean addSectionIfEmpty) {
4352 SubmarketPlugin storage = Misc.getStorage(market);
4353 SubmarketPlugin local = Misc.getLocalResources(market);
4354
4355 CargoAPI cargo = Global.getFactory().createCargo(true);
4356 List<FleetMemberAPI> ships = new ArrayList<FleetMemberAPI>();
4357 if (storage != null) {
4358 cargo.addAll(storage.getCargo());
4359 ships.addAll(storage.getCargo().getMothballedShips().getMembersListCopy());
4360 }
4361 if (local != null && includeLocalResources) {
4362 cargo.addAll(local.getCargo());
4363 ships.addAll(local.getCargo().getMothballedShips().getMembersListCopy());
4364 }
4365
4366 float opad = 15f;
4367 if (!cargo.isEmpty() || addSectionIfEmpty) {
4368 String title = "Cargo in storage";
4369 if (includeLocalResources && local != null) {
4370 title = "Cargo in storage and resource stockpiles";
4371 }
4372 tooltip.addSectionHeading(title, color, dark, Alignment.MID, opad);
4373 opad = 10f;
4374 tooltip.showCargo(cargo, 10, true, opad);
4375 }
4376
4377 if (!ships.isEmpty() || addSectionIfEmpty) {
4378 String title = "Ships in storage";
4379 if (includeLocalResources && local != null) {
4380 title = "Ships in storage";
4381 }
4382 tooltip.addSectionHeading(title, color, dark, Alignment.MID, opad);
4383 opad = 10f;
4384 tooltip.showShips(ships, 10, true, opad);
4385 }
4386
4387 if (!market.isPlayerOwned()) {
4388 int cost = getStorageCostPerMonth(market);
4389 if (cost > 0) {
4390 tooltip.addPara("Monthly storage fee: %s", opad, getHighlightColor(), getDGSCredits(cost));
4391 }
4392 }
4393
4394 if (addSectionIfEmpty) return true;
4395
4396 return !cargo.isEmpty() || !ships.isEmpty();
4397 }
4398
4399 public static String getTokenReplaced(String in, SectorEntityToken entity) {
4400 in = Global.getSector().getRules().performTokenReplacement(null, in, entity, null);
4401 return in;
4402 }
4403
4404 public static float getOutpostPenalty() {
4405 return Global.getSettings().getFloat("colonyOverMaxPenalty");
4406 }
4407
4408
4409 public static float getAdminSalary(PersonAPI admin) {
4410 int tier = (int) admin.getMemoryWithoutUpdate().getFloat("$ome_adminTier");
4411 String salaryKey = "adminSalaryTier" + tier;
4412 float s = Global.getSettings().getInt(salaryKey);
4413 return s;
4414 }
4415
4416 public static float getOfficerSalary(PersonAPI officer) {
4417 return getOfficerSalary(officer, Misc.isMercenary(officer));
4418 }
4419 public static float getOfficerSalary(PersonAPI officer, boolean mercenary) {
4420 int officerBase = Global.getSettings().getInt("officerSalaryBase");
4421 int officerPerLevel = Global.getSettings().getInt("officerSalaryPerLevel");
4422
4423 float payMult = 1f;
4424 if (mercenary) {
4425 payMult = Global.getSettings().getFloat("officerMercPayMult");
4426 }
4427
4428 float salary = (officerBase + officer.getStats().getLevel() * officerPerLevel) * payMult;
4429 return salary;
4430 }
4431
4432// public static int getAccessibilityPercent(float a) {
4433// int result = (int) Math.round(a * 100f);
4434// if (a < 0 && result == 0) result = -1; // shipping penalty at "below zero"
4435// return result;
4436// }
4437
4438 public static Map<String, Integer> variantToFPCache = new HashMap<String, Integer>();
4439 //public static Map<String, Boolean> variantToIsBaseCache = new HashMap<String, Boolean>();
4440 public static Map<String, String> variantToHullCache = new HashMap<String, String>();
4441 //public static Map<String, String> hullIdToHasTag = new HashMap<String, String>();
4442 public static String getHullIdForVariantId(String variantId) {
4443 String hull = variantToHullCache.get(variantId);
4444 if (hull != null) return hull;
4445
4446 ShipVariantAPI variant = Global.getSettings().getVariant(variantId);
4447 hull = variant.getHullSpec().getHullId();
4448 variantToHullCache.put(variantId, hull);
4449
4450 return hull;
4451 }
4452
4453// public static boolean getIsBaseForVariantId(String variantId) {
4454// Boolean isBase = variantToIsBaseCache.get(variantId);
4455// if (isBase != null) return isBase;
4460// ShipVariantAPI variant = Global.getSettings().getVariant(variantId);
4461// isBase = variant.getHullSpec().hasTag(Items.TAG_BASE_BP);
4462// variantToIsBaseCache.put(variantId, isBase);
4463//
4464// return isBase;
4465// }
4466
4467 public static int getFPForVariantId(String variantId) {
4468 Integer fp = variantToFPCache.get(variantId);
4469 if (fp != null) return fp;
4470
4471 ShipVariantAPI variant = Global.getSettings().getVariant(variantId);
4472 fp = variant.getHullSpec().getFleetPoints();
4473 variantToFPCache.put(variantId, fp);
4474
4475 return fp;
4476 }
4477
4481
4482
4483 public static float getAdjustedStrength(float fp, MarketAPI market) {
4484 fp *= Math.max(0.25f, 0.5f + Math.min(1f, Misc.getShipQuality(market)));
4485
4486 if (market != null) {
4487 float numShipsMult = market.getStats().getDynamic().getMod(Stats.COMBAT_FLEET_SIZE_MULT).computeEffective(0f);
4488 fp *= numShipsMult;
4489
4490 // float pts = market.getFaction().getDoctrine().getNumShips() + market.getFaction().getDoctrine().getOfficerQuality();
4491 // fp *= 1f + (pts - 2f) / 4f;
4492 float pts = market.getFaction().getDoctrine().getOfficerQuality();
4493 fp *= 1f + (pts - 1f) / 4f;
4494 }
4495 return fp;
4496 }
4497 public static float getAdjustedFP(float fp, MarketAPI market) {
4498 if (market != null) {
4499 float numShipsMult = market.getStats().getDynamic().getMod(Stats.COMBAT_FLEET_SIZE_MULT).computeEffective(0f);
4500 fp *= numShipsMult;
4501 }
4502 return fp;
4503 }
4504
4505 public static float getShipQuality(MarketAPI market) {
4506 return getShipQuality(market, null);
4507 }
4508 public static float getShipQuality(MarketAPI market, String factionId) {
4509 return ShipQuality.getShipQuality(market, factionId);
4510// float quality = 0f;
4511//
4512// if (market != null) {
4513// CommodityOnMarketAPI com = market.getCommodityData(Commodities.SHIPS);
4514//
4515// SupplierData sd = com.getSupplier();
4516// if (sd != null && sd.getMarket() != null) {
4517// quality = sd.getMarket().getStats().getDynamic().getMod(Stats.PRODUCTION_QUALITY_MOD).computeEffective(0f);
4518// if (factionId == null && sd.getMarket().getFaction() != market.getFaction()) {
4519// quality -= FleetFactoryV3.IMPORTED_QUALITY_PENALTY;
4520// } else if (factionId != null && !factionId.equals(sd.getMarket().getFactionId())) {
4521// quality -= FleetFactoryV3.IMPORTED_QUALITY_PENALTY;
4522// }
4523// }
4524//
4525// quality += market.getStats().getDynamic().getMod(Stats.FLEET_QUALITY_MOD).computeEffective(0f);
4526// }
4527//
4528//
4529// if (factionId == null) {
4530// //quality += market.getFaction().getDoctrine().getShipQualityContribution();
4531// } else {
4532// if (market != null) {
4533// quality -= market.getFaction().getDoctrine().getShipQualityContribution();
4534// }
4535// quality += Global.getSector().getFaction(factionId).getDoctrine().getShipQualityContribution();
4536// }
4537//
4538// return quality;
4539 }
4540
4541
4542 public static ShipPickMode getShipPickMode(MarketAPI market) {
4543 return getShipPickMode(market, null);
4544 }
4545 public static ShipPickMode getShipPickMode(MarketAPI market, String factionId) {
4546 QualityData d = ShipQuality.getInstance().getQualityData(market);
4547 if (d.market != null) {
4548 if (factionId == null && d.market.getFaction() != market.getFaction()) {
4549 return ShipPickMode.IMPORTED;
4550 } else if (factionId != null && !factionId.equals(d.market.getFactionId())) {
4551 return ShipPickMode.IMPORTED;
4552 }
4553 return ShipPickMode.PRIORITY_THEN_ALL;
4554 }
4555 return ShipPickMode.IMPORTED;
4556 }
4557
4558 public static boolean isBusy(CampaignFleetAPI fleet) {
4560 }
4561
4563 for (SectorEntityToken entity : market.getConnectedEntities()) {
4564 if (entity.hasTag(Tags.STATION)) {
4565 CampaignFleetAPI curr = getStationFleet(entity);
4566 if (curr != null && curr == fleet) return entity;
4567 }
4568 }
4569 return null;
4570 }
4572 for (SectorEntityToken entity : market.getConnectedEntities()) {
4573 if (entity.hasTag(Tags.STATION)) {
4574 CampaignFleetAPI fleet = getStationFleet(entity);
4575 if (fleet != null) return fleet;
4576 }
4577 }
4578 return null;
4579 }
4581 if (station.hasTag(Tags.STATION)) {// && station instanceof CustomCampaignEntityAPI) {
4582 Object test = station.getMemoryWithoutUpdate().get(MemFlags.STATION_FLEET);
4583 if (test instanceof CampaignFleetAPI) {
4584 return (CampaignFleetAPI) test;
4585 }
4586 }
4587 return null;
4588 }
4589
4591 for (SectorEntityToken entity : market.getConnectedEntities()) {
4592 if (entity.hasTag(Tags.STATION)) {
4593 CampaignFleetAPI fleet = getStationBaseFleet(entity);
4594 if (fleet != null) return fleet;
4595 }
4596 }
4597 return null;
4598 }
4600 if (station.hasTag(Tags.STATION)) {// && station instanceof CustomCampaignEntityAPI) {
4601 Object test = station.getMemoryWithoutUpdate().get(MemFlags.STATION_BASE_FLEET);
4602 if (test instanceof CampaignFleetAPI) {
4603 return (CampaignFleetAPI) test;
4604 }
4605 }
4606 return null;
4607 }
4608
4610 Object test = station.getMemoryWithoutUpdate().get(MemFlags.STATION_MARKET);
4611 if (test instanceof MarketAPI) {
4612 return (MarketAPI) test;
4613 }
4614 return null;
4615 }
4616
4617 public static Industry getStationIndustry(MarketAPI market) {
4618 for (Industry ind : market.getIndustries()) {
4619 if (ind.getSpec().hasTag(Industries.TAG_STATION)) {
4620 return ind;
4621 }
4622 }
4623 return null;
4624 }
4625
4626 public static boolean isActiveModule(ShipVariantAPI variant) {
4627 boolean notActiveModule = variant.getHullSpec().getOrdnancePoints(null) <= 0 &&
4628 variant.getWeaponGroups().isEmpty() &&
4629 variant.getHullSpec().getFighterBays() <= 0;
4630 return !notActiveModule;
4631 }
4632 public static boolean isActiveModule(ShipAPI ship) {
4633 boolean notActiveModule = ship.getVariant().getHullSpec().getOrdnancePoints(null) <= 0 &&
4634 ship.getVariant().getWeaponGroups().isEmpty() &&
4636 return !notActiveModule;
4637 }
4638
4639 public static void addCreditsMessage(String format, int credits) {
4642 }
4643
4644
4646 for (JumpDestination d : jp.getDestinations()) {
4647 if (d.getDestination() != null && d.getDestination().getContainingLocation() != null &&
4648 d.getDestination().getContainingLocation().isHyperspace()) {
4649 return d.getDestination().getLocation();
4650 }
4651 }
4652 return jp.getLocationInHyperspace();
4653 }
4654
4655
4656 public static boolean isNear(SectorEntityToken entity, Vector2f hyperLoc) {
4657 float maxRange = Global.getSettings().getFloat("commRelayRangeAroundSystem");
4658 float dist = Misc.getDistanceLY(entity.getLocationInHyperspace(), hyperLoc);
4659 if (dist > maxRange) return false;
4660 return true;
4661 }
4662
4663 public static float getDays(float amount) {
4664 return Global.getSector().getClock().convertToDays(amount);
4665 }
4666
4667 public static float getProbabilityMult(float desired, float current, float deviationMult) {
4668 float deviation = desired * deviationMult;
4669 float exponent = (desired - current) / deviation;
4670 if (exponent > 4) exponent = 4;
4671 float probMult = (float) Math.pow(10f, exponent);
4672 return probMult;
4673 }
4674
4675 public static boolean isHyperspaceAnchor(SectorEntityToken entity) {
4676 return entity != null && entity.hasTag(Tags.SYSTEM_ANCHOR);
4677 }
4678
4682
4683 public static void showCost(TextPanelAPI text, Color color, Color dark, String [] res, int [] quantities) {
4684 showCost(text, "Resources: consumed (available)", true, color, dark, res, quantities);
4685 }
4686 public static void showCost(TextPanelAPI text, String title, boolean withAvailable, Color color, Color dark, String [] res, int [] quantities) {
4687 showCost(text, title, withAvailable, -1f, color, dark, res, quantities, null);
4688 }
4689 public static void showCost(TextPanelAPI text, String title, boolean withAvailable, float widthOverride, Color color, Color dark, String [] res, int [] quantities, boolean [] consumed) {
4690 if (color == null) color = getBasePlayerColor();
4691 if (dark == null) dark = getDarkPlayerColor();
4692
4693 Set<String> unmet = new HashSet<String>();
4694 Set<String> all = new LinkedHashSet<String>();
4695
4697
4698 for (int i = 0; i < res.length; i++) {
4699 String commodityId = res[i];
4700 int quantity = quantities[i];
4701 if (quantity > cargo.getQuantity(CargoItemType.RESOURCES, commodityId)) {
4702 unmet.add(commodityId);
4703 }
4704 all.add(commodityId);
4705 }
4706
4707 float costHeight = 67;
4708 ResourceCostPanelAPI cost = text.addCostPanel(title, costHeight,
4709 color, dark);
4710 cost.setNumberOnlyMode(true);
4711 cost.setWithBorder(false);
4713
4714 if (widthOverride > 0) {
4715 cost.setComWidthOverride(widthOverride);
4716 }
4717
4718 boolean dgs = true;
4719 for (int i = 0; i < res.length; i++) {
4720 String commodityId = res[i];
4721 int required = quantities[i];
4722 int available = (int) cargo.getCommodityQuantity(commodityId);
4723 Color curr = color;
4724 if (withAvailable && required > cargo.getQuantity(CargoItemType.RESOURCES, commodityId)) {
4726 }
4727 if (dgs) {
4728 if (withAvailable) {
4729 cost.addCost(commodityId, Misc.getWithDGS(required) + " (" + Misc.getWithDGS(available) + ")", curr);
4730 } else {
4731 cost.addCost(commodityId, Misc.getWithDGS(required), curr);
4732 }
4733 if (consumed != null && consumed[i]) {
4734 cost.setLastCostConsumed(true);
4735 }
4736 } else {
4737 if (withAvailable) {
4738 cost.addCost(commodityId, "" + required + " (" + available + ")", curr);
4739 } else {
4740 cost.addCost(commodityId, "" + required, curr);
4741 }
4742 if (consumed != null && consumed[i]) {
4743 cost.setLastCostConsumed(true);
4744 }
4745 }
4746 }
4747 cost.update();
4748 }
4749
4750 public static boolean isPlayerFactionSetUp() {
4751 String key = "$shownFactionConfigDialog";
4753 return true;
4754 }
4755 return false;
4756 }
4757
4758 public static String getFleetType(CampaignFleetAPI fleet) {
4760 }
4761 public static boolean isPatrol(CampaignFleetAPI fleet) {
4763 }
4764 public static boolean isSmuggler(CampaignFleetAPI fleet) {
4766 }
4767 public static boolean isTrader(CampaignFleetAPI fleet) {
4769 }
4770 public static boolean isPirate(CampaignFleetAPI fleet) {
4772 }
4773 public static boolean isScavenger(CampaignFleetAPI fleet) {
4775 }
4776 public static boolean isRaider(CampaignFleetAPI fleet) {
4778 }
4779 public static boolean isWarFleet(CampaignFleetAPI fleet) {
4781 }
4782
4783
4790 SectorEntityToken closestEntity = null;
4791 CampaignFleetAPI closest = null;
4792 float minDist = Float.MAX_VALUE;
4794 CampaignFleetAPI fleet = Misc.getStationFleet(station);
4795 if (fleet == null || fleet.isEmpty()) continue;
4796
4797 if (!isStationInSupportRange(from, fleet)) continue;
4798 float dist = Misc.getDistance(from.getLocation(), station.getLocation());
4799
4800 if (dist < minDist) {
4801 closest = fleet;
4802 closestEntity = station;
4803 minDist = dist;
4804 }
4805 }
4806
4807 // remnant stations and other fleets that are in station mode, w/o a related market
4808 for (CampaignFleetAPI fleet : from.getContainingLocation().getFleets()) {
4809 if (!fleet.isStationMode()) continue;
4810 if (fleet.isHidden()) continue;
4811
4812 if (!isStationInSupportRange(from, fleet)) continue;
4813 float dist = Misc.getDistance(from.getLocation(), fleet.getLocation());
4814
4815 if (dist < minDist) {
4816 closest = fleet;
4817 closestEntity = null;
4818 minDist = dist;
4819 }
4820 }
4821
4822 if (closest == null) return null;
4823
4824 return new Pair<SectorEntityToken, CampaignFleetAPI>(closestEntity, closest);
4825 }
4826
4827 public static boolean isStationInSupportRange(CampaignFleetAPI fleet, CampaignFleetAPI station) {
4828 float check = Misc.getBattleJoinRange();
4829 float distPrimary = 10000f;
4830 MarketAPI market = getStationMarket(station);
4831 if (market != null) {
4832 distPrimary = Misc.getDistance(fleet.getLocation(), market.getPrimaryEntity().getLocation());
4833 }
4834 float distStation = Misc.getDistance(fleet.getLocation(), station.getLocation());
4835
4836 if (distPrimary > check && distStation > check) {
4837 return false;
4838 }
4839 return true;
4840
4841 }
4842
4843
4844 public static float getMemberStrength(FleetMemberAPI member) {
4845 return getMemberStrength(member, true, true, true);
4846 }
4847
4848 public static float getMemberStrength(FleetMemberAPI member, boolean withHull, boolean withQuality, boolean withCaptain) {
4849 float str = member.getMemberStrength();
4850 float min = 0.25f;
4851 if (str < min) str = min;
4852
4853 float quality = 0.5f;
4854 float sMods = 0f;
4855 if (member.getFleetData() != null && member.getFleetData().getFleet() != null) {
4856 CampaignFleetAPI fleet = member.getFleetData().getFleet();
4857 if (fleet.getInflater() != null && !fleet.isInflated()) {
4858 quality = fleet.getInflater().getQuality();
4859 sMods = fleet.getInflater().getAverageNumSMods();
4860 } else {
4861 BattleAPI battle = fleet.getBattle();
4862 CampaignFleetAPI source = battle == null ? null : battle.getSourceFleet(member);
4863 if (source != null && source.getInflater() != null &&
4864 !source.isInflated()) {
4865 quality = source.getInflater().getQuality();
4866 sMods = source.getInflater().getAverageNumSMods();
4867 } else {
4868 float dmods = DModManager.getNumDMods(member.getVariant());
4869 quality = 1f - Global.getSettings().getFloat("qualityPerDMod") * dmods;
4870 if (quality < 0) quality = 0f;
4871
4872 sMods = member.getVariant().getSMods().size();
4873 }
4874 }
4875 }
4876
4877 if (member.isStation()) {
4878 quality = 1f;
4879 }
4880
4881 if (sMods > 0) {
4882 quality += sMods * Global.getSettings().getFloat("qualityPerSMod");
4883 }
4884
4885 float captainMult = 1f;
4886 if (member.getCaptain() != null) {
4887 float captainLevel = (member.getCaptain().getStats().getLevel() - 1f);
4888 if (member.isStation()) {
4889 captainMult += captainLevel / (MAX_OFFICER_LEVEL * 2f);
4890 } else {
4891 captainMult += captainLevel / MAX_OFFICER_LEVEL;
4892 }
4893 }
4894
4895 if (withQuality) {
4896 //str *= Math.max(0.25f, 0.5f + quality);
4897 str *= Math.max(0.25f, 0.8f + quality * 0.4f);
4898 }
4899 if (withHull) {
4900 str *= 0.5f + 0.5f * member.getStatus().getHullFraction();
4901 }
4902 if (withCaptain) {
4903 str *= captainMult;
4904 }
4905 //System.out.println("Member: " + member + ", str: " + str);
4906
4907 return str;
4908 }
4909
4910
4911 public static void increaseMarketHostileTimeout(MarketAPI market, float days) {
4912 MemoryAPI mem = market.getMemoryWithoutUpdate();
4913 float expire = days;
4916 }
4917 if (expire > 180) expire = 180;
4918 if (expire > 0) {
4920 }
4921 }
4922
4923 public static void removeRadioChatter(MarketAPI market) {
4924 if (market.getContainingLocation() == null) return;
4925 for (CampaignTerrainAPI terrain : market.getContainingLocation().getTerrainCopy()) {
4926 if (Terrain.RADIO_CHATTER.equals(terrain.getType())) {
4927 float dist = Misc.getDistance(terrain, market.getPrimaryEntity());
4928 if (dist < 200) {
4929 market.getContainingLocation().removeEntity(terrain);
4930 }
4931 }
4932 }
4933 }
4934
4935
4936 public static Color getDesignTypeColor(String designType) {
4937 return Global.getSettings().getDesignTypeColor(designType);
4938 }
4939
4940 public static Color getDesignTypeColorDim(String designType) {
4941 Color c = Global.getSettings().getDesignTypeColor(designType);
4942 return Misc.scaleColorOnly(c, 0.53f);
4943 }
4944
4945
4946 public static LabelAPI addDesignTypePara(TooltipMakerAPI tooltip, String design, float pad) {
4947 if (design != null && !design.isEmpty()) {
4948 return tooltip.addPara("Design type: %s", pad, Misc.getGrayColor(), Global.getSettings().getDesignTypeColor(design), design);
4949 }
4950 return null;
4951 }
4952
4956 float radius = fleet.getRadius();
4957
4958 //radius = 1000;
4959
4960 float mult = (radius - min) / (max - min);
4961 if (mult > 1) mult = 1;
4962 //if (mult < 0) mult = 0;
4964 //mult = MIN_BURN_PENALTY + mult * BURN_PENALTY_RANGE;
4965
4967 mult *= skillMod;
4968
4969 mult = Math.round(mult * 100f) / 100f;
4970
4971 return mult;
4972 }
4973
4974 public static float MIN_TERRAIN_EFFECT_MULT = Global.getSettings().getFloat("minTerrainEffectMult");
4975 public static float BURN_PENALTY_MULT = Global.getSettings().getFloat("standardBurnPenaltyMult");
4976 public static float getBurnMultForTerrain(CampaignFleetAPI fleet) {
4977 float mult = getFleetRadiusTerrainEffectMult(fleet);
4978 mult = (1f - BURN_PENALTY_MULT * mult);
4979 mult = Math.round(mult * 100f) / 100f;
4980 if (mult < 0.1f) mult = 0.1f;
4981// if (mult > 1) mult = 1;
4982 return mult;
4983 }
4984
4985
4986 public static void addHitGlow(LocationAPI location, Vector2f loc, Vector2f vel, float size, Color color) {
4987 float dur = 1f + (float) Math.random();
4988 addHitGlow(location, loc, vel, size, dur, color);
4989 }
4990 public static void addHitGlow(LocationAPI location, Vector2f loc, Vector2f vel, float size, float dur, Color color) {
4991 location.addHitParticle(loc, vel,
4992 size, 0.4f, dur, color);
4993 location.addHitParticle(loc, vel,
4994 size * 0.25f, 0.4f, dur, color);
4995 location.addHitParticle(loc, vel,
4996 size * 0.15f, 1f, dur, Color.white);
4997 }
4998
4999 public static ParticleControllerAPI [] addGlowyParticle(LocationAPI location, Vector2f loc, Vector2f vel, float size, float rampUp, float dur, Color color) {
5000 //rampUp = 0f;
5001 //dur = 3f;
5002
5004
5005 result[0] = location.addParticle(loc, vel,
5006 size, 0.4f, rampUp, dur, color);
5007 result[1] = location.addParticle(loc, vel,
5008 size * 0.25f, 0.4f, rampUp, dur, color);
5009 result[2] = location.addParticle(loc, vel,
5010 size * 0.15f, 1f, rampUp, dur, Color.white);
5011
5012 return result;
5013 }
5014
5015
5016 public static float SAME_FACTION_BONUS = Global.getSettings().getFloat("accessibilitySameFactionBonus");
5017 public static float PER_UNIT_SHIPPING = Global.getSettings().getFloat("accessibilityPerUnitShipping");
5018
5019 public static int getShippingCapacity(MarketAPI market, boolean inFaction) {
5020 float a = Math.round(market.getAccessibilityMod().computeEffective(0f) * 100f) / 100f;
5021 if (inFaction) {
5022 a += SAME_FACTION_BONUS;
5023 }
5024 return (int) Math.max(0, a / PER_UNIT_SHIPPING);
5025 }
5026
5027 public static String getStrengthDesc(float strAdjustedFP) {
5028 String strDesc;
5029 if (strAdjustedFP < 50) {
5030 strDesc = "very weak";
5031 } else if (strAdjustedFP < 150) {
5032 strDesc = "somewhat weak";
5033 } else if (strAdjustedFP < 300) {
5034 strDesc = "fairly capable";
5035 } else if (strAdjustedFP < 750) {
5036 strDesc = "fairly strong";
5037 } else if (strAdjustedFP < 1250) {
5038 strDesc = "strong";
5039 } else {
5040 strDesc = "very strong";
5041 }
5042 return strDesc;
5043 }
5044
5045 public static boolean isMilitary(MarketAPI market) {
5046 return market != null && market.getMemoryWithoutUpdate().getBoolean(MemFlags.MARKET_MILITARY);
5047 }
5048
5049 public static boolean hasHeavyIndustry(MarketAPI market) {
5050 boolean heavyIndustry = false;
5051 for (Industry curr : market.getIndustries()) {
5052 if (curr.getSpec().hasTag(Industries.TAG_HEAVYINDUSTRY)) {
5053 heavyIndustry = true;
5054 }
5055 }
5056 return heavyIndustry;
5057 }
5058
5059 public static boolean hasOrbitalStation(MarketAPI market) {
5060 for (Industry curr : market.getIndustries()) {
5061 if (curr.getSpec().hasTag(Industries.TAG_STATION)) {
5062 return true;
5063 }
5064 }
5065 return false;
5066 }
5067
5069 if (planet.getStarSystem() != null) {
5071 if (claimedBy != null) {
5072 return Global.getSector().getFaction(claimedBy);
5073 }
5074 }
5075
5076 int max = 0;
5077 MarketAPI result = null;
5078 List<MarketAPI> markets = Global.getSector().getEconomy().getMarkets(planet.getContainingLocation());
5079 for (MarketAPI curr : markets) {
5080 if (curr.isHidden()) continue;
5081 if (curr.getFaction().isPlayerFaction()) continue;
5082
5083 int score = curr.getSize();
5084 for (MarketAPI other : markets) {
5085 if (other != curr && other.getFaction() == curr.getFaction()) score++;
5086 }
5087 if (isMilitary(curr)) score += 10;
5088 if (score > max) {
5089 JSONObject json = curr.getFaction().getCustom().optJSONObject(Factions.CUSTOM_PUNITIVE_EXPEDITION_DATA);
5090 if (json == null) continue;
5091 boolean territorial = json.optBoolean("territorial");
5092 if (!territorial) continue;
5093
5094 max = score;
5095 result = curr;
5096 }
5097 }
5098 if (result == null) return null;
5099
5100 return result.getFaction();
5101 }
5102
5103
5104 public static int computeTotalShutdownRefund(MarketAPI market) {
5105 int total = 0;
5106 for (Industry industry : market.getIndustries()) {
5107 total += computeShutdownRefund(market, industry);
5108 }
5109
5110 // since incentives no longer work this way...
5111// float refundFraction = Global.getSettings().getFloat("industryRefundFraction");
5112// float incentives = market.getIncentiveCredits() * refundFraction;
5113// total += incentives;
5114
5115 return total;
5116 }
5117
5118 public static int computeShutdownRefund(MarketAPI market, Industry industry) {
5119 float refund = 0;
5120
5121 Industry upInd = null;
5122 if (industry.isUpgrading()) {
5123 String up = industry.getSpec().getUpgrade();
5124 if (up != null) {
5125 upInd = market.instantiateIndustry(up);
5126 }
5127 }
5128 if (industry.isUpgrading() && upInd != null) {
5129 refund += upInd.getBuildCost();
5130 }
5131
5132 float refundFraction = Global.getSettings().getFloat("industryRefundFraction");
5133 Industry curr = industry;
5134 while (curr != null) {
5135 if (curr.isBuilding() && !curr.isUpgrading()) {
5136 refund += curr.getBuildCost();
5137 } else {
5138 refund += curr.getBuildCost() * refundFraction;
5139 }
5140 String down = curr.getSpec().getDowngrade();
5141 if (down != null) {
5142 curr = market.instantiateIndustry(down);
5143 } else {
5144 curr = null;
5145 }
5146 }
5147
5148 return (int) refund;
5149 }
5150
5151
5152 public static SectorEntityToken addWarningBeacon(SectorEntityToken center, OrbitGap gap, String beaconTag) {
5154 beacon.addTag(beaconTag);
5155
5156 float radius = (gap.start + gap.end) / 2f;
5157 float orbitDays = radius / (10f + StarSystemGenerator.random.nextFloat() * 5f);
5158 beacon.setCircularOrbitPointingDown(center, StarSystemGenerator.random.nextFloat() * 360f, radius, orbitDays);
5159
5160 Color glowColor = new Color(255,200,0,255);
5161 Color pingColor = new Color(255,200,0,255);
5162 if (beaconTag.equals(Tags.BEACON_MEDIUM)) {
5163 glowColor = new Color(250,155,0,255);
5164 pingColor = new Color(250,155,0,255);
5165 } else if (beaconTag.equals(Tags.BEACON_HIGH)) {
5166 glowColor = new Color(250,55,0,255);
5167 pingColor = new Color(250,125,0,255);
5168 }
5169 Misc.setWarningBeaconColors(beacon, glowColor, pingColor);
5170 return beacon;
5171 }
5172
5173
5174 public static CoreUITradeMode getTradeMode(MemoryAPI memory) {
5175 CoreUITradeMode mode = CoreUITradeMode.OPEN;
5176 String val = memory.getString("$tradeMode");
5177 if (val != null && !val.isEmpty()) {
5178 mode = CoreUITradeMode.valueOf(val);
5179 }
5180 return mode;
5181 }
5182
5183 public static boolean isSpacerStart() {
5184 return Global.getSector().getMemoryWithoutUpdate().getBoolean("$spacerStart");
5185 }
5186
5187 public static Industry getSpaceport(MarketAPI market) {
5188 for (Industry ind : market.getIndustries()) {
5189 if (ind.getSpec().hasTag(Industries.TAG_SPACEPORT)) {
5190 return ind;
5191 }
5192 }
5193 return null;
5194 }
5195
5196 public static Color setBrightness(Color color, int brightness) {
5197 float max = color.getRed();
5198 if (color.getGreen() > max) max = color.getGreen();
5199 if (color.getBlue() > max) max = color.getBlue();
5200 float f = brightness / max;
5201 color = scaleColorSaturate(color, f);
5202 return color;
5203 }
5204
5205 public static Color scaleColorSaturate(Color color, float factor) {
5206 int red = (int) (color.getRed() * factor);
5207 int green = (int) (color.getGreen() * factor);
5208 int blue = (int) (color.getBlue() * factor);
5209 int alpha = (int) (color.getAlpha() * factor);
5210
5211 if (red > 255) red = 255;
5212 if (green > 255) green = 255;
5213 if (blue > 255) blue = 255;
5214 if (alpha > 255) alpha = 255;
5215
5216 return new Color(red, green, blue, alpha);
5217 }
5218
5219 public static int getMaxOfficers(CampaignFleetAPI fleet) {
5220 int max = (int) fleet.getCommander().getStats().getOfficerNumber().getModifiedValue();
5221 return max;
5222 }
5223 public static int getNumNonMercOfficers(CampaignFleetAPI fleet) {
5224 int count = 0;
5225 for (OfficerDataAPI od : fleet.getFleetData().getOfficersCopy()) {
5226 if (!isMercenary(od.getPerson())) {
5227 count++;
5228 }
5229 }
5230 return count;
5231 }
5232
5233 public static List<OfficerDataAPI> getMercs(CampaignFleetAPI fleet) {
5234 List<OfficerDataAPI> mercs = new ArrayList<OfficerDataAPI>();
5235 for (OfficerDataAPI od : fleet.getFleetData().getOfficersCopy()) {
5236 if (isMercenary(od.getPerson())) {
5237 mercs.add(od);
5238 }
5239 }
5240 return mercs;
5241 }
5242
5243
5244 public static int getMaxIndustries(MarketAPI market) {
5245 return (int)Math.round(market.getStats().getDynamic().getMod(Stats.MAX_INDUSTRIES).computeEffective(0));
5246 }
5247
5248 public static int getNumIndustries(MarketAPI market) {
5249 int count = 0;
5250 for (Industry curr : market.getIndustries()) {
5251 if (curr.isIndustry()) {
5252 count++;
5253 } else if (curr.isUpgrading()) {
5254 String up = curr.getSpec().getUpgrade();
5255 if (up != null) {
5256 Industry upInd = market.instantiateIndustry(up);
5257 if (upInd.isIndustry()) count++;
5258 }
5259 }
5260 }
5261 for (ConstructionQueueItem item : market.getConstructionQueue().getItems()) {
5263 if (spec.hasTag(Industries.TAG_INDUSTRY)) count++;
5264 }
5265 return count;
5266 }
5267
5268 public static int getNumImprovedIndustries(MarketAPI market) {
5269 int count = 0;
5270 for (Industry curr : market.getIndustries()) {
5271 if (curr.isImproved()) {
5272 count++;
5273 }
5274 }
5275 return count;
5276 }
5277
5278 public static int getNumStableLocations(StarSystemAPI system) {
5279 if (system == null) return 0;
5280 int count = system.getEntitiesWithTag(Tags.STABLE_LOCATION).size();
5281 count += system.getEntitiesWithTag(Tags.OBJECTIVE).size();
5282 for (SectorEntityToken e : system.getJumpPoints()) {
5283 if (e instanceof JumpPointAPI) {
5284 JumpPointAPI jp = (JumpPointAPI) e;
5285 if (jp.isWormhole()) count++;
5286 }
5287 }
5288 return count;
5289 }
5290
5292 for (Industry curr : market.getIndustries()) {
5293 if (curr.getSpec().hasTag(Industries.TAG_POPULATION)) continue;
5294
5295 if (curr.isBuilding() && !curr.isUpgrading()) {
5296 return curr;
5297 }
5298 }
5299 return null;
5300 }
5301
5302 public static Color getRelColor(float rel) {
5303 Color relColor = new Color(125,125,125,255);
5304 if (rel > 1) rel = 1;
5305 if (rel < -1) rel = -1;
5306
5307 if (rel > 0) {
5308 relColor = Misc.interpolateColor(relColor, Misc.getPositiveHighlightColor(), Math.max(0.15f, rel));
5309 } else if (rel < 0) {
5310 relColor = Misc.interpolateColor(relColor, Misc.getNegativeHighlightColor(), Math.max(0.15f, -rel));
5311 }
5312 return relColor;
5313 }
5314
5315 public static MusicPlayerPlugin musicPlugin = null;
5317 if (musicPlugin == null) {
5319 }
5320 return musicPlugin;
5321 }
5322
5323
5324
5325 public static String DANGER_LEVEL_OVERRIDE = "$dangerLevelOverride";
5326 public static int getDangerLevel(CampaignFleetAPI fleet) {
5329 }
5330
5332
5333 float playerStr = 0f;
5334 float fleetStr = 0f;
5335 for (FleetMemberAPI member : pf.getFleetData().getMembersListCopy()) {
5336 float strength = Misc.getMemberStrength(member, true, true, true);
5337 playerStr += strength;
5338 }
5339
5340 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
5341 float strength = Misc.getMemberStrength(member, true, true, true);
5342 fleetStr += strength;
5343 }
5344
5345 if (playerStr > fleetStr * 3f) return 1;
5346 if (playerStr > fleetStr * 1.5f) return 2;
5347 if (playerStr > fleetStr * 0.75f) return 3;
5348 if (playerStr > fleetStr * 0.33f) return 4;
5349 return 5;
5350 }
5351
5352
5353 public static float getHitGlowSize(float baseSize, float baseDamage, ApplyDamageResultAPI result) {
5354 if (result == null || baseDamage <= 0) return baseSize;
5355
5356 float sd = result.getDamageToShields() + result.getOverMaxDamageToShields();
5357 float ad = result.getTotalDamageToArmor();
5358 float hd = result.getDamageToHull();
5359 float ed = result.getEmpDamage();
5360 DamageType type = result.getType();
5361 return getHitGlowSize(baseSize, baseDamage, type, sd, ad, hd, ed);
5362 }
5363
5364
5365 public static float getHitGlowSize(float baseSize, float baseDamage, DamageType type, float sd, float ad, float hd, float ed) {
5366
5367 float minBonus = 0f;
5368 if (type == DamageType.KINETIC) {
5369 sd *= 0.5f;
5370 //if (sd > 0) minBonus = 0.1f;
5371 } else if (type == DamageType.HIGH_EXPLOSIVE) {
5372 ad *= 0.5f;
5373 if (ad > 0) minBonus = 0.1f;
5374 } else if (type == DamageType.FRAGMENTATION) {
5375 if (hd > 0) {
5376 minBonus = 0.2f * (hd / (hd + ad));
5377 }
5378 sd *= 2f;
5379 ad *= 2f;
5380 hd *= 2f;
5381 }
5382
5383 float totalDamage = sd + ad + hd;
5384 if (totalDamage <= 0) return baseSize;
5385
5386 // emp damage makes the hitglow normal-sized, but not bigger
5387 if (totalDamage < baseDamage) {
5388 totalDamage += ed;
5389 if (totalDamage > baseDamage) {
5390 totalDamage = baseDamage;
5391 }
5392 }
5393
5394 float minSize = 15f;
5395 float minMult = minSize / baseSize;
5396 minMult = Math.max(minMult, 0.67f + minBonus);
5397 if (minMult > 1) minMult = 1;
5398
5399 float mult = totalDamage / baseDamage;
5400 if (mult < minMult) mult = minMult;
5401
5402 float maxMult = 1.5f;
5403 if (mult > maxMult) mult = maxMult;
5404 //mult = maxMult;
5405 //mult = 1f;
5406 //System.out.println("Mult: " + mult);
5407 return baseSize * mult;
5408 }
5409
5410 public static int getNumEliteSkills(PersonAPI person) {
5411 int count = 0;
5412 for (SkillLevelAPI sl : person.getStats().getSkillsCopy()) {
5413 if (sl.getLevel() >= 2) count++;
5414 }
5415 return count;
5416 }
5417
5418
5419// public static void spawnExtraHitGlow(Object param, Vector2f loc, Vector2f vel, float intensity) {
5420// if (param instanceof DamagingProjectileAPI) {
5421// DamagingProjectileAPI proj = (DamagingProjectileAPI) param;
5422// ProjectileSpecAPI spec = proj.getProjectileSpec();
5423// if (spec != null) {
5424// CombatEngineAPI engine = Global.getCombatEngine();
5425// float base = spec.getHitGlowRadius();
5426// if (base == 0) base = spec.getLength() * 1.0f;
5427// float size = base * (1f + 1f * intensity) * 0.5f;
5428// if (size < 20) return;
5429//
5430// Color color = Misc.interpolateColor(spec.getFringeColor(), spec.getCoreColor(), 0.25f);
5431// engine.addHitParticle(loc, vel, size, 0.75f * intensity, color);
5432// }
5433// } else if (param instanceof BeamAPI) {
5434// BeamAPI beam = (BeamAPI) param;
5435// CombatEngineAPI engine = Global.getCombatEngine();
5436// float size = beam.getHitGlowRadius() * (1f + intensity) * 0.5f;
5437// if (size < 20) return;
5438//
5439// Color color = Misc.interpolateColor(beam.getFringeColor(), beam.getCoreColor(), 0.25f);
5440// engine.addHitParticle(loc, vel, size, 0.75f * intensity, color);
5441// }
5442// }
5443
5444 public static String MENTORED = "$mentored";
5445 public static boolean isMentored(PersonAPI person) {
5446 return person.getMemoryWithoutUpdate().is(MENTORED, true);
5447 }
5448
5449 public static void setMentored(PersonAPI person, boolean mentored) {
5450 person.getMemoryWithoutUpdate().set(MENTORED, mentored);
5451 }
5452
5453 public static final String IS_MERCENARY = "$isMercenary";
5454 public static boolean isMercenary(PersonAPI person) {
5455 return person != null && person.getMemoryWithoutUpdate().is(IS_MERCENARY, true);
5456 }
5457
5458 public static final String MERCENARY_HIRE_TIMESTAMP = "$mercHireTS";
5462
5463 public static float getMercDaysSinceHired(PersonAPI person) {
5466 }
5467
5468 public static void setMercenary(PersonAPI person, boolean mercenary) {
5469 person.getMemoryWithoutUpdate().set(IS_MERCENARY, mercenary);
5470 }
5471
5472 public static final String CAPTAIN_UNREMOVABLE = "$captain_unremovable";
5473 public static boolean isUnremovable(PersonAPI person) {
5474 //if (true) return true;
5475 return person != null && person.getMemoryWithoutUpdate().is(CAPTAIN_UNREMOVABLE, true);
5476 }
5477
5478 public static void setUnremovable(PersonAPI person, boolean unremovable) {
5479 person.getMemoryWithoutUpdate().set(CAPTAIN_UNREMOVABLE, unremovable);
5480 }
5481
5482 public static final String KEEP_CAPTAIN_ON_SHIP_RECOVERY = "$keep_captain_on_ship_recovery";
5483 public static boolean isKeepOnShipRecovery(PersonAPI person) {
5484 return person != null && person.getMemoryWithoutUpdate().is(KEEP_CAPTAIN_ON_SHIP_RECOVERY, true);
5485 }
5486
5487 public static void setKeepOnShipRecovery(PersonAPI person, boolean keepOnRecovery) {
5489 }
5490
5491 public static boolean isAutomated(MutableShipStatsAPI stats) {
5492 if (stats == null) return false;
5493 return isAutomated(stats.getFleetMember());
5494
5495 }
5496 public static boolean isAutomated(FleetMemberAPI member) {
5497 return member != null && member.getVariant() != null && isAutomated(member.getVariant());
5498 }
5499 public static boolean isAutomated(ShipVariantAPI variant) {
5500 return variant != null && (variant.hasHullMod(HullMods.AUTOMATED) ||
5501 variant.hasTag(Tags.AUTOMATED) ||
5502 (variant.getHullSpec() != null && variant.getHullSpec().hasTag(Tags.AUTOMATED)));
5503 }
5504 public static boolean isAutomated(ShipAPI ship) {
5505 if (ship == null) return false;
5506 return isAutomated(ship.getVariant());
5507 }
5508
5509
5510 public static String RECOVERY_TAGS_KEY = "$core_recoveryTags";
5511 @SuppressWarnings("unchecked")
5512 public static Set<String> getAllowedRecoveryTags() {
5513 Set<String> tags = (Set<String>) Global.getSector().getMemoryWithoutUpdate().get(RECOVERY_TAGS_KEY);
5514 if (tags == null) {
5515 tags = new HashSet<String>();
5517 }
5518 return tags;
5519 }
5520
5521 public static int MAX_PERMA_MODS = Global.getSettings().getInt("maxPermanentHullmods");
5522
5523 public static int getMaxPermanentMods(ShipAPI ship) {
5524 if (ship == null) return 0;
5526 }
5527
5529 if (member == null) return 0;
5530 PersonAPI prev = member.getFleetCommanderForStats();
5532 fake.setStats(stats);
5533 member.setFleetCommanderForStats(fake, null);
5535 member.setFleetCommanderForStats(prev, null);
5536 return num;
5537 }
5538
5539
5540 public static float getBuildInBonusXP(HullModSpecAPI mod, HullSize size) {
5541 //float threshold = Global.getSettings().getBonusXP("permModNoBonusXPOPThreshold");
5542
5543 float fraction = 0f;
5544 //float cost = 0f;
5545 switch (size) {
5546 case CAPITAL_SHIP:
5547 fraction = Global.getSettings().getBonusXP("permModCapital");
5548 //cost = mod.getCapitalCost();
5549 break;
5550 case CRUISER:
5551 fraction = Global.getSettings().getBonusXP("permModCruiser");
5552 //cost = mod.getCruiserCost();
5553 break;
5554 case DESTROYER:
5555 fraction = Global.getSettings().getBonusXP("permModDestroyer");
5556 //cost = mod.getDestroyerCost();
5557 break;
5558 case FRIGATE:
5559 fraction = Global.getSettings().getBonusXP("permModFrigate");
5560 //cost = mod.getFrigateCost();
5561 break;
5562 }
5563
5564 //float max = Global.getSettings().getBonusXP("permModMaxBonusXP");
5565
5566// float fraction = 0f;
5567// if (threshold > 0) {
5568// fraction = max * (1f - cost / threshold);
5569// if (fraction < 0f) fraction = 0f;
5570// if (fraction > 1f) fraction = 1f;
5571// }
5572
5573// MutableCharacterStatsAPI stats = Global.getSector().getPlayerStats();
5574// fraction += stats.getDynamic().getMod(Stats.BUILD_IN_BONUS_XP_MOD).computeEffective(0);
5575 if (fraction < 0f) fraction = 0f;
5576 if (fraction > 1f) fraction = 1f;
5577 return fraction;
5578 }
5579
5580 public static int getOPCost(HullModSpecAPI mod, HullSize size) {
5581 switch (size) {
5582 case CAPITAL_SHIP:
5583 return mod.getCapitalCost();
5584 case CRUISER:
5585 return mod.getCruiserCost();
5586 case DESTROYER:
5587 return mod.getDestroyerCost();
5588 case FRIGATE:
5589 return mod.getFrigateCost();
5590 }
5591 return mod.getFrigateCost();
5592 }
5593
5594 public static boolean isSpecialMod(ShipVariantAPI variant, HullModSpecAPI spec) {
5595// if (spec.getId().equals(HullMods.ANDRADA_MODS)) {
5596// return true;fwewefwefe
5597// }
5598 if (spec.isHidden()) return false;
5599 if (spec.isHiddenEverywhere()) return false;
5600 if (spec.hasTag(Tags.HULLMOD_DMOD)) return false;
5601 if (!variant.getPermaMods().contains(spec.getId())) return false;
5602 if (variant.getHullSpec().getBuiltInMods().contains(spec.getId())) return false;
5603 if (!variant.getSMods().contains(spec.getId())) return false;
5604
5605 return true;
5606 }
5607
5608 public static boolean hasSModdableBuiltIns(ShipVariantAPI variant) {
5609 if (!CAN_SMOD_BUILT_IN || variant == null) return false;
5610 int num = 0;
5611 for (String id : variant.getHullMods()) {
5613 if (spec.isHidden()) continue;
5614 if (spec.isHiddenEverywhere()) continue;
5615 if (spec.hasTag(Tags.HULLMOD_DMOD)) continue;
5616 if (variant.getHullSpec().isBuiltInMod(id) &&
5617 spec.getEffect().hasSModEffect() && !spec.getEffect().isSModEffectAPenalty() &&
5618 !variant.getSModdedBuiltIns().contains(id)) {
5619 num++;
5620 }
5621 }
5622 return num > 0;
5623 }
5624 public static int getCurrSpecialMods(ShipVariantAPI variant) {
5625 if (variant == null) return 0;
5626 int num = 0;
5627 for (String id : variant.getHullMods()) {
5629 if (!isSpecialMod(variant, spec)) continue;
5630// if (spec.isHidden()) continue;
5631// if (spec.isHiddenEverywhere()) continue;
5632// if (spec.hasTag(Tags.HULLMOD_DMOD)) continue;
5633// if (!variant.getPermaMods().contains(spec.getId())) continue;
5634 num++;
5635 }
5636 return num;
5637 }
5638
5639 public static List<HullModSpecAPI> getCurrSpecialModsList(ShipVariantAPI variant) {
5640 List<HullModSpecAPI> result = new ArrayList<HullModSpecAPI>();
5641 if (variant == null) return result;
5642 int num = 0;
5643 for (String id : variant.getHullMods()) {
5645 if (!isSpecialMod(variant, spec)) continue;
5646 result.add(spec);
5647 }
5648 return result;
5649 }
5650
5651 public static boolean isSlowMoving(CampaignFleetAPI fleet) {
5652 return fleet.getCurrBurnLevel() <= getGoSlowBurnLevel(fleet);
5653 }
5654
5655
5656
5657 //public static float MAX_SNEAK_BURN_LEVEL = Global.getSettings().getFloat("maxSneakBurnLevel");
5658 public static float SNEAK_BURN_MULT = Global.getSettings().getFloat("sneakBurnMult");
5659
5660 public static int getGoSlowBurnLevel(CampaignFleetAPI fleet) {
5661// if (fleet.isPlayerFleet()) {
5662// System.out.println("fewfewfe");
5663// }
5665 //int burn = (int)Math.round(MAX_SNEAK_BURN_LEVEL + bonus);
5666 //int burn = (int)Math.round(fleet.getFleetData().getMinBurnLevelUnmodified() * SNEAK_BURN_MULT);
5667 int burn = (int)Math.round(fleet.getFleetData().getMinBurnLevel() * SNEAK_BURN_MULT);
5668 burn += bonus;
5669 //burn = (int) Math.min(burn, fleet.getFleetData().getBurnLevel() - 1);
5670 return burn;
5671 }
5672
5673
5674 public static enum FleetMemberDamageLevel {
5675 LOW,
5676 MEDIUM,
5677 HIGH,
5678 }
5679
5680 public static void applyDamage(FleetMemberAPI member, Random random, FleetMemberDamageLevel level,
5681 boolean withCRDamage, String crDamageId, String crDamageReason,
5682 boolean withMessage, TextPanelAPI textPanel,
5683 String messageText) {
5684 float damageMult = 1f;
5685 switch (level) {
5686 case LOW:
5687 damageMult = 3f;
5688 break;
5689 case MEDIUM:
5690 damageMult = 10f;
5691 break;
5692 case HIGH:
5693 damageMult = 20f;
5694 break;
5695 }
5696 applyDamage(member, random, damageMult, withCRDamage, crDamageId, crDamageReason,
5697 withMessage, textPanel, messageText);
5698 }
5699
5700 public static void applyDamage(FleetMemberAPI member, Random random, float damageMult,
5701 boolean withCRDamage, String crDamageId, String crDamageReason,
5702 boolean withMessage, TextPanelAPI textPanel,
5703 String messageText) {
5704 if (random == null) random = Misc.random;
5705 damageMult *= 0.75f + random.nextFloat() * 0.5f;
5706
5707// float hitStrength = 0f;
5708// hitStrength += member.getHullSpec().getArmorRating() * 0.1f;
5709// hitStrength *= damageMult;
5710
5711 // hull damage going to be overridden by hullDamageFraction, anyway
5712 // so just want enough hitStrength to visibly damage the armor
5713 float hitStrength = member.getHullSpec().getArmorRating() * 2f;
5714
5715 float hullDamageFraction = 0.025f * damageMult;
5716 float max = 0.5f + random.nextFloat() * 0.1f;
5717 float min = 0.01f + random.nextFloat() * 0.04f;
5718 if (hullDamageFraction > max) hullDamageFraction = max;
5719 if (hullDamageFraction < min) hullDamageFraction = min;
5720
5721 if (hitStrength > 0) {
5722 float numHits = 3f;
5723 for (int i = 0; i < numHits; i++) {
5724 member.getStatus().applyDamage(hitStrength / numHits, hullDamageFraction / numHits);
5725 }
5726 if (member.getStatus().getHullFraction() < 0.01f) {
5727 member.getStatus().setHullFraction(0.01f);
5728 }
5729
5730 boolean isPF = member != null && member.getFleetData() != null &&
5731 member.getFleetData().getFleet() != null && member.getFleetData().getFleet().isPlayerFleet();
5732
5733 if (withCRDamage) {
5734 float crPerDep = member.getDeployCost();
5735 float currCR = member.getRepairTracker().getBaseCR();
5736 float crDamage = Math.min(currCR, crPerDep * 0.1f * damageMult);
5737 if (crDamage > 0) {
5738 if (isPF) {
5739 member.getRepairTracker().applyCREvent(-crDamage, crDamageId, crDamageReason);
5740 } else {
5741 member.getRepairTracker().applyCREvent(-crDamage, null, null);
5742 }
5743 }
5744 }
5745
5746 if (withMessage && isPF) {
5747 MessageIntel intel = new MessageIntel(messageText,
5749 intel.setIcon(Global.getSettings().getSpriteName("intel", "damage_report"));
5750
5751 if (textPanel != null) {
5753 } else {
5754 Global.getSector().getCampaignUI().addMessage(intel, MessageClickAction.REFIT_TAB, member);
5755 }
5756 }
5757 }
5758 }
5759
5760 public static float getBonusXPForRecovering(FleetMemberAPI member) {
5761 float ownedShip = Global.getSettings().getBonusXP("recoverOwnedShip");
5762 float threshold = Global.getSettings().getBonusXP("recoverNoBonusXPDeploymentPoints");
5763
5764 if (member.getOwner() == 0) {
5765 return ownedShip;
5766 }
5767
5768 float f = 1f - member.getDeploymentPointsCost() / threshold;
5769 if (f < 0) f = 0;
5770 if (f > 1) f = 1;
5771
5772 return f;
5773 }
5774
5775 public static float [] getBonusXPForScuttling(FleetMemberAPI member) {
5776 float points = 0f;
5777 float xp = 0f;
5779 //if (member.getId() != null && member.getId().equals(record.getMemberId())) {
5780 if (member == record.getMember() && record.getMember() != null) {
5781 points += record.getSPSpent();
5782 xp += record.getBonusXPFractionGained() * record.getSPSpent();
5783 }
5784 }
5785 if (points > 0) {
5786 return new float[] {points, 1f - xp/points};
5787 }
5788 return new float[] {0f, 0f};
5789 }
5790
5791 public static float getSpawnFPMult(CampaignFleetAPI fleet) {
5793 if (mult == 0) mult = 1f;
5794 return mult;
5795 }
5796
5797 public static void setSpawnFPMult(CampaignFleetAPI fleet, float mult) {
5799 }
5800
5801 public static boolean isDecentralized(FactionAPI faction) {
5802 return faction != null && faction.getCustomBoolean(Factions.CUSTOM_DECENTRALIZED);
5803 }
5804
5805 public static String getPersonalityName(PersonAPI person) {
5806 String personalityName = person.getPersonalityAPI().getDisplayName();
5807 if (person.isAICore()) {
5808 if (Personalities.RECKLESS.equals(person.getPersonalityAPI().getId())) {
5809 personalityName = "Fearless";
5810 }
5811 }
5812 return personalityName;
5813 }
5814
5815 public static String LAST_RAIDED_AT = "$lastRaidedAt";
5819
5820 public static float getDaysSinceLastRaided(MarketAPI market) {
5821 Long ts = market.getMemoryWithoutUpdate().getLong(LAST_RAIDED_AT);
5822 if (ts == null) return Float.MAX_VALUE;
5824 }
5825
5827 float currQty = com.getCombinedTradeModQuantity();
5828 int currMod = (int) com.getModValueForQuantity(currQty);
5829
5830 float quantityWithTX = com.getTradeMod().getModifiedValue() + quantity +
5831 Math.max(com.getTradeModPlus().getModifiedValue(), 0) +
5832 Math.min(com.getTradeModMinus().getModifiedValue(), 0);
5833
5834 int newMod = (int) com.getModValueForQuantity(quantityWithTX);
5835
5836 int diff = newMod - currMod;
5837
5838 return diff;
5839 }
5840
5841 public static void affectAvailabilityWithinReason(CommodityOnMarketAPI com, int quantity) {
5842 int units = computeEconUnitChangeFromTradeModChange(com, quantity);
5843 int maxUnits = Math.min(3, Math.max(com.getMaxDemand(), com.getMaxSupply()));
5844 if (Math.abs(units) > maxUnits) {
5845 int sign = (int) Math.signum(quantity);
5846 quantity = (int) Math.round(com.getQuantityForModValue(maxUnits));
5847 quantity *= sign;
5848 }
5849 com.addTradeMod("mod_" + Misc.genUID(), quantity, BaseSubmarketPlugin.TRADE_IMPACT_DAYS);
5850 }
5851
5852
5853 public static boolean isOpenlyPopulated(StarSystemAPI system) {
5854 for (MarketAPI market : Misc.getMarketsInLocation(system)) {
5855 if (!market.isHidden()) return true;
5856 }
5857 return false;
5858 }
5859
5860
5861 public static boolean hasAtLeastOneOfTags(Collection<String> tags, String ... other) {
5862 for (String tag : other) {
5863 if (tags.contains(tag)) return true;
5864 }
5865 return false;
5866 }
5867
5868
5869
5870// public static boolean isUnpopulatedPlanet(PlanetAPI planet) {
5871// if (planet.isStar() ||
5872// planet.getMarket() == null ||
5873// !planet.getMarket().isPlanetConditionMarketOnly()) {
5874// return false;
5875// }
5876// return true;
5877// }
5878
5879 public static boolean hasUnexploredRuins(MarketAPI market) {
5880 return market != null && market.isPlanetConditionMarketOnly() &&
5881 hasRuins(market) && !market.getMemoryWithoutUpdate().getBoolean("$ruinsExplored");
5882 }
5883 public static boolean hasRuins(MarketAPI market) {
5884 return market != null &&
5889 }
5890
5892 String id = getRuinsType(market);
5894 }
5895
5901 public static String getRuinsType(MarketAPI market) {
5902 if (market == null) return Conditions.RUINS_SCATTERED;
5908 }
5909
5910 public static boolean hasFarmland(MarketAPI market) {
5911 return market != null &&
5916 }
5917
5918
5919 public static String DEFEAT_TRIGGERS = "$defeatTriggers";
5920 public static void addDefeatTrigger(CampaignFleetAPI fleet, String trigger) {
5921 List<String> triggers = getDefeatTriggers(fleet, true);
5922 triggers.add(trigger);
5923 }
5924
5925 public static void removeDefeatTrigger(CampaignFleetAPI fleet, String trigger) {
5926 List<String> triggers = getDefeatTriggers(fleet, false);
5927 if (triggers != null) {
5928 triggers.remove(trigger);
5930 }
5931 }
5932
5933 @SuppressWarnings("unchecked")
5934 public static List<String> getDefeatTriggers(CampaignFleetAPI fleet, boolean createIfNecessary) {
5935 MemoryAPI mem = fleet.getMemoryWithoutUpdate();
5936 List<String> triggers = null;
5937 if (!mem.contains(DEFEAT_TRIGGERS)) {
5938 if (!createIfNecessary) return null;
5939 triggers = new ArrayList<String>();
5940 mem.set(DEFEAT_TRIGGERS, triggers);
5941 } else {
5942 triggers = (List<String>) mem.get(DEFEAT_TRIGGERS);
5943 }
5944 return triggers;
5945 }
5946
5948 List<String> triggers = getDefeatTriggers(fleet, false);
5949 if (triggers != null && triggers.isEmpty()) {
5950 MemoryAPI mem = fleet.getMemoryWithoutUpdate();
5952 }
5953 }
5954
5955 public static boolean shouldShowDamageFloaty(ShipAPI source, ShipAPI target) {
5956 if (target == null || !Global.getCombatEngine().getShips().contains(target)) {
5957 return false;
5958 }
5960 ShipAPI playerShip = engine.getPlayerShip();
5961
5962 boolean sourceIsPlayerShipWing = false;
5963 sourceIsPlayerShipWing = source != null && source.getWing() != null &&
5964 source.getWing().getSourceShip() == playerShip;
5965
5966 CombatEntityAPI followedEntity = engine.getCombatUI().getEntityToFollowV2();
5967 boolean showFloaty = target == playerShip || // this is the player's ship
5968 target == followedEntity || // getting video feed from this ship
5969 source == playerShip || // the damage came from the player's ship
5970 sourceIsPlayerShipWing ||
5971 target == playerShip.getShipTarget() || // the ship is the player ship's target
5972 engine.hasAttachedFloaty(target); // the ship already has a floaty on it, meaning the player is likely looking at it
5973 showFloaty = showFloaty && !target.isFighter(); // no floaties on fighters
5974 showFloaty = showFloaty && Global.getSettings().isShowDamageFloaties();
5975 return showFloaty;
5976 }
5977
5978//
5979// public static Vector2f cubeBezier(Vector2f p0, Vector2f p1, Vector2f p2, Vector2f p3, float t)
5980// {
5981// float r = 1f - t;
5982// float f0 = r * r * r;
5983// float f1 = r * r * t * 3;
5984// float f2 = r * t * t * 3;
5985// float f3 = t * t * t;
5986// return f0*p0 + f1*p1 + f2*p2 + f3*p3;
5987// }
5988
5989
5990// long memorySize = ((com.sun.management.OperatingSystemMXBean) ManagementFactory
5991// .getOperatingSystemMXBean()).getTotalPhysicalMemorySize();
5992 protected static Boolean canCheckVramNVIDIA = null;
5993 public static boolean canCheckVram() {
5994 if (canCheckVramNVIDIA == null) {
5995 String str = GL11.glGetString(GL11.GL_EXTENSIONS);
5996 if (str != null) {
5997 List<String> extensions = Arrays.asList(str.split(" "));
5998 canCheckVramNVIDIA = extensions.contains("GL_NVX_gpu_memory_info");
5999 //canCheckVramATI = extensions.contains("GL_ATI_meminfo");
6000 } else {
6001 canCheckVramNVIDIA = false;
6002 }
6003 }
6004 return true;
6005 }
6010 public static int getVramFreeKB() {
6011 if (canCheckVramNVIDIA) {
6012 return GL11.glGetInteger(NVXGpuMemoryInfo.GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX);
6013 } else {
6014 return GL11.glGetInteger(ATIMeminfo.GL_TEXTURE_FREE_MEMORY_ATI);
6015 }
6016 }
6017
6018 public static int getVramMaximumKB() {
6019 return GL11.glGetInteger(NVXGpuMemoryInfo.GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX);
6020 }
6021 public static int getVramDedicatedKB() {
6022 return GL11.glGetInteger(NVXGpuMemoryInfo.GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX);
6023 }
6024 public static int getVramUsedKB() {
6025 return getVramMaximumKB() - getVramFreeKB();
6026 }
6027
6028// public static void printExtensions() {
6029// String str = GL11.glGetString(GL11.GL_EXTENSIONS);
6030// System.out.println(str);
6031// }
6032
6033
6034 public static float IMPACT_VOLUME_MULT = Global.getSettings().getFloat("impactSoundVolumeMult");
6035
6036 public static void playSound(ApplyDamageResultAPI result, Vector2f loc, Vector2f vel,
6037 String lightShields, String solidShields, String heavyShields,
6038 String lightHull, String solidHull, String heavyHull
6039 ) {
6040 float shieldDam = result.getDamageToShields();
6041 float armorDam = result.getTotalDamageToArmor();
6042 float hullDam = result.getDamageToHull();
6043 float fluxDam = result.getEmpDamage();
6044
6045
6046 float totalDam = shieldDam + armorDam + hullDam;
6047 // if no damage, don't play sounds
6048 if (totalDam + fluxDam <= 0) return;
6049
6050 float vol = 1f;
6051
6052 float volMult = IMPACT_VOLUME_MULT;
6053
6054 // if shields were damaged, then ONLY shields were damaged
6055 if (shieldDam > 0) {
6056 String soundId = null;
6057 if (shieldDam < 70) {
6058 vol = shieldDam / 20f;
6059 if (vol > 1) vol = 1;
6060 soundId = lightShields;
6061 } else if (shieldDam < 200) {
6062 soundId = solidShields;
6063 } else {
6064 soundId = heavyShields;
6065 }
6066 if (soundId != null) {
6067 Global.getSoundPlayer().playSound(soundId, 1f, vol * volMult, loc, vel);
6068 }
6069 return;
6070 }
6071
6072 String soundId = null;
6073
6074 float physicalDam = armorDam + hullDam + fluxDam;
6075 //System.out.println(physicalDam);
6076 if (physicalDam < 5) {
6077 vol = physicalDam / 5f;
6078 if (vol > 1) vol = 1;
6079 soundId = lightHull;
6080 } else if (physicalDam < 40) {
6081 soundId = lightHull;
6082 } else if (physicalDam < 150) {
6083 soundId = solidHull;
6084 } else {
6085 soundId = heavyHull;
6086 }
6087
6088 if (soundId != null) {
6089 Global.getSoundPlayer().playSound(soundId, 1f, vol * volMult, loc, vel);
6090 }
6091 return;
6092 }
6093
6094
6095 public static float getShipWeight(ShipAPI ship) {
6096 return getShipWeight(ship, true);
6097 }
6098
6099 public static float getShipWeight(ShipAPI ship, boolean adjustForNonCombat) {
6100 if (ship.isDrone()) return 0.1f;
6101 boolean nonCombat = ship.isNonCombat(false);
6102 float weight = 0;
6103 switch (ship.getHullSize()) {
6104 case CAPITAL_SHIP: weight += 8; break;
6105 case CRUISER: weight += 4; break;
6106 case DESTROYER: weight += 2; break;
6107 case FRIGATE: weight += 1; break;
6108 case FIGHTER: weight += 1; break;
6109 }
6110 if (ship.getHullSpec().isPhase() && (ship.isFrigate() || ship.isDestroyer())) {
6111 weight += 2f;
6112 }
6113 if (nonCombat && adjustForNonCombat) weight *= 0.25f;
6114 if (ship.isDrone()) weight *= 0.1f;
6115 return weight;
6116 }
6117
6118 public static float getIncapacitatedTime(ShipAPI ship) {
6119 float incapTime = 0f;
6120 if (ship.getFluxTracker().isVenting()){
6121 incapTime = ship.getFluxTracker().getTimeToVent();
6122 } else if (ship.getFluxTracker().isOverloaded()) {
6123 incapTime = ship.getFluxTracker().getOverloadTimeRemaining();
6124 }
6125 return incapTime;
6126 }
6127
6130 return false;
6131 }
6134 if (avoidingPlayer && !fleet.isHostileTo(player)) return true;
6135
6137 if (fleeingFrom != null && fleeingFrom.isPlayerFleet()) {
6138 if (Misc.shouldNotWantRunFromPlayerEvenIfWeaker(fleet) && fleet.isHostileTo(player)) {
6139 return true;
6140 }
6141 }
6142 return false;
6143 }
6144
6150 public static boolean isPirateFaction(FactionAPI faction) {
6151 return faction != null &&
6153 //faction.getCustomBoolean(Factions.CUSTOM_MAKES_PIRATE_BASES);
6154 }
6155
6160 public static String getAOrAnFor(String word) {
6161 word = word.toLowerCase();
6162 for (String other : new String[] {"euler", "heir", "honest", "hono"}) {
6163 if (word.startsWith(other)) {
6164 return "an";
6165 }
6166 }
6167
6168 if (word.startsWith("hour") && !word.startsWith("houri")) {
6169 return "an";
6170 }
6171
6172 Pattern p;
6173 Matcher m;
6174
6175 for (String regex : new String[] { "^e[uw]", "^onc?e\b", "^uni([^nmd]|mo)", "^u[bcfhjkqrst][aeiou]"}) {
6176 p = Pattern.compile("(?is)" + regex + ".*");
6177 m = p.matcher(word);
6178 if (m.matches()) {
6179 return "a";
6180 }
6181 }
6182
6183 p = Pattern.compile("(?is)" + "^U[NK][AIEO]");
6184 m = p.matcher(word);
6185 if (m.matches()) {
6186 return "a";
6187 }
6188
6189 for (String letter : new String[] { "a", "e", "i", "o", "u" }) {
6190 if (word.startsWith(letter)) {
6191 return "an";
6192 }
6193 }
6194
6195 p = Pattern.compile("(?is)" + "^y(b[lor]|cl[ea]|fere|gg|p[ios]|rou|tt)" + ".*");
6196 m = p.matcher(word);
6197 if (m.matches()) {
6198 return "an";
6199 }
6200
6201 return "a";
6202 }
6203
6204
6205 public static void moveToMarket(PersonAPI person, MarketAPI destination, boolean alwaysAddToCommDirectory) {
6207 if (intel != null) {
6208 intel.relocateToMarket(destination, false);
6209 } else {
6210 boolean addToComms = alwaysAddToCommDirectory;
6211 boolean hidden = false;
6212 if (person.getMarket() != null) {
6213 MarketAPI market = person.getMarket();
6215 if (entry != null) {
6216 addToComms = true;
6217 hidden = entry.isHidden();
6218 }
6219 market.removePerson(person);
6220 market.getCommDirectory().removePerson(person);
6221 }
6222
6223 if (!destination.getPeopleCopy().contains(person)) {
6224 destination.addPerson(person);
6225 }
6226 person.setMarket(destination);
6227
6228 if (addToComms) {
6229 if (destination.getCommDirectory() != null &&
6230 destination.getCommDirectory().getEntryForPerson(person) == null) {
6231 destination.getCommDirectory().addPerson(person);
6232 if (hidden) {
6233 CommDirectoryEntryAPI entry = destination.getCommDirectory().getEntryForPerson(person);
6234 if (entry != null) {
6235 entry.setHidden(true);
6236 }
6237 }
6238 }
6239 }
6240 }
6241 }
6242
6243 public static void makeStoryCritical(String marketId, String reason) {
6244 makeStoryCritical(Global.getSector().getEconomy().getMarket(marketId), reason);
6245 }
6246 public static void makeStoryCritical(MarketAPI market, String reason) {
6247 makeStoryCritical(market.getMemoryWithoutUpdate(), reason);
6248 }
6249 public static void makeStoryCritical(MemoryAPI memory, String reason) {
6250 setFlagWithReason(memory, MemFlags.STORY_CRITICAL, reason, true, -1f);
6251 }
6252 public static void makeNonStoryCritical(MarketAPI market, String reason) {
6254 }
6255 public static void makeNonStoryCritical(MemoryAPI memory, String reason) {
6256 setFlagWithReason(memory, MemFlags.STORY_CRITICAL, reason, false, -1f);
6257 }
6258 public static boolean isStoryCritical(MarketAPI market) {
6259 return isStoryCritical(market.getMemoryWithoutUpdate());
6260 }
6261 public static boolean isStoryCritical(MemoryAPI memory) {
6262 return memory.getBoolean(MemFlags.STORY_CRITICAL);
6263 }
6264
6265
6272 public static boolean isInsignificant(CampaignFleetAPI fleet) {
6274 if (recentlyBeaten) return true;
6275
6277 if (pf == null) return true; // ??
6278 if (fleet.getAI() != null) {
6279 EncounterOption opt = fleet.getAI().pickEncounterOption(null, pf);
6280 if (opt == EncounterOption.DISENGAGE || opt == EncounterOption.HOLD_VS_STRONGER) {
6281 return true;
6282 }
6283 if (opt == EncounterOption.ENGAGE) {
6284 return false;
6285 }
6286 }
6287 int pfCount = pf.getFleetSizeCount();
6288 int otherCount = fleet.getFleetSizeCount();
6289
6290 return otherCount <= pfCount / 4;
6291 }
6292
6301 if (recentlyBeaten) return true;
6302 if (fleet.getFleetData() == null) return false;
6303
6304 float count = 0;
6305 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
6306 if (!member.isCivilian() && member.getHullSpec() != null) {
6307 switch (member.getHullSpec().getHullSize()) {
6308 case CAPITAL_SHIP: count += 4; break;
6309 case CRUISER: count += 3; break;
6310 case DESTROYER: count += 2; break;
6311 case FRIGATE: count += 1; break;
6312 }
6313 }
6314 }
6315
6317 float pfCount = 0;
6318 for (FleetMemberAPI member : pf.getFleetData().getMembersListCopy()) {
6319 if (!member.isCivilian() && member.getHullSpec() != null) {
6320 switch (member.getHullSpec().getHullSize()) {
6321 case CAPITAL_SHIP: pfCount += 4; break;
6322 case CRUISER: pfCount += 3; break;
6323 case DESTROYER: pfCount += 2; break;
6324 case FRIGATE: pfCount += 1; break;
6325 }
6326 }
6327 }
6328
6329 if (count > pfCount * 0.67f) {
6330 return true;
6331 }
6332
6333 if (isInsignificant(fleet) && count <= 6) return true;
6334
6335 return false;
6336 }
6337
6338 public static float findKth(float[] arr, int k) {
6339 if (arr == null || arr.length <= k || k < 0) {
6340 return -1;
6341 }
6342
6343 int from = 0;
6344 int to = arr.length - 1;
6345
6346 while (from < to) {
6347 int r = from;
6348 int w = to;
6349 float mid = arr[(r + w) / 2];
6350
6351 while (r < w) {
6352 if (arr[r] >= mid) {
6353 float tmp = arr[w];
6354 arr[w] = arr[r];
6355 arr[r] = tmp;
6356 w--;
6357 } else {
6358 r++;
6359 }
6360 }
6361
6362 if (arr[r] > mid) r--;
6363
6364 if (k <= r) {
6365 to = r;
6366 } else {
6367 from = r + 1;
6368 }
6369 }
6370
6371 return arr[k];
6372 }
6373
6374 public static float getAdjustedBaseRange(float base, ShipAPI ship, WeaponAPI weapon) {
6375 if (ship == null || weapon == null) return base;
6376 float flat = CombatListenerUtil.getWeaponBaseRangeFlatMod(ship, weapon);
6377 float percent = CombatListenerUtil.getWeaponBaseRangePercentMod(ship, weapon);
6378 float mult = CombatListenerUtil.getWeaponBaseRangeMultMod(ship, weapon);
6379 return (base * (1f + percent/100f) + flat) * mult;
6380 }
6381
6382
6383 public static Vector2f bezier(Vector2f p0, Vector2f p1, Vector2f p2, float t) {
6384 if (t < 0) t = 0;
6385 if (t > 1) t = 1;
6386 Vector2f r = new Vector2f();
6387 r.x = (1f - t) * (1f - t) * p0.x + 2f * (1f - t) * t * p1.x + t * t * p2.x;
6388 r.y = (1f - t) * (1f - t) * p0.y + 2f * (1f - t) * t * p1.y + t * t * p2.y;
6389 return r;
6390 }
6391
6392 public static Vector2f bezierCubic(Vector2f p0, Vector2f p1, Vector2f p2, Vector2f p3, float t) {
6393 if (t < 0) t = 0;
6394 if (t > 1) t = 1;
6395 Vector2f r = new Vector2f();
6396
6397 r.x = (1f - t) * (1f - t) * (1f -t) * p0.x +
6398 3f * (1f - t) * (1f - t) * t * p1.x +
6399 3f * (1f - t) * t * t * p2.x +
6400 t * t * t * p3.x;
6401 r.y = (1f - t) * (1f - t) * (1f -t) * p0.y +
6402 3f * (1f - t) * (1f - t) * t * p1.y +
6403 3f * (1f - t) * t * t * p2.y +
6404 t * t * t * p3.y;
6405 return r;
6406 }
6407
6408 public static boolean isInsideSlipstream(Vector2f loc, float radius) {
6409 return isInsideSlipstream(loc, radius, Global.getSector().getHyperspace());
6410 }
6411 public static boolean isInsideSlipstream(Vector2f loc, float radius, LocationAPI location) {
6412 if (location == null) return false;
6413 for (CampaignTerrainAPI ter : location.getTerrainCopy()) {
6414 if (ter.getPlugin() instanceof SlipstreamTerrainPlugin2) {
6415 SlipstreamTerrainPlugin2 plugin = (SlipstreamTerrainPlugin2) ter.getPlugin();
6416 if (plugin.containsPoint(loc, radius)) {
6417 return true;
6418 }
6419 }
6420 }
6421 return false;
6422 }
6423 public static boolean isInsideSlipstream(SectorEntityToken entity) {
6424 if (entity == null || entity.getContainingLocation() == null) return false;
6426 if (ter.getPlugin() instanceof SlipstreamTerrainPlugin2) {
6427 SlipstreamTerrainPlugin2 plugin = (SlipstreamTerrainPlugin2) ter.getPlugin();
6428 if (plugin.containsEntity(entity)) {
6429 return true;
6430 }
6431 }
6432 }
6433 return false;
6434 }
6435
6436 public static boolean isOutsideSector(Vector2f loc) {
6437 float sw = Global.getSettings().getFloat("sectorWidth");
6438 float sh = Global.getSettings().getFloat("sectorHeight");
6439 return loc.x < -sw/2f || loc.x > sw/2f || loc.y < -sh/2f || loc.y > sh/2f;
6440 }
6441
6442 public static boolean crossesAnySlipstream(LocationAPI location, Vector2f from, Vector2f to) {
6443 for (CampaignTerrainAPI ter : location.getTerrainCopy()) {
6444 if (ter.getPlugin() instanceof SlipstreamTerrainPlugin2) {
6445 SlipstreamTerrainPlugin2 plugin = (SlipstreamTerrainPlugin2) ter.getPlugin();
6446 List<SlipstreamSegment> segments = plugin.getSegments();
6447 int skip = Math.max(20, segments.size() / 10);
6448 for (int i = 0; i < segments.size(); i += skip) {
6449 int i2 = i + skip;
6450 if (i2 > segments.size() - skip/2) i2 = segments.size() - 1;
6451 if (i2 >= segments.size()) i2 = segments.size() - 1;
6452
6453 if (i2 <= i) break;
6454
6455 Vector2f p = intersectSegments(segments.get(i).loc, segments.get(i2).loc, from, to);
6456 if (p != null) return true;
6457 }
6458 }
6459 }
6460 return false;
6461 }
6462
6463 public static void computeCoreWorldsExtent() {
6464 Vector2f min = new Vector2f();
6465 Vector2f max = new Vector2f();
6466 for (StarSystemAPI curr : Global.getSector().getStarSystems()) {
6467 if (curr.hasTag(Tags.THEME_CORE)) {
6468 Vector2f loc = curr.getLocation();
6469 min.x = Math.min(min.x, loc.x);
6470 min.y = Math.min(min.y, loc.y);
6471 max.x = Math.max(max.x, loc.x);
6472 max.y = Math.max(max.y, loc.y);
6473 }
6474 }
6475
6476 Vector2f core = Vector2f.add(min, max, new Vector2f());
6477 core.scale(0.5f);
6478
6479 Global.getSector().getMemoryWithoutUpdate().set("$coreWorldsMin", min);
6480 Global.getSector().getMemoryWithoutUpdate().set("$coreWorldsMax", max);
6481 Global.getSector().getMemoryWithoutUpdate().set("$coreWorldsCenter", core);
6482 }
6483
6484 public static Vector2f getCoreMin() {
6485 Vector2f v = (Vector2f) Global.getSector().getMemoryWithoutUpdate().get("$coreWorldsMin");
6486 if (v == null) {
6488 v = (Vector2f) Global.getSector().getMemoryWithoutUpdate().get("$coreWorldsMin");
6489 }
6490 return v;
6491 }
6492 public static Vector2f getCoreMax() {
6493 Vector2f v = (Vector2f) Global.getSector().getMemoryWithoutUpdate().get("$coreWorldsMax");
6494 if (v == null) {
6496 v = (Vector2f) Global.getSector().getMemoryWithoutUpdate().get("$coreWorldsMax");
6497 }
6498 return v;
6499 }
6500 public static Vector2f getCoreCenter() {
6501 Vector2f v = (Vector2f) Global.getSector().getMemoryWithoutUpdate().get("$coreWorldsCenter");
6502 if (v == null) {
6504 v = (Vector2f) Global.getSector().getMemoryWithoutUpdate().get("$coreWorldsCenter");
6505 }
6506 return v;
6507 }
6508
6509
6510// public static void createColonyStatic(MarketAPI market)
6511// {
6512// String factionId = Factions.PLAYER;
6513//
6514// market.setSize(3);
6515// market.addCondition("population_3");
6516// market.setFactionId(factionId);
6517// market.setPlanetConditionMarketOnly(false);
6518//
6519// if (market.hasCondition(Conditions.DECIVILIZED))
6520// {
6521// market.removeCondition(Conditions.DECIVILIZED);
6522// market.addCondition(Conditions.DECIVILIZED_SUBPOP);
6523// }
6524// market.addIndustry(Industries.POPULATION);
6525//
6526// market.addSubmarket(Submarkets.LOCAL_RESOURCES);
6527// market.addSubmarket(Submarkets.SUBMARKET_STORAGE);
6528//
6529// market.setSurveyLevel(MarketAPI.SurveyLevel.FULL);
6530// for (MarketConditionAPI cond : market.getConditions())
6531// {
6532// cond.setSurveyed(true);
6533// }
6534//
6535// Global.getSector().getEconomy().addMarket(market, true);
6536// market.getPrimaryEntity().setFaction(factionId);
6537//
6538// market.setPlayerOwned(true);
6539// market.addIndustry(Industries.SPACEPORT);
6540// SubmarketAPI storage = market.getSubmarket(Submarkets.SUBMARKET_STORAGE);
6541// if (storage != null)
6542// ((StoragePlugin)storage.getPlugin()).setPlayerPaidToUnlock(true);
6543// }
6544
6545
6546 public static boolean turnTowardsPointV2(MissileAPI missile, Vector2f point, float angVel) {
6547 float desiredFacing = getAngleInDegrees(missile.getLocation(), point);
6548 return turnTowardsFacingV2(missile, desiredFacing, angVel);
6549 }
6550
6551 public static boolean turnTowardsFacingV2(MissileAPI missile, float desiredFacing, float relativeAngVel) {
6552
6553 float turnVel = missile.getAngularVelocity() - relativeAngVel;
6554 float absTurnVel = Math.abs(turnVel);
6555
6556 float turnDecel = missile.getEngineController().getTurnDeceleration();
6557 // v t - 0.5 a t t = dist
6558 // dv = a t; t = v / a
6559 float decelTime = absTurnVel / turnDecel;
6560 float decelDistance = absTurnVel * decelTime - 0.5f * turnDecel * decelTime * decelTime;
6561
6562 float facingAfterNaturalDecel = missile.getFacing() + Math.signum(turnVel) * decelDistance;
6563 float diffWithEventualFacing = getAngleDiff(facingAfterNaturalDecel, desiredFacing);
6564 float diffWithCurrFacing = getAngleDiff(missile.getFacing(), desiredFacing);
6565
6566 if (diffWithEventualFacing > 1f) {
6567 float turnDir = getClosestTurnDirection(missile.getFacing(), desiredFacing);
6568 if (Math.signum(turnVel) == Math.signum(turnDir)) {
6569 if (decelDistance > diffWithCurrFacing) {
6570 turnDir = -turnDir;
6571 }
6572 }
6573 if (turnDir < 0) {
6575 } else if (turnDir >= 0) {
6577 } else {
6578 return false;
6579 }
6580 }
6581 return false;
6582 }
6583
6584 public static boolean turnTowardsFacingV2(ShipAPI ship, float desiredFacing, float relativeAngVel) {
6585
6586 float turnVel = ship.getAngularVelocity() - relativeAngVel;
6587 float absTurnVel = Math.abs(turnVel);
6588
6589 float turnDecel = ship.getEngineController().getTurnDeceleration();
6590 // v t - 0.5 a t t = dist
6591 // dv = a t; t = v / a
6592 float decelTime = absTurnVel / turnDecel;
6593 float decelDistance = absTurnVel * decelTime - 0.5f * turnDecel * decelTime * decelTime;
6594
6595 float facingAfterNaturalDecel = ship.getFacing() + Math.signum(turnVel) * decelDistance;
6596 float diffWithEventualFacing = getAngleDiff(facingAfterNaturalDecel, desiredFacing);
6597 float diffWithCurrFacing = getAngleDiff(ship.getFacing(), desiredFacing);
6598
6599 if (diffWithEventualFacing > 1f) {
6600 float turnDir = getClosestTurnDirection(ship.getFacing(), desiredFacing);
6601 if (Math.signum(turnVel) == Math.signum(turnDir)) {
6602 if (decelDistance > diffWithCurrFacing) {
6603 turnDir = -turnDir;
6604 }
6605 }
6606 if (turnDir < 0) {
6607 ship.giveCommand(ShipCommand.TURN_RIGHT, null, 0);
6608 } else if (turnDir >= 0) {
6609 ship.giveCommand(ShipCommand.TURN_LEFT, null, 0);
6610 } else {
6611 return false;
6612 }
6613 }
6614 return false;
6615 }
6616
6617 public static int getUntrustwortyCount() {
6619 return count;
6620 }
6621
6622 public static void incrUntrustwortyCount() {
6623 int count = getUntrustwortyCount();
6625 }
6626
6627 public static ReputationAdjustmentResult adjustRep(PersonAPI person, float delta, TextPanelAPI text) {
6628 return adjustRep(person, delta, null, text);
6629 }
6630 public static ReputationAdjustmentResult adjustRep(PersonAPI person, float delta, RepLevel limit, TextPanelAPI text) {
6631 return adjustRep(person, delta, limit, text, true, true);
6632 }
6633 public static ReputationAdjustmentResult adjustRep(PersonAPI person, float delta, RepLevel limit, TextPanelAPI text,
6634 boolean addMessageOnNoChange, boolean withMessage) {
6635 CustomRepImpact impact = new CustomRepImpact();
6636 impact.delta = delta;
6637 if (limit != null) {
6638 impact.limit = limit;
6639 }
6641 new RepActionEnvelope(RepActions.CUSTOM,
6642 impact, null, text, addMessageOnNoChange, withMessage),
6643 person);
6644 }
6645
6646 public static ReputationAdjustmentResult adjustRep(String factionId, float delta, TextPanelAPI text) {
6647 return adjustRep(factionId, delta, null, text);
6648 }
6649 public static ReputationAdjustmentResult adjustRep(String factionId, float delta, RepLevel limit, TextPanelAPI text) {
6650 return adjustRep(factionId, delta, limit, text, true, true);
6651 }
6652 public static ReputationAdjustmentResult adjustRep(String factionId, float delta, RepLevel limit, TextPanelAPI text,
6653 boolean addMessageOnNoChange, boolean withMessage) {
6654 CustomRepImpact impact = new CustomRepImpact();
6655 impact.delta = delta;
6656 if (limit != null) {
6657 impact.limit = limit;
6658 }
6660 new RepActionEnvelope(RepActions.CUSTOM,
6661 impact, null, text, addMessageOnNoChange, withMessage),
6662 factionId);
6663 }
6664
6665 public static String getHullSizeStr(HullSize size) {
6666 switch (size) {
6667 case CAPITAL_SHIP: return "Capital";
6668 case CRUISER: return "Cruiser";
6669 case DESTROYER: return "Destroyer";
6670 case FIGHTER: return "Fighter";
6671 case FRIGATE: return "Frigate";
6672 }
6673 return "Unknown";
6674 }
6675
6676 public static float getColorDist(Color one, Color two) {
6677 float r = Math.abs(one.getRed() - two.getRed());
6678 float g = Math.abs(one.getGreen() - two.getGreen());
6679 float b = Math.abs(one.getBlue() - two.getBlue());
6680 float a = Math.abs(one.getAlpha() - two.getAlpha());
6681
6682 return (float) Math.sqrt(r * r + g * g + b * b + a * a);
6683 }
6684
6685
6686 public static float FRINGE_THRESHOLD = 0.7f;
6687
6688 public static boolean isFringe(SectorEntityToken entity) {
6689 return isFringe(entity.getLocationInHyperspace());
6690 }
6691 public static boolean isFringe(StarSystemAPI system) {
6692 return isFringe(system.getLocation());
6693 }
6694 public static boolean isFringe(Vector2f loc) {
6695 return getFringeFactor(loc) > FRINGE_THRESHOLD;
6696 }
6697 public static float getFringeFactor(Vector2f loc) {
6698 float sw = Global.getSettings().getFloat("sectorWidth");
6699 float sh = Global.getSettings().getFloat("sectorHeight");
6700 float mult = 0.8f;
6701 //float mult = 1f;
6702 float a = sw * 0.5f * mult;
6703 float b = sh * 0.5f * mult;
6704 float x = loc.x;
6705 float y = loc.y;
6706
6707 float f = (x * x) / (a * a) + (y * y)/ (b * b);
6708 if (f < 0) f = 0;
6709 if (f > 1) f = 1;
6710 return f;
6711 }
6712
6713 public static boolean isHiddenBase(MarketAPI market) {
6715 }
6716
6717
6721
6722
6723
6724 public static enum CatalogEntryType {
6725 PLANET("P"),
6726 GIANT("G"),
6727 STAR("S"),
6728 BLACK_HOLE("B");
6729
6730 public String suffix;
6731 private CatalogEntryType(String suffix) {
6732 this.suffix = suffix;
6733 }
6734
6735 }
6736 public static String genEntityCatalogId(CatalogEntryType type) {
6737 return genEntityCatalogId(-1, -1, -1, type);
6738 }
6739 public static String genEntityCatalogId(int cycleOverride, int monthOverride, int dayOverride, CatalogEntryType type) {
6740 return genEntityCatalogId(null, cycleOverride, monthOverride, dayOverride, type);
6741 }
6742 public static String genEntityCatalogId(String firstChar, int cycleOverride, int monthOverride, int dayOverride, CatalogEntryType type) {
6743
6744 String base = "Perseus";
6745
6746 int cycle = Global.getSector().getClock().getCycle();
6747 cycle += 3000;
6748 if (cycleOverride > 0) cycle = cycleOverride;
6749
6750 int month = Global.getSector().getClock().getMonth();
6751 if (monthOverride > 0) month = monthOverride;
6752 int day = Global.getSector().getClock().getDay();
6753 if (dayOverride > 0) day = dayOverride;
6754
6755 String s1 = Integer.toHexString(cycle).toUpperCase();
6756
6757 Random r = StarSystemGenerator.random;
6758
6759 String s0 = Integer.toHexString(r.nextInt(16)).toUpperCase();
6760 if (firstChar != null) s0 = firstChar;
6761
6762 String s2 = Integer.toHexString(month).toUpperCase();
6763 String s3 = Integer.toHexString(day).toUpperCase();
6764
6765// s1 = "" + cycle;
6766// s0 = "";
6767
6768 while (s1.length() < 3) s1 = "0" + s1;
6769 while (s3.length() < 2) s3 = "0" + s3;
6770
6771 return base + " " + s0 + s1 + "-" + s2 + s3 + type.suffix;
6772 }
6773
6774 public static float getAveragePlanetRadius(PlanetSpecAPI spec) {
6775 if (spec.isStar()) {
6776 StarGenDataSpec starData = (StarGenDataSpec)
6778 if (starData != null) {
6779 return (starData.getMinRadius() + starData.getMaxRadius()) * 0.5f;
6780 }
6781 }
6782
6783 PlanetGenDataSpec planetData = (PlanetGenDataSpec)
6785 if (planetData != null) {
6786 return (planetData.getMinRadius() + planetData.getMaxRadius()) * 0.5f;
6787 }
6788
6789 return 200f;
6790 }
6791
6792 public static boolean canPlanetTypeRollHabitable(PlanetSpecAPI spec) {
6794 }
6795
6796 public static boolean canPlanetTypeRollCondition(PlanetSpecAPI spec, String id) {
6799
6802
6803 if (genData != null && hab != null) {
6804 String planetCat = genData.getCategory();
6805 if (hab.hasMultiplier(planetCat) && hab.getMultiplier(planetCat) > 0) {
6806 return true;
6807 }
6808 }
6809 return false;
6810 }
6811
6812 public static int getMaxMarketSize(MarketAPI market) {
6813 return (int)Math.round(market.getStats().getDynamic().getMod(
6815 }
6816
6817 public static float countEnemyWeightInArc(ShipAPI ship, float dir, float arc, float maxRange, boolean ignoreFightersAndModules) {
6818 return countEnemyWeightInArcAroundLocation(ship, ship.getLocation(), dir, arc, maxRange, null, ignoreFightersAndModules);
6819 }
6820 public static float countEnemyWeightInArcAroundLocation(ShipAPI ship, Vector2f loc, float dir, float arc, float maxRange,
6821 ShipAPI ignore, boolean ignoreFightersAndModules) {
6822 return countEnemyWeightInArcAroundLocation(ship.getOwner(), loc, dir, arc, maxRange, ignore, ignoreFightersAndModules, false);
6823 }
6824 public static float countEnemyWeightInArcAroundLocation(int owner, Vector2f loc,
6825 float dir, float arc, float maxRange,
6826 ShipAPI ignore, boolean ignoreFightersAndModules, boolean awareOnly) {
6828 List<ShipAPI> ships = engine.getAllShips();
6829
6830 float weight = 0;
6831 for (ShipAPI other : ships) {
6832 if (ignoreFightersAndModules) {
6833 if (other.isFighter()) continue;
6834 if (other.isStationModule()) continue;
6835 }
6836 if (other.isFighter() && other.getWing() != null && !other.getWing().isLeader(other)) continue;
6837 if (other.isHulk()) continue;
6838 if (other.isDrone()) continue;
6839 if (other.isShuttlePod()) continue;
6840 if (other.getOwner() == 100) continue;
6841 if (owner == other.getOwner()) continue;
6842 //if (other.isRetreating()) continue;
6843 if (other.controlsLocked()) continue;
6844 if (other == ignore) continue;
6845 if (awareOnly && !engine.isAwareOf(owner, other)) continue;
6846
6847 float dist = getDistance(loc, other.getLocation());
6848 if (dist > maxRange) continue;
6849
6850 if (arc >= 360f || isInArc(dir, arc, loc, other.getLocation())) {
6851 weight += getShipWeight(other);
6852 //weight += other.getHullSize().ordinal();
6853 }
6854 }
6855 return weight;
6856 }
6857
6858 public static float [] getFloatArray(String key) {
6859 try {
6860 JSONArray arr = Global.getSettings().getJSONArray(key);
6861 float [] result = new float [arr.length()];
6862 for (int i = 0; i < arr.length(); i++) {
6863 result[i] = (float) arr.optDouble(i, 0f);
6864 }
6865 return result;
6866 } catch (JSONException e) {
6867 return null;
6868 }
6869 }
6870
6871 public static enum WeaponSkinType {
6872 UNDER,
6873 TURRET,
6874 HARDPOINT,
6875 TURRET_GLOW,
6876 HARDPOINT_GLOW,
6877 TURRET_BARRELS,
6878 HARDPOINT_BARRELS,
6879 }
6880
6881 public static SpriteAPI getWeaponSkin(ShipAPI ship, String weaponId, WeaponSkinType type) {
6882 String cat = null;
6883 SpriteAPI skin = null;
6884 if (ship.getOwner() == 0 || ship.getOriginalOwner() == 0) {
6885 cat = "weaponSkinsPlayerOnly";
6886 skin = getWeaponSkin(cat, weaponId, ship, type);
6887 }
6888 if (skin != null) return skin;
6889
6890 cat = "weaponSkinsPlayerAndNPC";
6891 skin = getWeaponSkin(cat, weaponId, ship, type);
6892 return skin;
6893 }
6894
6895
6896 public static SpriteAPI getWeaponSkin(String cat, String weaponId, ShipAPI ship, WeaponSkinType type) {
6897
6898 String exclude = "weaponSkinsExcludeFromSharing";
6899 String style = ship.getHullStyleId();
6900
6901 List<String> skins = Global.getSettings().getSpriteKeys(cat);
6902 Set<String> noSharing = new LinkedHashSet<String>(Global.getSettings().getSpriteKeys(exclude));
6903
6904 List<SpriteAPI> matching = new ArrayList<SpriteAPI>();
6905 String keyForHull = weaponId + ":" + style + ":" + type.name();
6906 for (String key : skins) {
6907 if (key.equals(keyForHull)) {
6908 return Global.getSettings().getSprite(cat, key);
6909 }
6910 if (key.startsWith(weaponId) && key.endsWith(type.name()) && !noSharing.contains(key)) {
6911 matching.add(Global.getSettings().getSprite(cat, key));
6912 }
6913 }
6914
6915 if (!matching.isEmpty()) {
6916 SpriteAPI best = null;
6917 float minDist = Float.MAX_VALUE;
6918
6919 for (SpriteAPI curr : matching) {
6920 float dist = Misc.getColorDist(ship.getSpriteAPI().getAverageBrightColor(), curr.getAverageBrightColor());
6921 if (dist < minDist) {
6922 best = curr;
6923 minDist = dist;
6924 }
6925 }
6926 return best;
6927 }
6928 return null;
6929 }
6930}
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
static SettingsAPI getSettings()
Definition Global.java:57
static SoundPlayerAPI getSoundPlayer()
Definition Global.java:49
static FactoryAPI getFactory()
Definition Global.java:41
static Logger getLogger(Class c)
Definition Global.java:32
static CombatEngineAPI getCombatEngine()
Definition Global.java:69
static SectorAPI getSector()
Definition Global.java:65
void modifyFlat(String source, float value)
float computeEffective(float baseValue)
static float getWeaponBaseRangeMultMod(ShipAPI ship, WeaponAPI weapon)
static float getWeaponBaseRangeFlatMod(ShipAPI ship, WeaponAPI weapon)
static float getWeaponBaseRangePercentMod(ShipAPI ship, WeaponAPI weapon)
boolean reportPlayerAwareOfPlanet(String planetId, boolean withSave)
static int getNumDMods(ShipVariantAPI variant)
static float getShipQuality(MarketAPI market, String factionId)
static final String CUSTOM_ALLOWS_TRANSPONDER_OFF_TRADE
Definition Factions.java:54
static final String MEMORY_KEY_MAKE_HOSTILE_TO_PLAYER_TRADE_FLEETS
static final String MEMORY_KEY_SAW_PLAYER_WITH_TRANSPONDER_ON
static final String MEMORY_KEY_SAW_PLAYER_WITH_TRANSPONDER_OFF
static final String MEMORY_KEY_MAKE_HOSTILE_TO_ALL_TRADE_FLEETS
static final String MEMORY_KEY_PLAYER_HOSTILE_ACTIVITY_NEAR_MARKET
static final String MEMORY_KEY_RECENTLY_DEFEATED_BY_PLAYER
static final String NAVIGATION_PENALTY_MULT
Definition Stats.java:77
static final String MOVE_SLOW_SPEED_BONUS_MOD
Definition Stats.java:75
static final String INDIVIDUAL_SHIP_RECOVERY_MOD
Definition Stats.java:200
static final String OFFICER_SHIP_RECOVERY_MOD
Definition Stats.java:103
static final String MAX_PERMANENT_HULLMODS_MOD
Definition Stats.java:173
static final String VARIANT_ALWAYS_RECOVERABLE
Definition Tags.java:78
static final String VARIANT_UNBOARDABLE
Definition Tags.java:79
static final String FADING_OUT_AND_EXPIRING
Definition Tags.java:341
void relocateToMarket(MarketAPI other, boolean withIntelUpdate)
static void generateConditionsForPlanet(GenContext context, PlanetAPI planet)
static void addCommodityGainText(String commodityId, int quantity, TextPanelAPI text)
static void makeAwareOfConditionsOn(MarketAPI market)
static float getFleetwideTotalStat(CampaignFleetAPI fleet, String dynamicMemberStatId)
Definition Misc.java:2770
static void setDefenderOverride(SectorEntityToken entity, DefenderDataOverride override)
Definition Misc.java:3629
static void setWarningBeaconColors(SectorEntityToken beacon, Color glow, Color ping)
Definition Misc.java:3741
static long getNameBasedSeed(SectorEntityToken entity)
Definition Misc.java:4155
static boolean isStoryCritical(MarketAPI market)
Definition Misc.java:6258
static String getJoined(String joiner, String ... strings)
Definition Misc.java:882
static Color getStoryOptionColor()
Definition Misc.java:782
static MarketConditionSpecAPI getRuinsSpec(MarketAPI market)
Definition Misc.java:5891
static float getBonusXPForRecovering(FleetMemberAPI member)
Definition Misc.java:5760
static float getBurnMultForTerrain(CampaignFleetAPI fleet)
Definition Misc.java:4976
static void setUnremovable(PersonAPI person, boolean unremovable)
Definition Misc.java:5478
static float getDistanceSq(Vector2f v1, Vector2f v2)
Definition Misc.java:613
static Color getRelColor(float rel)
Definition Misc.java:5302
static Color getTextColor()
Definition Misc.java:839
static float getGenericRollingAverageFactor()
Definition Misc.java:862
static ShipAPI findClosestShipEnemyOf(ShipAPI ship, Vector2f locFromForSorting, HullSize smallestToNote, float maxRange, boolean considerShipRadius)
Definition Misc.java:2497
static float getBuildInBonusXP(HullModSpecAPI mod, HullSize size)
Definition Misc.java:5540
static SectorEntityToken addWarningBeacon(SectorEntityToken center, OrbitGap gap, String beaconTag)
Definition Misc.java:5152
static String getStringWithTokenReplacement(String format, SectorEntityToken entity, Map< String, MemoryAPI > memoryMap)
Definition Misc.java:3104
static List< StarSystemAPI > getSystemsInRange(SectorEntityToken from, Set< StarSystemAPI > exclude, boolean nonEmpty, float maxRange)
Definition Misc.java:3654
static boolean isHiddenBase(MarketAPI market)
Definition Misc.java:6713
static int getMaxOfficers(CampaignFleetAPI fleet)
Definition Misc.java:5219
static String getDGSCredits(float num)
Definition Misc.java:1390
static int getNumStableLocations(StarSystemAPI system)
Definition Misc.java:5278
static String genEntityCatalogId(int cycleOverride, int monthOverride, int dayOverride, CatalogEntryType type)
Definition Misc.java:6739
static void applyDamage(FleetMemberAPI member, Random random, float damageMult, boolean withCRDamage, String crDamageId, String crDamageReason, boolean withMessage, TextPanelAPI textPanel, String messageText)
Definition Misc.java:5700
static void cleanBuffer(Buffer toBeDestroyed)
Definition Misc.java:2730
static MarketAPI getSourceMarket(CampaignFleetAPI fleet)
Definition Misc.java:2162
static String getWithDGS(float num)
Definition Misc.java:1381
static SectorEntityToken addNebulaFromPNG(String image, float centerX, float centerY, LocationAPI location, String category, String key, int tilesWide, int tilesHigh, String terrainType, StarAge age)
Definition Misc.java:1770
static DecimalFormat format
Definition Misc.java:1365
static boolean isPatrol(CampaignFleetAPI fleet)
Definition Misc.java:4761
static int getShippingCapacity(MarketAPI market, boolean inFaction)
Definition Misc.java:5019
static boolean turnTowardsPointV2(MissileAPI missile, Vector2f point, float angVel)
Definition Misc.java:6546
static JumpPointAPI findNearestJumpPointThatCouldBeExitedFrom(SectorEntityToken entity)
Definition Misc.java:3388
static Color getButtonTextColor()
Definition Misc.java:842
static Color genColor(Color min, Color max, Random random)
Definition Misc.java:1273
static float getSpawnChanceMult(Vector2f locInHyper)
Definition Misc.java:2180
static int getNumImprovedIndustries(MarketAPI market)
Definition Misc.java:5268
static boolean hasHeavyIndustry(MarketAPI market)
Definition Misc.java:5049
static void makeNonHostileToFaction(CampaignFleetAPI fleet, String factionId, float dur)
Definition Misc.java:1485
static void playSound(ApplyDamageResultAPI result, Vector2f loc, Vector2f vel, String lightShields, String solidShields, String heavyShields, String lightHull, String solidHull, String heavyHull)
Definition Misc.java:6036
static void renderQuad(float x, float y, float width, float height, Color color, float alphaMult)
Definition Misc.java:1842
static void removeDefeatTrigger(CampaignFleetAPI fleet, String trigger)
Definition Misc.java:5925
static void makeImportant(MemoryAPI memory, String reason, float dur)
Definition Misc.java:4067
static float countEnemyWeightInArcAroundLocation(ShipAPI ship, Vector2f loc, float dir, float arc, float maxRange, ShipAPI ignore, boolean ignoreFightersAndModules)
Definition Misc.java:6820
static List< StarSystemAPI > getSystemsWithPlayerColonies(boolean includeNonPlayerFaction)
Definition Misc.java:996
static float getDistanceLY(SectorEntityToken from, SectorEntityToken to)
Definition Misc.java:602
static float getShipWeight(ShipAPI ship)
Definition Misc.java:6095
static PlanetAPI getPulsarInSystem(StarSystemAPI system)
Definition Misc.java:3677
static float GATE_FUEL_COST_MULT
Definition Misc.java:220
static float getMercDaysSinceHired(PersonAPI person)
Definition Misc.java:5463
static Vector2f getPointAtRadius(Vector2f from, float r, Random random)
Definition Misc.java:704
static FleetInflater getInflater(CampaignFleetAPI fleet, Object params)
Definition Misc.java:4246
static Map< Class, Method > cleanCache
Definition Misc.java:2728
static int getDangerLevel(CampaignFleetAPI fleet)
Definition Misc.java:5326
static SectorEntityToken addNebulaFromPNG(String image, float centerX, float centerY, LocationAPI location, String category, String key, int tilesWide, int tilesHigh, StarAge age)
Definition Misc.java:1764
static CampaignEventPlugin startEvent(CampaignEventTarget eventTarget, String eventId, Object params)
Definition Misc.java:761
static float countEnemyWeightInArcAroundLocation(int owner, Vector2f loc, float dir, float arc, float maxRange, ShipAPI ignore, boolean ignoreFightersAndModules, boolean awareOnly)
Definition Misc.java:6824
static float getDistanceFromArc(float direction, float arc, float angle)
Definition Misc.java:3564
static Map< String, Integer > variantToFPCache
Definition Misc.java:4438
static AICoreOfficerPlugin getAICoreOfficerPlugin(String commodityId)
Definition Misc.java:4230
static List< MarketAPI > getFactionMarkets(String factionId)
Definition Misc.java:1008
static float getStorageShipValue(MarketAPI market)
Definition Misc.java:4333
static int getNumEliteSkills(PersonAPI person)
Definition Misc.java:5410
static Vector2f getInterceptPoint(SectorEntityToken from, SectorEntityToken to, float maxSpeedFrom)
Definition Misc.java:3954
static Vector2f closestPointOnSegmentToPoint(Vector2f p1, Vector2f p2, Vector2f p3)
Definition Misc.java:1889
static Vector2f getUnitVectorAtDegreeAngle(float degrees)
Definition Misc.java:1196
static String lcFirst(String str)
Definition Misc.java:565
static void setMentored(PersonAPI person, boolean mentored)
Definition Misc.java:5449
static long getSalvageSeed(SectorEntityToken entity, boolean nonRandom)
Definition Misc.java:4132
static Color getStoryDarkColor()
Definition Misc.java:773
static float getStorageFeeFraction()
Definition Misc.java:4286
static float getColorDist(Color one, Color two)
Definition Misc.java:6676
static List< CampaignFleetAPI > getNearbyFleets(SectorEntityToken from, float maxDist)
Definition Misc.java:3747
static boolean isInAbyss(Vector2f loc)
Definition Misc.java:2324
static WeightedRandomPicker< String > createStringPicker(Random random, Object ... params)
Definition Misc.java:3718
static float getFleetwideTotalMod(CampaignFleetAPI fleet, String dynamicMemberStatId, float base, ShipAPI ship)
Definition Misc.java:2782
static List< String > getDefeatTriggers(CampaignFleetAPI fleet, boolean createIfNecessary)
Definition Misc.java:5934
static int computeTotalShutdownRefund(MarketAPI market)
Definition Misc.java:5104
static boolean isWarFleet(CampaignFleetAPI fleet)
Definition Misc.java:4779
static boolean isRaider(CampaignFleetAPI fleet)
Definition Misc.java:4776
static ReputationAdjustmentResult adjustRep(String factionId, float delta, RepLevel limit, TextPanelAPI text)
Definition Misc.java:6649
static void unsetAll(String prefix, String memKey, MemoryAPI memory)
Definition Misc.java:1341
static List< StarSystemAPI > getAbyssalSystems()
Definition Misc.java:2339
static boolean isInsideSlipstream(Vector2f loc, float radius)
Definition Misc.java:6408
static void setAsteroidSource(SectorEntityToken asteroid, AsteroidSource source)
Definition Misc.java:2267
static SectorEntityToken addDebrisField(LocationAPI loc, DebrisFieldParams params, Random random)
Definition Misc.java:3262
static float FP_TO_GROUND_RAID_STR_APPROX_MULT
Definition Misc.java:227
static boolean isSameCargo(CargoAPI baseOne, CargoAPI baseTwo)
Definition Misc.java:3773
static float getEconomyInterval()
Definition Misc.java:858
static List< FleetMemberAPI > getSnapshotMembersLost(CampaignFleetAPI fleet)
Definition Misc.java:748
static List< MarketAPI > getMarketsInLocation(LocationAPI location, String factionId)
Definition Misc.java:936
static float approach(float curr, float dest, float minSpeed, float diffSpeedMult, float amount)
Definition Misc.java:2719
static float getClosestTurnDirection(Vector2f one, Vector2f two)
Definition Misc.java:2152
static Color getMissileMountColor()
Definition Misc.java:812
static String ucFirst(String str)
Definition Misc.java:559
static float getMemberStrength(FleetMemberAPI member)
Definition Misc.java:4844
static boolean isMercenary(PersonAPI person)
Definition Misc.java:5454
static boolean isFastStartExplorer()
Definition Misc.java:2277
static float getDesiredMoveDir(CampaignFleetAPI fleet)
Definition Misc.java:4191
static Color getNegativeHighlightColor()
Definition Misc.java:802
static Object getSalvageSpecial(SectorEntityToken entity)
Definition Misc.java:3644
static float getSizeNum(HullSize size)
Definition Misc.java:1322
static Map< String, String > variantToHullCache
Definition Misc.java:4440
static Vector2f bezier(Vector2f p0, Vector2f p1, Vector2f p2, float t)
Definition Misc.java:6383
static void addHitGlow(LocationAPI location, Vector2f loc, Vector2f vel, float size, float dur, Color color)
Definition Misc.java:4990
static CargoAPI getStorageCargo(MarketAPI market)
Definition Misc.java:4307
static float getAngleInDegreesStrict(Vector2f from, Vector2f to)
Definition Misc.java:1120
static String getHullSizeStr(HullSize size)
Definition Misc.java:6665
static void moveToMarket(PersonAPI person, MarketAPI destination, boolean alwaysAddToCommDirectory)
Definition Misc.java:6205
static float getStorageCargoValue(MarketAPI market)
Definition Misc.java:4323
static void setColor(Color color, float alphaMult)
Definition Misc.java:4013
static void makeImportant(PersonAPI person, String reason)
Definition Misc.java:4057
static float getIncapacitatedTime(ShipAPI ship)
Definition Misc.java:6118
static String getHullIdForVariantId(String variantId)
Definition Misc.java:4442
static boolean shouldShowDamageFloaty(ShipAPI source, ShipAPI target)
Definition Misc.java:5955
static float getRoundedValueFloat(float value)
Definition Misc.java:661
static int computeShutdownRefund(MarketAPI market, Industry industry)
Definition Misc.java:5118
static void setColor(Color color)
Definition Misc.java:4006
static void setAbandonedStationMarket(String marketId, SectorEntityToken station)
Definition Misc.java:4177
static String getStringForDays(int days)
Definition Misc.java:1608
static Vector2f getSystemJumpPointHyperExitLocation(JumpPointAPI jp)
Definition Misc.java:4645
static float getDistance(Vector3f v1, Vector3f v2)
Definition Misc.java:1711
static boolean doesMarketHaveMissionImportantPeopleOrIsMarketMissionImportant(SectorEntityToken entity)
Definition Misc.java:4029
static boolean areSegmentsCoincident(Vector2f a1, Vector2f a2, Vector2f b1, Vector2f b2)
Definition Misc.java:2079
static float getHitGlowSize(float baseSize, float baseDamage, DamageType type, float sd, float ad, float hd, float ed)
Definition Misc.java:5365
static boolean hasOrbitalStation(MarketAPI market)
Definition Misc.java:5059
static void makeHostileToFaction(CampaignFleetAPI fleet, String factionId, float dur)
Definition Misc.java:1496
static SurveyLevel getMinSystemSurveyLevel(StarSystemAPI system)
Definition Misc.java:2828
static void genFractalNoise(Random random, float[][] noise, int x1, int y1, int x2, int y2, int iter, float spikes)
Definition Misc.java:2675
static List< MarketAPI > getFactionMarkets(FactionAPI faction, String econGroup)
Definition Misc.java:971
static Random getRandom(long seed, int level)
Definition Misc.java:2973
static Color setAlpha(Color color, int alpha)
Definition Misc.java:1316
static String getJoined(String joiner, List< String > strings)
Definition Misc.java:879
static void giveStandardReturnToSourceAssignments(CampaignFleetAPI fleet, boolean withClear)
Definition Misc.java:3846
static void removeRadioChatter(MarketAPI market)
Definition Misc.java:4923
static void setPrevSalvageSpecial(SectorEntityToken entity, Object data)
Definition Misc.java:3640
static String DEFEAT_TRIGGERS
Definition Misc.java:5919
static Color FLOATY_ARMOR_DAMAGE_COLOR
Definition Misc.java:214
static boolean isAutomated(MutableShipStatsAPI stats)
Definition Misc.java:5491
static Vector2f pickLocationNotNearPlayer(LocationAPI where, Vector2f from, float minDist)
Definition Misc.java:2210
static void makeStoryCritical(MemoryAPI memory, String reason)
Definition Misc.java:6249
static String getTokenReplaced(String in, SectorEntityToken entity)
Definition Misc.java:4399
static List< HullModSpecAPI > getCurrSpecialModsList(ShipVariantAPI variant)
Definition Misc.java:5639
static float getDistance(float x1, float y1, float x2, float y2)
Definition Misc.java:618
static void makeImportant(SectorEntityToken entity, String reason)
Definition Misc.java:4051
static ShipAPI findClosestShipTo(ShipAPI ship, Vector2f locFromForSorting, HullSize smallestToNote, float maxRange, boolean considerShipRadius, boolean allowHulks, FindShipFilter filter)
Definition Misc.java:2526
static void fadeInOutAndExpire(final SectorEntityToken entity, final float in, final float dur, final float out)
Definition Misc.java:3163
static boolean isKeepOnShipRecovery(PersonAPI person)
Definition Misc.java:5483
static CampaignFleetAPI getStationBaseFleet(SectorEntityToken station)
Definition Misc.java:4599
static Pair< SectorEntityToken, CampaignFleetAPI > getNearestStationInSupportRange(CampaignFleetAPI from)
Definition Misc.java:4789
static Vector2f rotateAroundOrigin(Vector2f v, float angle)
Definition Misc.java:1205
static CustomCampaignEntityAPI addCargoPods(LocationAPI where, Vector2f loc)
Definition Misc.java:3245
static Vector2f closestPointOnLineToPoint(Vector2f p1, Vector2f p2, Vector2f p3)
Definition Misc.java:1877
static String genEntityCatalogId(String firstChar, int cycleOverride, int monthOverride, int dayOverride, CatalogEntryType type)
Definition Misc.java:6742
static void increaseMarketHostileTimeout(MarketAPI market, float days)
Definition Misc.java:4911
static boolean isAutomated(ShipAPI ship)
Definition Misc.java:5504
static float MAX_OFFICER_LEVEL
Definition Misc.java:239
static String getStarId(PlanetAPI planet)
Definition Misc.java:2795
static boolean turnTowardsFacingV2(MissileAPI missile, float desiredFacing, float relativeAngVel)
Definition Misc.java:6551
static void setAllPlanetsSurveyed(StarSystemAPI system, boolean setRuinsExplored)
Definition Misc.java:2892
static float[] getBonusXPForScuttling(FleetMemberAPI member)
Definition Misc.java:5775
static Color getStoryBrightColor()
Definition Misc.java:776
static float getAbyssalDepth(SectorEntityToken entity, boolean uncapped)
Definition Misc.java:2354
static int getGoSlowBurnLevel(CampaignFleetAPI fleet)
Definition Misc.java:5660
static PulsarBeamTerrainPlugin getPulsarFor(PlanetAPI star)
Definition Misc.java:2401
static void addSurveyDataFor(PlanetAPI planet, TextPanelAPI text)
Definition Misc.java:2984
static Object getPrevSalvageSpecial(SectorEntityToken entity)
Definition Misc.java:3647
static float getShipWeight(ShipAPI ship, boolean adjustForNonCombat)
Definition Misc.java:6099
static boolean isActiveModule(ShipAPI ship)
Definition Misc.java:4632
static float getCampaignShipScaleMult(HullSize size)
Definition Misc.java:3696
static final Vector2f ZERO
Definition Misc.java:249
static final String D_HULL_SUFFIX
Definition Misc.java:3552
static StabilizeMarketPlugin getStabilizeMarketPlugin(MarketAPI market)
Definition Misc.java:4240
static float getFleetwideTotalMod(CampaignFleetAPI fleet, String dynamicMemberStatId, float base)
Definition Misc.java:2779
static HullModSpecAPI getMod(String id)
Definition Misc.java:3560
static ReputationAdjustmentResult adjustRep(PersonAPI person, float delta, TextPanelAPI text)
Definition Misc.java:6627
static CampaignFleetAPI getStationBaseFleet(MarketAPI market)
Definition Misc.java:4590
static final boolean shouldConvertFromStub(LocationAPI containingLocation, Vector2f location)
Definition Misc.java:3423
static boolean isStoryCritical(MemoryAPI memory)
Definition Misc.java:6261
static String getAgoStringForTimestamp(long timestamp)
Definition Misc.java:1526
static float getMarketSizeProgress(MarketAPI market)
Definition Misc.java:4270
static String getAtLeastStringForDays(int days)
Definition Misc.java:1586
static boolean isFastStartMerc()
Definition Misc.java:2280
static float DISSIPATION_PER_VENT
Definition Misc.java:197
static List< StarSystemAPI > getPlayerSystems(boolean includeNonPlayerFaction)
Definition Misc.java:993
static boolean isAutomated(ShipVariantAPI variant)
Definition Misc.java:5499
static boolean isInsideBlackHole(CampaignFleetAPI fleet, boolean includeEventHorizon)
Definition Misc.java:2359
static void incrUntrustwortyCount()
Definition Misc.java:6622
static Industry getSpaceport(MarketAPI market)
Definition Misc.java:5187
static float getAbyssalDepthOfPlayer(boolean uncapped)
Definition Misc.java:2348
static float computeAngleSpan(float radius, float range)
Definition Misc.java:2709
static boolean isFringe(SectorEntityToken entity)
Definition Misc.java:6688
static JumpPointAPI findNearestJumpPoint(SectorEntityToken from)
Definition Misc.java:3536
static Vector2f getVector(JSONObject json, String arrayKey, int index)
Definition Misc.java:2618
static float computeAngleRadius(float angle, float range)
Definition Misc.java:2714
static JumpPointAPI getDistressJumpPoint(StarSystemAPI system)
Definition Misc.java:3803
static List< StarSystemAPI > getNearbyStarSystems(SectorEntityToken token, float maxRangeLY)
Definition Misc.java:1045
static void giveStandardReturnToSourceAssignments(CampaignFleetAPI fleet)
Definition Misc.java:3836
static Vector2f pickHyperLocationNotNearPlayer(Vector2f from, float minDist)
Definition Misc.java:2193
static boolean playerHasStorageAccess(MarketAPI market)
Definition Misc.java:4262
static CargoAPI getLocalResourcesCargo(MarketAPI market)
Definition Misc.java:4314
static boolean isBusy(CampaignFleetAPI fleet)
Definition Misc.java:4558
static float countEnemyWeightInArc(ShipAPI ship, float dir, float arc, float maxRange, boolean ignoreFightersAndModules)
Definition Misc.java:6817
static void makeNonStoryCritical(MemoryAPI memory, String reason)
Definition Misc.java:6255
static SectorEntityToken findNearestPlanetTo(SectorEntityToken entity, boolean requireGasGiant, boolean allowStars)
Definition Misc.java:3404
static final String KEEP_CAPTAIN_ON_SHIP_RECOVERY
Definition Misc.java:5482
static void makeNotLowRepImpact(CampaignFleetAPI fleet, String reason)
Definition Misc.java:1520
static void addCreditsMessage(String format, int credits)
Definition Misc.java:4639
static List< CampaignFleetAPI > getFleetsInOrNearSystem(StarSystemAPI system)
Definition Misc.java:926
static final int OWNER_PLAYER
Definition Misc.java:211
static void wiggle(Vector2f v, float max)
Definition Misc.java:2231
static Color getBasePlayerColor()
Definition Misc.java:833
static FactionCommissionIntel getCommissionIntel()
Definition Misc.java:2432
static float getHitGlowSize(float baseSize, float baseDamage, ApplyDamageResultAPI result)
Definition Misc.java:5353
static void normalizeNoise(float[][] noise)
Definition Misc.java:2625
static boolean isDecentralized(FactionAPI faction)
Definition Misc.java:5801
static boolean isShipRecoverable(FleetMemberAPI member, CampaignFleetAPI recoverer, boolean own, boolean useOfficerRecovery, float chanceMult)
Definition Misc.java:3317
static List< CampaignFleetAPI > getVisibleFleets(SectorEntityToken from, boolean includeSensorContacts)
Definition Misc.java:3759
static Color getGrayColor()
Definition Misc.java:826
static String DANGER_LEVEL_OVERRIDE
Definition Misc.java:5325
static void initConditionMarket(PlanetAPI planet)
Definition Misc.java:3576
static String colorsToString(List< Color > colors)
Definition Misc.java:3507
static void cleanUpMissionMemory(MemoryAPI memory, String prefix)
Definition Misc.java:4088
static DecimalFormat getFormat()
Definition Misc.java:1366
static boolean hasRuins(MarketAPI market)
Definition Misc.java:5883
static void fadeAndExpire(SectorEntityToken entity)
Definition Misc.java:3133
static Vector2f getVector(JSONObject json, String arrayKey)
Definition Misc.java:2588
static String getAOrAnFor(String word)
Definition Misc.java:6160
static void addDefeatTrigger(CampaignFleetAPI fleet, String trigger)
Definition Misc.java:5920
static String getAndJoined(String ... strings)
Definition Misc.java:875
static AsteroidSource getAsteroidSource(SectorEntityToken asteroid)
Definition Misc.java:2261
static int getNumIndustries(MarketAPI market)
Definition Misc.java:5248
static List< OfficerDataAPI > getMercs(CampaignFleetAPI fleet)
Definition Misc.java:5233
static void setSeen(MarketAPI market, TextPanelAPI text, boolean withNotification)
Definition Misc.java:3069
static Map< Class, Method > cleanerCache
Definition Misc.java:2727
static float getShieldedCargoFraction(CampaignFleetAPI fleet)
Definition Misc.java:1247
static void adjustRep(float repChangeFaction, RepLevel limit, String factionId, float repChangePerson, RepLevel personLimit, PersonAPI person, TextPanelAPI text)
Definition Misc.java:3884
static void addHitGlow(LocationAPI location, Vector2f loc, Vector2f vel, float size, Color color)
Definition Misc.java:4986
static List< MarketAPI > findNearbyLocalMarkets(SectorEntityToken token, float maxDist, MarketFilter filter)
Definition Misc.java:1165
static float getFuelPerDay(CampaignFleetAPI fleet, float burnLevel)
Definition Misc.java:1676
static int getVramDedicatedKB()
Definition Misc.java:6021
static String getRuinsType(MarketAPI market)
Definition Misc.java:5901
static boolean isBetween(float one, float two, float check)
Definition Misc.java:1232
static StarSystemAPI getNearestStarSystem(SectorEntityToken token)
Definition Misc.java:1075
static void makeStoryCritical(String marketId, String reason)
Definition Misc.java:6243
static String getStrengthDesc(float strAdjustedFP)
Definition Misc.java:5027
static boolean CAN_SMOD_BUILT_IN
Definition Misc.java:190
static MarketAPI findNearestLocalMarketWithSameFaction(final SectorEntityToken token, float maxDist)
Definition Misc.java:1183
static boolean isSmuggler(CampaignFleetAPI fleet)
Definition Misc.java:4764
static float getDistance(Vector2f v1, Vector2f v2)
Definition Misc.java:608
static void clearDefeatTriggersIfNeeded(CampaignFleetAPI fleet)
Definition Misc.java:5947
static void computeCoreWorldsExtent()
Definition Misc.java:6463
static float findKth(float[] arr, int k)
Definition Misc.java:6338
static void setKeepOnShipRecovery(PersonAPI person, boolean keepOnRecovery)
Definition Misc.java:5487
static Color getDesignTypeColorDim(String designType)
Definition Misc.java:4940
static Vector2f intersectLines(Vector2f a1, Vector2f a2, Vector2f b1, Vector2f b2)
Definition Misc.java:1994
static void renderQuadAlpha(float x, float y, float width, float height, Color color, float alphaMult)
Definition Misc.java:3111
static boolean isFleetMadeHostileToFaction(CampaignFleetAPI fleet, FactionAPI faction)
Definition Misc.java:1508
static String getDHullId(ShipHullSpecAPI spec)
Definition Misc.java:3553
static Color getEnergyMountColor()
Definition Misc.java:815
static WeightedRandomPicker< String > createStringPicker(Object ... params)
Definition Misc.java:3714
static void makeHostileToAllTradeFleets(CampaignFleetAPI fleet)
Definition Misc.java:1481
static Vector2f bezierCubic(Vector2f p0, Vector2f p1, Vector2f p2, Vector2f p3, float t)
Definition Misc.java:6392
static float getAdminSalary(PersonAPI admin)
Definition Misc.java:4409
static Vector2f getCoreMin()
Definition Misc.java:6484
static float getAngleDiff(float from, float to)
Definition Misc.java:1716
static boolean isOpenlyPopulated(StarSystemAPI system)
Definition Misc.java:5853
static StarSystemAPI getNearbyStarSystem(SectorEntityToken token)
Definition Misc.java:1092
static List< Color > colorsFromString(String in)
Definition Misc.java:3518
static Color setBrightness(Color color, int brightness)
Definition Misc.java:5196
static Color getBrightPlayerColor()
Definition Misc.java:830
static float getDistance(SectorEntityToken from, SectorEntityToken to)
Definition Misc.java:599
static float getClosestTurnDirection(float facing, Vector2f from, Vector2f to)
Definition Misc.java:2128
static void applyDamage(FleetMemberAPI member, Random random, FleetMemberDamageLevel level, boolean withCRDamage, String crDamageId, String crDamageReason, boolean withMessage, TextPanelAPI textPanel, String messageText)
Definition Misc.java:5680
static void setAllPlanetsKnown(StarSystemAPI system)
Definition Misc.java:2878
static float getProfitMarginFlat()
Definition Misc.java:850
static boolean hasPulsar(StarSystemAPI system)
Definition Misc.java:2411
static StarSystemAPI getNearbyStarSystem(SectorEntityToken token, float maxRangeLY)
Definition Misc.java:1056
static float getShipQuality(MarketAPI market, String factionId)
Definition Misc.java:4508
static boolean isFringe(Vector2f loc)
Definition Misc.java:6694
static float getDays(float amount)
Definition Misc.java:4663
static Vector2f getPointWithinRadius(Vector2f from, float r, Random random)
Definition Misc.java:714
static long getSalvageSeed(SectorEntityToken entity)
Definition Misc.java:4129
static boolean isReversePolarity(SectorEntityToken entity)
Definition Misc.java:6718
static boolean isMentored(PersonAPI person)
Definition Misc.java:5445
static boolean isNear(SectorEntityToken entity, Vector2f hyperLoc)
Definition Misc.java:4656
static Vector2f getUnitVector(Vector2f from, Vector2f to)
Definition Misc.java:1191
static float getFleetRadiusTerrainEffectMult(CampaignFleetAPI fleet)
Definition Misc.java:4953
static void fadeAndExpire(final SectorEntityToken entity, final float seconds)
Definition Misc.java:3136
static float getFringeFactor(Vector2f loc)
Definition Misc.java:6697
static float getStorageTotalValue(MarketAPI market)
Definition Misc.java:4320
static boolean isHyperspaceAnchor(SectorEntityToken entity)
Definition Misc.java:4675
static MusicPlayerPlugin musicPlugin
Definition Misc.java:5315
static List< Token > tokenize(String string)
Definition Misc.java:425
static Color scaleAlpha(Color color, float factor)
Definition Misc.java:1309
static String getSurveyLevelString(SurveyLevel level, boolean withBrackets)
Definition Misc.java:3604
static void setFullySurveyed(MarketAPI market, TextPanelAPI text, boolean withNotification)
Definition Misc.java:3003
static boolean isOutsideSector(Vector2f loc)
Definition Misc.java:6436
static float getUnitsPerLightYear()
Definition Misc.java:846
static float getAbyssalDepth(Vector2f loc, boolean uncapped)
Definition Misc.java:2333
static boolean flagHasReason(MemoryAPI memory, String flagKey, String reason)
Definition Misc.java:1453
static AICoreAdminPlugin getAICoreAdminPlugin(String commodityId)
Definition Misc.java:4225
static float getOfficerSalary(PersonAPI officer, boolean mercenary)
Definition Misc.java:4419
static boolean hasSModdableBuiltIns(ShipVariantAPI variant)
Definition Misc.java:5608
static Vector2f intersectSegmentAndCircle(Vector2f p1, Vector2f p2, Vector2f p3, float r)
Definition Misc.java:2026
static List< MarketAPI > getNearbyMarkets(Vector2f locInHyper, float distLY)
Definition Misc.java:1022
static boolean hasUnexploredRuins(MarketAPI market)
Definition Misc.java:5879
static SubmarketPlugin getLocalResources(MarketAPI market)
Definition Misc.java:4302
static float getClosestTurnDirection(float facing, float desired)
Definition Misc.java:2102
static Color getHighlightedOptionColor()
Definition Misc.java:788
static MusicPlayerPlugin getMusicPlayerPlugin()
Definition Misc.java:5316
static void setSalvageSpecial(SectorEntityToken entity, Object data)
Definition Misc.java:3633
static boolean hasAtLeastOneOfTags(Collection< String > tags, String ... other)
Definition Misc.java:5861
static FactionPersonalityPickerPlugin getFactionPersonalityPicker()
Definition Misc.java:4478
static int getMaxPermanentMods(FleetMemberAPI member, MutableCharacterStatsAPI stats)
Definition Misc.java:5528
static void makeNonStoryCritical(MarketAPI market, String reason)
Definition Misc.java:6252
static MarketAPI getStationMarket(CampaignFleetAPI station)
Definition Misc.java:4609
static void showCost(TextPanelAPI text, String title, boolean withAvailable, float widthOverride, Color color, Color dark, String[] res, int[] quantities, boolean[] consumed)
Definition Misc.java:4689
static boolean isInsideSlipstream(Vector2f loc, float radius, LocationAPI location)
Definition Misc.java:6411
static boolean isInAbyss(SectorEntityToken entity)
Definition Misc.java:2327
static float getDistanceToPlayerLY(Vector2f locInHyper)
Definition Misc.java:626
static void affectAvailabilityWithinReason(CommodityOnMarketAPI com, int quantity)
Definition Misc.java:5841
static Vector2f getInterceptPoint(CampaignFleetAPI from, SectorEntityToken to)
Definition Misc.java:3921
static Vector2f intersectSegments(Vector2f a1, Vector2f a2, Vector2f b1, Vector2f b2)
Definition Misc.java:1936
static boolean isSpecialMod(ShipVariantAPI variant, HullModSpecAPI spec)
Definition Misc.java:5594
static boolean isTrader(CampaignFleetAPI fleet)
Definition Misc.java:4767
static CampaignTerrainAPI getHyperspaceTerrain()
Definition Misc.java:2308
static void makeImportant(SectorEntityToken entity, String reason, float dur)
Definition Misc.java:4054
static void forgetAboutTransponder(CampaignFleetAPI fleet)
Definition Misc.java:4168
static float distanceFromLineToPoint(Vector2f p1, Vector2f p2, Vector2f p3)
Definition Misc.java:1865
static void clearAreaAroundPlayer(float minDist)
Definition Misc.java:4108
static boolean isFleetMadeHostileToFaction(CampaignFleetAPI fleet, String factionId)
Definition Misc.java:1511
static void makeImportant(PersonAPI person, String reason, float dur)
Definition Misc.java:4060
static void makeUnimportant(SectorEntityToken entity, String reason)
Definition Misc.java:4077
static int getMaxPermanentMods(ShipAPI ship)
Definition Misc.java:5523
static Color FLOATY_HULL_DAMAGE_COLOR
Definition Misc.java:216
static boolean isSpacerStart()
Definition Misc.java:5183
static Color getHighlightColor()
Definition Misc.java:792
static boolean isInsignificant(CampaignFleetAPI fleet)
Definition Misc.java:6272
static String RECOVERY_TAGS_KEY
Definition Misc.java:5510
static Color getDesignTypeColor(String designType)
Definition Misc.java:4936
static Color optColor(JSONObject json, String key, Color defaultValue)
Definition Misc.java:2578
static int getEstimatedOrbitIndex(PlanetAPI planet)
Definition Misc.java:2930
static Color FLOATY_EMP_DAMAGE_COLOR
Definition Misc.java:213
static boolean isPlayerOrCombinedContainingPlayer(CampaignFleetAPI fleet)
Definition Misc.java:2250
static float getShipQuality(MarketAPI market)
Definition Misc.java:4505
static Vector2f optVector(JSONObject json, String arrayKey)
Definition Misc.java:2602
static LabelAPI addDesignTypePara(TooltipMakerAPI tooltip, String design, float pad)
Definition Misc.java:4946
static void clearAsteroidSource(SectorEntityToken asteroid)
Definition Misc.java:2270
static boolean hasAnySurveyDataFor(StarSystemAPI system)
Definition Misc.java:2855
static AbandonMarketPlugin getAbandonMarketPlugin(MarketAPI market)
Definition Misc.java:4235
static void setColor(Color color, int alpha)
Definition Misc.java:4021
static< T extends Enum< T > T mapToEnum(JSONObject json, String key, Class< T > enumType, T defaultOption, boolean required)
Definition Misc.java:2557
static String getDetailedAgoString(long timestamp)
Definition Misc.java:1551
static String getAndJoined(List< String > strings)
Definition Misc.java:871
static void makeImportant(MemoryAPI memory, String reason)
Definition Misc.java:4063
static Color FLOATY_SHIELD_DAMAGE_COLOR
Definition Misc.java:215
static Color getTooltipTitleAndLightHighlightColor()
Definition Misc.java:799
static int getMaxIndustries(MarketAPI market)
Definition Misc.java:5244
static boolean addStorageInfo(TooltipMakerAPI tooltip, Color color, Color dark, MarketAPI market, boolean includeLocalResources, boolean addSectionIfEmpty)
Definition Misc.java:4349
static float getAdjustedFP(float fp, MarketAPI market)
Definition Misc.java:4497
static boolean isFastStart()
Definition Misc.java:2274
static CampaignFleetAPI getStationFleet(SectorEntityToken station)
Definition Misc.java:4580
static void setMercHiredNow(PersonAPI person)
Definition Misc.java:5459
static float getRounded(float in)
Definition Misc.java:639
static boolean isInArc(float direction, float arc, float test)
Definition Misc.java:1743
static boolean isPermaKnowsWhoPlayerIs(CampaignFleetAPI fleet)
Definition Misc.java:4204
static List< MarketAPI > getFactionMarkets(FactionAPI faction)
Definition Misc.java:1011
static ImmigrationPlugin getImmigrationPlugin(MarketAPI market)
Definition Misc.java:4217
static HyperspaceTerrainPlugin getHyperspaceTerrainPlugin()
Definition Misc.java:2316
static SubmarketPlugin getStorage(MarketAPI market)
Definition Misc.java:4295
static boolean setFlagWithReason(MemoryAPI memory, String flagKey, String reason, boolean value, float expire)
Definition Misc.java:1439
static boolean isNormal()
Definition Misc.java:2288
static void initEconomyMarket(PlanetAPI planet)
Definition Misc.java:3591
static float getClosingSpeed(Vector2f p1, Vector2f p2, Vector2f v1, Vector2f v2)
Definition Misc.java:1354
static void interruptAbilitiesWithTag(CampaignFleetAPI fleet, String tag)
Definition Misc.java:3907
static ShipAPI findClosestShipEnemyOf(ShipAPI ship, Vector2f locFromForSorting, HullSize smallestToNote, float maxRange, boolean considerShipRadius, FindShipFilter filter)
Definition Misc.java:2500
static String getPersonalityName(PersonAPI person)
Definition Misc.java:5805
static float interpolate(float from, float to, float progress)
Definition Misc.java:1291
static CoreUITradeMode getTradeMode(MemoryAPI memory)
Definition Misc.java:5174
static float[] getFloatArray(String key)
Definition Misc.java:6858
static int getFPForVariantId(String variantId)
Definition Misc.java:4467
static Color scaleColorSaturate(Color color, float factor)
Definition Misc.java:5205
static float getMemberStrength(FleetMemberAPI member, boolean withHull, boolean withQuality, boolean withCaptain)
Definition Misc.java:4848
static CampaignFleetAPI getStationFleet(MarketAPI market)
Definition Misc.java:4571
static void showCost(TextPanelAPI text, Color color, Color dark, String[] res, int[] quantities)
Definition Misc.java:4683
static boolean isPirateFaction(FactionAPI faction)
Definition Misc.java:6150
static float getSpawnFPMult(CampaignFleetAPI fleet)
Definition Misc.java:5791
static String getListOfResources(Map< String, Integer > res, List< String > quantities)
Definition Misc.java:3994
static Vector2f getPointWithinRadiusUniform(Vector2f from, float minR, float maxR, Random random)
Definition Misc.java:730
static boolean isAvoidingPlayerHalfheartedly(CampaignFleetAPI fleet)
Definition Misc.java:6128
static float getSnapshotFPLost(CampaignFleetAPI fleet)
Definition Misc.java:738
static void makeHostileToPlayerTradeFleets(CampaignFleetAPI fleet)
Definition Misc.java:1477
static final String ASTEROID_SOURCE
Definition Misc.java:2259
static Color scaleColorOnly(Color color, float factor)
Definition Misc.java:1302
static boolean isImportantForReason(MemoryAPI memory, String reason)
Definition Misc.java:4072
static int getCurrSpecialMods(ShipVariantAPI variant)
Definition Misc.java:5624
static boolean shouldNotWantRunFromPlayerEvenIfWeaker(CampaignFleetAPI fleet)
Definition Misc.java:6299
static Vector2f getPerp(Vector2f v)
Definition Misc.java:2095
static int OVER_MAX_INDUSTRIES_PENALTY
Definition Misc.java:223
static SectorEntityToken getSourceEntity(CampaignFleetAPI fleet)
Definition Misc.java:2169
static Vector2f getInterceptPointBasic(SectorEntityToken from, SectorEntityToken to)
Definition Misc.java:1396
static boolean canPlanetTypeRollCondition(PlanetSpecAPI spec, String id)
Definition Misc.java:6796
static float getFuelPerDayAtSpeed(CampaignFleetAPI fleet, float speed)
Definition Misc.java:1681
static boolean hasFarmland(MarketAPI market)
Definition Misc.java:5910
static Boolean canCheckVramNVIDIA
Definition Misc.java:5992
static float getBurnLevelForSpeed(float speed)
Definition Misc.java:1652
static boolean isUnremovable(PersonAPI person)
Definition Misc.java:5473
static final int OWNER_NEUTRAL
Definition Misc.java:210
static float getAdjustedBaseRange(float base, ShipAPI ship, WeaponAPI weapon)
Definition Misc.java:6374
static float[][] initNoise(Random random, int w, int h, float spikes)
Definition Misc.java:2660
static float normalizeAngle(float angleDeg)
Definition Misc.java:1142
static Vector2f getPointAtRadius(Vector2f from, float r)
Definition Misc.java:697
static ShipPickMode getShipPickMode(MarketAPI market, String factionId)
Definition Misc.java:4545
static void setPreliminarySurveyed(MarketAPI market, TextPanelAPI text, boolean withNotification)
Definition Misc.java:3038
static Industry getStationIndustry(MarketAPI market)
Definition Misc.java:4617
static float logOfBase(float base, float num)
Definition Misc.java:693
static JumpPointAPI getJumpPointTo(PlanetAPI star)
Definition Misc.java:3527
static boolean isInsideSlipstream(SectorEntityToken entity)
Definition Misc.java:6423
static ReputationAdjustmentResult adjustRep(PersonAPI person, float delta, RepLevel limit, TextPanelAPI text)
Definition Misc.java:6630
static boolean isPlayerFactionSetUp()
Definition Misc.java:4750
static Vector2f getDiff(Vector2f v1, Vector2f v2)
Definition Misc.java:2156
static Industry getCurrentlyBeingConstructed(MarketAPI market)
Definition Misc.java:5291
static boolean isPirate(CampaignFleetAPI fleet)
Definition Misc.java:4770
static void makeHostileToFaction(CampaignFleetAPI fleet, String factionId, boolean hostile, float dur)
Definition Misc.java:1499
static float getAveragePlanetRadius(PlanetSpecAPI spec)
Definition Misc.java:6774
static Vector2f rotateAroundOrigin(Vector2f v, float angle, Vector2f origin)
Definition Misc.java:1214
static boolean isPointInBounds(Vector2f p1, List< Vector2f > bounds)
Definition Misc.java:1906
static String replaceTokensFromMemory(String text, Map< String, MemoryAPI > memoryMap)
Definition Misc.java:572
static Vector2f interpolateVector(Vector2f from, Vector2f to, float progress)
Definition Misc.java:1282
static boolean canPlanetTypeRollHabitable(PlanetSpecAPI spec)
Definition Misc.java:6792
static void setMercenary(PersonAPI person, boolean mercenary)
Definition Misc.java:5468
static JumpPointAPI findNearestJumpPointTo(SectorEntityToken entity, boolean allowWormhole)
Definition Misc.java:3369
static int getNumNonMercOfficers(CampaignFleetAPI fleet)
Definition Misc.java:5223
static Vector2f getVector(JSONObject json, String arrayKey, Vector2f def)
Definition Misc.java:2584
static void setWarningBeaconGlowColor(SectorEntityToken beacon, Color color)
Definition Misc.java:3733
static int getNumHostileMarkets(FactionAPI faction, SectorEntityToken from, float maxDist)
Definition Misc.java:1032
static SimulatorPlugin getSimulatorPlugin()
Definition Misc.java:4213
static boolean systemHasPlanets(StarSystemAPI system)
Definition Misc.java:3689
static void makeStoryCritical(MarketAPI market, String reason)
Definition Misc.java:6246
static boolean isFleetReturningToDespawn(CampaignFleetAPI fleet)
Definition Misc.java:3842
static float getAbyssalDepth(Vector2f loc)
Definition Misc.java:2330
static final String MERCENARY_HIRE_TIMESTAMP
Definition Misc.java:5458
static List< MarketAPI > getPlayerMarkets(boolean includeNonPlayerFaction)
Definition Misc.java:980
static float getOfficerSalary(PersonAPI officer)
Definition Misc.java:4416
static void setWarningBeaconPingColor(SectorEntityToken beacon, Color color)
Definition Misc.java:3737
static float getDistanceLY(Vector2f v1, Vector2f v2)
Definition Misc.java:635
static MarketAPI findNearestLocalMarket(SectorEntityToken token, float maxDist, MarketFilter filter)
Definition Misc.java:1146
static float getTargetingRadius(Vector2f from, CombatEntityAPI target, boolean considerShield)
Definition Misc.java:1349
static Color interpolateColor(Color from, Color to, float progress)
Definition Misc.java:1261
static boolean canCheckVram()
Definition Misc.java:5993
static float getSpeedForBurnLevel(float burnLevel)
Definition Misc.java:1671
static boolean isFringe(StarSystemAPI system)
Definition Misc.java:6691
static Color getDarkHighlightColor()
Definition Misc.java:795
static String genEntityCatalogId(CatalogEntryType type)
Definition Misc.java:6736
static IntervalUtil createEconIntervalTracker()
Definition Misc.java:866
static float MIN_TERRAIN_EFFECT_MULT
Definition Misc.java:4974
static boolean isAutomated(FleetMemberAPI member)
Definition Misc.java:5496
static Vector2f getCoreMax()
Definition Misc.java:6492
static void makeHostile(CampaignFleetAPI fleet)
Definition Misc.java:1473
static int getStorageCostPerMonth(MarketAPI market)
Definition Misc.java:4291
static boolean caresAboutPlayerTransponder(CampaignFleetAPI fleet)
Definition Misc.java:2441
static Vector2f getPointWithinRadius(Vector2f from, float r)
Definition Misc.java:711
static FactionAPI getCommissionFaction()
Definition Misc.java:2424
static void clearTarget(CampaignFleetAPI fleet, boolean forgetTransponder)
Definition Misc.java:3824
static void giveStandardReturnAssignments(CampaignFleetAPI fleet, SectorEntityToken where, String text, boolean withClear)
Definition Misc.java:3869
static float getProfitMarginMult()
Definition Misc.java:854
static final String CAPTAIN_UNREMOVABLE
Definition Misc.java:5472
static float FLUX_PER_CAPACITOR
Definition Misc.java:196
static boolean isPlayerOrCombinedPlayerPrimary(CampaignFleetAPI fleet)
Definition Misc.java:2240
static float getBattleJoinRange()
Definition Misc.java:2227
static String FLEET_RETURNING_TO_DESPAWN
Definition Misc.java:3840
static int computeEconUnitChangeFromTradeModChange(CommodityOnMarketAPI com, int quantity)
Definition Misc.java:5826
static void setAllPlanetsKnown(String systemName)
Definition Misc.java:2869
static float getLYPerDayAtSpeed(CampaignFleetAPI fleet, float speed)
Definition Misc.java:1699
static MarketAPI getBiggestMarketInLocation(LocationAPI location)
Definition Misc.java:946
static ParticleControllerAPI[] addGlowyParticle(LocationAPI location, Vector2f loc, Vector2f vel, float size, float rampUp, float dur, Color color)
Definition Misc.java:4999
static final String IS_MERCENARY
Definition Misc.java:5453
static StarSystemAPI getStarSystemForAnchor(SectorEntityToken anchor)
Definition Misc.java:4679
static boolean isSlowMoving(CampaignFleetAPI fleet)
Definition Misc.java:5651
static Color getDarkPlayerColor()
Definition Misc.java:836
static float getLYPerDayAtBurn(CampaignFleetAPI fleet, float burnLevel)
Definition Misc.java:1695
static float getProbabilityMult(float desired, float current, float deviationMult)
Definition Misc.java:4667
static int getMaxMarketSize(MarketAPI market)
Definition Misc.java:6812
static void showCost(TextPanelAPI text, String title, boolean withAvailable, Color color, Color dark, String[] res, int[] quantities)
Definition Misc.java:4686
static Color getColor(JSONObject json, String key)
Definition Misc.java:2572
static Color getStoryDarkBrighterColor()
Definition Misc.java:770
static void makeUnimportant(PersonAPI person, String reason)
Definition Misc.java:4080
static void stopPlayerFleet()
Definition Misc.java:3987
static void generatePlanetConditions(String systemName, StarAge age)
Definition Misc.java:2910
static int getUntrustwortyCount()
Definition Misc.java:6617
static float FP_TO_BOMBARD_COST_APPROX_MULT
Definition Misc.java:226
static void makeNoRepImpact(CampaignFleetAPI fleet, String reason)
Definition Misc.java:1468
static Set< String > getAllowedRecoveryTags()
Definition Misc.java:5512
static boolean turnTowardsFacingV2(ShipAPI ship, float desiredFacing, float relativeAngVel)
Definition Misc.java:6584
static float getOutpostPenalty()
Definition Misc.java:4404
static float IMPACT_VOLUME_MULT
Definition Misc.java:6034
static void clearFlag(MemoryAPI memory, String flagKey)
Definition Misc.java:1459
static boolean crossesAnySlipstream(LocationAPI location, Vector2f from, Vector2f to)
Definition Misc.java:6442
static float getAngleInDegreesStrict(Vector2f v)
Definition Misc.java:1115
static void setRaidedTimestamp(MarketAPI market)
Definition Misc.java:5816
static float SAME_FACTION_BONUS
Definition Misc.java:5016
static boolean isActiveModule(ShipVariantAPI variant)
Definition Misc.java:4626
static JumpPointAPI findNearestJumpPointTo(SectorEntityToken entity)
Definition Misc.java:3366
static void setSpawnFPMult(CampaignFleetAPI fleet, float mult)
Definition Misc.java:5797
static float getDistanceToPlayerLY(SectorEntityToken other)
Definition Misc.java:630
static void fadeIn(final SectorEntityToken entity, final float in)
Definition Misc.java:3195
static ShipPickMode getShipPickMode(MarketAPI market)
Definition Misc.java:4542
static Color getPositiveHighlightColor()
Definition Misc.java:822
static MagneticFieldTerrainPlugin getMagneticFieldFor(PlanetAPI planet)
Definition Misc.java:2389
static float getDaysSinceLastRaided(MarketAPI market)
Definition Misc.java:5820
static String getRoundedValueMaxOneAfterDecimal(float value)
Definition Misc.java:673
static float getAdjustedStrength(float fp, MarketAPI market)
Definition Misc.java:4483
static ReputationAdjustmentResult adjustRep(String factionId, float delta, TextPanelAPI text)
Definition Misc.java:6646
static List< MarketAPI > getMarketsInLocation(LocationAPI location)
Definition Misc.java:960
static int getOPCost(HullModSpecAPI mod, HullSize size)
Definition Misc.java:5580
static void makeUnimportant(MemoryAPI memory, String reason)
Definition Misc.java:4083
static boolean showRuleDialog(SectorEntityToken entity, String initialTrigger)
Definition Misc.java:1103
static FactionAPI getClaimingFaction(SectorEntityToken planet)
Definition Misc.java:5068
static ReputationAdjustmentResult adjustRep(String factionId, float delta, RepLevel limit, TextPanelAPI text, boolean addMessageOnNoChange, boolean withMessage)
Definition Misc.java:6652
static Vector2f getCoreCenter()
Definition Misc.java:6500
static SectorEntityToken getStationEntity(MarketAPI market, CampaignFleetAPI fleet)
Definition Misc.java:4562
static boolean isMilitary(MarketAPI market)
Definition Misc.java:5045
static boolean isUnboardable(FleetMemberAPI member)
Definition Misc.java:3293
static float getAngleInDegrees(Vector2f from, Vector2f to)
Definition Misc.java:1130
static boolean isInArc(float direction, float arc, Vector2f from, Vector2f to)
Definition Misc.java:1722
static boolean isStationInSupportRange(CampaignFleetAPI fleet, CampaignFleetAPI station)
Definition Misc.java:4827
static List< CampaignFleetAPI > findNearbyFleets(SectorEntityToken from, float maxRange, FleetFilter filter)
Definition Misc.java:912
static Vector2f getPointWithinRadiusUniform(Vector2f from, float r, Random random)
Definition Misc.java:722
static float getFractionalBurnLevelForSpeed(float speed)
Definition Misc.java:1661
static String getRoundedValueOneAfterDecimalIfNotWhole(float value)
Definition Misc.java:683
static StarCoronaTerrainPlugin getCoronaFor(PlanetAPI star)
Definition Misc.java:2377
static< T extends Enum< T > T mapToEnum(JSONObject json, String key, Class< T > enumType, T defaultOption)
Definition Misc.java:2554
static boolean isScavenger(CampaignFleetAPI fleet)
Definition Misc.java:4773
static void makeNonHostileToFaction(CampaignFleetAPI fleet, String factionId, boolean nonHostile, float dur)
Definition Misc.java:1488
static String getCommissionFactionId()
Definition Misc.java:2419
static float getAngleInDegrees(Vector2f v)
Definition Misc.java:1126
static ReputationAdjustmentResult adjustRep(PersonAPI person, float delta, RepLevel limit, TextPanelAPI text, boolean addMessageOnNoChange, boolean withMessage)
Definition Misc.java:6633
static SpriteAPI getWeaponSkin(String cat, String weaponId, ShipAPI ship, WeaponSkinType type)
Definition Misc.java:6896
static void generatePlanetConditions(StarSystemAPI system, StarAge age)
Definition Misc.java:2919
static Vector2f normalise(Vector2f v)
Definition Misc.java:1134
static Vector3f optVector3f(JSONObject json, String arrayKey)
Definition Misc.java:2610
static Vector3f getVector3f(JSONObject json, String arrayKey)
Definition Misc.java:2595
static Color scaleColor(Color color, float factor)
Definition Misc.java:1296
static String getPlanetSurveyClass(PlanetAPI planet)
Definition Misc.java:3617
static void makeLowRepImpact(CampaignFleetAPI fleet, String reason)
Definition Misc.java:1465
static boolean isEasy()
Definition Misc.java:2284
static float getAbyssalDepthOfPlayer()
Definition Misc.java:2345
static String getFleetType(CampaignFleetAPI fleet)
Definition Misc.java:4758
static String getRoundedValue(float value)
Definition Misc.java:647
static boolean isUnboardable(ShipHullSpecAPI hullSpec)
Definition Misc.java:3300
static float getAbyssalDepth(SectorEntityToken entity)
Definition Misc.java:2351
static SpriteAPI getWeaponSkin(ShipAPI ship, String weaponId, WeaponSkinType type)
Definition Misc.java:6881
static Color getBallisticMountColor()
Definition Misc.java:809
CargoAPI createCargo(boolean unlimitedStacks)
MarketAPI createMarket(String id, String name, int size)
JSONArray getJSONArray(String key)
float getTargetingRadius(Vector2f from, CombatEntityAPI target, boolean considerShield)
String getSpriteName(String category, String id)
ShipVariantAPI getVariant(String variantId)
MarketConditionSpecAPI getMarketConditionSpec(String conditionId)
Object getSpec(Class c, String id, boolean nullOnNotFound)
HullModSpecAPI getHullModSpec(String modId)
IndustrySpecAPI getIndustrySpec(String industryId)
InputStream openStream(String filename)
Object getNewPluginInstance(String id)
boolean getBoolean(String key)
List< String > getSpriteKeys(String category)
CommoditySpecAPI getCommoditySpec(String commodityId)
SpriteAPI getSprite(String filename)
float getAngleInDegreesFast(Vector2f v)
Color getDesignTypeColor(String designType)
SoundAPI playSound(String id, float pitch, float volume, Vector2f loc, Vector2f vel)
CampaignFleetAPI getSourceFleet(FleetMemberAPI member)
boolean isOnPlayerSide(CampaignFleetAPI participantOrCombined)
void setInteractionTarget(SectorEntityToken target)
void addAssignment(FleetAssignment assignment, SectorEntityToken target, float maxDurationInDays)
boolean isHostileTo(SectorEntityToken other)
MutableCharacterStatsAPI getCommanderStats()
boolean showInteractionDialog(InteractionDialogPlugin plugin, SectorEntityToken interactionTarget)
float getQuantity(CargoAPI.CargoItemType type, Object data)
List< CargoStackAPI > getStacksCopy()
void addCommodity(String commodityId, float quantity)
List< CommDirectoryEntryAPI > getEntriesCopy()
CommDirectoryEntryAPI getEntryForPerson(PersonAPI person)
ArrayList< FleetMemberAPI > getSnapshot()
List< OfficerDataAPI > getOfficersCopy()
List< FleetMemberAPI > getMembersListCopy()
< T > T pickPlugin(Class< T > c, Object params)
SectorEntityToken getDestinationVisualEntity()
List< JumpDestination > getDestinations()
SectorEntityToken addTerrain(String terrainId, Object param)
List getEntities(Class implementedClassOrInterface)
ParticleControllerAPI addParticle(Vector2f loc, Vector2f vel, float size, float brightness, float rampUp, float duration, Color color)
void addHitParticle(Vector2f loc, Vector2f vel, float size, float brightness, float duration, Color color)
List< SectorEntityToken > getJumpPoints()
List< SectorEntityToken > getEntitiesWithTag(String tag)
List< CustomCampaignEntityAPI > getCustomEntitiesWithTag(String tag)
List< CampaignTerrainAPI > getTerrainCopy()
SectorEntityToken createToken(float x, float y)
CustomCampaignEntityAPI addCustomEntity(String id, String name, String type, String factionId)
void removeEntity(SectorEntityToken entity)
List< CampaignFleetAPI > getFleets()
AICoreOfficerPlugin pickAICoreOfficerPlugin(String commodityId)
ImmigrationPlugin pickImmigrationPlugin(MarketAPI market)
FleetInflater pickFleetInflater(CampaignFleetAPI fleet, Object params)
AICoreAdminPlugin pickAICoreAdminPlugin(String commodityId)
void setComWidthOverride(float comWidthOverride)
void setNumberOnlyMode(boolean numberOnlyMode)
void addCost(String commodityId, int quantity, Color color)
List< StarSystemAPI > getStarSystems()
ReputationAdjustmentResult adjustPlayerReputation(Object action, String factionId)
GenericPluginManagerAPI getGenericPlugins()
CampaignEventManagerAPI getEventManager()
FactionAPI getFaction(String factionId)
StarSystemAPI getStarSystem(String name)
SectorEntityToken getEntityById(String id)
void setAlwaysUseSensorFaderBrightness(Boolean alwaysUseSensorFaderBrightness)
void setCircularOrbitPointingDown(SectorEntityToken focus, float angle, float orbitRadius, float orbitDays)
boolean isInOrNearSystem(StarSystemAPI system)
void addDropValue(String group, int value)
void addScript(EveryFrameScript script)
Map< String, AbilityPlugin > getAbilities()
void setDiscoverable(Boolean discoverable)
void setHasSystemwideNebula(Boolean hasSystemwideNebula)
OnClickAction getOnClickAction(CoreUIAPI ui)
ResourceCostPanelAPI addCostPanel(String title, float height, Color color, Color dark)
EncounterOption pickEncounterOption(FleetEncounterContextPlugin context, CampaignFleetAPI otherFleet)
void setPriorityTarget(SectorEntityToken priorityTarget, float duration, boolean followMode)
void addIntelToTextPanel(IntelInfoPlugin plugin, TextPanelAPI textPanel)
void addTradeMod(String source, float quantity, float days)
void addMarket(MarketAPI market, boolean withJunkAndChatter)
List< MarketAPI > getMarketsInGroup(String group)
List< MarketAPI > getMarkets(LocationAPI loc)
void setSurveyLevel(SurveyLevel surveyLevel)
void setPlanetConditionMarketOnly(boolean isPlanetConditionMarketOnly)
void setPrimaryEntity(SectorEntityToken primaryEntity)
Set< SectorEntityToken > getConnectedEntities()
SubmarketAPI getSubmarket(String specId)
List< MarketConditionAPI > getConditions()
CampaignEventPlugin startEvent(CampaignEventTarget eventTarget, String eventType, Object param)
CampaignEventPlugin getOngoingEvent(CampaignEventTarget eventTarget, String eventType)
void addRequired(String key, String requiredKey)
void set(String key, Object value)
boolean is(String key, Object value)
CampaignFleetAPI getFleet(String key)
String performTokenReplacement(String ruleId, String text, SectorEntityToken entity, Map< String, MemoryAPI > memoryMap)
void setStats(MutableCharacterStatsAPI stats)
MutableCharacterStatsAPI getStats()
boolean isAwareOf(int owner, CombatEntityAPI other)
boolean hasAttachedFloaty(CombatEntityAPI entity)
void giveCommand(ShipCommand command)
ShipEngineControllerAPI getEngineController()
boolean isNonCombat(boolean considerOrders)
MutableShipStatsAPI getMutableStats()
ShipEngineControllerAPI getEngineController()
void giveCommand(ShipCommand command, Object param, int groupNumber)
EnumSet< ShipTypeHints > getHints()
int getOrdnancePoints(MutableCharacterStatsAPI stats)
LinkedHashSet< String > getSMods()
LinkedHashSet< String > getSModdedBuiltIns()
List< WeaponGroupSpec > getWeaponGroups()
void setFleetCommanderForStats(PersonAPI alternateFleetCommander, FleetDataAPI fleetForStats)
void applyCREvent(float crChange, String description)
void init(CampaignFleetAPI fleet, PlanetAPI planet)
String getSurveyDataType(PlanetAPI planet)
void showShips(List< FleetMemberAPI > ships, int max, boolean sort, float pad)
LabelAPI addPara(String format, float pad, Color hl, String... highlights)
LabelAPI addSectionHeading(String str, Alignment align, float pad)
void showCargo(CargoAPI cargo, int max, boolean sort, float pad)