 2fb59d39c9
			
		
	
	2fb59d39c9
	
	
	
		
			
			* Zillion: use "new" settings api and cleaning * python 3.10 typing update * don't separate assignments of item link players
		
			
				
	
	
		
			92 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import os
 | |
| from typing import BinaryIO
 | |
| import zipfile
 | |
| 
 | |
| from typing_extensions import override
 | |
| 
 | |
| import Utils
 | |
| from worlds.Files import APAutoPatchInterface
 | |
| 
 | |
| from zilliandomizer.patch import Patcher
 | |
| 
 | |
| from .gen_data import GenData
 | |
| 
 | |
| US_HASH = "d4bf9e7bcf9a48da53785d2ae7bc4270"
 | |
| 
 | |
| 
 | |
| class ZillionPatch(APAutoPatchInterface):
 | |
|     hash = US_HASH
 | |
|     game = "Zillion"
 | |
|     patch_file_ending = ".apzl"
 | |
|     result_file_ending = ".sms"
 | |
| 
 | |
|     gen_data_str: str
 | |
|     """ JSON encoded """
 | |
| 
 | |
|     def __init__(self,
 | |
|                  path: str | None = None,
 | |
|                  player: int | None = None,
 | |
|                  player_name: str = "",
 | |
|                  server: str = "",
 | |
|                  *,
 | |
|                  gen_data_str: str = "") -> None:
 | |
|         super().__init__(path=path, player=player, player_name=player_name, server=server)
 | |
|         self.gen_data_str = gen_data_str
 | |
| 
 | |
|     @classmethod
 | |
|     def get_source_data(cls) -> bytes:
 | |
|         with open(get_base_rom_path(), "rb") as stream:
 | |
|             return read_rom(stream)
 | |
| 
 | |
|     @override
 | |
|     def write_contents(self, opened_zipfile: zipfile.ZipFile) -> None:
 | |
|         super().write_contents(opened_zipfile)
 | |
|         opened_zipfile.writestr("gen_data.json",
 | |
|                                 self.gen_data_str,
 | |
|                                 compress_type=zipfile.ZIP_DEFLATED)
 | |
| 
 | |
|     @override
 | |
|     def read_contents(self, opened_zipfile: zipfile.ZipFile) -> None:
 | |
|         super().read_contents(opened_zipfile)
 | |
|         self.gen_data_str = opened_zipfile.read("gen_data.json").decode()
 | |
| 
 | |
|     @override
 | |
|     def patch(self, target: str) -> None:
 | |
|         self.read()
 | |
|         write_rom_from_gen_data(self.gen_data_str, target)
 | |
| 
 | |
| 
 | |
| def get_base_rom_path(file_name: str | None = None) -> str:
 | |
|     from . import ZillionSettings, ZillionWorld
 | |
|     settings: ZillionSettings = ZillionWorld.settings
 | |
|     if not file_name:
 | |
|         file_name = settings.rom_file
 | |
|     if not os.path.exists(file_name):
 | |
|         file_name = Utils.user_path(file_name)
 | |
|     return file_name
 | |
| 
 | |
| 
 | |
| def read_rom(stream: BinaryIO) -> bytes:
 | |
|     """ reads rom into bytearray """
 | |
|     data = stream.read()
 | |
|     # I'm not aware of any sms header.
 | |
|     return data
 | |
| 
 | |
| 
 | |
| def write_rom_from_gen_data(gen_data_str: str, output_rom_file_name: str) -> None:
 | |
|     """ take the output of `GenData.to_json`, and create rom from it """
 | |
|     gen_data = GenData.from_json(gen_data_str)
 | |
| 
 | |
|     base_rom_path = get_base_rom_path()
 | |
|     zz_patcher = Patcher(base_rom_path)
 | |
| 
 | |
|     zz_patcher.write_locations(gen_data.zz_game.regions, gen_data.zz_game.char_order[0])
 | |
|     zz_patcher.all_fixes_and_options(gen_data.zz_game)
 | |
|     zz_patcher.set_external_item_interface(gen_data.zz_game.char_order[0], gen_data.zz_game.options.max_level)
 | |
|     zz_patcher.set_multiworld_items(gen_data.multi_items)
 | |
|     zz_patcher.set_rom_to_ram_data(gen_data.game_id)
 | |
| 
 | |
|     patched_rom_bytes = zz_patcher.get_patched_bytes()
 | |
|     with open(output_rom_file_name, "wb") as binary_file:
 | |
|         binary_file.write(patched_rom_bytes)
 |