mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-06-12 18:50:42 +00:00
fe47e51351
* WIP refactor of d2map stuff * more d2map refactor adding realm init to game client passing map engine from client and server into realm at init change `generate map packet` to have act and level index as data * client explodes, but getting there * realm now initializes, networking works, but map generators dont currently do anything * changed the way that level type records are loaded * fixed funcs for level data lookups * started implementing level generator, currently crashing * client no longer exploding * d2networking refactor put exports into d2client.go and d2server.go kept GameClient and GameServer methods into their respective files made methods for packet handlers instead of the giant switch statements * bugfix: getting first level id by act * minor refactor of gamescreen for readability * towns now generate on server start, create player takes act and level id as args, levels have their own map engine
152 lines
4.6 KiB
Go
152 lines
4.6 KiB
Go
package d2mapstamp
|
|
|
|
import (
|
|
"math"
|
|
"math/rand"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapentity"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2ds1"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dt1"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
|
)
|
|
|
|
// Represents a pre-fabricated map stamp that can be placed on a map
|
|
type Stamp struct {
|
|
regionPath string // The file path of the region
|
|
levelType *d2datadict.LevelTypeRecord // The level type id for this stamp
|
|
levelPreset *d2datadict.LevelPresetRecord // The level preset id for this stamp
|
|
tiles []d2dt1.Tile // The tiles contained on this stamp
|
|
ds1 *d2ds1.DS1 // The backing DS1 file for this stamp
|
|
}
|
|
|
|
// Loads a stamp based on the supplied parameters
|
|
func LoadStamp(levelType d2enum.RegionIdType, levelPreset int, fileIndex int) *Stamp {
|
|
stamp := &Stamp{
|
|
levelType: d2datadict.LevelTypes[levelType],
|
|
levelPreset: d2datadict.LevelPresets[levelPreset],
|
|
}
|
|
for _, levelTypeDt1 := range stamp.levelType.Files {
|
|
if len(levelTypeDt1) != 0 && levelTypeDt1 != "" && levelTypeDt1 != "0" {
|
|
fileData, err := d2asset.LoadFile("/data/global/tiles/" + levelTypeDt1)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
dt1, _ := d2dt1.LoadDT1(fileData)
|
|
|
|
stamp.tiles = append(stamp.tiles, dt1.Tiles...)
|
|
}
|
|
}
|
|
|
|
var levelFilesToPick []string
|
|
for _, fileRecord := range stamp.levelPreset.Files {
|
|
if len(fileRecord) != 0 && fileRecord != "" && fileRecord != "0" {
|
|
levelFilesToPick = append(levelFilesToPick, fileRecord)
|
|
}
|
|
}
|
|
|
|
levelIndex := int(math.Round(float64(len(levelFilesToPick)-1) * rand.Float64()))
|
|
if fileIndex >= 0 && fileIndex < len(levelFilesToPick) {
|
|
levelIndex = fileIndex
|
|
}
|
|
|
|
if levelFilesToPick == nil {
|
|
panic("no level files to pick from")
|
|
}
|
|
|
|
stamp.regionPath = levelFilesToPick[levelIndex]
|
|
fileData, err := d2asset.LoadFile("/data/global/tiles/" + stamp.regionPath)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
stamp.ds1, _ = d2ds1.LoadDS1(fileData)
|
|
|
|
// Update the region info for the tiles
|
|
for rx := 0; rx < len(stamp.ds1.Tiles); rx++ {
|
|
for x := 0; x < len(stamp.ds1.Tiles[rx]); x++ {
|
|
stamp.ds1.Tiles[rx][x].RegionType = levelType
|
|
}
|
|
}
|
|
|
|
return stamp
|
|
}
|
|
|
|
// Returns the size of the stamp, in tiles
|
|
func (mr *Stamp) Size() d2common.Size {
|
|
return d2common.Size{int(mr.ds1.Width), int(mr.ds1.Height)}
|
|
}
|
|
|
|
// Gets the level preset id
|
|
func (mr *Stamp) LevelPreset() *d2datadict.LevelPresetRecord {
|
|
return mr.levelPreset
|
|
}
|
|
|
|
// Returns the level type id
|
|
func (mr *Stamp) LevelType() *d2datadict.LevelTypeRecord {
|
|
return mr.levelType
|
|
}
|
|
|
|
// Gets the file path of the region
|
|
func (mr *Stamp) RegionPath() string {
|
|
return mr.regionPath
|
|
}
|
|
|
|
// Returns the specified tile
|
|
func (mr *Stamp) Tile(x, y int) *d2ds1.TileRecord {
|
|
return &mr.ds1.Tiles[y][x]
|
|
}
|
|
|
|
// Returns tile data based on the supplied paramters
|
|
func (mr *Stamp) TileData(style int32, sequence int32, tileType d2enum.TileType) *d2dt1.Tile {
|
|
for _, tile := range mr.tiles {
|
|
if tile.Style == style && tile.Sequence == sequence && tile.Type == int32(tileType) {
|
|
return &tile
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (mr *Stamp) Entities(tileOffsetX, tileOffsetY int) []d2mapentity.MapEntity {
|
|
entities := make([]d2mapentity.MapEntity, 0)
|
|
|
|
for _, object := range mr.ds1.Objects {
|
|
|
|
switch object.Lookup.Type {
|
|
case d2datadict.ObjectTypeCharacter:
|
|
if object.Lookup.Base != "" && object.Lookup.Token != "" && object.Lookup.TR != "" {
|
|
npc := d2mapentity.CreateNPC((tileOffsetX*5)+object.X, (tileOffsetY*5)+object.Y, object.Lookup, 0)
|
|
npc.SetPaths(convertPaths(tileOffsetX, tileOffsetY, object.Paths))
|
|
entities = append(entities, npc)
|
|
}
|
|
case d2datadict.ObjectTypeItem:
|
|
if object.ObjectInfo != nil && object.ObjectInfo.Draw && object.Lookup.Base != "" && object.Lookup.Token != "" {
|
|
entity, err := d2mapentity.CreateObject((tileOffsetX*5)+object.X, (tileOffsetY*5)+object.Y, object.Lookup, d2resource.PaletteUnits)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
entity.SetMode(object.Lookup.Mode, object.Lookup.Class, 0)
|
|
entities = append(entities, entity)
|
|
}
|
|
}
|
|
}
|
|
|
|
return entities
|
|
}
|
|
|
|
func convertPaths(tileOffsetX, tileOffsetY int, paths []d2common.Path) []d2common.Path {
|
|
result := make([]d2common.Path, len(paths))
|
|
for i := 0; i < len(paths); i++ {
|
|
result[i].Action = paths[i].Action
|
|
result[i].X = paths[i].X + (tileOffsetX * 5)
|
|
result[i].Y = paths[i].Y + (tileOffsetY * 5)
|
|
}
|
|
|
|
return result
|
|
}
|