Skip to content

Commit

Permalink
Fix shuffling, logic bugs, remove messy debug prints
Browse files Browse the repository at this point in the history
  • Loading branch information
21aslade committed Jul 2, 2019
1 parent c030975 commit 299635c
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 25 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

This program aims to randomize the item locations in such a way that all items are be available. This works sometimes, but currently is rather bugged.

It's currently in early development; it likely will silently fail randomization and be broken until you reload the ROM.
It's currently in early development; it likely will fail randomization and be broken until you reload the ROM.
When it's finished to the point that it can randomize the entire game without failing often, it'll be set up on a website similar to other popular randomizers.

Logic only goes up to the Cave of Flames currently; in the future it'll be extended to cover the whole game.
Expand Down
8 changes: 2 additions & 6 deletions Randomizer/Dependency.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ public static List<Dependency> GetDependencies(string logic)
default:
string[] splitSequence = sequence.Split(':');
string requirement = splitSequence[0];
Console.WriteLine($"It's {requirement}");
string dungeon = "";
int count = 1;

Expand All @@ -60,8 +59,6 @@ public static List<Dependency> GetDependencies(string logic)

string[] dependencyParts = requirement.Split('.');

Console.WriteLine($"It's also {dependencyParts[1]}");

if (dependencyParts.Length < 2)
{
break;
Expand Down Expand Up @@ -123,6 +120,7 @@ public override bool DependencyFulfilled(List<Item> availableItems, List<Locatio
int counter = 0;
foreach (Item item in availableItems)
{

if (item.Type == RequiredItem.Type && item.SubValue == RequiredItem.SubValue && (RequiredItem.Dungeon == "" || RequiredItem.Dungeon == item.Dungeon))
{
counter++;
Expand All @@ -132,7 +130,6 @@ public override bool DependencyFulfilled(List<Item> availableItems, List<Locatio
}
}
}

return false;
}
}
Expand All @@ -154,8 +151,7 @@ public override bool DependencyFulfilled(List<Item> availableItems, List<Locatio
return location.IsAccessible(availableItems, locations);
}
}
Console.WriteLine($"Could not find location: {RequiredLocationName}");
return false;
throw new ShuffleException($"Could not find location {RequiredLocationName}. You may have an invalid logic file!");
}
}

Expand Down
18 changes: 14 additions & 4 deletions Randomizer/Location.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ public enum LocationType
NPCItem,
KinstoneItem,
HeartPieceItem,
JabberNonsense,
Split,
Helper,
//StartingItem,
PurchaseItem,
Expand Down Expand Up @@ -190,7 +190,7 @@ public void WriteLocation(Writer w)
case LocationType.Helper:
case LocationType.Untyped:
return;
case LocationType.JabberNonsense:
case LocationType.Split:
w.WriteByte((byte)Contents.Type, Address);
w.WriteByte(Contents.SubValue, Address + 2);
break;
Expand Down Expand Up @@ -235,14 +235,18 @@ public Item GetItemContents()

switch (Type)
{
case LocationType.JabberNonsense:
case LocationType.Split:
type = (ItemType)ROM.Instance.reader.ReadByte(Address);
subType = ROM.Instance.reader.ReadByte(Address + 2);
break;
case LocationType.PurchaseItem:
type = (ItemType)ROM.Instance.reader.ReadByte(Address);
subType = 0x00;
break;
case LocationType.ScrollItem:
type = (ItemType)(ROM.Instance.reader.ReadByte(Address) & 0x7F);
subType = 0;
break;
default:
type = (ItemType)ROM.Instance.reader.ReadByte(Address);
subType = ROM.Instance.reader.ReadByte();
Expand Down Expand Up @@ -317,13 +321,19 @@ public void InvalidateCache()

public void Fill(Item contents)
{
SetItem(contents);
Contents = contents;
Filled = true;
}

public void SetItem(Item contents)
{
Contents = contents;
DefaultContents = contents;
}

public void SetDefaultContents()
{
Contents = DefaultContents;
}
}
}
28 changes: 23 additions & 5 deletions Randomizer/Shuffler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@

