Add Super Mario 64 (PC Port) to Archipelago (#207)
* Add Super Mario 64
This commit is contained in:
parent
b4ad0ebf52
commit
23211dd1ee
|
@ -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.
|
|
@ -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.
|
|
@ -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": [
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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}
|
|
@ -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
|
||||||
|
}
|
|
@ -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)
|
|
@ -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)
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue