class State:
	counter=0
	def __init__(self):
		self.render = None
		self.render2d = None
		self.camera = None
		self.keys = None
		self.node = NodePath("State"+str(State.counter)+"Node")
		self.node2d = NodePath("State"+str(State.counter)+"Node2D")
		State.counter+=1

		# OMG so ugly, sorry
		self.waitTime = 0

	def iterate(self):
		pass

	def register(self, render, camera, keys, render2d=None):
		self.render = render
		self.render2d = render2d
		self.camera = camera
		self.keys = keys
		self.enter()

	def enter(self):
		self.node.reparentTo(self.render)

		if self.render2d:
			self.node2d.reparentTo(self.render2d)

	def exit(self):
		self.node.detachNode()

		if self.render2d:
			self.node2d.detachNode()
Exemple #2
0
class CamManager(DirectObject.DirectObject):
    """1st or 3d person camera, or disable
    """
    def __init__(self, game):
        self.game = game
        self.char = self.game.char
        self.win = self.game.gui.win
        self.hotkeys = self.game.gui.hotkeys
        self.node = NodePath('char')
        self.Ccentr = NodePath('Ccentr')
        self.Ccentr.reparentTo(self.node)
        self.Ccentr.setZ(1)
        self.third_dist = -6
        self.sleep = 0.001
        self.camera = self.game.gui.camera
        self.char.reparentTo(self.node)
        taskMgr.setupTaskChain('cam_move', numThreads = 1,
                       frameSync = False, threadPriority = TPUrgent, timeslicePriority = False)


    def set_enable(self, value, third = False):
        self.enable = value
        self.third = third

        self.node.reparentTo(self.game.world.root_node)
        self.node.setPos(self.game.world.avatar.getPos())
        if self.enable:
            self.camera.reparentTo(self.Ccentr)
            if self.third:
                self.camera.setPos(0, self.third_dist, 0)
                #self.char.show()
            else:
                self.camera.setPos(0, 0, 0)
                #self.char.hide()
            self.camera.lookAt(self.Ccentr)
            taskMgr.add(self.mouse_update, 'mouse-task')
        else:
            self.camera.reparentTo(self.game.world.root_node)
            self.camera.setPos(self.game.world.root_node, self.game.world.avatar.getPos(self.game.world.root_node))
            self.node.detachNode()

    #@profile_decorator
    def mouse_update(self, task):
        """ this task updates the mouse """
        if not self.enable:
            return task.done

        md = base.win.getPointer(0)
        x = md.getX()
        y = md.getY()
        if self.win.movePointer(0, self.win.getXSize()/2, self.win.getYSize()/2):
            self.node.setH(self.node.getH() -  (x - self.win.getXSize()/2)*0.1)
            self.Ccentr.setP(self.Ccentr.getP() - (y - self.win.getYSize()/2)*0.1)

        time.sleep(self.sleep)
        return task.cont

    def point_dist(self, p1, p2):
        return math.sqrt((p1[0]-p2[0])**2+(p1[1]-p2[1])**2+(p1[2]-p2[2])**2)
class DistributedTreasure(DistributedObject):
    notify = directNotify.newCategory('DistributedTreasure')

    def __init__(self, cr):
        DistributedObject.__init__(self, cr)
        self.grabSoundPath = None
        self.rejectSoundPath = 'phase_4/audio/sfx/ring_miss.mp3'
        self.dropShadow = None
        self.treasureTrack = None
        self.nodePath = None
        self.modelPath = None
        self.modelChildString = None
        self.sphereRadius = 2.0
        self.scale = 1.0
        self.zOffset = 0.0
        self.playSoundForRemoteToons = True
        self.fly = True
        self.shadow = True
        self.billboard = False
        self.av = None
        return

    def announceGenerate(self):
        DistributedObject.announceGenerate(self)
        self.loadModel(self.modelPath, self.modelChildString)
        self.startAnimation()
        self.nodePath.reparentTo(render)
        self.accept(self.uniqueName('entertreasureSphere'), self.handleEnterSphere)

    def loadModel(self, mdlPath, childString = None):
        self.grabSound = base.loadSfx(self.grabSoundPath)
        self.rejectSound = base.loadSfx(self.rejectSoundPath)
        if self.nodePath == None:
            self.makeNodePath()
        else:
            self.treasure.getChildren().detach()
        model = loader.loadModel(mdlPath)
        if childString:
            model = model.find('**/' + childString)
        model.instanceTo(self.treasure)
        return

    def makeNodePath(self):
        self.nodePath = NodePath('treasure')
        if self.billboard:
            self.nodePath.setBillboardPointEye()
        self.nodePath.setScale(0.9 * self.scale)
        self.treasure = self.nodePath.attachNewNode('treasure')
        if self.shadow:
            if not self.dropShadow:
                self.dropShadow = loader.loadModel('phase_3/models/props/drop_shadow.bam')
                self.dropShadow.setColor(0, 0, 0, 0.5)
                self.dropShadow.setPos(0, 0, 0.025)
                self.dropShadow.setScale(0.4 * self.scale)
                self.dropShadow.flattenLight()
            self.dropShadow.reparentTo(self.nodePath)
        collSphere = CollisionSphere(0, 0, 0, self.sphereRadius)
        collSphere.setTangible(0)
        collNode = CollisionNode(self.uniqueName('treasureSphere'))
        collNode.setIntoCollideMask(CIGlobals.WallBitmask)
        collNode.addSolid(collSphere)
        self.collNodePath = self.nodePath.attachNewNode(collNode)
        self.collNodePath.stash()

    def handleEnterSphere(self, collEntry = None):
        localAvId = base.localAvatar.doId
        if not self.fly:
            self.setGrab(localAvId)
        self.d_requestGrab()

    def setPosition(self, x, y, z):
        if not self.nodePath:
            self.makeNodePath()
        self.nodePath.reparentTo(render)
        self.nodePath.setPos(x, y, z + self.zOffset)
        self.collNodePath.unstash()

    def setReject(self):
        self.cleanupTrack()
        base.playSfx(self.rejectSound, node=self.nodePath)
        self.treasureTrack = Sequence(LerpColorScaleInterval(self.nodePath, 0.8, colorScale=VBase4(0, 0, 0, 0), startColorScale=VBase4(1, 1, 1, 1), blendType='easeIn'), LerpColorScaleInterval(self.nodePath, 0.2, colorScale=VBase4(1, 1, 1, 1), startColorScale=VBase4(0, 0, 0, 0), blendType='easeOut', name='treasureFlyTrack'))
        self.treasureTrack.start()

    def setGrab(self, avId):
        self.collNodePath.stash()
        self.avId = avId
        if self.cr.doId2do.has_key(avId):
            self.av = self.cr.doId2do[avId]
        else:
            self.nodePath.detachNode()
            return
        if self.playSoundForRemoteToons or self.avId == base.localAvatar.doId:
            base.playSfx(self.grabSound, node=self.nodePath)
        if not self.fly:
            self.nodePath.detachNode()
            return
        self.cleanupTrack()
        avatarGoneName = self.av.uniqueName('disable')
        self.accept(avatarGoneName, self.handleUnexpectedExit)
        flyTime = 1.0
        track = Sequence(LerpPosInterval(self.nodePath, flyTime, pos=Point3(0, 0, 3), startPos=self.nodePath.getPos(self.av), blendType='easeInOut'), Func(self.nodePath.detachNode), Func(self.ignore, avatarGoneName))
        if self.shadow:
            self.treasureTrack = Sequence(HideInterval(self.dropShadow), track, ShowInterval(self.dropShadow), name='treasureFlyTrack')
        else:
            self.treasureTrack = Sequence(track, name='treasureFlyTrack')
        self.nodePath.reparentTo(self.av)
        self.treasureTrack.start()

    def handleUnexpectedExit(self):
        self.notify.warning('%s disconnected while collecting treasure.' % str(self.avId))
        self.cleanupTrack()

    def d_requestGrab(self):
        self.sendUpdate('requestGrab', [])

    def startAnimation(self):
        pass

    def disable(self):
        self.ignoreAll()
        self.nodePath.detachNode()
        DistributedObject.disable(self)

    def cleanupTrack(self):
        if self.treasureTrack:
            self.treasureTrack.finish()
            self.treasureTrack = None
        return

    def delete(self):
        self.cleanupTrack()
        DistributedObject.delete(self)
        self.nodePath.removeNode()
Exemple #4
0
class StaticGeometricModel(object):
    """
    load an object as a static geometric model -> changing pos, rot, color, etc. are not allowed
    there is no extra elements for this model, thus is much faster
    author: weiwei
    date: 20190312
    """
    def __init__(self,
                 initor=None,
                 name="defaultname",
                 btransparency=True,
                 btwosided=False):
        """
        :param initor: path type defined by os.path or trimesh or nodepath
        :param btransparency
        :param name
        """
        if isinstance(initor, StaticGeometricModel):
            self._objpath = copy.deepcopy(initor.objpath)
            self._objtrm = copy.deepcopy(initor.objtrm)
            self._objpdnp = copy.deepcopy(initor.objpdnp)
            self._name = copy.deepcopy(initor.name)
            self._localframe = copy.deepcopy(initor.localframe)
        else:
            # make a grandma nodepath to separate decorations (-autoshader) and raw nodepath (+autoshader)
            self._name = name
            self._objpdnp = NodePath(name)
            if isinstance(initor, str):
                self._objpath = initor
                self._objtrm = da.trm.load(self._objpath)
                objpdnp_raw = da.trimesh_to_nodepath(self._objtrm,
                                                     name='pdnp_raw')
                objpdnp_raw.reparentTo(self._objpdnp)
            elif isinstance(initor, da.trm.Trimesh):
                self._objpath = None
                self._objtrm = initor
                objpdnp_raw = da.trimesh_to_nodepath(self._objtrm)
                objpdnp_raw.reparentTo(self._objpdnp)
            elif isinstance(initor, o3d.geometry.PointCloud
                            ):  # TODO should pointcloud be pdnp or pdnp_raw
                self._objpath = None
                self._objtrm = da.trm.Trimesh(np.asarray(initor.points))
                objpdnp_raw = da.nodepath_from_points(self._objtrm.vertices,
                                                      name='pdnp_raw')
                objpdnp_raw.reparentTo(self._objpdnp)
            elif isinstance(
                    initor,
                    np.ndarray):  # TODO should pointcloud be pdnp or pdnp_raw
                self._objpath = None
                if initor.shape[1] == 3:
                    self._objtrm = da.trm.Trimesh(initor)
                    objpdnp_raw = da.nodepath_from_points(
                        self._objtrm.vertices)
                elif initor.shape[1] == 7:
                    self._objtrm = da.trm.Trimesh(initor[:, :3])
                    objpdnp_raw = da.nodepath_from_points(
                        self._objtrm.vertices, initor[:, 3:].tolist())
                    objpdnp_raw.setRenderMode(RenderModeAttrib.MPoint, 3)
                else:
                    # TODO depth UV?
                    raise NotImplementedError
                objpdnp_raw.reparentTo(self._objpdnp)
            elif isinstance(initor, o3d.geometry.TriangleMesh):
                self._objpath = None
                self._objtrm = da.trm.Trimesh(
                    vertices=initor.vertices,
                    faces=initor.triangles,
                    face_normals=initor.triangle_normals)
                objpdnp_raw = da.trimesh_to_nodepath(self._objtrm,
                                                     name='pdnp_raw')
                objpdnp_raw.reparentTo(self._objpdnp)
            elif isinstance(initor, NodePath):
                self._objpath = None
                self._objtrm = None  # TODO nodepath to trimesh?
                objpdnp_raw = initor
                objpdnp_raw.reparentTo(self._objpdnp)
            else:
                self._objpath = None
                self._objtrm = None
                objpdnp_raw = NodePath("pdnp_raw")
                objpdnp_raw.reparentTo(self._objpdnp)
            if btransparency:
                self._objpdnp.setTransparency(TransparencyAttrib.MDual)
            if btwosided:
                self._objpdnp.getChild(0).setTwoSided(True)
            self._localframe = None

    @property
    def name(self):
        # read-only property
        return self._name

    @property
    def objpath(self):
        # read-only property
        return self._objpath

    @property
    def objpdnp(self):
        # read-only property
        return self._objpdnp

    @property
    def objpdnp_raw(self):
        # read-only property
        return self._objpdnp.getChild(0)

    @property
    def objtrm(self):
        # read-only property
        # 20210328 comment out, allow None
        # if self._objtrm is None:
        #     raise ValueError("Only applicable to models with a trimesh!")
        return self._objtrm

    @property
    def localframe(self):
        # read-only property
        return self._localframe

    @property
    def volume(self):
        # read-only property
        if self._objtrm is None:
            raise ValueError("Only applicable to models with a trimesh!")
        return self._objtrm.volume

    def set_rgba(self, rgba):
        self._objpdnp.setColor(rgba[0], rgba[1], rgba[2], rgba[3])

    def get_rgba(self):
        return da.pdv4_to_npv4(
            self._objpdnp.getColor())  # panda3d.core.LColor -> LBase4F

    def clear_rgba(self):
        self._objpdnp.clearColor()

    def set_scale(self, scale=[1, 1, 1]):
        self._objpdnp.setScale(scale[0], scale[1], scale[2])
        self._objtrm.apply_scale(scale)

    def get_scale(self):
        return da.pdv3_to_npv3(self._objpdnp.getScale())

    def set_vert_size(self, size=.005):
        self.objpdnp_raw.setRenderModeThickness(size * 1000)

    def attach_to(self, obj):
        if isinstance(obj, ShowBase):
            # for rendering to base.render
            self._objpdnp.reparentTo(obj.render)
        elif isinstance(obj, StaticGeometricModel
                        ):  # prepared for decorations like local frames
            self._objpdnp.reparentTo(obj.objpdnp)
        elif isinstance(obj, mc.ModelCollection):
            obj.add_gm(self)
        else:
            print(
                "Must be ShowBase, modeling.StaticGeometricModel, GeometricModel, CollisionModel, or CollisionModelCollection!"
            )

    def detach(self):
        self._objpdnp.detachNode()

    def remove(self):
        self._objpdnp.removeNode()

    def show_localframe(self):
        self._localframe = gen_frame()
        self._localframe.attach_to(self)

    def unshow_localframe(self):
        if self._localframe is not None:
            self._localframe.remove()
            self._localframe = None

    def copy(self):
        return copy.deepcopy(self)
    def create_all_text(self):
        self.continue_text = OnscreenText(**{
            "text": (
                "In a moment, you will be asked the question displayed on "
                "the left.  When you are ready, press the spacebar to begin."),
            "style": 1,
            "fg": (.75, 0, 0, 1),
            "bg": self.text_bg,
            "pos": (.4, .4),
            "align": TextNode.ACenter,
            "scale": .08,
            "font": self.font,
            "wordwrap": 20
        })
        self.text_parent = self.continue_text.getParent()
        self.continue_text.detachNode()

        xpos = -1.25
        skip = .15
        self.question_text = OnscreenText(**{
            "text": self.question[0],
            "style": 1,
            "fg": (0, 0, .8, 1),
            "bg": self.text_bg,
            "pos": ((xpos + .05), .8),
            "align": TextNode.ALeft,
            "scale": .075,
            "font": self.font,
            "wordwrap": 35})

        self.question_choice_text = []
        for i in xrange(len(self.question[1])):
            n = len(self.question[1]) - i - 1
            ypos = self.choice_text_start - (skip * n)

            t1 = OnscreenText(**{
                "text": "%s" % self.question[1][i][0],
                "style": 1,
                "fg": (0, .1, 0, 1),
                "bg": self.text_bg,
                "pos": ((xpos + .1), ypos),
                "align": TextNode.ALeft,
                "scale": .075,
                "font": self.font})

            t2 = OnscreenText(**{
                "text": "%s" % self.question[1][i][1],
                "style": 1,
                "fg": (0, .1, 0, 1),
                "bg": self.text_bg,
                "pos": ((xpos + 0.17), ypos),
                "align": TextNode.ALeft,
                "scale": .05,
                "font": self.font})

            t = NodePath("choice_%s" % i)
            t.reparentTo(self.text_parent)
            t1.reparentTo(t)
            t2.reparentTo(t)
            self.question_choice_text.append(t)

        for t in self.question_choice_text:
            t.detachNode()

        self.trials_remaining_text = OnscreenText(**{
            "text": "",
            "style": 1,
            "fg": (0, 0, 0, 1),
            "bg": self.text_bg,
            "pos": (-xpos, -.95),
            "align": TextNode.ARight,
            "scale": .05,
            "font": self.font})
