Exemple #1
0
class SkyDome1(Att_base):
    def __init__(self, scene, dynamic=True, rate=(0.005,0.05),
        texturescale=(1000,1000),
        scale=(40,40,10), texturefile=None):
        Att_base.__init__(self,False, "Sky Dome 1")
        self.skybox = loader.loadModel("../media/models/dome2")
        self.skybox.setCollideMask(BitMask32().allOff())
        self.skybox.setTwoSided(False)
        self.skybox.setScale(scale[0],scale[1],scale[2])
        self.skybox.setLightOff()
        if texturefile == None:
            texturefile = "../media/textures/concrete.jpg"
        texture = loader.loadTexture(texturefile)
        self.textureStage0 = TextureStage("stage0")
        self.textureStage0.setMode(TextureStage.MReplace)
        self.skybox.setTexture(self.textureStage0,texture,1)
        self.skybox.setTexScale(self.textureStage0, texturescale[0], texturescale[1])

        self.skybox.reparentTo(scene)

    def setTextureScale(self, texturescale):
        self.skybox.setTexScale(self.textureStage0, texturescale[0], texturescale[1])

    def Destroy(self):
        self.skybox.removeNode()

    def setPos(self, v):
        self.skybox.setPos(v)

    def show(self):
        self.skybox.show()

    def hide(self):
        self.skybox.hide()
class DetailTexturer(TerrainTexturer):
    """adds a texture + detail texture to TerrainTiles"""

    def load(self):
        self.ts1 = TextureStage('ts2')
        tex = self.loadTexture("snow.jpg")
        tex.setWrapU(Texture.WMMirror)
        tex.setWrapV(Texture.WMMirror)
        self.monoTexture = tex

        self.loadDetail()

    def loadDetail(self):
        self.detailTS = TextureStage('ts')
        tex = self.loadTexture("Detail_COLOR.jpg")
        tex.setWrapU(Texture.WMMirror)
        tex.setWrapV(Texture.WMMirror)
        self.detailTexture = tex
        self.textureBlendMode = self.detailTS.MHeight
        self.detailTS.setMode(self.textureBlendMode)

    def apply(self, input):
        """Apply textures and shaders to the input."""

        input.setTexture(self.ts1, self.monoTexture)
        input.setTexScale(self.ts1, 5, 5)

        input.setTexture(self.detailTS, self.detailTexture)
        input.setTexScale(self.detailTS, 120, 120)


    def setDetailBlendMode(self, num):
        """Set the blending mode of the detail texture."""

        if (not self.detailTexture):
            return
        self.textureBlendMode = num
        #for pos, tile in self.tiles.items():
        #    if tile.detailTS:
        #        tile.detailTS.setMode(self.textureBlendMode)

        self.detailTS.setMode(self.textureBlendMode)

    def incrementDetailBlendMode(self):
        """Set the blending mode of the detail texture."""

        if (not self.detailTexture):
            return
        self.textureBlendMode += 1
        self.setDetailBlendMode(self.textureBlendMode)

    def decrementDetailBlendMode(self):
        """Set the blending mode of the detail texture."""

        if (not self.detailTexture):
            return
        self.textureBlendMode -= 1
        self.setDetailBlendMode(self.textureBlendMode)
class DetailTexturer(TerrainTexturer):
    """adds a texture + detail texture to TerrainTiles"""
    def load(self):
        self.ts1 = TextureStage('ts2')
        tex = self.loadTexture("snow.jpg")
        tex.setWrapU(Texture.WMMirror)
        tex.setWrapV(Texture.WMMirror)
        self.monoTexture = tex

        self.loadDetail()

    def loadDetail(self):
        self.detailTS = TextureStage('ts')
        tex = self.loadTexture("Detail_COLOR.jpg")
        tex.setWrapU(Texture.WMMirror)
        tex.setWrapV(Texture.WMMirror)
        self.detailTexture = tex
        self.textureBlendMode = self.detailTS.MHeight
        self.detailTS.setMode(self.textureBlendMode)

    def apply(self, input):
        """Apply textures and shaders to the input."""

        input.setTexture(self.ts1, self.monoTexture)
        input.setTexScale(self.ts1, 5, 5)

        input.setTexture(self.detailTS, self.detailTexture)
        input.setTexScale(self.detailTS, 120, 120)

    def setDetailBlendMode(self, num):
        """Set the blending mode of the detail texture."""

        if (not self.detailTexture):
            return
        self.textureBlendMode = num
        #for pos, tile in self.tiles.items():
        #    if tile.detailTS:
        #        tile.detailTS.setMode(self.textureBlendMode)

        self.detailTS.setMode(self.textureBlendMode)

    def incrementDetailBlendMode(self):
        """Set the blending mode of the detail texture."""

        if (not self.detailTexture):
            return
        self.textureBlendMode += 1
        self.setDetailBlendMode(self.textureBlendMode)

    def decrementDetailBlendMode(self):
        """Set the blending mode of the detail texture."""

        if (not self.detailTexture):
            return
        self.textureBlendMode -= 1
        self.setDetailBlendMode(self.textureBlendMode)
Exemple #4
0
 def UpdateTexture(self):
     if(not self.model):
         self.LoadContent()
         
     (u, v) = BlockGeometryGenerator.BlockIdToUV(self.currentBlockIdToPlace + 1) # Add 1 to offset from Air Id = 0
     ts = TextureStage('ts')
     ts.setMode(TextureStage.MReplace)
     self.model.clearTexture()
     self.model.setTexture(ts, self.blockTexture)
     self.model.setTexOffset(ts, u[0], v[0])
     self.model.setTexScale(ts, 0.0625, 0.0625)
Exemple #5
0
    def SetGeomTexture(geom, geomId, node, blockTexture):
        """ Applies the texture to the visible geometry of the Chunk."""
        ts = TextureStage('ts')
        ts.setMode(TextureStage.MDecal)
        ts.setTexcoordName('light')

        # Setup the block texture
        attrib = TextureAttrib.make(blockTexture)
        
        # Add the light overlay
        #attrib = attrib.addOnStage(ts, geom['lighttexture'])
        
        # Apply the texture to the node
        node.setGeomState(geomId, 
                               node.getGeomState(geomId).addAttrib(attrib))
    def Texture(self):
        """Applies textures and if needed shaders to the terrain.
    Call this initially, and whenever you have changed the size of some important textures,
    or added/removed some textures or changed the lighting mode.
    This function is automatically called by Initialize()."""
        if self.TextureMap == "": self.TextureMap = None
        if self.LightMap == "": self.LightMap = None

        # Does it have a detail map?
        if len(self.AlphaMaps) > 0:
            self._textureDetailed()
        elif self.TextureMap != None:
            self.Root.setTexture(self.TextureMap, 1)
            if self.LightMap != None:
                ts = TextureStage("LightMap")
                ts.setMode(TextureStage.MModulate)
                ts.setSort(2)
                self.Root.setTexture(ts, self.LightMap, 2)
        elif self.LightMap != None:
            self.Root.setTexture(ts, self.LightMap, 1)
 def Texture(self):
   """Applies textures and if needed shaders to the terrain.
   Call this initially, and whenever you have changed the size of some important textures,
   or added/removed some textures or changed the lighting mode.
   This function is automatically called by Initialize()."""    
   if self.TextureMap == "": self.TextureMap = None
   if self.LightMap == "": self.LightMap = None
   
   # Does it have a detail map?
   if len(self.AlphaMaps) > 0:
     self._textureDetailed()
   elif self.TextureMap != None:
     self.Root.setTexture(self.TextureMap, 1)
     if self.LightMap != None:
       ts = TextureStage("LightMap")
       ts.setMode(TextureStage.MModulate)
       ts.setSort(2)
       self.Root.setTexture(ts, self.LightMap, 2)
   elif self.LightMap != None:
     self.Root.setTexture(ts, self.LightMap, 1)
Exemple #8
0
class SkyDome1(Att_base):
    def __init__(self,
                 scene,
                 dynamic=True,
                 rate=(0.005, 0.05),
                 texturescale=(1000, 1000),
                 scale=(40, 40, 10),
                 texturefile=None):
        Att_base.__init__(self, False, "Sky Dome 1")
        self.skybox = loader.loadModel("../media/models/dome2")
        self.skybox.setCollideMask(BitMask32().allOff())
        self.skybox.setTwoSided(False)
        self.skybox.setScale(scale[0], scale[1], scale[2])
        self.skybox.setLightOff()
        if texturefile == None:
            texturefile = "../media/textures/concrete.jpg"
        texture = loader.loadTexture(texturefile)
        self.textureStage0 = TextureStage("stage0")
        self.textureStage0.setMode(TextureStage.MReplace)
        self.skybox.setTexture(self.textureStage0, texture, 1)
        self.skybox.setTexScale(self.textureStage0, texturescale[0],
                                texturescale[1])

        self.skybox.reparentTo(scene)

    def setTextureScale(self, texturescale):
        self.skybox.setTexScale(self.textureStage0, texturescale[0],
                                texturescale[1])

    def Destroy(self):
        self.skybox.removeNode()

    def setPos(self, v):
        self.skybox.setPos(v)

    def show(self):
        self.skybox.show()

    def hide(self):
        self.skybox.hide()
