From 93395708cc47242b39e2f01216db75168691e5e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20K=C3=B6pcke?= Date: Mon, 22 Feb 2021 19:49:50 +0100 Subject: [PATCH] Closes #29: Add seed information to top title screen --- skytemple_randomizer/config.py | 20 +++++++ skytemple_randomizer/main.py | 23 +------- skytemple_randomizer/randomizer/abstract.py | 3 +- skytemple_randomizer/randomizer/dungeon.py | 4 +- skytemple_randomizer/randomizer/fixed_room.py | 6 +-- .../randomizer/global_items.py | 4 +- .../randomizer/overworld_music.py | 4 +- skytemple_randomizer/randomizer/seed_info.py | 54 +++++++++++++++++++ skytemple_randomizer/randomizer_thread.py | 7 +-- 9 files changed, 91 insertions(+), 34 deletions(-) create mode 100644 skytemple_randomizer/randomizer/seed_info.py diff --git a/skytemple_randomizer/config.py b/skytemple_randomizer/config.py index 1299e3b64..657203608 100644 --- a/skytemple_randomizer/config.py +++ b/skytemple_randomizer/config.py @@ -16,12 +16,14 @@ # You should have received a copy of the GNU General Public License # along with SkyTemple. If not, see . import json +import os import sys import time from enum import Enum from functools import partial from typing import TypedDict, Optional, List, Dict +import pkg_resources from gi.repository import Gtk from skytemple_files.common.ppmdu_config.dungeon_data import Pmd2DungeonDungeon @@ -464,3 +466,21 @@ def default(self, obj): if isinstance(obj, Enum): return obj.value return json.JSONEncoder.default(self, obj) + + +def version(): + try: + return pkg_resources.get_distribution("skytemple-randomizer").version + except pkg_resources.DistributionNotFound: + # Try reading from a VERISON file instead + version_file = os.path.join(data_dir(), 'VERSION') + if os.path.exists(version_file): + with open(version_file) as f: + return f.read() + return 'unknown' + + +def data_dir(): + if getattr(sys, 'frozen', False): + return os.path.join(os.path.dirname(sys.executable), 'data') + return os.path.join(os.path.dirname(__file__), 'data') diff --git a/skytemple_randomizer/main.py b/skytemple_randomizer/main.py index dac464507..66e46092d 100644 --- a/skytemple_randomizer/main.py +++ b/skytemple_randomizer/main.py @@ -31,14 +31,13 @@ gi.require_version('Gtk', '3.0') -import pkg_resources from ndspy.rom import NintendoDSRom from skytemple_files.common.ppmdu_config.xml_reader import Pmd2XmlReader from skytemple_files.common.util import open_utf8 from skytemple_icons import icons from skytemple_randomizer.config import ConfigUIApplier, ConfigUIReader, ConfigFileLoader, EnumJsonEncoder, \ - get_effective_seed, ConfigDocApplier + get_effective_seed, ConfigDocApplier, version, data_dir from skytemple_randomizer.randomizer_thread import RandomizerThread from skytemple_randomizer.status import Status @@ -255,7 +254,7 @@ def check_done(): seed = get_effective_seed(config['seed']) random.seed(seed) self.builder.get_object('seed_label').set_text('Your Seed: ' + str(seed)) - randomizer = RandomizerThread(status, rom, config) + randomizer = RandomizerThread(status, rom, config, seed) randomizer.start() # SHOW DIALOG @@ -339,29 +338,11 @@ def main(): Gtk.main() -def data_dir(): - if getattr(sys, 'frozen', False): - return os.path.join(os.path.dirname(sys.executable), 'data') - return os.path.join(os.path.dirname(__file__), 'data') - - def _load_theme(): settings = Gtk.Settings.get_default() settings.set_property("gtk-theme-name", 'Arc-Dark') -def version(): - try: - return pkg_resources.get_distribution("skytemple-randomizer").version - except pkg_resources.DistributionNotFound: - # Try reading from a VERISON file instead - version_file = os.path.join(data_dir(), 'VERSION') - if os.path.exists(version_file): - with open(version_file) as f: - return f.read() - return 'unknown' - - if __name__ == '__main__': # TODO: At the moment doesn't support any cli arguments. logging.basicConfig() diff --git a/skytemple_randomizer/randomizer/abstract.py b/skytemple_randomizer/randomizer/abstract.py index 82e470d49..06ac827d3 100644 --- a/skytemple_randomizer/randomizer/abstract.py +++ b/skytemple_randomizer/randomizer/abstract.py @@ -24,10 +24,11 @@ class AbstractRandomizer(ABC): - def __init__(self, config: RandomizerConfig, rom: NintendoDSRom, static_data: Pmd2Data): + def __init__(self, config: RandomizerConfig, rom: NintendoDSRom, static_data: Pmd2Data, seed: str): self.config = config self.rom = rom self.static_data = static_data + self.seed = seed @abstractmethod def step_count(self) -> int: diff --git a/skytemple_randomizer/randomizer/dungeon.py b/skytemple_randomizer/randomizer/dungeon.py index 3345f22db..54f0e1943 100644 --- a/skytemple_randomizer/randomizer/dungeon.py +++ b/skytemple_randomizer/randomizer/dungeon.py @@ -225,8 +225,8 @@ class DungeonRandomizer(AbstractRandomizer): - def __init__(self, config: RandomizerConfig, rom: NintendoDSRom, static_data: Pmd2Data): - super().__init__(config, rom, static_data) + def __init__(self, config: RandomizerConfig, rom: NintendoDSRom, static_data: Pmd2Data, seed: str): + super().__init__(config, rom, static_data, seed) self.dungeons = HardcodedDungeons.get_dungeon_list( get_binary_from_rom_ppmdu(self.rom, self.static_data.binaries['arm9.bin']), diff --git a/skytemple_randomizer/randomizer/fixed_room.py b/skytemple_randomizer/randomizer/fixed_room.py index 6f168e079..7f71c0cf0 100644 --- a/skytemple_randomizer/randomizer/fixed_room.py +++ b/skytemple_randomizer/randomizer/fixed_room.py @@ -41,8 +41,8 @@ class FixedRoomRandomizer(AbstractRandomizer): - def __init__(self, config: RandomizerConfig, rom: NintendoDSRom, static_data: Pmd2Data): - super().__init__(config, rom, static_data) + def __init__(self, config: RandomizerConfig, rom: NintendoDSRom, static_data: Pmd2Data, seed: str): + super().__init__(config, rom, static_data, seed) self.dungeons = HardcodedDungeons.get_dungeon_list( get_binary_from_rom_ppmdu(self.rom, self.static_data.binaries['arm9.bin']), @@ -127,7 +127,7 @@ def _get_random_room(self, entities_and_special_tiles_to_preserve: List[FixedFlo return width, height, actions def _get_random_room_txt(self): - from skytemple_randomizer.main import data_dir + from skytemple_randomizer.config import data_dir i = randrange(0, 1000) with open_utf8(os.path.join(data_dir(), 'fixed_floor_layouts', f'{i}.txt')) as f: return f.read().splitlines() diff --git a/skytemple_randomizer/randomizer/global_items.py b/skytemple_randomizer/randomizer/global_items.py index 04febf28c..731043fbd 100644 --- a/skytemple_randomizer/randomizer/global_items.py +++ b/skytemple_randomizer/randomizer/global_items.py @@ -50,8 +50,8 @@ class GlobalItemsRandomizer(AbstractRandomizer): - def __init__(self, config: RandomizerConfig, rom: NintendoDSRom, static_data: Pmd2Data): - super().__init__(config, rom, static_data) + def __init__(self, config: RandomizerConfig, rom: NintendoDSRom, static_data: Pmd2Data, seed: str): + super().__init__(config, rom, static_data, seed) def step_count(self) -> int: return 2 if self.config['starters_npcs']['global_items'] else 0 diff --git a/skytemple_randomizer/randomizer/overworld_music.py b/skytemple_randomizer/randomizer/overworld_music.py index 1aec5ca9a..d59414432 100644 --- a/skytemple_randomizer/randomizer/overworld_music.py +++ b/skytemple_randomizer/randomizer/overworld_music.py @@ -24,8 +24,8 @@ class OverworldMusicRandomizer(AbstractRandomizer): - def __init__(self, config, rom, static_data): - super().__init__(config, rom, static_data) + def __init__(self, config, rom, static_data, seed): + super().__init__(config, rom, static_data, seed) self.bgs = [b for b in self.static_data.script_data.bgms if b.loops] def step_count(self) -> int: diff --git a/skytemple_randomizer/randomizer/seed_info.py b/skytemple_randomizer/randomizer/seed_info.py new file mode 100644 index 000000000..0b48fd25b --- /dev/null +++ b/skytemple_randomizer/randomizer/seed_info.py @@ -0,0 +1,54 @@ +# Copyright 2020-2021 Parakoopa and the SkyTemple Contributors +# +# This file is part of SkyTemple. +# +# SkyTemple is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SkyTemple is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SkyTemple. If not, see . +from skytemple_files.common.ppmdu_config.data import GAME_REGION_US +from skytemple_files.common.types.file_types import FileType +from skytemple_randomizer.config import version +from skytemple_randomizer.randomizer.abstract import AbstractRandomizer +from skytemple_randomizer.randomizer.util.util import get_all_string_files +from skytemple_randomizer.status import Status + +STR_EU = 16330 +STR_US = 16328 + + +class SeedInfo(AbstractRandomizer): + def step_count(self) -> int: + return 1 + + def run(self, status: Status): + status.step("Loading Seed Info...") + + langs = list(get_all_string_files(self.rom, self.static_data)) + str_offset = STR_EU + if self.static_data.game_region == GAME_REGION_US: + str_offset = STR_US + + for lang, string_file in langs: + string_file.strings[str_offset] = f"""Randomized with SkyTemple Randomizer. +Version:[CS:Z]{version()}[CR] +Seed: [CS:C]{self.seed}[CR] + +[CS:H]PLEASE NOTE:[CR] +This seed will only produce the same output +when used with the exact same version +and configuration of the randomizer that +was used.""" + + for lang, string_file in langs: + self.rom.setFileByName(f'MESSAGE/{lang.filename}', FileType.STR.serialize(string_file)) + + status.done() diff --git a/skytemple_randomizer/randomizer_thread.py b/skytemple_randomizer/randomizer_thread.py index 4b69e4226..db78a3eb8 100644 --- a/skytemple_randomizer/randomizer_thread.py +++ b/skytemple_randomizer/randomizer_thread.py @@ -37,6 +37,7 @@ from skytemple_randomizer.randomizer.patch_applier import PatchApplier from skytemple_randomizer.randomizer.portrait_downloader import PortraitDownloader from skytemple_randomizer.randomizer.recruitment_table import RecruitmentTableRandomizer +from skytemple_randomizer.randomizer.seed_info import SeedInfo from skytemple_randomizer.randomizer.starter import StarterRandomizer from skytemple_randomizer.randomizer.text_main import TextMainRandomizer from skytemple_randomizer.randomizer.text_script import TextScriptRandomizer @@ -48,13 +49,13 @@ PatchApplier, NpcRandomizer, StarterRandomizer, BossRandomizer, RecruitmentTableRandomizer, DungeonRandomizer, FixedRoomRandomizer, DungeonUnlocker, PortraitDownloader, MonsterRandomizer, MovesetRandomizer, LocationRandomizer, ChapterRandomizer, TextMainRandomizer, TextScriptRandomizer, GlobalItemsRandomizer, - OverworldMusicRandomizer + OverworldMusicRandomizer, SeedInfo ] logger = logging.getLogger(__name__) class RandomizerThread(Thread): - def __init__(self, status: Status, rom: NintendoDSRom, config: RandomizerConfig): + def __init__(self, status: Status, rom: NintendoDSRom, config: RandomizerConfig, seed: str): """ Inits the thread. If it's started() access to rom and config MUST NOT be done until is_done(). is_done is also signaled by the status object's done() event. @@ -71,7 +72,7 @@ def __init__(self, status: Status, rom: NintendoDSRom, config: RandomizerConfig) self.static_data = get_ppmdu_config_for_rom(rom) self.randomizers: List[AbstractRandomizer] = [] for cls in RANDOMIZERS: - self.randomizers.append(cls(config, rom, self.static_data)) + self.randomizers.append(cls(config, rom, self.static_data, seed)) self.total_steps = sum(x.step_count() for x in self.randomizers) + 1 self.error = None