Merge branch 'estates' into 'beta-wip'

Cattlelogs

While they aren't entirely done, they are certainly stable enough to begin testing. We can easily add things in as time goes on.
This commit is contained in:
Hawkheart 2014-08-12 19:16:41 -06:00
commit abfc22a3d7
54 changed files with 1415 additions and 438 deletions

View file

@ -48,8 +48,10 @@ dc-file config/otp.dc
want-pets #f
want-news-tab #f
want-news-page #f
want-accessories #f
want-parties #f
want-gardening #f
want-gardening #t
want-gifting #f
# This is a temporary 'fix' for DistributedSmoothNodes... probably not the permanent solution to our problem, but it works for now.
smooth-lag 0.4
want-keep-alive #f

View file

@ -58,6 +58,7 @@ want-pets #f
want-news-tab #f
want-news-page #f
want-gardening #f
want-gifting #f
# This is a temporary 'fix' for DistributedSmoothNodes... probably not the permanent solution to our problem, but it works for now.
smooth-lag 0.4
want-keep-alive #f

View file

@ -446,7 +446,7 @@ dclass DistributedToon : DistributedPlayer {
setWebAccountId(uint32 webId = 0) required airecv;
setDNAString(blob dnaString) required broadcast ownrecv db;
setGM(uint8 type = 0) required broadcast ownrecv db;
setMaxBankMoney(int16 maxMoney = 1200) required broadcast ownrecv db;
setMaxBankMoney(int16 maxMoney = 15000) required broadcast ownrecv db;
setBankMoney(int16 money = 0) required broadcast ownrecv db;
setMaxMoney(int16 maxMoney = 40) required broadcast ownrecv db;
setMoney(int16 money = 0) required broadcast ownrecv db;
@ -531,8 +531,8 @@ dclass DistributedToon : DistributedPlayer {
setDisguisePageFlag(int8 flag) ownrecv;
setSosPageFlag(int8 flag) ownrecv;
setHouseId(uint32 id = 0) required ownrecv db;
setQuests(uint32 flattenedQuests[] = [175, 401000019, 1000, 100, 1]) required broadcast ownrecv db;
setQuestHistory(uint16 questList[] = [175]) required ownrecv db;
setQuests(uint32 flattenedQuests[] = []) required broadcast ownrecv db;
setQuestHistory(uint16 questList[] = []) required ownrecv db;
setRewardHistory(uint8 rewardTier = 0, uint16 rewardList[] = [100]) required ownrecv db;
setQuestCarryLimit(uint8 limit = 1) required ownrecv db;
requestDeleteQuest(uint32 questDesc[]) ownsend airecv;
@ -608,7 +608,7 @@ dclass DistributedToon : DistributedPlayer {
logMessage(char message[0-1024]) ownsend airecv;
forceLogoutWithNotify() ownrecv;
setPinkSlips(uint8 pinkSlips = 0) required ownrecv db;
setNametagStyle(uint8 nametagStyle = 0) broadcast required ram db;
setNametagStyle(uint8 nametagStyle = 100) required broadcast ownrecv db;
setMail(simpleMail mail[]) ownrecv;
setNumMailItems(uint32 numMailItems) airecv;
setSimpleMailNotify(uint8 simpleMailNotify) ownrecv airecv;
@ -1279,6 +1279,7 @@ dclass DistributedHouse : DistributedObject {
setAvatarId(uint32 toonId = 0) required broadcast db;
setName(string toonName = "") required broadcast db;
setColor(uint8 colorIndex = 0) required broadcast db;
setGender(uint8 genderIndex = 1) required;
setAtticItems(blob atticItems = "") required db;
setInteriorItems(blob interiorItems = "") required db;
setAtticWallpaper(blob atticWallpaper = "") required db;

View file

@ -17,8 +17,10 @@ csmud-secret Yv1JrpTUdkX6M86h44Z9q4AUaQYdFnectDgl2I5HOQf8CBh7LUZWpzKB9FBD
want-bbhq #f
want-pets #f
want-parties #f
want-accessories #f
want-golf #f
want-gardening #f
want-gifting #f
want-keep-alive #f

View file

@ -39,6 +39,7 @@ class Avatar(Actor, ShadowCaster):
Actor.__init__(self, None, None, other, flattenable=0, setFinal=0)
ShadowCaster.__init__(self)
self.__font = OTPGlobals.getInterfaceFont()
self.__speechFont = OTPGlobals.getInterfaceFont()
self.soundChatBubble = None
self.avatarType = ''
self.nametagNodePath = None
@ -46,6 +47,7 @@ class Avatar(Actor, ShadowCaster):
self.nametag = NametagGroup()
self.nametag.setAvatar(self)
self.nametag.setFont(OTPGlobals.getInterfaceFont())
self.nametag.setSpeechFont(OTPGlobals.getInterfaceFont())
self.nametag2dContents = Nametag.CName | Nametag.CSpeech
self.nametag2dDist = Nametag.CName | Nametag.CSpeech
self.nametag2dNormalContents = Nametag.CName | Nametag.CSpeech
@ -91,6 +93,7 @@ class Avatar(Actor, ShadowCaster):
self.ignoreNametagAmbientLightChange()
self.Avatar_deleted = 1
del self.__font
del self.__speechFont
del self.style
del self.soundChatBubble
self.nametag.destroy()
@ -252,6 +255,13 @@ class Avatar(Actor, ShadowCaster):
self.__font = font
self.nametag.setFont(font)
def getSpeechFont(self):
return self.__speechFont
def setSpeechFont(self, font):
self.__speechFont = font
self.nametag.setSpeechFont(font)
def getStyle(self):
return self.style

View file

@ -1,6 +1,7 @@
from NametagConstants import *
import NametagGlobals
from otp.margins.ClickablePopup import ClickablePopup
from otp.otpbase import OTPGlobals
from pandac.PandaModules import *
class Nametag(ClickablePopup):
@ -29,6 +30,7 @@ class Nametag(ClickablePopup):
self.chatWordWrap = None
self.font = None
self.speechFont = None
self.name = ''
self.displayName = ''
self.qtColor = VBase4(1,1,1,1)
@ -91,13 +93,16 @@ class Nametag(ClickablePopup):
self.showName()
def showBalloon(self, balloon, text):
if not self.speechFont:
# If no font is set, we can't display anything yet...
return
color = self.qtColor if (self.chatFlags&CFQuicktalker) else self.chatBg
if color[3] > self.CHAT_ALPHA:
color = (color[0], color[1], color[2], self.CHAT_ALPHA)
reversed = (self.IS_3D and (self.chatFlags&CFReversed))
balloon, frame = balloon.generate(text, self.font, textColor=self.chatFg,
balloon, frame = balloon.generate(text, self.speechFont, textColor=self.chatFg,
balloonColor=color,
wordWrap=self.chatWordWrap or \
self.DEFAULT_CHAT_WORDWRAP,

View file

@ -26,6 +26,7 @@ class NametagGroup:
self.chatTimeoutTask = None
self.font = None
self.speechFont = None
self.name = ''
self.displayName = ''
self.wordWrap = None
@ -141,6 +142,10 @@ class NametagGroup:
self.font = font
self.updateTags()
def setSpeechFont(self, font):
self.speechFont = font
self.updateTags()
def setWordwrap(self, wrap):
self.wordWrap = wrap
self.updateTags()
@ -227,6 +232,7 @@ class NametagGroup:
def updateNametag(self, tag):
tag.font = self.font
tag.speechFont = self.speechFont
tag.name = self.name
tag.wordWrap = self.wordWrap or DEFAULT_WORDWRAPS[self.colorCode]
tag.displayName = self.displayName or self.name

@ -1 +1 @@
Subproject commit 306c0a3a03d1474891fda914ab439afd9cddd531
Subproject commit 0f45fb2ac5a1aec318c2e2a4f3118714cac7b0e6

View file

@ -56,6 +56,9 @@ from toontown.suit.SuitInvasionManagerAI import SuitInvasionManagerAI
# Toontorial
from toontown.tutorial.TutorialManagerAI import TutorialManagerAI
# Catalogs.
from toontown.catalog.CatalogManagerAI import CatalogManagerAI
# Magic Words!
from panda3d.core import PStatClient
from otp.ai.MagicWordGlobal import *
@ -79,7 +82,7 @@ class ToontownAIRepository(ToontownInternalRepository):
self.zoneDataStore = AIZoneDataStore()
self.useAllMinigames = self.config.GetBool('want-all-minigames', False)
self.doLiveUpdates = False
self.doLiveUpdates = self.config.GetBool('want-live-updates', True)
self.holidayManager = HolidayManagerAI(self)
@ -188,6 +191,9 @@ class ToontownAIRepository(ToontownInternalRepository):
self.tutorialManager = TutorialManagerAI(self)
self.tutorialManager.generateWithRequired(2)
self.catalogManager = CatalogManagerAI(self)
self.catalogManager.generateWithRequired(2)
def createZones(self):
"""

View file

@ -16,7 +16,6 @@ from pymongo.errors import AutoReconnect
class DistributedBuildingMgrAI:
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedBuildingMgrAI')
serverDatafolder = simbase.config.GetString('server-data-folder', '')
def __init__(self, air, branchID, dnaStore, trophyMgr):
self.branchID = branchID

View file

@ -19,20 +19,23 @@ class CatalogAccessoryItem(CatalogItem.CatalogItem):
return 1
def notOfferedTo(self, avatar):
article = AccessoryTypes[self.accessoryType][ATArticle]
if article in [AHat,
AGlasses,
ABackpack,
AShoes]:
return 0
forBoys = article in [ABoysHat,
ABoysGlasses,
ABoysBackpack,
ABoysShoes]
if avatar.getStyle().getGender() == 'm':
return not forBoys
else:
return forBoys
if simbase.config.GetBool('want-accessories', 1):
article = AccessoryTypes[self.accessoryType][ATArticle]
if article in [AHat,
AGlasses,
ABackpack,
AShoes]:
return 0
forBoys = article in [ABoysHat,
ABoysGlasses,
ABoysBackpack,
ABoysShoes]
if avatar.getStyle().getGender() == 'm':
return not forBoys
else:
return forBoys
# If we get here, we probably don't want accessories yet.
return 1
def forBoysOnly(self):
article = AccessoryTypes[self.accessoryType][ATArticle]

View file

@ -17,7 +17,8 @@ ABoysShorts = 3
AGirlsShorts = 4
AGirlsSkirt = 5
AShorts = 6
ClothingTypes = {101: (ABoysShirt, 'bss1', 40),
ClothingTypes = {
101: (ABoysShirt, 'bss1', 40),
102: (ABoysShirt, 'bss2', 40),
103: (ABoysShirt, 'bss3', 40),
105: (ABoysShirt, 'bss4', 40),

View file

@ -115,7 +115,7 @@ class CatalogFlooringItem(CatalogSurfaceItem):
if versionNumber < 4 or store & CatalogItem.Customization:
self.colorIndex = di.getUint8()
else:
self.colorIndex = None
self.colorIndex = 0
wtype = FlooringTypes[self.patternIndex]
return

View file

@ -18,66 +18,39 @@ FLIsTable = 32
FLPhone = 64
FLBillboard = 128
FLTrunk = 256
furnitureColors = [(0.792,
0.353,
0.29,
1.0),
(0.176,
0.592,
0.439,
1.0),
(0.439,
0.424,
0.682,
1.0),
(0.325,
0.58,
0.835,
1.0),
(0.753,
0.345,
0.557,
1.0),
(0.992,
0.843,
0.392,
1.0)]
woodColors = [(0.933,
0.773,
0.569,
1.0),
(0.9333,
0.6785,
0.055,
1.0),
(0.545,
0.451,
0.333,
1.0),
(0.541,
0.0,
0.0,
1.0),
(0.5451,
0.2706,
0.0745,
1.0),
(0.5451,
0.4118,
0.4118,
1.0)]
BankToMoney = {1300: 12000,
1310: 12000,
1320: 12000,
1330: 12000,
1340: 12000,
1350: 12000}
FLBoysOnly = 512
FLGirlsOnly = 1024
furnitureColors = [
(0.792, 0.353, 0.29, 1.0),
(0.176, 0.592, 0.439, 1.0),
(0.439, 0.424, 0.682, 1.0),
(0.325, 0.58, 0.835, 1.0),
(0.753, 0.345, 0.557, 1.0),
(0.992, 0.843, 0.392, 1.0)
]
woodColors = [
(0.933, 0.773, 0.569, 1.0),
(0.9333, 0.6785, 0.055, 1.0),
(0.545, 0.451, 0.333, 1.0),
(0.541, 0.0, 0.0, 1.0),
(0.5451, 0.2706, 0.0745, 1.0),
(0.5451, 0.4118, 0.4118, 1.0)
]
BankToMoney = {
1300: 15000,
1310: 15000,
1320: 15000,
1330: 15000,
1340: 15000,
1350: 15000
}
MoneyToBank = {}
for bankId, maxMoney in BankToMoney.items():
MoneyToBank[maxMoney] = bankId
MaxBankId = 1350
ClosetToClothes = {500: 10,
ClosetToClothes = {
500: 10,
502: 15,
504: 20,
506: 25,
@ -86,7 +59,8 @@ ClosetToClothes = {500: 10,
512: 15,
514: 20,
516: 25,
518: 50}
518: 50
}
ClothesToCloset = {}
for closetId, maxClothes in ClosetToClothes.items():
if not ClothesToCloset.has_key(maxClothes):
@ -96,10 +70,13 @@ for closetId, maxClothes in ClosetToClothes.items():
MaxClosetIds = (508, 518)
MaxTrunkIds = (4000, 4010)
FurnitureTypes = {100: ('phase_5.5/models/estate/chairA',
None,
None,
80),
FurnitureTypes = {
100: ('phase_5.5/models/estate/chairA', # Model
None, # Color
None, # Color Options
80), # Base Price
# Flags
# Scale
105: ('phase_5.5/models/estate/chairAdesat',
None,
{0: (('**/cushion*', furnitureColors[0]), ('**/arm*', furnitureColors[0])),
@ -187,7 +164,8 @@ FurnitureTypes = {100: ('phase_5.5/models/estate/chairA',
210: ('phase_5.5/models/estate/girly_bed',
None,
None,
450),
450,
FLGirlsOnly),
220: ('phase_5.5/models/estate/bathtub_bed',
None,
None,
@ -231,7 +209,8 @@ FurnitureTypes = {100: ('phase_5.5/models/estate/chairA',
410: ('phase_5.5/models/estate/FireplaceGirlee',
None,
None,
800),
800,
FLGirlsOnly),
420: ('phase_5.5/models/estate/FireplaceRound',
None,
None,
@ -273,7 +252,7 @@ FurnitureTypes = {100: ('phase_5.5/models/estate/chairA',
None,
None,
1100,
None,
FLGirlsOnly,
None,
0.5),
491: ('phase_5.5/models/estate/tt_m_prp_int_fireplace_bugRoom',
@ -903,7 +882,8 @@ FurnitureTypes = {100: ('phase_5.5/models/estate/chairA',
None,
None,
200,
FLPainting)}
FLPainting)
}
class CatalogFurnitureItem(CatalogAtticItem.CatalogAtticItem):
@ -944,8 +924,24 @@ class CatalogFurnitureItem(CatalogAtticItem.CatalogAtticItem):
return not forBoys
else:
return forBoys
if self.forBoysOnly():
if avatar.getStyle().getGender() == 'm':
return 0
else:
return 1
elif self.forGirlsOnly():
if avatar.getStyle().getGender() == 'f':
return 0
else:
return 1
return 0
def forBoysOnly(self):
return self.getFlags() & FLBoysOnly > 0
def forGirlsOnly(self):
return self.getFlags() & FLGirlsOnly > 0
def isDeletable(self):
return self.getFlags() & (FLBank | FLCloset | FLPhone | FLTrunk) == 0
@ -1168,15 +1164,18 @@ def getAllClosets():
def get50ItemTrunk(avatar, duplicateItems):
if avatar.getStyle().getGender() == 'm':
index = 0
else:
index = 1
trunkId = MaxTrunkIds[index]
item = CatalogFurnitureItem(trunkId)
if item in avatar.onOrder or item in avatar.mailboxContents:
return None
return item
if simbase.config.GetBool('want-accessories', 1):
if avatar.getStyle().getGender() == 'm':
index = 0
else:
index = 1
trunkId = MaxTrunkIds[index]
item = CatalogFurnitureItem(trunkId)
if item in avatar.onOrder or item in avatar.mailboxContents:
return None
return item
# If we get here, we probably don't want accessories yet.
return None
def getMaxTrunks():

View file

@ -33,10 +33,10 @@ class CatalogGardenStarterItem(CatalogItem.CatalogItem):
print 'rental-- record purchase'
if avatar:
print 'starter garden-- has avater'
estate = simbase.air.estateMgr.estate.get(avatar.doId)
estate = simbase.air.estateManager.toon2estate.get(avatar)
if estate:
print 'starter garden-- has estate'
estate.placeStarterGarden(avatar.doId)
estate.placeStarterGarden(avatar)
else:
print 'starter garden-- something not there'
return ToontownGlobals.P_ItemAvailable

View file

@ -40,20 +40,25 @@ MetaItems = {100: getAllClothes(101, 102, 103, 104, 105, 106, 107, 108, 109, 109
2921: getChatRange(12050, 12099),
2930: getChatRange(13000, 13099),
2940: getChatRange(14000, 14099),
3000: getWallpapers(1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2100),
3010: getWallpapers(2200, 2300, 2400, 2500, 2600, 2700, 2800),
3020: getWallpapers(2900, 3000, 3100, 3200, 3300, 3400, 3500, 3600),
3030: getWallpapers(3700, 3800, 3900),
3500: getAllWainscotings(1000, 1010),
3510: getAllWainscotings(1020),
3520: getAllWainscotings(1030),
3530: getAllWainscotings(1040),
4000: getFloorings(1000, 1010, 1020, 1030, 1040, 1050, 1060, 1070, 1080, 1090, 1100),
4010: getFloorings(1110, 1120, 1130),
4020: getFloorings(1140, 1150, 1160, 1170, 1180, 1190),
4500: getAllMouldings(1000, 1010),
4510: getAllMouldings(1020, 1030, 1040),
4520: getAllMouldings(1070),
5000: getAllPetTricks()}
MetaItemChatKeysSold = (2000,
2010,
@ -397,22 +402,34 @@ MonthlySchedule = ((7,
1,
9,
30,
(CatalogGardenItem(135, 1),)),
(
# CatalogGardenItem(135, 1)
)
),
(1,
1,
1,
31,
(CatalogGardenItem(135, 1),)),
(
# CatalogGardenItem(135, 1)
)
),
(4,
1,
4,
30,
(CatalogGardenItem(135, 1),)),
(
# CatalogGardenItem(135, 1)
)
),
(6,
1,
6,
30,
(CatalogGardenItem(135, 1),)),
(
# CatalogGardenItem(135, 1)
)
),
(6,
26,
7,
@ -432,8 +449,8 @@ MonthlySchedule = ((7,
4,
(CatalogFurnitureItem(680),
CatalogFurnitureItem(681),
CatalogGardenItem(130, 1),
CatalogGardenItem(131, 1),
# CatalogGardenItem(130, 1),
# CatalogGardenItem(131, 1),
CatalogAnimatedFurnitureItem(10020),
CatalogFurnitureItem(10030, 0))),
(12,
@ -507,13 +524,14 @@ MonthlySchedule = ((7,
1,
12,
31,
(CatalogGardenItem(100, 1),
CatalogGardenItem(101, 1),
CatalogGardenItem(103, 1),
CatalogGardenItem(104, 1),
CatalogToonStatueItem(105, endPoseIndex=108),
CatalogRentalItem(1, 2880, 1000),
CatalogGardenStarterItem(),
(
# CatalogGardenItem(100, 1),
# CatalogGardenItem(101, 1),
# CatalogGardenItem(103, 1),
# CatalogGardenItem(104, 1),
# CatalogToonStatueItem(105, endPoseIndex=108),
# CatalogRentalItem(1, 2880, 1000),
# CatalogGardenStarterItem(), # We don't want Gardens yet.
CatalogNametagItem(100),
CatalogNametagItem(0),
CatalogClothingItem(1608, 0, 720),
@ -597,8 +615,8 @@ MonthlySchedule = ((7,
((3, 2910),
CatalogFurnitureItem(680),
CatalogFurnitureItem(681),
CatalogGardenItem(130, 1),
CatalogGardenItem(131, 1),
# CatalogGardenItem(130, 1),
# CatalogGardenItem(131, 1),
CatalogAnimatedFurnitureItem(10020),
CatalogFurnitureItem(10030, 0),
CatalogWallpaperItem(11000),

View file

@ -1,9 +1,31 @@
from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from CatalogGenerator import CatalogGenerator
from toontown.toonbase import ToontownGlobals
import time
class CatalogManagerAI(DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory("CatalogManagerAI")
def __init__(self, air):
DistributedObjectAI.__init__(self, air)
self.catalogGenerator = CatalogGenerator()
def startCatalog(self):
pass
avId = self.air.getAvatarIdFromSender()
av = self.air.doId2do.get(avId)
if av:
self.deliverCatalogFor(av)
def deliverCatalogFor(self, av):
monthlyCatalog = self.catalogGenerator.generateMonthlyCatalog(av, time.time() / 60)
newWeek = (av.catalogScheduleCurrentWeek + 1) % ToontownGlobals.CatalogNumWeeks
weeklyCatalog = self.catalogGenerator.generateWeeklyCatalog(av, newWeek, monthlyCatalog)
backCatalog = self.catalogGenerator.generateBackCatalog(av, newWeek, av.catalogScheduleCurrentWeek, monthlyCatalog)
av.b_setCatalog(monthlyCatalog, weeklyCatalog, backCatalog)
av.b_setCatalogSchedule(newWeek, int((time.time() + 604800)/60))
av.b_setCatalogNotify(ToontownGlobals.NewItems, av.mailboxNotify)
def isItemReleased(self, accessory):
return 1

View file

@ -3,7 +3,7 @@ from toontown.toonbase import ToontownGlobals
from toontown.toonbase import TTLocalizer
from direct.gui.DirectGui import *
from pandac.PandaModules import *
CatalogNotifyBaseXPos = 0.4
CatalogNotifyBaseXPos = -0.93
class CatalogNotifyDialog:
notify = DirectNotifyGlobal.directNotify.newCategory('CatalogNotifyDialog')
@ -15,7 +15,7 @@ class CatalogNotifyDialog:
from toontown.toon import LocalToon
if LocalToon.WantNewsPage:
framePosX += LocalToon.AdjustmentForNewsButton
self.frame = DirectFrame(relief=None, sortOrder=DGG.BACKGROUND_SORT_INDEX - 2, image=DGG.getDefaultDialogGeom(), image_color=ToontownGlobals.GlobalDialogColor, image_scale=(1.2, 1.0, 0.4), text=message[0], text_wordwrap=16, text_scale=0.06, text_pos=(-0.1, 0.1), pos=(framePosX, 0, 0.78))
self.frame = DirectFrame(relief=None, parent=base.a2dTopRight, sortOrder=DGG.BACKGROUND_SORT_INDEX - 2, image=DGG.getDefaultDialogGeom(), image_color=ToontownGlobals.GlobalDialogColor, image_scale=(1.2, 1.0, 0.4), text=message[0], text_wordwrap=16, text_scale=0.06, text_pos=(-0.1, 0.1), pos=(framePosX, 0, -0.22))
buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui')
cancelImageList = (buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr'))
okImageList = (buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr'))

View file

@ -17,6 +17,7 @@ class CatalogPetTrickItem(CatalogItem.CatalogItem):
return 1
def reachedPurchaseLimit(self, avatar):
return 1 # until we have pets
if self in avatar.onOrder or self in avatar.mailboxContents or self in avatar.onGiftOrder or self in avatar.awardMailboxContents or self in avatar.onAwardOrder:
return 1
return self.trickId in avatar.petTrickPhrases
@ -44,9 +45,9 @@ class CatalogPetTrickItem(CatalogItem.CatalogItem):
def getPicture(self, avatar):
from toontown.pets import PetDNA, Pet
pet = Pet.Pet(forGui=1)
dna = avatar.petDNA
if dna == None:
dna = PetDNA.getRandomPetDNA()
#dna = avatar.petDNA
i#f dna == None:
dna = PetDNA.getRandomPetDNA() # another temphack
pet.setDNA(dna)
pet.setH(180)
model, ival = self.makeFrameModel(pet, 0)

View file

@ -50,7 +50,7 @@ class CatalogRentalItem(CatalogItem.CatalogItem):
self.notify.debug('rental -- record purchase')
if avatar:
self.notify.debug('rental -- has avater')
estate = simbase.air.estateMgr.estate.get(avatar.doId)
estate = simbase.air.estateManager.toon2estate.get(avatar)
if estate:
self.notify.debug('rental -- has estate')
estate.rentItem(self.typeIndex, self.duration)

View file

@ -14,6 +14,8 @@ from direct.actor import Actor
import random
from toontown.toon import DistributedToon
from direct.directnotify import DirectNotifyGlobal
from otp.nametag.ChatBalloon import ChatBalloon
from otp.nametag import NametagGroup
NUM_CATALOG_ROWS = 3
NUM_CATALOG_COLS = 2
CatalogPanelCenters = [[Point3(-0.95, 0, 0.91), Point3(-0.275, 0, 0.91)], [Point3(-0.95, 0, 0.275), Point3(-0.275, 0, 0.275)], [Point3(-0.95, 0, -0.4), Point3(-0.275, 0, -0.4)]]
@ -62,6 +64,10 @@ class CatalogScreen(DirectFrame):
self.hide()
self.clarabelleChatNP = None
self.clarabelleChatBalloon = None
self.clarabelleGreetingSfx = None
self.clarabelleGoodbyeSfx = None
self.clarabelleErrorSfx = None
self.clarabelleChatterSfx = None
self.gifting = -1
self.createdGiftGui = None
self.viewing = None
@ -75,11 +81,12 @@ class CatalogScreen(DirectFrame):
self.accept(localAvatar.uniqueName('emblemsChange'), self.__emblemChange)
deliveryText = 'setDeliverySchedule-%s' % base.localAvatar.doId
self.accept(deliveryText, self.remoteUpdate)
base.setBackgroundColor(Vec4(0.529, 0.290, 0.286, 1))
render.hide()
DirectFrame.show(self)
def clarabelleGreeting(task):
self.setClarabelleChat(TTLocalizer.CatalogGreeting)
self.setClarabelleChat(TTLocalizer.CatalogGreeting, type='greeting')
def clarabelleHelpText1(task):
self.setClarabelleChat(TTLocalizer.CatalogHelpText1)
@ -103,6 +110,7 @@ class CatalogScreen(DirectFrame):
self.ignore(localAvatar.uniqueName('emblemsChange'))
deliveryText = 'setDeliverySchedule-%s' % base.localAvatar.doId
self.ignore(deliveryText)
base.setBackgroundColor(ToontownGlobals.DefaultBackgroundColor)
render.show()
DirectFrame.hide(self)
@ -296,7 +304,7 @@ class CatalogScreen(DirectFrame):
page = self.emblemPageList[self.pageIndex]
newOrBackOrLoyalty = 3
page.show()
for panel in self.panelDict[page.id()]:
for panel in self.panelDict[page.get_key()]:
panel.load()
if panel.ival:
panel.ival.loop()
@ -436,9 +444,9 @@ class CatalogScreen(DirectFrame):
pageList.append(page)
item.reparentTo(page)
item.setPos(CatalogPanelCenters[i][j])
itemList = self.panelDict.get(page.id(), [])
itemList = self.panelDict.get(page.get_key(), [])
itemList.append(item)
self.panelDict[page.id()] = itemList
self.panelDict[page.get_key()] = itemList
j += 1
if j == NUM_CATALOG_COLS:
j = 0
@ -544,8 +552,9 @@ class CatalogScreen(DirectFrame):
self.emblemCatalogButton2.hide()
self.__makeFFlist()
if len(self.ffList) > 0:
self.giftToggle = DirectButton(self.base, relief=None, pressEffect=0, image=(giftToggleUp, giftToggleDown, giftToggleUp), image_scale=(1.0, 1, 0.7), command=self.__giftToggle, text=TTLocalizer.CatalogGiftToggleOff, text_font=ToontownGlobals.getSignFont(), text_pos=TTLocalizer.CSgiftTogglePos, text_scale=TTLocalizer.CSgiftToggle, text_fg=(0.353, 0.627, 0.627, 1.0), text3_fg=(0.15, 0.3, 0.3, 1.0), text2_fg=(0.353, 0.427, 0.427, 1.0), image_color=Vec4(1.0, 1.0, 0.2, 1.0), image1_color=Vec4(0.9, 0.85, 0.2, 1.0), image2_color=Vec4(0.9, 0.85, 0.2, 1.0), image3_color=Vec4(0.5, 0.45, 0.2, 1.0))
self.giftToggle.setPos(0.0, 0, -0.035)
if config.GetBool('want-gifting', True):
self.giftToggle = DirectButton(self.base, relief=None, pressEffect=0, image=(giftToggleUp, giftToggleDown, giftToggleUp), image_scale=(1.0, 1, 0.7), command=self.__giftToggle, text=TTLocalizer.CatalogGiftToggleOff, text_font=ToontownGlobals.getSignFont(), text_pos=TTLocalizer.CSgiftTogglePos, text_scale=TTLocalizer.CSgiftToggle, text_fg=(0.353, 0.627, 0.627, 1.0), text3_fg=(0.15, 0.3, 0.3, 1.0), text2_fg=(0.353, 0.427, 0.427, 1.0), image_color=Vec4(1.0, 1.0, 0.2, 1.0), image1_color=Vec4(0.9, 0.85, 0.2, 1.0), image2_color=Vec4(0.9, 0.85, 0.2, 1.0), image3_color=Vec4(0.5, 0.45, 0.2, 1.0))
self.giftToggle.setPos(0.0, 0, -0.035)
self.giftLabel = DirectLabel(self.base, relief=None, image=giftFriends, image_scale=(1.15, 1, 1.14), text=' ', text_font=ToontownGlobals.getSignFont(), text_pos=(1.2, -0.97), text_scale=0.07, text_fg=(0.392, 0.549, 0.627, 1.0), sortOrder=100, textMayChange=1)
self.giftLabel.setPos(-0.15, 0, 0.08)
self.giftLabel.hide()
@ -683,7 +692,7 @@ class CatalogScreen(DirectFrame):
self.clarabelleFrame = DirectLabel(self, relief=None, image=guiItems.find('**/clarabelle_frame'))
hangupGui = guiItems.find('**/hangup')
hangupRolloverGui = guiItems.find('**/hangup_rollover')
self.hangup = DirectButton(self, relief=None, pos=(1.78, 0, -1.3), image=[hangupGui,
self.hangup = DirectButton(base.a2dBottomRight, relief=None, pos=(-0.158, 0, 0.14), scale=(0.7, 0.7, 0.7), image=[hangupGui,
hangupRolloverGui,
hangupRolloverGui,
hangupGui], text=['', TTLocalizer.CatalogHangUp, TTLocalizer.CatalogHangUp], text_fg=Vec4(1), text_scale=0.07, text_pos=(0.0, 0.14), command=self.hangUp)
@ -718,7 +727,7 @@ class CatalogScreen(DirectFrame):
self.cCamNode.setLens(self.cLens)
self.cCamNode.setScene(self.cRender)
self.cCam = self.cCamera.attachNewNode(self.cCamNode)
self.cDr = base.win.makeDisplayRegion(0.58, 0.82, 0.53, 0.85)
self.cDr = base.win.makeDisplayRegion(0.56, 0.81, 0.52, 0.85)
self.cDr.setSort(1)
self.cDr.setClearDepthActive(1)
self.cDr.setClearColorActive(1)
@ -733,10 +742,24 @@ class CatalogScreen(DirectFrame):
self.clarabelle.find('**/glassR').setBin('fixed', 2)
switchboard = loader.loadModel('phase_5.5/models/estate/switchboard')
switchboard.reparentTo(self.clarabelle)
switchboard.setPos(0, -2, 0)
switchboard.setPos(1, -1.6, 0)
switchboard.setH(30)
room = loader.loadModel('phase_3/models/makeatoon/tt_m_ara_mat_room.bam')
room.reparentTo(self.clarabelle)
room.find('**/genderProps').removeNode()
room.find('**/bodyWalls').removeNode()
room.find('**/bodyProps').removeNode()
room.find('**/colorWalls').removeNode()
room.find('**/colorProps').removeNode()
room.find('**/clothWalls').removeNode()
room.find('**/nameWalls').removeNode()
room.find('**/nameProps').removeNode()
room.find('**/spotlight').removeNode()
room.setPos(5.5, 1.25, 0)
room.setH(330)
self.clarabelle.reparentTo(self.cRender)
self.clarabelle.setPosHprScale(-0.56, 6.43, -3.81, 121.61, 0.0, 0.0, 1.0, 1.0, 1.0)
self.clarabelleFrame.setPosHprScale(-0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0)
self.clarabelle.setPosHprScale(-0.52, 6.13, -3.81, 85, 0.0, 0.0, 1.0, 1.0, 1.0)
self.clarabelleFrame.setPosHprScale(-0.01, 0.0, -0.01, 0.0, 0.0, 0.0, 1.02, 1.0, 1.02)
def reload(self):
for panel in self.panelList + self.backPanelList + self.loyaltyPanelList + self.emblemPanelList:
@ -804,6 +827,7 @@ class CatalogScreen(DirectFrame):
if self.giftAvatar:
base.cr.cancelAvatarDetailsRequest(self.giftAvatar)
self.hide()
self.hangup.hide()
self.destroy()
del self.base
del self.squares
@ -855,10 +879,30 @@ class CatalogScreen(DirectFrame):
self.clarabelle.cleanup()
del self.clarabelle
if self.clarabelleChatBalloon:
self.clarabelleChatBalloon.removeNode()
del self.clarabelleChatBalloon
if self.clarabelleGreetingSfx:
for sound in self.clarabelleGreetingSfx:
del sound
del self.clarabelleGreetingSfx
if self.clarabelleGoodbyeSfx:
for sound in self.clarabelleGoodbyeSfx:
del sound
del self.clarabelleGoodbyeSfx
if self.clarabelleErrorSfx:
for sound in self.clarabelleGoodbyeSfx:
del sound
del self.clarabelleGoodbyeSfx
if self.clarabelleChatterSfx:
for sound in self.clarabelleChatterSfx:
del sound
del self.clarabelleChatterSfx
def hangUp(self):
if hasattr(self, 'giftAvatar') and self.giftAvatar:
self.giftAvatar.disable()
self.setClarabelleChat(random.choice(TTLocalizer.CatalogGoodbyeList))
self.setClarabelleChat(random.choice(TTLocalizer.CatalogGoodbyeList), type='goodbye')
self.setPageIndex(-1)
self.showPageItems()
self.nextPageButton.hide()
@ -929,13 +973,41 @@ class CatalogScreen(DirectFrame):
self.responseDialog = None
return
def setClarabelleChat(self, str, timeout = 6):
def setClarabelleChat(self, str, timeout = 6, type = None):
self.clearClarabelleChat()
# Clarabelle can talk now! Let's give her some variation.
if type == 'greeting':
if not self.clarabelleGreetingSfx:
clarabelleGreeting1 = base.loadSfx('phase_5.5/audio/dial/clarabelle_ah_1.ogg')
clarabelleGreeting2 = base.loadSfx('phase_5.5/audio/dial/clarabelle_ah_2.ogg')
self.clarabelleGreetingSfx = [clarabelleGreeting1, clarabelleGreeting2]
base.playSfx(random.choice(self.clarabelleGreetingSfx))
elif type == 'goodbye':
if not self.clarabelleGoodbyeSfx:
clarabelleGoodbye1 = base.loadSfx('phase_5.5/audio/dial/clarabelle_wa_2.ogg')
clarabelleGoodbye2 = base.loadSfx('phase_5.5/audio/dial/clarabelle_wa_3.ogg')
clarabelleGoodbye3 = base.loadSfx('phase_5.5/audio/dial/clarabelle_wa_4.ogg')
self.clarabelleGoodbyeSfx = [clarabelleGoodbye1, clarabelleGoodbye2, clarabelleGoodbye3]
base.playSfx(random.choice(self.clarabelleGoodbyeSfx))
elif type == 'error':
if not self.clarabelleErrorSfx:
clarabelleError1 = base.loadSfx('phase_5.5/audio/dial/clarabelle_ah_2.ogg')
self.clarabelleChatterSfx = [clarabelleError1]
base.playSfx(random.choice(self.clarabelleErrorSfx))
else:
# These are currently placeholders.
if not self.clarabelleChatterSfx:
clarabelleChatter1 = base.loadSfx('phase_5.5/audio/dial/clarabelle_ah_2.ogg')
clarabelleChatter2 = base.loadSfx('phase_5.5/audio/dial/clarabelle_gen_2.ogg')
self.clarabelleChatterSfx = [clarabelleChatter1, clarabelleChatter2]
base.playSfx(random.choice(self.clarabelleChatterSfx))
if not self.clarabelleChatBalloon:
self.clarabelleChatBalloon = loader.loadModel('phase_3/models/props/chatbox')
self.clarabelleChat = ChatBalloon(self.clarabelleChatBalloon.node())
chatNode = self.clarabelleChat.generate(str, ToontownGlobals.getInterfaceFont(), 10, Vec4(0, 0, 0, 1), Vec4(1, 1, 1, 1), 0, 0, 0, NodePath(), 0, 0, NodePath())
self.clarabelleChatNP = self.attachNewNode(chatNode, 1000)
self.clarabelleChat = ChatBalloon(self.clarabelleChatBalloon)
chatNode = self.clarabelleChat.generate(str, ToontownGlobals.getInterfaceFont())[0]
self.clarabelleChatNP = self.attachNewNode(chatNode.node(), 1000)
self.clarabelleChatNP.setScale(0.08)
self.clarabelleChatNP.setPos(0.7, 0, 0.6)
if timeout:
@ -1028,8 +1100,20 @@ class CatalogScreen(DirectFrame):
self.scrollList.refresh()
def makeFamilyButton(self, familyId, familyName, colorCode):
fg = NametagGlobals.getNameFg(colorCode, PGButton.SInactive)
return DirectButton(relief=None, text=familyName, text_scale=0.04, text_align=TextNode.ALeft, text_fg=fg, text1_bg=self.textDownColor, text2_bg=self.textRolloverColor, text3_fg=self.textDisabledColor, textMayChange=0, command=self.__chooseFriend, extraArgs=[familyId, familyName])
# fg = NametagGlobals.getNameFg(colorCode, PGButton.SInactive)
return DirectButton(
relief=None,
text=familyName,
text_scale=0.04,
text_align=TextNode.ALeft,
# text_fg=fg,
text1_bg=self.textDownColor,
text2_bg=self.textRolloverColor,
text3_fg=self.textDisabledColor,
textMayChange=0,
command=self.__chooseFriend,
extraArgs=[familyId, familyName]
)
def __chooseFriend(self, friendId, friendName):
messenger.send('wakeup')

View file

@ -32,3 +32,4 @@ class CatalogSurfaceItem(CatalogAtticItem.CatalogAtticItem):
def getDeliveryTime(self):
return 60

View file

@ -664,11 +664,11 @@ class CatalogWallpaperItem(CatalogSurfaceItem):
def decodeDatagram(self, di, versionNumber, store):
CatalogAtticItem.CatalogAtticItem.decodeDatagram(self, di, versionNumber, store)
self.colorIndex = None
self.colorIndex = 0
if store & CatalogItem.Customization:
self.borderIndex = 0
else:
self.borderIndex = None
self.borderIndex = 0
self.borderColorIndex = 0
if versionNumber < 3:
self.patternIndex = di.getUint8()

View file

@ -39,8 +39,9 @@ class DNAFurnitureReaderAI:
# house to the default furniture arrangement.
notify = DirectNotifyGlobal.directNotify.newCategory("DNAFurnitureReaderAI")
def __init__(self, dnaData):
def __init__(self, dnaData, phonePos):
self.dnaData = dnaData
self.phonePos = phonePos
self.itemList = None
def buildList(self):
@ -55,6 +56,7 @@ class DNAFurnitureReaderAI:
else:
self.notify.error('Could not find "interior" in DNA!')
self.itemList.append(CatalogFurnitureItem(1399, posHpr=self.phonePos))
# Every child in the interior node is a prop, thus:
for child in interior.children:
code = child.getCode()

View file

@ -1,18 +1,76 @@
from direct.directnotify import DirectNotifyGlobal
from toontown.estate.DistributedFurnitureItemAI import DistributedFurnitureItemAI
from direct.distributed.ClockDelta import *
import BankGlobals
class DistributedBankAI(DistributedFurnitureItemAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedBankAI")
def __init__(self, air, furnitureMgr, item):
DistributedFurnitureItemAI.__init__(self, air, furnitureMgr, item)
self.avId = None
self.movie = BankGlobals.BANK_MOVIE_CLEAR
def avatarEnter(self):
pass
avId = self.air.getAvatarIdFromSender()
if not self.avId:
if not self.furnitureMgr.ownerId:
self.b_setMovie(BankGlobals.BANK_MOVIE_NO_OWNER, avId, globalClockDelta.getRealNetworkTime())
return
elif self.furnitureMgr.ownerId != avId:
self.b_setMovie(BankGlobals.BANK_MOVIE_NOT_OWNER, avId, globalClockDelta.getRealNetworkTime())
return
else:
self.avId = avId
self.b_setMovie(BankGlobals.BANK_MOVIE_GUI, avId, globalClockDelta.getRealNetworkTime())
return
else:
if avId == self.avId:
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to use bank while already using it!')
self.sendUpdateToAvatarId(avId, 'freeAvatar', [])
def freeAvatar(self):
pass
def setMovie(self, mode, avId, time):
self.movie = mode
if self.movie != BankGlobals.BANK_MOVIE_CLEAR:
taskMgr.doMethodLater(2.0, self.clearMovie, 'clear-movie-%d' % self.getDoId())
def clearMovie(self, task):
self.b_setMovie(BankGlobals.BANK_MOVIE_CLEAR, 0, globalClockDelta.getRealNetworkTime())
def b_setMovie(self, mode, avId, time):
self.setMovie(mode, avId, time)
self.d_setMovie(mode, avId, time)
def d_setMovie(self, mode, avId, time):
self.sendUpdate('setMovie', [mode, avId, time])
def setMovie(self, todo0, todo1, todo2):
pass
def transferMoney(self, todo0):
pass
def transferMoney(self, amount):
avId = self.air.getAvatarIdFromSender()
if avId != self.avId:
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to transfer money while not using a bank!')
return
av = self.air.doId2do.get(avId)
if not av:
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to transfer money while not on the AI!')
return
if amount == 0: # No transfer needed.
self.b_setMovie(BankGlobals.BANK_MOVIE_NO_OP, avId, globalClockDelta.getRealNetworkTime())
elif amount > 0:
self.b_setMovie(BankGlobals.BANK_MOVIE_DEPOSIT, avId, globalClockDelta.getRealNetworkTime())
if av.money < amount:
self.air.writeServerEvent('suspicious', avId=avId, issue='Toon tried to deposit more money than they have!')
else:
av.b_setMoney(av.money - amount)
av.b_setBankMoney(av.bankMoney + amount)
else:
self.b_setMovie(BankGlobals.BANK_MOVIE_WITHDRAW, avId, globalClockDelta.getRealNetworkTime())
if av.bankMoney + amount < 0:
self.air.writeServerEvent('suspicious', avId=avId, issue='Toon tried to withdraw more money than they have!')
else:
av.b_setMoney(av.money - amount)
av.b_setBankMoney(av.bankMoney + amount)
self.avId = None

View file

@ -154,8 +154,10 @@ class DistributedCloset(DistributedFurnitureItem.DistributedFurnitureItem):
self._openDoors()
if self.customerId == base.localAvatar.doId:
camera.wrtReparentTo(self)
camera.lerpPosHpr(-7.58, -6.02, 6.9, 286.3, 336.8, 0, 1, other=self, blendType='easeOut', task=self.uniqueName('lerpCamera'))
camera.setPosHpr(self, -7.58, -6.02, 6.9, 286.3, 336.8, 0)
quat = Quat()
quat.setHpr((286.3, 336.7, 0))
LerpPosQuatInterval(camera, 1, (-7.58, -6.02, 6.9), quat, blendType='easeOut', other=self).start()
if self.av:
if self.avMoveTrack:
self.avMoveTrack.finish()

View file

@ -1,26 +1,211 @@
from direct.directnotify import DirectNotifyGlobal
from toontown.estate.DistributedFurnitureItemAI import DistributedFurnitureItemAI
from toontown.toon.ToonDNA import ToonDNA
from direct.distributed.ClockDelta import *
import ClosetGlobals
class DistributedClosetAI(DistributedFurnitureItemAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedClosetAI")
def setOwnerId(self, todo0):
pass
def __init__(self, air, furnitureMgr, itemType):
DistributedFurnitureItemAI.__init__(self, air, furnitureMgr, itemType)
self.avId = None
self.customerDNA = None
self.topList = []
self.botList = []
self.gender = 'm'
self.removedBottoms = []
self.removedTops = []
def generate(self):
if self.furnitureMgr.ownerId:
owner = self.air.doId2do.get(self.furnitureMgr.ownerId)
if owner:
self.topList = owner.clothesTopsList
self.botList = owner.clothesBottomsList
self.gender = owner.dna.gender
else:
self.air.dbInterface.queryObject(self.air.dbId, self.furnitureMgr.ownerId, self.__gotOwner)
def __gotOwner(self, dclass, fields):
if dclass != self.air.dclassesByName['DistributedToonAI']:
self.notify.warning('Got object of wrong type!')
return
self.botList = fields['setClothesBottomsList'][0]
self.topList = fields['setClothesTopsList'][0]
dna = ToonDNA(str=fields['setDNAString'][0])
self.gender = dna.gender
def getOwnerId(self):
return self.furnitureMgr.ownerId
def __verifyAvatarInMyZone(self, av):
return av.getLocation() == self.getLocation()
def enterAvatar(self):
pass
avId = self.air.getAvatarIdFromSender()
if self.avId:
if self.avId == avId:
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to use closet twice!')
self.sendUpdateToAvatarId(avId, 'freeAvatar', [])
return
av = self.air.doId2do.get(avId)
if not av:
self.air.writeServerEvent('suspicious', avId=avId, issue='Not in same shard as closet!')
return
if not self.__verifyAvatarInMyZone(av):
self.air.writeServerEvent('suspicious', avId=avId, issue='Not in same zone as closet!')
return
self.customerDNA = av.dna
self.avId = avId
self.d_setState(ClosetGlobals.OPEN, avId, self.furnitureMgr.ownerId, self.gender, self.topList, self.botList)
def freeAvatar(self):
pass
def removeItem(self, item, topOrBottom):
avId = self.air.getAvatarIdFromSender()
if avId != self.furnitureMgr.ownerId:
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to remove item from someone else\'s closet!')
return
if avId != self.avId:
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to remove item while not interacting with closet!')
return
av = self.air.doId2do.get(avId)
if not av:
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to interact with a closet from another shard!')
return
tempDna = ToonDNA()
if not tempDna.isValidNetString(item):
self.air.writeServerEvent('suspicious', avId=avId, issue='Sent an invalid DNA string!')
return
tempDna.makeFromNetString(item)
if topOrBottom == ClosetGlobals.SHIRT:
self.removedTops.append([tempDna.topTex, tempDna.topTexColor, tempDna.sleeveTex, tempDna.sleeveTexColor])
elif topOrBottom == ClosetGlobals.SHORTS:
self.removedBottoms.append([tempDna.botTex, tempDna.botTexColor])
else:
self.air.writeServerEvent('suspicious', avId=avId, issue='Set an invalid topOrBottom value!')
return
def __checkValidDNAChange(self, av, testDNA):
# verify they aren't trying to change anything other than their clothing.
# FML this took some time to write...
if testDNA.head != av.dna.head:
return False
if testDNA.torso != av.dna.torso:
if av.dna.gender == 'm':
return False
elif testDNA.torso[0] != av.dna.torso[0]: #first character of torso ('size') must remain the same, otherwise you are hacker scum.
return False
if testDNA.legs != av.dna.legs:
return False
if testDNA.gender != av.dna.gender:
return False
if testDNA.armColor != av.dna.armColor:
return False
if testDNA.gloveColor != av.dna.gloveColor:
# wtf u little hackin' shit.
return False
if testDNA.legColor != av.dna.legColor:
return False
if testDNA.headColor != av.dna.headColor:
return False
return True
def removeItem(self, todo0, todo1):
pass
def setDNA(self, todo0, todo1, todo2):
pass
def setDNA(self, dnaString, finished, whichItem):
avId = self.air.getAvatarIdFromSender()
if avId != self.avId:
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to set DNA from closet while not using it!')
return
av = self.air.doId2do.get(avId)
if not av:
self.air.writeServerEvent('suspicious', avId=avId, issue='Interacted with a closet from another shard!')
return
if not self.__verifyAvatarInMyZone(av):
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to setDNA while in another zone!')
return
testDna = ToonDNA()
if not testDna.isValidNetString(dnaString):
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to set invalid DNA at a closet!')
return
if not finished:
testDna.makeFromNetString(dnaString)
if not self.__checkValidDNAChange(av, testDna):
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to change their DNA temporarily!')
return
self.sendUpdate('setCustomerDNA', [avId, dnaString])
return
elif finished == 1:
self.d_setMovie(ClosetGlobals.CLOSET_MOVIE_COMPLETE, avId, globalClockDelta.getRealNetworkTime())
taskMgr.doMethodLater(1, self.__resetMovie, 'resetMovie-%d' % self.getDoId(), extraArgs=[])
self.d_setState(ClosetGlobals.CLOSED, 0, self.furnitureMgr.ownerId, self.gender, self.topList, self.botList)
av.b_setDNAString(self.customerDNA.makeNetString())
self.removedBottoms = []
self.removedTops = []
self.customerDNA = None
self.avId = None
elif finished == 2:
if avId != self.furnitureMgr.ownerId:
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to set their clothes from somebody else\'s closet!')
return
testDna.makeFromNetString(dnaString)
if whichItem & ClosetGlobals.SHIRT:
success = av.replaceItemInClothesTopsList(testDna.topTex, testDna.topTexColor, testDna.sleeveTex, testDna.sleeveTexColor, self.customerDNA.topTex, self.customerDNA.topTexColor, self.customerDNA.sleeveTex, self.customerDNA.sleeveTexColor)
if success:
self.customerDNA.topTex = testDna.topTex
self.customerDNA.topTexColor = testDna.topTexColor
self.customerDNA.sleeveTex = testDna.sleeveTex
self.customerDNA.sleeveTexColor = testDna.sleeveTexColor
else:
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to set their shirt to a shirt they don\'t own!')
if whichItem & ClosetGlobals.SHORTS:
success = av.replaceItemInClothesBottomsList(testDna.botTex, testDna.botTexColor, self.customerDNA.botTex, self.customerDNA.botTexColor)
if success:
self.customerDNA.botTex = testDna.botTex
self.customerDNA.botTexColor = testDna.botTexColor
if self.customerDNA.torso != testDna.torso:
if self.customerDNA.gender == 'm':
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to change their torso size!')
return
elif self.customerDNA.torso[0] != testDna.torso[0]:
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to change their torso size!')
return
self.customerDNA.torso = testDna.torso
else:
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to set their shorts to a pair they don\'t own!')
for bottom in self.removedBottoms:
botTex, botTexColor = bottom
success = av.removeItemInClothesBottomsList(botTex, botTexColor)
if not success:
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to remove a bottom they didn\'t have!')
for top in self.removedTops:
topTex, topTexColor, sleeveTex, sleeveTexColor = top
success = av.removeItemInClothesTopsList(topTex, topTexColor, sleeveTex, sleeveTexColor)
if not success:
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to remove a top they didn\'t have!')
av.b_setDNAString(self.customerDNA.makeNetString())
av.b_setClothesTopsList(av.getClothesTopsList())
av.b_setClothesBottomsList(av.getClothesBottomsList())
self.topList = av.getClothesTopsList()
self.botList = av.getClothesBottomsList()
self.removedBottoms = []
self.removedTops = []
self.d_setMovie(ClosetGlobals.CLOSET_MOVIE_COMPLETE, avId, globalClockDelta.getRealNetworkTime())
taskMgr.doMethodLater(1, self.__resetMovie, 'resetMovie-%d' % self.getDoId(), extraArgs=[])
self.d_setState(ClosetGlobals.CLOSED, 0, self.furnitureMgr.ownerId, self.gender, self.topList, self.botList)
self.customerDNA = None
self.avId = None
def setState(self, todo0, todo1, todo2, todo3, todo4, todo5):
pass
def d_setState(self, mode, avId, ownerId, gender, topList, botList):
self.sendUpdate('setState', [mode, avId, ownerId, gender, topList, botList])
def d_setMovie(self, movie, avId, time):
self.sendUpdate('setMovie', [movie, avId, time])
def __resetMovie(self):
self.d_setMovie(ClosetGlobals.CLOSET_MOVIE_CLEAR, 0, globalClockDelta.getRealNetworkTime())
def setMovie(self, todo0, todo1, todo2):
pass

View file

@ -2,6 +2,7 @@ from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from toontown.toonbase import ToontownGlobals
import HouseGlobals
import GardenGlobals
import time
from toontown.fishing.DistributedFishingPondAI import DistributedFishingPondAI
from toontown.fishing.DistributedFishingTargetAI import DistributedFishingTargetAI
@ -11,6 +12,9 @@ from toontown.safezone.DistributedFishingSpotAI import DistributedFishingSpotAI
from toontown.safezone.SZTreasurePlannerAI import SZTreasurePlannerAI
from toontown.safezone import TreasureGlobals
from toontown.estate.DistributedGardenBoxAI import DistributedGardenBoxAI
from toontown.estate.DistributedGardenPlotAI import DistributedGardenPlotAI
class DistributedEstateAI(DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedEstateAI")
@ -25,28 +29,41 @@ class DistributedEstateAI(DistributedObjectAI):
self.lastEpochTimestamp = 0
self.rentalTimestamp = 0
self.houses = [None] * 6
self.pond = None
self.spots = []
self.targets = []
self.treasurePlanner = None
self.owner = None
def generate(self):
DistributedObjectAI.generate(self)
# Gone fishin'
self.pond = DistributedFishingPondAI(simbase.air)
self.pond.setArea(ToontownGlobals.MyEstate)
self.pond.generateWithRequired(self.zoneId)
for i in range(FishingTargetGlobals.getNumTargets(ToontownGlobals.MyEstate)):
target = DistributedFishingTargetAI(self.air)
target.setPondDoId(self.pond.getDoId())
target.generateWithRequired(self.zoneId)
self.targets.append(target)
for i in xrange(6):
avItems = self.items[i]
for item in avItems:
type, hardPoint, waterLevel, growthLevel, optional = item
if type == 2: # broken for now, rip
boxes = GardenGlobals.estateBoxes[i]
box = DistributedGardenBoxAI(self.air)
box.setPlot(i)
box.setOwnerIndex(i)
box.setTypeIndex(boxes[hardPoint][3])
box.setPosition(boxes[hardPoint][0], boxes[hardPoint][1], 20)
box.setHeading(boxes[hardPoint][2])
box.generateWithRequired(self.zoneId)
spot = DistributedFishingSpotAI(self.air)
spot.setPondDoId(self.pond.getDoId())
@ -75,16 +92,21 @@ class DistributedEstateAI(DistributedObjectAI):
# Let's place some popsicles
self.createTreasurePlanner()
def rentItem(self, type, duration):
pass # TODO - implement this
def destroy(self):
for house in self.houses:
if house:
house.requestDelete()
del self.houses[:]
if self.pond:
self.pond.requestDelete()
for spot in self.spots:
spot.requestDelete()
for target in self.targets:
target.requestDelete()
if self.treasurePlanner:
self.treasurePlanner.stop()
@ -98,17 +120,17 @@ class DistributedEstateAI(DistributedObjectAI):
def setEstateType(self, type):
self.estateType = type
def d_setEstateType(self, type):
self.sendUpdate('setEstateType', [type])
def b_setEstateType(self, type):
self.setEstateType(type)
self.d_setEstateType(type)
def getEstateType(self):
return self.estateType
def setClosestHouse(self, todo0):
pass
@ -129,14 +151,14 @@ class DistributedEstateAI(DistributedObjectAI):
def setDawnTime(self, dawnTime):
self.dawnTime = dawnTime
def d_setDawnTime(self, dawnTime):
self.sendUpdate('setDawnTime', [dawnTime])
def b_setDawnTime(self, dawnTime):
self.setDawnTime(dawnTime)
self.d_setDawnTime(dawnTime)
def getDawnTime(self):
return self.dawnTime
@ -145,59 +167,59 @@ class DistributedEstateAI(DistributedObjectAI):
def setDecorData(self, decorData):
self.decorData = decorData
def d_setDecorData(self, decorData):
self.sendUpdate('setDecorData', [decorData])
def b_setDecorData(self, decorData):
self.setDecorData(decorData)
self.d_setDecorData(decorData)
def getDecorData(self):
return self.decorData
def setLastEpochTimeStamp(self, last): #how do I do this
self.lastEpochTimestamp = last
def d_setLastEpochTimeStamp(self, last):
self.sendUpdate('setLastEpochTimeStamp', [last])
def b_setLastEpochTimeStamp(self, last):
self.setLastEpochTimeStamp(last)
self.d_setLastEpochTimeStamp(last)
def getLastEpochTimeStamp(self):
return self.lastEpochTimestamp
def setRentalTimeStamp(self, rental):
self.rentalTimestamp = rental
def d_setRentalTimeStamp(self, rental):
self.sendUpdate('setRentalTimeStamp', [rental])
def b_setRentalTimeStamp(self, rental):
self.setRentalTimeStamp(self, rental)
self.b_setRentalTimeStamp(self, rental)
def getRentalTimeStamp(self):
return self.rentalTimestamp
def setRentalType(self, todo0):
pass
def getRentalType(self):
return 0
def setSlot0ToonId(self, id):
self.toons[0] = id
def d_setSlot0ToonId(self, id):
self.sendUpdate('setSlot0ToonId', [id])
def b_setSlot0ToonId(self, id):
self.setSlot0ToonId(id)
self.d_setSlot0ToonId(id)
def getSlot0ToonId(self):
return self.toons[0]
@ -206,37 +228,37 @@ class DistributedEstateAI(DistributedObjectAI):
def d_setSlot0Items(self, items):
self.sendUpdate('setSlot5Items', [items])
def b_setSlot0Items(self, items):
self.setSlot0Items(items)
self.d_setSlot0Items(items)
def getSlot0Items(self):
return self.items[0]
def setSlot1ToonId(self, id):
self.toons[1] = id
def d_setSlot1ToonId(self, id):
self.sendUpdate('setSlot1ToonId', [id])
def b_setSlot1ToonId(self, id):
self.setSlot1ToonId(id)
self.d_setSlot1ToonId(id)
def getSlot1ToonId(self):
return self.toons[1]
def setSlot1Items(self, items):
self.items[1] = items
def d_setSlot1Items(self, items):
self.sendUpdate('setSlot2Items', [items])
def b_setSlot1Items(self, items):
self.setSlot2Items(items)
self.d_setSlot2Items(items)
def getSlot1Items(self):
return self.items[1]
@ -245,11 +267,11 @@ class DistributedEstateAI(DistributedObjectAI):
def d_setSlot2ToonId(self, id):
self.sendUpdate('setSlot2ToonId', [id])
def b_setSlot2ToonId(self, id):
self.setSlot2ToonId(id)
self.d_setSlot2ToonId(id)
def getSlot2ToonId(self):
return self.toons[2]
@ -258,90 +280,90 @@ class DistributedEstateAI(DistributedObjectAI):
def d_setSlot2Items(self, items):
self.sendUpdate('setSlot2Items', [items])
def b_setSlot2Items(self, items):
self.setSlot2Items(items)
self.d_setSlot2Items(items)
def getSlot2Items(self):
return self.items[2]
def setSlot3ToonId(self, id):
self.toons[3] = id
def d_setSlot3ToonId(self, id):
self.sendUpdate('setSlot3ToonId', [id])
def b_setSlot3ToonId(self, id):
self.setSlot3ToonId(id)
self.d_setSlot3ToonId(id)
def getSlot3ToonId(self):
return self.toons[3]
def setSlot3Items(self, items):
self.items[3] = items
def d_setSlot3Items(self, items):
self.sendUpdate('setSlot3Items', [items])
def b_setSlot3Items(self, items):
self.setSlot3Items(items)
self.d_setSlot3Items(items)
def getSlot3Items(self):
return self.items[3]
def setSlot4ToonId(self, id):
self.toons[4] = id
def d_setSlot4ToonId(self, id):
self.sendUpdate('setSlot4ToonId', [id])
def b_setSlot5ToonId(self, id):
self.setSlot4ToonId(id)
self.d_setSlot4ToonId(id)
def getSlot4ToonId(self):
return self.toons[4]
def setSlot4Items(self, items):
self.items[4] = items
def d_setSlot4Items(self, items):
self.sendUpdate('setSlot4Items', [items])
def b_setSlot4Items(self, items):
self.setSlot4Items(items)
self.d_setSlot4Items(items)
def getSlot4Items(self):
return self.items[4]
def setSlot5ToonId(self, id):
self.toons[5] = id
def d_setSlot5ToonId(self, id):
self.sendUpdate('setSlot5ToonId', [id])
def b_setSlot5ToonId(self, id):
self.setSlot5ToonId(id)
self.d_setSlot5ToonId(id)
def getSlot5ToonId(self):
return self.toons[5]
def setSlot5Items(self, items):
self.items[5] = items
def d_setSlot5Items(self, items):
self.sendUpdate('setSlot5Items', [items])
def b_setSlot5Items(self, items):
self.setSlot5Items(items)
self.d_setSlot5Items(items)
def getSlot5Items(self):
return self.items[5]
@ -350,14 +372,14 @@ class DistributedEstateAI(DistributedObjectAI):
if i >= 6:
return
self.toons[i] = idList[i]
def d_setIdList(self, idList):
self.sendUpdate('setIdList', [idList])
def b_setIdList(self, idList):
self.setIdList(idList)
self.d_setIdLst(idList)
def completeFlowerSale(self, todo0):
pass
@ -366,14 +388,14 @@ class DistributedEstateAI(DistributedObjectAI):
def setClouds(self, clouds):
self.cloudType = clouds
def d_setClouds(self, clouds):
self.sendUpdate('setClouds', [clouds])
def b_setClouds(self, clouds):
self.setClouds(clouds)
self.d_setClouds(clouds)
def getClouds(self):
return self.cloudType
@ -383,3 +405,49 @@ class DistributedEstateAI(DistributedObjectAI):
def gameTableOver(self):
pass
def updateToons(self):
self.d_setSlot0ToonId(self.toons[0])
self.d_setSlot1ToonId(self.toons[1])
self.d_setSlot2ToonId(self.toons[2])
self.d_setSlot3ToonId(self.toons[3])
self.d_setSlot4ToonId(self.toons[4])
self.d_setSlot5ToonId(self.toons[5])
self.sendUpdate('setIdList', [self.toons])
def updateItems(self):
self.d_setSlot0Items(self.items[0])
self.d_setSlot1Items(self.items[1])
self.d_setSlot2Items(self.items[2])
self.d_setSlot3Items(self.items[3])
self.d_setSlot4Items(self.items[4])
self.d_setSlot5Items(self.items[5])
def placeStarterGarden(self, avatar):
items = []
if avatar.getGardenStarted():
return
avId = avatar.getDoId()
houseIndex = self.toons.index(avId)
plots = GardenGlobals.estatePlots[houseIndex]
boxes = GardenGlobals.estateBoxes[houseIndex]
for i in xrange(len(boxes)):
items.append([2, i, 0, 0, 0])
box = DistributedGardenBoxAI(self.air)
box.setPlot(i)
box.setOwnerIndex(houseIndex)
box.setTypeIndex(boxes[i][3])
box.setPosition(boxes[i][0], boxes[i][1], 20)
box.setHeading(boxes[i][2])
box.generateWithRequired(self.zoneId)
for i in xrange(len(plots)):
items.append([1, i, 0, 0, 0])
plot = DistributedGardenPlotAI(self.air)
plot.setPlot(i)
plot.setOwnerIndex(houseIndex)
if plots[i][3] != GardenGlobals.FLOWER_TYPE:
plot.setPosition(plots[i][0], plots[i][1], 20)
plot.setHeading(plots[i][2])
plot.generateWithRequired(self.zoneId)
self.items[houseIndex] = items
self.updateItems()
avatar.b_setGardenStarted(1)

View file

@ -20,15 +20,12 @@ class DistributedFurnitureItemAI(DistributedSmoothNodeAI):
self.b_setPosHpr(x, y, z, h, p, r)
def getItem(self):
return (self.furnitureMgr.doId,
self.catalogItem.getBlob(CatalogItem.Customization))
return (self.furnitureMgr.doId, self.catalogItem.getBlob(CatalogItem.Customization))
def requestPosHpr(self, final, x, y, z, h, p, r, t):
senderId = self.air.getAvatarIdFromSender()
if (not self.furnitureMgr.director or
senderId != self.furnitureMgr.director.doId):
self.air.writeServerEvent('suspicious', avId=senderId,
issue='DistributedFurnitureItemAI.requestPosHpr Tried to move furniture without being the director!')
if (not self.furnitureMgr.director or senderId != self.furnitureMgr.director.doId):
self.air.writeServerEvent('suspicious', avId=senderId, issue='DistributedFurnitureItemAI.requestPosHpr Tried to move furniture without being the director!')
return
self.catalogItem.posHpr = x, y, z, h, p, r

View file

@ -84,14 +84,7 @@ class DistributedFurnitureManager(DistributedObject.DistributedObject):
def moveItemFromAttic(self, index, posHpr, callback):
context = self.getCallbackContext(callback, [index])
self.sendUpdate('moveItemFromAtticMessage', [index,
posHpr[0],
posHpr[1],
posHpr[2],
posHpr[3],
posHpr[4],
posHpr[5],
context])
self.sendUpdate('moveItemFromAtticMessage', [index, posHpr[0], posHpr[1], posHpr[2], posHpr[3], posHpr[4], posHpr[5], context])
def deleteItemFromAttic(self, item, index, callback):
context = self.getCallbackContext(callback, [item, index])

View file

@ -2,9 +2,16 @@ from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from toontown.catalog.CatalogItemList import CatalogItemList
from toontown.catalog import CatalogItem
from toontown.catalog.CatalogFurnitureItem import CatalogFurnitureItem
from toontown.catalog.CatalogFurnitureItem import CatalogFurnitureItem, FLCloset, FLBank, FLPhone
from toontown.catalog.CatalogWallpaperItem import CatalogWallpaperItem
from toontown.catalog.CatalogMouldingItem import CatalogMouldingItem
from toontown.catalog.CatalogFlooringItem import CatalogFlooringItem
from toontown.catalog.CatalogWainscotingItem import CatalogWainscotingItem
from toontown.toonbase import ToontownGlobals
from DistributedFurnitureItemAI import DistributedFurnitureItemAI
from DistributedBankAI import DistributedBankAI
from DistributedPhoneAI import DistributedPhoneAI
from DistributedClosetAI import DistributedClosetAI
class FurnitureError(Exception):
def __init__(self, code):
@ -90,7 +97,22 @@ class DistributedFurnitureManagerAI(DistributedObjectAI):
self.items = []
for item in items:
do = DistributedFurnitureItemAI(self.air, self, item)
if item.getFlags() & FLCloset:
if self.house.gender is 0:
# If they have a male closet, we need to make it a female closet.
if item.furnitureType - 500 < 10:
item.furnitureType += 10
elif item.furnitureType - 500 > 10:
# If they have a female closet, we need to make it a male closet.
item.furnitureType -= 10
do = DistributedClosetAI(self.air, self, item)
elif item.getFlags() & FLBank:
do = DistributedBankAI(self.air, self, item)
elif item.getFlags() & FLPhone:
do = DistributedPhoneAI(self.air, self, item)
else:
do = DistributedFurnitureItemAI(self.air, self, item)
if self.isGenerated():
do.generateWithRequired(self.zoneId)
self.items.append(do)
@ -192,19 +214,16 @@ class DistributedFurnitureManagerAI(DistributedObjectAI):
senderId = self.air.getAvatarIdFromSender()
if self.ownerId != senderId:
self.air.writeServerEvent('suspicious', avId=senderId,
issue='Tried to move furniture, but not the house owner!')
self.air.writeServerEvent('suspicious', avId=senderId, issue='Tried to move furniture, but not the house owner!')
return
if senderId != directorId and directorId != 0:
self.air.writeServerEvent('suspicious', avId=senderId,
issue='Tried to make someone else (%d) move their furniture!' % directorId)
self.air.writeServerEvent('suspicious', avId=senderId, issue='Tried to make someone else (%d) move their furniture!' % directorId)
return
director = self.air.doId2do.get(directorId)
if directorId and not director:
self.air.writeServerEvent('suspicious', avId=directorId,
issue='Tried to move furniture without being on the shard!')
self.air.writeServerEvent('suspicious', avId=directorId, issue='Tried to move furniture without being on the shard!')
return
if self.director:
@ -246,23 +265,78 @@ class DistributedFurnitureManagerAI(DistributedObjectAI):
item.posHpr = (x, y, z, h, p, r)
do = DistributedFurnitureItemAI(self.air, self, item)
# TODO: Add DistributedTrunkAI when accessories are enabled
# TODO2: Is there any point in repeating this? Perhaps we should unify this (and the above)
# into a single self.__getDOFromItem(item)?
if item.getFlags() & FLCloset:
if self.house.gender is 0:
# If they have a male closet, we need to make it a female closet.
if item.furnitureType - 500 < 10:
item.furnitureType += 10
elif item.furnitureType - 500 > 10:
# If they have a female closet, we need to make it a male closet.
item.furnitureType -= 10
do = DistributedClosetAI(self.air, self, item)
elif item.getFlags() & FLBank:
do = DistributedBankAI(self.air, self, item)
elif item.getFlags() & FLPhone:
do = DistributedPhoneAI(self.air, self, item)
else:
do = DistributedFurnitureItemAI(self.air, self, item)
do.generateWithRequired(self.zoneId)
self.items.append(do)
return (ToontownGlobals.FM_MovedItem, do.doId)
def deleteItemFromAttic(self, blob, index):
pass
item = self.getAtticFurniture(self.atticItems, index)
if item is None:
self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Tried to delete an invalid item at index %s' % index)
return ToontownGlobals.FM_InvalidIndex
self.atticItems.remove(item)
self.d_setAtticItems(self.getAtticItems())
return ToontownGlobals.FM_DeletedItem
def deleteItemFromRoom(self, blob, doId):
pass
def moveWallpaperFromAttic(self, index, room):
pass
# CatalogFlooringItem(1020, 0)
# CatalogWainscotingItem(1000, 3)
# CatalogFlooringItem(1020, 0)
retcode = ToontownGlobals.FM_SwappedItem
wallpaper = self.getAtticFurniture(self.atticWallpaper, index)
if wallpaper is None:
# rip
self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Invalid wallpaper at index %s' % index)
return ToontownGlobals.FM_InvalidIndex
if room > 1:
# This is not a valid room!
self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Tried to apply a wallpaper in an invalid room %d!' % room)
return ToontownGlobals.FM_InvalidItem
interiorIndex = room*4
if isinstance(wallpaper, CatalogMouldingItem):
interiorIndex += 1
elif isinstance(wallpaper, CatalogFlooringItem):
interiorIndex += 2
elif isinstance(wallpaper, CatalogWainscotingItem):
interiorIndex += 3
atticIndex = self.atticWallpaper.index(wallpaper)
self.atticWallpaper[atticIndex] = self.wallpaper[interiorIndex]
self.d_setAtticWallpaper(self.getAtticWallpaper())
self.wallpaper[interiorIndex] = wallpaper
self.applyWallpaper()
return retcode
def deleteWallpaperFromAttic(self, blob, index):
pass
wallpaper = self.getAtticFurniture(blob, index)
self.atticWallpaper.remove(wallpaper)
self.b_setAtticWallpaper(self.getAtticWallpaper())
def moveWindowToAttic(self, slot):
window = self.getWindow(slot)
@ -324,7 +398,15 @@ class DistributedFurnitureManagerAI(DistributedObjectAI):
return retcode
def deleteWindowFromAttic(self, blob, index):
pass
window = self.getAtticFurniture(self.atticWindows, index)
if window is None:
self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Tried to delete an invalid window at index %s' % index)
return ToontownGlobals.FM_InvalidIndex
self.atticWindows.remove(window)
self.d_setAtticWindows(self.getAtticWindows())
return ToontownGlobals.FM_DeletedItem
def recoverDeletedItem(self, blob, index):
pass
@ -357,7 +439,7 @@ class DistributedFurnitureManagerAI(DistributedObjectAI):
# Brief delay; this is to give the State Server time to finish
# processing the new furniture item appearing before we hit the
# client with the doId:
taskMgr.doMethodLater(5, self.sendUpdateToAvatarId,
taskMgr.doMethodLater(1, self.sendUpdateToAvatarId,
self.uniqueName('send-attic-response'),
extraArgs=[senderId, response, [retval, doId, context]])
else:
@ -367,8 +449,7 @@ class DistributedFurnitureManagerAI(DistributedObjectAI):
self.handleMessage(self.moveItemToAttic, 'moveItemToAtticResponse', doId, context)
def moveItemFromAtticMessage(self, index, x, y, z, h, p, r, context):
self.handleMessage(self.moveItemFromAttic, 'moveItemFromAtticResponse',
index, x, y, z, h, p, r, context)
self.handleMessage(self.moveItemFromAttic, 'moveItemFromAtticResponse', index, x, y, z, h, p, r, context)
def deleteItemFromAtticMessage(self, blob, index, context):
self.handleMessage(self.deleteItemFromAttic, 'deleteItemFromAtticResponse', blob, index, context)

View file

@ -3,7 +3,14 @@ from toontown.estate.DistributedLawnDecorAI import DistributedLawnDecorAI
class DistributedGardenBoxAI(DistributedLawnDecorAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedGardenBoxAI")
def __init__(self, air):
DistributedLawnDecorAI.__init__(self, air)
self.typeIndex = 0
def setTypeIndex(self, todo0):
pass
def setTypeIndex(self, index):
self.typeIndex = index
def getTypeIndex(self):
return self.typeIndex

View file

@ -2,12 +2,16 @@ from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from toontown.estate.DistributedHouseInteriorAI import DistributedHouseInteriorAI
from toontown.estate.DistributedHouseDoorAI import DistributedHouseDoorAI
from toontown.estate.DistributedMailboxAI import DistributedMailboxAI
from toontown.building import DoorTypes
from toontown.catalog.CatalogItemList import CatalogItemList
from otp.ai.MagicWordGlobal import *
from toontown.catalog.CatalogFurnitureItem import *
from toontown.catalog.CatalogItem import Customization, WindowPlacement, Location
class DistributedHouseAI(DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedHouseAI")
def __init__(self, air):
DistributedObjectAI.__init__(self, air)
@ -17,21 +21,22 @@ class DistributedHouseAI(DistributedObjectAI):
self.name = ''
self.color = 0
self.housePos = 0
self.gender = 1
self.isInteriorInitialized = 1 # Only fresh DB houses are not inited.
self.atticItems = ''
self.interiorItems = ''
self.atticItems = ''
self.interiorWallpaper = ''
self.atticWallpaper = ''
self.interiorWindows = ''
self.atticWindows = ''
self.deletedItems = ''
# FIXME: Now I think I did this wrong...
self.atticItems = CatalogItemList(store=Customization)
self.interiorItems = CatalogItemList(store=Customization)
self.interiorWallpaper = CatalogItemList(store=Customization)
self.atticWallpaper = CatalogItemList(store=Customization)
self.interiorWindows = CatalogItemList(store=Customization)
self.atticWindows = CatalogItemList(store=Customization)
self.deletedItems = CatalogItemList(store=Customization)
def announceGenerate(self):
DistributedObjectAI.announceGenerate(self)
self.interiorZone = self.air.allocateZone(owner=self.air.estateManager)
self.door = DistributedHouseDoorAI(self.air, self.getDoId(), DoorTypes.EXT_STANDARD)
self.door.setSwing(3)
self.door.generateWithRequired(self.zoneId)
@ -48,101 +53,113 @@ class DistributedHouseAI(DistributedObjectAI):
self.interior.setHouseId(self.getDoId())
self.interior.generateWithRequired(self.interiorZone)
if self.avatarId:
self.mailbox = DistributedMailboxAI(self.air, self)
self.mailbox.generateWithRequired(self.zoneId)
if not self.isInteriorInitialized:
self.notify.info('Initializing interior...')
self.interior.initialize()
self.b_setInteriorInitialized(1)
self.sendUpdate('setHouseReady', [])
def delete(self):
self.door.requestDelete()
self.interiorDoor.requestDelete()
self.interior.requestDelete()
if self.avatarId:
self.mailbox.requestDelete()
self.air.deallocateZone(self.interiorZone)
DistributedObjectAI.delete(self)
def setHousePos(self, pos):
self.housePos = pos
def d_setHousePos(self, pos):
self.sendUpdate('setHousePos', [pos])
def b_setHousePos(self, pos):
self.setHousePos(pos)
self.d_setHousePos(pos)
def getHousePos(self):
return self.housePos
def setHouseType(self, type):
self.houseType = type
def d_setHouseType(self, type):
self.sendUpdate('setHouseType', [type])
def b_setHouseType(self, type):
self.setHouseType(type)
self.d_setHouseType(type)
def getHouseType(self):
return self.houseType
def setGardenPos(self, pos):
self.gardenPos = pos
def d_setGardenPos(self, pos):
self.sendUpdate('setGardenPos', [pos])
def b_setGardenPos(self, pos):
self.setGardenPow(pos)
self.d_setGardenPos(pos)
def getGardenPos(self):
return self.gardenPos
def setAvatarId(self, avId):
self.avatarId = avId
def d_setAvatarId(self, avId):
self.sendUpdate('setAvatarId', [avId])
def b_setAvatarId(self, avId):
self.setAvatarId(avId)
self.d_setAvatarId(avId)
def getAvatarId(self):
return self.avatarId
def setName(self, name):
self.name = name
def d_setName(self, name):
self.sendUpdate('setName', [name])
def b_setName(self, name):
self.setName(name)
self.d_setName(name)
def getName(self):
return self.name
def setColor(self, color):
self.color = color
def d_setColor(self, color):
self.sendUpdate('setColor', [color])
def b_setColor(self, color):
self.setColor(color)
self.d_setColor(color)
def getColor(self):
return self.color
def setGender(self, genderIndex):
self.gender = genderIndex
def getGender(self):
return self.gender
def setAtticItems(self, atticItems):
self.atticItems = atticItems
self.atticItems = CatalogItemList(atticItems, store=Customization)
def d_setAtticItems(self, atticItems):
self.sendUpdate('setAtticItems', [atticItems])
@ -152,10 +169,10 @@ class DistributedHouseAI(DistributedObjectAI):
self.d_setAtticItems(atticItems)
def getAtticItems(self):
return self.atticItems
return self.atticItems.getBlob()
def setInteriorItems(self, interiorItems):
self.interiorItems = interiorItems
self.interiorItems = CatalogItemList(interiorItems, store=Customization | Location)
def d_setInteriorItems(self, interiorItems):
self.sendUpdate('setInteriorItems', [interiorItems])
@ -163,12 +180,12 @@ class DistributedHouseAI(DistributedObjectAI):
def b_setInteriorItems(self, interiorItems):
self.setInteriorItems(interiorItems)
self.d_setInteriorItems(interiorItems)
def getInteriorItems(self):
return self.interiorItems
return self.interiorItems.getBlob()
def setAtticWallpaper(self, atticWallpaper):
self.atticWallpaper = atticWallpaper
self.atticWallpaper = CatalogItemList(atticWallpaper, store=Customization)
def d_setAtticWallpaper(self, atticWallpaper):
self.sendUpdate('setAtticWallpaper', [atticWallpaper])
@ -176,12 +193,12 @@ class DistributedHouseAI(DistributedObjectAI):
def b_setAtticWallpaper(self, atticWallpaper):
self.setAtticWallpaper(atticWallpaper)
self.d_setAtticWallpaper(atticWallpaper)
def getAtticWallpaper(self):
return self.atticWallpaper
return self.atticWallpaper.getBlob()
def setInteriorWallpaper(self, interiorWallpaper):
self.interiorWallpaper = interiorWallpaper
self.interiorWallpaper = CatalogItemList(interiorWallpaper, store=Customization)
def d_setInteriorWallpaper(self, interiorWallpaper):
self.sendUpdate('setInteriorWallpaper', [interiorWallpaper])
@ -191,10 +208,10 @@ class DistributedHouseAI(DistributedObjectAI):
self.d_setInteriorWallpaper(interiorWallpaper)
def getInteriorWallpaper(self):
return self.interiorWallpaper
return self.interiorWallpaper.getBlob()
def setAtticWindows(self, atticWindows):
self.atticWindows = atticWindows
self.atticWindows = CatalogItemList(atticWindows, store=Customization)
def d_setAtticWindows(self, atticWindows):
self.sendUpdate('setAtticWindows', [atticWindows])
@ -204,10 +221,10 @@ class DistributedHouseAI(DistributedObjectAI):
self.d_setAtticWindows(atticWindows)
def getAtticWindows(self):
return self.atticWindows
return self.atticWindows.getBlob()
def setInteriorWindows(self, interiorWindows):
self.interiorWindows = interiorWindows
self.interiorWindows = CatalogItemList(interiorWindows, store=Customization | WindowPlacement)
def d_setInteriorWindows(self, interiorWindows):
self.sendUpdate('setInteriorWindows', [interiorWindows])
@ -217,10 +234,10 @@ class DistributedHouseAI(DistributedObjectAI):
self.d_setInteriorWindows(interiorWindows)
def getInteriorWindows(self):
return self.interiorWindows
return self.interiorWindows.getBlob()
def setDeletedItems(self, deletedItems):
self.deletedItems = deletedItems
self.deletedItems = CatalogItemList(deletedItems, store=Customization)
def d_setDeletedItems(self, deletedItems):
self.sendUpdate('setDeletedItems', [deletedItems])
@ -230,7 +247,7 @@ class DistributedHouseAI(DistributedObjectAI):
self.d_setDeletedItems(deletedItems)
def getDeletedItems(self):
return self.deletedItems
return self.deletedItems.getBlob()
def setInteriorInitialized(self, initialized):
self.isInteriorInitialized = initialized
@ -247,13 +264,48 @@ class DistributedHouseAI(DistributedObjectAI):
def setCannonEnabled(self, todo0):
pass
def getCannonEnabled(self):
return 0
def setHouseReady(self):
pass
def addAtticItem(self, item):
self.interior.furnitureManager.saveToHouse()
if item.replacesExisting() and item.hasExisting():
if item.getFlags() & FLCloset:
closets = ClosetToClothes.keys()
for itItem in self.interiorItems:
if itItem.furnitureType in closets:
posHpr = itItem.posHpr
self.interiorItems.remove(itItem)
item.posHpr = posHpr
self.interiorItems.append(item)
break
for itItem in self.atticItems:
if itItem.furnitureType in closets:
self.atticItems.remove(itItem)
self.atticItems.append(item)
break
else:
self.atticItems.append(item)
self.d_setAtticItems(self.atticItems.getBlob())
self.d_setInteriorItems(self.interiorItems.getBlob())
self.interior.furnitureManager.loadFromHouse()
def addWindow(self, item):
self.interior.furnitureManager.saveToHouse()
self.atticWindows.append(item)
self.d_setAtticWindows(self.atticWindows.getBlob())
self.interior.furnitureManager.loadFromHouse()
def addWallpaper(self, item):
self.interior.furnitureManager.saveToHouse()
self.atticWallpaper.append(item)
self.d_setAtticWallpaper(self.atticWallpaper.getBlob())
self.interior.furnitureManager.loadFromHouse()
@magicWord(category=CATEGORY_OVERRIDE, types=[int])
def houseType(type=0):
"""Set target house type (must be spawned!). Default (if left blank) is 0 (normal house)."""

View file

@ -1,26 +1,29 @@
from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from DistributedFurnitureManagerAI import *
from toontown.catalog import CatalogItem
from toontown.catalog.CatalogWindowItem import CatalogWindowItem
from toontown.catalog.CatalogWallpaperItem import CatalogWallpaperItem
from toontown.catalog.CatalogMouldingItem import CatalogMouldingItem
from toontown.catalog.CatalogFlooringItem import CatalogFlooringItem
from toontown.catalog.CatalogWainscotingItem import CatalogWainscotingItem
from DNAFurnitureReaderAI import DNAFurnitureReaderAI
# The house interior DNA files for each
houseInteriors = [
'phase_5.5/dna/house_interior3.xml',
'phase_5.5/dna/house_interior4.xml',
'phase_5.5/dna/house_interior5.xml',
'phase_5.5/dna/house_interior7.xml',
'phase_5.5/dna/house_interior8.xml',
'phase_5.5/dna/house_interior10.xml',
]
import HouseGlobals
import random
# 2?
defaultWindows = [
CatalogWindowItem(20, placement=0),
CatalogWindowItem(20, placement=2), CatalogWindowItem(20, placement=4)
]
defaultWallpaper = [
CatalogWallpaperItem(1100, 0, 1000, 0),
CatalogWallpaperItem(1110, 0, 1010, 0),
CatalogMouldingItem(1000, 2),
CatalogFlooringItem(1000, 4),
CatalogWainscotingItem(1010, 4),
CatalogWallpaperItem(1110, 0, 1010, 0),
CatalogMouldingItem(1000, 2),
CatalogFlooringItem(1000, 4),
CatalogWainscotingItem(1010, 4),
]
class DistributedHouseInteriorAI(DistributedObjectAI):
@ -49,21 +52,24 @@ class DistributedHouseInteriorAI(DistributedObjectAI):
def initialize(self):
# Get DNA file appropriate to this house...
dnaFile = houseInteriors[self.houseIndex]
interior = random.choice(HouseGlobals.interiors)
dnaFile = interior[0]
phonePos = interior[4]
# Load DNA...
dnaData = self.air.loadDNA(dnaFile)
# Read it into furniture...
furnitureReader = DNAFurnitureReaderAI(dnaData)
furnitureReader = DNAFurnitureReaderAI(dnaData, phonePos)
# Set furniture:
self.furnitureManager.setItems(furnitureReader.getBlob())
# Set default windows and wallpaper:
#del self.furnitureManager.windows[:]
#self.furnitureManager.windows.extend(defaultWindows)
#self.furnitureManager.applyWindows()
del self.furnitureManager.windows[:]
self.furnitureManager.windows.extend(defaultWindows)
self.furnitureManager.applyWindows()
del self.furnitureManager.wallpaper[:]
self.furnitureManager.wallpaper.extend(defaultWallpaper)
self.furnitureManager.applyWallpaper()

View file

@ -265,9 +265,6 @@ class DistributedLawnDecor(DistributedNode.DistributedNode, NodePath, ShadowCast
toonTrack = Sequence(Parallel(ActorInterval(toon, 'walk', loop=True, duration=1), Parallel(LerpPosInterval(toon, 1.0, Point3(finalX, finalY, toon.getZ(render)), fluid=True, bakeInStart=False)), LerpHprInterval(toon, 1.0, hpr=hpr)), Func(toon.loop, 'neutral'))
return toonTrack
def unprint(self, string):
print string
def startInteraction(self):
place = base.cr.playGame.getPlace()
if place:

View file

@ -3,18 +3,47 @@ from direct.distributed.DistributedNodeAI import DistributedNodeAI
class DistributedLawnDecorAI(DistributedNodeAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedLawnDecorAI")
def __init__(self, air):
DistributedNodeAI.__init__(self, air)
self.plot = 0
self.h = 0
self.pos = (0, 0, 0)
self.ownerIndex = 0
def setPlot(self, todo0):
pass
def setPlot(self, plot):
self.plot = plot
def setHeading(self, todo0):
pass
def getPlot(self):
return self.plot
def setHeading(self, h):
self.setH(h)
self.h = h
def getHeading(self):
return self.h
def setPosition(self, x, y, z):
self.setPos(x, y, z)
self.pos = (x, y, z)
def d_setPosition(self, x, y, z):
self.sendUpdate('setPos', [x, y, z])
self.sendUpdate('setPosition', [x, y, z])
def b_setPosition(self, x, y, z):
self.setPosition(x, y, z)
self.d_setPosition(x, y, z)
def getPosition(self):
return self.pos
def getOwnerIndex(self):
return self.ownerIndex
def setPosition(self, todo0, todo1, todo2):
pass
def setOwnerIndex(self, todo0):
pass
def setOwnerIndex(self, index):
self.ownerIndex = index
def plotEntered(self):
pass

View file

@ -1,41 +1,117 @@
from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from toontown.toonbase import ToontownGlobals
from toontown.catalog import CatalogItem
import MailboxGlobals
class DistributedMailboxAI(DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedMailboxAI")
def __init__(self, air, house):
DistributedObjectAI.__init__(self, air)
self.house = house
self.housePos = house.housePos
self.name = house.name
self.avId = None
def setHouseId(self, todo0):
pass
def setHousePos(self, todo0):
pass
def setName(self, todo0):
pass
def setFullIndicator(self, todo0):
def getHouseId(self):
return self.house.getDoId()
def getHousePos(self):
return self.housePos
def getName(self):
return self.name
def setFullIndicator(self, fullIndicator):
pass
def b_setFullIndicator(self, fullIndicator):
self.setFullIndicator(fullIndicator)
self.d_setFullIndicator(fullIndicator)
def d_setFullIndicator(self, fullIndicator):
self.sendUpdate('setFullIndicator', [fullIndicator])
def avatarEnter(self):
pass
avId = self.air.getAvatarIdFromSender()
if avId != self.house.avatarId:
self.d_setMovie(MailboxGlobals.MAILBOX_MOVIE_NOT_OWNER, avId)
taskMgr.doMethodLater(2, self.__resetMovie, 'resetMovie-%d' % self.getDoId(), extraArgs=[])
return
if self.avId:
# We're using the mailbox twice! Burn!
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to use a mailbox twice at one time!')
return
av = self.air.doId2do.get(avId)
if not av:
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to use mailbox from another shard!')
return
inMailbox = len(av.mailboxContents)
onOrder = len(av.onOrder)
if inMailbox:
self.d_setMovie(MailboxGlobals.MAILBOX_MOVIE_READY, avId)
self.avId = avId
elif onOrder:
self.d_setMovie(MailboxGlobals.MAILBOX_MOVIE_WAITING, avId)
else:
self.d_setMovie(MailboxGlobals.MAILBOX_MOVIE_EMPTY, avId)
taskMgr.doMethodLater(2, self.__resetMovie, 'resetMovie-%d' % self.getDoId(), extraArgs=[])
def avatarExit(self):
pass
avId = self.air.getAvatarIdFromSender()
if avId != self.avId:
self.air.writeServerEvent('suspicious', avId=avId, issue='Exited mailbox without using it first!')
return
self.d_setMovie(MailboxGlobals.MAILBOX_MOVIE_EXIT, avId)
self.sendUpdateToAvatarId(avId, 'freeAvatar', [])
self.avId = None
taskMgr.doMethodLater(2, self.__resetMovie, 'resetMovie-%d' % self.getDoId(), extraArgs=[])
def freeAvatar(self):
pass
def setMovie(self, todo0, todo1):
pass
def d_setMovie(self, mode, avId):
self.sendUpdate('setMovie', [mode, avId])
def __resetMovie(self):
self.d_setMovie(MailboxGlobals.MAILBOX_MOVIE_CLEAR, 0)
def acceptItemMessage(self, todo0, todo1, todo2, todo3):
pass
def acceptItemMessage(self, context, item, index, optional):
avId = self.air.getAvatarIdFromSender()
if avId != self.avId:
return
av = self.air.doId2do.get(avId)
if not av:
return
if index >= len(av.mailboxContents):
self.sendUpdateToAvatarId(avId, 'acceptItemResponse', [context, ToontownGlobals.P_InvalidIndex])
return
item = av.mailboxContents[index]
del av.mailboxContents[index]
av.b_setMailboxContents(av.mailboxContents)
self.sendUpdateToAvatarId(avId, 'acceptItemResponse', [context, item.recordPurchase(av, optional)])
def acceptItemResponse(self, todo0, todo1):
pass
def discardItemMessage(self, todo0, todo1, todo2, todo3):
pass
def discardItemMessage(self, context, item, index, optional):
avId = self.air.getAvatarIdFromSender()
if avId != self.avId:
return
av = self.air.doId2do.get(avId)
if not av:
return
if index >= len(av.mailboxContents):
self.sendUpdateToAvatarId(avId, 'discardItemResponse', [context, ToontownGlobals.P_InvalidIndex])
return
del av.mailboxContents[index]
av.b_setMailboxContents(av.mailboxContents)
self.sendUpdateToAvatarId(avId, 'discardItemResponse', [context, ToontownGlobals.P_ItemAvailable])
def discardItemResponse(self, todo0, todo1):
pass

View file

@ -116,7 +116,9 @@ class DistributedPhone(DistributedFurnitureItem.DistributedFurnitureItem):
def setupCamera(self, mode):
camera.wrtReparentTo(render)
if mode == PhoneGlobals.PHONE_MOVIE_PICKUP:
camera.lerpPosHpr(4, -4, base.localAvatar.getHeight() - 0.5, 35, -8, 0, 1, other=base.localAvatar, blendType='easeOut', task=self.uniqueName('lerpCamera'))
quat = Quat()
quat.setHpr((35, -8, 0))
LerpPosQuatInterval(camera, 1, (4, -4, base.localAvatar.getHeight() - 0.5), quat, blendType='easeOut', other=base.localAvatar).start()
def setupCord(self):
if self.cord:
@ -173,7 +175,8 @@ class DistributedPhone(DistributedFurnitureItem.DistributedFurnitureItem):
return
if self.hasLocalAvatar:
self.freeAvatar()
base.localAvatar.lookupPetDNA()
if base.config.GetBool('want-pets', 1):
base.localAvatar.lookupPetDNA()
self.notify.debug('Entering Phone Sphere....')
taskMgr.remove(self.uniqueName('ringDoLater'))
self.ignore(self.phoneSphereEnterEvent)
@ -209,22 +212,26 @@ class DistributedPhone(DistributedFurnitureItem.DistributedFurnitureItem):
self.ignore(self.pickupMovieDoneEvent)
if avId != 0:
self.lastAvId = avId
self.lastTime = globalClock.getFrameTime()
isLocalToon = avId == base.localAvatar.doId
avatar = self.cr.doId2do.get(avId)
self.notify.debug('setMovie: %s %s %s' % (mode, avId, isLocalToon))
if mode == PhoneGlobals.PHONE_MOVIE_CLEAR:
self.notify.debug('setMovie: clear')
self.numHouseItems = None
if self.phoneInUse:
self.clearInterval()
self.phoneInUse = 0
elif mode == PhoneGlobals.PHONE_MOVIE_EMPTY:
self.notify.debug('setMovie: empty')
if isLocalToon:
self.phoneDialog = TTDialog.TTDialog(dialogName='PhoneEmpty', style=TTDialog.Acknowledge, text=TTLocalizer.DistributedPhoneEmpty, text_wordwrap=15, fadeScreen=1, command=self.__clearDialog)
self.numHouseItems = None
self.phoneInUse = 0
elif mode == PhoneGlobals.PHONE_MOVIE_PICKUP:
self.notify.debug('setMovie: gui')
if avatar:
@ -235,6 +242,7 @@ class DistributedPhone(DistributedFurnitureItem.DistributedFurnitureItem):
self.acceptOnce(self.pickupMovieDoneEvent, self.__showPhoneGui)
self.playInterval(interval, elapsed, avatar)
self.phoneInUse = 1
elif mode == PhoneGlobals.PHONE_MOVIE_HANGUP:
self.notify.debug('setMovie: gui')
if avatar:
@ -242,6 +250,7 @@ class DistributedPhone(DistributedFurnitureItem.DistributedFurnitureItem):
self.playInterval(interval, elapsed, avatar)
self.numHouseItems = None
self.phoneInUse = 0
else:
self.notify.warning('unknown mode in setMovie: %s' % mode)
return
@ -269,10 +278,7 @@ class DistributedPhone(DistributedFurnitureItem.DistributedFurnitureItem):
print 'in the client phone'
blob = item.getBlob(store=CatalogItem.Customization)
context = self.getCallbackContext(callback, [item])
self.sendUpdate('requestGiftPurchaseMessage', [context,
targetDoID,
blob,
optional])
self.sendUpdate('requestGiftPurchaseMessage', [context, targetDoID, blob, optional])
def requestPurchaseResponse(self, context, retcode):
self.doCallbackContext(context, [retcode])

View file

@ -1,20 +1,84 @@
from direct.directnotify import DirectNotifyGlobal
from toontown.estate.DistributedFurnitureItemAI import DistributedFurnitureItemAI
from toontown.toonbase import ToontownGlobals
from toontown.catalog import CatalogItem
from toontown.catalog.CatalogItemList import CatalogItemList
from direct.distributed.ClockDelta import *
import time
import PhoneGlobals
class DistributedPhoneAI(DistributedFurnitureItemAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedPhoneAI")
def setInitialScale(self, todo0, todo1, todo2):
def __init__(self, air, furnitureMgr, item):
DistributedFurnitureItemAI.__init__(self, air, furnitureMgr, item)
self.avId = None
def setInitialScale(self, sx, sy, sz):
pass
def setNewScale(self, todo0, todo1, todo2):
pass
def getInitialScale(self):
return (1, 1, 1)
def setNewScale(self, sx, sy, sz):
if sx + sy + sz < 5:
return
self.sendUpdate('setInitialScale', [sx, sy, sz])
def avatarEnter(self):
pass
avId = self.air.getAvatarIdFromSender()
if self.avId:
if self.avId == avId:
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to use a phone twice!')
return
self.sendUpdateToAvatarId(avId, 'freeAvatar', [])
return
av = self.air.doId2do.get(avId)
if not av:
return
if not av.houseId:
# Let's not deal with toons that have no houses, pls.
self.sendUpdateToAvatarId(avId, 'freeAvatar', [])
return
if len(av.monthlyCatalog) == 0 and len(av.weeklyCatalog) == 0 and len(av.backCatalog) == 0:
self.d_setMovie(PhoneGlobals.PHONE_MOVIE_EMPTY, avId, globalClockDelta.getRealNetworkTime())
taskMgr.doMethodLater(1, self.__resetMovie, 'resetMovie-%d' % self.getDoId(), extraArgs=[])
self.notify.debug("No Catalogs")
return
self.air.questManager.toonCalledClarabelle(av)
self.notify.debug("Loading the catalog")
self.avId = avId
self.d_setMovie(PhoneGlobals.PHONE_MOVIE_PICKUP, avId, globalClockDelta.getRealNetworkTime())
house = self.air.doId2do.get(av.houseId)
if house:
numItems = len(house.interiorItems) + len(house.atticItems) + len(house.atticWallpaper) + len(house.atticWindows) + len (house.interiorWallpaper) + len(house.interiorWindows)
self.sendUpdateToAvatarId(avId, 'setLimits', [numItems])
else:
self.air.dbInterface.queryObject(self.air.dbId, av.houseId, self.__gotHouse)
av.b_setCatalogNotify(ToontownGlobals.NoItems, av.mailboxNotify)
def __gotHouse(self, dclass, fields):
if dclass != self.air.dclassesByName['DistributedHouseAI']:
return #rip
# this is too long
numItems = len(CatalogItemList(fields['setInteriorItems'][0], store=CatalogItem.Customization)) + len(CatalogItemList(fields['setAtticItems'][0], store=CatalogItem.Customization)) + len(CatalogItemList(fields['setAtticWallpaper'][0], store=CatalogItem.Customization)) + len(CatalogItemList(fields['setAtticWindows'][0], store=CatalogItem.Customization)) + len(CatalogItemList(fields['setInteriorWallpaper'][0], store=CatalogItem.Customization)) + len(CatalogItemList(fields['setInteriorWindows'][0], store=CatalogItem.Customization))
self.sendUpdateToAvatarId(fields['setAvatarId'][0], 'setLimits', [numItems])
def avatarExit(self):
pass
avId = self.air.getAvatarIdFromSender()
if avId != self.avId:
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to exit a phone they weren\'t using!')
return
self.avId = None
self.d_setMovie(PhoneGlobals.PHONE_MOVIE_HANGUP, avId, globalClockDelta.getRealNetworkTime())
taskMgr.doMethodLater(1, self.__resetMovie, 'resetMovie-%d' % self.getDoId(), extraArgs=[])
def freeAvatar(self):
pass
@ -25,8 +89,49 @@ class DistributedPhoneAI(DistributedFurnitureItemAI):
def setMovie(self, todo0, todo1, todo2):
pass
def requestPurchaseMessage(self, todo0, todo1, todo2):
pass
def d_setMovie(self, mode, avId, time):
self.sendUpdate('setMovie', [mode, avId, time])
def __resetMovie(self):
self.d_setMovie(PhoneGlobals.PHONE_MOVIE_CLEAR, 0, globalClockDelta.getRealNetworkTime())
def requestPurchaseMessage(self, context, item, optional):
avId = self.air.getAvatarIdFromSender()
if avId != self.avId:
self.air.writeServerEvent('suspicious', avId=avId, issue='Tried to purchase while not using the phone!')
return
av = self.air.doId2do.get(avId)
if not av:
self.air.writeServerEvent('suspicious', avId=avId, issue='Used phone from other shard!')
return
item = CatalogItem.getItem(item)
if item in av.backCatalog:
price = item.getPrice(CatalogItem.CatalogTypeBackorder)
elif item in av.weeklyCatalog or item in av.monthlyCatalog:
price = item.getPrice(0)
else:
return
if item.getDeliveryTime():
if len(av.onOrder) > 3: #TODO correct number
self.sendUpdateToAvatarId(avId, 'requestPurchaseResponse', [context, ToontownGlobals.P_OnOrderListFull])
return
if len(av.mailboxContents) + len(av.onOrder) >= ToontownGlobals.MaxMailboxContents:
self.sendUpdateToAvatarId(avId, 'requestPurchaseResponse', [context, ToontownGlobals.P_MailboxFull])
if not av.takeMoney(price):
return
item.deliveryDate = int(time.time()/60) + item.getDeliveryTime()
av.onOrder.append(item)
av.b_setDeliverySchedule(av.onOrder)
self.sendUpdateToAvatarId(avId, 'requestPurchaseResponse', [context, ToontownGlobals.P_ItemOnOrder])
else:
if not av.takeMoney(price):
#u wot m8
return
resp = item.recordPurchase(av, optional)
if resp < 0: # refund if purchase unsuccessful
av.addMoney(price)
self.sendUpdateToAvatarId(avId, 'requestPurchaseResponse', [context, resp])
def requestPurchaseResponse(self, todo0, todo1):
pass
@ -36,4 +141,4 @@ class DistributedPhoneAI(DistributedFurnitureItemAI):
def requestGiftPurchaseResponse(self, todo0, todo1):
pass

View file

@ -5,6 +5,7 @@ from toontown.estate.DistributedEstateAI import DistributedEstateAI
from toontown.estate.DistributedHouseAI import DistributedHouseAI
import HouseGlobals
import functools
from toontown.toon.ToonDNA import ToonDNA
class LoadHouseFSM(FSM):
def __init__(self, mgr, estate, houseIndex, toon, callback):
@ -74,13 +75,19 @@ class LoadHouseFSM(FSM):
self.demand('LoadHouse')
def enterLoadHouse(self):
# Quickly parse DNA and get gender.
dna = ToonDNA()
dna.makeFromNetString(self.toon['setDNAString'][0])
gender = 1 if dna.getGender() == 'm' else 0
# Activate the house:
self.mgr.air.sendActivate(self.houseId, self.mgr.air.districtId, self.estate.zoneId,
self.mgr.air.dclassesByName['DistributedHouseAI'],
{'setHousePos': [self.houseIndex],
'setColor': [self.houseIndex],
'setName': [self.toon['setName'][0]],
'setAvatarId': [self.toon['ID']]})
'setAvatarId': [self.toon['ID']],
'setGender': [gender]})
# Now we wait for the house to show up... We do this by hanging a messenger
# hook which the DistributedHouseAI throws once it spawns.
@ -180,6 +187,15 @@ class LoadEstateFSM(FSM):
if self.state != 'CreateEstate':
return # We must have aborted or something...
self.estateId = estateId
# Update our account so we can store this new estate object.
self.mgr.air.dbInterface.updateObject(
self.mgr.air.dbId,
self.accountId,
self.mgr.air.dclassesByName['AccountAI'],
{ 'ESTATE_ID': estateId }
)
self.demand('LoadEstate')
def enterLoadEstate(self):
@ -193,6 +209,9 @@ class LoadEstateFSM(FSM):
def __gotEstate(self, estate):
self.estate = estate
self.estate.toons = self.toonIds
self.estate.updateToons()
# Gotcha! Now we need to load houses:
self.demand('LoadHouses')
@ -236,14 +255,14 @@ class LoadEstateFSM(FSM):
class EstateManagerAI(DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory("EstateManagerAI")
def __init__(self, air):
DistributedObjectAI.__init__(self, air)
self.estate2toons = {}
self.toon2estate = {}
self.estate2timeout = {}
def getEstateZone(self, avId):
senderId = self.air.getAvatarIdFromSender()
accId = self.air.getAccountIdFromSender()

View file

@ -56,46 +56,36 @@ atticWood = (0.49, 0.314, 0.224)
stairWood = (0.651, 0.376, 0.31)
doorWood = (0.647, 0.392, 0.353)
windowWood = (0.557, 0.388, 0.2)
interiors = [['phase_5.5/dna/house_interior3.xml',
[-19.45,
24.7018,
0,
0,
0,
0],
[-21.4932,
5.76027,
0,
120,
0,
0],
[]], ['phase_5.5/dna/house_interior7.xml',
[-19.45,
24.7018,
0,
0,
0,
0],
[-21.4932,
5.76027,
0,
120,
0,
0],
[]], ['phase_5.5/dna/house_interior10.xml',
[-22.5835,
21.8784,
0,
90,
0,
0],
[-20.96,
6.49,
0,
120,
0,
0],
['c', 'e']]]
interiors = [
[
'phase_5.5/dna/house_interior1.xml', # House Layout
[-19.45, 24.7018, 0, 0, 0, 0], # Closet Position (Unused, set in DNA)
[-21.4932, 5.76027, 0, 120, 0, 0], # Bean Bank Position (Unused, set in DNA)
[], # ???
[-11, 2, 0, 0, 0, 0] # Phone Position
],
[
'phase_5.5/dna/house_interior2.xml',
[-19.45, 24.7018, 0, 0, 0, 0],
[-21.4932, 5.76027, 0, 120, 0, 0],
[],
[-11, 2, 0, 0, 0, 0]
],
[
'phase_5.5/dna/house_interior3.xml',
[-22.5835, 21.8784, 0, 90, 0, 0],
[-20.96, 6.49, 0, 120, 0, 0],
['c', 'e'],
[-11, 2, 0, 0, 0, 0]
],
[
'phase_5.5/dna/house_interior4.xml',
[-22.5835, 21.8784, 0, 90, 0, 0],
[-20.96, 6.49, 0, 120, 0, 0],
['c', 'e'],
[-11, 2, 0, 0, 0, 0]
]
]
NUM_PROPS = 3
PROP_ICECUBE = 0
PROP_FLOWER = 1

View file

@ -431,7 +431,7 @@ class ObjectManager(NodePath, DirectObject):
self.objectDict = {}
for item in dfitems:
mo = MovableObject(item, parent=self.targetNodePath)
self.objectDict[mo.id()] = mo
self.objectDict[mo.get_key()] = mo
def setCamPosIndex(self, index):
self.camPosIndex = index
@ -469,7 +469,7 @@ class ObjectManager(NodePath, DirectObject):
def loadObject(self, filename):
mo = MovableObject(filename, parent=self.targetNodePath)
self.objectDict[mo.id()] = mo
self.objectDict[mo.get_key()] = mo
self.selectObject(mo)
return mo
@ -490,6 +490,7 @@ class ObjectManager(NodePath, DirectObject):
messenger.send('wakeup')
if self.selectedObject:
self.deselectObject()
if selectedObject:
self.selectedObject = selectedObject
self.deselectEvent = self.selectedObject.dfitem.uniqueName('disable')
@ -504,9 +505,22 @@ class ObjectManager(NodePath, DirectObject):
self.lnp.create()
self.buttonFrame.show()
self.enableButtonFrameTask()
self.sendToAtticButton.show()
self.atticRoof.hide()
# We dont want to move the Closet, Phone, Bank or Trunk to the attic
if config.GetBool('want-permanent-interactables', True):
if selectedObject.dfitem.item.getFlags() & CatalogFurnitureItem.FLCloset or \
selectedObject.dfitem.item.getFlags() & CatalogFurnitureItem.FLPhone or \
selectedObject.dfitem.item.getFlags() & CatalogFurnitureItem.FLBank or \
selectedObject.dfitem.item.getFlags() &CatalogFurnitureItem.FLTrunk:
self.sendToAtticButton.hide()
self.atticRoof.show()
else:
self.sendToAtticButton.show()
return
self.sendToAtticButton.show()
def deselectObject(self):
self.moveObjectStop()
if self.deselectEvent:
@ -528,7 +542,7 @@ class ObjectManager(NodePath, DirectObject):
if np.isEmpty():
return None
else:
return self.objectDict.get(np.id(), None)
return self.objectDict.get(np.get_key(), None)
return None
def moveObjectStop(self, *args):
@ -1155,7 +1169,7 @@ class ObjectManager(NodePath, DirectObject):
self.notify.info('QA-REGRESSION: ESTATE: Send Item to Attic')
messenger.send('wakeup')
if self.selectedObject:
callback = PythonUtil.Functor(self.__sendItemToAtticCallback, self.selectedObject.id())
callback = PythonUtil.Functor(self.__sendItemToAtticCallback, self.selectedObject.get_key())
self.furnitureManager.moveItemToAttic(self.selectedObject.dfitem, callback)
self.deselectObject()
@ -1165,7 +1179,7 @@ class ObjectManager(NodePath, DirectObject):
self.notify.info('Unable to send item %s to attic, reason %s.' % (item.getName(), retcode))
return
del self.objectDict[objectId]
if self.selectedObject != None and self.selectedObject.id() == objectId:
if self.selectedObject != None and self.selectedObject.get_key() == objectId:
self.selectedObject.detachNode()
self.deselectObject()
itemIndex = len(self.atticItemPanels)
@ -1244,7 +1258,7 @@ class ObjectManager(NodePath, DirectObject):
self.notify.info('Unable to delete item %s from room, reason %s.' % (item.getName(), retcode))
return
del self.objectDict[objectId]
if self.selectedObject != None and self.selectedObject.id() == objectId:
if self.selectedObject != None and self.selectedObject.get_key() == objectId:
self.selectedObject.detachNode()
self.deselectObject()
if self.inRoomPicker and itemIndex is not None:
@ -1294,7 +1308,7 @@ class ObjectManager(NodePath, DirectObject):
self.notify.info('Unable to bring furniture item %s into room, reason %s.' % (itemIndex, retcode))
return
mo = self.loadObject(dfitem)
objectId = mo.id()
objectId = mo.get_key()
self.atticItemPanels[itemIndex].destroy()
del self.atticItemPanels[itemIndex]
for i in range(itemIndex, len(self.atticItemPanels)):

View file

@ -159,6 +159,12 @@ class QuestManagerAI:
self.__incrementQuestProgress(toon.quests[index])
toon.updateQuests()
def toonCalledClarabelle(self, toon):
for index, quest in enumerate(self.__toonQuestsList2Quests(toon.quests)):
if isinstance(quest, Quests.PhoneQuest):
self.__incrementQuestProgress(toon.quests[index])
toon.updateQuests()
def completeQuest(self, toon, questId):
"""
@ -189,7 +195,7 @@ class QuestManagerAI:
# If non-zero, this indicates this is the first quest in the whole ToonTask.
# This means we want to store the reward in the toons setRewardHistory.
finalReward = rewardId if storeReward else 0
progress = 1 if questId == Quests.PHONE_QUEST_ID else 0 # hacky fix to cattlelog quest...
progress = 0
toon.addQuest((questId, npc.getDoId(), toNpcId, rewardId, progress), finalReward)
# Tell the NPC that we assigned this quest to the given toon.
npc.assignQuest(toon.getDoId(), questId, rewardId, toNpcId)

View file

@ -344,6 +344,7 @@ class Suit(Avatar.Avatar):
Avatar.Avatar.__init__(self)
self.setFont(ToontownGlobals.getSuitFont())
self.setSpeechFont(ToontownGlobals.getSuitFont())
self.setPlayerType(NametagGroup.CCSuit)
self.setPickable(1)
self.leftHand = None

View file

@ -8,7 +8,7 @@ from toontown.estate import ClosetGlobals
class DistributedNPCTailorAI(DistributedNPCToonBaseAI):
freeClothes = simbase.config.GetBool('free-clothes', 0)
housingEnabled = simbase.config.GetBool('want-housing', 1)
useJellybeans = simbase.config.GetBool('want-tailor-jellybeans', True)
useJellybeans = simbase.config.GetBool('want-tailor-jellybeans', False)
def __init__(self, air, npcId):
DistributedNPCToonBaseAI.__init__(self, air, npcId)
@ -43,10 +43,10 @@ class DistributedNPCTailorAI(DistributedNPCToonBaseAI):
if testDNA.head != av.dna.head:
return False
if testDNA.torso != av.dna.torso:
# TODO: Check that they aren't changing torso size, but only skirt/shorts.
# Male toons can never change, but girls can change between skirt and shorts.
if av.dna.gender == 'm':
return False
elif testDNA.torso[0] != av.dna.torso[0]: #first character of torso ('size') must remain the same, otherwise you are hacker scum.
return False
if testDNA.legs != av.dna.legs:
return False
if testDNA.gender != av.dna.gender:

View file

@ -2180,7 +2180,6 @@ class DistributedToon(DistributedPlayer.DistributedPlayer, Toon.Toon, Distribute
else:
self.setFont(ToontownGlobals.getNametagFont(self.getNametagStyle()))
Avatar.Avatar.setDisplayName(self, name)
self.setFont(ToontownGlobals.getToonFont())
return
def removeFancyNametag(self):
@ -2624,7 +2623,7 @@ class DistributedToon(DistributedPlayer.DistributedPlayer, Toon.Toon, Distribute
else:
self.gmToonLockStyle = False
self.removeGMIcon()
self.setNametagStyle(0)
self.setNametagStyle(100)
def setGMIcon(self, gmType = None):
if hasattr(self, 'gmIcon') and self.gmIcon:

View file

@ -584,6 +584,28 @@ class DistributedToonAI(DistributedPlayerAI.DistributedPlayerAI, DistributedSmoo
if self.dna.getAnimal() == 'cat':
allowedColors = allowedColors + [26]
if 26 in [self.dna.legColor, self.dna.armColor, self.dna.headColor]: # Disney ALSO didn't do this. Verify that a toon is fully black/white.
if self.dna.legColor != 26:
self.dna.legColor = 26
changed = True
if self.dna.armColor != 26:
self.dna.armColor = 26
changed = True
if self.dna.headColor != 26:
self.dna.headColor = 26
changed = True
elif 0 in [self.dna.legColor, self.dna.armColor, self.dna.headColor]:
if self.dna.legColor != 0:
self.dna.legColor = 0
changed = True
if self.dna.armColor != 0:
self.dna.armColor = 0
changed = True
if self.dna.headColor != 0:
self.dna.headColor = 0
changed = True
if self.dna.legColor not in allowedColors:
self.dna.legColor = allowedColors[0]
changed = True
@ -2498,7 +2520,7 @@ class DistributedToonAI(DistributedPlayerAI.DistributedPlayerAI, DistributedSmoo
now = int(time.time() / 60 + 0.5)
delivered, remaining = self.onOrder.extractDeliveryItems(now)
deliveredGifts, remainingGifts = self.onGiftOrder.extractDeliveryItems(now)
simbase.air.deliveryManager.sendDeliverGifts(self.getDoId(), now)
#simbase.air.deliveryManager.sendDeliverGifts(self.getDoId(), now) TODO DeliveryManager
giftItem = CatalogItemList.CatalogItemList(deliveredGifts, store=CatalogItem.Customization | CatalogItem.DeliveryDate)
if len(giftItem) > 0:
self.air.writeServerEvent('Getting Gift', avId=self.doId, msg='sender %s receiver %s gift %s' % (giftItem[0].giftTag, self.doId, giftItem[0].getName()))
@ -5100,7 +5122,7 @@ def locate(avIdShort=0, returnType=''):
return "%s has been located %s %s, inside a building." % (av.getName(), where[1], where[2])
return "%s has been located %s %s." % (av.getName(), where[1], where[2])
@magicWord(category=CATEGORY_OVERRIDE, types=[int])
@magicWord(category=CATEGORY_MODERATION, types=[int])
def online(doId):
""" Check if a toon is online. """
av = spellbook.getTarget()
@ -5284,6 +5306,10 @@ def fanfare():
spellbook.getTarget().magicFanfare()
return "Jason: Because the trumpets they go...~"
@magicWord(category=CATEGORY_OVERRIDE)
def catalog():
simbase.air.catalogManager.deliverCatalogFor(spellbook.getTarget())
@magicWord(category=CATEGORY_CHARACTERSTATS, types=[int])
def pouch(amt):
""" Set the target's max gag limit. """
@ -5346,3 +5372,88 @@ def correctlaff():
av = spellbook.getTarget()
av.correctToonLaff()
return "Corrected %s's laff successfully." % av.getName()
@magicWord(category=CATEGORY_CHARACTERSTATS, types=[str])
def nametag(styleName):
"""
Set the style of the target's nametag to the specified ID.
Examples are 100 for basic, 0 for simple.
"""
nametag_list = list(TTLocalizer.NametagFontNames)
for index, item in enumerate(nametag_list):
nametag_list[index] = item.lower()
styleName = styleName.lower()
if styleName in nametag_list:
index = nametag_list.index(styleName)
elif styleName == "basic":
index = 100
else:
return "Invalid nametag name entered."
spellbook.getTarget().b_setNametagStyle(index)
return "Set %s's nametag style successfully." % spellbook.getTarget().getName()
@magicWord(category=CATEGORY_CHARACTERSTATS, types=[str])
def animations():
"""
Unlock all of the animations on the target toon.
This exclutes the "Toons of the world unite!" phrase. (because it sucks)
"""
av = spellbook.getTarget()
emotes = list(av.getEmoteAccess())
# Ripped directly from alpha days, cause I'm lazy.
# Get this list out of OTPLocalizerEnglish.py
ALPHA_EMOTES = ['Wave', 'Happy', 'Sad', 'Angry', 'Sleepy',
'Dance', 'Think', 'Bored', 'Applause', 'Cringe',
'Confused', 'Bow', 'Delighted', 'Belly Flop', 'Banana Peel',
'Shrug', 'Surprise', 'Furious',
'Laugh', 'Cry']
for emote in ALPHA_EMOTES:
emoteId = OTPLocalizer.EmoteFuncDict.get(emote)
if emoteId is None: continue
emotes[emoteId] = 1
av.b_setEmoteAccess(emotes)
return "Unlocked all animations for %s." % av.getName()
@magicWord(category=CATEGORY_CHARACTERSTATS, types=[str])
def phrase(phraseStringOrId):
"""
Unlocks a new phrase and adds it to target's list of "My Phrases".
If the phrase list is full, the top item will be knocked off and the
requested one will be appended to the bottom.
"""
strings = OTPLocalizer.CustomSCStrings
av = spellbook.getTarget()
# hack check if int (fuck .isdigit())
try:
scId = int(phraseStringOrId)
if scId in strings.iterkeys():
id = scId
else:
id = None
except ValueError:
# It's a string! Search phrase by string.
id = None
phraseString = phraseStringOrId
for scId, string in strings.iteritems():
if string.lower() == phraseString.lower():
id = scId
break
if id is None:
return "Unable to match string to a custom phrase."
else:
if av.customMessages.count(id) != 0:
return "%s already has this custom phrase!" % av.getName()
if len(av.customMessages) >= ToontownGlobals.MaxCustomMessages:
av.customMessages = av.customMessages[1:] # get rid of the first phrase.
av.customMessages.append(id)
av.d_setCustomMessages(av.customMessages)
return "Added new phrase to %s's custom phrases." % av.getName()

View file

@ -60,7 +60,7 @@ from toontown.toontowngui import NewsPageButtonManager
if WantNewsPage:
from toontown.shtiker import NewsPage
AdjustmentForNewsButton = -0.275
ClaraBaseXPos = 1.45
ClaraBaseXPos = 0.12
if (__debug__):
import pdb
@ -1006,7 +1006,7 @@ class LocalToon(DistributedToon.DistributedToon, LocalAvatar.LocalAvatar):
if show:
claraXPos += AdjustmentForNewsButton
notifyXPos += AdjustmentForNewsButton
newPos = (claraXPos - 0.1, 1.0, 0.45)
newPos = (claraXPos - 0.1, 1.0, -0.63)
self.__clarabelleButton.setPos(newPos)
if self.__catalogNotifyDialog == None or self.__catalogNotifyDialog.frame == None:
return
@ -1027,14 +1027,14 @@ class LocalToon(DistributedToon.DistributedToon, LocalAvatar.LocalAvatar):
icon.setColor(white)
claraXPos = ClaraBaseXPos
newScale = oldScale = 0.5
newPos = (claraXPos, 1.0, 0.37)
newPos = (claraXPos, 1.0, -0.63)
if WantNewsPage:
claraXPos += AdjustmentForNewsButton
oldPos = ((claraXPos, 1.0, 0.37),)
oldPos = ((claraXPos, 1.0, -0.63))
newScale = oldScale * ToontownGlobals.NewsPageScaleAdjust
newPos = (claraXPos - 0.1, 1.0, 0.45)
newPos = (claraXPos - 0.1, 1.0, -0.63)
self.__clarabelleButton = DirectButton(relief=None, image=circle, text='', text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), text_scale=0.1, text_pos=(-1.06, 1.06), text_font=ToontownGlobals.getInterfaceFont(), pos=newPos, scale=newScale, command=self.__handleClarabelleButton)
self.__clarabelleButton.reparentTo(aspect2d, DGG.BACKGROUND_SORT_INDEX - 1)
self.__clarabelleButton.reparentTo(base.a2dTopRight, DGG.BACKGROUND_SORT_INDEX - 1)
button = self.__clarabelleButton.stateNodePath[0]
self.__clarabelleFlash = Sequence(LerpColorInterval(button, 2, white, blendType='easeInOut'), LerpColorInterval(button, 2, rgba, blendType='easeInOut'))
self.__clarabelleFlash.loop()
@ -1049,7 +1049,7 @@ class LocalToon(DistributedToon.DistributedToon, LocalAvatar.LocalAvatar):
self.__clarabelleButton['text'] = ['', TTLocalizer.CatalogNewCatalogButton, TTLocalizer.CatalogNewCatalogButton]
if not self.mailboxNotify and not self.awardNotify and self.catalogNotify == ToontownGlobals.OldItems and (self.simpleMailNotify != ToontownGlobals.NoItems or self.inviteMailNotify != ToontownGlobals.NoItems):
self.__clarabelleButton['text'] = ['', TTLocalizer.MailNewMailButton, TTLocalizer.MailNewMailButton]
if self.newsButtonMgr.isNewIssueButtonShown():
if self.newsButtonMgr.isNewIssueButtonShown() and WantNewsPage:
self.clarabelleNewsPageCollision(True)
self.__clarabelleButton.show()
self.__clarabelleFlash.resume()

View file

@ -504,6 +504,7 @@ class Toon(Avatar.Avatar, ToonHead):
self.jar = None
self.setTag('pieCode', str(ToontownGlobals.PieCodeToon))
self.setFont(ToontownGlobals.getToonFont())
self.setSpeechFont(ToontownGlobals.getToonFont())
self.soundChatBubble = base.loadSfx('phase_3/audio/sfx/GUI_balloon_popup.ogg')
self.animFSM = ClassicFSM('Toon', [State('off', self.enterOff, self.exitOff),
State('neutral', self.enterNeutral, self.exitNeutral),
@ -2971,6 +2972,7 @@ class Toon(Avatar.Avatar, ToonHead):
self.suit.loop('neutral')
self.isDisguised = 1
self.setFont(ToontownGlobals.getSuitFont())
self.setSpeechFont(ToontownGlobals.getSuitFont())
if setDisplayName:
if hasattr(base, 'idTags') and base.idTags:
name = self.getAvIdName()
@ -3004,6 +3006,7 @@ class Toon(Avatar.Avatar, ToonHead):
Emote.globalEmote.releaseAll(self)
self.isDisguised = 0
self.setFont(ToontownGlobals.getToonFont())
self.setSpeechFont(ToontownGlobals.getToonFont())
self.nametag.setWordwrap(None)
if hasattr(base, 'idTags') and base.idTags:
name = self.getAvIdName()

View file

@ -87,7 +87,7 @@ class ToonAvatarPanel(AvatarPanelBase.AvatarPanelBase):
pos=(0.0125, 0, 0.4),
relief=None,
text=self.avName,
text_font=avatar.getFont(),
text_font=ToontownGlobals.getInterfaceFont(),
text_fg=Vec4(0, 0, 0, 1),
text_pos=(0, 0),
text_scale=0.042,

View file

@ -175,7 +175,8 @@ toonTorsoTypes = ['ss',
'm',
'l']
toonLegTypes = ['s', 'm', 'l']
Shirts = ['phase_3/maps/desat_shirt_1.jpg',
Shirts = [
'phase_3/maps/desat_shirt_1.jpg',
'phase_3/maps/desat_shirt_2.jpg',
'phase_3/maps/desat_shirt_3.jpg',
'phase_3/maps/desat_shirt_4.jpg',
@ -327,8 +328,10 @@ Shirts = ['phase_3/maps/desat_shirt_1.jpg',
'phase_4/maps/tt_t_chr_avt_shirt_saveBuilding05.jpg',
'phase_4/maps/tt_t_chr_avt_shirt_anniversary.jpg',
'phase_4/maps/tt_t_chr_avt_shirt_sora.jpg',
'phase_4/maps/tt_t_chr_avt_shirt_slappy.jpg']
BoyShirts = [(0, 0),
'phase_4/maps/tt_t_chr_avt_shirt_slappy.jpg'
]
BoyShirts = [
(0, 0),
(1, 1),
(2, 2),
(3, 3),
@ -342,8 +345,10 @@ BoyShirts = [(0, 0),
(16, 0),
(17, 0),
(18, 12),
(19, 13)]
GirlShirts = [(0, 0),
(19, 13)
]
GirlShirts = [
(0, 0),
(1, 1),
(2, 2),
(3, 3),
@ -357,7 +362,8 @@ GirlShirts = [(0, 0),
(16, 0),
(20, 0),
(21, 0),
(22, 0)]
(22, 0)
]
def isValidBoyShirt(index):
for pair in BoyShirts:

View file

@ -28,7 +28,7 @@ NametagFonts = ('phase_3/models/fonts/AnimGothic',
'phase_3/models/fonts/Alie',
'phase_3/models/fonts/OysterBar',
'phase_3/models/fonts/RedDogSaloon')
NametagFontNames = ('Member',
NametagFontNames = ('Simple',
'Shivering',
'Wonky',
'Fancy',
@ -6448,7 +6448,7 @@ FurnitureNames = {100: 'Armchair',
1320: '5000 Bean Bank',
1330: '7500 Bean Bank',
1340: '10000 Bean Bank',
1350: '12000 Bean Bank',
1350: '15000 Bean Bank',
1399: 'Telephone',
1400: 'Cezanne Toon',
1410: 'Flowers',

View file

@ -113,6 +113,8 @@ class NewsPageButtonManager(FSM.FSM):
self.__blinkIval.pause()
def isNewIssueButtonShown(self):
if not base.config.GetBool('want-news-tab', 1):
return False
if localAvatar.getLastTimeReadNews() < base.cr.inGameNewsMgr.getLatestIssue():
return True
return False

View file

@ -146,6 +146,7 @@ class TutorialManagerAI(DistributedObjectAI):
av.b_setTutorialAck(1)
av.b_setQuestHistory([110, 100])
av.addQuest((110, Quests.getQuestFromNpcId(110), Quests.getQuestToNpcId(110), Quests.getQuestReward(110, av), 0), 0)
self.air.questManager.toonRodeTrolleyFirstTime(av) #gg hacky
self.d_skipTutorialResponse(avId, 1)
else:
self.d_skipTutorialResponse(avId, 0)