Fix GetTiles being called for already cached tiles. (#219)

* Don't call GetTile from the render functions.
Don't bother trying to render uncached tiles.
* Added back randomization code
* Update refs
* Fix random tiles selection.
No sorting the input, no selecting 0 probability tiles if there are
other options.
This commit is contained in:
Ziemas 2019-11-22 01:54:56 +01:00 committed by Tim Sarbin
parent 31cda81847
commit 90b5e8a334
4 changed files with 81 additions and 101 deletions

View File

@ -144,31 +144,27 @@ func (v *Engine) GenTiles(region *EngineRegion) {
}
func (v *Engine) GenTilesCache(region *EngineRegion) {
n := 0
for tileIdx := range region.Tiles {
t := &region.Tiles[tileIdx]
if t.tileY < len(region.Region.DS1.Tiles) && t.tileX < len(region.Region.DS1.Tiles[t.tileY]) {
tile := region.Region.DS1.Tiles[t.tileY][t.tileX]
tile := &region.Region.DS1.Tiles[t.tileY][t.tileX]
for i := range tile.Floors {
if tile.Floors[i].Hidden || tile.Floors[i].Prop1 == 0 {
continue
}
region.Region.generateFloorCache(&tile.Floors[i], t.tileX, t.tileY)
n++
}
for i, shadow := range tile.Shadows {
for i := range tile.Shadows {
if tile.Shadows[i].Hidden || tile.Shadows[i].Prop1 == 0 {
continue
}
region.Region.generateShadowCache(&shadow, t.tileX, t.tileY)
n++
region.Region.generateShadowCache(&tile.Shadows[i], t.tileX, t.tileY)
}
for i, wall := range tile.Walls {
if tile.Walls[i].Hidden {
for i := range tile.Walls {
if tile.Walls[i].Hidden || tile.Walls[i].Prop1 == 0 {
continue
}
region.Region.generateWallCache(&wall, t.tileX, t.tileY)
n++
region.Region.generateWallCache(&tile.Walls[i], t.tileX, t.tileY)
}
}
}
@ -203,7 +199,7 @@ func (v *Engine) RenderPass1(region *Region, offX, offY, x, y int, target *ebite
tile := region.DS1.Tiles[y][x]
// Draw lower walls
for i := range tile.Walls {
if tile.Walls[i].Orientation <= 15 {
if tile.Walls[i].Orientation <= 15 || tile.Walls[i].Prop1 == 0 {
continue
}
if tile.Walls[i].Hidden || tile.Walls[i].Orientation == 10 || tile.Walls[i].Orientation == 11 || tile.Walls[i].Orientation == 0 {

View File

@ -27,13 +27,6 @@ import (
"github.com/hajimehoshi/ebiten"
)
//TODO: move to corresponding file
type ByRarity []d2dt1.Tile
func (a ByRarity) Len() int { return len(a) }
func (a ByRarity) Less(i, j int) bool { return a[i].RarityFrameIndex < a[j].RarityFrameIndex }
func (a ByRarity) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
type Region struct {
RegionPath string
LevelType d2datadict.LevelTypeRecord
@ -48,7 +41,6 @@ type Region struct {
StartX float64
StartY float64
imageCacheRecords map[uint32]*ebiten.Image
tileSource *rand.Rand
seed int64
}
@ -83,14 +75,12 @@ func LoadRegion(seed int64, levelType d2enum.RegionIdType, levelPreset int, file
}
levelFilesToPick = append(levelFilesToPick, fileRecord)
}
randomSource := rand.NewSource(seed)
random := rand.New(randomSource)
levelIndex := int(math.Round(float64(len(levelFilesToPick)-1) * random.Float64()))
levelIndex := int(math.Round(float64(len(levelFilesToPick)-1) * rand.Float64()))
if fileIndex >= 0 && fileIndex < len(levelFilesToPick) {
levelIndex = fileIndex
}
levelFile := levelFilesToPick[levelIndex]
result.tileSource = rand.New(rand.NewSource(seed))
result.RegionPath = levelFile
result.DS1 = d2ds1.LoadDS1("/data/global/tiles/"+levelFile, fileProvider)
result.TileWidth = result.DS1.Width
@ -154,7 +144,37 @@ func (v *Region) RenderTile(offsetX, offsetY, tileX, tileY int, layerType d2enum
}
func (v *Region) getRandomTile(tiles []d2dt1.Tile, x, y int, seed int64) (*d2dt1.Tile, byte) {
// Temporary hack...
/* Walker's Alias Method for weighted random selection
* with xorshifting for random numbers */
var tileSeed uint64
tileSeed = uint64(seed) + uint64(x)
tileSeed *= uint64(y) + uint64(v.LevelType.Id)
tileSeed ^= tileSeed << 13
tileSeed ^= tileSeed >> 17
tileSeed ^= tileSeed << 5
weightSum := 0
for _, tile := range tiles {
weightSum += int(tile.RarityFrameIndex)
}
if weightSum == 0 {
return &tiles[0], 0
}
random := (tileSeed % uint64(weightSum))
sum := 0
for i, tile := range tiles {
sum += int(tile.RarityFrameIndex)
if sum >= int(random) {
return &tiles[i], byte(i)
}
}
// This return shouldn't be hit
return &tiles[0], 0
}
@ -174,11 +194,12 @@ func (v *Region) getTile(mainIndex, subIndex, orientation int32, x, y int, seed
}
func (v *Region) renderFloor(tile d2ds1.FloorShadowRecord, offsetX, offsetY int, target *ebiten.Image, tileX, tileY int) {
opts := &ebiten.DrawImageOptions{}
img := v.GetImageCacheRecord(tile.MainIndex, tile.SubIndex, 0, tile.RandomIndex)
if img == nil {
img = v.generateFloorCache(&tile, tileX, tileY)
log.Printf("Render called on uncached floor {%v,%v}", tile.MainIndex, tile.SubIndex)
return
}
opts := &ebiten.DrawImageOptions{}
opts.GeoM.Translate(float64(offsetX), float64(offsetY))
_ = target.DrawImage(img, opts)
return
@ -187,58 +208,22 @@ func (v *Region) renderFloor(tile d2ds1.FloorShadowRecord, offsetX, offsetY int,
func (v *Region) renderWall(tile d2ds1.WallRecord, offsetX, offsetY int, target *ebiten.Image, tileX, tileY int) {
img := v.GetImageCacheRecord(tile.MainIndex, tile.SubIndex, tile.Orientation, tile.RandomIndex)
if img == nil {
img = v.generateWallCache(&tile, tileX, tileY)
if img == nil {
return
}
}
tileData, _ := v.getTile(int32(tile.MainIndex), int32(tile.SubIndex), int32(tile.Orientation), tileX, tileY, v.seed)
if tileData == nil {
log.Printf("Render called on uncached wall {%v,%v,%v}", tile.MainIndex, tile.SubIndex, tile.Orientation)
return
}
var newTileData *d2dt1.Tile = nil
if tile.Orientation == 3 {
newTileData, _ = v.getTile(int32(tile.MainIndex), int32(tile.SubIndex), int32(4), tileX, tileY, v.seed)
}
tileMinY := int32(0)
tileMaxY := int32(0)
targetTileData := tileData
if newTileData != nil && newTileData.Height < tileData.Height {
targetTileData = newTileData
}
for _, block := range targetTileData.Blocks {
tileMinY = d2helper.MinInt32(tileMinY, int32(block.Y))
tileMaxY = d2helper.MaxInt32(tileMaxY, int32(block.Y+32))
}
yAdjust := 0
if tile.Orientation == 15 {
// Roof
yAdjust = -int(tileData.RoofHeight)
} else {
// Upper Walls, Special Tiles
yAdjust = int(tileMinY) + 80
}
opts := &ebiten.DrawImageOptions{}
opts.GeoM.Translate(float64(offsetX), float64(offsetY+yAdjust))
opts.GeoM.Translate(float64(offsetX), float64(offsetY+tile.YAdjust))
target.DrawImage(img, opts)
}
func (v *Region) renderShadow(tile d2ds1.FloorShadowRecord, offsetX, offsetY int, target *ebiten.Image, tileX, tileY int) {
img := v.GetImageCacheRecord(tile.MainIndex, tile.SubIndex, 13, tile.RandomIndex)
if img == nil {
img = v.generateShadowCache(&tile, tileX, tileY)
}
tileData, _ := v.getTile(int32(tile.MainIndex), int32(tile.SubIndex), 13, tileX, tileY, v.seed)
if tileData == nil {
log.Printf("Render called on uncached shadow {%v,%v}", tile.MainIndex, tile.SubIndex)
return
}
tileMinY := int32(0)
for _, block := range tileData.Blocks {
tileMinY = d2helper.MinInt32(tileMinY, int32(block.Y))
}
opts := &ebiten.DrawImageOptions{}
opts.GeoM.Translate(float64(offsetX), float64(offsetY+int(tileMinY)+80))
opts.GeoM.Translate(float64(offsetX), float64(offsetY+tile.YAdjust))
opts.ColorM = d2corehelper.ColorToColorM(color.RGBA{255, 255, 255, 160})
target.DrawImage(img, opts)
}
@ -323,11 +308,11 @@ func (v *Region) generateFloorCache(tile *d2ds1.FloorShadowRecord, tileX, tileY
tileData.Width = 10
tileData.Height = 10
}
tile.RandomIndex = tileIndex
cachedImage := v.GetImageCacheRecord(tile.MainIndex, tile.SubIndex, 0, tileIndex)
if cachedImage != nil {
return cachedImage
}
tile.RandomIndex = tileIndex
tileYMinimum := int32(0)
for _, block := range tileData.Blocks {
tileYMinimum = d2helper.MinInt32(tileYMinimum, int32(block.Y))
@ -348,10 +333,6 @@ func (v *Region) generateShadowCache(tile *d2ds1.FloorShadowRecord, tileX, tileY
return nil
}
tile.RandomIndex = tileIndex
cachedImage := v.GetImageCacheRecord(tile.MainIndex, tile.SubIndex, 13, tileIndex)
if cachedImage != nil {
return cachedImage
}
tileMinY := int32(0)
tileMaxY := int32(0)
for _, block := range tileData.Blocks {
@ -360,6 +341,13 @@ func (v *Region) generateShadowCache(tile *d2ds1.FloorShadowRecord, tileX, tileY
}
tileYOffset := -tileMinY
tileHeight := int(tileMaxY - tileMinY)
tile.YAdjust = int(tileMinY + 80)
cachedImage := v.GetImageCacheRecord(tile.MainIndex, tile.SubIndex, 13, tileIndex)
if cachedImage != nil {
return cachedImage
}
image, _ := ebiten.NewImage(int(tileData.Width), int(tileHeight), ebiten.FilterNearest)
pixels := make([]byte, 4*tileData.Width*int32(tileHeight))
v.decodeTileGfxData(tileData.Blocks, &pixels, tileYOffset, tileData.Width)
@ -373,45 +361,62 @@ func (v *Region) generateWallCache(tile *d2ds1.WallRecord, tileX, tileY int) *eb
if tileData == nil {
return nil
}
tile.RandomIndex = tileIndex
var newTileData *d2dt1.Tile = nil
if tile.Orientation == 3 {
newTileData, _ = v.getTile(int32(tile.MainIndex), int32(tile.SubIndex), int32(4), tileX, tileY, v.seed)
}
tileMinY := int32(0)
tileMaxY := int32(0)
target := tileData
if newTileData != nil && newTileData.Height < tileData.Height {
target = newTileData
}
for _, block := range target.Blocks {
tileMinY = d2helper.MinInt32(tileMinY, int32(block.Y))
tileMaxY = d2helper.MaxInt32(tileMaxY, int32(block.Y+32))
}
realHeight := d2helper.MaxInt32(d2helper.AbsInt32(tileData.Height), tileMaxY-tileMinY)
tileYOffset := -tileMinY
//tileHeight := int(tileMaxY - tileMinY)
if tile.Orientation == 15 {
tile.YAdjust = -int(tileData.RoofHeight)
} else {
tile.YAdjust = int(tileMinY) + 80
}
cachedImage := v.GetImageCacheRecord(tile.MainIndex, tile.SubIndex, tile.Orientation, tileIndex)
if cachedImage != nil {
return cachedImage //, 0, yAdjust}
return cachedImage
}
if realHeight == 0 {
log.Printf("Invalid 0 height for wall tile")
return nil
}
image, _ := ebiten.NewImage(160, int(realHeight), ebiten.FilterNearest)
pixels := make([]byte, 4*160*realHeight)
v.decodeTileGfxData(tileData.Blocks, &pixels, tileYOffset, 160)
if newTileData != nil {
v.decodeTileGfxData(newTileData.Blocks, &pixels, tileYOffset, 160)
}
if err := image.ReplacePixels(pixels); err != nil {
log.Panicf(err.Error())
}
v.SetImageCacheRecord(tile.MainIndex, tile.SubIndex, tile.Orientation, tileIndex, image)
return image //,0,yAdjust,
return image
}
func (v *Region) GetImageCacheRecord(mainIndex, subIndex, orientation, randomIndex byte) *ebiten.Image {

4
go.mod
View File

@ -3,13 +3,11 @@ module github.com/OpenDiablo2/OpenDiablo2
go 1.12
require (
github.com/JoshVarga/blast v0.0.0-20180421040937-681c804fb9f0
github.com/OpenDiablo2/D2Shared v0.0.0-20191119200215-b4d6d042eb13
github.com/OpenDiablo2/D2Shared v0.0.0-20191121150938-91629c87a1be
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
github.com/hajimehoshi/ebiten v1.11.0-alpha.0.20191119174134-52f6be26392b
github.com/mitchellh/go-homedir v1.1.0
github.com/pkg/profile v1.3.0
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 // indirect
golang.org/x/mobile v0.0.0-20191115022231-f0c40035f2ba // indirect
golang.org/x/sys v0.0.0-20191115151921-52ab43148777 // indirect

31
go.sum
View File

@ -2,19 +2,13 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/JoshVarga/blast v0.0.0-20180421040937-681c804fb9f0 h1:tDnuU0igiBiQFjsvq1Bi7DpoUjqI76VVvW045vpeFeM=
github.com/JoshVarga/blast v0.0.0-20180421040937-681c804fb9f0/go.mod h1:h/5OEGj4G+fpYxluLjSMZbFY011ZxAntO98nCl8mrCs=
github.com/OpenDiablo2/D2Shared v0.0.0-20191117023413-d9429afbbed6 h1:KAejCXdaPBH3/pyS9tPemi3gWzvCVvSitkPmYPfmYTk=
github.com/OpenDiablo2/D2Shared v0.0.0-20191117023413-d9429afbbed6/go.mod h1:ZB6LLdzmBJrQ0ADH671WFvsAhNQfYaOp0EI3KJ9Ckck=
github.com/OpenDiablo2/D2Shared v0.0.0-20191117044836-c56c888bec7d h1:2yQG+kQSdd/9NvbUDYYkvfjMPGRb5vLSClYRWF835SI=
github.com/OpenDiablo2/D2Shared v0.0.0-20191117044836-c56c888bec7d/go.mod h1:tWln5/64VDcLuOr/GHyQU1ea5zdm5WfleFPEr8rFgcw=
github.com/OpenDiablo2/D2Shared v0.0.0-20191117053631-b0c159330365 h1:CinnWYg8Pa+FUuMvhNpJyxf9FeDmc4J3PllQdeGuXGU=
github.com/OpenDiablo2/D2Shared v0.0.0-20191117053631-b0c159330365/go.mod h1:tWln5/64VDcLuOr/GHyQU1ea5zdm5WfleFPEr8rFgcw=
github.com/OpenDiablo2/D2Shared v0.0.0-20191119053321-f24eee9fc5d7 h1:z33kCTl7E5u/1tT48ZFC1zaaT3uak/dqEmyQ3y90/eA=
github.com/OpenDiablo2/D2Shared v0.0.0-20191119053321-f24eee9fc5d7/go.mod h1:zRNOUiglwakbufN8EsNWqLLDHsZoQDA6/dI2GIu2nnU=
github.com/OpenDiablo2/D2Shared v0.0.0-20191119200215-b4d6d042eb13/go.mod h1:zRNOUiglwakbufN8EsNWqLLDHsZoQDA6/dI2GIu2nnU=
github.com/OpenDiablo2/D2Shared v0.0.0-20191121150938-91629c87a1be h1:KbpiV80D35hozRinTXGXUWeaNWgPhLyYXd6zc8V1p+Y=
github.com/OpenDiablo2/D2Shared v0.0.0-20191121150938-91629c87a1be/go.mod h1:zRNOUiglwakbufN8EsNWqLLDHsZoQDA6/dI2GIu2nnU=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
@ -22,24 +16,10 @@ github.com/gofrs/flock v0.7.1 h1:DP+LD/t0njgoPBvT5MJLeliUIVQR03hiKR6vezdwHlc=
github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/hajimehoshi/bitmapfont v1.2.0/go.mod h1:h9QrPk6Ktb2neObTlAbma6Ini1xgMjbJ3w7ysmD7IOU=
github.com/hajimehoshi/ebiten v1.10.0 h1:ADLOUI/7aaTOP7GRlQBHVI1Qtvfdt9M6XQqeULSK7Uo=
github.com/hajimehoshi/ebiten v1.10.0/go.mod h1:8BJhIws+Jkol+z7hSGP/WFsaDAPTtRQ+ELBPPQetq2w=
github.com/hajimehoshi/ebiten v1.11.0-alpha.0.20191115171053-e42cff071c36 h1:fHp/oiWM4uC88FHWCaTn6Lck4sTEKZ0KhWsajb7zfL0=
github.com/hajimehoshi/ebiten v1.11.0-alpha.0.20191115171053-e42cff071c36/go.mod h1:52cGPFR+BqkkBap9Ue4BEKkfvICkvXoONeWCYPEFTPo=
github.com/hajimehoshi/ebiten v1.11.0-alpha.0.20191116200143-acc933b7c399 h1:UeyExTBk9PT8voPAc8UvIqOytjRrPBQX7D1jiQnhhls=
github.com/hajimehoshi/ebiten v1.11.0-alpha.0.20191116200143-acc933b7c399/go.mod h1:52cGPFR+BqkkBap9Ue4BEKkfvICkvXoONeWCYPEFTPo=
github.com/hajimehoshi/ebiten v1.11.0-alpha.0.20191117051038-800b98a0c66d h1:dJL9ygMUE9U5WOEwgQ+D33t0dDRm3VkwNi2lzaoGQ6A=
github.com/hajimehoshi/ebiten v1.11.0-alpha.0.20191117051038-800b98a0c66d/go.mod h1:6ax6p5ui8fuQ/+00sQ79oTy4OfrythHfDEYV4yni5So=
github.com/hajimehoshi/ebiten v1.11.0-alpha.0.20191117152313-63f9ac2ccc2a h1:EoW3KYFBekMCBuCxnmseVGV0wh6pgmkZGJP7pRWK4ek=
github.com/hajimehoshi/ebiten v1.11.0-alpha.0.20191117152313-63f9ac2ccc2a/go.mod h1:6ax6p5ui8fuQ/+00sQ79oTy4OfrythHfDEYV4yni5So=
github.com/hajimehoshi/ebiten v1.11.0-alpha.0.20191119174134-52f6be26392b h1:8LbFtMYNChUizU4eCdzhluH0RsUmOdh1rRlDt54K7/4=
github.com/hajimehoshi/ebiten v1.11.0-alpha.0.20191119174134-52f6be26392b/go.mod h1:6ax6p5ui8fuQ/+00sQ79oTy4OfrythHfDEYV4yni5So=
github.com/hajimehoshi/go-mp3 v0.2.1/go.mod h1:Rr+2P46iH6PwTPVgSsEwBkon0CK5DxCAeX/Rp65DCTE=
github.com/hajimehoshi/oto v0.3.4/go.mod h1:PgjqsBJff0efqL2nlMJidJgVJywLn6M4y8PI4TfeWfA=
github.com/hajimehoshi/oto v0.5.2 h1:5FEPlejAsR2PVRqiW7h2PIwp9UWR+8zxj2And102YU4=
github.com/hajimehoshi/oto v0.5.2/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
github.com/hajimehoshi/oto v0.5.3-0.20191110112117-6298480de6b1 h1:D/mCcGB1KpQDbI8itypR0vhNA1LClAD336h0VKmwNCo=
github.com/hajimehoshi/oto v0.5.3-0.20191110112117-6298480de6b1/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
github.com/hajimehoshi/oto v0.5.3 h1:IccIFFUkT0oAr/KdH3LH7USyvI1ZE84HXiGtuCjs3y0=
github.com/hajimehoshi/oto v0.5.3/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
github.com/jakecoffman/cp v0.1.0/go.mod h1:a3xPx9N8RyFAACD644t2dj/nK4SuLg1v+jL61m2yVo4=
@ -53,10 +33,10 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
github.com/pkg/profile v1.3.0 h1:OQIvuDgm00gWVWGTf4m4mCt6W1/0YqU7Ntg0mySWgaI=
github.com/pkg/profile v1.3.0/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@ -99,4 +79,5 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=