Internationalization of the public mod (JavaScript and GUI XML side)
It includes a marvelous language selection menu developed by Yves. It also includes the introduction of a sprintf implementation for JavaScript, as well as translation helper functions that use JavaScript-side translation caching. This patch includes code by Yves, sanderd17, leper and Gallaecio. Ref #67 This was SVN commit r14954.
This commit is contained in:
parent
d6db5a466d
commit
e05c8263c5
154
binaries/data/mods/public/globalscripts/l10n.js
Normal file
154
binaries/data/mods/public/globalscripts/l10n.js
Normal file
@ -0,0 +1,154 @@
|
||||
var g_translations = {};
|
||||
var g_pluralTranslations = {};
|
||||
var g_translationsWithContext = {};
|
||||
var g_pluralTranslationsWithContext = {};
|
||||
|
||||
// Translates the specified English message into the current language.
|
||||
//
|
||||
// This function relies on the g_translations cache when possible. You should use this function instead of
|
||||
// Engine.Translate() whenever you can to minimize the number of C++ calls and string conversions involved.
|
||||
function translate(message)
|
||||
{
|
||||
var translation = g_translations[message];
|
||||
if (!translation)
|
||||
return g_translations[message] = Engine.Translate(message);
|
||||
return translation;
|
||||
}
|
||||
|
||||
|
||||
// Translates the specified English message into the current language for the specified number.
|
||||
//
|
||||
// This function relies on the g_pluralTranslations cache when possible. You should use this function instead of
|
||||
// Engine.TranslatePlural() whenever you can to minimize the number of C++ calls and string conversions involved.
|
||||
function translatePlural(singularMessage, pluralMessage, number)
|
||||
{
|
||||
var translation = g_pluralTranslations[singularMessage];
|
||||
if (!translation)
|
||||
g_pluralTranslations[singularMessage] = {};
|
||||
|
||||
var pluralTranslation = g_pluralTranslations[singularMessage][number];
|
||||
if (!pluralTranslation)
|
||||
return g_pluralTranslations[singularMessage][number] = Engine.TranslatePlural(singularMessage, pluralMessage, number);
|
||||
|
||||
return pluralTranslation;
|
||||
}
|
||||
|
||||
|
||||
// Translates the specified English message into the current language for the specified context.
|
||||
//
|
||||
// This function relies on the g_translationsWithContext cache when possible. You should use this function instead of
|
||||
// Engine.TranslateWithContext() whenever you can to minimize the number of C++ calls and string conversions involved.
|
||||
function translateWithContext(context, message)
|
||||
{
|
||||
var translationContext = g_translationsWithContext[context];
|
||||
if (!translationContext)
|
||||
g_translationsWithContext[context] = {}
|
||||
|
||||
var translationWithContext = g_translationsWithContext[context][message];
|
||||
if (!translationWithContext)
|
||||
return g_translationsWithContext[context][message] = Engine.TranslateWithContext(context, message);
|
||||
|
||||
return translationWithContext;
|
||||
}
|
||||
|
||||
|
||||
// Translates the specified English message into the current language for the specified context and number.
|
||||
//
|
||||
// This function relies on the g_pluralTranslationsWithContext cache when possible. You should use this function instead of
|
||||
// Engine.TranslatePluralWithContext() whenever you can to minimize the number of C++ calls and string conversions involved.
|
||||
function translatePluralWithContext(context, singularMessage, pluralMessage, number)
|
||||
{
|
||||
var translationContext = g_pluralTranslationsWithContext[context];
|
||||
if (!translationContext)
|
||||
g_pluralTranslationsWithContext[context] = {};
|
||||
|
||||
var translationWithContext = g_pluralTranslationsWithContext[context][singularMessage];
|
||||
if (!translationWithContext)
|
||||
g_pluralTranslationsWithContext[context][singularMessage] = {};
|
||||
|
||||
var pluralTranslationWithContext = g_pluralTranslationsWithContext[context][singularMessage][number];
|
||||
if (!pluralTranslationWithContext)
|
||||
return g_pluralTranslationsWithContext[context][singularMessage][number] = Engine.TranslatePluralWithContext(context, singularMessage, pluralMessage, number);
|
||||
|
||||
return pluralTranslationWithContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates any string value in the specified JavaScript object
|
||||
* that is associated with a key included in the specified keys array.
|
||||
*
|
||||
* it accepts an object in the form of
|
||||
*
|
||||
* {
|
||||
* translatedString1: "my first message",
|
||||
* unTranslatedString1: "some English string",
|
||||
* ignoredObject: {
|
||||
* translatedString2: "my second message",
|
||||
* unTranslatedString2: "some English string"
|
||||
* },
|
||||
* translatedObject1: {
|
||||
* message: "my third singular message",
|
||||
* context: "message context",
|
||||
* },
|
||||
* translatedObject2: {
|
||||
* list: ["list", "of", "strings"],
|
||||
* context: "message context",
|
||||
* },
|
||||
* }
|
||||
*
|
||||
* Together with a keys list to translate the strings and objects
|
||||
* ["translatedString1", "translatedString2", "translatedObject1",
|
||||
* "translatedObject2"]
|
||||
*
|
||||
* The result will be (f.e. in Dutch)
|
||||
* {
|
||||
* translatedString1: "mijn eerste bericht",
|
||||
* unTranslatedString1: "some English string",
|
||||
* ignoredObject: {
|
||||
* translatedString2: "mijn tweede bericht",
|
||||
* unTranslatedString2: "some English string"
|
||||
* },
|
||||
* translatedObject1: "mijn derde bericht",
|
||||
* translatedObject2: "lijst, van, teksten",
|
||||
* }
|
||||
*
|
||||
* So you see that the keys array can also contain lower-level keys,
|
||||
* And that you can include objects in the keys array to translate
|
||||
* them with a context, or to join a list of translations.
|
||||
*/
|
||||
function translateObjectKeys(object, keys) {
|
||||
for (var property in object)
|
||||
{
|
||||
if (keys.indexOf(property) > -1)
|
||||
{
|
||||
if (typeof object[property] == "string")
|
||||
object[property] = translate(object[property]);
|
||||
else if (object[property] instanceof Object)
|
||||
{
|
||||
// the translation function
|
||||
var trans = translate;
|
||||
if (object[property].context)
|
||||
trans = function(msg) { return translateWithContext(object[property].context, msg);};
|
||||
|
||||
if (object[property].message)
|
||||
object[property] = trans(object[property].message);
|
||||
else if (object[property].list)
|
||||
{
|
||||
var translatedList = object[property].list.map(trans);
|
||||
object[property] = translatedList.join(translateWithContext("enumeration", ", "));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (object[property] instanceof Object)
|
||||
translateObjectKeys(object[property], keys);
|
||||
}
|
||||
}
|
||||
|
||||
function markForTranslation(message) {
|
||||
return message;
|
||||
}
|
||||
|
||||
function markForTranslationWithContext(context, message) {
|
||||
return message;
|
||||
}
|
||||
|
183
binaries/data/mods/public/globalscripts/sprintf.js
Normal file
183
binaries/data/mods/public/globalscripts/sprintf.js
Normal file
@ -0,0 +1,183 @@
|
||||
/**
|
||||
sprintf() for JavaScript 0.7-beta1
|
||||
http://www.diveintojavascript.com/projects/javascript-sprintf
|
||||
|
||||
Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of sprintf() for JavaScript nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
Changelog:
|
||||
2010.09.06 - 0.7-beta1
|
||||
- features: vsprintf, support for named placeholders
|
||||
- enhancements: format cache, reduced global namespace pollution
|
||||
|
||||
2010.05.22 - 0.6:
|
||||
- reverted to 0.4 and fixed the bug regarding the sign of the number 0
|
||||
Note:
|
||||
Thanks to Raphael Pigulla <raph (at] n3rd [dot) org> (http://www.n3rd.org/)
|
||||
who warned me about a bug in 0.5, I discovered that the last update was
|
||||
a regress. I appologize for that.
|
||||
|
||||
2010.05.09 - 0.5:
|
||||
- bug fix: 0 is now preceeded with a + sign
|
||||
- bug fix: the sign was not at the right position on padded results (Kamal Abdali)
|
||||
- switched from GPL to BSD license
|
||||
|
||||
2007.10.21 - 0.4:
|
||||
- unit test and patch (David Baird)
|
||||
|
||||
2007.09.17 - 0.3:
|
||||
- bug fix: no longer throws exception on empty paramenters (Hans Pufal)
|
||||
|
||||
2007.09.11 - 0.2:
|
||||
- feature: added argument swapping
|
||||
|
||||
2007.04.03 - 0.1:
|
||||
- initial release
|
||||
**/
|
||||
|
||||
var sprintf = (function() {
|
||||
function get_type(variable) {
|
||||
return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
|
||||
}
|
||||
function str_repeat(input, multiplier) {
|
||||
for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */}
|
||||
return output.join('');
|
||||
}
|
||||
|
||||
var str_format = function() {
|
||||
if (!str_format.cache.hasOwnProperty(arguments[0])) {
|
||||
str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
|
||||
}
|
||||
return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
|
||||
};
|
||||
|
||||
str_format.format = function(parse_tree, argv) {
|
||||
var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
|
||||
for (i = 0; i < tree_length; i++) {
|
||||
node_type = get_type(parse_tree[i]);
|
||||
if (node_type === 'string') {
|
||||
output.push(parse_tree[i]);
|
||||
}
|
||||
else if (node_type === 'array') {
|
||||
match = parse_tree[i]; // convenience purposes only
|
||||
if (match[2]) { // keyword argument
|
||||
arg = argv[cursor];
|
||||
for (k = 0; k < match[2].length; k++) {
|
||||
if (!arg.hasOwnProperty(match[2][k])) {
|
||||
throw(sprintf(Engine.Translate('[sprintf] property "%s" does not exist'), match[2][k]));
|
||||
}
|
||||
arg = arg[match[2][k]];
|
||||
}
|
||||
}
|
||||
else if (match[1]) { // positional argument (explicit)
|
||||
arg = argv[match[1]];
|
||||
}
|
||||
else { // positional argument (implicit)
|
||||
arg = argv[cursor++];
|
||||
}
|
||||
|
||||
if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
|
||||
throw(sprintf(Engine.Translate('[sprintf] expecting number but found %s'), get_type(arg)));
|
||||
}
|
||||
switch (match[8]) {
|
||||
case 'b': arg = arg.toString(2); break;
|
||||
case 'c': arg = String.fromCharCode(arg); break;
|
||||
case 'd': arg = parseInt(arg, 10); break;
|
||||
case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
|
||||
case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
|
||||
case 'o': arg = arg.toString(8); break;
|
||||
case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
|
||||
case 'u': arg = Math.abs(arg); break;
|
||||
case 'x': arg = arg.toString(16); break;
|
||||
case 'X': arg = arg.toString(16).toUpperCase(); break;
|
||||
}
|
||||
arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
|
||||
pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
|
||||
pad_length = match[6] - String(arg).length;
|
||||
pad = match[6] ? str_repeat(pad_character, pad_length) : '';
|
||||
output.push(match[5] ? arg + pad : pad + arg);
|
||||
}
|
||||
}
|
||||
return output.join('');
|
||||
};
|
||||
|
||||
str_format.cache = {};
|
||||
|
||||
str_format.parse = function(fmt) {
|
||||
var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
|
||||
while (_fmt) {
|
||||
if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
|
||||
parse_tree.push(match[0]);
|
||||
}
|
||||
else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
|
||||
parse_tree.push('%');
|
||||
}
|
||||
else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
|
||||
if (match[2]) {
|
||||
arg_names |= 1;
|
||||
var field_list = [], replacement_field = match[2], field_match = [];
|
||||
if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
|
||||
field_list.push(field_match[1]);
|
||||
while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
|
||||
if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
|
||||
field_list.push(field_match[1]);
|
||||
}
|
||||
else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
|
||||
field_list.push(field_match[1]);
|
||||
}
|
||||
else {
|
||||
throw(Engine.Translate('[sprintf] huh?'));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw(Engine.Translate('[sprintf] huh?'));
|
||||
}
|
||||
match[2] = field_list;
|
||||
}
|
||||
else {
|
||||
arg_names |= 2;
|
||||
}
|
||||
if (arg_names === 3) {
|
||||
throw(Engine.Translate('[sprintf] mixing positional and named placeholders is not (yet) supported'));
|
||||
}
|
||||
parse_tree.push(match);
|
||||
}
|
||||
else {
|
||||
throw(sprintf(Engine.Translate('[sprintf] No placeholder found in the ‘%(formatString)s’ format string. Maybe you used an incorrect syntax for your placeholder?'), { formatString: _fmt } ));
|
||||
}
|
||||
_fmt = _fmt.substring(match[0].length);
|
||||
}
|
||||
return parse_tree;
|
||||
};
|
||||
|
||||
return str_format;
|
||||
})();
|
||||
|
||||
var vsprintf = function(fmt, argv) {
|
||||
argv.unshift(fmt);
|
||||
return sprintf.apply(null, argv);
|
||||
};
|
@ -4,12 +4,14 @@ var g_PlayerSlot;
|
||||
function init(settings)
|
||||
{
|
||||
g_PlayerSlot = settings.playerSlot;
|
||||
|
||||
translateObjectKeys(settings.ais, ["name", "description"]);
|
||||
g_AIs = [
|
||||
{id: "", data: {name: "None", description: "AI will be disabled for this player."}}
|
||||
{id: "", data: {name: translateWithContext("ai", "None"), description: translate("AI will be disabled for this player.")}}
|
||||
].concat(settings.ais);
|
||||
|
||||
var aiSelection = Engine.GetGUIObjectByName("aiSelection");
|
||||
aiSelection.list = [ ai.data.name for each (ai in g_AIs) ];
|
||||
aiSelection.list = [ translate(ai.data.name) for each (ai in g_AIs) ];
|
||||
|
||||
var selected = 0;
|
||||
for (var i = 0; i < g_AIs.length; ++i)
|
||||
@ -23,7 +25,7 @@ function init(settings)
|
||||
aiSelection.selected = selected;
|
||||
|
||||
var aiDiff = Engine.GetGUIObjectByName("aiDifficulty");
|
||||
aiDiff.list = [ "Sandbox", "Easy", "Medium", "Hard", "Very Hard" ];
|
||||
aiDiff.list = [translate("Sandbox"), translate("Easy"), translate("Medium"), translate("Hard"), translate("Very Hard")];
|
||||
aiDiff.selected = settings.difficulty;
|
||||
}
|
||||
|
||||
|
@ -9,11 +9,13 @@
|
||||
|
||||
<object type="image" style="ModernDialog" size="50%-200 40%-140 50%+200 40%+180">
|
||||
|
||||
<object style="TitleText" type="text" size="50%-128 -16 50%+128 16">AI Configuration</object>
|
||||
<object style="TitleText" type="text" size="50%-128 -16 50%+128 16">
|
||||
<translatableAttribute id="caption">AI Configuration</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object size="50%-128 30 50%+128 80">
|
||||
<object type="text" style="ModernRightLabelText" size="-10 0 90 50%">
|
||||
AI Player
|
||||
<translatableAttribute id="caption">AI Player</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object name="aiSelection" type="dropdown" style="ModernDropDown" size="50%-24 0 50%+136 28">
|
||||
@ -21,7 +23,7 @@
|
||||
</object>
|
||||
|
||||
<object type="text" style="ModernRightLabelText" size="-10 35 90 50%+35">
|
||||
AI Difficulty
|
||||
<translatableAttribute id="caption">AI Difficulty</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object name="aiDifficulty" type="dropdown" style="ModernDropDown" size="50%-24 35 50%+136 63">
|
||||
@ -37,12 +39,12 @@
|
||||
</object>
|
||||
|
||||
<object type="button" style="StoneButton" size="50%-144 100%-60 50%-16 100%-32">
|
||||
OK
|
||||
<translatableAttribute id="caption">OK</translatableAttribute>
|
||||
<action on="Press">returnAI();</action>
|
||||
</object>
|
||||
|
||||
<object type="button" style="StoneButton" size="50%+16 100%-60 50%+144 100%-32">
|
||||
Cancel
|
||||
<translatableAttribute id="caption">Cancel</translatableAttribute>
|
||||
<action on="Press">Engine.PopGuiPage();</action>
|
||||
</object>
|
||||
</object>
|
||||
|
@ -80,37 +80,41 @@ function heading(string, size)
|
||||
// Called when user selects civ from dropdown
|
||||
function selectCiv(code)
|
||||
{
|
||||
var escapeChars = function(str)
|
||||
{
|
||||
return str.replace(/\[/g, "[").replace(/\]/g, "]").replace(/"/g, """);
|
||||
};
|
||||
|
||||
var civInfo = g_CivData[code];
|
||||
|
||||
if(!civInfo)
|
||||
error("Error loading civ data for \""+code+"\"");
|
||||
error(sprintf("Error loading civ data for \"%(code)s\"", { code: code }));
|
||||
|
||||
// Update civ gameplay display
|
||||
Engine.GetGUIObjectByName("civGameplayHeading").caption = heading(civInfo.Name+" Gameplay", 16);
|
||||
|
||||
Engine.GetGUIObjectByName("civGameplayHeading").caption = heading(sprintf(translate("%(civilization)s Gameplay"), { civilization: civInfo.Name }), 16);
|
||||
|
||||
// Bonuses
|
||||
var bonusCaption = heading("Civilization Bonus"+(civInfo.CivBonuses.length == 1 ? "" : "es"), 12) + '\n';
|
||||
var bonusCaption = heading(translatePlural("Civilization Bonus", "Civilization Bonuses", civInfo.CivBonuses.length), 12) + '\n';
|
||||
|
||||
for(var i = 0; i < civInfo.CivBonuses.length; ++i)
|
||||
{
|
||||
bonusCaption += '[color="' + TEXTCOLOR + '"][font="serif-bold-14"]' + civInfo.CivBonuses[i].Name + '[/font] [icon="iconInfo" tooltip="'
|
||||
+ civInfo.CivBonuses[i].History + '" tooltip_style="civInfoTooltip"]\n ' + civInfo.CivBonuses[i].Description + '\n[/color]';
|
||||
+ escapeChars(civInfo.CivBonuses[i].History) + '" tooltip_style="civInfoTooltip"]\n ' + civInfo.CivBonuses[i].Description + '\n[/color]';
|
||||
}
|
||||
|
||||
bonusCaption += heading("Team Bonus"+(civInfo.TeamBonuses.length == 1 ? "" : "es"), 12) + '\n';
|
||||
bonusCaption += heading(translatePlural("Team Bonus", "Team Bonuses", civInfo.TeamBonuses.length), 12) + '\n';
|
||||
|
||||
for(var i = 0; i < civInfo.TeamBonuses.length; ++i)
|
||||
{
|
||||
bonusCaption += '[color="' + TEXTCOLOR + '"][font="serif-bold-14"]' + civInfo.TeamBonuses[i].Name + '[/font] [icon="iconInfo" tooltip="'
|
||||
+ civInfo.TeamBonuses[i].History + '" tooltip_style="civInfoTooltip"]\n ' + civInfo.TeamBonuses[i].Description + '\n[/color]';
|
||||
+ escapeChars(civInfo.TeamBonuses[i].History) + '" tooltip_style="civInfoTooltip"]\n ' + civInfo.TeamBonuses[i].Description + '\n[/color]';
|
||||
}
|
||||
|
||||
Engine.GetGUIObjectByName("civBonuses").caption = bonusCaption;
|
||||
|
||||
|
||||
// Special techs / buildings
|
||||
var techCaption = heading("Special Technologies", 12) + '\n';
|
||||
var techCaption = heading(translate("Special Technologies"), 12) + '\n';
|
||||
|
||||
for(var i = 0; i < civInfo.Factions.length; ++i)
|
||||
{
|
||||
@ -118,23 +122,23 @@ function selectCiv(code)
|
||||
for(var j = 0; j < faction.Technologies.length; ++j)
|
||||
{
|
||||
techCaption += '[color="' + TEXTCOLOR + '"][font="serif-bold-14"]' + faction.Technologies[j].Name + '[/font] [icon="iconInfo" tooltip="'
|
||||
+ faction.Technologies[j].History + '" tooltip_style="civInfoTooltip"]\n ' + faction.Technologies[j].Description + '\n[/color]';
|
||||
+ escapeChars(faction.Technologies[j].History) + '" tooltip_style="civInfoTooltip"]\n ' + faction.Technologies[j].Description + '\n[/color]';
|
||||
}
|
||||
}
|
||||
|
||||
techCaption += heading("Special Building"+(civInfo.Structures.length == 1 ? "" : "s"), 12) + '\n';
|
||||
techCaption += heading(translatePlural("Special Building", "Special Buildings", civInfo.Structures.length), 12) + '\n';
|
||||
|
||||
for(var i = 0; i < civInfo.Structures.length; ++i)
|
||||
{
|
||||
techCaption += '[color="' + TEXTCOLOR + '"][font="serif-bold-14"]' + civInfo.Structures[i].Name + '[/font][/color] [icon="iconInfo" tooltip="'
|
||||
+ civInfo.Structures[i].History + '" tooltip_style="civInfoTooltip"]\n';
|
||||
+ escapeChars(civInfo.Structures[i].History) + '" tooltip_style="civInfoTooltip"]\n';
|
||||
}
|
||||
|
||||
Engine.GetGUIObjectByName("civTechs").caption = techCaption;
|
||||
|
||||
|
||||
// Heroes
|
||||
var heroCaption = heading("Heroes", 12) + '\n';
|
||||
var heroCaption = heading(translate("Heroes"), 12) + '\n';
|
||||
|
||||
for(var i = 0; i < civInfo.Factions.length; ++i)
|
||||
{
|
||||
@ -142,7 +146,7 @@ function selectCiv(code)
|
||||
for(var j = 0; j < faction.Heroes.length; ++j)
|
||||
{
|
||||
heroCaption += '[color="' + TEXTCOLOR + '"][font="serif-bold-14"]' + faction.Heroes[j].Name + '[/font][/color] [icon="iconInfo" tooltip="'
|
||||
+ faction.Heroes[j].History + '" tooltip_style="civInfoTooltip"]\n';
|
||||
+ escapeChars(faction.Heroes[j].History) + '" tooltip_style="civInfoTooltip"]\n';
|
||||
}
|
||||
heroCaption += '\n';
|
||||
}
|
||||
@ -151,6 +155,6 @@ function selectCiv(code)
|
||||
|
||||
|
||||
// Update civ history display
|
||||
Engine.GetGUIObjectByName("civHistoryHeading").caption = heading("History of the " + civInfo.Name, 16);
|
||||
Engine.GetGUIObjectByName("civHistoryHeading").caption = heading(sprintf(translate("History of the %(civilization)s"), { civilization: civInfo.Name }), 16);
|
||||
Engine.GetGUIObjectByName("civHistoryText").caption = civInfo.History;
|
||||
}
|
||||
|
@ -10,9 +10,11 @@
|
||||
<!-- Add a translucent black background to fade out the menu page -->
|
||||
<object type="image" z="0" sprite="bkTranslucent"/>
|
||||
|
||||
<object type="image" style="ModernDialog" size="50%-466 50%-316 50%+466 50%+316">
|
||||
<object type="image" style="ModernDialog" size="50%-500 50%-368 50%+500 50%+370">
|
||||
|
||||
<object style="TitleText" type="text" size="50%-128 -16 50%+128 16">Civilizations</object>
|
||||
<object style="TitleText" type="text" size="50%-128 -16 50%+128 16">
|
||||
<translatableAttribute id="caption">Civilizations</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<!-- Civ selection -->
|
||||
<object size="25 10 100% 30">
|
||||
@ -22,8 +24,8 @@
|
||||
font="serif-bold-20"
|
||||
textcolor="white"
|
||||
text_align="left"
|
||||
size="50%-320 10 50%-96 48">
|
||||
Civilization Selection
|
||||
size="50%-420 10 50%-96 48">
|
||||
<translatableAttribute id="caption">Civilization Selection</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object name="civSelection" type="dropdown" style="ModernDropDown" size="50%-96 10 50%+96 40">
|
||||
@ -112,7 +114,8 @@
|
||||
type="button"
|
||||
style="StoneButton"
|
||||
size="100%-164 100%-52 100%-24 100%-24"
|
||||
>Close
|
||||
>
|
||||
<translatableAttribute id="caption">Close</translatableAttribute>
|
||||
<action on="Press">
|
||||
<![CDATA[
|
||||
Engine.PopGuiPage();
|
||||
|
@ -14,10 +14,11 @@ function loadCivData()
|
||||
for each (var filename in civFiles)
|
||||
{ // Parse data if valid file
|
||||
var data = parseJSONData(filename);
|
||||
translateObjectKeys(data, ["Name", "Description", "History", "Special"]);
|
||||
civData[data.Code] = data;
|
||||
}
|
||||
|
||||
return civData;
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
// ====================================================================
|
||||
|
@ -70,5 +70,5 @@ function messageBox (mbWidth, mbHeight, mbMessage, mbTitle, mbMode, mbButtonCapt
|
||||
|
||||
function updateFPS()
|
||||
{
|
||||
Engine.GetGUIObjectByName("fpsCounter").caption = "FPS: " + Engine.GetFPS();
|
||||
Engine.GetGUIObjectByName("fpsCounter").caption = sprintf(translate("FPS: %(fps)s"), { fps: Engine.GetFPS() });
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ function parseJSONData(pathname)
|
||||
var rawData = Engine.ReadFile(pathname);
|
||||
if (!rawData)
|
||||
{
|
||||
error("Failed to read file: "+pathname);
|
||||
error(sprintf("Failed to read file: %(path)s", { path: pathname }));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -73,13 +73,11 @@ function parseJSONData(pathname)
|
||||
// TODO: Need more info from the parser on why it failed: line number, position, etc!
|
||||
data = JSON.parse(rawData);
|
||||
if (!data)
|
||||
error("Failed to parse JSON data in: "+pathname+" (check for valid JSON data)");
|
||||
|
||||
|
||||
error(sprintf("Failed to parse JSON data in: %(path)s (check for valid JSON data)", { path: pathname }));
|
||||
}
|
||||
catch(err)
|
||||
{
|
||||
error(err.toString()+": parsing JSON data in "+pathname);
|
||||
error(sprintf("%(error)s: parsing JSON data in %(path)s", { error: err.toString(), path: pathname }));
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,7 +139,7 @@ function parseJSONFromDataFile(filename)
|
||||
var path = "simulation/data/"+filename;
|
||||
var rawData = Engine.ReadFile(path);
|
||||
if (!rawData)
|
||||
error("Failed to read file: "+path);
|
||||
error(sprintf("Failed to read file: %(path)s", { path: path }));
|
||||
|
||||
try
|
||||
{
|
||||
@ -152,7 +150,7 @@ function parseJSONFromDataFile(filename)
|
||||
}
|
||||
catch(err)
|
||||
{
|
||||
error(err.toString()+": parsing JSON data in "+path);
|
||||
error(sprintf("%(error)s: parsing JSON data in %(path)s", { error: err.toString(), path: path }));
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@ -169,7 +167,10 @@ function initPlayerDefaults()
|
||||
if (!data || !data.PlayerData)
|
||||
error("Failed to parse player defaults in player_defaults.json (check for valid JSON data)");
|
||||
else
|
||||
{
|
||||
translateObjectKeys(data.PlayerData, ["Name"])
|
||||
defaults = data.PlayerData;
|
||||
}
|
||||
|
||||
return defaults;
|
||||
}
|
||||
@ -191,6 +192,7 @@ function initMapSizes()
|
||||
error("Failed to parse map sizes in map_sizes.json (check for valid JSON data)");
|
||||
else
|
||||
{
|
||||
translateObjectKeys(data, ["Name", "LongName"]);
|
||||
for (var i = 0; i < data.Sizes.length; ++i)
|
||||
{
|
||||
sizes.shortNames.push(data.Sizes[i].Name);
|
||||
@ -221,6 +223,7 @@ function initGameSpeeds()
|
||||
error("Failed to parse game speeds in game_speeds.json (check for valid JSON data)");
|
||||
else
|
||||
{
|
||||
translateObjectKeys(data, ["Name"]);
|
||||
for (var i = 0; i < data.Speeds.length; ++i)
|
||||
{
|
||||
gameSpeeds.names.push(data.Speeds[i].Name);
|
||||
@ -250,16 +253,17 @@ function iColorToString(color)
|
||||
// ====================================================================
|
||||
|
||||
/**
|
||||
* Convert time in milliseconds to hh:mm:ss string representation.
|
||||
* Convert time in milliseconds to [hh:]mm:ss string representation.
|
||||
* @param time Time period in milliseconds (integer)
|
||||
* @return String representing time period
|
||||
*/
|
||||
function timeToString(time)
|
||||
{
|
||||
var hours = Math.floor(time / 1000 / 60 / 60);
|
||||
var minutes = Math.floor(time / 1000 / 60) % 60;
|
||||
var seconds = Math.floor(time / 1000) % 60;
|
||||
return hours + ':' + (minutes < 10 ? '0' + minutes : minutes) + ':' + (seconds < 10 ? '0' + seconds : seconds);
|
||||
if (time < 1000 * 60 * 60)
|
||||
var format = translate("mm:ss");
|
||||
else
|
||||
var format = translate("HH:mm:ss");
|
||||
return Engine.FormatMillisecondsIntoDateString(time, format);
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
|
@ -19,7 +19,7 @@ function cancelOnError(msg)
|
||||
width: 500,
|
||||
height: 200,
|
||||
message: '[font="serif-bold-18"]' + msg + '[/font]',
|
||||
title: "Loading Aborted",
|
||||
title: translate("Loading Aborted"),
|
||||
mode: 2
|
||||
});
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
function removeItem (objectName, pos)
|
||||
{
|
||||
if (Engine.GetGUIObjectByName (objectName) == null)
|
||||
Engine.Console_Write ("removeItem(): " + objectName + " not found.");
|
||||
Engine.Console_Write (sprintf(translate("%(functionName)s: %(object)s not found."), { functionName: "removeItem()", object: objectName }));
|
||||
|
||||
var list = Engine.GetGUIObjectByName (objectName).list;
|
||||
var selected = Engine.GetGUIObjectByName (objectName).selected;
|
||||
@ -41,7 +41,7 @@ function removeItem (objectName, pos)
|
||||
function addItem (objectName, pos, value)
|
||||
{
|
||||
if (Engine.GetGUIObjectByName (objectName) == null)
|
||||
Engine.Console_Write ("addItem(): " + objectName + " not found.");
|
||||
Engine.Console_Write (sprintf(translate("%(functionName)s: %(object)s not found."), { functionName: "addItem()", object: objectName }));
|
||||
|
||||
var list = Engine.GetGUIObjectByName (objectName).list;
|
||||
var selected = Engine.GetGUIObjectByName (objectName).selected;
|
||||
@ -66,7 +66,7 @@ function addItem (objectName, pos, value)
|
||||
function pushItem (objectName, value)
|
||||
{
|
||||
if (Engine.GetGUIObjectByName (objectName) == null)
|
||||
Engine.Console_Write ("pushItem(): " + objectName + " not found.");
|
||||
Engine.Console_Write (sprintf(translate("%(functionName)s: %(object)s not found."), { functionName: "pushItem()", object: objectName }));
|
||||
|
||||
var list = Engine.GetGUIObjectByName (objectName).list;
|
||||
list.push (value);
|
||||
@ -81,7 +81,7 @@ function pushItem (objectName, value)
|
||||
function popItem (objectName)
|
||||
{
|
||||
if (Engine.GetGUIObjectByName (objectName) == null)
|
||||
Engine.Console_Write ("popItem(): " + objectName + " not found.");
|
||||
Engine.Console_Write (sprintf(translate("%(functionName)s: %(object)s not found."), { functionName: "popItem()", object: objectName }));
|
||||
|
||||
var selected = Engine.GetGUIObjectByName (objectName).selected;
|
||||
removeItem(objectName, getNumItems(objectName)-1);
|
||||
@ -98,7 +98,7 @@ function popItem (objectName)
|
||||
function getNumItems (objectName)
|
||||
{
|
||||
if (Engine.GetGUIObjectByName (objectName) == null)
|
||||
Engine.Console_Write ("getNumItems(): " + objectName + " not found.");
|
||||
Engine.Console_Write (sprintf(translate("%(functionName)s: %(object)s not found."), { functionName: "getNumItems()", object: objectName }));
|
||||
|
||||
var list = Engine.GetGUIObjectByName(objectName).list;
|
||||
return list.length;
|
||||
@ -110,7 +110,7 @@ function getNumItems (objectName)
|
||||
function getItemValue (objectName, pos)
|
||||
{
|
||||
if (Engine.GetGUIObjectByName (objectName) == null)
|
||||
Engine.Console_Write ("getItemValue(): " + objectName + " not found.");
|
||||
Engine.Console_Write (sprintf(translate("%(functionName)s: %(object)s not found."), { functionName: "getItemValue()", object: objectName }));
|
||||
|
||||
var list = Engine.GetGUIObjectByName(objectName).list;
|
||||
return list[pos];
|
||||
@ -122,7 +122,7 @@ function getItemValue (objectName, pos)
|
||||
function getCurrItemValue (objectName)
|
||||
{
|
||||
if (Engine.GetGUIObjectByName (objectName) == null)
|
||||
Engine.Console_Write ("getCurrItemValue(): " + objectName + " not found.");
|
||||
Engine.Console_Write (sprintf(translate("%(functionName)s: %(object)s not found."), { functionName: "getCurrItemValue()", object: objectName }));
|
||||
|
||||
if (Engine.GetGUIObjectByName(objectName).selected == -1)
|
||||
return "";
|
||||
@ -136,8 +136,9 @@ function getCurrItemValue (objectName)
|
||||
// already in the list).
|
||||
function setCurrItemValue (objectName, string)
|
||||
{
|
||||
if (Engine.GetGUIObjectByName(objectName) == null) {
|
||||
Engine.Console_Write ("setCurrItemValue(): " + objectName + " not found.");
|
||||
if (Engine.GetGUIObjectByName(objectName) == null)
|
||||
{
|
||||
Engine.Console_Write (sprintf(translate("%(functionName)s: %(object)s not found."), { functionName: "setCurrItemValue()", object: objectName }));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -157,7 +158,7 @@ function setCurrItemValue (objectName, string)
|
||||
}
|
||||
|
||||
// Return -2 if failed to find value in list.
|
||||
Engine.Console_Write ("Requested string '" + string + "' not found in " + objectName + "'s list.");
|
||||
Engine.Console_Write (sprintf(translate("Requested string '%(string)s' not found in %(object)s's list."), { string: string, object: objectName }));
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -3,29 +3,21 @@ function sortDecreasingDate(a, b)
|
||||
return b.metadata.time - a.metadata.time;
|
||||
}
|
||||
|
||||
function twoDigits(n)
|
||||
{
|
||||
return n < 10 ? "0" + n : n;
|
||||
}
|
||||
|
||||
function generateLabel(metadata, engineInfo)
|
||||
{
|
||||
var t = new Date(metadata.time*1000);
|
||||
var date = t.getFullYear()+"-"+twoDigits(1+t.getMonth())+"-"+twoDigits(t.getDate());
|
||||
var time = twoDigits(t.getHours())+":"+twoDigits(t.getMinutes())+":"+twoDigits(t.getSeconds());
|
||||
var label = "["+date+" "+time+"] ";
|
||||
|
||||
var dateTimeString = Engine.FormatMillisecondsIntoDateString(metadata.time*1000, translate("yyyy-MM-dd HH:mm:ss"));
|
||||
var dateString = sprintf(translate("[%(date)s]"), { date: dateTimeString });
|
||||
if (engineInfo)
|
||||
{
|
||||
if (!hasSameVersion(metadata, engineInfo))
|
||||
label = "[color=\"red\"]" + label + "[/color]";
|
||||
dateString = "[color=\"red\"]" + dateString + "[/color]";
|
||||
else if (!hasSameMods(metadata, engineInfo))
|
||||
label = "[color=\"orange\"]" + label + "[/color]";
|
||||
dateString = "[color=\"orange\"]" + dateString + "[/color]";
|
||||
}
|
||||
|
||||
label += metadata.initAttributes.map.replace("maps/","")
|
||||
+ (metadata.description ? " - "+metadata.description : "");
|
||||
return label;
|
||||
if (metadata.description)
|
||||
return sprintf(translate("%(dateString)s %(map)s - %(description)s"), { dateString: dateString, map: metadata.initAttributes.map, description: metadata.description });
|
||||
else
|
||||
return sprintf(translate("%(dateString)s %(map)s"), { dateString: dateString, map: metadata.initAttributes.map });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,7 +53,7 @@ function newRandomSound(soundType, soundSubType, soundPrePath)
|
||||
var soundArray = Engine.BuildDirEntList(randomSoundPath, "*" + soundSubType + "*", false);
|
||||
if (soundArray.length == 0)
|
||||
{
|
||||
Engine.Console_Write ("Failed to find sounds matching '*"+soundSubType+"*'");
|
||||
Engine.Console_Write (sprintf("Failed to find sounds matching '*%(subtype)s*'", { soundSubType: subtype }));
|
||||
return undefined;
|
||||
}
|
||||
// Get a random number within the sound's range.
|
||||
@ -75,7 +75,7 @@ function newRandomSound(soundType, soundSubType, soundPrePath)
|
||||
return new AmbientSound(randomSoundPath);
|
||||
break;
|
||||
case "effect":
|
||||
Engine.Console_Write("am loading effect '*"+randomSoundPath+"*'");
|
||||
Engine.Console_Write(sprintf("am loading effect '*%(path)s*'", { path: randomSoundPath }));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -99,7 +99,7 @@ Music.prototype.updateState = function()
|
||||
break;
|
||||
|
||||
default:
|
||||
warn("Music.updateState(): Unknown music state: " + this.currentState);
|
||||
warn(sprintf("%(functionName)s: Unknown music state: %(state)s", { functionName: "Music.updateState()", state: this.currentState }));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -122,7 +122,7 @@ Music.prototype.storeTracks = function(civMusic)
|
||||
|
||||
if (type === undefined)
|
||||
{
|
||||
warn("Music.storeTracks(): Unrecognized music type: " + music.Type);
|
||||
warn(sprintf("%(functionName)s: Unrecognized music type: %(musicType)s", { functionName: "Music.storeTracks()", musicType: music.Type }));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -3,11 +3,11 @@ function getDisconnectReason(id)
|
||||
// Must be kept in sync with source/network/NetHost.h
|
||||
switch (id)
|
||||
{
|
||||
case 0: return "Unknown reason";
|
||||
case 1: return "Unexpected shutdown";
|
||||
case 2: return "Incorrect network protocol version";
|
||||
case 3: return "Game has already started";
|
||||
default: return "[Invalid value "+id+"]";
|
||||
case 0: return translate("Unknown reason");
|
||||
case 1: return translate("Unexpected shutdown");
|
||||
case 2: return translate("Incorrect network protocol version");
|
||||
case 3: return translate("Game has already started");
|
||||
default: return sprintf(translate("[Invalid value %(id)s]"), { id: id });
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,6 +16,6 @@ function reportDisconnect(reason)
|
||||
var reasontext = getDisconnectReason(reason);
|
||||
|
||||
messageBox(400, 200,
|
||||
"Lost connection to the server.\n\nReason: " + reasontext + ".",
|
||||
"Disconnected", 2);
|
||||
translate("Lost connection to the server.") + "\n\n" + sprintf(translate("Reason: %(reason)s."), { reason: reasontext }),
|
||||
translate("Disconnected"), 2);
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ function updateTimers()
|
||||
t[1]();
|
||||
} catch (e) {
|
||||
var stack = e.stack.trimRight().replace(/^/mg, ' '); // indent the stack trace
|
||||
error("Error in timer: "+e+"\n"+stack+"\n");
|
||||
error(sprintf("Error in timer: %(error)s", { error: e })+"\n"+stack+"\n");
|
||||
}
|
||||
delete g_Timers[id];
|
||||
}
|
||||
|
@ -4,13 +4,13 @@ const DEFAULT_NETWORKED_MAP = "Acropolis 01";
|
||||
const DEFAULT_OFFLINE_MAP = "Acropolis 01";
|
||||
|
||||
// TODO: Move these somewhere like simulation\data\game_types.json, Atlas needs them too
|
||||
const VICTORY_TEXT = ["Conquest", "Wonder", "None"];
|
||||
const VICTORY_TEXT = [translate("Conquest"), translate("Wonder"), translateWithContext("victory", "None")];
|
||||
const VICTORY_DATA = ["conquest", "wonder", "endless"];
|
||||
const VICTORY_DEFAULTIDX = 0;
|
||||
const POPULATION_CAP = ["50", "100", "150", "200", "250", "300", "Unlimited"];
|
||||
const POPULATION_CAP = ["50", "100", "150", "200", "250", "300", translate("Unlimited")];
|
||||
const POPULATION_CAP_DATA = [50, 100, 150, 200, 250, 300, 10000];
|
||||
const POPULATION_CAP_DEFAULTIDX = 5;
|
||||
const STARTING_RESOURCES = ["Very Low", "Low", "Medium", "High", "Very High", "Deathmatch"];
|
||||
const STARTING_RESOURCES = [translate("Very Low"), translate("Low"), translate("Medium"), translate("High"), translate("Very High"), translate("Deathmatch")];
|
||||
const STARTING_RESOURCES_DATA = [100, 300, 500, 1000, 3000, 50000];
|
||||
const STARTING_RESOURCES_DEFAULTIDX = 1;
|
||||
// Max number of players for any map
|
||||
@ -53,9 +53,10 @@ var g_CivData = {};
|
||||
var g_MapFilters = [];
|
||||
|
||||
// Warn about the AI's nonexistent naval map support.
|
||||
var g_NavalWarning = "\n\n[font=\"serif-bold-12\"][color=\"orange\"]Warning:[/color][/font] \
|
||||
The AI does not support naval maps and may cause severe performance issues. \
|
||||
Naval maps are recommended to be played with human opponents only.";
|
||||
var g_NavalWarning = "\n\n" + sprintf(
|
||||
translate("%(warning)s The AI does not support naval maps and may cause severe performance issues. Naval maps are recommended to be played with human opponents only."),
|
||||
{ warning: "[font=\"serif-bold-12\"][color=\"orange\"]" + translate("Warning:") + "[/color][/font]" }
|
||||
);
|
||||
|
||||
// To prevent the display locking up while we load the map metadata,
|
||||
// we'll start with a 'loading' message and switch to the main screen in the
|
||||
@ -81,7 +82,7 @@ function init(attribs)
|
||||
g_IsController = false;
|
||||
break;
|
||||
default:
|
||||
error("Unexpected 'type' in gamesetup init: "+attribs.type);
|
||||
error(sprintf("Unexpected 'type' in gamesetup init: %(unexpectedType)s", { unexpectedType: attribs.type }));
|
||||
}
|
||||
|
||||
if (attribs.serverName)
|
||||
@ -91,11 +92,11 @@ function init(attribs)
|
||||
var cancelButton = Engine.GetGUIObjectByName("cancelGame");
|
||||
if(!Engine.HasXmppClient())
|
||||
{
|
||||
cancelButton.tooltip = "Return to the main menu."
|
||||
cancelButton.tooltip = translate("Return to the main menu.");
|
||||
}
|
||||
else
|
||||
{
|
||||
cancelButton.tooltip = "Return to the lobby."
|
||||
cancelButton.tooltip = translate("Return to the lobby.");
|
||||
}
|
||||
|
||||
}
|
||||
@ -125,19 +126,20 @@ function initMain()
|
||||
|
||||
// Init map types
|
||||
var mapTypes = Engine.GetGUIObjectByName("mapTypeSelection");
|
||||
mapTypes.list = ["Skirmish","Random","Scenario"];
|
||||
mapTypes.list = [translateWithContext("map", "Skirmish"), translateWithContext("map", "Random"), translate("Scenario")];
|
||||
mapTypes.list_data = ["skirmish","random","scenario"];
|
||||
|
||||
// Setup map filters - will appear in order they are added
|
||||
addFilter("Default", function(settings) { return settings && (settings.Keywords === undefined || !keywordTestOR(settings.Keywords, ["naval", "demo", "hidden"])); });
|
||||
addFilter("Naval Maps", function(settings) { return settings && settings.Keywords !== undefined && keywordTestAND(settings.Keywords, ["naval"]); });
|
||||
addFilter("Demo Maps", function(settings) { return settings && settings.Keywords !== undefined && keywordTestAND(settings.Keywords, ["demo"]); });
|
||||
addFilter("All Maps", function(settings) { return true; });
|
||||
addFilter("default", translate("Default"), function(settings) { return settings && (settings.Keywords === undefined || !keywordTestOR(settings.Keywords, ["naval", "demo", "hidden"])); });
|
||||
addFilter("naval", translate("Naval Maps"), function(settings) { return settings && settings.Keywords !== undefined && keywordTestAND(settings.Keywords, ["naval"]); });
|
||||
addFilter("demo", translate("Demo Maps"), function(settings) { return settings && settings.Keywords !== undefined && keywordTestAND(settings.Keywords, ["demo"]); });
|
||||
addFilter("all", translate("All Maps"), function(settings) { return true; });
|
||||
|
||||
// Populate map filters dropdown
|
||||
var mapFilters = Engine.GetGUIObjectByName("mapFilterSelection");
|
||||
mapFilters.list = getFilters();
|
||||
g_GameAttributes.mapFilter = "Default";
|
||||
mapFilters.list = getFilterNames();
|
||||
mapFilters.list_data = getFilterIds();
|
||||
g_GameAttributes.mapFilter = "default";
|
||||
|
||||
// Setup controls for host only
|
||||
if (g_IsController)
|
||||
@ -341,7 +343,7 @@ function initMain()
|
||||
|
||||
// Populate team dropdowns
|
||||
var team = Engine.GetGUIObjectByName("playerTeam["+i+"]");
|
||||
team.list = ["None", "1", "2", "3", "4"];
|
||||
team.list = [translateWithContext("team", "None"), "1", "2", "3", "4"];
|
||||
team.list_data = [-1, 0, 1, 2, 3];
|
||||
team.selected = 0;
|
||||
|
||||
@ -512,9 +514,9 @@ function initCivNameList()
|
||||
var civListNames = [ civ.name for each (civ in civList) ];
|
||||
var civListCodes = [ civ.code for each (civ in civList) ];
|
||||
|
||||
// Add random civ to beginning of list
|
||||
civListNames.unshift("[color=\"orange\"]Random");
|
||||
civListCodes.unshift("random");
|
||||
// Add random civ to beginning of list
|
||||
civListNames.unshift("[color=\"orange\"]" + translateWithContext("civilization", "Random"));
|
||||
civListCodes.unshift("random");
|
||||
|
||||
// Update the dropdowns
|
||||
for (var i = 0; i < MAX_PLAYERS; ++i)
|
||||
@ -546,7 +548,7 @@ function initMapNameList()
|
||||
break;
|
||||
|
||||
default:
|
||||
error("initMapNameList: Unexpected map type '"+g_GameAttributes.mapType+"'");
|
||||
error(sprintf("initMapNameList: Unexpected map type '%(mapType)s'", { mapType: g_GameAttributes.mapType }));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -564,7 +566,7 @@ function initMapNameList()
|
||||
// Alphabetically sort the list, ignoring case
|
||||
mapList.sort(sortNameIgnoreCase);
|
||||
if (g_GameAttributes.mapType == "random")
|
||||
mapList.unshift({ "name": "[color=\"orange\"]Random[/color]", "file": "random" });
|
||||
mapList.unshift({ "name": "[color=\"orange\"]" + translateWithContext("map", "Random") + "[/color]", "file": "random" });
|
||||
|
||||
var mapListNames = [ map.name for each (map in mapList) ];
|
||||
var mapListFiles = [ map.file for each (map in mapList) ];
|
||||
@ -595,17 +597,21 @@ function loadMapData(name)
|
||||
case "scenario":
|
||||
case "skirmish":
|
||||
g_MapData[name] = Engine.LoadMapSettings(name);
|
||||
translateObjectKeys(g_MapData[name], ["Name", "Description"]);
|
||||
break;
|
||||
|
||||
case "random":
|
||||
if (name == "random")
|
||||
g_MapData[name] = {settings : {"Name" : "Random", "Description" : "Randomly selects a map from the list"}};
|
||||
g_MapData[name] = { settings: { "Name": translateWithContext("map", "Random"), "Description": translate("Randomly selects a map from the list") } };
|
||||
else
|
||||
{
|
||||
g_MapData[name] = parseJSONData(name+".json");
|
||||
translateObjectKeys(g_MapData[name], ["Name", "Description"]);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
error("loadMapData: Unexpected map type '"+g_GameAttributes.mapType+"'");
|
||||
error(sprintf("loadMapData: Unexpected map type '%(mapType)s'", { mapType: g_GameAttributes.mapType }));
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@ -705,7 +711,7 @@ function selectNumPlayers(num)
|
||||
if (g_IsNetworked)
|
||||
Engine.AssignNetworkPlayer(player, "");
|
||||
else
|
||||
g_PlayerAssignments = { "local": { "name": "You", "player": 1, "civ": "", "team": -1} };
|
||||
g_PlayerAssignments = { "local": { "name": translate("You"), "player": 1, "civ": "", "team": -1} };
|
||||
}
|
||||
}
|
||||
|
||||
@ -759,7 +765,7 @@ function selectMapType(type)
|
||||
break;
|
||||
|
||||
default:
|
||||
error("selectMapType: Unexpected map type '"+g_GameAttributes.mapType+"'");
|
||||
error(sprintf("selectMapType: Unexpected map type '%(mapType)s'", { mapType: g_GameAttributes.mapType }));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -768,7 +774,7 @@ function selectMapType(type)
|
||||
updateGameAttributes();
|
||||
}
|
||||
|
||||
function selectMapFilter(filterName)
|
||||
function selectMapFilter(id)
|
||||
{
|
||||
// Avoid recursion
|
||||
if (g_IsInGuiUpdate)
|
||||
@ -778,7 +784,7 @@ function selectMapFilter(filterName)
|
||||
if (g_IsNetworked && !g_IsController)
|
||||
return;
|
||||
|
||||
g_GameAttributes.mapFilter = filterName;
|
||||
g_GameAttributes.mapFilter = id;
|
||||
|
||||
initMapNameList();
|
||||
|
||||
@ -806,7 +812,7 @@ function selectMap(name)
|
||||
// Copy any new settings
|
||||
g_GameAttributes.map = name;
|
||||
g_GameAttributes.script = mapSettings.Script;
|
||||
if (mapData !== "Random")
|
||||
if (g_GameAttributes.map !== "random")
|
||||
for (var prop in mapSettings)
|
||||
g_GameAttributes.settings[prop] = mapSettings[prop];
|
||||
|
||||
@ -822,7 +828,7 @@ function selectMap(name)
|
||||
// Reset player assignments on map change
|
||||
if (!g_IsNetworked)
|
||||
{ // Slot 1
|
||||
g_PlayerAssignments = { "local": { "name": "You", "player": 1, "civ": "", "team": -1} };
|
||||
g_PlayerAssignments = { "local": { "name": translate("You"), "player": 1, "civ": "", "team": -1} };
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -897,8 +903,9 @@ function launchGame()
|
||||
usedName++;
|
||||
|
||||
// Assign civ specific names to AI players
|
||||
chosenName = translate(chosenName);
|
||||
if (usedName)
|
||||
g_GameAttributes.settings.PlayerData[i].Name = chosenName + " " + romanNumbers[usedName+1];
|
||||
g_GameAttributes.settings.PlayerData[i].Name = sprintf(translate("%(playerName)s %(romanNumber)s"), { playerName: chosenName, romanNumber: romanNumbers[usedName+1]});
|
||||
else
|
||||
g_GameAttributes.settings.PlayerData[i].Name = chosenName;
|
||||
}
|
||||
@ -947,7 +954,9 @@ function onGameAttributesChange()
|
||||
// Update some controls for clients
|
||||
if (!g_IsController)
|
||||
{
|
||||
Engine.GetGUIObjectByName("mapFilterText").caption = g_GameAttributes.mapFilter;
|
||||
var mapFilderSelection = Engine.GetGUIObjectByName("mapFilterText");
|
||||
var mapFilterId = mapFilderSelection.list_data.indexOf(g_GameAttributes.mapFilter);
|
||||
Engine.GetGUIObjectByName("mapFilterText").caption = mapFilderSelection.list[mapFilterId];
|
||||
var mapTypeSelection = Engine.GetGUIObjectByName("mapTypeSelection");
|
||||
var idx = mapTypeSelection.list_data.indexOf(g_GameAttributes.mapType);
|
||||
Engine.GetGUIObjectByName("mapTypeText").caption = mapTypeSelection.list[idx];
|
||||
@ -1012,7 +1021,7 @@ function onGameAttributesChange()
|
||||
switch (g_GameAttributes.mapType)
|
||||
{
|
||||
case "random":
|
||||
mapSizeDesc.hidden = false;
|
||||
mapSizeDesc.hidden = false;
|
||||
if (g_IsController)
|
||||
{
|
||||
//Host
|
||||
@ -1034,17 +1043,17 @@ function onGameAttributesChange()
|
||||
lockTeamsText.hidden = true;
|
||||
populationCapText.hidden = true;
|
||||
startingResourcesText.hidden = true;
|
||||
|
||||
mapSizeText.caption = "Map size:";
|
||||
|
||||
mapSizeText.caption = translate("Map size:");
|
||||
mapSize.selected = sizeIdx;
|
||||
revealMapText.caption = "Reveal map:";
|
||||
exploreMapText.caption = "Explore map:";
|
||||
revealMapText.caption = translate("Reveal map:");
|
||||
exploreMapText.caption = translate("Explored map:");
|
||||
revealMap.checked = (mapSettings.RevealMap ? true : false);
|
||||
exploreMap.checked = (mapSettings.ExploreMap ? true : false);
|
||||
|
||||
victoryConditionText.caption = "Victory condition:";
|
||||
victoryConditionText.caption = translate("Victory condition:");
|
||||
victoryCondition.selected = victoryIdx;
|
||||
lockTeamsText.caption = "Teams locked:";
|
||||
lockTeamsText.caption = translate("Teams locked:");
|
||||
lockTeams.checked = (mapSettings.LockTeams ? true : false);
|
||||
}
|
||||
else
|
||||
@ -1063,16 +1072,16 @@ function onGameAttributesChange()
|
||||
|
||||
numPlayersText.caption = numPlayers;
|
||||
mapSizeText.caption = g_MapSizes.names[sizeIdx];
|
||||
revealMapText.caption = (mapSettings.RevealMap ? "Yes" : "No");
|
||||
exploreMapText.caption = (mapSettings.ExloreMap ? "Yes" : "No");
|
||||
revealMapText.caption = (mapSettings.RevealMap ? translate("Yes") : translate("No"));
|
||||
exploreMapText.caption = (mapSettings.ExporeMap ? translate("Yes") : translate("No"));
|
||||
victoryConditionText.caption = VICTORY_TEXT[victoryIdx];
|
||||
lockTeamsText.caption = (mapSettings.LockTeams ? "Yes" : "No");
|
||||
lockTeamsText.caption = (mapSettings.LockTeams ? translate("Yes") : translate("No"));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "skirmish":
|
||||
mapSizeText.caption = "Default";
|
||||
mapSizeText.caption = translate("Default");
|
||||
numPlayersText.caption = numPlayers;
|
||||
numPlayersSelection.hidden = true;
|
||||
mapSize.hidden = true;
|
||||
@ -1096,14 +1105,14 @@ function onGameAttributesChange()
|
||||
populationCapText.hidden = true;
|
||||
startingResourcesText.hidden = true;
|
||||
|
||||
revealMapText.caption = "Reveal map:";
|
||||
exploreMapText.caption = "Explore map:";
|
||||
revealMapText.caption = translate("Reveal map:");
|
||||
exploreMapText.caption = translate("Explore map:");
|
||||
revealMap.checked = (mapSettings.RevealMap ? true : false);
|
||||
exploreMap.checked = (mapSettings.ExploreMap ? true : false);
|
||||
|
||||
victoryConditionText.caption = "Victory condition:";
|
||||
victoryConditionText.caption = translate("Victory condition:");
|
||||
victoryCondition.selected = victoryIdx;
|
||||
lockTeamsText.caption = "Teams locked:";
|
||||
lockTeamsText.caption = translate("Teams locked:");
|
||||
lockTeams.checked = (mapSettings.LockTeams ? true : false);
|
||||
}
|
||||
else
|
||||
@ -1119,10 +1128,10 @@ function onGameAttributesChange()
|
||||
startingResources.hidden = true;
|
||||
startingResourcesText.hidden = false;
|
||||
|
||||
revealMapText.caption = (mapSettings.RevealMap ? "Yes" : "No");
|
||||
exploreMapText.caption = (mapSettings.ExploreMap ? "Yes" : "No");
|
||||
revealMapText.caption = (mapSettings.RevealMap ? translate("Yes") : translate("No"));
|
||||
exploreMapText.caption = (mapSettings.ExploreMap ? translate("Yes") : translate("No"));
|
||||
victoryConditionText.caption = VICTORY_TEXT[victoryIdx];
|
||||
lockTeamsText.caption = (mapSettings.LockTeams ? "Yes" : "No");
|
||||
lockTeamsText.caption = (mapSettings.LockTeams ? translate("Yes") : translate("No"));
|
||||
}
|
||||
|
||||
break;
|
||||
@ -1149,17 +1158,17 @@ function onGameAttributesChange()
|
||||
startingResourcesText.hidden = false;
|
||||
|
||||
numPlayersText.caption = numPlayers;
|
||||
mapSizeText.caption = "Default";
|
||||
revealMapText.caption = (mapSettings.RevealMap ? "Yes" : "No");
|
||||
exploreMapText.caption = (mapSettings.ExploreMap ? "Yes" : "No");
|
||||
mapSizeText.caption = translate("Default");
|
||||
revealMapText.caption = (mapSettings.RevealMap ? translate("Yes") : translate("No"));
|
||||
exploreMapText.caption = (mapSettings.ExploreMap ? translate("Yes") : translate("No"));
|
||||
victoryConditionText.caption = VICTORY_TEXT[victoryIdx];
|
||||
lockTeamsText.caption = (mapSettings.LockTeams ? "Yes" : "No");
|
||||
lockTeamsText.caption = (mapSettings.LockTeams ? translate("Yes") : translate("No"));
|
||||
Engine.GetGUIObjectByName("populationCap").selected = POPULATION_CAP_DEFAULTIDX;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
error("onGameAttributesChange: Unexpected map type '"+g_GameAttributes.mapType+"'");
|
||||
error(sprintf("onGameAttributesChange: Unexpected map type '%(mapType)s'", { mapType: g_GameAttributes.mapType }));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1167,13 +1176,13 @@ function onGameAttributesChange()
|
||||
Engine.GetGUIObjectByName("mapInfoName").caption = getMapDisplayName(mapName);
|
||||
|
||||
// Load the description from the map file, if there is one
|
||||
var description = mapSettings.Description || "Sorry, no description available.";
|
||||
var description = mapSettings.Description || translate("Sorry, no description available.");
|
||||
|
||||
if (g_GameAttributes.mapFilter == "Naval Maps")
|
||||
if (g_GameAttributes.mapFilter == "naval")
|
||||
description += g_NavalWarning;
|
||||
|
||||
// Describe the number of players
|
||||
var playerString = numPlayers + " " + (numPlayers == 1 ? "player" : "players") + ". ";
|
||||
var playerString = sprintf(translatePlural("%(number)s player. %(description)s", "%(number)s players. %(description)s", numPlayers), { number: numPlayers, description: description });
|
||||
|
||||
for (var i = 0; i < MAX_PLAYERS; ++i)
|
||||
{
|
||||
@ -1212,7 +1221,7 @@ function onGameAttributesChange()
|
||||
pTeam.hidden = true;
|
||||
// Set text values
|
||||
if (civ == "random")
|
||||
pCivText.caption = "[color=\"orange\"]Random";
|
||||
pCivText.caption = "[color=\"orange\"]" + translateWithContext("civilization", "Random");
|
||||
else
|
||||
pCivText.caption = g_CivData[civ].Name;
|
||||
pTeamText.caption = (team !== undefined && team >= 0) ? team+1 : "-";
|
||||
@ -1229,7 +1238,7 @@ function onGameAttributesChange()
|
||||
}
|
||||
}
|
||||
|
||||
Engine.GetGUIObjectByName("mapInfoDescription").caption = playerString + description;
|
||||
Engine.GetGUIObjectByName("mapInfoDescription").caption = playerString;
|
||||
|
||||
g_IsInGuiUpdate = false;
|
||||
|
||||
@ -1310,12 +1319,12 @@ function updatePlayerList()
|
||||
}
|
||||
// Give AI a different color so it stands out
|
||||
aiAssignments[ai.id] = hostNameList.length;
|
||||
hostNameList.push("[color=\"70 150 70 255\"]AI: " + ai.data.name);
|
||||
hostNameList.push("[color=\"70 150 70 255\"]" + sprintf(translate("AI: %(ai)s"), { ai: translate(ai.data.name) }));
|
||||
hostGuidList.push("ai:" + ai.id);
|
||||
}
|
||||
|
||||
noAssignment = hostNameList.length;
|
||||
hostNameList.push("[color=\"140 140 140 255\"]Unassigned");
|
||||
hostNameList.push("[color=\"140 140 140 255\"]" + translate("Unassigned"));
|
||||
hostGuidList.push("");
|
||||
|
||||
for (var i = 0; i < MAX_PLAYERS; ++i)
|
||||
@ -1342,7 +1351,7 @@ function updatePlayerList()
|
||||
if (aiId in aiAssignments)
|
||||
selection = aiAssignments[aiId];
|
||||
else
|
||||
warn("AI \""+aiId+"\" not present. Defaulting to unassigned.");
|
||||
warn(sprintf("AI \"%(id)s\" not present. Defaulting to unassigned.", { id: aiId }));
|
||||
}
|
||||
|
||||
if (!selection)
|
||||
@ -1507,19 +1516,23 @@ function addChatMessage(msg)
|
||||
switch (msg.type)
|
||||
{
|
||||
case "connect":
|
||||
formatted = '[font="serif-bold-13"][color="'+ color +'"]' + username + '[/color][/font] [color="gold"]has joined[/color]';
|
||||
var formattedUsername = '[font="serif-bold-13"][color="'+ color +'"]' + username + '[/color][/font][color="gold"]'
|
||||
formatted = '[color="gold"]' + sprintf(translate("%(username)s has joined"), { username: formattedUsername });
|
||||
break;
|
||||
|
||||
case "disconnect":
|
||||
formatted = '[font="serif-bold-13"][color="'+ color +'"]' + username + '[/color][/font] [color="gold"]has left[/color]';
|
||||
var formattedUsername = '[font="serif-bold-13"][color="'+ color +'"]' + username + '[/color][/font][color="gold"]'
|
||||
formatted = '[color="gold"]' + sprintf(translate("%(username)s has left"), { username: formattedUsername });
|
||||
break;
|
||||
|
||||
case "message":
|
||||
formatted = '[font="serif-bold-13"]<[color="'+ color +'"]' + username + '[/color]>[/font] ' + message;
|
||||
var formattedUsername = '[color="'+ color +'"]' + username + '[/color]'
|
||||
var formattedUsernamePrefix = '[font="serif-bold-13"]' + sprintf(translate("<%(username)s>"), { username: formattedUsername }) + '[/font]'
|
||||
formatted = sprintf(translate("%(username)s %(message)s"), { username: formattedUsernamePrefix, message: message });
|
||||
break;
|
||||
|
||||
default:
|
||||
error("Invalid chat message '" + uneval(msg) + "'");
|
||||
error(sprintf("Invalid chat message '%(message)s'", { message: uneval(msg) }));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1538,11 +1551,12 @@ function toggleMoreOptions()
|
||||
// Basic map filters API
|
||||
|
||||
// Add a new map list filter
|
||||
function addFilter(name, filterFunc)
|
||||
function addFilter(id, name, filterFunc)
|
||||
{
|
||||
if (filterFunc instanceof Object)
|
||||
{ // Basic validity test
|
||||
var newFilter = {};
|
||||
newFilter.id = id;
|
||||
newFilter.name = name;
|
||||
newFilter.filter = filterFunc;
|
||||
|
||||
@ -1550,12 +1564,22 @@ function addFilter(name, filterFunc)
|
||||
}
|
||||
else
|
||||
{
|
||||
error("Invalid map filter: "+name);
|
||||
error(sprintf("Invalid map filter: %(name)s", { name: name }));
|
||||
}
|
||||
}
|
||||
|
||||
// Get array of map filter IDs
|
||||
function getFilterIds()
|
||||
{
|
||||
var filters = [];
|
||||
for (var i = 0; i < g_MapFilters.length; ++i)
|
||||
filters.push(g_MapFilters[i].id);
|
||||
|
||||
return filters;
|
||||
}
|
||||
|
||||
// Get array of map filter names
|
||||
function getFilters()
|
||||
function getFilterNames()
|
||||
{
|
||||
var filters = [];
|
||||
for (var i = 0; i < g_MapFilters.length; ++i)
|
||||
@ -1565,13 +1589,13 @@ function getFilters()
|
||||
}
|
||||
|
||||
// Test map filter on given map settings object
|
||||
function testFilter(name, mapSettings)
|
||||
function testFilter(id, mapSettings)
|
||||
{
|
||||
for (var i = 0; i < g_MapFilters.length; ++i)
|
||||
if (g_MapFilters[i].name == name)
|
||||
if (g_MapFilters[i].id == id)
|
||||
return g_MapFilters[i].filter(mapSettings);
|
||||
|
||||
error("Invalid map filter: "+name);
|
||||
error(sprintf("Invalid map filter: %(id)s", { id: id }));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -12,17 +12,17 @@
|
||||
<object type="image" style="ModernWindow" size="0 0 100% 100%">
|
||||
|
||||
<object style="TitleText" type="text" size="50%-128 4 50%+128 36">
|
||||
Match Setup
|
||||
<translatableAttribute id="caption">Match Setup</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object type="image" style="ModernDialog" size="50%-190 50%-80 50%+190 50%+80" name="loadingWindow">
|
||||
|
||||
<object type="text" style="TitleText" size="50%-128 0%-16 50%+128 16">
|
||||
Loading
|
||||
<translatableAttribute id="caption">Loading</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object type="text" style="ModernLabelText">
|
||||
Loading map data. Please wait...
|
||||
<translatableAttribute id="caption">Loading map data. Please wait...</translatableAttribute>
|
||||
</object>
|
||||
|
||||
</object>
|
||||
@ -38,7 +38,9 @@
|
||||
|
||||
<!-- Number of Players-->
|
||||
<object size="0 0 150 28">
|
||||
<object size="0 0 100% 100%" type="text" style="ModernRightLabelText">Number of players:</object>
|
||||
<object size="0 0 100% 100%" type="text" style="ModernRightLabelText">
|
||||
<translatableAttribute id="caption">Number of players:</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<!-- Number of Players-->
|
||||
@ -48,8 +50,8 @@
|
||||
type="dropdown"
|
||||
style="ModernDropDown"
|
||||
size="0 0 100% 28"
|
||||
tooltip_style="onscreenToolTip"
|
||||
tooltip="Select number of players.">
|
||||
tooltip_style="onscreenToolTip">
|
||||
<translatableAttribute id="tooltip">Select number of players.</translatableAttribute>
|
||||
<action on="SelectionChange">selectNumPlayers(this.list_data[this.selected]);</action>
|
||||
</object>
|
||||
</object>
|
||||
@ -59,37 +61,53 @@
|
||||
<!-- Player assignments -->
|
||||
<object size="24 59 100%-440 358" type="image" sprite="ModernDarkBoxGold" name="playerAssignmentsPannel">
|
||||
<object size="0 6 100% 30">
|
||||
<object name="playerNameHeading" type="text" style="ModernLabelText" size="0 0 20% 100%">Player Name</object>
|
||||
<object name="playerPlacementHeading" type="text" style="ModernLabelText" size="20%+5 0 50% 100%">Player Placement</object>
|
||||
<object name="playerCivHeading" type="text" style="ModernLabelText" size="50%+65 0 85% 100%">Civilization</object>
|
||||
<object name="playerNameHeading" type="text" style="ModernLabelText" size="0 0 20% 100%">
|
||||
<translatableAttribute id="caption">Player Name</translatableAttribute>
|
||||
</object>
|
||||
<object name="playerPlacementHeading" type="text" style="ModernLabelText" size="20%+5 0 50% 100%">
|
||||
<translatableAttribute id="caption">Player Placement</translatableAttribute>
|
||||
</object>
|
||||
<object name="playerCivHeading" type="text" style="ModernLabelText" size="50%+65 0 85% 100%">
|
||||
<translatableAttribute id="caption">Civilization</translatableAttribute>
|
||||
</object>
|
||||
<object name="civInfoButton"
|
||||
type="button"
|
||||
sprite="iconInfoGold"
|
||||
sprite_over="iconInfoWhite"
|
||||
size="82%-8 0 82%+8 16"
|
||||
tooltip_style="onscreenToolTip"
|
||||
tooltip="View civilization info"
|
||||
>
|
||||
<translatableAttribute id="tooltip">View civilization info</translatableAttribute>
|
||||
<action on="Press"><![CDATA[
|
||||
Engine.PushGuiPage("page_civinfo.xml");
|
||||
]]></action>
|
||||
</object>
|
||||
<object name="playerTeamHeading" type="text" style="ModernLabelText" size="85%+5 0 100%-5 100%">Team</object>
|
||||
<object name="playerTeamHeading" type="text" style="ModernLabelText" size="85%+5 0 100%-5 100%">
|
||||
<translatableAttribute id="caption">Team</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
<object size="1 36 100%-1 100%">
|
||||
<repeat count="8">
|
||||
<object name="playerBox[n]" size="0 0 100% 32" hidden="true">
|
||||
<object name="playerColour[n]" type="image" size="0 0 100% 100%"/>
|
||||
<object name="playerName[n]" type="text" style="ModernLabelText" size="0 2 20% 30"/>
|
||||
<object name="playerAssignment[n]" type="dropdown" style="ModernDropDown" size="20%+5 2 50% 30" tooltip_style="onscreenToolTip" tooltip="Select player."/>
|
||||
<object name="playerAssignment[n]" type="dropdown" style="ModernDropDown" size="20%+5 2 50% 30" tooltip_style="onscreenToolTip">
|
||||
<translatableAttribute id="tooltip">Select player.</translatableAttribute>
|
||||
</object>
|
||||
<object name="playerConfig[n]" type="button" style="StoneButton" size="50%+5 6 50%+60 26"
|
||||
tooltip_style="onscreenToolTip"
|
||||
tooltip="Configure AI settings."
|
||||
font="serif-bold-stroke-12"
|
||||
>Settings</object>
|
||||
<object name="playerCiv[n]" type="dropdown" style="ModernDropDown" size="50%+65 2 85% 30" tooltip_style="onscreenToolTip" tooltip="Select player's civilization."/>
|
||||
>
|
||||
<translatableAttribute id="caption">Settings</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Configure AI settings.</translatableAttribute>
|
||||
</object>
|
||||
<object name="playerCiv[n]" type="dropdown" style="ModernDropDown" size="50%+65 2 85% 30" tooltip_style="onscreenToolTip">
|
||||
<translatableAttribute id="tooltip">Select player's civilization.</translatableAttribute>
|
||||
</object>
|
||||
<object name="playerCivText[n]" type="text" style="ModernLabelText" size="50%+65 0 85% 30"/>
|
||||
<object name="playerTeam[n]" type="dropdown" style="ModernDropDown" size="85%+5 2 100%-5 30" tooltip_style="onscreenToolTip" tooltip="Select player's team."/>
|
||||
<object name="playerTeam[n]" type="dropdown" style="ModernDropDown" size="85%+5 2 100%-5 30" tooltip_style="onscreenToolTip">
|
||||
<translatableAttribute id="tooltip">Select player's team.</translatableAttribute>
|
||||
</object>
|
||||
<object name="playerTeamText[n]" type="text" style="ModernLabelText" size="85%+5 0 100%-5 100%"/>
|
||||
</object>
|
||||
</repeat>
|
||||
@ -100,10 +118,18 @@
|
||||
|
||||
|
||||
<object size="100%-425 363 100%-325 455" name="mapTypeSelectionTooltip">
|
||||
<object type="text" style="ModernRightLabelText" size="0 0 100% 30">Match Type:</object>
|
||||
<object type="text" style="ModernRightLabelText" size="0 32 100% 62">Map Filter:</object>
|
||||
<object type="text" style="ModernRightLabelText" size="0 64 100% 94">Select Map:</object>
|
||||
<object name="mapSizeDesc" type="text" style="ModernRightLabelText" size="0 96 100% 126">Map Size:</object>
|
||||
<object type="text" style="ModernRightLabelText" size="0 0 100% 30">
|
||||
<translatableAttribute id="caption">Match Type:</translatableAttribute>
|
||||
</object>
|
||||
<object type="text" style="ModernRightLabelText" size="0 32 100% 62">
|
||||
<translatableAttribute id="caption">Map Filter:</translatableAttribute>
|
||||
</object>
|
||||
<object type="text" style="ModernRightLabelText" size="0 64 100% 94">
|
||||
<translatableAttribute id="caption">Select Map:</translatableAttribute>
|
||||
</object>
|
||||
<object name="mapSizeDesc" type="text" style="ModernRightLabelText" size="0 96 100% 126">
|
||||
<translatableAttribute id="caption">Map Size:</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object size="100%-327 363 100%-25 423" name="mapFilterSelectionTooltip">
|
||||
@ -117,8 +143,8 @@
|
||||
type="dropdown"
|
||||
style="ModernDropDown"
|
||||
size="100%-315 363 100%-25 391"
|
||||
tooltip_style="onscreenToolTip"
|
||||
tooltip="Select a map type.">
|
||||
tooltip_style="onscreenToolTip">
|
||||
<translatableAttribute id="tooltip">Select a map type.</translatableAttribute>
|
||||
<action on="SelectionChange">selectMapType(this.list_data[this.selected]);</action>
|
||||
</object>
|
||||
|
||||
@ -126,9 +152,9 @@
|
||||
type="dropdown"
|
||||
style="ModernDropDown"
|
||||
size="100%-315 395 100%-25 423"
|
||||
tooltip_style="onscreenToolTip"
|
||||
tooltip="Select a map filter.">
|
||||
<action on="SelectionChange">selectMapFilter(this.list[this.selected]);</action>
|
||||
tooltip_style="onscreenToolTip">
|
||||
<translatableAttribute id="tooltip">Select a map filter.</translatableAttribute>
|
||||
<action on="SelectionChange">selectMapFilter(this.list_data[this.selected]);</action>
|
||||
</object>
|
||||
|
||||
<object size="100%-315 427 100%-25 455" name="mapSelectionPannel">
|
||||
@ -137,14 +163,16 @@
|
||||
style="ModernDropDown"
|
||||
type="dropdown"
|
||||
size="0 0 100% 100%"
|
||||
tooltip_style="onscreenToolTip"
|
||||
tooltip="Select a map to play on.">
|
||||
tooltip_style="onscreenToolTip">
|
||||
<translatableAttribute id="tooltip">Select a map to play on.</translatableAttribute>
|
||||
<action on="SelectionChange">selectMap(this.list_data[this.selected]);</action>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object name="mapSize" size="100%-315 459 100%-25 487" type="dropdown" style="ModernDropDown" hidden="true" tooltip_style="onscreenToolTip" tooltip="Select map size. (Larger sizes may reduce performance.)"/>
|
||||
|
||||
|
||||
<object name="mapSize" size="100%-325 459 100%-25 487" type="dropdown" style="ModernDropDown" hidden="true" tooltip_style="onscreenToolTip">
|
||||
<translatableAttribute id="tooltip">Select map size. (Larger sizes may reduce performance.)</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<!-- Map Preview -->
|
||||
<object type="image" sprite="ModernDarkBoxGold" name="gamePreviewBox" size="100%-426 57 100%-24 359">
|
||||
<object type="image" sprite="snMapPreview" size="1 1 401 301" name="mapPreview"/>
|
||||
@ -167,7 +195,7 @@
|
||||
</object>
|
||||
|
||||
<object size="100%-72 100%-24 100%-4 100%-4" type="button" style="StoneButton">
|
||||
Send
|
||||
<translatableAttribute id="caption">Send</translatableAttribute>
|
||||
<action on="Press">submitChatInput();</action>
|
||||
</object>
|
||||
</object>
|
||||
@ -180,7 +208,9 @@
|
||||
sprite="BackgroundTranslucent"
|
||||
hidden="true"
|
||||
size="100%-700 100%-56 100%-312 100%-24"
|
||||
>[Tooltip text]</object>
|
||||
>
|
||||
<translatableAttribute id="caption">[Tooltip text]</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<!-- Start Button -->
|
||||
<object
|
||||
@ -189,22 +219,22 @@
|
||||
style="StoneButton"
|
||||
size="100%-308 100%-52 100%-168 100%-24"
|
||||
tooltip_style="onscreenToolTip"
|
||||
tooltip="Start a new game with the current settings."
|
||||
enabled="false"
|
||||
>
|
||||
Start game!
|
||||
<translatableAttribute id="caption">Start game!</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Start a new game with the current settings.</translatableAttribute>
|
||||
<action on="Press">launchGame();</action>
|
||||
</object>
|
||||
|
||||
<!-- Cancel Button -->
|
||||
<object
|
||||
name="cancelGame"
|
||||
caption="Back"
|
||||
type="button"
|
||||
style="StoneButton"
|
||||
size="100%-164 100%-52 100%-24 100%-24"
|
||||
tooltip_style="onscreenToolTip"
|
||||
>
|
||||
<translatableAttribute id="caption">Back</translatableAttribute>
|
||||
<action on="Press">
|
||||
<![CDATA[
|
||||
cancelSetup();
|
||||
@ -225,9 +255,9 @@
|
||||
style="StoneButton"
|
||||
size="100%-120 0 100% 28"
|
||||
tooltip_style="onscreenToolTip"
|
||||
tooltip="See more game options"
|
||||
>
|
||||
More Options
|
||||
<translatableAttribute id="caption">More Options</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">See more game options</translatableAttribute>
|
||||
<action on="Press">toggleMoreOptions();</action>
|
||||
</object>
|
||||
|
||||
@ -300,9 +330,9 @@
|
||||
style="StoneButton"
|
||||
size="50%-70 310 50%+70 336"
|
||||
tooltip_style="onscreenToolTip"
|
||||
tooltip="Close more game options window"
|
||||
>
|
||||
OK
|
||||
<translatableAttribute id="caption">OK</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Close more game options window</translatableAttribute>
|
||||
<action on="Press">toggleMoreOptions();</action>
|
||||
</object>
|
||||
<!-- End More Options -->
|
||||
|
@ -31,13 +31,13 @@ function init(attribs)
|
||||
{
|
||||
Engine.GetGUIObjectByName("hostServerNameWrapper").hidden = false;
|
||||
Engine.GetGUIObjectByName("hostPlayerName").caption = attribs.name;
|
||||
Engine.GetGUIObjectByName("hostServerName").caption = attribs.name + "'s game";
|
||||
Engine.GetGUIObjectByName("hostServerName").caption = sprintf(translate("%(name)s's game"), { name: attribs.name });
|
||||
}
|
||||
else
|
||||
Engine.GetGUIObjectByName("hostPlayerNameWrapper").hidden = false;
|
||||
break;
|
||||
default:
|
||||
error("Unrecognised multiplayer game type : " + attribs.multiplayerGameType);
|
||||
error(sprintf("Unrecognised multiplayer game type: %(gameType)s", { gameType: multiplayerGameType }));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -57,7 +57,7 @@ function startConnectionStatus(type)
|
||||
g_GameType = type;
|
||||
g_IsConnecting = true;
|
||||
g_IsRejoining = false;
|
||||
Engine.GetGUIObjectByName("connectionStatus").caption = "Connecting to server...";
|
||||
Engine.GetGUIObjectByName("connectionStatus").caption = translate("Connecting to server...");
|
||||
}
|
||||
|
||||
function onTick()
|
||||
@ -76,7 +76,7 @@ function pollAndHandleNetworkClient()
|
||||
if (!message)
|
||||
break;
|
||||
|
||||
log("Net message: "+uneval(message));
|
||||
log(sprintf(translate("Net message: %(message)s"), { message: uneval(message) }));
|
||||
|
||||
// If we're rejoining an active game, we don't want to actually display
|
||||
// the game setup screen, so perform similar processing to gamesetup.js
|
||||
@ -94,7 +94,7 @@ function pollAndHandleNetworkClient()
|
||||
return;
|
||||
|
||||
default:
|
||||
error("Unrecognised netstatus type "+message.status);
|
||||
error(sprintf("Unrecognised netstatus type %(netType)s", { netType: message.status }));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -120,7 +120,7 @@ function pollAndHandleNetworkClient()
|
||||
break;
|
||||
|
||||
default:
|
||||
error("Unrecognised net message type "+message.type);
|
||||
error(sprintf("Unrecognised net message type %(messageType)s", { messageType: message.type }));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -133,13 +133,13 @@ function pollAndHandleNetworkClient()
|
||||
switch (message.status)
|
||||
{
|
||||
case "connected":
|
||||
Engine.GetGUIObjectByName("connectionStatus").caption = "Registering with server...";
|
||||
Engine.GetGUIObjectByName("connectionStatus").caption = translate("Registering with server...");
|
||||
break;
|
||||
|
||||
case "authenticated":
|
||||
if (message.rejoining)
|
||||
{
|
||||
Engine.GetGUIObjectByName("connectionStatus").caption = "Game has already started - rejoining...";
|
||||
Engine.GetGUIObjectByName("connectionStatus").caption = translate("Game has already started, rejoining...");
|
||||
g_IsRejoining = true;
|
||||
return; // we'll process the game setup messages in the next tick
|
||||
}
|
||||
@ -155,12 +155,12 @@ function pollAndHandleNetworkClient()
|
||||
return;
|
||||
|
||||
default:
|
||||
error("Unrecognised netstatus type "+message.status);
|
||||
error(sprintf("Unrecognised netstatus type %(netType)s", { netType: message.status }));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error("Unrecognised net message type "+message.type);
|
||||
error(sprintf("Unrecognised net message type %(messageType)s", { messageType: message.type }));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -182,7 +182,7 @@ function startHost(playername, servername)
|
||||
{
|
||||
if (g.name === servername)
|
||||
{
|
||||
Engine.GetGUIObjectByName("hostFeedback").caption = "Game name already in use.";
|
||||
Engine.GetGUIObjectByName("hostFeedback").caption = translate("Game name already in use.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -198,7 +198,7 @@ function startHost(playername, servername)
|
||||
{
|
||||
cancelSetup();
|
||||
messageBox(400, 200,
|
||||
"Cannot host game: " + e.message + ".",
|
||||
sprintf("Cannot host game: %(message)s.", { message: e.message }),
|
||||
"Error", 2);
|
||||
return false;
|
||||
}
|
||||
@ -224,7 +224,7 @@ function startJoin(playername, ip)
|
||||
{
|
||||
cancelSetup();
|
||||
messageBox(400, 200,
|
||||
"Cannot join game: " + e.message + ".",
|
||||
sprintf("Cannot join game: %(message)s.", { message: e.message }),
|
||||
"Error", 2);
|
||||
return false;
|
||||
}
|
||||
@ -235,3 +235,8 @@ function startJoin(playername, ip)
|
||||
Engine.LobbySetPlayerPresence("playing");
|
||||
return true;
|
||||
}
|
||||
|
||||
function getDefaultGameName()
|
||||
{
|
||||
return sprintf(translate("%(playername)s's game"), { playername: Engine.ConfigDB_GetValue("user", "playername")});
|
||||
}
|
||||
|
@ -16,17 +16,17 @@
|
||||
</action>
|
||||
|
||||
<object style="TitleText" type="text" size="50%-128 0%-16 50%+128 16">
|
||||
Multiplayer
|
||||
<translatableAttribute id="caption">Multiplayer</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object name="pageJoin" size="0 32 100% 100%" hidden="true">
|
||||
|
||||
<object type="text" style="ModernLabelText" size="0 0 400 30">
|
||||
Joining an existing game.
|
||||
<translatableAttribute id="caption">Joining an existing game.</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object type="text" size="0 40 200 70" style="ModernRightLabelText">
|
||||
Player name:
|
||||
<translatableAttribute id="caption">Player name:</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object name="joinPlayerName" type="input" size="210 40 100%-32 64" style="ModernInput">
|
||||
@ -36,7 +36,7 @@
|
||||
</object>
|
||||
|
||||
<object type="text" size="0 80 200 110" style="ModernRightLabelText">
|
||||
Server Hostname or IP:
|
||||
<translatableAttribute id="caption">Server Hostname or IP:</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object name="joinServer" type="input" size="210 80 100%-32 104" style="ModernInput">
|
||||
@ -46,7 +46,7 @@
|
||||
</object>3 100%-33 103 100%-3
|
||||
|
||||
<object hotkey="confirm" type="button" size="50%-144 100%-60 50%-16 100%-32" style="StoneButton">
|
||||
Continue
|
||||
<translatableAttribute id="caption">Continue</translatableAttribute>
|
||||
<action on="Press">
|
||||
var joinPlayerName = Engine.GetGUIObjectByName("joinPlayerName").caption;
|
||||
var joinServer = Engine.GetGUIObjectByName("joinServer").caption;
|
||||
@ -64,12 +64,12 @@
|
||||
<object name="pageHost" size="0 32 100% 100%" hidden="true">
|
||||
|
||||
<object type="text" style="ModernLabelText" size="0 0 400 30">
|
||||
Set up your server to host.
|
||||
<translatableAttribute id="caption">Set up your server to host.</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object name="hostPlayerNameWrapper" hidden="true">
|
||||
<object type="text" size="0 40 200 70" style="ModernRightLabelText">
|
||||
Player name:
|
||||
<translatableAttribute id="caption">Player name:</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object name="hostPlayerName" type="input" size="210 40 100%-32 64" style="ModernInput">
|
||||
@ -81,18 +81,18 @@
|
||||
|
||||
<object name="hostServerNameWrapper" hidden="true">
|
||||
<object type="text" size="0 80 200 110" style="ModernRightLabelText">
|
||||
Server name:
|
||||
<translatableAttribute id="caption">Server name:</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object name="hostServerName" type="input" size="210 80 100%-32 104" style="ModernInput">
|
||||
<action on="Load">
|
||||
this.caption = Engine.ConfigDB_GetValue("user", "playername") + "'s game";
|
||||
this.caption = getDefaultGameName();
|
||||
</action>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object type="button" size="50%-144 100%-60 50%-16 100%-32" style="StoneButton">
|
||||
Continue
|
||||
<translatableAttribute id="caption">Continue</translatableAttribute>
|
||||
<action on="Press">
|
||||
var hostPlayerName = Engine.GetGUIObjectByName("hostPlayerName").caption;
|
||||
Engine.ConfigDB_CreateValue("user", "playername", hostPlayerName);
|
||||
@ -106,13 +106,13 @@
|
||||
<object name="hostFeedback" type="text" style="ModernLabelText" size="32 150 100%-32 180" textcolor="red" />
|
||||
|
||||
<object type="button" style="StoneButton" size="50%+16 100%-60 50%+144 100%-32">
|
||||
Cancel
|
||||
<translatableAttribute id="caption">Cancel</translatableAttribute>
|
||||
<action on="Press">cancelSetup();</action>
|
||||
</object>
|
||||
|
||||
<object name="pageConnecting" hidden="true">
|
||||
<object name="connectionStatus" type="text" style="ModernLabelText" size="0 100 100% 120">
|
||||
[Connection status]
|
||||
<translatableAttribute id="caption">[Connection status]</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
|
@ -15,7 +15,7 @@ function init(data)
|
||||
{
|
||||
// Set tip text
|
||||
var tipTextFilePath = tipTextLoadingArray[getRandom (0, tipTextLoadingArray.length-1)];
|
||||
var tipText = Engine.ReadFile(tipTextFilePath);
|
||||
var tipText = Engine.TranslateLines(Engine.ReadFile(tipTextFilePath));
|
||||
|
||||
if (tipText)
|
||||
{
|
||||
@ -48,15 +48,15 @@ function init(data)
|
||||
{
|
||||
case "skirmish":
|
||||
case "scenario":
|
||||
loadingMapName.caption = "Loading \"" + mapName + "\"";
|
||||
loadingMapName.caption = sprintf(translate("Loading \"%(map)s\""), {map: mapName});
|
||||
break;
|
||||
|
||||
case "random":
|
||||
loadingMapName.caption = "Generating \"" + mapName + "\"";
|
||||
loadingMapName.caption = sprintf(translate("Generating \"%(map)s\""), {map: mapName});
|
||||
break;
|
||||
|
||||
default:
|
||||
error("Unknown map type: " + data.attribs.mapType);
|
||||
error(sprintf("Unknown map type: %(mapType)s", { mapType: data.attribs.mapType }));
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ function init(data)
|
||||
|
||||
// Pick a random quote of the day (each line is a separate tip).
|
||||
var quoteArray = Engine.ReadFileLines("gui/text/quotes.txt");
|
||||
Engine.GetGUIObjectByName("quoteText").caption = quoteArray[getRandom(0, quoteArray.length-1)];
|
||||
Engine.GetGUIObjectByName("quoteText").caption = translate(quoteArray[getRandom(0, quoteArray.length-1)]);
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
|
@ -44,7 +44,9 @@
|
||||
|
||||
<!-- LOADING SCREEN QUOTE (needs increased z value to overcome the transparent area of the tip image above it -->
|
||||
<object size="50%-448 50%+230 50%+448 100%-16" z="20">
|
||||
<object name="quoteTitleText" size="0 0 100% 30" type="text" style="LoadingTitleText">Quote of the Day:</object>
|
||||
<object name="quoteTitleText" size="0 0 100% 30" type="text" style="LoadingTitleText">
|
||||
<translatableAttribute id="caption">Quote of the Day:</translatableAttribute>
|
||||
</object>
|
||||
<object name="quoteText" size="0 30 100% 100%" type="text" style="LoadingText"></object>
|
||||
</object>
|
||||
</object>
|
||||
|
@ -22,7 +22,7 @@ function init(attribs)
|
||||
g_Name = Engine.LobbyGetNick();
|
||||
|
||||
g_mapSizes = initMapSizes();
|
||||
g_mapSizes.shortNames.splice(0, 0, "Any");
|
||||
g_mapSizes.shortNames.splice(0, 0, translateWithContext("map size", "Any"));
|
||||
g_mapSizes.tiles.splice(0, 0, "");
|
||||
|
||||
var mapSizeFilter = Engine.GetGUIObjectByName("mapSizeFilter");
|
||||
@ -30,11 +30,11 @@ function init(attribs)
|
||||
mapSizeFilter.list_data = g_mapSizes.tiles;
|
||||
|
||||
var playersNumberFilter = Engine.GetGUIObjectByName("playersNumberFilter");
|
||||
playersNumberFilter.list = ["Any",2,3,4,5,6,7,8];
|
||||
playersNumberFilter.list = [translateWithContext("player number", "Any"),2,3,4,5,6,7,8];
|
||||
playersNumberFilter.list_data = ["",2,3,4,5,6,7,8];
|
||||
|
||||
var mapTypeFilter = Engine.GetGUIObjectByName("mapTypeFilter");
|
||||
mapTypeFilter.list = ["Any", "Skirmish", "Random", "Scenario"];
|
||||
mapTypeFilter.list = [translateWithContext("map", "Any"), translateWithContext("map", "Skirmish"), translateWithContext("map", "Random"), translate("Scenario")];
|
||||
mapTypeFilter.list_data = ["", "skirmish", "random", "scenario"];
|
||||
|
||||
Engine.LobbySetPlayerPresence("available");
|
||||
@ -296,30 +296,31 @@ function updateGameList()
|
||||
function formatPlayerListEntry(nickname, presence, rating, role)
|
||||
{
|
||||
// Set colors based on player status
|
||||
var color, status;
|
||||
var color;
|
||||
var status;
|
||||
switch (presence)
|
||||
{
|
||||
case "playing":
|
||||
color = "125 0 0";
|
||||
status = "Busy";
|
||||
status = translate("Busy");
|
||||
break;
|
||||
case "gone":
|
||||
case "away":
|
||||
color = "229 76 13";
|
||||
status = "Away";
|
||||
status = translate("Away");
|
||||
break;
|
||||
case "available":
|
||||
color = "0 125 0";
|
||||
status = "Online";
|
||||
status = translate("Online");
|
||||
break;
|
||||
case "offline":
|
||||
color = "0 0 0";
|
||||
status = "Offline";
|
||||
status = translate("Offline");
|
||||
break;
|
||||
default:
|
||||
warn("Unknown presence '" + presence + "'");
|
||||
warn(sprintf("Unknown presence '%(presence)s'", { presence: presence }));
|
||||
color = "178 178 178";
|
||||
status = "Unknown";
|
||||
status = translateWithContext("lobby presence", "Unknown");
|
||||
break;
|
||||
}
|
||||
// Center the unrated symbol.
|
||||
@ -334,6 +335,7 @@ function formatPlayerListEntry(nickname, presence, rating, role)
|
||||
// Give moderators special formatting.
|
||||
if (role == "moderator")
|
||||
formattedName = formattedName; //TODO
|
||||
|
||||
// Push this player's name and status onto the list
|
||||
return [formattedName, formattedStatus, formattedRating];
|
||||
}
|
||||
@ -358,14 +360,14 @@ function updateGameSelection()
|
||||
|
||||
// Load map data
|
||||
if (g_GameList[g].mapType == "random" && g_GameList[g].mapName == "random")
|
||||
mapData = {"settings": {"Description": "A randomly selected map."}};
|
||||
mapData = {"settings": {"Description": translate("A randomly selected map.")}};
|
||||
else if (g_GameList[g].mapType == "random" && Engine.FileExists(g_GameList[g].mapName + ".json"))
|
||||
mapData = parseJSONData(g_GameList[g].mapName + ".json");
|
||||
else if (Engine.FileExists(g_GameList[g].mapName + ".xml"))
|
||||
mapData = Engine.LoadMapSettings(g_GameList[g].mapName + ".xml");
|
||||
else
|
||||
// Warn the player if we can't find the map.
|
||||
warn("Map '" + g_GameList[g].mapName + "' not found locally.");
|
||||
warn(sprintf("Map '%(mapName)s' not found locally.", { mapName: g_GameList[g].mapName }));
|
||||
|
||||
// Show the game info panel and join button.
|
||||
Engine.GetGUIObjectByName("gameInfo").hidden = false;
|
||||
@ -383,7 +385,7 @@ function updateGameSelection()
|
||||
if (mapData && mapData.settings.Description)
|
||||
var mapDescription = mapData.settings.Description;
|
||||
else
|
||||
var mapDescription = "Sorry, no description available.";
|
||||
var mapDescription = translate("Sorry, no description available.");
|
||||
|
||||
// Display map preview if it exists, otherwise display a placeholder.
|
||||
if (mapData && mapData.settings.Preview)
|
||||
@ -411,7 +413,7 @@ function joinSelectedGame()
|
||||
// Check if it looks like an ip address
|
||||
if (sip.split('.').length != 4)
|
||||
{
|
||||
addChatMessage({ "from": "system", "text": "This game's address '" + sip + "' does not appear to be valid." });
|
||||
addChatMessage({ "from": "system", "text": sprintf(translate("This game's address '%(ip)s' does not appear to be valid."), { ip: sip }) });
|
||||
return;
|
||||
}
|
||||
|
||||
@ -433,14 +435,6 @@ function hostGame()
|
||||
// Utils
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Add a leading zero to single-digit numbers.
|
||||
*/
|
||||
function twoDigits(n)
|
||||
{
|
||||
return n < 10 ? "0" + n : n;
|
||||
}
|
||||
|
||||
function stripColorCodes(input)
|
||||
{
|
||||
return input.replace(/\[(\w+)[^w]*?](.*?)\[\/\1]/g, '$2');
|
||||
@ -500,7 +494,7 @@ function onTick()
|
||||
nickList.push(nick);
|
||||
ratingList.push(String(rating));
|
||||
Engine.SendGetRatingList();
|
||||
addChatMessage({ "text": "/special " + nick + " has joined.", "key": g_specialKey });
|
||||
addChatMessage({ "text": "/special " + sprintf(translate("%(nick)s has joined."), { nick: nick }), "key": g_specialKey });
|
||||
break;
|
||||
case "leave":
|
||||
if (nickIndex == -1) // Left, but not present (TODO: warn about this?)
|
||||
@ -509,21 +503,21 @@ function onTick()
|
||||
presenceList.splice(nickIndex, 1);
|
||||
nickList.splice(nickIndex, 1);
|
||||
ratingList.splice(nickIndex, 1);
|
||||
addChatMessage({ "text": "/special " + nick + " has left.", "key": g_specialKey });
|
||||
addChatMessage({ "text": "/special " + sprintf(translate("%(nick)s has left."), { nick: nick }), "key": g_specialKey });
|
||||
break;
|
||||
case "nick":
|
||||
if (nickIndex == -1) // This shouldn't ever happen
|
||||
break;
|
||||
if (!isValidNick(message.data))
|
||||
{
|
||||
addChatMessage({ "from": "system", "text": "Invalid nickname: " + message.data });
|
||||
addChatMessage({ "from": "system", "text": sprintf(translate("Invalid nickname: %(nick)s"), { nick: message.data })});
|
||||
break;
|
||||
}
|
||||
var [name, status, rating] = formatPlayerListEntry(message.data, presence, stripColorCodes(ratingList[nickIndex])); // TODO: actually we don't want to change the presence here, so use what was used before
|
||||
playerList[nickIndex] = name;
|
||||
// presence stays the same
|
||||
nickList[nickIndex] = message.data;
|
||||
addChatMessage({ "text": "/special " + nick + " is now known as " + message.data + ".", "key": g_specialKey });
|
||||
addChatMessage({ "text": "/special " + sprintf(translate("%(oldnick)s is now known as %(newnick)s."), { oldnick: nick, newnick: message.data }), "key": g_specialKey });
|
||||
Engine.SendGetRatingList();
|
||||
break;
|
||||
case "presence":
|
||||
@ -538,7 +532,7 @@ function onTick()
|
||||
updateSubject(message.text);
|
||||
break;
|
||||
default:
|
||||
warn("Unknown message.level '" + message.level + "'");
|
||||
warn(sprintf("Unknown message.level '%(msglvl)s'", { msglvl: message.level }));
|
||||
break;
|
||||
}
|
||||
// Push new data to GUI
|
||||
@ -588,7 +582,7 @@ function onTick()
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error("Unrecognised message type "+message.type);
|
||||
error(sprintf("Unrecognised message type %(msgtype)s", { msgtype: message.type }));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -677,7 +671,7 @@ function handleSpecialCommand(text)
|
||||
case "me":
|
||||
return false;
|
||||
default:
|
||||
addChatMessage({ "from":"system", "text":"We're sorry, the '" + cmd + "' command is not supported."});
|
||||
addChatMessage({ "from":"system", "text": sprintf(translate("We're sorry, the '%(cmd)s' command is not supported."), { cmd: cmd})});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -749,15 +743,6 @@ function ircFormat(text, from, color, key)
|
||||
else if (color && from)
|
||||
var coloredFrom = '[color="' + color + '"]' + from + "[/color]";
|
||||
|
||||
// Time for optional time header
|
||||
var time = new Date(Date.now());
|
||||
|
||||
// Build time header if enabled
|
||||
if (g_timestamp)
|
||||
var formatted = '[font="serif-bold-13"]\x5B' + twoDigits(time.getHours() % 12) + ":" + twoDigits(time.getMinutes()) + '\x5D[/font] '
|
||||
else
|
||||
var formatted = "";
|
||||
|
||||
// Handle commands allowed past handleSpecialCommand.
|
||||
if (text[0] == '/')
|
||||
{
|
||||
@ -765,19 +750,61 @@ function ircFormat(text, from, color, key)
|
||||
switch (command)
|
||||
{
|
||||
case "me":
|
||||
return formatted + '[font="serif-bold-13"]* ' + coloredFrom + '[/font] ' + message;
|
||||
// Translation: IRC message prefix when the sender uses the /me command.
|
||||
var senderString = '[font="serif-bold-13"]' + sprintf(translate("* %(sender)s"), { sender: coloredFrom }) + '[/font]';
|
||||
// Translation: IRC message issued using the ‘/me’ command.
|
||||
var formattedMessage = sprintf(translate("%(sender)s %(action)s"), { sender: senderString, action: message });
|
||||
break;
|
||||
case "say":
|
||||
return formatted + '[font="serif-bold-13"]<' + coloredFrom + '>[/font] ' + message;
|
||||
// Translation: IRC message prefix.
|
||||
var senderString = '[font="serif-bold-13"]' + sprintf(translate("<%(sender)s>"), { sender: coloredFrom }) + '[/font]';
|
||||
// Translation: IRC message.
|
||||
var formattedMessage = sprintf(translate("%(sender)s %(message)s"), { sender: senderString, message: message });
|
||||
break
|
||||
case "special":
|
||||
if (key === g_specialKey)
|
||||
return formatted + '[font="serif-bold-13"] == ' + message + '[/font]';
|
||||
// Translation: IRC system message.
|
||||
var formattedMessage = '[font="serif-bold-13"]' + sprintf(translate("== %(message)s"), { message: message }) + '[/font]';
|
||||
else
|
||||
{
|
||||
// Translation: IRC message prefix.
|
||||
var senderString = '[font="serif-bold-13"]' + sprintf(translate("<%(sender)s>"), { sender: coloredFrom }) + '[/font]';
|
||||
// Translation: IRC message.
|
||||
var formattedMessage = sprintf(translate("%(sender)s %(message)s"), { sender: senderString, message: message });
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// This should never happen.
|
||||
return "";
|
||||
var formattedMessage = "";
|
||||
}
|
||||
}
|
||||
return formatted + '[font="serif-bold-13"]<' + coloredFrom + '>[/font] ' + text;
|
||||
else
|
||||
{
|
||||
// Translation: IRC message prefix.
|
||||
var senderString = '[font="serif-bold-13"]' + sprintf(translate("<%(sender)s>"), { sender: coloredFrom }) + '[/font]';
|
||||
// Translation: IRC message.
|
||||
var formattedMessage = sprintf(translate("%(sender)s %(message)s"), { sender: senderString, message: text });
|
||||
}
|
||||
|
||||
// Build time header if enabled
|
||||
if (g_timestamp)
|
||||
{
|
||||
// Time for optional time header
|
||||
var time = new Date(Date.now());
|
||||
|
||||
// Translation: Time as shown in the multiplayer lobby (when you enable it in the options page).
|
||||
// For a list of symbols that you can use, see:
|
||||
// https://sites.google.com/site/icuprojectuserguide/formatparse/datetime?pli=1#TOC-Date-Field-Symbol-Table
|
||||
var timeString = Engine.FormatMillisecondsIntoDateString(time.getTime(), translate("HH:mm"));
|
||||
|
||||
// Translation: Time prefix as shown in the multiplayer lobby (when you enable it in the options page).
|
||||
var timePrefixString = '[font="serif-bold-13"]' + sprintf(translate("[%(time)s]"), { time: timeString }) + '[/font]';
|
||||
|
||||
// Translation: IRC message format when there is a time prefix.
|
||||
return sprintf(translate("%(time)s %(message)s"), { time: timePrefixString, message: formattedMessage });
|
||||
}
|
||||
else
|
||||
return formattedMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -824,7 +851,7 @@ function isSpam(text, from)
|
||||
{
|
||||
g_spamMonitor[from][2] = time;
|
||||
if (from == g_Name)
|
||||
addChatMessage({ "from": "system", "text": "Please do not spam. You have been blocked for thirty seconds." });
|
||||
addChatMessage({ "from": "system", "text": translate("Please do not spam. You have been blocked for thirty seconds.") });
|
||||
return true;
|
||||
}
|
||||
// Return false if everything is clear.
|
||||
|
@ -11,7 +11,7 @@
|
||||
<object type="image" style="ModernWindow" size="0 0 100% 100%" name="lobbyWindow">
|
||||
|
||||
<object style="TitleText" type="text" size="50%-128 0%+4 50%+128 36">
|
||||
Multiplayer Lobby
|
||||
<translatableAttribute id="caption">Multiplayer Lobby</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<action on="Tick">
|
||||
@ -21,15 +21,21 @@
|
||||
<!-- Left panel: Player list. -->
|
||||
<object name="leftPanel" size="20 30 20% 100%-50">
|
||||
<object name="playersBox" style="ModernList" type="olist" size="0 0 100% 100%" font="serif-bold-stroke-13">
|
||||
<def id="status" heading="Status" width="27%"/>
|
||||
<def id="name" heading="Name" width="50%"/>
|
||||
<def id="rating" heading="Rating" width="23%"/>
|
||||
<def id="status" width="27%">
|
||||
<translatableAttribute id="heading">Status</translatableAttribute>
|
||||
</def>
|
||||
<def id="name" width="50%">
|
||||
<translatableAttribute id="heading">Name</translatableAttribute>
|
||||
</def>
|
||||
<def id="rating" width="23%">
|
||||
<translatableAttribute id="heading">Rating</translatableAttribute>
|
||||
</def>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object name="leftButtonPanel" size="20 100%-45 20% 100%-20">
|
||||
<object type="button" style="StoneButton" size="0 0 100% 100%">
|
||||
Leaderboard
|
||||
<translatableAttribute id="caption">Leaderboard</translatableAttribute>
|
||||
<action on="Press">Engine.GetGUIObjectByName("leaderboard").hidden = false;Engine.GetGUIObjectByName("leaderboardFade").hidden = false;</action>
|
||||
</object>
|
||||
</object>
|
||||
@ -54,7 +60,9 @@
|
||||
|
||||
<!-- Map Type -->
|
||||
<object size="5 240 50% 265" type="image" sprite="ModernItemBackShadeLeft">
|
||||
<object size="0 0 100%-10 100%" type="text" style="ModernLabelText" text_align="right">Map Type:</object>
|
||||
<object size="0 0 100%-10 100%" type="text" style="ModernLabelText" text_align="right">
|
||||
<translatableAttribute id="caption">Map Type:</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
<object size="50% 240 100%-5 265" type="image" sprite="ModernItemBackShadeRight">
|
||||
<object name="sgMapType" size="0 0 100% 100%" type="text" style="ModernLabelText" text_align="left"/>
|
||||
@ -64,7 +72,9 @@
|
||||
|
||||
<!-- Map Size -->
|
||||
<object size="5 265 50% 290" type="image" sprite="ModernItemBackShadeLeft">
|
||||
<object size="0 0 100%-10 100%" type="text" style="ModernLabelText" text_align="right">Map Size:</object>
|
||||
<object size="0 0 100%-10 100%" type="text" style="ModernLabelText" text_align="right">
|
||||
<translatableAttribute id="caption">Map Size:</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
<object size="50% 265 100%-5 290" type="image" sprite="ModernItemBackShadeRight">
|
||||
<object name="sgMapSize" size="0 0 100% 100%" type="text" style="ModernLabelText" text_align="left"/>
|
||||
@ -79,7 +89,9 @@
|
||||
|
||||
<object type="image" sprite="ModernDarkBoxWhite" size="3% 76% 97% 99%">
|
||||
<!-- Number of Players -->
|
||||
<object size="32% 3% 57% 12%" type="text" style="ModernLabelText" text_align="left">Players:</object>
|
||||
<object size="32% 3% 57% 12%" type="text" style="ModernLabelText" text_align="left">
|
||||
<translatableAttribute id="caption">Players:</translatableAttribute>
|
||||
</object>
|
||||
<object name="sgNbPlayers" size="52% 3% 62% 12%" type="text" style="ModernLabelText" text_align="left"/>
|
||||
|
||||
<!-- Player Names -->
|
||||
@ -87,20 +99,20 @@
|
||||
</object>
|
||||
</object>
|
||||
<object name="joinGameButton" type="button" style="StoneButton" size="0 100%-85 100% 100%-60" hidden="true">
|
||||
Join Game
|
||||
<translatableAttribute id="caption">Join Game</translatableAttribute>
|
||||
<action on="Press">
|
||||
joinSelectedGame();
|
||||
</action>
|
||||
</object>
|
||||
<object name="hostButton" type="button" style="StoneButton" size="0 100%-55 100% 100%-30">
|
||||
Host Game
|
||||
<translatableAttribute id="caption">Host Game</translatableAttribute>
|
||||
<action on="Press">
|
||||
hostGame();
|
||||
</action>
|
||||
</object>
|
||||
|
||||
<object type="button" style="StoneButton" size="0 100%-25 100% 100%">
|
||||
Main Menu
|
||||
<translatableAttribute id="caption">Main Menu</translatableAttribute>
|
||||
<action on="Press">
|
||||
lobbyStop();
|
||||
Engine.SwitchGuiPage("page_pregame.xml");
|
||||
@ -112,12 +124,22 @@
|
||||
<object name="middlePanel" size="20%+5 5% 100%-255 97.2%">
|
||||
<object name="gamesBox" style="ModernList" type="olist" size="0 25 100% 48%">
|
||||
<action on="SelectionChange">updateGameSelection();</action>
|
||||
<def id="name" heading="Name" color="0 60 0" width="20%"/>
|
||||
<def id="name" color="0 60 0" width="20%">
|
||||
<translatableAttribute id="heading">Name</translatableAttribute>
|
||||
</def>
|
||||
<!--<def id="ip" heading="IP" color="0 128 128" width="170"/>-->
|
||||
<def id="mapName" heading="Map Name" color="128 128 128" width="25%"/>
|
||||
<def id="mapSize" heading="Map Size" color="128 128 128" width="25%"/>
|
||||
<def id="mapType" heading="Map Type" color="0 128 128" width="20%"/>
|
||||
<def id="nPlayers" heading="Players" color="0 128 128" width="10%"/>
|
||||
<def id="mapName" color="128 128 128" width="25%">
|
||||
<translatableAttribute id="heading">Map Name</translatableAttribute>
|
||||
</def>
|
||||
<def id="mapSize" color="128 128 128" width="25%">
|
||||
<translatableAttribute id="heading">Map Size</translatableAttribute>
|
||||
</def>
|
||||
<def id="mapType" color="0 128 128" width="20%">
|
||||
<translatableAttribute id="heading">Map Type</translatableAttribute>
|
||||
</def>
|
||||
<def id="nPlayers" color="0 128 128" width="10%">
|
||||
<translatableAttribute id="heading">Players</translatableAttribute>
|
||||
</def>
|
||||
</object>
|
||||
|
||||
<object name="filterPanel" size="0 0 100% 24">
|
||||
@ -145,7 +167,9 @@
|
||||
<action on="SelectionChange">applyFilters();</action>
|
||||
</object>
|
||||
|
||||
<object type="text" size="22 0 35% 100%" text_align="left" textcolor="white">Show full games</object>
|
||||
<object type="text" size="22 0 35% 100%" text_align="left" textcolor="white">
|
||||
<translatableAttribute id="caption">Show full games</translatableAttribute>
|
||||
</object>
|
||||
<object name="showFullFilter"
|
||||
type="checkbox"
|
||||
checked="true"
|
||||
@ -169,21 +193,29 @@
|
||||
<!-- Add a translucent black background to fade out the menu page -->
|
||||
<object hidden="true" name="leaderboardFade" type="image" z="100" sprite="ModernFade"/>
|
||||
<object hidden="true" name="leaderboard" type="image" style="ModernDialog" size="50%-224 50%-160 50%+224 50%+160" z="101">
|
||||
<object style="TitleText" type="text" size="50%-128 0%-16 50%+128 16">Leaderboard</object>
|
||||
<object style="TitleText" type="text" size="50%-128 0%-16 50%+128 16">
|
||||
<translatableAttribute id="caption">Leaderboard</translatableAttribute>
|
||||
</object>
|
||||
<object name="leaderboardBox"
|
||||
style="ModernList"
|
||||
type="olist"
|
||||
size="19 19 100%-19 100%-58">
|
||||
<def id="rank" heading="Rank" color="255 255 255" width="15%"/>
|
||||
<def id="rating" heading="Rating" color="255 255 255" width="20%"/>
|
||||
<def id="name" heading="Name" color="255 255 255" width="65%"/>
|
||||
<def id="rank" color="255 255 255" width="15%">
|
||||
<translatableAttribute id="heading">Rank</translatableAttribute>
|
||||
</def>
|
||||
<def id="rating" color="255 255 255" width="20%">
|
||||
<translatableAttribute id="heading">Rating</translatableAttribute>
|
||||
</def>
|
||||
<def id="name" color="255 255 255" width="65%">
|
||||
<translatableAttribute id="heading">Name</translatableAttribute>
|
||||
</def>
|
||||
</object>
|
||||
<object type="button" style="StoneButton" size="50%+5 100%-45 50%+133 100%-17">
|
||||
Back
|
||||
<translatableAttribute id="caption">Back</translatableAttribute>
|
||||
<action on="Press">Engine.GetGUIObjectByName("leaderboard").hidden = true;Engine.GetGUIObjectByName("leaderboardFade").hidden = true;</action>
|
||||
</object>
|
||||
<object type="button" style="StoneButton" size="50%-133 100%-45 50%-5 100%-17">
|
||||
Update
|
||||
<translatableAttribute id="caption">Update</translatableAttribute>
|
||||
<action on="Press">Engine.SendGetBoardList();</action>
|
||||
</object>
|
||||
</object>
|
||||
|
@ -32,7 +32,7 @@ function lobbyStart()
|
||||
var room = Engine.ConfigDB_GetValue("user", "lobby.room");
|
||||
var history = Number(Engine.ConfigDB_GetValue("user", "lobby.history"));
|
||||
|
||||
feedback.caption = "Connecting....";
|
||||
feedback.caption = translate("Connecting...");
|
||||
// If they enter a different password, re-encrypt.
|
||||
if (password != g_EncrytedPassword.substring(0, 10))
|
||||
g_EncrytedPassword = Engine.EncryptPassword(password, username);
|
||||
@ -58,14 +58,14 @@ function lobbyStartRegister()
|
||||
// Check the passwords match.
|
||||
if (password != passwordAgain)
|
||||
{
|
||||
feedback.caption = "Passwords do not match";
|
||||
feedback.caption = translate("Passwords do not match");
|
||||
Engine.GetGUIObjectByName("connectPassword").caption = "";
|
||||
Engine.GetGUIObjectByName("registerPasswordAgain").caption = "";
|
||||
switchRegister();
|
||||
return;
|
||||
}
|
||||
|
||||
feedback.caption = "Registering...";
|
||||
feedback.caption = translate("Registering...");
|
||||
g_EncrytedPassword = Engine.EncryptPassword(password, account);
|
||||
Engine.StartRegisterXmppClient(account, g_EncrytedPassword);
|
||||
g_LobbyIsConnecting = true;
|
||||
@ -106,20 +106,21 @@ function onTick()
|
||||
connectButton.enabled = false;
|
||||
registerButton.enabled = false;
|
||||
if (!username && !password)
|
||||
feedback.caption = "Please enter existing login or desired registration credentials.";
|
||||
feedback.caption = translate("Please enter existing login or desired registration credentials.");
|
||||
}
|
||||
// Check they are using a valid account name.
|
||||
else if (username != sanitizedName)
|
||||
{
|
||||
feedback.caption = "Usernames can't contain [, ], unicode, whitespace, or commas.";
|
||||
feedback.caption = translate("Usernames can't contain [, ], unicode, whitespace, or commas.");
|
||||
connectButton.enabled = false;
|
||||
registerButton.enabled = false;
|
||||
}
|
||||
// Allow them to connect/begin registation if there aren't any problems.
|
||||
else if (pageRegisterHidden)
|
||||
{
|
||||
if (feedback.caption == "Usernames can't contain [, ], unicode, whitespace, or commas." ||
|
||||
feedback.caption == "Please enter existing login or desired registration credentials.")
|
||||
// TODO Do this without comparing the caption
|
||||
if (feedback.caption == translate("Usernames can't contain [, ], unicode, whitespace, or commas.") ||
|
||||
feedback.caption == translate("Please enter existing login or desired registration credentials."))
|
||||
feedback.caption = "";
|
||||
connectButton.enabled = true;
|
||||
registerButton.enabled = true;
|
||||
|
@ -16,20 +16,20 @@
|
||||
|
||||
<object name="pageConnecting" hidden="true">
|
||||
<object name="connectionStatus" type="text" text_align="center" size="0 100 100% 120">
|
||||
[Connection status]
|
||||
<translatableAttribute id="caption">[Connection status]</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object style="TitleText" type="text" size="50%-128 0%-16 50%+128 16">
|
||||
Multiplayer Lobby
|
||||
<translatableAttribute id="caption">Multiplayer Lobby</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object name="pageConnect" size="0 32 100% 100%">
|
||||
<object type="text" size="0 0 400 30" style="ModernLabelText" text_align="center">
|
||||
Connect to the game lobby
|
||||
<translatableAttribute id="caption">Connect to the game lobby</translatableAttribute>
|
||||
</object>
|
||||
<object name="connectUsernameLabel" type="text" size="50 40 125 70" style="ModernLabelText" text_align="right">
|
||||
Login:
|
||||
<translatableAttribute id="caption">Login:</translatableAttribute>
|
||||
</object>
|
||||
<object name="connectUsername" type="input" size="135 40 100%-50 64" style="ModernInput">
|
||||
<action on="Load">
|
||||
@ -37,7 +37,7 @@
|
||||
</action>
|
||||
</object>
|
||||
<object name="connectPasswordLabel" type="text" size="50 80 125 110" style="ModernLabelText" text_align="right">
|
||||
Password:
|
||||
<translatableAttribute id="caption">Password:</translatableAttribute>
|
||||
</object>
|
||||
<object name="connectPassword" type="input" size="135 80 100%-50 104" style="ModernInput" mask="true" mask_char="*">
|
||||
<action on="Load">
|
||||
@ -51,10 +51,10 @@
|
||||
</object>
|
||||
<object name="pageRegister" size="0 32 100% 100%" hidden="true">
|
||||
<object type="text" style="ModernLabelText" size="0 0 400 30" text_align="center">
|
||||
Registration
|
||||
<translatableAttribute id="caption">Registration</translatableAttribute>
|
||||
</object>
|
||||
<object type="text" size="50 40 170 70" style="ModernLabelText" text_align="right">
|
||||
Password again:
|
||||
<translatableAttribute id="caption">Password again:</translatableAttribute>
|
||||
</object>
|
||||
<object name="registerPasswordAgain" type="input" size="180 40 100%-50 64" style="ModernInput" mask="true" mask_char="*">
|
||||
<action on="Press">
|
||||
@ -64,7 +64,7 @@
|
||||
</object>
|
||||
<object name="feedback" type="text" size="50 150 100%-50 190" style="ModernLabelText" textcolor="red" text_align="center"/>
|
||||
<object type="button" size="18 100%-45 126 100%-17" style="StoneButton">
|
||||
Cancel
|
||||
<translatableAttribute id="caption">Cancel</translatableAttribute>
|
||||
<action on="Press">
|
||||
if (Engine.GetGUIObjectByName("pageRegister").hidden)
|
||||
{
|
||||
@ -76,7 +76,7 @@
|
||||
</action>
|
||||
</object>
|
||||
<object name="register" type="button" size="136 100%-45 244 100%-17" style="StoneButton">
|
||||
Register
|
||||
<translatableAttribute id="caption">Register</translatableAttribute>
|
||||
<action on="Press">
|
||||
if (Engine.GetGUIObjectByName("pageRegister").hidden)
|
||||
{
|
||||
@ -87,7 +87,7 @@
|
||||
</action>
|
||||
</object>
|
||||
<object name="connect" type="button" size="254 100%-45 100%-18 100%-17" style="StoneButton">
|
||||
Connect
|
||||
<translatableAttribute id="caption">Connect</translatableAttribute>
|
||||
<action on="Press">
|
||||
lobbyStart();
|
||||
</action>
|
||||
|
65
binaries/data/mods/public/gui/locale/locale.js
Normal file
65
binaries/data/mods/public/gui/locale/locale.js
Normal file
@ -0,0 +1,65 @@
|
||||
function init()
|
||||
{
|
||||
var languageList = Engine.GetGUIObjectByName("languageList");
|
||||
languageList.list = Engine.GetSupportedLocaleDisplayNames();
|
||||
languageList.list_data = Engine.GetSupportedLocaleBaseNames();
|
||||
|
||||
var currentLocale = Engine.GetCurrentLocale();
|
||||
var currentLocaleBaseName = Engine.GetLocaleBaseName(currentLocale);
|
||||
var currentLocaleLanguage = Engine.GetLocaleLanguage(currentLocale);
|
||||
if (languageList.list_data.indexOf(currentLocaleBaseName) != -1)
|
||||
languageList.selected = languageList.list_data.indexOf(currentLocaleBaseName);
|
||||
else if (languageList.list_data.indexOf(currentLocaleLanguage) != -1)
|
||||
languageList.selected = languageList.list_data.indexOf(currentLocaleLanguage);
|
||||
|
||||
var localeText = Engine.GetGUIObjectByName("localeText");
|
||||
localeText.caption = currentLocale;
|
||||
}
|
||||
|
||||
function cancelSetup()
|
||||
{
|
||||
Engine.PopGuiPage();
|
||||
}
|
||||
|
||||
function applySelectedLocale()
|
||||
{
|
||||
var localeText = Engine.GetGUIObjectByName("localeText");
|
||||
if(!Engine.SaveLocale(localeText.caption))
|
||||
{
|
||||
warn("Selected locale could not be saved in the configuration!");
|
||||
return;
|
||||
}
|
||||
Engine.ReevaluateCurrentLocaleAndReload();
|
||||
Engine.SwitchGuiPage("page_pregame.xml");
|
||||
}
|
||||
|
||||
function languageSelectionChanged()
|
||||
{
|
||||
var languageList = Engine.GetGUIObjectByName("languageList");
|
||||
var locale = languageList.list_data[languageList.selected];
|
||||
if(!Engine.ValidateLocale(locale))
|
||||
warn("Selected locale is not valid! This is not expected, please report the issue.");
|
||||
var localeText = Engine.GetGUIObjectByName("localeText");
|
||||
localeText.caption = locale;
|
||||
}
|
||||
|
||||
function openAdvancedMenu()
|
||||
{
|
||||
var localeText = Engine.GetGUIObjectByName("localeText");
|
||||
Engine.PushGuiPage("page_locale_advanced.xml", { "callback": "applyFromAdvancedMenu", "locale": localeText.caption } );
|
||||
}
|
||||
|
||||
function applyFromAdvancedMenu(locale)
|
||||
{
|
||||
var languageList = Engine.GetGUIObjectByName("languageList");
|
||||
|
||||
var localeBaseName = Engine.GetLocaleBaseName(locale);
|
||||
var localeLanguage = Engine.GetLocaleLanguage(locale);
|
||||
if (languageList.list_data.indexOf(localeBaseName) != -1)
|
||||
languageList.selected = languageList.list_data.indexOf(localeBaseName);
|
||||
else if (languageList.list_data.indexOf(localeLanguage) != -1)
|
||||
languageList.selected = languageList.list_data.indexOf(localeLanguage);
|
||||
|
||||
var localeText = Engine.GetGUIObjectByName("localeText");
|
||||
localeText.caption = locale;
|
||||
}
|
47
binaries/data/mods/public/gui/locale/locale.xml
Normal file
47
binaries/data/mods/public/gui/locale/locale.xml
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<objects>
|
||||
|
||||
<script file="gui/common/functions_global_object.js"/>
|
||||
<script file="gui/locale/locale.js"/>
|
||||
|
||||
<!-- Add a translucent black background to fade out the menu page -->
|
||||
<object type="image" z="0" sprite="bkTranslucent"/>
|
||||
|
||||
<object type="image" style="ModernDialog" size="50%-190 50%-100 50%+190 50%+100">
|
||||
<object size="15 0 100%-15 100%">
|
||||
<object style="TitleText" type="text" size="50%-128 0%-16 50%+128 16">
|
||||
<translatableAttribute id="caption">Language</translatableAttribute>
|
||||
</object>
|
||||
<object type="text" size="5 50 40% 75" style="ModernLeftLabelText">
|
||||
<translatableAttribute id="caption">Language:</translatableAttribute>
|
||||
</object>
|
||||
<object name="languageList"
|
||||
type="dropdown"
|
||||
style="ModernDropDown"
|
||||
size="40%+10 50 100% 75">
|
||||
<action on="SelectionChange">languageSelectionChanged();</action>
|
||||
</object>
|
||||
<object type="text" size="5 80 40% 105" style="ModernLeftLabelText">
|
||||
<translatableAttribute id="caption">Locale:</translatableAttribute>
|
||||
</object>
|
||||
<object name="localeText" type="text" size="40%+10 80 100% 105" textcolor="white" />
|
||||
|
||||
<object type="button" size="0 100%-60 33% 100%-32" style="StoneButton">
|
||||
<translatableAttribute id="caption">Accept</translatableAttribute>
|
||||
<action on="Press">applySelectedLocale();</action>
|
||||
</object>
|
||||
|
||||
<object type="button" size="33%+5 100%-60 66% 100%-32" style="StoneButton">
|
||||
<translatableAttribute id="caption">Advanced</translatableAttribute>
|
||||
<action on="Press">openAdvancedMenu();</action>
|
||||
</object>
|
||||
|
||||
<object type="button" style="StoneButton" size="66%+5 100%-60 100% 100%-32">
|
||||
<translatableAttribute id="caption">Cancel</translatableAttribute>
|
||||
<action on="Press">cancelSetup();</action>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
</objects>
|
115
binaries/data/mods/public/gui/locale/locale_advanced.js
Normal file
115
binaries/data/mods/public/gui/locale/locale_advanced.js
Normal file
@ -0,0 +1,115 @@
|
||||
function init(initData)
|
||||
{
|
||||
var languageList = Engine.GetGUIObjectByName("languageList");
|
||||
var countryList = Engine.GetGUIObjectByName("countryList");
|
||||
var resultingLocaleText = Engine.GetGUIObjectByName("resultingLocale");
|
||||
var scriptInput = Engine.GetGUIObjectByName("scriptInput");
|
||||
|
||||
// get languageList data. Only list languages for which we have a dictionary.
|
||||
var languageListData = [];
|
||||
var languageListTmp = Engine.GetSupportedLocaleBaseNames();
|
||||
var currentLocaleLanguage = Engine.GetLocaleLanguage(initData.locale);
|
||||
for (var i=0; i<languageListTmp.length; ++i)
|
||||
{
|
||||
var lang = Engine.GetLocaleLanguage(languageListTmp[i]);
|
||||
if (lang != "" && languageListData.indexOf(lang) == -1)
|
||||
languageListData.push(lang);
|
||||
}
|
||||
|
||||
|
||||
// get countryList data (we get all countries and not only the ones we have dictionaries for)
|
||||
var countryListData = [];
|
||||
countryListData.push(translateWithContext("localeCountry", "None"));
|
||||
var countryListTmp = Engine.GetAllLocales();
|
||||
var currentLocaleCountry = Engine.GetLocaleCountry(initData.locale);
|
||||
for (var i=0; i<countryListTmp.length; ++i)
|
||||
{
|
||||
var country = Engine.GetLocaleCountry(countryListTmp[i]);
|
||||
if (country != "" && countryListData.indexOf(country) == -1)
|
||||
countryListData.push(country);
|
||||
}
|
||||
|
||||
// fill the languageList
|
||||
languageList.list = languageListData;
|
||||
languageList.list_data = languageListData;
|
||||
if (languageList.list_data.indexOf(currentLocaleLanguage) != -1)
|
||||
languageList.selected = languageList.list_data.indexOf(currentLocaleLanguage);
|
||||
|
||||
// fill the country list
|
||||
countryList.list = countryListData;
|
||||
countryList.list_data = countryListData;
|
||||
if (currentLocaleCountry != "")
|
||||
countryList.selected = countryList.list_data.indexOf(currentLocaleCountry);
|
||||
else
|
||||
countryList.selected = 0;
|
||||
|
||||
// fill the script
|
||||
scriptInput.caption = Engine.GetLocaleScript(initData.locale);
|
||||
}
|
||||
|
||||
// TODO: an onChanged event for input boxes would be useful and would allow us to avoid a tick event here.
|
||||
function onTick()
|
||||
{
|
||||
updateResultingLocale();
|
||||
}
|
||||
|
||||
function cancelSetup()
|
||||
{
|
||||
Engine.PopGuiPage();
|
||||
}
|
||||
|
||||
function updateResultingLocale()
|
||||
{
|
||||
var languageList = Engine.GetGUIObjectByName("languageList");
|
||||
var countryList = Engine.GetGUIObjectByName("countryList");
|
||||
var resultingLocaleText = Engine.GetGUIObjectByName("resultingLocale");
|
||||
var scriptInput = Engine.GetGUIObjectByName("scriptInput");
|
||||
var variantInput = Engine.GetGUIObjectByName("variantInput");
|
||||
var dictionaryFile = Engine.GetGUIObjectByName("dictionaryFile");
|
||||
var resultingLocaleTmp = "";
|
||||
|
||||
var resultingLocaleTmp = languageList.list_data[languageList.selected];
|
||||
|
||||
if (scriptInput.caption != "")
|
||||
resultingLocaleTmp = resultingLocaleTmp + "_" + scriptInput.caption;
|
||||
|
||||
if (countryList.selected != -1 && countryList.list_data[countryList.selected] != translateWithContext("localeCountry", "None"))
|
||||
resultingLocaleTmp = resultingLocaleTmp + "_" + countryList.list_data[countryList.selected];
|
||||
|
||||
if (Engine.ValidateLocale(resultingLocaleTmp))
|
||||
{
|
||||
resultingLocaleText.caption = resultingLocaleTmp;
|
||||
var dictionaryFileList = Engine.GetDictionariesForDictLocale(Engine.GetDictionaryLocale(resultingLocaleTmp));
|
||||
var dictionaryFileString = "";
|
||||
dictionaryFileList.forEach( function (entry) { dictionaryFileString = dictionaryFileString + entry + "\n"; });
|
||||
dictionaryFile.caption = dictionaryFileString;
|
||||
}
|
||||
else
|
||||
{
|
||||
resultingLocaleText.caption = translate("<invalid>");
|
||||
dictionaryFile.caption = "";
|
||||
}
|
||||
}
|
||||
|
||||
function autoDetectLocale()
|
||||
{
|
||||
var languageList = Engine.GetGUIObjectByName("languageList");
|
||||
var countryList = Engine.GetGUIObjectByName("countryList");
|
||||
var scriptInput = Engine.GetGUIObjectByName("scriptInput");
|
||||
var variantInput = Engine.GetGUIObjectByName("variantInput");
|
||||
var dictionaryFile = Engine.GetGUIObjectByName("dictionaryFile");
|
||||
|
||||
variantInput.caption = "";
|
||||
dictionaryFile.caption = "";
|
||||
var locale = Engine.GetDictionaryLocale("");
|
||||
|
||||
languageList.selected = languageList.list_data.indexOf(Engine.GetLocaleLanguage(locale));
|
||||
countryList.selected = countryList.selected = countryList.list_data.indexOf(Engine.GetLocaleCountry(locale));
|
||||
scriptInput.caption = Engine.GetLocaleScript(locale);
|
||||
}
|
||||
|
||||
function applySelectedLocale()
|
||||
{
|
||||
var resultingLocaleText = Engine.GetGUIObjectByName("resultingLocale");
|
||||
Engine.PopGuiPageCB(resultingLocaleText.caption);
|
||||
}
|
81
binaries/data/mods/public/gui/locale/locale_advanced.xml
Normal file
81
binaries/data/mods/public/gui/locale/locale_advanced.xml
Normal file
@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<objects>
|
||||
|
||||
<script file="gui/common/functions_global_object.js"/>
|
||||
<script file="gui/locale/locale_advanced.js"/>
|
||||
|
||||
<!-- Add a translucent black background to fade out the menu page -->
|
||||
<object type="image" z="0" sprite="bkTranslucent"/>
|
||||
<object type="image" style="ModernDialog" size="50%-220 50%-200 50%+220 50%+200">
|
||||
<action on="Tick">onTick();</action>
|
||||
<object size="15 0 100%-15 100%">
|
||||
<object style="TitleText" type="text" size="50%-150 0%-16 50%+150 16">
|
||||
<translatableAttribute id="caption">Language</translatableAttribute>
|
||||
</object>
|
||||
<object type="text" size="5 50 40% 75" style="ModernLeftLabelText">
|
||||
<translatableAttribute id="caption">Language:</translatableAttribute>
|
||||
</object>
|
||||
<object name="languageList"
|
||||
type="dropdown"
|
||||
style="ModernDropDown"
|
||||
size="40%+10 50 100% 75">
|
||||
</object>
|
||||
<object type="text" size="5 80 40% 105" style="ModernLeftLabelText">
|
||||
<translatableAttribute id="caption">Country:</translatableAttribute>
|
||||
</object>
|
||||
<object name="countryList"
|
||||
type="dropdown"
|
||||
style="ModernDropDown"
|
||||
size="40%+10 80 100% 105">
|
||||
</object>
|
||||
|
||||
<object type="text" size="5 110 40% 135" style="ModernLeftLabelText">
|
||||
<translatableAttribute id="caption">Script:</translatableAttribute>
|
||||
</object>
|
||||
<object name="scriptInput" size="40%+10 110 100% 135" type="input" style="ModernInput">
|
||||
<translatableAttribute id="tooltip">Optional four-letter script code part following the language code (as listed in ISO 15924)</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object type="text" size="5 140 40% 165" style="ModernLeftLabelText">
|
||||
<translatableAttribute id="caption">Variant (unused):</translatableAttribute>
|
||||
</object>
|
||||
<object name="variantInput" size="40%+10 140 100% 165" type="input" style="ModernInput">
|
||||
<translatableAttribute id="tooltip">Not implemented yet.</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object type="text" size="5 170 40% 195" style="ModernLeftLabelText">
|
||||
<translatableAttribute id="caption">Keywords (unused):</translatableAttribute>
|
||||
</object>
|
||||
<object name="keywordsInput" size="40%+10 170 100% 195" type="input" style="ModernInput">
|
||||
<translatableAttribute id="tooltip">Not implemented yet.</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object type="text" size="5 230 40% 255" style="ModernLeftLabelText">
|
||||
<translatableAttribute id="caption">Resulting locale:</translatableAttribute>
|
||||
</object>
|
||||
<object name="resultingLocale" type="text" size="40%+10 230 100% 255" textcolor="white" />
|
||||
|
||||
<object type="text" size="5 260 40% 285" style="ModernLeftLabelText">
|
||||
<translatableAttribute id="caption">Dictionary files used:</translatableAttribute>
|
||||
</object>
|
||||
<object name="dictionaryFile" type="text" size="40%+10 260 100% 345" textcolor="white" />
|
||||
|
||||
<object type="button" size="0 100%-60 33% 100%-32" style="StoneButton">
|
||||
<translatableAttribute id="caption">Accept</translatableAttribute>
|
||||
<action on="Press">applySelectedLocale();</action>
|
||||
</object>
|
||||
|
||||
<object type="button" size="33%+5 100%-60 66% 100%-32" style="StoneButton">
|
||||
<translatableAttribute id="caption">Auto detect</translatableAttribute>
|
||||
<action on="Press">autoDetectLocale();</action>
|
||||
</object>
|
||||
|
||||
<object type="button" style="StoneButton" size="66%+5 100%-60 100% 100%-32">
|
||||
<translatableAttribute id="caption">Cancel</translatableAttribute>
|
||||
<action on="Press">cancelSetup();</action>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
</objects>
|
@ -2,7 +2,7 @@ var hasCallback = false;
|
||||
|
||||
function init(data)
|
||||
{
|
||||
Engine.GetGUIObjectByName("mainText").caption = Engine.ReadFile("gui/manual/" + data.page + ".txt");
|
||||
Engine.GetGUIObjectByName("mainText").caption = Engine.TranslateLines(Engine.ReadFile("gui/manual/" + data.page + ".txt"));
|
||||
if (data.callback)
|
||||
hasCallback = true;
|
||||
}
|
||||
|
@ -8,21 +8,24 @@
|
||||
<object type="image" z="0" style="TranslucentPanel"/>
|
||||
|
||||
<object type="image" style="ModernDialog" size="50%-466 50%-316 50%+466 50%+316">
|
||||
<object type="text" style="TitleText" size="50%-128 0%-16 50%+128 16">Manual</object>
|
||||
<object type="text" style="TitleText" size="50%-128 0%-16 50%+128 16">
|
||||
<translatableAttribute id="caption">Manual</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object type="image" sprite="ModernFade" size="20 20 100%-20 100%-58">
|
||||
<object name="mainText" type="text" style="textPanel"/>
|
||||
</object>
|
||||
<object type="button" style="StoneButton" size="100%-308 100%-52 100%-168 100%-24">
|
||||
Online Manual
|
||||
|
||||
<object type="button" style="StoneButton" size="100%-308 100%-52 100%-168 100%-24">
|
||||
<translatableAttribute id="caption">Online Manual</translatableAttribute>
|
||||
<action on="Press"><![CDATA[
|
||||
var url = "http://trac.wildfiregames.com/wiki/0adManual";
|
||||
Engine.OpenURL(url);
|
||||
messageBox(450, 200, "Opening "+url+"\n in default web browser. Please wait...", "Opening page", 2);
|
||||
]]></action>
|
||||
]]></action>
|
||||
</object>
|
||||
<object type="button" style="StoneButton" tooltip_style="snToolTip" size="100%-164 100%-52 100%-24 100%-24">
|
||||
Close
|
||||
<translatableAttribute id="caption">Close</translatableAttribute>
|
||||
<action on="Press"><![CDATA[closeManual();]]></action>
|
||||
</object>
|
||||
</object>
|
||||
|
100
binaries/data/mods/public/gui/msgbox/msgbox.js
Normal file
100
binaries/data/mods/public/gui/msgbox/msgbox.js
Normal file
@ -0,0 +1,100 @@
|
||||
function init(data)
|
||||
{
|
||||
var mbMainObj = Engine.GetGUIObjectByName("mbMain");
|
||||
var mbTitleObj = Engine.GetGUIObjectByName("mbTitleBar");
|
||||
var mbTextObj = Engine.GetGUIObjectByName("mbText");
|
||||
|
||||
var mbButton1Obj = Engine.GetGUIObjectByName("mbButton1");
|
||||
var mbButton2Obj = Engine.GetGUIObjectByName("mbButton2");
|
||||
var mbButton3Obj = Engine.GetGUIObjectByName("mbButton3");
|
||||
|
||||
// Calculate size
|
||||
var mbLRDiff = data.width / 2; // Message box left/right difference from 50% of screen
|
||||
var mbUDDiff = data.height / 2; // Message box up/down difference from 50% of screen
|
||||
|
||||
var mbSizeString = "50%-" + mbLRDiff + " 50%-" + mbUDDiff + " 50%+" + mbLRDiff + " 50%+" + mbUDDiff;
|
||||
|
||||
mbMainObj.size = mbSizeString;
|
||||
|
||||
// Texts
|
||||
mbTitleObj.caption = data.title;
|
||||
mbTextObj.caption = data.message;
|
||||
|
||||
if (data.font)
|
||||
mbTextObj.font = data.font;
|
||||
|
||||
// Message box modes
|
||||
// There is a number of standard modes, and if none of these is used (mbMode == 0), the button captions will be
|
||||
// taken from the array mbButtonCaptions; there currently is a maximum of three buttons.
|
||||
switch (data.mode)
|
||||
{
|
||||
case 1:
|
||||
// Simple Yes/No question box
|
||||
data.buttonCaptions = [translate("Yes"), translate("No")];
|
||||
break;
|
||||
case 2:
|
||||
// Okay-only box
|
||||
data.buttonCaptions = [translate("OK")];
|
||||
break;
|
||||
case 3:
|
||||
// Retry/Abort/Ignore box (will we ever need this?!)
|
||||
data.buttonCaptions = [translate("Retry"), translate("Ignore"), translate("Abort")];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Buttons
|
||||
var codes = data.buttonCode;
|
||||
if (data.buttonCaptions.length >= 1)
|
||||
{
|
||||
mbButton1Obj.caption = data.buttonCaptions[0];
|
||||
mbButton1Obj.onPress = function ()
|
||||
{
|
||||
if (data.callback)
|
||||
Engine.PopGuiPageCB(0);
|
||||
else
|
||||
Engine.PopGuiPage();
|
||||
};
|
||||
mbButton1Obj.hidden = false;
|
||||
}
|
||||
if (data.buttonCaptions.length >= 2)
|
||||
{
|
||||
mbButton2Obj.caption = data.buttonCaptions[1];
|
||||
mbButton2Obj.onPress = function ()
|
||||
{
|
||||
if (data.callback)
|
||||
Engine.PopGuiPageCB(1);
|
||||
else
|
||||
Engine.PopGuiPage();
|
||||
};
|
||||
mbButton2Obj.hidden = false;
|
||||
}
|
||||
if (data.buttonCaptions.length >= 3)
|
||||
{
|
||||
mbButton3Obj.caption = data.buttonCaptions[2];
|
||||
mbButton3Obj.onPress = function ()
|
||||
{
|
||||
if (data.callback)
|
||||
Engine.PopGuiPageCB(2);
|
||||
else
|
||||
Engine.PopGuiPage();
|
||||
};
|
||||
mbButton3Obj.hidden = false;
|
||||
}
|
||||
|
||||
switch (data.buttonCaptions.length)
|
||||
{
|
||||
case 1:
|
||||
mbButton1Obj.size = "50%-64 100%-76 50%+64 100%-48";
|
||||
break;
|
||||
case 2:
|
||||
mbButton1Obj.size = "50%-144 100%-76 50%-16 100%-48";
|
||||
mbButton2Obj.size = "50%+16 100%-76 50%+144 100%-48";
|
||||
break;
|
||||
case 3:
|
||||
mbButton1Obj.size = "10% 100%-76 30% 100%-48";
|
||||
mbButton2Obj.size = "40% 100%-76 60% 100%-48";
|
||||
mbButton3Obj.size = "70% 100%-76 90% 100%-48";
|
||||
break;
|
||||
}
|
||||
}
|
@ -1,108 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<objects>
|
||||
<script><![CDATA[
|
||||
function init(data)
|
||||
{
|
||||
var mbMainObj = Engine.GetGUIObjectByName("mbMain");
|
||||
var mbTitleObj = Engine.GetGUIObjectByName("mbTitleBar");
|
||||
var mbTextObj = Engine.GetGUIObjectByName("mbText");
|
||||
|
||||
var mbButton1Obj = Engine.GetGUIObjectByName("mbButton1");
|
||||
var mbButton2Obj = Engine.GetGUIObjectByName("mbButton2");
|
||||
var mbButton3Obj = Engine.GetGUIObjectByName("mbButton3");
|
||||
|
||||
// Calculate size
|
||||
var mbLRDiff = data.width / 2; // Message box left/right difference from 50% of screen
|
||||
var mbUDDiff = data.height / 2; // Message box up/down difference from 50% of screen
|
||||
|
||||
var mbSizeString = "50%-" + mbLRDiff + " 50%-" + mbUDDiff + " 50%+" + mbLRDiff + " 50%+" + mbUDDiff;
|
||||
|
||||
mbMainObj.size = mbSizeString;
|
||||
|
||||
// Texts
|
||||
mbTitleObj.caption = data.title;
|
||||
mbTextObj.caption = data.message;
|
||||
|
||||
if (data.font)
|
||||
mbTextObj.font = data.font;
|
||||
|
||||
// Message box modes
|
||||
// There is a number of standard modes, and if none of these is used (mbMode == 0), the button captions will be
|
||||
// taken from the array mbButtonCaptions; there currently is a maximum of three buttons.
|
||||
switch (data.mode)
|
||||
{
|
||||
case 1:
|
||||
// Simple Yes/No question box
|
||||
data.buttonCaptions = ["Yes", "No"];
|
||||
break;
|
||||
case 2:
|
||||
// Okay-only box
|
||||
data.buttonCaptions = ["OK"];
|
||||
break;
|
||||
case 3:
|
||||
// Retry/Abort/Ignore box (will we ever need this?!)
|
||||
data.buttonCaptions = ["Retry", "Ignore", "Abort"];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Buttons
|
||||
var codes = data.buttonCode;
|
||||
if (data.buttonCaptions.length >= 1)
|
||||
{
|
||||
mbButton1Obj.caption = data.buttonCaptions[0];
|
||||
mbButton1Obj.onPress = function ()
|
||||
{
|
||||
if (data.callback)
|
||||
Engine.PopGuiPageCB(0);
|
||||
else
|
||||
Engine.PopGuiPage();
|
||||
};
|
||||
mbButton1Obj.hidden = false;
|
||||
}
|
||||
if (data.buttonCaptions.length >= 2)
|
||||
{
|
||||
mbButton2Obj.caption = data.buttonCaptions[1];
|
||||
mbButton2Obj.onPress = function ()
|
||||
{
|
||||
if (data.callback)
|
||||
Engine.PopGuiPageCB(1);
|
||||
else
|
||||
Engine.PopGuiPage();
|
||||
};
|
||||
mbButton2Obj.hidden = false;
|
||||
}
|
||||
if (data.buttonCaptions.length >= 3)
|
||||
{
|
||||
mbButton3Obj.caption = data.buttonCaptions[2];
|
||||
mbButton3Obj.onPress = function ()
|
||||
{
|
||||
if (data.callback)
|
||||
Engine.PopGuiPageCB(2);
|
||||
else
|
||||
Engine.PopGuiPage();
|
||||
};
|
||||
mbButton3Obj.hidden = false;
|
||||
}
|
||||
|
||||
switch (data.buttonCaptions.length)
|
||||
{
|
||||
case 1:
|
||||
mbButton1Obj.size = "50%-64 100%-76 50%+64 100%-48";
|
||||
break;
|
||||
case 2:
|
||||
mbButton1Obj.size = "50%-144 100%-76 50%-16 100%-48";
|
||||
mbButton2Obj.size = "50%+16 100%-76 50%+144 100%-48";
|
||||
break;
|
||||
case 3:
|
||||
mbButton1Obj.size = "10% 100%-76 30% 100%-48";
|
||||
mbButton2Obj.size = "40% 100%-76 60% 100%-48";
|
||||
mbButton3Obj.size = "70% 100%-76 90% 100%-48";
|
||||
break;
|
||||
}
|
||||
}
|
||||
]]></script>
|
||||
<script file="gui/msgbox/msgbox.js"/>
|
||||
|
||||
<object hotkey="leave">
|
||||
<action on="Press">Engine.PopGuiPage();</action>
|
||||
|
@ -5,37 +5,37 @@
|
||||
var options = {
|
||||
"generalSetting":
|
||||
[
|
||||
["Windowed Mode", "Start 0 A.D. in windowed mode", {"config":"windowed"}, "boolean"],
|
||||
["Background Pause", "Pause single player games when window loses focus", {"config":"pauseonfocusloss"}, "boolean"],
|
||||
[translate("Windowed Mode"), translate("Start 0 A.D. in windowed mode"), {"config":"windowed"}, "boolean"],
|
||||
[translate("Background Pause"), translate("Pause single player games when window loses focus"), {"config":"pauseonfocusloss"}, "boolean"],
|
||||
],
|
||||
"graphicsSetting":
|
||||
[
|
||||
["Prefer GLSL", "Use OpenGL 2.0 shaders (recommended)", {"renderer":"PreferGLSL"}, "boolean"],
|
||||
["Shadows", "Enable shadows", {"renderer":"Shadows"}, "boolean"],
|
||||
["Particles", "Enable particles", {"renderer":"Particles"}, "boolean"],
|
||||
["Show Sky", "Render Sky", {"renderer":"ShowSky"}, "boolean"],
|
||||
["Unit Silhouettes", "Show outlines of units behind buildings", {"renderer":"Silhouettes"}, "boolean"],
|
||||
["Shadow Flitering", "Smooth shadows", {"renderer":"ShadowPCF"}, "boolean"],
|
||||
["HQ Waviness", "Use real normals for ocean-wave rendering, instead of applying them as a flat texture", {"renderer":"WaterNormal"}, "boolean"],
|
||||
["Real Water Depth", "Use actual water depth in rendering calculations", {"renderer":"WaterRealDepth"}, "boolean"],
|
||||
["Water Reflections", "Allow water to reflect a mirror image", {"renderer":"WaterReflection"}, "boolean"],
|
||||
["Water Refraction", "Use a real water refraction map and not transparency", {"renderer":"WaterRefraction"}, "boolean"],
|
||||
["Shore Foam", "Show foam on water near shore depending on water waviness", {"renderer":"WaterFoam"}, "boolean"],
|
||||
["Shore Waves", "Show breaking waves on water near shore (Requires HQ Waviness)", {"renderer":"WaterCoastalWaves"}, "boolean"],
|
||||
["Water Shadows", "Cast shadows on water", {"renderer":"WaterShadow"}, "boolean"],
|
||||
[translate("Prefer GLSL"), translate("Use OpenGL 2.0 shaders (recommended)"), {"renderer":"PreferGLSL"}, "boolean"],
|
||||
[translate("Shadows"), translate("Enable shadows"), {"renderer":"Shadows"}, "boolean"],
|
||||
[translate("Particles"), translate("Enable particles"), {"renderer":"Particles"}, "boolean"],
|
||||
[translate("Show Sky"), translate("Render Sky"), {"renderer":"ShowSky"}, "boolean"],
|
||||
[translate("Unit Silhouettes"), translate("Show outlines of units behind buildings"), {"renderer":"Silhouettes"}, "boolean"],
|
||||
[translate("Shadow Filtering"), translate("Smooth shadows"), {"renderer":"ShadowPCF"}, "boolean"],
|
||||
[translate("HQ Waviness"), translate("Use real normals for ocean-wave rendering, instead of applying them as a flat texture"), {"renderer":"WaterNormal"}, "boolean"],
|
||||
[translate("Real Water Depth"), translate("Use actual water depth in rendering calculations"), {"renderer":"WaterRealDepth"}, "boolean"],
|
||||
[translate("Water Reflections"), translate("Allow water to reflect a mirror image"), {"renderer":"WaterReflection"}, "boolean"],
|
||||
[translate("Water Refraction"), translate("Use a real water refraction map and not transparency"), {"renderer":"WaterRefraction"}, "boolean"],
|
||||
[translate("Shore Foam"), translate("Show foam on water near shore depending on water waviness"), {"renderer":"WaterFoam"}, "boolean"],
|
||||
[translate("Shore Waves"), translate("Show breaking waves on water near shore (Requires HQ Waviness)"), {"renderer":"WaterCoastalWaves"}, "boolean"],
|
||||
[translate("Water Shadows"), translate("Cast shadows on water"), {"renderer":"WaterShadow"}, "boolean"],
|
||||
],
|
||||
"soundSetting":
|
||||
[
|
||||
["Master Gain", "Master audio gain", {"config":"sound.mastergain", "function":"Engine.SetMasterGain(Number(this.caption));"}, "number"],
|
||||
["Music Gain", "In game music gain", {"config":"sound.musicgain", "function":"Engine.SetMusicGain(Number(this.caption));"}, "number"],
|
||||
["Ambient Gain", "In game ambient sound gain", {"config":"sound.ambientgain", "function":"Engine.SetMusicGain(Number(this.caption));"}, "number"],
|
||||
["Action Gain", "In game unit action sound gain", {"config":"sound.actiongain", "function":"Engine.SetMusicGain(Number(this.caption));"}, "number"],
|
||||
["UI Gain", "UI sound gain", {"config":"sound.uigain", "function":"Engine.SetMusicGain(Number(this.caption));"}, "number"],
|
||||
[translate("Master Gain"), translate("Master audio gain"), {"config":"sound.mastergain", "function":"Engine.SetMasterGain(Number(this.caption));"}, "number"],
|
||||
[translate("Music Gain"), translate("In game music gain"), {"config":"sound.musicgain", "function":"Engine.SetMusicGain(Number(this.caption));"}, "number"],
|
||||
[translate("Ambient Gain"), translate("In game ambient sound gain"), {"config":"sound.ambientgain", "function":"Engine.SetMusicGain(Number(this.caption));"}, "number"],
|
||||
[translate("Action Gain"), translate("In game unit action sound gain"), {"config":"sound.actiongain", "function":"Engine.SetMusicGain(Number(this.caption));"}, "number"],
|
||||
[translate("UI Gain"), translate("UI sound gain"), {"config":"sound.uigain", "function":"Engine.SetMusicGain(Number(this.caption));"}, "number"],
|
||||
],
|
||||
"lobbySetting":
|
||||
[
|
||||
["Chat Backlog", "Number of backlogged messages to load when joining the lobby", {"config":"lobby.history"}, "number"],
|
||||
["Chat Timestamp", "Show time that messages are posted in the lobby chat", {"config":"lobby.chattimestamp"}, "boolean"],
|
||||
[translate("Chat Backlog"), translate("Number of backlogged messages to load when joining the lobby"), {"config":"lobby.history"}, "number"],
|
||||
[translate("Chat Timestamp"), translate("Show time that messages are posted in the lobby chat"), {"config":"lobby.chattimestamp"}, "boolean"],
|
||||
],
|
||||
};
|
||||
|
||||
|
@ -11,12 +11,16 @@
|
||||
|
||||
<!-- Add a translucent black background to fade out the menu page -->
|
||||
<object type="image" z="0" style="TranslucentPanel"/>
|
||||
|
||||
|
||||
<!-- Settings Window -->
|
||||
<object name="options" type="image" style="ModernDialog" size="50%-466 50%-316 50%+466 50%+316">
|
||||
<object style="TitleText" type="text" size="50%-128 0%-16 50%+128 16">Game Options</object>
|
||||
<object style="TitleText" type="text" size="50%-128 0%-16 50%+128 16">
|
||||
<translatableAttribute id="caption">Game Options</translatableAttribute>
|
||||
</object>
|
||||
<object name="GeneralSettings" type="image" sprite="ModernDarkBoxGold" size="16 16 312 100%-16">
|
||||
<object style="TitleText" type="text" size="0 5 100% 25">General</object>
|
||||
<object style="TitleText" type="text" size="0 5 100% 25">
|
||||
<translatableAttribute id="caption">General</translatableAttribute>
|
||||
</object>
|
||||
<repeat count="23">
|
||||
<object name="generalSetting[n]" size="0 25 100% 50" hidden="true">
|
||||
<object name="generalSettingLabel[n]" size="0 0 65% 100%" type="text" style="ModernLabelText" text_align="right"/>
|
||||
@ -26,7 +30,9 @@
|
||||
</repeat>
|
||||
</object>
|
||||
<object name="GraphicsSettings" type="image" sprite="ModernDarkBoxGold" size="320 16 612 100%-56">
|
||||
<object style="TitleText" type="text" size="0 5 100% 25">Graphics Settings</object>
|
||||
<object style="TitleText" type="text" size="0 5 100% 25">
|
||||
<translatableAttribute id="caption">Graphics Settings</translatableAttribute>
|
||||
</object>
|
||||
<repeat count="21">
|
||||
<object name="graphicsSetting[n]" size="0 25 100% 50" hidden="true">
|
||||
<object name="graphicsSettingLabel[n]" size="0 0 65% 100%" type="text" style="ModernLabelText" text_align="right"/>
|
||||
@ -36,7 +42,9 @@
|
||||
</repeat>
|
||||
</object>
|
||||
<object name="SoundSettings" type="image" sprite="ModernDarkBoxGold" size="620 16 916 50%-4">
|
||||
<object style="TitleText" type="text" size="0 5 100% 25">Sound Settings</object>
|
||||
<object style="TitleText" type="text" size="0 5 100% 25">
|
||||
<translatableAttribute id="caption">Sound Settings</translatableAttribute>
|
||||
</object>
|
||||
<repeat count="10">
|
||||
<object name="soundSetting[n]" size="0 25 100% 50" hidden="true">
|
||||
<object name="soundSettingLabel[n]" size="0 0 65% 100%" type="text" style="ModernLabelText" text_align="right"/>
|
||||
@ -46,7 +54,9 @@
|
||||
</repeat>
|
||||
</object>
|
||||
<object name="LobbySettings" type="image" sprite="ModernDarkBoxGold" size="620 50%+4 916 100%-16">
|
||||
<object style="TitleText" type="text" size="0 5 100% 25">Lobby Settings</object>
|
||||
<object style="TitleText" type="text" size="0 5 100% 25">
|
||||
<translatableAttribute id="caption">Lobby Settings</translatableAttribute>
|
||||
</object>
|
||||
<repeat count="10">
|
||||
<object name="lobbySetting[n]" size="0 25 100% 50" hidden="true">
|
||||
<object name="lobbySettingLabel[n]" size="0 0 65% 100%" type="text" style="ModernLabelText" text_align="right"/>
|
||||
@ -56,11 +66,11 @@
|
||||
</repeat>
|
||||
</object>
|
||||
<object type="button" style="StoneButton" size="320 100%-48 50%-4 100%-16">
|
||||
Save
|
||||
<translatableAttribute id="caption">Save</translatableAttribute>
|
||||
<action on="Press">Engine.ConfigDB_WriteFile("user", "config/user.cfg");Engine.PopGuiPage();</action>
|
||||
</object>
|
||||
<object type="button" style="StoneButton" size="50%+4 100%-48 612 100%-16">
|
||||
Cancel
|
||||
<translatableAttribute id="caption">Cancel</translatableAttribute>
|
||||
<action on="Press">Engine.PopGuiPage();</action>
|
||||
</object>
|
||||
</object>
|
||||
|
16
binaries/data/mods/public/gui/page_locale.xml
Normal file
16
binaries/data/mods/public/gui/page_locale.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<page>
|
||||
|
||||
<include>common/modern/styles.xml</include>
|
||||
<include>common/modern/sprites.xml</include>
|
||||
<include>common/modern/setup.xml</include>
|
||||
<include>common/setup.xml</include>
|
||||
<include>common/styles.xml</include>
|
||||
<include>common/sprite1.xml</include>
|
||||
<include>common/common_sprites.xml</include>
|
||||
<include>common/common_styles.xml</include>
|
||||
|
||||
<include>locale/locale.xml</include>
|
||||
|
||||
<include>common/global.xml</include>
|
||||
</page>
|
16
binaries/data/mods/public/gui/page_locale_advanced.xml
Normal file
16
binaries/data/mods/public/gui/page_locale_advanced.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<page>
|
||||
|
||||
<include>common/modern/styles.xml</include>
|
||||
<include>common/modern/sprites.xml</include>
|
||||
<include>common/modern/setup.xml</include>
|
||||
<include>common/setup.xml</include>
|
||||
<include>common/styles.xml</include>
|
||||
<include>common/sprite1.xml</include>
|
||||
<include>common/common_sprites.xml</include>
|
||||
<include>common/common_styles.xml</include>
|
||||
|
||||
<include>locale/locale_advanced.xml</include>
|
||||
|
||||
<include>common/global.xml</include>
|
||||
</page>
|
@ -103,34 +103,34 @@ function formatUserReportStatus(status)
|
||||
var d = status.split(/:/, 3);
|
||||
|
||||
if (d[0] == "disabled")
|
||||
return "disabled";
|
||||
return translate("disabled");
|
||||
|
||||
if (d[0] == "connecting")
|
||||
return "connecting to server";
|
||||
return translate("connecting to server");
|
||||
|
||||
if (d[0] == "sending")
|
||||
{
|
||||
var done = d[1];
|
||||
return "uploading (" + Math.floor(100*done) + "%)";
|
||||
return sprintf(translate("uploading (%f%%)"), Math.floor(100*done));
|
||||
}
|
||||
|
||||
if (d[0] == "completed")
|
||||
{
|
||||
var httpCode = d[1];
|
||||
if (httpCode == 200)
|
||||
return "upload succeeded";
|
||||
return translate("upload succeeded");
|
||||
else
|
||||
return "upload failed (" + httpCode + ")";
|
||||
return sprintf(translate("upload failed (%(errorCode)s)"), { errorCode: httpCode });
|
||||
}
|
||||
|
||||
if (d[0] == "failed")
|
||||
{
|
||||
var errCode = d[1];
|
||||
var errMessage = d[2];
|
||||
return "upload failed (" + errMessage + ")";
|
||||
return sprintf(translate("upload failed (%(errorMessage)s)"), { errorMessage: errMessage });
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
return translate("unknown");
|
||||
}
|
||||
|
||||
var lastTickTime = new Date;
|
||||
@ -162,7 +162,6 @@ function onTick()
|
||||
Engine.PushGuiPage("page_splashscreen.xml", { "page": "splashscreen", callback : "SplashScreenClosedCallback" } );
|
||||
else
|
||||
ShowRenderPathMessage();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,10 +172,17 @@ function ShowRenderPathMessage()
|
||||
messageBox(
|
||||
600,
|
||||
300,
|
||||
"[font=\"serif-bold-16\"][color=\"200 20 20\"]Warning:[/color] You appear to be using non-shader (fixed function) graphics. This option will be removed in a future 0 A.D. release, to allow for more advanced graphics features. We advise upgrading your graphics card to a more recent, shader-compatible model.\n\nPlease press \"Read More\" for more information or \"Ok\" to continue.",
|
||||
"WARNING!",
|
||||
"[font=\"serif-bold-16\"]" +
|
||||
sprintf(translate("%(startWarning)sWarning:%(endWarning)s You appear to be using non-shader (fixed function) graphics. This option will be removed in a future 0 A.D. release, to allow for more advanced graphics features. We advise upgrading your graphics card to a more recent, shader-compatible model."), { startWarning: "[color=\"200 20 20\"]", endWarning: "[/color]"}) +
|
||||
"\n\n" +
|
||||
// Translation: This is the second paragraph of a warning. The
|
||||
// warning explains that the user is using “non-shader“ graphics,
|
||||
// and that in the future this will not be supported by the game, so
|
||||
// the user will need a better graphics card.
|
||||
translate("Please press \"Read More\" for more information or \"OK\" to continue."),
|
||||
translate("WARNING!"),
|
||||
0,
|
||||
["Ok", "Read More"],
|
||||
[translate("OK"), translate("Read More")],
|
||||
[ null, function() { Engine.OpenURL("http://www.wildfiregames.com/forum/index.php?showtopic=16734"); } ]
|
||||
);
|
||||
}
|
||||
@ -275,6 +281,11 @@ function blendSubmenuIntoMain(topPosition, bottomPosition)
|
||||
bottomSprite.size = "100%-2 " + (bottomPosition) + " 100% 100%";
|
||||
}
|
||||
|
||||
function getBuildString()
|
||||
{
|
||||
return sprintf(translate("Build: %(buildDate)s (%(revision)s)"), { buildDate: Engine.GetBuildTimestamp(0), revision: Engine.GetBuildTimestamp(2) });
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTIONS BELOW DO NOT WORK YET
|
||||
*/
|
||||
@ -330,3 +341,26 @@ function blendSubmenuIntoMain(topPosition, bottomPosition)
|
||||
// guiUnHide ("pg");
|
||||
// }
|
||||
//}
|
||||
|
||||
function exitGamePressed()
|
||||
{
|
||||
closeMenu();
|
||||
var btCaptions = [translate("Yes"), translate("No")];
|
||||
var btCode = [Engine.Exit, null];
|
||||
messageBox(400, 200, translate("Are you sure you want to quit 0 A.D.?"), translate("Confirmation"), 0, btCaptions, btCode);
|
||||
}
|
||||
|
||||
function pressedScenarioEditorButton()
|
||||
{
|
||||
closeMenu();
|
||||
// Start Atlas
|
||||
if (Engine.AtlasIsAvailable())
|
||||
Engine.RestartInAtlas();
|
||||
else
|
||||
messageBox(400, 200, translate("The scenario editor is not available or failed to load."), translate("Error"), 2);
|
||||
}
|
||||
|
||||
function getLobbyDisabledByBuild()
|
||||
{
|
||||
return translate("Launch the multiplayer lobby. [DISABLED BY BUILD]");
|
||||
}
|
||||
|
@ -91,16 +91,20 @@
|
||||
<object
|
||||
type="text"
|
||||
style="userReportText"
|
||||
>[font="serif-bold-16"]Help improve 0 A.D.![/font]
|
||||
|
||||
You can automatically send us anonymous feedback that will help us fix bugs, and improve performance and compatibility.
|
||||
>
|
||||
<attribute id="caption">
|
||||
<keep>[font="serif-bold-16"]</keep>
|
||||
<translate>Help improve 0 A.D.!</translate>
|
||||
<keep>[/font]\n\n</keep>
|
||||
<translate>You can automatically send us anonymous feedback that will help us fix bugs, and improve performance and compatibility.</translate>
|
||||
</attribute>
|
||||
</object>
|
||||
<object type="button" style="StoneButton" size="8 100%-36 146 100%-8">
|
||||
Enable feedback
|
||||
<translatableAttribute id="caption">Enable feedback</translatableAttribute>
|
||||
<action on="Press">EnableUserReport(true);</action>
|
||||
</object>
|
||||
<object type="button" style="StoneButton" size="100%-146 100%-36 100%-8 100%-8">
|
||||
Technical details
|
||||
<translatableAttribute id="caption">Technical details</translatableAttribute>
|
||||
<action on="Press">Engine.PushGuiPage("page_manual.xml", { "page": "userreport" });</action>
|
||||
</object>
|
||||
</object>
|
||||
@ -115,18 +119,23 @@ You can automatically send us anonymous feedback that will help us fix bugs, and
|
||||
name="userReportEnabledText"
|
||||
type="text"
|
||||
style="userReportText"
|
||||
>[font="serif-bold-16"]Thank you for helping improve 0 A.D.![/font]
|
||||
|
||||
Anonymous feedback is currently enabled.
|
||||
Status: $status.
|
||||
</object>
|
||||
>
|
||||
<attribute id="caption">
|
||||
<keep>[font="serif-bold-16"]</keep>
|
||||
<translate>Thank you for helping improve 0 A.D.!</translate>
|
||||
<keep>[/font]\n\n</keep>
|
||||
<translate>Anonymous feedback is currently enabled.</translate>
|
||||
<keep>\n</keep>
|
||||
<translate>Status: $status.</translate>
|
||||
</attribute>
|
||||
</object>
|
||||
|
||||
<object type="button" style="StoneButton" size="8 100%-36 146 100%-8">
|
||||
Disable feedback
|
||||
<translatableAttribute id="caption">Disable feedback</translatableAttribute>
|
||||
<action on="Press">EnableUserReport(false);</action>
|
||||
</object>
|
||||
<object type="button" style="StoneButton" size="100%-146 100%-36 100%-8 100%-8">
|
||||
Technical details
|
||||
<translatableAttribute id="caption">Technical details</translatableAttribute>
|
||||
<action on="Press">Engine.PushGuiPage("page_manual.xml", { "page": "userreport" });</action>
|
||||
</object>
|
||||
</object>
|
||||
@ -157,7 +166,6 @@ Status: $status.
|
||||
type="image"
|
||||
size="0 4 100%-4 100%-4"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="The 0 A.D. Game Manual."
|
||||
hidden="true"
|
||||
>
|
||||
<object name="subMenuSinglePlayerButton"
|
||||
@ -165,9 +173,9 @@ Status: $status.
|
||||
style="StoneButtonFancy"
|
||||
size="0 0 100% 28"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="Click here to start a new single player game."
|
||||
>
|
||||
Matches
|
||||
<translatableAttribute id="caption">Matches</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Click here to start a new single player game.</translatableAttribute>
|
||||
<action on="Press">
|
||||
Engine.SwitchGuiPage("page_gamesetup.xml", { type: "offline" });
|
||||
</action>
|
||||
@ -178,10 +186,10 @@ Status: $status.
|
||||
style="StoneButtonFancy"
|
||||
size="0 32 100% 60"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="Relive history through historical military campaigns. [NOT YET IMPLEMENTED]"
|
||||
enabled="false"
|
||||
>
|
||||
Campaigns
|
||||
<translatableAttribute id="caption">Campaigns</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Relive history through historical military campaigns. [NOT YET IMPLEMENTED]</translatableAttribute>
|
||||
<action on="Press">
|
||||
closeMenu();
|
||||
<![CDATA[
|
||||
@ -196,9 +204,9 @@ Status: $status.
|
||||
style="StoneButtonFancy"
|
||||
size="0 64 100% 92"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="Click here to load a saved game."
|
||||
>
|
||||
Load Game
|
||||
<translatableAttribute id="caption">Load Game</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Click here to load a saved game.</translatableAttribute>
|
||||
<action on="Press">
|
||||
closeMenu();
|
||||
Engine.PushGuiPage("page_loadgame.xml", { type: "offline" });
|
||||
@ -212,7 +220,6 @@ Status: $status.
|
||||
type="image"
|
||||
size="0 4 100%-4 100%-4"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="The 0 A.D. Game Manual"
|
||||
hidden="true"
|
||||
>
|
||||
<object name="subMenuMultiplayerJoinButton"
|
||||
@ -220,9 +227,9 @@ Status: $status.
|
||||
style="StoneButtonFancy"
|
||||
size="0 0 100% 28"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="Joining an existing multiplayer game."
|
||||
>
|
||||
Join Game
|
||||
<translatableAttribute id="caption">Join Game</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Joining an existing multiplayer game.</translatableAttribute>
|
||||
<action on="Press">
|
||||
closeMenu();
|
||||
// Open Multiplayer connection window with join option.
|
||||
@ -235,9 +242,9 @@ Status: $status.
|
||||
style="StoneButtonFancy"
|
||||
size="0 32 100% 60"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="Host a multiplayer game.\n\nRequires UDP port 20595 to be open."
|
||||
>
|
||||
Host Game
|
||||
<translatableAttribute id="caption">Host Game</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Host a multiplayer game.\n\nRequires UDP port 20595 to be open.</translatableAttribute>
|
||||
<action on="Press">
|
||||
closeMenu();
|
||||
// Open Multiplayer connection window with host option.
|
||||
@ -250,9 +257,9 @@ Status: $status.
|
||||
style="StoneButtonFancy"
|
||||
size="0 64 100% 92"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="Launch the multiplayer lobby."
|
||||
>
|
||||
Game Lobby
|
||||
<translatableAttribute id="caption">Game Lobby</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Launch the multiplayer lobby.</translatableAttribute>
|
||||
<action on="Press">
|
||||
closeMenu();
|
||||
// Open Multiplayer game lobby.
|
||||
@ -262,7 +269,7 @@ Status: $status.
|
||||
if (!Engine.StartXmppClient)
|
||||
{
|
||||
this.enabled = false;
|
||||
this.tooltip = "Launch the multiplayer lobby. [DISABLED BY BUILD]";
|
||||
this.tooltip = getLobbyDisabledByBuild();
|
||||
}
|
||||
</action>
|
||||
</object>
|
||||
@ -273,7 +280,6 @@ Status: $status.
|
||||
type="image"
|
||||
size="0 4 100%-4 100%-4"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="The 0 A.D. Game Manual"
|
||||
hidden="true"
|
||||
>
|
||||
<object name="submenuOptionsButton"
|
||||
@ -281,10 +287,10 @@ Status: $status.
|
||||
type="button"
|
||||
size="0 0 100% 28"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="Adjust game settings."
|
||||
enabled="true"
|
||||
>
|
||||
Options
|
||||
<translatableAttribute id="caption">Options</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Adjust game settings.</translatableAttribute>
|
||||
<action on="Press">
|
||||
closeMenu();
|
||||
<![CDATA[
|
||||
@ -294,25 +300,34 @@ Status: $status.
|
||||
</action>
|
||||
</object>
|
||||
|
||||
<object name="submenuEditorButton"
|
||||
<object name="submenuLocaleButton"
|
||||
style="StoneButtonFancy"
|
||||
type="button"
|
||||
size="0 32 100% 60"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="Open the Atlas Scenario Editor in a new window. You can run this more reliably by starting the game with the command-line argument "-editor"."
|
||||
>
|
||||
Scenario Editor
|
||||
<translatableAttribute id="caption">Language</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Choose the language of the game.</translatableAttribute>
|
||||
<action on="Press">
|
||||
closeMenu();
|
||||
<![CDATA[
|
||||
// Start Atlas
|
||||
if (Engine.AtlasIsAvailable())
|
||||
Engine.RestartInAtlas();
|
||||
else
|
||||
messageBox(400, 200, "The scenario editor is not available or failed to load.", "Error", 2);
|
||||
closeMenu();
|
||||
Engine.PushGuiPage("page_locale.xml");
|
||||
]]>
|
||||
</action>
|
||||
</object>
|
||||
|
||||
<object name="submenuEditorButton"
|
||||
style="StoneButtonFancy"
|
||||
type="button"
|
||||
size="0 64 100% 92"
|
||||
tooltip_style="pgToolTip"
|
||||
>
|
||||
<translatableAttribute id="caption">Scenario Editor</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Open the Atlas Scenario Editor in a new window. You can run this more reliably by starting the game with the command-line argument "-editor".</translatableAttribute>
|
||||
<action on="Press">
|
||||
pressedScenarioEditorButton();
|
||||
</action>
|
||||
</object>
|
||||
</object>
|
||||
</object><!-- end of submenu -->
|
||||
|
||||
@ -360,9 +375,9 @@ Status: $status.
|
||||
style="StoneButtonFancy"
|
||||
size="4 4 100%-4 32"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="The 0 A.D. Game Manual"
|
||||
>
|
||||
Learn To Play
|
||||
<translatableAttribute id="caption">Learn To Play</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">The 0 A.D. Game Manual</translatableAttribute>
|
||||
<action on="Press">
|
||||
closeMenu();
|
||||
<![CDATA[
|
||||
@ -377,9 +392,9 @@ Status: $status.
|
||||
type="button"
|
||||
size="4 36 100%-4 64"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="Challenge the computer player to a single player match."
|
||||
>
|
||||
Single Player
|
||||
<translatableAttribute id="caption">Single Player</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Challenge the computer player to a single player match.</translatableAttribute>
|
||||
<action on="Press">
|
||||
closeMenu();
|
||||
openMenu("submenuSinglePlayer", (this.parent.size.top+this.size.top), (this.size.bottom-this.size.top), 3);
|
||||
@ -392,9 +407,9 @@ Status: $status.
|
||||
type="button"
|
||||
size="4 68 100%-4 96"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="Fight against one or more human players in a multiplayer game."
|
||||
>
|
||||
Multiplayer
|
||||
<translatableAttribute id="caption">Multiplayer</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Fight against one or more human players in a multiplayer game.</translatableAttribute>
|
||||
<action on="Press">
|
||||
closeMenu();
|
||||
openMenu("submenuMultiplayer", (this.parent.size.top+this.size.top), (this.size.bottom-this.size.top), 3);
|
||||
@ -407,12 +422,12 @@ Status: $status.
|
||||
type="button"
|
||||
size="4 100 100%-4 128"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="Game options and scenario design tools."
|
||||
>
|
||||
Tools <![CDATA[&]]> Options
|
||||
<translatableAttribute id="caption">Tools & Options</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Game options and scenario design tools.</translatableAttribute>
|
||||
<action on="Press">
|
||||
closeMenu();
|
||||
openMenu("submenuToolsAndOptions", (this.parent.size.top+this.size.top), (this.size.bottom-this.size.top), 2);
|
||||
openMenu("submenuToolsAndOptions", (this.parent.size.top+this.size.top), (this.size.bottom-this.size.top), 3);
|
||||
</action>
|
||||
</object>
|
||||
|
||||
@ -422,9 +437,9 @@ Status: $status.
|
||||
type="button"
|
||||
size="4 132 100%-4 160"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="Learn about the many civilizations featured in 0 A.D."
|
||||
>
|
||||
History
|
||||
<translatableAttribute id="caption">History</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Learn about the many civilizations featured in 0 A.D.</translatableAttribute>
|
||||
<action on="Press">
|
||||
closeMenu();
|
||||
<![CDATA[
|
||||
@ -439,17 +454,10 @@ Status: $status.
|
||||
style="StoneButtonFancy"
|
||||
size="4 164 100%-4 192"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="Exit Game"
|
||||
>
|
||||
Exit
|
||||
<action on="Press">
|
||||
closeMenu();
|
||||
<![CDATA[
|
||||
var btCaptions = ["Yes", "No"];
|
||||
var btCode = [Engine.Exit, null]
|
||||
messageBox(400, 200, "Are you sure you want to quit 0 A.D.?", "Confirmation", 0, btCaptions, btCode);
|
||||
]]>
|
||||
</action>
|
||||
<translatableAttribute id="caption">Exit</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Exit Game</translatableAttribute>
|
||||
<action on="Press">exitGamePressed();</action>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
@ -467,21 +475,25 @@ Status: $status.
|
||||
size="8 8 100%-8 100%-36"
|
||||
ghost="true"
|
||||
>
|
||||
[font="serif-bold-16"]Alpha XV: Osiris<!-- IMPORTANT: remember to update session/session.xml in sync with this -->[/font]
|
||||
|
||||
WARNING: This is an early development version of the game. Many features have not been added yet.
|
||||
|
||||
Get involved at: play0ad.com
|
||||
<!-- IMPORTANT: remember to update session/session.xml in sync with this: -->
|
||||
<attribute id="caption">
|
||||
<keep>[font="serif-bold-16"]</keep>
|
||||
<translate>Alpha XV: Osiris</translate>
|
||||
<keep>[/font]\n\n</keep>
|
||||
<translate>WARNING: This is an early development version of the game. Many features have not been added yet.</translate>
|
||||
<keep>\n\n</keep>
|
||||
<translate>Get involved at: play0ad.com</translate>
|
||||
</attribute>
|
||||
</object>
|
||||
|
||||
<!-- CONTACT METHODS -->
|
||||
<object type="button"
|
||||
style="StoneButton"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="Click to open play0ad.com in your web browser."
|
||||
size="8 100%-72 50%-4 100%-44"
|
||||
>
|
||||
Website
|
||||
<translatableAttribute id="caption">Website</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Click to open play0ad.com in your web browser.</translatableAttribute>
|
||||
<action on="Press"><![CDATA[
|
||||
var url = "http://play0ad.com/";
|
||||
Engine.OpenURL(url);
|
||||
@ -492,10 +504,10 @@ Get involved at: play0ad.com
|
||||
<object type="button"
|
||||
style="StoneButton"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="Click to open the 0 A.D. IRC chat in your browser. (#0ad on webchat.quakenet.org)"
|
||||
size="50%+4 100%-72 100%-8 100%-44"
|
||||
>
|
||||
Chat
|
||||
<translatableAttribute id="caption">Chat</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Click to open the 0 A.D. IRC chat in your browser. (#0ad on webchat.quakenet.org)</translatableAttribute>
|
||||
<action on="Press"><![CDATA[
|
||||
var url = "http://webchat.quakenet.org/?channels=0ad";
|
||||
Engine.OpenURL(url);
|
||||
@ -506,10 +518,10 @@ Get involved at: play0ad.com
|
||||
<object type="button"
|
||||
style="StoneButton"
|
||||
tooltip_style="pgToolTip"
|
||||
tooltip="Click to visit 0 A.D. Trac to report a bug, crash, or error"
|
||||
size="8 100%-36 100%-8 100%-8"
|
||||
>
|
||||
Report a Bug
|
||||
<translatableAttribute id="caption">Report a Bug</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Click to visit 0 A.D. Trac to report a bug, crash, or error</translatableAttribute>
|
||||
<action on="Press"><![CDATA[
|
||||
var url = "http://trac.wildfiregames.com/wiki/ReportingErrors/";
|
||||
Engine.OpenURL(url);
|
||||
@ -538,7 +550,9 @@ Get involved at: play0ad.com
|
||||
style="MediumTitleText"
|
||||
ghost="true"
|
||||
size="50%-128 32 50%+128 48"
|
||||
>WILDFIRE GAMES</object>
|
||||
>
|
||||
<translatableAttribute id="caption">WILDFIRE GAMES</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<!-- VERSION -->
|
||||
@ -548,9 +562,9 @@ Get involved at: play0ad.com
|
||||
ghost="true"
|
||||
size="50%-128 100%-36 50%+128 100%"
|
||||
>
|
||||
<action on="Load"><![CDATA[
|
||||
this.caption = "Build: " + Engine.BuildTime(0) + " - " + Engine.BuildTime(2);
|
||||
]]></action>
|
||||
<action on="Load">
|
||||
this.caption = getBuildString();
|
||||
</action>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
@ -7,7 +7,7 @@ function init()
|
||||
var savedGames = Engine.GetSavedGames();
|
||||
if (savedGames.length == 0)
|
||||
{
|
||||
gameSelection.list = [ "No saved games found" ];
|
||||
gameSelection.list = [translate("No saved games found")];
|
||||
gameSelection.selected = 0;
|
||||
Engine.GetGUIObjectByName("loadGameButton").enabled = false;
|
||||
Engine.GetGUIObjectByName("deleteGameButton").enabled = false;
|
||||
@ -41,29 +41,35 @@ function loadGame()
|
||||
if (!hasSameVersion(metadata, engineInfo) || !hasSameMods(metadata, engineInfo))
|
||||
{
|
||||
// version not compatible ... ask for confirmation
|
||||
var btCaptions = ["Yes", "No"];
|
||||
var btCaptions = [translate("Yes"), translate("No")];
|
||||
var btCode = [function(){ reallyLoadGame(gameId); }, init];
|
||||
var message = "This saved game may not be compatible:";
|
||||
var message = translate("This saved game may not be compatible:");
|
||||
if (!hasSameVersion(metadata, engineInfo))
|
||||
message += "\nIt needs 0AD version " + metadata.version_major
|
||||
+ " while you are running version " + engineInfo.version_major + ".";
|
||||
message += "\n" + sprintf(translate("It needs 0 A.D. version %(requiredVersion)s, while you are running version %(currentVersion)s."), {
|
||||
requiredVersion: metadata.version_major,
|
||||
currentVersion: engineInfo.version_major
|
||||
});
|
||||
|
||||
if (!hasSameMods(metadata, engineInfo))
|
||||
{
|
||||
if (!metadata.mods) // only for backwards compatibility with previous saved games
|
||||
metadata.mods = [];
|
||||
if (metadata.mods.length == 0)
|
||||
message += "\nIt does not need any mod"
|
||||
+ " while you are running with \"" + engineInfo.mods.join() + "\".";
|
||||
message += "\n" + sprintf(translate("It does not need any mod while you are running with \"%(currentMod)s\"."), {
|
||||
currentMod: engineInfo.mods.join()
|
||||
});
|
||||
else if (engineInfo.mods.length == 0)
|
||||
message += "\nIt needs the mod \"" + metadata.mods.join() + "\""
|
||||
+ " while you are running without mod.";
|
||||
message += "\n" + sprintf(translate("It needs the mod \"%(requiredMod)s\" while you are running without a mod."), {
|
||||
requiredMod: metadata.mods.join()
|
||||
});
|
||||
else
|
||||
message += "\nIt needs the mod \"" + metadata.mods.join() + "\""
|
||||
+ " while you are running with \"" + engineInfo.mods.join() + "\".";
|
||||
message += "\n" + sprintf(translate("It needs the mod \"%(requiredMod)s\" while you are running with \"%(currentMod)s\"."), {
|
||||
requiredMod: metadata.mods.join(),
|
||||
currentMod: engineInfo.mods.join()
|
||||
});
|
||||
}
|
||||
message += "\nDo you still want to proceed ?";
|
||||
messageBox(500, 250, message, "Warning", 0, btCaptions, btCode);
|
||||
message += "\n" + translate("Do you still want to proceed?");
|
||||
messageBox(500, 250, message, translate("Warning"), 0, btCaptions, btCode);
|
||||
}
|
||||
else
|
||||
reallyLoadGame(gameId);
|
||||
@ -76,7 +82,7 @@ function reallyLoadGame(gameId)
|
||||
{
|
||||
// Probably the file wasn't found
|
||||
// Show error and refresh saved game list
|
||||
error("Could not load saved game '"+gameId+"'");
|
||||
error(sprintf("Could not load saved game '%(id)s'", { id: gameId }));
|
||||
init();
|
||||
}
|
||||
else
|
||||
@ -97,15 +103,15 @@ function deleteGame()
|
||||
var gameID = gameSelection.list_data[gameSelection.selected];
|
||||
|
||||
// Ask for confirmation
|
||||
var btCaptions = ["Yes", "No"];
|
||||
var btCaptions = [translate("Yes"), translate("No")];
|
||||
var btCode = [function(){ reallyDeleteGame(gameID); }, null];
|
||||
messageBox(500, 200, "\""+gameLabel+"\"\nSaved game will be permanently deleted, are you sure?", "DELETE", 0, btCaptions, btCode);
|
||||
messageBox(500, 200, sprintf(translate("\"%(label)s\""), { label: gameLabel }) + "\n" + translate("Saved game will be permanently deleted, are you sure?"), translate("DELETE"), 0, btCaptions, btCode);
|
||||
}
|
||||
|
||||
function reallyDeleteGame(gameID)
|
||||
{
|
||||
if (!Engine.DeleteSavedGame(gameID))
|
||||
error("Could not delete saved game '"+gameID+"'");
|
||||
error(sprintf("Could not delete saved game '%(id)s'", { id: gameID }));
|
||||
|
||||
// Run init again to refresh saved game list
|
||||
init();
|
||||
|
@ -12,7 +12,7 @@
|
||||
<object type="image" style="ModernDialog" size="50%-300 50%-200 50%+300 50%+200">
|
||||
|
||||
<object type="text" style="TitleText" size="50%-128 0%-16 50%+128 16">
|
||||
Load Game
|
||||
<translatableAttribute id="caption">Load Game</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object name="gameSelection"
|
||||
@ -22,17 +22,17 @@
|
||||
</object>
|
||||
|
||||
<object name="loadGameButton" type="button" size="0%+25 100%-60 33%+10 100%-32" style="StoneButton">
|
||||
Load
|
||||
<translatableAttribute id="caption">Load</translatableAttribute>
|
||||
<action on="Press">loadGame();</action>
|
||||
</object>
|
||||
|
||||
<object name="deleteGameButton" type="button" size="33%+20 100%-60 66%-15 100%-32" style="StoneButton">
|
||||
Delete
|
||||
<translatableAttribute id="caption">Delete</translatableAttribute>
|
||||
<action on="Press">deleteGame();</action>
|
||||
</object>
|
||||
|
||||
<object type="button" style="StoneButton" size="66%-5 100%-60 100%-25 100%-32">
|
||||
Cancel
|
||||
<translatableAttribute id="caption">Cancel</translatableAttribute>
|
||||
<action on="Press">Engine.PopGuiPage();</action>
|
||||
</object>
|
||||
|
||||
|
@ -27,7 +27,7 @@ function init(data)
|
||||
var savedGames = Engine.GetSavedGames();
|
||||
if (savedGames.length == 0)
|
||||
{
|
||||
gameSelection.list = [ "No saved games found" ];
|
||||
gameSelection.list = [translate("No saved games found")];
|
||||
gameSelection.selected = -1;
|
||||
return;
|
||||
}
|
||||
@ -56,9 +56,9 @@ function saveGame()
|
||||
if (gameSelection.selected != -1)
|
||||
{
|
||||
// Ask for confirmation
|
||||
var btCaptions = ["Yes", "No"];
|
||||
var btCaptions = [translate("Yes"), translate("No")];
|
||||
var btCode = [function(){ reallySaveGame(name, desc, false); }, null];
|
||||
messageBox(500, 200, "\""+gameLabel+"\"\nSaved game will be permanently overwritten, are you sure?", "OVERWRITE SAVE", 0, btCaptions, btCode);
|
||||
messageBox(500, 200, sprintf(translate("\"%(label)s\""), { label: gameLabel }) + "\n" + translate("Saved game will be permanently overwritten, are you sure?"), translate("OVERWRITE SAVE"), 0, btCaptions, btCode);
|
||||
}
|
||||
else
|
||||
reallySaveGame(name, desc, true);
|
||||
@ -86,15 +86,15 @@ function deleteGame()
|
||||
var gameID = gameSelection.list_data[gameSelection.selected];
|
||||
|
||||
// Ask for confirmation
|
||||
var btCaptions = ["Yes", "No"];
|
||||
var btCaptions = [translate("Yes"), translate("No")];
|
||||
var btCode = [function(){ reallyDeleteGame(gameID); }, null];
|
||||
messageBox(500, 200, "\""+gameLabel+"\"\nSaved game will be permanently deleted, are you sure?", "DELETE", 0, btCaptions, btCode);
|
||||
messageBox(500, 200, sprintf(translate("\"%(label)s\""), { label: gameLabel }) + "\n" + translate("Saved game will be permanently deleted, are you sure?"), translate("DELETE"), 0, btCaptions, btCode);
|
||||
}
|
||||
|
||||
function reallyDeleteGame(gameID)
|
||||
{
|
||||
if (!Engine.DeleteSavedGame(gameID))
|
||||
error("Could not delete saved game '"+gameID+"'");
|
||||
error(sprintf("Could not delete saved game '%(id)s'", { id: gameID }));
|
||||
|
||||
// Run init again to refresh saved game list
|
||||
init();
|
||||
|
@ -12,7 +12,7 @@
|
||||
<object type="image" style="StoneDialog" size="50%-300 50%-200 50%+300 50%+200">
|
||||
<object type="image" z="0" sprite="BackgroundTranslucent"/>
|
||||
<object type="text" style="TitleText" size="50%-128 0%-16 50%+128 16">
|
||||
Save Game
|
||||
<translatableAttribute id="caption">Save Game</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object name="gameSelection"
|
||||
@ -25,24 +25,26 @@
|
||||
</action>
|
||||
</object>
|
||||
|
||||
<object size="24 100%-124 100%-24 100%-100" name="descLabel" type="text" style="LeftLabelText">Description:</object>
|
||||
<object size="24 100%-124 100%-24 100%-100" name="descLabel" type="text" style="LeftLabelText">
|
||||
<translatableAttribute id="caption">Description:</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object name="saveGameDesc" size="24 100%-96 100%-24 100%-72" type="input" style="StoneInput">
|
||||
<action on="Press">saveGame();</action>
|
||||
</object>
|
||||
|
||||
<object name="saveButton" type="button" size="0%+25 100%-60 33%+10 100%-32" style="StoneButton">
|
||||
Save
|
||||
<translatableAttribute id="caption">Save</translatableAttribute>
|
||||
<action on="Press">saveGame();</action>
|
||||
</object>
|
||||
|
||||
<object name="deleteGameButton" type="button" size="33%+20 100%-60 66%-15 100%-32" style="StoneButton">
|
||||
Delete
|
||||
<translatableAttribute id="caption">Delete</translatableAttribute>
|
||||
<action on="Press">deleteGame();</action>
|
||||
</object>
|
||||
|
||||
<object type="button" style="StoneButton" size="66%-5 100%-60 100%-25 100%-32">
|
||||
Cancel
|
||||
<translatableAttribute id="caption">Cancel</translatableAttribute>
|
||||
<action on="Press">closeSave(true);</action>
|
||||
</object>
|
||||
|
||||
|
@ -123,10 +123,18 @@ function updateBuildingPlacementPreview()
|
||||
|
||||
// Show placement info tooltip if invalid position
|
||||
placementSupport.tooltipError = !result.success;
|
||||
placementSupport.tooltipMessage = result.success ? "" : result.message;
|
||||
placementSupport.tooltipMessage = "";
|
||||
|
||||
if (!result.success)
|
||||
{
|
||||
if (result.message && result.parameters)
|
||||
{
|
||||
// translate the message parameters
|
||||
translateObjectKeys(result.parameters, Object.keys(result.parameters), true)
|
||||
placementSupport.tooltipMessage = sprintf(translate(result.message), result.parameters);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (placementSupport.attack)
|
||||
{
|
||||
@ -138,7 +146,7 @@ function updateBuildingPlacementPreview()
|
||||
elevationBonus: placementSupport.attack.elevationBonus,
|
||||
};
|
||||
var averageRange = Engine.GuiInterfaceCall("GetAverageRangeForBuildings",cmd);
|
||||
placementSupport.tooltipMessage = "Basic range: "+Math.round(cmd.range/4)+"\nAverage bonus range: "+Math.round((averageRange - cmd.range)/4);
|
||||
placementSupport.tooltipMessage = sprintf(translate("Basic range: %(range)s"), { range: Math.round(cmd.range/4) }) + "\n" + sprintf(translate("Average bonus range: %(range)s"), { range: Math.round((averageRange - cmd.range)/4) });
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -253,8 +261,10 @@ function getActionInfo(action, target)
|
||||
data.command = "garrison";
|
||||
data.target = target;
|
||||
cursor = "action-garrison";
|
||||
tooltip = "Current garrison: " + targetState.garrisonHolder.garrisonedEntitiesCount
|
||||
+ "/" + targetState.garrisonHolder.capacity;
|
||||
tooltip = sprintf(translate("Current garrison: %(garrisoned)s/%(capacity)s"), {
|
||||
garrisoned: targetState.garrisonHolder.garrisonedEntitiesCount,
|
||||
capacity: targetState.garrisonHolder.capacity
|
||||
});
|
||||
if (targetState.garrisonHolder.garrisonedEntitiesCount >= targetState.garrisonHolder.capacity)
|
||||
tooltip = "[color=\"orange\"]" + tooltip + "[/color]";
|
||||
}
|
||||
@ -293,11 +303,11 @@ function getActionInfo(action, target)
|
||||
data.target = traderData.secondMarket;
|
||||
data.source = traderData.firstMarket;
|
||||
cursor = "action-setup-trade-route";
|
||||
tooltip = "Right-click to establish a default route for new traders.";
|
||||
tooltip = translate("Right-click to establish a default route for new traders.");
|
||||
if (trader)
|
||||
tooltip += "\nGain: " + getTradingTooltip(gain);
|
||||
tooltip += "\n" + sprintf(translate("Gain: %(gain)s"), { gain: getTradingTooltip(gain) });
|
||||
else // Foundation or cannot produce traders
|
||||
tooltip += "\nExpected gain: " + getTradingTooltip(gain);
|
||||
tooltip += "\n" + sprintf(translate("Expected gain: %(gain)s"), { gain: getTradingTooltip(gain) });
|
||||
}
|
||||
}
|
||||
else if (targetState.needsRepair && allyOwned)
|
||||
@ -344,8 +354,10 @@ function getActionInfo(action, target)
|
||||
case "garrison":
|
||||
if (hasClass(entState, "Unit") && targetState.garrisonHolder && (playerOwned || mutualAllyOwned))
|
||||
{
|
||||
var tooltip = "Current garrison: " + targetState.garrisonHolder.garrisonedEntitiesCount
|
||||
+ "/" + targetState.garrisonHolder.capacity;
|
||||
var tooltip = sprintf(translate("Current garrison: %(garrisoned)s/%(capacity)s"), {
|
||||
garrisoned: targetState.garrisonHolder.garrisonedEntitiesCount,
|
||||
capacity: targetState.garrisonHolder.capacity
|
||||
});
|
||||
var extraCount = 0;
|
||||
if (entState.garrisonHolder)
|
||||
extraCount += entState.garrisonHolder.garrisonedEntitiesCount;
|
||||
@ -372,22 +384,28 @@ function getActionInfo(action, target)
|
||||
switch (tradingDetails.type)
|
||||
{
|
||||
case "is first":
|
||||
tooltip = "Origin trade market.";
|
||||
tooltip = translate("Origin trade market.");
|
||||
if (tradingDetails.hasBothMarkets)
|
||||
tooltip += "\nGain: " + getTradingTooltip(tradingDetails.gain);
|
||||
tooltip += "\n" + sprintf(translate("Gain: %(gain)s"), {
|
||||
gain: getTradingTooltip(tradingDetails.gain)
|
||||
});
|
||||
else
|
||||
tooltip += "\nRight-click on another market to set it as a destination trade market."
|
||||
tooltip += "\n" + translate("Right-click on another market to set it as a destination trade market.")
|
||||
break;
|
||||
case "is second":
|
||||
tooltip = "Destination trade market.\nGain: " + getTradingTooltip(tradingDetails.gain);
|
||||
tooltip = translate("Destination trade market.") + "\n" + sprintf(translate("Gain: %(gain)s"), {
|
||||
gain: getTradingTooltip(tradingDetails.gain)
|
||||
});
|
||||
break;
|
||||
case "set first":
|
||||
tooltip = "Right-click to set as origin trade market";
|
||||
tooltip = translate("Right-click to set as origin trade market");
|
||||
break;
|
||||
case "set second":
|
||||
if (tradingDetails.gain.traderGain == 0) // markets too close
|
||||
return {"possible": false};
|
||||
tooltip = "Right-click to set as destination trade market.\nGain: " + getTradingTooltip(tradingDetails.gain);
|
||||
tooltip = translate("Right-click to set as destination trade market.") + "\n" + sprintf(translate("Gain: %(gain)s"), {
|
||||
gain: getTradingTooltip(tradingDetails.gain)
|
||||
});
|
||||
break;
|
||||
}
|
||||
return {"possible": true, "tooltip": tooltip};
|
||||
@ -585,7 +603,10 @@ function tryPlaceBuilding(queued)
|
||||
{
|
||||
if (placementSupport.mode !== "building")
|
||||
{
|
||||
error("[tryPlaceBuilding] Called while in '"+placementSupport.mode+"' placement mode instead of 'building'");
|
||||
error(sprintf("[%(functionName)s] Called while in '%(mode)s' placement mode instead of 'building'", {
|
||||
functionName: "tryPlaceBuilding",
|
||||
mode: placementSupport.mode
|
||||
}));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -626,14 +647,21 @@ function tryPlaceWall(queued)
|
||||
{
|
||||
if (placementSupport.mode !== "wall")
|
||||
{
|
||||
error("[tryPlaceWall] Called while in '" + placementSupport.mode + "' placement mode; expected 'wall' mode");
|
||||
error(sprintf("[%(functionName)s] Called while in '%(mode)s' placement mode; expected 'wall' mode", {
|
||||
functionName: "tryPlaceWall",
|
||||
mode: placementSupport.mode
|
||||
}));
|
||||
return false;
|
||||
}
|
||||
|
||||
var wallPlacementInfo = updateBuildingPlacementPreview(); // entities making up the wall (wall segments, towers, ...)
|
||||
if (!(wallPlacementInfo === false || typeof(wallPlacementInfo) === "object"))
|
||||
{
|
||||
error("[tryPlaceWall] Unexpected return value from updateBuildingPlacementPreview: '" + uneval(placementInfo) + "'; expected either 'false' or 'object'");
|
||||
error(sprintf("[%(functionName)s] Unexpected return value from %(function2Name)s: '%(value)s'; expected either 'false' or 'object'", {
|
||||
functionName: "tryPlaceWall",
|
||||
function2Name: "updateBuildingPlacementPreview",
|
||||
value: uneval(placementInfo)
|
||||
}));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -965,7 +993,7 @@ function handleInputBeforeGui(ev, hoveredObject)
|
||||
}
|
||||
else
|
||||
{
|
||||
placementSupport.tooltipMessage = "Cannot build wall here!";
|
||||
placementSupport.tooltipMessage = translate("Cannot build wall here!");
|
||||
}
|
||||
|
||||
updateBuildingPlacementPreview();
|
||||
@ -2245,3 +2273,4 @@ function clearSelection()
|
||||
g_Selection.reset();
|
||||
preSelectedAction = ACTION_NONE;
|
||||
}
|
||||
|
||||
|
@ -136,9 +136,9 @@ function resignMenuButton()
|
||||
closeMenu();
|
||||
closeOpenDialogs();
|
||||
pauseGame();
|
||||
var btCaptions = ["Yes", "No"];
|
||||
var btCaptions = [translate("Yes"), translate("No")];
|
||||
var btCode = [resignGame, resumeGame];
|
||||
messageBox(400, 200, "Are you sure you want to resign?", "Confirmation", 0, btCaptions, btCode);
|
||||
messageBox(400, 200, translate("Are you sure you want to resign?"), translate("Confirmation"), 0, btCaptions, btCode);
|
||||
}
|
||||
|
||||
function exitMenuButton()
|
||||
@ -149,27 +149,27 @@ function exitMenuButton()
|
||||
if (g_IsNetworked && g_IsController)
|
||||
{
|
||||
var btCode = [leaveGame, resumeGame];
|
||||
var message = "Are you sure you want to quit? Leaving will disconnect all other players.";
|
||||
var message = translate("Are you sure you want to quit? Leaving will disconnect all other players.");
|
||||
}
|
||||
else if (g_IsNetworked && !g_GameEnded && !g_IsObserver)
|
||||
{
|
||||
var btCode = [networkReturnQuestion, resumeGame];
|
||||
var message = "Are you sure you want to quit?";
|
||||
var message = translate("Are you sure you want to quit?");
|
||||
}
|
||||
else
|
||||
{
|
||||
var btCode = [leaveGame, resumeGame];
|
||||
var message = "Are you sure you want to quit?";
|
||||
var message = translate("Are you sure you want to quit?");
|
||||
}
|
||||
messageBox(400, 200, message, "Confirmation", 0, ["Yes", "No"], btCode);
|
||||
messageBox(400, 200, message, translate("Confirmation"), 0, [translate("Yes"), translate("No")], btCode);
|
||||
}
|
||||
|
||||
function networkReturnQuestion()
|
||||
{
|
||||
var btCaptions = ["I resign", "I will return"];
|
||||
var btCaptions = [translate("I resign"), translate("I will return")];
|
||||
var btCode = [leaveGame, leaveGame];
|
||||
var btArgs = [false, true];
|
||||
messageBox(400, 200, "Do you want to resign or will you return soon?", "Confirmation", 0, btCaptions, btCode, btArgs);
|
||||
messageBox(400, 200, translate("Do you want to resign or will you return soon?"), translate("Confirmation"), 0, btCaptions, btCode, btArgs);
|
||||
}
|
||||
|
||||
function openDeleteDialog(selection)
|
||||
@ -182,10 +182,10 @@ function openDeleteDialog(selection)
|
||||
Engine.PostNetworkCommand({"type": "delete-entities", "entities": selectionArg});
|
||||
};
|
||||
|
||||
var btCaptions = ["Yes", "No"];
|
||||
var btCaptions = [translate("Yes"), translate("No")];
|
||||
var btCode = [deleteSelectedEntities, resumeGame];
|
||||
|
||||
messageBox(400, 200, "Destroy everything currently selected?", "Delete", 0, btCaptions, btCode, [selection, null]);
|
||||
messageBox(400, 200, translate("Destroy everything currently selected?"), translate("Delete"), 0, btCaptions, btCode, [selection, null]);
|
||||
}
|
||||
|
||||
// Menu functions
|
||||
@ -289,10 +289,10 @@ function openDiplomacy()
|
||||
Engine.GetGUIObjectByName("diplomacyPlayerName["+(i-1)+"]").caption = "[color=\"" + playerColor + "\"]" + players[i].name + "[/color]";
|
||||
Engine.GetGUIObjectByName("diplomacyPlayerCiv["+(i-1)+"]").caption = g_CivData[players[i].civ].Name;
|
||||
|
||||
Engine.GetGUIObjectByName("diplomacyPlayerTeam["+(i-1)+"]").caption = (players[i].team < 0) ? "None" : players[i].team+1;
|
||||
Engine.GetGUIObjectByName("diplomacyPlayerTeam["+(i-1)+"]").caption = (players[i].team < 0) ? translateWithContext("team", "None") : players[i].team+1;
|
||||
|
||||
if (i != we)
|
||||
Engine.GetGUIObjectByName("diplomacyPlayerTheirs["+(i-1)+"]").caption = (players[i].isAlly[we] ? "Ally" : (players[i].isNeutral[we] ? "Neutral" : "Enemy"));
|
||||
Engine.GetGUIObjectByName("diplomacyPlayerTheirs["+(i-1)+"]").caption = (players[i].isAlly[we] ? translate("Ally") : (players[i].isNeutral[we] ? translate("Neutral") : translate("Enemy")));
|
||||
|
||||
// Don't display the options for ourself, or if we or the other player aren't active anymore
|
||||
if (i == we || players[we].state != "active" || players[i].state != "active")
|
||||
@ -353,25 +353,24 @@ function openDiplomacy()
|
||||
if (setting == "ally")
|
||||
{
|
||||
if (players[we].isAlly[i])
|
||||
button.caption = "x";
|
||||
button.caption = translate("x");
|
||||
else
|
||||
button.caption = "";
|
||||
}
|
||||
else if (setting == "neutral")
|
||||
{
|
||||
if (players[we].isNeutral[i])
|
||||
button.caption = "x";
|
||||
button.caption = translate("x");
|
||||
else
|
||||
button.caption = "";
|
||||
}
|
||||
else // "enemy"
|
||||
{
|
||||
if (players[we].isEnemy[i])
|
||||
button.caption = "x";
|
||||
button.caption = translate("x");
|
||||
else
|
||||
button.caption = "";
|
||||
}
|
||||
|
||||
button.onpress = (function(e){ return function() { setDiplomacy(e) } })({"player": i, "to": setting});
|
||||
button.hidden = false;
|
||||
}
|
||||
@ -392,7 +391,7 @@ function toggleDiplomacy()
|
||||
closeDiplomacy();
|
||||
else
|
||||
openDiplomacy();
|
||||
};
|
||||
}
|
||||
|
||||
function openTrade()
|
||||
{
|
||||
@ -478,41 +477,126 @@ function openTrade()
|
||||
|
||||
var traderNumber = Engine.GuiInterfaceCall("GetTraderNumber");
|
||||
var caption = "";
|
||||
var comma = "";
|
||||
if (traderNumber.landTrader.total == 0)
|
||||
caption += "0";
|
||||
caption = translate("There are no land traders.");
|
||||
else
|
||||
{
|
||||
var inactive = traderNumber.landTrader.total - traderNumber.landTrader.trading - traderNumber.landTrader.garrisoned;
|
||||
var inactiveString = "";
|
||||
if (inactive > 0)
|
||||
inactiveString = "[color=\"orange\"]" + sprintf(translatePlural("%(numberOfLandTraders)s inactive", "%(numberOfLandTraders)s inactive", inactive), { numberOfLandTraders: inactive }) + "[/color]";
|
||||
|
||||
if (traderNumber.landTrader.trading > 0)
|
||||
{
|
||||
caption += traderNumber.landTrader.trading + " trading"
|
||||
comma = ", ";
|
||||
var openingTradingString = sprintf(translatePlural("There is %(numberTrading)s land trader trading", "There are %(numberTrading)s land traders trading", traderNumber.landTrader.trading), { numberTrading: traderNumber.landTrader.trading });
|
||||
if (traderNumber.landTrader.garrisoned > 0)
|
||||
{
|
||||
var garrisonedString = sprintf(translatePlural("%(numberGarrisoned)s garrisoned on a trading merchant ship", "%(numberGarrisoned)s garrisoned on a trading merchant ship", traderNumber.landTrader.garrisoned), { numberGarrisoned: traderNumber.landTrader.garrisoned });
|
||||
if (inactive > 0)
|
||||
{
|
||||
caption = sprintf(translate("%(openingTradingString)s, %(garrisonedString)s, and %(inactiveString)s."), {
|
||||
openingTradingString: openingTradingString,
|
||||
garrisonedString: garrisonedString,
|
||||
inactiveString: inactiveString
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
caption = sprintf(translate("%(openingTradingString)s, and %(garrisonedString)s."), {
|
||||
openingTradingString: openingTradingString,
|
||||
garrisonedString: garrisonedString
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inactive > 0)
|
||||
{
|
||||
caption = sprintf(translate("%(openingTradingString)s, and %(inactiveString)s."), {
|
||||
openingTradingString: openingTradingString,
|
||||
inactiveString: inactiveString
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
caption = sprintf(translate("%(openingTradingString)s."), {
|
||||
openingTradingString: openingTradingString,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (traderNumber.landTrader.garrisoned > 0)
|
||||
else
|
||||
{
|
||||
caption += comma + traderNumber.landTrader.garrisoned + " garrisoned inside ships";
|
||||
comma = ", ";
|
||||
if (traderNumber.landTrader.garrisoned > 0)
|
||||
{
|
||||
var openingGarrisonedString = sprintf(translatePlural("There is %(numberGarrisoned)s land trader garrisoned on a trading merchant ship", "There are %(numberGarrisoned)s land traders garrisoned on a trading merchant ship", traderNumber.landTrader.garrisoned), { numberGarrisoned: traderNumber.landTrader.garrisoned });
|
||||
if (inactive > 0)
|
||||
{
|
||||
caption = sprintf(translate("%(openingGarrisonedString)s, and %(inactiveString)s."), {
|
||||
openingGarrisonedString: openingGarrisonedString,
|
||||
inactiveString: inactiveString
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
caption = sprintf(translate("%(openingGarrisonedString)s."), {
|
||||
openingGarrisonedString: openingGarrisonedString
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inactive > 0)
|
||||
{
|
||||
inactiveString = "[color=\"orange\"]" + sprintf(translatePlural("%(numberOfLandTraders)s land trader inactive", "%(numberOfLandTraders)s land traders inactive", inactive), { numberOfLandTraders: inactive }) + "[/color]";
|
||||
caption = sprintf(translatePlural("There is %(inactiveString)s.", "There are %(inactiveString)s.", inactive), {
|
||||
inactiveString: inactiveString
|
||||
});
|
||||
}
|
||||
// The “else” here is already handled by “if (traderNumber.landTrader.total == 0)” above.
|
||||
}
|
||||
}
|
||||
var inactive = traderNumber.landTrader.total - traderNumber.landTrader.trading - traderNumber.landTrader.garrisoned;
|
||||
if (inactive > 0)
|
||||
caption += comma + "[color=\"orange\"]" + inactive + " inactive[/color]";
|
||||
}
|
||||
Engine.GetGUIObjectByName("landTraders").caption = caption;
|
||||
|
||||
caption = "";
|
||||
comma = "";
|
||||
if (traderNumber.shipTrader.total == 0)
|
||||
caption += "0";
|
||||
caption = translate("There are no merchant ships.");
|
||||
else
|
||||
{
|
||||
var inactive = traderNumber.shipTrader.total - traderNumber.shipTrader.trading;
|
||||
var inactiveString = "";
|
||||
if (inactive > 0)
|
||||
inactiveString = "[color=\"orange\"]" + sprintf(translatePlural("%(numberOfShipTraders)s inactive", "%(numberOfShipTraders)s inactive", inactive), { numberOfShipTraders: inactive }) + "[/color]";
|
||||
|
||||
if (traderNumber.shipTrader.trading > 0)
|
||||
{
|
||||
caption += traderNumber.shipTrader.trading + " trading"
|
||||
comma = ", ";
|
||||
var openingTradingString = sprintf(translatePlural("There is %(numberTrading)s merchant ship trading", "There are %(numberTrading)s merchant ships trading", traderNumber.shipTrader.trading), { numberTrading: traderNumber.shipTrader.trading });
|
||||
if (inactive > 0)
|
||||
{
|
||||
caption = sprintf(translate("%(openingTradingString)s, and %(inactiveString)s."), {
|
||||
openingTradingString: openingTradingString,
|
||||
inactiveString: inactiveString
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
caption = sprintf(translate("%(openingTradingString)s."), {
|
||||
openingTradingString: openingTradingString,
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inactive > 0)
|
||||
{
|
||||
inactiveString = "[color=\"orange\"]" + sprintf(translatePlural("%(numberOfShipTraders)s merchant ship inactive", "%(numberOfShipTraders)s merchant ships inactive", inactive), { numberOfShipTraders: inactive }) + "[/color]";
|
||||
caption = sprintf(translatePlural("There is %(inactiveString)s.", "There are %(inactiveString)s.", inactive), {
|
||||
inactiveString: inactiveString
|
||||
});
|
||||
}
|
||||
// The “else” here is already handled by “if (traderNumber.shipTrader.total == 0)” above.
|
||||
}
|
||||
var inactive = traderNumber.shipTrader.total - traderNumber.shipTrader.trading;
|
||||
if (inactive > 0)
|
||||
caption += comma + "[color=\"orange\"]" + inactive + " inactive[/color]";
|
||||
}
|
||||
Engine.GetGUIObjectByName("shipTraders").caption = caption;
|
||||
|
||||
@ -531,7 +615,7 @@ function toggleTrade()
|
||||
closeTrade();
|
||||
else
|
||||
openTrade();
|
||||
};
|
||||
}
|
||||
|
||||
function toggleGameSpeed()
|
||||
{
|
||||
@ -594,8 +678,10 @@ function toggleDeveloperOverlay()
|
||||
return;
|
||||
|
||||
var devCommands = Engine.GetGUIObjectByName("devCommands");
|
||||
var text = devCommands.hidden ? "opened." : "closed.";
|
||||
submitChatDirectly("The Developer Overlay was " + text);
|
||||
if (devCommands.hidden)
|
||||
submitChatDirectly(translate("The Developer Overlay was opened."));
|
||||
else
|
||||
submitChatDirectly(translate("The Developer Overlay was closed."));
|
||||
// Update the options dialog
|
||||
Engine.GetGUIObjectByName("developerOverlayCheckbox").checked = devCommands.hidden;
|
||||
devCommands.hidden = !devCommands.hidden;
|
||||
@ -613,6 +699,10 @@ function closeOpenDialogs()
|
||||
function formatTributeTooltip(player, resource, amount)
|
||||
{
|
||||
var playerColor = player.color.r + " " + player.color.g + " " + player.color.b;
|
||||
return "Tribute " + amount + " " + resource + " to [color=\"" + playerColor + "\"]" + player.name +
|
||||
"[/color]. Shift-click to tribute " + (amount < 500 ? 500 : amount + 500) + ".";
|
||||
return sprintf(translate("Tribute %(resourceAmount)s %(resourceType)s to %(playerName)s. Shift-click to tribute %(greaterAmount)s."), {
|
||||
resourceAmount: amount,
|
||||
resourceType: resource,
|
||||
playerName: "[color=\"" + playerColor + "\"]" + player.name + "[/color]",
|
||||
greaterAmount: (amount < 500 ? 500 : amount + 500)
|
||||
});
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ function getCheatsData()
|
||||
{
|
||||
var currentCheat = parseJSONData("simulation/data/cheats/"+fileName+".json");
|
||||
if (Object.keys(cheats).indexOf(currentCheat.Name) !== -1)
|
||||
warn("Cheat name '"+currentCheat.Name+"' is already present");
|
||||
warn(sprintf("Cheat name '%(name)s' is already present", { name: currentCheat.Name }));
|
||||
else
|
||||
cheats[currentCheat.Name] = currentCheat.Data;
|
||||
}
|
||||
@ -142,13 +142,34 @@ function displayNotifications()
|
||||
{
|
||||
var messages = [];
|
||||
for each (var n in notifications)
|
||||
messages.push(n.message);
|
||||
{
|
||||
var parameters = n.parameters || {};
|
||||
if (n.translateParameters && n.translateParameters.length)
|
||||
translateObjectKeys(parameters, n.translateParameters);
|
||||
var message = n.message;
|
||||
if (n.translateMessage)
|
||||
message = translate(message);
|
||||
messages.push(sprintf(message, parameters));
|
||||
}
|
||||
Engine.GetGUIObjectByName("notificationText").caption = messages.join("\n");
|
||||
}
|
||||
|
||||
function updateTimeNotifications()
|
||||
{
|
||||
Engine.GetGUIObjectByName("timeNotificationText").caption = Engine.GuiInterfaceCall("GetTimeNotificationText");
|
||||
var notifications = Engine.GuiInterfaceCall("GetTimeNotifications");
|
||||
var notificationText = "";
|
||||
for (var n of notifications)
|
||||
{
|
||||
var message = n.message;
|
||||
if (n.translateMessage)
|
||||
message = translate(message);
|
||||
var parameters = n.parameters || {};
|
||||
if (n.translateParameters && n.translateParameters.length)
|
||||
translateObjectKeys(parameters, n.translateParameters);
|
||||
parameters.time = timeToString(n.time);
|
||||
notificationText += sprintf(message, parameters) + "\n";
|
||||
}
|
||||
Engine.GetGUIObjectByName("timeNotificationText").caption = notificationText;
|
||||
}
|
||||
|
||||
// Returns [username, playercolor] for the given player
|
||||
@ -165,7 +186,7 @@ function getUsernameAndColor(player)
|
||||
// Messages
|
||||
function handleNetMessage(message)
|
||||
{
|
||||
log("Net message: " + uneval(message));
|
||||
log(sprintf(translate("Net message: %(message)s"), { message: uneval(message) }));
|
||||
|
||||
switch (message.type)
|
||||
{
|
||||
@ -178,11 +199,11 @@ function handleNetMessage(message)
|
||||
switch (message.status)
|
||||
{
|
||||
case "waiting_for_players":
|
||||
obj.caption = "Waiting for other players to connect...";
|
||||
obj.caption = translate("Waiting for other players to connect...");
|
||||
obj.hidden = false;
|
||||
break;
|
||||
case "join_syncing":
|
||||
obj.caption = "Synchronising gameplay with other players...";
|
||||
obj.caption = translate("Synchronising gameplay with other players...");
|
||||
obj.hidden = false;
|
||||
break;
|
||||
case "active":
|
||||
@ -190,20 +211,20 @@ function handleNetMessage(message)
|
||||
obj.hidden = true;
|
||||
break;
|
||||
case "connected":
|
||||
obj.caption = "Connected to the server.";
|
||||
obj.caption = translate("Connected to the server.");
|
||||
obj.hidden = false;
|
||||
break;
|
||||
case "authenticated":
|
||||
obj.caption = "Connection to the server has been authenticated.";
|
||||
obj.caption = translate("Connection to the server has been authenticated.");
|
||||
obj.hidden = false;
|
||||
break;
|
||||
case "disconnected":
|
||||
g_Disconnected = true;
|
||||
obj.caption = "Connection to the server has been lost.\n\nThe game has ended.";
|
||||
obj.caption = translate("Connection to the server has been lost.") + "\n\n" + translate("The game has ended.");
|
||||
obj.hidden = false;
|
||||
break;
|
||||
default:
|
||||
error("Unrecognised netstatus type "+message.status);
|
||||
error(sprintf("Unrecognised netstatus type %(netType)s", { netType: message.status }));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -255,7 +276,7 @@ function handleNetMessage(message)
|
||||
break;
|
||||
|
||||
default:
|
||||
error("Unrecognised net message type "+message.type);
|
||||
error(sprintf("Unrecognised net message type %(messageType)s", { messageType: message.type }));
|
||||
}
|
||||
}
|
||||
|
||||
@ -351,8 +372,8 @@ function addChatMessage(msg, playerAssignments)
|
||||
|
||||
var playerColor, username;
|
||||
|
||||
// No prefix by default. May be set by parseChatCommands().
|
||||
msg.prefix = "";
|
||||
// No context by default. May be set by parseChatCommands().
|
||||
msg.context = "";
|
||||
|
||||
if (playerAssignments[msg.guid])
|
||||
{
|
||||
@ -379,37 +400,47 @@ function addChatMessage(msg, playerAssignments)
|
||||
else
|
||||
{
|
||||
playerColor = "255 255 255";
|
||||
username = "Unknown player";
|
||||
username = translate("Unknown player");
|
||||
}
|
||||
|
||||
var message = escapeText(msg.text);
|
||||
|
||||
var formatted;
|
||||
|
||||
switch (msg.type)
|
||||
{
|
||||
case "connect":
|
||||
formatted = "[color=\"" + playerColor + "\"]" + username + "[/color] has joined the game.";
|
||||
formatted = sprintf(translate("%(player)s has joined the game."), { player: "[color=\"" + playerColor + "\"]" + username + "[/color]" });
|
||||
break;
|
||||
case "disconnect":
|
||||
formatted = "[color=\"" + playerColor + "\"]" + username + "[/color] has left the game.";
|
||||
formatted = sprintf(translate("%(player)s has left the game."), { player: "[color=\"" + playerColor + "\"]" + username + "[/color]" });
|
||||
break;
|
||||
case "defeat":
|
||||
// In singleplayer, the local player is "You". "You has" is incorrect.
|
||||
var verb = (!g_IsNetworked && msg.player == Engine.GetPlayerID()) ? "have" : "has";
|
||||
formatted = "[color=\"" + playerColor + "\"]" + username + "[/color] " + verb + " been defeated.";
|
||||
if (!g_IsNetworked && msg.player == Engine.GetPlayerID())
|
||||
formatted = translate("You have been defeated.");
|
||||
else
|
||||
formatted = sprintf(translate("%(player)s has been defeated."), { player: "[color=\"" + playerColor + "\"]" + username + "[/color]" });
|
||||
break;
|
||||
case "diplomacy":
|
||||
var status = (msg.status == "ally" ? "allied" : (msg.status == "enemy" ? "at war" : "neutral"));
|
||||
if (msg.player == Engine.GetPlayerID())
|
||||
{
|
||||
[username, playerColor] = getUsernameAndColor(msg.player1);
|
||||
formatted = "You are now "+status+" with [color=\"" + playerColor + "\"]"+username + "[/color].";
|
||||
if (msg.status == "ally")
|
||||
formatted = sprintf(translate("You are now allied with %(player)s."), { player: "[color=\"" + playerColor + "\"]" + username + "[/color]" });
|
||||
else if (msg.status == "enemy")
|
||||
formatted = sprintf(translate("You are now at war with %(player)s."), { player: "[color=\"" + playerColor + "\"]" + username + "[/color]" });
|
||||
else // (msg.status == "neutral")
|
||||
formatted = sprintf(translate("You are now neutral with %(player)s."), { player: "[color=\"" + playerColor + "\"]" + username + "[/color]" });
|
||||
}
|
||||
else if (msg.player1 == Engine.GetPlayerID())
|
||||
{
|
||||
[username, playerColor] = getUsernameAndColor(msg.player);
|
||||
formatted = "[color=\"" + playerColor + "\"]" + username + "[/color] is now " + status + " with you."
|
||||
if (msg.status == "ally")
|
||||
formatted = sprintf(translate("%(player)s is now allied with you."), { player: "[color=\"" + playerColor + "\"]" + username + "[/color]" });
|
||||
else if (msg.status == "enemy")
|
||||
formatted = sprintf(translate("%(player)s is now at war with you."), { player: "[color=\"" + playerColor + "\"]" + username + "[/color]" });
|
||||
else // (msg.status == "neutral")
|
||||
formatted = sprintf(translate("%(player)s is now neutral with you."), { player: "[color=\"" + playerColor + "\"]" + username + "[/color]" });
|
||||
}
|
||||
else // No need for other players to know of this.
|
||||
return;
|
||||
@ -428,36 +459,84 @@ function addChatMessage(msg, playerAssignments)
|
||||
if (amounts.length > 1)
|
||||
{
|
||||
var lastAmount = amounts.pop();
|
||||
amounts = amounts.join(", ") + " and " + lastAmount;
|
||||
amounts = sprintf(translate("%(previousAmounts)s and %(lastAmount)s"), {
|
||||
previousAmounts: amounts.join(translate(", ")),
|
||||
lastAmount: lastAmount
|
||||
});
|
||||
}
|
||||
|
||||
formatted = "[color=\"" + playerColor + "\"]" + username + "[/color] has sent you " + amounts + ".";
|
||||
formatted = sprintf(translate("%(player)s has sent you %(amounts)s."), {
|
||||
player: "[color=\"" + playerColor + "\"]" + username + "[/color]",
|
||||
amounts: amounts
|
||||
});
|
||||
break;
|
||||
case "attack":
|
||||
if (msg.player != Engine.GetPlayerID())
|
||||
return;
|
||||
|
||||
[username, playerColor] = getUsernameAndColor(msg.attacker);
|
||||
formatted = "You have been attacked by [color=\"" + playerColor + "\"]" + username + "[/color]!";
|
||||
formatted = sprintf(translate("You have been attacked by %(attacker)s!"), { attacker: "[color=\"" + playerColor + "\"]" + username + "[/color]" });
|
||||
break;
|
||||
case "message":
|
||||
// May have been hidden by the 'team' command.
|
||||
if (msg.hide)
|
||||
return;
|
||||
|
||||
var message = escapeText(msg.text);
|
||||
|
||||
if (msg.action)
|
||||
{
|
||||
Engine.Console_Write(msg.prefix + "* " + username + " " + message);
|
||||
formatted = msg.prefix + "* [color=\"" + playerColor + "\"]" + username + "[/color] " + message;
|
||||
if (msg.context !== "")
|
||||
{
|
||||
Engine.Console_Write(sprintf(translate("(%(context)s) * %(user)s %(message)s"), {
|
||||
context: msg.context,
|
||||
user: username,
|
||||
message: message
|
||||
}));
|
||||
formatted = sprintf(translate("(%(context)s) * %(user)s %(message)s"), {
|
||||
context: msg.context,
|
||||
user: "[color=\"" + playerColor + "\"]" + username + "[/color]",
|
||||
message: message
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Engine.Console_Write(sprintf(translate("* %(user)s %(message)s"), {
|
||||
user: username,
|
||||
message: message
|
||||
}));
|
||||
formatted = sprintf(translate("* %(user)s %(message)s"), {
|
||||
user: "[color=\"" + playerColor + "\"]" + username + "[/color]",
|
||||
message: message
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Engine.Console_Write(msg.prefix + "<" + username + "> " + message);
|
||||
formatted = msg.prefix + "<[color=\"" + playerColor + "\"]" + username + "[/color]> " + message;
|
||||
var userTag = sprintf(translate("<%(user)s>"), { user: username })
|
||||
var formattedUserTag = sprintf(translate("<%(user)s>"), { user: "[color=\"" + playerColor + "\"]" + username + "[/color]" })
|
||||
if (msg.context !== "")
|
||||
{
|
||||
Engine.Console_Write(sprintf(translate("(%(context)s) %(userTag)s %(message)s"), {
|
||||
context: msg.context,
|
||||
userTag: userTag,
|
||||
message: message
|
||||
}));
|
||||
formatted = sprintf(translate("(%(context)s) %(userTag)s %(message)s"), {
|
||||
context: msg.context,
|
||||
userTag: formattedUserTag,
|
||||
message: message
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Engine.Console_Write(sprintf(translate("%(userTag)s %(message)s"), { userTag: userTag, message: message}));
|
||||
formatted = sprintf(translate("%(userTag)s %(message)s"), { userTag: formattedUserTag, message: message});
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error("Invalid chat message '" + uneval(msg) + "'");
|
||||
error(sprintf("Invalid chat message '%(message)s'", { message: uneval(msg) }));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -499,7 +578,7 @@ function parseChatCommands(msg, playerAssignments)
|
||||
{
|
||||
case "/all":
|
||||
// Resets values that 'team' or 'enemy' may have set.
|
||||
msg.prefix = "";
|
||||
msg.context = "";
|
||||
msg.hide = false;
|
||||
recurse = true;
|
||||
break;
|
||||
@ -510,7 +589,7 @@ function parseChatCommands(msg, playerAssignments)
|
||||
if (g_Players[Engine.GetPlayerID()].team != g_Players[sender].team)
|
||||
msg.hide = true;
|
||||
else
|
||||
msg.prefix = "(Team) ";
|
||||
msg.context = translate("Team");
|
||||
}
|
||||
else
|
||||
msg.hide = true;
|
||||
@ -523,7 +602,7 @@ function parseChatCommands(msg, playerAssignments)
|
||||
if (g_Players[Engine.GetPlayerID()].team == g_Players[sender].team && sender != Engine.GetPlayerID())
|
||||
msg.hide = true;
|
||||
else
|
||||
msg.prefix = "(Enemy) ";
|
||||
msg.context = translate("Enemy");
|
||||
}
|
||||
recurse = true;
|
||||
break;
|
||||
@ -543,7 +622,7 @@ function parseChatCommands(msg, playerAssignments)
|
||||
var playerName = g_Players[Engine.GetPlayerID()].name;
|
||||
if (matched.length && (matched == playerName || sender == Engine.GetPlayerID()))
|
||||
{
|
||||
msg.prefix = "(Private) ";
|
||||
msg.context = translate("Private");
|
||||
msg.text = trimmed.substr(matched.length + 1);
|
||||
msg.hide = false; // Might override team message hiding.
|
||||
return;
|
||||
|
@ -10,6 +10,40 @@ function layoutSelectionMultiple()
|
||||
Engine.GetGUIObjectByName("detailsAreaSingle").hidden = true;
|
||||
}
|
||||
|
||||
function getLocalizedResourceName(resourceCode)
|
||||
{
|
||||
switch(resourceCode)
|
||||
{
|
||||
case "food": return translate("Food");
|
||||
case "meat": return translate("Meat");
|
||||
case "metal": return translate("Metal");
|
||||
case "ore": return translate("Ore");
|
||||
case "rock": return translate("Rock");
|
||||
case "ruins": return translate("Ruins");
|
||||
case "stone": return translate("Stone");
|
||||
case "treasure": return translate("Treasure");
|
||||
case "tree": return translate("Tree");
|
||||
case "wood": return translate("Wood");
|
||||
case "fruit": return translate("Fruit");
|
||||
case "grain": return translate("Grain");
|
||||
case "fish": return translate("Fish");
|
||||
default:
|
||||
warn(sprintf("Internationalization: Unexpected resource type found with code ‘%(resource)s’. This resource type must be internationalized.", { resource: resourceCode }));
|
||||
return resourceCode; // It should never get here.
|
||||
}
|
||||
}
|
||||
|
||||
function getResourceTypeDisplayName(resourceType)
|
||||
{
|
||||
var resourceCode = resourceType["generic"];
|
||||
var displayName = "";
|
||||
if (resourceCode == "treasure")
|
||||
displayName = getLocalizedResourceName(resourceType["specific"]);
|
||||
else
|
||||
displayName = getLocalizedResourceName(resourceCode);
|
||||
return displayName;
|
||||
}
|
||||
|
||||
// Fills out information that most entities have
|
||||
function displaySingle(entState, template)
|
||||
{
|
||||
@ -18,7 +52,7 @@ function displaySingle(entState, template)
|
||||
var genericName = template.name.generic != template.name.specific ? template.name.generic : "";
|
||||
// If packed, add that to the generic name (reduces template clutter)
|
||||
if (genericName && template.pack && template.pack.state == "packed")
|
||||
genericName += " -- Packed";
|
||||
genericName = sprintf(translate("%(genericName)s — Packed"), { genericName: genericName });
|
||||
var playerState = g_Players[entState.player];
|
||||
|
||||
var civName = g_CivData[playerState.civ].Name;
|
||||
@ -30,13 +64,13 @@ function displaySingle(entState, template)
|
||||
// Indicate disconnected players by prefixing their name
|
||||
if (g_Players[entState.player].offline)
|
||||
{
|
||||
playerName = "[OFFLINE] " + playerName;
|
||||
playerName = sprintf(translate("[OFFLINE] %(player)s"), { player: playerName });
|
||||
}
|
||||
|
||||
// Rank
|
||||
if (entState.identity && entState.identity.rank && entState.identity.classes)
|
||||
{
|
||||
Engine.GetGUIObjectByName("rankIcon").tooltip = entState.identity.rank + " Rank";
|
||||
Engine.GetGUIObjectByName("rankIcon").tooltip = sprintf(translate("%(rank)s Rank"), { rank: entState.identity.rank });
|
||||
Engine.GetGUIObjectByName("rankIcon").sprite = getRankIconSprite(entState);
|
||||
Engine.GetGUIObjectByName("rankIcon").hidden = false;
|
||||
}
|
||||
@ -45,7 +79,7 @@ function displaySingle(entState, template)
|
||||
Engine.GetGUIObjectByName("rankIcon").hidden = true;
|
||||
Engine.GetGUIObjectByName("rankIcon").tooltip = "";
|
||||
}
|
||||
|
||||
|
||||
// Hitpoints
|
||||
if (entState.hitpoints)
|
||||
{
|
||||
@ -54,8 +88,10 @@ function displaySingle(entState, template)
|
||||
healthSize.rright = 100*Math.max(0, Math.min(1, entState.hitpoints / entState.maxHitpoints));
|
||||
unitHealthBar.size = healthSize;
|
||||
|
||||
var hitpoints = Math.ceil(entState.hitpoints) + " / " + entState.maxHitpoints;
|
||||
Engine.GetGUIObjectByName("healthStats").caption = hitpoints;
|
||||
Engine.GetGUIObjectByName("healthStats").caption = sprintf(translate("%(hitpoints)s / %(maxHitpoints)s"), {
|
||||
hitpoints: Math.ceil(entState.hitpoints),
|
||||
maxHitpoints: entState.maxHitpoints
|
||||
});
|
||||
Engine.GetGUIObjectByName("healthSection").hidden = false;
|
||||
}
|
||||
else
|
||||
@ -66,13 +102,9 @@ function displaySingle(entState, template)
|
||||
// TODO: Stamina
|
||||
var player = Engine.GetPlayerID();
|
||||
if (entState.stamina && (entState.player == player || g_DevSettings.controlAll))
|
||||
{
|
||||
Engine.GetGUIObjectByName("staminaSection").hidden = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Engine.GetGUIObjectByName("staminaSection").hidden = true;
|
||||
}
|
||||
|
||||
// Experience
|
||||
if (entState.promotion)
|
||||
@ -82,10 +114,17 @@ function displaySingle(entState, template)
|
||||
experienceSize.rtop = 100 - (100 * Math.max(0, Math.min(1, 1.0 * +entState.promotion.curr / +entState.promotion.req)));
|
||||
experienceBar.size = experienceSize;
|
||||
|
||||
var experience = "[font=\"serif-bold-13\"]Experience: [/font]" + Math.floor(entState.promotion.curr);
|
||||
if (entState.promotion.curr < entState.promotion.req)
|
||||
experience += " / " + entState.promotion.req;
|
||||
Engine.GetGUIObjectByName("experience").tooltip = experience;
|
||||
Engine.GetGUIObjectByName("experience").tooltip = sprintf(translate("%(experience)s %(current)s / %(required)s"), {
|
||||
experience: "[font=\"serif-bold-13\"]" + translate("Experience:") + "[/font]",
|
||||
current: Math.floor(entState.promotion.curr),
|
||||
required: entState.promotion.req
|
||||
});
|
||||
else
|
||||
Engine.GetGUIObjectByName("experience").tooltip = sprintf(translate("%(experience)s %(current)s"), {
|
||||
experience: "[font=\"serif-bold-13\"]" + translate("Experience:") + "[/font]",
|
||||
current: Math.floor(entState.promotion.curr)
|
||||
});
|
||||
Engine.GetGUIObjectByName("experience").hidden = false;
|
||||
}
|
||||
else
|
||||
@ -96,11 +135,9 @@ function displaySingle(entState, template)
|
||||
// Resource stats
|
||||
if (entState.resourceSupply)
|
||||
{
|
||||
var resources = entState.resourceSupply.isInfinite ? "\u221E" : // Infinity symbol
|
||||
Math.ceil(+entState.resourceSupply.amount) + " / " + entState.resourceSupply.max;
|
||||
var resourceType = entState.resourceSupply.type["generic"];
|
||||
if (resourceType == "treasure")
|
||||
resourceType = entState.resourceSupply.type["specific"];
|
||||
var resources = entState.resourceSupply.isInfinite ? translate("∞") : // Infinity symbol
|
||||
sprintf(translate("%(amount)s / %(max)s"), { amount: Math.ceil(+entState.resourceSupply.amount), max: entState.resourceSupply.max });
|
||||
var resourceType = getResourceTypeDisplayName(entState.resourceSupply.type);
|
||||
|
||||
var unitResourceBar = Engine.GetGUIObjectByName("resourceBar");
|
||||
var resourceSize = unitResourceBar.size;
|
||||
@ -108,7 +145,7 @@ function displaySingle(entState, template)
|
||||
resourceSize.rright = entState.resourceSupply.isInfinite ? 100 :
|
||||
100 * Math.max(0, Math.min(1, +entState.resourceSupply.amount / +entState.resourceSupply.max));
|
||||
unitResourceBar.size = resourceSize;
|
||||
Engine.GetGUIObjectByName("resourceLabel").caption = toTitleCase(resourceType) + ":";
|
||||
Engine.GetGUIObjectByName("resourceLabel").caption = sprintf(translate("%(resource)s:"), { resource: resourceType });
|
||||
Engine.GetGUIObjectByName("resourceStats").caption = resources;
|
||||
|
||||
if (entState.hitpoints)
|
||||
@ -132,7 +169,7 @@ function displaySingle(entState, template)
|
||||
Engine.GetGUIObjectByName("resourceCarryingIcon").hidden = false;
|
||||
Engine.GetGUIObjectByName("resourceCarryingText").hidden = false;
|
||||
Engine.GetGUIObjectByName("resourceCarryingIcon").sprite = "stretched:session/icons/resources/"+carried.type+".png";
|
||||
Engine.GetGUIObjectByName("resourceCarryingText").caption = carried.amount + " / " + carried.max;
|
||||
Engine.GetGUIObjectByName("resourceCarryingText").caption = sprintf(translate("%(amount)s / %(max)s"), { amount: carried.amount, max: carried.max });
|
||||
Engine.GetGUIObjectByName("resourceCarryingIcon").tooltip = "";
|
||||
}
|
||||
// Use the same indicators for traders
|
||||
@ -147,7 +184,7 @@ function displaySingle(entState, template)
|
||||
if (entState.trader.goods.amount.market2Gain)
|
||||
totalGain += entState.trader.goods.amount.market2Gain;
|
||||
Engine.GetGUIObjectByName("resourceCarryingText").caption = totalGain;
|
||||
Engine.GetGUIObjectByName("resourceCarryingIcon").tooltip = "Gain: " + getTradingTooltip(entState.trader.goods.amount);
|
||||
Engine.GetGUIObjectByName("resourceCarryingIcon").tooltip = sprintf(translate("Gain: %(amount)s"), { amount: getTradingTooltip(entState.trader.goods.amount) });
|
||||
}
|
||||
// And for number of workers
|
||||
else if (entState.foundation)
|
||||
@ -156,15 +193,15 @@ function displaySingle(entState, template)
|
||||
Engine.GetGUIObjectByName("resourceCarryingText").hidden = false;
|
||||
Engine.GetGUIObjectByName("resourceCarryingIcon").sprite = "stretched:session/icons/repair.png";
|
||||
Engine.GetGUIObjectByName("resourceCarryingText").caption = entState.foundation.numBuilders + " ";
|
||||
Engine.GetGUIObjectByName("resourceCarryingIcon").tooltip = "Number of builders";
|
||||
Engine.GetGUIObjectByName("resourceCarryingIcon").tooltip = translate("Number of builders");
|
||||
}
|
||||
else if (entState.resourceSupply && (!entState.resourceSupply.killBeforeGather || !entState.hitpoints))
|
||||
{
|
||||
Engine.GetGUIObjectByName("resourceCarryingIcon").hidden = false;
|
||||
Engine.GetGUIObjectByName("resourceCarryingText").hidden = false;
|
||||
Engine.GetGUIObjectByName("resourceCarryingIcon").sprite = "stretched:session/icons/repair.png";
|
||||
Engine.GetGUIObjectByName("resourceCarryingText").caption = entState.resourceSupply.gatherers.length + " / " + entState.resourceSupply.maxGatherers + " ";
|
||||
Engine.GetGUIObjectByName("resourceCarryingIcon").tooltip = "Current/max gatherers";
|
||||
Engine.GetGUIObjectByName("resourceCarryingText").caption = sprintf(translate("%(amount)s / %(max)s"), { amount: entState.resourceSupply.gatherers.length, max: entState.resourceSupply.maxGatherers }) + " ";
|
||||
Engine.GetGUIObjectByName("resourceCarryingIcon").tooltip = translate("Current/max gatherers");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -179,7 +216,7 @@ function displaySingle(entState, template)
|
||||
|
||||
if (genericName)
|
||||
{
|
||||
Engine.GetGUIObjectByName("generic").caption = "(" + genericName + ")";
|
||||
Engine.GetGUIObjectByName("generic").caption = sprintf(translate("(%(genericName)s)"), { genericName: genericName });
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -209,31 +246,78 @@ function displaySingle(entState, template)
|
||||
Engine.GetGUIObjectByName("icon").sprite = "bkFillBlack";
|
||||
}
|
||||
|
||||
var armorLabel = "[font=\"serif-bold-13\"]" + translate("Armor:") + "[/font]"
|
||||
var armorString = sprintf(translate("%(label)s %(details)s"), { label: armorLabel, details: armorTypeDetails(entState.armour) });
|
||||
|
||||
// Attack and Armor
|
||||
var type = "";
|
||||
var attack = "[font=\"serif-bold-13\"]"+type+"Attack:[/font] " + damageTypeDetails(entState.attack);
|
||||
if (entState.attack)
|
||||
{
|
||||
type = entState.attack.type + " ";
|
||||
// Rate
|
||||
if (entState.buildingAI)
|
||||
var rateLabel = "[font=\"serif-bold-13\"]" + translate("Interval:") + "[/font]";
|
||||
else
|
||||
var rateLabel = "[font=\"serif-bold-13\"]" + translate("Rate:") + "[/font]";
|
||||
|
||||
// Show max attack range if ranged attack, also convert to tiles (4m per tile)
|
||||
var rate = sprintf(translate("%(label)s %(details)s"), {
|
||||
label: rateLabel,
|
||||
details: attackRateDetails(entState)
|
||||
});
|
||||
|
||||
var attack;
|
||||
var label = "[font=\"serif-bold-13\"]" + getAttackTypeLabel(entState.attack.type) + "[/font]"
|
||||
if (entState.attack.type == "Ranged")
|
||||
{
|
||||
var realRange = entState.attack.elevationAdaptedRange;
|
||||
var range = entState.attack.maxRange;
|
||||
attack += ", [font=\"serif-bold-13\"]Range:[/font] " + Math.round(range) +
|
||||
"[font=\"sans-10\"][color=\"orange\"] meters[/color][/font]";
|
||||
|
||||
if (Math.round(realRange - range) > 0)
|
||||
attack += " (+" + Math.round(realRange - range) + ")";
|
||||
else if (Math.round(realRange - range) < 0)
|
||||
attack += " (" + Math.round(realRange - range) + ")";
|
||||
var rangeLabel = "[font=\"serif-bold-13\"]" + translate("Range:") + "[/font]"
|
||||
var relativeRange = Math.round((realRange - range));
|
||||
var meters = "[font=\"sans-10\"][color=\"orange\"]" + translate("meters") + "[/color][/font]";
|
||||
|
||||
if (relativeRange > 0)
|
||||
attack = sprintf(translate("%(label)s %(details)s, %(rangeLabel)s %(range)s %(meters)s (%(relative)s), %(rate)s"), {
|
||||
label: label,
|
||||
details: damageTypeDetails(entState.attack),
|
||||
rangeLabel: rangeLabel,
|
||||
range: Math.round(range),
|
||||
meters: meters,
|
||||
relative: "+" + relativeRange,
|
||||
rate: rate
|
||||
});
|
||||
else if (relativeRange < 0)
|
||||
attack = sprintf(translate("%(label)s %(details)s, %(rangeLabel)s %(range)s %(meters)s (%(relative)s), %(rate)s"), {
|
||||
label: label,
|
||||
details: damageTypeDetails(entState.attack),
|
||||
rangeLabel: rangeLabel,
|
||||
range: Math.round(range),
|
||||
meters: meters,
|
||||
relative: relativeRange,
|
||||
rate: rate
|
||||
});
|
||||
else // don't show when it's 0
|
||||
attack = sprintf(translate("%(label)s %(details)s, %(rangeLabel)s %(range)s %(meters)s, %(rate)s"), {
|
||||
label: label,
|
||||
details: damageTypeDetails(entState.attack),
|
||||
rangeLabel: rangeLabel,
|
||||
range: Math.round(range),
|
||||
meters: meters,
|
||||
rate: rate
|
||||
});
|
||||
}
|
||||
attack += ", [font=\"serif-bold-13\"]" + (entState.buildingAI ? "Rate" : "Interval") + ":[/font] " + attackRateDetails(entState);
|
||||
else
|
||||
{
|
||||
attack = sprintf(translate("%(label)s %(details)s, %(rate)s"), {
|
||||
label: label,
|
||||
details: damageTypeDetails(entState.attack),
|
||||
rate: rate
|
||||
});
|
||||
}
|
||||
|
||||
Engine.GetGUIObjectByName("attackAndArmorStats").tooltip = attack + "\n" + armorString;
|
||||
}
|
||||
else
|
||||
{
|
||||
Engine.GetGUIObjectByName("attackAndArmorStats").tooltip = armorString;
|
||||
}
|
||||
|
||||
Engine.GetGUIObjectByName("attackAndArmorStats").tooltip = attack + "\n[font=\"serif-bold-13\"]Armor:[/font] " + armorTypeDetails(entState.armour);
|
||||
|
||||
// Icon Tooltip
|
||||
var iconTooltip = "";
|
||||
@ -277,7 +361,8 @@ function displayMultiple(selection, template)
|
||||
healthSize.rtop = 100-100*Math.max(0, Math.min(1, averageHealth / maxHealth));
|
||||
unitHealthBar.size = healthSize;
|
||||
|
||||
var hitpoints = "[font=\"serif-bold-13\"]Hitpoints [/font]" + averageHealth + " / " + maxHealth;
|
||||
var hitpointsLabel = "[font=\"serif-bold-13\"]" + translate("Hitpoints:") + "[/font]"
|
||||
var hitpoints = sprintf(translate("%(label)s %(current)s / %(max)s"), { label: hitpointsLabel, current: averageHealth, max: maxHealth });
|
||||
var healthMultiple = Engine.GetGUIObjectByName("healthMultiple");
|
||||
healthMultiple.tooltip = hitpoints;
|
||||
healthMultiple.hidden = false;
|
||||
|
@ -16,7 +16,7 @@ var g_CivData = {};
|
||||
var g_GameSpeeds = {};
|
||||
var g_CurrentSpeed;
|
||||
|
||||
var g_PlayerAssignments = { "local": { "name": "You", "player": 1 } };
|
||||
var g_PlayerAssignments = { "local": { "name": translate("You"), "player": 1 } };
|
||||
|
||||
// Cache dev-mode settings that are frequently or widely used
|
||||
var g_DevSettings = {
|
||||
@ -100,6 +100,7 @@ function GetExtendedEntityState(entId)
|
||||
|
||||
// Cache TemplateData
|
||||
var g_TemplateData = {}; // {id:template}
|
||||
var g_TemplateDataWithoutLocalization = {};
|
||||
|
||||
|
||||
function GetTemplateData(templateName)
|
||||
@ -107,12 +108,24 @@ function GetTemplateData(templateName)
|
||||
if (!(templateName in g_TemplateData))
|
||||
{
|
||||
var template = Engine.GuiInterfaceCall("GetTemplateData", templateName);
|
||||
translateObjectKeys(template, ["specific", "generic", "tooltip"]);
|
||||
g_TemplateData[templateName] = template;
|
||||
}
|
||||
|
||||
return g_TemplateData[templateName];
|
||||
}
|
||||
|
||||
function GetTemplateDataWithoutLocalization(templateName)
|
||||
{
|
||||
if (!(templateName in g_TemplateDataWithoutLocalization))
|
||||
{
|
||||
var template = Engine.GuiInterfaceCall("GetTemplateData", templateName);
|
||||
g_TemplateDataWithoutLocalization[templateName] = template;
|
||||
}
|
||||
|
||||
return g_TemplateDataWithoutLocalization[templateName];
|
||||
}
|
||||
|
||||
// Cache TechnologyData
|
||||
var g_TechnologyData = {}; // {id:template}
|
||||
|
||||
@ -121,6 +134,7 @@ function GetTechnologyData(technologyName)
|
||||
if (!(technologyName in g_TechnologyData))
|
||||
{
|
||||
var template = Engine.GuiInterfaceCall("GetTechnologyData", technologyName);
|
||||
translateObjectKeys(template, ["specific", "generic", "description", "tooltip", "requirementsTooltip"]);
|
||||
g_TechnologyData[technologyName] = template;
|
||||
}
|
||||
|
||||
@ -153,7 +167,7 @@ function init(initData, hotloadData)
|
||||
|
||||
// Cache civ data
|
||||
g_CivData = loadCivData();
|
||||
g_CivData["gaia"] = { "Code": "gaia", "Name": "Gaia"};
|
||||
g_CivData["gaia"] = { "Code": "gaia", "Name": translate("Gaia") };
|
||||
|
||||
if (Engine.GetPlayerID() <= 0)
|
||||
{
|
||||
@ -295,32 +309,26 @@ function leaveGame(willRejoin)
|
||||
if (g_IsObserver)
|
||||
{
|
||||
// Observers don't win/lose.
|
||||
gameResult = "You have left the game.";
|
||||
gameResult = translate("You have left the game.");
|
||||
global.music.setState(global.music.states.VICTORY);
|
||||
}
|
||||
else
|
||||
{
|
||||
var playerState = extendedSimState.players[Engine.GetPlayerID()];
|
||||
if (g_Disconnected)
|
||||
{
|
||||
gameResult = "You have been disconnected."
|
||||
}
|
||||
gameResult = translate("You have been disconnected.");
|
||||
else if (playerState.state == "won")
|
||||
{
|
||||
gameResult = "You have won the battle!";
|
||||
}
|
||||
gameResult = translate("You have won the battle!");
|
||||
else if (playerState.state == "defeated")
|
||||
{
|
||||
gameResult = "You have been defeated...";
|
||||
}
|
||||
gameResult = translate("You have been defeated...");
|
||||
else // "active"
|
||||
{
|
||||
global.music.setState(global.music.states.DEFEAT);
|
||||
if (willRejoin)
|
||||
gameResult = "You have left the game.";
|
||||
gameResult = translate("You have left the game.");
|
||||
else
|
||||
{
|
||||
gameResult = "You have abandoned the game.";
|
||||
gameResult = translate("You have abandoned the game.");
|
||||
resignGame(true);
|
||||
}
|
||||
}
|
||||
@ -471,21 +479,21 @@ function checkPlayerState()
|
||||
if (Engine.IsAtlasRunning())
|
||||
{
|
||||
// If we're in Atlas, we can't leave the game
|
||||
var btCaptions = ["OK"];
|
||||
var btCaptions = [translate("OK")];
|
||||
var btCode = [null];
|
||||
var message = "Press OK to continue";
|
||||
var message = translate("Press OK to continue");
|
||||
}
|
||||
else
|
||||
{
|
||||
var btCaptions = ["Yes", "No"];
|
||||
var btCaptions = [translate("Yes"), translate("No")];
|
||||
var btCode = [leaveGame, null];
|
||||
var message = "Do you want to quit?";
|
||||
var message = translate("Do you want to quit?");
|
||||
}
|
||||
|
||||
if (playerState.state == "defeated")
|
||||
{
|
||||
global.music.setState(global.music.states.DEFEAT);
|
||||
messageBox(400, 200, message, "DEFEATED!", 0, btCaptions, btCode);
|
||||
messageBox(400, 200, message, translate("DEFEATED!"), 0, btCaptions, btCode);
|
||||
}
|
||||
else if (playerState.state == "won")
|
||||
{
|
||||
@ -493,9 +501,8 @@ function checkPlayerState()
|
||||
// TODO: Reveal map directly instead of this silly proxy.
|
||||
if (!Engine.GetGUIObjectByName("devCommandsRevealMap").checked)
|
||||
Engine.GetGUIObjectByName("devCommandsRevealMap").checked = true;
|
||||
messageBox(400, 200, message, "VICTORIOUS!", 0, btCaptions, btCode);
|
||||
messageBox(400, 200, message, translate("VICTORIOUS!"), 0, btCaptions, btCode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function changeGameSpeed(speed)
|
||||
@ -621,14 +628,25 @@ function updateHero()
|
||||
|
||||
// Setup tooltip
|
||||
var tooltip = "[font=\"serif-bold-16\"]" + template.name.specific + "[/font]";
|
||||
tooltip += "\n[font=\"serif-bold-13\"]Health:[/font] " + heroState.hitpoints + "/" + heroState.maxHitpoints;
|
||||
tooltip += "\n[font=\"serif-bold-13\"]" + (heroState.attack ? heroState.attack.type + " " : "")
|
||||
+ "Attack:[/font] " + damageTypeDetails(heroState.attack);
|
||||
// Show max attack range if ranged attack, also convert to tiles (4m per tile)
|
||||
var healthLabel = "[font=\"serif-bold-13\"]" + translate("Health:") + "[/font]";
|
||||
tooltip += "\n" + sprintf(translate("%(label)s %(current)s / %(max)s"), { label: healthLabel, current: heroState.hitpoints, max: heroState.maxHitpoints });
|
||||
var attackLabel = "[font=\"serif-bold-13\"]" + getAttackTypeLabel(heroState.attack.type) + "[/font]";
|
||||
if (heroState.attack && heroState.attack.type == "Ranged")
|
||||
tooltip += ", [font=\"serif-bold-13\"]Range:[/font] " + Math.round(heroState.attack.maxRange/4);
|
||||
// Show max attack range if ranged attack, also convert to tiles (4m per tile)
|
||||
tooltip += "\n" + sprintf(
|
||||
translate("%(attackLabel)s %(details)s, %(rangeLabel)s %(range)s"),
|
||||
{
|
||||
attackLabel: attackLabel,
|
||||
details: damageTypeDetails(heroState.attack),
|
||||
rangeLabel: "[font=\"serif-bold-13\"]" + translate("Range:") + "[/font]",
|
||||
range: Math.round(heroState.attack.maxRange/4)
|
||||
}
|
||||
);
|
||||
else
|
||||
tooltip += "\n" + sprintf(translate("%(label)s %(details)s"), { label: attackLabel, details: damageTypeDetails(heroState.armour) });
|
||||
|
||||
tooltip += "\n[font=\"serif-bold-13\"]Armor:[/font] " + damageTypeDetails(heroState.armour);
|
||||
var armorLabel = "[font=\"serif-bold-13\"]" + translate("Armor:") + "[/font]";
|
||||
tooltip += "\n" + sprintf(translate("%(label)s %(details)s"), { label: armorLabel, details: damageTypeDetails(heroState.attack) });
|
||||
tooltip += "\n" + template.tooltip;
|
||||
|
||||
heroButton.tooltip = tooltip;
|
||||
@ -792,9 +810,11 @@ function updateResearchDisplay()
|
||||
function updateTimeElapsedCounter()
|
||||
{
|
||||
var simState = GetSimState();
|
||||
var speed = g_CurrentSpeed != 1.0 ? " (" + g_CurrentSpeed + "x)" : "";
|
||||
var timeElapsedCounter = Engine.GetGUIObjectByName("timeElapsedCounter");
|
||||
timeElapsedCounter.caption = timeToString(simState.timeElapsed) + speed;
|
||||
if (g_CurrentSpeed != 1.0)
|
||||
timeElapsedCounter.caption = sprintf(translate("%(time)s (%(speed)sx)"), { time: timeToString(simState.timeElapsed), speed: Engine.FormatDecimalNumberIntoString(g_CurrentSpeed) });
|
||||
else
|
||||
timeElapsedCounter.caption = timeToString(simState.timeElapsed);
|
||||
}
|
||||
|
||||
// Toggles the display of status bars for all of the player's entities.
|
||||
@ -881,7 +901,7 @@ function playRandomAmbient(type)
|
||||
break;
|
||||
|
||||
default:
|
||||
Engine.Console_Write("Unrecognized ambient type: " + type);
|
||||
Engine.Console_Write(sprintf(translate("Unrecognized ambient type: %(ambientType)s"), { ambientType: type }));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -895,6 +915,17 @@ function stopAmbient()
|
||||
currentAmbient = null;
|
||||
}
|
||||
}
|
||||
|
||||
function getBuildString()
|
||||
{
|
||||
return sprintf(translate("Build: %(buildDate)s (%(revision)s)"), { buildDate: Engine.GetBuildTimestamp(0), revision: Engine.GetBuildTimestamp(2) });
|
||||
}
|
||||
|
||||
function showTimeWarpMessageBox()
|
||||
{
|
||||
messageBox(500, 250, translate("Note: time warp mode is a developer option, and not intended for use over long periods of time. Using it incorrectly may cause the game to run out of memory or crash."), translate("Time warp mode"), 2);
|
||||
}
|
||||
|
||||
// Send a report on the game status to the lobby
|
||||
function reportGame(extendedSimState)
|
||||
{
|
||||
|
@ -243,7 +243,9 @@
|
||||
hidden="true" hotkey="session.devcommands.toggle">
|
||||
<action on="Press">toggleDeveloperOverlay();</action>
|
||||
|
||||
<object size="0 0 100%-18 16" type="text" style="devCommandsText">Control all units</object>
|
||||
<object size="0 0 100%-18 16" type="text" style="devCommandsText">
|
||||
<translatableAttribute id="caption">Control all units</translatableAttribute>
|
||||
</object>
|
||||
<object size="100%-16 0 100% 16" type="checkbox" name="devControlAll" style="ModernTickBox">
|
||||
<action on="Press">
|
||||
g_DevSettings.controlAll = this.checked;
|
||||
@ -251,40 +253,56 @@
|
||||
</action>
|
||||
</object>
|
||||
|
||||
<object size="0 16 100%-18 32" type="text" style="devCommandsText">Change perspective</object>
|
||||
<object size="0 16 100%-18 32" type="text" style="devCommandsText">
|
||||
<translatableAttribute id="caption">Change perspective</translatableAttribute>
|
||||
</object>
|
||||
<object size="100%-16 16 100% 32" type="checkbox" style="ModernTickBox">
|
||||
<action on="Press">Engine.GetGUIObjectByName("viewPlayer").hidden = !this.checked;</action>
|
||||
</object>
|
||||
|
||||
<object size="0 32 100%-18 48" type="text" style="devCommandsText">Display selection state</object>
|
||||
<object size="0 32 100%-18 48" type="text" style="devCommandsText">
|
||||
<translatableAttribute id="caption">Display selection state</translatableAttribute>
|
||||
</object>
|
||||
<object size="100%-16 32 100% 48" type="checkbox" name="devDisplayState" style="ModernTickBox"/>
|
||||
|
||||
<object size="0 48 100%-18 64" type="text" style="devCommandsText">Pathfinder overlay</object>
|
||||
<object size="0 48 100%-18 64" type="text" style="devCommandsText">
|
||||
<translatableAttribute id="caption">Pathfinder overlay</translatableAttribute>
|
||||
</object>
|
||||
<object size="100%-16 48 100% 64" type="checkbox" style="ModernTickBox">
|
||||
<action on="Press">Engine.GuiInterfaceCall("SetPathfinderDebugOverlay", this.checked);</action>
|
||||
</object>
|
||||
|
||||
<object size="0 64 100%-18 80" type="text" style="devCommandsText">Obstruction overlay</object>
|
||||
<object size="0 64 100%-18 80" type="text" style="devCommandsText">
|
||||
<translatableAttribute id="caption">Obstruction overlay</translatableAttribute>
|
||||
</object>
|
||||
<object size="100%-16 64 100% 80" type="checkbox" style="ModernTickBox">
|
||||
<action on="Press">Engine.GuiInterfaceCall("SetObstructionDebugOverlay", this.checked);</action>
|
||||
</object>
|
||||
|
||||
<object size="0 80 100%-18 96" type="text" style="devCommandsText">Unit motion overlay</object>
|
||||
<object size="0 80 100%-18 96" type="text" style="devCommandsText">
|
||||
<translatableAttribute id="caption">Unit motion overlay</translatableAttribute>
|
||||
</object>
|
||||
<object size="100%-16 80 100% 96" type="checkbox" style="ModernTickBox">
|
||||
<action on="Press">g_Selection.SetMotionDebugOverlay(this.checked);</action>
|
||||
</object>
|
||||
|
||||
<object size="0 96 100%-18 112" type="text" style="devCommandsText">Range overlay</object>
|
||||
<object size="0 96 100%-18 112" type="text" style="devCommandsText">
|
||||
<translatableAttribute id="caption">Range overlay</translatableAttribute>
|
||||
</object>
|
||||
<object size="100%-16 96 100% 112" type="checkbox" style="ModernTickBox">
|
||||
<action on="Press">Engine.GuiInterfaceCall("SetRangeDebugOverlay", this.checked);</action>
|
||||
</object>
|
||||
|
||||
<object size="0 112 100%-18 128" type="text" style="devCommandsText">Bounding box overlay</object>
|
||||
<object size="0 112 100%-18 128" type="text" style="devCommandsText">
|
||||
<translatableAttribute id="caption">Bounding box overlay</translatableAttribute>
|
||||
</object>
|
||||
<object size="100%-16 112 100% 128" type="checkbox" style="ModernTickBox">
|
||||
<action on="Press">Engine.SetBoundingBoxDebugOverlay(this.checked);</action>
|
||||
</object>
|
||||
|
||||
<object size="0 128 100%-18 144" type="text" style="devCommandsText">Restrict camera</object>
|
||||
<object size="0 128 100%-18 144" type="text" style="devCommandsText">
|
||||
<translatableAttribute id="caption">Restrict camera</translatableAttribute>
|
||||
</object>
|
||||
<object size="100%-16 128 100% 144" type="checkbox" style="ModernTickBox" checked="true">
|
||||
<action on="Press">
|
||||
Engine.GameView_SetConstrainCameraEnabled(this.checked);
|
||||
@ -296,21 +314,27 @@
|
||||
</action>
|
||||
</object>
|
||||
|
||||
<object size="0 144 100%-18 160" type="text" style="devCommandsText">Reveal map</object>
|
||||
<object size="0 144 100%-18 160" type="text" style="devCommandsText">
|
||||
<translatableAttribute id="caption">Reveal map</translatableAttribute>
|
||||
</object>
|
||||
<object size="100%-16 144 100% 160" type="checkbox" name="devCommandsRevealMap" style="ModernTickBox">
|
||||
<action on="Load">this.checked = Engine.GuiInterfaceCall("IsMapRevealed");</action>
|
||||
<action on="Press">Engine.PostNetworkCommand({"type": "reveal-map", "enable": this.checked});</action>
|
||||
</object>
|
||||
|
||||
<object size="0 160 100%-18 176" type="text" style="devCommandsText">Enable time warp</object>
|
||||
<object size="0 160 100%-18 176" type="text" style="devCommandsText">
|
||||
<translatableAttribute id="caption">Enable time warp</translatableAttribute>
|
||||
</object>
|
||||
<object size="100%-16 160 100% 176" type="checkbox" name="devTimeWarp" style="ModernTickBox">
|
||||
<action on="Press">
|
||||
if (this.checked)
|
||||
messageBox(500, 250, "Note: time warp mode is a developer option, and not intended\nfor use over long periods of time. Using it incorrectly may\ncause the game to run out of memory or crash.", "Time warp mode", 2);
|
||||
showTimeWarpMessageBox();
|
||||
Engine.EnableTimeWarpRecording(this.checked ? 10 : 0);</action>
|
||||
</object>
|
||||
|
||||
<object size="0 176 100%-18 192" type="text" style="devCommandsText">Promote selected units</object>
|
||||
<object size="0 176 100%-18 192" type="text" style="devCommandsText">
|
||||
<translatableAttribute id="caption">Promote selected units</translatableAttribute>
|
||||
</object>
|
||||
<object size="100%-16 176 100% 192" type="button" style="ModernTickBox">
|
||||
<action on="Press">Engine.PostNetworkCommand({"type": "promote", "entities": g_Selection.toList()});</action>
|
||||
</object>
|
||||
@ -335,8 +359,12 @@
|
||||
z="0"
|
||||
>
|
||||
<object size="0 0 100% 100%" type="image" sprite="devCommandsBackground" ghost="true" z="0"/>
|
||||
<object size="50%-128 50%-20 50%+128 50%+20" type="text" style="PauseText" ghost="true" z="0">Game Paused</object>
|
||||
<object size="50%-128 50%+20 50%+128 50%+30" type="text" style="PauseMessageText" ghost="true" z="0">Click to Resume Game</object>
|
||||
<object size="50%-128 50%-20 50%+128 50%+20" type="text" style="PauseText" ghost="true" z="0">
|
||||
<translatableAttribute id="caption">Game Paused</translatableAttribute>
|
||||
</object>
|
||||
<object size="50%-128 50%+20 50%+128 50%+30" type="text" style="PauseMessageText" ghost="true" z="0">
|
||||
<translatableAttribute id="caption">Click to Resume Game</translatableAttribute>
|
||||
</object>
|
||||
<action on="Press">togglePause();</action>
|
||||
</object>
|
||||
|
||||
@ -367,13 +395,13 @@
|
||||
</object>
|
||||
|
||||
<object size="16 100%-40 30%+16 100%-12" type="button" style="StoneButton">
|
||||
Send
|
||||
<action on="Press">submitChatInput();</action>
|
||||
<translatableAttribute id="caption">Send</translatableAttribute>
|
||||
<action on="Press">submitChatInput();</action>
|
||||
</object>
|
||||
|
||||
<object size="30%+24 100%-40 60%+24 100%-12" type="button" style="StoneButton">
|
||||
Cancel
|
||||
<action on="Press">closeChat();</action>
|
||||
<translatableAttribute id="caption">Cancel</translatableAttribute>
|
||||
<action on="Press">closeChat();</action>
|
||||
</object>
|
||||
<object name="toggleTeamChat" size="60%+32 100%-34 60%+48 100%-6" type="checkbox" style="ModernTickBox"/>
|
||||
<object size="60%+48 100%-40 100% 100%-12" type="text" style="ModernLeftLabelText">
|
||||
@ -390,17 +418,38 @@
|
||||
hidden="true"
|
||||
sprite="ModernDialog"
|
||||
>
|
||||
<object type="text" style="TitleText" size="50%-96 -16 50%+96 16">Diplomacy</object>
|
||||
<object type="text" style="TitleText" size="50%-96 -16 50%+96 16">
|
||||
<translatableAttribute id="caption">Diplomacy</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object name="diplomacyHeader" size="32 32 100%-32 64">
|
||||
<object name="diplomacyHeaderName" size="0 0 150 100%" type="text" style="chatPanel" ghost="true" caption="Name"/>
|
||||
<object name="diplomacyHeaderCiv" size="150 0 250 100%" type="text" style="chatPanel" ghost="true" caption="Civilization"/>
|
||||
<object name="diplomacyHeaderTeam" size="250 0 300 100%" type="text" style="chatPanel" ghost="true" caption="Team"/>
|
||||
<object name="diplomacyHeaderTheirs" size="300 0 360 100%" type="text" style="chatPanel" ghost="true" caption="Theirs"/>
|
||||
<object name="diplomacyHeaderAlly" size="100%-180 0 100%-160 100%" type="text" style="chatPanel" caption="A" tooltip="Ally" tooltip_style="sessionToolTipBold"/>
|
||||
<object name="diplomacyHeaderNeutral" size="100%-160 0 100%-140 100%" type="text" style="chatPanel" caption="N" tooltip="Neutral" tooltip_style="sessionToolTipBold"/>
|
||||
<object name="diplomacyHeaderEnemy" size="100%-140 0 100%-120 100%" type="text" style="chatPanel" caption="E" tooltip="Enemy" tooltip_style="sessionToolTipBold"/>
|
||||
<object name="diplomacyHeaderTribute" size="100%-110 0 100% 100%" type="text" style="chatPanel" caption="Tribute"/>
|
||||
<object name="diplomacyHeaderName" size="0 0 150 100%" type="text" style="chatPanel" ghost="true">
|
||||
<translatableAttribute id="caption">Name</translatableAttribute>
|
||||
</object>
|
||||
<object name="diplomacyHeaderCiv" size="150 0 250 100%" type="text" style="chatPanel" ghost="true">
|
||||
<translatableAttribute id="caption">Civilization</translatableAttribute>
|
||||
</object>
|
||||
<object name="diplomacyHeaderTeam" size="250 0 300 100%" type="text" style="chatPanel" ghost="true">
|
||||
<translatableAttribute id="caption">Team</translatableAttribute>
|
||||
</object>
|
||||
<object name="diplomacyHeaderTheirs" size="300 0 360 100%" type="text" style="chatPanel" ghost="true">
|
||||
<translatableAttribute id="caption">Theirs</translatableAttribute>
|
||||
</object>
|
||||
<object name="diplomacyHeaderAlly" size="100%-180 0 100%-160 100%" type="text" style="chatPanel" tooltip_style="sessionToolTipBold">
|
||||
<translatableAttribute id="caption">A</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Ally</translatableAttribute>
|
||||
</object>
|
||||
<object name="diplomacyHeaderNeutral" size="100%-160 0 100%-140 100%" type="text" style="chatPanel" tooltip_style="sessionToolTipBold">
|
||||
<translatableAttribute id="caption">N</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Neutral</translatableAttribute>
|
||||
</object>
|
||||
<object name="diplomacyHeaderEnemy" size="100%-140 0 100%-120 100%" type="text" style="chatPanel" tooltip_style="sessionToolTipBold">
|
||||
<translatableAttribute id="caption">E</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Enemy</translatableAttribute>
|
||||
</object>
|
||||
<object name="diplomacyHeaderTribute" size="100%-110 0 100% 100%" type="text" style="chatPanel">
|
||||
<translatableAttribute id="caption">Tribute</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object size="32 64 100%-32 384">
|
||||
@ -448,11 +497,15 @@
|
||||
hidden="true"
|
||||
sprite="ModernDialog"
|
||||
>
|
||||
<object type="text" style="TitleText" size="50%-96 -16 50%+96 16">Trade</object>
|
||||
<object type="text" style="TitleText" size="50%-96 -16 50%+96 16">
|
||||
<translatableAttribute id="caption">Trade</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<!-- Trading goods -->
|
||||
<object name="tradeGoods" size="20 50 100%-20 82">
|
||||
<object name="tradeHeader" size="0 0 180 100%" type="text" style="ModernLabelText" text_align="left" ghost="true" caption="Trading goods selection:"/>
|
||||
<object name="tradeHeader" size="0 0 180 100%" type="text" style="ModernLabelText" text_align="left" ghost="true">
|
||||
<translatableAttribute id="caption">Trading goods selection:</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object size="180 0 100% 100%">
|
||||
<repeat count="4">
|
||||
@ -470,21 +523,20 @@
|
||||
</object>
|
||||
</object>
|
||||
</repeat>
|
||||
<object name="tradeHelp" size="100%-24 4 100% 28" enabled="false" type="button" style="StoneButton" tooltip_style="sessionToolTipBold" tooltip="Select one goods as origin of the changes, \nthen use the arrows of the target goods to make the changes.">
|
||||
<object name="tradeHelp" size="100%-24 4 100% 28" enabled="false" type="button" style="StoneButton" tooltip_style="sessionToolTipBold">
|
||||
<translatableAttribute id="tooltip">Select one goods as origin of the changes,\nthen use the arrows of the target goods to make the changes.</translatableAttribute>
|
||||
<object size="20% 15% 80% 75%" type="image" ghost="true" sprite="iconInfoWhite"/>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object name="tradeStatistics" size="20 120 100%-20 168">
|
||||
<object size="0 0 130 50%" type="text" style="ModernLabelText" text_align="left" ghost="true" caption="Traders:"/>
|
||||
<object name="landTraders" size="130 0 100% 50%" type="text" style="ModernLabelText" text_align="left" ghost="true" />
|
||||
<object size="0 50% 130 100%" type="text" style="ModernLabelText" text_align="left" ghost="true" caption = "Merchant ships:"/>
|
||||
<object name="shipTraders" size="130 50% 100% 100%" type="text" style="ModernLabelText" text_align="left" ghost="true" />
|
||||
<object name="tradeStatistics" size="20 90 100%-20 168">
|
||||
<object name="landTraders" size="0 0 100% 50%" type="text" style="ModernLabelText" text_align="left" ghost="true" />
|
||||
<object name="shipTraders" size="0 50% 100% 100%" type="text" style="ModernLabelText" text_align="left" ghost="true" />
|
||||
</object>
|
||||
|
||||
<object size="50%-64 100%-50 50%+64 100%-22" type="button" style="StoneButton">
|
||||
Close
|
||||
<translatableAttribute id="caption">Close</translatableAttribute>
|
||||
<action on="Press">closeTrade();</action>
|
||||
</object>
|
||||
</object>
|
||||
@ -499,97 +551,125 @@
|
||||
hidden="true"
|
||||
z="200"
|
||||
>
|
||||
<object type="text" style="TitleText" size="50%-96 -16 50%+96 16">Settings</object>
|
||||
<object type="text" style="TitleText" size="50%-96 -16 50%+96 16">
|
||||
<translatableAttribute id="caption">Settings</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object style="TranslucentPanelThinBorder"
|
||||
type="image"
|
||||
size="32 32 100%-32 100%-70"
|
||||
>
|
||||
<!-- Settings / shadows -->
|
||||
<object size="0 10 100%-80 35" type="text" style="ModernRightLabelText" ghost="true">Enable Shadows</object>
|
||||
<object size="0 10 100%-80 35" type="text" style="ModernRightLabelText" ghost="true">
|
||||
<translatableAttribute id="caption">Enable Shadows</translatableAttribute>
|
||||
</object>
|
||||
<object name="shadowsCheckbox" size="100%-56 15 100%-30 40" type="checkbox" style="ModernTickBox" checked="true">
|
||||
<action on="Load">this.checked = Engine.Renderer_GetShadowsEnabled();</action>
|
||||
<action on="Press">Engine.Renderer_SetShadowsEnabled(this.checked);</action>
|
||||
</object>
|
||||
|
||||
<!-- Settings / Shadow PCF -->
|
||||
<object size="0 35 100%-80 60" type="text" style="ModernRightLabelText" ghost="true">Enable Shadow Filtering</object>
|
||||
<object size="0 35 100%-80 60" type="text" style="ModernRightLabelText" ghost="true">
|
||||
<translatableAttribute id="caption">Enable Shadow Filtering</translatableAttribute>
|
||||
</object>
|
||||
<object name="shadowPCFCheckbox" size="100%-56 40 100%-30 65" type="checkbox" style="ModernTickBox" checked="true">
|
||||
<action on="Load">this.checked = Engine.Renderer_GetShadowPCFEnabled();</action>
|
||||
<action on="Press">Engine.Renderer_SetShadowPCFEnabled(this.checked);</action>
|
||||
</object>
|
||||
|
||||
<!-- Settings / Water Normals -->
|
||||
<object size="0 60 100%-80 85" type="text" style="ModernRightLabelText" ghost="true">Water - HQ Waviness</object>
|
||||
<object size="0 60 100%-80 85" type="text" style="ModernRightLabelText" ghost="true">
|
||||
<translatableAttribute id="caption">Water - HQ Waviness</translatableAttribute>
|
||||
</object>
|
||||
<object name="waterNormalCheckox" size="100%-56 65 100%-30 90" type="checkbox" style="ModernTickBox" checked="true">
|
||||
<action on="Load">this.checked = Engine.Renderer_GetWaterNormalEnabled();</action>
|
||||
<action on="Press">Engine.Renderer_SetWaterNormalEnabled(this.checked);</action>
|
||||
</object>
|
||||
|
||||
<!-- Settings / Real Depth -->
|
||||
<object size="0 85 100%-80 110" type="text" style="ModernRightLabelText" ghost="true">Water - Use Actual Depth</object>
|
||||
<object size="0 85 100%-80 110" type="text" style="ModernRightLabelText" ghost="true">
|
||||
<translatableAttribute id="caption">Water - Use Actual Depth</translatableAttribute>
|
||||
</object>
|
||||
<object name="waterRealDepthCheckbox" size="100%-56 90 100%-30 115" type="checkbox" style="ModernTickBox" checked="true">
|
||||
<action on="Load">this.checked = Engine.Renderer_GetWaterRealDepthEnabled();</action>
|
||||
<action on="Press">Engine.Renderer_SetWaterRealDepthEnabled(this.checked);</action>
|
||||
</object>
|
||||
|
||||
<!-- Settings / Reflection -->
|
||||
<object size="0 110 100%-80 135" type="text" style="ModernRightLabelText" ghost="true">Water - Enable Reflections</object>
|
||||
<object size="0 110 100%-80 135" type="text" style="ModernRightLabelText" ghost="true">
|
||||
<translatableAttribute id="caption">Water - Enable Reflections</translatableAttribute>
|
||||
</object>
|
||||
<object name="waterReflectionCheckbox" size="100%-56 115 100%-30 140" type="checkbox" style="ModernTickBox" checked="true">
|
||||
<action on="Load">this.checked = Engine.Renderer_GetWaterReflectionEnabled();</action>
|
||||
<action on="Press">Engine.Renderer_SetWaterReflectionEnabled(this.checked);</action>
|
||||
</object>
|
||||
|
||||
<!-- Settings / Refraction -->
|
||||
<object size="0 135 100%-80 160" type="text" style="ModernRightLabelText" ghost="true">Water - Enable Refraction</object>
|
||||
<object size="0 135 100%-80 160" type="text" style="ModernRightLabelText" ghost="true">
|
||||
<translatableAttribute id="caption">Water - Enable Refraction</translatableAttribute>
|
||||
</object>
|
||||
<object name="waterRefractionCheckbox" size="100%-56 140 100%-30 165" type="checkbox" style="ModernTickBox" checked="true">
|
||||
<action on="Load">this.checked = Engine.Renderer_GetWaterRefractionEnabled();</action>
|
||||
<action on="Press">Engine.Renderer_SetWaterRefractionEnabled(this.checked);</action>
|
||||
</object>
|
||||
|
||||
<!-- Settings / Foam -->
|
||||
<object size="0 160 100%-80 185" type="text" style="ModernRightLabelText" ghost="true">Water - Enable Shore Foam</object>
|
||||
<object size="0 160 100%-80 185" type="text" style="ModernRightLabelText" ghost="true">
|
||||
<translatableAttribute id="caption">Water - Enable Shore Foam</translatableAttribute>
|
||||
</object>
|
||||
<object name="waterFoamCheckbox" size="100%-56 165 100%-30 190" type="checkbox" style="ModernTickBox" checked="true">
|
||||
<action on="Load">this.checked = Engine.Renderer_GetWaterFoamEnabled();</action>
|
||||
<action on="Press">Engine.Renderer_SetWaterFoamEnabled(this.checked);</action>
|
||||
</object>
|
||||
|
||||
<!-- Settings / Waves -->
|
||||
<object size="0 185 100%-80 210" type="text" style="ModernRightLabelText" ghost="true">Water - Enable Shore Waves</object>
|
||||
<object size="0 185 100%-80 210" type="text" style="ModernRightLabelText" ghost="true">
|
||||
<translatableAttribute id="caption">Water - Enable Shore Waves</translatableAttribute>
|
||||
</object>
|
||||
<object name="waterCoastalWavesCheckbox" size="100%-56 190 100%-30 215" type="checkbox" style="ModernTickBox" checked="true">
|
||||
<action on="Load">this.checked = Engine.Renderer_GetWaterCoastalWavesEnabled();</action>
|
||||
<action on="Press">Engine.Renderer_SetWaterCoastalWavesEnabled(this.checked);</action>
|
||||
</object>
|
||||
|
||||
<!-- Settings / Shadows -->
|
||||
<object size="0 210 100%-80 235" type="text" style="ModernRightLabelText" ghost="true">Water - Use Surface Shadows</object>
|
||||
<object size="0 210 100%-80 235" type="text" style="ModernRightLabelText" ghost="true">
|
||||
<translatableAttribute id="caption">Water - Use Surface Shadows</translatableAttribute>
|
||||
</object>
|
||||
<object name="waterShadowsCheckbox" size="100%-56 215 100%-30 240" type="checkbox" style="ModernTickBox" checked="true">
|
||||
<action on="Load">if (Engine.Renderer_GetWaterShadowEnabled()) this.checked = true; else this.checked = false;</action>
|
||||
<action on="Press">Engine.Renderer_SetWaterShadowEnabled(this.checked);</action>
|
||||
</object>
|
||||
|
||||
<!-- Settings / Particles -->
|
||||
<object size="0 235 100%-80 260" type="text" style="ModernRightLabelText" ghost="true">Enable Particles</object>
|
||||
<object size="0 235 100%-80 260" type="text" style="ModernRightLabelText" ghost="true">
|
||||
<translatableAttribute id="caption">Enable Particles</translatableAttribute>
|
||||
</object>
|
||||
<object name="particlesCheckbox" size="100%-56 240 100%-30 265" type="checkbox" style="ModernTickBox" checked="true">
|
||||
<action on="Load">this.checked = Engine.Renderer_GetParticlesEnabled();</action>
|
||||
<action on="Press">Engine.Renderer_SetParticlesEnabled(this.checked);</action>
|
||||
</object>
|
||||
|
||||
<!-- Settings / Unit Silhouettes -->
|
||||
<object size="0 260 100%-80 285" type="text" style="ModernRightLabelText" ghost="true">Enable Unit Silhouettes</object>
|
||||
<object size="0 260 100%-80 285" type="text" style="ModernRightLabelText" ghost="true">
|
||||
<translatableAttribute id="caption">Enable Unit Silhouettes</translatableAttribute>
|
||||
</object>
|
||||
<object name="silhouettesCheckbox" size="100%-56 265 100%-30 290" type="checkbox" style="ModernTickBox" checked="true">
|
||||
<action on="Load">this.checked = Engine.Renderer_GetSilhouettesEnabled();</action>
|
||||
<action on="Press">Engine.Renderer_SetSilhouettesEnabled(this.checked);</action>
|
||||
</object>
|
||||
|
||||
<!-- Settings / Music-->
|
||||
<object size="0 285 100%-80 310" type="text" style="ModernRightLabelText" ghost="true">Enable Music</object>
|
||||
<object size="0 285 100%-80 310" type="text" style="ModernRightLabelText" ghost="true">
|
||||
<translatableAttribute id="caption">Enable Music</translatableAttribute>
|
||||
</object>
|
||||
<object name="musicCheckbox" size="100%-56 290 100%-30 315" type="checkbox" style="ModernTickBox" checked="true">
|
||||
<action on="Press">if (this.checked) global.music.start(); else global.music.stop();</action>
|
||||
</object>
|
||||
|
||||
<!-- Settings / Dev Overlay -->
|
||||
<object size="0 310 100%-80 335" type="text" style="ModernRightLabelText" ghost="true">Developer Overlay</object>
|
||||
<object size="0 310 100%-80 335" type="text" style="ModernRightLabelText" ghost="true">
|
||||
<translatableAttribute id="caption">Developer Overlay</translatableAttribute>
|
||||
</object>
|
||||
<object name="developerOverlayCheckbox" size="100%-56 315 100%-30 340" type="checkbox" style="ModernTickBox" checked="false">
|
||||
<action on="Load"><![CDATA[
|
||||
if (Engine.IsRankedGame())
|
||||
@ -625,31 +705,36 @@
|
||||
size="10 0 45% 100%"
|
||||
>
|
||||
<!-- Food -->
|
||||
<object name="food" size="0 0 90 100%" type="image" style="resourceCounter" tooltip="Food" tooltip_style="sessionToolTipBold">
|
||||
<object name="food" size="0 0 90 100%" type="image" style="resourceCounter" tooltip_style="sessionToolTipBold">
|
||||
<translatableAttribute id="tooltip">Food</translatableAttribute>
|
||||
<object size="0 -4 40 36" type="image" sprite="stretched:session/icons/resources/food.png" ghost="true"/>
|
||||
<object size="32 0 100% 100%-2" type="text" style="resourceText" name="resourceFood"/>
|
||||
</object>
|
||||
|
||||
<!-- Wood -->
|
||||
<object name="wood" size="90 0 180 100%" type="image" style="resourceCounter" tooltip="Wood" tooltip_style="sessionToolTipBold">
|
||||
<object name="wood" size="90 0 180 100%" type="image" style="resourceCounter" tooltip_style="sessionToolTipBold">
|
||||
<translatableAttribute id="tooltip">Wood</translatableAttribute>
|
||||
<object size="0 -4 40 36" type="image" sprite="stretched:session/icons/resources/wood.png" ghost="true"/>
|
||||
<object size="32 0 100% 100%-2" type="text" style="resourceText" name="resourceWood"/>
|
||||
</object>
|
||||
|
||||
<!-- Stone -->
|
||||
<object name="stone" size="180 0 270 100%" type="image" style="resourceCounter" tooltip="Stone" tooltip_style="sessionToolTipBold">
|
||||
<object name="stone" size="180 0 270 100%" type="image" style="resourceCounter" tooltip_style="sessionToolTipBold">
|
||||
<translatableAttribute id="tooltip">Stone</translatableAttribute>
|
||||
<object size="0 -4 40 36" type="image" sprite="stretched:session/icons/resources/stone.png" ghost="true"/>
|
||||
<object size="32 0 100% 100%-2" type="text" style="resourceText" name="resourceStone"/>
|
||||
</object>
|
||||
|
||||
<!-- Metal -->
|
||||
<object name="metal" size="270 0 360 100%" type="image" style="resourceCounter" tooltip="Metal" tooltip_style="sessionToolTipBold">
|
||||
<object name="metal" size="270 0 360 100%" type="image" style="resourceCounter" tooltip_style="sessionToolTipBold">
|
||||
<translatableAttribute id="tooltip">Metal</translatableAttribute>
|
||||
<object size="0 -4 40 36" type="image" sprite="stretched:session/icons/resources/metal.png" ghost="true"/>
|
||||
<object size="32 0 100% 100%-2" type="text" style="resourceText" name="resourceMetal"/>
|
||||
</object>
|
||||
|
||||
<!-- Population -->
|
||||
<object name="population" size="360 0 450 100%" type="image" style="resourceCounter" tooltip="Population (current / limit)" tooltip_style="sessionToolTipBold">
|
||||
<object name="population" size="360 0 450 100%" type="image" style="resourceCounter" tooltip_style="sessionToolTipBold">
|
||||
<translatableAttribute id="tooltip">Population (current / limit)</translatableAttribute>
|
||||
<object size="0 -4 40 34" type="image" sprite="stretched:session/icons/resources/population.png" ghost="true"/>
|
||||
<object size="32 0 100% 100%-2" type="text" style="resourceText" name="resourcePop"/>
|
||||
</object>
|
||||
@ -661,8 +746,9 @@
|
||||
<object size="50%-48 -26 50%+48 70" name="civIcon" type="image" tooltip_style="sessionToolTipBold"/>
|
||||
|
||||
<!-- Switch the view perspective to another player's (largely for AI development) -->
|
||||
<object size="50%+50 5 50%+150 100%-5" name="viewPlayer" type="dropdown" hidden="true" style="ModernDropDown" tooltip_style="sessionToolTipBold" tooltip="Choose player to view">
|
||||
<action on="SelectionChange">selectViewPlayer(this.selected);</action>
|
||||
<object size="50%+50 5 50%+150 100%-5" name="viewPlayer" type="dropdown" hidden="true" style="ModernDropDown" tooltip_style="sessionToolTipBold">
|
||||
<translatableAttribute id="tooltip">Choose player to view</translatableAttribute>
|
||||
<action on="SelectionChange">selectViewPlayer(this.selected);</action>
|
||||
</object>
|
||||
|
||||
<!-- ================================ ================================ -->
|
||||
@ -683,12 +769,13 @@
|
||||
|
||||
<!-- Displays Alpha name and number -->
|
||||
<object size="50%+48 0 100%-226 100%" name="alphaLabel" type="text" style="ModernLabelText" text_valign="top" ghost="true">
|
||||
ALPHA XV : Osiris<!-- IMPORTANT: remember to update pregame/mainmenu.xml in sync with this -->
|
||||
<!-- IMPORTANT: remember to update pregame/mainmenu.xml in sync with this: -->
|
||||
<translatableAttribute id="caption">ALPHA XV : Osiris</translatableAttribute>
|
||||
|
||||
<!-- Displays build date and revision number-->
|
||||
<object size="50%-128 0 50%+128 100%-2" name="Engine.BuildTimeLabel" type="text" style="BuildNameText" ghost="true">
|
||||
<action on="Load">this.caption = Engine.BuildTime(0) + " (" + Engine.BuildTime(2) + ")"</action>
|
||||
</object>
|
||||
<!-- Displays build date and revision number-->
|
||||
<object size="50%-128 0 50%+128 100%-2" name="buildTimeLabel" type="text" style="BuildNameText" ghost="true">
|
||||
<action on="Load">this.caption = getBuildString()</action>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<!-- ================================ ================================ -->
|
||||
@ -699,16 +786,18 @@
|
||||
size="100%-258 4 100%-230 32"
|
||||
style="iconButton"
|
||||
tooltip_style="sessionToolTip"
|
||||
tooltip="Game speed"
|
||||
>
|
||||
>
|
||||
<translatableAttribute id="tooltip">Game speed</translatableAttribute>
|
||||
<object size="5 5 100%-5 100%-5" type="image" sprite="stretched:session/icons/resources/time_small.png" ghost="true"/>
|
||||
<action on="Press">
|
||||
toggleGameSpeed();
|
||||
</action>
|
||||
</object>
|
||||
|
||||
<object size="100%-380 40 100%-230 65" name="gameSpeed" type="dropdown" buffer_zone="5" style="ModernDropDown" hidden="true" tooltip="Choose game speed" tooltip_style="sessionToolTip"/>
|
||||
|
||||
<object size="100%-380 40 100%-230 65" name="gameSpeed" type="dropdown" buffer_zone="5" style="ModernDropDown" hidden="true" tooltip_style="sessionToolTip">
|
||||
<translatableAttribute id="tooltip">Choose game speed</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<!-- ================================ ================================ -->
|
||||
<!-- Diplomacy Button -->
|
||||
<!-- ================================ ================================ -->
|
||||
@ -717,8 +806,8 @@
|
||||
size="100%-226 4 100%-198 32"
|
||||
style="iconButton"
|
||||
tooltip_style="sessionToolTip"
|
||||
tooltip="Diplomacy"
|
||||
>
|
||||
>
|
||||
<translatableAttribute id="tooltip">Diplomacy</translatableAttribute>
|
||||
<!-- TODO make the button less ugly -->
|
||||
<object size="0 0 100% 100%" name="diplomacyButtonImage" type="image" sprite="stretched:session/icons/diplomacy.png" ghost="true"/>
|
||||
<action on="Press">
|
||||
@ -734,13 +823,13 @@
|
||||
size="100%-194 4 100%-166 32"
|
||||
style="iconButton"
|
||||
tooltip_style="sessionToolTip"
|
||||
tooltip="Trade"
|
||||
>
|
||||
<!-- TODO make the button less ugly -->
|
||||
<object size="0 0 100% 100%" name="tradeButtonImage" type="image" sprite="stretched:session/icons/economics.png" ghost="true"/>
|
||||
<action on="Press">
|
||||
toggleTrade();
|
||||
</action>
|
||||
<!-- TODO make the button less ugly -->
|
||||
<object size="0 0 100% 100%" name="tradeButtonImage" type="image" sprite="stretched:session/icons/economics.png" ghost="true"/>
|
||||
<translatableAttribute id="tooltip">Trade</translatableAttribute>
|
||||
<action on="Press">
|
||||
toggleTrade();
|
||||
</action>
|
||||
</object>
|
||||
|
||||
<!-- ================================ ================================ -->
|
||||
@ -758,7 +847,9 @@
|
||||
them on top of the main menu button -->
|
||||
<object size="0 -4 100% 0" type="image" sprite="horizontalThinBorder" ghost="true"/>
|
||||
|
||||
<object size="50%-32 50%-16 50%+32 50%+16" type="image" sprite="menuButton" ghost="true">MENU</object>
|
||||
<object size="50%-32 50%-16 50%+32 50%+16" type="image" sprite="menuButton" ghost="true">
|
||||
<translatableAttribute id="caption">MENU</translatableAttribute>
|
||||
</object>
|
||||
<action on="Press">
|
||||
toggleMenu();
|
||||
</action>
|
||||
@ -783,7 +874,7 @@
|
||||
size="0 0 100% 28"
|
||||
tooltip_style="sessionToolTip"
|
||||
>
|
||||
Manual
|
||||
<translatableAttribute id="caption">Manual</translatableAttribute>
|
||||
<action on="Press">openManual();</action>
|
||||
</object>
|
||||
|
||||
@ -794,7 +885,7 @@
|
||||
size="0 32 100% 60"
|
||||
tooltip_style="sessionToolTip"
|
||||
>
|
||||
Chat
|
||||
<translatableAttribute id="caption">Chat</translatableAttribute>
|
||||
<action on="Press">chatMenuButton();</action>
|
||||
</object>
|
||||
|
||||
@ -805,7 +896,7 @@
|
||||
size="0 64 100% 92"
|
||||
tooltip_style="sessionToolTip"
|
||||
>
|
||||
Save
|
||||
<translatableAttribute id="caption">Save</translatableAttribute>
|
||||
<action on="Press">
|
||||
openSave();
|
||||
</action>
|
||||
@ -818,7 +909,7 @@
|
||||
size="0 96 100% 124"
|
||||
tooltip_style="sessionToolTip"
|
||||
>
|
||||
Settings
|
||||
<translatableAttribute id="caption">Settings</translatableAttribute>
|
||||
<action on="Press">settingsMenuButton();</action>
|
||||
</object>
|
||||
|
||||
@ -829,7 +920,9 @@
|
||||
size="0 128 100% 156"
|
||||
tooltip_style="sessionToolTip"
|
||||
>
|
||||
<object name="pauseButtonText" type="text" style="CenteredButtonText" ghost="true">Pause</object>
|
||||
<object name="pauseButtonText" type="text" style="CenteredButtonText" ghost="true">
|
||||
<translatableAttribute id="caption">Pause</translatableAttribute>
|
||||
</object>
|
||||
<action on="Press">togglePause();</action>
|
||||
</object>
|
||||
|
||||
@ -840,7 +933,7 @@
|
||||
size="0 160 100% 188"
|
||||
tooltip_style="sessionToolTip"
|
||||
>
|
||||
Resign
|
||||
<translatableAttribute id="caption">Resign</translatableAttribute>
|
||||
<action on="Press">resignMenuButton();</action>
|
||||
</object>
|
||||
|
||||
@ -851,7 +944,7 @@
|
||||
size="0 192 100% 220"
|
||||
tooltip_style="sessionToolTip"
|
||||
>
|
||||
Exit
|
||||
<translatableAttribute id="caption">Exit</translatableAttribute>
|
||||
<action on="Press">exitMenuButton();</action>
|
||||
</object>
|
||||
</object>
|
||||
@ -870,14 +963,14 @@
|
||||
<!-- ================================ ================================ -->
|
||||
<!-- Hero Selection -->
|
||||
<!-- ================================ ================================ -->
|
||||
<object
|
||||
<object
|
||||
name="unitHeroPanel"
|
||||
size="0 36 50 93"
|
||||
hidden="true"
|
||||
>
|
||||
<object name="unitHeroButton" size="0 0 50 50" type="button" style="iconButton"
|
||||
tooltip_style="sessionToolTip" tooltip="Attack and Armor"
|
||||
>
|
||||
tooltip_style="sessionToolTip">
|
||||
<translatableAttribute id="tooltip">Attack and Armor</translatableAttribute>
|
||||
<object name="unitHeroImage" size="5 5 100%-5 100%-5" type="image" ghost="true"/>
|
||||
<object name="heroHitOverlay" hidden="true" type="image" ghost="true" size="5 5 100%-5 100%-5"/>
|
||||
</object>
|
||||
@ -900,9 +993,8 @@
|
||||
size="0% 50%-216 0%+36 50%+144"
|
||||
>
|
||||
<repeat count="10">
|
||||
<object name="unitGroupButton[n]" size="0 0 36 36" type="button" hidden="false" style="iconButton" tooltip_style="sessionToolTipBottomBold"
|
||||
tooltip="Click to select grouped units, double-click to focus the grouped units and right-click to disband the group."
|
||||
>
|
||||
<object name="unitGroupButton[n]" size="0 0 36 36" type="button" hidden="false" style="iconButton" tooltip_style="sessionToolTipBottomBold">
|
||||
<translatableAttribute id="tooltip">Click to select grouped units, double-click to focus the grouped units and right-click to disband the group.</translatableAttribute>
|
||||
<object name="unitGroupIcon[n]" size="3 3 33 33" type="image" sprite="groupsIcon" ghost="true"/>
|
||||
<object name="unitGroupLabel[n]" type="text" style="largeCenteredOutlinedText" ghost="true"/>
|
||||
</object>
|
||||
@ -939,10 +1031,10 @@
|
||||
<object size="100%-80 100%-80 100%-5 100%-5">
|
||||
<!-- TODO: We should disable this button if there are no idle workers. -->
|
||||
<object type="button"
|
||||
tooltip="Find idle worker"
|
||||
tooltip_style="sessionToolTip"
|
||||
hotkey="selection.idleworker"
|
||||
>
|
||||
<translatableAttribute id="tooltip">Find idle worker</translatableAttribute>
|
||||
<action on="Press">findIdleUnit(["Female", "Trade", "FishingBoat", "CitizenSoldier", "Healer"]);</action>
|
||||
<action on="MouseEnter">Engine.GetGUIObjectByName("idleOverlay").sprite = "stretched:session/minimap-idle-highlight.png";</action>
|
||||
<action on="MouseLeave">Engine.GetGUIObjectByName("idleOverlay").sprite = "stretched:session/minimap-idle.png";</action>
|
||||
@ -993,7 +1085,9 @@
|
||||
size="6 36 100% 100%"
|
||||
hidden="true"
|
||||
>
|
||||
<object ghost="true" style="resourceText" type="text" size="0 0 100% 20">Exchange resources:</object>
|
||||
<object ghost="true" style="resourceText" type="text" size="0 0 100% 20">
|
||||
<translatableAttribute id="tooltip">Exchange resources:</translatableAttribute>
|
||||
</object>
|
||||
<object size="0 32 100% 78">
|
||||
<repeat count="4">
|
||||
<object name="unitBarterSellButton[n]" style="iconButton" type="button" size="0 0 46 46" tooltip_style="sessionToolTipBottomBold">
|
||||
@ -1050,7 +1144,9 @@
|
||||
<object size="0 8 100% 60" type="image" sprite="edgedPanelShader">
|
||||
<!-- Health bar -->
|
||||
<object size="88 0 100% 24" name="healthSection">
|
||||
<object size="0 0 100% 16" name="healthLabel" type="text" style="StatsTextLeft" ghost="true">Health:</object>
|
||||
<object size="0 0 100% 16" name="healthLabel" type="text" style="StatsTextLeft" ghost="true">
|
||||
<translatableAttribute id="tooltip">Health:</translatableAttribute>
|
||||
</object>
|
||||
<object size="0 0 100% 16" name="healthStats" type="text" style="StatsTextRight" ghost="true"/>
|
||||
<object size="1 16 100% 23" name="health" type="image">
|
||||
<object type="image" sprite="barBorder" ghost="true" size="-1 -1 100%+1 100%+1"/>
|
||||
@ -1062,7 +1158,9 @@
|
||||
|
||||
<!-- Stamina bar -->
|
||||
<object size="88 28 100% 52" name="staminaSection">
|
||||
<object size="0 0 100% 16" name="staminaLabel" type="text" style="StatsTextLeft" ghost="true">Stamina:</object>
|
||||
<object size="0 0 100% 16" name="staminaLabel" type="text" style="StatsTextLeft" ghost="true">
|
||||
<translatableAttribute id="tooltip">Stamina:</translatableAttribute>
|
||||
</object>
|
||||
<object size="0 0 100% 16" name="staminaStats" type="text" style="StatsTextRight" ghost="true"/>
|
||||
<object size="1 16 100% 23" name="stamina" type="image">
|
||||
<object type="image" sprite="barBorder" ghost="true" size="-1 -1 100%+1 100%+1"/>
|
||||
@ -1087,7 +1185,9 @@
|
||||
|
||||
<object size="0 60 100% 96" type="image" sprite="edgedPanelShader">
|
||||
<!-- Attack and Armor -->
|
||||
<object size="90 -2 126 34" name="attackAndArmorStats" type="image" sprite="stretched:session/icons/stances/defensive.png" tooltip="Attack and Armor" tooltip_style="sessionToolTip"/>
|
||||
<object size="90 -2 126 34" name="attackAndArmorStats" type="image" sprite="stretched:session/icons/stances/defensive.png" tooltip_style="sessionToolTip">
|
||||
<translatableAttribute id="tooltip">Attack and Armor</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<!-- Resource carrying icon/counter -->
|
||||
<!-- Used also for number of gatherers/builders -->
|
||||
@ -1100,14 +1200,17 @@
|
||||
<object size="1 1 100%-1 100%-1" type="image" name="icon" ghost="true"/>
|
||||
|
||||
<!-- Experience bar -->
|
||||
<object size="2 2 6 100%-2" type="image" name="experience" tooltip="Experience" tooltip_style="sessionToolTip">
|
||||
<object type="image" sprite="barBorder" ghost="true" size="-1 -1 100%+1 100%+1"/>
|
||||
<object type="image" sprite="experienceBackground" ghost="true"/>
|
||||
<object type="image" sprite="experienceForeground" ghost="true" name="experienceBar"/>
|
||||
<object type="image" sprite="statsBarShaderVertical" ghost="true"/>
|
||||
<object size="2 2 6 100%-2" type="image" name="experience" tooltip_style="sessionToolTip">
|
||||
<translatableAttribute id="tooltip">Experience</translatableAttribute>
|
||||
<object type="image" sprite="barBorder" ghost="true" size="-1 -1 100%+1 100%+1"/>
|
||||
<object type="image" sprite="experienceBackground" ghost="true"/>
|
||||
<object type="image" sprite="experienceForeground" ghost="true" name="experienceBar"/>
|
||||
<object type="image" sprite="statsBarShaderVertical" ghost="true"/>
|
||||
</object>
|
||||
|
||||
<object z="20" size="4 4 20 20" name="rankIcon" type="image" tooltip="Rank" tooltip_style="sessionToolTip"/>
|
||||
<object z="20" size="4 4 20 20" name="rankIcon" type="image" tooltip_style="sessionToolTip">
|
||||
<translatableAttribute id="tooltip">Rank</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
@ -1165,7 +1268,8 @@
|
||||
<!-- Stats Bars -->
|
||||
<object size= "100%-38 50 100%-18 100%-44" type="image" tooltip_style="sessionToolTip">
|
||||
<!-- Health bar -->
|
||||
<object size="4 0 11 100%" type="image" name="healthMultiple" tooltip="Hitpoints" tooltip_style="sessionToolTip">
|
||||
<object size="4 0 11 100%" type="image" name="healthMultiple" tooltip_style="sessionToolTip">
|
||||
<translatableAttribute id="tooltip">Hitpoints</translatableAttribute>
|
||||
<object type="image" sprite="barBorder" ghost="true" size="-1 -1 100%+1 100%+1"/>
|
||||
<object type="image" sprite="healthBackground" ghost="true"/>
|
||||
<object type="image" sprite="healthForeground" ghost="true" name="healthBarMultiple"/>
|
||||
@ -1173,7 +1277,8 @@
|
||||
</object>
|
||||
|
||||
<!-- Stamina bar -->
|
||||
<object size="15 0 22 100%" type="image" name="staminaMultiple" tooltip="Stamina" tooltip_style="sessionToolTipBold">
|
||||
<object size="15 0 22 100%" type="image" name="staminaMultiple" tooltip_style="sessionToolTipBold">
|
||||
<translatableAttribute id="tooltip">Stamina</translatableAttribute>
|
||||
<object type="image" sprite="barBorder" ghost="true" size="-1 -1 100%+1 100%+1"/>
|
||||
<object type="image" sprite="staminaBackground" ghost="true"/>
|
||||
<object type="image" sprite="staminaForeground" ghost="true" name="staminaBarMultiple"/>
|
||||
@ -1336,7 +1441,9 @@
|
||||
size="50%-84 50%+128 50%+84 50%+160"
|
||||
tooltip_style="sessionToolTip"
|
||||
>
|
||||
<object size="0 0 100% 100%" type="text" style="CenteredButtonText" name="disconnectedExitButtonText" ghost="true">Exit</object>
|
||||
<object size="0 0 100% 100%" type="text" style="CenteredButtonText" name="disconnectedExitButtonText" ghost="true">
|
||||
<translatableAttribute id="caption">Exit</translatableAttribute>
|
||||
</object>
|
||||
<action on="Press">leaveGame()</action>
|
||||
</object>
|
||||
</object>
|
||||
|
@ -27,7 +27,7 @@ const BARTER_RESOURCES = ["food", "wood", "stone", "metal"];
|
||||
const BARTER_ACTIONS = ["Sell", "Buy"];
|
||||
|
||||
// Gate constants
|
||||
const GATE_ACTIONS = ["Lock", "Unlock"];
|
||||
const GATE_ACTIONS = ["lock", "unlock"];
|
||||
|
||||
// The number of currently visible buttons (used to optimise showing/hiding)
|
||||
var g_unitPanelButtons = {"Selection": 0, "Queue": 0, "Formation": 0, "Garrison": 0, "Training": 0, "Research": 0, "Barter": 0, "Trading": 0, "Construction": 0, "Command": 0, "Stance": 0, "Gate": 0, "Pack": 0};
|
||||
@ -146,15 +146,15 @@ function formatLimitString(trainEntLimit, trainEntCount, trainEntLimitChangers)
|
||||
{
|
||||
if (trainEntLimit == undefined)
|
||||
return "";
|
||||
var text = "\n\nCurrent Count: " + trainEntCount + ", Limit: " + trainEntLimit + ".";
|
||||
var text = "\n\n" + sprintf(translate("Current Count: %(count)s, Limit: %(limit)s."), { count: trainEntCount, limit: trainEntLimit });
|
||||
if (trainEntCount >= trainEntLimit)
|
||||
text = "[color=\"red\"]" + text + "[/color]";
|
||||
for (var c in trainEntLimitChangers)
|
||||
{
|
||||
if (trainEntLimitChangers[c] > 0)
|
||||
text += "\n" + c + " enlarges the limit with " + trainEntLimitChangers[c] + ".";
|
||||
text += "\n" + sprintf("%(changer)s enlarges the limit with %(change)s.", { changer: c, change: trainEntLimitChangers[c] });
|
||||
else if (trainEntLimitChangers[c] < 0)
|
||||
text += "\n" + c + " lessens the limit with " + (-trainEntLimitChangers[c]) + ".";
|
||||
text += "\n" + sprintf("%(changer)s lessens the limit with %(change)s.", { changer: c, change: (-trainEntLimitChangers[c]) });
|
||||
}
|
||||
return text;
|
||||
}
|
||||
@ -181,25 +181,70 @@ function formatBatchTrainingString(buildingsCountToTrainFullBatch, fullBatchSize
|
||||
if (buildingsCountToTrainFullBatch > 0)
|
||||
{
|
||||
if (buildingsCountToTrainFullBatch > 1)
|
||||
fullBatchesString += buildingsCountToTrainFullBatch + "*";
|
||||
fullBatchesString += fullBatchSize;
|
||||
fullBatchesString = sprintf(translate("%(buildings)s*%(batchSize)s"), {
|
||||
buildings: buildingsCountToTrainFullBatch,
|
||||
batchSize: fullBatchSize
|
||||
});
|
||||
else
|
||||
fullBatchesString = fullBatchSize;
|
||||
}
|
||||
var remainderBatchString = remainderBatch > 0 ? remainderBatch : "";
|
||||
var batchDetailsString = "";
|
||||
var action = "[font=\"serif-bold-13\"]" + translate("Shift-click") + "[/font][font=\"serif-13\"]"
|
||||
|
||||
// We need to display the batch details part if there is either more than
|
||||
// one building with full batch or one building with the full batch and
|
||||
// another with a partial batch
|
||||
if (buildingsCountToTrainFullBatch > 1 ||
|
||||
(buildingsCountToTrainFullBatch == 1 && remainderBatch > 0))
|
||||
{
|
||||
batchDetailsString += " (" + fullBatchesString;
|
||||
if (remainderBatchString != "")
|
||||
batchDetailsString += " + " + remainderBatchString;
|
||||
batchDetailsString += ")";
|
||||
if (remainderBatch > 0)
|
||||
return "\n[font=\"serif-13\"]" + sprintf(translate("%(action)s to train %(number)s (%(fullBatch)s + %(remainderBatch)s)."), {
|
||||
action: action,
|
||||
number: totalBatchTrainingCount,
|
||||
fullBatch: fullBatchesString,
|
||||
remainderBatch: remainderBatch
|
||||
}) + "[/font]";
|
||||
|
||||
return "\n[font=\"serif-13\"]" + sprintf(translate("%(action)s to train %(number)s (%(fullBatch)s)."), {
|
||||
action: action,
|
||||
number: totalBatchTrainingCount,
|
||||
fullBatch: fullBatchesString
|
||||
}) + "[/font]";
|
||||
}
|
||||
|
||||
return "\n[font=\"serif-bold-13\"]Shift-click[/font][font=\"serif-13\"] to train "
|
||||
+ totalBatchTrainingCount + batchDetailsString + ".[/font]";
|
||||
return "\n[font=\"serif-13\"]" + sprintf(translate("%(action)s to train %(number)s."), {
|
||||
action: action,
|
||||
number: totalBatchTrainingCount
|
||||
}) + "[/font]";
|
||||
}
|
||||
|
||||
function getStanceDisplayName(name)
|
||||
{
|
||||
var displayName;
|
||||
switch(name)
|
||||
{
|
||||
case "violent":
|
||||
displayName = translate("Violent");
|
||||
break;
|
||||
case "aggressive":
|
||||
displayName = translate("Aggressive");
|
||||
break;
|
||||
case "passive":
|
||||
displayName = translate("Passive");
|
||||
break;
|
||||
case "defensive":
|
||||
displayName = translate("Defensive");
|
||||
break;
|
||||
case "standground":
|
||||
displayName = translate("Standground");
|
||||
break;
|
||||
default:
|
||||
warn(sprintf("Internationalization: Unexpected stance found with code ‘%(stance)s’. This stance must be internationalized.", { stance: name }));
|
||||
displayName = name;
|
||||
break;
|
||||
}
|
||||
return displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -393,7 +438,7 @@ function setupUnitPanel(guiName, usedPanels, unitEntState, playerState, items, c
|
||||
case QUEUE:
|
||||
var tooltip = getEntityNames(template);
|
||||
if (item.neededSlots)
|
||||
tooltip += "\n[color=\"red\"]Insufficient population capacity:\n[/color]"+getCostComponentDisplayName("population")+" "+item.neededSlots;
|
||||
tooltip += "\n[color=\"red\"]" + translate("Insufficient population capacity:") + "\n[/color]" + sprintf(translate("%(population)s %(neededSlots)s"), { population: getCostComponentDisplayName("population"), neededSlots: item.neededSlots });
|
||||
|
||||
var progress = Math.round(item.progress*100) + "%";
|
||||
Engine.GetGUIObjectByName("unit"+guiName+"Count["+i+"]").caption = (item.count > 1 ? item.count : "");
|
||||
@ -411,7 +456,7 @@ function setupUnitPanel(guiName, usedPanels, unitEntState, playerState, items, c
|
||||
|
||||
case GARRISON:
|
||||
var name = getEntityNames(template);
|
||||
var tooltip = "Unload " + name + "\nSingle-click to unload 1. Shift-click to unload all of this type.";
|
||||
var tooltip = sprintf(translate("Unload %(name)s"), { name: name })+ "\n" + translate("Single-click to unload 1. Shift-click to unload all of this type.");
|
||||
var count = garrisonGroups.getCount(item);
|
||||
Engine.GetGUIObjectByName("unit"+guiName+"Count["+i+"]").caption = (count > 1 ? count : "");
|
||||
break;
|
||||
@ -447,7 +492,7 @@ function setupUnitPanel(guiName, usedPanels, unitEntState, playerState, items, c
|
||||
break;
|
||||
|
||||
case STANCE:
|
||||
var tooltip = toTitleCase(item);
|
||||
var tooltip = getStanceDisplayName(item);
|
||||
break;
|
||||
|
||||
case TRAINING:
|
||||
@ -580,7 +625,7 @@ function setupUnitPanel(guiName, usedPanels, unitEntState, playerState, items, c
|
||||
{
|
||||
var formationInfo = Engine.GuiInterfaceCall("GetFormationInfoFromTemplate", {"templateName": item});
|
||||
|
||||
button.tooltip = formationInfo.name;
|
||||
button.tooltip = translate(formationInfo.name);
|
||||
var formationOk = canMoveSelectionIntoFormation(item);
|
||||
var grayscale = "";
|
||||
button.enabled = formationOk;
|
||||
@ -589,8 +634,8 @@ function setupUnitPanel(guiName, usedPanels, unitEntState, playerState, items, c
|
||||
grayscale = "grayscale:";
|
||||
|
||||
// Display a meaningful tooltip why the formation is disabled
|
||||
button.tooltip += " (disabled)"+formationInfo.tooltip;
|
||||
}
|
||||
button.tooltip += "\n" + "[color=\"red\"]" + translate(formationInfo.tooltip) + "[/color]";
|
||||
}
|
||||
|
||||
var formationSelected = Engine.GuiInterfaceCall("IsFormationSelected", {
|
||||
"ents": g_Selection.toList(),
|
||||
@ -621,7 +666,7 @@ function setupUnitPanel(guiName, usedPanels, unitEntState, playerState, items, c
|
||||
// If already a gate, show locking actions
|
||||
if (item.gate)
|
||||
{
|
||||
gateIcon = "icons/lock_" + GATE_ACTIONS[item.locked ? 0 : 1].toLowerCase() + "ed.png";
|
||||
gateIcon = "icons/lock_" + GATE_ACTIONS[item.locked ? 0 : 1] + "ed.png";
|
||||
guiSelection.hidden = item.gate.locked === undefined ? false : item.gate.locked != item.locked;
|
||||
}
|
||||
// otherwise show gate upgrade icon
|
||||
@ -660,7 +705,7 @@ function setupUnitPanel(guiName, usedPanels, unitEntState, playerState, items, c
|
||||
{
|
||||
button.enabled = false;
|
||||
var techName = getEntityNames(GetTechnologyData(template.requiredTechnology));
|
||||
button.tooltip += "\nRequires " + techName;
|
||||
button.tooltip += "\n" + sprintf(translate("Requires %(technology)s"), { technology: techName });
|
||||
grayscale = "grayscale:";
|
||||
affordableMask.hidden = false;
|
||||
affordableMask.sprite = "colour: 0 0 0 127";
|
||||
@ -905,7 +950,7 @@ function setupUnitTradingPanel(usedPanels, unitEntState, selection)
|
||||
var selectRequiredGoodsData = { "entities": selection, "requiredGoods": resource };
|
||||
button.onpress = (function(e){ return function() { selectRequiredGoods(e); } })(selectRequiredGoodsData);
|
||||
button.enabled = true;
|
||||
button.tooltip = "Set/unset " + resource + " as forced trading goods.";
|
||||
button.tooltip = sprintf(translate("Set/unset %(resource)s as forced trading goods."), { resource: resource });
|
||||
var icon = Engine.GetGUIObjectByName("unitTradingIcon["+i+"]");
|
||||
var selected = Engine.GetGUIObjectByName("unitTradingSelection["+i+"]");
|
||||
selected.hidden = !(resource == requiredGoods);
|
||||
@ -1091,11 +1136,37 @@ function updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, s
|
||||
var gateTemplate = getWallGateTemplate(state.id);
|
||||
if (gateTemplate)
|
||||
{
|
||||
var wallName = GetTemplateData(state.template).name.generic;
|
||||
var gateName = GetTemplateData(gateTemplate).name.generic;
|
||||
var wallName = GetTemplateDataWithoutLocalization(state.template).name.generic;
|
||||
var gateName = GetTemplateDataWithoutLocalization(gateTemplate).name.generic;
|
||||
var tooltipString;
|
||||
|
||||
// For internationalization purposes, when possible, available combinations should be provided
|
||||
// as placeholder-free strings as below.
|
||||
//
|
||||
// The placeholder implementation is provided only so that undetected new combinations of wall
|
||||
// and gate names are not simply printed in English, but as close to a perfect translation as
|
||||
// possible.
|
||||
|
||||
if (wallName === "Wooden Wall" && gateName === "Wooden Gate")
|
||||
{
|
||||
tooltipString = translate("Convert Wooden Wall into Wooden Gate");
|
||||
}
|
||||
else if (wallName === "Stone Wall" && gateName === "City Gate")
|
||||
{
|
||||
tooltipString = translate("Convert Stone Wall into City Gate");
|
||||
}
|
||||
else if (wallName === "Siege Wall" && gateName === "Siege Wall Gate")
|
||||
{
|
||||
tooltipString = translate("Convert Siege Wall into Siege Wall Gate");
|
||||
}
|
||||
else
|
||||
{
|
||||
warn(sprintf("Internationalization: Unexpected combination of ‘%(localizedWall)s’ (%(englishWall)s) and ‘%(localizedGate)s’ (%(englishGate)s). This combination of wall and gate types must be internationalized.", { localizedWall: translate(wallName), englishWall: wallName, localizedGate: translate(gateName), englishGate: gateName }));
|
||||
tooltipString = sprintf(translate("Convert %(wall)s into %(gate)s"), { wall: translate(wallName), gate: translate(gateName) });
|
||||
}
|
||||
|
||||
walls.push({
|
||||
"tooltip": "Convert " + wallName + " to " + gateName,
|
||||
"tooltip": tooltipString,
|
||||
"template": gateTemplate,
|
||||
"callback": function (item) { transformWallToGate(item.template); }
|
||||
});
|
||||
@ -1105,13 +1176,20 @@ function updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, s
|
||||
longWallTypes[state.template] = true;
|
||||
}
|
||||
else if (state.gate && !gates.length)
|
||||
for (var j = 0; j < GATE_ACTIONS.length; ++j)
|
||||
gates.push({
|
||||
"gate": state.gate,
|
||||
"tooltip": GATE_ACTIONS[j] + " gate",
|
||||
"locked": j == 0,
|
||||
"callback": function (item) { lockGate(item.locked); }
|
||||
});
|
||||
{
|
||||
gates.push({
|
||||
"gate": state.gate,
|
||||
"tooltip": translate("Lock Gate"),
|
||||
"locked": true,
|
||||
"callback": function (item) { lockGate(item.locked); }
|
||||
});
|
||||
gates.push({
|
||||
"gate": state.gate,
|
||||
"tooltip": translate("Unlock Gate"),
|
||||
"locked": false,
|
||||
"callback": function (item) { lockGate(item.locked); }
|
||||
});
|
||||
}
|
||||
// Show both 'locked' and 'unlocked' as active if the selected gates have both lock states.
|
||||
else if (state.gate && state.gate.locked != gates[0].gate.locked)
|
||||
for (var j = 0; j < gates.length; ++j)
|
||||
@ -1156,13 +1234,13 @@ function updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, s
|
||||
}
|
||||
}
|
||||
if (packButton)
|
||||
items.push({ "packing": false, "packed": false, "tooltip": "Pack", "callback": function() { packUnit(true); } });
|
||||
items.push({ "packing": false, "packed": false, "tooltip": translate("Pack"), "callback": function() { packUnit(true); } });
|
||||
if (unpackButton)
|
||||
items.push({ "packing": false, "packed": true, "tooltip": "Unpack", "callback": function() { packUnit(false); } });
|
||||
items.push({ "packing": false, "packed": true, "tooltip": translate("Unpack"), "callback": function() { packUnit(false); } });
|
||||
if (packCancelButton)
|
||||
items.push({ "packing": true, "packed": false, "tooltip": "Cancel packing", "callback": function() { cancelPackUnit(true); } });
|
||||
items.push({ "packing": true, "packed": false, "tooltip": translate("Cancel Packing"), "callback": function() { cancelPackUnit(true); } });
|
||||
if (unpackCancelButton)
|
||||
items.push({ "packing": true, "packed": true, "tooltip": "Cancel unpacking", "callback": function() { cancelPackUnit(false); } });
|
||||
items.push({ "packing": true, "packed": true, "tooltip": translate("Cancel Unpacking"), "callback": function() { cancelPackUnit(false); } });
|
||||
|
||||
if (items.length)
|
||||
setupUnitPanel(PACK, usedPanels, entState, playerState, items);
|
||||
|
@ -32,17 +32,6 @@ function toTitleCase(word)
|
||||
return word;
|
||||
}
|
||||
|
||||
function pluralize(word, count, pluralWord)
|
||||
{
|
||||
if (count == 1 && pluralWord != null)
|
||||
return pluralWord;
|
||||
|
||||
var plural = "s";
|
||||
if (word[word.length - 1] == "s")
|
||||
plural = "es";
|
||||
return word + (count == 1 ? "" : plural);
|
||||
}
|
||||
|
||||
// Get the basic player data
|
||||
function getPlayerData(playerAssignments)
|
||||
{
|
||||
@ -162,110 +151,132 @@ function damageValues(dmg)
|
||||
// For the unit details panel
|
||||
function damageTypeDetails(dmg)
|
||||
{
|
||||
if (dmg)
|
||||
{
|
||||
var dmgArray = [];
|
||||
if (dmg.hack) dmgArray.push(dmg.hack + "[font=\"sans-10\"][color=\"orange\"] Hack[/color][/font]");
|
||||
if (dmg.pierce) dmgArray.push(dmg.pierce + "[font=\"sans-10\"][color=\"orange\"] Pierce[/color][/font]");
|
||||
if (dmg.crush) dmgArray.push(dmg.crush + "[font=\"sans-10\"][color=\"orange\"] Crush[/color][/font]");
|
||||
if (!dmg)
|
||||
return "[font=\"serif-12\"]" + translate("(None)") + "[/font]";
|
||||
|
||||
return dmgArray.join(", ");
|
||||
}
|
||||
else
|
||||
{
|
||||
return "[font=\"serif-12\"](None)[/font]";
|
||||
}
|
||||
var dmgArray = [];
|
||||
if (dmg.hack)
|
||||
dmgArray.push(sprintf(translate("%(damage)s %(damageType)s"), {
|
||||
damage: dmg.hack,
|
||||
damageType: "[font=\"sans-10\"][color=\"orange\"]" + translate("Hack") + "[/color][/font]"
|
||||
}));
|
||||
if (dmg.pierce)
|
||||
dmgArray.push(sprintf(translate("%(damage)s %(damageType)s"), {
|
||||
damage: dmg.pierce,
|
||||
damageType: "[font=\"sans-10\"][color=\"orange\"]" + translate("Pierce") + "[/color][/font]"
|
||||
}));
|
||||
if (dmg.crush)
|
||||
dmgArray.push(sprintf(translate("%(damage)s %(damageType)s"), {
|
||||
damage: dmg.crush,
|
||||
damageType: "[font=\"sans-10\"][color=\"orange\"]" + translate("Crush") + "[/color][/font]"
|
||||
}));
|
||||
|
||||
return dmgArray.join(translate(", "));
|
||||
}
|
||||
|
||||
function attackRateDetails(entState) {
|
||||
if (entState.buildingAI)
|
||||
var arrows = entState.buildingAI.arrowCount;
|
||||
|
||||
var time = entState.attack.repeatTime / 1000;
|
||||
if (entState.buildingAI) {
|
||||
return Math.max(arrows, entState.buildingAI.defaultArrowCount) + "[font=\"sans-10\"][color=\"orange\"] " +
|
||||
pluralize("arrow", arrows) + "[/color][/font]" + " / " + (time == 1 ? "" : time) +
|
||||
" [font=\"sans-10\"][color=\"orange\"]" + pluralize("second", time) + "[/color][/font]";
|
||||
var arrows = Math.max(entState.buildingAI.arrowCount, entState.buildingAI.defaultArrowCount);
|
||||
// TODO TODO TODO color, font
|
||||
return sprintf(translate("%(arrowString)s / %(timeString)s"), {
|
||||
arrowString: sprintf(translatePlural("%(arrows)s arrow", "%(arrows)s arrows", arrows), { arrows: arrows}),
|
||||
timeString: sprintf(translatePlural("%(time)s second", "%(time)s seconds", time), { time: time })
|
||||
});
|
||||
}
|
||||
return time + "[font=\"sans-10\"][color=\"orange\"] " + pluralize("second", time) + "[/color][/font]";
|
||||
// TODO TODO TODO color, font
|
||||
return sprintf(translatePlural("%(time)s second", "%(time)s seconds", time), { time: time });
|
||||
}
|
||||
|
||||
// Converts an armor level into the actual reduction percentage
|
||||
function armorLevelToPercentage(level)
|
||||
function armorLevelToPercentageString(level)
|
||||
{
|
||||
return 100 - Math.round(Math.pow(0.9, level) * 100);
|
||||
return (100 - Math.round(Math.pow(0.9, level) * 100)) + "%";
|
||||
// return sprintf(translate("%(armorPercentage)s%"), { armorPercentage: (100 - Math.round(Math.pow(0.9, level) * 100)) }); // Not supported by our sprintf implementation.
|
||||
}
|
||||
|
||||
// Also for the unit details panel
|
||||
function armorTypeDetails(dmg)
|
||||
{
|
||||
if (dmg)
|
||||
{
|
||||
var dmgArray = [];
|
||||
if (dmg.hack)
|
||||
{
|
||||
dmgArray.push(dmg.hack + "[font=\"sans-10\"][color=\"orange\"] Hack[/color][/font] " +
|
||||
" [font=\"sans-10\"](" + armorLevelToPercentage(dmg.hack) + "%)[/font]");
|
||||
}
|
||||
if (dmg.pierce)
|
||||
{
|
||||
dmgArray.push(dmg.pierce + "[font=\"sans-10\"][color=\"orange\"] Pierce[/color][/font] " +
|
||||
" [font=\"sans-10\"](" + armorLevelToPercentage(dmg.pierce) + "%)[/font]");
|
||||
}
|
||||
if (dmg.crush)
|
||||
{
|
||||
dmgArray.push(dmg.crush + "[font=\"sans-10\"][color=\"orange\"] Crush[/color][/font] " +
|
||||
" [font=\"sans-10\"](" + armorLevelToPercentage(dmg.crush) + "%)[/font]");
|
||||
}
|
||||
if (!dmg)
|
||||
return "[font=\"serif-12\"]" + translate("(None)") + "[/font]";
|
||||
|
||||
return dmgArray.join(", ");
|
||||
}
|
||||
else
|
||||
{
|
||||
return "[font=\"serif-12\"](None)[/font]";
|
||||
}
|
||||
var dmgArray = [];
|
||||
if (dmg.hack)
|
||||
dmgArray.push(sprintf(translate("%(damage)s %(damageType)s %(armorPercentage)s"), {
|
||||
damage: dmg.hack,
|
||||
damageType: "[font=\"sans-10\"][color=\"orange\"]" + translate("Hack") + "[/color][/font]",
|
||||
armorPercentage: "[font=\"sans-10\"]" + sprintf(translate("(%(armorPercentage)s)"), { armorPercentage: armorLevelToPercentageString(dmg.hack) }) + "[/font]"
|
||||
}));
|
||||
if (dmg.pierce)
|
||||
dmgArray.push(sprintf(translate("%(damage)s %(damageType)s %(armorPercentage)s"), {
|
||||
damage: dmg.pierce,
|
||||
damageType: "[font=\"sans-10\"][color=\"orange\"]" + translate("Pierce") + "[/color][/font]",
|
||||
armorPercentage: "[font=\"sans-10\"]" + sprintf(translate("(%(armorPercentage)s)"), { armorPercentage: armorLevelToPercentageString(dmg.pierce) }) + "[/font]"
|
||||
}));
|
||||
if (dmg.crush)
|
||||
dmgArray.push(sprintf(translate("%(damage)s %(damageType)s %(armorPercentage)s"), {
|
||||
damage: dmg.crush,
|
||||
damageType: "[font=\"sans-10\"][color=\"orange\"]" + translate("Crush") + "[/color][/font]",
|
||||
armorPercentage: "[font=\"sans-10\"]" + sprintf(translate("(%(armorPercentage)s)"), { armorPercentage: armorLevelToPercentageString(dmg.crush) }) + "[/font]"
|
||||
}));
|
||||
|
||||
return dmgArray.join(translate(", "));
|
||||
}
|
||||
|
||||
// For the training tooltip
|
||||
function damageTypesToText(dmg)
|
||||
{
|
||||
if (!dmg)
|
||||
return "[font=\"serif-12\"](None)[/font]";
|
||||
|
||||
var hackLabel = "[font=\"serif-12\"] Hack[/font]";
|
||||
var pierceLabel = "[font=\"serif-12\"] Pierce[/font]";
|
||||
var crushLabel = "[font=\"serif-12\"] Crush[/font]";
|
||||
var hackDamage = dmg.hack;
|
||||
var pierceDamage = dmg.pierce;
|
||||
var crushDamage = dmg.crush;
|
||||
return "[font=\"serif-12\"]" + translate("(None)") + "[/font]";
|
||||
|
||||
var dmgArray = [];
|
||||
if (hackDamage) dmgArray.push(Math.round(hackDamage) + hackLabel);
|
||||
if (pierceDamage) dmgArray.push(Math.round(pierceDamage) + pierceLabel);
|
||||
if (crushDamage) dmgArray.push(Math.round(crushDamage) + crushLabel);
|
||||
if (dmg.hack)
|
||||
dmgArray.push(sprintf(translate("%(damage)s %(damageType)s"), {
|
||||
damage: dmg.hack,
|
||||
damageType: "[font=\"serif-12\"]" + translate("Hack") + "[/font]"
|
||||
}));
|
||||
if (dmg.pierce)
|
||||
dmgArray.push(sprintf(translate("%(damage)s %(damageType)s"), {
|
||||
damage: dmg.pierce,
|
||||
damageType: "[font=\"serif-12\"]" + translate("Pierce") + "[/font]"
|
||||
}));
|
||||
if (dmg.crush)
|
||||
dmgArray.push(sprintf(translate("%(damage)s %(damageType)s"), {
|
||||
damage: dmg.crush,
|
||||
damageType: "[font=\"serif-12\"]" + translate("Crush") + "[/font]"
|
||||
}));
|
||||
|
||||
return dmgArray.join("[font=\"serif-12\"], [/font]");
|
||||
return dmgArray.join("[font=\"serif-12\"]" + translate(", ") + "[/font]");
|
||||
}
|
||||
|
||||
// Also for the training tooltip
|
||||
function armorTypesToText(dmg)
|
||||
{
|
||||
if (!dmg)
|
||||
return "[font=\"serif-12\"](None)[/font]";
|
||||
|
||||
var hackDamage = dmg.hack;
|
||||
var pierceDamage = dmg.pierce;
|
||||
var crushDamage = dmg.crush;
|
||||
var hackLabel = "[font=\"serif-12\"] Hack (" + armorLevelToPercentage(hackDamage) + "%)[/font]";
|
||||
var pierceLabel = "[font=\"serif-12\"] Pierce (" + armorLevelToPercentage(pierceDamage) + "%)[/font]";
|
||||
var crushLabel = "[font=\"serif-12\"] Crush (" + armorLevelToPercentage(crushDamage) + "%)[/font]";
|
||||
return "[font=\"serif-12\"]" + translate("(None)") + "[/font]";
|
||||
|
||||
var dmgArray = [];
|
||||
if (hackDamage) dmgArray.push(hackDamage + hackLabel);
|
||||
if (pierceDamage) dmgArray.push(pierceDamage + pierceLabel);
|
||||
if (crushDamage) dmgArray.push(crushDamage + crushLabel);
|
||||
if (dmg.hack)
|
||||
dmgArray.push(sprintf(translate("%(damage)s %(damageType)s %(armorPercentage)s"), {
|
||||
damage: dmg.hack,
|
||||
damageType: "[font=\"serif-12\"]" + translate("Hack") + "[/font]",
|
||||
armorPercentage: "[font=\"sans-10\"]" + sprintf(translate("(%(armorPercentage)s)"), { armorPercentage: armorLevelToPercentageString(dmg.hack) }) + "[/font]"
|
||||
}));
|
||||
if (dmg.pierce)
|
||||
dmgArray.push(sprintf(translate("%(damage)s %(damageType)s %(armorPercentage)s"), {
|
||||
damage: dmg.pierce,
|
||||
damageType: "[font=\"serif-12\"]" + translate("Pierce") + "[/font]",
|
||||
armorPercentage: "[font=\"sans-10\"]" + sprintf(translate("(%(armorPercentage)s)"), { armorPercentage: armorLevelToPercentageString(dmg.pierce) }) + "[/font]"
|
||||
}));
|
||||
if (dmg.crush)
|
||||
dmgArray.push(sprintf(translate("%(damage)s %(damageType)s %(armorPercentage)s"), {
|
||||
damage: dmg.crush,
|
||||
damageType: "[font=\"serif-12\"]" + translate("Crush") + "[/font]",
|
||||
armorPercentage: "[font=\"sans-10\"]" + sprintf(translate("(%(armorPercentage)s)"), { armorPercentage: armorLevelToPercentageString(dmg.crush) }) + "[/font]"
|
||||
}));
|
||||
|
||||
return dmgArray.join("[font=\"serif-12\"], [/font]");
|
||||
return dmgArray.join("[font=\"serif-12\"]" + translate(", ") + "[/font]");
|
||||
}
|
||||
|
||||
function getEntityCommandsList(entState)
|
||||
@ -275,14 +286,14 @@ function getEntityCommandsList(entState)
|
||||
{
|
||||
commands.push({
|
||||
"name": "unload-all",
|
||||
"tooltip": "Unload All",
|
||||
"tooltip": translate("Unload All"),
|
||||
"icon": "garrison-out.png"
|
||||
});
|
||||
}
|
||||
|
||||
commands.push({
|
||||
"name": "delete",
|
||||
"tooltip": "Delete",
|
||||
"tooltip": translate("Delete"),
|
||||
"icon": "kill_small.png"
|
||||
});
|
||||
|
||||
@ -290,12 +301,12 @@ function getEntityCommandsList(entState)
|
||||
{
|
||||
commands.push({
|
||||
"name": "stop",
|
||||
"tooltip": "Stop",
|
||||
"tooltip": translate("Stop"),
|
||||
"icon": "stop.png"
|
||||
});
|
||||
commands.push({
|
||||
"name": "garrison",
|
||||
"tooltip": "Garrison",
|
||||
"tooltip": translate("Garrison"),
|
||||
"icon": "garrison.png"
|
||||
});
|
||||
}
|
||||
@ -304,7 +315,7 @@ function getEntityCommandsList(entState)
|
||||
{
|
||||
commands.push({
|
||||
"name": "repair",
|
||||
"tooltip": "Repair",
|
||||
"tooltip": translate("Repair"),
|
||||
"icon": "repair.png"
|
||||
});
|
||||
}
|
||||
@ -313,16 +324,16 @@ function getEntityCommandsList(entState)
|
||||
{
|
||||
commands.push({
|
||||
"name": "focus-rally",
|
||||
"tooltip": "Focus on Rally Point",
|
||||
"tooltip": translate("Focus on Rally Point"),
|
||||
"icon": "focus-rally.png"
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (entState.unitAI && entState.unitAI.hasWorkOrders)
|
||||
{
|
||||
commands.push({
|
||||
"name": "back-to-work",
|
||||
"tooltip": "Back to Work",
|
||||
"tooltip": translate("Back to Work"),
|
||||
"icon": "production.png"
|
||||
});
|
||||
}
|
||||
@ -331,7 +342,7 @@ function getEntityCommandsList(entState)
|
||||
{
|
||||
commands.push({
|
||||
"name": "add-guard",
|
||||
"tooltip": "Guard",
|
||||
"tooltip": translate("Guard"),
|
||||
"icon": "add-guard.png"
|
||||
});
|
||||
}
|
||||
@ -340,7 +351,7 @@ function getEntityCommandsList(entState)
|
||||
{
|
||||
commands.push({
|
||||
"name": "remove-guard",
|
||||
"tooltip": "Remove guard",
|
||||
"tooltip": translate("Remove guard"),
|
||||
"icon": "remove-guard.png"
|
||||
});
|
||||
}
|
||||
@ -349,7 +360,7 @@ function getEntityCommandsList(entState)
|
||||
{
|
||||
commands.push({
|
||||
"name": "select-trading-goods",
|
||||
"tooltip": "Select trading goods",
|
||||
"tooltip": translate("Select trading goods"),
|
||||
"icon": "economics.png"
|
||||
});
|
||||
}
|
||||
@ -359,9 +370,9 @@ function getEntityCommandsList(entState)
|
||||
if(entState.alertRaiser.canIncreaseLevel)
|
||||
{
|
||||
if(entState.alertRaiser.hasRaisedAlert)
|
||||
var tooltip = "Increase the alert level to protect more units";
|
||||
var tooltip = translate("Increase the alert level to protect more units");
|
||||
else
|
||||
var tooltip = "Raise an alert!";
|
||||
var tooltip = translate("Raise an alert!");
|
||||
commands.push({
|
||||
"name": "increase-alert-level",
|
||||
"tooltip": tooltip,
|
||||
@ -372,7 +383,7 @@ function getEntityCommandsList(entState)
|
||||
if(entState.alertRaiser.hasRaisedAlert)
|
||||
commands.push({
|
||||
"name": "alert-end",
|
||||
"tooltip": "End of alert.",
|
||||
"tooltip": translate("End of alert."),
|
||||
"icon": "bell_level0.png"
|
||||
});
|
||||
}
|
||||
@ -413,12 +424,12 @@ function getEntityCostComponentsTooltipString(template, trainNum, entity)
|
||||
totalCosts.time = Math.ceil(template.cost.time * (entity ? Engine.GuiInterfaceCall("GetBatchTime", {"entity": entity, "batchSize": trainNum}) : 1));
|
||||
|
||||
var costs = [];
|
||||
if (totalCosts.food) costs.push(getCostComponentDisplayName("food") + " " + totalCosts.food);
|
||||
if (totalCosts.wood) costs.push(getCostComponentDisplayName("wood") + " " + totalCosts.wood);
|
||||
if (totalCosts.metal) costs.push(getCostComponentDisplayName("metal") + " " + totalCosts.metal);
|
||||
if (totalCosts.stone) costs.push(getCostComponentDisplayName("stone") + " " + totalCosts.stone);
|
||||
if (totalCosts.population) costs.push(getCostComponentDisplayName("population") + " " + totalCosts.population);
|
||||
if (totalCosts.time) costs.push(getCostComponentDisplayName("time") + " " + totalCosts.time);
|
||||
if (totalCosts.food) costs.push(sprintf(translate("%(component)s %(cost)s"), { component: getCostComponentDisplayName("food"), cost: totalCosts.food }));
|
||||
if (totalCosts.wood) costs.push(sprintf(translate("%(component)s %(cost)s"), { component: getCostComponentDisplayName("wood"), cost: totalCosts.wood }));
|
||||
if (totalCosts.metal) costs.push(sprintf(translate("%(component)s %(cost)s"), { component: getCostComponentDisplayName("metal"), cost: totalCosts.metal }));
|
||||
if (totalCosts.stone) costs.push(sprintf(translate("%(component)s %(cost)s"), { component: getCostComponentDisplayName("stone"), cost: totalCosts.stone }));
|
||||
if (totalCosts.population) costs.push(sprintf(translate("%(component)s %(cost)s"), { component: getCostComponentDisplayName("population"), cost: totalCosts.population }));
|
||||
if (totalCosts.time) costs.push(sprintf(translate("%(component)s %(cost)s"), { component: getCostComponentDisplayName("time"), cost: totalCosts.time }));
|
||||
return costs;
|
||||
}
|
||||
|
||||
@ -499,14 +510,13 @@ function getEntityCostTooltip(template, trainNum, entity)
|
||||
var wallCosts = getWallPieceTooltip([templateShort, templateMedium, templateLong]);
|
||||
var towerCosts = getEntityCostComponentsTooltipString(templateTower);
|
||||
|
||||
cost += "\n";
|
||||
cost += " Walls: " + wallCosts.join(" ") + "\n";
|
||||
cost += " Towers: " + towerCosts.join(" ");
|
||||
cost += " " + sprintf(translate("Walls: %(costs)s"), { costs: wallCosts.join(translate(" ")) }) + "\n";
|
||||
cost += " " + sprintf(translate("Towers: %(costs)s"), { costs: towerCosts.join(translate(" ")) });
|
||||
}
|
||||
else if (template.cost)
|
||||
{
|
||||
var costs = getEntityCostComponentsTooltipString(template, trainNum, entity);
|
||||
cost += costs.join(" ");
|
||||
cost = costs.join(translate(" "));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -523,7 +533,10 @@ function getPopulationBonusTooltip(template)
|
||||
{
|
||||
var popBonus = "";
|
||||
if (template.cost && template.cost.populationBonus)
|
||||
popBonus = "\n[font=\"serif-bold-13\"]Population Bonus:[/font] " + template.cost.populationBonus;
|
||||
popBonus = "\n" + sprintf(translate("%(label)s %(populationBonus)s"), {
|
||||
label: "[font=\"serif-bold-13\"]" + translate("Population Bonus:") + "[/font]",
|
||||
populationBonus: template.cost.populationBonus
|
||||
});
|
||||
return popBonus;
|
||||
}
|
||||
|
||||
@ -534,9 +547,12 @@ function getNeededResourcesTooltip(resources)
|
||||
{
|
||||
var formatted = [];
|
||||
for (var resource in resources)
|
||||
formatted.push("[font=\"serif-12\"]" + getCostComponentDisplayName(resource) + "[/font] " + resources[resource]);
|
||||
formatted.push(sprintf(translate("%(component)s %(cost)s"), {
|
||||
component: "[font=\"serif-12\"]" + getCostComponentDisplayName(resource) + "[/font]",
|
||||
cost: resources[resource]
|
||||
}));
|
||||
|
||||
return "\n\n[font=\"serif-bold-13\"][color=\"red\"]Insufficient resources:[/color][/font]\n" + formatted.join(" ");
|
||||
return "\n\n[font=\"serif-bold-13\"][color=\"red\"]" + translate("Insufficient resources:") + "[/color][/font]\n" + formatted.join(translate(" "));
|
||||
}
|
||||
|
||||
function getEntitySpeed(template)
|
||||
@ -544,12 +560,12 @@ function getEntitySpeed(template)
|
||||
var speed = "";
|
||||
if (template.speed)
|
||||
{
|
||||
speed += "[font=\"serif-bold-13\"]Speed:[/font] ";
|
||||
var label = "[font=\"serif-bold-13\"]" + translate("Speed:") + "[/font]";
|
||||
var speeds = [];
|
||||
if (template.speed.walk) speeds.push(template.speed.walk + " [font=\"serif-12\"]Walk[/font]");
|
||||
if (template.speed.run) speeds.push(template.speed.run + " [font=\"serif-12\"]Run[/font]");
|
||||
if (template.speed.walk) speeds.push(sprintf(translate("%(speed)s %(movementType)s"), { speed: template.speed.walk, movementType: "[font=\"serif-12\"]" + translate("Walk") + "[/font]"}));
|
||||
if (template.speed.run) speeds.push(sprintf(translate("%(speed)s %(movementType)s"), { speed: template.speed.run, movementType: "[font=\"serif-12\"]" + translate("Run") + "[/font]"}));
|
||||
|
||||
speed += speeds.join(", ");
|
||||
speed = sprintf(translate("%(label)s %(speeds)s"), { label: label, speeds: speeds.join(translate(", ")) })
|
||||
}
|
||||
return speed;
|
||||
}
|
||||
@ -563,34 +579,47 @@ function getEntityAttack(template)
|
||||
delete template.attack['Slaughter'];
|
||||
for (var type in template.attack)
|
||||
{
|
||||
var attack = "[font=\"serif-bold-13\"]" + type + " Attack:[/font] " + damageTypesToText(template.attack[type]);
|
||||
// Show max attack range if ranged attack, also convert to tiles (4m per tile)
|
||||
var attack = "";
|
||||
var attackLabel = "[font=\"serif-bold-13\"]" + getAttackTypeLabel(type) + "[/font]";
|
||||
if (type == "Ranged")
|
||||
attack += ", [font=\"serif-bold-13\"]Range:[/font] "+Math.round(template.attack[type].maxRange/4);
|
||||
{
|
||||
// Show max attack range if ranged attack, also convert to tiles (4m per tile)
|
||||
attack = sprintf(translate("%(attackLabel)s %(damageTypes)s, %(rangeLabel)s %(range)s"), {
|
||||
attackLabel: attackLabel,
|
||||
damageTypes: damageTypesToText(template.attack[type]),
|
||||
rangeLabel: "[font=\"serif-bold-13\"]" + translate("Range:") + "[/font]",
|
||||
range: Math.round(template.attack[type].maxRange/4)
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
attack = sprintf(translate("%(attackLabel)s %(damageTypes)s"), {
|
||||
attackLabel: attackLabel,
|
||||
damageTypes: damageTypesToText(template.attack[type])
|
||||
});
|
||||
}
|
||||
attacks.push(attack);
|
||||
}
|
||||
}
|
||||
return attacks.join("\n");
|
||||
}
|
||||
|
||||
function getEntityName(template)
|
||||
{
|
||||
return template.name.specific || template.name.generic || "???";
|
||||
}
|
||||
|
||||
function getEntityNames(template)
|
||||
{
|
||||
var names = [];
|
||||
if (template.name.specific)
|
||||
{
|
||||
names.push(template.name.specific);
|
||||
if (template.name.generic && names[0] != template.name.generic)
|
||||
names.push("(" + template.name.generic + ")");
|
||||
}
|
||||
else if (template.name.generic)
|
||||
names.push(template.name.generic);
|
||||
{
|
||||
if (template.name.generic && template.name.specific != template.name.generic)
|
||||
return sprintf(translate("%(specificName)s (%(genericName)s)"), {
|
||||
specificName: template.name.specific,
|
||||
genericName: template.name.generic
|
||||
});
|
||||
return template.name.specific;
|
||||
}
|
||||
if (template.name.generic)
|
||||
return template.name.generic;
|
||||
|
||||
return (names.length) ? names.join(" ") : "???";
|
||||
warn("Entity name requested on an entity without a name, specific or generic.");
|
||||
return translate("???");
|
||||
}
|
||||
|
||||
function getEntityNamesFormatted(template)
|
||||
@ -620,7 +649,7 @@ function getEntityRankedName(entState)
|
||||
var template = GetTemplateData(entState.template)
|
||||
var rank = entState.identity.rank;
|
||||
if (rank)
|
||||
return rank + " " + template.name.specific;
|
||||
return sprintf(translate("%(rank)s %(name)s"), { rank: rank, name: template.name.specific });
|
||||
else
|
||||
return template.name.specific;
|
||||
}
|
||||
@ -642,21 +671,41 @@ function getRankIconSprite(entState)
|
||||
*/
|
||||
function getTradingTooltip(gain)
|
||||
{
|
||||
var tooltip = gain.traderGain;
|
||||
var gainString = gain.traderGain;
|
||||
if (gain.market1Gain && gain.market1Owner == gain.traderOwner)
|
||||
tooltip += "+" + gain.market1Gain;
|
||||
gainString += translate("+") + gain.market1Gain;
|
||||
if (gain.market2Gain && gain.market2Owner == gain.traderOwner)
|
||||
tooltip += "+" + gain.market2Gain;
|
||||
tooltip += " (you)";
|
||||
gainString += translate("+") + gain.market2Gain;
|
||||
|
||||
var tooltip = sprintf(translate("%(gain)s (%(player)s)"), {
|
||||
gain: gainString,
|
||||
player: translate("you")
|
||||
});
|
||||
|
||||
if (gain.market1Gain && gain.market1Owner != gain.traderOwner)
|
||||
tooltip += ", " + gain.market1Gain + " (player " + gain.market1Owner + ")";
|
||||
tooltip += translate(", ") + sprintf(translate("%(gain)s (%(player)s)"), {
|
||||
gain: gain.market1Gain,
|
||||
player: sprintf(translate("player %(name)s"), { name: gain.market1Owner })
|
||||
});
|
||||
if (gain.market2Gain && gain.market2Owner != gain.traderOwner)
|
||||
tooltip += ", " + gain.market2Gain + " (player " + gain.market2Owner + ")";
|
||||
tooltip += translate(", ") + sprintf(translate("%(gain)s (%(player)s)"), {
|
||||
gain: gain.market2Gain,
|
||||
player: sprintf(translate("player %(name)s"), { name: gain.market2Owner })
|
||||
});
|
||||
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
function getAttackTypeLabel(type)
|
||||
{
|
||||
if (type === "Charge") return translate("Charge Attack:");
|
||||
if (type === "Melee") return translate("Melee Attack:");
|
||||
if (type === "Ranged") return translate("Ranged Attack:");
|
||||
|
||||
warn(sprintf("Internationalization: Unexpected attack type found with code ‘%(attackType)s’. This attack type must be internationalized.", { attackType: type }));
|
||||
return translate("Attack:");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entity itself except when garrisoned where it returns its garrisonHolder
|
||||
*/
|
||||
|
@ -1,6 +1,10 @@
|
||||
function init(data)
|
||||
{
|
||||
Engine.GetGUIObjectByName("mainText").caption = Engine.ReadFile("gui/splashscreen/" + data.page + ".txt");
|
||||
|
||||
Engine.GetGUIObjectByName("mainText").caption = Engine.TranslateLines(Engine.ReadFile("gui/splashscreen/" + data.page + ".txt"));
|
||||
}
|
||||
|
||||
function openURL(url)
|
||||
{
|
||||
Engine.OpenURL(url);
|
||||
messageBox(600, 200, sprintf(translate("Opening %(url)s\n in default web browser. Please wait..."), { url: url }), translate("Opening page"), 2);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
[font="serif-bold-16"]Thank you for installing 0 A.D.!
|
||||
[font="serif-bold-16"]Thank you for installing 0 A.D.!
|
||||
[font="serif-16"]
|
||||
[icon="constructionIcon"] This is an early experimental version of the game. Features are missing and it contains bugs.
|
||||
|
||||
|
@ -8,19 +8,23 @@
|
||||
<object type="image" z="0" sprite="ModernFade"/>
|
||||
|
||||
<object type="image" style="ModernDialog" size="50%-274 50%-200 50%+274 50%+200">
|
||||
<object type="text" style="TitleText" size="50%-128 0%-16 50%+128 16">Welcome to 0 A.D. !</object>
|
||||
<object type="text" style="TitleText" size="50%-128 0%-16 50%+128 16">
|
||||
<translatableAttribute id="caption">Welcome to 0 A.D. !</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object type="image" sprite="BackgroundTranslucent" size="20 20 100%-20 100%-52">
|
||||
<object name="mainText" type="text" style="textPanel"/>
|
||||
<object size="8 100%-60 100% 100%">
|
||||
<object size="0 20 100% 100%">
|
||||
<object name="displaySplashScreenText" size="20 0 100% 100%" type="text" style="ModernLeftLabelText">Show this message in the future</object>
|
||||
<object name="displaySplashScreenText" size="20 0 100% 100%" type="text" style="ModernLeftLabelText">
|
||||
<translatableAttribute id="caption">Show this message in the future</translatableAttribute>
|
||||
</object>
|
||||
<object name="displaySplashScreen" checked="true" size="0 50%-8 16 50%+8" type="checkbox" style="ModernTickBox"/>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object name="btnOK" type="button" style="StoneButton" tooltip_style="snToolTip" size="24 100%-52 188 100%-24">
|
||||
OK
|
||||
<translatableAttribute id="caption">OK</translatableAttribute>
|
||||
<action on="Press"><![CDATA[
|
||||
Engine.ConfigDB_CreateValue("user", "splashscreenenable", Engine.GetGUIObjectByName("displaySplashScreen").checked ? "true" : "false");
|
||||
Engine.ConfigDB_WriteFile("user", "config/user.cfg");
|
||||
@ -28,12 +32,10 @@
|
||||
]]></action>
|
||||
</object>
|
||||
<object type="button" style="StoneButton" size="192 100%-52 356 100%-24">
|
||||
Known issues (web)
|
||||
<translatableAttribute id="caption">Known issues (web)</translatableAttribute>
|
||||
<action on="Press"><![CDATA[
|
||||
var url = "http://www.wildfiregames.com/forum/index.php?showtopic=15796";
|
||||
Engine.OpenURL(url);
|
||||
messageBox(600, 200, "Opening "+url+"\n in default web browser. Please wait...", "Opening page", 2);
|
||||
]]></action>
|
||||
openURL("http://www.wildfiregames.com/forum/index.php?showtopic=15796");
|
||||
]]></action>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
|
@ -505,9 +505,9 @@ function init(data)
|
||||
// Load data
|
||||
var civData = loadCivData();
|
||||
// Map
|
||||
var mapSize = "Scenario";
|
||||
var mapDisplayType = translate("Scenario");
|
||||
|
||||
Engine.GetGUIObjectByName("timeElapsed").caption = "Time elapsed: " + timeToString(data.timeElapsed);
|
||||
Engine.GetGUIObjectByName("timeElapsed").caption = sprintf(translate("Time elapsed: %(time)s"), { time: timeToString(data.timeElapsed) });
|
||||
|
||||
Engine.GetGUIObjectByName("summaryText").caption = data.gameResult;
|
||||
|
||||
@ -522,13 +522,13 @@ function init(data)
|
||||
{
|
||||
if (mapSizes.tiles[mapSizeIndex] == data.mapSettings.Size)
|
||||
{
|
||||
mapSize = mapSizes.names[mapSizeIndex];
|
||||
mapDisplayType = mapSizes.names[mapSizeIndex];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Engine.GetGUIObjectByName("mapName").caption = data.mapSettings.Name + " - " + mapSize;
|
||||
Engine.GetGUIObjectByName("mapName").caption = sprintf(translate("%(mapName)s - %(mapType)s"), { mapName: data.mapSettings.Name, mapType: mapDisplayType});
|
||||
|
||||
// Panels
|
||||
// Align headers
|
||||
|
@ -20,7 +20,7 @@
|
||||
</action>
|
||||
|
||||
<object style="TitleText" type="text" size="50%-128 4 50%+128 36">
|
||||
Summary
|
||||
<translatableAttribute id="caption">Summary</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object type="image" sprite="ForegroundBody" size="20 24 100%-20 80">
|
||||
@ -59,51 +59,63 @@
|
||||
|
||||
<object name="scorePanelButton" type="button" sprite="ForegroundTab" size="20 92 136 120">
|
||||
<action on="Press">selectPanel(0);</action>
|
||||
<object type="text" style="TitleText" ghost="true">Score</object>
|
||||
<object type="text" style="TitleText" ghost="true">
|
||||
<translatableAttribute id="caption">Score</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object name="buildingsPanelButton" type="button" sprite="BackgroundTab" size="142 92 260 120">
|
||||
<action on="Press">selectPanel(1);</action>
|
||||
<object type="text" style="TitleText" ghost="true">Buildings</object>
|
||||
<object type="text" style="TitleText" ghost="true">
|
||||
<translatableAttribute id="caption">Buildings</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object name="unitsPanelButton" type="button" sprite="BackgroundTab" size="266 92 384 120">
|
||||
<action on="Press">selectPanel(2);</action>
|
||||
<object type="text" style="TitleText" ghost="true">Units</object>
|
||||
<object type="text" style="TitleText" ghost="true">
|
||||
<translatableAttribute id="caption">Units</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object name="resourcesPanelButton" type="button" sprite="BackgroundTab" size="390 92 508 120">
|
||||
<action on="Press">selectPanel(3);</action>
|
||||
<object type="text" style="TitleText" ghost="true">Resources</object>
|
||||
<object type="text" style="TitleText" ghost="true">
|
||||
<translatableAttribute id="caption">Resources</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object name="marketPanelButton" type="button" sprite="BackgroundTab" size="514 92 632 120">
|
||||
<action on="Press">selectPanel(4);</action>
|
||||
<object type="text" style="TitleText" ghost="true">Market</object>
|
||||
<object type="text" style="TitleText" ghost="true">
|
||||
<translatableAttribute id="caption">Market</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object name="miscPanelButton" type="button" sprite="BackgroundTab" size="638 92 756 120">
|
||||
<action on="Press">selectPanel(5);</action>
|
||||
<object type="text" style="TitleText" ghost="true">Miscellaneous</object>
|
||||
<object type="text" style="TitleText" ghost="true">
|
||||
<translatableAttribute id="caption">Miscellaneous</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object name="scorePanel" type="image" sprite="ForegroundBody" size="20 120 100%-20 100%-58">
|
||||
|
||||
<object size="0 0 100% 100%-50">
|
||||
<object name="playerName0Heading" type="text" style="ModernLeftTabLabelText">
|
||||
Player name
|
||||
<translatableAttribute id="caption">Player name</translatableAttribute>
|
||||
</object>
|
||||
<object name="economyScoreHeading" type="text" style="ModernTabLabelText">
|
||||
Economy score
|
||||
<translatableAttribute id="caption">Economy score</translatableAttribute>
|
||||
</object>
|
||||
<object name="militaryScoreHeading" type="text" style="ModernTabLabelText">
|
||||
Military score
|
||||
<translatableAttribute id="caption">Military score</translatableAttribute>
|
||||
</object>
|
||||
<object name="explorationScoreHeading" type="text" style="ModernTabLabelText">
|
||||
Exploration score
|
||||
<translatableAttribute id="caption">Exploration score</translatableAttribute>
|
||||
</object>
|
||||
<object name="totalScoreHeading" type="text" style="ModernTabLabelText">
|
||||
Total score
|
||||
<translatableAttribute id="caption">Total score</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
@ -213,34 +225,34 @@
|
||||
|
||||
<object size="0 0 100% 100%-50">
|
||||
<object name="playerName1Heading" type="text" style="ModernLeftTabLabelText">
|
||||
Player name
|
||||
<translatableAttribute id="caption">Player name</translatableAttribute>
|
||||
</object>
|
||||
<object name="buildingsHeading" type="text" style="ModernTabLabelText">
|
||||
Buildings Statistics (Constructed / Lost / Destroyed)
|
||||
<translatableAttribute id="caption">Buildings Statistics (Constructed / Lost / Destroyed)</translatableAttribute>
|
||||
</object>
|
||||
<object name="totalBuildingsHeading" type="text" style="ModernTabLabelText">
|
||||
Total
|
||||
<translatableAttribute id="caption">Total</translatableAttribute>
|
||||
</object>
|
||||
<object name="houseBuildingsHeading" type="text" style="ModernTabLabelText">
|
||||
Houses
|
||||
<translatableAttribute id="caption">Houses</translatableAttribute>
|
||||
</object>
|
||||
<object name="economicBuildingsHeading" type="text" style="ModernTabLabelText">
|
||||
Economic
|
||||
<translatableAttribute id="caption">Economic</translatableAttribute>
|
||||
</object>
|
||||
<object name="outpostBuildingsHeading" type="text" style="ModernTabLabelText">
|
||||
Outposts
|
||||
<translatableAttribute id="caption">Outposts</translatableAttribute>
|
||||
</object>
|
||||
<object name="militaryBuildingsHeading" type="text" style="ModernTabLabelText">
|
||||
Military
|
||||
<translatableAttribute id="caption">Military</translatableAttribute>
|
||||
</object>
|
||||
<object name="fortressBuildingsHeading" type="text" style="ModernTabLabelText">
|
||||
Fortresses
|
||||
<translatableAttribute id="caption">Fortresses</translatableAttribute>
|
||||
</object>
|
||||
<object name="civCentreBuildingsHeading" type="text" style="ModernTabLabelText">
|
||||
Civ Centers
|
||||
<translatableAttribute id="caption">Civ Centers</translatableAttribute>
|
||||
</object>
|
||||
<object name="wonderBuildingsHeading" type="text" style="ModernTabLabelText">
|
||||
Wonders
|
||||
<translatableAttribute id="caption">Wonders</translatableAttribute>
|
||||
</object>
|
||||
|
||||
</object>
|
||||
@ -387,31 +399,31 @@
|
||||
|
||||
<object size="0 0 100% 100%-50">
|
||||
<object name="playerName2Heading" type="text" style="ModernLeftTabLabelText">
|
||||
Player name
|
||||
<translatableAttribute id="caption">Player name</translatableAttribute>
|
||||
</object>
|
||||
<object name="unitsHeading" type="text" style="ModernTabLabelText">
|
||||
Units Statistics (Trained / Lost / Killed)
|
||||
<translatableAttribute id="caption">Units Statistics (Trained / Lost / Killed)</translatableAttribute>
|
||||
</object>
|
||||
<object name="totalUnitsHeading" type="text" style="ModernTabLabelText">
|
||||
Total
|
||||
<translatableAttribute id="caption">Total</translatableAttribute>
|
||||
</object>
|
||||
<object name="infantryUnitsHeading" type="text" style="ModernTabLabelText">
|
||||
Infantry
|
||||
<translatableAttribute id="caption">Infantry</translatableAttribute>
|
||||
</object>
|
||||
<object name="workerUnitsHeading" type="text" style="ModernTabLabelText">
|
||||
Worker
|
||||
<translatableAttribute id="caption">Worker</translatableAttribute>
|
||||
</object>
|
||||
<object name="cavalryUnitsHeading" type="text" style="ModernTabLabelText">
|
||||
Cavalry
|
||||
<translatableAttribute id="caption">Cavalry</translatableAttribute>
|
||||
</object>
|
||||
<object name="championUnitsHeading" type="text" style="ModernTabLabelText">
|
||||
Champion
|
||||
<translatableAttribute id="caption">Champion</translatableAttribute>
|
||||
</object>
|
||||
<object name="heroesUnitsHeading" type="text" style="ModernTabLabelText">
|
||||
Heroes
|
||||
<translatableAttribute id="caption">Heroes</translatableAttribute>
|
||||
</object>
|
||||
<object name="navyUnitsHeading" type="text" style="ModernTabLabelText">
|
||||
Navy
|
||||
<translatableAttribute id="caption">Navy</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
@ -548,31 +560,31 @@
|
||||
|
||||
<object size="0 0 100% 100%-50">
|
||||
<object name="playerName3Heading" type="text" style="ModernLeftTabLabelText">
|
||||
Player name
|
||||
<translatableAttribute id="caption">Player name</translatableAttribute>
|
||||
</object>
|
||||
<object name="resourceHeading" type="text" style="ModernTabLabelText">
|
||||
Resource Statistics (Gathered / Used)
|
||||
<translatableAttribute id="caption">Resource Statistics (Gathered / Used)</translatableAttribute>
|
||||
</object>
|
||||
<object name="foodGatheredHeading" type="text" style="ModernTabLabelText">
|
||||
Food
|
||||
<translatableAttribute id="caption">Food</translatableAttribute>
|
||||
</object>
|
||||
<object name="woodGatheredHeading" type="text" style="ModernTabLabelText">
|
||||
Wood
|
||||
<translatableAttribute id="caption">Wood</translatableAttribute>
|
||||
</object>
|
||||
<object name="stoneGatheredHeading" type="text" style="ModernTabLabelText">
|
||||
Stone
|
||||
<translatableAttribute id="caption">Stone</translatableAttribute>
|
||||
</object>
|
||||
<object name="metalGatheredHeading" type="text" style="ModernTabLabelText">
|
||||
Metal
|
||||
<translatableAttribute id="caption">Metal</translatableAttribute>
|
||||
</object>
|
||||
<object name="totalGatheredHeading" type="text" style="ModernTabLabelText">
|
||||
Total
|
||||
<translatableAttribute id="caption">Total</translatableAttribute>
|
||||
</object>
|
||||
<object name="treasuresCollectedHeading" type="text" style="ModernTabLabelText">
|
||||
Treasures collected
|
||||
<translatableAttribute id="caption">Treasures collected</translatableAttribute>
|
||||
</object>
|
||||
<object name="resourcesTributedHeading" type="text" style="ModernTabLabelText">
|
||||
Tributes (Sent / Received)
|
||||
<translatableAttribute id="caption">Tributes (Sent / Received)</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
@ -709,25 +721,25 @@
|
||||
|
||||
<object size="0 0 100% 100%-50">
|
||||
<object name="playerName4Heading" type="text" style="ModernLeftTabLabelText">
|
||||
Player name
|
||||
<translatableAttribute id="caption">Player name</translatableAttribute>
|
||||
</object>
|
||||
<object name="exchangedFoodHeading" type="text" style="ModernTabLabelText">
|
||||
Food exchanged
|
||||
<translatableAttribute id="caption">Food exchanged</translatableAttribute>
|
||||
</object>
|
||||
<object name="exchangedWoodHeading" type="text" style="ModernTabLabelText">
|
||||
Wood exchanged
|
||||
<translatableAttribute id="caption">Wood exchanged</translatableAttribute>
|
||||
</object>
|
||||
<object name="exchangedStoneHeading" type="text" style="ModernTabLabelText">
|
||||
Stone exchanged
|
||||
<translatableAttribute id="caption">Stone exchanged</translatableAttribute>
|
||||
</object>
|
||||
<object name="exchangedMetalHeading" type="text" style="ModernTabLabelText">
|
||||
Metal exchanged
|
||||
<translatableAttribute id="caption">Metal exchanged</translatableAttribute>
|
||||
</object>
|
||||
<object name="barterEfficiencyHeading" type="text" style="ModernTabLabelText">
|
||||
Barter efficiency
|
||||
<translatableAttribute id="caption">Barter efficiency</translatableAttribute>
|
||||
</object>
|
||||
<object name="tradeIncomeHeading" type="text" style="ModernTabLabelText">
|
||||
Trade income
|
||||
<translatableAttribute id="caption">Trade income</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
@ -855,19 +867,19 @@
|
||||
|
||||
<object size="0 0 100% 100%-50">
|
||||
<object name="playerName5Heading" type="text" style="ModernLeftTabLabelText">
|
||||
Player name
|
||||
<translatableAttribute id="caption">Player name</translatableAttribute>
|
||||
</object>
|
||||
<object name="vegetarianRatioHeading" type="text" style="ModernTabLabelText">
|
||||
Vegetarian ratio
|
||||
<translatableAttribute id="caption">Vegetarian\nratio</translatableAttribute>
|
||||
</object>
|
||||
<object name="feminisationHeading" type="text" style="ModernTabLabelText">
|
||||
Feminisation
|
||||
<translatableAttribute id="caption">Feminisation</translatableAttribute>
|
||||
</object>
|
||||
<object name="killDeathRatioHeading" type="text" style="ModernTabLabelText">
|
||||
Kill / Death ratio
|
||||
<translatableAttribute id="caption">Kill / Death\nratio</translatableAttribute>
|
||||
</object>
|
||||
<object name="mapExplorationHeading" type="text" style="ModernTabLabelText">
|
||||
Map exploration
|
||||
<translatableAttribute id="caption">Map\nexploration</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
@ -974,7 +986,7 @@
|
||||
</object>
|
||||
|
||||
<object type="button" style="StoneButton" size="100%-164 100%-52 100%-24 100%-24">
|
||||
Continue
|
||||
<translatableAttribute id="caption">Continue</translatableAttribute>
|
||||
<action on="Press"><![CDATA[
|
||||
if(!Engine.HasXmppClient())
|
||||
{
|
||||
|
@ -64,8 +64,9 @@ BuildRestrictions.prototype.Init = function()
|
||||
*
|
||||
* Returns result object:
|
||||
* {
|
||||
* "success": true iff the placement is valid, else false
|
||||
* "message": message to display in UI for invalid placement, else empty string
|
||||
* "success": true iff the placement is valid, else false
|
||||
* "message": message to display in UI for invalid placement, else ""
|
||||
* "parameters": parameters to use in the GUI message
|
||||
* }
|
||||
*
|
||||
* Note: The entity which is used to check this should be a preview entity
|
||||
@ -79,7 +80,10 @@ BuildRestrictions.prototype.CheckPlacement = function()
|
||||
|
||||
var result = {
|
||||
"success": false,
|
||||
"message": name+" cannot be built due to unknown error",
|
||||
"message": markForTranslation("%(name)s cannot be built due to unknown error"),
|
||||
"parameters": {
|
||||
"name": name,
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: AI has no visibility info
|
||||
@ -97,7 +101,7 @@ BuildRestrictions.prototype.CheckPlacement = function()
|
||||
var explored = (cmpRangeManager.GetLosVisibility(this.entity, cmpOwnership.GetOwner(), true) != "hidden");
|
||||
if (!explored)
|
||||
{
|
||||
result.message = name+" cannot be built in unexplored area";
|
||||
result.message = markForTranslation("%(name)s cannot be built in unexplored area");
|
||||
return result; // Fail
|
||||
}
|
||||
}
|
||||
@ -145,11 +149,11 @@ BuildRestrictions.prototype.CheckPlacement = function()
|
||||
error("CheckPlacement: Error returned from CheckFoundation");
|
||||
break;
|
||||
case "fail_obstructs_foundation":
|
||||
result.message = name+" cannot be built on another building or resource";
|
||||
result.message = markForTranslation("%(name)s cannot be built on another building or resource");
|
||||
break;
|
||||
case "fail_terrain_class":
|
||||
// TODO: be more specific and/or list valid terrain?
|
||||
result.message = name+" cannot be built on invalid terrain";
|
||||
result.message = markForTranslation("%(name)s cannot be built on invalid terrain");
|
||||
}
|
||||
return result; // Fail
|
||||
}
|
||||
@ -172,19 +176,26 @@ BuildRestrictions.prototype.CheckPlacement = function()
|
||||
var territoryFail = true;
|
||||
var territoryType = "";
|
||||
if (isAlly && !this.HasTerritory("ally"))
|
||||
territoryType = "ally";
|
||||
// Translation: territoryType being displayed in a translated sentence in the form: "House cannot be built in %(territoryType)s territory.".
|
||||
territoryType = markForTranslationWithContext("Territory type", "ally");
|
||||
else if (isOwn && !this.HasTerritory("own"))
|
||||
territoryType = "own";
|
||||
// Translation: territoryType being displayed in a translated sentence in the form: "House cannot be built in %(territoryType)s territory.".
|
||||
territoryType = markForTranslationWithContext("Territory type", "own");
|
||||
else if (isNeutral && !this.HasTerritory("neutral"))
|
||||
territoryType = "neutral";
|
||||
// Translation: territoryType being displayed in a translated sentence in the form: "House cannot be built in %(territoryType)s territory.".
|
||||
territoryType = markForTranslationWithContext("Territory type", "neutral");
|
||||
else if (isEnemy && !this.HasTerritory("enemy"))
|
||||
territoryType = "enemy";
|
||||
// Translation: territoryType being displayed in a translated sentence in the form: "House cannot be built in %(territoryType)s territory.".
|
||||
territoryType = markForTranslationWithContext("Territory type", "enemy");
|
||||
else
|
||||
territoryFail = false;
|
||||
|
||||
if (territoryFail)
|
||||
{
|
||||
result.message = name+" cannot be built in "+territoryType+" territory. Valid territories: " + this.GetTerritories().join(", ");
|
||||
result.message = markForTranslation("%(name)s cannot be built in %(territoryType)s territory. Valid territories: %(validTerritories)s");
|
||||
result.parameters.territoryType = {"context": "Territory type", "message": territoryType};
|
||||
// gui code will join this array to a string
|
||||
result.parameters.validTerritories = {"context": "Territory type list", "list": this.GetTerritories()};
|
||||
return result; // Fail
|
||||
}
|
||||
|
||||
@ -218,7 +229,7 @@ BuildRestrictions.prototype.CheckPlacement = function()
|
||||
if ((cmpWaterManager.GetWaterLevel(pos.x + sz, pos.y + cz) - cmpTerrain.GetGroundLevel(pos.x + sz, pos.y + cz)) < 1.0 // front
|
||||
|| (cmpWaterManager.GetWaterLevel(pos.x - sz, pos.y - cz) - cmpTerrain.GetGroundLevel(pos.x - sz, pos.y - cz)) > 2.0) // back
|
||||
{
|
||||
result.message = name+" must be built on a valid shoreline";
|
||||
result.message = markForTranslation("%(name)s must be built on a valid shoreline");
|
||||
return result; // Fail
|
||||
}
|
||||
}
|
||||
@ -242,7 +253,9 @@ BuildRestrictions.prototype.CheckPlacement = function()
|
||||
var nearEnts = cmpRangeManager.ExecuteQuery(this.entity, 0, dist, [cmpPlayer.GetPlayerID()], IID_BuildRestrictions).filter(filter);
|
||||
if (nearEnts.length)
|
||||
{
|
||||
result.message = name+" too close to a "+cat+", must be at least "+ +this.template.Distance.MinDistance+" units away";
|
||||
result.message = markForTranslation("%(name)s too close to a %(category)s, must be at least %(distance)s meters away");
|
||||
result.parameters.category = cat;
|
||||
result.parameters.distance = this.template.Distance.MinDistance;
|
||||
return result; // Fail
|
||||
}
|
||||
}
|
||||
@ -252,7 +265,9 @@ BuildRestrictions.prototype.CheckPlacement = function()
|
||||
var nearEnts = cmpRangeManager.ExecuteQuery(this.entity, 0, dist, [cmpPlayer.GetPlayerID()], IID_BuildRestrictions).filter(filter);
|
||||
if (!nearEnts.length)
|
||||
{
|
||||
result.message = name+" too far away from a "+cat+", must be within "+ +this.template.Distance.MaxDistance+" units";
|
||||
result.message = markForTranslation("%(name)s too far from a %(category)s, must be within %(distance)s meters");
|
||||
result.parameters.category = cat;
|
||||
result.parameters.distance = this.template.Distance.MinDistance;
|
||||
return result; // Fail
|
||||
}
|
||||
}
|
||||
@ -279,4 +294,13 @@ BuildRestrictions.prototype.HasTerritory = function(territory)
|
||||
return (this.GetTerritories().indexOf(territory) != -1);
|
||||
};
|
||||
|
||||
// Translation: Territory types being displayed as part of a list like "Valid territories: own, ally".
|
||||
markForTranslationWithContext("Territory type list", "own");
|
||||
// Translation: Territory types being displayed as part of a list like "Valid territories: own, ally".
|
||||
markForTranslationWithContext("Territory type list", "ally");
|
||||
// Translation: Territory types being displayed as part of a list like "Valid territories: own, ally".
|
||||
markForTranslationWithContext("Territory type list", "neutral");
|
||||
// Translation: Territory types being displayed as part of a list like "Valid territories: own, ally".
|
||||
markForTranslationWithContext("Territory type list", "enemy");
|
||||
|
||||
Engine.RegisterComponentType(IID_BuildRestrictions, "BuildRestrictions", BuildRestrictions);
|
||||
|
@ -783,7 +783,7 @@ GuiInterface.prototype.GetNeededResources = function(player, amounts)
|
||||
GuiInterface.prototype.AddTimeNotification = function(notification)
|
||||
{
|
||||
var time = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer).GetTime();
|
||||
notification.endTime = notification.time + time;
|
||||
notification.endTime = notification.duration + time;
|
||||
notification.id = ++this.timeNotificationID;
|
||||
this.timeNotifications.push(notification);
|
||||
this.timeNotifications.sort(function (n1, n2){return n2.endTime - n1.endTime});
|
||||
@ -802,32 +802,19 @@ GuiInterface.prototype.DeleteTimeNotification = function(notificationID)
|
||||
}
|
||||
};
|
||||
|
||||
GuiInterface.prototype.GetTimeNotificationText = function(playerID)
|
||||
{
|
||||
var formatTime = function(time)
|
||||
{
|
||||
// add 1000 ms to get ceiled instead of floored millisecons
|
||||
// displaying 00:00 for a full second isn't nice
|
||||
time += 1000;
|
||||
var hours = Math.floor(time / 1000 / 60 / 60);
|
||||
var minutes = Math.floor(time / 1000 / 60) % 60;
|
||||
var seconds = Math.floor(time / 1000) % 60;
|
||||
return (hours ? hours + ':' : "") + (minutes < 10 ? '0' + minutes : minutes) + ':' + (seconds < 10 ? '0' + seconds : seconds);
|
||||
};
|
||||
GuiInterface.prototype.GetTimeNotifications = function(playerID)
|
||||
{
|
||||
var time = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer).GetTime();
|
||||
var text = "";
|
||||
for each (var n in this.timeNotifications)
|
||||
var toDelete = [];
|
||||
for (var n of this.timeNotifications)
|
||||
{
|
||||
if (time >= n.endTime)
|
||||
{
|
||||
// delete the notification and start over
|
||||
this.DeleteTimeNotification(n.id);
|
||||
return this.GetTimeNotificationText(playerID);
|
||||
}
|
||||
if (n.players.indexOf(playerID) >= 0)
|
||||
text += n.message.replace("%T",formatTime(n.endTime - time))+"\n";
|
||||
n.time = n.endTime - time;
|
||||
if (n.time < 0)
|
||||
toDelete.push(n.id);
|
||||
}
|
||||
return text;
|
||||
for (var id of toDelete)
|
||||
this.DeleteTimeNotification(id);
|
||||
return this.timeNotifications;
|
||||
};
|
||||
|
||||
GuiInterface.prototype.PushNotification = function(notification)
|
||||
@ -868,7 +855,7 @@ GuiInterface.prototype.GetFormationInfoFromTemplate = function(player, data)
|
||||
if (!template || !template.Formation)
|
||||
return r;
|
||||
r.name = template.Formation.FormationName;
|
||||
r.tooltip = template.Formation.DisabledTooltip;
|
||||
r.tooltip = template.Formation.DisabledTooltip || "";
|
||||
return r;
|
||||
};
|
||||
|
||||
@ -1027,8 +1014,9 @@ GuiInterface.prototype.DisplayRallyPoint = function(player, cmd)
|
||||
*
|
||||
* Returns result object from CheckPlacement:
|
||||
* {
|
||||
* "success": true iff the placement is valid, else false
|
||||
* "message": message to display in UI for invalid placement, else empty string
|
||||
* "success": true iff the placement is valid, else false
|
||||
* "message": message to display in UI for invalid placement, else ""
|
||||
"parameters": parameters to use in the message
|
||||
* }
|
||||
*/
|
||||
GuiInterface.prototype.SetBuildingPlacementPreview = function(player, cmd)
|
||||
@ -1036,6 +1024,7 @@ GuiInterface.prototype.SetBuildingPlacementPreview = function(player, cmd)
|
||||
var result = {
|
||||
"success": false,
|
||||
"message": "",
|
||||
"parameters": {},
|
||||
}
|
||||
|
||||
// See if we're changing template
|
||||
@ -1981,7 +1970,7 @@ var exposedFunctions = {
|
||||
"GetIncomingAttacks": 1,
|
||||
"GetNeededResources": 1,
|
||||
"GetNextNotification": 1,
|
||||
"GetTimeNotificationText": 1,
|
||||
"GetTimeNotifications": 1,
|
||||
|
||||
"GetAvailableFormations": 1,
|
||||
"GetFormationRequirements": 1,
|
||||
|
@ -36,6 +36,12 @@ Player.prototype.Init = function()
|
||||
this.cheatsEnabled = false;
|
||||
this.cheatTimeMultiplier = 1;
|
||||
this.heroes = [];
|
||||
this.resourceNames = {
|
||||
"food": markForTranslation("Food"),
|
||||
"wood": markForTranslation("Wood"),
|
||||
"metal": markForTranslation("Metal"),
|
||||
"stone": markForTranslation("Stone"),
|
||||
}
|
||||
Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager).CheckConquestCriticalEntities();
|
||||
};
|
||||
|
||||
@ -212,10 +218,38 @@ Player.prototype.SubtractResourcesOrNotify = function(amounts)
|
||||
// If we don't have enough resources, send a notification to the player
|
||||
if (amountsNeeded)
|
||||
{
|
||||
var formatted = [];
|
||||
var parameters = {};
|
||||
var i = 0;
|
||||
for (var type in amountsNeeded)
|
||||
formatted.push(amountsNeeded[type] + " " + type[0].toUpperCase() + type.substr(1) );
|
||||
var notification = {"player": this.playerID, "message": "Insufficient resources - " + formatted.join(", ")};
|
||||
{
|
||||
i++;
|
||||
parameters["resourceType"+i] = this.resourceNames[type];
|
||||
parameters["resourceAmount"+i] = amountsNeeded[type];
|
||||
}
|
||||
|
||||
var msg = "";
|
||||
// when marking strings for translations, you need to include the actual string,
|
||||
// not some way to derive the string
|
||||
if (i < 1)
|
||||
warn("Amounts needed but no amounts given?");
|
||||
else if (i == 1)
|
||||
msg = markForTranslation("Insufficient resources - %(resourceAmount1)s %(resourceType1)s");
|
||||
else if (i == 2)
|
||||
msg = markForTranslation("Insufficient resources - %(resourceAmount1)s %(resourceType1)s, %(resourceAmount2)s %(resourceType2)s");
|
||||
else if (i == 3)
|
||||
msg = markForTranslation("Insufficient resources - %(resourceAmount1)s %(resourceType1)s, %(resourceAmount2)s %(resourceType2)s, %(resourceAmount3)s %(resourceType3)s");
|
||||
else if (i == 4)
|
||||
msg = markForTranslation("Insufficient resources - %(resourceAmount1)s %(resourceType1)s, %(resourceAmount2)s %(resourceType2)s, %(resourceAmount3)s %(resourceType3)s, %(resourceAmount4)s %(resourceType4)s");
|
||||
else
|
||||
warn("Localisation: Strings are not localised for more than 4 resources");
|
||||
|
||||
var notification = {
|
||||
"player": this.playerID,
|
||||
"message": msg,
|
||||
"parameters": parameters,
|
||||
"translateMessage": true,
|
||||
"translateParameters": ["resourceType1", "resourceType2", "resourceType3", "resourceType4"],
|
||||
};
|
||||
var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
|
||||
cmpGUIInterface.PushNotification(notification);
|
||||
return false;
|
||||
|
@ -50,14 +50,18 @@ Wonder.prototype.ResetTimer = function(ownerID)
|
||||
players.push(i);
|
||||
|
||||
this.otherMessage = cmpGuiInterface.AddTimeNotification({
|
||||
"message": cmpPlayer.GetName() + " will have won in %T",
|
||||
"message": markForTranslation("%(player)s will have won in %(time)s"),
|
||||
"players": players,
|
||||
"time": +this.template.TimeTillVictory*1000
|
||||
"duration": +this.template.TimeTillVictory*1000,
|
||||
"parameters": {"player": cmpPlayer.GetName()},
|
||||
"translateMessage": true,
|
||||
"translateParameters": [],
|
||||
});
|
||||
this.ownMessage = cmpGuiInterface.AddTimeNotification({
|
||||
"message": "You will have won in %T",
|
||||
"message": markForTranslation("You will have won in %(time)s"),
|
||||
"players": [ownerID],
|
||||
"time": +this.template.TimeTillVictory*1000
|
||||
"duration": +this.template.TimeTillVictory*1000,
|
||||
"translateMessage": true,
|
||||
});
|
||||
this.timer = cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_EndGameManager, "MarkPlayerAsWon", +this.template.TimeTillVictory*1000, ownerID);
|
||||
};
|
||||
|
@ -899,7 +899,7 @@ void GuiScriptingInit(ScriptInterface& scriptInterface)
|
||||
scriptInterface.RegisterFunction<bool, &IsPaused>("IsPaused");
|
||||
scriptInterface.RegisterFunction<void, bool, &SetPaused>("SetPaused");
|
||||
scriptInterface.RegisterFunction<int, &GetFps>("GetFPS");
|
||||
scriptInterface.RegisterFunction<std::wstring, int, &GetBuildTimestamp>("BuildTime");
|
||||
scriptInterface.RegisterFunction<std::wstring, int, &GetBuildTimestamp>("GetBuildTimestamp");
|
||||
|
||||
// User report functions
|
||||
scriptInterface.RegisterFunction<bool, &IsUserReportEnabled>("IsUserReportEnabled");
|
||||
|
Loading…
Reference in New Issue
Block a user