Skip to content

Commit 5f1b9c3

Browse files
committed
Functions for magic cost-dependent logic for spells
This still needs to be routed in. Currently these functions aren't used anywhere. One suggestion is rolling StatRandomizer early and then adding it to RandomizerProperties, but I'm not sure.
1 parent 8912595 commit 5f1b9c3

3 files changed

Lines changed: 157 additions & 1 deletion

File tree

RandomizerCore/RequirementType.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,33 @@ public enum RequirementType
3535

3636
public static class RequirementTypeExtensions
3737
{
38+
/// Mirror of Collectable.AsRequirement()
39+
public static Collectable? AsCollectable(this RequirementType requirementType)
40+
{
41+
return requirementType switch
42+
{
43+
RequirementType.JUMP => Collectable.JUMP_SPELL,
44+
RequirementType.FAIRY => Collectable.FAIRY_SPELL,
45+
RequirementType.UPSTAB => Collectable.UPSTAB,
46+
RequirementType.DOWNSTAB => Collectable.DOWNSTAB,
47+
RequirementType.KEY => Collectable.MAGIC_KEY,
48+
RequirementType.DASH => Collectable.DASH_SPELL,
49+
RequirementType.GLOVE => Collectable.GLOVE,
50+
RequirementType.REFLECT => Collectable.REFLECT_SPELL,
51+
RequirementType.SPELL => Collectable.SPELL_SPELL,
52+
RequirementType.TROPHY => Collectable.TROPHY,
53+
RequirementType.MEDICINE => Collectable.MEDICINE,
54+
RequirementType.CHILD => Collectable.CHILD,
55+
RequirementType.MIRROR => Collectable.MIRROR,
56+
RequirementType.WATER => Collectable.WATER,
57+
RequirementType.FLUTE => Collectable.FLUTE,
58+
RequirementType.HAMMER => Collectable.HAMMER,
59+
RequirementType.BOOTS => Collectable.BOOTS,
60+
RequirementType.BAGU_LETTER => Collectable.BAGUS_NOTE,
61+
_ => null
62+
};
63+
}
64+
3865
public static RequirementType[] UpToXContainers(int x)
3966
{
4067
List<RequirementType> requirements = [];
@@ -72,4 +99,27 @@ public static RequirementType[] UpToXContainers(int x)
7299
}
73100
return requirements.ToArray();
74101
}
102+
103+
public static RequirementType MagicContainerRequirementFromCost(int magicCost)
104+
{
105+
switch (magicCost)
106+
{
107+
case <= 16:
108+
return RequirementType.ONE_CONTAINER;
109+
case <= 32:
110+
return RequirementType.TWO_CONTAINERS;
111+
case <= 48:
112+
return RequirementType.THREE_CONTAINERS;
113+
case <= 64:
114+
return RequirementType.FOUR_CONTAINERS;
115+
case <= 80:
116+
return RequirementType.FIVE_CONTAINERS;
117+
case <= 96:
118+
return RequirementType.SIX_CONTAINERS;
119+
case <= 112:
120+
return RequirementType.SEVEN_CONTAINERS;
121+
default:
122+
return RequirementType.EIGHT_CONTAINERS;
123+
}
124+
}
75125
}

RandomizerCore/Requirements.cs

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,16 @@ public class Requirements
1919
{RequirementType.FAIRY, [RequirementType.FOUR_CONTAINERS] },
2020
{RequirementType.REFLECT, [RequirementType.FOUR_CONTAINERS] },
2121
{RequirementType.SPELL, [RequirementType.FOUR_CONTAINERS] },
22-
};
22+
};
23+
24+
// the magic level you have to each for each spell to be considered in-logic
25+
private static readonly Dictionary<RequirementType, int> ImplicitMagicLevelRequirements = new()
26+
{
27+
{ RequirementType.JUMP, 3 },
28+
{ RequirementType.FAIRY, 3 },
29+
{ RequirementType.REFLECT, 4 },
30+
{ RequirementType.SPELL, 4 },
31+
};
2332

