mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-08-21 06:48:39 -04:00
Progressive BGS (#7037)
This commit is contained in:
@@ -182,7 +182,11 @@ void GenerateItemPool() {
|
||||
AddFixedItemToPool(RG_PROGRESSIVE_HOOKSHOT, 2 - ctx->GetOption(RSK_STARTING_HOOKSHOT).Get());
|
||||
if (!ctx->GetOption(RSK_STARTING_HYLIAN_SHIELD)) AddItemToPool(RG_HYLIAN_SHIELD, 1, 1, 1, 1);
|
||||
AddItemToPool(RG_DOUBLE_DEFENSE, 2, 1, 0, 0);
|
||||
if (ctx->GetOption(RSK_STARTING_BIGGORON_SWORD).IsNot(RO_STARTING_BGS_BIGGORON_SWORD)) {
|
||||
if (ctx->GetOption(RSK_PROGRESSIVE_GORON_SWORD)) {
|
||||
int startGoronSword = ctx->GetOption(RSK_STARTING_BIGGORON_SWORD).Get();
|
||||
AddItemToPool(RG_PROGRESSIVE_GORONSWORD, std::max(0, 3 - startGoronSword), std::max(0, 2 - startGoronSword),
|
||||
std::max(0, 2 - startGoronSword), std::max(0, 1 - startGoronSword));
|
||||
} else if (ctx->GetOption(RSK_STARTING_BIGGORON_SWORD).IsNot(RO_STARTING_BGS_BIGGORON_SWORD)) {
|
||||
AddItemToPool(RG_BIGGORON_SWORD, 2, 1, 1, 0);
|
||||
}
|
||||
bool isScrubs = ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_ALL);
|
||||
@@ -527,7 +531,7 @@ void GenerateItemPool() {
|
||||
|
||||
if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) ||
|
||||
ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)) {
|
||||
if (/*!ProgressiveGoronSword TODO: Implement Progressive Goron Sword*/
|
||||
if (!ctx->GetOption(RSK_PROGRESSIVE_GORON_SWORD) &&
|
||||
ctx->GetOption(RSK_STARTING_BIGGORON_SWORD).Is(RO_STARTING_BGS_OFF)) {
|
||||
AddFixedItemToPool(RG_GIANTS_KNIFE, 1);
|
||||
}
|
||||
@@ -538,7 +542,9 @@ void GenerateItemPool() {
|
||||
}
|
||||
} else {
|
||||
ctx->PlaceItemInLocation(RC_KAK_GRANNYS_SHOP, RG_BLUE_POTION_REFILL, false, true);
|
||||
ctx->PlaceItemInLocation(RC_GC_MEDIGORON, RG_GIANTS_KNIFE, false, true);
|
||||
// when progressive, Medigoron only replaces broken knives, so he never hands out a first one
|
||||
ctx->PlaceItemInLocation(
|
||||
RC_GC_MEDIGORON, ctx->GetOption(RSK_PROGRESSIVE_GORON_SWORD) ? RG_SOLD_OUT : RG_GIANTS_KNIFE, false, true);
|
||||
ctx->PlaceItemInLocation(RC_WASTELAND_BOMBCHU_SALESMAN, RG_BOMBCHU_10, false, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -1495,6 +1495,9 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
|
||||
Flags_UnsetInfTable(INFTABLE_B1);
|
||||
*should = true;
|
||||
}
|
||||
} else if (id == VB_BE_ELIGIBLE_FOR_GIANTS_KNIFE_PURCHASE && RAND_GET_OPTION(RSK_PROGRESSIVE_GORON_SWORD)) {
|
||||
// the progressive sword carries the first knife, leaving Medigoron to replace broken ones
|
||||
*should = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -370,8 +370,9 @@ std::shared_ptr<GetItemEntry> Item::GetGIEntry() const { // NOLINT(*-no-recursio
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case RG_PROGRESSIVE_GORONSWORD: // todo progressive?
|
||||
actual = RG_BIGGORON_SWORD;
|
||||
case RG_PROGRESSIVE_GORONSWORD:
|
||||
// owning the slot means the knife was already given, breaking it doesn't clear the flag
|
||||
actual = logic->CheckEquipment(EQUIP_FLAG_SWORD_BGS) ? RG_BIGGORON_SWORD : RG_GIANTS_KNIFE;
|
||||
break;
|
||||
case RG_PROGRESSIVE_BOMBCHU_BAG:
|
||||
if (OTRGlobals::Instance->gRandoContext->GetOption(RSK_BOMBCHU_BAG).Is(RO_BOMBCHU_BAG_SINGLE)) {
|
||||
|
||||
@@ -73,10 +73,13 @@ bool Logic::HasItem(RandomizerGet itemName) {
|
||||
case RG_IRON_BOOTS:
|
||||
case RG_HOVER_BOOTS:
|
||||
return CheckEquipment(RandoGetToEquipFlag.at(itemName));
|
||||
case RG_PROGRESSIVE_GORONSWORD:
|
||||
case RG_GIANTS_KNIFE:
|
||||
return CheckEquipment(RandoGetToEquipFlag.at(itemName)) || Get(LOGIC_MEDIGORON);
|
||||
// progressive leaves Medigoron replacing broken knives, so the first one has to be found
|
||||
return CheckEquipment(EQUIP_FLAG_SWORD_BGS) ||
|
||||
(!ctx->GetOption(RSK_PROGRESSIVE_GORON_SWORD) && Get(LOGIC_MEDIGORON));
|
||||
case RG_BIGGORON_SWORD:
|
||||
return CheckEquipment(RandoGetToEquipFlag.at(itemName)) && mSaveContext->bgsFlag;
|
||||
return CheckEquipment(EQUIP_FLAG_SWORD_BGS) && mSaveContext->bgsFlag;
|
||||
case RG_GORONS_BRACELET:
|
||||
return CurrentUpgrade(UPG_STRENGTH);
|
||||
case RG_SILVER_GAUNTLETS:
|
||||
@@ -335,6 +338,7 @@ bool Logic::ItemUseAllowed(RandomizerGet itemName) {
|
||||
switch (itemName) {
|
||||
case RG_KOKIRI_SWORD:
|
||||
case RG_MASTER_SWORD:
|
||||
case RG_PROGRESSIVE_GORONSWORD:
|
||||
case RG_GIANTS_KNIFE:
|
||||
case RG_BIGGORON_SWORD:
|
||||
return BAllowed();
|
||||
@@ -578,6 +582,7 @@ bool Logic::CanUse(RandomizerGet itemName) {
|
||||
return IsAdult; // || MirrorShieldAsChild;
|
||||
case RG_MASTER_SWORD:
|
||||
return IsAdult; // || MasterSwordAsChild;
|
||||
case RG_PROGRESSIVE_GORONSWORD:
|
||||
case RG_GIANTS_KNIFE:
|
||||
case RG_BIGGORON_SWORD:
|
||||
return IsAdult; // || BiggoronSwordAsChild;
|
||||
@@ -2262,6 +2267,15 @@ void Logic::ApplyItemEffect(Item& item, bool state) {
|
||||
}
|
||||
SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU));
|
||||
} break;
|
||||
case RG_PROGRESSIVE_GORONSWORD:
|
||||
if (state ? CheckEquipment(EQUIP_FLAG_SWORD_BGS) : mSaveContext->bgsFlag) {
|
||||
mSaveContext->bgsFlag = state;
|
||||
} else if (state) {
|
||||
mSaveContext->inventory.equipment |= EQUIP_FLAG_SWORD_BGS;
|
||||
} else {
|
||||
mSaveContext->inventory.equipment &= ~EQUIP_FLAG_SWORD_BGS;
|
||||
}
|
||||
break;
|
||||
case RG_PROGRESSIVE_MAGIC_METER: {
|
||||
auto realGI = item.GetGIEntry();
|
||||
if (realGI->itemId == RG_MAGIC_INF && realGI->modIndex == MOD_RANDOMIZER) {
|
||||
|
||||
@@ -860,6 +860,12 @@ void Settings::CreateOptionDescriptions() {
|
||||
"\n"
|
||||
"If you have Bombchu Bag disabled, you will need a Bomb Bag "
|
||||
"and existing Bombchus for Bombchus to drop.";
|
||||
mOptionDescriptions[RSK_PROGRESSIVE_GORON_SWORD] =
|
||||
"Giant's Knife and Biggoron's Sword are shuffled as one progressive item: the first copy is the "
|
||||
"breakable Giant's Knife, the second is Biggoron's Sword.\n"
|
||||
"\n"
|
||||
"Starting with Biggoron's Sword still starts you with both.\n"
|
||||
"Medigoron only repairs broken Giant's Knife.";
|
||||
mOptionDescriptions[RSK_BLUE_FIRE_ARROWS] =
|
||||
"Ice Arrows act like Blue Fire, making them able to melt red ice. "
|
||||
"Item placement logic will respect this option, so it might be required to use this to progress.";
|
||||
|
||||
@@ -472,7 +472,10 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe
|
||||
return Inventory_HasEmptyBottle() ? CAN_OBTAIN : CANT_OBTAIN_NEED_EMPTY_BOTTLE;
|
||||
|
||||
// Trade Items
|
||||
// case RG_PROGRESSIVE_GORONSWORD:
|
||||
// Giant's Knife and Biggoron's Sword share a slot, bgsFlag marks the final upgrade.
|
||||
// Giant's Knife itself stays obtainable, Medigoron replaces broken ones.
|
||||
case RG_PROGRESSIVE_GORONSWORD:
|
||||
return !gSaveContext.bgsFlag ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE;
|
||||
// case RG_GIANTS_KNIFE:
|
||||
|
||||
// Misc Items
|
||||
|
||||
@@ -308,6 +308,7 @@ RANDO_ENUM_ITEM(RSK_ROCS_FEATHER)
|
||||
RANDO_ENUM_ITEM(RSK_SHUFFLE_ICICLES)
|
||||
RANDO_ENUM_ITEM(RSK_SHUFFLE_RED_ICE)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_BUNNY_HOOD)
|
||||
RANDO_ENUM_ITEM(RSK_PROGRESSIVE_GORON_SWORD)
|
||||
RANDO_ENUM_ITEM(RSK_MAX)
|
||||
RANDO_ENUM_END(RandomizerSettingKey)
|
||||
|
||||
|
||||
@@ -882,13 +882,15 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) {
|
||||
|
||||
void DrawEquip(ItemTrackerItem item) {
|
||||
assert(item.kind == ITEM_KIND_ITEM);
|
||||
bool hasEquip = HasEquipment(item);
|
||||
bool hasEquip = HasEquipment(item) && IsValidSaveFile();
|
||||
bool giantsKnife = item.id == ITEM_SWORD_BGS && hasEquip && !gSaveContext.bgsFlag;
|
||||
std::string iconName = giantsKnife ? "ITEM_SWORD_KNIFE" : hasEquip ? item.iconName : item.fadedIconName;
|
||||
float iconSize = static_cast<float>(CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36));
|
||||
ImGui::Image(std::dynamic_pointer_cast<Fast::Fast3dGui>(Ship::Context::GetRawInstance()->GetWindow()->GetGui())
|
||||
->GetTextureByName(hasEquip && IsValidSaveFile() ? item.iconName : item.fadedIconName),
|
||||
->GetTextureByName(iconName),
|
||||
ImVec2(iconSize, iconSize), ImVec2(0.0f, 0.0f), ImVec2(1, 1));
|
||||
|
||||
Tooltip(SohUtils::GetItemName(item.id).c_str());
|
||||
Tooltip(giantsKnife ? "Giant's Knife" : SohUtils::GetItemName(item.id).c_str());
|
||||
}
|
||||
|
||||
void DrawQuest(ItemTrackerItem item) {
|
||||
|
||||
@@ -423,6 +423,7 @@ void Settings::CreateOptions() {
|
||||
});
|
||||
OPT_U8(RSK_BOMBCHU_BAG, "Bombchu Bag", {"None", "Single Bag", "Progressive Bags"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BombchuBag"), mOptionDescriptions[RSK_BOMBCHU_BAG], WIDGET_CVAR_COMBOBOX, RO_BOMBCHU_BAG_NONE);
|
||||
OPT_U8(RSK_ENABLE_BOMBCHU_DROPS, "Bombchu Drops", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"), mOptionDescriptions[RSK_ENABLE_BOMBCHU_DROPS], WIDGET_CVAR_COMBOBOX, RO_AMMO_DROPS_ON);
|
||||
OPT_BOOL(RSK_PROGRESSIVE_GORON_SWORD, "Progressive Goron Sword", CVAR_RANDOMIZER_SETTING("ProgressiveGoronSword"), mOptionDescriptions[RSK_PROGRESSIVE_GORON_SWORD]);
|
||||
// TODO: AmmoDrops and/or HeartDropRefill, combine with/separate Ammo Drops from Bombchu Drops?
|
||||
// Triforce Hunt: the total piece count is the on/off control. Zero disables the hunt entirely; any
|
||||
// positive value adds that many Triforce Pieces to the pool and unlocks the pieces-location option.
|
||||
@@ -2116,6 +2117,7 @@ void Settings::CreateOptions() {
|
||||
&mOptions[RSK_ROCS_FEATHER],
|
||||
&mOptions[RSK_BOMBCHU_BAG],
|
||||
&mOptions[RSK_ENABLE_BOMBCHU_DROPS],
|
||||
&mOptions[RSK_PROGRESSIVE_GORON_SWORD],
|
||||
&mOptions[RSK_INFINITE_UPGRADES],
|
||||
&mOptions[RSK_SKELETON_KEY],
|
||||
},
|
||||
@@ -2305,6 +2307,7 @@ void Settings::CreateOptions() {
|
||||
&mOptions[RSK_SHUFFLE_100_GS_REWARD],
|
||||
&mOptions[RSK_SHUFFLE_BEAN_SOULS],
|
||||
&mOptions[RSK_ROCS_FEATHER],
|
||||
&mOptions[RSK_PROGRESSIVE_GORON_SWORD],
|
||||
&mOptions[RSK_SHUFFLE_BOSS_SOULS],
|
||||
&mOptions[RSK_SHUFFLE_DEKU_STICK_BAG],
|
||||
&mOptions[RSK_SHUFFLE_DEKU_NUT_BAG],
|
||||
|
||||
Reference in New Issue
Block a user