152 lines
6.2 KiB
C#
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];
|
|
}
|
|
}
|