Exemple #6
0
class FancyLoadingScreen(DirectObject.DirectObject):
    notify = DirectNotifyGlobal.directNotify.newCategory('LoadingScreen')
    
    def __init__(self, parent):
        DirectObject.DirectObject.__init__(self)
        self.debugMode = config.GetInt('loading-screen') == 2
        self.parent = parent
        self.state = False
        self.currScreenshot = None
        self.snapshot = None
        self.snapshotFrame = None
        self.snapshotFrameBasic = None
        self.currentTime = 0
        self.analyzeMode = False
        self.loadScale = 1.0
        self.unmappedTicks = []
        self.stepInfo = { }
        self.accept(base.win.getWindowEvent(), self.adjustSize)
        self.accept('tick', self.tick)
        self.currStage = 'unmapped'
        self.stagePercent = 0
        self.numObjects = 0
        self.currPercent = 0.0
        self.line = LineSegs()
        self.line.setColor((0, 0, 0, 1))
        self.line.setThickness(1)
        self.stageLabel = None
        self.currNum = 0
        self.overallPercent = 0
        self.lastPercent = 0
        self.topLock = aspect2dp.attachNewNode('topShift')
        self.root = self.topLock.attachNewNode('loadingScreenRoot')
        self.root.setZ(-1)
        self.root.stash()
        self.model = loader.loadModel('models/gui/pir_m_gui_gen_loadScreen.bam')
        self.model.setP(90)
        self.model.reparentTo(self.root)
        cm = CardMaker('backdrop')
        cm.setFrame(-10, 10, -10, 10)
        if self.debugMode:
            self.backdrop = self.root.attachNewNode(cm.generate())
            self.backdrop.setX(-1.5)
            self.backdrop.setZ(-1)
            self.backdrop.setScale(4)
            self.backdrop.setColor(0.5, 0.5, 0.5, 1)
            cm = CardMaker('loadingBarBase')
            cm.setFrame(-0.90000000000000002, 0.90000000000000002, 0.10000000000000001, 0.5)
            self.loadingBarBacking = self.root.attachNewNode(cm.generate())
            self.loadingBarRoot = self.root.attachNewNode('loadingBarRoot')
            cm.setName('analysisBarBase')
            cm.setFrame(-0.90000000000000002, 0.90000000000000002, -0.5, -0.10000000000000001)
            self.analysisBar = self.root.attachNewNode(cm.generate())
            self.analysisBarRoot = self.root.attachNewNode('analysisBarRoot')
            self.analysisBar.hide()
            self.analysisButtons = []
            self.enterToContinue = DirectLabel(parent = self.root, text = 'Press Shift To Continue', relief = None, text_scale = 0.10000000000000001, pos = (0, 0, -0.90000000000000002), text_align = TextNode.ACenter)
            self.enterToContinue.hide()
            self.stageLabel = DirectLabel(parent = self.root, text = '', relief = None, text_scale = 0.10000000000000001, pos = (-1.25, 0, 0.75), text_align = TextNode.ALeft, textMayChange = 1)
            self.tickLabel = DirectLabel(parent = self.root, text = '', relief = None, text_scale = 0.10000000000000001, pos = (0.75, 0, 0.75), textMayChange = 1)
            self.overallLabel = DirectLabel(parent = self.root, text = '', relief = None, text_scale = 0.10000000000000001, pos = (0, 0, -0.75), textMayChange = 1)
        else:
            self.backdrop = loader.loadModel('models/gui/pir_m_gui_gen_loadScreen')
            self.backdrop.reparentTo(self.root)
            bg = self.backdrop.find('**/expandable_bg')
            bg.setScale(1000, 1, 1000)
            bg.flattenStrong()
            self.backdrop.find('**/loadbar_grey').setColorScale(0.14999999999999999, 0.14999999999999999, 0.14999999999999999, 0.10000000000000001)
            self.loadingBar = self.backdrop.find('**/loadbar')
            self.loadingBar.setColorScale(0.20000000000000001, 0.59999999999999998, 0.5, 1)
            self.loadingPlank = NodePathCollection()
            self.loadingPlank.addPath(self.backdrop.find('**/plank_loading_bar'))
            self.loadingPlank.addPath(self.backdrop.find('**/loadbar'))
            self.loadingPlank.addPath(self.backdrop.find('**/loadbar_frame'))
            self.loadingPlank.addPath(self.backdrop.find('**/loadbar_grey'))
            self.titlePlank = self.backdrop.find('**/plank_title')
            self.percentLabel = DirectLabel(text = '0%', parent = self.root, relief = None, text_font = PiratesGlobals.getPirateFont(), text_fg = PiratesGuiGlobals.TextFG2, text_shadow = PiratesGuiGlobals.TextShadow, text_scale = 0.031, pos = (0, 0, -0.44450000000000001), textMayChange = 1)
            self.loadingPlank.addPath(self.percentLabel)
            self.screenshot = self.backdrop.find('**/screenshot')
            copyGeom = self.loadingBar.find('**/+GeomNode').node().getGeom(0)
            format = copyGeom.getVertexData().getFormat()
            primitive = copyGeom.getPrimitive(0)
            data = GeomVertexData(self.screenshot.node().getGeom(0).getVertexData())
            data.setFormat(format)
            writer = GeomVertexWriter(data, 'texcoord')
            writer.setData2f(0, 0)
            writer.setData2f(1, 0)
            writer.setData2f(1, 1)
            writer.setData2f(0, 1)
            geom = Geom(data)
            geom.addPrimitive(primitive)
            self.screenshot.node().removeGeom(0)
            self.screenshot.node().addGeom(geom)
            self.titlePlankMiddle = self.backdrop.find('**/plank_title_middle_box')
            self.titlePlankLeft = self.backdrop.find('**/plank_title_left')
            self.titlePlankRight = self.backdrop.find('**/plank_title_right')
        self.loadingBarColors = [ (((i % 10) / 10.0 + 0.5) / 2.0, ((i % 100) / 10 / 10.0 + 0.5) / 2.0, (i / 100 / 10.0 + 0.5) / 2.0, 1) for i in range(1000) ]
        random.shuffle(self.loadingBarColors)
        self.lastUpdateTime = globalClock.getRealTime()
        self.locationLabel = DirectLabel(parent = self.root, relief = None, text = '', text_font = PiratesGlobals.getPirateOutlineFont(), text_fg = PiratesGuiGlobals.TextFG1, text_shadow = PiratesGuiGlobals.TextShadow, text_scale = PiratesGuiGlobals.TextScaleTitleJumbo * 0.69999999999999996, text_align = TextNode.ACenter, pos = (0.0, 0.0, 0.51500000000000001), textMayChange = 1)
        self.locationText = None
        self.hintLabel = DirectLabel(parent = self.root, relief = None, text = '', text_font = PiratesGlobals.getPirateOutlineFont(), text_fg = PiratesGuiGlobals.TextFG1, text_shadow = PiratesGuiGlobals.TextShadow, text_scale = PiratesGuiGlobals.TextScaleTitleJumbo * 0.5, text_align = TextNode.ACenter, pos = (0.0, 0.0, -0.62), text_wordwrap = 30, textMayChange = 1)
        self.hintText = None
        self.adImage = None
        self.allowLiveFlatten = ConfigVariableBool('allow-live-flatten')
        self.title_art = []
        self.tempVolume = []
        self.adjustSize(base.win)
        gsg = base.win.getGsg()
        if gsg:
            self.root.prepareScene(gsg)
        

    
    def startLoading(self, expectedLoadScale):
        if not self.debugMode:
            self.loadingBar.setSx(0)
        
        self.loadScale = float(expectedLoadScale)
        self.currStage = 'unmapped'
        self.stagePercent = 0
        self.numObjects = 0
        self.currPercent = 0.0
        self.loadingStart = globalClock.getRealTime()
        self.currNum = 0
        self.overallPercent = 0
        self.lastPercent = 0
        self.stepNum = 0
        if self.debugMode:
            self.overallLabel['text'] = '0.0'
            self.stageLabel['text'] = self.currStage
        
        self.update()

    
    def beginStep(self, stageName, amt = 0, percent = 0.001):
        if not self.state:
            return None
        
        if self.currStage != 'unmapped' and stageName != self.currStage:
            if __dev__ and self.debugMode:
                self.notify.error('step %s not finished when step %s was started!' % (self.currStage, stageName))
            else:
                self.notify.warning('step %s not finished when step %s was started!' % (self.currStage, stageName))
                return None
        
        self.stepNum += 1
        if self.debugMode:
            stageColor = self.loadingBarColors[self.stepNum]
            self.stepInfo[stageName] = [
                globalClock.getRealTime() - self.loadingStart,
                0.0,
                stageColor,
                [],
                self.lastPercent + self.stagePercent,
                percent,
                amt]
            self.stepCard = CardMaker('step-%s' % stageName)
            self.stepCard.setColor(stageColor)
            self.currPoly = NodePath('empty')
            self.stageLabel['text'] = stageName
            self.tickLabel['text'] = '0.0'
        
        self.currPercent = 0.0
        self.overallPercent = min(100.0 * self.loadScale, self.lastPercent + self.stagePercent)
        self.lastPercent = self.overallPercent
        self.currStage = stageName
        self.stagePercent = percent
        self.numObjects = amt
        self.currNum = 0
        base.graphicsEngine.renderFrame()
        base.graphicsEngine.renderFrame()

    
    def endStep(self, stageName):
        if self.currStage == 'unmapped':
            self.notify.warning('step %s was started before loading screen was enabled' % stageName)
            return None
        
        if stageName != self.currStage:
            if __dev__ and self.debugMode:
                self.notify.error('step %s was active while step %s was trying to end!' % (self.currStage, stageName))
            else:
                return None
        
        self.tick()
        if self.debugMode:
            stageInfo = self.stepInfo[self.currStage]
            stageInfo[1] = globalClock.getRealTime() - self.loadingStart - stageInfo[0]
            self.currPoly.detachNode()
            self.stepCard.setFrame((self.lastPercent / self.loadScale) * 0.017999999999999999 - 0.90000000000000002, ((self.lastPercent + self.stagePercent) / self.loadScale) * 0.017999999999999999 - 0.90000000000000002, 0.10000000000000001, 0.5)
            self.loadingBarRoot.attachNewNode(self.stepCard.generate())
            self.stageLabel['text'] = 'unmapped'
        
        self.currStage = 'unmapped'
        self.currPercent = 0.0

    
    def tick(self):
        if self.state == False or self.analyzeMode:
            return None
        
        if self.debugMode:
            if self.currStage == 'unmapped':
                self.unmappedTicks.append(globalClock.getRealTime() - self.loadingStart)
            else:
                self.stepInfo[self.currStage][3].append(globalClock.getRealTime() - self.loadingStart)
        
        self.currNum += 1
        self.currPercent = min(1.0, self.currNum / float(self.numObjects + 1))
        self.overallPercent = min(100.0 * self.loadScale, self.lastPercent + self.currPercent * self.stagePercent)
        self.update()

    
    def destroy(self):
        taskMgr.remove('updateLoadingScreen')
        for part in (self.model, self.snapshot):
            if part is not None:
                tex = part.findTexture('*')
                if tex:
                    tex.releaseAll()
                
                part.removeNode()
        
        self.model = None
        self.snapshot = None
        if self.snapshotFrame:
            self.snapshotFrame.destroy()
        
        if self.snapshotFrameBasic:
            self.snapshotFrameBasic.destroy()
        
        if self.locationLabel:
            self.locationLabel.destroy()
        
        if self.hintLabel:
            self.hintLabel.destroy()
        
        if self.debugMode:
            self.stageLabel.destroy()
            self.tickLabel.destroy()
            self.overallLabel.destroy()
            self.enterToContinue.destroy()
            self.stageLabel = None
            self.tickLabel = None
            self.overallLabel = None
            self.enterToContinue = None
        
        self.ignoreAll()

    
    def showTitleFrame(self):
        if base.config.GetBool('no-loading-screen', 0):
            return None
        
        for part in self.title_art:
            part.show()
        

    
    def hideTitleFrame(self):
        for part in self.title_art:
            part.hide()
        

    
    def show(self, waitForLocation = False, disableSfx = True, expectedLoadScale = 1.0):
        if self.state and base.config.GetBool('no-loading-screen', 0) or not (self.locationLabel):
            return None
        
        render.hide()
        render2d.hide()
        render2dp.hide()
        if not self.debugMode:
            self.loadingPlank.hide()
        
        self.root.unstash()
        self.root.showThrough()
        self.state = True
        gsg = base.win.getGsg()
        if gsg:
            gsg.setIncompleteRender(False)
        
        base.setTaskChainNetNonthreaded()
        self.allowLiveFlatten.setValue(1)
        self.startLoading(expectedLoadScale)
        base.graphicsEngine.renderFrame()
        base.graphicsEngine.renderFrame()
        base.refreshAds()
        taskMgr.add(self.update, 'updateLoadingScreen', priority = -100)
        if base.sfxManagerList and disableSfx:
            index = 0
            while index < len(base.sfxManagerList):
                sfx_manager = base.sfxManagerList[index]
                sfx_manager.setVolume(0.0)
                index += 1
        
        if base.appRunner:
            base.appRunner.notifyRequest('onLoadingMessagesStart')
        
        self._FancyLoadingScreen__setLocationText(self.locationText)
        self._FancyLoadingScreen__setHintText(self.hintText)
        if not waitForLocation:
            screenshot = random.choice(tutorialShots_MoveAim)
            self._FancyLoadingScreen__setLoadingArt(screenshot)
        

    
    def showHint(self, destId = None, ocean = False):
        if base.config.GetBool('no-loading-screen', 0) or not (self.locationLabel):
            return None
        
        if ocean:
            hint = getOceanHint()
        elif hasattr(base, 'localAvatar'):
            totalReputation = 0
            level = base.localAvatar.getLevel()
            if totalReputation:
                hint = getHint(destId, level)
            else:
                hint = getHint(destId)
        else:
            hint = getHint()
        shipPVPIslands = [
            '1196970035.53sdnaik',
            '1196970080.56sdnaik']
        if (destId in shipPVPIslands or ocean) and base.localAvatar.getCurrentIsland() in shipPVPIslands:
            hint = getPrivateeringHint()
        
        if self.parent and base.localAvatar.style.getTutorial() == PiratesGlobals.TUT_MET_JOLLY_ROGER:
            hint = '%s:  %s' % (PLocalizer.LoadingScreen_Hint, PLocalizer.GeneralTip7)
        
        self._FancyLoadingScreen__setHintText(hint)

    
    def update(self, task = None):
        if not (self.state) or self.analyzeMode:
            return Task.cont
        
        realTime = globalClock.getRealTime()
        if realTime - self.lastUpdateTime < 0.10000000000000001:
            return Task.cont
        
        self.currentTime += min(10, (realTime - self.lastUpdateTime) * 250)
        self.lastUpdateTime = realTime
        if self.debugMode:
            self.overallLabel['text'] = '%3.1f' % (self.overallPercent / self.loadScale)
            self.tickLabel['text'] = '%3.1f' % (self.currPercent * 100.0)
        else:
            self.percentLabel['text'] = '%d%%' % (self.overallPercent / self.loadScale)
        if self.currStage != 'unmapped':
            if self.debugMode:
                self.currPoly.detachNode()
                self.stepCard.setFrame((self.lastPercent / self.loadScale) * 0.017999999999999999 - 0.90000000000000002, (self.overallPercent / self.loadScale) * 0.017999999999999999 - 0.90000000000000002, 0.20000000000000001, 0.40000000000000002)
                self.currPoly = self.loadingBarRoot.attachNewNode(self.stepCard.generate())
            
        
        if not self.debugMode:
            self.loadingBar.setSx((self.overallPercent / self.loadScale) * 3.3999999999999999)
            if self.overallPercent > 0:
                self.loadingPlank.show()
            
        
        base.eventMgr.doEvents()
        base.graphicsEngine.renderFrame()
        return Task.cont

    
    def hide(self, reallyHide = not (config.GetInt('loading-screen', 0) == 2)):
        if not self.state:
            return None
        
        if not reallyHide:
            if not self.analyzeMode:
                self.loadingEnd = globalClock.getRealTime()
                self.accept('shift', self.hide, extraArgs = [
                    1])
                self.enterToContinue.show()
                self.generateAnalysis()
            
            return None
        
        self.cleanupLoadingScreen()
        if self.debugMode:
            self.enterToContinue.hide()
            self.ignore('shift')
        
        self.root.hide()
        self.root.stash()
        render2d.show()
        render2dp.show()
        render.show()
        base.graphicsEngine.renderFrame()
        self.state = False
        self.currentTime = 0
        self.locationText = None
        self.hintText = None
        self.currScreenshot = None
        gsg = base.win.getGsg()
        if gsg:
            gsg.setIncompleteRender(True)
            render.prepareScene(gsg)
            render2d.prepareScene(gsg)
        
        taskMgr.remove('updateLoadingScreen')
        self.allowLiveFlatten.clearValue()
        base.setTaskChainNetThreaded()
        if base.sfxManagerList:
            index = 0
            while index < len(base.sfxManagerList):
                sfx_manager = base.sfxManagerList[index]
                sfx_manager.setVolume(base.options.sound_volume)
                index += 1
        
        messenger.send('texture_state_changed')
        if base.appRunner:
            base.appRunner.notifyRequest('onLoadingMessagesStop')
        

    
    def showTarget(self, targetId = None, ocean = False, jail = False, pickapirate = False, exit = False, potionCrafting = False, benchRepair = False, shipRepair = False, cannonDefense = False, fishing = False):
        if base.config.GetBool('no-loading-screen', 0):
            return None
        
        if pickapirate:
            screenshot = screenShot_EnterGame
        elif exit:
            screenshot = screenShot_ExitGame
        elif ocean:
            screenshot = screenShot_Dinghy
        elif jail:
            screenshot = screenShot_Jail
        elif potionCrafting:
            screenshot = screenShot_Potions
        elif benchRepair:
            screenshot = screenShot_BenchRepair
        elif shipRepair:
            screenshot = screenShot_ShipRepair
        elif cannonDefense:
            screenshot = screenShot_CannonDefense
        elif fishing:
            screenshot = screenShot_Fishing
        elif base.localAvatar.style.getTutorial() < PiratesGlobals.TUT_GOT_CUTLASS:
            screenshot = screenShot_Weapon
        elif base.localAvatar.style.getTutorial() < PiratesGlobals.TUT_MET_JOLLY_ROGER:
            screenshot = screenShot_Cutlass
        elif base.cr.newsManager and base.cr.newsManager.getHoliday(21):
            screenshot = screenShots_WinterHolidayLocations.get(targetId)
            if not screenshot:
                screenshot = screenShots_Locations.get(targetId)
            
        else:
            screenshot = screenShots_Locations.get(targetId)
        if not screenshot:
            if areaType_Jungles.has_key(targetId):
                screenshot = random.choice(screenShots_Jungles)
            elif areaType_Swamps.has_key(targetId):
                screenshot = random.choice(screenShots_Swamps)
            elif areaType_Caves.has_key(targetId):
                screenshot = random.choice(screenShots_Caves)
            else:
                island = getParentIsland(targetId)
                screenshot = screenShots_Locations.get(island, [
                    random.choice(screenShots)])[0]

        if isinstance(screenshot, list):
            screenshot = random.choice(screenshot)

        self._FancyLoadingScreen__setLoadingArt(screenshot)

        if pickapirate:
            targetName = PLocalizer.LoadingScreen_PickAPirate
        elif exit:
            targetName = None
        elif ocean:
            targetName = PLocalizer.LoadingScreen_Ocean
        elif jail:
            targetName = PLocalizer.LoadingScreen_Jail
        else:
            targetName = PLocalizer.LocationNames.get(targetId)
        base.setLocationCode('Loading: %s' % targetName)
        if targetName is None:
            return None
        
        if len(targetName):
            self._FancyLoadingScreen__setLocationText(targetName)
        

    
    def _FancyLoadingScreen__setLoadingArt(self, screenshot):
        if self.currScreenshot:
            return None
        
        if self.parent and hasattr(base, 'localAvatar') and base.localAvatar.style.getTutorial() < PiratesGlobals.TUT_MET_JOLLY_ROGER and screenshot not in tutorialShots:
            screenshot = random.choice(tutorialShots)
        
        try:
            self.currScreenshot = loader.loadModel(screenshot).findAllTextures()[0]
        except:
            self.currScreenshot = loader.loadModel(random.choice(screenshot)).findAllTextures()[0]

        if not self.debugMode:
            self.screenshot.setTexture(self.currScreenshot)
        

    
    def _FancyLoadingScreen__setLocationText(self, locationText):
        if self.debugMode:
            return None
        
        self.locationText = locationText
        if not self.locationText:
            self.locationText = ''
            self.titlePlank.hide()
        
        if len(self.locationText) > 12:
            scaleFactor = len(self.locationText) / 12.0
            self.titlePlankMiddle.setSx(scaleFactor)
            self.titlePlankRight.setX(0.215 * scaleFactor - 0.215)
            self.titlePlankLeft.setX(-1 * (0.215 * scaleFactor - 0.215))
        else:
            self.titlePlankMiddle.setSx(1)
            self.titlePlankRight.setX(0)
            self.titlePlankLeft.setX(0)
        self.locationLabel['text'] = self.locationText
        if self._FancyLoadingScreen__isVisible() and len(self.locationText):
            self.locationLabel.show()
            self.titlePlank.show()
        else:
            self.locationLabel.hide()
            self.titlePlank.hide()
        launcher.setValue('gameLocation', self.locationText)

    
    def _FancyLoadingScreen__setHintText(self, hintText):
        self.hintText = hintText
        if not self.hintText:
            self.hintText = ''
        
        self.hintLabel['text'] = self.hintText
        if self._FancyLoadingScreen__isVisible():
            self.hintLabel.show()
        

    
    def _FancyLoadingScreen__isVisible(self):
        return self.state

    
    def scheduleHide(self, function):
        base.cr.queueAllInterestsCompleteEvent()
        self.acceptOnce(function, self.interestComplete)

    
    def interestComplete(self):
        self.endStep('scheduleHide')
        self.hide()

    
    def _FancyLoadingScreen__setAdArt(self):
        return None
        imageFrame = self.model.find('**/frame')
        randomImageNumber = random.randint(0, len(screenShots) - 1)
        imageFileName = screenShots[randomImageNumber]
        self.adImage = loader.loadModel(imageFileName)
        self.adImage.reparentTo(imageFrame)
        self.adImage.setScale(2.1499999999999999 * 5, 1, 1.2 * 5)
        self.adImage.setPos(0, 0, 2.2999999999999998)
        self.adImage.setBin('fixed', 1)
        if randomImageNumber == 0:
            urlToGet = 'http://log.go.com/log?srvc=dis&guid=951C36F8-3ACD-4EB2-9F02-8E8A0A217AF5&drop=0&addata=3232:64675:408091:64675&a=0'
            self.httpSession = HTTPClient()
            self.nonBlockHTTP = self.httpSession.makeChannel(False)
            self.nonBlockHTTP.beginGetDocument(DocumentSpec(urlToGet))
            instanceMarker = 'FunnelLoggingRequest-%s' % str(random.randint(1, 1000))
            self.startCheckingAsyncRequest(instanceMarker)
        

    
    def startCheckingAsyncRequest(self, name):
        taskMgr.remove(name)
        taskMgr.doMethodLater(0.5, self.pollAdTask, name)

    
    def pollAdTask(self, task):
        result = self.nonBlockHTTP.run()
        if result == 0:
            self.stopCheckingAdTask(task)
        else:
            return Task.again

    
    def stopCheckingAdTask(self, name):
        taskMgr.remove(name)

    
    def cleanupLoadingScreen(self):
        if self.debugMode:
            self.loadingBarRoot.removeChildren()
            self.cleanupAnalysis()
            self.stepInfo = { }
            self.unmappedTicks = []
        

    
    def showInfo(self, stepName, pos):
        self.stageLabel['text'] = stepName
        info = self.stepInfo[stepName]
        self.tickLabel['text'] = '%s ticks(%s)' % (len(info[3]), info[6])
        self.overallLabel['text'] = '%3.2f seconds (%d%%)' % (info[1], 100 * info[1] / (self.loadingEnd - self.loadingStart))

    
    def generateAnalysis(self):
        if self.analyzeMode:
            self.cleanupAnalysis()
        
        self.analyzeMode = True
        cm = CardMaker('cm')
        self.analysisBar.show()
        loadingTime = self.loadingEnd - self.loadingStart
        for stepName in self.stepInfo:
            (startTime, duration, color, ticks, startPercent, percent, expectedTicks) = self.stepInfo[stepName]
            cm.setName(stepName)
            cm.setColor(color)
            cm.setFrame((startTime / loadingTime) * 1.8 - 0.90000000000000002, ((startTime + duration) / loadingTime) * 1.8 - 0.90000000000000002, -0.5, -0.10000000000000001)
            self.analysisBarRoot.attachNewNode(cm.generate())
            button = DirectFrame(parent = self.analysisBarRoot, geom = NodePath('empty'), image = NodePath('empty'), state = DGG.NORMAL, relief = None, frameSize = ((startTime / loadingTime) * 1.8 - 0.90000000000000002, ((startTime + duration) / loadingTime) * 1.8 - 0.90000000000000002, -0.5, -0.10000000000000001))
            button.bind(DGG.ENTER, self.showInfo, extraArgs = [
                stepName])
            self.analysisButtons.append(button)
            button = DirectFrame(parent = self.analysisBarRoot, geom = NodePath('empty'), image = NodePath('empty'), state = DGG.NORMAL, relief = None, frameSize = ((startPercent / self.loadScale / 100.0) * 1.8 - 0.90000000000000002, ((startPercent + percent) / self.loadScale / 100.0) * 1.8 - 0.90000000000000002, 0.10000000000000001, 0.5))
            button.bind(DGG.ENTER, self.showInfo, extraArgs = [
                stepName])
            self.analysisButtons.append(button)
            for tick in ticks:
                self.line.moveTo(VBase3((tick / loadingTime) * 1.8 - 0.90000000000000002, 0, -0.5))
                self.line.drawTo(VBase3((tick / loadingTime) * 1.8 - 0.90000000000000002, 0, -0.55000000000000004))
            
        
        for tick in self.unmappedTicks:
            self.line.moveTo(VBase3((tick / loadingTime) * 1.8 - 0.90000000000000002, 0, -0.5))
            self.line.drawTo(VBase3((tick / loadingTime) * 1.8 - 0.90000000000000002, 0, -0.55000000000000004))
        
        self.analysisSegs = self.analysisBarRoot.attachNewNode(self.line.create())

    
    def cleanupAnalysis(self):
        for button in self.analysisButtons:
            button.destroy()
        
        self.analysisButtons = []
        self.analysisBarRoot.removeChildren()
        self.analysisBar.hide()
        self.analyzeMode = False
        self.analysisSegs = None

    
    def adjustSize(self, window):
        x = max(1, window.getXSize())
        y = max(1, window.getYSize())
        minSz = min(x, y)
        aspect = float(x) / y
        if x > y:
            self.topLock.setZ(1)
        else:
            self.topLock.setZ(float(y) / x)
        if minSz > IDEALX:
            self.topLock.setScale(IDEALX / float(x))
        elif minSz > IDEALY:
            self.topLock.setScale(IDEALY / float(y))
        else:
            self.topLock.setScale(1.0)
