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
18public class HyperspaceAbyssPluginImpl extends BaseHyperspaceAbyssPlugin implements EncounterPointProvider {
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_ABYSSAL_LIGHT = 1f;
34 public static float DEPTH_THRESHOLD_FOR_ABYSSAL_STAR_SYSTEM = 0.5f;
36 public static float DEPTH_THRESHOLD_FOR_FLEETS_FLEEING = 0.5f;
37
38
39 public static class AbyssalEPData {
40 public float depth;
41 public Random random;
42 public StarSystemAPI nearest = null;
43 public float distToNearest = Float.MAX_VALUE;
44 }
45
46
47 public static float PLAYER_DIST_TRAVELLED_TO_REGEN_EPS = 1000f; // units not light-years
48
49 protected Vector2f playerLocWhenGeneratingEPs = null;
50 protected List<EncounterPoint> encounterPoints = null;
51 protected Random random = new Random();
52
54 Global.getSector().getListenerManager().addListener(this);
55 }
56
57 protected Object readResolve() {
58 if (random == null) {
59 random = new Random();
60 }
61 return this;
62 }
63
64 public float getAbyssalDepth(Vector2f loc) {
65 float w = Global.getSettings().getFloat("sectorWidth");
66 float h = Global.getSettings().getFloat("sectorHeight");
67
68 // Orion-Perseus Abyss, lower left of the map, plus whatever area outside the map
69 float baseW = 100000f;
70 float baseH = 50000f;
71
72 float normalizedX = (loc.x + w/2f) / baseW;
73 float normalizedY = (loc.y + h/2f) / baseH;
74
75 float test = 1f;
76 if (normalizedX >= 0 && normalizedY >= 0) {
77 test = (float) (Math.sqrt(normalizedX) + Math.sqrt(normalizedY));
78 } else if (normalizedX < 0 && (loc.y + h/2f) < baseH) {
79 test = 0f;
80 } else if (normalizedY < 0 && (loc.x + w/2f) < baseW) {
81 test = 0f;
82 }
83
84 if (test < 1f) {
85 float threshold = 0.95f;
86 if (test < threshold) return 1f;
87
88 return 1f - (test - threshold) / (1f - threshold);
89 }
90
91 // outside the map area
92 float left = -w/2f - loc.x;
93 float below = -h/2f - loc.y;
94 float right = loc.x - w/2f;
95 float above = loc.y - h/2f;
96
97 float max = Math.max(left, Math.max(right, Math.max(above, below)));
98 if (max > 0) {
99 return Math.min(1f, max / 2000f);
100 }
101
102 // inside the map, outside the Abyss area
103 return 0f;
104 }
105
109 public void advance(float amount) {
110 if (!Global.getSector().getListenerManager().hasListener(this)) {
111 Global.getSector().getListenerManager().addListener(this);
112 }
113
114 }
115
116 public List<StarSystemAPI> getAbyssalSystems() {
117 List<StarSystemAPI> abyssal = new ArrayList<StarSystemAPI>();
118 for (StarSystemAPI system : Global.getSector().getStarSystems()) {
119 float depth = Misc.getAbyssalDepth(system.getLocation());
121 abyssal.add(system);
122 }
123 }
124 return abyssal;
125 }
126
127
128
129 public List<EncounterPoint> generateEncounterPoints(LocationAPI where) {
130 if (!where.isHyperspace()) return null;
131
132 boolean regenerate = encounterPoints == null || playerLocWhenGeneratingEPs == null;
133 CampaignFleetAPI pf = Global.getSector().getPlayerFleet();
134
135 if (!regenerate) {
136 Vector2f loc = pf.getLocation();
137 float dist = Misc.getDistance(loc, playerLocWhenGeneratingEPs);
138 regenerate = dist > PLAYER_DIST_TRAVELLED_TO_REGEN_EPS;
139 }
140
141 if (!regenerate) return encounterPoints;
142
143 List<StarSystemAPI> abyssal = getAbyssalSystems();
144
145 playerLocWhenGeneratingEPs = new Vector2f(pf.getLocation());
146 encounterPoints = new ArrayList<EncounterPoint>();
147
148 float startAngle = random.nextFloat() * 360f;
149 for (float angle = startAngle; angle < startAngle + 360f; angle += 30f) {
150 Vector2f loc = Misc.getUnitVectorAtDegreeAngle(angle);
151 float dist = 3000f;
152 loc.scale(dist);
153 Vector2f.add(loc, playerLocWhenGeneratingEPs, loc);
154 loc = Misc.getPointWithinRadius(loc, 1000f, random);
155
156 float depth = getAbyssalDepth(loc);
157 if (depth < DEPTH_THRESHOLD_FOR_ENCOUNTER) continue;
158
159 // Can match ids of other points, or have different ids for points that are
160 // very close to each other if they're across 1000-boundary
161 // this is fine. Just a way to *somewhat* limit repeated spawns in the same location
162
163 String id = "abyssal_" + (int)(loc.x/1000f) + "_" + (int)(loc.y/1000f);
164 EncounterPoint point = new EncounterPoint(id, where, loc, EP_TYPE_ABYSSAL);
165
166 AbyssalEPData data = new AbyssalEPData();
167 data.depth = depth;
168 data.random = Misc.getRandom(random.nextLong(), 7);
169
170 float minDist = Float.MAX_VALUE;
171 StarSystemAPI nearest = null;
172 for (StarSystemAPI system : abyssal) {
173 float distToSystem = Misc.getDistance(system.getLocation(), loc);
174 float testDist = ENCOUNTER_NEAR_ABYSSAL_SYSTEM_DIST;
175 if (system.getType() == StarSystemType.DEEP_SPACE) {
176 testDist *= 0.5f;
177 }
178 if (distToSystem < testDist && distToSystem < minDist) {
179 minDist = distToSystem;
180 nearest = system;
181 }
182 }
183 if (nearest != null) {
184 data.nearest = nearest;
185 data.distToNearest = minDist;
186 }
187
188 point.custom = data;
189 encounterPoints.add(point);
190 }
191
192 return encounterPoints;
193 }
194
195}
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
static SettingsAPI getSettings()
Definition Global.java:51
static SectorAPI getSector()
Definition Global.java:59