Starsector API
Loading...
Searching...
No Matches
SmugglingScanScript.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign;
2
3import java.util.List;
4
5import com.fs.starfarer.api.EveryFrameScript;
6import com.fs.starfarer.api.Global;
7import com.fs.starfarer.api.campaign.CampaignFleetAPI;
8import com.fs.starfarer.api.campaign.FleetAssignment;
9import com.fs.starfarer.api.campaign.SectorEntityToken.VisibilityLevel;
10import com.fs.starfarer.api.campaign.ai.FleetAssignmentDataAPI;
11import com.fs.starfarer.api.campaign.ai.ModularFleetAIAPI;
12import com.fs.starfarer.api.campaign.econ.MarketAPI;
13import com.fs.starfarer.api.campaign.rules.MemoryAPI;
14import com.fs.starfarer.api.impl.campaign.events.BaseEventPlugin.MarketFilter;
15import com.fs.starfarer.api.impl.campaign.ids.Conditions;
16import com.fs.starfarer.api.impl.campaign.ids.Factions;
17import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
18import com.fs.starfarer.api.util.IntervalUtil;
19import com.fs.starfarer.api.util.Misc;
20import com.fs.starfarer.api.util.Misc.FleetFilter;
21
22public class SmugglingScanScript implements EveryFrameScript {
23
24 public static final String SCAN_COMPLETE_KEY = "$smugglingScanComplete";
25 public static final String MARKET_TIMEOUT_KEY = "$smugglingScanTimeout";
26
27 private IntervalUtil interval = new IntervalUtil(0.1f, 0.3f);
28
29 private float currDuration = 0f;
30 private float currElapsed = 0f;
31 private CampaignFleetAPI curr = null;
32
33 public void advance(float amount) {
34 float days = Global.getSector().getClock().convertToDays(amount);
35
36 if (curr != null) {
38 return;
39 }
40
41 interval.advance(days);
42 if (!interval.intervalElapsed()) return;
43
44 final float MAX_RANGE_FROM_MARKET = 5000;
45 final float MAX_RANGE_FROM_PLAYER = 2000;
46
48 if (player == null || player.isInHyperspace()) return;
49 final MarketAPI market = Misc.findNearestLocalMarket(player, MAX_RANGE_FROM_MARKET, new MarketFilter() {
50 public boolean acceptMarket(MarketAPI market) {
51 if (market.hasCondition(Conditions.FREE_PORT)) return false;
52
53 MemoryAPI mem = market.getMemoryWithoutUpdate();
54 //mem.unset(MARKET_TIMEOUT_KEY);
55 if (mem.contains(MARKET_TIMEOUT_KEY)) return false;
56 return true;
57 }
58 });
59 if (market == null) return;
61 return;
62 }
63
64 if (market.getFaction().isHostileTo(player.getFaction())) return;
65
66 List<CampaignFleetAPI> patrols = Misc.findNearbyFleets(player, MAX_RANGE_FROM_PLAYER, new FleetFilter() {
67 public boolean accept(CampaignFleetAPI curr) {
68 if (curr.getFaction() != market.getFaction()) return false;
69 if (curr.getFaction().isPlayerFaction()) return false;
70 if (curr.isHostileTo(player)) return false;
71 if (curr.isStationMode()) return false;
72 if (Misc.getSourceMarket(curr) != market) return false;
74 if (curr.getAI() instanceof ModularFleetAIAPI) {
76 if (ai.isFleeing()) return false;
77 if (curr.getInteractionTarget() instanceof CampaignFleetAPI) return false;
78 }
79 VisibilityLevel vis = player.getVisibilityLevelTo(curr);
80 if (vis == VisibilityLevel.NONE) return false;
81 return true;
82 }
83 });
84
85 if (patrols.isEmpty()) return;
86
87 float minDist = Float.MAX_VALUE;
88 CampaignFleetAPI closestPatrol = null;
89 float closestSuspicion = 0f;
90 for (CampaignFleetAPI curr : patrols) {
91 float dist = Misc.getDistance(player.getLocation(), curr.getLocation());
93 if (dist < minDist || extra > closestSuspicion) {
94 minDist = dist;
95 closestSuspicion = extra;
96 closestPatrol = curr;
97 }
98 }
99
100 if (closestPatrol == null) return;
101
102 curr = closestPatrol;
103
104 float threshold = 0.05f;
105 MemoryAPI marketMemory = market.getMemory();
106 float suspicionLevel = marketMemory.getFloat(MemFlags.MEMORY_MARKET_SMUGGLING_SUSPICION_LEVEL);
107 suspicionLevel += closestSuspicion;
108 //suspicionLevel = 1f;
109 boolean doScan = (float) Math.random() < suspicionLevel * 5f && suspicionLevel >= threshold;
111 doScan = false;
112 }
113 //doScan = true;
114
115 if (doScan) {
116 currDuration = 10f + (float) Math.random() * 5f;
117 currElapsed = 0f;
119 Misc.setFlagWithReason(mem, MemFlags.MEMORY_KEY_PURSUE_PLAYER, "smugglingScan", true, 1f);
120 Misc.setFlagWithReason(mem, MemFlags.MEMORY_KEY_STICK_WITH_PLAYER_IF_ALREADY_TARGET, "smugglingScan", true, currDuration);
121 } else {
122 curr = null;
123 }
124
125
126 if (suspicionLevel >= threshold) {
127 float timeoutDuration = 20f + (float) Math.random() * 10f;
128 marketMemory.set(MARKET_TIMEOUT_KEY, true, timeoutDuration);
129 }
130 }
131
132 public void maintainOngoingScan(float days) {
133 if (!curr.isAlive()) {
134 cleanUpCurr();
135 return;
136 }
138 cleanUpCurr();
139 return;
140 }
141
142 currElapsed += days;
143 if (currElapsed > currDuration) {
144 cleanUpCurr();
145 return;
146 }
147
148
149 // if visible, keep extending "pursue player" duration by a day
150 // so, player has to lose the patrol for a day to be able to sneak into market
152 if (player.isInHyperspace() || player.isInHyperspaceTransition()) {
153 cleanUpCurr();
154 return;
155 }
156
157 VisibilityLevel vis = player.getVisibilityLevelTo(curr);
158
159 if (vis != VisibilityLevel.NONE) {
161 if (mem.getBoolean(SCAN_COMPLETE_KEY)) { // this happens when fleet interacts w/ player
162 cleanUpCurr();
163 return;
164 }
165 //curr.getMemoryWithoutUpdate().contains("$pursuePlayer_smugglingScan");
167 Misc.setFlagWithReason(mem, MemFlags.MEMORY_KEY_PURSUE_PLAYER, "smugglingScan", true, 1f);
168 } else {
169 Misc.setFlagWithReason(mem, MemFlags.MEMORY_KEY_PURSUE_PLAYER, "smugglingScan", false, 0f);
170 }
171 }
172 }
173
174
175 protected void cleanUpCurr() {
176 if (curr != null) {
179 if (a != null && a.getAssignment() == FleetAssignment.INTERCEPT &&
180 a.getTarget() == pf) {
182 }
183 curr.setInteractionTarget(null);
184 if (curr.getAI() instanceof ModularFleetAIAPI) {
186 if (ai.getTacticalModule().getTarget() == pf) {
187 ai.getTacticalModule().setTarget(null);
188 }
189 }
190
192 Misc.setFlagWithReason(mem, MemFlags.MEMORY_KEY_PURSUE_PLAYER, "smugglingScan", false, 0f);
195 curr = null;
196 currDuration = currElapsed = 0f;
197 }
198 }
199
200
201 public boolean isDone() {
202 return false;
203 }
204
205 public boolean runWhilePaused() {
206 return false;
207 }
208}
209
210
211
212
213
214
215
216
217
218
219
220
221
static SectorAPI getSector()
Definition Global.java:65
static final String CUSTOM_ALLOWS_TRANSPONDER_OFF_TRADE
Definition Factions.java:54
static final String MEMORY_MARKET_SMUGGLING_SUSPICION_LEVEL
static final String MEMORY_KEY_STICK_WITH_PLAYER_IF_ALREADY_TARGET
static MarketAPI getSourceMarket(CampaignFleetAPI fleet)
Definition Misc.java:2162
static float getDistance(SectorEntityToken from, SectorEntityToken to)
Definition Misc.java:599
static boolean setFlagWithReason(MemoryAPI memory, String flagKey, String reason, boolean value, float expire)
Definition Misc.java:1439
static MarketAPI findNearestLocalMarket(SectorEntityToken token, float maxDist, MarketFilter filter)
Definition Misc.java:1146
static List< CampaignFleetAPI > findNearbyFleets(SectorEntityToken from, float maxRange, FleetFilter filter)
Definition Misc.java:912
void setInteractionTarget(SectorEntityToken target)
boolean isHostileTo(SectorEntityToken other)
boolean isHostileTo(FactionAPI other)
FleetAssignmentDataAPI getCurrentAssignment()
void removeFirstAssignmentIfItIs(FleetAssignment assignment)
VisibilityLevel getVisibilityLevelTo(SectorEntityToken other)
void set(String key, Object value)