Skip to content
This repository has been archived by the owner on Aug 19, 2022. It is now read-only.

Commit

Permalink
Merge pull request #4 from syyePhenomenol/v2.2.x-refactor
Browse files Browse the repository at this point in the history
v2.2.0 refactor
  • Loading branch information
syyePhenomenol authored Feb 11, 2022
2 parents 7e9e82e + c90ef26 commit f3de09a
Show file tree
Hide file tree
Showing 36 changed files with 2,125 additions and 1,802 deletions.
222 changes: 155 additions & 67 deletions MapModS/Data/DataLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,72 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ItemChanger;
using RandomizerCore;
using RandomizerMod.IC;

namespace MapModS.Data
{
public static class DataLoader
{
private static Dictionary<string, PinDef> _pins;
private static Dictionary<string, PinDef> _pinsAM;
private static Dictionary<string, PinDef> _allPins;
private static Dictionary<string, PinDef> _allPinsAM;
private static Dictionary<string, PinDef> _usedPins = new();

//public static Dictionary<string, PinDef> newPins = new();

private static readonly HashSet<string> shopLocations = new()
{
"Sly",
"Sly_(Key)",
"Iselda",
"Salubra",
"Leg_Eater",
"Grubfather",
"Seer",
"Egg_Shop"
};

public static PinDef[] GetPinArray()
{
return _pins.Values.ToArray();
return _allPins.Values.ToArray();
}

public static PinDef[] GetPinAMArray()
{
return _pinsAM.Values.ToArray();
return _allPinsAM.Values.ToArray();
}

public static PinDef[] GetUsedPinArray()
{
return _usedPins.Values.ToArray();
}

public static PinDef GetUsedPinDef(string locationName)
{
if (_usedPins.TryGetValue(locationName, out PinDef pinDef))
{
return pinDef;
}

return default;
}

// Uses RandomizerData to get the PoolGroup from an item name
public static PoolGroup GetPoolGroup(string cleanItemName)
{
if (shopLocations.Contains(cleanItemName)) return PoolGroup.Shop;

if (cleanItemName.EndsWith("_Geo")) return PoolGroup.GeoChests;

switch (cleanItemName)
{
case "Dreamer":
return PoolGroup.Dreamers;

case "Split_Mothwing_Cloak":
case "Split_Crystal_Heart":
case "Downslash":
return PoolGroup.Skills;

case "Double_Mask_Shard":
Expand Down Expand Up @@ -64,6 +102,10 @@ public static PoolGroup GetPoolGroup(string cleanItemName)
case "WallClimb":
return PoolGroup.Skills;

case "Lever":
case "Switch":
return PoolGroup.Levers;

default:
break;
}
Expand All @@ -81,107 +123,153 @@ public static PoolGroup GetPoolGroup(string cleanItemName)
}
}

MapModS.Instance.LogWarn($"PoolGroup not found for an item");
MapModS.Instance.LogWarn($"PoolGroup not found for an item: " + cleanItemName);

return PoolGroup.Unknown;
}

public static PoolGroup GetVanillaPoolGroup(string location)
public static PoolGroup GetLocationPoolGroup(string location)
{
string cleanItemName = location.Split('-')[0];

return GetPoolGroup(cleanItemName);
}

public static PoolGroup GetRandomizerPoolGroup(string location, bool getLast)
public static PoolGroup GetItemPoolGroup(string item)
{
if (RandomizerMod.RandomizerMod.RS.Context.itemPlacements.Any(pair => pair.location.Name == location))
string cleanItemName = item.Replace("Placeholder-", "").Split('-')[0];

return GetPoolGroup(cleanItemName);
}

// Next five helper functions are based on BadMagic100's Rando4Stats RandoExtensions
// MIT License

// Copyright(c) 2022 BadMagic100

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
public static ItemPlacement RandoPlacement(this AbstractItem item)
{
if (item.GetTag(out RandoItemTag tag))
{
RandomizerCore.ItemPlacement ilp;
return RandomizerMod.RandomizerMod.RS.Context.itemPlacements[tag.id];
}
return default;
}

if (getLast)
{
ilp = RandomizerMod.RandomizerMod.RS.Context.itemPlacements.Last(pair => pair.location.Name == location);
}
else
{
ilp = RandomizerMod.RandomizerMod.RS.Context.itemPlacements.First(pair => pair.location.Name == location);
}
public static string RandoItemName(this AbstractItem item)
{
return item.RandoPlacement().item.Name ?? "";
}

