mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-10-01 15:46:17 -04:00
Added object support (#93)
* Fixed LevelTypes load * Update ResourcePaths.go * Added DCC loading support * Added animation data. Fixed bitshift version compile issue. * Fixed another go build error * Initial support for object rendering
This commit is contained in:
parent
2ec5dd2d85
commit
01a48d8720
125
Common/AnimatedEntity.go
Normal file
125
Common/AnimatedEntity.go
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
package Common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AnimatedEntity struct {
|
||||||
|
dcc *DCC
|
||||||
|
cof *Cof
|
||||||
|
palette PaletteDefs.PaletteType
|
||||||
|
base string
|
||||||
|
token string
|
||||||
|
tr string
|
||||||
|
animationMode string
|
||||||
|
weaponClass string
|
||||||
|
lastFrameTime time.Time
|
||||||
|
framesToAnimate int
|
||||||
|
animationSpeed int
|
||||||
|
direction int
|
||||||
|
currentFrame int
|
||||||
|
LocationX float64
|
||||||
|
LocationY float64
|
||||||
|
frames []*ebiten.Image
|
||||||
|
frameLocations []Rectangle
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateAnimatedEntity(base, token, tr string, palette PaletteDefs.PaletteType) *AnimatedEntity {
|
||||||
|
result := &AnimatedEntity{
|
||||||
|
base: base,
|
||||||
|
token: token,
|
||||||
|
tr: tr,
|
||||||
|
palette: palette,
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
var DirectionLookup = []int{3, 15, 4, 8, 0, 9, 5, 10, 1, 11, 6, 12, 2, 13, 7, 14}
|
||||||
|
|
||||||
|
func (v *AnimatedEntity) SetMode(animationMode, weaponClass string, direction int, provider FileProvider) {
|
||||||
|
dccPath := fmt.Sprintf("%s/%s/tr/%str%s%s%s.dcc", v.base, v.token, v.token, v.tr, animationMode, weaponClass)
|
||||||
|
v.dcc = LoadDCC(dccPath, provider)
|
||||||
|
cofPath := fmt.Sprintf("%s/%s/cof/%s%s%s.cof", v.base, v.token, v.token, animationMode, weaponClass)
|
||||||
|
v.cof = LoadCof(cofPath, provider)
|
||||||
|
v.animationMode = animationMode
|
||||||
|
v.weaponClass = weaponClass
|
||||||
|
v.direction = direction
|
||||||
|
v.cacheFrames()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *AnimatedEntity) Render(target *ebiten.Image, offsetX, offsetY int) {
|
||||||
|
for v.lastFrameTime.Add(time.Millisecond * time.Duration(v.animationSpeed)).Before(time.Now()) {
|
||||||
|
v.lastFrameTime = v.lastFrameTime.Add(time.Millisecond * time.Duration(v.animationSpeed))
|
||||||
|
v.currentFrame++
|
||||||
|
if v.currentFrame >= v.framesToAnimate {
|
||||||
|
v.currentFrame = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := &ebiten.DrawImageOptions{}
|
||||||
|
opts.GeoM.Translate(float64(v.frameLocations[v.currentFrame].Left+offsetX), float64(v.frameLocations[v.currentFrame].Top+offsetY+40))
|
||||||
|
target.DrawImage(v.frames[v.currentFrame], opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *AnimatedEntity) cacheFrames() {
|
||||||
|
animationData := AnimationData[strings.ToLower(v.token+v.animationMode+v.weaponClass)][v.direction]
|
||||||
|
v.animationSpeed = int((float64(animationData.AnimationSpeed) / 255.0) * 0.04 * 1000.0)
|
||||||
|
v.framesToAnimate = animationData.FramesPerDirection
|
||||||
|
v.lastFrameTime = time.Now()
|
||||||
|
minX := int32(2147483647)
|
||||||
|
minY := int32(2147483647)
|
||||||
|
maxX := int32(-2147483648)
|
||||||
|
maxY := int32(-2147483648)
|
||||||
|
for _, layer := range v.dcc.Directions {
|
||||||
|
minX = MinInt32(minX, int32(layer.Box.Left))
|
||||||
|
minY = MinInt32(minY, int32(layer.Box.Top))
|
||||||
|
maxX = MaxInt32(maxX, int32(layer.Box.Right()))
|
||||||
|
maxY = MaxInt32(maxY, int32(layer.Box.Bottom()))
|
||||||
|
}
|
||||||
|
frameW := maxX - minX
|
||||||
|
frameH := maxY - minY
|
||||||
|
v.frames = make([]*ebiten.Image, v.framesToAnimate)
|
||||||
|
v.frameLocations = make([]Rectangle, v.framesToAnimate)
|
||||||
|
for frameIndex := range v.frames {
|
||||||
|
v.frames[frameIndex], _ = ebiten.NewImage(int(frameW), int(frameH), ebiten.FilterNearest)
|
||||||
|
priorityBase := (v.direction * animationData.FramesPerDirection * v.cof.NumberOfLayers) + (frameIndex * v.cof.NumberOfLayers)
|
||||||
|
for layerIdx := 0; layerIdx < v.cof.NumberOfLayers; layerIdx++ {
|
||||||
|
comp := v.cof.Priority[priorityBase+layerIdx]
|
||||||
|
if _, found := v.cof.CompositeLayers[comp]; !found {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
direction := v.dcc.Directions[v.direction]
|
||||||
|
frame := direction.Frames[frameIndex]
|
||||||
|
pixelData := make([]byte, 4*frameW*frameH)
|
||||||
|
for y := 0; y < direction.Box.Height; y++ {
|
||||||
|
for x := 0; x < direction.Box.Width; x++ {
|
||||||
|
paletteIndex := frame.PixelData[x+(y*direction.Box.Width)]
|
||||||
|
|
||||||
|
if paletteIndex == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
color := Palettes[v.palette].Colors[paletteIndex]
|
||||||
|
actualX := x + direction.Box.Left - int(minX)
|
||||||
|
actualY := y + direction.Box.Top - int(minY)
|
||||||
|
pixelData[(actualX*4)+(actualY*int(frameW)*4)] = color.R
|
||||||
|
pixelData[(actualX*4)+(actualY*int(frameW)*4)+1] = color.G
|
||||||
|
pixelData[(actualX*4)+(actualY*int(frameW)*4)+2] = color.B
|
||||||
|
pixelData[(actualX*4)+(actualY*int(frameW)*4)+3] = 255
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v.frames[frameIndex].ReplacePixels(pixelData)
|
||||||
|
v.frameLocations[frameIndex] = Rectangle{
|
||||||
|
Left: int(minX),
|
||||||
|
Top: int(minY),
|
||||||
|
Width: int(frameW),
|
||||||
|
Height: int(frameH),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
244
Common/Cof.go
Normal file
244
Common/Cof.go
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
package Common
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
type AnimationMode int
|
||||||
|
|
||||||
|
const (
|
||||||
|
AnimationModePlayerDeath AnimationMode = 0
|
||||||
|
AnimationModePlayerNeutral AnimationMode = 1
|
||||||
|
AnimationModePlayerWalk AnimationMode = 2
|
||||||
|
AnimationModePlayerRun AnimationMode = 3
|
||||||
|
AnimationModePlayerGetHit AnimationMode = 4
|
||||||
|
AnimationModePlayerTownNeutral AnimationMode = 5
|
||||||
|
AnimationModePlayerTownWalk AnimationMode = 6
|
||||||
|
AnimationModePlayerAttack1 AnimationMode = 7
|
||||||
|
AnimationModePlayerAttack2 AnimationMode = 8
|
||||||
|
AnimationModePlayerBlock AnimationMode = 9
|
||||||
|
AnimationModePlayerCast AnimationMode = 10
|
||||||
|
AnimationModePlayerThrow AnimationMode = 11
|
||||||
|
AnimationModePlayerKick AnimationMode = 12
|
||||||
|
AnimationModePlayerSkill1 AnimationMode = 13
|
||||||
|
AnimationModePlayerSkill2 AnimationMode = 14
|
||||||
|
AnimationModePlayerSkill3 AnimationMode = 15
|
||||||
|
AnimationModePlayerSkill4 AnimationMode = 16
|
||||||
|
AnimationModePlayerDead AnimationMode = 17
|
||||||
|
AnimationModePlayerSequence AnimationMode = 18
|
||||||
|
AnimationModePlayerKnockBack AnimationMode = 19
|
||||||
|
AnimationModeMonsterDeath AnimationMode = 20
|
||||||
|
AnimationModeMonsterNeutral AnimationMode = 21
|
||||||
|
AnimationModeMonsterWalk AnimationMode = 22
|
||||||
|
AnimationModeMonsterGetHit AnimationMode = 23
|
||||||
|
AnimationModeMonsterAttack1 AnimationMode = 24
|
||||||
|
AnimationModeMonsterAttack2 AnimationMode = 25
|
||||||
|
AnimationModeMonsterBlock AnimationMode = 26
|
||||||
|
AnimationModeMonsterCast AnimationMode = 27
|
||||||
|
AnimationModeMonsterSkill1 AnimationMode = 28
|
||||||
|
AnimationModeMonsterSkill2 AnimationMode = 29
|
||||||
|
AnimationModeMonsterSkill3 AnimationMode = 30
|
||||||
|
AnimationModeMonsterSkill4 AnimationMode = 31
|
||||||
|
AnimationModeMonsterDead AnimationMode = 32
|
||||||
|
AnimationModeMonsterKnockback AnimationMode = 33
|
||||||
|
AnimationModeMonsterSequence AnimationMode = 34
|
||||||
|
AnimationModeMonsterRun AnimationMode = 35
|
||||||
|
AnimationModeObjectNeutral AnimationMode = 36
|
||||||
|
AnimationModeObjectOperating AnimationMode = 37
|
||||||
|
AnimationModeObjectOpened AnimationMode = 38
|
||||||
|
AnimationModeObjectSpecial1 AnimationMode = 39
|
||||||
|
AnimationModeObjectSpecial2 AnimationMode = 40
|
||||||
|
AnimationModeObjectSpecial3 AnimationMode = 41
|
||||||
|
AnimationModeObjectSpecial4 AnimationMode = 42
|
||||||
|
AnimationModeObjectSpecial5 AnimationMode = 43
|
||||||
|
)
|
||||||
|
|
||||||
|
var AnimationModeStr = map[AnimationMode]string{
|
||||||
|
AnimationModePlayerDeath: "DT",
|
||||||
|
AnimationModePlayerNeutral: "NU",
|
||||||
|
AnimationModePlayerWalk: "WL",
|
||||||
|
AnimationModePlayerRun: "RN",
|
||||||
|
AnimationModePlayerGetHit: "GH",
|
||||||
|
AnimationModePlayerTownNeutral: "TN",
|
||||||
|
AnimationModePlayerTownWalk: "TW",
|
||||||
|
AnimationModePlayerAttack1: "A1",
|
||||||
|
AnimationModePlayerAttack2: "A2",
|
||||||
|
AnimationModePlayerBlock: "BL",
|
||||||
|
AnimationModePlayerCast: "SC",
|
||||||
|
AnimationModePlayerThrow: "TH",
|
||||||
|
AnimationModePlayerKick: "KK",
|
||||||
|
AnimationModePlayerSkill1: "S1",
|
||||||
|
AnimationModePlayerSkill2: "S2",
|
||||||
|
AnimationModePlayerSkill3: "S3",
|
||||||
|
AnimationModePlayerSkill4: "S4",
|
||||||
|
AnimationModePlayerDead: "DD",
|
||||||
|
AnimationModePlayerSequence: "GH",
|
||||||
|
AnimationModePlayerKnockBack: "GH",
|
||||||
|
AnimationModeMonsterDeath: "DT",
|
||||||
|
AnimationModeMonsterNeutral: "NU",
|
||||||
|
AnimationModeMonsterWalk: "WL",
|
||||||
|
AnimationModeMonsterGetHit: "GH",
|
||||||
|
AnimationModeMonsterAttack1: "A1",
|
||||||
|
AnimationModeMonsterAttack2: "A2",
|
||||||
|
AnimationModeMonsterBlock: "BL",
|
||||||
|
AnimationModeMonsterCast: "SC",
|
||||||
|
AnimationModeMonsterSkill1: "S1",
|
||||||
|
AnimationModeMonsterSkill2: "S2",
|
||||||
|
AnimationModeMonsterSkill3: "S3",
|
||||||
|
AnimationModeMonsterSkill4: "S4",
|
||||||
|
AnimationModeMonsterDead: "DD",
|
||||||
|
AnimationModeMonsterKnockback: "GH",
|
||||||
|
AnimationModeMonsterSequence: "xx",
|
||||||
|
AnimationModeMonsterRun: "RN",
|
||||||
|
AnimationModeObjectNeutral: "NU",
|
||||||
|
AnimationModeObjectOperating: "OP",
|
||||||
|
AnimationModeObjectOpened: "ON",
|
||||||
|
AnimationModeObjectSpecial1: "S1",
|
||||||
|
AnimationModeObjectSpecial2: "S2",
|
||||||
|
AnimationModeObjectSpecial3: "S3",
|
||||||
|
AnimationModeObjectSpecial4: "S4",
|
||||||
|
AnimationModeObjectSpecial5: "S5",
|
||||||
|
}
|
||||||
|
|
||||||
|
type CompositeType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
CompositeTypeHead CompositeType = 0
|
||||||
|
CompositeTypeTorso CompositeType = 1
|
||||||
|
CompositeTypeLegs CompositeType = 2
|
||||||
|
CompositeTypeRightArm CompositeType = 3
|
||||||
|
CompositeTypeLeftArm CompositeType = 4
|
||||||
|
CompositeTypeRightHand CompositeType = 5
|
||||||
|
CompositeTypeLeftHand CompositeType = 6
|
||||||
|
CompositeTypeShield CompositeType = 7
|
||||||
|
CompositeTypeSpecial1 CompositeType = 8
|
||||||
|
CompositeTypeSpecial2 CompositeType = 9
|
||||||
|
CompositeTypeSpecial3 CompositeType = 10
|
||||||
|
CompositeTypeSpecial4 CompositeType = 11
|
||||||
|
CompositeTypeSpecial5 CompositeType = 12
|
||||||
|
CompositeTypeSpecial6 CompositeType = 13
|
||||||
|
CompositeTypeSpecial7 CompositeType = 14
|
||||||
|
CompositeTypeSpecial8 CompositeType = 15
|
||||||
|
CompositeTypeMax CompositeType = 16
|
||||||
|
)
|
||||||
|
|
||||||
|
type DrawEffect int
|
||||||
|
|
||||||
|
const (
|
||||||
|
DrawEffectPctTransparency75 = 0 //75 % transparency (colormaps 561-816 in a .pl2)
|
||||||
|
DrawEffectPctTransparency50 = 1 //50 % transparency (colormaps 305-560 in a .pl2)
|
||||||
|
DrawEffectPctTransparency25 = 2 //25 % transparency (colormaps 49-304 in a .pl2)
|
||||||
|
DrawEffectScreen = 3 //Screen (colormaps 817-1072 in a .pl2)
|
||||||
|
DrawEffectLuminance = 4 //luminance (colormaps 1073-1328 in a .pl2)
|
||||||
|
DrawEffectBringAlphaBlending = 5 //bright alpha blending (colormaps 1457-1712 in a .pl2)
|
||||||
|
)
|
||||||
|
|
||||||
|
type WeaponClass int
|
||||||
|
|
||||||
|
const (
|
||||||
|
WeaponClassNone WeaponClass = 0
|
||||||
|
WeaponClassHandToHand WeaponClass = 1
|
||||||
|
WeaponClassBow WeaponClass = 2
|
||||||
|
WeaponClassOneHandSwing WeaponClass = 3
|
||||||
|
WeaponClassOneHandThrust WeaponClass = 4
|
||||||
|
WeaponClassStaff WeaponClass = 5
|
||||||
|
WeaponClassTwoHandSwing WeaponClass = 6
|
||||||
|
WeaponClassTwoHandThrust WeaponClass = 7
|
||||||
|
WeaponClassCrossbow WeaponClass = 8
|
||||||
|
WeaponClassLeftJabRightSwing WeaponClass = 9
|
||||||
|
WeaponClassLeftJabRightThrust WeaponClass = 10
|
||||||
|
WeaponClassLeftSwingRightSwing WeaponClass = 11
|
||||||
|
WeaponClassLeftSwingRightThrust WeaponClass = 12
|
||||||
|
WeaponClassOneHandToHand WeaponClass = 13
|
||||||
|
WeaponClassTwoHandToHand WeaponClass = 14
|
||||||
|
)
|
||||||
|
|
||||||
|
var WeaponClassStr = map[WeaponClass]string{
|
||||||
|
WeaponClassNone: "",
|
||||||
|
WeaponClassHandToHand: "hth",
|
||||||
|
WeaponClassBow: "bow",
|
||||||
|
WeaponClassOneHandSwing: "1hs",
|
||||||
|
WeaponClassOneHandThrust: "1ht",
|
||||||
|
WeaponClassStaff: "stf",
|
||||||
|
WeaponClassTwoHandSwing: "2hs",
|
||||||
|
WeaponClassTwoHandThrust: "2ht",
|
||||||
|
WeaponClassCrossbow: "xbw",
|
||||||
|
WeaponClassLeftJabRightSwing: "1js",
|
||||||
|
WeaponClassLeftJabRightThrust: "1jt",
|
||||||
|
WeaponClassLeftSwingRightSwing: "1ss",
|
||||||
|
WeaponClassLeftSwingRightThrust: "1st",
|
||||||
|
WeaponClassOneHandToHand: "ht1",
|
||||||
|
WeaponClassTwoHandToHand: "ht2",
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetWeaponClass(val string) WeaponClass {
|
||||||
|
for weaponClass, weaponStr := range WeaponClassStr {
|
||||||
|
if val != weaponStr {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return weaponClass
|
||||||
|
}
|
||||||
|
return WeaponClassNone
|
||||||
|
}
|
||||||
|
|
||||||
|
type AnimationFrame int
|
||||||
|
|
||||||
|
const (
|
||||||
|
AnimationFrameNoEvent AnimationFrame = 0
|
||||||
|
AnimationFrameAttack AnimationFrame = 1
|
||||||
|
AnimationFrameMissile AnimationFrame = 2
|
||||||
|
AnimationFrameSound AnimationFrame = 3
|
||||||
|
AnimationFrameSkill AnimationFrame = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
type CofLayer struct {
|
||||||
|
Type CompositeType
|
||||||
|
Shadow byte
|
||||||
|
Transparent bool
|
||||||
|
DrawEffect DrawEffect
|
||||||
|
WeaponClass WeaponClass
|
||||||
|
}
|
||||||
|
|
||||||
|
type Cof struct {
|
||||||
|
NumberOfDirections int
|
||||||
|
FramesPerDirection int
|
||||||
|
NumberOfLayers int
|
||||||
|
CofLayers []*CofLayer
|
||||||
|
CompositeLayers map[CompositeType]int
|
||||||
|
AnimationFrames []AnimationFrame
|
||||||
|
Priority []CompositeType
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadCof(fileName string, fileProvider FileProvider) *Cof {
|
||||||
|
result := &Cof{}
|
||||||
|
fileData := fileProvider.LoadFile(fileName)
|
||||||
|
streamReader := CreateStreamReader(fileData)
|
||||||
|
result.NumberOfLayers = int(streamReader.GetByte())
|
||||||
|
result.FramesPerDirection = int(streamReader.GetByte())
|
||||||
|
result.NumberOfDirections = int(streamReader.GetByte())
|
||||||
|
streamReader.SkipBytes(25) // Skip 25 unknown bytes...
|
||||||
|
result.CofLayers = make([]*CofLayer, 0)
|
||||||
|
result.CompositeLayers = make(map[CompositeType]int, 0)
|
||||||
|
for i := 0; i < result.NumberOfLayers; i++ {
|
||||||
|
layer := &CofLayer{}
|
||||||
|
layer.Type = CompositeType(streamReader.GetByte())
|
||||||
|
layer.Shadow = streamReader.GetByte()
|
||||||
|
streamReader.SkipBytes(1) // Unknown
|
||||||
|
layer.Transparent = streamReader.GetByte() != 0
|
||||||
|
layer.DrawEffect = DrawEffect(streamReader.GetByte())
|
||||||
|
weaponClassStr, _ := streamReader.ReadBytes(4)
|
||||||
|
layer.WeaponClass = GetWeaponClass(strings.TrimSpace(strings.ReplaceAll(string(weaponClassStr), string(0), "")))
|
||||||
|
result.CofLayers = append(result.CofLayers, layer)
|
||||||
|
result.CompositeLayers[layer.Type] = i
|
||||||
|
}
|
||||||
|
animationFrameBytes, _ := streamReader.ReadBytes(result.FramesPerDirection)
|
||||||
|
result.AnimationFrames = make([]AnimationFrame, result.FramesPerDirection)
|
||||||
|
for i := range animationFrameBytes {
|
||||||
|
result.AnimationFrames[i] = AnimationFrame(animationFrameBytes[i])
|
||||||
|
}
|
||||||
|
priorityLen := result.FramesPerDirection * result.NumberOfDirections * result.NumberOfLayers
|
||||||
|
result.Priority = make([]CompositeType, priorityLen)
|
||||||
|
priorityBytes, _ := streamReader.ReadBytes(priorityLen)
|
||||||
|
for i := range priorityBytes {
|
||||||
|
result.Priority[i] = CompositeType(priorityBytes[i])
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
@ -513,5 +513,6 @@ func LoadDCC(path string, fileProvider FileProvider) *DCC {
|
|||||||
for i := 0; i < result.NumberOfDirections; i++ {
|
for i := 0; i < result.NumberOfDirections; i++ {
|
||||||
result.Directions[i] = CreateDCCDirection(CreateBitMuncher(fileData, directionOffsets[i]*8), result)
|
result.Directions[i] = CreateDCCDirection(CreateBitMuncher(fileData, directionOffsets[i]*8), result)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -58,3 +58,9 @@ func IsoToScreen(isoX, isoY, modX, modY int) (int, int) {
|
|||||||
screenY := (isoX + isoY) * 40
|
screenY := (isoX + isoY) * 40
|
||||||
return screenX + modX, screenY + modY
|
return screenX + modX, screenY + modY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ScreenToIso(sx, sy float64) (float64, float64) {
|
||||||
|
x := (sx/80 + sy/40) / 2
|
||||||
|
y := (sy/40 - (sx / 80)) / 2
|
||||||
|
return x, y
|
||||||
|
}
|
||||||
|
@ -2,7 +2,6 @@ package Common
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
"github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
||||||
)
|
)
|
||||||
@ -34,15 +33,15 @@ func CreatePalette(name PaletteDefs.PaletteType, data []byte) PaletteRec {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadPalettes(mpqFiles map[string]*MpqFileRecord, fileProvider FileProvider) {
|
func LoadPalettes(mpqFiles map[string]string, fileProvider FileProvider) {
|
||||||
Palettes = make(map[PaletteDefs.PaletteType]PaletteRec)
|
Palettes = make(map[PaletteDefs.PaletteType]PaletteRec)
|
||||||
for file := range mpqFiles {
|
for _, pal := range []string{
|
||||||
if strings.Index(file, "/data/global/palette/") != 0 || strings.Index(file, ".dat") != len(file)-4 {
|
"act1", "act2", "act3", "act4", "act5", "endgame", "endgame2", "fechar", "loading",
|
||||||
continue
|
"menu0", "menu1", "menu2", "menu3", "menu4", "sky", "static", "trademark", "units",
|
||||||
}
|
} {
|
||||||
nameParts := strings.Split(file, `/`)
|
filePath := `data\global\palette\` + pal + `\pal.dat`
|
||||||
paletteName := PaletteDefs.PaletteType(nameParts[len(nameParts)-2])
|
paletteName := PaletteDefs.PaletteType(pal)
|
||||||
palette := CreatePalette(paletteName, fileProvider.LoadFile(file))
|
palette := CreatePalette(paletteName, fileProvider.LoadFile(filePath))
|
||||||
Palettes[paletteName] = palette
|
Palettes[paletteName] = palette
|
||||||
}
|
}
|
||||||
log.Printf("Loaded %d palettes", len(Palettes))
|
log.Printf("Loaded %d palettes", len(Palettes))
|
||||||
|
@ -14,3 +14,7 @@ func (v *Rectangle) Bottom() int {
|
|||||||
func (v *Rectangle) Right() int {
|
func (v *Rectangle) Right() int {
|
||||||
return v.Left + v.Width
|
return v.Left + v.Width
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *Rectangle) IsInRect(x, y int) bool {
|
||||||
|
return x >= v.Left && x < v.Left+v.Width && y >= v.Top && y < v.Top+v.Height
|
||||||
|
}
|
||||||
|
@ -2,7 +2,6 @@ package Core
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
@ -11,12 +10,13 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/MPQ"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
"github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Sound"
|
"github.com/OpenDiablo2/OpenDiablo2/Sound"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/MPQ"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Scenes"
|
"github.com/OpenDiablo2/OpenDiablo2/Scenes"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/UI"
|
"github.com/OpenDiablo2/OpenDiablo2/UI"
|
||||||
@ -42,17 +42,17 @@ type EngineConfig struct {
|
|||||||
|
|
||||||
// Engine is the core OpenDiablo2 engine
|
// Engine is the core OpenDiablo2 engine
|
||||||
type Engine struct {
|
type Engine struct {
|
||||||
Settings *EngineConfig // Engine configuration settings from json file
|
Settings *EngineConfig // Engine configuration settings from json file
|
||||||
Files map[string]*Common.MpqFileRecord // Map that defines which files are in which MPQs
|
Files map[string]string // Map that defines which files are in which MPQs
|
||||||
CheckedPatch map[string]bool // First time we check a file, we'll check if it's in the patch. This notes that we've already checked that.
|
CheckedPatch map[string]bool // First time we check a file, we'll check if it's in the patch. This notes that we've already checked that.
|
||||||
LoadingSprite *Common.Sprite // The sprite shown when loading stuff
|
LoadingSprite *Common.Sprite // The sprite shown when loading stuff
|
||||||
loadingProgress float64 // LoadingProcess is a range between 0.0 and 1.0. If set, loading screen displays.
|
loadingProgress float64 // LoadingProcess is a range between 0.0 and 1.0. If set, loading screen displays.
|
||||||
stepLoadingSize float64 // The size for each loading step
|
stepLoadingSize float64 // The size for each loading step
|
||||||
CurrentScene Scenes.Scene // The current scene being rendered
|
CurrentScene Scenes.Scene // The current scene being rendered
|
||||||
UIManager *UI.Manager // The UI manager
|
UIManager *UI.Manager // The UI manager
|
||||||
SoundManager *Sound.Manager // The sound manager
|
SoundManager *Sound.Manager // The sound manager
|
||||||
nextScene Scenes.Scene // The next scene to be loaded at the end of the game loop
|
nextScene Scenes.Scene // The next scene to be loaded at the end of the game loop
|
||||||
fullscreenKey bool // When true, the fullscreen toggle is still being pressed
|
fullscreenKey bool // When true, the fullscreen toggle is still being pressed
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateEngine creates and instance of the OpenDiablo2 engine
|
// CreateEngine creates and instance of the OpenDiablo2 engine
|
||||||
@ -115,6 +115,11 @@ func (v *Engine) loadConfigurationFile() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *Engine) mapMpqFiles() {
|
||||||
|
v.Files = make(map[string]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
func (v *Engine) mapMpqFiles() {
|
func (v *Engine) mapMpqFiles() {
|
||||||
log.Println("mapping mpq file structure")
|
log.Println("mapping mpq file structure")
|
||||||
v.Files = make(map[string]*Common.MpqFileRecord)
|
v.Files = make(map[string]*Common.MpqFileRecord)
|
||||||
@ -229,6 +234,37 @@ func (v *Engine) LoadFile(fileName string) []byte {
|
|||||||
mutex.Unlock()
|
mutex.Unlock()
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
var mutex sync.Mutex
|
||||||
|
|
||||||
|
func (v *Engine) LoadFile(fileName string) []byte {
|
||||||
|
fileName = strings.ReplaceAll(fileName, "{LANG}", ResourcePaths.LanguageCode)
|
||||||
|
fileName = strings.ToLower(fileName)
|
||||||
|
fileName = strings.ReplaceAll(fileName, `/`, "\\")
|
||||||
|
if fileName[0] == '\\' {
|
||||||
|
fileName = fileName[1:]
|
||||||
|
}
|
||||||
|
mutex.Lock()
|
||||||
|
defer mutex.Unlock()
|
||||||
|
// TODO: May want to cache some things if performance becomes an issue
|
||||||
|
cachedMpqFile, cacheExists := v.Files[fileName]
|
||||||
|
if cacheExists {
|
||||||
|
mpq, _ := MPQ.Load(cachedMpqFile)
|
||||||
|
result, _ := mpq.ReadFile(fileName)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
for _, mpqFile := range v.Settings.MpqLoadOrder {
|
||||||
|
mpq, _ := MPQ.Load(path.Join(v.Settings.MpqPath, mpqFile))
|
||||||
|
if !mpq.FileExists(fileName) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
v.Files[fileName] = path.Join(v.Settings.MpqPath, mpqFile)
|
||||||
|
result, _ := mpq.ReadFile(fileName)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
log.Fatalf("Could not load %s from MPQs", fileName)
|
||||||
|
return []byte{}
|
||||||
|
}
|
||||||
|
|
||||||
// IsLoading returns true if the engine is currently in a loading state
|
// IsLoading returns true if the engine is currently in a loading state
|
||||||
func (v *Engine) IsLoading() bool {
|
func (v *Engine) IsLoading() bool {
|
||||||
|
@ -242,7 +242,6 @@ func (v *MPQ) Close() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (v MPQ) FileExists(fileName string) bool {
|
func (v MPQ) FileExists(fileName string) bool {
|
||||||
fileName = strings.ReplaceAll(fileName, "{LANG}", ResourcePaths.LanguageCode)
|
|
||||||
_, err := v.getFileHashEntry(fileName)
|
_, err := v.getFileHashEntry(fileName)
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
140
Map/Engine.go
140
Map/Engine.go
@ -1,7 +1,7 @@
|
|||||||
package Map
|
package Map
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
||||||
@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type EngineRegion struct {
|
type EngineRegion struct {
|
||||||
Rect image.Rectangle
|
Rect Common.Rectangle
|
||||||
Region *Region
|
Region *Region
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,76 +37,116 @@ func (v *Engine) GenerateMap(regionType RegionIdType, levelPreset int) {
|
|||||||
randomSource := rand.NewSource(v.gameState.Seed)
|
randomSource := rand.NewSource(v.gameState.Seed)
|
||||||
region := LoadRegion(randomSource, regionType, levelPreset, v.fileProvider)
|
region := LoadRegion(randomSource, regionType, levelPreset, v.fileProvider)
|
||||||
v.regions = append(v.regions, EngineRegion{
|
v.regions = append(v.regions, EngineRegion{
|
||||||
Rect: image.Rectangle{image.Point{0, 0}, image.Point{int(region.TileWidth), int(region.TileHeight)}},
|
Rect: Common.Rectangle{0, 0, int(region.TileWidth), int(region.TileHeight)},
|
||||||
Region: region,
|
Region: region,
|
||||||
})
|
})
|
||||||
v.soundManager.PlayBGM("/data/global/music/Act1/tristram.wav") // TODO: Temp stuff here
|
v.soundManager.PlayBGM("/data/global/music/Act1/town1.wav") // TODO: Temp stuff here
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Engine) GetRegionAt(x, y int) *Region {
|
||||||
|
if v.regions == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for _, region := range v.regions {
|
||||||
|
if !region.Rect.IsInRect(x, y) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return region.Region
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Engine) Render(target *ebiten.Image) {
|
func (v *Engine) Render(target *ebiten.Image) {
|
||||||
for y := 0; y < int(v.regions[0].Region.TileHeight); y++ {
|
for _, region := range v.regions {
|
||||||
offX := -(y * 80)
|
for y := 0; y < int(region.Region.TileHeight); y++ {
|
||||||
offY := y * 40
|
offX := -(y * 80)
|
||||||
for x := 0; x < int(v.regions[0].Region.TileWidth); x++ {
|
offY := y * 40
|
||||||
sx, sy := Common.IsoToScreen(x, y, int(v.OffsetX), int(v.OffsetY))
|
for x := 0; x < int(region.Region.TileWidth); x++ {
|
||||||
if sx > -160 && sy > -160 && sx <= 800 && sy <= 1000 {
|
sx, sy := Common.IsoToScreen(x, y, int(v.OffsetX), int(v.OffsetY))
|
||||||
tile := v.regions[0].Region.DS1.Tiles[y][x]
|
if sx > -160 && sy > -160 && sx <= 880 && sy <= 1000 {
|
||||||
for i := range tile.Floors {
|
tile := region.Region.DS1.Tiles[y][x]
|
||||||
if !tile.Floors[i].Hidden && tile.Floors[i].Prop1 != 0 {
|
for i := range tile.Floors {
|
||||||
v.regions[0].Region.RenderTile(offX+int(v.OffsetX), offY+int(v.OffsetY), x, y, RegionLayerTypeFloors, i, target)
|
if tile.Floors[i].Hidden || tile.Floors[i].Prop1 == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
region.Region.RenderTile(offX+int(v.OffsetX), offY+int(v.OffsetY), x, y, RegionLayerTypeFloors, i, target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
offX += 80
|
||||||
|
offY += 40
|
||||||
}
|
}
|
||||||
offX += 80
|
|
||||||
offY += 40
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for y := 0; y < int(v.regions[0].Region.TileHeight); y++ {
|
for _, region := range v.regions {
|
||||||
offX := -(y * 80)
|
for y := 0; y < int(region.Region.TileHeight); y++ {
|
||||||
offY := y * 40
|
offX := -(y * 80)
|
||||||
for x := 0; x < int(v.regions[0].Region.TileWidth); x++ {
|
offY := y * 40
|
||||||
sx, sy := Common.IsoToScreen(x, y, int(v.OffsetX), int(v.OffsetY))
|
for x := 0; x < int(region.Region.TileWidth); x++ {
|
||||||
if sx > -160 && sy > -160 && sx <= 800 && sy <= 1000 {
|
sx, sy := Common.IsoToScreen(x, y, int(v.OffsetX), int(v.OffsetY))
|
||||||
tile := v.regions[0].Region.DS1.Tiles[y][x]
|
if sx > -160 && sy > -160 && sx <= 880 && sy <= 1000 {
|
||||||
for i := range tile.Shadows {
|
tile := region.Region.DS1.Tiles[y][x]
|
||||||
if tile.Shadows[i].Hidden || tile.Shadows[i].Prop1 == 0 {
|
for i := range tile.Shadows {
|
||||||
|
if tile.Shadows[i].Hidden || tile.Shadows[i].Prop1 == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
region.Region.RenderTile(offX+int(v.OffsetX), offY+int(v.OffsetY), x, y, RegionLayerTypeShadows, i, target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offX += 80
|
||||||
|
offY += 40
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, region := range v.regions {
|
||||||
|
for y := 0; y < int(region.Region.TileHeight); y++ {
|
||||||
|
offX := -(y * 80)
|
||||||
|
offY := y * 40
|
||||||
|
for x := 0; x < int(region.Region.TileWidth); x++ {
|
||||||
|
tile := region.Region.DS1.Tiles[y][x]
|
||||||
|
for i := range tile.Walls {
|
||||||
|
if tile.Walls[i].Hidden || tile.Walls[i].Orientation == 15 || tile.Walls[i].Orientation == 10 || tile.Walls[i].Orientation == 11 || tile.Walls[i].Orientation == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
v.regions[0].Region.RenderTile(offX+int(v.OffsetX), offY+int(v.OffsetY), x, y, RegionLayerTypeShadows, i, target)
|
region.Region.RenderTile(offX+int(v.OffsetX), offY+int(v.OffsetY), x, y, RegionLayerTypeWalls, i, target)
|
||||||
}
|
}
|
||||||
|
offX += 80
|
||||||
|
offY += 40
|
||||||
}
|
}
|
||||||
offX += 80
|
|
||||||
offY += 40
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for y := 0; y < int(v.regions[0].Region.TileHeight); y++ {
|
for _, region := range v.regions {
|
||||||
offX := -(y * 80)
|
for y := 0; y < int(region.Region.TileHeight); y++ {
|
||||||
offY := y * 40
|
offX := -(y * 80)
|
||||||
for x := 0; x < int(v.regions[0].Region.TileWidth); x++ {
|
offY := y * 40
|
||||||
tile := v.regions[0].Region.DS1.Tiles[y][x]
|
for x := 0; x < int(region.Region.TileWidth); x++ {
|
||||||
for i := range tile.Walls {
|
tile := region.Region.DS1.Tiles[y][x]
|
||||||
if tile.Walls[i].Hidden || tile.Walls[i].Orientation == 15 || tile.Walls[i].Orientation == 10 || tile.Walls[i].Orientation == 11 || tile.Walls[i].Orientation == 0 {
|
for i := range tile.Walls {
|
||||||
continue
|
if tile.Walls[i].Hidden || tile.Walls[i].Orientation != 15 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
region.Region.RenderTile(offX+int(v.OffsetX), offY+int(v.OffsetY), x, y, RegionLayerTypeWalls, i, target)
|
||||||
}
|
}
|
||||||
v.regions[0].Region.RenderTile(offX+int(v.OffsetX), offY+int(v.OffsetY), x, y, RegionLayerTypeWalls, i, target)
|
offX += 80
|
||||||
|
offY += 40
|
||||||
}
|
}
|
||||||
offX += 80
|
|
||||||
offY += 40
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for y := 0; y < int(v.regions[0].Region.TileHeight); y++ {
|
for _, region := range v.regions {
|
||||||
offX := -(y * 80)
|
for y := 0; y < int(region.Region.TileHeight); y++ {
|
||||||
offY := y * 40
|
offX := -(y * 80)
|
||||||
for x := 0; x < int(v.regions[0].Region.TileWidth); x++ {
|
offY := y * 40
|
||||||
tile := v.regions[0].Region.DS1.Tiles[y][x]
|
for x := 0; x < int(region.Region.TileWidth); x++ {
|
||||||
for i := range tile.Walls {
|
sx, sy := Common.IsoToScreen(x, y, int(v.OffsetX), int(v.OffsetY))
|
||||||
if tile.Walls[i].Hidden || tile.Walls[i].Orientation != 15 {
|
if sx > -160 && sy > -160 && sx <= 880 && sy <= 1000 {
|
||||||
continue
|
for _, obj := range region.Region.AnimationEntities {
|
||||||
|
if int(math.Floor(obj.LocationX)) == x && int(math.Floor(obj.LocationY)) == y {
|
||||||
|
obj.Render(target, offX+int(v.OffsetX), offY+int(v.OffsetY))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
v.regions[0].Region.RenderTile(offX+int(v.OffsetX), offY+int(v.OffsetY), x, y, RegionLayerTypeWalls, i, target)
|
offX += 80
|
||||||
|
offY += 40
|
||||||
}
|
}
|
||||||
offX += 80
|
|
||||||
offY += 40
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"sync"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
"github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
||||||
|
|
||||||
@ -22,16 +22,17 @@ type TileCacheRecord struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Region struct {
|
type Region struct {
|
||||||
levelType Common.LevelTypeRecord
|
LevelType Common.LevelTypeRecord
|
||||||
levelPreset *Common.LevelPresetRecord
|
levelPreset *Common.LevelPresetRecord
|
||||||
TileWidth int32
|
TileWidth int32
|
||||||
TileHeight int32
|
TileHeight int32
|
||||||
Tiles []Tile
|
Tiles []Tile
|
||||||
DS1 *DS1
|
DS1 *DS1
|
||||||
Palette Common.PaletteRec
|
Palette Common.PaletteRec
|
||||||
FloorCache map[uint32]*TileCacheRecord
|
FloorCache map[uint32]*TileCacheRecord
|
||||||
ShadowCache map[uint32]*TileCacheRecord
|
ShadowCache map[uint32]*TileCacheRecord
|
||||||
WallCache map[uint32]*TileCacheRecord
|
WallCache map[uint32]*TileCacheRecord
|
||||||
|
AnimationEntities []*Common.AnimatedEntity
|
||||||
}
|
}
|
||||||
|
|
||||||
type RegionLayerType int
|
type RegionLayerType int
|
||||||
@ -84,16 +85,16 @@ const (
|
|||||||
|
|
||||||
func LoadRegion(seed rand.Source, levelType RegionIdType, levelPreset int, fileProvider Common.FileProvider) *Region {
|
func LoadRegion(seed rand.Source, levelType RegionIdType, levelPreset int, fileProvider Common.FileProvider) *Region {
|
||||||
result := &Region{
|
result := &Region{
|
||||||
levelType: Common.LevelTypes[levelType],
|
LevelType: Common.LevelTypes[levelType],
|
||||||
levelPreset: Common.LevelPresets[levelPreset],
|
levelPreset: Common.LevelPresets[levelPreset],
|
||||||
Tiles: make([]Tile, 0),
|
Tiles: make([]Tile, 0),
|
||||||
FloorCache: make(map[uint32]*TileCacheRecord),
|
FloorCache: make(map[uint32]*TileCacheRecord),
|
||||||
ShadowCache: make(map[uint32]*TileCacheRecord),
|
ShadowCache: make(map[uint32]*TileCacheRecord),
|
||||||
WallCache: make(map[uint32]*TileCacheRecord),
|
WallCache: make(map[uint32]*TileCacheRecord),
|
||||||
}
|
}
|
||||||
result.Palette = Common.Palettes[PaletteDefs.PaletteType("act"+strconv.Itoa(int(result.levelType.Act)))]
|
result.Palette = Common.Palettes[PaletteDefs.PaletteType("act"+strconv.Itoa(int(result.LevelType.Act)))]
|
||||||
//\bm := result.levelPreset.Dt1Mask
|
//\bm := result.levelPreset.Dt1Mask
|
||||||
for _, levelTypeDt1 := range result.levelType.Files {
|
for _, levelTypeDt1 := range result.LevelType.Files {
|
||||||
/*
|
/*
|
||||||
if bm&1 == 0 {
|
if bm&1 == 0 {
|
||||||
bm >>= 1
|
bm >>= 1
|
||||||
@ -120,22 +121,32 @@ func LoadRegion(seed rand.Source, levelType RegionIdType, levelPreset int, fileP
|
|||||||
result.DS1 = LoadDS1("/data/global/tiles/"+levelFile, fileProvider)
|
result.DS1 = LoadDS1("/data/global/tiles/"+levelFile, fileProvider)
|
||||||
result.TileWidth = result.DS1.Width
|
result.TileWidth = result.DS1.Width
|
||||||
result.TileHeight = result.DS1.Height
|
result.TileHeight = result.DS1.Height
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(len(result.DS1.Objects))
|
||||||
|
result.AnimationEntities = make([]*Common.AnimatedEntity, 0)
|
||||||
for _, object := range result.DS1.Objects {
|
for _, object := range result.DS1.Objects {
|
||||||
switch object.Lookup.Type {
|
go func(object Object) {
|
||||||
case Common.ObjectTypeCharacter:
|
defer wg.Done()
|
||||||
case Common.ObjectTypeItem:
|
switch object.Lookup.Type {
|
||||||
if object.Lookup.Base == "" {
|
case Common.ObjectTypeCharacter:
|
||||||
continue
|
case Common.ObjectTypeItem:
|
||||||
|
if object.Lookup.Base == "" || object.Lookup.Token == "" || object.Lookup.TR == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
animEntity := Common.CreateAnimatedEntity(object.Lookup.Base, object.Lookup.Token, object.Lookup.TR, PaletteDefs.Units)
|
||||||
|
animEntity.SetMode(object.Lookup.Mode, object.Lookup.Class, 0, fileProvider)
|
||||||
|
animEntity.LocationX = math.Floor(float64(object.X) / 5)
|
||||||
|
animEntity.LocationY = math.Floor(float64(object.Y) / 5)
|
||||||
|
result.AnimationEntities = append(result.AnimationEntities, animEntity)
|
||||||
}
|
}
|
||||||
objPath := strings.ToLower(object.Lookup.Base + "/" + object.Lookup.Token + "/tr/" + object.Lookup.Token + "tr" + object.Lookup.TR +
|
}(object)
|
||||||
object.Lookup.Mode + object.Lookup.Class + ".dcc")
|
|
||||||
_ = Common.LoadDCC(objPath, fileProvider) // This is where the magic will happen
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
wg.Wait()
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Region) RenderTile(offsetX, offsetY, tileX, tileY int, layerType RegionLayerType, layerIndex int, target *ebiten.Image) {
|
func (v *Region) RenderTile(offsetX, offsetY, tileX, tileY int, layerType RegionLayerType, layerIndex int, target *ebiten.Image) {
|
||||||
|
offsetX -= 80
|
||||||
switch layerType {
|
switch layerType {
|
||||||
case RegionLayerTypeFloors:
|
case RegionLayerTypeFloors:
|
||||||
v.renderFloor(v.DS1.Tiles[tileY][tileX].Floors[layerIndex], offsetX, offsetY, target)
|
v.renderFloor(v.DS1.Tiles[tileY][tileX].Floors[layerIndex], offsetX, offsetY, target)
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
package Scenes
|
package Scenes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Map"
|
"github.com/OpenDiablo2/OpenDiablo2/Map"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Sound"
|
"github.com/OpenDiablo2/OpenDiablo2/Sound"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/UI"
|
"github.com/OpenDiablo2/OpenDiablo2/UI"
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
|
"github.com/hajimehoshi/ebiten/ebitenutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MapEngineTest struct {
|
type MapEngineTest struct {
|
||||||
@ -43,16 +47,16 @@ func (v *MapEngineTest) Load() []func() {
|
|||||||
v.mapEngine.GenerateMap(Map.RegionAct1Town, 1)
|
v.mapEngine.GenerateMap(Map.RegionAct1Town, 1)
|
||||||
//v.mapEngine.GenerateMap(Map.RegionAct1Tristram, 300)
|
//v.mapEngine.GenerateMap(Map.RegionAct1Tristram, 300)
|
||||||
//v.mapEngine.GenerateMap(Map.RegionAct1Cathedral, 257)
|
//v.mapEngine.GenerateMap(Map.RegionAct1Cathedral, 257)
|
||||||
//v.mapEngine.GenerateMap(Map.RegionAct2Town, 301) // Broken rendering
|
//v.mapEngine.GenerateMap(Map.RegionAct2Town, 301)
|
||||||
//v.mapEngine.GenerateMap(Map.RegionAct2Harem, 353)
|
//v.mapEngine.GenerateMap(Map.RegionAct2Harem, 353) // Crashes on dcc load
|
||||||
//v.mapEngine.GenerateMap(Map.RegionAct3Town, 529)
|
//v.mapEngine.GenerateMap(Map.RegionAct3Town, 529)
|
||||||
//v.mapEngine.GenerateMap(Map.RegionAct3Jungle, 574)
|
//v.mapEngine.GenerateMap(Map.RegionAct3Jungle, 574)
|
||||||
//v.mapEngine.GenerateMap(Map.RegionAct4Town, 797)
|
//v.mapEngine.GenerateMap(Map.RegionAct4Town, 797) // Broken height of large objects
|
||||||
//v.mapEngine.GenerateMap(Map.RegonAct5Town, 863)
|
//v.mapEngine.GenerateMap(Map.RegonAct5Town, 863) // Completely broken!!
|
||||||
//v.mapEngine.GenerateMap(Map.RegionAct5IceCaves, 1038)
|
//v.mapEngine.GenerateMap(Map.RegionAct5IceCaves, 1038) // Completely broken!
|
||||||
//v.mapEngine.GenerateMap(Map.RegionAct5Siege, 879)
|
//v.mapEngine.GenerateMap(Map.RegionAct5Siege, 879) // Completely broken!
|
||||||
//v.mapEngine.GenerateMap(Map.RegionAct5Lava, 1057) // PALETTE ISSUE
|
//v.mapEngine.GenerateMap(Map.RegionAct5Lava, 1057) // Broken
|
||||||
//v.mapEngine.GenerateMap(Map.RegionAct5Barricade, 880)
|
//v.mapEngine.GenerateMap(Map.RegionAct5Barricade, 880) // Broken
|
||||||
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -64,6 +68,18 @@ func (v *MapEngineTest) Unload() {
|
|||||||
|
|
||||||
func (v *MapEngineTest) Render(screen *ebiten.Image) {
|
func (v *MapEngineTest) Render(screen *ebiten.Image) {
|
||||||
v.mapEngine.Render(screen)
|
v.mapEngine.Render(screen)
|
||||||
|
actualX := float64(v.uiManager.CursorX) - v.mapEngine.OffsetX
|
||||||
|
actualY := float64(v.uiManager.CursorY) - v.mapEngine.OffsetY
|
||||||
|
tileX, tileY := Common.ScreenToIso(actualX, actualY)
|
||||||
|
subtileX := int(math.Ceil(math.Mod((tileX*10), 10))) / 2
|
||||||
|
subtileY := int(math.Ceil(math.Mod((tileY*10), 10))) / 2
|
||||||
|
line := fmt.Sprintf("%d, %d (Tile %d.%d, %d.%d)", int(math.Ceil(actualX)), int(math.Ceil(actualY)), int(math.Ceil(tileX)), subtileX, int(math.Ceil(tileY)), subtileY)
|
||||||
|
ebitenutil.DebugPrintAt(screen, line, 5, 5)
|
||||||
|
curRegion := v.mapEngine.GetRegionAt(int(tileX), int(tileY))
|
||||||
|
if curRegion == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ebitenutil.DebugPrintAt(screen, "Map: "+curRegion.LevelType.Name, 5, 17)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *MapEngineTest) Update(tickTime float64) {
|
func (v *MapEngineTest) Update(tickTime float64) {
|
||||||
|
7
go.mod
7
go.mod
@ -5,6 +5,11 @@ go 1.13
|
|||||||
require (
|
require (
|
||||||
github.com/JoshVarga/blast v0.0.0-20180421040937-681c804fb9f0
|
github.com/JoshVarga/blast v0.0.0-20180421040937-681c804fb9f0
|
||||||
github.com/giorgisio/goav v0.1.0
|
github.com/giorgisio/goav v0.1.0
|
||||||
github.com/hajimehoshi/ebiten v1.9.3
|
github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de // indirect
|
||||||
|
github.com/gopherjs/gopherwasm v1.1.0 // indirect
|
||||||
|
github.com/hajimehoshi/ebiten v1.10.0
|
||||||
github.com/mitchellh/go-homedir v1.1.0
|
github.com/mitchellh/go-homedir v1.1.0
|
||||||
|
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 // indirect
|
||||||
|
golang.org/x/mobile v0.0.0-20191031020345-0945064e013a // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd // indirect
|
||||||
)
|
)
|
||||||
|
50
go.sum
50
go.sum
@ -1,14 +1,20 @@
|
|||||||
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
|
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 h1:tDnuU0igiBiQFjsvq1Bi7DpoUjqI76VVvW045vpeFeM=
|
||||||
github.com/JoshVarga/blast v0.0.0-20180421040937-681c804fb9f0/go.mod h1:h/5OEGj4G+fpYxluLjSMZbFY011ZxAntO98nCl8mrCs=
|
github.com/JoshVarga/blast v0.0.0-20180421040937-681c804fb9f0/go.mod h1:h/5OEGj4G+fpYxluLjSMZbFY011ZxAntO98nCl8mrCs=
|
||||||
github.com/giorgisio/goav v0.1.0 h1:ZyfG3NfX7PMSimv4ulhmnQJf/XeHpMdGCn+afRmY5Oc=
|
github.com/giorgisio/goav v0.1.0 h1:ZyfG3NfX7PMSimv4ulhmnQJf/XeHpMdGCn+afRmY5Oc=
|
||||||
github.com/giorgisio/goav v0.1.0/go.mod h1:RtH8HyxLRLU1iY0pjfhWBKRhnbsnmfoI+FxMwb5bfEo=
|
github.com/giorgisio/goav v0.1.0/go.mod h1:RtH8HyxLRLU1iY0pjfhWBKRhnbsnmfoI+FxMwb5bfEo=
|
||||||
github.com/go-gl/glfw v0.0.0-20181213070059-819e8ce5125f h1:7MsFMbSn8Lcw0blK4+NEOf8DuHoOBDhJsHz04yh13pM=
|
github.com/go-gl/glfw v0.0.0-20181213070059-819e8ce5125f h1:7MsFMbSn8Lcw0blK4+NEOf8DuHoOBDhJsHz04yh13pM=
|
||||||
github.com/go-gl/glfw v0.0.0-20181213070059-819e8ce5125f/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20181213070059-819e8ce5125f/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
|
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=
|
||||||
github.com/gofrs/flock v0.7.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
github.com/gofrs/flock v0.7.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||||
|
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/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c h1:16eHWuMGvCjSfgRJKqIzapE78onvvTbdi1rMkU00lZw=
|
github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c h1:16eHWuMGvCjSfgRJKqIzapE78onvvTbdi1rMkU00lZw=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
|
github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/gopherjs/gopherwasm v0.1.1/go.mod h1:kx4n9a+MzHH0BJJhvlsQ65hqLFXDO/m256AsaDPQ+/4=
|
github.com/gopherjs/gopherwasm v0.1.1/go.mod h1:kx4n9a+MzHH0BJJhvlsQ65hqLFXDO/m256AsaDPQ+/4=
|
||||||
github.com/gopherjs/gopherwasm v1.0.0/go.mod h1:SkZ8z7CWBz5VXbhJel8TxCmAcsQqzgWGR/8nMhyhZSI=
|
github.com/gopherjs/gopherwasm v1.0.0/go.mod h1:SkZ8z7CWBz5VXbhJel8TxCmAcsQqzgWGR/8nMhyhZSI=
|
||||||
github.com/gopherjs/gopherwasm v1.1.0 h1:fA2uLoctU5+T3OhOn2vYP0DVT6pxc7xhTlBB1paATqQ=
|
github.com/gopherjs/gopherwasm v1.1.0 h1:fA2uLoctU5+T3OhOn2vYP0DVT6pxc7xhTlBB1paATqQ=
|
||||||
@ -16,12 +22,19 @@ github.com/gopherjs/gopherwasm v1.1.0/go.mod h1:SkZ8z7CWBz5VXbhJel8TxCmAcsQqzgWG
|
|||||||
github.com/gosuri/uilive v0.0.0-20170323041506-ac356e6e42cd/go.mod h1:qkLSc0A5EXSP6B04TrN4oQoxqFI7A8XvoXSlJi8cwk8=
|
github.com/gosuri/uilive v0.0.0-20170323041506-ac356e6e42cd/go.mod h1:qkLSc0A5EXSP6B04TrN4oQoxqFI7A8XvoXSlJi8cwk8=
|
||||||
github.com/gosuri/uiprogress v0.0.0-20170224063937-d0567a9d84a1/go.mod h1:C1RTYn4Sc7iEyf6j8ft5dyoZ4212h8G1ol9QQluh5+0=
|
github.com/gosuri/uiprogress v0.0.0-20170224063937-d0567a9d84a1/go.mod h1:C1RTYn4Sc7iEyf6j8ft5dyoZ4212h8G1ol9QQluh5+0=
|
||||||
github.com/hajimehoshi/bitmapfont v1.1.1/go.mod h1:Hamfxgney7tDSmVOSDh2AWzoDH70OaC+P24zc02Gum4=
|
github.com/hajimehoshi/bitmapfont v1.1.1/go.mod h1:Hamfxgney7tDSmVOSDh2AWzoDH70OaC+P24zc02Gum4=
|
||||||
|
github.com/hajimehoshi/bitmapfont v1.2.0/go.mod h1:h9QrPk6Ktb2neObTlAbma6Ini1xgMjbJ3w7ysmD7IOU=
|
||||||
github.com/hajimehoshi/ebiten v1.9.3 h1:YijWGMBwH2XA1ZytUQFy33UDHeCSS6d4JZKH1wq38O0=
|
github.com/hajimehoshi/ebiten v1.9.3 h1:YijWGMBwH2XA1ZytUQFy33UDHeCSS6d4JZKH1wq38O0=
|
||||||
github.com/hajimehoshi/ebiten v1.9.3/go.mod h1:XxiJ4Eltvb1KmcD0i6F81eIB1asJhK47y5DC+FPkyso=
|
github.com/hajimehoshi/ebiten v1.9.3/go.mod h1:XxiJ4Eltvb1KmcD0i6F81eIB1asJhK47y5DC+FPkyso=
|
||||||
|
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/go-mp3 v0.2.0/go.mod h1:4i+c5pDNKDrxl1iu9iG90/+fhP37lio6gNhjCx9WBJw=
|
github.com/hajimehoshi/go-mp3 v0.2.0/go.mod h1:4i+c5pDNKDrxl1iu9iG90/+fhP37lio6gNhjCx9WBJw=
|
||||||
|
github.com/hajimehoshi/go-mp3 v0.2.1/go.mod h1:Rr+2P46iH6PwTPVgSsEwBkon0CK5DxCAeX/Rp65DCTE=
|
||||||
github.com/hajimehoshi/oto v0.1.1/go.mod h1:hUiLWeBQnbDu4pZsAhOnGqMI1ZGibS6e2qhQdfpwz04=
|
github.com/hajimehoshi/oto v0.1.1/go.mod h1:hUiLWeBQnbDu4pZsAhOnGqMI1ZGibS6e2qhQdfpwz04=
|
||||||
github.com/hajimehoshi/oto v0.3.3 h1:Wi7VVtxe9sF2rbDBIJtVXnpFWhRfK57hw0JY7tR2qXM=
|
github.com/hajimehoshi/oto v0.3.3 h1:Wi7VVtxe9sF2rbDBIJtVXnpFWhRfK57hw0JY7tR2qXM=
|
||||||
github.com/hajimehoshi/oto v0.3.3/go.mod h1:e9eTLBB9iZto045HLbzfHJIc+jP3xaKrjZTghvb6fdM=
|
github.com/hajimehoshi/oto v0.3.3/go.mod h1:e9eTLBB9iZto045HLbzfHJIc+jP3xaKrjZTghvb6fdM=
|
||||||
|
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/jakecoffman/cp v0.1.0/go.mod h1:a3xPx9N8RyFAACD644t2dj/nK4SuLg1v+jL61m2yVo4=
|
github.com/jakecoffman/cp v0.1.0/go.mod h1:a3xPx9N8RyFAACD644t2dj/nK4SuLg1v+jL61m2yVo4=
|
||||||
github.com/jfreymuth/oggvorbis v1.0.0/go.mod h1:abe6F9QRjuU9l+2jek3gj46lu40N4qlYxh2grqkLEDM=
|
github.com/jfreymuth/oggvorbis v1.0.0/go.mod h1:abe6F9QRjuU9l+2jek3gj46lu40N4qlYxh2grqkLEDM=
|
||||||
github.com/jfreymuth/vorbis v1.0.0/go.mod h1:8zy3lUAm9K/rJJk223RKy6vjCZTWC61NA2QD06bfOE0=
|
github.com/jfreymuth/vorbis v1.0.0/go.mod h1:8zy3lUAm9K/rJJk223RKy6vjCZTWC61NA2QD06bfOE0=
|
||||||
@ -30,18 +43,55 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
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 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
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=
|
||||||
|
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=
|
||||||
golang.org/x/exp v0.0.0-20180710024300-14dda7b62fcd h1:nLIcFw7GiqKXUS7HiChg6OAYWgASB2H97dZKd1GhDSs=
|
golang.org/x/exp v0.0.0-20180710024300-14dda7b62fcd h1:nLIcFw7GiqKXUS7HiChg6OAYWgASB2H97dZKd1GhDSs=
|
||||||
golang.org/x/exp v0.0.0-20180710024300-14dda7b62fcd/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20180710024300-14dda7b62fcd/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
|
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
|
||||||
|
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw=
|
||||||
|
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||||
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
||||||
golang.org/x/image v0.0.0-20180926015637-991ec62608f3/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
golang.org/x/image v0.0.0-20180926015637-991ec62608f3/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
||||||
golang.org/x/image v0.0.0-20190118043309-183bebdce1b2 h1:FNSSV4jv1PrPsiM2iKGpqLPPgYACqh9Muav7Pollk1k=
|
golang.org/x/image v0.0.0-20190118043309-183bebdce1b2 h1:FNSSV4jv1PrPsiM2iKGpqLPPgYACqh9Muav7Pollk1k=
|
||||||
golang.org/x/image v0.0.0-20190118043309-183bebdce1b2/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
golang.org/x/image v0.0.0-20190118043309-183bebdce1b2/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
||||||
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
|
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
|
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
|
||||||
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/mobile v0.0.0-20180806140643-507816974b79/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
golang.org/x/mobile v0.0.0-20180806140643-507816974b79/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||||
golang.org/x/mobile v0.0.0-20190127143845-a42111704963 h1:2HSxAhImj2OpXsNjXSqfnv1xtqeCpDjwPB3o1DnQqKM=
|
golang.org/x/mobile v0.0.0-20190127143845-a42111704963 h1:2HSxAhImj2OpXsNjXSqfnv1xtqeCpDjwPB3o1DnQqKM=
|
||||||
golang.org/x/mobile v0.0.0-20190127143845-a42111704963/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
golang.org/x/mobile v0.0.0-20190127143845-a42111704963/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||||
|
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||||
|
golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||||
|
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||||
|
golang.org/x/mobile v0.0.0-20191025110607-73ccc5ba0426/go.mod h1:p895TfNkDgPEmEQrNiOtIl3j98d/tGU95djDj7NfyjQ=
|
||||||
|
golang.org/x/mobile v0.0.0-20191031020345-0945064e013a h1:CrJ8+QyIm2tcw/zt9Rp/vGFsey+jndL1y5EnFwzgGOg=
|
||||||
|
golang.org/x/mobile v0.0.0-20191031020345-0945064e013a/go.mod h1:p895TfNkDgPEmEQrNiOtIl3j98d/tGU95djDj7NfyjQ=
|
||||||
|
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190203050204-7ae0202eb74c h1:YeMXU0KQqExdpG959DFhAhfpY8myIsnfqj8lhNFRzzE=
|
golang.org/x/sys v0.0.0-20190203050204-7ae0202eb74c h1:YeMXU0KQqExdpG959DFhAhfpY8myIsnfqj8lhNFRzzE=
|
||||||
golang.org/x/sys v0.0.0-20190203050204-7ae0202eb74c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190203050204-7ae0202eb74c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd h1:3x5uuvBgE6oaXJjCOvpCC1IpgJogqQ+PqGGU3ZxAgII=
|
||||||
|
golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/tools v0.0.0-20190202235157-7414d4c1f71c/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190202235157-7414d4c1f71c/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190909214602-067311248421/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191026034945-b2104f82a97d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
Loading…
Reference in New Issue
Block a user