class Block( object ): def __init__(self, blockType, position, owner, damage, seed, baseColor ): """ """ from blockType import BlockType from player import Player from pandac.PandaModules import Vec3 if not isinstance( blockType, BlockType ): raise TypeError( blockType ) if not isinstance( owner, Player ): raise TypeError( owner ) if not isinstance( position, Vec3 ): raise TypeError( position ) if not isinstance( damage, int ): raise TypeError( damage ) if not isinstance( seed, int ): raise TypeError( seed ) if not isinstance( baseColor, tuple ): raise TypeError( baseColor ) super(Block, self).__init__() self.identifier = blockType.identifier self.blockType = blockType self.position = position self.damage = damage self.owner = owner self.seed = seed self.baseColor = baseColor return None def damage(self, amount): """ """ # Abuse the fact that int rounds down? self.damage += int( amount / self.blockType.rate ) if self.damage > self.blockType.durability: return self.destroy() else: return self.damage def create(self, environment ): return self.load( environment ) def load(self, environment): """Add the block to the world. Do the actual construction of the model when necessary and add it to the environment (should actually be a chunk).""" if self.blockType.name == 'air': return None self.cube = NodePath('cube') model = self.blockType.getModel() model.instanceTo( self.cube ) self.cube.setPos( self.position ) self.cube.reparentTo( environment ) return self def unload( self ): ''' ''' self.cube.detachNode() return None def destroy(self): """See what items should be dropped, remove the block from the world, and handle everything else that should happens when a block breaks.""" raise NotImplementedError
class BaseBlock( BlockIF ): ''' ''' def __init__(self, blockType, position, owner, damage, seed): ''' ''' if not isinstance( blockType, BlockType ): raise TypeError( blockType ) if not isinstance( owner, Player ): raise TypeError( owner ) if not isinstance( position, Vec3 ): raise TypeError( position ) if not isinstance( damage, int ): raise TypeError( damage ) if not isinstance( seed, int ): raise TypeError( seed ) super(BaseBlock, self).__init__() self.identifier = blockType.identifier self.blockType = blockType self.position = position self.damage = damage self.owner = owner self.seed = seed return None def create( self, environment ): return self.load( environment ) def load( self, environment ): ''' ''' self.cube = NodePath('cube') model = self.blockType.getModel() model.instanceTo( self.cube ) self.cube.setPos( self.position ) self.cube.reparentTo( environment ) return self def unload( self ): ''' ''' self.cube.detachNode() return None
class RepairGridPiece(DirectButton, FSM.FSM): def __init__(self, name, parent, allWoodSquaresGeom, selectedOutlineGeom, command, location, **kw): optiondefs = () self.defineoptions(kw, optiondefs) DirectButton.__init__(self, parent, **None) self.initialiseoptions(RepairGridPiece) FSM.FSM.__init__(self, 'RepairGridPiece_%sFSM' % name) self.name = name self.allWoodSquaresGeom = allWoodSquaresGeom self.selectedOutlineGeom = selectedOutlineGeom self.command = command self.location = location self._initVars() self._initGUI() self._initIntervals() self.accept(self.guiItem.getEnterEvent(), self.onMouseEnter) self.accept(self.guiItem.getExitEvent(), self.onMouseExit) self.bind(DGG.B1PRESS, self.onMouseDown) self.bind(DGG.B1RELEASE, self.onMouseUp) self.bind(DGG.B2PRESS, self.onMouseUp) self.bind(DGG.B2RELEASE, self.onMouseUp) self.bind(DGG.B3PRESS, self.onMouseUp) self.bind(DGG.B3RELEASE, self.onMouseUp) self.idleGeom = NodePath('idleGeom') self.highlightedGeom = NodePath('highlightedGeom') self.haveMoved = False self.grabPoint = None self.setType(GOAL_NONE) def _initVars(self): self.pieceType = GOAL_NONE self.enabled = True self.isMouseDown = False self.isMouseInButton = False def _initGUI(self): self.selectedOutlineGeom.reparentTo(self) self.selectedOutlineGeom.hide() self.selectedOutlineGeom.setBin('fixed', 38) def _initIntervals(self): self.moveInterval = LerpPosInterval( self, duration=RepairGlobals.Bracing.moveTime, pos=self.getPos(), name='RepairGridPiece_%s.moveInterval' % self.name) def destroy(self): taskMgr.remove(self.uniqueName('RepairGridPiece.updateTask')) taskMgr.remove(DGG.B1PRESS) taskMgr.remove(DGG.B1RELEASE) taskMgr.remove(DGG.B2PRESS) taskMgr.remove(DGG.B2RELEASE) taskMgr.remove(DGG.B3PRESS) taskMgr.remove(DGG.B3RELEASE) self.idleGeom.detachNode() self.idleGeom = None self.highlightedGeom.detachNode() self.highlightedGeom = None self.ignore(self.guiItem.getEnterEvent()) self.ignore(self.guiItem.getExitEvent()) self.moveInterval.clearToInitial() del self.moveInterval DirectFrame.destroy(self) self.clearPiece() self.allWoodSquaresGeom.removeNode() del self.allWoodSquaresGeom def setGeomState(self, state): if state == 'idle': self.idleGeom.show() self.highlightedGeom.hide() elif state == 'highlighted': self.highlightedGeom.show() self.idleGeom.hide() def onMouseEnter(self, event): self.isMouseInButton = True if self.isMouseDown: self.setGeomState('idle') else: self.setGeomState('highlighted') def onMouseExit(self, event): self.isMouseInButton = False self.setGeomState('idle') def onMouseDown(self, event): if self.isMouseInButton: self.selectedOutlineGeom.show() self.setGeomState('idle') self.isMouseDown = True self.haveMoved = False screenx = base.mouseWatcherNode.getMouseX() screeny = base.mouseWatcherNode.getMouseY() self.grabPoint = aspect2d.getRelativePoint(render2d, (screenx, 0, screeny)) taskMgr.add(self.updateTask, self.uniqueName('RepairGridPiece.updateTask'), extraArgs=[]) def onMouseUp(self, event): if self.isMouseDown: self.isMouseDown = False if not self.haveMoved: self.checkMovePiece(True) self.grabPoint = None if self.isMouseInButton: self.setGeomState('highlighted') else: self.setGeomState('idle') self.selectedOutlineGeom.hide() taskMgr.remove(self.uniqueName('RepairGridPiece.updateTask')) def onMoveButtonPressed(self, dir1, dir2): if not self.moveInterval.isPlaying(): self.haveMoved = True args = self.location[:] args.append((dir1, dir2)) return self.command(*args) def updateTask(self): if not (self.isMouseInButton) and not self.moveInterval.isPlaying(): self.checkMovePiece() return Task.cont def checkMovePiece(self, isPush=False): directions = [(0, 1), (0, -1), (-1, 0), (1, 0)] if self.grabPoint is None: self.grabPoint = self.getPos(aspect2d) screenx = base.mouseWatcherNode.getMouseX() screeny = base.mouseWatcherNode.getMouseY() cursorPos = aspect2d.getRelativePoint(render2d, (screenx, 0, screeny)) diff = self.grabPoint - cursorPos absX = math.fabs(diff.getX()) absZ = math.fabs(diff.getZ()) moveDirection = None if isPush: threshold = RepairGlobals.Bracing.pushPieceThreshold else: threshold = RepairGlobals.Bracing.movePieceThreshold if absZ > absX and diff.getZ() > 0.0 and absZ > threshold: moveDirection = directions[1] elif absZ > absX and diff.getZ() < 0.0 and absZ > threshold: moveDirection = directions[0] elif absX > absZ and diff.getX() > 0.0 and absX > threshold: moveDirection = directions[2] elif absX > absZ and diff.getX() < 0.0 and absX > threshold: moveDirection = directions[3] if moveDirection: if self.onMoveButtonPressed( *moveDirection) and self.grabPoint is not None: self.grabPoint += VBase3(SPACING * moveDirection[0], 0.0, SPACING * moveDirection[1]) def setType(self, type): self.pieceType = type activeWoodSquareGeom = self.allWoodSquaresGeom.find( '**/%s' % GOAL_TO_TEXTURE[type]) self.idleGeom.detachNode() self.idleGeom = None self.highlightedGeom.detachNode() self.highlightedGeom = None self.idleGeom = NodePath('idleGeom') self.highlightedGeom = NodePath('highlightedGeom') self.idleGeom.reparentTo(self) self.highlightedGeom.reparentTo(self) if activeWoodSquareGeom.isEmpty(): self.stash() else: activeWoodSquareGeom.find('**/idle').copyTo(self.idleGeom) activeWoodSquareGeom.find('**/over').copyTo(self.highlightedGeom) self.setGeomState('idle') self.unstash() def setEnabled(self, enabled): self.onMouseUp(None) self.enabled = enabled if not enabled: self['state'] = DGG.DISABLED else: self['state'] = DGG.NORMAL def isGoalPiece(self): if self.pieceType != GOAL_NONE: pass return self.pieceType != GOAL_EMPTY def isEmptyPiece(self): return self.pieceType == GOAL_EMPTY def setGridLocation(self, location, pos): self.location = location self.setPos(pos) def enterIdle(self): self.stash() self.setEnabled(False) def exitIdle(self): self.unstash() def enterBlank(self): self.setType(GOAL_NONE) def exitBlank(self): self.unstash() def enterGoal(self, pieceType): self.setType(pieceType) def exitGoal(self): self.unstash() def enterEmpty(self): self.setEnabled(False) self.setType(GOAL_EMPTY) def exitEmpty(self): self.unstash()
class cameraRotationClass( DirectObject ): enabled = False def __init__( self ): # disable the default camera control base.disableMouse() # create the aiming cross cm = CardMaker('aim-cross') cm.setFrame(-AIMCROSSWIDTH,AIMCROSSWIDTH,-AIMCROSSHEIGHT,AIMCROSSHEIGHT) cross = cm.generate() self.aimingCross = NodePath(cross) # set texture to cross tex = loader.loadTexture(CROSSTEXTURE) self.aimingCross.setTexture(tex) # enable transparency on the aiming cross self.aimingCross.setTransparency(TransparencyAttrib.MAlpha) self.aimingCross.detachNode() # enable this class functions self.enable() self.accept( 'space', self.toggle ) def toggle( self ): if self.enabled: self.disable() else: self.enable() def enable( self ): ''' enable first person camera rotation by mouse and bind/hide the mouse ''' # the mouse is not centered self.mouseCentered = False # enable the mouse rotation task taskMgr.add(self.rotationTask, 'cameraRotationTask') # hide mouse cursor wp = WindowProperties() wp.setCursorHidden(True) # does not exist panda 1.3.2 / but is reqired for osx-mouse movement try: wp.setMouseMode(WindowProperties.MRelative) except: pass base.win.requestProperties(wp) # add the cross to the window self.aimingCross.reparentTo( render2d ) self.enabled = True def disable( self ): ''' disable first person camera rotation of mouse and free/show the mouse ''' self.rotationSpeed = 0 # disable the mouse rotation task taskMgr.remove('cameraRotationTask') # show mouse cursor wp = WindowProperties() wp.setCursorHidden(False) # does not exist panda 1.3.2 / but is reqired for osx-mouse movement try: wp.setMouseMode(WindowProperties.MAbsolute) except: pass base.win.requestProperties(wp) # remove the cross from the window self.aimingCross.detachNode() self.enabled = False def setMouseCentered( self, task=None ): # reset mouse position to the center of the window base.win.movePointer(0, base.win.getXSize()/2, base.win.getYSize()/2) def rotationTask( self, task ): # if we can find a mouse if base.mouseWatcherNode.hasMouse(): # we want to center the mouse on the first frame if not self.mouseCentered: self.setMouseCentered() self.mouseCentered = True else: # get mouse position mpos = base.mouseWatcherNode.getMouse() x, y = mpos.getX(), mpos.getY() if x!=0 or y!=0: # reset mouse position to the center of the window self.setMouseCentered() # calculate movement force rotationSpeed = ROTATIONSPEED # * globalClock.getDt() # get current rotation currentHpr = base.camera.getHpr() # add up and down limit for camera h = currentHpr.getX() - x * rotationSpeed p = currentHpr.getY() + max( min( rotationSpeed*y, UPCAMERALIMIT), DOWNCAMERALIMIT) # add new rotation (mouse movement) to existing one base.camera.setHpr( render, h, p, 0) else: print "camera.cameraRotation.mouseControlTask no mouse found" return Task.cont
class MoveCursor(object): _EDGES = 40 _zPos = 0 _movingUp = False _movingDown = False _color = Vec4(0.3, 0.3, 0.8, 1) _currentPos = Vec3(0, 0, 0) def __init__(self, parent, entity, foot=1): # We keep a reference to the entity self.entity = entity # Setup the components of the cursor self._moveRadCircleNP = NodePath("Movement Radius Node") self._moveLine = LineSegs() self._moveLineNP = NodePath("Movement Direction Line Node") self._moveZLine = LineSegs() self._moveZLineNP = NodePath("Movement Z Line Node") self._moveZFootNP = NodePath("Movement Z Foot Node") self._moveFootCircle = LineSegs() self._moveFootCircleNP = NodePath("Movement Foot Circle Node") self._np = NodePath("Movement Node") self.aaLevel = 16 self.parent = parent self.start = Vec3(0, 0, 0) self.moveRad = entity.moveRadius self.footRad = foot self.plane = Plane(Vec3(0, 0, 1), Point3(0, 0, 0)) if self.aaLevel > 0: self._np.setAntialias(AntialiasAttrib.MLine, self.aaLevel) x = 0 y = 0 z = 0 # Draw movement radius moveRadLine = LineSegs() moveRadLine.setThickness(1) moveRadLine.setColor(self._color) moveRadLine.moveTo(self.moveRad, 0, 0) for i in range(self._EDGES + 1): newX = (self.moveRad * math.cos((2*math.pi/self._EDGES)*i)) newY = (self.moveRad * math.sin((2*math.pi/self._EDGES)*i)) moveRadLine.drawTo(newX, newY, 0) moveRadGeom = moveRadLine.create() self._moveRadCircleNP = NodePath(moveRadGeom) self._moveRadCircleNP.reparentTo(self._np) # Draw movement foot circle self._moveFootCircle.setThickness(1) self._moveFootCircle.setColor(self._color) self._moveFootCircle.moveTo(self.footRad, 0, 0) for i in range(self._EDGES): newX = (self.footRad * math.cos((2*math.pi/self._EDGES)*i)) newY = (self.footRad * math.sin((2*math.pi/self._EDGES)*i)) self._moveFootCircle.drawTo(newX, newY, 0) self._moveFootCircle.drawTo(self.footRad, 0, 0) moveFootCircleGeom = self._moveFootCircle.create() self._moveFootCircleNP = NodePath(moveFootCircleGeom) self._moveFootCircleNP.reparentTo(self._np) # Draw movement direction line self._moveLine.setThickness(1) self._moveLine.setColor(self._color) self._moveLine.moveTo(0, 0, 0) self._moveLine.drawTo(x, y, z) self.moveLineGO = self._moveLine.create(True) self._moveLineNP = NodePath(self.moveLineGO) self._moveLineNP.reparentTo(self._np) def updateMovePos(self, Task): # endPos must be transformed in the the coord sys of the model m_pos = self.getMouseXY() if m_pos is not None: # Transform current mouse pos endPos = self.parent.getRelativePoint(render, m_pos) # Adjust Z coord if needed if self._movingUp: self._zPos += 0.1 elif self._movingDown: self._zPos -= 0.1 endPos.setZ(self._zPos) # Check if we're trying to move too far, if not update pos dist = math.sqrt(endPos.getX()**2 + endPos.getY()**2 + 2*(endPos.getZ()**2)) if dist <= self.moveRad: self._moveLine.setVertex(1, endPos) self._moveFootCircleNP.setPos(endPos) #self._currentPos = self.parent.getRelativePoint(self.parent, endPos) #print("endPos=%s"%endPos) #print("myRelPos=%s"%self._currentPos) self._currentPos = endPos return Task.cont def getMouseXY(self): # NOTE - this returns the mouse pos in the ships coord sys if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() pos3d = Point3() nearPoint = Point3() farPoint = Point3() base.camLens.extrude(mpos, nearPoint, farPoint) if self.plane.intersectsLine(pos3d, render.getRelativePoint(camera, nearPoint), render.getRelativePoint(camera, farPoint)): return pos3d return None def getPosition(self): return self._currentPos def startDrawing(self): self._np.reparentTo(self.parent) taskMgr.add(self.updateMovePos, 'Movement Indicator Update Task') def stopDrawing(self): taskMgr.remove('Movement Indicator Update Task') self._np.detachNode()
class CogdoFlyingGuiManager: def __init__(self, player): self.player = player self.root = NodePath("CogdoFlyingGui") self.root.reparentTo(aspect2d) self.fuelMeter = NodePath("scrubMeter") self.fuelMeter.reparentTo(self.root) self.fuelMeter.setPos(1.1, 0.0, -0.7) self.fuelMeter.setSz(2.0) cm = CardMaker('card') cm.setFrame(-0.07, 0.07, 0.0, 0.75) self.fuelMeterBar = self.fuelMeter.attachNewNode(cm.generate()) self.fuelMeterBar.setColor(0.95, 0.95, 0.0, 1.0) self.fuelLabel = DirectLabel( parent=self.root, relief=None, pos=(1.1, 0, -0.8), scale=0.075, text="Fuel", text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_font=ToontownGlobals.getInterfaceFont(), ) self.messageLabel = DirectLabel( parent=self.root, relief=None, pos=(0.0, 0.0, -0.9), scale=0.1, text=" ", text_align=TextNode.ACenter, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_font=ToontownGlobals.getInterfaceFont(), textMayChange=1, ) self.messageLabel.stash() self.winLabel = DirectLabel( parent=self.root, relief=None, pos=(0.0, 0.0, 0.0), scale=0.25, text="You win!", text_align=TextNode.ACenter, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_font=ToontownGlobals.getInterfaceFont(), ) self.winLabel.stash() self.refuelLerp = LerpFunctionInterval(self.fuelMeterBar.setSz, fromData=0.0, toData=1.0, duration=2.0) def setRefuelLerpFromData(self): startScale = self.fuelMeterBar.getSz() self.refuelLerp.fromData = startScale def setMessageLabelText(self, text): self.messageLabel["text"] = text self.messageLabel.setText() def update(self): self.fuelMeterBar.setSz(self.player.fuel) def destroy(self): # print "Destroying GUI" self.fuelMeterBar.detachNode() self.fuelMeterBar = None self.fuelLabel.detachNode() self.fuelLabel = None self.fuelMeter.detachNode() self.fuelMeter = None self.winLabel.detachNode() self.winLabel = None self.root.detachNode() self.root = None self.player = None
class CogdoFlyingGame(DirectObject): UPDATE_TASK_NAME = "CogdoFlyingGameUpdate" GAME_COMPLETE_TASK_NAME = "CogdoFlyingGameCompleteTask" def __init__(self, distGame): self.distGame = distGame # Unused currently self.players = {} self.localPlayer = CogdoFlyingLocalPlayer(self, base.localAvatar) # Unused currently self.toonDropShadows = [] self.startPlatform = None # self.currentPlatform = None self.endPlatform = None self.fuelPlatforms = {} self.isGameComplete = False self.upLimit = 0.0 self.downLimit = 0.0 self.leftLimit = 0.0 self.rightLimit = 0.0 def load(self): self.root = NodePath('root') self.root.reparentTo(render) self.root.stash() self.world = loadMockup("cogdominium/mockup.egg") self.world.reparentTo(self.root) self.world.stash() # Setup and placement of starting platform self.startPlatform = loadMockup("cogdominium/start_platform.egg") startPlatformLoc = self.world.find("**/start_platform_loc") self.startPlatform.reparentTo(startPlatformLoc) colModel = self.startPlatform.find("**/col_floor") colModel.setTag('start_platform', '%s' % base.localAvatar.doId) # Here we set the current platform for the local player self.localPlayer.setCheckpointPlatform(self.startPlatform) # Setup and placement of the end platform self.endPlatform = loadMockup("cogdominium/end_platform.egg") endPlatformLoc = self.world.find("**/end_platform_loc") self.endPlatform.reparentTo(endPlatformLoc) colModel = self.endPlatform.find("**/col_floor") colModel.setTag('end_platform', '%s' % base.localAvatar.doId) # Setup and placement for all the fuel platforms fuelPlatformModel = loadMockup("cogdominium/fuel_platform.egg") fuelIndex = 1 fuelLoc = self.world.find('**/fuel_platform_loc_%d' % fuelIndex) while not fuelLoc.isEmpty(): fuelModel = NodePath("fuel_platform_%d" % fuelIndex) fuelPlatformModel.copyTo(fuelModel) fuelModel.reparentTo(fuelLoc) colModel = fuelModel.find("**/col_floor") colModel.setTag('fuel_platform', '%s' % base.localAvatar.doId) colModel.setTag('isUsed', '%s' % 0) self.fuelPlatforms[fuelModel.getName()] = fuelModel fuelIndex += 1 fuelLoc = self.world.find('**/fuel_platform_loc_%d' % fuelIndex) self.accept("entercol_floor", self.handleCollision) self.skybox = self.world.find("**/skybox") self.upLimit = self.world.find("**/limit_up").getPos(render).getZ() self.downLimit = self.world.find("**/limit_down").getPos(render).getZ() self.leftLimit = self.world.find("**/limit_left").getPos(render).getX() self.rightLimit = self.world.find("**/limit_right").getPos( render).getX() del fuelPlatformModel self._initFog() def unload(self): self.__stopUpdateTask() self.__stopGameCompleteTask() self._destroyFog() # print "Unload Flying CogdoGame" self.localPlayer.unload() del self.localPlayer self.fuelPlatforms.clear() self.endPlatform = None self.world.detachNode() del self.world self.root.detachNode() del self.root self.ignore("entercol_floor") def handleCollision(self, collEntry): fromNodePath = collEntry.getFromNodePath() intoNodePath = collEntry.getIntoNodePath() intoName = intoNodePath.getName() fromName = fromNodePath.getName() if intoNodePath.getTag('fuel_platform') != "": if not int( intoNodePath.getTag('isUsed') ) or CogdoFlyingGameGlobals.FlyingGame.MULTIPLE_REFUELS_PER_STATION: intoNodePath.setTag('isUsed', '%s' % 1) self.localPlayer.setCheckpointPlatform( intoNodePath.getParent()) self.localPlayer.request("Refuel") if intoNodePath.getTag('end_platform') != "": self.localPlayer.request("WaitingForWin") def enable(self): self.localPlayer.request("FreeFly") self.__startUpdateTask() self.isGameComplete = False def disable(self): self.__stopUpdateTask() self.__stopGameCompleteTask() self.localPlayer.request("Inactive") def _initFog(self): self.fog = Fog("FlyingFog") self.fog.setColor(VBase4(0.8, 0.8, 0.8, 1.0)) self.fog.setLinearRange(100.0, 400.0) self._renderFog = render.getFog() render.setFog(self.fog) def _destroyFog(self): render.clearFog() del self.fog del self._renderFog def onstage(self): self.root.unstash() self.world.unstash() self.localPlayer.onstage() def offstage(self): self.__stopUpdateTask() self.world.stash() self.root.stash() self.localPlayer.offstage() #TODO: Temp solution, this is supposed to come from the minigame # Which means the minigame isn't getting cleaned up properly look into this self.unload() def handleToonJoined(self, toon): # Not used, no multiplayer support in yet if toon == base.localAvatar: player = CogdoFlyingLocalPlayer(toon) player.entersActivity() self.localPlayer = player else: player = CogdoFlyingPlayer(toon) player.entersActivity() self.players[toon.doId] = player def __startUpdateTask(self): self.__stopUpdateTask() taskMgr.add(self.__updateTask, CogdoFlyingGame.UPDATE_TASK_NAME, 45) def __stopUpdateTask(self): taskMgr.remove(CogdoFlyingGame.UPDATE_TASK_NAME) def __stopGameCompleteTask(self): taskMgr.remove(CogdoFlyingGame.GAME_COMPLETE_TASK_NAME) def gameComplete(self): self.localPlayer.request("Win") def __updateTask(self, task): self.localPlayer.update() #TODO:flying: make this win condition stuff work for multiple toons if self.localPlayer.state == "WaitingForWin" and not self.isGameComplete: self.isGameComplete = True taskMgr.doMethodLater(6.0, self.gameComplete, CogdoFlyingGame.GAME_COMPLETE_TASK_NAME, extraArgs=[]) self.skybox.setPos(self.skybox.getPos().getX(), self.localPlayer.toon.getPos().getY(), self.skybox.getPos().getZ()) return Task.cont
class RepairGridPiece(DirectButton, FSM.FSM): def __init__(self, name, parent, allWoodSquaresGeom, selectedOutlineGeom, command, location, **kw): optiondefs = () self.defineoptions(kw, optiondefs) DirectButton.__init__(self, parent) self.initialiseoptions(RepairGridPiece) FSM.FSM.__init__(self, 'RepairGridPiece_%sFSM' % name) self.name = name self.allWoodSquaresGeom = allWoodSquaresGeom self.selectedOutlineGeom = selectedOutlineGeom self.command = command self.location = location self._initVars() self._initGUI() self._initIntervals() self.accept(self.guiItem.getEnterEvent(), self.onMouseEnter) self.accept(self.guiItem.getExitEvent(), self.onMouseExit) self.bind(DGG.B1PRESS, self.onMouseDown) self.bind(DGG.B1RELEASE, self.onMouseUp) self.bind(DGG.B2PRESS, self.onMouseUp) self.bind(DGG.B2RELEASE, self.onMouseUp) self.bind(DGG.B3PRESS, self.onMouseUp) self.bind(DGG.B3RELEASE, self.onMouseUp) self.idleGeom = NodePath('idleGeom') self.highlightedGeom = NodePath('highlightedGeom') self.haveMoved = False self.grabPoint = None self.setType(GOAL_NONE) def _initVars(self): self.pieceType = GOAL_NONE self.enabled = True self.isMouseDown = False self.isMouseInButton = False def _initGUI(self): self.selectedOutlineGeom.reparentTo(self) self.selectedOutlineGeom.hide() self.selectedOutlineGeom.setBin('fixed', 38) def _initIntervals(self): self.moveInterval = LerpPosInterval(self, duration = RepairGlobals.Bracing.moveTime, pos = self.getPos(), name = 'RepairGridPiece_%s.moveInterval' % self.name) def destroy(self): taskMgr.remove(self.uniqueName('RepairGridPiece.updateTask')) taskMgr.remove(DGG.B1PRESS) taskMgr.remove(DGG.B1RELEASE) taskMgr.remove(DGG.B2PRESS) taskMgr.remove(DGG.B2RELEASE) taskMgr.remove(DGG.B3PRESS) taskMgr.remove(DGG.B3RELEASE) self.idleGeom.detachNode() self.idleGeom = None self.highlightedGeom.detachNode() self.highlightedGeom = None self.ignore(self.guiItem.getEnterEvent()) self.ignore(self.guiItem.getExitEvent()) self.moveInterval.clearToInitial() del self.moveInterval DirectFrame.destroy(self) self.clearPiece() self.allWoodSquaresGeom.removeNode() del self.allWoodSquaresGeom def setGeomState(self, state): if state == 'idle': self.idleGeom.show() self.highlightedGeom.hide() elif state == 'highlighted': self.highlightedGeom.show() self.idleGeom.hide() def onMouseEnter(self, event): self.isMouseInButton = True if self.isMouseDown: self.setGeomState('idle') else: self.setGeomState('highlighted') def onMouseExit(self, event): self.isMouseInButton = False self.setGeomState('idle') def onMouseDown(self, event): if self.isMouseInButton: self.selectedOutlineGeom.show() self.setGeomState('idle') self.isMouseDown = True self.haveMoved = False screenx = base.mouseWatcherNode.getMouseX() screeny = base.mouseWatcherNode.getMouseY() self.grabPoint = aspect2d.getRelativePoint(render2d, (screenx, 0, screeny)) taskMgr.add(self.updateTask, self.uniqueName('RepairGridPiece.updateTask'), extraArgs = []) def onMouseUp(self, event): if self.isMouseDown: self.isMouseDown = False if not self.haveMoved: self.checkMovePiece(True) self.grabPoint = None if self.isMouseInButton: self.setGeomState('highlighted') else: self.setGeomState('idle') self.selectedOutlineGeom.hide() taskMgr.remove(self.uniqueName('RepairGridPiece.updateTask')) def onMoveButtonPressed(self, dir1, dir2): if not self.moveInterval.isPlaying(): self.haveMoved = True args = self.location[:] args.append((dir1, dir2)) return self.command(*args) def updateTask(self): if not (self.isMouseInButton) and not self.moveInterval.isPlaying(): self.checkMovePiece() return Task.cont def checkMovePiece(self, isPush = False): directions = [ (0, 1), (0, -1), (-1, 0), (1, 0)] if self.grabPoint is None: self.grabPoint = self.getPos(aspect2d) screenx = base.mouseWatcherNode.getMouseX() screeny = base.mouseWatcherNode.getMouseY() cursorPos = aspect2d.getRelativePoint(render2d, (screenx, 0, screeny)) diff = self.grabPoint - cursorPos absX = math.fabs(diff.getX()) absZ = math.fabs(diff.getZ()) moveDirection = None if isPush: threshold = RepairGlobals.Bracing.pushPieceThreshold else: threshold = RepairGlobals.Bracing.movePieceThreshold if absZ > absX and diff.getZ() > 0.0 and absZ > threshold: moveDirection = directions[1] elif absZ > absX and diff.getZ() < 0.0 and absZ > threshold: moveDirection = directions[0] elif absX > absZ and diff.getX() > 0.0 and absX > threshold: moveDirection = directions[2] elif absX > absZ and diff.getX() < 0.0 and absX > threshold: moveDirection = directions[3] if moveDirection: if self.onMoveButtonPressed(*moveDirection) and self.grabPoint is not None: self.grabPoint += VBase3(SPACING * moveDirection[0], 0.0, SPACING * moveDirection[1]) def setType(self, type): self.pieceType = type activeWoodSquareGeom = self.allWoodSquaresGeom.find('**/%s' % GOAL_TO_TEXTURE[type]) self.idleGeom.detachNode() self.idleGeom = None self.highlightedGeom.detachNode() self.highlightedGeom = None self.idleGeom = NodePath('idleGeom') self.highlightedGeom = NodePath('highlightedGeom') self.idleGeom.reparentTo(self) self.highlightedGeom.reparentTo(self) if activeWoodSquareGeom.isEmpty(): self.stash() else: activeWoodSquareGeom.find('**/idle').copyTo(self.idleGeom) activeWoodSquareGeom.find('**/over').copyTo(self.highlightedGeom) self.setGeomState('idle') self.unstash() def setEnabled(self, enabled): self.onMouseUp(None) self.enabled = enabled if not enabled: self['state'] = DGG.DISABLED else: self['state'] = DGG.NORMAL def isGoalPiece(self): if self.pieceType != GOAL_NONE: pass return self.pieceType != GOAL_EMPTY def isEmptyPiece(self): return self.pieceType == GOAL_EMPTY def setGridLocation(self, location, pos): self.location = location self.setPos(pos) def enterIdle(self): self.stash() self.setEnabled(False) def exitIdle(self): self.unstash() def enterBlank(self): self.setType(GOAL_NONE) def exitBlank(self): self.unstash() def enterGoal(self, pieceType): self.setType(pieceType) def exitGoal(self): self.unstash() def enterEmpty(self): self.setEnabled(False) self.setType(GOAL_EMPTY) def exitEmpty(self): self.unstash()
class Chunk(object): """ """ def __init__(self, encoder, generator, fileObj, chunkSize, position): """ """ from chunkGenerator import ChunkGenerator from encoder import Encoder from panda3d.core import Filename if not isinstance(generator, ChunkGenerator): raise TypeError(generator) if not isinstance(encoder, Encoder): raise TypeError(encoder) if not isinstance(fileObj, FileObjectIF): raise TypeError(fileObj) if not isinstance(position, Vec3): raise TypeError(position) if not isinstance(chunkSize, int): raise TypeError(chunkSize) super(Chunk, self).__init__() self.encoder = encoder self.generator = generator self.position = position self.chunkSize = chunkSize self.fileObj = fileObj self.chunkModel = None self.blocks = [] return None def toRelativePosition(self, position): """Given the absolute coordinates of a block, get the coordinates of the block relative to the chunk it belongs to.""" chunkSize = self.settings["general"]["chunkSize"] x = position.getX() % chunkSize y = position.getY() % chunkSize z = position.getZ() % chunkSize return Vec3(x, y, z) def toAbsolutePosition(self, position): """Given the position of a block in it's chunk, calculate it's position in absolute coordinates.""" x = position.getX() + self.chunkSize * self.position.getX() y = position.getY() + self.chunkSize * self.position.getY() z = position.getZ() + self.chunkSize * self.position.getZ() return Vec3(x, y, z) def getFilePosition(self, position): """given the coordinates within the chunk, get the index where the data of the block begins in the file.""" x, y, z = position.getX(), position.getY(), position.getZ() index = x * self.chunkSize ** 2 + y * self.chunkSize + z return index def saveBlock(self, block): """ """ position = self.toRelativePosition(block.position) index = self.getFilePosition(position) representation = self.encoder.encodeBlock(block) self.fileObj.open("w+b") self.fileObj.seek(index) self.fileObj.write(representation) self.fileObj.close() return None def load(self, environment): """Construct all the blocks in this chunk, and add it to the environment.""" self.chunkModel = NodePath("chunk") pos = Vec3(0, 0, 0) if not self.fileObj.exists(): self.generator.generate(self.fileObj, self.position) self.fileObj.open() self.fileObj.seek(0) while True: part = self.fileObj.read(self.encoder.size()) block = self.encoder.decodeBlock(part, pos) block.create(self.chunkModel) self.blocks.append(block) if pos.getX() >= self.chunkSize - 1: pos = Vec3(0, pos.getY() + 1, pos.getZ()) else: pos = pos + (1, 0, 0) if pos.getY() >= self.chunkSize: pos = Vec3(pos.getX(), 0, pos.getZ() + 1) if pos.getZ() >= self.chunkSize: break self.fileObj.close() self.chunkModel.reparentTo(environment) return None def unload(self): """ """ self.chunkModel.detachNode() return None def purge(self): """allow the garbage collector to clean all the block data?""" self.chunkModel.removeNode() self.chunkModel = None return None def place(self, block, position): string = self.encoder.encodeBlock(block) blockIdx = self.getIdx(position) self.fileObj.open() self.fileObj.seek(blockIdx) self.fileObj.write(string) self.fileObj.close() return None def getIdx(self, position): """ """ i = position.getX() i += position.getY() * self.chunkSize i += position.getZ() * self.chunkSize ** 2 i = i * self.encoder.size() return int(i) def __iter__(self): return self.blocks
class ForestNode(NodePath): def __init__(self, config, world): NodePath.__init__(self, 'ForestNode') self.config = config self.world = world self.added = [] self.trees = {} self.trees_in_node = 10 self.mutex = self.world.mutex_repaint self.flatten_node = NodePath('flatten_nodes') def add_trees(self, chunk): # level if chunk not in self.added: self.added.append(chunk) else: return size2 = chunk[1] / 2 x = chunk[0][0] y = chunk[0][1] sx = x - size2 sy = y - size2 ex = x + size2 ey = y + size2 t = time.time() trees = self.world.treeland[sx, sy, ex, ey] for tree in trees: if not self.trees.has_key(tree): self.trees[tree] = [] self.trees[tree] = self.trees[tree] + trees[tree] def clear(self): self.flatten_node.detachNode() self.flatten_node.removeNode() self.flatten_node = NodePath('flatten_nodes') def show_forest(self, DX, DY, char_far, far, charpos, Force=False): """Set to new X center X - self.size/2 - DX """ tmp_node = NodePath('tmp') self.flatten_node.copyTo(tmp_node) self.mutex.acquire() tmp_node.reparentTo(self) self.flatten_node.removeNode() self.mutex.release() self.tree_nodes = [] self.flatten_node = NodePath('flatten_nodes') t = time.time() count_trees = 0 for tree_n in self.trees: # create or attach for coord in self.trees[tree_n]: #length_cam_2d = VBase2.length(Vec2(coord[0], coord[1]) - Vec2(charpos[0], charpos[1])) length_cam_3d = VBase3.length(Vec3(coord) - Vec3(charpos)) if char_far >= length_cam_3d <= far: tree = self.world.trees[tree_n] self.tree_nodes.append(NodePath('TreeNode')) tree.copyTo(self.tree_nodes[count_trees]) x, y, z = coord self.tree_nodes[count_trees].setPos(x - DX, y - DY, z - 1) count_trees += 1 print 'Attach detach loop: ', time.time() - t if count_trees == 0: self.mutex.acquire() tmp_node.removeNode() self.mutex.release() return t = time.time() self.count_f_nodes = (count_trees / self.trees_in_node) + 1 self.flatten_nodes = [ NodePath('flatten_node') for i in xrange(self.count_f_nodes) ] s = 0 e = self.trees_in_node added = 0 for node in self.flatten_nodes: t_nodes = self.tree_nodes[s:e] s += self.trees_in_node e += self.trees_in_node for t_node in t_nodes: t_node.reparentTo(node) added += 1 node.flattenStrong() if not Force: time.sleep(self.config.tree_sleep) node.reparentTo(self.flatten_node) if added == count_trees: break print 'Added: ', added, time.time() - t t = time.time() self.flatten_node.flattenStrong() self.mutex.acquire() self.flatten_node.reparentTo(self) tmp_node.removeNode() self.mutex.release() print 'flatten all trees: ', time.time() - t
class itemClass(objectIdClass): def __init__( self, ground ): objectIdClass.__init__( self ) self.ground = ground # create collision object pass # create position node self.positionNp = NodePath( 'positionNp%s' % self.objectId ) #self.positionNp.reparentTo( render ) # load model self.modelNp = loader.loadModelCopy( 'data/models/box.egg' ) self.modelNp.reparentTo( self.positionNp ) self.setPos( Vec3(0,0,0) ) self.create3dObject() def destroy( self ): objectIdClass.destroy( self ) def create3dObject( self ): self.reparentTo( render ) #self.positionNp.show() self.makePickable( self.modelNp ) def setPos( self, position ): xPos, yPos, zPos = position.getX(), position.getY(), position.getZ() zGround = self.ground.get_elevation( [xPos, yPos] ) zPos = zGround #if zPos < zGround: # zPos = zGround return self.positionNp.setPos( Vec3(xPos, yPos, zPos) ) def getPos( self, relativeTo=None ): return self.positionNp.getPos( relativeTo ) def setHpr( self, hpr ): return self.positionNp.setHpr( hpr ) def reparentTo( self, object ): return self.positionNp.reparentTo( object ) def wrtReparentTo( self, object ): return self.positionNp.wrtReparentTo( object ) def putOnGround( self, xyPos ): return self.ground.get_elevation( xyPos ) def destroy3dObject( self ): self.positionNp.detachNode() #self.positionNp.hide() # destroy collision object # destroy shape #pass def create2dObject( self ): pass def destroy2dObject( self ): pass