mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-11-02 09:17:19 -04:00
e70378d627
* Scroll slowly in map test by holding shift * Increase draw distance up and down Avoid issues with long tiles popping in and out of view. (As long as camera is reasonably within bounds)
313 lines
9.0 KiB
Go
313 lines
9.0 KiB
Go
package d2scene
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"os"
|
|
|
|
"github.com/OpenDiablo2/D2Shared/d2helper"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core"
|
|
|
|
"github.com/OpenDiablo2/D2Shared/d2common/d2interface"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2corecommon/d2coreinterface"
|
|
|
|
"github.com/OpenDiablo2/D2Shared/d2common/d2enum"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2audio"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2render/d2mapengine"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2render/d2ui"
|
|
"github.com/hajimehoshi/ebiten"
|
|
"github.com/hajimehoshi/ebiten/ebitenutil"
|
|
"github.com/hajimehoshi/ebiten/inpututil"
|
|
)
|
|
|
|
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{}},
|
|
}
|
|
|
|
type MapEngineTest struct {
|
|
uiManager *d2ui.Manager
|
|
soundManager *d2audio.Manager
|
|
fileProvider d2interface.FileProvider
|
|
sceneProvider d2coreinterface.SceneProvider
|
|
gameState *d2core.GameState
|
|
mapEngine *d2mapengine.Engine
|
|
|
|
//TODO: this is region specific properties, should be refactored for multi-region rendering
|
|
currentRegion int
|
|
levelPreset int
|
|
fileIndex int
|
|
regionSpec RegionSpec
|
|
filesCount int
|
|
}
|
|
|
|
func CreateMapEngineTest(
|
|
fileProvider d2interface.FileProvider,
|
|
sceneProvider d2coreinterface.SceneProvider,
|
|
uiManager *d2ui.Manager,
|
|
soundManager *d2audio.Manager,
|
|
currentRegion int, levelPreset int) *MapEngineTest {
|
|
result := &MapEngineTest{
|
|
fileProvider: fileProvider,
|
|
uiManager: uiManager,
|
|
soundManager: soundManager,
|
|
sceneProvider: sceneProvider,
|
|
currentRegion: currentRegion,
|
|
levelPreset: levelPreset,
|
|
fileIndex: 0,
|
|
regionSpec: RegionSpec{},
|
|
filesCount: 0,
|
|
}
|
|
result.gameState = d2core.CreateTestGameState()
|
|
return result
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
if levelPreset > spec.endPresetIndex {
|
|
levelPreset = spec.endPresetIndex
|
|
}
|
|
}
|
|
v.levelPreset = levelPreset
|
|
}
|
|
}
|
|
|
|
if n == 0 {
|
|
v.mapEngine.GenerateAct1Overworld()
|
|
} else {
|
|
v.mapEngine = d2mapengine.CreateMapEngine(v.gameState, v.soundManager, v.fileProvider) // necessary for map name update
|
|
v.mapEngine.GenerateMap(d2enum.RegionIdType(n), levelPreset, fileIndex)
|
|
}
|
|
isox, isoy := d2helper.IsoToScreen(v.mapEngine.GetRegion(0).Rect.Width/2,
|
|
v.mapEngine.GetRegion(0).Rect.Height/2, 0, 0)
|
|
v.mapEngine.CenterCameraOn(float64(isox), float64(isoy))
|
|
}
|
|
|
|
func (v *MapEngineTest) Load() []func() {
|
|
// TODO: Game seed comes from the game state object
|
|
|
|
v.soundManager.PlayBGM("")
|
|
return []func(){
|
|
func() {
|
|
v.mapEngine = d2mapengine.CreateMapEngine(v.gameState, v.soundManager, v.fileProvider)
|
|
v.LoadRegionByIndex(v.currentRegion, v.levelPreset, v.fileIndex)
|
|
},
|
|
}
|
|
}
|
|
|
|
func (v *MapEngineTest) Unload() {
|
|
|
|
}
|
|
|
|
func (v *MapEngineTest) Render(screen *ebiten.Image) {
|
|
v.mapEngine.Render(screen)
|
|
actualX := float64(v.uiManager.CursorX) - v.mapEngine.OffsetX
|
|
actualY := float64(v.uiManager.CursorY) - v.mapEngine.OffsetY
|
|
tileX, tileY := d2helper.ScreenToIso(actualX, actualY)
|
|
subtileX := int(math.Ceil(math.Mod((tileX*10), 10))) / 2
|
|
subtileY := int(math.Ceil(math.Mod((tileY*10), 10))) / 2
|
|
curRegion := v.mapEngine.GetRegionAt(int(tileX), int(tileY))
|
|
if curRegion == nil {
|
|
return
|
|
}
|
|
line := fmt.Sprintf("%d, %d (Tile %d.%d, %d.%d)",
|
|
int(math.Ceil(actualX)),
|
|
int(math.Ceil(actualY)),
|
|
int(math.Floor(tileX))-curRegion.Rect.Left,
|
|
subtileX,
|
|
int(math.Floor(tileY))-curRegion.Rect.Top,
|
|
subtileY,
|
|
)
|
|
|
|
levelFilesToPick := make([]string, 0)
|
|
fileIndex := v.fileIndex
|
|
for n, fileRecord := range curRegion.Region.LevelPreset.Files {
|
|
if len(fileRecord) == 0 || fileRecord == "" || fileRecord == "0" {
|
|
continue
|
|
}
|
|
levelFilesToPick = append(levelFilesToPick, fileRecord)
|
|
if fileRecord == curRegion.Region.RegionPath {
|
|
fileIndex = n
|
|
}
|
|
}
|
|
if v.fileIndex == -1 {
|
|
v.fileIndex = fileIndex
|
|
}
|
|
v.filesCount = len(levelFilesToPick)
|
|
ebitenutil.DebugPrintAt(screen, line, 5, 5)
|
|
ebitenutil.DebugPrintAt(screen, "Map: "+curRegion.Region.LevelType.Name, 5, 17)
|
|
ebitenutil.DebugPrintAt(screen, fmt.Sprintf("%v: %v/%v [%v, %v]", curRegion.Region.RegionPath, fileIndex+1, v.filesCount, v.currentRegion, v.levelPreset), 5, 29)
|
|
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)
|
|
}
|
|
|
|
func (v *MapEngineTest) Update(tickTime float64) {
|
|
ctrlPressed := v.uiManager.KeyPressed(ebiten.KeyControl)
|
|
shiftPressed := v.uiManager.KeyPressed(ebiten.KeyShift)
|
|
|
|
if v.uiManager.KeyPressed(ebiten.KeyDown) {
|
|
if v.uiManager.KeyPressed(ebiten.KeyShift) {
|
|
v.mapEngine.OffsetY -= tickTime * 200
|
|
} else {
|
|
v.mapEngine.OffsetY -= tickTime * 800
|
|
}
|
|
}
|
|
if v.uiManager.KeyPressed(ebiten.KeyUp) {
|
|
if v.uiManager.KeyPressed(ebiten.KeyShift) {
|
|
v.mapEngine.OffsetY += tickTime * 200
|
|
} else {
|
|
v.mapEngine.OffsetY += tickTime * 800
|
|
}
|
|
}
|
|
if v.uiManager.KeyPressed(ebiten.KeyLeft) {
|
|
if v.uiManager.KeyPressed(ebiten.KeyShift) {
|
|
v.mapEngine.OffsetX += tickTime * 200
|
|
} else {
|
|
v.mapEngine.OffsetX += tickTime * 800
|
|
}
|
|
}
|
|
if v.uiManager.KeyPressed(ebiten.KeyRight) {
|
|
if v.uiManager.KeyPressed(ebiten.KeyShift) {
|
|
v.mapEngine.OffsetX -= tickTime * 200
|
|
} else {
|
|
v.mapEngine.OffsetX -= tickTime * 800
|
|
}
|
|
}
|
|
|
|
if inpututil.IsKeyJustPressed(ebiten.KeyF7) {
|
|
if v.mapEngine.ShowTiles < 2 {
|
|
v.mapEngine.ShowTiles++
|
|
} else {
|
|
v.mapEngine.ShowTiles = 0
|
|
}
|
|
}
|
|
|
|
if v.uiManager.KeyPressed(ebiten.KeyEscape) {
|
|
os.Exit(0)
|
|
}
|
|
|
|
if inpututil.IsKeyJustPressed(ebiten.KeyN) && ctrlPressed {
|
|
v.fileIndex = increment(v.fileIndex, 0, v.filesCount-1)
|
|
v.sceneProvider.SetNextScene(v)
|
|
return
|
|
}
|
|
|
|
if inpututil.IsKeyJustPressed(ebiten.KeyP) && ctrlPressed {
|
|
v.fileIndex = decrement(v.fileIndex, 0, v.filesCount-1)
|
|
v.sceneProvider.SetNextScene(v)
|
|
return
|
|
}
|
|
|
|
if inpututil.IsKeyJustPressed(ebiten.KeyN) && shiftPressed {
|
|
v.levelPreset = increment(v.levelPreset, v.regionSpec.startPresetIndex, v.regionSpec.endPresetIndex)
|
|
v.sceneProvider.SetNextScene(v)
|
|
return
|
|
}
|
|
|
|
if inpututil.IsKeyJustPressed(ebiten.KeyP) && shiftPressed {
|
|
v.levelPreset = decrement(v.levelPreset, v.regionSpec.startPresetIndex, v.regionSpec.endPresetIndex)
|
|
v.sceneProvider.SetNextScene(v)
|
|
return
|
|
}
|
|
|
|
if inpututil.IsKeyJustPressed(ebiten.KeyN) {
|
|
v.currentRegion = increment(v.currentRegion, 0, len(regions))
|
|
v.sceneProvider.SetNextScene(v)
|
|
return
|
|
}
|
|
|
|
if inpututil.IsKeyJustPressed(ebiten.KeyP) {
|
|
v.currentRegion = decrement(v.currentRegion, 0, len(regions))
|
|
v.sceneProvider.SetNextScene(v)
|
|
return
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|