diff --git a/d2common/d2util/stringutils.go b/d2common/d2util/stringutils.go index c9c859cb..24f268bd 100644 --- a/d2common/d2util/stringutils.go +++ b/d2common/d2util/stringutils.go @@ -135,6 +135,11 @@ func SplitIntoLinesWithMaxWidth(fullSentence string, maxChars int) []string { return lines } +// SplitIntoLinesWithMaxWidthOneLine does the same as SplitIntoLinesWithMaxWidth but return string with newline char +func SplitIntoLinesWithMaxWidthOneLine(s string, l int) string { + return strings.Join(SplitIntoLinesWithMaxWidth(s, l), "\n") +} + func splitCjkIntoChunks(str string, chars int) []string { chunks := make([]string, chars/len(str)) i, count := 0, 0 diff --git a/d2core/d2asset/asset_manager.go b/d2core/d2asset/asset_manager.go index d710b115..5a5acdec 100644 --- a/d2core/d2asset/asset_manager.go +++ b/d2core/d2asset/asset_manager.go @@ -291,6 +291,31 @@ func (am *AssetManager) TranslateString(key string) string { return key } +// TranslateHeroClass translates her class given to game locale +func (am *AssetManager) TranslateHeroClass(h d2enum.Hero) string { + switch h { + case d2enum.HeroBarbarian: + return am.TranslateString("Barbarian") + case d2enum.HeroNecromancer: + return am.TranslateString("Necromancer") + case d2enum.HeroPaladin: + return am.TranslateString("Paladin") + case d2enum.HeroAssassin: + return am.TranslateString("Assassin") + case d2enum.HeroSorceress: + return am.TranslateString("Sorceress") + case d2enum.HeroAmazon: + return am.TranslateString("Amazon") + case d2enum.HeroDruid: + return am.TranslateString("Druid") + default: + am.Error("Unknown Hero Class") + } + + // should not be reached + return "---" +} + // LoadPaletteTransform loads a palette transform file func (am *AssetManager) LoadPaletteTransform(path string) (*d2pl2.PL2, error) { if pl2, found := am.transforms.Retrieve(path); found { diff --git a/d2game/d2gamescreen/character_select.go b/d2game/d2gamescreen/character_select.go index bbbc8015..6bd355f8 100644 --- a/d2game/d2gamescreen/character_select.go +++ b/d2game/d2gamescreen/character_select.go @@ -292,17 +292,17 @@ func rgbaColor(rgba uint32) color.RGBA { } func (v *CharacterSelect) createButtons(loading d2screen.LoadingState) { - v.newCharButton = v.uiManager.NewButton(d2ui.ButtonTypeTall, "CREATE NEW\nCHARACTER") - + v.newCharButton = v.uiManager.NewButton(d2ui.ButtonTypeTall, d2util.SplitIntoLinesWithMaxWidthOneLine(v.asset.TranslateString("#831"), 13)) v.newCharButton.SetPosition(newCharBtnX, newCharBtnY) v.newCharButton.OnActivated(func() { v.onNewCharButtonClicked() }) - v.convertCharButton = v.uiManager.NewButton(d2ui.ButtonTypeTall, "CONVERT TO\nEXPANSION") - + v.convertCharButton = v.uiManager.NewButton(d2ui.ButtonTypeTall, + d2util.SplitIntoLinesWithMaxWidthOneLine(v.asset.TranslateString("#825"), 13)) v.convertCharButton.SetPosition(convertCharBtnX, convertCharBtnY) v.convertCharButton.SetEnabled(false) - v.deleteCharButton = v.uiManager.NewButton(d2ui.ButtonTypeTall, "DELETE\nCHARACTER") + v.deleteCharButton = v.uiManager.NewButton(d2ui.ButtonTypeTall, + d2util.SplitIntoLinesWithMaxWidthOneLine(v.asset.TranslateString("#832"), 13)) v.deleteCharButton.OnActivated(func() { v.onDeleteCharButtonClicked() }) v.deleteCharButton.SetPosition(deleteCharBtnX, deleteCharBtnY) @@ -333,7 +333,7 @@ func (v *CharacterSelect) onScrollUpdate() { } func (v *CharacterSelect) updateCharacterBoxes() { - expText := "EXPANSION CHARACTER" + expText := v.asset.TranslateString("#803") for i := 0; i < 8; i++ { idx := i + (v.charScrollbar.GetCurrentOffset() * 2) @@ -348,7 +348,8 @@ func (v *CharacterSelect) updateCharacterBoxes() { } heroName := v.gameStates[idx].HeroName - heroInfo := "Level " + strconv.FormatInt(int64(v.gameStates[idx].Stats.Level), 10) + " " + v.gameStates[idx].HeroType.String() + heroInfo := v.asset.TranslateString("level") + " " + strconv.FormatInt(int64(v.gameStates[idx].Stats.Level), 10) + + " " + v.asset.TranslateHeroClass(v.gameStates[idx].HeroType) v.characterNameLabel[i].SetText(d2ui.ColorTokenize(heroName, d2ui.ColorTokenGold)) v.characterStatsLabel[i].SetText(d2ui.ColorTokenize(heroInfo, d2ui.ColorTokenWhite)) diff --git a/d2game/d2gamescreen/cinematics.go b/d2game/d2gamescreen/cinematics.go index 2a7a07b7..718c0efb 100644 --- a/d2game/d2gamescreen/cinematics.go +++ b/d2game/d2gamescreen/cinematics.go @@ -102,44 +102,35 @@ func (v *Cinematics) OnLoad(_ d2screen.LoadingState) { } func (v *Cinematics) createButtons() { - /*CINEMATICS NAMES: - Act 1: The Sister's Lament - Act 2: Dessert Journay - Act 3: Mephisto's Jungle - Act 4: Enter Hell - Act 5: Search For Ball - end Credit Classic: Terror's End - end Credit Expansion: Destruction's End - */ - v.cinematicsExitBtn = v.uiManager.NewButton(d2ui.ButtonTypeMedium, "CANCEL") + v.cinematicsExitBtn = v.uiManager.NewButton(d2ui.ButtonTypeMedium, v.asset.TranslateString("cancel")) v.cinematicsExitBtn.SetPosition(cinematicsExitBtnX, cinematicsExitBtnY) v.cinematicsExitBtn.OnActivated(func() { v.onCinematicsExitBtnClicked() }) - v.a1Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, "THE SISTER'S LAMENT") + v.a1Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.asset.TranslateString("act1X")) v.a1Btn.SetPosition(a1BtnX, a1BtnY) v.a1Btn.OnActivated(func() { v.onA1BtnClicked() }) - v.a2Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, "DESSERT JOURNAY") + v.a2Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.asset.TranslateString("act2X")) v.a2Btn.SetPosition(a2BtnX, a2BtnY) v.a2Btn.OnActivated(func() { v.onA2BtnClicked() }) - v.a3Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, "MEPHISTO'S JUNGLE") + v.a3Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.asset.TranslateString("act3X")) v.a3Btn.SetPosition(a3BtnX, a3BtnY) v.a3Btn.OnActivated(func() { v.onA3BtnClicked() }) - v.a4Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, "ENTER HELL") + v.a4Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.asset.TranslateString("act4X")) v.a4Btn.SetPosition(a4BtnX, a4BtnY) v.a4Btn.OnActivated(func() { v.onA4BtnClicked() }) - v.endCreditClassBtn = v.uiManager.NewButton(d2ui.ButtonTypeWide, "TERROR'S END") + v.endCreditClassBtn = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.asset.TranslateString("strepilogueX")) v.endCreditClassBtn.SetPosition(endCreditClassBtnX, endCreditClassBtnY) v.endCreditClassBtn.OnActivated(func() { v.onEndCreditClassBtnClicked() }) - v.a5Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, "SEARCH FOR BAAL") + v.a5Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.asset.TranslateString("act5X")) v.a5Btn.SetPosition(a5BtnX, a5BtnY) v.a5Btn.OnActivated(func() { v.onA5BtnClicked() }) - v.endCreditExpBtn = v.uiManager.NewButton(d2ui.ButtonTypeWide, "DESTRUCTION'S END") + v.endCreditExpBtn = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.asset.TranslateString("strlastcinematic")) v.endCreditExpBtn.SetPosition(endCreditExpBtnX, endCreditExpBtnY) v.endCreditExpBtn.OnActivated(func() { v.onEndCreditExpBtnClicked() }) } diff --git a/d2game/d2player/hero_stats_panel.go b/d2game/d2player/hero_stats_panel.go index 922d345d..d1814a65 100644 --- a/d2game/d2player/hero_stats_panel.go +++ b/d2game/d2player/hero_stats_panel.go @@ -2,6 +2,7 @@ package d2player import ( "strconv" + "strings" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface" @@ -27,14 +28,14 @@ const ( labelLevelX, labelLevelY = 110, 100 labelHeroNameX, labelHeroNameY = 165, 72 - labelHeroClassX, labelHeroClassY = 330, 72 + labelHeroClassX, labelHeroClassY = 330, 74 labelExperienceX, labelExperienceY = 200, 100 labelNextLevelX, labelNextLevelY = 330, 100 labelStrengthX, labelStrengthY = 100, 150 labelDexterityX, labelDexterityY = 100, 213 - labelVitalityX, labelVitalityY = 100, 300 + labelVitalityX, labelVitalityY = 95, 300 labelEnergyX, labelEnergyY = 100, 360 labelDefenseX, labelDefenseY = 280, 260 @@ -42,14 +43,14 @@ const ( labelLifeX, labelLifeY = 280, 322 labelManaX, labelManaY = 280, 360 - labelResFireLine1X, labelResFireLine1Y = 310, 395 - labelResFireLine2X, labelResFireLine2Y = 310, 402 - labelResColdLine1X, labelResColdLine1Y = 310, 445 + labelResFireLine1X, labelResFireLine1Y = 310, 396 + labelResFireLine2X, labelResFireLine2Y = 310, 403 + labelResColdLine1X, labelResColdLine1Y = 310, 444 labelResColdLine2X, labelResColdLine2Y = 310, 452 labelResLightLine1X, labelResLightLine1Y = 310, 420 - labelResLightLine2X, labelResLightLine2Y = 310, 427 + labelResLightLine2X, labelResLightLine2Y = 310, 428 labelResPoisLine1X, labelResPoisLine1Y = 310, 468 - labelResPoisLine2X, labelResPoisLine2Y = 310, 477 + labelResPoisLine2X, labelResPoisLine2Y = 310, 476 ) const ( @@ -241,6 +242,10 @@ func (s *HeroStatsPanel) renderStaticPanelFrames(target d2interface.Surface) { func (s *HeroStatsPanel) renderStaticLabels(target d2interface.Surface) { var label *d2ui.Label + fr := strings.Split(s.asset.TranslateString("strchrfir"), "\n") + lr := strings.Split(s.asset.TranslateString("strchrlit"), "\n") + cr := strings.Split(s.asset.TranslateString("strchrcol"), "\n") + pr := strings.Split(s.asset.TranslateString("strchrpos"), "\n") // all static labels are not stored since we use them only once to generate the image cache var staticLabelConfigs = []struct { x, y int @@ -249,32 +254,32 @@ func (s *HeroStatsPanel) renderStaticLabels(target d2interface.Surface) { centerAlign bool }{ {labelHeroNameX, labelHeroNameY, s.heroName, d2resource.Font16, true}, - {labelHeroClassX, labelHeroClassY, s.heroClass.String(), d2resource.Font16, true}, + {labelHeroClassX, labelHeroClassY, s.asset.TranslateHeroClass(s.heroClass), d2resource.Font16, true}, - {labelLevelX, labelLevelY, "Level", d2resource.Font6, true}, - {labelExperienceX, labelExperienceY, "Experience", d2resource.Font6, true}, - {labelNextLevelX, labelNextLevelY, "Next Level", d2resource.Font6, true}, - {labelStrengthX, labelStrengthY, "Strength", d2resource.Font6, false}, - {labelDexterityX, labelDexterityY, "Dexterity", d2resource.Font6, false}, - {labelVitalityX, labelVitalityY, "Vitality", d2resource.Font6, false}, - {labelEnergyX, labelEnergyY, "Energy", d2resource.Font6, false}, - {labelDefenseX, labelDefenseY, "Defense", d2resource.Font6, false}, - {labelStaminaX, labelStaminaY, "Stamina", d2resource.Font6, true}, - {labelLifeX, labelLifeY, "Life", d2resource.Font6, true}, - {labelManaX, labelManaY, "Mana", d2resource.Font6, true}, + {labelLevelX, labelLevelY, s.asset.TranslateString("strchrlvl"), d2resource.Font6, true}, + {labelExperienceX, labelExperienceY, s.asset.TranslateString("strchrexp"), d2resource.Font6, true}, + {labelNextLevelX, labelNextLevelY, s.asset.TranslateString("strchrnxtlvl"), d2resource.Font6, true}, + {labelStrengthX, labelStrengthY, s.asset.TranslateString("strchrstr"), d2resource.Font6, false}, + {labelDexterityX, labelDexterityY, s.asset.TranslateString("strchrdex"), d2resource.Font6, false}, + {labelVitalityX, labelVitalityY, s.asset.TranslateString("strchrvit"), d2resource.Font6, false}, + {labelEnergyX, labelEnergyY, s.asset.TranslateString("strchreng"), d2resource.Font6, false}, + {labelDefenseX, labelDefenseY, s.asset.TranslateString("strchrdef"), d2resource.Font6, false}, + {labelStaminaX, labelStaminaY, s.asset.TranslateString("strchrstm"), d2resource.Font6, true}, + {labelLifeX, labelLifeY, s.asset.TranslateString("strchrlif"), d2resource.Font6, true}, + {labelManaX, labelManaY, s.asset.TranslateString("strchrman"), d2resource.Font6, true}, // can't use "Fire\nResistance" because line spacing is too big and breaks the layout - {labelResFireLine1X, labelResFireLine1Y, "Fire", d2resource.Font6, true}, - {labelResFireLine2X, labelResFireLine2Y, "Resistance", d2resource.Font6, true}, + {labelResFireLine1X, labelResFireLine1Y, fr[0], d2resource.Font6, true}, + {labelResFireLine2X, labelResFireLine2Y, fr[len(fr)-1], d2resource.Font6, true}, - {labelResColdLine1X, labelResColdLine1Y, "Cold", d2resource.Font6, true}, - {labelResColdLine2X, labelResColdLine2Y, "Resistance", d2resource.Font6, true}, + {labelResColdLine1X, labelResColdLine1Y, cr[0], d2resource.Font6, true}, + {labelResColdLine2X, labelResColdLine2Y, cr[len(cr)-1], d2resource.Font6, true}, - {labelResLightLine1X, labelResLightLine1Y, "Lightning", d2resource.Font6, true}, - {labelResLightLine2X, labelResLightLine2Y, "Resistance", d2resource.Font6, true}, + {labelResLightLine1X, labelResLightLine1Y, lr[0], d2resource.Font6, true}, + {labelResLightLine2X, labelResLightLine2Y, lr[len(lr)-1], d2resource.Font6, true}, - {labelResPoisLine1X, labelResPoisLine1Y, "Poison", d2resource.Font6, true}, - {labelResPoisLine2X, labelResPoisLine2Y, "Resistance", d2resource.Font6, true}, + {labelResPoisLine1X, labelResPoisLine1Y, pr[0], d2resource.Font6, true}, + {labelResPoisLine2X, labelResPoisLine2Y, pr[len(pr)-1], d2resource.Font6, true}, } for _, cfg := range staticLabelConfigs {