|
|
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 System.Reflection;
|
|
|
using System.Diagnostics;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
using SpriteFontPlus;
|
|
|
|
|
|
using isometricparkfna;
|
|
|
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 Num = System.Numerics;
|
|
|
|
|
|
using ImGuiNET.SampleProgram.XNA;
|
|
|
using ImGuiNET;
|
|
|
using ImPlotNET;
|
|
|
using TraceryNet;
|
|
|
using Encompass;
|
|
|
using Ink.Runtime;
|
|
|
|
|
|
//Let's let core builds be deterministic
|
|
|
#if NETCOREAPP
|
|
|
[assembly:AssemblyVersion("0.36.31.0")]
|
|
|
#else
|
|
|
[assembly:AssemblyVersion("0.36.31.*")]
|
|
|
#endif
|
|
|
|
|
|
class FNAGame : Game
|
|
|
{
|
|
|
private KeyboardState keyboardPrev = new KeyboardState();
|
|
|
private MouseState mousePrev = new MouseState();
|
|
|
|
|
|
private SpriteBatch batch;
|
|
|
private SpriteBatch tileBatch;
|
|
|
#if DEBUG
|
|
|
private SoundEffect sound;
|
|
|
#endif
|
|
|
private SpriteFont monoFont;
|
|
|
private SpriteFont largeMonoFont;
|
|
|
|
|
|
private Camera camera = new Camera(new float[] {0.125f, 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 tileDrawTime = TimeSpan.Zero;
|
|
|
TimeSpan gridDrawTime = TimeSpan.Zero;
|
|
|
TimeSpan treeDrawTime = TimeSpan.Zero;
|
|
|
TimeSpan updateTime = TimeSpan.Zero;
|
|
|
|
|
|
Queue<float> past_fps = new Queue<float>(100);
|
|
|
Queue<TimeSpan> past_draw = new Queue<TimeSpan>(100);
|
|
|
int tilesDrawn = 0;
|
|
|
|
|
|
private static int width = 1280;
|
|
|
private static int height = 640;
|
|
|
|
|
|
//new tile stuff
|
|
|
int squaresAcross = 200;
|
|
|
int squaresDown = 200;
|
|
|
|
|
|
Simulation simulation;
|
|
|
|
|
|
public Vector2 mouseGrid;
|
|
|
Vector2 original_point;
|
|
|
|
|
|
//for now
|
|
|
public bool in_zone;
|
|
|
public bool in_active_zone;
|
|
|
public bool in_preserve;
|
|
|
|
|
|
public bool isPlaying = false;
|
|
|
|
|
|
private ImGuiRenderer _imGuiRenderer;
|
|
|
private DebugWindow debugWindow;
|
|
|
|
|
|
public ImGuiImageMap imageMap;
|
|
|
public ImGuiImageMap portraitsMap;
|
|
|
|
|
|
public bool show_another_window;
|
|
|
|
|
|
public Story Story;
|
|
|
|
|
|
//buggy
|
|
|
private static bool enableCulling = false;
|
|
|
|
|
|
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;
|
|
|
|
|
|
//Encompass
|
|
|
private WorldBuilder WorldBuilder = new WorldBuilder();
|
|
|
private World World;
|
|
|
|
|
|
private ImGuiWindowBridgeEngine imGuiWindowBridgeEngine;
|
|
|
|
|
|
public bool quit = false;
|
|
|
|
|
|
|
|
|
|
|
|
private static void Main(string[] args)
|
|
|
{
|
|
|
#if NETCOREAPP
|
|
|
DllMap.Initialise(false);
|
|
|
#endif
|
|
|
try {
|
|
|
using FNAGame g = new FNAGame();
|
|
|
g.Run();
|
|
|
}
|
|
|
catch (Exception e)
|
|
|
{
|
|
|
Logging.Critical(string.Format("Unhandled exception: {0}", e));
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
#if !DEBUG
|
|
|
Logging.logFile.Close();
|
|
|
File.Delete(Logging.logFileName);
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
|
|
|
private FNAGame()
|
|
|
{
|
|
|
|
|
|
#if DEBUG
|
|
|
foreach (System.Reflection.Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
|
|
|
{
|
|
|
Logging.Debug("Loaded: " + assembly.ToString() + "\n");
|
|
|
}
|
|
|
;
|
|
|
|
|
|
#endif
|
|
|
this.gdm = new GraphicsDeviceManager(this) {
|
|
|
// Typically you would load a config here...
|
|
|
PreferredBackBufferWidth = width,
|
|
|
PreferredBackBufferHeight = height,
|
|
|
IsFullScreen = false,
|
|
|
SynchronizeWithVerticalRetrace = true
|
|
|
};
|
|
|
IsFixedTimeStep = false;
|
|
|
|
|
|
this.simulation = new Simulation(this.squaresAcross, this.squaresDown, new float[] {16.66667f*240, 16.66667f*120, 16.66667f*60, 16.66667f*30, 16.66667f*1 });
|
|
|
|
|
|
|
|
|
showBudget = false;
|
|
|
showGrid = true;
|
|
|
showTrees = true;
|
|
|
|
|
|
this.Window.Title = "Isometric Park";
|
|
|
|
|
|
Content.RootDirectory = "Content";
|
|
|
}
|
|
|
|
|
|
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...
|
|
|
this.batch = new SpriteBatch(GraphicsDevice);
|
|
|
this.tileBatch = new SpriteBatch(GraphicsDevice);
|
|
|
|
|
|
#if DEBUG
|
|
|
sound = Content.Load<SoundEffect>("FNASound");
|
|
|
#endif
|
|
|
Tile.TileSetTexture = Content.Load<Texture2D>(@"merged_tileset");
|
|
|
var texture = Content.Load<Texture2D>(@"solid_tileset");
|
|
|
|
|
|
var imageMapTexture = Content.Load<Texture2D>(@"photos_converted3");
|
|
|
this.imageMap = new ImGuiImageMap(500, 400, imageMapTexture, _imGuiRenderer, null);
|
|
|
|
|
|
var portraitMapTexture = Content.Load<Texture2D>(@"portraits");
|
|
|
this.portraitsMap = new ImGuiImageMap(300, 400, portraitMapTexture, _imGuiRenderer, @"Content/portraits.yaml");
|
|
|
|
|
|
Line.initialize(GraphicsDevice);
|
|
|
Quad.Initialize(GraphicsDevice, texture);
|
|
|
Logging.Success("Initialized Quad texture.");
|
|
|
ContractWindow.LoadContent(this._imGuiRenderer, this.imageMap);
|
|
|
DialogInterface.LoadContent(this._imGuiRenderer, this.portraitsMap);
|
|
|
|
|
|
//Must be done before SetFontMessage is sent
|
|
|
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)
|
|
|
}
|
|
|
);
|
|
|
|
|
|
var bakedMonoLarge = TtfFontBaker.Bake(File.OpenRead(@"Content/iosevka-term-extendedmedium.ttf"),
|
|
|
30,
|
|
|
1024,
|
|
|
1024,
|
|
|
new[]
|
|
|
{
|
|
|
CharacterRange.BasicLatin,
|
|
|
CharacterRange.Latin1Supplement,
|
|
|
CharacterRange.LatinExtendedA,
|
|
|
CharacterRange.Cyrillic,
|
|
|
CharacterRange.LatinExtendedB,
|
|
|
new CharacterRange((char) 0x00B7)
|
|
|
}
|
|
|
);
|
|
|
monoFont = bakedMono.CreateSpriteFont(GraphicsDevice);
|
|
|
largeMonoFont = bakedMonoLarge.CreateSpriteFont(GraphicsDevice);
|
|
|
|
|
|
//Has to happen before Encompass stuff, because the Encompass machinery around ImGui requires debugWindow's monoFont to be loaded:
|
|
|
this.debugWindow = new DebugWindow(this._imGuiRenderer, GraphicsDevice, this.imageMap);
|
|
|
|
|
|
//Has to happen before Encompass stuff, so Spawners can use the grammar:
|
|
|
var json2 = new FileInfo(@"Content/grammar.json");
|
|
|
|
|
|
this.grammar = new TraceryNet.Grammar(json2);
|
|
|
|
|
|
//Has to happen after Grammar initialization.
|
|
|
NewGameWindow.Initialize(this.grammar);
|
|
|
|
|
|
this.Story = new Story(File.ReadAllText(@"Content/dialog.json"));
|
|
|
//Bindings have to
|
|
|
Story.BindExternalFunction ("endGame", () => {
|
|
|
Logging.Success("endGame");
|
|
|
this.imGuiWindowBridgeEngine.gameStateMessages.Add(new GameStateMessage {isPlaying = false});
|
|
|
this.imGuiWindowBridgeEngine.typeMessages.Add(new ToggleWindowTypeMessage {Window = isometricparkfna.Messages.Window.MainMenu});
|
|
|
});
|
|
|
|
|
|
Logging.Debug(this.Story.ContinueMaximally());
|
|
|
|
|
|
WorldBuilder.AddEngine(new InputEngine(Menu.MENU_BAR_HEIGHT, this.camera, gdm,
|
|
|
this.simulation.map.MapHeight, this.simulation.map.MapWidth));
|
|
|
WorldBuilder.AddEngine(new UIEngine(this.Story));
|
|
|
WorldBuilder.AddEngine(new DialogEngine(this.Story, this.grammar));
|
|
|
|
|
|
WorldBuilder.AddEngine(new EventEngine());
|
|
|
|
|
|
var gameBridgeEngine = new GameBridgeEngine(this);
|
|
|
|
|
|
WorldBuilder.AddEngine(gameBridgeEngine);
|
|
|
WorldBuilder.AddEngine(new GameStateEngine());
|
|
|
WorldBuilder.AddEngine(this.simulation.BridgeEngine);
|
|
|
WorldBuilder.AddEngine(new CameraBridgeEngine(this.camera));
|
|
|
this.imGuiWindowBridgeEngine = new ImGuiWindowBridgeEngine(this.debugWindow, debugWindow.monoFont, debugWindow.italicFont, this.simulation);
|
|
|
WorldBuilder.AddEngine(this.imGuiWindowBridgeEngine);
|
|
|
WorldBuilder.AddEngine(new ContractStatusEngine(this.simulation));
|
|
|
|
|
|
WorldBuilder.AddEngine(new ContractSpawner(simulation.map.MapWidth, simulation.map.MapHeight, this.simulation, this.grammar));
|
|
|
WorldBuilder.AddEngine(new GameSpawner(this.simulation, this, this.grammar));
|
|
|
WorldBuilder.AddEngine(new OrganizationSpawner(this.simulation, this.grammar));
|
|
|
WorldBuilder.AddEngine(new DialogSpawner(this.Story, this.grammar));
|
|
|
WorldBuilder.AddEngine(new PolicyEngine());
|
|
|
WorldBuilder.AddEngine(new TraceryBridgeEngine(this.grammar));
|
|
|
WorldBuilder.AddEngine(new SimulationGameRateBridgeEngine(this.simulation));
|
|
|
WorldBuilder.AddEngine(new BuildToolEngine(this.simulation.map));
|
|
|
|
|
|
WorldBuilder.AddGeneralRenderer(new AreaRenderer(this.tileBatch, this.monoFont), 1);
|
|
|
WorldBuilder.AddGeneralRenderer(new ImGuiWindowRenderer(this, this.simulation, this.imGuiWindowBridgeEngine, this.gdm), 2);
|
|
|
WorldBuilder.AddGeneralRenderer(new CursorRenderer(this.tileBatch, this.monoFont), 3);
|
|
|
var contractWindow = WorldBuilder.CreateEntity();
|
|
|
WorldBuilder.SetComponent(contractWindow, new VisibilityComponent { visible = false });
|
|
|
WorldBuilder.SetComponent(contractWindow, new WindowTypeComponent { type = isometricparkfna.Messages.Window.Contracts });
|
|
|
|
|
|
|
|
|
var forestWindow = WorldBuilder.CreateEntity();
|
|
|
WorldBuilder.SetComponent(forestWindow, new VisibilityComponent { visible = false });
|
|
|
WorldBuilder.SetComponent(forestWindow, new WindowTypeComponent { type = isometricparkfna.Messages.Window.Forest });
|
|
|
|
|
|
var newsWindow = WorldBuilder.CreateEntity();
|
|
|
WorldBuilder.SetComponent(newsWindow, new VisibilityComponent { visible = false });
|
|
|
WorldBuilder.SetComponent(newsWindow, new WindowTypeComponent { type = isometricparkfna.Messages.Window.News });
|
|
|
|
|
|
var mainMenu = WorldBuilder.CreateEntity();
|
|
|
WorldBuilder.SetComponent(mainMenu, new VisibilityComponent { visible = true });
|
|
|
WorldBuilder.SetComponent(mainMenu, new WindowTypeComponent { type = isometricparkfna.Messages.Window.MainMenu });
|
|
|
|
|
|
var inputMenu = WorldBuilder.CreateEntity();
|
|
|
WorldBuilder.SetComponent(inputMenu, new VisibilityComponent { visible = false });
|
|
|
WorldBuilder.SetComponent(inputMenu, new WindowTypeComponent { type = isometricparkfna.Messages.Window.InGameMenu });
|
|
|
|
|
|
var optionsWindow = WorldBuilder.CreateEntity();
|
|
|
WorldBuilder.SetComponent(optionsWindow, new VisibilityComponent { visible = false });
|
|
|
WorldBuilder.SetComponent(optionsWindow, new WindowTypeComponent { type = isometricparkfna.Messages.Window.Options });
|
|
|
|
|
|
var newGameWindow = WorldBuilder.CreateEntity();
|
|
|
WorldBuilder.SetComponent(newGameWindow, new VisibilityComponent { visible = false });
|
|
|
WorldBuilder.SetComponent(newGameWindow, new WindowTypeComponent { type = isometricparkfna.Messages.Window.NewGame });
|
|
|
|
|
|
var graphWindow = WorldBuilder.CreateEntity();
|
|
|
WorldBuilder.SetComponent(graphWindow, new VisibilityComponent { visible = false });
|
|
|
WorldBuilder.SetComponent(graphWindow, new WindowTypeComponent { type = isometricparkfna.Messages.Window.Graph });
|
|
|
|
|
|
//Create a tool for each tool type.
|
|
|
foreach (var tool in System.Enum.GetValues(typeof(Tool))) {
|
|
|
if ((Tool)tool != Tool.None) {
|
|
|
var toolEntity = WorldBuilder.CreateEntity();
|
|
|
WorldBuilder.SetComponent(toolEntity, new ToolComponent { Tool = (Tool)tool });
|
|
|
WorldBuilder.SetComponent(toolEntity, new SelectedComponent {Type = SelectionType.Tool, selected = ((Tool)tool == Tool.Preserve)});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// var preserveTool = WorldBuilder.CreateEntity();
|
|
|
// WorldBuilder.SetComponent(preserveTool, new ToolComponent { Tool = Tool.Preserve });
|
|
|
// WorldBuilder.SetComponent(preserveTool, new SelectedComponent {Type = SelectionType.Tool, selected = true});
|
|
|
//
|
|
|
// var dezoneTool = WorldBuilder.CreateEntity();
|
|
|
// WorldBuilder.SetComponent(dezoneTool, new ToolComponent { Tool = Tool.Dezone });
|
|
|
// WorldBuilder.SetComponent(dezoneTool, new SelectedComponent {Type = SelectionType.Tool, selected = false});
|
|
|
|
|
|
|
|
|
var gameEntity = WorldBuilder.CreateEntity();
|
|
|
|
|
|
WorldBuilder.SetComponent(gameEntity, new GameStateComponent { isPlaying = false});
|
|
|
|
|
|
var policyEntity = WorldBuilder.CreateEntity();
|
|
|
WorldBuilder.SetComponent(policyEntity,
|
|
|
new TrespassingPolicyComponent { tresspassingPolicy = EnforcementLevel.NoEnforcement});
|
|
|
WorldBuilder.SetComponent(policyEntity,
|
|
|
new BudgetLineComponent { });
|
|
|
|
|
|
try {
|
|
|
var options = Options.readOptions();
|
|
|
|
|
|
this.imGuiWindowBridgeEngine.fontMessages.Add(new SetFontMessage {
|
|
|
fontSize = options.fontSize,
|
|
|
fontName = options.fontName
|
|
|
});
|
|
|
|
|
|
WorldBuilder.SetComponent(gameEntity, new OptionsComponent {ProfanitySetting = options.profanitySetting});
|
|
|
|
|
|
OptionsWindow.Initialize(new Vector2(FNAGame.width, FNAGame.height), gdm.IsFullScreen, options.profanitySetting);
|
|
|
Logging.Success("Loaded options.");
|
|
|
|
|
|
}
|
|
|
catch (FileNotFoundException e)
|
|
|
{
|
|
|
Logging.Error(String.Format("Error loading file: {0}", e.ToString()));
|
|
|
}
|
|
|
|
|
|
World = WorldBuilder.Build();
|
|
|
|
|
|
this.output = grammar.Flatten("#greeting#");
|
|
|
var result = grammar.Flatten("#[assistantName:#assistantNames#][friendOfThePark:#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.budgetWindow = new BudgetWindow(new Budget { }, this.monoFont, 0, 0);
|
|
|
|
|
|
Logging.Success("Content loaded.");
|
|
|
}
|
|
|
|
|
|
|
|
|
public void setFont(string font, int size)
|
|
|
{
|
|
|
var font_path = DebugWindow.fonts[font];
|
|
|
|
|
|
var baked = TtfFontBaker.Bake(File.OpenRead(font_path),
|
|
|
size,
|
|
|
1024,
|
|
|
1024,
|
|
|
new[]
|
|
|
{
|
|
|
CharacterRange.BasicLatin,
|
|
|
CharacterRange.Latin1Supplement,
|
|
|
CharacterRange.LatinExtendedA,
|
|
|
CharacterRange.Cyrillic,
|
|
|
CharacterRange.LatinExtendedB,
|
|
|
new CharacterRange((char) 0x00B7)
|
|
|
}
|
|
|
);
|
|
|
|
|
|
this.monoFont = baked.CreateSpriteFont(GraphicsDevice);
|
|
|
}
|
|
|
|
|
|
|
|
|
protected override void UnloadContent()
|
|
|
{
|
|
|
batch.Dispose();
|
|
|
#if DEBUG
|
|
|
sound.Dispose();
|
|
|
#endif
|
|
|
Tile.TileSetTexture.Dispose();
|
|
|
Logging.Success("Disposed of Tile texture.");
|
|
|
if (Quad.PixelTexture != null)
|
|
|
{
|
|
|
Quad.PixelTexture.Dispose();
|
|
|
Logging.Success("Disposed of Pixel texture.");
|
|
|
}
|
|
|
if (Quad.SolidTexture != null)
|
|
|
{
|
|
|
Quad.SolidTexture.Dispose();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
Vector2 calculateMousegrid(Vector2 normalizedMousePos)
|
|
|
{
|
|
|
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);
|
|
|
}
|
|
|
|
|
|
|
|
|
private String CurrentStatus() {
|
|
|
|
|
|
if (this.in_active_zone) {
|
|
|
return "Contracted";
|
|
|
}
|
|
|
else if (this.in_zone) {
|
|
|
return "Proposed Contract";
|
|
|
}
|
|
|
else if (this.in_preserve) {
|
|
|
return "Preserve";
|
|
|
}
|
|
|
else {
|
|
|
return "Unused";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected override void Update(GameTime gameTime)
|
|
|
{
|
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
|
stopWatch.Start();
|
|
|
|
|
|
#if DEBUG
|
|
|
float volume = 1.0f;
|
|
|
float pitch = 0.0f;
|
|
|
float pan = 0.0f;
|
|
|
#endif
|
|
|
|
|
|
KeyboardState keyboardCur = Keyboard.GetState();
|
|
|
MouseState mouseCur = Mouse.GetState();
|
|
|
|
|
|
#region input
|
|
|
|
|
|
#region misc_keys
|
|
|
#if DEBUG
|
|
|
if (keyboardCur.IsKeyDown(Keys.OemBackslash)
|
|
|
&& keyboardPrev.IsKeyUp(Keys.OemBackslash)
|
|
|
&& keyboardCur.IsKeyDown(Keys.LeftShift))
|
|
|
{
|
|
|
sound.Play(volume, pitch, pan);
|
|
|
}
|
|
|
#endif
|
|
|
#endregion misc_keys
|
|
|
#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);
|
|
|
}
|
|
|
|
|
|
|
|
|
this.original_point = Vector2.Transform(new Vector2(mouseCur.X, mouseCur.Y), Matrix.Invert(camera.get_transformation(GraphicsDevice)));
|
|
|
|
|
|
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;
|
|
|
this.mousePrev = mouseCur;
|
|
|
|
|
|
stopWatch.Stop();
|
|
|
this.updateTime = stopWatch.Elapsed;
|
|
|
|
|
|
base.Update(gameTime);
|
|
|
|
|
|
if (quit) {
|
|
|
this.Exit();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
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.BetweenExclusive(original.X, -Tile.TileSpriteWidth, FNAGame.width)
|
|
|
&& MathUtils.BetweenExclusive(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, Color color)
|
|
|
{
|
|
|
float maxdepth = ((this.squaresAcross + 1) + ((this.squaresDown + 1) * Tile.TileWidth)) * 10;
|
|
|
|
|
|
float depthOffset = 0.7f - ((x + (y * Tile.TileWidth)) / maxdepth);
|
|
|
|
|
|
Tile.drawTileAt(this.tileBatch, x, y, tileIndex, height, depthOffset, color);
|
|
|
}
|
|
|
|
|
|
protected void drawTileAt(int x, int y, int tileIndex, int height) {
|
|
|
drawTileAt(x, y, tileIndex, height, Color.White);
|
|
|
}
|
|
|
|
|
|
|
|
|
protected override void Draw(GameTime gameTime)
|
|
|
{
|
|
|
frameCounter++;
|
|
|
|
|
|
string fps = string.Format("fps: {0}", frameRate);
|
|
|
bool has_tree = false;
|
|
|
|
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
|
stopWatch.Start();
|
|
|
GraphicsDevice.Clear(Color.CornflowerBlue);
|
|
|
|
|
|
_imGuiRenderer.BeforeLayout(gameTime);
|
|
|
if (this.isPlaying)
|
|
|
{
|
|
|
batch.Begin(SpriteSortMode.Deferred,
|
|
|
BlendState.AlphaBlend,
|
|
|
null,
|
|
|
null,
|
|
|
null,
|
|
|
null,
|
|
|
camera.get_transformation(GraphicsDevice));
|
|
|
|
|
|
|
|
|
#region draw_tiles
|
|
|
Stopwatch stopWatch2 = new Stopwatch();
|
|
|
stopWatch2.Start();
|
|
|
//reset
|
|
|
this.tilesDrawn = 0;
|
|
|
|
|
|
var scale_factor = 1;
|
|
|
var x_adjust = scale_factor > 1 ? -scale_factor : 0;
|
|
|
var y_adjust = scale_factor > 1 ? -scale_factor/2 : 0;
|
|
|
|
|
|
for (int y = y_adjust; y < this.squaresDown + y_adjust; y += scale_factor)
|
|
|
{
|
|
|
for (int x = x_adjust; x < this.squaresAcross + x_adjust; x += scale_factor)
|
|
|
{
|
|
|
int screenx = (x - y) * (Tile.TileSpriteWidth) / 2 - 3*scale_factor;
|
|
|
int screeny = (x + y) * (Tile.TileSpriteHeight) / 2;
|
|
|
|
|
|
// if (this.cull(x, y))
|
|
|
// {
|
|
|
batch.Draw(
|
|
|
Tile.TileSetTexture,
|
|
|
new Rectangle(
|
|
|
screenx,
|
|
|
screeny,
|
|
|
Tile.TileWidth * scale_factor, Tile.TileHeight * scale_factor),
|
|
|
Tile.GetSourceRectangle(1),
|
|
|
Color.White,
|
|
|
0.0f,
|
|
|
Vector2.Zero,
|
|
|
SpriteEffects.None,
|
|
|
0.9f);
|
|
|
|
|
|
this.tilesDrawn++;
|
|
|
// }
|
|
|
}
|
|
|
}
|
|
|
batch.End();
|
|
|
stopWatch2.Stop();
|
|
|
this.tileDrawTime = stopWatch2.Elapsed;
|
|
|
#endregion draw_tiles
|
|
|
|
|
|
#region draw_gridlines
|
|
|
batch.Begin(SpriteSortMode.Deferred,
|
|
|
BlendState.AlphaBlend,
|
|
|
null,
|
|
|
null,
|
|
|
null,
|
|
|
null,
|
|
|
camera.get_transformation(GraphicsDevice));
|
|
|
stopWatch2 = new Stopwatch();
|
|
|
stopWatch2.Start();
|
|
|
|
|
|
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 - (y)) * Tile.TileSpriteWidth / 2,
|
|
|
(this.squaresAcross + (y)) * Tile.TileSpriteHeight / 2) + adjust,
|
|
|
|
|
|
Color.White, 0.81f);//Just below the highlighted square and areas
|
|
|
|
|
|
}
|
|
|
|
|
|
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((x - this.squaresDown) * Tile.TileSpriteWidth / 2, (x + this.squaresDown) * Tile.TileSpriteHeight / 2) + adjust,
|
|
|
Color.White, 0.81f);
|
|
|
|
|
|
}
|
|
|
}
|
|
|
batch.End();
|
|
|
stopWatch2.Stop();
|
|
|
this.gridDrawTime = stopWatch2.Elapsed;
|
|
|
#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);
|
|
|
|
|
|
}
|
|
|
*/
|
|
|
tileBatch.Begin(SpriteSortMode.BackToFront,
|
|
|
BlendState.AlphaBlend,
|
|
|
null,
|
|
|
null,
|
|
|
null,
|
|
|
null,
|
|
|
camera.get_transformation(GraphicsDevice));
|
|
|
#if DEBUG
|
|
|
|
|
|
var translucent = new Color(1.0f, 1.0f, 1.0f, 0.25f);
|
|
|
drawTileAt(4, 4, 140, 3, translucent);
|
|
|
drawTileAt(6, 4, 141, 3, translucent);
|
|
|
drawTileAt(8, 4, 142, 2, translucent);
|
|
|
drawTileAt(10, 4, 142, 3, translucent);
|
|
|
|
|
|
for (int i = 10; i < 199; i++) {
|
|
|
drawTileAt(10, i, 281, 1, translucent);
|
|
|
}
|
|
|
drawTileAt(10, 199, 284, 1, translucent);
|
|
|
drawTileAt(11, 199, 280, 1, translucent);
|
|
|
drawTileAt(12, 199, 280, 1, translucent);
|
|
|
drawTileAt(13, 199, 283, 1, translucent);
|
|
|
drawTileAt(13, 198, 281, 1, translucent);
|
|
|
drawTileAt(13, 197, 282, 1, translucent);
|
|
|
drawTileAt(12, 197, 285, 1, translucent);
|
|
|
drawTileAt(12, 25, 300, 2, translucent);
|
|
|
#endif
|
|
|
|
|
|
#if DEBUG
|
|
|
Tile.OutlineSquare(tileBatch, 1, 1, Color.Red, 2);
|
|
|
Tile.OutlineSquare(tileBatch, 3, 1, Color.Blue, 2);
|
|
|
Tile.OutlineSquare(tileBatch, 5, 1, Color.Green, 2);
|
|
|
Tile.OutlineSquare(tileBatch, 7, 1, Color.Orange, 2);
|
|
|
Tile.OutlineSquare(tileBatch, 9, 1, Color.Orange, 3);
|
|
|
|
|
|
//donut
|
|
|
Tile.DrawOutlinedSquares(tileBatch, 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);
|
|
|
|
|
|
Quad.FillSquare2(tileBatch, 7, 4, Color.Orange, 1.0f, 0.79f);
|
|
|
Quad.FillSquare2(tileBatch, 7, 3, Color.Yellow, 1.0f, 0.79f);
|
|
|
Quad.FillSquare2(tileBatch, 7, 5, Color.Yellow, .5f, 0.79f);
|
|
|
Quad.FillSquare2(tileBatch, 7, 6, Color.Yellow, .25f, 0.79f);
|
|
|
Quad.FillSquare2(tileBatch, 7, 7, Color.Yellow, .125f, 0.79f);
|
|
|
Quad.FillSquare2(tileBatch, 8, 5, Color.Teal, .5f, 0.79f);
|
|
|
Quad.FillSquare2(tileBatch, 8, 6, Color.Teal, .25f, 0.79f);
|
|
|
Quad.FillSquare2(tileBatch, 8, 7, Color.Teal, .125f, 0.79f);
|
|
|
#endif
|
|
|
|
|
|
stopWatch2 = new Stopwatch();
|
|
|
stopWatch2.Start();
|
|
|
#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:
|
|
|
if (this.simulation.map.cells[i][j].Type == TreeType.GenericDeciduous) {
|
|
|
drawTileAt(i, j, 252, 2); // 142, , 262
|
|
|
}
|
|
|
else if (this.simulation.map.cells[i][j].Type == TreeType.Oak) {
|
|
|
drawTileAt(i, j, 142, 2);
|
|
|
}
|
|
|
else if (this.simulation.map.cells[i][j].Type == TreeType.GenericShrub) {
|
|
|
drawTileAt(i, j, 210, 2);
|
|
|
}
|
|
|
else {
|
|
|
drawTileAt(i, j, 122, 2); //122, 203, 221
|
|
|
}
|
|
|
// 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));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
stopWatch2.Stop();
|
|
|
this.treeDrawTime = stopWatch2.Elapsed;
|
|
|
#endregion draw_trees
|
|
|
|
|
|
#if DEBUG
|
|
|
drawTileAt(2, 2, 140, 2);
|
|
|
drawTileAt(1, 1, 140, 2);
|
|
|
drawTileAt(3, 2, 140, 2);
|
|
|
#endif
|
|
|
|
|
|
World.Draw();
|
|
|
// _imGuiRenderer.AfterLayout();
|
|
|
tileBatch.End();
|
|
|
|
|
|
#region draw_header
|
|
|
batch.Begin(SpriteSortMode.BackToFront,
|
|
|
BlendState.AlphaBlend,
|
|
|
null,
|
|
|
null,
|
|
|
null,
|
|
|
null);
|
|
|
|
|
|
if (MathUtils.BetweenExclusive(this.mouseGrid.X, 0, this.squaresAcross)
|
|
|
&& MathUtils.BetweenExclusive(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.BetweenExclusive(this.mouseGrid.X, -1, this.simulation.map.MapWidth)
|
|
|
&& MathUtils.BetweenExclusive(this.mouseGrid.Y, -1, this.simulation.map.MapHeight))
|
|
|
{
|
|
|
var treeStatus = this.simulation.map.cells[(int)this.mouseGrid.X][(int)this.mouseGrid.Y].Status;
|
|
|
var treeStatusAdjective = this.simulation.map.cells[(int)this.mouseGrid.X][(int)this.mouseGrid.Y].StatusAdjective;
|
|
|
var treeType = this.simulation.map.cells[(int)this.mouseGrid.X][(int)this.mouseGrid.Y].TypeName;
|
|
|
var useStatus = this.CurrentStatus();
|
|
|
if (treeStatus != CellStatus.Clear)
|
|
|
{
|
|
|
status_left = String.Format("{0:},{1:} {2} {3} ({4})", this.mouseGrid.X, this.mouseGrid.Y,
|
|
|
treeStatusAdjective,
|
|
|
treeType,
|
|
|
useStatus);
|
|
|
}
|
|
|
else {
|
|
|
status_left = String.Format("{0:},{1:} {2} ({3})", this.mouseGrid.X, this.mouseGrid.Y,
|
|
|
treeStatusAdjective,
|
|
|
useStatus);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
#endregion draw_header
|
|
|
|
|
|
#region budget
|
|
|
|
|
|
if (this.showBudget)
|
|
|
{
|
|
|
budgetWindow.draw(batch);
|
|
|
}
|
|
|
|
|
|
#endregion budget
|
|
|
|
|
|
batch.End();
|
|
|
|
|
|
#region window
|
|
|
Menu.Render(debugWindow.monoFont, FNAGame.width, this.imGuiWindowBridgeEngine, ref quit, ref this.simulation.paused, ref this.simulation.currentRate, ref this.showBudget, header_left);
|
|
|
|
|
|
if (quit) {
|
|
|
System.Environment.Exit(0);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else {
|
|
|
GraphicsDevice.Clear(Color.Teal);
|
|
|
batch.Begin(SpriteSortMode.BackToFront,
|
|
|
BlendState.AlphaBlend,
|
|
|
null,
|
|
|
null,
|
|
|
null,
|
|
|
null);
|
|
|
|
|
|
Vector2 middle_dimensions = largeMonoFont.MeasureString("Isometric Park");
|
|
|
float middle_start = (int)((FNAGame.width / 2) - (middle_dimensions.X / 2));
|
|
|
batch.DrawString(largeMonoFont, "Isometric Park",
|
|
|
new Vector2(middle_start, 50),
|
|
|
Color.Black, 0.0f, Vector2.Zero,
|
|
|
1.0f, SpriteEffects.None, 0.5f);
|
|
|
batch.DrawString(largeMonoFont, "Isometric Park",
|
|
|
new Vector2(middle_start-1, 49),
|
|
|
Color.White, 0.0f, Vector2.Zero,
|
|
|
1.0f, SpriteEffects.None, 0.51f);
|
|
|
World.Draw();
|
|
|
|
|
|
Vector2 version_dimensions = monoFont.MeasureString(typeof(FNAGame).Assembly.GetName().Version.ToString());
|
|
|
batch.DrawString(monoFont,
|
|
|
typeof(FNAGame).Assembly.GetName().Version.ToString(),
|
|
|
new Vector2(0, FNAGame.height-version_dimensions.Y),
|
|
|
Color.White, 0.0f, Vector2.Zero,
|
|
|
1.0f, SpriteEffects.None, 0.51f);
|
|
|
|
|
|
Vector2 name_dimensions = monoFont.MeasureString("by actuallyalys<3");
|
|
|
float name_start = (int)(FNAGame.width / 2) - (name_dimensions.X / 2);
|
|
|
|
|
|
batch.DrawString(monoFont, "by actuallyalys <3",
|
|
|
new Vector2(name_start, 50+middle_dimensions.Y),
|
|
|
Color.White, 0.0f, Vector2.Zero,
|
|
|
1.0f, SpriteEffects.None, 0.51f);
|
|
|
batch.End();
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
#region debug_window
|
|
|
//Calcs for debug window:
|
|
|
past_draw.Enqueue(this.drawTime);
|
|
|
if ((this.frameCounter % 15) == 0)
|
|
|
{
|
|
|
past_fps.Enqueue(this.frameRate);
|
|
|
|
|
|
|
|
|
/*
|
|
|
if (this.frameRate > 60.0)
|
|
|
{
|
|
|
Logging.Warning(String.Format("Framerate is higher than limit: {0}", this.frameRate));
|
|
|
}
|
|
|
if (this.frameRate < 30.0)
|
|
|
{
|
|
|
Logging.Warning(String.Format("Framerate is lower than desired: {0}", this.frameRate));
|
|
|
}
|
|
|
*/
|
|
|
}
|
|
|
/*
|
|
|
if (this.frameRate > 120.0)
|
|
|
{
|
|
|
Logging.Error(String.Format("Framerate is much higher than limit: {0}", this.frameRate));
|
|
|
}
|
|
|
else if (this.frameRate < 15.0)
|
|
|
{
|
|
|
Logging.Error(String.Format("Framerate is much lower than desired: {0}", this.frameRate));
|
|
|
}
|
|
|
*/
|
|
|
|
|
|
DebugInfo debugInfo = new DebugInfo
|
|
|
{ fps = this.frameRate,
|
|
|
pastFps = past_fps.ToArray(),
|
|
|
cameraPosition = camera.position,
|
|
|
drawTime = this.drawTime,
|
|
|
treeDrawTime = this.treeDrawTime,
|
|
|
gridDrawTime = this.gridDrawTime,
|
|
|
tileDrawTime = this.tileDrawTime,
|
|
|
updateTime = this.updateTime,
|
|
|
treeCount = this.simulation.map.tree_count,
|
|
|
mouseGrid = this.mouseGrid,
|
|
|
hasTree = has_tree,
|
|
|
tilesDrawn = this.tilesDrawn
|
|
|
};
|
|
|
|
|
|
//Finally, draw the debug window
|
|
|
|
|
|
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());
|
|
|
|
|
|
string entries = "";
|
|
|
string descriptions = "";
|
|
|
foreach (var pair in DialogSpawner.indexes)
|
|
|
{
|
|
|
entries += String.Format("{0}={1},", pair.Key, pair.Value);
|
|
|
}
|
|
|
|
|
|
foreach (var meta in portraitsMap.Metadata)
|
|
|
{
|
|
|
descriptions += String.Format("{0}: {1}\n", meta.Filename,
|
|
|
meta.Description);
|
|
|
}
|
|
|
|
|
|
additionalInfo.Add("Tracery Test", this.output);
|
|
|
additionalInfo.Add("Log Entry", string.Format("{0} {1}", Logging.entries[Logging.entries.Count-1].level, Logging.entries[Logging.entries.Count-1].message));
|
|
|
additionalInfo.Add("Dialog entries", entries);
|
|
|
additionalInfo.Add("Metadata entries", descriptions);
|
|
|
|
|
|
if (past_fps.Count() > 5) {
|
|
|
additionalInfo.Add(".01%% fps", MathUtils.Percentile(past_fps.Skip(5).ToArray(), 0.0001f).ToString());
|
|
|
additionalInfo.Add(".1%% fps", MathUtils.Percentile(past_fps.Skip(5).ToArray(), 0.001f).ToString());
|
|
|
additionalInfo.Add("1%% fps", MathUtils.Percentile(past_fps.Skip(5).ToArray(), 0.01f).ToString());
|
|
|
additionalInfo.Add("50%% fps", MathUtils.Percentile(past_fps.Skip(5).ToArray(), 0.50f).ToString());
|
|
|
}
|
|
|
|
|
|
if (past_draw.Count() > 5) {
|
|
|
var past_draw_floats = past_draw.Skip(5).Select(ts => ts.TotalMilliseconds).ToArray();
|
|
|
additionalInfo.Add(".01%% draw", MathUtils.Percentile(past_draw_floats, 0.0001f).ToString());
|
|
|
additionalInfo.Add(".1%% draw", MathUtils.Percentile(past_draw_floats, 0.001f).ToString());
|
|
|
additionalInfo.Add("1%% draw", MathUtils.Percentile(past_draw_floats, 0.01f).ToString());
|
|
|
additionalInfo.Add("50%% draw", MathUtils.Percentile(past_draw_floats, 0.50f).ToString());
|
|
|
additionalInfo.Add("99%% draw", MathUtils.Percentile(past_draw_floats, 0.99f).ToString());
|
|
|
additionalInfo.Add("99.9%% draw", MathUtils.Percentile(past_draw_floats, 0.999f).ToString());
|
|
|
additionalInfo.Add("99.99%% draw", MathUtils.Percentile(past_draw_floats, 0.9999f).ToString());
|
|
|
}
|
|
|
|
|
|
debugWindow.Layout(debugInfo, additionalInfo, ref show_another_window);
|
|
|
|
|
|
_imGuiRenderer.AfterLayout();
|
|
|
|
|
|
#endregion debug_window
|
|
|
|
|
|
stopWatch.Stop();
|
|
|
this.drawTime = stopWatch.Elapsed;
|
|
|
|
|
|
base.Draw(gameTime);
|
|
|
}
|
|
|
|
|
|
public void setResolution(Vector2 newResolution, bool fullscreen)
|
|
|
{
|
|
|
FNAGame.width = (int)newResolution.X;
|
|
|
FNAGame.height = (int)newResolution.Y;
|
|
|
|
|
|
this.gdm.PreferredBackBufferWidth = (int)newResolution.X;
|
|
|
this.gdm.PreferredBackBufferHeight = (int)newResolution.Y;
|
|
|
this.gdm.IsFullScreen = fullscreen;
|
|
|
this.gdm.ApplyChanges();
|
|
|
}
|
|
|
}
|
|
|
|