You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
7.6 KiB

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<ConstructViewComponent>
{
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<ConstructViewComponent>
{
public override void Awake(ConstructViewComponent self)
{
self.Awake();
}
}
public class ConstructViewComponentDestroySystem : DestroySystem<ConstructViewComponent>
{
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<Construct>();
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<MapComponent>();
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<NavMeshModifier>();
modifier.ignoreFromBuild = true;
var sprRender = baseTrans.GetComponent<SpriteRenderer>();
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<SpriteRenderer>();
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>();
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<OperationComponent>();
// 防止拖动后又响应点击事件
if (operationComponent.IsDragging)
{
return;
}
var prepareBuildingWindowComponent = FUIComponent.Instance.ShowWindow<FUI_PrepareBuildingWindow,FUIPrepareBuildingWindowComponent>();
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<MapComponent>();
if (mapComp == null)
{
return;
}
var baseTrans = self.BuildingRoot.transform.Find("Build_Base");
var sprRender = baseTrans.GetComponent<SpriteRenderer>();
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});
}
}
}
}