1package com.fs.starfarer.api.impl.campaign.missions.cb;
4import java.util.ArrayList;
5import java.util.LinkedHashSet;
10import com.fs.starfarer.api.Global;
11import com.fs.starfarer.api.campaign.BattleAPI;
12import com.fs.starfarer.api.campaign.CampaignEventListener.FleetDespawnReason;
13import com.fs.starfarer.api.campaign.CampaignFleetAPI;
14import com.fs.starfarer.api.campaign.InteractionDialogAPI;
15import com.fs.starfarer.api.campaign.PlanetAPI;
16import com.fs.starfarer.api.campaign.SectorEntityToken;
17import com.fs.starfarer.api.campaign.econ.MarketAPI;
18import com.fs.starfarer.api.campaign.listeners.FleetEventListener;
19import com.fs.starfarer.api.campaign.rules.MemKeys;
20import com.fs.starfarer.api.campaign.rules.MemoryAPI;
21import com.fs.starfarer.api.characters.PersonAPI;
22import com.fs.starfarer.api.impl.campaign.ids.Tags;
23import com.fs.starfarer.api.impl.campaign.missions.cb.CustomBountyCreator.CustomBountyData;
24import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithBarEvent;
25import com.fs.starfarer.api.impl.campaign.rulecmd.FireBest;
26import com.fs.starfarer.api.ui.SectorMapAPI;
27import com.fs.starfarer.api.ui.TooltipMakerAPI;
28import com.fs.starfarer.api.util.Misc;
29import com.fs.starfarer.api.util.Misc.Token;
30import com.fs.starfarer.api.util.WeightedRandomPicker;
32public class BaseCustomBounty extends HubMissionWithBarEvent implements FleetEventListener {
36 public static enum Stage {
43 public static enum DifficultyChoice {
49 public static class AggregateBountyData {
50 public List<Integer> completedDifficulty =
new ArrayList<Integer>();
54 return "$" + getMissionId() +
"_aggregateData";
61 data =
new AggregateBountyData();
74 protected CustomBountyData
data;
80 return new ArrayList<CustomBountyCreator>();
91 for (Integer diff : d.completedDifficulty) {
96 float difficulty = total;
99 difficulty = (int) difficulty;
109 difficulty = Math.min(difficulty - 3f, (
int)(difficulty / 2f));
114 difficulty = difficulty + 1;
118 difficulty = difficulty + 3;
122 int result = (int)Math.round(difficulty);
140 }
catch (Throwable t) {
141 throw new RuntimeException(t);
145 WeightedRandomPicker<CustomBountyCreator> picker =
new WeightedRandomPicker<CustomBountyCreator>(genRandom);
147 float quality = getQuality();
151 if (curr.getMinDifficulty() > difficulty)
continue;
152 if (curr.getMaxDifficulty() < difficulty)
continue;
155 if (choice == DifficultyChoice.HIGH) {
157 if (difficulty >= threshold)
continue;
159 if (choice == DifficultyChoice.NORMAL) {
161 if (difficulty >= threshold)
continue;
164 float probToSkip = (1.1f - quality) * (
float) curr.getMinDifficulty() / maxDiff;
165 if (rollProbability(probToSkip))
continue;
167 picker.add(curr, curr.getFrequency(
this, difficulty));
170 return picker.pick();
180 genRandom = Misc.random;
188 protected boolean create(MarketAPI createdAt,
boolean barEvent) {
208 PersonAPI person = getPerson();
209 if (person ==
null)
return false;
211 String
id = getMissionId();
212 if (!setPersonMissionRef(person,
"$" +
id +
"_ref")) {
216 setStartingStage(Stage.BOUNTY);
217 setSuccessStage(Stage.COMPLETED);
218 setFailureStage(Stage.FAILED);
219 addNoPenaltyFailureStages(Stage.FAILED_NO_PENALTY);
223 connectWithMemoryFlag(Stage.BOUNTY, Stage.COMPLETED, person,
"$" +
id +
"_completed");
224 connectWithMemoryFlag(Stage.BOUNTY, Stage.FAILED, person,
"$" +
id +
"_failed");
226 addTag(Tags.INTEL_BOUNTY);
257 String
id = getMissionId();
258 set(
"$" +
id +
"_barEvent", isBarEvent());
259 set(
"$" +
id +
"_manOrWoman", getPerson().getManOrWoman());
260 set(
"$" +
id +
"_reward", Misc.getWithDGS(getCreditsReward()));
261 set(
"$bcb_barEvent", isBarEvent());
262 set(
"$bcb_manOrWoman", getPerson().getManOrWoman());
263 set(
"$bcb_reward", Misc.getWithDGS(getCreditsReward()));
268 set(
"$" +
id +
"_difficultyNum",
showData.difficulty);
269 set(
"$bcb_difficultyNum",
showData.difficulty);
272 set(
"$" +
id +
"_systemName",
showData.system.getNameWithLowercaseType());
273 set(
"$" +
id +
"_dist", getDistanceLY(
showData.system.getCenter()));
274 set(
"$bcb_systemName",
showData.system.getNameWithLowercaseType());
275 set(
"$bcb_dist", getDistanceLY(
showData.system.getCenter()));
278 set(
"$" +
id +
"_targetMarketName",
showData.market.getName());
279 set(
"$bcb_targetMarketName",
showData.market.getName());
280 set(
"$" +
id +
"_targetMarketOnOrAt",
showData.market.getOnOrAt());
281 set(
"$bcb_targetMarketOnOrAt",
showData.market.getOnOrAt());
287 PersonAPI p =
showData.fleet.getCommander();
288 set(
"$" +
id +
"_targetHeOrShe", p.getHeOrShe());
289 set(
"$" +
id +
"_targetHisOrHer", p.getHisOrHer());
290 set(
"$" +
id +
"_targetHimOrHer", p.getHimOrHer());
291 set(
"$" +
id +
"_targetName", p.getNameString());
292 set(
"$bcb_targetHeOrShe", p.getHeOrShe());
293 set(
"$bcb_targetHisOrHer", p.getHisOrHer());
294 set(
"$bcb_targetHimOrHer", p.getHimOrHer());
295 set(
"$bcb_targetName", p.getNameString());
297 set(
"$" +
id +
"_TargetHeOrShe", Misc.ucFirst(p.getHeOrShe()));
298 set(
"$" +
id +
"_TargetHisOrHer", Misc.ucFirst(p.getHisOrHer()));
299 set(
"$" +
id +
"_TargetHimOrHer", Misc.ucFirst(p.getHimOrHer()));
300 set(
"$bcb_TargetHeOrShe", Misc.ucFirst(p.getHeOrShe()));
301 set(
"$bcb_TargetHisOrHer", Misc.ucFirst(p.getHisOrHer()));
302 set(
"$bcb_TargetHimOrHer", Misc.ucFirst(p.getHimOrHer()));
304 set(
"$bcb_fleetName",
showData.fleet.getName());
313 protected boolean callAction(String action, String ruleId, InteractionDialogAPI dialog, List<Token> params,
314 Map<String, MemoryAPI> memoryMap) {
316 if (
"showBountyDetail".equals(action)) {
317 String
id = getMissionId();
318 MemoryAPI memory = memoryMap.get(MemKeys.LOCAL);
319 DifficultyChoice difficulty = (DifficultyChoice) Enum.valueOf(DifficultyChoice.class, memory.getString(
"$" +
id +
"_difficulty"));
322 switch (difficulty) {
337 setCreditRewardApplyRelMult(
showData.baseReward);
339 updateInteractionData(dialog, memoryMap);
341 FireBest.fire(
null, dialog, memoryMap, trigger);
345 if (icon ==
null) icon = getIcon();
347 Set<String> tags =
new LinkedHashSet<String>();
348 tags.add(Tags.INTEL_MISSIONS);
349 Color color = Misc.getBasePlayerColor();
351 if (
showData.system.getCenter() !=
null &&
showData.system.getCenter().getMarket() !=
null) {
352 color =
showData.system.getCenter().getMarket().getTextColorForFactionOrPlanet();
353 }
else if (
showData.system.getCenter() instanceof PlanetAPI) {
354 color = Misc.setAlpha(((PlanetAPI)
showData.system.getCenter()).getSpec().getIconColor(), 255);
355 color = Misc.setBrightness(color, 235);
358 dialog.getVisualPanel().showMapMarker(
showData.system.getCenter(),
359 "Target: " +
showData.system.getNameWithLowercaseTypeShort(), color,
360 true, icon, text, tags);
363 }
else if (
"showBountyAssessment".equals(action) &&
showCreator !=
null) {
369 return super.callAction(action, ruleId, dialog, params, memoryMap);
374 public void accept(InteractionDialogAPI dialog, Map<String, MemoryAPI> memoryMap) {
375 String
id = getMissionId();
376 MemoryAPI memory = memoryMap.get(MemKeys.LOCAL);
377 DifficultyChoice difficulty = (DifficultyChoice) Enum.valueOf(DifficultyChoice.class, memory.getString(
"$" +
id +
"_difficulty"));
378 List<Abortable> abort =
new ArrayList<Abortable>();
379 switch (difficulty) {
383 abort.addAll(
dataNormal.abortWhenOtherVersionAccepted);
384 abort.addAll(
dataHigh.abortWhenOtherVersionAccepted);
389 abort.addAll(
dataLow.abortWhenOtherVersionAccepted);
390 abort.addAll(
dataHigh.abortWhenOtherVersionAccepted);
395 abort.addAll(
dataLow.abortWhenOtherVersionAccepted);
396 abort.addAll(
dataNormal.abortWhenOtherVersionAccepted);
400 for (Abortable curr : abort) {
401 curr.abort(
this,
false);
407 MarketAPI createdAt = getPerson().getMarket();
408 if (createdAt ==
null) createdAt = dialog.getInteractionTarget().getMarket();
415 data.fleet.addEventListener(
this);
416 makeImportant(
data.fleet,
"$" +
id +
"_target", Stage.BOUNTY);
418 if (
data.fleet.isHidden()) {
419 MarketAPI market = Misc.getStationMarket(
data.fleet);
420 if (market !=
null) {
421 SectorEntityToken station = Misc.getStationEntity(market,
data.fleet);
422 if (station !=
null) {
423 makeImportant(station,
"$" +
id +
"_target", Stage.BOUNTY);
428 if (!
data.fleet.getFaction().isNeutralFaction()) {
429 addTag(
data.fleet.getFaction().getId());
436 setCreditRewardApplyRelMult(
data.baseReward);
437 setRepRewardPerson(
data.repPerson);
438 setRepRewardFaction(
data.repFaction);
440 super.accept(dialog, memoryMap);
445 public void acceptImpl(InteractionDialogAPI dialog, Map<String, MemoryAPI> memoryMap) {
455 Color h = Misc.getHighlightColor();
456 if (currentStage == Stage.BOUNTY) {
457 if (currentStage == Stage.BOUNTY) {
466 Color h = Misc.getHighlightColor();
467 if (currentStage == Stage.BOUNTY) {
468 if (
data.system !=
null) {
480 return super.getMapLocation(map);
485 super.notifyEnding();
490 protected void endSuccessImpl(InteractionDialogAPI dialog, Map<String, MemoryAPI> memoryMap) {
494 d.completedDifficulty.add(
data.difficulty);
496 d.completedDifficulty.remove(0);
501 protected void endFailureImpl(InteractionDialogAPI dialog, Map<String, MemoryAPI> memoryMap) {
505 d.completedDifficulty.add(0);
507 d.completedDifficulty.remove(0);
512 if (isDone() || result !=
null)
return;
515 float distToPlayer = Misc.getDistance(fleet,
Global.
getSector().getPlayerFleet());
516 boolean playerInvolved = battle.isPlayerInvolved() || (fleet.isInCurrentLocation() && distToPlayer < 2000f);
518 if (battle.isInvolved(fleet) && !playerInvolved) {
519 boolean cancelBounty = (fleet.isStationMode() && fleet.getFlagship() ==
null) ||
520 (!fleet.isStationMode() && fleet.getFlagship() !=
null && fleet.getFlagship().getCaptain() !=
target);
522 String
id = getMissionId();
523 getPerson().getMemoryWithoutUpdate().set(
"$" +
id +
"_failed",
true);
535 if (!playerInvolved || !battle.isInvolved(fleet) || battle.onPlayerSide(fleet)) {
539 if (fleet.isStationMode()) {
540 if (fleet.getFlagship() !=
null)
return;
542 if (fleet.getFlagship() !=
null && fleet.getFlagship().getCaptain() ==
target)
return;
545 String
id = getMissionId();
546 getPerson().getMemoryWithoutUpdate().set(
"$" +
id +
"_completed",
true);
551 if (isDone() || result !=
null)
return;
553 if (this.data.fleet == fleet) {
554 String
id = getMissionId();
555 getPerson().getMemoryWithoutUpdate().set(
"$" +
id +
"_failed",
true);
577 String post = super.getPostfixForState();
578 post = post.replaceFirst(
" - ",
"");
579 if (!post.isEmpty()) post =
" (" + post +
")";
582 return super.getPostfixForState();
587 return super.getName();
static SectorAPI getSector()
boolean callAction(String action, String ruleId, InteractionDialogAPI dialog, List< Token > params, Map< String, MemoryAPI > memoryMap)
void createBarGiver(MarketAPI createdAt)
void updateInteractionDataImpl()
CustomBountyCreator creatorLow
void setTestMode(Class c, int difficulty)
CustomBountyData dataHigh
boolean create(MarketAPI createdAt, boolean barEvent)
String getPostfixForState()
String getAggregateDataKey()
void accept(InteractionDialogAPI dialog, Map< String, MemoryAPI > memoryMap)
void endFailureImpl(InteractionDialogAPI dialog, Map< String, MemoryAPI > memoryMap)
List< CustomBountyCreator > getCreators()
SectorEntityToken getMapLocation(SectorMapAPI map)
boolean addNextStepText(TooltipMakerAPI info, Color tc, float pad)
void endSuccessImpl(InteractionDialogAPI dialog, Map< String, MemoryAPI > memoryMap)
void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle)
static int NUM_TO_TRACK_FOR_DIFFICULTY
String getMissionTypeNoun()
void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param)
CustomBountyCreator creator
transient CustomBountyData showData
void addDescriptionForNonEndStage(TooltipMakerAPI info, float width, float height)
int pickDifficulty(DifficultyChoice choice)
CustomBountyCreator creatorHigh
AggregateBountyData getAggregateData()
CustomBountyCreator creatorNormal
transient Integer difficultyOverride
CustomBountyCreator pickCreator(int difficulty, DifficultyChoice choice)
void acceptImpl(InteractionDialogAPI dialog, Map< String, MemoryAPI > memoryMap)
transient CustomBountyCreator showCreator
CustomBountyData dataNormal
transient Class creatorOverride
static int getThresholdNotHigh(Class c)
static int getThresholdNotNormal(Class c)
void addIntelAssessment(TextPanelAPI text, HubMissionWithBarEvent mission, CustomBountyData data)
void updateInteractionData(HubMissionWithBarEvent mission, CustomBountyData data)
void notifyFailed(HubMissionWithBarEvent mission, CustomBountyData data)
void addTargetLocationAndDescriptionBulletPoint(TooltipMakerAPI info, Color tc, float pad, HubMissionWithBarEvent mission, CustomBountyData data)
void addFleetDescription(TooltipMakerAPI info, float width, float height, HubMissionWithBarEvent mission, CustomBountyData data)
static int MAX_DIFFICULTY
CustomBountyData createBounty(MarketAPI createdAt, HubMissionWithBarEvent mission, int difficulty, Object bountyStage)
void addTargetLocationAndDescription(TooltipMakerAPI info, float width, float height, HubMissionWithBarEvent mission, CustomBountyData data)
void notifyCompleted(HubMissionWithBarEvent mission, CustomBountyData data)
String getBountyNamePostfix(HubMissionWithBarEvent mission, CustomBountyData data)
void notifyAccepted(MarketAPI createdAt, HubMissionWithBarEvent mission, CustomBountyData data)
StarSystemAPI getSystemWithNoTimeLimit(CustomBountyData data)
String getBaseBountyName(HubMissionWithBarEvent mission, CustomBountyData data)
static int MIN_DIFFICULTY