class RepairLeak(DirectButton, FSM.FSM):
    __module__ = __name__

    def __init__(self, name, parent, leakscale, **kw):
        self.name = name
        pitchingGui = loader.loadModel(
            'models/gui/pir_m_gui_srp_pitching_main')
        self.hole = pitchingGui.find('**/hole')
        if random.random() > 0.5:
            self.holeFilled = pitchingGui.find('**/pitch1')
        else:
            self.holeFilled = pitchingGui.find('**/pitch2')
        optiondefs = (('relief', None,
                       None), ('geom', (self.hole, self.hole, self.hole,
                                        self.holeFilled), None),
                      ('rolloverSound', None, None), ('clickSound', None,
                                                      None))
        self.defineoptions(kw, optiondefs)
        DirectButton.__init__(self, parent=parent, **kw)
        self.initialiseoptions(RepairLeak)
        FSM.FSM.__init__(self, 'leak_%sFSM' % self.name)
        self.onCleanup = None
        self.leakScale = leakscale
        self.pitchingGame = parent
        self._initVars()
        self._initVisuals()
        self._initIntervals()
        self.fadeSequence = None
        self.request('Idle')
        return

    def _initVars(self):
        self.timeActive = 0.0
        self.pulseScale = 0.6

    def _initVisuals(self):
        textureCard = loader.loadModel('models/minigames/pir_m_gam_srp_water')
        self.waterStream = textureCard.find('**/waterPlane')
        tex = textureCard.findTexture('pir_t_gui_srp_waterDrops')
        textureCard2 = loader.loadModel('models/minigames/pir_m_gam_srp_water')
        self.waterStream2 = textureCard2.find('**/waterPlane')
        tex2 = textureCard2.findTexture('pir_t_gui_srp_waterDrops')
        alphaCard = loader.loadModel(
            'models/minigames/pir_m_gui_srp_waterDropsAlpha')
        self.alphaWaterStream = textureCard.find(
            '**/pir_t_gui_srp_waterDropsAlpha')
        alphatex = alphaCard.find(
            '**/pir_t_gui_srp_waterDropsAlpha').findTexture('*')
        self.alphaWaterStream2 = textureCard.find(
            '**/pir_t_gui_srp_waterDropsAlpha2')
        alphatex2 = alphaCard.find(
            '**/pir_t_gui_srp_waterDropsAlpha2').findTexture('*')
        alphaCard2 = loader.loadModel(
            'models/minigames/pir_m_gui_srp_waterDropsAlpha')
        self.alphaWaterStream3 = textureCard.find(
            '**/pir_t_gui_srp_waterDropsAlpha')
        alphatex3 = alphaCard2.findTexture('*')
        self.alphaWaterStream4 = textureCard.find(
            '**/pir_t_gui_srp_waterDropsAlpha2')
        alphatex4 = alphaCard2.findTexture('*')
        tex.setWrapU(Texture.WMRepeat)
        tex.setWrapV(Texture.WMRepeat)
        alphatex.setWrapU(Texture.WMRepeat)
        alphatex.setWrapV(Texture.WMRepeat)
        tex2.setWrapU(Texture.WMRepeat)
        tex2.setWrapV(Texture.WMRepeat)
        alphatex3.setWrapU(Texture.WMRepeat)
        alphatex3.setWrapV(Texture.WMRepeat)
        self.setScale(2.5 * self.leakScale)
        self.waterStream.setScale(self.leakScale)
        self.waterStream.setPos(self.getX(), 0.0,
                                -0.5 * self.leakScale + self.getZ())
        self.waterStream2.setScale(self.leakScale * 0.8, self.leakScale,
                                   self.leakScale * 1.2)
        self.waterStream2.setPos(self.getX(), 0.0,
                                 -0.6 * self.leakScale + self.getZ())
        self.waterStream.setColor(0.7, 0.85, 1.0, 1.0)
        self.waterStream2.setColor(0.5, 0.6, 0.9, 1.0)
        self.waterStream2.reparentTo(self.pitchingGame)
        self.waterStream.reparentTo(self.pitchingGame)
        self.waterStream2.setBin('fixed', 42)
        self.waterStream.setBin('fixed', 40)
        self.textureYOffset = random.random()
        self.textureYDelta = 0.25 + 0.025 / self.leakScale
        self.textureYOffset2 = random.random()
        self.textureYDelta2 = 0.25412354 + 0.058754645634 / self.leakScale
        self.textureYOffsetAlpha = 0.0
        self.textureYDeltaAlpha = 0.25 + 0.025 / self.leakScale
        self.textureYOffsetAlpha2 = 0.0
        self.textureYDeltaAlpha2 = 0.25412354 + 0.058754645634 / self.leakScale
        self.textureStage = self.waterStream.findTextureStage('*')
        self.textureStage2 = self.waterStream2.findTextureStage('*')
        self.textureStage3 = TextureStage('alphaLayer')
        self.textureStage3.setMode(TextureStage.MModulate)
        self.textureStage3.setSort(1)
        self.waterStream.setTexture(self.textureStage3, alphatex)
        self.textureStage4 = TextureStage('alphaLayer2')
        self.textureStage4.setMode(TextureStage.MModulate)
        self.textureStage4.setSort(2)
        self.waterStream.setTexture(self.textureStage4, alphatex2)
        trans = TransformState.makePos((0, 0.48, 0))
        self.waterStream.setTexTransform(self.textureStage4, trans)
        self.textureStage5 = TextureStage('alphaLayer3')
        self.textureStage5.setMode(TextureStage.MModulate)
        self.textureStage5.setSort(1)
        self.waterStream2.setTexture(self.textureStage5, alphatex3)
        self.textureStage6 = TextureStage('alphaLayer4')
        self.textureStage6.setMode(TextureStage.MModulate)
        self.textureStage6.setSort(2)
        self.waterStream2.setTexture(self.textureStage6, alphatex4)
        trans = TransformState.makePos((0, 0.48, 0))
        self.waterStream2.setTexTransform(self.textureStage6, trans)

    def repositionTo(self, newX, newZ):
        self.setPos(newX, 0.0, newZ)
        self.waterStream.setPos(self.getX(), 0.0,
                                -0.5 * self.leakScale + self.getZ())
        self.waterStream2.setPos(self.getX(), 0.0,
                                 -0.6 * self.leakScale + self.getZ())

    def _initIntervals(self):
        pass

    def destroy(self):
        if self.fadeSequence is not None:
            self.fadeSequence.clearToInitial()
        self['extraArgs'] = None
        taskMgr.remove('RepairLeak_%s.update' % self.name)
        if self.onCleanup is not None:
            self.onCleanup(self)
        self.cleanup()
        self.waterStream.removeNode()
        self.waterStream2.removeNode()
        DirectButton.destroy(self)
        return

    def update(self, task):
        dt = globalClock.getDt()
        self.timeActive += dt
        self.textureYOffset += self.textureYDelta * dt
        trans = TransformState.makePos((0, self.textureYOffset, 0))
        self.waterStream.setTexTransform(self.textureStage, trans)
        done = False
        if self.getCurrentOrNextState() == 'Active':
            if self.textureYOffsetAlpha < _activePosition:
                self.textureYOffsetAlpha += self.textureYDeltaAlpha * dt
                if self.textureYOffsetAlpha > _activePosition:
                    self.textureYOffsetAlpha = _activePosition
                trans2 = TransformState.makePos(
                    (0, self.textureYOffsetAlpha, 0))
                self.waterStream.setTexTransform(self.textureStage3, trans2)
            if self.getCurrentOrNextState() == 'Patched':
                if self.textureYOffsetAlpha < _activePosition:
                    self.textureYOffsetAlpha = 0.75 - self.textureYOffsetAlpha / 2.0
                    trans2 = TransformState.makePos(
                        (0, self.textureYOffsetAlpha, 0))
                    self.waterStream.setTexTransform(self.textureStage3,
                                                     trans2)
                elif self.textureYOffsetAlpha < 1.0:
                    self.textureYOffsetAlpha += self.textureYDeltaAlpha * dt
                    trans2 = TransformState.makePos(
                        (0, self.textureYOffsetAlpha, 0))
                    self.waterStream.setTexTransform(self.textureStage3,
                                                     trans2)
            self.textureYOffset2 += self.textureYDelta2 * dt
            trans = TransformState.makePos((0, self.textureYOffset2, 0))
            self.waterStream2.setTexTransform(self.textureStage2, trans)
            if self.getCurrentOrNextState(
            ) == 'Active' and self.textureYOffsetAlpha2 < _activePosition:
                self.textureYOffsetAlpha2 += self.textureYDeltaAlpha2 * dt
                if self.textureYOffsetAlpha2 > _activePosition:
                    self.textureYOffsetAlpha2 = _activePosition
                trans2 = TransformState.makePos(
                    (0, self.textureYOffsetAlpha2, 0))
                self.waterStream2.setTexTransform(self.textureStage5, trans2)
            if self.getCurrentOrNextState() == 'Patched':
                if self.textureYOffsetAlpha2 < _activePosition:
                    self.textureYOffsetAlpha2 = 0.75 - self.textureYOffsetAlpha2 / 2.0
                    trans2 = TransformState.makePos(
                        (0, self.textureYOffsetAlpha2, 0))
                    self.waterStream2.setTexTransform(self.textureStage5,
                                                      trans2)
                if self.textureYOffsetAlpha2 < 1.0:
                    self.textureYOffsetAlpha2 += self.textureYDeltaAlpha2 * dt
                    trans2 = TransformState.makePos(
                        (0, self.textureYOffsetAlpha2, 0))
                    self.waterStream2.setTexTransform(self.textureStage5,
                                                      trans2)
                else:
                    done = True
            done and self.waterStream.stash()
            self.waterStream2.stash()
            self.fadeSequence = Sequence(
                LerpColorScaleInterval(self,
                                       duration=2.0,
                                       colorScale=(1.0, 1.0, 1.0, 0.0)),
                Func(self.destroy))
            self.fadeSequence.start()
            return Task.done
        else:
            return Task.cont

    def setCommandButtons(self):
        self.guiItem.addClickButton(MouseButton.one())
        self.bind(DGG.B1PRESS, self.commandFunc)

    def enterIdle(self):
        self.stash()
        self.waterStream.stash()
        self.waterStream2.stash()
        self['state'] = DGG.DISABLED

    def exitIdle(self):
        pass

    def enterPatched(self):
        self['state'] = DGG.DISABLED
        self.setScale(0.85)

    def exitPatched(self):
        self.stash()
        self.waterStream.stash()
        self.waterStream2.stash()

    def enterActive(self):
        taskMgr.add(self.update, 'RepairLeak_%s.update' % self.name)
        self.unstash()
        self.waterStream.unstash()
        self.waterStream2.unstash()
        self['state'] = DGG.NORMAL

    def exitActive(self):
        self['state'] = DGG.DISABLED
