4package com.fs.starfarer.api.impl.campaign.shared;
6import java.util.ArrayList;
7import java.util.Collection;
8import java.util.HashMap;
9import java.util.LinkedHashMap;
13import com.fs.starfarer.api.Global;
14import com.fs.starfarer.api.campaign.CargoAPI;
15import com.fs.starfarer.api.campaign.CargoAPI.CargoItemType;
16import com.fs.starfarer.api.campaign.CargoStackAPI;
17import com.fs.starfarer.api.campaign.PlayerMarketTransaction;
18import com.fs.starfarer.api.campaign.PlayerMarketTransaction.ShipSaleInfo;
19import com.fs.starfarer.api.campaign.econ.CommodityOnMarketAPI;
20import com.fs.starfarer.api.campaign.econ.MarketAPI;
21import com.fs.starfarer.api.campaign.econ.SubmarketAPI;
22import com.fs.starfarer.api.combat.MutableStatWithTempMods;
23import com.fs.starfarer.api.impl.campaign.ids.Commodities;
24import com.fs.starfarer.api.impl.campaign.ids.Conditions;
25import com.fs.starfarer.api.impl.campaign.ids.Stats;
26import com.fs.starfarer.api.impl.campaign.submarkets.BaseSubmarketPlugin.ShipSalesData;
27import com.fs.starfarer.api.util.IntervalUtil;
28import com.fs.starfarer.api.util.Misc;
32 private Map<String, MutableStatWithTempMods> tx =
new HashMap<String, MutableStatWithTempMods>();
34 private CargoAPI playerBought, playerSold;
35 private float accumulatedPlayerTradeValueForPositive = 0;
36 private float accumulatedPlayerTradeValueForNegative = 0;
37 private float totalPlayerTradeValue = 0;
39 private IntervalUtil tracker;
41 private Map<String, ShipSalesData> playerBoughtShips =
new LinkedHashMap<String, ShipSalesData>();
42 private Map<String, ShipSalesData> playerSoldShips =
new LinkedHashMap<String, ShipSalesData>();
43 private MarketAPI market;
44 private SubmarketAPI submarket;
47 this.market = submarket.getMarket();
48 this.submarket = submarket;
53 tracker = Misc.createEconIntervalTracker();
58 tx =
new HashMap<String, MutableStatWithTempMods>();
63 public static String
getTXId(CargoStackAPI stack) {
64 return stack.getType().name() +
"_" + stack.getData().toString();
67 public static String
getTXId(ShipSalesData data) {
68 return data.getVariantId();
71 public MutableStatWithTempMods
getStat(String
id) {
72 MutableStatWithTempMods stat = tx.get(
id);
74 stat =
new MutableStatWithTempMods(0);
81 tracker.advance(days);
82 if (tracker.intervalElapsed()) {
86 for (CargoStackAPI stack : playerBought.getStacksCopy()) {
87 stack.setSize(stack.getSize() * factor);
88 if (stack.getSize() < 10) {
92 playerBought.removeEmptyStacks();
93 for (CargoStackAPI stack : playerSold.getStacksCopy()) {
94 stack.setSize(stack.getSize() * factor);
95 if (stack.getSize() < 10) {
99 playerSold.removeEmptyStacks();
106 List<String>
remove =
new ArrayList<String>();
107 for (ShipSalesData data : playerBoughtShips.values()) {
108 data.setNumShips(data.getNumShips() * factor);
109 data.setTotalValue(data.getTotalValue() * factor);
110 if (data.getNumShips() < 0.2f)
remove.add(data.getVariantId());
112 for (String vid :
remove) {
113 playerBoughtShips.remove(vid);
117 for (ShipSalesData data : playerSoldShips.values()) {
118 data.setNumShips(data.getNumShips() * factor);
119 data.setTotalValue(data.getTotalValue() * factor);
120 if (data.getNumShips() < 0.2f)
remove.add(data.getVariantId());
122 for (String vid :
remove) {
123 playerSoldShips.remove(vid);
128 accumulatedPlayerTradeValueForPositive *= factor;
129 accumulatedPlayerTradeValueForNegative *= factor;
130 totalPlayerTradeValue *= factor;
136 for (CargoStackAPI stack : transaction.getSold().getStacksCopy()) {
139 for (CargoStackAPI stack : transaction.getBought().getStacksCopy()) {
142 for (ShipSaleInfo info : transaction.getShipsBought()) {
145 for (ShipSaleInfo info : transaction.getShipsSold()) {
150 private float getTransponderMult() {
161 String vid = info.getMember().getVariant().getHullSpec().getHullId();
167 float fractionBought = 1f;
168 if (sold.getNumShips() > 0) {
169 fractionBought = Math.max(0, fractionBought - sold.getNumShips());
170 sold.setNumShips(sold.getNumShips() - 1f);
171 sold.setTotalValue(sold.getTotalValue() - (1f - fractionBought) * info.getPrice() * playerImpactMult);
172 if (sold.getNumShips() < 0) sold.setNumShips(0);
173 if (sold.getTotalValue() < 0) sold.setTotalValue(0);
176 if (fractionBought > 0) {
177 accumulatedPlayerTradeValueForPositive += info.getPrice() * playerImpactMult * fractionBought * getTransponderMult();
178 accumulatedPlayerTradeValueForNegative += info.getPrice() * playerImpactMult * fractionBought * getTransponderMult();
179 totalPlayerTradeValue += info.getPrice() * playerImpactMult * fractionBought * getTransponderMult();
180 bought.setNumShips(bought.getNumShips() + 1f * fractionBought);
181 bought.setTotalValue(bought.getTotalValue() + info.getPrice() * playerImpactMult * fractionBought);
186 String vid = info.getMember().getVariant().getHullSpec().getHullId();
192 float fractionSold = 1f;
193 if (bought.getNumShips() > 0) {
194 fractionSold = Math.max(0, fractionSold - bought.getNumShips());
195 bought.setNumShips(bought.getNumShips() - 1f);
196 bought.setTotalValue(bought.getTotalValue() - (1f - fractionSold) * info.getPrice() * playerImpactMult);
197 if (bought.getNumShips() < 0) bought.setNumShips(0);
198 if (bought.getTotalValue() < 0) bought.setTotalValue(0);
201 if (fractionSold > 0) {
202 accumulatedPlayerTradeValueForPositive += info.getPrice() * playerImpactMult * fractionSold * getTransponderMult();
203 accumulatedPlayerTradeValueForNegative += info.getPrice() * playerImpactMult * fractionSold * getTransponderMult();
204 totalPlayerTradeValue += info.getPrice() * playerImpactMult * fractionSold * getTransponderMult();
205 sold.setNumShips(sold.getNumShips() + 1f * fractionSold);
206 sold.setTotalValue(sold.getTotalValue() + info.getPrice() * playerImpactMult * fractionSold);
211 float qty = stack.getSize() - playerSold.getQuantity(stack.getType(), stack.getData());
213 stack.getType(), stack.getData(), stack.getBaseValuePerUnit(), qty);
214 accumulatedPlayerTradeValueForPositive += impact * getTransponderMult();
215 accumulatedPlayerTradeValueForNegative += impact * getTransponderMult();
216 totalPlayerTradeValue += impact * getTransponderMult();
218 playerBought.addItems(stack.getType(), stack.getData(), stack.getSize());
219 playerSold.removeItems(stack.getType(), stack.getData(), stack.getSize());
221 if (qty >= 1 && stack.getType() == CargoItemType.RESOURCES) {
224 stack.getType(), stack.getData(), stack.getBaseValuePerUnit(), qty);
234 float qty = stack.getSize() - playerBought.getQuantity(stack.getType(), stack.getData());
236 stack.getType(), stack.getData(), stack.getBaseValuePerUnit(), qty);
238 playerSold.addItems(stack.getType(), stack.getData(), stack.getSize());
239 playerBought.removeItems(stack.getType(), stack.getData(), stack.getSize());
241 float overrideImpactMult = 1f;
242 if (qty >= 1 && stack.getType() == CargoItemType.RESOURCES) {
245 stack.getType(), stack.getData(), stack.getBaseValuePerUnit(), qty);
246 if (totalPriceOverride > 0) {
248 overrideImpactMult = totalPriceOverride / price;
250 price = totalPriceOverride;
261 accumulatedPlayerTradeValueForPositive += impact * getTransponderMult() * overrideImpactMult;
262 accumulatedPlayerTradeValueForNegative += impact * getTransponderMult() * overrideImpactMult;
263 totalPlayerTradeValue += impact * getTransponderMult() * overrideImpactMult;
267 if (qty < 1)
return 0;
273 if (type == CargoItemType.RESOURCES) {
274 String commodityId = (String) data;
275 CommodityOnMarketAPI com = market.getCommodityData(commodityId);
276 float val = market.getDemandPriceAssumingExistingTransaction(commodityId, qty, -qty * com.getUtilityOnMarket(),
true);
277 if (!market.hasCondition(Conditions.FREE_PORT) &&
278 market.isIllegal(commodityId)) {
279 val *= illegalImpactMult;
281 val *= playerImpactMult;
283 String multId = Stats.getPlayerTradeRepImpactMultId(commodityId);
284 val *= market.getStats().getDynamic().getValue(multId);
285 multId = Stats.getPlayerSellRepImpactMultId(commodityId);
286 val *= market.getStats().getDynamic().getValue(multId);
288 if (com.getCommodity().hasTag(Commodities.TAG_MILITARY)) {
289 val *= militaryImpactMult;
293 float val = (float) baseValue * qty * playerImpactMult;
299 if (qty < 1)
return 0;
301 if (type == CargoItemType.RESOURCES) {
302 String commodityId = (String) data;
303 CommodityOnMarketAPI com = market.getCommodityData(commodityId);
304 float val = market.getDemandPriceAssumingExistingTransaction(commodityId, qty, -qty * com.getUtilityOnMarket(),
true);
307 float val = (float) baseValue * qty;
313 if (qty < 1)
return 0;
318 if (type == CargoItemType.RESOURCES) {
319 String commodityId = (String) data;
320 CommodityOnMarketAPI com = market.getCommodityData(commodityId);
321 float val = market.getSupplyPriceAssumingExistingTransaction(commodityId, qty, qty * com.getUtilityOnMarket(),
true);
322 val *= playerImpactMult;
324 String multId = Stats.getPlayerTradeRepImpactMultId(commodityId);
325 val *= market.getStats().getDynamic().getValue(multId);
326 multId = Stats.getPlayerBuyRepImpactMultId(commodityId);
327 val *= market.getStats().getDynamic().getValue(multId);
330 float val = (float) baseValue * qty * playerImpactMult;
336 if (qty < 1)
return 0;
338 if (type == CargoItemType.RESOURCES) {
339 String commodityId = (String) data;
340 CommodityOnMarketAPI com = market.getCommodityData(commodityId);
341 float val = market.getSupplyPriceAssumingExistingTransaction(commodityId, qty, qty * com.getUtilityOnMarket(),
true);
344 float val = (float) baseValue * qty;
351 return totalPlayerTradeValue;
355 this.totalPlayerTradeValue = totalPlayerTradeValue;
367 return accumulatedPlayerTradeValueForPositive;
371 this.accumulatedPlayerTradeValueForPositive = accumulatedPlayerTradeValue;
375 return accumulatedPlayerTradeValueForNegative;
379 float accumulatedPlayerTradeValueForNegative) {
380 this.accumulatedPlayerTradeValueForNegative = accumulatedPlayerTradeValueForNegative;
388 return playerBoughtShips.values();
392 return playerSoldShips.values();
405 ShipSalesData sold = playerSoldShips.get(vid);
407 sold =
new ShipSalesData();
408 sold.setVariantId(vid);
409 playerSoldShips.put(vid, sold);
415 ShipSalesData bought = playerBoughtShips.get(vid);
416 if (bought ==
null) {
417 bought =
new ShipSalesData();
418 bought.setVariantId(vid);
419 playerBoughtShips.put(vid, bought);
429 for (CargoStackAPI stack : playerBought.getStacksCopy()) {
430 float qty = stack.getSize();
434 stack.getType(), stack.getData(), stack.getBaseValuePerUnit(), qty);
437 for (CargoStackAPI stack : playerSold.getStacksCopy()) {
438 float qty = stack.getSize();
439 if (qty < 1)
continue;
446 stack.getType(), stack.getData(), stack.getBaseValuePerUnit(), qty);
453 this.submarket = submarket;
static SettingsAPI getSettings()
static FactoryAPI getFactory()
static SectorAPI getSector()
PlayerTradeProfitabilityData getProfitabilityData()
void addToTrackedPlayerSold(CargoStackAPI stack, float totalPriceOverride)
void setAccumulatedPlayerTradeValueForPositive(float accumulatedPlayerTradeValue)
void addToTrackedPlayerSold(ShipSaleInfo info)
float getAccumulatedPlayerTradeValueForNegative()
CargoAPI getRecentPlayerBought()
static String getTXId(CargoStackAPI stack)
void addToTrackedPlayerSold(CargoStackAPI stack)
static String getTXId(ShipSalesData data)
void addTransaction(PlayerMarketTransaction transaction)
MutableStatWithTempMods getStat(String id)
static float computePriceOfHavingAlreadySold(MarketAPI market, CargoItemType type, Object data, float baseValue, float qty)
float getRecentBaseTradeValueImpact()
Collection< ShipSalesData > getRecentlyPlayerSoldShips()
void setSubmarket(SubmarketAPI submarket)
float getTotalPlayerTradeValue()
ShipSalesData getSoldShipData(String vid)
SubmarketAPI getSubmarket()
void addToTrackedPlayerBought(CargoStackAPI stack)
CargoAPI getRecentPlayerSold()
static float computePriceOfHavingAlreadyBought(MarketAPI market, CargoItemType type, Object data, float baseValue, float qty)
ShipSalesData getBoughtShipData(String vid)
void addToTrackedPlayerBought(ShipSaleInfo info)
PlayerTradeDataForSubmarket(SubmarketAPI submarket)
static float computeImpactOfHavingAlreadySold(MarketAPI market, CargoItemType type, Object data, float baseValue, float qty)
float getAccumulatedPlayerTradeValueForPositive()
Collection< ShipSalesData > getRecentlyPlayerBoughtShips()
IntervalUtil getTracker()
void setAccumulatedPlayerTradeValueForNegative(float accumulatedPlayerTradeValueForNegative)
static float computeImpactOfHavingAlreadyBought(MarketAPI market, CargoItemType type, Object data, float baseValue, float qty)
void setTotalPlayerTradeValue(float totalPlayerTradeValue)
void reportNetBought(String commodityId, float quantity, float totalPrice)
void reportNetSold(String commodityId, float quantity, float totalPrice)
PlayerActivityTracker getPlayerActivityTracker()
static SharedData getData()
CargoAPI createCargo(boolean unlimitedStacks)
float getFloat(String key)