2433
public RequirementType[] IndividualRequirements { get; private set; }
2534
public RequirementType[][] CompositeRequirements { get; private set; }
@@ -147,6 +156,73 @@ public bool AreSatisfiedBy(IEnumerable<RequirementType> requireables, bool enfor
147156
}
148157
}
149158
return individualRequirementsSatisfied || compositeRequirementSatisfied;
159+
}
160+
161+
public bool AreSatisfiedBy(IEnumerable<RequirementType> requireables, StatRandomizer statRoll)
162+
{
163+
if (IndividualRequirements.Length + CompositeRequirements.Length == 0)
164+
{
165+
return true;
166+
}
167+
var individualRequirementsSatisfied = false;
168+
var requirementTypes = requireables as RequirementType[] ?? requireables.ToArray();
169+
170+
statRoll.AssertHasRandomized();
171+
172+
bool StatAdjustedContainerRequirementSatisfied(RequirementType requirement)
173+
{
174+
if (ImplicitMagicLevelRequirements.ContainsKey(requirement))
175+
{
176+
Collectable collectable = requirement.AsCollectable()!.Value;
177+
var requiredLevel = ImplicitMagicLevelRequirements[requirement];
178+
var magicCost = statRoll.GetSpellCost(collectable, requiredLevel);
179+
var containerRequirement = MagicContainerRequirementFromCost(magicCost);
180+
return requirementTypes.Contains(containerRequirement);
181+
}
182+
else
183+
{
184+
return true;
185+
}
186+
}
187+
188+
foreach (var requirement in IndividualRequirements)
189+
{
190+
if (requirementTypes.Contains(requirement))
191+
{
192+
individualRequirementsSatisfied = true;
193+
if (!StatAdjustedContainerRequirementSatisfied(requirement))
194+
{
195+
individualRequirementsSatisfied = false;
196+
}
197+
198+
if (individualRequirementsSatisfied)
199+
{
200+
break;
201+
}
202+
}
203+
}
204+
205+
bool compositeRequirementSatisfied = false;
206+
foreach (RequirementType[] compositeRequirement in CompositeRequirements)
207+
{
208+
if (compositeRequirement.All(i => requireables.Contains(i)))
209+
{
210+
compositeRequirementSatisfied = true;
211+
}
212+
foreach (RequirementType component in compositeRequirement)
213+
{
214+
if (!StatAdjustedContainerRequirementSatisfied(component))
215+
{
216+
compositeRequirementSatisfied = false;
217+
break;
218+
}
219+
}
220+
if (compositeRequirementSatisfied == true)
221+
{
222+
break;
223+
}
224+
}
225+
return individualRequirementsSatisfied || compositeRequirementSatisfied;
150226
}
151227

152228
public Requirements WithHardRequirement(RequirementType requirement)
@@ -240,6 +316,29 @@ public bool HasHardRequirement(RequirementType requireable)
240316
}
241317
return true;
242318
}
319+
320+
public static RequirementType MagicContainerRequirementFromCost(int magicCost)
321+
{
322+
switch (magicCost)
323+
{
324+
case <= 16:
325+
return RequirementType.ONE_CONTAINER;
326+
case <= 32:
327+
return RequirementType.TWO_CONTAINERS;
328+
case <= 48:
329+
return RequirementType.THREE_CONTAINERS;
330+
case <= 64:
331+
return RequirementType.FOUR_CONTAINERS;
332+
case <= 80:
333+
return RequirementType.FIVE_CONTAINERS;
334+
case <= 96:
335+
return RequirementType.SIX_CONTAINERS;
336+
case <= 112:
337+
return RequirementType.SEVEN_CONTAINERS;
338+
default:
339+
return RequirementType.EIGHT_CONTAINERS;
340+
}
341+
}
243342
}
244343

245344
public class RequirementsJsonConverter : JsonConverter<Requirements>

RandomizerCore/StatRandomizer.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,4 +712,11 @@ public void FixRebonackHorseKillBug()
712712
BossHpTable[2] = reboHp;
713713
}
714714
}
715+
716+
public int GetSpellCost(Collectable spell, int level)
717+
{
718+
var spellIndex = spell.VanillaSpellOrder();
719+
int index = spellIndex * 8 + level - 1;
720+
return MagicEffectivenessTable[index];
721+
}
715722
}

0 commit comments

Comments
 (0)