Exemple #10
0
def construct_scene(lbase,
                    modelpath,
                    bgpath,
                    scale,
                    pos,
                    hpr,
                    bgscale,
                    bghp,
                    texture=None,
                    internal_canonical=False,
                    check_penetration=False,
                    light_spec=None,
                    use_envmap=False,
                    shader=None,
                    world_coords=False):
    """ Constructs the scene per the parameters. """

    # Default scene is lbase's rootnode
    if bgpath is not None:
        bgpath = mt.resolve_bg_path(bgpath)
    rootnode = lbase.rootnode
    # Modelpath points to the model .egg/.bam file

    if isstring(modelpath):
        modelpaths = [modelpath]
        scales = [scale]
        poses = [pos]
        hprs = [hpr]
        textures = [texture]
    else:
        modelpaths = modelpath
        scales = scale
        poses = pos
        hprs = hpr
        textures = texture

    texmodes = []
    for _i, _t in enumerate(textures):
        if isinstance(_t, tuple):
            texfile, texmode = _t
            texmodes.append(texmode)
            textures[_i] = texfile
        else:
            texmodes.append(TexGenAttrib.MWorldNormal)

    assert hasattr(modelpaths, '__iter__')
    assert hasattr(scales, '__iter__')
    assert hasattr(poses, '__iter__')
    assert hasattr(hprs, '__iter__')
    assert hasattr(textures, '__iter__')
    assert len(modelpaths) == len(scales) == len(hprs) == len(poses) == len(
        textures), (len(modelpaths), len(scales), len(hprs), len(poses),
                    len(textures))

    modelpaths = map(mt.resolve_model_path, modelpaths)
    modelpaths = map(cm.autogen_egg, modelpaths)
    textures = map(mt.resolve_texture_path, textures)
    objnodes = []
    for mpth, scale, hpr, pos, t, tm in zip(modelpaths, scales, hprs, poses,
                                            textures, texmodes):
        objnode = tools.read_file(lbase.loader.loadModel, mpth)
        if t is not None:
            #ts = TextureStage('ts')
            ts = TextureStage.get_default()
            ts.setMode(TextureStage.MReplace)
            tex = tools.read_file(lbase.loader.loadTexture, t)
            objnode.setTexGen(ts, tm)
            objnode.setTexture(tex, 6)

        robjnode = rootnode.attachNewNode('root_' + objnode.get_name())
        objnode.reparentTo(robjnode)
        if internal_canonical:
            vertices = np.array(objnode.getTightBounds())
            initial_scale_factor = max(abs(vertices[0] - vertices[1]))
            cscale = 1.2 / initial_scale_factor
            ppos = vertices.mean(0) * cscale
            objnode.setPos(-ppos[0], -ppos[1], -ppos[2])
            objnode.setScale(cscale, cscale, cscale)

        if world_coords:
            refnodeX = rootnode.attachNewNode('world_coords_x')
            refnodeY = rootnode.attachNewNode('world_coords_y')
            refnodeZ = rootnode.attachNewNode('world_coords_z')

            robjnode.wrtReparentTo(refnodeZ)
            refnodeZ.setH(refnodeX, hpr[2])
            robjnode.wrtReparentTo(refnodeY)
            refnodeY.setP(refnodeX, hpr[1])
            robjnode.wrtReparentTo(refnodeX)
            refnodeX.setR(refnodeX, hpr[0])
            robjnode.wrtReparentTo(rootnode)
        else:
            robjnode.setHpr(hpr[2], hpr[1], hpr[0])

        robjnode.setScale(scale[0], scale[0], scale[0])
        robjnode.setPos(pos[0], -pos[2], pos[1])
        robjnode.setTwoSided(1)

        objnodes.append(robjnode)

    if check_penetration:
        for (i, n1) in enumerate(objnodes):
            for j, n2 in enumerate(objnodes[i + 1:]):
                p = is_penetrating(n1, n2)
                if p:
                    for onode in objnodes:
                        onode.removeNode()
                    raise PenetrationError(i, j, n1, n2)

    # Environment map
    if bgpath and use_envmap:
        envtex = tools.read_file(lbase.loader.loadTexture, bgpath)
        # Map onto object
        ts = TextureStage('env')
        ts.setMode(TextureStage.MBlendColorScale)
        if not isinstance(use_envmap, list):
            use_envmap = [use_envmap] * len(objnodes)
        for _objnode, ue in zip(objnodes, use_envmap):
            if ue:
                if isstring(ue):
                    envtex0 = tools.read_file(lbase.loader.loadTexture,
                                              mt.resolve_texture_path(ue))
                else:
                    envtex0 = envtex
                _objnode.setTexGen(ts, TexGenAttrib.MEyeSphereMap)
                _objnode.setTexture(ts, envtex0)

    if bgpath and not np.isinf(bghp[0]):
        bgtex = tools.read_file(lbase.loader.loadTexture, bgpath)
        # Set as background
        #plane = cm.autogen_egg(mt.resolve_model_path('plane2d'))
        bgnode = lbase.loader.loadModel('smiley')
        # Get material list
        bgnode.clearMaterial()
        bgnode.clearTexture()
        bgnode.setAttrib(
            CullFaceAttrib.make(CullFaceAttrib.MCullCounterClockwise))
        bgnode.setTexture(bgtex, 2)
        c = 5.
        bgnode.setScale(c * bgscale[0], c * bgscale[0], c * bgscale[0])
        bgnode.setPos(0, 0, 0)  #0)
        bgnode.setHpr(bghp[0], bghp[1], 0.)
        # Detach point light
        plight1 = lbase.rootnode.find('**/plight1')
        if plight1:
            plight1.detachNode()
    elif bgpath:
        bgnode = NodePath("empty-bgnode")
        imageObject = OnscreenImage(image=bgpath,
                                    pos=(0, 0, 0),
                                    scale=tuple(bgscale),
                                    parent=bgnode,
                                    base=lbase)
    else:
        bgnode = NodePath("empty-bgnode")
    bgnode.reparentTo(rootnode)

    if shader is not None:
        vshaderpath, fshaderpath = shader
        rootnode.setShaderAuto()
        shader = Shader.load(Shader.SLGLSL, vshaderpath, fshaderpath)
        rootnode.setShader(shader)

    if light_spec is not None:
        lbase.rootnode.clearLight()
        lights = LightBase.make_lights(light_spec=light_spec,
                                       lname='scene_lights')
        lights.reparentTo(rootnode)
        for light in lights.getChildren():
            rootnode.setLight(light)

    return objnodes, bgnode
Exemple #11
0
class SkyDome2(Att_base):
    def __init__(self, scene, dynamic=True, rate=Vec4(0.004, 0.002, 0.008, 0.010),
        skycolor=Vec4(0.25, 0.5, 1, 0),
        texturescale=Vec4(1,1,1,1),
        scale=(4000,4000,1000),
        texturefile=None):
        Att_base.__init__(self,False, "Sky Dome 2")
        self.skybox = loader.loadModel("./media/models/dome2")
        self.skybox.reparentTo(scene)
        self.skybox.setScale(scale[0],scale[1],scale[2])
        self.skybox.setLightOff()

        if texturefile == None:
            texturefile = "./media/textures/clouds_bw.png"
        texture = loader.loadTexture(texturefile)
        self.textureStage0 = TextureStage("stage0")
        self.textureStage0.setMode(TextureStage.MReplace)
        self.skybox.setTexture(self.textureStage0,texture,1)
        #self.skybox.setTexScale(self.textureStage0, texturescale[0], texturescale[1])

        self.rate = rate
        self.textureScale = texturescale
        self.skycolor = skycolor
        self.dynamic = dynamic
        if self.dynamic:
            self.skybox.setShader( loader.loadShader( './media/shaders/skydome2.sha' ) )
            self.setShaderInput()

    def setRate(self, rate):
        self.rate = rate

    def setTextureScale(self, texturescale):
        self.skybox.setTexScale(self.textureStage0, texturescale[0], texturescale[1])

    def Destroy(self):
        self.skybox.clearShader()
        self.skybox.removeNode()

    def setPos(self, v):
        self.skybox.setPos(v)

    def show(self):
        self.skybox.show()

    def hide(self):
        self.skybox.hide()

    def setStandardControl(self):
        self.att_rate = Att_Vecs(False,"Cloud Speed",4,self.rate,-1,1,3)
        self.att_scale = Att_Vecs(False, "Tex-scale", 4, self.textureScale, 0.01, 100.0, 2)
        self.att_skycolor = Att_color(False, "Sky Color", self.skycolor)
        self.att_rate.setNotifier(self.changeParams)
        self.att_scale.setNotifier(self.changeParams)
        self.att_skycolor.setNotifier(self.changeParams)

    def changeParams(self, object):
        self.rate = self.att_rate.getValue()
        self.skycolor = self.att_skycolor.getColor()
        self.textureScale = self.att_scale.getValue()
        self.setShaderInput()

    #def skyboxscalechange(self,object):
    #    self.setTextureScale(self.att_scale.getValue())

    def setShaderInput(self):
        self.skybox.setShaderInput("sky", self.skycolor)
        self.skybox.setShaderInput("clouds", self.rate)
        self.skybox.setShaderInput("ts", self.textureScale)
