Exemplo n.º 1
0
    def start_pygame(self):
        """ Initialize pygame system stuff and draw empty window """
        if not pygame.display.get_init():
            pygame.display.init()
        if not pygame.font.get_init():
            pygame.font.init()
        pygame.display.set_icon(self.get_image("collectibles_333.png"))
        self.clock = pygame.time.Clock()

        opt = Options()
        # figure out where we should put our window.
        xpos = opt.x_position
        ypos = opt.y_position
        # it can go negative when weird problems happen, so put it in a default location in that case
        if xpos < 0:
            xpos = 100
        if ypos < 0:
            ypos = 100

        os.environ['SDL_VIDEO_WINDOW_POS'] = "%d, %d" % (xpos, ypos)

        if self.screen is None and opt.transparent_mode:  # If screen is none, we make our own
            self.screen = pygame.display.set_mode((opt.width, opt.height),
                                                  NOFRAME)
            self.transparent_mode()
        elif self.screen is None:
            self.screen = pygame.display.set_mode((opt.width, opt.height),
                                                  RESIZABLE)
            self.screen.fill(DrawingTool.color(opt.background_color))
        self.reset_options()

        if platform.system() == "Windows":
            self.win_info = pygameWindowInfo.PygameWindowInfo()
        del os.environ['SDL_VIDEO_WINDOW_POS']
