diff --git a/TouchyTickets/Attractions/Attraction.cs b/TouchyTickets/Attractions/Attraction.cs index 4b74feb..62a2d97 100644 --- a/TouchyTickets/Attractions/Attraction.cs +++ b/TouchyTickets/Attractions/Attraction.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Runtime.Serialization; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using MLEM.Extensions; +using MLEM.Misc; using MLEM.Startup; using MLEM.Textures; @@ -32,13 +34,30 @@ namespace TouchyTickets.Attractions { } } - public void Update(GameTime time, TimeSpan passed) { - this.ticketPercentage += this.Type.GenerationPerSecond * (float) passed.TotalSeconds; + public float Update(GameTime time, TimeSpan passed, ParkMap map, Point position) { + var genRate = this.Type.GenerationPerSecond; + + if (Upgrade.FoodCourtModifier.IsActive() && this.GetSurrounding(map, position, AttractionType.FoodCourt).Any()) + genRate *= 3; + + this.ticketPercentage += genRate * (float) passed.TotalSeconds; var amount = this.ticketPercentage.Floor(); if (amount > 0) { GameImpl.Instance.Tickets += amount; this.ticketPercentage -= amount; } + // return the generation rate per second + return genRate; + } + + public IEnumerable GetSurrounding(ParkMap map, Point position, AttractionType type) { + foreach (var tile in this.GetCoveredTiles()) { + foreach (var dir in Direction2Helper.Adjacent) { + var other = map.GetAttractionAt(position + tile + dir.Offset()); + if (other != null && other != this && other.Type == type) + yield return other; + } + } } } diff --git a/TouchyTickets/Attractions/AttractionType.cs b/TouchyTickets/Attractions/AttractionType.cs index 642c378..8855c5a 100644 --- a/TouchyTickets/Attractions/AttractionType.cs +++ b/TouchyTickets/Attractions/AttractionType.cs @@ -8,12 +8,9 @@ namespace TouchyTickets.Attractions { public class AttractionType { public static readonly Dictionary Attractions = new Dictionary(); - - static AttractionType() { - Register(new AttractionType("Carousel", new[,] {{true}}, Attraction.Texture[0, 0, 1, 1], 0.5F, 50)); - Register(new AttractionType("FoodCourt", new[,] {{true, true}}, Attraction.Texture[1, 0, 2, 1], 1.1F, 300)); - Register(new AttractionType("FerrisWheel", new[,] {{true, true}, {true, true}}, Attraction.Texture[0, 1, 2, 2], 3.5F, 2000)); - } + public static readonly AttractionType Carousel = Register(new AttractionType("Carousel", new[,] {{true}}, Attraction.Texture[0, 0, 1, 1], 0.5F, 50)); + public static readonly AttractionType FoodCourt = Register(new AttractionType("FoodCourt", new[,] {{true, true}}, Attraction.Texture[1, 0, 2, 1], 1.1F, 300)); + public static readonly AttractionType FerrisWheel = Register(new AttractionType("FerrisWheel", new[,] {{true, true}, {true, true}}, Attraction.Texture[0, 1, 2, 2], 3.5F, 2000)); public readonly string Name; public readonly bool[,] Area; @@ -37,8 +34,9 @@ namespace TouchyTickets.Attractions { return this.create(this); } - private static void Register(AttractionType type) { + private static AttractionType Register(AttractionType type) { Attractions.Add(type.Name, type); + return type; } public delegate Attraction Constructor(AttractionType type); diff --git a/TouchyTickets/Content/Textures/Ui.aseprite b/TouchyTickets/Content/Textures/Ui.aseprite index e838644..c8ffca6 100644 Binary files a/TouchyTickets/Content/Textures/Ui.aseprite and b/TouchyTickets/Content/Textures/Ui.aseprite differ diff --git a/TouchyTickets/Content/Textures/Ui.png b/TouchyTickets/Content/Textures/Ui.png index 5c4e6eb..ac06e86 100644 Binary files a/TouchyTickets/Content/Textures/Ui.png and b/TouchyTickets/Content/Textures/Ui.png differ diff --git a/TouchyTickets/GameImpl.cs b/TouchyTickets/GameImpl.cs index 5a80ebd..b702fcb 100644 --- a/TouchyTickets/GameImpl.cs +++ b/TouchyTickets/GameImpl.cs @@ -8,7 +8,6 @@ using MLEM.Extensions; using MLEM.Font; using MLEM.Startup; using TouchyTickets.Attractions; -using TouchyTickets.Upgrades; namespace TouchyTickets { public class GameImpl : MlemGame { diff --git a/TouchyTickets/ParkMap.cs b/TouchyTickets/ParkMap.cs index 659d442..7463100 100644 --- a/TouchyTickets/ParkMap.cs +++ b/TouchyTickets/ParkMap.cs @@ -25,6 +25,7 @@ namespace TouchyTickets { private readonly List<(Point, Attraction)> attractions = new List<(Point, Attraction)>(); private readonly Dictionary treePositions = new Dictionary(); private readonly Dictionary fencePositions = new Dictionary(); + private readonly Attraction[,] attractionGrid; public float TicketsPerSecond { get; private set; } public Attraction PlacingAttraction; @@ -34,6 +35,7 @@ namespace TouchyTickets { public ParkMap(int width, int height) { this.Width = width; this.Height = height; + this.attractionGrid = new Attraction[width, height]; // set up trees var random = new Random(); @@ -65,9 +67,9 @@ namespace TouchyTickets { public void Update(GameTime time, TimeSpan passed) { var tickets = 0F; - foreach (var (_, attraction) in this.attractions) { - attraction.Update(time, passed); - tickets += attraction.Type.GenerationPerSecond; + foreach (var (pos, attraction) in this.attractions) { + var genPerSecond = attraction.Update(time, passed, this, pos); + tickets += genPerSecond; } this.TicketsPerSecond = tickets; @@ -150,25 +152,24 @@ namespace TouchyTickets { } public void Place(Point position, Attraction attraction) { - this.attractions.RemoveAll(pa => pa.Item1 == position); + foreach (var (x, y) in attraction.GetCoveredTiles()) + this.attractionGrid[position.X + x, position.Y + y] = attraction; this.attractions.Add((position, attraction)); } public Attraction GetAttractionAt(Point position) { - foreach (var (pos, attraction) in this.attractions) { - if (attraction.GetCoveredTiles().Any(p => pos + p == position)) - return attraction; - } - return null; + return this.attractionGrid[position.X, position.Y]; } public int GetAttractionAmount(AttractionType type) { return this.attractions.Count(a => a.Item2.Type == type); } - public void CopyAttractionsFrom(ParkMap other) { - foreach (var (pos, attraction) in other.attractions) - this.Place(pos, attraction); + public ParkMap Copy(int? newWidth = null, int? newHeight = null) { + var newMap = new ParkMap(newWidth ?? this.Width, newHeight ?? this.Height); + foreach (var (pos, attraction) in this.attractions) + newMap.Place(pos, attraction); + return newMap; } } diff --git a/TouchyTickets/SaveHandler.cs b/TouchyTickets/SaveHandler.cs index 3e3a633..3b1eccb 100644 --- a/TouchyTickets/SaveHandler.cs +++ b/TouchyTickets/SaveHandler.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Numerics; using Newtonsoft.Json; -using TouchyTickets.Upgrades; namespace TouchyTickets { public static class SaveHandler { @@ -40,7 +39,7 @@ namespace TouchyTickets { var data = Serializer.Deserialize(stream); game.Tickets = data.Tickets; game.LastUpdate = data.LastUpdate; - game.Map = data.Map; + game.Map = data.Map.Copy(); game.Stars = data.Stars; game.TimesRestarted = data.TimesRestarted; game.AppliedUpgrades.Clear(); diff --git a/TouchyTickets/Ui.cs b/TouchyTickets/Ui.cs index 6ea83e3..330f0a2 100644 --- a/TouchyTickets/Ui.cs +++ b/TouchyTickets/Ui.cs @@ -16,7 +16,6 @@ using MLEM.Textures; using MLEM.Ui; using MLEM.Ui.Elements; using TouchyTickets.Attractions; -using TouchyTickets.Upgrades; namespace TouchyTickets { public class Ui { @@ -196,7 +195,7 @@ namespace TouchyTickets { }); button.OnUpdated += (e, time) => { // we want to hide if we're active, or if we still need a dependency to be active - button.IsHidden = Upgrade.IsActive(upgrade) || upgrade.Dependencies.Any(u => !Upgrade.IsActive(u)); + button.IsHidden = upgrade.IsActive() || upgrade.Dependencies.Any(u => !u.IsActive()); button.IsDisabled = GameImpl.Instance.Stars < upgrade.Price; }; var center = button.AddChild(new Group(Anchor.Center, new Vector2(0.8F, 1), false) {CanBeMoused = false}); diff --git a/TouchyTickets/Upgrade.cs b/TouchyTickets/Upgrade.cs index e005c17..0bcfb97 100644 --- a/TouchyTickets/Upgrade.cs +++ b/TouchyTickets/Upgrade.cs @@ -1,15 +1,15 @@ using System; using System.Collections.Generic; using System.Linq; -using Microsoft.Xna.Framework; using MLEM.Extensions; using MLEM.Textures; -namespace TouchyTickets.Upgrades { +namespace TouchyTickets { public class Upgrade { public static readonly Dictionary Upgrades = new Dictionary(); public static readonly Upgrade[] MapSize = RegisterTiers("MapSize", 10, 1, 0.5F, Ui.Texture[0, 3]); + public static readonly Upgrade FoodCourtModifier = Register(new Upgrade("FoodCourtModifier", 1, Ui.Texture[1, 3])); public readonly string Name; public readonly int Price; @@ -38,18 +38,17 @@ namespace TouchyTickets.Upgrades { // map size upgrades if (MapSize.Contains(this)) { var oldMap = GameImpl.Instance.Map; - var newMap = new ParkMap(oldMap.Width + 5, oldMap.Height + 5); - newMap.CopyAttractionsFrom(oldMap); - GameImpl.Instance.Map = newMap; + GameImpl.Instance.Map = oldMap.Copy(oldMap.Width + 5, oldMap.Height + 5); } } - private static void Register(Upgrade upgrade) { + private static Upgrade Register(Upgrade upgrade) { Upgrades.Add(upgrade.Name, upgrade); + return upgrade; } - public static bool IsActive(Upgrade upgrade) { - return GameImpl.Instance.AppliedUpgrades.Contains(upgrade); + public bool IsActive() { + return GameImpl.Instance.AppliedUpgrades.Contains(this); } }