Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,10 @@ public interface ITrackerGameStateService
public void UpdateLastMarkedLocations(List<Location> locations);

public void ClearLastViewedObject(float confidence);

public void UpdateGanonsTowerRequirement(int crystalAmount, bool autoTracked);

public void UpdateGanonRequirement(int crystalAmount, bool autoTracked);

public void UpdateTourianRequirement(int bossAmount, bool autoTracked);
}
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,27 @@ public class ResponseConfig : IMergeable<ResponseConfig>, IConfigFile<ResponseCo
/// </summary>
public SchrodingersString? LongSpeechResponse { get; init; }

/// <summary>
/// Gets the phrases for when the player has updated the number of crystals required
/// to get into GT
/// <c>{0}</c> is a placeholder for the number of crystals required
/// </summary>
public SchrodingersString? UpdatedGanonsTowerCrystalRequirement { get; init; }

/// <summary>
/// Gets the phrases for when the player has updated the number of crystals required
/// to defeat Ganon
/// <c>{0}</c> is a placeholder for the number of crystals required
/// </summary>
public SchrodingersString? UpdatedGanonCrystalRequirement { get; init; }

/// <summary>
/// Gets the phrases for when the player has updated the number of bosses required
/// to enter Tourian
/// <c>{0}</c> is a placeholder for the number of bosses required
/// </summary>
public SchrodingersString? UpdatedTourianBossRequirement { get; init; }

/// <summary>
/// Gets a dictionary that contains the phrases to respond with when no
/// voice commands have been issued after a certain period of time, as
Expand Down
10 changes: 9 additions & 1 deletion src/TrackerCouncil.Smz3.Data/Services/TrackerStateService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ public TrackerState CreateTrackerState(List<World> worlds)
hintStates.Add(hintState);
}

var localWorld = worlds.First(x => x.IsLocalWorld);

