2019-11-10 08:51:02 -05:00
|
|
|
package d2scene
|
2019-10-27 19:00:38 -04:00
|
|
|
|
|
|
|
import (
|
2019-11-06 18:25:19 -05:00
|
|
|
"fmt"
|
|
|
|
"math"
|
2019-11-15 09:04:27 -05:00
|
|
|
"os"
|
2019-11-06 18:25:19 -05:00
|
|
|
|
2019-11-10 03:36:53 -05:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core"
|
|
|
|
|
2019-11-17 00:16:33 -05:00
|
|
|
"github.com/OpenDiablo2/D2Shared/d2common/d2interface"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2corecommon/d2coreinterface"
|
2019-11-10 03:36:53 -05:00
|
|
|
|
2019-11-17 00:16:33 -05:00
|
|
|
"github.com/OpenDiablo2/D2Shared/d2common/d2enum"
|
2019-11-17 01:14:58 -05:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2audio"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2render/d2mapengine"
|
2019-11-10 08:51:02 -05:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2render/d2ui"
|
2019-10-27 19:00:38 -04:00
|
|
|
"github.com/hajimehoshi/ebiten"
|
2019-11-06 18:25:19 -05:00
|
|
|
"github.com/hajimehoshi/ebiten/ebitenutil"
|
2019-11-15 09:04:27 -05:00
|
|
|
"github.com/hajimehoshi/ebiten/inpututil"
|
2019-10-27 19:00:38 -04:00
|
|
|
)
|
|
|
|
|
2019-11-17 00:52:13 -05:00
|
|
|
type RegionSpec struct {
|
|
|
|
regionType d2enum.RegionIdType
|
|
|
|
startPresetIndex int
|
|
|
|
endPresetIndex int
|
|
|
|
extra []int
|
|
|
|
}
|
|
|
|
|
|
|
|
var regions []RegionSpec = []RegionSpec{
|
|
|
|
//Act I
|
|
|
|
{d2enum.RegionAct1Town, 1, 3, []int{}},
|
|
|
|
{d2enum.RegionAct1Wilderness, 4, 52, []int{
|
|
|
|
108,
|
|
|
|
160, 161, 162, 163, 164,
|
|
|
|
}},
|
|
|
|
{d2enum.RegionAct1Cave, 53, 107, []int{}},
|
|
|
|
{d2enum.RegionAct1Crypt, 109, 159, []int{}},
|
|
|
|
{d2enum.RegionAct1Monestary, 165, 165, []int{}},
|
|
|
|
{d2enum.RegionAct1Courtyard, 166, 166, []int{256}},
|
|
|
|
{d2enum.RegionAct1Barracks, 167, 205, []int{}},
|
|
|
|
{d2enum.RegionAct1Jail, 206, 255, []int{}},
|
|
|
|
{d2enum.RegionAct1Cathedral, 257, 257, []int{}},
|
|
|
|
{d2enum.RegionAct1Catacombs, 258, 299, []int{}},
|
|
|
|
{d2enum.RegionAct1Tristram, 300, 300, []int{}},
|
|
|
|
|
|
|
|
//Act II
|
|
|
|
{d2enum.RegionAct2Town, 301, 301, []int{}},
|
|
|
|
{d2enum.RegionAct2Sewer, 302, 352, []int{}},
|
|
|
|
{d2enum.RegionAct2Harem, 353, 357, []int{}},
|
|
|
|
{d2enum.RegionAct2Basement, 358, 361, []int{}},
|
|
|
|
{d2enum.RegionAct2Desert, 362, 413, []int{}},
|
|
|
|
{d2enum.RegionAct2Tomb, 414, 481, []int{}},
|
|
|
|
{d2enum.RegionAct2Lair, 482, 509, []int{}},
|
|
|
|
{d2enum.RegionAct2Arcane, 510, 528, []int{}},
|
|
|
|
|
|
|
|
//Act III
|
|
|
|
{d2enum.RegionAct3Town, 529, 529, []int{}},
|
|
|
|
{d2enum.RegionAct3Jungle, 530, 604, []int{}},
|
|
|
|
{d2enum.RegionAct3Kurast, 605, 658, []int{
|
|
|
|
748, 749, 750, 751, 752, 753, 754,
|
|
|
|
755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796,
|
|
|
|
//yeah, i know =(
|
|
|
|
}},
|
|
|
|
{d2enum.RegionAct3Spider, 659, 664, []int{}},
|
|
|
|
{d2enum.RegionAct3Dungeon, 665, 704, []int{}},
|
|
|
|
{d2enum.RegionAct3Sewer, 705, 747, []int{}},
|
|
|
|
|
|
|
|
//Act IV
|
|
|
|
{d2enum.RegionAct4Town, 797, 798, []int{}},
|
|
|
|
{d2enum.RegionAct4Mesa, 799, 835, []int{}},
|
|
|
|
{d2enum.RegionAct4Lava, 836, 862, []int{}},
|
|
|
|
|
|
|
|
//Act V -- broken or wrong order
|
|
|
|
{d2enum.RegonAct5Town, 863, 864, []int{}},
|
|
|
|
{d2enum.RegionAct5Siege, 865, 879, []int{}},
|
|
|
|
{d2enum.RegionAct5Barricade, 880, 1002, []int{}},
|
|
|
|
{d2enum.RegionAct5IceCaves, 1003, 1041, []int{}},
|
|
|
|
{d2enum.RegionAct5Temple, 1042, 1052, []int{}},
|
|
|
|
{d2enum.RegionAct5Baal, 1059, 1090, []int{}},
|
|
|
|
{d2enum.RegionAct5Lava, 1053, 1058, []int{}},
|
|
|
|
}
|
|
|
|
|
2019-10-27 19:00:38 -04:00
|
|
|
type MapEngineTest struct {
|
2019-11-10 08:51:02 -05:00
|
|
|
uiManager *d2ui.Manager
|
2019-11-10 03:36:53 -05:00
|
|
|
soundManager *d2audio.Manager
|
|
|
|
fileProvider d2interface.FileProvider
|
2019-11-17 00:16:33 -05:00
|
|
|
sceneProvider d2coreinterface.SceneProvider
|
2019-11-10 03:36:53 -05:00
|
|
|
gameState *d2core.GameState
|
2019-12-13 00:33:11 -05:00
|
|
|
mapEngine *d2mapengine.MapEngine
|
2019-11-17 00:52:13 -05:00
|
|
|
|
|
|
|
//TODO: this is region specific properties, should be refactored for multi-region rendering
|
2019-11-13 14:26:42 -05:00
|
|
|
currentRegion int
|
2019-11-17 00:52:13 -05:00
|
|
|
levelPreset int
|
|
|
|
fileIndex int
|
|
|
|
regionSpec RegionSpec
|
|
|
|
filesCount int
|
2019-12-13 00:33:11 -05:00
|
|
|
debugVisLevel int
|
2019-10-27 19:00:38 -04:00
|
|
|
}
|
|
|
|
|
2019-11-01 14:12:23 -04:00
|
|
|
func CreateMapEngineTest(
|
2019-11-10 03:36:53 -05:00
|
|
|
fileProvider d2interface.FileProvider,
|
2019-11-17 00:16:33 -05:00
|
|
|
sceneProvider d2coreinterface.SceneProvider,
|
2019-11-10 08:51:02 -05:00
|
|
|
uiManager *d2ui.Manager,
|
2019-11-13 14:26:42 -05:00
|
|
|
soundManager *d2audio.Manager,
|
2019-11-17 00:52:13 -05:00
|
|
|
currentRegion int, levelPreset int) *MapEngineTest {
|
2019-10-27 19:00:38 -04:00
|
|
|
result := &MapEngineTest{
|
|
|
|
fileProvider: fileProvider,
|
|
|
|
uiManager: uiManager,
|
|
|
|
soundManager: soundManager,
|
|
|
|
sceneProvider: sceneProvider,
|
2019-11-13 14:26:42 -05:00
|
|
|
currentRegion: currentRegion,
|
2019-11-17 00:52:13 -05:00
|
|
|
levelPreset: levelPreset,
|
2019-11-17 08:09:54 -05:00
|
|
|
fileIndex: 0,
|
2019-11-17 00:52:13 -05:00
|
|
|
regionSpec: RegionSpec{},
|
|
|
|
filesCount: 0,
|
2019-10-27 19:00:38 -04:00
|
|
|
}
|
2019-11-11 23:48:55 -05:00
|
|
|
result.gameState = d2core.CreateTestGameState()
|
2019-10-27 19:00:38 -04:00
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2019-11-17 00:52:13 -05:00
|
|
|
func (v *MapEngineTest) LoadRegionByIndex(n int, levelPreset, fileIndex int) {
|
|
|
|
for _, spec := range regions {
|
|
|
|
if spec.regionType == d2enum.RegionIdType(n) {
|
|
|
|
v.regionSpec = spec
|
|
|
|
inExtra := false
|
|
|
|
for _, e := range spec.extra {
|
|
|
|
if e == levelPreset {
|
|
|
|
inExtra = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !inExtra {
|
|
|
|
if levelPreset < spec.startPresetIndex {
|
|
|
|
levelPreset = spec.startPresetIndex
|
|
|
|
}
|
2019-11-13 14:26:42 -05:00
|
|
|
|
2019-11-17 00:52:13 -05:00
|
|
|
if levelPreset > spec.endPresetIndex {
|
|
|
|
levelPreset = spec.endPresetIndex
|
|
|
|
}
|
|
|
|
}
|
|
|
|
v.levelPreset = levelPreset
|
|
|
|
}
|
|
|
|
}
|
2019-11-13 14:26:42 -05:00
|
|
|
|
|
|
|
if n == 0 {
|
|
|
|
v.mapEngine.GenerateAct1Overworld()
|
2019-11-17 16:06:02 -05:00
|
|
|
} else {
|
|
|
|
v.mapEngine = d2mapengine.CreateMapEngine(v.gameState, v.soundManager, v.fileProvider) // necessary for map name update
|
|
|
|
v.mapEngine.GenerateMap(d2enum.RegionIdType(n), levelPreset, fileIndex)
|
2019-11-13 14:26:42 -05:00
|
|
|
}
|
2019-12-13 00:33:11 -05:00
|
|
|
|
|
|
|
v.mapEngine.MoveCameraTo(v.mapEngine.WorldToOrtho(v.mapEngine.GetCenterPosition()))
|
2019-11-13 14:26:42 -05:00
|
|
|
}
|
|
|
|
|
2019-10-27 19:00:38 -04:00
|
|
|
func (v *MapEngineTest) Load() []func() {
|
2019-10-31 13:39:05 -04:00
|
|
|
// TODO: Game seed comes from the game state object
|
2019-10-31 21:17:13 -04:00
|
|
|
|
2019-10-27 21:35:16 -04:00
|
|
|
v.soundManager.PlayBGM("")
|
|
|
|
return []func(){
|
|
|
|
func() {
|
2019-11-17 01:14:58 -05:00
|
|
|
v.mapEngine = d2mapengine.CreateMapEngine(v.gameState, v.soundManager, v.fileProvider)
|
2019-11-17 00:52:13 -05:00
|
|
|
v.LoadRegionByIndex(v.currentRegion, v.levelPreset, v.fileIndex)
|
2019-10-27 21:35:16 -04:00
|
|
|
},
|
|
|
|
}
|
2019-10-27 19:00:38 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func (v *MapEngineTest) Unload() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *MapEngineTest) Render(screen *ebiten.Image) {
|
2019-10-31 21:17:13 -04:00
|
|
|
v.mapEngine.Render(screen)
|
2019-12-13 00:33:11 -05:00
|
|
|
screenX := v.uiManager.CursorX
|
|
|
|
screenY := v.uiManager.CursorY
|
|
|
|
worldX, worldY := v.mapEngine.ScreenToWorld(screenX, screenY)
|
|
|
|
subtileX := int(math.Ceil(math.Mod((worldX*10), 10))) / 2
|
|
|
|
subtileY := int(math.Ceil(math.Mod((worldY*10), 10))) / 2
|
|
|
|
curRegion := v.mapEngine.GetRegionAtTile(int(worldX), int(worldY))
|
2019-11-06 18:25:19 -05:00
|
|
|
if curRegion == nil {
|
|
|
|
return
|
|
|
|
}
|
2019-12-13 00:33:11 -05:00
|
|
|
|
|
|
|
tileRect := curRegion.GetTileRect()
|
2019-11-06 21:25:09 -05:00
|
|
|
line := fmt.Sprintf("%d, %d (Tile %d.%d, %d.%d)",
|
2019-12-13 00:33:11 -05:00
|
|
|
screenX,
|
|
|
|
screenY,
|
|
|
|
int(math.Floor(worldX))-tileRect.Left,
|
2019-11-06 21:25:09 -05:00
|
|
|
subtileX,
|
2019-12-13 00:33:11 -05:00
|
|
|
int(math.Floor(worldY))-tileRect.Top,
|
2019-11-06 21:25:09 -05:00
|
|
|
subtileY,
|
|
|
|
)
|
2019-11-17 00:52:13 -05:00
|
|
|
|
|
|
|
levelFilesToPick := make([]string, 0)
|
|
|
|
fileIndex := v.fileIndex
|
2019-12-13 00:33:11 -05:00
|
|
|
levelPreset := curRegion.GetLevelPreset()
|
|
|
|
regionPath := curRegion.GetPath()
|
|
|
|
for n, fileRecord := range levelPreset.Files {
|
2019-11-17 00:52:13 -05:00
|
|
|
if len(fileRecord) == 0 || fileRecord == "" || fileRecord == "0" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
levelFilesToPick = append(levelFilesToPick, fileRecord)
|
2019-12-13 00:33:11 -05:00
|
|
|
if fileRecord == regionPath {
|
2019-11-17 00:52:13 -05:00
|
|
|
fileIndex = n
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if v.fileIndex == -1 {
|
|
|
|
v.fileIndex = fileIndex
|
|
|
|
}
|
|
|
|
v.filesCount = len(levelFilesToPick)
|
2019-11-06 21:25:09 -05:00
|
|
|
ebitenutil.DebugPrintAt(screen, line, 5, 5)
|
2019-12-13 00:33:11 -05:00
|
|
|
ebitenutil.DebugPrintAt(screen, "Map: "+curRegion.GetLevelType().Name, 5, 17)
|
|
|
|
ebitenutil.DebugPrintAt(screen, fmt.Sprintf("%v: %v/%v [%v, %v]", regionPath, fileIndex+1, v.filesCount, v.currentRegion, v.levelPreset), 5, 29)
|
2019-11-17 00:52:13 -05:00
|
|
|
ebitenutil.DebugPrintAt(screen, "N - next region, P - previous region", 5, 41)
|
|
|
|
ebitenutil.DebugPrintAt(screen, "Shift+N - next preset, Shift+P - previous preset", 5, 53)
|
|
|
|
ebitenutil.DebugPrintAt(screen, "Ctrl+N - next file, Ctrl+P - previous file", 5, 65)
|
2019-10-27 19:00:38 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func (v *MapEngineTest) Update(tickTime float64) {
|
2019-12-13 00:33:11 -05:00
|
|
|
v.mapEngine.Advance(tickTime)
|
|
|
|
|
2019-11-17 00:52:13 -05:00
|
|
|
ctrlPressed := v.uiManager.KeyPressed(ebiten.KeyControl)
|
|
|
|
shiftPressed := v.uiManager.KeyPressed(ebiten.KeyShift)
|
|
|
|
|
2019-12-08 22:18:42 -05:00
|
|
|
var moveSpeed float64 = 800
|
|
|
|
if v.uiManager.KeyPressed(ebiten.KeyShift) {
|
|
|
|
moveSpeed = 200
|
|
|
|
}
|
|
|
|
|
2019-11-01 14:12:23 -04:00
|
|
|
if v.uiManager.KeyPressed(ebiten.KeyDown) {
|
2019-12-08 22:18:42 -05:00
|
|
|
v.mapEngine.MoveCameraBy(0, moveSpeed*tickTime)
|
2019-11-01 14:12:23 -04:00
|
|
|
}
|
|
|
|
if v.uiManager.KeyPressed(ebiten.KeyUp) {
|
2019-12-08 22:18:42 -05:00
|
|
|
v.mapEngine.MoveCameraBy(0, -moveSpeed*tickTime)
|
2019-11-01 14:12:23 -04:00
|
|
|
}
|
|
|
|
if v.uiManager.KeyPressed(ebiten.KeyLeft) {
|
2019-12-08 22:18:42 -05:00
|
|
|
v.mapEngine.MoveCameraBy(-moveSpeed*tickTime, 0)
|
2019-11-01 14:12:23 -04:00
|
|
|
}
|
|
|
|
if v.uiManager.KeyPressed(ebiten.KeyRight) {
|
2019-12-08 22:18:42 -05:00
|
|
|
v.mapEngine.MoveCameraBy(moveSpeed*tickTime, 0)
|
2019-11-01 14:12:23 -04:00
|
|
|
}
|
2019-11-15 09:04:27 -05:00
|
|
|
|
|
|
|
if inpututil.IsKeyJustPressed(ebiten.KeyF7) {
|
2019-12-13 00:33:11 -05:00
|
|
|
if v.debugVisLevel < 2 {
|
|
|
|
v.debugVisLevel++
|
2019-11-15 09:04:27 -05:00
|
|
|
} else {
|
2019-12-13 00:33:11 -05:00
|
|
|
v.debugVisLevel = 0
|
2019-11-15 09:04:27 -05:00
|
|
|
}
|
2019-12-13 00:33:11 -05:00
|
|
|
|
|
|
|
v.mapEngine.SetDebugVisLevel(v.debugVisLevel)
|
2019-11-15 09:04:27 -05:00
|
|
|
}
|
|
|
|
|
2019-11-13 14:26:42 -05:00
|
|
|
if v.uiManager.KeyPressed(ebiten.KeyEscape) {
|
|
|
|
os.Exit(0)
|
|
|
|
}
|
2019-11-17 00:52:13 -05:00
|
|
|
|
2019-11-17 08:09:54 -05:00
|
|
|
if inpututil.IsKeyJustPressed(ebiten.KeyN) && ctrlPressed {
|
|
|
|
v.fileIndex = increment(v.fileIndex, 0, v.filesCount-1)
|
|
|
|
v.sceneProvider.SetNextScene(v)
|
|
|
|
return
|
|
|
|
}
|
2019-11-17 00:52:13 -05:00
|
|
|
|
2019-11-17 08:09:54 -05:00
|
|
|
if inpututil.IsKeyJustPressed(ebiten.KeyP) && ctrlPressed {
|
|
|
|
v.fileIndex = decrement(v.fileIndex, 0, v.filesCount-1)
|
|
|
|
v.sceneProvider.SetNextScene(v)
|
|
|
|
return
|
|
|
|
}
|
2019-11-17 00:52:13 -05:00
|
|
|
|
2019-11-17 08:09:54 -05:00
|
|
|
if inpututil.IsKeyJustPressed(ebiten.KeyN) && shiftPressed {
|
|
|
|
v.levelPreset = increment(v.levelPreset, v.regionSpec.startPresetIndex, v.regionSpec.endPresetIndex)
|
|
|
|
v.sceneProvider.SetNextScene(v)
|
|
|
|
return
|
|
|
|
}
|
2019-11-17 00:52:13 -05:00
|
|
|
|
2019-11-17 08:09:54 -05:00
|
|
|
if inpututil.IsKeyJustPressed(ebiten.KeyP) && shiftPressed {
|
|
|
|
v.levelPreset = decrement(v.levelPreset, v.regionSpec.startPresetIndex, v.regionSpec.endPresetIndex)
|
|
|
|
v.sceneProvider.SetNextScene(v)
|
|
|
|
return
|
|
|
|
}
|
2019-11-17 00:52:13 -05:00
|
|
|
|
2019-11-17 08:09:54 -05:00
|
|
|
if inpututil.IsKeyJustPressed(ebiten.KeyN) {
|
|
|
|
v.currentRegion = increment(v.currentRegion, 0, len(regions))
|
|
|
|
v.sceneProvider.SetNextScene(v)
|
|
|
|
return
|
2019-11-13 14:26:42 -05:00
|
|
|
}
|
|
|
|
|
2019-11-17 08:09:54 -05:00
|
|
|
if inpututil.IsKeyJustPressed(ebiten.KeyP) {
|
|
|
|
v.currentRegion = decrement(v.currentRegion, 0, len(regions))
|
|
|
|
v.sceneProvider.SetNextScene(v)
|
|
|
|
return
|
2019-11-13 14:26:42 -05:00
|
|
|
}
|
2019-10-27 19:00:38 -04:00
|
|
|
}
|
2019-11-17 00:52:13 -05:00
|
|
|
|
|
|
|
func increment(v, min, max int) int {
|
|
|
|
v++
|
|
|
|
if v > max {
|
|
|
|
return min
|
|
|
|
}
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
|
|
|
|
func decrement(v, min, max int) int {
|
|
|
|
v--
|
|
|
|
if v < min {
|
|
|
|
return max
|
|
|
|
}
|
|
|
|
return v
|
|
|
|
}
|