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
119 changes: 37 additions & 82 deletions source/fill.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ static void FastFill(std::vector<ItemKey> items, std::vector<LocationKey> locati
static void AssumedFill(const std::vector<ItemKey>& items, const std::vector<LocationKey>& allowedLocations, bool setLocationsAsHintable = false) {

if (items.size() > allowedLocations.size()) {
//If Tokensanity is on and RepeatableItemsOnTokens is off
//If NoRepeatOnTokens is on
//Don't display this message
if (NoRepeatOnTokens) {
//do nothing here to not display the message
Expand Down Expand Up @@ -444,9 +444,9 @@ static void AssumedFill(const std::vector<ItemKey>& items, const std::vector<Loc
retries--;
if (retries <= 0) {
placementFailure = true;
#ifdef ENABLE_DEBUG
#ifdef ENABLE_DEBUG
CitraPrint("Placement Failed");
#endif
#endif
return;
}

Expand Down Expand Up @@ -509,9 +509,8 @@ static void AssumedFill(const std::vector<ItemKey>& items, const std::vector<Loc
//retry if there are no more locations to place items
if (accessibleLocations.empty()) {

//If Tokensanity is on and RepeatableItemsOnTokens is off
//the item pool sent is much larger than the location pool
//in this case we just place 30 of the items and then move on
//If NoRepeatOnTokens is on then we don't want to retry,
//because the item pool is much larger than the location pool by design
if (NoRepeatOnTokens) {
//put back the last item we picked up
itemsToPlace.push_back(item);
Expand Down Expand Up @@ -542,63 +541,50 @@ static void AssumedFill(const std::vector<ItemKey>& items, const std::vector<Loc

LocationKey selectedLocation = RandomElement(accessibleLocations);

//If Tokensanity is on and RepeatableItemsOnTokens is off
//Only place non repeatable items
if (Tokensanity && !RepeatableItemsOnTokens) {
//If the item is repeatable put it back and try again
if (ItemTable(item).IsReusable() ) {
CitraPrint("Attempting to place Repeatable Item in SSH/OSH Location");
PlacementLog_Msg("\n Attempted to place Repeatable Item in SSH/OSH Loaction");
itemsToPlace.push_back(item);
}
else {
//Else place it and keep going
PlaceItemInLocation(selectedLocation, item);
attemptedLocations.push_back(selectedLocation);
//This tells us the location went through the randomization algorithm
//to distinguish it from locations which did not or that the player already
//knows
if (setLocationsAsHintable) {
Location(selectedLocation)->SetAsHintable();
}
//Else place it and keep going
PlaceItemInLocation(selectedLocation, item);
attemptedLocations.push_back(selectedLocation);
//This tells us the location went through the randomization algorithm
//to distinguish it from locations which did not or that the player already
//knows
if (setLocationsAsHintable) {
Location(selectedLocation)->SetAsHintable();
}

//If ALR is off, then we check beatability after placing the item.
//If the game is beatable, then we can stop placing items with logic.
if (!LocationsReachable) {
playthroughBeatable = false;
Logic::LogicReset();
GetAccessibleLocations(allLocations, SearchMode::CheckBeatable);
if (playthroughBeatable) {
FastFill(itemsToPlace, GetAllEmptyLocations(), true);
return;
}
}
//If ALR is off, then we check beatability after placing the item.
//If the game is beatable, then we can stop placing items with logic.
if (!LocationsReachable) {
playthroughBeatable = false;
Logic::LogicReset();
GetAccessibleLocations(allLocations, SearchMode::CheckBeatable);
if (playthroughBeatable) {
FastFill(itemsToPlace, GetAllEmptyLocations(), true);
return;
}
}
else {

//place the item within one of the allowed locations accounting for if this item needs to be able to be obtained more than once and if location allows that
//the only situation we don't want is a non repeatable location with a reusable item
if ( !(Location(selectedLocation)->IsRepeatable()) && ItemTable(item).IsReusable() ){
//unsuccessfulPlacement = true;
#ifdef ENABLE_DEBUG
CitraPrint("Attempting to place repeatable item in non repeatable spot in AssumedFill");
#endif
PlacementLog_Msg("\n Attempted to place " + ItemTable(item).GetName().GetNAEnglish() + " at " + Location(selectedLocation)->GetName());
itemsToPlace.push_back(item);
}
else {
//unsuccessfulPlacement = true;
#ifdef ENABLE_DEBUG
CitraPrint("Attempting to place repeatable item in non repeatable spot in AssumedFill");
#endif
PlacementLog_Msg("\n Attempted to place " + ItemTable(item).GetName().GetNAEnglish() + " at " + Location(selectedLocation)->GetName());
itemsToPlace.push_back(item);
}
else {
PlaceItemInLocation(selectedLocation, item);
//PlacementLog_Msg("Placed " + ItemTable(item).GetName().GetNAEnglish() + " at " + Location(selectedLocation)->GetName());
//CitraPrint("Placed " + ItemTable(item).GetName().GetNAEnglish() + " at " + Location(selectedLocation)->GetName());
attemptedLocations.push_back(selectedLocation);

//This tells us the location went through the randomization algorithm
//to distinguish it from locations which did not or that the player already
//knows
if (setLocationsAsHintable) {
Location(selectedLocation)->SetAsHintable();
}

//If ALR is off, then we check beatability after placing the item.
//If the game is beatable, then we can stop placing items with logic.
if (!LocationsReachable) {
Expand All @@ -613,7 +599,8 @@ static void AssumedFill(const std::vector<ItemKey>& items, const std::vector<Loc
}
}
}
} while (unsuccessfulPlacement);
}
while (unsuccessfulPlacement);
}

//This function will specifically randomize dungeon rewards for the End of Dungeons
Expand Down Expand Up @@ -900,7 +887,6 @@ int Fill() {
#ifdef ENABLE_DEBUG
CitraPrint("Trying to place songs");
#endif
//Place Songs before inventory to prevent song locations from being used
//get Songs in pool
std::vector<ItemKey> songs = FilterAndEraseFromPool(ItemPool, [](const ItemKey i) {return ItemTable(i).GetItemType() == ITEMTYPE_SONG;});
//If Shuffled in Song Locations restrict location pool to only song locations
Expand All @@ -926,6 +912,7 @@ int Fill() {
// Ensure Ocarina and Song of Time are obtainable with the current placement.
// If they are not reachable with currently placed items (Rewards, Keys, etc.),
// we place additional advancement items from the pool to open paths until they are reachable.
// but only if the logic setting is not set to "None" (No Logic).
if (((StartingOcarina.Value<u8>() == 0) || ShuffleSongOfTime) && Settings::Logic.IsNot(LogicSetting::LOGIC_NONE)) {
while (true) {
Logic::LogicReset();
Expand Down Expand Up @@ -1041,38 +1028,6 @@ int Fill() {

AssumedFill(gfItems, gfLocations, true);
}
//Then if repeatable items on tokens is off -- fill token spots with nonrepeatable items
if (Tokensanity && !RepeatableItemsOnTokens){
//Set Variable to not mess with fill algorithm
NoRepeatOnTokens = true;
//Get SSH locations
std::vector<LocationKey> SwampSkullLocations = FilterFromPool(allLocations, [](const LocationKey loc) {return Location(loc)->IsCategory(Category::cSwampSkulltula);});
//Get NonRepeatItems
std::vector<ItemKey> NonRepeatItems = FilterAndEraseFromPool(ItemPool, [](const ItemKey i) {return !ItemTable(i).IsReusable();});
//fill SSH spots with nonrepeatableitems
AssumedFill(NonRepeatItems, SwampSkullLocations, true);

//Get OSH locations
std::vector<LocationKey> OceanSkullLocations = FilterFromPool(allLocations, [](const LocationKey loc1) {return Location(loc1)->IsCategory(Category::cOceanSkulltula);});
//Get NonRepeatItems
std::vector<ItemKey> NonRepeatItems2 = FilterAndEraseFromPool(ItemPool, [](const ItemKey i) {return !ItemTable(i).IsReusable();});
//CitraPrint("Items in NonRepeatItems2:\n");
//fill OSH spots with NonRepeatableItems
AssumedFill(NonRepeatItems2, OceanSkullLocations, true);
//Set Variable back to false to go back to normal filling
NoRepeatOnTokens = false;

//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
//Do this before continuing as the pool of accessable locations is smaller after filling all skulltula locations
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);

//get the rest of the repeatable items and fill them in -- may not be needed?
//std::vector<ItemKey> remainingRepeatItems = FilterAndEraseFromPool(ItemPool, [](const ItemKey i) {return ItemTable(i).IsReusable();});
//CitraPrint("Starting Fill of remaining Repeat Items");
//AssumedFill(remainingRepeatItems, allLocations,true);
}

//Place Main Inventory First
//So first get all items in the pool + DekuMask,
Expand Down
6 changes: 6 additions & 0 deletions source/hint_list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,12 @@ void HintTable_Init() {
}, //clear
Text{"a progressive magic power", "une amélioration d'énergie magique", "un poder mágico progresivo"}
);
hintTable[PROGRESSIVE_LULLABY] = HintText::Item({
//obscure
Text{"a progressive lullaby", "une berceuse progressive", "una canción de cuna progresiva"}
}, //clear
Text{"a progressive lullaby", "une berceuse progressive", "una canción de cuna progresiva"}
);
//PROGRESSIVE_BOMBCHUS
//BOTTLE ITEMS
hintTable[EMPTY_BOTTLE] = HintText::Item({
Expand Down
1 change: 1 addition & 0 deletions source/include/keys.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ typedef enum {
PROGRESSIVE_WALLET,
PROGRESSIVE_MAGIC_METER,
PROGRESSIVE_BOMBCHUS,
PROGRESSIVE_LULLABY,

//Keys just used for Logic
RAZOR_SWORD,
Expand Down
1 change: 1 addition & 0 deletions source/include/logic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ namespace Logic {
extern u8 ProgressiveWallet;
extern u8 ProgressiveBombBag;
extern u8 ProgressiveSword;
extern u8 ProgressiveLullaby;
//Keys
extern u8 WoodfallTempleKeys;
extern u8 SnowheadTempleKeys;
Expand Down
1 change: 0 additions & 1 deletion source/include/settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,6 @@ namespace Settings {
extern std::vector<Option*> gameOptions;
extern Menu gameSettings;

extern Option RepeatableItemsOnTokens;
extern std::vector<Menu *> shuffleItemsMenu;

}
Expand Down
1 change: 1 addition & 0 deletions source/item_list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ void ItemTable_Init() { //repeatable denotes that an item in a vanilla playth
itemTable[PROGRESSIVE_BOW] = Item(true, false, &ProgressiveBow, Text{"Progressive Bow", "Arc (prog.)", "Arco progresivo", }, PROGRESSIVE_BOW, 0x47, ITEMTYPE_ITEM);
itemTable[PROGRESSIVE_WALLET] = Item(true, false, &ProgressiveWallet, Text{"Progressive Wallet", "Bourse (prog.)", "Bolsa de rupias progresiva", }, PROGRESSIVE_WALLET, 0x48, ITEMTYPE_ITEM);
itemTable[PROGRESSIVE_MAGIC_METER] = Item(true, false, &ProgressiveMagic, Text{"Progressive Magic Meter", "Jauge de magie (prog)", "Poder mágico progresivo", "", "Capacité de magie (prog.)", "" }, PROGRESSIVE_MAGIC_METER, 0x49, ITEMTYPE_GFAIRY);
itemTable[PROGRESSIVE_LULLABY] = Item(true, false, &ProgressiveLullaby, Text{"Progressive Lullaby", "Berceuse (prog.)", "Canción de cuna progresiva", "", "Berceuse (prog.)", "" }, PROGRESSIVE_LULLABY, 0x45, ITEMTYPE_SONG);

itemTable[MAJORAS_MASK] = Item(true, false, &noVariable, Text{"Majora's Mask", "Masque de Majora", "Máscara de Majora", }, MAJORAS_MASK, (u32)GetItemID::GI_ERROR_NOTHING_40, ITEMTYPE_EVENT);
itemTable[HINT] = Item(true, true, &noVariable, Text{"Hint", "Indice", "Pista", }, HINT, (u32)GetItemID::GI_ERROR_NOTHING_40, ITEMTYPE_EVENT);
Expand Down
Loading