Esempio n. 1
0
class RepairPumpingGame(RepairMincroGame):
    pumpDownSounds = None
    pumpUpSounds = None
    pumpGoodSounds = None
    pumpBadSounds = None
    
    def __init__(self, repairGame):
        self.config = RepairGlobals.Pumping
        RepairMincroGame.__init__(self, repairGame, 'pumping', PLocalizer.Minigame_Repair_Pumping_Start)

    
    def _initVars(self):
        RepairMincroGame._initVars(self)
        self.pumpRate = 0.0
        self.remainingWater = 1.0
        self.chainCount = 0
        self.barDirection = UP
        self.goalIndex = TOP
        self.currentBarRate = self.config.barStartRange[0]
        self.hitRange = self.config.hitRange[0]
        self.barPercent = 0.0
        self.failedPercentAndDirection = (-1.0, UP)

    
    def _initAudio(self):
        RepairMincroGame._initAudio(self)
        if not self.pumpDownSounds:
            RepairPumpingGame.pumpDownSounds = (loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_DOWN01), loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_DOWN02), loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_DOWN03))
            RepairPumpingGame.pumpUpSounds = (loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_UP01), loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_UP02), loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_UP03))
            RepairPumpingGame.pumpGoodSounds = (loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_GOOD01), loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_GOOD02), loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_GOOD03), loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_GOOD04), loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_GOOD05), loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_GOOD06))
            RepairPumpingGame.pumpBadSounds = (loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_BAD),)
        

    
    def _initVisuals(self):
        RepairMincroGame._initVisuals(self)
        self.model = loader.loadModel('models/gui/pir_m_gui_srp_pumping_main')
        self.visual = self.attachNewNode('visual')
        self.visual.setPos(-0.25, 0.0, 0.074999999999999997)
        goalTopLoc = self.model.find('**/locator_top')
        goalTopLoc.reparentTo(self.visual)
        goalBottomLoc = self.model.find('**/locator_bottom')
        goalBottomLoc.reparentTo(self.visual)
        self.goalPositions = (goalBottomLoc.getPos(self), goalTopLoc.getPos(self))
        self.greatLabel = DirectLabel(text = PLocalizer.Minigame_Repair_Pumping_Great, text_fg = (0.20000000000000001, 0.80000000000000004, 0.29999999999999999, 1.0), text_pos = (0.0, 0.59999999999999998), text_align = TextNode.ACenter, text_font = PiratesGlobals.getPirateFont(), relief = None, text_shadow = (0.0, 0.0, 0.0, 1.0), scale = (0.080000000000000002, 0.080000000000000002, 0.080000000000000002), pos = (-0.46500000000000002, 0.0, 0.0), parent = self)
        self.failLabel = DirectLabel(text = PLocalizer.Minigame_Repair_Pumping_Fail, text_fg = (0.80000000000000004, 0.20000000000000001, 0.29999999999999999, 1.0), text_pos = (0.0, 0.59999999999999998), text_align = TextNode.ARight, text_font = PiratesGlobals.getPirateFont(), text_shadow = (0.0, 0.0, 0.0, 1.0), relief = None, scale = (0.080000000000000002, 0.080000000000000002, 0.080000000000000002), pos = (-0.625, 0.0, 0.0), parent = self)
        self.shipBackground = self.model.find('**/static_ship_background')
        self.shipBackground.reparentTo(self.visual)
        self.waterMeter = self.model.find('**/sprite_waterBottom')
        self.waterMeter.reparentTo(self.visual)
        self.waterTop = self.model.find('**/sprite_waterTop')
        self.waterTop.reparentTo(self.visual)
        self.waterMeterTopLoc = self.waterMeter.find('**/locator_topOfShipWater')
        self.pumpBackground = self.model.find('**/pumpBackground')
        self.pumpBackground.reparentTo(self.visual)
        self.pumpWaterTop = self.model.find('**/sprite_pumpWaterTop')
        self.pumpWaterTop.reparentTo(self.visual)
        self.pumpWaterBottom = self.model.find('**/sprite_pumpWaterBottom')
        self.pumpWaterBottom.reparentTo(self.visual)
        self.pumpWaterTopLoc = self.pumpWaterBottom.find('**/locator_topOfPumpWater')
        self.pumpHandle = self.model.find('**/sprite_handle')
        self.pumpHandle.reparentTo(self.visual)
        self.pumpBar = self.model.find('**/static_pump')
        self.pumpBar.reparentTo(self.visual)
        self.goalBox = self.model.find('**/sprite_clickField')
        self.goalBox.reparentTo(self.visual)
        self.goalBox.setTransparency(1)
        self.enableGoalBox()
        self.pumpLine = self.model.find('**/sprite_bar')
        self.pumpLine.reparentTo(self.visual)
        self.ghostLine = self.visual.attachNewNode('ghostLine')
        self.pumpLine.getChild(0).copyTo(self.ghostLine)
        self.ghostLine.setScale(self.pumpLine.getScale())
        self.ghostLine.setColor(1.0, 0.20000000000000001, 0.20000000000000001, 1.0)
        self.shipForground = self.model.find('**/static_ship_foreground')
        self.shipForground.reparentTo(self.visual)
        cm = CardMaker('cardMaker')
        cm.setFrame(-0.33000000000000002, 0.33000000000000002, 0.0, 1.0)
        self.goalBox.setZ(self.goalPositions[TOP].getZ())
        self.goalBoxStartScale = self.goalBox.getSz()
        self.enableGoalBox()
        self.pumpWaterUpLerp = LerpFunc(self.setPumpWater, fromData = -0.10000000000000001, toData = 1.0, duration = 0.5)
        self.pumpWaterDownLerp = LerpFunc(self.setPumpWater, fromData = 1.0, toData = -0.10000000000000001, duration = 0.5)
        self.model.removeNode()
        del self.model

    
    def destroy(self):
        del self.goalPositions
        self.pumpBar.removeNode()
        self.pumpLine.removeNode()
        self.goalBox.removeNode()
        self.pumpHandle.removeNode()
        self.waterMeter.removeNode()
        self.waterTop.removeNode()
        self.ghostLine.removeNode()
        self.shipBackground.removeNode()
        self.shipForground.removeNode()

    
    def reset(self):
        RepairMincroGame.reset(self)
        self.remainingWater = WATER_LEVEL_START
        self.chainCount = 0
        self.barDirection = UP
        self.goalIndex = TOP
        self.barPercent = 0.0
        self.failedPercentAndDirection = (-1.0, UP)
        actualZ = self.goalPositions[BOTTOM].getZ()
        actualZ -= self.visual.getZ()
        self.pumpLine.setZ(actualZ)
        self.setGoalIndex(TOP)
        self.pumpHandle.setR(ROTATION_MIN)
        self.waterMeter.setSz(WATER_LEVEL_START)
        self.waterTop.setZ(self.waterMeterTopLoc.getZ(self.visual))
        self.ghostLine.stash()
        self.setPumpWater(1.0)
        self.failLabel.stash()
        self.greatLabel.stash()
        self.repairGame.gui.setTutorial(self.name)
        self.repairGame.gui.setTitle(self.name)

    
    def setDifficulty(self, difficulty):
        RepairMincroGame.setDifficulty(self, difficulty)
        percent = difficulty / self.repairGame.difficultyMax
        dif = self.config.pumpPowerRange[0] - self.config.pumpPowerRange[1]
        self.pumpRate = self.config.pumpPowerRange[0] - dif * percent
        dif = self.config.barStartRange[0] - self.config.barStartRange[1]
        self.currentBarRate = self.config.barStartRange[0] - dif * percent
        dif = self.config.hitRange[0] - self.config.hitRange[1]
        self.hitRange = self.config.hitRange[0] - dif * percent
        self.goalBox.setSz((self.hitRange / 0.17999999999999999) * self.goalBoxStartScale)

    
    def setGoalIndex(self, goalIndex):
        self.goalIndex = goalIndex
        self.goalBox.setZ(self, self.goalPositions[goalIndex].getZ())
        self.goalBox.setR(180 * (goalIndex - 1))

    
    def resetFail(self):
        self.failedPercentAndDirection = (-1.0, UP)
        self.enableGoalBox()
        self.hideMarkers()

    
    def updateTask(self, task):
        dt = globalClock.getDt()
        percentTimeThisStep = dt / (self.currentBarRate + self.config.barSpeedMax)
        self.barPercent = self.barPercent + percentTimeThisStep * self.barDirection
        if self.failedPercentAndDirection[0] >= 0.0:
            if self.failedPercentAndDirection[1] != self.barDirection:
                if self.failedPercentAndDirection[0] * self.barDirection < self.barPercent * self.barDirection:
                    self.resetFail()
                
            
        
        if self.barPercent >= 1.0:
            self.barPercent = 1.0
            self.barDirection = DOWN
            if not self.isLineInBox():
                self.chainCount = 0
            
            if self.failedPercentAndDirection[0] < 0.5:
                self.resetFail()
            
        elif self.barPercent <= 0.0:
            self.barPercent = 0.0
            self.barDirection = UP
            if not self.isLineInBox():
                self.chainCount = 0
            
            if self.failedPercentAndDirection[0] > 0.5:
                self.resetFail()
            
        
        actualZ = self.goalPositions[0].getZ() + (self.goalPositions[1].getZ() - self.goalPositions[0].getZ()) * self.barPercent
        actualZ -= self.visual.getZ()
        self.pumpLine.setZ(actualZ)
        return Task.cont

    
    def enableGoalBox(self):
        self.goalBox.setColor(0.20000000000000001, 1.0, 0.20000000000000001, 0.59999999999999998)
        self.goalBoxEnabled = 1

    
    def disableGoalBox(self):
        self.goalBox.setColor(1.0, 0.20000000000000001, 0.20000000000000001, 0.29999999999999999)
        self.goalBoxEnabled = 0

    
    def isLineInBox(self):
        if self.goalIndex == TOP:
            return self.barPercent >= 1.0 - self.hitRange
        else:
            return self.barPercent <= self.hitRange

    
    def onMouseClick(self):
        if self.isLineInBox() and self.goalBoxEnabled == 1:
            actualPumpAmount = self.pumpRate + self.config.chainMultiplier * self.chainCount * self.pumpRate
            actualPumpAmount *= WATER_LEVEL_START - WATER_LEVEL_DONE
            self.remainingWater -= actualPumpAmount
            self.remainingWater = max(0.0, self.remainingWater)
            self.waterMeter.setSz(self.remainingWater)
            self.waterTop.setZ(self.waterMeterTopLoc.getZ(self.visual) - 0.001)
            if self.barPercent > 0.5:
                self.pumpWaterDownLerp.duration = self.currentBarRate
                self.pumpWaterDownLerp.start()
                self.barDirection = DOWN
                self.pumpHandle.setR(ROTATION_MAX)
                random.choice(self.pumpDownSounds).play()
            else:
                self.pumpWaterUpLerp.duration = self.currentBarRate
                self.pumpWaterUpLerp.start()
                self.barDirection = UP
                self.pumpHandle.setR(ROTATION_MIN)
                random.choice(self.pumpUpSounds).play()
            if self.barPercent > 0.5:
                self.setGoalIndex(BOTTOM)
            else:
                self.setGoalIndex(TOP)
            self.currentBarRate /= self.config.barSpeedIncrease
            self.chainCount += 1
            self.setSuccessMarker()
            if self.remainingWater <= WATER_LEVEL_DONE and self.barDirection == DOWN:
                self.remainingWater = 0.0
                self.request('Outro')
                return None
            
            totalRange = WATER_LEVEL_START - WATER_LEVEL_DONE
            current = WATER_LEVEL_START - self.remainingWater
            percent = min(100, int((current / totalRange) * 100))
            self.repairGame.d_reportMincroGameProgress(percent, max(0, min(5, self.chainCount) - 1))
        else:
            self.disableGoalBox()
            self.currentBarRate /= self.config.barSpeedDecrease
            self.currentBarRate += (1 - self.config.barSpeedDecrease) * self.config.barSpeedMin
            self.currentBarRate = min(self.currentBarRate, self.config.barSpeedMin)
            self.setFailMarker()
            self.chainCount = 0
            self.failedPercentAndDirection = (self.barPercent, self.barDirection)

    
    def setPumpWater(self, value):
        self.pumpWaterBottom.setSz(value)
        self.pumpWaterTop.setZ(self.pumpWaterTopLoc.getZ(self.visual))

    
    def setSuccessMarker(self):
        self.greatLabel.setZ(self.pumpLine.getZ())
        self.greatLabel.unstash()
        pumpSoundIndex = min(len(self.pumpGoodSounds) - 1, self.chainCount / 2)
        self.pumpGoodSounds[pumpSoundIndex].play()

    
    def setFailMarker(self):
        self.hideMarkers()
        self.ghostLine.setPos(self.pumpLine.getPos())
        self.ghostLine.unstash()
        self.failLabel.setZ(self.pumpLine.getZ())
        self.failLabel.unstash()
        random.choice(self.pumpBadSounds).play()

    
    def hideMarkers(self):
        self.ghostLine.stash()
        self.greatLabel.stash()
        self.failLabel.stash()

    
    def enterGame(self):
        RepairMincroGame.enterGame(self)
        taskMgr.add(self.updateTask, 'RepairPumpingGame.updateTask')
        self.accept('mouse1', self.onMouseClick)
        self.enableGoalBox()

    
    def exitGame(self):
        RepairMincroGame.exitGame(self)
        taskMgr.remove('RepairPumpingGame.updateTask')
        self.ignore('mouse1')

    
    def enterOutro(self):
        RepairMincroGame.enterOutro(self)
        self.repairGame.d_reportMincroGameScore(150)