Exemple #12
0
def construct_scene(lbase, modelpath, bgpath, scale, pos, hpr, 
                    bgscale, bghp,
                    texture=None,
                    internal_canonical=False,
                    check_penetration=False, 
                    light_spec=None, 
                    use_envmap=False):
    """ Constructs the scene per the parameters. """

    # Default scene is lbase's rootnode
    if bgpath is not None:
        bgpath = mt.resolve_bg_path(bgpath)
    rootnode = lbase.rootnode
    # Modelpath points to the model .egg/.bam file

    if isinstance(modelpath, str):
        modelpaths = [modelpath]
        scales = [scale]
        poses = [pos]
        hprs = [hpr]
        textures = [texture]
    else:  
        modelpaths = modelpath
        scales = scale
        poses = pos
        hprs = hpr
        textures = texture

    texmodes = []
    for _i, _t in enumerate(textures):
        if isinstance(_t, tuple):
            texfile, texmode = _t
            texmodes.append(texmode)
            textures[_i] = texfile
        else:
            texmodes.append(TexGenAttrib.MWorldNormal)    

    assert hasattr(modelpaths, '__iter__')
    assert hasattr(scales, '__iter__')
    assert hasattr(poses, '__iter__')
    assert hasattr(hprs, '__iter__')
    assert hasattr(textures, '__iter__')
    assert len(modelpaths) == len(scales) == len(hprs) == len(poses) == len(textures), (len(modelpaths), len(scales), len(hprs), len(poses), len(textures))
        
    modelpaths = map(mt.resolve_model_path, modelpaths)
    modelpaths = map(cm.autogen_egg, modelpaths)
    textures = map(mt.resolve_texture_path, textures)
    objnodes = []
    for mpth, scale, hpr, pos, t, tm in zip(modelpaths, scales, hprs, poses, textures, texmodes):
        objnode = tools.read_file(lbase.loader.loadModel, mpth)
        if t is not None: 
            #ts = TextureStage('ts')
            ts = TextureStage.get_default()
            ts.setMode(TextureStage.MReplace) 
            tex = tools.read_file(lbase.loader.loadTexture, t) 
            objnode.setTexGen(ts, tm)
            objnode.setTexture(tex, 6)
        
        robjnode = rootnode.attachNewNode('root_' + objnode.get_name())
        objnode.reparentTo(robjnode)
        if internal_canonical:
            vertices = np.array(objnode.getTightBounds())
            initial_scale_factor = max(abs(vertices[0]-vertices[1]))
            cscale = 1.2/initial_scale_factor
            ppos = vertices.mean(0) * cscale
            objnode.setPos(-ppos[0], -ppos[1], -ppos[2])
            objnode.setScale(cscale, cscale, cscale)
            
        robjnode.setScale(scale[0], scale[0], scale[0])
        robjnode.setPos(pos[0], -pos[2], pos[1])
        robjnode.setHpr(hpr[2], hpr[1], hpr[0])
        robjnode.setTwoSided(1)

        objnodes.append(robjnode)

    if check_penetration:
        for (i, n1) in enumerate(objnodes):
            for j, n2 in enumerate(objnodes[i+1:]):
                p = is_penetrating(n1, n2)
                if p:
                    for onode in objnodes:
                        onode.removeNode()
                    raise PenetrationError(i, j, n1, n2)

    # Environment map
    if bgpath and use_envmap:
        envtex = tools.read_file(lbase.loader.loadTexture, bgpath)
        # Map onto object
        ts = TextureStage('env')
        ts.setMode(TextureStage.MBlendColorScale)
        if not isinstance(use_envmap, list):
            use_envmap = [use_envmap] * len(objnodes)
        for _objnode, ue in zip(objnodes, use_envmap):
            if ue:
                if isinstance(ue, str):
                    envtex0 = tools.read_file(lbase.loader.loadTexture, mt.resolve_texture_path(ue))
                else:
                    envtex0 = envtex
                _objnode.setTexGen(ts, TexGenAttrib.MEyeSphereMap)
                _objnode.setTexture(ts, envtex0)

    if bgpath and not np.isinf(bghp[0]):
        bgtex = tools.read_file(lbase.loader.loadTexture, bgpath)
        # Set as background
        #plane = cm.autogen_egg(mt.resolve_model_path('plane2d'))
        bgnode = lbase.loader.loadModel('smiley')
        # Get material list
        bgnode.clearMaterial()
        bgnode.clearTexture()
        bgnode.setAttrib(CullFaceAttrib.make(
            CullFaceAttrib.MCullCounterClockwise))
        bgnode.setTexture(bgtex, 2)
        c = 5.
        bgnode.setScale(c * bgscale[0], c * bgscale[0], c * bgscale[0])
        bgnode.setPos(0, 0, 0) #0)
        bgnode.setHpr(bghp[0], bghp[1], 0.) 
        # Detach point light
        plight1 = lbase.rootnode.find('**/plight1')
        if plight1:
            plight1.detachNode()
    elif bgpath:
        bgnode = NodePath("empty-bgnode")
        imageObject = OnscreenImage(image = bgpath, pos = (0, 0, 0), scale=tuple(bgscale), parent=bgnode, base=lbase)
    else:
        bgnode = NodePath("empty-bgnode")
    bgnode.reparentTo(rootnode)

    if light_spec is not None:
        lbase.rootnode.clearLight()
        lights = LightBase.make_lights(light_spec=light_spec, lname='scene_lights')
        lights.reparentTo(rootnode)
        for light in lights.getChildren():
            rootnode.setLight(light)

    return objnodes, bgnode
