Files
GameJamDungeon/Zennysoft.Game.Ma/src/items/ItemDatabase.cs
2026-02-13 15:59:10 -08:00

152 lines
6.2 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<IBaseInventoryItem> Items { get; set; }
public T PickItem<T>(params T[] itemsToExclude)
where T : IBaseInventoryItem
{
var itemsToSelectFrom = Items.OfType<T>();
return PickItemInternal(itemsToSelectFrom, itemsToExclude);
}
public T PickRareItem<T>(params T[] itemsToExclude)
where T : IBaseInventoryItem
{
var getRareItems = Items.OfType<T>().Where(x => x.SpawnRate < 0.1f);
return PickItemInternal(getRareItems, itemsToExclude);
}
public T PickBasicItem<T>(params T[] itemsToExclude)
where T : IBaseInventoryItem
{
var getBasicItems = Items.OfType<T>().Where(x => x.SpawnRate > 0.5f);
return PickItemInternal(getBasicItems, itemsToExclude);
}
private T PickItemInternal<T>(IEnumerable<T> itemsToSelectFrom, params T[] itemsToExclude)
where T : IBaseInventoryItem
{
var rng = new RandomNumberGenerator();
rng.Randomize();
if (itemsToExclude.Any())
itemsToSelectFrom.Except(itemsToExclude);
var weights = itemsToSelectFrom.Select(x => x.SpawnRate).ToArray();
var selectedItem = itemsToSelectFrom.ToArray()[rng.RandWeighted(weights)];
return selectedItem;
}
private ItemDatabase()
{
var database = new List<IBaseInventoryItem>();
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/");
var boxResources = DirAccess.GetFilesAt("res://src/items/box/resources/");
var ammoResources = DirAccess.GetFilesAt("res://src/items/ammo/resources/");
var jewelResources = DirAccess.GetFilesAt("res://src/items/jewels/resources/");
foreach (var armor in armorResources)
{
var armorInfo = GD.Load<ArmorStats>($"res://src/items/armor/resources/{armor}".TrimSuffix(".remap"));
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}".TrimSuffix(".remap"));
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}".TrimSuffix(".remap"));
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}".TrimSuffix(".remap"));
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}".TrimSuffix(".remap"));
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}".TrimSuffix(".remap"));
var effectItemScene = ResourceLoader.Load<PackedScene>("res://src/items/effect/EffectItem.tscn").Instantiate<EffectItem>();
effectItemScene.Stats = effectItemInfo;
if (!database.Contains(effectItemScene))
database.Add(effectItemScene);
}
foreach (var boxItem in boxResources)
{
var boxItemInfo = GD.Load<BoxItemStats>($"res://src/items/box/resources/{boxItem}".TrimSuffix(".remap"));
var boxItemScene = ResourceLoader.Load<PackedScene>("res://src/items/box/BoxItem.tscn").Instantiate<BoxItem>();
boxItemScene.Stats = boxItemInfo;
if (!database.Contains(boxItemScene))
database.Add(boxItemScene);
}
foreach (var ammoItem in ammoResources)
{
var ammoItemInfo = GD.Load<AmmoStats>($"res://src/items/ammo/resources/{ammoItem}".TrimSuffix(".remap"));
var ammoItemScene = ResourceLoader.Load<PackedScene>("res://src/items/ammo/Ammo.tscn").Instantiate<Ammo>();
ammoItemScene.Stats = ammoItemInfo;
if (!database.Contains(ammoItemScene))
database.Add(ammoItemScene);
}
foreach (var jewelItem in jewelResources)
{
var jewelItemInfo = GD.Load<JewelStats>($"res://src/items/jewels/resources/{jewelItem}".TrimSuffix(".remap"));
var jewelItemScene = ResourceLoader.Load<PackedScene>("res://src/items/jewels/Jewel.tscn").Instantiate<Jewel>();
jewelItemScene.Stats = jewelItemInfo;
if (!database.Contains(jewelItemScene))
database.Add(jewelItemScene);
}
Items = [.. database];
}
}