Ejemplo n.º 1
0
def play(screen, playlist, configs, songconf, playmode):
    numplayers = len(configs)

    game = games.GAMES[playmode]

    songs_played = 0
    # Decides whether or not the Ready?/Go! should be displayed before
    # the song.
    first = True

    display_songinfo = (mainconfig['songinfoscreen'] == 2
                        or (mainconfig['songinfoscreen'] == 1
                            and len(playlist) != 1))

    songdata = None

    players = []
    for playerID in range(numplayers):
        plr = Player(playerID, configs[playerID], songconf, game)
        players.append(plr)

    for songfn, diff in playlist:
        try:
            current_song = fileparsers.SongItem(songfn)
        except None:
            error.ErrorMessage(
                screen,
                _("There was an error loading ") + os.path.split(songfn)[1])
            first = True
            continue

        songs_played += 1
        prevscr = pygame.transform.scale(screen, (640, 480))
        songdata = steps.SongData(current_song, songconf)

        if display_songinfo:
            if not SongInfoScreen(current_song, diff, playmode, songconf,
                                  configs, screen).proceed_to_song:
                break
            for playerID in range(numplayers):
                for opt, dummy in changeable_between:
                    players[playerID].__dict__[opt] = configs[playerID][opt]

        for pid, player in enumerate(players):
            player.set_song(current_song, diff[pid], songdata.lyricdisplay)

        print(_("Playing"), songfn)
        print(songdata.title.encode(STDOUT_ENCODING, "replace"), "by", end=' ')
        print(songdata.artist.encode(STDOUT_ENCODING, "replace"))

        if dance(screen, songdata, players, prevscr, first, game):
            first = False
            break  # Failed
        first = False
        if True in [p.escaped for p in players]:
            break

    if mainconfig['grading'] and not first and songdata:
        grade = gradescreen.GradingScreen(screen, players, songdata.banner)

    if songconf["audiosync"] == 2:
        old_offset = mainconfig["masteroffset"]
        new_offset = old_offset + players[0].stats.offset()
        # Do not just replace masteroffset with new offset. Feed it into masteroffset
        # with 33% significance. That way we approach the correct value across multiple
        # plays and avoid messing up the value based on a single "bad" play.
        mainconfig["masteroffset"] = (old_offset * 2 + new_offset) // 3

    # If we only play one song (all the way through), then it's safe to enter
    # a grade. This means course grades are going to get kind of messy,
    # and have to be handled by the course stuff rather than here.
    if songs_played == 1 and not players[0].escaped:
        for p in players:
            if not p.failed:
                records.add(current_song.info["recordkey"], diff[p.pid],
                            playmode, p.grade.rank(), " ")
            else:
                records.add(current_song.info["recordkey"], diff[p.pid],
                            playmode, -2, " ")
