mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-09-25 20:55:55 -04:00
Lowercased all of the packages (#96)
This commit is contained in:
parent
da4ffba9c1
commit
e433c758e9
@ -1,568 +0,0 @@
|
|||||||
package Scenes
|
|
||||||
|
|
||||||
import (
|
|
||||||
"image"
|
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Sound"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/UI"
|
|
||||||
"github.com/hajimehoshi/ebiten"
|
|
||||||
)
|
|
||||||
|
|
||||||
type HeroStance int
|
|
||||||
|
|
||||||
const (
|
|
||||||
HeroStanceIdle HeroStance = 0
|
|
||||||
HeroStanceIdleSelected HeroStance = 1
|
|
||||||
HeroStanceApproaching HeroStance = 2
|
|
||||||
HeroStanceSelected HeroStance = 3
|
|
||||||
HeroStanceRetreating HeroStance = 4
|
|
||||||
)
|
|
||||||
|
|
||||||
type HeroRenderInfo struct {
|
|
||||||
Stance HeroStance
|
|
||||||
IdleSprite *Common.Sprite
|
|
||||||
IdleSelectedSprite *Common.Sprite
|
|
||||||
ForwardWalkSprite *Common.Sprite
|
|
||||||
ForwardWalkSpriteOverlay *Common.Sprite
|
|
||||||
SelectedSprite *Common.Sprite
|
|
||||||
SelectedSpriteOverlay *Common.Sprite
|
|
||||||
BackWalkSprite *Common.Sprite
|
|
||||||
BackWalkSpriteOverlay *Common.Sprite
|
|
||||||
SelectionBounds image.Rectangle
|
|
||||||
SelectSfx *Sound.SoundEffect
|
|
||||||
DeselectSfx *Sound.SoundEffect
|
|
||||||
}
|
|
||||||
|
|
||||||
type SelectHeroClass struct {
|
|
||||||
uiManager *UI.Manager
|
|
||||||
soundManager *Sound.Manager
|
|
||||||
fileProvider Common.FileProvider
|
|
||||||
sceneProvider SceneProvider
|
|
||||||
bgImage *Common.Sprite
|
|
||||||
campfire *Common.Sprite
|
|
||||||
headingLabel *UI.Label
|
|
||||||
heroClassLabel *UI.Label
|
|
||||||
heroDesc1Label *UI.Label
|
|
||||||
heroDesc2Label *UI.Label
|
|
||||||
heroDesc3Label *UI.Label
|
|
||||||
heroRenderInfo map[Common.Hero]*HeroRenderInfo
|
|
||||||
selectedHero Common.Hero
|
|
||||||
exitButton *UI.Button
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateSelectHeroClass(
|
|
||||||
fileProvider Common.FileProvider,
|
|
||||||
sceneProvider SceneProvider,
|
|
||||||
uiManager *UI.Manager, soundManager *Sound.Manager,
|
|
||||||
) *SelectHeroClass {
|
|
||||||
result := &SelectHeroClass{
|
|
||||||
uiManager: uiManager,
|
|
||||||
sceneProvider: sceneProvider,
|
|
||||||
fileProvider: fileProvider,
|
|
||||||
soundManager: soundManager,
|
|
||||||
heroRenderInfo: make(map[Common.Hero]*HeroRenderInfo),
|
|
||||||
selectedHero: Common.HeroNone,
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *SelectHeroClass) Load() []func() {
|
|
||||||
v.soundManager.PlayBGM(ResourcePaths.BGMTitle)
|
|
||||||
return []func(){
|
|
||||||
func() {
|
|
||||||
v.bgImage = v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectBackground, PaletteDefs.Fechar)
|
|
||||||
v.bgImage.MoveTo(0, 0)
|
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.headingLabel = UI.CreateLabel(v.fileProvider, ResourcePaths.Font30, PaletteDefs.Units)
|
|
||||||
fontWidth, _ := v.headingLabel.GetSize()
|
|
||||||
v.headingLabel.MoveTo(400-int(fontWidth/2), 17)
|
|
||||||
v.headingLabel.SetText("Select Hero Class")
|
|
||||||
v.headingLabel.Alignment = UI.LabelAlignCenter
|
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroClassLabel = UI.CreateLabel(v.fileProvider, ResourcePaths.Font30, PaletteDefs.Units)
|
|
||||||
v.heroClassLabel.Alignment = UI.LabelAlignCenter
|
|
||||||
v.heroClassLabel.MoveTo(400, 65)
|
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroDesc1Label = UI.CreateLabel(v.fileProvider, ResourcePaths.Font16, PaletteDefs.Units)
|
|
||||||
v.heroDesc1Label.Alignment = UI.LabelAlignCenter
|
|
||||||
v.heroDesc1Label.MoveTo(400, 100)
|
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroDesc2Label = UI.CreateLabel(v.fileProvider, ResourcePaths.Font16, PaletteDefs.Units)
|
|
||||||
v.heroDesc2Label.Alignment = UI.LabelAlignCenter
|
|
||||||
v.heroDesc2Label.MoveTo(400, 115)
|
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroDesc3Label = UI.CreateLabel(v.fileProvider, ResourcePaths.Font16, PaletteDefs.Units)
|
|
||||||
v.heroDesc3Label.Alignment = UI.LabelAlignCenter
|
|
||||||
v.heroDesc3Label.MoveTo(400, 130)
|
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.campfire = v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectCampfire, PaletteDefs.Fechar)
|
|
||||||
v.campfire.MoveTo(380, 335)
|
|
||||||
v.campfire.Animate = true
|
|
||||||
v.campfire.Blend = true
|
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.exitButton = UI.CreateButton(UI.ButtonTypeMedium, v.fileProvider, Common.TranslateString("#970"))
|
|
||||||
v.exitButton.MoveTo(33, 537)
|
|
||||||
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
|
||||||
v.uiManager.AddWidget(v.exitButton)
|
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroRenderInfo[Common.HeroBarbarian] = &HeroRenderInfo{
|
|
||||||
HeroStanceIdle,
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectBarbarianUnselected, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectBarbarianUnselectedH, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectBarbarianForwardWalk, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectBarbarianForwardWalkOverlay, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectBarbarianSelected, PaletteDefs.Fechar),
|
|
||||||
nil,
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectBarbarianBackWalk, PaletteDefs.Fechar),
|
|
||||||
nil,
|
|
||||||
image.Rectangle{Min: image.Point{364, 201}, Max: image.Point{90, 170}},
|
|
||||||
v.soundManager.LoadSoundEffect(ResourcePaths.SFXBarbarianSelect),
|
|
||||||
v.soundManager.LoadSoundEffect(ResourcePaths.SFXBarbarianDeselect),
|
|
||||||
}
|
|
||||||
v.heroRenderInfo[Common.HeroBarbarian].IdleSprite.MoveTo(400, 330)
|
|
||||||
v.heroRenderInfo[Common.HeroBarbarian].IdleSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroBarbarian].IdleSelectedSprite.MoveTo(400, 330)
|
|
||||||
v.heroRenderInfo[Common.HeroBarbarian].IdleSelectedSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroBarbarian].ForwardWalkSprite.MoveTo(400, 330)
|
|
||||||
v.heroRenderInfo[Common.HeroBarbarian].ForwardWalkSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroBarbarian].ForwardWalkSprite.SpecialFrameTime = 2500
|
|
||||||
v.heroRenderInfo[Common.HeroBarbarian].ForwardWalkSprite.StopOnLastFrame = true
|
|
||||||
v.heroRenderInfo[Common.HeroBarbarian].ForwardWalkSpriteOverlay.MoveTo(400, 330)
|
|
||||||
v.heroRenderInfo[Common.HeroBarbarian].ForwardWalkSpriteOverlay.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroBarbarian].ForwardWalkSpriteOverlay.SpecialFrameTime = 2500
|
|
||||||
v.heroRenderInfo[Common.HeroBarbarian].ForwardWalkSpriteOverlay.StopOnLastFrame = true
|
|
||||||
v.heroRenderInfo[Common.HeroBarbarian].SelectedSprite.MoveTo(400, 330)
|
|
||||||
v.heroRenderInfo[Common.HeroBarbarian].SelectedSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroBarbarian].BackWalkSprite.MoveTo(400, 330)
|
|
||||||
v.heroRenderInfo[Common.HeroBarbarian].BackWalkSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroBarbarian].BackWalkSprite.SpecialFrameTime = 1000
|
|
||||||
v.heroRenderInfo[Common.HeroBarbarian].BackWalkSprite.StopOnLastFrame = true
|
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress] = &HeroRenderInfo{
|
|
||||||
HeroStanceIdle,
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecSorceressUnselected, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecSorceressUnselectedH, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecSorceressForwardWalk, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecSorceressForwardWalkOverlay, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecSorceressSelected, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecSorceressSelectedOverlay, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecSorceressBackWalk, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecSorceressBackWalkOverlay, PaletteDefs.Fechar),
|
|
||||||
image.Rectangle{Min: image.Point{580, 240}, Max: image.Point{65, 160}},
|
|
||||||
v.soundManager.LoadSoundEffect(ResourcePaths.SFXSorceressSelect),
|
|
||||||
v.soundManager.LoadSoundEffect(ResourcePaths.SFXSorceressDeselect),
|
|
||||||
}
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].IdleSprite.MoveTo(626, 352)
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].IdleSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].IdleSelectedSprite.MoveTo(626, 352)
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].IdleSelectedSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].ForwardWalkSprite.MoveTo(626, 352)
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].ForwardWalkSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].ForwardWalkSprite.SpecialFrameTime = 2300
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].ForwardWalkSprite.StopOnLastFrame = true
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].ForwardWalkSpriteOverlay.Blend = true
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].ForwardWalkSpriteOverlay.MoveTo(626, 352)
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].ForwardWalkSpriteOverlay.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].ForwardWalkSpriteOverlay.SpecialFrameTime = 2300
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].ForwardWalkSpriteOverlay.StopOnLastFrame = true
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].SelectedSprite.MoveTo(626, 352)
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].SelectedSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].SelectedSpriteOverlay.Blend = true
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].SelectedSpriteOverlay.MoveTo(626, 352)
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].SelectedSpriteOverlay.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].BackWalkSprite.MoveTo(626, 352)
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].BackWalkSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].BackWalkSprite.SpecialFrameTime = 1200
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].BackWalkSprite.StopOnLastFrame = true
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].BackWalkSpriteOverlay.Blend = true
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].BackWalkSpriteOverlay.MoveTo(626, 352)
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].BackWalkSpriteOverlay.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].BackWalkSpriteOverlay.SpecialFrameTime = 1200
|
|
||||||
v.heroRenderInfo[Common.HeroSorceress].BackWalkSpriteOverlay.StopOnLastFrame = true
|
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer] = &HeroRenderInfo{
|
|
||||||
HeroStanceIdle,
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectNecromancerUnselected, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectNecromancerUnselectedH, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecNecromancerForwardWalk, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecNecromancerForwardWalkOverlay, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecNecromancerSelected, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecNecromancerSelectedOverlay, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecNecromancerBackWalk, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecNecromancerBackWalkOverlay, PaletteDefs.Fechar),
|
|
||||||
image.Rectangle{Min: image.Point{265, 220}, Max: image.Point{55, 175}},
|
|
||||||
v.soundManager.LoadSoundEffect(ResourcePaths.SFXNecromancerSelect),
|
|
||||||
v.soundManager.LoadSoundEffect(ResourcePaths.SFXNecromancerDeselect),
|
|
||||||
}
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].IdleSprite.MoveTo(300, 335)
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].IdleSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].IdleSelectedSprite.MoveTo(300, 335)
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].IdleSelectedSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].ForwardWalkSprite.MoveTo(300, 335)
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].ForwardWalkSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].ForwardWalkSprite.SpecialFrameTime = 2000
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].ForwardWalkSprite.StopOnLastFrame = true
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].ForwardWalkSpriteOverlay.Blend = true
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].ForwardWalkSpriteOverlay.MoveTo(300, 335)
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].ForwardWalkSpriteOverlay.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].ForwardWalkSpriteOverlay.SpecialFrameTime = 2000
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].ForwardWalkSpriteOverlay.StopOnLastFrame = true
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].SelectedSprite.MoveTo(300, 335)
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].SelectedSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].SelectedSpriteOverlay.Blend = true
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].SelectedSpriteOverlay.MoveTo(300, 335)
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].SelectedSpriteOverlay.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].BackWalkSprite.MoveTo(300, 335)
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].BackWalkSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].BackWalkSprite.SpecialFrameTime = 1500
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].BackWalkSprite.StopOnLastFrame = true
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].BackWalkSpriteOverlay.Blend = true
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].BackWalkSpriteOverlay.MoveTo(300, 335)
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].BackWalkSpriteOverlay.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].BackWalkSpriteOverlay.SpecialFrameTime = 1500
|
|
||||||
v.heroRenderInfo[Common.HeroNecromancer].BackWalkSpriteOverlay.StopOnLastFrame = true
|
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroRenderInfo[Common.HeroPaladin] = &HeroRenderInfo{
|
|
||||||
HeroStanceIdle,
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectPaladinUnselected, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectPaladinUnselectedH, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecPaladinForwardWalk, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecPaladinForwardWalkOverlay, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecPaladinSelected, PaletteDefs.Fechar),
|
|
||||||
nil,
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecPaladinBackWalk, PaletteDefs.Fechar),
|
|
||||||
nil,
|
|
||||||
image.Rectangle{Min: image.Point{490, 210}, Max: image.Point{65, 180}},
|
|
||||||
v.soundManager.LoadSoundEffect(ResourcePaths.SFXPaladinSelect),
|
|
||||||
v.soundManager.LoadSoundEffect(ResourcePaths.SFXPaladinDeselect),
|
|
||||||
}
|
|
||||||
v.heroRenderInfo[Common.HeroPaladin].IdleSprite.MoveTo(521, 338)
|
|
||||||
v.heroRenderInfo[Common.HeroPaladin].IdleSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroPaladin].IdleSelectedSprite.MoveTo(521, 338)
|
|
||||||
v.heroRenderInfo[Common.HeroPaladin].IdleSelectedSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroPaladin].ForwardWalkSprite.MoveTo(521, 338)
|
|
||||||
v.heroRenderInfo[Common.HeroPaladin].ForwardWalkSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroPaladin].ForwardWalkSprite.SpecialFrameTime = 3400
|
|
||||||
v.heroRenderInfo[Common.HeroPaladin].ForwardWalkSprite.StopOnLastFrame = true
|
|
||||||
v.heroRenderInfo[Common.HeroPaladin].ForwardWalkSpriteOverlay.MoveTo(521, 338)
|
|
||||||
v.heroRenderInfo[Common.HeroPaladin].ForwardWalkSpriteOverlay.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroPaladin].ForwardWalkSpriteOverlay.SpecialFrameTime = 3400
|
|
||||||
v.heroRenderInfo[Common.HeroPaladin].ForwardWalkSpriteOverlay.StopOnLastFrame = true
|
|
||||||
v.heroRenderInfo[Common.HeroPaladin].SelectedSprite.MoveTo(521, 338)
|
|
||||||
v.heroRenderInfo[Common.HeroPaladin].SelectedSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroPaladin].BackWalkSprite.MoveTo(521, 338)
|
|
||||||
v.heroRenderInfo[Common.HeroPaladin].BackWalkSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroPaladin].BackWalkSprite.SpecialFrameTime = 1300
|
|
||||||
v.heroRenderInfo[Common.HeroPaladin].BackWalkSprite.StopOnLastFrame = true
|
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroRenderInfo[Common.HeroAmazon] = &HeroRenderInfo{
|
|
||||||
HeroStanceIdle,
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectAmazonUnselected, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectAmazonUnselectedH, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecAmazonForwardWalk, PaletteDefs.Fechar),
|
|
||||||
nil,
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecAmazonSelected, PaletteDefs.Fechar),
|
|
||||||
nil,
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelecAmazonBackWalk, PaletteDefs.Fechar),
|
|
||||||
nil,
|
|
||||||
image.Rectangle{Min: image.Point{70, 220}, Max: image.Point{55, 200}},
|
|
||||||
v.soundManager.LoadSoundEffect(ResourcePaths.SFXAmazonSelect),
|
|
||||||
v.soundManager.LoadSoundEffect(ResourcePaths.SFXAmazonDeselect),
|
|
||||||
}
|
|
||||||
v.heroRenderInfo[Common.HeroAmazon].IdleSprite.MoveTo(100, 339)
|
|
||||||
v.heroRenderInfo[Common.HeroAmazon].IdleSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroAmazon].IdleSelectedSprite.MoveTo(100, 339)
|
|
||||||
v.heroRenderInfo[Common.HeroAmazon].IdleSelectedSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroAmazon].ForwardWalkSprite.MoveTo(100, 339)
|
|
||||||
v.heroRenderInfo[Common.HeroAmazon].ForwardWalkSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroAmazon].ForwardWalkSprite.SpecialFrameTime = 2200
|
|
||||||
v.heroRenderInfo[Common.HeroAmazon].ForwardWalkSprite.StopOnLastFrame = true
|
|
||||||
v.heroRenderInfo[Common.HeroAmazon].SelectedSprite.MoveTo(100, 339)
|
|
||||||
v.heroRenderInfo[Common.HeroAmazon].SelectedSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroAmazon].BackWalkSprite.MoveTo(100, 339)
|
|
||||||
v.heroRenderInfo[Common.HeroAmazon].BackWalkSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroAmazon].BackWalkSprite.SpecialFrameTime = 1500
|
|
||||||
v.heroRenderInfo[Common.HeroAmazon].BackWalkSprite.StopOnLastFrame = true
|
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroRenderInfo[Common.HeroAssassin] = &HeroRenderInfo{
|
|
||||||
HeroStanceIdle,
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectAssassinUnselected, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectAssassinUnselectedH, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectAssassinForwardWalk, PaletteDefs.Fechar),
|
|
||||||
nil,
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectAssassinSelected, PaletteDefs.Fechar),
|
|
||||||
nil,
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectAssassinBackWalk, PaletteDefs.Fechar),
|
|
||||||
nil,
|
|
||||||
image.Rectangle{Min: image.Point{175, 235}, Max: image.Point{50, 180}},
|
|
||||||
v.soundManager.LoadSoundEffect(ResourcePaths.SFXAssassinSelect),
|
|
||||||
v.soundManager.LoadSoundEffect(ResourcePaths.SFXAssassinDeselect),
|
|
||||||
}
|
|
||||||
v.heroRenderInfo[Common.HeroAssassin].IdleSprite.MoveTo(231, 365)
|
|
||||||
v.heroRenderInfo[Common.HeroAssassin].IdleSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroAssassin].IdleSelectedSprite.MoveTo(231, 365)
|
|
||||||
v.heroRenderInfo[Common.HeroAssassin].IdleSelectedSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroAssassin].ForwardWalkSprite.MoveTo(231, 365)
|
|
||||||
v.heroRenderInfo[Common.HeroAssassin].ForwardWalkSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroAssassin].ForwardWalkSprite.SpecialFrameTime = 3800
|
|
||||||
v.heroRenderInfo[Common.HeroAssassin].ForwardWalkSprite.StopOnLastFrame = true
|
|
||||||
v.heroRenderInfo[Common.HeroAssassin].SelectedSprite.MoveTo(231, 365)
|
|
||||||
v.heroRenderInfo[Common.HeroAssassin].SelectedSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroAssassin].BackWalkSprite.MoveTo(231, 365)
|
|
||||||
v.heroRenderInfo[Common.HeroAssassin].BackWalkSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroAssassin].BackWalkSprite.SpecialFrameTime = 1500
|
|
||||||
v.heroRenderInfo[Common.HeroAssassin].BackWalkSprite.StopOnLastFrame = true
|
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroRenderInfo[Common.HeroDruid] = &HeroRenderInfo{
|
|
||||||
HeroStanceIdle,
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectDruidUnselected, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectDruidUnselectedH, PaletteDefs.Fechar),
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectDruidForwardWalk, PaletteDefs.Fechar),
|
|
||||||
nil,
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectDruidSelected, PaletteDefs.Fechar),
|
|
||||||
nil,
|
|
||||||
v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectDruidBackWalk, PaletteDefs.Fechar),
|
|
||||||
nil,
|
|
||||||
image.Rectangle{Min: image.Point{680, 220}, Max: image.Point{70, 195}},
|
|
||||||
v.soundManager.LoadSoundEffect(ResourcePaths.SFXDruidSelect),
|
|
||||||
v.soundManager.LoadSoundEffect(ResourcePaths.SFXDruidDeselect),
|
|
||||||
}
|
|
||||||
v.heroRenderInfo[Common.HeroDruid].IdleSprite.MoveTo(720, 370)
|
|
||||||
v.heroRenderInfo[Common.HeroDruid].IdleSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroDruid].IdleSelectedSprite.MoveTo(720, 370)
|
|
||||||
v.heroRenderInfo[Common.HeroDruid].IdleSelectedSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroDruid].ForwardWalkSprite.MoveTo(720, 370)
|
|
||||||
v.heroRenderInfo[Common.HeroDruid].ForwardWalkSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroDruid].ForwardWalkSprite.SpecialFrameTime = 4800
|
|
||||||
v.heroRenderInfo[Common.HeroDruid].ForwardWalkSprite.StopOnLastFrame = true
|
|
||||||
v.heroRenderInfo[Common.HeroDruid].SelectedSprite.MoveTo(720, 370)
|
|
||||||
v.heroRenderInfo[Common.HeroDruid].SelectedSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroDruid].BackWalkSprite.MoveTo(720, 370)
|
|
||||||
v.heroRenderInfo[Common.HeroDruid].BackWalkSprite.Animate = true
|
|
||||||
v.heroRenderInfo[Common.HeroDruid].BackWalkSprite.SpecialFrameTime = 1500
|
|
||||||
v.heroRenderInfo[Common.HeroDruid].BackWalkSprite.StopOnLastFrame = true
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *SelectHeroClass) Unload() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *SelectHeroClass) onExitButtonClicked() {
|
|
||||||
v.sceneProvider.SetNextScene(CreateCharacterSelect(v.fileProvider, v.sceneProvider, v.uiManager, v.soundManager))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *SelectHeroClass) Render(screen *ebiten.Image) {
|
|
||||||
v.bgImage.DrawSegments(screen, 4, 3, 0)
|
|
||||||
v.headingLabel.Draw(screen)
|
|
||||||
if v.selectedHero != Common.HeroNone {
|
|
||||||
v.heroClassLabel.Draw(screen)
|
|
||||||
v.heroDesc1Label.Draw(screen)
|
|
||||||
v.heroDesc2Label.Draw(screen)
|
|
||||||
v.heroDesc3Label.Draw(screen)
|
|
||||||
}
|
|
||||||
for heroClass, heroInfo := range v.heroRenderInfo {
|
|
||||||
if heroInfo.Stance == HeroStanceIdle || heroInfo.Stance == HeroStanceIdleSelected {
|
|
||||||
v.renderHero(screen, heroClass)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for heroClass, heroInfo := range v.heroRenderInfo {
|
|
||||||
if heroInfo.Stance != HeroStanceIdle && heroInfo.Stance != HeroStanceIdleSelected {
|
|
||||||
v.renderHero(screen, heroClass)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
v.campfire.Draw(screen)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *SelectHeroClass) Update(tickTime float64) {
|
|
||||||
canSelect := true
|
|
||||||
for _, info := range v.heroRenderInfo {
|
|
||||||
if info.Stance != HeroStanceIdle && info.Stance != HeroStanceIdleSelected && info.Stance != HeroStanceSelected {
|
|
||||||
canSelect = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
allIdle := true
|
|
||||||
for heroType, data := range v.heroRenderInfo {
|
|
||||||
if allIdle && data.Stance != HeroStanceIdle {
|
|
||||||
allIdle = false
|
|
||||||
}
|
|
||||||
v.updateHeroSelectionHover(heroType, canSelect)
|
|
||||||
}
|
|
||||||
if v.selectedHero != Common.HeroNone && allIdle {
|
|
||||||
v.selectedHero = Common.HeroNone
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *SelectHeroClass) updateHeroSelectionHover(hero Common.Hero, canSelect bool) {
|
|
||||||
renderInfo := v.heroRenderInfo[hero]
|
|
||||||
switch renderInfo.Stance {
|
|
||||||
case HeroStanceApproaching:
|
|
||||||
if renderInfo.ForwardWalkSprite.OnLastFrame() {
|
|
||||||
renderInfo.Stance = HeroStanceSelected
|
|
||||||
renderInfo.SelectedSprite.ResetAnimation()
|
|
||||||
if renderInfo.SelectedSpriteOverlay != nil {
|
|
||||||
renderInfo.SelectedSpriteOverlay.ResetAnimation()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
case HeroStanceRetreating:
|
|
||||||
if renderInfo.BackWalkSprite.OnLastFrame() {
|
|
||||||
renderInfo.Stance = HeroStanceIdle
|
|
||||||
renderInfo.IdleSprite.ResetAnimation()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !canSelect {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if renderInfo.Stance == HeroStanceSelected {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mouseX := v.uiManager.CursorX
|
|
||||||
mouseY := v.uiManager.CursorY
|
|
||||||
b := renderInfo.SelectionBounds
|
|
||||||
mouseHover := (mouseX >= b.Min.X) && (mouseX <= b.Min.X+b.Max.X) && (mouseY >= b.Min.Y) && (mouseY <= b.Min.Y+b.Max.Y)
|
|
||||||
if mouseHover && v.uiManager.CursorButtonPressed(UI.CursorButtonLeft) {
|
|
||||||
// showEntryUi = true;
|
|
||||||
renderInfo.Stance = HeroStanceApproaching
|
|
||||||
renderInfo.ForwardWalkSprite.ResetAnimation()
|
|
||||||
if renderInfo.ForwardWalkSpriteOverlay != nil {
|
|
||||||
renderInfo.ForwardWalkSpriteOverlay.ResetAnimation()
|
|
||||||
}
|
|
||||||
for _, heroInfo := range v.heroRenderInfo {
|
|
||||||
if heroInfo.Stance != HeroStanceSelected {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
heroInfo.SelectSfx.Stop()
|
|
||||||
heroInfo.DeselectSfx.Play()
|
|
||||||
heroInfo.Stance = HeroStanceRetreating
|
|
||||||
heroInfo.BackWalkSprite.ResetAnimation()
|
|
||||||
if heroInfo.BackWalkSpriteOverlay != nil {
|
|
||||||
heroInfo.BackWalkSpriteOverlay.ResetAnimation()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
v.selectedHero = hero
|
|
||||||
v.updateHeroText()
|
|
||||||
renderInfo.SelectSfx.Play()
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if mouseHover {
|
|
||||||
renderInfo.Stance = HeroStanceIdleSelected
|
|
||||||
} else {
|
|
||||||
renderInfo.Stance = HeroStanceIdle
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.selectedHero == Common.HeroNone && mouseHover {
|
|
||||||
v.selectedHero = hero
|
|
||||||
v.updateHeroText()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *SelectHeroClass) renderHero(screen *ebiten.Image, hero Common.Hero) {
|
|
||||||
renderInfo := v.heroRenderInfo[hero]
|
|
||||||
switch renderInfo.Stance {
|
|
||||||
case HeroStanceIdle:
|
|
||||||
renderInfo.IdleSprite.Draw(screen)
|
|
||||||
case HeroStanceIdleSelected:
|
|
||||||
renderInfo.IdleSelectedSprite.Draw(screen)
|
|
||||||
case HeroStanceApproaching:
|
|
||||||
renderInfo.ForwardWalkSprite.Draw(screen)
|
|
||||||
if renderInfo.ForwardWalkSpriteOverlay != nil {
|
|
||||||
renderInfo.ForwardWalkSpriteOverlay.Draw(screen)
|
|
||||||
}
|
|
||||||
case HeroStanceSelected:
|
|
||||||
renderInfo.SelectedSprite.Draw(screen)
|
|
||||||
if renderInfo.SelectedSpriteOverlay != nil {
|
|
||||||
renderInfo.SelectedSpriteOverlay.Draw(screen)
|
|
||||||
}
|
|
||||||
case HeroStanceRetreating:
|
|
||||||
renderInfo.BackWalkSprite.Draw(screen)
|
|
||||||
if renderInfo.BackWalkSpriteOverlay != nil {
|
|
||||||
renderInfo.BackWalkSpriteOverlay.Draw(screen)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *SelectHeroClass) updateHeroText() {
|
|
||||||
switch v.selectedHero {
|
|
||||||
case Common.HeroNone:
|
|
||||||
return
|
|
||||||
case Common.HeroBarbarian:
|
|
||||||
v.heroClassLabel.SetText(Common.TranslateString("partycharbar"))
|
|
||||||
v.setDescLabels("#1709")
|
|
||||||
case Common.HeroNecromancer:
|
|
||||||
v.heroClassLabel.SetText(Common.TranslateString("partycharnec"))
|
|
||||||
v.setDescLabels("#1704")
|
|
||||||
case Common.HeroPaladin:
|
|
||||||
v.heroClassLabel.SetText(Common.TranslateString("partycharpal"))
|
|
||||||
v.setDescLabels("#1711")
|
|
||||||
case Common.HeroAssassin:
|
|
||||||
v.heroClassLabel.SetText(Common.TranslateString("partycharass"))
|
|
||||||
v.setDescLabels("#305")
|
|
||||||
case Common.HeroSorceress:
|
|
||||||
v.heroClassLabel.SetText(Common.TranslateString("partycharsor"))
|
|
||||||
v.setDescLabels("#1710")
|
|
||||||
case Common.HeroAmazon:
|
|
||||||
v.heroClassLabel.SetText(Common.TranslateString("partycharama"))
|
|
||||||
v.setDescLabels("#1698")
|
|
||||||
case Common.HeroDruid:
|
|
||||||
v.heroClassLabel.SetText(Common.TranslateString("partychardru"))
|
|
||||||
v.setDescLabels("#304")
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
if (selectedHero == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (selectedHero.Value)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
heroClassLabel.Location = new Point(400 - (heroClassLabel.TextArea.Width / 2), 65);
|
|
||||||
heroDesc1Label.Location = new Point(400 - (heroDesc1Label.TextArea.Width / 2), 100);
|
|
||||||
heroDesc2Label.Location = new Point(400 - (heroDesc2Label.TextArea.Width / 2), 115);
|
|
||||||
heroDesc3Label.Location = new Point(400 - (heroDesc3Label.TextArea.Width / 2), 130);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *SelectHeroClass) setDescLabels(descKey string) {
|
|
||||||
heroDesc := Common.TranslateString(descKey)
|
|
||||||
parts := Common.SplitIntoLinesWithMaxWidth(heroDesc, 37)
|
|
||||||
if len(parts) > 1 {
|
|
||||||
v.heroDesc1Label.SetText(parts[0])
|
|
||||||
} else {
|
|
||||||
v.heroDesc1Label.SetText("")
|
|
||||||
}
|
|
||||||
if len(parts) > 1 {
|
|
||||||
v.heroDesc2Label.SetText(parts[1])
|
|
||||||
} else {
|
|
||||||
v.heroDesc2Label.SetText("")
|
|
||||||
}
|
|
||||||
if len(parts) > 2 {
|
|
||||||
v.heroDesc3Label.SetText(parts[2])
|
|
||||||
} else {
|
|
||||||
v.heroDesc3Label.SetText("")
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +1,24 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
"github.com/OpenDiablo2/OpenDiablo2/palettedefs"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// AnimatedEntity represents an entity on the map that can be animated
|
||||||
type AnimatedEntity struct {
|
type AnimatedEntity struct {
|
||||||
|
// LocationX represents the tile X position of the entity
|
||||||
|
LocationX float64
|
||||||
|
// LocationY represents the tile Y position of the entity
|
||||||
|
LocationY float64
|
||||||
dcc *DCC
|
dcc *DCC
|
||||||
cof *Cof
|
cof *Cof
|
||||||
palette PaletteDefs.PaletteType
|
palette palettedefs.PaletteType
|
||||||
base string
|
base string
|
||||||
token string
|
token string
|
||||||
tr string
|
tr string
|
||||||
@ -24,13 +29,12 @@ type AnimatedEntity struct {
|
|||||||
animationSpeed int
|
animationSpeed int
|
||||||
direction int
|
direction int
|
||||||
currentFrame int
|
currentFrame int
|
||||||
LocationX float64
|
|
||||||
LocationY float64
|
|
||||||
frames []*ebiten.Image
|
frames []*ebiten.Image
|
||||||
frameLocations []Rectangle
|
frameLocations []Rectangle
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateAnimatedEntity(base, token, tr string, palette PaletteDefs.PaletteType) *AnimatedEntity {
|
// CreateAnimatedEntity creates an instance of AnimatedEntity
|
||||||
|
func CreateAnimatedEntity(base, token, tr string, palette palettedefs.PaletteType) *AnimatedEntity {
|
||||||
result := &AnimatedEntity{
|
result := &AnimatedEntity{
|
||||||
base: base,
|
base: base,
|
||||||
token: token,
|
token: token,
|
||||||
@ -40,8 +44,10 @@ func CreateAnimatedEntity(base, token, tr string, palette PaletteDefs.PaletteTyp
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DirectionLookup is used to decode the direction offset indexes
|
||||||
var DirectionLookup = []int{3, 15, 4, 8, 0, 9, 5, 10, 1, 11, 6, 12, 2, 13, 7, 14}
|
var DirectionLookup = []int{3, 15, 4, 8, 0, 9, 5, 10, 1, 11, 6, 12, 2, 13, 7, 14}
|
||||||
|
|
||||||
|
// SetMode changes the graphical mode of this animated entity
|
||||||
func (v *AnimatedEntity) SetMode(animationMode, weaponClass string, direction int, provider FileProvider) {
|
func (v *AnimatedEntity) SetMode(animationMode, weaponClass string, direction int, provider FileProvider) {
|
||||||
dccPath := fmt.Sprintf("%s/%s/tr/%str%s%s%s.dcc", v.base, v.token, v.token, v.tr, animationMode, weaponClass)
|
dccPath := fmt.Sprintf("%s/%s/tr/%str%s%s%s.dcc", v.base, v.token, v.token, v.tr, animationMode, weaponClass)
|
||||||
v.dcc = LoadDCC(dccPath, provider)
|
v.dcc = LoadDCC(dccPath, provider)
|
||||||
@ -53,6 +59,7 @@ func (v *AnimatedEntity) SetMode(animationMode, weaponClass string, direction in
|
|||||||
v.cacheFrames()
|
v.cacheFrames()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render draws this animated entity onto the target
|
||||||
func (v *AnimatedEntity) Render(target *ebiten.Image, offsetX, offsetY int) {
|
func (v *AnimatedEntity) Render(target *ebiten.Image, offsetX, offsetY int) {
|
||||||
for v.lastFrameTime.Add(time.Millisecond * time.Duration(v.animationSpeed)).Before(time.Now()) {
|
for v.lastFrameTime.Add(time.Millisecond * time.Duration(v.animationSpeed)).Before(time.Now()) {
|
||||||
v.lastFrameTime = v.lastFrameTime.Add(time.Millisecond * time.Duration(v.animationSpeed))
|
v.lastFrameTime = v.lastFrameTime.Add(time.Millisecond * time.Duration(v.animationSpeed))
|
@ -1,24 +1,31 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
"github.com/OpenDiablo2/OpenDiablo2/resourcepaths"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// AnimationDataRecord represents a single entry in the animation data dictionary file
|
||||||
type AnimationDataRecord struct {
|
type AnimationDataRecord struct {
|
||||||
|
// COFName is the name of the COF file used for this animation
|
||||||
COFName string
|
COFName string
|
||||||
|
// FramesPerDirection specifies how many frames are in each direction
|
||||||
FramesPerDirection int
|
FramesPerDirection int
|
||||||
|
// AnimationSpeed represents a value of X where the rate is a ration of (x/255) at 25FPS
|
||||||
AnimationSpeed int
|
AnimationSpeed int
|
||||||
|
// Flags are used in keyframe triggers
|
||||||
Flags []byte
|
Flags []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AnimationData represents all of the animation data records, mapped by the COF index
|
||||||
var AnimationData map[string][]*AnimationDataRecord
|
var AnimationData map[string][]*AnimationDataRecord
|
||||||
|
|
||||||
|
// LoadAnimationData loads the animation data table into the global AnimationData dictionary
|
||||||
func LoadAnimationData(fileProvider FileProvider) {
|
func LoadAnimationData(fileProvider FileProvider) {
|
||||||
AnimationData = make(map[string][]*AnimationDataRecord)
|
AnimationData = make(map[string][]*AnimationDataRecord)
|
||||||
rawData := fileProvider.LoadFile(ResourcePaths.AnimationData)
|
rawData := fileProvider.LoadFile(resourcepaths.AnimationData)
|
||||||
streamReader := CreateStreamReader(rawData)
|
streamReader := CreateStreamReader(rawData)
|
||||||
for !streamReader.Eof() {
|
for !streamReader.Eof() {
|
||||||
dataCount := int(streamReader.GetInt32())
|
dataCount := int(streamReader.GetInt32())
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
type BitMuncher struct {
|
type BitMuncher struct {
|
||||||
data []byte
|
data []byte
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import "log"
|
import "log"
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
type BuildInfoRecord struct {
|
type BuildInfoRecord struct {
|
||||||
Branch string
|
Branch string
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import "strings"
|
import "strings"
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image/color"
|
"image/color"
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import "github.com/hajimehoshi/ebiten"
|
import "github.com/hajimehoshi/ebiten"
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import "github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
import "github.com/OpenDiablo2/OpenDiablo2/palettedefs"
|
||||||
|
|
||||||
// FileProvider is an instance that can provide different types of files
|
// FileProvider is an instance that can provide different types of files
|
||||||
type FileProvider interface {
|
type FileProvider interface {
|
||||||
LoadFile(fileName string) []byte
|
LoadFile(fileName string) []byte
|
||||||
LoadSprite(fileName string, palette PaletteDefs.PaletteType) *Sprite
|
LoadSprite(fileName string, palette palettedefs.PaletteType) *Sprite
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
type Hero int
|
type Hero int
|
||||||
|
|
@ -1,10 +1,10 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
"github.com/OpenDiablo2/OpenDiablo2/resourcepaths"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LevelPresetRecord struct {
|
type LevelPresetRecord struct {
|
||||||
@ -73,7 +73,7 @@ var LevelPresets map[int]*LevelPresetRecord
|
|||||||
|
|
||||||
func LoadLevelPresets(fileProvider FileProvider) {
|
func LoadLevelPresets(fileProvider FileProvider) {
|
||||||
LevelPresets = make(map[int]*LevelPresetRecord)
|
LevelPresets = make(map[int]*LevelPresetRecord)
|
||||||
data := strings.Split(string(fileProvider.LoadFile(ResourcePaths.LevelPreset)), "\r\n")[1:]
|
data := strings.Split(string(fileProvider.LoadFile(resourcepaths.LevelPreset)), "\r\n")[1:]
|
||||||
for _, line := range data {
|
for _, line := range data {
|
||||||
if len(line) == 0 {
|
if len(line) == 0 {
|
||||||
continue
|
continue
|
@ -1,10 +1,10 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
"github.com/OpenDiablo2/OpenDiablo2/resourcepaths"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LevelTypeRecord struct {
|
type LevelTypeRecord struct {
|
||||||
@ -19,7 +19,7 @@ type LevelTypeRecord struct {
|
|||||||
var LevelTypes []LevelTypeRecord
|
var LevelTypes []LevelTypeRecord
|
||||||
|
|
||||||
func LoadLevelTypes(fileProvider FileProvider) {
|
func LoadLevelTypes(fileProvider FileProvider) {
|
||||||
data := strings.Split(string(fileProvider.LoadFile(ResourcePaths.LevelType)), "\r\n")[1:]
|
data := strings.Split(string(fileProvider.LoadFile(resourcepaths.LevelType)), "\r\n")[1:]
|
||||||
LevelTypes = make([]LevelTypeRecord, len(data))
|
LevelTypes = make([]LevelTypeRecord, len(data))
|
||||||
for i, line := range data {
|
for i, line := range data {
|
||||||
idx := -1
|
idx := -1
|
@ -1,9 +1,9 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
"github.com/OpenDiablo2/OpenDiablo2/resourcepaths"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LevelWarpRecord struct {
|
type LevelWarpRecord struct {
|
||||||
@ -25,7 +25,7 @@ var LevelWarps map[int]*LevelWarpRecord
|
|||||||
|
|
||||||
func LoadLevelWarps(fileProvider FileProvider) {
|
func LoadLevelWarps(fileProvider FileProvider) {
|
||||||
LevelWarps = make(map[int]*LevelWarpRecord)
|
LevelWarps = make(map[int]*LevelWarpRecord)
|
||||||
levelWarpData := fileProvider.LoadFile(ResourcePaths.LevelWarp)
|
levelWarpData := fileProvider.LoadFile(resourcepaths.LevelWarp)
|
||||||
streamReader := CreateStreamReader(levelWarpData)
|
streamReader := CreateStreamReader(levelWarpData)
|
||||||
numRecords := int(streamReader.GetInt32())
|
numRecords := int(streamReader.GetInt32())
|
||||||
for i := 0; i < numRecords; i++ {
|
for i := 0; i < numRecords; i++ {
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
// Min returns the lower of two values
|
// Min returns the lower of two values
|
||||||
func Min(a, b uint32) uint32 {
|
func Min(a, b uint32) uint32 {
|
@ -1,10 +1,10 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
"github.com/OpenDiablo2/OpenDiablo2/resourcepaths"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MissileCalcParam struct {
|
type MissileCalcParam struct {
|
||||||
@ -293,7 +293,7 @@ var Missiles map[int]*MissileRecord
|
|||||||
|
|
||||||
func LoadMissiles(fileProvider FileProvider) {
|
func LoadMissiles(fileProvider FileProvider) {
|
||||||
Missiles = make(map[int]*MissileRecord)
|
Missiles = make(map[int]*MissileRecord)
|
||||||
data := strings.Split(string(fileProvider.LoadFile(ResourcePaths.Missiles)), "\r\n")[1:]
|
data := strings.Split(string(fileProvider.LoadFile(resourcepaths.Missiles)), "\r\n")[1:]
|
||||||
for _, line := range data {
|
for _, line := range data {
|
||||||
if len(line) == 0 {
|
if len(line) == 0 {
|
||||||
continue
|
continue
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
type MpqFileRecord struct {
|
type MpqFileRecord struct {
|
||||||
MpqFile string
|
MpqFile string
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
@ -1,10 +1,10 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
"github.com/OpenDiablo2/OpenDiablo2/resourcepaths"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ObjectTypeRecord struct {
|
type ObjectTypeRecord struct {
|
||||||
@ -15,7 +15,7 @@ type ObjectTypeRecord struct {
|
|||||||
var ObjectTypes []ObjectTypeRecord
|
var ObjectTypes []ObjectTypeRecord
|
||||||
|
|
||||||
func LoadObjectTypes(fileProvider FileProvider) {
|
func LoadObjectTypes(fileProvider FileProvider) {
|
||||||
objectTypeData := fileProvider.LoadFile(ResourcePaths.ObjectType)
|
objectTypeData := fileProvider.LoadFile(resourcepaths.ObjectType)
|
||||||
streamReader := CreateStreamReader(objectTypeData)
|
streamReader := CreateStreamReader(objectTypeData)
|
||||||
count := streamReader.GetInt32()
|
count := streamReader.GetInt32()
|
||||||
ObjectTypes = make([]ObjectTypeRecord, count)
|
ObjectTypes = make([]ObjectTypeRecord, count)
|
@ -1,10 +1,10 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
"github.com/OpenDiablo2/OpenDiablo2/resourcepaths"
|
||||||
)
|
)
|
||||||
|
|
||||||
// An ObjectRecord represents the settings for one type of object from objects.txt
|
// An ObjectRecord represents the settings for one type of object from objects.txt
|
||||||
@ -337,7 +337,7 @@ var Objects map[int]*ObjectRecord
|
|||||||
|
|
||||||
func LoadObjects(fileProvider FileProvider) {
|
func LoadObjects(fileProvider FileProvider) {
|
||||||
Objects = make(map[int]*ObjectRecord)
|
Objects = make(map[int]*ObjectRecord)
|
||||||
data := strings.Split(string(fileProvider.LoadFile(ResourcePaths.ObjectDetails)), "\r\n")[1:]
|
data := strings.Split(string(fileProvider.LoadFile(resourcepaths.ObjectDetails)), "\r\n")[1:]
|
||||||
for _, line := range data {
|
for _, line := range data {
|
||||||
if len(line) == 0 {
|
if len(line) == 0 {
|
||||||
continue
|
continue
|
@ -1,9 +1,9 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
"github.com/OpenDiablo2/OpenDiablo2/palettedefs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PaletteRGB represents a color in a palette
|
// PaletteRGB represents a color in a palette
|
||||||
@ -13,14 +13,14 @@ type PaletteRGB struct {
|
|||||||
|
|
||||||
// PaletteType represents a palette
|
// PaletteType represents a palette
|
||||||
type PaletteRec struct {
|
type PaletteRec struct {
|
||||||
Name PaletteDefs.PaletteType
|
Name palettedefs.PaletteType
|
||||||
Colors [256]PaletteRGB
|
Colors [256]PaletteRGB
|
||||||
}
|
}
|
||||||
|
|
||||||
var Palettes map[PaletteDefs.PaletteType]PaletteRec
|
var Palettes map[palettedefs.PaletteType]PaletteRec
|
||||||
|
|
||||||
// CreatePalette creates a palette
|
// CreatePalette creates a palette
|
||||||
func CreatePalette(name PaletteDefs.PaletteType, data []byte) PaletteRec {
|
func CreatePalette(name palettedefs.PaletteType, data []byte) PaletteRec {
|
||||||
result := PaletteRec{Name: name}
|
result := PaletteRec{Name: name}
|
||||||
|
|
||||||
for i := 0; i <= 255; i++ {
|
for i := 0; i <= 255; i++ {
|
||||||
@ -34,13 +34,13 @@ func CreatePalette(name PaletteDefs.PaletteType, data []byte) PaletteRec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func LoadPalettes(mpqFiles map[string]string, fileProvider FileProvider) {
|
func LoadPalettes(mpqFiles map[string]string, fileProvider FileProvider) {
|
||||||
Palettes = make(map[PaletteDefs.PaletteType]PaletteRec)
|
Palettes = make(map[palettedefs.PaletteType]PaletteRec)
|
||||||
for _, pal := range []string{
|
for _, pal := range []string{
|
||||||
"act1", "act2", "act3", "act4", "act5", "endgame", "endgame2", "fechar", "loading",
|
"act1", "act2", "act3", "act4", "act5", "endgame", "endgame2", "fechar", "loading",
|
||||||
"menu0", "menu1", "menu2", "menu3", "menu4", "sky", "static", "trademark", "units",
|
"menu0", "menu1", "menu2", "menu3", "menu4", "sky", "static", "trademark", "units",
|
||||||
} {
|
} {
|
||||||
filePath := `data\global\palette\` + pal + `\pal.dat`
|
filePath := `data\global\palette\` + pal + `\pal.dat`
|
||||||
paletteName := PaletteDefs.PaletteType(pal)
|
paletteName := palettedefs.PaletteType(pal)
|
||||||
palette := CreatePalette(paletteName, fileProvider.LoadFile(filePath))
|
palette := CreatePalette(paletteName, fileProvider.LoadFile(filePath))
|
||||||
Palettes[paletteName] = palette
|
Palettes[paletteName] = palette
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
type Rectangle struct {
|
type Rectangle struct {
|
||||||
Left int
|
Left int
|
@ -1,10 +1,10 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
"github.com/OpenDiablo2/OpenDiablo2/resourcepaths"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SoundEntry represents a sound entry
|
// SoundEntry represents a sound entry
|
||||||
@ -73,7 +73,7 @@ var Sounds map[string]SoundEntry
|
|||||||
|
|
||||||
func LoadSounds(fileProvider FileProvider) {
|
func LoadSounds(fileProvider FileProvider) {
|
||||||
Sounds = make(map[string]SoundEntry)
|
Sounds = make(map[string]SoundEntry)
|
||||||
soundData := strings.Split(string(fileProvider.LoadFile(ResourcePaths.SoundSettings)), "\r\n")[1:]
|
soundData := strings.Split(string(fileProvider.LoadFile(resourcepaths.SoundSettings)), "\r\n")[1:]
|
||||||
for _, line := range soundData {
|
for _, line := range soundData {
|
||||||
if len(line) == 0 {
|
if len(line) == 0 {
|
||||||
continue
|
continue
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
// StreamWriter allows you to create a byte array by streaming in writes of various sizes
|
// StreamWriter allows you to create a byte array by streaming in writes of various sizes
|
||||||
type StreamWriter struct {
|
type StreamWriter struct {
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
@ -1,4 +1,4 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
@ -1,10 +1,10 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
"github.com/OpenDiablo2/OpenDiablo2/resourcepaths"
|
||||||
)
|
)
|
||||||
|
|
||||||
type textDictionaryHashEntry struct {
|
type textDictionaryHashEntry struct {
|
||||||
@ -29,9 +29,9 @@ func TranslateString(key string) string {
|
|||||||
func LoadTextDictionary(fileProvider FileProvider) {
|
func LoadTextDictionary(fileProvider FileProvider) {
|
||||||
lookupTable = make(map[string]string)
|
lookupTable = make(map[string]string)
|
||||||
|
|
||||||
loadDictionary(fileProvider, ResourcePaths.PatchStringTable)
|
loadDictionary(fileProvider, resourcepaths.PatchStringTable)
|
||||||
loadDictionary(fileProvider, ResourcePaths.ExpansionStringTable)
|
loadDictionary(fileProvider, resourcepaths.ExpansionStringTable)
|
||||||
loadDictionary(fileProvider, ResourcePaths.StringTable)
|
loadDictionary(fileProvider, resourcepaths.StringTable)
|
||||||
log.Printf("Loaded %d entries from the string table", len(lookupTable))
|
log.Printf("Loaded %d entries from the string table", len(lookupTable))
|
||||||
}
|
}
|
||||||
|
|
@ -1,10 +1,10 @@
|
|||||||
package Common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
"github.com/OpenDiablo2/OpenDiablo2/resourcepaths"
|
||||||
)
|
)
|
||||||
|
|
||||||
type WeaponRecord struct {
|
type WeaponRecord struct {
|
||||||
@ -268,7 +268,7 @@ var Weapons map[string]*WeaponRecord
|
|||||||
|
|
||||||
func LoadWeapons(fileProvider FileProvider) {
|
func LoadWeapons(fileProvider FileProvider) {
|
||||||
Weapons = make(map[string]*WeaponRecord)
|
Weapons = make(map[string]*WeaponRecord)
|
||||||
data := strings.Split(string(fileProvider.LoadFile(ResourcePaths.Weapons)), "\r\n")[1:]
|
data := strings.Split(string(fileProvider.LoadFile(resourcepaths.Weapons)), "\r\n")[1:]
|
||||||
for _, line := range data {
|
for _, line := range data {
|
||||||
if len(line) == 0 {
|
if len(line) == 0 {
|
||||||
continue
|
continue
|
@ -27,12 +27,12 @@
|
|||||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
//
|
//
|
||||||
package Compression
|
package compression
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// linkedNode is a node which is both hierachcical (parent/child) and doubly linked (next/prev)
|
// linkedNode is a node which is both hierachcical (parent/child) and doubly linked (next/prev)
|
||||||
@ -182,7 +182,7 @@ var sPrime = [][]byte{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func decode(input *Common.BitStream, head *linkedNode) *linkedNode {
|
func decode(input *common.BitStream, head *linkedNode) *linkedNode {
|
||||||
node := head
|
node := head
|
||||||
|
|
||||||
for node.Child0 != nil {
|
for node.Child0 != nil {
|
||||||
@ -344,8 +344,8 @@ func HuffmanDecompress(data []byte) []byte {
|
|||||||
tail := buildList(sPrime[comptype])
|
tail := buildList(sPrime[comptype])
|
||||||
head := buildTree(tail)
|
head := buildTree(tail)
|
||||||
|
|
||||||
outputstream := Common.CreateStreamWriter()
|
outputstream := common.CreateStreamWriter()
|
||||||
bitstream := Common.CreateBitStream(data[1:])
|
bitstream := common.CreateBitStream(data[1:])
|
||||||
var decoded int
|
var decoded int
|
||||||
for true {
|
for true {
|
||||||
node := decode(bitstream, head)
|
node := decode(bitstream, head)
|
@ -1,7 +1,7 @@
|
|||||||
package Compression
|
package compression
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var sLookup = []int{
|
var sLookup = []int{
|
||||||
@ -30,8 +30,8 @@ func WavDecompress(data []byte, channelCount int) []byte {
|
|||||||
Array1 := []int{0x2c, 0x2c}
|
Array1 := []int{0x2c, 0x2c}
|
||||||
Array2 := make([]int, channelCount)
|
Array2 := make([]int, channelCount)
|
||||||
|
|
||||||
input := Common.CreateStreamReader(data)
|
input := common.CreateStreamReader(data)
|
||||||
output := Common.CreateStreamWriter()
|
output := common.CreateStreamWriter()
|
||||||
input.GetByte()
|
input.GetByte()
|
||||||
|
|
||||||
shift := input.GetByte()
|
shift := input.GetByte()
|
@ -1,4 +1,4 @@
|
|||||||
package Core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@ -10,16 +10,16 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/MPQ"
|
"github.com/OpenDiablo2/OpenDiablo2/mpq"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
"github.com/OpenDiablo2/OpenDiablo2/palettedefs"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Sound"
|
"github.com/OpenDiablo2/OpenDiablo2/sound"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
"github.com/OpenDiablo2/OpenDiablo2/resourcepaths"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Scenes"
|
"github.com/OpenDiablo2/OpenDiablo2/scenes"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/UI"
|
"github.com/OpenDiablo2/OpenDiablo2/ui"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/mitchellh/go-homedir"
|
"github.com/mitchellh/go-homedir"
|
||||||
@ -45,13 +45,13 @@ type Engine struct {
|
|||||||
Settings *EngineConfig // Engine configuration settings from json file
|
Settings *EngineConfig // Engine configuration settings from json file
|
||||||
Files map[string]string // Map that defines which files are in which MPQs
|
Files map[string]string // Map that defines which files are in which MPQs
|
||||||
CheckedPatch map[string]bool // First time we check a file, we'll check if it's in the patch. This notes that we've already checked that.
|
CheckedPatch map[string]bool // First time we check a file, we'll check if it's in the patch. This notes that we've already checked that.
|
||||||
LoadingSprite *Common.Sprite // The sprite shown when loading stuff
|
LoadingSprite *common.Sprite // The sprite shown when loading stuff
|
||||||
loadingProgress float64 // LoadingProcess is a range between 0.0 and 1.0. If set, loading screen displays.
|
loadingProgress float64 // LoadingProcess is a range between 0.0 and 1.0. If set, loading screen displays.
|
||||||
stepLoadingSize float64 // The size for each loading step
|
stepLoadingSize float64 // The size for each loading step
|
||||||
CurrentScene Scenes.Scene // The current scene being rendered
|
CurrentScene scenes.Scene // The current scene being rendered
|
||||||
UIManager *UI.Manager // The UI manager
|
UIManager *ui.Manager // The UI manager
|
||||||
SoundManager *Sound.Manager // The sound manager
|
SoundManager *sound.Manager // The sound manager
|
||||||
nextScene Scenes.Scene // The next scene to be loaded at the end of the game loop
|
nextScene scenes.Scene // The next scene to be loaded at the end of the game loop
|
||||||
fullscreenKey bool // When true, the fullscreen toggle is still being pressed
|
fullscreenKey bool // When true, the fullscreen toggle is still being pressed
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,27 +62,27 @@ func CreateEngine() *Engine {
|
|||||||
nextScene: nil,
|
nextScene: nil,
|
||||||
}
|
}
|
||||||
result.loadConfigurationFile()
|
result.loadConfigurationFile()
|
||||||
ResourcePaths.LanguageCode = result.Settings.Language
|
resourcepaths.LanguageCode = result.Settings.Language
|
||||||
result.mapMpqFiles()
|
result.mapMpqFiles()
|
||||||
Common.LoadPalettes(result.Files, result)
|
common.LoadPalettes(result.Files, result)
|
||||||
Common.LoadTextDictionary(result)
|
common.LoadTextDictionary(result)
|
||||||
Common.LoadLevelTypes(result)
|
common.LoadLevelTypes(result)
|
||||||
Common.LoadLevelPresets(result)
|
common.LoadLevelPresets(result)
|
||||||
Common.LoadLevelWarps(result)
|
common.LoadLevelWarps(result)
|
||||||
Common.LoadObjectTypes(result)
|
common.LoadObjectTypes(result)
|
||||||
Common.LoadObjects(result)
|
common.LoadObjects(result)
|
||||||
Common.LoadWeapons(result)
|
common.LoadWeapons(result)
|
||||||
Common.LoadMissiles(result)
|
common.LoadMissiles(result)
|
||||||
Common.LoadSounds(result)
|
common.LoadSounds(result)
|
||||||
Common.LoadObjectLookups()
|
common.LoadObjectLookups()
|
||||||
Common.LoadAnimationData(result)
|
common.LoadAnimationData(result)
|
||||||
result.SoundManager = Sound.CreateManager(result)
|
result.SoundManager = sound.CreateManager(result)
|
||||||
result.SoundManager.SetVolumes(result.Settings.BgmVolume, result.Settings.SfxVolume)
|
result.SoundManager.SetVolumes(result.Settings.BgmVolume, result.Settings.SfxVolume)
|
||||||
result.UIManager = UI.CreateManager(result, *result.SoundManager)
|
result.UIManager = ui.CreateManager(result, *result.SoundManager)
|
||||||
result.LoadingSprite = result.LoadSprite(ResourcePaths.LoadingScreen, PaletteDefs.Loading)
|
result.LoadingSprite = result.LoadSprite(resourcepaths.LoadingScreen, palettedefs.Loading)
|
||||||
loadingSpriteSizeX, loadingSpriteSizeY := result.LoadingSprite.GetSize()
|
loadingSpriteSizeX, loadingSpriteSizeY := result.LoadingSprite.GetSize()
|
||||||
result.LoadingSprite.MoveTo(int(400-(loadingSpriteSizeX/2)), int(300+(loadingSpriteSizeY/2)))
|
result.LoadingSprite.MoveTo(int(400-(loadingSpriteSizeX/2)), int(300+(loadingSpriteSizeY/2)))
|
||||||
result.SetNextScene(Scenes.CreateMainMenu(result, result, result.UIManager, result.SoundManager))
|
result.SetNextScene(scenes.CreateMainMenu(result, result, result.UIManager, result.SoundManager))
|
||||||
//result.SetNextScene(Scenes.CreateBlizzardIntro(result, result))
|
//result.SetNextScene(Scenes.CreateBlizzardIntro(result, result))
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -238,7 +238,7 @@ func (v *Engine) LoadFile(fileName string) []byte {
|
|||||||
var mutex sync.Mutex
|
var mutex sync.Mutex
|
||||||
|
|
||||||
func (v *Engine) LoadFile(fileName string) []byte {
|
func (v *Engine) LoadFile(fileName string) []byte {
|
||||||
fileName = strings.ReplaceAll(fileName, "{LANG}", ResourcePaths.LanguageCode)
|
fileName = strings.ReplaceAll(fileName, "{LANG}", resourcepaths.LanguageCode)
|
||||||
fileName = strings.ToLower(fileName)
|
fileName = strings.ToLower(fileName)
|
||||||
fileName = strings.ReplaceAll(fileName, `/`, "\\")
|
fileName = strings.ReplaceAll(fileName, `/`, "\\")
|
||||||
if fileName[0] == '\\' {
|
if fileName[0] == '\\' {
|
||||||
@ -249,12 +249,12 @@ func (v *Engine) LoadFile(fileName string) []byte {
|
|||||||
// TODO: May want to cache some things if performance becomes an issue
|
// TODO: May want to cache some things if performance becomes an issue
|
||||||
cachedMpqFile, cacheExists := v.Files[fileName]
|
cachedMpqFile, cacheExists := v.Files[fileName]
|
||||||
if cacheExists {
|
if cacheExists {
|
||||||
mpq, _ := MPQ.Load(cachedMpqFile)
|
mpq, _ := mpq.Load(cachedMpqFile)
|
||||||
result, _ := mpq.ReadFile(fileName)
|
result, _ := mpq.ReadFile(fileName)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
for _, mpqFile := range v.Settings.MpqLoadOrder {
|
for _, mpqFile := range v.Settings.MpqLoadOrder {
|
||||||
mpq, _ := MPQ.Load(path.Join(v.Settings.MpqPath, mpqFile))
|
mpq, _ := mpq.Load(path.Join(v.Settings.MpqPath, mpqFile))
|
||||||
if !mpq.FileExists(fileName) {
|
if !mpq.FileExists(fileName) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -272,9 +272,9 @@ func (v *Engine) IsLoading() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// LoadSprite loads a sprite from the game's data files
|
// LoadSprite loads a sprite from the game's data files
|
||||||
func (v *Engine) LoadSprite(fileName string, palette PaletteDefs.PaletteType) *Common.Sprite {
|
func (v *Engine) LoadSprite(fileName string, palette palettedefs.PaletteType) *common.Sprite {
|
||||||
data := v.LoadFile(fileName)
|
data := v.LoadFile(fileName)
|
||||||
sprite := Common.CreateSprite(data, Common.Palettes[palette])
|
sprite := common.CreateSprite(data, common.Palettes[palette])
|
||||||
return sprite
|
return sprite
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,7 +328,7 @@ func (v *Engine) Update() {
|
|||||||
// Draw draws the game
|
// Draw draws the game
|
||||||
func (v *Engine) Draw(screen *ebiten.Image) {
|
func (v *Engine) Draw(screen *ebiten.Image) {
|
||||||
if v.loadingProgress < 1.0 {
|
if v.loadingProgress < 1.0 {
|
||||||
v.LoadingSprite.Frame = uint8(Common.Max(0, Common.Min(uint32(len(v.LoadingSprite.Frames)-1), uint32(float64(len(v.LoadingSprite.Frames)-1)*v.loadingProgress))))
|
v.LoadingSprite.Frame = uint8(common.Max(0, common.Min(uint32(len(v.LoadingSprite.Frames)-1), uint32(float64(len(v.LoadingSprite.Frames)-1)*v.loadingProgress))))
|
||||||
v.LoadingSprite.Draw(screen)
|
v.LoadingSprite.Draw(screen)
|
||||||
} else {
|
} else {
|
||||||
if v.CurrentScene == nil {
|
if v.CurrentScene == nil {
|
||||||
@ -340,7 +340,7 @@ func (v *Engine) Draw(screen *ebiten.Image) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetNextScene tells the engine what scene to load on the next update cycle
|
// SetNextScene tells the engine what scene to load on the next update cycle
|
||||||
func (v *Engine) SetNextScene(nextScene Scenes.Scene) {
|
func (v *Engine) SetNextScene(nextScene scenes.Scene) {
|
||||||
v.nextScene = nextScene
|
v.nextScene = nextScene
|
||||||
}
|
}
|
||||||
|
|
6
go.sum
6
go.sum
@ -65,6 +65,8 @@ golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+o
|
|||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
|
||||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
||||||
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/mobile v0.0.0-20180806140643-507816974b79/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
golang.org/x/mobile v0.0.0-20180806140643-507816974b79/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||||
golang.org/x/mobile v0.0.0-20190127143845-a42111704963 h1:2HSxAhImj2OpXsNjXSqfnv1xtqeCpDjwPB3o1DnQqKM=
|
golang.org/x/mobile v0.0.0-20190127143845-a42111704963 h1:2HSxAhImj2OpXsNjXSqfnv1xtqeCpDjwPB3o1DnQqKM=
|
||||||
golang.org/x/mobile v0.0.0-20190127143845-a42111704963/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
golang.org/x/mobile v0.0.0-20190127143845-a42111704963/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||||
@ -92,10 +94,14 @@ golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd h1:3x5uuvBgE6oaXJjCOvpCC1Ipg
|
|||||||
golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/tools v0.0.0-20190202235157-7414d4c1f71c/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190202235157-7414d4c1f71c/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190909214602-067311248421/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190909214602-067311248421/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191026034945-b2104f82a97d h1:QFO0Wgcqcp8nI9hbisKDTBsmfwrvLswk2T73QDZZgVo=
|
||||||
golang.org/x/tools v0.0.0-20191026034945-b2104f82a97d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191026034945-b2104f82a97d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191107010934-f79515f33823 h1:akkRBeitX2EZP59KdtKw310CI4WGPCNPyrLbE7WZA8Y=
|
||||||
|
golang.org/x/tools v0.0.0-20191107010934-f79515f33823/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
17
main.go
17
main.go
@ -6,31 +6,34 @@ import (
|
|||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/ebitenutil"
|
"github.com/hajimehoshi/ebiten/ebitenutil"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Core"
|
"github.com/OpenDiablo2/OpenDiablo2/core"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/MPQ"
|
"github.com/OpenDiablo2/OpenDiablo2/mpq"
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// GitBranch is set by the CI build process to the name of the branch
|
||||||
var GitBranch string
|
var GitBranch string
|
||||||
|
|
||||||
|
// GitCommit is set by the CI build process to the commit hash
|
||||||
var GitCommit string
|
var GitCommit string
|
||||||
var d2Engine *Core.Engine
|
var d2Engine *core.Engine
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if len(GitBranch) == 0 {
|
if len(GitBranch) == 0 {
|
||||||
GitBranch = "Local Build"
|
GitBranch = "Local Build"
|
||||||
GitCommit = ""
|
GitCommit = ""
|
||||||
}
|
}
|
||||||
Common.SetBuildInfo(GitBranch, GitCommit)
|
common.SetBuildInfo(GitBranch, GitCommit)
|
||||||
log.SetFlags(log.Ldate | log.LUTC | log.Lmicroseconds | log.Llongfile)
|
log.SetFlags(log.Ldate | log.LUTC | log.Lmicroseconds | log.Llongfile)
|
||||||
log.Println("OpenDiablo2 - Open source Diablo 2 engine")
|
log.Println("OpenDiablo2 - Open source Diablo 2 engine")
|
||||||
_, iconImage, err := ebitenutil.NewImageFromFile("d2logo.png", ebiten.FilterLinear)
|
_, iconImage, err := ebitenutil.NewImageFromFile("d2logo.png", ebiten.FilterLinear)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ebiten.SetWindowIcon([]image.Image{iconImage})
|
ebiten.SetWindowIcon([]image.Image{iconImage})
|
||||||
}
|
}
|
||||||
MPQ.InitializeCryptoBuffer()
|
mpq.InitializeCryptoBuffer()
|
||||||
d2Engine = Core.CreateEngine()
|
d2Engine = core.CreateEngine()
|
||||||
ebiten.SetCursorVisible(false)
|
ebiten.SetCursorVisible(false)
|
||||||
ebiten.SetFullscreen(d2Engine.Settings.FullScreen)
|
ebiten.SetFullscreen(d2Engine.Settings.FullScreen)
|
||||||
ebiten.SetRunnableInBackground(d2Engine.Settings.RunInBackground)
|
ebiten.SetRunnableInBackground(d2Engine.Settings.RunInBackground)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package Map
|
package _map
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var dirLookup = []int32{
|
var dirLookup = []int32{
|
||||||
@ -79,7 +79,7 @@ type Object struct {
|
|||||||
Y int32
|
Y int32
|
||||||
Flags int32
|
Flags int32
|
||||||
Paths []Path
|
Paths []Path
|
||||||
Lookup *Common.ObjectLookupRecord
|
Lookup *common.ObjectLookupRecord
|
||||||
}
|
}
|
||||||
|
|
||||||
type DS1 struct {
|
type DS1 struct {
|
||||||
@ -99,7 +99,7 @@ type DS1 struct {
|
|||||||
SubstitutionGroups []SubstitutionGroup
|
SubstitutionGroups []SubstitutionGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadDS1(path string, fileProvider Common.FileProvider) *DS1 {
|
func LoadDS1(path string, fileProvider common.FileProvider) *DS1 {
|
||||||
ds1 := &DS1{
|
ds1 := &DS1{
|
||||||
NumberOfFloors: 1,
|
NumberOfFloors: 1,
|
||||||
NumberOfWalls: 1,
|
NumberOfWalls: 1,
|
||||||
@ -107,12 +107,12 @@ func LoadDS1(path string, fileProvider Common.FileProvider) *DS1 {
|
|||||||
NumberOfSubstitutionLayers: 0,
|
NumberOfSubstitutionLayers: 0,
|
||||||
}
|
}
|
||||||
fileData := fileProvider.LoadFile(path)
|
fileData := fileProvider.LoadFile(path)
|
||||||
br := Common.CreateStreamReader(fileData)
|
br := common.CreateStreamReader(fileData)
|
||||||
ds1.Version = br.GetInt32()
|
ds1.Version = br.GetInt32()
|
||||||
ds1.Width = br.GetInt32() + 1
|
ds1.Width = br.GetInt32() + 1
|
||||||
ds1.Height = br.GetInt32() + 1
|
ds1.Height = br.GetInt32() + 1
|
||||||
if ds1.Version >= 8 {
|
if ds1.Version >= 8 {
|
||||||
ds1.Act = Common.MinInt32(5, br.GetInt32()+1)
|
ds1.Act = common.MinInt32(5, br.GetInt32()+1)
|
||||||
}
|
}
|
||||||
if ds1.Version >= 10 {
|
if ds1.Version >= 10 {
|
||||||
ds1.SubstitutionType = br.GetInt32()
|
ds1.SubstitutionType = br.GetInt32()
|
||||||
@ -250,7 +250,7 @@ func LoadDS1(path string, fileProvider Common.FileProvider) *DS1 {
|
|||||||
newObject.X = br.GetInt32()
|
newObject.X = br.GetInt32()
|
||||||
newObject.Y = br.GetInt32()
|
newObject.Y = br.GetInt32()
|
||||||
newObject.Flags = br.GetInt32()
|
newObject.Flags = br.GetInt32()
|
||||||
newObject.Lookup = Common.LookupObject(int(ds1.Act), int(newObject.Type), int(newObject.Id))
|
newObject.Lookup = common.LookupObject(int(ds1.Act), int(newObject.Type), int(newObject.Id))
|
||||||
ds1.Objects = append(ds1.Objects, newObject)
|
ds1.Objects = append(ds1.Objects, newObject)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,9 +1,9 @@
|
|||||||
package Map
|
package _map
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// https://d2mods.info/forum/viewtopic.php?t=65163
|
// https://d2mods.info/forum/viewtopic.php?t=65163
|
||||||
@ -47,10 +47,10 @@ const (
|
|||||||
BlockFormatIsometric BlockDataFormat = 1
|
BlockFormatIsometric BlockDataFormat = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
func LoadDT1(path string, fileProvider Common.FileProvider) *DT1 {
|
func LoadDT1(path string, fileProvider common.FileProvider) *DT1 {
|
||||||
result := &DT1{}
|
result := &DT1{}
|
||||||
fileData := fileProvider.LoadFile(path)
|
fileData := fileProvider.LoadFile(path)
|
||||||
br := Common.CreateStreamReader(fileData)
|
br := common.CreateStreamReader(fileData)
|
||||||
ver1 := br.GetInt32()
|
ver1 := br.GetInt32()
|
||||||
ver2 := br.GetInt32()
|
ver2 := br.GetInt32()
|
||||||
if ver1 != 7 || ver2 != 6 {
|
if ver1 != 7 || ver2 != 6 {
|
@ -1,30 +1,30 @@
|
|||||||
package Map
|
package _map
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Sound"
|
"github.com/OpenDiablo2/OpenDiablo2/sound"
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
)
|
)
|
||||||
|
|
||||||
type EngineRegion struct {
|
type EngineRegion struct {
|
||||||
Rect Common.Rectangle
|
Rect common.Rectangle
|
||||||
Region *Region
|
Region *Region
|
||||||
}
|
}
|
||||||
|
|
||||||
type Engine struct {
|
type Engine struct {
|
||||||
soundManager *Sound.Manager
|
soundManager *sound.Manager
|
||||||
gameState *Common.GameState
|
gameState *common.GameState
|
||||||
fileProvider Common.FileProvider
|
fileProvider common.FileProvider
|
||||||
regions []EngineRegion
|
regions []EngineRegion
|
||||||
OffsetX float64
|
OffsetX float64
|
||||||
OffsetY float64
|
OffsetY float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateMapEngine(gameState *Common.GameState, soundManager *Sound.Manager, fileProvider Common.FileProvider) *Engine {
|
func CreateMapEngine(gameState *common.GameState, soundManager *sound.Manager, fileProvider common.FileProvider) *Engine {
|
||||||
result := &Engine{
|
result := &Engine{
|
||||||
gameState: gameState,
|
gameState: gameState,
|
||||||
soundManager: soundManager,
|
soundManager: soundManager,
|
||||||
@ -38,7 +38,7 @@ func (v *Engine) GenerateMap(regionType RegionIdType, levelPreset int) {
|
|||||||
randomSource := rand.NewSource(v.gameState.Seed)
|
randomSource := rand.NewSource(v.gameState.Seed)
|
||||||
region := LoadRegion(randomSource, regionType, levelPreset, v.fileProvider)
|
region := LoadRegion(randomSource, regionType, levelPreset, v.fileProvider)
|
||||||
v.regions = append(v.regions, EngineRegion{
|
v.regions = append(v.regions, EngineRegion{
|
||||||
Rect: Common.Rectangle{0, 0, int(region.TileWidth), int(region.TileHeight)},
|
Rect: common.Rectangle{0, 0, int(region.TileWidth), int(region.TileHeight)},
|
||||||
Region: region,
|
Region: region,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -48,19 +48,19 @@ func (v *Engine) GenerateAct1Overworld() {
|
|||||||
randomSource := rand.NewSource(v.gameState.Seed)
|
randomSource := rand.NewSource(v.gameState.Seed)
|
||||||
region := LoadRegion(randomSource, RegionAct1Town, 1, v.fileProvider)
|
region := LoadRegion(randomSource, RegionAct1Town, 1, v.fileProvider)
|
||||||
v.regions = append(v.regions, EngineRegion{
|
v.regions = append(v.regions, EngineRegion{
|
||||||
Rect: Common.Rectangle{0, 0, int(region.TileWidth), int(region.TileHeight)},
|
Rect: common.Rectangle{0, 0, int(region.TileWidth), int(region.TileHeight)},
|
||||||
Region: region,
|
Region: region,
|
||||||
})
|
})
|
||||||
if strings.Contains(region.RegionPath, "E1") {
|
if strings.Contains(region.RegionPath, "E1") {
|
||||||
region2 := LoadRegion(randomSource, RegionAct1Town, 2, v.fileProvider)
|
region2 := LoadRegion(randomSource, RegionAct1Town, 2, v.fileProvider)
|
||||||
v.regions = append(v.regions, EngineRegion{
|
v.regions = append(v.regions, EngineRegion{
|
||||||
Rect: Common.Rectangle{int(region.TileWidth - 1), 0, int(region2.TileWidth), int(region2.TileHeight)},
|
Rect: common.Rectangle{int(region.TileWidth - 1), 0, int(region2.TileWidth), int(region2.TileHeight)},
|
||||||
Region: region2,
|
Region: region2,
|
||||||
})
|
})
|
||||||
} else if strings.Contains(region.RegionPath, "S1") {
|
} else if strings.Contains(region.RegionPath, "S1") {
|
||||||
region2 := LoadRegion(randomSource, RegionAct1Town, 3, v.fileProvider)
|
region2 := LoadRegion(randomSource, RegionAct1Town, 3, v.fileProvider)
|
||||||
v.regions = append(v.regions, EngineRegion{
|
v.regions = append(v.regions, EngineRegion{
|
||||||
Rect: Common.Rectangle{0, int(region.TileHeight - 1), int(region2.TileWidth), int(region2.TileHeight)},
|
Rect: common.Rectangle{0, int(region.TileHeight - 1), int(region2.TileWidth), int(region2.TileHeight)},
|
||||||
Region: region2,
|
Region: region2,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ func (v *Engine) RenderRegion(region EngineRegion, target *ebiten.Image) {
|
|||||||
offX := -((y + region.Rect.Top) * 80) + (region.Rect.Left * 80)
|
offX := -((y + region.Rect.Top) * 80) + (region.Rect.Left * 80)
|
||||||
offY := ((y + region.Rect.Top) * 40) + (region.Rect.Left * 40)
|
offY := ((y + region.Rect.Top) * 40) + (region.Rect.Left * 40)
|
||||||
for x := 0; x < int(region.Region.TileWidth); x++ {
|
for x := 0; x < int(region.Region.TileWidth); x++ {
|
||||||
sx, sy := Common.IsoToScreen(x+region.Rect.Left, y+region.Rect.Top, int(v.OffsetX), int(v.OffsetY))
|
sx, sy := common.IsoToScreen(x+region.Rect.Left, y+region.Rect.Top, int(v.OffsetX), int(v.OffsetY))
|
||||||
if sx > -160 && sy > -160 && sx <= 880 && sy <= 1000 {
|
if sx > -160 && sy > -160 && sx <= 880 && sy <= 1000 {
|
||||||
v.RenderTile(region.Region, offX, offY, x, y, target)
|
v.RenderTile(region.Region, offX, offY, x, y, target)
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package Map
|
package _map
|
||||||
|
|
||||||
type Orientation int32
|
type Orientation int32
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package Map
|
package _map
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image/color"
|
"image/color"
|
||||||
@ -8,11 +8,11 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
"github.com/OpenDiablo2/OpenDiablo2/palettedefs"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TileCacheRecord struct {
|
type TileCacheRecord struct {
|
||||||
@ -23,17 +23,17 @@ type TileCacheRecord struct {
|
|||||||
|
|
||||||
type Region struct {
|
type Region struct {
|
||||||
RegionPath string
|
RegionPath string
|
||||||
LevelType Common.LevelTypeRecord
|
LevelType common.LevelTypeRecord
|
||||||
levelPreset *Common.LevelPresetRecord
|
levelPreset *common.LevelPresetRecord
|
||||||
TileWidth int32
|
TileWidth int32
|
||||||
TileHeight int32
|
TileHeight int32
|
||||||
Tiles []Tile
|
Tiles []Tile
|
||||||
DS1 *DS1
|
DS1 *DS1
|
||||||
Palette Common.PaletteRec
|
Palette common.PaletteRec
|
||||||
FloorCache map[uint32]*TileCacheRecord
|
FloorCache map[uint32]*TileCacheRecord
|
||||||
ShadowCache map[uint32]*TileCacheRecord
|
ShadowCache map[uint32]*TileCacheRecord
|
||||||
WallCache map[uint32]*TileCacheRecord
|
WallCache map[uint32]*TileCacheRecord
|
||||||
AnimationEntities []*Common.AnimatedEntity
|
AnimationEntities []*common.AnimatedEntity
|
||||||
}
|
}
|
||||||
|
|
||||||
type RegionLayerType int
|
type RegionLayerType int
|
||||||
@ -84,16 +84,16 @@ const (
|
|||||||
RegionAct5Lava RegionIdType = 35
|
RegionAct5Lava RegionIdType = 35
|
||||||
)
|
)
|
||||||
|
|
||||||
func LoadRegion(seed rand.Source, levelType RegionIdType, levelPreset int, fileProvider Common.FileProvider) *Region {
|
func LoadRegion(seed rand.Source, levelType RegionIdType, levelPreset int, fileProvider common.FileProvider) *Region {
|
||||||
result := &Region{
|
result := &Region{
|
||||||
LevelType: Common.LevelTypes[levelType],
|
LevelType: common.LevelTypes[levelType],
|
||||||
levelPreset: Common.LevelPresets[levelPreset],
|
levelPreset: common.LevelPresets[levelPreset],
|
||||||
Tiles: make([]Tile, 0),
|
Tiles: make([]Tile, 0),
|
||||||
FloorCache: make(map[uint32]*TileCacheRecord),
|
FloorCache: make(map[uint32]*TileCacheRecord),
|
||||||
ShadowCache: make(map[uint32]*TileCacheRecord),
|
ShadowCache: make(map[uint32]*TileCacheRecord),
|
||||||
WallCache: make(map[uint32]*TileCacheRecord),
|
WallCache: make(map[uint32]*TileCacheRecord),
|
||||||
}
|
}
|
||||||
result.Palette = Common.Palettes[PaletteDefs.PaletteType("act"+strconv.Itoa(int(result.LevelType.Act)))]
|
result.Palette = common.Palettes[palettedefs.PaletteType("act"+strconv.Itoa(int(result.LevelType.Act)))]
|
||||||
//\bm := result.levelPreset.Dt1Mask
|
//\bm := result.levelPreset.Dt1Mask
|
||||||
for _, levelTypeDt1 := range result.LevelType.Files {
|
for _, levelTypeDt1 := range result.LevelType.Files {
|
||||||
/*
|
/*
|
||||||
@ -125,17 +125,17 @@ func LoadRegion(seed rand.Source, levelType RegionIdType, levelPreset int, fileP
|
|||||||
result.TileHeight = result.DS1.Height
|
result.TileHeight = result.DS1.Height
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(len(result.DS1.Objects))
|
wg.Add(len(result.DS1.Objects))
|
||||||
result.AnimationEntities = make([]*Common.AnimatedEntity, 0)
|
result.AnimationEntities = make([]*common.AnimatedEntity, 0)
|
||||||
for _, object := range result.DS1.Objects {
|
for _, object := range result.DS1.Objects {
|
||||||
go func(object Object) {
|
go func(object Object) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
switch object.Lookup.Type {
|
switch object.Lookup.Type {
|
||||||
case Common.ObjectTypeCharacter:
|
case common.ObjectTypeCharacter:
|
||||||
case Common.ObjectTypeItem:
|
case common.ObjectTypeItem:
|
||||||
if object.Lookup.Base == "" || object.Lookup.Token == "" || object.Lookup.TR == "" {
|
if object.Lookup.Base == "" || object.Lookup.Token == "" || object.Lookup.TR == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
animEntity := Common.CreateAnimatedEntity(object.Lookup.Base, object.Lookup.Token, object.Lookup.TR, PaletteDefs.Units)
|
animEntity := common.CreateAnimatedEntity(object.Lookup.Base, object.Lookup.Token, object.Lookup.TR, palettedefs.Units)
|
||||||
animEntity.SetMode(object.Lookup.Mode, object.Lookup.Class, 0, fileProvider)
|
animEntity.SetMode(object.Lookup.Mode, object.Lookup.Class, 0, fileProvider)
|
||||||
animEntity.LocationX = math.Floor(float64(object.X) / 5)
|
animEntity.LocationX = math.Floor(float64(object.X) / 5)
|
||||||
animEntity.LocationY = math.Floor(float64(object.Y) / 5)
|
animEntity.LocationY = math.Floor(float64(object.Y) / 5)
|
||||||
@ -213,7 +213,7 @@ func (v *Region) renderShadow(tile FloorShadowRecord, offsetX, offsetY int, targ
|
|||||||
}
|
}
|
||||||
opts := &ebiten.DrawImageOptions{}
|
opts := &ebiten.DrawImageOptions{}
|
||||||
opts.GeoM.Translate(float64(offsetX+tileCache.XOffset), float64(offsetY+tileCache.YOffset))
|
opts.GeoM.Translate(float64(offsetX+tileCache.XOffset), float64(offsetY+tileCache.YOffset))
|
||||||
opts.ColorM = Common.ColorToColorM(color.RGBA{255, 255, 255, 160})
|
opts.ColorM = common.ColorToColorM(color.RGBA{255, 255, 255, 160})
|
||||||
target.DrawImage(tileCache.Image, opts)
|
target.DrawImage(tileCache.Image, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,10 +296,10 @@ func (v *Region) generateFloorCache(tile FloorShadowRecord) *TileCacheRecord {
|
|||||||
}
|
}
|
||||||
tileYMinimum := int32(0)
|
tileYMinimum := int32(0)
|
||||||
for _, block := range tileData.Blocks {
|
for _, block := range tileData.Blocks {
|
||||||
tileYMinimum = Common.MinInt32(tileYMinimum, int32(block.Y))
|
tileYMinimum = common.MinInt32(tileYMinimum, int32(block.Y))
|
||||||
}
|
}
|
||||||
tileYOffset := Common.AbsInt32(tileYMinimum)
|
tileYOffset := common.AbsInt32(tileYMinimum)
|
||||||
tileHeight := Common.AbsInt32(tileData.Height)
|
tileHeight := common.AbsInt32(tileData.Height)
|
||||||
image, _ := ebiten.NewImage(int(tileData.Width), int(tileHeight), ebiten.FilterNearest)
|
image, _ := ebiten.NewImage(int(tileData.Width), int(tileHeight), ebiten.FilterNearest)
|
||||||
pixels := make([]byte, 4*tileData.Width*tileHeight)
|
pixels := make([]byte, 4*tileData.Width*tileHeight)
|
||||||
v.decodeTileGfxData(tileData.Blocks, pixels, tileYOffset, tileData.Width)
|
v.decodeTileGfxData(tileData.Blocks, pixels, tileYOffset, tileData.Width)
|
||||||
@ -315,8 +315,8 @@ func (v *Region) generateShadowCache(tile FloorShadowRecord) *TileCacheRecord {
|
|||||||
tileMinY := int32(0)
|
tileMinY := int32(0)
|
||||||
tileMaxY := int32(0)
|
tileMaxY := int32(0)
|
||||||
for _, block := range tileData.Blocks {
|
for _, block := range tileData.Blocks {
|
||||||
tileMinY = Common.MinInt32(tileMinY, int32(block.Y))
|
tileMinY = common.MinInt32(tileMinY, int32(block.Y))
|
||||||
tileMaxY = Common.MaxInt32(tileMaxY, int32(block.Y+32))
|
tileMaxY = common.MaxInt32(tileMaxY, int32(block.Y+32))
|
||||||
}
|
}
|
||||||
tileYOffset := -tileMinY
|
tileYOffset := -tileMinY
|
||||||
tileHeight := int(tileMaxY - tileMinY)
|
tileHeight := int(tileMaxY - tileMinY)
|
||||||
@ -344,10 +344,10 @@ func (v *Region) generateWallCache(tile WallRecord) *TileCacheRecord {
|
|||||||
target = newTileData
|
target = newTileData
|
||||||
}
|
}
|
||||||
for _, block := range target.Blocks {
|
for _, block := range target.Blocks {
|
||||||
tileMinY = Common.MinInt32(tileMinY, int32(block.Y))
|
tileMinY = common.MinInt32(tileMinY, int32(block.Y))
|
||||||
tileMaxY = Common.MaxInt32(tileMaxY, int32(block.Y+32))
|
tileMaxY = common.MaxInt32(tileMaxY, int32(block.Y+32))
|
||||||
}
|
}
|
||||||
realHeight := Common.MaxInt32(Common.AbsInt32(tileData.Height), tileMaxY-tileMinY)
|
realHeight := common.MaxInt32(common.AbsInt32(tileData.Height), tileMaxY-tileMinY)
|
||||||
tileYOffset := -tileMinY
|
tileYOffset := -tileMinY
|
||||||
//tileHeight := int(tileMaxY - tileMinY)
|
//tileHeight := int(tileMaxY - tileMinY)
|
||||||
image, _ := ebiten.NewImage(160, int(realHeight), ebiten.FilterNearest)
|
image, _ := ebiten.NewImage(160, int(realHeight), ebiten.FilterNearest)
|
@ -1,4 +1,4 @@
|
|||||||
package MPQ
|
package mpq
|
||||||
|
|
||||||
// CryptoBuffer contains the crypto bytes for filename hashing
|
// CryptoBuffer contains the crypto bytes for filename hashing
|
||||||
var CryptoBuffer [0x500]uint32
|
var CryptoBuffer [0x500]uint32
|
@ -1,4 +1,4 @@
|
|||||||
package MPQ
|
package mpq
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
@ -8,7 +8,7 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
"github.com/OpenDiablo2/OpenDiablo2/resourcepaths"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MPQ represents an MPQ archive
|
// MPQ represents an MPQ archive
|
||||||
@ -225,7 +225,7 @@ func (v MPQ) getFileHashEntry(fileName string) (HashTableEntry, error) {
|
|||||||
|
|
||||||
// GetFileBlockData gets a block table entry
|
// GetFileBlockData gets a block table entry
|
||||||
func (v MPQ) GetFileBlockData(fileName string) (BlockTableEntry, error) {
|
func (v MPQ) GetFileBlockData(fileName string) (BlockTableEntry, error) {
|
||||||
fileName = strings.ReplaceAll(fileName, "{LANG}", ResourcePaths.LanguageCode)
|
fileName = strings.ReplaceAll(fileName, "{LANG}", resourcepaths.LanguageCode)
|
||||||
fileEntry, err := v.getFileHashEntry(fileName)
|
fileEntry, err := v.getFileHashEntry(fileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return BlockTableEntry{}, err
|
return BlockTableEntry{}, err
|
||||||
@ -248,7 +248,7 @@ func (v MPQ) FileExists(fileName string) bool {
|
|||||||
|
|
||||||
// ReadFile reads a file from the MPQ and returns a memory stream
|
// ReadFile reads a file from the MPQ and returns a memory stream
|
||||||
func (v MPQ) ReadFile(fileName string) ([]byte, error) {
|
func (v MPQ) ReadFile(fileName string) ([]byte, error) {
|
||||||
fileName = strings.ReplaceAll(fileName, "{LANG}", ResourcePaths.LanguageCode)
|
fileName = strings.ReplaceAll(fileName, "{LANG}", resourcepaths.LanguageCode)
|
||||||
fileBlockData, err := v.GetFileBlockData(fileName)
|
fileBlockData, err := v.GetFileBlockData(fileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []byte{}, err
|
return []byte{}, err
|
||||||
@ -263,7 +263,7 @@ func (v MPQ) ReadFile(fileName string) ([]byte, error) {
|
|||||||
|
|
||||||
// ReadTextFile reads a file and returns it as a string
|
// ReadTextFile reads a file and returns it as a string
|
||||||
func (v MPQ) ReadTextFile(fileName string) (string, error) {
|
func (v MPQ) ReadTextFile(fileName string) (string, error) {
|
||||||
fileName = strings.ReplaceAll(fileName, "{LANG}", ResourcePaths.LanguageCode)
|
fileName = strings.ReplaceAll(fileName, "{LANG}", resourcepaths.LanguageCode)
|
||||||
data, err := v.ReadFile(fileName)
|
data, err := v.ReadFile(fileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
@ -1,4 +1,4 @@
|
|||||||
package MPQ
|
package mpq
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@ -9,8 +9,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/JoshVarga/blast"
|
"github.com/JoshVarga/blast"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Compression"
|
"github.com/OpenDiablo2/OpenDiablo2/compression"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Stream represents a stream of data in an MPQ archive
|
// Stream represents a stream of data in an MPQ archive
|
||||||
@ -90,7 +90,7 @@ func (v *Stream) readInternalSingleUnit(buffer []byte, offset, count uint32) uin
|
|||||||
v.loadSingleUnit()
|
v.loadSingleUnit()
|
||||||
}
|
}
|
||||||
|
|
||||||
bytesToCopy := Common.Min(uint32(len(v.CurrentData))-v.CurrentPosition, count)
|
bytesToCopy := common.Min(uint32(len(v.CurrentData))-v.CurrentPosition, count)
|
||||||
copy(buffer[offset:offset+bytesToCopy], v.CurrentData[v.CurrentPosition:v.CurrentPosition+bytesToCopy])
|
copy(buffer[offset:offset+bytesToCopy], v.CurrentData[v.CurrentPosition:v.CurrentPosition+bytesToCopy])
|
||||||
v.CurrentPosition += bytesToCopy
|
v.CurrentPosition += bytesToCopy
|
||||||
return bytesToCopy
|
return bytesToCopy
|
||||||
@ -99,7 +99,7 @@ func (v *Stream) readInternalSingleUnit(buffer []byte, offset, count uint32) uin
|
|||||||
func (v *Stream) readInternal(buffer []byte, offset, count uint32) uint32 {
|
func (v *Stream) readInternal(buffer []byte, offset, count uint32) uint32 {
|
||||||
v.bufferData()
|
v.bufferData()
|
||||||
localPosition := v.CurrentPosition % v.BlockSize
|
localPosition := v.CurrentPosition % v.BlockSize
|
||||||
bytesToCopy := Common.MinInt32(int32(len(v.CurrentData))-int32(localPosition), int32(count))
|
bytesToCopy := common.MinInt32(int32(len(v.CurrentData))-int32(localPosition), int32(count))
|
||||||
if bytesToCopy <= 0 {
|
if bytesToCopy <= 0 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@ -113,7 +113,7 @@ func (v *Stream) bufferData() {
|
|||||||
if requiredBlock == v.CurrentBlockIndex {
|
if requiredBlock == v.CurrentBlockIndex {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
expectedLength := Common.Min(v.BlockTableEntry.UncompressedFileSize-(requiredBlock*v.BlockSize), v.BlockSize)
|
expectedLength := common.Min(v.BlockTableEntry.UncompressedFileSize-(requiredBlock*v.BlockSize), v.BlockSize)
|
||||||
v.CurrentData = v.loadBlock(requiredBlock, expectedLength)
|
v.CurrentData = v.loadBlock(requiredBlock, expectedLength)
|
||||||
v.CurrentBlockIndex = requiredBlock
|
v.CurrentBlockIndex = requiredBlock
|
||||||
}
|
}
|
||||||
@ -178,7 +178,7 @@ func decompressMulti(data []byte, expectedLength uint32) []byte {
|
|||||||
case 0x10: // BZip2
|
case 0x10: // BZip2
|
||||||
panic("bzip2 decompression not supported")
|
panic("bzip2 decompression not supported")
|
||||||
case 0x80: // IMA ADPCM Stereo
|
case 0x80: // IMA ADPCM Stereo
|
||||||
return Compression.WavDecompress(data[1:], 2)
|
return compression.WavDecompress(data[1:], 2)
|
||||||
//return MpqWavCompression.Decompress(sinput, 2);
|
//return MpqWavCompression.Decompress(sinput, 2);
|
||||||
//panic("ima adpcm sterio decompression not supported")
|
//panic("ima adpcm sterio decompression not supported")
|
||||||
case 0x40: // IMA ADPCM Mono
|
case 0x40: // IMA ADPCM Mono
|
||||||
@ -194,8 +194,8 @@ func decompressMulti(data []byte, expectedLength uint32) []byte {
|
|||||||
// TODO: sparse then bzip2
|
// TODO: sparse then bzip2
|
||||||
panic("sparse decompression + bzip2 decompression not supported")
|
panic("sparse decompression + bzip2 decompression not supported")
|
||||||
case 0x41:
|
case 0x41:
|
||||||
sinput := Compression.HuffmanDecompress(data[1:])
|
sinput := compression.HuffmanDecompress(data[1:])
|
||||||
sinput = Compression.WavDecompress(sinput, 1)
|
sinput = compression.WavDecompress(sinput, 1)
|
||||||
tmp := make([]byte, len(sinput))
|
tmp := make([]byte, len(sinput))
|
||||||
copy(tmp, sinput)
|
copy(tmp, sinput)
|
||||||
return tmp
|
return tmp
|
||||||
@ -204,8 +204,8 @@ func decompressMulti(data []byte, expectedLength uint32) []byte {
|
|||||||
//return MpqWavCompression.Decompress(new MemoryStream(result), 1);
|
//return MpqWavCompression.Decompress(new MemoryStream(result), 1);
|
||||||
panic("pk + mpqwav decompression not supported")
|
panic("pk + mpqwav decompression not supported")
|
||||||
case 0x81:
|
case 0x81:
|
||||||
sinput := Compression.HuffmanDecompress(data[1:])
|
sinput := compression.HuffmanDecompress(data[1:])
|
||||||
sinput = Compression.WavDecompress(sinput, 2)
|
sinput = compression.WavDecompress(sinput, 2)
|
||||||
tmp := make([]byte, len(sinput))
|
tmp := make([]byte, len(sinput))
|
||||||
copy(tmp, sinput)
|
copy(tmp, sinput)
|
||||||
return tmp
|
return tmp
|
@ -1,4 +1,4 @@
|
|||||||
package PaletteDefs
|
package palettedefs
|
||||||
|
|
||||||
// PaletteType represents a named palette
|
// PaletteType represents a named palette
|
||||||
type PaletteType string
|
type PaletteType string
|
@ -1,4 +1,4 @@
|
|||||||
package ResourcePaths
|
package resourcepaths
|
||||||
|
|
||||||
var LanguageCode string
|
var LanguageCode string
|
||||||
|
|
@ -1,18 +1,18 @@
|
|||||||
package Scenes
|
package scenes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Video"
|
"github.com/OpenDiablo2/OpenDiablo2/video"
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BlizzardIntro struct {
|
type BlizzardIntro struct {
|
||||||
fileProvider Common.FileProvider
|
fileProvider common.FileProvider
|
||||||
sceneProvider SceneProvider
|
sceneProvider SceneProvider
|
||||||
videoDecoder *Video.BinkDecoder
|
videoDecoder *video.BinkDecoder
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateBlizzardIntro(fileProvider Common.FileProvider, sceneProvider SceneProvider) *BlizzardIntro {
|
func CreateBlizzardIntro(fileProvider common.FileProvider, sceneProvider SceneProvider) *BlizzardIntro {
|
||||||
result := &BlizzardIntro{
|
result := &BlizzardIntro{
|
||||||
fileProvider: fileProvider,
|
fileProvider: fileProvider,
|
||||||
sceneProvider: sceneProvider,
|
sceneProvider: sceneProvider,
|
||||||
@ -25,7 +25,7 @@ func (v *BlizzardIntro) Load() []func() {
|
|||||||
return []func(){
|
return []func(){
|
||||||
func() {
|
func() {
|
||||||
videoBytes := v.fileProvider.LoadFile("/data/local/video/BlizNorth640x480.bik")
|
videoBytes := v.fileProvider.LoadFile("/data/local/video/BlizNorth640x480.bik")
|
||||||
v.videoDecoder = Video.CreateBinkDecoder(videoBytes)
|
v.videoDecoder = video.CreateBinkDecoder(videoBytes)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,32 +1,32 @@
|
|||||||
package Scenes
|
package scenes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
"github.com/OpenDiablo2/OpenDiablo2/palettedefs"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
"github.com/OpenDiablo2/OpenDiablo2/resourcepaths"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Sound"
|
"github.com/OpenDiablo2/OpenDiablo2/sound"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/UI"
|
"github.com/OpenDiablo2/OpenDiablo2/ui"
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CharacterSelect struct {
|
type CharacterSelect struct {
|
||||||
uiManager *UI.Manager
|
uiManager *ui.Manager
|
||||||
soundManager *Sound.Manager
|
soundManager *sound.Manager
|
||||||
fileProvider Common.FileProvider
|
fileProvider common.FileProvider
|
||||||
sceneProvider SceneProvider
|
sceneProvider SceneProvider
|
||||||
background *Common.Sprite
|
background *common.Sprite
|
||||||
newCharButton *UI.Button
|
newCharButton *ui.Button
|
||||||
convertCharButton *UI.Button
|
convertCharButton *ui.Button
|
||||||
deleteCharButton *UI.Button
|
deleteCharButton *ui.Button
|
||||||
exitButton *UI.Button
|
exitButton *ui.Button
|
||||||
okButton *UI.Button
|
okButton *ui.Button
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateCharacterSelect(
|
func CreateCharacterSelect(
|
||||||
fileProvider Common.FileProvider,
|
fileProvider common.FileProvider,
|
||||||
sceneProvider SceneProvider,
|
sceneProvider SceneProvider,
|
||||||
uiManager *UI.Manager,
|
uiManager *ui.Manager,
|
||||||
soundManager *Sound.Manager,
|
soundManager *sound.Manager,
|
||||||
) *CharacterSelect {
|
) *CharacterSelect {
|
||||||
result := &CharacterSelect{
|
result := &CharacterSelect{
|
||||||
uiManager: uiManager,
|
uiManager: uiManager,
|
||||||
@ -38,38 +38,38 @@ func CreateCharacterSelect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (v *CharacterSelect) Load() []func() {
|
func (v *CharacterSelect) Load() []func() {
|
||||||
v.soundManager.PlayBGM(ResourcePaths.BGMTitle)
|
v.soundManager.PlayBGM(resourcepaths.BGMTitle)
|
||||||
return []func(){
|
return []func(){
|
||||||
func() {
|
func() {
|
||||||
v.background = v.fileProvider.LoadSprite(ResourcePaths.CharacterSelectionBackground, PaletteDefs.Sky)
|
v.background = v.fileProvider.LoadSprite(resourcepaths.CharacterSelectionBackground, palettedefs.Sky)
|
||||||
v.background.MoveTo(0, 0)
|
v.background.MoveTo(0, 0)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.newCharButton = UI.CreateButton(UI.ButtonTypeTall, v.fileProvider, Common.CombineStrings(Common.SplitIntoLinesWithMaxWidth(Common.TranslateString("#831"), 15)))
|
v.newCharButton = ui.CreateButton(ui.ButtonTypeTall, v.fileProvider, common.CombineStrings(common.SplitIntoLinesWithMaxWidth(common.TranslateString("#831"), 15)))
|
||||||
v.newCharButton.MoveTo(33, 468)
|
v.newCharButton.MoveTo(33, 468)
|
||||||
v.newCharButton.OnActivated(func() { v.onNewCharButtonClicked() })
|
v.newCharButton.OnActivated(func() { v.onNewCharButtonClicked() })
|
||||||
v.uiManager.AddWidget(v.newCharButton)
|
v.uiManager.AddWidget(v.newCharButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.convertCharButton = UI.CreateButton(UI.ButtonTypeTall, v.fileProvider, Common.CombineStrings(Common.SplitIntoLinesWithMaxWidth(Common.TranslateString("#825"), 15)))
|
v.convertCharButton = ui.CreateButton(ui.ButtonTypeTall, v.fileProvider, common.CombineStrings(common.SplitIntoLinesWithMaxWidth(common.TranslateString("#825"), 15)))
|
||||||
v.convertCharButton.MoveTo(233, 468)
|
v.convertCharButton.MoveTo(233, 468)
|
||||||
v.convertCharButton.SetEnabled(false)
|
v.convertCharButton.SetEnabled(false)
|
||||||
v.uiManager.AddWidget(v.convertCharButton)
|
v.uiManager.AddWidget(v.convertCharButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.deleteCharButton = UI.CreateButton(UI.ButtonTypeTall, v.fileProvider, Common.CombineStrings(Common.SplitIntoLinesWithMaxWidth(Common.TranslateString("#832"), 15)))
|
v.deleteCharButton = ui.CreateButton(ui.ButtonTypeTall, v.fileProvider, common.CombineStrings(common.SplitIntoLinesWithMaxWidth(common.TranslateString("#832"), 15)))
|
||||||
v.deleteCharButton.MoveTo(433, 468)
|
v.deleteCharButton.MoveTo(433, 468)
|
||||||
v.deleteCharButton.SetEnabled(false)
|
v.deleteCharButton.SetEnabled(false)
|
||||||
v.uiManager.AddWidget(v.deleteCharButton)
|
v.uiManager.AddWidget(v.deleteCharButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.exitButton = UI.CreateButton(UI.ButtonTypeMedium, v.fileProvider, Common.TranslateString("#970"))
|
v.exitButton = ui.CreateButton(ui.ButtonTypeMedium, v.fileProvider, common.TranslateString("#970"))
|
||||||
v.exitButton.MoveTo(33, 537)
|
v.exitButton.MoveTo(33, 537)
|
||||||
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
||||||
v.uiManager.AddWidget(v.exitButton)
|
v.uiManager.AddWidget(v.exitButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.okButton = UI.CreateButton(UI.ButtonTypeMedium, v.fileProvider, Common.TranslateString("#971"))
|
v.okButton = ui.CreateButton(ui.ButtonTypeMedium, v.fileProvider, common.TranslateString("#971"))
|
||||||
v.okButton.MoveTo(625, 537)
|
v.okButton.MoveTo(625, 537)
|
||||||
v.okButton.SetEnabled(false)
|
v.okButton.SetEnabled(false)
|
||||||
v.uiManager.AddWidget(v.okButton)
|
v.uiManager.AddWidget(v.okButton)
|
@ -1,31 +1,31 @@
|
|||||||
package Scenes
|
package scenes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image/color"
|
"image/color"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
"github.com/OpenDiablo2/OpenDiablo2/palettedefs"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
"github.com/OpenDiablo2/OpenDiablo2/resourcepaths"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Sound"
|
"github.com/OpenDiablo2/OpenDiablo2/sound"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/UI"
|
"github.com/OpenDiablo2/OpenDiablo2/ui"
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
)
|
)
|
||||||
|
|
||||||
type labelItem struct {
|
type labelItem struct {
|
||||||
Label *UI.Label
|
Label *ui.Label
|
||||||
IsHeading bool
|
IsHeading bool
|
||||||
Available bool
|
Available bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Credits represents the credits scene
|
// Credits represents the credits scene
|
||||||
type Credits struct {
|
type Credits struct {
|
||||||
uiManager *UI.Manager
|
uiManager *ui.Manager
|
||||||
soundManager *Sound.Manager
|
soundManager *sound.Manager
|
||||||
fileProvider Common.FileProvider
|
fileProvider common.FileProvider
|
||||||
sceneProvider SceneProvider
|
sceneProvider SceneProvider
|
||||||
creditsBackground *Common.Sprite
|
creditsBackground *common.Sprite
|
||||||
exitButton *UI.Button
|
exitButton *ui.Button
|
||||||
creditsText []string
|
creditsText []string
|
||||||
labels []*labelItem
|
labels []*labelItem
|
||||||
cycleTime float64
|
cycleTime float64
|
||||||
@ -34,7 +34,7 @@ type Credits struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateCredits creates an instance of the credits scene
|
// CreateCredits creates an instance of the credits scene
|
||||||
func CreateCredits(fileProvider Common.FileProvider, sceneProvider SceneProvider, uiManager *UI.Manager, soundManager *Sound.Manager) *Credits {
|
func CreateCredits(fileProvider common.FileProvider, sceneProvider SceneProvider, uiManager *ui.Manager, soundManager *sound.Manager) *Credits {
|
||||||
result := &Credits{
|
result := &Credits{
|
||||||
fileProvider: fileProvider,
|
fileProvider: fileProvider,
|
||||||
uiManager: uiManager,
|
uiManager: uiManager,
|
||||||
@ -52,17 +52,17 @@ func CreateCredits(fileProvider Common.FileProvider, sceneProvider SceneProvider
|
|||||||
func (v *Credits) Load() []func() {
|
func (v *Credits) Load() []func() {
|
||||||
return []func(){
|
return []func(){
|
||||||
func() {
|
func() {
|
||||||
v.creditsBackground = v.fileProvider.LoadSprite(ResourcePaths.CreditsBackground, PaletteDefs.Sky)
|
v.creditsBackground = v.fileProvider.LoadSprite(resourcepaths.CreditsBackground, palettedefs.Sky)
|
||||||
v.creditsBackground.MoveTo(0, 0)
|
v.creditsBackground.MoveTo(0, 0)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.exitButton = UI.CreateButton(UI.ButtonTypeMedium, v.fileProvider, Common.TranslateString("#970"))
|
v.exitButton = ui.CreateButton(ui.ButtonTypeMedium, v.fileProvider, common.TranslateString("#970"))
|
||||||
v.exitButton.MoveTo(30, 550)
|
v.exitButton.MoveTo(30, 550)
|
||||||
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
||||||
v.uiManager.AddWidget(v.exitButton)
|
v.uiManager.AddWidget(v.exitButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
fileData, _ := Common.Utf16BytesToString(v.fileProvider.LoadFile(ResourcePaths.CreditsText)[2:])
|
fileData, _ := common.Utf16BytesToString(v.fileProvider.LoadFile(resourcepaths.CreditsText)[2:])
|
||||||
v.creditsText = strings.Split(fileData, "\r\n")
|
v.creditsText = strings.Split(fileData, "\r\n")
|
||||||
for i := range v.creditsText {
|
for i := range v.creditsText {
|
||||||
v.creditsText[i] = strings.Trim(v.creditsText[i], " ")
|
v.creditsText[i] = strings.Trim(v.creditsText[i], " ")
|
||||||
@ -174,7 +174,7 @@ func (v *Credits) addNextItem() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Credits) getNewFontLabel(isHeading bool) *UI.Label {
|
func (v *Credits) getNewFontLabel(isHeading bool) *ui.Label {
|
||||||
for _, label := range v.labels {
|
for _, label := range v.labels {
|
||||||
if label.Available {
|
if label.Available {
|
||||||
label.Available = false
|
label.Available = false
|
||||||
@ -190,7 +190,7 @@ func (v *Credits) getNewFontLabel(isHeading bool) *UI.Label {
|
|||||||
newLabelItem := &labelItem{
|
newLabelItem := &labelItem{
|
||||||
Available: false,
|
Available: false,
|
||||||
IsHeading: isHeading,
|
IsHeading: isHeading,
|
||||||
Label: UI.CreateLabel(v.fileProvider, ResourcePaths.FontFormal10, PaletteDefs.Sky),
|
Label: ui.CreateLabel(v.fileProvider, resourcepaths.FontFormal10, palettedefs.Sky),
|
||||||
}
|
}
|
||||||
|
|
||||||
if isHeading {
|
if isHeading {
|
@ -1,4 +1,4 @@
|
|||||||
package Scenes
|
package scenes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -8,45 +8,45 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
"github.com/OpenDiablo2/OpenDiablo2/palettedefs"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Sound"
|
"github.com/OpenDiablo2/OpenDiablo2/sound"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/UI"
|
"github.com/OpenDiablo2/OpenDiablo2/ui"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
"github.com/OpenDiablo2/OpenDiablo2/resourcepaths"
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MainMenu represents the main menu
|
// MainMenu represents the main menu
|
||||||
type MainMenu struct {
|
type MainMenu struct {
|
||||||
uiManager *UI.Manager
|
uiManager *ui.Manager
|
||||||
soundManager *Sound.Manager
|
soundManager *sound.Manager
|
||||||
fileProvider Common.FileProvider
|
fileProvider common.FileProvider
|
||||||
sceneProvider SceneProvider
|
sceneProvider SceneProvider
|
||||||
trademarkBackground *Common.Sprite
|
trademarkBackground *common.Sprite
|
||||||
background *Common.Sprite
|
background *common.Sprite
|
||||||
diabloLogoLeft *Common.Sprite
|
diabloLogoLeft *common.Sprite
|
||||||
diabloLogoRight *Common.Sprite
|
diabloLogoRight *common.Sprite
|
||||||
diabloLogoLeftBack *Common.Sprite
|
diabloLogoLeftBack *common.Sprite
|
||||||
diabloLogoRightBack *Common.Sprite
|
diabloLogoRightBack *common.Sprite
|
||||||
singlePlayerButton *UI.Button
|
singlePlayerButton *ui.Button
|
||||||
githubButton *UI.Button
|
githubButton *ui.Button
|
||||||
exitDiabloButton *UI.Button
|
exitDiabloButton *ui.Button
|
||||||
creditsButton *UI.Button
|
creditsButton *ui.Button
|
||||||
cinematicsButton *UI.Button
|
cinematicsButton *ui.Button
|
||||||
mapTestButton *UI.Button
|
mapTestButton *ui.Button
|
||||||
copyrightLabel *UI.Label
|
copyrightLabel *ui.Label
|
||||||
copyrightLabel2 *UI.Label
|
copyrightLabel2 *ui.Label
|
||||||
openDiabloLabel *UI.Label
|
openDiabloLabel *ui.Label
|
||||||
versionLabel *UI.Label
|
versionLabel *ui.Label
|
||||||
commitLabel *UI.Label
|
commitLabel *ui.Label
|
||||||
|
|
||||||
ShowTrademarkScreen bool
|
ShowTrademarkScreen bool
|
||||||
leftButtonHeld bool
|
leftButtonHeld bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateMainMenu creates an instance of MainMenu
|
// CreateMainMenu creates an instance of MainMenu
|
||||||
func CreateMainMenu(fileProvider Common.FileProvider, sceneProvider SceneProvider, uiManager *UI.Manager, soundManager *Sound.Manager) *MainMenu {
|
func CreateMainMenu(fileProvider common.FileProvider, sceneProvider SceneProvider, uiManager *ui.Manager, soundManager *sound.Manager) *MainMenu {
|
||||||
result := &MainMenu{
|
result := &MainMenu{
|
||||||
fileProvider: fileProvider,
|
fileProvider: fileProvider,
|
||||||
uiManager: uiManager,
|
uiManager: uiManager,
|
||||||
@ -60,107 +60,107 @@ func CreateMainMenu(fileProvider Common.FileProvider, sceneProvider SceneProvide
|
|||||||
|
|
||||||
// Load is called to load the resources for the main menu
|
// Load is called to load the resources for the main menu
|
||||||
func (v *MainMenu) Load() []func() {
|
func (v *MainMenu) Load() []func() {
|
||||||
v.soundManager.PlayBGM(ResourcePaths.BGMTitle)
|
v.soundManager.PlayBGM(resourcepaths.BGMTitle)
|
||||||
return []func(){
|
return []func(){
|
||||||
func() {
|
func() {
|
||||||
v.versionLabel = UI.CreateLabel(v.fileProvider, ResourcePaths.FontFormal12, PaletteDefs.Static)
|
v.versionLabel = ui.CreateLabel(v.fileProvider, resourcepaths.FontFormal12, palettedefs.Static)
|
||||||
v.versionLabel.Alignment = UI.LabelAlignRight
|
v.versionLabel.Alignment = ui.LabelAlignRight
|
||||||
v.versionLabel.SetText("OpenDiablo2 - " + Common.BuildInfo.Branch)
|
v.versionLabel.SetText("OpenDiablo2 - " + common.BuildInfo.Branch)
|
||||||
v.versionLabel.Color = color.RGBA{255, 255, 255, 255}
|
v.versionLabel.Color = color.RGBA{255, 255, 255, 255}
|
||||||
v.versionLabel.MoveTo(795, -10)
|
v.versionLabel.MoveTo(795, -10)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.commitLabel = UI.CreateLabel(v.fileProvider, ResourcePaths.FontFormal10, PaletteDefs.Static)
|
v.commitLabel = ui.CreateLabel(v.fileProvider, resourcepaths.FontFormal10, palettedefs.Static)
|
||||||
v.commitLabel.Alignment = UI.LabelAlignLeft
|
v.commitLabel.Alignment = ui.LabelAlignLeft
|
||||||
v.commitLabel.SetText(Common.BuildInfo.Commit)
|
v.commitLabel.SetText(common.BuildInfo.Commit)
|
||||||
v.commitLabel.Color = color.RGBA{255, 255, 255, 255}
|
v.commitLabel.Color = color.RGBA{255, 255, 255, 255}
|
||||||
v.commitLabel.MoveTo(2, 2)
|
v.commitLabel.MoveTo(2, 2)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.copyrightLabel = UI.CreateLabel(v.fileProvider, ResourcePaths.FontFormal12, PaletteDefs.Static)
|
v.copyrightLabel = ui.CreateLabel(v.fileProvider, resourcepaths.FontFormal12, palettedefs.Static)
|
||||||
v.copyrightLabel.Alignment = UI.LabelAlignCenter
|
v.copyrightLabel.Alignment = ui.LabelAlignCenter
|
||||||
v.copyrightLabel.SetText("Diablo 2 is © Copyright 2000-2016 Blizzard Entertainment")
|
v.copyrightLabel.SetText("Diablo 2 is © Copyright 2000-2016 Blizzard Entertainment")
|
||||||
v.copyrightLabel.Color = color.RGBA{188, 168, 140, 255}
|
v.copyrightLabel.Color = color.RGBA{188, 168, 140, 255}
|
||||||
v.copyrightLabel.MoveTo(400, 500)
|
v.copyrightLabel.MoveTo(400, 500)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.copyrightLabel2 = UI.CreateLabel(v.fileProvider, ResourcePaths.FontFormal12, PaletteDefs.Static)
|
v.copyrightLabel2 = ui.CreateLabel(v.fileProvider, resourcepaths.FontFormal12, palettedefs.Static)
|
||||||
v.copyrightLabel2.Alignment = UI.LabelAlignCenter
|
v.copyrightLabel2.Alignment = ui.LabelAlignCenter
|
||||||
v.copyrightLabel2.SetText(Common.TranslateString("#1614"))
|
v.copyrightLabel2.SetText(common.TranslateString("#1614"))
|
||||||
v.copyrightLabel2.Color = color.RGBA{188, 168, 140, 255}
|
v.copyrightLabel2.Color = color.RGBA{188, 168, 140, 255}
|
||||||
v.copyrightLabel2.MoveTo(400, 525)
|
v.copyrightLabel2.MoveTo(400, 525)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.openDiabloLabel = UI.CreateLabel(v.fileProvider, ResourcePaths.FontFormal10, PaletteDefs.Static)
|
v.openDiabloLabel = ui.CreateLabel(v.fileProvider, resourcepaths.FontFormal10, palettedefs.Static)
|
||||||
v.openDiabloLabel.Alignment = UI.LabelAlignCenter
|
v.openDiabloLabel.Alignment = ui.LabelAlignCenter
|
||||||
v.openDiabloLabel.SetText("OpenDiablo2 is neither developed by, nor endorsed by Blizzard or its parent company Activision")
|
v.openDiabloLabel.SetText("OpenDiablo2 is neither developed by, nor endorsed by Blizzard or its parent company Activision")
|
||||||
v.openDiabloLabel.Color = color.RGBA{255, 255, 140, 255}
|
v.openDiabloLabel.Color = color.RGBA{255, 255, 140, 255}
|
||||||
v.openDiabloLabel.MoveTo(400, 580)
|
v.openDiabloLabel.MoveTo(400, 580)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.background = v.fileProvider.LoadSprite(ResourcePaths.GameSelectScreen, PaletteDefs.Sky)
|
v.background = v.fileProvider.LoadSprite(resourcepaths.GameSelectScreen, palettedefs.Sky)
|
||||||
v.background.MoveTo(0, 0)
|
v.background.MoveTo(0, 0)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.trademarkBackground = v.fileProvider.LoadSprite(ResourcePaths.TrademarkScreen, PaletteDefs.Sky)
|
v.trademarkBackground = v.fileProvider.LoadSprite(resourcepaths.TrademarkScreen, palettedefs.Sky)
|
||||||
v.trademarkBackground.MoveTo(0, 0)
|
v.trademarkBackground.MoveTo(0, 0)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.diabloLogoLeft = v.fileProvider.LoadSprite(ResourcePaths.Diablo2LogoFireLeft, PaletteDefs.Units)
|
v.diabloLogoLeft = v.fileProvider.LoadSprite(resourcepaths.Diablo2LogoFireLeft, palettedefs.Units)
|
||||||
v.diabloLogoLeft.Blend = true
|
v.diabloLogoLeft.Blend = true
|
||||||
v.diabloLogoLeft.Animate = true
|
v.diabloLogoLeft.Animate = true
|
||||||
v.diabloLogoLeft.MoveTo(400, 120)
|
v.diabloLogoLeft.MoveTo(400, 120)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.diabloLogoRight = v.fileProvider.LoadSprite(ResourcePaths.Diablo2LogoFireRight, PaletteDefs.Units)
|
v.diabloLogoRight = v.fileProvider.LoadSprite(resourcepaths.Diablo2LogoFireRight, palettedefs.Units)
|
||||||
v.diabloLogoRight.Blend = true
|
v.diabloLogoRight.Blend = true
|
||||||
v.diabloLogoRight.Animate = true
|
v.diabloLogoRight.Animate = true
|
||||||
v.diabloLogoRight.MoveTo(400, 120)
|
v.diabloLogoRight.MoveTo(400, 120)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.diabloLogoLeftBack = v.fileProvider.LoadSprite(ResourcePaths.Diablo2LogoBlackLeft, PaletteDefs.Units)
|
v.diabloLogoLeftBack = v.fileProvider.LoadSprite(resourcepaths.Diablo2LogoBlackLeft, palettedefs.Units)
|
||||||
v.diabloLogoLeftBack.MoveTo(400, 120)
|
v.diabloLogoLeftBack.MoveTo(400, 120)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.diabloLogoRightBack = v.fileProvider.LoadSprite(ResourcePaths.Diablo2LogoBlackRight, PaletteDefs.Units)
|
v.diabloLogoRightBack = v.fileProvider.LoadSprite(resourcepaths.Diablo2LogoBlackRight, palettedefs.Units)
|
||||||
v.diabloLogoRightBack.MoveTo(400, 120)
|
v.diabloLogoRightBack.MoveTo(400, 120)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.exitDiabloButton = UI.CreateButton(UI.ButtonTypeWide, v.fileProvider, Common.TranslateString("#1625"))
|
v.exitDiabloButton = ui.CreateButton(ui.ButtonTypeWide, v.fileProvider, common.TranslateString("#1625"))
|
||||||
v.exitDiabloButton.MoveTo(264, 535)
|
v.exitDiabloButton.MoveTo(264, 535)
|
||||||
v.exitDiabloButton.SetVisible(!v.ShowTrademarkScreen)
|
v.exitDiabloButton.SetVisible(!v.ShowTrademarkScreen)
|
||||||
v.exitDiabloButton.OnActivated(func() { v.onExitButtonClicked() })
|
v.exitDiabloButton.OnActivated(func() { v.onExitButtonClicked() })
|
||||||
v.uiManager.AddWidget(v.exitDiabloButton)
|
v.uiManager.AddWidget(v.exitDiabloButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.creditsButton = UI.CreateButton(UI.ButtonTypeShort, v.fileProvider, Common.TranslateString("#1627"))
|
v.creditsButton = ui.CreateButton(ui.ButtonTypeShort, v.fileProvider, common.TranslateString("#1627"))
|
||||||
v.creditsButton.MoveTo(264, 505)
|
v.creditsButton.MoveTo(264, 505)
|
||||||
v.creditsButton.SetVisible(!v.ShowTrademarkScreen)
|
v.creditsButton.SetVisible(!v.ShowTrademarkScreen)
|
||||||
v.creditsButton.OnActivated(func() { v.onCreditsButtonClicked() })
|
v.creditsButton.OnActivated(func() { v.onCreditsButtonClicked() })
|
||||||
v.uiManager.AddWidget(v.creditsButton)
|
v.uiManager.AddWidget(v.creditsButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.cinematicsButton = UI.CreateButton(UI.ButtonTypeShort, v.fileProvider, Common.TranslateString("#1639"))
|
v.cinematicsButton = ui.CreateButton(ui.ButtonTypeShort, v.fileProvider, common.TranslateString("#1639"))
|
||||||
v.cinematicsButton.MoveTo(401, 505)
|
v.cinematicsButton.MoveTo(401, 505)
|
||||||
v.cinematicsButton.SetVisible(!v.ShowTrademarkScreen)
|
v.cinematicsButton.SetVisible(!v.ShowTrademarkScreen)
|
||||||
v.uiManager.AddWidget(v.cinematicsButton)
|
v.uiManager.AddWidget(v.cinematicsButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.singlePlayerButton = UI.CreateButton(UI.ButtonTypeWide, v.fileProvider, Common.TranslateString("#1620"))
|
v.singlePlayerButton = ui.CreateButton(ui.ButtonTypeWide, v.fileProvider, common.TranslateString("#1620"))
|
||||||
v.singlePlayerButton.MoveTo(264, 290)
|
v.singlePlayerButton.MoveTo(264, 290)
|
||||||
v.singlePlayerButton.SetVisible(!v.ShowTrademarkScreen)
|
v.singlePlayerButton.SetVisible(!v.ShowTrademarkScreen)
|
||||||
v.singlePlayerButton.OnActivated(func() { v.onSinglePlayerClicked() })
|
v.singlePlayerButton.OnActivated(func() { v.onSinglePlayerClicked() })
|
||||||
v.uiManager.AddWidget(v.singlePlayerButton)
|
v.uiManager.AddWidget(v.singlePlayerButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.githubButton = UI.CreateButton(UI.ButtonTypeWide, v.fileProvider, "PROJECT WEBSITE")
|
v.githubButton = ui.CreateButton(ui.ButtonTypeWide, v.fileProvider, "PROJECT WEBSITE")
|
||||||
v.githubButton.MoveTo(264, 330)
|
v.githubButton.MoveTo(264, 330)
|
||||||
v.githubButton.SetVisible(!v.ShowTrademarkScreen)
|
v.githubButton.SetVisible(!v.ShowTrademarkScreen)
|
||||||
v.githubButton.OnActivated(func() { v.onGithubButtonClicked() })
|
v.githubButton.OnActivated(func() { v.onGithubButtonClicked() })
|
||||||
v.uiManager.AddWidget(v.githubButton)
|
v.uiManager.AddWidget(v.githubButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.mapTestButton = UI.CreateButton(UI.ButtonTypeWide, v.fileProvider, "MAP ENGINE TEST")
|
v.mapTestButton = ui.CreateButton(ui.ButtonTypeWide, v.fileProvider, "MAP ENGINE TEST")
|
||||||
v.mapTestButton.MoveTo(264, 450)
|
v.mapTestButton.MoveTo(264, 450)
|
||||||
v.mapTestButton.SetVisible(!v.ShowTrademarkScreen)
|
v.mapTestButton.SetVisible(!v.ShowTrademarkScreen)
|
||||||
v.mapTestButton.OnActivated(func() { v.onMapTestClicked() })
|
v.mapTestButton.OnActivated(func() { v.onMapTestClicked() })
|
||||||
@ -240,7 +240,7 @@ func (v *MainMenu) Render(screen *ebiten.Image) {
|
|||||||
// Update runs the update logic on the main menu
|
// Update runs the update logic on the main menu
|
||||||
func (v *MainMenu) Update(tickTime float64) {
|
func (v *MainMenu) Update(tickTime float64) {
|
||||||
if v.ShowTrademarkScreen {
|
if v.ShowTrademarkScreen {
|
||||||
if v.uiManager.CursorButtonPressed(UI.CursorButtonLeft) {
|
if v.uiManager.CursorButtonPressed(ui.CursorButtonLeft) {
|
||||||
if v.leftButtonHeld {
|
if v.leftButtonHeld {
|
||||||
return
|
return
|
||||||
}
|
}
|
@ -1,38 +1,38 @@
|
|||||||
package Scenes
|
package scenes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Map"
|
_map "github.com/OpenDiablo2/OpenDiablo2/map"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Sound"
|
"github.com/OpenDiablo2/OpenDiablo2/sound"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/UI"
|
"github.com/OpenDiablo2/OpenDiablo2/ui"
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/ebitenutil"
|
"github.com/hajimehoshi/ebiten/ebitenutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MapEngineTest struct {
|
type MapEngineTest struct {
|
||||||
uiManager *UI.Manager
|
uiManager *ui.Manager
|
||||||
soundManager *Sound.Manager
|
soundManager *sound.Manager
|
||||||
fileProvider Common.FileProvider
|
fileProvider common.FileProvider
|
||||||
sceneProvider SceneProvider
|
sceneProvider SceneProvider
|
||||||
gameState *Common.GameState
|
gameState *common.GameState
|
||||||
mapEngine *Map.Engine
|
mapEngine *_map.Engine
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateMapEngineTest(
|
func CreateMapEngineTest(
|
||||||
fileProvider Common.FileProvider,
|
fileProvider common.FileProvider,
|
||||||
sceneProvider SceneProvider,
|
sceneProvider SceneProvider,
|
||||||
uiManager *UI.Manager,
|
uiManager *ui.Manager,
|
||||||
soundManager *Sound.Manager) *MapEngineTest {
|
soundManager *sound.Manager) *MapEngineTest {
|
||||||
result := &MapEngineTest{
|
result := &MapEngineTest{
|
||||||
fileProvider: fileProvider,
|
fileProvider: fileProvider,
|
||||||
uiManager: uiManager,
|
uiManager: uiManager,
|
||||||
soundManager: soundManager,
|
soundManager: soundManager,
|
||||||
sceneProvider: sceneProvider,
|
sceneProvider: sceneProvider,
|
||||||
}
|
}
|
||||||
result.gameState = Common.CreateGameState()
|
result.gameState = common.CreateGameState()
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ func (v *MapEngineTest) Load() []func() {
|
|||||||
v.soundManager.PlayBGM("")
|
v.soundManager.PlayBGM("")
|
||||||
return []func(){
|
return []func(){
|
||||||
func() {
|
func() {
|
||||||
v.mapEngine = Map.CreateMapEngine(v.gameState, v.soundManager, v.fileProvider)
|
v.mapEngine = _map.CreateMapEngine(v.gameState, v.soundManager, v.fileProvider)
|
||||||
|
|
||||||
v.mapEngine.GenerateAct1Overworld()
|
v.mapEngine.GenerateAct1Overworld()
|
||||||
//v.mapEngine.GenerateMap(Map.RegionAct1Tristram, 300)
|
//v.mapEngine.GenerateMap(Map.RegionAct1Tristram, 300)
|
||||||
@ -70,7 +70,7 @@ func (v *MapEngineTest) Render(screen *ebiten.Image) {
|
|||||||
v.mapEngine.Render(screen)
|
v.mapEngine.Render(screen)
|
||||||
actualX := float64(v.uiManager.CursorX) - v.mapEngine.OffsetX
|
actualX := float64(v.uiManager.CursorX) - v.mapEngine.OffsetX
|
||||||
actualY := float64(v.uiManager.CursorY) - v.mapEngine.OffsetY
|
actualY := float64(v.uiManager.CursorY) - v.mapEngine.OffsetY
|
||||||
tileX, tileY := Common.ScreenToIso(actualX, actualY)
|
tileX, tileY := common.ScreenToIso(actualX, actualY)
|
||||||
subtileX := int(math.Ceil(math.Mod((tileX*10), 10))) / 2
|
subtileX := int(math.Ceil(math.Mod((tileX*10), 10))) / 2
|
||||||
subtileY := int(math.Ceil(math.Mod((tileY*10), 10))) / 2
|
subtileY := int(math.Ceil(math.Mod((tileY*10), 10))) / 2
|
||||||
curRegion := v.mapEngine.GetRegionAt(int(tileX), int(tileY))
|
curRegion := v.mapEngine.GetRegionAt(int(tileX), int(tileY))
|
@ -1,4 +1,4 @@
|
|||||||
package Scenes
|
package scenes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
@ -1,4 +1,4 @@
|
|||||||
package Scenes
|
package scenes
|
||||||
|
|
||||||
// SceneProvider provides the ability to change scenes
|
// SceneProvider provides the ability to change scenes
|
||||||
type SceneProvider interface {
|
type SceneProvider interface {
|
568
scenes/SelectHeroClass.go
Normal file
568
scenes/SelectHeroClass.go
Normal file
@ -0,0 +1,568 @@
|
|||||||
|
package scenes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/palettedefs"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/resourcepaths"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/sound"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/ui"
|
||||||
|
"github.com/hajimehoshi/ebiten"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HeroStance int
|
||||||
|
|
||||||
|
const (
|
||||||
|
HeroStanceIdle HeroStance = 0
|
||||||
|
HeroStanceIdleSelected HeroStance = 1
|
||||||
|
HeroStanceApproaching HeroStance = 2
|
||||||
|
HeroStanceSelected HeroStance = 3
|
||||||
|
HeroStanceRetreating HeroStance = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
type HeroRenderInfo struct {
|
||||||
|
Stance HeroStance
|
||||||
|
IdleSprite *common.Sprite
|
||||||
|
IdleSelectedSprite *common.Sprite
|
||||||
|
ForwardWalkSprite *common.Sprite
|
||||||
|
ForwardWalkSpriteOverlay *common.Sprite
|
||||||
|
SelectedSprite *common.Sprite
|
||||||
|
SelectedSpriteOverlay *common.Sprite
|
||||||
|
BackWalkSprite *common.Sprite
|
||||||
|
BackWalkSpriteOverlay *common.Sprite
|
||||||
|
SelectionBounds image.Rectangle
|
||||||
|
SelectSfx *sound.SoundEffect
|
||||||
|
DeselectSfx *sound.SoundEffect
|
||||||
|
}
|
||||||
|
|
||||||
|
type SelectHeroClass struct {
|
||||||
|
uiManager *ui.Manager
|
||||||
|
soundManager *sound.Manager
|
||||||
|
fileProvider common.FileProvider
|
||||||
|
sceneProvider SceneProvider
|
||||||
|
bgImage *common.Sprite
|
||||||
|
campfire *common.Sprite
|
||||||
|
headingLabel *ui.Label
|
||||||
|
heroClassLabel *ui.Label
|
||||||
|
heroDesc1Label *ui.Label
|
||||||
|
heroDesc2Label *ui.Label
|
||||||
|
heroDesc3Label *ui.Label
|
||||||
|
heroRenderInfo map[common.Hero]*HeroRenderInfo
|
||||||
|
selectedHero common.Hero
|
||||||
|
exitButton *ui.Button
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateSelectHeroClass(
|
||||||
|
fileProvider common.FileProvider,
|
||||||
|
sceneProvider SceneProvider,
|
||||||
|
uiManager *ui.Manager, soundManager *sound.Manager,
|
||||||
|
) *SelectHeroClass {
|
||||||
|
result := &SelectHeroClass{
|
||||||
|
uiManager: uiManager,
|
||||||
|
sceneProvider: sceneProvider,
|
||||||
|
fileProvider: fileProvider,
|
||||||
|
soundManager: soundManager,
|
||||||
|
heroRenderInfo: make(map[common.Hero]*HeroRenderInfo),
|
||||||
|
selectedHero: common.HeroNone,
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *SelectHeroClass) Load() []func() {
|
||||||
|
v.soundManager.PlayBGM(resourcepaths.BGMTitle)
|
||||||
|
return []func(){
|
||||||
|
func() {
|
||||||
|
v.bgImage = v.fileProvider.LoadSprite(resourcepaths.CharacterSelectBackground, palettedefs.Fechar)
|
||||||
|
v.bgImage.MoveTo(0, 0)
|
||||||
|
},
|
||||||
|
func() {
|
||||||
|
v.headingLabel = ui.CreateLabel(v.fileProvider, resourcepaths.Font30, palettedefs.Units)
|
||||||
|
fontWidth, _ := v.headingLabel.GetSize()
|
||||||
|
v.headingLabel.MoveTo(400-int(fontWidth/2), 17)
|
||||||
|
v.headingLabel.SetText("Select Hero Class")
|
||||||
|
v.headingLabel.Alignment = ui.LabelAlignCenter
|
||||||
|
},
|
||||||
|
func() {
|
||||||
|
v.heroClassLabel = ui.CreateLabel(v.fileProvider, resourcepaths.Font30, palettedefs.Units)
|
||||||
|
v.heroClassLabel.Alignment = ui.LabelAlignCenter
|
||||||
|
v.heroClassLabel.MoveTo(400, 65)
|
||||||
|
},
|
||||||
|
func() {
|
||||||
|
v.heroDesc1Label = ui.CreateLabel(v.fileProvider, resourcepaths.Font16, palettedefs.Units)
|
||||||
|
v.heroDesc1Label.Alignment = ui.LabelAlignCenter
|
||||||
|
v.heroDesc1Label.MoveTo(400, 100)
|
||||||
|
},
|
||||||
|
func() {
|
||||||
|
v.heroDesc2Label = ui.CreateLabel(v.fileProvider, resourcepaths.Font16, palettedefs.Units)
|
||||||
|
v.heroDesc2Label.Alignment = ui.LabelAlignCenter
|
||||||
|
v.heroDesc2Label.MoveTo(400, 115)
|
||||||
|
},
|
||||||
|
func() {
|
||||||
|
v.heroDesc3Label = ui.CreateLabel(v.fileProvider, resourcepaths.Font16, palettedefs.Units)
|
||||||
|
v.heroDesc3Label.Alignment = ui.LabelAlignCenter
|
||||||
|
v.heroDesc3Label.MoveTo(400, 130)
|
||||||
|
},
|
||||||
|
func() {
|
||||||
|
v.campfire = v.fileProvider.LoadSprite(resourcepaths.CharacterSelectCampfire, palettedefs.Fechar)
|
||||||
|
v.campfire.MoveTo(380, 335)
|
||||||
|
v.campfire.Animate = true
|
||||||
|
v.campfire.Blend = true
|
||||||
|
},
|
||||||
|
func() {
|
||||||
|
v.exitButton = ui.CreateButton(ui.ButtonTypeMedium, v.fileProvider, common.TranslateString("#970"))
|
||||||
|
v.exitButton.MoveTo(33, 537)
|
||||||
|
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
||||||
|
v.uiManager.AddWidget(v.exitButton)
|
||||||
|
},
|
||||||
|
func() {
|
||||||
|
v.heroRenderInfo[common.HeroBarbarian] = &HeroRenderInfo{
|
||||||
|
HeroStanceIdle,
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectBarbarianUnselected, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectBarbarianUnselectedH, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectBarbarianForwardWalk, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectBarbarianForwardWalkOverlay, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectBarbarianSelected, palettedefs.Fechar),
|
||||||
|
nil,
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectBarbarianBackWalk, palettedefs.Fechar),
|
||||||
|
nil,
|
||||||
|
image.Rectangle{Min: image.Point{364, 201}, Max: image.Point{90, 170}},
|
||||||
|
v.soundManager.LoadSoundEffect(resourcepaths.SFXBarbarianSelect),
|
||||||
|
v.soundManager.LoadSoundEffect(resourcepaths.SFXBarbarianDeselect),
|
||||||
|
}
|
||||||
|
v.heroRenderInfo[common.HeroBarbarian].IdleSprite.MoveTo(400, 330)
|
||||||
|
v.heroRenderInfo[common.HeroBarbarian].IdleSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroBarbarian].IdleSelectedSprite.MoveTo(400, 330)
|
||||||
|
v.heroRenderInfo[common.HeroBarbarian].IdleSelectedSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroBarbarian].ForwardWalkSprite.MoveTo(400, 330)
|
||||||
|
v.heroRenderInfo[common.HeroBarbarian].ForwardWalkSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroBarbarian].ForwardWalkSprite.SpecialFrameTime = 2500
|
||||||
|
v.heroRenderInfo[common.HeroBarbarian].ForwardWalkSprite.StopOnLastFrame = true
|
||||||
|
v.heroRenderInfo[common.HeroBarbarian].ForwardWalkSpriteOverlay.MoveTo(400, 330)
|
||||||
|
v.heroRenderInfo[common.HeroBarbarian].ForwardWalkSpriteOverlay.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroBarbarian].ForwardWalkSpriteOverlay.SpecialFrameTime = 2500
|
||||||
|
v.heroRenderInfo[common.HeroBarbarian].ForwardWalkSpriteOverlay.StopOnLastFrame = true
|
||||||
|
v.heroRenderInfo[common.HeroBarbarian].SelectedSprite.MoveTo(400, 330)
|
||||||
|
v.heroRenderInfo[common.HeroBarbarian].SelectedSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroBarbarian].BackWalkSprite.MoveTo(400, 330)
|
||||||
|
v.heroRenderInfo[common.HeroBarbarian].BackWalkSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroBarbarian].BackWalkSprite.SpecialFrameTime = 1000
|
||||||
|
v.heroRenderInfo[common.HeroBarbarian].BackWalkSprite.StopOnLastFrame = true
|
||||||
|
},
|
||||||
|
func() {
|
||||||
|
v.heroRenderInfo[common.HeroSorceress] = &HeroRenderInfo{
|
||||||
|
HeroStanceIdle,
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecSorceressUnselected, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecSorceressUnselectedH, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecSorceressForwardWalk, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecSorceressForwardWalkOverlay, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecSorceressSelected, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecSorceressSelectedOverlay, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecSorceressBackWalk, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecSorceressBackWalkOverlay, palettedefs.Fechar),
|
||||||
|
image.Rectangle{Min: image.Point{580, 240}, Max: image.Point{65, 160}},
|
||||||
|
v.soundManager.LoadSoundEffect(resourcepaths.SFXSorceressSelect),
|
||||||
|
v.soundManager.LoadSoundEffect(resourcepaths.SFXSorceressDeselect),
|
||||||
|
}
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].IdleSprite.MoveTo(626, 352)
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].IdleSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].IdleSelectedSprite.MoveTo(626, 352)
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].IdleSelectedSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].ForwardWalkSprite.MoveTo(626, 352)
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].ForwardWalkSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].ForwardWalkSprite.SpecialFrameTime = 2300
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].ForwardWalkSprite.StopOnLastFrame = true
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].ForwardWalkSpriteOverlay.Blend = true
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].ForwardWalkSpriteOverlay.MoveTo(626, 352)
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].ForwardWalkSpriteOverlay.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].ForwardWalkSpriteOverlay.SpecialFrameTime = 2300
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].ForwardWalkSpriteOverlay.StopOnLastFrame = true
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].SelectedSprite.MoveTo(626, 352)
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].SelectedSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].SelectedSpriteOverlay.Blend = true
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].SelectedSpriteOverlay.MoveTo(626, 352)
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].SelectedSpriteOverlay.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].BackWalkSprite.MoveTo(626, 352)
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].BackWalkSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].BackWalkSprite.SpecialFrameTime = 1200
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].BackWalkSprite.StopOnLastFrame = true
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].BackWalkSpriteOverlay.Blend = true
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].BackWalkSpriteOverlay.MoveTo(626, 352)
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].BackWalkSpriteOverlay.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].BackWalkSpriteOverlay.SpecialFrameTime = 1200
|
||||||
|
v.heroRenderInfo[common.HeroSorceress].BackWalkSpriteOverlay.StopOnLastFrame = true
|
||||||
|
},
|
||||||
|
func() {
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer] = &HeroRenderInfo{
|
||||||
|
HeroStanceIdle,
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectNecromancerUnselected, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectNecromancerUnselectedH, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecNecromancerForwardWalk, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecNecromancerForwardWalkOverlay, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecNecromancerSelected, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecNecromancerSelectedOverlay, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecNecromancerBackWalk, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecNecromancerBackWalkOverlay, palettedefs.Fechar),
|
||||||
|
image.Rectangle{Min: image.Point{265, 220}, Max: image.Point{55, 175}},
|
||||||
|
v.soundManager.LoadSoundEffect(resourcepaths.SFXNecromancerSelect),
|
||||||
|
v.soundManager.LoadSoundEffect(resourcepaths.SFXNecromancerDeselect),
|
||||||
|
}
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].IdleSprite.MoveTo(300, 335)
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].IdleSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].IdleSelectedSprite.MoveTo(300, 335)
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].IdleSelectedSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].ForwardWalkSprite.MoveTo(300, 335)
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].ForwardWalkSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].ForwardWalkSprite.SpecialFrameTime = 2000
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].ForwardWalkSprite.StopOnLastFrame = true
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].ForwardWalkSpriteOverlay.Blend = true
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].ForwardWalkSpriteOverlay.MoveTo(300, 335)
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].ForwardWalkSpriteOverlay.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].ForwardWalkSpriteOverlay.SpecialFrameTime = 2000
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].ForwardWalkSpriteOverlay.StopOnLastFrame = true
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].SelectedSprite.MoveTo(300, 335)
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].SelectedSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].SelectedSpriteOverlay.Blend = true
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].SelectedSpriteOverlay.MoveTo(300, 335)
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].SelectedSpriteOverlay.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].BackWalkSprite.MoveTo(300, 335)
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].BackWalkSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].BackWalkSprite.SpecialFrameTime = 1500
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].BackWalkSprite.StopOnLastFrame = true
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].BackWalkSpriteOverlay.Blend = true
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].BackWalkSpriteOverlay.MoveTo(300, 335)
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].BackWalkSpriteOverlay.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].BackWalkSpriteOverlay.SpecialFrameTime = 1500
|
||||||
|
v.heroRenderInfo[common.HeroNecromancer].BackWalkSpriteOverlay.StopOnLastFrame = true
|
||||||
|
},
|
||||||
|
func() {
|
||||||
|
v.heroRenderInfo[common.HeroPaladin] = &HeroRenderInfo{
|
||||||
|
HeroStanceIdle,
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectPaladinUnselected, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectPaladinUnselectedH, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecPaladinForwardWalk, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecPaladinForwardWalkOverlay, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecPaladinSelected, palettedefs.Fechar),
|
||||||
|
nil,
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecPaladinBackWalk, palettedefs.Fechar),
|
||||||
|
nil,
|
||||||
|
image.Rectangle{Min: image.Point{490, 210}, Max: image.Point{65, 180}},
|
||||||
|
v.soundManager.LoadSoundEffect(resourcepaths.SFXPaladinSelect),
|
||||||
|
v.soundManager.LoadSoundEffect(resourcepaths.SFXPaladinDeselect),
|
||||||
|
}
|
||||||
|
v.heroRenderInfo[common.HeroPaladin].IdleSprite.MoveTo(521, 338)
|
||||||
|
v.heroRenderInfo[common.HeroPaladin].IdleSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroPaladin].IdleSelectedSprite.MoveTo(521, 338)
|
||||||
|
v.heroRenderInfo[common.HeroPaladin].IdleSelectedSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroPaladin].ForwardWalkSprite.MoveTo(521, 338)
|
||||||
|
v.heroRenderInfo[common.HeroPaladin].ForwardWalkSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroPaladin].ForwardWalkSprite.SpecialFrameTime = 3400
|
||||||
|
v.heroRenderInfo[common.HeroPaladin].ForwardWalkSprite.StopOnLastFrame = true
|
||||||
|
v.heroRenderInfo[common.HeroPaladin].ForwardWalkSpriteOverlay.MoveTo(521, 338)
|
||||||
|
v.heroRenderInfo[common.HeroPaladin].ForwardWalkSpriteOverlay.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroPaladin].ForwardWalkSpriteOverlay.SpecialFrameTime = 3400
|
||||||
|
v.heroRenderInfo[common.HeroPaladin].ForwardWalkSpriteOverlay.StopOnLastFrame = true
|
||||||
|
v.heroRenderInfo[common.HeroPaladin].SelectedSprite.MoveTo(521, 338)
|
||||||
|
v.heroRenderInfo[common.HeroPaladin].SelectedSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroPaladin].BackWalkSprite.MoveTo(521, 338)
|
||||||
|
v.heroRenderInfo[common.HeroPaladin].BackWalkSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroPaladin].BackWalkSprite.SpecialFrameTime = 1300
|
||||||
|
v.heroRenderInfo[common.HeroPaladin].BackWalkSprite.StopOnLastFrame = true
|
||||||
|
},
|
||||||
|
func() {
|
||||||
|
v.heroRenderInfo[common.HeroAmazon] = &HeroRenderInfo{
|
||||||
|
HeroStanceIdle,
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectAmazonUnselected, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectAmazonUnselectedH, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecAmazonForwardWalk, palettedefs.Fechar),
|
||||||
|
nil,
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecAmazonSelected, palettedefs.Fechar),
|
||||||
|
nil,
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelecAmazonBackWalk, palettedefs.Fechar),
|
||||||
|
nil,
|
||||||
|
image.Rectangle{Min: image.Point{70, 220}, Max: image.Point{55, 200}},
|
||||||
|
v.soundManager.LoadSoundEffect(resourcepaths.SFXAmazonSelect),
|
||||||
|
v.soundManager.LoadSoundEffect(resourcepaths.SFXAmazonDeselect),
|
||||||
|
}
|
||||||
|
v.heroRenderInfo[common.HeroAmazon].IdleSprite.MoveTo(100, 339)
|
||||||
|
v.heroRenderInfo[common.HeroAmazon].IdleSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroAmazon].IdleSelectedSprite.MoveTo(100, 339)
|
||||||
|
v.heroRenderInfo[common.HeroAmazon].IdleSelectedSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroAmazon].ForwardWalkSprite.MoveTo(100, 339)
|
||||||
|
v.heroRenderInfo[common.HeroAmazon].ForwardWalkSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroAmazon].ForwardWalkSprite.SpecialFrameTime = 2200
|
||||||
|
v.heroRenderInfo[common.HeroAmazon].ForwardWalkSprite.StopOnLastFrame = true
|
||||||
|
v.heroRenderInfo[common.HeroAmazon].SelectedSprite.MoveTo(100, 339)
|
||||||
|
v.heroRenderInfo[common.HeroAmazon].SelectedSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroAmazon].BackWalkSprite.MoveTo(100, 339)
|
||||||
|
v.heroRenderInfo[common.HeroAmazon].BackWalkSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroAmazon].BackWalkSprite.SpecialFrameTime = 1500
|
||||||
|
v.heroRenderInfo[common.HeroAmazon].BackWalkSprite.StopOnLastFrame = true
|
||||||
|
},
|
||||||
|
func() {
|
||||||
|
v.heroRenderInfo[common.HeroAssassin] = &HeroRenderInfo{
|
||||||
|
HeroStanceIdle,
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectAssassinUnselected, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectAssassinUnselectedH, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectAssassinForwardWalk, palettedefs.Fechar),
|
||||||
|
nil,
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectAssassinSelected, palettedefs.Fechar),
|
||||||
|
nil,
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectAssassinBackWalk, palettedefs.Fechar),
|
||||||
|
nil,
|
||||||
|
image.Rectangle{Min: image.Point{175, 235}, Max: image.Point{50, 180}},
|
||||||
|
v.soundManager.LoadSoundEffect(resourcepaths.SFXAssassinSelect),
|
||||||
|
v.soundManager.LoadSoundEffect(resourcepaths.SFXAssassinDeselect),
|
||||||
|
}
|
||||||
|
v.heroRenderInfo[common.HeroAssassin].IdleSprite.MoveTo(231, 365)
|
||||||
|
v.heroRenderInfo[common.HeroAssassin].IdleSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroAssassin].IdleSelectedSprite.MoveTo(231, 365)
|
||||||
|
v.heroRenderInfo[common.HeroAssassin].IdleSelectedSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroAssassin].ForwardWalkSprite.MoveTo(231, 365)
|
||||||
|
v.heroRenderInfo[common.HeroAssassin].ForwardWalkSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroAssassin].ForwardWalkSprite.SpecialFrameTime = 3800
|
||||||
|
v.heroRenderInfo[common.HeroAssassin].ForwardWalkSprite.StopOnLastFrame = true
|
||||||
|
v.heroRenderInfo[common.HeroAssassin].SelectedSprite.MoveTo(231, 365)
|
||||||
|
v.heroRenderInfo[common.HeroAssassin].SelectedSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroAssassin].BackWalkSprite.MoveTo(231, 365)
|
||||||
|
v.heroRenderInfo[common.HeroAssassin].BackWalkSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroAssassin].BackWalkSprite.SpecialFrameTime = 1500
|
||||||
|
v.heroRenderInfo[common.HeroAssassin].BackWalkSprite.StopOnLastFrame = true
|
||||||
|
},
|
||||||
|
func() {
|
||||||
|
v.heroRenderInfo[common.HeroDruid] = &HeroRenderInfo{
|
||||||
|
HeroStanceIdle,
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectDruidUnselected, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectDruidUnselectedH, palettedefs.Fechar),
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectDruidForwardWalk, palettedefs.Fechar),
|
||||||
|
nil,
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectDruidSelected, palettedefs.Fechar),
|
||||||
|
nil,
|
||||||
|
v.fileProvider.LoadSprite(resourcepaths.CharacterSelectDruidBackWalk, palettedefs.Fechar),
|
||||||
|
nil,
|
||||||
|
image.Rectangle{Min: image.Point{680, 220}, Max: image.Point{70, 195}},
|
||||||
|
v.soundManager.LoadSoundEffect(resourcepaths.SFXDruidSelect),
|
||||||
|
v.soundManager.LoadSoundEffect(resourcepaths.SFXDruidDeselect),
|
||||||
|
}
|
||||||
|
v.heroRenderInfo[common.HeroDruid].IdleSprite.MoveTo(720, 370)
|
||||||
|
v.heroRenderInfo[common.HeroDruid].IdleSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroDruid].IdleSelectedSprite.MoveTo(720, 370)
|
||||||
|
v.heroRenderInfo[common.HeroDruid].IdleSelectedSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroDruid].ForwardWalkSprite.MoveTo(720, 370)
|
||||||
|
v.heroRenderInfo[common.HeroDruid].ForwardWalkSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroDruid].ForwardWalkSprite.SpecialFrameTime = 4800
|
||||||
|
v.heroRenderInfo[common.HeroDruid].ForwardWalkSprite.StopOnLastFrame = true
|
||||||
|
v.heroRenderInfo[common.HeroDruid].SelectedSprite.MoveTo(720, 370)
|
||||||
|
v.heroRenderInfo[common.HeroDruid].SelectedSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroDruid].BackWalkSprite.MoveTo(720, 370)
|
||||||
|
v.heroRenderInfo[common.HeroDruid].BackWalkSprite.Animate = true
|
||||||
|
v.heroRenderInfo[common.HeroDruid].BackWalkSprite.SpecialFrameTime = 1500
|
||||||
|
v.heroRenderInfo[common.HeroDruid].BackWalkSprite.StopOnLastFrame = true
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *SelectHeroClass) Unload() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *SelectHeroClass) onExitButtonClicked() {
|
||||||
|
v.sceneProvider.SetNextScene(CreateCharacterSelect(v.fileProvider, v.sceneProvider, v.uiManager, v.soundManager))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *SelectHeroClass) Render(screen *ebiten.Image) {
|
||||||
|
v.bgImage.DrawSegments(screen, 4, 3, 0)
|
||||||
|
v.headingLabel.Draw(screen)
|
||||||
|
if v.selectedHero != common.HeroNone {
|
||||||
|
v.heroClassLabel.Draw(screen)
|
||||||
|
v.heroDesc1Label.Draw(screen)
|
||||||
|
v.heroDesc2Label.Draw(screen)
|
||||||
|
v.heroDesc3Label.Draw(screen)
|
||||||
|
}
|
||||||
|
for heroClass, heroInfo := range v.heroRenderInfo {
|
||||||
|
if heroInfo.Stance == HeroStanceIdle || heroInfo.Stance == HeroStanceIdleSelected {
|
||||||
|
v.renderHero(screen, heroClass)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for heroClass, heroInfo := range v.heroRenderInfo {
|
||||||
|
if heroInfo.Stance != HeroStanceIdle && heroInfo.Stance != HeroStanceIdleSelected {
|
||||||
|
v.renderHero(screen, heroClass)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v.campfire.Draw(screen)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *SelectHeroClass) Update(tickTime float64) {
|
||||||
|
canSelect := true
|
||||||
|
for _, info := range v.heroRenderInfo {
|
||||||
|
if info.Stance != HeroStanceIdle && info.Stance != HeroStanceIdleSelected && info.Stance != HeroStanceSelected {
|
||||||
|
canSelect = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
allIdle := true
|
||||||
|
for heroType, data := range v.heroRenderInfo {
|
||||||
|
if allIdle && data.Stance != HeroStanceIdle {
|
||||||
|
allIdle = false
|
||||||
|
}
|
||||||
|
v.updateHeroSelectionHover(heroType, canSelect)
|
||||||
|
}
|
||||||
|
if v.selectedHero != common.HeroNone && allIdle {
|
||||||
|
v.selectedHero = common.HeroNone
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *SelectHeroClass) updateHeroSelectionHover(hero common.Hero, canSelect bool) {
|
||||||
|
renderInfo := v.heroRenderInfo[hero]
|
||||||
|
switch renderInfo.Stance {
|
||||||
|
case HeroStanceApproaching:
|
||||||
|
if renderInfo.ForwardWalkSprite.OnLastFrame() {
|
||||||
|
renderInfo.Stance = HeroStanceSelected
|
||||||
|
renderInfo.SelectedSprite.ResetAnimation()
|
||||||
|
if renderInfo.SelectedSpriteOverlay != nil {
|
||||||
|
renderInfo.SelectedSpriteOverlay.ResetAnimation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
case HeroStanceRetreating:
|
||||||
|
if renderInfo.BackWalkSprite.OnLastFrame() {
|
||||||
|
renderInfo.Stance = HeroStanceIdle
|
||||||
|
renderInfo.IdleSprite.ResetAnimation()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !canSelect {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if renderInfo.Stance == HeroStanceSelected {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mouseX := v.uiManager.CursorX
|
||||||
|
mouseY := v.uiManager.CursorY
|
||||||
|
b := renderInfo.SelectionBounds
|
||||||
|
mouseHover := (mouseX >= b.Min.X) && (mouseX <= b.Min.X+b.Max.X) && (mouseY >= b.Min.Y) && (mouseY <= b.Min.Y+b.Max.Y)
|
||||||
|
if mouseHover && v.uiManager.CursorButtonPressed(ui.CursorButtonLeft) {
|
||||||
|
// showEntryUi = true;
|
||||||
|
renderInfo.Stance = HeroStanceApproaching
|
||||||
|
renderInfo.ForwardWalkSprite.ResetAnimation()
|
||||||
|
if renderInfo.ForwardWalkSpriteOverlay != nil {
|
||||||
|
renderInfo.ForwardWalkSpriteOverlay.ResetAnimation()
|
||||||
|
}
|
||||||
|
for _, heroInfo := range v.heroRenderInfo {
|
||||||
|
if heroInfo.Stance != HeroStanceSelected {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
heroInfo.SelectSfx.Stop()
|
||||||
|
heroInfo.DeselectSfx.Play()
|
||||||
|
heroInfo.Stance = HeroStanceRetreating
|
||||||
|
heroInfo.BackWalkSprite.ResetAnimation()
|
||||||
|
if heroInfo.BackWalkSpriteOverlay != nil {
|
||||||
|
heroInfo.BackWalkSpriteOverlay.ResetAnimation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v.selectedHero = hero
|
||||||
|
v.updateHeroText()
|
||||||
|
renderInfo.SelectSfx.Play()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if mouseHover {
|
||||||
|
renderInfo.Stance = HeroStanceIdleSelected
|
||||||
|
} else {
|
||||||
|
renderInfo.Stance = HeroStanceIdle
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.selectedHero == common.HeroNone && mouseHover {
|
||||||
|
v.selectedHero = hero
|
||||||
|
v.updateHeroText()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *SelectHeroClass) renderHero(screen *ebiten.Image, hero common.Hero) {
|
||||||
|
renderInfo := v.heroRenderInfo[hero]
|
||||||
|
switch renderInfo.Stance {
|
||||||
|
case HeroStanceIdle:
|
||||||
|
renderInfo.IdleSprite.Draw(screen)
|
||||||
|
case HeroStanceIdleSelected:
|
||||||
|
renderInfo.IdleSelectedSprite.Draw(screen)
|
||||||
|
case HeroStanceApproaching:
|
||||||
|
renderInfo.ForwardWalkSprite.Draw(screen)
|
||||||
|
if renderInfo.ForwardWalkSpriteOverlay != nil {
|
||||||
|
renderInfo.ForwardWalkSpriteOverlay.Draw(screen)
|
||||||
|
}
|
||||||
|
case HeroStanceSelected:
|
||||||
|
renderInfo.SelectedSprite.Draw(screen)
|
||||||
|
if renderInfo.SelectedSpriteOverlay != nil {
|
||||||
|
renderInfo.SelectedSpriteOverlay.Draw(screen)
|
||||||
|
}
|
||||||
|
case HeroStanceRetreating:
|
||||||
|
renderInfo.BackWalkSprite.Draw(screen)
|
||||||
|
if renderInfo.BackWalkSpriteOverlay != nil {
|
||||||
|
renderInfo.BackWalkSpriteOverlay.Draw(screen)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *SelectHeroClass) updateHeroText() {
|
||||||
|
switch v.selectedHero {
|
||||||
|
case common.HeroNone:
|
||||||
|
return
|
||||||
|
case common.HeroBarbarian:
|
||||||
|
v.heroClassLabel.SetText(common.TranslateString("partycharbar"))
|
||||||
|
v.setDescLabels("#1709")
|
||||||
|
case common.HeroNecromancer:
|
||||||
|
v.heroClassLabel.SetText(common.TranslateString("partycharnec"))
|
||||||
|
v.setDescLabels("#1704")
|
||||||
|
case common.HeroPaladin:
|
||||||
|
v.heroClassLabel.SetText(common.TranslateString("partycharpal"))
|
||||||
|
v.setDescLabels("#1711")
|
||||||
|
case common.HeroAssassin:
|
||||||
|
v.heroClassLabel.SetText(common.TranslateString("partycharass"))
|
||||||
|
v.setDescLabels("#305")
|
||||||
|
case common.HeroSorceress:
|
||||||
|
v.heroClassLabel.SetText(common.TranslateString("partycharsor"))
|
||||||
|
v.setDescLabels("#1710")
|
||||||
|
case common.HeroAmazon:
|
||||||
|
v.heroClassLabel.SetText(common.TranslateString("partycharama"))
|
||||||
|
v.setDescLabels("#1698")
|
||||||
|
case common.HeroDruid:
|
||||||
|
v.heroClassLabel.SetText(common.TranslateString("partychardru"))
|
||||||
|
v.setDescLabels("#304")
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (selectedHero == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (selectedHero.Value)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
heroClassLabel.Location = new Point(400 - (heroClassLabel.TextArea.Width / 2), 65);
|
||||||
|
heroDesc1Label.Location = new Point(400 - (heroDesc1Label.TextArea.Width / 2), 100);
|
||||||
|
heroDesc2Label.Location = new Point(400 - (heroDesc2Label.TextArea.Width / 2), 115);
|
||||||
|
heroDesc3Label.Location = new Point(400 - (heroDesc3Label.TextArea.Width / 2), 130);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *SelectHeroClass) setDescLabels(descKey string) {
|
||||||
|
heroDesc := common.TranslateString(descKey)
|
||||||
|
parts := common.SplitIntoLinesWithMaxWidth(heroDesc, 37)
|
||||||
|
if len(parts) > 1 {
|
||||||
|
v.heroDesc1Label.SetText(parts[0])
|
||||||
|
} else {
|
||||||
|
v.heroDesc1Label.SetText("")
|
||||||
|
}
|
||||||
|
if len(parts) > 1 {
|
||||||
|
v.heroDesc2Label.SetText(parts[1])
|
||||||
|
} else {
|
||||||
|
v.heroDesc2Label.SetText("")
|
||||||
|
}
|
||||||
|
if len(parts) > 2 {
|
||||||
|
v.heroDesc3Label.SetText(parts[2])
|
||||||
|
} else {
|
||||||
|
v.heroDesc3Label.SetText("")
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +1,16 @@
|
|||||||
package Sound
|
package sound
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
"github.com/hajimehoshi/ebiten/audio"
|
"github.com/hajimehoshi/ebiten/audio"
|
||||||
"github.com/hajimehoshi/ebiten/audio/wav"
|
"github.com/hajimehoshi/ebiten/audio/wav"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Manager provides sound
|
// Manager provides sound
|
||||||
type Manager struct {
|
type Manager struct {
|
||||||
fileProvider Common.FileProvider
|
fileProvider common.FileProvider
|
||||||
audioContext *audio.Context // The Audio context
|
audioContext *audio.Context // The Audio context
|
||||||
bgmAudio *audio.Player // The audio player
|
bgmAudio *audio.Player // The audio player
|
||||||
lastBgm string
|
lastBgm string
|
||||||
@ -19,7 +19,7 @@ type Manager struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateManager creates a sound provider
|
// CreateManager creates a sound provider
|
||||||
func CreateManager(fileProvider Common.FileProvider) *Manager {
|
func CreateManager(fileProvider common.FileProvider) *Manager {
|
||||||
result := &Manager{
|
result := &Manager{
|
||||||
fileProvider: fileProvider,
|
fileProvider: fileProvider,
|
||||||
}
|
}
|
@ -1,11 +1,11 @@
|
|||||||
package Sound
|
package sound
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/audio/wav"
|
"github.com/hajimehoshi/ebiten/audio/wav"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/audio"
|
"github.com/hajimehoshi/ebiten/audio"
|
||||||
)
|
)
|
||||||
@ -14,11 +14,11 @@ type SoundEffect struct {
|
|||||||
player *audio.Player
|
player *audio.Player
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateSoundEffect(sfx string, fileProvider Common.FileProvider, context *audio.Context, volume float64) *SoundEffect {
|
func CreateSoundEffect(sfx string, fileProvider common.FileProvider, context *audio.Context, volume float64) *SoundEffect {
|
||||||
result := &SoundEffect{}
|
result := &SoundEffect{}
|
||||||
var soundFile string
|
var soundFile string
|
||||||
if _, exists := Common.Sounds[sfx]; exists {
|
if _, exists := common.Sounds[sfx]; exists {
|
||||||
soundEntry := Common.Sounds[sfx]
|
soundEntry := common.Sounds[sfx]
|
||||||
soundFile = soundEntry.FileName
|
soundFile = soundEntry.FileName
|
||||||
} else {
|
} else {
|
||||||
soundFile = sfx
|
soundFile = sfx
|
@ -1,12 +1,12 @@
|
|||||||
package UI
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
"github.com/OpenDiablo2/OpenDiablo2/palettedefs"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
"github.com/OpenDiablo2/OpenDiablo2/resourcepaths"
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ type ButtonLayout struct {
|
|||||||
XSegments int //1
|
XSegments int //1
|
||||||
YSegments int // 1
|
YSegments int // 1
|
||||||
ResourceName string // Font Name
|
ResourceName string // Font Name
|
||||||
PaletteName PaletteDefs.PaletteType // PaletteType
|
PaletteName palettedefs.PaletteType // PaletteType
|
||||||
Toggleable bool // false
|
Toggleable bool // false
|
||||||
BaseFrame int // 0
|
BaseFrame int // 0
|
||||||
DisabledFrame int // -1
|
DisabledFrame int // -1
|
||||||
@ -55,10 +55,10 @@ type ButtonLayout struct {
|
|||||||
|
|
||||||
// ButtonLayouts define the type of buttons you can have
|
// ButtonLayouts define the type of buttons you can have
|
||||||
var ButtonLayouts = map[ButtonType]ButtonLayout{
|
var ButtonLayouts = map[ButtonType]ButtonLayout{
|
||||||
ButtonTypeWide: {2, 1, ResourcePaths.WideButtonBlank, PaletteDefs.Units, false, 0, -1, ResourcePaths.FontExocet10, nil, true, 1},
|
ButtonTypeWide: {2, 1, resourcepaths.WideButtonBlank, palettedefs.Units, false, 0, -1, resourcepaths.FontExocet10, nil, true, 1},
|
||||||
ButtonTypeShort: {1, 1, ResourcePaths.ShortButtonBlank, PaletteDefs.Units, false, 0, -1, ResourcePaths.FontRediculous, nil, true, -1},
|
ButtonTypeShort: {1, 1, resourcepaths.ShortButtonBlank, palettedefs.Units, false, 0, -1, resourcepaths.FontRediculous, nil, true, -1},
|
||||||
ButtonTypeMedium: {1, 1, ResourcePaths.MediumButtonBlank, PaletteDefs.Units, false, 0, 0, ResourcePaths.FontExocet10, nil, true, 0},
|
ButtonTypeMedium: {1, 1, resourcepaths.MediumButtonBlank, palettedefs.Units, false, 0, 0, resourcepaths.FontExocet10, nil, true, 0},
|
||||||
ButtonTypeTall: {1, 1, ResourcePaths.TallButtonBlank, PaletteDefs.Units, false, 0, 0, ResourcePaths.FontExocet10, nil, true, 5},
|
ButtonTypeTall: {1, 1, resourcepaths.TallButtonBlank, palettedefs.Units, false, 0, 0, resourcepaths.FontExocet10, nil, true, 5},
|
||||||
/*
|
/*
|
||||||
{eButtonType.Wide, new ButtonLayout { XSegments = 2, ResourceName = ResourcePaths.WideButtonBlank, PaletteName = PaletteDefs.Units } },
|
{eButtonType.Wide, new ButtonLayout { XSegments = 2, ResourceName = ResourcePaths.WideButtonBlank, PaletteName = PaletteDefs.Units } },
|
||||||
{eButtonType.Narrow, new ButtonLayout { ResourceName = ResourcePaths.NarrowButtonBlank, PaletteName = PaletteDefs.Units } },
|
{eButtonType.Narrow, new ButtonLayout { ResourceName = ResourcePaths.NarrowButtonBlank, PaletteName = PaletteDefs.Units } },
|
||||||
@ -89,7 +89,7 @@ type Button struct {
|
|||||||
visible bool
|
visible bool
|
||||||
pressed bool
|
pressed bool
|
||||||
toggled bool
|
toggled bool
|
||||||
fileProvider Common.FileProvider
|
fileProvider common.FileProvider
|
||||||
normalImage *ebiten.Image
|
normalImage *ebiten.Image
|
||||||
pressedImage *ebiten.Image
|
pressedImage *ebiten.Image
|
||||||
toggledImage *ebiten.Image
|
toggledImage *ebiten.Image
|
||||||
@ -100,7 +100,7 @@ type Button struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateButton creates an instance of Button
|
// CreateButton creates an instance of Button
|
||||||
func CreateButton(buttonType ButtonType, fileProvider Common.FileProvider, text string) *Button {
|
func CreateButton(buttonType ButtonType, fileProvider common.FileProvider, text string) *Button {
|
||||||
result := &Button{
|
result := &Button{
|
||||||
fileProvider: fileProvider,
|
fileProvider: fileProvider,
|
||||||
width: 0,
|
width: 0,
|
||||||
@ -111,7 +111,7 @@ func CreateButton(buttonType ButtonType, fileProvider Common.FileProvider, text
|
|||||||
}
|
}
|
||||||
buttonLayout := ButtonLayouts[buttonType]
|
buttonLayout := ButtonLayouts[buttonType]
|
||||||
result.buttonLayout = buttonLayout
|
result.buttonLayout = buttonLayout
|
||||||
font := GetFont(buttonLayout.FontPath, PaletteDefs.Units, fileProvider)
|
font := GetFont(buttonLayout.FontPath, palettedefs.Units, fileProvider)
|
||||||
buttonSprite := fileProvider.LoadSprite(buttonLayout.ResourceName, buttonLayout.PaletteName)
|
buttonSprite := fileProvider.LoadSprite(buttonLayout.ResourceName, buttonLayout.PaletteName)
|
||||||
totalButtonTypes := buttonSprite.GetTotalFrames() / (buttonLayout.XSegments * buttonLayout.YSegments)
|
totalButtonTypes := buttonSprite.GetTotalFrames() / (buttonLayout.XSegments * buttonLayout.YSegments)
|
||||||
for i := 0; i < buttonLayout.XSegments; i++ {
|
for i := 0; i < buttonLayout.XSegments; i++ {
|
||||||
@ -179,7 +179,7 @@ func (v *Button) Draw(target *ebiten.Image) {
|
|||||||
|
|
||||||
if !v.enabled {
|
if !v.enabled {
|
||||||
//opts.CompositeMode = ebiten.CompositeModeLighter
|
//opts.CompositeMode = ebiten.CompositeModeLighter
|
||||||
opts.ColorM = Common.ColorToColorM(color.RGBA{128, 128, 128, 195})
|
opts.ColorM = common.ColorToColorM(color.RGBA{128, 128, 128, 195})
|
||||||
target.DrawImage(v.disabledImage, opts)
|
target.DrawImage(v.disabledImage, opts)
|
||||||
} else if v.toggled && v.pressed {
|
} else if v.toggled && v.pressed {
|
||||||
target.DrawImage(v.pressedToggledImage, opts)
|
target.DrawImage(v.pressedToggledImage, opts)
|
@ -1,11 +1,11 @@
|
|||||||
package UI
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image/color"
|
"image/color"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
"github.com/OpenDiablo2/OpenDiablo2/palettedefs"
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -19,12 +19,12 @@ type FontSize struct {
|
|||||||
|
|
||||||
// Font represents a font
|
// Font represents a font
|
||||||
type Font struct {
|
type Font struct {
|
||||||
fontSprite *Common.Sprite
|
fontSprite *common.Sprite
|
||||||
metrics map[uint8]FontSize
|
metrics map[uint8]FontSize
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFont creates or loads an existing font
|
// GetFont creates or loads an existing font
|
||||||
func GetFont(font string, palette PaletteDefs.PaletteType, fileProvider Common.FileProvider) *Font {
|
func GetFont(font string, palette palettedefs.PaletteType, fileProvider common.FileProvider) *Font {
|
||||||
cacheItem, exists := fontCache[font+"_"+string(palette)]
|
cacheItem, exists := fontCache[font+"_"+string(palette)]
|
||||||
if exists {
|
if exists {
|
||||||
return cacheItem
|
return cacheItem
|
||||||
@ -35,7 +35,7 @@ func GetFont(font string, palette PaletteDefs.PaletteType, fileProvider Common.F
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateFont creates an instance of a MPQ Font
|
// CreateFont creates an instance of a MPQ Font
|
||||||
func CreateFont(font string, palette PaletteDefs.PaletteType, fileProvider Common.FileProvider) *Font {
|
func CreateFont(font string, palette palettedefs.PaletteType, fileProvider common.FileProvider) *Font {
|
||||||
result := &Font{
|
result := &Font{
|
||||||
metrics: make(map[uint8]FontSize),
|
metrics: make(map[uint8]FontSize),
|
||||||
}
|
}
|
||||||
@ -62,12 +62,12 @@ func (v *Font) GetTextMetrics(text string) (width, height uint32) {
|
|||||||
height = uint32(0)
|
height = uint32(0)
|
||||||
maxCharHeight := uint32(0)
|
maxCharHeight := uint32(0)
|
||||||
for _, m := range v.fontSprite.Frames {
|
for _, m := range v.fontSprite.Frames {
|
||||||
maxCharHeight = Common.Max(maxCharHeight, uint32(m.Height))
|
maxCharHeight = common.Max(maxCharHeight, uint32(m.Height))
|
||||||
}
|
}
|
||||||
for i := 0; i < len(text); i++ {
|
for i := 0; i < len(text); i++ {
|
||||||
ch := text[i]
|
ch := text[i]
|
||||||
if ch == '\n' {
|
if ch == '\n' {
|
||||||
width = Common.Max(width, curWidth)
|
width = common.Max(width, curWidth)
|
||||||
curWidth = 0
|
curWidth = 0
|
||||||
height += maxCharHeight + 6
|
height += maxCharHeight + 6
|
||||||
continue
|
continue
|
||||||
@ -75,7 +75,7 @@ func (v *Font) GetTextMetrics(text string) (width, height uint32) {
|
|||||||
metric := v.metrics[uint8(ch)]
|
metric := v.metrics[uint8(ch)]
|
||||||
curWidth += uint32(metric.Width)
|
curWidth += uint32(metric.Width)
|
||||||
}
|
}
|
||||||
width = Common.Max(width, curWidth)
|
width = common.Max(width, curWidth)
|
||||||
height += maxCharHeight
|
height += maxCharHeight
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -87,7 +87,7 @@ func (v *Font) Draw(x, y int, text string, color color.Color, target *ebiten.Ima
|
|||||||
|
|
||||||
maxCharHeight := uint32(0)
|
maxCharHeight := uint32(0)
|
||||||
for _, m := range v.metrics {
|
for _, m := range v.metrics {
|
||||||
maxCharHeight = Common.Max(maxCharHeight, uint32(m.Height))
|
maxCharHeight = common.Max(maxCharHeight, uint32(m.Height))
|
||||||
}
|
}
|
||||||
|
|
||||||
targetWidth, _ := target.Size()
|
targetWidth, _ := target.Size()
|
@ -1,10 +1,10 @@
|
|||||||
package UI
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image/color"
|
"image/color"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
"github.com/OpenDiablo2/OpenDiablo2/palettedefs"
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ type Label struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateLabel creates a new instance of a UI label
|
// CreateLabel creates a new instance of a UI label
|
||||||
func CreateLabel(provider Common.FileProvider, font string, palette PaletteDefs.PaletteType) *Label {
|
func CreateLabel(provider common.FileProvider, font string, palette palettedefs.PaletteType) *Label {
|
||||||
result := &Label{
|
result := &Label{
|
||||||
Alignment: LabelAlignLeft,
|
Alignment: LabelAlignLeft,
|
||||||
Color: color.White,
|
Color: color.White,
|
@ -1,10 +1,10 @@
|
|||||||
package UI
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/PaletteDefs"
|
"github.com/OpenDiablo2/OpenDiablo2/palettedefs"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/ResourcePaths"
|
"github.com/OpenDiablo2/OpenDiablo2/resourcepaths"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Sound"
|
"github.com/OpenDiablo2/OpenDiablo2/sound"
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -21,22 +21,22 @@ const (
|
|||||||
// Manager represents the UI manager
|
// Manager represents the UI manager
|
||||||
type Manager struct {
|
type Manager struct {
|
||||||
widgets []Widget
|
widgets []Widget
|
||||||
cursorSprite *Common.Sprite
|
cursorSprite *common.Sprite
|
||||||
cursorButtons CursorButton
|
cursorButtons CursorButton
|
||||||
pressedIndex int
|
pressedIndex int
|
||||||
CursorX int
|
CursorX int
|
||||||
CursorY int
|
CursorY int
|
||||||
clickSfx *Sound.SoundEffect
|
clickSfx *sound.SoundEffect
|
||||||
waitForLeftMouseUp bool
|
waitForLeftMouseUp bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateManager creates a new instance of a UI manager
|
// CreateManager creates a new instance of a UI manager
|
||||||
func CreateManager(fileProvider Common.FileProvider, soundManager Sound.Manager) *Manager {
|
func CreateManager(fileProvider common.FileProvider, soundManager sound.Manager) *Manager {
|
||||||
result := &Manager{
|
result := &Manager{
|
||||||
pressedIndex: -1,
|
pressedIndex: -1,
|
||||||
widgets: make([]Widget, 0),
|
widgets: make([]Widget, 0),
|
||||||
cursorSprite: fileProvider.LoadSprite(ResourcePaths.CursorDefault, PaletteDefs.Units),
|
cursorSprite: fileProvider.LoadSprite(resourcepaths.CursorDefault, palettedefs.Units),
|
||||||
clickSfx: soundManager.LoadSoundEffect(ResourcePaths.SFXButtonClick),
|
clickSfx: soundManager.LoadSoundEffect(resourcepaths.SFXButtonClick),
|
||||||
waitForLeftMouseUp: false,
|
waitForLeftMouseUp: false,
|
||||||
}
|
}
|
||||||
return result
|
return result
|
@ -1,12 +1,12 @@
|
|||||||
package UI
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Widget defines an object that is a UI widget
|
// Widget defines an object that is a UI widget
|
||||||
type Widget interface {
|
type Widget interface {
|
||||||
Common.Drawable
|
common.Drawable
|
||||||
GetEnabled() bool
|
GetEnabled() bool
|
||||||
SetEnabled(enabled bool)
|
SetEnabled(enabled bool)
|
||||||
SetPressed(pressed bool)
|
SetPressed(pressed bool)
|
@ -1,9 +1,9 @@
|
|||||||
package Video
|
package video
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/Common"
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BinkVideoMode uint32
|
type BinkVideoMode uint32
|
||||||
@ -41,7 +41,7 @@ type BinkDecoder struct {
|
|||||||
VideoHeight uint32
|
VideoHeight uint32
|
||||||
FPS uint32
|
FPS uint32
|
||||||
FrameTimeMS uint32
|
FrameTimeMS uint32
|
||||||
streamReader *Common.StreamReader
|
streamReader *common.StreamReader
|
||||||
VideoMode BinkVideoMode
|
VideoMode BinkVideoMode
|
||||||
HasAlphaPlane bool
|
HasAlphaPlane bool
|
||||||
Grayscale bool
|
Grayscale bool
|
||||||
@ -52,7 +52,7 @@ type BinkDecoder struct {
|
|||||||
|
|
||||||
func CreateBinkDecoder(source []byte) *BinkDecoder {
|
func CreateBinkDecoder(source []byte) *BinkDecoder {
|
||||||
result := &BinkDecoder{
|
result := &BinkDecoder{
|
||||||
streamReader: Common.CreateStreamReader(source),
|
streamReader: common.CreateStreamReader(source),
|
||||||
}
|
}
|
||||||
result.loadHeaderInformation()
|
result.loadHeaderInformation()
|
||||||
return result
|
return result
|
Loading…
Reference in New Issue
Block a user