diff --git a/dependencies/astron/dclass/stride.dc b/dependencies/astron/dclass/stride.dc index 3900dbb4..b3c0921a 100644 --- a/dependencies/astron/dclass/stride.dc +++ b/dependencies/astron/dclass/stride.dc @@ -154,7 +154,7 @@ dclass DistributedPlayer : DistributedAvatar { setDISLid(uint32 = 0) broadcast ownrecv ram db airecv required; WishName(string = "") db ram; WishNameState(string = "OPEN") db ram; - setAdminAccess(uint16 = 0) broadcast ownrecv required airecv; + setAdminAccess(uint16 = 0) broadcast ownrecv required airecv db; setAsGM(bool = 0) required ram broadcast ownrecv airecv; }; @@ -3319,6 +3319,7 @@ struct Friend uint32 doId; string name; blob dna; +uint16 adminAccess; uint32 petId; }; diff --git a/otp/ai/MagicWordManagerAI.py b/otp/ai/MagicWordManagerAI.py index 9393001b..30d437ce 100755 --- a/otp/ai/MagicWordManagerAI.py +++ b/otp/ai/MagicWordManagerAI.py @@ -19,7 +19,7 @@ class MagicWordManagerAI(DistributedObjectAI): self.sendUpdateToAvatarId(invokerId, 'sendMagicWordResponse', ['missing invoker']) return - if invoker.getAdminAccess() < MINIMUM_MAGICWORD_ACCESS: + if not invoker.isAdmin(): self.air.writeServerEvent('suspicious', invokerId, 'Attempted to issue magic word: %s' % word) dg = PyDatagram() dg.addServerHeader(self.GetPuppetConnectionChannel(invokerId), self.air.ourChannel, CLIENTAGENT_EJECT) diff --git a/otp/avatar/Avatar.py b/otp/avatar/Avatar.py index a306fb7f..95191d1b 100755 --- a/otp/avatar/Avatar.py +++ b/otp/avatar/Avatar.py @@ -138,6 +138,9 @@ class Avatar(Actor, ShadowCaster): if hasattr(base, 'localAvatar') and (self == base.localAvatar): self.understandable = 1 self.setPlayerType(NametagGlobals.CCNormal) + elif hasattr(self, 'adminAccess') and self.isAdmin(): + self.understandable = 2 + self.setPlayerType(NametagGlobals.CCAdmin) elif self.playerType == NametagGlobals.CCSuit: self.understandable = 1 self.setPlayerType(NametagGlobals.CCSuit) diff --git a/otp/avatar/DistributedPlayer.py b/otp/avatar/DistributedPlayer.py index af3a1e7e..3a79bbd8 100755 --- a/otp/avatar/DistributedPlayer.py +++ b/otp/avatar/DistributedPlayer.py @@ -340,12 +340,16 @@ class DistributedPlayer(DistributedAvatar.DistributedAvatar, PlayerBase.PlayerBa def setAdminAccess(self, access): self.adminAccess = access + self.considerUnderstandable() if self.isLocal(): - self.cr.wantMagicWords = self.adminAccess >= MINIMUM_MAGICWORD_ACCESS + self.cr.wantMagicWords = self.isAdmin() def getAdminAccess(self): return self.adminAccess + def isAdmin(self): + return self.adminAccess >= MINIMUM_MAGICWORD_ACCESS + def setAutoRun(self, value): self.autoRun = value diff --git a/otp/avatar/DistributedPlayerAI.py b/otp/avatar/DistributedPlayerAI.py index 3d04d921..f306690d 100755 --- a/otp/avatar/DistributedPlayerAI.py +++ b/otp/avatar/DistributedPlayerAI.py @@ -8,7 +8,6 @@ from otp.avatar import PlayerBase from otp.distributed import OtpDoGlobals from otp.otpbase import OTPLocalizer - class DistributedPlayerAI(DistributedAvatarAI.DistributedAvatarAI, PlayerBase.PlayerBase): def __init__(self, air): DistributedAvatarAI.DistributedAvatarAI.__init__(self, air) @@ -100,6 +99,9 @@ class DistributedPlayerAI(DistributedAvatarAI.DistributedAvatarAI, PlayerBase.Pl def getAdminAccess(self): return self.adminAccess + + def isAdmin(self): + return self.adminAccess >= MINIMUM_MAGICWORD_ACCESS def extendFriendsList(self, friendId): if friendId in self.friendsList: diff --git a/toontown/distributed/ToontownClientRepository.py b/toontown/distributed/ToontownClientRepository.py index 080348df..90e2279c 100755 --- a/toontown/distributed/ToontownClientRepository.py +++ b/toontown/distributed/ToontownClientRepository.py @@ -664,9 +664,9 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository): else: handle = avatar else: - handle = FriendHandle.FriendHandle(doId, avatar.getName(), avatar.style, avatar.getPetId()) + handle = FriendHandle.FriendHandle(doId, avatar.getName(), avatar.style, avatar.adminAccess, avatar.getPetId()) else: - handle = FriendHandle.FriendHandle(doId, avatar.getName(), avatar.style, '') + handle = FriendHandle.FriendHandle(doId, avatar.getName(), avatar.style, avatar.adminAccess, '') teleportNotify.debug('adding %s to friendsMap' % doId) self.friendsMap[doId] = handle return handle @@ -739,8 +739,9 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository): dnaString = toon[2] dna = ToonDNA.ToonDNA() dna.makeFromNetString(dnaString) - petId = toon[3] - handle = FriendHandle.FriendHandle(doId, name, dna, petId) + adminAccess = toon[3] + petId = toon[4] + handle = FriendHandle.FriendHandle(doId, name, dna, adminAccess, petId) self.friendsMap[doId] = handle if doId in self.friendsOnline: self.friendsOnline[doId] = handle @@ -769,9 +770,10 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository): else: dna = ToonDNA.ToonDNA() dna.makeFromNetString(dnaString) - petId = toon[3] + adminAccess = toon[3] + petId = toon[4] if not abort: - handle = FriendHandle.FriendHandle(doId, name, dna, petId) + handle = FriendHandle.FriendHandle(doId, name, dna, adminAccess, petId) avatarHandleList.append(handle) if avatarHandleList: diff --git a/toontown/friends/FriendHandle.py b/toontown/friends/FriendHandle.py index 64fdbc21..e0627047 100755 --- a/toontown/friends/FriendHandle.py +++ b/toontown/friends/FriendHandle.py @@ -1,14 +1,14 @@ +from otp.ai.MagicWordGlobal import * from otp.avatar.Avatar import teleportNotify -from toontown.toonbase import ToontownGlobals -import copy from toontown.chat import ToonChatGarbler - +from toontown.toonbase import ToontownGlobals class FriendHandle: - def __init__(self, doId, name, style, petId, isAPet = False): + def __init__(self, doId, name, style, adminAccess, petId, isAPet = False): self.doId = doId self.style = style self.petId = petId + self.adminAccess = adminAccess self.isAPet = isAPet self.chatGarbler = ToonChatGarbler.ToonChatGarbler() self.name = name @@ -16,6 +16,12 @@ class FriendHandle: def getDoId(self): return self.doId + def getAdminAccess(self): + return self.adminAccess + + def isAdmin(self): + return self.adminAccess >= MINIMUM_MAGICWORD_ACCESS + def getPetId(self): return self.petId diff --git a/toontown/friends/TTSFriendsManagerUD.py b/toontown/friends/TTSFriendsManagerUD.py index 1736d62c..02e286dc 100755 --- a/toontown/friends/TTSFriendsManagerUD.py +++ b/toontown/friends/TTSFriendsManagerUD.py @@ -67,7 +67,7 @@ class FriendsListOperation(OperationFSM): friendId = self.friendsList[self.friendIndex] self.realFriendsList.append([friendId, fields['setName'][0], - fields['setDNAString'][0], fields['setPetId'][0]]) + fields['setDNAString'][0], fields['setAdminAccess'][0], fields['setPetId'][0]]) if len(self.realFriendsList) >= len(self.friendsList): self.result = self.realFriendsList diff --git a/toontown/nametag/NametagGlobals.py b/toontown/nametag/NametagGlobals.py index 8f6d3a3c..07769eee 100755 --- a/toontown/nametag/NametagGlobals.py +++ b/toontown/nametag/NametagGlobals.py @@ -8,6 +8,7 @@ CCToonBuilding = 3 CCSuitBuilding = 4 CCHouseBuilding = 5 CCSpeedChat = 6 +CCAdmin = 7 CHAT = 0 SPEEDCHAT = 1 @@ -180,6 +181,12 @@ NametagColors = { (VBase4(0.0, 0.5, 0.0, 1.0), VBase4(0.5, 0.5, 0.5, 0.1875)), # Down (VBase4(0.0, 0.7, 0.2, 1.0), VBase4(1.0, 1.0, 1.0, 0.5625)), # Rollover (VBase4(0.0, 0.6, 0.2, 1.0), VBase4(0.8, 0.8, 0.8, 0.375)) # Disabled + ), + CCAdmin: ( # Purple + (VBase4(0.7, 0.3, 0.7, 1.0), VBase4(0.8, 0.8, 0.8, 0.375)), # Normal + (VBase4(0.7, 0.3, 0.7, 1.0), VBase4(0.2, 0.2, 0.2, 0.1875)), # Down + (VBase4(1.0, 0.5, 0.9, 1.0), VBase4(1.0, 1.0, 1.0, 0.5625)), # Rollover + (VBase4(0.7, 0.3, 0.7, 1.0), VBase4(1.0, 1.0, 1.0, 0.375)) # Disabled ) } @@ -226,5 +233,11 @@ ChatColors = { (VBase4(1.0, 0.5, 0.5, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Down (VBase4(0.0, 0.6, 0.6, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Rollover (VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)) # Disabled + ), + CCAdmin: ( + (VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Normal + (VBase4(1.0, 0.5, 0.5, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Down + (VBase4(0.0, 0.6, 0.6, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Rollover + (VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)) # Disabled ) } diff --git a/toontown/pets/PetAvatarPanel.py b/toontown/pets/PetAvatarPanel.py index 2316985f..5e1204fc 100755 --- a/toontown/pets/PetAvatarPanel.py +++ b/toontown/pets/PetAvatarPanel.py @@ -10,7 +10,6 @@ from otp.avatar import Avatar, AvatarPanel from toontown.toon import ToonHead from toontown.toon import LaffMeter from toontown.toon import ToonAvatarDetailPanel -from toontown.friends import FriendHandle from toontown.toonbase import ToontownGlobals from toontown.toonbase import TTLocalizer from toontown.pets import Pet, PetConstants, PetDetailPanel diff --git a/toontown/toon/DistributedToonUD.py b/toontown/toon/DistributedToonUD.py index 91cdba0e..80fa0b77 100755 --- a/toontown/toon/DistributedToonUD.py +++ b/toontown/toon/DistributedToonUD.py @@ -4,6 +4,9 @@ from direct.distributed.DistributedObjectUD import DistributedObjectUD class DistributedToonUD(DistributedObjectUD): notify = DirectNotifyGlobal.directNotify.newCategory("DistributedToonUD") + def setAdminAccess(self, todo0): + pass + def setDNAString(self, todo0): pass diff --git a/toontown/toon/ToonAvatarPanel.py b/toontown/toon/ToonAvatarPanel.py index 9945d47a..b7b45412 100755 --- a/toontown/toon/ToonAvatarPanel.py +++ b/toontown/toon/ToonAvatarPanel.py @@ -3,7 +3,6 @@ from direct.gui.DirectGui import * from pandac.PandaModules import * from direct.showbase import DirectObject import ToonHead -from toontown.friends import FriendHandle import LaffMeter from otp.avatar import Avatar from direct.distributed import DistributedObject @@ -43,6 +42,7 @@ class ToonAvatarPanel(AvatarPanelBase.AvatarPanelBase): relief=None, pos=(-0.22, 0, -0.47), parent=base.a2dTopRight) + self.disabledImageColor = Vec4(1, 1, 1, 0.4) self.text0Color = Vec4(1, 1, 1, 1) self.text1Color = Vec4(0.5, 1, 0.5, 1) @@ -68,7 +68,6 @@ class ToonAvatarPanel(AvatarPanelBase.AvatarPanelBase): self.healthText.hide() - self.nameLabel = DirectLabel( parent=self.frame, pos=(0.0125, 0, 0.4), @@ -81,7 +80,6 @@ class ToonAvatarPanel(AvatarPanelBase.AvatarPanelBase): text_wordwrap=7.5, text_shadow=(1, 1, 1, 1)) - self.closeButton = DirectButton( parent=self.frame, image=( @@ -93,7 +91,6 @@ class ToonAvatarPanel(AvatarPanelBase.AvatarPanelBase): pos=(0.157644, 0, -0.379167), command=self.__handleClose) - self.friendButton = DirectButton( parent=self.frame, image=( @@ -115,9 +112,6 @@ class ToonAvatarPanel(AvatarPanelBase.AvatarPanelBase): text_align=TextNode.ALeft, command=self.__handleFriend) - if base.localAvatar.isIgnored(self.avId): - self.friendButton['state'] = DGG.DISABLED - self.goToButton = DirectButton( parent=self.frame, image=( @@ -139,11 +133,6 @@ class ToonAvatarPanel(AvatarPanelBase.AvatarPanelBase): text_align=TextNode.ALeft, command=self.__handleGoto) - - - if base.localAvatar.isIgnored(self.avId): - self.goToButton['state'] = DGG.DISABLED - self.whisperButton = DirectButton( parent=self.frame, image=( @@ -165,11 +154,6 @@ class ToonAvatarPanel(AvatarPanelBase.AvatarPanelBase): text_align=TextNode.ALeft, command=self.__handleWhisper) - - - if base.localAvatar.isIgnored(self.avId): - self.whisperButton['state'] = DGG.DISABLED - self.trueFriendsButton = DirectButton( parent=self.frame, image=( @@ -191,8 +175,6 @@ class ToonAvatarPanel(AvatarPanelBase.AvatarPanelBase): text_align=TextNode.ALeft, command=self.__handleTrueFriends) - if base.localAvatar.isIgnored(self.avId): - self.trueFriendsButton['state'] = DGG.DISABLED ignoreStr, ignoreCmd, ignoreScale = self.getIgnoreButtonInfo() self.ignoreButton = DirectButton( @@ -236,6 +218,15 @@ class ToonAvatarPanel(AvatarPanelBase.AvatarPanelBase): text_align=TextNode.ALeft, command=self.handleReport) + if avatar.isAdmin(): + self.trueFriendsButton['state'] = DGG.DISABLED + self.ignoreButton['state'] = DGG.DISABLED + self.reportButton['state'] = DGG.DISABLED + elif base.localAvatar.isIgnored(self.avId): + self.friendButton['state'] = DGG.DISABLED + self.goToButton['state'] = DGG.DISABLED + self.whisperButton['state'] = DGG.DISABLED + self.trueFriendsButton['state'] = DGG.DISABLED if not base.localAvatar.isTeleportAllowed(): self.goToButton['state'] = DGG.DISABLED @@ -509,6 +500,15 @@ class ToonAvatarPanel(AvatarPanelBase.AvatarPanelBase): return def __makePetGui(self, avatar): + if self.avatar.isAdmin(): + helpGui = loader.loadModel('phase_3.5/models/gui/tt_m_gui_brd_help') + image = (helpGui.find('**/tt_t_gui_brd_helpUp'), helpGui.find('**/tt_t_gui_brd_helpDown'), helpGui.find('**/tt_t_gui_brd_helpHover'), helpGui.find('**/tt_t_gui_brd_helpDown')) + text = ('', TTLocalizer.AvatarPanelCast, TTLocalizer.AvatarPanelCast, '') + self.petButton = DirectButton(parent=self.frame, image=image, relief=None, pos=(0.02, -0.2, -0.385), text=text, text_fg=self.text2Color, scale=0.8, + text_shadow=(0, 0, 0, 1), text_scale=0.07, text_pos=(0, -0.125), text_align=TextNode.ACenter, command=self.__handleCastDialog) + helpGui.removeNode() + return + petGui = loader.loadModel('phase_3.5/models/gui/PetControlPannel') self.petButton = DirectButton(parent=self.frame, image=(petGui.find('**/PetControlToonButtonUp1'), petGui.find('**/PetControlToonButtonDown1'), petGui.find('**/PetControlToonButtonRollover1')), geom=petGui.find('**/PetBattleIcon'), geom3_color=self.disabledImageColor, relief=None, pos=(0.22, -0.2, -0.475), text=('', TTLocalizer.AvatarPanelPet, @@ -519,7 +519,12 @@ class ToonAvatarPanel(AvatarPanelBase.AvatarPanelBase): self.petButton['state'] = DGG.DISABLED self.petButton.hide() petGui.removeNode() - return + + def __handleCastDialog(self): + self.cleanupDialog() + base.cr.playGame.getPlace().setState('stopped') + self.dialog = TTDialog.TTDialog(style=TTDialog.Acknowledge, text=TTLocalizer.AvatarPanelCastInfo % self.avatar.getName(), text_wordwrap=20, command=self.cleanupDialogAndWalk) + self.dialog.show() def __makeBoardingGui(self): self.confirmKickOutDialog = None diff --git a/toontown/toonbase/TTLocalizerEnglish.py b/toontown/toonbase/TTLocalizerEnglish.py index e4c567ed..c0d53b45 100755 --- a/toontown/toonbase/TTLocalizerEnglish.py +++ b/toontown/toonbase/TTLocalizerEnglish.py @@ -1940,6 +1940,8 @@ AvatarPanelGroupMerge = 'Resulting in' AvatarPanelGroupRetract = 'Retract Invitation' AvatarPanelGroupMember = 'Already In Group' AvatarPanelGroupMemberKick = 'Remove' +AvatarPanelCast = 'Cast Member' +AvatarPanelCastInfo = '%s is a Toontown United Cast Member.' ReportPanelTitle = 'Report A Toon' ReportPanelBody = 'This feature will send a complete report to a Moderator. Instead of sending a report, you might choose to do one of the following:\n\n - Teleport to another district\n - Use "Ignore" on the toon\'s panel\n\nDo you really want to report %s to a Moderator?' ReportPanelBodyFriends = 'This feature will send a complete report to a Moderator. Instead of sending a report, you might choose to do one of the following:\n\n - Teleport to another district\n - Break your friendship\n\nDo you really want to report %s to a Moderator?\n\n(This will also break your friendship)'