Exemplo n.º 1
0
class RandomObject():
    def __init__(self, id, common, node, render, moneyamount=1):
        self.id = id
        self.common = common
        self.node = node
        self.message = None
        self.moneyamount = moneyamount
        self.object = Actor("models/object",
                            {'rotate': 'models/object-rotate'})
        self.object.setScale(0.20)
        self.object.setZ(1.5)
        self.object.reparentTo(render)
        self.object.loop("rotate")
        #Get last position of monster
        (x, y, z) = self.node.getPos()
        self.object.setPos((x, y, z + 0.5))
        base.enableParticles()
        #Load particles
        self.pe = ParticleEffect()
        self.pe.loadConfig(Filename("vfx/object.ptf"))
        self.pe.start(parent=self.object, renderParent=self.object)
        self.ambientLight = AmbientLight('ambientLight')
        self.ambientLight.setColor(VBase4(.3, .3, .3, 1))
        self.ambientLightNode = render.attachNewNode(self.ambientLight)
        self.object.setLight(self.ambientLightNode)
        taskMgr.doMethodLater(.1, self.update, 'random-object' + str(self.id))

    def showLabel(self, message):
        text = TextNode('onscreenmessage')
        text.setText(message)
        text.setFont(loader.loadFont('Bitter-Bold.otf'))
        self.message = aspect2d.attachNewNode(text)
        self.message.setScale(0.05)
        window = base.win.getProperties()
        windowX = window.getXSize()
        windowY = window.getYSize()
        self.message.setPos(-0.6, 0, -0.8)

    def update(self, task):
        if self.object.getDistance(self.common['PC'].node) < 1:
            notifysound = base.loader.loadSfx("sfx/effect-notify.wav")
            notifysound.play()
            self.object.hide()
            self.pe.disable()
            #The object can fully heal the player, give him money or give him an item
            n = random.randrange(100)
            if (n == 0):
                self.common['PC'].heal()
            elif (n < 5):
                shopitems = self.common['PC'].getShopItems()
                i = random.randrange(len(shopitems))
                self.showLabel("You received '" + shopitems[i]['name'] + "'")
                shopitems[i]['count'] += shopitems[i]['count'] + 1
                self.common['PC'].items.append(shopitems[i])
                self.common['PC'].showCurrentItem()
                taskMgr.doMethodLater(2, self.destroyTask, 'show-message')
            else:
                self.common['PC'].addMoney(self.moneyamount)
            return task.done
        return task.again

    def destroyTask(self, task):
        self.destroy()
        return task.done

    def destroy(self):
        taskMgr.remove('random-object' + str(self.id))
        self.object.cleanup()
        self.object.removeNode()
        self.pe.removeNode()
        if self.message:
            self.message.removeNode()
        self.ambientLightNode.removeNode()
Exemplo n.º 2
0
class Saucer(DirectObject):
    def __init__(self):
    
        self.ship = loader.loadModel("Art\ufo.egg")
        self.beam = loader.loadModel("Art\eam.egg")
        self.health = 100
      
        #Dummy is used to position the tractor beam collisionsphere
        self.dummy = NodePath('dummy')
        self.dummy.reparentTo(render)
        
        #Dummy2 used to position abductees
        self.dummy2 =  NodePath('dummy2')
        self.dummy2.reparentTo(render)

        self.beam.reparentTo(self.dummy2)
        
        self.glownode = self.ship.find("**/l_glownode")
        self.glownode.setColor(0,0,.5,1)
        
        self.glownode2 = self.ship.find("**/r_glownode")
        self.glownode2.setColor(0,0,.5,1)
            
        self.ship.reparentTo(render)
        self.ship.setScale(1)
        #self.ship.setH(180)
        self.ship.setPos(0,0,25)
        self.dummy.setPos(0,0,25)
        self.dummy2.setPos(0,0,25)
        
        #list of things currently abducting
        self.abductlist = []
        self.animals = []
        self.inanimates = []
        taskMgr.add(self.abductTask, "abductTask")
        taskMgr.add(self.lightTask, "lightTask")
        self.stuntime = 30
        self.stunbase = 30
        self.updown = False
        self.beamspeed = 1
        self.basebeamspeed = 2
        
        self.collected = 0
        
        self.beamon = True
        
        taskMgr.add(self.particleTask, "shipparticleTask")

        self.mydir = os.path.abspath(sys.path[0])
        self.mydir = Filename.fromOsSpecific(self.mydir).getFullpath()
        self.mydir = Filename(self.mydir)
        #self.mydir = self.mydir.toOsSpecific()
        
        self.abductp = ParticleEffect()
        self.abductp.loadConfig(self.mydir + '/abduct.ptf')
        self.pcount = 0
        self.particletime = 60 #Must be integer 

    def pickUp(self,object):   #Pick up another pickupable 
        if object.stuncount < self.stuntime:
            object.stunned = True
        else:
            if (len(self.abductlist) < 15):
                if object.type1 == 'inanimate':
                    self.inanimates.append(object)
                elif object.type1 == 'hostile':
                    self.inanimates.append(object)
                elif object.type1 == 'animal':
                    self.animals.append(object)
                    
                self.findSpeed()
                
                object.resetStun()
                object.abduct = True
                self.abductlist.append(object)
                object.playPickupSound()
                object.pickup.reparentTo(self.dummy2)
                object.pickup.setHpr(0,0,0)
                object.pickup.setPos(0,0,-37)
            else:
                print ("Pickup list full.")
    
    def drop(self,env): #Drop all
        for object in self.abductlist:
            object.abduct = False
            object.pickup.wrtReparentTo(env)
            #object.pickup.setPos(self.dummy2.getX(),self.dummy2.getY(),self.dummy2.getZ())
        self.abductlist[:] = []
 
    def lightTask(self,task):
        if not self.beamon:
            self.glownode.setColor(.1,.06,.92,1)
            self.glownode2.setColor(.1,.06,.92,1)
        if self.beamon:
            s = self.beamspeed/25     
            self.glownode.setColor(.12 - s/10,1 - s,.08 - s/10,1)
            self.glownode2.setColor(.12 - s/10,1 - s,.08- s/10,1)
        return task.cont
            
    def abductTask(self,task):
        if self.updown:
            self.dummy.setZ(self.ship.getZ())
            self.updown = False
        else:
            self.dummy.setZ(36)
            self.updown = True
    
        for obj in self.abductlist:
            obj.rise(self)
            
        return Task.cont

    def cowbig(self,me):
        if me > self.panda and me > self.pigs and me > self.sheep:
            return True
    def pigbig(self,me):
        if me > self.cows and me > self.sheep and me > self.panda:
            return True
    def sheepbig(self,me):
        if me > self.cows and me > self.pigs and me > self.panda:
            return True
    def pandabig(self,me):
        if me > self.cows and me > self.pigs and me > self.sheep:
            return True            


    def biggest(self):
        if self.cowbig(self.cows):
            return self.cows - ((self.pigs + self.sheep + self.panda) / 3)
        if self.pigbig(self.pigs):
            return self.pigs - ((self.cows + self.sheep + self.panda) / 3)
        if self.sheepbig(self.sheep):
            return self.sheep - ((self.pigs + self.cows + self.panda) / 3)
        if self.pandabig(self.panda):
            return self.panda - ((self.pigs + self.sheep + self.cows) / 3)
          
        return 0
        
    def findSpeed(self):
        self.cows = 0
        self.pigs = 0
        self.sheep = 0
        self.panda = 0
        for animal in self.animals:
            if animal.type2 == 'cow':
                self.cows += 1
            if animal.type2 == 'pig':
                self.pigs += 1
            if animal.type2 == 'sheep':
                self.sheep += 1
            if animal.type2 == 'panda':
                self.panda += 1
        
        speedadd = self.biggest() * 1.7
        
        speeddeduct = len(self.inanimates)
        self.beamspeed = self.basebeamspeed - speeddeduct + speedadd
        self.stuntime = self.stunbase - (self.beamspeed * 1.5)
        
        if self.stuntime < 2:
            self.stuntime = 2
        
        #Minimum beam speed
        if self.beamspeed < 2:
            self.beamspeed = 2
            
    def abductAnimal(self):
        self.pcount = self.particletime
        #self.abductp.start(parent = self.ship, renderParent = self.ship)
        self.collected += 1

        
    def particleTask(self,task):
        if self.pcount > 0:
            self.pcount -= 1
        elif self.pcount == 0:
            self.pcount = -1
            self.abductp.reset()
            self.abductp.disable()
            
        return task.cont
