Starsector API
Loading...
Searching...
No Matches
BlueprintIntel.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.missions;
2
3import java.awt.Color;
4import java.util.Map;
5
6import com.fs.starfarer.api.Global;
7import com.fs.starfarer.api.campaign.CargoAPI;
8import com.fs.starfarer.api.campaign.CargoStackAPI;
9import com.fs.starfarer.api.campaign.InteractionDialogAPI;
10import com.fs.starfarer.api.campaign.SectorEntityToken;
11import com.fs.starfarer.api.campaign.SpecialItemData;
12import com.fs.starfarer.api.campaign.StarSystemAPI;
13import com.fs.starfarer.api.campaign.econ.MarketAPI;
14import com.fs.starfarer.api.campaign.listeners.CargoGainedListener;
15import com.fs.starfarer.api.campaign.listeners.ShowLootListener;
16import com.fs.starfarer.api.campaign.rules.MemoryAPI;
17import com.fs.starfarer.api.characters.PersonAPI;
18import com.fs.starfarer.api.combat.ShipAPI.HullSize;
19import com.fs.starfarer.api.combat.ShipHullSpecAPI;
20import com.fs.starfarer.api.combat.WeaponAPI.WeaponSize;
21import com.fs.starfarer.api.impl.campaign.ids.Factions;
22import com.fs.starfarer.api.impl.campaign.ids.FleetTypes;
23import com.fs.starfarer.api.impl.campaign.ids.Items;
24import com.fs.starfarer.api.impl.campaign.ids.Ranks;
25import com.fs.starfarer.api.impl.campaign.ids.Tags;
26import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithBarEvent;
27import com.fs.starfarer.api.impl.campaign.missions.hub.ReqMode;
28import com.fs.starfarer.api.loading.FighterWingSpecAPI;
29import com.fs.starfarer.api.loading.WeaponSpecAPI;
30import com.fs.starfarer.api.ui.SectorMapAPI;
31import com.fs.starfarer.api.ui.TooltipMakerAPI;
32import com.fs.starfarer.api.util.Misc;
33import com.fs.starfarer.api.util.WeightedRandomPicker;
34
35public class BlueprintIntel extends HubMissionWithBarEvent implements ShowLootListener, CargoGainedListener {
36
37 public static float PROB_PATHER = 0.5f;
38 public static float PROB_MERC = 0.5f;
39
40 public static float PROB_TRY_TO_FIND_RUINS = 0.5f;
41 public static float FREQ_WEAPON = 10f;
42 public static float FREQ_FIGHTER = 10f;
43 public static float FREQ_SHIP = 10f;
44
45 public static enum Stage {
46 GET_ITEM,
47 COMPLETED,
48 }
49
50 protected StarSystemAPI system;
51
52 protected SpecialItemData item;
53 protected int price;
54 protected SectorEntityToken entity;
55
56 protected float getQualityMultForTier(int tier) {
57 float q = getQuality();
58 float qWeight = 1f;
59 if (tier <= 0) qWeight = 0;
60 else if (tier == 1) qWeight = 1f;
61 else if (tier == 2) qWeight = 2f;
62 else if (tier >= 3) qWeight = 4f;
63
64 return (1f - qWeight) + qWeight * (1f + q);
65 }
66
67 protected void pickItem() {
68
69 WeightedRandomPicker<String> typePicker = new WeightedRandomPicker<String>(genRandom);
70 typePicker.add(Items.FIGHTER_BP, FREQ_FIGHTER);
71 typePicker.add(Items.WEAPON_BP, FREQ_WEAPON);
72 typePicker.add(Items.SHIP_BP, FREQ_SHIP);
73
74 while (item == null && !typePicker.isEmpty()) {
75 String type = typePicker.pick();
76
77 if (type.equals(Items.FIGHTER_BP)) {
78 WeightedRandomPicker<FighterWingSpecAPI> picker = new WeightedRandomPicker<FighterWingSpecAPI>(genRandom);
79 for (FighterWingSpecAPI spec : Global.getSettings().getAllFighterWingSpecs()) {
80 if (!spec.hasTag(Items.TAG_RARE_BP)) continue;
81 if (spec.hasTag(Tags.NO_DROP)) continue;
82 if (Global.getSector().getPlayerFaction().knowsFighter(spec.getId())) continue;
83 float w = spec.getRarity() * getQualityMultForTier(spec.getTier());
84 picker.add(spec, w);
85 }
86 FighterWingSpecAPI pick = picker.pick();
87 if (pick != null) {
88 item = new SpecialItemData(type, pick.getId());
89 price = (int) pick.getBaseValue();
90 } else {
91 typePicker.remove(type);
92 }
93 } else if (type.equals(Items.WEAPON_BP)) {
94 WeightedRandomPicker<WeaponSpecAPI> picker = new WeightedRandomPicker<WeaponSpecAPI>(genRandom);
95 for (WeaponSpecAPI spec : Global.getSettings().getAllWeaponSpecs()) {
96 if (!spec.hasTag(Items.TAG_RARE_BP)) continue;
97 if (spec.hasTag(Tags.NO_DROP)) continue;
98 if (Global.getSector().getPlayerFaction().knowsWeapon(spec.getWeaponId())) continue;
99 float w = spec.getRarity() * getQualityMultForTier(spec.getTier());;
100 picker.add(spec, w);
101 }
102 WeaponSpecAPI pick = picker.pick();
103 if (pick != null) {
104 item = new SpecialItemData(type, pick.getWeaponId());
105 price = (int) pick.getBaseValue();
106 } else {
107 typePicker.remove(type);
108 }
109 } else if (type.equals(Items.SHIP_BP)) {
110 WeightedRandomPicker<ShipHullSpecAPI> picker = new WeightedRandomPicker<ShipHullSpecAPI>(genRandom);
111 for (ShipHullSpecAPI spec : Global.getSettings().getAllShipHullSpecs()) {
112 if (!spec.hasTag(Items.TAG_RARE_BP)) continue;
113 if (spec.hasTag(Tags.NO_DROP)) continue;
114 if (Global.getSector().getPlayerFaction().knowsShip(spec.getHullId())) continue;
115 float w = spec.getRarity() * getQualityMultForTier(spec.getFleetPoints() / 6);;
116 picker.add(spec, w);
117 }
118 ShipHullSpecAPI pick = picker.pick();
119 if (pick != null) {
120 item = new SpecialItemData(type, pick.getHullId());
121 price = (int) pick.getBaseValue();
122 } else {
123 typePicker.remove(type);
124 }
125 } else {
126 // ???
127 break;
128 }
129 }
130
131 if (price != 0) {
132 price = getRoundNumber(price * (1.5f + (1f - getRewardMultFraction())));
133 }
134 }
135
136 protected String getItemNameLowercaseItem() {
137 String item = getItemName();
138 item = item.replaceFirst(" Item", " item");
139 item = item.replaceFirst(" Blueprint", " blueprint");
140 return item;
141 }
142 protected String getItemName() {
143 if (item == null) return "an Invalid Item";
144
145 String name = "Invalid Item";
146 if (item.getId().equals(Items.FIGHTER_BP)) {
147 FighterWingSpecAPI spec = Global.getSettings().getFighterWingSpec(item.getData());
148 name = spec.getWingName() + " Blueprint";
149 } else if (item.getId().equals(Items.WEAPON_BP)) {
150 WeaponSpecAPI spec = Global.getSettings().getWeaponSpec(item.getData());
151 name = spec.getWeaponName() + " Blueprint";
152 } else if (item.getId().equals(Items.SHIP_BP)) {
153 ShipHullSpecAPI spec = Global.getSettings().getHullSpec(item.getData());
154 name = spec.getHullName() + " Blueprint";
155 }
156 return Misc.getAOrAnFor(name) + " " + name;
157 }
158
159 protected boolean isVeryValuable() {
160 if (item.getId().equals(Items.FIGHTER_BP)) {
161 //FighterWingSpecAPI spec = Global.getSettings().getFighterWingSpec(item.getData());
162 return false;
163 } else if (item.getId().equals(Items.WEAPON_BP)) {
164 WeaponSpecAPI spec = Global.getSettings().getWeaponSpec(item.getData());
165 return spec.getSize() == WeaponSize.LARGE;
166 } else if (item.getId().equals(Items.SHIP_BP)) {
167 ShipHullSpecAPI spec = Global.getSettings().getHullSpec(item.getData());
168 return spec.getHullSize().ordinal() >= HullSize.DESTROYER.ordinal();
169 }
170 return false;
171 }
172
173
174 @Override
175 protected boolean create(MarketAPI createdAt, boolean barEvent) {
176 //genRandom = Misc.random;
177
178 if (barEvent) {
179 setGiverRank(Ranks.CITIZEN);
180 setGiverPost(pickOne(Ranks.POST_AGENT, Ranks.POST_SMUGGLER, Ranks.POST_GANGSTER,
181 Ranks.POST_FENCE, Ranks.POST_CRIMINAL));
182 setGiverImportance(pickImportance());
183 setGiverFaction(Factions.PIRATES);
184 setGiverTags(Tags.CONTACT_UNDERWORLD);
185 findOrCreateGiver(createdAt, false, false);
186 }
187
188 PersonAPI person = getPerson();
189 if (person == null) return false;
190
191 pickItem();
192 if (item == null) return false;
193
194
195 if (!setPersonMissionRef(person, "$sitm_ref")) {
196 return false;
197 }
198
199 if (barEvent) {
200 setGiverIsPotentialContactOnSuccess();
201 }
202
203 requireSystemInterestingAndNotCore();
204 preferSystemUnexplored();
205 preferSystemTags(ReqMode.NOT_ANY, Tags.THEME_DERELICT);
206
207 entity = null;
208 if (rollProbability(PROB_TRY_TO_FIND_RUINS)) {
209 requirePlanetUnpopulated();
210 requirePlanetWithRuins();
211 requirePlanetNotFullySurveyed();
212 requirePlanetUnexploredRuins();
213 preferPlanetInDirectionOfOtherMissions();
214 entity = pickPlanet();
215 }
216
217 if (entity == null) {
218 requireEntityTags(ReqMode.ANY, Tags.SALVAGEABLE);
219 preferEntityInDirectionOfOtherMissions();
220 entity = pickEntity();
221 }
222
223 if (entity == null) {
224 return false;
225 }
226
227 system = entity.getStarSystem();
228 if (system == null) return false;
229
230 setStartingStage(Stage.GET_ITEM);
231 setSuccessStage(Stage.COMPLETED);
232
233 addTag(Tags.INTEL_EXPLORATION);
234
235 boolean veryValuable = isVeryValuable();
236
237 int numScav = genRandom.nextInt(3);
238 if (veryValuable) numScav += 2;
239
240 for (int i = 0; i < numScav; i++) {
241 beginWithinHyperspaceRangeTrigger(system, 3f, false, Stage.GET_ITEM);
242 triggerCreateFleet(FleetSize.LARGE, FleetQuality.DEFAULT, Factions.SCAVENGERS, FleetTypes.SCAVENGER_MEDIUM, system);
243 triggerAutoAdjustFleetStrengthMajor();
244 triggerSetFleetFaction(Factions.INDEPENDENT);
245
246 triggerMakeLowRepImpact();
247
248 triggerSpawnFleetNear(system.getCenter(), null, "$sitm_ref");
249 triggerFleetSetTravelActionText("exploring system");
250 triggerFleetSetPatrolActionText("scanning local volume");
251 triggerOrderFleetPatrol(system, true, Tags.SALVAGEABLE, Tags.PLANET);
252 triggerFleetSetWarnAttack("SITMScavWarning", "SITMScavAttack", Stage.GET_ITEM);
253 endTrigger();
254 }
255
256
257 if (veryValuable && rollProbability(PROB_MERC)) {
258 beginWithinHyperspaceRangeTrigger(system, 3f, false, Stage.GET_ITEM);
259 triggerCreateFleet(FleetSize.VERY_LARGE, FleetQuality.VERY_HIGH, Factions.MERCENARY, FleetTypes.PATROL_LARGE, system);
260 triggerSetFleetFaction(Factions.INDEPENDENT);
261 triggerSetFleetOfficers(OfficerNum.MORE, OfficerQuality.HIGHER);
262 triggerAutoAdjustFleetStrengthMajor();
263 triggerMakeLowRepImpact();
264 triggerFleetAllowLongPursuit();
265 triggerSetFleetAlwaysPursue();
266 triggerSpawnFleetNear(system.getCenter(), null, "$sitm_ref");
267 triggerOrderFleetPatrol(system, true, Tags.JUMP_POINT);
268 triggerFleetSetWarnAttack("SITMMercWarning", "SITMMercAttack", Stage.GET_ITEM);
269 endTrigger();
270 }
271
272 return true;
273 }
274
275
276 public void reportAboutToShowLootToPlayer(CargoAPI loot, InteractionDialogAPI dialog) {
277 for (CargoStackAPI stack : loot.getStacksCopy()) {
278 if (item.equals(stack.getData())) {
279 Global.getSector().getListenerManager().removeListener(this);
280 setCurrentStage(Stage.COMPLETED, dialog, dialog.getPlugin().getMemoryMap());
281 break;
282 }
283 }
284 }
285
286 public void reportSpecialCargoGainedFromRecoveredDerelict(CargoAPI loot, InteractionDialogAPI dialog) {
287 reportAboutToShowLootToPlayer(loot, dialog);
288 }
289
290 @Override
291 public void acceptImpl(InteractionDialogAPI dialog, Map<String, MemoryAPI> memoryMap) {
292 super.acceptImpl(dialog, memoryMap);
293 addSpecialItemDropOnlyUseInAcceptImplNotUndoneOnAbort(entity, item);
294 Global.getSector().getListenerManager().addListener(this);
295 }
296
297 @Override
298 protected void notifyEnding() {
299 super.notifyEnding();
300
301 Global.getSector().getListenerManager().removeListener(this);
302
303 if (!rollProbability(PROB_PATHER)) return;
304
305 PersonAPI person = getPerson();
306 if (person == null || person.getMarket() == null) return;
307 String patrolFaction = person.getMarket().getFactionId();
308 if (patrolFaction.equals(person.getFaction().getId()) ||
309 Misc.isPirateFaction(person.getMarket().getFaction())) {
310 return;
311 }
312
313 DelayedFleetEncounter e = new DelayedFleetEncounter(genRandom, getMissionId());
314 e.setDelayNone();
316 e.setLocationAnywhere(true, Factions.LUDDIC_PATH);
317 e.beginCreate();
318 e.triggerCreateFleet(FleetSize.LARGE, FleetQuality.DEFAULT, Factions.LUDDIC_PATH, FleetTypes.PATROL_LARGE, system);
319 e.triggerSetAdjustStrengthBasedOnQuality(true, getQuality());
321 e.triggerSetFleetGenericHailPermanent("SITMPatherHail");
322 e.triggerFleetPatherNoDefaultTithe();
323 e.endCreate();
324 }
325
326
327 protected void updateInteractionDataImpl() {
328 set("$sitm_barEvent", isBarEvent());
329 set("$sitm_manOrWoman", getPerson().getManOrWoman());
330 set("$sitm_heOrShe", getPerson().getHeOrShe());
331
332 set("$sitm_price", Misc.getWithDGS(price));
333
334 set("$sitm_aOrAnItem", getItemNameLowercaseItem());
335 set("$sitm_item", getWithoutArticle(getItemNameLowercaseItem()));
336
337 set("$sitm_personName", getPerson().getNameString());
338 set("$sitm_systemName", system.getNameWithLowercaseTypeShort());
339 set("$sitm_dist", getDistanceLY(system));
340 }
341
342 @Override
343 public void addDescriptionForNonEndStage(TooltipMakerAPI info, float width, float height) {
344 float opad = 10f;
345 Color h = Misc.getHighlightColor();
346 if (currentStage == Stage.GET_ITEM) {
347 info.addPara("There is " + getItemNameLowercaseItem() +
348 " to be found somewhere in the " + system.getNameWithLowercaseTypeShort() + ".", opad);
349 }
350 }
351
352 @Override
353 public boolean addNextStepText(TooltipMakerAPI info, Color tc, float pad) {
354 Color h = Misc.getHighlightColor();
355 if (currentStage == Stage.GET_ITEM) {
356 info.addPara("There is " + getItemNameLowercaseItem() + " in the " +
357 system.getNameWithLowercaseTypeShort(), tc, pad);
358 return true;
359 }
360 return false;
361 }
362
363 @Override
364 public String getBaseName() {
365 return Misc.ucFirst(getWithoutArticle(getItemName())) + " Intel";
366 }
367
368 protected String getMissionTypeNoun() {
369 return "intel";
370 }
371
372 protected String getMissionCompletionVerb() {
373 return "acted on";
374 }
375
376 @Override
377 public SectorEntityToken getMapLocation(SectorMapAPI map) {
378 return getMapLocationFor(system.getHyperspaceAnchor());
379 }
380
381
382}
383
384
385
386
387
388
static SettingsAPI getSettings()
Definition Global.java:51
static SectorAPI getSector()
Definition Global.java:59
boolean addNextStepText(TooltipMakerAPI info, Color tc, float pad)
void addDescriptionForNonEndStage(TooltipMakerAPI info, float width, float height)
void reportSpecialCargoGainedFromRecoveredDerelict(CargoAPI loot, InteractionDialogAPI dialog)
void reportAboutToShowLootToPlayer(CargoAPI loot, InteractionDialogAPI dialog)
boolean create(MarketAPI createdAt, boolean barEvent)
void acceptImpl(InteractionDialogAPI dialog, Map< String, MemoryAPI > memoryMap)
void setLocationAnywhere(boolean allowInsidePopulatedSystems, String requireLargestMarketNotHostileToFaction)
void triggerCreateFleet(FleetSize size, FleetQuality quality, String factionId, String type, SectorEntityToken roughlyWhere)
ShipHullSpecAPI getHullSpec(String hullId)
List< WeaponSpecAPI > getAllWeaponSpecs()
FighterWingSpecAPI getFighterWingSpec(String wingId)
WeaponSpecAPI getWeaponSpec(String weaponId)
List< ShipHullSpecAPI > getAllShipHullSpecs()
List< FighterWingSpecAPI > getAllFighterWingSpecs()