lobby manager and GUI update

This commit is contained in:
Zach 2015-05-30 06:16:23 -05:00
parent e560829a14
commit 097ea4942f
5 changed files with 434 additions and 2 deletions

View file

@ -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})
"""

View file

@ -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()

View file

@ -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.

View file

@ -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

View file

@ -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')