Ejemplo n.º 2
0
def dance(screen, song, players, prevscr, ready_go, game):
    songFailed = False

    # text group, e.g. judgings and combos
    tgroup = RenderUpdates()
    # lyric display group
    lgroup = RenderUpdates()

    background = pygame.Surface([640, 480])

    if song.movie != None:
        backmovie = BGMovie(song.movie)
    else:
        backmovie = None

    background.fill(colors.BLACK)
    screen.fill(colors.BLACK)

    if ready_go:
        ready_go_time = min(100, *[plr.ready for plr in players])
        tgroup.add(ReadyGoSprite(ready_go_time))

    if mainconfig['showbackground'] > 0:
        if backmovie is None:
            bgkludge = pygame.image.load(song.background).convert()
            bgkrect = bgkludge.get_rect()
            if (bgkrect.size[0] == 320) and (bgkrect.size[1] == 240):
                bgkludge = pygame.transform.scale2x(bgkludge)
            else:
                bgkludge = pygame.transform.scale(bgkludge, [640, 480])
            bgkludge.set_alpha(mainconfig['bgbrightness'], RLEACCEL)

            q = mainconfig['bgbrightness'] / 256.0
            # FIXME
            for i in range(0, 101, 5):
                p = i / 100.0
                prevscr.set_alpha(256 * (1 - p) * q, RLEACCEL)
                screen.fill(colors.BLACK)
                screen.blit(prevscr, [0, 0])
                screen.blit(bgkludge, [0, 0])
                pygame.display.update()
                pygame.time.delay(1)

            background.blit(bgkludge, [0, 0])
        else:
            pygame.display.update()
    else:
        pygame.display.update()

    if mainconfig["strobe"]: tgroup.add(Blinky(song.bpm))

    if mainconfig["fpsdisplay"]:
        fpstext = FPSDisp()
        timewatch = TimeDisp()
        tgroup.add([fpstext, timewatch])
    else:
        fpstext = None

    if mainconfig['showlyrics']:
        lgroup.add(song.lyricdisplay.channels())

    fontfn, basesize = FontTheme.Dance_title_artist
    songtext = fontfx.zztext(song.title, 480, 12, basesize, fontfn)
    grptext = fontfx.zztext(song.artist, 160, 12, basesize, fontfn)

    songtext.zin()
    grptext.zin()

    tgroup.add([songtext, grptext])

    song.init()

    if song.crapout != 0:
        error.ErrorMessage(
            screen,
            _("The audio file for this song ") + song.filename +
            _(" could not be found."))
        return False  # The player didn't fail.

    if mainconfig['assist']: music.set_volume(0.6)
    else: music.set_volume(1.0)

    song.play()
    for plr in players:
        plr.start_song()

    autofail = mainconfig['autofail']

    screenshot = False
    ui.ui.clear()

    while True:
        if autofail:
            songFailed = True
            for plr in players:
                if not plr.lifebar.gameover:
                    songFailed = False
                    break
            if songFailed:
                song.kill()

        for plr in players:
            plr.get_next_events(song)

        if song.is_over(): break
        else: curtime = music.get_pos() / 1000.0

        key = []

        ev = ui.ui.poll_dance()

        while ev[1] != ui.PASS:
            if ev[1] == ui.CANCEL:
                for p in players:
                    p.escaped = True
                return False
            elif ev[1] == ui.SCREENSHOT:
                screenshot = True
            elif ev[1] == ui.LEFT:
                key.append((ev[0], 'l'))
            elif ev[1] == ui.DOWNLEFT:
                key.append((ev[0], 'w'))
            elif ev[1] == ui.UPLEFT:
                key.append((ev[0], 'k'))
            elif ev[1] == ui.RIGHT:
                key.append((ev[0], 'r'))
            elif ev[1] == ui.UPRIGHT:
                key.append((ev[0], 'z'))
            elif ev[1] == ui.DOWNRIGHT:
                key.append((ev[0], 'g'))
            elif ev[1] == ui.UP:
                key.append((ev[0], 'u'))
            elif ev[1] == ui.DOWN:
                key.append((ev[0], 'd'))
            elif ev[1] == ui.CENTER:
                key.append((ev[0], 'c'))
            elif ev[1] == -ui.LEFT:
                key.append((ev[0], '-l'))
            elif ev[1] == -ui.DOWNLEFT:
                key.append((ev[0], '-w'))
            elif ev[1] == -ui.UPLEFT:
                key.append((ev[0], '-k'))
            elif ev[1] == -ui.RIGHT:
                key.append((ev[0], '-r'))
            elif ev[1] == -ui.UPRIGHT:
                key.append((ev[0], '-z'))
            elif ev[1] == -ui.DOWNRIGHT:
                key.append((ev[0], '-g'))
            elif ev[1] == -ui.UP:
                key.append((ev[0], '-u'))
            elif ev[1] == -ui.DOWN:
                key.append((ev[0], '-d'))
            elif ev[1] == -ui.CENTER:
                key.append((ev[0], '-c'))

            ev = ui.ui.poll_dance()

        for ev in key:
            if game.double: pid = ev[0] / 2
            else: pid = ev[0]

            if pid >= 0 and pid < len(players):
                if ev[1][0] != '-':
                    players[pid].handle_keydown(ev, curtime)
                else:
                    players[pid].handle_keyup((ev[0], ev[1][1:]), curtime)

        rectlist = []

        if backmovie:
            backmovie.update(curtime)
            if backmovie.changed or (fpstext.fps() > 30):
                backmovie.resetchange()
                screen.blit(backmovie.image, [0, 0])

        for plr in players:
            rectlist.extend(plr.game_loop(curtime, screen))

        lgroup.update(curtime)
        tgroup.update(curtime)
        rectlist.extend(tgroup.draw(screen))
        rectlist.extend(lgroup.draw(screen))

        if backmovie is None: pygame.display.update(rectlist)
        else: pygame.display.update()

        if screenshot:
            fn = os.path.join(rc_path, "screenshot.bmp")
            print(_("Saving a screenshot to"), fn)
            pygame.image.save(screen, fn)
            screenshot = False

        if backmovie is None:
            lgroup.clear(screen, background)
            tgroup.clear(screen, background)
            for plr in players:
                plr.clear_sprites(screen, background)

        if ((curtime > players[0].length - 1) and (songtext.zdir == 0)
                and (songtext.zoom > 0)):
            songtext.zout()
            grptext.zout()

    if fpstext: print(_("Average FPS for this song was %d.") % fpstext.fps())
    return songFailed