Exemplo n.º 2
0
    def run(self):
        os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (
            self.options["xposition"], self.options["yposition"])
        # initialize pygame system stuff
        pygame.init()
        update_notifier = self.check_for_update()
        pygame.display.set_caption("Rebirth Item Tracker" + update_notifier)
        screen = pygame.display.set_mode(
            (self.options["width"], self.options["height"]), RESIZABLE)
        self.font = pygame.font.SysFont("Arial",
                                        int(8 *
                                            self.options["size_multiplier"]),
                                        bold=True)
        pygame.display.set_icon(
            self.get_image("collectibles/collectibles_333.png"))
        done = False
        clock = pygame.time.Clock()
        winInfo = None
        if platform.system() == "Windows":
            winInfo = pygameWindowInfo.PygameWindowInfo()

        del os.environ['SDL_VIDEO_WINDOW_POS']
        while not done:
            # pygame logic
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    if platform.system() == "Windows":
                        winPos = winInfo.getScreenPosition()
                        self.options["xposition"] = winPos["left"]
                        self.options["yposition"] = winPos["top"]
                        self.save_options()
                    done = True
                elif event.type == VIDEORESIZE:
                    screen = pygame.display.set_mode(event.dict['size'],
                                                     RESIZABLE)
                    self.options["width"] = event.dict["w"]
                    self.options["height"] = event.dict["h"]
                    self.save_options()
                    self.reflow()
                    pygame.display.flip()
                elif event.type == MOUSEMOTION:
                    if pygame.mouse.get_focused():
                        x, y = pygame.mouse.get_pos()
                        if y < len(self.item_position_index):
                            selected_row = self.item_position_index[y]
                            if x < len(selected_row):
                                self.selected_item_idx = selected_row[x]
                                if self.selected_item_idx:
                                    self.item_message_start_time = self.framecount
                elif event.type == KEYDOWN:
                    if len(self.collected_items) > 0:
                        if event.key == pygame.K_RIGHT:
                            self.adjust_selected_item(1)
                        elif event.key == pygame.K_LEFT:
                            self.adjust_selected_item(-1)
                        elif event.key == pygame.K_RETURN:
                            self.load_selected_detail_page()
                elif event.type == MOUSEBUTTONDOWN:
                    if event.button == 1:
                        self.load_selected_detail_page()
                    if event.button == 3:
                        if os.path.isfile("optionpicker/option_picker.exe"):
                            self.log_msg("Starting option picker from .exe",
                                         "D")
                            subprocess.call(os.path.join(
                                'optionpicker', "option_picker.exe"),
                                            shell=True)
                        elif os.path.isfile("option_picker.py"):
                            self.log_msg("Starting option picker from .py",
                                         "D")
                            subprocess.call("python option_picker.py",
                                            shell=True)
                        else:
                            self.log_msg("No option_picker found!", "D")
                        self.load_options()
                        self.selected_item_idx = None  # Clear this to avoid overlapping an item that may have been hidden
                        self.reflow()

            screen.fill(self.color(self.options["background_color"]))
            clock.tick(int(self.options["framerate_limit"]))

            if self.log_not_found:
                draw_text(
                    screen,
                    "log.txt not found. Put the RebirthItemTracker folder inside the isaac folder, next to log.txt",
                    self.color(self.options["text_color"]),
                    pygame.Rect(2, 2, self.options["width"] - 2,
                                self.options["height"] - 2),
                    self.font,
                    aa=True,
                    wrap=True)

            # draw item pickup text, if applicable
            if (len(self.collected_items) > 0
                    and self.options["show_description"]
                    and self.run_start_frame + 120 < self.framecount
                    and self.item_message_countdown_in_progress()):
                self.write_item_text(self.font, screen)
            elif (self.options["show_seed"] or
                  self.options["show_guppy_count"]) and not self.log_not_found:
                # draw seed/guppy text:

                seed = ""
                guppy = ""
                if self.options["show_seed"]:
                    seed = "Seed: " + self.seed

                if self.options["show_guppy_count"]:
                    if len(self.collected_guppy_items) >= 3:
                        guppy += " - Guppy: yes"
                    else:
                        guppy += " - Guppy: " + str(
                            len(self.collected_guppy_items))
                else:
                    guppy = ""

                self.text_height = draw_text(
                    screen,
                    "{}{}".format(seed, guppy),
                    self.color(self.options["text_color"]),
                    pygame.Rect(2, 2, self.options["width"] - 2,
                                self.options["height"] - 2),
                    self.font,
                    aa=True)
                self.reflow()
            else:
                # can only happen if you turn seed + item descriptions off in options while its running
                if self.text_height != 0:
                    self.text_height = 0
                    self.reflow()

            if not self.item_message_countdown_in_progress():
                self.selected_item_idx = None

            floor_to_draw = None
            # draw items on screen, excluding filtered items:
            for item in self.collected_item_info:
                if item.shown:
                    if item.floor:
                        floor_to_draw = item
                    else:
                        self.draw_item(item, screen)
                        #don't draw a floor until we hit the next item (this way multiple floors in a row collapse)
                        if floor_to_draw and self.options["show_floors"]:
                            self.draw_floor(floor_to_draw, screen, self.font)

            # also draw the floor if we hit the end, so the current floor is visible
            if floor_to_draw and self.options["show_floors"]:
                self.draw_floor(floor_to_draw, screen, self.font)

            if (self.selected_item_idx
                    and self.selected_item_idx < len(self.collected_item_info)
                    and self.item_message_countdown_in_progress()):
                item = self.collected_item_info[self.selected_item_idx]
                if item.id not in self.floor_id_to_label:
                    screen.blit(self.get_image(self.id_to_image(item.id)),
                                (item.x, item.y))
                    pygame.draw.rect(
                        screen, self.color(self.options["text_color"]),
                        (item.x, item.y,
                         int(32 * self.options["size_multiplier"]),
                         int(32 * self.options["size_multiplier"])), 2)

            pygame.display.flip()
            self.framecount += 1

            # process log stuff every read_delay seconds. making sure to truncate to an integer or else it might never mod to 0
            if self.framecount % int(
                    self.options["framerate_limit"] * self.read_delay) == 0:
                self.load_log_file()
                self.splitfile = self.content.splitlines()
                # return to start if seek passes the end of the file (usually b/c log file restarted)
                if self.seek > len(self.splitfile):
                    self.log_msg(
                        "Current line number longer than lines in file, returning to start of file",
                        "D")
                    self.seek = 0

                should_reflow = False
                # process log's new output
                for current_line_number, line in enumerate(
                        self.splitfile[self.seek:]):
                    self.log_msg(line, "V")
                    # end floor boss defeated, hopefully?
                    if line.startswith('Mom clear time:'):
                        kill_time = int(line.split(" ")[-1])
                        # if you re-enter a room you get a "mom clear time" again, check for that.
                        # can you fight the same boss twice?
                        if self.current_room not in [
                                x[0] for x in self.bosses
                        ]:
                            self.bosses.append((self.current_room, kill_time))
                            self.log_msg(
                                "Defeated %s%s boss %s at time %s" %
                                (len(self.bosses), self.suffix(len(
                                    self.bosses)), self.current_room,
                                 kill_time), "D")
                    # check + handle the end of the run (order important here!)
                    # we want it after boss kill (so we have that handled) but before RNG Start Seed (so we can handle that)
                    self.check_end_run(line, current_line_number + self.seek)
                    # start of a run
                    if line.startswith('RNG Start Seed:'):
                        # this assumes a fixed width, but from what i see it seems safe
                        self.seed = line[16:25]
                        self.log_msg("Starting new run, seed: %s" % self.seed,
                                     "D")
                        self.run_start_frame = self.framecount
                        self.rolled_item_indices = []
                        self.collected_items = []
                        self.collected_guppy_items = []
                        self.collected_blind_item_indices = []
                        self.log_msg("Emptied item array", "D")
                        self.bosses = []
                        self.log_msg("Emptied boss array", "D")
                        self.run_start_line = current_line_number + self.seek
                        self.run_ended = False
                        with open("seed.txt", "w") as f:
                            f.write(self.seed)

                    # entered a room, use to keep track of bosses
                    if line.startswith('Room'):
                        self.current_room = re.search('\((.*)\)',
                                                      line).group(1)
                        if 'Start Room' not in line:
                            self.getting_start_items = False
                        self.log_msg("Entered room: %s" % self.current_room,
                                     "D")
                    if line.startswith('Level::Init'):
                        self.current_floor = tuple([
                            re.search(
                                "Level::Init m_Stage (\d+), m_AltStage (\d+)",
                                line).group(x) for x in [1, 2]
                        ])
                        self.blind_floor = False  # assume floors aren't blind until we see they are
                        self.getting_start_items = True
                        floor = int(self.current_floor[0])
                        alt = self.current_floor[1]
                        # special handling for cath and chest
                        if alt == '1' and (floor == 9 or floor == 11):
                            floor += 1
                        self.collected_items.append('f' + str(floor))
                        should_reflow = True
                    if line.startswith('Curse of the Labyrinth!'):
                        #it SHOULD always begin with f (that is, it's a floor) because this line only comes right after the floor line
                        if self.collected_items[-1].startswith('f'):
                            self.collected_items[-1] += 'x'
                    if line.startswith('Curse of Blind'):
                        self.blind_floor = True
                    if line.startswith('Spawn co-player!'):
                        self.spawned_coop_baby = current_line_number + self.seek
                    if re.search("Added \d+ Collectibles", line):
                        self.log_msg("Reroll detected!", "D")
                        self.rolled_item_indices = [
                            index
                            for index, item in enumerate(self.collected_items)
                            if item[0] != 'f'
                        ]
                    if line.startswith('Adding collectible'):
                        if len(self.splitfile) > 1 and self.splitfile[
                                current_line_number + self.seek - 1] == line:
                            self.log_msg(
                                "Skipped duplicate item line from baby presence",
                                "D")
                            continue
                        # hacky string manip, idgaf
                        space_split = line.split(" ")
                        # string has the form "Adding collectible 105 (The D6)"
                        item_id = space_split[2]
                        if ((current_line_number + self.seek) -
                                self.spawned_coop_baby) < (
                                    len(self.collected_items) +
                                    10) and item_id in self.collected_items:
                            self.log_msg(
                                "Skipped duplicate item line from baby entry",
                                "D")
                            continue
                        item_name = " ".join(space_split[3:])[1:-1]
                        self.log_msg(
                            "Picked up item. id: %s, name: %s" %
                            (item_id, item_name), "D")
                        id_padded = item_id.zfill(3)
                        item_info = self.items_info[id_padded]
                        with open("itemInfo.txt", "w") as f:
                            desc = self.generateItemDescription(item_info)
                            f.write(item_info["name"] + ":" + desc)

                        # ignore repeated pickups of space bar items
                        if not (item_info.get("space")
                                and item_id in self.collected_items):
                            self.collected_items.append(item_id)
                            self.item_message_start_time = self.framecount
                            self.item_pickup_time = self.framecount
                        else:
                            self.log_msg(
                                "Skipped adding item %s to avoid space-bar duplicate"
                                % item_id, "D")
                        if "guppy" in item_info and item_info.get(
                                "guppy"
                        ) and item_id not in self.collected_guppy_items:
                            self.collected_guppy_items.append(item_id)
                        if self.blind_floor and not self.getting_start_items:
                            # the item we just picked up was picked up blind, so add its index here to track that fact
                            self.collected_blind_item_indices.append(
                                len(self.collected_items) - 1)
                        should_reflow = True

                self.seek = len(self.splitfile)
                if should_reflow:
                    self.reflow()
