Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/mars_patcher/constants/enemies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from enum import Enum


class EnemyType(Enum):
CRAWLING = 1
GROUND = 2
CEILING = 3
GROUND_CEILING = 4
WALL = 5
FLYING = 6
103 changes: 47 additions & 56 deletions src/mars_patcher/mf/constants/enemies.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,49 @@
from enum import Enum
from mars_patcher.constants.enemies import EnemyType
from mars_patcher.mf.constants.sprites import SpriteIdMF


class EnemyType(Enum):
CRAWLING = 1
GROUND = 2
CEILING = 3
GROUND_CEILING = 4
WALL = 5
FLYING = 6


ENEMY_TYPES = {
0x12: ("Hornoad", EnemyType.GROUND),
0x13: ("Halzyn", EnemyType.FLYING),
0x14: ("Zebesian (wall)", EnemyType.WALL),
0x15: ("Hornoad spawner", EnemyType.GROUND),
0x18: ("Moto", EnemyType.GROUND),
0x1B: ("Yameba", EnemyType.FLYING),
0x31: ("Zeela", EnemyType.CRAWLING),
0x33: ("Skree (unused)", EnemyType.CEILING),
0x37: ("Zombie", EnemyType.GROUND),
0x39: ("Geemer", EnemyType.CRAWLING),
0x3B: ("Waver", EnemyType.FLYING),
0x3C: ("Sciser", EnemyType.CRAWLING),
0x3D: ("Sidehopper", EnemyType.GROUND_CEILING),
0x3E: ("Dessgeega", EnemyType.GROUND_CEILING),
0x5A: ("Zoro", EnemyType.CRAWLING),
0x5B: ("Kihunter (flying)", EnemyType.FLYING),
0x5C: ("Kihunter (ground)", EnemyType.GROUND),
0x5E: ("Reo", EnemyType.FLYING),
0x60: ("Namihe", EnemyType.WALL),
0x61: ("Fune", EnemyType.WALL),
0x63: ("Blue zoro", EnemyType.CRAWLING),
0x64: ("Geruda", EnemyType.FLYING),
0x6A: ("Skultera (large)", EnemyType.FLYING),
0x6B: ("Skultera (small, cannot become large)", EnemyType.FLYING),
0x6C: ("Sova", EnemyType.CRAWLING),
0x6D: ("Yard", EnemyType.CRAWLING),
0x6E: ("Evir", EnemyType.FLYING),
0x6F: ("Bull", EnemyType.FLYING),
0x70: ("Memu", EnemyType.FLYING),
0x71: ("Geruboss", EnemyType.CEILING),
0x72: ("Choot", EnemyType.GROUND),
0x73: ("Zebesian (ground)", EnemyType.GROUND),
0x88: ("Ripper", EnemyType.FLYING),
0xA3: ("Red Zeela", EnemyType.CRAWLING),
0xA4: ("Owtch", EnemyType.CRAWLING),
0xA8: ("Genesis", EnemyType.GROUND),
0xA9: ("Puyo", EnemyType.GROUND),
0xAD: ("Fake energy tank", EnemyType.GROUND),
0xAE: ("Fake missile tank", EnemyType.GROUND),
0xB3: ("Zebesian (aqua)", EnemyType.FLYING),
0xB4: ("Zebesian (pre-aqua)", EnemyType.GROUND),
0xB5: ("Skultera (small)", EnemyType.FLYING),
0xBD: ("Powamp", EnemyType.FLYING),
0xBE: ("Zozoro", EnemyType.CRAWLING),
ENEMY_TYPES_MF = {
SpriteIdMF.HORNOAD: EnemyType.GROUND,
SpriteIdMF.HALZYN: EnemyType.FLYING,
SpriteIdMF.ZEBESIAN_WALL: EnemyType.WALL,
SpriteIdMF.HORNOAD_SPAWNER: EnemyType.GROUND,
SpriteIdMF.MOTO: EnemyType.GROUND,
SpriteIdMF.YAMEBA: EnemyType.FLYING,
SpriteIdMF.ZEELA: EnemyType.CRAWLING,
SpriteIdMF.SKREE_UNUSED: EnemyType.CEILING,
SpriteIdMF.ZOMBIE: EnemyType.GROUND,
SpriteIdMF.GEEMER: EnemyType.CRAWLING,
SpriteIdMF.WAVER: EnemyType.FLYING,
SpriteIdMF.SCISER: EnemyType.CRAWLING,
SpriteIdMF.SIDEHOPPER: EnemyType.GROUND_CEILING,
SpriteIdMF.DESSGEEGA: EnemyType.GROUND_CEILING,
SpriteIdMF.ZORO: EnemyType.CRAWLING,
SpriteIdMF.KIHUNTER_FLYING: EnemyType.FLYING,
SpriteIdMF.KIHUNTER_GROUND: EnemyType.GROUND,
SpriteIdMF.REO: EnemyType.FLYING,
SpriteIdMF.NAMIHE: EnemyType.WALL,
SpriteIdMF.FUNE: EnemyType.WALL,
SpriteIdMF.BLUE_ZORO: EnemyType.CRAWLING,
SpriteIdMF.GERUDA: EnemyType.FLYING,
SpriteIdMF.SKULTERA_LARGE: EnemyType.FLYING,
SpriteIdMF.SKULTERA_SMALL_ONLY: EnemyType.FLYING,
SpriteIdMF.SOVA: EnemyType.CRAWLING,
SpriteIdMF.YARD: EnemyType.CRAWLING,
SpriteIdMF.EVIR: EnemyType.FLYING,
SpriteIdMF.BULL: EnemyType.FLYING,
SpriteIdMF.MEMU: EnemyType.FLYING,
SpriteIdMF.GERUBOSS: EnemyType.CEILING,
SpriteIdMF.CHOOT: EnemyType.GROUND,
SpriteIdMF.ZEBESIAN_GROUND: EnemyType.GROUND,
SpriteIdMF.RIPPER: EnemyType.FLYING,
SpriteIdMF.RED_ZEELA: EnemyType.CRAWLING,
SpriteIdMF.OWTCH: EnemyType.CRAWLING,
SpriteIdMF.GENESIS: EnemyType.GROUND,
SpriteIdMF.PUYO: EnemyType.GROUND,
SpriteIdMF.FAKE_ENERGY_TANK: EnemyType.GROUND,
SpriteIdMF.FAKE_MISSILE_TANK: EnemyType.GROUND,
SpriteIdMF.ZEBESIAN_AQUA: EnemyType.FLYING,
SpriteIdMF.ZEBESIAN_PRE_AQUA: EnemyType.GROUND,
SpriteIdMF.SKULTERA_SMALL: EnemyType.FLYING,
SpriteIdMF.POWAMP: EnemyType.FLYING,
SpriteIdMF.ZOZORO: EnemyType.CRAWLING,
}
104 changes: 38 additions & 66 deletions src/mars_patcher/mf/constants/palettes.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from mars_patcher.rom import Game
from mars_patcher.mf.constants.sprites import SpriteIdMF

MF_TILESET_ALT_PAL_ROWS = {
0x46F134: 0xD, # 08
Expand Down Expand Up @@ -71,75 +71,47 @@
}


EXCLUDED_ENEMIES = {
Game.MF: {
0x11, # SA-X (elevator)
0x1D, # Area banner
0x21, # Message box
0x8C, # SA-X (TRO 1)
0x8D, # SA-X (NOC)
0xA0, # SA-X (ARC)
0xBC, # SA-X (lab)
0xC0, # SA-X (boss)
0xC1, # SA-X monster
0xC9, # SA-X (Omega cutscene)
0xCD, # SA-X (TRO 2)
},
Game.ZM: {
0x10, # Unused
0x11, # Item banner
0x8A, # Crocomire
},
EXCLUDED_ENEMIES_MF = {
SpriteIdMF.SAX_ELEVATOR,
SpriteIdMF.AREA_BANNER,
SpriteIdMF.MESSAGE_BANNER,
SpriteIdMF.SAX_TRO_1,
SpriteIdMF.SAX_NOC,
SpriteIdMF.SAX_ARC,
SpriteIdMF.SAX_LAB,
SpriteIdMF.SAX_BOSS,
SpriteIdMF.SAX_MONSTER,
SpriteIdMF.SAX_OMEGA,
SpriteIdMF.SAX_TRO_2,
}

ENEMY_GROUPS = {
Game.MF: {
"Zebesian": [0x14, 0x73, 0xA2, 0xB3, 0xB4],
"Zeela": [0x31, 0xA3],
"Sciser": [0x3C, 0x8B],
"BeamCoreX": [0x56, 0x57, 0x58, 0x59],
"Zoro": [0x5A, 0x63, 0x89, 0x8A],
"FakeTank": [0xAD, 0xAE],
},
Game.ZM: {
"Ripper": [0x16, 0x17, 0x71],
"Zeb": [0x18, 0x19],
"Skree": [0x1F, 0x20],
"ChozoStatue": [
0x22,
0x23,
0x24,
0x25,
0x26,
0x27,
0x28,
0x29,
0x2A,
0x2B,
0x2C,
0x2D,
0x2E,
0x2F,
0x30,
0x31,
0x58,
0x59,
0x94,
],
"Viola": [0x34, 0x68, 0x69],
"GerutaTangleVine": [0x36, 0x37, 0xB7, 0xB8, 0xB9, 0xBA],
"Reo": [0x3F, 0x40],
"Imago": [0x4D, 0x4F, 0x70, 0x7F, 0x86, 0x8B],
"SpacePirate": [0x51, 0x52, 0x53, 0x54, 0x55, 0xB6, 0xC6, 0xC7],
"Gamet": [0x56, 0x57, 0x9D, 0x9E],
"Zebbo": [0x5B, 0x5C, 0xA1, 0xA2],
"Rinka": [0x66, 0x7C, 0xA5, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD],
"Geega": [0x7A, 0x7B, 0x9F, 0xA0],
"ElevatorStatue": [0x95, 0x96],
"UnknownItemBlocks": [0xAA, 0xAB, 0xAC],
},

ENEMY_GROUPS_MF = {
"Zebesian": [
SpriteIdMF.ZEBESIAN_WALL,
SpriteIdMF.ZEBESIAN_GROUND,
SpriteIdMF.GOLD_ZEBESIAN,
SpriteIdMF.ZEBESIAN_AQUA,
SpriteIdMF.ZEBESIAN_PRE_AQUA,
],
"Zeela": [SpriteIdMF.ZEELA, SpriteIdMF.RED_ZEELA],
"Sciser": [SpriteIdMF.SCISER, SpriteIdMF.GOLD_SCISER],
"BeamCoreX": [
SpriteIdMF.CHARGE_BEAM_CORE_X,
SpriteIdMF.WIDE_BEAM_CORE_X,
SpriteIdMF.PLASMA_BEAM_CORE_X,
SpriteIdMF.WAVE_BEAM_CORE_X,
],
"Zoro": [
SpriteIdMF.ZORO,
SpriteIdMF.BLUE_ZORO,
SpriteIdMF.ZORO_COCOON,
SpriteIdMF.ZORO_HUSK,
],
"FakeTank": [SpriteIdMF.FAKE_ENERGY_TANK, SpriteIdMF.FAKE_MISSILE_TANK],
}


NETTORI_EXTRA_PALS = [
(0x36A480, 1), # Medium health palette
(0x36A4A0, 1), # Low health palette
Expand Down
71 changes: 71 additions & 0 deletions src/mars_patcher/mf/constants/sprites.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from enum import IntEnum


class SpriteIdMF(IntEnum):
SAX_ELEVATOR = 0x11
HORNOAD = 0x12
HALZYN = 0x13
ZEBESIAN_WALL = 0x14
HORNOAD_SPAWNER = 0x15
MOTO = 0x18
YAMEBA = 0x1B
AREA_BANNER = 0x1D
MESSAGE_BANNER = 0x21
SAMUS_EATER_BUD = 0x26
SAMUS_EATER = 0x27
ZEELA = 0x31
SKREE_UNUSED = 0x33
ZOMBIE = 0x37
GEEMER = 0x39
WAVER = 0x3B
SCISER = 0x3C
SIDEHOPPER = 0x3D
DESSGEEGA = 0x3E
ICE_BEAM_ABILITY = 0x4D
NETTORI = 0x54
CHARGE_BEAM_CORE_X = 0x56
WIDE_BEAM_CORE_X = 0x57
PLASMA_BEAM_CORE_X = 0x58
WAVE_BEAM_CORE_X = 0x59
ZORO = 0x5A
KIHUNTER_FLYING = 0x5B
KIHUNTER_GROUND = 0x5C
REO = 0x5E
NAMIHE = 0x60
FUNE = 0x61
BLUE_ZORO = 0x63
GERUDA = 0x64
SKULTERA_LARGE = 0x6A
SKULTERA_SMALL_ONLY = 0x6B
SOVA = 0x6C
YARD = 0x6D
EVIR = 0x6E
BULL = 0x6F
MEMU = 0x70
GERUBOSS = 0x71
CHOOT = 0x72
ZEBESIAN_GROUND = 0x73
RIPPER = 0x88
ZORO_COCOON = 0x89
ZORO_HUSK = 0x8A
GOLD_SCISER = 0x8B
SAX_TRO_1 = 0x8C
SAX_NOC = 0x8D
SAX_ARC = 0xA0
GOLD_ZEBESIAN = 0xA2
RED_ZEELA = 0xA3
OWTCH = 0xA4
GENESIS = 0xA8
PUYO = 0xA9
FAKE_ENERGY_TANK = 0xAD
FAKE_MISSILE_TANK = 0xAE
ZEBESIAN_AQUA = 0xB3
ZEBESIAN_PRE_AQUA = 0xB4
SKULTERA_SMALL = 0xB5
SAX_LAB = 0xBC
POWAMP = 0xBD
ZOZORO = 0xBE
SAX_BOSS = 0xC0
SAX_MONSTER = 0xC1
SAX_OMEGA = 0xC9
SAX_TRO_2 = 0xCD
17 changes: 15 additions & 2 deletions src/mars_patcher/random_enemies.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
import random
from typing import TYPE_CHECKING

from mars_patcher.constants.enemies import EnemyType
from mars_patcher.constants.game_data import spriteset_count, spriteset_ptrs
from mars_patcher.mf.constants.enemies import ENEMY_TYPES, EnemyType
from mars_patcher.mf.constants.enemies import ENEMY_TYPES_MF
from mars_patcher.mf.constants.game_data import sprite_vram_sizes
from mars_patcher.rom import Rom

if TYPE_CHECKING:
from mars_patcher.mf.constants.sprites import SpriteIdMF
from mars_patcher.zm.constants.sprites import SpriteIdZM


def randomize_enemies(rom: Rom) -> None:
# Setup enemy types dictionary
enemy_types = {k: v[1] for k, v in ENEMY_TYPES.items()}
_enemy_types: dict[SpriteIdMF, EnemyType] | dict[SpriteIdZM, EnemyType]
if rom.is_mf():
_enemy_types = ENEMY_TYPES_MF
elif rom.is_zm():
raise NotImplementedError("Enemey types not yet implemented for ZM")
else:
raise ValueError(rom.game)
enemy_types = {k.value: v for k, v in _enemy_types.items()}

# Get graphics info for each enemy
size_addr = sprite_vram_sizes(rom)
Expand Down
Loading