mirror of
https://github.com/Sneed-Group/Poodletooth-iLand
synced 2024-12-26 13:12:30 -06:00
145 lines
5.1 KiB
Python
145 lines
5.1 KiB
Python
|
|
||
|
from pandac.PandaModules import *
|
||
|
|
||
|
from direct.task import Task
|
||
|
from DistributedNodeAI import DistributedNodeAI
|
||
|
from CartesianGridBase import CartesianGridBase
|
||
|
|
||
|
class DistributedCartesianGridAI(DistributedNodeAI, CartesianGridBase):
|
||
|
notify = directNotify.newCategory("DistributedCartesianGridAI")
|
||
|
|
||
|
RuleSeparator = ":"
|
||
|
|
||
|
def __init__(self, air, startingZone, gridSize, gridRadius, cellWidth,
|
||
|
style="Cartesian"):
|
||
|
DistributedNodeAI.__init__(self, air)
|
||
|
self.style = style
|
||
|
self.startingZone = startingZone
|
||
|
self.gridSize = gridSize
|
||
|
self.gridRadius = gridRadius
|
||
|
self.cellWidth = cellWidth
|
||
|
|
||
|
# Keep track of all AI objects added to the grid
|
||
|
self.gridObjects = {}
|
||
|
self.updateTaskStarted = 0
|
||
|
|
||
|
def delete(self):
|
||
|
DistributedNodeAI.delete(self)
|
||
|
self.stopUpdateGridTask()
|
||
|
|
||
|
def isGridParent(self):
|
||
|
# If this distributed object is a DistributedGrid return 1.
|
||
|
# 0 by default
|
||
|
return 1
|
||
|
|
||
|
def getCellWidth(self):
|
||
|
return self.cellWidth
|
||
|
|
||
|
def getParentingRules(self):
|
||
|
self.notify.debug("calling getter")
|
||
|
rule = ("%i%s%i%s%i" % (self.startingZone, self.RuleSeparator,
|
||
|
self.gridSize, self.RuleSeparator,
|
||
|
self.gridRadius))
|
||
|
return [self.style, rule]
|
||
|
|
||
|
# Reparent and setLocation on av to DistributedOceanGrid
|
||
|
def addObjectToGrid(self, av, useZoneId=-1, startAutoUpdate=True):
|
||
|
self.notify.debug("setting parent to grid %s" % self)
|
||
|
avId = av.doId
|
||
|
|
||
|
# Create a grid parent
|
||
|
#gridParent = self.attachNewNode("gridParent-%s" % avId)
|
||
|
#self.gridParents[avId] = gridParent
|
||
|
self.gridObjects[avId] = av
|
||
|
|
||
|
# Put the avatar on the grid
|
||
|
self.handleAvatarZoneChange(av, useZoneId)
|
||
|
|
||
|
if (not self.updateTaskStarted) and startAutoUpdate:
|
||
|
self.startUpdateGridTask()
|
||
|
|
||
|
def removeObjectFromGrid(self, av):
|
||
|
# TODO: WHAT LOCATION SHOULD WE SET THIS TO?
|
||
|
#av.wrtReparentTo(self.parentNP)
|
||
|
#av.setLocation(self.air.districtId, 1000)
|
||
|
|
||
|
# Remove grid parent for this av
|
||
|
avId = av.doId
|
||
|
if avId in self.gridObjects:
|
||
|
del self.gridObjects[avId]
|
||
|
|
||
|
# Stop task if there are no more av's being managed
|
||
|
if len(self.gridObjects) == 0:
|
||
|
self.stopUpdateGridTask()
|
||
|
|
||
|
#####################################################################
|
||
|
# updateGridTask
|
||
|
# This task is similar to the processVisibility task for the local client.
|
||
|
# A couple differences:
|
||
|
# - we are not doing setInterest on the AI (that is a local client
|
||
|
# specific call).
|
||
|
# - we assume that the moving objects on the grid are parented to a
|
||
|
# gridParent, and are broadcasting their position relative to that
|
||
|
# gridParent. This makes the task's math easy. Just check to see
|
||
|
# when our position goes out of the current grid cell. When it does,
|
||
|
# call handleAvatarZoneChange
|
||
|
|
||
|
def startUpdateGridTask(self):
|
||
|
self.stopUpdateGridTask()
|
||
|
self.updateTaskStarted = 1
|
||
|
taskMgr.add(self.updateGridTask, self.taskName("updateGridTask"))
|
||
|
|
||
|
def stopUpdateGridTask(self):
|
||
|
taskMgr.remove(self.taskName("updateGridTask"))
|
||
|
self.updateTaskStarted = 0
|
||
|
|
||
|
def updateGridTask(self, task=None):
|
||
|
# Run through all grid objects and update their parents if needed
|
||
|
missingObjs = []
|
||
|
for avId in self.gridObjects.keys():
|
||
|
av = self.gridObjects[avId]
|
||
|
# handle a missing object after it is already gone?
|
||
|
if (av.isEmpty()):
|
||
|
task.setDelay(1.0)
|
||
|
del self.gridObjects[avId]
|
||
|
continue
|
||
|
pos = av.getPos()
|
||
|
if ((pos[0] < 0 or pos[1] < 0) or
|
||
|
(pos[0] > self.cellWidth or pos[1] > self.cellWidth)):
|
||
|
# we are out of the bounds of this current cell
|
||
|
self.handleAvatarZoneChange(av)
|
||
|
# Do this every second, not every frame
|
||
|
if (task):
|
||
|
task.setDelay(1.0)
|
||
|
return Task.again
|
||
|
|
||
|
def handleAvatarZoneChange(self, av, useZoneId=-1):
|
||
|
# Calculate zone id
|
||
|
# Get position of av relative to this grid
|
||
|
if (useZoneId == -1):
|
||
|
pos = av.getPos(self)
|
||
|
zoneId = self.getZoneFromXYZ(pos)
|
||
|
else:
|
||
|
# zone already calculated, position of object might not
|
||
|
# give the correct zone
|
||
|
pos = None
|
||
|
zoneId = useZoneId
|
||
|
|
||
|
if not self.isValidZone(zoneId):
|
||
|
self.notify.warning(
|
||
|
"%s handleAvatarZoneChange %s: not a valid zone (%s) for pos %s" %(self.doId, av.doId, zoneId, pos))
|
||
|
return
|
||
|
|
||
|
# Set the location on the server.
|
||
|
# setLocation will update the gridParent
|
||
|
av.b_setLocation(self.doId, zoneId)
|
||
|
|
||
|
def handleSetLocation(self, av, parentId, zoneId):
|
||
|
pass
|
||
|
#if (av.parentId != parentId):
|
||
|
# parent changed, need to look up instance tree
|
||
|
# to see if avatar's named area location information
|
||
|
# changed
|
||
|
#av.requestRegionUpdateTask(regionegionUid)
|
||
|
|