Ejemplo n.º 3
0
    def loop(self):
        pid, ev = ui.ui.poll()
        self._list.set_index(self._index)
        self._title.set_text(self._base_text + " - %d/%d" %
                             (self._index + 1, len(self._songitems)))
        while not (ev == ui.CANCEL and
                   (not self._folders or self._song.isfolder)):
            # Inactive player. If the event isn't set to ui.PASS, we try to use
            # the pid later, which will be bad.
            if pid >= len(self._diff_names):
                ev = ui.PASS
            elif pid >= 0 and ev in (ui.UP,
                                     ui.DOWN):  # Only use menuing UP/DOWN
                ev = ui.PASS
            elif pid < 0 and ev in (
                    ui.LEFT, ui.RIGHT):  # Need LEFT/RIGHT player-specific
                ev = ui.PASS
            elif ev == ui.UP:
                self._index -= 1
            elif ev == ui.DOWN:
                self._index += 1
            elif ev == ui.PGUP:
                self._index -= 7
                ev = ui.UP
            elif ev == ui.PGDN:
                self._index += 7
                ev = ui.DOWN

            elif ev == ui.LEFT:
                if not self._song.isfolder:
                    namei = self._song.diff_list.index(self._diff_names[pid])
                    namei = (namei - 1) % len(self._song.diff_list)
                    name = self._song.diff_list[namei]
                    self._diff_names[pid] = name
                    self._pref_diff_names[pid] = name
                    self._last_player = pid

            elif ev == ui.RIGHT:
                if not self._song.isfolder:
                    namei = self._song.diff_list.index(self._diff_names[pid])
                    namei = (namei + 1) % len(self._song.diff_list)
                    name = self._song.diff_list[namei]
                    self._diff_names[pid] = name
                    self._pref_diff_names[pid] = name
                    self._last_player = pid

            elif ev == ui.RANDOM:
                if self._song.isfolder:
                    if len(self._all_valid_songitems) > 0:
                        self._song = random.choice(self._all_valid_songitems)
                        fol = self._song.folder[SORT_NAMES[
                            mainconfig["sortmode"]]]
                        self._create_song_list(fol)
                        self._index = self._songitems.index(self._song)
                    else:
                        error.ErrorMessage(
                            screen,
                            _("You don't have any songs that are marked ") +
                            _("\"valid\" for random selection."))
                else:
                    valid_songs = [
                        s for s in self._songitems if s.info["valid"]
                    ]
                    if len(valid_songs) > 0:
                        self._song = random.choice(valid_songs)
                        self._index = self._songitems.index(self._song)
                    else:
                        error.ErrorMessage(
                            screen,
                            _("You don't have any songs here that ") +
                            _("are marked \"valid\" for random selection."))
            elif ev == ui.OPTIONS:
                opts = options.OptionScreen(self._configs, self._config,
                                            self._screen)
                self._screen.blit(self._bg, [0, 0])
                self.update()
                pygame.display.update()
                if opts.start_dancing:
                    ev = ui.CONFIRM
                    continue

            elif ev == ui.SORT:
                s = self._songitems[self._index]
                mainconfig["sortmode"] = (mainconfig["sortmode"] +
                                          1) % NUM_SORTS
                sort_name = self._update_songitems()
                if self._folders:
                    if s.isfolder:
                        self._create_folder_list()
                    else:
                        s = self._find_resorted()
                        self._create_song_list(s.folder[sort_name])
                        self._index = self._songitems.index(s)
                else:
                    s = self._find_resorted()
                    self._base_text = _(sort_name).upper()
                    self._songitems.sort(key=SORTS[sort_name])
                    self._index = self._songitems.index(s)
                    self._list.set_items(
                        [s.info["title"] for s in self._songitems])

            elif ev == ui.CONFIRM:
                if self._song.isfolder:
                    self._create_song_list(self._song.name)
                    self._index = 0
                else:
                    music.fadeout(500)
                    dance.play(self._screen,
                               [(self._song.filename, self._diff_names)],
                               self._configs, self._config, self._game)
                    music.fadeout(500)  # The just-played song
                    self._screen.blit(self._bg, [0, 0])
                    pygame.display.update()
                    ui.ui.clear()

            elif ev == ui.CANCEL:
                # first: get the parent folder of the active song
                sort_name = SORT_NAMES[mainconfig["sortmode"]]
                fol = folder_name(self._song.folder[sort_name], sort_name)
                # next: change folder
                self._create_folder_list()
                for d in self._diff_widgets:
                    d.set("None", [127, 127, 127], 0, "?")

                lst = [s.info["title"] for s in self._songitems]
                self._index = lst.index(fol)

            elif ev == ui.FULLSCREEN:
                mainconfig["fullscreen"] ^= 1
                pygame.display.toggle_fullscreen()

            self._index %= len(self._songitems)
            self._song = self._songitems[self._index]

            if self._locked and ev in [ui.LEFT, ui.RIGHT]:
                for i, sd in enumerate(self._diff_names):
                    self._diff_names[i] = self._diff_names[pid]
                    self._pref_diff_names[i] = self._diff_names[pid]

            if ev in [
                    ui.CANCEL, ui.UP, ui.DOWN, ui.RANDOM, ui.CONFIRM, ui.SORT
            ]:
                self._preview.preview(self._song)
                self._banner.set_song(self._song)

            if ev in [
                    ui.CANCEL, ui.UP, ui.DOWN, ui.RANDOM, ui.CONFIRM, ui.SORT
            ]:
                if ev == ui.UP: self._list.set_index(self._index, -1)
                elif ev == ui.DOWN: self._list.set_index(self._index, 1)
                else: self._list.set_index(self._index, 0)  # don't animate
                self._title.set_text(self._base_text + " - %d/%d" %
                                     (self._index + 1, len(self._songitems)))

            if ev in [ui.UP, ui.DOWN, ui.RANDOM, ui.SORT, ui.CONFIRM]:
                if not self._song.isfolder:
                    for pl, dname in enumerate(self._diff_names):
                        name = self._pref_diff_names[pl]
                        if name in self._song.diff_list:
                            self._diff_names[pl] = name
                        elif self._unify_difficulties(
                                name) in self._song.diff_list:
                            self._diff_names[pl] = self._unify_difficulties(
                                name)
                        else:
                            # if both name and the song's difficulty list can be indexed:
                            # find the nearest defined difficulty
                            if  (name in util.DIFFICULTY_LIST or
                                self._unify_difficulties(name) in util.DIFFICULTY_LIST) and \
                                reduce(lambda a,b: a and b in util.DIFFICULTY_LIST,
                                       self._song.diff_list , True ):
                                name = self._unify_difficulties(name)
                                namei = util.DIFFICULTY_LIST.index(name)
                                diffi = [
                                    util.DIFFICULTY_LIST.index(d)
                                    for d in self._song.diff_list
                                ]
                                dds = [abs(d - namei) for d in diffi]
                                self._diff_names[pl] = self._song.diff_list\
                                                                          [dds.index(min(dds))]
                            else:  # no sensible way to resolve this: jump to middle of list
                                difflen = len(self._song.diff_list)
                                self._diff_names[pl] = self._song.diff_list[
                                    difflen / 2]

            if ev in [
                    ui.UP, ui.DOWN, ui.LEFT, ui.RIGHT, ui.RANDOM, ui.CONFIRM
            ]:
                if not self._song.isfolder:
                    for i, name in enumerate(self._diff_names):
                        rank = records.get(self._song.info["recordkey"], name,
                                           self._game)[0]
                        grade = grades.grades[
                            self._config["grade"]].grade_by_rank(rank)
                        self._diff_widgets[i].set(
                            name, DIFF_COLORS.get(name, [127, 127, 127]),
                            self._song.difficulty[name], grade)

            self.update()
            pid, ev = ui.ui.poll()
