mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-10-15 14:44:49 -04: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
165 lines
4.6 KiB
Go
165 lines
4.6 KiB
Go
package d2client
|
|
|
|
import (
|
|
"log"
|
|
"os"
|
|
|
|
// "github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapgen"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapengine"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapentity"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2maprenderer"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2game/d2player"
|
|
d2cct "github.com/OpenDiablo2/OpenDiablo2/d2networking/d2client/d2clientconnectiontype"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket/d2netpackettype"
|
|
)
|
|
|
|
type GameClient struct {
|
|
clientConnection ClientConnection
|
|
connectionType d2cct.ClientConnectionType
|
|
GameState *d2player.PlayerState
|
|
MapEngine *d2mapengine.MapEngine
|
|
MapRenderer *d2maprenderer.MapRenderer
|
|
realm *d2mapengine.MapRealm
|
|
PlayerId string
|
|
Players map[string]*d2mapentity.Player
|
|
Seed int64
|
|
RegenMap bool
|
|
}
|
|
|
|
// Using the `clientConnection`, opens a connection and passes the savefile path
|
|
func (g *GameClient) Open(connectionString string, saveFilePath string) error {
|
|
return g.clientConnection.Open(connectionString, saveFilePath)
|
|
}
|
|
|
|
// Closes the `clientConnection`
|
|
func (g *GameClient) Close() error {
|
|
return g.clientConnection.Close()
|
|
}
|
|
|
|
// Closes the `clientConnection`
|
|
func (g *GameClient) Destroy() error {
|
|
return g.clientConnection.Close()
|
|
}
|
|
|
|
// Routes the incoming packets to the packet handlers
|
|
func (g *GameClient) OnPacketReceived(packet d2netpacket.NetPacket) error {
|
|
switch packet.PacketType {
|
|
|
|
// UNSURE: should we be bubbling up errors from these handler calls?
|
|
case d2netpackettype.UpdateServerInfo:
|
|
g.handleUpdateServerInfo(packet)
|
|
|
|
case d2netpackettype.AddPlayer:
|
|
g.handleAddPlayer(packet)
|
|
|
|
case d2netpackettype.GenerateMap:
|
|
g.handleGenerateMap(packet)
|
|
|
|
case d2netpackettype.MovePlayer:
|
|
g.handleMovePlayer(packet)
|
|
|
|
case d2netpackettype.Ping:
|
|
g.handlePong(packet)
|
|
|
|
case d2netpackettype.ServerClosed:
|
|
g.handleServerClosed(packet)
|
|
|
|
default:
|
|
log.Fatalf("Invalid packet type: %d", packet.PacketType)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Using the `clientConnection`, sends a packet to the server
|
|
func (g *GameClient) SendPacketToServer(packet d2netpacket.NetPacket) error {
|
|
return g.clientConnection.SendPacketToServer(packet)
|
|
}
|
|
|
|
func (g *GameClient) handleUpdateServerInfo(p d2netpacket.NetPacket) {
|
|
serverInfo := p.PacketData.(d2netpacket.UpdateServerInfoPacket)
|
|
seed := serverInfo.Seed
|
|
playerId := serverInfo.PlayerId
|
|
|
|
g.Seed = seed
|
|
g.realm.Init(seed)
|
|
g.PlayerId = playerId
|
|
|
|
log.Printf("Player id set to %s", playerId)
|
|
}
|
|
|
|
func (g *GameClient) handleAddPlayer(p d2netpacket.NetPacket) {
|
|
player := p.PacketData.(d2netpacket.AddPlayerPacket)
|
|
levelId := g.realm.GetFirstActLevelId(player.Act)
|
|
g.MapEngine = g.realm.GetMapEngine(player.Act, levelId)
|
|
|
|
pId := player.Id
|
|
pName := player.Name
|
|
pAct := player.Act
|
|
pLvlId := levelId
|
|
pX := player.X
|
|
pY := player.Y
|
|
pDir := 0
|
|
pHero := player.HeroType
|
|
pStat := player.Stats
|
|
pEquip := player.Equipment
|
|
|
|
// UNSURE: maybe we should be passing a struct instead of all the vars?
|
|
newPlayer := d2mapentity.CreatePlayer(
|
|
pId, pName, pAct, pLvlId, pX, pY, pDir, pHero, pStat, pEquip,
|
|
)
|
|
|
|
g.Players[newPlayer.Id] = newPlayer
|
|
g.realm.AddPlayer(pId, pAct)
|
|
g.MapEngine.AddEntity(newPlayer)
|
|
}
|
|
|
|
func (g *GameClient) handleGenerateMap(p d2netpacket.NetPacket) {
|
|
mapData := p.PacketData.(d2netpacket.GenerateMapPacket)
|
|
g.realm.GenerateMap(mapData.ActId, mapData.LevelId)
|
|
engine := g.realm.GetMapEngine(mapData.ActId, mapData.LevelId)
|
|
g.MapRenderer = d2maprenderer.CreateMapRenderer(engine)
|
|
g.RegenMap = true
|
|
}
|
|
|
|
func (g *GameClient) handleMovePlayer(p d2netpacket.NetPacket) {
|
|
movePlayer := p.PacketData.(d2netpacket.MovePlayerPacket)
|
|
|
|
player := g.Players[movePlayer.PlayerId]
|
|
x1, y1 := movePlayer.StartX, movePlayer.StartY
|
|
x2, y2 := movePlayer.DestX, movePlayer.DestY
|
|
|
|
path, _, _ := g.MapEngine.PathFind(x1, y1, x2, y2)
|
|
|
|
if len(path) > 0 {
|
|
player.SetPath(path, func() {
|
|
tile := g.MapEngine.TileAt(player.TileX, player.TileY)
|
|
if tile == nil {
|
|
return
|
|
}
|
|
|
|
regionType := tile.RegionType
|
|
if regionType == d2enum.RegionAct1Town {
|
|
player.SetIsInTown(true)
|
|
} else {
|
|
player.SetIsInTown(false)
|
|
}
|
|
player.SetAnimationMode(player.GetAnimationMode().String())
|
|
})
|
|
}
|
|
}
|
|
|
|
func (g *GameClient) handlePong(p d2netpacket.NetPacket) {
|
|
pong := d2netpacket.CreatePongPacket(g.PlayerId)
|
|
g.clientConnection.SendPacketToServer(pong)
|
|
}
|
|
|
|
func (g *GameClient) handleServerClosed(p d2netpacket.NetPacket) {
|
|
// TODO: Need to be tied into a character save and exit
|
|
log.Print("Server has been closed")
|
|
os.Exit(0)
|
|
}
|