using CommonAI.RTS; using CommonLang.Vector; using CommonAI.RTS.Manhattan; using CommonAI.Zone.ZoneEditor; using System; using System.Collections.Generic; using System.Linq; using System.Text; using CommonLang; using CommonAI.Zone.Helper; namespace CommonAI.ZoneClient { public abstract class ZoneFlag : ZoneLayerObject { protected readonly SceneObjectData data; public string Name { get; private set; } public bool Enable { get; internal set; } public string Tag { get; internal set; } public SceneObjectData EditorData { get { return data; } } public ZoneFlag(SceneObjectData data, ZoneLayer parent) : base(parent) { this.data = data; this.Name = data.Name; this.mPos.SetX(data.X); this.mPos.SetY(data.Y); this.Enable = data.Enable; this.Tag = data.Tag; } public virtual void OnInit() { } } public class ZoneEditorUnit : ZoneFlag { public readonly UnitData Data; public ZoneEditorUnit(UnitData data, ZoneLayer parent) : base(data, parent) { this.Data = data; } } public class ZoneEditorItem : ZoneFlag { public readonly ItemData Data; public ZoneEditorItem(ItemData data, ZoneLayer parent) : base(data, parent) { this.Data = data; } } public class ZoneEditorRegion : ZoneFlag { public readonly RegionData Data; public ZoneEditorRegion(RegionData data, ZoneLayer parent) : base(data, parent) { this.Data = data; } } public class ZoneEditorPoint : ZoneFlag { public readonly PointData Data; public ZoneEditorPoint(PointData data, ZoneLayer parent) : base(data, parent) { this.Data = data; } } public class ZoneEditorDecoration : ZoneFlag { public readonly DecorationData Data; public readonly float W; public readonly float H; private readonly Rectangle BoundingBox; public ZoneEditorDecoration(DecorationData flag, ZoneLayer parent) : base(flag, parent) { this.Data = flag; this.W = flag.W; this.H = flag.H; switch (Data.RegionType) { case DecorationData.Shape.STRIP: TLine2 line = new TLine2(X, Y, X, Y); MathVector.movePolarExt(ref line.p, Data.StripDirection, -H / 2); MathVector.movePolarExt(ref line.q, Data.StripDirection, +H / 2); BoundingBox = new Rectangle( Math.Min(line.p.X, line.q.X), Math.Min(line.p.Y, line.q.Y), Math.Abs(line.p.X - line.q.X), Math.Abs(line.p.Y - line.q.Y)); break; case DecorationData.Shape.RECTANGLE: case DecorationData.Shape.ROUND: default: BoundingBox = new Rectangle(X - W / 2, Y - H / 2, W, H); break; } } public void DecorationChanged() { if (Data.Blockable) { if (Enable) { this.FillTerrain(fill_Terrain_value); } else { this.FillTerrain(fill_Terrain_reset); } } } public override void OnInit() { this.DecorationChanged(); } #region FillTerrain private void fill_Terrain_value(int bx, int by) { Parent.PathFinder.TryFillTerrain(bx, by, Data.BlockValue); } private void fill_Terrain_reset(int bx, int by) { Parent.PathFinder.TryFillTerrain(bx, by, Parent.TerrainSrc.TerrainMatrix[bx, by]); } protected void FillTerrain(AstarManhattan.ForEachTerrainAction fillAction) { if (!Parent.IsShareTerrain) { var mmap = Parent.PathFinder.MMap; switch (Data.RegionType) { case DecorationData.Shape.RECTANGLE: AstarManhattan.ForEachTerrainRect(mmap, X - W / 2, Y - H / 2, W, H, fillAction); break; case DecorationData.Shape.ROUND: AstarManhattan.ForEachTerrainEllipse(mmap, X - W / 2, Y - H / 2, W, H, fillAction); break; case DecorationData.Shape.STRIP: TLine2 line = new TLine2(X, Y, X, Y); MathVector.movePolarExt(ref line.p, Data.StripDirection, -H / 2); MathVector.movePolarExt(ref line.q, Data.StripDirection, +H / 2); AstarManhattan.ForEachTerrainStripWidth(mmap, line.p.X, line.p.Y, line.q.X, line.q.Y, W / 2, fillAction); break; } Parent.PathFinder.BeginFindPath(); } } public bool TouchBlock(float x, float y) { if (Data.Blockable && Enable && Parent.PathFinder.MMap.TestBlockValue(Data.BlockValue)) { int bx = (((int)x) / Parent.TerrainSrc.GridCellW); int by = (((int)y) / Parent.TerrainSrc.GridCellH); var mmap = Parent.PathFinder.MMap; switch (Data.RegionType) { case DecorationData.Shape.RECTANGLE: return AstarManhattan.ForEachTerrainRect(mmap, X - W / 2, Y - H / 2, W, H, (cx, cy) => { return cx == bx && cy == by; }); case DecorationData.Shape.ROUND: return AstarManhattan.ForEachTerrainEllipse(mmap, X - W / 2, Y - H / 2, W, H, (cx, cy) => { return cx == bx && cy == by; }); case DecorationData.Shape.STRIP: TLine2 line = new TLine2(X, Y, X, Y); MathVector.movePolarExt(ref line.p, Data.StripDirection, -H / 2); MathVector.movePolarExt(ref line.q, Data.StripDirection, +H / 2); return AstarManhattan.ForEachTerrainStripWidth(mmap, line.p.X, line.p.Y, line.q.X, line.q.Y, W / 2, (cx, cy) => { return cx == bx && cy == by; }); } } return false; } #endregion } public class ZoneEditorArea : ZoneFlag { public readonly AreaData Data; public readonly float W; public readonly float H; public int CurrentMapNodeValue { get; private set; } public ZoneEditorArea(AreaData data, ZoneLayer parent) : base(data, parent) { this.Data = data; this.W = data.W; this.H = data.H; } public override void OnInit() { var current_node = Parent.PathFinder.GetMapNodeByPos(X, Y); if (current_node != null) { this.CurrentMapNodeValue = current_node.Value; var list = Parent.TerrainAreaGenerator.GetContinuousMapNode(X, Y, W / 2, H / 2); foreach (var index in list) { var node = Parent.PathFinder.GetMapNode(index.BX, index.BY) as ZoneMapNode; if (node != null) { node.SetClientArea(this); } } } } } }