diff --git a/asura/__init__.py b/asura/__init__.py
index 63efc86..c600838 100644
--- a/asura/__init__.py
+++ b/asura/__init__.py
@@ -11,11 +11,11 @@ def generate(rng=None, mode='snes', forbidden=[]):
seed(rng)
if mode == 'snes':
- max_espers = Esper.SNES_Count
- max_spells = Spell.SNES_Count
+ max_espers = Esper.SNES_Count - 1
+ max_spells = Spell.SNES_Count - 1
else:
- max_espers = Esper.GBA_Count
- max_spells = Spell.GBA_Count
+ max_espers = Esper.GBA_Count - 1
+ max_spells = Spell.GBA_Count - 1
espers = {}
@@ -39,6 +39,7 @@ remove = [
]
def write_rom(input_name, output_name, mode, espers):
+ offset = 0
if mode == 'gba':
offset = 0x70000
spello = 0x62A480
@@ -55,7 +56,7 @@ def write_rom(input_name, output_name, mode, espers):
rom.seek(i[0] + offset, 0)
rom.write(b'\xFD' * i[1])
- esper_list = espers.keys()
+ esper_list = list(espers.keys())
# these four are the espers given when you reach Tina in Zozo
rom.seek(0xAA824 + offset, 0); rom.write(bytes([esper_list[0] + 0x36]))
@@ -72,7 +73,7 @@ def write_rom(input_name, output_name, mode, espers):
rom.seek(spello + esper * 11, 0)
for spell in spells:
- rom.write(bytes(spell[1], spell[0]))
+ rom.write(bytes([spell[1], spell[0]]))
if leftover > 0:
rom.write(b'\x00\xFF' * leftover)
diff --git a/asura/data.py b/asura/data.py
index f99d06a..88e1456 100644
--- a/asura/data.py
+++ b/asura/data.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-#
# Copyright (C) 2019 Kiyoshi Aman
#
# This program is free software: you can redistribute it and/or modify
@@ -14,24 +12,10 @@
# You should have received a copy of the GNU Affero General Public
# License along with this program. If not, see
# .
-#
-# This project was made possible by:
-# * Lenophis, who told me where the 'give this esper' bytes are
-# * ff6hacking.com, which hosts the data tables I used to pick from.
-# * CanOfWorms, for figuring out the GBA offsets.
-#
-# ChangeLog:
-# 0.3:
-# - GBA support! Purportedly works for J, U, *and* E versions.
-# 0.2:
-# - Preliminary work toward supporting GBA ROMs. This needs data I
-# don't have to complete, however, but the cleanup it required was
-# useful.
-# - Reworked learning rates. Rates should be overall lower now.
-# - Majority of output moved to a spoilers file.
from copy import copy
from enum import IntEnum
+from collections import defaultdict
class Bonus(IntEnum):
HP_10 = 0x00
@@ -168,7 +152,7 @@ spell_map = {
'Poison': Spell.Poison,
'Firera': Spell.Firera,
'Fira': Spell.Firera,
- 'Fire2': Spell.Firera
+ 'Fire2': Spell.Firera,
'Blizzardra': Spell.Blizzardra,
'Blizzara': Spell.Blizzardra,
'Ice2': Spell.Blizzardra,
@@ -269,28 +253,32 @@ spell_map = {
}
slots = defaultdict(lambda: 1)
-slots[Spell.Ultima] = 4
-slots[Spell.Quick] = 4
-slots[Spell.Firega] = 3
-slots[Spell.Thunderga] = 3
-slots[Spell.Blizzardga] = 3
-slots[Spell.Meltdown] = 3
-slots[Spell.Tornado] = 3
-slots[Spell.Quake] = 3
-slots[Spell.Arise] = 3
-slots[Spell.Curega] = 3
+slots[Spell.Quick] = 5
+slots[Spell.Ultima] = 5
+slots[Spell.Arise] = 4
+slots[Spell.Blizzardga] = 4
+slots[Spell.Curega] = 4
+slots[Spell.Firega] = 4
+slots[Spell.Meltdown] = 4
+slots[Spell.Quake] = 4
+slots[Spell.Slowga] = 4
+slots[Spell.Thunderga] = 4
+slots[Spell.Tornado] = 4
+slots[Spell.Death] = 3
+slots[Spell.Gravityga] = 3
slots[Spell.Hastega] = 3
-slots[Spell.Slowga] = 3
+slots[Spell.NullStatus] = 3
slots[Spell.Osmose] = 3
-slots[Spell.Raise] = 2
slots[Spell.Curera] = 2
slots[Spell.Haste] = 2
+slots[Spell.Raise] = 2
+slots[Spell.Reraise] = 2
slots[Spell.Slow] = 2
slots_gba = copy(slots)
-slots_gba[Spell.Gravityja] = 3
-slots_gba[Spell.Flood] = 3
-slots_gba[Spell.Valor] = 3
+slots_gba[Spell.Gravityja] = 5
+slots_gba[Spell.Flood] = 4
+slots_gba[Spell.Valor] = 4
class Esper(IntEnum):
Ramuh = 0
diff --git a/asura/spells.py b/asura/spells.py
index 430bae6..5513998 100644
--- a/asura/spells.py
+++ b/asura/spells.py
@@ -2,8 +2,8 @@
from random import randint
from .data import Spell, slots, slots_gba
-def roll_spells(max, forbidden=()):
- count = 8
+def roll_spells(cap, forbidden=()):
+ count = 6
n = 5
spells = []
spells_got = list(forbidden)
@@ -12,15 +12,15 @@ def roll_spells(max, forbidden=()):
if n <= 0 or count <= 0:
break
- spell = Spell(randint(0, max))
+ spell = Spell(randint(0, cap))
if spell in spells_got:
continue
if (count - slots[spell]) >= 0:
- spells.append([spell, randint(1, 5 - slots[spell]) * 5])
+ spells.append([spell, randint(1, max(6 - slots[spell], 2)) * 5])
spells_got.append(spell)
- count -= slots
+ count -= slots[spell]
n -= 1
return spells
diff --git a/main.py b/main.py
new file mode 100755
index 0000000..91cd3ac
--- /dev/null
+++ b/main.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python3
+
+from sys import argv, exit
+from time import time
+
+import os.path as op
+
+from asura import generate, write_rom, write_spoilers
+from asura.data import spell_map
+
+if len(argv) < 2 or len(argv) > 4:
+ print('Usage: {} [seed [forbidden,spells,...]]'.format(argv[0]))
+ exit(1)
+
+if len(argv) == 2:
+ seed = str(time()).split('.')[0]
+if len(argv) >= 3:
+ seed = argv[2]
+if len(argv) == 4:
+ spells = argv[3].split(',')
+ forbidden = [spell_map[i] for i in spells]
+else:
+ forbidden = []
+
+filename = argv[1]
+namebase, ext = op.splitext(filename)
+ext = ext[1:]
+output_rom = '.'.join([namebase, seed, ext])
+output_txt = '.'.join([namebase, seed, 'txt'])
+
+mode = 'snes' if ext != 'gba' else 'gba'
+
+espers = generate(seed, mode, forbidden)
+
+print('Seed: {}\n'.format(seed))
+print('Writing ROM...')
+write_rom(filename, output_rom, mode, espers)
+print('Writing spoilers...')
+write_spoilers(output_txt, espers, seed)