svc_simulator.py (9537B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\devtools\script\svc_simulator.py 2 from math import sqrt, exp, log 3 import evetypes 4 import blue 5 from carbon.common.script.sys.service import Service 6 from carbon.common.script.util.format import FmtTimeInterval 7 from carbonui import uiconst 8 from carbonui.primitives.container import Container 9 from eve.client.script.ui.control import eveLabel, eveScroll 10 from carbonui.button.group import ButtonGroup, ButtonSizeMode 11 from carbonui.control.window import Window 12 from eve.client.script.ui.control.entries.util import GetFromClass 13 from eve.client.script.ui.comparison.attributeSelectionPanel import AttributeCheckbox 14 from eve.common.lib import appConst as const 15 SERVICENAME = 'capsim' 16 17 class Simulator: 18 19 def __init__(self, mods): 20 self.data = sim = [] 21 for a in mods: 22 duration = getattr(a, 'speed', 0) or a.duration 23 sim.append([a.capacitorNeed, long(duration * 10000), 0]) 24 25 def Reset(self): 26 for x in self.data: 27 x[2] = 0 28 29 def Run(self, capacitorCapacity, rechargeRate): 30 capacitor = capacitorCapacity 31 tauThingy = float(const.dgmTauConstant) * (rechargeRate / 5.0) 32 currentTime = nextTime = 0 33 while capacitor > 0.0 and nextTime < const.DAY: 34 capacitor = (1.0 + (sqrt(capacitor / capacitorCapacity) - 1.0) * exp((currentTime - nextTime) / tauThingy)) ** 2 * capacitorCapacity 35 currentTime = nextTime 36 nextTime = const.DAY 37 for data in self.data: 38 if data[2] == currentTime: 39 data[2] += data[1] 40 capacitor -= data[0] 41 nextTime = min(nextTime, data[2]) 42 43 if capacitor > 0.0: 44 self.duration = const.DAY 45 return const.DAY 46 self.duration = currentTime 47 return currentTime 48 49 50 class SimulatorService(Service): 51 __module__ = __name__ 52 __doc__ = 'Capacitor Simulator' 53 __exportedcalls__ = {'Show': []} 54 __notifyevents__ = ['ProcessRestartUI', 'OnItemChange', 'OnClientReady'] 55 __dependencies__ = [] 56 __guid__ = 'svc.capsim' 57 __servicename__ = SERVICENAME 58 __displayname__ = SERVICENAME.capitalize() 59 60 def Run(self, *args): 61 self.wnd = None 62 self.checked = {} 63 64 def Stop(self, memStream = None): 65 self.Hide() 66 Service.Stop(self, memStream) 67 68 def Show(self): 69 if self.wnd: 70 self.wnd.Maximize() 71 return 72 self.wnd = wnd = Window.Open(windowID='Cap Simulator') 73 wnd._OnClose = self.Hide 74 wnd.SetCaption('Capacitor Simulator') 75 wnd.SetMinSize([256, 384]) 76 main = Container(name='main', parent=wnd.GetChild('main'), pos=(const.defaultPadding, 77 const.defaultPadding, 78 const.defaultPadding, 79 const.defaultPadding)) 80 bottom = Container(name='bottom', parent=main, align=uiconst.TOBOTTOM, height=60) 81 wnd.sr.text = eveLabel.Label(text='<br><br><br><br>', parent=bottom, align=uiconst.TOALL, left=const.defaultPadding, state=uiconst.UI_NORMAL) 82 wnd.sr.scroll = eveScroll.Scroll(name='attributescroll', parent=main) 83 wnd.sr.scroll.sr.id = 'capsim_modulescroll' 84 wnd.sr.scroll.hiliteSorted = 0 85 btns = ButtonGroup(btns=[['Run Simulation', 86 self.Simulate, 87 (), 88 None]], parent=main, idx=0, button_size_mode=ButtonSizeMode.DYNAMIC) 89 self.Load() 90 wnd.Maximize(1) 91 92 def Hide(self, *args): 93 if self.wnd: 94 self.wnd.Close() 95 self.wnd = None 96 97 def ProcessRestartUI(self): 98 if self.wnd: 99 self.Hide() 100 self.Show() 101 102 def Load(self): 103 d = {} 104 dgm = sm.GetService('godma') 105 for item in sm.GetService('invCache').GetInventoryFromId(session.shipid).ListHardwareModules(): 106 a = dgm.GetItem(item.itemID) 107 if (getattr(a, 'speed', 0) or getattr(a, 'duration', 0)) and getattr(a, 'capacitorNeed'): 108 d[item.flagID] = a 109 110 mods = [] 111 for x in (const.flagHiSlot0, const.flagMedSlot0, const.flagLoSlot0): 112 for flag in range(x, x + 8): 113 if flag in d: 114 mods.append(d[flag]) 115 116 self.mods = mods 117 del d 118 scrollList = [] 119 for a in mods: 120 e = GetFromClass(AttributeCheckbox, {'line': 1, 121 'info': a, 122 'label': evetypes.GetGroupNameByGroup(a.groupID), 123 'iconID': a.iconID, 124 'item': a, 125 'text': a.name, 126 'hint': a.name, 127 'cfgname': a.itemID, 128 'checked': self.checked.get(a.itemID, True), 129 'OnChange': self.OnModuleSelectedChanged}) 130 scrollList.append(e) 131 132 if self.wnd: 133 self.wnd.sr.scroll.Load(contentList=scrollList) 134 self.wnd.sr.text.text = 'Sustainable: ???' 135 136 def OnClientReady(self, *args): 137 if self.wnd: 138 self.Load() 139 140 def OnItemChange(self, item, change, location): 141 if item.locationID == session.shipid and change.get(const.ixLocationID, 0) != session.shipid: 142 self.checked[item.itemID] = True 143 self.Load() 144 if item.locationID != session.shipid and change.get(const.ixLocationID, 0) == session.shipid: 145 if item.itemID in self.checked: 146 del self.checked[item.itemID] 147 self.Load() 148 149 def OnModuleSelectedChanged(self, obj): 150 itemID = obj.parent.sr.node.info.itemID 151 self.checked[itemID] = obj.checked 152 153 def Simulate(self): 154 155 def Progress(current, total): 156 sm.GetService('loading').ProgressWnd('Running Simulation', 'Please wait...', current, total) 157 blue.pyos.synchro.Yield() 158 159 dgm = sm.GetService('godma') 160 ship = dgm.GetItem(session.shipid) 161 mods = [ a for a in self.mods if self.checked.get(a.itemID, True) ] 162 Progress(0, 1) 163 sim = Simulator(mods) 164 sim.Run(ship.capacitorCapacity, ship.rechargeRate) 165 duration = sim.duration 166 t = self.wnd.sr.text 167 if sim.duration == const.DAY: 168 colorTag = '<color=0xFF00FF00>' 169 t.text = 'Sustainable: %sIndefinitely</color><br>' % colorTag 170 else: 171 colorTag = '<color=0xFFFF0000>' 172 t.text = 'Sustainable: %s%s</color><br>' % (colorTag, FmtTimeInterval(sim.duration, breakAt='sec')) 173 i = 1 174 if sim.duration < const.DAY: 175 sustainCapacity = ship.capacitorCapacity 176 while sim.duration < const.DAY and i < 32: 177 failCapacity = sustainCapacity 178 sustainCapacity *= 2.0 179 sim.Reset() 180 sim.Run(sustainCapacity, ship.rechargeRate) 181 i += 1 182 183 else: 184 failCapacity = ship.capacitorCapacity 185 while sim.duration == const.DAY and i < 32: 186 sustainCapacity = failCapacity 187 failCapacity /= 2.0 188 sim.Reset() 189 sim.Run(failCapacity, ship.rechargeRate) 190 i += 1 191 192 totalSteps = int(log(sustainCapacity - failCapacity) / log(2) + 1.5) * 2 + 1 193 while sustainCapacity - failCapacity > 1 and i < 32: 194 Progress(min(i, totalSteps / 2 - 1), totalSteps) 195 tryCapacity = (sustainCapacity + failCapacity) / 2.0 196 sim.Reset() 197 sim.Run(tryCapacity, ship.rechargeRate) 198 if sim.duration < const.DAY: 199 failCapacity = tryCapacity 200 else: 201 sustainCapacity = tryCapacity 202 i += 1 203 204 sustainRecharge = ship.rechargeRate / 1000.0 205 t.text = t.text + 'Minimum cap/recharge needed for sustainability:<br>' 206 t.text = t.text + '- %s%.2f cap</color> / %0.2f sec (ratio: %.2f)<br>' % (colorTag, 207 sustainCapacity, 208 sustainRecharge, 209 sustainCapacity / sustainRecharge) 210 Progress(1, 2) 211 sim.duration = duration 212 i = 1 213 if sim.duration < const.DAY: 214 sustainRecharge = ship.rechargeRate 215 while sim.duration < const.DAY and i < 32: 216 failRecharge = sustainRecharge 217 sustainRecharge /= 2.0 218 sim.Reset() 219 sim.Run(ship.capacitorCapacity, sustainRecharge) 220 i += 1 221 222 else: 223 failRecharge = ship.rechargeRate 224 while sim.duration == const.DAY and i < 32: 225 sustainRecharge = failRecharge 226 failRecharge *= 2.0 227 sim.Reset() 228 sim.Run(ship.capacitorCapacity, failRecharge) 229 i += 1 230 231 totalSteps = int(log(failRecharge - sustainRecharge) / log(2) + 0.5) 232 while failRecharge - sustainRecharge > 500 and i < 32: 233 Progress(min(i + totalSteps, totalSteps * 2 - 1), totalSteps * 2) 234 tryRecharge = (sustainRecharge + failRecharge) / 2.0 235 sim.Reset() 236 sim.Run(ship.capacitorCapacity, tryRecharge) 237 if sim.duration < const.DAY: 238 failRecharge = tryRecharge 239 else: 240 sustainRecharge = tryRecharge 241 i += 1 242 243 sustainRecharge = sustainRecharge / 1000.0 244 sustainCapacity = ship.capacitorCapacity 245 t.text = t.text + '- %.2f cap / %s%0.2f</color> sec (ratio: %.2f)<br>' % (sustainCapacity, 246 colorTag, 247 sustainRecharge, 248 sustainCapacity / sustainRecharge) 249 Progress(1, 1) 250 251 252 exports = {}