func (l *Lighting) Image(x, y int) *image.Alpha { if l.lightmapVersion != layout.Version() || l.lightmap == nil { l.lightmapVersion = layout.Version() l.lightmap = make(map[layout.Coord]uint8) l.recalculateLightmap() l.cachedInvalid = true } if !l.cachedInvalid && l.cachedImage != nil && l.cachedX == x>>lightShift && l.cachedY == y>>lightShift { return l.cachedImage } if l.cachedImage == nil { l.cachedImage = image.NewAlpha(image.Rect(0, 0, 2<<lightShift<<res.TileSize, 2<<lightShift<<res.TileSize)) } l.cachedInvalid = false l.cachedX, l.cachedY = x>>lightShift, y>>lightShift l.initializeImage() return l.cachedImage }
func Paint(w wde.Window, rect image.Rectangle) { xOffset, yOffset := GetTopLeft() center := layout.Coord{ViewportWidth/2 - xOffset, ViewportHeight/2 - yOffset} if center != oldCenter || layout.Version() != oldVersion { oldCenter = center oldVersion = layout.Version() for x := 0; x <= ViewportWidth; x++ { for y := 0; y <= ViewportHeight; y++ { if layout.Visible(center, layout.Coord{x - xOffset, y - yOffset}) { res.Tile(terrain, res.Terrain, uint16(layout.GetSpace(x-xOffset, y-yOffset)), x, y) draw.Draw(terrain, image.Rect(x<<res.TileSize, y<<res.TileSize, (x+1)<<res.TileSize, (y+1)<<res.TileSize), image.Transparent, image.ZP, draw.Src) for _, t := range layout.Get(x-xOffset, y-yOffset) { if !t.NoClient() { res.Tile(terrain, res.Terrain, uint16(t), x, y) } } } else { res.Tile(terrain, image.Black, 0, x, y) } } } switch GetPlayerFlags() & packet.FlagSpriteMask { case packet.FlagEngineer: for x := 0; x <= ViewportWidth; x++ { for y := 0; y <= ViewportHeight; y++ { dx, dy := x-ViewportWidth/2, y-ViewportHeight/2 dist := dx*dx + dy*dy if dist <= 3*3 && layout.Visible(center, layout.Coord{x - xOffset, y - yOffset}) { for _, t := range layout.Get(x-xOffset, y-yOffset) { if t >= layout.WireW && t <= layout.WireS { res.Tile(terrain, res.Terrain, uint16(t), x, y) } } } } } } } minX, maxX := rect.Min.X>>res.TileSize, (rect.Max.X-1)>>res.TileSize+1 minY, maxY := rect.Min.Y>>res.TileSize, (rect.Max.Y-1)>>res.TileSize+1 draw.Draw(sprites, sprites.Bounds(), image.Transparent, image.ZP, draw.Src) var pixOffset image.Point var hasAnimation image.Rectangle paintLock.Lock() for _, p := range paintContexts { if layout.Visible(center, p.To) { x1, y1 := p.From.X+xOffset, p.From.Y+yOffset x2, y2 := p.To.X+xOffset, p.To.Y+yOffset if minX <= x2 && x2 <= maxX && minY <= y2 && y2 <= maxY { interp := float32(time.Since(p.Changed)*5) / float32(time.Second) if interp >= 1 { res.Tile(sprites, res.Actors, p.Sprite, x2, y2) } else { toInvalidate := image.Rect(x1, y1, x1+1, y1+1).Union(image.Rect(x2, y2, x2+1, y2+1)) if hasAnimation.Empty() { hasAnimation = toInvalidate } else { hasAnimation = hasAnimation.Union(toInvalidate) } if p == thePlayer.paint { pixOffset.X = int(float32((x1-x2)<<res.TileSize) * (1 - interp)) pixOffset.Y = int(float32((y1-y2)<<res.TileSize) * (1 - interp)) hasAnimation = viewport.Bounds() } res.TileFloat(sprites, res.Actors, p.Sprite, x1, y1, x2, y2, interp) } } } } paintLock.Unlock() draw.Draw(viewport, rect, terrain, rect.Min.Add(pixOffset), draw.Src) draw.Draw(viewport, rect, sprites, rect.Min.Add(pixOffset), draw.Over) draw.DrawMask(viewport, rect, image.Black, image.ZP, light.Image(-xOffset, -yOffset), rect.Min.Add(light.Origin(-xOffset, -yOffset)).Add(pixOffset), draw.Over) if image.Rect(0, 0, 1, 1).Overlaps(rect) { mouseTileLock.Lock() res.DrawString(viewport, mouseTileString, color.White, res.FontSmall, 1, 1) mouseTileLock.Unlock() } if !hasAnimation.Empty() { Invalidate(image.Rectangle{hasAnimation.Min.Mul(1 << res.TileSize), hasAnimation.Max.Mul(1 << res.TileSize)}) } paints++ /* // For debugging paints res.DrawString(viewport, strconv.FormatUint(paints, 10), color.White, res.FontSmall, 300, 1) draw.Draw(viewport, image.Rectangle{rect.Min, image.Pt(rect.Max.X+1, rect.Min.Y+1)}, image.White, image.ZP, draw.Src) draw.Draw(viewport, image.Rectangle{image.Pt(rect.Min.X-1, rect.Max.Y-1), rect.Max}, image.White, image.ZP, draw.Src) draw.Draw(viewport, image.Rectangle{rect.Min, image.Pt(rect.Min.X+1, rect.Max.Y+1)}, image.White, image.ZP, draw.Src) draw.Draw(viewport, image.Rectangle{image.Pt(rect.Max.X-1, rect.Min.Y-1), rect.Max}, image.White, image.ZP, draw.Src) //*/ w.Screen().CopyRGBA(viewport, viewport.Bounds()) w.FlushImage(rect) }