OoT: Add warp song text replacement
This commit is contained in:
parent
cc3d5e60a1
commit
686812ee9e
|
@ -1,6 +1,6 @@
|
||||||
class Dungeon(object):
|
class Dungeon(object):
|
||||||
|
|
||||||
def __init__(self, world, name, hint, boss_key, small_keys, dungeon_items):
|
def __init__(self, world, name, hint, font_color, boss_key, small_keys, dungeon_items):
|
||||||
def to_array(obj):
|
def to_array(obj):
|
||||||
if obj == None:
|
if obj == None:
|
||||||
return []
|
return []
|
||||||
|
@ -12,6 +12,7 @@ class Dungeon(object):
|
||||||
self.world = world
|
self.world = world
|
||||||
self.name = name
|
self.name = name
|
||||||
self.hint_text = hint
|
self.hint_text = hint
|
||||||
|
self.font_color = font_color
|
||||||
self.regions = []
|
self.regions = []
|
||||||
self.boss_key = to_array(boss_key)
|
self.boss_key = to_array(boss_key)
|
||||||
self.small_keys = to_array(small_keys)
|
self.small_keys = to_array(small_keys)
|
||||||
|
@ -28,7 +29,7 @@ class Dungeon(object):
|
||||||
new_small_keys = [item.copy(new_world) for item in self.small_keys]
|
new_small_keys = [item.copy(new_world) for item in self.small_keys]
|
||||||
new_dungeon_items = [item.copy(new_world) for item in self.dungeon_items]
|
new_dungeon_items = [item.copy(new_world) for item in self.dungeon_items]
|
||||||
|
|
||||||
new_dungeon = Dungeon(new_world, self.name, self.hint, new_boss_key, new_small_keys, new_dungeon_items)
|
new_dungeon = Dungeon(new_world, self.name, self.hint_text, self.font_color, new_boss_key, new_small_keys, new_dungeon_items)
|
||||||
|
|
||||||
return new_dungeon
|
return new_dungeon
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@ from .Utils import data_path
|
||||||
dungeon_table = [
|
dungeon_table = [
|
||||||
{
|
{
|
||||||
'name': 'Deku Tree',
|
'name': 'Deku Tree',
|
||||||
|
'hint': 'the Deku Tree',
|
||||||
|
'font_color': 'Green',
|
||||||
'boss_key': 0,
|
'boss_key': 0,
|
||||||
'small_key': 0,
|
'small_key': 0,
|
||||||
'small_key_mq': 0,
|
'small_key_mq': 0,
|
||||||
|
@ -15,6 +17,7 @@ dungeon_table = [
|
||||||
{
|
{
|
||||||
'name': 'Dodongos Cavern',
|
'name': 'Dodongos Cavern',
|
||||||
'hint': 'Dodongo\'s Cavern',
|
'hint': 'Dodongo\'s Cavern',
|
||||||
|
'font_color': 'Red',
|
||||||
'boss_key': 0,
|
'boss_key': 0,
|
||||||
'small_key': 0,
|
'small_key': 0,
|
||||||
'small_key_mq': 0,
|
'small_key_mq': 0,
|
||||||
|
@ -23,6 +26,7 @@ dungeon_table = [
|
||||||
{
|
{
|
||||||
'name': 'Jabu Jabus Belly',
|
'name': 'Jabu Jabus Belly',
|
||||||
'hint': 'Jabu Jabu\'s Belly',
|
'hint': 'Jabu Jabu\'s Belly',
|
||||||
|
'font_color': 'Blue',
|
||||||
'boss_key': 0,
|
'boss_key': 0,
|
||||||
'small_key': 0,
|
'small_key': 0,
|
||||||
'small_key_mq': 0,
|
'small_key_mq': 0,
|
||||||
|
@ -30,6 +34,8 @@ dungeon_table = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'Forest Temple',
|
'name': 'Forest Temple',
|
||||||
|
'hint': 'the Forest Temple',
|
||||||
|
'font_color': 'Green',
|
||||||
'boss_key': 1,
|
'boss_key': 1,
|
||||||
'small_key': 5,
|
'small_key': 5,
|
||||||
'small_key_mq': 6,
|
'small_key_mq': 6,
|
||||||
|
@ -37,6 +43,8 @@ dungeon_table = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'Bottom of the Well',
|
'name': 'Bottom of the Well',
|
||||||
|
'hint': 'the Bottom of the Well',
|
||||||
|
'font_color': 'Pink',
|
||||||
'boss_key': 0,
|
'boss_key': 0,
|
||||||
'small_key': 3,
|
'small_key': 3,
|
||||||
'small_key_mq': 2,
|
'small_key_mq': 2,
|
||||||
|
@ -44,6 +52,8 @@ dungeon_table = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'Fire Temple',
|
'name': 'Fire Temple',
|
||||||
|
'hint': 'the Fire Temple',
|
||||||
|
'font_color': 'Red',
|
||||||
'boss_key': 1,
|
'boss_key': 1,
|
||||||
'small_key': 8,
|
'small_key': 8,
|
||||||
'small_key_mq': 5,
|
'small_key_mq': 5,
|
||||||
|
@ -51,6 +61,8 @@ dungeon_table = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'Ice Cavern',
|
'name': 'Ice Cavern',
|
||||||
|
'hint': 'the Ice Cavern',
|
||||||
|
'font_color': 'Blue',
|
||||||
'boss_key': 0,
|
'boss_key': 0,
|
||||||
'small_key': 0,
|
'small_key': 0,
|
||||||
'small_key_mq': 0,
|
'small_key_mq': 0,
|
||||||
|
@ -58,6 +70,8 @@ dungeon_table = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'Water Temple',
|
'name': 'Water Temple',
|
||||||
|
'hint': 'the Water Temple',
|
||||||
|
'font_color': 'Blue',
|
||||||
'boss_key': 1,
|
'boss_key': 1,
|
||||||
'small_key': 6,
|
'small_key': 6,
|
||||||
'small_key_mq': 2,
|
'small_key_mq': 2,
|
||||||
|
@ -65,6 +79,8 @@ dungeon_table = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'Shadow Temple',
|
'name': 'Shadow Temple',
|
||||||
|
'hint': 'the Shadow Temple',
|
||||||
|
'font_color': 'Pink',
|
||||||
'boss_key': 1,
|
'boss_key': 1,
|
||||||
'small_key': 5,
|
'small_key': 5,
|
||||||
'small_key_mq': 6,
|
'small_key_mq': 6,
|
||||||
|
@ -72,6 +88,8 @@ dungeon_table = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'Gerudo Training Grounds',
|
'name': 'Gerudo Training Grounds',
|
||||||
|
'hint': 'the Gerudo Training Grounds',
|
||||||
|
'font_color': 'Yellow',
|
||||||
'boss_key': 0,
|
'boss_key': 0,
|
||||||
'small_key': 9,
|
'small_key': 9,
|
||||||
'small_key_mq': 3,
|
'small_key_mq': 3,
|
||||||
|
@ -79,6 +97,8 @@ dungeon_table = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'Spirit Temple',
|
'name': 'Spirit Temple',
|
||||||
|
'hint': 'the Spirit Temple',
|
||||||
|
'font_color': 'Yellow',
|
||||||
'boss_key': 1,
|
'boss_key': 1,
|
||||||
'small_key': 5,
|
'small_key': 5,
|
||||||
'small_key_mq': 7,
|
'small_key_mq': 7,
|
||||||
|
@ -100,6 +120,7 @@ def create_dungeons(ootworld):
|
||||||
for dungeon_info in dungeon_table:
|
for dungeon_info in dungeon_table:
|
||||||
name = dungeon_info['name']
|
name = dungeon_info['name']
|
||||||
hint = dungeon_info['hint'] if 'hint' in dungeon_info else name
|
hint = dungeon_info['hint'] if 'hint' in dungeon_info else name
|
||||||
|
font_color = dungeon_info['font_color'] if 'font_color' in dungeon_info else 'White'
|
||||||
|
|
||||||
if ootworld.logic_rules == 'glitchless':
|
if ootworld.logic_rules == 'glitchless':
|
||||||
if not ootworld.dungeon_mq[name]:
|
if not ootworld.dungeon_mq[name]:
|
||||||
|
@ -125,5 +146,5 @@ def create_dungeons(ootworld):
|
||||||
for item in dungeon_items:
|
for item in dungeon_items:
|
||||||
item.priority = True
|
item.priority = True
|
||||||
|
|
||||||
ootworld.dungeons.append(Dungeon(ootworld, name, hint, boss_keys, small_keys, dungeon_items))
|
ootworld.dungeons.append(Dungeon(ootworld, name, hint, font_color, boss_keys, small_keys, dungeon_items))
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import json
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
from .HintList import getHint, getHintGroup, Hint, hintExclusions
|
from .HintList import getHint, getHintGroup, Hint, hintExclusions
|
||||||
from .Messages import update_message_by_id
|
from .Messages import COLOR_MAP, update_message_by_id
|
||||||
from .TextBox import line_wrap
|
from .TextBox import line_wrap
|
||||||
from .Utils import data_path, read_json
|
from .Utils import data_path, read_json
|
||||||
|
|
||||||
|
@ -266,17 +266,6 @@ def getSimpleHintNoPrefix(item):
|
||||||
|
|
||||||
|
|
||||||
def colorText(gossip_text):
|
def colorText(gossip_text):
|
||||||
colorMap = {
|
|
||||||
'White': '\x40',
|
|
||||||
'Red': '\x41',
|
|
||||||
'Green': '\x42',
|
|
||||||
'Blue': '\x43',
|
|
||||||
'Light Blue': '\x44',
|
|
||||||
'Pink': '\x45',
|
|
||||||
'Yellow': '\x46',
|
|
||||||
'Black': '\x47',
|
|
||||||
}
|
|
||||||
|
|
||||||
text = gossip_text.text
|
text = gossip_text.text
|
||||||
colors = list(gossip_text.colors) if gossip_text.colors is not None else []
|
colors = list(gossip_text.colors) if gossip_text.colors is not None else []
|
||||||
color = 'White'
|
color = 'White'
|
||||||
|
@ -292,7 +281,7 @@ def colorText(gossip_text):
|
||||||
splitText[1] = splitText[1][len(prefix):]
|
splitText[1] = splitText[1][len(prefix):]
|
||||||
break
|
break
|
||||||
|
|
||||||
splitText[1] = '\x05' + colorMap[color] + splitText[1] + '\x05\x40'
|
splitText[1] = '\x05' + COLOR_MAP[color] + splitText[1] + '\x05\x40'
|
||||||
text = ''.join(splitText)
|
text = ''.join(splitText)
|
||||||
|
|
||||||
return text
|
return text
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# text details: https://wiki.cloudmodding.com/oot/Text_Format
|
# text details: https://wiki.cloudmodding.com/oot/Text_Format
|
||||||
|
|
||||||
|
import logging
|
||||||
import random
|
import random
|
||||||
from .TextBox import line_wrap
|
from .TextBox import line_wrap
|
||||||
|
|
||||||
|
@ -316,6 +317,17 @@ KEYSANITY_MESSAGES = {
|
||||||
0x00A9: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x45Shadow Temple\x05\x40!\x09",
|
0x00A9: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x45Shadow Temple\x05\x40!\x09",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
COLOR_MAP = {
|
||||||
|
'White': '\x40',
|
||||||
|
'Red': '\x41',
|
||||||
|
'Green': '\x42',
|
||||||
|
'Blue': '\x43',
|
||||||
|
'Light Blue': '\x44',
|
||||||
|
'Pink': '\x45',
|
||||||
|
'Yellow': '\x46',
|
||||||
|
'Black': '\x47',
|
||||||
|
}
|
||||||
|
|
||||||
MISC_MESSAGES = {
|
MISC_MESSAGES = {
|
||||||
0x507B: (bytearray(
|
0x507B: (bytearray(
|
||||||
b"\x08I tell you, I saw him!\x04" \
|
b"\x08I tell you, I saw him!\x04" \
|
||||||
|
@ -995,3 +1007,30 @@ def shuffle_messages(messages, except_hints=True, always_allow_skip=True):
|
||||||
]))
|
]))
|
||||||
|
|
||||||
return permutation
|
return permutation
|
||||||
|
|
||||||
|
# Update warp song text boxes for ER
|
||||||
|
def update_warp_song_text(messages, ootworld):
|
||||||
|
msg_list = {
|
||||||
|
0x088D: 'Minuet of Forest Warp -> Sacred Forest Meadow',
|
||||||
|
0x088E: 'Bolero of Fire Warp -> DMC Central Local',
|
||||||
|
0x088F: 'Serenade of Water Warp -> Lake Hylia',
|
||||||
|
0x0890: 'Requiem of Spirit Warp -> Desert Colossus',
|
||||||
|
0x0891: 'Nocturne of Shadow Warp -> Graveyard Warp Pad Region',
|
||||||
|
0x0892: 'Prelude of Light Warp -> Temple of Time',
|
||||||
|
}
|
||||||
|
|
||||||
|
for id, entr in msg_list.items():
|
||||||
|
destination = ootworld.world.get_entrance(entr, ootworld.player).connected_region
|
||||||
|
|
||||||
|
if destination.pretty_name:
|
||||||
|
destination_name = destination.pretty_name
|
||||||
|
elif destination.hint_text:
|
||||||
|
destination_name = destination.hint_text
|
||||||
|
elif destination.dungeon:
|
||||||
|
destination_name = destination.dungeon.hint
|
||||||
|
else:
|
||||||
|
destination_name = destination.name
|
||||||
|
color = COLOR_MAP[destination.font_color or 'White']
|
||||||
|
|
||||||
|
new_msg = f"\x08\x05{color}Warp to {destination_name}?\x05\40\x09\x01\x01\x1b\x05{color}OK\x01No\x05\40"
|
||||||
|
update_message_by_id(messages, id, new_msg)
|
||||||
|
|
|
@ -9,7 +9,7 @@ from .LocationList import business_scrubs
|
||||||
from .Hints import writeGossipStoneHints, buildAltarHints, \
|
from .Hints import writeGossipStoneHints, buildAltarHints, \
|
||||||
buildGanonText, getSimpleHintNoPrefix
|
buildGanonText, getSimpleHintNoPrefix
|
||||||
from .Utils import data_path
|
from .Utils import data_path
|
||||||
from .Messages import read_messages, update_message_by_id, read_shop_items, \
|
from .Messages import read_messages, update_message_by_id, read_shop_items, update_warp_song_text, \
|
||||||
write_shop_items, remove_unused_messages, make_player_message, \
|
write_shop_items, remove_unused_messages, make_player_message, \
|
||||||
add_item_messages, repack_messages, shuffle_messages, \
|
add_item_messages, repack_messages, shuffle_messages, \
|
||||||
get_message_by_id
|
get_message_by_id
|
||||||
|
@ -1747,6 +1747,10 @@ def patch_rom(world, rom):
|
||||||
elif world.text_shuffle == 'complete':
|
elif world.text_shuffle == 'complete':
|
||||||
permutation = shuffle_messages(messages, except_hints=False)
|
permutation = shuffle_messages(messages, except_hints=False)
|
||||||
|
|
||||||
|
# If Warp Song ER is on, update text boxes
|
||||||
|
if world.warp_songs:
|
||||||
|
update_warp_song_text(messages, world)
|
||||||
|
|
||||||
repack_messages(rom, messages, permutation)
|
repack_messages(rom, messages, permutation)
|
||||||
|
|
||||||
# output a text dump, for testing...
|
# output a text dump, for testing...
|
||||||
|
|
|
@ -38,6 +38,8 @@ class OOTRegion(Region):
|
||||||
self.provides_time = TimeOfDay.NONE
|
self.provides_time = TimeOfDay.NONE
|
||||||
self.scene = None
|
self.scene = None
|
||||||
self.dungeon = None
|
self.dungeon = None
|
||||||
|
self.pretty_name = None
|
||||||
|
self.font_color = None
|
||||||
|
|
||||||
def get_scene(self):
|
def get_scene(self):
|
||||||
if self.scene:
|
if self.scene:
|
||||||
|
|
|
@ -275,6 +275,10 @@ class OOTWorld(World):
|
||||||
for region in region_json:
|
for region in region_json:
|
||||||
new_region = OOTRegion(region['region_name'], RegionType.Generic, None, self.player)
|
new_region = OOTRegion(region['region_name'], RegionType.Generic, None, self.player)
|
||||||
new_region.world = self.world
|
new_region.world = self.world
|
||||||
|
if 'pretty_name' in region:
|
||||||
|
new_region.pretty_name = region['pretty_name']
|
||||||
|
if 'font_color' in region:
|
||||||
|
new_region.font_color = region['font_color']
|
||||||
if 'scene' in region:
|
if 'scene' in region:
|
||||||
new_region.scene = region['scene']
|
new_region.scene = region['scene']
|
||||||
if 'hint' in region:
|
if 'hint' in region:
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue