mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-01-11 11:57:44 -05:00
D2core logger (#934)
* logger for d2audio & d2map * logger for d2ui e.t.c * d2inventory now passes on error messages * no more importing log in d2core * implemented #925 * added logger to part of d2networking & fixed "need to be changed" comments * fixed lints * fixed errors Co-authored-by: M. Sz <mszeptuch@protonmail.com>
This commit is contained in:
parent
34f9538afb
commit
9ffbf1320c
12
d2app/app.go
12
d2app/app.go
@ -138,7 +138,7 @@ func (a *App) startDedicatedServer() error {
|
||||
srvChanIn := make(chan int)
|
||||
srvChanLog := make(chan string)
|
||||
|
||||
srvErr := d2networking.StartDedicatedServer(a.asset, srvChanIn, srvChanLog, maxPlayers)
|
||||
srvErr := d2networking.StartDedicatedServer(a.asset, srvChanIn, srvChanLog, a.config.LogLevel, maxPlayers)
|
||||
if srvErr != nil {
|
||||
return srvErr
|
||||
}
|
||||
@ -179,7 +179,7 @@ func (a *App) loadEngine() error {
|
||||
|
||||
a.asset.SetLogLevel(logLevel)
|
||||
|
||||
audio := ebiten2.CreateAudio(a.asset)
|
||||
audio := ebiten2.CreateAudio(a.config.LogLevel, a.asset)
|
||||
|
||||
inputManager := d2input.NewInputManager()
|
||||
|
||||
@ -195,7 +195,7 @@ func (a *App) loadEngine() error {
|
||||
|
||||
scriptEngine := d2script.CreateScriptEngine()
|
||||
|
||||
uiManager := d2ui.NewUIManager(a.asset, renderer, inputManager, audio)
|
||||
uiManager := d2ui.NewUIManager(a.asset, renderer, inputManager, a.config.LogLevel, audio)
|
||||
|
||||
a.inputManager = inputManager
|
||||
a.terminal = term
|
||||
@ -409,14 +409,14 @@ func (a *App) initialize() error {
|
||||
}
|
||||
}
|
||||
|
||||
gui, err := d2gui.CreateGuiManager(a.asset, a.inputManager)
|
||||
gui, err := d2gui.CreateGuiManager(a.asset, a.config.LogLevel, a.inputManager)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
a.guiManager = gui
|
||||
|
||||
a.screen = d2screen.NewScreenManager(a.ui, a.guiManager)
|
||||
a.screen = d2screen.NewScreenManager(a.ui, a.config.LogLevel, a.guiManager)
|
||||
|
||||
a.audio.SetVolumes(a.config.BgmVolume, a.config.SfxVolume)
|
||||
|
||||
@ -931,7 +931,7 @@ func (a *App) ToSelectHero(connType d2clientconnectiontype.ClientConnectionType,
|
||||
|
||||
// ToCreateGame forces the game to transition to the Create Game screen
|
||||
func (a *App) ToCreateGame(filePath string, connType d2clientconnectiontype.ClientConnectionType, host string) {
|
||||
gameClient, err := d2client.Create(connType, a.asset, a.scriptEngine)
|
||||
gameClient, err := d2client.Create(connType, a.asset, a.config.LogLevel, a.scriptEngine)
|
||||
if err != nil {
|
||||
a.logger.Error(err.Error())
|
||||
}
|
||||
|
@ -3,9 +3,9 @@ package ebiten
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/audio"
|
||||
@ -14,14 +14,20 @@ import (
|
||||
|
||||
const sampleRate = 44100
|
||||
|
||||
const logPrefix = "Ebiten Audio Provider"
|
||||
|
||||
var _ d2interface.AudioProvider = &AudioProvider{} // Static check to confirm struct conforms to interface
|
||||
|
||||
// CreateAudio creates an instance of ebiten's audio provider
|
||||
func CreateAudio(am *d2asset.AssetManager) *AudioProvider {
|
||||
func CreateAudio(l d2util.LogLevel, am *d2asset.AssetManager) *AudioProvider {
|
||||
result := &AudioProvider{
|
||||
asset: am,
|
||||
}
|
||||
|
||||
result.Logger = d2util.NewLogger()
|
||||
result.Logger.SetLevel(l)
|
||||
result.Logger.SetPrefix(logPrefix)
|
||||
|
||||
result.audioContext = audio.NewContext(sampleRate)
|
||||
|
||||
return result
|
||||
@ -36,6 +42,8 @@ type AudioProvider struct {
|
||||
lastBgm string
|
||||
sfxVolume float64
|
||||
bgmVolume float64
|
||||
|
||||
*d2util.Logger
|
||||
}
|
||||
|
||||
// PlayBGM loads an audio stream and plays it in the background
|
||||
@ -55,7 +63,7 @@ func (eap *AudioProvider) PlayBGM(song string) {
|
||||
err := eap.bgmAudio.Close()
|
||||
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
eap.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,20 +74,20 @@ func (eap *AudioProvider) PlayBGM(song string) {
|
||||
}
|
||||
|
||||
if _, err = audioStream.Seek(0, io.SeekStart); err != nil {
|
||||
log.Fatal(err)
|
||||
eap.Fatal(err.Error())
|
||||
}
|
||||
|
||||
eap.bgmStream, err = wav.Decode(eap.audioContext, audioStream)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
eap.Fatal(err.Error())
|
||||
}
|
||||
|
||||
s := audio.NewInfiniteLoop(eap.bgmStream, eap.bgmStream.Length())
|
||||
eap.bgmAudio, err = audio.NewPlayer(eap.audioContext, s)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
eap.Fatal(err.Error())
|
||||
}
|
||||
|
||||
eap.bgmAudio.SetVolume(eap.bgmVolume)
|
||||
@ -142,7 +150,7 @@ func (eap *AudioProvider) createSoundEffect(sfx string, context *audio.Context,
|
||||
d, err := wav.Decode(context, audioData)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
eap.Fatal(err.Error())
|
||||
}
|
||||
|
||||
var player *audio.Player
|
||||
@ -157,7 +165,7 @@ func (eap *AudioProvider) createSoundEffect(sfx string, context *audio.Context,
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
eap.Fatal(err.Error())
|
||||
}
|
||||
|
||||
result.player = player
|
||||
|
@ -1,7 +1,7 @@
|
||||
package d2audio
|
||||
|
||||
import (
|
||||
"log"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
@ -9,10 +9,15 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2records"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
)
|
||||
|
||||
type envState int
|
||||
|
||||
const (
|
||||
logPrefix = "Sound Engine"
|
||||
)
|
||||
|
||||
const (
|
||||
envAttack = 0
|
||||
envSustain = 1
|
||||
@ -32,6 +37,8 @@ type Sound struct {
|
||||
vRate float64
|
||||
state envState
|
||||
// panning float64 // lets forget about this for now
|
||||
|
||||
*d2util.Logger
|
||||
}
|
||||
|
||||
func (s *Sound) update(elapsed float64) {
|
||||
@ -66,7 +73,7 @@ func (s *Sound) SetPan(pan float64) {
|
||||
|
||||
// Play the sound
|
||||
func (s *Sound) Play() {
|
||||
log.Println("starting sound", s.entry.Handle)
|
||||
s.Info("starting sound" + s.entry.Handle)
|
||||
s.effect.Play()
|
||||
|
||||
if s.entry.FadeIn != 0 {
|
||||
@ -103,11 +110,13 @@ type SoundEngine struct {
|
||||
timer float64
|
||||
accTime float64
|
||||
sounds map[*Sound]struct{}
|
||||
|
||||
*d2util.Logger
|
||||
}
|
||||
|
||||
// NewSoundEngine creates a new sound engine
|
||||
func NewSoundEngine(provider d2interface.AudioProvider,
|
||||
asset *d2asset.AssetManager, term d2interface.Terminal) *SoundEngine {
|
||||
asset *d2asset.AssetManager, l d2util.LogLevel, term d2interface.Terminal) *SoundEngine {
|
||||
r := SoundEngine{
|
||||
asset: asset,
|
||||
provider: provider,
|
||||
@ -115,11 +124,15 @@ func NewSoundEngine(provider d2interface.AudioProvider,
|
||||
timer: 1,
|
||||
}
|
||||
|
||||
r.Logger = d2util.NewLogger()
|
||||
r.Logger.SetPrefix(logPrefix)
|
||||
r.Logger.SetLevel(l)
|
||||
|
||||
err := term.BindAction("playsoundid", "plays the sound for a given id", func(id int) {
|
||||
r.PlaySoundID(id)
|
||||
})
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
r.Error(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -127,25 +140,25 @@ func NewSoundEngine(provider d2interface.AudioProvider,
|
||||
r.PlaySoundHandle(handle)
|
||||
})
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
r.Error(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
err = term.BindAction("activesounds", "list currently active sounds", func() {
|
||||
for s := range r.sounds {
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
r.Error(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
log.Println(s)
|
||||
r.Info(fmt.Sprint(s))
|
||||
}
|
||||
})
|
||||
|
||||
err = term.BindAction("killsounds", "kill active sounds", func() {
|
||||
for s := range r.sounds {
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
r.Error(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@ -207,13 +220,14 @@ func (s *SoundEngine) PlaySoundID(id int) *Sound {
|
||||
|
||||
effect, err := s.provider.LoadSound(entry.FileName, entry.Loop, entry.MusicVol)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
s.Error(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
snd := Sound{
|
||||
entry: entry,
|
||||
effect: effect,
|
||||
Logger: s.Logger,
|
||||
}
|
||||
|
||||
s.sounds[&snd] = struct{}{}
|
||||
|
@ -1,8 +1,6 @@
|
||||
package d2gui
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
@ -66,6 +64,8 @@ type Box struct {
|
||||
disableBorder bool
|
||||
isOpen bool
|
||||
title string
|
||||
|
||||
*d2util.Logger
|
||||
}
|
||||
|
||||
// NewBox return a new Box instance
|
||||
@ -76,9 +76,10 @@ func NewBox(
|
||||
contentLayout *Layout,
|
||||
width, height int,
|
||||
x, y int,
|
||||
l d2util.LogLevel,
|
||||
title string,
|
||||
) *Box {
|
||||
return &Box{
|
||||
box := &Box{
|
||||
asset: asset,
|
||||
renderer: renderer,
|
||||
uiManager: ui,
|
||||
@ -90,6 +91,12 @@ func NewBox(
|
||||
x: x,
|
||||
y: y,
|
||||
}
|
||||
|
||||
box.Logger = d2util.NewLogger()
|
||||
box.Logger.SetLevel(l)
|
||||
box.Logger.SetPrefix(logPrefix)
|
||||
|
||||
return box
|
||||
}
|
||||
|
||||
// GetLayout returns the box layout
|
||||
@ -145,12 +152,12 @@ func (box *Box) setupTopBorder(offsetY int) {
|
||||
for _, frameIndex := range topEdgePiece {
|
||||
f, err := box.uiManager.NewSprite(d2resource.BoxPieces, d2resource.PaletteSky)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
box.Error(err.Error())
|
||||
}
|
||||
|
||||
err = f.SetCurrentFrame(frameIndex)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
box.Error(err.Error())
|
||||
}
|
||||
|
||||
f.SetPosition(currentX, currentY)
|
||||
@ -187,12 +194,12 @@ func (box *Box) setupBottomBorder(offsetY int) {
|
||||
for _, frameIndex := range bottomEdgePiece {
|
||||
f, err := box.uiManager.NewSprite(d2resource.BoxPieces, d2resource.PaletteSky)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
box.Error(err.Error())
|
||||
}
|
||||
|
||||
err = f.SetCurrentFrame(frameIndex)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
box.Error(err.Error())
|
||||
}
|
||||
|
||||
f.SetPosition(currentX, currentY)
|
||||
@ -227,12 +234,12 @@ func (box *Box) setupLeftBorder() {
|
||||
for _, frameIndex := range leftBorderPiece {
|
||||
f, err := box.uiManager.NewSprite(d2resource.BoxPieces, d2resource.PaletteSky)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
box.Error(err.Error())
|
||||
}
|
||||
|
||||
err = f.SetCurrentFrame(frameIndex)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
box.Error(err.Error())
|
||||
}
|
||||
|
||||
f.SetPosition(currentX, currentY)
|
||||
@ -266,12 +273,12 @@ func (box *Box) setupRightBorder() {
|
||||
for _, frameIndex := range rightBorderPiece {
|
||||
f, err := box.uiManager.NewSprite(d2resource.BoxPieces, d2resource.PaletteSky)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
box.Error(err.Error())
|
||||
}
|
||||
|
||||
err = f.SetCurrentFrame(frameIndex)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
box.Error(err.Error())
|
||||
}
|
||||
|
||||
f.SetPosition(currentX, currentY)
|
||||
@ -302,12 +309,12 @@ func (box *Box) setupCorners() {
|
||||
for _, frameIndex := range cornersFrames {
|
||||
f, err := box.uiManager.NewSprite(d2resource.BoxPieces, d2resource.PaletteSky)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
box.Error(err.Error())
|
||||
}
|
||||
|
||||
err = f.SetCurrentFrame(frameIndex)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
box.Error(err.Error())
|
||||
}
|
||||
|
||||
switch frameIndex {
|
||||
|
@ -2,14 +2,18 @@ package d2gui
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
"log"
|
||||
"math"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
)
|
||||
|
||||
const (
|
||||
logPrefix = "GUI Manager"
|
||||
)
|
||||
|
||||
// GuiManager is a GUI widget manager that handles dynamic layout/positioning of widgets
|
||||
type GuiManager struct {
|
||||
asset *d2asset.AssetManager
|
||||
@ -20,10 +24,12 @@ type GuiManager struct {
|
||||
loadingAnim d2interface.Animation
|
||||
cursorVisible bool
|
||||
loading bool
|
||||
|
||||
*d2util.Logger
|
||||
}
|
||||
|
||||
// CreateGuiManager creates an instance of the GuiManager
|
||||
func CreateGuiManager(asset *d2asset.AssetManager, inputManager d2interface.InputManager) (*GuiManager, error) {
|
||||
func CreateGuiManager(asset *d2asset.AssetManager, l d2util.LogLevel, inputManager d2interface.InputManager) (*GuiManager, error) {
|
||||
cursorAnim, err := asset.LoadAnimation(d2resource.CursorDefault, d2resource.PaletteUnits)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -41,6 +47,10 @@ func CreateGuiManager(asset *d2asset.AssetManager, inputManager d2interface.Inpu
|
||||
cursorVisible: true,
|
||||
}
|
||||
|
||||
manager.Logger = d2util.NewLogger()
|
||||
manager.Logger.SetPrefix(logPrefix)
|
||||
manager.Logger.SetLevel(l)
|
||||
|
||||
manager.clear()
|
||||
|
||||
if err := inputManager.BindHandler(manager); err != nil {
|
||||
@ -159,7 +169,7 @@ func (m *GuiManager) ShowLoadScreen(progress float64) {
|
||||
|
||||
err := animation.SetCurrentFrame(int(float64(frameCount-1) * progress))
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
m.Error(err.Error())
|
||||
}
|
||||
|
||||
m.loading = true
|
||||
|
@ -2,7 +2,6 @@ package d2gui
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
@ -36,7 +35,7 @@ type Label struct {
|
||||
blinkTimer time.Time
|
||||
}
|
||||
|
||||
func createLabel(renderer d2interface.Renderer, text string, font *d2asset.Font, col color.RGBA) *Label {
|
||||
func createLabel(renderer d2interface.Renderer, text string, font *d2asset.Font, col color.RGBA) (*Label, error) {
|
||||
label := &Label{
|
||||
font: font,
|
||||
renderer: renderer,
|
||||
@ -46,13 +45,12 @@ func createLabel(renderer d2interface.Renderer, text string, font *d2asset.Font,
|
||||
|
||||
err := label.setText(text)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label.SetVisible(true)
|
||||
|
||||
return label
|
||||
return label, nil
|
||||
}
|
||||
|
||||
// SetHoverColor will set the value of hoverColor
|
||||
|
@ -2,7 +2,6 @@ package d2gui
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
@ -19,11 +18,13 @@ type LabelButton struct {
|
||||
isHovered bool
|
||||
layout *Layout
|
||||
x, y int
|
||||
|
||||
*d2util.Logger
|
||||
}
|
||||
|
||||
// NewLabelButton generates a new instance of LabelButton
|
||||
func NewLabelButton(x, y int, text string, col color.RGBA, callback func()) *LabelButton {
|
||||
return &LabelButton{
|
||||
func NewLabelButton(x, y int, text string, col color.RGBA, l d2util.LogLevel, callback func()) *LabelButton {
|
||||
lb := &LabelButton{
|
||||
x: x,
|
||||
y: y,
|
||||
hoverColor: col,
|
||||
@ -31,6 +32,12 @@ func NewLabelButton(x, y int, text string, col color.RGBA, callback func()) *Lab
|
||||
callback: callback,
|
||||
canHover: true,
|
||||
}
|
||||
|
||||
lb.Logger = d2util.NewLogger()
|
||||
lb.Logger.SetLevel(l)
|
||||
lb.Logger.SetPrefix(logPrefix)
|
||||
|
||||
return lb
|
||||
}
|
||||
|
||||
// IsInRect checks if the given point is within the overlay layout rectangle
|
||||
@ -60,13 +67,13 @@ func (lb *LabelButton) Load(renderer d2interface.Renderer, asset *d2asset.AssetM
|
||||
|
||||
mainLayout.SetMouseEnterHandler(func(event d2interface.MouseMoveEvent) {
|
||||
if err := l.SetIsHovered(true); err != nil {
|
||||
log.Printf("could not change label to hover state: %v", err)
|
||||
lb.Errorf("could not change label to hover state: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
mainLayout.SetMouseLeaveHandler(func(event d2interface.MouseMoveEvent) {
|
||||
if err := l.SetIsHovered(false); err != nil {
|
||||
log.Printf("could not change label to hover state: %v", err)
|
||||
lb.Errorf("could not change label to hover state: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -167,7 +167,10 @@ func (l *Layout) AddLabel(text string, fontStyle FontStyle) (*Label, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := createLabel(l.renderer, text, font, d2util.Color(ColorWhite))
|
||||
label, err := createLabel(l.renderer, text, font, d2util.Color(ColorWhite))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
l.entries = append(l.entries, &layoutEntry{widget: label})
|
||||
|
||||
@ -181,7 +184,10 @@ func (l *Layout) AddLabelWithColor(text string, fontStyle FontStyle, col color.R
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := createLabel(l.renderer, text, font, col)
|
||||
label, err := createLabel(l.renderer, text, font, col)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
l.entries = append(l.entries, &layoutEntry{widget: label})
|
||||
|
||||
|
@ -2,7 +2,6 @@ package d2hero
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2records"
|
||||
)
|
||||
@ -27,10 +26,10 @@ func (hs *HeroSkill) MarshalJSON() ([]byte, error) {
|
||||
// only serialize the Shallow object instead of the SkillRecord & SkillDescriptionRecord
|
||||
bytes, err := json.Marshal(hs.Shallow)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bytes, err
|
||||
return bytes, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON overrides the default logic used when the HeroSkill is deserialized from a byte array.
|
||||
|
@ -1,7 +1,7 @@
|
||||
package d2inventory
|
||||
|
||||
import (
|
||||
"log"
|
||||
"fmt"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
@ -11,7 +11,10 @@ import (
|
||||
func NewInventoryItemFactory(asset *d2asset.AssetManager) (*InventoryItemFactory, error) {
|
||||
factory := &InventoryItemFactory{asset: asset}
|
||||
|
||||
factory.loadHeroObjects()
|
||||
err := factory.loadHeroObjects()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return factory, nil
|
||||
}
|
||||
@ -23,46 +26,88 @@ type InventoryItemFactory struct {
|
||||
}
|
||||
|
||||
// LoadHeroObjects loads the equipment objects of the hero
|
||||
func (f *InventoryItemFactory) loadHeroObjects() {
|
||||
func (f *InventoryItemFactory) loadHeroObjects() error {
|
||||
// https://github.com/OpenDiablo2/OpenDiablo2/issues/795
|
||||
//Mode: d2enum.AnimationModePlayerNeutral.String(),
|
||||
//Base: "/data/global/chars",
|
||||
shield, err := f.GetArmorItemByCode("buc")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rhhex, err := f.GetWeaponItemByCode("hax")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rhwnd, err := f.GetWeaponItemByCode("wnd")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rhssd, err := f.GetWeaponItemByCode("ssd")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rhktr, err := f.GetWeaponItemByCode("ktr")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rhsst, err := f.GetWeaponItemByCode("sst")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rhjav, err := f.GetWeaponItemByCode("jav")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rhclb, err := f.GetWeaponItemByCode("clb")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.DefaultHeroItems = map[d2enum.Hero]CharacterEquipment{
|
||||
d2enum.HeroBarbarian: {
|
||||
RightHand: f.GetWeaponItemByCode("hax"),
|
||||
Shield: f.GetArmorItemByCode("buc"),
|
||||
RightHand: rhhex,
|
||||
Shield: shield,
|
||||
},
|
||||
d2enum.HeroNecromancer: {
|
||||
RightHand: f.GetWeaponItemByCode("wnd"),
|
||||
RightHand: rhwnd,
|
||||
},
|
||||
d2enum.HeroPaladin: {
|
||||
RightHand: f.GetWeaponItemByCode("ssd"),
|
||||
Shield: f.GetArmorItemByCode("buc"),
|
||||
RightHand: rhssd,
|
||||
Shield: shield,
|
||||
},
|
||||
d2enum.HeroAssassin: {
|
||||
RightHand: f.GetWeaponItemByCode("ktr"),
|
||||
Shield: f.GetArmorItemByCode("buc"),
|
||||
RightHand: rhktr,
|
||||
Shield: shield,
|
||||
},
|
||||
d2enum.HeroSorceress: {
|
||||
RightHand: f.GetWeaponItemByCode("sst"),
|
||||
LeftHand: f.GetWeaponItemByCode("sst"),
|
||||
RightHand: rhsst,
|
||||
LeftHand: rhsst,
|
||||
},
|
||||
d2enum.HeroAmazon: {
|
||||
RightHand: f.GetWeaponItemByCode("jav"),
|
||||
Shield: f.GetArmorItemByCode("buc"),
|
||||
RightHand: rhjav,
|
||||
Shield: shield,
|
||||
},
|
||||
d2enum.HeroDruid: {
|
||||
RightHand: f.GetWeaponItemByCode("clb"),
|
||||
Shield: f.GetArmorItemByCode("buc"),
|
||||
RightHand: rhclb,
|
||||
Shield: shield,
|
||||
},
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetArmorItemByCode returns the armor item for the given code
|
||||
func (f *InventoryItemFactory) GetArmorItemByCode(code string) *InventoryItemArmor {
|
||||
func (f *InventoryItemFactory) GetArmorItemByCode(code string) (*InventoryItemArmor, error) {
|
||||
result := f.asset.Records.Item.Armors[code]
|
||||
if result == nil {
|
||||
log.Fatalf("Could not find armor entry for code '%s'", code)
|
||||
return nil, fmt.Errorf("could not find armor entry for code '%s'", code)
|
||||
}
|
||||
|
||||
return &InventoryItemArmor{
|
||||
@ -71,14 +116,14 @@ func (f *InventoryItemFactory) GetArmorItemByCode(code string) *InventoryItemArm
|
||||
ItemName: result.Name,
|
||||
ItemCode: result.Code,
|
||||
ArmorClass: d2enum.ArmorClassLite, // comes from ArmType.txt
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetMiscItemByCode returns the miscellaneous item for the given code
|
||||
func (f *InventoryItemFactory) GetMiscItemByCode(code string) *InventoryItemMisc {
|
||||
func (f *InventoryItemFactory) GetMiscItemByCode(code string) (*InventoryItemMisc, error) {
|
||||
result := f.asset.Records.Item.Misc[code]
|
||||
if result == nil {
|
||||
log.Fatalf("Could not find misc item entry for code '%s'", code)
|
||||
return nil, fmt.Errorf("could not find misc item entry for code '%s'", code)
|
||||
}
|
||||
|
||||
return &InventoryItemMisc{
|
||||
@ -86,15 +131,15 @@ func (f *InventoryItemFactory) GetMiscItemByCode(code string) *InventoryItemMisc
|
||||
InventorySizeY: result.InventoryHeight,
|
||||
ItemName: result.Name,
|
||||
ItemCode: result.Code,
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetWeaponItemByCode returns the weapon item for the given code
|
||||
func (f *InventoryItemFactory) GetWeaponItemByCode(code string) *InventoryItemWeapon {
|
||||
func (f *InventoryItemFactory) GetWeaponItemByCode(code string) (*InventoryItemWeapon, error) {
|
||||
// https://github.com/OpenDiablo2/OpenDiablo2/issues/796
|
||||
result := f.asset.Records.Item.Weapons[code]
|
||||
if result == nil {
|
||||
log.Fatalf("Could not find weapon entry for code '%s'", code)
|
||||
return nil, fmt.Errorf("could not find weapon entry for code '%s'", code)
|
||||
}
|
||||
|
||||
return &InventoryItemWeapon{
|
||||
@ -104,5 +149,5 @@ func (f *InventoryItemFactory) GetWeaponItemByCode(code string) *InventoryItemWe
|
||||
ItemCode: result.Code,
|
||||
WeaponClass: result.WeaponClass,
|
||||
WeaponClassOffHand: result.WeaponClass2Hand,
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package d2mapengine
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2records"
|
||||
@ -13,10 +12,15 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dt1"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2geom"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapstamp"
|
||||
)
|
||||
|
||||
const (
|
||||
logPrefix = "Map Engine"
|
||||
)
|
||||
|
||||
// MapEngine loads the tiles which make up the isometric map and the entities
|
||||
type MapEngine struct {
|
||||
asset *d2asset.AssetManager
|
||||
@ -34,6 +38,8 @@ type MapEngine struct {
|
||||
|
||||
// https://github.com/OpenDiablo2/OpenDiablo2/issues/789
|
||||
IsLoading bool // (temp) Whether we have processed the GenerateMapPacket(only for remote client)
|
||||
|
||||
*d2util.Logger
|
||||
}
|
||||
|
||||
const (
|
||||
@ -41,9 +47,9 @@ const (
|
||||
)
|
||||
|
||||
// CreateMapEngine creates a new instance of the map engine and returns a pointer to it.
|
||||
func CreateMapEngine(asset *d2asset.AssetManager) *MapEngine {
|
||||
func CreateMapEngine(l d2util.LogLevel, asset *d2asset.AssetManager) *MapEngine {
|
||||
entity, _ := d2mapentity.NewMapEntityFactory(asset)
|
||||
stamp := d2mapstamp.NewStampFactory(asset, entity)
|
||||
stamp := d2mapstamp.NewStampFactory(asset, l, entity)
|
||||
|
||||
engine := &MapEngine{
|
||||
asset: asset,
|
||||
@ -53,6 +59,10 @@ func CreateMapEngine(asset *d2asset.AssetManager) *MapEngine {
|
||||
IsLoading: false,
|
||||
}
|
||||
|
||||
engine.Logger = d2util.NewLogger()
|
||||
engine.Logger.SetLevel(l)
|
||||
engine.Logger.SetPrefix(logPrefix)
|
||||
|
||||
return engine
|
||||
}
|
||||
|
||||
@ -89,14 +99,13 @@ func (m *MapEngine) addDT1(fileName string) {
|
||||
|
||||
fileData, err := m.asset.LoadFile("/data/global/tiles/" + fileName)
|
||||
if err != nil {
|
||||
log.Printf("Could not load /data/global/tiles/%s", fileName)
|
||||
// panic(err)
|
||||
m.Fatalf("Could not load /data/global/tiles/%s", fileName)
|
||||
return
|
||||
}
|
||||
|
||||
dt1, err := d2dt1.LoadDT1(fileData)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
m.Error(err.Error())
|
||||
}
|
||||
|
||||
m.dt1TileData = append(m.dt1TileData, dt1.Tiles...)
|
||||
@ -118,7 +127,7 @@ func (m *MapEngine) AddDS1(fileName string) {
|
||||
|
||||
ds1, err := d2ds1.LoadDS1(fileData)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
m.Error(err.Error())
|
||||
}
|
||||
|
||||
for idx := range ds1.Files {
|
||||
@ -138,7 +147,7 @@ func (m *MapEngine) LevelType() d2records.LevelTypeRecord {
|
||||
|
||||
// SetSeed sets the seed of the map for generation.
|
||||
func (m *MapEngine) SetSeed(seed int64) {
|
||||
log.Printf("Setting map engine seed to %d", seed)
|
||||
m.Infof("Setting map engine seed to %d", seed)
|
||||
m.seed = seed
|
||||
}
|
||||
|
||||
@ -259,7 +268,7 @@ func (m *MapEngine) GetTiles(style, sequence int, tileType d2enum.TileType) []d2
|
||||
}
|
||||
|
||||
if len(tiles) == 0 {
|
||||
log.Printf("Unknown tile ID [%d %d %d]\n", style, sequence, tileType)
|
||||
m.Warningf("Unknown tile ID [%d %d %d]", style, sequence, tileType)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@ package d2mapgen
|
||||
// is experiemental, and mapgen will likely change dramatically in the future.
|
||||
|
||||
import (
|
||||
"log"
|
||||
"math/rand"
|
||||
"strings"
|
||||
|
||||
@ -49,7 +48,7 @@ func (g *MapGenerator) GenerateAct1Overworld() {
|
||||
townStamp.RegionPath()
|
||||
townSize := townStamp.Size()
|
||||
|
||||
log.Printf("Region Path: %s", townStamp.RegionPath())
|
||||
g.Infof("Region Path: %s", townStamp.RegionPath())
|
||||
|
||||
switch {
|
||||
case strings.Contains(townStamp.RegionPath(), "E1"):
|
||||
|
@ -5,17 +5,26 @@ import (
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2geom"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapengine"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapstamp"
|
||||
)
|
||||
|
||||
const (
|
||||
logPrefix = "Map Generator"
|
||||
)
|
||||
|
||||
// NewMapGenerator creates a map generator instance
|
||||
func NewMapGenerator(a *d2asset.AssetManager, e *d2mapengine.MapEngine) (*MapGenerator, error) {
|
||||
func NewMapGenerator(a *d2asset.AssetManager, l d2util.LogLevel, e *d2mapengine.MapEngine) (*MapGenerator, error) {
|
||||
generator := &MapGenerator{
|
||||
asset: a,
|
||||
engine: e,
|
||||
}
|
||||
|
||||
generator.Logger = d2util.NewLogger()
|
||||
generator.Logger.SetLevel(l)
|
||||
generator.Logger.SetPrefix(logPrefix)
|
||||
|
||||
return generator, nil
|
||||
}
|
||||
|
||||
@ -23,6 +32,8 @@ func NewMapGenerator(a *d2asset.AssetManager, e *d2mapengine.MapEngine) (*MapGen
|
||||
type MapGenerator struct {
|
||||
asset *d2asset.AssetManager
|
||||
engine *d2mapengine.MapEngine
|
||||
|
||||
*d2util.Logger
|
||||
}
|
||||
|
||||
func (g *MapGenerator) loadPreset(id, index int) *d2mapstamp.Stamp {
|
||||
|
@ -2,9 +2,7 @@ package d2maprenderer
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"image/color"
|
||||
"log"
|
||||
"math"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
@ -17,6 +15,10 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapengine"
|
||||
)
|
||||
|
||||
const (
|
||||
logPrefix = "Map Renderer"
|
||||
)
|
||||
|
||||
const (
|
||||
screenMiddleX = 400
|
||||
two = 2
|
||||
@ -59,12 +61,14 @@ type MapRenderer struct {
|
||||
entityDebugVisLevel int // Entity Debug visibility index (0=none, 1=vectors)
|
||||
lastFrameTime float64 // The last time the map was rendered
|
||||
currentFrame int // Current render frame (for animations)
|
||||
|
||||
*d2util.Logger
|
||||
}
|
||||
|
||||
// CreateMapRenderer creates a new MapRenderer, sets the required fields and returns a pointer to it.
|
||||
func CreateMapRenderer(asset *d2asset.AssetManager, renderer d2interface.Renderer,
|
||||
mapEngine *d2mapengine.MapEngine,
|
||||
term d2interface.Terminal, startX, startY float64) *MapRenderer {
|
||||
term d2interface.Terminal, l d2util.LogLevel, startX, startY float64) *MapRenderer {
|
||||
result := &MapRenderer{
|
||||
asset: asset,
|
||||
renderer: renderer,
|
||||
@ -72,6 +76,10 @@ func CreateMapRenderer(asset *d2asset.AssetManager, renderer d2interface.Rendere
|
||||
viewport: NewViewport(0, 0, 800, 600),
|
||||
}
|
||||
|
||||
result.Logger = d2util.NewLogger()
|
||||
result.Logger.SetPrefix(logPrefix)
|
||||
result.Logger.SetLevel(l)
|
||||
|
||||
result.Camera = Camera{}
|
||||
rx, ry := result.WorldToOrtho(startX, startY)
|
||||
startPosition := d2vector.NewPosition(rx, ry)
|
||||
@ -84,7 +92,7 @@ func CreateMapRenderer(asset *d2asset.AssetManager, renderer d2interface.Rendere
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("could not bind the mapdebugvis action, err: %v\n", err)
|
||||
result.Errorf("could not bind the mapdebugvis action, err: %v", err)
|
||||
}
|
||||
|
||||
err = term.BindAction("entitydebugvis", "set entity debug visualization level", func(level int) {
|
||||
@ -92,7 +100,7 @@ func CreateMapRenderer(asset *d2asset.AssetManager, renderer d2interface.Rendere
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("could not bind the entitydebugvis action, err: %v\n", err)
|
||||
result.Errorf("could not bind the entitydebugvis action, err: %v", err)
|
||||
}
|
||||
|
||||
if mapEngine.LevelType().ID != 0 {
|
||||
@ -363,7 +371,7 @@ func (mr *MapRenderer) renderFloor(tile d2ds1.FloorShadowRecord, target d2interf
|
||||
}
|
||||
|
||||
if img == nil {
|
||||
log.Printf("Render called on uncached floor {%v,%v}", tile.Style, tile.Sequence)
|
||||
mr.Warningf("Render called on uncached floor {%v,%v}", tile.Style, tile.Sequence)
|
||||
return
|
||||
}
|
||||
|
||||
@ -379,7 +387,7 @@ func (mr *MapRenderer) renderFloor(tile d2ds1.FloorShadowRecord, target d2interf
|
||||
func (mr *MapRenderer) renderWall(tile d2ds1.WallRecord, viewport *Viewport, target d2interface.Surface) {
|
||||
img := mr.getImageCacheRecord(tile.Style, tile.Sequence, tile.Type, tile.RandomIndex)
|
||||
if img == nil {
|
||||
log.Printf("Render called on uncached wall {%v,%v,%v}", tile.Style, tile.Sequence, tile.Type)
|
||||
mr.Warningf("Render called on uncached wall {%v,%v,%v}", tile.Style, tile.Sequence, tile.Type)
|
||||
return
|
||||
}
|
||||
|
||||
@ -395,7 +403,7 @@ func (mr *MapRenderer) renderWall(tile d2ds1.WallRecord, viewport *Viewport, tar
|
||||
func (mr *MapRenderer) renderShadow(tile d2ds1.FloorShadowRecord, target d2interface.Surface) {
|
||||
img := mr.getImageCacheRecord(tile.Style, tile.Sequence, 13, tile.RandomIndex)
|
||||
if img == nil {
|
||||
log.Printf("Render called on uncached shadow {%v,%v}", tile.Style, tile.Sequence)
|
||||
mr.Warningf("Render called on uncached shadow {%v,%v}", tile.Style, tile.Sequence)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
package d2maprenderer
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2ds1"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dt1"
|
||||
@ -28,7 +26,7 @@ func (mr *MapRenderer) generateTileCache() {
|
||||
mr.palette, err = mr.loadPaletteForAct(d2enum.RegionIdType(mr.mapEngine.LevelType().ID))
|
||||
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
mr.Error(err.Error())
|
||||
}
|
||||
|
||||
tiles := *mr.mapEngine.Tiles()
|
||||
@ -61,7 +59,7 @@ func (mr *MapRenderer) generateFloorCache(tile *d2ds1.FloorShadowRecord) {
|
||||
var tileData []*d2dt1.Tile
|
||||
|
||||
if tileOptions == nil {
|
||||
log.Printf("Could not locate tile Style:%d, Seq: %d, Type: %d\n", tile.Style, tile.Sequence, 0)
|
||||
mr.Errorf("Could not locate tile Style:%d, Seq: %d, Type: %d", tile.Style, tile.Sequence, 0)
|
||||
|
||||
tileData = append(tileData, &d2dt1.Tile{})
|
||||
tileData[0].Width = defaultFloorTileWidth
|
||||
@ -205,7 +203,7 @@ func (mr *MapRenderer) generateWallCache(tile *d2ds1.WallRecord) {
|
||||
}
|
||||
|
||||
if realHeight == 0 {
|
||||
log.Printf("Invalid 0 height for wall tile")
|
||||
mr.Error("Invalid 0 height for wall tile")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package d2mapstamp
|
||||
|
||||
import (
|
||||
"log"
|
||||
"math"
|
||||
"math/rand"
|
||||
|
||||
@ -10,12 +9,24 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2ds1"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dt1"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
)
|
||||
|
||||
const logPrefix = "Map Stamp"
|
||||
|
||||
// NewStampFactory creates a MapStamp factory instance
|
||||
func NewStampFactory(asset *d2asset.AssetManager, entity *d2mapentity.MapEntityFactory) *StampFactory {
|
||||
return &StampFactory{asset, entity}
|
||||
func NewStampFactory(asset *d2asset.AssetManager, l d2util.LogLevel, entity *d2mapentity.MapEntityFactory) *StampFactory {
|
||||
result := &StampFactory{
|
||||
asset: asset,
|
||||
entity: entity,
|
||||
}
|
||||
|
||||
result.Logger = d2util.NewLogger()
|
||||
result.Logger.SetLevel(l)
|
||||
result.Logger.SetPrefix(logPrefix)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// StampFactory is responsible for loading map stamps. A stamp can be thought of like a
|
||||
@ -23,6 +34,8 @@ func NewStampFactory(asset *d2asset.AssetManager, entity *d2mapentity.MapEntityF
|
||||
type StampFactory struct {
|
||||
asset *d2asset.AssetManager
|
||||
entity *d2mapentity.MapEntityFactory
|
||||
|
||||
*d2util.Logger
|
||||
}
|
||||
|
||||
// LoadStamp loads the Stamp data from file, using the given level type, level preset index, and
|
||||
@ -48,7 +61,7 @@ func (f *StampFactory) LoadStamp(levelType d2enum.RegionIdType, levelPreset, fil
|
||||
|
||||
dt1, err := d2dt1.LoadDT1(fileData)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
f.Error(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -82,7 +95,7 @@ func (f *StampFactory) LoadStamp(levelType d2enum.RegionIdType, levelPreset, fil
|
||||
|
||||
stamp.ds1, err = d2ds1.LoadDS1(fileData)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
f.Error(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package d2records
|
||||
|
||||
import (
|
||||
"log"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@ -24,6 +24,11 @@ func cubeRecipeLoader(r *RecordManager, d *d2txt.DataDictionary) error {
|
||||
var inputFields = []string{"input 1", "input 2", "input 3", "input 4", "input 5", "input 6", "input 7"}
|
||||
|
||||
for d.Next() {
|
||||
class, err := classFieldToEnum(d.String("class"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
record := &CubeRecipeRecord{
|
||||
Description: d.String("description"),
|
||||
|
||||
@ -37,7 +42,7 @@ func cubeRecipeLoader(r *RecordManager, d *d2txt.DataDictionary) error {
|
||||
ReqOperation: d.Number("op"),
|
||||
ReqValue: d.Number("value"),
|
||||
|
||||
Class: classFieldToEnum(d.String("class")),
|
||||
Class: class,
|
||||
|
||||
NumInputs: d.Number("numinputs"),
|
||||
}
|
||||
@ -45,17 +50,25 @@ func cubeRecipeLoader(r *RecordManager, d *d2txt.DataDictionary) error {
|
||||
// Create inputs - input 1-7
|
||||
record.Inputs = make([]CubeRecipeItem, len(inputFields))
|
||||
for i := range inputFields {
|
||||
record.Inputs[i] = newCubeRecipeItem(
|
||||
record.Inputs[i], err = newCubeRecipeItem(
|
||||
d.String(inputFields[i]))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Create outputs - output "", b, c
|
||||
record.Outputs = make([]CubeRecipeResult, len(outputLabels))
|
||||
for o, outLabel := range outputLabels {
|
||||
record.Outputs[o] = CubeRecipeResult{
|
||||
Item: newCubeRecipeItem(
|
||||
d.String(outputFields[o])),
|
||||
|
||||
for o, outLabel := range outputLabels {
|
||||
item, err := newCubeRecipeItem(
|
||||
d.String(outputFields[o]))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
record.Outputs[o] = CubeRecipeResult{
|
||||
Item: item,
|
||||
Level: d.Number(outLabel + "lvl"),
|
||||
ILevel: d.Number(outLabel + "plvl"),
|
||||
PLevel: d.Number(outLabel + "ilvl"),
|
||||
@ -94,7 +107,7 @@ func cubeRecipeLoader(r *RecordManager, d *d2txt.DataDictionary) error {
|
||||
// arguments. arguments include at least an item and sometimes
|
||||
// parameters and/or a count (qty parameter). For example:
|
||||
// "weap,sock,mag,qty=10"
|
||||
func newCubeRecipeItem(f string) CubeRecipeItem {
|
||||
func newCubeRecipeItem(f string) (CubeRecipeItem, error) {
|
||||
args := splitFieldValue(f)
|
||||
|
||||
item := CubeRecipeItem{
|
||||
@ -115,7 +128,8 @@ func newCubeRecipeItem(f string) CubeRecipeItem {
|
||||
count, err := strconv.Atoi(strings.Split(arg, "=")[1])
|
||||
|
||||
if err != nil {
|
||||
log.Fatal("Error parsing item count:", err)
|
||||
// need to be verified
|
||||
return item, fmt.Errorf("error parsing item count %e", err)
|
||||
}
|
||||
|
||||
item.Count = count
|
||||
@ -132,7 +146,7 @@ func newCubeRecipeItem(f string) CubeRecipeItem {
|
||||
|
||||
// No other arguments were provided
|
||||
if len(args) == 0 {
|
||||
return item
|
||||
return item, nil
|
||||
}
|
||||
|
||||
// Record the argument strings
|
||||
@ -141,11 +155,11 @@ func newCubeRecipeItem(f string) CubeRecipeItem {
|
||||
item.Params[idx] = arg
|
||||
}
|
||||
|
||||
return item
|
||||
return item, nil
|
||||
}
|
||||
|
||||
// classFieldToEnum converts class tokens to s2enum.Hero.
|
||||
func classFieldToEnum(f string) []d2enum.Hero {
|
||||
func classFieldToEnum(f string) ([]d2enum.Hero, error) {
|
||||
split := splitFieldValue(f)
|
||||
enums := make([]d2enum.Hero, len(split))
|
||||
|
||||
@ -170,11 +184,11 @@ func classFieldToEnum(f string) []d2enum.Hero {
|
||||
case "dru":
|
||||
enums[idx] = d2enum.HeroDruid
|
||||
default:
|
||||
log.Fatalf("Unknown hero token: '%s'", class)
|
||||
return nil, fmt.Errorf("unknown hero token: '%s'", class)
|
||||
}
|
||||
}
|
||||
|
||||
return enums
|
||||
return enums, nil
|
||||
}
|
||||
|
||||
// splitFieldValue splits a string array from the following format:
|
||||
|
@ -1,7 +1,7 @@
|
||||
package d2records
|
||||
|
||||
import (
|
||||
"log"
|
||||
"fmt"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
|
||||
@ -13,6 +13,11 @@ func monsterStats2Loader(r *RecordManager, d *d2txt.DataDictionary) error {
|
||||
records := make(MonStats2)
|
||||
|
||||
for d.Next() {
|
||||
resurrectMode, err := monsterAnimationModeFromString(d.String("ResurrectMode"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
record := &MonStats2Record{
|
||||
Key: d.String("Id"),
|
||||
Height: d.Number("Height"),
|
||||
@ -145,7 +150,7 @@ func monsterStats2Loader(r *RecordManager, d *d2txt.DataDictionary) error {
|
||||
InfernoLen: d.Number("InfernoLen"),
|
||||
InfernoAnim: d.Number("InfernoAnim"),
|
||||
InfernoRollback: d.Number("InfernoRollback"),
|
||||
ResurrectMode: monsterAnimationModeFromString(d.String("ResurrectMode")),
|
||||
ResurrectMode: resurrectMode,
|
||||
ResurrectSkill: d.String("ResurrectSkill"),
|
||||
}
|
||||
|
||||
@ -170,12 +175,11 @@ var monsterAnimationModeLookup = map[string]d2enum.MonsterAnimationMode{
|
||||
d2enum.MonsterAnimationModeSequence.String(): d2enum.MonsterAnimationModeSequence,
|
||||
}
|
||||
|
||||
func monsterAnimationModeFromString(s string) d2enum.MonsterAnimationMode {
|
||||
func monsterAnimationModeFromString(s string) (d2enum.MonsterAnimationMode, error) {
|
||||
v, ok := monsterAnimationModeLookup[s]
|
||||
if !ok {
|
||||
log.Fatalf("unhandled MonsterAnimationMode %q", s)
|
||||
return d2enum.MonsterAnimationModeNeutral
|
||||
return d2enum.MonsterAnimationModeNeutral, fmt.Errorf("unhandled MonsterAnimationMode %q", s)
|
||||
}
|
||||
|
||||
return v
|
||||
return v, nil
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package d2records
|
||||
|
||||
import (
|
||||
"log"
|
||||
"testing"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
@ -17,7 +16,7 @@ func TestIndexObjects(t *testing.T) {
|
||||
|
||||
r, err := NewRecordManager(d2util.LogLevelDefault)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
testObjects := []ObjectLookupRecord{
|
||||
|
@ -2,7 +2,6 @@ package d2records
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
|
||||
@ -37,7 +36,7 @@ func NewRecordManager(l d2util.LogLevel) (*RecordManager, error) {
|
||||
|
||||
// RecordManager stores all of the records loaded from txt files
|
||||
type RecordManager struct {
|
||||
Logger *d2util.Logger
|
||||
*d2util.Logger
|
||||
boundLoaders map[string][]recordLoader // there can be more than one loader bound for a file
|
||||
Animation struct {
|
||||
Data d2data.AnimationData
|
||||
@ -411,7 +410,7 @@ func (r *RecordManager) initObjectRecords(lookups []ObjectLookupRecord) {
|
||||
func (r *RecordManager) LookupObject(act, typ, id int) *ObjectLookupRecord {
|
||||
object := r.lookupObject(act, typ, id)
|
||||
if object == nil {
|
||||
log.Panicf("Failed to look up object Act: %d, Type: %d, ID: %d", act, typ, id)
|
||||
r.Fatalf("Failed to look up object Act: %d, Type: %d, ID: %d", act, typ, id)
|
||||
}
|
||||
|
||||
return object
|
||||
|
@ -1,7 +1,7 @@
|
||||
package d2records
|
||||
|
||||
import (
|
||||
"log"
|
||||
"fmt"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2calculation/d2parser"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
@ -19,6 +19,11 @@ func skillDetailsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
|
||||
name := d.String("skill")
|
||||
parser.SetCurrentReference("skill", name)
|
||||
|
||||
anim, err := animToEnum(d.String("anim"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
record := &SkillRecord{
|
||||
Skill: d.String("skill"),
|
||||
ID: d.Number("Id"),
|
||||
@ -141,7 +146,7 @@ func skillDetailsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
|
||||
Itypeb3: d.String("itypeb3"),
|
||||
Etypeb1: d.String("etypeb1"),
|
||||
Etypeb2: d.String("etypeb2"),
|
||||
Anim: animToEnum(d.String("anim")),
|
||||
Anim: anim,
|
||||
Seqtrans: d.String("seqtrans"),
|
||||
Monanim: d.String("monanim"),
|
||||
Seqnum: d.Number("seqnum"),
|
||||
@ -277,45 +282,42 @@ func skillDetailsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func animToEnum(anim string) d2enum.PlayerAnimationMode {
|
||||
func animToEnum(anim string) (d2enum.PlayerAnimationMode, error) {
|
||||
switch anim {
|
||||
case "SC":
|
||||
return d2enum.PlayerAnimationModeCast
|
||||
return d2enum.PlayerAnimationModeCast, nil
|
||||
|
||||
case "TH":
|
||||
return d2enum.PlayerAnimationModeThrow
|
||||
return d2enum.PlayerAnimationModeThrow, nil
|
||||
|
||||
case "KK":
|
||||
return d2enum.PlayerAnimationModeKick
|
||||
return d2enum.PlayerAnimationModeKick, nil
|
||||
|
||||
case "SQ":
|
||||
return d2enum.PlayerAnimationModeSequence
|
||||
return d2enum.PlayerAnimationModeSequence, nil
|
||||
|
||||
case "S1":
|
||||
return d2enum.PlayerAnimationModeSkill1
|
||||
return d2enum.PlayerAnimationModeSkill1, nil
|
||||
|
||||
case "S2":
|
||||
return d2enum.PlayerAnimationModeSkill2
|
||||
return d2enum.PlayerAnimationModeSkill2, nil
|
||||
|
||||
case "S3":
|
||||
return d2enum.PlayerAnimationModeSkill3
|
||||
return d2enum.PlayerAnimationModeSkill3, nil
|
||||
|
||||
case "S4":
|
||||
return d2enum.PlayerAnimationModeSkill4
|
||||
return d2enum.PlayerAnimationModeSkill4, nil
|
||||
|
||||
case "A1":
|
||||
return d2enum.PlayerAnimationModeAttack1
|
||||
return d2enum.PlayerAnimationModeAttack1, nil
|
||||
|
||||
case "A2":
|
||||
return d2enum.PlayerAnimationModeAttack2
|
||||
return d2enum.PlayerAnimationModeAttack2, nil
|
||||
|
||||
case "":
|
||||
return d2enum.PlayerAnimationModeNone
|
||||
|
||||
default:
|
||||
log.Fatalf("Unknown skill anim value [%s]", anim)
|
||||
return d2enum.PlayerAnimationModeNone, nil
|
||||
}
|
||||
|
||||
// should not be reached
|
||||
return d2enum.PlayerAnimationModeNone
|
||||
return d2enum.PlayerAnimationModeNone, fmt.Errorf("unknown skill anim value [%s]", anim)
|
||||
}
|
||||
|
@ -1,13 +1,16 @@
|
||||
package d2screen
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||
)
|
||||
|
||||
const (
|
||||
logPrefix = "Screen Manager"
|
||||
)
|
||||
|
||||
// ScreenManager manages game screens (main menu, credits, character select, game, etc)
|
||||
type ScreenManager struct {
|
||||
uiManager *d2ui.UIManager
|
||||
@ -16,11 +19,22 @@ type ScreenManager struct {
|
||||
loadingState LoadingState
|
||||
currentScreen Screen
|
||||
guiManager *d2gui.GuiManager
|
||||
|
||||
*d2util.Logger
|
||||
}
|
||||
|
||||
// NewScreenManager creates a screen manager
|
||||
func NewScreenManager(ui *d2ui.UIManager, guiManager *d2gui.GuiManager) *ScreenManager {
|
||||
return &ScreenManager{uiManager: ui, guiManager: guiManager}
|
||||
func NewScreenManager(ui *d2ui.UIManager, l d2util.LogLevel, guiManager *d2gui.GuiManager) *ScreenManager {
|
||||
sm := &ScreenManager{
|
||||
uiManager: ui,
|
||||
guiManager: guiManager,
|
||||
}
|
||||
|
||||
sm.Logger = d2util.NewLogger()
|
||||
sm.Logger.SetPrefix(logPrefix)
|
||||
sm.Logger.SetLevel(l)
|
||||
|
||||
return sm
|
||||
}
|
||||
|
||||
// SetNextScreen is about to set a given screen as next
|
||||
@ -35,11 +49,11 @@ func (sm *ScreenManager) Advance(elapsed float64) error {
|
||||
// this call blocks execution and could lead to deadlock if a screen implements OnLoad incorreclty
|
||||
load, ok := <-sm.loadingState.updates
|
||||
if !ok {
|
||||
log.Println("loadingState chan should not be closed while in a loading screen")
|
||||
sm.Warning("loadingState chan should not be closed while in a loading screen")
|
||||
}
|
||||
|
||||
if load.err != nil {
|
||||
log.Printf("PROBLEM LOADING THE SCREEN: %v", load.err)
|
||||
sm.Errorf("PROBLEM LOADING THE SCREEN: %v", load.err)
|
||||
return load.err
|
||||
}
|
||||
|
||||
|
@ -445,7 +445,7 @@ func (ui *UIManager) NewButton(buttonType ButtonType, text string) *Button {
|
||||
|
||||
buttonSprite, err := ui.NewSprite(buttonLayout.ResourceName, buttonLayout.PaletteName)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
ui.Error(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -455,7 +455,7 @@ func (ui *UIManager) NewButton(buttonType ButtonType, text string) *Button {
|
||||
for i := 0; i < buttonLayout.XSegments; i++ {
|
||||
w, _, frameSizeErr := buttonSprite.GetFrameSize(i)
|
||||
if frameSizeErr != nil {
|
||||
log.Print(frameSizeErr)
|
||||
ui.Error(frameSizeErr.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -469,7 +469,7 @@ func (ui *UIManager) NewButton(buttonType ButtonType, text string) *Button {
|
||||
for i := 0; i < buttonLayout.YSegments; i++ {
|
||||
_, h, frameSizeErr := buttonSprite.GetFrameSize(i * buttonLayout.YSegments)
|
||||
if frameSizeErr != nil {
|
||||
log.Print(frameSizeErr)
|
||||
ui.Error(frameSizeErr.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
package d2ui
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
@ -35,13 +33,13 @@ func (ui *UIManager) NewCheckbox(checkState bool) *Checkbox {
|
||||
|
||||
checkboxSprite, err := ui.NewSprite(d2resource.Checkbox, d2resource.PaletteFechar)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
ui.Error(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
result.width, result.height, err = checkboxSprite.GetFrameSize(0)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
ui.Error(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -2,12 +2,17 @@ package d2ui
|
||||
|
||||
import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
)
|
||||
|
||||
// CursorButton represents a mouse button
|
||||
type CursorButton uint8
|
||||
|
||||
const (
|
||||
logPrefix = "UI Manager"
|
||||
)
|
||||
|
||||
const (
|
||||
// CursorButtonLeft represents the left mouse button
|
||||
CursorButtonLeft CursorButton = 1
|
||||
@ -30,6 +35,7 @@ func NewUIManager(
|
||||
asset *d2asset.AssetManager,
|
||||
renderer d2interface.Renderer,
|
||||
input d2interface.InputManager,
|
||||
l d2util.LogLevel,
|
||||
audio d2interface.AudioProvider,
|
||||
) *UIManager {
|
||||
ui := &UIManager{
|
||||
@ -39,5 +45,9 @@ func NewUIManager(
|
||||
audio: audio,
|
||||
}
|
||||
|
||||
ui.Logger = d2util.NewLogger()
|
||||
ui.Logger.SetPrefix(logPrefix)
|
||||
ui.Logger.SetLevel(l)
|
||||
|
||||
return ui
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
package d2ui
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
@ -69,6 +67,8 @@ func NewUIFrame(
|
||||
}
|
||||
frame.Load()
|
||||
|
||||
frame.asset.Logger.SetPrefix(logPrefix) // workaround
|
||||
|
||||
return frame
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ func NewUIFrame(
|
||||
func (u *UIFrame) Load() {
|
||||
sprite, err := u.manager.NewSprite(d2resource.Frame, d2resource.PaletteSky)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
u.asset.Logger.Error(err.Error())
|
||||
}
|
||||
|
||||
u.frame = sprite
|
||||
@ -111,7 +111,7 @@ func (u *UIFrame) calculateSize() {
|
||||
for i := range framesWidth {
|
||||
w, _, err := u.frame.GetFrameSize(framesWidth[i])
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
u.asset.Logger.Error(err.Error())
|
||||
}
|
||||
|
||||
u.width += w
|
||||
@ -120,7 +120,7 @@ func (u *UIFrame) calculateSize() {
|
||||
for i := range framesHeight {
|
||||
_, h, err := u.frame.GetFrameSize(framesHeight[i])
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
u.asset.Logger.Error(err.Error())
|
||||
}
|
||||
|
||||
u.height += h
|
||||
@ -132,11 +132,11 @@ func (u *UIFrame) Render(target d2interface.Surface) {
|
||||
switch u.frameOrientation {
|
||||
case FrameLeft:
|
||||
if err := u.renderLeft(target); err != nil {
|
||||
log.Printf("Render error %e", err)
|
||||
u.asset.Logger.Error("Render error" + err.Error())
|
||||
}
|
||||
case FrameRight:
|
||||
if err := u.renderRight(target); err != nil {
|
||||
log.Printf("Render error %e", err)
|
||||
u.asset.Logger.Error("Render error" + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package d2ui
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
"log"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
@ -20,13 +19,15 @@ type Label struct {
|
||||
font *d2asset.Font
|
||||
Color map[int]color.Color
|
||||
backgroundColor color.Color
|
||||
|
||||
*d2util.Logger
|
||||
}
|
||||
|
||||
// NewLabel creates a new instance of a UI label
|
||||
func (ui *UIManager) NewLabel(fontPath, palettePath string) *Label {
|
||||
font, err := ui.asset.LoadFont(fontPath+".tbl", fontPath+".dc6", palettePath)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
ui.Error(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -37,6 +38,7 @@ func (ui *UIManager) NewLabel(fontPath, palettePath string) *Label {
|
||||
Alignment: HorizontalAlignLeft,
|
||||
Color: map[int]color.Color{0: color.White},
|
||||
font: font,
|
||||
Logger: ui.Logger,
|
||||
}
|
||||
|
||||
result.bindManager(ui)
|
||||
@ -75,7 +77,7 @@ func (v *Label) Render(target d2interface.Surface) {
|
||||
|
||||
err := v.font.RenderText(character, target)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
v.Error(err.Error())
|
||||
}
|
||||
|
||||
target.PushTranslation(charWidth, 0)
|
||||
@ -160,7 +162,7 @@ func (v *Label) getAlignOffset(textWidth int) int {
|
||||
case HorizontalAlignRight:
|
||||
return -textWidth
|
||||
default:
|
||||
log.Fatal("Invalid Alignment")
|
||||
v.Fatal("Invalid Alignment")
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
package d2ui
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
)
|
||||
@ -33,7 +31,7 @@ type Scrollbar struct {
|
||||
func (ui *UIManager) NewScrollbar(x, y, height int) *Scrollbar {
|
||||
scrollbarSprite, err := ui.NewSprite(d2resource.Scrollbar, d2resource.PaletteSky)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
ui.Error(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -4,17 +4,19 @@ import (
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
)
|
||||
|
||||
// Sprite is a positioned visual object.
|
||||
type Sprite struct {
|
||||
*BaseWidget
|
||||
animation d2interface.Animation
|
||||
|
||||
*d2util.Logger
|
||||
}
|
||||
|
||||
const (
|
||||
@ -34,7 +36,9 @@ func (ui *UIManager) NewSprite(animationPath, palettePath string) (*Sprite, erro
|
||||
|
||||
return &Sprite{
|
||||
BaseWidget: base,
|
||||
animation: animation}, nil
|
||||
animation: animation,
|
||||
Logger: ui.Logger,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Render renders the sprite on the given surface
|
||||
@ -70,7 +74,7 @@ func (s *Sprite) RenderSegmented(target d2interface.Surface, segmentsX, segments
|
||||
for x := 0; x < segmentsX; x++ {
|
||||
idx := x + y*segmentsX + frameOffset*segmentsX*segmentsY
|
||||
if err := s.animation.SetCurrentFrame(idx); err != nil {
|
||||
log.Printf("SetCurrentFrame error %e", err)
|
||||
s.Error("SetCurrentFrame error" + err.Error())
|
||||
}
|
||||
|
||||
target.PushTranslation(s.x+currentX, s.y+currentY)
|
||||
@ -150,7 +154,7 @@ func (s *Sprite) SetCurrentFrame(frameIndex int) error {
|
||||
func (s *Sprite) Rewind() {
|
||||
err := s.animation.SetCurrentFrame(0)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
s.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package d2ui
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -29,7 +28,7 @@ type TextBox struct {
|
||||
func (ui *UIManager) NewTextbox() *TextBox {
|
||||
bgSprite, err := ui.NewSprite(d2resource.TextBox2, d2resource.PaletteUnits)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
ui.Error(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package d2ui
|
||||
|
||||
import (
|
||||
"log"
|
||||
"sort"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
@ -9,6 +8,7 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
)
|
||||
|
||||
// UIManager manages a collection of UI elements (buttons, textboxes, labels)
|
||||
@ -25,6 +25,8 @@ type UIManager struct {
|
||||
CursorY int
|
||||
pressedWidget ClickableWidget
|
||||
clickSfx d2interface.SoundEffect
|
||||
|
||||
*d2util.Logger
|
||||
}
|
||||
|
||||
// Note: methods for creating buttons and stuff are in their respective files
|
||||
@ -34,13 +36,13 @@ type UIManager struct {
|
||||
func (ui *UIManager) Initialize() {
|
||||
sfx, err := ui.audio.LoadSound(d2resource.SFXButtonClick, false, false)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to initialize ui: %v", err)
|
||||
ui.Fatalf("failed to initialize ui: %v", err)
|
||||
}
|
||||
|
||||
ui.clickSfx = sfx
|
||||
|
||||
if err := ui.inputManager.BindHandler(ui); err != nil {
|
||||
log.Fatalf("failed to initialize ui: %v", err)
|
||||
ui.Fatalf("failed to initialize ui: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,7 +66,7 @@ func (ui *UIManager) addWidgetGroup(group *WidgetGroup) {
|
||||
func (ui *UIManager) addWidget(widget Widget) {
|
||||
err := ui.inputManager.BindHandler(widget)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
ui.Error(err.Error())
|
||||
}
|
||||
|
||||
clickable, ok := widget.(ClickableWidget)
|
||||
@ -159,7 +161,7 @@ func (ui *UIManager) Advance(elapsed float64) {
|
||||
if widget.GetVisible() {
|
||||
err := widget.Advance(elapsed)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
ui.Error(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -72,13 +72,13 @@ func CreateGame(
|
||||
lastRegionType: d2enum.RegionNone,
|
||||
ticksSinceLevelCheck: 0,
|
||||
mapRenderer: d2maprenderer.CreateMapRenderer(asset, renderer,
|
||||
gameClient.MapEngine, term, startX, startY),
|
||||
gameClient.MapEngine, term, l, startX, startY),
|
||||
escapeMenu: d2player.NewEscapeMenu(navigator, renderer, audioProvider, ui, guiManager, asset, l, keyMap),
|
||||
inputManager: inputManager,
|
||||
audioProvider: audioProvider,
|
||||
renderer: renderer,
|
||||
terminal: term,
|
||||
soundEngine: d2audio.NewSoundEngine(audioProvider, asset, term),
|
||||
soundEngine: d2audio.NewSoundEngine(audioProvider, asset, l, term),
|
||||
uiManager: ui,
|
||||
guiManager: guiManager,
|
||||
keyMap: keyMap,
|
||||
|
@ -116,6 +116,7 @@ func CreateMapEngineTest(currentRegion,
|
||||
audioProvider: audioProvider,
|
||||
screen: screen,
|
||||
playerStateFactory: heroStateFactory,
|
||||
logLevel: l,
|
||||
}
|
||||
|
||||
mapEngineTest.playerState = heroStateFactory.CreateTestGameState()
|
||||
@ -152,7 +153,8 @@ type MapEngineTest struct {
|
||||
regionSpec regionSpec
|
||||
filesCount int
|
||||
|
||||
logger *d2util.Logger
|
||||
logger *d2util.Logger
|
||||
logLevel d2util.LogLevel
|
||||
}
|
||||
|
||||
func (met *MapEngineTest) loadRegionByIndex(n, levelPreset, fileIndex int) {
|
||||
@ -187,14 +189,14 @@ func (met *MapEngineTest) loadRegionByIndex(n, levelPreset, fileIndex int) {
|
||||
met.levelPreset = levelPreset
|
||||
}
|
||||
|
||||
mapGen, _ := d2mapgen.NewMapGenerator(met.asset, met.mapEngine)
|
||||
mapGen, _ := d2mapgen.NewMapGenerator(met.asset, met.logLevel, met.mapEngine)
|
||||
met.mapGen = mapGen
|
||||
|
||||
if n == 0 {
|
||||
met.mapEngine.SetSeed(time.Now().UnixNano())
|
||||
met.mapGen.GenerateAct1Overworld()
|
||||
} else {
|
||||
met.mapEngine = d2mapengine.CreateMapEngine(met.asset) // necessary for map name update
|
||||
met.mapEngine = d2mapengine.CreateMapEngine(met.logLevel, met.asset) // necessary for map name update
|
||||
met.mapEngine.SetSeed(time.Now().UnixNano())
|
||||
met.mapEngine.GenerateMap(d2enum.RegionIdType(n), levelPreset, fileIndex)
|
||||
}
|
||||
@ -216,12 +218,12 @@ func (met *MapEngineTest) OnLoad(loading d2screen.LoadingState) {
|
||||
|
||||
loading.Progress(twentyPercent)
|
||||
|
||||
met.mapEngine = d2mapengine.CreateMapEngine(met.asset)
|
||||
met.mapEngine = d2mapengine.CreateMapEngine(met.logLevel, met.asset)
|
||||
|
||||
loading.Progress(fiftyPercent)
|
||||
|
||||
met.mapRenderer = d2maprenderer.CreateMapRenderer(met.asset, met.renderer, met.mapEngine,
|
||||
met.terminal, 0.0, 0.0)
|
||||
met.terminal, met.logLevel, 0.0, 0.0)
|
||||
|
||||
loading.Progress(seventyPercent)
|
||||
met.loadRegionByIndex(met.currentRegion, met.levelPreset, met.fileIndex)
|
||||
|
@ -77,23 +77,23 @@ func NewKeyBindingMenu(
|
||||
ret.Box = d2gui.NewBox(
|
||||
asset, renderer, ui, ret.mainLayout,
|
||||
keyBindingMenuWidth, keyBindingMenuHeight,
|
||||
keyBindingMenuX, keyBindingMenuY, "",
|
||||
keyBindingMenuX, keyBindingMenuY, l, "",
|
||||
)
|
||||
|
||||
ret.Box.SetPadding(keyBindingMenuPaddingX, keyBindingSettingPaddingY)
|
||||
|
||||
ret.Box.SetOptions([]*d2gui.LabelButton{
|
||||
d2gui.NewLabelButton(0, 0, "Cancel", d2util.Color(d2gui.ColorRed), func() {
|
||||
d2gui.NewLabelButton(0, 0, "Cancel", d2util.Color(d2gui.ColorRed), d2util.LogLevelDefault, func() {
|
||||
if err := ret.onCancelClicked(); err != nil {
|
||||
ret.logger.Error("error while clicking option Cancel: %v" + err.Error())
|
||||
}
|
||||
}),
|
||||
d2gui.NewLabelButton(0, 0, "Default", d2util.Color(d2gui.ColorBlue), func() {
|
||||
d2gui.NewLabelButton(0, 0, "Default", d2util.Color(d2gui.ColorBlue), d2util.LogLevelDefault, func() {
|
||||
if err := ret.onDefaultClicked(); err != nil {
|
||||
ret.logger.Error("error while clicking option Default: %v" + err.Error())
|
||||
}
|
||||
}),
|
||||
d2gui.NewLabelButton(0, 0, "Accept", d2util.Color(d2gui.ColorGreen), func() {
|
||||
d2gui.NewLabelButton(0, 0, "Accept", d2util.Color(d2gui.ColorGreen), d2util.LogLevelDefault, func() {
|
||||
if err := ret.onAcceptClicked(); err != nil {
|
||||
ret.logger.Error("error while clicking option Accept: %v" + err.Error())
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package d2localclient
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero"
|
||||
|
||||
@ -22,16 +23,18 @@ type LocalClientConnection struct {
|
||||
openNetworkServer bool // True if this is a server
|
||||
playerState *d2hero.HeroState // Local player state
|
||||
gameServer *d2server.GameServer // Game Server
|
||||
|
||||
logLevel d2util.LogLevel
|
||||
}
|
||||
|
||||
// GetUniqueID returns LocalClientConnection.uniqueID.
|
||||
func (l LocalClientConnection) GetUniqueID() string {
|
||||
func (l *LocalClientConnection) GetUniqueID() string {
|
||||
return l.uniqueID
|
||||
}
|
||||
|
||||
// GetConnectionType returns an enum representing the connection type.
|
||||
// See: d2clientconnectiontype
|
||||
func (l LocalClientConnection) GetConnectionType() d2clientconnectiontype.ClientConnectionType {
|
||||
func (l *LocalClientConnection) GetConnectionType() d2clientconnectiontype.ClientConnectionType {
|
||||
return d2clientconnectiontype.Local
|
||||
}
|
||||
|
||||
@ -42,7 +45,10 @@ func (l *LocalClientConnection) SendPacketToClient(packet d2netpacket.NetPacket)
|
||||
|
||||
// Create constructs a new LocalClientConnection and returns
|
||||
// a pointer to it.
|
||||
func Create(asset *d2asset.AssetManager, openNetworkServer bool) (*LocalClientConnection, error) {
|
||||
func Create(
|
||||
asset *d2asset.AssetManager,
|
||||
l d2util.LogLevel,
|
||||
openNetworkServer bool) (*LocalClientConnection, error) {
|
||||
heroStateFactory, err := d2hero.NewHeroStateFactory(asset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -53,6 +59,7 @@ func Create(asset *d2asset.AssetManager, openNetworkServer bool) (*LocalClientCo
|
||||
asset: asset,
|
||||
uniqueID: uuid.New().String(),
|
||||
openNetworkServer: openNetworkServer,
|
||||
logLevel: l,
|
||||
}
|
||||
|
||||
return result, nil
|
||||
@ -64,7 +71,7 @@ func (l *LocalClientConnection) Open(_, saveFilePath string) error {
|
||||
|
||||
l.SetPlayerState(l.heroState.LoadHeroState(saveFilePath))
|
||||
|
||||
l.gameServer, err = d2server.NewGameServer(l.asset, l.openNetworkServer, 30)
|
||||
l.gameServer, err = d2server.NewGameServer(l.asset, l.openNetworkServer, l.logLevel, 30)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -3,12 +3,12 @@ package d2remoteclient
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2networking"
|
||||
@ -17,6 +17,8 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket/d2netpackettype"
|
||||
)
|
||||
|
||||
const logPrefix = "Remote Client"
|
||||
|
||||
// RemoteClientConnection is the implementation of ClientConnection
|
||||
// for a remote client.
|
||||
type RemoteClientConnection struct {
|
||||
@ -26,11 +28,13 @@ type RemoteClientConnection struct {
|
||||
uniqueID string // Unique ID generated on construction
|
||||
tcpConnection *net.TCPConn // UDP connection to the server
|
||||
active bool // The connection is currently open
|
||||
|
||||
*d2util.Logger
|
||||
}
|
||||
|
||||
// Create constructs a new RemoteClientConnection
|
||||
// and returns a pointer to it.
|
||||
func Create(asset *d2asset.AssetManager) (*RemoteClientConnection, error) {
|
||||
func Create(l d2util.LogLevel, asset *d2asset.AssetManager) (*RemoteClientConnection, error) {
|
||||
heroStateFactory, err := d2hero.NewHeroStateFactory(asset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -42,6 +46,10 @@ func Create(asset *d2asset.AssetManager) (*RemoteClientConnection, error) {
|
||||
uniqueID: uuid.New().String(),
|
||||
}
|
||||
|
||||
result.Logger = d2util.NewLogger()
|
||||
result.Logger.SetPrefix(logPrefix)
|
||||
result.Logger.SetLevel(l)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@ -66,14 +74,14 @@ func (r *RemoteClientConnection) Open(connectionString, saveFilePath string) err
|
||||
r.active = true
|
||||
go r.serverListener()
|
||||
|
||||
log.Printf("Connected to server at %s", r.tcpConnection.RemoteAddr().String())
|
||||
r.Infof("Connected to server at %s", r.tcpConnection.RemoteAddr().String())
|
||||
|
||||
gameState := r.heroState.LoadHeroState(saveFilePath)
|
||||
packet := d2netpacket.CreatePlayerConnectionRequestPacket(r.GetUniqueID(), gameState)
|
||||
err = r.SendPacketToServer(packet)
|
||||
|
||||
if err != nil {
|
||||
log.Print("RemoteClientConnection: error sending PlayerConnectionRequestPacket to server.")
|
||||
r.Errorf("RemoteClientConnection: error sending PlayerConnectionRequestPacket to server.")
|
||||
return err
|
||||
}
|
||||
|
||||
@ -134,18 +142,18 @@ func (r *RemoteClientConnection) serverListener() {
|
||||
for {
|
||||
err := decoder.Decode(&packet)
|
||||
if err != nil {
|
||||
log.Printf("failed to decode the packet, err: %v\n", err)
|
||||
r.Errorf("failed to decode the packet, err: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
p, err := r.decodeToPacket(packet.PacketType, string(packet.PacketData))
|
||||
if err != nil {
|
||||
log.Println(packet.PacketType, err)
|
||||
r.Error(fmt.Sprintln(packet.PacketType, err))
|
||||
}
|
||||
|
||||
err = r.clientListener.OnPacketReceived(p)
|
||||
if err != nil {
|
||||
log.Println(packet.PacketType, err)
|
||||
r.Error(fmt.Sprintln(packet.PacketType, err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package d2client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero"
|
||||
@ -15,6 +14,7 @@ import (
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math/d2vector"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapengine"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapentity"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2records"
|
||||
@ -26,6 +26,8 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2script"
|
||||
)
|
||||
|
||||
const logPrefix = "Game Client"
|
||||
|
||||
const (
|
||||
numSubtilesPerTile = 5
|
||||
)
|
||||
@ -44,24 +46,32 @@ type GameClient struct {
|
||||
Players map[string]*d2mapentity.Player // IDs of the other players
|
||||
Seed int64 // Map seed
|
||||
RegenMap bool // Regenerate tile cache on render (map has changed)
|
||||
|
||||
*d2util.Logger
|
||||
}
|
||||
|
||||
// Create constructs a new GameClient and returns a pointer to it.
|
||||
func Create(connectionType d2clientconnectiontype.ClientConnectionType,
|
||||
asset *d2asset.AssetManager, scriptEngine *d2script.ScriptEngine) (*GameClient, error) {
|
||||
asset *d2asset.AssetManager,
|
||||
l d2util.LogLevel,
|
||||
scriptEngine *d2script.ScriptEngine) (*GameClient, error) {
|
||||
result := &GameClient{
|
||||
asset: asset,
|
||||
MapEngine: d2mapengine.CreateMapEngine(asset),
|
||||
MapEngine: d2mapengine.CreateMapEngine(l, asset),
|
||||
Players: make(map[string]*d2mapentity.Player),
|
||||
connectionType: connectionType,
|
||||
scriptEngine: scriptEngine,
|
||||
}
|
||||
|
||||
result.Logger = d2util.NewLogger()
|
||||
result.Logger.SetPrefix(logPrefix)
|
||||
result.Logger.SetLevel(l)
|
||||
|
||||
// for a remote client connection, set loading to true - wait until we process the GenerateMapPacket
|
||||
// before we start updating map entites
|
||||
result.MapEngine.IsLoading = connectionType == d2clientconnectiontype.LANClient
|
||||
|
||||
mapGen, err := d2mapgen.NewMapGenerator(asset, result.MapEngine)
|
||||
mapGen, err := d2mapgen.NewMapGenerator(asset, l, result.MapEngine)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -70,11 +80,11 @@ func Create(connectionType d2clientconnectiontype.ClientConnectionType,
|
||||
|
||||
switch connectionType {
|
||||
case d2clientconnectiontype.LANClient:
|
||||
result.clientConnection, err = d2remoteclient.Create(asset)
|
||||
result.clientConnection, err = d2remoteclient.Create(l, asset)
|
||||
case d2clientconnectiontype.LANServer:
|
||||
result.clientConnection, err = d2localclient.Create(asset, true)
|
||||
result.clientConnection, err = d2localclient.Create(asset, l, true)
|
||||
case d2clientconnectiontype.Local:
|
||||
result.clientConnection, err = d2localclient.Create(asset, false)
|
||||
result.clientConnection, err = d2localclient.Create(asset, l, false)
|
||||
default:
|
||||
err = fmt.Errorf("unknown client connection type specified: %d", connectionType)
|
||||
}
|
||||
@ -147,20 +157,20 @@ func (g *GameClient) OnPacketReceived(packet d2netpacket.NetPacket) error {
|
||||
}
|
||||
case d2netpackettype.Ping:
|
||||
if err := g.handlePingPacket(); err != nil {
|
||||
log.Printf("GameClient: error responding to server ping: %s", err)
|
||||
g.Errorf("GameClient: error responding to server ping: %s", err)
|
||||
}
|
||||
case d2netpackettype.PlayerDisconnectionNotification:
|
||||
// Not implemented
|
||||
log.Printf("RemoteClientConnection: received disconnect: %s", packet.PacketData)
|
||||
g.Infof("RemoteClientConnection: received disconnect: %s", packet.PacketData)
|
||||
case d2netpackettype.ServerClosed:
|
||||
// https://github.com/OpenDiablo2/OpenDiablo2/issues/802
|
||||
log.Print("Server has been closed")
|
||||
g.Infof("Server has been closed")
|
||||
os.Exit(0)
|
||||
case d2netpackettype.ServerFull:
|
||||
log.Println("Server is full")
|
||||
g.Infof("Server is full") // need to be verified
|
||||
os.Exit(0)
|
||||
default:
|
||||
log.Fatalf("Invalid packet type: %d", packet.PacketType)
|
||||
g.Fatalf("Invalid packet type: %d", packet.PacketType)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -196,7 +206,7 @@ func (g *GameClient) handleUpdateServerInfoPacket(packet d2netpacket.NetPacket)
|
||||
g.MapEngine.SetSeed(serverInfo.Seed)
|
||||
g.PlayerID = serverInfo.PlayerID
|
||||
g.Seed = serverInfo.Seed
|
||||
log.Printf("Player id set to %s", serverInfo.PlayerID)
|
||||
g.Infof("Player id set to %s", serverInfo.PlayerID)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -259,7 +269,7 @@ func (g *GameClient) handleMovePlayerPacket(packet d2netpacket.NetPacket) error
|
||||
|
||||
if err != nil {
|
||||
fmtStr := "GameClient: error setting animation mode for player %s: %s"
|
||||
log.Printf(fmtStr, player.ID(), err)
|
||||
g.Errorf(fmtStr, player.ID(), err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
@ -13,6 +12,7 @@ import (
|
||||
"github.com/robertkrimen/otto"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapengine"
|
||||
@ -23,6 +23,8 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2script"
|
||||
)
|
||||
|
||||
const logPrefix = "Game Server"
|
||||
|
||||
const (
|
||||
port = "6669"
|
||||
chunkSize int = 4096 // nolint:deadcode,unused,varcheck // WIP
|
||||
@ -51,6 +53,8 @@ type GameServer struct {
|
||||
maxConnections int
|
||||
packetManagerChan chan []byte
|
||||
heroStateFactory *d2hero.HeroStateFactory
|
||||
|
||||
*d2util.Logger
|
||||
}
|
||||
|
||||
// NewGameServer builds a new GameServer that can be started
|
||||
@ -58,7 +62,9 @@ type GameServer struct {
|
||||
// ctx: required context item
|
||||
// networkServer: true = 0.0.0.0 | false = 127.0.0.1
|
||||
// maxConnections (default: 8): maximum number of TCP connections allowed open
|
||||
func NewGameServer(asset *d2asset.AssetManager, networkServer bool,
|
||||
func NewGameServer(asset *d2asset.AssetManager,
|
||||
networkServer bool,
|
||||
l d2util.LogLevel,
|
||||
maxConnections ...int) (*GameServer,
|
||||
error) {
|
||||
if len(maxConnections) == 0 {
|
||||
@ -86,11 +92,15 @@ func NewGameServer(asset *d2asset.AssetManager, networkServer bool,
|
||||
heroStateFactory: heroStateFactory,
|
||||
}
|
||||
|
||||
mapEngine := d2mapengine.CreateMapEngine(asset)
|
||||
gameServer.Logger = d2util.NewLogger()
|
||||
gameServer.Logger.SetPrefix(logPrefix)
|
||||
gameServer.Logger.SetLevel(l)
|
||||
|
||||
mapEngine := d2mapengine.CreateMapEngine(l, asset)
|
||||
mapEngine.SetSeed(gameServer.seed)
|
||||
mapEngine.ResetMap(d2enum.RegionAct1Town, 100, 100)
|
||||
|
||||
mapGen, err := d2mapgen.NewMapGenerator(asset, mapEngine)
|
||||
mapGen, err := d2mapgen.NewMapGenerator(asset, l, mapEngine)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -118,7 +128,7 @@ func (g *GameServer) Start() error {
|
||||
listenerAddress = "0.0.0.0:" + port
|
||||
}
|
||||
|
||||
log.Printf("Starting Game Server @ %s\n", listenerAddress)
|
||||
g.Infof("Starting Game Server @ %s\n", listenerAddress)
|
||||
|
||||
l, err := net.Listen("tcp4", listenerAddress)
|
||||
if err != nil {
|
||||
@ -133,7 +143,7 @@ func (g *GameServer) Start() error {
|
||||
for {
|
||||
c, err := g.listener.Accept()
|
||||
if err != nil {
|
||||
log.Printf("Unable to accept connection: %s\n", err)
|
||||
g.Errorf("Unable to accept connection: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -150,7 +160,7 @@ func (g *GameServer) Stop() {
|
||||
g.cancel()
|
||||
|
||||
if err := g.listener.Close(); err != nil {
|
||||
log.Printf("failed to close the listener %s, err: %v\n", g.listener.Addr(), err)
|
||||
g.Errorf("failed to close the listener %s, err: %v\n", g.listener.Addr(), err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,14 +178,14 @@ func (g *GameServer) packetManager() {
|
||||
case d2netpackettype.PlayerConnectionRequest:
|
||||
player, err := d2netpacket.UnmarshalNetPacket(p)
|
||||
if err != nil {
|
||||
log.Printf("Unable to unmarshal PlayerConnectionRequestPacket: %s\n", err)
|
||||
g.Errorf("Unable to unmarshal PlayerConnectionRequestPacket: %s\n", err)
|
||||
}
|
||||
|
||||
g.sendPacketToClients(player)
|
||||
case d2netpackettype.MovePlayer:
|
||||
move, err := d2netpacket.UnmarshalNetPacket(p)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
g.Error(err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
@ -183,7 +193,7 @@ func (g *GameServer) packetManager() {
|
||||
case d2netpackettype.CastSkill:
|
||||
castSkill, err := d2netpacket.UnmarshalNetPacket(p)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
g.Error(err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
@ -191,7 +201,7 @@ func (g *GameServer) packetManager() {
|
||||
case d2netpackettype.SpawnItem:
|
||||
item, err := d2netpacket.UnmarshalNetPacket(p)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
g.Error(err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
@ -206,7 +216,7 @@ func (g *GameServer) packetManager() {
|
||||
func (g *GameServer) sendPacketToClients(packet d2netpacket.NetPacket) {
|
||||
for _, c := range g.connections {
|
||||
if err := c.SendPacketToClient(packet); err != nil {
|
||||
log.Printf("GameServer: error sending packet: %s to client %s: %s", packet.PacketType, c.GetUniqueID(), err)
|
||||
g.Errorf("GameServer: error sending packet: %s to client %s: %s", packet.PacketType, c.GetUniqueID(), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -218,11 +228,11 @@ func (g *GameServer) handleConnection(conn net.Conn) {
|
||||
|
||||
var packet d2netpacket.NetPacket
|
||||
|
||||
log.Printf("Accepting connection: %s\n", conn.RemoteAddr().String())
|
||||
g.Infof("Accepting connection: %s\n", conn.RemoteAddr().String())
|
||||
|
||||
defer func() {
|
||||
if err := conn.Close(); err != nil {
|
||||
log.Printf("failed to close the connection: %s\n", conn.RemoteAddr())
|
||||
g.Errorf("failed to close the connection: %s\n", conn.RemoteAddr())
|
||||
}
|
||||
}()
|
||||
|
||||
@ -231,7 +241,7 @@ func (g *GameServer) handleConnection(conn net.Conn) {
|
||||
for {
|
||||
err := decoder.Decode(&packet)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
g.Error(err.Error())
|
||||
return // exit this connection as we could not read the first packet
|
||||
}
|
||||
|
||||
@ -240,16 +250,16 @@ func (g *GameServer) handleConnection(conn net.Conn) {
|
||||
// to.
|
||||
if connected == 0 {
|
||||
if packet.PacketType != d2netpackettype.PlayerConnectionRequest {
|
||||
log.Printf("Closing connection with %s: did not receive new player connection request...\n", conn.RemoteAddr().String())
|
||||
g.Infof("Closing connection with %s: did not receive new player connection request...", conn.RemoteAddr().String())
|
||||
}
|
||||
|
||||
if err := g.registerConnection(packet.PacketData, conn); err != nil {
|
||||
switch err {
|
||||
case errServerFull: // Server is currently full and not accepting new connections.
|
||||
_, errServerFullPacket := conn.Write(d2netpacket.MarshalPacket(d2netpacket.CreateServerFullPacket()))
|
||||
log.Println(errServerFullPacket)
|
||||
g.Error(fmt.Sprintln(errServerFullPacket))
|
||||
case errPlayerAlreadyExists: // Player is already registered and did not disconnection correctly.
|
||||
log.Println(err)
|
||||
g.Error(fmt.Sprintln(err))
|
||||
}
|
||||
|
||||
return
|
||||
@ -283,7 +293,7 @@ func (g *GameServer) registerConnection(b []byte, conn net.Conn) error {
|
||||
// if it is not full, unmarshal the playerConnectionRequest
|
||||
packet, err := d2netpacket.UnmarshalPlayerConnectionRequest(b)
|
||||
if err != nil {
|
||||
log.Printf("Failed to unmarshal PlayerConnectionRequest: %s\n", err)
|
||||
g.Errorf("Failed to unmarshal PlayerConnectionRequest: %s\n", err)
|
||||
}
|
||||
|
||||
// check to see if the player is already registered
|
||||
@ -294,7 +304,7 @@ func (g *GameServer) registerConnection(b []byte, conn net.Conn) error {
|
||||
// Client a new TCP Client Connection and add it to the connections map
|
||||
client := d2tcpclientconnection.CreateTCPClientConnection(conn, packet.ID)
|
||||
client.SetPlayerState(packet.PlayerState)
|
||||
log.Printf("Client connected with an id of %s", client.GetUniqueID())
|
||||
g.Infof("Client connected with an id of %s", client.GetUniqueID())
|
||||
g.connections[client.GetUniqueID()] = client
|
||||
|
||||
// Temporary position hack --------------------------------------------
|
||||
@ -330,7 +340,7 @@ func (g *GameServer) OnClientConnected(client ClientConnection) {
|
||||
clientPlayerState.Y = sy
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
log.Printf("Client connected with an id of %s", client.GetUniqueID())
|
||||
g.Infof("Client connected with an id of %s", client.GetUniqueID())
|
||||
g.connections[client.GetUniqueID()] = client
|
||||
|
||||
g.handleClientConnection(client, sx, sy)
|
||||
@ -339,12 +349,12 @@ func (g *GameServer) OnClientConnected(client ClientConnection) {
|
||||
func (g *GameServer) handleClientConnection(client ClientConnection, x, y float64) {
|
||||
err := client.SendPacketToClient(d2netpacket.CreateUpdateServerInfoPacket(g.seed, client.GetUniqueID()))
|
||||
if err != nil {
|
||||
log.Printf("GameServer: error sending UpdateServerInfoPacket to client %s: %s", client.GetUniqueID(), err)
|
||||
g.Errorf("GameServer: error sending UpdateServerInfoPacket to client %s: %s", client.GetUniqueID(), err)
|
||||
}
|
||||
|
||||
err = client.SendPacketToClient(d2netpacket.CreateGenerateMapPacket(d2enum.RegionAct1Town))
|
||||
if err != nil {
|
||||
log.Printf("GameServer: error sending GenerateMapPacket to client %s: %s", client.GetUniqueID(), err)
|
||||
g.Errorf("GameServer: error sending GenerateMapPacket to client %s: %s", client.GetUniqueID(), err)
|
||||
}
|
||||
|
||||
playerState := client.GetPlayerState()
|
||||
@ -371,7 +381,7 @@ func (g *GameServer) handleClientConnection(client ClientConnection, x, y float6
|
||||
for _, connection := range g.connections {
|
||||
err := connection.SendPacketToClient(createPlayerPacket)
|
||||
if err != nil {
|
||||
log.Printf("GameServer: error sending %T to client %s: %s", createPlayerPacket, connection.GetUniqueID(), err)
|
||||
g.Errorf("GameServer: error sending %T to client %s: %s", createPlayerPacket, connection.GetUniqueID(), err)
|
||||
}
|
||||
|
||||
if connection.GetUniqueID() == client.GetUniqueID() {
|
||||
@ -397,7 +407,7 @@ func (g *GameServer) handleClientConnection(client ClientConnection, x, y float6
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("GameServer: error sending CreateAddPlayerPacket to client %s: %s", connection.GetUniqueID(), err)
|
||||
g.Errorf("GameServer: error sending CreateAddPlayerPacket to client %s: %s", connection.GetUniqueID(), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -405,7 +415,7 @@ func (g *GameServer) handleClientConnection(client ClientConnection, x, y float6
|
||||
// OnClientDisconnected removes the given client from the list
|
||||
// of client connections.
|
||||
func (g *GameServer) OnClientDisconnected(client ClientConnection) {
|
||||
log.Printf("Client disconnected with an id of %s", client.GetUniqueID())
|
||||
g.Infof("Client disconnected with an id of %s", client.GetUniqueID())
|
||||
delete(g.connections, client.GetUniqueID())
|
||||
}
|
||||
|
||||
@ -443,10 +453,10 @@ func (g *GameServer) OnPacketReceived(client ClientConnection, packet d2netpacke
|
||||
|
||||
err = g.heroStateFactory.Save(playerState)
|
||||
if err != nil {
|
||||
log.Printf("GameServer: error saving saving Player: %s", err)
|
||||
g.Errorf("GameServer: error saving saving Player: %s", err)
|
||||
}
|
||||
default:
|
||||
log.Printf("GameServer: received unknown packet %T", packet)
|
||||
g.Warningf("GameServer: received unknown packet %T", packet)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -3,6 +3,7 @@ package d2networking
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2networking/d2server"
|
||||
)
|
||||
@ -33,9 +34,10 @@ func StartDedicatedServer(
|
||||
manager *d2asset.AssetManager,
|
||||
in chan int,
|
||||
log chan string,
|
||||
l d2util.LogLevel,
|
||||
maxPlayers int,
|
||||
) error {
|
||||
server, err := d2server.NewGameServer(manager, true, maxPlayers)
|
||||
server, err := d2server.NewGameServer(manager, true, l, maxPlayers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user