Esempio n. 1
0
 def kill_escaped(self):
     '''
     Kill all sprites related to a plane that left the aerospace.
     '''
     for plane in self.__planes.values():
         s = self.surface.get_rect()
         x, y = plane['sprites'][0].position
         if x < 0 or x > s.width or y < 0 or y > s.height:
             # This is the worst scenario
             msg = 'Tower? ... Tower? ... Aaaaahhhh!'
             event = S.PLANE_LEAVES_RANDOM
             colour = S.KO_COLOUR
             crossed = self.__get_crossed_gates(plane['plane'])
             # This might be better
             for gate in crossed:
                 msg = 'Tower? It doesn\'t seem we are where we should...'
                 event = S.PLANE_LEAVES_WRONG_GATE  #little better!
                 if gate.name == plane['plane'].destination and \
                    plane['plane'].altitude % 1000 == 0:
                     msg = 'Thank you tower, and good bye!'
                     colour = S.OK_COLOUR
                     event = S.PLANE_LEAVES_CORRECT_GATE  #yay! :)
             plane['plane'].pilot.say(msg, colour)
             self.gamelogic.remove_plane(plane['plane'], event)
             log.info('%s left aerospace under event %s' %
                      (plane['plane'].icao, event))
             log.debug('Data at exit was: %s' %
                       plane['plane'].get_current_configuration())
Esempio n. 2
0
 def msg_append(self, colour, text):
     '''
     Append a message to the console.
     '''
     log.debug(text)
     wrapped = textwrap.wrap(text,
                             width=self.max_small_line_length,
                             subsequent_indent=' ' * S.CONSOLE_INDENTATION)
     for line in wrapped:
         self.console_lines.append((colour, line))
Esempio n. 3
0
    def process_commands(self, commands):
        '''
        Process commands.

        This is a "subroutine" of ``execute`` which is also called by some of
        the procedures. This is such that is possible to process commands
        without triggering score events and setting flags (as it happens with
        ``execute()``).

        This method will silently pass if the command name has not been
        recognised. This is to allow the method to process set of commands that
        also contains *procedures* (such LAND, TAKEOFF, etc...).
        '''
        pi = self.pilot
        pl = self.plane
        tc = self.pilot.target_conf
        for cname, (args, flags) in commands.items():
            log.info('%s executes: %s' %
                     (pl.icao, ' '.join((cname, repr(args), repr(flags)))))
            # PROCESS COMMANDS
            # Since flags are "universal" across commands (they all do the same
            # thing if they are called the same), it is possible to process
            # them separately.
            if cname == 'HEADING':
                assert len(args) == 1
                tc.heading = args[0]
                pi.status['veer_dir'] = \
                                pi.navigator.get_shortest_veering_direction()
            elif cname == 'ALTITUDE':
                tc.altitude = args[0]
            elif cname == 'SPEED':
                tc.speed = args[0]
            elif cname == 'ABORT':
                self.abort()
            elif cname == 'SQUAWK':
                if pl.flags.on_ground:
                    pi.say('Currently at airport %s, our destination is %s' %
                              (pl.origin, pl.destination), S.OK_COLOUR)
                else:
                    pi.say('Currently heading %s, our destination is %s' %
                          (U.rint(pl.heading), pl.destination), S.OK_COLOUR)
            else:
                log.debug('process_commands() ignored: %s' % cname)
            # PROCESS FLAGS
            # Flags with the same name have the same meaning and therefore
            # can be processed independently from the command they are
            # associated with. Since they can modify the value set by their
            # command, they must follow the command processing
            if 'EXPEDITE' in flags:
                pi.status['haste'] = 'expedite'
            if 'LONG' in flags:
                pi.status['veer_dir'] *= -1  #invert direction
Esempio n. 4
0
 def _toggle_paused(self):
     '''
     Toggle the paused machine state.
     '''
     gl = self.gamelogic
     gl.machine_state = \
         [S.MS_RUN, S.MS_PAUSED][gl.machine_state == S.MS_RUN]
     if gl.machine_state == S.MS_PAUSED:
         self.__blur_radar()
         log.debug('### GAME PAUSED ###')
     else:
         self.__restore_radar()
         log.debug('### GAME RESUMED ###')
Esempio n. 5
0
 def __add_plane(self):
     '''
     Add an aeroplane to the game.
     '''
     kwargs = {}
     # Aeroplane model and specifications
     kwargs.update(self.model_generator())
     # Flight number and callsign
     kwargs.update(self.flightnum_generator())
     # Origin and destionation. If for some reason the challenge engine
     # hasn't find a viable entry point for the challenge logic, it will
     # return False, and no aeroplane will be added to the game
     result = self.__generate_flight_plan()
     if not result:
         return
     kwargs.update(result)
     # Set the module of the velocity (until here a normalized vector)
     kwargs['velocity'] *= kwargs['max_speed']
     log.debug('About to add plane: %s' % kwargs)
     self.gamelogic.add_plane(Aeroplane(self.gamelogic.aerospace, **kwargs))
     self.plane_counter += 1
Esempio n. 6
0
 def make_decision(self):
     '''
     Make a decision if trying to land or not depending on whether the
     target runway is free or not. If free, return True and mark runway
     busy, otherwise return False.
     '''
     rman = self.plane.aerospace.runways_manager
     if rman.check_runway_free(self.port, self.rnwy):
         rman.use_runway(self.port, self.rnwy, self.plane)
         full_length_speed = float(self.rnwy['length'])/S.RUNWAY_BUSY_TIME
         self.taxiing_data = dict(
              speed = min(self.plane.landing_speed, full_length_speed),
              timer = S.RUNWAY_BUSY_TIME)
         log.debug('%s *positive* landing decision on %s %s' %
                   (self.plane.icao, self.port.iata, self.rnwy['name']))
         self.plane.flags.locked = True
         return True
     log.debug('%s *negative* landing decision on %s %s' %
               (self.plane.icao, self.port.iata, self.rnwy['name']))
     msg = 'Somebody is using our landing runway!!!'
     self.plane.pilot._abort_landing(msg)
     return False
