Starsector API
Loading...
Searching...
No Matches
BarEventManager.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.intel.bar.events;
2
3import java.util.ArrayList;
4import java.util.HashSet;
5import java.util.LinkedHashMap;
6import java.util.LinkedHashSet;
7import java.util.List;
8import java.util.Set;
9
10import com.fs.starfarer.api.EveryFrameScript;
11import com.fs.starfarer.api.Global;
12import com.fs.starfarer.api.campaign.SectorEntityToken;
13import com.fs.starfarer.api.characters.PersonAPI;
14import com.fs.starfarer.api.impl.campaign.DebugFlags;
15import com.fs.starfarer.api.impl.campaign.intel.bar.PortsideBarData;
16import com.fs.starfarer.api.impl.campaign.intel.bar.PortsideBarEvent;
17import com.fs.starfarer.api.loading.BarEventSpec;
18import com.fs.starfarer.api.util.IntervalUtil;
19import com.fs.starfarer.api.util.Misc;
20import com.fs.starfarer.api.util.TimeoutTracker;
21import com.fs.starfarer.api.util.WeightedRandomPicker;
22
23public class BarEventManager implements EveryFrameScript {
24
25 public static interface GenericBarEventCreator {
26 PortsideBarEvent createBarEvent();
27 float getBarEventFrequencyWeight();
28 float getBarEventActiveDuration();
29 float getBarEventTimeoutDuration();
30 float getBarEventAcceptedTimeoutDuration();
31
32
38 boolean isPriority();
39 //void updateSeed();
40 String getBarEventId();
41 boolean wasAutoAdded();
42 }
43
44
45 public static final String KEY = "$core_genericBarEventManager";
46
47 public static BarEventManager getInstance() {
48 Object test = Global.getSector().getMemoryWithoutUpdate().get(KEY);
49 return (BarEventManager) test;
50 }
51
52 protected List<GenericBarEventCreator> creators = new ArrayList<GenericBarEventCreator>();
53 protected LinkedHashMap<PortsideBarEvent, GenericBarEventCreator> barEventCreators = new LinkedHashMap<PortsideBarEvent, GenericBarEventCreator>();
54
55 protected IntervalUtil tracker = new IntervalUtil(0.4f, 0.6f);
56 protected IntervalUtil tracker2 = new IntervalUtil(20f, 40f);
57 protected TimeoutTracker<PortsideBarEvent> active = new TimeoutTracker<PortsideBarEvent>();
58 protected TimeoutTracker<GenericBarEventCreator> timeout = new TimeoutTracker<GenericBarEventCreator>();
59
60 protected long seed = Misc.genRandomSeed();
61
62 public BarEventManager() {
63 super();
64 Global.getSector().getMemoryWithoutUpdate().set(KEY, this);
66 }
67
68// public long getSeed(SectorEntityToken entity) {
69// //updateSeed();
70// if (entity == null) return seed;
71// return seed + (long) entity.getId().hashCode() * 181783497276652981L;
72// }
73
74 public long getSeed(SectorEntityToken entity, PersonAPI person, String extra) {
75 //updateSeed();
76 long mult = 1;
77 if (entity != null) mult *= (long) entity.getName().hashCode();
78 if (person != null) mult *= (long) person.getNameString().hashCode();
79 if (extra != null) mult *= (long) extra.hashCode();
80
81 return seed + mult * 181783497276652981L;
82 }
83
84 public void updateSeed() {
85 seed = Misc.genRandomSeed();
86 }
87
88
89 protected Object readResolve() {
90 if (timeout == null) {
91 timeout = new TimeoutTracker<GenericBarEventCreator>();
92 }
93 if (tracker2 == null) {
94 tracker2 = new IntervalUtil(20f, 40f);
95 }
96 if (seed == 0) {
97 updateSeed();
98 }
99
101
102 return this;
103 }
104
105
107 List<BarEventSpec> specs = Global.getSettings().getAllBarEventSpecs();
108
109 Set<String> validEvents = new HashSet<String>();
110 Set<String> alreadyHaveCreatorsFor = new HashSet<String>();
111 for (BarEventSpec spec : specs) {
112 validEvents.add(spec.getId());
113 }
114
115 for (GenericBarEventCreator curr : new ArrayList<GenericBarEventCreator>(creators)) {
116 if (!curr.wasAutoAdded()) continue;
117
118 if (!validEvents.contains(curr.getBarEventId())) {
119 creators.remove(curr);
120 timeout.remove(curr);
121 } else {
122 alreadyHaveCreatorsFor.add(curr.getBarEventId());
123 }
124 }
125
126 for (BarEventSpec spec : specs) {
127 if (!alreadyHaveCreatorsFor.contains(spec.getId())) {
128 SpecBarEventCreator curr = new SpecBarEventCreator(spec.getId());
129 curr.setWasAutoAdded(true);
130 creators.add(curr);
131 }
132 }
133 }
134
135
136 public void addEventCreator(GenericBarEventCreator creator) {
137 creators.add(creator);
138 }
139
140 public boolean hasEventCreator(Class<?> clazz) {
141 for (GenericBarEventCreator script : creators) {
142 if (clazz.isInstance(script)) return true;
143 }
144 return false;
145 }
146
147 public List<GenericBarEventCreator> getCreators() {
148 return creators;
149 }
150
151 public TimeoutTracker<PortsideBarEvent> getActive() {
152 return active;
153 }
154
155 public TimeoutTracker<GenericBarEventCreator> getTimeout() {
156 return timeout;
157 }
158
159 public void setTimeout(Class creatorClass, float duration) {
160 for (GenericBarEventCreator curr : creators) {
161 if (curr.getClass().equals(creatorClass)) {
162 timeout.set(curr, duration);
163 break;
164 }
165 }
166 }
167
168
171 GenericBarEventCreator creator = getCreatorFor(event);
172 if (creator != null) {
173 float dur = creator.getBarEventAcceptedTimeoutDuration();
174 dur = Math.max(dur, timeout.getRemaining(creator));
175 timeout.set(creator, dur);
176 active.remove(event);
177 }
178 }
179
180 public GenericBarEventCreator getCreatorFor(PortsideBarEvent event) {
181 return barEventCreators.get(event);
182 }
183
184 public void advance(float amount) {
185 float days = Misc.getDays(amount);
186
187 //timeout.clear();
188
189
190 active.advance(days);
191 timeout.advance(days);
192
193 if (DebugFlags.BAR_DEBUG) {
194 days *= 100f;
195 timeout.clear();
196 }
197
198 tracker.advance(days);
199
200 tracker2.advance(days);
201 if (tracker2.intervalElapsed()) {
202 updateSeed();
203 }
204
205 if (tracker.intervalElapsed()) {
206 for (int i = 0; i < 5; i++) {
207 List<PortsideBarEvent> orphaned = new ArrayList<PortsideBarEvent>(barEventCreators.keySet());
208 for (PortsideBarEvent s : active.getItems()) {
209 orphaned.remove(s);
210 }
211
212 for (PortsideBarEvent event : orphaned) {
213 GenericBarEventCreator creator = barEventCreators.remove(event);
214 if (creator != null) {
215 float dur = creator.getBarEventTimeoutDuration();
216 dur = Math.max(dur, timeout.getRemaining(creator));
217 timeout.set(creator, dur);
218 }
220 }
221
222 float f = Global.getSettings().getFloat("maxTotalBarEventsAsFractionOfEventTypes");
223 float max = Math.round(creators.size() * f);
224
225 if (DebugFlags.BAR_DEBUG) {
226 max = 10000f;
227 }
228
229 if (max < 1) max = 1;
230
231 if (active.getItems().size() >= max) return;
232 if (barEventCreators.size() >= creators.size()) return;
233
234 Set<String> activeCreators = new LinkedHashSet<String>();
235 for (GenericBarEventCreator curr : barEventCreators.values()) {
236 activeCreators.add(curr.getBarEventId());
237 }
238
239 WeightedRandomPicker<GenericBarEventCreator> priority = new WeightedRandomPicker<GenericBarEventCreator>();
240 WeightedRandomPicker<GenericBarEventCreator> picker = new WeightedRandomPicker<GenericBarEventCreator>();
241 for (GenericBarEventCreator curr : creators) {
242 //if (barEventCreators.containsValue(curr)) continue;
243 if (activeCreators.contains(curr.getBarEventId())) continue;
244 if (timeout.contains(curr)) continue;
245
246 if (curr.isPriority()) {
247 priority.add(curr, curr.getBarEventFrequencyWeight());
248 } else {
249 picker.add(curr, curr.getBarEventFrequencyWeight());
250 }
251 }
252
253 GenericBarEventCreator pick = priority.pick();
254 if (pick == null) pick = picker.pick();
255 if (pick == null) return;
256
257 PortsideBarEvent event = pick.createBarEvent();
258 if (event == null) return;
259
260 active.add(event, pick.getBarEventActiveDuration());
261 barEventCreators.put(event, pick);
263 }
264 }
265 }
266
267
268 public boolean isDone() {
269 return false;
270 }
271
272 public boolean runWhilePaused() {
273 return false;
274 }
275
276}
277
278
279
280
281
282
283
static SettingsAPI getSettings()
Definition Global.java:51
static SectorAPI getSector()
Definition Global.java:59
LinkedHashMap< PortsideBarEvent, GenericBarEventCreator > barEventCreators
GenericBarEventCreator getCreatorFor(PortsideBarEvent event)
long getSeed(SectorEntityToken entity, PersonAPI person, String extra)
List< BarEventSpec > getAllBarEventSpecs()