toontown-just-works/toontown/shtiker/ShardPage.py

501 lines
24 KiB
Python
Raw Normal View History

2024-07-07 18:08:39 -05:00
from direct.directnotify import DirectNotifyGlobal
from direct.gui.DirectGui import *
from direct.task.Task import Task
from panda3d.core import *
from toontown.distributed import ToontownDistrictStats
from toontown.hood import ZoneUtil
from toontown.shtiker import ShtikerPage
from toontown.coghq import CogDisguiseGlobals
from toontown.suit import SuitDNA
from toontown.suit import Suit
from toontown.toonbase import TTLocalizer
from toontown.toonbase import ToontownGlobals
from toontown.toontowngui import TTDialog
ICON_COLORS = (Vec4(0.863, 0.776, 0.769, 1.0), Vec4(0.749, 0.776, 0.824, 1.0),
Vec4(0.749, 0.769, 0.749, 1.0), Vec4(0.843, 0.745, 0.745, 1.0))
POP_COLORS = (Vec4(0.4, 0.4, 1.0, 1.0), Vec4(0.4, 1.0, 0.4, 1.0),
Vec4(1.0, 0.4, 0.4, 1.0))
def compareShardTuples(a, b):
if a[1] < b[1]:
return -1
elif b[1] < a[1]:
return 1
else:
return 0
def setupInvasionMarkerAny(node):
pass
def setupInvasionMarker(node, invasionStatus):
if node.find('**/*invasion-marker'):
return
markerNode = node.attachNewNode('invasion-marker')
if invasionStatus == 5:
setupInvasionMarkerAny(markerNode)
return
icons = loader.loadModel('phase_3/models/gui/cog_icons')
iconStatus = invasionStatus - 1
if iconStatus in SuitDNA.suitDeptModelPaths:
icon = icons.find(SuitDNA.suitDeptModelPaths[iconStatus]).copyTo(markerNode)
icons.removeNode()
icon.setColor(ICON_COLORS[iconStatus])
icon.setPos(0.50, 0, 0.0125)
icon.setScale(0.0535)
def removeInvasionMarker(node):
markerNode = node.find('**/*invasion-marker')
if not markerNode.isEmpty():
markerNode.removeNode()
class ShardPage(ShtikerPage.ShtikerPage):
notify = DirectNotifyGlobal.directNotify.newCategory('ShardPage')
def __init__(self):
ShtikerPage.ShtikerPage.__init__(self)
self.shardButtonMap = {}
self.shardButtons = []
self.scrollList = None
self.currentBTP = None
self.currentBTL = None
self.currentBTR = None
self.currentBTI = None
self.currentO = None
self.textRolloverColor = Vec4(1, 1, 0, 1)
self.textDownColor = Vec4(0.5, 0.9, 1, 1)
self.textDisabledColor = Vec4(0.4, 0.8, 0.4, 1)
self.ShardInfoUpdateInterval = 5.0
self.lowPop = config.GetInt('shard-low-pop', 150)
self.midPop = config.GetInt('shard-mid-pop', 300)
self.highPop = -1
self.showPop = config.GetBool('show-population', 0)
self.showTotalPop = config.GetBool('show-total-population', 0)
self.noTeleport = config.GetBool('shard-page-disable', 0)
self.shardGroups = []
self.shardText = []
self.groupDialog = None
def load(self):
matchGui = loader.loadModel('phase_3.5/models/gui/matching_game_gui')
main_text_scale = 0.06
title_text_scale = 0.12
self.title = DirectLabel(parent=self, relief=None, text=TTLocalizer.ShardPageTitle, text_scale=title_text_scale, textMayChange=0, pos=(0, 0, 0.6))
helpText_ycoord = 0.403
self.helpText = DirectLabel(parent=self, relief=None, text='', text_scale=main_text_scale, text_wordwrap=12, text_align=TextNode.ALeft, textMayChange=1, pos=(0.058, 0, helpText_ycoord))
shardPop_ycoord = helpText_ycoord - 0.523
totalPop_ycoord = shardPop_ycoord - 0.44
self.districtInfo = NodePath('Selected-Shard-Info')
self.districtInfo.reparentTo(self)
self.preferredButton = DirectButton(parent=self, relief=None, image=matchGui.find('**/minnieCircle'), pos=(0.1, 0, -0.575), scale=0.35, text=TTLocalizer.ShardPagePreferred, text_scale=0.11, text_pos=(0, -0.2), command=self.setPreferredShard)
self.totalPopulationText = DirectLabel(parent=self.districtInfo, relief=None, text=TTLocalizer.ShardPagePopulationTotal % 1, text_scale=main_text_scale, text_wordwrap=8, textMayChange=1, text_align=TextNode.ACenter, pos=(0.4247, 0, totalPop_ycoord))
if self.showTotalPop:
self.totalPopulationText.show()
else:
self.totalPopulationText.hide()
self.gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui')
self.listXorigin = -0.02
self.listFrameSizeX = 0.67
self.listZorigin = -0.96
self.listFrameSizeZ = 1.04
self.arrowButtonScale = 1.3
self.itemFrameXorigin = -0.247
self.itemFrameZorigin = 0.365
self.buttonXstart = self.itemFrameXorigin + 0.293
self.regenerateScrollList()
scrollTitle = DirectFrame(parent=self.scrollList, text=TTLocalizer.ShardPageScrollTitle, text_scale=main_text_scale, text_align=TextNode.ACenter, relief=None, pos=(self.buttonXstart, 0, self.itemFrameZorigin + 0.127))
matchGui.removeNode()
def firstLoadShard(self, buttonTuple):
curShardTuples = base.cr.listActiveShards()
curShardTuples.sort(compareShardTuples)
actualShardId = base.localAvatar.defaultShard
for i in xrange(len(curShardTuples)):
shardId, name, pop, invasionStatus, groupAvCount = curShardTuples[i]
if shardId == actualShardId:
self.currentBTP = buttonTuple[0]
self.currentBTL = buttonTuple[1]
self.currentBTR = buttonTuple[2]
self.currentBTI = buttonTuple[3]
self.currentO = [pop, name, shardId]
self.currentBTL['state'] = DGG.DISABLED
self.currentBTR['state'] = DGG.DISABLED
self.reloadRightBrain(pop, name, groupAvCount, shardId, buttonTuple)
def unload(self):
self.gui.removeNode()
del self.title
self.scrollList.destroy()
del self.scrollList
del self.shardButtons
taskMgr.remove('ShardPageUpdateTask-doLater')
ShtikerPage.ShtikerPage.unload(self)
def regenerateScrollList(self):
selectedIndex = 0
if self.scrollList:
selectedIndex = self.scrollList.getSelectedIndex()
for button in self.shardButtons:
button.detachNode()
self.scrollList.destroy()
self.scrollList = None
self.scrollList = DirectScrolledList(parent=self, relief=None, pos=(-0.51, 0, 0), incButton_image=(self.gui.find('**/FndsLst_ScrollUp'),
self.gui.find('**/FndsLst_ScrollDN'),
self.gui.find('**/FndsLst_ScrollUp_Rllvr'),
self.gui.find('**/FndsLst_ScrollUp')), incButton_relief=None, incButton_scale=(self.arrowButtonScale, self.arrowButtonScale, -self.arrowButtonScale), incButton_pos=(self.buttonXstart + 0.005, 0, self.itemFrameZorigin - 1.000), incButton_image3_color=Vec4(1, 1, 1, 0.2), decButton_image=(self.gui.find('**/FndsLst_ScrollUp'),
self.gui.find('**/FndsLst_ScrollDN'),
self.gui.find('**/FndsLst_ScrollUp_Rllvr'),
self.gui.find('**/FndsLst_ScrollUp')), decButton_relief=None, decButton_scale=(self.arrowButtonScale, self.arrowButtonScale, self.arrowButtonScale), decButton_pos=(self.buttonXstart, 0.0025, self.itemFrameZorigin + 0.130), decButton_image3_color=Vec4(1, 1, 1, 0.2), itemFrame_pos=(self.itemFrameXorigin, 0, self.itemFrameZorigin), itemFrame_scale=1.0, itemFrame_relief=DGG.SUNKEN, itemFrame_frameSize=(self.listXorigin,
self.listXorigin + self.listFrameSizeX,
self.listZorigin,
self.listZorigin + self.listFrameSizeZ), itemFrame_frameColor=(0.85, 0.95, 1, 1), itemFrame_borderWidth=(0.01, 0.01), numItemsVisible=15, forceHeight=0.065, items=self.shardButtons)
self.scrollList.scrollTo(selectedIndex)
def askForShardInfoUpdate(self, task = None):
ToontownDistrictStats.refresh('shardInfoUpdated')
taskMgr.doMethodLater(self.ShardInfoUpdateInterval, self.askForShardInfoUpdate, 'ShardPageUpdateTask-doLater')
return Task.done
def makeShardButton(self, shardId, groupAvCount, shardName, shardPop):
shardButtonParent = DirectFrame()
shardButtonL = DirectButton(parent=shardButtonParent, relief=None, text=shardName, text_scale=0.06, text_align=TextNode.ALeft, text_fg=Vec4(0, 0, 0, 1), text3_fg=self.textDisabledColor, text1_bg=self.textDownColor, text2_bg=self.textRolloverColor, textMayChange=0, command=self.reloadRightBrain)
popText = str(shardPop)
if popText is None:
popText = ''
model = loader.loadModel('phase_3.5/models/gui/matching_game_gui')
button = model.find('**/minnieCircle')
shardButtonR = DirectButton(parent=shardButtonParent, relief=None,
image=button,
image_scale=(0.3, 1, 0.3),
image2_scale=(0.35, 1, 0.35),
image_color=self.getPopColor(shardPop),
pos=(0.58, 0, 0.0125),
text=popText,
text_scale=0.06,
text_align=TextNode.ARight,
text_pos=(-0.14, -0.0165), text_fg=Vec4(0, 0, 0, 1), text3_fg=self.textDisabledColor, text1_bg=self.textRolloverColor, text2_bg=self.textRolloverColor, textMayChange=1, command=self.reloadRightBrain)
model.removeNode()
button.removeNode()
invasionMarker = NodePath('InvasionMarker-%s' % shardId)
invasionMarker.reparentTo(shardButtonParent)
buttonTuple = (shardButtonParent, shardButtonR, shardButtonL, invasionMarker)
shardButtonL['extraArgs'] = extraArgs=[shardPop, shardName, groupAvCount, shardId, buttonTuple]
shardButtonR['extraArgs'] = extraArgs=[shardPop, shardName, groupAvCount, shardId, buttonTuple]
return buttonTuple
def makeGroupButton(self, shardId, group, population):
groupButtonParent = DirectFrame()
groupButtonL = DirectButton(parent=groupButtonParent, relief=None, text=TTLocalizer.GlobalStreetNames[group][-1], text_pos=(0.0, -0.0225), text_scale=0.048, text_align=TextNode.ALeft, text_fg=Vec4(0, 0, 0, 1), text3_fg=self.textDisabledColor, text1_bg=self.textDownColor, text2_bg=self.textRolloverColor, command=self.joinGroup, extraArgs=[group, shardId])
groupButtonR = DirectButton(parent=groupButtonParent, relief=None,
pos=(0.58, 0, -0.0125),
text=str(population),
text_scale=0.055,
text_align=TextNode.ACenter,
command=self.joinGroup,
extraArgs=[group, shardId],
text_pos=(-0.00575, -0.0125), text_fg=Vec4(0, 0, 0, 1), text3_fg=Vec4(0, 0, 0, 1), text1_bg=self.textRolloverColor, text2_bg=self.textRolloverColor)
return (groupButtonParent, groupButtonL, groupButtonR)
def joinGroup(self, group, shardId):
canonicalHoodId = ZoneUtil.getCanonicalHoodId(group)
shardName = base.cr.activeDistrictMap[shardId].name
hoodName = TTLocalizer.GlobalStreetNames[canonicalHoodId]
teleportAccess = base.localAvatar.hasTeleportAccess(canonicalHoodId)
if teleportAccess:
message = TTLocalizer.GroupAskAccess
elif base.localAvatar.defaultShard == shardId:
self.acceptOnce('groupDialogDone', self.cleanupGroupDialog)
self.groupDialog = TTDialog.TTGlobalDialog(style=TTDialog.Acknowledge, text=TTLocalizer.GroupAskNoAccessSame % (hoodName[0], hoodName[-1]), doneEvent='groupDialogDone')
self.groupDialog.show()
return
else:
message = TTLocalizer.GroupAskNoAccess
self.acceptOnce('groupDialogDone', self.__handleGroupDialog, extraArgs=[canonicalHoodId if teleportAccess else base.localAvatar.lastHood, shardId])
self.groupDialog = TTDialog.TTGlobalDialog(style=TTDialog.TwoChoice, text=message % (hoodName[0], hoodName[-1], shardName), doneEvent='groupDialogDone')
self.groupDialog.show()
def cleanupGroupDialog(self):
self.ignore('groupDialogDone')
self.groupDialog.cleanup()
del self.groupDialog
def __handleGroupDialog(self, canonicalHoodId, shardId):
response = self.groupDialog.doneStatus
self.cleanupGroupDialog()
if response == 'ok':
self.requestTeleport(canonicalHoodId, shardId)
def removeRightBrain(self):
self.districtInfo.find('**/*district-info').removeNode()
def reloadRightBrain(self, shardPop, shardName, groupAvCount, shardId, buttonTuple):
self.currentRightBrain = (shardPop, shardName, shardId, buttonTuple)
if self.districtInfo.find('**/*district-info'):
self.removeRightBrain()
if self.currentBTL:
self.currentBTL['state'] = DGG.NORMAL
if self.currentBTR:
self.currentBTR['state'] = DGG.NORMAL
popText = self.getPopText(shardPop)
districtInfoNode = self.districtInfo.attachNewNode('district-info')
self.districtStatusLabel = DirectLabel(parent=districtInfoNode, relief=None, pos=(0.4247, 0, 0.45), text=popText, text_scale=0.09, text_fg=Vec4(0, 0, 0, 1), textMayChange=1)
pText = TTLocalizer.ShardPageShardTitle % (shardName, str(shardPop))
self.populationStatusLabel = DirectLabel(parent=districtInfoNode, relief=None, pos=(0.4247, 0, 0.38), text=pText, text_scale=0.04, text_fg=Vec4(0, 0, 0, 1), textMayChange=1)
tText = TTLocalizer.ShardPageTeleport % shardName
tImage = loader.loadModel('phase_4/models/gui/purchase_gui')
tImage.setSz(1.35)
self.shardTeleportButton = DirectButton(parent=districtInfoNode, relief=None, pos=(0.4247, 0, 0.25), image=(tImage.find('**/PurchScrn_BTN_UP'), tImage.find('**/PurchScrn_BTN_DN'), tImage.find('**/PurchScrn_BTN_RLVR')), text=tText, text_scale=0.065, text_pos=(0.0, 0.015), text_fg=Vec4(0, 0, 0, 1), textMayChange=1, command=self.choseShard, extraArgs=[shardId])
self.currentBTP = buttonTuple[0]
self.currentBTL = buttonTuple[1]
self.currentBTR = buttonTuple[2]
self.currentBTI = buttonTuple[3]
self.currentO = [shardPop, shardName, shardId]
self.currentBTL['state'] = DGG.DISABLED
self.currentBTR['state'] = DGG.DISABLED
self.preferredButton.setColor((0, 1, 0, 1) if settings.get('preferredShard') == shardName else (1, 0, 0, 1))
if shardId == base.localAvatar.defaultShard:
self.shardTeleportButton['state'] = DGG.DISABLED
for button in self.shardGroups + self.shardText:
button.removeNode()
self.shardGroups = []
self.shardText = []
for i, group in enumerate(ToontownGlobals.GROUP_ZONES):
btuple = self.makeGroupButton(shardId, group, groupAvCount[i])
if ZoneUtil.getCanonicalHoodId(base.localAvatar.zoneId) == ZoneUtil.getCanonicalHoodId(group):
btuple[1]['state'] = DGG.DISABLED
btuple[2]['state'] = DGG.DISABLED
self.shardGroups.append(btuple[0])
self.shardText.append(btuple[2])
buttonImage = (self.gui.find('**/FndsLst_ScrollUp'), self.gui.find('**/FndsLst_ScrollDN'), self.gui.find('**/FndsLst_ScrollUp_Rllvr'), self.gui.find('**/FndsLst_ScrollUp'))
self.districtGroups = DirectScrolledList(parent=districtInfoNode, relief=None,
pos=(0.38, 0, -0.34),
incButton_image=buttonImage,
incButton_relief=None,
incButton_scale=(self.arrowButtonScale,
self.arrowButtonScale,
-self.arrowButtonScale),
incButton_pos=(self.buttonXstart + 0.005, 0, -0.125),
incButton_image3_color=Vec4(1, 1, 1, 0.2),
decButton_image=buttonImage,
decButton_relief=None,
decButton_scale=(self.arrowButtonScale,
self.arrowButtonScale,
self.arrowButtonScale),
decButton_pos=(self.buttonXstart, 0.0025, 0.445),
decButton_image3_color=Vec4(1, 1, 1, 0.2),
itemFrame_pos=(self.itemFrameXorigin, 0, self.itemFrameZorigin),
itemFrame_scale=1.0,
itemFrame_relief=DGG.SUNKEN,
itemFrame_frameSize=(self.listXorigin,
(self.listXorigin + self.listFrameSizeX),
self.listZorigin/2.1,
(self.listZorigin + self.listFrameSizeZ)/2.1),
itemFrame_frameColor=(0.85, 0.95, 1, 1),
itemFrame_borderWidth=(0.01, 0.01),
numItemsVisible=7,
forceHeight=0.065,
items=self.shardGroups)
def getPopColor(self, pop):
if pop <= self.lowPop:
newColor = POP_COLORS[0]
elif pop <= self.midPop:
newColor = POP_COLORS[1]
else:
newColor = POP_COLORS[2]
return newColor
def getPopText(self, pop):
if pop <= self.lowPop:
popText = TTLocalizer.ShardPageLow
elif pop <= self.midPop:
popText = TTLocalizer.ShardPageMed
else:
popText = TTLocalizer.ShardPageHigh
return popText
def getPopChoiceHandler(self, pop):
if pop <= self.midPop:
if self.noTeleport and not self.showPop:
handler = self.shardChoiceReject
else:
handler = self.choseShard
elif self.showPop:
handler = self.choseShard
else:
if localAvatar.isAdmin():
handler = self.choseShard
else:
handler = self.shardChoiceReject
return handler
def getCurrentZoneId(self):
try:
zoneId = base.cr.playGame.getPlace().getZoneId()
except:
zoneId = None
return zoneId
def createSuitHead(self, suitName):
suitDNA = SuitDNA.SuitDNA()
suitDNA.newSuit(suitName)
suit = Suit.Suit()
suit.setDNA(suitDNA)
headParts = suit.getHeadParts()
head = hidden.attachNewNode('head')
for part in headParts:
copyPart = part.copyTo(head)
copyPart.setDepthTest(1)
copyPart.setDepthWrite(1)
self.fitGeometry(head, fFlip=1)
suit.delete()
suit = None
return head
def updateScrollList(self):
curShardTuples = base.cr.listActiveShards()
curShardTuples.sort(compareShardTuples)
actualShardId = base.localAvatar.defaultShard
actualShardName = None
anyChanges = 0
totalPop = 0
currentMap = {}
self.shardButtons = []
for i in xrange(len(curShardTuples)):
shardId, name, pop, invasionStatus, groupAvCount = curShardTuples[i]
if shardId == actualShardId:
actualShardName = name
totalPop += pop
currentMap[shardId] = 1
buttonTuple = self.shardButtonMap.get(shardId)
if buttonTuple == None:
buttonTuple = self.makeShardButton(shardId, groupAvCount, name, pop)
self.shardButtonMap[shardId] = buttonTuple
anyChanges = 1
else:
buttonTuple[1]['image_color'] = self.getPopColor(pop)
buttonTuple[1]['text'] = str(pop)
buttonTuple[1]['command'] = self.reloadRightBrain
buttonTuple[1]['extraArgs'] = [pop, name, groupAvCount, shardId, buttonTuple]
buttonTuple[2]['command'] = self.reloadRightBrain
buttonTuple[2]['extraArgs'] = [pop, name, groupAvCount, shardId, buttonTuple]
for i, button in enumerate(self.shardText):
button['text'] = str(groupAvCount[i])
self.shardButtons.append(buttonTuple[0])
if invasionStatus:
setupInvasionMarker(buttonTuple[3], invasionStatus)
else:
removeInvasionMarker(buttonTuple[3])
for shardId, buttonTuple in self.shardButtonMap.items():
if shardId not in currentMap:
buttonTuple[3].removeNode()
buttonTuple[0].destroy()
del self.shardButtonMap[shardId]
anyChanges = 1
if anyChanges:
self.regenerateScrollList()
self.totalPopulationText['text'] = TTLocalizer.ShardPagePopulationTotal % totalPop
helpText = TTLocalizer.ShardPageHelpIntro
if actualShardName:
helpText += TTLocalizer.ShardPageHelpWhere % actualShardName
if not self.book.safeMode:
helpText += TTLocalizer.ShardPageHelpMove
def enter(self):
self.askForShardInfoUpdate()
self.updateScrollList()
currentShardId = base.localAvatar.defaultShard
buttonTuple = self.shardButtonMap.get(currentShardId)
if buttonTuple:
i = self.shardButtons.index(buttonTuple[0])
self.scrollList.scrollTo(i, centered=1)
self.firstLoadShard(buttonTuple)
ShtikerPage.ShtikerPage.enter(self)
self.accept('shardInfoUpdated', self.updateScrollList)
def exit(self):
for shardId, buttonTuple in self.shardButtonMap.items():
buttonTuple[1]['state'] = DGG.NORMAL
buttonTuple[2]['state'] = DGG.NORMAL
self.ignore('shardInfoUpdated')
self.ignore('ShardPageConfirmDone')
taskMgr.remove('ShardPageUpdateTask-doLater')
ShtikerPage.ShtikerPage.exit(self)
def shardChoiceReject(self, shardId):
self.confirm = TTDialog.TTGlobalDialog(doneEvent='ShardPageConfirmDone', message=TTLocalizer.ShardPageChoiceReject, style=TTDialog.Acknowledge)
self.confirm.show()
self.accept('ShardPageConfirmDone', self.__handleConfirm)
def __handleConfirm(self):
self.ignore('ShardPageConfirmDone')
self.confirm.cleanup()
del self.confirm
def choseShard(self, shardId):
if not base.localAvatar.defaultShard == shardId:
self.requestTeleport(base.localAvatar.lastHood, shardId)
def requestTeleport(self, hood, shardId):
canonicalHoodId = ZoneUtil.getCanonicalHoodId(hood)
try:
place = base.cr.playGame.getPlace()
except:
try:
place = base.cr.playGame.hood.loader.place
except:
place = base.cr.playGame.hood.place
place.requestTeleport(canonicalHoodId, canonicalHoodId, shardId, -1)
def setPreferredShard(self):
if settings.get('preferredShard', '') == self.currentO[1]:
self.preferredButton.setColor(1, 0, 0, 1)
del settings['preferredShard']
else:
self.preferredButton.setColor(0, 1, 0, 1)
settings['preferredShard'] = self.currentO[1]