Ejemplo n.º 4
0
    def __init__(self, songs, courses, screen, game):

        InterfaceWindow.__init__(self, screen, "newss-bg.png")
        songs = [s for s in songs if s.difficulty.has_key(game)]

        if len(songs) == 0:
            error.ErrorMessage(
                screen,
                _("You don't have any songs for the game mode (") + game +
                _(") that you selected.")
            )  #TODO: format using % for better i18n
            return

        # Construct a mapping between songs displays and dance displays.
        songs_and_dances = [
            (SongItemDisplay(s, game),
             [DanceItemDisplay(s, game, diff) for diff in s.diff_list[game]])
            for s in songs
        ]

        for (s, ds) in songs_and_dances:
            for d in ds:
                s.danceitems[d.diff] = d
                d.songitem = s

        self._songs = [s[0] for s in songs_and_dances]
        self._dances = reduce(lambda x, y: x + y[1], songs_and_dances, [])

        self._index = 0
        self._game = game
        self._config = dict(game_config)
        self._all_songs = self._songs
        self._all_dances = self._dances
        self._all_valid_songs = [s for s in self._songs if s.info["valid"]]
        self._all_valid_dances = [d for d in self._dances if d.info["valid"]]

        self._list = ListBox(FontTheme.SongSel_list, [255, 255, 255], 26, 16,
                             220, [408, 56])
        # please use set constructions after python 2.4 is adopted
        sort_name = self._update_songitems()

        if mainconfig["folders"]:
            self._create_folders()
            self._create_folder_list()
        else:
            self._folders = None
            self._base_text = sort_name.upper()

            self._songitems.sort(key=SORTS[sort_name])
            self._list.set_items([s.info["title"] for s in self._songitems])

        self._preview = SongPreview()
        self._preview.preview(self._songitems[self._index])
        self._song = self._songitems[self._index]

        # Both players must have the same difficulty in locked modes.
        self._locked = games.GAMES[self._game].couple

        players = games.GAMES[game].players
        #    self._diffs = [] # Current difficulty setting
        self._diff_widgets = []  # Difficulty widgets
        self._configs = []
        self._diff_names = []  # Current chosen difficulties
        self._pref_diff_names = []  # Last manually selected difficulty names
        self._last_player = 0  # Last player to change a difficulty

        for i in range(players):
            self._configs.append(dict(player_config))
            d = DifficultyBox([84 + (233 * i), 434])
            self._pref_diff_names.append(util.DIFFICULTY_LIST[0])
            if not self._song.isfolder:
                self._diff_names.append(self._song.diff_list[0])
                diff_name = self._diff_names[i]
                rank = records.get(self._song.info["recordkey"], diff_name,
                                   self._game)[0]
                grade = grades.grades[self._config["grade"]].grade_by_rank(
                    rank)
                d.set(diff_name, DIFF_COLORS.get(diff_name, [127, 127, 127]),
                      self._song.difficulty[diff_name], grade)
            else:
                self._diff_names.append(" ")
                d.set(_("None"), [127, 127, 127], 0, "?")
            self._diff_widgets.append(d)

        ActiveIndicator([405, 259], width=230).add(self._sprites)
        self._banner = BannerDisplay([205, 230])
        self._banner.set_song(self._song)
        self._sprites.add(
            HelpText(SS_HELP, [255, 255, 255], [0, 0, 0], FontTheme.help,
                     [206, 20]))

        self._title = TextDisplay('SongSel_sort_mode', [210, 28], [414, 27])
        self._sprites.add(self._diff_widgets +
                          [self._banner, self._list, self._title])
        self._screen.blit(self._bg, [0, 0])
        pygame.display.update()
        self.loop()
        music.fadeout(500)
        pygame.time.wait(500)
        # FIXME Does this belong in the menu code? Probably.
        music.load(os.path.join(sound_path, "menu.ogg"))
        music.set_volume(1.0)
        music.play(4, 0.0)
        player_config.update(self._configs[0])  # Save p1's settings
        game_config.update(self._config)  # save game settings
