v30 updates

This commit is contained in:
Kevin Cathcart 2018-09-22 22:51:54 -04:00
parent b259c10d27
commit 5539143f00
10 changed files with 93 additions and 85 deletions

View File

@ -45,7 +45,7 @@ class World(object):
self.aga_randomness = True
self.lock_aga_door_in_escape = False
self.fix_trock_doors = self.shuffle != 'vanilla'
self.save_and_quit_from_boss = False
self.save_and_quit_from_boss = True
self.check_beatable_only = check_beatable_only
self.fix_skullwoods_exit = self.shuffle not in ['vanilla', 'simple', 'restricted', 'dungeonssimple']
self.fix_palaceofdarkness_exit = self.shuffle not in ['vanilla', 'simple', 'restricted', 'dungeonssimple']
@ -456,6 +456,16 @@ class CollectionState(object):
return self.has('Bow') and (self.has('Silver Arrows') or self.can_buy_unlimited('Single Arrow'))
return self.has('Bow')
def can_get_good_bee(self):
cave = self.world.get_region('Good Bee Cave')
return (
self.has_bottle() and
self.has('Bug Catching Net') and
(self.has_Boots() or (self.has_sword() and self.has('Quake'))) and
cave.can_reach(self) and
(cave.is_light_world or self.has_Pearl())
)
def has_sword(self):
return self.has('Fighter Sword') or self.has('Master Sword') or self.has('Tempered Sword') or self.has('Golden Sword')
@ -775,6 +785,7 @@ class Crystal(Item):
class ShopType(Enum):
Shop = 0
TakeAny = 1
UpgradeShop = 2
class Shop(object):
def __init__(self, region, room_id, type, shopkeeper_config, replaceable):
@ -804,6 +815,8 @@ class Shop(object):
config |= 0x40 # ignore door id
if self.type == ShopType.TakeAny:
config |= 0x80
if self.type == ShopType.UpgradeShop:
config |= 0x10 # Alt. VRAM
return [0x00]+int16_as_bytes(self.room_id)+[door_id, 0x00, config, self.shopkeeper_config, 0x00]
def has_unlimited(self, item):

2
Gui.py
View File

@ -1114,7 +1114,7 @@ class SpriteSelector(object):
try:
task.update_status("Downloading official sprites list")
with urlopen('http://vt.alttp.run/sprites') as response:
with urlopen('https://alttpr.com/sprites') as response:
sprites_arr = json.loads(response.read().decode("utf-8"))
except Exception as e:
resultmessage = "Error getting list of official sprites. Sprites not updated.\n\n%s: %s" % (type(e).__name__, e)

View File