Exemplo n.º 3
0
class GrenadeLauncher:
    """Grenade launcher locomotive upgrade.

    Represents an active weapon, which can
    do a lot of damage on some radius.

    Args:
        loc_model (panda3d.core.NodePath): The locomotive model.
    """

    def __init__(self, loc_model):
        self.is_up = False
        # flag, which indicates if the launcher
        # is in (un-)loading process
        self._is_loading = False
        self._range_col_np = None

        self._loc_model = loc_model

        self._model = Actor(address("grenade_launcher"))
        self._model.reparentTo(loc_model)

        self._sight = loader.loadModel(address("grenade_sight"))  # noqa: F821
        self._sight.reparentTo(loc_model)
        self._sight.hide()

        self._grenade_explosion = ParticleEffect()
        self._grenade_explosion.loadConfig("effects/grenade_explode.ptf")

        self._grenade_smoke = ParticleEffect()
        self._grenade_smoke.loadConfig("effects/bomb_smoke1.ptf")

        self._hole_sprite = loader.loadModel(address("ground_hole"))  # noqa: F821
        self._hole_sprite.reparentTo(loc_model)
        self._hole_sprite.setTransparency(TransparencyAttrib.MAlpha)
        self._hole_sprite.hide()

        base.accept("1", self.change_state)  # noqa: F821

        self._shot_snd = loader.loadSfx(  # noqa: F821
            "sounds/combat/grenade_launcher_shot.ogg"
        )
        self._explosion_snd = loader.loadSfx(  # noqa: F821
            "sounds/combat/bomb_explosion1.ogg"
        )
        self._explosion_snd.setVolume(0.15)

        self._load_snd = loader.loadSfx(  # noqa: F821
            "sounds/combat/grenade_launcher_load.ogg"
        )

    def _change_mode(self, task):
        """Change controls mode - common or grenade launcher shooting."""
        if self.is_up:
            self._sight.hide()
            self._end_aiming()
        else:
            self._smoke = ParticleEffect()
            self._smoke.loadConfig("effects/grenade_launcher_smoke.ptf")
            self._smoke.setPos(0.026, -0.15, 0.35)

            taskMgr.doMethodLater(  # noqa: F821
                0.05, self._sight.show, "show_sight", extraArgs=[]
            )
            base.common_ctrl.deselect()  # noqa: F821
            self._start_aiming()

        self.is_up = not self.is_up
        self._is_loading = False
        return task.done

    def change_state(self):
        """Change the launcher state."""
        if not base.world.is_on_et or self._is_loading:  # noqa: F821
            return

        base.train.disable_enabled_weapon(self)  # noqa: F821

        self._is_loading = True
        self._model.setPlayRate(-4 if self.is_up else 4, "gun_up")
        self._model.play("gun_up")

        if not self.is_up:
            self._load_snd.play()

        taskMgr.doMethodLater(  # noqa: F821
            0.2, self._change_mode, "grenade_launcher_aim"
        )

    def _do_grenade_damage(self, event):
        """Event which is called by the grenade explosion.

        The method do damage to the enemy units, which
        were in the grenade explosion area.
        """
        base.world.enemy.active_units[  # noqa: F821
            event.getFromNodePath().getName()
        ].get_damage(40)

    def _end_aiming(self):
        """Stop aiming and disable aiming GUI."""
        self._range_col_np.removeNode()
        base.common_ctrl.set_mouse_events()  # noqa: F82

    def _explode_grenade(self, grenade_pos):
        """Explode the grenade, shot from the launcher.

        Args:
            grenade_pos (panda3d.core.Point3):
                The position, where the sight was
                when player made the shot.
        """
        col_node = CollisionNode("grenade_explosion")
        col_node.setFromCollideMask(NO_MASK)
        col_node.setIntoCollideMask(SHOT_RANGE_MASK)
        col_node.addSolid(CollisionSphere(0, 0, 0, 0.096))

        base.accept("into-grenade_explosion", self._do_grenade_damage)  # noqa: F821

        col_np = self._model.attachNewNode(col_node)
        col_np.setPos(grenade_pos)

        self._hole_sprite.setPos(grenade_pos)
        self._hole_sprite.wrtReparentTo(
            base.world.current_block.rails_mod  # noqa: F821
        )
        self._hole_sprite.show()

        self._grenade_explosion.setPos(grenade_pos)
        self._grenade_explosion.start(self._model, render)  # noqa: F821
        self._grenade_explosion.softStart()

        self._grenade_smoke.setPos(grenade_pos)
        self._grenade_smoke.start(self._model, render)  # noqa: F82
        self._grenade_smoke.softStart()

        self._explosion_snd.play()

        taskMgr.doMethodLater(  # noqa: F821
            1, self._grenade_explosion.softStop, "stop_grenade_explosion", extraArgs=[]
        )
        taskMgr.doMethodLater(  # noqa: F821
            2.5, self._grenade_smoke.softStop, "stop_grenade_smoke", extraArgs=[]
        )
        taskMgr.doMethodLater(  # noqa: F821
            0.1, col_np.removeNode, "remove_grenade_solid", extraArgs=[]
        )
        taskMgr.doMethodLater(  # noqa: F821
            4, self._return_hole_sprite, "hide_ground_hole",
        )

    def _return_hole_sprite(self, task):
        """Return the hole sprite to the grenade launcher model."""
        self._hole_sprite.hide()
        self._hole_sprite.reparentTo(self._loc_model)
        return task.done

    def _move_sight(self, event):
        """Move the launcher sight sprite.

        The launcher sight can be moved only
        within the Train part shooting range.
        """
        if event.getIntoNodePath().getName() != "grenade_launcher_range":
            return

        point = event.getSurfacePoint(base.train.model)  # noqa: F821
        self._sight.setPos(point.getX(), point.getY(), 0.01)

    def _shot(self):
        """Make a shot."""
        self._shot_snd.play()
        self.change_state()
        base.ignore("1")  # noqa: F82

        self._smoke.start(self._model, render)  # noqa: F82
        self._smoke.softStart()

        taskMgr.doMethodLater(  # noqa: F82
            0.5,
            self._explode_grenade,
            "explode_grenade",
            extraArgs=[self._sight.getPos()],
        )
        taskMgr.doMethodLater(  # noqa: F82
            1.45, self._stop_smoke, "stop_launcher_smoke"
        )
        taskMgr.doMethodLater(  # noqa: F82
            13,
            base.accept,  # noqa: F82
            "unblock_launcher",
            extraArgs=["1", self.change_state],
        )
        base.train.make_shot("Grenade Launcher")  # noqa: F82

    def _start_aiming(self):
        """Show aiming GUI and tweak shooting events."""
        col_node = CollisionNode("grenade_launcher_range")
        col_node.setFromCollideMask(NO_MASK)
        col_node.setIntoCollideMask(MOUSE_MASK)

        col_node.addSolid(
            CollisionPolygon(
                Point3(-1.2, -0.3, 0),
                Point3(-1.2, 1.5, 0),
                Point3(1.2, 1.5, 0),
                Point3(1.2, -0.3, 0),
            )
        )
        self._range_col_np = base.train.model.attachNewNode(col_node)  # noqa: F821

        base.accept("mouse1", self._shot)  # noqa: F821
        base.accept("mouse_ray-into", self._move_sight)  # noqa: F821
        base.accept("mouse_ray-again", self._move_sight)  # noqa: F82

    def _stop_smoke(self, task):
        """Stop the launcher shot smoke."""
        self._smoke.disable()
        self._smoke.cleanup()
        return task.done
