125 lines
4.8 KiB
C#
125 lines
4.8 KiB
C#
using Godot;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using System.Linq;
|
|
using Zennysoft.Ma.Adapter;
|
|
|
|
namespace Zennysoft.Game.Ma;
|
|
|
|
public class ItemDatabase
|
|
{
|
|
private static readonly Lazy<ItemDatabase> lazy =
|
|
new Lazy<ItemDatabase>(() => new ItemDatabase());
|
|
|
|
public static ItemDatabase Instance { get { return lazy.Value; } }
|
|
|
|
public ImmutableList<InventoryItem> Items { get; set; }
|
|
|
|
public T PickItem<T>(T itemToExclude = null)
|
|
where T : InventoryItem
|
|
{
|
|
var itemsToSelectFrom = Items;
|
|
return PickItemInternal(itemsToSelectFrom, itemToExclude);
|
|
}
|
|
|
|
public T PickRareItem<T>(T itemToExclude = null)
|
|
where T : InventoryItem
|
|
{
|
|
var getRareItems = Items.Where(x => x.SpawnRate < 0.1f);
|
|
return PickItemInternal(getRareItems, itemToExclude);
|
|
}
|
|
|
|
public T PickBasicItem<T>(T itemToExclude = null)
|
|
where T : InventoryItem
|
|
{
|
|
var getBasicItems = Items.Where(x => x.SpawnRate > 0.5f);
|
|
return PickItemInternal(getBasicItems, itemToExclude);
|
|
}
|
|
|
|
private T PickItemInternal<T>(IEnumerable<InventoryItem> itemsToSelectFrom, T itemToExclude = null)
|
|
where T : InventoryItem
|
|
{
|
|
var rng = new RandomNumberGenerator();
|
|
rng.Randomize();
|
|
|
|
if (itemToExclude is not null)
|
|
itemsToSelectFrom = [.. itemsToSelectFrom.OfType<T>().Where(x => x.ItemName != itemToExclude.ItemName)];
|
|
|
|
var weights = itemsToSelectFrom.Select(x => x.SpawnRate).ToArray();
|
|
var selectedItem = itemsToSelectFrom.ToArray()[rng.RandWeighted(weights)];
|
|
|
|
if (selectedItem is ThrowableItem throwableItem)
|
|
throwableItem.SetCount(rng.RandiRange(throwableItem.Stats.MinimumCount, throwableItem.Stats.MaximumCount));
|
|
|
|
return (T)selectedItem;
|
|
}
|
|
|
|
private ItemDatabase()
|
|
{
|
|
var database = new List<InventoryItem>();
|
|
var armorResources = DirAccess.GetFilesAt("res://src/items/armor/resources/");
|
|
var weaponResources = DirAccess.GetFilesAt("res://src/items/weapons/resources/");
|
|
var accessoryResources = DirAccess.GetFilesAt("res://src/items/accessory/resources/");
|
|
var throwableResources = DirAccess.GetFilesAt("res://src/items/throwable/resources/");
|
|
var consumableResources = DirAccess.GetFilesAt("res://src/items/consumable/resources/");
|
|
var effectResources = DirAccess.GetFilesAt("res://src/items/effect/resources/");
|
|
|
|
foreach (var armor in armorResources)
|
|
{
|
|
var armorInfo = GD.Load<ArmorStats>($"res://src/items/armor/resources/{armor}");
|
|
var armorScene = ResourceLoader.Load<PackedScene>("res://src/items/armor/Armor.tscn").Instantiate<Armor>();
|
|
armorScene.Stats = armorInfo;
|
|
if (!database.Contains(armorScene))
|
|
database.Add(armorScene);
|
|
}
|
|
|
|
foreach (var weapon in weaponResources)
|
|
{
|
|
var weaponInfo = GD.Load<WeaponStats>($"res://src/items/weapons/resources/{weapon}");
|
|
var weaponScene = ResourceLoader.Load<PackedScene>("res://src/items/weapons/Weapon.tscn").Instantiate<Weapon>();
|
|
weaponScene.Stats = weaponInfo;
|
|
if (!database.Contains(weaponScene))
|
|
database.Add(weaponScene);
|
|
}
|
|
|
|
foreach (var accessory in accessoryResources)
|
|
{
|
|
var accessoryInfo = GD.Load<AccessoryStats>($"res://src/items/accessory/resources/{accessory}");
|
|
var accessoryScene = ResourceLoader.Load<PackedScene>("res://src/items/accessory/Accessory.tscn").Instantiate<Accessory>();
|
|
accessoryScene.Stats = accessoryInfo;
|
|
if (!database.Contains(accessoryScene))
|
|
database.Add(accessoryScene);
|
|
}
|
|
|
|
foreach (var throwable in throwableResources)
|
|
{
|
|
var throwableItemInfo = GD.Load<ThrowableItemStats>($"res://src/items/throwable/resources/{throwable}");
|
|
var throwableItemScene = ResourceLoader.Load<PackedScene>("res://src/items/throwable/ThrowableItem.tscn").Instantiate<ThrowableItem>();
|
|
throwableItemScene.Stats = throwableItemInfo;
|
|
if (!database.Contains(throwableItemScene))
|
|
database.Add(throwableItemScene);
|
|
}
|
|
|
|
foreach (var consumable in consumableResources)
|
|
{
|
|
var consumableItemInfo = GD.Load<ConsumableItemStats>($"res://src/items/consumable/resources/{consumable}");
|
|
var consumableItemScene = ResourceLoader.Load<PackedScene>("res://src/items/consumable/ConsumableItem.tscn").Instantiate<ConsumableItem>();
|
|
consumableItemScene.Stats = consumableItemInfo;
|
|
if (!database.Contains(consumableItemScene))
|
|
database.Add(consumableItemScene);
|
|
}
|
|
|
|
foreach (var effectItem in effectResources)
|
|
{
|
|
var effectItemInfo = GD.Load<EffectItemStats>($"res://src/items/effect/resources/{effectItem}");
|
|
var effectItemScene = ResourceLoader.Load<PackedScene>("res://src/items/effect/EffectItem.tscn").Instantiate<EffectItem>();
|
|
effectItemScene.Stats = effectItemInfo;
|
|
if (!database.Contains(effectItemScene))
|
|
database.Add(effectItemScene);
|
|
}
|
|
|
|
Items = [.. database];
|
|
}
|
|
}
|