コード例 #1
0
def Init_Storms():
    # This is rather slow.
    global storm_graphics
    storm_graphics = particle.Make_Particle_Effect(particle.Storm_Particle)

    global storm_sound
    storm_sound = sound.Persisting_Sound("stormdmg", "stormbeeps")
コード例 #2
0
def Init_Aliens():
    global alien_firing_sound
    alien_firing_sound = sound.Persisting_Sound("clicker")
コード例 #3
0
def Main_Loop(screen, clock, xxx_todo_changeme, restore_pos, challenge):
    # Initialisation of screen things.

    (width, height) = xxx_todo_changeme
    menu_margin = height
    screen.fill((0, 0, 0))  # screen is black during init
    pygame.display.flip()
    tutor.Off()

    draw_obj.Flush_Draw_Obj_Cache()  # in case of resize

    # Grid setup
    (w, h) = GRID_SIZE
    assert w == h
    Set_Grid_Size(height / h)

    # Windows..
    game_screen_rect = Rect(0, 0, menu_margin, height)
    game_screen_surf = screen.subsurface(game_screen_rect)
    menu_area = screen.subsurface(
        Rect(menu_margin, 0, width - menu_margin, height))
    menu_width = width - menu_margin

    # Constraint on resolution applied here:
    assert menu_width >= 100

    def Sc(v):
        # Original values were for 800x600 - scale that
        # for whatever the user's screen res happens to be.
        return (v * height) / 600

    margin = Sc(10)
    x1 = menu_margin + margin
    menu_width1 = menu_width - (margin * 2)

    picture = resource.Load_Image("headersm.jpg")
    picture_rect = picture.get_rect().inflate(10, 10)
    picture_rect.center = (x1 + (menu_width1 / 2), 0)
    picture_rect.top = margin
    picture_surf = screen.subsurface(picture_rect)

    stats_rect = Rect(x1, picture_rect.bottom + margin, menu_width1, Sc(120))
    stats_surf = screen.subsurface(stats_rect)
    global_stats_rect = Rect(x1, stats_rect.bottom + margin, menu_width1,
                             Sc(110))
    global_stats_surf = screen.subsurface(global_stats_rect)
    controls_rect = Rect(x1, global_stats_rect.bottom + margin, menu_width1,
                         height - (margin + global_stats_rect.bottom + margin))
    controls_surf = screen.subsurface(controls_rect)

    def Special_Refresh():
        extra.Tile_Texture(
            screen, "rivets.jpg",
            Rect(menu_margin, 0, menu_width,
                 screen.get_rect().height))

        edge = Rect(menu_margin, -10, menu_width + 10,
                    screen.get_rect().height + 10)

        for r in [stats_rect, global_stats_rect, edge]:
            extra.Line_Edging(screen, r, False)

        r = picture.get_rect()
        r.center = picture_surf.get_rect().center
        extra.Line_Edging(picture_surf, r, False)
        picture_surf.blit(picture, r.topleft)

    Special_Refresh()

    stats_surf.fill((0, 0, 0))

    FRAME_RATE = 35

    alarm_sound = sound.Persisting_Sound("emergency")

    teaching = (challenge == MENU_TUTORIAL)

    # Game data holder
    g = Game_Data()
    g.version = startup.Get_Game_Version()
    g.sysinfo = extra.Get_System_Info()

    # Steam network initialisation
    g.net = Network(teaching)

    DIFFICULTY.Set(MENU_INTERMEDIATE)

    # Establish equilibrium with initial network.
    for i in range(300):
        g.net.Steam_Think()
        if (g.net.hub.Get_Pressure() >= PRESSURE_GOOD):
            if (DEBUG):
                print(i, 'steps required for equilibrium')
            break

    assert g.net.hub.Get_Pressure() >= PRESSURE_GOOD

    # UI setup
    ui = User_Interface(g.net, (width, height))
    inputs = [(controls_rect, ui.Control_Mouse_Down, ui.Control_Mouse_Move),
              (game_screen_rect, ui.Game_Mouse_Down, ui.Game_Mouse_Move)]
    exit_options = [(MENU_MENU, "Exit to Main Menu", []),
                    (MENU_QUIT, "Exit to " + extra.Get_OS(), [K_F10])]

    save_available = [(MENU_SAVE, "Save Game", []),
                      (MENU_LOAD, "Restore Game", []), (None, None, [])]

    if (challenge == MENU_TUTORIAL):
        save_available = []

    in_game_menu = menu.Menu([(None, None, []), (MENU_MUTE, "Toggle Sound",
                                                 []), (None, None, [])] +
                             save_available +
                             [(MENU_HIDE, "Return to Game", [K_ESCAPE])] +
                             exit_options)

    current_menu = in_game_menu

    flash = True
    loop_running = True
    quit = False
    stats_review = False
    in_game_menu.Select(None)
    mail.Initialise()
    rt_then = time.time()
    fps_count = 0
    fps_time = rt_then
    autosave_timer = 0

    if (restore_pos == None):
        DIFFICULTY.Set(challenge)

    # Game variables
    g.season = SEASON_START
    g.season_ends = 0
    g.season_effect = 0
    g.season_fx = Quiet_Season(g.net)
    g.work_units_used = 0
    g.challenge = challenge
    g.difficulty_level = 1.0
    g.work_timer = 0.1
    g.game_ends_at = None
    g.game_running = True
    g.game_time = gametime.Game_Time()
    g.historian = []
    g.historian_time = 0
    g.win = False
    g.warning_given = False
    g.wu_integral = 0
    mail.Set_Day(g.game_time.Get_Day())

    def Summary(g):
        lev = dict()
        lev[MENU_TUTORIAL] = "a Tutorial"
        lev[MENU_BEGINNER] = "a Beginner"
        lev[MENU_INTERMEDIATE] = "an Intermediate"
        lev[MENU_EXPERT] = "an Expert"
        lev[MENU_PEACEFUL] = "a Peaceful"

        assert g.challenge != None
        assert g.challenge in lev
        New_Mail("You are playing " + lev[g.challenge] + " game.")
        New_Mail("Win the game by upgrading your city to tech level %u." %
                 DIFFICULTY.CITY_MAX_TECH_LEVEL)

    # Almost ready to start... but are we starting
    # from a savegame?
    def Restore(g, cmd):
        (g2, result) = save_game.Load(g, cmd)
        if (result == None):
            g = g2
            ui.net = g.net
            mail.Initialise()
            mail.Set_Day(g.game_time.Get_Day())
            assert g.challenge != None
            DIFFICULTY.Set(g.challenge)
            New_Mail(
                f"Game restored. It is currently {g.season_fx.name} season.")
        else:
            New_Mail(result)
        return g

    if (restore_pos != None):
        g.challenge = MENU_INTERMEDIATE
        g = Restore(g, restore_pos)

    assert g.challenge != None
    Summary(g)

    if (g.challenge == MENU_TUTORIAL):
        tutor.On((menu_margin * 40) / 100)

    cur_time = g.game_time.time()

    # Main loop
    while (loop_running):

        if (g.game_running):
            flash = not flash
        menu_inhibit = ui.Is_Menu_Open() or not g.game_running

        # Insert delay...
        # Hmm, I'm not sure if I know what this does.
        clock.tick(FRAME_RATE)

        rt_now = time.time()
        rt_frame_length = rt_now - rt_then
        rt_then = rt_now
        fps_count += 1
        if (fps_count > 100):
            if (DEBUG):
                print(
                    f"{math.floor(float(fps_count) / (rt_now - fps_time))} fps"
                )
            fps_time = rt_now
            fps_count = 0

        if (not menu_inhibit):
            if (not tutor.Frozen()):
                g.game_time.Advance(rt_frame_length)
            draw_obj.Next_Frame()  # Flashing lights on the various items

        cur_time = g.game_time.time()
        mail.Set_Day(g.game_time.Get_Day())

        ui.Draw_Game(game_screen_surf, g.season_fx)

        # if ( flash ):
        # ui.Draw_Selection(picture_surf)

        if (g.challenge == MENU_TUTORIAL):
            until_next = []
        elif (g.challenge == MENU_PEACEFUL):
            until_next = [((128, 128, 128), 12, "Peaceful mode")]
        else:
            until_next = [(
                (128, 128, 128), 12,
                f"{math.floor((g.season_ends - cur_time) + 1)} days until next season)"
            )]

        ui.Draw_Stats(stats_surf,
                      [((128, 0, 128), 18, f"Day {g.game_time.Get_Day()}"),
                       ((128, 128, 0), 18, g.season_fx.name + " season")] +
                      until_next + g.season_fx.Get_Extra_Info())
        ui.Draw_Controls(controls_surf)

        if (menu_inhibit):
            current_menu.Draw(screen)
            alarm_sound.Set(0.0)

        stats_back = (0, 0, 0)
        supply = g.net.hub.Get_Steam_Supply()
        demand = g.net.hub.Get_Steam_Demand()
        if (g.net.hub.Get_Pressure() < PRESSURE_DANGER):
            # You'll lose the game if you stay in this zone
            # for longer than a timeout. Also, an
            # alarm will sound.

            if (g.game_ends_at == None):
                sound.FX("steamcrit")
                g.warning_given = True

                New_Mail("Danger! The City needs more steam!", (255, 0, 0))
                g.game_ends_at = cur_time + DIFFICULTY.GRACE_TIME
                New_Mail(
                    f"Game will end on Day {g.game_ends_at} unless supplies are increased.",
                    (255, 0, 0))

            if (flash):
                demand_colour = (255, 0, 0)
                if (not menu_inhibit):
                    alarm_sound.Set(0.6)
            else:
                demand_colour = (128, 0, 0)
                stats_back = (100, 0, 0)

        elif (g.net.hub.Get_Pressure() < PRESSURE_WARNING):

            g.game_ends_at = None
            if (flash):
                demand_colour = (255, 100, 0)
                if (not menu_inhibit):
                    alarm_sound.Set(0.3)
            else:
                demand_colour = (128, 50, 0)
                stats_back = (50, 25, 0)
        else:

            if (g.warning_given):
                sound.FX("steamres")
                g.warning_given = False

            if (g.net.hub.Get_Pressure() < PRESSURE_OK):
                demand_colour = (128, 128, 0)
            else:
                demand_colour = (0, 128, 0)

            g.game_ends_at = None
            alarm_sound.Set(0.0)

        avw = g.net.hub.Get_Avail_Work_Units()
        wu_unused = avw - g.work_units_used
        if (not menu_inhibit):
            global_stats_surf.fill(stats_back)
            stats.Draw_Stats_Window(
                global_stats_surf,
                [(CITY_COLOUR, 18, "Steam Pressure"),
                 (CITY_COLOUR, 18, "Supply : Demand"),
                 (demand_colour, 24,
                  f"{round(supply, 1)} : {round(demand, 1)}"),
                 (None, None, g.net.hub.Get_Pressure_Meter()),
                 (CITY_COLOUR, 0, ""),
                 (CITY_COLOUR, 12,
                  f"{wu_unused} of {avw} work units available"),
                 (None, None, (wu_unused, (255, 0, 255), avw, (0, 0, 0)))])

        if (g.challenge == MENU_TUTORIAL):
            tutor.Draw(screen, g)

        pygame.display.flip()

        if (not menu_inhibit):
            g.season_fx.Per_Frame(rt_frame_length)
            ui.Frame_Advance(rt_frame_length)

        # Timing effects
        if (g.work_timer <= cur_time):
            # Fixed periodic effects
            g.work_timer = cur_time + 0.1
            g.wu_integral += wu_unused
            g.work_units_used = g.net.Work_Pulse(
                g.net.hub.Get_Avail_Work_Units())

            g.net.Steam_Think()
            g.net.Expire_Popups()
            tutor.Examine_Game(g)

        if (g.season_effect <= cur_time):
            # Seasonal periodic effects
            g.season_effect = cur_time + g.season_fx.Get_Period()
            g.season_fx.Per_Period()

        if (((not tutor.Permit_Season_Change()) and (g.season == SEASON_QUIET))
                or (g.challenge == MENU_PEACEFUL)):
            g.season_ends = cur_time + 2

        if (g.season_ends <= cur_time):
            # Season change
            if (g.season == SEASON_START):
                g.season = SEASON_QUIET
                g.season_fx = Quiet_Season(g.net)
            elif ((g.season == SEASON_QUIET) or (g.season == SEASON_STORM)):
                g.season = SEASON_ALIEN
                g.season_fx = Alien_Season(g.net, g.difficulty_level)
                sound.FX("aliensappr")
            elif (g.season == SEASON_ALIEN):
                g.season = SEASON_QUAKE
                g.season_fx = Quake_Season(g.net, g.difficulty_level)
                if (not tutor.Active()):  # hack...
                    sound.FX("quakewarn")
            elif (g.season == SEASON_QUAKE):
                g.season = SEASON_STORM
                g.season_fx = Storm_Season(g.net, g.difficulty_level)
                g.difficulty_level *= 1.2  # 20% harder..
                sound.FX("stormwarn")
            else:
                assert False
            g.season_ends = cur_time + LENGTH_OF_SEASON
            g.season_effect = cur_time + (g.season_fx.Get_Period() / 2)

            if (g.challenge != MENU_PEACEFUL):
                New_Mail(f"The {g.season_fx.name} season has started.",
                         (200, 200, 200))

        just_ended = False
        if ((g.game_ends_at != None) and (g.game_ends_at <= cur_time)
                and (g.game_running)):
            # Game over - you lose
            g.game_running = False
            New_Mail("The City ran out of steam.", (255, 0, 0))
            New_Mail("Game Over!", (255, 255, 0))
            sound.FX("krankor")
            just_ended = True

        elif ((g.net.hub.tech_level >= DIFFICULTY.CITY_MAX_TECH_LEVEL)
              and (g.game_running)):
            # Game over - you win!
            g.game_running = False
            g.win = True
            New_Mail("The City is now fully upgraded!", (255, 255, 255))
            New_Mail("You have won the game!", (255, 255, 255))
            sound.FX("applause")
            just_ended = True

        if (just_ended):
            current_menu = in_game_menu = menu.Menu(
                [(None, None, []), (MENU_REVIEW, "Review Statistics", [])] +
                exit_options)
            in_game_menu.Select(None)

        # Events
        e = pygame.event.poll()
        while (e.type != NOEVENT):
            if e.type == QUIT:
                loop_running = False
                quit = True

            elif e.type == MOUSEBUTTONDOWN or e.type == MOUSEMOTION:
                if e.type == MOUSEBUTTONDOWN and e.button != 1:
                    if not menu_inhibit:
                        ui.Right_Mouse_Down()

                elif not menu_inhibit:
                    for rect, click, move in inputs:
                        if rect.collidepoint(e.pos):
                            (x, y) = e.pos
                            x -= rect.left
                            y -= rect.top
                            if e.type == MOUSEMOTION:
                                move((x, y))
                            else:
                                click((x, y))
                elif menu_inhibit:
                    if e.type == MOUSEMOTION:
                        current_menu.Mouse_Move(e.pos)
                    else:
                        current_menu.Mouse_Down(e.pos)

            elif e.type == KEYDOWN:
                if not menu_inhibit:
                    ui.Key_Press(e.key)

                elif menu_inhibit:
                    current_menu.Key_Press(e.key)

                if DEBUG:
                    # Cheats.
                    if e.key == K_F10:
                        New_Mail("Cheat used: Advanced to next season.")
                        g.season_ends = 0
                    elif e.key == K_F9:
                        New_Mail("Cheat used: Screen filled with white.")
                        screen.fill((255, 255, 255))
                    elif e.key == K_F8:
                        # Lose the game cheat
                        # Heh, worst cheat ever.
                        New_Mail("Cheat used: Game ended.")
                        g.game_ends_at = cur_time

            e = pygame.event.poll()

        # Any commands from the menu?
        if menu_inhibit:
            cmd = current_menu.Get_Command()
            current_menu.Select(None)  # consume command
            if current_menu == in_game_menu:
                # It's the normal menu.
                if cmd == MENU_QUIT:
                    loop_running = False
                    quit = True
                    ui.Reset()  # makes menu disappear
                elif cmd == MENU_MENU:
                    loop_running = False
                    ui.Reset()
                elif cmd == MENU_SAVE:
                    if (g.game_running):
                        # Switch to alternate menu
                        current_menu = save_menu.Save_Menu(True)
                elif cmd == MENU_LOAD:
                    current_menu = save_menu.Save_Menu(False)
                elif cmd == MENU_MUTE:
                    config.cfg.mute = not config.cfg.mute
                    ui.Reset()
                elif cmd == MENU_REVIEW:
                    loop_running = False
                    stats_review = True
                    ui.Reset()
                elif cmd != None:
                    # Default option - back to game
                    if (not g.game_running):
                        New_Mail("Sorry - the game has finished")
                    ui.Reset()
            else:
                # It's another menu! That means it's the save menu.
                if cmd != None and cmd >= 0:
                    if not current_menu.Is_Saving():
                        g = Restore(g, cmd)
                    else:
                        label = f"Day {math.floor(g.game_time.Get_Day())} - {g.season_fx.name} season - {time.asctime()}"
                        g.net.Make_Ready_For_Save()
                        result = save_game.Save(g, cmd, label)
                        if result == None:
                            New_Mail("Game saved.")
                        else:
                            New_Mail(result)
                if cmd != None:
                    # Back to game.
                    Special_Refresh()
                    current_menu = in_game_menu
                    ui.Reset()

        if autosave_timer <= cur_time and g.game_running and DEBUG and not menu_inhibit:
            # Autosave is slow, so it's really a debugging feature.
            save_game.Save(g, 11, "Autosave")
            autosave_timer = cur_time + 60

        if (g.historian_time <=
                cur_time) and (g.game_running) and (not menu_inhibit):
            g.historian.append(review.Analyse_Network(g))
            g.historian_time = cur_time + 4

    tutor.Off()

    # About to exit. Blackout.
    screen.fill((0, 0, 0))

    if (stats_review):
        review.Review(screen, (width, height), g, g.historian)

    return quit
