From 7a754d618d5faf3ebcf6fbf955f822449925c800 Mon Sep 17 00:00:00 2001 From: Leonid Pershin Date: Tue, 4 Aug 2026 05:32:57 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9A=D0=BE=D0=BC=D0=BD=D0=B0=D1=82=D1=8B:=20?= =?UTF-8?q?=D1=80=D1=83=D1=87=D0=BD=D1=8B=D0=B5=20=D1=84=D0=B8=D0=BA=D1=81?= =?UTF-8?q?-=D0=BF=D0=BE=D0=B7=D0=B8=D1=86=D0=B8=D0=B8=20=D1=81=D0=BB?= =?UTF-8?q?=D0=BE=D1=82=D0=BE=D0=B2=20(Room.SlotPos),=20=D0=BF=D0=BE=20?= =?UTF-8?q?=D0=BD=D0=BE=D0=B3=D0=B0=D0=BC=20=D0=BA=D0=B0=D0=BA=20=D0=B2=20?= =?UTF-8?q?=D0=B4=D0=B5=D0=B1=D0=B0=D0=B3=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Каждый слот может иметь точную позицию (перекрывает авто-распределение) - Дойка слот раба 1 = (1100, 918) - Фикс-позиция ставит НОГИ персонажа в координату (совпадает с DEBUG при drag), авто-слоты по-прежнему центрируются Co-Authored-By: Claude Opus 4.8 --- src/RoomMap.cs | 51 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/src/RoomMap.cs b/src/RoomMap.cs index 9243b95..3c291d0 100644 --- a/src/RoomMap.cs +++ b/src/RoomMap.cs @@ -54,9 +54,10 @@ public partial class RoomMap : Node2D public string[] States; // приоритет состояний-скелетов public CType[] SlotTypes; // тип, разрешённый в каждом слоте public Pawn[] SlotOcc; // кто в слоте (null = свободно) + public Vector2?[] SlotPos; // точная позиция слота (null = авто) public Label Header; public int Cap => SlotTypes.Length; - public void Init() => SlotOcc = new Pawn[SlotTypes.Length]; + public void Init() { SlotOcc = new Pawn[SlotTypes.Length]; SlotPos = new Vector2?[SlotTypes.Length]; } public int Count() { int n = 0; foreach (var s in SlotOcc) if (s != null) n++; return n; } public int SlotOf(Pawn p) => System.Array.IndexOf(SlotOcc, p); public int FreeSlotFor(CType t) @@ -338,6 +339,11 @@ public partial class RoomMap : Node2D SlotTypes = new[] { CType.Slave, CType.Slave, CType.Child, CType.Child, CType.Child, CType.Child } }, }; foreach (var r in _rooms) r.Init(); + + // ручные позиции посадки (фикс, по ногам как в дебаге) + var doyka = _rooms.First(r => r.Type == "Дойка"); + doyka.SlotPos[0] = new Vector2(1100, 918); // раб, слот 1 + BuildRoomHeaders(); // рамки поверх всех ячеек — читаемость сетки @@ -502,37 +508,42 @@ public partial class RoomMap : Node2D private static readonly Vector2 CenterAnchor = new Vector2(640f, 360f); // центр кадра 1280x720 - // расставить по слотам: основные (Игрок/Раб/Монстр) в ряд, дети — ниже и мельче + // расставить по слотам: фикс-позиция (SlotPos, по ногам) либо авто-распределение (по центру) private void LayoutRoom(Room room) { bool group = room.Count() >= 2; - var main = new List(); - var kids = new List(); for (int i = 0; i < room.Cap; i++) - (room.SlotTypes[i] == CType.Child ? kids : main).Add(i); - PlaceGroup(room, main, group, Cell * 0.74f, 1f); - PlaceGroup(room, kids, group, Cell * 0.9f, 0.55f); - UpdateRoomHeader(room); - } - - private void PlaceGroup(Room room, List slots, bool group, float yOff, float scale) - { - int n = slots.Count; - for (int k = 0; k < n; k++) { - var q = room.SlotOcc[slots[k]]; + var q = room.SlotOcc[i]; if (q == null) continue; - float t = n == 1 ? 0.5f : (k + 0.5f) / n; - float sx = room.Col * Cell + t * (room.Span * Cell); + bool child = room.SlotTypes[i] == CType.Child; + bool fixedPos = room.SlotPos != null && room.SlotPos[i].HasValue; + Vector2 pos = fixedPos ? room.SlotPos[i].Value : AutoSlotPos(room, i); + Vector2 anchor = fixedPos ? FootAnchor : CenterAnchor; // фикс — по ногам (как в дебаге) if (q.Node.GetChildCount() > 0 && q.Node.GetChild(0) is Node2D sc) - sc.Position = -CenterAnchor * CharScale; - q.X = sx; - q.Node.Position = new Vector2(sx, room.Row * Cell + yOff); + sc.Position = -anchor * CharScale; + float scale = child ? 0.55f : 1f; + q.X = pos.X; + q.Node.Position = pos; q.Node.Scale = new Vector2(scale, scale); var anims = q.Ap != null ? q.Ap.GetAnimationList() : System.Array.Empty(); string a = PickAction(anims, group); if (q.Ap != null && a != null) q.Ap.Play(a); } + UpdateRoomHeader(room); + } + + private static Vector2 AutoSlotPos(Room room, int slot) + { + bool child = room.SlotTypes[slot] == CType.Child; + var grp = new List(); + for (int i = 0; i < room.Cap; i++) + if ((room.SlotTypes[i] == CType.Child) == child) grp.Add(i); + int idx = grp.IndexOf(slot), n = grp.Count; + float t = n == 1 ? 0.5f : (idx + 0.5f) / n; + float sx = room.Col * Cell + t * (room.Span * Cell); + float yOff = child ? Cell * 0.9f : Cell * 0.74f; + return new Vector2(sx, room.Row * Cell + yOff); } private static string StateScene(string name, string[] states)