Starsector API
Loading...
Searching...
No Matches
AsteroidBeltTerrainPlugin.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.terrain;
2
3import java.awt.Color;
4import java.util.Random;
5
6import com.fs.starfarer.api.Global;
7import com.fs.starfarer.api.campaign.AsteroidAPI;
8import com.fs.starfarer.api.campaign.CampaignEngineLayers;
9import com.fs.starfarer.api.campaign.CampaignFleetAPI;
10import com.fs.starfarer.api.campaign.LocationAPI;
11import com.fs.starfarer.api.campaign.SectorEntityToken;
12import com.fs.starfarer.api.campaign.TerrainAIFlags;
13import com.fs.starfarer.api.campaign.rules.MemoryAPI;
14import com.fs.starfarer.api.combat.ViewportAPI;
15import com.fs.starfarer.api.loading.Description.Type;
16import com.fs.starfarer.api.ui.Alignment;
17import com.fs.starfarer.api.ui.TooltipMakerAPI;
18import com.fs.starfarer.api.util.Misc;
19
21
22// public static float MIN_BURN_PENALTY = 0.1f;
23// public static float BURN_PENALTY_RANGE = 0.4f;
24
25 public static class AsteroidBeltParams extends RingParams {
26 public int numAsteroids;
27 //public float orbitRadius;
28 //public float width;
29 public float minOrbitDays;
30 public float maxOrbitDays;
31 public float minSize;
32 public float maxSize;
33 public AsteroidBeltParams(int numAsteroids, float orbitRadius,
34 float width, float minOrbitDays, float maxOrbitDays,
35 float minSize, float maxSize, String name) {
36 super(width, orbitRadius, null, name);
37 this.numAsteroids = numAsteroids;
38 //this.orbitRadius = orbitRadius;
39 //this.width = width;
40 this.minOrbitDays = minOrbitDays;
41 this.maxOrbitDays = maxOrbitDays;
42 this.minSize = minSize;
43 this.maxSize = maxSize;
44 }
45 }
46
47
48 @Override
49 protected Object readResolve() {
50 super.readResolve();
51 return this;
52 }
53
54 private transient RingRenderer rr;
55 public void renderOnMap(float factor, float alphaMult) {
56 if (params == null) return;
57 if (rr == null) {
58 rr = new RingRenderer("systemMap", "map_asteroid_belt");
59 }
60 Color color = Global.getSettings().getColor("asteroidBeltMapColor");
61 float bandWidth = params.bandWidthInEngine;
62 bandWidth = 300f;
64 params.middleRadius - bandWidth * 0.5f,
65 params.middleRadius + bandWidth * 0.5f,
66 color,
67 false, factor, alphaMult);
68 }
69
70 public void regenerateAsteroids() {
72 }
73
74 protected boolean needToCreateAsteroids = true;
75 protected void createAsteroids() {
76 if (!(params instanceof AsteroidBeltParams)) return;
77
78 Random rand = new Random(Global.getSector().getClock().getTimestamp() + entity.getId().hashCode());
79
81 for (int i = 0; i < params.numAsteroids; i++) {
82 //float size = 8f + (float) Math.random() * 25f;
83 float size = params.minSize + rand.nextFloat() * (params.maxSize - params.minSize);
84 AsteroidAPI asteroid = location.addAsteroid(size);
85
86 asteroid.setFacing(rand.nextFloat() * 360f);
87 float currRadius = params.middleRadius - params.bandWidthInEngine/2f + rand.nextFloat() * params.bandWidthInEngine;
88 float angle = rand.nextFloat() * 360f;
89 float orbitDays = params.minOrbitDays + rand.nextFloat() * (params.maxOrbitDays - params.minOrbitDays);
90 asteroid.setCircularOrbit(this.entity, angle, currRadius, orbitDays);
91 Misc.setAsteroidSource(asteroid, this);
92 }
94 }
95
96 public void advance(float amount) {
99 }
100 super.advance(amount);
101
102// if (entity.isInCurrentLocation()) {
103// System.out.println("Params: " + params + ", name: " + getNameForTooltip());
104// if (params == null) {
105// System.out.println("efwefwe");
106// }
107// }
108 }
109
110
111
112// public static Map<HullSize, Float> burnPenalty = new HashMap<HullSize, Float>();
113// static {
114// burnPenalty.put(HullSize.FIGHTER, 0f);
115// burnPenalty.put(HullSize.FRIGATE, 0f);
116// burnPenalty.put(HullSize.DESTROYER, 1f);
117// burnPenalty.put(HullSize.CRUISER, 2f);
118// burnPenalty.put(HullSize.CAPITAL_SHIP, 3f);
119// }
120
121
122// public void init(String terrainId, SectorEntityToken entity, Object param) {
123// super.init(terrainId, entity, param);
124// if (params.name == null) {
125// params.name = "Asteroid Belt";
126// }
127// }
128
129 public AsteroidBeltParams params;
130 public void init(String terrainId, SectorEntityToken entity, Object param) {
131 super.init(terrainId, entity, param);
132 if (param instanceof AsteroidBeltParams) {
133 params = (AsteroidBeltParams) param;
134 name = params.name;
135 if (name == null) {
136 name = "Asteroid Belt";
137 }
138 }
139 }
140
141
142 public void render(CampaignEngineLayers layer, ViewportAPI viewport) {
143 super.render(layer, viewport);
144 }
145
146 @Override
147 public void applyEffect(SectorEntityToken entity, float days) {
148 if (entity instanceof CampaignFleetAPI) {
150
151// float penalty = getBurnPenalty(fleet);
152// fleet.getStats().addTemporaryModMult(0.1f, getModId() + "_1",
153// "Inside " + getNameForTooltip().toLowerCase(), 1f - penalty,
154// fleet.getStats().getFleetwideMaxBurnMod());
155
156 if (Misc.isSlowMoving(fleet)) {
157 fleet.getStats().addTemporaryModMult(0.1f, getModId() + "_2",
158 "Hiding inside " + getNameForTooltip().toLowerCase(), RingSystemTerrainPlugin.getVisibilityMult(fleet),
159 fleet.getStats().getDetectedRangeMod());
160 }
161// if (fleet.isPlayerFleet()) {
162// System.out.println("efwefwe");
163// }
164 if (!fleet.isInHyperspaceTransition()) {
165 String key = "$asteroidImpactTimeout";
166 String sKey = "$skippedImpacts";
167 String recentKey = "$recentImpact";
168 float probPerSkip = 0.15f;
169 float maxProb = 1f;
170 float maxSkipsToTrack = 7;
171 float durPerSkip = 0.2f;
172 MemoryAPI mem = fleet.getMemoryWithoutUpdate();
173 if (!mem.contains(key)) {
174 float expire = mem.getExpire(sKey);
175 if (expire < 0) expire = 0;
176
177 float hitProb = Misc.getFleetRadiusTerrainEffectMult(fleet) * 0.5f;
178 //hitProb = 0.33f;
179 hitProb = 0.5f;
180 //hitProb = 1f;
181 hitProb = expire / durPerSkip * probPerSkip;
182 if (hitProb > maxProb) hitProb = maxProb;
183 if ((float) Math.random() < hitProb) {
184 boolean hadRecent = mem.is(recentKey, true);
185 hadRecent &= (float) Math.random() > 0.5f;
186 fleet.addScript(new AsteroidImpact(fleet, hadRecent));
187 mem.set(sKey, true, 0);
188 mem.set(recentKey, true, 0.5f + 1f * (float) Math.random());
189 } else {
190 mem.set(sKey, true, Math.min(expire + durPerSkip, maxSkipsToTrack * durPerSkip));
191 }
192 mem.set(key, true, (float) (0.05f + 0.1f * Math.random()));
193 //mem.set(key, true, (float) (0.01f + 0.02f * Math.random()));
194 }
195 }
196 }
197 }
198
199// public static float getFleetRadiusTerrainEffectMult(CampaignFleetAPI fleet) {
200// float min = Global.getSettings().getBaseFleetSelectionRadius() + Global.getSettings().getFleetSelectionRadiusPerUnitSize();
201// float max = Global.getSettings().getMaxFleetSelectionRadius();
202// float radius = fleet.getRadius();
203//
204// //radius = 1000;
205//
206// float mult = (radius - min) / (max - min);
207// if (mult > 1) mult = 1;
208// //if (mult < 0) mult = 0;
209// if (mult < 0.1f) mult = 0.1f;
210// //mult = MIN_BURN_PENALTY + mult * BURN_PENALTY_RANGE;
211//
212// float skillMod = fleet.getCommanderStats().getDynamic().getValue(Stats.NAVIGATION_PENALTY_MULT);
213// mult *= skillMod;
214//
215// return mult;
216// }
217
218// protected float getBurnPenalty(CampaignFleetAPI fleet) {
219// float min = Global.getSettings().getBaseFleetSelectionRadius() + Global.getSettings().getFleetSelectionRadiusPerUnitSize();
220// float max = Global.getSettings().getMaxFleetSelectionRadius();
221// float radius = fleet.getRadius();
222//
223// float penalty = (radius - min) / (max - min);
224// if (penalty > 1) penalty = 1;
225// if (penalty < 0) penalty = 0;
226// penalty = MIN_BURN_PENALTY + penalty * BURN_PENALTY_RANGE;
227//
228// float skillMod = fleet.getCommanderStats().getDynamic().getValue(Stats.NAVIGATION_PENALTY_MULT);
229// penalty *= skillMod;
230//
231// return penalty;
232// }
233
234 public boolean hasTooltip() {
235 return true;
236 }
237
238 public String getNameForTooltip() {
239 return "Asteroid Belt";
240 }
241
242 public String getNameAOrAn() {
243 return "an";
244 }
245
246 public void createTooltip(TooltipMakerAPI tooltip, boolean expanded) {
247 float pad = 10f;
248 float small = 5f;
249 Color gray = Misc.getGrayColor();
250 Color highlight = Misc.getHighlightColor();
251 Color fuel = Global.getSettings().getColor("progressBarFuelColor");
252 Color bad = Misc.getNegativeHighlightColor();
253
254 //tooltip.addTitle(params.name);
255 tooltip.addTitle(getNameForTooltip());
256 tooltip.addPara(Global.getSettings().getDescription(getTerrainId(), Type.TERRAIN).getText1(), pad);
257
258 float nextPad = pad;
259 if (expanded) {
260 tooltip.addSectionHeading("Travel", Alignment.MID, pad);
261 nextPad = small;
262 }
263
264// tooltip.addPara("Reduces the travel speed of fleets inside by up to %s. Smaller fleets are more easily able to maneuver the enclosing drive bubble to avoid collisions and suffer a lower penalty.",
265// nextPad,
266// highlight,
267// "" + (int) ((MIN_BURN_PENALTY + BURN_PENALTY_RANGE) * 100f) + "%"
268// );
269//
270// float penalty = getBurnPenalty(Global.getSector().getPlayerFleet());
271// String penaltyStr = Misc.getRoundedValue(1f - penalty);
272// tooltip.addPara("Your fleet's speed is reduced by %s.", pad,
273// highlight,
274// "" + (int) Math.round((penalty) * 100) + "%"
275// //Strings.X + penaltyStr
276// );
277
278// tooltip.addPara("Chance of asteroid impacts on the drive field bubble. The impacts do not present a " +
279// "direct danger to ships but may briefly knock the fleet off course.", nextPad);
280 tooltip.addPara("Chance of asteroid impacts that briefly knock the fleet off course and " +
281 "may occasionally impact ships directly, dealing moderate damage.", nextPad);
282
283// tooltip.addPara("Smaller fleets are usually able to avoid the heavier impacts, and fleets traveling at burn %s or below do not risk impacts at all.", pad,
284// highlight,
285// "" + (int)Math.round(AsteroidImpact.SAFE_BURN_LEVEL)
286// );
287 tooltip.addPara("Smaller fleets are usually able to avoid the heavier impacts, " +
288 "and slow-moving fleets do not risk impacts at all.", pad,
289 highlight,
290 "slow-moving"
291 );
292
293// tooltip.addPara("Reduces the range at which stationary fleets inside it can be detected by %s.", pad,
294// highlight,
295// "" + (int) ((1f - RingSystemTerrainPlugin.VISIBLITY_MULT) * 100) + "%"
296// );
297
298 String stop = Global.getSettings().getControlStringForEnumName("GO_SLOW");
299 tooltip.addPara("Reduces the range at which stationary or slow-moving* fleets inside it can be detected by %s.", nextPad,
300 highlight,
301 "" + (int) ((1f - RingSystemTerrainPlugin.getVisibilityMult(Global.getSector().getPlayerFleet())) * 100) + "%"
302 );
303 tooltip.addPara("*Press and hold %s to stop; combine with holding the left mouse button down to move slowly. " +
304 "A slow-moving fleet moves at a burn level of half that of its slowest ship.", nextPad,
305 Misc.getGrayColor(), highlight,
306 stop
307 );
308
309// tooltip.addPara("Reduces the maximum burn level of ships depending on size. Smaller ships are more easily able to manuver to avoid impacts and suffer a smaller penalty.", nextPad);
310// tooltip.beginGrid(150, 1);
311// tooltip.addToGrid(0, 0, " Frigates", "" + -burnPenalty.get(HullSize.FRIGATE).intValue());
312// tooltip.addToGrid(0, 1, " Destroyers", "" + -burnPenalty.get(HullSize.DESTROYER).intValue());
313// tooltip.addToGrid(0, 2, " Cruisers", "" + -burnPenalty.get(HullSize.CRUISER).intValue());
314// tooltip.addToGrid(0, 3, " Capital ships", "" + -burnPenalty.get(HullSize.CAPITAL_SHIP).intValue());
315// tooltip.addGrid(3f);
316
317 if (expanded) {
318 tooltip.addSectionHeading("Combat", Alignment.MID, pad);
319 tooltip.addPara("Numerous asteroids present on the battlefield. Large enough to be an in-combat navigational hazard.", small);
320 }
321
322 //tooltip.addPara("Does not stack with other similar terrain effects.", pad);
323 }
324
325 public boolean isTooltipExpandable() {
326 return true;
327 }
328
329 public float getTooltipWidth() {
330 return 350f;
331 }
332
333 public String getEffectCategory() {
334 return "asteroid_belt";
335 }
336
337 public boolean hasAIFlag(Object flag) {
338 return flag == TerrainAIFlags.REDUCES_SPEED_LARGE || flag == TerrainAIFlags.DANGEROUS_UNLESS_GO_SLOW ||
340 }
341
342
344 if (Misc.getAsteroidSource(asteroid) == this) {
345 params.numAsteroids--;
346 }
347 }
348}
static SettingsAPI getSettings()
Definition Global.java:57
static SectorAPI getSector()
Definition Global.java:65
void init(String terrainId, SectorEntityToken entity, Object param)
void render(Vector2f loc, float minR, float maxR, Color color, boolean spiral, float factor, float alphaMult)
static void setAsteroidSource(SectorEntityToken asteroid, AsteroidSource source)
Definition Misc.java:2267
static Color getNegativeHighlightColor()
Definition Misc.java:802
static Color getGrayColor()
Definition Misc.java:826
static AsteroidSource getAsteroidSource(SectorEntityToken asteroid)
Definition Misc.java:2261
static float getFleetRadiusTerrainEffectMult(CampaignFleetAPI fleet)
Definition Misc.java:4953
static Color getHighlightColor()
Definition Misc.java:792
static boolean isSlowMoving(CampaignFleetAPI fleet)
Definition Misc.java:5651
Description getDescription(String id, Type type)
String getControlStringForEnumName(String name)
AsteroidAPI addAsteroid(float radius)
void setCircularOrbit(SectorEntityToken focus, float angle, float orbitRadius, float orbitDays)
void addScript(EveryFrameScript script)
void set(String key, Object value)
boolean is(String key, Object value)
void addTemporaryModMult(float durInDays, String source, String desc, float value, StatBonus stat)
LabelAPI addPara(String format, float pad, Color hl, String... highlights)
LabelAPI addSectionHeading(String str, Alignment align, float pad)