diff --git a/astron/dclass/toon.dc b/astron/dclass/toon.dc index 801bf693..9f3ba334 100644 --- a/astron/dclass/toon.dc +++ b/astron/dclass/toon.dc @@ -1192,16 +1192,22 @@ dclass DistributedEstate : DistributedObject { setRentalTimeStamp(uint32 timestamp = 0) required airecv db; setRentalType(uint8 type = 0) required airecv db; setSlot0ToonId(uint32 toonId = 0) required airecv db; + setSlot0Garden(blob g) required airecv db; setSlot0Items(lawnItem items[] = []) required airecv db; setSlot1ToonId(uint32 toonId = 0) required airecv db; + setSlot1Garden(blob g) required airecv db; setSlot1Items(lawnItem items[] = []) required airecv db; setSlot2ToonId(uint32 toonId = 0) required airecv db; + setSlot2Garden(blob g) required airecv db; setSlot2Items(lawnItem items[] = []) required airecv db; setSlot3ToonId(uint32 toonId = 0) required airecv db; + setSlot3Garden(blob g) required airecv db; setSlot3Items(lawnItem items[] = []) required airecv db; setSlot4ToonId(uint32 toonId = 0) required airecv db; + setSlot4Garden(blob g) required airecv db; setSlot4Items(lawnItem items[] = []) required airecv db; setSlot5ToonId(uint32 toonId = 0) required airecv db; + setSlot5Garden(blob g) required airecv db; setSlot5Items(lawnItem items[] = []) required airecv db; setIdList(uint32 []) broadcast ram; completeFlowerSale(uint8) airecv clsend; diff --git a/otp/distributed/DCClassImports.py b/otp/distributed/DCClassImports.py index 0ef5c0e6..4b26b95b 100644 --- a/otp/distributed/DCClassImports.py +++ b/otp/distributed/DCClassImports.py @@ -2,7 +2,7 @@ from pandac.PandaModules import * -hashVal = 2127944587 +hashVal = 2798365763L 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/toontown/estate/DistributedEstateAI.py b/toontown/estate/DistributedEstateAI.py index 11b29ac6..280ca6bd 100644 --- a/toontown/estate/DistributedEstateAI.py +++ b/toontown/estate/DistributedEstateAI.py @@ -3,7 +3,7 @@ from direct.distributed.DistributedObjectAI import DistributedObjectAI from toontown.toonbase import ToontownGlobals import HouseGlobals import time - +import random from toontown.fishing.DistributedFishingPondAI import DistributedFishingPondAI from toontown.fishing.DistributedFishingTargetAI import DistributedFishingTargetAI from toontown.fishing.DistributedPondBingoManagerAI import DistributedPondBingoManagerAI @@ -11,7 +11,141 @@ from toontown.fishing import FishingTargetGlobals from toontown.safezone.DistributedFishingSpotAI import DistributedFishingSpotAI from toontown.safezone.SZTreasurePlannerAI import SZTreasurePlannerAI from toontown.safezone import TreasureGlobals +from DistributedGardenBoxAI import * +from DistributedGagTreeAI import * +from DistributedFlowerAI import * +import GardenGlobals +from DistributedCannonAI import * +from DistributedTargetAI import * +import CannonGlobals +NULL_PLANT = [0, -1, 0, -1, 0] +NULL_TREES = [NULL_PLANT] * 8 +NULL_FLOWERS = [NULL_PLANT] * 10 +NULL_STATUARY = 0 + +def unpackGardenSetter(f): + def w(klass, data): + if data: + dg = PyDatagram(data) + dgi = PyDatagramIterator(dg) + def unpackPlant(_): + return dgi.getUint32, dgi.getInt8(), dgi.getUint32(), dgi.getInt8(), dgi.getUint16() + flowers = map(unpackPlant, range(10)) + trees = map(unpackPlant, range(8)) + st = dgi.getUint8() + started = dgi.getBool() + else: + flowers = NULL_FLOWERS + trees = NULL_TREES + st = NULL_STATUARY + started = 0 + return f(klass, started, flowers, trees, st) + return w + +def packGardenData(plants, statuary, started = True): + dg = PyDatagram() + for plant in plants: + a, b, c, d, e = plant + dg.addUint32(a) + dg.addInt8(b) + dg.addUint32(c) + dg.addInt8(d) + dg.addUint16(e) + + dg.addUint8(statuary) + dg.addBool(started) + return dg.getMessage() + +class Garden: + def __init__(self, avId): + self.avId = avId + self.treesData = NULL_TREES + self.flowersData = NULL_FLOWERS + self.statuaryIndex = NULL_STATUARY + self.trees = [] + self.flowers = [] + self.statuary = None + self.objects = [] + + def destroy(self): + del self.treesData + del self.flowersData + del self.statuaryIndex + for tree in self.trees: + tree.requestDelete() + for flower in self.flowers: + flower.requestDelete() + for object in self.objects: + object.requestDelete() + if self.statuary: + self.statuary.requestDelete() + del self.trees + del self.flowers + del self.objects + del self.statuary + + def create(self, estateMgr): + if self.avId not in estateMgr.toons: + estateMgr.notify.warning("Garden associated to unknown avatar %d, deleting..." % self.avId) + print estateMgr.toons + return False + houseIndex = estateMgr.toons.index(self.avId) + + boxDefs = GardenGlobals.estateBoxes[houseIndex] + for x, y, h, boxType in boxDefs: + box = DistributedGardenBoxAI(estateMgr.air) + box.setTypeIndex(boxType) + box.setPos(x, y, 0) + box.setH(h) + box.setOwnerIndex(houseIndex) + box.generateWithRequired(estateMgr.zoneId) + self.objects.append(box) + + plots = GardenGlobals.estatePlots[houseIndex] + treeIndex = 0 + for x, y, h, type in plots: + if type == GardenGlobals.GAG_TREE_TYPE: + planted, waterLevel, nextLevelDecrease, growthLevel, nextGrowth = self.treesData[treeIndex] + if planted: + treeIndex += 1 + tree = DistributedGagTreeAI(estateMgr.air) + tree.setPos(x, y, 0) + tree.setH(h) + tree.setOwnerIndex(houseIndex) + tree.setWaterLevel(waterLevel) + tree.setGrowthLevel(growthLevel) + tree.calculate(nextGrowth, nextLevelDecrease) + tree.generateWithRequired(estateMgr.zoneId) + self.trees.append(tree) + +class GardenManager: + def __init__(self, mgr): + self.mgr = mgr + self.gardens = {} + + def handleSingleGarden(self, avId, data): + g = Garden(avId) + g.flowersData, g.treesData, g.statuaryIndex = data + if not g.create(self.mgr): + return + self.gardens[avId] = g + + def placeGarden(self, avId): + g = Garden(avId) + g.create(self.mgr) + self.gardens[avId] = g + + def destroy(self): + for garden in self.gardens.values(): + garden.destroy() + del self.gardens + + def getData(self, avId): + g = self.gardens.get(avId) + if not g: + return packGardenData(NULL_FLOWERS + NULL_TREES, NULL_STATUARY, False) + return packGardenData(g.flowersData + g.treesData, g.statuaryIndex) class DistributedEstateAI(DistributedObjectAI): notify = DirectNotifyGlobal.directNotify.newCategory("DistributedEstateAI") @@ -26,13 +160,15 @@ class DistributedEstateAI(DistributedObjectAI): self.lastEpochTimestamp = 0 self.rentalTimestamp = 0 self.houses = [None] * 6 - + self.rentalType = 0 + self.rentalHandle = None self.pond = None self.spots = [] - self.targets = [] - + self.doId2do = {} self.owner = None + self.gardenManager = GardenManager(self) + self.__pendingGardens = {} def generate(self): DistributedObjectAI.generate(self) @@ -74,26 +210,35 @@ class DistributedEstateAI(DistributedObjectAI): self.createTreasurePlanner() + def announceGenerate(self): + DistributedObjectAI.announceGenerate(self) + for index, garden in self.__pendingGardens.items(): + started = garden[0] + if started: + self.gardenManager.handleSingleGarden(self.toons[index], garden[1:]) + self.__pendingGardens = {} def destroy(self): for house in self.houses: if house: house.requestDelete() - del self.houses[:] + self.houses = [] if self.pond: - self.pond.requestDelete() for spot in self.spots: spot.requestDelete() + self.spots = [] for target in self.targets: target.requestDelete() - + self.targets = [] + self.pond.requestDelete() + self.pond = None + self.gardenManager.destroy() if self.treasurePlanner: self.treasurePlanner.stop() - self.requestDelete() - def setEstateReady(self): - pass + def addDistObj(self, distObj): + self.doId2do[distObj.doId] = distObj def setClientReady(self): self.sendUpdate('setEstateReady', []) @@ -110,7 +255,7 @@ class DistributedEstateAI(DistributedObjectAI): def getEstateType(self): return self.estateType - + def setClosestHouse(self, todo0): pass @@ -142,9 +287,6 @@ class DistributedEstateAI(DistributedObjectAI): def getDawnTime(self): return self.dawnTime - def placeOnGround(self, todo0): - pass - def setDecorData(self, decorData): self.decorData = decorData @@ -307,7 +449,6 @@ class DistributedEstateAI(DistributedObjectAI): def getSlot4ToonId(self): return self.toons[4] - def setSlot4Items(self, items): self.items[4] = items @@ -401,3 +542,45 @@ class DistributedEstateAI(DistributedObjectAI): self.d_setSlot3Items(self.items[3]) self.d_setSlot4Items(self.items[4]) self.d_setSlot5Items(self.items[5]) + + @unpackGardenSetter + def setSlot0Garden(self, started, flowers, trees, si): + self.__pendingGardens[0] = (started, flowers, trees, si) + + @unpackGardenSetter + def setSlot1Garden(self, started, flowers, trees, si): + self.__pendingGardens[1] = (started, flowers, trees, si) + + @unpackGardenSetter + def setSlot2Garden(self, started, flowers, trees, si): + self.__pendingGardens[2] = (started, flowers, trees, si) + + @unpackGardenSetter + def setSlot3Garden(self, started, flowers, trees, si): + self.__pendingGardens[3] = (started, flowers, trees, si) + + @unpackGardenSetter + def setSlot4Garden(self, started, flowers, trees, si): + self.__pendingGardens[4] = (started, flowers, trees, si) + + @unpackGardenSetter + def setSlot5Garden(self, started, flowers, trees, si): + self.__pendingGardens[5] = (started, flowers, trees, si) + + def d_updateGarden(self, slot = None): + self.notify.info('updateGarden %s' % slot) + if slot is None: + for i in xrange(6): + self.d_updateGarden(i) + else: + data = self.gardenManager.getData(self.toons[slot]) + self.sendUpdate('setSlot%dGarden' % slot, [data]) + + def placeStarterGarden(self, avId): + av = self.air.doId2do.get(avId) + if not av: + return + av.b_setGardenStarted(1) + self.notify.info('placeStarterGarden %d' % avId) + self.gardenManager.placeGarden(avId) + self.d_updateGarden()