return new TrackerState()
{
LocationStates = locationStates,
Expand All @@ -169,10 +171,16 @@ public TrackerState CreateTrackerState(List<World> worlds)
BossStates = bossStates,
RewardStates = rewardStates,
PrerequisiteStates = prereqStates,
LocalWorldId = worlds.First(x => x.IsLocalWorld).Id,
LocalWorldId = localWorld.Id,
Hints = hintStates,
StartDateTime = DateTimeOffset.Now,
UpdatedDateTime = DateTimeOffset.Now,
GanonsTowerCrystalCount = localWorld.Config.GanonsTowerCrystalCount,
MarkedGanonsTowerCrystalCount = localWorld.LegacyWorld == null ? localWorld.Config.GanonsTowerCrystalCount : null,
GanonCrystalCount = localWorld.Config.GanonCrystalCount,
MarkedGanonCrystalCount = localWorld.LegacyWorld == null ? localWorld.Config.GanonCrystalCount : null,
TourianBossCount = localWorld.Config.TourianBossCount,
MarkedTourianBossCount = localWorld.LegacyWorld == null ? localWorld.Config.TourianBossCount : null,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

<ItemGroup>
<PackageReference Include="Avalonia" Version="11.0.11" />
<PackageReference Include="MattEqualsCoder.DynamicForms.Core" Version="1.0.2" />
<PackageReference Include="MattEqualsCoder.DynamicForms.Core" Version="1.2.0" />
<PackageReference Include="MattEqualsCoder.GitHubReleaseChecker" Version="1.1.2" />
<PackageReference Include="MattEqualsCoder.MSURandomizer.Library" Version="3.0.1" />
<PackageReference Include="NAudio.Wasapi" Version="2.2.1" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using TrackerCouncil.Smz3.Shared;
using TrackerCouncil.Smz3.Data.Configuration.ConfigTypes;
using TrackerCouncil.Smz3.Data.Options;
Expand Down Expand Up @@ -30,6 +32,10 @@ public WestCrateria(World world, Config config, IMetadataService? metadata, Trac

public TerminatorRoom Terminator { get; }

public Accessibility MotherBrainAccessibility { get; private set; }

public event EventHandler? UpdatedMotherBrainAccessibility;

public override bool CanEnter(Progression items, bool requireRewards)
{
return Logic.CanDestroyBombWalls(items) || Logic.CanParlorSpeedBoost(items);
Expand Down Expand Up @@ -107,4 +113,48 @@ public TerminatorRoom(WestCrateria region, IMetadataService? metadata, TrackerSt
};
}
}

public void UpdateMotherBrainAccessibility(Progression progression)
{
Accessibility NewAccessibility;

var tourianBossRequirement = World.State?.TourianBossCount == null
? Config.TourianBossCount
: World.State?.MarkedTourianBossCount ?? 4;

if (World.Bosses.First(x => x.Type == BossType.MotherBrain).Defeated)
{
NewAccessibility = Accessibility.Cleared;
}
else if (World.LegacyWorld == null)
{
var canAccessStatueRoom = Terminator.Locations.First().IsAvailable(progression) &&
(!World.Config.MetroidKeysanity || World.Config.SkipTourianBossDoor ||
progression.CardCrateriaBoss);

var canEnterTourian = World.GoldenBosses.Count(x => x.Defeated) >= tourianBossRequirement;

NewAccessibility = canAccessStatueRoom && canEnterTourian
? Accessibility.Available
: Accessibility.OutOfLogic;
}
else
{
var canAccessStatueRoom = World.LegacyWorld.IsLocationAccessible((int)LocationId.CrateriaTerminator, progression.LegacyProgression) &&
(!World.Config.MetroidKeysanity || World.Config.SkipTourianBossDoor ||
progression.CardCrateriaBoss);

var canEnterTourian = World.GoldenBosses.Count(x => x.Defeated) >= tourianBossRequirement;

NewAccessibility = canAccessStatueRoom && canEnterTourian
? Accessibility.Available
: Accessibility.OutOfLogic;
}

if (NewAccessibility != MotherBrainAccessibility)
{
MotherBrainAccessibility = NewAccessibility;
UpdatedMotherBrainAccessibility?.Invoke(this, EventArgs.Empty);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using TrackerCouncil.Smz3.Shared;
using TrackerCouncil.Smz3.Data.Configuration.ConfigTypes;
using TrackerCouncil.Smz3.Data.Options;
Expand Down Expand Up @@ -49,6 +51,10 @@ public DarkWorldNorthEast(World world, Config config, IMetadataService? metadata

public PyramidFairyChamber PyramidFairy { get; }

public Accessibility GanonAccessibility { get; private set; }

public event EventHandler? UpdatedGanonAccessibility;

public override bool CanEnter(Progression items, bool requireRewards)
{
return Logic.CheckAgahnim(items, World, requireRewards) ||
Expand All @@ -60,6 +66,62 @@ public override bool CanEnter(Progression items, bool requireRewards)
);
}

public void UpdateGanonAccessibility(Progression progression, Progression assumedKeyProgression)
{
Accessibility NewAccessibility;

var ganonCrystalRequirement = World.State?.GanonCrystalCount == null
? Config.GanonCrystalCount
: World.State?.MarkedGanonCrystalCount ?? 7;

if (World.Bosses.First(x => x.Type == BossType.Ganon).Defeated)
{
NewAccessibility = Accessibility.Cleared;
}
else if (World.LegacyWorld == null)
{
var canAccessPyramid = Pyramid.IsAvailable(progression);

var canClimbGt = World.GanonsTower.CanBeatBoss(progression, true) ||
(!World.Config.ZeldaKeysanity &&
World.GanonsTower.Locations.All(x => x.IsAvailable(assumedKeyProgression)) &&
World.GanonsTower.CanBeatBoss(assumedKeyProgression, true));

var isPyramidOpen = World.Config.OpenPyramid || canClimbGt;
var canHurtGanon = progression.CrystalCount >= ganonCrystalRequirement && progression.MasterSword &&
(progression.Lamp || progression.FireRod);

NewAccessibility = canAccessPyramid && isPyramidOpen && canHurtGanon
? Accessibility.Available
: Accessibility.OutOfLogic;
}
else
{
var canAccessPyramid = World.LegacyWorld.IsLocationAccessible((int)LocationId.Pyramid, progression.LegacyProgression);

var canClimbGt =
World.LegacyWorld.IsLocationAccessible((int)LocationId.GanonsTowerMoldormChest,
progression.LegacyProgression) || (!World.Config.ZeldaKeysanity &&
World.GanonsTower.Locations.All(x =>
World.LegacyWorld.IsLocationAccessible((int)x.Id,
assumedKeyProgression.LegacyProgression)));

var isPyramidOpen = World.Config.OpenPyramid || canClimbGt;
var canHurtGanon = progression.CrystalCount >= ganonCrystalRequirement && progression.MasterSword &&
(progression.Lamp || progression.FireRod);

NewAccessibility = canAccessPyramid && isPyramidOpen && canHurtGanon
? Accessibility.Available
: Accessibility.OutOfLogic;
}

if (NewAccessibility != GanonAccessibility)
{
GanonAccessibility = NewAccessibility;
UpdatedGanonAccessibility?.Invoke(this, EventArgs.Empty);
}
}

public class PyramidFairyChamber : Room
{
public PyramidFairyChamber(Region region, IMetadataService? metadata, TrackerState? trackerState)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,13 @@ public GanonsTower(World world, Config config, IMetadataService? metadata, Track

public override bool CanEnter(Progression items, bool requireRewards)
{
var gtCrystalRequirement = World.State?.GanonsTowerCrystalCount == null
? Config.GanonsTowerCrystalCount
: World.State?.MarkedGanonsTowerCrystalCount ?? 7;

var smBosses = new[] { BossType.Kraid, BossType.Phantoon, BossType.Draygon, BossType.Ridley };
var canEnterDDMEast = World.DarkWorldDeathMountainEast.CanEnter(items, requireRewards);
var haveEnoughCrystals = items.CrystalCount >= Config.GanonsTowerCrystalCount;
var haveEnoughCrystals = items.CrystalCount >= gtCrystalRequirement;
var gtOpenBeforeGanon = Config.GanonsTowerCrystalCount < Config.GanonCrystalCount;
var canBeatMetroid = World.CanDefeatBossCount(items, requireRewards, smBosses) >= Config.TourianBossCount;
return World.Logic.CanNavigateDarkWorld(items) && canEnterDDMEast && haveEnoughCrystals && (gtOpenBeforeGanon || canBeatMetroid);
Expand Down
10 changes: 5 additions & 5 deletions src/TrackerCouncil.Smz3.Data/WorldData/World.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public World(Config config, string player, int id, string guid, bool isLocalWorl

LegacyWorld = new LegacyWorld(legacyConfig, Player, Id, Guid);

UpdateLegacyWorld();
UpdateLegacyWorld(trackerState);
}
}

Expand Down Expand Up @@ -323,7 +323,7 @@ private void SetBottles(Random rnd)
}
}

public void UpdateLegacyWorld()
public void UpdateLegacyWorld(TrackerState? trackerState)
{
if (LegacyWorld == null)
{
Expand Down Expand Up @@ -354,9 +354,9 @@ public void UpdateLegacyWorld()
GetLegacyRewardType(InnerMaridia),
GetLegacyRewardType(LowerNorfairEast),
],
TowerCrystals = Config.GanonsTowerCrystalCount,
GanonCrystals = Config.GanonCrystalCount,
TourianBossTokens = Config.TourianBossCount
TowerCrystals = trackerState?.MarkedGanonsTowerCrystalCount ?? 7,
GanonCrystals = trackerState?.MarkedGanonCrystalCount ?? 7,
TourianBossTokens = trackerState?.MarkedGanonsTowerCrystalCount ?? 4
};

LegacyWorld.Setup(worldState);
Expand Down
4 changes: 4 additions & 0 deletions src/TrackerCouncil.Smz3.Data/maps.json
Original file line number Diff line number Diff line change
Expand Up @@ -1733,6 +1733,8 @@
{
"Name": "Dark World North East",
"TypeName": "TrackerCouncil.Smz3.Data.WorldData.Regions.Zelda.DarkWorld.DarkWorldNorthEast",
"BossX": 998,
"BossY": 815,
"Rooms": [
{
"Name": "Catfish",
Expand Down Expand Up @@ -2277,6 +2279,8 @@
{
"Name": "West Crateria",
"TypeName": "TrackerCouncil.Smz3.Data.WorldData.Regions.SuperMetroid.Crateria.WestCrateria",
"BossX": 453,
"BossY": 358,
"Rooms": [
{
"Name": "Energy Tank, Gauntlet",
Expand Down
Loading