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.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<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 static readonly Dictionary<string, AttractionType> Attractions = new Dictionary<string, AttractionType>();
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);

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.Startup;
using TouchyTickets.Attractions;
using TouchyTickets.Upgrades;
namespace TouchyTickets {
public class GameImpl : MlemGame {

View file

@ -25,6 +25,7 @@ namespace TouchyTickets {
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> fencePositions = new Dictionary<Point, int>();
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;
}
}

View file

@ -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<SaveData>(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();

View file

@ -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});

View file

@ -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<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 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);
}
}