class DistributedTreasure(DistributedObject):
    notify = directNotify.newCategory('DistributedTreasure')

    def __init__(self, cr):
        DistributedObject.__init__(self, cr)
        self.grabSoundPath = None
        self.rejectSoundPath = 'phase_4/audio/sfx/ring_miss.ogg'
        self.dropShadow = None
        self.treasureTrack = None
        self.nodePath = None
        self.modelPath = None
        self.modelChildString = None
        self.sphereRadius = 2.0
        self.scale = 1.0
        self.zOffset = 0.0
        self.playSoundForRemoteToons = True
        self.fly = True
        self.shadow = True
        self.billboard = False
        self.av = None
        self.spinTaskName = None
        return

    def announceGenerate(self):
        DistributedObject.announceGenerate(self)
        self.spinTaskName = self.uniqueName('treasureRotate')
        self.loadModel(self.modelPath, self.modelChildString)
        self.startAnimation()
        self.nodePath.reparentTo(render)
        self.accept(self.uniqueName('entertreasureSphere'),
                    self.handleEnterSphere)

    def loadModel(self, mdlPath, childString=None):
        self.grabSound = base.loadSfx(self.grabSoundPath)
        self.rejectSound = base.loadSfx(self.rejectSoundPath)
        if self.nodePath == None:
            self.makeNodePath()
        else:
            self.treasure.getChildren().detach()
        model = loader.loadModel(mdlPath)
        if childString:
            model = model.find('**/' + childString)
        model.instanceTo(self.treasure)
        if self.cr.holidayManager.getHoliday() != 0:
            self.treasure.setScale(1.5, 1.5, 1.5)
            self.treasure.setZ(0.8)
            taskMgr.add(self.__spinTreasure, self.spinTaskName)
        return

    def makeNodePath(self):
        self.nodePath = NodePath('treasure')
        if self.billboard:
            self.nodePath.setBillboardPointEye()
        self.nodePath.setScale(0.9 * self.scale)
        self.treasure = self.nodePath.attachNewNode('treasure')
        if self.shadow:
            if not self.dropShadow:
                self.dropShadow = loader.loadModel(
                    'phase_3/models/props/drop_shadow.bam')
                self.dropShadow.setColor(0, 0, 0, 0.5)
                self.dropShadow.setPos(0, 0, 0.025)
                self.dropShadow.setScale(0.4 * self.scale)
                self.dropShadow.flattenLight()
            self.dropShadow.reparentTo(self.nodePath)
        collSphere = CollisionSphere(0, 0, 0, self.sphereRadius)
        collSphere.setTangible(0)
        collNode = CollisionNode(self.uniqueName('treasureSphere'))
        collNode.setIntoCollideMask(CIGlobals.WallBitmask)
        collNode.addSolid(collSphere)
        self.collNodePath = self.nodePath.attachNewNode(collNode)
        self.collNodePath.stash()

    def __spinTreasure(self, task):
        self.treasure.setH(20.0 * task.time)
        return Task.cont

    def handleEnterSphere(self, collEntry=None):
        localAvId = base.localAvatar.doId
        if not self.fly:
            self.setGrab(localAvId)
        self.d_requestGrab()

    def setPosition(self, x, y, z):
        if not self.nodePath:
            self.makeNodePath()
        self.nodePath.reparentTo(render)
        self.nodePath.setPos(x, y, z + self.zOffset)
        self.collNodePath.unstash()

    def setReject(self):
        self.cleanupTrack()
        base.playSfx(self.rejectSound, node=self.nodePath)
        self.treasureTrack = Sequence(
            LerpColorScaleInterval(self.nodePath,
                                   0.8,
                                   colorScale=VBase4(0, 0, 0, 0),
                                   startColorScale=VBase4(1, 1, 1, 1),
                                   blendType='easeIn'),
            LerpColorScaleInterval(self.nodePath,
                                   0.2,
                                   colorScale=VBase4(1, 1, 1, 1),
                                   startColorScale=VBase4(0, 0, 0, 0),
                                   blendType='easeOut',
                                   name='treasureFlyTrack'))
        self.treasureTrack.start()

    def setGrab(self, avId):
        self.collNodePath.stash()
        self.avId = avId
        if self.cr.doId2do.has_key(avId):
            self.av = self.cr.doId2do[avId]
        else:
            self.nodePath.detachNode()
            return
        if self.playSoundForRemoteToons or self.avId == base.localAvatar.doId:
            base.playSfx(self.grabSound, node=self.nodePath)
        if not self.fly:
            self.nodePath.detachNode()
            return
        self.cleanupTrack()
        taskMgr.remove(str(self.spinTaskName))
        avatarGoneName = self.av.uniqueName('disable')
        self.accept(avatarGoneName, self.handleUnexpectedExit)
        flyTime = 1.0
        track = Sequence(
            LerpPosInterval(self.nodePath,
                            flyTime,
                            pos=Point3(0, 0, 3),
                            startPos=self.nodePath.getPos(self.av),
                            blendType='easeInOut'),
            Func(self.nodePath.detachNode), Func(self.ignore, avatarGoneName))
        if self.shadow:
            self.treasureTrack = Sequence(HideInterval(self.dropShadow),
                                          track,
                                          ShowInterval(self.dropShadow),
                                          name='treasureFlyTrack')
        else:
            self.treasureTrack = Sequence(track, name='treasureFlyTrack')
        self.nodePath.reparentTo(self.av)
        self.treasureTrack.start()

    def handleUnexpectedExit(self):
        self.notify.warning('%s disconnected while collecting treasure.' %
                            str(self.avId))
        self.cleanupTrack()

    def d_requestGrab(self):
        self.sendUpdate('requestGrab', [])

    def startAnimation(self):
        pass

    def disable(self):
        self.ignoreAll()
        self.nodePath.detachNode()
        DistributedObject.disable(self)

    def cleanupTrack(self):
        if self.treasureTrack:
            self.treasureTrack.finish()
            self.treasureTrack = None
        self.spinTaskName = None
        return

    def delete(self):
        self.cleanupTrack()
        DistributedObject.delete(self)
        self.nodePath.removeNode()
