using System; using System.Timers; using FairyGUI; using UnityEngine; using UnityEngine.AI; using UnityEngine.EventSystems; namespace ET { using FUIBuilding; [Timer(TimerType.UpdateBuildingProgressTimer)] public class UpdateBuildingProgressTimer : ATimer { public override void Run(ConstructViewComponent self) { try { if (self.IsDisposed || self.Parent == null) { return; } if (self.DomainScene() == null) { return; } self.UpdateProgress(); } catch (Exception e) { Log.Error(e.ToString()); } } } public class ConstructViewComponentAwakeSystem : AwakeSystem { public override void Awake(ConstructViewComponent self) { self.Awake(); } } public class ConstructViewComponentDestroySystem : DestroySystem { public override void Destroy(ConstructViewComponent self) { self.Destroy(); } } [FriendClass(typeof(Construct))] [FriendClass(typeof(ConstructViewComponent))] [FriendClass(typeof(MapComponent))] [FriendClass(typeof(OperationComponent))] public static class ConstructViewComponentSystem { public static void Awake(this ConstructViewComponent self) { var construct = self.GetParent(); self.CreateInProgressBuilding(construct); } public static void CreateInProgressBuilding(this ConstructViewComponent self, Construct construct) { self.Construct = construct; var synConfig = SynthesisConfigCategory.Instance.Get(construct.ConfigId); var buildingConfig = StructureConfigCategory.Instance.Get(synConfig.MixtureID); // 在地图中创建建筑实例 var mapComp = self.ZoneScene().CurrentScene().GetComponent(); GameObject building = self.InstantiateSync(buildingConfig.Prefab.ToPrefabAddress(), mapComp.BuildingRoot); building.transform.position = new Vector3(construct.X, construct.Y, 0); self.BuildingRoot = building; var baseTrans = self.BuildingRoot.transform.Find("Build_Base"); // 在建造的房子不阻止寻路 var modifier = baseTrans.GetComponent(); modifier.ignoreFromBuild = true; var sprRender = baseTrans.GetComponent(); self.CalcWorkingPoints(); // 要占住位置,但是要可以让人通过 Vector2Int size = mapComp.GetSizeBySpriteCollider(sprRender); mapComp.MarkPlaceOnGrid(self.BuildingRoot.transform.position, size); sprRender.enabled = false; #if CLIENTTEST var indicator = BuildingViewHelper.CreateOcupyPlaceInicator("OccupyPlaceInidcator", new Color(1, 0, 0, 0.3f)); indicator.transform.parent = self.BuildingRoot.transform; indicator.transform.localPosition = Vector3.zero; BuildingViewHelper.UpdateIndicatorLocal(indicator, mapComp, building.transform.position, size); #endif // 显示 进度条 var progressGO = self.BuildingRoot.transform.Find("Build_Base/BuildingProgress").gameObject; progressGO.SetActive(true); self.ProgressSR = progressGO.GetComponent(); var mat = self.ProgressSR.material; Vector4 rect = UnityEngine.Sprites.DataUtility.GetOuterUV(self.ProgressSR.sprite); mat.SetVector(self.UVRect, rect); EventTrigger trigger = self.BuildingRoot.transform.Find("Build_Base/SpriteClick").GetComponent(); EventTrigger.Entry entry = new EventTrigger.Entry(); entry.eventID = EventTriggerType.PointerClick; entry.callback.AddListener((data) => { self.OnSpriteClicked(); }); trigger.triggers.Add(entry); self.UpdateProgress(); // setup timer self.UpdateTimer = TimerComponent.Instance.NewRepeatedTimer(1000, TimerType.UpdateBuildingProgressTimer, self); } public static void CalcWorkingPoints(this ConstructViewComponent self) { var baseTrans = self.BuildingRoot.transform.Find("Build_Base"); // 暂时最多提供四个工作点 int maxWorkPos = 4; int interval = 1; float offset = (maxWorkPos - 1) * interval / 2; for (int i = 0; i < maxWorkPos; i++) { self.WorkingPoints.Add(baseTrans.position + new Vector3(- offset + i * interval, 0, 0)); } } public static void OnSpriteClicked(this ConstructViewComponent self) { if (Stage.isTouchOnUI) { return; } var operationComponent = self.ZoneScene().CurrentScene().GetComponent(); // 防止拖动后又响应点击事件 if (operationComponent.IsDragging) { return; } var prepareBuildingWindowComponent = FUIComponent.Instance.ShowWindow(); prepareBuildingWindowComponent.ShowInfo(self.Construct); } public static Vector3 GetWorkerPos(this ConstructViewComponent self, long peopleId) { if (self.WorkingPosDict.ContainsKey(peopleId)) { return self.WorkingPoints[self.WorkingPosDict[peopleId]]; } var count = self.WorkingPosDict.Keys.Count; self.WorkingPosDict.Add(peopleId, count); return self.WorkingPoints[count]; } public static void UpdateProgress(this ConstructViewComponent self) { var mat = self.ProgressSR.material; var synConfig = SynthesisConfigCategory.Instance.Get(self.Construct.ConfigId); float progress = (float)self.Construct.Progress / synConfig.BodyVolume; // Log.Info($"{self.Construct.Progress} | {synConfig.BodyVolume} | {progress}"); mat.SetFloat(self.FillAmount, progress); } public static void Destroy(this ConstructViewComponent self) { if (self.Parent == null) { return; } var mapComp = self.ZoneScene()?.CurrentScene()?.GetComponent(); if (mapComp == null) { return; } var baseTrans = self.BuildingRoot.transform.Find("Build_Base"); var sprRender = baseTrans.GetComponent(); mapComp.MarkPlaceOnGrid(self.BuildingRoot.transform.position, mapComp.GetSizeBySpriteCollider(sprRender), false); GameObject.Destroy(self.BuildingRoot); TimerComponent.Instance?.Remove(ref self.UpdateTimer); var zoneScene = self.ZoneScene(); if (zoneScene != null) { Unit unit = UnitHelper.GetMyUnitFromZoneScene(self.ZoneScene()); Game.EventSystem.Publish(new EventType.AfterRemoveConstruct(){Unit = unit, Construct = self.Construct}); } } } }