Add Super Mario 64 (PC Port) to Archipelago (#207)

* Add Super Mario 64
This commit is contained in:
Yussur Mustafa Oraji 2022-01-23 21:34:30 +01:00 committed by GitHub
parent b4ad0ebf52
commit 23211dd1ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 660 additions and 0 deletions

View File

@ -0,0 +1,28 @@
# Super Mario 64 EX
## Where is the settings page?
The player settings page for this game contains all the options you need to configure and export a config file. Player
settings page link: [SM64EX Player Settings Page](../player-settings).
## What does randomization do to this game?
All 120 Stars, the 3 Cap Switches, the Cellar and Secound Floor Key are now Location Checks and may contain Items for different games as well
as different Items from within SM64.
## What is the goal of SM64EX when randomized?
As in most Mario Games, save the Princess!
## Which items can be in another player's world?
Any of the 120 Stars, and the two Caste Keys. Additionally, Cap Switches are also considered "Items" and the "!"-Boxes will only be active
when someone collects the corresponding Cap Switch Item.
## What does another world's item look like in SM64EX?
The Items are visually unchanged, though after collecting a Message will pop up to inform you what you collected,
and who will receive it.
## When the player receives an item, what happens?
When you receive an Item, a Message will pop up to inform you where you received the Item from,
and which one it is.
NOTE: The Secret Star count in the Menu is broken.

View File

@ -0,0 +1,79 @@
# Super Mario 64 EX MultiWorld Setup Guide
## Required Software
- Super Mario 64 US Rom (Japanese may work also. Europe and Shindou not supported)
- Either of [sm64pclauncher](https://github.com/N00byKing/sm64pclauncher/actions/workflows/ci.yml?query=branch%3Aarchipelago+event%3Apush) or
- Cloning and building [sm64ex](https://github.com/N00byKing/sm64ex) manually.
NOTE: The above linked sm64pclauncher is a special version designed to work with the Archipelago build of sm64ex.
You can use other sm64-port based builds with it, but you can't use a different launcher with the Archipelago build of sm64ex.
## Installation and Game Start Procedures
# Installation via sm64pclauncher (For Windows)
First, install [MSYS](https://www.msys2.org/) as described on the page.
Then follow the steps below
1. Go to the page linked for sm64pclauncher, and press on the topmost entry
3. Scroll down, and download the zip file
4. Unpack the zip file in an empty folder
5. Run the Launcher and press build.
6. Set the location where you installed MSYS when prompted. Check the "Install Dependencies" Checkbox
7. Set the Repo link to `https://github.com/N00byKing/sm64ex` and the Branch to `archipelago` (Top two boxes). You can choose the folder (Secound Box) at will, as long as it does not exist yet
8. Point the Launcher to your Super Mario 64 US/JP Rom, and set the Region correspondingly
9. Set Build Options. Recommended: `-jn` where `n` is the Number of CPU Cores, to build faster.
10. SM64EX will now be compiled. The Launcher will appear to have crashed, but this is not likely the case. Best wait a bit, but there may be a problem if it takes longer than 10 Minutes
After it's done, the Build list should have another entry titled with what you named the folder in step 7.
NOTE: For some reason first start of the game always crashes the launcher. Just restart it.
If it still crashes, recheck if you typed the launch options correctly (Described in "Joining a MultiWorld Game")
# Manual Compilation (Linux/Windows)
Dependencies for Linux: `sdl2 glew cmake python make`.
Dependencies for Windows: `mingw-w64-x86_64-gcc mingw-w64-x86_64-glew mingw-w64-x86_64-SDL2 git make python3 cmake`
SM64EX will link `jsoncpp` dynamic if installed. If not, it will compile and link statically.
1. Clone `https://github.com/N00byKing/sm64ex` recursively
2. Enter `sm64ex` and copy your Rom to `baserom.REGION.z64` where `REGION` is either `us` or `jp` respectively.
3. Compile with `make`. For faster compilation set the parameter `-jn` where `n` is the Number of CPU Cores.
The Compiled binary will be in `build/REGION_pc/`.
# Joining a MultiWorld Game
To join, set the following launch options: `--sm64ap_name YourName --sm64ap_ip ServerIP:Port`.
Optionally, add `--sm64ap_passwd "YourPassword"` if the room you are using requires a password. All parameters without quotation marks.
The Name in this case is the one specified in your generated .yaml file.
In case you are using the Archipelago Website, the IP should be `archipelago.gg` and Port `38281`.
If everything worked out, you will see a textbox informing you the connection has been established after the story intro.
## Installation Troubleshooting
Start the game from the command line to view helpful messages regarding SM64EX.
### Game doesn't start after compiling
Most likely you forgot to set the launch options. `--sm64ap_name YourName` and `--sm64ap_ip ServerIP:Port` are required for startup.
## Game Troubleshooting
### Known Issues
When using a US Rom, the In-Game messages are missing some letters: `J Q V X Z` and `?`.
The Japanese Version should have no problem displaying these.
### What happens if I lose connection?
SM64EX tries to reconnect a few times, so be patient.
Should the problem still be there after about a minute or two, just save and restart the game.
### How do I update the Game to a new Build?
When manually compiling just pull in changes and run `make` again. Sometimes it helps to run `make clean` before.
When using the Launcher follow the normal build steps, but when choosing a folder name use the same as before. Then continue as normal.

View File

@ -442,6 +442,25 @@
} }
] ]
}, },
{
"gameTitle": "Super Mario 64 EX",
"tutorials": [
{
"name": "Multiworld Setup Guide",
"description": "A guide to setting up SM64EX for MultiWorld.",
"files": [
{
"language": "English",
"filename": "sm64ex/setup_en.md",
"link": "sm64ex/setup/en",
"authors": [
"N00byKing"
]
}
]
}
]
},
{ {
"gameTitle": "VVVVVV", "gameTitle": "VVVVVV",
"tutorials": [ "tutorials": [

13
worlds/sm64ex/Items.py Normal file
View File

@ -0,0 +1,13 @@
from BaseClasses import Item
class SM64Item(Item):
game: str = "Super Mario 64"
item_table = {
"Star": 3626000,
"Cellar Key": 3626178,
"Second Floor Key": 3626179,
"Wing Cap": 3626180,
"Metal Cap": 3626181,
"Vanish Cap": 3626182
}

211
worlds/sm64ex/Locations.py Normal file
View File

@ -0,0 +1,211 @@
from BaseClasses import Location
class SM64Location(Location):
game: str = "Super Mario 64"
#Bob-omb Battlefield
locBoB_table = {
"Big Bob-Omb on the Summit": 3626000,
"Footrace with Koopa The Quick": 3626001,
"Shoot to the Island in the Sky": 3626002,
"Find the 8 Red Coins": 3626003,
"Mario Wings to the Sky": 3626004,
"Behind Chain Chomps Gate": 3626005
}
#Whomp's Fortress
locWhomp_table = {
"Chip Off Whomp's Block": 3626007,
"To the Top of the Fortress": 3626008,
"Shoot into the Wild Blue": 3626009,
"Red Coins on the Floating Isle": 3626010,
"Fall onto the Caged Island": 3626011,
"Blast Away the Wall": 3626012
}
#Jolly Roger Bay
locJRB_table = {
"Plunder in the Sunken Ship": 3626014,
"Can the Eel Come Out to Play?": 3626015,
"Treasure of the Ocean Cave": 3626016,
"Red Coins on the Ship Afloat": 3626017,
"Blast to the Stone Pillar": 3626018,
"JRB: Through the Jet Stream": 3626019 # Prefix due to duplicate name
}
#Cool, Cool Mountain
locCCM_table = {
"Slip Slidin' Away": 3626021,
"Li'l Penguin Lost": 3626022,
"Big Penguin Race": 3626023,
"Frosty Slide for 8 Red Coins": 3626024,
"Snowman's Lost His Head": 3626025,
"Wall Kicks Will Work": 3626026
}
#Big Boo's Haunt
locBBH_table = {
"Go on a Ghost Hunt": 3626028,
"Ride Big Boo's Merry-Go-Round": 3626029,
"Secret of the Haunted Books": 3626030,
"Seek the 8 Red Coins": 3626031,
"Big Boo's Balcony": 3626032,
"Eye to Eye in the Secret Room": 3626033
}
#Hazy Maze Cave
locHMC_table = {
"Swimming Beast in the Cavern": 3626035,
"Elevate for 8 Red Coins": 3626036,
"Metal-Head Mario Can Move!": 3626037,
"Navigating the Toxic Maze": 3626038,
"A-Maze-Ing Emergency Exit": 3626039,
"Watch for Rolling Rocks": 3626040
}
#Lethal Lava Land
locLLL_table = {
"Boil the Big Bully": 3626042,
"Bully the Bullies": 3626043,
"8-Coin Puzzle with 15 Pieces": 3626044,
"Red-Hot Log Rolling": 3626045,
"Hot-Foot-It into the Volcano": 3626046,
"Elevator Tour in the Volcano": 3626047
}
#Shifting Sand Land
locSSL_table = {
"In the Talons of the Big Bird": 3626049,
"Shining Atop the Pyramid": 3626050,
"Inside the Ancient Pyramid": 3626051,
"Stand Tall on the Four Pillars": 3626052,
"Free Flying for 8 Red Coins": 3626053,
"Pyramid Puzzle": 3626054
}
#Dire, Dire Docks
locDDD_table = {
"Board Bowser's Sub": 3626056,
"Chests in the Current": 3626057,
"Pole-Jumping for Red Coins": 3626058,
"DDD: Through the Jet Stream": 3626059, # Prefix due to duplicate name
"The Manta Ray's Reward": 3626060,
"Collect the Caps...": 3626061
}
#Snowman's Land
locSL_table = {
"Snowman's Big Head": 3626063,
"Chill with the Bully": 3626064,
"In the Deep Freeze": 3626065,
"Whirl from the Freezing Pond": 3626066,
"Shell Shreddin' for Red Coins": 3626067,
"Into the Igloo": 3626068
}
#Wet-Dry World
locWDW_table = {
"Shocking Arrow Lifts!": 3626070,
"Top o' the Town": 3626071,
"Secrets in the Shallows & Sky": 3626072,
"Express Elevator--Hurry Up!": 3626073,
"Go to Town for Red Coins": 3626074,
"Quick Race Through Downtown!": 3626075
}
#Tall, Tall Mountain
locTTM_table = {
"Scale the Mountain": 3626077,
"Mystery of the Monkey Cage": 3626078,
"Scary 'Shrooms, Red Coins": 3626079,
"Mysterious Mountainside": 3626080,
"Breathtaking View from Bridge": 3626081,
"Blast to the Lonely Mushroom": 3626082
}
#Tiny-Huge Island
locTHI_table = {
"Pluck the Piranha Flower": 3626084,
"The Tip Top of the Huge Island": 3626085,
"Rematch with Koopa the Quick": 3626086,
"Five Itty Bitty Secrets": 3626087,
"Wiggler's Red Coins": 3626088,
"Make Wiggler Squirm": 3626089
}
#Tick Tock Clock
locTTC_table = {
"Roll into the Cage": 3626091,
"The Pit and the Pendulums": 3626092,
"Get a Hand": 3626093,
"Stomp on the Thwomp": 3626094,
"Timed Jumps on Moving Bars": 3626095,
"Stop Time for Red Coins": 3626096
}
#Rainbow Ride
locRR_table = {
"Cruiser Crossing the Rainbow": 3626098,
"The Big House in the Sky": 3626099,
"Coins Amassed in a Maze": 3626100,
"Swingin' in the Breeze": 3626101,
"Tricky Triangles!": 3626102,
"Somewhere Over the Rainbow": 3626103
}
loc100Coin_table = {
"BoB 100 Coins": 3626006,
"Whomp 100 Coins": 3626013,
"JRB 100 Coins": 3626020,
"CCM 100 Coins": 3626027,
"BBH 100 Coins": 3626034,
"HMC 100 Coins": 3626041,
"LLL 100 Coins": 3626048,
"SSL 100 Coins": 3626055,
"DDD 100 Coins": 3626062,
"SL 100 Coins": 3626069,
"WDW 100 Coins": 3626076,
"TTM 100 Coins": 3626083,
"THI 100 Coins": 3626090,
"TTC 100 Coins": 3626097,
"RR 100 Coins": 3626104
}
#Secret Stars and Stages
locSS_table = {
"Bowser in the Dark World Red Coins": 3626105,
"Bowser in the Fire Sea Red Coins": 3626112,
"Bowser in the Sky Red Coins": 3626119,
"The Princess's Secret Slide Box": 3626126,
"The Princess's Secret Slide Fast": 3626127,
"Cavern of the Metal Cap Red Coins": 3626133,
"Tower of the Wing Cap Red Coins": 3626140,
"Vanish Cap Under the Moat Red Coins": 3626147,
"Wing Mario Over the Rainbow Red Coins": 3626154,
"The Secret Aquarium": 3626161,
"Toad (Cellar)": 3626168,
"Toad (Second Floor)": 3626169,
"Toad (Third Floor)": 3626170,
"MIPS 1": 3626171,
"MIPS 2": 3626172
}
#Keys
locKey_table = {
"Cellar Key": 3626178,
"Second Floor Key": 3626179
}
#Caps
locCap_table = {
"Wing Cap Switch": 3626180,
"Metal Cap Switch": 3626181,
"Vanish Cap Switch": 3626182
}
# Correspond to 3626000 + course index * 7 + star index, then secret stars, then keys, then 100 Coin Stars
location_table = {**locBoB_table,**locWhomp_table,**locJRB_table,**locCCM_table,**locBBH_table, \
**locHMC_table,**locLLL_table,**locSSL_table,**locDDD_table,**locSL_table, \
**locWDW_table,**locTTM_table,**locTHI_table,**locTTC_table,**locRR_table, \
**loc100Coin_table,**locSS_table,**locKey_table,**locCap_table}

22
worlds/sm64ex/Options.py Normal file
View File

@ -0,0 +1,22 @@
import typing
from Options import Option, DefaultOnToggle, Range
class EnableCoinStars(DefaultOnToggle):
"""Disable to Ignore 100 Coin Stars. You can still collect them, but they don't do anything"""
displayname = "Enable 100 Coin Stars"
class StrictCapRequirements(DefaultOnToggle):
"""If disabled, Stars that expect special caps may have to be acquired without the caps"""
displayname = "Strict Cap Requirements"
class StarsToFinish(Range):
"""How many stars are required at the infinite stairs"""
range_start = 50
range_end = 100
default = 70
sm64_options: typing.Dict[str,type(Option)] = {
"EnableCoinStars": EnableCoinStars,
"StrictCapRequirements": StrictCapRequirements,
"StarsToFinish": StarsToFinish
}

140
worlds/sm64ex/Regions.py Normal file
View File

@ -0,0 +1,140 @@
import typing
from BaseClasses import MultiWorld, Region, Entrance, Location, RegionType
from .Locations import SM64Location, location_table,locBoB_table,locWhomp_table,locJRB_table,locCCM_table,locBBH_table, \
locHMC_table,locLLL_table,locSSL_table,locDDD_table,locSL_table, \
locWDW_table,locTTM_table,locTHI_table,locTTC_table,locRR_table, \
locSS_table, locKey_table, locCap_table
def create_regions(world: MultiWorld, player: int):
regSS = Region("Menu", RegionType.Generic, "Castle Area", player, world)
locSS_names = [name for name, id in locSS_table.items()]
locSS_names += [name for name, id in locKey_table.items()]
locSS_names += [name for name, id in locCap_table.items()]
regSS.locations += [SM64Location(player, loc_name, location_table[loc_name], regSS) for loc_name in locSS_names]
world.regions.append(regSS)
regBoB = Region("Bob-omb Battlefield", RegionType.Generic, "Bob-omb Battlefield", player, world)
locBoB_names = [name for name, id in locBoB_table.items()]
regBoB.locations += [SM64Location(player, loc_name, location_table[loc_name], regBoB) for loc_name in locBoB_names]
if (world.EnableCoinStars[player].value):
regBoB.locations.append(SM64Location(player, "BoB 100 Coins", location_table["BoB 100 Coins"], regBoB))
world.regions.append(regBoB)
regWhomp = Region("Whomp's Fortress", RegionType.Generic, "Whomp's Fortress", player, world)
locWhomp_names = [name for name, id in locWhomp_table.items()]
regWhomp.locations += [SM64Location(player, loc_name, location_table[loc_name], regWhomp) for loc_name in locWhomp_names]
if (world.EnableCoinStars[player].value):
regWhomp.locations.append(SM64Location(player, "Whomp 100 Coins", location_table["Whomp 100 Coins"], regWhomp))
world.regions.append(regWhomp)
regJRB = Region("Jolly Roger Bay", RegionType.Generic, "Jolly Roger Bay", player, world)
locJRB_names = [name for name, id in locJRB_table.items()]
regJRB.locations += [SM64Location(player, loc_name, location_table[loc_name], regJRB) for loc_name in locJRB_names]
if (world.EnableCoinStars[player].value):
regJRB.locations.append(SM64Location(player, "JRB 100 Coins", location_table["JRB 100 Coins"], regJRB))
world.regions.append(regJRB)
regCCM = Region("Cool, Cool Mountain", RegionType.Generic, "Cool, Cool Mountain", player, world)
locCCM_names = [name for name, id in locCCM_table.items()]
regCCM.locations += [SM64Location(player, loc_name, location_table[loc_name], regCCM) for loc_name in locCCM_names]
if (world.EnableCoinStars[player].value):
regCCM.locations.append(SM64Location(player, "CCM 100 Coins", location_table["CCM 100 Coins"], regCCM))
world.regions.append(regCCM)
regBBH = Region("Big Boo's Haunt", RegionType.Generic, "Big Boo's Haunt", player, world)
locBBH_names = [name for name, id in locBBH_table.items()]
regBBH.locations += [SM64Location(player, loc_name, location_table[loc_name], regBBH) for loc_name in locBBH_names]
if (world.EnableCoinStars[player].value):
regBBH.locations.append(SM64Location(player, "BBH 100 Coins", location_table["BBH 100 Coins"], regBBH))
world.regions.append(regBBH)
regCellar = Region("Cellar", RegionType.Generic, "Cellar", player, world)
world.regions.append(regCellar)
regHMC = Region("Hazy Maze Cave", RegionType.Generic, "Hazy Maze Cave", player, world)
locHMC_names = [name for name, id in locHMC_table.items()]
regHMC.locations += [SM64Location(player, loc_name, location_table[loc_name], regHMC) for loc_name in locHMC_names]
if (world.EnableCoinStars[player].value):
regHMC.locations.append(SM64Location(player, "HMC 100 Coins", location_table["HMC 100 Coins"], regHMC))
world.regions.append(regHMC)
regLLL = Region("Lethal Lava Land", RegionType.Generic, "Lethal Lava Land", player, world)
locLLL_names = [name for name, id in locLLL_table.items()]
regLLL.locations += [SM64Location(player, loc_name, location_table[loc_name], regLLL) for loc_name in locLLL_names]
if (world.EnableCoinStars[player].value):
regLLL.locations.append(SM64Location(player, "LLL 100 Coins", location_table["LLL 100 Coins"], regLLL))
world.regions.append(regLLL)
regSSL = Region("Shifting Sand Land", RegionType.Generic, "Shifting Sand Land", player, world)
locSSL_names = [name for name, id in locSSL_table.items()]
regSSL.locations += [SM64Location(player, loc_name, location_table[loc_name], regSSL) for loc_name in locSSL_names]
if (world.EnableCoinStars[player].value):
regSSL.locations.append(SM64Location(player, "SSL 100 Coins", location_table["SSL 100 Coins"], regSSL))
world.regions.append(regSSL)
regDDD = Region("Dire, Dire Docks", RegionType.Generic, "Dire, Dire Docks", player, world)
locDDD_names = [name for name, id in locDDD_table.items()]
regDDD.locations += [SM64Location(player, loc_name, location_table[loc_name], regDDD) for loc_name in locDDD_names]
if (world.EnableCoinStars[player].value):
regDDD.locations.append(SM64Location(player, "DDD 100 Coins", location_table["DDD 100 Coins"], regDDD))
world.regions.append(regDDD)
regFloor2 = Region("Second Floor", RegionType.Generic, "Second Floor", player, world)
world.regions.append(regFloor2)
regSL = Region("Snowman's Land", RegionType.Generic, "Snowman's Land", player, world)
locSL_names = [name for name, id in locSL_table.items()]
regSL.locations += [SM64Location(player, loc_name, location_table[loc_name], regSL) for loc_name in locSL_names]
if (world.EnableCoinStars[player].value):
regSL.locations.append(SM64Location(player, "SL 100 Coins", location_table["SL 100 Coins"], regSL))
world.regions.append(regSL)
regWDW = Region("Wet-Dry World", RegionType.Generic, "Wet-Dry World", player, world)
locWDW_names = [name for name, id in locWDW_table.items()]
regWDW.locations += [SM64Location(player, loc_name, location_table[loc_name], regWDW) for loc_name in locWDW_names]
if (world.EnableCoinStars[player].value):
regWDW.locations.append(SM64Location(player, "WDW 100 Coins", location_table["WDW 100 Coins"], regWDW))
world.regions.append(regWDW)
regTTM = Region("Tall, Tall Mountain", RegionType.Generic, "Tall, Tall Mountain", player, world)
locTTM_names = [name for name, id in locTTM_table.items()]
regTTM.locations += [SM64Location(player, loc_name, location_table[loc_name], regTTM) for loc_name in locTTM_names]
if (world.EnableCoinStars[player].value):
regTTM.locations.append(SM64Location(player, "TTM 100 Coins", location_table["TTM 100 Coins"], regTTM))
world.regions.append(regTTM)
regTHI = Region("Tiny-Huge Island", RegionType.Generic, "Tiny-Huge Island", player, world)
locTHI_names = [name for name, id in locTHI_table.items()]
regTHI.locations += [SM64Location(player, loc_name, location_table[loc_name], regTHI) for loc_name in locTHI_names]
if (world.EnableCoinStars[player].value):
regTHI.locations.append(SM64Location(player, "THI 100 Coins", location_table["THI 100 Coins"], regTHI))
world.regions.append(regTHI)
regFloor3 = Region("Third Floor", RegionType.Generic, "Third Floor", player, world)
world.regions.append(regFloor3)
regTTC = Region("Tick Tock Clock", RegionType.Generic, "Tick Tock Clock", player, world)
locTTC_names = [name for name, id in locTTC_table.items()]
regTTC.locations += [SM64Location(player, loc_name, location_table[loc_name], regTTC) for loc_name in locTTC_names]
if (world.EnableCoinStars[player].value):
regTTC.locations.append(SM64Location(player, "TTC 100 Coins", location_table["TTC 100 Coins"], regTTC))
world.regions.append(regTTC)
regRR = Region("Rainbow Ride", RegionType.Generic, "Rainbow Ride", player, world)
locRR_names = [name for name, id in locRR_table.items()]
regRR.locations += [SM64Location(player, loc_name, location_table[loc_name], regRR) for loc_name in locRR_names]
if (world.EnableCoinStars[player].value):
regRR.locations.append(SM64Location(player, "RR 100 Coins", location_table["RR 100 Coins"], regRR))
world.regions.append(regRR)
def connect_regions(world: MultiWorld, player: int, source: str, target: str, rule):
sourceRegion = world.get_region(source, player)
targetRegion = world.get_region(target, player)
connection = Entrance(player,'', sourceRegion)
connection.access_rule = rule
sourceRegion.exits.append(connection)
connection.connect(targetRegion)

89
worlds/sm64ex/Rules.py Normal file
View File

@ -0,0 +1,89 @@
import typing
from ..generic.Rules import add_rule
from .Regions import connect_regions
def set_rules(world,player):
connect_regions(world, player, "Menu", "Bob-omb Battlefield", lambda state: True)
connect_regions(world, player, "Menu", "Whomp's Fortress", lambda state: state.has("Star", player, 1))
connect_regions(world, player, "Menu", "Jolly Roger Bay", lambda state: state.has("Star", player, 3))
connect_regions(world, player, "Menu", "Cool, Cool Mountain", lambda state: state.has("Star", player, 3))
connect_regions(world, player, "Menu", "Big Boo's Haunt", lambda state: state.has("Star", player, 12))
connect_regions(world, player, "Menu", "Cellar", lambda state: state.has("Cellar Key", player))
connect_regions(world, player, "Cellar", "Menu", lambda state: True)
connect_regions(world, player, "Cellar", "Hazy Maze Cave", lambda state: True)
connect_regions(world, player, "Cellar", "Lethal Lava Land", lambda state: True)
connect_regions(world, player, "Cellar", "Shifting Sand Land", lambda state: True)
connect_regions(world, player, "Cellar", "Dire, Dire Docks", lambda state: state.has("Star", player, 30))
connect_regions(world, player, "Menu", "Second Floor", lambda state: state.has("Second Floor Key", player))
connect_regions(world, player, "Second Floor", "Menu", lambda state: True)
connect_regions(world, player, "Second Floor", "Snowman's Land", lambda state: True)
connect_regions(world, player, "Second Floor", "Wet-Dry World", lambda state: True)
connect_regions(world, player, "Second Floor", "Tall, Tall Mountain", lambda state: True)
connect_regions(world, player, "Second Floor", "Tiny-Huge Island", lambda state: True)
connect_regions(world, player, "Second Floor", "Third Floor", lambda state: state.has("Star", player, 50))
connect_regions(world, player, "Third Floor", "Second Floor", lambda state: True)
connect_regions(world, player, "Third Floor", "Tick Tock Clock", lambda state: True)
connect_regions(world, player, "Third Floor", "Rainbow Ride", lambda state: True)
connect_regions(world, player, "Bob-omb Battlefield", "Menu", lambda state: True)
connect_regions(world, player, "Whomp's Fortress", "Menu", lambda state: True)
connect_regions(world, player, "Jolly Roger Bay", "Menu", lambda state: True)
connect_regions(world, player, "Cool, Cool Mountain", "Menu", lambda state: True)
connect_regions(world, player, "Big Boo's Haunt", "Menu", lambda state: True)
connect_regions(world, player, "Hazy Maze Cave", "Cellar", lambda state: True)
connect_regions(world, player, "Lethal Lava Land", "Cellar", lambda state: True)
connect_regions(world, player, "Shifting Sand Land", "Cellar", lambda state: True)
connect_regions(world, player, "Dire, Dire Docks", "Cellar", lambda state: True)
connect_regions(world, player, "Snowman's Land", "Second Floor", lambda state: True)
connect_regions(world, player, "Wet-Dry World", "Second Floor", lambda state: True)
connect_regions(world, player, "Tall, Tall Mountain", "Second Floor", lambda state: True)
connect_regions(world, player, "Tiny-Huge Island", "Second Floor", lambda state: True)
connect_regions(world, player, "Tick Tock Clock", "Second Floor", lambda state: True)
connect_regions(world, player, "Rainbow Ride", "Second Floor", lambda state: True)
#Special Rules for some Locations
add_rule(world.get_location("Wing Cap Switch", player), lambda state: state.has("Star", player, 10))
add_rule(world.get_location("Metal Cap Switch", player), lambda state: state.can_reach("Cellar", 'Region', player))
add_rule(world.get_location("Vanish Cap Switch", player), lambda state: state.can_reach("Cellar", 'Region', player))
add_rule(world.get_location("Eye to Eye in the Secret Room", player), lambda state: state.has("Vanish Cap", player))
add_rule(world.get_location("Collect the Caps...", player), lambda state: state.has("Metal Cap", player) and
state.has("Vanish Cap", player))
add_rule(world.get_location("Into the Igloo", player), lambda state: state.has("Vanish Cap", player))
add_rule(world.get_location("Quick Race Through Downtown!", player), lambda state: state.has("Vanish Cap", player))
if (world.StrictCapRequirements[player].value):
add_rule(world.get_location("Mario Wings to the Sky", player), lambda state: state.has("Wing Cap", player))
add_rule(world.get_location("Metal-Head Mario Can Move!", player), lambda state: state.has("Metal Cap", player))
add_rule(world.get_location("JRB: Through the Jet Stream", player), lambda state: state.has("Metal Cap", player))
add_rule(world.get_location("Free Flying for 8 Red Coins", player), lambda state: state.has("Wing Cap", player))
add_rule(world.get_location("DDD: Through the Jet Stream", player), lambda state: state.has("Metal Cap", player))
add_rule(world.get_location("Vanish Cap Under the Moat Red Coins", player), lambda state: state.has("Vanish Cap", player))
#Rules for Secret Stars
add_rule(world.get_location("Bowser in the Dark World Red Coins", player), lambda state: state.has("Star", player, 8))
add_rule(world.get_location("Bowser in the Fire Sea Red Coins", player), lambda state: state.can_reach("Cellar",'Region',player) and state.has("Star", player, 30))
add_rule(world.get_location("Bowser in the Sky Red Coins", player), lambda state: state.can_reach("Third Floor",'Region',player) and state.has("Star", player, world.StarsToFinish[player].value))
add_rule(world.get_location("The Princess's Secret Slide Box", player), lambda state: state.has("Star", player, 1))
add_rule(world.get_location("The Princess's Secret Slide Fast", player), lambda state: state.has("Star", player, 1))
add_rule(world.get_location("Cavern of the Metal Cap Red Coins", player), lambda state: state.can_reach("Metal Cap Switch", 'Location', player) and state.has("Metal Cap", player))
add_rule(world.get_location("Tower of the Wing Cap Red Coins", player), lambda state: state.can_reach("Wing Cap Switch", 'Location', player))
add_rule(world.get_location("Vanish Cap Under the Moat Red Coins", player), lambda state: state.can_reach("Vanish Cap Switch", 'Location', player))
add_rule(world.get_location("Wing Mario Over the Rainbow Red Coins", player), lambda state: state.can_reach("Third Floor", 'Region', player) and state.has("Wing Cap", player))
add_rule(world.get_location("The Secret Aquarium", player), lambda state: state.can_reach("Jolly Roger Bay", 'Region', player))
add_rule(world.get_location("Toad (Cellar)", player), lambda state: state.can_reach("Cellar",'Region',player))
add_rule(world.get_location("Toad (Second Floor)", player), lambda state: state.can_reach("Second Floor",'Region',player))
add_rule(world.get_location("Toad (Third Floor)", player), lambda state: state.can_reach("Third Floor",'Region',player))
add_rule(world.get_location("MIPS 1", player), lambda state: state.can_reach("Cellar",'Region',player) and state.has("Star", player, 15))
add_rule(world.get_location("MIPS 2", player), lambda state: state.can_reach("Cellar",'Region',player) and state.has("Star", player, 50))
#Rules for Keys
add_rule(world.get_location("Cellar Key", player), lambda state: state.has("Star", player, 8))
add_rule(world.get_location("Second Floor Key", player), lambda state: state.can_reach("Cellar", 'Region', player) and state.has("Star", player, 30))
world.completion_condition[player] = lambda state: state.can_reach("Third Floor",'Region',player) and state.has("Star", player, world.StarsToFinish[player].value)

59
worlds/sm64ex/__init__.py Normal file
View File

@ -0,0 +1,59 @@
import string
from .Items import item_table, SM64Item
from .Locations import location_table, SM64Location
from .Options import sm64_options
from .Rules import set_rules
from .Regions import create_regions
from BaseClasses import Region, RegionType, Entrance, Item, MultiWorld
from ..AutoWorld import World
client_version = 1
class SM64World(World):
"""
dude do be jumping
"""
game: str = "Super Mario 64"
topology_present = False
item_name_to_id = item_table
location_name_to_id = location_table
data_version = 1
forced_auto_forfeit = False
options = sm64_options
def create_regions(self):
create_regions(self.world,self.player)
def set_rules(self):
set_rules(self.world,self.player)
def create_item(self, name: str) -> Item:
item_id = item_table[name]
item = SM64Item(name, True, item_id, self.player)
return item
def generate_basic(self):
staritem = self.create_item("Star")
if (self.world.EnableCoinStars[self.player].value):
self.world.itempool += [staritem for i in range(0,120)]
else:
self.world.itempool += [staritem for i in range(0,105)]
key1 = self.create_item("Cellar Key")
key2 = self.create_item("Second Floor Key")
self.world.itempool += [key1,key2]
wingcap = self.create_item("Wing Cap")
metalcap = self.create_item("Metal Cap")
vanishcap = self.create_item("Vanish Cap")
self.world.itempool += [wingcap,metalcap,vanishcap]
def fill_slot_data(self):
return {
"StarsToFinish": self.world.StarsToFinish[self.player].value
}