class MyApp(ShowBase): def center_mouse(self): self.win.movePointer(0,self.win.getXSize()/2,self.win.getYSize()/2) def __init__(self): #Game variables self.health = 100 self.panda_kill_count = 0 self.level = 0 #Implementation variables #self.color = [Vec4((204.0/255), (255.0/255), (204/255), 0.1),Vec4((0/255), (255.0/255), (255.0/255), 0.1),Vec4((255.0/255), (51.0/255), (255.0/255), 0.1),Vec4((153.0/255), (255.0/255), (153.0/255), 0.1),Vec4((255.0/255), (178.0/255), (102.0/255), 0.1),Vec4((229.0/255), (204.0/255), (255.0/255), 0.1)] self.color = [Vec4(0.4,0.4,0.4,0.1)] self.mirror=False self.paused=False self.displayed=False self.game_started=False self.randomthings_ = randomthings.RandomThings(self) self.shifted_cam=False self.is_firstP=False self.old_anim2 = None self.old_anim=None self.timeout=False (self.r,self.f,self.b,self.l)=(0,0,0,0) self.inside_level=False self.move_anim_queue=[] self.anim_queue=[] self.prev_time=0.0 self.bullets = [] self.rightspeed=0 self.forwardspeed=0 ShowBase.__init__(self) self.makeDefaultPipe() bb=self.pipe.getDisplayHeight() aa=self.pipe.getDisplayWidth() self.openDefaultWindow(size=(aa, bb)) import layer2d self.layer2d = layer2d self.layer2d.update_info('Loading...') self.keyreader= ReadKeys(self,layer2d) #Sounds self.gunshot = self.loader.loadSfx("sounds/gunshot_se.ogg") self.gunshot.setLoop(False) self.music = self.loader.loadSfx("sounds/music.ogg") self.music.setLoop(True) self.zombie_die = self.loader.loadSfx('sounds/zombie_die.ogg') self.zombie_die.setLoop(False) self.kicked = self.loader.loadSfx('sounds/kicked.ogg') self.kicked.setLoop(False) self.hurt_sound = self.loader.loadSfx('sounds/hurt.ogg') self.hurt_sound.setLoop(False) self.dead_sound = self.loader.loadSfx('sounds/dead.ogg') self.dead_sound.setLoop(False) self.intro_sound = self.loader.loadSfx('sounds/intro.ogg') self.intro_sound.setLoop(False) self.intro_sound.play() self.enableParticles() self.center_mouse() #self.disableMouse() self.prev_pos = None if base.mouseWatcherNode.hasMouse(): x=base.mouseWatcherNode.getMouseX() y=base.mouseWatcherNode.getMouseY() self.prev_pos = (x,y) #Hide cursor props = WindowProperties() props.setCursorHidden(True) self.win.requestProperties(props) self.environ = self.loader.loadModel('models/ourworld') self.environ.setPos(0,0,0) self.environ.reparentTo(self.render) self.pandaActor = Actor("models/hero_anim", {'kick':'models/hero_anim-kick','unready_to_shoot':'models/hero_anim-unready_to_shoot','jump':'models/hero_anim-jump',"shooting":"models/hero_anim-shooting","ready_to_shoot":"models/hero_anim-ready_to_shoot","ready_to_walk":"models/hero_anim-ready_to_run","ready_to_run":"models/hero_anim-ready_to_run","walk4":"models/hero_anim-walk1", "breathe": "models/hero_anim-breathe", "run": "models/hero_anim-walk"}) self.pandaActor.setPlayRate(3,'ready_to_shoot') self.pandaActor.setPlayRate(-1.0,"ready_to_walk") self.pandaActor.setPlayRate(1.5,'run') self.pandaActor.setPlayRate(1.5,'ready_to_run') self.pandaActor.reparentTo(self.render) self.pandaActor.setPos(self.environ,0,0,100) self.pandaActor.loop("breathe") self.phy = NodePath("PhysicsNode") self.phy.reparentTo(self.render) self.pandaAN = ActorNode("PandaActor") self.pandaActorPhysicsP = self.phy.attachNewNode(self.pandaAN) self.physicsMgr.attachPhysicalNode(self.pandaAN) self.pandaActor.reparentTo(self.pandaActorPhysicsP) #set mass of panda self.pandaAN.getPhysicsObject().setMass(100) #apply gravity self.gravityFN=ForceNode('world-forces') self.gravityFNP=self.environ.attachNewNode(self.gravityFN) self.gravityForce=LinearVectorForce(0,0,-30.81) #gravity acceleration self.gravityFN.addForce(self.gravityForce) self.physicsMgr.addLinearForce(self.gravityForce) #camera stuff self.camera.reparentTo(self.pandaActor) self.camera.lookAt(self.pandaActor) self.taskMgr.add(self.spinCameraTask, "zombieTask_SpinCameraTask") self.taskMgr.doMethodLater(0.01,self.movePandaTask,"zombieTask_movePandaTask") #Collision Handling self.cTrav = CollisionTraverser() self.collisionHandler = CollisionHandlerEvent() #Add collider for terrain self.groundCollider = self.environ.find("**/terrain") #Add walker for panda self.collision_sphere = CollisionSphere(0,0,1,1) self.collNode = CollisionNode('pandaWalker') self.cnodePath = self.pandaActor.attachNewNode(self.collNode) self.cnodePath.node().addSolid(self.collision_sphere) #AddZombieDetector for panda self.zombie_sphere = CollisionSphere(0,0,3,1) self.zomb_detector_node = CollisionNode('zombieDetector') self.zomb_detector_NP = self.pandaActor.attachNewNode(self.zomb_detector_node) self.zomb_detector_NP.node().addSolid(self.zombie_sphere) #self.zomb_detector_NP.show() #Add pusher against gravity self.pusher = PhysicsCollisionHandler() self.pusher.addCollider(self.cnodePath, self.pandaActorPhysicsP) self.pusher.addCollider(self.zomb_detector_NP,self.pandaActorPhysicsP) self.cTrav.addCollider(self.cnodePath,self.pusher) self.cTrav.addCollider(self.zomb_detector_NP,self.pusher) self.pusher.addInPattern('%fn-into-%in') self.pusher.addAgainPattern('%fn-again-%in') #Add collision handler patterns self.collisionHandler.addInPattern('%fn-into-%in') self.collisionHandler.addAgainPattern('%fn-again-%in') self.abientLight = AmbientLight("ambientLight") self.abientLight.setColor(Vec4(0.1, 0.1, 0.1, 1)) self.directionalLight = DirectionalLight("directionalLight") self.directionalLight.setDirection(Vec3(-5, -5, -5)) self.directionalLight.setColor(Vec4((229.0/255), (204.0/255), (255.0/255), 0.7)) self.directionalLight.setSpecularColor(Vec4(0.4, 0.4, 0.4, 0.1)) self.directionalLight.setShadowCaster(True,512,512) self.render.setLight(self.render.attachNewNode(self.abientLight)) self.render.setLight(self.render.attachNewNode(self.directionalLight)) self.render.setShaderAuto() #create zombie land self.zombieland = zombie.Zombies(self) self.taskMgr.doMethodLater(0.01,self.zombieland.moveZombie, "zombieTask_ZombieMover") layer2d.incBar(self.health) self.taskMgr.add(self.game_monitor,"zombieTask_gameMonitor") self.taskMgr.doMethodLater(2.7,self.music_play, "zombieTask_music") #Add random useless things: self.randomthings_.add_random_things() def music_play(self,task): self.music.play() return Task.done #def get_color(self): # return self.color[min(len(self.color)-1,self.level)] #GameMonitor def game_monitor(self,task): if self.paused: return Task.cont #Update Score self.layer2d.update_score(self.panda_kill_count) #Check for health of actor if self.health <= 0: self.dead_sound.play() self.pandaActor.detachNode() print "LOL u ded" self.info = """Game Over.. Score: """ + str(self.panda_kill_count) + """ Press alt+f4 to quit the game. """ self.layer2d.update_info(self.info) self.taskMgr.removeTasksMatching('zombieTask_*') if self.game_started<>True: if not self.displayed: self.display_information() self.pandaActor.setPos(self.pandaActorPhysicsP.getRelativePoint(self.render,Point3(10,10,100))) return Task.cont #Check if user is inside some level. if yes, pass. if self.inside_level or self.timeout: return Task.cont self.inside_level = True #self.health=100 self.timeout=True print ".." #The next lines will be executed only when the user is in between two levels (or at the beginning of the game) #Display information based on game level self.display_information() print "HUEHUEHUEHUE" #Schedule wave of zombies self.taskMgr.doMethodLater(10,self.addWave, "zombieTask_ZombieAdder") return Task.cont def addWave(self,task): ##add a wave of 5 zombies, depending on the level. ##speed of zombie increases with each level ##durability of zombie increases with each level. ##Wave ends when all zombies die. self.directionalLight.setSpecularColor(Vec4(0.4, 0.4, 0.4, 0.1)) self.layer2d.update_info("level"+str(self.level)) self.timeout=False self.zombieland.add(5) return Task.done #information displayer def display_information(self): #display information based on levels. print self.game_started self.displayed=True if self.game_started==False: info = """ Welcome to PandaLand. Once upon a time, there used to be these cute little creatures called Pandas. They were lazy, funny, and adorable. But that is what we humans thought. Pandas are actually an evil alien race that spread from planet to planet, spreading destruction and terror everywhere. They ruled earth several billion years ago. But our super ancestors (Dinosaurs) fought agaisnt them with great valour and selflessness; and managed to save planet Earth from doom. But the pandas went into hiding (and became cute); until few days back! Now they seek to kill all. You, the Joker, are our only hope,since Batman has retired. Go Kill Pandas.For Mother Earth! """ self.layer2d.information['bg'] = (0,0,0,0.8) else: self.layer2d.update_info('') if self.level==0: info=""" Your game will start in a few seconds. This is the first level. Pandas will spawn and follow you. Shoot to kill. Test out your controls while they are still cute and harmless :) Jump: Space Shoot: LeftClick Kick: RightClick Walk: A/W/S/D For more information, press P. """ self.layer2d.information['bg'] = (0,0,0,0.6) elif self.level==1: info=""" Level 0 Completed! Starting Level 1. Pandas have turned evil and stronger. They will try to eat you up. To run: Press Shift + A/S/W/D """ elif self.level==2: info=""" Level 1 Completed! Starting Level 2. Pandas are even stronger now. They will get stronger by each level. Your automatic shooting speed has also improved due to experience gained. """ elif self.level==3: info=""" Level 2 Completed! Starting Level 3. Pandas also move faster by each level. They really want to eat you. But don't worry, you also run faster as the levels proceed. """ else: info = """ Level """ + str(self.level-1) + """ Completed! Starting """ + str(self.level) + """ . Well done! Keep fighting, our fate lies in your hands. """ self.layer2d.update_info(info) #self.create_bullet() def create_bullet(self): self.bullet = self.loader.loadModel('models/gun/bullet') self.gunshot.play() self.bulletAN = ActorNode("BulletNode") self.bulletActorPhysicsP = self.phy.attachNewNode(self.bulletAN) self.physicsMgr.attachPhysicalNode(self.bulletAN) self.bullet.reparentTo(self.bulletActorPhysicsP) self.bulletAN.getPhysicsObject().setMass(1) self.bullet.setPos(self.pandaActor,0,-3,3.5) self.bullet.setScale(0.1,0.1,0.1) self.bullet.setHpr(self.pandaActor,0,90,0) self.bullet.setP(self.camera.getP()+90) self.bullet_sphere = CollisionSphere(0,0,0,0.2) self.bullet_collNode = CollisionNode('bullet') self.bullet_cnodePath = self.bullet.attachNewNode(self.bullet_collNode) self.bullet_cnodePath.node().addSolid(self.bullet_sphere) #self.pusher.addCollider(self.bullet_cnodePath,self.bulletActorPhysicsP) self.cTrav.addCollider(self.bullet_cnodePath,self.collisionHandler) #self.bullet_cnodePath.show() self.bullets += [self.bullet] def bulletKiller(self,task): if self.paused: return Task.cont self.bullets[0].remove_node() self.bullets = self.bullets[1:] return Task.done def bulletThrower(self,task): if self.paused: return Task.cont #make bullet move if self.pandaActor.getCurrentAnim()<>'shooting' and self.pandaActor.getCurrentAnim()<>'ready_to_shoot': self.pandaActor.play('shooting') print "loL" self.create_bullet() self.bulletAN.getPhysicsObject().setVelocity(self.render.getRelativeVector(self.camera,Vec3(0,200,0))) self.taskMgr.doMethodLater(max(0.05,0.1*(5-self.level)),self.bulletThrower, "zombieTask_bulletThrower") self.taskMgr.doMethodLater(0.5,self.bulletKiller, "zombieTask_bulletKiller") self.prev=True if self.old_anim2==None: self.old_anim2='breathe' if self.old_anim2 not in ['run','walk4']: self.old_anim2='breathe' self.anim_queue = [(self.pandaActor,True,'unready_to_shoot'),(self.pandaActor,False,self.old_anim2)] return Task.done def movePandaTask(self,task): if self.paused: return Task.cont tempos = self.pandaActor.getPos() speed = 0.1 if self.run_: speed+=0.3*self.level self.rightspeed = -(self.r-self.l)*speed self.forwardspeed = -(self.f-self.b)*speed if (self.r-self.l)<>0 and (self.f-self.b)<>0: #print self.forwardspeed #print self.rightspeed #sys.exit(0) self.rightspeed *= 0.7 self.forwardspeed *= 0.7 self.pandaActor.setPos(self.pandaActor,self.rightspeed, self.forwardspeed,0) return Task.again def spinCameraTask(self, task): if self.paused: return Task.cont if self.render.getRelativePoint(self.pandaActorPhysicsP,self.pandaActor.getPos())[2] < -10: self.pandaAN.getPhysicsObject().setVelocity(0,0,30) #self.pandaActor.setPos(self.pandaActorPhysicsP.getRelativePoint(self.render,Point3(10,10,100))) self.prev_time=task.time #play queued animations: for x in self.move_anim_queue+self.anim_queue: if x[0].getCurrentAnim()==None: if x[1]: x[0].play(x[2]) else: x[0].loop(x[2]) if x in self.move_anim_queue: self.move_anim_queue.remove(x) elif x in self.anim_queue: self.anim_queue.remove(x) #Do other stuff if self.mouseWatcherNode.hasMouse(): x=base.mouseWatcherNode.getMouseX() y=base.mouseWatcherNode.getMouseY() if self.prev_pos==None: self.prev_pos = (x,y) xx = self.prev_pos[0] - x yy = self.prev_pos[1] + y self.prev_pos = (xx,yy) self.pandaActor.setHpr(self.pandaActor,-20*(pi/2.0)*x,0,0) #self.camera.setHpr(self.pandaActor, 20*(pi/2.0)*x, 20*(pi/2.0)*yy, 0) if self.is_firstP: self.camera.lookAt(self.pandaActor) self.camera.setPos(self.pandaActor,0,0,4) self.camera.setHpr(self.camera,180,0,0) else: self.camera.setPos(self.pandaActor,0,8,5) self.camera.lookAt(self.pandaActor) if self.mirror: self.camera.setY(-self.camera.getY()) self.camera.lookAt(self.pandaActor) self.camera.setHpr(self.camera,0,20*(pi/2.0)*yy,0) self.center_mouse() #zombie collisions return Task.cont #User Actions: def meelee(self): #Make actor stomp here. or something #Load animation self.zombieland.meelee() self.anim_queue += [(self.pandaActor,True,self.pandaActor.getCurrentAnim())] self.pandaActor.play('kick') #pass def ranged_start(self): #put animation here self.old_anim = self.pandaActor.getCurrentAnim() if self.old_anim not in ['shooting','unready_to_shoot','ready_to_shoot'] : self.old_anim2 = self.old_anim if self.old_anim not in ['ready_to_shoot','shooting','unready_to_shoot']: self.pandaActor.play('ready_to_shoot') self.taskMgr.add(self.bulletThrower, "zombieTask_bulletThrower") def ranged_stop(self,task=None): if self.paused: return Task.cont #stop animation here if self.pandaActor.getCurrentAnim()<>'shooting' and task==None: self.pandaActor.play('shooting') self.taskMgr.remove("zombieTask_bulletThrower") self.taskMgr.doMethodLater(0.5,self.ranged_stop,'zombieTask_rangedStop') return Task.done self.taskMgr.remove("zombieTask_bulletThrower") return Task.done
class CollisionManager(Manager, DirectObject): """Handles the collision between objects on the scene.""" def __init__(self, debug=False): self._debug = debug self.handler = PhysicsCollisionHandler() self.handler.setStaticFrictionCoef(0.1) self.handler.setDynamicFrictionCoef(0.05) self.handler.addInPattern('into-%in') self.handler.addAgainPattern('again-%in') self.handler.addOutPattern('out-%in') self.handler.addInPattern('%fn-into-%in') @debug(['managers']) def setup(self): self._old_cTrav = base.cTrav base.cTrav = CollisionTraverser() base.cTrav.setRespectPrevTransform(True) if self._debug: base.cTrav.showCollisions(base.gameState.currentState.objectsNode) self.addCollider(base.gameState.currentState.objects['equismo']) @debug(['managers']) def clear(self): base.cTrav.clearColliders() base.cTrav = self._old_cTrav self.ignoreAll() def addCollider(self, physicalNode): """Add a node to the collision system. The parameter 'physicalNode' must be an instance of PhysicalNode. """ self.handler.addCollider(physicalNode.collider, physicalNode.actor) base.cTrav.addCollider(physicalNode.collider, self.handler) if self._debug: physicalNode.collider.show() def addCollisionHandling(self, intoNode, type, *handlers): """Notify that a collision event should be handled. The given 'type' should be "into", "again" or "out". The given handlers must inherit from the CollisionEventHandler class. Its 'handleCollisionEvent' method will be called whenever a collision with the node given by 'intoNode' occurs. """ pattern = "%s-%s" % (type, intoNode.getName()) self.accept(pattern, self._callHandlers, [handlers, type]) def addMutualCollisionHandling(self, fromNode, intoNode): """Notify that a 'into' collision event between two specific nodes should be handled by them. The given nodes must inherit from the CollisionEventHandler class. Its 'handleCollisionEvent' method will be called whenever a collision with the node given by 'intoNode' occurs. """ pattern = "%s-into-%s" % (fromNode.collider.getName(), intoNode.collider.getName()) handlers = [fromNode, intoNode] self.accept(pattern, self._callHandlers, [handlers, "into"]) def _callHandlers(self, handlers, type, entry): for handler in handlers: handler.handleCollisionEvent(entry, type)
class DistributedCashbotBossObject(DistributedSmoothNode.DistributedSmoothNode, FSM.FSM): notify = DirectNotifyGlobal.directNotify.newCategory( 'DistributedCashbotBossObject') wantsWatchDrift = 1 def __init__(self, cr): DistributedSmoothNode.DistributedSmoothNode.__init__(self, cr) FSM.FSM.__init__(self, 'DistributedCashbotBossObject') self.boss = None self.avId = 0 self.craneId = 0 self.cleanedUp = 0 self.collisionNode = CollisionNode('object') self.collisionNode.setIntoCollideMask( ToontownGlobals.PieBitmask | OTPGlobals.WallBitmask | ToontownGlobals.CashbotBossObjectBitmask | OTPGlobals.CameraBitmask) self.collisionNode.setFromCollideMask(ToontownGlobals.PieBitmask | OTPGlobals.FloorBitmask) self.collisionNodePath = NodePath(self.collisionNode) self.physicsActivated = 0 self.toMagnetSoundInterval = Sequence() self.hitFloorSoundInterval = Sequence() self.hitBossSfx = loader.loadSfx( 'phase_5/audio/sfx/AA_drop_safe_miss.ogg') self.hitBossSoundInterval = SoundInterval(self.hitBossSfx) self.touchedBossSfx = loader.loadSfx( 'phase_5/audio/sfx/AA_drop_sandbag.ogg') self.touchedBossSoundInterval = SoundInterval(self.touchedBossSfx, duration=0.8) self.lerpInterval = None def disable(self): self.cleanup() self.stopSmooth() DistributedSmoothNode.DistributedSmoothNode.disable(self) def cleanup(self): if self.cleanedUp: return else: self.cleanedUp = 1 self.demand('Off') self.detachNode() self.toMagnetSoundInterval.finish() self.hitFloorSoundInterval.finish() self.hitBossSoundInterval.finish() self.touchedBossSoundInterval.finish() del self.toMagnetSoundInterval del self.hitFloorSoundInterval del self.hitBossSoundInterval del self.touchedBossSoundInterval self.boss = None def setupPhysics(self, name): an = ActorNode('%s-%s' % (name, self.doId)) anp = NodePath(an) if not self.isEmpty(): self.reparentTo(anp) NodePath.assign(self, anp) self.physicsObject = an.getPhysicsObject() self.setTag('object', str(self.doId)) self.collisionNodePath.reparentTo(self) self.handler = PhysicsCollisionHandler() self.handler.addCollider(self.collisionNodePath, self) self.collideName = self.uniqueName('collide') self.handler.addInPattern(self.collideName + '-%in') self.handler.addAgainPattern(self.collideName + '-%in') self.watchDriftName = self.uniqueName('watchDrift') def activatePhysics(self): if not self.physicsActivated: self.boss.physicsMgr.attachPhysicalNode(self.node()) base.cTrav.addCollider(self.collisionNodePath, self.handler) self.physicsActivated = 1 self.accept(self.collideName + '-floor', self.__hitFloor) self.accept(self.collideName + '-goon', self.__hitGoon) self.acceptOnce(self.collideName + '-headTarget', self.__hitBoss) self.accept(self.collideName + '-dropPlane', self.__hitDropPlane) def deactivatePhysics(self): if self.physicsActivated: self.boss.physicsMgr.removePhysicalNode(self.node()) base.cTrav.removeCollider(self.collisionNodePath) self.physicsActivated = 0 self.ignore(self.collideName + '-floor') self.ignore(self.collideName + '-goon') self.ignore(self.collideName + '-headTarget') self.ignore(self.collideName + '-dropPlane') def hideShadows(self): pass def showShadows(self): pass def stashCollisions(self): self.collisionNodePath.stash() def unstashCollisions(self): self.collisionNodePath.unstash() def __hitFloor(self, entry): if self.state == 'Dropped' or self.state == 'LocalDropped': self.d_hitFloor() self.demand('SlidingFloor', localAvatar.doId) def __hitGoon(self, entry): if self.state == 'Dropped' or self.state == 'LocalDropped': goonId = int(entry.getIntoNodePath().getNetTag('doId')) goon = self.cr.doId2do.get(goonId) if goon: self.doHitGoon(goon) def doHitGoon(self, goon): pass def __hitBoss(self, entry): if (self.state == 'Dropped' or self.state == 'LocalDropped') and self.craneId != self.boss.doId: vel = self.physicsObject.getVelocity() vel = self.crane.root.getRelativeVector(render, vel) vel.normalize() impact = vel[1] if impact >= self.getMinImpact(): print 'hit! %s' % impact self.hitBossSoundInterval.start() self.doHitBoss(impact) else: self.touchedBossSoundInterval.start() print '--not hard enough: %s' % impact def doHitBoss(self, impact): self.d_hitBoss(impact) def __hitDropPlane(self, entry): self.notify.info('%s fell out of the world.' % self.doId) self.fellOut() def fellOut(self): raise StandardError, 'fellOut unimplented' def getMinImpact(self): return 0 def __watchDrift(self, task): v = self.physicsObject.getVelocity() if abs(v[0]) < 0.0001 and abs(v[1]) < 0.0001: self.d_requestFree() self.demand('Free') return Task.cont def prepareGrab(self): pass def prepareRelease(self): pass def setBossCogId(self, bossCogId): self.bossCogId = bossCogId self.boss = base.cr.doId2do[bossCogId] def setObjectState(self, state, avId, craneId): if state == 'G': self.demand('Grabbed', avId, craneId) elif state == 'D': if self.state != 'Dropped': self.demand('Dropped', avId, craneId) elif state == 's': if self.state != 'SlidingFloor': self.demand('SlidingFloor', avId) elif state == 'F': self.demand('Free') else: self.notify.error('Invalid state from AI: %s' % state) def d_requestGrab(self): self.sendUpdate('requestGrab') def rejectGrab(self): if self.state == 'LocalGrabbed': self.demand('LocalDropped', self.avId, self.craneId) def d_requestDrop(self): self.sendUpdate('requestDrop') def d_hitFloor(self): self.sendUpdate('hitFloor') def d_requestFree(self): self.sendUpdate( 'requestFree', [self.getX(), self.getY(), self.getZ(), self.getH()]) def d_hitBoss(self, impact): self.sendUpdate('hitBoss', [impact]) def defaultFilter(self, request, args): if self.boss == None: raise FSM.RequestDenied, request return FSM.FSM.defaultFilter(self, request, args) def enterOff(self): self.detachNode() if self.lerpInterval: self.lerpInterval.finish() self.lerpInterval = None def exitOff(self): self.reparentTo(render) def enterLocalGrabbed(self, avId, craneId): self.avId = avId self.craneId = craneId self.crane = self.cr.doId2do.get(craneId) self.hideShadows() self.prepareGrab() self.crane.grabObject(self) def exitLocalGrabbed(self): if self.newState != 'Grabbed': self.crane.dropObject(self) self.prepareRelease() del self.crane self.showShadows() def enterGrabbed(self, avId, craneId): if self.oldState == 'LocalGrabbed': if craneId == self.craneId: return else: self.crane.dropObject(self) self.prepareRelease() self.avId = avId self.craneId = craneId self.crane = self.cr.doId2do.get(craneId) self.hideShadows() self.prepareGrab() self.crane.grabObject(self) def exitGrabbed(self): self.crane.dropObject(self) self.prepareRelease() self.showShadows() del self.crane def enterLocalDropped(self, avId, craneId): self.avId = avId self.craneId = craneId self.crane = self.cr.doId2do.get(craneId) self.activatePhysics() self.startPosHprBroadcast() self.hideShadows() self.handler.setStaticFrictionCoef(0) self.handler.setDynamicFrictionCoef(0) def exitLocalDropped(self): if self.newState != 'SlidingFloor' and self.newState != 'Dropped': self.deactivatePhysics() self.stopPosHprBroadcast() del self.crane self.showShadows() def enterDropped(self, avId, craneId): self.avId = avId self.craneId = craneId self.crane = self.cr.doId2do.get(craneId) if self.avId == base.localAvatar.doId: self.activatePhysics() self.startPosHprBroadcast() self.handler.setStaticFrictionCoef(0) self.handler.setDynamicFrictionCoef(0) else: self.startSmooth() self.hideShadows() def exitDropped(self): if self.avId == base.localAvatar.doId: if self.newState != 'SlidingFloor': self.deactivatePhysics() self.stopPosHprBroadcast() else: self.stopSmooth() del self.crane self.showShadows() def enterSlidingFloor(self, avId): self.avId = avId if self.lerpInterval: self.lerpInterval.finish() self.lerpInterval = None if self.avId == base.localAvatar.doId: self.activatePhysics() self.startPosHprBroadcast() self.handler.setStaticFrictionCoef(0.9) self.handler.setDynamicFrictionCoef(0.5) if self.wantsWatchDrift: taskMgr.add(self.__watchDrift, self.watchDriftName) else: self.startSmooth() self.hitFloorSoundInterval.start() def exitSlidingFloor(self): if self.avId == base.localAvatar.doId: taskMgr.remove(self.watchDriftName) self.deactivatePhysics() self.stopPosHprBroadcast() else: self.stopSmooth() def enterFree(self): self.avId = 0 self.craneId = 0 def exitFree(self): pass