added achievements!
|
@ -8,6 +8,7 @@ using Android.Gms.Common;
|
||||||
using Android.Gms.Common.Apis;
|
using Android.Gms.Common.Apis;
|
||||||
using Android.Gms.Extensions;
|
using Android.Gms.Extensions;
|
||||||
using Android.Gms.Games;
|
using Android.Gms.Games;
|
||||||
|
using Android.Gms.Games.Achievement;
|
||||||
using Android.Runtime;
|
using Android.Runtime;
|
||||||
using Android.Views;
|
using Android.Views;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
|
@ -15,12 +16,40 @@ using Coroutine;
|
||||||
using GameAnalyticsSDK;
|
using GameAnalyticsSDK;
|
||||||
using GameAnalyticsSDK.Utilities;
|
using GameAnalyticsSDK.Utilities;
|
||||||
using TouchyTickets;
|
using TouchyTickets;
|
||||||
|
using Achievement = TouchyTickets.Achievement;
|
||||||
using Uri = Android.Net.Uri;
|
using Uri = Android.Net.Uri;
|
||||||
|
|
||||||
namespace Android {
|
namespace Android {
|
||||||
public class AndroidPlatform : Platform {
|
public class AndroidPlatform : Platform {
|
||||||
|
|
||||||
public const int GooglePlayLoginRequest = 9001;
|
public const int GooglePlayLoginRequest = 9001;
|
||||||
|
public const int ShowAchievementsRequest = 9002;
|
||||||
|
|
||||||
|
private static readonly Dictionary<string, string> AchievementIds = new Dictionary<string, string> {
|
||||||
|
{"1Stars", "CgkI_Lyp7PcEEAIQAw"},
|
||||||
|
{"10Stars", "CgkI_Lyp7PcEEAIQBA"},
|
||||||
|
{"100Stars", "CgkI_Lyp7PcEEAIQBQ"},
|
||||||
|
{"FullMap", "CgkI_Lyp7PcEEAIQBg"},
|
||||||
|
{"OnlySmallRides", "CgkI_Lyp7PcEEAIQBw"},
|
||||||
|
{"OnlyRelaxedRides", "CgkI_Lyp7PcEEAIQCA"},
|
||||||
|
{"OnlyWalkingRides", "CgkI_Lyp7PcEEAIQCQ"},
|
||||||
|
{"OnlyNonTechnologyRides", "CgkI_Lyp7PcEEAIQCg"},
|
||||||
|
{"100Modifiers", "CgkI_Lyp7PcEEAIQCw"},
|
||||||
|
{"500Modifiers", "CgkI_Lyp7PcEEAIQDA"},
|
||||||
|
{"1000Modifiers", "CgkI_Lyp7PcEEAIQDQ"},
|
||||||
|
{"5000Modifiers", "CgkI_Lyp7PcEEAIQDg"},
|
||||||
|
{"1.00MTickets", "CgkI_Lyp7PcEEAIQDw"},
|
||||||
|
{"1.00BTickets", "CgkI_Lyp7PcEEAIQEA"},
|
||||||
|
{"1.00TTickets", "CgkI_Lyp7PcEEAIQEQ"},
|
||||||
|
{"1.00QTickets", "CgkI_Lyp7PcEEAIQEg"},
|
||||||
|
{"1.00QiTickets", "CgkI_Lyp7PcEEAIQEw"},
|
||||||
|
{"1.00STickets", "CgkI_Lyp7PcEEAIQFA"},
|
||||||
|
{"1.00SpTickets", "CgkI_Lyp7PcEEAIQFQ"},
|
||||||
|
{"1.00OTickets", "CgkI_Lyp7PcEEAIQFg"},
|
||||||
|
{"1.00NTickets", "CgkI_Lyp7PcEEAIQFw"},
|
||||||
|
{"1.00DTickets", "CgkI_Lyp7PcEEAIQGA"}
|
||||||
|
};
|
||||||
|
|
||||||
private readonly Activity activity;
|
private readonly Activity activity;
|
||||||
private readonly LinearLayout adLayout;
|
private readonly LinearLayout adLayout;
|
||||||
public GoogleApiClient GoogleApi { get; private set; }
|
public GoogleApiClient GoogleApi { get; private set; }
|
||||||
|
@ -59,6 +88,11 @@ namespace Android {
|
||||||
})
|
})
|
||||||
.Build();
|
.Build();
|
||||||
this.GoogleApi.Connect();
|
this.GoogleApi.Connect();
|
||||||
|
|
||||||
|
// Sanity check to ensure that all achievements are mapped
|
||||||
|
foreach (var achievement in Achievement.Achievements.Values) {
|
||||||
|
var _ = AchievementIds[achievement.Name];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AddResourceEvent(bool sink, string currency, float amount, string itemType, string itemId) {
|
public override void AddResourceEvent(bool sink, string currency, float amount, string itemType, string itemId) {
|
||||||
|
@ -77,5 +111,17 @@ namespace Android {
|
||||||
this.activity.StartActivity(new Intent(Intent.ActionView, Uri.Parse("https://play.google.com/store/apps/details?id=de.ellpeck.touchytickets")));
|
this.activity.StartActivity(new Intent(Intent.ActionView, Uri.Parse("https://play.google.com/store/apps/details?id=de.ellpeck.touchytickets")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void GainAchievement(Achievement achievement) {
|
||||||
|
if (this.GoogleApi != null)
|
||||||
|
GamesClass.Achievements.Unlock(this.GoogleApi, AchievementIds[achievement.Name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ShowAchievements() {
|
||||||
|
if (this.GoogleApi == null)
|
||||||
|
return;
|
||||||
|
var intent = GamesClass.Achievements.GetAchievementsIntent(this.GoogleApi);
|
||||||
|
this.activity.StartActivityForResult(intent, ShowAchievementsRequest);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
4
Ideas.md
|
@ -8,10 +8,6 @@
|
||||||
|
|
||||||
# Achievements
|
# Achievements
|
||||||
- Each award has a "gotten for the first time" achievement
|
- Each award has a "gotten for the first time" achievement
|
||||||
- Getting the first star
|
|
||||||
- Filling each space on the map
|
|
||||||
- Only attractions of a certain type
|
|
||||||
- High amount of modifiers on each ride
|
|
||||||
|
|
||||||
# More star upgrades
|
# More star upgrades
|
||||||
- Upgrade that allows you to set park placement templates
|
- Upgrade that allows you to set park placement templates
|
||||||
|
|
BIN
Media/Achievements/FullMap.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
Media/Achievements/Modifiers.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Media/Achievements/OnlyNonTechnologyRides.png
Normal file
After Width: | Height: | Size: 3 KiB |
BIN
Media/Achievements/OnlyRelaxingRides.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
Media/Achievements/OnlySmallRides.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
Media/Achievements/OnlyWalkingRides.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
Media/Achievements/Star.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Media/Achievements/Tickets.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
60
TouchyTickets/Achievement.cs
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using TouchyTickets.Attractions;
|
||||||
|
|
||||||
|
namespace TouchyTickets {
|
||||||
|
public class Achievement {
|
||||||
|
|
||||||
|
public static readonly Dictionary<string, Achievement> Achievements = new Dictionary<string, Achievement>();
|
||||||
|
|
||||||
|
static Achievement() {
|
||||||
|
foreach (var amount in new[] {1, 10, 100})
|
||||||
|
Register(new Achievement($"{amount}Stars", g => g.Stars >= amount));
|
||||||
|
Register(new Achievement("FullMap", g => {
|
||||||
|
for (var x = 0; x < g.Map.Width; x++) {
|
||||||
|
for (var y = 0; y < g.Map.Height; y++) {
|
||||||
|
if (g.Map.GetAttractionAt(new Point(x, y)) == null)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}));
|
||||||
|
foreach (var flag in new[] {AttractionFlags.Small, AttractionFlags.Relaxed, AttractionFlags.Walking, AttractionFlags.NonTechnology})
|
||||||
|
Register(new Achievement($"Only{flag}Rides", g => g.Map.GetAttractionAmount(null) >= 100 && g.Map.GetAttractions().All(a => a.Item2.Type.Flags.HasFlag(flag))));
|
||||||
|
foreach (var amount in new[] {100, 500, 1000, 5000})
|
||||||
|
Register(new Achievement($"{amount}Modifiers", g => g.Map.GetAttractions().All(a => a.Item2.GetModifierAmount(null) >= amount)));
|
||||||
|
for (var i = 1; i <= 10; i++) {
|
||||||
|
var amount = BigInteger.Pow(1000, i + 1);
|
||||||
|
Register(new Achievement($"{Ui.PrettyPrintNumber(amount).Replace(" ", "")}Tickets", g => g.Tickets >= amount));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly string Name;
|
||||||
|
private readonly Func<GameImpl, bool> condition;
|
||||||
|
// this value doesn't save between game runs, since achievements
|
||||||
|
// are only displayed inside of the respective stores anyway
|
||||||
|
private bool unlocked;
|
||||||
|
|
||||||
|
public Achievement(string name, Func<GameImpl, bool> condition) {
|
||||||
|
this.Name = name;
|
||||||
|
this.condition = condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update() {
|
||||||
|
if (this.unlocked)
|
||||||
|
return;
|
||||||
|
if (!this.condition.Invoke(GameImpl.Instance))
|
||||||
|
return;
|
||||||
|
GameImpl.Instance.Platform.GainAchievement(this);
|
||||||
|
this.unlocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Register(Achievement achievement) {
|
||||||
|
Achievements.Add(achievement.Name, achievement);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ namespace TouchyTickets {
|
||||||
public DateTime LastUpdate;
|
public DateTime LastUpdate;
|
||||||
public TimeSpan PlayTime;
|
public TimeSpan PlayTime;
|
||||||
private double saveCounter;
|
private double saveCounter;
|
||||||
|
private double achievementCounter;
|
||||||
|
|
||||||
public GameImpl(Platform platform) {
|
public GameImpl(Platform platform) {
|
||||||
this.Platform = platform;
|
this.Platform = platform;
|
||||||
|
@ -78,6 +79,15 @@ namespace TouchyTickets {
|
||||||
if (this.Map != null) {
|
if (this.Map != null) {
|
||||||
// update the map
|
// update the map
|
||||||
this.UpdateMapOnce();
|
this.UpdateMapOnce();
|
||||||
|
|
||||||
|
// achievements
|
||||||
|
this.achievementCounter += gameTime.ElapsedGameTime.TotalSeconds;
|
||||||
|
if (this.achievementCounter >= 5) {
|
||||||
|
this.achievementCounter = 0;
|
||||||
|
foreach (var achievement in Achievement.Achievements.Values)
|
||||||
|
achievement.Update();
|
||||||
|
}
|
||||||
|
|
||||||
// save every 3 seconds
|
// save every 3 seconds
|
||||||
this.saveCounter += gameTime.ElapsedGameTime.TotalSeconds;
|
this.saveCounter += gameTime.ElapsedGameTime.TotalSeconds;
|
||||||
if (this.saveCounter >= 3) {
|
if (this.saveCounter >= 3) {
|
||||||
|
@ -122,7 +132,7 @@ namespace TouchyTickets {
|
||||||
if (this.LastUpdate != default) {
|
if (this.LastUpdate != default) {
|
||||||
var lastTickets = this.Tickets;
|
var lastTickets = this.Tickets;
|
||||||
var lastTps = this.Map.TicketsPerSecond;
|
var lastTps = this.Map.TicketsPerSecond;
|
||||||
|
|
||||||
var passed = now - this.LastUpdate;
|
var passed = now - this.LastUpdate;
|
||||||
this.Map.Update(passed, passed.TotalSeconds >= 1);
|
this.Map.Update(passed, passed.TotalSeconds >= 1);
|
||||||
|
|
||||||
|
|
|
@ -234,6 +234,11 @@ namespace TouchyTickets {
|
||||||
return this.attractions.Any(a => modifier.IsAffected(a.Item2));
|
return this.attractions.Any(a => modifier.IsAffected(a.Item2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<(Point, Attraction)> GetAttractions() {
|
||||||
|
foreach (var attraction in this.attractions)
|
||||||
|
yield return attraction;
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsInBounds(Point pos) {
|
public bool IsInBounds(Point pos) {
|
||||||
return pos.X >= 0 && pos.Y >= 0 && pos.X < this.Width && pos.Y < this.Height;
|
return pos.X >= 0 && pos.Y >= 0 && pos.X < this.Width && pos.Y < this.Height;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,5 +11,9 @@ namespace TouchyTickets {
|
||||||
|
|
||||||
public abstract void OpenRateLink();
|
public abstract void OpenRateLink();
|
||||||
|
|
||||||
|
public abstract void GainAchievement(Achievement achievement);
|
||||||
|
|
||||||
|
public abstract void ShowAchievements();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -393,6 +393,10 @@ namespace TouchyTickets {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
num.PositionOffset = new Vector2(0, 1);
|
num.PositionOffset = new Vector2(0, 1);
|
||||||
|
optionList.AddChild(new Button(Anchor.AutoLeft, new Vector2(1, 30), Localization.Get("Achievements")) {
|
||||||
|
PositionOffset = new Vector2(0, 1),
|
||||||
|
OnPressed = e => GameImpl.Instance.Platform.ShowAchievements()
|
||||||
|
});
|
||||||
|
|
||||||
optionList.AddChild(new Paragraph(Anchor.AutoCenter, 1, Localization.Get("OtherOptions"), true) {
|
optionList.AddChild(new Paragraph(Anchor.AutoCenter, 1, Localization.Get("OtherOptions"), true) {
|
||||||
PositionOffset = new Vector2(0, 10),
|
PositionOffset = new Vector2(0, 10),
|
||||||
|
@ -733,7 +737,7 @@ namespace TouchyTickets {
|
||||||
element.Transform = Matrix.Identity;
|
element.Transform = Matrix.Identity;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string PrettyPrintNumber(BigInteger number) {
|
public static string PrettyPrintNumber(BigInteger number) {
|
||||||
for (var i = 0; i < Localization.NumberFormat.Count; i++) {
|
for (var i = 0; i < Localization.NumberFormat.Count; i++) {
|
||||||
if (number < ExpoNums[i])
|
if (number < ExpoNums[i])
|
||||||
return number.ToString(Localization.NumberFormat[i]);
|
return number.ToString(Localization.NumberFormat[i]);
|
||||||
|
|
|
@ -20,5 +20,13 @@ namespace iOS {
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void GainAchievement(Achievement achievement) {
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ShowAchievements() {
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|