Starsector API
Loading...
Searching...
No Matches
PatrolAssignmentAI.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.fleets;
2
3import java.util.ArrayList;
4import java.util.List;
5
6import org.lwjgl.util.vector.Vector2f;
7
8import com.fs.starfarer.api.EveryFrameScript;
9import com.fs.starfarer.api.Global;
10import com.fs.starfarer.api.campaign.CampaignFleetAPI;
11import com.fs.starfarer.api.campaign.FleetAssignment;
12import com.fs.starfarer.api.campaign.SectorEntityToken;
13import com.fs.starfarer.api.campaign.StarSystemAPI;
14import com.fs.starfarer.api.campaign.ai.FleetAssignmentDataAPI;
15import com.fs.starfarer.api.campaign.econ.MarketAPI;
16import com.fs.starfarer.api.impl.campaign.fleets.PatrolFleetManager.PatrolFleetData;
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.WeightedRandomPicker;
21import com.fs.starfarer.api.util.Misc.FleetFilter;
22
23public class PatrolAssignmentAI implements EveryFrameScript {
24
25 private CampaignFleetAPI fleet;
26 private PatrolFleetData data;
27
28 private IntervalUtil tracker = new IntervalUtil(0.5f, 1.5f);
29
30 public PatrolAssignmentAI(CampaignFleetAPI fleet, PatrolFleetData data) {
31 this.fleet = fleet;
32 this.data = data;
33 giveInitialAssignment();
34 }
35
36 private void giveInitialAssignment() {
37
38 float daysToOrbit = getDaysToOrbit() * 0.25f;
39 if (daysToOrbit < 0.2f) {
40 daysToOrbit = 0.2f;
41 }
42 //fleet.addAssignment(FleetAssignment.ORBIT_PASSIVE, data.sourceMarket.getPrimaryEntity(), daysToOrbit,
43 fleet.addAssignment(FleetAssignment.ORBIT_PASSIVE, data.sourceMarket.getPrimaryEntity(), daysToOrbit,
44 "preparing for patrol duty");
45 }
46
47 private boolean orderedReturn = false;
48 public void advance(float amount) {
49 float days = Global.getSector().getClock().convertToDays(amount);
50
51// if (!orderedReturn) {
52// tracker.advance(days);
53// if (tracker.intervalElapsed()) {
54// checkNPCCustomsInspection();
55// }
56// performInspectionIfNeeded();
57// }
58
59
60
61// if (fleet.getFaction().getId().equals("knights_of_ludd")) {
62// System.out.println("wesdfsd");
63// }
64 if (fleet.getAI().getCurrentAssignment() != null) {
65 float fp = fleet.getFleetPoints();
66 if (fp < data.startingFleetPoints && !orderedReturn) {
67 orderedReturn = true;
68 fleet.clearAssignments();
69
70 fleet.addAssignment(FleetAssignment.GO_TO_LOCATION, data.sourceMarket.getPrimaryEntity(), 1000,
71 "returning to " + data.sourceMarket.getName());
72 fleet.addAssignment(FleetAssignment.ORBIT_PASSIVE, data.sourceMarket.getPrimaryEntity(), 1f,
73 "standing down from patrol duty");
74 fleet.addAssignment(FleetAssignment.GO_TO_LOCATION_AND_DESPAWN, data.sourceMarket.getPrimaryEntity(), 1000);
75 }
76 } else {
77// if (fleet.getFaction().getId().equals("knights_of_ludd")) {
78// System.out.println("wesdfsd");
79// }
80 float daysToOrbit = getDaysToOrbit();
81 StarSystemAPI system = data.sourceMarket.getStarSystem();
82 if (system == null) {
83 fleet.addAssignment(FleetAssignment.DEFEND_LOCATION, data.sourceMarket.getPrimaryEntity(), 20,
84 "patrolling around " + data.sourceMarket.getName());
85 fleet.addAssignment(FleetAssignment.GO_TO_LOCATION, data.sourceMarket.getPrimaryEntity(), 1000,
86 "returning to " + data.sourceMarket.getName());
87 fleet.addAssignment(FleetAssignment.ORBIT_PASSIVE, data.sourceMarket.getPrimaryEntity(), daysToOrbit,
88 "standing down from patrol duty");
89 } else {
90 if ((float) Math.random() > 0.95f) {
91 fleet.addAssignment(FleetAssignment.PATROL_SYSTEM, system.getHyperspaceAnchor(), 20,
92 "patrolling around the " + system.getBaseName() + " star system");
93 fleet.addAssignment(FleetAssignment.GO_TO_LOCATION, data.sourceMarket.getPrimaryEntity(), 1000,
94 "returning to " + data.sourceMarket.getName());
95 fleet.addAssignment(FleetAssignment.ORBIT_PASSIVE, data.sourceMarket.getPrimaryEntity(), daysToOrbit,
96 "standing down from patrol duty");
97 } else {
98 WeightedRandomPicker<SectorEntityToken> defenseTargets = new WeightedRandomPicker<SectorEntityToken>();
99 SectorEntityToken generalPatrol = data.sourceMarket.getPrimaryEntity().getContainingLocation().createToken(0, 0);
100
101// for (SectorEntityToken relay : system.getEntitiesWithTag(Tags.COMM_RELAY)) {
102// float weight = 10;
103// if (data.type == PatrolType.FAST) weight = 40;
104// defenseTargets.add(relay, weight);
105// }
106// defenseTargets.add(data.sourceMarket.getPrimaryEntity(), 30);
107 defenseTargets.add(generalPatrol, 30);
108
109 SectorEntityToken pick = defenseTargets.pick();
110
111 if (pick == generalPatrol) {
112 fleet.addAssignment(FleetAssignment.PATROL_SYSTEM, system.getStar(), 30,
113 "patrolling the " + system.getBaseName() + " star system");
114 fleet.addAssignment(FleetAssignment.GO_TO_LOCATION, data.sourceMarket.getPrimaryEntity(), 1000,
115 "returning to " + data.sourceMarket.getName());
116 fleet.addAssignment(FleetAssignment.ORBIT_PASSIVE, data.sourceMarket.getPrimaryEntity(), daysToOrbit,
117 "standing down from patrol duty");
118 } else {
119 fleet.addAssignment(FleetAssignment.DEFEND_LOCATION, pick, 30,
120 "patrolling around " + pick.getName());
121 fleet.addAssignment(FleetAssignment.GO_TO_LOCATION, data.sourceMarket.getPrimaryEntity(), 1000,
122 "returning to " + data.sourceMarket.getName());
123 fleet.addAssignment(FleetAssignment.ORBIT_PASSIVE, data.sourceMarket.getPrimaryEntity(), daysToOrbit,
124 "standing down from patrol duty");
125 }
126 }
127 }
128 }
129 }
130
131
132 private void performInspectionIfNeeded() {
133 if (inspectionTarget != null) {
134// if (fleet.isInCurrentLocation()) {
135// System.out.println("fe423fr");
136// }
137 List<CampaignFleetAPI> hostiles = Misc.findNearbyFleets(fleet, 200, new FleetFilter() {
138 public boolean accept(CampaignFleetAPI curr) {
139 //return curr.getFaction().isHostileTo(fleet.getFaction());
140 return curr.isHostileTo(fleet);
141 }
142 });
143 if (inspectionTarget != null) {
144 float dist = Misc.getDistance(inspectionTarget.getLocation(), fleet.getLocation());
145 if (dist > 2000 || inspectionTarget.getContainingLocation() != fleet.getContainingLocation()) {
146 inspectionTarget.getAI().removeFirstAssignmentIfItIs(FleetAssignment.HOLD);
147 fleet.getAI().removeFirstAssignmentIfItIs(FleetAssignment.HOLD);
148 fleet.getAI().removeFirstAssignmentIfItIs(FleetAssignment.FOLLOW);
149 fleet.getAI().removeFirstAssignmentIfItIs(FleetAssignment.HOLD);
150 fleet.getAI().removeFirstAssignmentIfItIs(FleetAssignment.FOLLOW);
151 //fleet.getAI().addAssignmentAtStart(FleetAssignment.FOLLOW, target, 2.5f, "performing customs inspection", null);
152 inspectionTarget = null;
153 fleet.getMemoryWithoutUpdate().unset("$performingNPCInspection");
154 return;
155 }
156 }
157
158 if (fleet.getMemoryWithoutUpdate().contains("$performingNPCInspection") && hostiles.isEmpty()) {
159 float dist = Misc.getDistance(inspectionTarget.getLocation(), fleet.getLocation());
160 float radSum = inspectionTarget.getRadius() + fleet.getRadius();
161 FleetAssignmentDataAPI curr = fleet.getAI().getCurrentAssignment();
162 Vector2f offset = Vector2f.sub(fleet.getLocation(), inspectionTarget.getLocation(), new Vector2f());
163 Misc.normalise(offset);
164 offset.scale(radSum);
165 Vector2f.add(inspectionTarget.getLocation(), offset, offset);
166 SectorEntityToken loc = fleet.getContainingLocation().createToken(offset.x, offset.y);
167
168 boolean forceReapproach = false;
169 if (curr != null && curr.getTarget() != null) {
170 float locDist = Misc.getDistance(inspectionTarget.getLocation(), curr.getTarget().getLocation());
171 forceReapproach = locDist > radSum + 5f;
172 }
173// if (fleet.isInCurrentLocation()) {
174// System.out.println("dsfwefe");
175// }
176 if ((dist - radSum > 5 || dist - radSum < -5) && (curr == null || curr.getAssignment() != FleetAssignment.FOLLOW || forceReapproach)) {
177 fleet.getAI().removeFirstAssignmentIfItIs(FleetAssignment.HOLD);
178 fleet.getAI().removeFirstAssignmentIfItIs(FleetAssignment.FOLLOW);
179 //fleet.getAI().addAssignmentAtStart(FleetAssignment.FOLLOW, inspectionTarget, 2f, "approaching " + inspectionTarget.getName(), null);
180 if (dist - radSum <= 50) {
181 fleet.getAI().addAssignmentAtStart(FleetAssignment.FOLLOW, loc, 0.1f, "performing customs inspection", null);
182 } else {
183 fleet.getAI().addAssignmentAtStart(FleetAssignment.FOLLOW, loc, 0.1f, "approaching " + inspectionTarget.getName(), null);
184 }
185 } else if ((dist - radSum <= 5 && dist - radSum >= -5) && (curr == null || curr.getAssignment() != FleetAssignment.HOLD)) {
186 fleet.getAI().removeFirstAssignmentIfItIs(FleetAssignment.FOLLOW);
187 fleet.getAI().removeFirstAssignmentIfItIs(FleetAssignment.HOLD);
188
189 //fleet.getAI().addAssignmentAtStart(FleetAssignment.HOLD, inspectionTarget, 2f, "performing customs inspection", null);
190 //fleet.getAI().addAssignmentAtStart(FleetAssignment.HOLD, loc, 2f, "performing customs inspection", null);
191 fleet.getAI().addAssignmentAtStart(FleetAssignment.HOLD, null, 0.1f, "performing customs inspection", null);
192 }
193 } else {
194 inspectionTarget.getAI().removeFirstAssignmentIfItIs(FleetAssignment.HOLD);
195 fleet.getAI().removeFirstAssignmentIfItIs(FleetAssignment.HOLD);
196 fleet.getAI().removeFirstAssignmentIfItIs(FleetAssignment.FOLLOW);
197 fleet.getAI().removeFirstAssignmentIfItIs(FleetAssignment.HOLD);
198 fleet.getAI().removeFirstAssignmentIfItIs(FleetAssignment.FOLLOW);
199 //fleet.getAI().addAssignmentAtStart(FleetAssignment.FOLLOW, target, 2.5f, "performing customs inspection", null);
200 inspectionTarget = null;
201 fleet.getMemoryWithoutUpdate().unset("$performingNPCInspection");
202 }
203 }
204 }
205
206 private CampaignFleetAPI inspectionTarget = null;
207 private void checkNPCCustomsInspection() {
208
209 //if (!fleet.isInCurrentLocation()) return;
210 //if ((float) Math.random() < 0.75f) return;
211
212 if (inspectionTarget != null) return;
213 if (fleet.getMemoryWithoutUpdate().contains(MemFlags.FLEET_BUSY)) return;
214 if (!fleet.getMemoryWithoutUpdate().contains(MemFlags.MEMORY_KEY_CUSTOMS_INSPECTOR)) return;
215
216 if (fleet.getAI() != null &&
217 !fleet.getAI().isCurrentAssignment(FleetAssignment.PATROL_SYSTEM) &&
218 !fleet.getAI().isCurrentAssignment(FleetAssignment.DEFEND_LOCATION)) return;
219
220 MarketAPI closest = Misc.findNearestLocalMarketWithSameFaction(fleet, 1500);
221 if (closest == null || !closest.getFactionId().equals(fleet.getFaction().getId())) return;
222
223 List<CampaignFleetAPI> hostiles = Misc.findNearbyFleets(fleet, 600, new FleetFilter() {
224 public boolean accept(CampaignFleetAPI curr) {
225 //return curr.getFaction().isHostileTo(fleet.getFaction());
226 return curr.isHostileTo(fleet);
227 }
228 });
229 if (!hostiles.isEmpty()) return;
230
231
232 List<CampaignFleetAPI> allFleets = new ArrayList<CampaignFleetAPI>(fleet.getContainingLocation().getFleets());
233 allFleets.addAll(fleet.getContainingLocation().getFleets());
234 WeightedRandomPicker<CampaignFleetAPI> picker = new WeightedRandomPicker<CampaignFleetAPI>();
235 for (final CampaignFleetAPI curr : allFleets) {
236 if (curr == fleet) continue;
237 //if (curr.getFaction().isHostileTo(fleet.getFaction())) continue;
238 if (curr.isHostileTo(fleet)) continue;
239
240 if (curr.isInHyperspaceTransition()) continue;
241
242 if (!curr.getMemoryWithoutUpdate().contains(MemFlags.MEMORY_KEY_SMUGGLER) &&
243 !curr.getMemoryWithoutUpdate().contains(MemFlags.MEMORY_KEY_TRADE_FLEET)) continue;
244
245 if (curr.getMemoryWithoutUpdate().contains("$recentlyInspected")) return;
246 if (curr.getMemoryWithoutUpdate().contains(MemFlags.FLEET_BUSY)) return;
247
248 float dist = Misc.getDistance(curr.getLocation(), fleet.getLocation());
249 if (dist > 1000) continue;
250 if (dist < 100) dist = 100f;
251
252 hostiles = Misc.findNearbyFleets(curr, 600, new FleetFilter() {
253 public boolean accept(CampaignFleetAPI curr) {
254 //return curr.getFaction().isHostileTo(curr.getFaction());
255 return curr.isHostileTo(fleet);
256 }
257 });
258 if (!hostiles.isEmpty()) continue;
259
260 picker.add(curr, 1000f / dist);
261 }
262
263 if (picker.isEmpty()) return;
264
265 CampaignFleetAPI target = picker.pick();
266
267 target.getMemoryWithoutUpdate().set("$recentlyInspected", true, 15f);
268 target.getMemoryWithoutUpdate().set(MemFlags.FLEET_BUSY, true, 3f);
269 fleet.getMemoryWithoutUpdate().set(MemFlags.FLEET_BUSY, true, 3f);
270 fleet.getMemoryWithoutUpdate().set("$performingNPCInspection", true, 2f);
271 //fleet.getMemoryWithoutUpdate().set("$performingNPCInspection", true, 3f);
272
273 target.getAI().addAssignmentAtStart(FleetAssignment.HOLD, null, 2f, "standing by for inspection", null);
274 //fleet.getAI().addAssignmentAtStart(FleetAssignment.FOLLOW, target, 2.5f, "performing customs inspection", null);
275
276 inspectionTarget = target;
277 }
278
279
280
281
282
283 private float getDaysToOrbit() {
284 float daysToOrbit = 0f;
285 switch (data.type) {
286 case FAST:
287 daysToOrbit += 2f;
288 break;
289 case COMBAT:
290 daysToOrbit += 4f;
291 break;
292 case HEAVY:
293 daysToOrbit += 6f;
294 break;
295 }
296
297 daysToOrbit = daysToOrbit * (0.5f + (float) Math.random() * 0.5f);
298 return daysToOrbit;
299 }
300
301 public boolean isDone() {
302 return false;
303 }
304 public boolean runWhilePaused() {
305 return false;
306 }
307
308}
309
310
311
312
313
static SectorAPI getSector()
Definition Global.java:59
PatrolAssignmentAI(CampaignFleetAPI fleet, PatrolFleetData data)