class RepairLeak(DirectButton, FSM.FSM):

    def __init__(self, name, parent, leakscale, **kw):
        self.name = name
        pitchingGui = loader.loadModel('models/gui/pir_m_gui_srp_pitching_main')
        self.hole = pitchingGui.find('**/hole')
        if random.random() > 0.5:
            self.holeFilled = pitchingGui.find('**/pitch1')
        else:
            self.holeFilled = pitchingGui.find('**/pitch2')
        optiondefs = (('relief', None, None), ('geom', (self.hole, self.hole, self.hole, self.holeFilled), None), ('rolloverSound', None, None), ('clickSound', None, None))
        self.defineoptions(kw, optiondefs)
        DirectButton.__init__(self, parent = parent)
        self.initialiseoptions(RepairLeak)
        FSM.FSM.__init__(self, 'leak_%sFSM' % self.name)
        self.onCleanup = None
        self.leakScale = leakscale
        self.pitchingGame = parent
        self._initVars()
        self._initVisuals()
        self._initIntervals()
        self.fadeSequence = None
        self.request('Idle')


    def _initVars(self):
        self.timeActive = 0.0
        self.pulseScale = 0.59999999999999998


    def _initVisuals(self):
        textureCard = loader.loadModel('models/minigames/pir_m_gam_srp_water')
        self.waterStream = textureCard.find('**/waterPlane')
        tex = textureCard.findTexture('pir_t_gui_srp_waterDrops')
        textureCard2 = loader.loadModel('models/minigames/pir_m_gam_srp_water')
        self.waterStream2 = textureCard2.find('**/waterPlane')
        tex2 = textureCard2.findTexture('pir_t_gui_srp_waterDrops')
        alphaCard = loader.loadModel('models/minigames/pir_m_gui_srp_waterDropsAlpha')
        self.alphaWaterStream = textureCard.find('**/pir_t_gui_srp_waterDropsAlpha')
        alphatex = alphaCard.find('**/pir_t_gui_srp_waterDropsAlpha').findTexture('*')
        self.alphaWaterStream2 = textureCard.find('**/pir_t_gui_srp_waterDropsAlpha2')
        alphatex2 = alphaCard.find('**/pir_t_gui_srp_waterDropsAlpha2').findTexture('*')
        alphaCard2 = loader.loadModel('models/minigames/pir_m_gui_srp_waterDropsAlpha')
        self.alphaWaterStream3 = textureCard.find('**/pir_t_gui_srp_waterDropsAlpha')
        alphatex3 = alphaCard2.findTexture('*')
        self.alphaWaterStream4 = textureCard.find('**/pir_t_gui_srp_waterDropsAlpha2')
        alphatex4 = alphaCard2.findTexture('*')
        tex.setWrapU(Texture.WMRepeat)
        tex.setWrapV(Texture.WMRepeat)
        alphatex.setWrapU(Texture.WMRepeat)
        alphatex.setWrapV(Texture.WMRepeat)
        tex2.setWrapU(Texture.WMRepeat)
        tex2.setWrapV(Texture.WMRepeat)
        alphatex3.setWrapU(Texture.WMRepeat)
        alphatex3.setWrapV(Texture.WMRepeat)
        self.setScale(2.5 * self.leakScale)
        self.waterStream.setScale(self.leakScale)
        self.waterStream.setPos(self.getX(), 0.0, -0.5 * self.leakScale + self.getZ())
        self.waterStream2.setScale(self.leakScale * 0.80000000000000004, self.leakScale, self.leakScale * 1.2)
        self.waterStream2.setPos(self.getX(), 0.0, -0.59999999999999998 * self.leakScale + self.getZ())
        self.waterStream.setColor(0.69999999999999996, 0.84999999999999998, 1.0, 1.0)
        self.waterStream2.setColor(0.5, 0.59999999999999998, 0.90000000000000002, 1.0)
        self.waterStream2.reparentTo(self.pitchingGame)
        self.waterStream.reparentTo(self.pitchingGame)
        self.waterStream2.setBin('fixed', 42)
        self.waterStream.setBin('fixed', 40)
        self.textureYOffset = random.random()
        self.textureYDelta = 0.25 + 0.025000000000000001 / self.leakScale
        self.textureYOffset2 = random.random()
        self.textureYDelta2 = 0.25412353999999998 + 0.058754645634 / self.leakScale
        self.textureYOffsetAlpha = 0.0
        self.textureYDeltaAlpha = 0.25 + 0.025000000000000001 / self.leakScale
        self.textureYOffsetAlpha2 = 0.0
        self.textureYDeltaAlpha2 = 0.25412353999999998 + 0.058754645634 / self.leakScale
        self.textureStage = self.waterStream.findTextureStage('*')
        self.textureStage2 = self.waterStream2.findTextureStage('*')
        self.textureStage3 = TextureStage('alphaLayer')
        self.textureStage3.setMode(TextureStage.MModulate)
        self.textureStage3.setSort(1)
        self.waterStream.setTexture(self.textureStage3, alphatex)
        self.textureStage4 = TextureStage('alphaLayer2')
        self.textureStage4.setMode(TextureStage.MModulate)
        self.textureStage4.setSort(2)
        self.waterStream.setTexture(self.textureStage4, alphatex2)
        trans = TransformState.makePos((0, 0.47999999999999998, 0))
        self.waterStream.setTexTransform(self.textureStage4, trans)
        self.textureStage5 = TextureStage('alphaLayer3')
        self.textureStage5.setMode(TextureStage.MModulate)
        self.textureStage5.setSort(1)
        self.waterStream2.setTexture(self.textureStage5, alphatex3)
        self.textureStage6 = TextureStage('alphaLayer4')
        self.textureStage6.setMode(TextureStage.MModulate)
        self.textureStage6.setSort(2)
        self.waterStream2.setTexture(self.textureStage6, alphatex4)
        trans = TransformState.makePos((0, 0.47999999999999998, 0))
        self.waterStream2.setTexTransform(self.textureStage6, trans)


    def repositionTo(self, newX, newZ):
        self.setPos(newX, 0.0, newZ)
        self.waterStream.setPos(self.getX(), 0.0, -0.5 * self.leakScale + self.getZ())
        self.waterStream2.setPos(self.getX(), 0.0, -0.59999999999999998 * self.leakScale + self.getZ())


    def _initIntervals(self):
        pass


    def destroy(self):
        if self.fadeSequence is not None:
            self.fadeSequence.clearToInitial()

        self['extraArgs'] = None
        taskMgr.remove('RepairLeak_%s.update' % self.name)
        if self.onCleanup is not None:
            self.onCleanup(self)

        self.cleanup()
        self.waterStream.removeNode()
        self.waterStream2.removeNode()
        DirectButton.destroy(self)


    def update(self, task):
        dt = globalClock.getDt()
        self.timeActive += dt
        self.textureYOffset += self.textureYDelta * dt
        trans = TransformState.makePos((0, self.textureYOffset, 0))
        self.waterStream.setTexTransform(self.textureStage, trans)
        done = False
        if self.getCurrentOrNextState() == 'Active' and self.textureYOffsetAlpha < _activePosition:
            self.textureYOffsetAlpha += self.textureYDeltaAlpha * dt
            if self.textureYOffsetAlpha > _activePosition:
                self.textureYOffsetAlpha = _activePosition

            trans2 = TransformState.makePos((0, self.textureYOffsetAlpha, 0))
            self.waterStream.setTexTransform(self.textureStage3, trans2)

        if self.getCurrentOrNextState() == 'Patched':
            if self.textureYOffsetAlpha < _activePosition:
                self.textureYOffsetAlpha = 0.75 - self.textureYOffsetAlpha / 2.0
                trans2 = TransformState.makePos((0, self.textureYOffsetAlpha, 0))
                self.waterStream.setTexTransform(self.textureStage3, trans2)
            elif self.textureYOffsetAlpha < 1.0:
                self.textureYOffsetAlpha += self.textureYDeltaAlpha * dt
                trans2 = TransformState.makePos((0, self.textureYOffsetAlpha, 0))
                self.waterStream.setTexTransform(self.textureStage3, trans2)


        self.textureYOffset2 += self.textureYDelta2 * dt
        trans = TransformState.makePos((0, self.textureYOffset2, 0))
        self.waterStream2.setTexTransform(self.textureStage2, trans)
        if self.getCurrentOrNextState() == 'Active' and self.textureYOffsetAlpha2 < _activePosition:
            self.textureYOffsetAlpha2 += self.textureYDeltaAlpha2 * dt
            if self.textureYOffsetAlpha2 > _activePosition:
                self.textureYOffsetAlpha2 = _activePosition

            trans2 = TransformState.makePos((0, self.textureYOffsetAlpha2, 0))
            self.waterStream2.setTexTransform(self.textureStage5, trans2)

        if self.getCurrentOrNextState() == 'Patched':
            if self.textureYOffsetAlpha2 < _activePosition:
                self.textureYOffsetAlpha2 = 0.75 - self.textureYOffsetAlpha2 / 2.0
                trans2 = TransformState.makePos((0, self.textureYOffsetAlpha2, 0))
                self.waterStream2.setTexTransform(self.textureStage5, trans2)

            if self.textureYOffsetAlpha2 < 1.0:
                self.textureYOffsetAlpha2 += self.textureYDeltaAlpha2 * dt
                trans2 = TransformState.makePos((0, self.textureYOffsetAlpha2, 0))
                self.waterStream2.setTexTransform(self.textureStage5, trans2)
            else:
                done = True

        if done:
            self.waterStream.stash()
            self.waterStream2.stash()
            self.fadeSequence = Sequence(LerpColorScaleInterval(self, duration = 2.0, colorScale = (1.0, 1.0, 1.0, 0.0)), Func(self.destroy))
            self.fadeSequence.start()
            return Task.done
        else:
            return Task.cont


    def setCommandButtons(self):
        self.guiItem.addClickButton(MouseButton.one())
        self.bind(DGG.B1PRESS, self.commandFunc)


    def enterIdle(self):
        self.stash()
        self.waterStream.stash()
        self.waterStream2.stash()
        self['state'] = DGG.DISABLED


    def exitIdle(self):
        pass


    def enterPatched(self):
        self['state'] = DGG.DISABLED
        self.setScale(0.84999999999999998)


    def exitPatched(self):
        self.stash()
        self.waterStream.stash()
        self.waterStream2.stash()


    def enterActive(self):
        taskMgr.add(self.update, 'RepairLeak_%s.update' % self.name)
        self.unstash()
        self.waterStream.unstash()
        self.waterStream2.unstash()
        self['state'] = DGG.NORMAL


    def exitActive(self):
        self['state'] = DGG.DISABLED
Exemple #14
0
class SkyDome2(Att_base):
    def __init__(self,
                 scene,
                 dynamic=True,
                 rate=Vec4(0.004, 0.002, 0.008, 0.010),
                 skycolor=Vec4(0.25, 0.5, 1, 0),
                 texturescale=Vec4(1, 1, 1, 1),
                 scale=(4000, 4000, 1000),
                 texturefile=None):
        Att_base.__init__(self, False, "Sky Dome 2")
        self.skybox = loader.loadModel("./media/models/dome2")
        self.skybox.reparentTo(scene)
        self.skybox.setScale(scale[0], scale[1], scale[2])
        self.skybox.setLightOff()

        if texturefile == None:
            texturefile = "./media/textures/clouds_bw.png"
        texture = loader.loadTexture(texturefile)
        self.textureStage0 = TextureStage("stage0")
        self.textureStage0.setMode(TextureStage.MReplace)
        self.skybox.setTexture(self.textureStage0, texture, 1)
        #self.skybox.setTexScale(self.textureStage0, texturescale[0], texturescale[1])

        self.rate = rate
        self.textureScale = texturescale
        self.skycolor = skycolor
        self.dynamic = dynamic
        if self.dynamic:
            self.skybox.setShader(
                loader.loadShader('./media/shaders/skydome2.sha'))
            self.setShaderInput()

    def setRate(self, rate):
        self.rate = rate

    def setTextureScale(self, texturescale):
        self.skybox.setTexScale(self.textureStage0, texturescale[0],
                                texturescale[1])

    def Destroy(self):
        self.skybox.clearShader()
        self.skybox.removeNode()

    def setPos(self, v):
        self.skybox.setPos(v)

    def show(self):
        self.skybox.show()

    def hide(self):
        self.skybox.hide()

    def setStandardControl(self):
        self.att_rate = Att_Vecs(False, "Cloud Speed", 4, self.rate, -1, 1, 3)
        self.att_scale = Att_Vecs(False, "Tex-scale", 4, self.textureScale,
                                  0.01, 100.0, 2)
        self.att_skycolor = Att_color(False, "Sky Color", self.skycolor)
        self.att_rate.setNotifier(self.changeParams)
        self.att_scale.setNotifier(self.changeParams)
        self.att_skycolor.setNotifier(self.changeParams)

    def changeParams(self, object):
        self.rate = self.att_rate.getValue()
        self.skycolor = self.att_skycolor.getColor()
        self.textureScale = self.att_scale.getValue()
        self.setShaderInput()

    #def skyboxscalechange(self,object):
    #    self.setTextureScale(self.att_scale.getValue())

    def setShaderInput(self):
        self.skybox.setShaderInput("sky", self.skycolor)
        self.skybox.setShaderInput("clouds", self.rate)
        self.skybox.setShaderInput("ts", self.textureScale)
Exemple #15
0
class Star(SphericalBody):
    '''
    Class star contain attributes of the star and
    a list of all the planets orbiting the star.
    '''

    def __init__(self, position, radius, player=None):
        '''
        Constructor for class star: creates a dead star object, initializing the star's attributes with 
        the given parameters. 
        @param position : Point3D, the position of the center of the star
        @param radius : float, star radius
        @param player: Player, the owner of the star
        @param activated: boolean, determine whether star is activated by the player or not
        @param stage: Integer, is the stage in which the star is in; consists of 6 stages
        @param counter: Timer, is the count-down timer for the star's life
        '''
        super(Star, self).__init__(position, radius, False, player)
        self.lifetime = 0
        self._planets = []
        self.stage = 0
        self.timer_task = None
        
        self.t = Timer(self) 
        self.__initSceneGraph()
    
    def __initSceneGraph(self):
        # Parent node for relative position (no scaling)
        self.point_path = render.attachNewNode("star_node")
        self.point_path.setPos(self.position)
        
        #For transforming the object with scaling, colors, shading, etc.
        # Hosting the actual 3d model object.
        #Models & textures
        self.flare_ts = TextureStage('flare')
        self.flare_ts.setMode(TextureStage.MModulateGlow)
        self.model_path = loader.loadModel("models/stars/planet_sphere")
        self.model_path.setTexture(SphericalBody.star_dead_tex, 1)
        self.model_path.reparentTo(self.point_path)
        self.model_path.setScale(self.radius)
        self.model_path.setPythonTag('pyStar', self);
        
        # Collision sphere for object picking
        #-----------------------------------------------------
        # As described in the Tut-Chessboard.py sample: "If this model was
        # any more complex than a single polygon, you should set up a collision
        # sphere around it instead."
        cnode = CollisionNode("coll_sphere_node")
        cnode.setTag('star', str(id(self)))
        #We use no displacement (0,0,0) and no scaling factor (1)
        cnode.addSolid(CollisionSphere(0,0,0,1))
        cnode.setIntoCollideMask(BitMask32.bit(1))
        self.cnode_path = self.model_path.attachNewNode(cnode)
        #For temporary testing, display collision sphere.
