Starsector API
Loading...
Searching...
No Matches
HyperspaceAbyssPluginImpl.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.terrain;
2
3import java.util.ArrayList;
4import java.util.List;
5import java.util.Random;
6
7import org.lwjgl.util.vector.Vector2f;
8
9import com.fs.starfarer.api.Global;
10import com.fs.starfarer.api.campaign.CampaignFleetAPI;
11import com.fs.starfarer.api.campaign.LocationAPI;
12import com.fs.starfarer.api.campaign.StarSystemAPI;
13import com.fs.starfarer.api.impl.campaign.enc.EncounterPoint;
14import com.fs.starfarer.api.impl.campaign.enc.EncounterPointProvider;
15import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator.StarSystemType;
16import com.fs.starfarer.api.util.Misc;
17
19
20 public static String EP_TYPE_ABYSSAL = "ep_type_abyssal";
21
22 public static float ENCOUNTER_NEAR_ABYSSAL_SYSTEM_DIST = 2000f;
23
24
25 public static float NASCENT_WELL_DETECTED_RANGE = 1000f;
26 public static float JUMP_POINT_DETECTED_RANGE = 1300f;
27 public static float GAS_GIANT_DETECTED_RANGE = 1600f;
28 public static float STAR_DETECTED_RANGE = 2000f;
29
30
31 public static float DEPTH_THRESHOLD_FOR_ENCOUNTER = 0.25f;
32 public static float DEPTH_THRESHOLD_FOR_DWELLER_LIGHT = 3f;
33 public static float DEPTH_THRESHOLD_FOR_ABYSSAL_LIGHT = 1f;
35 public static float DEPTH_THRESHOLD_FOR_ABYSSAL_STAR_SYSTEM = 0.5f;
37 public static float DEPTH_THRESHOLD_FOR_FLEETS_FLEEING = 0.5f;
38
39
40 public static class AbyssalEPData {
44 public float depth;
45 public Random random;
46 public StarSystemAPI nearest = null;
47 public float distToNearest = Float.MAX_VALUE;
48
49 public AbyssalEPData() {
50
51 }
52 }
53
54
55 public static float PLAYER_DIST_TRAVELLED_TO_REGEN_EPS = 1000f; // units not light-years
56
57 protected Vector2f playerLocWhenGeneratingEPs = null;
58 protected List<EncounterPoint> encounterPoints = null;
59 protected Random random = new Random();
60
64
65 protected Object readResolve() {
66 if (random == null) {
67 random = new Random();
68 }
69 return this;
70 }
71
72 public float getAbyssalDepth(Vector2f loc, boolean uncapped) {
73 float w = Global.getSettings().getFloat("sectorWidth");
74 float h = Global.getSettings().getFloat("sectorHeight");
75
76 // Orion-Perseus Abyss, lower left of the map, plus whatever area outside the map
77 float baseW = 100000f;
78 float baseH = 50000f;
79
80 float normalizedX = (loc.x + w/2f) / baseW;
81 float normalizedY = (loc.y + h/2f) / baseH;
82
83 float test = (float) (Math.sqrt(Math.max(0f, normalizedX)) + Math.sqrt(Math.max(0f, normalizedY)));
84// float test = 1f;
85// if (normalizedX >= 0 && normalizedY >= 0) {
86// test = (float) (Math.sqrt(normalizedX) + Math.sqrt(normalizedY));
87// } else if (normalizedX < 0 && (loc.y + h/2f) < baseH) {
88// test = 0f;
89// } else if (normalizedY < 0 && (loc.x + w/2f) < baseW) {
90// test = 0f;
91// }
92
93// boolean player = Misc.getDistance(Global.getSector().getPlayerFleet().getLocationInHyperspace(), loc) < 5f;
94
95 float depthBasedOnCorner = 0f;
96 if (test < 1f) {
97 float threshold = 0.95f;
98// if (player) {
99// System.out.println("Depth: " + (1f - (test - threshold) / (1f - threshold)));
100// }
101 if (uncapped) {
102 //return (1f - (test - threshold) / (1f - threshold));
103 depthBasedOnCorner = (1f - (test - threshold) / (1f - threshold));
104 } else {
105 if (test < threshold) depthBasedOnCorner = 1f;
106 else depthBasedOnCorner = 1f - (test - threshold) / (1f - threshold);
107 }
108// if (test < threshold) return 1f;
109// return 1f - (test - threshold) / (1f - threshold);
110 }
111
112 // outside the map area
113 float left = -w/2f - loc.x;
114 float below = -h/2f - loc.y;
115 float right = loc.x - w/2f;
116 float above = loc.y - h/2f;
117
118 float max = Math.max(left, Math.max(right, Math.max(above, below)));
119 if (max > 0) {
120// if (player) {
121// System.out.println("Depth: " + max/2000f);
122// }
123// if (uncapped) return max / 2000f;
124// return Math.min(1f, max / 2000f);
125 if (uncapped) {
126 return Math.max(depthBasedOnCorner, max / 2000f);
127 }
128 return Math.min(1f, Math.max(depthBasedOnCorner, max / 2000f));
129 }
130
131 // inside the map, outside the Abyss area
132 //return 0f;
133 return depthBasedOnCorner;
134 }
135
139 public void advance(float amount) {
142 }
143
144 }
145
146 public List<StarSystemAPI> getAbyssalSystems() {
147 List<StarSystemAPI> abyssal = new ArrayList<StarSystemAPI>();
148 for (StarSystemAPI system : Global.getSector().getStarSystems()) {
149 float depth = Misc.getAbyssalDepth(system.getLocation());
151 abyssal.add(system);
152 }
153 }
154 return abyssal;
155 }
156
157
158
159 public List<EncounterPoint> generateEncounterPoints(LocationAPI where) {
160 if (!where.isHyperspace()) return null;
161
162 boolean regenerate = encounterPoints == null || playerLocWhenGeneratingEPs == null;
164
165 if (!regenerate) {
166 Vector2f loc = pf.getLocation();
168 regenerate = dist > PLAYER_DIST_TRAVELLED_TO_REGEN_EPS;
169 }
170
171 if (!regenerate) return encounterPoints;
172
173 List<StarSystemAPI> abyssal = getAbyssalSystems();
174
175 playerLocWhenGeneratingEPs = new Vector2f(pf.getLocation());
176 encounterPoints = new ArrayList<EncounterPoint>();
177
178 float startAngle = random.nextFloat() * 360f;
179 for (float angle = startAngle; angle < startAngle + 360f; angle += 30f) {
180 Vector2f loc = Misc.getUnitVectorAtDegreeAngle(angle);
181 float dist = 3000f;
182 loc.scale(dist);
183 Vector2f.add(loc, playerLocWhenGeneratingEPs, loc);
184 loc = Misc.getPointWithinRadius(loc, 1000f, random);
185
186 float depth = getAbyssalDepth(loc, true);
187 if (depth < DEPTH_THRESHOLD_FOR_ENCOUNTER) continue;
188
189 // Can match ids of other points, or have different ids for points that are
190 // very close to each other if they're across 1000-boundary
191 // this is fine. Just a way to *somewhat* limit repeated spawns in the same location
192
193 String id = "abyssal_" + (int)(loc.x/1000f) + "_" + (int)(loc.y/1000f);
194 EncounterPoint point = new EncounterPoint(id, where, loc, EP_TYPE_ABYSSAL);
195
196 AbyssalEPData data = new AbyssalEPData();
197 data.depth = depth;
198 data.random = Misc.getRandom(random.nextLong(), 7);
199
200 float minDist = Float.MAX_VALUE;
201 StarSystemAPI nearest = null;
202 for (StarSystemAPI system : abyssal) {
203 float distToSystem = Misc.getDistance(system.getLocation(), loc);
204 float testDist = ENCOUNTER_NEAR_ABYSSAL_SYSTEM_DIST;
205 if (system.getType() == StarSystemType.DEEP_SPACE) {
206 testDist *= 0.5f;
207 }
208 if (distToSystem < testDist && distToSystem < minDist) {
209 minDist = distToSystem;
210 nearest = system;
211 }
212 }
213 if (nearest != null) {
214 data.nearest = nearest;
215 data.distToNearest = minDist;
216 }
217
218 point.custom = data;
219 encounterPoints.add(point);
220 }
221
222 return encounterPoints;
223 }
224
225}
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
static SettingsAPI getSettings()
Definition Global.java:57
static SectorAPI getSector()
Definition Global.java:65
static Vector2f getUnitVectorAtDegreeAngle(float degrees)
Definition Misc.java:1196
static Random getRandom(long seed, int level)
Definition Misc.java:2973
static float getDistance(SectorEntityToken from, SectorEntityToken to)
Definition Misc.java:599
static float getAbyssalDepth(Vector2f loc)
Definition Misc.java:2330
static Vector2f getPointWithinRadius(Vector2f from, float r)
Definition Misc.java:711
List< StarSystemAPI > getStarSystems()
ListenerManagerAPI getListenerManager()