From 56b66af0c391b3fd8abd5ecae80c9b052f58004c Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 5 Nov 2026 16:22:23 +0100 Subject: [PATCH] =?UTF-8?q?=D0=98=D0=BD=D1=82=D0=B5=D0=B3=D1=80=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=203D:=20=D1=81=D0=BE=D1=85=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2=20=D0=BF=D0=B5=D1=80=D0=B2?= =?UTF-8?q?=D0=BE=D0=BC=20=D0=BA=D0=B0=D0=B4=D1=80=D0=B5=20=D0=BD=D0=B5=20?= =?UTF-8?q?=D0=B7=D0=B0=D1=82=D0=B8=D1=80=D0=B0=D0=B5=D1=82=203D-=D0=B3?= =?UTF-8?q?=D0=BE=D1=80=D0=BE=D0=B4;=20=D0=A0=D0=B0=D1=82=D1=83=D1=88?= =?UTF-8?q?=D0=B0=20=D0=BD=D0=B0=20=D0=BA=D0=B0=D1=80=D1=82=D0=B5=20=D0=BC?= =?UTF-8?q?=D0=B8=D1=80=D0=B0=20--=20=D0=B8=D0=B7=20=D0=BF=D0=BE=D1=81?= =?UTF-8?q?=D0=BB=D0=B5=D0=B4=D0=BD=D0=B5=D0=B3=D0=BE=20=D0=BE=D1=82=D0=BA?= =?UTF-8?q?=D1=80=D1=8B=D1=82=D0=BE=D0=B3=D0=BE=20=D0=B3=D0=BE=D1=80=D0=BE?= =?UTF-8?q?=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CaptureState до ApplySaved отдаёт загруженное состояние (поход, вернувшийся офлайн, сохранял пустой город). ISettlement.TownHallLevel вне города -- уровень Ратуши последнего открытого города (2D или 3D). Co-Authored-By: Claude Opus 5.5 --- Assets/Scripts/City3D/City3DController.cs | 3 +++ .../Modules/Settlement/SettlementModule.cs | 15 +++++++++++++-- Docs/Modules/Settlement.md | 1 + 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Assets/Scripts/City3D/City3DController.cs b/Assets/Scripts/City3D/City3DController.cs index 3ba2a3e..b4e480a 100644 --- a/Assets/Scripts/City3D/City3DController.cs +++ b/Assets/Scripts/City3D/City3DController.cs @@ -135,6 +135,9 @@ public class City3DController : MonoBehaviour, City3DSave.ILive public City3DSave.Data CaptureState() { + // Сохранённый город ещё не поставлен (сохранение в первом кадре -- например, поход вернулся офлайн): + // отдаём то, что было загружено, иначе пустая сцена затёрла бы весь 3D-город + if (!stateApplied || map == null) return City3DSave.Cached; var d = new City3DSave.Data { nextId = nextBuildingId }; foreach (var b in map.Buildings) { diff --git a/Assets/Scripts/Modules/Settlement/SettlementModule.cs b/Assets/Scripts/Modules/Settlement/SettlementModule.cs index a56f146..655f8ba 100644 --- a/Assets/Scripts/Modules/Settlement/SettlementModule.cs +++ b/Assets/Scripts/Modules/Settlement/SettlementModule.cs @@ -44,11 +44,13 @@ public static class SettlementModule { cached = null; appliedToBuildManager = null; + lastTownHallLevel = 0; GameServices.Register(service); SaveRegistry.Register(service); } static bool CityLoaded => BuildManager.Instance != null; + static int lastTownHallLevel; // уровень Ратуши последнего открытого города (0 -- ещё не открывали) // ---------------- Сцена города <-> данные ---------------- @@ -185,8 +187,16 @@ public static class SettlementModule class Service : ISettlement, ISaveParticipant { - public int TownHallLevel => - TownHall.Instance != null ? TownHall.Instance.currentLevel : (cached?.townHallLevel ?? 1); + // Ратуша открытого города -- 2D или 3D. Вне города (карта мира) -- последнего открытого: в 3D-поселении + // уровень Ратуши свой (секция settlement3d), и 2D-сохранение показывало бы на карте чужой уровень (05.11) + public int TownHallLevel + { + get + { + if (TownHall.Instance != null) lastTownHallLevel = TownHall.Instance.currentLevel; + return lastTownHallLevel > 0 ? lastTownHallLevel : (cached?.townHallLevel ?? 1); + } + } public int BuildingCount => CityLoaded @@ -208,6 +218,7 @@ public static class SettlementModule public void ResetState() { cached = new SettlementSaveData(); + lastTownHallLevel = 0; if (!CityLoaded) return; ClearPlacedBuildings(); diff --git a/Docs/Modules/Settlement.md b/Docs/Modules/Settlement.md index 001e8ce..d502fcb 100644 --- a/Docs/Modules/Settlement.md +++ b/Docs/Modules/Settlement.md @@ -119,6 +119,7 @@ | Дата | Кто | Что | | --- | --- | --- | +| 05.11.2026 | Claude (Саша) | Интеграция 3D: (1) снимок 3D-города для сохранения до расстановки сохранённых зданий отдаёт загруженное состояние — сохранение в первом кадре (поход вернулся офлайн) больше не затирает 3D-город пустым; (2) `ISettlement.TownHallLevel` вне города — уровень Ратуши последнего открытого города (2D или 3D), а не всегда 2D-сохранения: на карте мира предел жилья, резерв и открытие войск считаются по 3D-Ратуше. | | 04.11.2026 | Claude | Решения 04.11: снос убран, остался бесплатный перенос; офлайн по временным меткам — стройка, закончившаяся офлайн, вступает в силу в момент завершения внутри расчёта добычи (`ConstructionClock`, `GameTimeSimulatedEvent`, `BuildTimer.MayComplete`); проверки таймеров из сохранения; уровень при завершении только растёт. | | 01.11.2026 | Claude | Стройка и улучшение по времени (`BuildTimer`), 2 строителя, ускорение за кристаллы, офлайн; лимит зданий по уровню Ратуши; перенос и снос зданий из окна. Сохранение: поля таймера у зданий и Ратуши (старые сохранения читаются). Терем богатыря (`HeroCastle`) и гуляющий герой. Числа — ТЕСТ, `EconomyConfig`. | | 04.11.2026 | Claude (Саша) | 3D-поселение, этап I (ТЗ от 04.11): правила места `Bogatyri.Settlement.Placement` + тесты, сцена City3D на примитивах (местность, зоны, призрак, поворот, перенос, расчистка, камера), 3D-рендерер для её камеры. Ветка `feature/3d-settlement`. |