diff --git a/Scenes/SelectHeroClass.go b/Scenes/SelectHeroClass.go deleted file mode 100644 index 9a0a8b93..00000000 --- a/Scenes/SelectHeroClass.go +++ /dev/null @@ -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("") - } -} diff --git a/Common/AnimatedEntity.go b/common/AnimatedEntity.go similarity index 85% rename from Common/AnimatedEntity.go rename to common/AnimatedEntity.go index 31e51769..b9d9f09b 100644 --- a/Common/AnimatedEntity.go +++ b/common/AnimatedEntity.go @@ -1,19 +1,24 @@ -package Common +package common import ( "fmt" "strings" "time" - "github.com/OpenDiablo2/OpenDiablo2/PaletteDefs" + "github.com/OpenDiablo2/OpenDiablo2/palettedefs" "github.com/hajimehoshi/ebiten" ) +// AnimatedEntity represents an entity on the map that can be animated 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 cof *Cof - palette PaletteDefs.PaletteType + palette palettedefs.PaletteType base string token string tr string @@ -24,13 +29,12 @@ type AnimatedEntity struct { animationSpeed int direction int currentFrame int - LocationX float64 - LocationY float64 frames []*ebiten.Image 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{ base: base, token: token, @@ -40,8 +44,10 @@ func CreateAnimatedEntity(base, token, tr string, palette PaletteDefs.PaletteTyp 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} +// SetMode changes the graphical mode of this animated entity 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) v.dcc = LoadDCC(dccPath, provider) @@ -53,6 +59,7 @@ func (v *AnimatedEntity) SetMode(animationMode, weaponClass string, direction in v.cacheFrames() } +// Render draws this animated entity onto the target func (v *AnimatedEntity) Render(target *ebiten.Image, offsetX, offsetY int) { for v.lastFrameTime.Add(time.Millisecond * time.Duration(v.animationSpeed)).Before(time.Now()) { v.lastFrameTime = v.lastFrameTime.Add(time.Millisecond * time.Duration(v.animationSpeed)) diff --git a/Common/AnimationData.go b/common/AnimationData.go similarity index 59% rename from Common/AnimationData.go rename to common/AnimationData.go index 554751a0..5427bd29 100644 --- a/Common/AnimationData.go +++ b/common/AnimationData.go @@ -1,24 +1,31 @@ -package Common +package common import ( "log" "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 { - COFName string + // COFName is the name of the COF file used for this animation + COFName string + // FramesPerDirection specifies how many frames are in each direction FramesPerDirection int - AnimationSpeed int - Flags []byte + // AnimationSpeed represents a value of X where the rate is a ration of (x/255) at 25FPS + AnimationSpeed int + // Flags are used in keyframe triggers + Flags []byte } +// AnimationData represents all of the animation data records, mapped by the COF index var AnimationData map[string][]*AnimationDataRecord +// LoadAnimationData loads the animation data table into the global AnimationData dictionary func LoadAnimationData(fileProvider FileProvider) { AnimationData = make(map[string][]*AnimationDataRecord) - rawData := fileProvider.LoadFile(ResourcePaths.AnimationData) + rawData := fileProvider.LoadFile(resourcepaths.AnimationData) streamReader := CreateStreamReader(rawData) for !streamReader.Eof() { dataCount := int(streamReader.GetInt32()) diff --git a/Common/BitMuncher.go b/common/BitMuncher.go similarity index 99% rename from Common/BitMuncher.go rename to common/BitMuncher.go index f7f0c172..665745e5 100644 --- a/Common/BitMuncher.go +++ b/common/BitMuncher.go @@ -1,4 +1,4 @@ -package Common +package common type BitMuncher struct { data []byte diff --git a/Common/BitStream.go b/common/BitStream.go similarity index 98% rename from Common/BitStream.go rename to common/BitStream.go index ced82554..6a9f48cd 100644 --- a/Common/BitStream.go +++ b/common/BitStream.go @@ -1,4 +1,4 @@ -package Common +package common import "log" diff --git a/Common/BitStream_test.go b/common/BitStream_test.go similarity index 97% rename from Common/BitStream_test.go rename to common/BitStream_test.go index a371e06a..bd2076a0 100644 --- a/Common/BitStream_test.go +++ b/common/BitStream_test.go @@ -1,4 +1,4 @@ -package Common +package common import ( "testing" diff --git a/Common/BuildInfo.go b/common/BuildInfo.go similarity index 93% rename from Common/BuildInfo.go rename to common/BuildInfo.go index c75d0760..7df25fcd 100644 --- a/Common/BuildInfo.go +++ b/common/BuildInfo.go @@ -1,4 +1,4 @@ -package Common +package common type BuildInfoRecord struct { Branch string diff --git a/Common/Cof.go b/common/Cof.go similarity index 99% rename from Common/Cof.go rename to common/Cof.go index 1c131782..1fd374f1 100644 --- a/Common/Cof.go +++ b/common/Cof.go @@ -1,4 +1,4 @@ -package Common +package common import "strings" diff --git a/Common/ColorConvert.go b/common/ColorConvert.go similarity index 98% rename from Common/ColorConvert.go rename to common/ColorConvert.go index db232e63..d9a5bb39 100644 --- a/Common/ColorConvert.go +++ b/common/ColorConvert.go @@ -1,4 +1,4 @@ -package Common +package common import ( "image/color" diff --git a/Common/Dcc.go b/common/Dcc.go similarity index 99% rename from Common/Dcc.go rename to common/Dcc.go index 7cd001be..ccc087b8 100644 --- a/Common/Dcc.go +++ b/common/Dcc.go @@ -1,4 +1,4 @@ -package Common +package common import ( "log" diff --git a/Common/Drawable.go b/common/Drawable.go similarity index 94% rename from Common/Drawable.go rename to common/Drawable.go index 4559ee2f..1b6f1fb1 100644 --- a/Common/Drawable.go +++ b/common/Drawable.go @@ -1,4 +1,4 @@ -package Common +package common import "github.com/hajimehoshi/ebiten" diff --git a/Common/FileProvider.go b/common/FileProvider.go similarity index 52% rename from Common/FileProvider.go rename to common/FileProvider.go index d1b05da0..8e2f267f 100644 --- a/Common/FileProvider.go +++ b/common/FileProvider.go @@ -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 type FileProvider interface { LoadFile(fileName string) []byte - LoadSprite(fileName string, palette PaletteDefs.PaletteType) *Sprite + LoadSprite(fileName string, palette palettedefs.PaletteType) *Sprite } diff --git a/Common/GameState.go b/common/GameState.go similarity index 94% rename from Common/GameState.go rename to common/GameState.go index 385a43ef..9828294a 100644 --- a/Common/GameState.go +++ b/common/GameState.go @@ -1,4 +1,4 @@ -package Common +package common import ( "log" diff --git a/Common/Hero.go b/common/Hero.go similarity index 93% rename from Common/Hero.go rename to common/Hero.go index d812bf6c..a8280376 100644 --- a/Common/Hero.go +++ b/common/Hero.go @@ -1,4 +1,4 @@ -package Common +package common type Hero int diff --git a/Common/LevelPresets.go b/common/LevelPresets.go similarity index 94% rename from Common/LevelPresets.go rename to common/LevelPresets.go index 58eeb3f4..1914d77c 100644 --- a/Common/LevelPresets.go +++ b/common/LevelPresets.go @@ -1,10 +1,10 @@ -package Common +package common import ( "log" "strings" - "github.com/OpenDiablo2/OpenDiablo2/ResourcePaths" + "github.com/OpenDiablo2/OpenDiablo2/resourcepaths" ) type LevelPresetRecord struct { @@ -73,7 +73,7 @@ var LevelPresets map[int]*LevelPresetRecord func LoadLevelPresets(fileProvider FileProvider) { 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 { if len(line) == 0 { continue diff --git a/Common/LevelTypes.go b/common/LevelTypes.go similarity index 88% rename from Common/LevelTypes.go rename to common/LevelTypes.go index 7f441080..e2204070 100644 --- a/Common/LevelTypes.go +++ b/common/LevelTypes.go @@ -1,10 +1,10 @@ -package Common +package common import ( "log" "strings" - "github.com/OpenDiablo2/OpenDiablo2/ResourcePaths" + "github.com/OpenDiablo2/OpenDiablo2/resourcepaths" ) type LevelTypeRecord struct { @@ -19,7 +19,7 @@ type LevelTypeRecord struct { var LevelTypes []LevelTypeRecord 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)) for i, line := range data { idx := -1 diff --git a/Common/LevelWarp.go b/common/LevelWarp.go similarity index 90% rename from Common/LevelWarp.go rename to common/LevelWarp.go index 0a7232bc..c00f8a51 100644 --- a/Common/LevelWarp.go +++ b/common/LevelWarp.go @@ -1,9 +1,9 @@ -package Common +package common import ( "log" - "github.com/OpenDiablo2/OpenDiablo2/ResourcePaths" + "github.com/OpenDiablo2/OpenDiablo2/resourcepaths" ) type LevelWarpRecord struct { @@ -25,7 +25,7 @@ var LevelWarps map[int]*LevelWarpRecord func LoadLevelWarps(fileProvider FileProvider) { LevelWarps = make(map[int]*LevelWarpRecord) - levelWarpData := fileProvider.LoadFile(ResourcePaths.LevelWarp) + levelWarpData := fileProvider.LoadFile(resourcepaths.LevelWarp) streamReader := CreateStreamReader(levelWarpData) numRecords := int(streamReader.GetInt32()) for i := 0; i < numRecords; i++ { diff --git a/Common/Math.go b/common/Math.go similarity index 98% rename from Common/Math.go rename to common/Math.go index 052fb304..39f4c2e0 100644 --- a/Common/Math.go +++ b/common/Math.go @@ -1,4 +1,4 @@ -package Common +package common // Min returns the lower of two values func Min(a, b uint32) uint32 { diff --git a/Common/Missiles.go b/common/Missiles.go similarity index 99% rename from Common/Missiles.go rename to common/Missiles.go index 24db3e1b..fe38f301 100644 --- a/Common/Missiles.go +++ b/common/Missiles.go @@ -1,10 +1,10 @@ -package Common +package common import ( "log" "strings" - "github.com/OpenDiablo2/OpenDiablo2/ResourcePaths" + "github.com/OpenDiablo2/OpenDiablo2/resourcepaths" ) type MissileCalcParam struct { @@ -293,7 +293,7 @@ var Missiles map[int]*MissileRecord func LoadMissiles(fileProvider FileProvider) { 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 { if len(line) == 0 { continue diff --git a/Common/MpqFileRecord.go b/common/MpqFileRecord.go similarity index 87% rename from Common/MpqFileRecord.go rename to common/MpqFileRecord.go index 7db92205..4fe633c9 100644 --- a/Common/MpqFileRecord.go +++ b/common/MpqFileRecord.go @@ -1,4 +1,4 @@ -package Common +package common type MpqFileRecord struct { MpqFile string diff --git a/Common/ObjectLookup.go b/common/ObjectLookup.go similarity index 99% rename from Common/ObjectLookup.go rename to common/ObjectLookup.go index 471fd73a..a7df3325 100644 --- a/Common/ObjectLookup.go +++ b/common/ObjectLookup.go @@ -1,4 +1,4 @@ -package Common +package common import ( "log" diff --git a/Common/ObjectTypes.go b/common/ObjectTypes.go similarity index 84% rename from Common/ObjectTypes.go rename to common/ObjectTypes.go index c4494314..53686c32 100644 --- a/Common/ObjectTypes.go +++ b/common/ObjectTypes.go @@ -1,10 +1,10 @@ -package Common +package common import ( "log" "strings" - "github.com/OpenDiablo2/OpenDiablo2/ResourcePaths" + "github.com/OpenDiablo2/OpenDiablo2/resourcepaths" ) type ObjectTypeRecord struct { @@ -15,7 +15,7 @@ type ObjectTypeRecord struct { var ObjectTypes []ObjectTypeRecord func LoadObjectTypes(fileProvider FileProvider) { - objectTypeData := fileProvider.LoadFile(ResourcePaths.ObjectType) + objectTypeData := fileProvider.LoadFile(resourcepaths.ObjectType) streamReader := CreateStreamReader(objectTypeData) count := streamReader.GetInt32() ObjectTypes = make([]ObjectTypeRecord, count) diff --git a/Common/Objects.go b/common/Objects.go similarity index 98% rename from Common/Objects.go rename to common/Objects.go index 7eb1c25d..d0f5b8dc 100644 --- a/Common/Objects.go +++ b/common/Objects.go @@ -1,10 +1,10 @@ -package Common +package common import ( "log" "strings" - "github.com/OpenDiablo2/OpenDiablo2/ResourcePaths" + "github.com/OpenDiablo2/OpenDiablo2/resourcepaths" ) // 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) { 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 { if len(line) == 0 { continue diff --git a/Common/Palette.go b/common/Palette.go similarity index 74% rename from Common/Palette.go rename to common/Palette.go index c7eda1ae..330b9fee 100644 --- a/Common/Palette.go +++ b/common/Palette.go @@ -1,9 +1,9 @@ -package Common +package common import ( "log" - "github.com/OpenDiablo2/OpenDiablo2/PaletteDefs" + "github.com/OpenDiablo2/OpenDiablo2/palettedefs" ) // PaletteRGB represents a color in a palette @@ -13,14 +13,14 @@ type PaletteRGB struct { // PaletteType represents a palette type PaletteRec struct { - Name PaletteDefs.PaletteType + Name palettedefs.PaletteType Colors [256]PaletteRGB } -var Palettes map[PaletteDefs.PaletteType]PaletteRec +var Palettes map[palettedefs.PaletteType]PaletteRec // CreatePalette creates a palette -func CreatePalette(name PaletteDefs.PaletteType, data []byte) PaletteRec { +func CreatePalette(name palettedefs.PaletteType, data []byte) PaletteRec { result := PaletteRec{Name: name} 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) { - Palettes = make(map[PaletteDefs.PaletteType]PaletteRec) + Palettes = make(map[palettedefs.PaletteType]PaletteRec) for _, pal := range []string{ "act1", "act2", "act3", "act4", "act5", "endgame", "endgame2", "fechar", "loading", "menu0", "menu1", "menu2", "menu3", "menu4", "sky", "static", "trademark", "units", } { filePath := `data\global\palette\` + pal + `\pal.dat` - paletteName := PaletteDefs.PaletteType(pal) + paletteName := palettedefs.PaletteType(pal) palette := CreatePalette(paletteName, fileProvider.LoadFile(filePath)) Palettes[paletteName] = palette } diff --git a/Common/Rectangle.go b/common/Rectangle.go similarity index 95% rename from Common/Rectangle.go rename to common/Rectangle.go index 54a4dcae..a6de206d 100644 --- a/Common/Rectangle.go +++ b/common/Rectangle.go @@ -1,4 +1,4 @@ -package Common +package common type Rectangle struct { Left int diff --git a/Common/Sounds.go b/common/Sounds.go similarity index 93% rename from Common/Sounds.go rename to common/Sounds.go index 9c3fd391..238c2f33 100644 --- a/Common/Sounds.go +++ b/common/Sounds.go @@ -1,10 +1,10 @@ -package Common +package common import ( "log" "strings" - "github.com/OpenDiablo2/OpenDiablo2/ResourcePaths" + "github.com/OpenDiablo2/OpenDiablo2/resourcepaths" ) // SoundEntry represents a sound entry @@ -73,7 +73,7 @@ var Sounds map[string]SoundEntry func LoadSounds(fileProvider FileProvider) { 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 { if len(line) == 0 { continue diff --git a/Common/Sprite.go b/common/Sprite.go similarity index 99% rename from Common/Sprite.go rename to common/Sprite.go index a630bfd3..dcccca18 100644 --- a/Common/Sprite.go +++ b/common/Sprite.go @@ -1,4 +1,4 @@ -package Common +package common import ( "encoding/binary" diff --git a/Common/StreamReader.go b/common/StreamReader.go similarity index 99% rename from Common/StreamReader.go rename to common/StreamReader.go index bb4b9ddf..f7804f79 100644 --- a/Common/StreamReader.go +++ b/common/StreamReader.go @@ -1,4 +1,4 @@ -package Common +package common import ( "bytes" diff --git a/Common/StreamReader_test.go b/common/StreamReader_test.go similarity index 99% rename from Common/StreamReader_test.go rename to common/StreamReader_test.go index 3a9d03ce..ac0cc682 100644 --- a/Common/StreamReader_test.go +++ b/common/StreamReader_test.go @@ -1,4 +1,4 @@ -package Common +package common import ( "testing" diff --git a/Common/StreamWriter.go b/common/StreamWriter.go similarity index 98% rename from Common/StreamWriter.go rename to common/StreamWriter.go index 2c871a97..4645e843 100644 --- a/Common/StreamWriter.go +++ b/common/StreamWriter.go @@ -1,4 +1,4 @@ -package Common +package common // StreamWriter allows you to create a byte array by streaming in writes of various sizes type StreamWriter struct { diff --git a/Common/StreamWriter_test.go b/common/StreamWriter_test.go similarity index 98% rename from Common/StreamWriter_test.go rename to common/StreamWriter_test.go index e160372d..bb127897 100644 --- a/Common/StreamWriter_test.go +++ b/common/StreamWriter_test.go @@ -1,4 +1,4 @@ -package Common +package common import ( "testing" diff --git a/Common/StringUtils.go b/common/StringUtils.go similarity index 99% rename from Common/StringUtils.go rename to common/StringUtils.go index 3b37457b..1e6908ed 100644 --- a/Common/StringUtils.go +++ b/common/StringUtils.go @@ -1,4 +1,4 @@ -package Common +package common import ( "bytes" diff --git a/Common/TextDictionary.go b/common/TextDictionary.go similarity index 90% rename from Common/TextDictionary.go rename to common/TextDictionary.go index 41954510..e9e45e25 100644 --- a/Common/TextDictionary.go +++ b/common/TextDictionary.go @@ -1,10 +1,10 @@ -package Common +package common import ( "log" "strconv" - "github.com/OpenDiablo2/OpenDiablo2/ResourcePaths" + "github.com/OpenDiablo2/OpenDiablo2/resourcepaths" ) type textDictionaryHashEntry struct { @@ -29,9 +29,9 @@ func TranslateString(key string) string { func LoadTextDictionary(fileProvider FileProvider) { lookupTable = make(map[string]string) - loadDictionary(fileProvider, ResourcePaths.PatchStringTable) - loadDictionary(fileProvider, ResourcePaths.ExpansionStringTable) - loadDictionary(fileProvider, ResourcePaths.StringTable) + loadDictionary(fileProvider, resourcepaths.PatchStringTable) + loadDictionary(fileProvider, resourcepaths.ExpansionStringTable) + loadDictionary(fileProvider, resourcepaths.StringTable) log.Printf("Loaded %d entries from the string table", len(lookupTable)) } diff --git a/Common/Weapons.go b/common/Weapons.go similarity index 98% rename from Common/Weapons.go rename to common/Weapons.go index 6d383116..ee03bf18 100644 --- a/Common/Weapons.go +++ b/common/Weapons.go @@ -1,10 +1,10 @@ -package Common +package common import ( "log" "strings" - "github.com/OpenDiablo2/OpenDiablo2/ResourcePaths" + "github.com/OpenDiablo2/OpenDiablo2/resourcepaths" ) type WeaponRecord struct { @@ -268,7 +268,7 @@ var Weapons map[string]*WeaponRecord func LoadWeapons(fileProvider FileProvider) { 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 { if len(line) == 0 { continue diff --git a/Compression/Huffman.go b/compression/Huffman.go similarity index 98% rename from Compression/Huffman.go rename to compression/Huffman.go index ec229453..0a86be91 100644 --- a/Compression/Huffman.go +++ b/compression/Huffman.go @@ -27,12 +27,12 @@ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -package Compression +package compression import ( "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) @@ -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 for node.Child0 != nil { @@ -344,8 +344,8 @@ func HuffmanDecompress(data []byte) []byte { tail := buildList(sPrime[comptype]) head := buildTree(tail) - outputstream := Common.CreateStreamWriter() - bitstream := Common.CreateBitStream(data[1:]) + outputstream := common.CreateStreamWriter() + bitstream := common.CreateBitStream(data[1:]) var decoded int for true { node := decode(bitstream, head) diff --git a/Compression/Wav.go b/compression/Wav.go similarity index 95% rename from Compression/Wav.go rename to compression/Wav.go index 834f2b18..66d15b82 100644 --- a/Compression/Wav.go +++ b/compression/Wav.go @@ -1,7 +1,7 @@ -package Compression +package compression import ( - "github.com/OpenDiablo2/OpenDiablo2/Common" + "github.com/OpenDiablo2/OpenDiablo2/common" ) var sLookup = []int{ @@ -30,8 +30,8 @@ func WavDecompress(data []byte, channelCount int) []byte { Array1 := []int{0x2c, 0x2c} Array2 := make([]int, channelCount) - input := Common.CreateStreamReader(data) - output := Common.CreateStreamWriter() + input := common.CreateStreamReader(data) + output := common.CreateStreamWriter() input.GetByte() shift := input.GetByte() diff --git a/Core/Engine.go b/core/Engine.go similarity index 84% rename from Core/Engine.go rename to core/Engine.go index e9d88118..76044160 100644 --- a/Core/Engine.go +++ b/core/Engine.go @@ -1,4 +1,4 @@ -package Core +package core import ( "encoding/json" @@ -10,16 +10,16 @@ import ( "strings" "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/ResourcePaths" - "github.com/OpenDiablo2/OpenDiablo2/Scenes" - "github.com/OpenDiablo2/OpenDiablo2/UI" + "github.com/OpenDiablo2/OpenDiablo2/common" + "github.com/OpenDiablo2/OpenDiablo2/resourcepaths" + "github.com/OpenDiablo2/OpenDiablo2/scenes" + "github.com/OpenDiablo2/OpenDiablo2/ui" "github.com/hajimehoshi/ebiten" "github.com/mitchellh/go-homedir" @@ -45,13 +45,13 @@ type Engine struct { Settings *EngineConfig // Engine configuration settings from json file 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. - 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. stepLoadingSize float64 // The size for each loading step - CurrentScene Scenes.Scene // The current scene being rendered - UIManager *UI.Manager // The UI manager - SoundManager *Sound.Manager // The sound manager - nextScene Scenes.Scene // The next scene to be loaded at the end of the game loop + CurrentScene scenes.Scene // The current scene being rendered + UIManager *ui.Manager // The UI manager + SoundManager *sound.Manager // The sound manager + 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 } @@ -62,27 +62,27 @@ func CreateEngine() *Engine { nextScene: nil, } result.loadConfigurationFile() - ResourcePaths.LanguageCode = result.Settings.Language + resourcepaths.LanguageCode = result.Settings.Language result.mapMpqFiles() - Common.LoadPalettes(result.Files, result) - Common.LoadTextDictionary(result) - Common.LoadLevelTypes(result) - Common.LoadLevelPresets(result) - Common.LoadLevelWarps(result) - Common.LoadObjectTypes(result) - Common.LoadObjects(result) - Common.LoadWeapons(result) - Common.LoadMissiles(result) - Common.LoadSounds(result) - Common.LoadObjectLookups() - Common.LoadAnimationData(result) - result.SoundManager = Sound.CreateManager(result) + common.LoadPalettes(result.Files, result) + common.LoadTextDictionary(result) + common.LoadLevelTypes(result) + common.LoadLevelPresets(result) + common.LoadLevelWarps(result) + common.LoadObjectTypes(result) + common.LoadObjects(result) + common.LoadWeapons(result) + common.LoadMissiles(result) + common.LoadSounds(result) + common.LoadObjectLookups() + common.LoadAnimationData(result) + result.SoundManager = sound.CreateManager(result) result.SoundManager.SetVolumes(result.Settings.BgmVolume, result.Settings.SfxVolume) - result.UIManager = UI.CreateManager(result, *result.SoundManager) - result.LoadingSprite = result.LoadSprite(ResourcePaths.LoadingScreen, PaletteDefs.Loading) + result.UIManager = ui.CreateManager(result, *result.SoundManager) + result.LoadingSprite = result.LoadSprite(resourcepaths.LoadingScreen, palettedefs.Loading) loadingSpriteSizeX, loadingSpriteSizeY := result.LoadingSprite.GetSize() 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)) return result } @@ -238,7 +238,7 @@ func (v *Engine) LoadFile(fileName string) []byte { var mutex sync.Mutex 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.ReplaceAll(fileName, `/`, "\\") 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 cachedMpqFile, cacheExists := v.Files[fileName] if cacheExists { - mpq, _ := MPQ.Load(cachedMpqFile) + mpq, _ := mpq.Load(cachedMpqFile) result, _ := mpq.ReadFile(fileName) return result } 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) { continue } @@ -272,9 +272,9 @@ func (v *Engine) IsLoading() bool { } // 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) - sprite := Common.CreateSprite(data, Common.Palettes[palette]) + sprite := common.CreateSprite(data, common.Palettes[palette]) return sprite } @@ -328,7 +328,7 @@ func (v *Engine) Update() { // Draw draws the game func (v *Engine) Draw(screen *ebiten.Image) { 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) } else { 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 -func (v *Engine) SetNextScene(nextScene Scenes.Scene) { +func (v *Engine) SetNextScene(nextScene scenes.Scene) { v.nextScene = nextScene } diff --git a/go.sum b/go.sum index aac266d6..cc7c71c5 100644 --- a/go.sum +++ b/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-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U= 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-20190127143845-a42111704963 h1:2HSxAhImj2OpXsNjXSqfnv1xtqeCpDjwPB3o1DnQqKM= 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/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-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-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-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-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= 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= diff --git a/main.go b/main.go index 8dc952ad..4bab7e4e 100644 --- a/main.go +++ b/main.go @@ -6,31 +6,34 @@ import ( "github.com/hajimehoshi/ebiten/ebitenutil" - "github.com/OpenDiablo2/OpenDiablo2/Common" + "github.com/OpenDiablo2/OpenDiablo2/common" - "github.com/OpenDiablo2/OpenDiablo2/Core" - "github.com/OpenDiablo2/OpenDiablo2/MPQ" + "github.com/OpenDiablo2/OpenDiablo2/core" + "github.com/OpenDiablo2/OpenDiablo2/mpq" "github.com/hajimehoshi/ebiten" ) +// GitBranch is set by the CI build process to the name of the branch var GitBranch string + +// GitCommit is set by the CI build process to the commit hash var GitCommit string -var d2Engine *Core.Engine +var d2Engine *core.Engine func main() { if len(GitBranch) == 0 { GitBranch = "Local Build" GitCommit = "" } - Common.SetBuildInfo(GitBranch, GitCommit) + common.SetBuildInfo(GitBranch, GitCommit) log.SetFlags(log.Ldate | log.LUTC | log.Lmicroseconds | log.Llongfile) log.Println("OpenDiablo2 - Open source Diablo 2 engine") _, iconImage, err := ebitenutil.NewImageFromFile("d2logo.png", ebiten.FilterLinear) if err == nil { ebiten.SetWindowIcon([]image.Image{iconImage}) } - MPQ.InitializeCryptoBuffer() - d2Engine = Core.CreateEngine() + mpq.InitializeCryptoBuffer() + d2Engine = core.CreateEngine() ebiten.SetCursorVisible(false) ebiten.SetFullscreen(d2Engine.Settings.FullScreen) ebiten.SetRunnableInBackground(d2Engine.Settings.RunInBackground) diff --git a/Map/DS1.go b/map/DS1.go similarity index 96% rename from Map/DS1.go rename to map/DS1.go index a74925ec..8c38fb77 100644 --- a/Map/DS1.go +++ b/map/DS1.go @@ -1,7 +1,7 @@ -package Map +package _map import ( - "github.com/OpenDiablo2/OpenDiablo2/Common" + "github.com/OpenDiablo2/OpenDiablo2/common" ) var dirLookup = []int32{ @@ -79,7 +79,7 @@ type Object struct { Y int32 Flags int32 Paths []Path - Lookup *Common.ObjectLookupRecord + Lookup *common.ObjectLookupRecord } type DS1 struct { @@ -99,7 +99,7 @@ type DS1 struct { SubstitutionGroups []SubstitutionGroup } -func LoadDS1(path string, fileProvider Common.FileProvider) *DS1 { +func LoadDS1(path string, fileProvider common.FileProvider) *DS1 { ds1 := &DS1{ NumberOfFloors: 1, NumberOfWalls: 1, @@ -107,12 +107,12 @@ func LoadDS1(path string, fileProvider Common.FileProvider) *DS1 { NumberOfSubstitutionLayers: 0, } fileData := fileProvider.LoadFile(path) - br := Common.CreateStreamReader(fileData) + br := common.CreateStreamReader(fileData) ds1.Version = br.GetInt32() ds1.Width = br.GetInt32() + 1 ds1.Height = br.GetInt32() + 1 if ds1.Version >= 8 { - ds1.Act = Common.MinInt32(5, br.GetInt32()+1) + ds1.Act = common.MinInt32(5, br.GetInt32()+1) } if ds1.Version >= 10 { ds1.SubstitutionType = br.GetInt32() @@ -250,7 +250,7 @@ func LoadDS1(path string, fileProvider Common.FileProvider) *DS1 { newObject.X = br.GetInt32() newObject.Y = 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) } } diff --git a/Map/DT1.go b/map/DT1.go similarity index 94% rename from Map/DT1.go rename to map/DT1.go index 9cb88326..9cf7caca 100644 --- a/Map/DT1.go +++ b/map/DT1.go @@ -1,9 +1,9 @@ -package Map +package _map import ( "log" - "github.com/OpenDiablo2/OpenDiablo2/Common" + "github.com/OpenDiablo2/OpenDiablo2/common" ) // https://d2mods.info/forum/viewtopic.php?t=65163 @@ -47,10 +47,10 @@ const ( BlockFormatIsometric BlockDataFormat = 1 ) -func LoadDT1(path string, fileProvider Common.FileProvider) *DT1 { +func LoadDT1(path string, fileProvider common.FileProvider) *DT1 { result := &DT1{} fileData := fileProvider.LoadFile(path) - br := Common.CreateStreamReader(fileData) + br := common.CreateStreamReader(fileData) ver1 := br.GetInt32() ver2 := br.GetInt32() if ver1 != 7 || ver2 != 6 { diff --git a/Map/Engine.go b/map/Engine.go similarity index 84% rename from Map/Engine.go rename to map/Engine.go index 8b121f7b..ac075062 100644 --- a/Map/Engine.go +++ b/map/Engine.go @@ -1,30 +1,30 @@ -package Map +package _map import ( "math" "math/rand" "strings" - "github.com/OpenDiablo2/OpenDiablo2/Common" - "github.com/OpenDiablo2/OpenDiablo2/Sound" + "github.com/OpenDiablo2/OpenDiablo2/common" + "github.com/OpenDiablo2/OpenDiablo2/sound" "github.com/hajimehoshi/ebiten" ) type EngineRegion struct { - Rect Common.Rectangle + Rect common.Rectangle Region *Region } type Engine struct { - soundManager *Sound.Manager - gameState *Common.GameState - fileProvider Common.FileProvider + soundManager *sound.Manager + gameState *common.GameState + fileProvider common.FileProvider regions []EngineRegion OffsetX 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{ gameState: gameState, soundManager: soundManager, @@ -38,7 +38,7 @@ func (v *Engine) GenerateMap(regionType RegionIdType, levelPreset int) { randomSource := rand.NewSource(v.gameState.Seed) region := LoadRegion(randomSource, regionType, levelPreset, v.fileProvider) 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, }) } @@ -48,19 +48,19 @@ func (v *Engine) GenerateAct1Overworld() { randomSource := rand.NewSource(v.gameState.Seed) region := LoadRegion(randomSource, RegionAct1Town, 1, v.fileProvider) 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, }) if strings.Contains(region.RegionPath, "E1") { region2 := LoadRegion(randomSource, RegionAct1Town, 2, v.fileProvider) 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, }) } else if strings.Contains(region.RegionPath, "S1") { region2 := LoadRegion(randomSource, RegionAct1Town, 3, v.fileProvider) 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, }) } @@ -90,7 +90,7 @@ func (v *Engine) RenderRegion(region EngineRegion, target *ebiten.Image) { offX := -((y + region.Rect.Top) * 80) + (region.Rect.Left * 80) offY := ((y + region.Rect.Top) * 40) + (region.Rect.Left * 40) 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 { v.RenderTile(region.Region, offX, offY, x, y, target) } diff --git a/Map/Orientation.go b/map/Orientation.go similarity index 99% rename from Map/Orientation.go rename to map/Orientation.go index 20d56b75..bdbffd3d 100644 --- a/Map/Orientation.go +++ b/map/Orientation.go @@ -1,4 +1,4 @@ -package Map +package _map type Orientation int32 diff --git a/Map/Region.go b/map/Region.go similarity index 89% rename from Map/Region.go rename to map/Region.go index 1cefc63f..78a361b6 100644 --- a/Map/Region.go +++ b/map/Region.go @@ -1,4 +1,4 @@ -package Map +package _map import ( "image/color" @@ -8,11 +8,11 @@ import ( "strconv" "sync" - "github.com/OpenDiablo2/OpenDiablo2/PaletteDefs" + "github.com/OpenDiablo2/OpenDiablo2/palettedefs" "github.com/hajimehoshi/ebiten" - "github.com/OpenDiablo2/OpenDiablo2/Common" + "github.com/OpenDiablo2/OpenDiablo2/common" ) type TileCacheRecord struct { @@ -23,17 +23,17 @@ type TileCacheRecord struct { type Region struct { RegionPath string - LevelType Common.LevelTypeRecord - levelPreset *Common.LevelPresetRecord + LevelType common.LevelTypeRecord + levelPreset *common.LevelPresetRecord TileWidth int32 TileHeight int32 Tiles []Tile DS1 *DS1 - Palette Common.PaletteRec + Palette common.PaletteRec FloorCache map[uint32]*TileCacheRecord ShadowCache map[uint32]*TileCacheRecord WallCache map[uint32]*TileCacheRecord - AnimationEntities []*Common.AnimatedEntity + AnimationEntities []*common.AnimatedEntity } type RegionLayerType int @@ -84,16 +84,16 @@ const ( 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{ - LevelType: Common.LevelTypes[levelType], - levelPreset: Common.LevelPresets[levelPreset], + LevelType: common.LevelTypes[levelType], + levelPreset: common.LevelPresets[levelPreset], Tiles: make([]Tile, 0), FloorCache: make(map[uint32]*TileCacheRecord), ShadowCache: 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 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 var wg sync.WaitGroup wg.Add(len(result.DS1.Objects)) - result.AnimationEntities = make([]*Common.AnimatedEntity, 0) + result.AnimationEntities = make([]*common.AnimatedEntity, 0) for _, object := range result.DS1.Objects { go func(object Object) { defer wg.Done() switch object.Lookup.Type { - case Common.ObjectTypeCharacter: - case Common.ObjectTypeItem: + case common.ObjectTypeCharacter: + case common.ObjectTypeItem: if object.Lookup.Base == "" || object.Lookup.Token == "" || object.Lookup.TR == "" { 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.LocationX = math.Floor(float64(object.X) / 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.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) } @@ -296,10 +296,10 @@ func (v *Region) generateFloorCache(tile FloorShadowRecord) *TileCacheRecord { } tileYMinimum := int32(0) for _, block := range tileData.Blocks { - tileYMinimum = Common.MinInt32(tileYMinimum, int32(block.Y)) + tileYMinimum = common.MinInt32(tileYMinimum, int32(block.Y)) } - tileYOffset := Common.AbsInt32(tileYMinimum) - tileHeight := Common.AbsInt32(tileData.Height) + tileYOffset := common.AbsInt32(tileYMinimum) + tileHeight := common.AbsInt32(tileData.Height) image, _ := ebiten.NewImage(int(tileData.Width), int(tileHeight), ebiten.FilterNearest) pixels := make([]byte, 4*tileData.Width*tileHeight) v.decodeTileGfxData(tileData.Blocks, pixels, tileYOffset, tileData.Width) @@ -315,8 +315,8 @@ func (v *Region) generateShadowCache(tile FloorShadowRecord) *TileCacheRecord { tileMinY := int32(0) tileMaxY := int32(0) for _, block := range tileData.Blocks { - tileMinY = Common.MinInt32(tileMinY, int32(block.Y)) - tileMaxY = Common.MaxInt32(tileMaxY, int32(block.Y+32)) + tileMinY = common.MinInt32(tileMinY, int32(block.Y)) + tileMaxY = common.MaxInt32(tileMaxY, int32(block.Y+32)) } tileYOffset := -tileMinY tileHeight := int(tileMaxY - tileMinY) @@ -344,10 +344,10 @@ func (v *Region) generateWallCache(tile WallRecord) *TileCacheRecord { target = newTileData } for _, block := range target.Blocks { - tileMinY = Common.MinInt32(tileMinY, int32(block.Y)) - tileMaxY = Common.MaxInt32(tileMaxY, int32(block.Y+32)) + tileMinY = common.MinInt32(tileMinY, int32(block.Y)) + 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 //tileHeight := int(tileMaxY - tileMinY) image, _ := ebiten.NewImage(160, int(realHeight), ebiten.FilterNearest) diff --git a/MPQ/CryptoBuff.go b/mpq/CryptoBuff.go similarity index 97% rename from MPQ/CryptoBuff.go rename to mpq/CryptoBuff.go index 3339ec2f..9edd7b2e 100644 --- a/MPQ/CryptoBuff.go +++ b/mpq/CryptoBuff.go @@ -1,4 +1,4 @@ -package MPQ +package mpq // CryptoBuffer contains the crypto bytes for filename hashing var CryptoBuffer [0x500]uint32 diff --git a/MPQ/MPQ.go b/mpq/MPQ.go similarity index 96% rename from MPQ/MPQ.go rename to mpq/MPQ.go index c3ef21dd..60554102 100644 --- a/MPQ/MPQ.go +++ b/mpq/MPQ.go @@ -1,4 +1,4 @@ -package MPQ +package mpq import ( "encoding/binary" @@ -8,7 +8,7 @@ import ( "path" "strings" - "github.com/OpenDiablo2/OpenDiablo2/ResourcePaths" + "github.com/OpenDiablo2/OpenDiablo2/resourcepaths" ) // MPQ represents an MPQ archive @@ -225,7 +225,7 @@ func (v MPQ) getFileHashEntry(fileName string) (HashTableEntry, error) { // GetFileBlockData gets a block table entry 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) if err != nil { 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 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) if err != nil { 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 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) if err != nil { return "", err diff --git a/MPQ/MPQStream.go b/mpq/MPQStream.go similarity index 92% rename from MPQ/MPQStream.go rename to mpq/MPQStream.go index e44ceb95..6b2ae7fc 100644 --- a/MPQ/MPQStream.go +++ b/mpq/MPQStream.go @@ -1,4 +1,4 @@ -package MPQ +package mpq import ( "bytes" @@ -9,8 +9,8 @@ import ( "strings" "github.com/JoshVarga/blast" - "github.com/OpenDiablo2/OpenDiablo2/Common" - "github.com/OpenDiablo2/OpenDiablo2/Compression" + "github.com/OpenDiablo2/OpenDiablo2/common" + "github.com/OpenDiablo2/OpenDiablo2/compression" ) // 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() } - 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]) v.CurrentPosition += 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 { v.bufferData() 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 { return 0 } @@ -113,7 +113,7 @@ func (v *Stream) bufferData() { if requiredBlock == v.CurrentBlockIndex { 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.CurrentBlockIndex = requiredBlock } @@ -178,7 +178,7 @@ func decompressMulti(data []byte, expectedLength uint32) []byte { case 0x10: // BZip2 panic("bzip2 decompression not supported") case 0x80: // IMA ADPCM Stereo - return Compression.WavDecompress(data[1:], 2) + return compression.WavDecompress(data[1:], 2) //return MpqWavCompression.Decompress(sinput, 2); //panic("ima adpcm sterio decompression not supported") case 0x40: // IMA ADPCM Mono @@ -194,8 +194,8 @@ func decompressMulti(data []byte, expectedLength uint32) []byte { // TODO: sparse then bzip2 panic("sparse decompression + bzip2 decompression not supported") case 0x41: - sinput := Compression.HuffmanDecompress(data[1:]) - sinput = Compression.WavDecompress(sinput, 1) + sinput := compression.HuffmanDecompress(data[1:]) + sinput = compression.WavDecompress(sinput, 1) tmp := make([]byte, len(sinput)) copy(tmp, sinput) return tmp @@ -204,8 +204,8 @@ func decompressMulti(data []byte, expectedLength uint32) []byte { //return MpqWavCompression.Decompress(new MemoryStream(result), 1); panic("pk + mpqwav decompression not supported") case 0x81: - sinput := Compression.HuffmanDecompress(data[1:]) - sinput = Compression.WavDecompress(sinput, 2) + sinput := compression.HuffmanDecompress(data[1:]) + sinput = compression.WavDecompress(sinput, 2) tmp := make([]byte, len(sinput)) copy(tmp, sinput) return tmp diff --git a/PaletteDefs/PaletteDefs.go b/palettedefs/PaletteDefs.go similarity index 97% rename from PaletteDefs/PaletteDefs.go rename to palettedefs/PaletteDefs.go index 8d9ad7ca..b3d7d1a7 100644 --- a/PaletteDefs/PaletteDefs.go +++ b/palettedefs/PaletteDefs.go @@ -1,4 +1,4 @@ -package PaletteDefs +package palettedefs // PaletteType represents a named palette type PaletteType string diff --git a/ResourcePaths/ResourcePaths.go b/resourcepaths/ResourcePaths.go similarity index 99% rename from ResourcePaths/ResourcePaths.go rename to resourcepaths/ResourcePaths.go index fb9b28d5..55e8884a 100644 --- a/ResourcePaths/ResourcePaths.go +++ b/resourcepaths/ResourcePaths.go @@ -1,4 +1,4 @@ -package ResourcePaths +package resourcepaths var LanguageCode string diff --git a/Scenes/BlizzardIntro.go b/scenes/BlizzardIntro.go similarity index 66% rename from Scenes/BlizzardIntro.go rename to scenes/BlizzardIntro.go index e8fad4f4..5152cbd9 100644 --- a/Scenes/BlizzardIntro.go +++ b/scenes/BlizzardIntro.go @@ -1,18 +1,18 @@ -package Scenes +package scenes import ( - "github.com/OpenDiablo2/OpenDiablo2/Common" - "github.com/OpenDiablo2/OpenDiablo2/Video" + "github.com/OpenDiablo2/OpenDiablo2/common" + "github.com/OpenDiablo2/OpenDiablo2/video" "github.com/hajimehoshi/ebiten" ) type BlizzardIntro struct { - fileProvider Common.FileProvider + fileProvider common.FileProvider 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{ fileProvider: fileProvider, sceneProvider: sceneProvider, @@ -25,7 +25,7 @@ func (v *BlizzardIntro) Load() []func() { return []func(){ func() { videoBytes := v.fileProvider.LoadFile("/data/local/video/BlizNorth640x480.bik") - v.videoDecoder = Video.CreateBinkDecoder(videoBytes) + v.videoDecoder = video.CreateBinkDecoder(videoBytes) }, } } diff --git a/Scenes/CharacterSelect.go b/scenes/CharacterSelect.go similarity index 54% rename from Scenes/CharacterSelect.go rename to scenes/CharacterSelect.go index 5969c922..5750d65a 100644 --- a/Scenes/CharacterSelect.go +++ b/scenes/CharacterSelect.go @@ -1,32 +1,32 @@ -package Scenes +package scenes import ( - "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/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 CharacterSelect struct { - uiManager *UI.Manager - soundManager *Sound.Manager - fileProvider Common.FileProvider + uiManager *ui.Manager + soundManager *sound.Manager + fileProvider common.FileProvider sceneProvider SceneProvider - background *Common.Sprite - newCharButton *UI.Button - convertCharButton *UI.Button - deleteCharButton *UI.Button - exitButton *UI.Button - okButton *UI.Button + background *common.Sprite + newCharButton *ui.Button + convertCharButton *ui.Button + deleteCharButton *ui.Button + exitButton *ui.Button + okButton *ui.Button } func CreateCharacterSelect( - fileProvider Common.FileProvider, + fileProvider common.FileProvider, sceneProvider SceneProvider, - uiManager *UI.Manager, - soundManager *Sound.Manager, + uiManager *ui.Manager, + soundManager *sound.Manager, ) *CharacterSelect { result := &CharacterSelect{ uiManager: uiManager, @@ -38,38 +38,38 @@ func CreateCharacterSelect( } func (v *CharacterSelect) Load() []func() { - v.soundManager.PlayBGM(ResourcePaths.BGMTitle) + v.soundManager.PlayBGM(resourcepaths.BGMTitle) return []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) }, 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.OnActivated(func() { v.onNewCharButtonClicked() }) v.uiManager.AddWidget(v.newCharButton) }, 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.SetEnabled(false) v.uiManager.AddWidget(v.convertCharButton) }, 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.SetEnabled(false) v.uiManager.AddWidget(v.deleteCharButton) }, 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.OnActivated(func() { v.onExitButtonClicked() }) v.uiManager.AddWidget(v.exitButton) }, 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.SetEnabled(false) v.uiManager.AddWidget(v.okButton) diff --git a/Scenes/Credits.go b/scenes/Credits.go similarity index 80% rename from Scenes/Credits.go rename to scenes/Credits.go index 29a3d528..009fcb1b 100644 --- a/Scenes/Credits.go +++ b/scenes/Credits.go @@ -1,31 +1,31 @@ -package Scenes +package scenes import ( "image/color" "strings" - "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/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 labelItem struct { - Label *UI.Label + Label *ui.Label IsHeading bool Available bool } // Credits represents the credits scene type Credits struct { - uiManager *UI.Manager - soundManager *Sound.Manager - fileProvider Common.FileProvider + uiManager *ui.Manager + soundManager *sound.Manager + fileProvider common.FileProvider sceneProvider SceneProvider - creditsBackground *Common.Sprite - exitButton *UI.Button + creditsBackground *common.Sprite + exitButton *ui.Button creditsText []string labels []*labelItem cycleTime float64 @@ -34,7 +34,7 @@ type Credits struct { } // 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{ fileProvider: fileProvider, uiManager: uiManager, @@ -52,17 +52,17 @@ func CreateCredits(fileProvider Common.FileProvider, sceneProvider SceneProvider func (v *Credits) Load() []func() { return []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) }, 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.OnActivated(func() { v.onExitButtonClicked() }) v.uiManager.AddWidget(v.exitButton) }, 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") for i := range v.creditsText { 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 { if label.Available { label.Available = false @@ -190,7 +190,7 @@ func (v *Credits) getNewFontLabel(isHeading bool) *UI.Label { newLabelItem := &labelItem{ Available: false, IsHeading: isHeading, - Label: UI.CreateLabel(v.fileProvider, ResourcePaths.FontFormal10, PaletteDefs.Sky), + Label: ui.CreateLabel(v.fileProvider, resourcepaths.FontFormal10, palettedefs.Sky), } if isHeading { diff --git a/Scenes/MainMenu.go b/scenes/MainMenu.go similarity index 63% rename from Scenes/MainMenu.go rename to scenes/MainMenu.go index 8e627a79..dcd6dcab 100644 --- a/Scenes/MainMenu.go +++ b/scenes/MainMenu.go @@ -1,4 +1,4 @@ -package Scenes +package scenes import ( "fmt" @@ -8,45 +8,45 @@ import ( "os/exec" "runtime" - "github.com/OpenDiablo2/OpenDiablo2/Common" - "github.com/OpenDiablo2/OpenDiablo2/PaletteDefs" - "github.com/OpenDiablo2/OpenDiablo2/Sound" - "github.com/OpenDiablo2/OpenDiablo2/UI" + "github.com/OpenDiablo2/OpenDiablo2/common" + "github.com/OpenDiablo2/OpenDiablo2/palettedefs" + "github.com/OpenDiablo2/OpenDiablo2/sound" + "github.com/OpenDiablo2/OpenDiablo2/ui" - "github.com/OpenDiablo2/OpenDiablo2/ResourcePaths" + "github.com/OpenDiablo2/OpenDiablo2/resourcepaths" "github.com/hajimehoshi/ebiten" ) // MainMenu represents the main menu type MainMenu struct { - uiManager *UI.Manager - soundManager *Sound.Manager - fileProvider Common.FileProvider + uiManager *ui.Manager + soundManager *sound.Manager + fileProvider common.FileProvider sceneProvider SceneProvider - trademarkBackground *Common.Sprite - background *Common.Sprite - diabloLogoLeft *Common.Sprite - diabloLogoRight *Common.Sprite - diabloLogoLeftBack *Common.Sprite - diabloLogoRightBack *Common.Sprite - singlePlayerButton *UI.Button - githubButton *UI.Button - exitDiabloButton *UI.Button - creditsButton *UI.Button - cinematicsButton *UI.Button - mapTestButton *UI.Button - copyrightLabel *UI.Label - copyrightLabel2 *UI.Label - openDiabloLabel *UI.Label - versionLabel *UI.Label - commitLabel *UI.Label + trademarkBackground *common.Sprite + background *common.Sprite + diabloLogoLeft *common.Sprite + diabloLogoRight *common.Sprite + diabloLogoLeftBack *common.Sprite + diabloLogoRightBack *common.Sprite + singlePlayerButton *ui.Button + githubButton *ui.Button + exitDiabloButton *ui.Button + creditsButton *ui.Button + cinematicsButton *ui.Button + mapTestButton *ui.Button + copyrightLabel *ui.Label + copyrightLabel2 *ui.Label + openDiabloLabel *ui.Label + versionLabel *ui.Label + commitLabel *ui.Label ShowTrademarkScreen bool leftButtonHeld bool } // 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{ fileProvider: fileProvider, uiManager: uiManager, @@ -60,107 +60,107 @@ func CreateMainMenu(fileProvider Common.FileProvider, sceneProvider SceneProvide // Load is called to load the resources for the main menu func (v *MainMenu) Load() []func() { - v.soundManager.PlayBGM(ResourcePaths.BGMTitle) + v.soundManager.PlayBGM(resourcepaths.BGMTitle) return []func(){ func() { - v.versionLabel = UI.CreateLabel(v.fileProvider, ResourcePaths.FontFormal12, PaletteDefs.Static) - v.versionLabel.Alignment = UI.LabelAlignRight - v.versionLabel.SetText("OpenDiablo2 - " + Common.BuildInfo.Branch) + v.versionLabel = ui.CreateLabel(v.fileProvider, resourcepaths.FontFormal12, palettedefs.Static) + v.versionLabel.Alignment = ui.LabelAlignRight + v.versionLabel.SetText("OpenDiablo2 - " + common.BuildInfo.Branch) v.versionLabel.Color = color.RGBA{255, 255, 255, 255} v.versionLabel.MoveTo(795, -10) }, func() { - v.commitLabel = UI.CreateLabel(v.fileProvider, ResourcePaths.FontFormal10, PaletteDefs.Static) - v.commitLabel.Alignment = UI.LabelAlignLeft - v.commitLabel.SetText(Common.BuildInfo.Commit) + v.commitLabel = ui.CreateLabel(v.fileProvider, resourcepaths.FontFormal10, palettedefs.Static) + v.commitLabel.Alignment = ui.LabelAlignLeft + v.commitLabel.SetText(common.BuildInfo.Commit) v.commitLabel.Color = color.RGBA{255, 255, 255, 255} v.commitLabel.MoveTo(2, 2) }, func() { - v.copyrightLabel = UI.CreateLabel(v.fileProvider, ResourcePaths.FontFormal12, PaletteDefs.Static) - v.copyrightLabel.Alignment = UI.LabelAlignCenter + v.copyrightLabel = ui.CreateLabel(v.fileProvider, resourcepaths.FontFormal12, palettedefs.Static) + v.copyrightLabel.Alignment = ui.LabelAlignCenter v.copyrightLabel.SetText("Diablo 2 is © Copyright 2000-2016 Blizzard Entertainment") v.copyrightLabel.Color = color.RGBA{188, 168, 140, 255} v.copyrightLabel.MoveTo(400, 500) }, func() { - v.copyrightLabel2 = UI.CreateLabel(v.fileProvider, ResourcePaths.FontFormal12, PaletteDefs.Static) - v.copyrightLabel2.Alignment = UI.LabelAlignCenter - v.copyrightLabel2.SetText(Common.TranslateString("#1614")) + v.copyrightLabel2 = ui.CreateLabel(v.fileProvider, resourcepaths.FontFormal12, palettedefs.Static) + v.copyrightLabel2.Alignment = ui.LabelAlignCenter + v.copyrightLabel2.SetText(common.TranslateString("#1614")) v.copyrightLabel2.Color = color.RGBA{188, 168, 140, 255} v.copyrightLabel2.MoveTo(400, 525) }, func() { - v.openDiabloLabel = UI.CreateLabel(v.fileProvider, ResourcePaths.FontFormal10, PaletteDefs.Static) - v.openDiabloLabel.Alignment = UI.LabelAlignCenter + v.openDiabloLabel = ui.CreateLabel(v.fileProvider, resourcepaths.FontFormal10, palettedefs.Static) + v.openDiabloLabel.Alignment = ui.LabelAlignCenter 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.MoveTo(400, 580) }, func() { - v.background = v.fileProvider.LoadSprite(ResourcePaths.GameSelectScreen, PaletteDefs.Sky) + v.background = v.fileProvider.LoadSprite(resourcepaths.GameSelectScreen, palettedefs.Sky) v.background.MoveTo(0, 0) }, func() { - v.trademarkBackground = v.fileProvider.LoadSprite(ResourcePaths.TrademarkScreen, PaletteDefs.Sky) + v.trademarkBackground = v.fileProvider.LoadSprite(resourcepaths.TrademarkScreen, palettedefs.Sky) v.trademarkBackground.MoveTo(0, 0) }, 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.Animate = true v.diabloLogoLeft.MoveTo(400, 120) }, 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.Animate = true v.diabloLogoRight.MoveTo(400, 120) }, func() { - v.diabloLogoLeftBack = v.fileProvider.LoadSprite(ResourcePaths.Diablo2LogoBlackLeft, PaletteDefs.Units) + v.diabloLogoLeftBack = v.fileProvider.LoadSprite(resourcepaths.Diablo2LogoBlackLeft, palettedefs.Units) v.diabloLogoLeftBack.MoveTo(400, 120) }, func() { - v.diabloLogoRightBack = v.fileProvider.LoadSprite(ResourcePaths.Diablo2LogoBlackRight, PaletteDefs.Units) + v.diabloLogoRightBack = v.fileProvider.LoadSprite(resourcepaths.Diablo2LogoBlackRight, palettedefs.Units) v.diabloLogoRightBack.MoveTo(400, 120) }, 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.SetVisible(!v.ShowTrademarkScreen) v.exitDiabloButton.OnActivated(func() { v.onExitButtonClicked() }) v.uiManager.AddWidget(v.exitDiabloButton) }, 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.SetVisible(!v.ShowTrademarkScreen) v.creditsButton.OnActivated(func() { v.onCreditsButtonClicked() }) v.uiManager.AddWidget(v.creditsButton) }, 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.SetVisible(!v.ShowTrademarkScreen) v.uiManager.AddWidget(v.cinematicsButton) }, 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.SetVisible(!v.ShowTrademarkScreen) v.singlePlayerButton.OnActivated(func() { v.onSinglePlayerClicked() }) v.uiManager.AddWidget(v.singlePlayerButton) }, 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.SetVisible(!v.ShowTrademarkScreen) v.githubButton.OnActivated(func() { v.onGithubButtonClicked() }) v.uiManager.AddWidget(v.githubButton) }, 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.SetVisible(!v.ShowTrademarkScreen) 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 func (v *MainMenu) Update(tickTime float64) { if v.ShowTrademarkScreen { - if v.uiManager.CursorButtonPressed(UI.CursorButtonLeft) { + if v.uiManager.CursorButtonPressed(ui.CursorButtonLeft) { if v.leftButtonHeld { return } diff --git a/Scenes/MapEngineTest.go b/scenes/MapEngineTest.go similarity index 80% rename from Scenes/MapEngineTest.go rename to scenes/MapEngineTest.go index e2511273..5c851f05 100644 --- a/Scenes/MapEngineTest.go +++ b/scenes/MapEngineTest.go @@ -1,38 +1,38 @@ -package Scenes +package scenes import ( "fmt" "math" - "github.com/OpenDiablo2/OpenDiablo2/Common" - "github.com/OpenDiablo2/OpenDiablo2/Map" - "github.com/OpenDiablo2/OpenDiablo2/Sound" - "github.com/OpenDiablo2/OpenDiablo2/UI" + "github.com/OpenDiablo2/OpenDiablo2/common" + _map "github.com/OpenDiablo2/OpenDiablo2/map" + "github.com/OpenDiablo2/OpenDiablo2/sound" + "github.com/OpenDiablo2/OpenDiablo2/ui" "github.com/hajimehoshi/ebiten" "github.com/hajimehoshi/ebiten/ebitenutil" ) type MapEngineTest struct { - uiManager *UI.Manager - soundManager *Sound.Manager - fileProvider Common.FileProvider + uiManager *ui.Manager + soundManager *sound.Manager + fileProvider common.FileProvider sceneProvider SceneProvider - gameState *Common.GameState - mapEngine *Map.Engine + gameState *common.GameState + mapEngine *_map.Engine } func CreateMapEngineTest( - fileProvider Common.FileProvider, + fileProvider common.FileProvider, sceneProvider SceneProvider, - uiManager *UI.Manager, - soundManager *Sound.Manager) *MapEngineTest { + uiManager *ui.Manager, + soundManager *sound.Manager) *MapEngineTest { result := &MapEngineTest{ fileProvider: fileProvider, uiManager: uiManager, soundManager: soundManager, sceneProvider: sceneProvider, } - result.gameState = Common.CreateGameState() + result.gameState = common.CreateGameState() return result } @@ -42,7 +42,7 @@ func (v *MapEngineTest) Load() []func() { v.soundManager.PlayBGM("") return []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.GenerateMap(Map.RegionAct1Tristram, 300) @@ -70,7 +70,7 @@ func (v *MapEngineTest) Render(screen *ebiten.Image) { v.mapEngine.Render(screen) actualX := float64(v.uiManager.CursorX) - v.mapEngine.OffsetX actualY := float64(v.uiManager.CursorY) - v.mapEngine.OffsetY - tileX, tileY := Common.ScreenToIso(actualX, actualY) + tileX, tileY := common.ScreenToIso(actualX, actualY) subtileX := int(math.Ceil(math.Mod((tileX*10), 10))) / 2 subtileY := int(math.Ceil(math.Mod((tileY*10), 10))) / 2 curRegion := v.mapEngine.GetRegionAt(int(tileX), int(tileY)) diff --git a/Scenes/Scene.go b/scenes/Scene.go similarity index 93% rename from Scenes/Scene.go rename to scenes/Scene.go index 4968911b..9b72ec73 100644 --- a/Scenes/Scene.go +++ b/scenes/Scene.go @@ -1,4 +1,4 @@ -package Scenes +package scenes import ( "github.com/hajimehoshi/ebiten" diff --git a/Scenes/SceneProvider.go b/scenes/SceneProvider.go similarity index 88% rename from Scenes/SceneProvider.go rename to scenes/SceneProvider.go index 19e12e1e..8db8c464 100644 --- a/Scenes/SceneProvider.go +++ b/scenes/SceneProvider.go @@ -1,4 +1,4 @@ -package Scenes +package scenes // SceneProvider provides the ability to change scenes type SceneProvider interface { diff --git a/scenes/SelectHeroClass.go b/scenes/SelectHeroClass.go new file mode 100644 index 00000000..dad92fe0 --- /dev/null +++ b/scenes/SelectHeroClass.go @@ -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("") + } +} diff --git a/Sound/AudioProvider.go b/sound/AudioProvider.go similarity index 91% rename from Sound/AudioProvider.go rename to sound/AudioProvider.go index dab9dd11..8eb2cc59 100644 --- a/Sound/AudioProvider.go +++ b/sound/AudioProvider.go @@ -1,16 +1,16 @@ -package Sound +package sound import ( "log" - "github.com/OpenDiablo2/OpenDiablo2/Common" + "github.com/OpenDiablo2/OpenDiablo2/common" "github.com/hajimehoshi/ebiten/audio" "github.com/hajimehoshi/ebiten/audio/wav" ) // Manager provides sound type Manager struct { - fileProvider Common.FileProvider + fileProvider common.FileProvider audioContext *audio.Context // The Audio context bgmAudio *audio.Player // The audio player lastBgm string @@ -19,7 +19,7 @@ type Manager struct { } // CreateManager creates a sound provider -func CreateManager(fileProvider Common.FileProvider) *Manager { +func CreateManager(fileProvider common.FileProvider) *Manager { result := &Manager{ fileProvider: fileProvider, } diff --git a/Sound/SoundEffect.go b/sound/SoundEffect.go similarity index 78% rename from Sound/SoundEffect.go rename to sound/SoundEffect.go index 59b2e325..6df1970c 100644 --- a/Sound/SoundEffect.go +++ b/sound/SoundEffect.go @@ -1,11 +1,11 @@ -package Sound +package sound import ( "log" "github.com/hajimehoshi/ebiten/audio/wav" - "github.com/OpenDiablo2/OpenDiablo2/Common" + "github.com/OpenDiablo2/OpenDiablo2/common" "github.com/hajimehoshi/ebiten/audio" ) @@ -14,11 +14,11 @@ type SoundEffect struct { 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{} var soundFile string - if _, exists := Common.Sounds[sfx]; exists { - soundEntry := Common.Sounds[sfx] + if _, exists := common.Sounds[sfx]; exists { + soundEntry := common.Sounds[sfx] soundFile = soundEntry.FileName } else { soundFile = sfx diff --git a/UI/Button.go b/ui/Button.go similarity index 90% rename from UI/Button.go rename to ui/Button.go index 8c10f587..d49cc09b 100644 --- a/UI/Button.go +++ b/ui/Button.go @@ -1,12 +1,12 @@ -package UI +package ui import ( "image" "image/color" - "github.com/OpenDiablo2/OpenDiablo2/Common" - "github.com/OpenDiablo2/OpenDiablo2/PaletteDefs" - "github.com/OpenDiablo2/OpenDiablo2/ResourcePaths" + "github.com/OpenDiablo2/OpenDiablo2/common" + "github.com/OpenDiablo2/OpenDiablo2/palettedefs" + "github.com/OpenDiablo2/OpenDiablo2/resourcepaths" "github.com/hajimehoshi/ebiten" ) @@ -43,7 +43,7 @@ type ButtonLayout struct { XSegments int //1 YSegments int // 1 ResourceName string // Font Name - PaletteName PaletteDefs.PaletteType // PaletteType + PaletteName palettedefs.PaletteType // PaletteType Toggleable bool // false BaseFrame int // 0 DisabledFrame int // -1 @@ -55,10 +55,10 @@ type ButtonLayout struct { // ButtonLayouts define the type of buttons you can have var ButtonLayouts = map[ButtonType]ButtonLayout{ - 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}, - 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}, + 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}, + 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}, /* {eButtonType.Wide, new ButtonLayout { XSegments = 2, ResourceName = ResourcePaths.WideButtonBlank, PaletteName = PaletteDefs.Units } }, {eButtonType.Narrow, new ButtonLayout { ResourceName = ResourcePaths.NarrowButtonBlank, PaletteName = PaletteDefs.Units } }, @@ -89,7 +89,7 @@ type Button struct { visible bool pressed bool toggled bool - fileProvider Common.FileProvider + fileProvider common.FileProvider normalImage *ebiten.Image pressedImage *ebiten.Image toggledImage *ebiten.Image @@ -100,7 +100,7 @@ type Button struct { } // 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{ fileProvider: fileProvider, width: 0, @@ -111,7 +111,7 @@ func CreateButton(buttonType ButtonType, fileProvider Common.FileProvider, text } buttonLayout := ButtonLayouts[buttonType] result.buttonLayout = buttonLayout - font := GetFont(buttonLayout.FontPath, PaletteDefs.Units, fileProvider) + font := GetFont(buttonLayout.FontPath, palettedefs.Units, fileProvider) buttonSprite := fileProvider.LoadSprite(buttonLayout.ResourceName, buttonLayout.PaletteName) totalButtonTypes := buttonSprite.GetTotalFrames() / (buttonLayout.XSegments * buttonLayout.YSegments) for i := 0; i < buttonLayout.XSegments; i++ { @@ -179,7 +179,7 @@ func (v *Button) Draw(target *ebiten.Image) { if !v.enabled { //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) } else if v.toggled && v.pressed { target.DrawImage(v.pressedToggledImage, opts) diff --git a/UI/Font.go b/ui/Font.go similarity index 81% rename from UI/Font.go rename to ui/Font.go index 956dde27..9fc38b28 100644 --- a/UI/Font.go +++ b/ui/Font.go @@ -1,11 +1,11 @@ -package UI +package ui import ( "image/color" "strings" - "github.com/OpenDiablo2/OpenDiablo2/Common" - "github.com/OpenDiablo2/OpenDiablo2/PaletteDefs" + "github.com/OpenDiablo2/OpenDiablo2/common" + "github.com/OpenDiablo2/OpenDiablo2/palettedefs" "github.com/hajimehoshi/ebiten" ) @@ -19,12 +19,12 @@ type FontSize struct { // Font represents a font type Font struct { - fontSprite *Common.Sprite + fontSprite *common.Sprite metrics map[uint8]FontSize } // 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)] if exists { return cacheItem @@ -35,7 +35,7 @@ func GetFont(font string, palette PaletteDefs.PaletteType, fileProvider Common.F } // 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{ metrics: make(map[uint8]FontSize), } @@ -62,12 +62,12 @@ func (v *Font) GetTextMetrics(text string) (width, height uint32) { height = uint32(0) maxCharHeight := uint32(0) 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++ { ch := text[i] if ch == '\n' { - width = Common.Max(width, curWidth) + width = common.Max(width, curWidth) curWidth = 0 height += maxCharHeight + 6 continue @@ -75,7 +75,7 @@ func (v *Font) GetTextMetrics(text string) (width, height uint32) { metric := v.metrics[uint8(ch)] curWidth += uint32(metric.Width) } - width = Common.Max(width, curWidth) + width = common.Max(width, curWidth) height += maxCharHeight return } @@ -87,7 +87,7 @@ func (v *Font) Draw(x, y int, text string, color color.Color, target *ebiten.Ima maxCharHeight := uint32(0) for _, m := range v.metrics { - maxCharHeight = Common.Max(maxCharHeight, uint32(m.Height)) + maxCharHeight = common.Max(maxCharHeight, uint32(m.Height)) } targetWidth, _ := target.Size() diff --git a/UI/Label.go b/ui/Label.go similarity index 91% rename from UI/Label.go rename to ui/Label.go index bf4e710d..3025a5a5 100644 --- a/UI/Label.go +++ b/ui/Label.go @@ -1,10 +1,10 @@ -package UI +package ui import ( "image/color" - "github.com/OpenDiablo2/OpenDiablo2/Common" - "github.com/OpenDiablo2/OpenDiablo2/PaletteDefs" + "github.com/OpenDiablo2/OpenDiablo2/common" + "github.com/OpenDiablo2/OpenDiablo2/palettedefs" "github.com/hajimehoshi/ebiten" ) @@ -34,7 +34,7 @@ type Label struct { } // 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{ Alignment: LabelAlignLeft, Color: color.White, diff --git a/UI/Manager.go b/ui/Manager.go similarity index 86% rename from UI/Manager.go rename to ui/Manager.go index 9b071362..6530b423 100644 --- a/UI/Manager.go +++ b/ui/Manager.go @@ -1,10 +1,10 @@ -package UI +package ui import ( - "github.com/OpenDiablo2/OpenDiablo2/Common" - "github.com/OpenDiablo2/OpenDiablo2/PaletteDefs" - "github.com/OpenDiablo2/OpenDiablo2/ResourcePaths" - "github.com/OpenDiablo2/OpenDiablo2/Sound" + "github.com/OpenDiablo2/OpenDiablo2/common" + "github.com/OpenDiablo2/OpenDiablo2/palettedefs" + "github.com/OpenDiablo2/OpenDiablo2/resourcepaths" + "github.com/OpenDiablo2/OpenDiablo2/sound" "github.com/hajimehoshi/ebiten" ) @@ -21,22 +21,22 @@ const ( // Manager represents the UI manager type Manager struct { widgets []Widget - cursorSprite *Common.Sprite + cursorSprite *common.Sprite cursorButtons CursorButton pressedIndex int CursorX int CursorY int - clickSfx *Sound.SoundEffect + clickSfx *sound.SoundEffect waitForLeftMouseUp bool } // 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{ pressedIndex: -1, widgets: make([]Widget, 0), - cursorSprite: fileProvider.LoadSprite(ResourcePaths.CursorDefault, PaletteDefs.Units), - clickSfx: soundManager.LoadSoundEffect(ResourcePaths.SFXButtonClick), + cursorSprite: fileProvider.LoadSprite(resourcepaths.CursorDefault, palettedefs.Units), + clickSfx: soundManager.LoadSoundEffect(resourcepaths.SFXButtonClick), waitForLeftMouseUp: false, } return result diff --git a/UI/Widget.go b/ui/Widget.go similarity index 75% rename from UI/Widget.go rename to ui/Widget.go index e3bd7e47..17f4a15d 100644 --- a/UI/Widget.go +++ b/ui/Widget.go @@ -1,12 +1,12 @@ -package UI +package ui import ( - "github.com/OpenDiablo2/OpenDiablo2/Common" + "github.com/OpenDiablo2/OpenDiablo2/common" ) // Widget defines an object that is a UI widget type Widget interface { - Common.Drawable + common.Drawable GetEnabled() bool SetEnabled(enabled bool) SetPressed(pressed bool) diff --git a/Video/BinkDecoder.go b/video/BinkDecoder.go similarity index 95% rename from Video/BinkDecoder.go rename to video/BinkDecoder.go index b533ac72..2ae912ef 100644 --- a/Video/BinkDecoder.go +++ b/video/BinkDecoder.go @@ -1,9 +1,9 @@ -package Video +package video import ( "log" - "github.com/OpenDiablo2/OpenDiablo2/Common" + "github.com/OpenDiablo2/OpenDiablo2/common" ) type BinkVideoMode uint32 @@ -41,7 +41,7 @@ type BinkDecoder struct { VideoHeight uint32 FPS uint32 FrameTimeMS uint32 - streamReader *Common.StreamReader + streamReader *common.StreamReader VideoMode BinkVideoMode HasAlphaPlane bool Grayscale bool @@ -52,7 +52,7 @@ type BinkDecoder struct { func CreateBinkDecoder(source []byte) *BinkDecoder { result := &BinkDecoder{ - streamReader: Common.CreateStreamReader(source), + streamReader: common.CreateStreamReader(source), } result.loadHeaderInformation() return result