Exemple #8
0
class VoxelGenerator(DirectObject):
    def __init__(self, parent, level, chunk_size=(7, 7, 1)):
        self.parent = parent
        self.level = level
        self.node = render.attachNewNode('main_level_node')
        self.chunk_size = chunk_size
        self.node_wall_original = NodePath('wall_original')
        self.node_wall_usable = self.node.attachNewNode("voxgen_wall_usable")
        self.node_forcewall_usable = self.node.attachNewNode(
            "voxgen_force_wall_usable")
        self.node_dynamic_wall_usable = self.node.attachNewNode(
            "voxgen_dynamic_wall_usable")
        self.wall_dict = {}
        self.dynamic_wall_dict = {}

        # For floors we will create a list of nodepaths, each list member will parent one chunk of tiles
        x = int((level.maxX - 1) / chunk_size[0]) + 1
        y = int((level.maxY - 1) / chunk_size[1]) + 1
        self.floor_np = NodePath("voxgen_floor_original")
        self.floor_usable_np = self.node.attachNewNode("voxgen_floor_usable")
        self.floor_np_list = []
        self.floor_usable_np_list = []
        for i in xrange(x):
            temp_list = []
            temp_list_usable = []
            for j in xrange(y):
                n = self.floor_np.attachNewNode('n_' + str(i) + '_' + str(j))
                temp_list.append(n)
                n2 = self.floor_usable_np.attachNewNode('n_usable_' + str(i) +
                                                        '_' + str(j))
                temp_list_usable.append(n2)
            self.floor_np_list.append(temp_list)
            self.floor_usable_np_list.append(temp_list_usable)

        self.floor_tile_dict = {}

        # We need a FIFO struct to hold pointers to dirty chunks that need flattening
        self.dirty_chunks = deque()
        self.dirty_walls = 0

        self.old_tile_dict = None
        self.old_invisible_walls = []

        # Create flatten task
        self.pause_flatten_task = True
        self.frames_between = 3
        self.frames_counter = 0
        taskMgr.add(self.flattenTask, "flatten_task")
        self.grid_display = False
        self.createGrid()
        self.accept('z', self.toggleGrid)

    def createGrid(self):
        segs = LineSegs()
        segs.setThickness(4.0)
        segs.setColor(Vec4(1, 1, 0, 0.3))
        for i in xrange(self.level.maxX):
            segs.moveTo(i + 1, 0, utils.GROUND_LEVEL)
            segs.drawTo(i + 1, self.level.maxY, utils.GROUND_LEVEL + 0.02)
        for j in xrange(self.level.maxY):
            segs.moveTo(0, j + 1, utils.GROUND_LEVEL)
            segs.drawTo(self.level.maxX, j + 1, utils.GROUND_LEVEL + 0.02)
        self.grid = NodePath(segs.create())
        self.grid.setTransparency(TransparencyAttrib.MAlpha)

    def toggleGrid(self):
        if not self.grid_display:
            self.grid.reparentTo(self.node)
            self.grid_display = True
        else:
            self.grid.detachNode()
            self.grid_display = False

    def markChunkDirty(self, x, y):
        chunk_x = int(x / self.chunk_size[0])
        chunk_y = int(y / self.chunk_size[0])
        payload = (self.floor_np_list[chunk_x][chunk_y], chunk_x, chunk_y)
        if not payload in self.dirty_chunks:
            self.dirty_chunks.append(payload)

    def markAllChunksDirty(self):
        self.pause_flatten_task = True
        for idx, val in enumerate(self.floor_np_list):
            for idy, v in enumerate(val):
                payload = self.floor_np_list[idx][idy], idx, idy
                self.dirty_chunks.append(payload)
        self.pause_flatten_task = False

    def createLevel(self):
        self.tex1 = loader.loadTexture("tile1.png")
        self.tex2 = loader.loadTexture("tile2.png")
        self.tex3 = loader.loadTexture("tile3.png")
        self.tex_tile_nm = loader.loadTexture("tile2nm.png")
        self.tex_fs = loader.loadTexture("rnbw.png")
        self.ts_fs = TextureStage('ts_fs')

        self.tex1.setMagfilter(Texture.FTLinearMipmapLinear)
        self.tex1.setMinfilter(Texture.FTLinearMipmapLinear)
        self.tex2.setMagfilter(Texture.FTLinearMipmapLinear)
        self.tex2.setMinfilter(Texture.FTLinearMipmapLinear)
        self.tex3.setMagfilter(Texture.FTLinearMipmapLinear)
        self.tex3.setMinfilter(Texture.FTLinearMipmapLinear)
        self.tex_tile_nm.setMagfilter(Texture.FTLinearMipmapLinear)
        self.tex_tile_nm.setMinfilter(Texture.FTLinearMipmapLinear)

        ts = TextureStage('ts')
        for x in xrange(0, self.level.maxX):
            for y in xrange(0, self.level.maxY):
                if self.level.getHeight((x, y)) == 0:

                    model = loader.loadModel('flattile')
                    model.setScale(utils.TILE_SIZE)
                    model.setPos(x * utils.TILE_SIZE, y * utils.TILE_SIZE,
                                 utils.GROUND_LEVEL)
                    """
                    if (x == 0 or x == self.level.maxX-1) or (y==0 or y==self.level.maxY-1):
                        model = loader.loadModel('halfcube')
                        model.setScale(utils.TILE_SIZE)
                        model.setPos(x*utils.TILE_SIZE, y*utils.TILE_SIZE, utils.GROUND_LEVEL)
                    else:
                        model = loader.loadModel('flattile')
                        model.setScale(utils.TILE_SIZE)
                        model.setPos(x*utils.TILE_SIZE, y*utils.TILE_SIZE, utils.GROUND_LEVEL)
                    """
                    #model = loader.loadModel('halfcube')
                    #model.setPos(x, y, 0)
                    model.reparentTo(self.floor_np_list[int(
                        x / self.chunk_size[0])][int(y / self.chunk_size[1])])
                    self.floor_tile_dict[(x, y)] = model
                elif self.level.getHeight((x, y)) == 1:
                    model = loader.loadModel('halfcube')
                    model.setScale(utils.TILE_SIZE)
                    model.setPos(x * utils.TILE_SIZE, y * utils.TILE_SIZE, 0)
                    model.reparentTo(self.floor_np_list[int(
                        x / self.chunk_size[0])][int(y / self.chunk_size[1])])
                    self.floor_tile_dict[(x, y)] = model
                    model = loader.loadModel('halfcube')
                    model.setScale(utils.TILE_SIZE)
                    model.setPos(x * utils.TILE_SIZE, y * utils.TILE_SIZE,
                                 utils.GROUND_LEVEL)
                    model.setTexture(ts, self.tex1)
                    #model.setTexture(self.ts_nm, self.tex_tile_nm)
                    model.reparentTo(self.node_wall_original)
                else:
                    for i in xrange(0, self.level.getHeight((x, y))):
                        if i == 0:

                            if (x == 0 or x == self.level.maxX -
                                    1) or (y == 0 or y == self.level.maxY - 1):
                                model = loader.loadModel('halfcube')
                                model.setScale(utils.TILE_SIZE)
                                model.setPos(x * utils.TILE_SIZE,
                                             y * utils.TILE_SIZE,
                                             utils.GROUND_LEVEL)
                            else:
                                model = loader.loadModel('flattile')
                                model.setScale(utils.TILE_SIZE)
                                model.setPos(x * utils.TILE_SIZE,
                                             y * utils.TILE_SIZE,
                                             utils.GROUND_LEVEL)

                            model.reparentTo(self.floor_np_list[int(
                                x / self.chunk_size[0])][int(
                                    y / self.chunk_size[1])])
                            self.floor_tile_dict[(x, y)] = model
                        else:
                            model = loader.loadModel('cube')
                            model.setScale(utils.TILE_SIZE)
                            model.setPos(
                                x * utils.TILE_SIZE, y * utils.TILE_SIZE,
                                (i - 1) * utils.TILE_SIZE + utils.GROUND_LEVEL)
                            model.setTexture(ts, self.tex2)
                            #model.setTexture(self.ts_nm, self.tex_tile_nm)
                            model.reparentTo(self.node_wall_original)
        self.floor_np.setTexture(self.tex3)

        #Calculate and place walls between tiles
        for x, val in enumerate(self.level._grid):
            for y, val2 in enumerate(val):
                if val2 != None:
                    # prvi parni, drugi neparni
                    tile2_x, tile2_y, h = self.getWallPosition(x, y)
                    if tile2_x == None:
                        continue

                    my_x = tile2_x
                    my_y = tile2_y
                    if val2.name == "Wall1":
                        model = loader.loadModel("wall")
                        model.setScale(utils.TILE_SIZE)
                        model.setPos(my_x * utils.TILE_SIZE,
                                     my_y * utils.TILE_SIZE,
                                     utils.GROUND_LEVEL)
                        model.setH(h)
                        self.wall_dict[(my_x, my_y, h)] = model
                        model.reparentTo(self.node_wall_original)
                    elif val2.name == "Wall2":
                        model = loader.loadModel("wall2")
                        model.setScale(utils.TILE_SIZE)
                        model.setPos(my_x * utils.TILE_SIZE,
                                     my_y * utils.TILE_SIZE,
                                     utils.GROUND_LEVEL)
                        model.setH(h)
                        model.setColor(0, 1, 0, 1)
                        self.wall_dict[(my_x, my_y, h)] = model
                        model.reparentTo(self.node_wall_original)
                    elif val2.name == "HalfWall":
                        model = loader.loadModel("wall2")
                        model.setScale(utils.TILE_SIZE)
                        model.flattenLight()
                        model.setPos(my_x * utils.TILE_SIZE,
                                     my_y * utils.TILE_SIZE,
                                     utils.GROUND_LEVEL)
                        model.setH(h)
                        model.setColor(0, 0, 0, 1)
                        model.setScale(1, 1, 0.4)
                        self.wall_dict[(my_x, my_y, h)] = model
                        model.reparentTo(self.node_wall_original)
                    elif val2.name == "Ruin":
                        model = loader.loadModel("wall2")
                        model.setScale(utils.TILE_SIZE)
                        model.setPos(my_x * utils.TILE_SIZE,
                                     my_y * utils.TILE_SIZE,
                                     utils.GROUND_LEVEL)
                        model.setH(h)
                        model.setColor(0.5, 0.8, 1, 0.6)
                        model.setTransparency(TransparencyAttrib.MAlpha)
                        model.reparentTo(self.node_forcewall_usable)
                        s = Sequence(
                            LerpColorInterval(model, 1,
                                              (0.13, 0.56, 0.78, 0.6)),
                            LerpColorInterval(model, 1, (0.5, 0.8, 1, 0.6)),
                        )
                        s.loop()
                        model.setLightOff()
                    elif val2.name == "ClosedDoor":
                        model = loader.loadModel("door")
                        model.setScale(utils.TILE_SIZE)
                        model.setPos(my_x * utils.TILE_SIZE,
                                     my_y * utils.TILE_SIZE,
                                     utils.GROUND_LEVEL)
                        model.setH(h)
                        model.setColor(1, 0.0, 0, 0.0)
                        self.dynamic_wall_dict[(my_x, my_y, h)] = model
                        model.reparentTo(self.node_dynamic_wall_usable)
                    elif val2.name == "OpenedDoor":
                        model = loader.loadModel("door")
                        model.setScale(utils.TILE_SIZE)
                        model.setPos(my_x * utils.TILE_SIZE,
                                     my_y * utils.TILE_SIZE,
                                     utils.GROUND_LEVEL)
                        model.setH(h)
                        model.setScale(0.2, 1, 1)
                        model.setColor(0.7, 0.2, 0.2, 0.0)
                        self.dynamic_wall_dict[(my_x, my_y, h)] = model
                        model.reparentTo(self.node_dynamic_wall_usable)
                    elif val2.name == "ForceField":
                        model = loader.loadModel("wall_fs")
                        model.setScale(utils.TILE_SIZE)
                        model.setPos(my_x * utils.TILE_SIZE,
                                     my_y * utils.TILE_SIZE,
                                     utils.GROUND_LEVEL)
                        model.setH(h)
                        model.setTexture(self.ts_fs, self.tex_fs)
                        model.setTransparency(TransparencyAttrib.MAlpha)
                        model.reparentTo(self.node_forcewall_usable)
                        self.dynamic_wall_dict[(my_x, my_y, h)] = model
                        model.setLightOff()

        #self.floor_usable_np.setShaderAuto()
        self.floor_usable_np.setTexture(self.tex3)
        self.markAllChunksDirty()
        self.dirty_walls = 1

    def getWallPosition(self, x, y):
        if (x % 2 == 0 and y % 2 != 0):
            pos_x = x / 2
            pos_y = (y - 1) / 2
            h = 90
        # prvi neparni, drugi parni
        elif (x % 2 != 0 and y % 2 == 0):
            pos_x = (x - 1) / 2
            pos_y = y / 2
            h = 0
        else:
            pos_x = None
            pos_y = None
            h = None
        return pos_x, pos_y, h

    def processLevel(self, invisible_walls):
        self.level = self.parent.parent.level
        for x, val in enumerate(self.level._grid):
            for y, val2 in enumerate(val):
                if val2 != None:
                    my_x, my_y, h = self.getWallPosition(x, y)
                    # prvi parni, drugi neparni
                    if my_x == None:
                        continue

                    if val2.name == "ClosedDoor" and val2.name != self.parent.parent.old_level._grid[
                            x][y].name:
                        if not (x, y) in self.old_invisible_walls:
                            self.dynamic_wall_dict[(my_x, my_y, h)].setScale(1)
                        else:
                            i = self.dynamic_wall_dict[(my_x, my_y,
                                                        h)].scaleInterval(
                                                            1, Vec3(1, 1, 1))
                            i.start()
                    elif val2.name == "OpenedDoor" and val2.name != self.parent.parent.old_level._grid[
                            x][y].name:
                        if not (x, y) in self.old_invisible_walls:
                            self.dynamic_wall_dict[(my_x, my_y,
                                                    h)].setScale(0.2, 1, 1)
                        else:
                            i = self.dynamic_wall_dict[(my_x, my_y,
                                                        h)].scaleInterval(
                                                            1, Vec3(0.2, 1, 1))
                            i.start()
        self.old_invisible_walls = invisible_walls

    def setInvisibleTilesInThread(self):
        taskMgr.add(self.setInvisibleTiles,
                    'invis_tiles',
                    extraArgs=[],
                    taskChain='thread_1')

    def setInvisibleTiles(self):
        tile_dict = self.parent.parent.getInvisibleTiles()
        for invisible_tile in tile_dict:
            if self.old_tile_dict == None or tile_dict[
                    invisible_tile] != self.old_tile_dict[invisible_tile]:
                if tile_dict[invisible_tile] == 0:
                    self.floor_tile_dict[invisible_tile].setColorScale(
                        0.3, 0.3, 0.3, 1)
                    self.markChunkDirty(invisible_tile[0], invisible_tile[1])
                else:
                    self.floor_tile_dict[invisible_tile].setColorScale(
                        1, 1, 1, 1)
                    self.markChunkDirty(invisible_tile[0], invisible_tile[1])
        self.old_tile_dict = tile_dict

    def setInvisibleWallsInThread(self):
        taskMgr.add(self.setInvisibleWalls,
                    'invis_walls',
                    extraArgs=[],
                    taskChain='thread_1')

    def setInvisibleWalls(self):
        visible_wall_list = self.parent.parent.getInvisibleWalls()
        self.processLevel(visible_wall_list)
        new_list = []
        for l in visible_wall_list:
            x, y, h = self.getWallPosition(l[0], l[1])
            new_list.append((x, y, h))
        for wall in self.wall_dict:
            # If we have key in visible_wall_dict, the wall is visible
            if wall in new_list:
                self.wall_dict[wall].setColorScale(1, 1, 1, 1)
            else:
                self.wall_dict[wall].setColorScale(0.3, 0.3, 0.3, 1)
        for wall in self.dynamic_wall_dict:
            if wall in new_list:
                self.dynamic_wall_dict[wall].setColorScale(1, 1, 1, 1)
            else:
                self.dynamic_wall_dict[wall].setColorScale(0.3, 0.3, 0.3, 1)
        self.dirty_walls = 1

    def flattenTask(self, task):
        if self.pause_flatten_task:
            return task.cont

        if self.frames_counter < self.frames_between:
            self.frames_counter += 1

        if self.dirty_walls == 1:
            np = self.node_wall_original.copyTo(NodePath())
            np.clearModelNodes()
            np.flattenStrong()
            self.node_wall_usable.removeNode()
            self.node_wall_usable = np
            self.node_wall_usable.reparentTo(self.node)
            #self.node_wall_usable.setShaderAuto()
            self.dirty_walls = 0

        if len(self.dirty_chunks) > 0:
            if self.frames_counter == self.frames_between:
                chunk_tupple = self.dirty_chunks.popleft()
                np = chunk_tupple[0].copyTo(NodePath())
                np.clearModelNodes()
                np.flattenStrong()
                self.floor_usable_np_list[chunk_tupple[1]][
                    chunk_tupple[2]].removeNode()
                self.floor_usable_np_list[chunk_tupple[1]][
                    chunk_tupple[2]] = np
                self.floor_usable_np_list[chunk_tupple[1]][
                    chunk_tupple[2]].reparentTo(self.floor_usable_np)
                self.frames_counter = 0
        return task.cont
