Starsector API
Loading...
Searching...
No Matches
CargoScan.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.rulecmd;
2
3import java.awt.Color;
4import java.util.ArrayList;
5import java.util.Collections;
6import java.util.List;
7import java.util.Map;
8
9import com.fs.starfarer.api.Global;
10import com.fs.starfarer.api.campaign.CampaignFleetAPI;
11import com.fs.starfarer.api.campaign.CargoAPI;
12import com.fs.starfarer.api.campaign.CargoStackAPI;
13import com.fs.starfarer.api.campaign.FactionAPI;
14import com.fs.starfarer.api.campaign.InteractionDialogAPI;
15import com.fs.starfarer.api.campaign.SectorEntityToken;
16import com.fs.starfarer.api.campaign.SectorEntityToken.VisibilityLevel;
17import com.fs.starfarer.api.campaign.TextPanelAPI;
18import com.fs.starfarer.api.campaign.econ.MarketAPI;
19import com.fs.starfarer.api.campaign.rules.MemKeys;
20import com.fs.starfarer.api.campaign.rules.MemoryAPI;
21import com.fs.starfarer.api.fleet.FleetMemberAPI;
22import com.fs.starfarer.api.impl.campaign.CargoPodsEntityPlugin;
23import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActionEnvelope;
24import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActions;
25import com.fs.starfarer.api.impl.campaign.ids.Entities;
26import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
27import com.fs.starfarer.api.impl.campaign.ids.Strings;
28import com.fs.starfarer.api.util.Misc;
29import com.fs.starfarer.api.util.Misc.Token;
30import com.fs.starfarer.api.util.WeightedRandomPicker;
31
32public class CargoScan extends BaseCommandPlugin {
33
34 public static String PODS_FOUND = "$scan_podsFound";
35 public static String CONTRABAND_FOUND = "$scan_contrabandFound";
36 public static String SUSPICOUS_CARGO_FOUND = "$scan_suspiciousCargoFound";
37 //public static String DEMAND_BOARDING = "$scan_demandBoarding";
38 public static String RESULT_KEY = "$scan_cargoScanResult";
39
40 public static float INSPECTION_DAMAGE_MULT = 0.2f;
41 public static float CHANCE_TO_FIND_ILLEGAL_MULT = 2f;
42
43 public static class CargoScanResult {
44 protected CargoAPI legalFound, illegalFound;
45 public CargoAPI getLegalFound() {
46 return legalFound;
47 }
48 public void setLegalFound(CargoAPI legalFound) {
49 this.legalFound = legalFound;
50 }
51 public CargoAPI getIllegalFound() {
52 return illegalFound;
53 }
54 public void setIllegalFound(CargoAPI illegalFound) {
55 this.illegalFound = illegalFound;
56 }
57
58 protected List<FleetMemberAPI> shipsToDamage = new ArrayList<FleetMemberAPI>();
59 }
60
61
62 public boolean execute(String ruleId, InteractionDialogAPI dialog, List<Token> params, Map<String, MemoryAPI> memoryMap) {
63 if (dialog == null) return false;
64 if (!(dialog.getInteractionTarget() instanceof CampaignFleetAPI)) return false;
65
66 CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet();
67 CampaignFleetAPI other = (CampaignFleetAPI) dialog.getInteractionTarget();
68
69 FactionAPI faction = other.getFaction();
70
71 CargoScanResult result = new CargoScanResult();
72
73 float totalLegal = 0;
74 float totalLegalCargo = 0;
75 float totalIllegal = 0;
76 float totalIllegalFound = 0;
77 CargoAPI legalFound = Global.getFactory().createCargo(true);
78 CargoAPI illegalFound = Global.getFactory().createCargo(true);
79 CargoAPI all = Global.getFactory().createCargo(true);
80
81 float totalCargo = playerFleet.getCargo().getSpaceUsed();
82 float totalCrew = playerFleet.getCargo().getTotalPersonnel();
83 float totalFuel = playerFleet.getCargo().getFuel();
84
85 for (CargoStackAPI stack : playerFleet.getCargo().getStacksCopy()) {
86 boolean legal = !faction.isIllegal(stack);
87 if (legal) {
88 totalLegal += stack.getSize();
89 totalLegalCargo += stack.getCargoSpace();
90 } else {
91 totalIllegal += stack.getSize();
92 }
93 all.addFromStack(stack);
94 }
95 //float guiltMult = InvestigationEvent.getPlayerRepGuiltMult(faction);
96 float guiltMult = 1f;
97
98 float shieldedFraction = Misc.getShieldedCargoFraction(playerFleet);
99 float unshieldedFraction = 1f - shieldedFraction;
100
101 float shieldedMult = (0.25f + 0.75f * unshieldedFraction);
102
103 MarketAPI market = Misc.getSourceMarket(other);
104 float level = market.getMemory().getFloat(MemFlags.MEMORY_MARKET_SMUGGLING_SUSPICION_LEVEL);
105 float suspicionMult = 0f;
106 if (market != null) {
107 if (level >= 0.05f) {
108 suspicionMult = 0.5f + 0.5f * level;
109 }
110 }
111
112 totalLegalCargo *= shieldedMult;
113
114
115 boolean suspicious = false;
116 boolean suspiciousDueToLevel = false;
117 if (totalLegalCargo > 50 || totalLegalCargo > playerFleet.getCargo().getMaxCapacity() * 0.5f) {
118 totalLegalCargo *= suspicionMult;
119 suspicious = totalLegalCargo * guiltMult * (float) Math.random() >
120 playerFleet.getCargo().getMaxCapacity() * (float) Math.random();
121 }
122
123// suspicious = false;
124// level = 10f;
125
126 if (!suspicious && level >= 0.5f) {
127 float r = (float) Math.random();
128 suspicious |= r * r < level;
129 if (suspicious) {
130 suspiciousDueToLevel = true;
131 }
132 }
133
134 if (totalLegal + totalIllegal > 0) {
135 List<CargoStackAPI> stacks = all.getStacksCopy();
136 Collections.shuffle(stacks);
137 //float illegalSoFar = 0;
138 float illegalCargoSoFar = 0;
139 float illegalCrewSoFar = 0;
140 float illegalFuelSoFar = 0;
141 for (CargoStackAPI stack : stacks) {
142 if (stack.getSize() <= 0) continue;
143 boolean legal = !faction.isIllegal(stack);
144 float chanceToFind = 0f;
145 if (stack.isPersonnelStack()) {
146 if (totalCrew > 0) {
147 if (!legal) illegalCrewSoFar += stack.getSize();
148 chanceToFind = illegalCrewSoFar / totalCrew;
149 }
150 } else if (stack.isFuelStack()) {
151 if (totalFuel > 0) {
152 if (!legal) illegalFuelSoFar += stack.getSize();
153 chanceToFind = illegalFuelSoFar / totalFuel;
154 }
155 } else {
156 if (totalCargo > 0) {
157 if (!legal) illegalCargoSoFar += stack.getCargoSpace();
158 chanceToFind = illegalCargoSoFar / totalCargo;
159 }
160 }
161
162 chanceToFind *= guiltMult;
163 chanceToFind *= shieldedMult;
164 chanceToFind *= CHANCE_TO_FIND_ILLEGAL_MULT;
165
166// if (chanceToFind > 0 && !legal) {
167// System.out.println("fwefwef");
168// }
169 if (legal) {
170 legalFound.addFromStack(stack);
171 } else if ((float) Math.random() < chanceToFind) {
172 float qty = stack.getSize();
173 qty = qty * (0.33f + (float) Math.random() * 0.67f);
174 qty *= shieldedMult;
175 qty = Math.round(qty);
176 if (qty < 1) qty = 1;
177 illegalFound.addItems(stack.getType(), stack.getData(), qty);
178 }
179 }
180 }
181 //illegalFound.clear();
182
183 //boolean boarding = !suspicious && level >= 0.5f && illegalFound.isEmpty();
184 if (suspicious && illegalFound.isEmpty()) {
185 WeightedRandomPicker<FleetMemberAPI> picker = new WeightedRandomPicker<FleetMemberAPI>();
186 for (FleetMemberAPI member : playerFleet.getFleetData().getMembersListCopy()) {
187 if (member.isMothballed() && member.getRepairTracker().getBaseCR() < 0.2f) continue;
188 picker.add(member, member.getFleetPointCost());
189 }
190 if (picker.isEmpty()) {
191 suspicious = false;
192 } else {
193 float totalDamage = Math.min(playerFleet.getFleetPoints(), other.getFleetPoints()) * INSPECTION_DAMAGE_MULT;
194 float picked = 0f;
195 while (picked < totalDamage && !picker.isEmpty()) {
196 FleetMemberAPI pick = picker.pickAndRemove();
197 result.shipsToDamage.add(pick);
198 picked += pick.getFleetPointCost();
199 }
200 }
201 }
202
203 result.setLegalFound(legalFound);
204 result.setIllegalFound(illegalFound);
205
206 MemoryAPI memory = memoryMap.get(MemKeys.LOCAL);
207 memory.set(CONTRABAND_FOUND, !illegalFound.isEmpty(), 0);
208 memory.set(SUSPICOUS_CARGO_FOUND, suspicious, 0);
209 memory.set(RESULT_KEY, result, 0);
210
211 float maxPodsDist = 1500f;
212 OUTER: for (SectorEntityToken entity : other.getContainingLocation().getAllEntities()) {
213 if (Entities.CARGO_PODS.equals(entity.getCustomEntityType())) {
214 VisibilityLevel vLevel = entity.getVisibilityLevelTo(other);
215 if (entity.getCustomPlugin() instanceof CargoPodsEntityPlugin) {
216 float dist = Misc.getDistance(playerFleet, entity);
217 if (dist > maxPodsDist) continue;
218
219 CargoPodsEntityPlugin plugin = (CargoPodsEntityPlugin) entity.getCustomPlugin();
220 if (plugin.getElapsed() <= 1f && entity.getCargo() != null) {
221 if (vLevel == VisibilityLevel.COMPOSITION_DETAILS ||
222 vLevel == VisibilityLevel.COMPOSITION_AND_FACTION_DETAILS) {
223 for (CargoStackAPI stack : entity.getCargo().getStacksCopy()) {
224 boolean legal = !faction.isIllegal(stack);
225 if (!legal) {
226 memory.set(PODS_FOUND, true, 0);
227 Misc.fadeAndExpire(entity);
228 break OUTER;
229 }
230 }
231
232 }
233 }
234 }
235 }
236 }
237
238 TextPanelAPI text = dialog.getTextPanel();
239
240 //text.setFontVictor();
241 text.setFontSmallInsignia();
242
243 Color hl = Misc.getHighlightColor();
244 Color red = Misc.getNegativeHighlightColor();
245 text.addParagraph("-----------------------------------------------------------------------------");
246
247 if (!illegalFound.isEmpty()) {
248 text.addParagraph("Contraband found!", red);
249 String para = "";
250 List<String> highlights = new ArrayList<String>();
251 for (CargoStackAPI stack : illegalFound.getStacksCopy()) {
252 para += stack.getDisplayName() + " " + Strings.X + " " + (int)stack.getSize() + "\n";
253 highlights.add("" + (int)stack.getSize());
254 }
255 para = para.substring(0, para.length() - 1);
256 text.addParagraph(para);
257 text.highlightInLastPara(hl, highlights.toArray(new String [0]));
258 } else if (suspicious) {
259 if (suspiciousDueToLevel) {
260 text.addParagraph("Vessels flagged for inspection due to overall suspicion level!", hl);
261 } else {
262 text.addParagraph("Suspicious cargo found!", hl);
263 }
264 } else {
265 text.addParagraph("No contraband or suspicious cargo found.");
266 }
267
268 text.addParagraph("-----------------------------------------------------------------------------");
269
270 text.setFontInsignia();
271
272 for (CargoStackAPI stack : illegalFound.getStacksCopy()) {
273 totalIllegalFound += stack.getSize();
274 }
275
276 float capacity = playerFleet.getCargo().getMaxCapacity();
277 float repLoss = totalIllegalFound / 5f * totalIllegalFound / capacity;
278 repLoss = Math.round(repLoss);
279 if (repLoss > 5) repLoss = 5f;
280 if (repLoss == 0 && totalIllegalFound > 0) repLoss = 1f;
281 if (suspicious) {
282 repLoss = 5f;
283 }
284 if (repLoss > 0) {
285 RepActionEnvelope envelope = new RepActionEnvelope(RepActions.CUSTOMS_CAUGHT_SMUGGLING, repLoss, dialog.getTextPanel());
286 Global.getSector().adjustPlayerReputation(envelope, faction.getId());
287
288 envelope = new RepActionEnvelope(RepActions.CUSTOMS_CAUGHT_SMUGGLING, repLoss * 2f, dialog.getTextPanel());
289 Global.getSector().adjustPlayerReputation(envelope, dialog.getInteractionTarget().getActivePerson());
290 }
291
292 return true;
293 }
294
295}
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
static FactoryAPI getFactory()
Definition Global.java:35
static SectorAPI getSector()
Definition Global.java:59
boolean execute(String ruleId, InteractionDialogAPI dialog, List< Token > params, Map< String, MemoryAPI > memoryMap)
CargoAPI createCargo(boolean unlimitedStacks)