Exemplo n.º 3
0
    def run(self):
        os.environ['SDL_VIDEO_WINDOW_POS'] = "%d, %d" % (self.options[Option.X_POSITION], self.options[Option.Y_POSITION])
        # initialize pygame system stuff
        pygame.init()
        update_notifier = self.check_for_update()
        pygame.display.set_caption("Rebirth Item Tracker v0.8" + update_notifier)
        screen = pygame.display.set_mode((self.options[Option.WIDTH], self.options[Option.HEIGHT]), RESIZABLE)
        self.font = pygame.font.SysFont(self.options[Option.SHOW_FONT], int(8 * self.options[Option.SIZE_MULTIPLIER]),
                                        bold=self.options[Option.BOLD_FONT])
        pygame.display.set_icon(self.get_image("collectibles/collectibles_333.png"))
        done = False
        clock = pygame.time.Clock()
        winInfo = None
        if platform.system() == "Windows":
            winInfo = pygameWindowInfo.PygameWindowInfo()

        del os.environ['SDL_VIDEO_WINDOW_POS']
        while not done:
            # pygame logic
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    if platform.system() == "Windows":
                        winPos = winInfo.getScreenPosition()
                        self.options[Option.X_POSITION] = winPos["left"]
                        self.options[Option.Y_POSITION] = winPos["top"]
                        self.save_options()
                    done = True
                elif event.type == VIDEORESIZE:
                    screen = pygame.display.set_mode(event.dict['size'],
                                                     RESIZABLE)
                    self.options[Option.WIDTH] = event.dict["w"]
                    self.options[Option.HEIGHT] = event.dict["h"]
                    self.save_options()
                    self.reflow()
                    pygame.display.flip()
                elif event.type == MOUSEMOTION:
                    if pygame.mouse.get_focused():
                        x, y = pygame.mouse.get_pos()
                        if y < len(self.item_position_index):
                            selected_row = self.item_position_index[y]
                            if x < len(selected_row):
                                self.selected_item_idx = selected_row[x]
                                if self.selected_item_idx:
                                    self.item_message_start_time = self.framecount
                elif event.type == KEYDOWN:
                    if len(self.collected_items) > 0:
                        if event.key == pygame.K_RIGHT:
                            self.adjust_selected_item(1)
                        elif event.key == pygame.K_LEFT:
                            self.adjust_selected_item(-1)
                        elif event.key == pygame.K_RETURN:
                            self.load_selected_detail_page()
                        elif event.key == pygame.K_c and pygame.key.get_mods() & pygame.KMOD_CTRL:
                            self.generate_run_summary()
                elif event.type == MOUSEBUTTONDOWN:
                    if event.button == 1:
                        self.load_selected_detail_page()
                    if event.button == 3:
                        import option_picker
                        pygame.event.set_blocked([QUIT, MOUSEBUTTONDOWN, KEYDOWN, MOUSEMOTION])
                        option_picker.options_menu().run()
                        pygame.event.set_allowed([QUIT, MOUSEBUTTONDOWN, KEYDOWN, MOUSEMOTION])
                        self.load_options()
                        self.selected_item_idx = None  # Clear this to avoid overlapping an item that may have been hidden
                        self.reflow()

            screen.fill(self.color(self.options[Option.BACKGROUND_COLOR]))
            clock.tick(int(self.options[Option.FRAMERATE_LIMIT]))

            if self.log_not_found:
                draw_text(
                    screen,
                    "log.txt not found. Put the RebirthItemTracker folder inside the isaac folder, next to log.txt",
                    self.color(self.options[Option.TEXT_COLOR]),
                    pygame.Rect(2, 2, self.options[Option.WIDTH] - 2, self.options[Option.HEIGHT] - 2),
                    self.font,
                    aa=True,
                    wrap=True
                )

            # 19 pixels is the default line height, but we don't know what the line height is with respect to the user's particular size_multiplier.
            # Thus, we can just draw a single space to ensure that the spacing is consistent whether text happens to be showing or not.
            if self.options[Option.SHOW_DESCRIPTION] or self.options[Option.SHOW_CUSTOM_MESSAGE]:
                self.text_height = draw_text(
                    screen,
                    " ",
                    self.color(self.options[Option.TEXT_COLOR]),
                    pygame.Rect(2, 2, self.options[Option.WIDTH] - 2, self.options[Option.HEIGHT] - 2),
                    self.font,
                    aa=True,
                    wrap=self.options[Option.WORD_WRAP]
                )
            else:
                self.text_height = 0

            text_written = False
            # draw item pickup text, if applicable
            if (len(self.collected_items) > 0
                and self.options[Option.SHOW_DESCRIPTION]
                and self.run_start_frame + 120 < self.framecount
                and self.item_message_countdown_in_progress()):
                text_written = self.write_item_text(self.font, screen)
            if not text_written and self.options[
                Option.SHOW_CUSTOM_MESSAGE] and not self.log_not_found:
                # draw seed/guppy text:
                seed = self.seed

                dic = defaultdict(str, seed=seed)
                dic.update(self.player_stats_display)

                # Use vformat to handle the case where the user adds an undefined
                # placeholder in default_message
                message = string.Formatter().vformat(
                    self.options[Option.CUSTOM_MESSAGE],
                    (),
                    dic
                )
                self.text_height = draw_text(
                    screen,
                    message,
                    self.color(self.options[Option.TEXT_COLOR]),
                    pygame.Rect(2, 2, self.options[Option.WIDTH] - 2, self.options[Option.HEIGHT] - 2),
                    self.font,
                    aa=True, wrap=self.options[Option.WORD_WRAP]
                )
            self.reflow()

            if not self.item_message_countdown_in_progress():
                self.selected_item_idx = None

            floor_to_draw = None
            # draw items on screen, excluding filtered items:
            for item in self.collected_item_info:
                if item.shown:
                    if item.floor:
                        floor_to_draw = item
                    else:
                        self.draw_item(item, screen)
                        # don't draw a floor until we hit the next item (this way multiple floors in a row collapse)
                        if floor_to_draw and self.options[Option.SHOW_FLOORS]:
                            self.draw_floor(floor_to_draw, screen, self.font)

            # also draw the floor if we hit the end, so the current floor is visible
            if floor_to_draw and self.options[Option.SHOW_FLOORS]:
                self.draw_floor(floor_to_draw, screen, self.font)

            if (self.selected_item_idx
                and self.selected_item_idx < len(self.collected_item_info)
                and self.item_message_countdown_in_progress()):
                item = self.collected_item_info[self.selected_item_idx]
                if item.id not in self.floor_id_to_label:
                    screen.blit(self.get_image(self.id_to_image(item.id)), (item.x, item.y))
                    size_multiplier = int(32 * self.options[Option.SIZE_MULTIPLIER])
                    pygame.draw.rect(
                        screen,
                        self.color(self.options[Option.TEXT_COLOR]),
                        (item.x,
                         item.y,
                         size_multiplier,
                         size_multiplier),
                        2
                    )

            pygame.display.flip()
            self.framecount += 1

            # process log stuff every read_delay seconds. making sure to truncate to an integer or else it might never mod to 0
            if self.framecount % int(self.options[Option.FRAMERATE_LIMIT] * self.read_delay) == 0:
                self.load_log_file()
                self.splitfile = self.content.splitlines()
                # return to start if seek passes the end of the file (usually b/c log file restarted)
                if self.seek > len(self.splitfile):
                    self.log_msg("Current line number longer than lines in file, returning to start of file", "D")
                    self.seek = 0

                should_reflow = False
                # process log's new output
                for current_line_number, line in enumerate(self.splitfile[self.seek:]):
                    self.log_msg(line, "V")
                    # end floor boss defeated, hopefully?
                    if line.startswith('Mom clear time:'):
                        kill_time = int(line.split(" ")[-1])
                        # if you re-enter a room you get a "mom clear time" again, check for that.
                        # can you fight the same boss twice?
                        if self.current_room not in [x[0] for x in self.bosses]:
                            self.bosses.append((self.current_room, kill_time))
                            self.log_msg(
                                "Defeated %s%s boss %s at time %s" % (len(self.bosses),
                                self.suffix(len(self.bosses)), self.current_room, kill_time), "D")
                    # check + handle the end of the run (order important here!)
                    # we want it after boss kill (so we have that handled) but before RNG Start Seed (so we can handle that)
                    self.check_end_run(line, current_line_number + self.seek)
                    # start of a run
                    if line.startswith('RNG Start Seed:'):
                        # this assumes a fixed width, but from what I see it seems safe
                        self.seed = line[16:25]
                        self.log_msg("Starting new run, seed: %s" % self.seed, "D")
                        self.run_start_frame = self.framecount
                        self.rolled_item_indices = []
                        self.collected_items = []
                        self.collected_guppy_items = []
                        self.collected_blind_item_indices = []
                        self.log_msg("Emptied item array", "D")
                        self.bosses = []
                        self.log_msg("Emptied boss array", "D")
                        self.run_start_line = current_line_number + self.seek
                        self.run_ended = False
                        self.reset_player_stats()
                        with open("overlay text/seed.txt", "w+") as f:
                            f.write(self.seed)

                    # entered a room, use to keep track of bosses
                    if line.startswith('Room'):
                        self.current_room = re.search('\((.*)\)', line).group(1)
                        if 'Start Room' not in line:
                            self.getting_start_items = False
                        self.log_msg("Entered room: %s" % self.current_room, "D")
                    if line.startswith('Level::Init'):
                        self.current_floor = tuple(
                            [re.search("Level::Init m_Stage (\d+), m_AltStage (\d+)", line).group(x) for x in [1, 2]])
                        # assume floors aren't cursed until we see they are
                        self.blind_floor = False
                        self.getting_start_items = True
                        floor = int(self.current_floor[0])
                        alt = self.current_floor[1]
                        # special handling for cath and chest
                        if alt == '1' and (floor == 9 or floor == 11):
                            floor += 1
                        floor_id = 'f' + str(floor)
                        self.collected_items.append(floor_id) # TODO: remove this line - items are not floors
                        self.floors.append(Floor(floor_id))
                        should_reflow = True
                    last_collected = self.collected_items[-1] if self.collected_items else None
                    if line.startswith("Curse of the Labyrinth!"):
                        # it SHOULD always begin with f (that is, it's a floor) because this line only comes right after the floor line
                        if last_collected.startswith('f'):
                            self.collected_items[-1] += 'x'
                    if line.startswith("Curse of Blind"):
                        self.floors[-1].blind = True
                        self.blind_floor = True
                    if line.startswith("Curse of the Lost!"):
                        self.floors[-1].lost = True
                    if line.startswith("Spawn co-player!"):
                        self.spawned_coop_baby = current_line_number + self.seek
                    if re.search("Added \d+ Collectibles", line):
                        self.log_msg("Reroll detected!", "D")
                        self.rolled_item_indices = [index for index, item in enumerate(self.collected_items) if item[0] != 'f']
                    if line.startswith('Adding collectible'):
                        if len(self.splitfile) > 1 and self.splitfile[current_line_number + self.seek - 1] == line:
                            self.log_msg("Skipped duplicate item line from baby presence", "D")
                            continue
                        # hacky string manip, idgaf
                        space_split = line.split(" ")
                        # string has the form "Adding collectible 105 (The D6)"
                        item_id = space_split[2]
                        if ((current_line_number + self.seek) - self.spawned_coop_baby) < (len(self.collected_items) + 10)\
                                and item_id in self.collected_items:
                            self.log_msg("Skipped duplicate item line from baby entry", "D")
                            continue
                        item_name = " ".join(space_split[3:])[1:-1]
                        self.log_msg("Picked up item. id: %s, name: %s" % (item_id, item_name), "D")
                        item_info = self.get_item_info(item_id)
                        with open("overlay text/itemInfo.txt", "w+") as f:
                            desc = self.generate_item_description(item_info)
                            f.write(item_info[ItemProperty.NAME] + ":" + desc)

                        # ignore repeated pickups of space bar items
                        if not (item_info.get(ItemProperty.SPACE) and item_id in self.collected_items):
                            self.collected_items.append(item_id)
                            self.item_message_start_time = self.framecount
                            self.item_pickup_time = self.framecount
                        else:
                            self.log_msg("Skipped adding item %s to avoid space-bar duplicate" % item_id, "D")
                        self.add_stats_for_item(item_info, item_id)
                        if self.blind_floor and not self.getting_start_items:
                            # the item we just picked up was picked up blind, so add its index here to track that fact
                            self.collected_blind_item_indices.append(len(self.collected_items) - 1)
                        should_reflow = True

                self.seek = len(self.splitfile)
                if should_reflow:
                    self.reflow()