ai: Getting somewhere
This commit is contained in:
parent
54cd9c8736
commit
e289553726
|
|
@ -1016,7 +1016,7 @@ class AIRepository(ConnectionRepository):
|
|||
datagram.addChannel(CONTROL_MESSAGE)
|
||||
datagram.addUint16(CONTROL_ADD_POST_REMOVE)
|
||||
|
||||
datagram.addString(themessage.getMessage())
|
||||
datagram.addBlob(themessage.getMessage())
|
||||
self.send(datagram)
|
||||
|
||||
def addPostSocketCloseUD(self, dclassName, fieldName, doId, args):
|
||||
|
|
|
|||
|
|
@ -1,37 +1,49 @@
|
|||
from direct.directnotify import DirectNotifyGlobal
|
||||
from direct.distributed.DistributedObjectAI import DistributedObjectAI
|
||||
|
||||
|
||||
from direct.distributed.DistributedObjectAI import DistributedObjectAI
|
||||
from direct.directnotify.DirectNotifyGlobal import directNotify
|
||||
|
||||
from direct.task import Task
|
||||
|
||||
class DistributedDistrictAI(DistributedObjectAI):
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedDistrictAI')
|
||||
|
||||
def __init__(self, air):
|
||||
notify = directNotify.newCategory("DistributedDistrictAI")
|
||||
|
||||
def __init__(self, air, name="untitled"):
|
||||
DistributedObjectAI.__init__(self, air)
|
||||
self.name = ''
|
||||
self.available = False
|
||||
self.air = air
|
||||
self.name=name
|
||||
self.available = 0
|
||||
|
||||
def delete(self):
|
||||
self.ignoreAll()
|
||||
self.b_setAvailable(0)
|
||||
DistributedObjectAI.delete(self)
|
||||
|
||||
def getAvailable(self):
|
||||
return self.available
|
||||
|
||||
def getName(self):
|
||||
return self.name
|
||||
|
||||
# available value
|
||||
def setAvailable(self, available):
|
||||
self.available=available
|
||||
|
||||
def d_setAvailable(self, available):
|
||||
self.sendUpdate("setAvailable", [available])
|
||||
|
||||
def b_setAvailable(self, available):
|
||||
self.setAvailable(available)
|
||||
self.d_setAvailable(available)
|
||||
|
||||
# set name
|
||||
def setName(self, name):
|
||||
self.name = name
|
||||
|
||||
self.name=name
|
||||
|
||||
def d_setName(self, name):
|
||||
self.sendUpdate('setName', [name])
|
||||
self.sendUpdate("setName", [name])
|
||||
|
||||
def b_setName(self, name):
|
||||
self.setName(name)
|
||||
self.d_setName(name)
|
||||
|
||||
def getName(self):
|
||||
return self.name
|
||||
|
||||
def setAvailable(self, available):
|
||||
self.available = available
|
||||
|
||||
def d_setAvailable(self, available):
|
||||
self.sendUpdate('setAvailable', [available])
|
||||
|
||||
def b_setAvailable(self, available):
|
||||
self.setAvailable(available)
|
||||
self.d_setAvailable(available)
|
||||
|
||||
def getAvailable(self):
|
||||
return self.available
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
from direct.directnotify import DirectNotifyGlobal
|
||||
from direct.distributed.DistributedObjectUD import DistributedObjectUD
|
||||
|
||||
|
||||
class DistributedDistrictUD(DistributedObjectUD):
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedDistrictUD')
|
||||
class DistributedDistrictUD:
|
||||
def __init__(self, air, name="untitled"):
|
||||
assert 0, "Hey, This assert is here to let you know that a DistributedDistrict should not be on a UD server."
|
||||
# There is probably a bug somewhere if you are getting a district
|
||||
# on an uberDog server, districts are for AI district servers and
|
||||
# clients.
|
||||
|
|
|
|||
|
|
@ -21,19 +21,19 @@ print("Initializing...")
|
|||
|
||||
from otp.ai.AIBaseGlobal import *
|
||||
from . import ToontownAIRepository
|
||||
from direct.showbase import PythonUtil
|
||||
from otp.otpbase import PythonUtil
|
||||
|
||||
# Clear the default model extension for AI developers, so they'll know
|
||||
# when they screw up and omit it.
|
||||
from panda3d.core import loadPrcFileData
|
||||
loadPrcFileData("AIStart.py", "default-model-extension")
|
||||
|
||||
simbase.mdip = simbase.config.GetString("msg-director-ip", "localhost")
|
||||
simbase.mdip = simbase.config.GetString("msg-director-ip", "127.0.0.1")
|
||||
|
||||
# Now the AI connects directly to the state server instead of the msg director
|
||||
simbase.mdport = simbase.config.GetInt("msg-director-port", 6666)
|
||||
|
||||
simbase.esip = simbase.config.GetString("event-server-ip", "localhost")
|
||||
simbase.esip = simbase.config.GetString("event-server-ip", "127.0.0.1")
|
||||
simbase.esport = simbase.config.GetInt("event-server-port", 4343)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -536,7 +536,7 @@ class ToontownAIRepository(AIDistrict):
|
|||
# them can be used to fill the world with requests for suit
|
||||
# buildings.
|
||||
if self.suitPlanners:
|
||||
self.suitPlanners.values()[0].assignInitialSuitBuildings()
|
||||
list(self.suitPlanners.values())[0].assignInitialSuitBuildings()
|
||||
|
||||
# mark district as avaliable
|
||||
self.district.b_setAvailable(1)
|
||||
|
|
|
|||
|
|
@ -1,20 +1,73 @@
|
|||
""" DistributedBuildingMgrAI module: contains the DistributedBuildingMgrAI
|
||||
class, the server side handler of all buildings in a neighborhood."""
|
||||
|
||||
# AI code should not import ShowBaseGlobal because it creates a graphics window
|
||||
# Use AIBaseGlobal instead
|
||||
# from ShowBaseGlobal import *
|
||||
|
||||
import os
|
||||
from direct.task.Task import Task
|
||||
import json
|
||||
import pickle
|
||||
from otp.ai.AIBaseGlobal import *
|
||||
from . import DistributedBuildingAI, HQBuildingAI, GagshopBuildingAI, PetshopBuildingAI
|
||||
from . import DistributedBuildingAI
|
||||
from . import HQBuildingAI
|
||||
from . import GagshopBuildingAI
|
||||
from . import PetshopBuildingAI
|
||||
from toontown.building.KartShopBuildingAI import KartShopBuildingAI
|
||||
from toontown.building import DistributedAnimBuildingAI
|
||||
#import DistributedDoorAI
|
||||
from direct.directnotify import DirectNotifyGlobal
|
||||
from toontown.hood import ZoneUtil
|
||||
import time, random
|
||||
import time
|
||||
import random
|
||||
|
||||
|
||||
class DistributedBuildingMgrAI:
|
||||
"""
|
||||
DistributedBuildingMgrAI class: a server side object, keeps track of
|
||||
all buildings within a single neighborhood (street), handles
|
||||
converting them from good to bad, and hands out information about
|
||||
buildings to whoever asks.
|
||||
|
||||
Landmark data will be saved to an AI Server local file.
|
||||
|
||||
*How landmark building info gets loaded:
|
||||
load list from dna;
|
||||
|
||||
look for backup .buildings file;
|
||||
if present:
|
||||
load from backup buildings file;
|
||||
#if buildings file is present:
|
||||
# remove buildings file;
|
||||
else:
|
||||
load .buildings file;
|
||||
|
||||
compare dna list with saved list;
|
||||
if they are different:
|
||||
make reasonable matches for suit blocks;
|
||||
|
||||
create the building AI dictionary
|
||||
|
||||
*Saving building data:
|
||||
check for backup buildings file;
|
||||
if present:
|
||||
remove buildings file;
|
||||
else:
|
||||
move buildings file to backup file;
|
||||
write new buildings file;
|
||||
remove backup buildings file;
|
||||
"""
|
||||
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedBuildingMgrAI')
|
||||
serverDatafolder = simbase.config.GetString('server-data-folder', "")
|
||||
|
||||
def __init__(self, air, branchID, dnaStore, trophyMgr):
|
||||
"""
|
||||
branchID: The street number. Such as 2200.
|
||||
"""
|
||||
self.branchID = branchID
|
||||
self.canonicalBranchID = ZoneUtil.getCanonicalZoneId(branchID)
|
||||
assert(self.debugPrint("__init__(air, branchID, dnaStore, trophyMgr)"))
|
||||
self.air = air
|
||||
self.__buildings = {}
|
||||
self.dnaStore = dnaStore
|
||||
|
|
@ -23,32 +76,38 @@ class DistributedBuildingMgrAI:
|
|||
self.backupExtension = '.bu'
|
||||
self.findAllLandmarkBuildings()
|
||||
self.doLaterTask = None
|
||||
return
|
||||
|
||||
|
||||
def cleanup(self):
|
||||
taskMgr.remove(str(self.branchID) + '_delayed_save-timer')
|
||||
for building in list(self.__buildings.values()):
|
||||
taskMgr.remove(str(self.branchID)+'_delayed_save-timer')
|
||||
|
||||
for building in self.__buildings.values():
|
||||
building.cleanup()
|
||||
|
||||
self.__buildings = {}
|
||||
|
||||
|
||||
def isValidBlockNumber(self, blockNumber):
|
||||
return blockNumber in self.__buildings
|
||||
"""return true if that block refers to a real block"""
|
||||
assert(self.debugPrint("isValidBlockNumber(blockNumber="+str(blockNumber)+")"))
|
||||
return self.__buildings.has_key(blockNumber)
|
||||
|
||||
def delayedSaveTask(self, task):
|
||||
assert(self.debugPrint("delayedSaveTask()"))
|
||||
self.save()
|
||||
self.doLaterTask = None
|
||||
self.doLaterTask=None
|
||||
return Task.done
|
||||
|
||||
def isSuitBlock(self, blockNumber):
|
||||
"""return true if that block is a suit block/building"""
|
||||
assert(self.debugPrint("isSuitBlock(blockNumber="+str(blockNumber)+")"))
|
||||
assert(self.__buildings.has_key(blockNumber))
|
||||
return self.__buildings[blockNumber].isSuitBlock()
|
||||
|
||||
def getSuitBlocks(self):
|
||||
blocks = []
|
||||
for i in list(self.__buildings.values()):
|
||||
assert(self.debugPrint("getSuitBlocks()"))
|
||||
blocks=[]
|
||||
for i in self.__buildings.values():
|
||||
if i.isSuitBlock():
|
||||
blocks.append(i.getBlock()[0])
|
||||
|
||||
return blocks
|
||||
|
||||
def isCogdoBlock(self, blockNumber):
|
||||
|
|
@ -63,193 +122,289 @@ class DistributedBuildingMgrAI:
|
|||
return blocks
|
||||
|
||||
def getEstablishedSuitBlocks(self):
|
||||
blocks = []
|
||||
for i in list(self.__buildings.values()):
|
||||
assert(self.debugPrint("getEstablishedSuitBlocks()"))
|
||||
blocks=[]
|
||||
for i in self.__buildings.values():
|
||||
if i.isEstablishedSuitBlock():
|
||||
blocks.append(i.getBlock()[0])
|
||||
|
||||
return blocks
|
||||
|
||||
def getToonBlocks(self):
|
||||
blocks = []
|
||||
for i in list(self.__buildings.values()):
|
||||
assert(self.debugPrint("getToonBlocks()"))
|
||||
blocks=[]
|
||||
for i in self.__buildings.values():
|
||||
if isinstance(i, HQBuildingAI.HQBuildingAI):
|
||||
continue
|
||||
if not i.isSuitBlock():
|
||||
blocks.append(i.getBlock()[0])
|
||||
|
||||
return blocks
|
||||
|
||||
def getBuildings(self):
|
||||
return list(self.__buildings.values())
|
||||
return self.__buildings.values()
|
||||
|
||||
def getFrontDoorPoint(self, blockNumber):
|
||||
"""get any associated path point for the specified building,
|
||||
useful for suits to know where to go when exiting from a
|
||||
building"""
|
||||
assert(self.debugPrint("getFrontDoorPoint(blockNumber="+str(blockNumber)+")"))
|
||||
assert(self.__buildings.has_key(blockNumber))
|
||||
return self.__buildings[blockNumber].getFrontDoorPoint()
|
||||
|
||||
def getBuildingTrack(self, blockNumber):
|
||||
"""get any associated path point for the specified building,
|
||||
useful for suits to know where to go when exiting from a
|
||||
building"""
|
||||
assert(self.debugPrint("getBuildingTrack(blockNumber="+str(blockNumber)+")"))
|
||||
assert(self.__buildings.has_key(blockNumber))
|
||||
return self.__buildings[blockNumber].track
|
||||
|
||||
def getBuilding(self, blockNumber):
|
||||
def getBuilding( self, blockNumber ):
|
||||
assert(self.debugPrint("getBuilding(%s)" %(str(blockNumber),)))
|
||||
assert(self.__buildings.has_key(blockNumber))
|
||||
return self.__buildings[blockNumber]
|
||||
|
||||
|
||||
def setFrontDoorPoint(self, blockNumber, point):
|
||||
"""get any associated path point for the specified building,
|
||||
useful for suits to know where to go when exiting from a
|
||||
building"""
|
||||
assert(self.debugPrint("setFrontDoorPoint(blockNumber="+str(blockNumber)
|
||||
+", point="+str(point)+")"))
|
||||
assert(self.__buildings.has_key(blockNumber))
|
||||
return self.__buildings[blockNumber].setFrontDoorPoint(point)
|
||||
|
||||
|
||||
def getDNABlockLists(self):
|
||||
blocks = []
|
||||
hqBlocks = []
|
||||
gagshopBlocks = []
|
||||
petshopBlocks = []
|
||||
blocks=[]
|
||||
hqBlocks=[]
|
||||
gagshopBlocks=[]
|
||||
petshopBlocks=[]
|
||||
kartshopBlocks = []
|
||||
animBldgBlocks = []
|
||||
for i in range(self.dnaStore.getNumBlockNumbers()):
|
||||
blockNumber = self.dnaStore.getBlockNumberAt(i)
|
||||
buildingType = self.dnaStore.getBlockBuildingType(blockNumber)
|
||||
if buildingType == 'hq':
|
||||
hqBlocks.append(blockNumber)
|
||||
elif buildingType == 'gagshop':
|
||||
if (buildingType == 'hq'):
|
||||
hqBlocks.append(blockNumber)
|
||||
elif (buildingType == 'gagshop'):
|
||||
gagshopBlocks.append(blockNumber)
|
||||
elif buildingType == 'petshop':
|
||||
elif (buildingType == 'petshop'):
|
||||
petshopBlocks.append(blockNumber)
|
||||
elif buildingType == 'kartshop':
|
||||
kartshopBlocks.append(blockNumber)
|
||||
elif buildingType == 'animbldg':
|
||||
animBldgBlocks.append(blockNumber)
|
||||
elif( buildingType == 'kartshop' ):
|
||||
kartshopBlocks.append( blockNumber )
|
||||
elif( buildingType == 'animbldg' ):
|
||||
animBldgBlocks.append( blockNumber )
|
||||
else:
|
||||
blocks.append(blockNumber)
|
||||
|
||||
return (
|
||||
blocks, hqBlocks, gagshopBlocks, petshopBlocks, kartshopBlocks, animBldgBlocks)
|
||||
|
||||
return blocks, hqBlocks, gagshopBlocks, petshopBlocks, kartshopBlocks, animBldgBlocks
|
||||
|
||||
def findAllLandmarkBuildings(self):
|
||||
buildings = self.load()
|
||||
assert(self.debugPrint("findAllLandmarkBuildings()"))
|
||||
# Load the saved buildings:
|
||||
buildings=self.load()
|
||||
# Create the distributed buildings:
|
||||
blocks, hqBlocks, gagshopBlocks, petshopBlocks, kartshopBlocks, animBldgBlocks = self.getDNABlockLists()
|
||||
for block in blocks:
|
||||
# Used saved data, if appropriate:
|
||||
self.newBuilding(block, buildings.get(block, None))
|
||||
|
||||
for block in animBldgBlocks:
|
||||
# Used saved data, if appropriate:
|
||||
self.newAnimBuilding(block, buildings.get(block, None))
|
||||
|
||||
for block in hqBlocks:
|
||||
self.newHQBuilding(block)
|
||||
|
||||
for block in gagshopBlocks:
|
||||
self.newGagshopBuilding(block)
|
||||
|
||||
|
||||
if simbase.wantPets:
|
||||
for block in petshopBlocks:
|
||||
self.newPetshopBuilding(block)
|
||||
|
||||
if simbase.wantKarts:
|
||||
if( simbase.wantKarts ):
|
||||
for block in kartshopBlocks:
|
||||
self.newKartShopBuilding(block)
|
||||
|
||||
return
|
||||
self.newKartShopBuilding( block )
|
||||
|
||||
def newBuilding(self, blockNumber, blockData=None):
|
||||
building = DistributedBuildingAI.DistributedBuildingAI(self.air, blockNumber, self.branchID, self.trophyMgr)
|
||||
"""Create a new building and keep track of it."""
|
||||
assert(self.debugPrint("newBuilding(blockNumber="+str(blockNumber)
|
||||
+", blockData="+str(blockData)+")"))
|
||||
assert(not self.__buildings.has_key(blockNumber))
|
||||
|
||||
building=DistributedBuildingAI.DistributedBuildingAI(
|
||||
self.air, blockNumber, self.branchID, self.trophyMgr)
|
||||
building.generateWithRequired(self.branchID)
|
||||
if blockData:
|
||||
building.track = blockData.get('track', 'c')
|
||||
building.difficulty = int(blockData.get('difficulty', 1))
|
||||
building.numFloors = int(blockData.get('numFloors', 1))
|
||||
building.track = blockData.get("track", "c")
|
||||
building.difficulty = int(blockData.get("difficulty", 1))
|
||||
building.numFloors = int(blockData.get("numFloors", 1))
|
||||
building.numFloors = max(1, min(5, building.numFloors))
|
||||
if not ZoneUtil.isWelcomeValley(building.zoneId):
|
||||
building.updateSavedBy(blockData.get('savedBy'))
|
||||
if not ZoneUtil.isWelcomeValley(building.zoneId):
|
||||
building.updateSavedBy(blockData.get("savedBy"))
|
||||
else:
|
||||
self.notify.warning('we had a cog building in welcome valley %d' % building.zoneId)
|
||||
building.becameSuitTime = blockData.get('becameSuitTime', time.time())
|
||||
if blockData['state'] == 'suit':
|
||||
building.setState('suit')
|
||||
building.becameSuitTime = blockData.get("becameSuitTime", time.time())
|
||||
|
||||
# Double check the state becuase we have seen the building
|
||||
# saved out with other states (like waitForVictor). If we
|
||||
# get one of these weird states, just make it a toon bldg
|
||||
if blockData["state"] == "suit":
|
||||
building.setState("suit")
|
||||
elif blockData['state'] == 'cogdo':
|
||||
if simbase.air.wantCogdominiums:
|
||||
building.numFloors = DistributedBuildingAI.DistributedBuildingAI.FieldOfficeNumFloors
|
||||
building.setState('cogdo')
|
||||
building.setState("cogdo")
|
||||
else:
|
||||
building.setState('toon')
|
||||
building.setState("toon")
|
||||
else:
|
||||
building.setState('toon')
|
||||
building.setState("toon")
|
||||
self.__buildings[blockNumber] = building
|
||||
return building
|
||||
|
||||
def newAnimBuilding(self, blockNumber, blockData=None):
|
||||
building = DistributedAnimBuildingAI.DistributedAnimBuildingAI(self.air, blockNumber, self.branchID, self.trophyMgr)
|
||||
"""Create a new building and keep track of it."""
|
||||
assert(self.debugPrint("newBuilding(blockNumber="+str(blockNumber)
|
||||
+", blockData="+str(blockData)+")"))
|
||||
assert(not self.__buildings.has_key(blockNumber))
|
||||
|
||||
building=DistributedAnimBuildingAI.DistributedAnimBuildingAI(
|
||||
self.air, blockNumber, self.branchID, self.trophyMgr)
|
||||
building.generateWithRequired(self.branchID)
|
||||
if blockData:
|
||||
building.track = blockData.get('track', 'c')
|
||||
building.difficulty = int(blockData.get('difficulty', 1))
|
||||
building.numFloors = int(blockData.get('numFloors', 1))
|
||||
if not ZoneUtil.isWelcomeValley(building.zoneId):
|
||||
building.updateSavedBy(blockData.get('savedBy'))
|
||||
building.track = blockData.get("track", "c")
|
||||
building.difficulty = int(blockData.get("difficulty", 1))
|
||||
building.numFloors = int(blockData.get("numFloors", 1))
|
||||
if not ZoneUtil.isWelcomeValley(building.zoneId):
|
||||
building.updateSavedBy(blockData.get("savedBy"))
|
||||
else:
|
||||
self.notify.warning('we had a cog building in welcome valley %d' % building.zoneId)
|
||||
building.becameSuitTime = blockData.get('becameSuitTime', time.time())
|
||||
if blockData['state'] == 'suit':
|
||||
building.setState('suit')
|
||||
building.becameSuitTime = blockData.get("becameSuitTime", time.time())
|
||||
|
||||
# Double check the state becuase we have seen the building
|
||||
# saved out with other states (like waitForVictor). If we
|
||||
# get one of these weird states, just make it a toon bldg
|
||||
if blockData["state"] == "suit":
|
||||
building.setState("suit")
|
||||
else:
|
||||
building.setState('toon')
|
||||
building.setState("toon")
|
||||
else:
|
||||
building.setState('toon')
|
||||
building.setState("toon")
|
||||
self.__buildings[blockNumber] = building
|
||||
return building
|
||||
return building
|
||||
|
||||
def newHQBuilding(self, blockNumber):
|
||||
"""Create a new HQ building and keep track of it."""
|
||||
assert(not self.__buildings.has_key(blockNumber))
|
||||
dnaStore = self.air.dnaStoreMap[self.canonicalBranchID]
|
||||
exteriorZoneId = dnaStore.getZoneFromBlockNumber(blockNumber)
|
||||
exteriorZoneId = ZoneUtil.getTrueZoneId(exteriorZoneId, self.branchID)
|
||||
interiorZoneId = self.branchID - self.branchID % 100 + 500 + blockNumber
|
||||
building = HQBuildingAI.HQBuildingAI(self.air, exteriorZoneId, interiorZoneId, blockNumber)
|
||||
interiorZoneId = (self.branchID-self.branchID%100)+500+blockNumber
|
||||
assert(self.debugPrint("newHQBuilding(blockNumber=%s exteriorZoneId=%s interiorZoneId=%s" %
|
||||
(blockNumber, exteriorZoneId, interiorZoneId)))
|
||||
building=HQBuildingAI.HQBuildingAI(self.air, exteriorZoneId, interiorZoneId, blockNumber)
|
||||
self.__buildings[blockNumber] = building
|
||||
return building
|
||||
|
||||
def newGagshopBuilding(self, blockNumber):
|
||||
"""Create a new Gagshop building and keep track of it."""
|
||||
assert(self.debugPrint("newGagshopBuilding(blockNumber="+str(blockNumber)+")"))
|
||||
assert(not self.__buildings.has_key(blockNumber))
|
||||
dnaStore = self.air.dnaStoreMap[self.canonicalBranchID]
|
||||
exteriorZoneId = dnaStore.getZoneFromBlockNumber(blockNumber)
|
||||
exteriorZoneId = ZoneUtil.getTrueZoneId(exteriorZoneId, self.branchID)
|
||||
interiorZoneId = self.branchID - self.branchID % 100 + 500 + blockNumber
|
||||
building = GagshopBuildingAI.GagshopBuildingAI(self.air, exteriorZoneId, interiorZoneId, blockNumber)
|
||||
interiorZoneId = (self.branchID-self.branchID%100)+500+blockNumber
|
||||
building=GagshopBuildingAI.GagshopBuildingAI(self.air, exteriorZoneId, interiorZoneId, blockNumber)
|
||||
self.__buildings[blockNumber] = building
|
||||
return building
|
||||
|
||||
|
||||
def newPetshopBuilding(self, blockNumber):
|
||||
"""Create a new Petshop building and keep track of it."""
|
||||
assert(self.debugPrint("newPetshopBuilding(blockNumber="+str(blockNumber)+")"))
|
||||
assert(not self.__buildings.has_key(blockNumber))
|
||||
dnaStore = self.air.dnaStoreMap[self.canonicalBranchID]
|
||||
exteriorZoneId = dnaStore.getZoneFromBlockNumber(blockNumber)
|
||||
exteriorZoneId = ZoneUtil.getTrueZoneId(exteriorZoneId, self.branchID)
|
||||
interiorZoneId = self.branchID - self.branchID % 100 + 500 + blockNumber
|
||||
building = PetshopBuildingAI.PetshopBuildingAI(self.air, exteriorZoneId, interiorZoneId, blockNumber)
|
||||
interiorZoneId = (self.branchID-self.branchID%100)+500+blockNumber
|
||||
building=PetshopBuildingAI.PetshopBuildingAI(self.air, exteriorZoneId, interiorZoneId, blockNumber)
|
||||
self.__buildings[blockNumber] = building
|
||||
return building
|
||||
|
||||
def newKartShopBuilding(self, blockNumber):
|
||||
dnaStore = self.air.dnaStoreMap[self.canonicalBranchID]
|
||||
exteriorZoneId = dnaStore.getZoneFromBlockNumber(blockNumber)
|
||||
exteriorZoneId = ZoneUtil.getTrueZoneId(exteriorZoneId, self.branchID)
|
||||
interiorZoneId = self.branchID - self.branchID % 100 + 500 + blockNumber
|
||||
building = KartShopBuildingAI(self.air, exteriorZoneId, interiorZoneId, blockNumber)
|
||||
self.__buildings[blockNumber] = building
|
||||
return building
|
||||
def newKartShopBuilding( self, blockNumber ):
|
||||
"""
|
||||
Purpose: The newKartShopBuilding Method creates a new KartShop
|
||||
building and keeps track of it.
|
||||
|
||||
Params: blockNumber - block that the shop is on.
|
||||
Return: None
|
||||
"""
|
||||
assert( self.debugPrint( "newKartShopBuilding(blockNumber=" + str( blockNumber ) + ")" ) )
|
||||
assert( not self.__buildings.has_key( blockNumber ) )
|
||||
|
||||
dnaStore = self.air.dnaStoreMap[ self.canonicalBranchID ]
|
||||
|
||||
# Retrieve the Exterior and Interior ZoneIds
|
||||
exteriorZoneId = dnaStore.getZoneFromBlockNumber( blockNumber )
|
||||
exteriorZoneId = ZoneUtil.getTrueZoneId( exteriorZoneId, self.branchID )
|
||||
interiorZoneId = ( self.branchID - self.branchID%100 ) + 500 + blockNumber
|
||||
|
||||
building = KartShopBuildingAI( self.air, exteriorZoneId, interiorZoneId, blockNumber )
|
||||
self.__buildings[ blockNumber ] = building
|
||||
|
||||
return building
|
||||
|
||||
def getFileName(self):
|
||||
f = '%s%s_%d_buildings.json' % (self.air.dataFolder, self.shard, self.branchID)
|
||||
"""Figure out the path to the saved state"""
|
||||
f = "%s%s_%d.buildings" % (self.serverDatafolder, self.shard, self.branchID)
|
||||
assert(self.debugPrint("getFileName() returning \""+str(f)+"\""))
|
||||
return f
|
||||
|
||||
def saveTo(self, file):
|
||||
buildings = {}
|
||||
for i in list(self.__buildings.values()):
|
||||
if isinstance(i, HQBuildingAI.HQBuildingAI):
|
||||
continue
|
||||
buildingData = i.getBuildingData()
|
||||
buildings[buildingData['block']] = buildingData
|
||||
|
||||
json.dump(buildings, file, indent=2)
|
||||
|
||||
def save(self):
|
||||
|
||||
def saveTo(self, file, block=None):
|
||||
"""Save data to specified file"""
|
||||
assert(self.debugPrint("saveTo(file="+str(file)+", block="+str(block)+")"))
|
||||
if block:
|
||||
# Save just this one block to the file:
|
||||
pickleData=block.getPickleData()
|
||||
pickle.dump(pickleData, file)
|
||||
else:
|
||||
# Save them all:
|
||||
for i in self.__buildings.values():
|
||||
# HQs do not need to be saved
|
||||
if isinstance(i, HQBuildingAI.HQBuildingAI):
|
||||
continue
|
||||
pickleData=i.getPickleData()
|
||||
pickle.dump(pickleData, file)
|
||||
|
||||
def fastSave(self, block):
|
||||
"""Save data to default location"""
|
||||
return
|
||||
# This code has not been tested or connected. If the normal save takes
|
||||
# too long on the AI server, this fastSave should be considered.
|
||||
assert(0)
|
||||
assert(self.debugPrint("fastSave(block="+str(block)+")"))
|
||||
try:
|
||||
fileName = self.getFileName()
|
||||
backup = fileName + self.backupExtension
|
||||
fileName=self.getFileName()+'.delta'
|
||||
working=fileName+'.temp'
|
||||
# Change the name to flag the work in progress:
|
||||
if os.path.exists(working):
|
||||
os.remove(working)
|
||||
os.rename(fileName, working)
|
||||
file=open(working, 'w')
|
||||
file.seek(0, 2)
|
||||
self.saveTo(file, block)
|
||||
file.close()
|
||||
# Change the name to flag the work complete:
|
||||
os.rename(working, fileName)
|
||||
except IOError:
|
||||
self.notify.error(str(sys.exc_info()[1]))
|
||||
# Even if it's just the rename that failed, we don't want to
|
||||
# clobber the prior file.
|
||||
|
||||
def save(self):
|
||||
"""Save data to default location"""
|
||||
assert(self.debugPrint("save()"))
|
||||
try:
|
||||
fileName=self.getFileName()
|
||||
backup=fileName+self.backupExtension
|
||||
# Move current file as the backup file:
|
||||
if os.path.exists(fileName):
|
||||
os.rename(fileName, backup)
|
||||
file = open(fileName, 'w')
|
||||
file=open(fileName, 'w')
|
||||
file.seek(0)
|
||||
self.saveTo(file)
|
||||
file.close()
|
||||
|
|
@ -257,28 +412,47 @@ class DistributedBuildingMgrAI:
|
|||
os.remove(backup)
|
||||
except EnvironmentError:
|
||||
self.notify.warning(str(sys.exc_info()[1]))
|
||||
|
||||
# Even if it's just the rename that failed, we don't want to
|
||||
# clobber the prior file.
|
||||
|
||||
def loadFrom(self, file):
|
||||
blocks = {}
|
||||
buildingData = json.load(file)
|
||||
for block in buildingData:
|
||||
blocks[int(block)] = buildingData[block]
|
||||
|
||||
return blocks
|
||||
|
||||
def load(self):
|
||||
fileName = self.getFileName()
|
||||
"""Load data from specified file"""
|
||||
assert(self.debugPrint("loadFrom(file="+str(file)+")"))
|
||||
blocks={}
|
||||
try:
|
||||
file = open(fileName + self.backupExtension, 'r')
|
||||
while 1:
|
||||
pickleData=pickle.load(file)
|
||||
blocks[int(pickleData['block'])]=pickleData
|
||||
except EOFError:
|
||||
pass
|
||||
return blocks
|
||||
|
||||
def load(self):
|
||||
"""Load data from default location"""
|
||||
assert(self.debugPrint("load()"))
|
||||
fileName=self.getFileName()
|
||||
try:
|
||||
# Try to open the backup file:
|
||||
file=open(fileName+self.backupExtension, 'r')
|
||||
# Remove the (assumed) broken file:
|
||||
if os.path.exists(fileName):
|
||||
os.remove(fileName)
|
||||
except IOError:
|
||||
# OK, there's no backup file, good.
|
||||
try:
|
||||
file = open(fileName, 'r')
|
||||
# Open the real file:
|
||||
file=open(fileName, 'r')
|
||||
except IOError:
|
||||
# OK, there's no file. Start new list:
|
||||
return {}
|
||||
|
||||
file.seek(0)
|
||||
blocks = self.loadFrom(file)
|
||||
blocks=self.loadFrom(file)
|
||||
file.close()
|
||||
return blocks
|
||||
|
||||
if __debug__:
|
||||
def debugPrint(self, message):
|
||||
"""for debugging"""
|
||||
return self.notify.debug(
|
||||
str(self.__dict__.get('branchID', '?'))+' '+message)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,31 @@
|
|||
from direct.directnotify import DirectNotifyGlobal
|
||||
from direct.directnotify.DirectNotifyGlobal import directNotify
|
||||
from direct.task import Task
|
||||
from otp.distributed.OtpDoGlobals import *
|
||||
from otp.distributed.DistributedDistrictAI import DistributedDistrictAI
|
||||
from toontown.distributed import ToontownDistrictStatsAI
|
||||
|
||||
class ToontownDistrictAI(DistributedDistrictAI):
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory('ToontownDistrictAI')
|
||||
|
||||
def __init__(self, air):
|
||||
DistributedDistrictAI.__init__(self, air)
|
||||
"""
|
||||
See Also: "toontown/src/distributed/DistributedDistrict.py"
|
||||
"""
|
||||
notify = directNotify.newCategory("ToontownDistrictAI")
|
||||
|
||||
def __init__(self, air, name="untitled"):
|
||||
DistributedDistrictAI.__init__(self, air, name)
|
||||
self.stats = None
|
||||
self.ahnnLog = False
|
||||
|
||||
def generate(self):
|
||||
DistributedDistrictAI.generate(self)
|
||||
self.stats = ToontownDistrictStatsAI.ToontownDistrictStatsAI(self.air)
|
||||
self.stats.toontownDistrictId = self.doId
|
||||
self.stats.generateOtpObject(self.stats.defaultParent, self.stats.defaultZone)
|
||||
|
||||
def delete(self):
|
||||
DistributedDistrictAI.delete(self)
|
||||
if(self.stats is not None):
|
||||
self.stats.requestDelete()
|
||||
self.stats = None
|
||||
|
||||
def allowAHNNLog(self, ahnnLog):
|
||||
self.ahnnLog = ahnnLog
|
||||
|
|
|
|||
|
|
@ -1,50 +1,89 @@
|
|||
from direct.distributed import DistributedObjectAI
|
||||
from direct.directnotify import DirectNotifyGlobal
|
||||
from direct.distributed.DistributedObjectAI import DistributedObjectAI
|
||||
from direct.task import Task
|
||||
|
||||
class ToontownDistrictStatsAI(DistributedObjectAI):
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory('ToontownDistrictStatsAI')
|
||||
from otp.distributed.OtpDoGlobals import *
|
||||
|
||||
|
||||
class ToontownDistrictStatsAI(DistributedObjectAI.DistributedObjectAI):
|
||||
"""
|
||||
See Also: "toontown/src/distributed/DistributedDistrictAi.py"
|
||||
"""
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory("ToontownDistrictStatsAI")
|
||||
|
||||
defaultParent = OTP_DO_ID_TOONTOWN
|
||||
defaultZone = OTP_ZONE_ID_DISTRICTS_STATS
|
||||
|
||||
|
||||
|
||||
def __init__(self, air):
|
||||
DistributedObjectAI.__init__(self, air)
|
||||
DistributedObjectAI.DistributedObjectAI.__init__(self, air)
|
||||
self.updateFreq = 5
|
||||
self.toontownDistrictId = 0
|
||||
self.avatarCount = 0
|
||||
self.newAvatarCount = 0
|
||||
|
||||
def settoontownDistrictId(self, toontownDistrictId):
|
||||
self.toontownDistrictId = toontownDistrictId
|
||||
|
||||
def d_settoontownDistrictId(self, toontownDistrictId):
|
||||
self.sendUpdate('settoontownDistrictId', [toontownDistrictId])
|
||||
|
||||
def b_settoontownDistrictId(self, toontownDistrictId):
|
||||
self.settoontownDistrictId(toontownDistrictId)
|
||||
self.d_settoontownDistrictId(toontownDistrictId)
|
||||
|
||||
|
||||
def gettoontownDistrictId(self):
|
||||
return self.toontownDistrictId
|
||||
return self.toontownDistrictId
|
||||
|
||||
def generate(self):
|
||||
DistributedObjectAI.DistributedObjectAI.generate(self)
|
||||
self.pushDistrictStats(firstTime=True)
|
||||
|
||||
|
||||
def delete(self):
|
||||
taskMgr.remove("DistributedToonDistrictAIStatsUpdate")
|
||||
DistributedObjectAI.DistributedObjectAI.delete(self)
|
||||
|
||||
# set avatar count
|
||||
def setAvatarCount(self, avatarCount):
|
||||
self.avatarCount = avatarCount
|
||||
|
||||
pass
|
||||
|
||||
def d_setAvatarCount(self, avatarCount):
|
||||
self.sendUpdate('setAvatarCount', [avatarCount])
|
||||
|
||||
self.sendUpdate("setAvatarCount", [avatarCount])
|
||||
|
||||
def b_setAvatarCount(self, avatarCount):
|
||||
self.setAvatarCount(avatarCount)
|
||||
self.d_setAvatarCount(avatarCount)
|
||||
self.setAvatarCount(avatarCount)
|
||||
self.d_setAvatarCount(avatarCount)
|
||||
|
||||
def getAvatarCount(self):
|
||||
return self.avatarCount
|
||||
|
||||
return 0
|
||||
|
||||
## avatars in bewbe zone...
|
||||
def setNewAvatarCount(self, newAvatarCount):
|
||||
self.newAvatarCount = newAvatarCount
|
||||
pass
|
||||
|
||||
def d_setNewAvatarCount(self, newAvatarCount):
|
||||
self.sendUpdate('setNewAvatarCount', [newAvatarCount])
|
||||
|
||||
self.sendUpdate("setAvatarCount", [newAvatarCount])
|
||||
|
||||
def b_setNewAvatarCount(self, newAvatarCount):
|
||||
self.setNewAvatarCount(newAvatarCount)
|
||||
self.d_setNewAvatarCount(newAvatarCount)
|
||||
|
||||
def getNewAvatarCount(self):
|
||||
return self.newAvatarCount
|
||||
return 0
|
||||
|
||||
## stat fields...
|
||||
|
||||
def setStats(self, avatarCount, newAvatarCount):
|
||||
self.setAvatarCount(avatarCount)
|
||||
self.setNewAvatarCount(newAvatarCount)
|
||||
|
||||
def d_setStats(self, avatarCount, newAvatarCount):
|
||||
self.sendUpdate("setStats", [avatarCount, newAvatarCount])
|
||||
|
||||
def b_setStats(self, avatarCount, newAvatarCount):
|
||||
self.setStats(avatarCount, newAvatarCount)
|
||||
self.d_setStats(avatarCount, newAvatarCount)
|
||||
|
||||
|
||||
def pushDistrictStats(self, task=None, firstTime=False):
|
||||
if self.isDeleted():
|
||||
return
|
||||
# the first time we're called, the AIR doesn't have a welcomeValleyManager yet
|
||||
if firstTime:
|
||||
wvCount = 0
|
||||
else:
|
||||
wvCount = self.air.getWelcomeValleyCount()
|
||||
avatar_count = self.air.getPopulation()
|
||||
self.b_setStats(avatar_count, wvCount)
|
||||
taskMgr.doMethodLater(self.updateFreq, self.pushDistrictStats, "DistributedDistrictUpdate")
|
||||
self.air.writeServerStatus("", avatar_count, len(self.air.doId2do))
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue