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
53 changes: 52 additions & 1 deletion source/custom_messages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ void CreateBaselineCustomMessages() {
// Woodfall
CreateMessageFromTextObject(0x6137, 0x003E, 0x3FFFFFFF, 0xFF0000,
GITextIntroMap + GITextDungeonWoodfall,
{QM_GREEN, QM_GREEN}, {}, {}, 0x0, false, false);
{QM_GREEN, QM_WHITE}, {}, {}, 0x0, false, false);

// Snowhead
CreateMessageFromTextObject(0x6138, 0x003E, 0x3FFFFFFF, 0xFF0000,
Expand Down Expand Up @@ -345,6 +345,57 @@ void CreateBaselineCustomMessages() {
},
{QM_BLUE, QM_RED}, {}, {}, 0x0, false, false);

//Bank Rewards
CreateMessage(0x045c, 0xFFFF, 0x3FFFFFFF, 0xFF0000,
{"What's this? You've already saved up #500 Rupees#!?! Well, little guy, here's your special gift. Take it!",
// French
"Vous avez déjà économisé #500 Rubis#?! Bon, petit, voici votre cadeau spécial. Prenez-le!",
},
{QM_RED}, {}, {}, 0x0, false, false);

CreateMessage(0x045d, 0xFFFF, 0x3FFFFFFF, 0xFF0000,
{"What's this? You've already saved up #1,000 Rupees#?! Well, little guy, I can't take any more deposits. Sorry, but this is all I can give you.",
// French
"Vous avez déjà économisé #1000 Rubis#?! Bon, petit, je ne peux plus accepter de dépôts. Désolé, mais c'est tout ce que je peux vous donner.",
},
{QM_RED}, {}, {}, 0x0, false, false);

//Stray Fairies
CreateMessage(0x06144, 0xFFFF, 0x3FFFFFFF, 0xFF0000,
{"You got the #Clock Town Stray Fairy#! Bring it to the Fairy Fountain in North Clock Town!",
// French
"Vous obtenez une #Fée Perdue de Clock Town#! Apporte-le à la Fontaine des Fées, dans le Quartier Nord de Bourg-Clocher!",
},
{QM_RED}, {}, {}, 0x0, false, false);

CreateMessage(0x06145, 0xFFFF, 0x3FFFFFFF, 0xFF0000,
{"You got a #Woodfall Stray Fairy#! &You have collected #=WFF#.",
// French
"Vous obtenez une #Fée Perdue de la forêt#!&Vous en avez désormais #=WFF#.",
},
{QM_GREEN, QM_RED}, {}, {}, 0x0, false, false);

CreateMessage(0x06146, 0xFFFF, 0x3FFFFFFF, 0xFF0000,
{"You got a #Snowhead Stray Fairy#! &You have collected #=SHF#.",
// French
"Vous obtenez une #Fée Perdue des neiges#!&Vous en avez désormais #=SHF#.",
},
{QM_MAGENTA, QM_RED}, {}, {}, 0x0, false, false);

CreateMessage(0x06147, 0xFFFF, 0x3FFFFFFF, 0xFF0000,
{"You got a #Great Bay Stray Fairy#! &You have collected #=GBF#.",
// French
"Vous obtenez une #Fée Perdue de la baie#!&Vous en avez désormais #=GBF#.",
},
{QM_BLUE, QM_RED}, {}, {}, 0x0, false, false);

CreateMessage(0x06148, 0xFFFF, 0x3FFFFFFF, 0xFF0000,
{"You got a #Stone Tower Stray Fairy#! &You have collected #=STF#.",
// French
"Vous obtenez une #Fée Perdue d'Ikana#!&Vous en avez désormais #=STF#.",
},
{QM_YELLOW, QM_RED}, {}, {}, 0x0, false, false);

}

u32 NumMessages() {
Expand Down
4 changes: 2 additions & 2 deletions source/dungeon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ void DungeonInfo::PlaceVanillaBossKey() {
auto bossKeyLocation = FilterFromPool(dungeonLocations, [](const LocationKey loc) { return Location(loc)->IsCategory(Category::cVanillaBossKey); })[0];
PlaceItemInLocation(bossKeyLocation, bossKey);
}
/*

void DungeonInfo::PlaceVanillaSwampToken() {
auto dungeonLocations = GetDungeonLocations();
auto tokenLocations = FilterFromPool(dungeonLocations, [](const LocationKey loc){return Location(loc)->IsCategory(Category::cSwampSkulltula);});
Expand Down Expand Up @@ -115,7 +115,7 @@ void DungeonInfo::PlaceVanillaSTStray() {
PlaceItemInLocation(location, ST_STRAY_FAIRY);
}
}
*/

void DungeonInfo::PlaceVanillaSmallKeys() {
if (smallKey == NONE) {
return;
Expand Down
136 changes: 67 additions & 69 deletions source/fill.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,17 +642,11 @@ static void RandomizeOwnDungeon(const Dungeon::DungeonInfo* dungeon) {
std::vector<LocationKey> dungeonLocations = dungeon->GetDungeonLocations();
std::vector<ItemKey> dungeonItems;

//filter out locations that may be required to have songs placed at them

dungeonLocations = FilterFromPool(dungeonLocations, [](const LocationKey loc) {
//if (ShuffleSongs.Is(rnd::SongShuffleSetting::SONGSHUFFLE_SONG_LOCATIONS)) {
return !(Location(loc)->IsCategory(Category::cSong)) && !(Location(loc)->IsCategory(Category::cDungeonReward));
//}
//if (ShuffleSongs.Is(rnd::SongShuffleSetting::SONGSHUFFLE_DUNGEON_REWARDS)) {
// return !(Location(loc)->IsCategory(Category::cDungeonReward));
//}
// true;
});
if (ShuffleSongs.Value<u8>() == 1 /*Song Locations*/) {
std::vector<LocationKey> songLocations = FilterFromPool(allLocations, [](const LocationKey loc) { return Location(loc)->IsCategory(Category::cSong);});
std::vector<ItemKey> songs = FilterAndEraseFromPool(ItemPool, [](const ItemKey i) { return ItemTable(i).GetItemType() == ITEMTYPE_SONG;});
AssumedFill(songs, songLocations, true);
}
/*
PlacementLog_Msg("\nAllowed Locations are: \n");
CitraPrint("Allowed Locations are:");
Expand All @@ -673,8 +667,30 @@ static void RandomizeOwnDungeon(const Dungeon::DungeonInfo* dungeon) {
AddElementsToPool(dungeonItems, dungeonBossKey);
}

if (StrayFairysanity.Value<u8>() == 2 /* Own Dungeon*/)
{
if (dungeon->GetName() == "Woodfall Temple") {
auto strayFairy = FilterAndEraseFromPool(ItemPool, [dungeon](const ItemKey i) {return i == WF_STRAY_FAIRY;});
AddElementsToPool(dungeonItems, strayFairy);
}
else if (dungeon->GetName() == "Snowhead Temple") {
auto strayFairy = FilterAndEraseFromPool(ItemPool, [dungeon](const ItemKey i) {return i == SH_STRAY_FAIRY;});
AddElementsToPool(dungeonItems, strayFairy);
}
else if (dungeon->GetName() == "Great Bay Temple") {
auto strayFairy = FilterAndEraseFromPool(ItemPool, [dungeon](const ItemKey i) {return i == GBT_STRAY_FAIRY;});
AddElementsToPool(dungeonItems, strayFairy);
}
else if (dungeon->GetName() == "Stone Tower Temple") {
auto strayFairy = FilterAndEraseFromPool(ItemPool, [dungeon](const ItemKey i) {return i == ST_STRAY_FAIRY;});
AddElementsToPool(dungeonItems, strayFairy);
}

}
//randomize boss key and small keys together for even distribution
NoRepeatOnTokens = true;
AssumedFill(dungeonItems, dungeonLocations, true);
NoRepeatOnTokens = false;

//randomize map and compass separately since they're not progressive
if (MapsAndCompasses.Is((u8)MapsAndCompassesSetting::MAPSANDCOMPASSES_OWN_DUNGEON) && dungeon->GetMap() != NONE && dungeon->GetCompass() != NONE) {
Expand Down Expand Up @@ -720,7 +736,42 @@ static void RandomizeDungeonItems() {
auto bossKey = FilterAndEraseFromPool(ItemPool, [dungeon](const ItemKey i) {return i == dungeon->GetBossKey();});
AddElementsToPool(overworldItems, bossKey);
}

if (StrayFairysanity.Value<u8>() == 3/*Any Dungeon*/) {
if (dungeon->GetName() == "Woodfall Temple") {
auto strayFairy = FilterAndEraseFromPool(ItemPool, [dungeon](const ItemKey i) {return i == WF_STRAY_FAIRY;});
AddElementsToPool(anyDungeonItems, strayFairy);
}
else if (dungeon->GetName() == "Snowhead Temple") {
auto strayFairy = FilterAndEraseFromPool(ItemPool, [dungeon](const ItemKey i) {return i == SH_STRAY_FAIRY;});
AddElementsToPool(anyDungeonItems, strayFairy);
}
else if (dungeon->GetName() == "Great Bay Temple") {
auto strayFairy = FilterAndEraseFromPool(ItemPool, [dungeon](const ItemKey i) {return i == GBT_STRAY_FAIRY;});
AddElementsToPool(anyDungeonItems, strayFairy);
}
else if (dungeon->GetName() == "Stone Tower Temple") {
auto strayFairy = FilterAndEraseFromPool(ItemPool, [dungeon](const ItemKey i) {return i == ST_STRAY_FAIRY;});
AddElementsToPool(anyDungeonItems, strayFairy);
}
}
else if (StrayFairysanity.Value<u8>() == 4/*Overworld*/) {
if (dungeon->GetName() == "Woodfall Temple") {
auto strayFairy = FilterAndEraseFromPool(ItemPool, [dungeon](const ItemKey i) {return i == WF_STRAY_FAIRY;});
AddElementsToPool(overworldItems, strayFairy);
}
else if (dungeon->GetName() == "Snowhead Temple") {
auto strayFairy = FilterAndEraseFromPool(ItemPool, [dungeon](const ItemKey i) {return i == SH_STRAY_FAIRY;});
AddElementsToPool(overworldItems, strayFairy);
}
else if (dungeon->GetName() == "Great Bay Temple") {
auto strayFairy = FilterAndEraseFromPool(ItemPool, [dungeon](const ItemKey i) {return i == GBT_STRAY_FAIRY;});
AddElementsToPool(overworldItems, strayFairy);
}
else if (dungeon->GetName() == "Stone Tower Temple") {
auto strayFairy = FilterAndEraseFromPool(ItemPool, [dungeon](const ItemKey i) {return i == ST_STRAY_FAIRY;});
AddElementsToPool(overworldItems, strayFairy);
}
}
}

const std::array<ItemKey, 4> dungeonRewards = {
Expand All @@ -744,8 +795,10 @@ static void RandomizeDungeonItems() {
}

//Randomize Any Dungeon and Overworld pools
NoRepeatOnTokens = true;
AssumedFill(anyDungeonItems, anyDungeonLocations, true);
AssumedFill(overworldItems, overworldLocations, true);
NoRepeatOnTokens = false;

//Randomize maps and compasses after since they're not advancement items
for (auto dungeon : dungeonList) {
Expand Down Expand Up @@ -818,40 +871,6 @@ int VanillaFill() {
return 1;
}

int NoLogicFill() {
// CitraPrint("StartingNoLogicFill\n");
AreaTable_Init(); //Reset the world graph to intialize the proper locations
ItemReset(); //Reset shops incase of shopsanity random
GenerateLocationPool();
GenerateItemPool();
GenerateStartingInventory();
RemoveStartingItemsFromPool();
FillExcludedLocations();
RandomizeDungeonRewards();
std::vector<ItemKey> remainingPool = FilterAndEraseFromPool(ItemPool, [](const ItemKey i) {return true;});
FastFill(remainingPool, GetAllEmptyLocations(), false);
GeneratePlaythrough();
printf("Done");
printf("\x1b[9;10HCalculating Playthrough... ");
PareDownPlaythrough();
printf("Done");
printf("\x1b[10;10HCalculating Way of the Hero...");
CalculateWotH();
printf("Done");
// CitraPrint("Creating Item Overrides");
CreateItemOverrides();
// CreateEntranceOverrides();
// CreateAlwaysIncludedMessages();
if (GossipStoneHints.IsNot(rnd::GossipStoneHintsSetting::HINTS_NO_HINTS)) {
printf("\x1b[11;10HCreating Hints...");
CreateAllHints();
printf("Done");
}

return 1;
}


int Fill() {
CustomMessages::CreateBaselineCustomMessages();

Expand All @@ -871,6 +890,7 @@ int Fill() {
GenerateStartingInventory();
RemoveStartingItemsFromPool();
FillExcludedLocations();
PlaceItemInLocation(S_CLOCK_TOWN_CLOCK_TOWER_ENTRANCE, WOODFALL_TEMPLE_SMALL_KEY);

showItemProgress = true;

Expand Down Expand Up @@ -1035,11 +1055,7 @@ int Fill() {
//Then Place those to expand the amount of checks available
AssumedFill(mainadvancementItems, allLocations,true);

//Then Place Anju & Kafei Items in spots accessable on Day 1, this should prevent situations where you cant get an item in time for its use
std::vector<LocationKey> day1Locations = FilterFromPool(allLocations, [](const LocationKey loc) {return Location(loc)->IsCategory(Category::cDayOne);});
std::vector<ItemKey> anjukafeiitems = FilterAndEraseFromPool(ItemPool, [](const ItemKey i) {return ItemTable(i).GetItemType() == ITEMTYPE_QUEST;});
AssumedFill(anjukafeiitems, day1Locations,true);

//Then place the rest of the repeatable items in locations marked as repeatable
std::vector<LocationKey> repeatableItemLocations = FilterFromPool(allLocations, [](const LocationKey loc) {return Location(loc)->IsRepeatable();});
std::vector<ItemKey> remainingRepeatItemPool = FilterAndEraseFromPool(ItemPool, [](const ItemKey i) {return ItemTable(i).IsReusable();});
AssumedFill(remainingRepeatItemPool, repeatableItemLocations, true);
Expand All @@ -1049,24 +1065,6 @@ int Fill() {
std::vector<ItemKey> dekuTrades = FilterAndEraseFromPool(ItemPool, [](const ItemKey i) {return ItemTable(i).GetItemType() == ITEMTYPE_TRADE;});
AssumedFill(dekuTrades, allLocations);
} */

//Then Place songs if song shuffle is set to specific locations
/*
if (ShuffleSongs.IsNot(SongShuffleSetting::SONGSHUFFLE_ANYWHERE)) {

//Get each song
std::vector<ItemKey> songs = FilterAndEraseFromPool(ItemPool, [](const ItemKey i) { return ItemTable(i).GetItemType() == ITEMTYPE_SONG;});

//Get each song location
std::vector<LocationKey> songLocations;
if (ShuffleSongs.Is(SongShuffleSetting::SONGSHUFFLE_SONG_LOCATIONS)) {
songLocations = FilterFromPool(allLocations, [](const LocationKey loc) { return Location(loc)->IsCategory(Category::cSong);});
}
else if (ShuffleSongs.Is(SongShuffleSetting::SONGSHUFFLE_ANYWHERE)) {
songLocations = allLocations;
}
AssumedFill(songs, songLocations, true);
}*/

//Then place Link's Pocket Item if it has to be an advancement item
//Links Pocket is useless as there is no unobtainable check due to a certain time travel sword pedistal
Expand Down
Loading