diff --git a/d2core/d2map/d2mapengine/engine.go b/d2core/d2map/d2mapengine/engine.go index 135d40c1..d946c400 100644 --- a/d2core/d2map/d2mapengine/engine.go +++ b/d2core/d2map/d2mapengine/engine.go @@ -137,18 +137,31 @@ func (m *MapEngine) Tiles() *[]d2ds1.TileRecord { return &m.tiles } -// Places a stamp at the specified location. Also adds any entities from the stamp to the map engine +// Places a stamp at the specified location. +// Also adds any entities from the stamp to the map engine func (m *MapEngine) PlaceStamp(stamp *d2mapstamp.Stamp, tileOffsetX, tileOffsetY int) { stampSize := stamp.Size() - if (tileOffsetX < 0) || (tileOffsetY < 0) || ((tileOffsetX + stampSize.Width) > m.size.Width) || ((tileOffsetY + stampSize.Height) > m.size.Height) { + stampW := stampSize.Width + stampH := stampSize.Height + + mapW := m.size.Width + mapH := m.size.Height + + xMin := tileOffsetX + yMin := tileOffsetY + xMax := xMin + stampSize.Width + yMax := yMin + stampSize.Height + + if (xMin < 0) || (yMin < 0) || (xMax > mapW) || (yMax > mapH) { panic("Tried placing a stamp outside the bounds of the map") } // Copy over the map tile data - for y := 0; y < stampSize.Height; y++ { - for x := 0; x < stampSize.Width; x++ { - mapTileIdx := x + tileOffsetX + ((y + tileOffsetY) * m.size.Width) - m.tiles[mapTileIdx] = *stamp.Tile(x, y) + for y := 0; y < stampH; y++ { + for x := 0; x < stampW; x++ { + targetTileIndex := m.tileCoordinateToIndex((x + xMin), (y + yMin)) + stampTile := *stamp.Tile(x, y) + m.tiles[targetTileIndex] = stampTile } } @@ -156,9 +169,19 @@ func (m *MapEngine) PlaceStamp(stamp *d2mapstamp.Stamp, tileOffsetX, tileOffsetY m.entities = append(m.entities, stamp.Entities(tileOffsetX, tileOffsetY)...) } -// Returns a reference to a map tile based on the specified tile X and Y coordinate +// converts x,y tile coordinate into index in MapEngine.tiles +func (m *MapEngine) tileCoordinateToIndex(x, y int) int { + return x + (y * m.size.Height) +} + +// converts tile index from MapEngine.tiles to x,y coordinate +func (m *MapEngine) tileIndexToCoordinate(index int) (int, int) { + return (index % m.size.Width), (index / m.size.Width) +} + +// Returns a reference to a map tile based on the tile X,Y coordinate func (m *MapEngine) TileAt(tileX, tileY int) *d2ds1.TileRecord { - idx := tileX + (tileY * m.size.Width) + idx := m.tileCoordinateToIndex(tileX, tileY) if idx < 0 || idx >= len(m.tiles) { return nil } @@ -231,12 +254,18 @@ func (m *MapEngine) Advance(tickTime float64) { } } +// Checks if a tile exists func (m *MapEngine) TileExists(tileX, tileY int) bool { - if tileX < 0 || tileX >= m.size.Width || tileY < 0 || tileY >= m.size.Height { - return false + tileIndex := m.tileCoordinateToIndex(tileX, tileY) + if valid := (tileIndex >= 0) && (tileIndex <= len(m.tiles)); valid { + tile := m.tiles[tileIndex] + numFeatures := len(tile.Floors) + numFeatures += len(tile.Shadows) + numFeatures += len(tile.Walls) + numFeatures += len(tile.Substitutions) + return numFeatures > 0 } - tile := m.tiles[tileX+(tileY*m.size.Width)] - return len(tile.Floors) > 0 || len(tile.Shadows) > 0 || len(tile.Walls) > 0 || len(tile.Substitutions) > 0 + return false } func (m *MapEngine) GenerateMap(regionType d2enum.RegionIdType, levelPreset int, fileIndex int, cacheTiles bool) {