Starsector API
Loading...
Searching...
No Matches
PlanetConditionGenerator.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.procgen;
2
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.Collections;
6import java.util.Comparator;
7import java.util.HashMap;
8import java.util.HashSet;
9import java.util.LinkedHashMap;
10import java.util.List;
11import java.util.Map;
12import java.util.Set;
13
14import com.fs.starfarer.api.Global;
15import com.fs.starfarer.api.campaign.PlanetAPI;
16import com.fs.starfarer.api.campaign.StarSystemAPI;
17import com.fs.starfarer.api.campaign.econ.MarketAPI;
18import com.fs.starfarer.api.campaign.econ.MarketConditionAPI;
19import com.fs.starfarer.api.impl.campaign.ids.Factions;
20import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator.CustomConstellationParams;
21import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator.GenContext;
22import com.fs.starfarer.api.util.Misc;
23import com.fs.starfarer.api.util.WeightedRandomPicker;
24
26
27 public static interface ConditionGenerator {
28 void addConditions(Set<String> conditionsSoFar, GenContext context, PlanetAPI planet);
29 }
30
31
35 public static Map<String, ConditionGenerator> generators = new HashMap<String, ConditionGenerator>();
36
37 static {
38 generators.put("gravity", new GravityConditionGenerator());
39 generators.put("cold", new ColdConditionGenerator());
40 generators.put("hot", new HotConditionGenerator());
41 generators.put("light", new LightConditionGenerator());
42 generators.put("radiation", new RadiationConditionGenerator());
43 }
44
45
46
47 public static void generateConditionsForPlanet(GenContext context, PlanetAPI planet) {
48 generateConditionsForPlanet(context, planet, null);
49 }
50
51 public static void generateConditionsForPlanet(PlanetAPI planet, StarAge age) {
52 generateConditionsForPlanet(null, planet, age);
53 }
54
55 public static void generateConditionsForPlanet(GenContext context, PlanetAPI planet, StarAge age) {
56
57 if (context == null) {
58// if (planet.getId().toLowerCase().equals("tlalocan")) {
59// System.out.println("sdfwefe");
60// }
61 context = createContext(planet, age);
62 }
63
64 Collection<ConditionGenDataSpec> all = Global.getSettings().getAllSpecs(ConditionGenDataSpec.class);
65 List<ConditionGenDataSpec> specs = new ArrayList<ConditionGenDataSpec>();
66 for (ConditionGenDataSpec spec : all) {
67 specs.add(spec);
68 }
69
70 Collections.sort(specs, new Comparator<ConditionGenDataSpec>() {
71 public int compare(ConditionGenDataSpec o1, ConditionGenDataSpec o2) {
72 return (int) Math.signum(o1.getOrder() - o2.getOrder());
73 }
74 });
75
76 Map<String, List<String>> groupsInOrder = new LinkedHashMap<String, List<String>>();
77 float prevGroup = -100000;
78 List<String> currList = null;
79 for (ConditionGenDataSpec spec : specs) {
80 float currGroup = spec.getOrder();
81 if (prevGroup != currGroup) {
82 currList = new ArrayList<String>();
83 groupsInOrder.put(spec.getGroup(), currList);
84 }
85 prevGroup = currGroup;
86
87 if (!currList.contains(spec.getGroup())) {
88 currList.add(spec.getGroup());
89 }
90 }
91
92
93// List<String> groups = new ArrayList<String>();
94// //String prev = null;
95// for (ConditionGenDataSpec spec : specs) {
96// if (spec.getGroup() == null) continue;
97// //if (!spec.getGroup().equals(prev)) {
98// if (!groups.contains(spec.getGroup())) {
99// groups.add(spec.getGroup());
100// }
101// //prev = spec.getGroup();
102// }
103
104
105 Set<String> conditionsSoFar = new HashSet<String>();
106
107 // want to add random/fixed conditions for ALL groups with the same order first,
108 // then do generators.
109 // why: fixed hot/cold need to be added before hot/cold generators so
110 // that those generators can process the conditions correctly.
111 // this is due to hot/cold circular requirement dependency: hot req !cold, and vice versa
112 for (String key : groupsInOrder.keySet()) {
113 List<String> groups = groupsInOrder.get(key);
114 for (String group : groups) {
115 WeightedRandomPicker<String> picker = getGroupPicker(group, conditionsSoFar, context, planet);
116 String pick = picker.pick();
117 if (pick != null) {
118 conditionsSoFar.add(pick);
119 }
120 }
121
122 for (String group : groups) {
123 ConditionGenerator generator = generators.get(group);
124 if (generator != null) {
125 generator.addConditions(conditionsSoFar, context, planet);
126 }
127 }
128 }
129
130
131 // add picked conditions to market
132 MarketAPI market = planet.getMarket();
133 if (market == null) {
134 market = Global.getFactory().createMarket("market_" + planet.getId(), planet.getName(), 1);
135 //market = Global.getFactory().createConditionMarket("market_" + planet.getId(), planet.getName(), 1);
136 market.setPlanetConditionMarketOnly(true);
137 market.setPrimaryEntity(planet);
138 market.setFactionId(Factions.NEUTRAL);
139 planet.setMarket(market);
140 }
141
142 for (String cid : conditionsSoFar) {
143 if (cid.endsWith(ConditionGenDataSpec.NO_PICK_SUFFIX)) continue;
144 //planet.getMemory().set("$genCondition:" + condition, true);
145
146 MarketConditionAPI mc = market.getSpecificCondition(market.addCondition(cid));
147
149 mc.setSurveyed(!spec.isRequiresSurvey());
150 }
151
152 market.reapplyConditions();
153 }
154
155
156 public static WeightedRandomPicker<String> getGroupPicker(String group, Set<String> conditionsSoFar,
157 GenContext context, PlanetAPI planet) {
158
159 WeightedRandomPicker<String> picker = new WeightedRandomPicker<String>(StarSystemGenerator.random);
160
161 List<ConditionGenDataSpec> groupData = getDataForGroup(group);
162
163 String planetType = planet.getSpec().getPlanetType();
164// if (planetType.equals("lava")) {
165// System.out.println("sdfwefwe");
166// }
167
168 PlanetGenDataSpec planetData = (PlanetGenDataSpec) Global.getSettings().getSpec(PlanetGenDataSpec.class, planetType, false);
169
170 String category = planetData.getCategory();
171
172 for (ConditionGenDataSpec data : groupData) {
173 float weight = 1f;
174 if (data.hasMultiplier(planetType)) {
175 weight = data.getMultiplier(planetType);
176 } else if (data.hasMultiplier(category)) {
177 weight = data.getMultiplier(category);
178 } else {
179 continue;
180 }
181
182 for (String cid : conditionsSoFar) {
183 if (data.hasMultiplier(cid)) {
184 weight *= data.getMultiplier(cid);
185 }
186 }
187
188 if (weight <= 0) continue;
189
190 if (!preconditionsMet(data.getId(), conditionsSoFar)) continue;
191
192 picker.add(data.getId(), weight);
193 }
194
195 return picker;
196 }
197
198
199 public static boolean preconditionsMet(String conditionId, Set<String> conditionsSoFar) {
201
202 boolean foundAll = true;
203 for (String cid : data.getRequiresAll()) {
204 if (!conditionsSoFar.contains(cid)) {
205 foundAll = false;
206 break;
207 }
208 }
209 if (!foundAll) return false;
210
211
212 boolean foundOne = false;
213 for (String cid : data.getRequiresAny()) {
214 if (conditionsSoFar.contains(cid)) {
215 foundOne = true;
216 break;
217 }
218 }
219 if (!foundOne && !data.getRequiresAny().isEmpty()) return false;
220
221
222 foundOne = false;
223 for (String cid : data.getRequiresNotAny()) {
224 if (conditionsSoFar.contains(cid)) {
225 foundOne = true;
226 break;
227 }
228 }
229 if (foundOne) return false;
230
231 return true;
232 }
233
234
235 public static List<ConditionGenDataSpec> getDataForGroup(String group) {
236 List<ConditionGenDataSpec> result = new ArrayList<ConditionGenDataSpec>();
237 Collection<ConditionGenDataSpec> all = Global.getSettings().getAllSpecs(ConditionGenDataSpec.class);
238 for (ConditionGenDataSpec spec : all) {
239 if (group.equals(spec.getGroup())) {
240 result.add(spec);
241 }
242 }
243 return result;
244 }
245
246
247 public static GenContext createContext(PlanetAPI planet, StarAge age) {
248
249 if (!(planet.getContainingLocation() instanceof StarSystemAPI)) return null;
250
251 StarSystemAPI system = (StarSystemAPI) planet.getContainingLocation();
252
253 CustomConstellationParams p = new CustomConstellationParams(age);
255 gen.system = system;
256 gen.starData = (StarGenDataSpec) Global.getSettings().getSpec(StarGenDataSpec.class, system.getStar().getSpec().getPlanetType(), false);
257 gen.starAge = age;
258 gen.constellationAge = age;
259 gen.starAgeData = (AgeGenDataSpec) Global.getSettings().getSpec(AgeGenDataSpec.class, age.name(), true);
260 gen.star = system.getStar();
262
263 gen.systemCenter = system.getCenter();
264
265
266 PlanetAPI parentPlanet = null;
267 PlanetAPI parentStar = null;
268 if (planet.getOrbitFocus() instanceof PlanetAPI) {
269 PlanetAPI p1 = (PlanetAPI) planet.getOrbitFocus();
270 PlanetAPI p2 = null;
271 if (p1.getOrbitFocus() instanceof PlanetAPI) {
272 p2 = (PlanetAPI) p1.getOrbitFocus();
273 }
274 if (p1.isStar()) {
275 parentStar = p1;
276 } else {
277 parentPlanet = p1;
278 if (p2 != null && p2.isStar()) {
279 parentStar = p2;
280 } else {
281 parentStar = system.getStar();
282 }
283 }
284 } else {
285 parentStar = system.getStar();
286 }
287
288 StarGenDataSpec starData = gen.starData;
289 PlanetGenDataSpec planetData = null;
290 if (parentStar != null) {
291 starData = (StarGenDataSpec) Global.getSettings().getSpec(StarGenDataSpec.class, parentStar.getSpec().getPlanetType(), false);
292 }
293 if (parentPlanet != null) {
294 planetData = (PlanetGenDataSpec) Global.getSettings().getSpec(PlanetGenDataSpec.class, parentPlanet.getSpec().getPlanetType(), false);
295 }
296
297 int parentOrbitIndex = -1;
298 int orbitIndex = 0;
299
300 float fromStar = 0;
301 if (parentPlanet == null) {
302 orbitIndex = Misc.getEstimatedOrbitIndex(planet);
303 parentOrbitIndex = -1;
304 float dist = Misc.getDistance(parentStar.getLocation(), planet.getLocation());
305 fromStar = dist;
306 } else {
307 parentOrbitIndex = Misc.getEstimatedOrbitIndex(planet);
308 float dist = 0f;
309 if (parentPlanet.getOrbitFocus() != null) {
310 dist = Misc.getDistance(parentPlanet.getLocation(), parentPlanet.getOrbitFocus().getLocation());
311 fromStar = dist;
312 }
313 orbitIndex = 1; // don't care about index of moon's orbit
314 }
315
316// if (parentOrbitIndex >= 0) {
317// System.out.println("Orbit index for " + planet.getName() + ": " + parentOrbitIndex);
318// } else {
319// System.out.println("Orbit index for " + planet.getName() + ": " + orbitIndex);
320// }
321
322 GenContext context = new GenContext(gen, system, gen.systemCenter, starData,
323 parentPlanet, orbitIndex, age.name(), fromStar, StarSystemGenerator.MAX_ORBIT_RADIUS,
324 planetData != null ? planetData.getCategory() : null, parentOrbitIndex);
325 context.orbitIndex = orbitIndex;
326
327 return context;
328 }
329}
330
331
332
333
334
335
336
337
338
339
340
341
342
static SettingsAPI getSettings()
Definition Global.java:51
static FactoryAPI getFactory()
Definition Global.java:35
static boolean preconditionsMet(String conditionId, Set< String > conditionsSoFar)
static void generateConditionsForPlanet(GenContext context, PlanetAPI planet)
static WeightedRandomPicker< String > getGroupPicker(String group, Set< String > conditionsSoFar, GenContext context, PlanetAPI planet)
static void generateConditionsForPlanet(GenContext context, PlanetAPI planet, StarAge age)
MarketAPI createMarket(String id, String name, int size)
< T > Collection< T > getAllSpecs(Class< T > c)
Object getSpec(Class c, String id, boolean nullOnNotFound)