1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2025-02-04 15:46:51 -05:00

Merge pull request #951 from gucio321/multi-language-labels

Multi language labels
This commit is contained in:
Tim Sarbin 2020-11-27 11:47:54 -05:00 committed by GitHub
commit 73d381215e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 240 additions and 70 deletions

View File

@ -49,3 +49,35 @@ func GetFontCharset(language string) string {
return charset[language] return charset[language]
} }
// GetLabelModifier returns modifier for language
/* modifiers for labels (used in string tables)
modifier is something like that:
english table: polish table:
key | value key | value
#1 | v1 |
#4 | v2 #4 | v1
#5 | v3 #5 | v2
#8 | v4 #8 | v3
So, GetLabelModifier returns value of offset in locale languages table
*/
// some of values need to be set up. For now values with "checked" comment
// was tested and works fine in main menu.
func GetLabelModifier(language string) int {
modifiers := map[string]int{
"ENG": 0, // (English) // checked
"ESP": 0, // (Spanish)
"DEU": 0, // (German) // checked
"FRA": 0, // (French)
"POR": 0, // (Portuguese)
"ITA": 0, // (Italian)
"JPN": 0, // (Japanese)
"KOR": 0, // (Korean)
"SIN": 0, //
"CHI": 0, // (Chinese)
"POL": 1, // (Polish) // checked
"RUS": 0, // (Russian)
}
return modifiers[language]
}

View File