#        self.cnode_path.show()
        self.quad_path = None
 
    def activateHighlight(self, thin):
        if thin:
            tex = base.loader.loadTexture("models/billboards/thin_ring.png")
        else:
            tex = base.loader.loadTexture("models/billboards/ring.png")
        cm = CardMaker('highlight')
        cm.setFrameFullscreenQuad() # so that the center acts as the origin (from -1 to 1)
        self.quad_path = self.point_path.attachNewNode(cm.generate())        
        self.quad_path.setTransparency(TransparencyAttrib.MAlpha)
        self.highlight_ts = TextureStage('flare')
        self.quad_path.setTexture(self.highlight_ts, tex)
        if thin:
            self.quad_path.setColor(Vec4(1.0, 1.0, 1.0, 1))
        else:
            self.quad_path.setColor(Vec4(1.0, 0.3, 0.2, 1))
        self.quad_path.setScale(12)
        self.quad_path.setPos(Vec3(0,0,0))
        self.quad_path.setBillboardPointEye()
    
    def deactivateHighlight(self):
        if self.quad_path:
            self.quad_path.detachNode()
            self.quad_path = None

    def select(self, player):
        '''
        @param player, the player who has selected
        This method observes the events on the star and calls the related methods
        and notifies the corresponding objects based on the state of the star
        '''
        player.selected_planet = None
        
        if(player.ge_amount != 0 and self.activated == False and \
           player.selected_star == self):
            player.ge_amount = player.ge_amount - 1
            self.activateStar(player)
            self.notify("updateGE")
        else:
#            from gameEngine.gameEngine import all_stars 
#            for star in all_stars:
#                if(star != self):
#                    star.deactivateHighlight()
            from gameEngine.gameEngine import all_planets
            for planet in all_planets:
                planet.deactivateHighlight()
            '''TODO: fix the conflict problem with highlight and star flare ''' 
            #self.activateHighlight(False)
            
        player.selected_star = self
        
    def activateStar(self, player):
        '''
        Activates a constructed dead star object, starting the lifetime counter with the assigned default value while
        the Game Engine calls the graphic engine to display the corresponding animation.
        @param player, the player who has activated the star
        '''
        self.lifetime = LIFETIME
        self.stage = 1
        self.activated = True
        self.radius = MAX_STAR_RADIUS
        self.player = player
        self.timer_task = taskMgr.doMethodLater(1, self.trackStarLife, 'starLifeTick')
        player.selected_star = self
        
#        point_light = PointLight("starLight")
#        point_light.setColor(Vec4(1.0, 1.0, 1.0, 1.0))
#        pt_node = render.attachNewNode(point_light)
##        pt_node.setHpr(60, 0, 90)
#        pt_node.setPos(Vec3(0, 0, -40.0))
#        render.setLight(pt_node)
        
        point_light = PointLight("starLight")
        point_light.setColor(Vec4(1.0, 1.0, 1.0, 1.0))
        point_light.setPoint(Point3(0, 0, 0))
        pt_node = self.point_path.attachNewNode(point_light)
#        pt_node.setHpr(60, 0, 90)
        render.setLight(pt_node)
        
        '''TODO : display star birth animation '''
        
        star_created_sound = base.loader.loadSfx("sound/effects/star/starCreation1.wav")
        star_created_sound.setVolume(0.6)
        star_created_sound.play()
#        base.sfxManagerList[0].update()
#        SphericalBody.star_created_sound1.play()
        #SphericalBody.star_created_sound2.play()
        
        self.radius = MAX_STAR_RADIUS
        self.model_path.setScale(self.radius)
        self.model_path.setTexture(self.flare_ts, SphericalBody.star_stage1_tex)
        self._activateSunflare()
    
    def _activateSunflare(self):
        self.deactivateHighlight()
        flare_tex = base.loader.loadTexture("models/billboards/sunflare.png")
        cm = CardMaker('flare')
        cm.setFrameFullscreenQuad() # so that the center acts as the origin (from -1 to 1)
        self.flare_path = self.point_path.attachNewNode(cm.generate())        
        self.flare_path.setTransparency(TransparencyAttrib.MAlpha)
        self.flare_path.setTexture(self.flare_ts,flare_tex)
        self.flare_path.setColor(Vec4(1.0, 1.0, 1.0, 1))
        self.flare_path.setScale(50)
        self.flare_path.setPos(Vec3(0,0,0))
        self.flare_path.setBillboardPointEye()
        self.flare_path.setLightOff()
        
    def trackStarLife(self, task):
        self.lifetime = self.lifetime - float(self.getNumberOfActivePlanets()+1)/(2)
        from graphicEngine import indicators
        indicators.drawStarProgressBar(self, self.lifetime)
#        self.updateTimer()
        if(self.lifetime <= LIFETIME - LIFETIME/6 and self.stage == 1):
            self.stage = 2
            self.model_path.setTexture(self.flare_ts, SphericalBody.star_stage2_tex)
        elif(self.lifetime <= LIFETIME - LIFETIME/3 and self.stage == 2):
            self.stage = 3
            self.model_path.setTexture(self.flare_ts, SphericalBody.star_stage3_tex)
        elif(self.lifetime <= LIFETIME - LIFETIME/2 and self.stage == 3):
            self.stage = 4
            self.model_path.setTexture(self.flare_ts, SphericalBody.star_stage4_tex)
        elif(self.lifetime <= LIFETIME - 2*LIFETIME/3 and self.stage == 4):
            self.stage = 5
            self.model_path.setTexture(self.flare_ts, SphericalBody.star_stage5_tex)
        elif(self.lifetime <= 0 and self.stage == 5):
            self.lifetime = 0
            self.stage = 6
            self.model_path.setTexture(SphericalBody.star_stage6_tex, 1)
            self._consumeSolarSystem()
#            timer_destruction= taskMgr.doMethodLater(1, self._consumeSolarSystem, 'consumeSolarSystem')
            '''calls the escape solar system routine from the AI class'''
            from gameEngine.gameEngine import ai
            task = taskMgr.doMethodLater(AI_ESCAPE_WAIT_TIME, ai.escapeStar, 'AIescapeStar', extraArgs =[self], appendTask=True)
            return task.done
        return task.again
    
    def _consumeSolarSystem(self):#, task):
        
        for planet in self.planets():
            planet.startCollapse()
        
#    def updateTimer(self):
#        self.notify("updateTime")
        
    def addPlanet(self, planet):
        '''
        Adds a planet to the star system
        @param: planet object
        '''
        if(len(self._planets) < MAX_NUMBER_OF_PLANETS):
            self._planets.append(planet)
        
    def removePlanet(self, planet):
        '''
        removes a planet from the star system
        @param planet object
        '''
        if len(self._planets) != 0:
            self._planets.remove(planet)
        
    def removeAllPlanets(self):
        '''
        removes all the planets in the star system
        '''
        del self._planets[:]
        
    def planets(self):
        '''
        Generator that iterates over the hosted planets.
        '''
        for planet in self._planets:
            yield planet
    
    def getPlanetAt(self, orbit):
        '''
        Returns the planet at the desired orbit
        @param orbit is an integer
        '''
        return self._planets[orbit]
        
    def getNextDeadPlanet(self):
        '''
        returns next un-activated planet
        '''
        for planet in self._planets:
            if not planet.activated:
                return planet
        return None
    
    def getlastPlanet(self):
        '''
        returns the last planet in the solar system
        '''
        if(self.getNumberOfPlanets()!=0):
            return self._planets[-1]
        
    def getOrbit(self, planet):
        return self._planets.index(planet)
        
    def getPlanet(self, planet):
        '''
        Returns the index of the given planet from list of planets 
        @param planet : the desired planet
        '''
        return self._planets.index(planet)
            
    def getNumberOfPlanets(self):
        '''
        Returns the number of dead planets currently around the star
        '''
        return len(self._planets)
    
    def getNumberOfActivePlanets(self):
        '''
        Returns the number of planets currently orbiting the star
        '''
        total = 0
        for planet in self.planets():
            if(planet.activated):
                total = total + 1
        return total
