localization!

This commit is contained in:
Ellpeck 2020-06-02 14:16:14 +02:00
parent 39409d3b96
commit a53070ba4d
12 changed files with 107 additions and 23 deletions

View file

@ -35,8 +35,9 @@ namespace TouchyTickets.Attractions {
} }
public float Update(GameTime time, TimeSpan passed, ParkMap map, Point position) { public float Update(GameTime time, TimeSpan passed, ParkMap map, Point position) {
var genRate = this.Type.GenerationPerSecond; var genRate = this.Type.GetGenerationRate();
// only apply dynamic upgrades here, static ones go into the type!
if (Upgrade.FoodCourtModifier.IsActive() && this.GetSurrounding(map, position, AttractionType.FoodCourt).Any()) if (Upgrade.FoodCourtModifier.IsActive() && this.GetSurrounding(map, position, AttractionType.FoodCourt).Any())
genRate *= 3; genRate *= 3;

View file

@ -17,7 +17,7 @@ namespace TouchyTickets.Attractions {
public int Width => this.Area.GetLength(1); public int Width => this.Area.GetLength(1);
public int Height => this.Area.GetLength(0); public int Height => this.Area.GetLength(0);
public readonly TextureRegion TextureRegion; public readonly TextureRegion TextureRegion;
public readonly float GenerationPerSecond; private readonly float generationPerSecond;
public readonly long InitialPrice; public readonly long InitialPrice;
private readonly Constructor create; private readonly Constructor create;
@ -25,7 +25,7 @@ namespace TouchyTickets.Attractions {
this.Name = name; this.Name = name;
this.Area = area; this.Area = area;
this.TextureRegion = texture; this.TextureRegion = texture;
this.GenerationPerSecond = generationPerSecond; this.generationPerSecond = generationPerSecond;
this.InitialPrice = initialPrice; this.InitialPrice = initialPrice;
this.create = constructor ?? (t => new Attraction(t)); this.create = constructor ?? (t => new Attraction(t));
} }
@ -34,6 +34,15 @@ namespace TouchyTickets.Attractions {
return this.create(this); return this.create(this);
} }
public float GetGenerationRate() {
var genRate = this.generationPerSecond;
if (this == FerrisWheel && Upgrade.FerrisWheelModifier.IsActive())
genRate *= 4;
return genRate;
}
private static AttractionType Register(AttractionType type) { private static AttractionType Register(AttractionType type) {
Attractions.Add(type.Name, type); Attractions.Add(type.Name, type);
return type; return type;

View file

@ -40,3 +40,6 @@
/processor:TextureProcessor /processor:TextureProcessor
/build:Textures/Tiles.png /build:Textures/Tiles.png
#begin Localization/Localization.json
/copy:Localization/Localization.json

View file

@ -0,0 +1,9 @@
{
"exclude": [
"obj/",
"bin/"
],
"overrides": {
".json": "Copy"
}
}

View file

@ -0,0 +1,23 @@
{
"Back": "Back",
"Place": "Place",
"EarnStar": "Earn <i star>",
"RequiresTickets": "Requires {0}<i ticket>",
"Carousel": "Carousel",
"FoodCourt": "Food Court",
"FerrisWheel": "Ferris Wheel",
"MapSize1": "Big Park",
"MapSize1Description": "Increases your park's buildable area",
"MapSize2": "Bigger Park",
"MapSize2Description": "Increases your park's buildable area more",
"MapSize3": "Biggest Park",
"MapSize3Description": "Increases your park's buildable area even more",
"MapSize4": "Biggester Park",
"MapSize4Description": "Increases your park's buildable area even more",
"MapSize5": "Biggestest Park",
"MapSize5Description": "Increases your park's buildable area to the maximum",
"FoodCourtModifier": "Tasty Treats",
"FoodCourtModifierDescription": "Triples ticket sales for all attractions adjacent to food courts",
"FerrisWheelModifier": "Crowded Pods",
"FerrisWheelModifierDescription": "Quadruples ticket sales for ferris wheels. Who cares about fire safety?"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using Microsoft.Xna.Framework;
using MLEM.Startup;
using Newtonsoft.Json;
namespace TouchyTickets {
public static class Localization {
private static readonly Dictionary<string, string> Strings;
static Localization() {
var location = GameImpl.Instance.Content.RootDirectory + "/Localization/Localization";
var culture = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
foreach (var path in new[] {$"{location}.{culture}.json", $"{location}.json"}) {
try {
using (var reader = new JsonTextReader(new StreamReader(TitleContainer.OpenStream(path)))) {
var ret = SaveHandler.Serializer.Deserialize<Dictionary<string, string>>(reader);
if (ret == null)
continue;
Strings = ret;
break;
}
} catch (Exception) {
// move on to the next path
}
}
}
public static string Get(string key) {
return Strings.TryGetValue(key, out var ret) ? ret : $"?{key}?";
}
}
}

View file

@ -158,6 +158,8 @@ namespace TouchyTickets {
} }
public Attraction GetAttractionAt(Point position) { public Attraction GetAttractionAt(Point position) {
if (position.X < 0 || position.Y < 0 || position.X >= this.Width || position.Y >= this.Height)
return null;
return this.attractionGrid[position.X, position.Y]; return this.attractionGrid[position.X, position.Y];
} }

View file

@ -8,7 +8,7 @@ using Newtonsoft.Json;
namespace TouchyTickets { namespace TouchyTickets {
public static class SaveHandler { public static class SaveHandler {
private static readonly JsonSerializer Serializer = JsonSerializer.Create(new JsonSerializerSettings { public static readonly JsonSerializer Serializer = JsonSerializer.Create(new JsonSerializerSettings {
DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate, DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate,
TypeNameHandling = TypeNameHandling.Auto, TypeNameHandling = TypeNameHandling.Auto,
Formatting = Formatting.Indented Formatting = Formatting.Indented

View file

@ -94,7 +94,7 @@ namespace TouchyTickets {
}, },
OnPressed = e => { OnPressed = e => {
var backUi = new Group(Anchor.BottomLeft, new Vector2(1)); var backUi = new Group(Anchor.BottomLeft, new Vector2(1));
backUi.AddChild(new Button(Anchor.AutoInlineIgnoreOverflow, new Vector2(1, 40), "Back") { backUi.AddChild(new Button(Anchor.AutoInlineIgnoreOverflow, new Vector2(1, 40), Localization.Get("Back")) {
OnPressed = e2 => this.FadeUi(false, () => this.uiSystem.Remove(e2.Root.Name)) OnPressed = e2 => this.FadeUi(false, () => this.uiSystem.Remove(e2.Root.Name))
}); });
// we want this to render below the main ui while it fades away // we want this to render below the main ui while it fades away
@ -123,10 +123,10 @@ namespace TouchyTickets {
map.PlacingPosition = new Point(MathHelper.Clamp(posX, 0, map.Width), MathHelper.Clamp(posY, 0, map.Height)); map.PlacingPosition = new Point(MathHelper.Clamp(posX, 0, map.Width), MathHelper.Clamp(posY, 0, map.Height));
var yesNoUi = new Group(Anchor.BottomLeft, new Vector2(1)); var yesNoUi = new Group(Anchor.BottomLeft, new Vector2(1));
yesNoUi.AddChild(new Button(Anchor.AutoInlineIgnoreOverflow, new Vector2(0.5F, 40), "Back") { yesNoUi.AddChild(new Button(Anchor.AutoInlineIgnoreOverflow, new Vector2(0.5F, 40), Localization.Get("Back")) {
OnPressed = e2 => this.FadeUi(false, () => this.uiSystem.Remove(e2.Root.Name)) OnPressed = e2 => this.FadeUi(false, () => this.uiSystem.Remove(e2.Root.Name))
}); });
yesNoUi.AddChild(new Button(Anchor.AutoInlineIgnoreOverflow, new Vector2(0.5F, 40), "Place") { yesNoUi.AddChild(new Button(Anchor.AutoInlineIgnoreOverflow, new Vector2(0.5F, 40), Localization.Get("Place")) {
OnPressed = e2 => { OnPressed = e2 => {
GameImpl.Instance.Tickets -= price; GameImpl.Instance.Tickets -= price;
map.Place(map.PlacingPosition, map.PlacingAttraction); map.Place(map.PlacingPosition, map.PlacingAttraction);
@ -150,13 +150,12 @@ namespace TouchyTickets {
button.IsDisabled = GameImpl.Instance.Tickets < price; button.IsDisabled = GameImpl.Instance.Tickets < price;
}; };
var center = button.AddChild(new Group(Anchor.Center, new Vector2(0.8F, 1), false) {CanBeMoused = false}); var center = button.AddChild(new Group(Anchor.Center, new Vector2(0.8F, 1), false) {CanBeMoused = false});
center.AddChild(new Paragraph(Anchor.AutoCenter, 1, attraction.Key, true)); center.AddChild(new Paragraph(Anchor.AutoCenter, 1, Localization.Get(attraction.Key), true));
center.AddChild(new Paragraph(Anchor.AutoCenter, 1, attraction.Value.GenerationPerSecond + "<i ticket>/s", true) {TextScale = 0.08F}); center.AddChild(new Paragraph(Anchor.AutoCenter, 1, p => attraction.Value.GetGenerationRate() + "<i ticket>/s", true) {TextScale = 0.08F});
var image = button.AddChild(new Image(Anchor.CenterLeft, new Vector2(1), attraction.Value.TextureRegion) { button.AddChild(new Image(Anchor.CenterLeft, new Vector2(40), attraction.Value.TextureRegion) {
Padding = new Vector2(4) Padding = new Vector2(4)
}); });
button.OnAreaUpdated += e => image.Size = new Vector2(e.DisplayArea.Height / e.Scale); button.AddChild(new Paragraph(Anchor.CenterRight, 1, p => PrettyPrintNumber(price) + "<i ticket>", true));
button.AddChild(new Paragraph(Anchor.CenterRight, 1, p => price + "<i ticket>", true));
} }
this.uiSystem.Add("Buy", buyUi); this.uiSystem.Add("Buy", buyUi);
@ -167,7 +166,7 @@ namespace TouchyTickets {
}; };
var upgradeHeader = upgradeUi.AddChild(new Group(Anchor.AutoLeft, new Vector2(1, 0.25F), false)); var upgradeHeader = upgradeUi.AddChild(new Group(Anchor.AutoLeft, new Vector2(1, 0.25F), false));
upgradeHeader.AddChild(new Paragraph(Anchor.AutoCenter, 1, p => GameImpl.Instance.Stars + "<i star>", true) {TextScale = 0.3F}); upgradeHeader.AddChild(new Paragraph(Anchor.AutoCenter, 1, p => GameImpl.Instance.Stars + "<i star>", true) {TextScale = 0.3F});
upgradeHeader.AddChild(new Button(Anchor.AutoCenter, new Vector2(0.8F, 20), "Earn <i star>") { upgradeHeader.AddChild(new Button(Anchor.AutoCenter, new Vector2(0.8F, 20), Localization.Get("EarnStar")) {
PositionOffset = new Vector2(0, 4), PositionOffset = new Vector2(0, 4),
OnUpdated = (e, time) => ((Button) e).IsDisabled = GameImpl.Instance.Tickets < GameImpl.Instance.GetStarPrice(), OnUpdated = (e, time) => ((Button) e).IsDisabled = GameImpl.Instance.Tickets < GameImpl.Instance.GetStarPrice(),
OnPressed = e => { OnPressed = e => {
@ -178,14 +177,15 @@ namespace TouchyTickets {
game.Tickets = 0; game.Tickets = 0;
} }
}); });
upgradeHeader.AddChild(new Paragraph(Anchor.AutoCenter, 1, p => $"Requires {PrettyPrintNumber(GameImpl.Instance.GetStarPrice())}<i ticket>", true) { upgradeHeader.AddChild(new Paragraph(Anchor.AutoCenter, 1, p => string.Format(Localization.Get("RequiresTickets"), PrettyPrintNumber(GameImpl.Instance.GetStarPrice())), true) {
PositionOffset = new Vector2(0, 2) PositionOffset = new Vector2(0, 2)
}); });
var upgradeList = upgradeUi.AddChild(new Panel(Anchor.AutoLeft, new Vector2(1, 0.75F), Vector2.Zero, false, true, new Point(10, 30), false) { var upgradeList = upgradeUi.AddChild(new Panel(Anchor.AutoLeft, new Vector2(1, 0.75F), Vector2.Zero, false, true, new Point(10, 30), false) {
ChildPadding = new Padding(5, 15, 5, 5) ChildPadding = new Padding(5, 15, 5, 5)
}); });
foreach (var upgrade in Upgrade.Upgrades.Values) { foreach (var upgrade in Upgrade.Upgrades.Values) {
var button = upgradeList.AddChild(new Button(Anchor.AutoLeft, new Vector2(1, 40)) { var button = upgradeList.AddChild(new Button(Anchor.AutoLeft, new Vector2(1)) {
SetHeightBasedOnChildren = true,
ChildPadding = new Vector2(4), ChildPadding = new Vector2(4),
OnPressed = e => { OnPressed = e => {
GameImpl.Instance.Stars--; GameImpl.Instance.Stars--;
@ -198,14 +198,13 @@ namespace TouchyTickets {
button.IsHidden = upgrade.IsActive() || upgrade.Dependencies.Any(u => !u.IsActive()); button.IsHidden = upgrade.IsActive() || upgrade.Dependencies.Any(u => !u.IsActive());
button.IsDisabled = GameImpl.Instance.Stars < upgrade.Price; button.IsDisabled = GameImpl.Instance.Stars < upgrade.Price;
}; };
var center = button.AddChild(new Group(Anchor.Center, new Vector2(0.8F, 1), false) {CanBeMoused = false}); button.AddChild(new Paragraph(Anchor.TopCenter, 1, Localization.Get(upgrade.Name), true));
center.AddChild(new Paragraph(Anchor.AutoCenter, 1, upgrade.Name, true)); button.AddChild(new Image(Anchor.CenterLeft, new Vector2(0.2F, 40), upgrade.Texture) {
//center.AddChild(new Paragraph(Anchor.AutoCenter, 1, upgrade.Description, true) {TextScale = 0.08F});
var image = button.AddChild(new Image(Anchor.CenterLeft, new Vector2(1), upgrade.Texture) {
Padding = new Vector2(4) Padding = new Vector2(4)
}); });
button.OnAreaUpdated += e => image.Size = new Vector2(e.DisplayArea.Height / e.Scale); var right = button.AddChild(new Group(Anchor.TopRight, new Vector2(0.8F, 1)) {CanBeMoused = false});
button.AddChild(new Paragraph(Anchor.CenterRight, 1, p => upgrade.Price + "<i star>", true)); right.AddChild(new Paragraph(Anchor.TopRight, 1, p => upgrade.Price + "<i star>", true));
right.AddChild(new Paragraph(Anchor.AutoLeft, 1, Localization.Get(upgrade.Name + "Description"), true) {TextScale = 0.08F});
} }
this.uiSystem.Add("Upgrade", upgradeUi); this.uiSystem.Add("Upgrade", upgradeUi);

View file

@ -8,9 +8,10 @@ namespace TouchyTickets {
public class Upgrade { public class Upgrade {
public static readonly Dictionary<string, Upgrade> Upgrades = new Dictionary<string, Upgrade>(); public static readonly Dictionary<string, Upgrade> Upgrades = new Dictionary<string, Upgrade>();
public static readonly Upgrade[] MapSize = RegisterTiers("MapSize", 10, 1, 0.5F, Ui.Texture[0, 3]); public static readonly Upgrade[] MapSize = RegisterTiers("MapSize", 5, 1, 0.5F, Ui.Texture[0, 3]);
public static readonly Upgrade FoodCourtModifier = Register(new Upgrade("FoodCourtModifier", 1, Ui.Texture[1, 3])); public static readonly Upgrade FoodCourtModifier = Register(new Upgrade("FoodCourtModifier", 1, Ui.Texture[1, 3]));
public static readonly Upgrade FerrisWheelModifier = Register(new Upgrade("FerrisWheelModifier", 1, Ui.Texture[2, 3]));
public readonly string Name; public readonly string Name;
public readonly int Price; public readonly int Price;
public readonly TextureRegion Texture; public readonly TextureRegion Texture;