@ -20,9 +20,9 @@ basicgloves = ['Power Glove', 'Titans Mitts']
normalbottles = ['Bottle', 'Bottle (Red Potion)', 'Bottle (Green Potion)', 'Bottle (Blue Potion)', 'Bottle (Fairy)', 'Bottle (Bee)', 'Bottle (Good Bee)']
hardbottles = ['Bottle', 'Bottle (Red Potion)', 'Bottle (Green Potion)', 'Bottle (Blue Potion)', 'Bottle (Bee)', 'Bottle (Good Bee)']
normalbaseitems = (['Silver Arrows', 'Magic Upgrade (1/2)', 'Single Arrow', 'Sanctuary Heart Container', 'Arrow Upgrade (+10)', 'Bomb Upgrade (+10)'] +
normalbaseitems = (['Silver Arrows', 'Magic Upgrade (1/2)', 'Single Arrow', 'Sanctuary Heart Container', 'Arrows (10)', 'Bombs (3)'] +
['Rupees (300)'] * 4 + ['Boss Heart Container'] * 10 + ['Piece of Heart'] * 24)
normalfirst15extra = ['Rupees (100)', 'Rupees (300)', 'Rupees (50)'] + ['Arrow Upgrade (+5)'] * 6 + ['Bomb Upgrade (+5)'] * 6
normalfirst15extra = ['Rupees (100)', 'Rupees (300)', 'Rupees (50)'] + ['Arrows (10)'] * 6 + ['Bombs (3)'] * 6
normalsecond15extra = ['Bombs (3)'] * 9 + ['Rupees (50)'] * 2 + ['Arrows (10)'] * 2 + ['Rupee (1)'] + ['Bombs (10)']
normalthird10extra = ['Rupees (50)'] * 4 + ['Rupees (20)'] * 3 + ['Arrows (10)', 'Rupee (1)', 'Rupees (5)']
normalfourth5extra = ['Arrows (10)'] * 2 + ['Rupees (20)'] * 2 + ['Rupees (5)']
@ -33,7 +33,7 @@ easybaseitems = (['Sanctuary Heart Container'] + ['Rupees (300)'] * 4 + ['Magic
['Boss Heart Container'] * 10 + ['Piece of Heart'] * 12)
easyextra = ['Piece of Heart'] * 12 + ['Rupees (300)']
easylimitedextra = ['Boss Heart Container'] * 3 # collapsing down the 12 pieces of heart
easyfirst15extra = ['Rupees (100)', 'Arrow Upgrade (+10)', 'Bomb Upgrade (+10)'] + ['Arrow Upgrade (+5)'] * 6 + ['Bomb Upgrade (+5)'] * 6
easyfirst15extra = ['Rupees (100)'] + ['Arrows (10)'] * 7 + ['Bombs (3)'] * 7
easysecond10extra = ['Bombs (3)'] * 7 + ['Rupee (1)', 'Rupees (50)', 'Bombs (10)']
easythird5extra = ['Rupees (50)'] * 2 + ['Bombs (3)'] * 2 + ['Arrows (10)']
easyfinal25extra = ['Rupees (50)'] * 4 + ['Rupees (20)'] * 14 + ['Rupee (1)'] + ['Arrows (10)'] * 4 + ['Rupees (5)'] * 2

View File

@ -6,7 +6,7 @@ import logging
import random
import time
from BaseClasses import World, CollectionState, Item, Region, Location, Entrance, Shop
from BaseClasses import World, CollectionState, Item, Region, Location, Shop
from Regions import create_regions, mark_light_world_regions
from EntranceShuffle import link_entrances
from Rom import patch_rom, Sprite, LocalRom, JsonRom

View File

@ -1,7 +1,7 @@
# ALttPEntranceRandomizer
This is a entrance randomizer for _The Legend of Zelda: A Link to the Past_ for the SNES.
See http://vt.alttp.run for more details on the normal randomizer.
See https://alttpr.com/ for more details on the normal randomizer.
# Installation

View File

@ -299,6 +299,10 @@ def create_regions(world):
for index, (item, price) in enumerate(default_shop_contents[region_name]):
shop.add_inventory(index, item, price)
region = world.get_region('Capacity Upgrade')
shop = Shop(region, 0x0115, ShopType.UpgradeShop, 0x04, True)
shop.add_inventory(0, 'Bomb Upgrade (+5)', 100, 7)
shop.add_inventory(1, 'Arrow Upgrade (+5)', 100, 7)
world.intialize_regions()
def create_lw_region(name, locations=None, exits=None):
@ -358,15 +362,15 @@ def mark_light_world_regions(world):
# (room_id, shopkeeper, replaceable)
shop_table = {
'Cave Shop (Dark Death Mountain)': (0x0112, 0x51, True),
'Red Shield Shop': (0x0110, 0x51, True),
'Dark Lake Hylia Shop': (0x010F, 0x51, True),
'Dark World Lumberjack Shop': (0x010F, 0x51, True),
'Village of Outcasts Shop': (0x010F, 0x51, True),
'Dark World Potion Shop': (0x010F, 0x51, True),
'Light World Death Mountain Shop': (0x00FF, 0x51, True),
'Kakariko Shop': (0x011F, 0x51, True),
'Cave Shop (Lake Hylia)': (0x0112, 0x51, True),
'Cave Shop (Dark Death Mountain)': (0x0112, 0xC1, True),
'Red Shield Shop': (0x0110, 0xC1, True),
'Dark Lake Hylia Shop': (0x010F, 0xC1, True),
'Dark World Lumberjack Shop': (0x010F, 0xC1, True),
'Village of Outcasts Shop': (0x010F, 0xC1, True),
'Dark World Potion Shop': (0x010F, 0xC1, True),
'Light World Death Mountain Shop': (0x00FF, 0xA0, True),
'Kakariko Shop': (0x011F, 0xA0, True),
'Cave Shop (Lake Hylia)': (0x0112, 0xA0, True),
'Potion Shop': (0x0109, 0xFF, False),
# Bomb Shop not currently modeled as a shop, due to special nature of items
}

101
Rom.py
View File

@ -9,7 +9,7 @@ import random
from BaseClasses import ShopType
from Dungeons import dungeon_music_addresses
from Text import MultiByteTextMapper, text_addresses, Credits, TextTable
from Text import Uncle_texts, Ganon1_texts, PyramidFairy_texts, TavernMan_texts, Sahasrahla2_texts, Triforce_texts, Blind_texts, BombShop2_texts
from Text import Uncle_texts, Ganon1_texts, TavernMan_texts, Sahasrahla2_texts, Triforce_texts, Blind_texts, BombShop2_texts
from Text import KingsReturn_texts, Sanctuary_texts, Kakariko_texts, Blacksmiths_texts, DeathMountain_texts, LostWoods_texts, WishingWell_texts, DesertPalace_texts, MountainTower_texts, LinksHouse_texts, Lumberjacks_texts, SickKid_texts, FluteBoy_texts, Zora_texts, MagicShop_texts, Sahasrahla_names
from Utils import local_path, int16_as_bytes, int32_as_bytes
from Items import ItemFactory
@ -42,6 +42,12 @@ class JsonRom(object):
with open(file, 'w') as stream:
json.dump([self.patches], stream)
def get_hash(self):
h = hashlib.md5()
h.update(json.dumps([self.patches]).encode('utf-8'))
return h.hexdigest()
class LocalRom(object):
@ -97,6 +103,11 @@ class LocalRom(object):
inv = crc ^ 0xFFFF
self.write_bytes(0x7FDC, [inv & 0xFF, (inv >> 8) & 0xFF, crc & 0xFF, (crc >> 8) & 0xFF])
def get_hash(self):
h = hashlib.md5()
h.update(self.buffer)
return h.hexdigest()
def read_rom(stream):
"Reads rom into bytearray and strips off any smc header"
buffer = bytearray(stream.read())
@ -422,24 +433,6 @@ def patch_rom(world, rom, hashtable, beep='normal', color='red', sprite=None):
rom.write_byte(0x180180, 0x02) # Hookshot only
# Make silver arrows only usable against Ganon
rom.write_byte(0x180181, 0x01)
#Make Blue Shield more expensive
rom.write_bytes(0xF73D2, [0xFC, 0xFF])
rom.write_bytes(0xF73DA, [0x04, 0x00])
rom.write_bytes(0xF73E2, [0x0C, 0x00])
rom.write_byte(0xF73D6, 0x31)
rom.write_byte(0xF73DE, 0x30)
rom.write_byte(0xF73E6, 0x30)
rom.write_byte(0xF7201, 0x00)
rom.write_byte(0xF71FF, 0x64)
#Make Red Shield more expensive
rom.write_bytes(0xF73FA, [0xFC, 0xFF])
rom.write_bytes(0xF7402, [0x04, 0x00])
rom.write_bytes(0xF740A, [0x0C, 0x00])
rom.write_byte(0xF73FE, 0x33)
rom.write_byte(0xF7406, 0x33)
rom.write_byte(0xF740E, 0x33)
rom.write_byte(0xF7241, 0x03)
rom.write_byte(0xF723F, 0xE7)
elif world.difficulty == 'expert':
# Powdered Fairies Prize
rom.write_byte(0x36DD0, 0xD8) # One Heart
@ -460,24 +453,6 @@ def patch_rom(world, rom, hashtable, beep='normal', color='red', sprite=None):
rom.write_byte(0x180180, 0x00) # Nothing
# Make silver arrows only usable against Ganon
rom.write_byte(0x180181, 0x01)
#Make Blue Shield more expensive
rom.write_bytes(0xF73D2, [0xFC, 0xFF])
rom.write_bytes(0xF73DA, [0x04, 0x00])
rom.write_bytes(0xF73E2, [0x0C, 0x00])
rom.write_byte(0xF73D6, 0x3C)
rom.write_byte(0xF73DE, 0x3C)
rom.write_byte(0xF73E6, 0x3C)
rom.write_byte(0xF7201, 0x27)
rom.write_byte(0xF71FF, 0x06)
#Make Red Shield more expensive
rom.write_bytes(0xF73FA, [0xFC, 0xFF])
rom.write_bytes(0xF7402, [0x04, 0x00])
rom.write_bytes(0xF740A, [0x0C, 0x00])
rom.write_byte(0xF73FE, 0x3C)
rom.write_byte(0xF7406, 0x3C)
rom.write_byte(0xF740E, 0x3C)
rom.write_byte(0xF7241, 0x27)
rom.write_byte(0xF723F, 0x06)
elif world.difficulty == 'insane':
# Powdered Fairies Prize
rom.write_byte(0x36DD0, 0x79) # Bees
@ -498,24 +473,6 @@ def patch_rom(world, rom, hashtable, beep='normal', color='red', sprite=None):
rom.write_byte(0x180180, 0x00) # Nothing
# Make silver arrows only usable against Ganon
rom.write_byte(0x180181, 0x01)
#Make Blue Shield more expensive
rom.write_bytes(0xF73D2, [0xFC, 0xFF])
rom.write_bytes(0xF73DA, [0x04, 0x00])
rom.write_bytes(0xF73E2, [0x0C, 0x00])
rom.write_byte(0xF73D6, 0x3C)
rom.write_byte(0xF73DE, 0x3C)
rom.write_byte(0xF73E6, 0x3C)
rom.write_byte(0xF7201, 0x27)
rom.write_byte(0xF71FF, 0x10)
#Make Red Shield more expensive
rom.write_bytes(0xF73FA, [0xFC, 0xFF])
rom.write_bytes(0xF7402, [0x04, 0x00])
rom.write_bytes(0xF740A, [0x0C, 0x00])
rom.write_byte(0xF73FE, 0x3C)
rom.write_byte(0xF7406, 0x3C)
rom.write_byte(0xF740E, 0x3C)
rom.write_byte(0xF7241, 0x27)
rom.write_byte(0xF723F, 0x10)
else:
# Powdered Fairies Prize
rom.write_byte(0x36DD0, 0xE3) # fairy
@ -543,7 +500,7 @@ def patch_rom(world, rom, hashtable, beep='normal', color='red', sprite=None):
if world.difficulty in ['easy']:
rom.write_byte(0x180182, 0x03) # auto equip silvers on pickup and at ganon
elif world.retro and world.difficulty in ['hard','expert', 'insane']: #FIXME: this is temporary for v29 baserom
elif world.retro and world.difficulty in ['hard', 'expert', 'insane']: #FIXME: this is temporary for v29 baserom (perhaps no so temporary?)
rom.write_byte(0x180182, 0x03) # auto equip silvers on pickup and at ganon
else:
rom.write_byte(0x180182, 0x01) # auto equip silvers on pickup
@ -574,6 +531,12 @@ def patch_rom(world, rom, hashtable, beep='normal', color='red', sprite=None):
0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2,
0xE3, 0xE3, 0xE3, 0xE3, 0xE3]
if world.difficulty in ['hard', 'expert', 'insane']:
prize_replacements = {0xE0: 0xDF, # Fairy -> heart
0xE3: 0xD8} # Big magic -> small magic
prizes = [prize_replacements.get(prize, prize) for prize in prizes]
dig_prizes = [prize_replacements.get(prize, prize) for prize in dig_prizes]
if world.retro:
prize_replacements = {0xE1: 0xDA, #5 Arrows -> Blue Rupee
0xE2: 0xDB} #10 Arrows -> Red Rupee
@ -640,12 +603,16 @@ def patch_rom(world, rom, hashtable, beep='normal', color='red', sprite=None):
# original_item, limit, replacement_item, filler
0x12, 0x01, 0x35, 0xFF, # lamp -> 5 rupees
0x58, 0x01, 0x43, 0xFF, # silver arrows -> 1 arrow
0x51, 0x06, 0x52, 0xFF, # 6 +5 bomb upgrades -> +10 bomb upgrade
0x53, 0x06, 0x54, 0xFF, # 6 +5 arrow upgrades -> +10 arrow upgrade
0xFF, 0xFF, 0xFF, 0xFF, # end of table sentinel
])
else:
rom.write_bytes(0x184000, [
# original_item, limit, replacement_item, filler
0x12, 0x01, 0x35, 0xFF, # lamp -> 5 rupees
0x51, 0x06, 0x52, 0xFF, # 6 +5 bomb upgrades -> +10 bomb upgrade
0x53, 0x06, 0x54, 0xFF, # 6 +5 arrow upgrades -> +10 arrow upgrade
0xFF, 0xFF, 0xFF, 0xFF, # end of table sentinel
])
@ -676,6 +643,10 @@ def patch_rom(world, rom, hashtable, beep='normal', color='red', sprite=None):
rom.write_byte(0x348DB, 0x3A) # Red Boomerang becomes Red Boomerang
rom.write_byte(0x348EB, 0x05) # Blue Shield becomes Blue Shield
# Remove Statues for upgrade fairy
rom.write_bytes(0x01F810, [0x1A, 0x1E, 0x01, 0x1A, 0x1E, 0x01])
rom.write_byte(0x180029, 0x01) # Smithy quick item give
# set swordless mode settings
@ -740,7 +711,6 @@ def patch_rom(world, rom, hashtable, beep='normal', color='red', sprite=None):
rom.write_byte(0x180211, 0x06) #Game type, we set the Entrance and item randomization flags
# assorted fixes
rom.write_byte(0x180030, 0x00) # Disable SRAM trace
rom.write_byte(0x1800A2, 0x01) # remain in real dark world when dying in dark word dungion before killing aga1
rom.write_byte(0x180169, 0x01 if world.lock_aga_door_in_escape else 0x00) # Lock or unlock aga tower door during escape sequence.
rom.write_byte(0x180171, 0x01 if world.ganon_at_pyramid else 0x00) # Enable respawning on pyramid after ganon death
@ -766,11 +736,14 @@ def patch_rom(world, rom, hashtable, beep='normal', color='red', sprite=None):
rom.write_byte(0x18302D, 0x18) # starting current health
rom.write_byte(0x183039, 0x68) # starting abilities, bit array
rom.write_byte(0x18004A, 0x00) # Inverted mode (off)
rom.write_byte(0x18005D, 0x00) # Hammer always breaks barrier
rom.write_byte(0x2AF79, 0xD0) # vortexes: Normal (D0=light to dark, F0=dark to light, 42 = both)
rom.write_byte(0x3A943, 0xD0) # Mirror: Normal (D0=Dark to Light, F0=light to dark, 42 = both)
rom.write_byte(0x3A96D, 0xF0) # Residual Portal: Normal (F0= Light Side, D0=Dark Side, 42 = both (Darth Vader))
rom.write_byte(0x3A9A7, 0xD0) # Residual Portal: Normal (D0= Light Side, F0=Dark Side, 42 = both (Darth Vader))
rom.write_bytes(0x180080, [50, 50, 70, 70]) # values to fill for Capacity Upgrades (Bomb5, Bomb10, Arrow5, Arrow10)
rom.write_byte(0x18004D, 0x00) # Escape assist (off)
rom.write_byte(0x18004E, 0x00) # escape fills
rom.write_int16_to_rom(0x180183, 0) # rupee fill (for bow if rupee arrows enabled)
@ -815,6 +788,7 @@ def patch_rom(world, rom, hashtable, beep='normal', color='red', sprite=None):
rom.write_byte(0x180020, digging_game_rng)
rom.write_byte(0xEFD95, digging_game_rng)
rom.write_byte(0x1800A3, 0x01) # enable correct world setting behaviour after agahnim kills
rom.write_byte(0x1800A4, 0x01 if world.logic != 'nologic' else 0x00) # enable POD EG fix
rom.write_byte(0x180042, 0x01 if world.save_and_quit_from_boss else 0x00) # Allow Save and Quit after boss kill
# remove shield from uncle
@ -859,8 +833,16 @@ def patch_rom(world, rom, hashtable, beep='normal', color='red', sprite=None):
# 21 bytes
rom.write_bytes(0x7FC0, bytearray('ER_060_%09d\0' % world.seed, 'utf8') + world.option_identifier.to_bytes(4, 'big'))
# store hash table for main menu hash
rom.write_bytes(0x187F00, hashtable)
# Write title screen Code
hashint = int(rom.get_hash(), 16)
code = [
(hashint >> 20) & 0x1F,
(hashint >> 15) & 0x1F,
(hashint >> 10) & 0x1F,
(hashint >> 5) & 0x1F,
hashint & 0x1F,
]
rom.write_bytes(0x180215, code)
apply_rom_settings(rom, beep, color, world.quickswap, world.fastmenu, world.disable_music, sprite)
@ -1047,7 +1029,6 @@ def write_strings(rom, world):
tt['uncle_leaving_text'] = Uncle_texts[random.randint(0, len(Uncle_texts) - 1)]
tt['end_triforce'] = "{NOBORDER}\n" + Triforce_texts[random.randint(0, len(Triforce_texts) - 1)]
tt['bomb_shop_big_bomb'] = BombShop2_texts[random.randint(0, len(BombShop2_texts) - 1)]
tt['pond_will_upgrade'] = PyramidFairy_texts[random.randint(0, len(PyramidFairy_texts) - 1)]
# this is what shows after getting the green pendant item in rando
tt['sahasrahla_quest_have_master_sword'] = Sahasrahla2_texts[random.randint(0, len(Sahasrahla2_texts) - 1)]

