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;
63 rr.render(entity.getLocation(),
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
80 LocationAPI location = entity.getContainingLocation();
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) {
149 CampaignFleetAPI fleet = (CampaignFleetAPI) entity;
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 ||
339 flag == TerrainAIFlags.NOT_SUPER_DANGEROUS_UNLESS_GO_SLOW;
340 }
341
342
343 public void reportAsteroidPersisted(SectorEntityToken asteroid) {
344 if (Misc.getAsteroidSource(asteroid) == this) {
345 params.numAsteroids--;
346 }
347 }
348}
static SettingsAPI getSettings()
Definition Global.java:51
static SectorAPI getSector()
Definition Global.java:59
void init(String terrainId, SectorEntityToken entity, Object param)
void render(Vector2f loc, float minR, float maxR, Color color, boolean spiral, float factor, float alphaMult)
Description getDescription(String id, Type type)
String getControlStringForEnumName(String name)