def __init__(self, app, parent, universe, target=None, replay=False):
        '''
        Called upon creation of a ViewManager object.  screen is a pygame
        screen object.  universe is the Universe object to draw.  target is
        either a point, a PlayerSprite object, or None.  If target is None, the
        view manager will follow the action, otherwise it will follow the
        specified point or player.
        '''
        super(ViewManager, self).__init__(app)
        self.universe = universe
        self.parent = parent
        self.replay = replay

        # self._focus represents the point where the viewManager is currently
        # looking.
        if self.universe.map:
            self._focus = (universe.map.layout.centreX,
                           universe.map.layout.centreY)
        else:
            self._focus = (0, 0)
        self._oldTargetPt = self._focus
        self.lastUpdateTime = timeNow()
        self.autoFocusInfo = (0, set(), set())
        self.speed = 0  # Speed that the focus is moving.

        self.loadingScreen = None
        self.loadingPlayer = None
        self.pauseMessage = None
        self.backgroundDrawer = BackgroundDrawer(app, universe)
        self.sRect = None

        # Now fill the backdrop with what we're looking at now.
        self.appResized()
        self.setTarget(target)
Exemple #2
0
    def respawned(self):
        time = timeNow()

        if self.lastTimeDied is not None:
            self.timeDead += (time - self.lastTimeDied)

        self.lastTimeRespawned = time
Exemple #3
0
    def run_twisted(self, reactor=None):
        '''Runs the application using Twisted's reactor.'''

        if reactor is None:
            from twisted.internet import reactor

        def _stop():
            if not self._running:
                if reactor.running:
                    log.warning(
                        'stop() called twice. Terminating immediately.')
                    reactor.stop()
                return

            self._running = False

            # Give time for shutdown sequence.
            reactor.callLater(0.3, reactor.stop)

        self._stop = _stop
        self.lastTime = self.lastFPSLog = timeNow()

        self.jitterLogger.noteGap()
        self.targetFrameInterval = 1. / TARGET_FRAME_RATE
        reactor.callLater(self.targetFrameInterval, self.twisted_tick, reactor)
        self._running = True
        reactor.run()
        pygame.display.quit()
        pygame.quit()
Exemple #4
0
 def applyOrderToLocalState(self, localState, world):
     now = timeNow()
     try:
         sendTime = localState.pings.pop(self.data)
     except KeyError:
         return
     localState.gotPingTime(now - sendTime)
Exemple #5
0
    def run_twisted(self, reactor=None):
        '''Runs the application using Twisted's reactor.'''

        if reactor is None:
            from twisted.internet import reactor

        def _stop():
            if not self._running:
                if reactor.running:
                    log.warning(
                        'stop() called twice. Terminating immediately.')
                    reactor.stop()
                return

            self._running = False

            # Give time for shutdown sequence.
            reactor.callLater(0.3, reactor.stop)

        self._stop = _stop
        self.lastTime = self.lastFPSLog = timeNow()

        # panda stuff
        self.displayLoop = task.LoopingCall(self.displayStep, reactor)
        self.displayLoop.clock = reactor
        self.displayLoop.start(0)  # self-limiting

        self._running = True
        reactor.run()