namespace MinishRandomizer.Randomizer
{
public class ShuffleException : Exception {
public ShuffleException(string message) : base(message) { }
}

public readonly struct Item
{
public readonly ItemType Type;
Expand Down Expand Up @@ -127,7 +131,7 @@ public void LoadLocations(string locationFile)
DungeonItems.Add(newLocation.Contents);
break;
case Location.LocationType.Major:
case Location.LocationType.JabberNonsense:
case Location.LocationType.Split:
case Location.LocationType.PurchaseItem:
case Location.LocationType.ScrollItem:
default:
Expand Down Expand Up @@ -160,6 +164,8 @@ public void PatchRom(string locationFile)

public void RandomizeLocations()
{
ResetLocations();

List<Item> unplacedItems = MajorItems.ToList();
List<Item> dungeonSpecificItems = DungeonItems.ToList();

Expand All @@ -180,7 +186,7 @@ public void RandomizeLocations()

if (unfilledLocations.Count != 0)
{
Console.WriteLine("Not all locations filled!");
throw new ShuffleException($"There are {unfilledLocations.Count} unfilled locations!");
}

using (MemoryStream ms = new MemoryStream(ROM.Instance.romData))
Expand All @@ -195,6 +201,16 @@ public void RandomizeLocations()
File.WriteAllBytes(OutputDirectory + "/mcrando.gba", ROM.Instance.romData);
}

private void ResetLocations()
{
foreach (Location location in Locations)
{
location.SetDefaultContents();
location.InvalidateCache();
location.Filled = false;
}
}

// Based off of the RandomAssumed ALttPR filler
private List<Location> FillLocations(List<Item> items, List<Location> locations, List<Item> assumedItems = null, List<Location> previousLocations = null)
{
Expand All @@ -217,6 +233,10 @@ private List<Location> FillLocations(List<Item> items, List<Location> locations,
int itemIndex = RNG.Next(items.Count);
Item item = items[itemIndex];
Console.WriteLine($"Placing: {item.Type.ToString()}");
if (item.Dungeon != "")
{
Console.WriteLine($"Dungeon: {item.Dungeon}");
}

items.RemoveAt(itemIndex);

Expand All @@ -233,9 +253,7 @@ private List<Location> FillLocations(List<Item> items, List<Location> locations,

if (availableLocations.Count <= 0)
{
Console.WriteLine($"Could not place {item.Type.ToString()}!");
return null;
//throw new Exception($"Could not place {item.Type.ToString()}!");
throw new ShuffleException($"Could not place {item.Type}");
}

int locationIndex = RNG.Next(availableLocations.Count);
Expand Down
24 changes: 16 additions & 8 deletions Resources/default.logic
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,29 @@ IntroItem1; Major; F252B;; Items.SmithSword
IntroItem2; Major; F253B;; Items.Shield
SouthKeeseCave; Minor; 32-13-00; Items.BombBag
HyruleWellRight; Minor; 41-00-04
SwiftbladeFirst; ScrollItem; 110D7B;
SwiftbladeFirst; ScrollItem; 110D7B; Helpers.HasSword

BottleScrub; PurchaseItem; 0CC0C0; Items.Shield, Items.BombBag, Helpers.HasSword#, Items.SpinAttack
BottleScrub; PurchaseItem; 0CC0C0; Items.Shield, Items.BombBag, Helpers.HasSword, Items.SpinAttack

# Minish Woods Locations
AccessMinishWoods; Helper;; (|Helpers.HasSword, Items.BombBag)
JabberNut; JabberNonsense; 09498C; Locations.AccessMinishWoods
JabberNut; Split; 09498C; Locations.AccessMinishWoods
BelariBombs; Major; 00A00C; Locations.AccessMinishWoods

# Mount Crenel Locations
AccessCrenel; Helper;; Helpers.HasBottle, (|Items.BombBag, Items.GripRing), Helpers.HasSword#, Items.SpinAttack
CrenelLowerScrub; PurchaseItem; 0CC09C; Helpers.HasBottle, Items.Shield # Technically a Crenel item, but doesn't need bombs
AccessCrenel; Helper;; Helpers.HasBottle, (|Items.BombBag, Items.GripRing), Helpers.HasSword, Items.SpinAttack
#CrenelLowerScrub; PurchaseItem; 0CC09C; Helpers.HasBottle, Items.Shield # Technically a Crenel item, but doesn't need bombs
CrenelVineHole; Minor; 35-00-00; Locations.AccessCrenel, (|Items.GustJar, Items.BombBag)
CrenelMinishHouse; Minor; 27-03-00; Locations.AccessCrenel, (|Items.GustJar, Items.BombBag)
CrenelCaveDownstairs; Minor; 26-07-00; Locations.AccessCrenel, Items.BombBag
CrenelHeartCaveLeft; Minor; 26-08-00; Locations.AccessCrenel, Items.BombBag
CrenelHeartCaveRight; Minor; 26-08-01; Locations.AccessCrenel, Items.BombBag
CrenelGripScrub; PurchaseItem; 0CC0A8; Locations.AccessCrenel, Items.Shield, Items.BombBag
CrenelBlockChest; Minor; 26-03-00; Locations.AccessCrenel, (|Items.PacciCane, (&Items.GripRing, (|Items.GustJar, Items.LightArrow)))
Melari; Major; 00D26E; Locations.CompleteCoF

# Castor Wilds Locations
AccessWilds; Helper;;

# Deepwood locations
DeepwoodAccess:Deepwood; Helper;; Locations.AccessMinishWoods, Items.JabberNut
Expand All @@ -52,8 +56,8 @@ DeepwoodStatueRoom:Deepwood; DungeonItem; 48-04-01; Locations.DeepwoodAccess, It
DeepwoodWestWing:Deepwood; DungeonItem; 48-05-01; Locations.DeepwoodAccess, Items.SmallKey:Deepwood
DeepwoodPreBarrel:Deepwood; Minor; 48-06-01; Locations.DeepwoodAccess, (|Items.GustJar, Items.BombBag), Items.SmallKey:Deepwood
DeepwoodSlugTorches:Deepwood; DungeonItem; 48-10-01; Locations.DeepwoodAccess
DeepwoodBasementNorth:Deepwood; DungeonItem; 48-11-01; Locations.DeepwoodAccess, (|Items.GustJar, (&Items.Flippers, Helpers.HasSword)), Items.SmallKey:Deepwood:3
DeepwoodBasementSwitch:Deepwood; DungeonItem; 48-12-01; Locations.DeepwoodAccess, (|(&Items.GustJar, Items.SmallKey:Deepwood), (&Items.SmallKey:Deepwood:2, (|Items.Flippers, Items.RocsCape)))
DeepwoodBasementNorth:Deepwood; DungeonItem; 48-11-01; Locations.DeepwoodAccess, Items.GustJar, Items.SmallKey:Deepwood:3
DeepwoodBasementSwitch:Deepwood; DungeonItem; 48-12-01; Locations.DeepwoodAccess, (|(&Items.GustJar, Items.SmallKey:Deepwood), (&Items.SmallKey:Deepwood:2, Items.RocsCape))
DeepwoodBasementEast:Deepwood; DungeonItem; 48-12-02; Locations.DeepwoodAccess, (|(&Items.GustJar, Items.SmallKey:Deepwood), Items.SmallKey:Deepwood:2)
DeepwoodUpstairsChest:Deepwood; Minor; 48-17-01; Locations.DeepwoodAccess, (|Items.GustJar, Items.LanternOff)
CompleteDeepwood:Deepwood; Helper;; Locations.DeepwoodAccess, Items.GustJar, Helpers.HasSword, Items.BigKey:Deepwood
Expand All @@ -73,4 +77,8 @@ CoFSpinies:FlameCave; DungeonItem; 50-15-00; Locations.CoFAccess
CoFBasementLava1:FlameCave; Minor; 50-17-00; Locations.CoFAccess, Items.PacciCane, Items.SmallKey:FlameCave:2
CoFBasementLava2:FlameCave; Minor; 50-17-01; Locations.CoFAccess, Items.PacciCane, Items.SmallKey:FlameCave:2
CoFBasementLavaBig:FlameCave; DungeonItem; 50-17-02; Locations.CoFAccess, Items.PacciCane, Items.SmallKey:FlameCave:2
CompleteCoF:FlameCave; Helper;; Locations.CoFAccess, Items.PacciCane, Items.SmallKey:FlameCave:2, Items.BigKey:FlameCave
CompleteCoF:FlameCave; Helper;; Locations.CoFAccess, Items.PacciCane, Items.SmallKey:FlameCave:2, Items.BigKey:FlameCave

# Fortress of Winds Locations
#FortressAccess:Fortress; Helper;; Locations.AccessWilds
#FortressPrize:Prizes; Major; 09C9E6
9 changes: 8 additions & 1 deletion UI/MainWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,14 @@ private void Randomize_Click(object sender, EventArgs e)
return;
}

shuffler.RandomizeLocations();
try
{
shuffler.RandomizeLocations();
}
catch (ShuffleException error)
{
MessageBox.Show(error.Message);
}
}

private void LoadRom()
Expand Down

1 comment on commit 299635c

@21aslade
Copy link
Member

Choose a reason for hiding this comment

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

Still breaks cause filling things is dumb

Please sign in to comment.