001package com.fs.starfarer.api.impl.campaign.intel; 002 003import java.util.ArrayList; 004import java.util.List; 005import java.util.Random; 006 007import com.fs.starfarer.api.EveryFrameScript; 008import com.fs.starfarer.api.Global; 009import com.fs.starfarer.api.impl.campaign.DebugFlags; 010import com.fs.starfarer.api.impl.campaign.intel.bases.LuddicPathBaseManager; 011import com.fs.starfarer.api.impl.campaign.intel.bases.PirateBaseManager; 012import com.fs.starfarer.api.util.IntervalUtil; 013 014public abstract class BaseEventManager implements EveryFrameScript { 015 016 017 protected List<EveryFrameScript> active = new ArrayList<EveryFrameScript>(); 018 protected IntervalUtil tracker; 019 protected IntervalUtil trackerMax; 020 protected int currMax = 0; 021 protected Random randomBase = new Random(); 022 023 public BaseEventManager() { 024 float interval = getBaseInterval(); 025 tracker = new IntervalUtil(interval * 0.75f, interval * 1.25f); 026 027 interval = getUpdateMaxInterval(); 028 trackerMax = new IntervalUtil(interval * 0.75f, interval * 1.25f); 029 updateMax(); 030 readResolve(); 031 } 032 033 protected void updateMax() { 034 int min = getMinConcurrent(); 035 int max = getMaxConcurrent(); 036 037 currMax = min + randomBase.nextInt(max - min + 1); 038 } 039 040 protected Object readResolve() { 041 if (randomBase == null) randomBase = new Random(); 042 return this; 043 } 044 045 protected abstract int getMinConcurrent(); 046 protected abstract int getMaxConcurrent(); 047 protected abstract EveryFrameScript createEvent(); 048 049 050 protected float getUpdateMaxInterval() { 051 return 10f; 052 } 053 protected float getBaseInterval() { 054 return 1f; 055 } 056 057 protected float getIntervalRateMult() { 058 return 1f; 059 } 060 061 protected int getHardLimit() { 062 return Global.getSector().getEconomy().getNumMarkets() * 2; 063 } 064 065 066 067 public void advance(float amount) { 068 float days = Global.getSector().getClock().convertToDays(amount); 069 070// if (this instanceof GenericMissionManager) { 071// CountingMap<String> counts = new CountingMap<String>(); 072// for (EveryFrameScript script : active) { 073// counts.add(script.getClass().getSimpleName()); 074// } 075// System.out.println("-------------------------------"); 076// System.out.println("MAX: " + getCurrMax()); 077// for (String key : counts.keySet()) { 078// System.out.println("" + counts.getCount(key) + " <- " + key); 079// } 080// System.out.println("-------------------------------"); 081// } 082 083 trackerMax.advance(days); 084 if (trackerMax.intervalElapsed()) { 085 int count = getActiveCount(); 086 // if we reduced the count before, wait until the number of active events 087 // drops down to match the reduction before updating currMax again 088 // otherwise, since events can last a while, will usually get closer to max active 089 // despite currMax periodically being low 090 if (count <= currMax || count == 0) { 091 if (randomBase.nextFloat() < 0.05f) { 092 updateMax(); 093 } else { 094 if (randomBase.nextFloat() < 0.5f) { 095 currMax--; 096 } else { 097 currMax++; 098 } 099 100 int min = getMinConcurrent(); 101 int max = getMaxConcurrent(); 102 if (currMax < min) currMax = min; 103 if (currMax > max) currMax = max; 104 } 105 106 int limit = getHardLimit(); 107 if (currMax > limit) currMax = limit; 108 } 109 } 110 111 112 List<EveryFrameScript> remove = new ArrayList<EveryFrameScript>(); 113 for (EveryFrameScript event : active) { 114 event.advance(amount); 115 if (event.isDone()) { 116 remove.add(event); 117 } 118 } 119 active.removeAll(remove); 120 //days *= 1000f; 121 if (Global.getSettings().isDevMode()) { 122 int count = getActiveCount(); 123 if (count <= 0) { 124 days *= 1000f; 125 } 126 } 127 tracker.advance(days * getIntervalRateMult()); 128 if (this instanceof PirateBaseManager && DebugFlags.RAID_DEBUG) { 129 tracker.advance(days * 1000000f); 130 } 131 if (this instanceof LuddicPathBaseManager && DebugFlags.PATHER_BASE_DEBUG) { 132 tracker.advance(days * 1000000f); 133 } 134 if (!tracker.intervalElapsed()) return; 135 136 137// if (this instanceof FactionHostilityManager) { 138// System.out.println("wefwefe"); 139// } 140// if (this instanceof PirateBaseManager) { 141// System.out.println("wefwefwef"); 142// } 143 144 int count = getActiveCount(); 145 146 if (count < currMax) { 147 EveryFrameScript event = createEvent(); 148 addActive(event); 149 } 150 } 151 152 public int getActiveCount() { 153 int count = 0; 154 for (EveryFrameScript s : active) { 155 if (s instanceof BaseIntelPlugin) { 156 BaseIntelPlugin intel = (BaseIntelPlugin) s; 157 if (intel.isEnding()) continue; 158 } 159 count++; 160 } 161 return count; 162 } 163 164 public int getOngoing() { 165 return active.size(); 166 } 167 168 public int getCurrMax() { 169 return currMax; 170 } 171 172 public boolean belowMax() { 173 return getCurrMax() > getOngoing(); 174 } 175 176 public void addActive(EveryFrameScript event) { 177 if (event != null) { 178 active.add(event); 179 } 180 } 181 182 public boolean isDone() { 183 return false; 184 } 185 public boolean runWhilePaused() { 186 return false; 187 } 188 189 public List<EveryFrameScript> getActive() { 190 return active; 191 } 192 193 public IntervalUtil getTracker() { 194 return tracker; 195 } 196 197 198 199} 200 201 202