Exemplo n.º 4
0
class Pickupable(DirectObject):
    def __init__(self, type1, type2):
        self.type1 = type1
        self.type2 = type2
        self.weight = 1
        self.pickupSounds = []

        if self.type1 == "animal":
            for i in range(4):
                sound = base.loader.loadSfx("Sounds/" + self.type2 + str(i) + ".wav")
                self.pickupSounds.append(sound)

            self.suckSound = base.loader.loadSfx("Sounds/suck.wav")
            self.splatSound = base.loader.loadSfx("Sounds/splat.wav")

        else:
            sound = base.loader.loadSfx("Sounds/crunch.wav")
            self.pickupSounds.append(sound)
            self.splatSound = base.loader.loadSfx("Sounds/explosion.wav")
            

        self.pickup = loader.loadModel("Art/" + self.type2 + ".egg")
        self.pickup.setScale(1)  
        
        #Being abducted?
        self.abduct = False 
        #When pickupable height reaches this level, it is abducted.
        self.abductheight = 35
       
        #Height off of ground
        self.height = 0
        self.fallspeed = 0
        self.stunned = False
        self.falling = False
        self.lr = False
        self.shakex = 0
        self.shakey = 0 
        self.shakez = 0
        self.stuncount = 0
        taskMgr.add(self.moveTask, "moveTask")
        taskMgr.add(self.particleTask, "particleTask")
        base.enableParticles()
        

        
        self.mydir = os.path.abspath(sys.path[0])
        self.mydir = Filename.fromOsSpecific(self.mydir).getFullpath()
        self.mydir = Filename(self.mydir)
        #self.mydir = self.mydir.toOsSpecific()
        
        self.bloodp = ParticleEffect()
        self.bloodp.loadConfig(self.mydir + '/blood.ptf')
        self.explodep = ParticleEffect()
        self.explodep.loadConfig(self.mydir + '/explode.ptf')
        self.particle = ParticleEffect()
        self.particle.loadConfig(self.mydir + '/blood.ptf')
        
        
        self.pcount = -6.66 #init to this number!
        self.particletime = 70
        
        self.willdie = False
        
    def setType(self,type1,type2):
        self.type1 = type1
        self.type2 = type2
        if self.type1 == 'animal':
            self.pickup = loader.loadModel("Art/" + self.type2 + ".egg")
            self.weight = 1
        if self.type1 ==  'inanimate':
            self.pickup = loader.loadModel("Art/" + self.type2 + ".egg")
            self.weight = 2
        if self.type1 ==  'hostile':
            self.pickup = loader.loadModel("Art/" + self.type2 + ".egg")        
            self.weight = 2
            
        self.pickup.setScale(1)
        
    def create(self,x,y,z):
        self.alive = True
        self.pickup.reparentTo(render)
        self.pickup.setPos(0,0,0)
        
    def rise(self,ship): #The ship should call this in one of its tasks on every animal that it is currently abducting. 
        self.stunned = False
        self.lr = False
        self.stuncount = 0
        self.myship = ship
        self.pickup.setZ(-36 + self.height)
        self.fallspeed = 0


        if self.type1 == 'animal':
            if self.height < self.abductheight:
                self.height += .01 * self.weight * ship.beamspeed
                self.pickup.setHpr(self.pickup.getH() + 1,0,0)
            else:
                self.abducted()
        else:
            if self.height < self.abductheight:
                self.height += .01 * self.weight * ship.beamspeed
                self.pickup.setHpr(self.pickup.getH() + .5,0,0)
            else:
                ship.abductlist.remove(self)
                self.explode()

        
    
    def playPickupSound(self):
        randSound = random.choice(self.pickupSounds)
        randSound.play()

    def abducted(self):
        self.suckSound.play()
        self.die()
    
    def die(self):      #Set self to dead, remove from render node. For recycler.
        self.myship.abductAnimal()
        self.pickup.detachNode()
        self.pickup.remove()
        if self in self.myship.abductlist: 
            self.myship.abductlist.remove(self)
            if self in self.myship.animals: 
                self.myship.animals.remove(self)
            if self in self.myship.inanimates: 
                self.myship.inanimates.remove(self)
            self.myship.findSpeed()
        self.alive = False
        self.particle.disable()
        
    def particleTask(self,task):
        if self.pcount > 0:
            self.pcount -= 1
        elif (self.pcount <= 0) and (self.pcount != -6.66):
            self.pcount = -6.66
            self.particle.disable()
            if self.willdie:
                self.die()
        return task.cont
    
    def moveTask(self,task): #Responsible for falling when dropped, walking around(??)
        if not self.willdie:
            if self.stunned:    
                if self.lr == False:
                    self.lr = True
                    self.shakex = self.pickup.getX()
                    self.shakey = self.pickup.getY()
                    self.shakez = self.pickup.getZ()
                else:
                    self.pickup.setPos(self.shakex + random.uniform(-.1,.1),self.shakey + random.uniform(-.1,.1),self.shakez + random.uniform(-.1,.1))
                self.stuncount += 1
                if self.stuncount > 35:
                    self.resetStun()
                    
            
            if self.abduct == False:
                if self.height > 0:
                    self.falling = True
                    self.fallspeed = self.fallspeed + ((2 - self.fallspeed) * .01)
                    self.height -= self.fallspeed
                    self.pickup.setZ(self.pickup,-self.fallspeed)
                elif self.height  <= 0:
                    if self.falling:
                        self.height  = 0
                        self.explode()
                        self.falling = False

        return task.cont
        
    def resetStun(self):
        self.stunned = False
        self.lr = False
        self.stuncount = 0
        self.pickup.setPos(self.shakex,self.shakey,self.shakez)
        
    def explode(self):
        self.pcount = self.particletime
        if self.type1 == 'animal':
            self.particle = self.bloodp
        else:
            self.particle = self.explodep
        self.particle.start(parent = self.pickup, renderParent = self.pickup)
        self.splatSound.play()
        #self.myship.isSplat = True
        self.pickup.setAlphaScale(0) 
        self.pickup.setTransparency(TransparencyAttrib.MAlpha)
        self.willdie = True
        self.falling = False  
Exemplo n.º 5
0
class SpaceJam(ShowBase):
    showInstructions = True

    def __init__(self):
        ShowBase.__init__(self)

        self.accept('escape', self.quit)
        self.setScene()
        self.setCamera()
        self.setInstruction()

        self.setParticels()
        self.cntExplode = 0
        self.xplodeIntervals = {}

        self.pusher.addCollider(self.khanShip.cNode, self.khanShip.modelNode)
        self.traverser.addCollider(self.khanShip.cNode, self.pusher)

    def setScene(self):
        self.traverser = CollisionTraverser()
        base.cTrav = self.traverser
        self.traverser.traverse(render)
        self.pusher = CollisionHandlerPusher()

        self.handler = CollisionHandlerEvent()
        self.handler.addInPattern("into")
        self.accept("into", self.handleInto)

        self.universe = sjc.Universe('./Universe/Universe.x', render,
                                     'Big Bang',
                                     './Universe/starfield-in-blue.jpg',
                                     Vec3(0, 0, 0), 10000)

        self.sunPlanet = sjc.Planet('./Planets/protoPlanet.x', render,
                                    'Sol', './Planets/sun.jpg',
                                    Vec3(-2000, 9000, 0), 800)
        self.redPlanet = sjc.Planet('./Planets/protoPlanet.x', render, 'Mars',
                                    './Planets/redPlanet.jpg',
                                    Vec3(-2500, 8000, -2000), 300)
        self.bluePlanet = sjc.Planet('./Planets/protoPlanet.x', render,
                                     'BigBlue', './Planets/BigBlue.jpg',
                                     Vec3(500, 1500, -200), 150)
        self.earthPlanet = sjc.Planet('./Planets/protoPlanet.x', render,
                                      'Earth', './Planets/earthLike.jpg',
                                      Vec3(0, 3000, 0), 100)
        self.earthMoon = sjc.Planet('./Planets/protoPlanet.x', render, 'Moon',
                                    './Planets/moonLike.jpg',
                                    Vec3(200, 2750, -25), 25)

        self.drone = sjc.spaceStation('./Ships/DroneDefender/DroneDefender',
                                      render, 'Drone Defender',
                                      Vec3(50, -50, 50), 2)
        self.morlockShip = sjc.spaceStation('./Ships/MorlockShip/theMorlocks',
                                            render, 'Morlock Fighter',
                                            Vec3(20, -20, 20), 2)
        self.tridentShip = sjc.spaceStation('./Ships/Trident/trident',
                                            render, 'Trident Fighter',
                                            Vec3(0, -100, 0), 10)
        self.spaceStation = sjc.spaceStation(
            './Ships/SpaceStation1B/spaceStation', render, 'SpaceStation1B',
            Vec3(-200, 500, -10), 2)

        self.khanShip = sjc.SpaceShip('./Ships/KhanShip/Khan', render,
                                      'Khan Fighter', Vec3(0, 0, 0), 0.25,
                                      self.traverser, self.handler)


        self.sentinal = sjc.Orbiter("./Ships/Dumbledore/Dumbledore", render, "Drone-Travler", 125, 6.0, \
            "./Ships/DroneDefender/octotoad1_auv.png", self.spaceStation, 230, "MLB")
        ######Defense Drones######
        radian = 0
        fullCycle = 60
        for j in range(fullCycle):
            sjc.Drone.droneCnt += 1
            nickName = "drone-" + str(sjc.Drone.droneCnt)

            unitVec = mp.CircleXY(j, fullCycle)

            unitVec.normalize()
            position = unitVec * 300 + self.spaceStation.modelNode.getPos()
            self.drone = sjc.Drone("./Ships/Dumbledore/Dumbledore", render,
                                   nickName, position, 4)

    def setCamera(self):
        self.disableMouse()
        self.camera.reparentTo(self.khanShip.modelNode)
        #Third party
        self.camera.setFluidPos(0, -200, 50)
        self.camera.setHpr(0, -8, 0)

    def setInstruction(self):
        self.hud = OnscreenImage(image="./Hud/_hud/krunkerRedDot.png",
                                 pos=(0, 0, 0),
                                 scale=0.10)
        self.hud.setTransparency(TransparencyAttrib.MAlpha)


