Starsector API
Loading...
Searching...
No Matches
GenericMissionManager.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.intel;
2
3import java.util.ArrayList;
4import java.util.LinkedHashMap;
5import java.util.LinkedHashSet;
6import java.util.List;
7import java.util.Map;
8import java.util.Set;
9
10import com.fs.starfarer.api.EveryFrameScript;
11import com.fs.starfarer.api.Global;
12import com.fs.starfarer.api.util.CountingMap;
13import com.fs.starfarer.api.util.WeightedRandomPicker;
14
16
17 public static interface GenericMissionCreator {
18 float getMissionFrequencyWeight();
19 EveryFrameScript createMissionIntel();
20 }
21
22
23 public static final String KEY = "$core_genericMissionManager";
24
26 Object test = Global.getSector().getMemoryWithoutUpdate().get(KEY);
27 return (GenericMissionManager) test;
28 }
29
30 protected List<GenericMissionCreator> creators = new ArrayList<GenericMissionCreator>();
31 protected Set<GenericMissionCreator> failed = new LinkedHashSet<GenericMissionCreator>();
32
33 protected Map<EveryFrameScript, GenericMissionCreator> missionCreators = new LinkedHashMap<EveryFrameScript, GenericMissionCreator>();
34
36 super();
37 Global.getSector().getMemoryWithoutUpdate().set(KEY, this);
38 }
39
40 protected Object readResolve() {
41 super.readResolve();
42 if (failed == null) {
43 failed = new LinkedHashSet<GenericMissionCreator>();
44 }
45 return this;
46 }
47
48 public void addMissionCreator(GenericMissionCreator creator) {
49 creators.add(creator);
50 }
51
52 public boolean hasMissionCreator(Class<?> clazz) {
53 for (GenericMissionCreator script : creators) {
54 if (clazz.isInstance(script)) return true;
55 }
56 return false;
57 }
58
59 public List<GenericMissionCreator> getCreators() {
60 return creators;
61 }
62
63 @Override
64 protected int getMinConcurrent() {
65 return Global.getSettings().getInt("minGenericMissions");
66 }
67 @Override
68 protected int getMaxConcurrent() {
69 return Global.getSettings().getInt("maxGenericMissions");
70 }
71
72 @Override
73 protected float getIntervalRateMult() {
74 float approximateMissionPostingDurationDays = 10f;
75 return (float) getCurrMax() / approximateMissionPostingDurationDays;
76 }
77
78 @Override
80 //if ((float) Math.random() < 0.75f) return null;
81
82// if (getActive().size() >= 3) {
83// return null;
84// }
85
86
87 List<EveryFrameScript> orphaned = new ArrayList<EveryFrameScript>(missionCreators.keySet());
88 CountingMap<GenericMissionCreator> current = new CountingMap<GenericMissionCreator>();
89 for (EveryFrameScript s : getActive()) {
90 orphaned.remove(s);
91 GenericMissionCreator c = missionCreators.get(s);
92 if (c != null) {
93 current.add(c);
94 }
95 }
96
97 for (EveryFrameScript s : orphaned) {
98 missionCreators.remove(s);
99 }
100
101
102
103 float totalWeight = 0f;
104 for (GenericMissionCreator c : creators) {
105 totalWeight += c.getMissionFrequencyWeight();
106 }
107
108 WeightedRandomPicker<GenericMissionCreator> picker = new WeightedRandomPicker<GenericMissionCreator>();
109 for (GenericMissionCreator c : creators) {
110 if (failed.contains(c)) continue;
111
112 float currNum = current.getCount(c);
113 if (currNum < 1) currNum = 1;
114
115 float desiredNum = getCurrMax() * c.getMissionFrequencyWeight() / totalWeight;
116 if (desiredNum < 0.1f) desiredNum = 0.1f;
117
118 float deviation = desiredNum * 0.25f;
119 float exponent = (desiredNum - currNum) / deviation;
120 if (exponent > 4) exponent = 4;
121
122 float probMult = (float) Math.pow(10f, exponent);
123 picker.add(c, c.getMissionFrequencyWeight() * probMult);
124 }
125
126 GenericMissionCreator creator = picker.pick();
127 if (creator == null) {
128 failed.clear();
129 return null;
130 }
131
132 EveryFrameScript intel = creator.createMissionIntel();
133 if (intel instanceof BaseIntelPlugin && ((BaseIntelPlugin)intel).isDone()) {
134 intel = null;
135 }
136
137 if (intel != null) {
138// debug stuff: make mission intel visible to player and print some stats when adding a new mission
139// ((BaseIntelPlugin) intel).setPostingLocation(null);
140// String detail = "";
141// for (GenericMissionCreator c : creators) {
142// detail += c.getClass().getSimpleName() + ": " + current.getCount(c) + " | ";
143// }
144// detail = "[" + detail + "]";
145// System.out.println("Added mission by " + creator.getClass().getSimpleName() + ", weight: " + (int)picker.getWeight(creator) + " / " + (int)picker.getTotal() + " " + detail);
146 missionCreators.put(intel, creator);
147 failed.clear();
148 } else {
149 failed.add(creator);
150 }
151
152 return intel;
153 }
154
155}
156
157
158
159
160
161
162
static SettingsAPI getSettings()
Definition Global.java:51
static SectorAPI getSector()
Definition Global.java:59
Map< EveryFrameScript, GenericMissionCreator > missionCreators