Beispiel #1
0
 def addToon(self, toon):
     marker = NodePath('toon_marker-%i' % toon.doId)
     marker.reparentTo(self)
     self._getToonMarker(toon).copyTo(marker)
     marker.setColor(toon.style.getHeadColor())
     if toon.isLocal():
         marker.setScale(Globals.Gui.LocalMarkerScale)
         marker.setBin('fixed', 10)
     else:
         marker.setScale(Globals.Gui.MarkerScale)
         marker.setBin('fixed', 5)
     marker.flattenStrong()
     self._toonMarkers[toon] = marker
Beispiel #2
0
class CogdoMazeFactory:
    def __init__(self,
                 randomNumGen,
                 width,
                 height,
                 frameWallThickness=Globals.FrameWallThickness,
                 cogdoMazeData=CogdoMazeData):
        self._rng = RandomNumGen(randomNumGen)
        self.width = width
        self.height = height
        self.frameWallThickness = frameWallThickness
        self._cogdoMazeData = cogdoMazeData
        self.quadrantSize = self._cogdoMazeData.QuadrantSize
        self.cellWidth = self._cogdoMazeData.QuadrantCellWidth

    def getMazeData(self):
        if not hasattr(self, '_data'):
            self._generateMazeData()
        return self._data

    def createCogdoMaze(self, flattenModel=True):
        if not hasattr(self, '_maze'):
            self._loadAndBuildMazeModel(flatten=flattenModel)
        return CogdoMaze(self._model, self._data, self.cellWidth)

    def _gatherQuadrantData(self):
        self.openBarriers = []
        barrierItems = list(range(Globals.TotalBarriers))
        self._rng.shuffle(barrierItems)
        for i in barrierItems[0:len(barrierItems) - Globals.NumBarriers]:
            self.openBarriers.append(i)

        self.quadrantData = []
        quadrantKeys = list(self._cogdoMazeData.QuadrantCollisions.keys())
        self._rng.shuffle(quadrantKeys)
        i = 0
        for y in range(self.height):
            for x in range(self.width):
                key = quadrantKeys[i]
                collTable = self._cogdoMazeData.QuadrantCollisions[key]
                angle = self._cogdoMazeData.QuadrantAngles[self._rng.randint(
                    0,
                    len(self._cogdoMazeData.QuadrantAngles) - 1)]
                self.quadrantData.append((key, collTable[angle], angle))
                i += 1
                if x * y >= self._cogdoMazeData.NumQuadrants:
                    i = 0

    def _generateBarrierData(self):
        data = []
        for y in range(self.height):
            data.append([])
            for x in range(self.width):
                if x == self.width - 1:
                    ax = -1
                else:
                    ax = 1
                if y == self.height - 1:
                    ay = -1
                else:
                    ay = 1
                data[y].append([ax, ay])

        dirUp = 0
        dirDown = 1
        dirLeft = 2
        dirRight = 3

        def getAvailableDirections(ax, ay, ignore=None):
            dirs = []
            if ax - 1 >= 0 and data[ay][ax - 1][BARRIER_DATA_RIGHT] == 1 and (
                    ax, ay) != ignore:
                dirs.append(dirLeft)
            if ax + 1 < self.width and data[ay][ax][
                    BARRIER_DATA_RIGHT] == 1 and (ax, ay) != ignore:
                dirs.append(dirRight)
            if ay - 1 >= 0 and data[ay - 1][ax][BARRIER_DATA_TOP] == 1 and (
                    ax, ay) != ignore:
                dirs.append(dirDown)
            if ay + 1 < self.height and data[ay][ax][
                    BARRIER_DATA_TOP] == 1 and (ax, ay) != ignore:
                dirs.append(dirUp)
            return dirs

        visited = []

        def tryVisitNeighbor(ax, ay, ad):
            if ad == dirUp:
                if data[ay][ax] in visited:
                    return None
                visited.append(data[ay][ax])
                data[ay][ax][BARRIER_DATA_TOP] = 0
                ay += 1
            elif ad == dirDown:
                if data[ay - 1][ax] in visited:
                    return None
                visited.append(data[ay - 1][ax])
                data[ay - 1][ax][BARRIER_DATA_TOP] = 0
                ay -= 1
            elif ad == dirLeft:
                if data[ay][ax - 1] in visited:
                    return None
                visited.append(data[ay][ax - 1])
                data[ay][ax - 1][BARRIER_DATA_RIGHT] = 0
                ax -= 1
            elif ad == dirRight:
                if data[ay][ax] in visited:
                    return None
                visited.append(data[ay][ax])
                data[ay][ax][BARRIER_DATA_RIGHT] = 0
                ax += 1
            return (ax, ay)

        def openBarriers(x, y):
            dirs = getAvailableDirections(x, y)
            for dir in dirs:
                next = tryVisitNeighbor(x, y, dir)
                if next is not None:
                    openBarriers(*next)

            return

        x = self._rng.randint(0, self.width - 1)
        y = self._rng.randint(0, self.height - 1)
        openBarriers(x, y)
        self._barrierData = data
        return

    def _generateMazeData(self):
        if not hasattr(self, 'quadrantData'):
            self._gatherQuadrantData()
        self._data = {}
        self._data['width'] = (
            self.width +
            1) * self.frameWallThickness + self.width * self.quadrantSize
        self._data['height'] = (
            self.height +
            1) * self.frameWallThickness + self.height * self.quadrantSize
        self._data['originX'] = int(self._data['width'] / 2)
        self._data['originY'] = int(self._data['height'] / 2)
        collisionTable = []
        horizontalWall = [1 for x in range(self._data['width'])]
        collisionTable.append(horizontalWall)
        for i in range(0, len(self.quadrantData), self.width):
            for y in range(self.quadrantSize):
                row = [1]
                for x in range(i, i + self.width):
                    if x == 1 and y < self.quadrantSize / 2 - 2:
                        newData = []
                        for j in self.quadrantData[x][1][y]:
                            if j == 0:
                                newData.append(2)
                            else:
                                newData.append(j + 0)

                        row += newData + [1]
                    else:
                        row += self.quadrantData[x][1][y] + [1]

                collisionTable.append(row)

            collisionTable.append(horizontalWall[:])

        barriers = Globals.MazeBarriers
        for i in range(len(barriers)):
            for coords in barriers[i]:
                collisionTable[coords[1]][coords[0]] = 0

        y = self._data['originY']
        for x in range(len(collisionTable[y])):
            if collisionTable[y][x] == 0:
                collisionTable[y][x] = 2

        x = self._data['originX']
        for y in range(len(collisionTable)):
            if collisionTable[y][x] == 0:
                collisionTable[y][x] = 2

        self._data['collisionTable'] = collisionTable

    def _loadAndBuildMazeModel(self, flatten=False):
        self.getMazeData()
        self._model = NodePath('CogdoMazeModel')
        levelModel = CogdoUtil.loadMazeModel('level')
        self.quadrants = []
        quadrantUnitSize = int(self.quadrantSize * self.cellWidth)
        frameActualSize = self.frameWallThickness * self.cellWidth
        size = quadrantUnitSize + frameActualSize
        halfWidth = int(self.width / 2)
        halfHeight = int(self.height / 2)
        i = 0
        for y in range(self.height):
            for x in range(self.width):
                ax = (x - halfWidth) * size
                ay = (y - halfHeight) * size
                extension = ''
                if hasattr(getBase(), 'air'):
                    extension = '.bam'
                filepath = self.quadrantData[i][0] + extension
                angle = self.quadrantData[i][2]
                m = self._createQuadrant(filepath, i, angle, quadrantUnitSize)
                m.setPos(ax, ay, 0)
                m.reparentTo(self._model)
                self.quadrants.append(m)
                i += 1

        quadrantHalfUnitSize = quadrantUnitSize * 0.5
        barrierModel = CogdoUtil.loadMazeModel('grouping_blockerDivider').find(
            '**/divider')
        y = 3
        for x in range(self.width):
            if x == (self.width - 1) / 2:
                continue
            ax = (x - halfWidth) * size
            ay = (y - halfHeight) * size - quadrantHalfUnitSize - (
                self.cellWidth - 0.5)
            b = NodePath('barrier')
            barrierModel.instanceTo(b)
            b.setPos(ax, ay, 0)
            b.reparentTo(self._model)

        offset = self.cellWidth - 0.5
        for x in (0, 3):
            for y in range(self.height):
                ax = (
                    x - halfWidth
                ) * size - quadrantHalfUnitSize - frameActualSize + offset
                ay = (y - halfHeight) * size
                b = NodePath('barrier')
                barrierModel.instanceTo(b)
                b.setPos(ax, ay, 0)
                b.setH(90)
                b.reparentTo(self._model)

            offset -= 2.0

        barrierModel.removeNode()
        levelModel.getChildren().reparentTo(self._model)
        for np in self._model.findAllMatches('**/*lightCone*'):
            CogdoUtil.initializeLightCone(np, 'fixed', 3)

        if flatten:
            self._model.flattenStrong()
        return self._model

    def _createQuadrant(self, filepath, serialNum, angle, size):
        root = NodePath('QuadrantRoot-%i' % serialNum)
        quadrant = loader.loadModel(filepath)
        quadrant.getChildren().reparentTo(root)
        root.setH(angle)
        return root