class RepairPumpingGame(RepairMincroGame):
    pumpDownSounds = None
    pumpUpSounds = None
    pumpGoodSounds = None
    pumpBadSounds = None
    
    def __init__(self, repairGame):
        self.config = RepairGlobals.Pumping
        RepairMincroGame.__init__(self, repairGame, 'pumping', PLocalizer.Minigame_Repair_Pumping_Start)

    
    def _initVars(self):
        RepairMincroGame._initVars(self)
        self.pumpRate = 0.0
        self.remainingWater = 1.0
        self.chainCount = 0
        self.barDirection = UP
        self.goalIndex = TOP
        self.currentBarRate = self.config.barStartRange[0]
        self.hitRange = self.config.hitRange[0]
        self.barPercent = 0.0
        self.failedPercentAndDirection = (-1.0, UP)

    
    def _initAudio(self):
        RepairMincroGame._initAudio(self)
        if not self.pumpDownSounds:
            RepairPumpingGame.pumpDownSounds = (loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_DOWN01), loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_DOWN02), loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_DOWN03))
            RepairPumpingGame.pumpUpSounds = (loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_UP01), loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_UP02), loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_UP03))
            RepairPumpingGame.pumpGoodSounds = (loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_GOOD01), loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_GOOD02), loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_GOOD03), loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_GOOD04), loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_GOOD05), loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_GOOD06))
            RepairPumpingGame.pumpBadSounds = (loadSfx(SoundGlobals.SFX_MINIGAME_REPAIR_PUMP_BAD),)
        

    
    def _initVisuals(self):
        RepairMincroGame._initVisuals(self)
        self.model = loader.loadModel('models/gui/pir_m_gui_srp_pumping_main')
        self.visual = self.attachNewNode('visual')
        self.visual.setPos(-0.25, 0.0, 0.074999999999999997)
        goalTopLoc = self.model.find('**/locator_top')
        goalTopLoc.reparentTo(self.visual)
        goalBottomLoc = self.model.find('**/locator_bottom')
        goalBottomLoc.reparentTo(self.visual)
        self.goalPositions = (goalBottomLoc.getPos(self), goalTopLoc.getPos(self))
        self.greatLabel = DirectLabel(text = PLocalizer.Minigame_Repair_Pumping_Great, text_fg = (0.20000000000000001, 0.80000000000000004, 0.29999999999999999, 1.0), text_pos = (0.0, 0.59999999999999998), text_align = TextNode.ACenter, text_font = PiratesGlobals.getPirateFont(), relief = None, text_shadow = (0.0, 0.0, 0.0, 1.0), scale = (0.080000000000000002, 0.080000000000000002, 0.080000000000000002), pos = (-0.46500000000000002, 0.0, 0.0), parent = self)
        self.failLabel = DirectLabel(text = PLocalizer.Minigame_Repair_Pumping_Fail, text_fg = (0.80000000000000004, 0.20000000000000001, 0.29999999999999999, 1.0), text_pos = (0.0, 0.59999999999999998), text_align = TextNode.ARight, text_font = PiratesGlobals.getPirateFont(), text_shadow = (0.0, 0.0, 0.0, 1.0), relief = None, scale = (0.080000000000000002, 0.080000000000000002, 0.080000000000000002), pos = (-0.625, 0.0, 0.0), parent = self)
        self.shipBackground = self.model.find('**/static_ship_background')
        self.shipBackground.reparentTo(self.visual)
        self.waterMeter = self.model.find('**/sprite_waterBottom')
        self.waterMeter.reparentTo(self.visual)
        self.waterTop = self.model.find('**/sprite_waterTop')
        self.waterTop.reparentTo(self.visual)
        self.waterMeterTopLoc = self.waterMeter.find('**/locator_topOfShipWater')
        self.pumpBackground = self.model.find('**/pumpBackground')
        self.pumpBackground.reparentTo(self.visual)
        self.pumpWaterTop = self.model.find('**/sprite_pumpWaterTop')
        self.pumpWaterTop.reparentTo(self.visual)
        self.pumpWaterBottom = self.model.find('**/sprite_pumpWaterBottom')
        self.pumpWaterBottom.reparentTo(self.visual)
        self.pumpWaterTopLoc = self.pumpWaterBottom.find('**/locator_topOfPumpWater')
        self.pumpHandle = self.model.find('**/sprite_handle')
        self.pumpHandle.reparentTo(self.visual)
        self.pumpBar = self.model.find('**/static_pump')
        self.pumpBar.reparentTo(self.visual)
        self.goalBox = self.model.find('**/sprite_clickField')
        self.goalBox.reparentTo(self.visual)
        self.goalBox.setTransparency(1)
        self.enableGoalBox()
        self.pumpLine = self.model.find('**/sprite_bar')
        self.pumpLine.reparentTo(self.visual)
        self.ghostLine = self.visual.attachNewNode('ghostLine')
        self.pumpLine.getChild(0).copyTo(self.ghostLine)
        self.ghostLine.setScale(self.pumpLine.getScale())
        self.ghostLine.setColor(1.0, 0.20000000000000001, 0.20000000000000001, 1.0)
        self.shipForground = self.model.find('**/static_ship_foreground')
        self.shipForground.reparentTo(self.visual)
        cm = CardMaker('cardMaker')
        cm.setFrame(-0.33000000000000002, 0.33000000000000002, 0.0, 1.0)
        self.goalBox.setZ(self.goalPositions[TOP].getZ())
        self.goalBoxStartScale = self.goalBox.getSz()
        self.enableGoalBox()
        self.pumpWaterUpLerp = LerpFunc(self.setPumpWater, fromData = -0.10000000000000001, toData = 1.0, duration = 0.5)
        self.pumpWaterDownLerp = LerpFunc(self.setPumpWater, fromData = 1.0, toData = -0.10000000000000001, duration = 0.5)
        self.model.removeNode()
        del self.model

    
    def destroy(self):
        del self.goalPositions
        self.pumpBar.removeNode()
        self.pumpLine.removeNode()
        self.goalBox.removeNode()
        self.pumpHandle.removeNode()
        self.waterMeter.removeNode()
        self.waterTop.removeNode()
        self.ghostLine.removeNode()
        self.shipBackground.removeNode()
        self.shipForground.removeNode()

    
    def reset(self):
        RepairMincroGame.reset(self)
        self.remainingWater = WATER_LEVEL_START
        self.chainCount = 0
        self.barDirection = UP
        self.goalIndex = TOP
        self.barPercent = 0.0
        self.failedPercentAndDirection = (-1.0, UP)
        actualZ = self.goalPositions[BOTTOM].getZ()
        actualZ -= self.visual.getZ()
        self.pumpLine.setZ(actualZ)
        self.setGoalIndex(TOP)
        self.pumpHandle.setR(ROTATION_MIN)
        self.waterMeter.setSz(WATER_LEVEL_START)
        self.waterTop.setZ(self.waterMeterTopLoc.getZ(self.visual))
        self.ghostLine.stash()
        self.setPumpWater(1.0)
        self.failLabel.stash()
        self.greatLabel.stash()
        self.repairGame.gui.setTutorial(self.name)
        self.repairGame.gui.setTitle(self.name)

    
    def setDifficulty(self, difficulty):
        RepairMincroGame.setDifficulty(self, difficulty)
        percent = difficulty / self.repairGame.difficultyMax
        dif = self.config.pumpPowerRange[0] - self.config.pumpPowerRange[1]
        self.pumpRate = self.config.pumpPowerRange[0] - dif * percent
        dif = self.config.barStartRange[0] - self.config.barStartRange[1]
        self.currentBarRate = self.config.barStartRange[0] - dif * percent
        dif = self.config.hitRange[0] - self.config.hitRange[1]
        self.hitRange = self.config.hitRange[0] - dif * percent
        self.goalBox.setSz((self.hitRange / 0.17999999999999999) * self.goalBoxStartScale)

    
    def setGoalIndex(self, goalIndex):
        self.goalIndex = goalIndex
        self.goalBox.setZ(self, self.goalPositions[goalIndex].getZ())
        self.goalBox.setR(180 * (goalIndex - 1))

    
    def resetFail(self):
        self.failedPercentAndDirection = (-1.0, UP)
        self.enableGoalBox()
        self.hideMarkers()

    
    def updateTask(self, task):
        dt = globalClock.getDt()
        percentTimeThisStep = dt / (self.currentBarRate + self.config.barSpeedMax)
        self.barPercent = self.barPercent + percentTimeThisStep * self.barDirection
        if self.failedPercentAndDirection[0] >= 0.0:
            if self.failedPercentAndDirection[1] != self.barDirection:
                if self.failedPercentAndDirection[0] * self.barDirection < self.barPercent * self.barDirection:
                    self.resetFail()
                
            
        
        if self.barPercent >= 1.0:
            self.barPercent = 1.0
            self.barDirection = DOWN
            if not self.isLineInBox():
                self.chainCount = 0
            
            if self.failedPercentAndDirection[0] < 0.5:
                self.resetFail()
            
        elif self.barPercent <= 0.0:
            self.barPercent = 0.0
            self.barDirection = UP
            if not self.isLineInBox():
                self.chainCount = 0
            
            if self.failedPercentAndDirection[0] > 0.5:
                self.resetFail()
            
        
        actualZ = self.goalPositions[0].getZ() + (self.goalPositions[1].getZ() - self.goalPositions[0].getZ()) * self.barPercent
        actualZ -= self.visual.getZ()
        self.pumpLine.setZ(actualZ)
        return Task.cont

    
    def enableGoalBox(self):
        self.goalBox.setColor(0.20000000000000001, 1.0, 0.20000000000000001, 0.59999999999999998)
        self.goalBoxEnabled = 1

    
    def disableGoalBox(self):
        self.goalBox.setColor(1.0, 0.20000000000000001, 0.20000000000000001, 0.29999999999999999)
        self.goalBoxEnabled = 0

    
    def isLineInBox(self):
        if self.goalIndex == TOP:
            return self.barPercent >= 1.0 - self.hitRange
        else:
            return self.barPercent <= self.hitRange

    
    def onMouseClick(self):
        if self.isLineInBox() and self.goalBoxEnabled == 1:
            actualPumpAmount = self.pumpRate + self.config.chainMultiplier * self.chainCount * self.pumpRate
            actualPumpAmount *= WATER_LEVEL_START - WATER_LEVEL_DONE
            self.remainingWater -= actualPumpAmount
            self.remainingWater = max(0.0, self.remainingWater)
            self.waterMeter.setSz(self.remainingWater)
            self.waterTop.setZ(self.waterMeterTopLoc.getZ(self.visual) - 0.001)
            if self.barPercent > 0.5:
                self.pumpWaterDownLerp.duration = self.currentBarRate
                self.pumpWaterDownLerp.start()
                self.barDirection = DOWN
                self.pumpHandle.setR(ROTATION_MAX)
                random.choice(self.pumpDownSounds).play()
            else:
                self.pumpWaterUpLerp.duration = self.currentBarRate
                self.pumpWaterUpLerp.start()
                self.barDirection = UP
                self.pumpHandle.setR(ROTATION_MIN)
                random.choice(self.pumpUpSounds).play()
            if self.barPercent > 0.5:
                self.setGoalIndex(BOTTOM)
            else:
                self.setGoalIndex(TOP)
            self.currentBarRate /= self.config.barSpeedIncrease
            self.chainCount += 1
            self.setSuccessMarker()
            if self.remainingWater <= WATER_LEVEL_DONE and self.barDirection == DOWN:
                self.remainingWater = 0.0
                self.request('Outro')
                return None
            
            totalRange = WATER_LEVEL_START - WATER_LEVEL_DONE
            current = WATER_LEVEL_START - self.remainingWater
            percent = min(100, int((current / totalRange) * 100))
            self.repairGame.d_reportMincroGameProgress(percent, max(0, min(5, self.chainCount) - 1))
        else:
            self.disableGoalBox()
            self.currentBarRate /= self.config.barSpeedDecrease
            self.currentBarRate += (1 - self.config.barSpeedDecrease) * self.config.barSpeedMin
            self.currentBarRate = min(self.currentBarRate, self.config.barSpeedMin)
            self.setFailMarker()
            self.chainCount = 0
            self.failedPercentAndDirection = (self.barPercent, self.barDirection)

    
    def setPumpWater(self, value):
        self.pumpWaterBottom.setSz(value)
        self.pumpWaterTop.setZ(self.pumpWaterTopLoc.getZ(self.visual))

    
    def setSuccessMarker(self):
        self.greatLabel.setZ(self.pumpLine.getZ())
        self.greatLabel.unstash()
        pumpSoundIndex = min(len(self.pumpGoodSounds) - 1, self.chainCount / 2)
        self.pumpGoodSounds[pumpSoundIndex].play()

    
    def setFailMarker(self):
        self.hideMarkers()
        self.ghostLine.setPos(self.pumpLine.getPos())
        self.ghostLine.unstash()
        self.failLabel.setZ(self.pumpLine.getZ())
        self.failLabel.unstash()
        random.choice(self.pumpBadSounds).play()

    
    def hideMarkers(self):
        self.ghostLine.stash()
        self.greatLabel.stash()
        self.failLabel.stash()

    
    def enterGame(self):
        RepairMincroGame.enterGame(self)
        taskMgr.add(self.updateTask, 'RepairPumpingGame.updateTask')
        self.accept('mouse1', self.onMouseClick)
        self.enableGoalBox()

    
    def exitGame(self):
        RepairMincroGame.exitGame(self)
        taskMgr.remove('RepairPumpingGame.updateTask')
        self.ignore('mouse1')

    
    def enterOutro(self):
        RepairMincroGame.enterOutro(self)
        self.repairGame.d_reportMincroGameScore(150)
Esempio n. 3
0
class CharacterGUI:
    """Widget with the selected character info."""

    def __init__(self):
        self.char = None  # the chosen character
        self.rest_list_shown = False
        self._status_lab = None
        self._rest_buttons = {}
        self._char_desc_wids = []
        self._char_desc_shown = False

        self._fr = DirectFrame(
            parent=base.a2dTopLeft,  # noqa: F821
            frameSize=(-0.31, 0.31, -0.1, 0.115),
            pos=(0.31, 0, -1.9),
            frameTexture=GUI_PIC + "metal1.png",
            state=DGG.NORMAL,
        )
        self._fr.setTransparency(TransparencyAttrib.MAlpha)

        # a "?" button to open a detailed description of the character
        self._char_desc_but = DirectButton(
            parent=self._fr,
            pos=(0.27, 0, 0.0675),
            command=self._show_char_desc,
            clickSound=base.main_menu.click_snd,  # noqa: F821
            **ABOUT_BUT_PARAMS,
        )
        DirectLabel(  # Name:
            parent=self._fr,
            text=base.labels.CHARACTERS[0],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.1, 0.1, 0.1, 0.1),
            text_scale=0.03,
            text_fg=RUST_COL,
            pos=(-0.22, 0, 0.07),
        )
        self._char_name = DirectLabel(
            parent=self._fr,
            text="",
            frameSize=(0.1, 0.1, 0.1, 0.1),
            text_scale=0.03,
            text_fg=SILVER_COL,
            pos=(-0.09, 0, 0.069),
        )
        self._traits = DirectLabel(
            parent=self._fr,
            text="",
            frameSize=(0.1, 0.1, 0.1, 0.1),
            text_scale=(0.028, 0.028),
            text_fg=SILVER_COL,
            text_font=base.main_font,  # noqa: F821
            pos=(0, 0, 0.025),
        )
        DirectLabel(  # Class:
            parent=self._fr,
            text=base.labels.CHARACTERS[1],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.1, 0.1, 0.1, 0.1),
            text_scale=0.03,
            text_fg=RUST_COL,
            pos=(0.05, 0, 0.07),
        )
        self._char_class = DirectLabel(
            parent=self._fr,
            text="",
            frameSize=(0.1, 0.1, 0.1, 0.1),
            text_scale=0.03,
            text_fg=SILVER_COL,
            pos=(0.17, 0, 0.068),
        )
        DirectLabel(  # Health
            parent=self._fr,
            text=base.labels.CHARACTERS[2],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.1, 0.1, 0.1, 0.1),
            text_scale=0.03,
            text_fg=RUST_COL,
            pos=(-0.22, 0, -0.015),
        )
        self._char_health = DirectWaitBar(
            parent=self._fr,
            frameSize=(-0.17, 0.17, -0.002, 0.002),
            frameColor=(0.35, 0.35, 0.35, 1),
            value=0,
            barColor=(0.85, 0.2, 0.28, 1),
            pos=(0.07, 0, -0.008),
        )
        DirectLabel(  # Energy
            parent=self._fr,
            text=base.labels.CHARACTERS[3],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.1, 0.1, 0.1, 0.1),
            text_scale=0.03,
            text_fg=RUST_COL,
            pos=(-0.216, 0, -0.06),
        )
        self._char_energy = DirectWaitBar(
            parent=self._fr,
            frameSize=(-0.17, 0.17, -0.002, 0.002),
            frameColor=(0.35, 0.35, 0.35, 1),
            value=0,
            barColor=(0.46, 0.61, 0.53, 1),
            pos=(0.07, 0, -0.053),
        )
        self._tip = OnscreenText(
            parent=base.render2d,  # noqa: F821
            text="",
            font=base.main_font,  # noqa: F821
            scale=(0.021, 0.027),
            fg=SILVER_COL,
            bg=(0, 0, 0, 0.4),
        )
        self._tip.hide()

        self._disease = DirectFrame(
            parent=self._fr,
            frameSize=(-0.02, 0.02, -0.02, 0.02),
            pos=(0.27, 0, -0.008),
            frameTexture=GUI_PIC + "disease.png",
        )
        self._disease.setTransparency(TransparencyAttrib.MAlpha)

        self.clear_char_info()

    def _update_char_info(self, task):
        """Track the chosen character parameters in the GUI."""
        if self.char.is_dead:
            self.clear_char_info()
            return task.done

        self._char_health["value"] = self.char.health
        self._char_energy["value"] = self.char.energy
        self._traits["text"] = ", ".join(self.char.traits)

        if self.char.is_diseased:
            self._disease.show()
        else:
            self._disease.hide()

        if self._char_desc_shown:
            self._update_desc()

        return task.again

    def _update_desc(self):
        """Update the chosen character description."""
        to_del = []
        for wid in self._char_desc_wids:
            if wid["text"] not in (
                # Traits
                base.labels.CHARACTERS[5],  # noqa: F821
                # Status
                base.labels.CHARACTERS[4],  # noqa: F821
                "",
            ):
                wid.destroy()
                to_del.append(wid)

        for del_wid in to_del:
            self._char_desc_wids.remove(del_wid)

        self._fill_status(self._fill_traits(0.64))

    def _fill_traits(self, shift):
        """Fill the chosen character traits.

        Args:
            shift (float): Z-coor for the new widgets.

        Returns:
            float: Z-coor including the new widgets shift.
        """
        shift -= 0.03
        for trait in self.char.traits + self.char.disabled_traits:
            self._char_desc_wids.append(
                DirectLabel(
                    parent=self._fr,
                    text=trait,
                    frameSize=(0.1, 0.1, 0.1, 0.1),
                    text_scale=0.03,
                    text_font=base.main_font,  # noqa: F821
                    text_fg=SILVER_COL
                    if trait in self.char.traits
                    else (0.3, 0.3, 0.3, 1),
                    pos=(0, 0, shift),
                )
            )
            self._char_desc_wids.append(
                DirectLabel(
                    parent=self._fr,
                    text=base.labels.TRAIT_DESC[trait],  # noqa: F821
                    text_font=base.main_font,  # noqa: F821
                    frameSize=(0.1, 0.1, 0.1, 0.1),
                    text_scale=0.029,
                    text_fg=SILVER_COL
                    if trait in self.char.traits
                    else (0.3, 0.3, 0.3, 1),
                    pos=(0, 0, shift - 0.045),
                )
            )
            shift -= 0.1
        return shift

    def _fill_status(self, shift):
        """Fill the chosen character status.

        Args:
            shift (float): Z-coor for the new widgets.
        """
        shift -= 0.04
        for status in self.char.statuses:
            self._char_desc_wids.append(
                DirectLabel(
                    parent=self._fr,
                    text=status,
                    text_font=base.main_font,  # noqa: F821
                    frameSize=(0.1, 0.1, 0.1, 0.1),
                    text_scale=0.029,
                    text_fg=SILVER_COL,
                    pos=(0, 0, shift),
                )
            )
            shift -= 0.045

    def _show_char_desc(self):
        """Show detailed character description.

        Includes description of every character's
        trait and their current status.
        """
        if self._char_desc_shown:
            self._fr["frameSize"] = (-0.31, 0.31, -0.1, 0.115)
            clear_wids(self._char_desc_wids)
            self._status_lab = None
        else:
            shift = 0.7
            self._fr["frameSize"] = (-0.31, 0.31, -0.1, shift)
            shift -= 0.06
            self._char_desc_wids.append(
                DirectLabel(
                    parent=self._fr,
                    # Traits
                    text=base.labels.CHARACTERS[5],  # noqa: F821,
                    text_font=base.main_font,  # noqa: F821,
                    frameSize=(0.1, 0.1, 0.1, 0.1),
                    text_scale=0.03,
                    text_fg=RUST_COL,
                    pos=(-0.225, 0, shift),
                )
            )
            if self.char.id in base.team.chars.keys():  # noqa: F821
                traits_but = DirectButton(
                    parent=self._fr,
                    text="",
                    frameSize=(-0.025, 0.025, -0.025, 0.025),
                    frameTexture=GUI_PIC + "like.png",
                    relief="flat",
                    pos=(0.265, 0, shift + 0.013),
                    command=base.traits_gui.show,  # noqa: F821
                )
                traits_but.bind(
                    DGG.ENTER, self._highlight_traits_but, extraArgs=[traits_but]
                )
                traits_but.bind(
                    DGG.EXIT, self._dehighlight_traits_but, extraArgs=[traits_but]
                )

                self._char_desc_wids.append(traits_but)

            shift = self._fill_traits(shift)

            self._status_lab = DirectLabel(  # Status
                parent=self._fr,
                # Status
                text=base.labels.CHARACTERS[4],  # noqa: F821
                text_font=base.main_font,  # noqa: F821
                frameSize=(0.1, 0.1, 0.1, 0.1),
                text_scale=0.03,
                text_fg=RUST_COL,
                pos=(-0.221, 0, shift),
            )
            self._char_desc_wids.append(self._status_lab)
            self._fill_status(shift)

        self._char_desc_shown = not self._char_desc_shown

    def _dehighlight_traits_but(self, button, _):
        """Dehighlight traits tweaking button.

        Args:
            button (panda3d.gui.DirectGui.DirectButton):
                Button to dehighlight.
        """
        button["frameTexture"] = GUI_PIC + "like.png"

    def _highlight_traits_but(self, button, _):
        """Hightlight traits tweaking button.

        Args:
            button (panda3d.gui.DirectGui.DirectButton):
                Button to highlight.
        """
        button["frameTexture"] = GUI_PIC + "hover_like.png"

    def clear_char_info(self, clear_resting=True):
        """Clear the character GUI.

        Args:
            clear_resting (bool):
                Optional. A flag indicating if the list of the
                resting characters should also be closed.
        """
        for wid in (
            self._char_name,
            self._char_class,
            self._char_health,
            self._char_energy,
            self._traits,
            self._char_desc_but,
            self._disease,
        ):
            wid.hide()

        if self._char_desc_shown:
            self._show_char_desc()

        taskMgr.remove("track_char_info")  # noqa: F821
        self.char = None

        if clear_resting:
            for but in self._rest_buttons.values():
                but.destroy()

        self.rest_list_shown = False

    def destroy_char_button(self, char_id):
        """Hide the given character button from the resting characters list.

        Args:
            char_id (str): Character id.
        """
        if char_id in self._rest_buttons.keys():
            self._rest_buttons[char_id].destroy()
            self._rest_buttons.pop(char_id)

    def hide_tip(self):
        """Hide the tooltip."""
        self._tip.hide()

    def show_char_info(self, char):
        """Show the given character status.

        Args:
            char (units.crew.character.Character):
                The chosen character object.
        """
        self._char_name["text"] = char.name
        self._char_class["text"] = char.class_.capitalize()
        self._traits["text"] = ", ".join(char.traits)

        self._char_health["range"] = char.class_data["health"]
        self._char_health["value"] = char.health
        self._char_energy["value"] = char.energy

        if char.is_diseased:
            self._disease.show()
        else:
            self._disease.hide()

        self.char = char
        self._char_name.show()
        self._char_class.show()
        self._char_health.show()
        self._char_energy.show()
        self._traits.show()
        self._char_desc_but.show()

        if self._char_desc_shown:
            self._show_char_desc()
            self._show_char_desc()

        taskMgr.doMethodLater(  # noqa: F821
            0.5, self._update_char_info, "track_char_info"
        )

    def show_tooltip(self, text):
        """Show tooltip with the given text.

        Args:
            text (str): Text to show in the tooltip.
        """
        if not base.mouseWatcherNode.hasMouse():  # noqa: F821
            return

        if self.rest_list_shown and text == "Rest zone":
            return

        self._tip.setText(text)
        self._tip.setX(base.mouseWatcherNode.getMouseX())  # noqa: F821
        self._tip.setY(base.mouseWatcherNode.getMouseY())  # noqa: F821
        self._tip.show()

    def show_resting_chars(self, part):
        """Show a list of the characters resting in this part.

        Args:
            part (Train.RestPart): Rest part of the Train.
        """
        if self.rest_list_shown:
            return

        self._tip.hide()
        self.rest_list_shown = True

        x = base.mouseWatcherNode.getMouseX()  # noqa: F821
        z = base.mouseWatcherNode.getMouseY()  # noqa: F821

        self._rest_buttons["title"] = DirectButton(
            pos=(x, 0, z),
            text=base.labels.TIPS[0],  # noqa: F821
            text_fg=RUST_COL,
            text_font=base.main_font,  # noqa: F821
            frameColor=(0, 0, 0, 0.6),
            scale=(0.04, 0, 0.03),
        )
        shift = -0.039
        for char in part.chars:
            if char.is_dead:
                continue

            self._rest_buttons[char.id] = DirectButton(
                pos=(x, 0, z + shift),
                text=char.name,
                text_fg=SILVER_COL,
                frameColor=(0, 0, 0, 0.6),
                command=base.common_ctrl.choose_char,  # noqa: F821
                extraArgs=[char.id],
                scale=(0.04, 0, 0.03),
            )
            shift -= 0.033

    def move_status_label(self, place):
        """Move the status label widget.

        Args:
            place (int): Place to shift the widget.
        """
        if self._status_lab is not None:
            self._status_lab.setZ(self._status_lab.getZ() + place / 10)

    def update_resting_chars(self, part):
        """Update the list of the resting characters.

        Args:
            part (train.part.TrainPart): Rest train part.
        """
        for key, but in self._rest_buttons.items():
            if key != "title":
                but.destroy()
                self._rest_buttons[key] = None

        x, _, z = self._rest_buttons["title"].getPos()

        shift = -0.039
        for char in part.chars:
            self._rest_buttons[char.id] = DirectButton(
                pos=(x, 0, z + shift),
                text=char.name,
                text_fg=SILVER_COL,
                frameColor=(0, 0, 0, 0.6),
                command=base.common_ctrl.choose_char,  # noqa: F821
                extraArgs=[char.id],
                scale=(0.04, 0, 0.03),
            )
            shift -= 0.033
