dungeoneditor.py (71885B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\inflight\dungeoneditor.py 2 import copy 3 import blue 4 import evecamera 5 import evetypes 6 import localization 7 import trinity 8 import uthread 9 import utillib 10 from carbonui import uiconst 11 from carbonui.control.combo import Combo 12 from carbonui.control.singlelineedits.singleLineEditFloat import SingleLineEditFloat 13 from carbonui.control.singlelineedits.singleLineEditInteger import SingleLineEditInteger 14 from carbonui.control.singlelineedits.singleLineEditText import SingleLineEditText 15 from carbonui.primitives.container import Container 16 from carbonui.primitives.line import Line 17 from eve.client.script.parklife import dungeonHelper, states 18 from carbonui.control.button import Button 19 from carbonui.control.checkbox import Checkbox 20 from eve.client.script.ui.control.entries.generic import Generic 21 from eve.client.script.ui.control.entries.util import GetFromClass 22 from carbonui.control.window import Window 23 from eve.client.script.ui.control.listgroup import ListGroup 24 from player_messaging.client.ui_message import message_player, prompt_player_fsd_dialog 25 from carbonui.control.tabGroup import TabGroup 26 from eve.client.script.ui.util import uix 27 from eve.common.lib import appConst as const 28 from evecamera.dungeonhack import DungeonHack 29 from ballparkCommon.ballRadius import ComputeRadiusFromQuantity 30 from eve.client.script.ui.control import eveIcon, eveLabel, eveScroll 31 from carbonui.uicore import uicore 32 from eveservices.menu import GetMenuService 33 pi = 3.141592653589793 34 35 def GetMessageFromLocalization(messageID): 36 return localization.GetByMessageID(messageID) 37 38 39 class DungeonEditor(Window): 40 __guid__ = 'form.DungeonEditor' 41 __nonpersistvars__ = [] 42 __notifyevents__ = ['OnJessicaOpenDungeon', 43 'OnJessicaOpenRoom', 44 'OnDESelectionChanged', 45 'OnDEObjectPaletteChanged', 46 'OnDEObjectListChanged', 47 'OnSelectObject', 48 'OnDungeonEdit', 49 'OnDungeonSelectionGroupRotation', 50 'OnStateChange'] 51 default_windowID = 'dungeoneditor' 52 53 def ApplyAttributes(self, attributes): 54 Window.ApplyAttributes(self, attributes) 55 self._navigation = DungeonHack() 56 self.loadedTab = None 57 self.roomTabSelected = 'Objects' 58 self.loadingThread = None 59 self.scope = uiconst.SCOPE_INFLIGHT 60 self.SetCaption('Dungeon Editor') 61 self.LoadPanels() 62 self.SetMinSize([350, 400]) 63 self.prevDungeonResults = None 64 self.prevFactionID = None 65 self.prevArchetypeID = None 66 self.filterText = '' 67 self.objectGroups = {} 68 self.groupNameToIDMap = {} 69 self.scenario = sm.GetService('scenario') 70 if dungeonHelper.IsJessicaOpen(): 71 self.cache = sm.GetService('cache') 72 else: 73 self.cache = sm.RemoteSvc('cache') 74 sm.GetService('sceneManager').SetPrimaryCamera(evecamera.CAM_TACTICAL) 75 76 def LoadPanels(self): 77 panel = Container(name='panel', parent=self.sr.main, left=const.defaultPadding, top=const.defaultPadding, width=const.defaultPadding, height=const.defaultPadding) 78 self.sr.panel = panel 79 self.sr.roomobjecttabs = TabGroup(name='tabparent', parent=self.sr.main, idx=0, tabs=[['Objects', 80 panel, 81 self, 82 'RoomObjectTab'], ['Groups', 83 panel, 84 self, 85 'RoomGroupTab']], groupID='roomobjectstab') 86 self.sr.maintabs = TabGroup(name='tabparent', parent=self.sr.main, idx=0, tabs=[['Dungeons', 87 panel, 88 self, 89 'DungeonTab'], 90 ['Room objects', 91 panel, 92 self, 93 'RoomTab'], 94 ['Transform', 95 panel, 96 self, 97 'AlignTab'], 98 ['Settings', 99 panel, 100 self, 101 'SettingTab'], 102 ['Palette', 103 panel, 104 self, 105 'PaletteTab']], groupID='tabgroupid') 106 107 def Load(self, tabid): 108 if self.loadingThread and self.loadingThread.alive: 109 self.loadingThread.kill() 110 self.UnloadPanel() 111 self.loadedTab = None 112 tabName = 'Load_%s' % tabid 113 if hasattr(self, tabName): 114 if tabName in ('Load_RoomTab', 'Load_RoomObjectTab', 'Load_RoomGroupTab'): 115 self.sr.roomobjecttabs.display = True 116 else: 117 self.sr.roomobjecttabs.display = False 118 self.loadedTab = tabid 119 self.loadingThread = uthread.new(getattr(self, tabName)) 120 self.loadingThread.context = 'DungeonEditor::%s' % tabName 121 122 def UpdateGridVisibility(self): 123 if self.loadedTab == 'PaletteTab': 124 self._navigation.SetGridState(True) 125 self._navigation.SetDrawAxis(True) 126 else: 127 showGrid = self.gridCheckbox.GetValue() 128 self._navigation.SetGridState(showGrid) 129 self._navigation.SetDrawAxis(showGrid) 130 self._navigation.SetGridSpacing(self.gridSpacingDropdown.GetValue()) 131 self._navigation.SetGridLength(self.gridSizeDropdown.GetValue()) 132 133 def IsTabLoaded(self, tabId): 134 return tabId == self.loadedTab 135 136 def Refresh(self): 137 self.Load(self.loadedTab) 138 139 def UnloadPanel(self): 140 self.sr.panel.Flush() 141 self.sr.palettescroll = None 142 self.sr.templatescroll = None 143 144 def _GetDungeons(self): 145 archetypeID = settings.user.ui.Get('dungeonArchetypeID', None) 146 factionID = settings.user.ui.Get('dungeonFactionID', None) 147 if self.prevDungeonResults is None or self.prevArchetypeID != archetypeID or self.prevFactionID != factionID: 148 comboOptions = [] 149 dungeons = sm.RemoteSvc('dungeon').DEGetDungeons(archetypeID=archetypeID, factionID=factionID) 150 for dungeon in dungeons: 151 factionID = dungeon.factionID 152 if dungeon.dungeonNameID is not None: 153 name = GetMessageFromLocalization(dungeon.dungeonNameID) 154 else: 155 name = '' 156 if factionID: 157 factionName = cfg.eveowners.Get(factionID).name 158 name = '%s (%s) [%d]' % (name, factionName, dungeon.dungeonID) 159 else: 160 name = '%s [%d]' % (name, dungeon.dungeonID) 161 comboOptions.append((name, dungeon.dungeonID)) 162 163 comboOptions.sort() 164 comboOptions.insert(0, [' - Select Dungeon - ', None]) 165 self.prevArchetypeID = archetypeID 166 self.prevFactionID = factionID 167 self.prevDungeonResults = comboOptions 168 comboOptions = self.prevDungeonResults 169 filterText = self.filterText.lower() 170 optionsFilter = lambda option: filterText in option[0].lower() 171 comboOptions = filter(optionsFilter, comboOptions) 172 availableDungeons = map(lambda option: option[1], comboOptions) 173 return (comboOptions, availableDungeons) 174 175 def _CreateCombo(self, comboOptions, comboID): 176 comboSetval = settings.user.ui.Get(comboID, None) 177 if comboSetval == 'All': 178 settings.user.ui.Set(comboID, None) 179 comboSetval = None 180 return Combo(parent=self.sr.panel, label='', options=comboOptions, name=comboID, select=comboSetval, callback=self.OnComboChange, align=uiconst.TOTOP) 181 182 def OnFilterDungeon(self, *args): 183 self.filterText = self.dungeonFilter.GetValue() 184 self.sr.maintabs.ReloadVisible() 185 186 def OnGodMode(self, *args): 187 settings.user.ui.Set('dungeonGodMode', self.godModeCheckbox.GetValue()) 188 189 def Load_DungeonTab(self): 190 eveLabel.EveLabelMedium(text='Search Dungeons:', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 191 Line(parent=self.sr.panel, align=uiconst.TOTOP) 192 Container(name='push', parent=self.sr.panel, align=uiconst.TOTOP, height=const.defaultPadding) 193 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=20) 194 sb = Button(parent=row, label='Search', func=self.OnFilterDungeon, align=uiconst.CENTERRIGHT, left=2) 195 self.dungeonFilter = SingleLineEditText(name='dungeonFilter', parent=row, setvalue=self.filterText, align=uiconst.TOALL, padRight=sb.width + 4, OnReturn=self.OnFilterDungeon) 196 Container(name='push', parent=self.sr.panel, align=uiconst.TOTOP, height=const.defaultPadding) 197 eveLabel.EveLabelMedium(text='Optional Filters:', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 198 Line(parent=self.sr.panel, align=uiconst.TOTOP) 199 Container(name='push', parent=self.sr.panel, align=uiconst.TOTOP, height=const.defaultPadding) 200 eveLabel.EveLabelMedium(text='Archetype:', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 201 archetypeOptions = sm.RemoteSvc('dungeon').DEGetArchetypes() 202 archetypeOptions.sort() 203 archetypeOptions.insert(0, ('All', None)) 204 self._CreateCombo(archetypeOptions, 'dungeonArchetypeID') 205 Container(name='push', parent=self.sr.panel, align=uiconst.TOTOP, height=const.defaultPadding) 206 eveLabel.EveLabelMedium(text='Faction:', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 207 factions = sm.RemoteSvc('dungeon').DEGetFactions() 208 factionOptions = [ (cfg.eveowners.Get(factionID).name, factionID) for factionID in factions ] 209 factionOptions.sort() 210 factionOptions.insert(0, ('All', None)) 211 self._CreateCombo(factionOptions, 'dungeonFactionID') 212 Container(name='pusher', align=uiconst.TOTOP, height=24, parent=self.sr.panel) 213 eveLabel.EveLabelMedium(text='Select Dungeon:', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 214 Line(parent=self.sr.panel, align=uiconst.TOTOP) 215 Container(name='push', parent=self.sr.panel, align=uiconst.TOTOP, height=const.defaultPadding) 216 comboOptions, availableDungeons = self._GetDungeons() 217 comboID = 'dungeonDungeon' 218 dungeonID = settings.user.ui.Get(comboID, 'All') 219 Combo(parent=self.sr.panel, label='', options=comboOptions, name=comboID, select=dungeonID, callback=self.OnComboChange, align=uiconst.TOTOP) 220 Container(name='pusher', align=uiconst.TOTOP, height=16, parent=self.sr.panel) 221 eveLabel.EveLabelMedium(text='Select Room:', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 222 Line(parent=self.sr.panel, align=uiconst.TOTOP) 223 if dungeonID not in availableDungeons: 224 Container(name='push', parent=self.sr.panel, align=uiconst.TOTOP, height=const.defaultPadding * 2) 225 eveLabel.EveLabelMedium(text=' - No dungeon selected - ', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 226 return 227 seldungeon = sm.RemoteSvc('dungeon').DEGetDungeons(dungeonID=dungeonID)[0] 228 eveLabel.EveLabelMedium(text=GetMessageFromLocalization(seldungeon.dungeonNameID) + ' - Version ', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 229 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOBOTTOM, height=16, padTop=4) 230 godMode = settings.user.ui.Get('dungeonGodMode', 1) 231 self.godModeCheckbox = Checkbox(text='God Mode', parent=row, settingsKey='dungeonGodMode', checked=godMode, callback=self.OnGodMode) 232 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOBOTTOM, height=16, padTop=4) 233 Button(parent=row, label='Play Dungeon', func=self.PlayDungeon, align=uiconst.TOLEFT, padLeft=4) 234 Button(parent=row, label='Go to selected room', func=self.GotoRoom, args=(), align=uiconst.TOLEFT, padLeft=4) 235 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOBOTTOM, height=16) 236 Button(parent=row, label='Edit Room', func=self.EditRoom, align=uiconst.TOLEFT, padLeft=4) 237 Button(parent=row, label='Save Room', func=self.SaveRoom, align=uiconst.TOLEFT, padLeft=4) 238 Button(parent=row, label='Reset', func=self.ResetDungeon, args=(), align=uiconst.TORIGHT, padLeft=4) 239 Container(name='push', parent=self.sr.panel, align=uiconst.TOBOTTOM, height=const.defaultPadding) 240 rooms = sm.RemoteSvc('dungeon').DEGetRooms(dungeonID=seldungeon.dungeonID) 241 Container(name='push', parent=self.sr.panel, align=uiconst.TOTOP, height=const.defaultPadding) 242 self.scrollOptions = [] 243 for i, (roomID, roomName) in enumerate(rooms): 244 self.scrollOptions.append(GetFromClass(Generic, {'label': '[%d] %s' % (roomID, roomName), 245 'id': i + 1, 246 'roomID': roomID, 247 'OnClick': self.OnGotoSelectedRoomClicked})) 248 249 self.sr.objscrollbox = eveScroll.Scroll(parent=self.sr.panel, name='scrollID') 250 self.sr.objscrollbox.LoadContent(contentList=self.scrollOptions) 251 if settings.user.ui.Get('selectedRoomID', None): 252 rooms = self.sr.objscrollbox.GetNodes() 253 for room in rooms: 254 if room.roomID == settings.user.ui.Get('selectedRoomID', None): 255 self.sr.objscrollbox.SelectNode(room) 256 break 257 258 def OnJessicaOpenDungeon(self, dungeonID, defaultRoomID = None): 259 self.OnJessicaOpenRoom(dungeonID, defaultRoomID) 260 261 def OnJessicaOpenRoom(self, dungeonID, roomID): 262 settings.user.ui.Set('dungeonDungeon', dungeonID) 263 self.loadedTab = 'DungeonTab' 264 for tab in self.sr.maintabs.sr.tabs: 265 if tab.sr.args == self.loadedTab: 266 tab.Select() 267 268 settings.user.ui.Set('selectedRoomID', roomID) 269 if roomID: 270 self.EditRoom() 271 272 def ResetDungeon(self): 273 sm.GetService('scenario').ResetDungeon() 274 275 def PlayDungeon(self, *args): 276 dungeonID = settings.user.ui.Get('dungeonDungeon', None) 277 if dungeonID is None or dungeonID == 'All': 278 return 279 roomID = settings.user.ui.Get('selectedRoomID', None) 280 if not roomID: 281 objectList = self.sr.objscrollbox.GetNodes() 282 if len(objectList) > 0: 283 roomID = objectList[0].roomID 284 else: 285 return 286 godMode = settings.user.ui.Get('dungeonGodMode', 1) 287 sm.GetService('scenario').PlayDungeon(dungeonID, roomID, godmode=godMode) 288 289 def EditRoom(self, *args): 290 dungeonID = settings.user.ui.Get('dungeonDungeon', None) 291 if dungeonID is None or dungeonID == 'All': 292 return 293 if not settings.user.ui.Get('selectedRoomID', None): 294 objectList = self.sr.objscrollbox.GetNodes() 295 if len(objectList) > 0: 296 settings.user.ui.Set('selectedRoomID', objectList[0].roomID) 297 else: 298 return 299 sm.GetService('scenario').EditRoom(dungeonID, settings.user.ui.Get('selectedRoomID', None)) 300 301 def SaveRoom(self, *args): 302 sm.StartService('scenario').SaveAllChanges() 303 304 def GotoRoom(self, *args): 305 roomID = settings.user.ui.Get('selectedRoomID', None) 306 if roomID: 307 sm.GetService('scenario').GotoRoom(roomID) 308 309 def OnDungeonEdit(self, dungeonID, roomID, roomPos): 310 self.InitializeSelectionGroups(roomID) 311 312 def InitializeSelectionGroups(self, roomID): 313 scenario = sm.StartService('scenario') 314 self.objectGroups = {} 315 self.groupNameToIDMap = {} 316 scenario.RemoveAllHardGroups() 317 318 def GetCurrentRoomID(self): 319 return sm.RemoteSvc('keeper').GetLevelEditor().GetCurrentlyEditedRoomID() 320 321 def Load_RoomTab(self): 322 dunObjs = self.scenario.GetDunObjects() 323 if len(dunObjs) == 0: 324 Container(name='push', parent=self.sr.panel, align=uiconst.TOTOP, height=28) 325 eveLabel.EveLabelMedium(text='No dungeon objects found', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 326 return 327 if hasattr(self, 'Load_%sTab' % self.roomTabSelected): 328 getattr(self, 'Load_%sTab' % self.roomTabSelected)() 329 self.loadedTab = 'RoomTab' 330 331 def Load_RoomObjectTab(self): 332 self.roomTabSelected = 'Objects' 333 self.Load_RoomTab() 334 335 def Load_RoomGroupTab(self): 336 self.roomTabSelected = 'Groups' 337 self.Load_RoomTab() 338 339 def Load_ObjectsTab(self): 340 self.roomTabSelected = 'Objects' 341 dunObjs = sm.GetService('scenario').GetDunObjects() 342 scrollOptions = [] 343 boxItems = [] 344 for slimItem in dunObjs: 345 if getattr(slimItem, 'dunObjectID', None) is not None: 346 typeName = evetypes.GetName(slimItem.typeID) 347 objName = cfg.evelocations.Get(slimItem.itemID).name 348 entryName = typeName + ' : ' + objName 349 boxItems.append([entryName, 350 slimItem.dunObjectID, 351 sm.GetService('scenario').IsSelectedByObjID(slimItem.dunObjectID), 352 slimItem.itemID, 353 slimItem.typeID]) 354 355 boxItems.sort() 356 for objName, objID, selected, itemID, typeID in boxItems: 357 scrollOptions.append(GetFromClass(Generic, {'label': objName, 358 'id': objID, 359 'itemID': itemID, 360 'typeID': typeID, 361 'OnClick': self.OnObjectClicked, 362 'isSelected': selected, 363 'GetMenu': self.GetItemMenu})) 364 365 self.sr.objscrollbox = eveScroll.Scroll(parent=self.sr.panel, name='scrollID', align=uiconst.TOTOP, height=256) 366 self.sr.objscrollbox.LoadContent(contentList=scrollOptions) 367 Container(name='push', parent=self.sr.panel, align=uiconst.TOTOP, height=16) 368 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=20) 369 Button(parent=row, label='Select All', func=self.ObjSelectAll, args=(), align=uiconst.TOLEFT, padLeft=4) 370 Button(parent=row, label='Invert selection', func=self.ObjInverseSel, args=(), align=uiconst.TOLEFT, padLeft=4) 371 Button(parent=row, label='Clear selection', func=self.ObjClearSel, args=(), align=uiconst.TOLEFT, padLeft=4) 372 Container(name='push', parent=self.sr.panel, align=uiconst.TOTOP, height=16) 373 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 374 Line(parent=self.sr.panel, align=uiconst.TOTOP) 375 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 376 eveLabel.EveLabelMedium(text='Duplicate: ', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 377 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=16) 378 counter = 0 379 for each in 'XYZ': 380 checkbox1ID = 'duplicateOffset%s' % each 381 curVal = 0 382 eveLabel.EveLabelMedium(text=each, parent=row, left=50 + counter * 52, state=uiconst.UI_NORMAL) 383 ed = SingleLineEditInteger(name='duplicateOffset%s' % each, parent=row, setvalue=curVal, pos=(60 + counter * 52, 384 0, 385 38, 386 0), minValue=-30000, maxValue=30000) 387 counter = counter + 1 388 setattr(self, checkbox1ID, ed) 389 390 eveLabel.EveLabelMedium(text='Offset: ', parent=row, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 391 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=16) 392 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=32) 393 self.duplicateAmount = SingleLineEditInteger(name='duplicateAmount', parent=row, setvalue=1, pos=(60, 0, 38, 0), minValue=1, maxValue=100) 394 eveLabel.EveLabelMedium(text='Amount: ', parent=row, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 395 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 396 Line(parent=self.sr.panel, align=uiconst.TOTOP) 397 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 398 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 399 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=20) 400 Button(parent=row, label='Delete selected', func=self.OnDeleteSelected, args=(), align=uiconst.TORIGHT, padLeft=4) 401 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=20, padTop=4) 402 Button(parent=row, label='Save Room', func=self.SaveRoom, align=uiconst.TOLEFT, padLeft=4) 403 404 def Load_GroupsTab(self): 405 self.roomTabSelected = 'Groups' 406 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 407 dunObjs = sm.GetService('scenario').GetDunObjects() 408 scrollOptions = [] 409 selectedGroups = self.GetSelectedGroups() 410 groups = self.objectGroups.items() 411 groups.sort() 412 boxItems = [ [index, 413 groupName, 414 groupItems, 415 groupName in selectedGroups] for index, (groupName, groupItems) in enumerate(groups) ] 416 for index, groupName, groupItems, selected in boxItems: 417 scrollOptions.append(GetFromClass(ObjectGroupListEntry, {'label': groupName, 418 'id': index, 419 'groupItems': groupItems, 420 'OnClick': self.OnObjectGroupClicked, 421 'isSelected': selected, 422 'locked': False, 423 'form': self})) 424 425 self.sr.objgroupscrollbox = eveScroll.Scroll(parent=self.sr.panel, name='scrollID', align=uiconst.TOTOP, height=256) 426 self.sr.objgroupscrollbox.LoadContent(contentList=scrollOptions) 427 Container(name='push', parent=self.sr.panel, align=uiconst.TOTOP, height=16) 428 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=16) 429 Button(parent=row, label='Rename Group', func=self.OnRenameGroup, args=(), align=uiconst.TOLEFT) 430 Button(parent=row, label='Remove Group', func=self.OnRemoveGroup, args=(), align=uiconst.TOLEFT) 431 Button(parent=row, label='Delete Group Objects', func=self.OnDeleteSelectedGroup, args=(), align=uiconst.TOLEFT) 432 433 def GetItemMenu(self, entry): 434 info = entry.sr.node 435 m = GetMenuService().GetMenuFromItemIDTypeID(info.itemID, info.typeID) 436 return m 437 438 def OnStateChange(self, itemID, flag, flagState, *args): 439 if flag == states.selected and flagState: 440 dunObjectID = sm.GetService('michelle').GetItem(itemID).dunObjectID 441 if dunObjectID: 442 sm.GetService('scenario').SetSelectionByID([dunObjectID]) 443 444 def OnObjectClicked(self, entry, *args): 445 uicore.cmd.ExecuteCombatCommand(entry.sr.node.itemID, uiconst.UI_CLICK) 446 if self.sr.objscrollbox: 447 ids = self.GetCurrentlySelectedObjects() 448 sm.StartService('scenario').SetSelectionByID(ids) 449 450 def OnObjectGroupClicked(self, entry, *args): 451 self.SelectObjectGroup(entry.sr.node.label) 452 453 def IsGroupSelected(self, groupName): 454 return self.scenario.AreAllSelected(self.objectGroups[groupName]) 455 456 def GetSelectedGroups(self): 457 return filter(self.IsGroupSelected, self.objectGroups.iterkeys()) 458 459 def SelectObjectGroup(self, label): 460 if label not in self.objectGroups: 461 return 462 scenarioSvc = sm.StartService('scenario') 463 selectedGroup = self.objectGroups[label] 464 ids = [] 465 dungeonObjects = scenarioSvc.GetDunObjects() 466 for slimItem in selectedGroup: 467 if slimItem.dunObjectID in [ dungeonObject.dunObjectID for dungeonObject in dungeonObjects ]: 468 ids.append(slimItem.dunObjectID) 469 470 for node in self.sr.objgroupscrollbox.GetNodes(): 471 if node.panel.sr.label.text == label: 472 self.sr.objgroupscrollbox.SelectNode(node) 473 scenarioSvc.SetSelectionByID(ids) 474 scenarioSvc.SetActiveHardGroup(label) 475 476 def ObjSelectAll(self): 477 dunObjs = sm.GetService('scenario').GetDunObjects() 478 selItems = [] 479 for slimItem in dunObjs: 480 selItems.append(slimItem.dunObjectID) 481 482 sm.GetService('scenario').SetSelectionByID(selItems) 483 if self.IsTabLoaded('RoomTab'): 484 self.Refresh() 485 486 def ObjClearSel(self): 487 sm.GetService('scenario').SetSelectionByID([]) 488 if self.IsTabLoaded('RoomTab'): 489 self.Refresh() 490 491 def ObjInverseSel(self): 492 curSel = self.sr.objscrollbox.GetSelected() 493 ids = [] 494 for each in curSel: 495 ids.append(each.id) 496 497 dunObjs = sm.GetService('scenario').GetDunObjects() 498 selItems = [] 499 for slimItem in dunObjs: 500 if not sm.GetService('scenario').IsSelectedByObjID(slimItem.dunObjectID): 501 selItems.append(slimItem.dunObjectID) 502 503 sm.GetService('scenario').SetSelectionByID(selItems) 504 if self.IsTabLoaded('RoomTab'): 505 self.Refresh() 506 507 def OnDESelectionChanged(self): 508 if self.IsTabLoaded('RoomTab') and not self.IsSelectionUpToDate(): 509 self.Refresh() 510 511 def OnDEObjectListChanged(self): 512 if self.IsTabLoaded('RoomTab'): 513 self.Refresh() 514 515 def IsSelectionUpToDate(self): 516 remoteSelection = copy.copy(sm.StartService('scenario').selectionObjs) 517 localSelection = self.GetCurrentlySelectedObjects() 518 remoteSelection.sort() 519 localSelection.sort() 520 return remoteSelection == localSelection 521 522 def GetCurrentlySelectedObjects(self): 523 if self.destroyed or self.sr.objscrollbox.destroyed: 524 selectedEntries = [] 525 else: 526 selectedEntries = self.sr.objscrollbox.GetSelected() 527 selectedObjects = [] 528 for entry in selectedEntries: 529 selectedObjects.append(entry.id) 530 531 return selectedObjects 532 533 def OnSelectObject(self, selectedList, id): 534 if id == 'In Game': 535 return 536 selectedObj = selectedList[0] 537 if hasattr(selectedObj, 'selectTypeString'): 538 if getattr(selectedObj, 'selectTypeString', 'unknown') == 'SelectDungeon': 539 settings.user.ui.Set('dungeonFactionID', None) 540 settings.user.ui.Set('dungeonArchetypeID', None) 541 settings.user.ui.Set('dungeonDungeon', selectedObj.dungeonID) 542 self.sr.maintabs.ReloadVisible() 543 elif getattr(selectedObj, 'selectTypeString', 'unknown') == 'SelectDungeonRoom': 544 if self.IsTabLoaded('DungeonTab'): 545 settings.user.ui.Set('selectedRoomID', selectedObj.roomID) 546 elif getattr(selectedObj, 'selectTypeString', 'unknown') == 'SelectDungeonObject': 547 sm.GetService('scenario').SetSelectionByID([selectedObj.objectID]) 548 if self.IsTabLoaded('RoomTab'): 549 objectList = self.sr.objscrollbox.GetNodes() 550 for objectEntry in objectList: 551 if objectEntry.id == selectedObj.objectID: 552 self.sr.objscrollbox.SetSelected(objectEntry.idx) 553 break 554 555 elif getattr(selectedObj, 'selectTypeString', 'unknown') == 'SelectDungeonEntity': 556 pass 557 elif getattr(selectedObj, 'selectTypeString', 'unknown') == 'SelectDungeonEntityGroup': 558 pass 559 elif selectedObj: 560 import log 561 log.LogWarn('dungeoneditor::OnSelectObject: Unknown selection:', selectedObj.selectTypeString) 562 563 def Load_AlignTab(self): 564 Container(name='push', parent=self.sr.panel, align=uiconst.TOTOP, height=4) 565 eveLabel.EveLabelMedium(text='Align: ', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 566 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=16) 567 Button(parent=row, label=' Align centres ', func=self.OnAlignCentres, args=('btn1',), align=uiconst.TOLEFT) 568 for each in 'XYZ': 569 checkbox1ID = 'alignCentre%s' % each 570 checkbox1Setval = settings.user.ui.Get(checkbox1ID, 0) 571 cb = Checkbox(text=each, parent=row, settingsKey=checkbox1ID, checked=checkbox1Setval, callback=self.OnCheckboxChange, align=uiconst.TOLEFT, pos=(0, 0, 28, 0)) 572 573 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 574 Line(parent=self.sr.panel, align=uiconst.TOTOP) 575 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 576 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=16) 577 Button(parent=row, label='Distribute centres', func=self.OnDistributeCentres, args=('btn1',), align=uiconst.TOLEFT) 578 for each in 'XYZ': 579 checkbox1ID = 'distributeCentre%s' % each 580 checkbox1Setval = settings.user.ui.Get(checkbox1ID, 0) 581 cb = Checkbox(text=each, parent=row, settingsKey=checkbox1ID, checked=checkbox1Setval, callback=self.OnCheckboxChange, align=uiconst.TOLEFT, pos=(0, 0, 28, 0)) 582 583 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 584 Line(parent=self.sr.panel, align=uiconst.TOTOP) 585 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 586 eveLabel.EveLabelMedium(text='Jitter: ', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 587 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=16) 588 for counter, each in enumerate('XYZ'): 589 checkbox1ID = 'jitterOffset%s' % each 590 curVal = 0 591 ed = SingleLineEditInteger(name='jitterOffset%s' % each, parent=row, setvalue=curVal, pos=(60 + counter * 52, 592 0, 593 38, 594 0), maxValue=30000) 595 setattr(self, checkbox1ID, ed) 596 597 eveLabel.EveLabelMedium(text='Offset: ', parent=row, align=uiconst.TOLEFT, state=uiconst.UI_NORMAL).name = 'Pos Text' 598 Button(parent=row, label='Jitter Position', func=self.OnJitterClicked, args=('btn1',), pos=(220, 0, 0, 0)) 599 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 600 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=16) 601 for counter, each in enumerate(('Yaw', 'Pitch', 'Roll')): 602 checkbox1ID = 'jitterOffset%s' % each 603 curVal = 0 604 ed = SingleLineEditInteger(name='jitterOffset%s' % each, parent=row, setvalue=curVal, pos=(60 + counter * 52, 605 0, 606 38, 607 0), maxValue=30000) 608 setattr(self, checkbox1ID, ed) 609 610 eveLabel.EveLabelMedium(text='Rotation: ', parent=row, align=uiconst.TOLEFT, state=uiconst.UI_NORMAL).name = 'Rot Text' 611 Button(parent=row, label='Jitter Rotation', func=self.OnJitterRotationClicked, pos=(220, 0, 0, 0)) 612 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 613 Line(parent=self.sr.panel, align=uiconst.TOTOP) 614 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 615 eveLabel.EveLabelMedium(text='Arrange: ', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 616 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=16) 617 counter = 0 618 Button(parent=row, label='Arrange', func=self.OnArrangeClicked, args=('btn1',), pos=(220, 0, 0, 0)) 619 for each in 'XYZ': 620 checkbox1ID = 'arrangeOffset%s' % each 621 curVal = 0 622 eveLabel.EveLabelMedium(text=each, parent=row, left=50 + counter * 52, state=uiconst.UI_NORMAL) 623 ed = SingleLineEditInteger(name='arrangeOffset%s' % each, parent=row, setvalue=curVal, pos=(60 + counter * 52, 624 0, 625 38, 626 0), minValue=-30000, maxValue=30000) 627 counter = counter + 1 628 setattr(self, checkbox1ID, ed) 629 630 eveLabel.EveLabelMedium(text='Offset: ', parent=row, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 631 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 632 Line(parent=self.sr.panel, align=uiconst.TOTOP) 633 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 634 eveLabel.EveLabelMedium(text='Quantity: (Only works on asteroids and clouds)', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 635 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=16) 636 counter = 0 637 Button(parent=row, label='Set Quantity', func=self.OnSetQuantityClicked, args=('btn1',), pos=(220, 0, 0, 0)) 638 minMaxQuantity = self.GetSelectedObjectsMinMaxQuantity() 639 minQuantity = minMaxQuantity[0] 640 maxQuantity = minMaxQuantity[1] 641 eveLabel.EveLabelMedium(text='Min.', parent=row, left=40, width=32, height=14, state=uiconst.UI_NORMAL) 642 eveLabel.EveLabelMedium(text='Max.', parent=row, left=130, width=32, height=14, state=uiconst.UI_NORMAL) 643 self.quantityMin = SingleLineEditInteger(name='quantityMin', parent=row, setvalue=int(minQuantity), pos=(60, 0, 64, 0)) 644 self.quantityMax = SingleLineEditInteger(name='quantityMax', parent=row, setvalue=int(maxQuantity), pos=(154, 0, 64, 0)) 645 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 646 Line(parent=self.sr.panel, align=uiconst.TOTOP) 647 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 648 eveLabel.EveLabelMedium(text='Radius: (Only works on asteroids and clouds)', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 649 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=16) 650 counter = 0 651 Button(parent=row, label='Set Radius', func=self.OnSetRadiusClicked, args=('btn1',), pos=(220, 0, 0, 0)) 652 eveLabel.EveLabelMedium(text='Min.', parent=row, left=40, width=32, height=14, state=uiconst.UI_NORMAL) 653 eveLabel.EveLabelMedium(text='Max.', parent=row, left=130, width=32, height=14, state=uiconst.UI_NORMAL) 654 minMaxRadius = self.GetSelectedObjectsMinMaxRadius() 655 minRadius = minMaxRadius[0] 656 maxRadius = minMaxRadius[1] 657 self.radiusMin = SingleLineEditInteger(name='radiusMin', parent=row, setvalue=int(minRadius), pos=(60, 0, 64, 0)) 658 self.radiusMax = SingleLineEditInteger(name='radiusMax', parent=row, setvalue=int(maxRadius), pos=(154, 0, 64, 0)) 659 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 660 Line(parent=self.sr.panel, align=uiconst.TOTOP) 661 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 662 eveLabel.EveLabelMedium(text='Rotate objects: ', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 663 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=16) 664 counter = 0 665 Button(parent=row, label='Rotate ', func=self.OnRotateClicked, args=('btn1',), pos=(220, 0, 0, 0)) 666 for each in ['Y', 'P', 'R']: 667 checkbox1ID = 'rotate_%s' % each 668 curVal = 0 669 eveLabel.EveLabelMedium(text=each, parent=row, left=50 + counter * 52, height=14, state=uiconst.UI_NORMAL) 670 ed = SingleLineEditInteger(name='rotate_%s' % each, parent=row, setvalue=curVal, pos=(60 + counter * 52, 671 0, 672 38, 673 0), minValue=-30000, maxValue=30000) 674 counter = counter + 1 675 setattr(self, checkbox1ID, ed) 676 677 eveLabel.EveLabelMedium(text='ROTATION: ', parent=row, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 678 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 679 Line(parent=self.sr.panel, align=uiconst.TOTOP) 680 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 681 eveLabel.EveLabelMedium(text='Set rotation: ', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 682 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=16) 683 counter = 0 684 Button(parent=row, label='Set rotation', func=self.OnSetRotateClicked, args=('btn1',), pos=(220, 0, 0, 0)) 685 for each in ['Y', 'P', 'R']: 686 checkbox1ID = 'rotateset_%s' % each 687 curVal = 0 688 eveLabel.EveLabelMedium(text=each, parent=row, left=50 + counter * 52, height=14, state=uiconst.UI_NORMAL) 689 ed = SingleLineEditInteger(name='rotateset_%s' % each, parent=row, setvalue=curVal, pos=(60 + counter * 52, 690 0, 691 38, 692 0), minValue=-30000, maxValue=30000) 693 counter = counter + 1 694 setattr(self, checkbox1ID, ed) 695 696 eveLabel.EveLabelMedium(text='ROTATION: ', parent=row, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 697 698 def GetSelectedObjectsMinMaxQuantity(self): 699 minQuantity = 1 700 maxQuantity = 1 701 selObjs = sm.GetService('scenario').GetSelObjects() 702 for slimItem in selObjs: 703 if slimItem.dunRadius is not None: 704 if slimItem.dunRadius > 1: 705 if minQuantity == 1: 706 minQuantity = slimItem.dunRadius 707 else: 708 minQuantity = min(minQuantity, slimItem.dunRadius) 709 maxQuantity = max(maxQuantity, slimItem.dunRadius) 710 711 return (minQuantity, maxQuantity) 712 713 def Close(self, *args, **kwds): 714 Window.Close(self, *args, **kwds) 715 self._navigation.RemoveAxisLines() 716 717 def GetSelectedObjectsMinMaxRadius(self): 718 minRadius = 1 719 maxRadius = 1 720 selObjs = sm.GetService('scenario').GetSelObjects() 721 godma = sm.GetService('godma') 722 for slimItem in selObjs: 723 if slimItem.dunRadius is not None: 724 if slimItem.dunRadius > 1: 725 if minRadius == 1: 726 minRadius = ComputeRadiusFromQuantity(slimItem.categoryID, slimItem.groupID, slimItem.typeID, slimItem.dunRadius, godma) 727 else: 728 minRadius = min(minRadius, ComputeRadiusFromQuantity(slimItem.categoryID, slimItem.groupID, slimItem.typeID, slimItem.dunRadius, godma)) 729 maxRadius = max(maxRadius, ComputeRadiusFromQuantity(slimItem.categoryID, slimItem.groupID, slimItem.typeID, slimItem.dunRadius, godma)) 730 731 return (minRadius, maxRadius) 732 733 def OnSetQuantityClicked(self, *args): 734 minQuantity = self.quantityMin.GetValue() 735 maxQuantity = self.quantityMax.GetValue() 736 if maxQuantity < minQuantity: 737 prompt_player_fsd_dialog('MinRadiusHigherThenMax') 738 return 739 sm.GetService('scenario').SetSelectedQuantity(minQuantity, maxQuantity) 740 newMinMaxRadius = self.GetSelectedObjectsMinMaxRadius() 741 newMinRadius = int(round(newMinMaxRadius[0])) 742 newMaxRadius = int(round(newMinMaxRadius[1])) 743 self.radiusMin.SetValue(newMinRadius) 744 self.radiusMax.SetValue(newMaxRadius) 745 746 def OnSetRadiusClicked(self, *args): 747 minRadius = self.radiusMin.GetValue() 748 maxRadius = self.radiusMax.GetValue() 749 if maxRadius < minRadius: 750 prompt_player_fsd_dialog('MinRadiusHigherThenMax') 751 return 752 sm.GetService('scenario').SetSelectedRadius(minRadius, maxRadius) 753 newMinMaxQuantity = self.GetSelectedObjectsMinMaxQuantity() 754 newMinQuantity = int(round(newMinMaxQuantity[0])) 755 newMaxQuantity = int(round(newMinMaxQuantity[1])) 756 self.quantityMin.SetValue(newMinQuantity) 757 self.quantityMax.SetValue(newMaxQuantity) 758 759 def OnSetRotateClicked(self, *args): 760 y = getattr(self, 'rotateset_Y').GetValue() 761 p = getattr(self, 'rotateset_P').GetValue() 762 r = getattr(self, 'rotateset_R').GetValue() 763 sm.GetService('scenario').SetRotate(y, p, r) 764 765 def OnRotateClicked(self, *args): 766 slimItems = sm.GetService('scenario').GetSelObjects() 767 if len(slimItems) == 0: 768 return 769 yaw = getattr(self, 'rotate_Y').GetValue() 770 pitch = getattr(self, 'rotate_P').GetValue() 771 roll = getattr(self, 'rotate_R').GetValue() 772 sm.GetService('scenario').RotateSelected(yaw, pitch, roll) 773 774 def OnJitterClicked(self, *args): 775 X = getattr(self, 'jitterOffsetX').GetValue() 776 Y = getattr(self, 'jitterOffsetY').GetValue() 777 Z = getattr(self, 'jitterOffsetZ').GetValue() 778 sm.GetService('scenario').JitterSelection(X, Y, Z) 779 780 def OnJitterRotationClicked(self, *args): 781 yaw = self.jitterOffsetYaw.GetValue() 782 pitch = self.jitterOffsetPitch.GetValue() 783 roll = self.jitterOffsetRoll.GetValue() 784 sm.StartService('scenario').JitterRotationSelection(yaw, pitch, roll) 785 786 def OnArrangeClicked(self, *args): 787 X = getattr(self, 'arrangeOffsetX').GetValue() 788 Y = getattr(self, 'arrangeOffsetY').GetValue() 789 Z = getattr(self, 'arrangeOffsetZ').GetValue() 790 sm.GetService('scenario').ArrangeSelection(X, Y, Z) 791 792 def OnDungeonSelectionGroupRotation(self, groupName, x, y, z, w): 793 pass 794 795 def OnRenameGroup(self): 796 selectedGroups = self.sr.objgroupscrollbox.GetSelected() 797 for each in selectedGroups: 798 self.OpenRenameGroupDialog(each.label) 799 return 800 801 def OpenRenameGroupDialog(self, key = ''): 802 oldGroupName = key 803 format = [{'type': 'btline'}, 804 {'type': 'push', 805 'height': 8, 806 'frame': 1}, 807 {'type': 'edit', 808 'setvalue': key, 809 'maxLength': 64, 810 'labelwidth': len('Group Name:') * 7, 811 'label': 'Group Name:', 812 'key': 'newGroupName', 813 'required': 1, 814 'frame': 1}, 815 {'type': 'push', 816 'height': 8, 817 'frame': 1}, 818 {'type': 'btline'}, 819 {'type': 'data', 820 'data': {'oldGroupName': oldGroupName}}, 821 {'type': 'errorcheck', 822 'errorcheck': self.RenameGroupErrorCheck}] 823 retval = uix.HybridWnd(format, caption='Rename Group', windowID='renameGroup', modal=1, buttons=uiconst.OKCANCEL, minW=300, minH=50) 824 if retval and retval['newGroupName'] and len(retval['newGroupName']) > 1: 825 self.RenameGroup(retval['oldGroupName'], retval['newGroupName']) 826 827 def RenameGroupErrorCheck(self, retval): 828 oldGroupName = retval['oldGroupName'] 829 newGroupName = retval['newGroupName'] 830 if oldGroupName == newGroupName: 831 return '' 832 if newGroupName in self.objectGroups: 833 return 'Cannot rename %s: A group with the name you specified already exists. Specify a new group name.' % oldGroupName 834 835 def RenameGroup(self, oldGroupName, newGroupName): 836 if oldGroupName == newGroupName: 837 return 838 sm.GetService('scenario').RenameHardGroup(oldGroupName, newGroupName) 839 self.objectGroups[newGroupName] = self.objectGroups[oldGroupName] 840 del self.objectGroups[oldGroupName] 841 self.Refresh() 842 843 def OnRemoveGroup(self): 844 self.RemoveSelectedGroups() 845 846 def _RemoveGroup(self, groupName): 847 del self.objectGroups[groupName] 848 self.scenario.RemoveHardGroup(groupName) 849 850 def RemoveGroup(self, groupName): 851 self._RemoveGroup(groupName) 852 self.Refresh() 853 854 def RemoveSelectedGroups(self): 855 selectedGroups = self.GetSelectedGroups() 856 for groupName in selectedGroups: 857 self._RemoveGroup(groupName) 858 859 self.Refresh() 860 861 def OnDeleteSelected(self): 862 uthread.new(self.DeleteSelected).context = 'svc.scenario.OnDeleteSelected' 863 864 def OnDeleteSelectedGroup(self): 865 uthread.new(self.DeleteSelectedGroups).context = 'svc.scenario.OnDeleteSelectedGroup' 866 867 def DeleteSelected(self): 868 self.RemoveSelectedGroups() 869 870 def DeleteGroup(self, groupName): 871 self.RemoveGroup(groupName) 872 873 def DeleteSelectedGroups(self): 874 selectedGroups = self.GetSelectedGroups() 875 for groupName in selectedGroups: 876 self._RemoveGroup(groupName) 877 878 self.Refresh() 879 880 def OnAlignCentres(self, *args): 881 selObjs = sm.GetService('scenario').GetSelObjects() 882 if len(selObjs) == 0: 883 return 884 centreAxis = trinity.TriVector() 885 for slimItem in selObjs: 886 centreAxis.x = centreAxis.x + slimItem.dunX 887 centreAxis.y = centreAxis.y + slimItem.dunY 888 centreAxis.z = centreAxis.z + slimItem.dunZ 889 890 centreAxis.Scale(1.0 / len(selObjs)) 891 for slimItem in selObjs: 892 newX = slimItem.dunX 893 newY = slimItem.dunY 894 newZ = slimItem.dunZ 895 if settings.user.ui.Get('alignCentreX', 0): 896 newX = int(centreAxis.x) 897 if settings.user.ui.Get('alignCentreY', 0): 898 newY = int(centreAxis.y) 899 if settings.user.ui.Get('alignCentreZ', 0): 900 newZ = int(centreAxis.z) 901 dungeonHelper.SetObjectPosition(slimItem.dunObjectID, newX, newY, newZ) 902 903 def OnDistributeCentres(self, *args): 904 selObjs = sm.GetService('scenario').GetSelObjects() 905 if len(selObjs) < 2: 906 return 907 centreAxis = trinity.TriVector() 908 minV = trinity.TriVector(selObjs[0].dunX, selObjs[0].dunY, selObjs[0].dunZ) 909 maxV = minV.CopyTo() 910 for slimItem in selObjs: 911 minV.x = min(minV.x, slimItem.dunX) 912 minV.y = min(minV.y, slimItem.dunY) 913 minV.z = min(minV.z, slimItem.dunZ) 914 maxV.x = max(maxV.x, slimItem.dunX) 915 maxV.y = max(maxV.y, slimItem.dunY) 916 maxV.z = max(maxV.z, slimItem.dunZ) 917 918 dMinMaxV = maxV - minV 919 dStepSize = dMinMaxV.CopyTo() 920 dStepSize.Scale(1.0 / (len(selObjs) - 1)) 921 if len(selObjs) == 0: 922 return 923 counter = 0 924 for slimItem in selObjs: 925 newX = slimItem.dunX 926 newY = slimItem.dunY 927 newZ = slimItem.dunZ 928 if settings.user.ui.Get('distributeCentreX', 0): 929 newX = minV.x + dStepSize.x * counter 930 if settings.user.ui.Get('distributeCentreY', 0): 931 newY = minV.y + dStepSize.y * counter 932 if settings.user.ui.Get('distributeCentreZ', 0): 933 newZ = minV.z + dStepSize.z * counter 934 dungeonHelper.SetObjectPosition(slimItem.dunObjectID, newX, newY, newZ) 935 counter = counter + 1 936 937 def Load_SettingTab(self): 938 eveLabel.EveLabelMedium(text='Cursor size clamping', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 939 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=16) 940 counter = 0 941 Button(parent=row, label='Set min and max', func=self.OnSetCursorRadiusClicked, args=('btn1',), pos=(220, 0, 0, 0)) 942 minRadius = settings.user.ui.Get('cursorMin', 1.0) 943 maxRadius = settings.user.ui.Get('cursorMax', 100000.0) 944 selObjs = sm.GetService('scenario').GetSelObjects() 945 for slimItem in selObjs: 946 if slimItem.radius > 1: 947 if minRadius == 1: 948 minRadius = slimItem.radius 949 else: 950 minRadius = min(minRadius, slimItem.radius) 951 maxRadius = max(maxRadius, slimItem.radius) 952 953 eveLabel.EveLabelMedium(text='Min.', parent=row, left=40, width=32, state=uiconst.UI_NORMAL) 954 eveLabel.EveLabelMedium(text='Max.', parent=row, left=130, width=32, state=uiconst.UI_NORMAL) 955 self.cursorMin = SingleLineEditInteger(name='cursorMin', parent=row, setvalue=int(minRadius), pos=(60, 0, 64, 0), maxValue=60000) 956 self.cursorMax = SingleLineEditInteger(name='cursorMax', parent=row, setvalue=int(maxRadius), pos=(154, 0, 64, 0), maxValue=60000) 957 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 958 Line(parent=self.sr.panel, align=uiconst.TOTOP) 959 Container(name='pusher', align=uiconst.TOTOP, height=6, parent=self.sr.panel) 960 eveLabel.EveLabelMedium(text='Aggression radius: ', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 961 checkbox1ID = 'showAggrRadius' 962 checkbox1Setval = settings.user.ui.Get(checkbox1ID, 0) 963 self.aggrSettings = Checkbox(text='Aggression radius', parent=self.sr.panel, settingsKey=checkbox1ID, checked=settings.user.ui.Get('showAggrRadius', 0), callback=self.OnDisplaySettingsChange) 964 self.aggrSettingsAll = Checkbox(text='Show agression radius of all objects', parent=self.sr.panel, settingsKey=checkbox1ID, checked=settings.user.ui.Get('aggrSettingsAll', 0), callback=self.OnDisplaySettingsChange) 965 Line(parent=self.sr.panel, align=uiconst.TOTOP) 966 self.gridCheckbox = Checkbox(text='Draw Grid Lines', parent=self.sr.panel, settingsKey=checkbox1ID, checked=self._navigation.IsGridEnabled(), callback=self.OnDisplaySettingsChange) 967 Container(name='pusher', align=uiconst.TOTOP, height=7, parent=self.sr.panel) 968 eveLabel.EveLabelMedium(text='Palette Placement Grid', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 969 gridSizeOptions = [('200x200m', 200.0), 970 ('2x2km', 2000.0), 971 ('20x20km', 20000.0), 972 ('200x200km', 200000.0), 973 ('2000x2000km', 2000000.0)] 974 Container(name='pusher', align=uiconst.TOTOP, height=14, parent=self.sr.panel) 975 self.gridSizeDropdown = Combo(parent=self.sr.panel, label='Grid Size', options=gridSizeOptions, name='', select=self._navigation.GetGridLength(), callback=self.OnDisplaySettingsChange, align=uiconst.TOTOP, adjustWidth=True) 976 gridSpacingOptions = [('10x10m', 10.0), 977 ('100x100m', 100.0), 978 ('1x1km', 1000.0), 979 ('10x10km', 10000.0)] 980 Container(name='pusher', align=uiconst.TOTOP, height=14, parent=self.sr.panel) 981 self.gridSpacingDropdown = Combo(parent=self.sr.panel, label='Unit Size', options=gridSpacingOptions, name='', select=self._navigation.GetGridSpacing(), callback=self.OnDisplaySettingsChange, align=uiconst.TOTOP, adjustWidth=True) 982 Container(name='pusher', align=uiconst.TOTOP, height=14, parent=self.sr.panel) 983 eveLabel.EveLabelMedium(text='Free Look Camera must be enabled to use the placement grid.', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 984 eveLabel.EveLabelMedium(text='Red Axis Line = X Axis', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 985 eveLabel.EveLabelMedium(text='Green Axis Line = Y Axis', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 986 eveLabel.EveLabelMedium(text='Blue Axis Line = Z Axis', parent=self.sr.panel, align=uiconst.TOTOP, state=uiconst.UI_NORMAL) 987 988 def OnDisplaySettingsChange(self, *args): 989 desiredSpacingValue = self.gridSpacingDropdown.GetValue() 990 settings.user.ui.Set('showAggrRadius', self.aggrSettings.GetValue()) 991 settings.user.ui.Set('aggrSettingsAll', self.aggrSettingsAll.GetValue()) 992 self.UpdateGridVisibility() 993 if desiredSpacingValue != self._navigation.GetGridSpacing(): 994 self.gridSpacingDropdown.SetValue(self._navigation.GetGridSpacing()) 995 sm.GetService('scenario').RefreshSelection() 996 997 def OnSetCursorRadiusClicked(self, *args): 998 minRadius = self.cursorMin.GetValue() 999 maxRadius = self.cursorMax.GetValue() 1000 if maxRadius < minRadius: 1001 prompt_player_fsd_dialog('MinRadiusHigherThenMax') 1002 return 1003 settings.user.ui.Set('cursorMin', minRadius) 1004 settings.user.ui.Set('cursorMax', maxRadius) 1005 sm.GetService('scenario').RefreshSelection() 1006 1007 def GetScrollOptions(self, key): 1008 data = [] 1009 if key == 'combo_retval1': 1010 data = [ ('1 label %s' % i, i) for i in xrange(100) ] 1011 elif key == 'combo_retval2': 1012 data = [ ('2 label %s' % i, i) for i in xrange(100) ] 1013 return [ GetFromClass(Generic, {'label': label, 1014 'id': id}) for label, id in data ] 1015 1016 def OnGotoSelectedRoomClicked(self, entry, *args): 1017 settings.user.ui.Set('selectedRoomID', entry.sr.node.roomID) 1018 dungeonID = settings.user.ui.Get('dungeonDungeon', None) 1019 sm.ScatterEvent('OnSelectObjectInGame', 'SelectDungeonRoom', dungeonID=dungeonID, roomID=entry.sr.node.roomID) 1020 1021 def OnComboChange(self, combo, newHeader, newValue, *args): 1022 settings.user.ui.Set(combo.name, newValue) 1023 self.sr.maintabs.ReloadVisible() 1024 if combo.name == 'dungeonDungeon': 1025 sm.ScatterEvent('OnSelectObjectInGame', 'SelectDungeon', dungeonID=newValue) 1026 1027 def OnClickButton(self, *args): 1028 self.sr.maintabs.ReloadVisible() 1029 1030 def OnCheckboxChange(self, checkbox, *args): 1031 settings.user.ui.Set(checkbox.GetSettingsKey(), checkbox.checked) 1032 1033 def Load_PaletteTab(self): 1034 roomObjectGroups = sm.RemoteSvc('dungeon').DEGetRoomObjectPaletteData() 1035 kv = utillib.KeyVal() 1036 kv.groupItems = roomObjectGroups 1037 scrollOptions = self.GetGroupTypes(kv) 1038 self.sr.palettescroll = eveScroll.Scroll(name='scroll', parent=self.sr.panel, align=uiconst.TOALL) 1039 self.sr.palettescroll.Load(contentList=scrollOptions, scrolltotop=0) 1040 self.sr.palettescroll.padBottom = button.height + const.defaultPadding * 5 1041 self.sr.palettescroll.multiSelect = 0 1042 1043 def GetGroupTypes(self, nodeData, *args): 1044 sublevel = nodeData.Get('sublevel', -1) + 1 1045 scrollOptions = [] 1046 if type(nodeData.groupItems) == list: 1047 nodeData.groupItems.sort(lambda x, y: cmp(x[1], y[1])) 1048 for id, name in nodeData.groupItems: 1049 scrollOptions.append(GetFromClass(PaletteEntry, {'label': name, 1050 'id': id, 1051 'sublevel': sublevel})) 1052 1053 elif type(nodeData.groupItems) == dict: 1054 keys = nodeData.groupItems.keys() 1055 keys.sort(lambda x, y: cmp(x[1], y[1])) 1056 for key in keys: 1057 groupID, groupName = key 1058 scrollOptions.append(GetFromClass(ListGroup, {'label': groupName, 1059 'id': ('group', groupID), 1060 'groupItems': nodeData.groupItems[key], 1061 'showlen': 1, 1062 'sublevel': sublevel, 1063 'GetSubContent': self.GetGroupTypes})) 1064 1065 return scrollOptions 1066 1067 def OnDEObjectPaletteChanged(self): 1068 if self.sr.Get('palettescroll') and self.sr.palettescroll is not None: 1069 self.UnloadPanel() 1070 self.Refresh() 1071 1072 def _OnClose(self, *args): 1073 self.scenario.ClearSelection() 1074 1075 1076 class DungeonDragEntry(Generic): 1077 __guid__ = 'listentry.DungeonDragEntry' 1078 __nonpersistvars__ = [] 1079 isDragObject = True 1080 DROPDISTANCE = 10000 1081 1082 def GetDragData(self, *args): 1083 return self.sr.node.scroll.GetSelectedNodes(self.sr.node) 1084 1085 def OnEndDrag(self, *args): 1086 uthread.new(self.OnEndDragFunc) 1087 1088 def OnEndDragFunc(self): 1089 from eve.client.script.ui.inflight.navigation import InflightLayer 1090 where = uicore.uilib.mouseOver 1091 if where and type(where) is InflightLayer: 1092 scenarioSvc = sm.services['scenario'] 1093 roomID = scenarioSvc.GetEditingRoomID() 1094 if roomID is None: 1095 message_player('You need to be editing a room to be able to add an object') 1096 return 1097 proj, view, vp = uix.GetFullscreenProjectionViewAndViewport() 1098 ray, startingPosition = trinity.device.GetPickRayFromViewport(uicore.uilib.x, uicore.uilib.y, vp, view.transform, proj.transform) 1099 ray = trinity.TriVector(*ray) 1100 roomPos = scenarioSvc.GetEditingRoomPosition() 1101 ship = sm.services['michelle'].GetBall(session.shipid) 1102 camera = sm.GetService('sceneManager').GetActiveCamera() 1103 cameraParent = sm.GetService('sceneManager').GetActiveCamera().GetCameraParent() 1104 cameraPosition = trinity.TriVector(ship.x - roomPos[0] + camera.pos[0], ship.y - roomPos[1] + camera.pos[1], ship.z - roomPos[2] + camera.pos[2]) 1105 focusPoint = cameraParent.translation 1106 focusPoint = trinity.TriVector(ship.x - roomPos[0] + focusPoint[0], ship.y - roomPos[1] + focusPoint[1], ship.z - roomPos[2] + focusPoint[2]) 1107 dist = (focusPoint.y - cameraPosition.y) / ray.y 1108 if dist < 0: 1109 message_player('This item can only be dragged onto the grid') 1110 return 1111 posInRoom = cameraPosition + ray * dist 1112 gridLength = sm.GetService('sceneManager').GetActiveCamera().dungeonHack.GetGridLength() 1113 minGrid = -gridLength / 2.0 1114 maxGrid = gridLength / 2.0 1115 if minGrid + focusPoint.x > posInRoom.x or maxGrid + focusPoint.x < posInRoom.x or minGrid + focusPoint.z > posInRoom.z or maxGrid + focusPoint.z < posInRoom.z: 1116 message_player('You can only drag Palette entries onto the grid') 1117 return 1118 self.DropIntoDungeonRoom(roomID, posInRoom) 1119 elif where and where.__guid__ not in (self.__guid__, 'form.DungeonEditor'): 1120 message_player('This item can only be dragged onto the grid') 1121 1122 def DropIntoDungeonRoom(self, roomID, posInRoom): 1123 pass 1124 1125 1126 class PaletteEntry(DungeonDragEntry): 1127 __guid__ = 'listentry.PaletteEntry' 1128 1129 1130 class DungeonObjectProperties(Window): 1131 __guid__ = 'form.DungeonObjectProperties' 1132 __nonpersistvars__ = [] 1133 __notifyevents__ = ['OnDungeonObjectProperties', 'OnSelectObjectInGame'] 1134 _windowHeight = 200 1135 default_windowID = 'dungeonObjectProperties' 1136 1137 def ApplyAttributes(self, attributes): 1138 Window.ApplyAttributes(self, attributes) 1139 self.scope = uiconst.SCOPE_INFLIGHT 1140 self.SetCaption('Object Properties') 1141 self.width = 300 1142 self.height = self._windowHeight 1143 self.SetHeight(self._windowHeight) 1144 self.objectRow = None 1145 self.noObjects = eveLabel.EveLabelMedium(text='No Objects Selected', parent=self.sr.main, left=5, top=4, state=uiconst.UI_NORMAL) 1146 panel = Container(name='panel', parent=self.sr.main, left=const.defaultPadding, top=const.defaultPadding, width=const.defaultPadding, height=const.defaultPadding) 1147 self.sr.panel = panel 1148 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=18) 1149 eveLabel.EveLabelMedium(text='Selected:', parent=row, left=2, top=4, state=uiconst.UI_NORMAL) 1150 self.selectedCombo = Combo(label='', parent=row, options=(('Nothing', 0),), name='combo', select=0, callback=self.OnComboChange, pos=(80, 0, 0, 0), align=uiconst.TOPLEFT) 1151 self.selectedCombo.width = 202 1152 Line(parent=self.sr.panel, align=uiconst.TOTOP) 1153 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=20) 1154 eveLabel.EveLabelMedium(text='Object Name:', parent=row, left=2, top=4, state=uiconst.UI_NORMAL) 1155 self.objectName = SingleLineEditText(name='objectName', parent=row, setvalue='', pos=(80, 0, 202, 16)) 1156 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=20) 1157 eveLabel.EveLabelMedium(text='Object Type:', parent=row, left=2, top=4, state=uiconst.UI_NORMAL) 1158 self.objectType = eveLabel.EveLabelMedium(text='', parent=row, left=80, top=4, state=uiconst.UI_NORMAL) 1159 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=20) 1160 eveLabel.EveLabelMedium(text='Quantity:', parent=row, left=2, top=4, state=uiconst.UI_NORMAL) 1161 self.quantity = SingleLineEditInteger(name='quantity', parent=row, setvalue=0, pos=(80, 0, 202, 0)) 1162 self.oldQuantity = 0 1163 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=20) 1164 eveLabel.EveLabelMedium(text='Radius:', parent=row, left=2, top=4, state=uiconst.UI_NORMAL) 1165 self.radius = SingleLineEditInteger(name='radius', parent=row, setvalue=0, pos=(80, 0, 202, 16)) 1166 self.oldRadius = 0 1167 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=20) 1168 eveLabel.EveLabelMedium(text='Position:', parent=row, left=2, top=4, state=uiconst.UI_NORMAL) 1169 for i, each in enumerate('XYZ'): 1170 editId = 'position%s' % each 1171 editBox = SingleLineEditFloat(name=editId, parent=row, setvalue=0, pos=(80 + i * 69, 1172 0, 1173 64, 1174 16), minValue=-100000.0, maxValue=100000.0) 1175 setattr(self, editId, editBox) 1176 1177 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=20) 1178 eveLabel.EveLabelMedium(text='Rotation:', parent=row, left=2, top=4, state=uiconst.UI_NORMAL) 1179 for i, each in enumerate(['Yaw', 'Pitch', 'Roll']): 1180 editId = 'rotation%s' % each 1181 editBox = SingleLineEditFloat(name=editId, parent=row, setvalue=0, pos=(80 + i * 69, 1182 0, 1183 64, 1184 16), minValue=-100000.0, maxValue=100000.0) 1185 setattr(self, editId, editBox) 1186 1187 Container(name='spacer', parent=self.sr.panel, align=uiconst.TOTOP, height=5) 1188 Line(parent=self.sr.panel, align=uiconst.TOTOP) 1189 Container(name='spacer', parent=self.sr.panel, align=uiconst.TOTOP, height=5) 1190 row = Container(name='row', parent=self.sr.panel, align=uiconst.TOTOP, height=20) 1191 Button(parent=row, label='Change Type', func=self.OnChangeType, align=uiconst.TOLEFT).width = 87 1192 Button(parent=row, label='Save', func=self.OnSave, align=uiconst.TOLEFT).width = 87 1193 Button(parent=row, label='Revert', func=self.OnRevert, align=uiconst.TOLEFT).width = 87 1194 self.scenario = sm.StartService('scenario') 1195 self.OnSelectObjectInGame('SelectDungeonObject') 1196 self.Show() 1197 1198 def LoadObjectID(self, objectID = None): 1199 if objectID is None: 1200 self.sr.panel.state = uiconst.UI_HIDDEN 1201 self.noObjects.state = uiconst.UI_DISABLED 1202 self.objectRow = None 1203 self.SetCaption('Object Properties') 1204 return 1205 self.ShowLoad() 1206 self.objectRow = None 1207 if self.objectRow is None: 1208 self.sr.panel.state = uiconst.UI_HIDDEN 1209 self.noObjects.state = uiconst.UI_DISABLED 1210 self.objectRow = None 1211 self.HideLoad() 1212 return 1213 self.sr.panel.state = uiconst.UI_PICKCHILDREN 1214 self.noObjects.state = uiconst.UI_HIDDEN 1215 self.SetHeight(self._windowHeight) 1216 self.UpdateDisplay() 1217 1218 def UpdateDisplay(self): 1219 self.ShowLoad() 1220 self.SetCaption('Object Properties: %d' % self.objectRow.objectID) 1221 objectName = '' 1222 if self.objectRow.objectNameID is not None: 1223 objectName = GetMessageFromLocalization(self.objectRow.objectNameID) 1224 self.objectName.SetValue(objectName) 1225 self.objectType.text = evetypes.GetNameOrNone(self.objectRow.typeID) or '<No Type Set>' 1226 quantity = dungeonHelper.GetObjectQuantity(self.objectRow.objectID) 1227 if quantity is None: 1228 self.quantity.SetValue('Quantity Invalid For This Type') 1229 self.quantity.state = uiconst.UI_DISABLED 1230 else: 1231 self.quantity.state = uiconst.UI_NORMAL 1232 self.quantity.SetValue(int(quantity)) 1233 self.oldQuantity = int(quantity) 1234 radius = dungeonHelper.GetObjectRadius(self.objectRow.objectID) 1235 if radius is None: 1236 self.radius.SetValue('Radius Invalid For This Type') 1237 self.radius.state = uiconst.UI_DISABLED 1238 else: 1239 self.radius.state = uiconst.UI_NORMAL 1240 self.radius.SetValue(int(radius)) 1241 self.oldRadius = int(radius) 1242 x, y, z = dungeonHelper.GetObjectPosition(self.objectRow.objectID) 1243 self.positionX.SetValue(x) 1244 self.positionY.SetValue(y) 1245 self.positionZ.SetValue(z) 1246 yaw, pitch, roll = dungeonHelper.GetObjectRotation(self.objectRow.objectID) 1247 self.rotationYaw.SetValue(yaw) 1248 self.rotationPitch.SetValue(pitch) 1249 self.rotationRoll.SetValue(roll) 1250 self.HideLoad() 1251 1252 def OnSelectObjectInGame(self, selectType, *args, **kwargs): 1253 if selectType == 'SelectDungeonObject': 1254 self._HandleSelection(self.scenario.GetSelectedObjIDs()) 1255 1256 def _HandleSelection(self, objectIds): 1257 if objectIds: 1258 scenarioSvc = sm.StartService('scenario') 1259 for objectID in objectIds: 1260 ball, slimItem = scenarioSvc.GetBallAndSlimItemFromObjectID(objectID) 1261 sleepTime = 0 1262 while ball is None or slimItem is None and sleepTime < 5000: 1263 sleepTime += 200 1264 blue.synchro.SleepWallclock(200) 1265 ball, slimItem = scenarioSvc.GetBallAndSlimItemFromObjectID(objectID) 1266 1267 if ball is None or slimItem is None: 1268 sm.StartService('scenario').LogError('DungeonObjectProperties._HandleSelection could not load balls and slimItems') 1269 1270 if self.objectRow is None or self.objectRow.objectID not in objectIds: 1271 self.LoadObjectID(objectIds[0]) 1272 options = [] 1273 for objectId in objectIds: 1274 options.append((objectId, objectId)) 1275 1276 self.selectedCombo.LoadOptions(options, select=self.objectRow.objectID) 1277 else: 1278 self.LoadObjectID() 1279 1280 def OnDungeonObjectProperties(self, objectID): 1281 if self.objectRow and objectID == self.objectRow.objectID: 1282 self.UpdateDisplay() 1283 1284 def OnChangeType(self, *args, **kwargs): 1285 ObjectTypeChooser.Open(objectRow=self.objectRow) 1286 1287 def OnSave(self, *args, **kwargs): 1288 dungeonID = settings.user.ui.Get('dungeonDungeon', None) 1289 if dungeonID is None or dungeonID == 'All': 1290 return 1291 selDungeon = sm.RemoteSvc('dungeon').DEGetDungeons(dungeonID=dungeonID)[0] 1292 dungeonNameID = selDungeon.dungeonNameID 1293 if dungeonNameID is not None: 1294 dungeonName = GetMessageFromLocalization(dungeonNameID) 1295 else: 1296 dungeonName = selDungeon.dungeonName 1297 quantity = self.quantity.GetValue() 1298 if quantity != 'Quantity Invalid For This Type' and quantity != self.oldQuantity: 1299 self.oldQuantity = quantity 1300 dungeonHelper.SetObjectQuantity(self.objectRow.objectID, quantity) 1301 radius = self.radius.GetValue() 1302 if radius != 'Radius Invalid For This Type' and radius != self.oldRadius: 1303 self.oldRadius = radius 1304 dungeonHelper.SetObjectRadius(self.objectRow.objectID, radius) 1305 x = self.positionX.GetValue() 1306 y = self.positionY.GetValue() 1307 z = self.positionZ.GetValue() 1308 dungeonHelper.SetObjectPosition(self.objectRow.objectID, x, y, z) 1309 yaw = self.rotationYaw.GetValue() 1310 pitch = self.rotationPitch.GetValue() 1311 roll = self.rotationRoll.GetValue() 1312 dungeonHelper.SetObjectRotation(self.objectRow.objectID, yaw, pitch, roll) 1313 objectName = self.objectName.GetValue() 1314 if not objectName: 1315 objectName = None 1316 if objectName is not None: 1317 objectNameID = self.objectRow.objectNameID 1318 if objectNameID is not None and objectName == GetMessageFromLocalization(objectNameID): 1319 return 1320 if objectNameID is not None and unicode(objectNameID) in objectName: 1321 msgText = 'Do you really want to name this object %s?' 1322 msgText += " Selecting 'No' will save other changes you have made to the object, but will not change the name." 1323 ret = prompt_player_fsd_dialog('CustomQuestion', {'header': 'Rename Object?', 1324 'question': msgText % objectName}, uiconst.YESNO) 1325 if ret == uiconst.ID_NO: 1326 return 1327 self.UpdateDisplay() 1328 1329 def OnRevert(self, *args, **kwargs): 1330 self.UpdateDisplay() 1331 1332 def OnComboChange(self, *args, **kwargs): 1333 selected = self.selectedCombo.GetValue() 1334 if selected != self.objectRow.objectID: 1335 self.LoadObjectID(selected) 1336 1337 1338 class ObjectTypeChooser(Window): 1339 1340 def ApplyAttributes(self, attributes): 1341 Window.ApplyAttributes(self, attributes) 1342 objectRow = attributes.objectRow 1343 self.scope = uiconst.SCOPE_INFLIGHT 1344 self.SetCaption('Object Type Chooser - %d' % objectRow.objectID) 1345 self.SetMinSize([350, 400]) 1346 self.objectRow = objectRow 1347 panel = Container(name='panel', parent=self.sr.main, left=const.defaultPadding, top=const.defaultPadding, width=const.defaultPadding, height=const.defaultPadding) 1348 self.sr.panel = panel 1349 roomObjectGroups = sm.RemoteSvc('dungeon').DEGetRoomObjectPaletteData() 1350 kv = utillib.KeyVal() 1351 kv.groupItems = roomObjectGroups 1352 scrollOptions = self.GetGroupTypes(kv) 1353 self.sr.palettescroll = eveScroll.Scroll(name='scroll', parent=self.sr.panel, align=uiconst.TOALL) 1354 self.sr.palettescroll.Load(contentList=scrollOptions, scrolltotop=0) 1355 button = Button(parent=self.sr.panel, label='Change Type', func=self.OnChangeType, align=uiconst.TOBOTTOM) 1356 self.sr.palettescroll.padBottom = const.defaultPadding * 7 1357 self.sr.palettescroll.multiSelect = 0 1358 self.Show() 1359 1360 def OnChangeType(self, *args, **kwargs): 1361 curSel = self.sr.palettescroll.GetSelected() 1362 if curSel: 1363 id = curSel[0].id 1364 name = curSel[0].label 1365 else: 1366 message_player('You need to select an object type from the chooser before you can change the object type') 1367 return 1368 self.objectRow.typeID = id 1369 1370 def GetGroupTypes(self, nodeData, *args): 1371 sublevel = nodeData.Get('sublevel', -1) + 1 1372 scrollOptions = [] 1373 if type(nodeData.groupItems) == list: 1374 nodeData.groupItems.sort(lambda x, y: cmp(x[1], y[1])) 1375 for id, name in nodeData.groupItems: 1376 scrollOptions.append(GetFromClass(PaletteEntry, {'label': name, 1377 'id': id, 1378 'sublevel': sublevel})) 1379 1380 elif type(nodeData.groupItems) == dict: 1381 keys = nodeData.groupItems.keys() 1382 keys.sort(lambda x, y: cmp(x[1], y[1])) 1383 for key in keys: 1384 groupID, groupName = key 1385 scrollOptions.append(GetFromClass(ListGroup, {'label': groupName, 1386 'id': ('group', groupID), 1387 'groupItems': nodeData.groupItems[key], 1388 'showlen': 1, 1389 'sublevel': sublevel, 1390 'GetSubContent': self.GetGroupTypes})) 1391 1392 return scrollOptions 1393 1394 1395 class ObjectGroupListEntry(Generic): 1396 __guid__ = 'listentry.ObjectGroupListEntry' 1397 __nonpersistvars__ = [] 1398 1399 def Startup(self, *args): 1400 Generic.Startup(self, args) 1401 self.sr.lock = eveIcon.Icon(icon='ui_22_32_30', parent=self, size=24, align=uiconst.CENTERRIGHT, state=uiconst.UI_HIDDEN, hint='You can not change this shortcut') 1402 1403 def Load(self, node): 1404 Generic.Load(self, node) 1405 self.sr.form = node.form 1406 self.sr.isLocked = node.locked 1407 self.sr.lock.state = [uiconst.UI_HIDDEN, uiconst.UI_NORMAL][node.locked] 1408 1409 def GetMenu(self): 1410 if self.sr.isLocked: 1411 return [] 1412 m = [('Rename Group', self.RenameGroup), ('Remove Group', self.RemoveGroup), ('Delete Group Objects', self.DeleteGroupObjects)] 1413 return m 1414 1415 def OnDblClick(self, *args): 1416 if not self.sr.isLocked: 1417 self.RenameGroup() 1418 1419 def RenameGroup(self): 1420 self.Deselect() 1421 self.sr.form.OpenRenameGroupDialog(key=self.sr.label.text) 1422 1423 def RemoveGroup(self): 1424 self.Deselect() 1425 self.sr.form.RemoveGroup(self.sr.label.text) 1426 1427 def DeleteGroupObjects(self): 1428 self.Deselect() 1429 uthread.new(self.sr.form.DeleteGroup, self.sr.label.text).context = 'svc.scenario.OnDeleteSelected' 1430 1431 def RefreshCallback(self, *args): 1432 if self.sr.node.Get('refreshcallback', None): 1433 self.sr.node.refreshcallback()