foundation for productivity modifiers

This commit is contained in:
Ellpeck 2020-06-02 12:20:16 +02:00
parent 3feb5f86da
commit 39409d3b96
9 changed files with 48 additions and 34 deletions

View file

@ -1,9 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using MLEM.Extensions; using MLEM.Extensions;
using MLEM.Misc;
using MLEM.Startup; using MLEM.Startup;
using MLEM.Textures; using MLEM.Textures;
@ -32,13 +34,30 @@ namespace TouchyTickets.Attractions {
} }
} }
public void Update(GameTime time, TimeSpan passed) { public float Update(GameTime time, TimeSpan passed, ParkMap map, Point position) {
this.ticketPercentage += this.Type.GenerationPerSecond * (float) passed.TotalSeconds; 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(); var amount = this.ticketPercentage.Floor();
if (amount > 0) { if (amount > 0) {
GameImpl.Instance.Tickets += amount; GameImpl.Instance.Tickets += amount;
this.ticketPercentage -= amount; this.ticketPercentage -= amount;
} }
// return the generation rate per second
return genRate;
}
public IEnumerable<Attraction> 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;
}
}
} }
} }

View file

@ -8,12 +8,9 @@ namespace TouchyTickets.Attractions {
public class AttractionType { public class AttractionType {
public static readonly Dictionary<string, AttractionType> Attractions = new Dictionary<string, AttractionType>(); public static readonly Dictionary<string, AttractionType> Attractions = new Dictionary<string, AttractionType>();
public static readonly AttractionType Carousel = Register(new AttractionType("Carousel", new[,] {{true}}, Attraction.Texture[0, 0, 1, 1], 0.5F, 50));
static AttractionType() { public static readonly AttractionType FoodCourt = Register(new AttractionType("FoodCourt", new[,] {{true, true}}, Attraction.Texture[1, 0, 2, 1], 1.1F, 300));
Register(new AttractionType("Carousel", new[,] {{true}}, Attraction.Texture[0, 0, 1, 1], 0.5F, 50)); public static readonly AttractionType FerrisWheel = Register(new AttractionType("FerrisWheel", new[,] {{true, true}, {true, true}}, Attraction.Texture[0, 1, 2, 2], 3.5F, 2000));
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 readonly string Name; public readonly string Name;
public readonly bool[,] Area; public readonly bool[,] Area;
@ -37,8 +34,9 @@ namespace TouchyTickets.Attractions {
return this.create(this); return this.create(this);
} }
private static void Register(AttractionType type) { private static AttractionType Register(AttractionType type) {
Attractions.Add(type.Name, type); Attractions.Add(type.Name, type);
return type;
} }
public delegate Attraction Constructor(AttractionType type); public delegate Attraction Constructor(AttractionType type);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -8,7 +8,6 @@ using MLEM.Extensions;
using MLEM.Font; using MLEM.Font;
using MLEM.Startup; using MLEM.Startup;
using TouchyTickets.Attractions; using TouchyTickets.Attractions;
using TouchyTickets.Upgrades;
namespace TouchyTickets { namespace TouchyTickets {
public class GameImpl : MlemGame { public class GameImpl : MlemGame {

View file

@ -25,6 +25,7 @@ namespace TouchyTickets {
private readonly List<(Point, Attraction)> attractions = new List<(Point, Attraction)>(); private readonly List<(Point, Attraction)> attractions = new List<(Point, Attraction)>();
private readonly Dictionary<Point, int> treePositions = new Dictionary<Point, int>(); private readonly Dictionary<Point, int> treePositions = new Dictionary<Point, int>();
private readonly Dictionary<Point, int> fencePositions = new Dictionary<Point, int>(); private readonly Dictionary<Point, int> fencePositions = new Dictionary<Point, int>();
private readonly Attraction[,] attractionGrid;
public float TicketsPerSecond { get; private set; } public float TicketsPerSecond { get; private set; }
public Attraction PlacingAttraction; public Attraction PlacingAttraction;
@ -34,6 +35,7 @@ namespace TouchyTickets {
public ParkMap(int width, int height) { public ParkMap(int width, int height) {
this.Width = width; this.Width = width;
this.Height = height; this.Height = height;
this.attractionGrid = new Attraction[width, height];
// set up trees // set up trees
var random = new Random(); var random = new Random();
@ -65,9 +67,9 @@ namespace TouchyTickets {
public void Update(GameTime time, TimeSpan passed) { public void Update(GameTime time, TimeSpan passed) {
var tickets = 0F; var tickets = 0F;
foreach (var (_, attraction) in this.attractions) { foreach (var (pos, attraction) in this.attractions) {
attraction.Update(time, passed); var genPerSecond = attraction.Update(time, passed, this, pos);
tickets += attraction.Type.GenerationPerSecond; tickets += genPerSecond;
} }
this.TicketsPerSecond = tickets; this.TicketsPerSecond = tickets;
@ -150,25 +152,24 @@ namespace TouchyTickets {
} }
public void Place(Point position, Attraction attraction) { 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)); this.attractions.Add((position, attraction));
} }
public Attraction GetAttractionAt(Point position) { public Attraction GetAttractionAt(Point position) {
foreach (var (pos, attraction) in this.attractions) { return this.attractionGrid[position.X, position.Y];
if (attraction.GetCoveredTiles().Any(p => pos + p == position))
return attraction;
}
return null;
} }
public int GetAttractionAmount(AttractionType type) { public int GetAttractionAmount(AttractionType type) {
return this.attractions.Count(a => a.Item2.Type == type); return this.attractions.Count(a => a.Item2.Type == type);
} }
public void CopyAttractionsFrom(ParkMap other) { public ParkMap Copy(int? newWidth = null, int? newHeight = null) {
foreach (var (pos, attraction) in other.attractions) var newMap = new ParkMap(newWidth ?? this.Width, newHeight ?? this.Height);
this.Place(pos, attraction); foreach (var (pos, attraction) in this.attractions)
newMap.Place(pos, attraction);
return newMap;
} }
} }

View file

@ -4,7 +4,6 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using Newtonsoft.Json; using Newtonsoft.Json;
using TouchyTickets.Upgrades;
namespace TouchyTickets { namespace TouchyTickets {
public static class SaveHandler { public static class SaveHandler {
@ -40,7 +39,7 @@ namespace TouchyTickets {
var data = Serializer.Deserialize<SaveData>(stream); var data = Serializer.Deserialize<SaveData>(stream);
game.Tickets = data.Tickets; game.Tickets = data.Tickets;
game.LastUpdate = data.LastUpdate; game.LastUpdate = data.LastUpdate;
game.Map = data.Map; game.Map = data.Map.Copy();
game.Stars = data.Stars; game.Stars = data.Stars;
game.TimesRestarted = data.TimesRestarted; game.TimesRestarted = data.TimesRestarted;
game.AppliedUpgrades.Clear(); game.AppliedUpgrades.Clear();

View file

@ -16,7 +16,6 @@ using MLEM.Textures;
using MLEM.Ui; using MLEM.Ui;
using MLEM.Ui.Elements; using MLEM.Ui.Elements;
using TouchyTickets.Attractions; using TouchyTickets.Attractions;
using TouchyTickets.Upgrades;
namespace TouchyTickets { namespace TouchyTickets {
public class Ui { public class Ui {
@ -196,7 +195,7 @@ namespace TouchyTickets {
}); });
button.OnUpdated += (e, time) => { button.OnUpdated += (e, time) => {
// we want to hide if we're active, or if we still need a dependency to be active // 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; button.IsDisabled = GameImpl.Instance.Stars < upgrade.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});

View file

@ -1,15 +1,15 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Microsoft.Xna.Framework;
using MLEM.Extensions; using MLEM.Extensions;
using MLEM.Textures; using MLEM.Textures;
namespace TouchyTickets.Upgrades { 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", 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 string Name;
public readonly int Price; public readonly int Price;
@ -38,18 +38,17 @@ namespace TouchyTickets.Upgrades {
// map size upgrades // map size upgrades
if (MapSize.Contains(this)) { if (MapSize.Contains(this)) {
var oldMap = GameImpl.Instance.Map; var oldMap = GameImpl.Instance.Map;
var newMap = new ParkMap(oldMap.Width + 5, oldMap.Height + 5); GameImpl.Instance.Map = oldMap.Copy(oldMap.Width + 5, oldMap.Height + 5);
newMap.CopyAttractionsFrom(oldMap);
GameImpl.Instance.Map = newMap;
} }
} }
private static void Register(Upgrade upgrade) { private static Upgrade Register(Upgrade upgrade) {
Upgrades.Add(upgrade.Name, upgrade); Upgrades.Add(upgrade.Name, upgrade);
return upgrade;
} }
public static bool IsActive(Upgrade upgrade) { public bool IsActive() {
return GameImpl.Instance.AppliedUpgrades.Contains(upgrade); return GameImpl.Instance.AppliedUpgrades.Contains(this);
} }
} }