@ -135,11 +135,6 @@ func SplitIntoLinesWithMaxWidth(fullSentence string, maxChars int) []string {
return lines 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 { func splitCjkIntoChunks(str string, chars int) []string {
chunks := make([]string, chars/len(str)) chunks := make([]string, chars/len(str))
i, count := 0, 0 i, count := 0, 0

View File

@ -57,6 +57,7 @@ type AssetManager struct {
palettes d2interface.Cache palettes d2interface.Cache
transforms d2interface.Cache transforms d2interface.Cache
Records *d2records.RecordManager Records *d2records.RecordManager
language string
} }
// SetLogLevel sets the log level for the asset manager, record manager, and file loader // SetLogLevel sets the log level for the asset manager, record manager, and file loader
@ -124,6 +125,8 @@ func (am *AssetManager) LoadLanguage(languagePath string) string {
language := d2resource.GetLanguageLiteral(languageCode) language := d2resource.GetLanguageLiteral(languageCode)
am.Infof("Language: %s", language) am.Infof("Language: %s", language)
am.language = language
return language return language
} }
@ -280,40 +283,97 @@ func (am *AssetManager) LoadStringTable(tablePath string) (d2tbl.TextDictionary,
// TranslateString returns the translation of the given string. The string is retrieved from // TranslateString returns the translation of the given string. The string is retrieved from
// the loaded string tables. // the loaded string tables.
func (am *AssetManager) TranslateString(key string) string { func (am *AssetManager) TranslateString(input interface{}) string {
var key string
switch s := input.(type) {
case string:
key = s
case fmt.Stringer:
key = s.String()
}
for idx := range am.tables { for idx := range am.tables {
if value, found := am.tables[idx][key]; found { if value, found := am.tables[idx][key]; found {
return value return value
} }
} }
// Fix to allow v.setDescLabels("#123") to be bypassed for a patch in issue #360. Reenable later. // Fix to allow v.setDescLabels("#123") to be bypassed for a patch in issue #360. Reenable later.
// log.Panicf("Could not find a string for the key '%s'", key) // log.Panicf("Could not find a string for the key '%s'", key)
return key return key
} }
// TranslateHeroClass translates her class given to game locale func (am *AssetManager) baseLabelNumbers(idx int) int {
func (am *AssetManager) TranslateHeroClass(h d2enum.Hero) string { baseLabelNumbers := []int{
switch h { // main menu labels
case d2enum.HeroBarbarian: 1612, // CANCEL
return am.TranslateString("Barbarian") 1613, // (c) 2000 Blizzard Entertainment
case d2enum.HeroNecromancer: 1614, // All Rights Reserved.
return am.TranslateString("Necromancer") 1620, // SINGLE PLAYER
case d2enum.HeroPaladin: 1621, // BATTLE.NET
return am.TranslateString("Paladin") 1623, // OTHER MULTIPLAYER
case d2enum.HeroAssassin: 1625, // EXIT DIABLO II
return am.TranslateString("Assassin") 1627, // CREDITS
case d2enum.HeroSorceress: 1639, // CINEMATICS
return am.TranslateString("Sorceress")
case d2enum.HeroAmazon: // cinematics menu labels
return am.TranslateString("Amazon") 1640, // View All Earned Cinematics
case d2enum.HeroDruid: 1659, // Epilogue
return am.TranslateString("Druid") 1660, // SELECT CINEMATICS
default:
am.Error("Unknown Hero Class") // multiplayer labels
1663, // OPEN BATTLE.NET
1666, // TCP/IP GAME
1667, // TCP/IP Options
1675, // HOST GAME
1676, // JOIN GAME
1678, // Enter Host IP Address to Join Game
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
/*in addition, as many elements as the value
of the highest modifier must be listed*/
1712,
/* here, should be labels used to battle.net multiplayer, but they are not used yet,
therefore I don't list them 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
970, // EXIT
971,
} }
// should not be reached return baseLabelNumbers[idx]
return "---" }
// TranslateLabel translates the label taking into account its shift in the table
func (am *AssetManager) TranslateLabel(label int) string {
return am.TranslateString(fmt.Sprintf("#%d", am.baseLabelNumbers(label+d2resource.GetLabelModifier(am.language))))
} }
// LoadPaletteTransform loads a palette transform file // LoadPaletteTransform loads a palette transform file

View File

@ -5,6 +5,7 @@ import (
"math" "math"
"os" "os"
"strconv" "strconv"
"strings"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero"
@ -229,7 +230,7 @@ func (v *CharacterSelect) loadHeroTitle() {
func (v *CharacterSelect) loadDeleteCharConfirm() { func (v *CharacterSelect) loadDeleteCharConfirm() {
v.deleteCharConfirmLabel = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteUnits) 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 := strings.Join(d2util.SplitIntoLinesWithMaxWidth(v.asset.TranslateLabel(delCharConfLabel), 30), "\n")
v.deleteCharConfirmLabel.SetText(lines) v.deleteCharConfirmLabel.SetText(lines)
v.deleteCharConfirmLabel.Alignment = d2ui.HorizontalAlignCenter v.deleteCharConfirmLabel.Alignment = d2ui.HorizontalAlignCenter
deleteConfirmX, deleteConfirmY := 400, 185 deleteConfirmX, deleteConfirmY := 400, 185
@ -292,32 +293,33 @@ func rgbaColor(rgba uint32) color.RGBA {
} }
func (v *CharacterSelect) createButtons(loading d2screen.LoadingState) { func (v *CharacterSelect) createButtons(loading d2screen.LoadingState) {
v.newCharButton = v.uiManager.NewButton(d2ui.ButtonTypeTall, d2util.SplitIntoLinesWithMaxWidthOneLine(v.asset.TranslateString("#831"), 13)) v.newCharButton = v.uiManager.NewButton(d2ui.ButtonTypeTall, strings.Join(
d2util.SplitIntoLinesWithMaxWidth(v.asset.TranslateString("#831"), 13), "\n"))
v.newCharButton.SetPosition(newCharBtnX, newCharBtnY) v.newCharButton.SetPosition(newCharBtnX, newCharBtnY)
v.newCharButton.OnActivated(func() { v.onNewCharButtonClicked() }) v.newCharButton.OnActivated(func() { v.onNewCharButtonClicked() })
v.convertCharButton = v.uiManager.NewButton(d2ui.ButtonTypeTall, v.convertCharButton = v.uiManager.NewButton(d2ui.ButtonTypeTall,
d2util.SplitIntoLinesWithMaxWidthOneLine(v.asset.TranslateString("#825"), 13)) strings.Join(d2util.SplitIntoLinesWithMaxWidth(v.asset.TranslateString("#825"), 13), "\n"))
v.convertCharButton.SetPosition(convertCharBtnX, convertCharBtnY) v.convertCharButton.SetPosition(convertCharBtnX, convertCharBtnY)
v.convertCharButton.SetEnabled(false) v.convertCharButton.SetEnabled(false)
v.deleteCharButton = v.uiManager.NewButton(d2ui.ButtonTypeTall, v.deleteCharButton = v.uiManager.NewButton(d2ui.ButtonTypeTall,
d2util.SplitIntoLinesWithMaxWidthOneLine(v.asset.TranslateString("#832"), 13)) strings.Join(d2util.SplitIntoLinesWithMaxWidth(v.asset.TranslateString("#832"), 13), "\n"))
v.deleteCharButton.OnActivated(func() { v.onDeleteCharButtonClicked() }) v.deleteCharButton.OnActivated(func() { v.onDeleteCharButtonClicked() })
v.deleteCharButton.SetPosition(deleteCharBtnX, deleteCharBtnY) v.deleteCharButton.SetPosition(deleteCharBtnX, deleteCharBtnY)
v.exitButton = v.uiManager.NewButton(d2ui.ButtonTypeMedium, "EXIT") v.exitButton = v.uiManager.NewButton(d2ui.ButtonTypeMedium, v.asset.TranslateLabel(exitLabel))
v.exitButton.SetPosition(exitBtnX, exitBtnY) v.exitButton.SetPosition(exitBtnX, exitBtnY)
v.exitButton.OnActivated(func() { v.onExitButtonClicked() }) v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
loading.Progress(twentyPercent) loading.Progress(twentyPercent)
v.deleteCharCancelButton = v.uiManager.NewButton(d2ui.ButtonTypeOkCancel, "NO") v.deleteCharCancelButton = v.uiManager.NewButton(d2ui.ButtonTypeOkCancel, v.asset.TranslateLabel(noLabel))
v.deleteCharCancelButton.SetPosition(deleteCancelX, deleteCancelY) v.deleteCharCancelButton.SetPosition(deleteCancelX, deleteCancelY)
v.deleteCharCancelButton.SetVisible(false) v.deleteCharCancelButton.SetVisible(false)
v.deleteCharCancelButton.OnActivated(func() { v.onDeleteCharacterCancelClicked() }) v.deleteCharCancelButton.OnActivated(func() { v.onDeleteCharacterCancelClicked() })
v.deleteCharOkButton = v.uiManager.NewButton(d2ui.ButtonTypeOkCancel, "YES") v.deleteCharOkButton = v.uiManager.NewButton(d2ui.ButtonTypeOkCancel, v.asset.TranslateLabel(yesLabel))
v.deleteCharOkButton.SetPosition(deleteOkX, deleteOkY) v.deleteCharOkButton.SetPosition(deleteOkX, deleteOkY)
v.deleteCharOkButton.SetVisible(false) v.deleteCharOkButton.SetVisible(false)
v.deleteCharOkButton.OnActivated(func() { v.onDeleteCharacterConfirmClicked() }) v.deleteCharOkButton.OnActivated(func() { v.onDeleteCharacterConfirmClicked() })
@ -349,7 +351,7 @@ func (v *CharacterSelect) updateCharacterBoxes() {
heroName := v.gameStates[idx].HeroName heroName := v.gameStates[idx].HeroName
heroInfo := v.asset.TranslateString("level") + " " + strconv.FormatInt(int64(v.gameStates[idx].Stats.Level), 10) + heroInfo := v.asset.TranslateString("level") + " " + strconv.FormatInt(int64(v.gameStates[idx].Stats.Level), 10) +
" " + v.asset.TranslateHeroClass(v.gameStates[idx].HeroType) " " + v.asset.TranslateString(v.gameStates[idx].HeroType.String())
v.characterNameLabel[i].SetText(d2ui.ColorTokenize(heroName, d2ui.ColorTokenGold)) v.characterNameLabel[i].SetText(d2ui.ColorTokenize(heroName, d2ui.ColorTokenGold))
v.characterStatsLabel[i].SetText(d2ui.ColorTokenize(heroInfo, d2ui.ColorTokenWhite)) v.characterStatsLabel[i].SetText(d2ui.ColorTokenize(heroInfo, d2ui.ColorTokenWhite))

View File

@ -96,13 +96,14 @@ func (v *Cinematics) OnLoad(_ d2screen.LoadingState) {
v.cinematicsLabel = v.uiManager.NewLabel(d2resource.Font30, d2resource.PaletteStatic) v.cinematicsLabel = v.uiManager.NewLabel(d2resource.Font30, d2resource.PaletteStatic)
v.cinematicsLabel.Alignment = d2ui.HorizontalAlignCenter v.cinematicsLabel.Alignment = d2ui.HorizontalAlignCenter
v.cinematicsLabel.SetText("SELECT CINEMATIC") v.cinematicsLabel.SetText(v.asset.TranslateLabel(selectCinematicLabel))
v.cinematicsLabel.Color[0] = rgbaColor(lightBrown) v.cinematicsLabel.Color[0] = rgbaColor(lightBrown)
v.cinematicsLabel.SetPosition(cinematicsLabelX, cinematicsLabelY) v.cinematicsLabel.SetPosition(cinematicsLabelX, cinematicsLabelY)
} }
func (v *Cinematics) createButtons() { 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(v.asset.TranslateLabel(cancelLabel)))
v.cinematicsExitBtn.SetPosition(cinematicsExitBtnX, cinematicsExitBtnY) v.cinematicsExitBtn.SetPosition(cinematicsExitBtnX, cinematicsExitBtnY)
v.cinematicsExitBtn.OnActivated(func() { v.onCinematicsExitBtnClicked() }) v.cinematicsExitBtn.OnActivated(func() { v.onCinematicsExitBtnClicked() })

View File

@ -105,7 +105,7 @@ func (v *Credits) OnLoad(loading d2screen.LoadingState) {
v.creditsBackground.SetPosition(creditsX, creditsY) v.creditsBackground.SetPosition(creditsX, creditsY)
loading.Progress(twentyPercent) loading.Progress(twentyPercent)
v.exitButton = v.uiManager.NewButton(d2ui.ButtonTypeMedium, "EXIT") v.exitButton = v.uiManager.NewButton(d2ui.ButtonTypeMedium, v.asset.TranslateLabel(exitLabel))
v.exitButton.SetPosition(charSelExitBtnX, charSelExitBtnY) v.exitButton.SetPosition(charSelExitBtnX, charSelExitBtnY)
v.exitButton.OnActivated(func() { v.onExitButtonClicked() }) v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
loading.Progress(fourtyPercent) loading.Progress(fourtyPercent)

View File

@ -7,6 +7,7 @@ import (
"os" "os"
"os/exec" "os/exec"
"runtime" "runtime"
"strings"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero"
@ -83,6 +84,76 @@ type BuildInfo struct {
Branch, Commit string Branch, Commit string
} }
const (
// main menu labels
cancelLabel = iota
copyrightLabel
allRightsReservedLabel
singlePlayerLabel
_
otherMultiplayerLabel
exitGameLabel
creditsLabel
cinematicsLabel
// cinematics menu labels
//nolint:deadcode,varcheck,unused // will be used
viewAllCinematicsLabel
//nolint:deadcode,varcheck,unused // will be used
epilogueLabel
selectCinematicLabel
// multiplayer menu labels
_
tcpIPGameLabel
tcpIPOptionsLabel
tcpIPHostGameLabel
tcpIPJoinGameLabel
tcpIPEnterHostIPLabel
tcpIPYourIPLabel
//nolint:deadcode,varcheck,unused // will be used
tipHostLabel
//nolint:deadcode,varcheck,unused // will be used
tipJoinLabel
ipNotFoundLabel
// select hero class menu labels
charNameLabel
hardCoreLabel
selectHeroClassLabel
amazonDescr
necromancerDescr
barbarianDescr
sorceressDescr
paladinDescr
_
//nolint:deadcode,varcheck,unused // will be used
hellLabel
//nolint:deadcode,varcheck,unused // will be used
nightmareLabel
//nolint:deadcode,varcheck,unused // will be used
normalLabel
//nolint:deadcode,varcheck,unused // will be used
selectDifficultyLabel
_
delCharConfLabel
//nolint:deadcode,varcheck,unused // will be used
openLabel
_
yesLabel
noLabel
_
exitLabel
)
// CreateMainMenu creates an instance of MainMenu // CreateMainMenu creates an instance of MainMenu
func CreateMainMenu( func CreateMainMenu(
navigator d2interface.Navigator, navigator d2interface.Navigator,
@ -249,14 +320,14 @@ func (v *MainMenu) createLabels(loading d2screen.LoadingState) {
v.copyrightLabel = v.uiManager.NewLabel(d2resource.FontFormal12, d2resource.PaletteStatic) v.copyrightLabel = v.uiManager.NewLabel(d2resource.FontFormal12, d2resource.PaletteStatic)
v.copyrightLabel.Alignment = d2ui.HorizontalAlignCenter v.copyrightLabel.Alignment = d2ui.HorizontalAlignCenter
v.copyrightLabel.SetText("Diablo 2 is © Copyright 2000-2016 Blizzard Entertainment") v.copyrightLabel.SetText(v.asset.TranslateLabel(copyrightLabel))
v.copyrightLabel.Color[0] = rgbaColor(lightBrown) v.copyrightLabel.Color[0] = rgbaColor(lightBrown)
v.copyrightLabel.SetPosition(copyrightX, copyrightY) v.copyrightLabel.SetPosition(copyrightX, copyrightY)
loading.Progress(thirtyPercent) loading.Progress(thirtyPercent)
v.copyrightLabel2 = v.uiManager.NewLabel(d2resource.FontFormal12, d2resource.PaletteStatic) v.copyrightLabel2 = v.uiManager.NewLabel(d2resource.FontFormal12, d2resource.PaletteStatic)
v.copyrightLabel2.Alignment = d2ui.HorizontalAlignCenter v.copyrightLabel2.Alignment = d2ui.HorizontalAlignCenter
v.copyrightLabel2.SetText("All Rights Reserved.") v.copyrightLabel2.SetText(v.asset.TranslateLabel(allRightsReservedLabel))
v.copyrightLabel2.Color[0] = rgbaColor(lightBrown) v.copyrightLabel2.Color[0] = rgbaColor(lightBrown)
v.copyrightLabel2.SetPosition(copyright2X, copyright2Y) v.copyrightLabel2.SetPosition(copyright2X, copyright2Y)
@ -270,17 +341,17 @@ func (v *MainMenu) createLabels(loading d2screen.LoadingState) {
v.tcpIPOptionsLabel = v.uiManager.NewLabel(d2resource.Font42, d2resource.PaletteUnits) v.tcpIPOptionsLabel = v.uiManager.NewLabel(d2resource.Font42, d2resource.PaletteUnits)
v.tcpIPOptionsLabel.SetPosition(tcpOptionsX, tcpOptionsY) v.tcpIPOptionsLabel.SetPosition(tcpOptionsX, tcpOptionsY)
v.tcpIPOptionsLabel.Alignment = d2ui.HorizontalAlignCenter v.tcpIPOptionsLabel.Alignment = d2ui.HorizontalAlignCenter
v.tcpIPOptionsLabel.SetText("TCP/IP Options") v.tcpIPOptionsLabel.SetText(v.asset.TranslateLabel(tcpIPOptionsLabel))
v.tcpJoinGameLabel = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteUnits) v.tcpJoinGameLabel = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteUnits)
v.tcpJoinGameLabel.Alignment = d2ui.HorizontalAlignCenter v.tcpJoinGameLabel.Alignment = d2ui.HorizontalAlignCenter
v.tcpJoinGameLabel.SetText("Enter Host IP Address\nto Join Game") v.tcpJoinGameLabel.SetText(strings.Join(d2util.SplitIntoLinesWithMaxWidth(v.asset.TranslateLabel(tcpIPEnterHostIPLabel), 27), "\n"))
v.tcpJoinGameLabel.Color[0] = rgbaColor(gold) v.tcpJoinGameLabel.Color[0] = rgbaColor(gold)
v.tcpJoinGameLabel.SetPosition(joinGameX, joinGameY) v.tcpJoinGameLabel.SetPosition(joinGameX, joinGameY)
v.machineIP = v.uiManager.NewLabel(d2resource.Font24, d2resource.PaletteUnits) v.machineIP = v.uiManager.NewLabel(d2resource.Font24, d2resource.PaletteUnits)
v.machineIP.Alignment = d2ui.HorizontalAlignCenter v.machineIP.Alignment = d2ui.HorizontalAlignCenter
v.machineIP.SetText("Your IP address is:\n" + v.getLocalIP()) v.machineIP.SetText(v.asset.TranslateLabel(tcpIPYourIPLabel) + "\n" + v.getLocalIP())
v.machineIP.Color[0] = rgbaColor(lightYellow) v.machineIP.Color[0] = rgbaColor(lightYellow)
v.machineIP.SetPosition(machineIPX, machineIPY) v.machineIP.SetPosition(machineIPX, machineIPY)
@ -329,20 +400,20 @@ func (v *MainMenu) createLogos(loading d2screen.LoadingState) {
} }
func (v *MainMenu) createButtons(loading d2screen.LoadingState) { func (v *MainMenu) createButtons(loading d2screen.LoadingState) {
v.exitDiabloButton = v.uiManager.NewButton(d2ui.ButtonTypeWide, "EXIT DIABLO II") v.exitDiabloButton = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.asset.TranslateLabel(exitGameLabel))
v.exitDiabloButton.SetPosition(exitDiabloBtnX, exitDiabloBtnY) v.exitDiabloButton.SetPosition(exitDiabloBtnX, exitDiabloBtnY)
v.exitDiabloButton.OnActivated(func() { v.onExitButtonClicked() }) v.exitDiabloButton.OnActivated(func() { v.onExitButtonClicked() })
v.creditsButton = v.uiManager.NewButton(d2ui.ButtonTypeShort, "CREDITS") v.creditsButton = v.uiManager.NewButton(d2ui.ButtonTypeShort, v.asset.TranslateLabel(creditsLabel))
v.creditsButton.SetPosition(creditBtnX, creditBtnY) v.creditsButton.SetPosition(creditBtnX, creditBtnY)
v.creditsButton.OnActivated(func() { v.onCreditsButtonClicked() }) v.creditsButton.OnActivated(func() { v.onCreditsButtonClicked() })
v.cinematicsButton = v.uiManager.NewButton(d2ui.ButtonTypeShort, "CINEMATICS") v.cinematicsButton = v.uiManager.NewButton(d2ui.ButtonTypeShort, v.asset.TranslateLabel(cinematicsLabel))
v.cinematicsButton.SetPosition(cineBtnX, cineBtnY) v.cinematicsButton.SetPosition(cineBtnX, cineBtnY)
v.cinematicsButton.OnActivated(func() { v.onCinematicsButtonClicked() }) v.cinematicsButton.OnActivated(func() { v.onCinematicsButtonClicked() })
loading.Progress(seventyPercent) loading.Progress(seventyPercent)
v.singlePlayerButton = v.uiManager.NewButton(d2ui.ButtonTypeWide, "SINGLE PLAYER") v.singlePlayerButton = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.asset.TranslateLabel(singlePlayerLabel))
v.singlePlayerButton.SetPosition(singlePlayerBtnX, singlePlayerBtnY) v.singlePlayerButton.SetPosition(singlePlayerBtnX, singlePlayerBtnY)
v.singlePlayerButton.OnActivated(func() { v.onSinglePlayerClicked() }) v.singlePlayerButton.OnActivated(func() { v.onSinglePlayerClicked() })
@ -355,11 +426,11 @@ func (v *MainMenu) createButtons(loading d2screen.LoadingState) {
v.mapTestButton.OnActivated(func() { v.onMapTestClicked() }) v.mapTestButton.OnActivated(func() { v.onMapTestClicked() })
v.btnTCPIPCancel = v.uiManager.NewButton(d2ui.ButtonTypeMedium, v.btnTCPIPCancel = v.uiManager.NewButton(d2ui.ButtonTypeMedium,
v.asset.TranslateString("cancel")) v.asset.TranslateLabel(cancelLabel))
v.btnTCPIPCancel.SetPosition(tcpBtnX, tcpBtnY) v.btnTCPIPCancel.SetPosition(tcpBtnX, tcpBtnY)
v.btnTCPIPCancel.OnActivated(func() { v.onTCPIPCancelClicked() }) v.btnTCPIPCancel.OnActivated(func() { v.onTCPIPCancelClicked() })
v.btnServerIPCancel = v.uiManager.NewButton(d2ui.ButtonTypeOkCancel, "CANCEL") v.btnServerIPCancel = v.uiManager.NewButton(d2ui.ButtonTypeOkCancel, v.asset.TranslateLabel(cancelLabel))
v.btnServerIPCancel.SetPosition(srvCancelBtnX, srvCancelBtnY) v.btnServerIPCancel.SetPosition(srvCancelBtnX, srvCancelBtnY)
v.btnServerIPCancel.OnActivated(func() { v.onBtnTCPIPCancelClicked() }) v.btnServerIPCancel.OnActivated(func() { v.onBtnTCPIPCancelClicked() })
@ -372,24 +443,25 @@ func (v *MainMenu) createButtons(loading d2screen.LoadingState) {
} }
func (v *MainMenu) createMultiplayerMenuButtons() { func (v *MainMenu) createMultiplayerMenuButtons() {
v.multiplayerButton = v.uiManager.NewButton(d2ui.ButtonTypeWide, "MULTIPLAYER") v.multiplayerButton = v.uiManager.NewButton(d2ui.ButtonTypeWide,
v.asset.TranslateLabel(otherMultiplayerLabel))
v.multiplayerButton.SetPosition(multiplayerBtnX, multiplayerBtnY) v.multiplayerButton.SetPosition(multiplayerBtnX, multiplayerBtnY)
v.multiplayerButton.OnActivated(func() { v.onMultiplayerClicked() }) v.multiplayerButton.OnActivated(func() { v.onMultiplayerClicked() })
v.networkTCPIPButton = v.uiManager.NewButton(d2ui.ButtonTypeWide, "TCP/IP GAME") v.networkTCPIPButton = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.asset.TranslateLabel(tcpIPGameLabel))
v.networkTCPIPButton.SetPosition(tcpNetBtnX, tcpNetBtnY) v.networkTCPIPButton.SetPosition(tcpNetBtnX, tcpNetBtnY)
v.networkTCPIPButton.OnActivated(func() { v.onNetworkTCPIPClicked() }) v.networkTCPIPButton.OnActivated(func() { v.onNetworkTCPIPClicked() })
v.networkCancelButton = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.networkCancelButton = v.uiManager.NewButton(d2ui.ButtonTypeWide,
v.asset.TranslateString("cancel")) v.asset.TranslateLabel(cancelLabel))
v.networkCancelButton.SetPosition(networkCancelBtnX, networkCancelBtnY) v.networkCancelButton.SetPosition(networkCancelBtnX, networkCancelBtnY)
v.networkCancelButton.OnActivated(func() { v.onNetworkCancelClicked() }) v.networkCancelButton.OnActivated(func() { v.onNetworkCancelClicked() })
v.btnTCPIPHostGame = v.uiManager.NewButton(d2ui.ButtonTypeWide, "HOST GAME") v.btnTCPIPHostGame = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.asset.TranslateLabel(tcpIPHostGameLabel))
v.btnTCPIPHostGame.SetPosition(tcpHostBtnX, tcpHostBtnY) v.btnTCPIPHostGame.SetPosition(tcpHostBtnX, tcpHostBtnY)
v.btnTCPIPHostGame.OnActivated(func() { v.onTCPIPHostGameClicked() }) v.btnTCPIPHostGame.OnActivated(func() { v.onTCPIPHostGameClicked() })
v.btnTCPIPJoinGame = v.uiManager.NewButton(d2ui.ButtonTypeWide, "JOIN GAME") v.btnTCPIPJoinGame = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.asset.TranslateLabel(tcpIPJoinGameLabel))
v.btnTCPIPJoinGame.SetPosition(tcpJoinBtnX, tcpJoinBtnY) v.btnTCPIPJoinGame.SetPosition(tcpJoinBtnX, tcpJoinBtnY)
v.btnTCPIPJoinGame.OnActivated(func() { v.onTCPIPJoinGameClicked() }) v.btnTCPIPJoinGame.OnActivated(func() { v.onTCPIPJoinGameClicked() })
} }
@ -645,5 +717,5 @@ func (v *MainMenu) getLocalIP() string {
v.Warning("no IPv4 Address could be found") v.Warning("no IPv4 Address could be found")
return "no IPv4 Address could be found" return v.asset.TranslateLabel(ipNotFoundLabel)
} }

View File

@ -416,7 +416,7 @@ func (v *SelectHeroClass) createLabels() {
halfFontWidth := fontWidth / half halfFontWidth := fontWidth / half
v.headingLabel.SetPosition(headingX-halfFontWidth, headingY) v.headingLabel.SetPosition(headingX-halfFontWidth, headingY)
v.headingLabel.SetText("Select Hero Class") v.headingLabel.SetText(v.asset.TranslateLabel(selectHeroClassLabel))
v.headingLabel.Alignment = d2ui.HorizontalAlignCenter v.headingLabel.Alignment = d2ui.HorizontalAlignCenter
v.heroClassLabel = v.uiManager.NewLabel(d2resource.Font30, d2resource.PaletteUnits) v.heroClassLabel = v.uiManager.NewLabel(d2resource.Font30, d2resource.PaletteUnits)
@ -437,22 +437,22 @@ func (v *SelectHeroClass) createLabels() {
v.heroNameLabel = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteUnits) v.heroNameLabel = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteUnits)
v.heroNameLabel.Alignment = d2ui.HorizontalAlignLeft v.heroNameLabel.Alignment = d2ui.HorizontalAlignLeft
v.heroNameLabel.SetText(d2ui.ColorTokenize("Character Name", d2ui.ColorTokenGold)) v.heroNameLabel.SetText(d2ui.ColorTokenize(v.asset.TranslateLabel(charNameLabel), d2ui.ColorTokenGold))
v.heroNameLabel.SetPosition(heroNameLabelX, heroNameLabelY) v.heroNameLabel.SetPosition(heroNameLabelX, heroNameLabelY)
v.expansionCharLabel = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteUnits) v.expansionCharLabel = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteUnits)
v.expansionCharLabel.Alignment = d2ui.HorizontalAlignLeft v.expansionCharLabel.Alignment = d2ui.HorizontalAlignLeft
v.expansionCharLabel.SetText(d2ui.ColorTokenize("EXPANSION CHARACTER", d2ui.ColorTokenGold)) v.expansionCharLabel.SetText(d2ui.ColorTokenize(v.asset.TranslateString("#803"), d2ui.ColorTokenGold))
v.expansionCharLabel.SetPosition(expansionLabelX, expansionLabelY) v.expansionCharLabel.SetPosition(expansionLabelX, expansionLabelY)
v.hardcoreCharLabel = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteUnits) v.hardcoreCharLabel = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteUnits)
v.hardcoreCharLabel.Alignment = d2ui.HorizontalAlignLeft v.hardcoreCharLabel.Alignment = d2ui.HorizontalAlignLeft
v.hardcoreCharLabel.SetText(d2ui.ColorTokenize("Hardcore", d2ui.ColorTokenGold)) v.hardcoreCharLabel.SetText(d2ui.ColorTokenize(v.asset.TranslateLabel(hardCoreLabel), d2ui.ColorTokenGold))
v.hardcoreCharLabel.SetPosition(hardcoreLabelX, hardcoreLabelY) v.hardcoreCharLabel.SetPosition(hardcoreLabelX, hardcoreLabelY)
} }
func (v *SelectHeroClass) createButtons() { func (v *SelectHeroClass) createButtons() {
v.exitButton = v.uiManager.NewButton(d2ui.ButtonTypeMedium, "EXIT") v.exitButton = v.uiManager.NewButton(d2ui.ButtonTypeMedium, v.asset.TranslateLabel(exitLabel))
v.exitButton.SetPosition(selHeroExitBtnX, selHeroExitBtnY) v.exitButton.SetPosition(selHeroExitBtnX, selHeroExitBtnY)
v.exitButton.OnActivated(func() { v.onExitButtonClicked() }) v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
@ -685,25 +685,26 @@ func (v *SelectHeroClass) updateHeroText() {
return return
case d2enum.HeroBarbarian: case d2enum.HeroBarbarian:
v.heroClassLabel.SetText(v.asset.TranslateString("partycharbar")) 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: case d2enum.HeroNecromancer:
v.heroClassLabel.SetText(v.asset.TranslateString("partycharnec")) 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: case d2enum.HeroPaladin:
v.heroClassLabel.SetText(v.asset.TranslateString("partycharpal")) 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: case d2enum.HeroAssassin:
v.heroClassLabel.SetText(v.asset.TranslateString("partycharass")) 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: case d2enum.HeroSorceress:
v.heroClassLabel.SetText(v.asset.TranslateString("partycharsor")) 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: case d2enum.HeroAmazon:
v.heroClassLabel.SetText(v.asset.TranslateString("partycharama")) 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: case d2enum.HeroDruid:
v.heroClassLabel.SetText(v.asset.TranslateString("partychardru")) 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 +713,15 @@ const (
twoLine = 2 twoLine = 2
) )
func (v *SelectHeroClass) setDescLabels(descKey string) { func (v *SelectHeroClass) setDescLabels(descKey int, key string) {
heroDesc := v.asset.TranslateString(descKey) var heroDesc string
if key != "" {
heroDesc = v.asset.TranslateString(key)
} else {
heroDesc = v.asset.TranslateLabel(descKey)
}
parts := d2util.SplitIntoLinesWithMaxWidth(heroDesc, heroDescCharWidth) parts := d2util.SplitIntoLinesWithMaxWidth(heroDesc, heroDescCharWidth)
numLines := len(parts) numLines := len(parts)

View File

@ -254,7 +254,7 @@ func (s *HeroStatsPanel) renderStaticLabels(target d2interface.Surface) {
centerAlign bool centerAlign bool
}{ }{
{labelHeroNameX, labelHeroNameY, s.heroName, d2resource.Font16, true}, {labelHeroNameX, labelHeroNameY, s.heroName, d2resource.Font16, true},
{labelHeroClassX, labelHeroClassY, s.asset.TranslateHeroClass(s.heroClass), d2resource.Font16, true}, {labelHeroClassX, labelHeroClassY, s.asset.TranslateString(s.heroClass), d2resource.Font16, true},
{labelLevelX, labelLevelY, s.asset.TranslateString("strchrlvl"), d2resource.Font6, true}, {labelLevelX, labelLevelY, s.asset.TranslateString("strchrlvl"), d2resource.Font6, true},
{labelExperienceX, labelExperienceY, s.asset.TranslateString("strchrexp"), d2resource.Font6, true}, {labelExperienceX, labelExperienceY, s.asset.TranslateString("strchrexp"), d2resource.Font6, true},