Ejemplo n.º 5
0
    def __init__(self, songitems, courses, screen, gametype):
        InterfaceWindow.__init__(self, screen, "endless-bg.png")
        pygame.display.update()

        self.player_configs = [dict(player_config)]

        if games.GAMES[gametype].players == 2:
            self.player_configs.append(dict(player_config))

        self.game_config = dict(game_config)
        songitems = [s for s in songitems if s.difficulty.has_key(gametype)]
        # Autofail always has to be on for endless, so back up the old value.
        oldaf = mainconfig["autofail"]
        diffs = []
        diff_count = {}  # if we see a difficulty 2 times or more, use it
        for song in songitems:
            if song.difficulty.has_key(gametype):
                for d in song.difficulty[gametype]:
                    if diff_count.has_key(d) and d not in diffs:
                        diffs.append(d)
                    else:
                        diff_count[d] = True

        diffs.sort(util.difficulty_sort)

        if len(diffs) == 0:
            error.ErrorMessage(
                screen,
                _("You need more songs to play Endless Mode. ") +
                _("Otherwise, it's just really boring."))
            return

        mainconfig["autofail"] = 1

        self.constraints = [
            Constraint("name", songitems[0].difficulty[gametype].keys()[0])
        ]

        if games.GAMES[gametype].players == 2:
            if games.GAMES[gametype].couple == True:
                # Lock both players to the same constraints in couple modes.
                self.constraints.append(self.constraints[0])
            else:
                c = Constraint("name",
                               songitems[0].difficulty[gametype].keys()[0])
                self.constraints.append(c)

        for i, c in enumerate(self.constraints):
            EndlessDiffDisplay(i, c).add(self._sprites)

        self._sprites.add(
            HelpText(ENDLESS_HELP, [255, 255, 255], [0, 0, 0], FontTheme.help,
                     [320, 20]))

        music.load(os.path.join(sound_path, "menu.ogg"))
        music.play(4, 0.0)

        pid, ev = 0, ui.PASS

        while ev != ui.QUIT:
            pid, ev = ui.ui.poll()

            if ev == ui.START:
                options.OptionScreen(self.player_configs, self.game_config,
                                     screen)
                self._screen.blit(self._bg, [0, 0])
                pygame.display.update()

            # Start game
            elif ev == ui.CONFIRM:
                dance.play(
                    screen,
                    FakePlaylist(songitems, self.constraints, screen,
                                 gametype), self.player_configs,
                    self.game_config, gametype)

                self._screen.blit(self._bg, [0, 0])
                pygame.display.update()
                music.load(os.path.join(sound_path, "menu.ogg"))
                music.play(4, 0.0)
                ui.ui.clear()

            # Ignore unknown events
            elif pid >= len(self.constraints):
                pass

            elif ev == ui.DOWN and self.constraints[pid].kind != "name":
                self.constraints[pid].kind = "name"
                self.constraints[pid].value = diffs[0]
            elif ev == ui.UP and self.constraints[pid].kind != "number":
                self.constraints[pid].kind = "number"
                self.constraints[pid].value = (1, 3)
            elif ev == ui.LEFT:  # easier
                if self.constraints[pid].kind == "name":
                    newi = max(0, diffs.index(self.constraints[pid].value) - 1)
                    self.constraints[pid].value = diffs[newi]
                elif self.constraints[pid].kind == "number":
                    newmin = max(self.constraints[pid].value[0] - 1, 1)
                    self.constraints[pid].value = (newmin, newmin + 2)

            elif ev == ui.RIGHT:  # harder
                if self.constraints[pid].kind == "name":
                    newi = min(
                        len(diffs) - 1,
                        diffs.index(self.constraints[pid].value) + 1)
                    self.constraints[pid].value = diffs[newi]
                elif self.constraints[pid].kind == "number":
                    newmin = min(self.constraints[pid].value[0] + 1, 9)
                    self.constraints[pid].value = (newmin, newmin + 2)

            elif ev == ui.FULLSCREEN:
                mainconfig["fullscreen"] ^= 1
                pygame.display.toggle_fullscreen()

            self.update()

        mainconfig["autofail"] = oldaf
        player_config.update(self.player_configs[0])
