Skip to content

Commit

Permalink
Fix hints for scam possible progression items like mushroom
Browse files Browse the repository at this point in the history
  • Loading branch information
MattEqualsCoder committed Jan 7, 2025
1 parent d7d211c commit df39ce6
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -309,10 +309,10 @@ public bool IsJunk(Config? config)
/// This method only considers the item's value on its own. Call TrackerBase.IsWorth(ItemData) to include
/// items that this item might logically lead to.
/// </remarks>
public bool IsProgression(Config? config, bool isLocalPlayerItem)
public bool IsPossibleProgression(Config? config, bool isLocalPlayerItem)
{
// Todo: We can add special logic like checking if it's one of the first two swords
return InternalItemType.IsPossibleProgression(config?.ZeldaKeysanity == true, config?.MetroidKeysanity == true, isLocalPlayerItem);
return InternalItemType.IsPossibleProgression(config?.ZeldaKeysanity == true, config?.MetroidKeysanity == true,
isLocalPlayerItem);
}

/// <summary>
Expand Down
41 changes: 22 additions & 19 deletions src/TrackerCouncil.Smz3.SeedGenerator/Generation/GameHintService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using TrackerCouncil.Smz3.Data.Configuration;
using TrackerCouncil.Smz3.Data.Configuration.ConfigFiles;
using TrackerCouncil.Smz3.Data.GeneratedData;
using TrackerCouncil.Smz3.Data.Options;
using TrackerCouncil.Smz3.Data.Services;
using TrackerCouncil.Smz3.Data.WorldData;
using TrackerCouncil.Smz3.Data.WorldData.Regions;
Expand Down Expand Up @@ -158,8 +157,10 @@ public void GetInGameHints(World hintPlayerWorld, List<World> allWorlds, Playthr
var importantLocations = GetImportantLocations(allWorlds);

locationsToCheck = locationsToCheck.Where(l => s_importantLocations.Contains(l.Id) || l.Item.Progression ||
l.Item.Type.IsInAnyCategory(ItemCategory.SmallKey, ItemCategory.BigKey, ItemCategory.Keycard) ||
l.Item.Type is ItemType.Super or ItemType.PowerBomb or ItemType.ProgressiveSword or ItemType.SilverArrows).ToList();
l.Item.Type.IsInAnyCategory(ItemCategory.SmallKey,
ItemCategory.BigKey, ItemCategory.Keycard,
ItemCategory.PossibleProgression,
ItemCategory.ProgressionOnLimitedAmount)).ToList();

if (!locationsToCheck.Any())
{
Expand All @@ -183,8 +184,9 @@ public LocationUsefulness GetUsefulness(List<Location> locations, List<World> al
var importantLocations = GetImportantLocations(allWorlds);

locations = locations.Where(l => s_importantLocations.Contains(l.Id) || l.Item.Progression ||
l.Item.Type.IsInAnyCategory(ItemCategory.SmallKey, ItemCategory.BigKey, ItemCategory.Keycard) ||
l.Item.Type is ItemType.Super or ItemType.PowerBomb or ItemType.ProgressiveSword or ItemType.SilverArrows).ToList();
l.Item.Type.IsInAnyCategory(ItemCategory.SmallKey, ItemCategory.BigKey,
ItemCategory.Keycard, ItemCategory.PossibleProgression,
ItemCategory.ProgressionOnLimitedAmount)).ToList();

if (!locations.Any())
{
Expand All @@ -200,13 +202,13 @@ public LocationUsefulness GetUsefulness(List<Location> locations, List<World> al
/// </summary>
private IEnumerable<Hint> GetProgressionItemHints(World hintPlayerWorld, IEnumerable<Playthrough.Sphere> spheres, int count)
{
// Grab items for the player marked as progression that are not junk or scam items
// Grab items for the player marked as progression that are not junk
var progressionLocations = spheres
.SelectMany(x => x.Locations)
.Where(x => x.Item.World == hintPlayerWorld && x.Item.Progression &&
!x.Item.Type.IsInAnyCategory(ItemCategory.Junk, ItemCategory.Scam)).ToList();
.Where(x => x.Item.World == hintPlayerWorld && x.Item.Type.IsInCategory(ItemCategory.PossibleProgression) &&
!x.Item.Type.IsInCategory(ItemCategory.Scam)).ToList();
progressionLocations =
progressionLocations.TakeLast(progressionLocations.Count() / 2).Shuffle(_random).Take(count).ToList();
progressionLocations.TakeLast(progressionLocations.Count() / 3).Shuffle(_random).Take(count).ToList();

return progressionLocations.Select(x => new Hint(() => GetProgressionItemHint(x)));

Expand Down Expand Up @@ -660,21 +662,22 @@ private IEnumerable<Location> GetImportantLocations(List<World> allWorlds)
// Get the first accessible ammo locations to make sure early ammo isn't considered mandatory when there
// are others available
var spheres = _playthroughService.GenerateSpheres(allWorlds.SelectMany(x => x.Locations));
var ammoItemTypes = new List<ItemType>()
{
ItemType.Missile,
ItemType.Super,
ItemType.PowerBomb,
ItemType.ETank,
ItemType.ReserveTank,
var ammoItemTypes = new Dictionary<ItemType, int>()
{
{ ItemType.Missile, 1 },
{ ItemType.Super, 1 },
{ ItemType.PowerBomb, 2 },
{ ItemType.ETank, 3 },
{ ItemType.ReserveTank, 3},
{ ItemType.HeartContainer, 3 }
};
var ammoLocations = new List<Location>();
foreach (var sphere in spheres)
{
foreach (var location in sphere.Locations.Where(x => ammoItemTypes.Contains(x.Item.Type)))
foreach (var location in sphere.Locations.Where(x => ammoItemTypes.ContainsKey(x.Item.Type)))
{
if (ammoLocations.Count(x =>
x.Item.World.Id == location.Item.World.Id && x.Item.Type == location.Item.Type) < 3)
x.Item.World.Id == location.Item.World.Id && x.Item.Type == location.Item.Type) < ammoItemTypes[location.Item.Type])
{
ammoLocations.Add(location);
}
Expand All @@ -684,7 +687,7 @@ private IEnumerable<Location> GetImportantLocations(List<World> allWorlds)
return allWorlds.SelectMany(w => w.Locations)
.Where(l => s_importantLocations.Contains(l.Id) || l.Item.Progression ||
l.Item.Type.IsInAnyCategory(ItemCategory.SmallKey, ItemCategory.BigKey,
ItemCategory.Keycard) || l.Item.Type is ItemType.Super or ItemType.PowerBomb or ItemType.ProgressiveSword or ItemType.SilverArrows)
ItemCategory.Keycard, ItemCategory.PossibleProgression))
.Concat(ammoLocations)
.Distinct();
}
Expand Down
13 changes: 12 additions & 1 deletion src/TrackerCouncil.Smz3.Shared/Enums/ItemCategory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,20 @@ public enum ItemCategory
/// </summary>
IgnoreOnMultiplayerCompletion,

/// <summary>
/// An item that is never considered progression, such as maps, compasses, or arrows
/// </summary>
NeverProgression,

ProgressionOnlyOnFirst,
/// <summary>
/// An item that can be the progression if it's one of the first ones picked up
/// </summary>
ProgressionOnLimitedAmount,

/// <summary>
/// An item that is at least sometimes required to complete the game
/// </summary>
PossibleProgression,

/// <summary>
/// If this is a Metroid map in an archipelago game
Expand Down
Loading

0 comments on commit df39ce6

Please sign in to comment.