def setupTire(self, avId, index): (tireNp, tireBody, tireOdeGeom) = self.createTire(index) self.tireDict[avId] = { 'tireNodePath': tireNp, 'tireBody': tireBody, 'tireOdeGeom': tireOdeGeom } if avId <= 0: tireBlocker = tireNp.find('**/tireblockermesh') if not tireBlocker.isEmpty(): tireBlocker.hide() if avId == self.localAvId: tireNp = self.tireDict[avId]['tireNodePath'] self.treasureSphereName = 'treasureCollider' self.treasureCollSphere = CollisionSphere( 0, 0, 0, IceGameGlobals.TireRadius) self.treasureCollSphere.setTangible(0) self.treasureCollNode = CollisionNode(self.treasureSphereName) self.treasureCollNode.setFromCollideMask( ToontownGlobals.PieBitmask) self.treasureCollNode.addSolid(self.treasureCollSphere) self.treasureCollNodePath = tireNp.attachNewNode( self.treasureCollNode) self.treasureHandler = CollisionHandlerEvent() self.treasureHandler.addInPattern('%fn-intoTreasure') base.cTrav.addCollider(self.treasureCollNodePath, self.treasureHandler) eventName = '%s-intoTreasure' % self.treasureCollNodePath.getName() self.notify.debug('eventName = %s' % eventName) self.accept(eventName, self.toonHitSomething)
def __init__(self, showbase, usersData, gameData): self.showbase = showbase self.usersData = usersData self.gameData = gameData random.seed(self.gameData.randSeed) # Initialize the collision traverser. self.cTrav = CollisionTraverser() # Initialize the handler. self.collHandEvent = CollisionHandlerEvent() self.collHandEvent.addInPattern('into-%in') self.world = World(showbase) for user in self.usersData: user.centipede = Centipede(showbase, len(self.usersData), self.addToCollisions) if user.thisPlayer: self.centipede = user.centipede self.centipede.attachRing(showbase) self.foods = [] for i in range(self.gameData.maxFoods): self.foods.append(Food(self.showbase, i, self.addToCollisions)) self.ticks = 0
def enterPlay(self): self.notify.debug('enterPlay') self.startGameWalk() self.spawnUpdateSuitsTask() self.accept('control', self.controlKeyPressed) self.pieHandler = CollisionHandlerEvent() self.pieHandler.setInPattern('pieHit-%fn')
def __init__(self, id, toon, game, guiMgr): CogdoMazePlayer.__init__(self, id, toon) self.disableGagCollision() self.game = game self.maze = self.game.maze self._guiMgr = guiMgr self.cameraMgr = CogdoMazeCameraManager(self.toon, self.maze, camera, render) self._proximityRadius = self.maze.cellWidth * Globals.CameraRemoteToonRadius orthoDrive = OrthoDrive(Globals.ToonRunSpeed, maxFrameMove=self.maze.cellWidth / 2, customCollisionCallback=self.maze.doOrthoCollisions, wantSound=True) self.orthoWalk = OrthoWalk(orthoDrive) self._audioMgr = base.cogdoGameAudioMgr self._getMemoSfx = self._audioMgr.createSfx('getMemo', source=self.toon) self._waterCoolerFillSfx = self._audioMgr.createSfx('waterCoolerFill', source=self.toon) self._hitByDropSfx = self._audioMgr.createSfx('toonHitByDrop', source=self.toon) self._winSfx = self._audioMgr.createSfx('win') self._loseSfx = self._audioMgr.createSfx('lose') self.enabled = False self.pickupCount = 0 self.numEntered = 0 self.throwPending = False self.coolDownAfterHitInterval = Sequence(Wait(Globals.HitCooldownTime), Func(self.setInvulnerable, False), name='coolDownAfterHitInterval-%i' % self.toon.doId) self.invulnerable = False self.gagHandler = CollisionHandlerEvent() self.gagHandler.addInPattern('%fn-into-%in') self.exited = False self.hints = {'find': False, 'throw': False, 'squashed': False, 'boss': False, 'minion': False} self.accept('control', self.controlKeyPressed)
def __init__(self, model, world, space, pos): self.model = model self.world = world self.space = space self.collHandEvent = CollisionHandlerEvent() self.collHandEvent.addInPattern('into-%in') self.addBox(pos) self.isCollected = False Coin.collectable += 1
def __init__(self): self.line_dir = NodePath() base.cTrav = CollisionTraverser() self.col_handler = CollisionHandlerEvent() picker_node = CollisionNode("mouseRayNode") pickerNPos = base.camera.attachNewNode(picker_node) self.pickerRay = CollisionRay() picker_node.addSolid(self.pickerRay) plane_node = CollisionNode("base_plane") plane = base.render.attachNewNode(plane_node) self.plane_col = CollisionPlane(Plane(Vec3(0, 0, 1), Point3(0, 0, 0))) picker_node.addSolid(self.pickerRay) picker_node.setTag("rays", "mray") base.cTrav.addCollider(pickerNPos, self.col_handler) self.col_handler.addInPattern("%(rays)ft-into-%(type)it") self.col_handler.addOutPattern("%(rays)ft-out-%(type)it") self.col_handler.addAgainPattern("ray_again_all%(" "rays" ")fh%(" "type" ")ih") self.model = loader.loadModel("../models/chest.egg") self.model_node = NodePath("sdfafd") self.model.reparentTo(self.model_node) self.model_node.reparentTo(render) # # self.text_node = TextNode("battle_text") # self.text_node.setText("TEXTYTEXTYTEXTTEXT") # self.text_node_path = render.attachNewNode(self.text_node) # self.text_node_path.reparentTo(render) # self.text_node_path.setPos(0,0,4) # self.text_node_path.setHpr(0,0,0) # self.text_node_path.setScale(1) # #self.text_node_path.setTransparency(TransparencyAttrib.MAlpha) # self.text_node.setTextColor((1,1,1,1)) # self.text_node.setAlign(TextNode.ALeft) self.placement_ghost = EditorObjects.PlacementGhost( 0, "tower", base.object_scale) z = 0 self.plane = Plane(Vec3(0, 0, 1), Point3(0, 0, z)) taskMgr.add(self.ray_update, "updatePicker") taskMgr.add(self.get_mouse_plane_pos, "MousePositionOnPlane") taskMgr.add(self.task_mouse_press_check, "checkMousePress") self.input_init() self.pickable = None
def init_collisions(self): base.cTrav = CollisionTraverser() self.cHandler = CollisionHandlerEvent() pickerNode = CollisionNode("mouseRayNode") pickerNPos = base.camera.attachNewNode(pickerNode) self.pickerRay = CollisionRay() pickerNode.addSolid(self.pickerRay) pickerNode.setTag("rays","ray1") base.cTrav.addCollider(pickerNPos, self.cHandler)
def getFlyBallBubble(self): if self.__flyBallBubble == None: bubble = CollisionSphere(0, 0, 0, GolfGlobals.GOLF_BALL_RADIUS) node = CollisionNode('flyBallBubble') node.addSolid(bubble) node.setFromCollideMask(ToontownGlobals.PieBitmask | ToontownGlobals.CameraBitmask | ToontownGlobals.FloorBitmask) node.setIntoCollideMask(BitMask32.allOff()) self.__flyBallBubble = NodePath(node) self.flyBallHandler = CollisionHandlerEvent() self.flyBallHandler.addInPattern('flyBallHit-%d' % self.index) return self.__flyBallBubble
def initCollisionTest(self): self.collHandEvent = CollisionHandlerEvent() self.collHandEvent.addInPattern('into-%in') base.cTrav = CollisionTraverser('test name') if False: base.cTrav.showCollisions(render) cName = 'BallCollNode' cSphere = CollisionSphere(0, 0, 0, 1.0) cNode = CollisionNode(cName) cNode.addSolid(cSphere) cNodePath = self.ball.modelNode.attachNewNode(cNode) base.cTrav.addCollider(cNodePath, self.collHandEvent)
def __initCollisions(self): collSphere = CollisionSphere(0, 0, 0, Globals.PlayerCollisionRadius) collSphere.setTangible(0) self.mazeCollisionName = Globals.LocalPlayerCollisionName collNode = CollisionNode(self.mazeCollisionName) collNode.addSolid(collSphere) collNodePath = self.toon.attachNewNode(collNode) collNodePath.hide() handler = CollisionHandlerEvent() handler.addInPattern('%fn-into-%in') base.cTrav.addCollider(collNodePath, handler) self.handler = handler self._collNodePath = collNodePath
def setupFloorEventSphere(self, avatarNodePath, bitmask, avatarRadius): cSphere = CollisionSphere(0.0, 0.0, 0.0, 0.75) cSphereNode = CollisionNode('Flyer.cFloorEventSphere') cSphereNode.addSolid(cSphere) cSphereNodePath = avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) self.floorCollisionEvent = CollisionHandlerEvent() self.floorCollisionEvent.addInPattern('%fn-enter-%in') self.floorCollisionEvent.addAgainPattern('%fn-again-%in') self.floorCollisionEvent.addOutPattern('%fn-exit-%in') base.cTrav.addCollider(cSphereNodePath, self.floorCollisionEvent) self.cFloorEventSphereNodePath = cSphereNodePath
def setupHeadSphere(self, avatarNodePath): collSphere = CollisionSphere(0, 0, 0, 1) collSphere.setTangible(1) collNode = CollisionNode('Flyer.cHeadCollSphere') collNode.setFromCollideMask(ToontownGlobals.CeilingBitmask) collNode.setIntoCollideMask(BitMask32.allOff()) collNode.addSolid(collSphere) self.cHeadSphereNodePath = avatarNodePath.attachNewNode(collNode) self.cHeadSphereNodePath.setZ(base.localAvatar.getHeight() + 1.0) self.headCollisionEvent = CollisionHandlerEvent() self.headCollisionEvent.addInPattern('%fn-enter-%in') self.headCollisionEvent.addOutPattern('%fn-exit-%in') base.cTrav.addCollider(self.cHeadSphereNodePath, self.headCollisionEvent)
def setupEventSphere(self, bitmask, avatarRadius): self.avatarRadius = avatarRadius cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75, self.avatarRadius * 1.04) cSphere.setTangible(0) cSphereNode = CollisionNode('Flyer.cEventSphereNode') cSphereNode.addSolid(cSphere) cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) self.event = CollisionHandlerEvent() self.event.addInPattern('enter%in') self.event.addOutPattern('exit%in') self.cEventSphereNodePath = cSphereNodePath
def loadGame(self): self.camera.setPos(CposX, CposY, CposZ) self.camera.setHpr(0,0,0) #for j in range(0, 100): #self.environ[j] = self.loader.loadModel("CityTerrain/CityTerrain") #self.environ[j].reparentTo(self.render) #self.environ[j].setPos(-8,42 + 210*j,0) #self.environ[j].setScale(0.25,0.25,0.25) self.accept("arrow_up-repeat", self.setKey, ["forward", 1]) self.accept("arrow_down-repeat", self.setKey, ["slow", 1]) self.accept("arrow_left", self.setKey, ["left", 1]) self.accept("arrow_right", self.setKey, ["right", 1]) base.cTrav = CollisionTraverser() self.collHandEvent = CollisionHandlerEvent() self.collCount=0 self.collHandEvent.addInPattern('into-%in') self.collHandEvent.addOutPattern('outof-%in') sColl = self.initCollisionSphere(self.environ1, True) base.cTrav.addCollider(sColl[0], self.collHandEvent) for child in render.getChildren(): if child != camera and child != self.environ2 and child!= self.environ4 and child != self.BS and child!= self.model and child!= self.barn and child!= self.barn1 and child!= self.barn2 and child!= self.barn3 and child!= self.barn5: #print child tColl = self.initCollisionSphere(child, True) base.cTrav.addCollider(tColl[0], self.collHandEvent) self.accept('into-' + tColl[1] , self.collide) ## for m in range(0,100): ## tgrb= self.initCollisionSphere(self.grb[i], True) ## base.cTrav.addCollider(tgrb[0], self.collHandEvent) ## self.accept('into-' + tgrb[1], self.collide) ## ## for n in range(0,100): ## tobs= self.initCollisionSphere(self.obs[i], True) ## base.cTrav.addCollider(tobs[0], self.collHandEvent) ## self.accept('into-' + tobs[1], self.collide) self.taskMgr.add(self.move, "moveTask")
def setupTire(self, avId, index): (tireNp, tireBody, tireOdeGeom) = self.createTire(index) self.tireDict[avId] = { 'tireNodePath': tireNp, 'tireBody': tireBody, 'tireOdeGeom': tireOdeGeom } if avId <= 0: tireBlocker = tireNp.find('**/tireblockermesh') if not tireBlocker.isEmpty(): tireBlocker.hide() if avId == self.localAvId: tireNp = self.tireDict[avId]['tireNodePath'] self.treasureSphereName = 'treasureCollider' self.treasureCollSphere = CollisionSphere(0, 0, 0, IceGameGlobals.TireRadius) self.treasureCollSphere.setTangible(0) self.treasureCollNode = CollisionNode(self.treasureSphereName) self.treasureCollNode.setFromCollideMask(ToontownGlobals.PieBitmask) self.treasureCollNode.addSolid(self.treasureCollSphere) self.treasureCollNodePath = tireNp.attachNewNode(self.treasureCollNode) self.treasureHandler = CollisionHandlerEvent() self.treasureHandler.addInPattern('%fn-intoTreasure') base.cTrav.addCollider(self.treasureCollNodePath, self.treasureHandler) eventName = '%s-intoTreasure' % self.treasureCollNodePath.getName() self.notify.debug('eventName = %s' % eventName) self.accept(eventName, self.toonHitSomething)
def __init__(self): # Initialize the traverser. base.cTrav = CollisionTraverser() # Initialize the handler. self.collHandEvent = CollisionHandlerEvent() self.collHandEvent.addInPattern('into-%in') self.collHandEvent.addOutPattern('outof-%in') # Make a variable to store the unique collision string count. self.collCount = 0 # Load a model. Reparent it to the camera so we can move it. s = loader.loadModel('smiley') s.reparentTo(camera) s.setPos(0, 25, 0) # Setup a collision solid for this model. sColl = self.initCollisionSphere(s, True) # Add this object to the traverser. base.cTrav.addCollider(sColl[0], self.collHandEvent) # Accept the events sent by the collisions. self.accept('into-' + sColl[1], self.collide3) self.accept('outof-' + sColl[1], self.collide4) print(sColl[1]) # Load another model. t = loader.loadModel('smiley') t.reparentTo(render) t.setPos(5, 25, 0) # Setup a collision solid for this model. tColl = self.initCollisionSphere(t, True) # Add this object to the traverser. base.cTrav.addCollider(tColl[0], self.collHandEvent) # Accept the events sent by the collisions. self.accept('into-' + tColl[1], self.collide) self.accept('outof-' + tColl[1], self.collide2) print(tColl[1]) print("WERT")
def startActivity(self, timestamp): self.pieHandler = CollisionHandlerEvent() self.pieHandler.setInPattern('pieHit-%fn') if self.player is not None: self.player.resetScore() self.hideTeamFlags(self.player.team) for player in self.players.values(): self.finishToonIval(player.toon.doId) player.enable() for cog in self.cogManager.cogs: cog.request('Active', timestamp) for ival in self.pieIvals: if ival.isPlaying(): ival.finish() self.pieIvals = []
def createCatchCollisions(self): radius = 0.7 handler = CollisionHandlerEvent() handler.setInPattern('ltCatch%in') self.ltLegsCollNode = CollisionNode('catchLegsCollNode') self.ltLegsCollNode.setCollideMask(PartyGlobals.CatchActivityBitmask) self.ltHeadCollNode = CollisionNode('catchHeadCollNode') self.ltHeadCollNode.setCollideMask(PartyGlobals.CatchActivityBitmask) self.ltLHandCollNode = CollisionNode('catchLHandCollNode') self.ltLHandCollNode.setCollideMask(PartyGlobals.CatchActivityBitmask) self.ltRHandCollNode = CollisionNode('catchRHandCollNode') self.ltRHandCollNode.setCollideMask(PartyGlobals.CatchActivityBitmask) legsCollNodepath = base.localAvatar.attachNewNode(self.ltLegsCollNode) legsCollNodepath.hide() head = base.localAvatar.getHeadParts().getPath(2) headCollNodepath = head.attachNewNode(self.ltHeadCollNode) headCollNodepath.hide() lHand = base.localAvatar.getLeftHands()[0] lHandCollNodepath = lHand.attachNewNode(self.ltLHandCollNode) lHandCollNodepath.hide() rHand = base.localAvatar.getRightHands()[0] rHandCollNodepath = rHand.attachNewNode(self.ltRHandCollNode) rHandCollNodepath.hide() base.localAvatar.cTrav.addCollider(legsCollNodepath, handler) base.localAvatar.cTrav.addCollider(headCollNodepath, handler) base.localAvatar.cTrav.addCollider(lHandCollNodepath, handler) base.localAvatar.cTrav.addCollider(lHandCollNodepath, handler) if self.ShowToonSpheres: legsCollNodepath.show() headCollNodepath.show() lHandCollNodepath.show() rHandCollNodepath.show() self.ltLegsCollNode.addSolid(CollisionSphere(0, 0, radius, radius)) self.ltHeadCollNode.addSolid(CollisionSphere(0, 0, 0, radius)) self.ltLHandCollNode.addSolid( CollisionSphere(0, 0, 0, 2 * radius / 3.0)) self.ltRHandCollNode.addSolid( CollisionSphere(0, 0, 0, 2 * radius / 3.0)) self.toonCollNodes = [ legsCollNodepath, headCollNodepath, lHandCollNodepath, rHandCollNodepath ]
def createCatchCollisions(self): radius = 0.7 handler = CollisionHandlerEvent() handler.setInPattern('ltCatch%in') self.ltLegsCollNode = CollisionNode('catchLegsCollNode') self.ltLegsCollNode.setCollideMask(PartyGlobals.CatchActivityBitmask) self.ltHeadCollNode = CollisionNode('catchHeadCollNode') self.ltHeadCollNode.setCollideMask(PartyGlobals.CatchActivityBitmask) self.ltLHandCollNode = CollisionNode('catchLHandCollNode') self.ltLHandCollNode.setCollideMask(PartyGlobals.CatchActivityBitmask) self.ltRHandCollNode = CollisionNode('catchRHandCollNode') self.ltRHandCollNode.setCollideMask(PartyGlobals.CatchActivityBitmask) legsCollNodepath = base.localAvatar.attachNewNode(self.ltLegsCollNode) legsCollNodepath.hide() head = base.localAvatar.getHeadParts().getPath(2) headCollNodepath = head.attachNewNode(self.ltHeadCollNode) headCollNodepath.hide() lHand = base.localAvatar.getLeftHands()[0] lHandCollNodepath = lHand.attachNewNode(self.ltLHandCollNode) lHandCollNodepath.hide() rHand = base.localAvatar.getRightHands()[0] rHandCollNodepath = rHand.attachNewNode(self.ltRHandCollNode) rHandCollNodepath.hide() base.localAvatar.cTrav.addCollider(legsCollNodepath, handler) base.localAvatar.cTrav.addCollider(headCollNodepath, handler) base.localAvatar.cTrav.addCollider(lHandCollNodepath, handler) base.localAvatar.cTrav.addCollider(lHandCollNodepath, handler) if self.ShowToonSpheres: legsCollNodepath.show() headCollNodepath.show() lHandCollNodepath.show() rHandCollNodepath.show() self.ltLegsCollNode.addSolid(CollisionSphere(0, 0, radius, radius)) self.ltHeadCollNode.addSolid(CollisionSphere(0, 0, 0, radius)) self.ltLHandCollNode.addSolid(CollisionSphere(0, 0, 0, 2 * radius / 3.0)) self.ltRHandCollNode.addSolid(CollisionSphere(0, 0, 0, 2 * radius / 3.0)) self.toonCollNodes = [legsCollNodepath, headCollNodepath, lHandCollNodepath, rHandCollNodepath]
def __init__(self): self.line_dir = NodePath() base.cTrav = CollisionTraverser() self.col_handler = CollisionHandlerEvent() picker_node = CollisionNode("mouseRayNode") pickerNPos = base.camera.attachNewNode(picker_node) self.pickerRay = CollisionRay() picker_node.addSolid(self.pickerRay) plane_node = CollisionNode("base_plane") plane = base.render.attachNewNode(plane_node) self.plane_col = CollisionPlane(Plane(Vec3(0, 0, 1), Point3(0, 0, 0))) picker_node.addSolid(self.pickerRay) picker_node.setTag("rays","mray") base.cTrav.addCollider(pickerNPos, self.col_handler) self.col_handler.addInPattern("%(rays)ft-into-%(type)it") self.col_handler.addOutPattern("%(rays)ft-out-%(type)it") self.col_handler.addAgainPattern("ray_again_all%(""rays"")fh%(""type"")ih") self.model = loader.loadModel("../models/chest.egg") self.model_node = NodePath("sdfafd") self.model.reparentTo(self.model_node) self.model_node.reparentTo(render) # # self.text_node = TextNode("battle_text") # self.text_node.setText("TEXTYTEXTYTEXTTEXT") # self.text_node_path = render.attachNewNode(self.text_node) # self.text_node_path.reparentTo(render) # self.text_node_path.setPos(0,0,4) # self.text_node_path.setHpr(0,0,0) # self.text_node_path.setScale(1) # #self.text_node_path.setTransparency(TransparencyAttrib.MAlpha) # self.text_node.setTextColor((1,1,1,1)) # self.text_node.setAlign(TextNode.ALeft) self.placement_ghost = EditorObjects.PlacementGhost(0,"tower",base.object_scale) z=0 self.plane = Plane(Vec3(0, 0, 1), Point3(0, 0, z)) taskMgr.add(self.ray_update, "updatePicker") taskMgr.add(self.get_mouse_plane_pos, "MousePositionOnPlane") taskMgr.add(self.task_mouse_press_check, "checkMousePress") self.input_init() self.pickable=None
def __init__(self): # Initialize the traverser. base.cTrav = CollisionTraverser() # Initialize the handler. self.collHandEvent = CollisionHandlerEvent() self.collHandEvent.addInPattern("into-%in") self.collHandEvent.addOutPattern("outof-%in") # Make a variable to store the unique collision string count. self.collCount = 0 # Load a model. Reparent it to the camera so we can move it. s = loader.loadModel("smiley") s.reparentTo(camera) s.setPos(0, 25, 0) # Setup a collision solid for this model. sColl = self.initCollisionSphere(s, True) # Add this object to the traverser. base.cTrav.addCollider(sColl[0], self.collHandEvent) # Accept the events sent by the collisions. self.accept("into-" + sColl[1], self.collide3) self.accept("outof-" + sColl[1], self.collide4) print(sColl[1]) # Load another model. t = loader.loadModel("smiley") t.reparentTo(render) t.setPos(5, 25, 0) # Setup a collision solid for this model. tColl = self.initCollisionSphere(t, True) # Add this object to the traverser. base.cTrav.addCollider(tColl[0], self.collHandEvent) # Accept the events sent by the collisions. self.accept("into-" + tColl[1], self.collide) self.accept("outof-" + tColl[1], self.collide2) print(tColl[1]) print("WERT")
""" #========================================================================= #** Collision system ignition base.cTrav = CollisionTraverser() #** This is the known collision handler we use for floor collisions. We'll keep going with the usual settings here as well. avatarFloorHandler = CollisionHandlerGravity() avatarFloorHandler.setGravity(9.81 + 25) avatarFloorHandler.setMaxVelocity(100) #** the walls collider wallHandler = CollisionHandlerPusher() #** we'll use this to 'sense' the fallout impact velocity and also to 'read' various triggers we've put around the map for several purposes. collisionEvent = CollisionHandlerEvent() #** Collision masks - this time there is a new one: the TRIGGER_MASK is used to detect certain collision geometry to act as a trigger, therefore we need to distinguish'em from floor and walls. FLOOR_MASK = BitMask32.bit(1) WALL_MASK = BitMask32.bit(2) TRIGGER_MASK = BitMask32.bit(3) #** Our steering avatar avatarNP = base.render.attachNewNode(ActorNode('yolkyNP')) avatarNP.reparentTo(base.render) # by the way: this time we wont use the same old smiley but a 2d guy for this snippet purposes only - it is just a plane with a texture glued on, a so 2d object then. avatar = loader.loadModel('yolky') avatar.reparentTo(avatarNP) # why this? this is to have our flat puppet rendered always on top of all objects in the scene, either 2d and 3d. avatar.setDepthWrite(True, 100) # the rest of the stuff is as usual...
class DistributedCogThiefGame(DistributedMinigame): notify = directNotify.newCategory('DistributedCogThiefGame') ToonSpeed = CTGG.ToonSpeed StageHalfWidth = 200.0 StageHalfHeight = 100.0 BarrelScale = 0.25 TOON_Z = 0 UPDATE_SUITS_TASK = 'CogThiefGameUpdateSuitsTask' REWARD_COUNTDOWN_TASK = 'cogThiefGameRewardCountdown' ControlKeyLimitTime = 1.0 def __init__(self, cr): DistributedMinigame.__init__(self, cr) self.gameFSM = ClassicFSM.ClassicFSM('DistributedCogThiefGame', [State.State('off', self.enterOff, self.exitOff, ['play']), State.State('play', self.enterPlay, self.exitPlay, ['cleanup']), State.State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup') self.addChildGameFSM(self.gameFSM) self.cameraTopView = (0, 0, 55, 0, -90.0, 0) self.barrels = [] self.cogInfo = {} self.lastTimeControlPressed = 0 self.stolenBarrels = [] self.resultIval = None self.gameIsEnding = False self.__textGen = TextNode('cogThiefGame') self.__textGen.setFont(ToontownGlobals.getSignFont()) self.__textGen.setAlign(TextNode.ACenter) return def getTitle(self): return TTLocalizer.CogThiefGameTitle def getInstructions(self): return TTLocalizer.CogThiefGameInstructions def getMaxDuration(self): return 0 def load(self): self.notify.debug('load') DistributedMinigame.load(self) self.music = base.loadMusic('phase_4/audio/bgm/MG_CogThief.ogg') self.initCogInfo() for barrelIndex in range(CTGG.NumBarrels): barrel = loader.loadModel('phase_4/models/minigames/cogthief_game_gagTank') barrel.setPos(CTGG.BarrelStartingPositions[barrelIndex]) barrel.setScale(self.BarrelScale) barrel.reparentTo(render) barrel.setTag('barrelIndex', str(barrelIndex)) collSphere = CollisionSphere(0, 0, 0, 4) collSphere.setTangible(0) name = 'BarrelSphere-%d' % barrelIndex collSphereName = self.uniqueName(name) collNode = CollisionNode(collSphereName) collNode.setFromCollideMask(CTGG.BarrelBitmask) collNode.addSolid(collSphere) colNp = barrel.attachNewNode(collNode) handler = CollisionHandlerEvent() handler.setInPattern('barrelHit-%fn') base.cTrav.addCollider(colNp, handler) self.accept('barrelHit-' + collSphereName, self.handleEnterBarrel) nodeToHide = '**/gagMoneyTen' if barrelIndex % 2: nodeToHide = '**/gagMoneyFive' iconToHide = barrel.find(nodeToHide) if not iconToHide.isEmpty(): iconToHide.hide() self.barrels.append(barrel) self.gameBoard = loader.loadModel('phase_4/models/minigames/cogthief_game') self.gameBoard.find('**/floor_TT').hide() self.gameBoard.find('**/floor_DD').hide() self.gameBoard.find('**/floor_DG').hide() self.gameBoard.find('**/floor_MM').hide() self.gameBoard.find('**/floor_BR').hide() self.gameBoard.find('**/floor_DL').hide() zone = self.getSafezoneId() if zone == ToontownGlobals.ToontownCentral: self.gameBoard.find('**/floor_TT').show() elif zone == ToontownGlobals.DonaldsDock: self.gameBoard.find('**/floor_DD').show() elif zone == ToontownGlobals.DaisyGardens: self.gameBoard.find('**/floor_DG').show() elif zone == ToontownGlobals.MinniesMelodyland: self.gameBoard.find('**/floor_MM').show() elif zone == ToontownGlobals.TheBrrrgh: self.gameBoard.find('**/floor_BR').show() elif zone == ToontownGlobals.DonaldsDreamland: self.gameBoard.find('**/floor_DL').show() else: self.gameBoard.find('**/floor_TT').show() self.gameBoard.setPosHpr(0, 0, 0, 0, 0, 0) self.gameBoard.setScale(1.0) self.toonSDs = {} avId = self.localAvId toonSD = CogThiefGameToonSD.CogThiefGameToonSD(avId, self) self.toonSDs[avId] = toonSD toonSD.load() self.loadCogs() self.toonHitTracks = {} self.toonPieTracks = {} self.sndOof = base.loadSfx('phase_4/audio/sfx/MG_cannon_hit_dirt.ogg') self.sndRewardTick = base.loadSfx('phase_3.5/audio/sfx/tick_counter.ogg') self.sndPerfect = base.loadSfx('phase_4/audio/sfx/ring_perfect.ogg') self.timer = ToontownTimer.ToontownTimer() self.timer.posInTopRightCorner() self.timer.hide() purchaseModels = loader.loadModel('phase_4/models/gui/purchase_gui') self.jarImage = purchaseModels.find('**/Jar') self.jarImage.reparentTo(hidden) self.rewardPanel = DirectLabel(parent=hidden, relief=None, pos=(1.16, 0.0, 0.45), scale=0.65, text='', text_scale=0.2, text_fg=(0.95, 0.95, 0, 1), text_pos=(0, -0.13), text_font=ToontownGlobals.getSignFont(), image=self.jarImage) self.rewardPanelTitle = DirectLabel(parent=self.rewardPanel, relief=None, pos=(0, 0, 0.06), scale=0.08, text=TTLocalizer.CannonGameReward, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1)) self.initGameWalk() return def unload(self): self.notify.debug('unload') DistributedMinigame.unload(self) del self.music self.removeChildGameFSM(self.gameFSM) del self.gameFSM self.gameBoard.removeNode() del self.gameBoard for barrel in self.barrels: barrel.removeNode() del self.barrels for avId in self.toonSDs.keys(): toonSD = self.toonSDs[avId] toonSD.unload() del self.toonSDs self.timer.destroy() del self.timer self.rewardPanel.destroy() del self.rewardPanel self.jarImage.removeNode() del self.jarImage del self.sndRewardTick def onstage(self): self.notify.debug('onstage') DistributedMinigame.onstage(self) self.gameBoard.reparentTo(render) lt = base.localAvatar lt.reparentTo(render) self.__placeToon(self.localAvId) lt.setSpeed(0, 0) self.moveCameraToTop() toonSD = self.toonSDs[self.localAvId] toonSD.enter() toonSD.fsm.request('normal') self.stopGameWalk() for cogIndex in xrange(self.getNumCogs()): suit = self.cogInfo[cogIndex]['suit'].suit pos = self.cogInfo[cogIndex]['pos'] suit.reparentTo(self.gameBoard) suit.setPos(pos) for avId in self.avIdList: self.toonHitTracks[avId] = Wait(0.1) self.toonRNGs = [] for i in xrange(self.numPlayers): self.toonRNGs.append(RandomNumGen.RandomNumGen(self.randomNumGen)) self.sndTable = {'hitBySuit': [None] * self.numPlayers, 'falling': [None] * self.numPlayers} for i in xrange(self.numPlayers): self.sndTable['hitBySuit'][i] = base.loadSfx('phase_4/audio/sfx/MG_Tag_C.ogg') self.sndTable['falling'][i] = base.loadSfx('phase_4/audio/sfx/MG_cannon_whizz.ogg') base.playMusic(self.music, looping=1, volume=0.8) self.introTrack = self.getIntroTrack() self.introTrack.start() return def offstage(self): self.notify.debug('offstage') self.gameBoard.hide() self.music.stop() for barrel in self.barrels: barrel.hide() for avId in self.toonSDs.keys(): self.toonSDs[avId].exit() for avId in self.avIdList: av = self.getAvatar(avId) if av: av.resetLOD() self.timer.reparentTo(hidden) self.rewardPanel.reparentTo(hidden) if self.introTrack.isPlaying(): self.introTrack.finish() del self.introTrack DistributedMinigame.offstage(self) def handleDisabledAvatar(self, avId): self.notify.debug('handleDisabledAvatar') self.notify.debug('avatar ' + str(avId) + ' disabled') self.toonSDs[avId].exit(unexpectedExit=True) del self.toonSDs[avId] DistributedMinigame.handleDisabledAvatar(self, avId) def setGameReady(self): if not self.hasLocalToon: return self.notify.debug('setGameReady') if DistributedMinigame.setGameReady(self): return for avId in self.remoteAvIdList: toon = self.getAvatar(avId) if toon: toon.reparentTo(render) self.__placeToon(avId) toon.useLOD(1000) toonSD = CogThiefGameToonSD.CogThiefGameToonSD(avId, self) self.toonSDs[avId] = toonSD toonSD.load() toonSD.enter() toonSD.fsm.request('normal') toon.startSmooth() def setGameStart(self, timestamp): if not self.hasLocalToon: return self.notify.debug('setGameStart') DistributedMinigame.setGameStart(self, timestamp) if not base.config.GetBool('cog-thief-endless', 0): self.timer.show() self.timer.countdown(CTGG.GameTime, self.__gameTimerExpired) self.clockStopTime = None self.rewardPanel.reparentTo(aspect2d) self.scoreMult = MinigameGlobals.getScoreMult(self.cr.playGame.hood.id) self.__startRewardCountdown() if self.introTrack.isPlaying(): self.introTrack.finish() self.gameFSM.request('play') return def enterOff(self): self.notify.debug('enterOff') def exitOff(self): pass def enterPlay(self): self.notify.debug('enterPlay') self.startGameWalk() self.spawnUpdateSuitsTask() self.accept('control', self.controlKeyPressed) self.pieHandler = CollisionHandlerEvent() self.pieHandler.setInPattern('pieHit-%fn') def exitPlay(self): self.ignore('control') if self.resultIval and self.resultIval.isPlaying(): self.resultIval.finish() self.resultIval = None return def enterCleanup(self): self.__killRewardCountdown() if hasattr(self, 'jarIval'): self.jarIval.finish() del self.jarIval for key in self.toonHitTracks: ival = self.toonHitTracks[key] if ival.isPlaying(): ival.finish() self.toonHitTracks = {} for key in self.toonPieTracks: ival = self.toonPieTracks[key] if ival.isPlaying(): ival.finish() self.toonPieTracks = {} for key in self.cogInfo: cogThief = self.cogInfo[key]['suit'] cogThief.cleanup() self.removeUpdateSuitsTask() self.notify.debug('enterCleanup') def exitCleanup(self): pass def __placeToon(self, avId): toon = self.getAvatar(avId) if toon: index = self.avIdList.index(avId) toon.setPos(CTGG.ToonStartingPositions[index]) toon.setHpr(0, 0, 0) def moveCameraToTop(self): camera.reparentTo(render) p = self.cameraTopView camera.setPosHpr(p[0], p[1], p[2], p[3], p[4], p[5]) base.camLens.setMinFov(46/(4./3.)) camera.setZ(camera.getZ() + base.config.GetFloat('cog-thief-z-camera-adjust', 0.0)) def destroyGameWalk(self): self.notify.debug('destroyOrthoWalk') self.gameWalk.destroy() del self.gameWalk def initGameWalk(self): self.notify.debug('startOrthoWalk') def doCollisions(oldPos, newPos, self = self): x = bound(newPos[0], CTGG.StageHalfWidth, -CTGG.StageHalfWidth) y = bound(newPos[1], CTGG.StageHalfHeight, -CTGG.StageHalfHeight) newPos.setX(x) newPos.setY(y) return newPos orthoDrive = OrthoDrive(self.ToonSpeed, customCollisionCallback=doCollisions, instantTurn=True) self.gameWalk = OrthoWalk(orthoDrive, broadcast=not self.isSinglePlayer()) def initCogInfo(self): for cogIndex in xrange(self.getNumCogs()): self.cogInfo[cogIndex] = {'pos': Point3(CTGG.CogStartingPositions[cogIndex]), 'goal': CTGG.NoGoal, 'goalId': CTGG.InvalidGoalId, 'suit': None} return def loadCogs(self): suitTypes = ['ds', 'ac', 'bc', 'ms'] for suitIndex in xrange(self.getNumCogs()): st = self.randomNumGen.choice(suitTypes) suit = CogThief.CogThief(suitIndex, st, self, self.getCogSpeed()) self.cogInfo[suitIndex]['suit'] = suit def handleEnterSphere(self, colEntry): if self.gameIsEnding: return intoName = colEntry.getIntoNodePath().getName() fromName = colEntry.getFromNodePath().getName() debugInto = intoName.split('/') debugFrom = fromName.split('/') self.notify.debug('handleEnterSphere gametime=%s %s into %s' % (self.getCurrentGameTime(), debugFrom[-1], debugInto[-1])) intoName = colEntry.getIntoNodePath().getName() if 'CogThiefSphere' in intoName: parts = intoName.split('-') suitNum = int(parts[1]) self.localToonHitBySuit(suitNum) def localToonHitBySuit(self, suitNum): self.notify.debug('localToonHitBySuit %d' % suitNum) timestamp = globalClockDelta.localToNetworkTime(globalClock.getFrameTime(), bits=32) pos = self.cogInfo[suitNum]['suit'].suit.getPos() self.sendUpdate('hitBySuit', [self.localAvId, timestamp, suitNum, pos[0], pos[1], pos[2]]) self.showToonHitBySuit(self.localAvId, timestamp) self.makeSuitRespondToToonHit(timestamp, suitNum) def hitBySuit(self, avId, timestamp, suitNum, x, y, z): if not self.hasLocalToon: return if self.gameFSM.getCurrentState().getName() not in ['play']: self.notify.warning('ignoring msg: av %s hit by suit' % avId) return if self.gameIsEnding: return self.notify.debug('avatar ' + `avId` + ' hit by a suit') if avId != self.localAvId: self.showToonHitBySuit(avId, timestamp) self.makeSuitRespondToToonHit(timestamp, suitNum) def showToonHitBySuit(self, avId, timestamp): toon = self.getAvatar(avId) if toon == None: return rng = self.toonRNGs[self.avIdList.index(avId)] curPos = toon.getPos(render) oldTrack = self.toonHitTracks[avId] if oldTrack.isPlaying(): oldTrack.finish() toon.setPos(curPos) toon.setZ(self.TOON_Z) parentNode = render.attachNewNode('mazeFlyToonParent-' + `avId`) parentNode.setPos(toon.getPos()) toon.reparentTo(parentNode) toon.setPos(0, 0, 0) startPos = parentNode.getPos() dropShadow = toon.dropShadow.copyTo(parentNode) dropShadow.setScale(toon.dropShadow.getScale(render)) trajectory = Trajectory.Trajectory(0, Point3(0, 0, 0), Point3(0, 0, 50), gravMult=1.0) oldFlyDur = trajectory.calcTimeOfImpactOnPlane(0.0) trajectory = Trajectory.Trajectory(0, Point3(0, 0, 0), Point3(0, 0, 50), gravMult=0.55) flyDur = trajectory.calcTimeOfImpactOnPlane(0.0) avIndex = self.avIdList.index(avId) endPos = CTGG.ToonStartingPositions[avIndex] def flyFunc(t, trajectory, startPos = startPos, endPos = endPos, dur = flyDur, moveNode = parentNode, flyNode = toon): u = t / dur moveNode.setX(startPos[0] + u * (endPos[0] - startPos[0])) moveNode.setY(startPos[1] + u * (endPos[1] - startPos[1])) flyNode.setPos(trajectory.getPos(t)) flyTrack = Sequence(LerpFunctionInterval(flyFunc, fromData=0.0, toData=flyDur, duration=flyDur, extraArgs=[trajectory]), name=toon.uniqueName('hitBySuit-fly')) geomNode = toon.getGeomNode() startHpr = geomNode.getHpr() destHpr = Point3(startHpr) hRot = rng.randrange(1, 8) if rng.choice([0, 1]): hRot = -hRot destHpr.setX(destHpr[0] + hRot * 360) spinHTrack = Sequence(LerpHprInterval(geomNode, flyDur, destHpr, startHpr=startHpr), Func(geomNode.setHpr, startHpr), name=toon.uniqueName('hitBySuit-spinH')) parent = geomNode.getParent() rotNode = parent.attachNewNode('rotNode') geomNode.reparentTo(rotNode) rotNode.setZ(toon.getHeight() / 2.0) oldGeomNodeZ = geomNode.getZ() geomNode.setZ(-toon.getHeight() / 2.0) startHpr = rotNode.getHpr() destHpr = Point3(startHpr) pRot = rng.randrange(1, 3) if rng.choice([0, 1]): pRot = -pRot destHpr.setY(destHpr[1] + pRot * 360) spinPTrack = Sequence(LerpHprInterval(rotNode, flyDur, destHpr, startHpr=startHpr), Func(rotNode.setHpr, startHpr), name=toon.uniqueName('hitBySuit-spinP')) i = self.avIdList.index(avId) soundTrack = Sequence(Func(base.playSfx, self.sndTable['hitBySuit'][i]), Wait(flyDur * (2.0 / 3.0)), SoundInterval(self.sndTable['falling'][i], duration=flyDur * (1.0 / 3.0)), name=toon.uniqueName('hitBySuit-soundTrack')) def preFunc(self = self, avId = avId, toon = toon, dropShadow = dropShadow): forwardSpeed = toon.forwardSpeed rotateSpeed = toon.rotateSpeed if avId == self.localAvId: self.stopGameWalk() else: toon.stopSmooth() if forwardSpeed or rotateSpeed: toon.setSpeed(forwardSpeed, rotateSpeed) toon.dropShadow.hide() def postFunc(self = self, avId = avId, oldGeomNodeZ = oldGeomNodeZ, dropShadow = dropShadow, parentNode = parentNode): if avId == self.localAvId: base.localAvatar.setPos(endPos) if hasattr(self, 'gameWalk'): toon = base.localAvatar toon.setSpeed(0, 0) self.startGameWalk() dropShadow.removeNode() del dropShadow toon = self.getAvatar(avId) if toon: toon.dropShadow.show() geomNode = toon.getGeomNode() rotNode = geomNode.getParent() baseNode = rotNode.getParent() geomNode.reparentTo(baseNode) rotNode.removeNode() del rotNode geomNode.setZ(oldGeomNodeZ) if toon: toon.reparentTo(render) toon.setPos(endPos) parentNode.removeNode() del parentNode if avId != self.localAvId: if toon: toon.startSmooth() preFunc() slipBack = Parallel(Sequence(ActorInterval(toon, 'slip-backward', endFrame=24), Wait(CTGG.LyingDownDuration - (flyDur - oldFlyDur)), ActorInterval(toon, 'slip-backward', startFrame=24))) if toon.doId == self.localAvId: slipBack.append(SoundInterval(self.sndOof)) hitTrack = Sequence(Parallel(flyTrack, spinHTrack, spinPTrack, soundTrack), slipBack, Func(postFunc), name=toon.uniqueName('hitBySuit')) self.notify.debug('hitTrack duration = %s' % hitTrack.getDuration()) self.toonHitTracks[avId] = hitTrack hitTrack.start(globalClockDelta.localElapsedTime(timestamp)) return def updateSuitGoal(self, timestamp, inResponseToClientStamp, suitNum, goalType, goalId, x, y, z): if not self.hasLocalToon: return self.notify.debug('updateSuitGoal gameTime=%s timeStamp=%s cog=%s goal=%s goalId=%s (%.1f, %.1f,%.1f)' % (self.getCurrentGameTime(), timestamp, suitNum, CTGG.GoalStr[goalType], goalId, x, y, z)) cog = self.cogInfo[suitNum] cog['goal'] = goalType cog['goalId'] = goalId newPos = Point3(x, y, z) cog['pos'] = newPos suit = cog['suit'] suit.updateGoal(timestamp, inResponseToClientStamp, goalType, goalId, newPos) def spawnUpdateSuitsTask(self): self.notify.debug('spawnUpdateSuitsTask') for cogIndex in self.cogInfo: suit = self.cogInfo[cogIndex]['suit'] suit.gameStart(self.gameStartTime) taskMgr.remove(self.UPDATE_SUITS_TASK) taskMgr.add(self.updateSuitsTask, self.UPDATE_SUITS_TASK) def removeUpdateSuitsTask(self): taskMgr.remove(self.UPDATE_SUITS_TASK) def updateSuitsTask(self, task): if self.gameIsEnding: return task.done for cogIndex in self.cogInfo: suit = self.cogInfo[cogIndex]['suit'] suit.think() return task.cont def makeSuitRespondToToonHit(self, timestamp, suitNum): cog = self.cogInfo[suitNum]['suit'] cog.respondToToonHit(timestamp) def handleEnterBarrel(self, colEntry): if self.gameIsEnding: return intoName = colEntry.getIntoNodePath().getName() fromName = colEntry.getFromNodePath().getName() debugInto = intoName.split('/') debugFrom = fromName.split('/') self.notify.debug('handleEnterBarrel gameTime=%s %s into %s' % (self.getCurrentGameTime(), debugFrom[-1], debugInto[-1])) if 'CogThiefSphere' in intoName: parts = intoName.split('-') cogIndex = int(parts[1]) barrelName = colEntry.getFromNodePath().getName() barrelParts = barrelName.split('-') barrelIndex = int(barrelParts[1]) cog = self.cogInfo[cogIndex]['suit'] if cog.barrel == CTGG.NoBarrelCarried and barrelIndex not in self.stolenBarrels: timestamp = globalClockDelta.localToNetworkTime(globalClock.getFrameTime(), bits=32) if cog.suit: cogPos = cog.suit.getPos() collisionPos = colEntry.getContactPos(render) if (cogPos - collisionPos).length() > 4: import pdb pdb.set_trace() self.sendUpdate('cogHitBarrel', [timestamp, cogIndex, barrelIndex, cogPos[0], cogPos[1], cogPos[2]]) def makeCogCarryBarrel(self, timestamp, inResponseToClientStamp, cogIndex, barrelIndex, x, y, z): if not self.hasLocalToon: return if self.gameIsEnding: return self.notify.debug('makeCogCarryBarrel gameTime=%s timeStamp=%s cog=%s barrel=%s (%.1f, %.1f,%.1f)' % (self.getCurrentGameTime(), timestamp, cogIndex, barrelIndex, x, y, z)) barrel = self.barrels[barrelIndex] self.notify.debug('barrelPos= %s' % barrel.getPos()) cog = self.cogInfo[cogIndex]['suit'] cogPos = Point3(x, y, z) cog.makeCogCarryBarrel(timestamp, inResponseToClientStamp, barrel, barrelIndex, cogPos) def makeCogDropBarrel(self, timestamp, inResponseToClientStamp, cogIndex, barrelIndex, x, y, z): if not self.hasLocalToon: return self.notify.debug('makeCogDropBarrel gameTime=%s timeStamp=%s cog=%s barrel=%s (%.1f, %.1f,%.1f)' % (self.getCurrentGameTime(), timestamp, cogIndex, barrelIndex, x, y, z)) barrel = self.barrels[barrelIndex] self.notify.debug('barrelPos= %s' % barrel.getPos()) cog = self.cogInfo[cogIndex]['suit'] cogPos = Point3(x, y, z) cog.makeCogDropBarrel(timestamp, inResponseToClientStamp, barrel, barrelIndex, cogPos) def controlKeyPressed(self): if self.isToonPlayingHitTrack(self.localAvId): return if self.gameIsEnding: return if self.getCurrentGameTime() - self.lastTimeControlPressed > self.ControlKeyLimitTime: self.lastTimeControlPressed = self.getCurrentGameTime() self.notify.debug('controlKeyPressed') toonSD = self.toonSDs[self.localAvId] curState = toonSD.fsm.getCurrentState().getName() toon = self.getAvatar(self.localAvId) timestamp = globalClockDelta.localToNetworkTime(globalClock.getFrameTime(), bits=32) pos = toon.getPos() heading = toon.getH() self.sendUpdate('throwingPie', [self.localAvId, timestamp, heading, pos[0], pos[1], pos[2]]) self.showToonThrowingPie(self.localAvId, timestamp, heading, pos) def throwingPie(self, avId, timestamp, heading, x, y, z): if not self.hasLocalToon: return if self.gameFSM.getCurrentState().getName() not in ['play']: self.notify.warning('ignoring msg: av %s hit by suit' % avId) return self.notify.debug('avatar ' + `avId` + ' throwing pie') if avId != self.localAvId: pos = Point3(x, y, z) self.showToonThrowingPie(avId, timestamp, heading, pos) def showToonThrowingPie(self, avId, timestamp, heading, pos): toon = self.getAvatar(avId) if toon: tossTrack, pieTrack, flyPie = self.getTossPieInterval(toon, pos[0], pos[1], pos[2], heading, 0, 0, 0) def removePieFromTraverser(flyPie = flyPie): if base.cTrav: if flyPie: base.cTrav.removeCollider(flyPie) if avId == self.localAvId: flyPie.setTag('throwerId', str(avId)) collSphere = CollisionSphere(0, 0, 0, 0.5) collSphere.setTangible(0) name = 'PieSphere-%d' % avId collSphereName = self.uniqueName(name) collNode = CollisionNode(collSphereName) collNode.setFromCollideMask(ToontownGlobals.PieBitmask) collNode.addSolid(collSphere) colNp = flyPie.attachNewNode(collNode) colNp.show() base.cTrav.addCollider(colNp, self.pieHandler) self.accept('pieHit-' + collSphereName, self.handlePieHitting) def matchRunningAnim(toon = toon): toon.playingAnim = None toon.setSpeed(toon.forwardSpeed, toon.rotateSpeed) return newTossTrack = Sequence(tossTrack, Func(matchRunningAnim)) pieTrack = Parallel(newTossTrack, pieTrack) elapsedTime = globalClockDelta.localElapsedTime(timestamp) if elapsedTime < 16.0 / 24.0: elapsedTime = 16.0 / 24.0 pieTrack.start(elapsedTime) self.toonPieTracks[avId] = pieTrack def getTossPieInterval(self, toon, x, y, z, h, p, r, power, beginFlyIval = Sequence()): from toontown.toonbase import ToontownBattleGlobals from toontown.battle import BattleProps pie = toon.getPieModel() pie.setScale(0.9) flyPie = pie.copyTo(NodePath('a')) pieName = ToontownBattleGlobals.pieNames[toon.pieType] pieType = BattleProps.globalPropPool.getPropType(pieName) animPie = Sequence() if pieType == 'actor': animPie = ActorInterval(pie, pieName, startFrame=48) sound = loader.loadSfx('phase_3.5/audio/sfx/AA_pie_throw_only.ogg') t = power / 100.0 dist = 100 - 70 * t time = 1 + 0.5 * t proj = ProjectileInterval(None, startPos=Point3(0, 0, 0), endPos=Point3(0, dist, 0), duration=time) relVel = proj.startVel def getVelocity(toon = toon, relVel = relVel): return render.getRelativeVector(toon, relVel) * 0.6 toss = Track((0, Sequence(Func(toon.setPosHpr, x, y, z, h, p, r), Func(pie.reparentTo, toon.rightHand), Func(pie.setPosHpr, 0, 0, 0, 0, 0, 0), Parallel(ActorInterval(toon, 'throw', startFrame=48, partName='torso'), animPie), Func(toon.loop, 'neutral'))), (16.0 / 24.0, Func(pie.detachNode))) fly = Track((14.0 / 24.0, SoundInterval(sound, node=toon)), (16.0 / 24.0, Sequence(Func(flyPie.reparentTo, render), Func(flyPie.setPosHpr, toon, 0.52, 0.97, 2.24, 0, -45, 0), beginFlyIval, ProjectileInterval(flyPie, startVel=getVelocity, duration=6), Func(flyPie.detachNode)))) return (toss, fly, flyPie) def handlePieHitting(self, colEntry): if self.gameIsEnding: return into = colEntry.getIntoNodePath() intoName = into.getName() if 'CogThiefPieSphere' in intoName: timestamp = globalClockDelta.localToNetworkTime(globalClock.getFrameTime(), bits=32) parts = intoName.split('-') suitNum = int(parts[1]) pos = self.cogInfo[suitNum]['suit'].suit.getPos() if pos in CTGG.CogStartingPositions: self.notify.debug('Cog %d hit at starting pos %s, ignoring' % (suitNum, pos)) else: self.sendUpdate('pieHitSuit', [self.localAvId, timestamp, suitNum, pos[0], pos[1], pos[2]]) self.makeSuitRespondToPieHit(timestamp, suitNum) def pieHitSuit(self, avId, timestamp, suitNum, x, y, z): if not self.hasLocalToon: return if self.gameFSM.getCurrentState().getName() not in ['play']: self.notify.warning('ignoring msg: av %s hit by suit' % avId) return if self.gameIsEnding: return self.notify.debug('avatar ' + `avId` + ' hit by a suit') if avId != self.localAvId: self.makeSuitRespondToPieHit(timestamp, suitNum) def makeSuitRespondToPieHit(self, timestamp, suitNum): cog = self.cogInfo[suitNum]['suit'] cog.respondToPieHit(timestamp) def sendCogAtReturnPos(self, cogIndex, barrelIndex): timestamp = globalClockDelta.localToNetworkTime(globalClock.getFrameTime(), bits=32) self.sendUpdate('cogAtReturnPos', [timestamp, cogIndex, barrelIndex]) def markBarrelStolen(self, timestamp, inResponseToClientStamp, barrelIndex): if not self.hasLocalToon: return if barrelIndex not in self.stolenBarrels: self.stolenBarrels.append(barrelIndex) barrel = self.barrels[barrelIndex] barrel.hide() if base.config.GetBool('cog-thief-check-barrels', 1): if not base.config.GetBool('cog-thief-endless', 0): if len(self.stolenBarrels) == len(self.barrels): localStamp = globalClockDelta.networkToLocalTime(timestamp, bits=32) gameTime = self.local2GameTime(localStamp) self.clockStopTime = gameTime self.notify.debug('clockStopTime = %s' % gameTime) score = int(self.scoreMult * CTGG.calcScore(gameTime) + 0.5) self.rewardPanel['text'] = str(score) self.showResults() def __gameTimerExpired(self): self.notify.debug('game timer expired') self.showResults() def __startRewardCountdown(self): taskMgr.remove(self.REWARD_COUNTDOWN_TASK) taskMgr.add(self.__updateRewardCountdown, self.REWARD_COUNTDOWN_TASK) def __killRewardCountdown(self): taskMgr.remove(self.REWARD_COUNTDOWN_TASK) def __updateRewardCountdown(self, task): curTime = self.getCurrentGameTime() if self.clockStopTime is not None: if self.clockStopTime < curTime: self.notify.debug('self.clockStopTime < curTime %s %s' % (self.clockStopTime, curTime)) self.__killRewardCountdown() curTime = self.clockStopTime if curTime > CTGG.GameTime: curTime = CTGG.GameTime score = int(self.scoreMult * CTGG.calcScore(curTime) + 0.5) if not hasattr(task, 'curScore'): task.curScore = score result = Task.cont if hasattr(self, 'rewardPanel'): self.rewardPanel['text'] = str(score) if task.curScore != score: if hasattr(self, 'jarIval'): self.jarIval.finish() s = self.rewardPanel.getScale() self.jarIval = Parallel(Sequence(self.rewardPanel.scaleInterval(0.15, s * 3.0 / 4.0, blendType='easeOut'), self.rewardPanel.scaleInterval(0.15, s, blendType='easeIn')), SoundInterval(self.sndRewardTick), name='cogThiefGameRewardJarThrob') self.jarIval.start() task.curScore = score else: result = Task.done return result def startGameWalk(self): self.gameWalk.start() def stopGameWalk(self): self.gameWalk.stop() def getCogThief(self, cogIndex): return self.cogInfo[cogIndex]['suit'] def isToonPlayingHitTrack(self, avId): if avId in self.toonHitTracks: track = self.toonHitTracks[avId] if track.isPlaying(): return True return False def getNumCogs(self): result = base.config.GetInt('cog-thief-num-cogs', 0) if not result: safezone = self.getSafezoneId() result = CTGG.calculateCogs(self.numPlayers, safezone) return result def getCogSpeed(self): result = 6.0 safezone = self.getSafezoneId() result = CTGG.calculateCogSpeed(self.numPlayers, safezone) return result def showResults(self): if not self.gameIsEnding: self.gameIsEnding = True for barrel in self.barrels: barrel.wrtReparentTo(render) for key in self.cogInfo: thief = self.cogInfo[key]['suit'] thief.suit.setPos(100, 0, 0) thief.suit.hide() self.__killRewardCountdown() self.stopGameWalk() numBarrelsSaved = len(self.barrels) - len(self.stolenBarrels) resultStr = '' if numBarrelsSaved == len(self.barrels): resultStr = TTLocalizer.CogThiefPerfect elif numBarrelsSaved > 1: resultStr = TTLocalizer.CogThiefBarrelsSaved % {'num': numBarrelsSaved} elif numBarrelsSaved == 1: resultStr = TTLocalizer.CogThiefBarrelSaved % {'num': numBarrelsSaved} else: resultStr = TTLocalizer.CogThiefNoBarrelsSaved perfectTextSubnode = hidden.attachNewNode(self.__genText(resultStr)) perfectText = hidden.attachNewNode('perfectText') perfectTextSubnode.reparentTo(perfectText) frame = self.__textGen.getCardActual() offsetY = -abs(frame[2] + frame[3]) / 2.0 perfectTextSubnode.setPos(0, 0, offsetY) perfectText.setColor(1, 0.1, 0.1, 1) def fadeFunc(t, text = perfectText): text.setColorScale(1, 1, 1, t) def destroyText(text = perfectText): text.removeNode() def safeGameOver(self = self): if not self.frameworkFSM.isInternalStateInFlux(): self.gameOver() textTrack = Sequence(Func(perfectText.reparentTo, aspect2d), Parallel(LerpScaleInterval(perfectText, duration=0.5, scale=0.3, startScale=0.0), LerpFunctionInterval(fadeFunc, fromData=0.0, toData=1.0, duration=0.5)), Wait(2.0), Parallel(LerpScaleInterval(perfectText, duration=0.5, scale=1.0), LerpFunctionInterval(fadeFunc, fromData=1.0, toData=0.0, duration=0.5, blendType='easeIn')), Func(destroyText), WaitInterval(0.5), Func(safeGameOver)) if numBarrelsSaved == len(self.barrels): soundTrack = SoundInterval(self.sndPerfect) else: soundTrack = Sequence() self.resultIval = Parallel(textTrack, soundTrack) self.resultIval.start() def __genText(self, text): self.__textGen.setText(text) return self.__textGen.generate() def getIntroTrack(self): base.camera.setPosHpr(0, -13.66, 13.59, 0, -51.6, 0) result = Sequence(Wait(2), LerpPosHprInterval(base.camera, 13, Point3(self.cameraTopView[0], self.cameraTopView[1], self.cameraTopView[2]), Point3(self.cameraTopView[3], self.cameraTopView[4], self.cameraTopView[5]), blendType='easeIn')) return result
class CollisionManager: def __init__(self): self.line_dir = NodePath() base.cTrav = CollisionTraverser() self.col_handler = CollisionHandlerEvent() picker_node = CollisionNode("mouseRayNode") pickerNPos = base.camera.attachNewNode(picker_node) self.pickerRay = CollisionRay() picker_node.addSolid(self.pickerRay) plane_node = CollisionNode("base_plane") plane = base.render.attachNewNode(plane_node) self.plane_col = CollisionPlane(Plane(Vec3(0, 0, 1), Point3(0, 0, 0))) picker_node.addSolid(self.pickerRay) picker_node.setTag("rays", "mray") base.cTrav.addCollider(pickerNPos, self.col_handler) self.col_handler.addInPattern("%(rays)ft-into-%(type)it") self.col_handler.addOutPattern("%(rays)ft-out-%(type)it") self.col_handler.addAgainPattern("ray_again_all%(" "rays" ")fh%(" "type" ")ih") self.model = loader.loadModel("../models/chest.egg") self.model_node = NodePath("sdfafd") self.model.reparentTo(self.model_node) self.model_node.reparentTo(render) # # self.text_node = TextNode("battle_text") # self.text_node.setText("TEXTYTEXTYTEXTTEXT") # self.text_node_path = render.attachNewNode(self.text_node) # self.text_node_path.reparentTo(render) # self.text_node_path.setPos(0,0,4) # self.text_node_path.setHpr(0,0,0) # self.text_node_path.setScale(1) # #self.text_node_path.setTransparency(TransparencyAttrib.MAlpha) # self.text_node.setTextColor((1,1,1,1)) # self.text_node.setAlign(TextNode.ALeft) self.placement_ghost = EditorObjects.PlacementGhost( 0, "tower", base.object_scale) z = 0 self.plane = Plane(Vec3(0, 0, 1), Point3(0, 0, z)) taskMgr.add(self.ray_update, "updatePicker") taskMgr.add(self.get_mouse_plane_pos, "MousePositionOnPlane") taskMgr.add(self.task_mouse_press_check, "checkMousePress") self.input_init() self.pickable = None def input_init(self): self.DO = DirectObject() self.DO.accept('mouse1', self.mouse_click, ["1-down"]) self.DO.accept('mouse1-up', self.mouse_click, ["1-up"]) self.DO.accept('mouse3', self.mouse_click, ["3-down"]) self.DO.accept('0', self.placement_ghost.change_player, [0]) self.DO.accept('1', self.placement_ghost.change_player, [1]) self.DO.accept('2', self.placement_ghost.change_player, [2]) self.DO.accept('a', self.placement_ghost.change_type, ["army"]) self.DO.accept('t', self.placement_ghost.change_type, ["tower"]) self.DO.accept('control-s', base.xml_manager.save) self.DO.accept('mray-into-army', self.col_in_object) self.DO.accept('mray-out-army', self.col_out_object) self.DO.accept('mray-into-tower', self.col_in_object) self.DO.accept('mray-out-tower', self.col_out_object) self.DO.accept('ray_again_all', self.col_against_object) def col_against_object(self, entry): if entry.getIntoNodePath().getParent() != self.pickable: np_from = entry.getFromNodePath() np_into = entry.getIntoNodePath() self.selected_type = np_into.getTag("type") self.pickable = np_into.getParent() def col_in_object(self, entry): if base.state == "selecting": np_into = entry.getIntoNodePath() np_into.getParent().setColor(0.5, 0.5, 0.5, 1) def col_out_object(self, entry): np_into = entry.getIntoNodePath() try: np_into.getParent().clearColor() except: print "ERROR CLEARING COLOUR" def get_mouse_plane_pos(self, task): if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.pos3d = Point3() nearPoint = Point3() farPoint = Point3() base.camLens.extrude(mpos, nearPoint, farPoint) if self.plane.intersectsLine( self.pos3d, render.getRelativePoint(camera, nearPoint), render.getRelativePoint(camera, farPoint)): #print "Mouse ray intersects ground plane at ", self.pos3d self.model_node.setPos(render, self.pos3d) self.placement_ghost.set_position(self.pos3d[0], self.pos3d[1]) return task.again def ray_update(self, task): if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) return task.cont def task_mouse_place(self, task): if base.mouseWatcherNode.isButtonDown(MouseButton.one()): self.placing_object = True self.place_pos = (self.anchor_x, self.anchor_y) self.line_dir.remove() ls = LineSegs() ls.move_to(self.anchor_x, self.anchor_y, 1) ls.draw_to(self.model.getX(), self.model.getY(), 1) node = ls.create() angle1 = math.atan2(self.anchor_y - self.anchor_y, self.anchor_x - self.anchor_x + 50) angle2 = math.atan2(self.anchor_y - self.model.getY(), self.anchor_x - self.model.getY()) final_angle = angle1 - angle2 self.model.setHpr(final_angle, 0, 0) self.line_dir = NodePath(node) self.line_dir.reparentTo(render) return task.again else: self.line_dir.hide() taskMgr.add(self.task_mouse_press_check, "checkMousePress") return task.done def task_mouse_press_check(self, task): if base.mouseWatcherNode.isButtonDown(MouseButton.one()): #if self.multi_select == True: self.anchor_x, self.anchor_y = self.model.getX(), self.model.getY() taskMgr.add(self.task_mouse_place, "multibox") return task.done return task.again def mouse_click(self, status): print base.state if status == "1-down": if base.state == "placement": if self.placement_ghost.get_type() == "tower": obj = self.placement_ghost.place("tower", self.model.getX(), self.model.getY()) elif self.placement_ghost.get_type() == "army": obj = self.placement_ghost.place("army", self.model.getX(), self.model.getY()) base.details_box.set_object(obj) base.change_state("modifying") elif base.state == "moving": obj = base.details_box.get_object() obj.set_position(self.pos3d[0], self.pos3d[1]) base.change_state("modifying") elif base.state == "selecting" and self.pickable != None: obj = base.get_obj_from_node(self.pickable) base.details_box.set_object(obj, "selecting") base.change_state("modifying") elif status == "1-up": print "Mouse", status elif status == "3-down": if base.state == "placement": base.change_state("selecting") elif base.state == "selecting": base.change_state("placement")
class FreeBLiTZ(ShowBase): def __init__(self): from pandac.PandaModules import CollisionHandlerFloor, CollisionHandlerPusher, CollisionHandlerEvent, CollisionTraverser from pandac.PandaModules import DirectionalLight, AmbientLight, VBase4 ShowBase.__init__(self) self.sky = self.loader.loadModel('models/sky-sphere') self.sky.reparentTo(self.render) self.stage = self.loader.loadModel('models/test-collide') self.stage.reparentTo(self.render) self.floor = self.stage.findAllMatches('**/=CollideType=floor') self.floor.setCollideMask(FLOOR_MASK) self.obstacles = self.stage.findAllMatches('**/=CollideType=obstacle') if self.obstacles: self.obstacles.setCollideMask(OBSTACLE_MASK) self.zones = self.stage.findAllMatches('**/=CollideType=zone') if self.zones: self.zones.setCollideMask(ZONE_MASK) self.create_stanchions() # Character rig, which allows camera to follow character self.char_rig = self.stage.attachNewNode('char_rig') self.active_char = Character('mainchar', self.char_rig) self.cam.reparentTo(self.char_rig) self.cam.setPos(0.5, -3, 1.5) self.cam.lookAt(0.5, 0, 1.5) self.light = DirectionalLight('dlight') self.light.setColor(VBase4(0.3, 0.28, 0.26, 1.0)) self.lightNP = self.stage.attachNewNode(self.light) self.lightNP.setHpr(-75, -45, 0) self.stage.setLight(self.lightNP) self.amblight = AmbientLight('amblight') self.amblight.setColor(VBase4(0.7, 0.68, 0.66, 1.0)) self.amblightNP = self.stage.attachNewNode(self.amblight) self.stage.setLight(self.amblightNP) self.accept('w', self.active_char.begin_forward) self.accept('a', self.active_char.begin_left) self.accept('s', self.active_char.begin_backward) self.accept('d', self.active_char.begin_right) self.accept('w-up', self.active_char.end_forward) self.accept('a-up', self.active_char.end_left) self.accept('s-up', self.active_char.end_backward) self.accept('d-up', self.active_char.end_right) self.taskMgr.add(self.active_char.MoveTask, 'MoveTask') self.look = False self.prev_pos = None self.accept('mouse2', self.begin_look) self.accept('mouse2-up', self.end_look) self.accept('mouse3', self.active_char.begin_spin) self.accept('mouse3-up', self.active_char.end_spin) self.taskMgr.add(self.MouseTask, 'MouseTask') self.floor_handler = CollisionHandlerFloor() self.floor_handler.addCollider(self.active_char.actor_from_floor, self.char_rig) self.wall_handler = CollisionHandlerPusher() self.wall_handler.addCollider(self.active_char.actor_from_obstacle, self.char_rig) self.zone_handler = CollisionHandlerEvent() self.zone_handler.addInPattern('%fn-into') self.zone_handler.addOutPattern('%fn-out') def foo(entry): print 'You are in the zone' def bar(entry): print 'You are not in the zone' self.accept('blockchar_zone-into', foo) self.accept('blockchar_zone-out', bar) self.cTrav = CollisionTraverser('main traverser') self.cTrav.setRespectPrevTransform(True) self.cTrav.addCollider(self.active_char.actor_from_floor, self.floor_handler) self.cTrav.addCollider(self.active_char.actor_from_obstacle, self.wall_handler) self.cTrav.addCollider(self.active_char.actor_from_zone, self.zone_handler) #self.cTrav.showCollisions(self.stage) def create_stanchions(self): from pandac.PandaModules import GeomVertexReader, CollisionNode, CollisionTube self.stanchions = self.stage.findAllMatches('**/=Stanchion') for stanchion in self.stanchions: geomnode = stanchion.node() radius = float(stanchion.getTag('Stanchion')) geom = geomnode.getGeom(0) vdata = geom.getVertexData() for gp in range(geom.getNumPrimitives()): vreader = GeomVertexReader(vdata, 'vertex') prim = geom.getPrimitive(gp) prim = prim.decompose() for p in range(prim.getNumPrimitives()): start = prim.getPrimitiveStart(p) end = prim.getPrimitiveEnd(p) vertices = [] for v in range(start, end): vi = prim.getVertex(v) vreader.setRow(vi) vertex = vreader.getData3f() vertices.append(vertex) vertices.append(vertices[0]) for i in range(1, len(vertices)): a, b = vertices[i-1], vertices[i] stanchion_np = stanchion.attachNewNode(CollisionNode('stanchion')) print 'creating cyl with radius %f from %s to %s' % (radius, a, b) stanchion_np.node().addSolid(CollisionTube(a[0], a[1], a[2], b[0], b[1], b[2], radius)) stanchion_np.node().setFromCollideMask(OBSTACLE_MASK) geomnode.removeAllGeoms() def begin_look(self): self.look = True def end_look(self): self.look = False self.prev_pos = None def MouseTask(self, task): if self.mouseWatcherNode.hasMouse(): (x, y) = self.mouseWatcherNode.getMouse() if self.prev_pos: if self.look or self.active_char.spinning: h_diff = (x - self.prev_pos[0]) * 180 p_diff = (y - self.prev_pos[1]) * 90 new_h = clamp_deg_sign(self.char_rig.getH() - h_diff) self.char_rig.setH(new_h) self.cam.setP(self.cam.getP() + p_diff) self.active_char.spin(new_h) self.prev_pos = (x, y) return task.cont
class CogdoFlyingCollisions(GravityWalker): wantFloorSphere = 0 def __init__(self): GravityWalker.__init__(self, gravity=0.0) def initializeCollisions(self, collisionTraverser, avatarNodePath, avatarRadius=1.4, floorOffset=1.0, reach=1.0): self.cHeadSphereNodePath = None self.cFloorEventSphereNodePath = None self.setupHeadSphere(avatarNodePath) self.setupFloorEventSphere(avatarNodePath, ToontownGlobals.FloorEventBitmask, avatarRadius) GravityWalker.initializeCollisions(self, collisionTraverser, avatarNodePath, avatarRadius, floorOffset, reach) return def setupWallSphere(self, bitmask, avatarRadius): self.avatarRadius = avatarRadius cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75, self.avatarRadius) cSphereNode = CollisionNode('Flyer.cWallSphereNode') cSphereNode.addSolid(cSphere) cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) if config.GetBool('want-fluid-pusher', 0): self.pusher = CollisionHandlerFluidPusher() else: self.pusher = CollisionHandlerPusher() self.pusher.addCollider(cSphereNodePath, self.avatarNodePath) self.cWallSphereNodePath = cSphereNodePath def setupEventSphere(self, bitmask, avatarRadius): self.avatarRadius = avatarRadius cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75, self.avatarRadius * 1.04) cSphere.setTangible(0) cSphereNode = CollisionNode('Flyer.cEventSphereNode') cSphereNode.addSolid(cSphere) cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) self.event = CollisionHandlerEvent() self.event.addInPattern('enter%in') self.event.addOutPattern('exit%in') self.cEventSphereNodePath = cSphereNodePath def setupRay(self, bitmask, floorOffset, reach): cRay = CollisionRay(0.0, 0.0, 3.0, 0.0, 0.0, -1.0) cRayNode = CollisionNode('Flyer.cRayNode') cRayNode.addSolid(cRay) self.cRayNodePath = self.avatarNodePath.attachNewNode(cRayNode) cRayNode.setFromCollideMask(bitmask) cRayNode.setIntoCollideMask(BitMask32.allOff()) self.lifter = CollisionHandlerGravity() self.lifter.setLegacyMode(self._legacyLifter) self.lifter.setGravity(self.getGravity(0)) self.lifter.addInPattern('%fn-enter-%in') self.lifter.addAgainPattern('%fn-again-%in') self.lifter.addOutPattern('%fn-exit-%in') self.lifter.setOffset(floorOffset) self.lifter.setReach(reach) self.lifter.addCollider(self.cRayNodePath, self.avatarNodePath) def setupHeadSphere(self, avatarNodePath): collSphere = CollisionSphere(0, 0, 0, 1) collSphere.setTangible(1) collNode = CollisionNode('Flyer.cHeadCollSphere') collNode.setFromCollideMask(ToontownGlobals.CeilingBitmask) collNode.setIntoCollideMask(BitMask32.allOff()) collNode.addSolid(collSphere) self.cHeadSphereNodePath = avatarNodePath.attachNewNode(collNode) self.cHeadSphereNodePath.setZ(base.localAvatar.getHeight() + 1.0) self.headCollisionEvent = CollisionHandlerEvent() self.headCollisionEvent.addInPattern('%fn-enter-%in') self.headCollisionEvent.addOutPattern('%fn-exit-%in') base.cTrav.addCollider(self.cHeadSphereNodePath, self.headCollisionEvent) def setupFloorEventSphere(self, avatarNodePath, bitmask, avatarRadius): cSphere = CollisionSphere(0.0, 0.0, 0.0, 0.75) cSphereNode = CollisionNode('Flyer.cFloorEventSphere') cSphereNode.addSolid(cSphere) cSphereNodePath = avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) self.floorCollisionEvent = CollisionHandlerEvent() self.floorCollisionEvent.addInPattern('%fn-enter-%in') self.floorCollisionEvent.addAgainPattern('%fn-again-%in') self.floorCollisionEvent.addOutPattern('%fn-exit-%in') base.cTrav.addCollider(cSphereNodePath, self.floorCollisionEvent) self.cFloorEventSphereNodePath = cSphereNodePath def deleteCollisions(self): GravityWalker.deleteCollisions(self) if self.cHeadSphereNodePath != None: base.cTrav.removeCollider(self.cHeadSphereNodePath) self.cHeadSphereNodePath.detachNode() self.cHeadSphereNodePath = None self.headCollisionsEvent = None if self.cFloorEventSphereNodePath != None: base.cTrav.removeCollider(self.cFloorEventSphereNodePath) self.cFloorEventSphereNodePath.detachNode() self.cFloorEventSphereNodePath = None self.floorCollisionEvent = None self.cRayNodePath.detachNode() del self.cRayNodePath self.cEventSphereNodePath.detachNode() del self.cEventSphereNodePath return def setCollisionsActive(self, active=1): if self.collisionsActive != active: if self.cHeadSphereNodePath != None: base.cTrav.removeCollider(self.cHeadSphereNodePath) if active: base.cTrav.addCollider(self.cHeadSphereNodePath, self.headCollisionEvent) if self.cFloorEventSphereNodePath != None: base.cTrav.removeCollider(self.cFloorEventSphereNodePath) if active: base.cTrav.addCollider(self.cFloorEventSphereNodePath, self.floorCollisionEvent) GravityWalker.setCollisionsActive(self, active) return def enableAvatarControls(self): pass def disableAvatarControls(self): pass def handleAvatarControls(self, task): pass
from pandac.PandaModules import CollisionHandlerEvent, CollisionNode, CollisionTraverser, CollisionRay from pandaImports import DirectObject from tower import * """This file handles all the collision events of our game """ # base.cTrav maintains a list of colliders of all solid objects in the world to check collisions (runs every frame) base.cTrav = CollisionTraverser() # collisionHandler specifies what to do when a collision event is detected collisionHandler = CollisionHandlerEvent() # "In" event: when there is a collision in the current frame, but it didn't in the previous frame collisionHandler.addInPattern("%fn-into-%in") # "Again" event: when there is a collision in the current frame, the same that happened in the previous frame collisionHandler.addAgainPattern("%fn-again-%in") # "Out" event: when there isn't a collision in the current frame, but there was in the previous frame collisionHandler.addOutPattern("%fn-out-%in") # self.collision3DPoint is the point where the collision occurs collision3DPoint = [0, 0, 0] # self.addCollider(mousePicking.pickerNP) # self.addCollider(player.getTower(-1).troop.troopModel.troopColliderNP) DO = DirectObject() def addCollisionEventAgain(fromName, intoName, function, extraArgs=[]):
class DistributedIceGame(DistributedMinigame.DistributedMinigame, DistributedIceWorld.DistributedIceWorld): notify = directNotify.newCategory('DistributedIceGame') MaxLocalForce = 100 MaxPhysicsForce = 25000 def __init__(self, cr): DistributedMinigame.DistributedMinigame.__init__(self, cr) DistributedIceWorld.DistributedIceWorld.__init__(self, cr) self.gameFSM = ClassicFSM.ClassicFSM('DistributedIceGame', [ State.State('off', self.enterOff, self.exitOff, ['inputChoice']), State.State( 'inputChoice', self.enterInputChoice, self.exitInputChoice, ['waitServerChoices', 'moveTires', 'displayVotes', 'cleanup']), State.State('waitServerChoices', self.enterWaitServerChoices, self.exitWaitServerChoices, ['moveTires', 'cleanup']), State.State('moveTires', self.enterMoveTires, self.exitMoveTires, ['synch', 'cleanup']), State.State('synch', self.enterSynch, self.exitSynch, ['inputChoice', 'scoring', 'cleanup']), State.State('scoring', self.enterScoring, self.exitScoring, ['cleanup', 'finalResults', 'inputChoice']), State.State('finalResults', self.enterFinalResults, self.exitFinalResults, ['cleanup']), State.State('cleanup', self.enterCleanup, self.exitCleanup, []) ], 'off', 'cleanup') self.addChildGameFSM(self.gameFSM) self.cameraThreeQuarterView = (0, -22, 45, 0, -62.890000000000001, 0) self.tireDict = {} self.forceArrowDict = {} self.canDrive = False self.timer = None self.timerStartTime = None self.curForce = 0 self.curHeading = 0 self.headingMomentum = 0.0 self.forceMomentum = 0.0 self.allTireInputs = None self.curRound = 0 self.curMatch = 0 self.controlKeyWarningLabel = DirectLabel( text=TTLocalizer.IceGameControlKeyWarning, text_fg=VBase4(1, 0, 0, 1), relief=None, pos=(0.0, 0, 0), scale=0.14999999999999999) self.controlKeyWarningLabel.hide() self.waitingMoveLabel = DirectLabel( text=TTLocalizer.IceGameWaitingForPlayersToFinishMove, text_fg=VBase4(1, 1, 1, 1), relief=None, pos=(-0.59999999999999998, 0, -0.75), scale=0.074999999999999997) self.waitingMoveLabel.hide() self.waitingSyncLabel = DirectLabel( text=TTLocalizer.IceGameWaitingForAISync, text_fg=VBase4(1, 1, 1, 1), relief=None, pos=(-0.59999999999999998, 0, -0.75), scale=0.074999999999999997) self.waitingSyncLabel.hide() self.infoLabel = DirectLabel(text='', text_fg=VBase4(0, 0, 0, 1), relief=None, pos=(0.0, 0, 0.69999999999999996), scale=0.074999999999999997) self.updateInfoLabel() self.lastForceArrowUpdateTime = 0 self.sendForceArrowUpdateAsap = False self.treasures = [] self.penalties = [] self.obstacles = [] self.controlKeyPressed = False self.controlKeyWarningIval = None def delete(self): DistributedIceWorld.DistributedIceWorld.delete(self) DistributedMinigame.DistributedMinigame.delete(self) if self.controlKeyWarningIval: self.controlKeyWarningIval.finish() self.controlKeyWarningIval = None self.controlKeyWarningLabel.destroy() del self.controlKeyWarningLabel self.waitingMoveLabel.destroy() del self.waitingMoveLabel self.waitingSyncLabel.destroy() del self.waitingSyncLabel self.infoLabel.destroy() del self.infoLabel for treasure in self.treasures: treasure.destroy() del self.treasures for penalty in self.penalties: penalty.destroy() del self.penalties for obstacle in self.obstacles: obstacle.removeNode() del self.obstacles del self.gameFSM def announceGenerate(self): DistributedMinigame.DistributedMinigame.announceGenerate(self) DistributedIceWorld.DistributedIceWorld.announceGenerate(self) self.debugTaskName = self.uniqueName('debugTask') def getTitle(self): return TTLocalizer.IceGameTitle def getInstructions(self): szId = self.getSafezoneId() numPenalties = IceGameGlobals.NumPenalties[szId] result = TTLocalizer.IceGameInstructions if numPenalties == 0: result = TTLocalizer.IceGameInstructionsNoTnt return result def getMaxDuration(self): return 0 def load(self): self.notify.debug('load') DistributedMinigame.DistributedMinigame.load(self) self.music = base.loadMusic('phase_4/audio/bgm/MG_IceGame.mid') self.gameBoard = loader.loadModel( 'phase_4/models/minigames/ice_game_icerink') background = loader.loadModel('phase_4/models/minigames/ice_game_2d') background.reparentTo(self.gameBoard) self.gameBoard.setPosHpr(0, 0, 0, 0, 0, 0) self.gameBoard.setScale(1.0) self.setupSimulation() index = 0 for avId in self.avIdList: self.setupTire(avId, index) self.setupForceArrow(avId) index += 1 for index in xrange(len(self.avIdList), 4): self.setupTire(-index, index) self.setupForceArrow(-index) self.showForceArrows(realPlayersOnly=True) self.westWallModel = NodePath() if not self.westWallModel.isEmpty(): self.westWallModel.reparentTo(self.gameBoard) self.westWallModel.setPos(IceGameGlobals.MinWall[0], IceGameGlobals.MinWall[1], 0) self.westWallModel.setScale(4) self.eastWallModel = NodePath() if not self.eastWallModel.isEmpty(): self.eastWallModel.reparentTo(self.gameBoard) self.eastWallModel.setPos(IceGameGlobals.MaxWall[0], IceGameGlobals.MaxWall[1], 0) self.eastWallModel.setScale(4) self.eastWallModel.setH(180) self.arrowKeys = ArrowKeys.ArrowKeys() self.target = loader.loadModel('phase_3/models/misc/sphere') self.target.setScale(0.01) self.target.reparentTo(self.gameBoard) self.target.setPos(0, 0, 0) self.scoreCircle = loader.loadModel( 'phase_4/models/minigames/ice_game_score_circle') self.scoreCircle.setScale(0.01) self.scoreCircle.reparentTo(self.gameBoard) self.scoreCircle.setZ(IceGameGlobals.TireRadius / 2.0) self.scoreCircle.setAlphaScale(0.5) self.scoreCircle.setTransparency(1) self.scoreCircle.hide() self.treasureModel = loader.loadModel( 'phase_4/models/minigames/ice_game_barrel') self.penaltyModel = loader.loadModel( 'phase_4/models/minigames/ice_game_tnt2') self.penaltyModel.setScale(0.75, 0.75, 0.69999999999999996) szId = self.getSafezoneId() obstacles = IceGameGlobals.Obstacles[szId] index = 0 cubicObstacle = IceGameGlobals.ObstacleShapes[szId] for pos in obstacles: newPos = Point3(pos[0], pos[1], IceGameGlobals.TireRadius) newObstacle = self.createObstacle(newPos, index, cubicObstacle) self.obstacles.append(newObstacle) index += 1 self.countSound = loader.loadSfx( 'phase_3.5/audio/sfx/tick_counter.mp3') self.treasureGrabSound = loader.loadSfx( 'phase_4/audio/sfx/MG_sfx_vine_game_bananas.mp3') self.penaltyGrabSound = loader.loadSfx( 'phase_4/audio/sfx/MG_cannon_fire_alt.mp3') self.tireSounds = [] for tireIndex in xrange(4): tireHit = loader.loadSfx( 'phase_4/audio/sfx/Golf_Hit_Barrier_1.mp3') wallHit = loader.loadSfx('phase_4/audio/sfx/MG_maze_pickup.mp3') obstacleHit = loader.loadSfx( 'phase_4/audio/sfx/Golf_Hit_Barrier_2.mp3') self.tireSounds.append({ 'tireHit': tireHit, 'wallHit': wallHit, 'obstacleHit': obstacleHit }) self.arrowRotateSound = loader.loadSfx( 'phase_4/audio/sfx/MG_sfx_ice_force_rotate.wav') self.arrowUpSound = loader.loadSfx( 'phase_4/audio/sfx/MG_sfx_ice_force_increase_3sec.mp3') self.arrowDownSound = loader.loadSfx( 'phase_4/audio/sfx/MG_sfx_ice_force_decrease_3sec.mp3') self.scoreCircleSound = loader.loadSfx( 'phase_4/audio/sfx/MG_sfx_ice_scoring_1.mp3') def unload(self): self.notify.debug('unload') DistributedMinigame.DistributedMinigame.unload(self) del self.music self.gameBoard.removeNode() del self.gameBoard for forceArrow in self.forceArrowDict.values(): forceArrow.removeNode() del self.forceArrowDict self.scoreCircle.removeNode() del self.scoreCircle del self.countSound def onstage(self): self.notify.debug('onstage') DistributedMinigame.DistributedMinigame.onstage(self) self.gameBoard.reparentTo(render) self._DistributedIceGame__placeToon(self.localAvId) self.moveCameraToTop() self.scorePanels = [] base.playMusic(self.music, looping=1, volume=0.80000000000000004) def offstage(self): self.notify.debug('offstage') self.music.stop() self.gameBoard.hide() self.infoLabel.hide() for avId in self.tireDict: self.tireDict[avId]['tireNodePath'].hide() for panel in self.scorePanels: panel.cleanup() del self.scorePanels for obstacle in self.obstacles: obstacle.hide() for treasure in self.treasures: treasure.nodePath.hide() for penalty in self.penalties: penalty.nodePath.hide() for avId in self.avIdList: av = self.getAvatar(avId) if av: av.dropShadow.show() av.resetLOD() continue taskMgr.remove(self.uniqueName('aimtask')) self.arrowKeys.destroy() del self.arrowKeys DistributedMinigame.DistributedMinigame.offstage(self) def handleDisabledAvatar(self, avId): self.notify.debug('handleDisabledAvatar') self.notify.debug('avatar ' + str(avId) + ' disabled') DistributedMinigame.DistributedMinigame.handleDisabledAvatar( self, avId) def setGameReady(self): if not self.hasLocalToon: return None self.notify.debug('setGameReady') if DistributedMinigame.DistributedMinigame.setGameReady(self): return None for index in xrange(self.numPlayers): avId = self.avIdList[index] toon = self.getAvatar(avId) if toon: toon.reparentTo(render) self._DistributedIceGame__placeToon(avId) toon.forwardSpeed = 0 toon.rotateSpeed = False toon.dropShadow.hide() toon.setAnimState('Sit') if avId in self.tireDict: tireNp = self.tireDict[avId]['tireNodePath'] toon.reparentTo(tireNp) toon.setY(1.0) toon.setZ(-3) toon.startLookAround() continue def setGameStart(self, timestamp): if not self.hasLocalToon: return None self.notify.debug('setGameStart') DistributedMinigame.DistributedMinigame.setGameStart(self, timestamp) for avId in self.remoteAvIdList: toon = self.getAvatar(avId) if toon: toon.stopLookAround() continue self.scores = [0] * self.numPlayers spacing = 0.40000000000000002 for i in xrange(self.numPlayers): avId = self.avIdList[i] avName = self.getAvatarName(avId) scorePanel = MinigameAvatarScorePanel.MinigameAvatarScorePanel( avId, avName) scorePanel.setScale(0.90000000000000002) scorePanel.setPos(0.75 - spacing * (self.numPlayers - 1 - i), 0.0, 0.875) scorePanel.makeTransparent(0.75) self.scorePanels.append(scorePanel) self.arrowKeys.setPressHandlers([ self._DistributedIceGame__upArrowPressed, self._DistributedIceGame__downArrowPressed, self._DistributedIceGame__leftArrowPressed, self._DistributedIceGame__rightArrowPressed, self._DistributedIceGame__controlPressed ]) def isInPlayState(self): if not self.gameFSM.getCurrentState(): return False if not self.gameFSM.getCurrentState().getName() == 'play': return False return True def enterOff(self): self.notify.debug('enterOff') def exitOff(self): pass def enterInputChoice(self): self.notify.debug('enterInputChoice') self.forceLocalToonToTire() self.controlKeyPressed = False if self.curRound == 0: self.setupStartOfMatch() else: self.notify.debug('self.curRound = %s' % self.curRound) self.timer = ToontownTimer.ToontownTimer() self.timer.hide() if self.timerStartTime != None: self.startTimer() self.showForceArrows(realPlayersOnly=True) self.localForceArrow().setPosHpr(0, 0, -1.0, 0, 0, 0) self.localForceArrow().reparentTo(self.localTireNp()) self.localForceArrow().setY(IceGameGlobals.TireRadius) self.localTireNp().headsUp(self.target) self.notify.debug('self.localForceArrow() heading = %s' % self.localForceArrow().getH()) self.curHeading = self.localTireNp().getH() self.curForce = 25 self.updateLocalForceArrow() for avId in self.forceArrowDict: forceArrow = self.forceArrowDict[avId] forceArrow.setPosHpr(0, 0, -1.0, 0, 0, 0) tireNp = self.tireDict[avId]['tireNodePath'] forceArrow.reparentTo(tireNp) forceArrow.setY(IceGameGlobals.TireRadius) tireNp.headsUp(self.target) self.updateForceArrow(avId, tireNp.getH(), 25) taskMgr.add(self._DistributedIceGame__aimTask, self.uniqueName('aimtask')) if base.localAvatar.laffMeter: base.localAvatar.laffMeter.stop() self.sendForceArrowUpdateAsap = False def exitInputChoice(self): if not self.controlKeyPressed: if self.controlKeyWarningIval: self.controlKeyWarningIval.finish() self.controlKeyWarningIval = None self.controlKeyWarningIval = Sequence( Func(self.controlKeyWarningLabel.show), self.controlKeyWarningLabel.colorScaleInterval( 10, VBase4(1, 1, 1, 0), startColorScale=VBase4(1, 1, 1, 1)), Func(self.controlKeyWarningLabel.hide)) self.controlKeyWarningIval.start() if self.timer != None: self.timer.destroy() self.timer = None self.timerStartTime = None self.hideForceArrows() self.arrowRotateSound.stop() self.arrowUpSound.stop() self.arrowDownSound.stop() taskMgr.remove(self.uniqueName('aimtask')) def enterWaitServerChoices(self): self.waitingMoveLabel.show() self.showForceArrows(True) def exitWaitServerChoices(self): self.waitingMoveLabel.hide() self.hideForceArrows() def enterMoveTires(self): for key in self.tireDict: body = self.tireDict[key]['tireBody'] body.setAngularVel(0, 0, 0) body.setLinearVel(0, 0, 0) for index in xrange(len(self.allTireInputs)): input = self.allTireInputs[index] avId = self.avIdList[index] body = self.getTireBody(avId) degs = input[1] + 90 tireNp = self.getTireNp(avId) tireH = tireNp.getH() self.notify.debug('tireH = %s' % tireH) radAngle = deg2Rad(degs) foo = NodePath('foo') dirVector = Vec3(math.cos(radAngle), math.sin(radAngle), 0) self.notify.debug('dirVector is now=%s' % dirVector) inputForce = input[0] inputForce /= self.MaxLocalForce inputForce *= self.MaxPhysicsForce force = dirVector * inputForce self.notify.debug('adding force %s to %d' % (force, avId)) body.addForce(force) self.enableAllTireBodies() self.totalPhysicsSteps = 0 self.startSim() taskMgr.add(self._DistributedIceGame__moveTiresTask, self.uniqueName('moveTiresTtask')) def exitMoveTires(self): self.forceLocalToonToTire() self.disableAllTireBodies() self.stopSim() self.notify.debug('total Physics steps = %d' % self.totalPhysicsSteps) taskMgr.remove(self.uniqueName('moveTiresTtask')) def enterSynch(self): self.waitingSyncLabel.show() def exitSynch(self): self.waitingSyncLabel.hide() def enterScoring(self): sortedByDistance = [] for avId in self.avIdList: np = self.getTireNp(avId) pos = np.getPos() pos.setZ(0) sortedByDistance.append((avId, pos.length())) def compareDistance(x, y): if x[1] - y[1] > 0: return 1 elif x[1] - y[1] < 0: return -1 else: return 0 sortedByDistance.sort(cmp=compareDistance) self.scoreMovie = Sequence() curScale = 0.01 curTime = 0 self.scoreCircle.setScale(0.01) self.scoreCircle.show() self.notify.debug('newScores = %s' % self.newScores) circleStartTime = 0 for index in xrange(len(sortedByDistance)): distance = sortedByDistance[index][1] avId = sortedByDistance[index][0] scorePanelIndex = self.avIdList.index(avId) time = (distance - curScale) / IceGameGlobals.ExpandFeetPerSec if time < 0: time = 0.01 scaleXY = distance + IceGameGlobals.TireRadius self.notify.debug('circleStartTime = %s' % circleStartTime) self.scoreMovie.append( Parallel( LerpScaleInterval(self.scoreCircle, time, Point3(scaleXY, scaleXY, 1.0)), SoundInterval(self.scoreCircleSound, duration=time, startTime=circleStartTime))) circleStartTime += time startScore = self.scorePanels[scorePanelIndex].getScore() destScore = self.newScores[scorePanelIndex] self.notify.debug('for avId %d, startScore=%d, newScores=%d' % (avId, startScore, destScore)) def increaseScores(t, scorePanelIndex=scorePanelIndex, startScore=startScore, destScore=destScore): oldScore = self.scorePanels[scorePanelIndex].getScore() diff = destScore - startScore newScore = int(startScore + diff * t) if newScore > oldScore: base.playSfx(self.countSound) self.scorePanels[scorePanelIndex].setScore(newScore) self.scores[scorePanelIndex] = newScore duration = (destScore - startScore) * IceGameGlobals.ScoreCountUpRate tireNp = self.tireDict[avId]['tireNodePath'] self.scoreMovie.append( Parallel( LerpFunctionInterval(increaseScores, duration), Sequence( LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 0, 0, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 1, 1, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 0, 0, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 1, 1, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 0, 0, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 1, 1, 1))))) curScale += distance self.scoreMovie.append( Func(self.sendUpdate, 'reportScoringMovieDone', [])) self.scoreMovie.start() def exitScoring(self): self.scoreMovie.finish() self.scoreMovie = None self.scoreCircle.hide() def enterFinalResults(self): lerpTrack = Parallel() lerpDur = 0.5 tY = 0.59999999999999998 bY = -0.050000000000000003 lX = -0.5 cX = 0 rX = 0.5 scorePanelLocs = (((cX, bY), ), ((lX, bY), (rX, bY)), ((cX, tY), (lX, bY), (rX, bY)), ((lX, tY), (rX, tY), (lX, bY), (rX, bY))) scorePanelLocs = scorePanelLocs[self.numPlayers - 1] for i in xrange(self.numPlayers): panel = self.scorePanels[i] pos = scorePanelLocs[i] lerpTrack.append( Parallel( LerpPosInterval(panel, lerpDur, Point3(pos[0], 0, pos[1]), blendType='easeInOut'), LerpScaleInterval(panel, lerpDur, Vec3(panel.getScale()) * 2.0, blendType='easeInOut'))) self.showScoreTrack = Parallel( lerpTrack, Sequence(Wait(IceGameGlobals.ShowScoresDuration), Func(self.gameOver))) self.showScoreTrack.start() def exitFinalResults(self): self.showScoreTrack.pause() del self.showScoreTrack def enterCleanup(self): self.notify.debug('enterCleanup') if base.localAvatar.laffMeter: base.localAvatar.laffMeter.start() def exitCleanup(self): pass def _DistributedIceGame__placeToon(self, avId): toon = self.getAvatar(avId) if toon: toon.setPos(0, 0, 0) toon.setHpr(0, 0, 0) def moveCameraToTop(self): camera.reparentTo(render) p = self.cameraThreeQuarterView camera.setPosHpr(p[0], p[1], p[2], p[3], p[4], p[5]) def setupTire(self, avId, index): (tireNp, tireBody, tireOdeGeom) = self.createTire(index) self.tireDict[avId] = { 'tireNodePath': tireNp, 'tireBody': tireBody, 'tireOdeGeom': tireOdeGeom } if avId <= 0: tireBlocker = tireNp.find('**/tireblockermesh') if not tireBlocker.isEmpty(): tireBlocker.hide() if avId == self.localAvId: tireNp = self.tireDict[avId]['tireNodePath'] self.treasureSphereName = 'treasureCollider' self.treasureCollSphere = CollisionSphere( 0, 0, 0, IceGameGlobals.TireRadius) self.treasureCollSphere.setTangible(0) self.treasureCollNode = CollisionNode(self.treasureSphereName) self.treasureCollNode.setFromCollideMask( ToontownGlobals.PieBitmask) self.treasureCollNode.addSolid(self.treasureCollSphere) self.treasureCollNodePath = tireNp.attachNewNode( self.treasureCollNode) self.treasureHandler = CollisionHandlerEvent() self.treasureHandler.addInPattern('%fn-intoTreasure') base.cTrav.addCollider(self.treasureCollNodePath, self.treasureHandler) eventName = '%s-intoTreasure' % self.treasureCollNodePath.getName() self.notify.debug('eventName = %s' % eventName) self.accept(eventName, self.toonHitSomething) def setupForceArrow(self, avId): arrow = loader.loadModel('phase_4/models/minigames/ice_game_arrow') priority = 0 if avId < 0: priority = -avId else: priority = self.avIdList.index(avId) if avId == self.localAvId: priority = 10 self.forceArrowDict[avId] = arrow def hideForceArrows(self): for forceArrow in self.forceArrowDict.values(): forceArrow.hide() def showForceArrows(self, realPlayersOnly=True): for avId in self.forceArrowDict: if realPlayersOnly: if avId > 0: self.forceArrowDict[avId].show() else: self.forceArrowDict[avId].hide() avId > 0 self.forceArrowDict[avId].show() def localForceArrow(self): if self.localAvId in self.forceArrowDict: return self.forceArrowDict[self.localAvId] else: return None def setChoices(self, input0, input1, input2, input3): pass def startDebugTask(self): taskMgr.add(self.debugTask, self.debugTaskName) def stopDebugTask(self): taskMgr.remove(self.debugTaskName) def debugTask(self, task): if self.canDrive and self.tireDict.has_key(localAvatar.doId): dt = globalClock.getDt() forceMove = 25000 forceMoveDt = forceMove tireBody = self.tireDict[localAvatar.doId]['tireBody'] if self.arrowKeys.upPressed() and not tireBody.isEnabled(): x = 0 y = 1 tireBody.enable() tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0)) if self.arrowKeys.downPressed() and not tireBody.isEnabled(): x = 0 y = -1 tireBody.enable() tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0)) if self.arrowKeys.leftPressed() and not tireBody.isEnabled(): x = -1 y = 0 tireBody.enable() tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0)) if self.arrowKeys.rightPressed() and not tireBody.isEnabled(): x = 1 y = 0 tireBody.enable() tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0)) return task.cont def _DistributedIceGame__upArrowPressed(self): pass def _DistributedIceGame__downArrowPressed(self): pass def _DistributedIceGame__leftArrowPressed(self): pass def _DistributedIceGame__rightArrowPressed(self): pass def _DistributedIceGame__controlPressed(self): if self.gameFSM.getCurrentState().getName() == 'inputChoice': self.sendForceArrowUpdateAsap = True self.updateLocalForceArrow() self.controlKeyPressed = True self.sendUpdate('setAvatarChoice', [self.curForce, self.curHeading]) self.gameFSM.request('waitServerChoices') def startTimer(self): now = globalClock.getFrameTime() elapsed = now - self.timerStartTime self.timer.posInTopRightCorner() self.timer.setTime(IceGameGlobals.InputTimeout) self.timer.countdown(IceGameGlobals.InputTimeout - elapsed, self.handleChoiceTimeout) self.timer.show() def setTimerStartTime(self, timestamp): if not self.hasLocalToon: return None self.timerStartTime = globalClockDelta.networkToLocalTime(timestamp) if self.timer != None: self.startTimer() def handleChoiceTimeout(self): self.sendUpdate('setAvatarChoice', [0, 0]) self.gameFSM.request('waitServerChoices') def localTireNp(self): ret = None if self.localAvId in self.tireDict: ret = self.tireDict[self.localAvId]['tireNodePath'] return ret def localTireBody(self): ret = None if self.localAvId in self.tireDict: ret = self.tireDict[self.localAvId]['tireBody'] return ret def getTireBody(self, avId): ret = None if avId in self.tireDict: ret = self.tireDict[avId]['tireBody'] return ret def getTireNp(self, avId): ret = None if avId in self.tireDict: ret = self.tireDict[avId]['tireNodePath'] return ret def updateForceArrow(self, avId, curHeading, curForce): forceArrow = self.forceArrowDict[avId] tireNp = self.tireDict[avId]['tireNodePath'] tireNp.setH(curHeading) tireBody = self.tireDict[avId]['tireBody'] tireBody.setQuaternion(tireNp.getQuat()) self.notify.debug('curHeading = %s' % curHeading) yScale = curForce / 100.0 yScale *= 1 headY = yScale * 15 xScale = (yScale - 1) / 2.0 + 1.0 shaft = forceArrow.find('**/arrow_shaft') head = forceArrow.find('**/arrow_head') shaft.setScale(xScale, yScale, 1) head.setPos(0, headY, 0) head.setScale(xScale, xScale, 1) def updateLocalForceArrow(self): avId = self.localAvId self.b_setForceArrowInfo(avId, self.curHeading, self.curForce) def _DistributedIceGame__aimTask(self, task): if not hasattr(self, 'arrowKeys'): return task.done dt = globalClock.getDt() headingMomentumChange = dt * 60.0 forceMomentumChange = dt * 160.0 arrowUpdate = False arrowRotating = False arrowUp = False arrowDown = False if self.arrowKeys.upPressed() and not self.arrowKeys.downPressed(): self.forceMomentum += forceMomentumChange if self.forceMomentum < 0: self.forceMomentum = 0 if self.forceMomentum > 50: self.forceMomentum = 50 oldForce = self.curForce self.curForce += self.forceMomentum * dt arrowUpdate = True if oldForce < self.MaxLocalForce: arrowUp = True elif self.arrowKeys.downPressed() and not self.arrowKeys.upPressed(): self.forceMomentum += forceMomentumChange if self.forceMomentum < 0: self.forceMomentum = 0 if self.forceMomentum > 50: self.forceMomentum = 50 oldForce = self.curForce self.curForce -= self.forceMomentum * dt arrowUpdate = True if oldForce > 0.01: arrowDown = True else: self.forceMomentum = 0 if self.arrowKeys.leftPressed() and not self.arrowKeys.rightPressed(): self.headingMomentum += headingMomentumChange if self.headingMomentum < 0: self.headingMomentum = 0 if self.headingMomentum > 50: self.headingMomentum = 50 self.curHeading += self.headingMomentum * dt arrowUpdate = True arrowRotating = True elif self.arrowKeys.rightPressed( ) and not self.arrowKeys.leftPressed(): self.headingMomentum += headingMomentumChange if self.headingMomentum < 0: self.headingMomentum = 0 if self.headingMomentum > 50: self.headingMomentum = 50 self.curHeading -= self.headingMomentum * dt arrowUpdate = True arrowRotating = True else: self.headingMomentum = 0 if arrowUpdate: self.normalizeHeadingAndForce() self.updateLocalForceArrow() if arrowRotating: if not self.arrowRotateSound.status( ) == self.arrowRotateSound.PLAYING: base.playSfx(self.arrowRotateSound, looping=True) else: self.arrowRotateSound.stop() if arrowUp: if not self.arrowUpSound.status() == self.arrowUpSound.PLAYING: base.playSfx(self.arrowUpSound, looping=False) else: self.arrowUpSound.stop() if arrowDown: if not self.arrowDownSound.status() == self.arrowDownSound.PLAYING: base.playSfx(self.arrowDownSound, looping=False) else: self.arrowDownSound.stop() return task.cont def normalizeHeadingAndForce(self): if self.curForce > self.MaxLocalForce: self.curForce = self.MaxLocalForce if self.curForce < 0.01: self.curForce = 0.01 def setTireInputs(self, tireInputs): if not self.hasLocalToon: return None self.allTireInputs = tireInputs self.gameFSM.request('moveTires') def enableAllTireBodies(self): for avId in self.tireDict.keys(): self.tireDict[avId]['tireBody'].enable() def disableAllTireBodies(self): for avId in self.tireDict.keys(): self.tireDict[avId]['tireBody'].disable() def areAllTiresDisabled(self): for avId in self.tireDict.keys(): if self.tireDict[avId]['tireBody'].isEnabled(): return False continue return True def _DistributedIceGame__moveTiresTask(self, task): if self.areAllTiresDisabled(): self.sendTirePositions() self.gameFSM.request('synch') return task.done return task.cont def sendTirePositions(self): tirePositions = [] for index in xrange(len(self.avIdList)): avId = self.avIdList[index] tire = self.getTireBody(avId) pos = Point3(tire.getPosition()) tirePositions.append([pos[0], pos[1], pos[2]]) for index in xrange(len(self.avIdList), 4): avId = -index tire = self.getTireBody(avId) pos = Point3(tire.getPosition()) tirePositions.append([pos[0], pos[1], pos[2]]) self.sendUpdate('endingPositions', [tirePositions]) def setFinalPositions(self, finalPos): if not self.hasLocalToon: return None for index in xrange(len(self.avIdList)): avId = self.avIdList[index] tire = self.getTireBody(avId) np = self.getTireNp(avId) pos = finalPos[index] tire.setPosition(pos[0], pos[1], pos[2]) np.setPos(pos[0], pos[1], pos[2]) for index in xrange(len(self.avIdList), 4): avId = -index tire = self.getTireBody(avId) np = self.getTireNp(avId) pos = finalPos[index] tire.setPosition(pos[0], pos[1], pos[2]) np.setPos(pos[0], pos[1], pos[2]) def updateInfoLabel(self): self.infoLabel['text'] = TTLocalizer.IceGameInfo % { 'curMatch': self.curMatch + 1, 'numMatch': IceGameGlobals.NumMatches, 'curRound': self.curRound + 1, 'numRound': IceGameGlobals.NumRounds } def setMatchAndRound(self, match, round): if not self.hasLocalToon: return None self.curMatch = match self.curRound = round self.updateInfoLabel() def setScores(self, match, round, scores): if not self.hasLocalToon: return None self.newMatch = match self.newRound = round self.newScores = scores def setNewState(self, state): if not self.hasLocalToon: return None self.notify.debug('setNewState gameFSM=%s newState=%s' % (self.gameFSM, state)) self.gameFSM.request(state) def putAllTiresInStartingPositions(self): for index in xrange(len(self.avIdList)): avId = self.avIdList[index] np = self.tireDict[avId]['tireNodePath'] np.setPos(IceGameGlobals.StartingPositions[index]) self.notify.debug('avId=%s newPos=%s' % (avId, np.getPos)) np.setHpr(0, 0, 0) quat = np.getQuat() body = self.tireDict[avId]['tireBody'] body.setPosition(IceGameGlobals.StartingPositions[index]) body.setQuaternion(quat) for index in xrange(len(self.avIdList), 4): avId = -index np = self.tireDict[avId]['tireNodePath'] np.setPos(IceGameGlobals.StartingPositions[index]) self.notify.debug('avId=%s newPos=%s' % (avId, np.getPos)) np.setHpr(0, 0, 0) quat = np.getQuat() body = self.tireDict[avId]['tireBody'] body.setPosition(IceGameGlobals.StartingPositions[index]) body.setQuaternion(quat) def b_setForceArrowInfo(self, avId, force, heading): self.setForceArrowInfo(avId, force, heading) self.d_setForceArrowInfo(avId, force, heading) def d_setForceArrowInfo(self, avId, force, heading): sendIt = False curTime = self.getCurrentGameTime() if self.sendForceArrowUpdateAsap: sendIt = True elif curTime - self.lastForceArrowUpdateTime > 0.20000000000000001: sendIt = True if sendIt: self.sendUpdate('setForceArrowInfo', [avId, force, heading]) self.sendForceArrowUpdateAsap = False self.lastForceArrowUpdateTime = self.getCurrentGameTime() def setForceArrowInfo(self, avId, force, heading): if not self.hasLocalToon: return None self.updateForceArrow(avId, force, heading) def setupStartOfMatch(self): self.putAllTiresInStartingPositions() szId = self.getSafezoneId() self.numTreasures = IceGameGlobals.NumTreasures[szId] if self.treasures: for treasure in self.treasures: treasure.destroy() self.treasures = [] index = 0 treasureMargin = IceGameGlobals.TireRadius + 1.0 while len(self.treasures) < self.numTreasures: xPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[0] + 5, IceGameGlobals.MaxWall[0] - 5) yPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[1] + 5, IceGameGlobals.MaxWall[1] - 5) self.notify.debug('yPos=%s' % yPos) pos = Point3(xPos, yPos, IceGameGlobals.TireRadius) newTreasure = IceTreasure.IceTreasure(self.treasureModel, pos, index, self.doId, penalty=False) goodSpot = True for obstacle in self.obstacles: if newTreasure.nodePath.getDistance(obstacle) < treasureMargin: goodSpot = False break continue if goodSpot: for treasure in self.treasures: if newTreasure.nodePath.getDistance( treasure.nodePath) < treasureMargin: goodSpot = False break continue if goodSpot: self.treasures.append(newTreasure) index += 1 continue newTreasure.destroy() self.numPenalties = IceGameGlobals.NumPenalties[szId] if self.penalties: for penalty in self.penalties: penalty.destroy() self.penalties = [] index = 0 while len(self.penalties) < self.numPenalties: xPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[0] + 5, IceGameGlobals.MaxWall[0] - 5) yPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[1] + 5, IceGameGlobals.MaxWall[1] - 5) self.notify.debug('yPos=%s' % yPos) pos = Point3(xPos, yPos, IceGameGlobals.TireRadius) newPenalty = IceTreasure.IceTreasure(self.penaltyModel, pos, index, self.doId, penalty=True) goodSpot = True for obstacle in self.obstacles: if newPenalty.nodePath.getDistance(obstacle) < treasureMargin: goodSpot = False break continue if goodSpot: for treasure in self.treasures: if newPenalty.nodePath.getDistance( treasure.nodePath) < treasureMargin: goodSpot = False break continue if goodSpot: for penalty in self.penalties: if newPenalty.nodePath.getDistance( penalty.nodePath) < treasureMargin: goodSpot = False break continue if goodSpot: self.penalties.append(newPenalty) index += 1 continue newPenalty.destroy() def toonHitSomething(self, entry): self.notify.debug('---- treasure Enter ---- ') self.notify.debug('%s' % entry) name = entry.getIntoNodePath().getName() parts = name.split('-') if len(parts) < 3: self.notify.debug('collided with %s, but returning' % name) return None if not int(parts[1]) == self.doId: self.notify.debug("collided with %s, but doId doesn't match" % name) return None treasureNum = int(parts[2]) if 'penalty' in parts[0]: self._DistributedIceGame__penaltyGrabbed(treasureNum) else: self._DistributedIceGame__treasureGrabbed(treasureNum) def _DistributedIceGame__treasureGrabbed(self, treasureNum): self.treasures[treasureNum].showGrab() self.treasureGrabSound.play() self.sendUpdate('claimTreasure', [treasureNum]) def setTreasureGrabbed(self, avId, treasureNum): if not self.hasLocalToon: return None self.notify.debug('treasure %s grabbed by %s' % (treasureNum, avId)) if avId != self.localAvId: self.treasures[treasureNum].showGrab() i = self.avIdList.index(avId) self.scores[i] += 1 self.scorePanels[i].setScore(self.scores[i]) def _DistributedIceGame__penaltyGrabbed(self, penaltyNum): self.penalties[penaltyNum].showGrab() self.sendUpdate('claimPenalty', [penaltyNum]) def setPenaltyGrabbed(self, avId, penaltyNum): if not self.hasLocalToon: return None self.notify.debug('penalty %s grabbed by %s' % (penaltyNum, avId)) if avId != self.localAvId: self.penalties[penaltyNum].showGrab() i = self.avIdList.index(avId) self.scores[i] -= 1 self.scorePanels[i].setScore(self.scores[i]) def postStep(self): DistributedIceWorld.DistributedIceWorld.postStep(self) for count in range(self.colCount): (c0, c1) = self.getOrderedContacts(count) if c1 in self.tireCollideIds: tireIndex = self.tireCollideIds.index(c1) if c0 in self.tireCollideIds: self.tireSounds[tireIndex]['tireHit'].play() elif c0 == self.wallCollideId: self.tireSounds[tireIndex]['wallHit'].play() elif c0 == self.obstacleCollideId: self.tireSounds[tireIndex]['obstacleHit'].play() c0 in self.tireCollideIds def forceLocalToonToTire(self): toon = localAvatar if toon and self.localAvId in self.tireDict: tireNp = self.tireDict[self.localAvId]['tireNodePath'] toon.reparentTo(tireNp) toon.setPosHpr(0, 0, 0, 0, 0, 0) toon.setY(1.0) toon.setZ(-3)
class World(DirectObject): def __init__(self): # Initialize the traverser. base.cTrav = CollisionTraverser() # Initialize the handler. self.collHandEvent = CollisionHandlerEvent() self.collHandEvent.addInPattern("into-%in") self.collHandEvent.addOutPattern("outof-%in") # Make a variable to store the unique collision string count. self.collCount = 0 # Load a model. Reparent it to the camera so we can move it. s = loader.loadModel("smiley") s.reparentTo(camera) s.setPos(0, 25, 0) # Setup a collision solid for this model. sColl = self.initCollisionSphere(s, True) # Add this object to the traverser. base.cTrav.addCollider(sColl[0], self.collHandEvent) # Accept the events sent by the collisions. self.accept("into-" + sColl[1], self.collide3) self.accept("outof-" + sColl[1], self.collide4) print(sColl[1]) # Load another model. t = loader.loadModel("smiley") t.reparentTo(render) t.setPos(5, 25, 0) # Setup a collision solid for this model. tColl = self.initCollisionSphere(t, True) # Add this object to the traverser. base.cTrav.addCollider(tColl[0], self.collHandEvent) # Accept the events sent by the collisions. self.accept("into-" + tColl[1], self.collide) self.accept("outof-" + tColl[1], self.collide2) print(tColl[1]) print("WERT") def collide(self, collEntry): print("WERT: object has collided into another object") Sequence( Func(collEntry.getFromNodePath().getParent().setColor, VBase4(1, 0, 0, 1)), Wait(0.2), Func(collEntry.getFromNodePath().getParent().setColor, VBase4(0, 1, 0, 1)), Wait(0.2), Func(collEntry.getFromNodePath().getParent().setColor, VBase4(1, 1, 1, 1)), ).start() def collide2(self, collEntry): print("WERT.: object is no longer colliding with another object") def collide3(self, collEntry): print("WERT2: object has collided into another object") def collide4(self, collEntry): print("WERT2: object is no longer colliding with another object") def initCollisionSphere(self, obj, show=False): # Get the size of the object for the collision sphere. bounds = obj.getChild(0).getBounds() center = bounds.getCenter() radius = bounds.getRadius() * 1.1 # Create a collision sphere and name it something understandable. collSphereStr = "CollisionHull" + str(self.collCount) + "_" + obj.getName() self.collCount += 1 cNode = CollisionNode(collSphereStr) cNode.addSolid(CollisionSphere(center, radius)) cNodepath = obj.attachNewNode(cNode) if show: cNodepath.show() # Return a tuple with the collision node and its corrsponding string so # that the bitmask can be set. return (cNodepath, collSphereStr)
class CogdoMazeLocalPlayer(CogdoMazePlayer): notify = directNotify.newCategory('CogdoMazeLocalPlayer') def __init__(self, id, toon, game, guiMgr): CogdoMazePlayer.__init__(self, id, toon) self.disableGagCollision() self.game = game self.maze = self.game.maze self._guiMgr = guiMgr self.cameraMgr = CogdoMazeCameraManager(self.toon, self.maze, camera, render) self._proximityRadius = self.maze.cellWidth * Globals.CameraRemoteToonRadius orthoDrive = OrthoDrive( Globals.ToonRunSpeed, maxFrameMove=self.maze.cellWidth / 2, customCollisionCallback=self.maze.doOrthoCollisions, wantSound=True) self.orthoWalk = OrthoWalk(orthoDrive) self._audioMgr = base.cogdoGameAudioMgr self._getMemoSfx = self._audioMgr.createSfx('getMemo', source=self.toon) self._waterCoolerFillSfx = self._audioMgr.createSfx('waterCoolerFill', source=self.toon) self._hitByDropSfx = self._audioMgr.createSfx('toonHitByDrop', source=self.toon) self._winSfx = self._audioMgr.createSfx('win') self._loseSfx = self._audioMgr.createSfx('lose') self.enabled = False self.pickupCount = 0 self.numEntered = 0 self.throwPending = False self.coolDownAfterHitInterval = Sequence( Wait(Globals.HitCooldownTime), Func(self.setInvulnerable, False), name='coolDownAfterHitInterval-%i' % self.toon.doId) self.invulnerable = False self.gagHandler = CollisionHandlerEvent() self.gagHandler.addInPattern('%fn-into-%in') self.exited = False self.hints = { 'find': False, 'throw': False, 'squashed': False, 'boss': False, 'minion': False } self.accept(base.JUMP, self.controlKeyPressed) def destroy(self): self.toon.showName() self.ignoreAll() self.coolDownAfterHitInterval.clearToInitial() del self.coolDownAfterHitInterval del self._getMemoSfx del self._waterCoolerFillSfx del self._hitByDropSfx del self._winSfx self.orthoWalk.stop() self.orthoWalk.destroy() del self.orthoWalk CogdoMazePlayer.destroy(self) def __initCollisions(self): collSphere = CollisionSphere(0, 0, 0, Globals.PlayerCollisionRadius) collSphere.setTangible(0) self.mazeCollisionName = Globals.LocalPlayerCollisionName collNode = CollisionNode(self.mazeCollisionName) collNode.addSolid(collSphere) collNodePath = self.toon.attachNewNode(collNode) collNodePath.hide() handler = CollisionHandlerEvent() handler.addInPattern('%fn-into-%in') base.cTrav.addCollider(collNodePath, handler) self.handler = handler self._collNodePath = collNodePath def clearCollisions(self): self.handler.clear() def __disableCollisions(self): self._collNodePath.removeNode() del self._collNodePath def _isNearPlayer(self, player): return self.toon.getDistance(player.toon) <= self._proximityRadius def update(self, dt): if self.getCurrentOrNextState() != 'Off': self._updateCamera(dt) def _updateCamera(self, dt): numPlayers = 0.0 for player in self.game.players: if player != self and player.toon and self._isNearPlayer(player): numPlayers += 1 d = clamp( Globals.CameraMinDistance + numPlayers / (CogdoGameConsts.MaxPlayers - 1) * (Globals.CameraMaxDistance - Globals.CameraMinDistance), Globals.CameraMinDistance, Globals.CameraMaxDistance) self.cameraMgr.setCameraTargetDistance(d) self.cameraMgr.update(dt) def enterOff(self): CogdoMazePlayer.enterOff(self) def exitOff(self): CogdoMazePlayer.exitOff(self) self.toon.hideName() def enterReady(self): CogdoMazePlayer.enterReady(self) self.cameraMgr.enable() def exitReady(self): CogdoMazePlayer.enterReady(self) def enterNormal(self): CogdoMazePlayer.enterNormal(self) self.orthoWalk.start() def exitNormal(self): CogdoMazePlayer.exitNormal(self) self.orthoWalk.stop() def enterHit(self, elapsedTime=0.0): CogdoMazePlayer.enterHit(self, elapsedTime) self.setInvulnerable(True) def exitHit(self): CogdoMazePlayer.exitHit(self) self.coolDownAfterHitInterval.clearToInitial() self.coolDownAfterHitInterval.start() def enterDone(self): CogdoMazePlayer.enterDone(self) self._guiMgr.hideQuestArrow() self.ignore(base.JUMP) self._guiMgr.setMessage('') if self.exited == False: self.lostMemos() def exitDone(self): CogdoMazePlayer.exitDone(self) def hitByDrop(self): if self.equippedGag is not None and not self.hints['squashed']: self._guiMgr.setMessageTemporary(TTLocalizer.CogdoMazeSquashHint, Globals.HintTimeout) self.hints['squashed'] = True self._hitByDropSfx.play() CogdoMazePlayer.hitByDrop(self) return def equipGag(self): CogdoMazePlayer.equipGag(self) self._waterCoolerFillSfx.play() messenger.send(Globals.WaterCoolerHideEventName, []) if not self.hints['throw']: self._guiMgr.setMessage(TTLocalizer.CogdoMazeThrowHint) self.hints['throw'] = True def hitSuit(self, suitType): if suitType == Globals.SuitTypes.Boss and not self.hints['boss']: self._guiMgr.setMessageTemporary(TTLocalizer.CogdoMazeBossHint, Globals.HintTimeout) self.hints['boss'] = True if suitType != Globals.SuitTypes.Boss and not self.hints['minion']: self._guiMgr.setMessageTemporary(TTLocalizer.CogdoMazeMinionHint, Globals.HintTimeout) self.hints['minion'] = True def createThrowGag(self, gag): throwGag = CogdoMazePlayer.createThrowGag(self, gag) collSphere = CollisionSphere(0, 0, 0, 0.5) collSphere.setTangible(0) name = Globals.GagCollisionName collNode = CollisionNode(name) collNode.setFromCollideMask(ToontownGlobals.PieBitmask) collNode.addSolid(collSphere) colNp = throwGag.attachNewNode(collNode) base.cTrav.addCollider(colNp, self.gagHandler) return throwGag def showToonThrowingGag(self, heading, pos): self._guiMgr.clearMessage() return CogdoMazePlayer.showToonThrowingGag(self, heading, pos) def removeGag(self): if self.equippedGag is None: return CogdoMazePlayer.removeGag(self) self.throwPending = False messenger.send(Globals.WaterCoolerShowEventName, []) return def controlKeyPressed(self): if self.game.finished or self.throwPending or self.getCurrentOrNextState( ) == 'Hit' or self.equippedGag == None: return self.throwPending = True heading = self.toon.getH() pos = self.toon.getPos() self.game.requestUseGag(pos.getX(), pos.getY(), heading) return def completeThrow(self): self.clearCollisions() CogdoMazePlayer.completeThrow(self) def shakeCamera(self, strength): self.cameraMgr.shake(strength) def getCameraShake(self): return self.cameraMgr.shakeStrength def setInvulnerable(self, bool): self.invulnerable = bool def handleGameStart(self): self.numEntered = len(self.game.players) self.__initCollisions() self._guiMgr.startGame(TTLocalizer.CogdoMazeFindHint) self.hints['find'] = True self.notify.info( 'toonId:%d laff:%d/%d %d player(s) started maze game' % (self.toon.doId, self.toon.hp, self.toon.maxHp, len(self.game.players))) def handleGameExit(self): self.cameraMgr.disable() self.__disableCollisions() def handlePickUp(self, toonId): if toonId == self.toon.doId: self.pickupCount += 1 self._guiMgr.setPickupCount(self.pickupCount) if self.pickupCount == 1: self._guiMgr.showPickupCounter() self._getMemoSfx.play() def handleOpenDoor(self, door): self._guiMgr.setMessage(TTLocalizer.CogdoMazeGameDoorOpens) self._guiMgr.showQuestArrow(self.toon, door, Point3(0, 0, self.toon.getHeight() + 2)) def handleTimeAlert(self): self._guiMgr.setMessageTemporary(TTLocalizer.CogdoMazeGameTimeAlert) def handleToonRevealsDoor(self, toonId, door): if toonId == self.toon.doId: self._guiMgr.setMessageTemporary( TTLocalizer.CogdoMazeGameLocalToonFoundExit) def handleToonEntersDoor(self, toonId, door): self.exited = True message = '' if door.getPlayerCount() < len(self.game.players): message = TTLocalizer.WaitingForOtherToons if toonId == self.toon.doId: self._guiMgr.setMessage(message) self._winSfx.play() self._audioMgr.stopMusic() self.notify.info( 'toonId:%d laff:%d/%d %d player(s) succeeded in maze game. Going to the executive suit building.' % (toonId, self.toon.hp, self.toon.maxHp, len(self.game.players))) if self.numEntered > len(self.game.players): self.notify.info('%d player(s) failed in maze game' % (self.numEntered - len(self.game.players))) def lostMemos(self): self.pickupCount = 0 self._guiMgr.setMessageTemporary(TTLocalizer.CogdoMazeGameTimeOut) self._guiMgr.setPickupCount(self.pickupCount) self.notify.info( 'toonId:%d laff:%d/%d %d player(s) failed in maze game' % (self.toon.doId, self.toon.hp, self.toon.maxHp, len(self.game.players)))
class StrategyGame(ShowBase): def __init__(self): ShowBase.__init__(self) self.camera_control() self.REGION_MAP = "maps/italy_provs.png" self.TEXTURE_MAP = "maps/italy_terrain2.png" self.WORLD_MAP = "maps/italy_map.xml" self.SCENARIO_MAP = "scenarios/italy_scen.xml" self.terrainScale = 1 # Currently Broken self.keyboard_setup() self.drawTerrain() self.xml_load_map(self.WORLD_MAP,"WorldMap") self.xml_load_map(self.SCENARIO_MAP,"Scenario") self.init_collisions() self.pickingEnabledObject = None self.taskMgr.add(self.camera_update, "UpdateCameraTask") self.generate_models() self.txtBox = OnscreenText("<No province>") self.setup_collision_calcs() taskMgr.add(self.rayUpdate, "updatePicker") taskMgr.doMethodLater(0.2,self.task_calendar, "calendar") self.init_variables() self.interface() def init_variables(self): self.armies = [[],[]] for n in range(len(self.nations)): self.armies.append(n) self.target = 0 self.army_count = 0 self.selected_prov = -1 self.months = ["January","February","March","April","May","June", "July","August","September","October","November","December"] self.adce = "AD" self.player = 1 self.money_inc = 0 for p in range(len(self.provs)): if self.provs_owner[p] == self.player: self.money_inc += self.provs_money[p] self.men_inc = 0 for p in range(len(self.provs)): if self.provs_owner[p] == self.player: self.men_inc += self.provs_men[p] def draw_card(self,x,y,width,height,colour): cm = CardMaker("CardMaker") cm.setFrame(x, x+width,y+height, y) card = render2d.attachNewNode(cm.generate()) card.setColor(colour) return (card) def interface(self): self.interface_back = self.draw_card(-0.8,-1,1.6,0.4,(100,100,100,100)) self.txt_name = OnscreenText(text = "", pos = (-0.8,-0.7,-0.8)) self.txt_money = OnscreenText(text = "", pos = (-0.8,-0.8,-0.8)) self.txt_men = OnscreenText(text = "", pos = (-0.8,-0.9,-0.8)) self.txt_nation = OnscreenText(text = self.nations[self.player-1], pos = (-1.2,0.9,-0.8)) self.txt_nation_money = OnscreenText(text = "Coin: " + str(self.nations_money[self.player-1])+" +"+str(self.money_inc), pos = (-0.4,0.9,-0.8)) self.txt_nation_men = OnscreenText(text = "Manpower: " + str(self.nations_men[self.player-1])+" +"+str(self.men_inc), pos = (0.4,0.9,-0.8)) self.txt_date = OnscreenText(text = str(self.day)+" of "+self.months[self.month-1]+" "+str(self.year)+self.adce, pos = (-1.0,0.8,-0.8)) def task_calendar(self,task): #task.delayTime = 5 if (self.month == 1 or self.month == 3 or self.month == 5 or self.month == 7 or self.month == 8 or self.month == 10 or self.month == 12): if self.day == 31 and self.month == 12: self.day = 1 self.month = 1 self.year += 1 elif self.day == 31: self.day = 1 self.month += 1 else: self.day += 1 elif (self.month == 4 or self.month == 6 or self.month == 9 or self.month == 11): if self.day == 30: self.day = 1 self.month += 1 else: self.day += 1 elif (self.month == 2): # if isleap: # print self.year/4 # print "LEAP YEAR" # if self.day == 29: # self.day = 1 # self.month = 3 # else: # self.day += 1 # else: print "IS NOT A LEAP YEAR" if self.day == 28: self.day = 1 self.month = 3 else: self.day += 1 self.daypass() return Task.again def daypass(self): self.nations_money[self.player-1] += self.money_inc self.nations_men[self.player-1] += self.men_inc self.update_interface() def update_interface(self): self.txt_date.setText(str(self.day)+" of "+self.months[self.month-1]+" "+str(self.year)+self.adce) self.txt_nation_money.setText("Coin: " + str(self.nations_money[self.player-1])+" +"+str(self.money_inc)) self.txt_nation_men.setText("Manpower: " + str(self.nations_men[self.player-1])+" +"+str(self.men_inc)) if self.selected_prov != -1: self.txt_name.setText("Province: "+self.provs[self.selected_prov]) self.txt_money.setText("Income: "+str(self.provs_money[self.selected_prov])) self.txt_men.setText("Manpower: "+str(self.provs_men[self.selected_prov])) self.interface_back.setColor(self.format_colour_tuple(self.nations_rgb[self.provs_owner[self.selected_prov]-1])) else: self.txt_name.setText("") self.txt_money.setText("") self.txt_men.setText("") self.interface_back.setColor((255,255,255,255)) def army_create(self): id = self.army_count+1 army = self.loader.loadModel("models/man.x") self.armies[0].append(id) army.reparentTo(self.render) army.setName(str(id)) army.setScale(1, 1, 1) x = 50 y = 50 target = self.target target_x = float(self.provs_x[target]) target_y = 257-float(self.provs_y[target]) target_z = float(self.getObjectZ(target_x,target_y)-1) oArmyCol = army.attachNewNode(CollisionNode("BuildingCNode%d"%id)) oArmyCol.setScale((2,2,2)) oArmyCol.node().addSolid(CollisionSphere(0,0,0,1)) oArmyCol.setTag("unit","army") oArmyCol.show() point1 = Point3(x,y,0) point2 = Point3(target_x,target_y,target_z) distance = (point1.getXy() - point2.getXy()).length() myInterval = army.posInterval(distance/10, Point3(target_x,target_y, target_z)) mySequence = Sequence(myInterval) mySequence.start() army.setPos(x, y, self.getObjectZ(x,y)-1) army.setTag("target",str(target)) self.army_count += 1 if (self.target<len(self.provs)-1): self.target += 1 else: self.target = 0 #taskMgr.add() def army_update(self,id): point1 = self.armies[0][id-1].getPos() point2 = Point3(target_x,target_y,target_z) distance = (point1.getXy() - point2.getXy()).length() def init_collisions(self): base.cTrav = CollisionTraverser() self.cHandler = CollisionHandlerEvent() pickerNode = CollisionNode("mouseRayNode") pickerNPos = base.camera.attachNewNode(pickerNode) self.pickerRay = CollisionRay() pickerNode.addSolid(self.pickerRay) pickerNode.setTag("rays","ray1") base.cTrav.addCollider(pickerNPos, self.cHandler) def setup_collision_calcs(self): self.cHandler.addInPattern("%(rays)ft-into-%(prov)it") self.cHandler.addOutPattern("%(rays)ft-out-%(prov)it") self.cHandler.addAgainPattern("ray_again_all%(""rays"")fh%(""prov"")ih") self.DO=DirectObject() self.DO.accept('ray1-into-city', self.collideInBuilding) self.DO.accept('ray1-out-city', self.collideOutBuilding) self.DO.accept('ray_again_all', self.collideAgainstBuilds) self.pickingEnabledOject=None self.DO.accept('mouse1', self.mouseClick, ["down"]) self.DO.accept('mouse1-up', self.mouseClick, ["up"]) def camera_control(self): base.disableMouse() self.camera = base.camera self.cam_speed = 3 self.cam_drag = 0.01 self.cam_x_moving = False self.cam_y_moving = False self.cam_z_moving = False self.cam_x_inc = 0 self.cam_y_inc = 0 self.cam_z_inc = 0 self.cameraDistance = -50 self.camHeight = 25 self.camXAngle = 0 self.camYAngle = -25 self.camZAngle = 0 self.camX = 0 self.camY = 0 self.camZ = 100 def camera_update(self,task): if self.cam_x_moving: self.camX+=self.cam_x_inc elif self.cam_x_inc != 0: if (self.cam_x_inc > 0 and self.cam_x_inc-self.cam_drag <= 0) or (self.cam_x_inc < 0 and self.cam_x_inc+self.cam_drag >= 0): self.cam_x_inc = 0 elif self.cam_x_inc > 0: self.cam_x_inc -= self.cam_drag elif self.cam_x_inc < 0: self.cam_x_inc -= self.cam_drag else: print "FUCKUP WITH CAM X INC" if self.cam_y_moving: self.camY+=self.cam_y_inc elif self.cam_y_inc != 0: if (self.cam_y_inc > 0 and self.cam_y_inc-self.cam_drag <= 0) or (self.cam_y_inc < 0 and self.cam_y_inc+self.cam_drag >= 0): self.cam_y_inc = 0 elif self.cam_y_inc > 0: self.cam_y_inc -= self.cam_drag elif self.cam_y_inc < 0: self.cam_y_inc -= self.cam_drag else: print "FUCKUP WITH CAM Y INC" if self.cam_z_moving: self.camZ+=self.cam_z_inc elif self.cam_z_inc != 0: if (self.cam_z_inc > 0 and self.cam_z_inc-self.cam_drag <= 0) or (self.cam_z_inc < 0 and self.cam_z_inc+self.cam_drag >= 0): self.cam_z_inc = 0 elif self.cam_z_inc > 0: self.cam_z_inc -= self.cam_drag elif self.cam_z_inc < 0: self.cam_z_inc -= self.cam_drag else: print "FUCKUP WITH CAM Z INC" self.camera.setPos(self.camX, self.camY, self.camZ) self.camera.setHpr(self.camXAngle, self.camYAngle, self.camZAngle) return Task.cont def camera_move(self, status): if status == "up": self.cam_y_moving = True self.cam_y_inc = self.cam_speed if status == "down": self.cam_y_moving = True self.cam_y_inc = -self.cam_speed if status == "left": self.cam_x_moving = True self.cam_x_inc = -self.cam_speed if status == "right": self.cam_x_moving = True self.cam_x_inc = self.cam_speed if status == "stopX": self.cam_x_moving = False if status == "stopY": self.cam_y_moving = False def keyboard_setup(self): self.accept("w", self.keyW) self.accept("w-up", self.stop_y) self.accept("s", self.keyS) self.accept("s-up", self.stop_y) self.accept("a", self.keyA) self.accept("a-up", self.stop_x) self.accept("d", self.keyD) self.accept("d-up", self.stop_x) self.accept("+", self.ZoomIn) self.accept("c", self.createArmy) def createArmy(self): self.army_create() def ZoomIn(self): self.camZ -= 1 def keyW( self ): self.camera_move("up") def keyS( self ): self.camera_move("down") def keyA( self ): self.camera_move("left") def keyD( self ): self.camera_move("right") def stop_x( self ): self.camera_move("stopX") def stop_y( self ): self.camera_move("stopY") def generate_models(self): for p in range(len(self.provs)): print "Making",self.provs[p] city = self.loader.loadModel("models/house2.x") city.reparentTo(self.render) city.setName(self.provs[p]) city.setScale(2, 2, 2) x = float(self.provs_x[p]*self.terrainScale) y = 257*self.terrainScale-float(self.provs_y[p]*self.terrainScale) city.setPos(x, y, self.getObjectZ(x,y)-1) oCityCol = city.attachNewNode(CollisionNode("BuildingCNode%d"%p)) oCityCol.setScale((3,3,3)) oCityCol.node().addSolid(CollisionSphere(0,0,0,1)) oCityCol.setTag("prov","city") city.setTag("id",str(p+1)) #oCityCol.show() def collideInBuilding(self,entry): np_into=entry.getIntoNodePath() np_into.getParent().setColor(.6,.5,1.0,1) def collideOutBuilding(self,entry): np_into=entry.getIntoNodePath() np_into.getParent().setColor(1.0,1.0,1.0,1) self.pickingEnabledObject = None self.txtBox.setText("<No province>") def collideAgainstBuilds(self,entry): if entry.getIntoNodePath().getParent() <> self.pickingEnabledOject: np_from=entry.getFromNodePath() np_into=entry.getIntoNodePath() self.pickingEnabledObject = np_into.getParent() self.txtBox.setText(self.pickingEnabledObject.getName()) def mouseClick(self,status): if self.pickingEnabledObject: if status == "down": self.pickingEnabledObject.setScale(0.95*2) print self.pickingEnabledObject.getTag("id"),self.provs[int(self.pickingEnabledObject.getTag("id"))-1] self.selected_prov = int(self.pickingEnabledObject.getTag("id"))-1 self.update_interface() if status == "up": self.pickingEnabledObject.setScale(1.0*2) elif self.pickingEnabledObject == None: self.selected_prov = -1 self.update_interface() def rayUpdate(self,task): if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.pickerRay.setFromLens(base.camNode, mpos.getX(),mpos.getY()) return task.cont def getObjectZ(self, x, y): if ((x > 0) and (x < 257) and (y > 0) and (y < 257)): return(self.terrain.getElevation(x,y)*self.terrainSize) else: return 0 def format_colour_tuple(self,colour): col = string.split(colour) tuple = (int(col[0]),int(col[1]),int(col[2]),255) return tuple def drawTerrain(self): self.terrainSize = 5 heightmap = "maps/italy_heightmap.png" colmap = self.TEXTURE_MAP self.terrain = GeoMipTerrain("terrain") self.terrain.setHeightfield(heightmap) self.terrain.setColorMap(colmap) self.terrain.setBlockSize(64) #self.terrain.setNear(40) #self.terrain.setFar(120) #self.terrain.setMinLevel(1) self.terrain.setBruteforce(True) self.terrain.generate() self.terrain.setAutoFlatten(self.terrain.AFMLight) self.root = self.terrain.getRoot() self.root.reparentTo(render) self.root.setSz(self.terrainSize) #self.root.setScale(self.terrainScale,self.terrainScale,1) def xml_load_map(self,file,type): if type == "WorldMap": tree = xml.parse(file) root = tree.getroot() self.provs = [] self.provs_x = [] self.provs_y = [] self.provs_rgb = [] self.provs_owner = [] self.provs_money = [] self.provs_men = [] counter = 1 for p in root.findall("province"): self.provs.append(self.get_tag(root,"province", counter, "name")) self.provs_x.append(self.get_tag(root, "province", counter, "x")) self.provs_y.append(self.get_tag(root, "province", counter, "y")) self.provs_rgb.append(self.get_tag(root, "province", counter, "rgb")) self.provs_owner.append(0) self.provs_money.append(0) self.provs_men.append(0) counter+=1 elif type == "Scenario": tree = xml.parse(file) root = tree.getroot() self.day = 0 self.month = 0 self.year = 0 self.adce = 0 self.day = int(root.attrib["day"]) self.month = int(root.attrib["month"]) self.year = int(root.attrib["year"]) self.nations = [] self.nations_rgb = [] self.nations_capital = [] self.nations_money = [] self.nations_men = [] self.nations_provs_id = [] counter = 0 for p in root.findall("province"): print p.attrib["id"] for n in root.findall("nation"): for p in n.findall("province"): self.provs_owner[int(p.attrib["id"])-1] = int(p.find("owner").text) self.provs_money[int(p.attrib["id"])-1] = int(p.find("money").text) self.provs_men[int(p.attrib["id"])-1] = int(p.find("men").text) print self.provs_owner[int(p.attrib["id"])-1] counter+=1 counter = 1 for n in root.findall("nation"): self.nations.append(self.get_tag(root, "nation", counter, "name")) self.nations_capital.append(n.attrib["capital"]) #print self.nations_capital self.nations_rgb.append(self.get_tag(root, "nation", counter, "rgb")) self.nations_money.append(int(self.get_tag(root, "nation", counter, "money"))) self.nations_men.append(int(self.get_tag(root, "nation", counter, "men"))) counter += 1 def get_tag(self,root,str_tag,prov_id, prov_tag): prov = root.find('.//'+str_tag+'[@id="'+str(prov_id)+'"]') tag = prov.find(prov_tag).text return tag
def load(self): self.notify.debug('load') DistributedMinigame.load(self) self.music = base.loadMusic('phase_4/audio/bgm/MG_CogThief.ogg') self.initCogInfo() for barrelIndex in range(CTGG.NumBarrels): barrel = loader.loadModel('phase_4/models/minigames/cogthief_game_gagTank') barrel.setPos(CTGG.BarrelStartingPositions[barrelIndex]) barrel.setScale(self.BarrelScale) barrel.reparentTo(render) barrel.setTag('barrelIndex', str(barrelIndex)) collSphere = CollisionSphere(0, 0, 0, 4) collSphere.setTangible(0) name = 'BarrelSphere-%d' % barrelIndex collSphereName = self.uniqueName(name) collNode = CollisionNode(collSphereName) collNode.setFromCollideMask(CTGG.BarrelBitmask) collNode.addSolid(collSphere) colNp = barrel.attachNewNode(collNode) handler = CollisionHandlerEvent() handler.setInPattern('barrelHit-%fn') base.cTrav.addCollider(colNp, handler) self.accept('barrelHit-' + collSphereName, self.handleEnterBarrel) nodeToHide = '**/gagMoneyTen' if barrelIndex % 2: nodeToHide = '**/gagMoneyFive' iconToHide = barrel.find(nodeToHide) if not iconToHide.isEmpty(): iconToHide.hide() self.barrels.append(barrel) self.gameBoard = loader.loadModel('phase_4/models/minigames/cogthief_game') self.gameBoard.find('**/floor_TT').hide() self.gameBoard.find('**/floor_DD').hide() self.gameBoard.find('**/floor_DG').hide() self.gameBoard.find('**/floor_MM').hide() self.gameBoard.find('**/floor_BR').hide() self.gameBoard.find('**/floor_DL').hide() zone = self.getSafezoneId() if zone == ToontownGlobals.ToontownCentral: self.gameBoard.find('**/floor_TT').show() elif zone == ToontownGlobals.DonaldsDock: self.gameBoard.find('**/floor_DD').show() elif zone == ToontownGlobals.DaisyGardens: self.gameBoard.find('**/floor_DG').show() elif zone == ToontownGlobals.MinniesMelodyland: self.gameBoard.find('**/floor_MM').show() elif zone == ToontownGlobals.TheBrrrgh: self.gameBoard.find('**/floor_BR').show() elif zone == ToontownGlobals.DonaldsDreamland: self.gameBoard.find('**/floor_DL').show() else: self.gameBoard.find('**/floor_TT').show() self.gameBoard.setPosHpr(0, 0, 0, 0, 0, 0) self.gameBoard.setScale(1.0) self.toonSDs = {} avId = self.localAvId toonSD = CogThiefGameToonSD.CogThiefGameToonSD(avId, self) self.toonSDs[avId] = toonSD toonSD.load() self.loadCogs() self.toonHitTracks = {} self.toonPieTracks = {} self.sndOof = base.loadSfx('phase_4/audio/sfx/MG_cannon_hit_dirt.ogg') self.sndRewardTick = base.loadSfx('phase_3.5/audio/sfx/tick_counter.ogg') self.sndPerfect = base.loadSfx('phase_4/audio/sfx/ring_perfect.ogg') self.timer = ToontownTimer.ToontownTimer() self.timer.posInTopRightCorner() self.timer.hide() purchaseModels = loader.loadModel('phase_4/models/gui/purchase_gui') self.jarImage = purchaseModels.find('**/Jar') self.jarImage.reparentTo(hidden) self.rewardPanel = DirectLabel(parent=hidden, relief=None, pos=(1.16, 0.0, 0.45), scale=0.65, text='', text_scale=0.2, text_fg=(0.95, 0.95, 0, 1), text_pos=(0, -0.13), text_font=ToontownGlobals.getSignFont(), image=self.jarImage) self.rewardPanelTitle = DirectLabel(parent=self.rewardPanel, relief=None, pos=(0, 0, 0.06), scale=0.08, text=TTLocalizer.CannonGameReward, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1)) self.initGameWalk() return
def __init__(self): from pandac.PandaModules import CollisionHandlerFloor, CollisionHandlerPusher, CollisionHandlerEvent, CollisionTraverser from pandac.PandaModules import DirectionalLight, AmbientLight, VBase4 ShowBase.__init__(self) self.sky = self.loader.loadModel('models/sky-sphere') self.sky.reparentTo(self.render) self.stage = self.loader.loadModel('models/test-collide') self.stage.reparentTo(self.render) self.floor = self.stage.findAllMatches('**/=CollideType=floor') self.floor.setCollideMask(FLOOR_MASK) self.obstacles = self.stage.findAllMatches('**/=CollideType=obstacle') if self.obstacles: self.obstacles.setCollideMask(OBSTACLE_MASK) self.zones = self.stage.findAllMatches('**/=CollideType=zone') if self.zones: self.zones.setCollideMask(ZONE_MASK) self.create_stanchions() # Character rig, which allows camera to follow character self.char_rig = self.stage.attachNewNode('char_rig') self.active_char = Character('mainchar', self.char_rig) self.cam.reparentTo(self.char_rig) self.cam.setPos(0.5, -3, 1.5) self.cam.lookAt(0.5, 0, 1.5) self.light = DirectionalLight('dlight') self.light.setColor(VBase4(0.3, 0.28, 0.26, 1.0)) self.lightNP = self.stage.attachNewNode(self.light) self.lightNP.setHpr(-75, -45, 0) self.stage.setLight(self.lightNP) self.amblight = AmbientLight('amblight') self.amblight.setColor(VBase4(0.7, 0.68, 0.66, 1.0)) self.amblightNP = self.stage.attachNewNode(self.amblight) self.stage.setLight(self.amblightNP) self.accept('w', self.active_char.begin_forward) self.accept('a', self.active_char.begin_left) self.accept('s', self.active_char.begin_backward) self.accept('d', self.active_char.begin_right) self.accept('w-up', self.active_char.end_forward) self.accept('a-up', self.active_char.end_left) self.accept('s-up', self.active_char.end_backward) self.accept('d-up', self.active_char.end_right) self.taskMgr.add(self.active_char.MoveTask, 'MoveTask') self.look = False self.prev_pos = None self.accept('mouse2', self.begin_look) self.accept('mouse2-up', self.end_look) self.accept('mouse3', self.active_char.begin_spin) self.accept('mouse3-up', self.active_char.end_spin) self.taskMgr.add(self.MouseTask, 'MouseTask') self.floor_handler = CollisionHandlerFloor() self.floor_handler.addCollider(self.active_char.actor_from_floor, self.char_rig) self.wall_handler = CollisionHandlerPusher() self.wall_handler.addCollider(self.active_char.actor_from_obstacle, self.char_rig) self.zone_handler = CollisionHandlerEvent() self.zone_handler.addInPattern('%fn-into') self.zone_handler.addOutPattern('%fn-out') def foo(entry): print 'You are in the zone' def bar(entry): print 'You are not in the zone' self.accept('blockchar_zone-into', foo) self.accept('blockchar_zone-out', bar) self.cTrav = CollisionTraverser('main traverser') self.cTrav.setRespectPrevTransform(True) self.cTrav.addCollider(self.active_char.actor_from_floor, self.floor_handler) self.cTrav.addCollider(self.active_char.actor_from_obstacle, self.wall_handler) self.cTrav.addCollider(self.active_char.actor_from_zone, self.zone_handler)
class CogdoFlyingCollisions(GravityWalker): wantFloorSphere = 0 def __init__(self): GravityWalker.__init__(self, gravity=0.0) def initializeCollisions(self, collisionTraverser, avatarNodePath, avatarRadius = 1.4, floorOffset = 1.0, reach = 1.0): self.cHeadSphereNodePath = None self.cFloorEventSphereNodePath = None self.setupHeadSphere(avatarNodePath) self.setupFloorEventSphere(avatarNodePath, ToontownGlobals.FloorEventBitmask, avatarRadius) GravityWalker.initializeCollisions(self, collisionTraverser, avatarNodePath, avatarRadius, floorOffset, reach) def setupWallSphere(self, bitmask, avatarRadius): self.avatarRadius = avatarRadius cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75, self.avatarRadius) cSphereNode = CollisionNode('Flyer.cWallSphereNode') cSphereNode.addSolid(cSphere) cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) if config.GetBool('want-fluid-pusher', 0): self.pusher = CollisionHandlerFluidPusher() else: self.pusher = CollisionHandlerPusher() self.pusher.addCollider(cSphereNodePath, self.avatarNodePath) self.cWallSphereNodePath = cSphereNodePath def setupEventSphere(self, bitmask, avatarRadius): self.avatarRadius = avatarRadius cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75, self.avatarRadius * 1.04) cSphere.setTangible(0) cSphereNode = CollisionNode('Flyer.cEventSphereNode') cSphereNode.addSolid(cSphere) cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) self.event = CollisionHandlerEvent() self.event.addInPattern('enter%in') self.event.addOutPattern('exit%in') self.cEventSphereNodePath = cSphereNodePath def setupRay(self, bitmask, floorOffset, reach): cRay = CollisionRay(0.0, 0.0, 3.0, 0.0, 0.0, -1.0) cRayNode = CollisionNode('Flyer.cRayNode') cRayNode.addSolid(cRay) self.cRayNodePath = self.avatarNodePath.attachNewNode(cRayNode) cRayNode.setFromCollideMask(bitmask) cRayNode.setIntoCollideMask(BitMask32.allOff()) self.lifter = CollisionHandlerGravity() self.lifter.setLegacyMode(self._legacyLifter) self.lifter.setGravity(self.getGravity(0)) self.lifter.addInPattern('%fn-enter-%in') self.lifter.addAgainPattern('%fn-again-%in') self.lifter.addOutPattern('%fn-exit-%in') self.lifter.setOffset(floorOffset) self.lifter.setReach(reach) self.lifter.addCollider(self.cRayNodePath, self.avatarNodePath) def setupHeadSphere(self, avatarNodePath): collSphere = CollisionSphere(0, 0, 0, 1) collSphere.setTangible(1) collNode = CollisionNode('Flyer.cHeadCollSphere') collNode.setFromCollideMask(ToontownGlobals.CeilingBitmask) collNode.setIntoCollideMask(BitMask32.allOff()) collNode.addSolid(collSphere) self.cHeadSphereNodePath = avatarNodePath.attachNewNode(collNode) self.cHeadSphereNodePath.setZ(base.localAvatar.getHeight() + 1.0) self.headCollisionEvent = CollisionHandlerEvent() self.headCollisionEvent.addInPattern('%fn-enter-%in') self.headCollisionEvent.addOutPattern('%fn-exit-%in') base.cTrav.addCollider(self.cHeadSphereNodePath, self.headCollisionEvent) def setupFloorEventSphere(self, avatarNodePath, bitmask, avatarRadius): cSphere = CollisionSphere(0.0, 0.0, 0.0, 0.75) cSphereNode = CollisionNode('Flyer.cFloorEventSphere') cSphereNode.addSolid(cSphere) cSphereNodePath = avatarNodePath.attachNewNode(cSphereNode) cSphereNode.setFromCollideMask(bitmask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) self.floorCollisionEvent = CollisionHandlerEvent() self.floorCollisionEvent.addInPattern('%fn-enter-%in') self.floorCollisionEvent.addAgainPattern('%fn-again-%in') self.floorCollisionEvent.addOutPattern('%fn-exit-%in') base.cTrav.addCollider(cSphereNodePath, self.floorCollisionEvent) self.cFloorEventSphereNodePath = cSphereNodePath def deleteCollisions(self): GravityWalker.deleteCollisions(self) if self.cHeadSphereNodePath != None: base.cTrav.removeCollider(self.cHeadSphereNodePath) self.cHeadSphereNodePath.detachNode() self.cHeadSphereNodePath = None self.headCollisionsEvent = None if self.cFloorEventSphereNodePath != None: base.cTrav.removeCollider(self.cFloorEventSphereNodePath) self.cFloorEventSphereNodePath.detachNode() self.cFloorEventSphereNodePath = None self.floorCollisionEvent = None self.cRayNodePath.detachNode() del self.cRayNodePath self.cEventSphereNodePath.detachNode() del self.cEventSphereNodePath def setCollisionsActive(self, active = 1): if self.collisionsActive != active: if self.cHeadSphereNodePath != None: base.cTrav.removeCollider(self.cHeadSphereNodePath) if active: base.cTrav.addCollider(self.cHeadSphereNodePath, self.headCollisionEvent) if self.cFloorEventSphereNodePath != None: base.cTrav.removeCollider(self.cFloorEventSphereNodePath) if active: base.cTrav.addCollider(self.cFloorEventSphereNodePath, self.floorCollisionEvent) GravityWalker.setCollisionsActive(self, active) def enableAvatarControls(self): pass def disableAvatarControls(self): pass def handleAvatarControls(self, task): pass
class FreeBLiTZ(ShowBase): def __init__(self): from pandac.PandaModules import CollisionHandlerFloor, CollisionHandlerPusher, CollisionHandlerEvent, CollisionTraverser from pandac.PandaModules import DirectionalLight, AmbientLight, VBase4 ShowBase.__init__(self) self.sky = self.loader.loadModel('models/sky-sphere') self.sky.reparentTo(self.render) self.stage = self.loader.loadModel('models/test-collide') self.stage.reparentTo(self.render) self.floor = self.stage.findAllMatches('**/=CollideType=floor') self.floor.setCollideMask(FLOOR_MASK) self.obstacles = self.stage.findAllMatches('**/=CollideType=obstacle') if self.obstacles: self.obstacles.setCollideMask(OBSTACLE_MASK) self.zones = self.stage.findAllMatches('**/=CollideType=zone') if self.zones: self.zones.setCollideMask(ZONE_MASK) self.create_stanchions() # Character rig, which allows camera to follow character self.char_rig = self.stage.attachNewNode('char_rig') self.active_char = Character('mainchar', self.char_rig) self.cam.reparentTo(self.char_rig) self.cam.setPos(0.5, -3, 1.5) self.cam.lookAt(0.5, 0, 1.5) self.light = DirectionalLight('dlight') self.light.setColor(VBase4(0.3, 0.28, 0.26, 1.0)) self.lightNP = self.stage.attachNewNode(self.light) self.lightNP.setHpr(-75, -45, 0) self.stage.setLight(self.lightNP) self.amblight = AmbientLight('amblight') self.amblight.setColor(VBase4(0.7, 0.68, 0.66, 1.0)) self.amblightNP = self.stage.attachNewNode(self.amblight) self.stage.setLight(self.amblightNP) self.accept('w', self.active_char.begin_forward) self.accept('a', self.active_char.begin_left) self.accept('s', self.active_char.begin_backward) self.accept('d', self.active_char.begin_right) self.accept('w-up', self.active_char.end_forward) self.accept('a-up', self.active_char.end_left) self.accept('s-up', self.active_char.end_backward) self.accept('d-up', self.active_char.end_right) self.taskMgr.add(self.active_char.MoveTask, 'MoveTask') self.look = False self.prev_pos = None self.accept('mouse2', self.begin_look) self.accept('mouse2-up', self.end_look) self.accept('mouse3', self.active_char.begin_spin) self.accept('mouse3-up', self.active_char.end_spin) self.taskMgr.add(self.MouseTask, 'MouseTask') self.floor_handler = CollisionHandlerFloor() self.floor_handler.addCollider(self.active_char.actor_from_floor, self.char_rig) self.wall_handler = CollisionHandlerPusher() self.wall_handler.addCollider(self.active_char.actor_from_obstacle, self.char_rig) self.zone_handler = CollisionHandlerEvent() self.zone_handler.addInPattern('%fn-into') self.zone_handler.addOutPattern('%fn-out') def foo(entry): print 'You are in the zone' def bar(entry): print 'You are not in the zone' self.accept('blockchar_zone-into', foo) self.accept('blockchar_zone-out', bar) self.cTrav = CollisionTraverser('main traverser') self.cTrav.setRespectPrevTransform(True) self.cTrav.addCollider(self.active_char.actor_from_floor, self.floor_handler) self.cTrav.addCollider(self.active_char.actor_from_obstacle, self.wall_handler) self.cTrav.addCollider(self.active_char.actor_from_zone, self.zone_handler) #self.cTrav.showCollisions(self.stage) def create_stanchions(self): from pandac.PandaModules import GeomVertexReader, CollisionNode, CollisionTube self.stanchions = self.stage.findAllMatches('**/=Stanchion') for stanchion in self.stanchions: geomnode = stanchion.node() radius = float(stanchion.getTag('Stanchion')) geom = geomnode.getGeom(0) vdata = geom.getVertexData() for gp in range(geom.getNumPrimitives()): vreader = GeomVertexReader(vdata, 'vertex') prim = geom.getPrimitive(gp) prim = prim.decompose() for p in range(prim.getNumPrimitives()): start = prim.getPrimitiveStart(p) end = prim.getPrimitiveEnd(p) vertices = [] for v in range(start, end): vi = prim.getVertex(v) vreader.setRow(vi) vertex = vreader.getData3f() vertices.append(vertex) vertices.append(vertices[0]) for i in range(1, len(vertices)): a, b = vertices[i - 1], vertices[i] stanchion_np = stanchion.attachNewNode( CollisionNode('stanchion')) print 'creating cyl with radius %f from %s to %s' % ( radius, a, b) stanchion_np.node().addSolid( CollisionTube(a[0], a[1], a[2], b[0], b[1], b[2], radius)) stanchion_np.node().setFromCollideMask(OBSTACLE_MASK) geomnode.removeAllGeoms() def begin_look(self): self.look = True def end_look(self): self.look = False self.prev_pos = None def MouseTask(self, task): if self.mouseWatcherNode.hasMouse(): (x, y) = self.mouseWatcherNode.getMouse() if self.prev_pos: if self.look or self.active_char.spinning: h_diff = (x - self.prev_pos[0]) * 180 p_diff = (y - self.prev_pos[1]) * 90 new_h = clamp_deg_sign(self.char_rig.getH() - h_diff) self.char_rig.setH(new_h) self.cam.setP(self.cam.getP() + p_diff) self.active_char.spin(new_h) self.prev_pos = (x, y) return task.cont
class Coin: """ An object that a ball collects. """ MODEL = "../egg/kolikko.egg" collectable = 0 def __init__(self, model, world, space, pos): self.model = model self.world = world self.space = space self.collHandEvent = CollisionHandlerEvent() self.collHandEvent.addInPattern('into-%in') self.addBox(pos) self.isCollected = False Coin.collectable += 1 def collect(self): if not self.isCollected: self.isCollected = True self.box.setColor(1, 0, 0) Coin.collectable -= 1 def onCollide(self, entry): body1 = entry.getFromNodePath() ballNode = self.model.getBall().getModelNode() if ballNode and ballNode == body1.getParent(): self.collect() def addBox(self, pos): lx, ly, lz = 1, 1, 1 # dimension px, py, pz = pos # position name = "box" + str(pos) self.box = loader.loadModel(self.MODEL) self.box.setPos(-0.5, -0.5, -0.5) self.box.flattenLight() # ApplyTransform self.box.reparentTo(render) # Make sure its center is at 0, 0, 0 like OdeBoxGeom self.box.setPos(px - lx / 2, py - ly / 2, pz - lz / 2) self.box.setScale(lx, ly, lz) self.box.setHpr(0, 50, 0) # Offset z by -1.0 because the coin model was so small cSphere = CollisionSphere(pos[0], pos[1], pos[2] - 1.0, 1) cNode = CollisionNode(name) cNode.addSolid(cSphere) model = render.find(name) if not model.isEmpty(): model.removeNode() cnodePath = render.attachNewNode(cNode) #cnodePath.show() base.cTrav.addCollider(cnodePath, self.collHandEvent) base.accept('into-' + name, self.onCollide) # Implementation below would not allow coins to float? # define mass """ mass = OdeMass() mass.setBox(500, lx, ly, lz) self.boxBody = OdeBody( self.world ) self.boxBody.setPosition( self.box.getPos(render) ) self.boxBody.setQuaternion( self.box.getQuat(render) ) self.boxBody.setMass( mass ) self.geom = OdeBoxGeom( self.space, lx, ly, lz) self.space.setSurfaceType( self.geom, SurfaceType.COIN ) self.geom.setBody( self.boxBody ) self.boxBody = None """ def updateModelNode(self): return None #None #self.box.setPos( render, self.boxBody.getPosition() ) #self.box.setQuat(render, Quat(self.boxBody.getQuaternion() ) ) def getBody(self): return None #return self.boxBody def removeNode(self): if not self.isCollected: Coin.collectable -= 1 # http://www.panda3d.org/apiref.php?page=NodePath#removeNode self.box.removeNode()
class DistributedIceGame(DistributedMinigame.DistributedMinigame, DistributedIceWorld.DistributedIceWorld): notify = directNotify.newCategory("DistributedIceGame") MaxLocalForce = 100 MaxPhysicsForce = 25000 def __init__(self, cr): DistributedMinigame.DistributedMinigame.__init__(self, cr) DistributedIceWorld.DistributedIceWorld.__init__(self, cr) self.gameFSM = ClassicFSM.ClassicFSM( "DistributedIceGame", [ State.State("off", self.enterOff, self.exitOff, ["inputChoice"]), State.State( "inputChoice", self.enterInputChoice, self.exitInputChoice, ["waitServerChoices", "moveTires", "displayVotes", "cleanup"], ), State.State( "waitServerChoices", self.enterWaitServerChoices, self.exitWaitServerChoices, ["moveTires", "cleanup"], ), State.State("moveTires", self.enterMoveTires, self.exitMoveTires, ["synch", "cleanup"]), State.State("synch", self.enterSynch, self.exitSynch, ["inputChoice", "scoring", "cleanup"]), State.State("scoring", self.enterScoring, self.exitScoring, ["cleanup", "finalResults", "inputChoice"]), State.State("finalResults", self.enterFinalResults, self.exitFinalResults, ["cleanup"]), State.State("cleanup", self.enterCleanup, self.exitCleanup, []), ], "off", "cleanup", ) self.addChildGameFSM(self.gameFSM) self.cameraThreeQuarterView = (0, -22, 45, 0, -62.89, 0) self.tireDict = {} self.forceArrowDict = {} self.canDrive = False self.timer = None self.timerStartTime = None self.curForce = 0 self.curHeading = 0 self.headingMomentum = 0.0 self.forceMomentum = 0.0 self.allTireInputs = None self.curRound = 0 self.curMatch = 0 self.controlKeyWarningLabel = DirectLabel( text=TTLocalizer.IceGameControlKeyWarning, text_fg=VBase4(1, 0, 0, 1), relief=None, pos=(0.0, 0, 0), scale=0.15, ) self.controlKeyWarningLabel.hide() self.waitingMoveLabel = DirectLabel( text=TTLocalizer.IceGameWaitingForPlayersToFinishMove, text_fg=VBase4(1, 1, 1, 1), relief=None, pos=(-0.6, 0, -0.75), scale=0.075, ) self.waitingMoveLabel.hide() self.waitingSyncLabel = DirectLabel( text=TTLocalizer.IceGameWaitingForAISync, text_fg=VBase4(1, 1, 1, 1), relief=None, pos=(-0.6, 0, -0.75), scale=0.075, ) self.waitingSyncLabel.hide() self.infoLabel = DirectLabel(text="", text_fg=VBase4(0, 0, 0, 1), relief=None, pos=(0.0, 0, 0.7), scale=0.075) self.updateInfoLabel() self.lastForceArrowUpdateTime = 0 self.sendForceArrowUpdateAsap = False self.treasures = [] self.penalties = [] self.obstacles = [] self.controlKeyPressed = False self.controlKeyWarningIval = None return def delete(self): DistributedIceWorld.DistributedIceWorld.delete(self) DistributedMinigame.DistributedMinigame.delete(self) if self.controlKeyWarningIval: self.controlKeyWarningIval.finish() self.controlKeyWarningIval = None self.controlKeyWarningLabel.destroy() del self.controlKeyWarningLabel self.waitingMoveLabel.destroy() del self.waitingMoveLabel self.waitingSyncLabel.destroy() del self.waitingSyncLabel self.infoLabel.destroy() del self.infoLabel for treasure in self.treasures: treasure.destroy() del self.treasures for penalty in self.penalties: penalty.destroy() del self.penalties for obstacle in self.obstacles: obstacle.removeNode() del self.obstacles del self.gameFSM return def announceGenerate(self): DistributedMinigame.DistributedMinigame.announceGenerate(self) DistributedIceWorld.DistributedIceWorld.announceGenerate(self) self.debugTaskName = self.uniqueName("debugTask") def getTitle(self): return TTLocalizer.IceGameTitle def getInstructions(self): szId = self.getSafezoneId() numPenalties = IceGameGlobals.NumPenalties[szId] result = TTLocalizer.IceGameInstructions if numPenalties == 0: result = TTLocalizer.IceGameInstructionsNoTnt return result def getMaxDuration(self): return 0 def load(self): self.notify.debug("load") DistributedMinigame.DistributedMinigame.load(self) self.music = base.loadMusic("phase_4/audio/bgm/MG_IceGame.ogg") self.gameBoard = loader.loadModel("phase_4/models/minigames/ice_game_icerink") background = loader.loadModel("phase_4/models/minigames/ice_game_2d") backgroundWide = loader.loadModel("phase_4/models/minigames/iceslide_ground") background.reparentTo(self.gameBoard) backgroundWide.reparentTo(self.gameBoard) backgroundWide.setPos(0, -0.3, -0.5) self.gameBoard.setPosHpr(0, 0, 0, 0, 0, 0) self.gameBoard.setScale(1.0) self.setupSimulation() index = 0 for avId in self.avIdList: self.setupTire(avId, index) self.setupForceArrow(avId) index += 1 for index in xrange(len(self.avIdList), 4): self.setupTire(-index, index) self.setupForceArrow(-index) self.showForceArrows(realPlayersOnly=True) self.westWallModel = NodePath() if not self.westWallModel.isEmpty(): self.westWallModel.reparentTo(self.gameBoard) self.westWallModel.setPos(IceGameGlobals.MinWall[0], IceGameGlobals.MinWall[1], 0) self.westWallModel.setScale(4) self.eastWallModel = NodePath() if not self.eastWallModel.isEmpty(): self.eastWallModel.reparentTo(self.gameBoard) self.eastWallModel.setPos(IceGameGlobals.MaxWall[0], IceGameGlobals.MaxWall[1], 0) self.eastWallModel.setScale(4) self.eastWallModel.setH(180) self.arrowKeys = ArrowKeys.ArrowKeys() self.target = loader.loadModel("phase_3/models/misc/sphere") self.target.setScale(0.01) self.target.reparentTo(self.gameBoard) self.target.setPos(0, 0, 0) self.scoreCircle = loader.loadModel("phase_4/models/minigames/ice_game_score_circle") self.scoreCircle.setScale(0.01) self.scoreCircle.reparentTo(self.gameBoard) self.scoreCircle.setZ(IceGameGlobals.TireRadius / 2.0) self.scoreCircle.setAlphaScale(0.5) self.scoreCircle.setTransparency(1) self.scoreCircle.hide() self.treasureModel = loader.loadModel("phase_4/models/minigames/ice_game_barrel") self.penaltyModel = loader.loadModel("phase_4/models/minigames/ice_game_tnt2") self.penaltyModel.setScale(0.75, 0.75, 0.7) szId = self.getSafezoneId() obstacles = IceGameGlobals.Obstacles[szId] index = 0 cubicObstacle = IceGameGlobals.ObstacleShapes[szId] for pos in obstacles: newPos = Point3(pos[0], pos[1], IceGameGlobals.TireRadius) newObstacle = self.createObstacle(newPos, index, cubicObstacle) self.obstacles.append(newObstacle) index += 1 self.countSound = loader.loadSfx("phase_3.5/audio/sfx/tick_counter.ogg") self.treasureGrabSound = loader.loadSfx("phase_4/audio/sfx/MG_sfx_vine_game_bananas.ogg") self.penaltyGrabSound = loader.loadSfx("phase_4/audio/sfx/MG_cannon_fire_alt.ogg") self.tireSounds = [] for tireIndex in xrange(4): tireHit = loader.loadSfx("phase_4/audio/sfx/Golf_Hit_Barrier_1.ogg") wallHit = loader.loadSfx("phase_4/audio/sfx/MG_maze_pickup.ogg") obstacleHit = loader.loadSfx("phase_4/audio/sfx/Golf_Hit_Barrier_2.ogg") self.tireSounds.append({"tireHit": tireHit, "wallHit": wallHit, "obstacleHit": obstacleHit}) self.arrowRotateSound = loader.loadSfx("phase_4/audio/sfx/MG_sfx_ice_force_rotate.ogg") self.arrowUpSound = loader.loadSfx("phase_4/audio/sfx/MG_sfx_ice_force_increase_3sec.ogg") self.arrowDownSound = loader.loadSfx("phase_4/audio/sfx/MG_sfx_ice_force_decrease_3sec.ogg") self.scoreCircleSound = loader.loadSfx("phase_4/audio/sfx/MG_sfx_ice_scoring_1.ogg") def unload(self): self.notify.debug("unload") DistributedMinigame.DistributedMinigame.unload(self) del self.music self.gameBoard.removeNode() del self.gameBoard for forceArrow in self.forceArrowDict.values(): forceArrow.removeNode() del self.forceArrowDict self.scoreCircle.removeNode() del self.scoreCircle del self.countSound def onstage(self): self.notify.debug("onstage") DistributedMinigame.DistributedMinigame.onstage(self) self.gameBoard.reparentTo(render) self.__placeToon(self.localAvId) self.moveCameraToTop() self.scorePanels = [] base.playMusic(self.music, looping=1, volume=0.8) def offstage(self): self.notify.debug("offstage") self.music.stop() self.gameBoard.hide() self.infoLabel.hide() for avId in self.tireDict: self.tireDict[avId]["tireNodePath"].hide() for panel in self.scorePanels: panel.cleanup() del self.scorePanels for obstacle in self.obstacles: obstacle.hide() for treasure in self.treasures: treasure.nodePath.hide() for penalty in self.penalties: penalty.nodePath.hide() for avId in self.avIdList: av = self.getAvatar(avId) if av: av.dropShadow.show() av.resetLOD() taskMgr.remove(self.uniqueName("aimtask")) self.arrowKeys.destroy() del self.arrowKeys DistributedMinigame.DistributedMinigame.offstage(self) def handleDisabledAvatar(self, avId): self.notify.debug("handleDisabledAvatar") self.notify.debug("avatar " + str(avId) + " disabled") DistributedMinigame.DistributedMinigame.handleDisabledAvatar(self, avId) def setGameReady(self): if not self.hasLocalToon: return self.notify.debug("setGameReady") if DistributedMinigame.DistributedMinigame.setGameReady(self): return for index in xrange(self.numPlayers): avId = self.avIdList[index] toon = self.getAvatar(avId) if toon: toon.reparentTo(render) self.__placeToon(avId) toon.forwardSpeed = 0 toon.rotateSpeed = False toon.dropShadow.hide() toon.setAnimState("Sit") if avId in self.tireDict: tireNp = self.tireDict[avId]["tireNodePath"] toon.reparentTo(tireNp) toon.setY(1.0) toon.setZ(-3) toon.startLookAround() def setGameStart(self, timestamp): if not self.hasLocalToon: return self.notify.debug("setGameStart") DistributedMinigame.DistributedMinigame.setGameStart(self, timestamp) for avId in self.remoteAvIdList: toon = self.getAvatar(avId) if toon: toon.stopLookAround() self.scores = [0] * self.numPlayers spacing = 0.4 for i in xrange(self.numPlayers): avId = self.avIdList[i] avName = self.getAvatarName(avId) scorePanel = MinigameAvatarScorePanel.MinigameAvatarScorePanel(avId, avName) scorePanel.setScale(0.9) scorePanel.setPos(-0.583 - spacing * (self.numPlayers - 1 - i), 0.0, -0.15) scorePanel.reparentTo(base.a2dTopRight) scorePanel.makeTransparent(0.75) self.scorePanels.append(scorePanel) self.arrowKeys.setPressHandlers( [ self.__upArrowPressed, self.__downArrowPressed, self.__leftArrowPressed, self.__rightArrowPressed, self.__controlPressed, ] ) def isInPlayState(self): if not self.gameFSM.getCurrentState(): return False if not self.gameFSM.getCurrentState().getName() == "play": return False return True def enterOff(self): self.notify.debug("enterOff") def exitOff(self): pass def enterInputChoice(self): self.notify.debug("enterInputChoice") self.forceLocalToonToTire() self.controlKeyPressed = False if self.curRound == 0: self.setupStartOfMatch() else: self.notify.debug("self.curRound = %s" % self.curRound) self.timer = ToontownTimer.ToontownTimer() self.timer.hide() if self.timerStartTime != None: self.startTimer() self.showForceArrows(realPlayersOnly=True) self.localForceArrow().setPosHpr(0, 0, -1.0, 0, 0, 0) self.localForceArrow().reparentTo(self.localTireNp()) self.localForceArrow().setY(IceGameGlobals.TireRadius) self.localTireNp().headsUp(self.target) self.notify.debug("self.localForceArrow() heading = %s" % self.localForceArrow().getH()) self.curHeading = self.localTireNp().getH() self.curForce = 25 self.updateLocalForceArrow() for avId in self.forceArrowDict: forceArrow = self.forceArrowDict[avId] forceArrow.setPosHpr(0, 0, -1.0, 0, 0, 0) tireNp = self.tireDict[avId]["tireNodePath"] forceArrow.reparentTo(tireNp) forceArrow.setY(IceGameGlobals.TireRadius) tireNp.headsUp(self.target) self.updateForceArrow(avId, tireNp.getH(), 25) taskMgr.add(self.__aimTask, self.uniqueName("aimtask")) if base.localAvatar.laffMeter: base.localAvatar.laffMeter.stop() self.sendForceArrowUpdateAsap = False return def exitInputChoice(self): if not self.controlKeyPressed: if self.controlKeyWarningIval: self.controlKeyWarningIval.finish() self.controlKeyWarningIval = None self.controlKeyWarningIval = Sequence( Func(self.controlKeyWarningLabel.show), self.controlKeyWarningLabel.colorScaleInterval( 10, VBase4(1, 1, 1, 0), startColorScale=VBase4(1, 1, 1, 1) ), Func(self.controlKeyWarningLabel.hide), ) self.controlKeyWarningIval.start() if self.timer != None: self.timer.destroy() self.timer = None self.timerStartTime = None self.hideForceArrows() self.arrowRotateSound.stop() self.arrowUpSound.stop() self.arrowDownSound.stop() taskMgr.remove(self.uniqueName("aimtask")) return def enterWaitServerChoices(self): self.waitingMoveLabel.show() self.showForceArrows(True) def exitWaitServerChoices(self): self.waitingMoveLabel.hide() self.hideForceArrows() def enterMoveTires(self): for key in self.tireDict: body = self.tireDict[key]["tireBody"] body.setAngularVel(0, 0, 0) body.setLinearVel(0, 0, 0) for index in xrange(len(self.allTireInputs)): input = self.allTireInputs[index] avId = self.avIdList[index] body = self.getTireBody(avId) degs = input[1] + 90 tireNp = self.getTireNp(avId) tireH = tireNp.getH() self.notify.debug("tireH = %s" % tireH) radAngle = deg2Rad(degs) foo = NodePath("foo") dirVector = Vec3(math.cos(radAngle), math.sin(radAngle), 0) self.notify.debug("dirVector is now=%s" % dirVector) inputForce = input[0] inputForce /= self.MaxLocalForce inputForce *= self.MaxPhysicsForce force = dirVector * inputForce self.notify.debug("adding force %s to %d" % (force, avId)) body.addForce(force) self.enableAllTireBodies() self.totalPhysicsSteps = 0 self.startSim() taskMgr.add(self.__moveTiresTask, self.uniqueName("moveTiresTtask")) def exitMoveTires(self): self.forceLocalToonToTire() self.disableAllTireBodies() self.stopSim() self.notify.debug("total Physics steps = %d" % self.totalPhysicsSteps) taskMgr.remove(self.uniqueName("moveTiresTtask")) def enterSynch(self): self.waitingSyncLabel.show() def exitSynch(self): self.waitingSyncLabel.hide() def enterScoring(self): sortedByDistance = [] for avId in self.avIdList: np = self.getTireNp(avId) pos = np.getPos() pos.setZ(0) sortedByDistance.append((avId, pos.length())) def compareDistance(x, y): if x[1] - y[1] > 0: return 1 elif x[1] - y[1] < 0: return -1 else: return 0 sortedByDistance.sort(cmp=compareDistance) self.scoreMovie = Sequence() curScale = 0.01 curTime = 0 self.scoreCircle.setScale(0.01) self.scoreCircle.show() self.notify.debug("newScores = %s" % self.newScores) circleStartTime = 0 for index in xrange(len(sortedByDistance)): distance = sortedByDistance[index][1] avId = sortedByDistance[index][0] scorePanelIndex = self.avIdList.index(avId) time = (distance - curScale) / IceGameGlobals.ExpandFeetPerSec if time < 0: time = 0.01 scaleXY = distance + IceGameGlobals.TireRadius self.notify.debug("circleStartTime = %s" % circleStartTime) self.scoreMovie.append( Parallel( LerpScaleInterval(self.scoreCircle, time, Point3(scaleXY, scaleXY, 1.0)), SoundInterval(self.scoreCircleSound, duration=time, startTime=circleStartTime), ) ) circleStartTime += time startScore = self.scorePanels[scorePanelIndex].getScore() destScore = self.newScores[scorePanelIndex] self.notify.debug("for avId %d, startScore=%d, newScores=%d" % (avId, startScore, destScore)) def increaseScores(t, scorePanelIndex=scorePanelIndex, startScore=startScore, destScore=destScore): oldScore = self.scorePanels[scorePanelIndex].getScore() diff = destScore - startScore newScore = int(startScore + diff * t) if newScore > oldScore: base.playSfx(self.countSound) self.scorePanels[scorePanelIndex].setScore(newScore) self.scores[scorePanelIndex] = newScore duration = (destScore - startScore) * IceGameGlobals.ScoreCountUpRate tireNp = self.tireDict[avId]["tireNodePath"] self.scoreMovie.append( Parallel( LerpFunctionInterval(increaseScores, duration), Sequence( LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 0, 0, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 1, 1, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 0, 0, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 1, 1, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 0, 0, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 1, 1, 1)), ), ) ) curScale += distance self.scoreMovie.append(Func(self.sendUpdate, "reportScoringMovieDone", [])) self.scoreMovie.start() def exitScoring(self): self.scoreMovie.finish() self.scoreMovie = None self.scoreCircle.hide() return def enterFinalResults(self): lerpTrack = Parallel() lerpDur = 0.5 tY = 0.6 bY = -0.05 lX = -0.5 cX = 0 rX = 0.5 scorePanelLocs = ( ((cX, bY),), ((lX, bY), (rX, bY)), ((cX, tY), (lX, bY), (rX, bY)), ((lX, tY), (rX, tY), (lX, bY), (rX, bY)), ) scorePanelLocs = scorePanelLocs[self.numPlayers - 1] for i in xrange(self.numPlayers): panel = self.scorePanels[i] pos = scorePanelLocs[i] panel.wrtReparentTo(aspect2d) lerpTrack.append( Parallel( LerpPosInterval(panel, lerpDur, Point3(pos[0], 0, pos[1]), blendType="easeInOut"), LerpScaleInterval(panel, lerpDur, Vec3(panel.getScale()) * 2.0, blendType="easeInOut"), ) ) self.showScoreTrack = Parallel( lerpTrack, Sequence(Wait(IceGameGlobals.ShowScoresDuration), Func(self.gameOver)) ) self.showScoreTrack.start() def exitFinalResults(self): self.showScoreTrack.pause() del self.showScoreTrack def enterCleanup(self): self.notify.debug("enterCleanup") if base.localAvatar.laffMeter: base.localAvatar.laffMeter.start() def exitCleanup(self): pass def __placeToon(self, avId): toon = self.getAvatar(avId) if toon: toon.setPos(0, 0, 0) toon.setHpr(0, 0, 0) def moveCameraToTop(self): camera.reparentTo(render) p = self.cameraThreeQuarterView camera.setPosHpr(p[0], p[1], p[2], p[3], p[4], p[5]) def setupTire(self, avId, index): tireNp, tireBody, tireOdeGeom = self.createTire(index) self.tireDict[avId] = {"tireNodePath": tireNp, "tireBody": tireBody, "tireOdeGeom": tireOdeGeom} if avId <= 0: tireBlocker = tireNp.find("**/tireblockermesh") if not tireBlocker.isEmpty(): tireBlocker.hide() if avId == self.localAvId: tireNp = self.tireDict[avId]["tireNodePath"] self.treasureSphereName = "treasureCollider" self.treasureCollSphere = CollisionSphere(0, 0, 0, IceGameGlobals.TireRadius) self.treasureCollSphere.setTangible(0) self.treasureCollNode = CollisionNode(self.treasureSphereName) self.treasureCollNode.setFromCollideMask(ToontownGlobals.PieBitmask) self.treasureCollNode.addSolid(self.treasureCollSphere) self.treasureCollNodePath = tireNp.attachNewNode(self.treasureCollNode) self.treasureHandler = CollisionHandlerEvent() self.treasureHandler.addInPattern("%fn-intoTreasure") base.cTrav.addCollider(self.treasureCollNodePath, self.treasureHandler) eventName = "%s-intoTreasure" % self.treasureCollNodePath.getName() self.notify.debug("eventName = %s" % eventName) self.accept(eventName, self.toonHitSomething) def setupForceArrow(self, avId): arrow = loader.loadModel("phase_4/models/minigames/ice_game_arrow") priority = 0 if avId < 0: priority = -avId else: priority = self.avIdList.index(avId) if avId == self.localAvId: priority = 10 self.forceArrowDict[avId] = arrow def hideForceArrows(self): for forceArrow in self.forceArrowDict.values(): forceArrow.hide() def showForceArrows(self, realPlayersOnly=True): for avId in self.forceArrowDict: if realPlayersOnly: if avId > 0: self.forceArrowDict[avId].show() else: self.forceArrowDict[avId].hide() else: self.forceArrowDict[avId].show() def localForceArrow(self): if self.localAvId in self.forceArrowDict: return self.forceArrowDict[self.localAvId] else: return None return None def setChoices(self, input0, input1, input2, input3): pass def startDebugTask(self): taskMgr.add(self.debugTask, self.debugTaskName) def stopDebugTask(self): taskMgr.remove(self.debugTaskName) def debugTask(self, task): if self.canDrive and self.tireDict.has_key(localAvatar.doId): dt = globalClock.getDt() forceMove = 25000 forceMoveDt = forceMove tireBody = self.tireDict[localAvatar.doId]["tireBody"] if self.arrowKeys.upPressed() and not tireBody.isEnabled(): x = 0 y = 1 tireBody.enable() tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0)) if self.arrowKeys.downPressed() and not tireBody.isEnabled(): x = 0 y = -1 tireBody.enable() tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0)) if self.arrowKeys.leftPressed() and not tireBody.isEnabled(): x = -1 y = 0 tireBody.enable() tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0)) if self.arrowKeys.rightPressed() and not tireBody.isEnabled(): x = 1 y = 0 tireBody.enable() tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0)) return task.cont def __upArrowPressed(self): pass def __downArrowPressed(self): pass def __leftArrowPressed(self): pass def __rightArrowPressed(self): pass def __controlPressed(self): if self.gameFSM.getCurrentState().getName() == "inputChoice": self.sendForceArrowUpdateAsap = True self.updateLocalForceArrow() self.controlKeyPressed = True self.sendUpdate("setAvatarChoice", [self.curForce, self.curHeading]) self.gameFSM.request("waitServerChoices") def startTimer(self): now = globalClock.getFrameTime() elapsed = now - self.timerStartTime self.timer.posInTopRightCorner() self.timer.setTime(IceGameGlobals.InputTimeout) self.timer.countdown(IceGameGlobals.InputTimeout - elapsed, self.handleChoiceTimeout) self.timer.show() def setTimerStartTime(self, timestamp): if not self.hasLocalToon: return self.timerStartTime = globalClockDelta.networkToLocalTime(timestamp) if self.timer != None: self.startTimer() return def handleChoiceTimeout(self): self.sendUpdate("setAvatarChoice", [0, 0]) self.gameFSM.request("waitServerChoices") def localTireNp(self): ret = None if self.localAvId in self.tireDict: ret = self.tireDict[self.localAvId]["tireNodePath"] return ret def localTireBody(self): ret = None if self.localAvId in self.tireDict: ret = self.tireDict[self.localAvId]["tireBody"] return ret def getTireBody(self, avId): ret = None if avId in self.tireDict: ret = self.tireDict[avId]["tireBody"] return ret def getTireNp(self, avId): ret = None if avId in self.tireDict: ret = self.tireDict[avId]["tireNodePath"] return ret def updateForceArrow(self, avId, curHeading, curForce): forceArrow = self.forceArrowDict[avId] tireNp = self.tireDict[avId]["tireNodePath"] tireNp.setH(curHeading) tireBody = self.tireDict[avId]["tireBody"] tireBody.setQuaternion(tireNp.getQuat()) self.notify.debug("curHeading = %s" % curHeading) yScale = curForce / 100.0 yScale *= 1 headY = yScale * 15 xScale = (yScale - 1) / 2.0 + 1.0 shaft = forceArrow.find("**/arrow_shaft") head = forceArrow.find("**/arrow_head") shaft.setScale(xScale, yScale, 1) head.setPos(0, headY, 0) head.setScale(xScale, xScale, 1) def updateLocalForceArrow(self): avId = self.localAvId self.b_setForceArrowInfo(avId, self.curHeading, self.curForce) def __aimTask(self, task): if not hasattr(self, "arrowKeys"): return task.done dt = globalClock.getDt() headingMomentumChange = dt * 60.0 forceMomentumChange = dt * 160.0 arrowUpdate = False arrowRotating = False arrowUp = False arrowDown = False if self.arrowKeys.upPressed() and not self.arrowKeys.downPressed(): self.forceMomentum += forceMomentumChange if self.forceMomentum < 0: self.forceMomentum = 0 if self.forceMomentum > 50: self.forceMomentum = 50 oldForce = self.curForce self.curForce += self.forceMomentum * dt arrowUpdate = True if oldForce < self.MaxLocalForce: arrowUp = True elif self.arrowKeys.downPressed() and not self.arrowKeys.upPressed(): self.forceMomentum += forceMomentumChange if self.forceMomentum < 0: self.forceMomentum = 0 if self.forceMomentum > 50: self.forceMomentum = 50 oldForce = self.curForce self.curForce -= self.forceMomentum * dt arrowUpdate = True if oldForce > 0.01: arrowDown = True else: self.forceMomentum = 0 if self.arrowKeys.leftPressed() and not self.arrowKeys.rightPressed(): self.headingMomentum += headingMomentumChange if self.headingMomentum < 0: self.headingMomentum = 0 if self.headingMomentum > 50: self.headingMomentum = 50 self.curHeading += self.headingMomentum * dt arrowUpdate = True arrowRotating = True elif self.arrowKeys.rightPressed() and not self.arrowKeys.leftPressed(): self.headingMomentum += headingMomentumChange if self.headingMomentum < 0: self.headingMomentum = 0 if self.headingMomentum > 50: self.headingMomentum = 50 self.curHeading -= self.headingMomentum * dt arrowUpdate = True arrowRotating = True else: self.headingMomentum = 0 if arrowUpdate: self.normalizeHeadingAndForce() self.updateLocalForceArrow() if arrowRotating: if not self.arrowRotateSound.status() == self.arrowRotateSound.PLAYING: base.playSfx(self.arrowRotateSound, looping=True) else: self.arrowRotateSound.stop() if arrowUp: if not self.arrowUpSound.status() == self.arrowUpSound.PLAYING: base.playSfx(self.arrowUpSound, looping=False) else: self.arrowUpSound.stop() if arrowDown: if not self.arrowDownSound.status() == self.arrowDownSound.PLAYING: base.playSfx(self.arrowDownSound, looping=False) else: self.arrowDownSound.stop() return task.cont def normalizeHeadingAndForce(self): if self.curForce > self.MaxLocalForce: self.curForce = self.MaxLocalForce if self.curForce < 0.01: self.curForce = 0.01 def setTireInputs(self, tireInputs): if not self.hasLocalToon: return self.allTireInputs = tireInputs self.gameFSM.request("moveTires") def enableAllTireBodies(self): for avId in self.tireDict.keys(): self.tireDict[avId]["tireBody"].enable() def disableAllTireBodies(self): for avId in self.tireDict.keys(): self.tireDict[avId]["tireBody"].disable() def areAllTiresDisabled(self): for avId in self.tireDict.keys(): if self.tireDict[avId]["tireBody"].isEnabled(): return False return True def __moveTiresTask(self, task): if self.areAllTiresDisabled(): self.sendTirePositions() self.gameFSM.request("synch") return task.done return task.cont def sendTirePositions(self): tirePositions = [] for index in xrange(len(self.avIdList)): avId = self.avIdList[index] tire = self.getTireBody(avId) pos = Point3(tire.getPosition()) tirePositions.append([pos[0], pos[1], pos[2]]) for index in xrange(len(self.avIdList), 4): avId = -index tire = self.getTireBody(avId) pos = Point3(tire.getPosition()) tirePositions.append([pos[0], pos[1], pos[2]]) self.sendUpdate("endingPositions", [tirePositions]) def setFinalPositions(self, finalPos): if not self.hasLocalToon: return for index in xrange(len(self.avIdList)): avId = self.avIdList[index] tire = self.getTireBody(avId) np = self.getTireNp(avId) pos = finalPos[index] tire.setPosition(pos[0], pos[1], pos[2]) np.setPos(pos[0], pos[1], pos[2]) for index in xrange(len(self.avIdList), 4): avId = -index tire = self.getTireBody(avId) np = self.getTireNp(avId) pos = finalPos[index] tire.setPosition(pos[0], pos[1], pos[2]) np.setPos(pos[0], pos[1], pos[2]) def updateInfoLabel(self): self.infoLabel["text"] = TTLocalizer.IceGameInfo % { "curMatch": self.curMatch + 1, "numMatch": IceGameGlobals.NumMatches, "curRound": self.curRound + 1, "numRound": IceGameGlobals.NumRounds, } def setMatchAndRound(self, match, round): if not self.hasLocalToon: return self.curMatch = match self.curRound = round self.updateInfoLabel() def setScores(self, match, round, scores): if not self.hasLocalToon: return self.newMatch = match self.newRound = round self.newScores = scores def setNewState(self, state): if not self.hasLocalToon: return self.notify.debug("setNewState gameFSM=%s newState=%s" % (self.gameFSM, state)) self.gameFSM.request(state) def putAllTiresInStartingPositions(self): for index in xrange(len(self.avIdList)): avId = self.avIdList[index] np = self.tireDict[avId]["tireNodePath"] np.setPos(IceGameGlobals.StartingPositions[index]) self.notify.debug("avId=%s newPos=%s" % (avId, np.getPos)) np.setHpr(0, 0, 0) quat = np.getQuat() body = self.tireDict[avId]["tireBody"] body.setPosition(IceGameGlobals.StartingPositions[index]) body.setQuaternion(quat) for index in xrange(len(self.avIdList), 4): avId = -index np = self.tireDict[avId]["tireNodePath"] np.setPos(IceGameGlobals.StartingPositions[index]) self.notify.debug("avId=%s newPos=%s" % (avId, np.getPos)) np.setHpr(0, 0, 0) quat = np.getQuat() body = self.tireDict[avId]["tireBody"] body.setPosition(IceGameGlobals.StartingPositions[index]) body.setQuaternion(quat) def b_setForceArrowInfo(self, avId, force, heading): self.setForceArrowInfo(avId, force, heading) self.d_setForceArrowInfo(avId, force, heading) def d_setForceArrowInfo(self, avId, force, heading): sendIt = False curTime = self.getCurrentGameTime() if self.sendForceArrowUpdateAsap: sendIt = True elif curTime - self.lastForceArrowUpdateTime > 0.2: sendIt = True if sendIt: self.sendUpdate("setForceArrowInfo", [avId, force, heading]) self.sendForceArrowUpdateAsap = False self.lastForceArrowUpdateTime = self.getCurrentGameTime() def setForceArrowInfo(self, avId, force, heading): if not self.hasLocalToon: return self.updateForceArrow(avId, force, heading) def setupStartOfMatch(self): self.putAllTiresInStartingPositions() szId = self.getSafezoneId() self.numTreasures = IceGameGlobals.NumTreasures[szId] if self.treasures: for treasure in self.treasures: treasure.destroy() self.treasures = [] index = 0 treasureMargin = IceGameGlobals.TireRadius + 1.0 while len(self.treasures) < self.numTreasures: xPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[0] + 5, IceGameGlobals.MaxWall[0] - 5) yPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[1] + 5, IceGameGlobals.MaxWall[1] - 5) self.notify.debug("yPos=%s" % yPos) pos = Point3(xPos, yPos, IceGameGlobals.TireRadius) newTreasure = IceTreasure.IceTreasure(self.treasureModel, pos, index, self.doId, penalty=False) goodSpot = True for obstacle in self.obstacles: if newTreasure.nodePath.getDistance(obstacle) < treasureMargin: goodSpot = False break if goodSpot: for treasure in self.treasures: if newTreasure.nodePath.getDistance(treasure.nodePath) < treasureMargin: goodSpot = False break if goodSpot: self.treasures.append(newTreasure) index += 1 else: newTreasure.destroy() self.numPenalties = IceGameGlobals.NumPenalties[szId] if self.penalties: for penalty in self.penalties: penalty.destroy() self.penalties = [] index = 0 while len(self.penalties) < self.numPenalties: xPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[0] + 5, IceGameGlobals.MaxWall[0] - 5) yPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[1] + 5, IceGameGlobals.MaxWall[1] - 5) self.notify.debug("yPos=%s" % yPos) pos = Point3(xPos, yPos, IceGameGlobals.TireRadius) newPenalty = IceTreasure.IceTreasure(self.penaltyModel, pos, index, self.doId, penalty=True) goodSpot = True for obstacle in self.obstacles: if newPenalty.nodePath.getDistance(obstacle) < treasureMargin: goodSpot = False break if goodSpot: for treasure in self.treasures: if newPenalty.nodePath.getDistance(treasure.nodePath) < treasureMargin: goodSpot = False break if goodSpot: for penalty in self.penalties: if newPenalty.nodePath.getDistance(penalty.nodePath) < treasureMargin: goodSpot = False break if goodSpot: self.penalties.append(newPenalty) index += 1 else: newPenalty.destroy() def toonHitSomething(self, entry): self.notify.debug("---- treasure Enter ---- ") self.notify.debug("%s" % entry) name = entry.getIntoNodePath().getName() parts = name.split("-") if len(parts) < 3: self.notify.debug("collided with %s, but returning" % name) return if not int(parts[1]) == self.doId: self.notify.debug("collided with %s, but doId doesn't match" % name) return treasureNum = int(parts[2]) if "penalty" in parts[0]: self.__penaltyGrabbed(treasureNum) else: self.__treasureGrabbed(treasureNum) def __treasureGrabbed(self, treasureNum): self.treasures[treasureNum].showGrab() self.treasureGrabSound.play() self.sendUpdate("claimTreasure", [treasureNum]) def setTreasureGrabbed(self, avId, treasureNum): if not self.hasLocalToon: return self.notify.debug("treasure %s grabbed by %s" % (treasureNum, avId)) if avId != self.localAvId: self.treasures[treasureNum].showGrab() i = self.avIdList.index(avId) self.scores[i] += 1 self.scorePanels[i].setScore(self.scores[i]) def __penaltyGrabbed(self, penaltyNum): self.penalties[penaltyNum].showGrab() self.sendUpdate("claimPenalty", [penaltyNum]) def setPenaltyGrabbed(self, avId, penaltyNum): if not self.hasLocalToon: return self.notify.debug("penalty %s grabbed by %s" % (penaltyNum, avId)) if avId != self.localAvId: self.penalties[penaltyNum].showGrab() i = self.avIdList.index(avId) self.scores[i] -= 1 self.scorePanels[i].setScore(self.scores[i]) def postStep(self): DistributedIceWorld.DistributedIceWorld.postStep(self) if not self.colCount: return for count in xrange(self.colCount): c0, c1 = self.getOrderedContacts(count) if c1 in self.tireCollideIds: tireIndex = self.tireCollideIds.index(c1) if c0 in self.tireCollideIds: self.tireSounds[tireIndex]["tireHit"].play() elif c0 == self.wallCollideId: self.tireSounds[tireIndex]["wallHit"].play() elif c0 == self.obstacleCollideId: self.tireSounds[tireIndex]["obstacleHit"].play() def forceLocalToonToTire(self): toon = localAvatar if toon and self.localAvId in self.tireDict: tireNp = self.tireDict[self.localAvId]["tireNodePath"] toon.reparentTo(tireNp) toon.setPosHpr(0, 0, 0, 0, 0, 0) toon.setY(1.0) toon.setZ(-3)
class DistributedGolfSpot(DistributedObject.DistributedObject, FSM.FSM): notify = DirectNotifyGlobal.directNotify.newCategory('DistributedGolfSpot') positions = ((-45, 100, GolfGlobals.GOLF_BALL_RADIUS), (-15, 100, GolfGlobals.GOLF_BALL_RADIUS), (15, 100, GolfGlobals.GOLF_BALL_RADIUS), (45, 100, GolfGlobals.GOLF_BALL_RADIUS)) toonGolfOffsetPos = Point3(-2, 0, -GolfGlobals.GOLF_BALL_RADIUS) toonGolfOffsetHpr = Point3(-90, 0, 0) rotateSpeed = 20 golfPowerSpeed = base.config.GetDouble('golf-power-speed', 3) golfPowerExponent = base.config.GetDouble('golf-power-exponent', 0.75) def __init__(self, cr): DistributedObject.DistributedObject.__init__(self, cr) FSM.FSM.__init__(self, 'DistributedGolfSpot') self.boss = None self.index = None self.avId = 0 self.toon = None self.golfSpotSmoother = SmoothMover() self.golfSpotSmoother.setSmoothMode(SmoothMover.SMOn) self.smoothStarted = 0 self.__broadcastPeriod = 0.2 if self.index > len(self.positions): self.notify.error('Invalid index %d' % index) self.fadeTrack = None self.setupPowerBar() self.aimStart = None self.golfSpotAdviceLabel = None self.changeSeq = 0 self.lastChangeSeq = 0 self.controlKeyAllowed = False self.flyBallTracks = {} self.splatTracks = {} self.__flyBallBubble = None self.flyBallHandler = None self.__flyBallSequenceNum = 0 self.swingInterval = None self.lastHitSequenceNum = -1 self.goingToReward = False self.gotHitByBoss = False self.releaseTrack = None self.grabTrack = None self.restoreScaleTrack = None return def setBossCogId(self, bossCogId): self.bossCogId = bossCogId self.boss = base.cr.doId2do[bossCogId] self.boss.setGolfSpot(self, self.index) def setIndex(self, index): self.index = index def disable(self): DistributedObject.DistributedObject.disable(self) self.ignoreAll() def delete(self): DistributedObject.DistributedObject.delete(self) self.ignoreAll() self.boss = None return def announceGenerate(self): DistributedObject.DistributedObject.announceGenerate(self) self.triggerName = self.uniqueName('trigger') self.triggerEvent = 'enter%s' % self.triggerName self.smoothName = self.uniqueName('golfSpotSmooth') self.golfSpotAdviceName = self.uniqueName('golfSpotAdvice') self.posHprBroadcastName = self.uniqueName('golfSpotBroadcast') self.ballPowerTaskName = self.uniqueName('updateGolfPower') self.adjustClubTaskName = self.uniqueName('adjustClub') self.loadAssets() self.accept('flyBallHit-%d' % self.index, self.__flyBallHit) def loadAssets(self): self.root = render.attachNewNode('golfSpot-%d' % self.index) self.root.setPos(*self.positions[self.index]) self.ballModel = loader.loadModel('phase_6/models/golf/golf_ball') self.ballColor = VBase4(1, 1, 1, 1) if self.index < len(GolfGlobals.PlayerColors): self.ballColor = VBase4(*GolfGlobals.PlayerColors[self.index]) self.ballModel.setColorScale(self.ballColor) self.ballModel.reparentTo(self.root) self.club = loader.loadModel('phase_6/models/golf/putter') self.clubLookatSpot = self.root.attachNewNode('clubLookat') self.clubLookatSpot.setY(-(GolfGlobals.GOLF_BALL_RADIUS + 0.1)) cs = CollisionSphere(0, 0, 0, 1) cs.setTangible(0) cn = CollisionNode(self.triggerName) cn.addSolid(cs) cn.setIntoCollideMask(ToontownGlobals.WallBitmask) self.trigger = self.root.attachNewNode(cn) self.trigger.stash() self.hitBallSfx = loader.loadSfx('phase_6/audio/sfx/Golf_Hit_Ball.ogg') def cleanup(self): if self.swingInterval: self.swingInterval.finish() self.swingInterval = None if self.releaseTrack: self.releaseTrack.finish() self.releaseTrack = None flyTracks = self.flyBallTracks.values() for track in flyTracks: track.finish() if self.fadeTrack: self.fadeTrack.finish() self.fadeTrack = None if self.restoreScaleTrack: self.restoreScaleTrack.finish() self.restoreScaleTrack = None self.root.removeNode() self.ballModel.removeNode() self.club.removeNode() if self.powerBar: self.powerBar.destroy() self.powerBar = None taskMgr.remove(self.triggerName) self.boss = None return def setState(self, state, avId, extraInfo): if not self.isDisabled(): self.gotHitByBoss = extraInfo if state == 'C': self.demand('Controlled', avId) elif state == 'F': self.demand('Free') elif state == 'O': self.demand('Off') else: self.notify.error('Invalid state from AI: %s' % state) def enterOff(self): pass def exitOff(self): pass def enterFree(self): if self.fadeTrack: self.fadeTrack.finish() self.fadeTrack = None self.restoreScaleTrack = Sequence(Wait(6), self.getRestoreScaleInterval(), name='restoreScaleTrack') self.restoreScaleTrack.start() if self.avId == localAvatar.doId: if not self.isDisabled(): self.ballModel.setAlphaScale(0.3) self.ballModel.setTransparency(1) taskMgr.doMethodLater(5, self.__allowDetect, self.triggerName) self.fadeTrack = Sequence(Func(self.ballModel.setTransparency, 1), self.ballModel.colorScaleInterval(0.2, VBase4(1, 1, 1, 0.3)), name='fadeTrack-enterFree') self.fadeTrack.start() else: self.trigger.unstash() self.accept(self.triggerEvent, self.__hitTrigger) self.avId = 0 return def exitFree(self): if self.fadeTrack: self.fadeTrack.finish() self.fadeTrack = None self.restoreScaleTrack.finish() self.restoreScaleTrack = None taskMgr.remove(self.triggerName) self.ballModel.clearTransparency() self.trigger.stash() self.ignore(self.triggerEvent) return def enterControlled(self, avId): self.avId = avId toon = base.cr.doId2do.get(avId) if not toon: return self.enableControlKey() self.toon = toon self.grabTrack = self.makeToonGrabInterval(toon) if avId == localAvatar.doId: self.boss.toCraneMode() camera.reparentTo(self.root) camera.setPosHpr(0, -10, 3, 0, 0, 0) localAvatar.setPos(self.root, self.toonGolfOffsetPos) localAvatar.setHpr(self.root, self.toonGolfOffsetHpr) localAvatar.sendCurrentPosition() self.__enableControlInterface() self.startPosHprBroadcast() self.accept('exitCrane', self.gotBossZapped) self.grabTrack.start() def exitControlled(self): self.grabTrack.finish() del self.grabTrack if self.swingInterval: self.swingInterval.finish() self.swingInterval = None if not self.ballModel.isEmpty(): if self.ballModel.isHidden(): self.notify.debug('ball is hidden scale =%s' % self.ballModel.getScale()) else: self.notify.debug('ball is showing scale=%s' % self.ballModel.getScale()) if self.toon and not self.toon.isDisabled(): self.toon.startSmooth() self.releaseTrack = self.makeToonReleaseInterval(self.toon) self.stopPosHprBroadcast() self.stopSmooth() if self.avId == localAvatar.doId: self.__disableControlInterface() if not self.goingToReward: camera.reparentTo(base.localAvatar) camera.setPos(base.localAvatar.cameraPositions[0][0]) camera.setHpr(0, 0, 0) self.stopAdjustClubTask() self.releaseTrack.start() self.enableControlKey() return def __allowDetect(self, task): if self.fadeTrack: self.fadeTrack.finish() self.fadeTrack = Sequence(self.ballModel.colorScaleInterval(0.2, self.ballColor), Func(self.ballModel.clearTransparency), name='fadeTrack-allowDetect') self.fadeTrack.start() self.trigger.unstash() self.accept(self.triggerEvent, self.__hitTrigger) def __hitTrigger(self, event): self.d_requestControl() def getRestoreScaleInterval(self): return Sequence() def d_requestControl(self): self.sendUpdate('requestControl') def d_requestFree(self, gotHitByBoss): self.sendUpdate('requestFree', [gotHitByBoss]) def makeToonGrabInterval(self, toon): origPos = toon.getPos(self.root) origHpr = toon.getHpr(self.root) a = self.accomodateToon(toon) newPos = toon.getPos() newHpr = toon.getHpr() origHpr.setX(PythonUtil.fitSrcAngle2Dest(origHpr[0], newHpr[0])) self.notify.debug('toon.setPosHpr %s %s' % (origPos, origHpr)) toon.setPosHpr(origPos, origHpr) walkTime = 0.2 reach = Sequence() if reach.getDuration() < walkTime: reach = Sequence(ActorInterval(toon, 'walk', loop=1, duration=walkTime - reach.getDuration()), reach) i = Sequence(Parallel(toon.posInterval(walkTime, newPos, origPos), toon.hprInterval(walkTime, newHpr, origHpr), reach), Func(toon.stopLookAround)) if toon == base.localAvatar: i.append(Func(self.switchToAnimState, 'GolfPuttLoop')) i.append(Func(self.startAdjustClubTask)) i = Parallel(i, a) return i def accomodateToon(self, toon): toon.wrtReparentTo(self.root) toon.setPos(self.toonGolfOffsetPos) toon.setHpr(self.toonGolfOffsetHpr) return Sequence() def switchToAnimState(self, animStateName, forced = False): curAnimState = base.localAvatar.animFSM.getCurrentState() curAnimStateName = '' if curAnimState: curAnimStateName = curAnimState.getName() if curAnimStateName != animStateName or forced: base.localAvatar.b_setAnimState(animStateName) def __enableControlInterface(self): gui = loader.loadModel('phase_3.5/models/gui/avatar_panel_gui') self.closeButton = DirectButton(image=(gui.find('**/CloseBtn_UP'), gui.find('**/CloseBtn_DN'), gui.find('**/CloseBtn_Rllvr'), gui.find('**/CloseBtn_UP')), relief=None, scale=2, text=TTLocalizer.BossbotGolfSpotLeave, text_scale=0.04, text_pos=(0, -0.07), text_fg=VBase4(1, 1, 1, 1), pos=(1.05, 0, -0.82), command=self.__exitGolfSpot) self.accept('escape', self.__exitGolfSpot) self.accept('control', self.__controlPressed) self.accept('control-up', self.__controlReleased) self.accept('InputState-forward', self.__upArrow) self.accept('InputState-reverse', self.__downArrow) self.accept('InputState-turnLeft', self.__leftArrow) self.accept('InputState-turnRight', self.__rightArrow) taskMgr.add(self.__watchControls, 'watchGolfSpotControls') taskMgr.doMethodLater(5, self.__displayGolfSpotAdvice, self.golfSpotAdviceName) self.arrowVert = 0 self.arrowHorz = 0 if self.powerBar: self.powerBar.show() return def __disableControlInterface(self): if self.closeButton: self.closeButton.destroy() self.closeButton = None self.__cleanupGolfSpotAdvice() self.ignore('escape') self.ignore('control') self.ignore('control-up') self.ignore('InputState-forward') self.ignore('InputState-reverse') self.ignore('InputState-turnLeft') self.ignore('InputState-turnRight') self.arrowVert = 0 self.arrowHorz = 0 taskMgr.remove('watchGolfSpotControls') if self.powerBar: self.powerBar.hide() else: self.notify.debug('self.powerBar is none') return def setupPowerBar(self): self.powerBar = DirectWaitBar(pos=(0.0, 0, -0.94), relief=DGG.SUNKEN, frameSize=(-2.0, 2.0, -0.2, 0.2), borderWidth=(0.02, 0.02), scale=0.25, range=100, sortOrder=50, frameColor=(0.5, 0.5, 0.5, 0.5), barColor=(1.0, 0.0, 0.0, 1.0), text='', text_scale=0.26, text_fg=(1, 1, 1, 1), text_align=TextNode.ACenter, text_pos=(0, -0.05)) self.power = 0 self.powerBar['value'] = self.power self.powerBar.hide() def resetPowerBar(self): self.power = 0 self.powerBar['value'] = self.power self.powerBar['text'] = '' def __displayGolfSpotAdvice(self, task): if self.golfSpotAdviceLabel == None: self.golfSpotAdviceLabel = DirectLabel(text=TTLocalizer.BossbotGolfSpotAdvice, text_fg=VBase4(1, 1, 1, 1), text_align=TextNode.ACenter, relief=None, pos=(0, 0, 0.69), scale=0.1) return def __cleanupGolfSpotAdvice(self): if self.golfSpotAdviceLabel: self.golfSpotAdviceLabel.destroy() self.golfSpotAdviceLabel = None taskMgr.remove(self.golfSpotAdviceName) return def showExiting(self): if self.closeButton: self.closeButton.destroy() self.closeButton = DirectLabel(relief=None, text=TTLocalizer.BossbotGolfSpotLeaving, pos=(1.05, 0, -0.88), text_pos=(0, 0), text_scale=0.06, text_fg=VBase4(1, 1, 1, 1)) self.__cleanupGolfSpotAdvice() return def __exitGolfSpot(self): self.d_requestFree(False) def __controlPressed(self): if self.controlKeyAllowed: self.__beginFireBall() def __controlReleased(self): if self.controlKeyAllowed: self.__endFireBall() def __upArrow(self, pressed): self.__incrementChangeSeq() self.__cleanupGolfSpotAdvice() if pressed: self.arrowVert = 1 elif self.arrowVert > 0: self.arrowVert = 0 def __downArrow(self, pressed): self.__incrementChangeSeq() self.__cleanupGolfSpotAdvice() if pressed: self.arrowVert = -1 elif self.arrowVert < 0: self.arrowVert = 0 def __rightArrow(self, pressed): self.__incrementChangeSeq() self.__cleanupGolfSpotAdvice() if pressed: self.arrowHorz = 1 self.switchToAnimState('GolfRotateLeft') elif self.arrowHorz > 0: self.arrowHorz = 0 self.switchToAnimState('GolfPuttLoop') def __leftArrow(self, pressed): self.__incrementChangeSeq() self.__cleanupGolfSpotAdvice() if pressed: self.arrowHorz = -1 self.switchToAnimState('GolfRotateRight') elif self.arrowHorz < 0: self.arrowHorz = 0 self.switchToAnimState('GolfPuttLoop') def __watchControls(self, task): if self.arrowHorz: self.__moveGolfSpot(self.arrowHorz) return Task.cont def __moveGolfSpot(self, xd): dt = globalClock.getDt() h = self.root.getH() - xd * self.rotateSpeed * dt h %= 360 limitH = h self.root.setH(limitH) def __incrementChangeSeq(self): self.changeSeq = self.changeSeq + 1 & 255 def __beginFireBall(self): if self.aimStart != None: return if not self.state == 'Controlled': return if not self.avId == localAvatar.doId: return time = globalClock.getFrameTime() self.aimStart = time messenger.send('wakeup') taskMgr.add(self.__updateBallPower, self.ballPowerTaskName) return def __endFireBall(self): if self.aimStart == None: return if not self.state == 'Controlled': return if not self.avId == localAvatar.doId: return taskMgr.remove(self.ballPowerTaskName) self.disableControlKey() messenger.send('wakeup') self.aimStart = None power = self.power angle = self.root.getH() self.notify.debug('incrementing self.__flyBallSequenceNum') self.__flyBallSequenceNum = (self.__flyBallSequenceNum + 1) % 255 self.sendSwingInfo(power, angle, self.__flyBallSequenceNum) self.setSwingInfo(power, angle, self.__flyBallSequenceNum) self.resetPowerBar() return def __updateBallPower(self, task): if not self.powerBar: print '### no power bar!!!' return task.done newPower = self.__getBallPower(globalClock.getFrameTime()) self.power = newPower self.powerBar['value'] = newPower return task.cont def __getBallPower(self, time): elapsed = max(time - self.aimStart, 0.0) t = elapsed / self.golfPowerSpeed t = math.pow(t, self.golfPowerExponent) power = int(t * 100) % 200 if power > 100: power = 200 - power return power def stopPosHprBroadcast(self): taskName = self.posHprBroadcastName taskMgr.remove(taskName) def startPosHprBroadcast(self): taskName = self.posHprBroadcastName self.b_clearSmoothing() self.d_sendGolfSpotPos() taskMgr.remove(taskName) taskMgr.doMethodLater(self.__broadcastPeriod, self.__posHprBroadcast, taskName) def __posHprBroadcast(self, task): self.d_sendGolfSpotPos() taskName = self.posHprBroadcastName taskMgr.doMethodLater(self.__broadcastPeriod, self.__posHprBroadcast, taskName) return Task.done def d_sendGolfSpotPos(self): timestamp = globalClockDelta.getFrameNetworkTime() self.sendUpdate('setGolfSpotPos', [self.changeSeq, self.root.getH(), timestamp]) def setGolfSpotPos(self, changeSeq, h, timestamp): self.changeSeq = changeSeq if self.smoothStarted: now = globalClock.getFrameTime() local = globalClockDelta.networkToLocalTime(timestamp, now) self.golfSpotSmoother.setH(h) self.golfSpotSmoother.setTimestamp(local) self.golfSpotSmoother.markPosition() else: self.root.setH(h) def b_clearSmoothing(self): self.d_clearSmoothing() self.clearSmoothing() def d_clearSmoothing(self): self.sendUpdate('clearSmoothing', [0]) def clearSmoothing(self, bogus = None): self.golfSpotSmoother.clearPositions(1) def doSmoothTask(self, task): self.golfSpotSmoother.computeAndApplySmoothHpr(self.root) return Task.cont def startSmooth(self): if not self.smoothStarted: taskName = self.smoothName taskMgr.remove(taskName) self.reloadPosition() taskMgr.add(self.doSmoothTask, taskName) self.smoothStarted = 1 def stopSmooth(self): if self.smoothStarted: taskName = self.smoothName taskMgr.remove(taskName) self.forceToTruePosition() self.smoothStarted = 0 def makeToonReleaseInterval(self, toon): def getSlideToPos(toon = toon): return render.getRelativePoint(toon, Point3(0, -5, 0)) if self.gotHitByBoss: grabIval = Sequence(Func(self.detachClub), name='makeToonReleaseInterval-gotHitByBoss') if not toon.isEmpty(): toonIval = Sequence(Func(toon.wrtReparentTo, render), Parallel(ActorInterval(toon, 'slip-backward'), toon.posInterval(0.5, getSlideToPos, fluid=1)), name='makeToonReleaseInterval-toonIval') grabIval.append(toonIval) else: grabIval = Sequence(Func(self.detachClub)) if not toon.isEmpty(): toonIval = Sequence(Parallel(ActorInterval(toon, 'walk', duration=1.0, playRate=-1.0), LerpPosInterval(toon, duration=1.0, pos=Point3(-10, 0, 0))), Func(toon.wrtReparentTo, render)) grabIval.append(toonIval) if localAvatar.doId == toon.doId: if not self.goingToReward and toon.hp > 0: grabIval.append(Func(self.goToFinalBattle)) grabIval.append(Func(self.notify.debug, 'goingToFinalBattlemode')) grabIval.append(Func(self.safeBossToFinalBattleMode)) return grabIval def safeBossToFinalBattleMode(self): if self.boss: self.boss.toFinalBattleMode() def goToFinalBattle(self): if self.cr: place = self.cr.playGame.getPlace() if place and hasattr(place, 'fsm'): curState = place.fsm.getCurrentState().getName() if place.fsm.getCurrentState().getName() == 'crane': place.setState('finalBattle') else: self.notify.debug('NOT going to final battle, state=%s' % curState) def attachClub(self, avId, pointToBall = False): club = self.club if club: av = base.cr.doId2do.get(avId) if av: av.useLOD(1000) lHand = av.getLeftHands()[0] club.setPos(0, 0, 0) club.reparentTo(lHand) netScale = club.getNetTransform().getScale()[1] counterActToonScale = lHand.find('**/counteractToonScale') if counterActToonScale.isEmpty(): counterActToonScale = lHand.attachNewNode('counteractToonScale') counterActToonScale.setScale(1 / netScale) self.notify.debug('creating counterActToonScale for %s' % av.getName()) club.reparentTo(counterActToonScale) club.setX(-0.25 * netScale) if pointToBall: club.lookAt(self.clubLookatSpot) def detachClub(self): if not self.club.isEmpty(): self.club.reparentTo(self.root) self.club.setZ(-20) self.club.setScale(1) def adjustClub(self): club = self.club if club: distance = club.getDistance(self.clubLookatSpot) scaleFactor = distance / 2.058 club.setScale(1, scaleFactor, 1) def startAdjustClubTask(self): taskMgr.add(self.adjustClubTask, self.adjustClubTaskName) def stopAdjustClubTask(self): taskMgr.remove(self.adjustClubTaskName) def adjustClubTask(self, task): self.attachClub(self.avId, True) self.adjustClub() return task.cont def enableControlKey(self): self.controlKeyAllowed = True def disableControlKey(self): self.controlKeyAllowed = False def sendSwingInfo(self, power, angle, sequenceNum): self.sendUpdate('setSwingInfo', [power, angle, sequenceNum]) def startBallPlayback(self, power, angle, sequenceNum): flyBall = self.ballModel.copyTo(NodePath()) flyBall.setScale(1.0) flyBallBubble = self.getFlyBallBubble().instanceTo(NodePath()) flyBallBubble.reparentTo(flyBall) flyBall.setTag('pieSequence', str(sequenceNum)) flyBall.setTag('throwerId', str(self.avId)) t = power / 100.0 t = 1.0 - t dist = 300 - 200 * t time = 1.5 + 0.5 * t proj = ProjectileInterval(None, startPos=Point3(0, 0, 0), endPos=Point3(0, dist, 0), duration=time) relVel = proj.startVel def getVelocity(root = self.root, relVel = relVel): return render.getRelativeVector(root, relVel) fly = Sequence(Func(flyBall.reparentTo, render), Func(flyBall.setPosHpr, self.root, 0, 0, 0, 0, 0, 0), Func(base.cTrav.addCollider, flyBallBubble, self.flyBallHandler), ProjectileInterval(flyBall, startVel=getVelocity, duration=3), Func(flyBall.detachNode), Func(base.cTrav.removeCollider, flyBallBubble), Func(self.notify.debug, 'removed collider'), Func(self.flyBallFinishedFlying, sequenceNum)) flyWithSound = Parallel(fly, SoundInterval(self.hitBallSfx, node=self.root), name='flyWithSound') self.notify.debug('starting flyball track') flyWithSound.start() self.flyBallTracks[sequenceNum] = flyWithSound return def setSwingInfo(self, power, angle, sequenceNum): av = base.cr.doId2do.get(self.avId) self.swingInterval = Sequence() if av: self.stopAdjustClubTask() self.swingInterval = Sequence(ActorInterval(av, 'swing-putt', startFrame=0, endFrame=GolfGlobals.BALL_CONTACT_FRAME), Func(self.startBallPlayback, power, angle, sequenceNum), Func(self.ballModel.hide), ActorInterval(av, 'swing-putt', startFrame=GolfGlobals.BALL_CONTACT_FRAME, endFrame=24), Func(self.ballModel.setScale, 0.1), Func(self.ballModel.show), LerpScaleInterval(self.ballModel, 1.0, Point3(1, 1, 1)), Func(self.enableControlKey)) if av == localAvatar: self.swingInterval.append(Func(self.switchToAnimState, 'GolfPuttLoop', True)) self.swingInterval.start() def getFlyBallBubble(self): if self.__flyBallBubble == None: bubble = CollisionSphere(0, 0, 0, GolfGlobals.GOLF_BALL_RADIUS) node = CollisionNode('flyBallBubble') node.addSolid(bubble) node.setFromCollideMask(ToontownGlobals.PieBitmask | ToontownGlobals.CameraBitmask | ToontownGlobals.FloorBitmask) node.setIntoCollideMask(BitMask32.allOff()) self.__flyBallBubble = NodePath(node) self.flyBallHandler = CollisionHandlerEvent() self.flyBallHandler.addInPattern('flyBallHit-%d' % self.index) return self.__flyBallBubble def __flyBallHit(self, entry): print entry def flyBallFinishedFlying(self, sequence): if self.flyBallTracks.has_key(sequence): del self.flyBallTracks[sequence] def __finishFlyBallTrack(self, sequence): if self.flyBallTracks.has_key(sequence): flyBallTrack = self.flyBallTracks[sequence] del self.flyBallTracks[sequence] flyBallTrack.finish() def flyBallFinishedSplatting(self, sequence): if self.splatTracks.has_key(sequence): del self.splatTracks[sequence] def __flyBallHit(self, entry): if not entry.hasSurfacePoint() or not entry.hasInto(): return if not entry.getInto().isTangible(): return sequence = int(entry.getFromNodePath().getNetTag('pieSequence')) self.__finishFlyBallTrack(sequence) if self.splatTracks.has_key(sequence): splatTrack = self.splatTracks[sequence] del self.splatTracks[sequence] splatTrack.finish() flyBallCode = 0 flyBallCodeStr = entry.getIntoNodePath().getNetTag('pieCode') if flyBallCodeStr: flyBallCode = int(flyBallCodeStr) pos = entry.getSurfacePoint(render) timestamp32 = globalClockDelta.getFrameNetworkTime(bits=32) throwerId = int(entry.getFromNodePath().getNetTag('throwerId')) splat = self.getFlyBallSplatInterval(pos[0], pos[1], pos[2], flyBallCode, throwerId) splat = Sequence(splat, Func(self.flyBallFinishedSplatting, sequence)) self.splatTracks[sequence] = splat splat.start() self.notify.debug('doId=%d into=%s flyBallCode=%d, throwerId=%d' % (self.doId, entry.getIntoNodePath(), flyBallCode, throwerId)) if flyBallCode == ToontownGlobals.PieCodeBossCog and self.avId == localAvatar.doId and self.lastHitSequenceNum != self.__flyBallSequenceNum: self.lastHitSequenceNum = self.__flyBallSequenceNum self.boss.d_ballHitBoss(1) elif flyBallCode == ToontownGlobals.PieCodeToon and self.avId == localAvatar.doId and self.lastHitSequenceNum != self.__flyBallSequenceNum: self.lastHitSequenceNum = self.__flyBallSequenceNum avatarDoId = entry.getIntoNodePath().getNetTag('avatarDoId') if avatarDoId == '': self.notify.warning('Toon %s has no avatarDoId tag.' % repr(entry.getIntoNodePath())) return doId = int(avatarDoId) if doId != localAvatar.doId: pass def getFlyBallSplatInterval(self, x, y, z, flyBallCode, throwerId): from toontown.toonbase import ToontownBattleGlobals from toontown.battle import BattleProps splatName = 'dust' splat = BattleProps.globalPropPool.getProp(splatName) splat.setBillboardPointWorld(2) color = ToontownGlobals.PieCodeColors.get(flyBallCode) if color: splat.setColor(*color) if flyBallCode == ToontownGlobals.PieCodeBossCog: self.notify.debug('changing color to %s' % self.ballColor) splat.setColor(self.ballColor) sound = loader.loadSfx('phase_11/audio/sfx/LB_evidence_miss.ogg') vol = 1.0 if flyBallCode == ToontownGlobals.PieCodeBossCog: sound = loader.loadSfx('phase_4/audio/sfx/Golf_Hit_Barrier_1.ogg') soundIval = SoundInterval(sound, node=splat, volume=vol) if flyBallCode == ToontownGlobals.PieCodeBossCog and localAvatar.doId == throwerId: vol = 1.0 soundIval = SoundInterval(sound, node=localAvatar, volume=vol) ival = Parallel(Func(splat.reparentTo, render), Func(splat.setPos, x, y, z), soundIval, Sequence(ActorInterval(splat, splatName), Func(splat.detachNode))) return ival def setGoingToReward(self): self.goingToReward = True def gotBossZapped(self): self.showExiting() self.d_requestFree(True)
class CollisionManager: def __init__(self): self.line_dir = NodePath() base.cTrav = CollisionTraverser() self.col_handler = CollisionHandlerEvent() picker_node = CollisionNode("mouseRayNode") pickerNPos = base.camera.attachNewNode(picker_node) self.pickerRay = CollisionRay() picker_node.addSolid(self.pickerRay) plane_node = CollisionNode("base_plane") plane = base.render.attachNewNode(plane_node) self.plane_col = CollisionPlane(Plane(Vec3(0, 0, 1), Point3(0, 0, 0))) picker_node.addSolid(self.pickerRay) picker_node.setTag("rays","mray") base.cTrav.addCollider(pickerNPos, self.col_handler) self.col_handler.addInPattern("%(rays)ft-into-%(type)it") self.col_handler.addOutPattern("%(rays)ft-out-%(type)it") self.col_handler.addAgainPattern("ray_again_all%(""rays"")fh%(""type"")ih") self.model = loader.loadModel("../models/chest.egg") self.model_node = NodePath("sdfafd") self.model.reparentTo(self.model_node) self.model_node.reparentTo(render) # # self.text_node = TextNode("battle_text") # self.text_node.setText("TEXTYTEXTYTEXTTEXT") # self.text_node_path = render.attachNewNode(self.text_node) # self.text_node_path.reparentTo(render) # self.text_node_path.setPos(0,0,4) # self.text_node_path.setHpr(0,0,0) # self.text_node_path.setScale(1) # #self.text_node_path.setTransparency(TransparencyAttrib.MAlpha) # self.text_node.setTextColor((1,1,1,1)) # self.text_node.setAlign(TextNode.ALeft) self.placement_ghost = EditorObjects.PlacementGhost(0,"tower",base.object_scale) z=0 self.plane = Plane(Vec3(0, 0, 1), Point3(0, 0, z)) taskMgr.add(self.ray_update, "updatePicker") taskMgr.add(self.get_mouse_plane_pos, "MousePositionOnPlane") taskMgr.add(self.task_mouse_press_check, "checkMousePress") self.input_init() self.pickable=None def input_init(self): self.DO=DirectObject() self.DO.accept('mouse1', self.mouse_click, ["1-down"]) self.DO.accept('mouse1-up', self.mouse_click, ["1-up"]) self.DO.accept('mouse3', self.mouse_click, ["3-down"]) self.DO.accept('0', self.placement_ghost.change_player, [0]) self.DO.accept('1', self.placement_ghost.change_player, [1]) self.DO.accept('2', self.placement_ghost.change_player, [2]) self.DO.accept('a', self.placement_ghost.change_type, ["army"]) self.DO.accept('t', self.placement_ghost.change_type, ["tower"]) self.DO.accept('control-s', base.xml_manager.save) self.DO.accept('mray-into-army', self.col_in_object) self.DO.accept('mray-out-army', self.col_out_object) self.DO.accept('mray-into-tower', self.col_in_object) self.DO.accept('mray-out-tower', self.col_out_object) self.DO.accept('ray_again_all', self.col_against_object) def col_against_object(self,entry): if entry.getIntoNodePath().getParent() != self.pickable: np_from=entry.getFromNodePath() np_into=entry.getIntoNodePath() self.selected_type = np_into.getTag("type") self.pickable = np_into.getParent() def col_in_object(self,entry): if base.state == "selecting": np_into=entry.getIntoNodePath() np_into.getParent().setColor(0.5,0.5,0.5,1) def col_out_object(self,entry): np_into=entry.getIntoNodePath() try: np_into.getParent().clearColor() except: print "ERROR CLEARING COLOUR" def get_mouse_plane_pos(self, task): if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.pos3d = Point3() nearPoint = Point3() farPoint = Point3() base.camLens.extrude(mpos, nearPoint, farPoint) if self.plane.intersectsLine(self.pos3d, render.getRelativePoint(camera, nearPoint), render.getRelativePoint(camera, farPoint)): #print "Mouse ray intersects ground plane at ", self.pos3d self.model_node.setPos(render, self.pos3d) self.placement_ghost.set_position(self.pos3d[0],self.pos3d[1]) return task.again def ray_update(self,task): if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.pickerRay.setFromLens(base.camNode, mpos.getX(),mpos.getY()) return task.cont def task_mouse_place(self,task): if base.mouseWatcherNode.isButtonDown(MouseButton.one()): self.placing_object = True self.place_pos = (self.anchor_x,self.anchor_y) self.line_dir.remove() ls = LineSegs() ls.move_to(self.anchor_x,self.anchor_y,1) ls.draw_to(self.model.getX(),self.model.getY(),1) node = ls.create() angle1 = math.atan2(self.anchor_y - self.anchor_y,self.anchor_x - self.anchor_x+50) angle2 = math.atan2(self.anchor_y - self.model.getY(),self.anchor_x - self.model.getY()); final_angle = angle1-angle2; self.model.setHpr(final_angle,0,0) self.line_dir = NodePath(node) self.line_dir.reparentTo(render) return task.again else: self.line_dir.hide() taskMgr.add(self.task_mouse_press_check, "checkMousePress") return task.done def task_mouse_press_check(self,task): if base.mouseWatcherNode.isButtonDown(MouseButton.one()): #if self.multi_select == True: self.anchor_x,self.anchor_y = self.model.getX(),self.model.getY() taskMgr.add(self.task_mouse_place, "multibox") return task.done return task.again def mouse_click(self,status): print base.state if status == "1-down": if base.state == "placement": if self.placement_ghost.get_type() == "tower": obj = self.placement_ghost.place("tower",self.model.getX(),self.model.getY()) elif self.placement_ghost.get_type() == "army": obj = self.placement_ghost.place("army",self.model.getX(),self.model.getY()) base.details_box.set_object(obj) base.change_state("modifying") elif base.state == "moving": obj = base.details_box.get_object() obj.set_position(self.pos3d[0],self.pos3d[1]) base.change_state("modifying") elif base.state == "selecting" and self.pickable != None: obj = base.get_obj_from_node(self.pickable) base.details_box.set_object(obj,"selecting") base.change_state("modifying") elif status == "1-up": print "Mouse",status elif status == "3-down": if base.state == "placement": base.change_state("selecting") elif base.state == "selecting": base.change_state("placement")
class PartyCogActivity(DirectObject): notify = directNotify.newCategory('PartyCogActivity') cog = None arena = None player = None players = {} def __init__(self, activity, arenaModel=None, texture=None): self.activity = activity self.root = self.activity.root self.toonPieTracks = {} self.toonPieEventNames = {} self.toonIdsToAnimIntervals = {} self.pieIvals = [] self.resultsIval = None self.arenaModel = arenaModel self.texture = texture def load(self): self.arena = loader.loadModel(self.arenaModel) self.arena.reparentTo(self.root) ground = self.arena.find('**/ground') ground.setBin('ground', 1) entranceArrows = self.arena.findAllMatches('**/arrowFlat*') for arrow in entranceArrows: arrow.setBin('ground', 5) self.leftEntranceLocator = self.arena.find('**/leftEntrance_locator') self.rightEntranceLocator = self.arena.find('**/rightEntrance_locator') self.leftExitLocator = self.arena.find('**/leftExit_locator') self.rightExitLocator = self.arena.find('**/rightExit_locator') self.teamCamPosLocators = (self.arena.find('**/team0CamPos_locator'), self.arena.find('**/team1CamPos_locator')) self.teamCamAimLocators = (self.arena.find('**/team0CamAim_locator'), self.arena.find('**/team1CamAim_locator')) leftTeamLocator = NodePath('TeamLocator-%d' % PartyGlobals.TeamActivityTeams.LeftTeam) leftTeamLocator.reparentTo(self.root) leftTeamLocator.setH(90) rightTeamLocator = NodePath('TeamLocator-%d' % PartyGlobals.TeamActivityTeams.RightTeam) rightTeamLocator.reparentTo(self.root) rightTeamLocator.setH(-90) self.teamLocators = (leftTeamLocator, rightTeamLocator) self._lengthBetweenEntrances = self.leftEntranceLocator.getY( ) - self.rightExitLocator.getY() self._skyCollisionsCollection = self.arena.findAllMatches( '**/cogPieArena_sky*_collision') if len(self._skyCollisionsCollection) > 0: self._skyCollisionParent = self._skyCollisionsCollection[ 0].getParent() else: self._skyCollisionParent = self.arena self._wallCollisionsCollection = self.arena.findAllMatches( '**/cogPieArena_wall*_collision') self._arenaFlagGroups = (self.arena.find('**/flagsL_grp'), self.arena.find('**/flagsR_grp')) self._initArenaDoors() self.cogManager = PartyCogManager() self.arrows = [] self.distanceLabels = [] self.teamColors = list(PartyGlobals.CogActivityColors) + [ PartyGlobals.TeamActivityStatusColor ] for i in range(3): start = self.arena.find('**/cog%d_start_locator' % (i + 1)) end = self.arena.find('**/cog%d_end_locator' % (i + 1)) cog = self.cogManager.generateCog(self.arena) cog.setEndPoints(start.getPos(), end.getPos()) arrow1 = StretchingArrow(self.arena, useColor='orange') arrow2 = StretchingArrow(self.arena, useColor='blue') arrow1.setZ(0.1) arrow2.setZ(0.1) self.arrows.append([arrow1, arrow2]) distanceLabel = self.createDistanceLabel(0, self.teamColors[1]) distanceLabel[0].stash() distanceLabel2 = self.createDistanceLabel(0, self.teamColors[0]) distanceLabel2[0].stash() self.distanceLabels.append([distanceLabel, distanceLabel2]) self.winText = [] text1 = self.createText(0, Point3(-0.5, 0.0, -0.5), self.teamColors[1]) text2 = self.createText(1, Point3(0.5, 0.0, -0.5), self.teamColors[0]) self.winText.append(text1) self.winText.append(text2) self.winStatus = self.createText(2, Point3(0.0, 0.0, -0.8), self.teamColors[0]) signLocator = self.arena.find('**/eventSign_locator') self.activity.sign.setPos(signLocator.getPos(self.root)) if self.texture: textureAlpha = self.texture[:-4] + '_a.rgb' reskinTexture = loader.loadTexture(self.texture, textureAlpha) self.arena.find('**/center_grp').setTexture(reskinTexture, 100) self.arena.find('**/leftSide_grp').setTexture(reskinTexture, 100) self.arena.find('**/rightSide_grp').setTexture(reskinTexture, 100) self.enable() def _initArenaDoors(self): self._arenaDoors = (self.arena.find('**/doorL'), self.arena.find('**/doorR')) arenaDoorLocators = (self.arena.find('**/doorL_locator'), self.arena.find('**/doorR_locator')) for i in range(len(arenaDoorLocators)): arenaDoorLocators[i].wrtReparentTo(self._arenaDoors[i]) self._arenaDoorTimers = (self.createDoorTimer( PartyGlobals.TeamActivityTeams.LeftTeam), self.createDoorTimer( PartyGlobals.TeamActivityTeams.RightTeam)) self._arenaDoorIvals = [None, None] self._doorStartPos = [] for i in range(len(self._arenaDoors)): door = self._arenaDoors[i] timer = self._arenaDoorTimers[i] timer.reparentTo(arenaDoorLocators[i]) timer.hide() self._doorStartPos.append(door.getPos()) door.setPos(door, 0, 0, -7.0) def _destroyArenaDoors(self): for ival in self._arenaDoorIvals: ival.finish() self._arenaDoorIvals = None self._arenaDoors = None for timer in self._arenaDoorTimers: timer.stop() timer.removeNode() self._arenaDoorTimers = None def createDoorTimer(self, team): timer = ToontownTimer(useImage=False, highlightNearEnd=False) timer['text_font'] = ToontownGlobals.getMinnieFont() timer.setFontColor(PartyGlobals.CogActivityColors[team]) timer.setScale(7.0) timer.setPos(0.2, -0.03, 0.0) return timer def createText(self, number, position, color): text = TextNode('winText%d' % number) text.setAlign(TextNode.ACenter) text.setTextColor(color) text.setFont(ToontownGlobals.getSignFont()) text.setText('') noteText = aspect2d.attachNewNode(text) noteText.setScale(0.2) noteText.setPos(position) noteText.stash() return text, noteText def createDistanceLabel(self, number, color): text = TextNode('distanceText-%d' % number) text.setAlign(TextNode.ACenter) text.setTextColor(color) text.setFont(ToontownGlobals.getSignFont()) text.setText('10 ft') node = self.root.attachNewNode(text) node.setBillboardPointEye() node.setScale(2.5) node.setZ(5.0) return node, text def unload(self): self.disable() self._cleanupResultsIval() if self.winText is not None: for pair in self.winText: pair[1].reparentTo(hidden) pair[1].removeNode() self.winText = None if self.winStatus is not None: self.winStatus[1].reparentTo(hidden) self.winStatus[1].removeNode() self.winStatus = None if self.cogManager is not None: self.cogManager.unload() self.cogManager = None if self.arrows is not None: for pair in self.arrows: for arrow in pair: arrow.destroy() arrow = None pair = None self.arrows = None if self.distanceLabels is not None: for pair in self.distanceLabels: for node, text in pair: node.removeNode() pair = None self.distanceLabels = None if len(self.players): for player in self.players.values(): player.disable() player.destroy() self.players.clear() self.player = None if self.arena is not None: self.leftEntranceLocator = None self.rightEntranceLocator = None self.leftExitLocator = None self.rightExitLocator = None self._skyCollisions = None self._skyCollisionParent = None self._arenaFlagGroups = None self._destroyArenaDoors() self.arena.removeNode() self.arena = None for ival in self.toonPieTracks.values(): if ival is not None and ival.isPlaying(): try: ival.finish() except Exception as theException: self.notify.warning( 'Ival could not finish:\n %s \nException %s ' % (str(ival), str(theException))) self.toonPieTracks = {} for ival in self.pieIvals: if ival is not None and ival.isPlaying(): try: ival.finish() except Exception as theException: self.notify.warning( 'Ival could not finish:\n %s \nException %s ' % (str(ival), str(theException))) self.pieIvals = [] self.toonIdsToAnimIntervals = {} for eventName in self.toonPieEventNames.values(): self.ignore(eventName) self.toonPieEventNames = {} def enable(self): self.enableEnterGateCollision() def disable(self): self.disableEnterGateCollision() self.ignoreAll() def hideTeamFlags(self, team): self._arenaFlagGroups[team].stash() def showTeamFlags(self, team): self._arenaFlagGroups[team].unstash() def _playArenaDoorIval(self, team, opening=True): ival = self._arenaDoorIvals[team] if ival is not None and ival.isPlaying(): ival.pause() if not opening: pos = self._doorStartPos[team] else: pos = (self._doorStartPos[team] + Point3(0, 0, -7.0), ) ival = self._arenaDoors[team].posInterval(0.75, Point3(0, 0, -7.0), blendType='easeIn') self._arenaDoorIvals[team] = ival ival.start() def openArenaDoorForTeam(self, team): self._playArenaDoorIval(team, opening=False) def closeArenaDoorForTeam(self, team): self._playArenaDoorIval(team, opening=False) def openArenaDoors(self): self.enableEnterGateCollision() for i in range(len(self._arenaDoors)): self.openArenaDoorForTeam(i) def closeArenaDoors(self): self.disableEnterGateCollision() for i in range(len(self._arenaDoors)): self.closeArenaDoorForTeam(i) def showArenaDoorTimers(self, duration): for timer in self._arenaDoorTimers: timer.setTime(duration) timer.countdown(duration) timer.show() def hideArenaDoorTimers(self): for timer in self._arenaDoorTimers: timer.hide() def enableEnterGateCollision(self): self.acceptOnce('entercogPieArena_entranceLeft_collision', self.handleEnterLeftEntranceTrigger) self.acceptOnce('entercogPieArena_entranceRight_collision', self.handleEnterRightEntranceTrigger) def disableEnterGateCollision(self): self.ignore('entercogPieArena_entranceLeft_collision') self.ignore('entercogPieArena_entranceRight_collision') def enableWallCollisions(self): self._wallCollisionsCollection.unstash() def disableWallCollisions(self): self._wallCollisionsCollection.stash() def enableSkyCollisions(self): self._skyCollisionsCollection.unstash() def disableSkyCollisions(self): self._skyCollisionsCollection.stash() def handleEnterLeftEntranceTrigger(self, collEntry): self.activity.d_toonJoinRequest( PartyGlobals.TeamActivityTeams.LeftTeam) def handleEnterRightEntranceTrigger(self, collEntry): self.activity.d_toonJoinRequest( PartyGlobals.TeamActivityTeams.RightTeam) def checkOrthoDriveCollision(self, oldPos, newPos): x = bound(newPos[0], -16.8, 16.8) y = bound(newPos[1], -17.25, -24.1) newPos.setX(x) newPos.setY(y) return newPos def getPlayerStartPos(self, team, spot): if team == PartyGlobals.TeamActivityTeams.LeftTeam: node = self.leftExitLocator else: node = self.rightExitLocator d = self._lengthBetweenEntrances / ( self.activity.getMaxPlayersPerTeam() + 1) yOffset = node.getY(self.root) + d * (spot + 1) pos = node.getPos(self.root) pos.setY(yOffset) return pos def handleToonJoined(self, toon, team, lateEntry=False): pos = self.getPlayerStartPos(team, self.activity.getIndex(toon.doId, team)) if toon == base.localAvatar: player = PartyCogActivityLocalPlayer(self.activity, pos, team, self.handleToonExited) player.entersActivity() self.player = player self.disableSkyCollisions() self.playPlayerEnterIval() else: player = PartyCogActivityPlayer(self.activity, toon, pos, team) player.entersActivity() if lateEntry: player.updateToonPosition() self.players[toon.doId] = player def handleToonSwitchedTeams(self, toon): toonId = toon.doId player = self.players.get(toonId) if player is None: self.notify.warning( 'handleToonSwitchedTeams: toonId %s not found' % toonId) return team = self.activity.getTeam(toonId) spot = self.activity.getIndex(toonId, team) pos = self.getPlayerStartPos(team, spot) self.finishToonIval(toonId) player.setTeam(team) player.setToonStartPosition(pos) player.updateToonPosition() def handleToonShifted(self, toon): toonId = toon.doId if self.players.has_key(toonId): player = self.players[toonId] spot = self.activity.getIndex(toonId, player.team) pos = self.getPlayerStartPos(player.team, spot) player.setToonStartPosition(pos) if self.player is not None and toon == self.player.toon: self.playToonIval(base.localAvatar.doId, self.player.getRunToStartPositionIval()) def handleToonDisabled(self, toonId): self.finishToonIval(toonId) self.finishPieIvals(toonId) player = self.players.get(toonId) if player is not None: player.disable() if player == self.player: self.player = None del self.players[toonId] def finishPieIvals(self, toonId): for ival in self.pieIvals: if ival.isPlaying(): if ival.getName().find(str(toonId)) != -1: ival.finish() def playPlayerEnterIval(self): def conditionallyShowSwitchButton(self=self, enable=True): if enable and self.activity.activityFSM.state in ('WaitForEnough', 'WaitToStart'): self.activity.teamActivityGui.enableSwitchButton() else: self.activity.teamActivityGui.disableSwitchButton() ival = Sequence(Func(self.disableWallCollisions), Func(conditionallyShowSwitchButton, self, False), self.player.getRunToStartPositionIval(), Func(conditionallyShowSwitchButton, self, True), Func(self.enableWallCollisions)) self.playToonIval(base.localAvatar.doId, ival) def finishToonIval(self, toonId): if self.toonIdsToAnimIntervals.get( toonId ) is not None and self.toonIdsToAnimIntervals[toonId].isPlaying(): self.toonIdsToAnimIntervals[toonId].finish() def playToonIval(self, toonId, ival): self.finishToonIval(toonId) self.toonIdsToAnimIntervals[toonId] = ival ival.start() def startActivity(self, timestamp): self.pieHandler = CollisionHandlerEvent() self.pieHandler.setInPattern('pieHit-%fn') if self.player is not None: self.player.resetScore() self.hideTeamFlags(self.player.team) for player in self.players.values(): self.finishToonIval(player.toon.doId) player.enable() for cog in self.cogManager.cogs: cog.request('Active', timestamp) for ival in self.pieIvals: if ival.isPlaying(): ival.finish() self.pieIvals = [] def stopActivity(self): for player in self.players.values(): player.disable() for eventName in self.toonPieEventNames.values(): self.ignore(eventName) self.toonPieEventNames.clear() for cog in self.cogManager.cogs: cog.request('Static') def handleToonExited(self, toon): self.finishToonIval(toon.doId) player = self.players[toon.doId] player.disable() player.exitsActivity() player.destroy() if player == self.player: self.showTeamFlags(self.activity.getTeam(toon.doId)) self.player = None self.enableEnterGateCollision() self.enableSkyCollisions() del self.players[toon.doId] def pieThrow(self, avId, timestamp, heading, pos, power): toon = self.activity.getAvatar(avId) if toon is None: return tossTrack, pieTrack, flyPie = self.getTossPieInterval( toon, pos[0], pos[1], pos[2], heading, 0, 0, power) if avId == base.localAvatar.doId: flyPie.setTag('throwerId', str(avId)) collSphere = CollisionSphere(0, 0, 0, 0.5) collSphere.setTangible(0) name = 'PieSphere-%d' % avId collSphereName = self.activity.uniqueName(name) collNode = CollisionNode(collSphereName) collNode.setFromCollideMask(ToontownGlobals.PieBitmask) collNode.addSolid(collSphere) collNP = flyPie.attachNewNode(collNode) base.cTrav.addCollider(collNP, self.pieHandler) self.toonPieEventNames[collNP] = 'pieHit-' + collSphereName self.accept(self.toonPieEventNames[collNP], self.handlePieCollision) else: player = self.players.get(avId) if player is not None: player.faceForward() def matchRunningAnim(toon=toon): toon.playingAnim = None toon.setSpeed(toon.forwardSpeed, toon.rotateSpeed) newTossTrack = Sequence(tossTrack, Func(matchRunningAnim)) pieTrack = Parallel(newTossTrack, pieTrack, name='PartyCogActivity.pieTrack-%d-%s' % (avId, timestamp)) elapsedTime = globalClockDelta.localElapsedTime(timestamp) if elapsedTime < 16.0 / 24.0: elapsedTime = 16.0 / 24.0 pieTrack.start(elapsedTime) self.pieIvals.append(pieTrack) self.toonPieTracks[avId] = pieTrack def getTossPieInterval(self, toon, x, y, z, h, p, r, power, beginFlyIval=Sequence()): from toontown.toonbase import ToontownBattleGlobals from toontown.battle import BattleProps pie = toon.getPieModel() pie.setScale(0.5) flyPie = pie.copyTo(NodePath('a')) pieName = ToontownBattleGlobals.pieNames[toon.pieType] pieType = BattleProps.globalPropPool.getPropType(pieName) animPie = Sequence() if pieType == 'actor': animPie = ActorInterval(pie, pieName, startFrame=48) sound = loader.loadSfx('phase_3.5/audio/sfx/AA_pie_throw_only.ogg') t = power / 100.0 dist = lerp(PartyGlobals.CogActivityPieMinDist, PartyGlobals.CogActivityPieMaxDist, t) time = lerp(1.0, 1.5, t) proj = ProjectileInterval(None, startPos=Point3(0, 0, 0), endPos=Point3(0, dist, 0), duration=time) relVel = proj.startVel def getVelocity(toon=toon, relVel=relVel): return render.getRelativeVector(toon, relVel) * 0.6 def __safeSetAnimState(toon=toon, state='Happy'): if toon and hasattr(toon, 'animFSM'): toon.setAnimState('Happy') else: self.notify.warning( 'The toon is being destroyed. No attribute animState.') toss = Track((0, Sequence( Func(toon.setPosHpr, x, y, z, h, p, r), Func(pie.reparentTo, toon.rightHand), Func(pie.setPosHpr, 0, 0, 0, 0, 0, 0), animPie, Parallel( ActorInterval(toon, 'throw', startFrame=48, playRate=1.5, partName='torso'), animPie), Func(__safeSetAnimState, toon, 'Happy'))), (16.0 / 24.0, Func(pie.detachNode))) fly = Track( (14.0 / 24.0, SoundInterval( sound, node=toon, cutOff=PartyGlobals.PARTY_COG_CUTOFF)), (16.0 / 24.0, Sequence( Func(flyPie.reparentTo, render), Func(flyPie.setPosHpr, toon, 0.52, 0.97, 2.24, 0, -45, 0), beginFlyIval, ProjectileInterval(flyPie, startVel=getVelocity, duration=6), Func(flyPie.detachNode)))) return toss, fly, flyPie def handlePieCollision(self, colEntry): if not self.activity.isState('Active') or self.player is None: return handled = False into = colEntry.getIntoNodePath() intoName = into.getName() timestamp = globalClockDelta.localToNetworkTime( globalClock.getFrameTime(), bits=32) if 'PartyCog' in intoName: if self.toonPieTracks.get(base.localAvatar.doId) is not None: self.toonPieTracks[base.localAvatar.doId].finish() self.toonPieTracks[base.localAvatar.doId] = None parts = intoName.split('-') cogID = int(parts[1]) point = colEntry.getSurfacePoint(self.cogManager.cogs[cogID].root) cog = self.cogManager.cogs[cogID] hitHead = point.getZ() > cog.getHeadLocation( ) and not parts[2].startswith('Arm') if self.activity.getTeam( base.localAvatar.doId ) == PartyGlobals.TeamActivityTeams.LeftTeam: direction = -1.0 else: direction = 1.0 self.activity.b_pieHitsCog(timestamp, cogID, point, direction, hitHead) if hitHead: hitPoints = self.player.hitHead() else: hitPoints = self.player.hitBody() self.player.updateScore() if hitPoints > 0: cog.showHitScore(hitPoints) handled = True elif 'distAvatarCollNode' in intoName: parts = intoName.split('-') hitToonId = int(parts[1]) toon = base.cr.doId2do.get(hitToonId) if toon is not None and self.activity.getTeam( hitToonId) != self.player.team: point = colEntry.getSurfacePoint(toon) self.activity.b_pieHitsToon(hitToonId, timestamp, point) handled = True if handled: eventName = self.toonPieEventNames.get(colEntry.getFromNodePath()) if eventName is not None: self.ignore(eventName) del self.toonPieEventNames[colEntry.getFromNodePath()] def pieHitsCog(self, timestamp, cogNum, pos, direction, part): cog = self.cogManager.cogs[cogNum] cog.respondToPieHit(timestamp, pos, part, direction) def pieHitsToon(self, toonId, timestamp, pos): player = self.players.get(toonId) if player is not None: player.respondToPieHit(timestamp, pos) def setCogDistances(self, distances): self.cogManager.updateDistances(distances) def showCogs(self): for cog in self.cogManager.cogs: cog.request('Static') def hideCogs(self): for cog in self.cogManager.cogs: cog.request('Down') def showResults(self, resultsText, winner, totals): if self.player is None: return None base.localAvatar.showName() self.resultsIval = Sequence( Wait(0.1), Func(self.activity.setStatus, TTLocalizer.PartyCogTimeUp), Func(self.activity.showStatus), Wait(2.0), Func(self.activity.hideStatus), Wait(0.5), Func(self.player.lookAtArena), Func(self.showTeamFlags, self.activity.getTeam(base.localAvatar.doId)), Wait(1.0), Func(self.showArrow, 0), Wait(1.3), Func(self.showArrow, 1), Wait(1.3), Func(self.showArrow, 2), Wait(1.3), Func(self.showTotals, totals), Wait(1.0), Func(self.showWinner, resultsText, winner), Func(self._cleanupResultsIval), name='PartyCog-conclusionSequence') self.accept('DistributedPartyActivity-showJellybeanReward', self._cleanupResultsIval) self.resultsIval.start() def _cleanupResultsIval(self): if self.resultsIval: if self.resultsIval.isPlaying(): self.resultsIval.pause() self.resultsIval = None self.ignore('DistributedPartyActivity-showJellybeanReward') def showTotals(self, totals): newtotals = (totals[1] - totals[0] + PartyGlobals.CogActivityArenaLength / 2.0 * 3, totals[0] - totals[1] + PartyGlobals.CogActivityArenaLength / 2.0 * 3) self.winText[0][0].setText(TTLocalizer.PartyCogDistance % newtotals[0]) self.winText[1][0].setText(TTLocalizer.PartyCogDistance % newtotals[1]) for textPair in self.winText: textPair[1].unstash() def hideTotals(self): for textPair in self.winText: textPair[0].setText('') textPair[1].stash() def showWinner(self, text, winner): self.winStatus[0].setText(text) self.winStatus[0].setTextColor(self.teamColors[winner]) self.winStatus[1].unstash() def hideWinner(self): self.winStatus[0].setText('') self.winStatus[1].stash() def showArrow(self, arrowNum): arrows = self.arrows[arrowNum] cog = self.cogManager.cogs[arrowNum] points = [ self.arena.find('**/cog%d_start_locator' % (arrowNum + 1)), self.arena.find('**/cog%d_end_locator' % (arrowNum + 1)) ] Y = cog.root.getY() for point in points: point.setY(Y) for i in range(len(arrows)): arrow = arrows[i] arrow.draw(points[i].getPos(), cog.root.getPos(), animate=False) arrow.unstash() i = -1 length = PartyGlobals.CogActivityArenaLength for node, text in self.distanceLabels[arrowNum]: current = bound(i, 0, 1) node.setPos(cog.root.getPos(self.root) + Point3(i * 4, 2, 4)) dist = PartyCogUtils.getCogDistanceUnitsFromCenter(cog.currentT) dist = abs(dist - i * length / 2) if dist > length - dist: node.setScale(2.8) else: node.setScale(2.2) text.setText(TTLocalizer.PartyCogDistance % dist) if dist > 0: node.unstash() else: arrows[current].stash() i += 2 def hideArrows(self): for pair in self.arrows: for arrow in pair: arrow.stash() for pair in self.distanceLabels: for node, text in pair: node.stash() def hideResults(self): self.hideArrows() self.hideTotals() self.hideWinner()
class DistributedGolfSpot(DistributedObject.DistributedObject, FSM.FSM): notify = DirectNotifyGlobal.directNotify.newCategory('DistributedGolfSpot') positions = ((-45, 100, GolfGlobals.GOLF_BALL_RADIUS), (-15, 100, GolfGlobals.GOLF_BALL_RADIUS), (15, 100, GolfGlobals.GOLF_BALL_RADIUS), (45, 100, GolfGlobals.GOLF_BALL_RADIUS)) toonGolfOffsetPos = Point3(-2, 0, -GolfGlobals.GOLF_BALL_RADIUS) toonGolfOffsetHpr = Point3(-90, 0, 0) rotateSpeed = 20 golfPowerSpeed = base.config.GetDouble('golf-power-speed', 3) golfPowerExponent = base.config.GetDouble('golf-power-exponent', 0.75) def __init__(self, cr): DistributedObject.DistributedObject.__init__(self, cr) FSM.FSM.__init__(self, 'DistributedGolfSpot') self.boss = None self.index = None self.avId = 0 self.toon = None self.golfSpotSmoother = SmoothMover() self.golfSpotSmoother.setSmoothMode(SmoothMover.SMOn) self.smoothStarted = 0 self.__broadcastPeriod = 0.2 if self.index > len(self.positions): self.notify.error('Invalid index %d' % index) self.fadeTrack = None self.setupPowerBar() self.aimStart = None self.golfSpotAdviceLabel = None self.changeSeq = 0 self.lastChangeSeq = 0 self.controlKeyAllowed = False self.flyBallTracks = {} self.splatTracks = {} self.__flyBallBubble = None self.flyBallHandler = None self.__flyBallSequenceNum = 0 self.swingInterval = None self.lastHitSequenceNum = -1 self.goingToReward = False self.gotHitByBoss = False self.releaseTrack = None self.grabTrack = None self.restoreScaleTrack = None return def setBossCogId(self, bossCogId): self.bossCogId = bossCogId self.boss = base.cr.doId2do[bossCogId] self.boss.setGolfSpot(self, self.index) def setIndex(self, index): self.index = index def disable(self): DistributedObject.DistributedObject.disable(self) self.ignoreAll() def delete(self): DistributedObject.DistributedObject.delete(self) self.ignoreAll() self.boss = None return def announceGenerate(self): DistributedObject.DistributedObject.announceGenerate(self) self.triggerName = self.uniqueName('trigger') self.triggerEvent = 'enter%s' % self.triggerName self.smoothName = self.uniqueName('golfSpotSmooth') self.golfSpotAdviceName = self.uniqueName('golfSpotAdvice') self.posHprBroadcastName = self.uniqueName('golfSpotBroadcast') self.ballPowerTaskName = self.uniqueName('updateGolfPower') self.adjustClubTaskName = self.uniqueName('adjustClub') self.loadAssets() self.accept('flyBallHit-%d' % self.index, self.__flyBallHit) def loadAssets(self): self.root = render.attachNewNode('golfSpot-%d' % self.index) self.root.setPos(*self.positions[self.index]) self.ballModel = loader.loadModel('phase_6/models/golf/golf_ball') self.ballColor = VBase4(1, 1, 1, 1) if self.index < len(GolfGlobals.PlayerColors): self.ballColor = VBase4(*GolfGlobals.PlayerColors[self.index]) self.ballModel.setColorScale(self.ballColor) self.ballModel.reparentTo(self.root) self.club = loader.loadModel('phase_6/models/golf/putter') self.clubLookatSpot = self.root.attachNewNode('clubLookat') self.clubLookatSpot.setY(-(GolfGlobals.GOLF_BALL_RADIUS + 0.1)) cs = CollisionSphere(0, 0, 0, 1) cs.setTangible(0) cn = CollisionNode(self.triggerName) cn.addSolid(cs) cn.setIntoCollideMask(ToontownGlobals.WallBitmask) self.trigger = self.root.attachNewNode(cn) self.trigger.stash() self.hitBallSfx = loader.loadSfx('phase_6/audio/sfx/Golf_Hit_Ball.ogg') def cleanup(self): if self.swingInterval: self.swingInterval.finish() self.swingInterval = None if self.releaseTrack: self.releaseTrack.finish() self.releaseTrack = None flyTracks = self.flyBallTracks.values() for track in flyTracks: track.finish() if self.fadeTrack: self.fadeTrack.finish() self.fadeTrack = None if self.restoreScaleTrack: self.restoreScaleTrack.finish() self.restoreScaleTrack = None self.root.removeNode() self.ballModel.removeNode() self.club.removeNode() if self.powerBar: self.powerBar.destroy() self.powerBar = None taskMgr.remove(self.triggerName) self.boss = None return def setState(self, state, avId, extraInfo): if not self.isDisabled(): self.gotHitByBoss = extraInfo if state == 'C': self.demand('Controlled', avId) elif state == 'F': self.demand('Free') elif state == 'O': self.demand('Off') else: self.notify.error('Invalid state from AI: %s' % state) def enterOff(self): pass def exitOff(self): pass def enterFree(self): if self.fadeTrack: self.fadeTrack.finish() self.fadeTrack = None self.restoreScaleTrack = Sequence(Wait(6), self.getRestoreScaleInterval(), name='restoreScaleTrack') self.restoreScaleTrack.start() if self.avId == localAvatar.doId: if not self.isDisabled(): self.ballModel.setAlphaScale(0.3) self.ballModel.setTransparency(1) taskMgr.doMethodLater(5, self.__allowDetect, self.triggerName) self.fadeTrack = Sequence(Func(self.ballModel.setTransparency, 1), self.ballModel.colorScaleInterval( 0.2, VBase4(1, 1, 1, 0.3)), name='fadeTrack-enterFree') self.fadeTrack.start() else: self.trigger.unstash() self.accept(self.triggerEvent, self.__hitTrigger) self.avId = 0 return def exitFree(self): if self.fadeTrack: self.fadeTrack.finish() self.fadeTrack = None self.restoreScaleTrack.finish() self.restoreScaleTrack = None taskMgr.remove(self.triggerName) self.ballModel.clearTransparency() self.trigger.stash() self.ignore(self.triggerEvent) return def enterControlled(self, avId): self.avId = avId toon = base.cr.doId2do.get(avId) if not toon: return self.enableControlKey() self.toon = toon self.grabTrack = self.makeToonGrabInterval(toon) if avId == localAvatar.doId: self.boss.toCraneMode() camera.reparentTo(self.root) camera.setPosHpr(0, -10, 3, 0, 0, 0) localAvatar.setPos(self.root, self.toonGolfOffsetPos) localAvatar.setHpr(self.root, self.toonGolfOffsetHpr) localAvatar.sendCurrentPosition() self.__enableControlInterface() self.startPosHprBroadcast() self.accept('exitCrane', self.gotBossZapped) self.grabTrack.start() def exitControlled(self): self.grabTrack.finish() del self.grabTrack if self.swingInterval: self.swingInterval.finish() self.swingInterval = None if not self.ballModel.isEmpty(): if self.ballModel.isHidden(): self.notify.debug('ball is hidden scale =%s' % self.ballModel.getScale()) else: self.notify.debug('ball is showing scale=%s' % self.ballModel.getScale()) if self.toon and not self.toon.isDisabled(): self.toon.startSmooth() self.releaseTrack = self.makeToonReleaseInterval(self.toon) self.stopPosHprBroadcast() self.stopSmooth() if self.avId == localAvatar.doId: self.__disableControlInterface() if not self.goingToReward: camera.reparentTo(base.localAvatar) camera.setPos(base.localAvatar.cameraPositions[0][0]) camera.setHpr(0, 0, 0) self.stopAdjustClubTask() self.releaseTrack.start() self.enableControlKey() return def __allowDetect(self, task): if self.fadeTrack: self.fadeTrack.finish() self.fadeTrack = Sequence(self.ballModel.colorScaleInterval( 0.2, self.ballColor), Func(self.ballModel.clearTransparency), name='fadeTrack-allowDetect') self.fadeTrack.start() self.trigger.unstash() self.accept(self.triggerEvent, self.__hitTrigger) def __hitTrigger(self, event): self.d_requestControl() def getRestoreScaleInterval(self): return Sequence() def d_requestControl(self): self.sendUpdate('requestControl') def d_requestFree(self, gotHitByBoss): self.sendUpdate('requestFree', [gotHitByBoss]) def makeToonGrabInterval(self, toon): origPos = toon.getPos(self.root) origHpr = toon.getHpr(self.root) a = self.accomodateToon(toon) newPos = toon.getPos() newHpr = toon.getHpr() origHpr.setX(PythonUtil.fitSrcAngle2Dest(origHpr[0], newHpr[0])) self.notify.debug('toon.setPosHpr %s %s' % (origPos, origHpr)) toon.setPosHpr(origPos, origHpr) walkTime = 0.2 reach = Sequence() if reach.getDuration() < walkTime: reach = Sequence( ActorInterval(toon, 'walk', loop=1, duration=walkTime - reach.getDuration()), reach) i = Sequence( Parallel(toon.posInterval(walkTime, newPos, origPos), toon.hprInterval(walkTime, newHpr, origHpr), reach), Func(toon.stopLookAround)) if toon == base.localAvatar: i.append(Func(self.switchToAnimState, 'GolfPuttLoop')) i.append(Func(self.startAdjustClubTask)) i = Parallel(i, a) return i def accomodateToon(self, toon): toon.wrtReparentTo(self.root) toon.setPos(self.toonGolfOffsetPos) toon.setHpr(self.toonGolfOffsetHpr) return Sequence() def switchToAnimState(self, animStateName, forced=False): curAnimState = base.localAvatar.animFSM.getCurrentState() curAnimStateName = '' if curAnimState: curAnimStateName = curAnimState.getName() if curAnimStateName != animStateName or forced: base.localAvatar.b_setAnimState(animStateName) def __enableControlInterface(self): gui = loader.loadModel('phase_3.5/models/gui/avatar_panel_gui') self.closeButton = DirectButton(image=(gui.find('**/CloseBtn_UP'), gui.find('**/CloseBtn_DN'), gui.find('**/CloseBtn_Rllvr'), gui.find('**/CloseBtn_UP')), relief=None, scale=2, text=TTLocalizer.BossbotGolfSpotLeave, text_scale=0.04, text_pos=(0, -0.07), text_fg=VBase4(1, 1, 1, 1), pos=(1.05, 0, -0.82), command=self.__exitGolfSpot) self.accept('escape', self.__exitGolfSpot) self.accept('control', self.__controlPressed) self.accept('control-up', self.__controlReleased) self.accept('InputState-forward', self.__upArrow) self.accept('InputState-reverse', self.__downArrow) self.accept('InputState-turnLeft', self.__leftArrow) self.accept('InputState-turnRight', self.__rightArrow) taskMgr.add(self.__watchControls, 'watchGolfSpotControls') taskMgr.doMethodLater(5, self.__displayGolfSpotAdvice, self.golfSpotAdviceName) self.arrowVert = 0 self.arrowHorz = 0 if self.powerBar: self.powerBar.show() return def __disableControlInterface(self): if self.closeButton: self.closeButton.destroy() self.closeButton = None self.__cleanupGolfSpotAdvice() self.ignore('escape') self.ignore('control') self.ignore('control-up') self.ignore('InputState-forward') self.ignore('InputState-reverse') self.ignore('InputState-turnLeft') self.ignore('InputState-turnRight') self.arrowVert = 0 self.arrowHorz = 0 taskMgr.remove('watchGolfSpotControls') if self.powerBar: self.powerBar.hide() else: self.notify.debug('self.powerBar is none') return def setupPowerBar(self): self.powerBar = DirectWaitBar(pos=(0.0, 0, -0.94), relief=DGG.SUNKEN, frameSize=(-2.0, 2.0, -0.2, 0.2), borderWidth=(0.02, 0.02), scale=0.25, range=100, sortOrder=50, frameColor=(0.5, 0.5, 0.5, 0.5), barColor=(1.0, 0.0, 0.0, 1.0), text='', text_scale=0.26, text_fg=(1, 1, 1, 1), text_align=TextNode.ACenter, text_pos=(0, -0.05)) self.power = 0 self.powerBar['value'] = self.power self.powerBar.hide() def resetPowerBar(self): self.power = 0 self.powerBar['value'] = self.power self.powerBar['text'] = '' def __displayGolfSpotAdvice(self, task): if self.golfSpotAdviceLabel == None: self.golfSpotAdviceLabel = DirectLabel( text=TTLocalizer.BossbotGolfSpotAdvice, text_fg=VBase4(1, 1, 1, 1), text_align=TextNode.ACenter, relief=None, pos=(0, 0, 0.69), scale=0.1) return def __cleanupGolfSpotAdvice(self): if self.golfSpotAdviceLabel: self.golfSpotAdviceLabel.destroy() self.golfSpotAdviceLabel = None taskMgr.remove(self.golfSpotAdviceName) return def showExiting(self): if self.closeButton: self.closeButton.destroy() self.closeButton = DirectLabel( relief=None, text=TTLocalizer.BossbotGolfSpotLeaving, pos=(1.05, 0, -0.88), text_pos=(0, 0), text_scale=0.06, text_fg=VBase4(1, 1, 1, 1)) self.__cleanupGolfSpotAdvice() return def __exitGolfSpot(self): self.d_requestFree(False) def __controlPressed(self): if self.controlKeyAllowed: self.__beginFireBall() def __controlReleased(self): if self.controlKeyAllowed: self.__endFireBall() def __upArrow(self, pressed): self.__incrementChangeSeq() self.__cleanupGolfSpotAdvice() if pressed: self.arrowVert = 1 elif self.arrowVert > 0: self.arrowVert = 0 def __downArrow(self, pressed): self.__incrementChangeSeq() self.__cleanupGolfSpotAdvice() if pressed: self.arrowVert = -1 elif self.arrowVert < 0: self.arrowVert = 0 def __rightArrow(self, pressed): self.__incrementChangeSeq() self.__cleanupGolfSpotAdvice() if pressed: self.arrowHorz = 1 self.switchToAnimState('GolfRotateLeft') elif self.arrowHorz > 0: self.arrowHorz = 0 self.switchToAnimState('GolfPuttLoop') def __leftArrow(self, pressed): self.__incrementChangeSeq() self.__cleanupGolfSpotAdvice() if pressed: self.arrowHorz = -1 self.switchToAnimState('GolfRotateRight') elif self.arrowHorz < 0: self.arrowHorz = 0 self.switchToAnimState('GolfPuttLoop') def __watchControls(self, task): if self.arrowHorz: self.__moveGolfSpot(self.arrowHorz) return Task.cont def __moveGolfSpot(self, xd): dt = globalClock.getDt() h = self.root.getH() - xd * self.rotateSpeed * dt h %= 360 limitH = h self.root.setH(limitH) def __incrementChangeSeq(self): self.changeSeq = self.changeSeq + 1 & 255 def __beginFireBall(self): if self.aimStart != None: return if not self.state == 'Controlled': return if not self.avId == localAvatar.doId: return time = globalClock.getFrameTime() self.aimStart = time messenger.send('wakeup') taskMgr.add(self.__updateBallPower, self.ballPowerTaskName) return def __endFireBall(self): if self.aimStart == None: return if not self.state == 'Controlled': return if not self.avId == localAvatar.doId: return taskMgr.remove(self.ballPowerTaskName) self.disableControlKey() messenger.send('wakeup') self.aimStart = None power = self.power angle = self.root.getH() self.notify.debug('incrementing self.__flyBallSequenceNum') self.__flyBallSequenceNum = (self.__flyBallSequenceNum + 1) % 255 self.sendSwingInfo(power, angle, self.__flyBallSequenceNum) self.setSwingInfo(power, angle, self.__flyBallSequenceNum) self.resetPowerBar() return def __updateBallPower(self, task): if not self.powerBar: print '### no power bar!!!' return task.done newPower = self.__getBallPower(globalClock.getFrameTime()) self.power = newPower self.powerBar['value'] = newPower return task.cont def __getBallPower(self, time): elapsed = max(time - self.aimStart, 0.0) t = elapsed / self.golfPowerSpeed t = math.pow(t, self.golfPowerExponent) power = int(t * 100) % 200 if power > 100: power = 200 - power return power def stopPosHprBroadcast(self): taskName = self.posHprBroadcastName taskMgr.remove(taskName) def startPosHprBroadcast(self): taskName = self.posHprBroadcastName self.b_clearSmoothing() self.d_sendGolfSpotPos() taskMgr.remove(taskName) taskMgr.doMethodLater(self.__broadcastPeriod, self.__posHprBroadcast, taskName) def __posHprBroadcast(self, task): self.d_sendGolfSpotPos() taskName = self.posHprBroadcastName taskMgr.doMethodLater(self.__broadcastPeriod, self.__posHprBroadcast, taskName) return Task.done def d_sendGolfSpotPos(self): timestamp = globalClockDelta.getFrameNetworkTime() self.sendUpdate( 'setGolfSpotPos', [self.changeSeq, self.root.getH(), timestamp]) def setGolfSpotPos(self, changeSeq, h, timestamp): self.changeSeq = changeSeq if self.smoothStarted: now = globalClock.getFrameTime() local = globalClockDelta.networkToLocalTime(timestamp, now) self.golfSpotSmoother.setH(h) self.golfSpotSmoother.setTimestamp(local) self.golfSpotSmoother.markPosition() else: self.root.setH(h) def b_clearSmoothing(self): self.d_clearSmoothing() self.clearSmoothing() def d_clearSmoothing(self): self.sendUpdate('clearSmoothing', [0]) def clearSmoothing(self, bogus=None): self.golfSpotSmoother.clearPositions(1) def doSmoothTask(self, task): self.golfSpotSmoother.computeAndApplySmoothHpr(self.root) return Task.cont def startSmooth(self): if not self.smoothStarted: taskName = self.smoothName taskMgr.remove(taskName) self.reloadPosition() taskMgr.add(self.doSmoothTask, taskName) self.smoothStarted = 1 def stopSmooth(self): if self.smoothStarted: taskName = self.smoothName taskMgr.remove(taskName) self.forceToTruePosition() self.smoothStarted = 0 def makeToonReleaseInterval(self, toon): def getSlideToPos(toon=toon): return render.getRelativePoint(toon, Point3(0, -5, 0)) if self.gotHitByBoss: grabIval = Sequence(Func(self.detachClub), name='makeToonReleaseInterval-gotHitByBoss') if not toon.isEmpty(): toonIval = Sequence(Func(toon.wrtReparentTo, render), Parallel( ActorInterval(toon, 'slip-backward'), toon.posInterval(0.5, getSlideToPos, fluid=1)), name='makeToonReleaseInterval-toonIval') grabIval.append(toonIval) else: grabIval = Sequence(Func(self.detachClub)) if not toon.isEmpty(): toonIval = Sequence( Parallel( ActorInterval(toon, 'walk', duration=1.0, playRate=-1.0), LerpPosInterval(toon, duration=1.0, pos=Point3(-10, 0, 0))), Func(toon.wrtReparentTo, render)) grabIval.append(toonIval) if localAvatar.doId == toon.doId: if not self.goingToReward and toon.hp > 0: grabIval.append(Func(self.goToFinalBattle)) grabIval.append( Func(self.notify.debug, 'goingToFinalBattlemode')) grabIval.append(Func(self.safeBossToFinalBattleMode)) return grabIval def safeBossToFinalBattleMode(self): if self.boss: self.boss.toFinalBattleMode() def goToFinalBattle(self): if self.cr: place = self.cr.playGame.getPlace() if place and hasattr(place, 'fsm'): curState = place.fsm.getCurrentState().getName() if place.fsm.getCurrentState().getName() == 'crane': place.setState('finalBattle') else: self.notify.debug('NOT going to final battle, state=%s' % curState) def attachClub(self, avId, pointToBall=False): club = self.club if club: av = base.cr.doId2do.get(avId) if av: av.useLOD(1000) lHand = av.getLeftHands()[0] club.setPos(0, 0, 0) club.reparentTo(lHand) netScale = club.getNetTransform().getScale()[1] counterActToonScale = lHand.find('**/counteractToonScale') if counterActToonScale.isEmpty(): counterActToonScale = lHand.attachNewNode( 'counteractToonScale') counterActToonScale.setScale(1 / netScale) self.notify.debug('creating counterActToonScale for %s' % av.getName()) club.reparentTo(counterActToonScale) club.setX(-0.25 * netScale) if pointToBall: club.lookAt(self.clubLookatSpot) def detachClub(self): if not self.club.isEmpty(): self.club.reparentTo(self.root) self.club.setZ(-20) self.club.setScale(1) def adjustClub(self): club = self.club if club: distance = club.getDistance(self.clubLookatSpot) scaleFactor = distance / 2.058 club.setScale(1, scaleFactor, 1) def startAdjustClubTask(self): taskMgr.add(self.adjustClubTask, self.adjustClubTaskName) def stopAdjustClubTask(self): taskMgr.remove(self.adjustClubTaskName) def adjustClubTask(self, task): self.attachClub(self.avId, True) self.adjustClub() return task.cont def enableControlKey(self): self.controlKeyAllowed = True def disableControlKey(self): self.controlKeyAllowed = False def sendSwingInfo(self, power, angle, sequenceNum): self.sendUpdate('setSwingInfo', [power, angle, sequenceNum]) def startBallPlayback(self, power, angle, sequenceNum): flyBall = self.ballModel.copyTo(NodePath()) flyBall.setScale(1.0) flyBallBubble = self.getFlyBallBubble().instanceTo(NodePath()) flyBallBubble.reparentTo(flyBall) flyBall.setTag('pieSequence', str(sequenceNum)) flyBall.setTag('throwerId', str(self.avId)) t = power / 100.0 t = 1.0 - t dist = 300 - 200 * t time = 1.5 + 0.5 * t proj = ProjectileInterval(None, startPos=Point3(0, 0, 0), endPos=Point3(0, dist, 0), duration=time) relVel = proj.startVel def getVelocity(root=self.root, relVel=relVel): return render.getRelativeVector(root, relVel) fly = Sequence( Func(flyBall.reparentTo, render), Func(flyBall.setPosHpr, self.root, 0, 0, 0, 0, 0, 0), Func(base.cTrav.addCollider, flyBallBubble, self.flyBallHandler), ProjectileInterval(flyBall, startVel=getVelocity, duration=3), Func(flyBall.detachNode), Func(base.cTrav.removeCollider, flyBallBubble), Func(self.notify.debug, 'removed collider'), Func(self.flyBallFinishedFlying, sequenceNum)) flyWithSound = Parallel(fly, SoundInterval(self.hitBallSfx, node=self.root), name='flyWithSound') self.notify.debug('starting flyball track') flyWithSound.start() self.flyBallTracks[sequenceNum] = flyWithSound return def setSwingInfo(self, power, angle, sequenceNum): av = base.cr.doId2do.get(self.avId) self.swingInterval = Sequence() if av: self.stopAdjustClubTask() self.swingInterval = Sequence( ActorInterval(av, 'swing-putt', startFrame=0, endFrame=GolfGlobals.BALL_CONTACT_FRAME), Func(self.startBallPlayback, power, angle, sequenceNum), Func(self.ballModel.hide), ActorInterval(av, 'swing-putt', startFrame=GolfGlobals.BALL_CONTACT_FRAME, endFrame=24), Func(self.ballModel.setScale, 0.1), Func(self.ballModel.show), LerpScaleInterval(self.ballModel, 1.0, Point3(1, 1, 1)), Func(self.enableControlKey)) if av == localAvatar: self.swingInterval.append( Func(self.switchToAnimState, 'GolfPuttLoop', True)) self.swingInterval.start() def getFlyBallBubble(self): if self.__flyBallBubble == None: bubble = CollisionSphere(0, 0, 0, GolfGlobals.GOLF_BALL_RADIUS) node = CollisionNode('flyBallBubble') node.addSolid(bubble) node.setFromCollideMask(ToontownGlobals.PieBitmask | ToontownGlobals.CameraBitmask | ToontownGlobals.FloorBitmask) node.setIntoCollideMask(BitMask32.allOff()) self.__flyBallBubble = NodePath(node) self.flyBallHandler = CollisionHandlerEvent() self.flyBallHandler.addInPattern('flyBallHit-%d' % self.index) return self.__flyBallBubble def __flyBallHit(self, entry): print entry def flyBallFinishedFlying(self, sequence): if self.flyBallTracks.has_key(sequence): del self.flyBallTracks[sequence] def __finishFlyBallTrack(self, sequence): if self.flyBallTracks.has_key(sequence): flyBallTrack = self.flyBallTracks[sequence] del self.flyBallTracks[sequence] flyBallTrack.finish() def flyBallFinishedSplatting(self, sequence): if self.splatTracks.has_key(sequence): del self.splatTracks[sequence] def __flyBallHit(self, entry): if not entry.hasSurfacePoint() or not entry.hasInto(): return if not entry.getInto().isTangible(): return sequence = int(entry.getFromNodePath().getNetTag('pieSequence')) self.__finishFlyBallTrack(sequence) if self.splatTracks.has_key(sequence): splatTrack = self.splatTracks[sequence] del self.splatTracks[sequence] splatTrack.finish() flyBallCode = 0 flyBallCodeStr = entry.getIntoNodePath().getNetTag('pieCode') if flyBallCodeStr: flyBallCode = int(flyBallCodeStr) pos = entry.getSurfacePoint(render) timestamp32 = globalClockDelta.getFrameNetworkTime(bits=32) throwerId = int(entry.getFromNodePath().getNetTag('throwerId')) splat = self.getFlyBallSplatInterval(pos[0], pos[1], pos[2], flyBallCode, throwerId) splat = Sequence(splat, Func(self.flyBallFinishedSplatting, sequence)) self.splatTracks[sequence] = splat splat.start() self.notify.debug( 'doId=%d into=%s flyBallCode=%d, throwerId=%d' % (self.doId, entry.getIntoNodePath(), flyBallCode, throwerId)) if flyBallCode == ToontownGlobals.PieCodeBossCog and self.avId == localAvatar.doId and self.lastHitSequenceNum != self.__flyBallSequenceNum: self.lastHitSequenceNum = self.__flyBallSequenceNum self.boss.d_ballHitBoss(10) elif flyBallCode == ToontownGlobals.PieCodeToon and self.avId == localAvatar.doId and self.lastHitSequenceNum != self.__flyBallSequenceNum: self.lastHitSequenceNum = self.__flyBallSequenceNum avatarDoId = entry.getIntoNodePath().getNetTag('avatarDoId') if avatarDoId == '': self.notify.warning('Toon %s has no avatarDoId tag.' % repr(entry.getIntoNodePath())) return doId = int(avatarDoId) if doId != localAvatar.doId: pass def getFlyBallSplatInterval(self, x, y, z, flyBallCode, throwerId): from toontown.toonbase import ToontownBattleGlobals from toontown.battle import BattleProps splatName = 'dust' splat = BattleProps.globalPropPool.getProp(splatName) splat.setBillboardPointWorld(2) color = ToontownGlobals.PieCodeColors.get(flyBallCode) if color: splat.setColor(*color) if flyBallCode == ToontownGlobals.PieCodeBossCog: self.notify.debug('changing color to %s' % self.ballColor) splat.setColor(self.ballColor) sound = loader.loadSfx('phase_11/audio/sfx/LB_evidence_miss.ogg') vol = 1.0 if flyBallCode == ToontownGlobals.PieCodeBossCog: sound = loader.loadSfx('phase_4/audio/sfx/Golf_Hit_Barrier_1.ogg') soundIval = SoundInterval(sound, node=splat, volume=vol) if flyBallCode == ToontownGlobals.PieCodeBossCog and localAvatar.doId == throwerId: vol = 1.0 soundIval = SoundInterval(sound, node=localAvatar, volume=vol) ival = Parallel( Func(splat.reparentTo, render), Func(splat.setPos, x, y, z), soundIval, Sequence(ActorInterval(splat, splatName), Func(splat.detachNode))) return ival def setGoingToReward(self): self.goingToReward = True def gotBossZapped(self): self.showExiting() self.d_requestFree(True)
class CogdoMazeLocalPlayer(CogdoMazePlayer): notify = directNotify.newCategory('CogdoMazeLocalPlayer') def __init__(self, id, toon, game, guiMgr): CogdoMazePlayer.__init__(self, id, toon) self.disableGagCollision() self.game = game self.maze = self.game.maze self._guiMgr = guiMgr self.cameraMgr = CogdoMazeCameraManager(self.toon, self.maze, camera, render) self._proximityRadius = self.maze.cellWidth * Globals.CameraRemoteToonRadius orthoDrive = OrthoDrive(Globals.ToonRunSpeed, maxFrameMove=self.maze.cellWidth / 2, customCollisionCallback=self.maze.doOrthoCollisions, wantSound=True) self.orthoWalk = OrthoWalk(orthoDrive) self._audioMgr = base.cogdoGameAudioMgr self._getMemoSfx = self._audioMgr.createSfx('getMemo', source=self.toon) self._waterCoolerFillSfx = self._audioMgr.createSfx('waterCoolerFill', source=self.toon) self._hitByDropSfx = self._audioMgr.createSfx('toonHitByDrop', source=self.toon) self._winSfx = self._audioMgr.createSfx('win') self._loseSfx = self._audioMgr.createSfx('lose') self.enabled = False self.pickupCount = 0 self.numEntered = 0 self.throwPending = False self.coolDownAfterHitInterval = Sequence(Wait(Globals.HitCooldownTime), Func(self.setInvulnerable, False), name='coolDownAfterHitInterval-%i' % self.toon.doId) self.invulnerable = False self.gagHandler = CollisionHandlerEvent() self.gagHandler.addInPattern('%fn-into-%in') self.exited = False self.hints = {'find': False, 'throw': False, 'squashed': False, 'boss': False, 'minion': False} self.accept('control', self.controlKeyPressed) def destroy(self): self.toon.showName() self.ignoreAll() self.coolDownAfterHitInterval.clearToInitial() del self.coolDownAfterHitInterval del self._getMemoSfx del self._waterCoolerFillSfx del self._hitByDropSfx del self._winSfx self.orthoWalk.stop() self.orthoWalk.destroy() del self.orthoWalk CogdoMazePlayer.destroy(self) def __initCollisions(self): collSphere = CollisionSphere(0, 0, 0, Globals.PlayerCollisionRadius) collSphere.setTangible(0) self.mazeCollisionName = Globals.LocalPlayerCollisionName collNode = CollisionNode(self.mazeCollisionName) collNode.addSolid(collSphere) collNodePath = self.toon.attachNewNode(collNode) collNodePath.hide() handler = CollisionHandlerEvent() handler.addInPattern('%fn-into-%in') base.cTrav.addCollider(collNodePath, handler) self.handler = handler self._collNodePath = collNodePath def clearCollisions(self): self.handler.clear() def __disableCollisions(self): self._collNodePath.removeNode() del self._collNodePath def _isNearPlayer(self, player): return self.toon.getDistance(player.toon) <= self._proximityRadius def update(self, dt): if self.getCurrentOrNextState() != 'Off': self._updateCamera(dt) def _updateCamera(self, dt): numPlayers = 0.0 for player in self.game.players: if player != self and player.toon and self._isNearPlayer(player): numPlayers += 1 d = clamp(Globals.CameraMinDistance + numPlayers / (CogdoGameConsts.MaxPlayers - 1) * (Globals.CameraMaxDistance - Globals.CameraMinDistance), Globals.CameraMinDistance, Globals.CameraMaxDistance) self.cameraMgr.setCameraTargetDistance(d) self.cameraMgr.update(dt) def enterOff(self): CogdoMazePlayer.enterOff(self) def exitOff(self): CogdoMazePlayer.exitOff(self) self.toon.hideName() def enterReady(self): CogdoMazePlayer.enterReady(self) self.cameraMgr.enable() def exitReady(self): CogdoMazePlayer.enterReady(self) def enterNormal(self): CogdoMazePlayer.enterNormal(self) self.orthoWalk.start() def exitNormal(self): CogdoMazePlayer.exitNormal(self) self.orthoWalk.stop() def enterHit(self, elapsedTime = 0.0): CogdoMazePlayer.enterHit(self, elapsedTime) self.setInvulnerable(True) def exitHit(self): CogdoMazePlayer.exitHit(self) self.coolDownAfterHitInterval.clearToInitial() self.coolDownAfterHitInterval.start() def enterDone(self): CogdoMazePlayer.enterDone(self) self._guiMgr.hideQuestArrow() self.ignore('control') self._guiMgr.setMessage('') if self.exited == False: self.lostMemos() def exitDone(self): CogdoMazePlayer.exitDone(self) def hitByDrop(self): if self.equippedGag is not None and not self.hints['squashed']: self._guiMgr.setMessageTemporary(TTLocalizer.CogdoMazeSquashHint, Globals.HintTimeout) self.hints['squashed'] = True self._hitByDropSfx.play() CogdoMazePlayer.hitByDrop(self) return def equipGag(self): CogdoMazePlayer.equipGag(self) self._waterCoolerFillSfx.play() messenger.send(Globals.WaterCoolerHideEventName, []) if not self.hints['throw']: self._guiMgr.setMessage(TTLocalizer.CogdoMazeThrowHint) self.hints['throw'] = True def hitSuit(self, suitType): if suitType == Globals.SuitTypes.Boss and not self.hints['boss']: self._guiMgr.setMessageTemporary(TTLocalizer.CogdoMazeBossHint, Globals.HintTimeout) self.hints['boss'] = True if suitType != Globals.SuitTypes.Boss and not self.hints['minion']: self._guiMgr.setMessageTemporary(TTLocalizer.CogdoMazeMinionHint, Globals.HintTimeout) self.hints['minion'] = True def createThrowGag(self, gag): throwGag = CogdoMazePlayer.createThrowGag(self, gag) collSphere = CollisionSphere(0, 0, 0, 0.5) collSphere.setTangible(0) name = Globals.GagCollisionName collNode = CollisionNode(name) collNode.setFromCollideMask(ToontownGlobals.PieBitmask) collNode.addSolid(collSphere) colNp = throwGag.attachNewNode(collNode) base.cTrav.addCollider(colNp, self.gagHandler) return throwGag def showToonThrowingGag(self, heading, pos): self._guiMgr.clearMessage() return CogdoMazePlayer.showToonThrowingGag(self, heading, pos) def removeGag(self): if self.equippedGag is None: return CogdoMazePlayer.removeGag(self) self.throwPending = False messenger.send(Globals.WaterCoolerShowEventName, []) return def controlKeyPressed(self): if self.game.finished or self.throwPending or self.getCurrentOrNextState() == 'Hit' or self.equippedGag == None: return self.throwPending = True heading = self.toon.getH() pos = self.toon.getPos() self.game.requestUseGag(pos.getX(), pos.getY(), heading) return def completeThrow(self): self.clearCollisions() CogdoMazePlayer.completeThrow(self) def shakeCamera(self, strength): self.cameraMgr.shake(strength) def getCameraShake(self): return self.cameraMgr.shakeStrength def setInvulnerable(self, bool): self.invulnerable = bool def handleGameStart(self): self.numEntered = len(self.game.players) self.__initCollisions() self._guiMgr.startGame(TTLocalizer.CogdoMazeFindHint) self.hints['find'] = True self.notify.info('toonId:%d laff:%d/%d %d player(s) started maze game' % (self.toon.doId, self.toon.hp, self.toon.maxHp, len(self.game.players))) def handleGameExit(self): self.cameraMgr.disable() self.__disableCollisions() def handlePickUp(self, toonId): if toonId == self.toon.doId: self.pickupCount += 1 self._guiMgr.setPickupCount(self.pickupCount) if self.pickupCount == 1: self._guiMgr.showPickupCounter() self._getMemoSfx.play() def handleOpenDoor(self, door): self._guiMgr.setMessage(TTLocalizer.CogdoMazeGameDoorOpens) self._guiMgr.showQuestArrow(self.toon, door, Point3(0, 0, self.toon.getHeight() + 2)) def handleTimeAlert(self): self._guiMgr.setMessageTemporary(TTLocalizer.CogdoMazeGameTimeAlert) def handleToonRevealsDoor(self, toonId, door): if toonId == self.toon.doId: self._guiMgr.setMessageTemporary(TTLocalizer.CogdoMazeGameLocalToonFoundExit) def handleToonEntersDoor(self, toonId, door): self.exited = True message = '' if door.getPlayerCount() < len(self.game.players): message = TTLocalizer.WaitingForOtherToons if toonId == self.toon.doId: self._guiMgr.setMessage(message) self._winSfx.play() self._audioMgr.stopMusic() self.notify.info('toonId:%d laff:%d/%d %d player(s) succeeded in maze game. Going to the executive suit building.' % (toonId, self.toon.hp, self.toon.maxHp, len(self.game.players))) if self.numEntered > len(self.game.players): self.notify.info('%d player(s) failed in maze game' % (self.numEntered - len(self.game.players))) def lostMemos(self): self.pickupCount = 0 self._guiMgr.setMessageTemporary(TTLocalizer.CogdoMazeGameTimeOut) self._guiMgr.setPickupCount(self.pickupCount) self.notify.info('toonId:%d laff:%d/%d %d player(s) failed in maze game' % (self.toon.doId, self.toon.hp, self.toon.maxHp, len(self.game.players)))
class DistributedCogThiefGame(DistributedMinigame): notify = directNotify.newCategory('DistributedCogThiefGame') ToonSpeed = CTGG.ToonSpeed StageHalfWidth = 200.0 StageHalfHeight = 100.0 BarrelScale = 0.25 TOON_Z = 0 UPDATE_SUITS_TASK = 'CogThiefGameUpdateSuitsTask' REWARD_COUNTDOWN_TASK = 'cogThiefGameRewardCountdown' ControlKeyLimitTime = 1.0 def __init__(self, cr): DistributedMinigame.__init__(self, cr) self.gameFSM = ClassicFSM.ClassicFSM('DistributedCogThiefGame', [ State.State('off', self.enterOff, self.exitOff, ['play']), State.State('play', self.enterPlay, self.exitPlay, ['cleanup']), State.State('cleanup', self.enterCleanup, self.exitCleanup, []) ], 'off', 'cleanup') self.addChildGameFSM(self.gameFSM) self.cameraTopView = (0, 0, 55, 0, -90.0, 0) self.barrels = [] self.cogInfo = {} self.lastTimeControlPressed = 0 self.stolenBarrels = [] self.useOrthoWalk = base.config.GetBool('cog-thief-ortho', 1) self.resultIval = None self.gameIsEnding = False self.__textGen = TextNode('cogThiefGame') self.__textGen.setFont(ToontownGlobals.getSignFont()) self.__textGen.setAlign(TextNode.ACenter) return def getTitle(self): return TTLocalizer.CogThiefGameTitle def getInstructions(self): return TTLocalizer.CogThiefGameInstructions def getMaxDuration(self): return 0 def load(self): self.notify.debug('load') DistributedMinigame.load(self) self.music = base.loadMusic('phase_4/audio/bgm/MG_CogThief.ogg') self.initCogInfo() for barrelIndex in xrange(CTGG.NumBarrels): barrel = loader.loadModel( 'phase_4/models/minigames/cogthief_game_gagTank') barrel.setPos(CTGG.BarrelStartingPositions[barrelIndex]) barrel.setScale(self.BarrelScale) barrel.reparentTo(render) barrel.setTag('barrelIndex', str(barrelIndex)) collSphere = CollisionSphere(0, 0, 0, 4) collSphere.setTangible(0) name = 'BarrelSphere-%d' % barrelIndex collSphereName = self.uniqueName(name) collNode = CollisionNode(collSphereName) collNode.setFromCollideMask(CTGG.BarrelBitmask) collNode.addSolid(collSphere) colNp = barrel.attachNewNode(collNode) handler = CollisionHandlerEvent() handler.setInPattern('barrelHit-%fn') base.cTrav.addCollider(colNp, handler) self.accept('barrelHit-' + collSphereName, self.handleEnterBarrel) nodeToHide = '**/gagMoneyTen' if barrelIndex % 2: nodeToHide = '**/gagMoneyFive' iconToHide = barrel.find(nodeToHide) if not iconToHide.isEmpty(): iconToHide.hide() self.barrels.append(barrel) self.gameBoard = loader.loadModel( 'phase_4/models/minigames/cogthief_game') self.gameBoard.find('**/floor_TT').hide() self.gameBoard.find('**/floor_DD').hide() self.gameBoard.find('**/floor_DG').hide() self.gameBoard.find('**/floor_MM').hide() self.gameBoard.find('**/floor_BR').hide() self.gameBoard.find('**/floor_DL').hide() zone = self.getSafezoneId() if zone == ToontownGlobals.ToontownCentral: self.gameBoard.find('**/floor_TT').show() elif zone == ToontownGlobals.DonaldsDock: self.gameBoard.find('**/floor_DD').show() elif zone == ToontownGlobals.DaisyGardens: self.gameBoard.find('**/floor_DG').show() elif zone == ToontownGlobals.MinniesMelodyland: self.gameBoard.find('**/floor_MM').show() elif zone == ToontownGlobals.TheBrrrgh: self.gameBoard.find('**/floor_BR').show() elif zone == ToontownGlobals.DonaldsDreamland: self.gameBoard.find('**/floor_DL').show() else: self.gameBoard.find('**/floor_TT').show() self.gameBoard.setPosHpr(0, 0, 0, 0, 0, 0) self.gameBoard.setScale(1.0) self.toonSDs = {} avId = self.localAvId toonSD = CogThiefGameToonSD.CogThiefGameToonSD(avId, self) self.toonSDs[avId] = toonSD toonSD.load() self.loadCogs() self.toonHitTracks = {} self.toonPieTracks = {} self.sndOof = base.loadSfx('phase_4/audio/sfx/MG_cannon_hit_dirt.ogg') self.sndRewardTick = base.loadSfx( 'phase_3.5/audio/sfx/tick_counter.ogg') self.sndPerfect = base.loadSfx('phase_4/audio/sfx/ring_perfect.ogg') self.timer = ToontownTimer.ToontownTimer() self.timer.posInTopRightCorner() self.timer.hide() purchaseModels = loader.loadModel('phase_4/models/gui/purchase_gui') self.jarImage = purchaseModels.find('**/Jar') self.jarImage.reparentTo(hidden) self.rewardPanel = DirectLabel(parent=hidden, relief=None, pos=(-0.173, 0.0, -0.55), scale=0.65, text='', text_scale=0.2, text_fg=(0.95, 0.95, 0, 1), text_pos=(0, -.13), text_font=ToontownGlobals.getSignFont(), image=self.jarImage) self.rewardPanelTitle = DirectLabel(parent=self.rewardPanel, relief=None, pos=(0, 0, 0.06), scale=0.08, text=TTLocalizer.CannonGameReward, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1)) return def unload(self): self.notify.debug('unload') DistributedMinigame.unload(self) del self.music self.removeChildGameFSM(self.gameFSM) del self.gameFSM self.gameBoard.removeNode() del self.gameBoard for barrel in self.barrels: barrel.removeNode() del self.barrels for avId in self.toonSDs.keys(): toonSD = self.toonSDs[avId] toonSD.unload() del self.toonSDs self.timer.destroy() del self.timer self.rewardPanel.destroy() del self.rewardPanel self.jarImage.removeNode() del self.jarImage del self.sndRewardTick def onstage(self): self.notify.debug('onstage') DistributedMinigame.onstage(self) self.gameBoard.reparentTo(render) lt = base.localAvatar lt.reparentTo(render) self.__placeToon(self.localAvId) lt.setSpeed(0, 0) self.moveCameraToTop() toonSD = self.toonSDs[self.localAvId] toonSD.enter() toonSD.fsm.request('normal') self.stopGameWalk() for cogIndex in xrange(self.getNumCogs()): suit = self.cogInfo[cogIndex]['suit'].suit pos = self.cogInfo[cogIndex]['pos'] suit.reparentTo(self.gameBoard) suit.setPos(pos) suit.nametag3d.stash() suit.nametag.destroy() for avId in self.avIdList: self.toonHitTracks[avId] = Wait(0.1) self.toonRNGs = [] for i in xrange(self.numPlayers): self.toonRNGs.append(RandomNumGen.RandomNumGen(self.randomNumGen)) self.sndTable = { 'hitBySuit': [None] * self.numPlayers, 'falling': [None] * self.numPlayers } for i in xrange(self.numPlayers): self.sndTable['hitBySuit'][i] = base.loadSfx( 'phase_4/audio/sfx/MG_Tag_C.ogg') self.sndTable['falling'][i] = base.loadSfx( 'phase_4/audio/sfx/MG_cannon_whizz.ogg') base.playMusic(self.music, looping=1, volume=0.8) self.introTrack = self.getIntroTrack() self.introTrack.start() return def offstage(self): self.notify.debug('offstage') self.gameBoard.hide() self.music.stop() for barrel in self.barrels: barrel.hide() for avId in self.toonSDs.keys(): self.toonSDs[avId].exit() for avId in self.avIdList: av = self.getAvatar(avId) if av: av.resetLOD() self.timer.reparentTo(hidden) self.rewardPanel.reparentTo(hidden) if self.introTrack.isPlaying(): self.introTrack.finish() del self.introTrack DistributedMinigame.offstage(self) def handleDisabledAvatar(self, avId): self.notify.debug('handleDisabledAvatar') self.notify.debug('avatar ' + str(avId) + ' disabled') self.toonSDs[avId].exit(unexpectedExit=True) del self.toonSDs[avId] DistributedMinigame.handleDisabledAvatar(self, avId) def setGameReady(self): if not self.hasLocalToon: return self.notify.debug('setGameReady') if DistributedMinigame.setGameReady(self): return for avId in self.remoteAvIdList: toon = self.getAvatar(avId) if toon: toon.reparentTo(render) self.__placeToon(avId) toon.useLOD(1000) toonSD = CogThiefGameToonSD.CogThiefGameToonSD(avId, self) self.toonSDs[avId] = toonSD toonSD.load() toonSD.enter() toonSD.fsm.request('normal') toon.startSmooth() def setGameStart(self, timestamp): if not self.hasLocalToon: return self.notify.debug('setGameStart') DistributedMinigame.setGameStart(self, timestamp) if not base.config.GetBool('cog-thief-endless', 0): self.timer.show() self.timer.countdown(CTGG.GameTime, self.__gameTimerExpired) self.clockStopTime = None self.rewardPanel.reparentTo(base.a2dTopRight) self.scoreMult = MinigameGlobals.getScoreMult(self.cr.playGame.hood.id) self.__startRewardCountdown() if self.introTrack.isPlaying(): self.introTrack.finish() self.gameFSM.request('play') return def enterOff(self): self.notify.debug('enterOff') def exitOff(self): pass def enterPlay(self): self.notify.debug('enterPlay') self.startGameWalk() self.spawnUpdateSuitsTask() self.accept('control', self.controlKeyPressed) self.pieHandler = CollisionHandlerEvent() self.pieHandler.setInPattern('pieHit-%fn') def exitPlay(self): self.ignore('control') if self.resultIval and self.resultIval.isPlaying(): self.resultIval.finish() self.resultIval = None return def enterCleanup(self): self.__killRewardCountdown() if hasattr(self, 'jarIval'): self.jarIval.finish() del self.jarIval for key in self.toonHitTracks: ival = self.toonHitTracks[key] if ival.isPlaying(): ival.finish() self.toonHitTracks = {} for key in self.toonPieTracks: ival = self.toonPieTracks[key] if ival.isPlaying(): ival.finish() self.toonPieTracks = {} for key in self.cogInfo: cogThief = self.cogInfo[key]['suit'] cogThief.cleanup() self.removeUpdateSuitsTask() self.notify.debug('enterCleanup') def exitCleanup(self): pass def __placeToon(self, avId): toon = self.getAvatar(avId) if toon: index = self.avIdList.index(avId) toon.setPos(CTGG.ToonStartingPositions[index]) toon.setHpr(0, 0, 0) def moveCameraToTop(self): camera.reparentTo(render) p = self.cameraTopView camera.setPosHpr(p[0], p[1], p[2], p[3], p[4], p[5]) base.camLens.setMinFov(46 / (4. / 3.)) camera.setZ(camera.getZ() + base.config.GetFloat('cog-thief-z-camera-adjust', 0.0)) def destroyGameWalk(self): self.notify.debug('destroyOrthoWalk') if self.useOrthoWalk: self.gameWalk.destroy() del self.gameWalk else: self.notify.debug('TODO destroyGameWalk') def initGameWalk(self): self.notify.debug('startOrthoWalk') if self.useOrthoWalk: def doCollisions(oldPos, newPos, self=self): x = bound(newPos[0], CTGG.StageHalfWidth, -CTGG.StageHalfWidth) y = bound(newPos[1], CTGG.StageHalfHeight, -CTGG.StageHalfHeight) newPos.setX(x) newPos.setY(y) return newPos orthoDrive = OrthoDrive(self.ToonSpeed, customCollisionCallback=doCollisions, instantTurn=True) self.gameWalk = OrthoWalk(orthoDrive, broadcast=not self.isSinglePlayer()) else: self.gameWalk = CogThiefWalk.CogThiefWalk('walkDone') forwardSpeed = self.ToonSpeed / 2.0 base.mouseInterfaceNode.setForwardSpeed(forwardSpeed) multiplier = forwardSpeed / ToontownGlobals.ToonForwardSpeed base.mouseInterfaceNode.setRotateSpeed( ToontownGlobals.ToonRotateSpeed * 4) def initCogInfo(self): for cogIndex in xrange(self.getNumCogs()): self.cogInfo[cogIndex] = { 'pos': Point3(CTGG.CogStartingPositions[cogIndex]), 'goal': CTGG.NoGoal, 'goalId': CTGG.InvalidGoalId, 'suit': None } return def loadCogs(self): suitTypes = ['ds', 'ac', 'bc', 'ms'] for suitIndex in xrange(self.getNumCogs()): st = self.randomNumGen.choice(suitTypes) suit = CogThief.CogThief(suitIndex, st, self, self.getCogSpeed()) self.cogInfo[suitIndex]['suit'] = suit def handleEnterSphere(self, colEntry): if self.gameIsEnding: return intoName = colEntry.getIntoNodePath().getName() fromName = colEntry.getFromNodePath().getName() debugInto = intoName.split('/') debugFrom = fromName.split('/') self.notify.debug( 'handleEnterSphere gametime=%s %s into %s' % (self.getCurrentGameTime(), debugFrom[-1], debugInto[-1])) intoName = colEntry.getIntoNodePath().getName() if 'CogThiefSphere' in intoName: parts = intoName.split('-') suitNum = int(parts[1]) self.localToonHitBySuit(suitNum) def localToonHitBySuit(self, suitNum): self.notify.debug('localToonHitBySuit %d' % suitNum) timestamp = globalClockDelta.localToNetworkTime( globalClock.getFrameTime(), bits=32) pos = self.cogInfo[suitNum]['suit'].suit.getPos() self.sendUpdate( 'hitBySuit', [self.localAvId, timestamp, suitNum, pos[0], pos[1], pos[2]]) self.showToonHitBySuit(self.localAvId, timestamp) self.makeSuitRespondToToonHit(timestamp, suitNum) def hitBySuit(self, avId, timestamp, suitNum, x, y, z): if not self.hasLocalToon: return if self.gameFSM.getCurrentState().getName() not in ['play']: self.notify.warning('ignoring msg: av %s hit by suit' % avId) return if self.gameIsEnding: return self.notify.debug('avatar ' + ` avId ` + ' hit by a suit') if avId != self.localAvId: self.showToonHitBySuit(avId, timestamp) self.makeSuitRespondToToonHit(timestamp, suitNum) def showToonHitBySuit(self, avId, timestamp): toon = self.getAvatar(avId) if toon == None: return rng = self.toonRNGs[self.avIdList.index(avId)] curPos = toon.getPos(render) oldTrack = self.toonHitTracks[avId] if oldTrack.isPlaying(): oldTrack.finish() toon.setPos(curPos) toon.setZ(self.TOON_Z) parentNode = render.attachNewNode('mazeFlyToonParent-' + ` avId `) parentNode.setPos(toon.getPos()) toon.reparentTo(parentNode) toon.setPos(0, 0, 0) startPos = parentNode.getPos() dropShadow = toon.dropShadow.copyTo(parentNode) dropShadow.setScale(toon.dropShadow.getScale(render)) trajectory = Trajectory.Trajectory(0, Point3(0, 0, 0), Point3(0, 0, 50), gravMult=1.0) oldFlyDur = trajectory.calcTimeOfImpactOnPlane(0.0) trajectory = Trajectory.Trajectory(0, Point3(0, 0, 0), Point3(0, 0, 50), gravMult=0.55) flyDur = trajectory.calcTimeOfImpactOnPlane(0.0) avIndex = self.avIdList.index(avId) endPos = CTGG.ToonStartingPositions[avIndex] def flyFunc(t, trajectory, startPos=startPos, endPos=endPos, dur=flyDur, moveNode=parentNode, flyNode=toon): u = t / dur moveNode.setX(startPos[0] + u * (endPos[0] - startPos[0])) moveNode.setY(startPos[1] + u * (endPos[1] - startPos[1])) flyNode.setPos(trajectory.getPos(t)) flyTrack = Sequence(LerpFunctionInterval(flyFunc, fromData=0.0, toData=flyDur, duration=flyDur, extraArgs=[trajectory]), name=toon.uniqueName('hitBySuit-fly')) geomNode = toon.getGeomNode() startHpr = geomNode.getHpr() destHpr = Point3(startHpr) hRot = rng.randrange(1, 8) if rng.choice([0, 1]): hRot = -hRot destHpr.setX(destHpr[0] + hRot * 360) spinHTrack = Sequence(LerpHprInterval(geomNode, flyDur, destHpr, startHpr=startHpr), Func(geomNode.setHpr, startHpr), name=toon.uniqueName('hitBySuit-spinH')) parent = geomNode.getParent() rotNode = parent.attachNewNode('rotNode') geomNode.reparentTo(rotNode) rotNode.setZ(toon.getHeight() / 2.0) oldGeomNodeZ = geomNode.getZ() geomNode.setZ(-toon.getHeight() / 2.0) startHpr = rotNode.getHpr() destHpr = Point3(startHpr) pRot = rng.randrange(1, 3) if rng.choice([0, 1]): pRot = -pRot destHpr.setY(destHpr[1] + pRot * 360) spinPTrack = Sequence(LerpHprInterval(rotNode, flyDur, destHpr, startHpr=startHpr), Func(rotNode.setHpr, startHpr), name=toon.uniqueName('hitBySuit-spinP')) i = self.avIdList.index(avId) soundTrack = Sequence(Func(base.playSfx, self.sndTable['hitBySuit'][i]), Wait(flyDur * (2.0 / 3.0)), SoundInterval(self.sndTable['falling'][i], duration=flyDur * (1.0 / 3.0)), name=toon.uniqueName('hitBySuit-soundTrack')) def preFunc(self=self, avId=avId, toon=toon, dropShadow=dropShadow): forwardSpeed = toon.forwardSpeed rotateSpeed = toon.rotateSpeed if avId == self.localAvId: self.stopGameWalk() else: toon.stopSmooth() if forwardSpeed or rotateSpeed: toon.setSpeed(forwardSpeed, rotateSpeed) toon.dropShadow.hide() def postFunc(self=self, avId=avId, oldGeomNodeZ=oldGeomNodeZ, dropShadow=dropShadow, parentNode=parentNode): if avId == self.localAvId: base.localAvatar.setPos(endPos) if hasattr(self, 'gameWalk'): toon = base.localAvatar toon.setSpeed(0, 0) self.startGameWalk() dropShadow.removeNode() del dropShadow toon = self.getAvatar(avId) if toon: toon.dropShadow.show() geomNode = toon.getGeomNode() rotNode = geomNode.getParent() baseNode = rotNode.getParent() geomNode.reparentTo(baseNode) rotNode.removeNode() del rotNode geomNode.setZ(oldGeomNodeZ) if toon: toon.reparentTo(render) toon.setPos(endPos) parentNode.removeNode() del parentNode if avId != self.localAvId: if toon: toon.startSmooth() preFunc() slipBack = Parallel( Sequence(ActorInterval(toon, 'slip-backward', endFrame=24), Wait(CTGG.LyingDownDuration - (flyDur - oldFlyDur)), ActorInterval(toon, 'slip-backward', startFrame=24))) if toon.doId == self.localAvId: slipBack.append(SoundInterval(self.sndOof)) hitTrack = Sequence(Parallel(flyTrack, spinHTrack, spinPTrack, soundTrack), slipBack, Func(postFunc), name=toon.uniqueName('hitBySuit')) self.notify.debug('hitTrack duration = %s' % hitTrack.getDuration()) self.toonHitTracks[avId] = hitTrack hitTrack.start(globalClockDelta.localElapsedTime(timestamp)) return def updateSuitGoal(self, timestamp, inResponseToClientStamp, suitNum, goalType, goalId, x, y, z): if not self.hasLocalToon: return self.notify.debug( 'updateSuitGoal gameTime=%s timeStamp=%s cog=%s goal=%s goalId=%s (%.1f, %.1f,%.1f)' % (self.getCurrentGameTime(), timestamp, suitNum, CTGG.GoalStr[goalType], goalId, x, y, z)) cog = self.cogInfo[suitNum] cog['goal'] = goalType cog['goalId'] = goalId newPos = Point3(x, y, z) cog['pos'] = newPos suit = cog['suit'] suit.updateGoal(timestamp, inResponseToClientStamp, goalType, goalId, newPos) def spawnUpdateSuitsTask(self): self.notify.debug('spawnUpdateSuitsTask') for cogIndex in self.cogInfo: suit = self.cogInfo[cogIndex]['suit'] suit.gameStart(self.gameStartTime) taskMgr.remove(self.UPDATE_SUITS_TASK) taskMgr.add(self.updateSuitsTask, self.UPDATE_SUITS_TASK) def removeUpdateSuitsTask(self): taskMgr.remove(self.UPDATE_SUITS_TASK) def updateSuitsTask(self, task): if self.gameIsEnding: return task.done for cogIndex in self.cogInfo: suit = self.cogInfo[cogIndex]['suit'] suit.think() return task.cont def makeSuitRespondToToonHit(self, timestamp, suitNum): cog = self.cogInfo[suitNum]['suit'] cog.respondToToonHit(timestamp) def handleEnterBarrel(self, colEntry): if self.gameIsEnding: return intoName = colEntry.getIntoNodePath().getName() fromName = colEntry.getFromNodePath().getName() debugInto = intoName.split('/') debugFrom = fromName.split('/') self.notify.debug( 'handleEnterBarrel gameTime=%s %s into %s' % (self.getCurrentGameTime(), debugFrom[-1], debugInto[-1])) if 'CogThiefSphere' in intoName: parts = intoName.split('-') cogIndex = int(parts[1]) barrelName = colEntry.getFromNodePath().getName() barrelParts = barrelName.split('-') barrelIndex = int(barrelParts[1]) cog = self.cogInfo[cogIndex]['suit'] if cog.barrel == CTGG.NoBarrelCarried and barrelIndex not in self.stolenBarrels: timestamp = globalClockDelta.localToNetworkTime( globalClock.getFrameTime(), bits=32) if cog.suit: cogPos = cog.suit.getPos() collisionPos = colEntry.getContactPos(render) self.sendUpdate('cogHitBarrel', [ timestamp, cogIndex, barrelIndex, cogPos[0], cogPos[1], cogPos[2] ]) def makeCogCarryBarrel(self, timestamp, inResponseToClientStamp, cogIndex, barrelIndex, x, y, z): if not self.hasLocalToon: return if self.gameIsEnding: return self.notify.debug( 'makeCogCarryBarrel gameTime=%s timeStamp=%s cog=%s barrel=%s (%.1f, %.1f,%.1f)' % (self.getCurrentGameTime(), timestamp, cogIndex, barrelIndex, x, y, z)) barrel = self.barrels[barrelIndex] self.notify.debug('barrelPos= %s' % barrel.getPos()) cog = self.cogInfo[cogIndex]['suit'] cogPos = Point3(x, y, z) cog.makeCogCarryBarrel(timestamp, inResponseToClientStamp, barrel, barrelIndex, cogPos) def makeCogDropBarrel(self, timestamp, inResponseToClientStamp, cogIndex, barrelIndex, x, y, z): if not self.hasLocalToon: return self.notify.debug( 'makeCogDropBarrel gameTime=%s timeStamp=%s cog=%s barrel=%s (%.1f, %.1f,%.1f)' % (self.getCurrentGameTime(), timestamp, cogIndex, barrelIndex, x, y, z)) barrel = self.barrels[barrelIndex] self.notify.debug('barrelPos= %s' % barrel.getPos()) cog = self.cogInfo[cogIndex]['suit'] cogPos = Point3(x, y, z) cog.makeCogDropBarrel(timestamp, inResponseToClientStamp, barrel, barrelIndex, cogPos) def controlKeyPressed(self): if self.isToonPlayingHitTrack(self.localAvId): return if self.gameIsEnding: return if self.getCurrentGameTime( ) - self.lastTimeControlPressed > self.ControlKeyLimitTime: self.lastTimeControlPressed = self.getCurrentGameTime() self.notify.debug('controlKeyPressed') toonSD = self.toonSDs[self.localAvId] curState = toonSD.fsm.getCurrentState().getName() toon = self.getAvatar(self.localAvId) timestamp = globalClockDelta.localToNetworkTime( globalClock.getFrameTime(), bits=32) pos = toon.getPos() heading = toon.getH() self.sendUpdate( 'throwingPie', [self.localAvId, timestamp, heading, pos[0], pos[1], pos[2]]) self.showToonThrowingPie(self.localAvId, timestamp, heading, pos) def throwingPie(self, avId, timestamp, heading, x, y, z): if not self.hasLocalToon: return if self.gameFSM.getCurrentState().getName() not in ['play']: self.notify.warning('ignoring msg: av %s hit by suit' % avId) return self.notify.debug('avatar ' + ` avId ` + ' throwing pie') if avId != self.localAvId: pos = Point3(x, y, z) self.showToonThrowingPie(avId, timestamp, heading, pos) def showToonThrowingPie(self, avId, timestamp, heading, pos): toon = self.getAvatar(avId) if toon: tossTrack, pieTrack, flyPie = self.getTossPieInterval( toon, pos[0], pos[1], pos[2], heading, 0, 0, 0) def removePieFromTraverser(flyPie=flyPie): if base.cTrav: if flyPie: base.cTrav.removeCollider(flyPie) if avId == self.localAvId: flyPie.setTag('throwerId', str(avId)) collSphere = CollisionSphere(0, 0, 0, 0.5) collSphere.setTangible(0) name = 'PieSphere-%d' % avId collSphereName = self.uniqueName(name) collNode = CollisionNode(collSphereName) collNode.setFromCollideMask(ToontownGlobals.PieBitmask) collNode.addSolid(collSphere) colNp = flyPie.attachNewNode(collNode) colNp.show() base.cTrav.addCollider(colNp, self.pieHandler) self.accept('pieHit-' + collSphereName, self.handlePieHitting) def matchRunningAnim(toon=toon): toon.playingAnim = None toon.setSpeed(toon.forwardSpeed, toon.rotateSpeed) return newTossTrack = Sequence(tossTrack, Func(matchRunningAnim)) pieTrack = Parallel(newTossTrack, pieTrack) elapsedTime = globalClockDelta.localElapsedTime(timestamp) if elapsedTime < 16.0 / 24.0: elapsedTime = 16.0 / 24.0 pieTrack.start(elapsedTime) self.toonPieTracks[avId] = pieTrack def getTossPieInterval(self, toon, x, y, z, h, p, r, power, beginFlyIval=Sequence()): from toontown.toonbase import ToontownBattleGlobals from toontown.battle import BattleProps pie = toon.getPieModel() pie.setScale(0.9) flyPie = pie.copyTo(NodePath('a')) pieName = ToontownBattleGlobals.pieNames[toon.pieType] pieType = BattleProps.globalPropPool.getPropType(pieName) animPie = Sequence() if pieType == 'actor': animPie = ActorInterval(pie, pieName, startFrame=48) sound = loader.loadSfx('phase_3.5/audio/sfx/AA_pie_throw_only.ogg') t = power / 100.0 dist = 100 - 70 * t time = 1 + 0.5 * t proj = ProjectileInterval(None, startPos=Point3(0, 0, 0), endPos=Point3(0, dist, 0), duration=time) relVel = proj.startVel def getVelocity(toon=toon, relVel=relVel): return render.getRelativeVector(toon, relVel) * 0.6 toss = Track( (0, Sequence( Func(toon.setPosHpr, x, y, z, h, p, r), Func(pie.reparentTo, toon.rightHand), Func(pie.setPosHpr, 0, 0, 0, 0, 0, 0), Parallel( ActorInterval( toon, 'throw', startFrame=48, partName='torso'), animPie), Func(toon.loop, 'neutral'))), (16.0 / 24.0, Func(pie.detachNode))) fly = Track( (14.0 / 24.0, SoundInterval(sound, node=toon)), (16.0 / 24.0, Sequence( Func(flyPie.reparentTo, render), Func(flyPie.setPosHpr, toon, 0.52, 0.97, 2.24, 0, -45, 0), beginFlyIval, ProjectileInterval(flyPie, startVel=getVelocity, duration=6), Func(flyPie.detachNode)))) return (toss, fly, flyPie) def handlePieHitting(self, colEntry): if self.gameIsEnding: return into = colEntry.getIntoNodePath() intoName = into.getName() if 'CogThiefPieSphere' in intoName: timestamp = globalClockDelta.localToNetworkTime( globalClock.getFrameTime(), bits=32) parts = intoName.split('-') suitNum = int(parts[1]) pos = self.cogInfo[suitNum]['suit'].suit.getPos() if pos in CTGG.CogStartingPositions: self.notify.debug('Cog %d hit at starting pos %s, ignoring' % (suitNum, pos)) else: self.sendUpdate('pieHitSuit', [ self.localAvId, timestamp, suitNum, pos[0], pos[1], pos[2] ]) self.makeSuitRespondToPieHit(timestamp, suitNum) def pieHitSuit(self, avId, timestamp, suitNum, x, y, z): if not self.hasLocalToon: return if self.gameFSM.getCurrentState().getName() not in ['play']: self.notify.warning('ignoring msg: av %s hit by suit' % avId) return if self.gameIsEnding: return self.notify.debug('avatar ' + ` avId ` + ' hit by a suit') if avId != self.localAvId: self.makeSuitRespondToPieHit(timestamp, suitNum) def makeSuitRespondToPieHit(self, timestamp, suitNum): cog = self.cogInfo[suitNum]['suit'] cog.respondToPieHit(timestamp) def sendCogAtReturnPos(self, cogIndex, barrelIndex): timestamp = globalClockDelta.localToNetworkTime( globalClock.getFrameTime(), bits=32) self.sendUpdate('cogAtReturnPos', [timestamp, cogIndex, barrelIndex]) def markBarrelStolen(self, timestamp, inResponseToClientStamp, barrelIndex): if not self.hasLocalToon: return if barrelIndex not in self.stolenBarrels: self.stolenBarrels.append(barrelIndex) barrel = self.barrels[barrelIndex] barrel.hide() if base.config.GetBool('cog-thief-check-barrels', 1): if not base.config.GetBool('cog-thief-endless', 0): if len(self.stolenBarrels) == len(self.barrels): localStamp = globalClockDelta.networkToLocalTime(timestamp, bits=32) gameTime = self.local2GameTime(localStamp) self.clockStopTime = gameTime self.notify.debug('clockStopTime = %s' % gameTime) score = int(self.scoreMult * CTGG.calcScore(gameTime) + 0.5) self.rewardPanel['text'] = str(score) self.showResults() def __gameTimerExpired(self): self.notify.debug('game timer expired') self.showResults() def __startRewardCountdown(self): taskMgr.remove(self.REWARD_COUNTDOWN_TASK) taskMgr.add(self.__updateRewardCountdown, self.REWARD_COUNTDOWN_TASK) def __killRewardCountdown(self): taskMgr.remove(self.REWARD_COUNTDOWN_TASK) def __updateRewardCountdown(self, task): curTime = self.getCurrentGameTime() if self.clockStopTime is not None: if self.clockStopTime < curTime: self.notify.debug('self.clockStopTime < curTime %s %s' % (self.clockStopTime, curTime)) self.__killRewardCountdown() curTime = self.clockStopTime if curTime > CTGG.GameTime: curTime = CTGG.GameTime score = int(self.scoreMult * CTGG.calcScore(curTime) + 0.5) if not hasattr(task, 'curScore'): task.curScore = score result = Task.cont if hasattr(self, 'rewardPanel'): self.rewardPanel['text'] = str(score) if task.curScore != score: if hasattr(self, 'jarIval'): self.jarIval.finish() s = self.rewardPanel.getScale() self.jarIval = Parallel(Sequence( self.rewardPanel.scaleInterval(0.15, s * 3.0 / 4.0, blendType='easeOut'), self.rewardPanel.scaleInterval(0.15, s, blendType='easeIn')), SoundInterval(self.sndRewardTick), name='cogThiefGameRewardJarThrob') self.jarIval.start() task.curScore = score else: result = Task.done return result def startGameWalk(self): if self.useOrthoWalk: self.gameWalk.start() else: self.gameWalk.enter() self.gameWalk.fsm.request('walking') def stopGameWalk(self): if self.useOrthoWalk: self.gameWalk.stop() else: self.gameWalk.exit() def getCogThief(self, cogIndex): return self.cogInfo[cogIndex]['suit'] def isToonPlayingHitTrack(self, avId): if avId in self.toonHitTracks: track = self.toonHitTracks[avId] if track.isPlaying(): return True return False def getNumCogs(self): result = base.config.GetInt('cog-thief-num-cogs', 0) if not result: safezone = self.getSafezoneId() result = CTGG.calculateCogs(self.numPlayers, safezone) return result def getCogSpeed(self): result = 6.0 safezone = self.getSafezoneId() result = CTGG.calculateCogSpeed(self.numPlayers, safezone) return result def showResults(self): if not self.gameIsEnding: self.gameIsEnding = True for barrel in self.barrels: barrel.wrtReparentTo(render) for key in self.cogInfo: thief = self.cogInfo[key]['suit'] thief.suit.setPos(100, 0, 0) thief.suit.hide() self.__killRewardCountdown() self.stopGameWalk() numBarrelsSaved = len(self.barrels) - len(self.stolenBarrels) resultStr = '' if numBarrelsSaved == len(self.barrels): resultStr = TTLocalizer.CogThiefPerfect elif numBarrelsSaved > 1: resultStr = TTLocalizer.CogThiefBarrelsSaved % { 'num': numBarrelsSaved } elif numBarrelsSaved == 1: resultStr = TTLocalizer.CogThiefBarrelSaved % { 'num': numBarrelsSaved } else: resultStr = TTLocalizer.CogThiefNoBarrelsSaved perfectTextSubnode = hidden.attachNewNode( self.__genText(resultStr)) perfectText = hidden.attachNewNode('perfectText') perfectTextSubnode.reparentTo(perfectText) frame = self.__textGen.getCardActual() offsetY = -abs(frame[2] + frame[3]) / 2.0 perfectTextSubnode.setPos(0, 0, offsetY) perfectText.setColor(1, 0.1, 0.1, 1) def fadeFunc(t, text=perfectText): text.setColorScale(1, 1, 1, t) def destroyText(text=perfectText): text.removeNode() def safeGameOver(self=self): if not self.frameworkFSM.isInternalStateInFlux(): self.gameOver() textTrack = Sequence( Func(perfectText.reparentTo, aspect2d), Parallel( LerpScaleInterval(perfectText, duration=0.5, scale=0.3, startScale=0.0), LerpFunctionInterval(fadeFunc, fromData=0.0, toData=1.0, duration=0.5)), Wait(2.0), Parallel( LerpScaleInterval(perfectText, duration=0.5, scale=1.0), LerpFunctionInterval(fadeFunc, fromData=1.0, toData=0.0, duration=0.5, blendType='easeIn')), Func(destroyText), WaitInterval(0.5), Func(safeGameOver)) if numBarrelsSaved == len(self.barrels): soundTrack = SoundInterval(self.sndPerfect) else: soundTrack = Sequence() self.resultIval = Parallel(textTrack, soundTrack) self.resultIval.start() def __genText(self, text): self.__textGen.setText(text) return self.__textGen.generate() def getIntroTrack(self): base.camera.setPosHpr(0, -13.66, 13.59, 0, -51.6, 0) result = Sequence( Wait(2), LerpPosHprInterval(base.camera, 13, Point3(self.cameraTopView[0], self.cameraTopView[1], self.cameraTopView[2]), Point3(self.cameraTopView[3], self.cameraTopView[4], self.cameraTopView[5]), blendType='easeIn')) return result
snipstuff.info.append("a collision setup for picking objects with the mouse pointer driscriminating an object from another") snipstuff.info.append("Move the mouse pointer over the smiley to see it change color and click LMB to see a reaction.\n") snipstuff.info_show() base.disableMouse() #========================================================================= # Main """ To biefly sum up what happen next, we'll make interact an invisible collision ray with two kinds of INTO objects: smileys and frowneys. The FROM ray will generate collision events as soon as touch each INTO object moving the mouse pointer over, routing toward different function handlers depending on the object group the object belongs (smiley or frowney). All of this is efficiently achieved using tags and special collision patterns, using therefore a slightly different setup from what we used to see so far in previous steps. """ #========================================================================= #** Collision events ignition base.cTrav=CollisionTraverser() collisionHandler = CollisionHandlerEvent() #** Setting the ray collider - see step5.py for details pickerNode=CollisionNode('mouseraycnode') pickerNP=base.camera.attachNewNode(pickerNode) pickerRay=CollisionRay() pickerNode.addSolid(pickerRay) #** This is new stuff: we set here a so called 'tag' for the ray - its purpose is to make the ray recognizable in a different event pattern matching situation from what we are used to use so far. Just note the first parameter is the main object grouping. See details below setting the patterns. pickerNode.setTag('rays','ray1') base.cTrav.addCollider(pickerNP, collisionHandler) #** This function is used to create all our smileys in the scene - I won't get into the basic commands that should be clear if you passed by the previous steps. def smileyMachine(n, pos): smileyModel = loader.loadModel('smiley') smileyModel.setName('Smiley#%d'%n)
def load(self): self.notify.debug('load') DistributedMinigame.load(self) self.music = base.loadMusic('phase_4/audio/bgm/MG_CogThief.ogg') self.initCogInfo() for barrelIndex in xrange(CTGG.NumBarrels): barrel = loader.loadModel( 'phase_4/models/minigames/cogthief_game_gagTank') barrel.setPos(CTGG.BarrelStartingPositions[barrelIndex]) barrel.setScale(self.BarrelScale) barrel.reparentTo(render) barrel.setTag('barrelIndex', str(barrelIndex)) collSphere = CollisionSphere(0, 0, 0, 4) collSphere.setTangible(0) name = 'BarrelSphere-%d' % barrelIndex collSphereName = self.uniqueName(name) collNode = CollisionNode(collSphereName) collNode.setFromCollideMask(CTGG.BarrelBitmask) collNode.addSolid(collSphere) colNp = barrel.attachNewNode(collNode) handler = CollisionHandlerEvent() handler.setInPattern('barrelHit-%fn') base.cTrav.addCollider(colNp, handler) self.accept('barrelHit-' + collSphereName, self.handleEnterBarrel) nodeToHide = '**/gagMoneyTen' if barrelIndex % 2: nodeToHide = '**/gagMoneyFive' iconToHide = barrel.find(nodeToHide) if not iconToHide.isEmpty(): iconToHide.hide() self.barrels.append(barrel) self.gameBoard = loader.loadModel( 'phase_4/models/minigames/cogthief_game') self.gameBoard.find('**/floor_TT').hide() self.gameBoard.find('**/floor_DD').hide() self.gameBoard.find('**/floor_DG').hide() self.gameBoard.find('**/floor_MM').hide() self.gameBoard.find('**/floor_BR').hide() self.gameBoard.find('**/floor_DL').hide() zone = self.getSafezoneId() if zone == ToontownGlobals.ToontownCentral: self.gameBoard.find('**/floor_TT').show() elif zone == ToontownGlobals.DonaldsDock: self.gameBoard.find('**/floor_DD').show() elif zone == ToontownGlobals.DaisyGardens: self.gameBoard.find('**/floor_DG').show() elif zone == ToontownGlobals.MinniesMelodyland: self.gameBoard.find('**/floor_MM').show() elif zone == ToontownGlobals.TheBrrrgh: self.gameBoard.find('**/floor_BR').show() elif zone == ToontownGlobals.DonaldsDreamland: self.gameBoard.find('**/floor_DL').show() else: self.gameBoard.find('**/floor_TT').show() self.gameBoard.setPosHpr(0, 0, 0, 0, 0, 0) self.gameBoard.setScale(1.0) self.toonSDs = {} avId = self.localAvId toonSD = CogThiefGameToonSD.CogThiefGameToonSD(avId, self) self.toonSDs[avId] = toonSD toonSD.load() self.loadCogs() self.toonHitTracks = {} self.toonPieTracks = {} self.sndOof = base.loadSfx('phase_4/audio/sfx/MG_cannon_hit_dirt.ogg') self.sndRewardTick = base.loadSfx( 'phase_3.5/audio/sfx/tick_counter.ogg') self.sndPerfect = base.loadSfx('phase_4/audio/sfx/ring_perfect.ogg') self.timer = ToontownTimer.ToontownTimer() self.timer.posInTopRightCorner() self.timer.hide() purchaseModels = loader.loadModel('phase_4/models/gui/purchase_gui') self.jarImage = purchaseModels.find('**/Jar') self.jarImage.reparentTo(hidden) self.rewardPanel = DirectLabel(parent=hidden, relief=None, pos=(-0.173, 0.0, -0.55), scale=0.65, text='', text_scale=0.2, text_fg=(0.95, 0.95, 0, 1), text_pos=(0, -.13), text_font=ToontownGlobals.getSignFont(), image=self.jarImage) self.rewardPanelTitle = DirectLabel(parent=self.rewardPanel, relief=None, pos=(0, 0, 0.06), scale=0.08, text=TTLocalizer.CannonGameReward, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1)) return
from direct.gui.OnscreenText import OnscreenText import direct.directbase.DirectStart from panda3d.core import Geom, GeomNode, GeomTriangles, GeomVertexData, GeomVertexFormat, GeomVertexWriter, NodePath, Texture, TextureStage camYMove = 0 camXMove = 0 camMovingX = False camMovingY = False camSpeed = 1 base.disableMouse() base.cTrav = CollisionTraverser() cHandler = CollisionHandlerEvent() pickerNode = CollisionNode("mouseRayNode") pickerNPos = base.camera.attachNewNode(pickerNode) pickerRay = CollisionRay() pickerNode.addSolid(pickerRay) pickerNode.setTag("rays","ray1") base.cTrav.addCollider(pickerNPos, cHandler) countBuilding = 0 buildingName = [] buildingX = [] buildingY = []
class PartyCogActivity(DirectObject): __module__ = __name__ notify = directNotify.newCategory('PartyCogActivity') cog = None arena = None player = None players = {} def __init__(self, activity, arenaModel = None, texture = None): self.activity = activity self.root = self.activity.root self.toonPieTracks = {} self.toonPieEventNames = {} self.toonIdsToAnimIntervals = {} self.pieIvals = [] self.resultsIval = None self.arenaModel = arenaModel self.texture = texture return def load(self): self.arena = loader.loadModel(self.arenaModel) self.arena.reparentTo(self.root) ground = self.arena.find('**/ground') ground.setBin('ground', 1) entranceArrows = self.arena.findAllMatches('**/arrowFlat*') for arrow in entranceArrows: arrow.setBin('ground', 5) self.leftEntranceLocator = self.arena.find('**/leftEntrance_locator') self.rightEntranceLocator = self.arena.find('**/rightEntrance_locator') self.leftExitLocator = self.arena.find('**/leftExit_locator') self.rightExitLocator = self.arena.find('**/rightExit_locator') self.teamCamPosLocators = (self.arena.find('**/team0CamPos_locator'), self.arena.find('**/team1CamPos_locator')) self.teamCamAimLocators = (self.arena.find('**/team0CamAim_locator'), self.arena.find('**/team1CamAim_locator')) leftTeamLocator = NodePath('TeamLocator-%d' % PartyGlobals.TeamActivityTeams.LeftTeam) leftTeamLocator.reparentTo(self.root) leftTeamLocator.setH(90) rightTeamLocator = NodePath('TeamLocator-%d' % PartyGlobals.TeamActivityTeams.RightTeam) rightTeamLocator.reparentTo(self.root) rightTeamLocator.setH(-90) self.teamLocators = (leftTeamLocator, rightTeamLocator) self._lengthBetweenEntrances = self.leftEntranceLocator.getY() - self.rightExitLocator.getY() self._skyCollisionsCollection = self.arena.findAllMatches('**/cogPieArena_sky*_collision') if len(self._skyCollisionsCollection) > 0: self._skyCollisionParent = self._skyCollisionsCollection[0].getParent() else: self._skyCollisionParent = self.arena self._wallCollisionsCollection = self.arena.findAllMatches('**/cogPieArena_wall*_collision') self._arenaFlagGroups = (self.arena.find('**/flagsL_grp'), self.arena.find('**/flagsR_grp')) self._initArenaDoors() self.cogManager = PartyCogManager() self.arrows = [] self.distanceLabels = [] self.teamColors = list(PartyGlobals.CogActivityColors) + [PartyGlobals.TeamActivityStatusColor] for i in range(3): start = self.arena.find('**/cog%d_start_locator' % (i + 1)) end = self.arena.find('**/cog%d_end_locator' % (i + 1)) cog = self.cogManager.generateCog(self.arena) cog.setEndPoints(start.getPos(), end.getPos()) arrow1 = StretchingArrow(self.arena, useColor='orange') arrow2 = StretchingArrow(self.arena, useColor='blue') arrow1.setZ(0.1) arrow2.setZ(0.1) self.arrows.append([arrow1, arrow2]) distanceLabel = self.createDistanceLabel(0, self.teamColors[1]) distanceLabel[0].stash() distanceLabel2 = self.createDistanceLabel(0, self.teamColors[0]) distanceLabel2[0].stash() self.distanceLabels.append([distanceLabel, distanceLabel2]) self.winText = [] text1 = self.createText(0, Point3(-0.5, 0.0, -0.5), self.teamColors[1]) text2 = self.createText(1, Point3(0.5, 0.0, -0.5), self.teamColors[0]) self.winText.append(text1) self.winText.append(text2) self.winStatus = self.createText(2, Point3(0.0, 0.0, -0.8), self.teamColors[0]) signLocator = self.arena.find('**/eventSign_locator') self.activity.sign.setPos(signLocator.getPos(self.root)) if self.texture: textureAlpha = self.texture[:-4] + '_a.rgb' reskinTexture = loader.loadTexture(self.texture, textureAlpha) self.arena.find('**/center_grp').setTexture(reskinTexture, 100) self.arena.find('**/leftSide_grp').setTexture(reskinTexture, 100) self.arena.find('**/rightSide_grp').setTexture(reskinTexture, 100) self.enable() def _initArenaDoors(self): self._arenaDoors = (self.arena.find('**/doorL'), self.arena.find('**/doorR')) arenaDoorLocators = (self.arena.find('**/doorL_locator'), self.arena.find('**/doorR_locator')) for i in range(len(arenaDoorLocators)): arenaDoorLocators[i].wrtReparentTo(self._arenaDoors[i]) self._arenaDoorTimers = (self.createDoorTimer(PartyGlobals.TeamActivityTeams.LeftTeam), self.createDoorTimer(PartyGlobals.TeamActivityTeams.RightTeam)) self._arenaDoorIvals = [None, None] self._doorStartPos = [] for i in range(len(self._arenaDoors)): door = self._arenaDoors[i] timer = self._arenaDoorTimers[i] timer.reparentTo(arenaDoorLocators[i]) timer.hide() self._doorStartPos.append(door.getPos()) door.setPos(door, 0, 0, -7.0) return def _destroyArenaDoors(self): for ival in self._arenaDoorIvals: ival.finish() self._arenaDoorIvals = None self._arenaDoors = None for timer in self._arenaDoorTimers: timer.stop() timer.removeNode() self._arenaDoorTimers = None return def createDoorTimer(self, team): timer = ToontownTimer(useImage=False, highlightNearEnd=False) timer['text_font'] = ToontownGlobals.getMinnieFont() timer.setFontColor(PartyGlobals.CogActivityColors[team]) timer.setScale(7.0) timer.setPos(0.2, -0.03, 0.0) return timer def createText(self, number, position, color): text = TextNode('winText%d' % number) text.setAlign(TextNode.ACenter) text.setTextColor(color) text.setFont(ToontownGlobals.getSignFont()) text.setText('') noteText = aspect2d.attachNewNode(text) noteText.setScale(0.2) noteText.setPos(position) noteText.stash() return (text, noteText) def createDistanceLabel(self, number, color): text = TextNode('distanceText-%d' % number) text.setAlign(TextNode.ACenter) text.setTextColor(color) text.setFont(ToontownGlobals.getSignFont()) text.setText('10 ft') node = self.root.attachNewNode(text) node.setBillboardPointEye() node.setScale(2.5) node.setZ(5.0) return (node, text) def unload(self): self.disable() self._cleanupResultsIval() if self.winText is not None: for pair in self.winText: pair[1].reparentTo(hidden) pair[1].removeNode() self.winText = None if self.winStatus is not None: self.winStatus[1].reparentTo(hidden) self.winStatus[1].removeNode() self.winStatus = None if self.cogManager is not None: self.cogManager.unload() self.cogManager = None if self.arrows is not None: for pair in self.arrows: for arrow in pair: arrow.destroy() arrow = None pair = None self.arrows = None if self.distanceLabels is not None: for pair in self.distanceLabels: for node, text in pair: node.removeNode() pair = None self.distanceLabels = None if len(self.players): for player in self.players.values(): player.disable() player.destroy() self.players.clear() self.player = None if self.arena is not None: self.leftEntranceLocator = None self.rightEntranceLocator = None self.leftExitLocator = None self.rightExitLocator = None self._skyCollisions = None self._skyCollisionParent = None self._arenaFlagGroups = None self._destroyArenaDoors() self.arena.removeNode() self.arena = None for ival in self.toonPieTracks.values(): if ival is not None and ival.isPlaying(): try: ival.finish() except Exception as theException: self.notify.warning('Ival could not finish:\n %s \nException %s ' % (str(ival), str(theException))) self.toonPieTracks = {} for ival in self.pieIvals: if ival is not None and ival.isPlaying(): try: ival.finish() except Exception as theException: self.notify.warning('Ival could not finish:\n %s \nException %s ' % (str(ival), str(theException))) self.pieIvals = [] self.toonIdsToAnimIntervals = {} for eventName in self.toonPieEventNames.values(): self.ignore(eventName) self.toonPieEventNames = {} return def enable(self): self.enableEnterGateCollision() def disable(self): self.disableEnterGateCollision() self.ignoreAll() def hideTeamFlags(self, team): self._arenaFlagGroups[team].stash() def showTeamFlags(self, team): self._arenaFlagGroups[team].unstash() def _playArenaDoorIval(self, team, opening = True): ival = self._arenaDoorIvals[team] if ival is not None and ival.isPlaying(): ival.pause() if not opening: pos = self._doorStartPos[team] else: pos = (self._doorStartPos[team] + Point3(0, 0, -7.0),) ival = self._arenaDoors[team].posInterval(0.75, pos, blendType='easeIn') self._arenaDoorIvals[team] = ival ival.start() return def openArenaDoorForTeam(self, team): self._playArenaDoorIval(team, opening=True) def closeArenaDoorForTeam(self, team): self._playArenaDoorIval(team, opening=False) def openArenaDoors(self): self.enableEnterGateCollision() for i in range(len(self._arenaDoors)): self.openArenaDoorForTeam(i) def closeArenaDoors(self): self.disableEnterGateCollision() for i in range(len(self._arenaDoors)): self.closeArenaDoorForTeam(i) def showArenaDoorTimers(self, duration): for timer in self._arenaDoorTimers: timer.setTime(duration) timer.countdown(duration) timer.show() def hideArenaDoorTimers(self): for timer in self._arenaDoorTimers: timer.hide() def enableEnterGateCollision(self): self.acceptOnce('entercogPieArena_entranceLeft_collision', self.handleEnterLeftEntranceTrigger) self.acceptOnce('entercogPieArena_entranceRight_collision', self.handleEnterRightEntranceTrigger) def disableEnterGateCollision(self): self.ignore('entercogPieArena_entranceLeft_collision') self.ignore('entercogPieArena_entranceRight_collision') def enableWallCollisions(self): self._wallCollisionsCollection.unstash() def disableWallCollisions(self): self._wallCollisionsCollection.stash() def enableSkyCollisions(self): self._skyCollisionsCollection.unstash() def disableSkyCollisions(self): self._skyCollisionsCollection.stash() def handleEnterLeftEntranceTrigger(self, collEntry): self.activity.d_toonJoinRequest(PartyGlobals.TeamActivityTeams.LeftTeam) def handleEnterRightEntranceTrigger(self, collEntry): self.activity.d_toonJoinRequest(PartyGlobals.TeamActivityTeams.RightTeam) def checkOrthoDriveCollision(self, oldPos, newPos): x = bound(newPos[0], -16.8, 16.8) y = bound(newPos[1], -17.25, -24.1) newPos.setX(x) newPos.setY(y) return newPos def getPlayerStartPos(self, team, spot): if team == PartyGlobals.TeamActivityTeams.LeftTeam: node = self.leftExitLocator else: node = self.rightExitLocator d = self._lengthBetweenEntrances / (self.activity.getMaxPlayersPerTeam() + 1) yOffset = node.getY(self.root) + d * (spot + 1) pos = node.getPos(self.root) pos.setY(yOffset) return pos def handleToonJoined(self, toon, team, lateEntry = False): pos = self.getPlayerStartPos(team, self.activity.getIndex(toon.doId, team)) if toon == base.localAvatar: player = PartyCogActivityLocalPlayer(self.activity, pos, team, self.handleToonExited) player.entersActivity() self.player = player self.disableSkyCollisions() self.playPlayerEnterIval() else: player = PartyCogActivityPlayer(self.activity, toon, pos, team) player.entersActivity() if lateEntry: player.updateToonPosition() self.players[toon.doId] = player def handleToonSwitchedTeams(self, toon): toonId = toon.doId player = self.players.get(toonId) if player is None: self.notify.warning('handleToonSwitchedTeams: toonId %s not found' % toonId) return team = self.activity.getTeam(toonId) spot = self.activity.getIndex(toonId, team) pos = self.getPlayerStartPos(team, spot) self.finishToonIval(toonId) player.setTeam(team) player.setToonStartPosition(pos) player.updateToonPosition() return def handleToonShifted(self, toon): toonId = toon.doId if self.players.has_key(toonId): player = self.players[toonId] spot = self.activity.getIndex(toonId, player.team) pos = self.getPlayerStartPos(player.team, spot) player.setToonStartPosition(pos) if self.player is not None and toon == self.player.toon: self.playToonIval(base.localAvatar.doId, self.player.getRunToStartPositionIval()) return def handleToonDisabled(self, toonId): self.finishToonIval(toonId) self.finishPieIvals(toonId) player = self.players.get(toonId) if player is not None: player.disable() if player == self.player: self.player = None del self.players[toonId] return def finishPieIvals(self, toonId): for ival in self.pieIvals: if ival.isPlaying(): if ival.getName().find(str(toonId)) != -1: ival.finish() def playPlayerEnterIval(self): def conditionallyShowSwitchButton(self = self, enable = True): if enable and self.activity.activityFSM.state in ['WaitForEnough', 'WaitToStart']: self.activity.teamActivityGui.enableSwitchButton() else: self.activity.teamActivityGui.disableSwitchButton() ival = Sequence(Func(self.disableWallCollisions), Func(conditionallyShowSwitchButton, self, False), self.player.getRunToStartPositionIval(), Func(conditionallyShowSwitchButton, self, True), Func(self.enableWallCollisions)) self.playToonIval(base.localAvatar.doId, ival) def finishToonIval(self, toonId): if self.toonIdsToAnimIntervals.get(toonId) is not None and self.toonIdsToAnimIntervals[toonId].isPlaying(): self.toonIdsToAnimIntervals[toonId].finish() return def playToonIval(self, toonId, ival): self.finishToonIval(toonId) self.toonIdsToAnimIntervals[toonId] = ival ival.start() def startActivity(self, timestamp): self.pieHandler = CollisionHandlerEvent() self.pieHandler.setInPattern('pieHit-%fn') if self.player is not None: self.player.resetScore() self.hideTeamFlags(self.player.team) for player in self.players.values(): self.finishToonIval(player.toon.doId) player.enable() for cog in self.cogManager.cogs: cog.request('Active', timestamp) for ival in self.pieIvals: if ival.isPlaying(): ival.finish() self.pieIvals = [] return def stopActivity(self): for player in self.players.values(): player.disable() for eventName in self.toonPieEventNames.values(): self.ignore(eventName) self.toonPieEventNames.clear() for cog in self.cogManager.cogs: cog.request('Static') def handleToonExited(self, toon): self.finishToonIval(toon.doId) player = self.players[toon.doId] player.disable() player.exitsActivity() player.destroy() if player == self.player: self.showTeamFlags(self.activity.getTeam(toon.doId)) self.player = None self.enableEnterGateCollision() self.enableSkyCollisions() del self.players[toon.doId] return def pieThrow(self, avId, timestamp, heading, pos, power): toon = self.activity.getAvatar(avId) if toon is None: return tossTrack, pieTrack, flyPie = self.getTossPieInterval(toon, pos[0], pos[1], pos[2], heading, 0, 0, power) if avId == base.localAvatar.doId: flyPie.setTag('throwerId', str(avId)) collSphere = CollisionSphere(0, 0, 0, 0.5) collSphere.setTangible(0) name = 'PieSphere-%d' % avId collSphereName = self.activity.uniqueName(name) collNode = CollisionNode(collSphereName) collNode.setFromCollideMask(ToontownGlobals.PieBitmask) collNode.addSolid(collSphere) collNP = flyPie.attachNewNode(collNode) base.cTrav.addCollider(collNP, self.pieHandler) self.toonPieEventNames[collNP] = 'pieHit-' + collSphereName self.accept(self.toonPieEventNames[collNP], self.handlePieCollision) else: player = self.players.get(avId) if player is not None: player.faceForward() def matchRunningAnim(toon = toon): toon.playingAnim = None toon.setSpeed(toon.forwardSpeed, toon.rotateSpeed) return newTossTrack = Sequence(tossTrack, Func(matchRunningAnim)) pieTrack = Parallel(newTossTrack, pieTrack, name='PartyCogActivity.pieTrack-%d-%s' % (avId, timestamp)) elapsedTime = globalClockDelta.localElapsedTime(timestamp) if elapsedTime < 16.0 / 24.0: elapsedTime = 16.0 / 24.0 pieTrack.start(elapsedTime) self.pieIvals.append(pieTrack) self.toonPieTracks[avId] = pieTrack return def getTossPieInterval(self, toon, x, y, z, h, p, r, power, beginFlyIval = Sequence()): from toontown.toonbase import ToontownBattleGlobals from toontown.battle import BattleProps pie = toon.getPieModel() pie.setScale(0.5) flyPie = pie.copyTo(NodePath('a')) pieName = ToontownBattleGlobals.pieNames[toon.pieType] pieType = BattleProps.globalPropPool.getPropType(pieName) animPie = Sequence() if pieType == 'actor': animPie = ActorInterval(pie, pieName, startFrame=48) sound = loader.loadSfx('phase_3.5/audio/sfx/AA_pie_throw_only.mp3') t = power / 100.0 dist = lerp(PartyGlobals.CogActivityPieMinDist, PartyGlobals.CogActivityPieMaxDist, t) time = lerp(1.0, 1.5, t) proj = ProjectileInterval(None, startPos=Point3(0, 0, 0), endPos=Point3(0, dist, 0), duration=time) relVel = proj.startVel def getVelocity(toon = toon, relVel = relVel): return render.getRelativeVector(toon, relVel) * 0.6 def __safeSetAnimState(toon = toon, state = 'Happy'): if toon and hasattr(toon, 'animFSM'): toon.setAnimState('Happy') else: self.notify.warning('The toon is being destroyed. No attribute animState.') toss = Track((0, Sequence(Func(toon.setPosHpr, x, y, z, h, p, r), Func(pie.reparentTo, toon.rightHand), Func(pie.setPosHpr, 0, 0, 0, 0, 0, 0), animPie, Parallel(ActorInterval(toon, 'throw', startFrame=48, playRate=1.5, partName='torso'), animPie), Func(__safeSetAnimState, toon, 'Happy'))), (16.0 / 24.0, Func(pie.detachNode))) fly = Track((14.0 / 24.0, SoundInterval(sound, node=toon, cutOff=PartyGlobals.PARTY_COG_CUTOFF)), (16.0 / 24.0, Sequence(Func(flyPie.reparentTo, render), Func(flyPie.setPosHpr, toon, 0.52, 0.97, 2.24, 0, -45, 0), beginFlyIval, ProjectileInterval(flyPie, startVel=getVelocity, duration=6), Func(flyPie.detachNode)))) return (toss, fly, flyPie) def handlePieCollision(self, colEntry): if not self.activity.isState('Active') or self.player is None: return handled = False into = colEntry.getIntoNodePath() intoName = into.getName() timestamp = globalClockDelta.localToNetworkTime(globalClock.getFrameTime(), bits=32) if 'PartyCog' in intoName: if self.toonPieTracks.get(base.localAvatar.doId) is not None: self.toonPieTracks[base.localAvatar.doId].finish() self.toonPieTracks[base.localAvatar.doId] = None parts = intoName.split('-') cogID = int(parts[1]) point = colEntry.getSurfacePoint(self.cogManager.cogs[cogID].root) cog = self.cogManager.cogs[cogID] if point.getZ() > cog.getHeadLocation(): hitHead = not parts[2].startswith('Arm') if self.activity.getTeam(base.localAvatar.doId) == PartyGlobals.TeamActivityTeams.LeftTeam: direction = -1.0 else: direction = 1.0 self.activity.b_pieHitsCog(timestamp, cogID, point, direction, hitHead) if hitHead: hitPoints = self.player.hitHead() else: hitPoints = self.player.hitBody() self.player.updateScore() if hitPoints > 0: cog.showHitScore(hitPoints) handled = True elif 'distAvatarCollNode' in intoName: parts = intoName.split('-') hitToonId = int(parts[1]) toon = base.cr.doId2do.get(hitToonId) if toon is not None and self.activity.getTeam(hitToonId) != self.player.team: point = colEntry.getSurfacePoint(toon) self.activity.b_pieHitsToon(hitToonId, timestamp, point) handled = True if handled: eventName = self.toonPieEventNames.get(colEntry.getFromNodePath()) eventName is not None and self.ignore(eventName) del self.toonPieEventNames[colEntry.getFromNodePath()] return def pieHitsCog(self, timestamp, cogNum, pos, direction, part): cog = self.cogManager.cogs[cogNum] cog.respondToPieHit(timestamp, pos, part, direction) def pieHitsToon(self, toonId, timestamp, pos): player = self.players.get(toonId) if player is not None: player.respondToPieHit(timestamp, pos) return def setCogDistances(self, distances): self.cogManager.updateDistances(distances) def showCogs(self): for cog in self.cogManager.cogs: cog.request('Static') def hideCogs(self): for cog in self.cogManager.cogs: cog.request('Down') def showResults(self, resultsText, winner, totals): if self.player is None: return base.localAvatar.showName() self.resultsIval = Sequence(Wait(0.1), Func(self.activity.setStatus, TTLocalizer.PartyCogTimeUp), Func(self.activity.showStatus), Wait(2.0), Func(self.activity.hideStatus), Wait(0.5), Func(self.player.lookAtArena), Func(self.showTeamFlags, self.activity.getTeam(base.localAvatar.doId)), Wait(1.0), Func(self.showArrow, 0), Wait(1.3), Func(self.showArrow, 1), Wait(1.3), Func(self.showArrow, 2), Wait(1.3), Func(self.showTotals, totals), Wait(1.0), Func(self.showWinner, resultsText, winner), Func(self._cleanupResultsIval), name='PartyCog-conclusionSequence') self.accept('DistributedPartyActivity-showJellybeanReward', self._cleanupResultsIval) self.resultsIval.start() return def _cleanupResultsIval(self): if self.resultsIval: if self.resultsIval.isPlaying(): self.resultsIval.pause() self.resultsIval = None self.ignore('DistributedPartyActivity-showJellybeanReward') return def showTotals(self, totals): newtotals = (totals[1] - totals[0] + PartyGlobals.CogActivityArenaLength / 2.0 * 3, totals[0] - totals[1] + PartyGlobals.CogActivityArenaLength / 2.0 * 3) self.winText[0][0].setText(TTLocalizer.PartyCogDistance % newtotals[0]) self.winText[1][0].setText(TTLocalizer.PartyCogDistance % newtotals[1]) for textPair in self.winText: textPair[1].unstash() def hideTotals(self): for textPair in self.winText: textPair[0].setText('') textPair[1].stash() def showWinner(self, text, winner): self.winStatus[0].setText(text) self.winStatus[0].setTextColor(self.teamColors[winner]) self.winStatus[1].unstash() def hideWinner(self): self.winStatus[0].setText('') self.winStatus[1].stash() def showArrow(self, arrowNum): arrows = self.arrows[arrowNum] cog = self.cogManager.cogs[arrowNum] points = [self.arena.find('**/cog%d_start_locator' % (arrowNum + 1)), self.arena.find('**/cog%d_end_locator' % (arrowNum + 1))] Y = cog.root.getY() for point in points: point.setY(Y) for i in range(len(arrows)): arrow = arrows[i] arrow.draw(points[i].getPos(), cog.root.getPos(), animate=False) arrow.unstash() i = -1 length = PartyGlobals.CogActivityArenaLength for node, text in self.distanceLabels[arrowNum]: current = bound(i, 0, 1) node.setPos(cog.root.getPos(self.root) + Point3(i * 4, 2, 4)) dist = PartyCogUtils.getCogDistanceUnitsFromCenter(cog.currentT) dist = abs(dist - i * length / 2) if dist > length - dist: node.setScale(2.8) else: node.setScale(2.2) text.setText(TTLocalizer.PartyCogDistance % dist) if dist > 0: node.unstash() else: arrows[current].stash() i += 2 def hideArrows(self): for pair in self.arrows: for arrow in pair: arrow.stash() for pair in self.distanceLabels: for node, text in pair: node.stash() def hideResults(self): self.hideArrows() self.hideTotals() self.hideWinner()