Skip to content

Commit

Permalink
Merge pull request #422 from Vivelin/auto-track-dungeon-rewards
Browse files Browse the repository at this point in the history
Mark dungeon rewards on hint text
  • Loading branch information
MattEqualsCoder authored Nov 19, 2023
2 parents ba54fe8 + 407799e commit f4590b2
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/Randomizer.Abstractions/AutoTrackerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ public abstract class AutoTrackerBase
/// <param name="action">The action to write to memory</param>
public abstract void WriteToMemory(EmulatorAction action);

/// <summary>
/// Sets the latest view action to use by voice command, or if specified in the options, automatically execute it
/// </summary>
/// <param name="action"></param>
public abstract void SetLatestViewAction(Action action);

/// <summary>
/// Invokes the AutoTrackerEnabled event
/// </summary>
Expand Down
13 changes: 13 additions & 0 deletions src/Randomizer.Data/Tracking/AutoTrackerZeldaState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,19 @@ public AutoTrackerZeldaState(EmulatorMemoryData data)
/// </summary>
public int OverworldScreen => ReadUInt16(0x8A);

/// <summary>
/// Returns true if Link is within a region of the screen
/// </summary>
/// <param name="topLeftX"></param>
/// <param name="topLeftY"></param>
/// <param name="bottomRightX"></param>
/// <param name="bottomRightY"></param>
/// <returns></returns>
public bool IsWithinRegion(int topLeftX, int topLeftY, int bottomRightX, int bottomRightY)
{
return LinkX >= topLeftX && LinkX <= bottomRightX && LinkY >= topLeftY && LinkX <= bottomRightY;
}

/// <summary>
/// Reads a specific block of memory
/// </summary>
Expand Down
12 changes: 12 additions & 0 deletions src/Randomizer.SMZ3.Tracking/AutoTracking/AutoTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,18 @@ public override void WriteToMemory(EmulatorAction action)
_sendActions.Enqueue(action);
}

public override void SetLatestViewAction(Action action)
{
if (TrackerBase.Options.AutoSaveLookAtEvents)
{
action.Invoke();
}
else
{
LatestViewAction = new AutoTrackerViewedAction(action);
}
}

/// <summary>
/// Called when a connector has temporarily lost connection with the emulator
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using System.Linq;
using Randomizer.Abstractions;
using Randomizer.Data.Tracking;
using Randomizer.Shared;
using Randomizer.SMZ3.Contracts;
using Randomizer.Data.WorldData;

namespace Randomizer.SMZ3.Tracking.AutoTracking.ZeldaStateChecks;

/// <summary>
/// Zelda State check for reading text
/// Checks if the game state says the player is reading text for hints
/// </summary>
public class ViewedText : IZeldaStateCheck
{
private readonly IWorldAccessor _worldAccessor;
private readonly IItemService _items;
private TrackerBase? _tracker;
private bool _greenPendantUpdated;
private bool _redCrystalsUpdated;

public ViewedText(IWorldAccessor worldAccessor, IItemService itemService)
{
_worldAccessor = worldAccessor;
_items = itemService;
}

private World World => _worldAccessor.World;

/// <summary>
/// Executes the check for the current state
/// </summary>
/// <param name="tracker">The tracker instance</param>
/// <param name="currentState">The current state in Zelda</param>
/// <param name="prevState">The previous state in Zelda</param>
/// <returns>True if the check was identified, false otherwise</returns>
public bool ExecuteCheck(TrackerBase tracker, AutoTrackerZeldaState currentState, AutoTrackerZeldaState prevState)
{
if (tracker.AutoTracker == null || currentState.State != 14 && currentState.Substate != 2) return false;

_tracker = tracker;

if (currentState.CurrentRoom == 261 && !_greenPendantUpdated && currentState.IsWithinRegion(2650, 8543, 2692, 8594))
{
tracker.AutoTracker.SetLatestViewAction(MarkGreenPendantDungeons);
}
else if (currentState.CurrentRoom == 284 && !_redCrystalsUpdated && currentState.IsWithinRegion(6268, 9070, 6308, 9122))
{
tracker.AutoTracker.SetLatestViewAction(MarkRedCrystalDungeons);
}

return false;
}

/// <summary>
/// Marks the dungeon with the green pendant
/// </summary>
private void MarkGreenPendantDungeons()
{
if (_tracker == null) return;

var dungeon = World.Dungeons.FirstOrDefault(x =>
x.DungeonRewardType == RewardType.PendantGreen && x.MarkedReward != RewardType.PendantGreen);

if (dungeon == null)
{
_greenPendantUpdated = true;
return;
}

_tracker.SetDungeonReward(dungeon, dungeon.DungeonRewardType);
_greenPendantUpdated = true;
}

/// <summary>
/// Marks the dungeons with the red crystals
/// </summary>
private void MarkRedCrystalDungeons()
{
if (_tracker == null) return;

var dungeons = World.Dungeons.Where(x =>
x.DungeonRewardType == RewardType.CrystalRed && x.MarkedReward != RewardType.CrystalRed).ToList();

if (!dungeons.Any())
{
_redCrystalsUpdated = true;
return;
}

foreach (var dungeon in dungeons)
{
_tracker.SetDungeonReward(dungeon, dungeon.DungeonRewardType);
}

_redCrystalsUpdated = true;
}
}

0 comments on commit f4590b2

Please sign in to comment.