Exemple #9
0
class LineDrawer:
	def __init__(self, game, color = (1,0.1,0.1,0.0)):
		self.game = game
		self.node = GeomNode("lines")
		self.np = NodePath(self.node)
		self.np.reparentTo(self.game.render)
		self.np.setShaderOff()
		self.np.setLightOff()
		self.color = color
		self.np.setColor(self.color)
		self.path = []
		self.start = (0, 0)
		self.end = (0, 0)
		
	def setStart(self, start):
		self.start = start
		#self.startModel.setPos(start[0]+0.5, start[1]+0.5, 0)
		
	def setEnd(self, end):
		self.end = end
		#self.endModel.setPos(end[0]+0.5, end[1]+0.5, 0)
		
	def clear(self):
		self.np.remove()
		self.node = GeomNode("lines")
		self.np = NodePath(self.node)
		self.np.reparentTo(self.game.render)
		self.np.setShaderOff()
		self.np.setLightOff()
		self.np.setColor(self.color)
		
	def destroy(self):
		self.np.detachNode()
		del self.np
		
	def drawLine(self, start, end):
		#print "Draw line : %s, %s" % (str(start), str(end))
		self.node.addGeom(self.line(start, end))
	
	def line (self, start, end):
		# since we're doing line segments, just vertices in our geom
		format = GeomVertexFormat.getV3()
	   
		# build our data structure and get a handle to the vertex column
		vdata = GeomVertexData ('', format, Geom.UHStatic)
		vertices = GeomVertexWriter (vdata, 'vertex')
		   
		# build a linestrip vertex buffer
		lines = GeomLinestrips (Geom.UHStatic)
	   
		vertices.addData3f (start[0], start[1], start[2])
		vertices.addData3f (end[0], end[1], end[2])
	   
		lines.addVertices (0, 1)
		
		lines.closePrimitive()
	   
		geom = Geom (vdata)
		geom.addPrimitive (lines)
		# Add our primitive to the geomnode
		#self.gnode.addGeom (geom)
		return geom
		
	def setPath(self, path):
		self.path = path
		self.clear()
		for pos in range(len(self.path)-1):
			self.drawLine(self.path[pos], self.path[pos+1])
