Example #1
0
def precacheScene(scene, reset=True):
    if reset:
        oldp = scene.getParent()

    rHidden = False
    if render.isHidden():
        rHidden = True
        render.show()

    stashed = NodePathCollection()
    for np in scene.findAllMatches("**;+s"):
        if np.isStashed():
            stashed.addPath(np)
            np.unstash()

    if not scene.isAncestorOf(render):
        # if it's parented to camera,
        # camera will always see it
        scene.reparentTo(render)

    # this says that the scene takes up infinite space,
    # making it always intersect the view frustum,
    # guaranteed to be rendered
    scene.node().setBounds(OmniBoundingVolume())
    scene.node().setFinal(1)

    # Always render if it's a BSP level, even if outside of PVS
    scene.setAttrib(BSPFaceAttrib.makeIgnorePvs(), 1)

    try:
        scene.premungeScene(base.win.getGsg())
        scene.prepareScene(base.win.getGsg())
        base.graphicsEngine.renderFrame()
        base.graphicsEngine.renderFrame()
        base.graphicsEngine.syncFrame()
        base.musicManager.update()

        if reset:
            scene.node().setFinal(0)
            scene.node().clearBounds()

            scene.reparentTo(oldp)

            if rHidden:
                render.hide()

        # restash
        for np in stashed:
            np.stash()
    except:
        # The program might have exited prematurely.
        # This will prevent the game from yelling at us.
        print("precacheScene failed")

    scene.clearAttrib(BSPFaceAttrib)

    return rHidden
Example #2
0
def optimizePhys(root):
    colls = 0
    npc = NodePathCollection()
    for child in root.getChildren():
        if child.node().isOfType(CollisionNode.getClassType()):
            colls += 1
            npc.addPath(child)

    if colls > 1:
        collide = root.attachNewNode("__collide__")
        npc.wrtReparentTo(collide)
        collide.clearModelNodes()
        collide.flattenStrong()

        # Move the possibly combined collisionNodes back to the root.
        collide.getChildren().wrtReparentTo(root)
        collide.removeNode()

    for child in root.getChildren():
        if child.getName() != '__collide__':
            optimizePhys(child)
Example #3
0
def TraverserLevelFirst(startNP, funcOpOnNP, *args, **kwargs):
    npCollection = NodePathCollection()
    currNP = startNP
    npCollection.addPath(currNP)
    notEmtpy = True
    while notEmtpy:
        if currNP.countNumDescendants() == 0:
            # no descendants to add to the stack
            pass
        else:
            # add the currNP's children to stack
            currChildColl = currNP.getChildren()
            npCollection.extend(currChildColl)

        if npCollection.getNumPaths() > 0:
            # operate on the current node
            funcOpOnNP(currNP, *args, **kwargs)
            npCollection.removePath(currNP)
            # get currNP's sister
            if npCollection.getNumPaths() > 0:
                currNP = npCollection.getPath(0)
        else:
            notEmtpy = False  # scene has been walked in level order
            currNP = None
Example #4
0
 def remove(self, psos):
     """ Remove sequence of PSOs from compound object."""
     with self._preserve_child_tranforms():
         NodePathCollection(psos).detach()
     if self.getNumChildren() > 0:
         self._compute_shapes()
Example #5
0
 def add(self, psos):
     """ Add sequence of PSOs to compound object."""
     NodePathCollection(psos).wrtReparentTo(self)
     self._compute_shapes()
Example #6
0
 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)
Example #7
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)
Example #8
0
def TraverserLevelFirst(startNP, funcOpOnNP, *args, **kwargs):
    npCollection = NodePathCollection()
    currNP = startNP
    npCollection.addPath(currNP)
    notEmtpy = True
    while notEmtpy:
            if currNP.countNumDescendants() == 0:
                # no descendants to add to the stack
                pass
            else:
                # add the currNP's children to stack
                currChildColl = currNP.getChildren()
                npCollection.extend(currChildColl)

            if npCollection.getNumPaths() > 0:
                # operate on the current node
                funcOpOnNP(currNP, *args, **kwargs)
                npCollection.removePath(currNP)
                # get currNP's sister
                if npCollection.getNumPaths() > 0:
                    currNP = npCollection.getPath(0)
            else:
                notEmtpy = False  # scene has been walked in level order
                currNP = None