#####Camera/ Instructions#####

    def addInstruction(self, pos, msg):
        return OnscreenText(text=msg,
                            style=1,
                            fg=(1, 1, 1, 1),
                            pos=(0.5, pos),
                            align=TextNode.ABoxedLeft,
                            scale=0)

    def setParticels(self):
        base.enableParticles()
        self.splodeEffect = ParticleEffect()
        self.splodeEffect.setScale(40)
        self.explodeNode = render.attachNewNode('xpl-efx')

    def handleInto(self, entry):
        print("XXXXXX")
        print(str(entry))
        fromNode = entry.getFromNodePath().getName()
        intoNode = entry.getIntoNodePath().getName()
        intoPos = Vec3(entry.getSurfacePoint(render))
        print(str(intoNode) + " : " + str(intoPos))

        tempVar = fromNode.split("_")
        shooter = tempVar[0]
        tempVar = intoNode.split("-")
        target = tempVar[0]
        tempVar = intoNode.split("_")
        victim = tempVar[0]

        print("missile Hit")
        print(shooter)
        print(fromNode + " into " + intoNode)
        print(victim)

        if target == "drone":
            sjc.Missile.Intervals[shooter].finish()
            self.droneDestroy(victim, intoPos)
        else:
            sjc.Missile.Intervals[shooter].finish()

    def droneDestroy(self, hitID, hitPos):
        nodeID = self.render.find(hitID)
        nodeID.detachNode()
        print(hitID + " destroyed")

        self.explode(hitID, hitPos)

        self.explodeNode.setPos(hitPos)

    def explode(self, hitID, impactPt):
        start = Vec3(0, 0, 0) + Vec3(impactPt)

        self.cntExplode += 1
        tag = 'particles-' + str(self.cntExplode)
        print('\n' + str(self.explodeNode.getPos()) + "explosion location")
        self.xplodeIntervals[tag] = LerpFunc(self.explodeLight, fromData=0, \
            toData=1, duration=2.0, extraArgs=[impactPt])
        self.xplodeIntervals[tag].start()

    def explodeLight(self, t, explPosition):
        if t == 1.0 and self.splodeEffect:
            self.splodeEffect.disable()
        elif t == 0:
            self.splodeEffect.start(self.explodeNode)

    def quit():
        sys.exit()