string cleanItemName = ilp.item.Name.Replace("Placeholder-", "").Split('-')[0];
public static string RandoLocationName(this AbstractItem item)
{
return item.RandoPlacement().location.Name ?? "";
}

return GetPoolGroup(cleanItemName);
public static int RandoItemId(this AbstractItem item)
{
if (item.GetTag(out RandoItemTag tag))
{
return tag.id;
}
return default;
}

return GetVanillaPoolGroup(location);
public static bool CanPreview(this AbstractPlacement placement)
{
return !placement.HasTag<ItemChanger.Tags.DisableItemPreviewTag>();
}

// This method finds the vanilla and spoiler PoolGroups corresponding to each Pin, using RandomizerMod's ItemPlacements array
// Called once per save load
public static void FindPoolGroups()
public static bool IsPersistent(this AbstractItem item)
{
foreach (KeyValuePair<string, PinDef> entry in _pins)
return item.HasTag<ItemChanger.Tags.PersistentItemTag>();
}

public static void SetUsedPinDefs()
{
_usedPins.Clear();

foreach (KeyValuePair<string, AbstractPlacement> placement in ItemChanger.Internal.Ref.Settings.Placements)
{
string vanillaItem = entry.Key;
PinDef pinD = entry.Value;
IEnumerable<ItemDef> items = placement.Value.Items
.Where(x => !x.IsObtained())
.Select(x => new ItemDef(x));

// First check if this is a shop pin
if (pinD.isShop)
if (!items.Any()) continue;

string locationName = placement.Value.Items.Where(x => !x.IsObtained()).First().RandoLocationName();

if (locationName == "Start") continue;

if (_allPins.TryGetValue(locationName, out PinDef pinDef))
{
pinD.vanillaPool = PoolGroup.Shop;
pinD.spoilerPool = PoolGroup.Shop;
pinDef.randoItems = items;
pinDef.canPreview = placement.Value.CanPreview();
pinDef.pinLocationState = PinLocationState.UncheckedUnreachable;
pinDef.locationPoolGroup = GetLocationPoolGroup(pinDef.name);

_usedPins.Add(locationName, pinDef);
}
// Then check if this item is randomized
else
{
pinD.vanillaPool = GetVanillaPoolGroup(vanillaItem);
pinD.spoilerPool = GetRandomizerPoolGroup(vanillaItem, false);
MapModS.Instance.Log("No corresponding pin location for a placement");
}
}

bool leverRandoEnabled = _usedPins.Any(p => p.Key.StartsWith("Lever"));

if (pinD.vanillaPool == PoolGroup.Unknown || pinD.spoilerPool == PoolGroup.Unknown)
foreach (KeyValuePair<string, PinDef> pinDef in _allPins)
{
if (!_usedPins.ContainsKey(pinDef.Key)
&& !pinDef.Value.randoOnly
&& !RandomizerMod.RandomizerMod.RS.TrackerData.clearedLocations.Contains(pinDef.Key))
{
if (leverRandoEnabled && (pinDef.Value.name == "Dirtmouth_Stag" || pinDef.Value.name == "Resting_Grounds_Stag"))
{
MapModS.Instance.LogWarn($"A location doesn't seem to have a valid pool.");
continue;
}

pinDef.Value.pinLocationState = PinLocationState.NonRandomizedUnchecked;
pinDef.Value.locationPoolGroup = GetLocationPoolGroup(pinDef.Value.name);
_usedPins.Add(pinDef.Key, pinDef.Value);
}
}

if (pinD.name == "Focus")
if (MapModS.AdditionalMapsInstalled)
{
foreach (PinDef pinDefAM in GetPinAMArray())
{
pinD.spoilerPool = GetRandomizerPoolGroup("Lore_Tablet-King's_Pass_Focus", true);
if (_usedPins.TryGetValue(pinDefAM.name, out PinDef pinDef))
{
pinDef.pinScene = pinDefAM.pinScene;
pinDef.mapZone = pinDefAM.mapZone;
pinDef.offsetX = pinDefAM.offsetX;
pinDef.offsetY = pinDefAM.offsetY;
}
}
}

// Disable pins based on Randomizer settings
_pins["Egg_Shop"].disable = !RandomizerMod.RandomizerMod.RS.GenerationSettings.NoveltySettings.EggShop;

_pins["Elevator_Pass"].disable = !RandomizerMod.RandomizerMod.RS.GenerationSettings.NoveltySettings.RandomizeElevatorPass;

_pins["Focus"].disable = !RandomizerMod.RandomizerMod.RS.GenerationSettings.NoveltySettings.RandomizeFocus;

_pins["Mantis_Claw"].disable = RandomizerMod.RandomizerMod.RS.GenerationSettings.NoveltySettings.SplitClaw;

_pins["Left_Mantis_Claw"].disable = !RandomizerMod.RandomizerMod.RS.GenerationSettings.NoveltySettings.SplitClaw;
_pins["Right_Mantis_Claw"].disable = !RandomizerMod.RandomizerMod.RS.GenerationSettings.NoveltySettings.SplitClaw;

_pins["Split_Mothwing_Cloak"].disable = !RandomizerMod.RandomizerMod.RS.GenerationSettings.NoveltySettings.SplitCloak;

_pins["Split_Crystal_Heart"].disable = !RandomizerMod.RandomizerMod.RS.GenerationSettings.NoveltySettings.SplitSuperdash;

_pins["World_Sense"].disable = !RandomizerMod.RandomizerMod.RS.GenerationSettings.PoolSettings.Dreamers;

bool disableMushroomLocations = !RandomizerMod.RandomizerMod.RS.Context.itemPlacements.Any(pair => pair.location.Name.Contains("Mr_Mushroom"));

_pins["Mr_Mushroom-Fungal_Wastes"].disable = disableMushroomLocations;
_pins["Mr_Mushroom-Kingdom's_Edge"].disable = disableMushroomLocations;
_pins["Mr_Mushroom-Deepnest"].disable = disableMushroomLocations;
_pins["Mr_Mushroom-Howling_Cliffs"].disable = disableMushroomLocations;
_pins["Mr_Mushroom-Ancient_Basin"].disable = disableMushroomLocations;
_pins["Mr_Mushroom-Fog_Canyon"].disable = disableMushroomLocations;
_pins["Mr_Mushroom-King's_Pass"].disable = disableMushroomLocations;
}

