diff --git a/README.md b/README.md index a7ae95f..873c8c9 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ D:\Godot_v4.7.1\Godot_v4.7.1-stable_mono_win64.exe 1. **Подземелье** (`scenes/Dungeon.tscn`) — разрез убежища à la Fallout Shelter: сетка 6×5 комнат + объекты (фонари/свет). Карта стартует пустой; персонажи создаются **спавнером** - (панель внизу: `+ Раб / Монстр / Ребёнок / Игрок`) и **стоят в idle**, пока их не перетащат. + (панель внизу: кнопки типов `+ Раб/Монстр/Ребёнок/Игрок` для случайного, или выпадающий список конкретного персонажа + «Заспавнить») и **стоят в idle**, пока их не перетащат. - **Типы персонажей** (Игрок/Раб/Монстр/Ребёнок) + генерация имён. - **Тематические комнаты со слотами по типу**: Дойка = 2 раба + 4 ребёнка, Логово = 1 раб + 1 монстр. Перетаскивание в подходящий слот меняет скелет на diff --git a/src/RoomMap.cs b/src/RoomMap.cs index 7d6bfed..9243b95 100644 --- a/src/RoomMap.cs +++ b/src/RoomMap.cs @@ -118,15 +118,13 @@ public partial class RoomMap : Node2D } // ---------- спавнер персонажей ---------- + private OptionButton _charPick; + private void BuildSpawner() { var bar = new HBoxContainer { Position = new Vector2(16, GetViewportRect().Size.Y - 46) }; bar.AddThemeConstantOverride("separation", 8); - var lbl = new Label { Text = "Спавн:" }; - lbl.AddThemeColorOverride("font_color", Colors.White); - lbl.AddThemeConstantOverride("outline_size", 3); - lbl.AddThemeColorOverride("font_outline_color", Colors.Black); - bar.AddChild(lbl); + bar.AddChild(BarLabel("Спавн (тип):")); foreach (var t in new[] { CType.Slave, CType.Monster, CType.Child, CType.Player }) { var tt = t; @@ -134,14 +132,48 @@ public partial class RoomMap : Node2D b.Pressed += () => SpawnCharacter(tt); bar.AddChild(b); } + bar.AddChild(BarLabel("| персонаж:")); + _charPick = new OptionButton(); + foreach (var name in SpawnableCharacters()) _charPick.AddItem(name); + bar.AddChild(_charPick); + var spawnBtn = new Button { Text = "Заспавнить" }; + spawnBtn.Pressed += () => + { + if (_charPick.Selected >= 0) SpawnByName(_charPick.GetItemText(_charPick.Selected)); + }; + bar.AddChild(spawnBtn); AddChild(bar); } + private static Label BarLabel(string text) + { + var l = new Label { Text = text }; + l.AddThemeColorOverride("font_color", Colors.White); + l.AddThemeConstantOverride("outline_size", 3); + l.AddThemeColorOverride("font_outline_color", Colors.Black); + return l; + } + + private static List SpawnableCharacters() + { + var list = new List(); + var root = DirAccess.Open("res://characters"); + if (root != null) + foreach (var d in root.GetDirectories()) + if (ResolveScene(d) != null) list.Add(d); + list.Sort(); + return list; + } + private void SpawnCharacter(CType type) { string[] roster = type == CType.Monster ? MonsterRoster : type == CType.Child ? ChildRoster : type == CType.Player ? PlayerRoster : SlaveRoster; - string name = roster[_rng.Next(roster.Length)]; + SpawnByName(roster[_rng.Next(roster.Length)]); + } + + private void SpawnByName(string name) + { string path = ResolveScene(name); if (path == null) return; var p = SpawnPawn(path, _rng.Next(Rows));