public void DoSnap() { // Get candidates var candidates = FindSnappableTiles(UserSettings.SnapDistance); if (candidates.Count == 0) { return; } // Get closest candidate int best = 0; for (int i = 1; i < candidates.Count; i++) { if (candidates[i].Item1 < candidates[best].Item1) { best = i; } } // Move all selected items to snap int mag = baseInfo.mag; TileInstance closestTile = candidates[best].Item2; MapTileDesignPotential closestInfo = candidates[best].Item3; SnapMoveAllMouseBoundItems(new XNA.Point(closestTile.X - closestInfo.x * mag, closestTile.Y - closestInfo.y * mag)); }
public List <Tuple <double, TileInstance, MapTileDesignPotential> > FindSnappableTiles(float threshold, Predicate <TileInstance> pred = null) { List <Tuple <double, TileInstance, MapTileDesignPotential> > result = new List <Tuple <double, TileInstance, MapTileDesignPotential> >(); MapTileDesign tilegroup = (MapTileDesign)TileSnap.tileCats[baseInfo.u]; int mag = baseInfo.mag; float first_threshold = MultiBoard.FirstSnapVerification * mag; foreach (BoardItem item in Board.BoardItems.Items) { if (item is TileInstance) { // Trying to snap to other selected items can mess up some of the mouse bindings if (item.Selected || item.Equals(this)) { continue; } TileInstance tile = (TileInstance)item; if (tile.LayerNumber != this.LayerNumber) { continue; } int dx = tile.X - this.X, dy = tile.Y - this.Y; // first verification to save time // Note that we are first checking dx and dy alone; although this is already covered by the following distance calculation, // it is significantly faster and will likely weed out most of the candidates before calculating their actual distance. if (dx > first_threshold || dy > first_threshold || InputHandler.Distance(dx, dy) > first_threshold) { continue; } if (pred != null && !pred.Invoke(tile)) { continue; } foreach (MapTileDesignPotential snapInfo in tilegroup.potentials) { if (snapInfo.type != tile.baseInfo.u) { continue; } double distance = InputHandler.Distance(this.X - tile.X + snapInfo.x * mag, this.Y - tile.Y + snapInfo.y * mag); if (distance > threshold) { continue; } result.Add(new Tuple <double, TileInstance, MapTileDesignPotential>(distance, tile, snapInfo)); } } } return(result); }
public void ParseOffsets(TileInstance instance, Board board, int x, int y) { List<FootholdAnchor> anchors = new List<FootholdAnchor>(); foreach (XNA.Point foothold in footholdOffsets) { FootholdAnchor anchor = new FootholdAnchor(board, x + foothold.X, y + foothold.Y, instance.LayerNumber, instance.PlatformNumber, true); anchors.Add(anchor); board.BoardItems.FHAnchors.Add(anchor); instance.BindItem(anchor, foothold); } for (int i = 0; i < anchors.Count - 1; i++) { FootholdLine fh = new FootholdLine(board, anchors[i], anchors[i + 1]); board.BoardItems.FootholdLines.Add(fh); } }
public BoardItem CreateInstance(Layer layer, Board board, int x, int y, int z, int zM, bool flip, bool parseOffsets) { TileInstance instance = new TileInstance(this, layer, board, x, y, z, zM); if (parseOffsets) ParseOffsets(instance, board, x, y); return instance; }
public override BoardItem CreateInstance(Layer layer, Board board, int x, int y, int z, bool flip) { TileInstance instance = new TileInstance(this, layer, board, x, y, z, layer.zMDefault); ParseOffsets(instance, board, x, y); return instance; }