Exemple #16
0
class Planet(SphericalBody): 
    '''
    Planet contains units and structures
    '''

    def __init__(self, orbital_radius, orbital_angle, radius, parent_star, prev_planet=None, player=None):
        '''
        Constructor for class planet.
        @param position: Point3D, position in space
        @param radius: float, body radius
        @param player: Player, the owner of the planet
        @param parent_star: Star, the specific star the planet is orbiting around
        @param prev_planet: previous planet in the star system, if None then the planet is the first
        '''
        position = Point3(orbital_radius * math.cos(orbital_angle),
                          orbital_radius * math.sin(orbital_angle), 0)
        super(Planet, self).__init__(position, radius, False, player)
        self.orbital_velocity = 0
        self.max_orbital_velocity = 0
        self.orbital_radius = orbital_radius
        self.orbital_angle = orbital_angle
        self.parent_star = parent_star
        self.prev_planet = prev_planet
        self.next_planet = None
        self._orbiting_units = []
        self._surface_structures = []
        self.__initSceneGraph()
               
        '''For the Player'''
        self.task_structure_timer = None
        self.task_unit_timer = None
        '''For the AI'''
        self.task_structure_timers = []
        self.task_unit_timers = []
        
    def __initSceneGraph(self):

        #load various texture stages of the planet
        self.forge_tex = TextureStage('forge')
        self.forge_tex.setMode(TextureStage.MDecal)
        self.nexus_tex = TextureStage('nexus')
        self.nexus_tex.setMode(TextureStage.MDecal)
        self.extractor_phylon_ge_tex = TextureStage('extractor_phylon_ge')
        self.extractor_phylon_ge_tex.setMode(TextureStage.MDecal)
        
        # Parent node for relative position (no scaling)
        self.point_path = self.parent_star.point_path.attachNewNode("planet_node")
        self.point_path.setPos(self.position)
        
        #Models & textures
        self.model_path = loader.loadModel("models/planets/planet_sphere")
        self.model_path.setTexture(SphericalBody.dead_planet_tex, 1)
        self.model_path.reparentTo(self.point_path)
        self.model_path.setScale(self.radius)
        self.model_path.setPythonTag('pyPlanet', self);
        
        cnode = CollisionNode("coll_sphere_node")
        cnode.setTag('planet', str(id(self)))
        #We use no displacement (0,0,0) and no scaling factor (1)
        cnode.addSolid(CollisionSphere(0,0,0,1))
        cnode.setIntoCollideMask(BitMask32.bit(1))
        # Reparenting the collision sphere so that it 
        # matches the planet perfectly.
        self.cnode_path = self.model_path.attachNewNode(cnode)
        
        self.lines = LineNodePath(parent = self.parent_star.point_path, thickness = 4.0, colorVec = Vec4(1.0, 1.0, 1.0, 0.2))
        self.quad_path = None
        
    def setTexture(self, structureType):
        '''
        Used whenever a structure is built on the planet
        @ StructureType is a string specifying the type of the structure
        '''
        if(structureType == "forge"):
            #SphericalBody.planet_forge_tex.setWrapU(Texture.WMInvalid)
            #SphericalBody.planet_forge_tex.setWrapV(Texture.WMInvalid)
            self.model_path.setTexture(self.forge_tex, SphericalBody.planet_forge_tex)
            #self.model_path.getTexture().setWrapU(Texture.WMClamp)
            #self.model_path.getTexture().setWrapV(Texture.WMClamp)
            self.model_path.setTexOffset(self.forge_tex, 0, 0)
            #self.model_path.setTexScale(self.forge_tex, -4, -2)
        elif(structureType == "nexus"):
            self.model_path.setTexture(self.nexus_tex, SphericalBody.planet_nexus_tex)
            self.model_path.setTexOffset(self.nexus_tex, 0, 10)
        elif(structureType == "extractor"):
            self.model_path.setTexture(self.extractor_phylon_ge_tex, SphericalBody.planet_extractor_tex)
            self.model_path.setTexOffset(self.extractor_phylon_ge_tex, 0, 20)
        elif(structureType == "phylon"):
            self.model_path.setTexture(self.extractor_phylon_ge_tex, SphericalBody.planet_phylon_tex)
            self.model_path.setTexOffset(self.extractor_phylon_ge_tex, 0, 20)
        elif(structureType == "generatorCore"):
            self.model_path.setTexture(self.extractor_phylon_ge_tex, SphericalBody.planet_generatorCore_tex)
            self.model_path.setTexOffset(self.extractor_phylon_ge_tex, 0, 20)
    
    def activateHighlight(self, thin):
        if thin:
            flare_tex = base.loader.loadTexture("models/billboards/thin_ring.png")
        else:
            flare_tex = base.loader.loadTexture("models/billboards/ring.png")
        cm = CardMaker('quad')
        cm.setFrameFullscreenQuad() # so that the center acts as the origin (from -1 to 1)
        self.quad_path = self.point_path.attachNewNode(cm.generate())        
        self.quad_path.setTransparency(TransparencyAttrib.MAlpha)
        self.quad_path.setTexture(flare_tex)
        if thin:
            self.quad_path.setColor(Vec4(1,1,1, 1))
        else:
            self.quad_path.setColor(Vec4(0.2, 0.3, 1.0, 1))
        self.quad_path.setScale(5)
        self.quad_path.setPos(Vec3(0,0,0))
        self.quad_path.setBillboardPointEye()
    
    def deactivateHighlight(self):
        if self.quad_path:
            self.quad_path.detachNode()
            self.quad_path = None
    
    def select(self, player):
        '''
        This method observes the events on the planet and calls the related methods
        and notifies the corresponding objects based on the state of the planet
        @param player, the player who has selected
        '''
        player.selected_star = None
        
        if(not self.activated and player.selected_planet == self):
            if((self.prev_planet == None or self.prev_planet.activated) and \
                    self.parent_star.activated and self.parent_star.player == player):
                self.activatePlanet(player)
        else:
#            from gameEngine.gameEngine import all_stars 
#            for star in all_stars:
#                star.deactivateHighlight()
            from gameEngine.gameEngine import all_planets
            for planet in all_planets:
                if(self != planet or self.next_planet != planet or self.prev_planet != planet):
                    planet.deactivateHighlight()
            if self.next_planet != None: self.next_planet.activateHighlight(True) 
            if self.prev_planet != None: self.prev_planet.activateHighlight(True)
            self.activateHighlight(False)
        
        player.selected_planet = self
        
        from gameEngine.gameEngine import updateGUI
        updateGUI.refreshUnitsAndConstructions(self)
        
    def selectRight(self, player):
        '''
        This method observes the events on the planet and calls the related methods
        and notifies the corresponding objects based on the state of the planet
        @param player, the player who has selected with right mouse click
        '''
        move_occured = False
        for selected_unit in player.selected_units:
            if(selected_unit != None and selected_unit.player == player):
                '''movement is inside the solar system'''
                if(selected_unit.host_planet.parent_star == self.parent_star):
                    if(selected_unit.host_planet == self.prev_planet):
                        selected_unit.moveUnitNext()
                        move_occured = True
                    if(selected_unit.host_planet == self.next_planet):
                        selected_unit.moveUnitPrev()   
                        move_occured = True 
                else:
                    '''movement is between solar systems in deep space'''
                    if(self.next_planet == None and selected_unit.host_planet.next_planet == None):
                        selected_unit.moveDeepSpace(self)
                        move_occured = True

        if(len(player.selected_units)!=0 and move_occured):
            if(player.selected_units[0] != None and player.selected_units[0].move_unit != None):
                base.sfxManagerList[0].update()
                player.selected_units[0].move_unit.play()
            
    def activatePlanet(self, player):
        '''
        Activates a constructed dead planet object, starting the orbital movement with the assigned value while
        the Game Engine calls the graphic engine to display the corresponding animation.
        @param player: Player, the player who controls the planet
        @precondition: MIN_PLANET_VELOCITY < orbital_velocity < MAX_PLANET_VELOCITY
        '''
        self.activated = True
        player.planets.append(self)
        self.player = player
        
        
        planet_created_sound = base.loader.loadSfx("sound/effects/planet/planetCreation.wav")
        planet_created_sound.setVolume(0.3)
        planet_created_sound.play()
#        base.sfxManagerList[0].update()
#        SphericalBody.planet_created_sound.play()
        
        self.radius = MAX_PLANET_RADIUS
        self.model_path.setScale(self.radius)
        
        '''TODO : display planet creation animation '''
        
        #rand = random.randrange(1,8,1)
        self.model_path.setTexture(SphericalBody.planet_activated_tex, 1)
        self.startSpin()
        
        # We want to avoid adding this task when the 'collapseOrbit' is already running
        if self.parent_star.lifetime != 0:
            taskMgr.add(self._accelerateOrbit, 'accelerateOrbit')
        
        self.orbit_path = shapes.makeArc(self.player.color, 360, int(self.orbital_radius))
        self.orbit_path.reparentTo(self.parent_star.point_path)
        self.orbit_path.setScale(self.orbital_radius)
        
        from gameModel.ai import AI
        if(type(self.player) != AI):
            from gameEngine.gameEngine import updateGUI
            updateGUI.refreshUnitsAndConstructions(self)
    
    def startSpin(self):
        self.day_period = self.model_path.hprInterval(PLANET_SPIN_VELOCITY, Vec3(360, 0, 0))
        self.day_period.loop()
    
    def startCollapse(self):
        try:
            if self.orbit_task:
                taskMgr.remove(self.orbit_task)
        except AttributeError:
            pass # no orbit on this planet (has not been activated)
        
        taskMgr.add(self._collapseOrbit, 'collapseOrbit')
#        taskMgr.setupTaskChain('collapseChain')
#        taskMgr.add(self._collapseOrbit, 'collapseOrbit')#, taskChain='collapseChain')
#        taskMgr.add(self._consume, 'consumePlanet', taskChain='collapseChain')
#        self.orbitTask = None
    
    def _consume(self):
        self._consumeUnits()
        self._consumeStructures()
        self.removeFromGame()
        
    def _accelerateOrbit(self, task):
        self.orbital_angle = self.orbital_angle + self.orbital_velocity
        self.orbital_angle = math.fmod(self.orbital_angle, 2.0*math.pi);
        self.point_path.setPos(self.orbital_radius * math.cos(self.orbital_angle),
                               self.orbital_radius * math.sin(self.orbital_angle), 0)
        self.position = self.point_path.getPos()
        self.orbital_velocity = self.orbital_velocity + 0.0001
        if self.orbital_velocity > self.max_orbital_velocity:
            self.orbit_task = taskMgr.add(self._stepOrbit, 'stepOrbit')
            return task.done
        else:
            return task.cont
    
    def _stepOrbit(self, task):
        self.orbital_angle = self.orbital_angle + self.orbital_velocity
        self.orbital_angle = math.fmod(self.orbital_angle, 2.0*math.pi)
        self.point_path.setPos(self.orbital_radius * math.cos(self.orbital_angle),
                               self.orbital_radius * math.sin(self.orbital_angle), 0)
        self.position = self.point_path.getPos()
        return task.cont
    
    def _collapseOrbit(self, task):
        self.orbital_radius = self.orbital_radius - 0.23
        self.orbital_angle = self.orbital_angle + self.orbital_velocity
        self.orbital_angle = math.fmod(self.orbital_angle, 2.0*math.pi)
        self.point_path.setPos(self.orbital_radius * math.cos(self.orbital_angle),
                               self.orbital_radius * math.sin(self.orbital_angle), 0)
        self.position = self.point_path.getPos()
