From 8bf8cf5f556c1de05c7917fac7050009d1694bf3 Mon Sep 17 00:00:00 2001 From: Zach Date: Sun, 24 May 2015 18:23:54 -0500 Subject: [PATCH] GARDENING, BITCHES --- astron/dclass/united.dc | 40 ++-- otp/avatar/LocalAvatar.py | 5 +- otp/distributed/Account.py | 6 +- otp/distributed/DCClassImports.py | 2 +- .../distributed/ConnectionRepository.py | 4 + panda/direct/showbase/PythonUtil.py | 4 +- toontown/catalog/CatalogGardenItem.py | 5 +- toontown/catalog/CatalogGardenStarterItem.py | 9 +- .../coderedemption/TTCodeRedemptionMgrAI.py | 10 + .../estate/DistributedChangingStatuaryAI.py | 12 +- toontown/estate/DistributedEstate.py | 4 + toontown/estate/DistributedEstateAI.py | 139 ++++++++++++- toontown/estate/DistributedFlower.py | 13 +- toontown/estate/DistributedFlowerAI.py | 16 +- toontown/estate/DistributedGagTree.py | 13 +- toontown/estate/DistributedGagTreeAI.py | 27 ++- toontown/estate/DistributedGardenBox.py | 2 +- toontown/estate/DistributedGardenBoxAI.py | 4 + toontown/estate/DistributedGardenPlot.py | 60 ++++-- toontown/estate/DistributedGardenPlotAI.py | 191 ++++++++++++++++-- toontown/estate/DistributedLawnDecor.py | 51 ++++- toontown/estate/DistributedLawnDecorAI.py | 57 ++++-- toontown/estate/DistributedPlantBase.py | 14 +- toontown/estate/DistributedPlantBaseAI.py | 75 ++++++- toontown/estate/DistributedStatuary.py | 6 + toontown/estate/DistributedStatuaryAI.py | 34 +++- toontown/estate/DistributedToonStatuaryAI.py | 12 +- toontown/estate/EstateManagerAI.py | 1 + toontown/estate/GardenGlobals.py | 87 ++++---- toontown/estate/HouseGlobals.py | 15 +- toontown/estate/SpecialsPhoto.py | 9 +- toontown/toon/DistributedToon.py | 2 +- toontown/toon/DistributedToonAI.py | 16 ++ 33 files changed, 744 insertions(+), 201 deletions(-) diff --git a/astron/dclass/united.dc b/astron/dclass/united.dc index c8966c4e..b5d7108d 100644 --- a/astron/dclass/united.dc +++ b/astron/dclass/united.dc @@ -1307,11 +1307,15 @@ struct decorItem { }; struct lawnItem { + int8 plot; uint8 type; - uint8 hardPoint; + uint8 species; + uint8 variety; int8 waterLevel; int8 growthLevel; uint16 optional; + uint64 plantedAt; + uint64 wateredAt; }; dclass DistributedEstate : DistributedObject { @@ -1329,17 +1333,17 @@ dclass DistributedEstate : DistributedObject { setRentalTimeStamp(uint32 timestamp = 0) required airecv db; setRentalType(uint8 type = 0) required airecv db; setSlot0ToonId(uint32 toonId = 0) required airecv db; - setSlot0Items(lawnItem items[] = []) required airecv db; + setSlot0Items(lawnItem items[] = []) required broadcast ownrecv db; setSlot1ToonId(uint32 toonId = 0) required airecv db; - setSlot1Items(lawnItem items[] = []) required airecv db; + setSlot1Items(lawnItem items[] = []) required broadcast ownrecv db; setSlot2ToonId(uint32 toonId = 0) required airecv db; - setSlot2Items(lawnItem items[] = []) required airecv db; + setSlot2Items(lawnItem items[] = []) required broadcast ownrecv db; setSlot3ToonId(uint32 toonId = 0) required airecv db; - setSlot3Items(lawnItem items[] = []) required airecv db; + setSlot3Items(lawnItem items[] = []) required broadcast ownrecv db; setSlot4ToonId(uint32 toonId = 0) required airecv db; - setSlot4Items(lawnItem items[] = []) required airecv db; + setSlot4Items(lawnItem items[] = []) required broadcast ownrecv db; setSlot5ToonId(uint32 toonId = 0) required airecv db; - setSlot5Items(lawnItem items[] = []) required airecv db; + setSlot5Items(lawnItem items[] = []) required broadcast ownrecv db; setIdList(uint32 []) broadcast ram; completeFlowerSale(uint8) airecv clsend; completeFishSale(uint8) airecv clsend; @@ -2714,23 +2718,27 @@ dclass DistributedLawbotChair : DistributedObject { }; dclass DistributedLawnDecor : DistributedNode { + setEstate(uint32) required broadcast ram; setPlot(int8) required broadcast ram; setHeading(int16/10) required broadcast ram; setPosition(int16/10, int16/10, int16/10) required broadcast ram; setOwnerIndex(int8) required broadcast ram; plotEntered() airecv clsend; - removeItem() airecv clsend; + removeItem(uint32) airecv clsend; setMovie(uint8, uint32) broadcast ram; movieDone() airecv clsend; interactionDenied(uint32) broadcast ram; }; dclass DistributedGardenPlot : DistributedLawnDecor { - plantFlower(uint8, uint8) airecv clsend; - plantGagTree(uint8, uint8) airecv clsend; - plantStatuary(uint8) airecv clsend; - plantToonStatuary(uint8, uint16) airecv clsend; - plantNothing(uint8) airecv clsend; + plantedItem(uint32) broadcast ram; + finishPlanting(uint32) airecv clsend; + finishRemoving(uint32) airecv clsend; + plantFlower(uint8, uint8, uint32) airecv clsend; + plantGagTree(uint8, uint8, uint32) airecv clsend; + plantStatuary(uint8, uint32) airecv clsend; + plantToonStatuary(uint8, uint16, uint32) airecv clsend; + plantNothing(uint8, uint32) airecv clsend; }; dclass DistributedGardenBox : DistributedLawnDecor { @@ -2738,6 +2746,7 @@ dclass DistributedGardenBox : DistributedLawnDecor { }; dclass DistributedStatuary : DistributedLawnDecor { + setOwnerPlot(uint32) required broadcast ram; setTypeIndex(uint8) required broadcast ram; setWaterLevel(int8) required broadcast ram; setGrowthLevel(int8) required broadcast ram; @@ -2755,10 +2764,11 @@ dclass DistributedChangingStatuary : DistributedStatuary { }; dclass DistributedPlantBase : DistributedLawnDecor { + setOwnerPlot(uint32) required broadcast ram; setTypeIndex(uint8) required broadcast ram; setWaterLevel(int8) required broadcast ram; setGrowthLevel(int8) required broadcast ram; - waterPlant() airecv clsend; + waterPlant(uint32) airecv clsend; waterPlantDone() airecv clsend; }; @@ -2769,7 +2779,7 @@ dclass DistributedFlower : DistributedPlantBase { dclass DistributedGagTree : DistributedPlantBase { setWilted(int8) required broadcast ram; - requestHarvest() airecv clsend; + requestHarvest(uint32) airecv clsend; }; struct golfData { diff --git a/otp/avatar/LocalAvatar.py b/otp/avatar/LocalAvatar.py index 205cafb8..cf29d310 100644 --- a/otp/avatar/LocalAvatar.py +++ b/otp/avatar/LocalAvatar.py @@ -629,8 +629,9 @@ class LocalAvatar(DistributedAvatar.DistributedAvatar, DistributedSmoothNode.Dis self.posCamera(1, 0.7) def unsetCameraPosForPetInteraction(self): - self.setIdealCameraPos(self.prevIdealPos) - del self.prevIdealPos + if hasattr(self, 'prevIdealPos'): + self.setIdealCameraPos(self.prevIdealPos) + del self.prevIdealPos self.posCamera(1, 0.7) def setCameraSettings(self, camSettings): diff --git a/otp/distributed/Account.py b/otp/distributed/Account.py index 6f0648bc..c0ff825b 100644 --- a/otp/distributed/Account.py +++ b/otp/distributed/Account.py @@ -1,6 +1,6 @@ -from direct.distributed import DistributedObject +from direct.distributed.DistributedObject import DistributedObject -class Account(DistributedObject.DistributedObject): +class Account(DistributedObject): def __init__(self, cr): - pass + DistributedObject.__init__(self, cr) diff --git a/otp/distributed/DCClassImports.py b/otp/distributed/DCClassImports.py index c5060377..e05779e7 100644 --- a/otp/distributed/DCClassImports.py +++ b/otp/distributed/DCClassImports.py @@ -2,7 +2,7 @@ from pandac.PandaModules import * -hashVal = 30166307 +hashVal = 1929413177 from toontown.coghq import DistributedCashbotBossSafe, DistributedCashbotBossCrane, DistributedBattleFactory, DistributedCashbotBossTreasure, DistributedCogHQDoor, DistributedSellbotHQDoor, DistributedFactoryElevatorExt, DistributedMintElevatorExt, DistributedLawOfficeElevatorExt, DistributedLawOfficeElevatorInt, LobbyManager, DistributedMegaCorp, DistributedFactory, DistributedLawOffice, DistributedLawOfficeFloor, DistributedLift, DistributedDoorEntity, DistributedSwitch, DistributedButton, DistributedTrigger, DistributedCrushableEntity, DistributedCrusherEntity, DistributedStomper, DistributedStomperPair, DistributedLaserField, DistributedGolfGreenGame, DistributedSecurityCamera, DistributedMover, DistributedElevatorMarker, DistributedBarrelBase, DistributedGagBarrel, DistributedBeanBarrel, DistributedHealBarrel, DistributedGrid, ActiveCell, DirectionalCell, CrusherCell, DistributedCrate, DistributedSinkingPlatform, BattleBlocker, DistributedMint, DistributedMintRoom, DistributedMintBattle, DistributedStage, DistributedStageRoom, DistributedStageBattle, DistributedLawbotBossGavel, DistributedLawbotCannon, DistributedLawbotChair, DistributedCogKart, DistributedCountryClub, DistributedCountryClubRoom, DistributedMoleField, DistributedCountryClubBattle, DistributedMaze, DistributedFoodBelt, DistributedBanquetTable, DistributedGolfSpot diff --git a/panda/direct/distributed/ConnectionRepository.py b/panda/direct/distributed/ConnectionRepository.py index 782b7dc5..2c05a8d3 100644 --- a/panda/direct/distributed/ConnectionRepository.py +++ b/panda/direct/distributed/ConnectionRepository.py @@ -175,6 +175,10 @@ class ConnectionRepository( return retVal + def removeObject(self, di): + if self.doId2do.get(di): + del self.doId2do[di] + def generateGlobalObject(self, doId, dcname, values=None): def applyFieldValues(distObj, dclass, values): for i in range(dclass.getNumInheritedFields()): diff --git a/panda/direct/showbase/PythonUtil.py b/panda/direct/showbase/PythonUtil.py index 2a5dc802..a70fc275 100644 --- a/panda/direct/showbase/PythonUtil.py +++ b/panda/direct/showbase/PythonUtil.py @@ -2177,14 +2177,16 @@ def weightedChoice(choiceList, rng=random.random, sum=None): rand = rng() accum = rand * sum + ite = None for weight, item in choiceList: accum -= weight if accum <= 0.: return item + ite = item # rand is ~1., and floating-point error prevented accum from hitting 0. # Or you passed in a 'sum' that was was too large. # Return the last item. - return item + return ite def randFloat(a, b=0., rng=random.random): """returns a random float in [a, b] diff --git a/toontown/catalog/CatalogGardenItem.py b/toontown/catalog/CatalogGardenItem.py index c6a3961c..57b2f675 100644 --- a/toontown/catalog/CatalogGardenItem.py +++ b/toontown/catalog/CatalogGardenItem.py @@ -79,8 +79,9 @@ class CatalogGardenItem(CatalogItem.CatalogItem): def cleanupPicture(self): CatalogItem.CatalogItem.cleanupPicture(self) - self.model.detachNode() - self.model = None + if hasattr(self, 'model') and self.model: + self.model.detachNode() + self.model = None return def output(self, store = -1): diff --git a/toontown/catalog/CatalogGardenStarterItem.py b/toontown/catalog/CatalogGardenStarterItem.py index aa739595..876bbafe 100644 --- a/toontown/catalog/CatalogGardenStarterItem.py +++ b/toontown/catalog/CatalogGardenStarterItem.py @@ -30,15 +30,14 @@ class CatalogGardenStarterItem(CatalogItem.CatalogItem): return TTLocalizer.GardenStarterTypeName def recordPurchase(self, avatar, optional): - print 'rental-- record purchase' if avatar: - print 'starter garden-- has avater' estate = simbase.air.estateManager.toon2estate.get(avatar) if estate: - print 'starter garden-- has estate' + av = simbase.air.doId2do.get(avatar) + if av: + av.b_setGardenStarted(True) + print('garden saved') estate.placeStarterGarden(avatar) - else: - print 'starter garden-- something not there' return ToontownGlobals.P_ItemAvailable def getPicture(self, avatar): diff --git a/toontown/coderedemption/TTCodeRedemptionMgrAI.py b/toontown/coderedemption/TTCodeRedemptionMgrAI.py index eae89055..594981fa 100644 --- a/toontown/coderedemption/TTCodeRedemptionMgrAI.py +++ b/toontown/coderedemption/TTCodeRedemptionMgrAI.py @@ -59,6 +59,16 @@ class TTCodeRedemptionMgrAI(DistributedObjectAI): 'items': [ CatalogClothingItem.CatalogClothingItem(1753, 0) ] + }, + 'toonstatue': { + 'items': [ + CatalogToonStatueItem.CatalogToonStatueItem(105, endPoseIndex=108) + ] + }, + 'donaldstatue': { + 'items': [ + CatalogGardenItem.CatalogGardenItem(100, 1) + ] } } diff --git a/toontown/estate/DistributedChangingStatuaryAI.py b/toontown/estate/DistributedChangingStatuaryAI.py index 617c8d32..36641bf5 100644 --- a/toontown/estate/DistributedChangingStatuaryAI.py +++ b/toontown/estate/DistributedChangingStatuaryAI.py @@ -4,9 +4,13 @@ from toontown.estate.DistributedStatuaryAI import DistributedStatuaryAI class DistributedChangingStatuaryAI(DistributedStatuaryAI): notify = DirectNotifyGlobal.directNotify.newCategory("DistributedChangingStatuaryAI") - def __init__(self, air, species): + def __init__(self, air): + DistributedStatuaryAI.__init__(self, air) self.air = air - self.species = species + self.growthLevel = -1 - def setGrowthLevel(self, growth): - self.growth = growth + def setGrowthLevel(self, growthLevel): + self.growthLevel = growthLevel + + def getGrowthLevel(self): + return self.growthLevel diff --git a/toontown/estate/DistributedEstate.py b/toontown/estate/DistributedEstate.py index 02cb8e82..ffe9f5b1 100644 --- a/toontown/estate/DistributedEstate.py +++ b/toontown/estate/DistributedEstate.py @@ -105,6 +105,10 @@ class DistributedEstate(DistributedObject.DistributedObject): self.flowerSellBox.removeNode() del self.flowerSellBox self.flowerSellBox = None + if self.fishSellBox: + self.fishSellBox.removeNode() + del self.fishSellBox + self.fishSellBox = None GardenDropGame.GardenDropGame().endGame() return diff --git a/toontown/estate/DistributedEstateAI.py b/toontown/estate/DistributedEstateAI.py index 12c88f70..309df07a 100644 --- a/toontown/estate/DistributedEstateAI.py +++ b/toontown/estate/DistributedEstateAI.py @@ -14,24 +14,36 @@ from DistributedTargetAI import * import CannonGlobals import TableGlobals import HouseGlobals +import GardenGlobals +from DistributedGardenPlotAI import DistributedGardenPlotAI +from DistributedGardenBoxAI import DistributedGardenBoxAI +from DistributedFlowerAI import DistributedFlowerAI +from DistributedGagTreeAI import DistributedGagTreeAI +from DistributedStatuaryAI import DistributedStatuaryAI +from DistributedToonStatuaryAI import DistributedToonStatuaryAI import time import random from toontown.fishing import FishGlobals class Rental: + def __init__(self, estate): self.estate = estate self.objects = set() def destroy(self): del self.estate - for object in self.objects: - if not object.isDeleted(): - object.requestDelete() - taskMgr.remove(object.uniqueName('delete')) + for obj in self.objects: + if not obj.isDeleted(): + obj.requestDelete() + taskMgr.remove(obj.uniqueName('delete')) self.objects = set() class CannonRental(Rental): + + def __init__(self, estate): + Rental.__init__(self, estate) + def generateObjects(self): target = DistributedTargetAI(self.estate.air) target.generateWithRequired(self.estate.zoneId) @@ -93,8 +105,12 @@ class CannonRental(Rental): av.toonUp(3) return 1 -class TableRental(Rental): # Once we make rental game tables. +class TableRental(Rental): + + def __init__(self, estate): + Rental.__init__(self, estate) + def generateObjects(self): for drop in TableGlobals.tableDrops: table = None @@ -108,10 +124,13 @@ class TableRental(Rental): class DistributedEstateAI(DistributedObjectAI): notify = DirectNotifyGlobal.directNotify.newCategory("DistributedEstateAI") + def __init__(self, air): DistributedObjectAI.__init__(self, air) self.toons = [0, 0, 0, 0, 0, 0] self.items = [[], [], [], [], [], []] + self.boxes = [[], [], [], [], [], []] + self.plots = [[], [], [], [], [], []] self.decorData = [] self.cloudType = 0 self.dawnTime = 0 @@ -123,7 +142,6 @@ class DistributedEstateAI(DistributedObjectAI): self.pond = None self.spots = [] self.targets = [] - self.owner = None def generate(self): @@ -165,11 +183,70 @@ class DistributedEstateAI(DistributedObjectAI): self.createTreasurePlanner() + def generateRegisteredObjects(self, slot): + if len(self.plots[slot]) > 0: + for item in self.items[slot]: + plotData = GardenGlobals.estatePlots[slot][item[0]] + if item[1] == GardenGlobals.FLOWER_TYPE: + newItem = DistributedFlowerAI(self.air) + newItem.setEstate(self.doId) + newItem.setOwnerPlot(self.plots[slot][item[0]].doId) + newItem.setPlot(item[0]) + newItem.setHeading(plotData[2]) + newItem.setPosition(plotData[0], plotData[1], 1.3) + newItem.setOwnerIndex(slot) + newItem.setWaterLevel(item[4]) + newItem.setGrowthLevel(item[5]) + newItem.setTypeIndex(item[2]) + newItem.setVariety(item[3]) + elif item[1] == GardenGlobals.GAG_TREE_TYPE: + newItem = DistributedGagTreeAI(self.air) + newItem.setEstate(self.doId) + newItem.setOwnerPlot(self.plots[slot][item[0]].doId) + newItem.setPlot(item[0]) + newItem.setHeading(plotData[2]) + newItem.setPosition(plotData[0], plotData[1], 1.3) + newItem.setOwnerIndex(slot) + newItem.setTypeIndex(item[2]) + newItem.setWaterLevel(item[4]) + newItem.setGrowthLevel(item[5]) + elif item[1] == GardenGlobals.STATUARY_TYPE: + newItem = DistributedStatuaryAI(self.air) + newItem.setEstate(self.doId) + newItem.setOwnerPlot(self.plots[slot][item[0]].doId) + newItem.setPlot(item[0]) + newItem.setHeading(plotData[2]) + newItem.setPosition(plotData[0], plotData[1], 1.3) + newItem.setOwnerIndex(slot) + newItem.setTypeIndex(item[2]) + newItem.setWaterLevel(item[4]) + newItem.setGrowthLevel(item[5]) + elif item[1] == GardenGlobals.TOON_STATUARY_TYPE: + newItem = DistributedToonStatuaryAI(self.air) + newItem.setEstate(self.doId) + newItem.setOwnerPlot(self.plots[slot][item[0]].doId) + newItem.setPlot(item[0]) + newItem.setHeading(plotData[2]) + newItem.setPosition(plotData[0], plotData[1], 1.3) + newItem.setOwnerIndex(slot) + newItem.setTypeIndex(item[2]) + newItem.setWaterLevel(item[4]) + newItem.setGrowthLevel(item[5]) + newItem.setOptional(item[6]) + else: + continue + newItem.generateWithRequired(self.zoneId) + self.plots[slot][item[0]].planted = newItem + self.plots[slot][item[0]].sendUpdate('plantedItem', [newItem.doId]) + self.plots[slot][item[0]].sendUpdate('setMovie', [GardenGlobals.MOVIE_PLANT, 999999999]) + + 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: @@ -327,7 +404,7 @@ class DistributedEstateAI(DistributedObjectAI): self.items[0] = items def d_setSlot0Items(self, items): - self.sendUpdate('setSlot5Items', [items]) + self.sendUpdate('setSlot0Items', [items]) def b_setSlot0Items(self, items): self.setSlot0Items(items) @@ -353,11 +430,11 @@ class DistributedEstateAI(DistributedObjectAI): self.items[1] = items def d_setSlot1Items(self, items): - self.sendUpdate('setSlot2Items', [items]) + self.sendUpdate('setSlot1Items', [items]) def b_setSlot1Items(self, items): - self.setSlot2Items(items) - self.d_setSlot2Items(items) + self.setSlot1Items(items) + self.d_setSlot1Items(items) def getSlot1Items(self): return self.items[1] @@ -477,7 +554,7 @@ class DistributedEstateAI(DistributedObjectAI): def b_setIdList(self, idList): self.setIdList(idList) - self.d_setIdLst(idList) + self.d_setIdList(idList) def completeFlowerSale(self, todo0): pass @@ -517,6 +594,46 @@ class DistributedEstateAI(DistributedObjectAI): def gameTableOver(self): pass + def placeStarterGarden(self, avatar): + avId = avatar.doId + slot = self.toons.index(avId) + plotPos = GardenGlobals.estatePlots[slot] + boxPos = GardenGlobals.estateBoxes[slot] + for p, n in enumerate(boxPos): + x, y, h, i = n + newBox = DistributedGardenBoxAI(self.air) + newBox.setEstate(self.doId) + newBox.setTypeIndex(i) + newBox.setPlot(p) + newBox.setOwnerIndex(slot) + newBox.setPosition(x, y, 0) + newBox.setHeading(h) + newBox.generateWithRequired(self.zoneId) + self.boxes[slot].append(newBox) + for p, n in enumerate(plotPos): + i = n[3] + if i in [GardenGlobals.GAG_TREE_TYPE, GardenGlobals.STATUARY_TYPE]: + x, y, h = n[:3] + newPlot = DistributedGardenPlotAI(self.air) + newPlot.setEstate(self.doId) + newPlot.setPlot(p) + newPlot.setOwnerIndex(slot) + newPlot.setPosition(x, y, 0) + newPlot.setHeading(h) + newPlot.generateWithRequired(self.zoneId) + self.plots[slot].append(newPlot) + elif i == GardenGlobals.FLOWER_TYPE: + x, y, h = n[:3] + newPlot = DistributedGardenPlotAI(self.air) + newPlot.setEstate(self.doId) + newPlot.setPlot(p) + newPlot.setOwnerIndex(slot) + newPlot.setPosition(x, y, 1.3) + newPlot.setHeading(h) + newPlot.generateWithRequired(self.zoneId) + self.plots[slot].append(newPlot) + self.generateRegisteredObjects(slot) + def updateToons(self): self.d_setSlot0ToonId(self.toons[0]) self.d_setSlot1ToonId(self.toons[1]) diff --git a/toontown/estate/DistributedFlower.py b/toontown/estate/DistributedFlower.py index 629ca0c8..324130c9 100644 --- a/toontown/estate/DistributedFlower.py +++ b/toontown/estate/DistributedFlower.py @@ -17,7 +17,7 @@ class DistributedFlower(DistributedPlantBase.DistributedPlantBase, FlowerBase.Fl self.stickUp = 1.07 if DIRT_AS_WATER_INDICATOR: self.stickUp += DIRT_MOUND_HEIGHT - self.collSphereRadius = 2.2 + self.collSphereRadius = 2.8 self.shadowScale = 0.5 self.collSphereOffset = 0.0 self.dirtMound = None @@ -34,6 +34,9 @@ class DistributedFlower(DistributedPlantBase.DistributedPlantBase, FlowerBase.Fl DistributedPlantBase.DistributedPlantBase.setTypeIndex(self, typeIndex) self.setSpecies(typeIndex) + def getTypeIndex(self): + return self.typeIndex + def showWiltOrBloom(self): if not self.model: return @@ -129,7 +132,7 @@ class DistributedFlower(DistributedPlantBase.DistributedPlantBase, FlowerBase.Fl base.localAvatar.removeShovelRelatedDoId(self.doId) base.localAvatar.setInGardenAction(self) base.cr.playGame.getPlace().detectedGardenPlotUse() - self.sendUpdate('removeItem', []) + self.sendUpdate('removeItem', [base.localAvatar.doId]) def setWaterLevel(self, waterLevel): DistributedPlantBase.DistributedPlantBase.setWaterLevel(self, waterLevel) @@ -137,6 +140,9 @@ class DistributedFlower(DistributedPlantBase.DistributedPlantBase, FlowerBase.Fl if self.model: self.adjustWaterIndicator() + def getWaterLevel(self): + return self.waterLevel + def setGrowthLevel(self, growthLevel): origGrowthLevel = self.growthLevel self.growthLevel = growthLevel @@ -144,6 +150,9 @@ class DistributedFlower(DistributedPlantBase.DistributedPlantBase, FlowerBase.Fl self.loadModel() self.makeMovieNode() + def getGrowthLevel(self): + return self.growthLevel + def makeMovieNode(self): self.movieNode = self.rotateNode.attachNewNode('moviePos') self.movieNode.setPos(0, 3, 0) diff --git a/toontown/estate/DistributedFlowerAI.py b/toontown/estate/DistributedFlowerAI.py index 97e7203e..b2dffacd 100644 --- a/toontown/estate/DistributedFlowerAI.py +++ b/toontown/estate/DistributedFlowerAI.py @@ -4,14 +4,20 @@ from toontown.estate.DistributedPlantBaseAI import DistributedPlantBaseAI class DistributedFlowerAI(DistributedPlantBaseAI): notify = DirectNotifyGlobal.directNotify.newCategory("DistributedFlowerAI") - def __init__(self, air, species, variety): + def __init__(self, air): + DistributedPlantBaseAI.__init__(self, air) self.air = air - self.species = species - self.variety = variety self.typeIndex = None - def setTypeIndex(self, index): - self.typeIndex = index + def setTypeIndex(self, typeIndex): + DistributedPlantBaseAI.setTypeIndex(self, typeIndex) + self.typeIndex = typeIndex + + def getTypeIndex(self): + return self.typeIndex def setVariety(self, variety): self.variety = variety + + def getVariety(self): + return self.variety diff --git a/toontown/estate/DistributedGagTree.py b/toontown/estate/DistributedGagTree.py index ef4d558b..192494e0 100644 --- a/toontown/estate/DistributedGagTree.py +++ b/toontown/estate/DistributedGagTree.py @@ -141,6 +141,8 @@ class DistributedGagTree(DistributedPlantBase.DistributedPlantBase): self.confirmDialog.destroy() self.confirmDialog = None if value > 0: + base.localAvatar.showGardeningGui() + base.localAvatar.removeShovelRelatedDoId(self.doId) self.doPicking() else: self.finishInteraction() @@ -149,7 +151,7 @@ class DistributedGagTree(DistributedPlantBase.DistributedPlantBase): def doPicking(self): if not self.canBePicked(): return - self.sendUpdate('removeItem', []) + self.sendUpdate('removeItem', [base.localAvatar.doId]) def createBackupFruits(self): if not hasattr(self, 'fruits'): @@ -182,7 +184,13 @@ class DistributedGagTree(DistributedPlantBase.DistributedPlantBase): for fruit in self.backupFruits: fruit.show() - self.sendUpdate('requestHarvest', []) + self.sendUpdate('requestHarvest', [base.localAvatar.doId]) + + def hideItems(self): + seq = Parallel() + for item in self.fruits: + seq.append(LerpFunc(item.setAlphaScale, fromData=1, toData=0, duration=1)) + seq.start() def getTrack(self): return self.gagTrack @@ -259,6 +267,7 @@ class DistributedGagTree(DistributedPlantBase.DistributedPlantBase): self.movie.append(Func(toon.loop, 'neutral')) if avId == localAvatar.doId: self.movie.append(Func(self.finishInteraction)) + self.movie.append(Func(self.hideItems)) self.movie.append(Func(self.movieDone)) self.movie.append(Func(self.doResultDialog)) self.movie.start() diff --git a/toontown/estate/DistributedGagTreeAI.py b/toontown/estate/DistributedGagTreeAI.py index 2943f2f2..8e099afc 100644 --- a/toontown/estate/DistributedGagTreeAI.py +++ b/toontown/estate/DistributedGagTreeAI.py @@ -1,17 +1,34 @@ from direct.directnotify import DirectNotifyGlobal from toontown.estate.DistributedPlantBaseAI import DistributedPlantBaseAI +import GardenGlobals class DistributedGagTreeAI(DistributedPlantBaseAI): notify = DirectNotifyGlobal.directNotify.newCategory("DistributedGagTreeAI") - def __init__(self, air, gagTrack, gagLevel): + def __init__(self, air): + DistributedPlantBaseAI.__init__(self, air) self.air = air - self.track = gagTrack - self.level = level self.wilted = 0 + def announceGenerate(self): + DistributedPlantBaseAI.announceGenerate(self) + + def delete(self): + DistributedPlantBaseAI.delete(self) + + def disable(self): + DistributedPlantBaseAI.disable(self) + def setWilted(self, wilted): self.wilted = wilted - def requestHarvest(self): - pass + def getWilted(self): + return self.wilted + + def requestHarvest(self, doId): + av = simbase.air.doId2do.get(doId) + harvested = 0 + track, level = GardenGlobals.getTreeTrackAndLevel(self.typeIndex) + while av.inventory.addItem(track, level) > 0 and harvested < 10: + harvested += 1 + self.sendUpdate('setMovie', [GardenGlobals.MOVIE_HARVEST, doId]) diff --git a/toontown/estate/DistributedGardenBox.py b/toontown/estate/DistributedGardenBox.py index ad9cb9b9..b62dcf13 100644 --- a/toontown/estate/DistributedGardenBox.py +++ b/toontown/estate/DistributedGardenBox.py @@ -30,7 +30,7 @@ class DistributedGardenBox(DistributedLawnDecor.DistributedLawnDecor): elif self.typeIndex == GardenGlobals.BOX_TWO: self.defaultModel = 'phase_5.5/models/estate/planterC' else: - self.defaultModel = 'phase_5.5/models/estate/planterD' + self.defaultModel = 'phase_5.5/models/estate/planterB' self.collSphereOffset = 0.0 self.collSphereRadius = self.collSphereRadius * 1.41 self.plotScale = Vec3(1.0, 1.0, 1.0) diff --git a/toontown/estate/DistributedGardenBoxAI.py b/toontown/estate/DistributedGardenBoxAI.py index 139764d4..1c24b315 100644 --- a/toontown/estate/DistributedGardenBoxAI.py +++ b/toontown/estate/DistributedGardenBoxAI.py @@ -5,8 +5,12 @@ class DistributedGardenBoxAI(DistributedLawnDecorAI): notify = DirectNotifyGlobal.directNotify.newCategory("DistributedGardenBoxAI") def __init__(self, air): + DistributedLawnDecorAI.__init__(self, air) self.air = air self.typeIndex = 0 def setTypeIndex(self, index): self.typeIndex = index + + def getTypeIndex(self): + return self.typeIndex diff --git a/toontown/estate/DistributedGardenPlot.py b/toontown/estate/DistributedGardenPlot.py index 34f3bc82..f613df9f 100644 --- a/toontown/estate/DistributedGardenPlot.py +++ b/toontown/estate/DistributedGardenPlot.py @@ -25,6 +25,7 @@ class DistributedGardenPlot(DistributedLawnDecor.DistributedLawnDecor): self.defaultModel = 'phase_5.5/models/estate/dirt_mound' self.colorScaler = Vec4(1, 1, 1, 1) self.plantingGui = None + self.planted = None return def delete(self): @@ -83,6 +84,8 @@ class DistributedGardenPlot(DistributedLawnDecor.DistributedLawnDecor): return self.getPlantingText() def handleEnterPlot(self, entry = None): + #Force Gardens -Zach + base.localAvatar.setGardenStarted(True) dist = self.getDistance(localAvatar) if self.canBePlanted(): base.localAvatar.addShovelRelatedDoId(self.doId) @@ -110,6 +113,8 @@ class DistributedGardenPlot(DistributedLawnDecor.DistributedLawnDecor): retval = True if not base.localAvatar.doId == self.getOwnerId(): retval = False + if hasattr(self, 'planted') and self.planted: + retval = False return retval def plantSomething(self): @@ -139,12 +144,12 @@ class DistributedGardenPlot(DistributedLawnDecor.DistributedLawnDecor): if recipeKey >= 0: species, variety = GardenGlobals.getSpeciesVarietyGivenRecipe(recipeKey) if species >= 0 and variety >= 0: - self.sendUpdate('plantFlower', [species, variety]) + self.sendUpdate('plantFlower', [species, variety, base.localAvatar.doId]) successPlanting = True else: self.notify.debug('%s %d is not a valid recipe' % (recipeStr, special)) burntBeans = len(recipeStr) - self.sendUpdate('plantNothing', [burntBeans]) + self.sendUpdate('plantNothing', [burntBeans, base.localAvatar.doId]) if successPlanting: flowerName = GardenGlobals.getFlowerVarietyName(species, variety) stringToShow = TTLocalizer.getResultPlantedSomethingSentence(flowerName) @@ -204,11 +209,11 @@ class DistributedGardenPlot(DistributedLawnDecor.DistributedLawnDecor): if species >= 205 and species <= 208: successToonStatue = True else: - self.sendUpdate('plantStatuary', [species]) + self.sendUpdate('plantStatuary', [species, base.localAvatar.doId]) else: self.notify.debug('%s %d is not a valid recipe' % (recipeStr, special)) burntBeans = len(recipeStr) - self.sendUpdate('plantNothing', [burntBeans]) + self.sendUpdate('plantNothing', [burntBeans, base.localAvatar.doId]) if successPlanting: itemName = GardenGlobals.PlantAttributes[species]['name'] stringToShow = TTLocalizer.getResultPlantedSomethingSentence(itemName) @@ -247,7 +252,7 @@ class DistributedGardenPlot(DistributedLawnDecor.DistributedLawnDecor): base.localAvatar.showGardeningGui() base.localAvatar.removeShovelRelatedDoId(self.doId) if willPlant: - self.sendUpdate('plantToonStatuary', [species, dnaCode]) + self.sendUpdate('plantToonStatuary', [species, dnaCode, base.localAvatar.doId]) else: self.popupItemPlantingGui() return @@ -266,11 +271,21 @@ class DistributedGardenPlot(DistributedLawnDecor.DistributedLawnDecor): base.localAvatar.showGardeningGui() base.localAvatar.removeShovelRelatedDoId(self.doId) if willPlant: - self.sendUpdate('plantGagTree', [gagTrack, gagLevel]) + self.sendUpdate('plantGagTree', [gagTrack, gagLevel, base.localAvatar.doId]) else: self.finishInteraction() return + def plantedItem(self, doId): + self.planted = doId + + def removePlanted(self): + if self.planted: + item = base.cr.doId2do.get(self.planted) + if item: + item.delete() + self.planted = None + def setMovie(self, mode, avId): if mode == GardenGlobals.MOVIE_PLANT: self.doPlaceItemTrack(avId) @@ -301,8 +316,8 @@ class DistributedGardenPlot(DistributedLawnDecor.DistributedLawnDecor): self.movie.append(Func(toon.detachShovel)) if self.model: pos = self.model.getPos() - pos.setZ(pos[2] - 1) - animProp = LerpPosInterval(self.model, 3, self.model.getPos(), pos) + pos.setZ(pos[2] + 1) + animProp = LerpPosInterval(self.model, 3, pos, self.model.getPos()) shrinkProp = LerpScaleInterval(self.model, 3, scale=self.plotScale, startScale=0.01) objAnimShrink = ParallelEndTogether(animProp, shrinkProp) self.movie.append(objAnimShrink) @@ -310,10 +325,16 @@ class DistributedGardenPlot(DistributedLawnDecor.DistributedLawnDecor): self.movie.append(Func(toon.loop, 'neutral')) if avId == localAvatar.doId: self.movie.append(Func(self.finishInteraction)) - self.movie.append(Func(self.movieDone)) + self.movie.append(Func(self.removePlanted)) self.movie.start() def doPlaceItemTrack(self, avId, item = None): + if avId == 999999999: + pos = self.model.getPos() + pos.setZ(pos[2] - 1) + self.model.setPos(pos) + self.model.setScale(0.01) + return toon = base.cr.doId2do.get(avId) if not toon: return @@ -327,14 +348,24 @@ class DistributedGardenPlot(DistributedLawnDecor.DistributedLawnDecor): self.movie = Sequence(self.startCamIval(avId), moveTrack, Func(shovel.show), placeItemTrack) if avId == localAvatar.doId: self.expectingReplacement = 1 - self.movie.append(Func(self.movieDone)) + self.movie.append(Func(self.sendUpdate, 'finishPlanting', [avId])) self.movie.start() def generatePlaceItemTrack(self, toon, item): sound = loader.loadSfx('phase_5.5/audio/sfx/burrow.ogg') sound.setPlayRate(0.5) placeItemTrack = Parallel() - placeItemTrack.append(Sequence(ActorInterval(toon, 'start-dig'), Parallel(ActorInterval(toon, 'loop-dig', loop=1, duration=5.13), Sequence(Wait(0.25), SoundInterval(sound, node=toon, duration=0.55), Wait(0.8), SoundInterval(sound, node=toon, duration=0.55), Wait(1.35), SoundInterval(sound, node=toon, duration=0.55))), ActorInterval(toon, 'start-dig', playRate=-1), Func(toon.loop, 'neutral'), Func(toon.detachShovel))) + placeItemTrack.append(Sequence(ActorInterval(toon, 'start-dig'), + Parallel(ActorInterval(toon, 'loop-dig', loop=1, duration=5.13), + Sequence(Wait(0.25), + SoundInterval(sound, node=toon, duration=0.55), + Wait(0.8), + SoundInterval(sound, node=toon, duration=0.55), + Wait(1.35), + SoundInterval(sound, node=toon, duration=0.55))), + ActorInterval(toon, 'start-dig', playRate=-1), + Func(toon.loop, 'neutral'), + Func(toon.detachShovel))) if self.model: pos = self.model.getPos() pos.setZ(pos[2] - 1) @@ -343,7 +374,12 @@ class DistributedGardenPlot(DistributedLawnDecor.DistributedLawnDecor): objAnimShrink = ParallelEndTogether(animProp, shrinkProp) placeItemTrack.append(objAnimShrink) if item: - placeItemTrack.append(Sequence(Func(item.reparentTo, toon.rightHand), Wait(0.55), Func(item.wrtReparentTo, render), Parallel(LerpHprInterval(item, hpr=self.getHpr(render), duration=1.2), ProjectileInterval(item, endPos=self.getPos(render), duration=1.2, gravityMult=0.45)), Func(item.removeNode))) + placeItemTrack.append(Sequence(Func(item.reparentTo, toon.rightHand), + Wait(0.55), + Func(item.wrtReparentTo, render), + Parallel(LerpHprInterval(item, hpr=self.getHpr(render), duration=1.2), + ProjectileInterval(item, endPos=self.getPos(render), duration=1.2, gravityMult=0.45)), + Func(item.removeNode))) return placeItemTrack def makeMovieNode(self): diff --git a/toontown/estate/DistributedGardenPlotAI.py b/toontown/estate/DistributedGardenPlotAI.py index 0b51e048..818270ea 100644 --- a/toontown/estate/DistributedGardenPlotAI.py +++ b/toontown/estate/DistributedGardenPlotAI.py @@ -1,35 +1,186 @@ from direct.directnotify import DirectNotifyGlobal from toontown.estate.DistributedLawnDecorAI import DistributedLawnDecorAI -import DistributedToonStatuaryAI -import DistributedStatuaryAI +from DistributedToonStatuaryAI import DistributedToonStatuaryAI +from DistributedStatuaryAI import DistributedStatuaryAI +from DistributedGagTreeAI import DistributedGagTreeAI +from DistributedFlowerAI import DistributedFlowerAI +import GardenGlobals +import datetime + +slots2plots = { + 0: GardenGlobals.plots0, + 1: GardenGlobals.plots1, + 2: GardenGlobals.plots2, + 3: GardenGlobals.plots3, + 4: GardenGlobals.plots4, + 5: GardenGlobals.plots5 +} class DistributedGardenPlotAI(DistributedLawnDecorAI): notify = DirectNotifyGlobal.directNotify.newCategory("DistributedGardenPlotAI") def __init__(self, air): + DistributedLawnDecorAI.__init__(self, air) self.air = air self.planted = None - def plantFlower(self, species, variety): - flower = DistributedFlowerAI.DistributedFlowerAI(self.air, species, variety) - self.planted = flower + def announceGenerate(self): + DistributedLawnDecorAI.announceGenerate(self) - def plantGagTree(self, gagTrack, gagLevel): - tree = DistributedGagTreeAI.DistributedGagTreeAI(self.air, gagTrack, gagLevel) - self.planted = tree + def delete(self): + DistributedLawnDecorAI.delete(self) - def plantStatuary(self, species): - statue = DistributedStatuaryAI.DistributedStatuaryAI(self.air, species) - self.planted = statue + def disable(self): + DistributedLawnDecorAI.disable(self) - def plantToonStatuary(self, species, dnaCode): - statue = DistributedToonStatuaryAI.DistributedToonStatuaryAI(self.air, species, dnaCode) - self.planted = statue + def finishPlanting(self, avId): + self.planted.generateWithRequired(self.zoneId) + self.addData() + self.sendUpdate('plantedItem', [self.planted.doId]) + self.planted.sendUpdate('setMovie', [GardenGlobals.MOVIE_FINISHPLANTING, avId]) - def plantNothing(self, burntBeans): - avId = self.air.getAvatarIdFromSender() - av = self.air.doId2do[avId] - money = av.getMoney() - av.setMoney(money - burntBeans) - av.d_setMoney(money - burntBeans) + def finishRemoving(self, avId): + self.removeData() + self.planted.removeNode() + self.planted.delete() + simbase.air.removeObject(self.planted.doId) + self.planted = None + self.sendUpdate('setMovie', [GardenGlobals.MOVIE_FINISHREMOVING, avId]) + + def addData(self): + estate = simbase.air.doId2do.get(self.getEstate()) + plantedAt = int(datetime.datetime.now().strftime('%Y%m%d%H%M')) + if isinstance(self.planted, DistributedFlowerAI): + data = [ + self.getPlot(), + GardenGlobals.FLOWER_TYPE, + self.planted.getTypeIndex(), + self.planted.getVariety(), + self.planted.getWaterLevel(), + self.planted.getGrowthLevel(), + 0, + plantedAt, + plantedAt + ] + elif isinstance(self.planted, DistributedGagTreeAI): + data = [ + self.getPlot(), + GardenGlobals.GAG_TREE_TYPE, + self.planted.getTypeIndex(), + 0, + self.planted.getWaterLevel(), + self.planted.getGrowthLevel(), + 0, + plantedAt, + plantedAt + ] + elif isinstance(self.planted, DistributedToonStatuaryAI): + data = [ + self.getPlot(), + GardenGlobals.TOON_STATUARY_TYPE, + self.planted.getTypeIndex(), + 0, + self.planted.getWaterLevel(), + self.planted.getGrowthLevel(), + self.planted.getOptional(), + plantedAt, + plantedAt + ] + elif isinstance(self.planted, DistributedStatuaryAI): + data = [ + self.getPlot(), + GardenGlobals.STATUARY_TYPE, + self.planted.getTypeIndex(), + 0, + self.planted.getWaterLevel(), + self.planted.getGrowthLevel(), + 0, + plantedAt, + plantedAt + ] + else: + return + estate.items[self.getOwnerIndex()].append(tuple(data)) + estate.updateItems() + + def removeData(self): + estate = simbase.air.doId2do.get(self.getEstate()) + dataIndex = -1 + for n, item in enumerate(estate.items[self.getOwnerIndex()]): + if item[0] == self.getPlot(): + dataIndex = n + if dataIndex >= 0: + del estate.items[self.getOwnerIndex()][dataIndex] + estate.updateItems() + + def plantFlower(self, species, variety, toon): + #free for now + #av = simbase.air.doId2do.get(toon) + #av.takeMoney(GardenGlobals.getNumBeansRequired(species, variety)) + self.planted = DistributedFlowerAI(self.air) + self.planted.setEstate(self.getEstate()) + self.planted.setOwnerPlot(self.doId) + self.planted.setPlot(self.getPlot()) + self.planted.setHeading(self.getHeading()) + self.planted.setPosition(*self.getPosition()) + self.planted.setOwnerIndex(self.getOwnerIndex()) + self.planted.setWaterLevel(0) + self.planted.setGrowthLevel(0) + self.planted.setTypeIndex(species) + self.planted.setVariety(variety) + self.sendUpdate('setMovie', [GardenGlobals.MOVIE_PLANT, toon]) + + def plantGagTree(self, track, level, toon): + #free for now + #av = simbase.air.doId2do.get(toon) + #av.inventory.useItem(track, level) + #av.d_setInventory(av.inventory.makeNetString()) + self.planted = DistributedGagTreeAI(self.air) + self.planted.setEstate(self.getEstate()) + self.planted.setOwnerPlot(self.doId) + self.planted.setPlot(self.getPlot()) + self.planted.setHeading(self.getHeading()) + self.planted.setPosition(*self.getPosition()) + self.planted.setOwnerIndex(self.getOwnerIndex()) + self.planted.setTypeIndex(GardenGlobals.getTreeTypeIndex(track, level)) + self.planted.setWaterLevel(0) + self.planted.setGrowthLevel(0) + self.sendUpdate('setMovie', [GardenGlobals.MOVIE_PLANT, toon]) + + def plantStatuary(self, species, toon): + #free for now + #av = simbase.air.doId2do.get(toon) + #av.takeMoney(GardenGlobals.getNumBeansRequired(species, 0)) + self.planted = DistributedStatuaryAI(self.air) + self.planted.setEstate(self.getEstate()) + self.planted.setOwnerPlot(self.doId) + self.planted.setPlot(self.getPlot()) + self.planted.setHeading(self.getHeading()) + self.planted.setPosition(*self.getPosition()) + self.planted.setOwnerIndex(self.getOwnerIndex()) + self.planted.setTypeIndex(species) + self.planted.setWaterLevel(0) + self.planted.setGrowthLevel(0) + self.sendUpdate('setMovie', [GardenGlobals.MOVIE_PLANT, toon]) + + def plantToonStatuary(self, species, dnaCode, toon): + #free for now + #av = simbase.air.doId2do.get(toon) + #av.takeMoney(GardenGlobals.getNumBeansRequired(species, 0)) + self.planted = DistributedToonStatuaryAI(self.air) + self.planted.setEstate(self.getEstate()) + self.planted.setOwnerPlot(self.doId) + self.planted.setPlot(self.getPlot()) + self.planted.setHeading(self.getHeading()) + self.planted.setPosition(*self.getPosition()) + self.planted.setOwnerIndex(self.getOwnerIndex()) + self.planted.setTypeIndex(species) + self.planted.setWaterLevel(0) + self.planted.setGrowthLevel(0) + self.planted.setOptional(dnaCode) + self.sendUpdate('setMovie', [GardenGlobals.MOVIE_PLANT, toon]) + + def plantNothing(self, burntBeans, toon): + av = simbase.air.doId2do.get(toon) + av.takeMoney(burntBeans) self.planted = None diff --git a/toontown/estate/DistributedLawnDecor.py b/toontown/estate/DistributedLawnDecor.py index 1046be9c..9c7bb39a 100644 --- a/toontown/estate/DistributedLawnDecor.py +++ b/toontown/estate/DistributedLawnDecor.py @@ -50,7 +50,6 @@ class DistributedLawnDecor(DistributedNode.DistributedNode, NodePath, ShadowCast return def setHeading(self, h): - self.notify.debug('setting h') DistributedNode.DistributedNode.setH(self, h) def generateInit(self): @@ -122,7 +121,6 @@ class DistributedLawnDecor(DistributedNode.DistributedNode, NodePath, ShadowCast self.accept(self.exitMessageName, self.handleExitPlot) def handleEnterPlot(self, optional = None): - self.notify.debug('handleEnterPlot %d' % self.doId) self.sendUpdate('plotEntered', []) def handleExitPlot(self, optional = None): @@ -144,6 +142,12 @@ class DistributedLawnDecor(DistributedNode.DistributedNode, NodePath, ShadowCast taskMgr.remove(self.uniqueName('adjust tree')) return + def setEstate(self, estate): + self.estate = estate + + def getEstate(self): + return self.estate + def setPos(self, x, y, z): DistributedNode.DistributedNode.setPos(self, x, y, z) self.stick2Ground() @@ -193,12 +197,12 @@ class DistributedLawnDecor(DistributedNode.DistributedNode, NodePath, ShadowCast def stickParts(self): pass - def setPlot(self, plot): - self.plot = plot - def setH(self, h): DistributedNode.DistributedNode.setH(self, h) + def setPlot(self, plot): + self.plot = plot + def getPlot(self): return self.plot @@ -238,7 +242,7 @@ class DistributedLawnDecor(DistributedNode.DistributedNode, NodePath, ShadowCast base.localAvatar.hideShovelButton() base.localAvatar.hideWateringCanButton() self.startInteraction() - self.sendUpdate('removeItem', []) + self.sendUpdate('removeItem', [base.localAvatar.doId]) def generateToonMoveTrack(self, toon): node = NodePath('tempNode') @@ -257,7 +261,10 @@ class DistributedLawnDecor(DistributedNode.DistributedNode, NodePath, ShadowCast finalY = node.getY(render) finalZ = node.getZ(render) node.removeNode() - 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')) + 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): @@ -281,13 +288,16 @@ class DistributedLawnDecor(DistributedNode.DistributedNode, NodePath, ShadowCast def startCamIval(self, avId): track = Sequence() if avId == localAvatar.doId: - track = Sequence(Func(base.localAvatar.disableSmartCameraViews), Func(base.localAvatar.setCameraPosForPetInteraction)) + track = Sequence(Func(base.localAvatar.disableSmartCameraViews), + Func(base.localAvatar.setCameraPosForPetInteraction)) return track def stopCamIval(self, avId): track = Sequence() if avId == localAvatar.doId: - track = Sequence(Func(base.localAvatar.unsetCameraPosForPetInteraction), Wait(0.8), Func(base.localAvatar.enableSmartCameraViews)) + track = Sequence(Func(base.localAvatar.unsetCameraPosForPetInteraction), + Wait(0.8), + Func(base.localAvatar.enableSmartCameraViews)) return track def canBeWatered(self): @@ -322,6 +332,8 @@ class DistributedLawnDecor(DistributedNode.DistributedNode, NodePath, ShadowCast if not toon: return self.finishMovies() + if avId == localAvatar.doId: + self.startInteraction() self.model.setTransparency(1) self.model.setAlphaScale(1) shovel = toon.attachShovel() @@ -329,9 +341,11 @@ class DistributedLawnDecor(DistributedNode.DistributedNode, NodePath, ShadowCast moveTrack = self.generateToonMoveTrack(toon) digupTrack = self.generateDigupTrack(toon) self.movie = Sequence(self.startCamIval(avId), moveTrack, Func(shovel.show), digupTrack) + self.movie.append(Func(base.cr.removeObject, self.doId)) if avId == localAvatar.doId: self.expectingReplacement = 1 - self.movie.append(Func(self.movieDone)) + plotAv = base.cr.doId2do.get(self.getOwnerPlot()) + self.movie.append(Func(plotAv.sendUpdate, 'finishRemoving', [avId])) self.movie.start() def generateDigupTrack(self, toon): @@ -340,7 +354,22 @@ class DistributedLawnDecor(DistributedNode.DistributedNode, NodePath, ShadowCast pos = self.model.getPos() pos.setZ(pos[2] - 1) track = Parallel() - track.append(Sequence(ActorInterval(toon, 'start-dig'), Parallel(ActorInterval(toon, 'loop-dig', loop=1, duration=5.13), Sequence(Wait(0.25), SoundInterval(sound, node=toon, duration=0.55), Wait(0.8), SoundInterval(sound, node=toon, duration=0.55), Wait(1.35), SoundInterval(sound, node=toon, duration=0.55))), ActorInterval(toon, 'start-dig', playRate=-1), LerpFunc(self.model.setAlphaScale, fromData=1, toData=0, duration=1), Func(toon.loop, 'neutral'), Func(toon.detachShovel))) + sq = Sequence(ActorInterval(toon, 'start-dig'), + Parallel(ActorInterval(toon, 'loop-dig', loop=1, duration=5.13), + Sequence(Wait(0.25), + SoundInterval(sound, node=toon, duration=0.55), + Wait(0.8), + SoundInterval(sound, node=toon, duration=0.55), + Wait(1.35), + SoundInterval(sound, node=toon, duration=0.55))), + ActorInterval(toon, 'start-dig', playRate=-1), + LerpFunc(self.model.setAlphaScale, fromData=1, toData=0, duration=1)) + if hasattr(self, 'signModel'): + sq.append(Parallel(LerpFunc(self.signModel.setAlphaScale, fromData=1, toData=0, duration=1), + LerpScaleInterval(self.signModel, 1, 0, 1))) + sq.append(Func(toon.loop, 'neutral')) + sq.append(Func(toon.detachShovel)) + track.append(sq) return track def doFinishPlantingTrack(self, avId): diff --git a/toontown/estate/DistributedLawnDecorAI.py b/toontown/estate/DistributedLawnDecorAI.py index ee436997..3f297c48 100644 --- a/toontown/estate/DistributedLawnDecorAI.py +++ b/toontown/estate/DistributedLawnDecorAI.py @@ -1,41 +1,68 @@ from direct.directnotify import DirectNotifyGlobal from direct.distributed.DistributedNodeAI import DistributedNodeAI +import GardenGlobals class DistributedLawnDecorAI(DistributedNodeAI): notify = DirectNotifyGlobal.directNotify.newCategory("DistributedLawnDecorAI") def __init__(self, air): + DistributedNodeAI.__init__(self, air) self.air = air self.plot = None - self.heading = 0 - self.pos = (0, 0, 0) - self.ownerIndex = 0 + self.ownerIndex = None + + def announceGenerate(self): + DistributedNodeAI.announceGenerate(self) + + def delete(self): + DistributedNodeAI.delete(self) + + def disable(self): + DistributedNodeAI.disable(self) + + def setEstate(self, estate): + self.estate = estate + + def getEstate(self): + return self.estate def setPlot(self, plot): self.plot = plot - def setHeading(self, h): - self.heading = h - self.sendUpdate('setH', [h]) - - def setPosition(self, x, y, z): - self.pos = (x, y, z) - self.sendUpdate('setPos', [x, y, z]) + def getPlot(self): + return self.plot def setOwnerIndex(self, index): self.ownerIndex = index + def getOwnerIndex(self): + return self.ownerIndex + + def setPosition(self, x, y, z): + self.position = (x, y, z) + + def getPosition(self): + return self.position + + def setHeading(self, heading): + self.heading = heading + + def getHeading(self): + return self.heading + def plotEntered(self): pass - def removeItem(self): - pass + def removeItem(self, avId): + self.inUseBy = avId + self.d_setMovie(GardenGlobals.MOVIE_REMOVE, avId) - def setMovie(self, todo0, todo1): - pass + def d_setMovie(self, mode, avId): + self.sendUpdate('setMovie', [mode, avId]) def movieDone(self): - pass + if hasattr(self, 'inUseBy'): + del self.inUseBy def interactionDenied(self, todo0): pass diff --git a/toontown/estate/DistributedPlantBase.py b/toontown/estate/DistributedPlantBase.py index 4b1803c9..03453a52 100644 --- a/toontown/estate/DistributedPlantBase.py +++ b/toontown/estate/DistributedPlantBase.py @@ -44,6 +44,12 @@ class DistributedPlantBase(DistributedLawnDecor.DistributedLawnDecor): DistributedLawnDecor.DistributedLawnDecor.setupShadow(self) self.adjustWaterIndicator() + def setOwnerPlot(self, owner): + self.ownerPlot = owner + + def getOwnerPlot(self): + return self.ownerPlot + def setTypeIndex(self, typeIndex): self.typeIndex = typeIndex self.attributes = GardenGlobals.PlantAttributes[typeIndex] @@ -63,7 +69,9 @@ class DistributedPlantBase(DistributedLawnDecor.DistributedLawnDecor): self.waterLevel = waterLevel def getWaterLevel(self): - return self.waterLevel + if hasattr(self, 'waterLevel'): + return self.waterLevel + return 0 def setGrowthLevel(self, growthLevel): self.growthLevel = growthLevel @@ -97,11 +105,11 @@ class DistributedPlantBase(DistributedLawnDecor.DistributedLawnDecor): def handleWatering(self): self.startInteraction() - self.sendUpdate('waterPlant') + self.sendUpdate('waterPlant', [localAvatar.doId]) def __handleWatering(self, plantToWaterId): if plantToWaterId == self.doId: - self.sendUpdate('waterPlant') + self.sendUpdate('waterPlant', [localAvatar.doId]) else: self.notify.debug('not sending water plant') diff --git a/toontown/estate/DistributedPlantBaseAI.py b/toontown/estate/DistributedPlantBaseAI.py index c70ad3e1..fe0ffa87 100644 --- a/toontown/estate/DistributedPlantBaseAI.py +++ b/toontown/estate/DistributedPlantBaseAI.py @@ -1,26 +1,81 @@ from direct.directnotify import DirectNotifyGlobal from toontown.estate.DistributedLawnDecorAI import DistributedLawnDecorAI +import GardenGlobals +import datetime class DistributedPlantBaseAI(DistributedLawnDecorAI): notify = DirectNotifyGlobal.directNotify.newCategory("DistributedPlantBaseAI") def __init__(self, air): + DistributedLawnDecorAI.__init__(self, air) self.air = air - self.typeIndex = 0 - self.water = 0 - self.growth = 0 + self.growthLevel = -1 - def setTypeIndex(self, index): - self.typeIndex = index + def announceGenerate(self): + DistributedLawnDecorAI.announceGenerate(self) + + def delete(self): + DistributedLawnDecorAI.delete(self) + + def disable(self): + DistributedLawnDecorAI.disable(self) + + def setOwnerPlot(self, owner): + self.ownerPlot = owner + + def getOwnerPlot(self): + return self.ownerPlot + + def setTypeIndex(self, typeIndex): + self.typeIndex = typeIndex + self.attributes = GardenGlobals.PlantAttributes[typeIndex] + self.name = self.attributes['name'] + self.plantType = self.attributes['plantType'] + self.growthThresholds = self.attributes['growthThresholds'] + self.maxWaterLevel = self.attributes['maxWaterLevel'] + self.minWaterLevel = self.attributes['minWaterLevel'] + + def getTypeIndex(self): + return self.typeIndex def setWaterLevel(self, water): - self.water = water + self.waterLevel = water + + def getWaterLevel(self): + return self.waterLevel def setGrowthLevel(self, growth): - self.growth = growth + self.growthLevel = growth - def waterPlant(self): - pass + def getGrowthLevel(self): + return self.growthLevel + + def waterPlant(self, avId): + self.lastWateredBy = avId + newLevel = self.waterLevel + 1 + if newLevel > self.maxWaterLevel: + self.setWaterLevel(self.maxWaterLevel) + else: + self.setWaterLevel(newLevel) + self.sendUpdate('setMovie', [GardenGlobals.MOVIE_WATER, avId]) + self.sendUpdate('setWaterLevel', [self.getWaterLevel()]) def waterPlantDone(self): - pass + if hasattr(self, 'lastWateredBy'): + av = simbase.air.doId2do.get(self.lastWateredBy) + skill = av.getWateringCanSkill() + skill += GardenGlobals.WateringCanAttributes[av.wateringCan]['skillPts'] / 100 + av.b_setWateringCanSkill(skill) + del self.lastWateredBy + estate = simbase.air.doId2do.get(self.getEstate()) + dataIndex = -1 + for n, item in enumerate(estate.items[self.getOwnerIndex()]): + if item[0] == self.getPlot(): + dataIndex = n + if dataIndex >= 0: + dtime = int(datetime.datetime.now().strftime('%Y%m%d%H%M')) + data = list(estate.items[self.getOwnerIndex()][dataIndex]) + data[4] = self.getWaterLevel() + data[8] = dtime + estate.items[self.getOwnerIndex()][dataIndex] = tuple(data) + estate.updateItems() diff --git a/toontown/estate/DistributedStatuary.py b/toontown/estate/DistributedStatuary.py index 4d9680b1..9571696b 100644 --- a/toontown/estate/DistributedStatuary.py +++ b/toontown/estate/DistributedStatuary.py @@ -37,6 +37,12 @@ class DistributedStatuary(DistributedLawnDecor.DistributedLawnDecor): attrib = GardenGlobals.PlantAttributes[self.typeIndex] self.stick2Ground() + def setOwnerPlot(self, owner): + self.ownerPlot = owner + + def getOwnerPlot(self): + return self.ownerPlot + def setTypeIndex(self, typeIndex): self.typeIndex = typeIndex self.name = GardenGlobals.PlantAttributes[typeIndex]['name'] diff --git a/toontown/estate/DistributedStatuaryAI.py b/toontown/estate/DistributedStatuaryAI.py index efbe0d3b..066ffa06 100644 --- a/toontown/estate/DistributedStatuaryAI.py +++ b/toontown/estate/DistributedStatuaryAI.py @@ -4,18 +4,30 @@ from toontown.estate.DistributedLawnDecorAI import DistributedLawnDecorAI class DistributedStatuaryAI(DistributedLawnDecorAI): notify = DirectNotifyGlobal.directNotify.newCategory("DistributedStatuaryAI") - def __init__(self, air, species): + def __init__(self, air): + DistributedLawnDecorAI.__init__(self, air) self.air = air - self.species = species - self.typeIndex = 0 - self.water = 0 - self.growth = 0 - def setTypeIndex(self, index): - self.typeIndex = index + def setTypeIndex(self, typeIndex): + self.typeIndex = typeIndex - def setWaterLevel(self, water): - self.water = water + def getTypeIndex(self): + return self.typeIndex - def setGrowthLevel(self, growth): - self.growth = growth + def setOwnerPlot(self, owner): + self.ownerPlot = owner + + def getOwnerPlot(self): + return self.ownerPlot + + def setWaterLevel(self, waterLevel): + self.waterLevel = waterLevel + + def getWaterLevel(self): + return self.waterLevel + + def setGrowthLevel(self, growthLevel): + self.growthLevel = growthLevel + + def getGrowthLevel(self): + return self.growthLevel diff --git a/toontown/estate/DistributedToonStatuaryAI.py b/toontown/estate/DistributedToonStatuaryAI.py index eb270222..058ca7b0 100644 --- a/toontown/estate/DistributedToonStatuaryAI.py +++ b/toontown/estate/DistributedToonStatuaryAI.py @@ -4,10 +4,12 @@ from toontown.estate.DistributedStatuaryAI import DistributedStatuaryAI class DistributedToonStatuaryAI(DistributedStatuaryAI): notify = DirectNotifyGlobal.directNotify.newCategory("DistributedToonStatuaryAI") - def __init__(self, air, species, dnaCode): + def __init__(self, air): + DistributedStatuaryAI.__init__(self, air) self.air = air - self.species = species - self.dnaCode = dnaCode - def setOptional(self, opt): - self.optional = opt + def setOptional(self, optional): + self.optional = optional + + def getOptional(self): + return self.optional diff --git a/toontown/estate/EstateManagerAI.py b/toontown/estate/EstateManagerAI.py index 2d749f51..f4afe373 100644 --- a/toontown/estate/EstateManagerAI.py +++ b/toontown/estate/EstateManagerAI.py @@ -8,6 +8,7 @@ import functools class LoadHouseFSM(FSM): notify = DirectNotifyGlobal.directNotify.newCategory('LoadHouseFSM') + def __init__(self, mgr, estate, houseIndex, toon, callback): FSM.__init__(self, 'LoadHouseFSM') self.mgr = mgr diff --git a/toontown/estate/GardenGlobals.py b/toontown/estate/GardenGlobals.py index a1228001..51d4ad13 100644 --- a/toontown/estate/GardenGlobals.py +++ b/toontown/estate/GardenGlobals.py @@ -12,6 +12,7 @@ INVALID_TYPE = -1 GAG_TREE_TYPE = 0 FLOWER_TYPE = 1 STATUARY_TYPE = 2 +TOON_STATUARY_TYPE = 3 WATERING_CAN_SMALL = 0 WATERING_CAN_MEDIUM = 1 WATERING_CAN_LARGE = 2 @@ -682,7 +683,7 @@ def validatePlantAttributes(notify): notify.debug('plant attributes are ok') -plots0 = ((0, +plots0 = [(0, 0, 0.0, FLOWER_TYPE), @@ -757,45 +758,45 @@ plots0 = ((0, (-100, -43, -90.0, - STATUARY_TYPE)) -plots1 = ((0, - 0, + STATUARY_TYPE)] +plots1 = [(85.0, + -67.0, 0.0, FLOWER_TYPE), - (1, - 0, + (75, + -72, 0.0, FLOWER_TYPE), - (2, - 0, + (89.865, + -71.7725, 0.0, FLOWER_TYPE), - (2, - 1, + (91.0, + -74.0, 0.0, FLOWER_TYPE), - (2, - 2, + (92.135, + -76.2275, 0.0, FLOWER_TYPE), - (3, - 0, + (75.865, + -78.7725, 0.0, FLOWER_TYPE), - (3, - 1, + (77, + -81, 0.0, FLOWER_TYPE), - (3, - 2, + (78.135, + -83.2275, 0.0, FLOWER_TYPE), - (4, - 0, + (86.6518, + -86.6576, 0.0, FLOWER_TYPE), - (4, - 1, + (89.3482, + -85.3424, 0.0, FLOWER_TYPE), (62, @@ -833,8 +834,8 @@ plots1 = ((0, (47, -82, -30.0, - STATUARY_TYPE)) -plots2 = ((0, + STATUARY_TYPE)] +plots2 = [(0, 0, 0.0, FLOWER_TYPE), @@ -909,8 +910,8 @@ plots2 = ((0, (-97, -114, -60.0, - STATUARY_TYPE)) -plots3 = ((0, + STATUARY_TYPE)] +plots3 = [(0, 0, 0.0, FLOWER_TYPE), @@ -985,8 +986,8 @@ plots3 = ((0, (117, 27, 102.0, - STATUARY_TYPE)) -plots4 = ((0, + STATUARY_TYPE)] +plots4 = [(0, 0, 0.0, FLOWER_TYPE), @@ -1061,8 +1062,8 @@ plots4 = ((0, (16, 87, -140.0, - STATUARY_TYPE)) -plots5 = ((0, + STATUARY_TYPE)] +plots5 = [(0, 0, 0.0, FLOWER_TYPE), @@ -1137,7 +1138,7 @@ plots5 = ((0, (-55, 70, 213.0, - STATUARY_TYPE)) + STATUARY_TYPE)] estatePlots = (plots0, plots1, plots2, @@ -1147,7 +1148,7 @@ estatePlots = (plots0, BOX_ONE = 1 BOX_TWO = 2 BOX_THREE = 3 -flowerBoxes0 = ((-62.5, +flowerBoxes0 = [(-62.5, -52.5, 182.0, BOX_ONE), @@ -1166,8 +1167,8 @@ flowerBoxes0 = ((-62.5, (-57, -33, 0.0, - BOX_TWO)) -flowerBoxes1 = ((85.0, + BOX_TWO)] +flowerBoxes1 = [(85.0, -67.0, 26.0, BOX_ONE), @@ -1186,8 +1187,8 @@ flowerBoxes1 = ((85.0, (88, -86, 206.0, - BOX_TWO)) -flowerBoxes2 = ((-62, + BOX_TWO)] +flowerBoxes2 = [(-62, -112, 350.0, BOX_ONE), @@ -1206,8 +1207,8 @@ flowerBoxes2 = ((-62, (-71, -129, 169.0, - BOX_TWO)) -flowerBoxes3 = ((72, + BOX_TWO)] +flowerBoxes3 = [(72, 5, 265.0, BOX_ONE), @@ -1226,8 +1227,8 @@ flowerBoxes3 = ((72, (54, 12, 86.0, - BOX_TWO)) -flowerBoxes4 = ((35.5, + BOX_TWO)] +flowerBoxes4 = [(35.5, 70, 152.0, BOX_ONE), @@ -1246,8 +1247,8 @@ flowerBoxes4 = ((35.5, (47, 86, -19.0, - BOX_TWO)) -flowerBoxes5 = ((-26.5, + BOX_TWO)] +flowerBoxes5 = [(-26.5, 37.5, 318.0, BOX_ONE), @@ -1266,7 +1267,7 @@ flowerBoxes5 = ((-26.5, (-45, 31, 124.0, - BOX_TWO)) + BOX_TWO)] estateBoxes = (flowerBoxes0, flowerBoxes1, flowerBoxes2, diff --git a/toontown/estate/HouseGlobals.py b/toontown/estate/HouseGlobals.py index 5eb73683..ef5f4d6e 100644 --- a/toontown/estate/HouseGlobals.py +++ b/toontown/estate/HouseGlobals.py @@ -110,12 +110,11 @@ HALF_DAY_PERIOD = 105 HALF_NIGHT_PERIOD = 30 FIREWORKS_MOVIE_CLEAR = 0 FIREWORKS_MOVIE_GUI = 1 - HouseEmblemPrices = ( - (50, 20), # bungalo - (200, 75), # tiki - (200, 75), # tepee - (500, 250), # castle - (350, 150), # cupcake - (400, 200) # cabin - ) + (50, 20), # bungalo + (200, 75), # tiki + (200, 75), # tepee + (500, 250), # castle + (350, 150), # cupcake + (400, 200) # cabin +) diff --git a/toontown/estate/SpecialsPhoto.py b/toontown/estate/SpecialsPhoto.py index b88057b9..b47c7a9a 100644 --- a/toontown/estate/SpecialsPhoto.py +++ b/toontown/estate/SpecialsPhoto.py @@ -127,9 +127,12 @@ class SpecialsPhoto(NodePath): rotate = pitch.attachNewNode('rotate') scale = rotate.attachNewNode('scale') actor.reparentTo(scale) - bMin, bMax = actor.getTightBounds() - center = (bMin + bMax) / 2.0 - actor.setPos(-center[0], -center[1], -center[2]) + if actor.getTightBounds(): + bMin, bMax = actor.getTightBounds() + center = (bMin + bMax) / 2.0 + actor.setPos(-center[0], -center[1], -center[2]) + else: + actor.setPos(0, 0, 0) pitch.setY(2.5) return frame diff --git a/toontown/toon/DistributedToon.py b/toontown/toon/DistributedToon.py index 2a34c4d9..b67e5c51 100644 --- a/toontown/toon/DistributedToon.py +++ b/toontown/toon/DistributedToon.py @@ -2687,4 +2687,4 @@ def showParticle(name): particle.start(spellbook.getTarget()) return 'Successfully started particle!' - return 'Particle %s does not exist.' % name \ No newline at end of file + return 'Particle %s does not exist.' % name diff --git a/toontown/toon/DistributedToonAI.py b/toontown/toon/DistributedToonAI.py index 05587cbf..a73f36a7 100644 --- a/toontown/toon/DistributedToonAI.py +++ b/toontown/toon/DistributedToonAI.py @@ -5111,3 +5111,19 @@ def remCode(code): return 'Player can now reuse the code %s' % code else: return "Player hasn't redeemed this code!" + +@magicWord(category=CATEGORY_PROGRAMMER, types=[int]) +def shovelSkill(skill): + """ + Update shovel skill. + """ + av = spellbook.getTarget() + av.b_setShovelSkill(skill) + +@magicWord(category=CATEGORY_PROGRAMMER, types=[int]) +def canSkill(skill): + """ + Update watering can skill. + """ + av = spellbook.getTarget() + av.b_setWateringCanSkill(skill)