Exemple #6
0
    def _tick(self):
        '''Processes the events in the pygame event queue, and causes the
        application to be updated, then refreshes the screen. This routine is
        called as often as possible - it is not limited to a specific frame
        rate.'''
        if not self._running:
            return

        now = timeNow()

        self.ticksSinceFPSLog += 1
        if LOG_FPS and now - self.lastFPSLog > 1:
            log.warning('%.2f FPS',
                        self.ticksSinceFPSLog / (now - self.lastFPSLog))
            self.lastFPSLog = now
            self.ticksSinceFPSLog = 0

        # Process the events in the event queue.
        for event in pygame.event.get():
            try:
                event = self.musicManager.processEvent(event)
                if not self._running:
                    return
                if event is not None:
                    event = self.screenManager.processEvent(event)
                    if not self._running:
                        return
                    if event is not None:
                        # Special events.
                        if event.type == pygame.QUIT:
                            self.stop()
                            return
            except ApplicationExit:
                raise
            except Exception:
                log.exception('Error during Pygame event processing')
            if not self._running:
                return

        # Give things an opportunity to update their state.
        deltaT = now - self.lastTime
        self.lastTime = now
        try:
            self.screenManager.tick(deltaT)
        except ApplicationExit:
            raise
        except Exception:
            log.exception('Error drawing screen')

        if not self._running:
            return

        if pygame.display.get_active():
            # Update the screen.
            try:
                self.screenManager.draw(self.screenManager.screen)
            except pygame.error:
                # Surface may have been lost (DirectDraw error)
                log.exception('Error in screenManager.draw()')
    def updateFocus(self):
        '''Updates the location that the ViewManager is focused on.  First
        calculates where it would ideally be focused, then moves the focus
        towards that point. The focus cannot move faster than self.maxSpeed
        pix/s, and will only accelerate or decelerate at self.acceleration
        pix/s/s. This method returns the negative of the amount scrolled by.
        This is useful for moving the backdrop by the right amount.
        '''

        # Calculate where we should be looking at.
        if isinstance(self.target, PlayerSprite):
            # Take into account where the player's looking.
            targetPt = self.target.pos

            # If the player no longer exists, look wherever we want.
            if not self.universe.hasPlayer(self.target.player):
                self.setTarget(None)
        elif isinstance(self.target, (tuple, list)):
            targetPt = self.target
        else:
            targetPt = self.followAction()

        # Calculate time that's passed.
        now = timeNow()
        deltaT = now - self.lastUpdateTime
        self.lastUpdateTime = now

        # Calculate distance to target.
        self._oldTargetPt = targetPt
        sTarget = sum((targetPt[i] - self._focus[i])**2 for i in (0, 1))**0.5

        if sTarget == 0:
            return (0, 0)

        if self.target is not None:
            s = sTarget
        else:
            # Calculate the maximum velocity that will result in deceleration
            # to reach target. This is based on v**2 = u**2 + 2as
            vDecel = (2. * self.acceleration * sTarget)**0.5

            # Actual velocity is limited by this and maximum velocity.
            self.speed = min(self.maxSpeed, vDecel,
                             self.speed + self.acceleration * deltaT)

            # Distance travelled should never overshoot the target.
            s = min(sTarget, self.speed * deltaT)

        # How far does the backdrop need to move by?
        #  (This will be negative what the focus moves by.)
        deltaBackdrop = tuple(-s * (targetPt[i] - self._focus[i]) / sTarget
                              for i in (0, 1))

        # Calculate the new focus.
        self._focus = tuple(
            round(self._focus[i] - deltaBackdrop[i], 0) for i in (0, 1))
Exemple #8
0
    def toggleTerminal(self):
        if self.terminal is None:
            locs = {'app': self.app}
            if hasattr(self.app, 'getConsoleLocals'):
                locs.update(self.app.getConsoleLocals())
            self.terminal = console.TrosnothInteractiveConsole(
                self.app,
                self.app.screenManager.fonts.consoleFont,
                Region(size=Screen(1, 0.4), bottomright=Screen(1, 1)),
                locals=locs)
            self.terminal.interact().addCallback(self._terminalQuit)

        from trosnoth.utils.utils import timeNow
        if self.terminal in self.elements:
            if timeNow() > self._termWaitTime:
                self.elements.remove(self.terminal)
        else:
            self._termWaitTime = timeNow() + 0.1
            self.elements.append(self.terminal)
            self.setFocus(self.terminal)
Exemple #9
0
    def gotTick(self):
        now = timeNow()

        if self.ignoreUntil is not None:
            if now > self.ignoreUntil:
                self.reset()
            else:
                return

        self.ticks.append(now)
        limit = now - self.TIME_SPAN
        while self.ticks[0] < limit:
            self.ticks.pop(0)
