using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using CommonAI.Zone.ZoneEditor.Plugin.EditorToScene; using CommonAI.Zone.ZoneEditor.Plugin.SceneToEditor; using CommonAI.Zone; using CommonAI.Zone.ZoneEditor; using CommonAI.RTS; using CommonLang.Vector; using System.Collections; using CommonAI.Zone.Instance; using CommonLang; using GameEditorPlugin.Win32; using CommonFroms.Drawing; using CommonAI.RTS.Manhattan; using GameEditorPlugin.Tools; using CommonAI.Zone.Helper; namespace GameEditorPlugin.Win32.Editor { public class EditorWorld : DisplayTerrain { private EditorDisplayPanel owner; private HashMap objectes = new HashMap(); private ZoneManhattanMap mmap; private ManhattanMapAreaGenerator mmap_area_gen; public ZoneManhattanMap ManhattanMap { get { return mmap; } } public ManhattanMapAreaGenerator MapAreaGenerator { get { return mmap_area_gen; } } public EditorWorld(EditorDisplayPanel owner, ZoneInfo data) { this.owner = owner; this.mmap = new EditorZoneManhattanMap(data, null); this.mmap_area_gen = new ManhattanMapAreaGenerator(data); this.IsAreaDirty = true; base.InitTerrain(data); } public void ResetTerrain(ZoneInfo data) { this.mmap = new EditorZoneManhattanMap(data, null); this.mmap_area_gen = new ManhattanMapAreaGenerator(data); this.IsAreaDirty = true; base.InitTerrain(data); } public override void Dispose() { } //--------------------------------------------------- private HashSet fill_stack = new HashSet(); public delegate void TerrainMapBlockAction(ZoneInfo terrain, int bx, int by); public void ForEachTerrainRound(float wx, float wy, float size, TerrainMapBlockAction action) { int ix = (int)(wx / CellW); int iy = (int)(wy / CellH); float cw = CellW; float ch = CellH; float cx = cw / 2f; float cy = ch / 2f; float dr = (float)size * cw / 2f; float dw = (float)size * cw; float dh = (float)size * ch; float sx = ((int)((wx - dw / 2f) / CellW)) * cw; float sy = ((int)((wy - dh / 2f) / CellH)) * ch; for (float x = sx; x <= sx + dw; x += CellW) { for (float y = sy; y <= sy + dh; y += CellH) { if (CMath.includeRoundPoint(wx, wy, dr, x + cx, y + cy)) { ix = (int)(x / CellW); iy = (int)(y / CellH); if (ix >= 0 && ix < Terrain.XCount && iy >= 0 && iy < Terrain.YCount) { action(Terrain, ix, iy); } } } } } public void ForEachTerrainRectangle(float wx, float wy, float width, float height, TerrainMapBlockAction action) { int cx1 = (int)((wx - width / 2) / CellW); int cy1 = (int)((wy - height / 2) / CellH); int cx2 = (int)((wx + width / 2) / CellW); int cy2 = (int)((wy + height / 2) / CellH); cx1 = Math.Max(cx1, 0); cy1 = Math.Max(cy1, 0); cx2 = Math.Min(cx2, Terrain.XCount - 1); cy2 = Math.Min(cy2, Terrain.YCount - 1); for (int cx = cx1; cx <= cx2; ++cx) { for (int cy = cy1; cy <= cy2; ++cy) { action(Terrain, cx, cy); } } } public void FillTerrainRound(float wx, float wy, float size, int flag) { ForEachTerrainRound(wx, wy, size, (terrain, ix, iy) => { Terrain.TerrainMatrix[ix, iy] = flag; fill_stack.Add(new RspZoneFlagChanged(ix, iy, flag)); }); IsAreaDirty = true; } public void FillTerrainRectangle(float wx, float wy, float width, float height, int flag) { ForEachTerrainRectangle(wx, wy, width, height, (terrain, ix, iy) => { Terrain.TerrainMatrix[ix, iy] = flag; fill_stack.Add(new RspZoneFlagChanged(ix, iy, flag)); }); IsAreaDirty = true; } public List PopFillTerrainStack() { List ret = new List(fill_stack); fill_stack.Clear(); return ret; } //--------------------------------------------------- #region Events public void AddUnit(MsgPutUnit msg) { AddObject(new EditorUnit(this, msg)); } public void AddItem(MsgPutItem msg) { AddObject(new EditorItem(this, msg)); } public void AddRegion(MsgPutRegion msg) { AddObject(new EditorRegion(this, msg)); } public void AddPoint(MsgPutPoint msg) { AddObject(new EditorPoint(this, msg)); } public void AddDecoration(MsgPutDecoration msg) { AddObject(new EditorDecoration(this, msg)); } public void AddArea(MsgPutArea msg) { this.IsAreaDirty = true; AddObject(new EditorArea(this, msg)); } public void RenameObject(MsgRenameObject msg) { EditorObject obj = objectes.Get(msg.SrcName); if (obj != null) { obj.Name = msg.DstName; } } public void RemoveObject(MsgRemoveObject msg) { objectes.RemoveByKey(msg.Name); } public void SelectObject(MsgSelectObject msg) { EditorObject obj = objectes.Get(msg.Name); DeselectAll(obj); if (obj != null) { obj.Selected = true; if (msg.IsLocateCamera) { setCamera(obj.X, obj.Y); } } SelectedObject = obj; } public EditorObject SelectedObject { get; private set; } #endregion //--------------------------------------------------- #region Render internal bool IsAreaDirty { get; private set; } private SolidBrush name_brush = new SolidBrush(Color.White); private Font name_font = new Font(@"微软雅黑", 9f, FontStyle.Regular); protected override void renderObjects(Graphics g, RectangleF worldBounds) { drawObjectes(g, worldBounds, objectes.Values); if (owner.ShowGrid || owner.LastMode.Mode == MsgSetEditorMode.MODE_TERRAIN) { drawGrid(g, worldBounds, CellW, CellH); } } protected override void renderScreen(Graphics g, RectangleF worldBounds) { renderUnitsHP(g, worldBounds); } protected override void renderTerrain(Graphics g, RectangleF rect) { base.renderTerrain(g, rect); foreach (var so in objectes.Values) { so.render_in_terrain(g); } } private void renderUnitsHP(Graphics g, RectangleF rect) { bool showall = EditorDisplayPanel.ShowAll; foreach (EditorObject u in objectes.Values) { if (showall || u.Pickable) { if (CMath.intersectRect2( rect.X, rect.Y, rect.Width, rect.Height, u.X + u.LocalBounds.X, u.Y + u.LocalBounds.Y, u.LocalBounds.Width, u.LocalBounds.Height)) { System.Drawing.Drawing2D.GraphicsState state = g.Save(); g.TranslateTransform( worldToScreenX(u.X), worldToScreenY(u.Y)); g.DrawString(u.Name, name_font, name_brush, 0, 0); g.Restore(state); } } } } public override void render(Graphics g) { base.render(g); this.IsAreaDirty = false; } #endregion //--------------------------------------------------- public EditorObject GetObject(string name) { return objectes.Get(name); } private void AddObject(EditorObject obj) { var removed = objectes.RemoveByKey(obj.Name); objectes.Add(obj.Name, obj); if (SelectedObject == removed) { SelectedObject = obj; obj.Selected = true; } } public void DeselectAll(EditorObject exclude = null) { SelectedObject = null; foreach (EditorObject obj in objectes.Values) { if (exclude != obj) { if (obj.Selected) { obj.Selected = false; RspOnObjectSelected rsp = new RspOnObjectSelected(); rsp.Name = obj.Name; rsp.Selected = false; owner.SendToEditor(rsp); } } } } public void Deselect(EditorObject obj) { if (SelectedObject == obj) { SelectedObject = null; } if (obj.Selected) { obj.Selected = false; RspOnObjectSelected rsp = new RspOnObjectSelected(); rsp.Name = obj.Name; rsp.Selected = false; owner.SendToEditor(rsp); } } public EditorObject TryPickObject(float x, float y) { bool showall = EditorDisplayPanel.ShowAll; foreach (EditorObject u in objectes.Values) { if (showall || u.Pickable) { if (u.touch(x, y)) { return u; } } } return null; } public EditorObject PickObject(float x, float y) { bool showall = EditorDisplayPanel.ShowAll; foreach (EditorObject u in objectes.Values) { if (showall || u.Pickable) { if (u.touch(x, y)) { u.Selected = true; RspOnObjectSelected rsp = new RspOnObjectSelected(); rsp.Name = u.Name; rsp.Selected = true; owner.SendToEditor(rsp); return u; } } } DeselectAll(); return null; } public EditorObject PickObject(string name) { var u = GetObject(name); if (u != null && u.Pickable) { u.Selected = true; RspOnObjectSelected rsp = new RspOnObjectSelected(); rsp.Name = u.Name; rsp.Selected = true; owner.SendToEditor(rsp); return u; } DeselectAll(); return null; } } }