Skip to content
9 changes: 9 additions & 0 deletions args/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@ def __init__(self):
if self.debug:
self.spoiler_log = True

# Update the global args module attributes to match this Arguments instance,
# which is helpful if a wrapper script instantiates Arguments dynamically
# instead of importing the args module directly.
import sys
if "args" in sys.modules:
module = sys.modules["args"]
for name, value in self.__dict__.items():
setattr(module, name, value)

def _process_min_max(self, arg_name):
values = getattr(self, arg_name)
if values:
Expand Down
29 changes: 28 additions & 1 deletion args/graphics.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,32 @@ def parse(parser):
graphics.add_argument("-ahtc", "--alternate-healing-text-color", action = "store_true",
help = "Makes healing text blue, to be able to distinguish from damage.")

graphics.add_argument("-steve", "--steveify", type = str, nargs='?', const='Steve', default=None,
help = "Steveify the seed: rename all characters, items, espers, magic, enemies, etc. to a given name (default: Steve)")

def process(args):
import graphics.palettes.palettes as palettes
import graphics.portraits.portraits as portraits
import graphics.sprites.sprites as sprites

if args.steveify is not None:
if isinstance(args.steveify, bool):
if args.steveify:
args.steveify = "STEVE"
else:
args.steveify = None
else:
args.steveify = args.steveify.strip()
steveify_upper = args.steveify.upper()
if steveify_upper in ("NONE", "FALSE"):
args.steveify = None
elif not args.steveify:
args.steveify = "STEVE"

if args.steveify is not None:
if len(args.steveify) > 6:
args.steveify = args.steveify[:6]
Comment thread
wrjones104 marked this conversation as resolved.

if args.character_names is not None:
args.names = args.character_names.split('.')
if len(args.names) != Characters.CHARACTER_COUNT:
Expand All @@ -40,6 +61,9 @@ def process(args):
else:
args.names = Characters.DEFAULT_NAME

if args.steveify is not None:
args.names = [args.steveify] * Characters.CHARACTER_COUNT
Comment on lines +64 to +65

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since args.steveify is no longer truncated to 6 characters globally, we should explicitly truncate it to Characters.NAME_SIZE (6) when assigning to args.names to ensure character names do not exceed their limit.

Suggested change
if args.steveify is not None:
args.names = [args.steveify] * Characters.CHARACTER_COUNT
if args.steveify is not None:
args.names = [args.steveify[:Characters.NAME_SIZE]] * Characters.CHARACTER_COUNT


args.palettes = []
if args.character_palettes:
args.palette_ids = [int(palette_id) for palette_id in args.character_palettes.split('.')]
Expand Down Expand Up @@ -101,6 +125,8 @@ def flags(args):

if args.character_names:
flags += " -name " + args.character_names
if args.steveify:
flags += f' -steve "{args.steveify}"'
if args.character_palettes:
flags += " -cpal " + args.character_palettes
if args.character_portraits:
Expand Down Expand Up @@ -189,8 +215,9 @@ def _other_options_log(args):

entries = [
("Remove Flashes", remove_flashes, "remove_flashes"),
("World Minimap", world_minimap, "world_minimap"),
("Minimap", world_minimap, "world_minimap"),
("Healing Text", healing_text, "healing_text"),
("Steveify", args.steveify if args.steveify else "None", "steveify"),
]

for entry in entries:
Expand Down
4 changes: 4 additions & 0 deletions data/characters.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ def mod(self):
if self.args.character_names:
self.mod_names()

if self.args.steveify:
for character in self.characters:
character.name = self.args.steveify
Comment on lines +136 to +138

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Explicitly truncate self.args.steveify to self.NAME_SIZE (6) to prevent potential buffer overflow or write issues if a longer custom name is provided.

Suggested change
if self.args.steveify:
for character in self.characters:
character.name = self.args.steveify
if self.args.steveify:
for character in self.characters:
character.name = self.args.steveify[:self.NAME_SIZE]


if self.args.original_name_display:
characters_asm.show_original_names()