Esempio n. 4
0
class DirectTooltip():
    def __init__(self):

        self.tooltipText = DirectLabel(
            text = "Tooltip",
            text_fg = (1,1,1,1),
            text_scale = 0.05,
            text_align = TextNode.ALeft,
            frameColor = (0, 0, 0, 0.75),
            borderWidth = (0.1, 0.1))
        self.tooltipText.setTransparency(True)

        self.textXShift = 0.05
        self.textYShift = -0.08

        self.mousePos = None

        # this will determine when the tooltip should be moved in the
        # respective direction, whereby
        # 1  : display edge
        # <1 : margin inside the window
        # >1 : margin outside the window
        self.xEdgeStartShift = 0.99
        self.yEdgeStartShift = 0.99

        self.tooltipText.hide()

    def show(self, text=None, args=None):
        if text is not None:
            self.tooltipText.setText(text)
            self.tooltipText.resetFrameSize()
        self.tooltipText.show()

        # add the tooltips update task so it will be updated every frame
        base.taskMgr.add(self.updateTooltipPos, "task_updateTooltipPos")

    def delete(self, args=None):
        self.tooltipText.removeNode()

        # remove the tooltips update task
        base.taskMgr.remove("task_updateTooltipPos")

    def updateTooltipPos(self, task):
        # calculate new aspec tratio
        wp = base.win.getProperties()
        aspX = 1.0
        aspY = 1.0
        wpXSize = wp.getXSize()
        wpYSize = wp.getYSize()
        if wpXSize > wpYSize:
            aspX = wpXSize / float(wpYSize)
        else:
            aspY = wpYSize / float(wpXSize)

        # variables to store the mouses current x and y position
        x = 0.0
        y = 0.0
        if base.mouseWatcherNode.hasMouse():
            self.tooltipText.show()
            # get the mouse position
            x = base.mouseWatcherNode.getMouseX()
            y = base.mouseWatcherNode.getMouseY()

            # Move the tooltip to the mouse

            # set the text to the current mouse position
            self.tooltipText.setPos(
                (x*aspX) + self.textXShift,
                0,
                (y*aspY)+self.textYShift)

            bounds = self.tooltipText.getBounds()
            # bounds = left, right, bottom, top

            # calculate the texts bounds respecting its current position
            xLeft = self.tooltipText.getX() + bounds[0]*self.tooltipText.getScale()[0]
            xRight = self.tooltipText.getX() + bounds[1]*self.tooltipText.getScale()[0]
            yUp = self.tooltipText.getZ() + bounds[3]*self.tooltipText.getScale()[1]
            yDown = self.tooltipText.getZ() + bounds[2]*self.tooltipText.getScale()[1]

            # these will be used to shift the text in the desired direction
            xShift = 0.0
            yShift = 0.0
            if xRight/aspX > self.xEdgeStartShift:
                # shift to the left
                xShift = self.xEdgeStartShift - xRight/aspX
            elif xLeft/aspX < -self.xEdgeStartShift:
                # shift to the right
                xShift = -(self.xEdgeStartShift + xLeft/aspX)
            if yUp/aspY > self.yEdgeStartShift:
                # shift down
                yShift = self.yEdgeStartShift - yUp/aspY
            elif yDown/aspY < -self.yEdgeStartShift:
                # shift up
                yShift = -(self.yEdgeStartShift + yDown/aspY)

            # some aspect ratio calculation
            xShift *= aspX
            yShift *= aspY

            # move the tooltip to the new position
            self.tooltipText.setX(self.tooltipText.getX() + xShift)
            self.tooltipText.setZ(self.tooltipText.getZ() + yShift)
        else:
            self.tooltipText.delete()


        # continue the task until it got manually stopped
        return task.cont