1package com.fs.starfarer.api.impl.campaign.procgen;
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.Iterator;
7import java.util.Random;
9import org.json.JSONArray;
10import org.json.JSONException;
11import org.json.JSONObject;
13import com.fs.starfarer.api.Global;
14import com.fs.starfarer.api.campaign.CargoAPI.CargoItemType;
15import com.fs.starfarer.api.campaign.CargoStackAPI;
16import com.fs.starfarer.api.campaign.SpecialItemData;
17import com.fs.starfarer.api.campaign.SpecialItemPlugin;
18import com.fs.starfarer.api.campaign.SpecialItemSpecAPI;
19import com.fs.starfarer.api.campaign.econ.CommoditySpecAPI;
20import com.fs.starfarer.api.combat.WeaponAPI.WeaponSize;
21import com.fs.starfarer.api.combat.WeaponAPI.WeaponType;
22import com.fs.starfarer.api.impl.campaign.ids.Tags;
23import com.fs.starfarer.api.loading.FighterWingSpecAPI;
24import com.fs.starfarer.api.loading.WeaponSpecAPI;
25import com.fs.starfarer.api.util.Misc;
26import com.fs.starfarer.api.util.WeightedRandomPicker;
29 public static final String
NOTHING =
"nothing";
38 private String commodity, group;
40 private boolean percent =
false;
42 private boolean multiValued =
false;
43 private int tier = -1;
44 private List<String> tags =
new ArrayList<String>();
46 private WeaponType weaponType =
null;
47 private WeaponSize weaponSize =
null;
52 Object writeReplace() {
54 if (tags !=
null && tags.isEmpty()) {
69 }
catch (CloneNotSupportedException e) {
75 commodity = row.getString(
"commodity");
76 group = row.getString(
"group");
78 String fStr = row.getString(
"freq");
79 if (fStr.endsWith(
"%")) {
81 fStr = fStr.substring(0, fStr.length() - 1);
82 freq = Float.parseFloat(fStr);
84 freq = (float) row.getDouble(
"freq");
89 private void parseData() throws JSONException {
90 if (commodity.contains(
":")) {
101 String test = commodity.replaceFirst(
ITEM_PREFIX,
"");
102 int index = test.indexOf(
':');
106 String itemId = test.substring(0, index);
107 String secondPart = test.substring(index + 1);
109 if (itemId.isEmpty() && secondPart.startsWith(
"{")) {
110 JSONObject json =
new JSONObject(secondPart);
112 tier = json.optInt(
"tier", -1);
113 if (json.has(
"tags")) {
114 JSONArray tags = json.getJSONArray(
"tags");
115 for (
int i = 0; i < tags.length(); i++) {
116 this.tags.add(tags.getString(i));
119 }
else if (!secondPart.startsWith(
"{")) {
127 JSONObject json =
new JSONObject(commodity.substring(commodity.indexOf(
":") + 1));
128 tier = json.optInt(
"tier", -1);
129 if (json.has(
"tags")) {
130 JSONArray tags = json.getJSONArray(
"tags");
131 for (
int i = 0; i < tags.length(); i++) {
132 this.tags.add(tags.getString(i));
135 if (json.has(
"weaponType")) {
136 weaponType = Misc.mapToEnum(json,
"weaponType", WeaponType.class,
null);
138 if (json.has(
"weaponSize")) {
139 weaponSize = Misc.mapToEnum(json,
"weaponSize", WeaponSize.class,
null);
145 this.commodity = commodity;
150 }
catch (JSONException e) {
151 throw new RuntimeException(e);
177 if (
isMultiValued())
throw new RuntimeException(
"Call resolveToSpecificItem() before calling getBaseUnitValue()");
206 return commodity !=
null && commodity.startsWith(
WEAPON_PREFIX);
214 String afterPrefix = commodity.substring(
ITEM_PREFIX.length());
215 int index = afterPrefix.indexOf(
":");
217 afterPrefix = afterPrefix.substring(0, index);
222 String afterPrefix = commodity.substring(
ITEM_PREFIX.length());
223 int index = afterPrefix.indexOf(
":");
225 afterPrefix = afterPrefix.substring(index + 1);
242 return commodity !=
null && commodity.startsWith(
ITEM_PREFIX);
262 return commodity ==
null || commodity.equals(
NOTHING);
270 this.commodity = commodity;
298 if (!spec.isMultiValued() && spec.isFighterWing() && spec.getFighterWingSpec().hasTag(
Tags.
WING_NO_DROP)) {
302 if (spec.getGroup().equals(group)) {
303 picker.
add(spec, spec.getFreq());
308 if (curr.isNothing() && curr.percent) {
309 float totalOther = picker.
getTotal() - curr.freq;
311 float fNothing = curr.freq / 100f;
312 if (fNothing < 0) fNothing = 0;
313 if (fNothing > 1) fNothing = 1;
315 float weightNothing = totalOther * fNothing / (1f - fNothing);
323 throw new RuntimeException(
"No drop data found for drop group [" + group +
"], probably an error in drop_groups.csv");
331 if (random ==
null) random =
new Random();
336 copy.multiValued =
false;
346 String test = commodity.replaceFirst(
ITEM_PREFIX,
"");
347 int index = test.indexOf(
':');
350 boolean getParamsFromP =
false;
351 String itemId = test.substring(0, index);
352 String params = test.substring(index + 1);
354 if (!itemId.isEmpty()) {
359 Iterator<SpecialItemSpecAPI> iter = specs.iterator();
365 if (!tags.isEmpty()) {
366 iter = specs.iterator();
367 while (iter.hasNext()) {
369 for (String tag : tags) {
370 boolean not = tag.startsWith(
"!");
371 tag = not ? tag.substring(1) : tag;
372 boolean has = curr.
hasTag(tag);
383 picker.
add(spec, 1f * spec.getRarity());
389 itemId = pick.
getId();
390 getParamsFromP =
true;
395 if (!itemId.isEmpty()) {
398 if (getParamsFromP) {
399 JSONObject json =
new JSONObject(params);
401 params = json.getJSONObject(
"p").toString();
411 if (itemData ==
null) {
413 }
else if (itemData.isEmpty()) {
416 copy.commodity =
ITEM_PREFIX + itemId +
":" + itemData;
421 }
catch (JSONException e) {
422 throw new RuntimeException(
"Params: " + params, e);
478 Iterator<WeaponSpecAPI> iter = specs.iterator();
479 while (iter.hasNext()) {
481 if (curr.
getTier() != tier) iter.remove();
485 if (!tags.isEmpty()) {
486 Iterator<WeaponSpecAPI> iter = specs.iterator();
487 while (iter.hasNext()) {
489 for (String tag : tags) {
490 boolean not = tag.startsWith(
"!");
491 tag = not ? tag.substring(1) : tag;
492 boolean has = curr.
hasTag(tag);
501 if (weaponType !=
null || weaponSize !=
null) {
502 Iterator<WeaponSpecAPI> iter = specs.iterator();
503 while (iter.hasNext()) {
505 if ((weaponType !=
null && curr.
getType() != weaponType) ||
506 (weaponSize !=
null && curr.
getSize() != weaponSize)) {
516 picker.
add(spec, 1f * spec.getRarity());
526 Iterator<FighterWingSpecAPI> iter = specs.iterator();
527 while (iter.hasNext()) {
532 iter = specs.iterator();
533 while (iter.hasNext()) {
535 if (curr.
getTier() != tier) iter.remove();
539 if (!tags.isEmpty()) {
540 iter = specs.iterator();
541 while (iter.hasNext()) {
543 for (String tag : tags) {
544 boolean not = tag.startsWith(
"!");
545 tag = not ? tag.substring(1) : tag;
546 boolean has = curr.
hasTag(tag);
557 picker.
add(spec, 1f * spec.getRarity());
573 return super.toString() +
" " + commodity;
static SettingsAPI getSettings()
static FactoryAPI getFactory()
static SectorAPI getSector()
static final String FIGHTER_PREFIX
DropGroupRow(JSONObject row)
static WeightedRandomPicker< DropGroupRow > getPicker(String group)
DropGroupRow(String commodity, String group, float freq)
void setCommodity(String commodity)
String getFighterWingId()
static final String NOTHING
String getSpecialItemId()
static final String WEAPON_PREFIX
static final String ITEM_PREFIX
DropGroupRow resolveToSpecificItem(Random random)
FighterWingSpecAPI getFighterWingSpec()
String getSpecialItemData()
CommoditySpecAPI getSpec()
WeaponSpecAPI getWeaponSpec()
void setGroup(String group)
SpecialItemSpecAPI getSpecialItemSpec()
void setWeight(int index, float weight)
CargoStackAPI createCargoStack(CargoItemType type, Object data, CargoAPI cargo)
SpecialItemSpecAPI getSpecialItemSpec(String itemId)
< T > Collection< T > getAllSpecs(Class< T > c)
List< WeaponSpecAPI > getAllWeaponSpecs()
FighterWingSpecAPI getFighterWingSpec(String wingId)
List< SpecialItemSpecAPI > getAllSpecialItemSpecs()
WeaponSpecAPI getWeaponSpec(String weaponId)
List< FighterWingSpecAPI > getAllFighterWingSpecs()
SpecialItemPlugin getPlugin()
int getPrice(MarketAPI market, SubmarketAPI submarket)
String resolveDropParamsToSpecificItemData(String params, Random random)
boolean hasTag(String tag)
SpecialItemPlugin getNewPluginInstance(CargoStackAPI stack)
CommoditySpecAPI getCommoditySpec(String commodityId)
boolean hasTag(String tag)
boolean hasTag(String tag)