Expand Down
4 changes: 4 additions & 0 deletions data/dances.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ def shuffle(self):
dance.dances = abilities[ability_index : ability_index + self.DATA_SIZE]

def mod(self):
if self.args.steveify:
for dance in self.dances:
dance.name = self.args.steveify
Comment on lines +167 to +169

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Explicitly truncate self.args.steveify to self.NAME_SIZE (12) to prevent potential buffer overflow or write issues if a longer custom name is provided.

Suggested change
if self.args.steveify:
for dance in self.dances:
dance.name = self.args.steveify
if self.args.steveify:
for dance in self.dances:
dance.name = self.args.steveify[:self.NAME_SIZE]


self.write_learners_table()
self.write_is_learner()
self.after_battle_check_mod()
Expand Down
12 changes: 12 additions & 0 deletions data/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

class Data:
def __init__(self, rom, args):
self.rom = rom
self.args = args
self.dialogs = dialogs

self.spells = spells.Spells(rom, args)
Expand Down Expand Up @@ -81,6 +83,16 @@ def __init__(self, rom, args):
self.title_graphics.mod()

def write(self):
if self.args.steveify:
import data.text as text
ability_name_bytes = bytearray()
name_bytes = bytearray(text.get_bytes(self.args.steveify, text.TEXT2))
name_bytes = name_bytes[:10]
name_bytes.extend([0xff] * (10 - len(name_bytes)))
for i in range(175):
ability_name_bytes.extend(name_bytes)
Comment thread
wrjones104 marked this conversation as resolved.
self.rom.set_bytes(0x26f7b9, ability_name_bytes)

self.dialogs.write()
self.characters.write()
self.items.write()
Expand Down
9 changes: 9 additions & 0 deletions data/enemies.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ def get_enemy(self, name):
return enemy.id

def get_name(self, enemy_id):
if self.args.steveify:
return self.args.steveify
Comment on lines +78 to +79

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Ensure get_name returns the truncated name (up to self.NAME_SIZE characters) to remain consistent with what is actually written to the ROM.

Suggested change
if self.args.steveify:
return self.args.steveify
if self.args.steveify:
return self.args.steveify[:self.NAME_SIZE]

if enemy_id in bosses.enemy_name:
return bosses.enemy_name[enemy_id]
return self.enemies[enemy_id].name
Expand Down Expand Up @@ -439,6 +441,13 @@ def print(self):
enemy.print()

def write(self):
if self.args.steveify:
for enemy in self.enemies:
if enemy.name:
enemy.name = self.args.steveify
if enemy.special_name:
enemy.special_name = self.args.steveify
Comment on lines +444 to +449

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Explicitly truncate self.args.steveify to self.NAME_SIZE (10) and self.SPECIAL_NAMES_SIZE (10) respectively to prevent potential buffer overflow or write issues if a longer custom name is provided.

Suggested change
if self.args.steveify:
for enemy in self.enemies:
if enemy.name:
enemy.name = self.args.steveify
if enemy.special_name:
enemy.special_name = self.args.steveify
if self.args.steveify:
for enemy in self.enemies:
if enemy.name:
enemy.name = self.args.steveify[:self.NAME_SIZE]
if enemy.special_name:
enemy.special_name = self.args.steveify[:self.SPECIAL_NAMES_SIZE]


for enemy_index in range(len(self.enemies)):
self.enemy_data[enemy_index] = self.enemies[enemy_index].data()
self.enemy_name_data[enemy_index] = self.enemies[enemy_index].name_data()
Expand Down
6 changes: 5 additions & 1 deletion data/espers.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,10 @@ def multi_summon(self):
space = Reserve(0x24da3, 0x24da5, "espers set used in battle bit", asm.NOP())

def mod(self, dialogs):
if self.args.steveify:
for esper in self.espers:
esper.name = self.args.steveify
Comment on lines +278 to +280

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Explicitly truncate self.args.steveify to self.NAME_SIZE (8) to prevent potential buffer overflow or write issues if a longer custom name is provided.

Suggested change
if self.args.steveify:
for esper in self.espers:
esper.name = self.args.steveify
if self.args.steveify:
for esper in self.espers:
esper.name = self.args.steveify[:self.NAME_SIZE]