Exemplo n.º 6
0
class Block:
    """Single world block.

    Consists of railway model, path for the locomotive to move along,
    environment models and two terrain blocks.

    On creation it chooses terrains models and arranges environment
    models, but only coordinates and model names are generated.
    All of that content will be loaded on Block.prepare() call.

    Args:
        path (Mopath.Mopath): Motion path.
        cam_path (Mopath.Mopath): Motion path for camera.
        name (str): Block path name.
        z_coor (int): Coordinate of the block.
        z_dir (int): Direction of the block along Z-axis.
        id_ (int): The block id.
        direction (dict): Possible movement directions on this block.
        surf_vertices (dict): Vertices index of every surface model.
        branch (str): Branch direction indicator: "l" or "r".
        enemy_territory (bool): This block is an enemy territory.
        is_station (bool): Station must be set on this block.
        is_city (bool): This is a city block.
        is_rusty (bool): Rails on this block are deteriorated.
        is_stenchy (bool): This block is covered with the Stench clouds.
        outing_available (str): An outing type available on this block.
        desc (dict): Block description.
    """
    def __init__(
        self,
        path,
        cam_path,
        name,
        z_coor,
        z_dir,
        id_,
        directions,
        surf_vertices,
        branch=None,
        enemy_territory=False,
        is_station=False,
        is_city=False,
        is_rusty=False,
        is_stenchy=False,
        outing_available=None,
        desc=None,
    ):

        self._surfs = []
        self._phys_objs = []
        self.rails_mod = None
        self._add_surface = False
        self._old_values = None

        self.name = name
        self.path = path
        self.cam_path = cam_path
        self.enemy_territory = enemy_territory
        self.outing_available = outing_available
        self.is_city = is_city
        self.is_rusty = is_rusty
        self.is_stenchy = is_stenchy
        self.id = id_
        self.z_coor = z_coor
        self.z_dir = z_dir
        self.directions = directions
        self.branch = branch
        self.is_station = is_station
        self._fireflies = None

        if desc:  # loading block
            self._station_side = desc["station_side"]
            self._l_surface = desc["l_surface"]
            self._r_surface = desc["r_surface"]
            self._l_angle = desc["l_angle"]
            self._r_angle = desc["r_angle"]
            self._env_mods = desc["env_mods"]
            self._railways_model = desc["railways_model"]
            self.id = desc["id"]
            self.branch = desc["branch"]
            self.directions = desc["directions"]
            self.is_station = desc["is_station"]
            return

        # generating block
        self._station_side = random.choice(("l", "r")) if is_station else None

        self._l_surface, self._l_angle = self._gen_surface("l")
        self._r_surface, self._r_angle = self._gen_surface("r")

        self._env_mods = {
            "l":
            self._gen_env_mods(copy.deepcopy(surf_vertices[self._l_surface])),
            "r":
            self._gen_env_mods(copy.deepcopy(surf_vertices[self._r_surface])),
        }
        self._railways_model = self._gen_railways_model()

    def _gen_env_mods(self, vertices):
        """Randomly select and arrange environment models.

        Args:
            vertices (list): Vertices of the terrain model.

        Returns:
            list:
                Lists in which the first element is an environment
                model name, and the second is its position.
        """
        models = []
        et_suf = "et_" if self.enemy_territory else ""

        for models_conf in LOCATION_CONF[et_suf + "with_quantity"]:
            for _ in range(random.randint(*models_conf["quantity"])):
                models.append((
                    random.choice(models_conf["models"]),
                    take_random(vertices[models_conf["square"]]),
                ))
        for models_conf in LOCATION_CONF[et_suf + "with_chance"]:
            if chance(models_conf["chance"]):
                models.append((
                    random.choice(models_conf["models"]),
                    take_random(vertices[models_conf["square"]]),
                ))
        return models

    def _gen_railways_model(self):
        """Select railways model and generate its coordinates.

        Returns:
            list: Railways model name, x and y coords, angle.
        """
        if (self.name != "direct" or chance(83) or self.enemy_territory
                or self.is_station):
            return

        model = random.choice((
            "arch1",
            "sign1",
            "sign2",
            "sign3",
            "light_post{}".format(random.randint(1, 2)),
            "lamp_post1",
            "transparant1",
        ))
        if model in ("arch1", "transparant1"):
            coor = 0
        else:
            coor = random.choice((0.15, -0.15))

        if model == "lamp_post1" and coor > 0:
            angle = 180
        else:
            angle = 0

        return (address(model), (coor, random.randint(0, 8)), angle)

    def _gen_surface(self, side):
        """Generate a terrain block.

        Randomly choose one of the terrain blocks proper for this
        rails block. Randomly rotate it. Use special terrain blocks
        for enemy territory.

        Args:
            side (str):
                Side of the terrain block, relatively to the railway.

        Returns:
            str, int: Terrain model name, angle.
        """
        if self.enemy_territory:
            return address("surface_en1"), random.choice(ANGLES)

        if self.is_city:
            return address("surface_with_" + side +
                           "_city"), 180 if side == "r" else 0

        if side == self._station_side:
            surface = address(take_random(
                base.world.stations_pool))  # noqa: F821
            return surface, (180 if side == "r" else 0)

        surface = address(random.choice(SURFACES[self.name]))
        if self.name == "direct":
            return surface, random.choice(ANGLES)

        return surface, 0

    def _load_surface_block(self,
                            name,
                            x_pos,
                            y_pos,
                            angle,
                            side=None,
                            invert=False):
        """Load terrain model and set it to the given coords.

        Terrain model will be reparented to the rails model of this
        Block. Models are loaded asynchronous to avoid freezing.

        Args:
            name (str): Surface model name.
            x_pos (int): Position on X axis.
            y_pos (int): Position on Y axis.
            angle (int): Angle to rotate the model.
            side (str): Left or right side.
            invert (bool):
                True if the Train is moving in the direction
                opposite to the main railway line.
        """
        # load terrain
        surf_mod = loader.loadModel(name)  # noqa: F821
        if "surface4" in name or "surface5" in name:
            base.world.sun.ignore_shadows(surf_mod)  # noqa: F821

        surf_mod.reparentTo(self.rails_mod)
        surf_mod.setPos(x_pos, y_pos, 0)
        surf_mod.setH(angle)

        self._surfs.append(surf_mod)

        if not side:
            return

        # load environment models asynchronous
        delay = 0
        for env_mod in self._env_mods[side]:
            taskMgr.doMethodLater(  # noqa: F821
                delay,
                self._load_env_model,
                "load_env_model",
                extraArgs=[surf_mod, env_mod],
            )
            delay += 0.0275

        # load railways model
        if self._railways_model:
            railways_mod = loader.loadModel(
                self._railways_model[0])  # noqa: F821
            railways_mod.reparentTo(self.rails_mod)

            railways_mod.setX(self._railways_model[1][0])
            railways_mod.setY(self._railways_model[1][1])
            railways_mod.setH(self._railways_model[2])

        if not base.world.sun.is_dark:  # noqa: F821
            # generate texture flowers
            taskMgr.doMethodLater(  # noqa: F821
                2.5,
                self._gen_flowers,
                "generate_flowers",
                extraArgs=[surf_mod, angle, side],
            )

        if invert:
            if self.name in ("r_fork", "r90_turn"):
                surf_mod.setH(surf_mod, 90)
            elif self.name in ("l_fork", "l90_turn"):
                surf_mod.setH(surf_mod, -90)

    def turn_around(self):
        """Turn the terrain of the block around."""
        l_surf, r_surf = self._surfs

        l_pos = l_surf.getPos()

        l_surf.setPos(r_surf.getPos())
        l_surf.setH(l_surf, 180)

        r_surf.setPos(l_pos)
        r_surf.setH(r_surf, 180)

    def _load_env_model(self, surf_mod, env_mod):
        """Helper to load a model asynchronous.

        Args:
            surf_mod (panda3d.core.NodePath): Surface model.
            env_mod (str): Name of the model to load and its position.
        """
        mod = loader.loadModel(address(env_mod[0]))  # noqa: F821
        if "grass" in env_mod[0]:
            mod.setTransparency(TransparencyAttrib.M_binary)
            mod.setShaderOff()

        mod.reparentTo(surf_mod)
        mod.setPos(env_mod[1])
        mod.setH(random.randint(1, 359))

    def _gen_flowers(self, surf_mod, angle, side):
        """Generate texture flowers.

        Args:
            surf_mod (panda3d.core.NodePath): Surface model.
            angle (int): Surface model angle.
            side (str): Surface model side.
        """
        for i in range(random.randint(0, 3)):
            ts = TextureStage("ts_flower{}".format(str(i)))
            ts.setMode(TextureStage.MDecal)

            tex = loader.loadTexture(  # noqa: F821
                "just_tex/flower{}.png".format(str(random.randint(1, 5))))
            tex.setWrapU(Texture.WMClamp)
            tex.setWrapV(Texture.WMClamp)

            surf_mod.setTexture(ts, tex)
            surf_mod.setTexPos(
                ts,
                random.randint(*FLOWER_RANGES[(angle, side)]["u"]),
                random.randint(*FLOWER_RANGES[(angle, side)]["v"]),
                0,
            )
            surf_mod.setTexScale(ts, 20, 20)

    def prepare(self, invert=False, from_branch=False):
        """Load models, which represents this block content.

        Args:
            invert (bool):
                True if the Train is moving in the direction
                opposite to the main railway line.
            from_branch (str): Branch direction indicator: "l" or "r".

        Returns:
            Block: Returns self object.
        """
        if self.name in ("l_fork", "r_fork") and from_branch:
            self._old_values = (self.name, self.path, self.cam_path)
            self.name, self.path, self.cam_path = (
                "exit_from_fork",
                (
                    base.world._paths["r90_turn"],  # noqa: F821
                    base.world._paths["l90_turn"],  # noqa: F821
                ) if self.branch == "r" else (
                    base.world._paths["l90_turn"],  # noqa: F821
                    base.world._paths["r90_turn"],  # noqa: F821
                ),
                (
                    base.world._paths["cam_r90_turn"],  # noqa: F821
                    base.world._paths["cam_l90_turn"],  # noqa: F821
                ) if self.branch == "r" else (
                    base.world._paths["cam_l90_turn"],  # noqa: F821
                    base.world._paths["cam_r90_turn"],  # noqa: F821
                ),
            )

        if invert:
            self._old_values = (self.name, self.path, self.cam_path)
            base.world.invert(self)  # noqa: F821

        self.rails_mod = loader.loadModel(  # noqa: F821
            address(self.name + "_rails" +
                    ("_rusty" if self.is_rusty else "")))

        self._load_surface_block(self._l_surface,
                                 -4,
                                 4,
                                 self._l_angle,
                                 "l",
                                 invert=invert)
        self._load_surface_block(self._r_surface,
                                 4,
                                 4,
                                 self._r_angle,
                                 "r",
                                 invert=invert)

        if self.name == "l90_turn" or (self.name == "exit_from_fork"
                                       and self.branch == "l" and
                                       base.train.do_turn == 0  # noqa: F821
                                       ):
            self._load_surface_block(self._r_surface, -4, 12, self._l_angle)
            self._load_surface_block(self._r_surface, 4, 12, self._l_angle)

        elif self.name == "r90_turn" or (self.name == "exit_from_fork"
                                         and self.branch == "r" and
                                         base.train.do_turn == 0  # noqa: F821
                                         ):
            self._load_surface_block(self._l_surface, 4, 12, self._r_angle)
            self._load_surface_block(self._l_surface, -4, 12, self._r_angle)

        if self._add_surface:
            self.load_additional_surface()
            self._add_surface = False

        if self.id == 0:
            surf_mod = loader.loadModel(address("surface1"))  # noqa: F821
            surf_mod.reparentTo(self.rails_mod)
            surf_mod.setPos(-4, -4, 0)

            surf_mod = loader.loadModel(address("surface1"))  # noqa: F821
            surf_mod.reparentTo(self.rails_mod)
            surf_mod.setPos(4, -4, 0)

            rails_mod = loader.loadModel(address("direct_rails"))  # noqa: F821
            rails_mod.reparentTo(self.rails_mod)
            rails_mod.setPos(0, -8, 0)

        if chance(5):
            mist = loader.loadModel(address("mist"))  # noqa: F821
            mist.reparentTo(self.rails_mod)
            mist.setPos(random.randint(-3, 3), 0, 0.07)
            mist.setBin("transparent", 30)
            LerpPosHprScaleInterval(mist, 70, (0, -5, 0), 0,
                                    (1.3, 1.1, 1.3)).start()

        if base.world.sun.day_part == "night" and chance(70):  # noqa: F821
            self._fireflies = ParticleEffect()
            self._fireflies.loadConfig("effects/fireflies.ptf")

            if chance(50):
                self._fireflies.setPos(random.uniform(-0.15, -1), 0, 0.2)
            else:
                self._fireflies.setPos(random.uniform(0.15, 1), 0, 0.2)

            self._fireflies.start(self.rails_mod, render)  # noqa: F821

        if chance(10):
            light_rays = loader.loadModel(address("light_rays"))  # noqa: F821
            light_rays.reparentTo(self.rails_mod)
            light_rays.setPos(random.uniform(-1, 1), 0, 0.2)
            light_rays.setBillboardPointWorld()
            light_rays.setDepthWrite(False)

        return self

    def load_additional_surface(self):
        """Load the additional surface models for this block."""
        # the rails model isn't prepared yet - delay the additional
        # surfaces loading until the rails model loading
        if self.rails_mod is None:
            self._add_surface = True
            return

        if self.name == "l_fork" or (self.name == "exit_from_fork"
                                     and self.branch == "r"):
            self._load_surface_block(self._r_surface, -4, 12, self._l_angle)
            self._load_surface_block(self._r_surface, 4, 12, self._l_angle)

        elif self.name == "r_fork" or (self.name == "exit_from_fork"
                                       and self.branch == "l"):
            self._load_surface_block(self._l_surface, 4, 12, self._r_angle)
            self._load_surface_block(self._l_surface, -4, 12, self._r_angle)

    def prepare_physical_objects(self):
        """Prepare physical objects on this block.

        This method must be called only after reparenting
        the main rails_mod node of the block. Otherwise
        all the children physical nodes will be positioned
        relative to the game render.
        """
        if (self.enemy_territory
                and base.world.enemy.score >= BARRIER_THRESHOLD  # noqa: F821
                and chance(2)):
            self._phys_objs.append(Barrier(self))

        if (self.enemy_territory
                and base.world.enemy.score >= ROCKET_THRESHOLD  # noqa: F821
                and chance(2)):
            Rocket()

    def description(self):
        """Build block description.

        Used to save the game world.

        Returns:
            dict: Block description.
        """
        desc = {
            "name": self.name,
            "id": self.id,
            "branch": self.branch,
            "directions": self.directions,
            "outing_available": self.outing_available,
            "is_city": self.is_city,
            "is_rusty": self.is_rusty,
            "is_stenchy": self.is_stenchy,
            "station_side": self._station_side,
            "l_surface": self._l_surface,
            "r_surface": self._r_surface,
            "l_angle": self._l_angle,
            "r_angle": self._r_angle,
            "env_mods": self._env_mods,
            "railways_model": self._railways_model,
            "is_station": self.is_station,
        }
        return desc

    def clear(self):
        """Clear this block and revert its inversion."""
        if self._old_values:
            self.name, self.path, self.cam_path = self._old_values
            self._old_values = None

        for obj in self._phys_objs:
            obj.clear()

        self._surfs.clear()
        self.rails_mod.removeNode()
        self.rails_mod = None

        if self._fireflies is not None:
            self._fireflies.disable()
            self._fireflies = None
Exemplo n.º 7
0
class World(DirectObject):
    def freezeGame():
        # Pause all of the AI, stop model animations, cease taking inputs, except for reset
        return 0
        
    def resetGame(self):
        # Set everything back to its starting position and remove the game over message
        self.caught.destroy()
        self.pieDisplay.destroy()
        self.pieCount = 0
        self.pieDisplay = grabPie(self.pieCount)
        self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0, "run":0, "reset":0}
        eveStartPos = self.environ.find("**/start_point").getPos()
        self.gameOver = 0
        self.eve.setPos(eveStartPos)
        self.eateve.setPos(eveStartPos)
        self.pie.setPos(Vec3(-50, -30, 10))
        self.rand.setPos(Vec3(-70, -5, eveStartPos.getZ() + 5))
        self.rand2.setPos(Vec3(-70, -5, eveStartPos.getZ() + 10))
        
        # Blue Dragon
        self.character3.loop('win')
        self.character3.setPos(-114,11,1.9)
        self.blueDragonSound.play()
        
        # Red Dragon
        self.character2.loop('win')
        self.character2.setPos(-108,11,.3)
        self.redDragonStartPos = self.character2.getPos()
        self.redDragonCollideCount = 0
        self.redDragonSound.play()
        
        # Green Dragon
        self.character.loop('win')
        self.character.setPos(-118,21,0)
        self.greenDragonSound.play()
        self.dragonStartPos = self.character.getPos()
        self.dragonCollideCount = 0
        self.AIbehaviors.pursue(self.eateve, 1)
        
        self.AIbehaviorsRand.wander(10,0,47,.5)
        
        self.AIbehaviorsRand2.wander(10,0,47,.5)

        self.AIbehaviors3.pursue(self.rand, 1)
        
        self.redDragonChasingEve = 0
        self.AIbehaviors2.pursue(self.rand2, 1)
        
        self.isMoving = False
        self.isRunning = False
        self.isWalking = False
        
        base.camera.setPos(self.eve.getX(),self.eve.getY()+10,2)
        self.fixPieZ()
        return 0
    
    
    def __init__(self):
        # Sound
        
        self.collectSoundEffect = loader.loadMusic("sounds/item_collect.mp3")
        
        self.footstepSound = loader.loadMusic("sounds/footsteps.mp3")
        self.footstepSound.setLoop(1);
        
        audio3d = Audio3DManager.Audio3DManager(base.sfxManagerList[0], base.camera)
        
        self.musicend = loader.loadMusic("sounds/Enchanted-Woods.mp3")
    
        # Sky Box
        starTexture = loader.loadTexture("models/stars.jpg")
        self.sky = loader.loadModel("models/box.egg")
        self.sky.setScale(300)
        self.sky.setPos(-200,-150,0)
        self.sky.setBin('background', 0)
        self.sky.setDepthWrite(0)
        self.sky.setTwoSided(True)
        self.sky.setTexture(starTexture, 1)
        
        self.sky.reparentTo(render)
        self.sky.set_compass()
    
        # allow transparency
        render.setTransparency(TransparencyAttrib.MAlpha)

        self.pieCount = 0
        self.pieDisplay = grabPie(self.pieCount)
        self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0, "run":0, "reset":0}
        base.win.setClearColor(Vec4(0,0,0,1))
        self.environ = loader.loadModel("models/world")      
        self.environ.reparentTo(render)
        self.environ.setPos(0,0,0)
        
        # Create the main character
        eveStartPos = self.environ.find("**/start_point").getPos()
        self.eve = Actor("models/eve",
                                 {"run":"models/eve_run",
                                  "walk":"models/eve_walk"})
        print(eveStartPos)
        self.gameOver = 0
        self.eve.reparentTo(render)
        self.eve.setScale(.2)
        #self.eve.setShear(.5, .5, .5)
        self.eve.setPos(eveStartPos)

        self.eateve = Actor("models/eve")
        self.eateve.reparentTo(render)
        self.eateve.setScale(.2)
        self.eateve.setPos(eveStartPos)
        self.eateve.hide()
        
        self.pie = loader.loadModel("models/fruit-pie-slice")
        self.pie.reparentTo(render)
        self.pie.setScale(.5)
        self.pie.setPos(Vec3(-50, -30, 10))
        #self.pie.setP(20)
        
        self.rand = Actor("models/eve")
        self.rand.reparentTo(render)
        self.rand.setScale(.2)
        self.rand.setPos(Vec3(-70, -5, eveStartPos.getZ() + 5))
        self.rand.hide()       
         
        self.rand2 = Actor("models/eve")
        self.rand2.reparentTo(render)
        self.rand2.setScale(.2)
        self.rand2.setPos(Vec3(-70, -5, eveStartPos.getZ() + 10))
        self.rand2.hide()
        # print(eveStartPos)
        
        # Blue Dragon
        self.character3=Actor('models/nik-dragon')
        #self.character3.loadModel('models/nik-dragon')
        self.character3.reparentTo(render)
        self.character3.loadAnims({'win': 'models/nik-dragon'})
        self.character3.loop('win')
        self.character3.setPlayRate(.5,'win')
        self.character3.setScale(.23)
        self.character3.setTransparency(1)
        #self.character3.setColorScale(0.4,0.2,.4,.7)
        self.character3.setColorScale(9,9,9,.3)
        self.character3.setPos(-114,11,1.9)
        
        self.blueDragonSound = audio3d.loadSfx("sounds/Snoring Giant.mp3")
        audio3d.attachSoundToObject(self.blueDragonSound, self.character3)
        self.blueDragonSound.setLoop(True)
        self.blueDragonSound.play()
        
        # Red Dragon
        self.character2=Actor()
        self.character2.loadModel('models/nik-dragon')
        self.character2.reparentTo(render)
        self.character2.loadAnims({'win': 'models/nik-dragon'})
        self.character2.loop('win')
        self.character2.setPlayRate(1.5,'win')
        self.character2.setScale(.06)
        self.character2.setColorScale(6,0.2,0.2,50)
        self.character2.setPos(-108,11,.3)

        self.redDragonStartPos = self.character2.getPos()
        self.redDragonCollideCount = 0
        
        self.redDragonSound = audio3d.loadSfx("sounds/Velociraptor Call.mp3")
        audio3d.attachSoundToObject(self.redDragonSound, self.character3)
        self.redDragonSound.setLoop(True)
        self.redDragonSound.play()
        
        # Green Dragon
        self.character=Actor()
        self.character.loadModel('models/nik-dragon')
        self.character.reparentTo(render)
        self.character.loadAnims({'win': 'models/nik-dragon'})
        self.character.loop('win')
        self.character.setScale(.1)
        self.character.setPos(-118,21,0)
        
        self.greenDragonSound = audio3d.loadSfx("sounds/Raptor Call.mp3")
        audio3d.attachSoundToObject(self.greenDragonSound, self.character3)
        self.greenDragonSound.setLoop(True)
        self.greenDragonSound.play()
        
        self.dragonStartPos = self.character.getPos()
        self.dragonCollideCount = 0
        self.AIworld = AIWorld(render)
        #self.AIworld.addObstacle(self.environ)
        
        self.dragonAI = AICharacter("character", self.character, 100, 0.05, 5)
        self.AIworld.addAiChar(self.dragonAI)
        self.AIbehaviors = self.dragonAI.getAiBehaviors()
        #self.AIbehaviors.seek(self.character2)
        #self.AIbehaviors.wander(2, 0, 5, .5)
        self.AIbehaviors.pursue(self.eateve, 1)
        #self.AIbehaviors.wander(5,0,10,.5)
        #self.AIbehaviors.evade(self.character3, 10, 20, 300)
        #self.AIbehaviors.seek(self.eve, .5)
        #self.AIbehaviors.obstacleAvoidance(1)
        
        self.randomChase = AICharacter("rand", self.rand, 50, 20, 20)
        self.AIworld.addAiChar(self.randomChase)
        self.AIbehaviorsRand = self.randomChase.getAiBehaviors()
        self.AIbehaviorsRand.wander(10,0,47,.5)
        
        self.randomChase2 = AICharacter("rand2", self.rand2, 50, 20, 20)
        self.AIworld.addAiChar(self.randomChase2)
        self.AIbehaviorsRand2 = self.randomChase2.getAiBehaviors()
        self.AIbehaviorsRand2.wander(10,0,47,.5)

        self.ghostDragonAI = AICharacter("character3", self.character3, 250, .05, 5)
        self.AIworld.addAiChar(self.ghostDragonAI)
        self.AIbehaviors3 = self.ghostDragonAI.getAiBehaviors()
        self.AIbehaviors3.pursue(self.rand, 1)
        #self.AIbehaviors3.wander(5,0,10,.5)
        
        self.redDragonChasingEve = 0
        self.redDragonAI = AICharacter("character2", self.character2, 100, .05, 7)
        self.AIworld.addAiChar(self.redDragonAI)
        self.AIbehaviors2 = self.redDragonAI.getAiBehaviors()
        self.AIbehaviors2.pursue(self.rand2, 1)
        
        taskMgr.add(self.AIUpdate, "AIUpdate")

    
        # Create a floater object to use for camera management
        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(render)
        
        # Enable Particles
        base.enableParticles()

        # Accept the control keys for movement and rotation
        self.accept("escape", sys.exit)
        self.accept("arrow_left", self.setKey, ["left",1])
        self.accept("arrow_right", self.setKey, ["right",1])
        self.accept("arrow_up", self.setKey, ["forward",1])
        self.accept("space", self.setKey, ["run",1])
        self.accept("a", self.setKey, ["cam-left",1])
        self.accept("s", self.setKey, ["cam-right",1])
        self.accept("r", self.setKey, ["reset",1])
        self.accept("arrow_left-up", self.setKey, ["left",0])
        self.accept("arrow_right-up", self.setKey, ["right",0])
        self.accept("arrow_up-up", self.setKey, ["forward",0])
        self.accept("space-up", self.setKey, ["run",0])
        self.accept("a-up", self.setKey, ["cam-left",0])
        self.accept("s-up", self.setKey, ["cam-right",0])
        self.accept("r-up", self.setKey, ["reset",0])

        taskMgr.add(self.move,"moveTask")

        # Game state variables
        self.isMoving = False
        self.isRunning = False
        self.isWalking = False

        # Set up the camera
        base.disableMouse()
        base.camera.setPos(self.eve.getX(),self.eve.getY()+10,2)
        
        # Collision detection for eve against the ground and against objects
        # We will detect the height of the terrain by creating a collision
        # ray and casting it downward toward the terrain.  One ray will
        # start above eve's head, and the other will start above the camera.
        # A ray may hit the terrain, or it may hit a rock or a tree.  If it
        # hits the terrain, we can detect the height.  If it hits anything
        # else, we rule that the move is illegal.
        self.cTrav = CollisionTraverser()

        self.eveGroundRay = CollisionRay()
        self.eveGroundRay.setOrigin(0,0,4.5)
        self.eveGroundRay.setDirection(0,0,-1)
        self.eveGroundCol = CollisionNode('eveRay')
        self.eveGroundCol.addSolid(self.eveGroundRay)
        self.eveGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.eveGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.eveGroundColNp = self.eve.attachNewNode(self.eveGroundCol)
        self.eveGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.eveGroundColNp, self.eveGroundHandler)

        self.dragonGroundRay = CollisionRay()
        self.dragonGroundRay.setOrigin(0,0,10)
        self.dragonGroundRay.setDirection(0,0,-1)
        self.dragonGroundCol = CollisionNode('dragonRay')
        self.dragonGroundCol.addSolid(self.dragonGroundRay)
        self.dragonGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.dragonGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.dragonGroundColNp = self.character.attachNewNode(self.dragonGroundCol)
        self.dragonGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.dragonGroundColNp, self.dragonGroundHandler)

        self.ghostDragonGroundRay = CollisionRay()
        self.ghostDragonGroundRay.setOrigin(0,0,25)
        self.ghostDragonGroundRay.setDirection(0,0,-1)
        self.ghostDragonGroundCol = CollisionNode('ghostDragonRay')
        self.ghostDragonGroundCol.addSolid(self.ghostDragonGroundRay)
        self.ghostDragonGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.ghostDragonGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.ghostDragonGroundColNp = self.character3.attachNewNode(self.ghostDragonGroundCol)
        self.ghostDragonGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.ghostDragonGroundColNp, self.ghostDragonGroundHandler)

        self.redDragonGroundRay = CollisionRay()
        self.redDragonGroundRay.setOrigin(0,0,5)
        self.redDragonGroundRay.setDirection(0,0,-1)
        self.redDragonGroundCol = CollisionNode('redDragonRay')
        self.redDragonGroundCol.addSolid(self.redDragonGroundRay)
        self.redDragonGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.redDragonGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.redDragonGroundColNp = self.character2.attachNewNode(self.ghostDragonGroundCol)
        self.redDragonGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.redDragonGroundColNp, self.redDragonGroundHandler)
        
        self.pieRay = CollisionRay()
        self.pieRay.setOrigin(0,0,10)
        self.pieRay.setDirection(0,0,-1)
        self.pieCol = CollisionNode('pieRay')
        self.pieCol.addSolid(self.pieRay)
        self.pieCol.setFromCollideMask(BitMask32.bit(0))
        self.pieCol.setIntoCollideMask(BitMask32.allOff())
        self.pieColNp = self.pie.attachNewNode(self.pieCol)
        self.pieHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.pieColNp, self.pieHandler)
        
        self.camGroundRay = CollisionRay()
        self.camGroundRay.setOrigin(0,0,1000)
        self.camGroundRay.setDirection(0,0,-1)
        self.camGroundCol = CollisionNode('camRay')
        self.camGroundCol.addSolid(self.camGroundRay)
        self.camGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.camGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol)
        self.camGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)

        # Shows collision rays
        #self.eveGroundColNp.show()
        #self.camGroundColNp.show()
       
        # Shows collisions
        #self.cTrav.showCollisions(render)
        
        self.fixPieZ()
        
        # Create some lighting
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor(Vec4(.3, .3, .3, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection(Vec3(-5, -5, -5))
        directionalLight.setColor(Vec4(1, 1, 1, 1))
        directionalLight.setSpecularColor(Vec4(1, 1, 1, 1))
        #directionalLight.setShadowCaster(True, 512, 512)
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))
        #render.setShaderAuto()
    
    # Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value
    
    def AIUpdate(self, task):
        self.AIworld.update()
        return task.cont
    
    def fixPieZ(self):
        self.cTrav.traverse(render)
        entries = []
        for i in range(self.pieHandler.getNumEntries()):
            entry = self.pieHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            self.pie.setZ(entries[0].getSurfacePoint(render).getZ() + .5)
            return False
        else:
            return True
    
    # Accepts arrow keys to move either the player or the menu cursor,
    # Also deals with grid checking and collision detection
    def move(self, task):
        if (self.gameOver != 1):
            if math.sqrt((self.eve.getX() - self.pie.getX())**2 + (self.eve.getY() - self.pie.getY())**2) < .6:
                # particle effect
                self.p = ParticleEffect()
                self.p.loadConfig("models/sparkleparticlerenderer.ptf")
                
                self.copyPie = self.pie.copyTo(render)
                self.copyPie.setColor(0.0, 0.0, 0.0, 0.0)
                
                self.p.start(parent = self.copyPie, renderParent = render)
                taskMgr.add(self.timedParticle, "timedParticle")
                
                # play collect sounds
                self.collectSoundEffect.play()
                
                # collect pie
                try:
                    self.pie.setPos(Vec3(random.randrange(-120,-19), random.randrange(-60,51), 10))
                    while self.fixPieZ():
                        self.pie.setPos(Vec3(random.randrange(-120,-19), random.randrange(-60,51), 10))
                except Exception as ex:
                    print ex
                    raw_input()
                self.pieDisplay.clearText()
                self.pieCount = self.pieCount + 1
                self.pieDisplay = grabPie(self.pieCount)
                
                
            if math.sqrt((self.eve.getX() - self.character.getX())**2 + (self.eve.getY() - self.character.getY())**2) < 1 and self.gameOver == 0:
                self.caught = displayGameOver()
                self.gameOver = 1
    
            if math.sqrt((self.eve.getX() - self.character2.getX())**2 + (self.eve.getY() - self.character2.getY())**2) < 1 and self.gameOver == 0:
                self.caught = displayGameOver()
                self.gameOver = 1
                
            if math.sqrt((self.eve.getX() - self.character3.getX())**2 + (self.eve.getY() - self.character3.getY())**2) < 1.3 and self.gameOver == 0:
                self.caught = displayGameOver()
                self.gameOver = 1
    
            if math.sqrt((self.eve.getX() - self.character2.getX())**2 + (self.eve.getY() - self.character2.getY())**2) < 12.5 and self.redDragonCollideCount == 0 and self.redDragonChasingEve == 0:
                self.redDragonChasingEve = 1
                self.AIbehaviors2.removeAi("pursue")
                self.AIbehaviors2.pauseAi("seek")
                self.AIbehaviors2.pursue(self.eve, 1)
                
            # If the camera-left key is pressed, move camera left.
            # If the camera-right key is pressed, move camera right.
            base.camera.lookAt(self.eve)
            if (self.keyMap["cam-left"]!=0):
                base.camera.setX(base.camera, -20 * globalClock.getDt())
            if (self.keyMap["cam-right"]!=0):
                base.camera.setX(base.camera, +20 * globalClock.getDt())
    
            self.pie.setH(self.pie.getH() + 100 * globalClock.getDt())
    
            # save eve's initial position so that we can restore it,
            # in case she falls off the map or runs into something.
            startpos = self.eve.getPos()
            # If a move-key is pressed, move eve in the specified direction.
            if (self.keyMap["left"]!=0):
                self.eve.setH(self.eve.getH() + 300 * globalClock.getDt())
            if (self.keyMap["right"]!=0):
                self.eve.setH(self.eve.getH() - 300 * globalClock.getDt())
            if (self.keyMap["forward"]!=0):
                if (self.keyMap["run"] != 0):
                    self.eve.setY(self.eve, -30 * globalClock.getDt())
                else:
                    self.eve.setY(self.eve, -10 * globalClock.getDt())
                
            # If eve is moving, loop the run animation.
            # If she is standing still, stop the animation.
            if (self.keyMap["forward"]!=0) or (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0):
                if self.isMoving is False:
                    if (self.keyMap["run"] != 0):
                        self.eve.loop("run")
                        self.isMoving = True
                        self.isRunning = True
                        self.isWalking = False
                        self.footstepSound.setPlayRate(1.3)
                        self.footstepSound.play()
    
                    else:
                        self.eve.loop("walk")
                        self.eve.setPlayRate(2.0, "walk")
                        self.isMoving = True
                        self.isWalking = True
                        self.isRunning = False
                        self.footstepSound.setPlayRate(1.0)
                        self.footstepSound.play()
                else:
                    if (self.keyMap["run"] != 0 and self.isWalking):
                        self.eve.loop("run" )
                        self.isRunning = True
                        self.isWalking = False
                        self.footstepSound.setPlayRate(1.3)
    
                    elif (self.keyMap["run"] == 0 and self.isRunning):
                        self.eve.loop("walk")
                        self.eve.setPlayRate(2.0, "walk")
                        self.isWalking = True
                        self.isRunning = False
                        self.footstepSound.setPlayRate(1.0)
                        
            else:
                if self.isMoving:
                    self.eve.stop()
                    self.eve.pose("walk",10)
                    self.isMoving = False
                    self.footstepSound.stop()
    
            # If the camera is too far from eve, move it closer.
            # If the camera is too close to eve, move it farther.
            camvec = self.eve.getPos() - base.camera.getPos()
            camvec.setZ(0)
            camdist = camvec.length()
            camvec.normalize()
            if (camdist > 10.0):
                base.camera.setPos(base.camera.getPos() + camvec*(camdist-10))
                camdist = 10.0
            if (camdist < 5.0):
                base.camera.setPos(base.camera.getPos() - camvec*(5-camdist))
                camdist = 5.0
    
            # Now check for collisions.
            self.cTrav.traverse(render)
    
            # Adjust eve's Z coordinate. If eve's ray hit terrain,s
            # update her Z. If it hit anything else, or didn't hit anything, put
            # her back where she was last frame.
            entries = []
            for i in range(self.eveGroundHandler.getNumEntries()):
                entry = self.eveGroundHandler.getEntry(i)
                entries.append(entry)
            entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                        x.getSurfacePoint(render).getZ()))
            if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
                self.eve.setZ(entries[0].getSurfacePoint(render).getZ())
            else:
                self.eve.setPos(startpos)
                
                
    
            
            # Adjust the dragon's Z coordinate like with eve. Additionally, if
            # the dragon has hit an object, have it seek a location behind it
            # temporarily.
            if self.dragonCollideCount == 0:
                self.AIbehaviors.resumeAi("pursue")
                self.AIbehaviors.pauseAi("seek")
            else:
                self.dragonCollideCount = self.dragonCollideCount - 1
            
            entries = []
            for i in range(self.dragonGroundHandler.getNumEntries()):
                entry = self.dragonGroundHandler.getEntry(i)
                entries.append(entry)
            entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                        x.getSurfacePoint(render).getZ()))
            if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
                self.character.setZ(entries[0].getSurfacePoint(render).getZ() + 1)
            elif (self.dragonCollideCount == 0):
                try:
                    self.AIbehaviors.pauseAi("pursue")
                except Exception as ex:
                    print ex
                    raw_input()
                self.AIbehaviors.seek(Vec3(self.character.getX() + 2000*(-self.character.getX() + self.dragonStartPos.getX()), self.character.getY() + 2000*(-self.character.getY() + self.dragonStartPos.getY()), self.character.getZ() + 2000*(-self.character.getZ() + self.dragonStartPos.getZ())), 20000)
                #self.AIbehaviors.seek(self.character3)
                self.dragonCollideCount = 100
                #self.AIbehaviors.flee(self.character.getPos(), 1, 10, 10000)
                #self.character.setPos(dragonStartPos)
            else:
                #do nothing
                self.dragonCollideCount = self.dragonCollideCount
            
            if self.redDragonCollideCount == 0 and self.redDragonChasingEve == 0:
                self.AIbehaviors2.pursue(self.rand2, 1)
                self.AIbehaviors2.pauseAi("seek")
            elif self.redDragonChasingEve == 0:
                self.redDragonCollideCount = self.redDragonCollideCount - 1
            
            # Red dragon z correcting and collision detecting
            entries = []
            for i in range(self.redDragonGroundHandler.getNumEntries()):
                entry = self.redDragonGroundHandler.getEntry(i)
                entries.append(entry)
            entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                        x.getSurfacePoint(render).getZ()))
            if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
                self.character2.setZ(entries[0].getSurfacePoint(render).getZ() + .6)
            elif (self.redDragonCollideCount == 0):
                try:
                    self.AIbehaviors2.removeAi("pursue")
                except Exception as ex:
                    print ex
                    raw_input()
                self.redDragonChasingEve = 0
                self.AIbehaviors2.seek(Vec3(self.character2.getX() + 2000*(-self.character2.getX() + self.redDragonStartPos.getX()), self.character2.getY() + 2000*(-self.character2.getY() + self.redDragonStartPos.getY()), self.character2.getZ() + 2000*(-self.character2.getZ() + self.redDragonStartPos.getZ())), 20000)
                #self.AIbehaviors.seek(self.character3)
                self.redDragonCollideCount = 100
                #self.AIbehaviors.flee(self.character.getPos(), 1, 10, 10000)
                #self.character.setPos(dragonStartPos)
            else:
                #do nothing
                self.redDragonCollideCount = self.redDragonCollideCount
            
            # Adjust the ghost dragon's Z coordinate like with eve.
            # Additionally, if the ghost dragon has hit an object, have it
            # seek a location behind it temporarily.
            #if self.ghostDragonCollideCount == 0:
            #    self.AIbehaviors.resumeAi("wander")
            #    self.AIbehaviors3.pauseAi("seek")
            #else:
            #    self.ghostDragonCollideCount = self.dragonCollideCount - 1
            
            entries = []
            for i in range(self.ghostDragonGroundHandler.getNumEntries()):
                entry = self.ghostDragonGroundHandler.getEntry(i)
                entries.append(entry)
            entries.sort(lambda x,y: ghostDragonCmp(x,y))
            
            if (len(entries)>0):
                self.character3.setZ(entries[0].getSurfacePoint(render).getZ() + 2.5)
            #elif (self.ghostDragonCollideCount == 0):
            #    self.AIbehaviors3.pauseAi("wander")
            #    self.AIbehaviors3.seek(Vec3(self.character.getX() + 2000*(-self.character.getX() + self.dragonStartPos.getX()), self.character.getY() + 2000*(-self.character.getY() + self.dragonStartPos.getY()), self.character.getZ() + 2000*(-self.character.getZ() + self.dragonStartPos.getZ())), 20000)
                #self.AIbehaviors.seek(self.character3)
            #    self.ghostDragonCollideCount = 100
                #self.AIbehaviors.flee(self.character.getPos(), 1, 10, 10000)
                #self.character.setPos(dragonStartPos)
            #else:
                #do nothing
            #   self.ghostDragonCollideCount = self.ghostDragonCollideCount
                
            # Keep the camera at one foot above the terrain,
            # or two feet above eve, whichever is greater.
            entries = []
            for i in range(self.camGroundHandler.getNumEntries()):
                entry = self.camGroundHandler.getEntry(i)
                entries.append(entry)
            entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                        x.getSurfacePoint(render).getZ()))
            if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
                base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+1.0)
            if (base.camera.getZ() < self.eve.getZ() + 2.0):
                base.camera.setZ(self.eve.getZ() + 2.0)
                
            # The camera should look in eve's direction,
            # but it should also try to stay horizontal, so look at
            # a floater which hovers above eve's head.
            self.floater.setPos(self.eve.getPos())
            self.floater.setZ(self.eve.getZ() + 2.0)
            base.camera.lookAt(self.floater)
    
    
            self.eateve.setPos(self.eve.getX(), self.eve.getY(), self.eve.getZ() + 1)
            self.dragonStartPos = self.character.getPos()
            self.redDragonStartPos = self.character2.getPos()
            return task.cont
        else:
            self.eve.stop()
            self.isMoving = False
            self.footstepSound.stop()
            self.character.stop()
            self.AIbehaviors.pauseAi("wander")
            self.AIbehaviors.pauseAi("seek")
            self.AIbehaviors.pauseAi("pursue")
            self.character2.stop()
            self.AIbehaviors2.pauseAi("wander")
            self.AIbehaviors2.pauseAi("seek")
            self.AIbehaviors2.pauseAi("pursue")
            self.character3.stop()
            self.AIbehaviors3.pauseAi("wander")
            self.AIbehaviors3.pauseAi("seek")
            self.AIbehaviors3.pauseAi("pursue")
            self.greenDragonSound.stop()
            self.redDragonSound.stop()
            self.blueDragonSound.stop()
            if self.musicend.status() != self.musicend.PLAYING:
                self.musicend.setLoop(1)
                self.musicend.play()
            if (self.keyMap["reset"] == 1):
                self.gameOver = 0
                self.musicend.stop()
                self.resetGame()
                # Fill in all of the things
            return task.cont
            
    def timedParticle(self, task):
        if task.time < 1.0:
            return task.cont
        
        self.p.disable()
        self.copyPie.removeNode()
        return task.done