#        if self.orbital_velocity < 0.01:
        if self.orbital_radius != 0:
            self.orbital_velocity = self.orbital_velocity + 0.01/(self.orbital_radius**2)
        try:
            self.orbit_path.setScale(self.orbital_radius)
        except AttributeError:
            pass # no orbit on this planet (has not been activated)
        
        if self.orbital_radius <= 0:
            self._consume()
            return task.done
        else:
            return task.cont
        
    
    def drawLines(self): 
        # put some lighting on the line
        # for some reason the ambient and directional light in the environment drain out
        # all other colors in the scene
        # this is a temporary solution just so we can view the lines... the light can be removed and
        #a glow effect will be added later
#        alight = AmbientLight('alight')
#        alnp = render.attachNewNode(alight)
#        alight.setColor(Vec4(0.2, 0.2, 0.2, 1))
#        render.setLight(alnp)
        self.lines.reset()
        self.lines.drawLines([((0,0, 0),
                               (self.point_path.getX(), self.point_path.getY(), 0))])
        self.lines.create()
    
    def drawConnections(self, task):
#        cur_pos = self.point_path.getPos()
#        paired_pos = pairedPlanetDraw.point_path.getPos()
#        paired_pos = self.point_path.getRelativePoint(pairedPlanetDraw.point_path, pairedPlanetDraw.point_path.getPos())
#        print pairedPlanetDraw.point_path.getX(), pairedPlanetDraw.point_path.getY(), pairedPlanetDraw.point_path.getZ()
        self.connections.reset()
        if(self.next_planet):
            point_list = []
            point_list.append((self.point_path.getPos(), self.next_planet.point_path.getPos()))
            self.connections.drawLines(point_list)
            self.connections.create()
        return task.cont
        
    def changePlayer(self, player):
        '''
        Change the control of the planet from the self.player to the parameter player
        @param player: Player, the player who has captured the planet by swarms
        @precondition: the player must have used the capture ability of a swarm type unit on the planet
        '''
        '''TODO: Use makeArc to change the color of the orbit'''
        
        ''' stop any constructions on the planet '''
        if(self.task_structure_timer != None):
            taskMgr.remove(self.task_structure_timer)
            self.task_structure_timer = None
        if(self.task_unit_timer != None):
            taskMgr.remove(self.task_unit_timer)
            self.task_unit_timer = None
        if(self.task_structure_timers != None):
            taskMgr.remove(self.task_structure_timers)
            self.task_structure_timers = None
        if(self.task_unit_timers != None):
            taskMgr.remove(self.task_unit_timers)
            self.task_unit_timers = None
        ''' remove previous player's control from the planet '''
        for structure in self.structures():
            self.player.structures.remove(structure)
        ''' set control of the planet to the new player '''
        for structure in self.structures():
            player.structures.append(structure)
        ''' update the construction panel for the human player'''
        from gameModel.ai import AI
        ''' if human player is the previous owner '''
        if(type(self.player) != AI):
            from gameEngine.gameEngine import updateGUI
            updateGUI.refreshUnitsAndConstructions(self)
        ''' give total control to new player '''
        self.player = player
        ''' if human player is the new owner '''
        if(type(player) != AI):
            from gameEngine.gameEngine import updateGUI
            updateGUI.refreshUnitsAndConstructions(self)
        
    def addOrbitingUnit(self, unit):
        ''' 
        Add a unit to the hosted units by the planet
        @param unit: Orbiting unit object
        '''
        self._orbiting_units.append(unit)
    
    def addOrbitingUnits(self, units):
        '''
        Add a list of units to be hosted by the planet
        @param units: iterable of units
        '''
        self._orbiting_units.extend(units)
    
    def removeOrbitingUnit(self, unit):
        ''' 
        Remove the hosted unit from the planet
        @param unit: Orbiting unit object
        '''
        self._orbiting_units.remove(unit)
    
    def removeOrbitingUnits(self, units):
        ''' 
        Remove many hosted units from the planet
        @param units: List of unit objects
        '''
        self._orbiting_units[:] = [u for u in self._orbiting_units if u not in units]
        
    def units(self):
        '''
        Generator that iterates over the hosted units.
        '''
        for unit in self._orbiting_units:
            yield unit
            
    def unitsOfPlayer(self, player):
        '''
        Generator that iterates over the hosted units belonging to the player.
        @param player, the owner of the units 
        '''
        for unit in self._orbiting_units:
            if unit.player == player:
                yield unit
    
    def unitsOfEnemy(self, player):
        '''
        Generator that iterates over the hosted units not belonging to the player.
        @param player, the owner of the units 
        '''
        for unit in self._orbiting_units:
            if unit.player != player:
                yield unit
    
    def unitsOfEnemyLowestEnergy(self, player):
        '''
        Generator that iterates over the hosted units not belonging to the player
        sorted by lowest energy.
        @param player, the owner of the units 
        '''
        energyList = sorted(self._orbiting_units, key=lambda unit: unit.energy)
        for unit in energyList:
            if unit.player != player:
                yield unit
                
    def getNumberOfUnits(self):
        '''
        Returns the number of hosted units from the planet
        '''
        return len(self._orbiting_units)
    
    def getNumberOfUnitsOfPlayer(self, player):
        '''
        Returns the number of hosted units from the planet that belongs to the player
        @param player, the owner of the units
        '''
        num = 0
        for unit in self._orbiting_units:
            if(unit.player == player):
                num = num + 1
        return num
    
    def _task_unit_timers(self):
        '''
        Generator that iterates over the hosted units construction tasks.
        '''
        for task_unit in self.task_unit_timers:
            yield task_unit
            
    def _task_structure_timers(self):
        '''
        Generator that iterates over the surface structure construction tasks.
        '''
        for task_structure in self.task_structure_timers:
            yield task_structure
            
    def _consumeUnits(self):
        if(self.task_unit_timer!=None):
            taskMgr.remove(self.task_unit_timer)
            self.task_unit_timer = None
            
        for task in self.task_unit_timers:
            taskMgr.remove(task)
        del self.task_unit_timers[:]

        from gameModel.ai import AI        
        for unit in self._orbiting_units:
            unit.player.units.remove(unit)
            if(type(unit.player) != AI):
                try:
                    unit.player.selected_units.remove(unit)
                    print "selected unit"
                except ValueError:
                    pass
            unit.removeFromGame()    
        del self._orbiting_units[:]
        
    def _consumeStructures(self):
        if(self.task_structure_timer!=None):
            taskMgr.remove(self.task_structure_timer)
            self.task_structure_timer = None
        for task in self.task_structure_timers:
            taskMgr.remove(task)
        del self.task_structure_timers[:]

        for structure in self._surface_structures:
            self.player.structures.remove(structure)
        del self._surface_structures[:]
       
    def addSurfaceStructure(self, structure):
        ''' 
        Add a structure to the surface structures by the planet
        @param structure: Surface structure object
        '''
        if(len(self._surface_structures) < MAX_NUMBER_OF_STRUCTURE):
            self._surface_structures.append(structure)
    
    def addSurfaceStructures(self, structures):
        '''
        Add a list of structures to be hosted by the planet
        @param structures: iterable of structure
        '''
        if(len(self._surface_structures) + len(structures) <= MAX_NUMBER_OF_STRUCTURE):
            self._surface_structures.extend(structures)
    
    def removeSurfaceStructure(self, structure):
        ''' 
        Remove the surface structure from the planet
        @param structure: Surface structure object
        '''
        self._surface_structures.remove(structure)
    
    def removeSurfaceStructures(self, structures):
        ''' 
        Remove many surface structures from the planet
        @param structures: List of structure objects
        '''
        self._surface_structures[:] = [s for s in self._surface_structures if s not in structures]
        
    def structures(self):
        '''
        Generator that iterates over the surface structures.
        '''
        for structure in self._surface_structures:
            yield structure
            
    def getNumberOfStructures(self):
        '''
        Returns the number of surface structures from the planet
        '''
        return len(self._surface_structures)
        
    def hasStructure(self, structure):
        '''
        Returns true if a type of the structure already exists on the planet
        @structure: String, the desired structure type
        '''
        from structures import Forge, Nexus, Extractor, Phylon, GeneratorCore,\
            PlanetaryDefenseI, PlanetaryDefenseII, PlanetaryDefenseIII, PlanetaryDefenseIV
        for surface_structure in self._surface_structures:
            if(structure == "forge" and type(surface_structure) == Forge):
                return True
            elif(structure == "nexus" and type(surface_structure) == Nexus):
                return True
            elif(structure == "extractor" and type(surface_structure) == Extractor):
                return True
            elif(structure == "phylon" and type(surface_structure) == Phylon):
                return True
            elif(structure == "generatorCore" and type(surface_structure) == GeneratorCore):
                return True
            elif(structure == "pd1" and type(surface_structure) == PlanetaryDefenseI):
                return True
            elif(structure == "pd2" and type(surface_structure) == PlanetaryDefenseII):
                return True
            elif(structure == "pd3" and type(surface_structure) == PlanetaryDefenseIII):
                return True
            elif(structure == "pd4" and type(surface_structure) == PlanetaryDefenseIV):
                return True
        return False
    
    def removeFromGame(self):
        if(self.next_planet != None):
            self.next_planet.prev_planet = None
        self.point_path.removeNode()
        from player import Player
        if type(self.player) == Player and self.player.selected_planet == self:
            self.player.selected_planet = None
        if(self.player != None):
            self.player.planets.remove(self)
        self.parent_star.removePlanet(self)