Chests and Loot Drops

This commit is contained in:
Marco 2025-04-25 18:33:20 +02:00
commit a2a18c69fc
20 changed files with 242 additions and 58 deletions

View file

@ -6,7 +6,7 @@ namespace Cirno.Scripts.Components.FSM.Enemy;
public partial class EnemyDropsProvider : Node2D
{
private RandomNumberGenerator _rng = new();
//private RandomNumberGenerator _rng = new();
[Export] public float DropRadius { get; private set; } = 8f;
@ -23,7 +23,7 @@ public partial class EnemyDropsProvider : Node2D
{
if (loot is { Item: not null })
{
float roll = _rng.RandfRange(0f, 100f); // Generate a number between 0 and 100
float roll = (float)GD.RandRange(0d, 100d); // Generate a number between 0 and 100
if (roll <= loot.Chance) // Compare with drop chance
{
DropItem(loot.Item);

View file

@ -14,6 +14,8 @@ public partial class EnemyFSMProxy : CharacterBody2D, IActivable
[Export] public EnemyResource EnemyResource { get; private set; }
[Export] public Array<LootDrop> ExtraLoot { get; private set; } = [];
[Export] public bool OverrideLoot { get; set; } = false;
[Export]
public AiState StartingAiState { get; private set; }

View file

@ -23,7 +23,7 @@ public partial class EnemyStorageModule : Node2D, IFSMStorage
public float MovementSpeed => Root.EnemyResource.MovementSpeed;
public IEnumerable<LootDrop> LootDrops => Root.EnemyResource.LootDrops.Concat(Root.ExtraLoot);
public IEnumerable<LootDrop> LootDrops => Root.OverrideLoot ? Root.ExtraLoot : Root.EnemyResource.LootDrops.Concat(Root.ExtraLoot);
public AiState AiState { get; set; }

View file

@ -5,7 +5,9 @@ using Cirno.Scripts.Components.FSM.Enemy;
using Cirno.Scripts.Enums;
using Cirno.Scripts.Interactables;
using Cirno.Scripts.Resources;
using Cirno.Scripts.Resources.Loot;
using Cirno.Scripts.Resources.Roguelite;
using Cirno.Scripts.Utils;
using Godot;
using Godot.Collections;
@ -59,8 +61,9 @@ public partial class RogueliteRoom : Node2D
public RogueliteRoom Spawn()
{
SpawnEnemies();
SpawnFeatures();
//HandleDoors(connectionChecker);
AddDebugLabel();
//AddDebugLabel();
return this;
}
@ -226,12 +229,55 @@ public partial class RogueliteRoom : Node2D
var enemyScene = GD.Load<PackedScene>(e.PrefabPath);
var spawnedEnemy = spawner.CreateChild<EnemyFSMProxy>(enemyScene);
spawnedEnemy.OverrideLoot = true;
spawnedEnemy.ExtraLoot.Add(new LootDrop()
{
Item = MapTheme.EnemiesLootTable.Items.ToList().Shuffle().First(),
Chance = MapTheme.EnemyDropChance
});
spawnedEnemy.ExtraLoot.Add(new LootDrop()
{
Item = MapTheme.PointItemResource,
Chance = 100
});
_enemies.Add(spawnedEnemy);
spawnedEnemy.Death += SpawnedEnemyOnDeath;
}
}
private void SpawnFeatures()
{
// Get feature markers
// Roll for chances
// Spawn the objects
var markersContainer = this.GetNodeOrNull("Features");
if (markersContainer is null) return;
var markerNodes = markersContainer.GetChildren();
foreach (var markerNode in markerNodes)
{
if (markerNode is not Marker2D marker)
{
continue;
}
double chance = GD.RandRange(0d, 100d);
if (chance <= MapTheme.ChestChance)
{
var chest = marker.CreateChild<Chest>(MapTheme.ChestPrefab);
var loot = MapTheme.ChestLootTable.Items.ToList().Shuffle().First();
chest.LootTable.Add(loot);
}
}
}
private void SpawnedEnemyOnDeath(EnemyFSMProxy enemy)
{
enemy.Death -= SpawnedEnemyOnDeath;

View file

@ -6,8 +6,8 @@ namespace Cirno.Scripts.Resources.Loot;
public partial class LootDrop : Resource
{
[Export]
public LootItem Item { get; private set; }
public LootItem Item { get; set; }
[Export(PropertyHint.None, "suffix:%")]
public float Chance { get; private set; }
public float Chance { get; set; }
}

View file

@ -0,0 +1,10 @@
using Godot;
using Godot.Collections;
namespace Cirno.Scripts.Resources.Loot;
[GlobalClass]
public partial class LootTable : Resource
{
[Export] public Array<LootItem> Items { get; set; }
}

View file

@ -0,0 +1 @@
uid://rgx0g5iqksnn

View file

@ -1,4 +1,5 @@
using Cirno.Scripts.Resources.Roguelite;
using Cirno.Scripts.Resources.Loot;
using Cirno.Scripts.Resources.Roguelite;
using Godot;
using Godot.Collections;
@ -7,12 +8,25 @@ namespace Cirno.Scripts.Resources;
[GlobalClass]
public partial class RogueliteMapTheme : Resource
{
[ExportGroup("Prefabs")]
[Export] public PackedScene HorizontalDoorPrefab { get; set; }
[Export] public PackedScene HorizontalWallPrefab { get; set; }
[Export] public PackedScene VerticalDoorPrefab { get; set; }
[Export] public PackedScene VerticalWallPrefab { get; set; }
[Export] public PackedScene DoorLockPrefab { get; set; }
[Export] public PackedScene KeyCardPrefab { get; set; }
[Export] public PackedScene ChestPrefab { get; set; }
[Export] public PackedScene VendingMachinePrefab { get; set; }
[Export] public Array<PackedScene> KeyCardsPrefabs { get; set; }
[Export] public LootItem PointItemResource { get; set; }
[ExportGroup("Chances")]
[Export] public double ChestChance { get; set; }
[Export] public float EnemyDropChance { get; set; }
[Export] public LootTable ChestLootTable { get; set; }
[Export] public LootTable ShopLootTable { get; set; }
[Export] public LootTable EnemiesLootTable { get; set; }
[ExportCategory("Rooms")]
[Export] public Array<RogueliteRoomResource> Rooms { get; set; }
}