Exemple #10
0
class BaseObject(BaseRunnable):
    """
    BaseObject is something interacting with game engine. If something is expected to have a body in the world or have
    appearance in the world, it must be a subclass of BaseObject.

    It is created with name/config/randomEngine and can make decision in the world. Besides the random engine can help
    sample some special configs for it ,Properties and parameters in PARAMETER_SPACE of the object are fixed after
    calling __init__().
    """
    def __init__(self,
                 name=None,
                 random_seed=None,
                 config=None,
                 escape_random_seed_assertion=False):
        """
        Config is a static conception, which specified the parameters of one element.
        There parameters doesn't change, such as length of straight road, max speed of one vehicle, etc.
        """
        super(BaseObject, self).__init__(name, random_seed, config)
        if not escape_random_seed_assertion:
            assert random_seed is not None, "Please assign a random seed for {} class.".format(
                self.class_name)

        # Following properties are available when this object needs visualization and physics property
        self._body = None

        # each element has its node_path to render, physics node are child nodes of it
        self.origin = NodePath(self.name)

        # Temporally store bullet nodes that have to place in bullet world (not NodePath)
        self.dynamic_nodes = PhysicsNodeList()

        # Nodes in this tuple didn't interact with other nodes! they only used to do rayTest or sweepTest
        self.static_nodes = PhysicsNodeList()

        # render or not
        self.render = False if AssetLoader.loader is None else True
        if self.render:
            self.loader = AssetLoader.get_loader()

            if not hasattr(self.loader, "loader"):
                # It is closed before!
                self.loader.__init__()

    def add_body(self, physics_body):
        if self._body is None:
            # add it to physics world, in which this object will interact with other object (like collision)
            if not isinstance(physics_body, BulletBodyNode):
                raise ValueError("The physics body is not BulletBodyNode type")
            self._body = physics_body
            new_origin = NodePath(self._body)
            self.origin.getChildren().reparentTo(new_origin)
            self.origin = new_origin
            self.dynamic_nodes.append(physics_body)
        else:
            raise AttributeError("You can not set the object body for twice")

    @property
    def body(self):
        if self._body.hasPythonTag(self._body.getName()):
            return self._body.getPythonTag(self._body.getName())
        else:
            return self._body

    def attach_to_world(self, parent_node_path: NodePath,
                        physics_world: PhysicsWorld):
        """
        Load to world from memory
        """
        if self.render:
            # double check :-)
            assert isinstance(
                self.origin,
                NodePath), "No render model on node_path in this Element"
            self.origin.reparentTo(parent_node_path)
        self.dynamic_nodes.attach_to_physics_world(physics_world.dynamic_world)
        self.static_nodes.attach_to_physics_world(physics_world.static_world)

    def detach_from_world(self, physics_world: PhysicsWorld):
        """
        It is not fully remove, it will be left in memory. if this element is useless in the future, call Func delete()
        """
        if self.origin is not None:
            self.origin.detachNode()
        self.dynamic_nodes.detach_from_physics_world(
            physics_world.dynamic_world)
        self.static_nodes.detach_from_physics_world(physics_world.static_world)

    def destroy(self):
        """
        Fully delete this element and release the memory
        """
        from pgdrive.engine.engine_utils import get_engine
        engine = get_engine()
        self.detach_from_world(engine.physics_world)
        if self._body is not None and hasattr(self.body, "object"):
            self.body.generated_object = None
        if self.origin is not None:
            self.origin.removeNode()
        self.dynamic_nodes.clear()
        self.static_nodes.clear()
        self._config.clear()
class ARObject(object):
    NOTHING = object()
    def __init__(self, *args):
        self.args= args
        self.mainNP= NodePath('ARObject')
        self.bulletNodes= []
        self.junctionPoints= []
        
    #Position as 3 floats
    def setPos(self, X, Y, Z):
        self.mainNP.setPos(X,Y,Z)
    
    #Position as one Point3
    def setPos(self, Pos):
        self.mainNP.setPos(Pos)
        
    #HPR as 3 floats
    def setHpr(self, H, P, R):
        self.mainNP.setHpr(H,P,R)
        
    #HPR as a VBase3
    def setHpr(self, Hpr):
        self.mainNP.setHpr(Hpr)
        
    def reparentTo(self, NP, world):
        #Adding bullet ridig bodies to the world
        for x in self.bulletNodes:
            world.attachRigidBody(x)
        self.mainNP.reparentTo(NP)      
        
        
    def detach(self, world):
        #Removing bullet ridig bodies from the world
        for x in self.bulletNodes:
            world.removeRigidBody(x)
        self.mainNP.detachNode() 
            
    
    def addBulletNode(self, name, *shapes):
        bulletNode= BulletRigidBodyNode(name)
        bulletNode.setDeactivationEnabled(False)
        for x in shapes:
            bulletNode.addShape(x)
        self.bulletNodes.append(bulletNode)
        self.mainNP.attachNewNode(bulletNode)
        return bulletNode
    
    def setMass(self):
        self.bulletNodes[0].setMass(self.args[0])
    
    def setMassZero(self):
        self.bulletNodes[0].setMass(0)
    
        
    def NormalizeVector(self, myVec):
        myVec.normalize()
        return myVec    

    def makeSquare(self, x1,y1,z1, x2,y2,z2, 
                   colorVec=Vec4(1.0,1.0,1.0,1.0),
                   texFunction= NOTHING,
                   colorFunction= NOTHING 
                   ):
        vertexformat=GeomVertexFormat.getV3n3cpt2()
        vdata=GeomVertexData('square', vertexformat, Geom.UHDynamic)
        
        vertex=GeomVertexWriter(vdata, 'vertex')
        normal=GeomVertexWriter(vdata, 'normal')
        color=GeomVertexWriter(vdata, 'color')
        texcoord=GeomVertexWriter(vdata, 'texcoord')
        
        #make sure we draw the square in the right plane
        if x1!=x2:
            vertex.addData3f(x1, y1, z1)
            vertex.addData3f(x2, y1, z1)
            vertex.addData3f(x2, y2, z2)
            vertex.addData3f(x1, y2, z2)
        
            normal.addData3f(self.NormalizeVector(Vec3(2*x1-1, 2*y1-1, 2*z1-1)))
            normal.addData3f(self.NormalizeVector(Vec3(2*x2-1, 2*y1-1, 2*z1-1)))
            normal.addData3f(self.NormalizeVector(Vec3(2*x2-1, 2*y2-1, 2*z2-1)))
            normal.addData3f(self.NormalizeVector(Vec3(2*x1-1, 2*y2-1, 2*z2-1)))
            
        else:
            vertex.addData3f(x1, y1, z1)
            vertex.addData3f(x2, y2, z1)
            vertex.addData3f(x2, y2, z2)
            vertex.addData3f(x1, y1, z2)
            
            normal.addData3f(self.NormalizeVector(Vec3(2*x1-1, 2*y1-1, 2*z1-1)))
            normal.addData3f(self.NormalizeVector(Vec3(2*x2-1, 2*y2-1, 2*z1-1)))
            normal.addData3f(self.NormalizeVector(Vec3(2*x2-1, 2*y2-1, 2*z2-1)))
            normal.addData3f(self.NormalizeVector(Vec3(2*x1-1, 2*y1-1, 2*z2-1)))
        
        if(colorFunction == ARObject.NOTHING):
            self.addColor(color, colorVec)
        else:
            colorFunction(color,colorVec)
            
        if(texFunction == ARObject.NOTHING):
            self.addTexCoord(texcoord, x1,y1,z1,  x2,y2,z2)
        else:
            texFunction(texcoord, x1,y1,z1,  x2,y2,z2)
        
        tri1=GeomTriangles(Geom.UHDynamic)
        tri2=GeomTriangles(Geom.UHDynamic)
        
        tri1.addVertex(0)
        tri1.addVertex(1)
        tri1.addVertex(3)
        
        tri2.addConsecutiveVertices(1,3)
        
        tri1.closePrimitive()
        tri2.closePrimitive()
        
        
        square=Geom(vdata)
        square.addPrimitive(tri1)
        square.addPrimitive(tri2)
        
        return square
    
    
    def addColor(self, color, colorVec):
        color.addData4f(colorVec)
        color.addData4f(colorVec)
        color.addData4f(colorVec)
        color.addData4f(colorVec)
        
    def addTexCoord(self, texcoord, x1,y1,z1,  x2,y2,z2):
        texcoord.addData2f(0.0, 1.0)
        texcoord.addData2f(0.0, 0.0)
        texcoord.addData2f(1.0, 0.0)
        texcoord.addData2f(1.0, 1.0)
        
    def __del__(self):
        print "Instance of Class ", self.__class__.__name__ ," Removed."
