private void DrawObjects(Graphics g, List <Map.Object> objects, bool shadow = false) { Pen pen; PointF center, ptf, topLeft; ThingDb.Thing tt; Map.Object underCursor = null; if (MapInterface.CurrentMode == EditMode.OBJECT_SELECT || MainWindow.Instance.mapView.picking) { underCursor = MainWindow.Instance.mapView.GetObjectUnderCursor(); } if (mapRenderer.proDefault && underCursor == null) { MainWindow.Instance.mapView.mapPanel.Cursor = Cursors.Default; } bool drawExtents3D = EditorSettings.Default.Draw_Extents_3D; if (EditorSettings.Default.Draw_Objects) { foreach (Map.Object oe in objects) { var customRender = oe as CustomRenderObject; if (customRender != null) { customRender.Render(g); continue; } ptf = oe.Location; float x = ptf.X, y = ptf.Y; tt = ThingDb.Things[oe.Name]; center = new PointF(x, y); topLeft = new PointF(center.X - objectSelectionRadius, center.Y - objectSelectionRadius); pen = mapRenderer.ColorLayout.Objects; // Object facing helper if (EditorSettings.Default.Draw_ObjectFacing) { float deg = -1F; if (tt.Xfer == "MonsterXfer") { MonsterXfer xfer = oe.GetExtraData <MonsterXfer>(); deg = (float)MonsterXfer.NOX_DIRECT_VALS[xfer.DirectionId] / 256F * 360F; } if (tt.Xfer == "NPCXfer") { NPCXfer xfer = oe.GetExtraData <NPCXfer>(); deg = (float)MonsterXfer.NOX_DIRECT_VALS[xfer.DirectionId] / 256F * 360F; } if (deg >= 0F) { using (var m = new System.Drawing.Drawing2D.Matrix()) { m.RotateAt(deg, center); g.Transform = m; g.DrawLine(objMoveablePen, center.X, center.Y, center.X + 20, center.Y); g.ResetTransform(); } } // Sentry ray if (tt.Xfer == "SentryXfer") { SentryXfer sentry = oe.GetExtraData <SentryXfer>(); float targX = x + ((float)Math.Cos(sentry.BasePosRadian) * 80F); float targY = y + ((float)Math.Sin(sentry.BasePosRadian) * 80F); // show sentry ray direction g.DrawLine(sentryPen, x, y, targX, targY); } } // invisible triggers and pressure plates if (tt.DrawType == "TriggerDraw" || tt.DrawType == "PressurePlateDraw") { if (shadow) { DrawObjectExtent(g, oe, drawExtents3D); } //else // DrawTriggerExtent(g, oe, underCursor); continue; } // black powder if (EditorSettings.Default.Edit_PreviewMode) // Visual Preview { if (tt.DrawType == "BlackPowderDraw") { /* Rectangle bp = new Rectangle((int)x - 2, (int)y - 2, 4, 4); * g.FillRectangle(new SolidBrush(Color.Gray), bp);*/ continue; } if (tt.Xfer == "InvisibleLightXfer") { /*bool isUnderCursor = false; * * Pen Penlight = new Pen(Color.Yellow, 1); * if (underCursor != null) isUnderCursor = underCursor.Equals(oe); * * if (isUnderCursor) * Penlight = new Pen(Color.Orange, 1); * * bool isSelected = mapRenderer.SelectedObjects.Items.Contains(oe); * bool isSelected2 = MapInterface.RecSelected.Contains(oe); * if (isSelected && isSelected2 && MapInterface.KeyHelper.ShiftKey) * { * isSelected = false; * isSelected2 = false; * } * * * if (isSelected || isSelected2) * { * Penlight = Pens.DarkOrange; * if (mapRenderer.proHand && isUnderCursor) * MainWindow.Instance.mapView.mapPanel.Cursor = Cursors.Hand; * * } * * g.DrawEllipse(Penlight, new RectangleF(center.X - 9, center.Y - 9, 18, 18)); * g.DrawEllipse(Penlight, new RectangleF(center.X - 13, center.Y - 13, 26, 26)); * g.DrawEllipse(Penlight, new RectangleF(center.X - 17, center.Y - 17, 34, 34)); */ continue; } Bitmap image = GetObjectImage(oe, shadow); /*if (tt.Name.StartsWith("Amb") && image == null) * { * image = mapRenderer.VideoBag.GetBitmap(tt.SpriteMenuIcon); * drawOffsetX = 82; * drawOffsetY = 122; * }*/ if (image == null || tt.DrawType == "NoDraw") { // in case of failure draw only the extent //DrawObjectExtent(g, oe, drawExtents3D); } else { int sizeX = tt.SizeX / 2; int sizeY = tt.SizeY / 2; x -= (sizeX - drawOffsetX); y -= (sizeY - drawOffsetY) + tt.Z; // no blurring int ix = Convert.ToInt32(x); int iy = Convert.ToInt32(y); // recolor in case it is being selected bool isSelected = mapRenderer.SelectedObjects.Items.Contains(oe); bool isSelected2 = MapInterface.RecSelected.Contains(oe); if (isSelected && isSelected2 && MapInterface.KeyHelper.ShiftKey) { isSelected = false; isSelected2 = false; } bool isUnderCursor = false; if (underCursor != null) { isUnderCursor = underCursor.Equals(oe); } // draw the image if (isSelected || isUnderCursor || shadow || isSelected2) { // highlight selection var shader = new BitmapShader(image); shader.LockBitmap(); var hltColor = mapRenderer.ColorLayout.Selection; if (isSelected || isSelected2) { if (mapRenderer.proHand && isUnderCursor) { MainWindow.Instance.mapView.mapPanel.Cursor = Cursors.Hand; } shader.ColorShade(hltColor, 0.5F); } else if (isUnderCursor) { hltColor = Color.PaleGreen; if (MapInterface.CurrentMode == EditMode.OBJECT_PLACE && !MainWindow.Instance.mapView.picking) { hltColor = mapRenderer.ColorLayout.Removing; } shader.ColorGradWaves(hltColor, 7F, Environment.TickCount); } if (shadow) { shader.MakeSemitransparent(165); } image = shader.UnlockBitmap(); g.DrawImage(image, ix, iy, image.Width, image.Height); image.Dispose(); } else { g.DrawImage(image, ix, iy, image.Width, image.Height); } } } else { if (mapRenderer.SelectedObjects.Items.Contains(oe)) { pen = Pens.Green; } if (MapInterface.RecSelected.Contains(oe)) { pen = Pens.Green; } if ((mapRenderer.SelectedObjects.Items.Contains(oe) && MapInterface.RecSelected.Contains(oe))) { pen = mapRenderer.ColorLayout.Objects; } g.DrawEllipse(pen, new RectangleF(topLeft, new Size(2 * objectSelectionRadius, 2 * objectSelectionRadius)));//55 // If is a door if ((tt.Class & ThingDb.Thing.ClassFlags.DOOR) == ThingDb.Thing.ClassFlags.DOOR) { DoorXfer door = oe.GetExtraData <DoorXfer>(); if (door.Direction == DoorXfer.DOORS_DIR.South) { g.DrawLine(doorPen, new Point((int)center.X, (int)center.Y), new Point((int)center.X - 20, (int)center.Y - 20)); if (drawExtents3D) { g.DrawLine(doorPen, new Point((int)center.X, (int)center.Y - 40), new Point((int)center.X - 20, (int)center.Y - 60)); g.DrawLine(doorPen, new Point((int)center.X, (int)center.Y), new Point((int)center.X - 20, (int)center.Y - 60)); g.DrawLine(doorPen, new Point((int)center.X - 20, (int)center.Y - 20), new Point((int)center.X - 20, (int)center.Y - 60)); } } else if (door.Direction == DoorXfer.DOORS_DIR.West) { g.DrawLine(doorPen, new Point((int)center.X, (int)center.Y), new Point((int)center.X + 20, (int)center.Y - 20)); if (drawExtents3D) { g.DrawLine(doorPen, new Point((int)center.X, (int)center.Y - 40), new Point((int)center.X + 20, (int)center.Y - 60)); g.DrawLine(doorPen, new Point((int)center.X, (int)center.Y), new Point((int)center.X + 20, (int)center.Y - 60)); g.DrawLine(doorPen, new Point((int)center.X + 20, (int)center.Y - 20), new Point((int)center.X + 20, (int)center.Y - 60)); } } else if (door.Direction == DoorXfer.DOORS_DIR.North) { g.DrawLine(doorPen, new Point((int)center.X, (int)center.Y), new Point((int)center.X + 20, (int)center.Y + 20)); if (drawExtents3D) { g.DrawLine(doorPen, new Point((int)center.X, (int)center.Y - 40), new Point((int)center.X + 20, (int)center.Y - 20)); g.DrawLine(doorPen, new Point((int)center.X, (int)center.Y), new Point((int)center.X + 20, (int)center.Y - 20)); g.DrawLine(doorPen, new Point((int)center.X + 20, (int)center.Y + 20), new Point((int)center.X + 20, (int)center.Y - 20)); } } else if (door.Direction == DoorXfer.DOORS_DIR.East) { g.DrawLine(doorPen, new Point((int)center.X, (int)center.Y), new Point((int)center.X - 20, (int)center.Y + 20)); if (drawExtents3D) { g.DrawLine(doorPen, new Point((int)center.X, (int)center.Y - 40), new Point((int)center.X - 20, (int)center.Y - 20)); g.DrawLine(doorPen, new Point((int)center.X, (int)center.Y), new Point((int)center.X - 20, (int)center.Y - 20)); g.DrawLine(doorPen, new Point((int)center.X - 20, (int)center.Y + 20), new Point((int)center.X - 20, (int)center.Y - 20)); } } } } if (EditorSettings.Default.Draw_Extents) { if (!(!EditorSettings.Default.Draw_AllExtents && oe.HasFlag(ThingDb.Thing.FlagsFlags.NO_COLLIDE))) { DrawObjectExtent(g, oe, drawExtents3D); } } } // Draw labels on the separate cycle to prevent layer glitching if (EditorSettings.Default.Draw_AllText) { foreach (Map.Object oe in objects) { Point textLocaton = new Point(Convert.ToInt32(oe.Location.X), Convert.ToInt32(oe.Location.Y)); textLocaton.X -= objectSelectionRadius; textLocaton.Y -= objectSelectionRadius; if (EditorSettings.Default.Draw_ObjCustomLabels && oe.Team > 0) { // Draw team Point loc = new Point(textLocaton.X, textLocaton.Y - 12); TextRenderer.DrawText(g, String.Format(FORMAT_OBJECT_TEAM, oe.Team), objectExtentFont, loc, Color.LightPink); } if (EditorSettings.Default.Draw_ObjCustomLabels && oe.Scr_Name.Length > 0) { // Draw custom label Size size = TextRenderer.MeasureText(oe.ScrNameShort, objectExtentFont); textLocaton.X -= size.Width / 3; TextRenderer.DrawText(g, oe.ScrNameShort, objectExtentFont, textLocaton, Color.Cyan); } else if (EditorSettings.Default.Draw_ObjThingNames) { // Draw thing name Size size = TextRenderer.MeasureText(oe.Name, objectExtentFont); textLocaton.X -= size.Width / 3; TextRenderer.DrawText(g, oe.Name, objectExtentFont, textLocaton, Color.Green); } else if (!EditorSettings.Default.Edit_PreviewMode && oe.Extent >= 0 && !(EditorSettings.Default.Draw_Extents || EditorSettings.Default.Draw_AllExtents)) { TextRenderer.DrawText(g, oe.Extent.ToString(), objectExtentFont, textLocaton, Color.Purple); } } } } }
/// <summary> /// Wall texture rendering routine /// </summary> public void DrawTexturedWall(Graphics g, Map.Wall wall, bool transparent, bool beingSelected) { ThingDb.Wall tt = ThingDb.Walls[wall.matId]; try { int actualVari = wall.Variation * 2; // для обычных стен все данные берутся отсюда ThingDb.Wall.WallRenderInfo wri = tt.RenderNormal[(int)wall.Facing][actualVari]; // если стену можно сломать if (wall.Destructable) { wri = tt.RenderBreakable[(int)wall.Facing][actualVari]; } // если стена содержит окошко if (wall.Window) { switch (wall.Facing) { case WallFacing.NORTH: wri = tt.RenderNormal[11][actualVari]; break; case WallFacing.WEST: wri = tt.RenderNormal[12][actualVari]; break; } } // достаем картинку Bitmap bitmap = VideoBag.GetBitmap(wri.SpriteIndex); BitmapShader shader = null; // тонируем если стена необычная if ((EditorSettings.Default.Draw_ColorWalls || (MapInterface.CurrentMode == EditMode.WALL_CHANGE)) && (!MainWindow.Instance.imgMode)) { if (wall.Destructable || wall.Secret || wall.Window || transparent || beingSelected || mapView.picking) { shader = new BitmapShader(bitmap); shader.LockBitmap(); if (wall.Destructable) { shader.ColorShade(ColorLayout.WallsBreakable, 0.30F); } if (wall.Secret) { shader.ColorShade(ColorLayout.WallsSecret, 0.40F); } if (wall.Window) { shader.ColorShade(ColorLayout.WallsWindowed, 0.30F); } if (wall.Secret_WallState == 4) { shader.MakeSemitransparent(135); } if (beingSelected) { Color selCol = Color.GhostWhite; if (MapInterface.CurrentMode == EditMode.WALL_PLACE && !mapView.picking) { selCol = ColorLayout.Removing; } if (MapInterface.CurrentMode == EditMode.WALL_CHANGE && !mapView.picking) { selCol = Color.Purple; } shader.ColorGradWaves(selCol, 4F, Environment.TickCount); } if (transparent) { shader.MakeSemitransparent(); } bitmap = shader.UnlockBitmap(); } } // допускается что стена одновременно и секретная, и разрушаемая, и с окном int x, y; if (bitmap != null) { x = 23 * wall.Location.X; y = 23 * wall.Location.Y; // коррекция координат int offX = (0 - wri.unknown1) - videoBagProvider.DrawOffsets[wri.SpriteIndex][0]; int offY = wri.unknown2 - videoBagProvider.DrawOffsets[wri.SpriteIndex][1]; x -= offX + 50; y -= offY + 72; // собственно рисуем g.DrawImage(bitmap, x, y, bitmap.Width, bitmap.Height); // сразу чистим память если картинка не кэшируется if (shader != null) { bitmap.Dispose(); } } } catch (Exception) { } }