Starsector API
Loading...
Searching...
No Matches
RepTrackerEvent.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.events;
2
3import java.util.ArrayList;
4import java.util.Collections;
5import java.util.Comparator;
6import java.util.HashMap;
7import java.util.List;
8import java.util.Map;
9
10import org.apache.log4j.Logger;
11
12import com.fs.starfarer.api.Global;
13import com.fs.starfarer.api.campaign.CampaignFleetAPI;
14import com.fs.starfarer.api.campaign.FactionAPI;
15import com.fs.starfarer.api.campaign.RepLevel;
16import com.fs.starfarer.api.campaign.SubmarketPlugin;
17import com.fs.starfarer.api.campaign.econ.MarketAPI;
18import com.fs.starfarer.api.campaign.econ.SubmarketAPI;
19import com.fs.starfarer.api.campaign.events.CampaignEventTarget;
20import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActionEnvelope;
21import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActions;
22import com.fs.starfarer.api.impl.campaign.ids.Factions;
23import com.fs.starfarer.api.impl.campaign.shared.PlayerTradeDataForSubmarket;
24import com.fs.starfarer.api.impl.campaign.shared.PlayerTradeProfitabilityData;
25import com.fs.starfarer.api.impl.campaign.shared.SharedData;
26import com.fs.starfarer.api.util.IntervalUtil;
27import com.fs.starfarer.api.util.Misc;
28
36public class RepTrackerEvent extends BaseEventPlugin {
37 public static Logger log = Global.getLogger(RepTrackerEvent.class);
38
39 public static class FactionTradeRepData {
40 public float currVolumePerPoint = Global.getSettings().getFloat("economyPlayerTradeVolumeForRepChangeMin");
41
42 public float [] getRepPointsAndVolumeUsedFor(float volume) {
43 float max = Global.getSettings().getFloat("economyPlayerTradeVolumeForRepChangeMax");
44 float incr = Global.getSettings().getFloat("economyPlayerTradeVolumeForRepChangeIncr");
45 float points = 0;
46
47 float used = 0;
48
49 while (volume >= currVolumePerPoint) {
50 points++;
51 used += currVolumePerPoint;
52 volume -= currVolumePerPoint;
53
54 if (currVolumePerPoint < max) currVolumePerPoint += incr;
55 if (currVolumePerPoint > max) currVolumePerPoint = max;
56 }
57 return new float [] {points, used};
58 }
59 }
60
61
62 private IntervalUtil tracker;
63 private IntervalUtil repDecayTracker;
64 private Map<String, FactionTradeRepData> repData = new HashMap<String, FactionTradeRepData>();
65
66 public void init(String type, CampaignEventTarget eventTarget) {
67 super.init(type, eventTarget);
68 readResolve();
69 }
70
71 Object readResolve() {
72 if (repDecayTracker == null) {
73 repDecayTracker = new IntervalUtil(130f, 170f);
74 }
75 if (tracker == null) {
76 tracker = new IntervalUtil(3f, 7f);
77 }
78 return this;
79 }
80
81 public void startEvent() {
82 super.startEvent();
83 }
84
85 private float [] getRepPointsAndVolumeUsedFor(float volume, FactionAPI faction) {
86 FactionTradeRepData data = repData.get(faction.getId());
87 if (data == null) {
88 data = new FactionTradeRepData();
89 repData.put(faction.getId(), data);
90 }
91 return data.getRepPointsAndVolumeUsedFor(volume);
92 }
93
94 public void advance(float amount) {
95 if (!isEventStarted()) return;
96 if (isDone()) return;
97
98 float days = Global.getSector().getClock().convertToDays(amount);
99
100 tracker.advance(days);
101 if (tracker.intervalElapsed()) {
102 for (FactionAPI faction : Global.getSector().getAllFactions()) {
103 //List<FactionAPI> factions = Global.getSector().getAllFactions();
104 //FactionAPI faction = factions.get(new Random().nextInt(factions.size()));
105 if (!faction.isPlayerFaction() && !faction.isNeutralFaction()) {
106 checkForTradeReputationChanges(faction);
107 }
108 }
109 checkForXPGain();
110 }
111
112// repDecayTracker.advance(days);
113// if (repDecayTracker.intervalElapsed()) {
114// checkForRepDecay();
115// }
116 }
117
118
119 private void checkForXPGain() {
120 PlayerTradeProfitabilityData data = SharedData.getData().getPlayerActivityTracker().getProfitabilityData();
121 final long gain = data.getAccruedXP();
122 //final long gain = 1000;
123 if (gain > 0) {
124 data.setAccruedXP(0);
125 Global.getSector().getCampaignUI().addMessage("Gained experience from profitable trades", Misc.getBasePlayerColor());
126 Global.getSector().getCharacterData().getPerson().getStats().addXP(gain);
127 }
128 }
129
130
131 public static class MarketTradeInfo {
132 public MarketAPI market;
133 public float tradeTotal;
134 public float smugglingTotal;
135 }
136
137 private void checkForTradeReputationChanges(final FactionAPI faction) {
138 float playerTradeVolume = 0;
139 float playerSmugglingVolume = 0;
140
141 final List<MarketTradeInfo> info = new ArrayList<MarketTradeInfo>();
142 for (MarketAPI market : Global.getSector().getEconomy().getMarketsCopy()) {
143 //if (market.getFaction() != faction) continue;
144
145// if (faction.getId().equals("hegemony")) {
146// System.out.println("23dsfsdf");
147// }
148
149 //boolean isFactionInvolved = market.getFaction() == faction;
150
151 MarketTradeInfo curr = new MarketTradeInfo();
152 curr.market = market;
153
154 for (SubmarketAPI submarket : market.getSubmarketsCopy()) {
155 SubmarketPlugin plugin = submarket.getPlugin();
156 if (!plugin.isParticipatesInEconomy()) continue;
157
158 //isFactionInvolved |= submarket.getFaction() == faction;
159
160 PlayerTradeDataForSubmarket tradeData = SharedData.getData().getPlayerActivityTracker().getPlayerTradeData(submarket);
161
162 //if (plugin.isBlackMarket()) {
163 if (market.getFaction() == faction && (submarket.getFaction().isHostileTo(faction) || submarket.getPlugin().isBlackMarket())) {
164 curr.smugglingTotal += tradeData.getAccumulatedPlayerTradeValueForNegative();
165 } else if (submarket.getFaction() == faction) {
166 curr.tradeTotal += tradeData.getAccumulatedPlayerTradeValueForPositive();
167 }
168 }
169
170 //if (!isFactionInvolved) continue;
171 if (curr.tradeTotal == 0 && curr.smugglingTotal == 0) continue;
172
173 info.add(curr);
174
175 playerTradeVolume += curr.tradeTotal;
176 playerSmugglingVolume += curr.smugglingTotal;
177 }
178
179// if (faction.getId().equals("pirates")) {
180// System.out.println("23dsfsdf");
181// }
182
183 float [] repPlus = getRepPointsAndVolumeUsedFor(playerTradeVolume, faction);
184 float [] repMinus = getRepPointsAndVolumeUsedFor(playerSmugglingVolume, faction);
185 final float repChange = repPlus[0] - repMinus[0];
186
187 if (Math.abs(repChange) < 1) {
188 log.info("Not enough trade/smuggling with " + faction.getDisplayNameWithArticle() + " for a rep change (" + playerTradeVolume + ", " + playerSmugglingVolume + ")");
189 return;
190 }
191
192 log.info("Sending rep change of " + repChange + " with " + faction.getDisplayNameWithArticle() + " due to trade/smuggling");
193
194 float tradeUsed = repPlus[1];
195 float smugglingUsed = repMinus[1];
196
197 // remove the player trade volume used for the rep change from the accumulated volume
198 for (MarketAPI market : Global.getSector().getEconomy().getMarketsCopy()) {
199 //if (market.getFaction() != faction) continue;
200 for (SubmarketAPI submarket : market.getSubmarketsCopy()) {
201 SubmarketPlugin plugin = submarket.getPlugin();
202 if (!plugin.isParticipatesInEconomy()) continue;
203
204 if (market.getFaction() != faction && submarket.getFaction() != faction) {
205 continue;
206 }
207
208 PlayerTradeDataForSubmarket tradeData = SharedData.getData().getPlayerActivityTracker().getPlayerTradeData(submarket);
209
210 //if (playerTradeVolume > 0 && !plugin.isBlackMarket()) {
211 if (playerSmugglingVolume > 0 && market.getFaction() == faction && (submarket.getFaction().isHostileTo(faction) || submarket.getPlugin().isBlackMarket())) {
212 float value = tradeData.getAccumulatedPlayerTradeValueForNegative();
213 tradeData.setAccumulatedPlayerTradeValueForNegative(value - smugglingUsed * value / playerSmugglingVolume);
214 } else if (playerTradeVolume > 0 && submarket.getFaction() == faction) {
215 float value = tradeData.getAccumulatedPlayerTradeValueForPositive();
216 tradeData.setAccumulatedPlayerTradeValueForPositive(value - tradeUsed * value / playerTradeVolume);
217 }
218 }
219 }
220
221
222 CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet();
223
224 if (repChange > 0) {
225 Collections.sort(info, new Comparator<MarketTradeInfo>() {
226 public int compare(MarketTradeInfo o1, MarketTradeInfo o2) {
227 return (int) (o2.tradeTotal - o1.tradeTotal);
228 }
229 });
230
231 RepActions action = RepActions.TRADE_EFFECT;
232 Global.getSector().adjustPlayerReputation(
233 new RepActionEnvelope(action, new Float(Math.abs(repChange)), null, null, false, true, "Change caused by trade with faction"),
234 faction.getId());
235
237 } else if (repChange < 0) {
238 Collections.sort(info, new Comparator<MarketTradeInfo>() {
239 public int compare(MarketTradeInfo o1, MarketTradeInfo o2) {
240 return (int) (o2.smugglingTotal - o1.smugglingTotal);
241 }
242 });
243
244 RepActions action = RepActions.SMUGGLING_EFFECT;
245
246 Global.getSector().adjustPlayerReputation(
247 new RepActionEnvelope(action, new Float(Math.abs(repChange)), null, null, false, true, "Change caused by black-market trade"),
248 faction.getId());
249
251 }
252 }
253
254
255 public void causeNegativeRepChangeWithEnemies(List<MarketTradeInfo> info) {
256
257 int maxToSend = 3;
258 int sent = 0;
259 for (final MarketTradeInfo curr : info) {
260 float actionableTotal = curr.tradeTotal * 2f + curr.smugglingTotal * 0.5f;
261 //float repMinus = (float) Math.floor(actionableTotal / volumeForRepChange);
262 List<FactionAPI> factions = new ArrayList<FactionAPI>(Global.getSector().getAllFactions());
263 Collections.shuffle(factions);
264 for (final FactionAPI faction : factions) {
265 // pirates don't get mad about you trading with someone else
266 //if (faction.getId().equals(Factions.PIRATES)) {
267 if (faction.getCustom().optBoolean(Factions.CUSTOM_IGNORE_TRADE_WITH_ENEMIES)) {
268 continue;
269 }
270 if (faction.isPlayerFaction()) continue; // don't report player to themselves for trading with their own enemies
271
272 final MarketAPI other = BaseEventPlugin.findNearestMarket(curr.market, new MarketFilter() {
273 public boolean acceptMarket(MarketAPI market) {
274 if (!market.getFactionId().equals(faction.getId())) {
275 return false;
276 }
277 if (market.getFaction().isAtBest(curr.market.getFaction(), RepLevel.HOSTILE)) {
278 return true;
279 }
280 return false;
281 }
282 });
283 if (other == null) continue;
284
285 float dist = Misc.getDistanceLY(curr.market.getLocationInHyperspace(), other.getLocationInHyperspace());
286 //if (dist > 2f) continue;
287 if (dist > Global.getSettings().getFloat("economyMaxRangeForNegativeTradeRepImpactLY")) continue;
288
289
290 float [] repMinus = getRepPointsAndVolumeUsedFor(actionableTotal, faction);
291 if (repMinus[0] <= 0) continue;
292
293 if (dist <= 0) { // same star system
294 repMinus[0] *= 2f;
295 }
296
297 final float repChange = -repMinus[0];
298
299 log.info("Sending rep change of " + repChange + " with " + other.getFaction().getDisplayNameWithArticle() +
300 " due to trade with enemy (" + curr.market.getFaction().getDisplayNameWithArticle() + ")");
301
302 RepActions action = RepActions.TRADE_WITH_ENEMY;
303 Global.getSector().adjustPlayerReputation(
304 new RepActionEnvelope(action, new Float(Math.abs(repChange)), null, null, false, true, "Change caused by trade with enemies"),
305 other.getFactionId());
306
307 sent++;
308 if (sent >= maxToSend) break;
309 }
310 if (sent >= maxToSend) break;
311 }
312 }
313
314 public boolean isDone() {
315 return false;
316 }
317}
318
319
320
321
322
323
324
325
326
327
static SettingsAPI getSettings()
Definition Global.java:51
static Logger getLogger(Class c)
Definition Global.java:26
static SectorAPI getSector()
Definition Global.java:59
static MarketAPI findNearestMarket(MarketAPI from, MarketFilter filter)
void init(String type, CampaignEventTarget eventTarget)
void causeNegativeRepChangeWithEnemies(List< MarketTradeInfo > info)