001package com.fs.starfarer.api.impl.campaign.procgen; 002 003import java.util.ArrayList; 004import java.util.HashSet; 005import java.util.List; 006import java.util.Set; 007 008import org.json.JSONException; 009import org.json.JSONObject; 010 011import com.fs.starfarer.api.util.Misc; 012import com.fs.starfarer.api.util.WeightedRandomPicker; 013 014public class SalvageEntityGenDataSpec { 015 016 public static enum DiscoverabilityType { 017 DISCOVERABLE, 018 NOT_DISCOVERABLE, 019 ALWAYS_VISIBLE, 020 } 021 022 public static class DropData implements Cloneable { 023 transient public String group; 024 transient public int chances = -1; 025 transient public int maxChances = -1; 026 transient public int value = -1; 027 transient public float valueMult = 1f; 028 private WeightedRandomPicker<DropGroupRow> custom = null; 029 030 private String j = null; 031// public DropData(String group) { 032// this.group = group; 033// } 034 Object readResolve() { 035 if (j != null) { 036 try { 037 JSONObject json = new JSONObject(j); 038 if (json.has("g")) group = json.getString("g"); 039 if (json.has("c")) { 040 chances = json.getInt("c"); 041 } else { 042 chances = -1; 043 } 044 if (json.has("mC")) { 045 maxChances = json.getInt("mC"); 046 } else { 047 maxChances = -1; 048 } 049 if (json.has("v")) { 050 value = json.getInt("v"); 051 } else { 052 value = -1; 053 } 054 if (json.has("vM")) { 055 valueMult = (float) json.getDouble("vM"); 056 } else { 057 valueMult = 1f; 058 } 059 } catch (JSONException e) { 060 throw new RuntimeException(e); 061 } 062 } 063 return this; 064 } 065 066 Object writeReplace() { 067 try { 068 JSONObject json = new JSONObject(); 069 if (group != null) json.put("g", group); 070 if (chances > 0) json.put("c", chances); 071 if (maxChances > 0) json.put("mC", maxChances); 072 if (value > 0) json.put("v", value); 073 if (valueMult != 1) json.put("vM", valueMult); 074 j = json.toString(); 075 } catch (JSONException e) { 076 throw new RuntimeException(e); 077 } 078 return this; 079 } 080 081 082 public void addWeapon(String id, float weight) { 083 addCustom(DropGroupRow.WEAPON_PREFIX + id, weight); 084 } 085 public void addHullMod(String id, float weight) { 086 //addCustom(DropGroupRow.MOD_PREFIX + id, weight); 087 addCustom("item_modspec:" + id, weight); 088 } 089 public void addFighterChip(String id, float weight) { 090 addCustom(DropGroupRow.FIGHTER_PREFIX + id, weight); 091 } 092 public void addNothing(float weight) { 093 addCustom(DropGroupRow.NOTHING, weight); 094 } 095 public void addCommodity(String id, float weight) { 096 addCustom(id, weight); 097 } 098 public void addSpecialItem(String data, float weight) { 099 addCustom(DropGroupRow.ITEM_PREFIX + data, weight); 100 } 101 public void addCustom(String data, float weight) { 102 initCustom(); 103 for (int i = 0; i < custom.getItems().size(); i++) { 104 DropGroupRow row = custom.getItems().get(i); 105 if (row.getCommodity() != null && row.getCommodity().equals(data)) { 106 float w = custom.getWeight(i); 107 w += weight; 108 custom.setWeight(i, w); 109 return; 110 } 111 } 112 DropGroupRow row = new DropGroupRow(data, "custom", weight); 113 custom.add(row, weight); 114 } 115 116 public void addRandomWeapons(int tier, float weight) { 117 addCustom(DropGroupRow.WEAPON_PREFIX, tier, weight, (String []) null); 118 } 119 public void addRandomWeapons(int tier, float weight, String ... tags) { 120 addCustom(DropGroupRow.WEAPON_PREFIX, tier, weight, tags); 121 } 122 123 public void addRandomHullmods(int tier, float weight) { 124 //addCustom(DropGroupRow.MOD_PREFIX, tier, weight, (String []) null); 125 addCustom("item_modspec:", tier, weight, (String []) null); 126 } 127 public void addRandomHullmods(int tier, float weight, String ... tags) { 128 //addCustom(DropGroupRow.MOD_PREFIX, tier, weight, tags); 129 addCustom("item_modspec:", tier, weight, tags); 130 } 131 132 public void addRandomFighters(int tier, float weight) { 133 addCustom(DropGroupRow.FIGHTER_PREFIX, tier, weight, (String []) null); 134 } 135 public void addRandomFighters(int tier, float weight, String ... tags) { 136 addCustom(DropGroupRow.FIGHTER_PREFIX, tier, weight, tags); 137 } 138 139 private void addCustom(String prefix, int tier, float weight, String ... tags) { 140 initCustom(); 141 142 String data = prefix; 143 data += "{"; 144 if (tier >= 0) { 145 data += "tier:" + tier + ","; 146 } 147 if (tags != null && tags.length > 0) { 148 data += "tags:["; 149 for (String tag : tags) { 150 data += tag + ","; 151 } 152 data += "]"; 153 } 154 data += "}"; 155 DropGroupRow row = new DropGroupRow(data, "custom", weight); 156 custom.add(row, weight); 157 } 158 159 public void initCustom() { 160 if (custom == null) { 161 custom = new WeightedRandomPicker<DropGroupRow>(); 162 } 163 } 164 165 public void clearCustom() { 166 custom = null; 167 } 168 169 public WeightedRandomPicker<DropGroupRow> getCustom() { 170 return custom; 171 } 172 173 @Override 174 public DropData clone() { 175 try { 176 DropData copy = (DropData) super.clone(); 177 178 if (custom != null) { 179 copy.custom = new WeightedRandomPicker<DropGroupRow>(); 180 for (int i = 0; i < custom.getItems().size(); i++) { 181 copy.custom.add(custom.getItems().get(i), custom.getWeight(i)); 182 } 183 } 184 return copy; 185 } catch (CloneNotSupportedException e) { 186 throw new RuntimeException(e); 187 } 188 } 189 } 190 191// id,rating,detection_range,xpGain,drop_value,drop_random 192// derelict_probe,0,2000,500,"basic:2000, extended:500",ai_cores1:1 193// probDefenders minStr maxStr maxSize 194 // probStation stationRole 195 private String id; 196 private String nameOverride; 197 private float salvageRating, detectionRange, xpDiscover, xpSalvage, radiusOverride = -1f; 198 private DiscoverabilityType type; 199 private float probDefenders, defQuality, minStr, maxStr, maxDefenderSize, minDefenderSize, probStation; 200 private String stationRole; 201 private String defFaction; 202 203// private Map<String, Float> dropValue = new HashMap<String, Float>(); 204// private Map<String, Float> dropRandom = new HashMap<String, Float>(); 205 private List<DropData> dropValue = new ArrayList<DropData>(); 206 private List<DropData> dropRandom = new ArrayList<DropData>(); 207 208 private Set<String> tags = new HashSet<String>(); 209 210 public SalvageEntityGenDataSpec(JSONObject row) throws JSONException { 211 id = row.getString("id"); 212 213 stationRole = row.getString("stationRole"); 214 215 nameOverride = row.optString("name"); 216 if (nameOverride != null && nameOverride.isEmpty()) nameOverride = null; 217 218 salvageRating = (float) row.optDouble("rating", 0); 219 detectionRange = (float) row.optDouble("detection_range", 0); 220 221 float baseXP = 200 + 1 * (salvageRating * 20f); 222 //baseXP /= 3f; 223 baseXP = Misc.getRounded(baseXP); 224// if (id.equals("ruins_vast")) { 225// System.out.println("wefwefe"); 226// } 227 xpDiscover = (float) row.optDouble("xpDiscover", baseXP); 228 xpSalvage = (float) row.optDouble("xpSalvage", baseXP * 3f); 229 230 radiusOverride = (float) row.optDouble("radius", -1); 231 232 defQuality = (float) row.optDouble("defQuality", 1f); 233 234 probDefenders = (float) row.optDouble("probDefenders", 0); 235 minStr = (float) row.optDouble("minStr", 0); 236 maxStr = (float) row.optDouble("maxStr", 0); 237 maxDefenderSize = (float) row.optDouble("maxSize", 4); 238 minDefenderSize = (float) row.optDouble("minSize", 0); 239 240 defFaction = row.optString("defFaction", null); 241 if (defFaction != null && defFaction.isEmpty()) defFaction = null; 242 243 probStation = (float) row.optDouble("probStation", 0); 244 245 type = Misc.mapToEnum(row, "type", DiscoverabilityType.class, DiscoverabilityType.DISCOVERABLE); 246 247 if (row.has("drop_value") && !row.getString("drop_value").isEmpty()) { 248 //readToMap(row.getString("drop_value"), dropValue); 249 String [] parts = row.getString("drop_value").split(","); 250 for (String part : parts) { 251 part = part.trim(); 252 String [] pair = part.split(":"); 253 String key = pair[0].trim(); 254 String value = pair[1].trim(); 255 256 DropData data = new DropData(); 257 data.group = key; 258 data.value = Integer.valueOf(value); 259 data.chances = -1; 260 261 dropValue.add(data); 262 } 263 } 264 265 if (row.has("drop_random") && !row.getString("drop_random").isEmpty()) { 266 //readToMap(row.getString("drop_random"), dropRandom); 267 String [] parts = row.getString("drop_random").split(","); 268 for (String part : parts) { 269 part = part.trim(); 270 String [] pair = part.split(":"); 271 String key = pair[0].trim(); 272 String value = pair[1].trim(); 273 274 DropData data = new DropData(); 275 data.group = key; 276 277 if (value.contains("x")) { 278 String [] chancesXValue = value.split("x"); 279 if (chancesXValue[0].trim().contains("-")) { 280 data.chances = Integer.valueOf(chancesXValue[0].trim().split("-")[0]); 281 data.maxChances = Integer.valueOf(chancesXValue[0].trim().split("-")[1]); 282 } else { 283 data.chances = Integer.valueOf(chancesXValue[0].trim()); 284 } 285 data.value = Integer.valueOf(chancesXValue[1].trim()); 286 } else { 287 data.value = -1; 288 289 if (value.contains("-")) { 290 data.chances = Integer.valueOf(value.trim().split("-")[0]); 291 data.maxChances = Integer.valueOf(value.trim().split("-")[1]); 292 } else { 293 float c = Float.valueOf(value); 294 data.chances = (int) Math.max(c, 1); 295 if (c < 1) data.valueMult = c; 296 } 297 //data.chances = Integer.valueOf(value); 298 } 299 300 dropRandom.add(data); 301 } 302 } 303 304 String tags = row.optString("tags", null); 305 if (tags != null) { 306 String [] split = tags.split(","); 307 for (String tag : split) { 308 tag = tag.trim(); 309 if (tag.isEmpty()) continue; 310 addTag(tag); 311 } 312 } 313 } 314 315 public String getDefFaction() { 316 return defFaction; 317 } 318 319 public void setDefFaction(String defFaction) { 320 this.defFaction = defFaction; 321 } 322 323 324 public Set<String> getTags() { 325 return tags; 326 } 327 328 public void addTag(String tag) { 329 tags.add(tag); 330 } 331 332 public boolean hasTag(String tag) { 333 return tags.contains(tag); 334 } 335 336 public float getRadiusOverride() { 337 return radiusOverride; 338 } 339 340 public void setRadiusOverride(float radiusOverride) { 341 this.radiusOverride = radiusOverride; 342 } 343 344 public String getNameOverride() { 345 return nameOverride; 346 } 347 348 public void setNameOverride(String nameOverride) { 349 this.nameOverride = nameOverride; 350 } 351 352 public String getId() { 353 return id; 354 } 355 public void setId(String id) { 356 this.id = id; 357 } 358 public float getSalvageRating() { 359 return salvageRating; 360 } 361 public void setSalvageRating(float salvageRating) { 362 this.salvageRating = salvageRating; 363 } 364 public float getDetectionRange() { 365 return detectionRange; 366 } 367 public void setDetectionRange(float detectionRange) { 368 this.detectionRange = detectionRange; 369 } 370 public float getXpDiscover() { 371 return xpDiscover; 372 } 373 public void setXpDiscover(float xpDiscover) { 374 this.xpDiscover = xpDiscover; 375 } 376 public float getXpSalvage() { 377 return xpSalvage; 378 } 379 public void setXpSalvage(float xpSalvage) { 380 this.xpSalvage = xpSalvage; 381 } 382 383 384 public List<DropData> getDropValue() { 385 return dropValue; 386 } 387 public List<DropData> getDropRandom() { 388 return dropRandom; 389 } 390 public DiscoverabilityType getType() { 391 return type; 392 } 393 public void setType(DiscoverabilityType type) { 394 this.type = type; 395 } 396 public float getProbDefenders() { 397 return probDefenders; 398 } 399 public void setProbDefenders(float probDefenders) { 400 this.probDefenders = probDefenders; 401 } 402 public float getMinStr() { 403 return minStr; 404 } 405 public void setMinStr(float minStr) { 406 this.minStr = minStr; 407 } 408 public float getMaxStr() { 409 return maxStr; 410 } 411 public void setMaxStr(float maxStr) { 412 this.maxStr = maxStr; 413 } 414 public float getMaxDefenderSize() { 415 return maxDefenderSize; 416 } 417 public void setMaxDefenderSize(float maxSize) { 418 this.maxDefenderSize = maxSize; 419 } 420 421 public float getMinDefenderSize() { 422 return minDefenderSize; 423 } 424 425 public void setMinDefenderSize(float minDefenderSize) { 426 this.minDefenderSize = minDefenderSize; 427 } 428 429 public float getDefQuality() { 430 return defQuality; 431 } 432 433 public void setDefQuality(float defQuality) { 434 this.defQuality = defQuality; 435 } 436 437 public float getProbStation() { 438 return probStation; 439 } 440 441 public void setProbStation(float probStation) { 442 this.probStation = probStation; 443 } 444 445 public String getStationRole() { 446 return stationRole; 447 } 448 449 public void setStationRole(String stationRole) { 450 this.stationRole = stationRole; 451 } 452 453 454// public static void readToMap(String input, Map<String, Float> map) { 455// String [] parts = input.split(","); 456// for (String part : parts) { 457// part = part.trim(); 458// String [] pair = part.split(":"); 459// String key = pair[0].trim(); 460// float value = Float.valueOf(pair[1].trim()); 461// map.put(key, value); 462// } 463// } 464 465// public static void verifySpecsExist(Class clazz, List<String> specs, String desc) { 466// for (String id : specs) { 467// Object spec = Global.getSettings().getSpec(clazz, id, true); 468// if (spec == null) { 469// throw new RuntimeException("Spec of class " + clazz.getName() + 470// " with id [" + id + "] not found while verifying [" + 471// desc + "]"); 472// } 473// } 474// } 475 476 477}