#######
####### http://www.panda3d.org/forums/viewtopic.php?t=5817

    # Classes and functions for polygons, convex hulls (including
    # bounding container convex hulls), point-in-polygon test and so on.

    #import psyco
    ##psyco.full()
    #psyco.profile()


    def isConvex(hull):
        '''Returns True if the given points form convex hull with vertices
        in ccw order.'''

        def _isLeft(q, r, p):
            return (r[0]-q[0])*(p[1]-q[1]) - (p[0]-q[0])*(r[1]-q[1])

        i = -2
        j = -1
        for k in range(len(hull)):
            p = hull[i]
            q = hull[j]
            r = hull[k]
            if _isLeft(p, q, r) <= 0:
                return False
            i = j
            j = k
        return True

    def monotone_chain(points):
        '''Returns a convex hull for an unordered group of 2D points.

        Uses Andrew's Monotone Chain Convex Hull algorithm.'''

        def _isLeft(q, r, p):
            return (r[0]-q[0])*(p[1]-q[1]) - (p[0]-q[0])*(r[1]-q[1])

        # Remove duplicates (this part of code is useless for Panda's
        # Point2 or Point3! In their case set() doesn't remove duplicates;
        # this is why internally this class has all points as (x,y) tuples).
        points = list(set(points))

        # Sort points first by X and then by Y component.
        points.sort()
        # Now, points[0] is the lowest leftmost point, and point[-1] is
        # the highest rightmost point. The line through points[0] and points[-1]
        # will become dividing line between the upper and the lower groups
        # of points.

        p0x, p0y = points[0]
        p1x, p1y = points[-1]

        # Initialize upper and lower stacks as empty lists.
        U = []
        L = []

        # For each point:
        for p in points:

            # First, we check if the point in # i.e. points is left or right or
            # collinear to the dividing line through points[0] and points[-1]:
            cross = (p1x-p0x)*(p[1]-p0y) - (p[0]-p0x)*(p1y-p0y)

            # If the point is lower or colinear, test it for inclusion
            # into the lower stack.
            if cross <= 0:
                # While L contains at least two points and the sequence
                # of the last two points in L and p does not make
                # a counter-clockwise turn:
                while len(L) >= 2 and _isLeft(L[-2], L[-1], p) <= 0:
                    L.pop()
                L.append(p)

            # If the point is higher or colinear, test it for inclusion
            # into the upper stack.
            if cross >= 0:
                # While U contains at least two points and the sequence
                # of the last two points in U and p does not make
                # a clockwise turn:
                while len(U) >= 2 and _isLeft(U[-2], U[-1], p) >= 0:
                    U.pop()
                U.append(p)

        L.pop()
        U.reverse()
        U.pop()

        return L+U

    def isLeft(qx, qy, rx, ry, px, py):
        '''Returns 2D cross product:
            >0 for p left of the infinite line through q and r,
            =0 for p on the line,
            <0 for p right of the line.

        Requires 6 integers or floats for 3 consecutive points: point1_x, point1_y,
        point2_x, point2_y, point3_x, point3_y.'''

        return (rx-qx)*(py-qy) - (px-qx)*(ry-qy)

    def isLeft2(q, r, p):
        '''Returns 2D cross product:
            >0 for p left of the infinite line through q and r,
            =0 for p on the line,
            <0 for p right of the line.

        Requires three consecutive points with (X, Y) as input. If present,
        Z component is ignored.'''

        return (r[0]-q[0])*(p[1]-q[1]) - (p[0]-q[0])*(r[1]-q[1])

    class AABB2D():
        '''Axis-aligned bounding box for 2D shapes.

        Represents minimum and maximum X and Y coordinates for the contained
        shape.'''

        def __init__(self, points):
            '''To be constructed, AABB requires a list of points with two
            coordinates (X, Y) each. If present, Z coordinate is ignored.'''

            self.minX = self.maxX = points[0][0]
            self.minY = self.maxY = points[0][1]

            self._calc(points)

        def _calc(self, points):
            i = 1 # Not from 0!
            while i < len(points):
                px, py = points[i]
                self.minX = min(self.minX, px)
                self.maxX = max(self.maxX, px)
                self.minY = min(self.minY, py)
                self.maxY = max(self.maxY, py)
                i += 1

        def getCenter(self):
            '''Returns the center of the AABB.'''

            x = (self.minX + self.maxX) / 2.0
            y = (self.minY + self.maxY) / 2.0
            return (x, y)

        def isInside(self, point):
            '''Returns True if the given point is inside of this AABB.'''

            px, py = point
            if (px - self.minX) * (px - self.maxX) < 0:
                return False
            if (py - self.minY) * (py - self.maxY) < 0:
                return False
            return True

        def intersect(self, aabb):
            '''Tests if this AABB intersects with another AABB.

            Returns a tuple of values that describe the area of intersection:
            (leftmost X of intersection, rightmost X of itersection,
            lowest Y of intersection, highest Y of itersection),
            or (min X, max X, min Y, max Y).
            Or 'False' if they don't intersect.'''

            if self.minX > aabb.maxX or self.maxX < aabb.minX:
                return False
            if self.minY > aabb.maxY or self.maxY < aabb.minY:
                return False
            minX = max(self.minX, aabb.minX)
            maxX = min(self.maxX, aabb.maxX)
            minY = max(self.minY, aabb.minY)
            maxY = min(self.maxY, aabb.maxY)
            return (minX, maxX, minY, maxY)

    class ConvexPolygon():
        '''Class for convex polygons in 2D.

        To be constructed, requires 3 or more different points/vertices.
        Assumes that polygon is convex, and all vertices are given in
        counter-clockwise order.

        Acceptable format for points is "(x, y)", Panda's built-in Point2 or
        Point3 (but internally they all are transformed into "(x, y)" tuple).

        It can be used to create a bounding convex hull for an unordered group
        of points. To do this, pass keyword argument "create=True" to
        the constructor. Then duplicate and redundant points will be removed
        and the new "clean" bounding convex hull will be created by applying
        Andrew's Monotone Chain Convex Hull algorithm:
        http://www.algorithmist.com/index.php/Monotone_Chain_Convex_Hull'''

        def __init__(self, *args, **kwargs):
            '''Pass it least 3 vertices into constructor.

            Vertices are assumed to be on 2D plane and be given in
            counter-clockwise order.'''

            if len(args) == 1:
                args = args[0]
            points = []
            for v in args:
                if not (isinstance(v, tuple) or isinstance(v, list)):
                    v = (v[0], v[1])
                points.append(v)

            # Initially, it is assumed that given points are vertices of
            # a convex hull in ccw order:
            self.vertices = points

            if "create" in kwargs:
                if kwargs["create"]:
                    # Create bounding convex hull:
                    self.vertices = monotone_chain(points)

            self.numVertices = len(self.vertices)
            # Create bounding box:
            self.aabb = AABB2D(self.vertices)

        def __repr__(self):
            vl = self.vertices
            for i in range(self.numVertices):
                vl[i] = str(vl[i])
            res = "\n".join(vl)
            return res

        def isInside(self, point):
            '''Simplified winding number algorithm for convex polys.

            If the point is within the poly then the endVertex of any edge
            must always be to the left from the infinite line through point and
            startVertex. If they are colinear and the point is inside of
            the AABB of the edge, the point is actually on the edge.

            Currently, this implementation is the fastest one (2.4 seconds
            for 1 mln executions on my computer).'''

            px = point[0]
            py = point[1]

            i = -1
            j = 0
            while j < self.numVertices:
                qx, qy = self.vertices[i]
                rx, ry = self.vertices[j]

                x = (rx-qx)*(py-qy) - (px-qx)*(ry-qy)
                if x <= 0:
                    if x == 0: # for colinear
                        if (px - qx) * (px - rx) > 0:
                            return False
                        if (py - qy) * (py - ry) > 0:
                            return False
                        return True
                    return False # for right turns

                i = j
                j += 1

            return True

        def windingNumber(self, point):
            '''Winding number point-in-polygon test.

            Has some difficulties when the point is located on an upward edge.
            Reference:
            http://softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm'''

            def _isLeft(qx, qy, rx, ry, px, py):
                return (rx-qx)*(py-qy) - (px-qx)*(ry-qy)

            wn = 0
            px = point[0]
            py = point[1]

            i = -1
            j = 0
            while j < self.numVertices:
                qx, qy = self.vertices[i]
                rx, ry = self.vertices[j]

                if (px, py) == (qx, qy):
                    return True

                if qy <= py:
                    if ry > py:
                        cross = _isLeft(qx, qy, rx, ry, px, py)
                        if cross > 0:
                            wn += 1
                else:
                    if ry <= py:
                        cross = _isLeft(qx, qy, rx, ry, px, py)
                        if cross < 0:
                            wn -= 1

                i = j
                j += 1

            if wn == 0:
                return False
            return True

        def crossingNumber(self, point):
            '''Crossing number point-in-polygon test.

            Has some difficulties when the point is located on an upward edge.
            Reference:
            http://softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm'''

            cn = 0
            px = point[0]
            py = point[1]

            i = -1
            j = 0
            while j < self.numVertices:
                qx, qy = self.vertices[i]
                rx, ry = self.vertices[j]

                if (px, py) == (qx, qy):
                    return True

                if (    ((qy <= py) and (ry > py)) or \
                        ((qy > py) and (ry <= py))    ):
                    vt = (py - qy) / (ry - qy)
                    if (px < qx + vt * (rx - qx)):
                        cn += 1

                i = j
                j += 1

            return cn%2