Starsector API
Loading...
Searching...
No Matches
CommodityStatTracker.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.shared;
2
3import java.util.HashMap;
4import java.util.List;
5import java.util.Map;
6
7import com.fs.starfarer.api.Global;
8import com.fs.starfarer.api.campaign.econ.CommodityOnMarketAPI;
9import com.fs.starfarer.api.campaign.econ.EconomyAPI;
10import com.fs.starfarer.api.campaign.econ.MarketAPI;
11import com.fs.starfarer.api.util.IntervalUtil;
12import com.fs.starfarer.api.util.Misc;
13import com.fs.starfarer.api.util.SaveableIterator;
14
16
17 public static class CommodityStats {
18 private float minSupplyPrice;
19 private float maxDemandPrice;
20 private float averageSupplyPrice;
21 private float averageDemandPrice;
22 private float totalDemand;
23 private float totalSupply;
24 private float totalStockpiles;
25 private final String commodityId;
26
27 public CommodityStats(String commodityId) {
28 this.commodityId = commodityId;
29 }
30
31// public MarketAPI getMarket() {
32// return Global.getSector().getEconomy().getMarket(marketId);
33// }
34// public CommodityOnMarketAPI getCommodity() {
35// MarketAPI market = getMarket();
36// if (market == null) return null;
37// return market.getCommodityData(commodityId);
38// }
39
40 public float getMinSupplyPrice() {
41 return minSupplyPrice;
42 }
43 public float getMaxDemandPrice() {
44 return maxDemandPrice;
45 }
46 public float getAverageSupplyPrice() {
47 return averageSupplyPrice;
48 }
49 public float getAverageDemandPrice() {
50 return averageDemandPrice;
51 }
52 public String getCommodityId() {
53 return commodityId;
54 }
55 public void setMinSupplyPrice(float min) {
56 this.minSupplyPrice = min;
57 }
58 public void setMaxDemandPrice(float max) {
59 this.maxDemandPrice = max;
60 }
61 public void setAverageSupplyPrice(float average) {
62 this.averageSupplyPrice = average;
63 }
64 public float getTotalDemand() {
65 return totalDemand;
66 }
67 public void setTotalDemand(float totalDemand) {
68 this.totalDemand = totalDemand;
69 }
70 public float getTotalSupply() {
71 return totalSupply;
72 }
73 public void setTotalSupply(float totalSupply) {
74 this.totalSupply = totalSupply;
75 }
76 public float getTotalStockpiles() {
77 return totalStockpiles;
78 }
79 public void setTotalStockpiles(float totalStockpiles) {
80 this.totalStockpiles = totalStockpiles;
81 }
82 public void setAverageDemandPrice(float weightedAveragePrice) {
83 this.averageDemandPrice = weightedAveragePrice;
84 }
85 }
86
87 private IntervalUtil timer = new IntervalUtil(0.25f, 0.75f);
88
89 private Map<String, CommodityStats> priceData = new HashMap<String, CommodityStats>();
90 private boolean firstFrame = true;
91
92 public void advance(float days) {
93
94 if (firstFrame) {
95 firstFrame = false;
96 EconomyAPI economy = Global.getSector().getEconomy();
97 for (String id : economy.getAllCommodityIds()) {
99 }
100 }
101
102 timer.advance(days);
103 if (timer.intervalElapsed()) {
104 updateStatsNextStep();
105 }
106
107// compute prices stuff here? min/max
108// add an "is price change significant" method; "is price significant" method
109 }
110
111
112 public boolean isSupplyPriceSignificant(CommodityOnMarketAPI com) {
113 return isSupplyPriceWithMultSignificant(com, 1f);
114 }
115 public boolean isDemandPriceSignificant(CommodityOnMarketAPI com) {
116 return isDemandPriceWithMultSignificant(com, 1f);
117 }
118
119 public boolean isSupplyPriceWithMultSignificant(CommodityOnMarketAPI com, float mult) {
120 float supplyPrice = Math.round(com.getMarket().getSupplyPrice(com.getId(), 1, true));
121 supplyPrice *= mult;
122 return isSupplyPriceSignificant(com, supplyPrice);
123 }
124
125 public boolean isDemandPriceWithMultSignificant(CommodityOnMarketAPI com, float mult) {
126 float demandPrice = Math.round(com.getMarket().getDemandPrice(com.getId(), 1, true));
127 demandPrice *= mult;
128 return isSupplyPriceSignificant(com, demandPrice);
129 }
130
131 public boolean isSupplyPriceSignificant(CommodityOnMarketAPI com, float price) {
132 //if (com.getAverageStockpileAfterDemand() < 100) return false;
133 CommodityStats stats = getStats(com.getId());
134 float average = stats.getAverageSupplyPrice();
135 //return price <= average * .5f || average - price > com.getCommodity().getBasePrice() * 0.5f;
136 //return price <= average * .5f || average - price > 100f;
137 //return price <= average * .5f || average - price > Math.max(100, com.getCommodity().getBasePrice() * 0.5f);
138
139// float margin = Misc.getProfitMargin();
140// margin = Math.min(margin * 0.5f, average * 0.75f);
141 float flat = Misc.getProfitMarginFlat();
142 float mult = Misc.getProfitMarginMult();
143
144 return price <= average - flat || price <= average / mult;
145
146// if (margin < Misc.getProfitMargin() * 0.25f) {
147// margin = Misc.getProfitMargin() * 0.25f;
148// }
149// return price <= average - margin;
150 }
151
152 public boolean isDemandPriceSignificant(CommodityOnMarketAPI com, float price) {
153 //if (com.getDemand().getDemandValue() < 100) return false;
154 CommodityStats stats = getStats(com.getId());
155 float average = stats.getAverageDemandPrice();
156 //return price >= average * 1.75f || price - average > com.getCommodity().getBasePrice() * 1f;
157 //return price >= average * 1.75f || price - average > 100f;
158 //return price >= average * 1.75f || price - average > Math.max(100, com.getCommodity().getBasePrice() * 1f);
159
160 float flat = Misc.getProfitMarginFlat();
161 float mult = Misc.getProfitMarginMult();
162
163 return price >= average + flat || price >= average * mult;
164
165// float margin = Misc.getProfitMargin();
166// margin = margin - Math.min(margin * 0.5f, average * 0.5f);
167//
168// return price >= average + margin;
169 }
170
171
172// public boolean isCommodityPriceSpreadInteresting(String commodityId) {
173// CommodityStats stats = getStats(commodityId);
174//
175// float diff = Math.abs(stats.getMaxDemandPrice() - stats.getMinSupplyPrice());
176// return isCommodityPriceSpreadInteresting(commodityId, diff);
177// }
178//
179// public boolean isCommodityPriceSpreadInteresting(String commodityId, float diff) {
180// CommodityStats stats = getStats(commodityId);
181// if (diff > 100) return true;
182// if (diff > stats.getMinSupplyPrice() * .75f) return true;
183// return false;
184// }
185
186
187
188 private SaveableIterator<String> commodityIterator = null;
189 private void updateStatsNextStep() {
190 EconomyAPI economy = Global.getSector().getEconomy();
191
192 if (commodityIterator == null || !commodityIterator.hasNext()) {
193 commodityIterator = new SaveableIterator<String>(economy.getAllCommodityIds());
194 }
195 if (!commodityIterator.hasNext()) return; // no commodities exist, yyeah.
196
197 String commodityId = commodityIterator.next();
198
199 updateCommodityStats(commodityId);
200 }
201
202 public void updateCommodityStats(String commodityId) {
203 EconomyAPI economy = Global.getSector().getEconomy();
204 List<MarketAPI> markets = economy.getMarketsCopy();
205
206 float totalSupply = 0;
207 float totalDemand = 0;
208 float totalStockpiles = 0;
209 float minSupplyPrice = Float.MAX_VALUE;
210 float maxDemandPrice = 0;
211
212 float totalSupplyPrice = 0;
213 float totalDemandPrice = 0;
214
215 for (MarketAPI market : markets) {
216 CommodityOnMarketAPI com = market.getCommodityData(commodityId);
217
218 //float supply = com.getSupplyValue();
219 float demand = com.getDemand().getDemandValue();
220 float supply = demand;
221 float stockpile = com.getStockpile();
222
223 if (supply < 10 && demand < 10 && stockpile < 10) continue;
224
225 float supplyPrice = Math.round(market.getSupplyPrice(com.getId(), 1, true));
226 float demandPrice = Math.round(market.getDemandPrice(com.getId(), 1, true));
227
228 if (supplyPrice < minSupplyPrice) {
229 minSupplyPrice = supplyPrice;
230 }
231 if (demandPrice > maxDemandPrice) {
232 maxDemandPrice = demandPrice;
233 }
234
235 totalSupply += supply;
236 totalDemand += demand;
237 totalStockpiles += stockpile;
238
239 totalSupplyPrice += stockpile * supplyPrice;
240 totalDemandPrice += demand * demandPrice;
241 }
242
243 CommodityStats stats = getStats(commodityId);
244
245 stats.setTotalSupply(totalSupply);
246 stats.setTotalDemand(totalDemand);
247 stats.setTotalStockpiles(totalStockpiles);
248 stats.setMaxDemandPrice(maxDemandPrice);
249 stats.setMinSupplyPrice(minSupplyPrice);
250
251 if (totalStockpiles > 0) {
252 stats.setAverageSupplyPrice(totalSupplyPrice / totalStockpiles);
253 } else {
254 stats.setAverageSupplyPrice(0);
255 }
256
257 if (totalDemand > 0) {
258 stats.setAverageDemandPrice(totalDemandPrice / totalDemand);
259 } else {
260 stats.setAverageDemandPrice(0);
261 }
262 }
263
264
265 public CommodityStats getStats(String commodityId) {
266 CommodityStats data = priceData.get(commodityId);
267 if (data == null) {
268 data = new CommodityStats(commodityId);
269 priceData.put(commodityId, data);
270 }
271 return data;
272 }
273}
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
static SectorAPI getSector()
Definition Global.java:59
boolean isSupplyPriceWithMultSignificant(CommodityOnMarketAPI com, float mult)
boolean isDemandPriceSignificant(CommodityOnMarketAPI com, float price)
boolean isSupplyPriceSignificant(CommodityOnMarketAPI com, float price)
boolean isDemandPriceWithMultSignificant(CommodityOnMarketAPI com, float mult)