Exemple #12
0
    def create_all_text(self):
        self.continue_text = OnscreenText(
            **{
                "text":
                ("In a moment, you will be asked the question displayed on "
                 "the left.  When you are ready, press the spacebar to begin."
                 ),
                "style":
                1,
                "fg": (.75, 0, 0, 1),
                "bg":
                self.text_bg,
                "pos": (.4, .4),
                "align":
                TextNode.ACenter,
                "scale":
                .08,
                "font":
                self.font,
                "wordwrap":
                20
            })
        self.text_parent = self.continue_text.getParent()
        self.continue_text.detachNode()

        xpos = -1.25
        skip = .15
        self.question_text = OnscreenText(
            **{
                "text": self.question[0],
                "style": 1,
                "fg": (0, 0, .8, 1),
                "bg": self.text_bg,
                "pos": ((xpos + .05), .8),
                "align": TextNode.ALeft,
                "scale": .075,
                "font": self.font,
                "wordwrap": 35
            })

        self.question_choice_text = []
        for i in xrange(len(self.question[1])):
            n = len(self.question[1]) - i - 1
            ypos = self.choice_text_start - (skip * n)

            t1 = OnscreenText(
                **{
                    "text": "%s" % self.question[1][i][0],
                    "style": 1,
                    "fg": (0, .1, 0, 1),
                    "bg": self.text_bg,
                    "pos": ((xpos + .1), ypos),
                    "align": TextNode.ALeft,
                    "scale": .075,
                    "font": self.font
                })

            t2 = OnscreenText(
                **{
                    "text": "%s" % self.question[1][i][1],
                    "style": 1,
                    "fg": (0, .1, 0, 1),
                    "bg": self.text_bg,
                    "pos": ((xpos + 0.17), ypos),
                    "align": TextNode.ALeft,
                    "scale": .05,
                    "font": self.font
                })

            t = NodePath("choice_%s" % i)
            t.reparentTo(self.text_parent)
            t1.reparentTo(t)
            t2.reparentTo(t)
            self.question_choice_text.append(t)

        for t in self.question_choice_text:
            t.detachNode()

        self.trials_remaining_text = OnscreenText(
            **{
                "text": "",
                "style": 1,
                "fg": (0, 0, 0, 1),
                "bg": self.text_bg,
                "pos": (-xpos, -.95),
                "align": TextNode.ARight,
                "scale": .05,
                "font": self.font
            })
Exemple #13
0
class Movement(DirectObject.DirectObject):
    def __init__(self, parent):
        self.parent = parent

        self.hovered_unit_id = None
        self.hovered_tile = None
        self.hovered_compass_tile = None

        self.mouse_node = aspect2d.attachNewNode('mouse_node')
        self.move_node = aspect2d.attachNewNode('move_node')
        self.move_outline_node = NodePath('')
        self.move_np_list = []
        self.target_info_node = None

        self.accept("mouse1", self.mouseLeftClick)
        self.accept("mouse1-up", self.mouseLeftClickUp)

        #taskMgr.add(self.rayupdate, 'rayupdate_task')
        taskMgr.add(self.pickerTask, 'picker_task')
        taskMgr.add(self.positionTask, 'position_task', sort=2)

        self.color_scale_parallel = None

        # Create movement compass nodes
        self.turn_node = NodePath('turn_node')
        self.turn_node.setTag('show', '0')
        self.turn_np_list = []
        for i in xrange(9):
            text = TextNode('node name')
            text.setAlign(TextNode.ACenter)
            if i == 0:
                text.setText('NW')
                key = utils.HEADING_NW
            elif i == 1:
                text.setText('N')
                key = utils.HEADING_N
            elif i == 2:
                text.setText('NE')
                key = utils.HEADING_NE
            elif i == 3:
                text.setText('W')
                key = utils.HEADING_W
            elif i == 4:
                text.setText('E')
                key = utils.HEADING_E
            elif i == 5:
                text.setText('SW')
                key = utils.HEADING_SW
            elif i == 6:
                text.setText('S')
                key = utils.HEADING_S
            elif i == 7:
                text.setText('SE')
                key = utils.HEADING_SE
            elif i == 8:
                text.setText('X')
                key = utils.HEADING_NONE
            textNodePath = self.turn_node.attachNewNode(text)
            textNodePath.setColor(1, 1, 1)
            textNodePath.setScale(0.06)
            textNodePath.setTag('key', str(key))
            self.turn_np_list.append(textNodePath)

    def calcUnitAvailMove(self, unit_id):
        """Displays visual indicator of tiles which are in movement range of the selected unit."""
        # First delete old movement list
        for c in self.move_np_list:
            c.removeNode()
        self.move_np_list = []
        # Start calculation of new list
        unit = self.parent.local_engine.units[unit_id]
        if self.parent.turn_player != self.parent.player_id:
            return
        if unit:
            unit['move_dict'] = getMoveDict(unit,
                                            self.parent.local_engine.level,
                                            self.parent.local_engine.units)
            self.parent.local_engine.units[unit_id]['move_dict'] = unit[
                'move_dict']
            move_dict = unit['move_dict']
            for tile in move_dict:
                text = TextNode('node name')
                text.setText("%s" % move_dict[tile])
                text.setAlign(TextNode.ACenter)
                textNodePath = self.move_node.attachNewNode(text)
                textNodePath.setColor(1, 1, 1)
                textNodePath.setScale(0.06)
                textNodePath.setPythonTag('pos', tile)
                pos2d = utils.pointCoordIn2d(
                    Point3(utils.TILE_SIZE * (tile[0] + 0.5),
                           utils.TILE_SIZE * (tile[1] + 0.5),
                           utils.GROUND_LEVEL))
                textNodePath.setPos(pos2d)
                self.move_np_list.append(textNodePath)

    def showUnitAvailMove(self):
        self.move_node.reparentTo(aspect2d)
        self.hovered_tile = None
        #self.drawMoveOutline(self.calcMoveOutline(move_dict, self.parent.local_engine.units[unit_id]['pos']))

    def hideUnitAvailMove(self):
        self.move_node.detachNode()

    """
    def calcMoveOutline(self, move_dict, pos):
        outline = {}
        for tile in move_dict:
            dir = []
            if not (tile[0]-1, tile[1]) in move_dict and (tile[0]-1, tile[1]) != pos:
                dir.append('W')
            if not (tile[0], tile[1]-1) in move_dict and (tile[0], tile[1]-1) != pos:
                dir.append('S')
            if not (tile[0]+1, tile[1]) in move_dict and (tile[0]+1, tile[1]) != pos:
                dir.append('E')                
            if not (tile[0], tile[1]+1) in move_dict and (tile[0], tile[1]+1) != pos:
                dir.append('N')
            if dir != []:
                outline[tile] = dir
        return outline
    
    def drawMoveOutline(self, outline):
        self.move_outline_node.removeNode()
        zpos = utils.GROUND_LEVEL + 0.01
        off = 0.1
        segs = LineSegs()
        segs.setThickness(3)
        segs.setColor(Vec4(0.686,1,0.992,1))
        for tile in outline:
            for dir in outline[tile]:
                if dir == 'N':
                    d1 = 0
                    d2 = 0
                    if (tile[0]+1, tile[1]) in outline and 'N' in outline[(tile[0]+1, tile[1])]:
                        d2 = off
                    elif (tile[0]+1, tile[1]+1) in outline:
                        d2 = 2*off
                    if (tile[0]-1, tile[1]) in outline and 'N' in outline[(tile[0]-1, tile[1])]:
                        d1 = off
                    elif (tile[0]-1, tile[1]+1) in outline:
                        d1 = 2*off
                    segs.moveTo(tile[0]+off-d1, tile[1]+1-off, zpos)
                    segs.drawTo(tile[0]+1-off+d2, tile[1]+1-off, zpos)
                elif dir == 'S':
                    d1 = 0
                    d2 = 0
                    if (tile[0]+1, tile[1]) in outline and 'S' in outline[(tile[0]+1, tile[1])]:
                        d2 = off
                    elif (tile[0]+1, tile[1]-1) in outline:
                        d2 = 2*off
                    if (tile[0]-1, tile[1]) in outline and 'S' in outline[(tile[0]-1, tile[1])]:
                        d1 = off
                    elif (tile[0]-1, tile[1]-1) in outline:
                        d1 = 2*off                  
                    segs.moveTo(tile[0]+off-d1, tile[1]+off, zpos)
                    segs.drawTo(tile[0]+1-off+d2, tile[1]+off, zpos)
                elif dir == 'W':
                    d1 = 0
                    d2 = 0
                    if (tile[0], tile[1]+1) in outline and 'W' in outline[(tile[0], tile[1]+1)]:
                        d2 = off
                    elif (tile[0]-1, tile[1]+1) in outline:
                        d2 = 2*off
                    if (tile[0], tile[1]-1) in outline and 'W' in outline[(tile[0], tile[1]-1)]:
                        d1 = off                     
                    elif (tile[0]-1, tile[1]-1) in outline:
                        d1 = 2*off
                    segs.moveTo(tile[0]+off, tile[1]+off-d1, zpos)
                    segs.drawTo(tile[0]+off, tile[1]+1-off+d2, zpos)
                elif dir == 'E':
                    d1 = 0
                    d2 = 0
                    if (tile[0], tile[1]+1) in outline and 'E' in outline[(tile[0], tile[1]+1)]:
                        d2 = off
                    elif (tile[0]+1, tile[1]+1) in outline:
                        d2 = 2*off
                    if (tile[0], tile[1]-1) in outline and 'E' in outline[(tile[0], tile[1]-1)]:
                        d1 = off                     
                    elif (tile[0]+1, tile[1]-1) in outline:
                        d1 = 2*off                   
                    segs.moveTo(tile[0]+1-off, tile[1]+off-d1, zpos)
                    segs.drawTo(tile[0]+1-off, tile[1]+1-off+d2, zpos)                                        
        self.move_outline_node = render.attachNewNode(segs.create())
        self.move_outline_node.setBin("fixed", 40)
        #self.move_outline_node.setDepthTest(False)
        #self.move_outline_node.setDepthWrite(False)
        self.move_outline_node.setLightOff()  
    """

    def showMoveCompass(self, dest):
        # Calculate postion of compass nodes based on destination tile
        for i in self.turn_np_list:
            i.setPythonTag('pos', utils.getHeadingTile(i.getTag('key'), dest))
        # Show compass nodes
        self.turn_node.reparentTo(aspect2d)
        self.turn_node.setPythonTag('pos', dest)
        self.turn_node.setTag('show', '1')

        # Hide move nodes
        self.move_node.detachNode()

    def hideMoveCompass(self):
        # Hide compass nodes
        self.turn_node.detachNode()
        self.turn_node.setTag('show', '0')
        if self.hovered_compass_tile != None:
            self.hovered_compass_tile.setColor(1, 1, 1)
            self.hovered_compass_tile.setScale(0.05)
            self.color_scale_parallel.pause()
            self.hovered_compass_tile = None

    def mouseLeftClick(self):
        if self.parent.interface.hovered_gui != None:
            return

        if self.hovered_unit_id != None:
            unit_id = int(self.hovered_unit_id)
            pickedCoord = self.parent.local_engine.getCoordsByUnit(unit_id)
            # Player can only select his own units
            if self.parent.local_engine.isThisMyUnit(unit_id):
                if unit_id != self.parent.sel_unit_id:
                    self.parent.selectUnit(unit_id)
                else:
                    # Remember movement tile so we can send orientation message when mouse is depressed
                    # Do this only if it is our turn
                    if self.parent.player_id == self.parent.turn_player:
                        self.unit_move_destination = pickedCoord
                        self.showMoveCompass(self.unit_move_destination)
            elif self.parent.local_engine.isThisEnemyUnit(unit_id):
                if self.parent.sel_unit_id != None and self.parent.player_id == self.parent.turn_player:
                    self.parent.render_manager.unit_renderer_dict[
                        self.parent.
                        sel_unit_id].target_unit = self.parent.render_manager.unit_renderer_dict[
                            unit_id]
                    if self.parent._anim_in_process == False:
                        ClientMsg.shoot(self.parent.sel_unit_id, unit_id)

        elif self.hovered_tile != None:
            if self.parent.sel_unit_id != None and self.parent.player_id == self.parent.turn_player:
                # Remember movement tile so we can send movement message when mouse is depressed
                # Do this only if it is our turn
                move_coord = self.hovered_tile.getPythonTag('pos')
                if self.parent.local_engine.units[self.parent.sel_unit_id][
                        'move_dict'].has_key(move_coord):
                    self.unit_move_destination = move_coord
                    self.showMoveCompass(self.unit_move_destination)

    def mouseLeftClickUp(self):
        """Handles left mouse click actions when mouse button is depressed.
           Used for unit movement.
        """
        o = None
        if self.hovered_compass_tile != None:
            x = self.turn_node.getPythonTag('pos')[0]
            y = self.turn_node.getPythonTag('pos')[1]
            orientation = int(self.hovered_compass_tile.getTag('key'))
            if orientation == utils.HEADING_NW:
                o = Point2(x - 1, y + 1)
            elif orientation == utils.HEADING_N:
                o = Point2(x, y + 1)
            elif orientation == utils.HEADING_NE:
                o = Point2(x + 1, y + 1)
            elif orientation == utils.HEADING_W:
                o = Point2(x - 1, y)
            elif orientation == utils.HEADING_E:
                o = Point2(x + 1, y)
            elif orientation == utils.HEADING_SW:
                o = Point2(x - 1, y - 1)
            elif orientation == utils.HEADING_S:
                o = Point2(x, y - 1)
            elif orientation == utils.HEADING_SE:
                o = Point2(x + 1, y - 1)
            else:
                o = None

        self.hideMoveCompass()
        if o != None:
            ClientMsg.move(self.parent.sel_unit_id, (x, y), (o.x, o.y))

    def positionTask(self, task):
        # If turn node is displayed, you have to cancel turning or turn to be able to pick another unit or another tile to move to
        if self.turn_node.getTag('show') == '1':
            for tile in self.turn_np_list:
                pos = Point3(
                    utils.TILE_SIZE * (tile.getPythonTag('pos')[0] + 0.5),
                    utils.TILE_SIZE * (tile.getPythonTag('pos')[1]) + 0.5,
                    utils.GROUND_LEVEL)
                pos2d = utils.pointCoordIn2d(pos)
                tile.setPos(pos2d)
        else:
            for unit in self.parent.render_manager.unit_renderer_dict.itervalues(
            ):
                p = utils.nodeCoordIn2d(unit.model)
                unit.node_2d.setPos(p)
            for tile in self.move_np_list:
                pos = Point3(
                    utils.TILE_SIZE * (tile.getPythonTag('pos')[0] + 0.5),
                    utils.TILE_SIZE * (tile.getPythonTag('pos')[1] + 0.5),
                    utils.GROUND_LEVEL)
                pos2d = utils.pointCoordIn2d(pos)
                tile.setPos(pos2d)
        return task.cont

    def pickerTask(self, task):
        if self.parent._anim_in_process:
            self.hovered_unit_id = None
            self.hovered_tile = None
            self.hovered_compass_tile = None
            return task.cont

        if self.parent.interface.hovered_gui != None:
            if self.hovered_unit_id != None:
                self.parent.render_manager.unit_marker_renderer.unmarkHovered(
                    self.hovered_unit_id)
                self.hovered_unit_id = None
            if self.hovered_tile != None and not self.hovered_tile.isEmpty():
                self.hovered_tile.setColor(1, 1, 1)
                self.hovered_tile.setScale(0.05)
                self.color_scale_parallel.pause()
            if self.hovered_compass_tile != None and not self.hovered_compass_tile.isEmpty(
            ):
                self.hovered_compass_tile.setColor(1, 1, 1)
                self.hovered_compass_tile.setScale(0.05)
                self.color_scale_parallel.pause()
            return task.cont

        min_distance = 0.5
        min_unit_id = None
        min_tile = None
        min_compass_tile = None
        if base.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()
            r2d = Point3(mpos.getX(), 0, mpos.getY())
            a2d = aspect2d.getRelativePoint(render2d, r2d)
            self.mouse_node.setPos(a2d)

            # At the end of all this we have:
            # - min_distance to a unit or a movement node, IF this distance is lower than 0.5 which is set at the beginning
            # - min_unit_id - ID of unit which is closest to the mouse, or None if there is a movement tile closer, or if everything is further than 0.5
            # - min_tile - nodepath of the movement tile closest to the mouse, or None if there is a unit closer, or if evertythin is further than 0.5
            if self.turn_node.getTag('show') == '1':
                # Get 2d coordinates for every compass node
                for tile in self.turn_np_list:
                    # We cannot do nodepath.getDistance() because tiles are reparented to self.turn_node and are in different coord space than mouse node
                    # So we do simple vector math to get distance
                    d = Vec3(self.mouse_node.getPos() - tile.getPos()).length()
                    if d < min_distance:
                        min_distance = d
                        min_unit_id = None
                        min_tile = None
                        min_compass_tile = tile
            else:
                # Get 2d coordinates of all units
                for unit_id in self.parent.render_manager.unit_renderer_dict:
                    unit = self.parent.render_manager.unit_renderer_dict[
                        unit_id]
                    if self.parent.local_engine.isThisMyUnit(unit_id):
                        # Calculate distance between every friendly unit and mouse cursor and remember closest unit
                        d = self.mouse_node.getDistance(unit.node_2d)
                        if d < min_distance:
                            min_distance = d
                            min_unit_id = unit_id
                    else:
                        # Calculate distance between every enemy unit and mouse cursor and remember closest unit
                        d = self.mouse_node.getDistance(unit.node_2d)
                        # To target enemy unit, distance has to be even smaller than needed for regular selection/movement
                        if d < min_distance and d < 0.1:
                            min_distance = d
                            min_unit_id = unit_id

                # Get 2d coordinates for every movement node of the selected unit
                for tile in self.move_np_list:
                    # We cannot do nodepath.getDistance() because tiles are reparented to self.move_node and are in different coord space than mouse node
                    # So we do simple vector math to get distance
                    d = Vec3(self.mouse_node.getPos() - tile.getPos()).length()
                    if d < min_distance:
                        min_distance = d
                        min_unit_id = None
                        min_tile = tile

        # If a unit is the closest to the mouse:
        # - hide movement nodes (Incubation style!)
        # - unmark last hovered unit
        # - unmark last hovered tile
        # - mark new hovered unit
        # TODO: ogs: potencijalna optimizacija da se provjeri da li je self.hovered_unit_id = min_unit_id, tada ne treba unmark+mark
        if min_compass_tile != None:
            if self.hovered_tile != None and not self.hovered_tile.isEmpty():
                self.hovered_tile.setColor(1, 1, 1)
                self.hovered_tile.setScale(0.05)
                self.color_scale_parallel.pause()
                self.hovered_tile = None
            if min_compass_tile != self.hovered_compass_tile:
                if self.hovered_compass_tile != None and not self.hovered_compass_tile.isEmpty(
                ):
                    self.hovered_compass_tile.setColor(1, 1, 1)
                    self.hovered_compass_tile.setScale(0.05)
                    self.color_scale_parallel.pause()
                min_compass_tile.setColor(1, 0, 0)
                s1 = Sequence(
                    LerpColorInterval(min_compass_tile, 0.5, (1, 1, 0, 1)),
                    LerpColorInterval(min_compass_tile, 0.5, (1, 0, 0, 1)))
                s2 = Sequence(LerpScaleInterval(min_compass_tile, 0.5, (0.1)),
                              LerpScaleInterval(min_compass_tile, 0.5, (0.05)))
                self.color_scale_parallel = Parallel(s1, s2)
                self.color_scale_parallel.loop()
            self.hovered_compass_tile = min_compass_tile
        elif min_unit_id != None:
            self.move_node.detachNode()
            if min_unit_id != self.hovered_unit_id and self.hovered_unit_id != None:
                if self.parent.render_manager.unit_renderer_dict.has_key(
                        int(self.hovered_unit_id)):
                    self.parent.render_manager.unit_marker_renderer.unmarkHovered(
                        self.hovered_unit_id)
            self.parent.render_manager.unit_marker_renderer.markHovered(
                min_unit_id)
            if self.hovered_tile != None and not self.hovered_tile.isEmpty():
                self.hovered_tile.setColor(1, 1, 1)
                self.hovered_tile.setScale(0.05)
                self.color_scale_parallel.pause()
                self.hovered_tile = None
            self.hovered_unit_id = min_unit_id
        # If a movement tile is closest to the mouse:
        # - unmark last hovered unit
        # - unmark last marked tile
        # - show movement nodes (Incubation style!)
        # - mark new hovered tile
        elif min_tile != None:
            if self.hovered_unit_id != None:
                if self.parent.render_manager.unit_renderer_dict.has_key(
                        int(self.hovered_unit_id)):
                    self.parent.render_manager.unit_marker_renderer.unmarkHovered(
                        self.hovered_unit_id)
                self.hovered_unit_id = None
            if min_tile != self.hovered_tile:
                self.move_node.reparentTo(aspect2d)
                if self.hovered_tile != None and not self.hovered_tile.isEmpty(
                ):
                    self.hovered_tile.setColor(1, 1, 1)
                    self.hovered_tile.setScale(0.05)
                    self.color_scale_parallel.pause()
                min_tile.setColor(1, 0, 0)
                s1 = Sequence(LerpColorInterval(min_tile, 0.5, (1, 1, 0, 1)),
                              LerpColorInterval(min_tile, 0.5, (1, 0, 0, 1)))
                s2 = Sequence(LerpScaleInterval(min_tile, 0.5, (0.1)),
                              LerpScaleInterval(min_tile, 0.5, (0.05)))
                self.color_scale_parallel = Parallel(s1, s2)
                self.color_scale_parallel.loop()
            self.hovered_tile = min_tile
        # If neither any of the units nor any of the movement tiles is closer than 0.5:
        # - unmark last hovered unit
        # - unmark last hovered tile
        else:
            if self.hovered_unit_id != None:
                if self.parent.render_manager.unit_renderer_dict.has_key(
                        int(self.hovered_unit_id)):
                    self.parent.render_manager.unit_marker_renderer.unmarkHovered(
                        self.hovered_unit_id)
                self.hovered_unit_id = None
            if self.hovered_tile != None and not self.hovered_tile.isEmpty():
                self.hovered_tile.setColor(1, 1, 1)
                self.hovered_tile.setScale(0.05)
                self.color_scale_parallel.pause()
                self.hovered_tile = None
            if self.hovered_compass_tile != None and not self.hovered_compass_tile.isEmpty(
            ):
                self.hovered_compass_tile.setColor(1, 1, 1)
                self.hovered_compass_tile.setScale(0.05)
                self.color_scale_parallel.pause()
                self.hovered_compass_tile = None
        return task.cont