Ejemplo n.º 6
0
def play(screen, playlist, configs, songconf, playmode):
    numplayers = len(configs)

    game = games.GAMES[playmode]

    songs_played = 0
    # Decides whether or not the Ready?/Go! should be displayed before
    # the song.
    first = True

    display_songinfo = (mainconfig['songinfoscreen'] == 2
                        or (mainconfig['songinfoscreen'] == 1
                            and len(playlist) != 1))

    songdata = None

    players = []
    for playerID in range(numplayers):
        plr = Player(playerID, configs[playerID], songconf, game)
        players.append(plr)

    for songfn, diff in playlist:
        try:
            current_song = fileparsers.SongItem(songfn)
        except None:
            error.ErrorMessage(
                screen,
                _("There was an error loading ") + os.path.split(songfn)[1])
            first = True
            continue

        songs_played += 1
        prevscr = pygame.transform.scale(screen, (640, 480))
        songdata = steps.SongData(current_song, songconf)

        if display_songinfo:
            if not SongInfoScreen(current_song, diff, playmode, songconf,
                                  configs, screen).proceed_to_song:
                break
            for playerID in range(numplayers):
                for opt, dummy in changeable_between:
                    players[playerID].__dict__[opt] = configs[playerID][opt]

        for pid, player in enumerate(players):
            player.set_song(current_song, diff[pid], songdata.lyricdisplay)

        print _("Playing"), songfn
        print songdata.title.encode(sys.stdout.encoding, "replace"), "by",
        print songdata.artist.encode(sys.stdout.encoding, "replace")

        if dance(screen, songdata, players, prevscr, first, game):
            first = False
            break  # Failed
        first = False
        if True in [p.escaped for p in players]:
            break

    if mainconfig['grading'] and not first and songdata:
        grade = gradescreen.GradingScreen(screen, players, songdata.banner)

    # If we only play one song (all the way through), then it's safe to enter
    # a grade. This means course grades are going to get kind of messy,
    # and have to be handled by the course stuff rather than here.
    if songs_played == 1 and not players[0].escaped:
        for p in players:
            if not p.failed:
                records.add(current_song.info["recordkey"], diff[p.pid],
                            playmode, p.grade.rank(), " ")
            else:
                records.add(current_song.info["recordkey"], diff[p.pid],
                            playmode, -2, " ")
