Poodletooth-iLand/toontown/coghq/DistributedGridAI.py

250 lines
8.8 KiB
Python

from CrateGlobals import *
from otp.level import DistributedEntityAI
from direct.directnotify import DirectNotifyGlobal
class DistributedGridAI(DistributedEntityAI.DistributedEntityAI):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedGridAI')
def __init__(self, level, entId):
self.initialized = 0
DistributedEntityAI.DistributedEntityAI.__init__(self, level, entId)
self.activeCellList = []
def delete(self):
DistributedEntityAI.DistributedEntityAI.delete(self)
del self.activeCellList
def generate(self):
DistributedEntityAI.DistributedEntityAI.generate(self)
def initializeGrid(self):
if not self.initialized:
self.objPos = {}
self.gridCells = [None] * self.numRow
for i in xrange(len(self.gridCells)):
self.gridCells[i] = [None] * self.numCol
for j in xrange(len(self.gridCells[i])):
self.gridCells[i][j] = []
self.initialized = 1
return
def addActiveCell(self, cell):
self.activeCellList.append(cell)
def getObjPos(self, objId):
objPos = self.objPos.get(objId, None)
if objPos:
row, col = objPos
if row >= 0 and row < self.numRow and col >= 0 and col < self.numCol:
return [(col + 1) * self.cellSize, (row + 1) * self.cellSize, 0]
else:
self.notify.debug('row/col out of range %s/%s' % (row, col))
else:
self.notify.debug("didn't have record of obj")
return
def addObjectByPos(self, objId, pos, width = 1):
if not self.initialized:
self.initializeGrid()
if self.objPos.get(objId, None):
return 1
x, y = pos[0], pos[1]
col = min(int(x / self.cellSize), self.numCol - width)
row = min(int(y / self.cellSize), self.numRow - width)
self.notify.debug('attempt add %d at %s, row,col = %d,%d' % (objId,
pos,
row,
col))
while col >= 0 and col < self.numCol:
while row >= 0 and row < self.numRow:
if self.addObjectByRowCol(objId, row, col):
return 1
else:
row += 2
else:
row = 0
col += 2
else:
self.notify.debug('requestObjPos: row/col out of range %s/%s' % (row, col))
row = min(row, self.numRow)
row = max(0, row)
col = min(col, self.numRow)
col = max(0, col)
return self.addObjectByRowCol(objId, row, col)
return
def addObjectByRowCol(self, objId, row, col):
if row >= 0 and row < self.numRow - 1 and col >= 0 and col < self.numCol - 1:
self.notify.debug('adding obj %s to grid cell %s,%s' % (objId, row, col))
self.gridCells[row][col].append(objId)
self.gridCells[row + 1][col].append(objId)
self.gridCells[row][col + 1].append(objId)
self.gridCells[row + 1][col + 1].append(objId)
self.objPos[objId] = [row, col]
self.__setChangedActiveCells(onList=[[row, col],
[row + 1, col],
[row, col + 1],
[row + 1, col + 1]], objId=objId)
return 1
self.notify.debug("couldn't obj to grid cell %s,%s" % (row, col))
return 0
def removeObject(self, objId):
objPos = self.objPos.get(objId)
if not objPos:
return
row, col = objPos
self.notify.debug('removing obj %s from %s, %s' % (objId, row, col))
self.gridCells[row][col].remove(objId)
self.gridCells[row + 1][col].remove(objId)
self.gridCells[row][col + 1].remove(objId)
self.gridCells[row + 1][col + 1].remove(objId)
del self.objPos[objId]
self.__setChangedActiveCells(offList=[[row, col],
[row + 1, col],
[row, col + 1],
[row + 1, col + 1]], objId=objId)
def checkMoveDir(self, objId, h):
if h > 225 and h < 315:
return self.checkMove(objId, 0, 1)
elif h > 45 and h < 135:
return self.checkMove(objId, 0, -1)
elif h < 45 or h > 315:
return self.checkMove(objId, 1, 0)
elif h > 135 and h < 225:
return self.checkMove(objId, -1, 0)
def doMoveDir(self, objId, h):
if h > 225 and h < 315:
return self.doMove(objId, 0, 1)
elif h > 45 and h < 135:
return self.doMove(objId, 0, -1)
elif h < 45 or h > 315:
return self.doMove(objId, 1, 0)
elif h > 135 and h < 225:
return self.doMove(objId, -1, 0)
def checkPush(self, objId, side):
if side == 0:
return self.checkMove(objId, 0, -1)
elif side == 1:
return self.checkMove(objId, 0, 1)
elif side == 2:
return self.checkMove(objId, -1, 0)
elif side == 3:
return self.checkMove(objId, 1, 0)
def doPush(self, objId, side):
if side == 0:
return self.doMove(objId, 0, -1)
elif side == 1:
return self.doMove(objId, 0, 1)
elif side == 2:
return self.doMove(objId, -1, 0)
elif side == 3:
return self.doMove(objId, 1, 0)
def checkMove(self, objId, dRow, dCol):
objPos = self.objPos.get(objId)
if not objPos:
return
row, col = objPos
validMove = 1
if dRow < 0:
validMove = validMove & self.__isEmpty(row - 1, col) & self.__isEmpty(row - 1, col + 1)
elif dRow > 0:
validMove = validMove & self.__isEmpty(row + 2, col) & self.__isEmpty(row + 2, col + 1)
if dCol < 0:
validMove = validMove & self.__isEmpty(row, col - 1) & self.__isEmpty(row + 1, col - 1)
elif dCol > 0:
validMove = validMove & self.__isEmpty(row, col + 2) & self.__isEmpty(row + 1, col + 2)
return validMove
def doMove(self, objId, dRow, dCol):
objPos = self.objPos.get(objId)
if not objPos:
return 0
row, col = objPos
validMove = self.checkMove(objId, dRow, dCol)
if validMove:
self.gridCells[row][col].remove(objId)
self.gridCells[row + 1][col].remove(objId)
self.gridCells[row][col + 1].remove(objId)
self.gridCells[row + 1][col + 1].remove(objId)
newRow = row + dRow
newCol = col + dCol
self.gridCells[newRow][newCol].append(objId)
self.gridCells[newRow + 1][newCol].append(objId)
self.gridCells[newRow][newCol + 1].append(objId)
self.gridCells[newRow + 1][newCol + 1].append(objId)
self.objPos[objId] = [newRow, newCol]
self.updateActiveCells(objId, row, col, dRow, dCol)
return validMove
def updateActiveCells(self, objId, row, col, dRow, dCol):
newRow = row + dRow
newCol = col + dCol
newCells = [[newRow, newCol],
[newRow + 1, newCol],
[newRow, newCol + 1],
[newRow + 1, newCol + 1]]
oldCells = [[row, col],
[row + 1, col],
[row, col + 1],
[row + 1, col + 1]]
onList = []
offList = []
for cell in newCells:
if cell not in oldCells:
onList.append(cell)
for cell in oldCells:
if cell not in newCells:
offList.append(cell)
self.__setChangedActiveCells(onList, offList, objId)
def __setChangedActiveCells(self, onList = [], offList = [], objId = None):
for cell in self.activeCellList:
self.notify.debug('onList = %s, offList = %s, cell = %s' % (onList, offList, cell.getRowCol()))
if cell.getRowCol() in onList:
cell.b_setState(1, objId)
elif cell.getRowCol() in offList:
cell.b_setState(0, objId)
def __isEmpty(self, row, col):
if row < 0 or row >= self.numRow or col < 0 or col >= self.numCol:
return 0
if len(self.gridCells[row][col]) > 0:
return 0
return 1
def printGrid(self):
if not __debug__:
return
for i in xrange(len(self.gridCells)):
str = ''
for j in xrange(len(self.gridCells[i])):
col = self.gridCells[i][j]
active = 0
for cell in self.activeCellList:
if cell.getRowCol() == [i, j]:
active = 1
if len(col) > 0:
if active:
str += '[X]'
else:
str += ' X '
elif active:
str += '[.]'
else:
str += ' . '
print str + ' : %d' % i
print ''