コード例 #4
0
def Init_Quakes():
    global quake_sound
    quake_sound = sound.Persisting_Sound("earthquake")
コード例 #5
0
        for r in [stats_rect, global_stats_rect, edge]:
            extra.Line_Edging(screen, r, False)

        r = picture.get_rect()
        r.center = picture_surf.get_rect().center
        extra.Line_Edging(picture_surf, r, False)
        picture_surf.blit(picture, r.topleft)

    Special_Refresh()

    stats_surf.fill((0, 0, 0))

    FRAME_RATE = 35

    alarm_sound = sound.Persisting_Sound("emergency")

    teaching = (challenge == MENU_TUTORIAL)

    # Game data holder
    g = Game_Data()
    g.version = startup.Get_Game_Version()
    g.sysinfo = extra.Get_System_Info()

    # Steam network initialisation
    g.net = Network(teaching)

    DIFFICULTY.Set(MENU_INTERMEDIATE)

    # Establish equilibrium with initial network.
    for i in xrange(300):
コード例 #6
0
ファイル: game.py プロジェクト: ubudog/20kly
def Main_Loop(restore_pos):
    global game

    # Initialisation of screen things.
    (width, height) = screen.Update_Resolution()
    menu_margin = height
    screen.surface.fill(BLACK)
    pygame.display.flip()
    tutor.Off()

    draw_obj.Flush_Draw_Obj_Cache()  # in case of resize

    # Grid setup
    (w, h) = GRID_SIZE
    assert w == h
    Set_Grid_Size(height / h)

    # Right-hand side windows are removed
    game_screen_rect = Rect(SCROLL_MARGIN, SCROLL_MARGIN,
                            width - (SCROLL_MARGIN * 2),
                            height - (SCROLL_MARGIN * 2))
    game_screen_surf = screen.surface.subsurface(game_screen_rect)

    menu_button_rect = Rect(0, 0, SCROLL_MARGIN * 3, SCROLL_MARGIN * 3)

    alarm_sound = sound.Persisting_Sound("emergency")

    # UI setup
    ui = User_Interface(game.net, (width, height), game.bg_number)

    exit_options = [(MENU_MENU, "Exit to Main Menu", []),
                    (MENU_QUIT, "Exit to " + extra.Get_OS(), [K_F10])]

    save_available = [(MENU_SAVE, "Save Game", []),
                      (MENU_LOAD, "Restore Game", []), (None, None, [])]

    if (game.challenge == MENU_TUTORIAL):
        save_available = []

    in_game_menu = menu.Menu([(None, None, []), (MENU_MUTE, "Toggle Sound",
                                                 []), (None, None, [])] +
                             save_available +
                             [(MENU_HIDE, "Return to Game", [K_ESCAPE])] +
                             exit_options)

    current_menu = in_game_menu

    flash = True
    quit_state = MENU_LOOP_RUN
    in_game_menu.Select(None)
    mail.Initialise()
    autosave_timer = 0

    DIFFICULTY.Set(game.challenge)

    def Summary():
        lev = dict()
        lev[MENU_TUTORIAL] = "a Tutorial"
        lev[MENU_BEGINNER] = "a Beginner"
        lev[MENU_INTERMEDIATE] = "an Intermediate"
        lev[MENU_EXPERT] = "an Expert"

        assert game.challenge != None
        assert lev.has_key(game.challenge)
        New_Mail("You are playing " + lev[game.challenge] + " game.")

    # Almost ready to start... but are we starting
    # from a savegame?
    def Restore(cmd):
        global game
        (g2, result) = save_game.Load(game, cmd)
        if (result == None):
            game = g2
            ui.net = game.net
            mail.Initialise()
            assert game.challenge != None
            DIFFICULTY.Set(game.challenge)
            New_Mail("Game restored. It is the " + game.season_fx.name +
                     " season.")
        else:
            New_Mail(result)

    if (restore_pos != None):
        game.challenge = MENU_INTERMEDIATE
        Restore(restore_pos)

    assert game.challenge != None
    Summary()

    if (game.challenge == MENU_TUTORIAL):
        tutor.On((menu_margin * 40) / 100)

    # In Game - Main loop
    while (quit_state == MENU_LOOP_RUN):

        if (game.game_running):
            flash = not flash

        draw_obj.Next_Frame()  # Flashing lights on the various items
        ui.Draw_Game(game_screen_surf, game.season_fx)
        pygame.draw.rect(screen.surface, CYAN, menu_button_rect)

        game.season_fx.Per_Frame(1)
        ui.Frame_Advance()
        game.net.Compute()

        pygame.display.flip()
        screen.clock.tick(FRAME_RATE)

        # Events
        e = screen.Get_Event(False)
        while (e.type != NOEVENT):
            if e.type == QUIT:
                quit_state = MENU_QUIT
                break

            elif e.type == VIDEORESIZE:
                quit_state = MENU_RESIZE_EVENT

            elif ((e.type == MOUSEBUTTONDOWN) and (e.button == BUTTON_LEFT)):
                # Left mouse down
                (x, y) = e.pos
                if menu_button_rect.collidepoint(e.pos):
                    # on menu button
                    quit_state = MENU_MENU

                elif game_screen_rect.collidepoint(e.pos):
                    # on game window
                    ui.Game_Mouse_Down(
                        (x - game_screen_rect.left, y - game_screen_rect.top))

                else:
                    # on scrollbar
                    pass

            elif (e.type == MOUSEMOTION):
                (x, y) = e.pos
                ui.Game_Mouse_Move(
                    (x - game_screen_rect.left, y - game_screen_rect.top))

            elif ((e.type == MOUSEBUTTONUP) and (e.button == BUTTON_LEFT)):
                (x, y) = e.pos
                ui.Game_Mouse_Up(
                    (x - game_screen_rect.left, y - game_screen_rect.top))

            elif e.type == KEYDOWN:
                ui.Key_Press(e.key)

            elif ((e.type == MOUSEBUTTONDOWN) and (e.button != BUTTON_LEFT)):
                ui.Right_Mouse_Down()

            e = screen.Get_Event(False)

    tutor.Off()
    alarm_sound.Set(0.0)

    if quit_state != MENU_MENU:
        return quit_state

    # In Game - Menu
    quit_state = MENU_LOOP_RUN
    while quit_state == MENU_LOOP_RUN:
        current_menu.Draw(screen.surface)

        pygame.display.flip()
        screen.clock.tick(FRAME_RATE)

        # Events
        e = screen.Get_Event(True)
        while (e.type != NOEVENT):
            if e.type == QUIT:
                quit_state = MENU_QUIT
                break

            elif e.type == VIDEORESIZE:
                quit_state = MENU_RESIZE_EVENT

            elif ((e.type == MOUSEBUTTONDOWN) and (e.button == BUTTON_LEFT)):
                current_menu.Mouse_Down(e.pos)

            elif e.type == MOUSEMOTION:
                current_menu.Mouse_Move(e.pos)

            elif e.type == KEYDOWN:
                current_menu.Key_Press(e.key)

            e = screen.Get_Event(False)

        cmd = current_menu.Get_Command()
        current_menu.Select(None)  # consume command

        if (current_menu == in_game_menu):

            # It's the normal menu.
            if (cmd == MENU_QUIT):
                quit_state = MENU_QUIT
                ui.Reset()  # makes menu disappear

            elif (cmd == MENU_MENU):
                quit_state = MENU_MENU
                ui.Reset()

            elif (cmd == MENU_SAVE):
                if (game.game_running):
                    # Switch to alternate menu
                    current_menu = save_menu.Save_Menu(True)

            elif (cmd == MENU_LOAD):
                current_menu = save_menu.Save_Menu(False)

            elif (cmd == MENU_REVIEW):
                quit_state = MENU_REVIEW
                ui.Reset()

            elif (cmd != None):
                # Default option - back to game
                if (not game.game_running):
                    New_Mail("Sorry - the game has finished")
                ui.Reset()

        else:
            # It's another menu! That means it's the save menu.
            if ((cmd != None) and (cmd >= 0)):
                if (not current_menu.Is_Saving()):
                    Restore(cmd)

                else:
                    label = "%s season - %s" % (game.season_fx.name,
                                                time.asctime())

                    game.net.Make_Ready_For_Save()
                    result = save_game.Save(game, cmd, label)
                    if (result == None):
                        New_Mail("Game saved.")
                    else:
                        New_Mail(result)

            if (cmd != None):
                # Back to game.
                Special_Refresh()
                current_menu = in_game_menu
                ui.Reset()

    return quit_state