View File

@ -294,6 +294,7 @@ def global_rules(world):
set_rule(world.get_entrance('Ice Palace Entrance Room'), lambda state: state.has('Fire Rod') or (state.has('Bombos') and state.has_sword()))
set_rule(world.get_location('Ice Palace - Big Chest'), lambda state: state.has('Big Key (Ice Palace)'))
set_rule(world.get_entrance('Ice Palace (Kholdstare)'), lambda state: state.can_lift_rocks() and state.has('Hammer') and state.has('Big Key (Ice Palace)') and (state.has_key('Small Key (Ice Palace)', 2) or (state.has('Cane of Somaria') and state.has_key('Small Key (Ice Palace)', 1))))
# TODO: investigate change from VT. Changed to hookshot or 2 keys (no checking for big key in specific chests)
set_rule(world.get_entrance('Ice Palace (East)'), lambda state: (state.has('Hookshot') or (item_in_locations(state, 'Big Key (Ice Palace)', ['Ice Palace - Spike Room', 'Ice Palace - Big Key Chest', 'Ice Palace - Map Chest']) and state.has_key('Small Key (Ice Palace)'))) and (state.world.can_take_damage or state.has('Hookshot') or state.has('Cape') or state.has('Cane of Byrna')))
set_rule(world.get_entrance('Ice Palace (East Top)'), lambda state: state.can_lift_rocks() and state.has('Hammer'))
for location in ['Ice Palace - Big Chest', 'Ice Palace - Kholdstare']:

17
Text.py
View File

@ -108,7 +108,6 @@ Triforce_texts = [
" Pick us up\n before we\n get dizzy!",
]
BombShop2_texts = ['Bombs!\nBombs!\nBiggest!\nBestest!\nGreatest!\nBoomest!']
PyramidFairy_texts = ['May I talk to you about our lord and savior, Ganon?']
Sahasrahla2_texts = ['You already got my item, idiot.', 'Why are you still talking to me?', 'This text won\'t change.', 'Have you met my brother, Hasarahshla?']
Blind_texts = [
"I hate insect\npuns, they\nreally bug me.",
@ -126,7 +125,7 @@ Blind_texts = [
"When you're a\nbaker, don't\nloaf around.",
"Mire requires\nEther Quake,\nor Bombos.",
"Broken pencils\nare pointless.",
"The food they\nserve guards\nlasts sentries.",
"The food they\nserve guards\nlasts sentries",
"Being crushed\nby big objects\nis depressing.",
"A tap dancer's\nroutine runs\nhot and cold.",
"A weeknight is\na tiny\nnobleman.",
@ -144,6 +143,7 @@ Blind_texts = [
"Sausage is\nthe wurst.",
"I tried to\ncatch fog,\nbut I mist.",
"Winter is a\ngreat time\nto chill.",
"Do you think\nthe Ice Rod\nis cool?",
]
Ganon1_texts = [
"Start your day\nsmiling with a\ndelicious\nwhole grain\nbreakfast\ncreated for\nyour\nincredible\ninsides.",
@ -246,7 +246,7 @@ Sahasrahla_names = [
"sandstorms", "sandwiched", "sauerkraut", "schipperke", "schismatic", "schizocarp", "schmalzier",
"schmeering", "schmoosing", "shibboleth", "shovelnose", "sahananana", "sarararara", "salamander",
"sharshalah", "shahabadoo", "sassafrass", "saddlebags", "sandalwood", "shagadelic", "sandcastle",
"saltpeters", "shabbiness", "shlrshlrsh",
"saltpeters", "shabbiness", "shlrshlrsh", "sassyralph", "sallyacorn",
]
Kakariko_texts = ["{}'s homecoming"]
@ -1300,6 +1300,9 @@ class TextTable(object):
'item_get_14_heart',
'item_get_24_heart',
'item_get_34_heart',
'pond_item_test',
'pond_will_upgrade',
# misc
'agahnim_final_meeting',
'agahnim_hide_and_seek_found',
@ -1461,7 +1464,7 @@ class TextTable(object):
text['sahasrahla_have_courage'] = CompressedTextMapper.convert("{BOTTOM}\nLook, you have the green pendant! I'll give you something. Go kill the other two bosses for more pendant fun!")
text['sahasrahla_found'] = CompressedTextMapper.convert("{BOTTOM}\nYup!\n\nI'm the old man you are looking for. I'll keep it short and sweet: Go into that dungeon, then bring me the green pendant and talk to me again.")
text['sign_rain_north_of_links_house'] = CompressedTextMapper.convert("↑ Dying Uncle\n This way…")
text['sign_north_of_links_house'] = CompressedTextMapper.convert("> Randomizer Don't read me, go beat Ganon!")
text['sign_north_of_links_house'] = CompressedTextMapper.convert("> Randomizer") #"> Randomizer The telepathic tiles can have hints!"
text['sign_path_to_death_mountain'] = CompressedTextMapper.convert("Cave to lost, old man.\nGood luck.")
text['sign_lost_woods'] = CompressedTextMapper.convert("\n↑ Lost Woods")
text['sign_zoras'] = CompressedTextMapper.convert("Danger!\nDeep water!\nZoras!")
@ -1596,11 +1599,11 @@ class TextTable(object):
text['mastersword_pedestal_translated'] = CompressedTextMapper.convert("A test of strength: If you have 3 pendants, I'm yours.")
text['telepathic_tile_spectacle_rock'] = CompressedTextMapper.convert("{NOBORDER}\n{NOBORDER}\nUse the Mirror, or the Hookshot and Hammer, to get to Tower of Hera!")
text['telepathic_tile_swamp_entrance'] = CompressedTextMapper.convert("{NOBORDER}\nDrain the floodgate to raise the water here!")
text['telepathic_tile_thieves_town_upstairs'] = CompressedTextMapper.convert("Secondary tournament winners\n{HARP}\n ~~~2017~~~\nA: Zaen")
text['telepathic_tile_thieves_town_upstairs'] = CompressedTextMapper.convert("{NOBORDER}\nBlind hate's bright light.")
text['telepathic_tile_misery_mire'] = CompressedTextMapper.convert("{NOBORDER}\nLighting 4 torches will open your way forward!")
text['hylian_text_2'] = CompressedTextMapper.convert("%%^= %==%\n ^ =%^=\n==%= ^^%^")
text['desert_entry_translated'] = CompressedTextMapper.convert("Kneel before this stone, and magic will move around you.")
text['telepathic_tile_under_ganon'] = CompressedTextMapper.convert("{NOBORDER}\nOnly arrows will finish off a blue Ganon, or really well-timed spins in phase 4.")
text['telepathic_tile_under_ganon'] = CompressedTextMapper.convert("Secondary tournament winners\n{HARP}\n ~~~2017~~~\nA: Zaen")
text['telepathic_tile_palace_of_darkness'] = CompressedTextMapper.convert("{NOBORDER}\nThis is a funny looking Enemizer")
# C0
text['telepathic_tile_desert_bonk_torch_room'] = CompressedTextMapper.convert("{NOBORDER}\nThings can be knocked down, if you fancy yourself a dashing dude.")
@ -1610,7 +1613,7 @@ class TextTable(object):
text['telepathic_tile_ice_entrace'] = CompressedTextMapper.convert("{NOBORDER}\nYou can use Fire Rod or Bombos to pass.")
text['telepathic_tile_ice_stalfos_knights_room'] = CompressedTextMapper.convert("{NOBORDER}\nKnock 'em down and then bomb them dead.")
text['telepathic_tile_tower_of_hera_entrance'] = CompressedTextMapper.convert("{NOBORDER}\nThis is a bad place, with a guy who will make you fall…\n\n\na lot.")
text['houlahan_room'] = CompressedTextMapper.convert("Randomizer tournament winners\n{HARP}\n ~~~2017~~~\nA: ajneb174\nS: ajneb174")
text['houlihan_room'] = CompressedTextMapper.convert("Randomizer tournament winners\n{HARP}\n ~~~2018~~~\nS: Andy\n\n ~~~2017~~~\nA: ajneb174\nS: ajneb174")
text['caught_a_bee'] = CompressedTextMapper.convert("Caught a Bee\n ≥ keep\n release\n{CHOICE}")
text['caught_a_fairy'] = CompressedTextMapper.convert("Caught Fairy!\n ≥ keep\n release\n{CHOICE}")
text['no_empty_bottles'] = CompressedTextMapper.convert("Whoa, bucko!\nNo empty bottles.")

View File

@ -10,6 +10,12 @@ def int32_as_bytes(value):
value = value & 0xFFFFFFFF
return [value & 0xFF, (value >> 8) & 0xFF, (value >> 16) & 0xFF, (value >> 24) & 0xFF]
def pc_to_snes(value):
return ((value<<1) & 0x7F0000)|(value & 0x7FFF)|0x8000
def snes_to_pc(value):
return ((value & 0x7F0000)>>1)|(value & 0x7FFF)
def is_bundled():
return getattr(sys, 'frozen', False)