Poodletooth-iLand/toontown/estate/DistributedEstateAI.py

716 lines
22 KiB
Python
Raw Normal View History

2015-03-03 16:10:12 -06:00
from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectAI import DistributedObjectAI
2015-03-23 15:28:42 -05:00
2015-03-03 16:10:12 -06:00
from toontown.toonbase import ToontownGlobals
2015-03-23 15:28:42 -05:00
2015-03-03 16:10:12 -06:00
import HouseGlobals
2015-03-23 15:28:42 -05:00
2015-03-03 16:10:12 -06:00
import time
2015-03-09 17:02:16 -05:00
import random
2015-03-23 15:28:42 -05:00
2015-03-03 16:10:12 -06:00
from toontown.fishing.DistributedFishingPondAI import DistributedFishingPondAI
from toontown.fishing.DistributedFishingTargetAI import DistributedFishingTargetAI
from toontown.fishing.DistributedPondBingoManagerAI import DistributedPondBingoManagerAI
from toontown.fishing import FishingTargetGlobals
2015-03-23 15:28:42 -05:00
2015-03-03 16:10:12 -06:00
from toontown.safezone.DistributedFishingSpotAI import DistributedFishingSpotAI
from toontown.safezone.SZTreasurePlannerAI import SZTreasurePlannerAI
2015-03-23 15:28:42 -05:00
from toontown.safezone import DistributedTreasureAI
2015-03-03 16:10:12 -06:00
from toontown.safezone import TreasureGlobals
2015-03-23 15:28:42 -05:00
2015-03-09 17:02:16 -05:00
from DistributedGardenBoxAI import *
from DistributedGagTreeAI import *
from DistributedFlowerAI import *
import GardenGlobals
2015-03-23 15:28:42 -05:00
2015-03-09 17:02:16 -05:00
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
2015-03-23 15:28:42 -05:00
from direct.distributed.PyDatagramIterator import *
from direct.distributed.PyDatagram import *
2015-03-09 17:02:16 -05:00
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)
2015-03-13 18:52:45 -05:00
box.generate()#WithRequired(estateMgr.zoneId)
2015-03-09 17:02:16 -05:00
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)
2015-03-13 18:52:45 -05:00
tree.generate()#WithRequired(estateMgr.zoneId)
2015-03-09 17:02:16 -05:00
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)
2015-03-03 16:10:12 -06:00
2015-03-23 07:56:48 -05:00
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'))
self.objects = set()
class CannonRental(Rental):
def generateObjects(self):
target = DistributedTargetAI(self.estate.air)
target.generateWithRequired(self.estate.zoneId)
for drop in CannonGlobals.cannonDrops:
cannon = DistributedCannonAI(self.estate.air)
cannon.setEstateId(self.estate.doId)
cannon.setTargetId(target.doId)
cannon.setPosHpr(*drop)
cannon.generateWithRequired(self.estate.zoneId)
self.objects.add(cannon)
self.generateTreasures()
self.estate.b_setClouds(1)
def destroy(self):
self.estate.b_setClouds(0)
Rental.destroy(self)
2015-03-23 15:28:42 -05:00
2015-03-23 07:56:48 -05:00
def generateTreasures(self):
doIds = []
z = 35
for i in xrange(20):
x = random.randint(100, 300) - 200
y = random.randint(100, 300) - 200
2015-03-23 15:28:42 -05:00
treasure = DistributedTreasureAI.DistributedTreasureAI(self.estate.air, self, 7, x, y, z)
2015-03-23 07:56:48 -05:00
treasure.generateWithRequired(self.estate.zoneId)
self.objects.add(treasure)
doIds.append(treasure.doId)
self.estate.sendUpdate("setTreasureIds", [doIds])
2015-03-23 15:28:42 -05:00
2015-03-23 07:56:48 -05:00
def grabAttempt(self, avId, treasureId):
av = self.estate.air.doId2do.get(avId)
if av == None:
self.estate.air.writeServerEvent('suspicious', avId, 'TreasurePlannerAI.grabAttempt unknown avatar')
self.estate.notify.warning('avid: %s does not exist' % avId)
return
treasure = self.estate.air.doId2do.get(treasureId)
if self.validAvatar(av):
treasure.d_setGrab(avId)
self.deleteTreasureSoon(treasure)
else:
treasure.d_setReject()
def deleteTreasureSoon(self, treasure):
taskName = treasure.uniqueName('delete')
taskMgr.doMethodLater(5, self.__deleteTreasureNow, taskName, extraArgs=(treasure, taskName))
def __deleteTreasureNow(self, treasure, taskName):
treasure.requestDelete()
def validAvatar(self, av):
if av.getMaxHp() == av.getHp():
return 0
av.toonUp(3)
return 1
2015-03-03 16:10:12 -06:00
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.decorData = []
self.estateType = 0 # NOT SURE IF THIS HAS ANY USE BUT THANKS DISNEY
self.cloudType = 0
self.dawnTime = 0
self.lastEpochTimestamp = 0
self.rentalTimestamp = 0
2015-03-12 21:12:43 -05:00
self.houses = [None, None, None, None, None, None]
2015-03-09 17:02:16 -05:00
self.rentalType = 0
self.rentalHandle = None
2015-03-03 16:10:12 -06:00
self.pond = None
self.spots = []
self.targets = []
2015-03-09 17:02:16 -05:00
self.doId2do = {}
2015-03-03 16:10:12 -06:00
self.owner = None
2015-03-09 17:02:16 -05:00
self.gardenManager = GardenManager(self)
self.__pendingGardens = {}
2015-03-03 16:10:12 -06:00
def generate(self):
DistributedObjectAI.generate(self)
self.pond = DistributedFishingPondAI(simbase.air)
self.pond.setArea(ToontownGlobals.MyEstate)
self.pond.generateWithRequired(self.zoneId)
for i in xrange(FishingTargetGlobals.getNumTargets(ToontownGlobals.MyEstate)):
target = DistributedFishingTargetAI(self.air)
target.setPondDoId(self.pond.getDoId())
target.generateWithRequired(self.zoneId)
self.targets.append(target)
spot = DistributedFishingSpotAI(self.air)
spot.setPondDoId(self.pond.getDoId())
spot.setPosHpr(49.1029, -124.805, 0.344704, 90, 0, 0)
spot.generateWithRequired(self.zoneId)
self.spots.append(spot)
spot = DistributedFishingSpotAI(self.air)
spot.setPondDoId(self.pond.getDoId())
spot.setPosHpr(46.5222, -134.739, 0.390713, 75, 0, 0)
spot.generateWithRequired(self.zoneId)
self.spots.append(spot)
spot = DistributedFishingSpotAI(self.air)
spot.setPondDoId(self.pond.getDoId())
spot.setPosHpr(41.31, -144.559, 0.375978, 45, 0, 0)
spot.generateWithRequired(self.zoneId)
self.spots.append(spot)
spot = DistributedFishingSpotAI(self.air)
spot.setPondDoId(self.pond.getDoId())
spot.setPosHpr(46.8254, -113.682, 0.46015, 135, 0, 0)
spot.generateWithRequired(self.zoneId)
self.spots.append(spot)
self.createTreasurePlanner()
2015-03-09 17:02:16 -05:00
def announceGenerate(self):
DistributedObjectAI.announceGenerate(self)
2015-03-15 11:26:22 -05:00
# Commented out because I had to reach estate to debug doors (Nacib)
#for index, garden in self.__pendingGardens.items():
# started = garden[0]
# self.gardenManager.handleSingleGarden(self.toons[index], garden[1:])
# self.placeStarterGarden(self.toons[index])
2015-03-09 17:02:16 -05:00
self.__pendingGardens = {}
2015-03-03 16:10:12 -06:00
def destroy(self):
for house in self.houses:
if house:
house.requestDelete()
2015-03-09 17:02:16 -05:00
self.houses = []
2015-03-03 16:10:12 -06:00
if self.pond:
for spot in self.spots:
spot.requestDelete()
2015-03-09 17:02:16 -05:00
self.spots = []
2015-03-03 16:10:12 -06:00
for target in self.targets:
target.requestDelete()
2015-03-09 17:02:16 -05:00
self.targets = []
self.pond.requestDelete()
self.pond = None
self.gardenManager.destroy()
2015-03-23 07:56:48 -05:00
if self.rentalHandle:
self.rentalHandle.destroy()
self.rentalHandle = None
2015-03-03 16:10:12 -06:00
if self.treasurePlanner:
self.treasurePlanner.stop()
self.requestDelete()
2015-03-09 17:02:16 -05:00
def addDistObj(self, distObj):
self.doId2do[distObj.doId] = distObj
2015-03-03 16:10:12 -06:00
def setClientReady(self):
self.sendUpdate('setEstateReady', [])
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
2015-03-09 17:02:16 -05:00
2015-03-03 16:10:12 -06:00
def setClosestHouse(self, todo0):
pass
def setTreasureIds(self, todo0):
pass
def createTreasurePlanner(self):
treasureType, healAmount, spawnPoints, spawnRate, maxTreasures = TreasureGlobals.SafeZoneTreasureSpawns[ToontownGlobals.MyEstate]
self.treasurePlanner = SZTreasurePlannerAI(self.zoneId, treasureType, healAmount, spawnPoints, spawnRate, maxTreasures)
self.treasurePlanner.start()
def requestServerTime(self):
avId = self.air.getAvatarIdFromSender()
self.sendUpdateToAvatarId(avId, 'setServerTime', [time.time() % HouseGlobals.DAY_NIGHT_PERIOD])
def setServerTime(self, todo0):
pass
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
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
2015-03-12 21:12:43 -05:00
def setLastEpochTimeStamp(self, last):
2015-03-03 16:10:12 -06:00
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):
2015-03-23 07:56:48 -05:00
self.setRentalTimeStamp(rental)
self.d_setRentalTimeStamp(rental)
2015-03-03 16:10:12 -06:00
def getRentalTimeStamp(self):
return self.rentalTimestamp
2015-03-23 07:56:48 -05:00
def b_setRentalType(self, type):
self.d_setRentalType(type)
self.setRentalType(type)
def d_setRentalType(self, type):
self.sendUpdate("setRentalType", [type])
def setRentalType(self, type):
expirestamp = self.getRentalTimeStamp()
if expirestamp == 0:
expire = 0
else:
expire = int(expirestamp - time.time())
if expire < 0:
self.rentalType = 0
self.d_setRentalType(0)
self.b_setRentalTimeStamp(0)
else:
if self.rentalType == type:
return
self.rentalType = type
if self.rentalHandle:
self.rentalHandle.destroy()
self.rentalHandle = None
if self.rentalType == ToontownGlobals.RentalCannon:
self.rentalHandle = CannonRental(self)
else:
self.notify.warning('Unknown rental %s' % self.rentalType)
return
self.rentalHandle.generateObjects()
2015-03-03 16:10:12 -06:00
def getRentalType(self):
2015-03-23 07:56:48 -05:00
return self.rentalType
def rentItem(self, rentType, duration):
self.rentalType = rentType
self.b_setRentalTimeStamp(time.time() + duration * 60)
self.b_setRentalType(rentType)
2015-03-03 16:10:12 -06:00
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]
def setSlot0Items(self, items):
self.items[0] = items
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]
def setSlot2ToonId(self, id):
self.toons[2] = id
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]
def setSlot2Items(self, items):
self.items[2] = items
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]
def setIdList(self, idList):
for i in xrange(len(idList)):
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
def awardedTrophy(self, todo0):
pass
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
def cannonsOver(self):
pass
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])
2015-03-09 17:02:16 -05:00
@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
self.notify.info('placeStarterGarden %d' % avId)
self.gardenManager.placeGarden(avId)
self.d_updateGarden()