self.receive_dialogs_mod(dialogs)

if self.args.esper_spells_shuffle or self.args.esper_spells_shuffle_random_rates:
Expand Down Expand Up @@ -353,7 +357,7 @@ def get_receive_esper_dialog(self, esper):
return self.receive_dialogs[esper]

def get_name(self, esper):
return self.esper_names[esper]
return self.espers[esper].get_name()

def log(self):
from log import COLUMN_WIDTH, section_entries, format_option
Expand Down
9 changes: 9 additions & 0 deletions data/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,15 @@ def moogle_starting_equipment(self):
self.characters.characters[index].init_head = random.choice(tiers[Item.HELMET][1])

def mod(self):
if self.args.steveify:
for item in self.items:
if item.id != self.EMPTY:
icon = ""
if item.name.startswith("<"):
end_tag = item.name.find(">")
if end_tag != -1:
icon = item.name[:end_tag + 1]
item.name = f"{icon}{self.args.steveify}"
not_relic_condition = lambda x: x != Item.RELIC
if self.args.item_equipable_random:
self.equipable_random(not_relic_condition, self.args.item_equipable_random_min,
Expand Down
9 changes: 9 additions & 0 deletions data/lores.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,15 @@ def mod(self, dialogs):
if self.args.lores_level_randomize:
self.random_lx_levels(dialogs)

if self.args.steveify:
import re
for lore in self.lores:
match = re.search('L.*[?1-9]', lore.name)
if match:
lore.name = f"{match.group()} {self.args.steveify}"[:self.NAME_SIZE]
else:
lore.name = self.args.steveify[:self.NAME_SIZE]

def write(self):
if self.args.spoiler_log:
self.log()
Expand Down
4 changes: 4 additions & 0 deletions data/magiteks.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ def fix_reflectable_beams(self):
self.magiteks[self.ICE_BEAM].flags2 = 0x22

def mod(self):
if self.args.steveify:
for magitek in self.magiteks:
magitek.name = self.args.steveify
Comment on lines +37 to +39

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Explicitly truncate self.args.steveify to self.NAME_SIZE (10) to prevent potential buffer overflow or write issues if a longer custom name is provided.

Suggested change
if self.args.steveify:
for magitek in self.magiteks:
magitek.name = self.args.steveify
if self.args.steveify:
for magitek in self.magiteks:
magitek.name = self.args.steveify[:self.NAME_SIZE]


self.fix_reflectable_beams()
pass

Expand Down
17 changes: 17 additions & 0 deletions data/spells.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,23 @@ def alternate_healing_text_color(self):
space.write(0x44, 0x7f) #default: F6 4B

def mod(self):
if self.args.steveify:
for spell in self.spells:
icon = ""
for tag in ['<black magic icon>', '<white magic icon>', '<gray magic icon>']:
if spell.name.startswith(tag):
icon = tag
break
suffix = ""
for s in [" 2", " 3", "2"]:
if spell.name.endswith(s):
suffix = s
break

max_steve_len = 6 - len(suffix)
steve_part = self.args.steveify[:max_steve_len]
spell.name = f"{icon}{steve_part}{suffix}"

if self.args.magic_mp_shuffle:
self.shuffle_mp()
elif self.args.magic_mp_random_value:
Expand Down
4 changes: 4 additions & 0 deletions data/swdtechs.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ def enable_fast_swdtech(self):
space.write(0x00)

def mod(self):
if self.args.steveify:
for swdtech in self.swdtechs:
swdtech.name = self.args.steveify
Comment on lines +133 to +135

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Explicitly truncate self.args.steveify to SwdTech.NAME_SIZE to prevent potential buffer overflow or write issues if a longer custom name is provided.

Suggested change
if self.args.steveify:
for swdtech in self.swdtechs:
swdtech.name = self.args.steveify
if self.args.steveify:
for swdtech in self.swdtechs:
swdtech.name = self.args.steveify[:SwdTech.NAME_SIZE]


self.write_learners_table()
self.write_is_learner()

Expand Down
Loading