From 097ea4942f99f48a25b69ad46cb6a3cf694dc6db Mon Sep 17 00:00:00 2001 From: Zach Date: Sat, 30 May 2015 06:16:23 -0500 Subject: [PATCH] lobby manager and GUI update --- toontown/coghq/BossLobbyGui.py | 235 +++++++++++++++++- .../coghq/DistributedCogHQExteriorDoor.py | 1 + toontown/uberdog/DistributedLobbyManager.py | 70 ++++++ toontown/uberdog/DistributedLobbyManagerAI.py | 121 +++++++++ toontown/uberdog/DistributedLobbyManagerUD.py | 9 + 5 files changed, 434 insertions(+), 2 deletions(-) create mode 100644 toontown/uberdog/DistributedLobbyManager.py create mode 100644 toontown/uberdog/DistributedLobbyManagerAI.py create mode 100644 toontown/uberdog/DistributedLobbyManagerUD.py diff --git a/toontown/coghq/BossLobbyGui.py b/toontown/coghq/BossLobbyGui.py index 2a7d59b5..5f1ae9aa 100644 --- a/toontown/coghq/BossLobbyGui.py +++ b/toontown/coghq/BossLobbyGui.py @@ -6,7 +6,6 @@ from toontown.toonbase import TTLocalizer class BossLobbyGui(DirectFrame): class InitialFrame(DirectFrame): - frame = 0 class LobbySelection(DirectButton): @@ -93,12 +92,232 @@ class BossLobbyGui(DirectFrame): else: self.callback(-1) + class SecondaryFrame(DirectFrame): + frame = 1 + + class LobbyList(DirectScrolledList): + + def __init__(self, parent, **kw): + buttons = loader.loadModel("phase_3/models/gui/tt_m_gui_mat_mainGui") + arrowGui = (buttons.find('**/tt_t_gui_mat_arrowUp'), buttons.find('**/tt_t_gui_mat_arrowDown'), buttons.find('**/tt_t_gui_mat_arrowDisabled')) + buttons.removeNode() + optiondefs = ( + ('relief', None, None), + ('pos', (-0.375, 0, -0.045), None), + ('numItemsVisible', 4, None), + ('forceHeight', 0.12, None), + ('itemFrame_relief', DGG.SUNKEN, None), + ('itemFrame_pos', (0, 0, 0), None), + ('itemFrame_scale', 1.0, None), + ('itemFrame_borderWidth', (0.015, 0.015), None), + ('itemFrame_frameSize', (-0.325, 0.225, -0.325, 0.2), None), + ('itemFrame_frameColor', (0.85, 0.95, 1, 1), None), + ('decButton_image', arrowGui, None), + ('decButton_relief', None, None), + ('decButton_pos', (0.31, 0, 0.025), None), + ('decButton_hpr', (0, 0, -90), None), + ('decButton_scale', 0.5, None), + ('incButton_image', arrowGui, None), + ('incButton_relief', None, None), + ('incButton_pos', (0.31, 0, -0.175), None), + ('incButton_hpr', (0, 0, 90), None), + ('incButton_scale', 0.5, None), + ) + self.defineoptions(kw, optiondefs) + DirectScrolledList.__init__(self, relief=None) + self.initialiseoptions(BossLobbyGui.SecondaryFrame.LobbyList) + + class LobbyListItem(DirectFrame): + + def __init__(self, parent, itemText, callback, **kw): + optiondefs = ( + ('relief', None, None), + ('frameColor', (0.85, 0.95, 1, 1), None), + ('frameSize', (-0.31, 0.21, 0.055, 0.185), None), + ) + self.defineoptions(kw, optiondefs) + DirectFrame.__init__(self, relief=None) + self.initialiseoptions(BossLobbyGui.SecondaryFrame.LobbyListItem) + self.button = DirectButton( + parent=self, + relief=None, + text=itemText, + text_align=TextNode.ALeft, + text_fg=Vec4(0, 0, 0, 1), + text3_fg=(0.4, 0.8, 0.4, 1), + text1_bg=(1, 1, 0, 1), + text2_bg=(0.5, 0.9, 1, 1), + pos=(-0.28, 0, 0.105), + scale=0.065, + command=callback, + extraArgs=[itemText], + ) + + def destroy(self): + if hasattr(self, 'button') and self.button: + self.button.destroy() + DirectFrame.destroy(self) + + class LobbyEntry(DirectEntry): + + def __init__(self, parent, **kw): + optiondefs = ( + ('relief', DGG.SUNKEN, None), + ('borderWidth', (0.25, 0.25), None), + ('pos', (-0.675, 0, 0.285), None), + ('scale', (0.05, 0.055, 0.055), None), + ('numLines', 1, None), + ('focus', 1, None), + ('frameColor', (0.85, 0.95, 1, 1), None), + ) + self.defineoptions(kw, optiondefs) + DirectEntry.__init__(self, relief=None) + self.initialiseoptions(BossLobbyGui.SecondaryFrame.LobbyEntry) + + def __init__(self, parent, callback, **kw): + optiondefs = ( + ('relief', None, None), + ('state', DGG.NORMAL, None), + ('image', DGG.getDefaultDialogGeom(), None), + ('image_scale', (1.6, 1.0, 1.3), None), + ('image_color', ToontownGlobals.GlobalDialogColor, None), + ('pos', (0, 0, 0), None), + ) + self.defineoptions(kw, optiondefs) + DirectFrame.__init__(self, relief=None) + self.initialiseoptions(BossLobbyGui.SecondaryFrame) + self.callback = callback + self.items = [] + self.selection = None + self.friendsOnly = False + self.laffLimit = False + self.lobbyName = None + self.load() + + def destroy(self): + if hasattr(self, 'titleLeft') and self.titleLeft: + self.titleLeft.destroy() + del self.titleLeft + if hasattr(self, 'lobbies') and self.lobbies: + self.lobbies.destroy() + del self.lobbies + if hasattr(self, 'entry') and self.entry: + self.entry.destroy() + del self.entry + if hasattr(self, 'cancelButton') and self.cancelButton: + self.cancelButton.destroy() + del self.cancelButton + if hasattr(self, 'nextButton') and self.nextButton: + self.nextButton.destroy() + del self.nextButton + DirectFrame.destroy(self) + + def load(self): + empty = loader.loadModel("phase_3.5/models/gui/matching_game_gui.bam") + buttons = loader.loadModel("phase_3/models/gui/tt_m_gui_mat_mainGui") + cancelImageList = (buttons.find('**/tt_t_gui_mat_closeUp'), buttons.find('**/tt_t_gui_mat_closeDown'), buttons.find('**/tt_t_gui_mat_closeDown')) + nextImageList = (buttons.find('**/tt_t_gui_mat_nextUp'), buttons.find('**/tt_t_gui_mat_nextDown'), buttons.find('**/tt_t_gui_mat_nextDown')) + emptyList = (empty.find("**/minnieCircle"), empty.find("**/minnieCircle"), empty.find("**/minnieCircle")) + empty.removeNode() + buttons.removeNode() + + self.titleLeft = DirectLabel(parent=self, relief=None, text="Select a Lobby", textMayChange=1, text_scale=0.08, pos=(-0.435, 0, 0.475)) + self.titleRight = DirectLabel(parent=self, relief=None, text="Create a Lobby", textMayChange=1, text_scale=0.08, pos=(0.39, 0, 0.475)) + + self.lobbies = BossLobbyGui.SecondaryFrame.LobbyList(self) + self.entry = BossLobbyGui.SecondaryFrame.LobbyEntry(self, command=self.loadItemsToList) + + self.items = [ + "Loudrob", + "Jake", + "Voltage", + "Daniel", + "Mel", + ] + + self.nameLabel = DirectLabel(parent=self, relief=None, text="Name:", text_scale=0.06, pos=(0.125, 0, 0.285)) + self.nameEntry = BossLobbyGui.SecondaryFrame.LobbyEntry(self, command=self.setLobbyName, pos=(0.27, 0, 0.285), width=9) + + self.friendLabel = DirectLabel(parent=self, relief=None, text="Friends Only?", text_scale=0.06, pos=(0.221, 0, 0.085)) + self.friendCheckbox = DirectButton(parent=self, relief=None, image=emptyList, pos=(0.62, 0, 0.095), scale=0.55, color=(1, 0, 0, 1), command=self.toggleFriendsOnly) + + self.laffLabel = DirectLabel(parent=self, relief=None, text="70+ Laff Only?", text_scale=0.06, pos=(0.251, 0, -0.115)) + self.laffCheckbox = DirectButton(parent=self, relief=None, image=emptyList, pos=(0.62, 0, -0.105), scale=0.55, color=(1, 0, 0, 1), command=self.toggleLaffLimit) + + self.cancelButton = DirectButton(parent=self, relief=None, image=cancelImageList, pos=(-0.65, 0, -0.535), scale=0.57, command=self.nextFrame, extraArgs=[False]) + self.nextButton = DirectButton(parent=self, relief=None, image=nextImageList, pos=(0.65, 0, -0.535), scale=0.3, command=self.nextFrame, extraArgs=[True]) + + def loadItemsToList(self, entryText): + if hasattr(self, 'lobbies') and self.lobbies: + self.lobbies.destroy() + self.lobbies = BossLobbyGui.SecondaryFrame.LobbyList(self) + toAdd = [] + for i in self.items: + if i.lower().startswith(entryText.lower()): + toAdd.append(i) + for i in sorted(toAdd): + newItem = BossLobbyGui.SecondaryFrame.LobbyListItem(self, i, self.setSelection) + self.lobbies.addItem(newItem) + + def setSelection(self, selection): + self.selection = selection + + def getSelection(self): + return self.selection + + def toggleFriendsOnly(self): + if self.friendsOnly: + self.friendsOnly = False + self.friendCheckbox.setColor(1, 0, 0, 1) + else: + self.friendsOnly = True + self.friendCheckbox.setColor(0, 1, 0, 1) + + def getFriendsOnly(self): + return self.friendsOnly + + def toggleLaffLimit(self): + if self.laffLimit: + self.laffLimit = False + self.laffCheckbox.setColor(1, 0, 0, 1) + else: + self.laffLimit = True + self.laffCheckbox.setColor(0, 1, 0, 1) + + def getLaffLimit(self): + return self.laffLimit + + def setLobbyName(self, name): + self.isCreating = bool(name) + self.lobbyName = name + + def getLobbyName(self): + return self.lobbyName + + def nextFrame(self, status): + if status: + if self.getSelection(): + options = { + 'selected': self.getSelection() + } + self.callback(self.frame + 1, options) + elif self.isCreating: + options = { + 'name': self.lobbyName, + 'friends': self.getFriendsOnly(), + 'laff': self.getLaffLimit(), + } + self.callback(self.frame + 1, options) + else: + self.callback(-1) + else: + self.callback(-1) + def __init__(self, callback, av): DirectFrame.__init__(self) self.callback = callback self.avatar = av self.frame = None - self.loadFrame(0) def destroy(self): if hasattr(self, 'frame') and self.frame: @@ -118,11 +337,23 @@ class BossLobbyGui(DirectFrame): if lobby == 0: self.callback(self.avatar, True) elif lobby == 1: + self.frame = BossLobbyGui.SecondaryFrame(self, self.loadFrame) + elif frameNum == 2: + selection = args.get('selected') + name = args.get('name') + if selection: self.callback(self.avatar, True) + elif name: + friendsOnly = args.get('friends') + laffLimit = args.get('laff') + self.callback(self.avatar, True) + else: + self.callback(self.avatar, False) # The following is made for use with the GUI editor. GUI_EDITOR = """ from toontown.coghq.BossLobbyGui import BossLobbyGui test = BossLobbyGui(None, None) +test.loadFrame(1, {'lobbyType': 1}) """ diff --git a/toontown/coghq/DistributedCogHQExteriorDoor.py b/toontown/coghq/DistributedCogHQExteriorDoor.py index 1388d968..d70d2ce1 100644 --- a/toontown/coghq/DistributedCogHQExteriorDoor.py +++ b/toontown/coghq/DistributedCogHQExteriorDoor.py @@ -16,6 +16,7 @@ class DistributedCogHQExteriorDoor(DistributedCogHQDoor.DistributedCogHQDoor): def selectLobby(self, avId): print("********\nCreating Lobby GUI...\n********") self.lobbyGui = BossLobbyGui(self.sendConfirmation, avId) + self.lobbyGui.loadFrame(0) def sendConfirmation(self, avId, status): self.lobbyGui.destroy() diff --git a/toontown/uberdog/DistributedLobbyManager.py b/toontown/uberdog/DistributedLobbyManager.py new file mode 100644 index 00000000..d291b079 --- /dev/null +++ b/toontown/uberdog/DistributedLobbyManager.py @@ -0,0 +1,70 @@ +from direct.directnotify import DirectNotifyGlobal +from direct.distributed.DistributedObject import DistributedObject + +class DistributedLobbyManager(DistributedObject): + neverDisable = 1 + notify = DirectNotifyGlobal.directNotify.newCategory('DistributedLobbyManager') + + def __init__(self, cr): + DistributedObject.__init__(self, cr) + base.cr.lobbyManager = self + self.allowUnreleased = False + + def delete(self): + DistributedObject.delete(self) + self.cr.lobbyManager = None + + def disable(self): + self.ignore('deallocateZoneIdFromPlannedLobby') + self.ignoreAll() + DistributedObject.disable(self) + + def generate(self): + DistributedObject.generate(self) + self.accept('deallocateZoneIdFromPlannedLobby', self.deallocateZoneIdFromPlannedLobby) + + def deallocateZoneIdFromPlannedLobby(self, zoneId): + self.sendUpdate('freeZoneIdFromPlannedLobby', [base.localAvatar.doId, zoneId]) + + def allowUnreleasedClient(self): + return self.allowUnreleased + + def setAllowUnreleaseClient(self, newValue): + self.allowUnreleased = newValue + + def toggleAllowUnreleasedClient(self): + self.allowUnreleased = not self.allowUnreleased + return self.allowUnreleased + + def sendAddLobby(self, hostId): + self.sendUpdate('addPartyRequest', [hostId]) + + def requestLobbyZone(self, avId, zoneId, callback): + if zoneId < 0: + zoneId = 0 + self.acceptOnce('requestLobbyZoneComplete', callback) + if hasattr(base.localAvatar, 'aboutToCreateLobby'): + if base.localAvatar.aboutToCreateLobby: + self.sendUpdate('getLobbyZone', [avId, zoneId, True]) + self.sendUpdate('getLobbyZone', [avId, zoneId, False]) + + def receiveLobbyZone(self, hostId, lobbyId, zoneId): + if lobbyId != 0 and zoneId != 0: + if base.localAvatar.doId == hostId: + lobbyInfo = base.localAvatar.hostedLobby: + if lobbyInfo.lobbyId == lobbyId: + lobbyInfo.status == LobbyGlobals.LobbyStatus.Open + messenger.send('requestLobbyZoneComplete', [hostId, lobbyId, zoneId]) + + def leaveLobby(self): + if self.isDisabled(): + return + self.sendUpdate('exitLobby', [localAvatar.zoneId]) + + def sendAvatarToLobby(self, hostId): + self.sendUpdate('requestShardIdZoneIdForHostId', [hostId]) + + def sendShardIdZoneIdToAvatar(self, shardId, zoneId): + # Avatar goes through door. + + diff --git a/toontown/uberdog/DistributedLobbyManagerAI.py b/toontown/uberdog/DistributedLobbyManagerAI.py new file mode 100644 index 00000000..6a39c443 --- /dev/null +++ b/toontown/uberdog/DistributedLobbyManagerAI.py @@ -0,0 +1,121 @@ +from direct.directnotify import DirectNotifyGlobal +from direct.distributed.DistributedObjectAI import DistributedObjectAI + +class DistributedLobbyManagerAI(DistributedObjectAI): + notify = DirectNotifyGlobal.directNotify.newCategory("DistributedLobbyManagerAI") + + def announceGenerate(self): + DistributedObjectAI.announceGenerate(self) + self.lobbyId2Zone = {} + self.lobbyId2PlanningZone = {} + self.lobbyId2Host = {} + self.host2LobbyId = {} + self.avId2LobbyId = {} + self.id2Lobby = {} + self.pubLobbyInfo = {} + self.idPool = range(self.air.ourChannel, self.air.ourChannel + 100000) + + def receiveId(self, ids): + self.idPool += ids + + def _makeLobbyDict(self, struct): + lobby = {} + lobby['lobbyId'] = struct[0] + lobby['hostId'] = struct[1] + return lobby + + def lobbyManagerUdStartingUp(self): + self.notify.info("LobbyManager UD is starting") + + def lobbyManagerUdLost(self): + self.notify.warning("LobbyManager UD is lost") + + def addLobbyRequest(self, hostId): + simbase.air.globalLobbyMgr.sendAddLobby(hostId, self.host2LobbyId[hostId]) + + def addLobbyResponseUdToAi(self, lobbyId, errorCode, lobbyStruct): + avId = lobbyStruct[1] + self.sendUpdateToAvatarId(avId, 'addLobbyResponse', [avId, errorCode]) + self.air.doId2do[avId].sendUpdate('setHostedLobby', [[lobbyStruct]]) + pass + + def getLobbyZone(self, hostId, zoneId, isAvAboutToCreateLobby): + avId = self.air.getAvatarIdFromSender() + if isAvAboutToCreateLobby: + lobbyId = self.idPool.pop() + self.lobbyId2Host[lobbyId] = hostId + self.lobbyId2PlanningZone[lobbyId] = zoneId + self.host2LobbyId[hostId] = lobbyId + else: + if hostId not in self.host2LobbyId: + self.air.globalLobbyMgr.queryLobbyForHost(hostId) + return + lobbyId = self.host2LobbyId[hostId] + if lobbyId in self.lobbyId2Zone: + zoneId = self.lobbyId2Zone[lobbyId] + self.sendUpdateToAvatarId(avId, 'receiveLobbyZone', [hostId, lobbyId, zoneId]) + + def lobbyInfoOfHostResponseUdToAi(self, lobbyStruct): + lobby = self._makeLobbyDict(lobbyStruct) + av = self.air.doId2do.get(lobby['hostId'], None) + if not av: + return + lobbyId = lobby['lobbyId'] + zoneId = self.air.allocateZone() + self.lobbyId2Zone[lobbyId] = zoneId + self.host2LobbyId[lobby['hostId']] = lobbyId + + lobbyAI = DistributedLobbyAI(self.air, lobby['hostId'], zoneId, lobby) + lobbyAI.generateWithRequiredAndId(self.air.allocateChannel(), self.air.districtId, zoneId) + self.id2Lobby[lobbyId] = lobbyAI + + self.air.globalLobbyMgr.d_lobbyStarted(lobbyId, self.air.ourChannel, zoneId, av.getName()) + self.sendUpdateToAvatarId(lobby['hostId'], 'receiveLobbyZone', [lobby['hostId'], lobbyId, zoneId]) + + def closeLobby(self, lobbyId): + lobbyAI = self.id2Lobby[lobbyId] + self.air.globalLobbyMgr.d_lobbyDone(lobbyId) + for av in lobbyAI.avIdsInLobby: + self.sendUpdateToAvatarId(av, 'sendAvToPlayground', [av, 0]) + lobbyAI.b_setLobbyState(LobbyStatus.Finished) + taskMgr.doMethodLater(10, self.__deleteLobby, 'closeLobby%d' % lobbyId, extraArgs=[lobbyId]) + + def __deleteLobby(self, lobbyId): + lobbyAI = self.id2Lobby[lobbyId] + for av in lobbyAI.avIdsAtLobby: + self.sendUpdateToAvatarId(av, 'sendAvToPlayground', [av, 1]) + lobbyAI.requestDelete() + zoneId = self.lobbyId2Zone[lobbyId] + del self.lobbyId2Zone[lobbyId] + del self.id2Lobby[lobbyId] + del self.pubLobbyInfo[lobbyId] + self.air.deallocateZone(zoneId) + + def freeZoneIdFromLobby(self, hostId, zoneId): + sender = self.air.getAvatarIdFromSender() + lobbyId = self.host2LobbyId[hostId] + if lobbyId in self.lobbyId2PlanningZone: + self.air.deallocateZone(self.lobbyId2PlanningZone[lobbyId]) + del self.lobbyId2PlanningZone[lobbyId] + del self.host2LobbyId[hostId] + del self.lobbyId2Host[lobbyId] + + def exitLobby(self, lobbyZone): + avId = simbase.air.getAvatarIdFromSender() + for lobbyInfo in self.pubLobbyInfo.values(): + if lobbyInfo['zoneId'] == lobbyZone: + lobby = self.id2Lobby.get(lobbyInfo['lobbyId']) + if lobby: + lobby._removeAvatar(avId) + + def getPublicLobbies(self): + p = [] + for lobbyId in self.pubLobbyInfo: + lobby = self.pubLobbyInfo[lobbyId] + toons = lobby.get('numToons', 0) + if toons > 255: + toons = 255 + elif toons < 0: + toons = 0 + p.append([lobby['shardId'], lobby['zoneId'], toons, lobby.get('hostName', '')]) + return p diff --git a/toontown/uberdog/DistributedLobbyManagerUD.py b/toontown/uberdog/DistributedLobbyManagerUD.py new file mode 100644 index 00000000..7fcb854a --- /dev/null +++ b/toontown/uberdog/DistributedLobbyManagerUD.py @@ -0,0 +1,9 @@ +from direct.directnotify import DirectNotifyGlobal +from direct.distributed.DistributedObjectUD import DistributedObjectUD + +class DistributedLobbyManagerUD(DistributedObjectUD): + notify = DirectNotifyGlobal.directNotify.newCategory("DistributedLobbyManagerUD") + + def announceGenerate(self): + DistributedObjectUD.announceGenerate(self) + self.sendUpdate('lobbyManagerUdStartingUp')