|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
using Microsoft.Xna.Framework;
|
|
|
using Microsoft.Xna.Framework.Audio;
|
|
|
using Microsoft.Xna.Framework.Input;
|
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
|
using Microsoft.Xna.Framework.Media;
|
|
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
using System.IO;
|
|
|
using SpriteFontPlus;
|
|
|
using isometricparkfna;
|
|
|
using System.Diagnostics;
|
|
|
|
|
|
using static isometricparkfna.CellMap;
|
|
|
using isometricparkfna.Utils;
|
|
|
using isometricparkfna.UI;
|
|
|
using isometricparkfna.Engines;
|
|
|
using isometricparkfna.Components;
|
|
|
using isometricparkfna.Renderers;
|
|
|
using isometricparkfna.Messages;
|
|
|
using isometricparkfna.Spawners;
|
|
|
|
|
|
using ImGuiNET.SampleProgram.XNA;
|
|
|
using ImGuiNET;
|
|
|
using TraceryNet;
|
|
|
using Encompass;
|
|
|
|
|
|
class FNAGame : Game
|
|
|
{
|
|
|
private KeyboardState keyboardPrev = new KeyboardState();
|
|
|
|
|
|
private SpriteBatch batch;
|
|
|
private SoundEffect sound;
|
|
|
private SpriteFont monoFont;
|
|
|
|
|
|
private Camera camera = new Camera(new float[] { 0.25f, 0.5f, 1.0f, 2.0f, 4.0f });
|
|
|
|
|
|
Random random_generator = new Random();
|
|
|
|
|
|
int frameRate = 0;
|
|
|
int frameCounter = 0;
|
|
|
TimeSpan elapsedTime = TimeSpan.Zero;
|
|
|
TimeSpan drawTime = TimeSpan.Zero;
|
|
|
TimeSpan updateTime = TimeSpan.Zero;
|
|
|
|
|
|
Queue<float> past_fps = new Queue<float>(100);
|
|
|
int tilesDrawn = 0;
|
|
|
|
|
|
private const int width = 1280;
|
|
|
private const int height = 640;
|
|
|
|
|
|
//new tile stuff
|
|
|
int squaresAcross = 50;
|
|
|
int squaresDown = 50;
|
|
|
// int baseOffsetX = -14;
|
|
|
// int baseOffsetY = -14;
|
|
|
|
|
|
Simulation simulation;
|
|
|
|
|
|
public Vector2 mouseGrid;
|
|
|
Vector2 original_point;
|
|
|
|
|
|
//for now
|
|
|
public bool in_zone;
|
|
|
|
|
|
private ImGuiRenderer _imGuiRenderer;
|
|
|
private DebugWindow debugWindow;
|
|
|
|
|
|
public bool show_another_window;
|
|
|
private bool showInitial;
|
|
|
int messageIndex;
|
|
|
|
|
|
//buggy
|
|
|
private static bool enableCulling = false;
|
|
|
|
|
|
private Node<DialogOption> currentNode;
|
|
|
private Queue<Node<DialogOption>> remainingDialog;
|
|
|
private List<NewsItem> newsItems;
|
|
|
|
|
|
|
|
|
public bool showGrid;
|
|
|
public bool showTrees;
|
|
|
private Grammar grammar;
|
|
|
private string output;
|
|
|
private GraphicsDeviceManager gdm;
|
|
|
public bool showBudget;
|
|
|
private BudgetWindow budgetWindow;
|
|
|
public bool showForest;
|
|
|
public bool showNews;
|
|
|
|
|
|
//Encompass
|
|
|
private WorldBuilder WorldBuilder = new WorldBuilder();
|
|
|
private World World;
|
|
|
|
|
|
private ImGuiWindowBridgeEngine imGuiWindowBridgeEngine;
|
|
|
|
|
|
private static void Main(string[] args)
|
|
|
{
|
|
|
#if NETCOREAPP
|
|
|
DllMap.Initialise(false);
|
|
|
#endif
|
|
|
using FNAGame g = new FNAGame();
|
|
|
g.Run();
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private FNAGame()
|
|
|
{
|
|
|
//this.device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, GraphicsProfile.)
|
|
|
|
|
|
#if DEBUG
|
|
|
foreach (System.Reflection.Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
|
|
|
{
|
|
|
Console.Out.Write(assembly.ToString() + "\n");
|
|
|
}
|
|
|
;
|
|
|
#endif
|
|
|
this.gdm = new GraphicsDeviceManager(this) {
|
|
|
// Typically you would load a config here...
|
|
|
PreferredBackBufferWidth = width,
|
|
|
PreferredBackBufferHeight = height,
|
|
|
IsFullScreen = false,
|
|
|
SynchronizeWithVerticalRetrace = true
|
|
|
};
|
|
|
//gdm.SynchronizeWithVerticalRetrace = false;
|
|
|
IsFixedTimeStep = false;
|
|
|
|
|
|
this.simulation = new Simulation(this.squaresAcross, this.squaresDown, new float[] {16.66667f*60, 16.66667f*30, 16.66667f*15, 16.66667f*7.5f, 16.66667f*1 });
|
|
|
|
|
|
foreach (List<Cell> row in this.simulation.map.cells)
|
|
|
{
|
|
|
foreach (Cell cell in row)
|
|
|
{
|
|
|
if (this.random_generator.NextDouble() > 0.75)
|
|
|
{
|
|
|
int random_year = (int)MathHelper.Clamp((float)MathUtils.NextNormal(random_generator, 2010.0f, 40.0f), 1800, Simulation.START_YEAR);
|
|
|
int random_month = random_generator.Next(1, 12);
|
|
|
DateTime random_date = new DateTime(random_year, random_month, 1);
|
|
|
|
|
|
cell.addTree(random_date);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
showInitial = true;
|
|
|
messageIndex = 0;
|
|
|
showBudget = false;
|
|
|
showForest = false;
|
|
|
showNews = false;
|
|
|
showGrid = true;
|
|
|
showTrees = true;
|
|
|
|
|
|
this.Window.Title = "Isometric Park";
|
|
|
|
|
|
Content.RootDirectory = "Content";
|
|
|
|
|
|
currentNode = DialogTrees.introTree;
|
|
|
|
|
|
}
|
|
|
|
|
|
protected override void Initialize()
|
|
|
{
|
|
|
/* This is a nice place to start up the engine, after
|
|
|
* loading configuration stuff in the constructor
|
|
|
*/
|
|
|
this.IsMouseVisible = true;
|
|
|
|
|
|
_imGuiRenderer = new ImGuiRenderer(this);
|
|
|
_imGuiRenderer.RebuildFontAtlas(); // Required so fonts are available for rendering
|
|
|
|
|
|
base.Initialize();
|
|
|
}
|
|
|
|
|
|
protected override void LoadContent()
|
|
|
{
|
|
|
// Create the batch...
|
|
|
batch = new SpriteBatch(GraphicsDevice);
|
|
|
|
|
|
sound = Content.Load<SoundEffect>("FNASound");
|
|
|
Tile.TileSetTexture = Content.Load<Texture2D>(@"part4_tileset");
|
|
|
|
|
|
Line.initialize(GraphicsDevice);
|
|
|
|
|
|
//let's see if this works:
|
|
|
// WorldBuilder = new WorldBuilder();
|
|
|
var dummy_entity = WorldBuilder.CreateEntity();
|
|
|
|
|
|
|
|
|
WorldBuilder.AddGeneralRenderer(new AreaRenderer(this.batch, this.monoFont), 1);
|
|
|
WorldBuilder.AddEngine(new InputEngine(Menu.MENU_BAR_HEIGHT, FNAGame.width, FNAGame.height));
|
|
|
WorldBuilder.AddEngine(new GameBridgeEngine(this));
|
|
|
WorldBuilder.AddEngine(new SimulationBridgeEngine(this.simulation));
|
|
|
WorldBuilder.AddEngine(new CameraBridgeEngine(this.camera));
|
|
|
this.imGuiWindowBridgeEngine = new ImGuiWindowBridgeEngine();
|
|
|
WorldBuilder.AddEngine(this.imGuiWindowBridgeEngine);
|
|
|
WorldBuilder.AddEngine(new ContractSpawner());
|
|
|
|
|
|
// var budgetWindow = WorldBuilder.CreateEntity();
|
|
|
// WorldBuilder.SetComponent(budgetWindow, new VisibilityComponent{visible = true});
|
|
|
// WorldBuilder.SetComponent(budgetWindow, new BudgetComponent());
|
|
|
|
|
|
var area = WorldBuilder.CreateEntity();
|
|
|
// WorldBuilder.SetComponent(area, new AreaComponent{squares = new[] {new Vector2(4,4), new Vector2(5,4)}});
|
|
|
WorldBuilder.SendMessage(new SpawnContractMessage{squares = new[] {new Vector2(4,4), new Vector2(5,4)},
|
|
|
name = "Contract"});
|
|
|
|
|
|
World = WorldBuilder.Build();
|
|
|
|
|
|
var bakedMono = TtfFontBaker.Bake(File.OpenRead(@"Content/iosevka-term-extendedmedium.ttf"),
|
|
|
15,
|
|
|
1024,
|
|
|
1024,
|
|
|
new[]
|
|
|
{
|
|
|
CharacterRange.BasicLatin,
|
|
|
CharacterRange.Latin1Supplement,
|
|
|
CharacterRange.LatinExtendedA,
|
|
|
CharacterRange.Cyrillic,
|
|
|
CharacterRange.LatinExtendedB,
|
|
|
new CharacterRange((char) 0x00B7)
|
|
|
}
|
|
|
);
|
|
|
|
|
|
this.debugWindow = new DebugWindow(this._imGuiRenderer, GraphicsDevice);
|
|
|
|
|
|
var json2 = new FileInfo(@"Content/grammar.json");
|
|
|
|
|
|
this.grammar = new TraceryNet.Grammar(json2);
|
|
|
|
|
|
this.output = grammar.Flatten("#greeting#");
|
|
|
var result = grammar.Flatten("#[assistantName:#assistantNames#][whatever:whatever]vars#");
|
|
|
|
|
|
Func<string, string> toUpper = delegate (string i)
|
|
|
{
|
|
|
return i.ToUpper();
|
|
|
};
|
|
|
|
|
|
grammar.AddModifier("toUpper", toUpper);
|
|
|
|
|
|
var newItems = new[] {new NewsItem{hed="Test", contents="#city.toUpper# - This is where the lede would go. #whatever#", source="Wire"}
|
|
|
};
|
|
|
|
|
|
this.newsItems = newItems.ToList();
|
|
|
|
|
|
using (var sr = new StreamReader(@"Content/news_items.yaml"))
|
|
|
{
|
|
|
this.newsItems.AddRange(NewsItem.FromYaml(sr.ReadToEnd()));
|
|
|
}
|
|
|
using (var sr_pregenerated = new StreamReader(@"Content/news_items_pregenerated.yaml"))
|
|
|
{
|
|
|
this.newsItems.AddRange(NewsItem.FromYaml(sr_pregenerated.ReadToEnd()));
|
|
|
}
|
|
|
this.simulation.LoadContent(this.newsItems, this.grammar);
|
|
|
// this.newsItems = this.newsItems.Select(s => s.Flatten(this.grammar)).ToList().Shuffle();
|
|
|
|
|
|
|
|
|
this.remainingDialog = new Queue<Node<DialogOption>>();
|
|
|
|
|
|
#if DEBUG
|
|
|
this.remainingDialog.Enqueue(DialogTrees.flatten(DialogTrees.testTree, this.grammar));
|
|
|
#endif
|
|
|
|
|
|
//font = fontBakeResult.CreateSpriteFont(GraphicsDevice);
|
|
|
monoFont = bakedMono.CreateSpriteFont(GraphicsDevice);
|
|
|
|
|
|
this.budgetWindow = new BudgetWindow(new Budget { }, this.monoFont, 0, 0);
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
protected override void UnloadContent()
|
|
|
{
|
|
|
batch.Dispose();
|
|
|
sound.Dispose();
|
|
|
Tile.TileSetTexture.Dispose();
|
|
|
}
|
|
|
|
|
|
Vector2 calculateMousegrid(Vector2 normalizedMousePos)
|
|
|
{
|
|
|
|
|
|
//int gridx = (int)(normalizedMousePos.X / Tile.TileSpriteWidth);
|
|
|
//int gridy = (int)(normalizedMousePos.Y / Tile.TileSpriteHeight);
|
|
|
Vector2 adjust = new Vector2(Tile.TileSpriteWidth / 2, Tile.TileSpriteHeight);
|
|
|
Vector2 adjustedMousePos = normalizedMousePos - adjust;
|
|
|
|
|
|
float boardx = ((adjustedMousePos.X / Tile.TileSpriteWidth) + (adjustedMousePos.Y / Tile.TileSpriteHeight));
|
|
|
float boardy = ((adjustedMousePos.Y / Tile.TileSpriteHeight) - (adjustedMousePos.X / Tile.TileSpriteWidth));
|
|
|
|
|
|
|
|
|
return new Vector2((int)boardx, (int)boardy);
|
|
|
/*
|
|
|
int gridx = (int)((normalizedMousePos.X + (this.baseOffsetX + 4)) / Tile.TileWidth) ;
|
|
|
int gridy = (int)((normalizedMousePos.Y + (this.baseOffsetX + 4) + (2*baseOffsetY)) / (Tile.TileStepY));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int within_gridx = (int)((normalizedMousePos.X) % Tile.TileWidth) - (Tile.TileWidth/2);
|
|
|
int within_gridy = (int)((normalizedMousePos.Y) % Tile.TileHeight) - (Tile.TileHeight / 2);
|
|
|
|
|
|
int middle_distance = Math.Abs(within_gridx) + Math.Abs(within_gridx);
|
|
|
Vector2 adjustment_vector;
|
|
|
|
|
|
return new Vector2(gridx, gridy);
|
|
|
if (middle_distance < (Tile.TileWidth / 2))
|
|
|
{
|
|
|
return new Vector2(gridx, gridy);
|
|
|
}
|
|
|
|
|
|
else if ((Math.Sign(within_gridx) == -1) && (Math.Sign(within_gridy) == 1))
|
|
|
{
|
|
|
adjustment_vector = new Vector2(-1, -1);
|
|
|
return new Vector2(gridx, gridy) + adjustment_vector;
|
|
|
}
|
|
|
else if ((Math.Sign(within_gridx) == -1) && (Math.Sign(within_gridy) == -1))
|
|
|
{
|
|
|
adjustment_vector = new Vector2(-1, 1);
|
|
|
return new Vector2(gridx, gridy) + adjustment_vector;
|
|
|
}
|
|
|
else if ((Math.Sign(within_gridx) == 1) && (Math.Sign(within_gridy) == 1))
|
|
|
{
|
|
|
adjustment_vector = new Vector2(0, -1);
|
|
|
return new Vector2(gridx, gridy) + adjustment_vector;
|
|
|
}
|
|
|
else if ((Math.Sign(within_gridx) == 1) && (Math.Sign(within_gridy) == -1))
|
|
|
{
|
|
|
adjustment_vector = new Vector2(0, 1);
|
|
|
return new Vector2(gridx, gridy) + adjustment_vector;
|
|
|
}
|
|
|
else {
|
|
|
return new Vector2(gridx, gridy);
|
|
|
}
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected override void Update(GameTime gameTime)
|
|
|
{
|
|
|
|
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
|
stopWatch.Start();
|
|
|
|
|
|
float volume = 1.0f;
|
|
|
float pitch = 0.0f;
|
|
|
float pan = 0.0f;
|
|
|
|
|
|
|
|
|
// Run game logic in here. Do NOT render anything here!
|
|
|
KeyboardState keyboardCur = Keyboard.GetState();
|
|
|
|
|
|
#region input
|
|
|
//
|
|
|
#region misc_keys
|
|
|
if (keyboardCur.IsKeyDown(Keys.OemBackslash) && keyboardPrev.IsKeyUp(Keys.OemBackslash) && keyboardCur.IsKeyDown(Keys.LeftShift))
|
|
|
{
|
|
|
sound.Play(volume, pitch, pan);
|
|
|
}
|
|
|
#endregion misc_keys
|
|
|
//
|
|
|
MouseState mouseCur = Mouse.GetState();
|
|
|
this.original_point = Vector2.Transform(new Vector2(mouseCur.X, mouseCur.Y), Matrix.Invert(camera.get_transformation(GraphicsDevice)));
|
|
|
|
|
|
|
|
|
#if DEBUG
|
|
|
if (mouseCur.RightButton == ButtonState.Pressed)
|
|
|
{
|
|
|
Vector2 cameraMiddle = this.camera.position + new Vector2(FNAGame.width / 2, FNAGame.height / 2);
|
|
|
Vector2 delta = this.camera.position - this.original_point;
|
|
|
this.camera.Jump(this.original_point);
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
#endregion input
|
|
|
|
|
|
|
|
|
|
|
|
World.Update(gameTime.ElapsedGameTime.TotalSeconds);
|
|
|
this.simulation.update(gameTime.ElapsedGameTime);
|
|
|
|
|
|
if (this.showBudget)
|
|
|
{
|
|
|
this.showBudget = this.budgetWindow.update(mouseCur, this.simulation.latestBudget, this.simulation.previousBudget);
|
|
|
}
|
|
|
|
|
|
|
|
|
if (!this.showInitial && this.remainingDialog.Count > 0)
|
|
|
{
|
|
|
this.currentNode = this.remainingDialog.Dequeue();
|
|
|
this.showInitial = true;
|
|
|
}
|
|
|
|
|
|
this.original_point = Vector2.Transform(new Vector2(mouseCur.X, mouseCur.Y), Matrix.Invert(camera.get_transformation(GraphicsDevice)));
|
|
|
|
|
|
//int gridx = (int)((this.original_point.X-baseOffsetX) / Tile.TileStepX);
|
|
|
/* int gridx = (int)(this.original_point.Y / Tile.TileHeight + this.original_point.X / Tile.TileWidth); */
|
|
|
//int gridy = (int)((this.original_point.Y-baseOffsetY) / (Tile.TileStepY*2));
|
|
|
/* int gridy = (int)(this.original_point.Y / Tile.TileHeight - this.original_point.X / Tile.TileWidth); */
|
|
|
|
|
|
//this.mouseGrid = new Vector2(gridx, gridy);
|
|
|
this.mouseGrid = this.calculateMousegrid(this.original_point);
|
|
|
|
|
|
elapsedTime += gameTime.ElapsedGameTime;
|
|
|
|
|
|
if (elapsedTime > TimeSpan.FromSeconds(1))
|
|
|
{
|
|
|
elapsedTime -= TimeSpan.FromSeconds(1);
|
|
|
frameRate = frameCounter;
|
|
|
frameCounter = 0;
|
|
|
}
|
|
|
|
|
|
this.keyboardPrev = keyboardCur;
|
|
|
|
|
|
stopWatch.Stop();
|
|
|
this.updateTime = stopWatch.Elapsed;
|
|
|
|
|
|
base.Update(gameTime);
|
|
|
|
|
|
}
|
|
|
|
|
|
protected float calculateDepth() {
|
|
|
return ((this.squaresAcross + 1) + ((this.squaresDown + 1) * Tile.TileWidth)) * 10;
|
|
|
}
|
|
|
|
|
|
protected Boolean cull(int gridX, int gridY)
|
|
|
{
|
|
|
int screenX = (gridX - gridY) * Tile.TileSpriteWidth / 2;
|
|
|
int screenY = (gridX + gridY) * Tile.TileSpriteHeight / 2;
|
|
|
|
|
|
Vector2 original = Vector2.Transform(new Vector2(screenX, screenY), camera.get_transformation(GraphicsDevice));
|
|
|
|
|
|
return (!FNAGame.enableCulling ||
|
|
|
(MathUtils.Between(original.X, -Tile.TileSpriteWidth, FNAGame.width)
|
|
|
&& MathUtils.Between(original.Y, -Tile.TileSpriteHeight, FNAGame.height)));
|
|
|
}
|
|
|
|
|
|
//Convenience method I'm not super sure about anymore.
|
|
|
protected void drawTileAt(int x, int y, int tileIndex, int height)
|
|
|
{
|
|
|
float maxdepth = ((this.squaresAcross + 1) + ((this.squaresDown + 1) * Tile.TileWidth)) * 10;
|
|
|
|
|
|
float depthOffset = 0.7f - ((0 + (0 * Tile.TileWidth)) / maxdepth);
|
|
|
|
|
|
Tile.drawTileAt(this.batch, x, y, tileIndex, height, depthOffset);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected override void Draw(GameTime gameTime)
|
|
|
{
|
|
|
// Render stuff in here. Do NOT run game logic in here!
|
|
|
|
|
|
frameCounter++;
|
|
|
|
|
|
string fps = string.Format("fps: {0}", frameRate);
|
|
|
|
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
|
stopWatch.Start();
|
|
|
GraphicsDevice.Clear(Color.CornflowerBlue);
|
|
|
batch.Begin(SpriteSortMode.BackToFront,
|
|
|
BlendState.AlphaBlend,
|
|
|
null,
|
|
|
null,
|
|
|
null,
|
|
|
null,
|
|
|
camera.get_transformation(GraphicsDevice));
|
|
|
|
|
|
//New tile stuff
|
|
|
/*
|
|
|
Vector2 firstSquare = Vector2.Zero;
|
|
|
int firstX = (int)firstSquare.X;
|
|
|
int firstY = (int)firstSquare.Y;
|
|
|
|
|
|
Vector2 squareOffset = Vector2.Zero;
|
|
|
|
|
|
int offsetX = (int)squareOffset.X;
|
|
|
int offsetY = (int)squareOffset.Y;
|
|
|
|
|
|
|
|
|
for (int y = 0; y < this.squaresDown; y++)
|
|
|
{
|
|
|
int rowOffset = 0;
|
|
|
if ((firstY + y) % 2 == 1)
|
|
|
rowOffset = Tile.OddRowXOffset;
|
|
|
|
|
|
for (int x = 0; x < this.squaresAcross; x++) {
|
|
|
|
|
|
|
|
|
batch.Draw(
|
|
|
Tile.TileSetTexture,
|
|
|
new Rectangle(
|
|
|
((x * Tile.TileStepX) - offsetX + rowOffset + baseOffsetX),
|
|
|
((y * Tile.TileStepY) - offsetY + baseOffsetY),
|
|
|
Tile.TileWidth, Tile.TileHeight),
|
|
|
Tile.GetSourceRectangle(1),
|
|
|
Color.White,
|
|
|
0.0f,
|
|
|
Vector2.Zero,
|
|
|
SpriteEffects.None,
|
|
|
0.9f);
|
|
|
|
|
|
|
|
|
}
|
|
|
}*/
|
|
|
|
|
|
#region draw_tiles
|
|
|
//reset
|
|
|
this.tilesDrawn = 0;
|
|
|
|
|
|
for (int y = 0; y < this.squaresDown; y++)
|
|
|
{
|
|
|
|
|
|
for (int x = 0; x < this.squaresAcross; x++)
|
|
|
{
|
|
|
|
|
|
int screenx = (x - y) * Tile.TileSpriteWidth / 2;
|
|
|
|
|
|
int screeny = (x + y) * Tile.TileSpriteHeight / 2;
|
|
|
|
|
|
if (this.cull(x, y))
|
|
|
{
|
|
|
batch.Draw(
|
|
|
Tile.TileSetTexture,
|
|
|
new Rectangle(
|
|
|
screenx,
|
|
|
screeny,
|
|
|
Tile.TileWidth, Tile.TileHeight),
|
|
|
Tile.GetSourceRectangle(1),
|
|
|
Color.White,
|
|
|
0.0f,
|
|
|
Vector2.Zero,
|
|
|
SpriteEffects.None,
|
|
|
0.9f);
|
|
|
|
|
|
this.tilesDrawn++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
#endregion draw_tiles
|
|
|
|
|
|
#region draw_gridlines
|
|
|
|
|
|
if (this.showGrid)
|
|
|
{
|
|
|
//need to go one extra so gridlines include the far side of the final tile:
|
|
|
for (int y = 0; y < (this.squaresDown + 1); y++)
|
|
|
{
|
|
|
|
|
|
Vector2 adjust = new Vector2(Tile.TileSpriteWidth / 2, Tile.TileSpriteHeight); //TODO figure out why this second value shouldn't be halved
|
|
|
|
|
|
Line.drawLine(batch,
|
|
|
new Vector2(((0 - y) * Tile.TileSpriteWidth / 2),
|
|
|
(0 + y) * Tile.TileSpriteHeight / 2) + adjust,
|
|
|
//new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
|
|
|
new Vector2((this.squaresAcross - (y)) * Tile.TileSpriteWidth / 2,
|
|
|
(this.squaresAcross + (y)) * Tile.TileSpriteHeight / 2) + adjust,
|
|
|
|
|
|
Color.White, 0.8f);
|
|
|
|
|
|
}
|
|
|
|
|
|
for (int x = 0; x < (this.squaresAcross + 1); x++)
|
|
|
{
|
|
|
|
|
|
Vector2 adjust = new Vector2(Tile.TileSpriteWidth / 2, Tile.TileSpriteHeight); //TODO figure out why this second value shouldn't be halved
|
|
|
|
|
|
Line.drawLine(batch,
|
|
|
new Vector2(((x - 0) * Tile.TileSpriteWidth / 2), (x + 0) * Tile.TileSpriteHeight / 2) + adjust,
|
|
|
//new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
|
|
|
new Vector2((x - this.squaresDown) * Tile.TileSpriteWidth / 2, (x + this.squaresDown) * Tile.TileSpriteHeight / 2) + adjust,
|
|
|
Color.White, 0.8f);
|
|
|
|
|
|
}
|
|
|
}
|
|
|
#endregion draw_gridlines
|
|
|
|
|
|
|
|
|
//Gridlines
|
|
|
//Lines going down and to the right:
|
|
|
/*
|
|
|
for (int x = (int)(-this.squaresAcross/2); x < this.squaresAcross; x++)
|
|
|
{
|
|
|
int rowOffset = 0;
|
|
|
|
|
|
float startX = (x * Tile.TileStepX) + baseOffsetX - (Tile.TileStepX / 2);
|
|
|
|
|
|
Vector2 start = new Vector2(startX, -baseOffsetY+4);
|
|
|
Vector2 stop = new Vector2(startX + this.squaresAcross* Tile.TileStepX/2,
|
|
|
this.squaresDown*Tile.TileStepY- baseOffsetY+4);
|
|
|
|
|
|
|
|
|
|
|
|
Line.drawLine(batch,
|
|
|
Line.departurePoint(stop, start, this.squaresAcross * Tile.TileWidth, this.squaresDown * Tile.TileHeight),
|
|
|
Line.departurePoint(start, stop, this.squaresAcross * Tile.TileWidth, this.squaresDown * Tile.TileHeight),
|
|
|
Color.White, 0.8f);
|
|
|
|
|
|
}
|
|
|
//Lines going down and to the left:
|
|
|
for (int x = 0; x < (int)(1.5*this.squaresAcross); x++)
|
|
|
{
|
|
|
|
|
|
float startX = (x * Tile.TileStepX) + baseOffsetX - (Tile.TileStepX / 2);
|
|
|
|
|
|
Vector2 start_reverse = new Vector2(startX, -baseOffsetY + 4);
|
|
|
Vector2 stop_reverse = new Vector2(startX + -(this.squaresAcross * Tile.TileStepX / 2),
|
|
|
(this.squaresDown * Tile.TileStepY) - baseOffsetY + 4);
|
|
|
|
|
|
Line.drawLine(batch,
|
|
|
Line.departurePoint(stop_reverse, start_reverse, this.squaresAcross * Tile.TileWidth, this.squaresDown * Tile.TileHeight),
|
|
|
Line.departurePoint(start_reverse, stop_reverse, this.squaresAcross * Tile.TileWidth, this.squaresDown * Tile.TileHeight),
|
|
|
Color.White, 0.8f);
|
|
|
|
|
|
}
|
|
|
*/
|
|
|
|
|
|
#if DEBUG
|
|
|
drawTileAt(4, 4, 140, 3);
|
|
|
drawTileAt(6, 4, 141, 3);
|
|
|
drawTileAt(8, 4, 142, 2);
|
|
|
drawTileAt(10, 4, 142, 3);
|
|
|
#endif
|
|
|
|
|
|
#region draw_cursor
|
|
|
//drawTileAt((int)this.mouseGrid.X, (int)this.mouseGrid.Y, 2, 1, 0.85f); //between tiles and gridlines
|
|
|
|
|
|
if (MathUtils.BetweenInclusive(this.mouseGrid.X, 0, this.simulation.map.MapWidth)
|
|
|
&& MathUtils.BetweenInclusive(this.mouseGrid.Y, 0, this.simulation.map.MapHeight))
|
|
|
{
|
|
|
Tile.OutlineSquare(batch, this.mouseGrid.X, this.mouseGrid.Y, Color.Yellow, 1);
|
|
|
}
|
|
|
|
|
|
#if DEBUG
|
|
|
Tile.OutlineSquare(batch, 1, 1, Color.Red, 2);
|
|
|
Tile.OutlineSquare(batch, 3, 1, Color.Blue, 2);
|
|
|
Tile.OutlineSquare(batch, 5, 1, Color.Green, 2);
|
|
|
Tile.OutlineSquare(batch, 7, 1, Color.Orange, 2);
|
|
|
Tile.OutlineSquare(batch, 9, 1, Color.Orange, 3);
|
|
|
// Tile.OutlineSquare2(batch, 12, 1, Color.Orange, 2);
|
|
|
|
|
|
//Tile.drawEdge(batch, new Edge {Start=new Vector2(14, 1), End= new Vector2(15, 1)}, Color.Orange);
|
|
|
|
|
|
//donut
|
|
|
Tile.DrawOutlinedSquares(batch, new Vector2[] {new Vector2(19, 1), new Vector2(19, 2), new Vector2(20, 1), new Vector2(21, 1),
|
|
|
new Vector2(21, 2), new Vector2(19, 3), new Vector2(20, 3), new Vector2(21, 3)}, Color.Purple);
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#endregion draw_cursor
|
|
|
/*
|
|
|
|
|
|
for (int i = 0; i< 80; i++)
|
|
|
{
|
|
|
for (int j = 0; j < 50; j += 1)
|
|
|
{
|
|
|
//Warning: creates a flashing effect because tree positions update every 1/60th of a second
|
|
|
|
|
|
if (this.random_generator.NextDouble() > 0.75)
|
|
|
{
|
|
|
drawTileAt(i, j, 142, 2);
|
|
|
}
|
|
|
|
|
|
if ((i + j) % 3 == 0)
|
|
|
{
|
|
|
drawTileAt(i, j, 142, 2);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}//*/
|
|
|
|
|
|
#region draw_trees
|
|
|
if (this.showTrees) {
|
|
|
for (int i = 0; i < this.simulation.map.MapHeight; i++)
|
|
|
{
|
|
|
for (int j = 0; j < this.simulation.map.MapWidth; j += 1)
|
|
|
{
|
|
|
|
|
|
if (this.simulation.map.cells[i][j].hasTree)
|
|
|
{ //until we actually simulate:
|
|
|
drawTileAt(i, j, 142, 2);
|
|
|
// if ((i + j) % 8 == 0)
|
|
|
// {
|
|
|
// drawTileAt(i, j, 141, 2);
|
|
|
// }
|
|
|
// else
|
|
|
// {
|
|
|
// drawTileAt(i, j, 142, 2);
|
|
|
// }
|
|
|
}
|
|
|
else if (this.simulation.map.cells[i][j].status == CellStatus.DeadTree) {
|
|
|
drawTileAt(i, j, 141, 2);
|
|
|
// System.Console.WriteLine(String.Format("Drew Dead Tree at {0},{1}", i, j));
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
#endregion draw_trees
|
|
|
|
|
|
drawTileAt(2, 2, 140, 2);
|
|
|
drawTileAt(1, 1, 140, 2);
|
|
|
drawTileAt(3, 2, 140, 2);
|
|
|
|
|
|
World.Draw();
|
|
|
batch.End();
|
|
|
|
|
|
#region draw_header
|
|
|
batch.Begin(SpriteSortMode.BackToFront,
|
|
|
BlendState.AlphaBlend,
|
|
|
null,
|
|
|
null,
|
|
|
null,
|
|
|
null);
|
|
|
|
|
|
bool has_tree = false;
|
|
|
if (MathUtils.Between(this.mouseGrid.X, 0, this.squaresAcross) && MathUtils.Between(this.mouseGrid.Y, 0, this.squaresAcross))
|
|
|
{
|
|
|
has_tree = this.simulation.map.cells[(int)this.mouseGrid.X][(int)this.mouseGrid.Y].hasTree;
|
|
|
}
|
|
|
//*/
|
|
|
|
|
|
String status_left = "";
|
|
|
if (MathUtils.Between(this.mouseGrid.X, -1, this.simulation.map.MapWidth) && MathUtils.Between(this.mouseGrid.Y, -1, this.simulation.map.MapHeight))
|
|
|
{
|
|
|
status_left = String.Format("{0:},{1:} {2} ({3})", this.mouseGrid.X, this.mouseGrid.Y,
|
|
|
this.simulation.map.cells[(int)this.mouseGrid.X][(int)this.mouseGrid.Y].status,
|
|
|
this.in_zone ? "Contracted" : "Unzoned"
|
|
|
);
|
|
|
}
|
|
|
|
|
|
String header_left = String.Format("${0:}|{1:} \ue124", this.simulation.money, this.simulation.map.tree_count);
|
|
|
String header_middle = String.Format("{0:MMMMM yyyy} ({1:})", this.simulation.DateTime, this.simulation.Season);
|
|
|
// String header_right = String.Format("Press H for help.");
|
|
|
String header_right = "";
|
|
|
|
|
|
this.Window.Title = String.Format("Isometric Park [{0:}]", header_middle);
|
|
|
Vector2 middle_dimensions = monoFont.MeasureString(header_middle);
|
|
|
Vector2 right_dimensions = monoFont.MeasureString(header_right);
|
|
|
|
|
|
float middle_start = (int)((FNAGame.width / 2) - (middle_dimensions.X / 2));
|
|
|
float right_start = (int)(FNAGame.width - right_dimensions.X - 10.0f);
|
|
|
float top = (float)Math.Round(FNAGame.height - middle_dimensions.Y); // Rounding so the int and float versions are closer.
|
|
|
|
|
|
|
|
|
FilledRectangle.drawFilledRectangle(batch, new Rectangle(0, (int)top, width, (int)middle_dimensions.Y), Color.White, 0.51f);
|
|
|
|
|
|
|
|
|
batch.DrawString(monoFont, status_left, new Vector2(1, top), Color.Black, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);
|
|
|
batch.DrawString(monoFont, header_left, new Vector2(1, 1), Color.Black, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);
|
|
|
batch.DrawString(monoFont, header_middle, new Vector2(middle_start, 1), Color.Black, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);
|
|
|
// batch.DrawString(monoFont, header_right, new Vector2(right_start, 1), Color.Black, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);
|
|
|
#endregion draw_header
|
|
|
|
|
|
|
|
|
#region budget
|
|
|
|
|
|
if (this.showBudget)
|
|
|
{
|
|
|
budgetWindow.draw(batch);
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion budget
|
|
|
|
|
|
batch.End();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region debug_window
|
|
|
//Calcs for debug window:
|
|
|
if ((this.frameCounter % 15) == 0)
|
|
|
{
|
|
|
past_fps.Enqueue(this.frameRate);
|
|
|
|
|
|
}
|
|
|
|
|
|
DebugInfo debugInfo = new DebugInfo
|
|
|
{ fps = this.frameRate,
|
|
|
pastFps = past_fps.ToArray(),
|
|
|
cameraPosition = camera.position,
|
|
|
drawTime = this.drawTime,
|
|
|
updateTime = this.updateTime,
|
|
|
treeCount = this.simulation.map.tree_count,
|
|
|
mouseGrid = this.mouseGrid,
|
|
|
hasTree = has_tree,
|
|
|
tilesDrawn = this.tilesDrawn
|
|
|
};
|
|
|
|
|
|
//Finally, draw the debug window
|
|
|
_imGuiRenderer.BeforeLayout(gameTime);
|
|
|
|
|
|
var additionalInfo = new Dictionary<string, string>();
|
|
|
|
|
|
Vector2 cameraMiddle = this.camera.position + new Vector2(FNAGame.width / 2, FNAGame.height / 2);
|
|
|
var state = Mouse.GetState();
|
|
|
Vector2 delta = this.camera.position - this.original_point;
|
|
|
|
|
|
additionalInfo.Add("cameraMiddle", cameraMiddle.ToString());
|
|
|
additionalInfo.Add("mouse ", String.Format("{0}, {1}", state.X, state.Y));
|
|
|
additionalInfo.Add("mouse delta", delta.ToString());
|
|
|
|
|
|
additionalInfo.Add("Tracery Test", this.output);
|
|
|
|
|
|
debugWindow.Layout(debugInfo, additionalInfo, ref show_another_window);
|
|
|
|
|
|
|
|
|
//debugWindow.ImGuiLayout();
|
|
|
//String[] messages = { "Message1", "Message2" };
|
|
|
|
|
|
//DialogOption[] dialog = { new DialogOption{ response="Welcome to your new park, director! You can use the mouse or arrow keys to move around, and the plus and minus keys to zoom in and out.", choice="Okay" },
|
|
|
// new DialogOption{ response="Make sure that you keep visitors happy and the budget in the black! You're currently getting an annual grant out of my budget—it'd sure be nice if you park were self-sufficient so we could drop that expense!", choice="And I need to keep the forest healthy, too, right?" },
|
|
|
// new DialogOption{ response="Oh yeah, of course.", choice="..." }};
|
|
|
|
|
|
|
|
|
if (this.currentNode != null)
|
|
|
{
|
|
|
this.currentNode = DialogInterface.RenderDialog(ref this.showInitial,
|
|
|
ref this.simulation.paused, debugWindow.monoFont, this.currentNode);
|
|
|
}
|
|
|
|
|
|
if (this.showForest)
|
|
|
{
|
|
|
ForestWindow.Render(this.showForest, debugWindow.monoFont, this.simulation, this.imGuiWindowBridgeEngine);
|
|
|
}
|
|
|
|
|
|
if (this.showNews)
|
|
|
{
|
|
|
NewsWindow.Render(this.showNews, debugWindow.monoFont, this.simulation, this.imGuiWindowBridgeEngine);
|
|
|
}
|
|
|
|
|
|
bool quit = false;
|
|
|
Menu.Render(debugWindow.monoFont, FNAGame.width, ref quit, ref this.simulation.paused, ref this.simulation.currentRate,
|
|
|
ref this.showBudget, ref this.showNews, ref this.showForest, header_left);
|
|
|
|
|
|
if (quit) {
|
|
|
System.Environment.Exit(0);
|
|
|
}
|
|
|
|
|
|
|
|
|
_imGuiRenderer.AfterLayout();
|
|
|
|
|
|
#endregion debug_window
|
|
|
|
|
|
|
|
|
|
|
|
stopWatch.Stop();
|
|
|
this.drawTime = stopWatch.Elapsed;
|
|
|
|
|
|
base.Draw(gameTime);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|