From 122b49b1cf6b3eaa92c8e2001682a9375383b438 Mon Sep 17 00:00:00 2001 From: "M. Sz" Date: Wed, 25 Nov 2020 18:40:56 +0100 Subject: [PATCH] Adds translatable labels in most part of main menu --- d2app/app.go | 6 +- d2game/d2gamescreen/character_select.go | 9 +- d2game/d2gamescreen/cinematics.go | 7 +- d2game/d2gamescreen/main_menu.go | 100 ++++++++++++++++++++--- d2game/d2gamescreen/select_hero_class.go | 36 +++++--- 5 files changed, 125 insertions(+), 33 deletions(-) diff --git a/d2app/app.go b/d2app/app.go index bdb96e82..186e17ec 100644 --- a/d2app/app.go +++ b/d2app/app.go @@ -922,7 +922,7 @@ func (a *App) ToMainMenu(errorMessageOptional ...string) { // ToSelectHero forces the game to transition to the Select Hero (create character) screen func (a *App) ToSelectHero(connType d2clientconnectiontype.ClientConnectionType, host string) { - selectHero, err := d2gamescreen.CreateSelectHeroClass(a, a.asset, a.renderer, a.audio, a.ui, connType, a.config.LogLevel, host) + selectHero, err := d2gamescreen.CreateSelectHeroClass(a, a.asset, a.renderer, a.audio, a.ui, connType, a.config.LogLevel, a.language, host) if err != nil { a.Error(err.Error()) return @@ -952,7 +952,7 @@ func (a *App) ToCreateGame(filePath string, connType d2clientconnectiontype.Clie // ToCharacterSelect forces the game to transition to the Character Select (load character) screen func (a *App) ToCharacterSelect(connType d2clientconnectiontype.ClientConnectionType, connHost string) { characterSelect, err := d2gamescreen.CreateCharacterSelect(a, a.asset, a.renderer, a.inputManager, - a.audio, a.ui, connType, a.config.LogLevel, connHost) + a.audio, a.ui, connType, a.config.LogLevel, a.language, connHost) if err != nil { fmt.Printf("unable to create character select screen: %s", err) } @@ -979,5 +979,5 @@ func (a *App) ToCredits() { // ToCinematics forces the game to transition to the cinematics menu func (a *App) ToCinematics() { - a.screen.SetNextScreen(d2gamescreen.CreateCinematics(a, a.asset, a.renderer, a.audio, a.config.LogLevel, a.ui)) + a.screen.SetNextScreen(d2gamescreen.CreateCinematics(a, a.asset, a.renderer, a.audio, a.config.LogLevel, a.language, a.ui)) } diff --git a/d2game/d2gamescreen/character_select.go b/d2game/d2gamescreen/character_select.go index b432adc6..0f049db2 100644 --- a/d2game/d2gamescreen/character_select.go +++ b/d2game/d2gamescreen/character_select.go @@ -29,6 +29,7 @@ func CreateCharacterSelect( ui *d2ui.UIManager, connectionType d2clientconnectiontype.ClientConnectionType, l d2util.LogLevel, + lang string, connectionHost string, ) (*CharacterSelect, error) { playerStateFactory, err := d2hero.NewHeroStateFactory(asset) @@ -53,6 +54,7 @@ func CreateCharacterSelect( navigator: navigator, uiManager: ui, HeroStateFactory: playerStateFactory, + language: lang, } characterSelect.Logger = d2util.NewLogger() @@ -100,6 +102,7 @@ type CharacterSelect struct { navigator d2interface.Navigator *d2util.Logger + language string } const ( @@ -229,7 +232,7 @@ func (v *CharacterSelect) loadHeroTitle() { func (v *CharacterSelect) loadDeleteCharConfirm() { v.deleteCharConfirmLabel = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteUnits) - lines := "Are you sure that you want\nto delete this character?\nTake note: this will delete all\nversions of this Character." + lines := d2util.SplitIntoLinesWithMaxWidthOneLine(translateLabel(delCharConfLabel, v.language, v.asset), 30) v.deleteCharConfirmLabel.SetText(lines) v.deleteCharConfirmLabel.Alignment = d2ui.HorizontalAlignCenter deleteConfirmX, deleteConfirmY := 400, 185 @@ -312,12 +315,12 @@ func (v *CharacterSelect) createButtons(loading d2screen.LoadingState) { loading.Progress(twentyPercent) - v.deleteCharCancelButton = v.uiManager.NewButton(d2ui.ButtonTypeOkCancel, "NO") + v.deleteCharCancelButton = v.uiManager.NewButton(d2ui.ButtonTypeOkCancel, translateLabel(noLabel, v.language, v.asset)) v.deleteCharCancelButton.SetPosition(deleteCancelX, deleteCancelY) v.deleteCharCancelButton.SetVisible(false) v.deleteCharCancelButton.OnActivated(func() { v.onDeleteCharacterCancelClicked() }) - v.deleteCharOkButton = v.uiManager.NewButton(d2ui.ButtonTypeOkCancel, "YES") + v.deleteCharOkButton = v.uiManager.NewButton(d2ui.ButtonTypeOkCancel, translateLabel(yesLabel, v.language, v.asset)) v.deleteCharOkButton.SetPosition(deleteOkX, deleteOkY) v.deleteCharOkButton.SetVisible(false) v.deleteCharOkButton.OnActivated(func() { v.onDeleteCharacterConfirmClicked() }) diff --git a/d2game/d2gamescreen/cinematics.go b/d2game/d2gamescreen/cinematics.go index 718c0efb..d5f59389 100644 --- a/d2game/d2gamescreen/cinematics.go +++ b/d2game/d2gamescreen/cinematics.go @@ -30,6 +30,7 @@ func CreateCinematics( renderer d2interface.Renderer, aup d2interface.AudioProvider, l d2util.LogLevel, + lang string, ui *d2ui.UIManager) *Cinematics { cinematics := &Cinematics{ asset: asset, @@ -37,6 +38,7 @@ func CreateCinematics( navigator: navigator, uiManager: ui, audioProvider: aup, + language: lang, } cinematics.Logger = d2util.NewLogger() @@ -68,6 +70,7 @@ type Cinematics struct { audioProvider d2interface.AudioProvider *d2util.Logger + language string } // OnLoad is called to load the resources for the credits screen @@ -96,13 +99,13 @@ func (v *Cinematics) OnLoad(_ d2screen.LoadingState) { v.cinematicsLabel = v.uiManager.NewLabel(d2resource.Font30, d2resource.PaletteStatic) v.cinematicsLabel.Alignment = d2ui.HorizontalAlignCenter - v.cinematicsLabel.SetText("SELECT CINEMATIC") + v.cinematicsLabel.SetText(translateLabel(selectCinematicLabel, v.language, v.asset)) v.cinematicsLabel.Color[0] = rgbaColor(lightBrown) v.cinematicsLabel.SetPosition(cinematicsLabelX, cinematicsLabelY) } func (v *Cinematics) createButtons() { - v.cinematicsExitBtn = v.uiManager.NewButton(d2ui.ButtonTypeMedium, v.asset.TranslateString("cancel")) + v.cinematicsExitBtn = v.uiManager.NewButton(d2ui.ButtonTypeMedium, v.asset.TranslateString(translateLabel(cancelLabel, v.language, v.asset))) v.cinematicsExitBtn.SetPosition(cinematicsExitBtnX, cinematicsExitBtnY) v.cinematicsExitBtn.OnActivated(func() { v.onCinematicsExitBtnClicked() }) diff --git a/d2game/d2gamescreen/main_menu.go b/d2game/d2gamescreen/main_menu.go index e655b5fc..34235ac3 100644 --- a/d2game/d2gamescreen/main_menu.go +++ b/d2game/d2gamescreen/main_menu.go @@ -84,15 +84,23 @@ type BuildInfo struct { } const ( - singlePlayerLabel = iota + // main menu labels + cancelLabel = iota + copyrightLabel + allRightsReservedLabel + singlePlayerLabel battleNetLabel otherMultiplayerLabel exitLabel creditsLabel cinematicsLabel - viewAllCinematicsLabel // (View All Earned Cinematics) + + // cinematics menu labels + viewAllCinematicsLabel epilogueLabel - selectCinematics + selectCinematicLabel + + // multiplayer menu labels openBattleNetLaBEL tcpIpGameLabel tcpIpOptionsLabel @@ -100,19 +108,55 @@ const ( tcpIpJoinGameLabel tcpIpEnterHostIpLabel tcpIpYourIpLabel + tipHostLabel + tipJoinLabel + ipNotFoundLabel + + // select hero class menu labels + charNameLabel + hardCoreLabel + selectHeroClassLabel + amazonDescr + necromancerDescr + barbarianDescr + sorceressDescr + paladinDescr + + notUsed1 // this position isn't used here. + + hellLabel + nightmareLabel + normalLabel + selectDifficultyLabel + + notUsed2 + + delCharConfLabel + openLabel + notUsed3 + yesLabel + noLabel ) func baseLabelNumbers(idx int) int { baseLabelNumbers := []int{ + // main menu labels + 1612, // CANCEL + 1613, // (c) 2000 Blizzard Entertainment + 1614, // All Rights Reserved. 1620, // SINGLE PLAYER 1621, // BATTLE.NET 1623, // OTHER MULTIPLAYER 1625, // EXIT DIABLO II 1627, // CREDITS 1639, // CINEMATICS + + // cinematics menu labels 1640, // View All Earned Cinematics 1659, // Epilogue 1660, // SELECT CINEMATICS + + // multiplayer labels 1663, // OPEN BATTLE.NET 1666, // TCP/IP GAME 1667, // TCP/IP Options @@ -122,6 +166,39 @@ func baseLabelNumbers(idx int) int { 1680, // Your IP Address is: 1689, // Tip: host game 1690, // Tip: join game + 1691, // Cannot detect a valid TCP/IP address. + 1694, // Character Name + 1696, // Hardcore + 1697, // Select Hero Class + + 1698, // amazon description + 1704, // nec description + 1709, // barb description + 1710, // sorc description + 1711, // pal description + + /* these items are for battle.net multiplayer + labels and are not used yet + in addition, as many elements as the value + of the highest modifier must be replaced*/ + 1712, // not used here + + // difficulty levels: + 1800, // Hell + 1864, // Nightmare + 1865, // Normal + 1867, // Select Difficulty + + 1869, // not used, for locales with +1 mod + + 1878, // delete char confirm + 1881, // Open + 1889, // char name is currently taken (not used) + 1896, // YES + 1925, // NO + + 1926, // not used, for locales with +1 mod + } return baseLabelNumbers[idx] } @@ -300,14 +377,14 @@ func (v *MainMenu) createLabels(loading d2screen.LoadingState) { v.copyrightLabel = v.uiManager.NewLabel(d2resource.FontFormal12, d2resource.PaletteStatic) v.copyrightLabel.Alignment = d2ui.HorizontalAlignCenter - v.copyrightLabel.SetText("Diablo 2 is © Copyright 2000-2016 Blizzard Entertainment") + v.copyrightLabel.SetText(translateLabel(copyrightLabel, v.language, v.asset)) v.copyrightLabel.Color[0] = rgbaColor(lightBrown) v.copyrightLabel.SetPosition(copyrightX, copyrightY) loading.Progress(thirtyPercent) v.copyrightLabel2 = v.uiManager.NewLabel(d2resource.FontFormal12, d2resource.PaletteStatic) v.copyrightLabel2.Alignment = d2ui.HorizontalAlignCenter - v.copyrightLabel2.SetText("All Rights Reserved.") + v.copyrightLabel2.SetText(translateLabel(allRightsReservedLabel, v.language, v.asset)) v.copyrightLabel2.Color[0] = rgbaColor(lightBrown) v.copyrightLabel2.SetPosition(copyright2X, copyright2Y) @@ -325,14 +402,13 @@ func (v *MainMenu) createLabels(loading d2screen.LoadingState) { v.tcpJoinGameLabel = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteUnits) v.tcpJoinGameLabel.Alignment = d2ui.HorizontalAlignCenter - //v.tcpJoinGameLabel.SetText("Enter Host IP Address\nto Join Game") - v.tcpJoinGameLabel.SetText(translateLabel(tcpIpEnterHostIpLabel, v.language, v.asset)) + v.tcpJoinGameLabel.SetText(d2util.SplitIntoLinesWithMaxWidthOneLine(translateLabel(tcpIpEnterHostIpLabel, v.language, v.asset), 27)) v.tcpJoinGameLabel.Color[0] = rgbaColor(gold) v.tcpJoinGameLabel.SetPosition(joinGameX, joinGameY) v.machineIP = v.uiManager.NewLabel(d2resource.Font24, d2resource.PaletteUnits) v.machineIP.Alignment = d2ui.HorizontalAlignCenter - v.machineIP.SetText("Your IP address is:\n" + v.getLocalIP()) + v.machineIP.SetText(translateLabel(tcpIpYourIpLabel, v.language, v.asset) + "\n" + v.getLocalIP()) v.machineIP.Color[0] = rgbaColor(lightYellow) v.machineIP.SetPosition(machineIPX, machineIPY) @@ -407,11 +483,11 @@ func (v *MainMenu) createButtons(loading d2screen.LoadingState) { v.mapTestButton.OnActivated(func() { v.onMapTestClicked() }) v.btnTCPIPCancel = v.uiManager.NewButton(d2ui.ButtonTypeMedium, - v.asset.TranslateString("cancel")) + translateLabel(cancelLabel, v.language, v.asset)) v.btnTCPIPCancel.SetPosition(tcpBtnX, tcpBtnY) v.btnTCPIPCancel.OnActivated(func() { v.onTCPIPCancelClicked() }) - v.btnServerIPCancel = v.uiManager.NewButton(d2ui.ButtonTypeOkCancel, "CANCEL") + v.btnServerIPCancel = v.uiManager.NewButton(d2ui.ButtonTypeOkCancel, translateLabel(cancelLabel, v.language, v.asset)) v.btnServerIPCancel.SetPosition(srvCancelBtnX, srvCancelBtnY) v.btnServerIPCancel.OnActivated(func() { v.onBtnTCPIPCancelClicked() }) @@ -434,7 +510,7 @@ func (v *MainMenu) createMultiplayerMenuButtons() { v.networkTCPIPButton.OnActivated(func() { v.onNetworkTCPIPClicked() }) v.networkCancelButton = v.uiManager.NewButton(d2ui.ButtonTypeWide, - v.asset.TranslateString("cancel")) + translateLabel(cancelLabel, v.language, v.asset)) v.networkCancelButton.SetPosition(networkCancelBtnX, networkCancelBtnY) v.networkCancelButton.OnActivated(func() { v.onNetworkCancelClicked() }) @@ -698,5 +774,5 @@ func (v *MainMenu) getLocalIP() string { v.Warning("no IPv4 Address could be found") - return "no IPv4 Address could be found" + return translateLabel(ipNotFoundLabel, v.language, v.asset) } diff --git a/d2game/d2gamescreen/select_hero_class.go b/d2game/d2gamescreen/select_hero_class.go index 733ccb4e..370ee5f3 100644 --- a/d2game/d2gamescreen/select_hero_class.go +++ b/d2game/d2gamescreen/select_hero_class.go @@ -279,6 +279,7 @@ func CreateSelectHeroClass( ui *d2ui.UIManager, connectionType d2clientconnectiontype.ClientConnectionType, l d2util.LogLevel, + lang string, connectionHost string, ) (*SelectHeroClass, error) { playerStateFactory, err := d2hero.NewHeroStateFactory(asset) @@ -303,6 +304,7 @@ func CreateSelectHeroClass( uiManager: ui, HeroStateFactory: playerStateFactory, InventoryItemFactory: inventoryItemFactory, + language: lang, } selectHeroClass.Logger = d2util.NewLogger() @@ -343,6 +345,7 @@ type SelectHeroClass struct { navigator d2interface.Navigator *d2util.Logger + language string } // OnLoad loads the resources for the Select Hero Class screen @@ -416,7 +419,7 @@ func (v *SelectHeroClass) createLabels() { halfFontWidth := fontWidth / half v.headingLabel.SetPosition(headingX-halfFontWidth, headingY) - v.headingLabel.SetText("Select Hero Class") + v.headingLabel.SetText(translateLabel(selectHeroClassLabel, v.language, v.asset)) v.headingLabel.Alignment = d2ui.HorizontalAlignCenter v.heroClassLabel = v.uiManager.NewLabel(d2resource.Font30, d2resource.PaletteUnits) @@ -437,17 +440,18 @@ func (v *SelectHeroClass) createLabels() { v.heroNameLabel = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteUnits) v.heroNameLabel.Alignment = d2ui.HorizontalAlignLeft - v.heroNameLabel.SetText(d2ui.ColorTokenize("Character Name", d2ui.ColorTokenGold)) + v.heroNameLabel.SetText(d2ui.ColorTokenize(translateLabel(charNameLabel, v.language, v.asset), d2ui.ColorTokenGold)) v.heroNameLabel.SetPosition(heroNameLabelX, heroNameLabelY) v.expansionCharLabel = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteUnits) v.expansionCharLabel.Alignment = d2ui.HorizontalAlignLeft - v.expansionCharLabel.SetText(d2ui.ColorTokenize("EXPANSION CHARACTER", d2ui.ColorTokenGold)) + // to be honest, it should be TranslateString("#803"), but I suppose that's the same + v.expansionCharLabel.SetText(d2ui.ColorTokenize(v.asset.TranslateString("expansionchar2x"), d2ui.ColorTokenGold)) v.expansionCharLabel.SetPosition(expansionLabelX, expansionLabelY) v.hardcoreCharLabel = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteUnits) v.hardcoreCharLabel.Alignment = d2ui.HorizontalAlignLeft - v.hardcoreCharLabel.SetText(d2ui.ColorTokenize("Hardcore", d2ui.ColorTokenGold)) + v.hardcoreCharLabel.SetText(d2ui.ColorTokenize(translateLabel(hardCoreLabel, v.language, v.asset), d2ui.ColorTokenGold)) v.hardcoreCharLabel.SetPosition(hardcoreLabelX, hardcoreLabelY) } @@ -685,25 +689,26 @@ func (v *SelectHeroClass) updateHeroText() { return case d2enum.HeroBarbarian: v.heroClassLabel.SetText(v.asset.TranslateString("partycharbar")) - v.setDescLabels("He is unequaled in close-quarters combat and mastery of weapons.") + v.setDescLabels(barbarianDescr, "") case d2enum.HeroNecromancer: v.heroClassLabel.SetText(v.asset.TranslateString("partycharnec")) - v.setDescLabels("Summoning undead minions and cursing his enemies are his specialties.") + v.setDescLabels(necromancerDescr, "") case d2enum.HeroPaladin: v.heroClassLabel.SetText(v.asset.TranslateString("partycharpal")) - v.setDescLabels("He is a natural party leader, holy man, and blessed warrior.") + v.setDescLabels(paladinDescr, "") case d2enum.HeroAssassin: v.heroClassLabel.SetText(v.asset.TranslateString("partycharass")) - v.setDescLabels("Schooled in the Martial Arts, her mind and body are deadly weapons.") + v.setDescLabels(0, "#305") case d2enum.HeroSorceress: v.heroClassLabel.SetText(v.asset.TranslateString("partycharsor")) - v.setDescLabels("She has mastered the elemental magicks -- fire, lightning, and ice.") + v.setDescLabels(sorceressDescr, "") case d2enum.HeroAmazon: v.heroClassLabel.SetText(v.asset.TranslateString("partycharama")) - v.setDescLabels("Skilled with the spear and the bow, she is a very versatile fighter.") + v.setDescLabels(amazonDescr, "") case d2enum.HeroDruid: v.heroClassLabel.SetText(v.asset.TranslateString("partychardru")) - v.setDescLabels("Commanding the forces of nature, he summons wild beasts and raging storms to his side.") + // here is a problem with polish language: in polish string table, there are two items with key "#304" + v.setDescLabels(0, "#304") } } @@ -712,8 +717,13 @@ const ( twoLine = 2 ) -func (v *SelectHeroClass) setDescLabels(descKey string) { - heroDesc := v.asset.TranslateString(descKey) +func (v *SelectHeroClass) setDescLabels(descKey int, key string) { + var heroDesc string + if key != "" { + heroDesc = v.asset.TranslateString(key) + } else { + heroDesc = translateLabel(descKey, v.language, v.asset) + } parts := d2util.SplitIntoLinesWithMaxWidth(heroDesc, heroDescCharWidth) numLines := len(parts)