Big project cleanup with overhaul of file responsibilities (KISS) and code (DRY, YAGNI)
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
public static class GateRequirementGenerator
|
||||
{
|
||||
public static void ApplyGateRequirements(Layer[] layers)
|
||||
{
|
||||
List<string> availableResources = new List<string>();
|
||||
|
||||
foreach (Layer layer in layers)
|
||||
{
|
||||
GateRequirementOptions options = BuildRequirementOptions(layer, availableResources);
|
||||
ApplyLayerRequirements(layer, options);
|
||||
}
|
||||
}
|
||||
|
||||
private static GateRequirementOptions BuildRequirementOptions(Layer layer, List<string> availableResources)
|
||||
{
|
||||
GateRequirementOptions options = new GateRequirementOptions();
|
||||
|
||||
foreach (string resource in layer.currentResources)
|
||||
{
|
||||
if (availableResources.Contains(resource)) continue;
|
||||
|
||||
availableResources.Add(resource);
|
||||
}
|
||||
|
||||
bool addedNewItem;
|
||||
do
|
||||
{
|
||||
addedNewItem = false;
|
||||
|
||||
foreach (ItemData item in GameData.availableItems.Values)
|
||||
{
|
||||
if (options.PossibleIngredients.Any(existing => existing.Id == item.Id)) continue;
|
||||
if (!CanCraftItem(item, availableResources)) continue;
|
||||
|
||||
options.PossibleIngredients.Add(item);
|
||||
availableResources.Add(item.Id);
|
||||
options.LowestCraftTime = Mathf.Min(options.LowestCraftTime, item.CraftTime);
|
||||
options.HighestCraftTime = Mathf.Max(options.HighestCraftTime, item.CraftTime);
|
||||
|
||||
addedNewItem = true;
|
||||
}
|
||||
} while (addedNewItem);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
private static bool CanCraftItem(ItemData item, List<string> availableResources)
|
||||
{
|
||||
return item.Inputs.All(input => availableResources.Contains(input.Item));
|
||||
}
|
||||
|
||||
private static void ApplyLayerRequirements(Layer layer, GateRequirementOptions options)
|
||||
{
|
||||
double goalCraftTime = GetGoalCraftTime(layer, options);
|
||||
int ingredientAmount = Mathf.Clamp(1 + layer.level / 3, 1, 4);
|
||||
float craftTimeModifier = 0f;
|
||||
|
||||
for (int i = 0; i < ingredientAmount; i++)
|
||||
{
|
||||
List<ItemData> validIngredients = GetValidIngredients(layer, options, goalCraftTime, craftTimeModifier);
|
||||
if (validIngredients.Count == 0)
|
||||
{
|
||||
i--;
|
||||
craftTimeModifier += 0.05f;
|
||||
continue;
|
||||
}
|
||||
|
||||
AddGateIngredient(layer, validIngredients);
|
||||
craftTimeModifier = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
private static double GetGoalCraftTime(Layer layer, GateRequirementOptions options)
|
||||
{
|
||||
return Mathf.Lerp(
|
||||
options.LowestCraftTime,
|
||||
options.HighestCraftTime,
|
||||
Mathf.Clamp(layer.level / (float)GameData.ruinSize, 0, 1)
|
||||
);
|
||||
}
|
||||
|
||||
private static List<ItemData> GetValidIngredients(
|
||||
Layer layer,
|
||||
GateRequirementOptions options,
|
||||
double goalCraftTime,
|
||||
float craftTimeModifier
|
||||
)
|
||||
{
|
||||
double craftTimeLower = goalCraftTime - goalCraftTime * craftTimeModifier;
|
||||
double craftTimeUpper = goalCraftTime + goalCraftTime * craftTimeModifier;
|
||||
|
||||
return options.PossibleIngredients
|
||||
.Where(item =>
|
||||
item.CraftTime >= craftTimeLower &&
|
||||
item.CraftTime <= craftTimeUpper &&
|
||||
!layer.gateIngredients.Any(ingredient => ingredient.Item == item.Id))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static void AddGateIngredient(Layer layer, List<ItemData> validIngredients)
|
||||
{
|
||||
ItemData item = validIngredients[GameData.rand.Next(validIngredients.Count)];
|
||||
|
||||
layer.gateIngredients.Add(new Ingredient
|
||||
{
|
||||
Item = item.Id,
|
||||
Amount = GameData.rand.Next(3 + layer.level * 2, 9 + layer.level * 4)
|
||||
});
|
||||
}
|
||||
|
||||
private class GateRequirementOptions
|
||||
{
|
||||
public List<ItemData> PossibleIngredients = new List<ItemData>();
|
||||
public double HighestCraftTime = 0;
|
||||
public double LowestCraftTime = double.MaxValue;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user