From e16fac95489fef9d1d709bc436bf840eab6d375a Mon Sep 17 00:00:00 2001
From: mhn65536 <53567009+mhn65536@users.noreply.github.com>
Date: Tue, 26 Nov 2024 17:31:13 +0100
Subject: [PATCH] i shall be squashed anyway (#1097)
---
FF1Blazorizer/Tabs/AdjustmentsTab.razor | 1 +
FF1Blazorizer/wwwroot/tooltips/tooltips.json | 6 +
FF1Lib/Flags/Flags.cs | 1460 +++++++++---------
FF1Lib/Hacks.cs | 10 +
FF1Lib/Randomize.cs | 891 +++++------
5 files changed, 1194 insertions(+), 1174 deletions(-)
diff --git a/FF1Blazorizer/Tabs/AdjustmentsTab.razor b/FF1Blazorizer/Tabs/AdjustmentsTab.razor
index d9290d28a..ddce798a3 100644
--- a/FF1Blazorizer/Tabs/AdjustmentsTab.razor
+++ b/FF1Blazorizer/Tabs/AdjustmentsTab.razor
@@ -60,6 +60,7 @@
Other Tweaks
TRANCE is Status Element
Increase Dark Penalty
+ Increase Enemy Regeneration
Disable Minimap
In-Battle Poison Damage:
Damage:
diff --git a/FF1Blazorizer/wwwroot/tooltips/tooltips.json b/FF1Blazorizer/wwwroot/tooltips/tooltips.json
index 0f6de6287..19c0359e8 100644
--- a/FF1Blazorizer/wwwroot/tooltips/tooltips.json
+++ b/FF1Blazorizer/wwwroot/tooltips/tooltips.json
@@ -2349,6 +2349,12 @@
"screenshot": "increaseDarkPenaltyCheckBox.png",
"description": "If enabled, \"Dark\" status severely decreases an attacker's chance to hit or crit an enemy: their crit chance is set to 0%, and they lose all of their base hit chance (this effectively makes the penalty -168 instead of the normal -40), leaving them with only their Hit% vs the defender's Evasion.\nAffects both players and enemies inflicted with \"Dark\" status."
},
+ {
+ "Id": "increaseRegenerationCheckBox",
+ "title": "Increase Enemy Regeneration",
+ "screenshot": null,
+ "description": "If enabled, \"Regeneration\" category enemies heal 57HP per turn instead of 3HP."
+ },
{
"Id": "poisonModeDropDown",
"title": "In-Battle Poison Damage",
diff --git a/FF1Lib/Flags/Flags.cs b/FF1Lib/Flags/Flags.cs
index dce1227f0..13e6427b6 100644
--- a/FF1Lib/Flags/Flags.cs
+++ b/FF1Lib/Flags/Flags.cs
@@ -1,729 +1,731 @@
-using System.Numerics;
-using System.Reflection;
-using Newtonsoft.Json;
-using System.IO.Compression;
-using static FF1Lib.FF1Rom;
-using FF1Lib.Sanity;
-using System.ComponentModel;
-
-namespace FF1Lib
-{
- public partial class Flags : IIncentiveFlags, IScaleFlags, IVictoryConditionFlags, IFloorShuffleFlags, IItemPlacementFlags
- {
- #region StartingEquipment
-
- public bool? StartingEquipmentMasamune { get; set; } = false;
-
- public bool? StartingEquipmentKatana { get; set; } = false;
-
- public bool? StartingEquipmentHealStaff { get; set; } = false;
-
- public bool? StartingEquipmentZeusGauntlet { get; set; } = false;
-
- public bool? StartingEquipmentWhiteShirt { get; set; } = false;
-
- public bool? StartingEquipmentRibbon { get; set; } = false;
-
- public bool? StartingEquipmentDragonslayer { get; set; } = false;
-
- public bool? StartingEquipmentLegendKit { get; set; } = false;
-
- public bool? StartingEquipmentRandomEndgameWeapon { get; set; } = false;
-
- public bool? StartingEquipmentRandomAoe { get; set; } = false;
-
- public bool? StartingEquipmentRandomCasterItem { get; set; } = false;
-
- public bool? StartingEquipmentGrandpasSecretStash { get; set; } = false;
-
- public bool? StartingEquipmentOneItem { get; set; } = false;
-
- public bool? StartingEquipmentRandomCrap { get; set; } = false;
-
- public bool? StartingEquipmentStarterPack { get; set; } = false;
-
- public bool? StartingEquipmentRandomTypeWeapon { get; set; } = false;
-
- public bool StartingEquipmentRemoveFromPool { get; set; } = false;
-
- public bool StartingEquipmentNoDuplicates { get; set; } = false;
-
- #endregion
-
- public bool? ReversedFloors { get; set; } = false;
- public bool BuffTier1DamageSpells { get; set; } = false;
- public bool NoEmptyScripts { get; set; } = false;
- public bool LaterLoose { get; set; } = false;
- public bool? MermaidPrison { get; set; } = false;
-
- public GuaranteedDefenseItem GuaranteedDefenseItem { get; set; } = GuaranteedDefenseItem.None;
-
- public GuaranteedPowerItem GuaranteedPowerItem { get; set; } = GuaranteedPowerItem.None;
-
- public ScriptTouchMultiplier ScriptMultiplier { get; set; } = ScriptTouchMultiplier.Vanilla;
- public ScriptTouchMultiplier TouchMultiplier { get; set; } = ScriptTouchMultiplier.Vanilla;
- public TouchPool TouchPool { get; set; } = TouchPool.All;
- public TouchMode TouchMode { get; set; } = TouchMode.Standard;
- public RibbonMode RibbonMode { get; set; } = RibbonMode.Vanilla;
-
- public bool Archipelago { get; set; } = false;
- public bool ArchipelagoGold { get; set; } = false;
- public bool ArchipelagoConsumables { get; set; } = false;
- public bool ArchipelagoShards { get; set; } = false;
- public ArchipelagoEquipment ArchipelagoEquipment { get; set; } = ArchipelagoEquipment.None;
-
- public ItemMagicMode ItemMagicMode { get; set; } = ItemMagicMode.Vanilla;
- public ItemMagicPool ItemMagicPool { get; set; } = ItemMagicPool.All;
- public bool? MagisizeWeapons { get; set; } = false;
-
- public bool DisableMinimap { get; set; } = false;
-
- public bool LooseItemsForwardPlacement { get; set; } = false;
-
- public bool LooseItemsSpreadPlacement { get; set; } = false;
-
- public bool LooseItemsNpcBalance { get; set; } = false;
- public bool AllowUnsafePlacement { get; set; } = false;
- public bool ShipCanalBeforeFloater { get; set; } = false;
-
- [IntegerFlag(0, 100, 10)]
- public int ExpChestConversionMin { get; set; } = 0;
-
- [IntegerFlag(0, 100, 10)]
- public int ExpChestConversionMax { get; set; } = 0;
-
- [IntegerFlag(0, 20000, 500)]
- public int ExpChestMinReward { get; set; } = 2000;
-
- [IntegerFlag(0, 20000, 500)]
- public int ExpChestMaxReward { get; set; } = 8000;
-
- public SpellNameMadness SpellNameMadness { get; set; } = SpellNameMadness.None;
-
- public ExtConsumableSet ExtConsumableSet { get; set; } = ExtConsumableSet.None;
-
- public bool EnableSoftInBattle { get; set; } = false;
- public LifeInBattleSetting EnableLifeInBattle { get; set; } = LifeInBattleSetting.LifeInBattleAll;
-
- public bool? NormalShopsHaveExtConsumables { get; set; } = false;
-
- public bool? LegendaryShopHasExtConsumables { get; set; } = false;
-
- public TreasureStackSize ExtConsumableTreasureStackSize { get; set; } = TreasureStackSize.Default;
-
- public ExtStartingItemSet ExtStartingItemSet { get; set; } = ExtStartingItemSet.None;
-
- public ExtConsumableChestSet ExtConsumableChests { get; set; } = ExtConsumableChestSet.None;
-
- public OwMapExchanges OwMapExchange { get; set; } = OwMapExchanges.None;
- public bool OwShuffledAccess { get; set; } = false;
- public bool OwUnsafeStart { get; set; } = false;
- public bool OwRandomPregen { get; set; } = false;
-
- public bool? RelocateChests { get; set; } = false;
- public bool RelocateChestsTrapIndicator { get; set; } = false;
-
- public bool? ShuffleChimeAccess { get; set; } = false;
- public bool? ShuffleChimeIncludeTowns { get; set; } = false;
-
- public GameModes GameMode { get; set; } = GameModes.Standard;
-
- [IntegerFlag(0, Int32.MaxValue-1)]
- public int MapGenSeed { get; set; } = 0;
-
- public OwMapExchangeData ReplacementMap { get; set; } = null;
-
- public string ResourcePack { get; set; } = null;
-
- #region ShopKiller
-
- public ShopKillMode ShopKillMode_Weapons { get; set; } = ShopKillMode.None;
- public ShopKillMode ShopKillMode_Armor { get; set; } = ShopKillMode.None;
- public ShopKillMode ShopKillMode_Item { get; set; } = ShopKillMode.None;
- public ShopKillMode ShopKillMode_Black { get; set; } = ShopKillMode.None;
- public ShopKillMode ShopKillMode_White { get; set; } = ShopKillMode.None;
-
- public ShopKillFactor ShopKillFactor_Weapons { get; set; } = ShopKillFactor.Kill20Percent;
- public ShopKillFactor ShopKillFactor_Armor { get; set; } = ShopKillFactor.Kill20Percent;
- public ShopKillFactor ShopKillFactor_Item { get; set; } = ShopKillFactor.Kill20Percent;
- public ShopKillFactor ShopKillFactor_Black { get; set; } = ShopKillFactor.Kill20Percent;
- public ShopKillFactor ShopKillFactor_White { get; set; } = ShopKillFactor.Kill20Percent;
-
- public bool ShopKillExcludeConeria_Weapons { get; set; } = false;
- public bool ShopKillExcludeConeria_Armor { get; set; } = false;
- public bool ShopKillExcludeConeria_Item { get; set; } = false;
- public bool ShopKillExcludeConeria_Black { get; set; } = false;
- public bool ShopKillExcludeConeria_White { get; set; } = false;
-
- #endregion
-
- public bool? ExcludeGoldFromScaling { get; set; } = false;
- public bool CheapVendorItem { get; set; } = false;
-
- public StartingLevel StartingLevel { get; set; }
- public TransmooglifierVariance TransmooglifierVariance { get; set; }
-
- [IntegerFlag(1, 50)]
- public int MaxLevelLow { get; set; } = 50;
- [IntegerFlag(1, 50)]
- public int MaxLevelHigh { get; set; } = 50;
-
- public bool Spoilers { get; set; } = false;
- public bool TournamentSafe { get; set; } = false;
- public bool BlindSeed { get; set; } = false;
- public bool? Shops { get; set; } = false;
- public bool? Treasures { get; set; } = false;
- public bool? ChestsKeyItems { get; set; } = false;
- public bool? NPCItems { get; set; } = false;
- public bool? NPCFetchItems { get; set; } = false;
- public bool? RandomWares { get; set; } = false;
- public bool? RandomWaresIncludesSpecialGear { get; set; } = false;
- public bool? RandomLoot { get; set; } = false;
-
- public bool ShardHunt { get; set; } = false;
- public ShardCount ShardCount { get; set; } = ShardCount.Count16;
-
- [IntegerFlag(0, 5)]
- public int OrbsRequiredCount { get; set; } = 4;
- public OrbsRequiredMode OrbsRequiredMode { get; set; } = OrbsRequiredMode.Any;
- public bool? OrbsRequiredSpoilers { get; set; } = false;
- public FinalFormation TransformFinalFormation { get; set; } = FinalFormation.None;
- public bool? ChaosRush { get; set; } = false;
- public ToFRMode ToFRMode { get; set; } = ToFRMode.Long;
- public FiendsRefights FiendsRefights { get; set; } = FiendsRefights.All;
- public bool? ExitToFR { get; set; } = false;
- public bool? ChaosFloorEncounters { get; set; } = false;
- public bool? MagicShops { get; set; } = false;
- public bool? MagicShopLocs { get; set; } = false;
- public bool? MagicShopLocationPairs { get; set; } = false;
- public bool? MagicLevels { get; set; } = false;
- public bool? MagicPermissions { get; set; } = false;
- public bool? Weaponizer { get; set; } = false;
- public bool? WeaponizerNamesUseQualityOnly { get; set; } = false;
- public bool? WeaponizerCommonWeaponsHavePowers { get; set; } = false;
- public bool? ArmorCrafter { get; set; } = false;
- public bool? MagicLevelsTiered { get; set; } = false;
- public bool? MagicLevelsMixed { get; set; } = false;
-
- public AutohitThreshold MagicAutohitThreshold { get; set; } = AutohitThreshold.Vanilla;
-
- public bool? Rng { get; set; } = false;
- public bool FixMissingBattleRngEntry { get; set; } = false;
-
- public bool? EncounterPrng { get; set; } = false;
-
- public bool? UnrunnableShuffle { get; set; } = true;
- [IntegerFlag(0, 100, 4)]
- public int UnrunnablesLow { get; set; } = 0;
- [IntegerFlag(0, 100, 4)]
- public int UnrunnablesHigh { get; set; } = 0;
- public bool? EnemyFormationsSurprise { get; set; } = false;
- public bool? UnrunnablesStrikeFirstAndSurprise { get; set; } = false;
-
- public TrapTileMode EnemyTrapTiles { get; set; } = TrapTileMode.Vanilla;
- public FormationPool TCFormations { get; set; } = FormationPool.AltFormationDist;
- public TCOptions TCBetterTreasure { get; set; } = TCOptions.None;
- public TCOptions TCKeyItems { get; set; } = TCOptions.None;
- public TCOptions TCShards { get; set; } = TCOptions.None;
- public bool TCExcludeCommons { get; set; } = false;
-
- [IntegerFlag(0, 260, 20)]
- public int TCChestCount { get; set; } = 0;
- public bool TCProtectIncentives { get; set; } = false;
- public bool? TCMasaGuardian { get; set; } = false;
- public bool? TrappedChaos { get; set; } = false;
- public bool? TCIndicator { get; set; } = false;
- public bool? SwolePirates { get; set; } = false;
- public bool? ShuffleScriptsEnemies { get; set; } = false;
- public bool? RemoveBossScripts { get; set; } = false;
- public bool? ShuffleScriptsBosses { get; set; } = false;
- public bool? ShuffleSkillsSpellsEnemies { get; set; } = false;
- public bool? ShuffleSkillsSpellsBosses { get; set; } = false;
- public bool? NoConsecutiveNukes { get; set; } = false;
- public bool TranceHasStatusElement { get; set; } = false;
- public bool? EnemySkillsSpellsTiered { get; set; } = false;
- public bool? AllowUnsafePirates { get; set; } = false;
- public bool? AllowUnsafeMelmond { get; set; } = false;
-
- public WarMECHMode WarMECHMode { get; set; } = WarMECHMode.Vanilla;
- public bool? OrdealsPillars { get; set; } = false;
- public bool? ShuffleLavaTiles { get; set; } = false;
- public SkyCastle4FMazeMode SkyCastle4FMazeMode { get; set; } = SkyCastle4FMazeMode.Vanilla;
- public bool? TitansTrove { get; set; } = false;
- public bool? LefeinSuperStore { get; set; } = false;
- public bool? LefeinShops { get; set; } = false;
- public bool? RandomVampAttack { get; set; } = false;
- public bool? RandomVampAttackIncludesConeria { get; set; } = false;
- public bool? FightBahamut { get; set; } = false;
- public bool? SwoleBahamut { get; set; } = false;
- public bool? SwoleAstos { get; set; } = false;
- public bool? ConfusedOldMen { get; set; } = false;
- public bool? GaiaShortcut { get; set; } = false;
-
- [IntegerFlag(0, 10, 1)]
- public int DamageTileLow { get; set; } = 1;
- [IntegerFlag(0, 10, 1)]
- public int DamageTileHigh { get; set; } = 1;
- public bool? OWDamageTiles { get; set; } = false;
- public bool? DamageTilesKill { get; set; } = false;
- public bool? ArmorResistsDamageTileDamage { get; set; } = false;
-
- public bool? MoveGaiaItemShop { get; set; } = false;
- public bool? ShufflePravokaShops { get; set; } = false;
- public bool? FlipDungeons { get; set; } = false;
- public bool? VerticallyFlipDungeons { get; set; } = false;
- public bool SpookyFlag { get; set; } = false;
- public bool DraculasFlag { get; set; } = false;
- public bool? MapOpenProgression { get; set; } = false;
- public bool? MapOpenProgressionDocks { get; set; } = false;
- public bool? Entrances { get; set; } = false;
- public bool? Towns { get; set; } = false;
- public bool? IncludeConeria { get; set; } = false;
- public bool? Floors { get; set; } = false;
- public bool? AllowDeepCastles { get; set; } = false;
- public bool? AllowDeepTowns { get; set; } = false;
- public bool? MapOpenProgressionExtended { get; set; } = false;
- public bool? MapAirshipDock { get; set; } = false;
- public bool? MapBahamutCardiaDock { get; set; } = false;
- public bool? MapLefeinRiver { get; set; } = false;
- public bool? MapBridgeLefein { get; set; } = false;
- public bool? MapRiverToMelmond { get; set; } = false;
- public bool? MapGaiaMountainPass { get; set; } = false;
- public bool? MapHighwayToOrdeals { get; set; } = false;
- public bool? MapDragonsHoard { get; set; } = false;
- public bool? MapHallOfDragons { get; set; } = false;
- public bool? EntrancesIncludesDeadEnds { get; set; } = false;
- public bool? EntrancesMixedWithTowns { get; set; } = false;
-
- public bool? IncentivizeFreeNPCs { get; set; } = false;
- public bool? IncentivizeFetchNPCs { get; set; } = false;
- public bool? IncentivizeTail { get; set; } = false;
- public bool? IncentivizeMainItems { get; set; } = false;
- public bool? IncentivizeFetchItems { get; set; } = false;
- public bool? IncentivizeCanoeItem { get; set; } = false;
- public bool? IncentivizeAirship { get; set; } = false;
- public bool? IncentivizeShipAndCanal { get; set; } = false;
- public bool? IncentivizeBridgeItem { get; set; } = false;
-
- public bool? IncentivizeMarsh { get; set; } = false;
- public bool? IncentivizeEarth { get; set; } = false;
- public bool? IncentivizeVolcano { get; set; } = false;
- public bool? IncentivizeIceCave { get; set; } = false;
- public bool? IncentivizeOrdeals { get; set; } = false;
- public bool? IncentivizeSeaShrine { get; set; } = false;
- public bool? IncentivizeConeria { get; set; } = false;
- public bool? IncentivizeMarshKeyLocked { get; set; } = false;
- public bool? IncentivizeSkyPalace { get; set; } = false;
- public bool? IncentivizeTitansTrove { get; set; } = false;
- public bool? IncentivizeCardia { get; set; } = false;
-
- public IncentivePlacementType IceCaveIncentivePlacementType { get; set; } = IncentivePlacementType.Vanilla;
- public IncentivePlacementType OrdealsIncentivePlacementType { get; set; } = IncentivePlacementType.Vanilla;
- public IncentivePlacementType MarshIncentivePlacementType { get; set; } = IncentivePlacementType.Vanilla;
- public IncentivePlacementType TitansIncentivePlacementType { get; set; } = IncentivePlacementType.Vanilla;
- public IncentivePlacementTypeEarth EarthIncentivePlacementType { get; set; } = IncentivePlacementTypeEarth.Vanilla;
- public IncentivePlacementTypeVolcano VolcanoIncentivePlacementType { get; set; } = IncentivePlacementTypeVolcano.Vanilla;
- public IncentivePlacementTypeSea SeaShrineIncentivePlacementType { get; set; } = IncentivePlacementTypeSea.Vanilla;
- public IncentivePlacementTypeSky SkyPalaceIncentivePlacementType { get; set; } = IncentivePlacementTypeSky.Vanilla;
- public IncentivePlacementType CorneriaIncentivePlacementType { get; set; } = IncentivePlacementType.Vanilla;
- public IncentivePlacementType MarshLockedIncentivePlacementType { get; set; } = IncentivePlacementType.Vanilla;
- public IncentivePlacementType CardiaIncentivePlacementType { get; set; } = IncentivePlacementType.Vanilla;
-
- public bool? BetterTrapChests { get; set; } = false;
- public bool? IncentivizeMasamune { get; set; } = false;
- public bool? IncentivizeKatana { get; set; } = false;
- public bool? IncentivizeXcalber { get; set; } = false;
- public bool? IncentivizeVorpal { get; set; } = false;
- public bool? IncentivizeOpal { get; set; } = false;
- public bool? IncentivizeRibbon { get; set; } = false;
- public bool? IncentivizeDefCastArmor { get; set; } = false;
- public bool? IncentivizeOffCastArmor { get; set; } = false;
- public bool? IncentivizeOtherCastArmor { get; set; } = false;
- public bool? IncentivizePowerRod { get; set; } = false;
- public bool? IncentivizeDefCastWeapon { get; set; } = false;
- public bool? IncentivizeOffCastWeapon { get; set; } = false;
- public bool IncentivizeOtherCastWeapon { get; set; } = false;
- public bool? LooseExcludePlacedDungeons { get; set; } = false;
- public bool? EarlyKing { get; set; } = false;
- public bool? EarlySarda { get; set; } = false;
- public bool? EarlySage { get; set; } = false;
- public bool? EarlyOrdeals { get; set; } = false;
- public bool? ShuffleObjectiveNPCs { get; set; } = false;
- public bool OnlyRequireGameIsBeatable { get; set; } = true;
- public bool? FreeBridge { get; set; } = false;
- public bool? FreeShip { get; set; } = false;
- public bool? FreeAirship { get; set; } = false;
- public bool? FreeLute { get; set; } = false;
- public bool? FreeRod { get; set; } = false;
- public bool EnableCritNumberDisplay { get; set; } = false;
- public bool? FreeCanal { get; set; } = false;
- public bool? FreeCanoe { get; set; } = false;
- public bool EasyMode { get; set; } = false;
-
- public bool HousesFillHp { get; set; } = false;
-
- public bool SpeedHacks { get; set; } = false;
- public bool NoPartyShuffle { get; set; } = false;
- public bool Dash { get; set; } = false;
- public bool SpeedBoat { get; set; } = false;
- public bool? AirBoat { get; set; } = false;
- public bool BuyTen { get; set; } = false;
- public bool IdentifyTreasures { get; set; } = false;
- public bool ShopInfo { get; set; } = false;
- public bool ChestInfo { get; set; } = false;
- public bool IncentiveChestItemsFanfare { get; set; } = false;
- public bool WaitWhenUnrunnable { get; set; } = false;
- public bool ImprovedClinic { get; set; } = false;
- public bool Etherizer { get; set; } = false;
- // Done
- public bool HouseMPRestoration { get; set; } = false;
- public bool WeaponStats { get; set; } = false;
- public bool BBCritRate { get; set; } = false;
- public bool WeaponCritRate { get; set; } = false;
- public bool WeaponBonuses { get; set; } = false;
- public ThiefAGI ThiefAgilityBuff { get; set; } = ThiefAGI.Vanilla;
- public SpoilerBatHints SkyWarriorSpoilerBats { get; set; } = SpoilerBatHints.Vanilla;
- public bool? SpoilerBatsDontCheckOrbs { get; set; } = false;
- public bool? MoveToFBats { get; set; } = false;
-
- [IntegerFlag(0, 50)]
- public int WeaponTypeBonusValue { get; set; } = 10;
-
- public ChanceToRunMode ChanceToRun { get; set; } = ChanceToRunMode.Vanilla;
-
- public bool SpellBugs { get; set; } = false;
- public bool BlackBeltAbsorb { get; set; } = false;
- public bool NPCSwatter { get; set; } = false;
- public bool BattleMagicMenuWrapAround { get; set; } = false;
- public bool MagicMenuSpellReordering { get; set; } = false;
- public bool InventoryAutosort { get; set; } = false;
- public bool RepeatedHealPotionUse { get; set; } = false;
- public bool AutoRetargeting { get; set; } = false;
- public bool EnemyStatusAttackBug { get; set; } = false;
- public bool ImproveTurnOrderRandomization { get; set; } = false;
- public bool FixHitChanceCap { get; set; } = false;
-
- public bool? MelmondClinic { get; set; } = false;
- public bool DDProgressiveTilesets { get; set; } = false;
- public bool DDFiendOrbs { get; set; } = false;
- public TailBahamutMode TailBahamutMode { get; set; } = TailBahamutMode.Random;
- public StartingGold StartingGold { get; set; } = StartingGold.Gp400;
- public bool IncludeMorale { get; set; } = false;
- public bool DeadsGainXP { get; set; } = false;
- public bool NonesGainXP { get; set; } = false;
- public bool? NoTail { get; set; } = false;
- public bool? NoFloater { get; set; } = false;
- public bool? GuaranteedMasamune { get; set; } = false;
- public bool? SendMasamuneHome { get; set; } = false;
-
- public ConsumableChestSet MoreConsumableChests { get; set; } = ConsumableChestSet.Vanilla;
-
- public bool? NoMasamune { get; set; } = false;
- public bool? NoXcalber { get; set; } = false;
- public bool? ClassAsNpcFiends { get; set; } = false;
- public bool? ClassAsNpcKeyNPC { get; set; } = false;
-
- [IntegerFlag(0, 13)]
- public int ClassAsNpcCount { get; set; } = 6;
- public bool? ClassAsNpcDuplicate { get; set; } = false;
- public bool? ClassAsNpcForcedFiends { get; set; } = false;
- public bool? ClassAsNpcPromotion { get; set; } = false;
-
- [IntegerFlag(0, 500, 10)]
- public int BossScaleStatsLow { get; set; } = 50;
-
- [IntegerFlag(0, 500, 10)]
- public int BossScaleStatsHigh { get; set; } = 200;
-
- [IntegerFlag(0, 500, 10)]
- public int BossScaleHpLow { get; set; } = 50;
-
- [IntegerFlag(0, 500, 10)]
- public int BossScaleHpHigh { get; set; } = 200;
-
- [IntegerFlag(0, 500, 10)]
- public int EnemyScaleStatsLow { get; set; } = 50;
-
- [IntegerFlag(0, 500, 10)]
- public int EnemyScaleStatsHigh { get; set; } = 200;
-
- [IntegerFlag(0, 500, 10)]
- public int EnemyScaleHpLow { get; set; } = 50;
-
- [IntegerFlag(0, 500, 10)]
- public int EnemyScaleHpHigh { get; set; } = 200;
-
- [IntegerFlag(0, 500, 10)]
- public int PriceScaleFactorLow { get; set; } = 50;
-
- [IntegerFlag(0, 500, 10)]
- public int PriceScaleFactorHigh { get; set; } = 200;
-
- [DoubleFlag(1.0, 5.0, 0.1)]
- public double ExpMultiplier { get; set; } = 0;
-
- [IntegerFlag(0, 250, 25)]
- public int ExpBonus { get; set; } = 0;
-
- [DoubleFlag(0.5, 3.0, 0.1)]
- public double ExpMultiplierFighter { get; set; } = 1.0;
-
- [DoubleFlag(0.5, 3.0, 0.1)]
- public double ExpMultiplierThief { get; set; } = 1.0;
-
- [DoubleFlag(0.5, 3.0, 0.1)]
- public double ExpMultiplierBlackBelt { get; set; } = 1.0;
-
- [DoubleFlag(0.5, 3.0, 0.1)]
- public double ExpMultiplierRedMage { get; set; } = 1.0;
-
- [DoubleFlag(0.5, 3.0, 0.1)]
- public double ExpMultiplierWhiteMage { get; set; } = 1.0;
-
- [DoubleFlag(0.5, 3.0, 0.1)]
- public double ExpMultiplierBlackMage { get; set; } = 1.0;
-
- [DoubleFlag(0, 45)]
- public double EncounterRate { get; set; } = 0;
-
- [DoubleFlag(0, 45)]
- public double DungeonEncounterRate { get; set; } = 0;
- public ProgressiveScaleMode ProgressiveScaleMode { get; set; } = ProgressiveScaleMode.Disabled;
-
- public StartingItemSet StartingItemSet { get; set; } = StartingItemSet.None;
-
- public TreasureStackSize ConsumableTreasureStackSize { get; set; } = TreasureStackSize.Default;
-
- public bool? FIGHTER1 { get; set; } = false;
- public bool? THIEF1 { get; set; } = false;
- public bool? BLACK_BELT1 { get; set; } = false;
- public bool? RED_MAGE1 { get; set; } = false;
- public bool? WHITE_MAGE1 { get; set; } = false;
- public bool? BLACK_MAGE1 { get; set; } = false;
-
- public bool? FIGHTER2 { get; set; } = false;
- public bool? THIEF2 { get; set; } = false;
- public bool? BLACK_BELT2 { get; set; } = false;
- public bool? RED_MAGE2 { get; set; } = false;
- public bool? WHITE_MAGE2 { get; set; } = false;
- public bool? BLACK_MAGE2 { get; set; } = false;
-
- public bool? FIGHTER3 { get; set; } = false;
- public bool? THIEF3 { get; set; } = false;
- public bool? BLACK_BELT3 { get; set; } = false;
- public bool? RED_MAGE3 { get; set; } = false;
- public bool? WHITE_MAGE3 { get; set; } = false;
- public bool? BLACK_MAGE3 { get; set; } = false;
-
- public bool? FIGHTER4 { get; set; } = false;
- public bool? THIEF4 { get; set; } = false;
- public bool? BLACK_BELT4 { get; set; } = false;
- public bool? RED_MAGE4 { get; set; } = false;
- public bool? WHITE_MAGE4 { get; set; } = false;
- public bool? BLACK_MAGE4 { get; set; } = false;
-
- public bool? KNIGHT1 { get; set; } = false;
- public bool? KNIGHT2 { get; set; } = false;
- public bool? KNIGHT3 { get; set; } = false;
- public bool? KNIGHT4 { get; set; } = false;
- public bool? NINJA1 { get; set; } = false;
- public bool? NINJA2 { get; set; } = false;
- public bool? NINJA3 { get; set; } = false;
- public bool? NINJA4 { get; set; } = false;
- public bool? MASTER1 { get; set; } = false;
- public bool? MASTER2 { get; set; } = false;
- public bool? MASTER3 { get; set; } = false;
- public bool? MASTER4 { get; set; } = false;
- public bool? RED_WIZ1 { get; set; } = false;
- public bool? RED_WIZ2 { get; set; } = false;
- public bool? RED_WIZ3 { get; set; } = false;
- public bool? RED_WIZ4 { get; set; } = false;
- public bool? WHITE_WIZ1 { get; set; } = false;
- public bool? WHITE_WIZ2 { get; set; } = false;
- public bool? WHITE_WIZ3 { get; set; } = false;
- public bool? WHITE_WIZ4 { get; set; } = false;
- public bool? BLACK_WIZ1 { get; set; } = false;
- public bool? BLACK_WIZ2 { get; set; } = false;
- public bool? BLACK_WIZ3 { get; set; } = false;
- public bool? BLACK_WIZ4 { get; set; } = false;
- public bool? NONE_CLASS2 { get; set; } = false;
- public bool? NONE_CLASS3 { get; set; } = false;
- public bool? NONE_CLASS4 { get; set; } = false;
- public bool? FORCED1 { get; set; } = false;
- public bool? FORCED2 { get; set; } = false;
- public bool? FORCED3 { get; set; } = false;
- public bool? FORCED4 { get; set; } = false;
- public bool? DraftFighter { get; set; } = false;
- public bool? DraftThief { get; set; } = false;
- public bool? DraftBlackBelt { get; set; } = false;
- public bool? DraftRedMage { get; set; } = false;
- public bool? DraftWhiteMage { get; set; } = false;
- public bool? DraftBlackMage { get; set; } = false;
- public bool? DraftKnight { get; set; } = false;
- public bool? DraftNinja { get; set; } = false;
- public bool? DraftMaster { get; set; } = false;
- public bool? DraftRedWiz { get; set; } = false;
- public bool? DraftWhiteWiz { get; set; } = false;
- public bool? DraftBlackWiz { get; set; } = false;
- public bool? TAVERN1 { get; set; } = false;
- public bool? TAVERN2 { get; set; } = false;
- public bool? TAVERN3 { get; set; } = false;
- public bool? TAVERN4 { get; set; } = false;
- public bool? TAVERN5 { get; set; } = false;
- public bool? TAVERN6 { get; set; } = false;
-
- public bool WeaponPermissions { get; set; } = false;
- public bool ArmorPermissions { get; set; } = false;
- public bool? RecruitmentMode { get; set; } = false;
- public bool? RecruitmentModeHireOnly { get; set; } = false;
- public bool? RecruitmentModeReplaceOnlyNone { get; set; } = false;
- public bool? ClampMinimumStatScale { get; set; } = false;
- public bool? ClampMinimumBossStatScale { get; set; } = false;
- public bool? ClampMinimumPriceScale { get; set; } = false;
- public bool EFGWaterfall { get; set; } = false;
- public bool? FiendShuffle { get; set; } = false;
- public bool DisableTentSaving { get; set; } = false;
- public bool DisableInnSaving { get; set; } = false;
- public bool SaveGameWhenGameOver { get; set; } = false;
- public bool SaveGameDWMode { get; set; } = false;
- public bool? ShuffleAstos { get; set; } = false;
- public bool UnsafeAstos { get; set; } = false;
- public bool? RandomizeEnemizer { get; set; } = false;
- public bool? RandomizeFormationEnemizer { get; set; } = false;
- public bool? GenerateNewSpellbook { get; set; } = false;
- public bool? SpellcrafterMixSpells { get; set; } = false;
- public bool ThiefHitRate { get; set; } = false;
- public bool AllSpellLevelsForKnightNinja { get; set; } = false;
- public bool BuffHealingSpells { get; set; } = false;
- public bool IntAffectsSpells { get; set; } = false;
- public bool? AddDamageTiles { get; set; } = false;
- public bool? DamageTilesCastles { get; set; } = false;
- public bool? DamageTilesDungeons { get; set; } = false;
- public bool? DamageTilesCaves { get; set; } = false;
- public bool? DamageTilesTowns { get; set; } = false;
- public bool? DamageTilesTof { get; set; } = false;
- public DamageTilesQuantity DamageTilesQuantity { get; set; } = DamageTilesQuantity.Normal;
- public bool? FreeTail { get; set; } = false;
- public bool? HintsVillage { get; set; } = false;
- public bool? SpellcrafterRetainPermissions { get; set; } = false;
- public bool? RandomWeaponBonus { get; set; } = false;
- public bool? RandomArmorBonus { get; set; } = false;
- public bool? RandomWeaponBonusExcludeMasa { get; set; } = false;
-
- [IntegerFlag(-9, 9)]
- public int RandomWeaponBonusLow { get; set; } = -5;
-
- [IntegerFlag(-9, 9)]
- public int RandomWeaponBonusHigh { get; set; } = 5;
-
- [IntegerFlag(-9, 9)]
- public int RandomArmorBonusLow { get; set; } = -5;
-
- [IntegerFlag(-9, 9)]
- public int RandomArmorBonusHigh { get; set; } = 5;
- public bool? SeparateBossHPScaling { get; set; } = false;
- public bool? SeparateEnemyHPScaling { get; set; } = false;
- public bool? ClampBossHPScaling { get; set; } = false;
- public bool? ClampEnemyHpScaling { get; set; } = false;
- public PoolSize PoolSize { get; set; } = PoolSize.Size6;
- public bool? EnablePoolParty { get; set; } = false;
- public bool SafePoolParty { get; set; } = false;
- public bool? IncludePromClasses { get; set; } = false;
- public bool? EnableRandomPromotions { get; set; } = false;
- public bool? IncludeBaseClasses { get; set; } = false;
- public bool? RandomPromotionsSpoilers { get; set; } = false;
- public bool? RandomizeClassCasting { get; set; } = false;
- public bool? RandomizeClassKeyItems { get; set; } = false;
- public bool? RandomizeClassIncludeXpBonus { get; set; } = false;
- public bool? AlternateFiends { get; set; } = false;
- public bool? FinalFantasy2Fiends { get; set; } = false;
- public bool? FinalFantasy3Fiends { get; set; } = false;
- public bool? FinalFantasy4Fiends { get; set; } = false;
- public bool? FinalFantasy5Fiends { get; set; } = false;
- public bool? FinalFantasy6Fiends { get; set; } = false;
- public bool? FinalFantasy1BonusFiends { get; set; } = false;
- public bool? BlackOrbFiends { get; set; } = false;
- public bool? NoBossSkillScriptShuffle { get; set; } = false;
-
- public bool? MooglieWeaponBalance { get; set; } = false;
- public bool? GuaranteeCustomClassComposition { get; set; } = false;
-
- public bool? LegendaryWeaponShop { get; set; } = false;
- public bool? LegendaryArmorShop { get; set; } = false;
- public bool? LegendaryBlackShop { get; set; } = false;
- public bool? LegendaryWhiteShop { get; set; } = false;
- public bool? LegendaryItemShop { get; set; } = false;
-
- public bool ExclusiveLegendaryWeaponShop { get; set; } = false;
- public bool ExclusiveLegendaryArmorShop { get; set; } = false;
- public bool ExclusiveLegendaryBlackShop { get; set; } = false;
- public bool ExclusiveLegendaryWhiteShop { get; set; } = false;
- public bool ExclusiveLegendaryItemShop { get; set; } = false;
- public ClassRandomizationMode RandomizeClassMode { get; set; } = ClassRandomizationMode.None;
-
- [IntegerFlag(0, 3)]
- public int RandomizeClassMaxBonus { get; set; } = 2;
-
- [IntegerFlag(0, 3)]
- public int RandomizeClassMaxMalus { get; set; } = 1;
- public bool? EarlierHighTierMagic { get; set; } = false;
- public bool? ChangeMaxMP { get; set; } = false;
-
- [IntegerFlag(0, 9)]
- public int RedMageMaxMP { get; set; } = 9;
-
- [IntegerFlag(0, 9)]
- public int WhiteMageMaxMP { get; set; } = 9;
-
- [IntegerFlag(0, 9)]
- public int BlackMageMaxMP { get; set; } = 9;
-
- [IntegerFlag(0, 9)]
- public int KnightMaxMP { get; set; } = 4;
-
- [IntegerFlag(0, 9)]
- public int NinjaMaxMP { get; set; } = 4;
-
- public bool? Knightlvl4 { get; set; } = false;
- public bool? PinkMage { get; set; } = false;
- public bool? BlackKnight { get; set; } = false;
- public bool? BlackKnightKeep { get; set; } = false;
- public bool? WhiteNinja { get; set; } = false;
- public bool? WhiteNinjaKeep { get; set; } = false;
-
- public MpGainOnMaxGain MpGainOnMaxGainMode { get; set; } = MpGainOnMaxGain.None;
-
- public LockHitMode LockMode { get; set; } = LockHitMode.Vanilla;
- // Done
- public MDEFGrowthMode MDefMode { get; set; } = MDEFGrowthMode.None;
-
- public FormationShuffleMode FormationShuffleMode { get; set; } = FormationShuffleMode.None;
-
- public RandomizeTreasureMode RandomizeTreasure { get; set; } = RandomizeTreasureMode.None;
- public bool OpenChestsInOrder { get; set; } = false;
- public bool SetRNG { get; set; } = false;
- public WorldWealthMode WorldWealth { get; set; } = WorldWealthMode.Standard;
- public DeepDungeonGeneratorMode DeepDungeonGenerator { get; set; } = DeepDungeonGeneratorMode.Progressive;
- public EvadeCapValues EvadeCap { get; set; } = EvadeCapValues.medium;
-
- public bool? AllowUnsafeStartArea { get; set; } = false;
-
- public bool? IncreaseDarkPenalty { get; set; } = false;
- public PoisonModeOptions PoisonMode { get; set; } = PoisonModeOptions.Constant;
- [IntegerFlag(1,500)]
- public int PoisonSetDamageValue { get; set; } = 3;
-
- public bool? TouchIncludeBosses { get; set; } = false;
-
- public bool? Lockpicking { get; set; } = false;
- // Done
- public bool? ReducedLuck { get; set; } = false;
-
- [IntegerFlag(1, 50)]
- public int LockpickingLevelRequirement { get; set; } = 10;
-
- public bool WhiteMageHarmEveryone { get; set; } = false;
-
- public bool? ProcgenEarth { get; set; } = false;
- }
-}
+using System.Numerics;
+using System.Reflection;
+using Newtonsoft.Json;
+using System.IO.Compression;
+using static FF1Lib.FF1Rom;
+using FF1Lib.Sanity;
+using System.ComponentModel;
+
+namespace FF1Lib
+{
+ public partial class Flags : IIncentiveFlags, IScaleFlags, IVictoryConditionFlags, IFloorShuffleFlags, IItemPlacementFlags
+ {
+ #region StartingEquipment
+
+ public bool? StartingEquipmentMasamune { get; set; } = false;
+
+ public bool? StartingEquipmentKatana { get; set; } = false;
+
+ public bool? StartingEquipmentHealStaff { get; set; } = false;
+
+ public bool? StartingEquipmentZeusGauntlet { get; set; } = false;
+
+ public bool? StartingEquipmentWhiteShirt { get; set; } = false;
+
+ public bool? StartingEquipmentRibbon { get; set; } = false;
+
+ public bool? StartingEquipmentDragonslayer { get; set; } = false;
+
+ public bool? StartingEquipmentLegendKit { get; set; } = false;
+
+ public bool? StartingEquipmentRandomEndgameWeapon { get; set; } = false;
+
+ public bool? StartingEquipmentRandomAoe { get; set; } = false;
+
+ public bool? StartingEquipmentRandomCasterItem { get; set; } = false;
+
+ public bool? StartingEquipmentGrandpasSecretStash { get; set; } = false;
+
+ public bool? StartingEquipmentOneItem { get; set; } = false;
+
+ public bool? StartingEquipmentRandomCrap { get; set; } = false;
+
+ public bool? StartingEquipmentStarterPack { get; set; } = false;
+
+ public bool? StartingEquipmentRandomTypeWeapon { get; set; } = false;
+
+ public bool StartingEquipmentRemoveFromPool { get; set; } = false;
+
+ public bool StartingEquipmentNoDuplicates { get; set; } = false;
+
+ #endregion
+
+ public bool? ReversedFloors { get; set; } = false;
+ public bool BuffTier1DamageSpells { get; set; } = false;
+ public bool NoEmptyScripts { get; set; } = false;
+ public bool LaterLoose { get; set; } = false;
+ public bool? MermaidPrison { get; set; } = false;
+
+ public GuaranteedDefenseItem GuaranteedDefenseItem { get; set; } = GuaranteedDefenseItem.None;
+
+ public GuaranteedPowerItem GuaranteedPowerItem { get; set; } = GuaranteedPowerItem.None;
+
+ public ScriptTouchMultiplier ScriptMultiplier { get; set; } = ScriptTouchMultiplier.Vanilla;
+ public ScriptTouchMultiplier TouchMultiplier { get; set; } = ScriptTouchMultiplier.Vanilla;
+ public TouchPool TouchPool { get; set; } = TouchPool.All;
+ public TouchMode TouchMode { get; set; } = TouchMode.Standard;
+ public RibbonMode RibbonMode { get; set; } = RibbonMode.Vanilla;
+
+ public bool Archipelago { get; set; } = false;
+ public bool ArchipelagoGold { get; set; } = false;
+ public bool ArchipelagoConsumables { get; set; } = false;
+ public bool ArchipelagoShards { get; set; } = false;
+ public ArchipelagoEquipment ArchipelagoEquipment { get; set; } = ArchipelagoEquipment.None;
+
+ public ItemMagicMode ItemMagicMode { get; set; } = ItemMagicMode.Vanilla;
+ public ItemMagicPool ItemMagicPool { get; set; } = ItemMagicPool.All;
+ public bool? MagisizeWeapons { get; set; } = false;
+
+ public bool DisableMinimap { get; set; } = false;
+
+ public bool LooseItemsForwardPlacement { get; set; } = false;
+
+ public bool LooseItemsSpreadPlacement { get; set; } = false;
+
+ public bool LooseItemsNpcBalance { get; set; } = false;
+ public bool AllowUnsafePlacement { get; set; } = false;
+ public bool ShipCanalBeforeFloater { get; set; } = false;
+
+ [IntegerFlag(0, 100, 10)]
+ public int ExpChestConversionMin { get; set; } = 0;
+
+ [IntegerFlag(0, 100, 10)]
+ public int ExpChestConversionMax { get; set; } = 0;
+
+ [IntegerFlag(0, 20000, 500)]
+ public int ExpChestMinReward { get; set; } = 2000;
+
+ [IntegerFlag(0, 20000, 500)]
+ public int ExpChestMaxReward { get; set; } = 8000;
+
+ public SpellNameMadness SpellNameMadness { get; set; } = SpellNameMadness.None;
+
+ public ExtConsumableSet ExtConsumableSet { get; set; } = ExtConsumableSet.None;
+
+ public bool EnableSoftInBattle { get; set; } = false;
+ public LifeInBattleSetting EnableLifeInBattle { get; set; } = LifeInBattleSetting.LifeInBattleAll;
+
+ public bool? NormalShopsHaveExtConsumables { get; set; } = false;
+
+ public bool? LegendaryShopHasExtConsumables { get; set; } = false;
+
+ public TreasureStackSize ExtConsumableTreasureStackSize { get; set; } = TreasureStackSize.Default;
+
+ public ExtStartingItemSet ExtStartingItemSet { get; set; } = ExtStartingItemSet.None;
+
+ public ExtConsumableChestSet ExtConsumableChests { get; set; } = ExtConsumableChestSet.None;
+
+ public OwMapExchanges OwMapExchange { get; set; } = OwMapExchanges.None;
+ public bool OwShuffledAccess { get; set; } = false;
+ public bool OwUnsafeStart { get; set; } = false;
+ public bool OwRandomPregen { get; set; } = false;
+
+ public bool? RelocateChests { get; set; } = false;
+ public bool RelocateChestsTrapIndicator { get; set; } = false;
+
+ public bool? ShuffleChimeAccess { get; set; } = false;
+ public bool? ShuffleChimeIncludeTowns { get; set; } = false;
+
+ public GameModes GameMode { get; set; } = GameModes.Standard;
+
+ [IntegerFlag(0, Int32.MaxValue-1)]
+ public int MapGenSeed { get; set; } = 0;
+
+ public OwMapExchangeData ReplacementMap { get; set; } = null;
+
+ public string ResourcePack { get; set; } = null;
+
+ #region ShopKiller
+
+ public ShopKillMode ShopKillMode_Weapons { get; set; } = ShopKillMode.None;
+ public ShopKillMode ShopKillMode_Armor { get; set; } = ShopKillMode.None;
+ public ShopKillMode ShopKillMode_Item { get; set; } = ShopKillMode.None;
+ public ShopKillMode ShopKillMode_Black { get; set; } = ShopKillMode.None;
+ public ShopKillMode ShopKillMode_White { get; set; } = ShopKillMode.None;
+
+ public ShopKillFactor ShopKillFactor_Weapons { get; set; } = ShopKillFactor.Kill20Percent;
+ public ShopKillFactor ShopKillFactor_Armor { get; set; } = ShopKillFactor.Kill20Percent;
+ public ShopKillFactor ShopKillFactor_Item { get; set; } = ShopKillFactor.Kill20Percent;
+ public ShopKillFactor ShopKillFactor_Black { get; set; } = ShopKillFactor.Kill20Percent;
+ public ShopKillFactor ShopKillFactor_White { get; set; } = ShopKillFactor.Kill20Percent;
+
+ public bool ShopKillExcludeConeria_Weapons { get; set; } = false;
+ public bool ShopKillExcludeConeria_Armor { get; set; } = false;
+ public bool ShopKillExcludeConeria_Item { get; set; } = false;
+ public bool ShopKillExcludeConeria_Black { get; set; } = false;
+ public bool ShopKillExcludeConeria_White { get; set; } = false;
+
+ #endregion
+
+ public bool? ExcludeGoldFromScaling { get; set; } = false;
+ public bool CheapVendorItem { get; set; } = false;
+
+ public StartingLevel StartingLevel { get; set; }
+ public TransmooglifierVariance TransmooglifierVariance { get; set; }
+
+ [IntegerFlag(1, 50)]
+ public int MaxLevelLow { get; set; } = 50;
+ [IntegerFlag(1, 50)]
+ public int MaxLevelHigh { get; set; } = 50;
+
+ public bool Spoilers { get; set; } = false;
+ public bool TournamentSafe { get; set; } = false;
+ public bool BlindSeed { get; set; } = false;
+ public bool? Shops { get; set; } = false;
+ public bool? Treasures { get; set; } = false;
+ public bool? ChestsKeyItems { get; set; } = false;
+ public bool? NPCItems { get; set; } = false;
+ public bool? NPCFetchItems { get; set; } = false;
+ public bool? RandomWares { get; set; } = false;
+ public bool? RandomWaresIncludesSpecialGear { get; set; } = false;
+ public bool? RandomLoot { get; set; } = false;
+
+ public bool ShardHunt { get; set; } = false;
+ public ShardCount ShardCount { get; set; } = ShardCount.Count16;
+
+ [IntegerFlag(0, 5)]
+ public int OrbsRequiredCount { get; set; } = 4;
+ public OrbsRequiredMode OrbsRequiredMode { get; set; } = OrbsRequiredMode.Any;
+ public bool? OrbsRequiredSpoilers { get; set; } = false;
+ public FinalFormation TransformFinalFormation { get; set; } = FinalFormation.None;
+ public bool? ChaosRush { get; set; } = false;
+ public ToFRMode ToFRMode { get; set; } = ToFRMode.Long;
+ public FiendsRefights FiendsRefights { get; set; } = FiendsRefights.All;
+ public bool? ExitToFR { get; set; } = false;
+ public bool? ChaosFloorEncounters { get; set; } = false;
+ public bool? MagicShops { get; set; } = false;
+ public bool? MagicShopLocs { get; set; } = false;
+ public bool? MagicShopLocationPairs { get; set; } = false;
+ public bool? MagicLevels { get; set; } = false;
+ public bool? MagicPermissions { get; set; } = false;
+ public bool? Weaponizer { get; set; } = false;
+ public bool? WeaponizerNamesUseQualityOnly { get; set; } = false;
+ public bool? WeaponizerCommonWeaponsHavePowers { get; set; } = false;
+ public bool? ArmorCrafter { get; set; } = false;
+ public bool? MagicLevelsTiered { get; set; } = false;
+ public bool? MagicLevelsMixed { get; set; } = false;
+
+ public AutohitThreshold MagicAutohitThreshold { get; set; } = AutohitThreshold.Vanilla;
+
+ public bool? Rng { get; set; } = false;
+ public bool FixMissingBattleRngEntry { get; set; } = false;
+
+ public bool? EncounterPrng { get; set; } = false;
+
+ public bool? UnrunnableShuffle { get; set; } = true;
+ [IntegerFlag(0, 100, 4)]
+ public int UnrunnablesLow { get; set; } = 0;
+ [IntegerFlag(0, 100, 4)]
+ public int UnrunnablesHigh { get; set; } = 0;
+ public bool? EnemyFormationsSurprise { get; set; } = false;
+ public bool? UnrunnablesStrikeFirstAndSurprise { get; set; } = false;
+
+ public TrapTileMode EnemyTrapTiles { get; set; } = TrapTileMode.Vanilla;
+ public FormationPool TCFormations { get; set; } = FormationPool.AltFormationDist;
+ public TCOptions TCBetterTreasure { get; set; } = TCOptions.None;
+ public TCOptions TCKeyItems { get; set; } = TCOptions.None;
+ public TCOptions TCShards { get; set; } = TCOptions.None;
+ public bool TCExcludeCommons { get; set; } = false;
+
+ [IntegerFlag(0, 260, 20)]
+ public int TCChestCount { get; set; } = 0;
+ public bool TCProtectIncentives { get; set; } = false;
+ public bool? TCMasaGuardian { get; set; } = false;
+ public bool? TrappedChaos { get; set; } = false;
+ public bool? TCIndicator { get; set; } = false;
+ public bool? SwolePirates { get; set; } = false;
+ public bool? ShuffleScriptsEnemies { get; set; } = false;
+ public bool? RemoveBossScripts { get; set; } = false;
+ public bool? ShuffleScriptsBosses { get; set; } = false;
+ public bool? ShuffleSkillsSpellsEnemies { get; set; } = false;
+ public bool? ShuffleSkillsSpellsBosses { get; set; } = false;
+ public bool? NoConsecutiveNukes { get; set; } = false;
+ public bool TranceHasStatusElement { get; set; } = false;
+ public bool? EnemySkillsSpellsTiered { get; set; } = false;
+ public bool? AllowUnsafePirates { get; set; } = false;
+ public bool? AllowUnsafeMelmond { get; set; } = false;
+
+ public WarMECHMode WarMECHMode { get; set; } = WarMECHMode.Vanilla;
+ public bool? OrdealsPillars { get; set; } = false;
+ public bool? ShuffleLavaTiles { get; set; } = false;
+ public SkyCastle4FMazeMode SkyCastle4FMazeMode { get; set; } = SkyCastle4FMazeMode.Vanilla;
+ public bool? TitansTrove { get; set; } = false;
+ public bool? LefeinSuperStore { get; set; } = false;
+ public bool? LefeinShops { get; set; } = false;
+ public bool? RandomVampAttack { get; set; } = false;
+ public bool? RandomVampAttackIncludesConeria { get; set; } = false;
+ public bool? FightBahamut { get; set; } = false;
+ public bool? SwoleBahamut { get; set; } = false;
+ public bool? SwoleAstos { get; set; } = false;
+ public bool? ConfusedOldMen { get; set; } = false;
+ public bool? GaiaShortcut { get; set; } = false;
+
+ [IntegerFlag(0, 10, 1)]
+ public int DamageTileLow { get; set; } = 1;
+ [IntegerFlag(0, 10, 1)]
+ public int DamageTileHigh { get; set; } = 1;
+ public bool? OWDamageTiles { get; set; } = false;
+ public bool? DamageTilesKill { get; set; } = false;
+ public bool? ArmorResistsDamageTileDamage { get; set; } = false;
+
+ public bool? MoveGaiaItemShop { get; set; } = false;
+ public bool? ShufflePravokaShops { get; set; } = false;
+ public bool? FlipDungeons { get; set; } = false;
+ public bool? VerticallyFlipDungeons { get; set; } = false;
+ public bool SpookyFlag { get; set; } = false;
+ public bool DraculasFlag { get; set; } = false;
+ public bool? MapOpenProgression { get; set; } = false;
+ public bool? MapOpenProgressionDocks { get; set; } = false;
+ public bool? Entrances { get; set; } = false;
+ public bool? Towns { get; set; } = false;
+ public bool? IncludeConeria { get; set; } = false;
+ public bool? Floors { get; set; } = false;
+ public bool? AllowDeepCastles { get; set; } = false;
+ public bool? AllowDeepTowns { get; set; } = false;
+ public bool? MapOpenProgressionExtended { get; set; } = false;
+ public bool? MapAirshipDock { get; set; } = false;
+ public bool? MapBahamutCardiaDock { get; set; } = false;
+ public bool? MapLefeinRiver { get; set; } = false;
+ public bool? MapBridgeLefein { get; set; } = false;
+ public bool? MapRiverToMelmond { get; set; } = false;
+ public bool? MapGaiaMountainPass { get; set; } = false;
+ public bool? MapHighwayToOrdeals { get; set; } = false;
+ public bool? MapDragonsHoard { get; set; } = false;
+ public bool? MapHallOfDragons { get; set; } = false;
+ public bool? EntrancesIncludesDeadEnds { get; set; } = false;
+ public bool? EntrancesMixedWithTowns { get; set; } = false;
+
+ public bool? IncentivizeFreeNPCs { get; set; } = false;
+ public bool? IncentivizeFetchNPCs { get; set; } = false;
+ public bool? IncentivizeTail { get; set; } = false;
+ public bool? IncentivizeMainItems { get; set; } = false;
+ public bool? IncentivizeFetchItems { get; set; } = false;
+ public bool? IncentivizeCanoeItem { get; set; } = false;
+ public bool? IncentivizeAirship { get; set; } = false;
+ public bool? IncentivizeShipAndCanal { get; set; } = false;
+ public bool? IncentivizeBridgeItem { get; set; } = false;
+
+ public bool? IncentivizeMarsh { get; set; } = false;
+ public bool? IncentivizeEarth { get; set; } = false;
+ public bool? IncentivizeVolcano { get; set; } = false;
+ public bool? IncentivizeIceCave { get; set; } = false;
+ public bool? IncentivizeOrdeals { get; set; } = false;
+ public bool? IncentivizeSeaShrine { get; set; } = false;
+ public bool? IncentivizeConeria { get; set; } = false;
+ public bool? IncentivizeMarshKeyLocked { get; set; } = false;
+ public bool? IncentivizeSkyPalace { get; set; } = false;
+ public bool? IncentivizeTitansTrove { get; set; } = false;
+ public bool? IncentivizeCardia { get; set; } = false;
+
+ public IncentivePlacementType IceCaveIncentivePlacementType { get; set; } = IncentivePlacementType.Vanilla;
+ public IncentivePlacementType OrdealsIncentivePlacementType { get; set; } = IncentivePlacementType.Vanilla;
+ public IncentivePlacementType MarshIncentivePlacementType { get; set; } = IncentivePlacementType.Vanilla;
+ public IncentivePlacementType TitansIncentivePlacementType { get; set; } = IncentivePlacementType.Vanilla;
+ public IncentivePlacementTypeEarth EarthIncentivePlacementType { get; set; } = IncentivePlacementTypeEarth.Vanilla;
+ public IncentivePlacementTypeVolcano VolcanoIncentivePlacementType { get; set; } = IncentivePlacementTypeVolcano.Vanilla;
+ public IncentivePlacementTypeSea SeaShrineIncentivePlacementType { get; set; } = IncentivePlacementTypeSea.Vanilla;
+ public IncentivePlacementTypeSky SkyPalaceIncentivePlacementType { get; set; } = IncentivePlacementTypeSky.Vanilla;
+ public IncentivePlacementType CorneriaIncentivePlacementType { get; set; } = IncentivePlacementType.Vanilla;
+ public IncentivePlacementType MarshLockedIncentivePlacementType { get; set; } = IncentivePlacementType.Vanilla;
+ public IncentivePlacementType CardiaIncentivePlacementType { get; set; } = IncentivePlacementType.Vanilla;
+
+ public bool? BetterTrapChests { get; set; } = false;
+ public bool? IncentivizeMasamune { get; set; } = false;
+ public bool? IncentivizeKatana { get; set; } = false;
+ public bool? IncentivizeXcalber { get; set; } = false;
+ public bool? IncentivizeVorpal { get; set; } = false;
+ public bool? IncentivizeOpal { get; set; } = false;
+ public bool? IncentivizeRibbon { get; set; } = false;
+ public bool? IncentivizeDefCastArmor { get; set; } = false;
+ public bool? IncentivizeOffCastArmor { get; set; } = false;
+ public bool? IncentivizeOtherCastArmor { get; set; } = false;
+ public bool? IncentivizePowerRod { get; set; } = false;
+ public bool? IncentivizeDefCastWeapon { get; set; } = false;
+ public bool? IncentivizeOffCastWeapon { get; set; } = false;
+ public bool IncentivizeOtherCastWeapon { get; set; } = false;
+ public bool? LooseExcludePlacedDungeons { get; set; } = false;
+ public bool? EarlyKing { get; set; } = false;
+ public bool? EarlySarda { get; set; } = false;
+ public bool? EarlySage { get; set; } = false;
+ public bool? EarlyOrdeals { get; set; } = false;
+ public bool? ShuffleObjectiveNPCs { get; set; } = false;
+ public bool OnlyRequireGameIsBeatable { get; set; } = true;
+ public bool? FreeBridge { get; set; } = false;
+ public bool? FreeShip { get; set; } = false;
+ public bool? FreeAirship { get; set; } = false;
+ public bool? FreeLute { get; set; } = false;
+ public bool? FreeRod { get; set; } = false;
+ public bool EnableCritNumberDisplay { get; set; } = false;
+ public bool? FreeCanal { get; set; } = false;
+ public bool? FreeCanoe { get; set; } = false;
+ public bool EasyMode { get; set; } = false;
+
+ public bool HousesFillHp { get; set; } = false;
+
+ public bool SpeedHacks { get; set; } = false;
+ public bool NoPartyShuffle { get; set; } = false;
+ public bool Dash { get; set; } = false;
+ public bool SpeedBoat { get; set; } = false;
+ public bool? AirBoat { get; set; } = false;
+ public bool BuyTen { get; set; } = false;
+ public bool IdentifyTreasures { get; set; } = false;
+ public bool ShopInfo { get; set; } = false;
+ public bool ChestInfo { get; set; } = false;
+ public bool IncentiveChestItemsFanfare { get; set; } = false;
+ public bool WaitWhenUnrunnable { get; set; } = false;
+ public bool ImprovedClinic { get; set; } = false;
+ public bool Etherizer { get; set; } = false;
+ // Done
+ public bool HouseMPRestoration { get; set; } = false;
+ public bool WeaponStats { get; set; } = false;
+ public bool BBCritRate { get; set; } = false;
+ public bool WeaponCritRate { get; set; } = false;
+ public bool WeaponBonuses { get; set; } = false;
+ public ThiefAGI ThiefAgilityBuff { get; set; } = ThiefAGI.Vanilla;
+ public SpoilerBatHints SkyWarriorSpoilerBats { get; set; } = SpoilerBatHints.Vanilla;
+ public bool? SpoilerBatsDontCheckOrbs { get; set; } = false;
+ public bool? MoveToFBats { get; set; } = false;
+
+ [IntegerFlag(0, 50)]
+ public int WeaponTypeBonusValue { get; set; } = 10;
+
+ public ChanceToRunMode ChanceToRun { get; set; } = ChanceToRunMode.Vanilla;
+
+ public bool SpellBugs { get; set; } = false;
+ public bool BlackBeltAbsorb { get; set; } = false;
+ public bool NPCSwatter { get; set; } = false;
+ public bool BattleMagicMenuWrapAround { get; set; } = false;
+ public bool MagicMenuSpellReordering { get; set; } = false;
+ public bool InventoryAutosort { get; set; } = false;
+ public bool RepeatedHealPotionUse { get; set; } = false;
+ public bool AutoRetargeting { get; set; } = false;
+ public bool EnemyStatusAttackBug { get; set; } = false;
+ public bool ImproveTurnOrderRandomization { get; set; } = false;
+ public bool FixHitChanceCap { get; set; } = false;
+
+ public bool? MelmondClinic { get; set; } = false;
+ public bool DDProgressiveTilesets { get; set; } = false;
+ public bool DDFiendOrbs { get; set; } = false;
+ public TailBahamutMode TailBahamutMode { get; set; } = TailBahamutMode.Random;
+ public StartingGold StartingGold { get; set; } = StartingGold.Gp400;
+ public bool IncludeMorale { get; set; } = false;
+ public bool DeadsGainXP { get; set; } = false;
+ public bool NonesGainXP { get; set; } = false;
+ public bool? NoTail { get; set; } = false;
+ public bool? NoFloater { get; set; } = false;
+ public bool? GuaranteedMasamune { get; set; } = false;
+ public bool? SendMasamuneHome { get; set; } = false;
+
+ public ConsumableChestSet MoreConsumableChests { get; set; } = ConsumableChestSet.Vanilla;
+
+ public bool? NoMasamune { get; set; } = false;
+ public bool? NoXcalber { get; set; } = false;
+ public bool? ClassAsNpcFiends { get; set; } = false;
+ public bool? ClassAsNpcKeyNPC { get; set; } = false;
+
+ [IntegerFlag(0, 13)]
+ public int ClassAsNpcCount { get; set; } = 6;
+ public bool? ClassAsNpcDuplicate { get; set; } = false;
+ public bool? ClassAsNpcForcedFiends { get; set; } = false;
+ public bool? ClassAsNpcPromotion { get; set; } = false;
+
+ [IntegerFlag(0, 500, 10)]
+ public int BossScaleStatsLow { get; set; } = 50;
+
+ [IntegerFlag(0, 500, 10)]
+ public int BossScaleStatsHigh { get; set; } = 200;
+
+ [IntegerFlag(0, 500, 10)]
+ public int BossScaleHpLow { get; set; } = 50;
+
+ [IntegerFlag(0, 500, 10)]
+ public int BossScaleHpHigh { get; set; } = 200;
+
+ [IntegerFlag(0, 500, 10)]
+ public int EnemyScaleStatsLow { get; set; } = 50;
+
+ [IntegerFlag(0, 500, 10)]
+ public int EnemyScaleStatsHigh { get; set; } = 200;
+
+ [IntegerFlag(0, 500, 10)]
+ public int EnemyScaleHpLow { get; set; } = 50;
+
+ [IntegerFlag(0, 500, 10)]
+ public int EnemyScaleHpHigh { get; set; } = 200;
+
+ [IntegerFlag(0, 500, 10)]
+ public int PriceScaleFactorLow { get; set; } = 50;
+
+ [IntegerFlag(0, 500, 10)]
+ public int PriceScaleFactorHigh { get; set; } = 200;
+
+ [DoubleFlag(1.0, 5.0, 0.1)]
+ public double ExpMultiplier { get; set; } = 0;
+
+ [IntegerFlag(0, 250, 25)]
+ public int ExpBonus { get; set; } = 0;
+
+ [DoubleFlag(0.5, 3.0, 0.1)]
+ public double ExpMultiplierFighter { get; set; } = 1.0;
+
+ [DoubleFlag(0.5, 3.0, 0.1)]
+ public double ExpMultiplierThief { get; set; } = 1.0;
+
+ [DoubleFlag(0.5, 3.0, 0.1)]
+ public double ExpMultiplierBlackBelt { get; set; } = 1.0;
+
+ [DoubleFlag(0.5, 3.0, 0.1)]
+ public double ExpMultiplierRedMage { get; set; } = 1.0;
+
+ [DoubleFlag(0.5, 3.0, 0.1)]
+ public double ExpMultiplierWhiteMage { get; set; } = 1.0;
+
+ [DoubleFlag(0.5, 3.0, 0.1)]
+ public double ExpMultiplierBlackMage { get; set; } = 1.0;
+
+ [DoubleFlag(0, 45)]
+ public double EncounterRate { get; set; } = 0;
+
+ [DoubleFlag(0, 45)]
+ public double DungeonEncounterRate { get; set; } = 0;
+ public ProgressiveScaleMode ProgressiveScaleMode { get; set; } = ProgressiveScaleMode.Disabled;
+
+ public StartingItemSet StartingItemSet { get; set; } = StartingItemSet.None;
+
+ public TreasureStackSize ConsumableTreasureStackSize { get; set; } = TreasureStackSize.Default;
+
+ public bool? FIGHTER1 { get; set; } = false;
+ public bool? THIEF1 { get; set; } = false;
+ public bool? BLACK_BELT1 { get; set; } = false;
+ public bool? RED_MAGE1 { get; set; } = false;
+ public bool? WHITE_MAGE1 { get; set; } = false;
+ public bool? BLACK_MAGE1 { get; set; } = false;
+
+ public bool? FIGHTER2 { get; set; } = false;
+ public bool? THIEF2 { get; set; } = false;
+ public bool? BLACK_BELT2 { get; set; } = false;
+ public bool? RED_MAGE2 { get; set; } = false;
+ public bool? WHITE_MAGE2 { get; set; } = false;
+ public bool? BLACK_MAGE2 { get; set; } = false;
+
+ public bool? FIGHTER3 { get; set; } = false;
+ public bool? THIEF3 { get; set; } = false;
+ public bool? BLACK_BELT3 { get; set; } = false;
+ public bool? RED_MAGE3 { get; set; } = false;
+ public bool? WHITE_MAGE3 { get; set; } = false;
+ public bool? BLACK_MAGE3 { get; set; } = false;
+
+ public bool? FIGHTER4 { get; set; } = false;
+ public bool? THIEF4 { get; set; } = false;
+ public bool? BLACK_BELT4 { get; set; } = false;
+ public bool? RED_MAGE4 { get; set; } = false;
+ public bool? WHITE_MAGE4 { get; set; } = false;
+ public bool? BLACK_MAGE4 { get; set; } = false;
+
+ public bool? KNIGHT1 { get; set; } = false;
+ public bool? KNIGHT2 { get; set; } = false;
+ public bool? KNIGHT3 { get; set; } = false;
+ public bool? KNIGHT4 { get; set; } = false;
+ public bool? NINJA1 { get; set; } = false;
+ public bool? NINJA2 { get; set; } = false;
+ public bool? NINJA3 { get; set; } = false;
+ public bool? NINJA4 { get; set; } = false;
+ public bool? MASTER1 { get; set; } = false;
+ public bool? MASTER2 { get; set; } = false;
+ public bool? MASTER3 { get; set; } = false;
+ public bool? MASTER4 { get; set; } = false;
+ public bool? RED_WIZ1 { get; set; } = false;
+ public bool? RED_WIZ2 { get; set; } = false;
+ public bool? RED_WIZ3 { get; set; } = false;
+ public bool? RED_WIZ4 { get; set; } = false;
+ public bool? WHITE_WIZ1 { get; set; } = false;
+ public bool? WHITE_WIZ2 { get; set; } = false;
+ public bool? WHITE_WIZ3 { get; set; } = false;
+ public bool? WHITE_WIZ4 { get; set; } = false;
+ public bool? BLACK_WIZ1 { get; set; } = false;
+ public bool? BLACK_WIZ2 { get; set; } = false;
+ public bool? BLACK_WIZ3 { get; set; } = false;
+ public bool? BLACK_WIZ4 { get; set; } = false;
+ public bool? NONE_CLASS2 { get; set; } = false;
+ public bool? NONE_CLASS3 { get; set; } = false;
+ public bool? NONE_CLASS4 { get; set; } = false;
+ public bool? FORCED1 { get; set; } = false;
+ public bool? FORCED2 { get; set; } = false;
+ public bool? FORCED3 { get; set; } = false;
+ public bool? FORCED4 { get; set; } = false;
+ public bool? DraftFighter { get; set; } = false;
+ public bool? DraftThief { get; set; } = false;
+ public bool? DraftBlackBelt { get; set; } = false;
+ public bool? DraftRedMage { get; set; } = false;
+ public bool? DraftWhiteMage { get; set; } = false;
+ public bool? DraftBlackMage { get; set; } = false;
+ public bool? DraftKnight { get; set; } = false;
+ public bool? DraftNinja { get; set; } = false;
+ public bool? DraftMaster { get; set; } = false;
+ public bool? DraftRedWiz { get; set; } = false;
+ public bool? DraftWhiteWiz { get; set; } = false;
+ public bool? DraftBlackWiz { get; set; } = false;
+ public bool? TAVERN1 { get; set; } = false;
+ public bool? TAVERN2 { get; set; } = false;
+ public bool? TAVERN3 { get; set; } = false;
+ public bool? TAVERN4 { get; set; } = false;
+ public bool? TAVERN5 { get; set; } = false;
+ public bool? TAVERN6 { get; set; } = false;
+
+ public bool WeaponPermissions { get; set; } = false;
+ public bool ArmorPermissions { get; set; } = false;
+ public bool? RecruitmentMode { get; set; } = false;
+ public bool? RecruitmentModeHireOnly { get; set; } = false;
+ public bool? RecruitmentModeReplaceOnlyNone { get; set; } = false;
+ public bool? ClampMinimumStatScale { get; set; } = false;
+ public bool? ClampMinimumBossStatScale { get; set; } = false;
+ public bool? ClampMinimumPriceScale { get; set; } = false;
+ public bool EFGWaterfall { get; set; } = false;
+ public bool? FiendShuffle { get; set; } = false;
+ public bool DisableTentSaving { get; set; } = false;
+ public bool DisableInnSaving { get; set; } = false;
+ public bool SaveGameWhenGameOver { get; set; } = false;
+ public bool SaveGameDWMode { get; set; } = false;
+ public bool? ShuffleAstos { get; set; } = false;
+ public bool UnsafeAstos { get; set; } = false;
+ public bool? RandomizeEnemizer { get; set; } = false;
+ public bool? RandomizeFormationEnemizer { get; set; } = false;
+ public bool? GenerateNewSpellbook { get; set; } = false;
+ public bool? SpellcrafterMixSpells { get; set; } = false;
+ public bool ThiefHitRate { get; set; } = false;
+ public bool AllSpellLevelsForKnightNinja { get; set; } = false;
+ public bool BuffHealingSpells { get; set; } = false;
+ public bool IntAffectsSpells { get; set; } = false;
+ public bool? AddDamageTiles { get; set; } = false;
+ public bool? DamageTilesCastles { get; set; } = false;
+ public bool? DamageTilesDungeons { get; set; } = false;
+ public bool? DamageTilesCaves { get; set; } = false;
+ public bool? DamageTilesTowns { get; set; } = false;
+ public bool? DamageTilesTof { get; set; } = false;
+ public DamageTilesQuantity DamageTilesQuantity { get; set; } = DamageTilesQuantity.Normal;
+ public bool? FreeTail { get; set; } = false;
+ public bool? HintsVillage { get; set; } = false;
+ public bool? SpellcrafterRetainPermissions { get; set; } = false;
+ public bool? RandomWeaponBonus { get; set; } = false;
+ public bool? RandomArmorBonus { get; set; } = false;
+ public bool? RandomWeaponBonusExcludeMasa { get; set; } = false;
+
+ [IntegerFlag(-9, 9)]
+ public int RandomWeaponBonusLow { get; set; } = -5;
+
+ [IntegerFlag(-9, 9)]
+ public int RandomWeaponBonusHigh { get; set; } = 5;
+
+ [IntegerFlag(-9, 9)]
+ public int RandomArmorBonusLow { get; set; } = -5;
+
+ [IntegerFlag(-9, 9)]
+ public int RandomArmorBonusHigh { get; set; } = 5;
+ public bool? SeparateBossHPScaling { get; set; } = false;
+ public bool? SeparateEnemyHPScaling { get; set; } = false;
+ public bool? ClampBossHPScaling { get; set; } = false;
+ public bool? ClampEnemyHpScaling { get; set; } = false;
+ public PoolSize PoolSize { get; set; } = PoolSize.Size6;
+ public bool? EnablePoolParty { get; set; } = false;
+ public bool SafePoolParty { get; set; } = false;
+ public bool? IncludePromClasses { get; set; } = false;
+ public bool? EnableRandomPromotions { get; set; } = false;
+ public bool? IncludeBaseClasses { get; set; } = false;
+ public bool? RandomPromotionsSpoilers { get; set; } = false;
+ public bool? RandomizeClassCasting { get; set; } = false;
+ public bool? RandomizeClassKeyItems { get; set; } = false;
+ public bool? RandomizeClassIncludeXpBonus { get; set; } = false;
+ public bool? AlternateFiends { get; set; } = false;
+ public bool? FinalFantasy2Fiends { get; set; } = false;
+ public bool? FinalFantasy3Fiends { get; set; } = false;
+ public bool? FinalFantasy4Fiends { get; set; } = false;
+ public bool? FinalFantasy5Fiends { get; set; } = false;
+ public bool? FinalFantasy6Fiends { get; set; } = false;
+ public bool? FinalFantasy1BonusFiends { get; set; } = false;
+ public bool? BlackOrbFiends { get; set; } = false;
+ public bool? NoBossSkillScriptShuffle { get; set; } = false;
+
+ public bool? MooglieWeaponBalance { get; set; } = false;
+ public bool? GuaranteeCustomClassComposition { get; set; } = false;
+
+ public bool? LegendaryWeaponShop { get; set; } = false;
+ public bool? LegendaryArmorShop { get; set; } = false;
+ public bool? LegendaryBlackShop { get; set; } = false;
+ public bool? LegendaryWhiteShop { get; set; } = false;
+ public bool? LegendaryItemShop { get; set; } = false;
+
+ public bool ExclusiveLegendaryWeaponShop { get; set; } = false;
+ public bool ExclusiveLegendaryArmorShop { get; set; } = false;
+ public bool ExclusiveLegendaryBlackShop { get; set; } = false;
+ public bool ExclusiveLegendaryWhiteShop { get; set; } = false;
+ public bool ExclusiveLegendaryItemShop { get; set; } = false;
+ public ClassRandomizationMode RandomizeClassMode { get; set; } = ClassRandomizationMode.None;
+
+ [IntegerFlag(0, 3)]
+ public int RandomizeClassMaxBonus { get; set; } = 2;
+
+ [IntegerFlag(0, 3)]
+ public int RandomizeClassMaxMalus { get; set; } = 1;
+ public bool? EarlierHighTierMagic { get; set; } = false;
+ public bool? ChangeMaxMP { get; set; } = false;
+
+ [IntegerFlag(0, 9)]
+ public int RedMageMaxMP { get; set; } = 9;
+
+ [IntegerFlag(0, 9)]
+ public int WhiteMageMaxMP { get; set; } = 9;
+
+ [IntegerFlag(0, 9)]
+ public int BlackMageMaxMP { get; set; } = 9;
+
+ [IntegerFlag(0, 9)]
+ public int KnightMaxMP { get; set; } = 4;
+
+ [IntegerFlag(0, 9)]
+ public int NinjaMaxMP { get; set; } = 4;
+
+ public bool? Knightlvl4 { get; set; } = false;
+ public bool? PinkMage { get; set; } = false;
+ public bool? BlackKnight { get; set; } = false;
+ public bool? BlackKnightKeep { get; set; } = false;
+ public bool? WhiteNinja { get; set; } = false;
+ public bool? WhiteNinjaKeep { get; set; } = false;
+
+ public MpGainOnMaxGain MpGainOnMaxGainMode { get; set; } = MpGainOnMaxGain.None;
+
+ public LockHitMode LockMode { get; set; } = LockHitMode.Vanilla;
+ // Done
+ public MDEFGrowthMode MDefMode { get; set; } = MDEFGrowthMode.None;
+
+ public FormationShuffleMode FormationShuffleMode { get; set; } = FormationShuffleMode.None;
+
+ public RandomizeTreasureMode RandomizeTreasure { get; set; } = RandomizeTreasureMode.None;
+ public bool OpenChestsInOrder { get; set; } = false;
+ public bool SetRNG { get; set; } = false;
+ public WorldWealthMode WorldWealth { get; set; } = WorldWealthMode.Standard;
+ public DeepDungeonGeneratorMode DeepDungeonGenerator { get; set; } = DeepDungeonGeneratorMode.Progressive;
+ public EvadeCapValues EvadeCap { get; set; } = EvadeCapValues.medium;
+
+ public bool? AllowUnsafeStartArea { get; set; } = false;
+
+ public bool? IncreaseDarkPenalty { get; set; } = false;
+ public bool? IncreaseRegeneration { get; set; } = false;
+ public PoisonModeOptions PoisonMode { get; set; } = PoisonModeOptions.Constant;
+ [IntegerFlag(1,500)]
+
+ public int PoisonSetDamageValue { get; set; } = 3;
+
+ public bool? TouchIncludeBosses { get; set; } = false;
+
+ public bool? Lockpicking { get; set; } = false;
+ // Done
+ public bool? ReducedLuck { get; set; } = false;
+
+ [IntegerFlag(1, 50)]
+ public int LockpickingLevelRequirement { get; set; } = 10;
+
+ public bool WhiteMageHarmEveryone { get; set; } = false;
+
+ public bool? ProcgenEarth { get; set; } = false;
+ }
+}
diff --git a/FF1Lib/Hacks.cs b/FF1Lib/Hacks.cs
index d542fd723..10edfb351 100644
--- a/FF1Lib/Hacks.cs
+++ b/FF1Lib/Hacks.cs
@@ -325,6 +325,16 @@ public void IncreaseDarkPenalty(bool enable)
Put(0x326A7, Blob.FromHex("A9008D56688D62681A"));
}
+ public void IncreaseRegeneration(bool enable)
+ {
+ if (!enable)
+ {
+ return;
+ }
+
+ PutInBank(0x0C, 0xA26A, Blob.FromHex("39"));
+ }
+
public void SetPoisonMode(PoisonModeOptions poisonMode, int poisonValue)
{
//see 1C_A670_ImprovedPoison.asm
diff --git a/FF1Lib/Randomize.cs b/FF1Lib/Randomize.cs
index 71ac4614b..be0359fc1 100644
--- a/FF1Lib/Randomize.cs
+++ b/FF1Lib/Randomize.cs
@@ -1,445 +1,446 @@
-using FF1Lib.Music;
-using FF1Lib.Procgen;
-using RomUtilities;
-namespace FF1Lib;
-
-// ReSharper disable once InconsistentNaming
-public partial class FF1Rom : NesRom
-{
- public const int LevelRequirementsOffset = 0x6CC81;
- public const int LevelRequirementsSize = 3;
- public const int LevelRequirementsCount = 49;
-
- public const int GoldItemOffset = 108; // 108 items before gold chests
- public const int GoldItemCount = 68;
- //public List UnusedGoldItems = new List { 110, 111, 112, 113, 114, 116, 120, 121, 122, 124, 125, 127, 132, 158, 165, 166, 167, 168, 170, 171, 172 };
-
- public ItemNames ItemsText;
- public GearPermissions ArmorPermissions;
- public GearPermissions WeaponPermissions;
- public SpellPermissions SpellPermissions;
- public GameClasses ClassData;
- public RngTables RngTables;
- public TileSetsData TileSetsData;
- public ZoneFormations ZoneFormations;
- public StandardMaps Maps;
- public NpcObjectData NpcData;
- public DialogueData Dialogues;
- public MenuText MenuText;
- public TalkRoutines TalkRoutines;
- public StartingItems StartingItems;
- public EncounterRate EncounterRates;
- public EnemyScripts EnemyScripts;
- public ShopData ShopData;
- public MusicTracks Music;
- public NewMusic NewMusic;
- public ExtAltFiends ExtAltFiends;
-
- public DeepDungeon DeepDungeon;
-
- public OwMapExchange OverworldMapData;
- public Teleporters Teleporters;
- public Overworld Overworld;
-
- private SanityCheckerV2 sanityChecker = null;
- private PlacementContext PlacementContext = null;
-
- private Blob SavedHash;
-
- public void LoadSharedDataTables()
- {
- ItemsText = new ItemNames(this);
- ArmorPermissions = new GearPermissions(0x3BFA0, (int)Item.Cloth, this);
- WeaponPermissions = new GearPermissions(0x3BF50, (int)Item.WoodenNunchucks, this);
- SpellPermissions = new SpellPermissions(this);
- ClassData = new GameClasses(WeaponPermissions, ArmorPermissions, SpellPermissions, this);
- }
-
- public delegate Task ProgressMessage(int step, int max, string message);
-
- public delegate Task ReportProgress(string message="", int addMax=0);
-
- int currentStep = 0;
- int maxSteps = 0;
- public ProgressMessage ProgressCallback;
-
- public async Task Progress(string message="", int addMax=0)
- {
- maxSteps += addMax;
- currentStep += 1;
- if (ProgressCallback != null) {
- await ProgressCallback(currentStep, maxSteps, message);
- }
- }
- public async Task Randomize(Blob seed, Flags flags, Preferences preferences)
- {
- // Confirm ROM integrity
- if (flags.TournamentSafe) AssureSafe();
-
- // Copy flags for various use
- Flags flagsForRng = flags.ShallowCopy();
- Flags unmodifiedFlags = flags.ShallowCopy();
-
- // Setup Rng
- Blob resourcesPackHash = GenerateRng(flagsForRng, seed);
-
- // Collapse tristate flags
- flags = Flags.ConvertAllTriState(flags, rng);
-
- await this.Progress("Beginning Randomization", 15);
-
- // load resource pack data that needs to go into initial ROM before
- // data is read
- await this.LoadResourcePackPreROM(flags.ResourcePack, preferences);
- await this.LoadFunTiles(preferences);
-
- // Load Initial Data
- RngTables = new(this);
- TileSetsData = new(this);
- ZoneFormations = new(this);
- Overworld = new(this, flags, ZoneFormations, rng);
- await Overworld.LoadMapExchange();
- ItemsText = new ItemNames(this);
- ArmorPermissions = new GearPermissions(0x3BFA0, (int)Item.Cloth, this);
- WeaponPermissions = new GearPermissions(0x3BF50, (int)Item.WoodenNunchucks, this);
- SpellPermissions = new SpellPermissions(this);
- ClassData = new GameClasses(WeaponPermissions, ArmorPermissions, SpellPermissions, this);
- Teleporters = new Teleporters(this, Overworld.MapExchangeData);
- Maps = new StandardMaps(this, Teleporters, flags);
- NpcData = new NpcObjectData(Maps, flags, rng, this);
- TalkRoutines = new TalkRoutines();
- Dialogues = new DialogueData(this);
- MenuText = new MenuText(this);
- ShopData = new ShopData(flags, this);
- EncounterRates = new EncounterRate(this);
- EnemyScripts = new EnemyScripts(this);
- Music = new MusicTracks();
- ExtAltFiends = new ExtAltFiends(flags);
-
-
- await this.Progress();
-
- // Expand ROM, move data around
- GlobalHacks();
-
- // load resource pack data that requires the ROM expansion that just took place
- await this.LoadResourcePackPostROM(flags.ResourcePack, Dialogues, EnemyScripts, preferences);
-
-
- TalkRoutines.TransferTalkRoutines(this, flags);
- Dialogues.TransferDialogues();
-
- // Apply general fixes and hacks
- FF1Text.AddNewIcons(this, flags);
- Music.ShuffleMusic(this, preferences, new MT19337(funRng.Next()));
- NewMusic = new NewMusic(this);
- Bugfixes(flags);
- GlobalImprovements(flags, Maps, preferences);
- MiscHacks(flags, rng);
- var oldItemNames = ItemsText.ToList();
- MapIndex warmMechFloor = MapIndex.SkyPalace4F;
-
- // Load Ressources Packs Maps
- LoadResourcePackMaps(flags.ResourcePack, Maps, Teleporters);
-
- await this.Progress();
-
- // Game Modes
- DeepDungeon = new DeepDungeon(Maps, Teleporters, NpcData, TileSetsData, flags, this);
- if (flags.GameMode == GameModes.DeepDungeon)
- {
- await this.Progress("Generating Deep Dungeon's Floors...", 2);
-
- DeepDungeon.Generate(rng, Overworld, EncounterRates, ZoneFormations, Dialogues);
- DeepDungeonFloorIndicator();
- warmMechFloor = (MapIndex)DeepDungeon.WarMechFloor;
-
- await this.Progress("Generating Deep Dungeon's Floors... Done!");
- }
- DesertOfDeath.ApplyDesertModifications((bool)flags.DesertOfDeath, this, ZoneFormations, Overworld, NpcData, Dialogues, Music);
- Spooky(TalkRoutines, NpcData, Dialogues, ZoneFormations, Maps, rng, flags);
- BlackOrbMode(TalkRoutines, Dialogues, flags, preferences, rng, new MT19337(funRng.Next()));
- Maps.ProcgenDungeons(rng);
- DraculasCurse(Overworld, Teleporters, rng, flags);
-
- await this.Progress();
-
- // Maps
- GeneralMapHacks(flags, Overworld, Maps, ZoneFormations, TileSetsData, rng);
- Maps.Update(ZoneFormations, rng);
- if (flags.NoOverworld) await this.Progress("Linking NoOverworld's Map", 1);
- NoOverworld(Overworld.DecompressedMap, Maps, Teleporters, TileSetsData, TalkRoutines, Dialogues, NpcData, flags, rng);
- UpdateToFR(Maps, Teleporters, TileSetsData, flags, rng);
- Teleporters.ShuffleEntrancesAndFloors(Overworld.OverworldMap, rng, flags);
- Overworld.Update(Teleporters);
- EncounterRates.ScaleEncounterRate(flags);
-
- // Tile Sets
- TileSetsData.Update(flags, rng);
- TileSetsData.UpdateTrapTiles(this, ZoneFormations, flags, rng);
- await DamageTilesHack(flags, Overworld);
-
- await this.Progress();
-
- // NPCs
- Dialogues.UpdateNPCDialogues(flags);
- PacifistBat(Maps, TalkRoutines, NpcData);
- TalkRoutines.Update(flags);
- ClassAsNPC(flags, TalkRoutines, NpcData, Dialogues, Maps, rng);
-
- // Relocate chests need to happen after NPCs, before logic
- await new RelocateChests(this).RandomlyRelocateChests(rng, Maps, TileSetsData, Teleporters, NpcData, flags);
-
- // Spells
- CraftNewSpellbook(EnemyScripts, flags, rng);
- SpellBalanceHacks(flags, rng);
- TranceHasStatusElement(flags.TranceHasStatusElement);
- ShuffleMagicLevels(EnemyScripts, rng, (bool)flags.MagicLevels, (bool)flags.MagicPermissions, (bool)flags.MagicLevelsTiered, (bool)flags.MagicLevelsMixed);
- SpellNames(flags, preferences, rng);
- var extConsumables = new ExtConsumables(ShopData, this, flags, rng);
- extConsumables.LoadSpells();
-
- // Create items
- Etherizer(flags.Etherizer, ItemsText);
-
- Weaponizer(flags, rng);
- ArmorCrafter(flags, rng);
- new RibbonShuffle(this, rng, flags, ItemsText, ArmorPermissions).Work();
-
- ItemMagic(flags, rng);
-
- DoubleWeaponCritRates(flags.WeaponCritRate);
- List weaponBlursesValues = Enumerable.Repeat(0, 40).ToList();
- RandomWeaponBonus(flags, preferences.CleanBlursedEquipmentNames, weaponBlursesValues, rng);
- RandomArmorBonus(flags, preferences.CleanBlursedEquipmentNames, rng);
- IncreaseWeaponBonus(flags.WeaponBonuses, flags.WeaponTypeBonusValue);
-
- // Starting Inventory
- StartingItems = new StartingItems(new() { }, rng, flags, this);
-
- // Placement Context
- var priceList = Get(0x37C00, 0x200).ToUShorts().Select(x => (int)x).ToList(); // Temporary until we extract price
- PlacementContext = (flags.GameMode != GameModes.DeepDungeon) ?
- new PlacementContext(StartingItems, new() { }, priceList, rng, flags) :
- new PlacementContext(StartingItems, new() { }, DeepDungeon.PlacedItems, DeepDungeon.ChestLocations, priceList, rng, flags);
-
- // Shops
- ShopData.ShuffleShops(rng, PlacementContext.ExcludedItemsFromShops, Teleporters.ConeriaTownEntranceItemShopIndex);
- ShopData.ShuffleMagicLocations((bool)flags.MagicShopLocs, (bool)flags.MagicShopLocationPairs, rng);
- ShopData.ShuffleMagicShops((bool)flags.MagicShops, rng);
- extConsumables.AddNormalShopEntries();
- new ShopKiller(Maps, ShopData, rng, flags, this).KillShops();
- new LegendaryShops(rng, flags, Maps, ShopData, TileSetsData, this).PlaceShops();
-
- await this.Progress("Building Placement Logic");
-
- // Create Logic Checker
- sanityChecker = new SanityCheckerV2(Maps, Overworld, NpcData, Teleporters, TileSetsData, this, ShopData.ItemShopSlot);
- if (!sanityChecker.CheckSanity(ItemLocations.AllQuestItemLocations.ToList(), null, flags, true).Complete) throw new InsaneException("Not Completable");
-
- await this.Progress(flags.VanillaPlacement ? "Placing Treasures" : "Shuffling Treasures");
-
- // Item Placement
- ItemPlacement itemPlacement = ItemPlacement.Create(this, flags, PlacementContext, ShopData.ItemShopSlot, Overworld, sanityChecker);
- itemPlacement.PlaceItems(rng);
-
- NpcData.UpdateItemPlacement(itemPlacement.PlacedItems);
- ShopData.UpdateShopSlotPlacement(itemPlacement.PlacedItems);
-
- List funMessages = new()
- {
- "Placing Out of Bound Bat",
- "Cleaning up Lich's closet",
- "Labelling pots in Sarda's Cave",
- "Partying in the Bat Party Room",
- "Buffing up NPC's path-blocking AI",
- "Debugging WarMech's software",
- "Knocking down some impertinent fools",
- "Sending Garland 2,000 years in the past",
- "Giving a snack to Titan while waiting for the main course",
- "Disguising Astos",
- "Cursing the Elf Prince",
- "Stealing Matoya's Crystal",
- "Abducting Princess Sara",
- "Placing the worst skills in Medusa's script",
- "Applying for a Bridge building permit",
- "Reticulating Splines",
- "Digging Cave Holes",
- "Bottling the Fairy",
- "Floating the Sky Castle",
- "Locking the door in Temple of Fiends",
- "Teaching Kraken Kung Fu",
- "Raising the Lich",
- };
-
- funMessages.AddRange(Enumerable.Repeat("Finalizing", funMessages.Count * 4).ToList());
-
- await this.Progress(funMessages.PickRandom(rng));
-
- // Enemies
- if ((bool)flags.AlternateFiends && !flags.SpookyFlag) await this.Progress("Creating new Fiends", 1);
- AlternativeFiends(ExtAltFiends, EnemyScripts, rng, flags);
- TransformFinalFormation(flags, rng);
- DoEnemizer(EnemyScripts, ZoneFormations, flags, rng);
-
- ShuffleEnemyScripts(rng, flags);
- EnemyScripts.ShuffleEnemySkillsSpells(this, rng, flags);
- StatusAttacks(flags, rng);
- ShuffleUnrunnable(rng, flags);
- AllowStrikeFirstAndSurprise(flags.WaitWhenUnrunnable, (bool)flags.UnrunnablesStrikeFirstAndSurprise);
- ShuffleSurpriseBonus((bool)flags.EnemyFormationsSurprise, rng);
-
- // After unrunnable shuffle and before formation shuffle
- WarMechMode.Process(this, flags, NpcData, ZoneFormations, Dialogues, rng, Maps, warmMechFloor);
- FightBahamut(flags, TalkRoutines, NpcData, ZoneFormations, Dialogues, Maps, EnemyScripts, rng);
- Astos(NpcData, Dialogues, TalkRoutines, EnemyScripts, flags, rng);
- EnableSwolePirates((bool)flags.SwolePirates);
- ExtAltFiends.ExtendedFiendsUpdate(NpcData, Dialogues, this, rng);
-
- FiendShuffle((bool)flags.FiendShuffle, rng);
- ScaleEnemyStats(rng, flags);
- ScaleBossStats(rng, flags);
-
- // Encounters
- ZoneFormations.ShuffleEnemyFormations(rng, flags.FormationShuffleMode, flags.EnemizerEnabled);
- ZoneFormations.UnleashWarMECH(flags.WarMECHMode == WarMECHMode.Unleashed || flags.WarMECHMode == WarMECHMode.All);
-
- await this.Progress();
-
- // Misc
- RngTables.Update(flags, rng);
- DisableMinimap(flags.DisableMinimap);
- ImproveTurnOrderRandomization(flags.ImproveTurnOrderRandomization, rng);
- SavingHacks(Overworld, flags);
- ImprovedClinic(flags.ImprovedClinic && !(bool)flags.RecruitmentMode);
- IncreaseDarkPenalty((bool)flags.IncreaseDarkPenalty);
- SetPoisonMode(flags.PoisonMode, flags.PoisonSetDamageValue);
- new QuickMiniMap(this, Overworld.DecompressedMap).EnableQuickMinimap(flags.SpeedHacks || Overworld.MapExchange != null, Music);
- EnableAirBoat(flags);
- OpenChestsInOrder(flags.OpenChestsInOrder && !flags.Archipelago);
- SetRNG(flags);
-
- new TreasureStacks(this, flags).SetTreasureStacks();
-
- await this.Progress();
-
- NPCHints(rng, NpcData, Maps, Dialogues, flags, PlacementContext, sanityChecker, itemPlacement, ShopData);
- SkyWarriorSpoilerBats(rng, flags, NpcData, Dialogues, EnemyScripts);
-
- MonsterInABox(itemPlacement, ZoneFormations, TileSetsData, NpcData, Dialogues, rng, flags);
-
- ExpGoldBoost(flags);
- ScalePrices(ShopData, flags, rng, ((bool)flags.ClampMinimumPriceScale), ShopData.ItemShopSlot, flags.ImprovedClinic);
- extConsumables.AddExtConsumables();
-
- await this.Progress();
-
- // Party
- PartyGeneration(rng, flags, preferences);
- PubReplaceClinic(rng, Maps.AttackedTown, flags);
-
- // Experience
- ScaleAllAltExp(flags);
- XpAdmissibility((bool)flags.NonesGainXP, flags.DeadsGainXP);
- SetProgressiveScaleMode(flags);
- var expChests = new ExpChests(itemPlacement.PlacedItems, this, flags, rng);
- expChests.BuildExpChests();
-
- // Classes Features
- ClassesBalances(flags, rng);
- ClassData.SetMPMax(flags);
- ClassData.SetMpGainOnMaxGain(flags, this);
- ClassData.RaiseThiefHitRate(flags);
- ClassData.BuffThiefAGI(flags);
- ClassData.EarlierHighTierMagicCharges(flags);
- ClassData.Randomize(flags, rng, oldItemNames, ItemsText, this);
- ClassData.ProcessStartWithRoutines(flags, weaponBlursesValues, this);
- ClassData.PinkMage(flags);
- ClassData.BlackKnight(flags);
- ClassData.WhiteNinja(flags);
- ClassData.Knightlvl4(flags, rng);
- EnableRandomPromotions(flags, rng);
-
- await this.Progress();
-
-
- RollCredits(rng);
-
-
- StatsTrackingHacks(flags, preferences);
- if ((bool)flags.IsShipFree || flags.Archipelago) Overworld.SetShipLocation(255);
- if (flags.TournamentSafe || preferences.CropScreen) ActivateCropScreen();
-
- // Quality of Life Stuff
- ShopUpgrade(flags, Dialogues, preferences);
- QualityOfLifeHacks(flags, preferences);
- UseVariablePaletteForCursorAndStone(preferences.ThirdBattlePalette || flags.ResourcePack != null);
- EnableModernBattlefield(preferences.ModernBattlefield);
- DynamicWindowColor(preferences.MenuColor);
-
- // Fun Stuff
- ChangeLute(preferences.ChangeLute, Dialogues, new MT19337(funRng.Next()));
- TitanSnack(preferences.TitanSnack, NpcData, Dialogues, new MT19337(funRng.Next()));
- HurrayDwarfFate(preferences.HurrayDwarfFate, NpcData, Dialogues, new MT19337(funRng.Next()));
- PaletteSwap(preferences.PaletteSwap && !flags.EnemizerEnabled, new MT19337(funRng.Next()));
- TeamSteak(preferences.TeamSteak && !(bool)flags.RandomizeEnemizer);
- FunEnemyNames(flags, preferences, new MT19337(funRng.Next()));
-
- await this.Progress();
-
- // Custom Sprites
- if (preferences.SpriteSheet != null)
- {
- using (var stream = new MemoryStream(Convert.FromBase64String(preferences.SpriteSheet)))
- {
- await SetCustomPlayerSprites(stream, preferences.ThirdBattlePalette, preferences.MapmanSlot);
- }
- }
-
- // Archipelago
- if (flags.Archipelago)
- {
- Archipelago exporter = new Archipelago(this, itemPlacement, sanityChecker, expChests, PlacementContext, Overworld.Locations, seed, flags, unmodifiedFlags, preferences);
- Utilities.ArchipelagoCache = exporter.Work();
- }
-
- // Spoilers
- if (flags.Spoilers && sanityChecker != null) new ExtSpoiler(this, sanityChecker, ShopData, ItemsText, itemPlacement.PlacedItems, Overworld, PlacementContext, WeaponPermissions, ArmorPermissions, flags).WriteSpoiler();
-
- // Write back everything
- ItemsText.Write(this, flags.GameMode == GameModes.DeepDungeon ? new List- () : ItemLists.UnusedGoldItems.ToList());
- TalkRoutines.Write(this);
- NpcData.Write(TalkRoutines.ScriptPointers);
- Dialogues.Write();
- ShopData.StoreData();
-
- EnemyScripts.Write(this);
- EncounterRates.Write();
- itemPlacement.Write();
-
- Maps.Write();
- TileSetsData.Write();
- ZoneFormations.Write(this);
- StartingItems.Write();
- RngTables.Write(this,flags);
- Teleporters.Write();
- Overworld.Write();
- ArmorPermissions.Write(this);
- WeaponPermissions.Write(this);
- SpellPermissions.Write(this);
- ClassData.Write(this);
- MenuText.Write(this);
- Music.Write(this, flags, preferences);
- NewMusic.Write(this, preferences, flags, new MT19337(funRng.Next()));
-
- await this.Progress();
-
- uint last_rng_value = rng.Next();
-
- // Final ROM writes
- WriteSeedAndFlags(seed.ToHex(), flags, flagsForRng, unmodifiedFlags, resourcesPackHash.ToHex(), last_rng_value);
- if (flags.TournamentSafe) Put(0x3FFE3, Blob.FromHex("66696E616C2066616E74617379"));
-
- await this.Progress("Randomization Completed");
- }
-}
+using FF1Lib.Music;
+using FF1Lib.Procgen;
+using RomUtilities;
+namespace FF1Lib;
+
+// ReSharper disable once InconsistentNaming
+public partial class FF1Rom : NesRom
+{
+ public const int LevelRequirementsOffset = 0x6CC81;
+ public const int LevelRequirementsSize = 3;
+ public const int LevelRequirementsCount = 49;
+
+ public const int GoldItemOffset = 108; // 108 items before gold chests
+ public const int GoldItemCount = 68;
+ //public List UnusedGoldItems = new List { 110, 111, 112, 113, 114, 116, 120, 121, 122, 124, 125, 127, 132, 158, 165, 166, 167, 168, 170, 171, 172 };
+
+ public ItemNames ItemsText;
+ public GearPermissions ArmorPermissions;
+ public GearPermissions WeaponPermissions;
+ public SpellPermissions SpellPermissions;
+ public GameClasses ClassData;
+ public RngTables RngTables;
+ public TileSetsData TileSetsData;
+ public ZoneFormations ZoneFormations;
+ public StandardMaps Maps;
+ public NpcObjectData NpcData;
+ public DialogueData Dialogues;
+ public MenuText MenuText;
+ public TalkRoutines TalkRoutines;
+ public StartingItems StartingItems;
+ public EncounterRate EncounterRates;
+ public EnemyScripts EnemyScripts;
+ public ShopData ShopData;
+ public MusicTracks Music;
+ public NewMusic NewMusic;
+ public ExtAltFiends ExtAltFiends;
+
+ public DeepDungeon DeepDungeon;
+
+ public OwMapExchange OverworldMapData;
+ public Teleporters Teleporters;
+ public Overworld Overworld;
+
+ private SanityCheckerV2 sanityChecker = null;
+ private PlacementContext PlacementContext = null;
+
+ private Blob SavedHash;
+
+ public void LoadSharedDataTables()
+ {
+ ItemsText = new ItemNames(this);
+ ArmorPermissions = new GearPermissions(0x3BFA0, (int)Item.Cloth, this);
+ WeaponPermissions = new GearPermissions(0x3BF50, (int)Item.WoodenNunchucks, this);
+ SpellPermissions = new SpellPermissions(this);
+ ClassData = new GameClasses(WeaponPermissions, ArmorPermissions, SpellPermissions, this);
+ }
+
+ public delegate Task ProgressMessage(int step, int max, string message);
+
+ public delegate Task ReportProgress(string message="", int addMax=0);
+
+ int currentStep = 0;
+ int maxSteps = 0;
+ public ProgressMessage ProgressCallback;
+
+ public async Task Progress(string message="", int addMax=0)
+ {
+ maxSteps += addMax;
+ currentStep += 1;
+ if (ProgressCallback != null) {
+ await ProgressCallback(currentStep, maxSteps, message);
+ }
+ }
+ public async Task Randomize(Blob seed, Flags flags, Preferences preferences)
+ {
+ // Confirm ROM integrity
+ if (flags.TournamentSafe) AssureSafe();
+
+ // Copy flags for various use
+ Flags flagsForRng = flags.ShallowCopy();
+ Flags unmodifiedFlags = flags.ShallowCopy();
+
+ // Setup Rng
+ Blob resourcesPackHash = GenerateRng(flagsForRng, seed);
+
+ // Collapse tristate flags
+ flags = Flags.ConvertAllTriState(flags, rng);
+
+ await this.Progress("Beginning Randomization", 15);
+
+ // load resource pack data that needs to go into initial ROM before
+ // data is read
+ await this.LoadResourcePackPreROM(flags.ResourcePack, preferences);
+ await this.LoadFunTiles(preferences);
+
+ // Load Initial Data
+ RngTables = new(this);
+ TileSetsData = new(this);
+ ZoneFormations = new(this);
+ Overworld = new(this, flags, ZoneFormations, rng);
+ await Overworld.LoadMapExchange();
+ ItemsText = new ItemNames(this);
+ ArmorPermissions = new GearPermissions(0x3BFA0, (int)Item.Cloth, this);
+ WeaponPermissions = new GearPermissions(0x3BF50, (int)Item.WoodenNunchucks, this);
+ SpellPermissions = new SpellPermissions(this);
+ ClassData = new GameClasses(WeaponPermissions, ArmorPermissions, SpellPermissions, this);
+ Teleporters = new Teleporters(this, Overworld.MapExchangeData);
+ Maps = new StandardMaps(this, Teleporters, flags);
+ NpcData = new NpcObjectData(Maps, flags, rng, this);
+ TalkRoutines = new TalkRoutines();
+ Dialogues = new DialogueData(this);
+ MenuText = new MenuText(this);
+ ShopData = new ShopData(flags, this);
+ EncounterRates = new EncounterRate(this);
+ EnemyScripts = new EnemyScripts(this);
+ Music = new MusicTracks();
+ ExtAltFiends = new ExtAltFiends(flags);
+
+
+ await this.Progress();
+
+ // Expand ROM, move data around
+ GlobalHacks();
+
+ // load resource pack data that requires the ROM expansion that just took place
+ await this.LoadResourcePackPostROM(flags.ResourcePack, Dialogues, EnemyScripts, preferences);
+
+
+ TalkRoutines.TransferTalkRoutines(this, flags);
+ Dialogues.TransferDialogues();
+
+ // Apply general fixes and hacks
+ FF1Text.AddNewIcons(this, flags);
+ Music.ShuffleMusic(this, preferences, new MT19337(funRng.Next()));
+ NewMusic = new NewMusic(this);
+ Bugfixes(flags);
+ GlobalImprovements(flags, Maps, preferences);
+ MiscHacks(flags, rng);
+ var oldItemNames = ItemsText.ToList();
+ MapIndex warmMechFloor = MapIndex.SkyPalace4F;
+
+ // Load Ressources Packs Maps
+ LoadResourcePackMaps(flags.ResourcePack, Maps, Teleporters);
+
+ await this.Progress();
+
+ // Game Modes
+ DeepDungeon = new DeepDungeon(Maps, Teleporters, NpcData, TileSetsData, flags, this);
+ if (flags.GameMode == GameModes.DeepDungeon)
+ {
+ await this.Progress("Generating Deep Dungeon's Floors...", 2);
+
+ DeepDungeon.Generate(rng, Overworld, EncounterRates, ZoneFormations, Dialogues);
+ DeepDungeonFloorIndicator();
+ warmMechFloor = (MapIndex)DeepDungeon.WarMechFloor;
+
+ await this.Progress("Generating Deep Dungeon's Floors... Done!");
+ }
+ DesertOfDeath.ApplyDesertModifications((bool)flags.DesertOfDeath, this, ZoneFormations, Overworld, NpcData, Dialogues, Music);
+ Spooky(TalkRoutines, NpcData, Dialogues, ZoneFormations, Maps, rng, flags);
+ BlackOrbMode(TalkRoutines, Dialogues, flags, preferences, rng, new MT19337(funRng.Next()));
+ Maps.ProcgenDungeons(rng);
+ DraculasCurse(Overworld, Teleporters, rng, flags);
+
+ await this.Progress();
+
+ // Maps
+ GeneralMapHacks(flags, Overworld, Maps, ZoneFormations, TileSetsData, rng);
+ Maps.Update(ZoneFormations, rng);
+ if (flags.NoOverworld) await this.Progress("Linking NoOverworld's Map", 1);
+ NoOverworld(Overworld.DecompressedMap, Maps, Teleporters, TileSetsData, TalkRoutines, Dialogues, NpcData, flags, rng);
+ UpdateToFR(Maps, Teleporters, TileSetsData, flags, rng);
+ Teleporters.ShuffleEntrancesAndFloors(Overworld.OverworldMap, rng, flags);
+ Overworld.Update(Teleporters);
+ EncounterRates.ScaleEncounterRate(flags);
+
+ // Tile Sets
+ TileSetsData.Update(flags, rng);
+ TileSetsData.UpdateTrapTiles(this, ZoneFormations, flags, rng);
+ await DamageTilesHack(flags, Overworld);
+
+ await this.Progress();
+
+ // NPCs
+ Dialogues.UpdateNPCDialogues(flags);
+ PacifistBat(Maps, TalkRoutines, NpcData);
+ TalkRoutines.Update(flags);
+ ClassAsNPC(flags, TalkRoutines, NpcData, Dialogues, Maps, rng);
+
+ // Relocate chests need to happen after NPCs, before logic
+ await new RelocateChests(this).RandomlyRelocateChests(rng, Maps, TileSetsData, Teleporters, NpcData, flags);
+
+ // Spells
+ CraftNewSpellbook(EnemyScripts, flags, rng);
+ SpellBalanceHacks(flags, rng);
+ TranceHasStatusElement(flags.TranceHasStatusElement);
+ ShuffleMagicLevels(EnemyScripts, rng, (bool)flags.MagicLevels, (bool)flags.MagicPermissions, (bool)flags.MagicLevelsTiered, (bool)flags.MagicLevelsMixed);
+ SpellNames(flags, preferences, rng);
+ var extConsumables = new ExtConsumables(ShopData, this, flags, rng);
+ extConsumables.LoadSpells();
+
+ // Create items
+ Etherizer(flags.Etherizer, ItemsText);
+
+ Weaponizer(flags, rng);
+ ArmorCrafter(flags, rng);
+ new RibbonShuffle(this, rng, flags, ItemsText, ArmorPermissions).Work();
+
+ ItemMagic(flags, rng);
+
+ DoubleWeaponCritRates(flags.WeaponCritRate);
+ List weaponBlursesValues = Enumerable.Repeat(0, 40).ToList();
+ RandomWeaponBonus(flags, preferences.CleanBlursedEquipmentNames, weaponBlursesValues, rng);
+ RandomArmorBonus(flags, preferences.CleanBlursedEquipmentNames, rng);
+ IncreaseWeaponBonus(flags.WeaponBonuses, flags.WeaponTypeBonusValue);
+
+ // Starting Inventory
+ StartingItems = new StartingItems(new() { }, rng, flags, this);
+
+ // Placement Context
+ var priceList = Get(0x37C00, 0x200).ToUShorts().Select(x => (int)x).ToList(); // Temporary until we extract price
+ PlacementContext = (flags.GameMode != GameModes.DeepDungeon) ?
+ new PlacementContext(StartingItems, new() { }, priceList, rng, flags) :
+ new PlacementContext(StartingItems, new() { }, DeepDungeon.PlacedItems, DeepDungeon.ChestLocations, priceList, rng, flags);
+
+ // Shops
+ ShopData.ShuffleShops(rng, PlacementContext.ExcludedItemsFromShops, Teleporters.ConeriaTownEntranceItemShopIndex);
+ ShopData.ShuffleMagicLocations((bool)flags.MagicShopLocs, (bool)flags.MagicShopLocationPairs, rng);
+ ShopData.ShuffleMagicShops((bool)flags.MagicShops, rng);
+ extConsumables.AddNormalShopEntries();
+ new ShopKiller(Maps, ShopData, rng, flags, this).KillShops();
+ new LegendaryShops(rng, flags, Maps, ShopData, TileSetsData, this).PlaceShops();
+
+ await this.Progress("Building Placement Logic");
+
+ // Create Logic Checker
+ sanityChecker = new SanityCheckerV2(Maps, Overworld, NpcData, Teleporters, TileSetsData, this, ShopData.ItemShopSlot);
+ if (!sanityChecker.CheckSanity(ItemLocations.AllQuestItemLocations.ToList(), null, flags, true).Complete) throw new InsaneException("Not Completable");
+
+ await this.Progress(flags.VanillaPlacement ? "Placing Treasures" : "Shuffling Treasures");
+
+ // Item Placement
+ ItemPlacement itemPlacement = ItemPlacement.Create(this, flags, PlacementContext, ShopData.ItemShopSlot, Overworld, sanityChecker);
+ itemPlacement.PlaceItems(rng);
+
+ NpcData.UpdateItemPlacement(itemPlacement.PlacedItems);
+ ShopData.UpdateShopSlotPlacement(itemPlacement.PlacedItems);
+
+ List funMessages = new()
+ {
+ "Placing Out of Bound Bat",
+ "Cleaning up Lich's closet",
+ "Labelling pots in Sarda's Cave",
+ "Partying in the Bat Party Room",
+ "Buffing up NPC's path-blocking AI",
+ "Debugging WarMech's software",
+ "Knocking down some impertinent fools",
+ "Sending Garland 2,000 years in the past",
+ "Giving a snack to Titan while waiting for the main course",
+ "Disguising Astos",
+ "Cursing the Elf Prince",
+ "Stealing Matoya's Crystal",
+ "Abducting Princess Sara",
+ "Placing the worst skills in Medusa's script",
+ "Applying for a Bridge building permit",
+ "Reticulating Splines",
+ "Digging Cave Holes",
+ "Bottling the Fairy",
+ "Floating the Sky Castle",
+ "Locking the door in Temple of Fiends",
+ "Teaching Kraken Kung Fu",
+ "Raising the Lich",
+ };
+
+ funMessages.AddRange(Enumerable.Repeat("Finalizing", funMessages.Count * 4).ToList());
+
+ await this.Progress(funMessages.PickRandom(rng));
+
+ // Enemies
+ if ((bool)flags.AlternateFiends && !flags.SpookyFlag) await this.Progress("Creating new Fiends", 1);
+ AlternativeFiends(ExtAltFiends, EnemyScripts, rng, flags);
+ TransformFinalFormation(flags, rng);
+ DoEnemizer(EnemyScripts, ZoneFormations, flags, rng);
+
+ ShuffleEnemyScripts(rng, flags);
+ EnemyScripts.ShuffleEnemySkillsSpells(this, rng, flags);
+ StatusAttacks(flags, rng);
+ ShuffleUnrunnable(rng, flags);
+ AllowStrikeFirstAndSurprise(flags.WaitWhenUnrunnable, (bool)flags.UnrunnablesStrikeFirstAndSurprise);
+ ShuffleSurpriseBonus((bool)flags.EnemyFormationsSurprise, rng);
+
+ // After unrunnable shuffle and before formation shuffle
+ WarMechMode.Process(this, flags, NpcData, ZoneFormations, Dialogues, rng, Maps, warmMechFloor);
+ FightBahamut(flags, TalkRoutines, NpcData, ZoneFormations, Dialogues, Maps, EnemyScripts, rng);
+ Astos(NpcData, Dialogues, TalkRoutines, EnemyScripts, flags, rng);
+ EnableSwolePirates((bool)flags.SwolePirates);
+ ExtAltFiends.ExtendedFiendsUpdate(NpcData, Dialogues, this, rng);
+
+ FiendShuffle((bool)flags.FiendShuffle, rng);
+ ScaleEnemyStats(rng, flags);
+ ScaleBossStats(rng, flags);
+
+ // Encounters
+ ZoneFormations.ShuffleEnemyFormations(rng, flags.FormationShuffleMode, flags.EnemizerEnabled);
+ ZoneFormations.UnleashWarMECH(flags.WarMECHMode == WarMECHMode.Unleashed || flags.WarMECHMode == WarMECHMode.All);
+
+ await this.Progress();
+
+ // Misc
+ RngTables.Update(flags, rng);
+ DisableMinimap(flags.DisableMinimap);
+ ImproveTurnOrderRandomization(flags.ImproveTurnOrderRandomization, rng);
+ SavingHacks(Overworld, flags);
+ ImprovedClinic(flags.ImprovedClinic && !(bool)flags.RecruitmentMode);
+ IncreaseDarkPenalty((bool)flags.IncreaseDarkPenalty);
+ IncreaseRegeneration((bool)flags.IncreaseRegeneration);
+ SetPoisonMode(flags.PoisonMode, flags.PoisonSetDamageValue);
+ new QuickMiniMap(this, Overworld.DecompressedMap).EnableQuickMinimap(flags.SpeedHacks || Overworld.MapExchange != null, Music);
+ EnableAirBoat(flags);
+ OpenChestsInOrder(flags.OpenChestsInOrder && !flags.Archipelago);
+ SetRNG(flags);
+
+ new TreasureStacks(this, flags).SetTreasureStacks();
+
+ await this.Progress();
+
+ NPCHints(rng, NpcData, Maps, Dialogues, flags, PlacementContext, sanityChecker, itemPlacement, ShopData);
+ SkyWarriorSpoilerBats(rng, flags, NpcData, Dialogues, EnemyScripts);
+
+ MonsterInABox(itemPlacement, ZoneFormations, TileSetsData, NpcData, Dialogues, rng, flags);
+
+ ExpGoldBoost(flags);
+ ScalePrices(ShopData, flags, rng, ((bool)flags.ClampMinimumPriceScale), ShopData.ItemShopSlot, flags.ImprovedClinic);
+ extConsumables.AddExtConsumables();
+
+ await this.Progress();
+
+ // Party
+ PartyGeneration(rng, flags, preferences);
+ PubReplaceClinic(rng, Maps.AttackedTown, flags);
+
+ // Experience
+ ScaleAllAltExp(flags);
+ XpAdmissibility((bool)flags.NonesGainXP, flags.DeadsGainXP);
+ SetProgressiveScaleMode(flags);
+ var expChests = new ExpChests(itemPlacement.PlacedItems, this, flags, rng);
+ expChests.BuildExpChests();
+
+ // Classes Features
+ ClassesBalances(flags, rng);
+ ClassData.SetMPMax(flags);
+ ClassData.SetMpGainOnMaxGain(flags, this);
+ ClassData.RaiseThiefHitRate(flags);
+ ClassData.BuffThiefAGI(flags);
+ ClassData.EarlierHighTierMagicCharges(flags);
+ ClassData.Randomize(flags, rng, oldItemNames, ItemsText, this);
+ ClassData.ProcessStartWithRoutines(flags, weaponBlursesValues, this);
+ ClassData.PinkMage(flags);
+ ClassData.BlackKnight(flags);
+ ClassData.WhiteNinja(flags);
+ ClassData.Knightlvl4(flags, rng);
+ EnableRandomPromotions(flags, rng);
+
+ await this.Progress();
+
+
+ RollCredits(rng);
+
+
+ StatsTrackingHacks(flags, preferences);
+ if ((bool)flags.IsShipFree || flags.Archipelago) Overworld.SetShipLocation(255);
+ if (flags.TournamentSafe || preferences.CropScreen) ActivateCropScreen();
+
+ // Quality of Life Stuff
+ ShopUpgrade(flags, Dialogues, preferences);
+ QualityOfLifeHacks(flags, preferences);
+ UseVariablePaletteForCursorAndStone(preferences.ThirdBattlePalette || flags.ResourcePack != null);
+ EnableModernBattlefield(preferences.ModernBattlefield);
+ DynamicWindowColor(preferences.MenuColor);
+
+ // Fun Stuff
+ ChangeLute(preferences.ChangeLute, Dialogues, new MT19337(funRng.Next()));
+ TitanSnack(preferences.TitanSnack, NpcData, Dialogues, new MT19337(funRng.Next()));
+ HurrayDwarfFate(preferences.HurrayDwarfFate, NpcData, Dialogues, new MT19337(funRng.Next()));
+ PaletteSwap(preferences.PaletteSwap && !flags.EnemizerEnabled, new MT19337(funRng.Next()));
+ TeamSteak(preferences.TeamSteak && !(bool)flags.RandomizeEnemizer);
+ FunEnemyNames(flags, preferences, new MT19337(funRng.Next()));
+
+ await this.Progress();
+
+ // Custom Sprites
+ if (preferences.SpriteSheet != null)
+ {
+ using (var stream = new MemoryStream(Convert.FromBase64String(preferences.SpriteSheet)))
+ {
+ await SetCustomPlayerSprites(stream, preferences.ThirdBattlePalette, preferences.MapmanSlot);
+ }
+ }
+
+ // Archipelago
+ if (flags.Archipelago)
+ {
+ Archipelago exporter = new Archipelago(this, itemPlacement, sanityChecker, expChests, PlacementContext, Overworld.Locations, seed, flags, unmodifiedFlags, preferences);
+ Utilities.ArchipelagoCache = exporter.Work();
+ }
+
+ // Spoilers
+ if (flags.Spoilers && sanityChecker != null) new ExtSpoiler(this, sanityChecker, ShopData, ItemsText, itemPlacement.PlacedItems, Overworld, PlacementContext, WeaponPermissions, ArmorPermissions, flags).WriteSpoiler();
+
+ // Write back everything
+ ItemsText.Write(this, flags.GameMode == GameModes.DeepDungeon ? new List
- () : ItemLists.UnusedGoldItems.ToList());
+ TalkRoutines.Write(this);
+ NpcData.Write(TalkRoutines.ScriptPointers);
+ Dialogues.Write();
+ ShopData.StoreData();
+
+ EnemyScripts.Write(this);
+ EncounterRates.Write();
+ itemPlacement.Write();
+
+ Maps.Write();
+ TileSetsData.Write();
+ ZoneFormations.Write(this);
+ StartingItems.Write();
+ RngTables.Write(this,flags);
+ Teleporters.Write();
+ Overworld.Write();
+ ArmorPermissions.Write(this);
+ WeaponPermissions.Write(this);
+ SpellPermissions.Write(this);
+ ClassData.Write(this);
+ MenuText.Write(this);
+ Music.Write(this, flags, preferences);
+ NewMusic.Write(this, preferences, flags, new MT19337(funRng.Next()));
+
+ await this.Progress();
+
+ uint last_rng_value = rng.Next();
+
+ // Final ROM writes
+ WriteSeedAndFlags(seed.ToHex(), flags, flagsForRng, unmodifiedFlags, resourcesPackHash.ToHex(), last_rng_value);
+ if (flags.TournamentSafe) Put(0x3FFE3, Blob.FromHex("66696E616C2066616E74617379"));
+
+ await this.Progress("Randomization Completed");
+ }
+}