Exemple #10
0
    def notePeriod(self):
        '''
        Called periodically to allow the analyser to notice if the reactor is
        not running smoothly.
        '''
        now = timeNow()
        if self.lastNote is None:
            self.lastNote = now
            return
        period = now - self.lastNote
        self.lastNote = now

        if period - self.NOTE_TIME >= self.NOTE_TIME:
            # Reactor congestion: reset tally
            self.ignoreUntil = now + self.NOTE_TIME
Exemple #11
0
    def died(self, killer, deathType):
        self.deaths += 1
        self.playerDeaths[killer] += 1

        time = timeNow()

        self._updateStreaks(True)

        self.lastTimeDied = time

        if self.timeAlive >= 1000:
            self.sendAchievementProgress('totalAliveTime')

        if self.timeAlive >= 300 and self.timeAlive >= (self.timeAlive +
                self.timeDead) * 0.75:
            self.sendAchievementProgress('stayingAlive')
Exemple #12
0
    def observation(self, expectedTime, resume=False):
        if resume:
            self.noteGap()

        now = timeNow()
        if self.lastTime:
            value = now - self.lastTime - expectedTime
            self.thisMax = max(self.thisMax, value)
            self.thisCount += 1

            if self.thisCount >= self.cycle:
                self.jitter = self.thisMax
                self.thisCount = 0
                self.thisMax = 0

        self.lastTime = now
Exemple #13
0
    def run(self):
        '''Runs the application.'''
        def _stop():
            self._running = False
            raise ApplicationExit

        self._stop = _stop

        self._running = True
        self.lastTime = self.lastFPSLog = timeNow()
        while self._running:
            try:
                self.tick()
                self.doFlip()
            except ApplicationExit:
                break
        pygame.quit()
    def __init__(self, game):
        self.game = game
        self.world = world = game.world
        self.lastSave = timeNow()

        # All players recorded this game, indexed by user id.
        self.allPlayers = {}

        defs = self.achievementDefs
        self.oncePerGameAchievements = [c(world) for c in defs.oncePerGame]
        self.oncePerTeamPerGameAchievements = [
            c(world, team) for c in defs.oncePerTeamPerGame
            for team in world.teams
        ]

        self.loop = WeakLoopingCall(self, 'save')
        self.started = False
        self.stopped = False
Exemple #15
0
    def verify(self):
        '''
        If more than GAME_VERIFY_TIME has passed since the last verification,
        connects to the game to check whether it is still running. Returns a
        deferred whose callback will be executed with True or False depending
        on whether the game is still running.
        '''
        t = timeNow()
        if t - self.lastVerified < GAME_VERIFY_TIME:
            defer.returnValue(self.running)
            return
        self.lastVerified = t

        try:
            yield ClientCreator(reactor, Protocol).connectTCP(self.host,
                                                              self.port,
                                                              timeout=5)
        except ConnectError:
            self.running = False
            defer.returnValue(False)
            return

        self.running = True
        defer.returnValue(True)
Exemple #16
0
    def _updateStreaks(self, updateAlive):
        '''
        updateAlive will be set to True in three situations:
          1. if the player has just died
          2. if the player was alive when the game ended
          3. if the player was alive when they disconnected
        '''
        self.killStreak = max(self.killStreak, self.currentKillStreak)
        self.tagStreak = max(self.tagStreak, self.currentTagStreak)

        time = timeNow()

        if updateAlive and self.lastTimeRespawned:
            lastLife = time - self.lastTimeRespawned
            self.aliveStreak = max(self.aliveStreak, lastLife)
            self.timeAlive += lastLife
            if lastLife >= 180:
                self.sendAchievementProgress('aliveStreak')

        elif self.lastTimeDied is not None:
            self.timeDead += time - self.lastTimeDied

        self.currentKillStreak = 0
        self.currentTagStreak = 0
Exemple #17
0
 def reset(self):
     self.startTime = timeNow()
     self.ticks = [self.startTime]
Exemple #18
0
 def applyRequestToLocalState(self, localState):
     localState.pings[self.data] = timeNow()