Esempio n. 7
0
 def do(self, commands):
     '''
     Perform an order issued by the player.
     Input is a list of triplets each of them in the format:
     [command, [arg1, arg2, ...], [flag1, flag2, ...]].
     Return boolean.
     '''
     radio_last = self.last_radio_hash
     # Transform the commands in a more suitable dictionary form..
     commands = dict([(a, (b, c)) for a, b, c in commands])
     # ...perform validity checks...
     check = self.checker.check(commands)
     if check != True:
         log.debug('%s failed to execute %s. Message: %s'
                   % (self.plane.icao, commands, check))
         self.say(check, S.KO_COLOUR)
         return False
     # ..and eventually execute the commands!
     self.executer.execute(commands)
     # If no radio feedback has been provided yet by any of the commands,
     # provide a generic affirmative answer.
     if radio_last == self.last_radio_hash:
         self.say(choice(self.AFFIRMATIVE_ANSWERS), S.OK_COLOUR)
     return True
Esempio n. 8
0
 def update(self):
     '''
     Guide a plane towards the ILS descent path and then makes it land.
     Return the phase of the landing sequence.
     '''
     pl = self.plane
     pi = self.pilot
     l = self.lander
     assert self.phase in (self.ABORTED, self.INTERCEPTING, self.MERGING,
                           self.MATCHING, self.GLIDING, self.TAXIING)
     if self.phase == self.INTERCEPTING:
         #BUG: if command is given too late the plane won't manage to
         #     turn into the vector
         log.debug('%s INTERCEPTING: md=%s fd=%s' % (pl.icao, l.md, l.fd))
         if pi.navigator.check_overshot(l.mp) == True:
             pi.target_conf.heading = l.foot
             self.phase = self.MERGING
     if self.phase == self.MERGING:
         log.debug('%s MERGING: head=%s t_head= %s fd=%s' % (pl.icao,
                   pl.heading, pi.target_conf.heading, l.fd))
         if pl.heading == pi.target_conf.heading:
             self.phase = self.MATCHING
     if self.phase == self.MATCHING:
         path_alt = l.path_alt
         alt_diff = path_alt - pl.altitude  #negative -> descend!
         log.debug('%s MATCHING: alt=%s path_alt=%s delta=%s fd=%s' %
                   (pl.icao, pl.altitude, path_alt, alt_diff, l.fd))
         secs_to_foot = l.fd / pl.speed
         # Abort if the plane is too fast to descend
         if abs(secs_to_foot * pl.climb_rate_limits[0]) < l.above_foot:
             msg = 'Plane is flying too fast to lose enough altitude'
             return self._abort_landing(msg)
         # If the delta to the path is less than the climbing/descending
         # capabilities of the aeroplane, consider it on slope...
         if alt_diff < 0 and alt_diff > pl.climb_rate_limits[0] or \
            alt_diff > 0 and alt_diff < pl.climb_rate_limits[1]:
             pl.position.z = path_alt
             self.phase = self.GLIDING
             l.set_breaking_point()
             if pi.navigator.check_overshot(l.bp):
                 msg = 'Plane too fast to slow down to landing speed'
                 self._abort_landing(msg)
         # ...otherwise tell it to climb/descend!!
         else:
             pi.target_conf.altitude = path_alt
     elif self.phase == self.GLIDING:
         log.debug('%s GLIDING: footalt=%s speed=%s t_speed=%s bd=%s fd=%s'
                   % (pl.icao, l.above_foot, pl.speed,
                      pi.target_conf.speed, l.bd, l.fd))
         # Abort if the plane is too fast to slow to landing speed
         if pi.navigator.check_overshot(l.bp):
             pi.target_conf.speed = pl.landing_speed
         # Make decision if below minimum altitude
         if not l.taxiing_data and l.above_foot <= S.DECISION_ALTITUDE:
             l.make_decision()
         ticks = 1.0 * l.fd / pi.target_conf.speed / S.PING_IN_SECONDS
         z_step = 1.0 * l.above_foot / ticks
         pi.target_conf.altitude -= z_step
         if pl.position.z <= l.foot.z \
            or pi.navigator.check_overshot(l.foot):
             pl.flags.on_ground = True
             self.phase = self.TAXIING
             pi.target_conf.speed = l.taxiing_data['speed']
             if pl.destination == l.port.iata:
                 msg = 'Thank you tower, we\'ve hit home. Over and out!'
                 pi.say(msg, S.OK_COLOUR)
             else:
                 msg = 'Well, well... we just landed at the WRONG airport!'
                 pi.say(msg, S.KO_COLOUR)
     elif self.phase == self.TAXIING:
         log.debug('%s TAXIING: speed=%s fd=%s' % (pl.icao, pl.speed, l.fd))
         l.taxiing_data['timer'] -= S.PING_IN_SECONDS
         if l.taxiing_data['timer'] <= 0:
             if pl.destination == l.port.iata:
                 pl.terminate(S.PLANE_LANDS_CORRECT_PORT)
             else:
                 pl.terminate(S.PLANE_LANDS_WRONG_PORT)
     return self.phase