public static void Load()
{
_pins = JsonUtil.Deserialize<Dictionary<string, PinDef>>("MapModS.Resources.pins.json");
_pinsAM = JsonUtil.Deserialize<Dictionary<string, PinDef>>("MapModS.Resources.pinsAM.json");
_allPins = JsonUtil.Deserialize<Dictionary<string, PinDef>>("MapModS.Resources.pins.json");
_allPinsAM = JsonUtil.Deserialize<Dictionary<string, PinDef>>("MapModS.Resources.pinsAM.json");
}

// For debugging pins
//public static void LoadNewPinDef()
//{
// newPins.Clear();
// newPins = JsonUtil.DeserializeFromExternalFile<Dictionary<string, PinDef>>("newPins.json");
//}
}
}
25 changes: 25 additions & 0 deletions MapModS/Data/ItemDef.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using ItemChanger;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MapModS.Data
{
public class ItemDef
{
public ItemDef(AbstractItem item)
{
id = item.RandoItemId();
itemName = item.RandoItemName();
poolGroup = DataLoader.GetItemPoolGroup(item.RandoItemName());
persistent = item.IsPersistent();
}

public int id;
public string itemName;
public PoolGroup poolGroup;
public bool persistent = false;
}
}
10 changes: 10 additions & 0 deletions MapModS/Data/JsonUtil.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.IO;
using System.Reflection;

// Code taken from homothety: https://github.com/homothetyhk/RandomizerMod/

Expand All @@ -17,6 +18,15 @@ public static T Deserialize<T>(string embeddedResourcePath)
return _js.Deserialize<T>(jtr);
}

// For debugging pins
//public static T DeserializeFromExternalFile<T>(string externalFile)
//{
// string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
// using StreamReader sr = new(Path.Combine(assemblyFolder, externalFile));
// using JsonTextReader jtr = new(sr);
// return _js.Deserialize<T>(jtr);
//}

public static T DeserializeString<T>(string json)
{
using StringReader sr = new(json);
Expand Down
14 changes: 6 additions & 8 deletions MapModS/Data/PinDef.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using GlobalEnums;
using System.Collections.Generic;

namespace MapModS.Data
{
Expand All @@ -24,19 +25,16 @@ public class PinDef

// The local offset of the pin relative to its pinScene/sceneName map object
public float offsetX;

public float offsetY;
public float offsetZ;

public bool isShop = false;
public bool randoOnly = false;

// These are assigned during FindSpoilerPools, unusued if it's a Shop
public PoolGroup vanillaPool;

public PoolGroup spoilerPool;

public PreviewGroup previewGroup;
public PoolGroup locationPoolGroup;

public bool disable = false;
public IEnumerable<ItemDef> randoItems;
public bool canPreview;
public PinLocationState pinLocationState;
}
}
Loading

0 comments on commit f3de09a

Please sign in to comment.