Ejemplo n.º 7
0
    def __next__(self):
        # We're done.
        if self.index == len(self.songs): raise StopIteration
        name, diff, mods = self.songs[self.index]
        fullname = None

        a, b = 0, 0
        if isinstance(diff, list): pass
        elif diff.find("..") != -1: a, b = list(map(int, diff.split("..")))
        elif len(diff) < 3: a, b = int(diff), int(diff)
        if a or b: diff = list(range(a, b + 1))

        # Check for player's best/worst/likes/dislikes. There are stored
        # as a tuple of (type, number).
        if name[0] == _("BEST"):
            s = self.recordkeys.get(records.best(name[1], diff, self.gametype),
                                    None)
            if s:
                fullname = s.filename
                if isinstance(diff, list):
                    diff = [
                        d for d in diff if d in s.difficulty[self.gametype]
                    ][0]
        elif name[0] == _("WORST"):
            s = self.recordkeys.get(
                records.worst(name[1], diff, self.gametype), None)
            if s:
                fullname = s.filename
                if isinstance(diff, list):
                    diff = [
                        d for d in diff if d in s.difficulty[self.gametype]
                    ][0]
        elif name[0] == _("LIKES"):
            s = self.recordkeys.get(records.like(name[1], diff, self.gametype),
                                    None)
            if s:
                fullname = s.filename
                if isinstance(diff, list):
                    diff = [
                        d for d in diff if d in s.difficulty[self.gametype]
                    ][0]
        elif name[0] == _("DISLIKES"):
            s = self.recordkeys.get(
                records.dislike(name[1], diff, self.gametype), None)
            if s:
                fullname = s.filename
                if isinstance(diff, list):
                    diff = [
                        d for d in diff if d in s.difficulty[self.gametype]
                    ][0]

        elif name[-1] == "*":  # A random song
            # First pull out all the songs that we might be acceptable.
            if "/" in name:
                # Random song from a specific mix.
                folder, dummy = name.split("/")
                folder = folder.lower()
                if folder in self.all_songs:
                    songs = [
                        s for s in list(self.all_songs[folder].values())
                        if (s, diff) not in self.past_songs
                    ]
                else:
                    error.ErrorMessage(self.screen,
                                       folder + _(" was not found."))
                    raise StopIteration

            else:
                # Any random song.
                songs = []
                for v in list(self.all_songs.values()):
                    songs.extend(list(v.values()))

            songs = [
                s for s in songs if (s, diff) not in self.past_songs
                and self._find_difficulty(s, diff)
            ]

            if len(songs) == 0:
                error.ErrorMessage(self.screen,
                                   _("No valid songs were found."))
                raise StopIteration
            else:
                song = random.choice(songs)
                diff = self._find_difficulty(song, diff)
                fullname = song.filename

        # Let's try to find the damned song.
        # Unfortunately, it can be given as just a title(+subtitle), or a
        # mix with a title. Or a filename. That's why we need the
        # all_songs hash.
        else:
            for path in mainconfig["songdir"].split(os.pathsep):
                fn = os.path.join(path, name)
                fn = os.path.expanduser(fn)
                if os.path.isfile(fn): fullname = fn
                elif os.path.isdir(fn):
                    file_list = util.find(fn, ["*.sm", "*.dwi"], 1)
                    if len(file_list) != 0: fullname = file_list[0]
                if fullname: break

        if not fullname and len(name[0]) == 1:  # Still haven't found it...
            folder, song = name.split("/")
            song = self.all_songs.get(folder.lower(), {}).get(song.lower())
            if song: fullname = song.filename

        if not fullname:
            if len(name[0]) > 1:
                name = _("Player's %s #%d") % (name[0].capitalize(), name[1])
            error.ErrorMessage(self.screen, name + _("was not found."))
            raise StopIteration

        self.index += 1
        self.past_songs.append((fullname, diff))
        return (fullname, [diff] * len(self.player_configs))