Exemple #14
0
class Cuboid(object):
    def __init__(self, size, translation, rotation, color, text):
        self._visible = False
        wy, wx, wz = size[0], size[1], size[2]
        format = GeomVertexFormat.getV3c4()
        vdata = GeomVertexData('cu_points', format, Geom.UHStatic)
        vdata.setNumRows(8)
        self._pos_writer = GeomVertexWriter(vdata, 'vertex')
        self._color_writer = GeomVertexWriter(vdata, 'color')
        self._pos_writer.set_row(0)
        self._color_writer.set_row(0)
        self._pos_writer.addData3f(-0.5 * wx, -0.5 * wy, 0.)
        self._pos_writer.addData3f(-0.5 * wx, -0.5 * wy, wz)
        self._pos_writer.addData3f(0.5 * wx, -0.5 * wy, wz)
        self._pos_writer.addData3f(0.5 * wx, -0.5 * wy, 0.)
        self._pos_writer.addData3f(-0.5 * wx, 0.5 * wy, 0.)
        self._pos_writer.addData3f(-0.5 * wx, 0.5 * wy, wz)
        self._pos_writer.addData3f(0.5 * wx, 0.5 * wy, wz)
        self._pos_writer.addData3f(0.5 * wx, 0.5 * wy, 0.)
        for i in range(8):
            self._color_writer.addData4f(color[0], color[1], color[2],
                                         color[3])

        lines = GeomLines(Geom.UHStatic)
        lines.addVertices(0, 1)
        lines.addVertices(1, 2)
        lines.addVertices(2, 3)
        lines.addVertices(3, 0)
        lines.addVertices(4, 5)
        lines.addVertices(5, 6)
        lines.addVertices(6, 7)
        lines.addVertices(7, 4)
        lines.addVertices(0, 4)
        lines.addVertices(1, 5)
        lines.addVertices(2, 6)
        lines.addVertices(3, 7)
        cuboid = Geom(vdata)
        cuboid.addPrimitive(lines)
        node = GeomNode('cuboid')
        node.addGeom(cuboid)
        self._node_path = NodePath(node)
        # self.title = OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), pos=(-0.1, 0.1), scale=.05,
        #                           parent=self._node_path, align=TextNode.ARight)

        self._txt_node = TextNode('id')
        self._txt_node.setText(text)
        self._txt_node.setTextScale(0.2)
        self._txt_node.setCardColor(0, 0, 1, 1)
        self._txt_node.setCardAsMargin(0, 0, 0, 0)
        self._txt_node.setCardDecal(True)
        self._txt_node.set_align(2)
        text_geom = GeomNode('text')
        text_geom.addChild(self._txt_node)
        self._txt_np = NodePath(text_geom)
        self._txt_np.reparentTo(self._node_path)

        self.show()
        self.update_values(size, translation, rotation, color, text)

    def update_values(self, size, translation, rotation, color, text):
        if self._visible:
            self.update_bb(self._node_path, self._pos_writer,
                           self._color_writer, tuple(size), tuple(translation),
                           tuple(rotation), tuple(color), text, self._txt_node,
                           self._txt_np)

    def hide(self):
        if self._visible:
            self._node_path.detachNode()
            self._visible = False

    def show(self):
        if not self._visible:
            self._node_path.reparentTo(base.render)
            self._node_path.setTwoSided(True)
            self._node_path.setTransparency(TransparencyAttrib.MAlpha)
            self._visible = True

    def update_bb(self, cuboid, pos_writer, color_writer, size, translation,
                  rotation, color, text, text_node, text_np):
        wx, wy, wz = size
        pos_writer.setRow(0)
        color_writer.setRow(0)
        pos_writer.setData3f(-0.5 * wx, -0.5 * wy, 0.)
        pos_writer.setData3f(-0.5 * wx, -0.5 * wy, wz)
        pos_writer.setData3f(0.5 * wx, -0.5 * wy, wz)
        pos_writer.setData3f(0.5 * wx, -0.5 * wy, 0.)
        pos_writer.setData3f(-0.5 * wx, 0.5 * wy, 0.)
        pos_writer.setData3f(-0.5 * wx, 0.5 * wy, wz)
        pos_writer.setData3f(0.5 * wx, 0.5 * wy, wz)
        pos_writer.setData3f(0.5 * wx, 0.5 * wy, 0.)
        r, g, b, a = color
        for i in range(8):
            color_writer.setData4f(r, g, b, a)

        tx, ty, tz = translation
        ty = -ty
        rx, ry, rz = rotation
        rz = -rz
        cuboid.setPos(ty, tx, tz)
        cuboid.setHpr(-rz - 90., ry, rx)
        text_node.setText(text)
        text_np.setPos((0., 0., wz + 0.2))
        text_np.setHpr(rz + 90., 0, 0)