svc_poser.py (32529B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\devtools\script\svc_poser.py 2 import os 3 from math import sqrt 4 import evetypes 5 import blue 6 import triui 7 from carbon.common.script.sys.service import Service 8 from carbon.common.script.sys.serviceConst import SERVICE_RUNNING, SERVICE_START_PENDING, ROLE_WORLDMOD 9 from carbonui import uiconst 10 from carbonui.control.combo import Combo 11 from carbonui.control.singlelineedits.singleLineEditInteger import SingleLineEditInteger 12 from carbonui.primitives.container import Container 13 from carbonui.primitives.line import Line 14 from controltowerresources.data import get_control_tower_resources 15 from eve.client.script.ui.control import eveLabel, eveScroll 16 from carbonui.button.group import ButtonGroup 17 from carbonui.control.buttonIcon import ButtonIcon 18 from carbonui.control.button import Button 19 from eve.client.script.ui.control.entries.checkbox import CheckboxEntry 20 from eve.client.script.ui.control.entries.util import GetFromClass 21 from carbonui.control.window import Window 22 from player_messaging.client.ui_message import prompt_player 23 from eve.client.script.ui.util import utilWindows 24 from eve.client.script.util import eveMisc 25 from eve.common.script.sys import idCheckers 26 from eveexceptions import UserError 27 from player_messaging import IGNORE_TO_TOP 28 Slash = lambda x: sm.RemoteSvc('slash').SlashCmd(x) 29 Progress = lambda title, text, current, total: sm.GetService('loading').ProgressWnd(title, text, current, total) 30 PURPOSE_ONLINE = 1 31 PURPOSE_POWER = 2 32 PURPOSE_CPU = 3 33 PURPOSE_REINFORCED = 4 34 ORIENTATION = 1 35 36 class Structure(): 37 __guid__ = 'poser.Structure' 38 39 def __init__(self, starbase, typeID, options = None): 40 self.starbase = starbase 41 self.typeID = typeID 42 self.itemID = None 43 self.quantity = 1 44 self.name = evetypes.GetName(typeID) 45 self.options = options or {} 46 self.godma = sm.GetService('godma') 47 self.attr = self.godma.GetType(typeID) 48 groupID = evetypes.GetGroupID(typeID) 49 self.isControlTower = groupID == const.groupControlTower 50 self.isWeapon = self.attr.AttributeExists('chargeGroup1') 51 self.isRenameable = groupID in (const.groupMobileLaboratory, const.groupAssemblyArray) 52 53 def Create(self): 54 if not self.itemID: 55 self.itemID = Slash('/createitem %s' % self.typeID) 56 else: 57 raise RuntimeError('Instance of poser.Structure already bound to an item') 58 59 def Position(self, x, y, z): 60 self.x = self.x_ + x 61 self.y = self.y_ + y 62 self.z = self.z_ + z 63 Slash('/tr %s %s %s %s' % (self.itemID, 64 self.x, 65 self.y, 66 self.z)) 67 68 def Anchor(self): 69 try: 70 Slash('/pos anchor %s' % self.itemID) 71 except: 72 raise 73 74 if 'name' in self.options and self.isRenameable: 75 cfg.evelocations.Prime([self.itemID]) 76 sm.GetService('invCache').GetInventoryMgr().SetLabel(self.itemID, self.options['name']) 77 sm.ScatterEvent('OnItemNameChange', self.itemID) 78 79 def Online(self): 80 if 'offline' not in self.options or self.isControlTower: 81 Slash('/pos online %s' % self.itemID) 82 83 def Arm(self): 84 a = self.attr 85 ammo = sm.GetService(SERVICENAME).GetAmmo() 86 if a.AttributeExists('damageMultiplier'): 87 for ammoType in ammo[a.chargeGroup1]: 88 if ammoType.chargeSize == a.chargeSize: 89 break 90 91 else: 92 for ammoType in ammo[a.chargeGroup1]: 93 break 94 95 units = int(a.capacity / ammoType.volume) 96 itemID = Slash('/createitem %s %s' % (ammoType.typeID, units)) 97 inv = sm.GetService('invCache').GetInventoryFromId(self.itemID) 98 inv.Add(itemID, session.shipid, qty=units) 99 100 def GetCapacity(self): 101 if self.isControlTower: 102 ctinv = sm.GetService('invCache').GetInventoryFromId(self.itemID) 103 try: 104 row = ctinv.GetCapacity(const.flagNone) 105 capacity = row.capacity 106 used = row.used 107 except: 108 capacity = sm.GetService('godma').GetType(self.typeID).capacity 109 used = 0.0 110 111 return (capacity, used) 112 raise RuntimeError('this only works on towers') 113 114 def Requirements(self): 115 if self.isControlTower: 116 return (self.attr.cpuOutput, self.attr.powerOutput) 117 else: 118 return (self.attr.cpu, self.attr.power) 119 120 def Distance(self, this): 121 dx = this.x - self.x 122 dy = this.y - self.y 123 dz = this.z - self.z 124 return sqrt(dx * dx + dy * dy + dz * dz) - this.radius 125 126 def MoveTo(self): 127 self.starbase.MoveTo(self) 128 129 def Approach(self): 130 Slash('/tr me %s' % self.itemID) 131 132 def Hug(self): 133 Slash('/tr me pos=%s,%s,%s' % (self.x + 700, self.y, self.z + 700)) 134 135 136 class Starbase(): 137 __guid__ = 'poser.Starbase' 138 139 def MoveTo(self, structure): 140 structure.Approach() 141 distance = 1501 142 i = 600 143 ball = self.bp.GetBall(structure.itemID) 144 while distance > 1500: 145 if not i: 146 raise RuntimeError('Shit happened') 147 i -= 1 148 blue.pyos.synchro.SleepSim(100) 149 distance = structure.Distance(self.ship) - ball.radius 150 151 def Step(self, s = None, a = 0, title = 'Poser - Starbase Assembly<br>Stage %d of %d'): 152 bp = self.bp = sm.GetService('michelle').GetBallpark() 153 if not bp: 154 return 155 ship = self.ship = bp.GetBall(session.shipid) 156 if not ship: 157 return 158 if s is None: 159 Progress(self.title, self.info, 1, 1) 160 return 161 if type(s) == type(0): 162 self.maxsteps = s 163 self.maxamount = a 164 self.step = 0 165 self.title_ = title 166 return 167 self.step += 1 168 if self.maxsteps: 169 self.title = self.title_ % (self.step, self.maxsteps) 170 else: 171 self.title = self.title_ 172 self.info = s 173 self.done = 0 174 self.Update() 175 176 def Update(self, maxamount = 0): 177 if not maxamount: 178 maxamount = self.maxamount 179 Progress(self.title, self.info, self.done * 1000, maxamount * 1000 + 1) 180 self.done += 1 181 182 def ImportFromEnvironment(self): 183 bp = self.bp = sm.GetService('michelle').GetBallpark() 184 if not bp: 185 return 186 ship = self.ship = bp.GetBall(session.shipid) 187 if not ship: 188 return 189 ct = None 190 structs = [] 191 self.Step(0, 16, 'Poser - Starbase Scan') 192 self.Step('Scanning Area...') 193 i = 1 194 for ballID in bp.balls.iterkeys(): 195 blue.pyos.BeNice() 196 i += 1 197 self.Update(i & 15) 198 if ballID: 199 ball = bp.GetBall(ballID) 200 item = bp.GetInvItem(ballID) 201 if ball and item and item.categoryID == const.categoryStarbase: 202 if item.groupID == const.groupControlTower: 203 ct = ballID 204 else: 205 structs.append(ballID) 206 207 if not ct: 208 info = 'No control tower found.' 209 raise UserError('CustomInfo', {'info': info}) 210 structs.insert(0, ct) 211 self.structures = [] 212 ownerID = bp.GetInvItem(ct).ownerID 213 for ballID in structs: 214 item = bp.GetInvItem(ballID) 215 if item.ownerID == ownerID: 216 options = {} 217 ball = bp.GetBall(ballID) 218 if not sm.GetService('pwn').GetStructureState(item)[0] == 'online': 219 options['offline'] = True 220 s = Structure(self, item.typeID, options) 221 s.x = ball.x 222 s.y = ball.y 223 s.z = ball.z 224 s.itemID = ballID 225 if s.isRenameable: 226 cfg.evelocations.Prime([ballID]) 227 name = cfg.evelocations.Get(ballID).name 228 if name != evetypes.GetName(item.typeID): 229 options['name'] = name 230 self.structures.append(s) 231 if s.isControlTower: 232 self.controltower = ct = s 233 s.x_ = int(s.x + 0.5) - int(ct.x + 0.5) 234 s.y_ = int(s.y + 0.5) - int(ct.y + 0.5) 235 s.z_ = int(s.z + 0.5) - int(ct.z + 0.5) 236 237 self.Assemble = self.NoAssemble 238 return self 239 240 def ImportFromFile(self, filename): 241 fh = open(filename, 'r') 242 stuff = fh.read().replace('\r', '').split('\n') 243 fh.close() 244 self.structures = [] 245 self.controltower = None 246 notFound = {} 247 amount = len(stuff) 248 for i in xrange(amount): 249 line = stuff[i] 250 if line.strip() != '': 251 coords, name = line.split('=', 1) 252 coords = coords.strip() 253 name = name.strip() 254 optionsDict = {} 255 if name.find(':') > -1: 256 name, options = name.split(':', 1) 257 name = name.strip() 258 for option in options.split(':'): 259 if '=' in option: 260 k, v = option.split('=', 1) 261 v = v.strip() 262 else: 263 k, v = option, True 264 optionsDict[k.strip().lower()] = v 265 266 x, y, z = coords.split() 267 if name.isdigit(): 268 typeID = name 269 else: 270 typeID = sm.GetService('poser').FindTypeID(name) 271 typeID = int(typeID) 272 if not typeID: 273 notFound[name] = True 274 else: 275 s = Structure(self, typeID, optionsDict) 276 s.x_ = float(x) 277 s.y_ = float(y) 278 s.z_ = float(z) 279 self.structures.append(s) 280 if s.isControlTower: 281 self.controltower = s 282 blue.pyos.BeNice() 283 284 Progress('Poser - Loading', 'Done!', 1, 1) 285 if notFound: 286 prompt_player('The following structures were not found:<br><font color="#FF0000">%s</font><br><br>It is possible these types have been deleted or had their name changed. Edit the .pos file and try again' % '<br>'.join(notFound.keys()), 'Unknown Structures', options=uiconst.OK, icon=triui.WARNING) 287 raise UserError(IGNORE_TO_TOP) 288 return self 289 290 def ExportAsTriText(self): 291 lines = [] 292 for s in self.structures: 293 options = '' 294 for k, v in s.options.iteritems(): 295 if v == True: 296 options += ':' + k 297 else: 298 options += ':%s=%s' % (k, v) 299 300 line = '% 6d % 6d % 6d = %s' % (s.x_, 301 s.y_, 302 s.z_, 303 s.typeID) 304 lines.append(line) 305 306 return '<br>'.join(lines) 307 308 def ExportAsFile(self, filename): 309 crud = self.ExportAsTriText().replace('<br>', '\r\n') 310 fh = open(filename, 'wb') 311 fh.write(crud) 312 fh.close() 313 314 def NoAssemble(self): 315 raise RuntimeError('Cannot Assemble from a live configuration') 316 317 def Assemble(self, stepSelection = {}): 318 bp = self.bp = sm.GetService('michelle').GetBallpark() 319 if not bp: 320 return 321 amount = len(self.structures) 322 self.Step(8, amount) 323 self.Step('Creating structures...') 324 x, y, z = self.ship.x, self.ship.y, self.ship.z 325 for s in self.structures: 326 self.Update() 327 s.Create() 328 329 self.Step('Launching structures...') 330 sm.RemoteSvc('slash').SlashCmd('/tr me offset=32000,0,0') 331 eveMisc.LaunchFromShip(self.structures, session.corpid) 332 blue.pyos.synchro.SleepSim(2000) 333 self.Step('Positioning structures...') 334 for s in self.structures: 335 self.Update() 336 s.Position(x, y, z) 337 338 if stepSelection.get('TowerAnchor', True): 339 self.controltower.Anchor() 340 if stepSelection.get('TowerFuel', True): 341 self.Fuel(1, [PURPOSE_ONLINE]) 342 if stepSelection.get('TowerOnline', True): 343 self.controltower.Online() 344 if stepSelection.get('StructAnchor', True): 345 self.Anchor() 346 if stepSelection.get('StructFuel', True): 347 self.Fuel() 348 if stepSelection.get('StructOnline', True): 349 self.Online() 350 if stepSelection.get('ArmWeapons', True): 351 self.Arm() 352 self.Assemble = self.NoAssemble 353 Progress('Poser - Complete', 'All done!', 1, 1) 354 355 def GetLoad(self): 356 cpu = 0 357 power = 0 358 for s in self.structures: 359 if not s.isControlTower: 360 if 'offline' not in s.options: 361 c, p = s.Requirements() 362 cpu += c 363 power += p 364 365 ccpu, cpower = self.controltower.Requirements() 366 if ccpu: 367 fcpu = float(min(cpu, ccpu)) 368 cpu = fcpu / ccpu 369 else: 370 cpu = 0 371 if cpower: 372 fpower = float(min(power, cpower)) 373 power = fpower / cpower 374 else: 375 power = 0 376 return (cpu, power) 377 378 def GetFuelInfo(self, filter = ()): 379 fcpu, fpower = self.GetLoad() 380 secStatus = sm.GetService('map').securityInfo[session.solarsystemid] 381 factionID = sm.GetService('map').GetItem(session.solarsystemid).factionID 382 fuel = {PURPOSE_ONLINE: [], 383 PURPOSE_POWER: [], 384 PURPOSE_CPU: [], 385 PURPOSE_REINFORCED: [], 386 'all': [], 387 'filter': []} 388 volumePerCycle = {PURPOSE_ONLINE: 0.0, 389 PURPOSE_POWER: 0.0, 390 PURPOSE_CPU: 0.0, 391 PURPOSE_REINFORCED: 0.0, 392 'all': 0.0, 393 'filter': 0.0} 394 395 def _add(r, x, v): 396 fuel[r.purpose].append(x) 397 volumePerCycle[r.purpose] += v 398 fuel['all'].append(x) 399 volumePerCycle['all'] += v 400 if r.purpose in filter: 401 fuel['filter'].append(x) 402 volumePerCycle['filter'] += v 403 404 resources = get_control_tower_resources(self.controltower.typeID) 405 for resource in resources: 406 info = sm.GetService('godma').GetType(resource.resourceTypeID) 407 volume = info.volume 408 if info.groupID == const.groupLease: 409 if secStatus >= resource.minSecurityLevel: 410 if factionID == resource.factionID: 411 _add(resource, (resource.resourceTypeID, 1), volume) 412 continue 413 if resource.purpose == PURPOSE_CPU: 414 factor = fcpu 415 elif resource.purpose == PURPOSE_POWER: 416 factor = fpower 417 else: 418 factor = 1.0 419 qty = int(factor * resource.quantity + 0.5) 420 _add(resource, (resource.resourceTypeID, qty), volume * qty) 421 422 return (volumePerCycle, fuel) 423 424 def Fuel(self, desiredCycles = 2147483647, what = (PURPOSE_ONLINE, PURPOSE_POWER, PURPOSE_CPU)): 425 self.Step('Fueling Control Tower...') 426 ct = self.controltower 427 v, fuel = self.GetFuelInfo(filter=what) 428 if v['filter'] > 0.0: 429 ct.MoveTo() 430 capacity, used = ct.GetCapacity() 431 ctinv = sm.GetService('invCache').GetInventoryFromId(ct.itemID) 432 free = capacity - used 433 cycles = min(int(free / v['filter']), desiredCycles) 434 for typeID, qty in fuel['filter']: 435 if qty: 436 self.Update(len(fuel['filter'])) 437 itemID = Slash('/createitem %s %s' % (typeID, qty * cycles)) 438 ctinv.Add(itemID, session.shipid, flag=const.flagNone) 439 440 self.Step() 441 442 def Anchor(self): 443 self.Step('Anchoring Structures...') 444 for s in self.structures: 445 self.Update() 446 if not s.isControlTower: 447 s.Anchor() 448 449 blue.pyos.synchro.SleepWallclock(1000) 450 self.Step() 451 452 def Online(self): 453 self.Step('Onlining Structures...') 454 for s in self.structures: 455 self.Update() 456 if not s.isControlTower: 457 s.Online() 458 459 self.Step() 460 461 def Arm(self): 462 self.Step('Arming Weapon Batteries...') 463 for s in self.structures: 464 self.Update() 465 if s.isWeapon: 466 s.MoveTo() 467 s.Arm() 468 469 self.Step() 470 471 472 class FuelWindow(Window): 473 __guid__ = 'form.FuelWindow' 474 default_windowID = 'FuelWindow' 475 476 def ApplyAttributes(self, attributes): 477 Window.ApplyAttributes(self, attributes) 478 self.SetCaption('Fuel Starbase') 479 self.SetMinSize([350, 250], 1) 480 self.MakeUnResizeable() 481 y = const.defaultPadding + 10 482 self.cycles_online = SingleLineEditInteger(name='cycles_online', parent=self.sr.main, setvalue=0, minValue=0, maxvalue=99999, left=90, width=100, top=y) 483 self.cycles_cpupow = SingleLineEditInteger(name='cycles_cpupow', parent=self.sr.main, setvalue=0, minValue=0, maxvalue=99999, left=90, width=100, top=y + 40) 484 self.cycles_reinf = SingleLineEditInteger(name='cycles_reinf', parent=self.sr.main, setvalue=0, minValue=0, maxvalue=99999, left=90, width=100, top=y + 80) 485 eveLabel.Label(text='Add number of cycles fuel for...', parent=self.sr.main, width=400, left=const.defaultPadding, top=y - 12, fontsize=9, letterspace=2, uppercase=1, state=uiconst.UI_NORMAL) 486 y += 4 487 eveLabel.Label(text='Online:', parent=self.sr.main, width=100, left=2 * const.defaultPadding, top=y, fontsize=9, letterspace=2, uppercase=1, state=uiconst.UI_NORMAL) 488 eveLabel.Label(text='CPU/Power:', parent=self.sr.main, width=100, left=2 * const.defaultPadding, top=y + 40, fontsize=9, letterspace=2, uppercase=1, state=uiconst.UI_NORMAL) 489 eveLabel.Label(text='Reinforced:', parent=self.sr.main, width=100, left=2 * const.defaultPadding, top=y + 80, fontsize=9, letterspace=2, uppercase=1, state=uiconst.UI_NORMAL) 490 Button(parent=self.sr.main, label='Auto', pos=(204, 491 y + 5, 492 0, 493 0), func=self.Auto) 494 y += 4 495 Line(parent=self.sr.main, align=uiconst.RELATIVE, color=(1.0, 1.0, 1.0, 0.5), left=194, top=y, width=4, height=1) 496 Line(parent=self.sr.main, align=uiconst.RELATIVE, color=(1.0, 1.0, 1.0, 0.5), left=194, top=y + 40, width=4, height=1) 497 Line(parent=self.sr.main, align=uiconst.RELATIVE, color=(1.0, 1.0, 1.0, 0.5), left=198, top=y, width=1, height=41) 498 Line(parent=self.sr.main, align=uiconst.RELATIVE, color=(1.0, 1.0, 1.0, 0.5), left=199, top=y + 20, width=4, height=1) 499 buttons = [['Fuel', 500 self.Fuel, 501 None, 502 81], ['Cancel', 503 self.Cancel, 504 None, 505 81]] 506 self.sr.main.children.insert(0, ButtonGroup(btns=buttons)) 507 508 def Cancel(self, *args): 509 self.Close() 510 511 def _prep(self): 512 try: 513 s = self.starbase 514 except AttributeError: 515 s = self.starbase = Starbase().ImportFromEnvironment() 516 s.controltower.MoveTo() 517 capacity, used = s.controltower.GetCapacity() 518 self.free = capacity - used 519 self.vol, self.fuel = s.GetFuelInfo(filter=(PURPOSE_ONLINE, PURPOSE_CPU, PURPOSE_POWER)) 520 521 def Auto(self, *args): 522 self._prep() 523 free = self.free - self.cycles_reinf.GetValue() * self.vol[PURPOSE_REINFORCED] 524 cycles = max(int(self.free / self.vol['filter']), 0) 525 self.cycles_online.SetValue(cycles) 526 self.cycles_cpupow.SetValue(cycles) 527 528 def Fuel(self, *args): 529 o = self.cycles_online.GetValue() 530 c = self.cycles_cpupow.GetValue() 531 r = self.cycles_reinf.GetValue() 532 self._prep() 533 self.state = uiconst.UI_HIDDEN 534 x = 0 535 self.starbase.controltower.MoveTo() 536 ctinv = sm.GetService('invCache').GetInventoryFromId(self.starbase.controltower.itemID) 537 for cycles, purpose in [(o, PURPOSE_ONLINE), 538 (c, PURPOSE_CPU), 539 (c, PURPOSE_POWER), 540 (r, PURPOSE_REINFORCED)]: 541 if cycles: 542 Progress('Adding Fuel...', 'Hold on!', x, 4) 543 for fuel in self.fuel[purpose]: 544 if fuel[1]: 545 itemID = Slash('/createitem %s %s' % (fuel[0], cycles * fuel[1])) 546 if fuel[0] != const.typeStrontiumClathrates: 547 ctinv.Add(itemID, session.shipid, flag=const.flagNone) 548 else: 549 ctinv.Add(itemID, session.shipid, flag=const.flagSecondaryStorage) 550 551 x += 1 552 553 Progress('Adding Fuel...', 'Done!', 1, 1) 554 self.Close() 555 556 557 class AssembleWindow(Window): 558 __guid__ = 'form.AssembleWindow' 559 default_windowID = 'AssembleWindow' 560 561 def ApplyAttributes(self, attributes): 562 Window.ApplyAttributes(self, attributes) 563 fileList = attributes.fileList 564 self.selected = fileList[0][0] + '.pos' 565 self.SetCaption('Assemble Starbase') 566 self.MakeUnResizeable() 567 self.SetMinSize([256, 256], 1) 568 guts = Container(parent=self.sr.main, pos=(const.defaultPadding, 569 const.defaultPadding, 570 const.defaultPadding, 571 const.defaultPadding), align=uiconst.TOALL) 572 Combo(label='Select POS file', parent=guts, options=fileList, name='fileselect', select=0, align=uiconst.TOTOP, pos=(0, 20, 0, 0), width=200, callback=self.OnComboChange) 573 scroll = eveScroll.Scroll(parent=guts, padding=(0, 574 const.defaultPadding, 575 0, 576 const.defaultPadding)) 577 scrolllist = [] 578 for cfgname, var, label, group in [['posTowerAnchor', 579 'TowerAnchor', 580 'Anchor Control Tower', 581 None], 582 ['posTowerFuel', 583 'TowerFuel', 584 'Fuel Control Tower (for onlining)', 585 None], 586 ['posTowerOnline', 587 'TowerOnline', 588 'Online Control Tower', 589 None], 590 ['posStructAnchor', 591 'StructAnchor', 592 'Anchor All Structures', 593 None], 594 ['posStructFuel', 595 'StructFuel', 596 'Fuel Control Tower (for structures)', 597 None], 598 ['posStructOnline', 599 'StructOnline', 600 'Online All Structures', 601 None], 602 ['posArmWeapons', 603 'ArmWeapons', 604 'Arm Weapon Batteries', 605 None]]: 606 le = GetFromClass(CheckboxEntry, {'label': label, 607 'checked': True, 608 'cfgname': cfgname, 609 'retval': var, 610 'group': group, 611 'OnChange': self.CheckBoxChange}) 612 scrolllist.append(le) 613 setattr(self, var, True) 614 setattr(self, var + 'LE', le) 615 616 scroll.Load(contentList=scrolllist) 617 buttons = [['Execute', 618 self.Execute, 619 None, 620 81], ['Cancel', 621 self.Cancel, 622 None, 623 81]] 624 self.sr.main.children.insert(0, ButtonGroup(btns=buttons)) 625 626 def Cancel(self, *args): 627 self.Close() 628 629 def Execute(self, *args): 630 INSIDERDIR = sm.GetService('insider').GetInsiderDir() 631 TARGET = os.path.join(INSIDERDIR, self.selected) 632 Starbase().ImportFromFile(TARGET).Assemble(stepSelection=self.__dict__) 633 AssembleWindow.CloseIfOpen() 634 635 def Set(self, state, list): 636 for x in list: 637 le = getattr(self, x + 'LE') 638 p = le.panel 639 if p: 640 p.sr.checkbox.SetChecked(state) 641 le.checked = state 642 643 def CheckBoxChange(self, checkbox, node, *args): 644 name = node.retval 645 setattr(self, name, checkbox.checked) 646 if name == 'TowerAnchor': 647 if not checkbox.checked: 648 self.Set(False, ['TowerFuel', 649 'TowerOnline', 650 'StructAnchor', 651 'StructFuel', 652 'StructOnline', 653 'ArmWeapons']) 654 elif name == 'TowerFuel': 655 if checkbox.checked: 656 self.Set(True, ['TowerAnchor']) 657 else: 658 self.Set(False, ['TowerOnline', 659 'StructAnchor', 660 'StructFuel', 661 'StructOnline', 662 'ArmWeapons']) 663 elif name == 'TowerOnline': 664 if checkbox.checked: 665 self.Set(True, ['TowerAnchor', 'TowerFuel']) 666 else: 667 self.Set(False, ['StructAnchor', 668 'StructFuel', 669 'StructOnline', 670 'ArmWeapons']) 671 elif name == 'StructAnchor': 672 if checkbox.checked: 673 self.Set(True, ['TowerAnchor', 'TowerFuel', 'TowerOnline']) 674 else: 675 self.Set(False, ['StructFuel', 'StructOnline', 'ArmWeapons']) 676 elif name == 'StructFuel': 677 if checkbox.checked: 678 self.Set(True, ['TowerAnchor', 679 'TowerFuel', 680 'TowerOnline', 681 'StructAnchor']) 682 else: 683 self.Set(False, ['StructOnline', 'ArmWeapons']) 684 elif name == 'StructOnline': 685 if checkbox.checked: 686 self.Set(True, ['TowerAnchor', 687 'TowerFuel', 688 'TowerOnline', 689 'StructAnchor', 690 'StructFuel']) 691 else: 692 self.Set(False, ['ArmWeapons']) 693 elif name == 'ArmWeapons': 694 if checkbox.checked: 695 self.Set(True, ['TowerAnchor', 696 'TowerFuel', 697 'TowerOnline', 698 'StructAnchor', 699 'StructFuel', 700 'StructOnline']) 701 702 def OnComboChange(self, combo, header, value, *args): 703 self.selected = header + '.pos' 704 705 706 SERVICENAME = 'poser' 707 708 class PoserService(Service): 709 __module__ = __name__ 710 __doc__ = 'Ultimate starbase setup tool' 711 __exportedcalls__ = {'Show': []} 712 __notifyevents__ = ['ProcessRestartUI'] 713 __dependencies__ = [] 714 __guid__ = 'svc.poser' 715 __servicename__ = SERVICENAME 716 __displayname__ = SERVICENAME.capitalize() 717 718 def Run(self, *args): 719 self.wnd = None 720 self.state = SERVICE_START_PENDING 721 godma = sm.GetService('godma') 722 self.structureTypeID = {} 723 self.ammo = {} 724 for typeID in evetypes.Iterate(): 725 categoryID = evetypes.GetCategoryID(typeID) 726 if categoryID == const.categoryStarbase: 727 self.structureTypeID[evetypes.GetName(typeID).lower().replace(' ', '')] = typeID 728 elif categoryID == const.categoryCharge: 729 groupID = evetypes.GetGroupID(typeID) 730 if groupID in self.ammo: 731 self.ammo[groupID].append(godma.GetType(typeID)) 732 else: 733 self.ammo[groupID] = [godma.GetType(typeID)] 734 735 blue.pyos.BeNice() 736 self.state = SERVICE_RUNNING 737 738 def RoleCheck(self, *roleSets): 739 for roleNames in roleSets: 740 flags = 0 741 for roleName in roleNames: 742 flags += globals()[roleName] 743 744 if session.role & flags == flags: 745 return True 746 747 summary = [] 748 for roleNames in roleSets: 749 summary.append('<br>- '.join(roleNames)) 750 751 prompt_player(title='Missing Roles', text='You require the following role(s) to use this function:<br>- %s' % '<br><br>Or the following role(s):<br>- '.join(summary), options=uiconst.OK, icon=uiconst.INFO) 752 753 def FindTypeID(self, name): 754 return self.structureTypeID.get(name.lower().replace(' ', ''), None) 755 756 def GetAmmo(self): 757 return self.ammo 758 759 def Show(self): 760 if self.wnd and not self.wnd.destroyed: 761 self.wnd.Maximize() 762 return 763 764 def MakeButton1(where, x, y, map, size, function, label, hint = None): 765 return ButtonIcon(name=label, parent=where, align=uiconst.TOPLEFT, pos=(x, 766 y, 767 size, 768 size), texturePath=map, iconSize=size, hint=hint, func=function, args=()) 769 770 self.wnd = wnd = Window.Open(windowID=SERVICENAME) 771 wnd._OnClose = self.Hide 772 wnd.sr.main = wnd.GetChild('main') 773 wnd.SetCaption('Poser') 774 x = const.defaultPadding 775 y = const.defaultPadding 776 size = 32 777 labelwidth = 128 778 for icon, label, func in [['res:/UI/Texture/Icons/41_64_2.png', 'Assemble Starbase', self.Assemble], 779 ['res:/UI/Texture/Icons/57_64_14.png', 'Store Starbase', self.Store], 780 ['res:/UI/Texture/Icons/24_64_5.png', 'Fuel Tower - Cycles', self.Fuel], 781 ['res:/UI/Texture/Icons/24_64_5.png', 'Fuel Tower - Full', lambda : sm.GetService('slash').SlashCmd('/pos fuel')], 782 ['res:/UI/Texture/Icons/56_64_2.png', 'Nuke Structures', lambda : sm.GetService('gridutils').NukeStructures()], 783 ['res:/UI/Texture/Icons/58_64_2.png', 'Anchor All', lambda : sm.GetService('slash').SlashCmd('/pos anchor all')], 784 ['res:/UI/Texture/Icons/58_64_15.png', 'Unanchor All', lambda : sm.GetService('slash').SlashCmd('/pos unanchor all')], 785 ['res:/UI/Texture/Icons/41_64_10.png', 'Online All', lambda : sm.GetService('slash').SlashCmd('/pos online all')], 786 ['res:/UI/Texture/Icons/41_64_11.png', 'Offline All', lambda : sm.GetService('slash').SlashCmd('/pos offline all')], 787 ['res:/UI/Texture/Icons/23_64_3.png', 'Reinforce', lambda : sm.GetService('slash').SlashCmd('/pos reinforce all')], 788 ['res:/UI/Texture/Icons/56_64_10.png', 'Interrupt', lambda : sm.GetService('slash').SlashCmd('/pos interrupt all')]]: 789 MakeButton1(wnd.sr.main, x, y, icon, size, func, label, label) 790 if ORIENTATION == 0: 791 eveLabel.Label(text=label, parent=wnd.sr.main, width=200, left=x + size + 6, top=y + size / 2 - 6, color=None, state=uiconst.UI_DISABLED) 792 y += size 793 else: 794 x += size 795 796 if ORIENTATION == 0: 797 width = 40 + const.defaultPadding + size - 1 + labelwidth + const.defaultPadding 798 height = 60 + const.defaultPadding + y + const.defaultPadding 799 else: 800 width = 20 + const.defaultPadding + x - 1 + const.defaultPadding 801 height = 60 + const.defaultPadding + size + const.defaultPadding 802 wnd.SetMinSize([width, height]) 803 wnd.SetFixedWidth(width) 804 wnd.SetFixedHeight(height) 805 wnd.MakeUnResizeable() 806 wnd.Maximize(1) 807 808 def Hide(self, *args): 809 if self.wnd: 810 self.wnd.Close() 811 self.wnd = None 812 813 def ProcessRestartUI(self): 814 if self.wnd: 815 self.Hide() 816 self.Show() 817 818 def Assemble(self, *args): 819 INSIDERDIR = sm.GetService('insider').GetInsiderDir() 820 if idCheckers.IsNPC(session.corpid): 821 info = "You can't be in an NPC corporation and expect to use POS's" 822 raise UserError('CustomInfo', {'info': info}) 823 return 824 if not self.RoleCheck(['ROLE_WORLDMOD']): 825 return 826 fileList = [] 827 if os.path.exists(INSIDERDIR) == False: 828 os.mkdir(INSIDERDIR) 829 else: 830 files = os.listdir(INSIDERDIR) 831 for fileName in files: 832 if fileName[-4:] == '.pos': 833 fileList.append((fileName[:-4], fileName)) 834 835 if not fileList: 836 info = "No '.pos' file found. POSer files must be located in:<br>'%s...'" % INSIDERDIR 837 raise UserError('CustomInfo', {'info': info}) 838 return 839 wnd = AssembleWindow.Open(fileList=fileList) 840 wnd.ShowModal() 841 842 def Store(self, *args): 843 insiderDir = sm.GetService('insider').GetInsiderDir() 844 s = Starbase() 845 s.ImportFromEnvironment() 846 filename = utilWindows.NamePopup(caption='Store Starbase', label='Enter filename:', setvalue='', maxLength=32) 847 if not filename: 848 return 849 filename = os.path.join(insiderDir, filename) 850 if not filename: 851 return 852 if filename[:4].lower() != '.pos': 853 filename += '.pos' 854 s.ExportAsFile(filename) 855 856 def Fuel(self, *args): 857 wnd = FuelWindow.Open() 858 wnd.ShowModal()