Description:
Merge in m5-tiles-and-trees! ?
Commit status:
[Not Reviewed]
References:
merge default
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r682:ead2604f189e -

@@ -0,0 +1,11
1 using Microsoft.Xna.Framework;
2
3 using Encompass;
4
5 namespace isometricparkfna.Components {
6
7 public struct CursorComponent : IComponent {
8 public Vector2 position;
9 public int size;
10 }
11 }
@@ -0,0 +1,11
1 using Microsoft.Xna.Framework;
2
3 using Encompass;
4
5 namespace isometricparkfna.Components {
6
7 public struct PointComponent : IComponent {
8 public Vector2 Square;
9 public Tool Tool;
10 }
11 }
@@ -0,0 +1,10
1
2 using Encompass;
3 using System;
4
5 namespace isometricparkfna.Components {
6
7 public struct PreserveComponent : IComponent {
8 public DateTime date;
9 }
10 }
@@ -0,0 +1,17
1
2 using Encompass;
3
4 using isometricparkfna.Messages;
5
6 namespace isometricparkfna.Components {
7 public enum Structure
8 {
9 None,
10 Tower
11 }
12
13 public struct StructureComponent : IComponent {
14 public Structure Structure;
15 // public DateTime Placed;
16 }
17 }
@@ -0,0 +1,19
1 using Encompass;
2
3 using isometricparkfna.Messages;
4
5 namespace isometricparkfna.Components {
6
7 public enum Tool
8 {
9 None,
10 Preserve,
11 Dezone,
12 Tower,
13 Bulldozer
14 }
15
16 public struct ToolComponent : IComponent {
17 public Tool Tool;
18 }
19 }
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
@@ -0,0 +1,350
1 using System;
2 using System.Linq;
3 using System.Collections.Generic;
4 using Microsoft.Xna.Framework;
5 using Microsoft.Xna.Framework.Graphics;
6 using Microsoft.Xna.Framework.Input;
7
8 using Encompass;
9 using JM.LinqFaster;
10
11 using isometricparkfna.Messages;
12 using isometricparkfna.Components;
13
14 namespace isometricparkfna.Engines {
15
16 [Receives(typeof(SpawnSelection),
17 typeof(AdjustSelection),
18 typeof(UndoPreserveMessage))]
19 [Writes(typeof(AreaComponent),
20 typeof(PointComponent),
21 typeof(PreserveComponent))]
22 [Reads(typeof(SelectedComponent),
23 typeof(ContractStatusComponent),
24 typeof(AreaComponent),
25 typeof(PreserveComponent),
26 typeof(SelectedComponent),
27 typeof(ToolComponent),
28 typeof(PointComponent),
29 typeof(StructureComponent))]
30 [Sends(typeof(ChangeContractStatusMessage),
31 typeof(PlaySoundMessage),
32 typeof(SingleExpenseMessage),
33 typeof(SpawnDialogMessage))]
34 public class BuildToolEngine : Engine {
35
36 private CellMap Map;
37 private Simulation Simulation;
38
39 private static Dictionary<Tool, bool> ToolArea = new Dictionary<Tool, bool> {{Tool.Preserve, true},
40 {Tool.Dezone, true},
41 {Tool.Tower, false},
42 {Tool.Bulldozer, true}};
43
44 public BuildToolEngine(Simulation simulation) {
45 this.Map = simulation.map;
46 this.Simulation = simulation;
47 }
48
49 private System.Collections.Generic.IEnumerable<float> step_until(float start, float stop) {
50 if (stop >= start) {
51 for(float i = start; i <= stop; i++)
52 {
53 yield return i;
54 }
55 }
56 else {
57 for(float i = start; i >= stop; i--)
58 {
59 yield return i;
60 }
61 }
62 }
63
64 private void clear_areas(Vector2[] clear_squares) {
65 List<Entity> entities = new List<Entity>();
66 foreach(ref readonly var entity in ReadEntities<AreaComponent>() ) {
67 var squares = GetComponent<AreaComponent>(entity).squares;
68
69 foreach(var clear_square in clear_squares) {
70
71 foreach(var square in squares) {
72 if(square == clear_square) {
73 entities.Add(entity);
74 break;
75 }
76 }
77 }
78 }
79
80 foreach(var entity in entities) {
81 Logging.Debug("Deleting entity.");
82
83 if (HasComponent<ContractStatusComponent>(entity)) {
84 SendMessage(new ChangeContractStatusMessage {newStatus = ContractStatus.Broken, Entity = entity});
85 }
86 else {
87 Destroy(entity);
88 }
89 }
90 }
91
92 private void clear_structures(Vector2[] clear_squares) {
93 List<Entity> entities = new List<Entity>();
94 foreach(ref readonly var entity in ReadEntities<StructureComponent>() ) {
95 var square = GetComponent<PointComponent>(entity).Square;
96
97 foreach(var clear_square in clear_squares) {
98 if(square == clear_square) {
99 entities.Add(entity);
100 }
101 }
102 }
103
104 foreach(var entity in entities) {
105 Logging.Debug("Deleting entity.");
106 Destroy(entity);
107 }
108 }
109
110 private void SpawnSelection(Tool tool) {
111 foreach (ref readonly var message in ReadMessages<SpawnSelection>())
112 {
113 if (message.Start.X >= 0 && message.Start.X < this.Map.MapWidth
114 && message.Start.Y >= 0 && message.Start.Y < this.Map.MapHeight) {
115 var entity = CreateEntity();
116 if (BuildToolEngine.ToolArea[tool]) {
117 AddComponent(entity, new AreaComponent {squares = new[] {message.Start},
118 Tool = tool});
119 }
120 else {
121 AddComponent(entity, new PointComponent {Square = message.Start,
122 Tool=tool});
123 }
124 AddComponent(entity, new SelectedComponent {selected = true, Type= SelectionType.Area});
125 }
126 }
127 }
128
129
130 public List<Vector2> GetOccupied() {
131 List<Vector2> occupied = new List<Vector2>();
132
133 foreach (var (entity, status) in ReadEntities<AreaComponent>()
134 .WhereF((e) => HasComponent<ContractStatusComponent>(e))
135 .SelectWhereF((e) => (e, GetComponent<ContractStatusComponent>(e)),
136 (e) => ((e.Item2.status != ContractStatus.Broken)
137 && (e.Item2.status != ContractStatus.Rejected)
138 && (e.Item2.status != ContractStatus.Expired)
139 && (e.Item2.status != ContractStatus.Completed)
140 && (e.Item2.status != ContractStatus.Proposed))
141 )) {
142 var entitySquares = GetComponent<AreaComponent>(entity).squares;
143 occupied.AddRange(entitySquares);
144 }
145 return occupied;
146 }
147
148 public override void Update(double dt) {
149 Dictionary<Tool, bool> statuses = new Dictionary<Tool, bool>();
150
151 foreach (var entity in ReadEntities<ToolComponent>()) {
152 var tool = GetComponent<ToolComponent>(entity);
153 var selected = GetComponent<SelectedComponent>(entity);
154
155 statuses.Add(tool.Tool, selected.selected);
156 }
157
158 if (statuses.ContainsKey(Tool.Preserve) && statuses[Tool.Preserve]) {
159 var occupied = GetOccupied();
160 foreach (var entity in ReadEntities<AreaComponent>()
161 .WhereF((e) => HasComponent<PreserveComponent>(e))) {
162 var entitySquares = GetComponent<AreaComponent>(entity).squares;
163 occupied.AddRange(entitySquares);
164 }
165
166 SpawnSelection(Tool.Preserve);
167
168 foreach (ref readonly var message in ReadMessages<AdjustSelection>()) {
169 foreach (ref readonly var entity in ReadEntities<SelectedComponent>()) {
170 var selection = GetComponent<SelectedComponent>(entity);
171 if(selection.Type == SelectionType.Area
172 && selection.selected) {
173 if(message.Type == AdjustmentType.Clear) {
174 Destroy(entity);
175 }
176 else if(message.Type == AdjustmentType.Complete) {
177 SetComponent(entity, new PreserveComponent {date = this.Simulation.DateTime});
178 // SetComponent(entity, new SelectedComponent {selected = false });
179 var area = GetComponent<AreaComponent>(entity);
180 if (area.squares.Length > 400) {
181 SendMessage<SpawnDialogMessage>(new SpawnDialogMessage {
182 Path = "LargePreserve" });
183 }
184 }
185 else {
186 var area = GetComponent<AreaComponent>(entity);
187
188 var newSquares = new List<Vector2>();
189
190 var end_x = MathUtils.Clamp(message.End.X, 0.0f, this.Map.MapWidth-1);
191 var end_y = MathUtils.Clamp(message.End.Y, 0.0f, this.Map.MapHeight-1);
192
193 if (area.squares.Length > 0) {
194 foreach (var i in step_until(area.squares[0].X, end_x)) {
195 foreach (var j in step_until(area.squares[0].Y, end_y)) {
196 var newSquare = new Vector2(i, j);
197 if (!occupied.Contains(newSquare)) {
198 newSquares.Add(newSquare);
199 }
200 }
201 }
202 }
203 SetComponent(entity, new AreaComponent { squares = newSquares.ToArray(), Tool = area.Tool});
204 }
205 }
206 }
207 }
208 }
209 else if (statuses.ContainsKey(Tool.Dezone) && statuses[Tool.Dezone]) {
210 SpawnSelection(Tool.Dezone);
211
212 foreach (ref readonly var message in ReadMessages<AdjustSelection>()) {
213 foreach (ref readonly var entity in ReadEntities<SelectedComponent>()) {
214 var selection = GetComponent<SelectedComponent>(entity);
215 if(selection.Type == SelectionType.Area
216 && selection.selected) {
217 if(message.Type == AdjustmentType.Clear) {
218 Destroy(entity);
219 }
220 else if(message.Type == AdjustmentType.Complete) {
221 var squares = GetComponent<AreaComponent>(entity).squares;
222 clear_areas(squares);
223 }
224 else {
225 var area = GetComponent<AreaComponent>(entity);
226
227 var newSquares = new List<Vector2>();
228
229 var end_x = MathUtils.Clamp(message.End.X, 0.0f, this.Map.MapWidth);
230 var end_y = MathUtils.Clamp(message.End.Y, 0.0f, this.Map.MapHeight);
231
232 foreach (var i in step_until(area.squares[0].X, end_x)) {
233 foreach (var j in step_until(area.squares[0].Y, end_y)) {
234 var newSquare = new Vector2(i, j);
235 newSquares.Add(newSquare);
236 }
237 }
238 SetComponent(entity, new AreaComponent { squares = newSquares.ToArray(), Tool = area.Tool});
239 }
240 }
241 }
242 }
243 }
244 else if (statuses.ContainsKey(Tool.Tower) && statuses[Tool.Tower]) {
245 SpawnSelection(Tool.Tower);
246
247 var occupied = GetOccupied();
248
249 foreach (var (entity, point) in ReadEntities<StructureComponent>()
250 .WhereF((e) => HasComponent<PointComponent>(e))
251 .Select((e) => (e, GetComponent<PointComponent>(e)))) {
252
253 occupied.Add(point.Square);
254 }
255
256 foreach (ref readonly var message in ReadMessages<AdjustSelection>()) {
257 foreach (ref readonly var entity in ReadEntities<SelectedComponent>()) {
258 var selection = GetComponent<SelectedComponent>(entity);
259
260 if (selection.Type == SelectionType.Area
261 && selection.selected) {
262 if(message.Type == AdjustmentType.Clear) {
263 Destroy(entity);
264 }
265 else if (message.Type == AdjustmentType.Complete) {
266 var point = GetComponent<PointComponent>(entity);
267 var structure_entity = CreateEntity();
268 var cell = this.Map.cells[(int)point.Square.X][(int)point.Square.Y];
269 //Verify square is free:
270 //
271 if (!occupied.Contains(point.Square) && !cell.HasTree && !cell.HasWater) {
272
273 AddComponent(structure_entity, new PointComponent {Square = point.Square,
274 Tool = point.Tool} );
275 AddComponent(structure_entity,
276 new StructureComponent { Structure = Structure.Tower});
277 Destroy(entity);
278 SendMessage(new PlaySoundMessage { SoundName = "ConstructionShort" });
279 SendMessage(new SingleExpenseMessage { category = "Construction",
280 amount = 500M });
281 Logging.Success("Placed Tower!");
282 }
283
284 }
285 else {
286 var point = GetComponent<PointComponent>(entity);
287 SetComponent(entity, new PointComponent {Square = message.End,
288 Tool = point.Tool});
289 }
290 }
291 }
292 }
293 }
294
295 else if ((statuses.ContainsKey(Tool.Bulldozer) && statuses[Tool.Bulldozer])) {
296 SpawnSelection(Tool.Bulldozer);
297
298 foreach (ref readonly var message in ReadMessages<AdjustSelection>()) {
299 foreach (ref readonly var entity in ReadEntities<SelectedComponent>()) {
300 var selection = GetComponent<SelectedComponent>(entity);
301 if(selection.Type == SelectionType.Area
302 && selection.selected) {
303 if (message.Type == AdjustmentType.Clear) {
304 Destroy(entity);
305 }
306 else if (message.Type == AdjustmentType.Complete) {
307 var squares = GetComponent<AreaComponent>(entity).squares;
308 clear_structures(squares);
309 Destroy(entity); //Dezone destroys itself, so it doesn't need this command.
310 }
311 else {
312 var area = GetComponent<AreaComponent>(entity);
313
314 var newSquares = new List<Vector2>();
315
316 var end_x = MathUtils.Clamp(message.End.X, 0.0f, this.Map.MapWidth);
317 var end_y = MathUtils.Clamp(message.End.Y, 0.0f, this.Map.MapHeight);
318
319 foreach (var i in step_until(area.squares[0].X, end_x)) {
320 foreach (var j in step_until(area.squares[0].Y, end_y)) {
321 var newSquare = new Vector2(i, j);
322 newSquares.Add(newSquare);
323 }
324 }
325 SetComponent(entity, new AreaComponent { squares = newSquares.ToArray(), Tool = area.Tool});
326 }
327 }
328 }
329 }
330 }
331
332 DateTime min = DateTime.MinValue;
333 Entity newestEntity = default;
334
335 foreach (ref readonly var message in ReadMessages<UndoPreserveMessage>()) {
336 foreach (var entity in ReadEntities<PreserveComponent>()) {
337 var preserveComponent = GetComponent<PreserveComponent>(entity);
338 if (min < preserveComponent.date) {
339 min = preserveComponent.date;
340 newestEntity = entity;
341 }
342 Logging.Debug(String.Format("Checking preserve entity for {0}.", min));
343 }
344 }
345 if (min != DateTime.MinValue) {
346 Destroy(newestEntity);
347 }
348 }
349 }
350 }
@@ -0,0 +1,68
1 using System.Collections.Generic;
2 using Microsoft.Xna.Framework.Content;
3 using Microsoft.Xna.Framework.Audio;
4
5 using Encompass;
6
7 using isometricparkfna.Messages;
8 using isometricparkfna.Components;
9
10 namespace isometricparkfna.Engines
11 {
12
13 [Reads(typeof(OptionsComponent))]
14 [Receives(typeof(PlaySoundMessage))]
15 public class SoundEffectEngine : Engine
16 {
17 public static Dictionary<string, SoundEffect> sounds = new Dictionary<string, SoundEffect>();
18 public float volume = 1.0f;
19 public float pitch = 0.0f;
20 public float pan = 0.0f;
21 public bool muted = false;
22
23 public static SoundEffect LoadSound(ContentManager content, string path) {
24 return LoadSound(content, path, path);
25 }
26
27 public static SoundEffect LoadSound(ContentManager content,
28 string path, string name) {
29 var sfx = content.Load<SoundEffect>(path);
30 sounds.Add(name, sfx);
31 return sfx;
32
33 }
34
35 public static void DisposeSounds() {
36
37 foreach (KeyValuePair<string, SoundEffect> entry in sounds ) {
38 entry.Value.Dispose();
39 }
40
41 }
42
43 public override void Update(double dt) {
44
45 foreach(ref readonly var entity in
46 ReadEntities<OptionsComponent>()) {
47
48 var component = GetComponent<OptionsComponent>(entity);
49 volume = component.SoundEffectVolume;
50 muted = component.SoundEffectMuted;
51
52 }
53
54 foreach(ref readonly var message
55 in ReadMessages<PlaySoundMessage>()) {
56 var sound = sounds[message.SoundName];
57
58 var volume = message.Volume ?? this.volume;
59
60 if (!muted) {
61 sound.Play(volume, this.pitch, this.pan);
62 }
63 }
64
65 }
66
67 }
68 }
@@ -0,0 +1,17
1 using Microsoft.Xna.Framework;
2
3 using Encompass;
4
5 namespace isometricparkfna.Messages {
6
7 public enum AdjustmentType {
8 None,
9 Clear,
10 Complete
11 }
12
13 public struct AdjustSelection : IMessage {
14 public Vector2 End;
15 public AdjustmentType Type;
16 }
17 }
@@ -0,0 +1,10
1 using Microsoft.Xna.Framework;
2
3 using Encompass;
4
5 namespace isometricparkfna.Messages {
6
7 public struct DebugAlterTreesMessage : IMessage {
8 public int DeltaTrees;
9 }
10 }
@@ -0,0 +1,15
1 using Microsoft.Xna.Framework.Audio;
2
3 using Encompass;
4
5 #nullable enable
6
7 namespace isometricparkfna.Messages
8 {
9 public struct PlaySoundMessage : IMessage
10 {
11 public string SoundName;
12 public float? Volume;
13
14 }
15 }
@@ -0,0 +1,10
1 using Encompass;
2
3 namespace isometricparkfna.Messages
4 {
5 public struct SingleExpenseMessage : IMessage
6 {
7 public string category;
8 public decimal amount;
9 }
10 }
@@ -0,0 +1,9
1 using Microsoft.Xna.Framework;
2
3 using Encompass;
4
5 namespace isometricparkfna.Messages {
6 public struct SpawnSelection : IMessage {
7 public Vector2 Start;
8 }
9 }
@@ -0,0 +1,11
1 using isometricparkfna.Components;
2
3 using Encompass;
4
5 namespace isometricparkfna.Messages
6 {
7 public struct ToggleToolMessage : IMessage
8 {
9 public Tool Tool;
10 }
11 }
@@ -0,0 +1,7
1 using Encompass;
2
3 namespace isometricparkfna.Messages
4 {
5
6 public struct UndoPreserveMessage : IMessage { }
7 }
@@ -0,0 +1,63
1 using Microsoft.Xna.Framework;
2 using Microsoft.Xna.Framework.Graphics;
3
4 using isometricparkfna.UI;
5 using isometricparkfna.Components;
6
7 using Encompass;
8 using SpriteFontPlus;
9
10 namespace isometricparkfna.Renderers
11 {
12 public class CursorRenderer : GeneralRenderer
13 {
14 private SpriteBatch batch;
15 private SpriteFont font;
16
17 public CursorRenderer(SpriteBatch batch, SpriteFont font)
18 {
19 this.batch = batch;
20 this.font = font;
21 }
22
23 public override void Render()
24 {
25
26 Tool selectedTool = Tool.None;
27
28 foreach (ref readonly var entity in ReadEntities<ToolComponent>()) {
29 var toolComponent = GetComponent<ToolComponent>(entity);
30 var selectedComponent = GetComponent<SelectedComponent>(entity);
31 if (selectedComponent.selected) {
32 selectedTool = toolComponent.Tool;
33 }
34 }
35
36 foreach (ref readonly var entity in ReadEntities<CursorComponent>())
37 {
38
39 var cursorComponent = GetComponent<CursorComponent>(entity);
40 switch (selectedTool) {
41 case Tool.Dezone:
42 Tile.OutlineSquare(batch, cursorComponent.position.X, cursorComponent.position.Y, Color.Red);
43 break;
44 case Tool.Bulldozer:
45 Tile.OutlineSquare(batch, cursorComponent.position.X, cursorComponent.position.Y, Color.Red);
46 break;
47 case Tool.Preserve:
48 Tile.OutlineSquare(batch, cursorComponent.position.X, cursorComponent.position.Y, Color.Blue);
49 break;
50 default:
51 Tile.OutlineSquare(batch, cursorComponent.position.X, cursorComponent.position.Y, Color.Yellow);
52 break;
53
54 }
55 if(selectedTool == Tool.Tower) {
56 Tile.drawTileAt(batch, (int)cursorComponent.position.X, (int)cursorComponent.position.Y, 300, 2, 0.70f, new Color(1.0f, 1.0f, 1.0f, 0.5f));
57 }
58 }
59 }
60
61
62 }
63 }
@@ -0,0 +1,40
1 using Microsoft.Xna.Framework;
2 using Microsoft.Xna.Framework.Graphics;
3
4 using isometricparkfna.UI;
5 using isometricparkfna.Components;
6
7 using Encompass;
8 using SpriteFontPlus;
9
10 namespace isometricparkfna.Renderers
11 {
12 public class StructureRenderer : GeneralRenderer
13 {
14 private SpriteBatch batch;
15 private SpriteFont font;
16
17 public StructureRenderer(SpriteBatch batch, SpriteFont font)
18 {
19 this.batch = batch;
20 this.font = font;
21 }
22
23 public override void Render()
24 {
25
26
27 foreach (ref readonly var entity in ReadEntities<StructureComponent>())
28 {
29 var point = GetComponent<PointComponent>(entity);
30 Tile.drawTileAt(this.batch, (int)point.Square.X, (int)point.Square.Y,
31 300, 2, 0.79f, Color.White);
32 }
33
34
35
36 }
37 }
38
39
40 }
@@ -0,0 +1,18
1
2 namespace isometricparkfna.UI {
3
4 public enum ImGuiColor : uint {
5 BLACK = 0xFF000000,
6 RED = 0xFFFF0000,
7 GREEN = 0xFF00FF00,
8 BLUE = 0xFF0000FF,
9 DARKGREY = 0xFF999999,
10 LIGHTRED = 0xFFAA0000,
11 LIGHTGREEN = 0xFF00AA00,
12 LIGHTBLUE = 0xFF0000AA,
13 LIGHTGREY = 0xFFAAAAAA,
14 WHITE = 0xFF000000,
15
16 }
17
18 } No newline at end of file
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
@@ -14,22 +14,25
14 build-debug:
14 build-debug:
15 stage: build
15 stage: build
16 script:
16 script:
17 - dotnet restore isometric-park-fna-core.sln
17 - dotnet build isometric-park-fna-core.sln -f netcoreapp3.1
18 - dotnet build isometric-park-fna-core.sln -f netcoreapp3.1
18 image: mcr.microsoft.com/dotnet/sdk:3.1-focal
19 image: mcr.microsoft.com/dotnet/sdk:3.1.415-focal
19
20
20
21
21 build-release-windows:
22 build-release-windows:
22 stage: build
23 stage: build
23 script:
24 script:
25 - dotnet restore isometric-park-fna-core.sln
24 - dotnet build isometric-park-fna-core.sln -f netcoreapp3.1 -c Release
26 - dotnet build isometric-park-fna-core.sln -f netcoreapp3.1 -c Release
25 image: mcr.microsoft.com/dotnet/sdk:3.1
27 image: mcr.microsoft.com/dotnet/sdk:3.1.415
26
28
27 build-release:
29 build-release:
28 stage: build
30 stage: build
29 script:
31 script:
32 - dotnet restore isometric-park-fna-core.sln
30 - dotnet build isometric-park-fna-core.sln -f netcoreapp3.1 -c Release
33 - dotnet build isometric-park-fna-core.sln -f netcoreapp3.1 -c Release
31 artifacts:
34 artifacts:
32 paths:
35 paths:
33 - screenshot.xwd
36 - screenshot.xwd
34 expire_in: 1 week
37 expire_in: 1 week
35 image: mcr.microsoft.com/dotnet/sdk:3.1-focal
38 image: mcr.microsoft.com/dotnet/sdk:3.1.415-focal
@@ -29,6 +29,7
29 isometric-park-fna/Content/images/crops/*
29 isometric-park-fna/Content/images/crops/*
30 isometric-park-fna/Content/Portraits/converted/*
30 isometric-park-fna/Content/Portraits/converted/*
31 isometric-park-fna/Content/Portraits/crops/*
31 isometric-park-fna/Content/Portraits/crops/*
32 isometric-park-fna/Content/Pak64/split/*
32 isometric-park-fna/DynamicLanguageRuntime.1.3.0/*
33 isometric-park-fna/DynamicLanguageRuntime.1.3.0/*
33 isometric-park-fna/IronPython.2.7.11/
34 isometric-park-fna/IronPython.2.7.11/
34 **.patch
35 **.patch
@@ -1,6 +1,24
1 {
1 {
2 "version": "0.2.0",
2 "version": "0.2.0",
3 "configurations": [
3 "configurations": [
4
5
6 {
7 "name": "Launch with Core Debugger No Build",
8 "type": "coreclr",
9 "request": "launch",
10 // "preLaunchTask": "Build: Core Debug",
11 "program": "${workspaceFolder}/isometric-park-fna/bin/Debug/netcoreapp3.1/isometric-park-fna.dll",
12 "args": [],
13 "env": {
14 // "LD_LIBRARY_PATH": "${workspaceFolder}/isometric-park-fna/bin/Debug/netcoreapp3.1/lib64",
15 "LD_LIBRARY_PATH": "${workspaceFolder}/fnalibs/lib64",
16 "DYLD_LIBRARY_PATH": "${workspaceFolder}/fnalibs/osx"
17 },
18 "cwd": "${workspaceFolder}/isometric-park-fna/bin/Debug/netcoreapp3.1",
19 "console": "integratedTerminal",
20 "internalConsoleOptions": "neverOpen"
21 },
4 {
22 {
5 "name": "Launch with Core Debugger",
23 "name": "Launch with Core Debugger",
6 "type": "coreclr",
24 "type": "coreclr",
@@ -23,12 +41,19
23 "name": "Attach LLDB to Running Process",
41 "name": "Attach LLDB to Running Process",
24 "pid": "${command:pickMyProcess}" // use ${command:pickProcess} to pick other users' processes
42 "pid": "${command:pickMyProcess}" // use ${command:pickProcess} to pick other users' processes
25 },
43 },
44
45 {
46 "type": "lldb",
47 "request": "attach",
48 "name": "Attach LLDB to Running Process",
49 "pid": "${command:pickMyProcess}" // use ${command:pickProcess} to pick other users' processes
50 },
26
51
27 {
52 {
28 "name": "Attach .NET Core to Running Process",
53 "name": "Attach .NET Core to Running Process",
29 "type": "coreclr",
54 "type": "coreclr",
30 "request": "attach",
55 "request": "attach",
31 "processId":"${command:pickMyProcess}"
56 "pid":"${command:pickMyProcess}"
32 }
57 }
33 ]
58 ]
34 }
59 }
@@ -137,7 +137,7
137 "command": "dotnet",
137 "command": "dotnet",
138 "args": [
138 "args": [
139 "build",
139 "build",
140 "./isometric-park-fna-core.sln",
140 "./isometric-park-fna/isometric-park-fna-core.csproj",
141 "-f",
141 "-f",
142 "netcoreapp3.1"
142 "netcoreapp3.1"
143 ],
143 ],
@@ -175,7 +175,7
175 "command": "dotnet",
175 "command": "dotnet",
176 "args": [
176 "args": [
177 "build",
177 "build",
178 "./isometric-park-fna-core.sln",
178 "./isometric-park-fna/isometric-park-fna-core.csproj",
179 "--configuration",
179 "--configuration",
180 "Release",
180 "Release",
181 "-f",
181 "-f",
@@ -21,7 +21,6
21 <DocumentationFile></DocumentationFile>
21 <DocumentationFile></DocumentationFile>
22 </PropertyGroup>
22 </PropertyGroup>
23 <ItemGroup>
23 <ItemGroup>
24 <Reference Include="System" />
25 <PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
24 <PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
26 <PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="5.0.0" />
25 <PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="5.0.0" />
27 <PackageReference Include="System.Buffers" Version="4.5.1" />
26 <PackageReference Include="System.Buffers" Version="4.5.1" />
@@ -26,6 +26,33
26
26
27 #PIPELINE
27 #PIPELINE
28
28
29 ##Paks
30
31 ##I do some dubious things here to adopt Make to a workflow that generates multiple output files per input file, which
32 ##is not Make's strong suit.
33
34 isometric-park-fna/Content/Pak64/split/%.png: isometric-park-fna/Content/Pak64/%.png
35 convert $< -transparent '#e7ffff' -crop 64x64 isometric-park-fna/Content/Pak64/split/$*"%02d.png"
36 cp isometric-park-fna/Content/Pak64/split/$*00.png $@
37
38 isometric-park-fna/Content/pak64_tileset.png: $(shell find -ipath "*isometric-park-fna/Content/Pak64/*.png" -and -not -ipath "*split*" | sed "s:Pak64/:Pak64/split/:" |sort)
39 rm $^
40 montage isometric-park-fna/Content/Pak64/split/* -background transparent -tile 5 -geometry +0+0 -gravity north PNG8:$@
41 touch $^
42
43
44 pak: isometric-park-fna/Content/pak64_tileset.png
45
46
47 ## Merged
48
49 isometric-park-fna/Content/merged_tileset.png: isometric-park-fna/Content/pak64_tileset.png
50 montage isometric-park-fna/Content/part4_tileset.png $^ isometric-park-fna/Content/remos_trees2.png isometric-park-fna/Content/64x64_Objects_2.png isometric-park-fna/Content/rubberduck_parts_tower.png -background transparent -geometry +0+0 -tile 1x PNG:isometric-park-fna/Content/merged_tileset.png
51
52 merged: isometric-park-fna/Content/merged_tileset.png
53
54 ##Portraits
55
29 isometric-park-fna/Content/Portraits/converted/%.png: isometric-park-fna/Content/Portraits/%.jpg
56 isometric-park-fna/Content/Portraits/converted/%.png: isometric-park-fna/Content/Portraits/%.jpg
30 convert $< -resize 500x500\> -dither FloydSteinberg -colors 8 -colorspace gray $@
57 convert $< -resize 500x500\> -dither FloydSteinberg -colors 8 -colorspace gray $@
31
58
@@ -1,11 +1,12
1
2
1
3 # isometric-park-fna
2 # isometric-park-fna
4
3
5
4
6 As the director of a small state park, your job is to balance conservation, leisure, and fiscal sustainability. Gameplay is still being added.
5 As the director of a small state park, your job is to balance conservation, leisure, and fiscal sustainability. Gameplay is still being added.
7
6
8 This is inspired by Maxis' Sim series of games, particularly SimSafari, and Chris Sawyer's Tycoon games. Its premise more closely resembles SimPark, but I never played it except for a demo. (Alternatively, watch [1990's Sim Games. SO GOOD!](https://www.youtube.com/watch?v=APFnM6DqtiA))
7 This is inspired by Maxis' [Sim series of games](https://en.wikipedia.org/wiki/List_of_Sim_video_games), particularly SimSafari, and Chris Sawyer's [Tycoon games](http://www.chrissawyergames.com/info.htm). Its premise more closely resembles [SimPark](https://en.wikipedia.org/wiki/SimPark), but I never played it except for a demo. (Alternatively, watch [1990's Sim Games. SO GOOD!](https://www.youtube.com/watch?v=APFnM6DqtiA))
8
9 I rewrote the core of this game for Procjam 2020, but the majority of the game has been added since.
9
10
10 I rewrote the core of this game for Procjam 2020, but the majority of the game has been added since.
11 I rewrote the core of this game for Procjam 2020, but the majority of the game has been added since.
11
12
@@ -24,11 +25,21
24 options aren't sufficient.
25 options aren't sufficient.
25
26
26 Currently, there are no options for adjusting the difficulty beyond the settings
27 Currently, there are no options for adjusting the difficulty beyond the settings
27 that appear on the initial selection.
28 that appear on the initial selection when you begin a game.
29
30 ## System Requirements ##
31
32 The requirements are pretty modest. It runs pretty well on a 2010 MacBook Pro. Here's my estimated minimum:
33
34 * ~2 Ghz Core 2 Duo or equivalent
35 * 2 GB of memory
36 * Nvidia GeForce 200 series
37
38 If you have a more typical machine with, say, 8 GB of memory, an NVIDIA GeForce GTX, and an i5, you should have no trouble running the game.
28
39
29 ## Relationship to past work ##
40 ## Relationship to past work ##
30
41
31 This game is a total rewrite of the original version in C#. I honestly like the original language and library more (Clojure and Quil), but Quil was starting to struggle with the amount of drawing, and I was hitting the limit of my optimization abilities and available information online. (Another drawback: I'm also giving up the browser version, unless people get XNA in the browser working.)
42 This game is a total rewrite of the [original version](https://actuallyalys.itch.io/isometric-park-working-title) in C#. I honestly like the original language and library more (Clojure and Quil), but Quil was starting to struggle with the amount of drawing, and I was hitting the limit of my optimization abilities and available information online. (Another drawback: I'm also giving up the browser version, unless people get FNA in the browser working.)
32
43
33
44
34 ## Installing and Running ##
45 ## Installing and Running ##
@@ -37,7 +48,6
37 * Windows and Linux users should be able to double-click the EXE and run it.
48 * Windows and Linux users should be able to double-click the EXE and run it.
38 * BSD users can try using [fbsd-fnaify](https://github.com/oshogbo/fbsd-fnaify), although I have yet to confirm it works with Isometric Park. (If you do try it, let me know!)
49 * BSD users can try using [fbsd-fnaify](https://github.com/oshogbo/fbsd-fnaify), although I have yet to confirm it works with Isometric Park. (If you do try it, let me know!)
39
50
40
41 ## Developing ##
51 ## Developing ##
42
52
43 To run from the command line, `make run`.
53 To run from the command line, `make run`.
@@ -54,7 +64,11
54 2. Removed the ImGui folder: `rm -r ImGui.NET/`
64 2. Removed the ImGui folder: `rm -r ImGui.NET/`
55 3. Copied `cp -r /tmp/ImGui.NET/src/ImGui.NET .`
65 3. Copied `cp -r /tmp/ImGui.NET/src/ImGui.NET .`
56
66
67 ### Architecture ###
57
68
69 This game uses an ECS structure, with significant parts of the simulation done in the `Simulation` class and some drawing in the `FNAGame` class. I use Encompass, which calls systems engines. It also adds messages, which last only one frame and are ideal for updates.
70
71 I call engines that connect the ECS and non-ECS parts bridge engines. It works reasonably well, although I'm trying to add new code to the ECS rather than to the `Simulation` and `FNAGame` classes.
58
72
59 ### File Structure ###
73 ### File Structure ###
60
74
@@ -67,8 +81,8
67 β”‚Β Β  β”œβ”€β”€ **bin**
81 β”‚Β Β  β”œβ”€β”€ **bin**
68 β”‚Β Β  β”‚Β Β  β”œβ”€β”€ **Debug** Debug version
82 β”‚Β Β  β”‚Β Β  β”œβ”€β”€ **Debug** Debug version
69 β”‚Β Β  β”‚Β Β  └── **Release** Release version
83 β”‚Β Β  β”‚Β Β  └── **Release** Release version
70 β”‚Β Β  β”œβ”€β”€ *Camera.cs*
84 β”‚Β Β  β”œβ”€β”€ *Camera.cs*
71 β”‚Β Β  β”œβ”€β”€ *CellMap.cs*
85 β”‚Β Β  β”œβ”€β”€ *CellMap.cs*
72 β”‚Β Β  β”œβ”€β”€ **Components** Components that store data on entities.
86 β”‚Β Β  β”œβ”€β”€ **Components** Components that store data on entities.
73 β”‚Β Β  β”œβ”€β”€ **Content**
87 β”‚Β Β  β”œβ”€β”€ **Content**
74 β”‚Β Β  β”‚Β Β  β”œβ”€β”€ **DejaVuSerif-BoldItalic.ttf**
88 β”‚Β Β  β”‚Β Β  β”œβ”€β”€ **DejaVuSerif-BoldItalic.ttf**
@@ -91,11 +105,11
91 β”‚Β Β  β”‚Β Β  └── **typicons.ttf**
105 β”‚Β Β  β”‚Β Β  └── **typicons.ttf**
92 β”‚Β Β  β”œβ”€β”€ *DllMap.cs* (vendored)
106 β”‚Β Β  β”œβ”€β”€ *DllMap.cs* (vendored)
93 β”‚Β Β  β”œβ”€β”€ *DrawVertDeclaration.cs*
107 β”‚Β Β  β”œβ”€β”€ *DrawVertDeclaration.cs*
94 β”‚Β Β  β”œβ”€β”€ **Engines** Engines
108 β”‚Β Β  β”œβ”€β”€ **Engines** Engines
95 β”‚Β Β  β”œβ”€β”€ *FilledRectangle.cs* Class for drawing a filled rectangle.
109 β”‚Β Β  β”œβ”€β”€ *FilledRectangle.cs* Class for drawing a filled rectangle.
96 β”‚Β Β  β”œβ”€β”€ *FNAGame.cs* Primary game class.
110 β”‚Β Β  β”œβ”€β”€ *FNAGame.cs* Primary game class.
97 β”‚Β Β  β”œβ”€β”€ **fnalibs** Compiled native libraries.
111 β”‚Β Β  β”œβ”€β”€ **fnalibs** Compiled native libraries.
98 β”‚Β Β  β”‚Β Β  β”œβ”€β”€ **lib64**
112 β”‚Β Β  β”‚Β Β  β”œβ”€β”€ **lib64**
99 β”‚Β Β  β”‚Β Β  β”œβ”€β”€ **osx**
113 β”‚Β Β  β”‚Β Β  β”œβ”€β”€ **osx**
100 β”‚Β Β  β”‚Β Β  β”œβ”€β”€ **x64**
114 β”‚Β Β  β”‚Β Β  β”œβ”€β”€ **x64**
101 β”‚Β Β  β”‚Β Β  └── **x86**
115 β”‚Β Β  β”‚Β Β  └── **x86**
@@ -146,22 +160,22
146
160
147 ## Acknowledgements ##
161 ## Acknowledgements ##
148
162
149 Art: [Isometric 64x64 Outside Tileset by Yar](https://opengameart.org/content/isometric-64x64-outside-tileset), various images from the Library of Congress and USDA Forest Service
163 Art: [Isometric 64x64 Outside Tileset by Yar](https://opengameart.org/content/isometric-64x64-outside-tileset), [Peaceful](https://silivar.itch.io/isometric-asset-pack-peaceful) by Silivar various images from the Library of Congress and USDA Forest Service
150
164
151 Libraries: [FNA](https://fna-xna.github.io/), [SpriteFontPlus](https://github.com/rds1983/SpriteFontPlus), [Tracery.Net](https://github.com/josh-perry/Tracery.Net), [ImGui.NET](http://imgui.net/), and [Encompass-cs](http://moonside.games/docs/encompass/)
165 Libraries: [FNA](https://fna-xna.github.io/), [SpriteFontPlus](https://github.com/rds1983/SpriteFontPlus), [Tracery.Net](https://github.com/josh-perry/Tracery.Net), [ImGui.NET](http://imgui.net/), and [Encompass-cs](http://moonside.games/docs/encompass/)
152
166
153 Fonts: Droid Sans, [Iosevka](https://typeof.net/Iosevka/) by Belleve Invis, [Typicons](https://www.s-ings.com/typicons/) by Stephen Hutchings
167 Fonts: Droid Sans, [Iosevka](https://typeof.net/Iosevka/) by Belleve Invis, [Typicons](https://www.s-ings.com/typicons/) by Stephen Hutchings, [OCRA}(http://luc.devroye.org/fonts-48511.html) designed by American Type Founders and converted by Matthew Skala
168
169 Sounds: Bell, hammering, and jackhammer sounds by InspectorJ; Switch clicking by qubodup
154
170
155 Sources for the procedural generation are documented in Sources.md.
171 Sources for the procedural generation are documented in Sources.md.
156
172
157 Watching Thin Matrix's [video devlogs](https://www.youtube.com/watch?v=90CZ7Q17sls&list=PLRIWtICgwaX1gcSZ8qj8Q473tz7PsNmpR) for Equilinox inspired me to press on. :) Despite some similarities, the design of this game wasn't really inspired by Equilinox. (I've also enjoyed Thoughtquake's [video devlogs](https://www.youtube.com/user/Thoughtquake/videos) for Cargo Defense and Cliff Harris' Democracy 4 [video devlogs](https://www.youtube.com/user/cliffski2/videos))
173 Watching ThinMatrix's [video devlogs](https://www.youtube.com/watch?v=90CZ7Q17sls&list=PLRIWtICgwaX1gcSZ8qj8Q473tz7PsNmpR) for Equilinox and his subsequent games inspired me to press on. :) Despite some similarities, the design of this game wasn't really inspired by Equilinox. (I've also enjoyed Thoughtquake's [video devlogs](https://www.youtube.com/user/Thoughtquake/videos) and Cliff Harris' Democracy 4 [video devlogs](https://www.youtube.com/user/cliffski2/videos)).
158
174
159 The original versions used art from the [Low Poly Forest Pack](https://devilsworkshop.itch.io/lowpoly-forest-pack) by [Devil's Work.Shop](https://devilsworkshop.itch.io/). (I had converted the models into isometric 2D images, using [this process.](https://www.youtube.com/watch?v=bk0PXMgZgQg))
175 The original versions used art from the [Low Poly Forest Pack](https://devilsworkshop.itch.io/lowpoly-forest-pack) by [Devil's Work.Shop](https://devilsworkshop.itch.io/). (I had converted the models into isometric 2D images, using [this process.](https://www.youtube.com/watch?v=bk0PXMgZgQg))
160
176
161 ## License ##
177 ## License ##
162
178
163 Β© 2021 Alys S. Brooks
179 Β© 2022 Alys S. Brooks
164
180
165 I haven't decided on a license.
181 I haven't decided on a license.
166
167
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
@@ -1,4 +1,4
1 // <autogenerated />
1 // <autogenerated />
2 using System;
2 using System;
3 using System.Reflection;
3 using System.Reflection;
4 // [assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
4 // [assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
This diff has been collapsed as it changes many lines, (595 lines changed) Show them Hide them
@@ -2,57 +2,8
2 "version": 3,
2 "version": 3,
3 "targets": {
3 "targets": {
4 ".NETFramework,Version=v4.5": {
4 ".NETFramework,Version=v4.5": {
5 "Microsoft.NETFramework.ReferenceAssemblies/1.0.0": {
6 "type": "package",
7 "dependencies": {
8 "Microsoft.NETFramework.ReferenceAssemblies.net45": "1.0.0"
9 }
10 },
11 "Microsoft.NETFramework.ReferenceAssemblies.net45/1.0.0": {
12 "type": "package",
13 "build": {
14 "build/Microsoft.NETFramework.ReferenceAssemblies.net45.targets": {}
15 }
16 },
17 "FNA/1.0.0": {
5 "FNA/1.0.0": {
18 "type": "project",
6 "type": "project",
19 "framework": ".NETFramework,Version=v4.0",
20 "compile": {
21 "bin/placeholder/FNA.dll": {}
22 },
23 "runtime": {
24 "bin/placeholder/FNA.dll": {}
25 }
26 }
27 },
28 ".NETStandard,Version=v2.0": {
29 "Microsoft.NETCore.Platforms/1.1.0": {
30 "type": "package",
31 "compile": {
32 "lib/netstandard1.0/_._": {}
33 },
34 "runtime": {
35 "lib/netstandard1.0/_._": {}
36 }
37 },
38 "NETStandard.Library/2.0.3": {
39 "type": "package",
40 "dependencies": {
41 "Microsoft.NETCore.Platforms": "1.1.0"
42 },
43 "compile": {
44 "lib/netstandard1.0/_._": {}
45 },
46 "runtime": {
47 "lib/netstandard1.0/_._": {}
48 },
49 "build": {
50 "build/netstandard2.0/NETStandard.Library.targets": {}
51 }
52 },
53 "FNA/1.0.0": {
54 "type": "project",
55 "framework": ".NETStandard,Version=v2.0",
56 "compile": {
7 "compile": {
57 "bin/placeholder/FNA.dll": {}
8 "bin/placeholder/FNA.dll": {}
58 },
9 },
@@ -63,536 +14,43
63 }
14 }
64 },
15 },
65 "libraries": {
16 "libraries": {
66 "Microsoft.NETCore.Platforms/1.1.0": {
67 "sha512": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==",
68 "type": "package",
69 "path": "microsoft.netcore.platforms/1.1.0",
70 "files": [
71 ".nupkg.metadata",
72 ".signature.p7s",
73 "ThirdPartyNotices.txt",
74 "dotnet_library_license.txt",
75 "lib/netstandard1.0/_._",
76 "microsoft.netcore.platforms.1.1.0.nupkg.sha512",
77 "microsoft.netcore.platforms.nuspec",
78 "runtime.json"
79 ]
80 },
81 "Microsoft.NETFramework.ReferenceAssemblies/1.0.0": {
82 "sha512": "7D2TMufjGiowmt0E941kVoTIS+GTNzaPopuzM1/1LSaJAdJdBrVP0SkZW7AgDd0a2U1DjsIeaKG1wxGVBNLDMw==",
83 "type": "package",
84 "path": "microsoft.netframework.referenceassemblies/1.0.0",
85 "files": [
86 ".nupkg.metadata",
87 ".signature.p7s",
88 "microsoft.netframework.referenceassemblies.1.0.0.nupkg.sha512",
89 "microsoft.netframework.referenceassemblies.nuspec"
90 ]
91 },
92 "Microsoft.NETFramework.ReferenceAssemblies.net45/1.0.0": {
93 "sha512": "f7XMQsZFaoc3w8Vg3VQ3FHuU2C9vf0Ng5EAV4gzdNWDerPM/OmrzccLj15eI1wCLLXj4jk8+lKsbonzJeyXgQQ==",
94 "type": "package",
95 "path": "microsoft.netframework.referenceassemblies.net45/1.0.0",
96 "files": [
97 ".nupkg.metadata",
98 ".signature.p7s",
99 "build/.NETFramework/v4.5/Accessibility.dll",
100 "build/.NETFramework/v4.5/Accessibility.xml",
101 "build/.NETFramework/v4.5/CustomMarshalers.dll",
102 "build/.NETFramework/v4.5/CustomMarshalers.xml",
103 "build/.NETFramework/v4.5/Facades/System.Collections.Concurrent.dll",
104 "build/.NETFramework/v4.5/Facades/System.Collections.dll",
105 "build/.NETFramework/v4.5/Facades/System.ComponentModel.Annotations.dll",
106 "build/.NETFramework/v4.5/Facades/System.ComponentModel.EventBasedAsync.dll",
107 "build/.NETFramework/v4.5/Facades/System.ComponentModel.dll",
108 "build/.NETFramework/v4.5/Facades/System.Diagnostics.Contracts.dll",
109 "build/.NETFramework/v4.5/Facades/System.Diagnostics.Debug.dll",
110 "build/.NETFramework/v4.5/Facades/System.Diagnostics.Tools.dll",
111 "build/.NETFramework/v4.5/Facades/System.Diagnostics.Tracing.dll",
112 "build/.NETFramework/v4.5/Facades/System.Dynamic.Runtime.dll",
113 "build/.NETFramework/v4.5/Facades/System.Globalization.dll",
114 "build/.NETFramework/v4.5/Facades/System.IO.dll",
115 "build/.NETFramework/v4.5/Facades/System.Linq.Expressions.dll",
116 "build/.NETFramework/v4.5/Facades/System.Linq.Parallel.dll",
117 "build/.NETFramework/v4.5/Facades/System.Linq.Queryable.dll",
118 "build/.NETFramework/v4.5/Facades/System.Linq.dll",
119 "build/.NETFramework/v4.5/Facades/System.Net.NetworkInformation.dll",
120 "build/.NETFramework/v4.5/Facades/System.Net.Primitives.dll",
121 "build/.NETFramework/v4.5/Facades/System.Net.Requests.dll",
122 "build/.NETFramework/v4.5/Facades/System.ObjectModel.dll",
123 "build/.NETFramework/v4.5/Facades/System.Reflection.Emit.ILGeneration.dll",
124 "build/.NETFramework/v4.5/Facades/System.Reflection.Emit.Lightweight.dll",
125 "build/.NETFramework/v4.5/Facades/System.Reflection.Emit.dll",
126 "build/.NETFramework/v4.5/Facades/System.Reflection.Extensions.dll",
127 "build/.NETFramework/v4.5/Facades/System.Reflection.Primitives.dll",
128 "build/.NETFramework/v4.5/Facades/System.Reflection.dll",
129 "build/.NETFramework/v4.5/Facades/System.Resources.ResourceManager.dll",
130 "build/.NETFramework/v4.5/Facades/System.Runtime.Extensions.dll",
131 "build/.NETFramework/v4.5/Facades/System.Runtime.InteropServices.WindowsRuntime.dll",
132 "build/.NETFramework/v4.5/Facades/System.Runtime.InteropServices.dll",
133 "build/.NETFramework/v4.5/Facades/System.Runtime.Numerics.dll",
134 "build/.NETFramework/v4.5/Facades/System.Runtime.Serialization.Json.dll",
135 "build/.NETFramework/v4.5/Facades/System.Runtime.Serialization.Primitives.dll",
136 "build/.NETFramework/v4.5/Facades/System.Runtime.Serialization.Xml.dll",
137 "build/.NETFramework/v4.5/Facades/System.Runtime.dll",
138 "build/.NETFramework/v4.5/Facades/System.Security.Principal.dll",
139 "build/.NETFramework/v4.5/Facades/System.ServiceModel.Duplex.dll",
140 "build/.NETFramework/v4.5/Facades/System.ServiceModel.Http.dll",
141 "build/.NETFramework/v4.5/Facades/System.ServiceModel.NetTcp.dll",
142 "build/.NETFramework/v4.5/Facades/System.ServiceModel.Primitives.dll",
143 "build/.NETFramework/v4.5/Facades/System.ServiceModel.Security.dll",
144 "build/.NETFramework/v4.5/Facades/System.Text.Encoding.Extensions.dll",
145 "build/.NETFramework/v4.5/Facades/System.Text.Encoding.dll",
146 "build/.NETFramework/v4.5/Facades/System.Text.RegularExpressions.dll",
147 "build/.NETFramework/v4.5/Facades/System.Threading.Tasks.Parallel.dll",
148 "build/.NETFramework/v4.5/Facades/System.Threading.Tasks.dll",
149 "build/.NETFramework/v4.5/Facades/System.Threading.dll",
150 "build/.NETFramework/v4.5/Facades/System.Xml.ReaderWriter.dll",
151 "build/.NETFramework/v4.5/Facades/System.Xml.XDocument.dll",
152 "build/.NETFramework/v4.5/Facades/System.Xml.XmlSerializer.dll",
153 "build/.NETFramework/v4.5/ISymWrapper.dll",
154 "build/.NETFramework/v4.5/ISymWrapper.xml",
155 "build/.NETFramework/v4.5/Microsoft.Activities.Build.dll",
156 "build/.NETFramework/v4.5/Microsoft.Activities.Build.xml",
157 "build/.NETFramework/v4.5/Microsoft.Build.Conversion.v4.0.dll",
158 "build/.NETFramework/v4.5/Microsoft.Build.Conversion.v4.0.xml",
159 "build/.NETFramework/v4.5/Microsoft.Build.Engine.dll",
160 "build/.NETFramework/v4.5/Microsoft.Build.Engine.xml",
161 "build/.NETFramework/v4.5/Microsoft.Build.Framework.dll",
162 "build/.NETFramework/v4.5/Microsoft.Build.Framework.xml",
163 "build/.NETFramework/v4.5/Microsoft.Build.Tasks.v4.0.dll",
164 "build/.NETFramework/v4.5/Microsoft.Build.Tasks.v4.0.xml",
165 "build/.NETFramework/v4.5/Microsoft.Build.Utilities.v4.0.dll",
166 "build/.NETFramework/v4.5/Microsoft.Build.Utilities.v4.0.xml",
167 "build/.NETFramework/v4.5/Microsoft.Build.dll",
168 "build/.NETFramework/v4.5/Microsoft.Build.xml",
169 "build/.NETFramework/v4.5/Microsoft.CSharp.dll",
170 "build/.NETFramework/v4.5/Microsoft.CSharp.xml",
171 "build/.NETFramework/v4.5/Microsoft.JScript.dll",
172 "build/.NETFramework/v4.5/Microsoft.JScript.xml",
173 "build/.NETFramework/v4.5/Microsoft.VisualBasic.Compatibility.Data.dll",
174 "build/.NETFramework/v4.5/Microsoft.VisualBasic.Compatibility.Data.xml",
175 "build/.NETFramework/v4.5/Microsoft.VisualBasic.Compatibility.dll",
176 "build/.NETFramework/v4.5/Microsoft.VisualBasic.Compatibility.xml",
177 "build/.NETFramework/v4.5/Microsoft.VisualBasic.dll",
178 "build/.NETFramework/v4.5/Microsoft.VisualBasic.xml",
179 "build/.NETFramework/v4.5/Microsoft.VisualC.STLCLR.dll",
180 "build/.NETFramework/v4.5/Microsoft.VisualC.STLCLR.xml",
181 "build/.NETFramework/v4.5/Microsoft.VisualC.dll",
182 "build/.NETFramework/v4.5/Microsoft.VisualC.xml",
183 "build/.NETFramework/v4.5/PermissionSets/FullTrust.xml",
184 "build/.NETFramework/v4.5/PermissionSets/Internet.xml",
185 "build/.NETFramework/v4.5/PermissionSets/LocalIntranet.xml",
186 "build/.NETFramework/v4.5/PresentationBuildTasks.dll",
187 "build/.NETFramework/v4.5/PresentationBuildTasks.xml",
188 "build/.NETFramework/v4.5/PresentationCore.dll",
189 "build/.NETFramework/v4.5/PresentationCore.xml",
190 "build/.NETFramework/v4.5/PresentationFramework.Aero.dll",
191 "build/.NETFramework/v4.5/PresentationFramework.Aero.xml",
192 "build/.NETFramework/v4.5/PresentationFramework.Aero2.dll",
193 "build/.NETFramework/v4.5/PresentationFramework.AeroLite.dll",
194 "build/.NETFramework/v4.5/PresentationFramework.Classic.dll",
195 "build/.NETFramework/v4.5/PresentationFramework.Classic.xml",
196 "build/.NETFramework/v4.5/PresentationFramework.Luna.dll",
197 "build/.NETFramework/v4.5/PresentationFramework.Luna.xml",
198 "build/.NETFramework/v4.5/PresentationFramework.Royale.dll",
199 "build/.NETFramework/v4.5/PresentationFramework.Royale.xml",
200 "build/.NETFramework/v4.5/PresentationFramework.dll",
201 "build/.NETFramework/v4.5/PresentationFramework.xml",
202 "build/.NETFramework/v4.5/ReachFramework.dll",
203 "build/.NETFramework/v4.5/ReachFramework.xml",
204 "build/.NETFramework/v4.5/RedistList/FrameworkList.xml",
205 "build/.NETFramework/v4.5/System.Activities.Core.Presentation.dll",
206 "build/.NETFramework/v4.5/System.Activities.Core.Presentation.xml",
207 "build/.NETFramework/v4.5/System.Activities.DurableInstancing.dll",
208 "build/.NETFramework/v4.5/System.Activities.DurableInstancing.xml",
209 "build/.NETFramework/v4.5/System.Activities.Presentation.dll",
210 "build/.NETFramework/v4.5/System.Activities.Presentation.xml",
211 "build/.NETFramework/v4.5/System.Activities.dll",
212 "build/.NETFramework/v4.5/System.Activities.xml",
213 "build/.NETFramework/v4.5/System.AddIn.Contract.dll",
214 "build/.NETFramework/v4.5/System.AddIn.Contract.xml",
215 "build/.NETFramework/v4.5/System.AddIn.dll",
216 "build/.NETFramework/v4.5/System.AddIn.xml",
217 "build/.NETFramework/v4.5/System.ComponentModel.Composition.Registration.dll",
218 "build/.NETFramework/v4.5/System.ComponentModel.Composition.dll",
219 "build/.NETFramework/v4.5/System.ComponentModel.Composition.xml",
220 "build/.NETFramework/v4.5/System.ComponentModel.DataAnnotations.dll",
221 "build/.NETFramework/v4.5/System.ComponentModel.DataAnnotations.xml",
222 "build/.NETFramework/v4.5/System.Configuration.Install.dll",
223 "build/.NETFramework/v4.5/System.Configuration.Install.xml",
224 "build/.NETFramework/v4.5/System.Configuration.dll",
225 "build/.NETFramework/v4.5/System.Configuration.xml",
226 "build/.NETFramework/v4.5/System.Core.dll",
227 "build/.NETFramework/v4.5/System.Core.xml",
228 "build/.NETFramework/v4.5/System.Data.DataSetExtensions.dll",
229 "build/.NETFramework/v4.5/System.Data.DataSetExtensions.xml",
230 "build/.NETFramework/v4.5/System.Data.Entity.Design.dll",
231 "build/.NETFramework/v4.5/System.Data.Entity.Design.xml",
232 "build/.NETFramework/v4.5/System.Data.Entity.dll",
233 "build/.NETFramework/v4.5/System.Data.Entity.xml",
234 "build/.NETFramework/v4.5/System.Data.Linq.dll",
235 "build/.NETFramework/v4.5/System.Data.Linq.xml",
236 "build/.NETFramework/v4.5/System.Data.OracleClient.dll",
237 "build/.NETFramework/v4.5/System.Data.OracleClient.xml",
238 "build/.NETFramework/v4.5/System.Data.Services.Client.dll",
239 "build/.NETFramework/v4.5/System.Data.Services.Client.xml",
240 "build/.NETFramework/v4.5/System.Data.Services.Design.dll",
241 "build/.NETFramework/v4.5/System.Data.Services.Design.xml",
242 "build/.NETFramework/v4.5/System.Data.Services.dll",
243 "build/.NETFramework/v4.5/System.Data.Services.xml",
244 "build/.NETFramework/v4.5/System.Data.SqlXml.dll",
245 "build/.NETFramework/v4.5/System.Data.SqlXml.xml",
246 "build/.NETFramework/v4.5/System.Data.dll",
247 "build/.NETFramework/v4.5/System.Data.xml",
248 "build/.NETFramework/v4.5/System.Deployment.dll",
249 "build/.NETFramework/v4.5/System.Deployment.xml",
250 "build/.NETFramework/v4.5/System.Design.dll",
251 "build/.NETFramework/v4.5/System.Design.xml",
252 "build/.NETFramework/v4.5/System.Device.dll",
253 "build/.NETFramework/v4.5/System.Device.xml",
254 "build/.NETFramework/v4.5/System.DirectoryServices.AccountManagement.dll",
255 "build/.NETFramework/v4.5/System.DirectoryServices.AccountManagement.xml",
256 "build/.NETFramework/v4.5/System.DirectoryServices.Protocols.dll",
257 "build/.NETFramework/v4.5/System.DirectoryServices.Protocols.xml",
258 "build/.NETFramework/v4.5/System.DirectoryServices.dll",
259 "build/.NETFramework/v4.5/System.DirectoryServices.xml",
260 "build/.NETFramework/v4.5/System.Drawing.Design.dll",
261 "build/.NETFramework/v4.5/System.Drawing.Design.xml",
262 "build/.NETFramework/v4.5/System.Drawing.dll",
263 "build/.NETFramework/v4.5/System.Drawing.xml",
264 "build/.NETFramework/v4.5/System.EnterpriseServices.Thunk.dll",
265 "build/.NETFramework/v4.5/System.EnterpriseServices.Wrapper.dll",
266 "build/.NETFramework/v4.5/System.EnterpriseServices.dll",
267 "build/.NETFramework/v4.5/System.EnterpriseServices.xml",
268 "build/.NETFramework/v4.5/System.IO.Compression.FileSystem.dll",
269 "build/.NETFramework/v4.5/System.IO.Compression.FileSystem.xml",
270 "build/.NETFramework/v4.5/System.IO.Compression.dll",
271 "build/.NETFramework/v4.5/System.IO.Compression.xml",
272 "build/.NETFramework/v4.5/System.IO.Log.dll",
273 "build/.NETFramework/v4.5/System.IO.Log.xml",
274 "build/.NETFramework/v4.5/System.IdentityModel.Selectors.dll",
275 "build/.NETFramework/v4.5/System.IdentityModel.Selectors.xml",
276 "build/.NETFramework/v4.5/System.IdentityModel.Services.dll",
277 "build/.NETFramework/v4.5/System.IdentityModel.Services.xml",
278 "build/.NETFramework/v4.5/System.IdentityModel.dll",
279 "build/.NETFramework/v4.5/System.IdentityModel.xml",
280 "build/.NETFramework/v4.5/System.Management.Instrumentation.dll",
281 "build/.NETFramework/v4.5/System.Management.Instrumentation.xml",
282 "build/.NETFramework/v4.5/System.Management.dll",
283 "build/.NETFramework/v4.5/System.Management.xml",
284 "build/.NETFramework/v4.5/System.Messaging.dll",
285 "build/.NETFramework/v4.5/System.Messaging.xml",
286 "build/.NETFramework/v4.5/System.Net.Http.WebRequest.dll",
287 "build/.NETFramework/v4.5/System.Net.Http.WebRequest.xml",
288 "build/.NETFramework/v4.5/System.Net.Http.dll",
289 "build/.NETFramework/v4.5/System.Net.Http.xml",
290 "build/.NETFramework/v4.5/System.Net.dll",
291 "build/.NETFramework/v4.5/System.Net.xml",
292 "build/.NETFramework/v4.5/System.Numerics.dll",
293 "build/.NETFramework/v4.5/System.Numerics.xml",
294 "build/.NETFramework/v4.5/System.Printing.dll",
295 "build/.NETFramework/v4.5/System.Printing.xml",
296 "build/.NETFramework/v4.5/System.Reflection.Context.dll",
297 "build/.NETFramework/v4.5/System.Reflection.Context.xml",
298 "build/.NETFramework/v4.5/System.Runtime.Caching.dll",
299 "build/.NETFramework/v4.5/System.Runtime.Caching.xml",
300 "build/.NETFramework/v4.5/System.Runtime.DurableInstancing.dll",
301 "build/.NETFramework/v4.5/System.Runtime.DurableInstancing.xml",
302 "build/.NETFramework/v4.5/System.Runtime.Remoting.dll",
303 "build/.NETFramework/v4.5/System.Runtime.Remoting.xml",
304 "build/.NETFramework/v4.5/System.Runtime.Serialization.Formatters.Soap.dll",
305 "build/.NETFramework/v4.5/System.Runtime.Serialization.Formatters.Soap.xml",
306 "build/.NETFramework/v4.5/System.Runtime.Serialization.dll",
307 "build/.NETFramework/v4.5/System.Runtime.Serialization.xml",
308 "build/.NETFramework/v4.5/System.Security.dll",
309 "build/.NETFramework/v4.5/System.Security.xml",
310 "build/.NETFramework/v4.5/System.ServiceModel.Activation.dll",
311 "build/.NETFramework/v4.5/System.ServiceModel.Activation.xml",
312 "build/.NETFramework/v4.5/System.ServiceModel.Activities.dll",
313 "build/.NETFramework/v4.5/System.ServiceModel.Activities.xml",
314 "build/.NETFramework/v4.5/System.ServiceModel.Channels.dll",
315 "build/.NETFramework/v4.5/System.ServiceModel.Channels.xml",
316 "build/.NETFramework/v4.5/System.ServiceModel.Discovery.dll",
317 "build/.NETFramework/v4.5/System.ServiceModel.Discovery.xml",
318 "build/.NETFramework/v4.5/System.ServiceModel.Routing.dll",
319 "build/.NETFramework/v4.5/System.ServiceModel.Routing.xml",
320 "build/.NETFramework/v4.5/System.ServiceModel.Web.dll",
321 "build/.NETFramework/v4.5/System.ServiceModel.Web.xml",
322 "build/.NETFramework/v4.5/System.ServiceModel.dll",
323 "build/.NETFramework/v4.5/System.ServiceModel.xml",
324 "build/.NETFramework/v4.5/System.ServiceProcess.dll",
325 "build/.NETFramework/v4.5/System.ServiceProcess.xml",
326 "build/.NETFramework/v4.5/System.Speech.dll",
327 "build/.NETFramework/v4.5/System.Speech.xml",
328 "build/.NETFramework/v4.5/System.Threading.Tasks.Dataflow.xml",
329 "build/.NETFramework/v4.5/System.Transactions.dll",
330 "build/.NETFramework/v4.5/System.Transactions.xml",
331 "build/.NETFramework/v4.5/System.Web.Abstractions.dll",
332 "build/.NETFramework/v4.5/System.Web.ApplicationServices.dll",
333 "build/.NETFramework/v4.5/System.Web.ApplicationServices.xml",
334 "build/.NETFramework/v4.5/System.Web.DataVisualization.Design.dll",
335 "build/.NETFramework/v4.5/System.Web.DataVisualization.dll",
336 "build/.NETFramework/v4.5/System.Web.DataVisualization.xml",
337 "build/.NETFramework/v4.5/System.Web.DynamicData.Design.dll",
338 "build/.NETFramework/v4.5/System.Web.DynamicData.Design.xml",
339 "build/.NETFramework/v4.5/System.Web.DynamicData.dll",
340 "build/.NETFramework/v4.5/System.Web.DynamicData.xml",
341 "build/.NETFramework/v4.5/System.Web.Entity.Design.dll",
342 "build/.NETFramework/v4.5/System.Web.Entity.Design.xml",
343 "build/.NETFramework/v4.5/System.Web.Entity.dll",
344 "build/.NETFramework/v4.5/System.Web.Entity.xml",
345 "build/.NETFramework/v4.5/System.Web.Extensions.Design.dll",
346 "build/.NETFramework/v4.5/System.Web.Extensions.Design.xml",
347 "build/.NETFramework/v4.5/System.Web.Extensions.dll",
348 "build/.NETFramework/v4.5/System.Web.Extensions.xml",
349 "build/.NETFramework/v4.5/System.Web.Mobile.dll",
350 "build/.NETFramework/v4.5/System.Web.Mobile.xml",
351 "build/.NETFramework/v4.5/System.Web.RegularExpressions.dll",
352 "build/.NETFramework/v4.5/System.Web.RegularExpressions.xml",
353 "build/.NETFramework/v4.5/System.Web.Routing.dll",
354 "build/.NETFramework/v4.5/System.Web.Services.dll",
355 "build/.NETFramework/v4.5/System.Web.Services.xml",
356 "build/.NETFramework/v4.5/System.Web.dll",
357 "build/.NETFramework/v4.5/System.Web.xml",
358 "build/.NETFramework/v4.5/System.Windows.Controls.Ribbon.dll",
359 "build/.NETFramework/v4.5/System.Windows.Controls.Ribbon.xml",
360 "build/.NETFramework/v4.5/System.Windows.Forms.DataVisualization.Design.dll",
361 "build/.NETFramework/v4.5/System.Windows.Forms.DataVisualization.dll",
362 "build/.NETFramework/v4.5/System.Windows.Forms.DataVisualization.xml",
363 "build/.NETFramework/v4.5/System.Windows.Forms.dll",
364 "build/.NETFramework/v4.5/System.Windows.Forms.xml",
365 "build/.NETFramework/v4.5/System.Windows.Input.Manipulations.dll",
366 "build/.NETFramework/v4.5/System.Windows.Input.Manipulations.xml",
367 "build/.NETFramework/v4.5/System.Windows.Presentation.dll",
368 "build/.NETFramework/v4.5/System.Windows.Presentation.xml",
369 "build/.NETFramework/v4.5/System.Windows.dll",
370 "build/.NETFramework/v4.5/System.Workflow.Activities.dll",
371 "build/.NETFramework/v4.5/System.Workflow.Activities.xml",
372 "build/.NETFramework/v4.5/System.Workflow.ComponentModel.dll",
373 "build/.NETFramework/v4.5/System.Workflow.ComponentModel.xml",
374 "build/.NETFramework/v4.5/System.Workflow.Runtime.dll",
375 "build/.NETFramework/v4.5/System.Workflow.Runtime.xml",
376 "build/.NETFramework/v4.5/System.WorkflowServices.dll",
377 "build/.NETFramework/v4.5/System.WorkflowServices.xml",
378 "build/.NETFramework/v4.5/System.Xaml.dll",
379 "build/.NETFramework/v4.5/System.Xaml.xml",
380 "build/.NETFramework/v4.5/System.Xml.Linq.dll",
381 "build/.NETFramework/v4.5/System.Xml.Linq.xml",
382 "build/.NETFramework/v4.5/System.Xml.Serialization.dll",
383 "build/.NETFramework/v4.5/System.Xml.dll",
384 "build/.NETFramework/v4.5/System.Xml.xml",
385 "build/.NETFramework/v4.5/System.dll",
386 "build/.NETFramework/v4.5/System.xml",
387 "build/.NETFramework/v4.5/UIAutomationClient.dll",
388 "build/.NETFramework/v4.5/UIAutomationClient.xml",
389 "build/.NETFramework/v4.5/UIAutomationClientsideProviders.dll",
390 "build/.NETFramework/v4.5/UIAutomationClientsideProviders.xml",
391 "build/.NETFramework/v4.5/UIAutomationProvider.dll",
392 "build/.NETFramework/v4.5/UIAutomationProvider.xml",
393 "build/.NETFramework/v4.5/UIAutomationTypes.dll",
394 "build/.NETFramework/v4.5/UIAutomationTypes.xml",
395 "build/.NETFramework/v4.5/WindowsBase.dll",
396 "build/.NETFramework/v4.5/WindowsBase.xml",
397 "build/.NETFramework/v4.5/WindowsFormsIntegration.dll",
398 "build/.NETFramework/v4.5/WindowsFormsIntegration.xml",
399 "build/.NETFramework/v4.5/XamlBuildTask.dll",
400 "build/.NETFramework/v4.5/XamlBuildTask.xml",
401 "build/.NETFramework/v4.5/mscorlib.dll",
402 "build/.NETFramework/v4.5/mscorlib.xml",
403 "build/.NETFramework/v4.5/sysglobl.dll",
404 "build/.NETFramework/v4.5/sysglobl.xml",
405 "build/Microsoft.NETFramework.ReferenceAssemblies.net45.targets",
406 "microsoft.netframework.referenceassemblies.net45.1.0.0.nupkg.sha512",
407 "microsoft.netframework.referenceassemblies.net45.nuspec"
408 ]
409 },
410 "NETStandard.Library/2.0.3": {
411 "sha512": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
412 "type": "package",
413 "path": "netstandard.library/2.0.3",
414 "files": [
415 ".nupkg.metadata",
416 ".signature.p7s",
417 "LICENSE.TXT",
418 "THIRD-PARTY-NOTICES.TXT",
419 "build/netstandard2.0/NETStandard.Library.targets",
420 "build/netstandard2.0/ref/Microsoft.Win32.Primitives.dll",
421 "build/netstandard2.0/ref/System.AppContext.dll",
422 "build/netstandard2.0/ref/System.Collections.Concurrent.dll",
423 "build/netstandard2.0/ref/System.Collections.NonGeneric.dll",
424 "build/netstandard2.0/ref/System.Collections.Specialized.dll",
425 "build/netstandard2.0/ref/System.Collections.dll",
426 "build/netstandard2.0/ref/System.ComponentModel.Composition.dll",
427 "build/netstandard2.0/ref/System.ComponentModel.EventBasedAsync.dll",
428 "build/netstandard2.0/ref/System.ComponentModel.Primitives.dll",
429 "build/netstandard2.0/ref/System.ComponentModel.TypeConverter.dll",
430 "build/netstandard2.0/ref/System.ComponentModel.dll",
431 "build/netstandard2.0/ref/System.Console.dll",
432 "build/netstandard2.0/ref/System.Core.dll",
433 "build/netstandard2.0/ref/System.Data.Common.dll",
434 "build/netstandard2.0/ref/System.Data.dll",
435 "build/netstandard2.0/ref/System.Diagnostics.Contracts.dll",
436 "build/netstandard2.0/ref/System.Diagnostics.Debug.dll",
437 "build/netstandard2.0/ref/System.Diagnostics.FileVersionInfo.dll",
438 "build/netstandard2.0/ref/System.Diagnostics.Process.dll",
439 "build/netstandard2.0/ref/System.Diagnostics.StackTrace.dll",
440 "build/netstandard2.0/ref/System.Diagnostics.TextWriterTraceListener.dll",
441 "build/netstandard2.0/ref/System.Diagnostics.Tools.dll",
442 "build/netstandard2.0/ref/System.Diagnostics.TraceSource.dll",
443 "build/netstandard2.0/ref/System.Diagnostics.Tracing.dll",
444 "build/netstandard2.0/ref/System.Drawing.Primitives.dll",
445 "build/netstandard2.0/ref/System.Drawing.dll",
446 "build/netstandard2.0/ref/System.Dynamic.Runtime.dll",
447 "build/netstandard2.0/ref/System.Globalization.Calendars.dll",
448 "build/netstandard2.0/ref/System.Globalization.Extensions.dll",
449 "build/netstandard2.0/ref/System.Globalization.dll",
450 "build/netstandard2.0/ref/System.IO.Compression.FileSystem.dll",
451 "build/netstandard2.0/ref/System.IO.Compression.ZipFile.dll",
452 "build/netstandard2.0/ref/System.IO.Compression.dll",
453 "build/netstandard2.0/ref/System.IO.FileSystem.DriveInfo.dll",
454 "build/netstandard2.0/ref/System.IO.FileSystem.Primitives.dll",
455 "build/netstandard2.0/ref/System.IO.FileSystem.Watcher.dll",
456 "build/netstandard2.0/ref/System.IO.FileSystem.dll",
457 "build/netstandard2.0/ref/System.IO.IsolatedStorage.dll",
458 "build/netstandard2.0/ref/System.IO.MemoryMappedFiles.dll",
459 "build/netstandard2.0/ref/System.IO.Pipes.dll",
460 "build/netstandard2.0/ref/System.IO.UnmanagedMemoryStream.dll",
461 "build/netstandard2.0/ref/System.IO.dll",
462 "build/netstandard2.0/ref/System.Linq.Expressions.dll",
463 "build/netstandard2.0/ref/System.Linq.Parallel.dll",
464 "build/netstandard2.0/ref/System.Linq.Queryable.dll",
465 "build/netstandard2.0/ref/System.Linq.dll",
466 "build/netstandard2.0/ref/System.Net.Http.dll",
467 "build/netstandard2.0/ref/System.Net.NameResolution.dll",
468 "build/netstandard2.0/ref/System.Net.NetworkInformation.dll",
469 "build/netstandard2.0/ref/System.Net.Ping.dll",
470 "build/netstandard2.0/ref/System.Net.Primitives.dll",
471 "build/netstandard2.0/ref/System.Net.Requests.dll",
472 "build/netstandard2.0/ref/System.Net.Security.dll",
473 "build/netstandard2.0/ref/System.Net.Sockets.dll",
474 "build/netstandard2.0/ref/System.Net.WebHeaderCollection.dll",
475 "build/netstandard2.0/ref/System.Net.WebSockets.Client.dll",
476 "build/netstandard2.0/ref/System.Net.WebSockets.dll",
477 "build/netstandard2.0/ref/System.Net.dll",
478 "build/netstandard2.0/ref/System.Numerics.dll",
479 "build/netstandard2.0/ref/System.ObjectModel.dll",
480 "build/netstandard2.0/ref/System.Reflection.Extensions.dll",
481 "build/netstandard2.0/ref/System.Reflection.Primitives.dll",
482 "build/netstandard2.0/ref/System.Reflection.dll",
483 "build/netstandard2.0/ref/System.Resources.Reader.dll",
484 "build/netstandard2.0/ref/System.Resources.ResourceManager.dll",
485 "build/netstandard2.0/ref/System.Resources.Writer.dll",
486 "build/netstandard2.0/ref/System.Runtime.CompilerServices.VisualC.dll",
487 "build/netstandard2.0/ref/System.Runtime.Extensions.dll",
488 "build/netstandard2.0/ref/System.Runtime.Handles.dll",
489 "build/netstandard2.0/ref/System.Runtime.InteropServices.RuntimeInformation.dll",
490 "build/netstandard2.0/ref/System.Runtime.InteropServices.dll",
491 "build/netstandard2.0/ref/System.Runtime.Numerics.dll",
492 "build/netstandard2.0/ref/System.Runtime.Serialization.Formatters.dll",
493 "build/netstandard2.0/ref/System.Runtime.Serialization.Json.dll",
494 "build/netstandard2.0/ref/System.Runtime.Serialization.Primitives.dll",
495 "build/netstandard2.0/ref/System.Runtime.Serialization.Xml.dll",
496 "build/netstandard2.0/ref/System.Runtime.Serialization.dll",
497 "build/netstandard2.0/ref/System.Runtime.dll",
498 "build/netstandard2.0/ref/System.Security.Claims.dll",
499 "build/netstandard2.0/ref/System.Security.Cryptography.Algorithms.dll",
500 "build/netstandard2.0/ref/System.Security.Cryptography.Csp.dll",
501 "build/netstandard2.0/ref/System.Security.Cryptography.Encoding.dll",
502 "build/netstandard2.0/ref/System.Security.Cryptography.Primitives.dll",
503 "build/netstandard2.0/ref/System.Security.Cryptography.X509Certificates.dll",
504 "build/netstandard2.0/ref/System.Security.Principal.dll",
505 "build/netstandard2.0/ref/System.Security.SecureString.dll",
506 "build/netstandard2.0/ref/System.ServiceModel.Web.dll",
507 "build/netstandard2.0/ref/System.Text.Encoding.Extensions.dll",
508 "build/netstandard2.0/ref/System.Text.Encoding.dll",
509 "build/netstandard2.0/ref/System.Text.RegularExpressions.dll",
510 "build/netstandard2.0/ref/System.Threading.Overlapped.dll",
511 "build/netstandard2.0/ref/System.Threading.Tasks.Parallel.dll",
512 "build/netstandard2.0/ref/System.Threading.Tasks.dll",
513 "build/netstandard2.0/ref/System.Threading.Thread.dll",
514 "build/netstandard2.0/ref/System.Threading.ThreadPool.dll",
515 "build/netstandard2.0/ref/System.Threading.Timer.dll",
516 "build/netstandard2.0/ref/System.Threading.dll",
517 "build/netstandard2.0/ref/System.Transactions.dll",
518 "build/netstandard2.0/ref/System.ValueTuple.dll",
519 "build/netstandard2.0/ref/System.Web.dll",
520 "build/netstandard2.0/ref/System.Windows.dll",
521 "build/netstandard2.0/ref/System.Xml.Linq.dll",
522 "build/netstandard2.0/ref/System.Xml.ReaderWriter.dll",
523 "build/netstandard2.0/ref/System.Xml.Serialization.dll",
524 "build/netstandard2.0/ref/System.Xml.XDocument.dll",
525 "build/netstandard2.0/ref/System.Xml.XPath.XDocument.dll",
526 "build/netstandard2.0/ref/System.Xml.XPath.dll",
527 "build/netstandard2.0/ref/System.Xml.XmlDocument.dll",
528 "build/netstandard2.0/ref/System.Xml.XmlSerializer.dll",
529 "build/netstandard2.0/ref/System.Xml.dll",
530 "build/netstandard2.0/ref/System.dll",
531 "build/netstandard2.0/ref/mscorlib.dll",
532 "build/netstandard2.0/ref/netstandard.dll",
533 "build/netstandard2.0/ref/netstandard.xml",
534 "lib/netstandard1.0/_._",
535 "netstandard.library.2.0.3.nupkg.sha512",
536 "netstandard.library.nuspec"
537 ]
538 },
539 "FNA/1.0.0": {
17 "FNA/1.0.0": {
540 "type": "project",
18 "type": "project",
541 "path": "../../FNA/FNA.Core.csproj",
19 "path": "../../FNA/FNA.csproj",
542 "msbuildProject": "../../FNA/FNA.Core.csproj"
20 "msbuildProject": "../../FNA/FNA.csproj"
543 }
21 }
544 },
22 },
545 "projectFileDependencyGroups": {
23 "projectFileDependencyGroups": {
546 ".NETFramework,Version=v4.5": [
24 ".NETFramework,Version=v4.5": [
547 "FNA >= 1.0.0",
25 "FNA >= 1.0.0"
548 "Microsoft.NETFramework.ReferenceAssemblies >= 1.0.0"
549 ],
550 ".NETStandard,Version=v2.0": [
551 "FNA >= 1.0.0",
552 "NETStandard.Library >= 2.0.3"
553 ]
26 ]
554 },
27 },
555 "packageFolders": {
28 "packageFolders": {
556 "/home/alys/.nuget/packages/": {},
29 "/home/alys/.nuget/packages/": {}
557 "/usr/share/dotnet/sdk/NuGetFallbackFolder": {}
558 },
30 },
559 "project": {
31 "project": {
560 "version": "1.0.0",
32 "version": "1.0.0",
561 "restore": {
33 "restore": {
562 "projectUniqueName": "/home/alys/repos/isometric-park-fna/SpriteFontPlus/src/SpriteFontPlus.FNA.Core.csproj",
34 "projectUniqueName": "/home/alys/repos/isometric-park-fna/SpriteFontPlus/src/SpriteFontPlus.FNA.csproj",
563 "projectName": "SpriteFontPlus",
35 "projectName": "SpriteFontPlus",
564 "projectPath": "/home/alys/repos/isometric-park-fna/SpriteFontPlus/src/SpriteFontPlus.FNA.Core.csproj",
36 "projectPath": "/home/alys/repos/isometric-park-fna/SpriteFontPlus/src/SpriteFontPlus.FNA.csproj",
565 "packagesPath": "/home/alys/.nuget/packages/",
37 "packagesPath": "/home/alys/.nuget/packages/",
566 "outputPath": "/home/alys/repos/isometric-park-fna/SpriteFontPlus/src/obj/",
38 "outputPath": "/home/alys/repos/isometric-park-fna/SpriteFontPlus/src/obj/",
567 "projectStyle": "PackageReference",
39 "projectStyle": "PackageReference",
568 "crossTargeting": true,
569 "fallbackFolders": [
570 "/usr/share/dotnet/sdk/NuGetFallbackFolder"
571 ],
572 "configFilePaths": [
40 "configFilePaths": [
573 "/home/alys/.nuget/NuGet/NuGet.Config"
41 "/home/alys/.config/NuGet/NuGet.Config"
574 ],
42 ],
575 "originalTargetFrameworks": [
43 "originalTargetFrameworks": [
576 "net45",
44 "net45"
577 "netstandard2.0"
578 ],
45 ],
579 "sources": {
46 "sources": {
580 "https://api.nuget.org/v3/index.json": {}
47 "https://api.nuget.org/v3/index.json": {}
581 },
48 },
582 "frameworks": {
49 "frameworks": {
583 "net45": {
50 "net45": {
584 "targetAlias": "net45",
585 "projectReferences": {
51 "projectReferences": {
586 "/home/alys/repos/isometric-park-fna/FNA/FNA.Core.csproj": {
52 "/home/alys/repos/isometric-park-fna/FNA/FNA.csproj": {
587 "projectPath": "/home/alys/repos/isometric-park-fna/FNA/FNA.Core.csproj"
53 "projectPath": "/home/alys/repos/isometric-park-fna/FNA/FNA.csproj"
588 }
589 }
590 },
591 "netstandard2.0": {
592 "targetAlias": "netstandard2.0",
593 "projectReferences": {
594 "/home/alys/repos/isometric-park-fna/FNA/FNA.Core.csproj": {
595 "projectPath": "/home/alys/repos/isometric-park-fna/FNA/FNA.Core.csproj"
596 }
54 }
597 }
55 }
598 }
56 }
@@ -605,38 +63,7
605 },
63 },
606 "frameworks": {
64 "frameworks": {
607 "net45": {
65 "net45": {
608 "targetAlias": "net45",
66 "runtimeIdentifierGraphPath": "/usr/lib/mono/msbuild/Current/bin/RuntimeIdentifierGraph.json"
609 "dependencies": {
610 "Microsoft.NETFramework.ReferenceAssemblies": {
611 "suppressParent": "All",
612 "target": "Package",
613 "version": "[1.0.0, )",
614 "autoReferenced": true
615 }
616 },
617 "runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/5.0.403/RuntimeIdentifierGraph.json"
618 },
619 "netstandard2.0": {
620 "targetAlias": "netstandard2.0",
621 "dependencies": {
622 "NETStandard.Library": {
623 "suppressParent": "All",
624 "target": "Package",
625 "version": "[2.0.3, )",
626 "autoReferenced": true
627 }
628 },
629 "imports": [
630 "net461",
631 "net462",
632 "net47",
633 "net471",
634 "net472",
635 "net48"
636 ],
637 "assetTargetFallback": true,
638 "warn": true,
639 "runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/5.0.403/RuntimeIdentifierGraph.json"
640 }
67 }
641 }
68 }
642 }
69 }
@@ -1,13 +1,8
1 {
1 {
2 "version": 2,
2 "version": 2,
3 "dgSpecHash": "rrWB70esJdTf9dAMXa2E6SMBq+jD6SmvcvweYYuLu7Fwj06OkeGl84NRxKWhvOqoLVKcJnfxbh2rNXh6qwNWGg==",
3 "dgSpecHash": "tOnJ1OKHA9fVe0r0rF8SXkY/g6Dsae+u1nunMHJtIiHm2UrxMmZk6x6accdLrAYlwIjYkj7fcv/RHNfOBL/3Kg==",
4 "success": true,
4 "success": true,
5 "projectFilePath": "/home/alys/repos/isometric-park-fna/SpriteFontPlus/src/SpriteFontPlus.FNA.Core.csproj",
5 "projectFilePath": "/home/alys/repos/isometric-park-fna/SpriteFontPlus/src/SpriteFontPlus.FNA.csproj",
6 "expectedPackageFiles": [
6 "expectedPackageFiles": [],
7 "/home/alys/.nuget/packages/microsoft.netcore.platforms/1.1.0/microsoft.netcore.platforms.1.1.0.nupkg.sha512",
8 "/home/alys/.nuget/packages/microsoft.netframework.referenceassemblies/1.0.0/microsoft.netframework.referenceassemblies.1.0.0.nupkg.sha512",
9 "/home/alys/.nuget/packages/microsoft.netframework.referenceassemblies.net45/1.0.0/microsoft.netframework.referenceassemblies.net45.1.0.0.nupkg.sha512",
10 "/home/alys/.nuget/packages/netstandard.library/2.0.3/netstandard.library.2.0.3.nupkg.sha512"
11 ],
12 "logs": []
7 "logs": []
13 } No newline at end of file
8 }
@@ -35,8 +35,11
35 Trees:
35 Trees:
36 - Add basic maintenance cost @milestone(1: Basic Money) @done(2021-01-27)
36 - Add basic maintenance cost @milestone(1: Basic Money) @done(2021-01-27)
37 - Add basic age simulation
37 - Add basic age simulation
38 - Add water @milestone(6: Trees and Tiles)
38 - Add water @milestone(6: Trees and Tiles) @done(2022-07-24)
39 - Biodiversity @maybe @milestone(6: Trees and Tiles)
39 - Biodiversity @maybe @milestone(6: Trees and Tiles)
40 - Tree Types @done(2022-01-27)
41 - Grass?
42 - Biodiversity score?
40 - Research agreements @maybe
43 - Research agreements @maybe
41 - Forest rangers allocatable as law enforcement? @maybe
44 - Forest rangers allocatable as law enforcement? @maybe
42 Have to think about thematic implications
45 Have to think about thematic implications
@@ -44,6 +47,21
44 Seems like a good way to get started?
47 Seems like a good way to get started?
45 Reduces cost of vandalism repair?
48 Reduces cost of vandalism repair?
46 - Sell Firewood?
49 - Sell Firewood?
50 - Preserve @milestone(6: Trees and Tiles)
51 - Add preserve tool @done(2021-02-17)
52 - Add bulldozer @done(2022-03-16)
53 - Adjust odds in preserve @done(2021-02-20)
54 - Dialog
55 - Assistant warns when a lot of the map has been made into preserve?
56 Maybe a lot made into preserve at once?
57 - Congratulations when reaching a majority @done(2022-12-14)
58 Maybe 75 percent
59 - Make them less easy to game
60 Right now they are free to add and remove, meaning you could make the whole map preserve until you need it for something else
61 One option: penalize if user switches them too early
62 Another option: charge nominal amount
63 Another option: benefits take time to accrue. Avoids punishment
64 Maybe a combination: benefits accrue after an area has been preserved for a while? Tourism ceases immediately. And you don't get offers to build on that land? Or fewer offers?
47 Staff:
65 Staff:
48 - Ranger staffing? @maybe @milestone(1: Basic Money)
66 - Ranger staffing? @maybe @milestone(1: Basic Money)
49 - Staffing window
67 - Staffing window
@@ -54,6 +72,9
54 - Employee training mechanic @maybe
72 - Employee training mechanic @maybe
55 Leisure:
73 Leisure:
56 - Add way to mark off area for leisure @milestone(7: Leisure)
74 - Add way to mark off area for leisure @milestone(7: Leisure)
75 Maybe add leisure items instead?
76 Or both?
77 - Add paths @milestone(7: Leisure)
57 - Basic satisfaction @milestone(7: Leisure)
78 - Basic satisfaction @milestone(7: Leisure)
58 - Set
79 - Set
59 End games/outcomes:
80 End games/outcomes:
@@ -62,7 +83,7
62 - Self-sufficient
83 - Self-sufficient
63 i.e., no need for subsidy
84 i.e., no need for subsidy
64 May not be ending
85 May not be ending
65 - Forest mismanagement @milestone(5: Events)
86 - Forest mismanagement @milestone(5: Events) @done(2021-12-12)
66 - Figure out threshold
87 - Figure out threshold
67 - High biodiversity? @maybe
88 - High biodiversity? @maybe
68 - High satisfaction
89 - High satisfaction
@@ -83,7 +104,7
83 Misc:
104 Misc:
84 - Assistant commentary @milestone(5: Events)
105 - Assistant commentary @milestone(5: Events)
85 Need to ensure it's not annoying
106 Need to ensure it's not annoying
86 - Basic random events
107 - Basic random events
87 - Tree planting campaign @done(2021-09-28) @milestone(5: Events)
108 - Tree planting campaign @done(2021-09-28) @milestone(5: Events)
88 - Friends of the park fundraiser @done(2021-11-07) @milestone(5: Events)
109 - Friends of the park fundraiser @done(2021-11-07) @milestone(5: Events)
89 - Federal grant @done(2021-11-27) @milestone(5: Events)
110 - Federal grant @done(2021-11-27) @milestone(5: Events)
@@ -94,14 +115,21
94 would probably have to animate
115 would probably have to animate
95 - Disease
116 - Disease
96 - Photos for dialog?
117 - Photos for dialog?
97 - Graphs window
118 - Graphs window @done(2021-01-05)
98 Could use ImPlot for this
119 Could use ImPlot for this
99
120
100 Structure:
121 Structure:
101 - Add modes
122 - Add modes
102 - Refactor stuff out of FNAGame
123 - Refactor stuff out of FNAGame
103 At this point, virtually everything in FNAGame is setting up key Engines or doing drawing
124 At this point, virtually everything in FNAGame is setting up key Engines or doing drawing
104 - Saving @prototyped @milestone(4: Beginning)
125 - Saving @prototyped @milestone(4: Beginning)
126 - Options are duplicated in too many places:
127 - Replace Options with OptionComponent?
128 - Put Options in OptionMessage?
129 - Remove Options from Encompass?
130 Options don't seem like a great fit for th ECS model.
131 - OptionsWindow should use two Options instances instead of recreating each field.
132 Adding an option requires adding variabls
105 - Encompass @maybe @done(2021-04-03)
133 - Encompass @maybe @done(2021-04-03)
106 Currently thinking about a hybrid model where the Simulation class receives a lot of the events from Encompass. so things like Events, Contracts, and Research agreements are handled by Encompass. Perhaps Input, too?
134 Currently thinking about a hybrid model where the Simulation class receives a lot of the events from Encompass. so things like Events, Contracts, and Research agreements are handled by Encompass. Perhaps Input, too?
107 - Ensure library loads
135 - Ensure library loads
@@ -144,7 +172,40
144 - Additional in-game menu
172 - Additional in-game menu
145 - Save
173 - Save
146 - Save & Quit
174 - Save & Quit
175 - Fix selection
176 Selections require two components to really work, which is messy and doesn't really fit. A Selection without some sort of associated selection that describes what's selected doesn't really work
177 - Turn tools into classes?
178 Creating a shallow hierarchy seems a little nicer than the current setup.
147
179
180 Music and Audio:
181 Sound Effects:
182 - Generic click sound (push button) @done(2022-05-09)
183 - Cheer/boo crowd sound effect
184 This is a sorta easter egg and a reference to SimCity
185 - Explosion effect (for bulldozer)
186
187 Performance:
188 Issues:
189 - Seeing up to 32 ms in update on framework-release? @done(2022-05-16)
190 - Drawing very large areas is very slow. @done(2022-05-16)
191 Sorta fixed
192 - Slows to a halt (~7fps) when drawing many preserve squares.
193 Drawing each tile individually is very silly when it's just a (big) square anyway.
194 For edges: Using a dictionary with counts doesn't work either. (~5 fps) Nor using sets.
195 Instead need to do the fill and edge-drawing as large regions.
196 - Draw slows down after merely leaving it running @done(2022-11-14)
197 Debug issue; could be faster but basically solved
198 Structural improvements:
199 - Button to clear/thin debug buffers?
200 Take every nth to reduce counters to past 100 measurements
201 - Disable some timing code in release mode?
202 Needs some way to enable it.
203 - Avoid redrawing tiles every time?
204 Draw tiles once into buffer
205 Instrumentation:
206 - Time individual sections of update loop @done(2022-05-16)
207 - Time simulation @done(2022-05-16)
208 - Time each engine?
148 Other features:
209 Other features:
149 Accessibility:
210 Accessibility:
150 - Verify contrast
211 - Verify contrast
@@ -181,29 +242,54
181 Internationalization:
242 Internationalization:
182 - Probably won't pay to translate or anything, but should consider setting up the structure @maybe @milestone(4: Beginning)
243 - Probably won't pay to translate or anything, but should consider setting up the structure @maybe @milestone(4: Beginning)
183 If nothing else, might be useful for future projects.
244 If nothing else, might be useful for future projects.
245 Balance:
246 - Hard mode is impossible with current map size.
247 Upkeep is too much money.
248 Might be addressed by adding staff instead of fixed upkeep.
184 Bugs:
249 Bugs:
185 Graphics:
250 Graphics:
186 - Trees jump around when pressing show/hide grid
251 - Trees jump around when pressing show/hide grid @done(2022-01-23)
187 - Grids sometimes overlap trees, including area overlays
252 - Grids sometimes overlap trees, including area overlays
188 - Trees sometimes
253 - Trees sometimes overlap each other @done(2022-01-23)
254 - Area overlays overlap trees @done(2022-01-24)
189 - Sometimes framerate jumps to 180-200 fps. (Better than reverse, but kinda weird)
255 - Sometimes framerate jumps to 180-200 fps. (Better than reverse, but kinda weird)
190 - Graphics don't adjust for the resolution
256 - Graphics don't adjust for the resolution
191 - Scroll area @done(2021-06-23)
257 - Scroll area @done(2021-06-23)
192 - Ingame Menu @done(2021-06-22)
258 - Ingame Menu @done(2021-06-22)
193 - Main Menu
259 - Main Menu
194 Simulation:
260 Simulation:
261 - Can keep playing after losing if you don't acknowledge the loss in the dialog
262 - Create preemption/priority system
263 Have to decide whether to have two levels: normal/preempting or a series of priorities
195 - Expired areas can't be reused. @done(2021-08-07)
264 - Expired areas can't be reused. @done(2021-08-07)
265 - Trees seem to spawn in lines.
266 Is it only spawning neighbor trees in one direction?
196 Dialog:
267 Dialog:
197 - Dialogs don't appear after
268 - Dialogs don't appear after
269 Crashes/Stability:
270 - News window crashes.
271 - Drawing error when clicking sometimes on main screen. @done(2022-04-27)
272 Tries to draw area?
273 - Crash when extending preserve past bottom. @done(2022-04-27)
274 - Segfault on quit (when it tries to dispose of the sound) or on playing sound on Linux
275 May be due to a quirk of my Linux setup
276 - Weird ImGui crash:
277 dotnet: /home/alys/repos/outside/ImGui.NET-nativebuild/cimgui/imgui/imgui.cpp:6293: bool ImGui::Begin(const char*, bool*, ImGuiWindowFlags): Assertion `name != __null && name[0] != '\0'' failed.
278 - Crashes after exiting a game.
279 Seems to be a draw issue (Batch hasn't begun.)
280 In Area renderer?
281 Also happens when you lose.
282 Unhandled exception: System.InvalidOperationException: Draw was called, but Begin has not yet been called. Begin must be called successfully before you can call Draw.
283 - No handler for Ink errors.
284 There really shouldn't be any way to run into an Ink error, but they will probably slip in.
198 Misc:
285 Misc:
286 - Starting a game after exiting a previous one doesn't really work, afaict
287 Also crases, but I suspect the crash isn't related.
199 - Events may not be deleted
288 - Events may not be deleted
200 - Exits are messy (does Encompass add threading?) @done(2021-11-28)
289 - Exits are messy (does Encompass add threading?) @done(2021-11-28)
201 Appears to be fixed by using Game.Exit
290 Appears to be fixed by using Game.Exit
202 [xcb] Unknown sequence number while appending request
291 [xcb] Unknown sequence number while appending request
203 [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
292 [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
204 [xcb] Aborting, sorry about that.
293 [xcb] Aborting, sorry about that.
205 dotnet: ../../src/xcb_io.c:145: append_pending_request: Assertion `!xcb_xlib_unknown_seq_number' failed.
294 dotnet: ../../src/xcb_io.c:145: append_pending_request: Assertion `!xcb_xlib_unknown_seq_number' failed.
206 Aborted (core dumped)
295 Aborted (core dumped)
207 - Segfault on quit (when it tries to dispose of the sound) or on playing sound on Linux
208 May be due to a quirk of my Linux setup
209
@@ -5,10 +5,6
5 MinimumVisualStudioVersion = 10.0.40219.1
5 MinimumVisualStudioVersion = 10.0.40219.1
6 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "isometric-park-fna-core", "isometric-park-fna\isometric-park-fna-core.csproj", "{4BA11D6F-B980-4E5B-99FE-729AD3D34A12}"
6 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "isometric-park-fna-core", "isometric-park-fna\isometric-park-fna-core.csproj", "{4BA11D6F-B980-4E5B-99FE-729AD3D34A12}"
7 EndProject
7 EndProject
8 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImPlot.NET", "ImPlot.NET\ImPlot.NET.csproj", "{50014300-51ED-4F7B-B72E-16BE29FBAE95}"
9 EndProject
10 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImGui.NET.Core", "ImGui.NET\ImGui.NET.Core.csproj", "{E7AB4506-A404-4BE8-AF71-5486AD9EBC71}"
11 EndProject
12 Global
8 Global
13 GlobalSection(SolutionConfigurationPlatforms) = preSolution
9 GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 Debug|Any CPU = Debug|Any CPU
10 Debug|Any CPU = Debug|Any CPU
@@ -13,8 +13,6
13 EndProject
13 EndProject
14 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "encompass-cs", "encompass-cs\encompass-cs\encompass-cs.csproj", "{D0CCEB74-D8A8-446A-AFFC-2B043DAF1E5F}"
14 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "encompass-cs", "encompass-cs\encompass-cs\encompass-cs.csproj", "{D0CCEB74-D8A8-446A-AFFC-2B043DAF1E5F}"
15 EndProject
15 EndProject
16 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImPlot.NET", "ImPlot.NET\ImPlot.NET.csproj", "{11118CB6-165C-4459-B5F4-54843206025E}"
17 EndProject
18 Global
16 Global
19 GlobalSection(SolutionConfigurationPlatforms) = preSolution
17 GlobalSection(SolutionConfigurationPlatforms) = preSolution
20 Debug|anycpu = Debug|anycpu
18 Debug|anycpu = Debug|anycpu
@@ -1,18 +1,34
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3
3
4 using Microsoft.Xna.Framework;
5
4 namespace isometricparkfna
6 namespace isometricparkfna
5 {
7 {
6
8
7 public class CellMap
9 public class CellMap
8 {
10 {
9 public List<List<Cell>> cells;
11 public List<List<Cell>> cells;
12 public List<Vector2> WaterCells;
13
14 //Defaults; overridden by settings from FNAGame in practice:
10 public int MapWidth = 50;
15 public int MapWidth = 50;
11 public int MapHeight = 50;
16 public int MapHeight = 50;
12
17
13 public int ZoneWidth = 10;
18 public int ZoneWidth = 10;
14 public int ZoneHeight = 10;
19 public int ZoneHeight = 10;
15
20
21
22 //These coefficients modify values I set based on the original 50x50 maps.
23 //Eventually I'll probably allow for multiple map sizes, so instead of changing those constants,
24 //I'm adding a multiplier based on the size of the map.
25 //
26 //What's the difference between these two multipliers?
27 //If you double the sides of the map, the linear multiplier is 2,
28 //but the area multiplier is 4 (2 x 2).
29 public int LinearMultiplier;
30 public int AreaMultiplier;
31
16 public int tree_count
32 public int tree_count
17 {
33 {
18 get
34 get
@@ -42,7 +58,6
42 }
58 }
43 }
59 }
44
60
45
46 public CellMap()
61 public CellMap()
47 {
62 {
48 //TileMap(MapWidth, MapHeight);
63 //TileMap(MapWidth, MapHeight);
@@ -55,6 +70,12
55
70
56 this.cells = new List<List<Cell>>();
71 this.cells = new List<List<Cell>>();
57
72
73 //Cached:
74 this.WaterCells = new List<Vector2>();
75
76 this.LinearMultiplier = (int)(((this.MapWidth / 50) + (this.MapHeight / 50)) / 2);
77 this.AreaMultiplier = (int)((this.MapWidth * this.MapHeight) / (50 * 50));
78
58 for (int i = 0; i < height; i++)
79 for (int i = 0; i < height; i++)
59 {
80 {
60 List<Cell> newRow = new List<Cell>();
81 List<Cell> newRow = new List<Cell>();
@@ -74,7 +95,7
74 {
95 {
75 foreach (Cell cell in row)
96 foreach (Cell cell in row)
76 {
97 {
77 if (cell.hasTree)
98 if (cell.HasTree)
78 {
99 {
79 yield return cell;
100 yield return cell;
80 }
101 }
@@ -88,7 +109,7
88 {
109 {
89 foreach (Cell cell in row)
110 foreach (Cell cell in row)
90 {
111 {
91 if (cell.hasTree)
112 if (cell.HasTree)
92 {
113 {
93 yield return cell;
114 yield return cell;
94 }
115 }
@@ -112,7 +133,7
112 return MathUtils.BetweenExclusive(x, 0, MapWidth - 1) && MathUtils.BetweenExclusive(y, 0, MapHeight - 1);
133 return MathUtils.BetweenExclusive(x, 0, MapWidth - 1) && MathUtils.BetweenExclusive(y, 0, MapHeight - 1);
113 }
134 }
114
135
115 private System.Collections.Generic.IEnumerable<Cell> iterate_neighbors(int x, int y)
136 public System.Collections.Generic.IEnumerable<Cell> iterate_neighbor_cells(int x, int y)
116 {
137 {
117 //iterates over neighbors (clockwise starting at noon/midnight)
138 //iterates over neighbors (clockwise starting at noon/midnight)
118 if (inBounds(x, y + 1))
139 if (inBounds(x, y + 1))
@@ -149,12 +170,61
149 }
170 }
150 }
171 }
151
172
173 public System.Collections.Generic.IEnumerable<(int, int)> iterate_neighbor_cell_locations(int x, int y)
174
175 {
176 //iterates over neighbors (clockwise starting at noon/midnight)
177 if (inBounds(x, y + 1))
178 {
179 yield return (x - 1, y);
180 }
181 if (inBounds(x + 1, y + 1))
182 {
183 yield return (x + 1, y + 1);
184 }
185 if (inBounds(x + 1, y))
186 {
187 yield return (x + 1, y);
188 }
189 if (inBounds(x + 1, y - 1))
190 {
191 yield return (x + 1, y - 1);
192 }
193 if (inBounds(x, y - 1))
194 {
195 yield return (x, y - 1);
196 }
197 if (inBounds(x - 1, y-1))
198 {
199 yield return (x - 1, y-1);
200 }
201 if (inBounds(x - 1, y))
202 {
203 yield return (x - 1, y);
204 }
205 if (inBounds(x - 1, y + 1))
206 {
207 yield return (x - 1, y+1);
208 }
209 }
210
211
212 public System.Collections.Generic.IEnumerable<Cell> iterate_neighbors(int x, int y)
213 {
214 foreach (Cell neighbor in this.iterate_neighbor_cells(x, y))
215 {
216 if (neighbor.HasTree) {
217 yield return neighbor;
218 }
219 }
220 }
221
152 private int countNeighbors(int x, int y)
222 private int countNeighbors(int x, int y)
153 {
223 {
154 int count = 0;
224 int count = 0;
155 foreach (Cell neighbor in this.iterate_neighbors(x, y))
225 foreach (Cell neighbor in this.iterate_neighbor_cells(x, y))
156 {
226 {
157 if (neighbor.hasTree) {
227 if (neighbor.HasTree) {
158 count++;
228 count++;
159 }
229 }
160 }
230 }
@@ -162,6 +232,17
162 return count;
232 return count;
163 }
233 }
164
234
235 public static Vector2 calculateMousegrid(Vector2 normalizedMousePos)
236 {
237 Vector2 adjust = new Vector2(Tile.TileSpriteWidth / 2, Tile.TileSpriteHeight);
238 Vector2 adjustedMousePos = normalizedMousePos - adjust;
239
240 float boardx = ((adjustedMousePos.X / Tile.TileSpriteWidth) + (adjustedMousePos.Y / Tile.TileSpriteHeight));
241 float boardy = ((adjustedMousePos.Y / Tile.TileSpriteHeight) - (adjustedMousePos.X / Tile.TileSpriteWidth));
242
243 return new Vector2((int)boardx, (int)boardy);
244 }
245
165 public System.Collections.Generic.IEnumerable<Cell> iterate_cells_with_neighbors(int neighbors)
246 public System.Collections.Generic.IEnumerable<Cell> iterate_cells_with_neighbors(int neighbors)
166 {
247 {
167 for (int i = 0; i < MapHeight; i++)
248 for (int i = 0; i < MapHeight; i++)
@@ -175,44 +256,93
175 }
256 }
176 }
257 }
177 }
258 }
259 }
178
260
179
261 public System.Collections.Generic.IEnumerable<(int, int)> iterate_cell_locations_with_neighbors(int neighbors)
262 {
263 for (int i = 0; i < MapHeight; i++)
264 {
265 List<Cell> newRow = new List<Cell>();
266 for (int j = 0; j < MapWidth; j++)
267 {
268 if (this.countNeighbors(i, j) >= neighbors)
269 {
270 yield return (i, j);
271 }
272 }
273 }
180 }
274 }
181
275
182 public enum CellStatus {
276 public enum CellStatus {
183 Clear,
277 Clear,
184 LivingTree,
278 LivingTree,
185 DeadTree
279 DeadTree,
280 Water
281 }
282
283 public enum TreeType {
284 Oak,
285 GenericEvergreen,
286 GenericDeciduous,
287 GenericShrub
186 }
288 }
187
289
188 public class Cell
290 public class Cell
189 {
291 {
190 // public Boolean _hasTree = false;
292 public CellStatus Status {
191 public CellStatus status {
293 get;
294 private set;
295 }
296
297 public String StatusAdjective {
298 get {
299 return this.Status.ToString().Replace("Tree", "");
300 }
301 }
302
303 public TreeType Type {
192 get;
304 get;
193 private set;
305 private set;
194 }
306 }
195
307
196 public Boolean hasTree {
308 public String TypeName {
309 get {
310 return this.Type.ToString().Replace("Generic", "");
311 }
312 }
313
314 public Boolean HasTree {
197 get {
315 get {
198 return this.status == CellStatus.LivingTree;
316 return this.Status == CellStatus.LivingTree;
317 }
318 }
319
320 public Boolean HasWater {
321 get {
322 return this.Status == CellStatus.Water;
199 }
323 }
200 }
324 }
201
325
202 public DateTime planted;
326 public DateTime Planted;
203
327
204 public void addTree(DateTime datetime) {
328 public void AddTree(DateTime datetime, TreeType type) {
205 this.status = CellStatus.LivingTree;
329 this.Status = CellStatus.LivingTree;
206
330
207 this.planted = datetime;
331 this.Planted = datetime;
332
333 this.Type = type;
208 }
334 }
209
335
210 public void removeTree() {
336 public void AddWater() {
211 this.status = CellStatus.Clear;
337 this.Status = CellStatus.Water;
212 }
338 }
213
339
214 public void markTreeDead() {
340 public void RemoveTree() {
215 this.status = CellStatus.DeadTree;
341 this.Status = CellStatus.Clear;
342 }
343
344 public void MarkTreeDead() {
345 this.Status = CellStatus.DeadTree;
216 }
346 }
217 }
347 }
218 }
348 }
@@ -1,4 +1,3
1
2 using Microsoft.Xna.Framework;
1 using Microsoft.Xna.Framework;
3
2
4 using Encompass;
3 using Encompass;
@@ -7,5 +6,6
7
6
8 public struct AreaComponent : IComponent {
7 public struct AreaComponent : IComponent {
9 public Vector2[] squares;
8 public Vector2[] squares;
9 public Tool Tool;
10 }
10 }
11 }
11 }
@@ -5,7 +5,6
5
5
6 public struct BudgetLineComponent : IComponent
6 public struct BudgetLineComponent : IComponent
7 {
7 {
8
9 public string category;
8 public string category;
10 public decimal amount;
9 public decimal amount;
11 }
10 }
@@ -4,6 +4,8
4
4
5 public struct OptionsComponent : IComponent {
5 public struct OptionsComponent : IComponent {
6 public ProfanityLevel ProfanitySetting;
6 public ProfanityLevel ProfanitySetting;
7 public float SoundEffectVolume;
8 public bool SoundEffectMuted;
7
9
8 }
10 }
9 }
11 }
@@ -3,7 +3,15
3
3
4 namespace isometricparkfna.Components
4 namespace isometricparkfna.Components
5 {
5 {
6 public enum SelectionType {
7 None,
8 Window, //Selected in a window
9 Area, //Selecting an area
10 Tool //Selecting a tool
11 }
12
6 public struct SelectedComponent : IComponent {
13 public struct SelectedComponent : IComponent {
7 public bool selected;
14 public bool selected;
15 public SelectionType Type;
8 }
16 }
9 } No newline at end of file
17 }
@@ -2,14 +2,16
2 VAR playerSwears = 0
2 VAR playerSwears = 0
3 VAR playerRude = 0
3 VAR playerRude = 0
4
4
5
5 VAR GovernorOpinion = 0
6 VAR GovernorOpinion = 0
7 VAR HeadOfParksOpinion = 0
6
8
7 LIST assistantTraits = shy, esoteric, sweary
9 LIST assistantTraits = shy, esoteric, sweary
8
10
9
11
10 EXTERNAL endGame()
12 EXTERNAL endGame()
11
13
12
14 EXTERNAL undoPreserve()
13
15
14
16
15 //This is needed to make both including and for jumping to dialog sections work:
17 //This is needed to make both including and for jumping to dialog sections work:
@@ -50,7 +52,7
50 Governor: Welcome to your new park, director!
52 Governor: Welcome to your new park, director!
51
53
52 * [Okay]
54 * [Okay]
53 Governor: 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!
55 Governor: 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!
54
56
55 * * [And I need to keep the forest healthy, too, right?]
57 * * [And I need to keep the forest healthy, too, right?]
56 ~ GovernorOpinion = GovernorOpinion - 1
58 ~ GovernorOpinion = GovernorOpinion - 1
@@ -299,7 +301,7
299 Head of Parks: What the hell do you think you're doing, you absolute piece of shit?!?
301 Head of Parks: What the hell do you think you're doing, you absolute piece of shit?!?
300
302
301
303
302 * {- not MeetHeadofPark } Sorry, who are you? -> MeetHeadofPark ->
304 * {- not MeetHeadofPark } [Sorry, who are you?] -> MeetHeadofPark ->
303 -> Screwed
305 -> Screwed
304
306
305 + [Uhh, what the fuck?]
307 + [Uhh, what the fuck?]
@@ -311,4 +313,89
311 Head of Parks: Look at this park, it has anxiety! You did that you megadick.
313 Head of Parks: Look at this park, it has anxiety! You did that you megadick.
312 ++ [...]
314 ++ [...]
313 Head of Parks: Yeah, you'd better stay quiet. I don't want to hear a single word out of your fucking useless knifewound of a mouth.
315 Head of Parks: Yeah, you'd better stay quiet. I don't want to hear a single word out of your fucking useless knifewound of a mouth.
314 -> END No newline at end of file
316 -> END
317
318
319 === PreserveProgress ===
320 Head of Parks: Hey, you goddam dunderhead. A quarter of this park is now a preserve! {inc(HeadOfParksOpinion)}
321
322
323 * {- not MeetHeadofPark } [Sorry, who are you?] -> MeetHeadofPark
324 -> WhatPreserves
325
326 + [And you're mad?]
327 Head of Parks: No, you vainglorious buffoon! I'm pretty goddamn pleased. -> WhatPreserves
328 + [Right!]
329 -> WhatPreserves
330
331 = WhatPreserves
332 Head of Parks: I goddamn love preserves. The peach kind. The strawberry kind. But especially the park kind. The trees are left alone. They fucking flourish! Do you think you could fucking photosynthese with people traipsing all over?
333
334 + [No?]
335 Head of Parks: You're goddamn right! You couldn't! Do you know how many preserves have been added since our cuntforsaken governor took office in 2014???
336 ++ [Uh one?]
337 Head of Parks: Not even one! -> Zero
338
339 ++ [None?]
340 Head of Parks: Bingo, my motherfucker -> Zero
341
342 ++ [HellifIknow] {inc(playerSwears)}
343 Head of Parks: Least your honest. -> Zero
344
345 ++ [One dozen]
346 Head of Parks: What? Not even close. -> Zero
347
348 ++ [One Hundred]
349 Head of Parks: What? Not even close. -> Zero
350
351 ++ [One billion]
352 Head of Parks: Fuck off. {dec(HeadOfParksOpinion)} -> HeadofParkSideRant
353 Anyway, it's not a billion!! -> Zero
354
355 = Zero
356 Head of Parks: It's zero! Zero new preserves on God's green earth. Or brown earth. I swear to god...
357 -> END
358
359 === PreserveHalf ===
360 Head of Parks: Hey, you goddam wunderkind. A whole half of this park is now a preserve! {inc(HeadOfParksOpinion)}
361
362 In fact, I want to shake your bloody hand!
363
364 + [Sure!] {inc(HeadOfParksOpinion)}
365 -> PostShake
366
367 + [Umm..okay]
368 -> PostShake
369
370 + [No thanks]
371 -> PostShake
372
373 + [No, you have germs] {dec(HeadOfParksOpinion)}
374 Head of Parks: Bloody hell, I wash! -> PostShake
375
376 = PostShake
377 Head of Parks: Anywyay, you're doing great. If that bloody governor gives you any shit, send him my way. And I think I can scrounge up some money to help you keep the park running.
378
379 + [Thanks]
380 -> END
381
382
383
384 === HeadofParkSideRant ===
385 Head of Parks: Are you fucking with me? Really fucking with me? Listen, you motherfucking piss-eared shit-for-brains backroad bureaucrat, I didn't come hear from the fucking capitol building holding up the whole natural resources administrative state like MiracleGrow Atlas to get scoffed at by a tinpot administrator who think 100 acres and a desk makes you some sort of important person. Aplogize!
386 + [Sorry] ->->
387
388
389 === LargePreserve ===
390 \#assistantName\#: I noticed you reserved quite a bit of space for a nature preserve. Remember that these are unavailable for leisure use or development.
391 + [Isn't it great!]
392 \#assistantName\#: Ummm. Yeah! It is.
393 -> END
394 + [It's fine.]
395 -> END
396 + [Thanks for checking in.]
397 -> END
398 + [I know what I'm doing! Never question me again!] {inc(playerRude)}
399 -> END
400 + [Maybe I've overreached. (Undoes Preserve)] { undoPreserve() }
401 -> END
@@ -1,1 +1,1
1 {"inkVersion":20,"root":[[["done",{"#n":"g-0"}],null],"done",{"placeholder":["end",null],"alter":[{"temp=":"k"},{"temp=":"x"},"ev",{"VAR?":"x"},{"VAR?":"k"},"+","/ev",{"temp=":"x","re":true},null],"inc":[{"temp=":"x"},"ev",{"VAR?":"x"},1,"+","/ev",{"temp=":"x","re":true},null],"dec":[{"temp=":"x"},"ev",{"VAR?":"x"},1,"-","/ev",{"temp=":"x","re":true},null],"endGame":["ev","void","/ev","~ret",null],"Once":[["^Once upon a time...","\n",["ev",{"^->":"Once.0.2.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.^.c-0","flg":2},{"s":["^There were two choices.",{"->":"$r","var":true},null]}],["ev",{"^->":"Once.0.3.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.^.c-1","flg":2},{"s":["^There were four lines of content.",{"->":"$r","var":true},null]}],{"c-0":["ev",{"^->":"Once.0.c-0.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.2.s"},[{"#n":"$r2"}],"\n",{"->":".^.^.g-0"},null],"c-1":["ev",{"^->":"Once.0.c-1.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.3.s"},[{"#n":"$r2"}],"\n",{"->":".^.^.g-0"},null],"g-0":["^They lived happily ever after.","\n","end",null]}],null],"IntroGovernor":[["^Governor: Welcome to your new park, director!","\n","ev","str","^Okay","/str","/ev",{"*":".^.c-0","flg":20},{"c-0":["\n","^Governor: 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!","\n",["ev","str","^And I need to keep the forest healthy, too, right?","/str","/ev",{"*":".^.c-0","flg":20},"ev","str","^Sounds good!","/str","/ev",{"*":".^.c-1","flg":20},{"c-0":["^ ","\n","ev",{"VAR?":"GovernorOpinion"},1,"-","/ev",{"VAR=":"GovernorOpinion","re":true},"^Governor: Ummm, yeah","\n",["ev","str","^...","/str","/ev",{"*":".^.c-0","flg":20},{"c-0":["\n","end",{"#f":5}]}],{"#f":5}],"c-1":["\n","ev",{"VAR?":"GovernorOpinion"},1,"+","/ev",{"VAR=":"GovernorOpinion","re":true},"^Governor: I'll check in soon.","\n","end",{"#f":5}]}],{"#f":5}]}],null],"IntroAssistant":[["^#assistantName#: Hello. I'm #assistantName#.","\n","ev","str","^Nice to meet you.","/str","/ev",{"*":".^.c-0","flg":20},{"c-0":["\n","^#assistantName#: You can use the mouse or arrow keys to move around, and the plus and minus keys to zoom in and out. B opens the budget and F lets you adjust Forest Policy.","\n",["ev","str","^Got it, thanks.","/str","/ev",{"*":".^.c-0","flg":20},"ev","str","^How are you?","/str","/ev",{"*":".^.c-1","flg":20},{"c-0":["\n","^#assistantName#: Bye","\n","end",{"#f":5}],"c-1":["\n","^#assistantName#: #howdoing#","\n","end",{"#f":5}]}],{"#f":5}]}],null],"BadNewsReact":[["ev","str","^Damn.","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Fuck.","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Shoot.","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^*Sigh.* Fine.","/str","/ev",{"*":".^.c-3","flg":4},"ev","str","^Who cares?","/str","/ev",{"*":".^.c-4","flg":4},{"c-0":["^ ","ev",{"^var":"playerSwears","ci":-1},{"f()":"inc"},"out","/ev","\n","ev","void","/ev","->->",null],"c-1":["^ ","ev",{"^var":"playerSwears","ci":-1},{"f()":"inc"},"out","/ev","\n","ev","void","/ev","->->",null],"c-2":["^ ","ev",{"^var":"playerSwears","ci":-1},{"f()":"inc"},"out","/ev","\n","ev","void","/ev","->->",null],"c-3":["\n","ev","void","/ev","->->",null],"c-4":["\n","ev","void","/ev","->->",null]}],null],"AssistantAcknowlege":[["ev","str","^Thanks.","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Mmmm hmm.","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Get to it.","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^I really appreciate it, #assistantName#","/str","/ev",{"*":".^.c-3","flg":4},{"c-0":["\n","ev","void","/ev","->->",null],"c-1":["\n","ev","void","/ev","->->",null],"c-2":["^ ","ev",{"^var":"playerRude","ci":-1},{"f()":"inc"},"out","/ev","\n","ev","void","/ev","->->",null],"c-3":["\n",{"->":".^.^.^.Appreciate"},null]}],{"Appreciate":["^#assistantName#: ","ev",{"VAR?":"assistantTraits"},{"VAR?":"shy"},"?","/ev",[{"->":".^.b","c":true},{"b":["^...",{"->":".^.^.^.8"},null]}],[{"->":".^.b"},{"b":[["ev","visit",3,"seq","/ev","ev","du",0,"==","/ev",{"->":".^.s0","c":true},"ev","du",1,"==","/ev",{"->":".^.s1","c":true},"ev","du",2,"==","/ev",{"->":".^.s2","c":true},"nop",{"s0":["pop","^No problem.",{"->":".^.^.23"},null],"s1":["pop","^Oh, you're welcome.",{"->":".^.^.23"},null],"s2":["pop","^My pleasure.",{"->":".^.^.23"},null],"#f":5}],{"->":".^.^.^.8"},null]}],"nop","\n","ev","void","/ev","->->",null]}],"MassVandalism":[["^#assistantName#: Bad news, director.","\n","ev","str","^Oh?","/str","/ev",{"*":".^.c-0","flg":4},{"c-0":["\n","^#assistantName#: A number of trees have been seriously damaged overnight.","\n",["ev","str","^How bad are they?","/str","/ev",{"*":".^.c-0","flg":4},{"c-0":["\n","^#assistantName#: I'm no botanist, but they're not great. The gouges are pretty deep.","\n",{"->t->":"BadNewsReact"},"^#assistantName#: Yeah, it's ","ev",{"VAR?":"assistantTraits"},{"VAR?":"sweary"},"?","/ev",[{"->":".^.b","c":true},{"b":["^fucking",{"->":".^.^.^.11"},null]}],"nop","^ awful.","\n","^I'll see who's around and get to cleaning.","\n",{"->t->":"AssistantAcknowlege"},"end",null]}],null]}],null],"LowFunds":[["^#assistantName#: Director, our funds are getting dangerously low!","\n","ev","str","^Don't worry about it. I have a plan.","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^I know.","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Stop bothering me with things I already know!","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^Have any ideas?","/str","/ev",{"*":".^.c-3","flg":4},"ev","str","^What?","/str","/ev",{"*":".^.c-4","flg":4},{"c-0":["\n","end",null],"c-1":["\n","end",null],"c-2":["^ ","ev",{"^var":"playerRude","ci":-1},{"f()":"inc"},"out","/ev","\n","end",null],"c-3":["\n","^#assistantName#: Consider accepting some contracts. Even if they're not the best terms, they'll keep us from running out of money.","\n","end",null],"c-4":["\n","^#assistantName#: Yes, we have less than $25,000. We're running the risk of a default.","\n",{"->t->":"BadNewsReact"},"^#assistantName#: I know! consider accepting some contracts. Even if they're not the best terms, they'll keep us from running out of money.","\n","end",null]}],null],"VeryLowFunds":[["^Governor: Director, you have almost no reserve funds. This isn't acceptable.","\n","ev",{"CNT?":".^.^"},1,">","/ev",[{"->":".^.b","c":true},{"b":["^ I can't believe I'm having this conversation with you again. ",{"->":".^.^.^.8"},null]}],"nop","\n","ev","str","^I know. I'm working on it.","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Have any ideas?","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^What happens if I run out of money?","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^What?","/str","/ev",{"*":".^.c-3","flg":4},{"c-0":["\n","^Governor: For your sake, I hope so.","\n","end",null],"c-1":["\n","^Governor: Accept some contracts. Now's not the time to worry about sustainability, or whatever you natural resources types care about. Just take the deal. They'll keep you from running out of money.","\n","end",null],"c-2":["\n",{"->":".^.^.^.WhatHappens"},null],"c-3":["\n",{"->":".^.^.^.Surprise"},null]}],{"Surprise":[["^Governor: Is this a *surprise* to you?","\n","ev","str","^Uh, um, no.","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Honestly, yes.","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^What happens if I run out of money?","/str","/ev",{"*":".^.c-2","flg":4},{"c-0":["\n","^Governor: Well, I hope you have a plan...","\n","^For your sake.","\n","end",null],"c-1":["\n","^Governor: Well! I appreciate your directness. But I hope you have a plan...","\n","^For your sake.","\n","end",null],"c-2":["\n",{"->":".^.^.^.^.WhatHappens"},null]}],null],"WhatHappens":[["^Governor: If you run out of money entirely...","\n","^The park will be fine, in the long run. The state department of natural resources will use its funds to bail the park out. Someone from my office will come in and trim the budget.","\n","^You, however, will be asked to resign.","\n","ev","str","^And if I don't resign?","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^I understand.","/str","/ev",{"*":".^.c-1","flg":4},{"c-0":["\n","^Governor: I'll fire you.","\n",["ev","str","^Oh.","/str","/ev",{"*":".^.c-0","flg":4},{"c-0":["\n","end",null]}],null],"c-1":["\n","end",null]}],null],"#f":1}],"EndLowFunds":[["^Governor: I've warned you.","\n","ev","str","^I understand. I resign. (Game Over)","/str","/ev",{"*":".^.c-0","flg":4},{"c-0":["^ ","ev",{"x()":"endGame"},"out","/ev","\n","end",null]}],null],"MeetFriendOfThePark":[["^#friendOfThePark#: Hi, I'm the president of the Friends of the Park. Nice to meet you!","\n","ev","str","^Nice to meet you!","/str","/ev",{"*":".^.c-0","flg":20},"ev","str","^Ahh.","/str","/ev",{"*":".^.c-1","flg":20},"ev","str","^I've been expecting you.","/str","/ev",{"*":".^.c-2","flg":20},{"c-0":["\n","ev","void","/ev","->->",{"#f":5}],"c-1":["\n","ev","void","/ev","->->",{"#f":5}],"c-2":["\n","^#friendOfThePark#: Huh!","\n","ev","void","/ev","->->",{"#f":5}]}],{"#f":1}],"Fundraiser":[["ev",{"CNT?":"MeetFriendOfThePark"},"!","_","/ev",[{"->":".^.b","c":true},{"b":["\n",{"->t->":"MeetFriendOfThePark"},{"->":".^.^.^.6"},null]}],"nop","\n","^#friendOfThePark#: I'm happy to announce the completion of our fundraiser! You won't guess how much we made!","\n","ev","str","^Please don't make me guess.","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Okay...","/str","/ev",{"*":".^.c-1","flg":4},{"c-0":["\n","^#friendOfThePark#: It's more fun if you guess.","\n",["ev","str","^ Fine.","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Well, I don't enjoy it.","/str","/ev",{"*":".^.c-1","flg":4},{"c-0":["\n",{"->":"Fundraiser.Guess"},null],"c-1":["\n",{"->":"Fundraiser.Amount"},null]}],null],"c-1":["\n",{"->":".^.^.^.Guess"},null]}],{"Guess":[["^#friendOfThePark#:","\n","ev","str","^$1,000?","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^$5,000?","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^$10,000?","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^$25,000?","/str","/ev",{"*":".^.c-3","flg":4},"ev","str","^$1 million?","/str","/ev",{"*":".^.c-4","flg":4},"ev","str","^$1 billion?","/str","/ev",{"*":".^.c-5","flg":4},"ev","str","^I give up.","/str","/ev",{"*":".^.c-6","flg":4},{"c-0":["\n","^#friendOfThePark#: Higher","\n",{"->":".^.^.^"},null],"c-1":["\n","^#friendOfThePark#: Higher","\n",{"->":".^.^.^"},null],"c-2":["\n","^#friendOfThePark#: You're right!","\n",{"->":".^.^.^.^.Amount"},null],"c-3":["\n","^#friendOfThePark#: Higher","\n",{"->":".^.^.^"},null],"c-4":["\n","^#friendOfThePark#: No, haha. I wish!","\n",{"->":".^.^.^"},null],"c-5":["\n","^#friendOfThePark#: Not quite that high, heh","\n",{"->":".^.^.^"},null],"c-6":["\n",{"->":".^.^.^.^.Amount"},null]}],null],"Amount":["^#friendOfThePark#: Anyway. we made $10,000!","\n","end",null]}],"GovernmentGrant":[["^Governor: Good news, director. You've been awarded a federal grant.","\n","ev","str","^Awesome","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Sounds good","/str","/ev",{"*":".^.c-1","flg":4},{"c-0":["\n",{"->":".^.^.^.Money"},null],"c-1":["\n",{"->":".^.^.^.Money"},null]}],{"Money":["^Governor: Well, it won't last forever. Don't get dependent on it.","\n","end",null]}],"MeetHeadofPark":["^Head of Parks: I'm the fucking head of parks, that's who I am, you absolute motherfucker. ","ev","void","/ev","->->","\n",{"#f":1}],"PoorTreeHealth":[["^Head of Parks: What the hell do you think you're doing, you absolute piece of shit?!?","\n",["ev",{"^->":"PoorTreeHealth.0.2.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str",{"CNT?":"MeetHeadofPark"},"!","_","/ev",{"*":".^.^.c-0","flg":19},{"s":["^Sorry, who are you? ",{"->":"$r","var":true},null]}],"ev","str","^Uhh, what the fuck?","/str","/ev",{"*":".^.c-1","flg":4},{"c-0":["ev",{"^->":"PoorTreeHealth.0.c-0.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.2.s"},[{"#n":"$r2"}],{"->t->":"MeetHeadofPark"},"\n",{"->":".^.^.^.Screwed"},{"#f":5}],"c-1":["\n",{"->":".^.^.^.Screwed"},null]}],{"Screwed":[["^Head of Parks: We're all fucking screwed and it's your fault, you colossal shitheel.","\n","ev","str","^...","/str","/ev",{"*":".^.c-0","flg":4},{"c-0":["\n","^Head of Parks: Look at this park, it has anxiety! You did that you megadick.","\n",["ev","str","^...","/str","/ev",{"*":".^.c-0","flg":4},{"c-0":["\n","^Head of Parks: Yeah, you'd better stay quiet. I don't want to hear a single word out of your fucking useless knifewound of a mouth.","\n","end",null]}],null]}],null]}],"global decl":["ev",0,{"VAR=":"playerSwears"},0,{"VAR=":"playerRude"},0,{"VAR=":"GovernorOpinion"},{"list":{},"origins":["assistantTraits"]},{"VAR=":"assistantTraits"},"/ev","end",null]}],"listDefs":{"assistantTraits":{"shy":1,"esoteric":2,"sweary":3}}} No newline at end of file
1 {"inkVersion":20,"root":[[["done",{"#n":"g-0"}],null],"done",{"placeholder":["end",null],"alter":[{"temp=":"k"},{"temp=":"x"},"ev",{"VAR?":"x"},{"VAR?":"k"},"+","/ev",{"temp=":"x","re":true},null],"inc":[{"temp=":"x"},"ev",{"VAR?":"x"},1,"+","/ev",{"temp=":"x","re":true},null],"dec":[{"temp=":"x"},"ev",{"VAR?":"x"},1,"-","/ev",{"temp=":"x","re":true},null],"endGame":["ev","void","/ev","~ret",null],"Once":[["^Once upon a time...","\n",["ev",{"^->":"Once.0.2.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.^.c-0","flg":2},{"s":["^There were two choices.",{"->":"$r","var":true},null]}],["ev",{"^->":"Once.0.3.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.^.c-1","flg":2},{"s":["^There were four lines of content.",{"->":"$r","var":true},null]}],{"c-0":["ev",{"^->":"Once.0.c-0.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.2.s"},[{"#n":"$r2"}],"\n",{"->":".^.^.g-0"},null],"c-1":["ev",{"^->":"Once.0.c-1.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.3.s"},[{"#n":"$r2"}],"\n",{"->":".^.^.g-0"},null],"g-0":["^They lived happily ever after.","\n","end",null]}],null],"IntroGovernor":[["^Governor: Welcome to your new park, director!","\n","ev","str","^Okay","/str","/ev",{"*":".^.c-0","flg":20},{"c-0":["\n","^Governor: 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!","\n",["ev","str","^And I need to keep the forest healthy, too, right?","/str","/ev",{"*":".^.c-0","flg":20},"ev","str","^Sounds good!","/str","/ev",{"*":".^.c-1","flg":20},{"c-0":["^ ","\n","ev",{"VAR?":"GovernorOpinion"},1,"-","/ev",{"VAR=":"GovernorOpinion","re":true},"^Governor: Ummm, yeah","\n",["ev","str","^...","/str","/ev",{"*":".^.c-0","flg":20},{"c-0":["\n","end",{"#f":5}]}],{"#f":5}],"c-1":["\n","ev",{"VAR?":"GovernorOpinion"},1,"+","/ev",{"VAR=":"GovernorOpinion","re":true},"^Governor: I'll check in soon.","\n","end",{"#f":5}]}],{"#f":5}]}],null],"IntroAssistant":[["^#assistantName#: Hello. I'm #assistantName#.","\n","ev","str","^Nice to meet you.","/str","/ev",{"*":".^.c-0","flg":20},{"c-0":["\n","^#assistantName#: You can use the mouse or arrow keys to move around, and the plus and minus keys to zoom in and out. B opens the budget and F lets you adjust Forest Policy.","\n",["ev","str","^Got it, thanks.","/str","/ev",{"*":".^.c-0","flg":20},"ev","str","^How are you?","/str","/ev",{"*":".^.c-1","flg":20},{"c-0":["\n","^#assistantName#: Bye","\n","end",{"#f":5}],"c-1":["\n","^#assistantName#: #howdoing#","\n","end",{"#f":5}]}],{"#f":5}]}],null],"BadNewsReact":[["ev","str","^Damn.","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Fuck.","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Shoot.","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^*Sigh.* Fine.","/str","/ev",{"*":".^.c-3","flg":4},"ev","str","^Who cares?","/str","/ev",{"*":".^.c-4","flg":4},{"c-0":["^ ","ev",{"^var":"playerSwears","ci":-1},{"f()":"inc"},"out","/ev","\n","ev","void","/ev","->->",null],"c-1":["^ ","ev",{"^var":"playerSwears","ci":-1},{"f()":"inc"},"out","/ev","\n","ev","void","/ev","->->",null],"c-2":["^ ","ev",{"^var":"playerSwears","ci":-1},{"f()":"inc"},"out","/ev","\n","ev","void","/ev","->->",null],"c-3":["\n","ev","void","/ev","->->",null],"c-4":["\n","ev","void","/ev","->->",null]}],null],"AssistantAcknowlege":[["ev","str","^Thanks.","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Mmmm hmm.","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Get to it.","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^I really appreciate it, #assistantName#","/str","/ev",{"*":".^.c-3","flg":4},{"c-0":["\n","ev","void","/ev","->->",null],"c-1":["\n","ev","void","/ev","->->",null],"c-2":["^ ","ev",{"^var":"playerRude","ci":-1},{"f()":"inc"},"out","/ev","\n","ev","void","/ev","->->",null],"c-3":["\n",{"->":".^.^.^.Appreciate"},null]}],{"Appreciate":["^#assistantName#: ","ev",{"VAR?":"assistantTraits"},{"VAR?":"shy"},"?","/ev",[{"->":".^.b","c":true},{"b":["^...",{"->":".^.^.^.8"},null]}],[{"->":".^.b"},{"b":[["ev","visit",3,"seq","/ev","ev","du",0,"==","/ev",{"->":".^.s0","c":true},"ev","du",1,"==","/ev",{"->":".^.s1","c":true},"ev","du",2,"==","/ev",{"->":".^.s2","c":true},"nop",{"s0":["pop","^No problem.",{"->":".^.^.23"},null],"s1":["pop","^Oh, you're welcome.",{"->":".^.^.23"},null],"s2":["pop","^My pleasure.",{"->":".^.^.23"},null],"#f":5}],{"->":".^.^.^.8"},null]}],"nop","\n","ev","void","/ev","->->",null]}],"MassVandalism":[["^#assistantName#: Bad news, director.","\n","ev","str","^Oh?","/str","/ev",{"*":".^.c-0","flg":4},{"c-0":["\n","^#assistantName#: A number of trees have been seriously damaged overnight.","\n",["ev","str","^How bad are they?","/str","/ev",{"*":".^.c-0","flg":4},{"c-0":["\n","^#assistantName#: I'm no botanist, but they're not great. The gouges are pretty deep.","\n",{"->t->":"BadNewsReact"},"^#assistantName#: Yeah, it's ","ev",{"VAR?":"assistantTraits"},{"VAR?":"sweary"},"?","/ev",[{"->":".^.b","c":true},{"b":["^fucking",{"->":".^.^.^.11"},null]}],"nop","^ awful.","\n","^I'll see who's around and get to cleaning.","\n",{"->t->":"AssistantAcknowlege"},"end",null]}],null]}],null],"LowFunds":[["^#assistantName#: Director, our funds are getting dangerously low!","\n","ev","str","^Don't worry about it. I have a plan.","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^I know.","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Stop bothering me with things I already know!","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^Have any ideas?","/str","/ev",{"*":".^.c-3","flg":4},"ev","str","^What?","/str","/ev",{"*":".^.c-4","flg":4},{"c-0":["\n","end",null],"c-1":["\n","end",null],"c-2":["^ ","ev",{"^var":"playerRude","ci":-1},{"f()":"inc"},"out","/ev","\n","end",null],"c-3":["\n","^#assistantName#: Consider accepting some contracts. Even if they're not the best terms, they'll keep us from running out of money.","\n","end",null],"c-4":["\n","^#assistantName#: Yes, we have less than $25,000. We're running the risk of a default.","\n",{"->t->":"BadNewsReact"},"^#assistantName#: I know! consider accepting some contracts. Even if they're not the best terms, they'll keep us from running out of money.","\n","end",null]}],null],"VeryLowFunds":[["^Governor: Director, you have almost no reserve funds. This isn't acceptable.","\n","ev",{"CNT?":".^.^"},1,">","/ev",[{"->":".^.b","c":true},{"b":["^ I can't believe I'm having this conversation with you again. ",{"->":".^.^.^.8"},null]}],"nop","\n","ev","str","^I know. I'm working on it.","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Have any ideas?","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^What happens if I run out of money?","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^What?","/str","/ev",{"*":".^.c-3","flg":4},{"c-0":["\n","^Governor: For your sake, I hope so.","\n","end",null],"c-1":["\n","^Governor: Accept some contracts. Now's not the time to worry about sustainability, or whatever you natural resources types care about. Just take the deal. They'll keep you from running out of money.","\n","end",null],"c-2":["\n",{"->":".^.^.^.WhatHappens"},null],"c-3":["\n",{"->":".^.^.^.Surprise"},null]}],{"Surprise":[["^Governor: Is this a *surprise* to you?","\n","ev","str","^Uh, um, no.","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Honestly, yes.","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^What happens if I run out of money?","/str","/ev",{"*":".^.c-2","flg":4},{"c-0":["\n","^Governor: Well, I hope you have a plan...","\n","^For your sake.","\n","end",null],"c-1":["\n","^Governor: Well! I appreciate your directness. But I hope you have a plan...","\n","^For your sake.","\n","end",null],"c-2":["\n",{"->":".^.^.^.^.WhatHappens"},null]}],null],"WhatHappens":[["^Governor: If you run out of money entirely...","\n","^The park will be fine, in the long run. The state department of natural resources will use its funds to bail the park out. Someone from my office will come in and trim the budget.","\n","^You, however, will be asked to resign.","\n","ev","str","^And if I don't resign?","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^I understand.","/str","/ev",{"*":".^.c-1","flg":4},{"c-0":["\n","^Governor: I'll fire you.","\n",["ev","str","^Oh.","/str","/ev",{"*":".^.c-0","flg":4},{"c-0":["\n","end",null]}],null],"c-1":["\n","end",null]}],null],"#f":1}],"EndLowFunds":[["^Governor: I've warned you.","\n","ev","str","^I understand. I resign. (Game Over)","/str","/ev",{"*":".^.c-0","flg":4},{"c-0":["^ ","ev",{"x()":"endGame"},"out","/ev","\n","end",null]}],null],"MeetFriendOfThePark":[["^#friendOfThePark#: Hi, I'm the president of the Friends of the Park. Nice to meet you!","\n","ev","str","^Nice to meet you!","/str","/ev",{"*":".^.c-0","flg":20},"ev","str","^Ahh.","/str","/ev",{"*":".^.c-1","flg":20},"ev","str","^I've been expecting you.","/str","/ev",{"*":".^.c-2","flg":20},{"c-0":["\n","ev","void","/ev","->->",{"#f":5}],"c-1":["\n","ev","void","/ev","->->",{"#f":5}],"c-2":["\n","^#friendOfThePark#: Huh!","\n","ev","void","/ev","->->",{"#f":5}]}],{"#f":1}],"Fundraiser":[["ev",{"CNT?":"MeetFriendOfThePark"},"!","_","/ev",[{"->":".^.b","c":true},{"b":["\n",{"->t->":"MeetFriendOfThePark"},{"->":".^.^.^.6"},null]}],"nop","\n","^#friendOfThePark#: I'm happy to announce the completion of our fundraiser! You won't guess how much we made!","\n","ev","str","^Please don't make me guess.","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Okay...","/str","/ev",{"*":".^.c-1","flg":4},{"c-0":["\n","^#friendOfThePark#: It's more fun if you guess.","\n",["ev","str","^ Fine.","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Well, I don't enjoy it.","/str","/ev",{"*":".^.c-1","flg":4},{"c-0":["\n",{"->":"Fundraiser.Guess"},null],"c-1":["\n",{"->":"Fundraiser.Amount"},null]}],null],"c-1":["\n",{"->":".^.^.^.Guess"},null]}],{"Guess":[["^#friendOfThePark#:","\n","ev","str","^$1,000?","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^$5,000?","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^$10,000?","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^$25,000?","/str","/ev",{"*":".^.c-3","flg":4},"ev","str","^$1 million?","/str","/ev",{"*":".^.c-4","flg":4},"ev","str","^$1 billion?","/str","/ev",{"*":".^.c-5","flg":4},"ev","str","^I give up.","/str","/ev",{"*":".^.c-6","flg":4},{"c-0":["\n","^#friendOfThePark#: Higher","\n",{"->":".^.^.^"},null],"c-1":["\n","^#friendOfThePark#: Higher","\n",{"->":".^.^.^"},null],"c-2":["\n","^#friendOfThePark#: You're right!","\n",{"->":".^.^.^.^.Amount"},null],"c-3":["\n","^#friendOfThePark#: Higher","\n",{"->":".^.^.^"},null],"c-4":["\n","^#friendOfThePark#: No, haha. I wish!","\n",{"->":".^.^.^"},null],"c-5":["\n","^#friendOfThePark#: Not quite that high, heh","\n",{"->":".^.^.^"},null],"c-6":["\n",{"->":".^.^.^.^.Amount"},null]}],null],"Amount":["^#friendOfThePark#: Anyway. we made $10,000!","\n","end",null]}],"GovernmentGrant":[["^Governor: Good news, director. You've been awarded a federal grant.","\n","ev","str","^Awesome","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Sounds good","/str","/ev",{"*":".^.c-1","flg":4},{"c-0":["\n",{"->":".^.^.^.Money"},null],"c-1":["\n",{"->":".^.^.^.Money"},null]}],{"Money":["^Governor: Well, it won't last forever. Don't get dependent on it.","\n","end",null]}],"MeetHeadofPark":["^Head of Parks: I'm the fucking head of parks, that's who I am, you absolute motherfucker. ","ev","void","/ev","->->","\n",{"#f":1}],"PoorTreeHealth":[["^Head of Parks: What the hell do you think you're doing, you absolute piece of shit?!?","\n","ev","str","^Sorry, who are you?","/str",{"CNT?":"MeetHeadofPark"},"!","_","/ev",{"*":".^.c-0","flg":21},"ev","str","^Uhh, what the fuck?","/str","/ev",{"*":".^.c-1","flg":4},{"c-0":["^ ",{"->t->":"MeetHeadofPark"},"\n",{"->":".^.^.^.Screwed"},{"#f":5}],"c-1":["\n",{"->":".^.^.^.Screwed"},null]}],{"Screwed":[["^Head of Parks: We're all fucking screwed and it's your fault, you colossal shitheel.","\n","ev","str","^...","/str","/ev",{"*":".^.c-0","flg":4},{"c-0":["\n","^Head of Parks: Look at this park, it has anxiety! You did that you megadick.","\n",["ev","str","^...","/str","/ev",{"*":".^.c-0","flg":4},{"c-0":["\n","^Head of Parks: Yeah, you'd better stay quiet. I don't want to hear a single word out of your fucking useless knifewound of a mouth.","\n","end",null]}],null]}],null]}],"PreserveProgress":[["^Head of Parks: Hey, you goddam dunderhead. A quarter of this park is now a preserve! ","ev",{"^var":"HeadOfParksOpinion","ci":-1},{"f()":"inc"},"out","/ev","\n","ev","str","^Sorry, who are you?","/str",{"CNT?":"MeetHeadofPark"},"!","_","/ev",{"*":".^.c-0","flg":21},"ev","str","^And you're mad?","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Right!","/str","/ev",{"*":".^.c-2","flg":4},{"c-0":["^ ",{"->":"MeetHeadofPark"},"\n",{"->":".^.^.^.WhatPreserves"},{"#f":5}],"c-1":["\n","^Head of Parks: No, you vainglorious buffoon! I'm pretty goddamn pleased. ",{"->":".^.^.^.WhatPreserves"},"\n",null],"c-2":["\n",{"->":".^.^.^.WhatPreserves"},null]}],{"WhatPreserves":[["^Head of Parks: I goddamn love preserves. The peach kind. The strawberry kind. But especially the park kind. The trees are left alone. They fucking flourish! Do you think you could fucking photosynthese with people traipsing all over?","\n","ev","str","^No?","/str","/ev",{"*":".^.c-0","flg":4},{"c-0":["\n","^Head of Parks: You're goddamn right! You couldn't! Do you know how many preserves have been added since our cuntforsaken governor took office in 2014???","\n",["ev","str","^Uh one?","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^None?","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^HellifIknow","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^One dozen","/str","/ev",{"*":".^.c-3","flg":4},"ev","str","^One Hundred","/str","/ev",{"*":".^.c-4","flg":4},"ev","str","^One billion","/str","/ev",{"*":".^.c-5","flg":4},{"c-0":["\n","^Head of Parks: Not even one! ",{"->":".^.^.^.^.^.^.Zero"},"\n",null],"c-1":["\n","^Head of Parks: Bingo, my motherfucker ",{"->":".^.^.^.^.^.^.Zero"},"\n",null],"c-2":["^ ","ev",{"^var":"playerSwears","ci":-1},{"f()":"inc"},"out","/ev","\n","^Head of Parks: Least your honest. ",{"->":".^.^.^.^.^.^.Zero"},"\n",null],"c-3":["\n","^Head of Parks: What? Not even close. ",{"->":".^.^.^.^.^.^.Zero"},"\n",null],"c-4":["\n","^Head of Parks: What? Not even close. ",{"->":".^.^.^.^.^.^.Zero"},"\n",null],"c-5":["\n","^Head of Parks: Fuck off. ","ev",{"^var":"HeadOfParksOpinion","ci":-1},{"f()":"dec"},"out","/ev","^ ",{"->":"HeadofParkSideRant"},"\n","^Anyway, it's not a billion!! ",{"->":".^.^.^.^.^.^.Zero"},"\n",null]}],null]}],null],"Zero":["^Head of Parks: It's zero! Zero new preserves on God's green earth. Or brown earth. I swear to god...","\n","end",null]}],"PreserveHalf":[["^Head of Parks: Hey, you goddam wunderkind. A whole half of this park is now a preserve! ","ev",{"^var":"HeadOfParksOpinion","ci":-1},{"f()":"inc"},"out","/ev","\n","^In fact, I want to shake your bloody hand!","\n","ev","str","^Sure!","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Umm..okay","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^No thanks","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^No, you have germs","/str","/ev",{"*":".^.c-3","flg":4},{"c-0":["^ ","ev",{"^var":"HeadOfParksOpinion","ci":-1},{"f()":"inc"},"out","/ev","\n",{"->":".^.^.^.PostShake"},null],"c-1":["\n",{"->":".^.^.^.PostShake"},null],"c-2":["\n",{"->":".^.^.^.PostShake"},null],"c-3":["^ ","ev",{"^var":"HeadOfParksOpinion","ci":-1},{"f()":"dec"},"out","/ev","\n","^Head of Parks: Bloody hell, I wash! ",{"->":".^.^.^.PostShake"},"\n",null]}],{"PostShake":[["^Head of Parks: Anywyay, you're doing great. If that bloody governor gives you any shit, send him my way. And I think I can scrounge up some money to help you keep the park running.","\n","ev","str","^Thanks","/str","/ev",{"*":".^.c-0","flg":4},{"c-0":["\n","end",null]}],null]}],"HeadofParkSideRant":[["^Head of Parks: Are you fucking with me? Really fucking with me? Listen, you motherfucking piss-eared shit-for-brains backroad bureaucrat, I didn't come hear from the fucking capitol building holding up the whole natural resources administrative state like MiracleGrow Atlas to get scoffed at by a tinpot administrator who think 100 acres and a desk makes you some sort of important person. Aplogize!","\n","ev","str","^Sorry","/str","/ev",{"*":".^.c-0","flg":4},{"c-0":["^ ","ev","void","/ev","->->","\n",null]}],null],"LargePreserve":[["^#assistantName#: I noticed you reserved quite a bit of space for a nature preserve. Remember that these are unavailable for leisure use or development.","\n","ev","str","^Isn't it great!","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Thanks for checking in.","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^I know what I'm doing!","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^Maybe I've overreached. (Undoes Preserve)","/str","/ev",{"*":".^.c-3","flg":4},{"c-0":["\n","^#assistantName#: Ummm. Yeah! It is.","\n","end",null],"c-1":["\n","end",null],"c-2":["^ ","ev",{"^var":"playerRude","ci":-1},{"f()":"inc"},"out","/ev","\n","end",null],"c-3":["^ ","ev",{"x()":"undoPreserve"},"out","/ev","\n","end",null]}],null],"global decl":["ev",0,{"VAR=":"playerSwears"},0,{"VAR=":"playerRude"},0,{"VAR=":"GovernorOpinion"},0,{"VAR=":"HeadOfParksOpinion"},{"list":{},"origins":["assistantTraits"]},{"VAR=":"assistantTraits"},"/ev","end",null]}],"listDefs":{"assistantTraits":{"shy":1,"esoteric":2,"sweary":3}}} No newline at end of file
@@ -6,6 +6,6
6 ~ assistantTraits = (shy, sweary)
6 ~ assistantTraits = (shy, sweary)
7
7
8
8
9 -> EndLowFunds
9 -> PreserveHalf
10
10
11 -> END No newline at end of file
11 -> END
@@ -103,7 +103,7
103 object1: "#object#"
103 object1: "#object#"
104 object2: "#object#"
104 object2: "#object#"
105 object3: "#object#"
105 object3: "#object#"
106 - hed: "How the people of #subject_area.capitalize# are fighting #subject_problem.capitalize#"
106 - hed: "How the people of #subject_area.capitalize# are fighting #subject_problem#"
107 contents: "#femaleCodedName# #surname#, an #occupation#, stares out at the wilderness of #subject_area#.
107 contents: "#femaleCodedName# #surname#, an #occupation#, stares out at the wilderness of #subject_area#.
108
108
109 Like many places, it has not been spared by #subject_problem#."
109 Like many places, it has not been spared by #subject_problem#."
@@ -132,9 +132,27
132 - hed: "Are Comets Real?"
132 - hed: "Are Comets Real?"
133 contents: ""
133 contents: ""
134 source: "True"
134 source: "True"
135 - hed: "Scientists Attached an Ear to the Back of a Mouse?? What the Hell???"
136 contents: ""
137 source: "True"
138 - hed: "EDITOR'S NOTE: Mole People are Just Like Us"
139 contents: "Many independent journalists report breathlessly on moleperson sightings. Take The Weekly Wolrd News. Despite uncovering such important stories as the Batboy and raising merfolk awareness, they also have perpetuated stigma against the moleperson community.
140
141 This is wrong. And for the 129 stories, anonymous poem and three unsigned letters, sensationalizing the molepeople I filled while an intern, I apologize.
142
143 In fact one of my best friends is a mole person. #moleperson_first_name# #moleperson_surname# was born underground to a loving mole family, who even took me in when my dad worked nights at the #object# factory.
144
145 While there are definite cultural differences between my normal, All-American family and his abnormal, All-Mole family, like their affinity for dirt and snouts instead of noses, we're all just people. Kumbyah, right?"
146 source: "True"
147 variables:
148 moleperson_first_name: "#maleCodedName#"
149 moleperson_surname: "#surname#"
150 - hed: "MYSTERY: Can Guys and Girls Just Be Friends?"
151 contents: ""
152 source: "True"
135 - hed: "Protester Struck After Bullet Emerges From Gun Held by Police Officer"
153 - hed: "Protester Struck After Bullet Emerges From Gun Held by Police Officer"
136 contents: "Local #protestor_first_name# #protestor_surname# was protesting when they were struck by a bullet
154 contents: "Local #protestor_first_name# #protestor_surname# was protesting when they were struck by a bullet
137 that came from a gun held by a police officer. They died later at #town# Memorial Hospital.
155 that emerged from a gun held by a police officer. They died later at #town# Memorial Hospital.
138
156
139 #protestor_surname#'s family insists the police take responsibility.
157 #protestor_surname#'s family insists the police take responsibility.
140
158
@@ -104,9 +104,6
104 AddComponent(fundraiserEntity, new EventComponent { EndEventDate = simulationDate.AddMonths(12) });
104 AddComponent(fundraiserEntity, new EventComponent { EndEventDate = simulationDate.AddMonths(12) });
105 SendMessage(new SpawnDialogMessage { Path = "GovernmentGrant" });
105 SendMessage(new SpawnDialogMessage { Path = "GovernmentGrant" });
106 }
106 }
107
108
109
110 }
107 }
111 #endregion
108 #endregion
112
109
@@ -1,4 +1,5
1
1
2 using System.Collections.Generic;
2 using System.IO;
3 using System.IO;
3
4
4 using Microsoft.Xna.Framework.Input;
5 using Microsoft.Xna.Framework.Input;
@@ -19,22 +20,38
19 typeof(SetFontMessage),
20 typeof(SetFontMessage),
20 typeof(QuitGameMessage))]
21 typeof(QuitGameMessage))]
21 [Reads(typeof(AreaComponent),
22 [Reads(typeof(AreaComponent),
22 typeof(ContractStatusComponent),
23 typeof(PointComponent),
23 typeof(OptionsComponent))]
24 typeof(ContractStatusComponent),
25 typeof(OptionsComponent),
26 typeof(PreserveComponent))]
27 [Sends(typeof(UndoPreserveMessage))]
24 class GameBridgeEngine : Engine
28 class GameBridgeEngine : Engine
25 {
29 {
26
30
27 public FNAGame game;
31 public FNAGame game;
28
32
33 public List<UndoPreserveMessage> undoPreserveMessages;
34
29 public GameBridgeEngine(FNAGame game)
35 public GameBridgeEngine(FNAGame game)
30 {
36 {
31 this.game = game;
37 this.game = game;
38
39 this.undoPreserveMessages = new List<UndoPreserveMessage>();
32 }
40 }
33
41
34 public override void Update(double dt)
42 public override void Update(double dt)
35 {
43 {
36
44
37 ProfanityLevel profanity_setting = default;
45 ProfanityLevel profanity_setting = default;
46 float sound_effect_volume = 1.0f; //full volume
47 bool sound_effect_muted = false;
48
49 foreach (var message in undoPreserveMessages)
50 {
51 SendMessage<UndoPreserveMessage>(message);
52 }
53
54 this.undoPreserveMessages.Clear();
38
55
39 foreach (ref readonly var windowMessage in ReadMessages<ToggleWindowTypeMessage>())
56 foreach (ref readonly var windowMessage in ReadMessages<ToggleWindowTypeMessage>())
40 {
57 {
@@ -77,40 +94,67
77 var component = GetComponent<OptionsComponent>(entity);
94 var component = GetComponent<OptionsComponent>(entity);
78
95
79 profanity_setting = component.ProfanitySetting;
96 profanity_setting = component.ProfanitySetting;
97 sound_effect_volume = component.SoundEffectVolume;
98 sound_effect_muted = component.SoundEffectMuted;
80 }
99 }
100
81 foreach (ref readonly var fontMessage in ReadMessages<SetFontMessage>())
101 foreach (ref readonly var fontMessage in ReadMessages<SetFontMessage>())
82 {
102 {
83 game.setFont(fontMessage.fontName, fontMessage.fontSize);
103 game.setFont(fontMessage.fontName, fontMessage.fontSize);
84 Options.writeOptions(fontMessage.fontName, fontMessage.fontSize,
104 Options.writeOptions(fontMessage.fontName, fontMessage.fontSize,
85 profanity_setting);
105 profanity_setting, sound_effect_volume, sound_effect_muted);
106 }
86
107
87 }
88
108
89 game.in_zone = false;
109 game.in_zone = false;
90 game.in_active_zone = false;
110 game.in_active_zone = false;
111 game.in_preserve = false;
112 game.has_tower = false;
91 foreach (ref readonly var entity in ReadEntities<AreaComponent>())
113 foreach (ref readonly var entity in ReadEntities<AreaComponent>())
92 {
114 {
93 var areaComponent = GetComponent<AreaComponent>(entity);
115 var areaComponent = GetComponent<AreaComponent>(entity);
94 var contractStatusComponent = GetComponent<ContractStatusComponent>(entity);
116
95 foreach (var square in areaComponent.squares)
117 if (HasComponent<ContractStatusComponent>(entity))
96 {
118 {
97 if (game.mouseGrid == square)
119 var contractStatusComponent = GetComponent<ContractStatusComponent>(entity);
120 foreach (var square in areaComponent.squares)
98 {
121 {
99 game.in_zone = true;
122 if (game.mouseGrid == square)
100 if ((contractStatusComponent.status == ContractStatus.Active)
101 || (contractStatusComponent.status == ContractStatus.Accepted))
102 {
123 {
103 game.in_active_zone = true;
124 game.in_zone = true;
125 if ((contractStatusComponent.status == ContractStatus.Active)
126 || (contractStatusComponent.status == ContractStatus.Accepted))
127 {
128 game.in_active_zone = true;
129 }
104 }
130 }
105 }
131 }
106 }
132 }
133 else if (HasComponent<PreserveComponent>(entity)) {
134 foreach (var square in areaComponent.squares) {
135 if (game.mouseGrid == square)
136 {
137
138 game.in_preserve = true;
139 }
140
141 }
142 }
143 }
144 foreach (ref readonly var entity in ReadEntities<PointComponent>())
145 {
146 var point_component = GetComponent<PointComponent>(entity);
147
148 if (game.mouseGrid == point_component.Square)
149 {
150 game.has_tower = true;
151 }
107 }
152 }
108
153
109 foreach (ref readonly var message in ReadMessages<QuitGameMessage>())
154 foreach (ref readonly var message in ReadMessages<QuitGameMessage>())
110 {
155 {
111 this.game.quit = true;
156 this.game.quit = true;
112 }
157 }
113
114 }
158 }
115 }
159 }
116 }
160 }
@@ -26,7 +26,7
26 foreach (var entity in ReadEntities<GameStateComponent>())
26 foreach (var entity in ReadEntities<GameStateComponent>())
27 {
27 {
28 var state = GetComponent<GameStateComponent>(entity).isPlaying;
28 var state = GetComponent<GameStateComponent>(entity).isPlaying;
29 Logging.Spy(state, "state");
29 Logging.Debug("Changing state: " + state.ToString());
30
30
31 SetComponent(entity, new GameStateComponent { isPlaying = message.isPlaying });
31 SetComponent(entity, new GameStateComponent { isPlaying = message.isPlaying });
32 }
32 }
@@ -27,14 +27,19
27 typeof(SetDialogMessage),
27 typeof(SetDialogMessage),
28 typeof(DialogChoiceMessage),
28 typeof(DialogChoiceMessage),
29 typeof(SetOptionMessage),
29 typeof(SetOptionMessage),
30 typeof(QuitGameMessage))]
30 typeof(QuitGameMessage),
31 typeof(ToggleToolMessage),
32 typeof(PlaySoundMessage),
33 typeof(DebugAlterTreesMessage))]
31 [Reads(typeof(VisibilityComponent),
34 [Reads(typeof(VisibilityComponent),
32 typeof(WindowTypeComponent),
35 typeof(WindowTypeComponent),
33 typeof(TrespassingPolicyComponent),
36 typeof(TrespassingPolicyComponent),
34 typeof(ContractStatusComponent),
37 typeof(ContractStatusComponent),
35 typeof(RelatedOrganizationComponent),
38 typeof(RelatedOrganizationComponent),
36 typeof(NameAndDescriptionComponent),
39 typeof(NameAndDescriptionComponent),
37 typeof(OptionsComponent))]
40 typeof(OptionsComponent),
41 typeof(ToolComponent),
42 typeof(SelectedComponent))]
38 [Writes(typeof(OptionsComponent))]
43 [Writes(typeof(OptionsComponent))]
39 public class ImGuiWindowBridgeEngine : Engine
44 public class ImGuiWindowBridgeEngine : Engine
40 {
45 {
@@ -54,6 +59,9
54 public List<SetOptionMessage> setOptionMessages;
59 public List<SetOptionMessage> setOptionMessages;
55 public List<GameRateMessage> gameRateMessages;
60 public List<GameRateMessage> gameRateMessages;
56 public List<QuitGameMessage> quitGameMessages;
61 public List<QuitGameMessage> quitGameMessages;
62 public List<ToggleToolMessage> toggleToolMessages;
63 public List<PlaySoundMessage> playSoundMessages;
64 public List<DebugAlterTreesMessage> debugAlterTreesMessages;
57
65
58 bool showBudget { get; }
66 bool showBudget { get; }
59 bool showForest { get; }
67 bool showForest { get; }
@@ -62,6 +70,7
62 bool showTrees { get; }
70 bool showTrees { get; }
63
71
64 public Dictionary<Window, bool> windowStatuses { get; }
72 public Dictionary<Window, bool> windowStatuses { get; }
73 public Dictionary<Tool, bool> toolStatuses { get; }
65
74
66 public bool showContractIndicator;
75 public bool showContractIndicator;
67 public List<string> contracts;
76 public List<string> contracts;
@@ -103,8 +112,12
103 this.setOptionMessages = new List<SetOptionMessage>();
112 this.setOptionMessages = new List<SetOptionMessage>();
104 this.gameRateMessages = new List<GameRateMessage>();
113 this.gameRateMessages = new List<GameRateMessage>();
105 this.quitGameMessages = new List<QuitGameMessage>();
114 this.quitGameMessages = new List<QuitGameMessage>();
115 this.toggleToolMessages = new List<ToggleToolMessage>();
116 this.playSoundMessages = new List<PlaySoundMessage>();
117 this.debugAlterTreesMessages = new List<DebugAlterTreesMessage>();
106
118
107 this.windowStatuses = new Dictionary<Window, bool>();
119 this.windowStatuses = new Dictionary<Window, bool>();
120 this.toolStatuses = new Dictionary<Tool, bool>();
108
121
109 this.showContractIndicator = false;
122 this.showContractIndicator = false;
110 this.showBudgetLow = false;
123 this.showBudgetLow = false;
@@ -124,6 +137,11
124 {
137 {
125 windowStatuses.Add((Window)type, false);
138 windowStatuses.Add((Window)type, false);
126 }
139 }
140
141 foreach (var type in System.Enum.GetValues(typeof(Tool)))
142 {
143 toolStatuses.Add((Tool)type, false);
144 }
127 }
145 }
128
146
129 public override void Update(double dt)
147 public override void Update(double dt)
@@ -209,6 +227,11
209 SendMessage(message);
227 SendMessage(message);
210 }
228 }
211
229
230 foreach (var message in this.toggleToolMessages)
231 {
232 SendMessage(message);
233 }
234
212 foreach (var message in this.setOptionMessages)
235 foreach (var message in this.setOptionMessages)
213 {
236 {
214 foreach (var entity in ReadEntities<OptionsComponent>())
237 foreach (var entity in ReadEntities<OptionsComponent>())
@@ -216,12 +239,22
216
239
217 SetComponent(entity, new OptionsComponent
240 SetComponent(entity, new OptionsComponent
218 {
241 {
219 ProfanitySetting = message.NewProfanitySetting
242 ProfanitySetting = message.NewProfanitySetting,
243 SoundEffectVolume = message.NewSoundEffectVolume,
244 SoundEffectMuted = message.NewSoundEffectMuted
220 });
245 });
221 }
246 }
222
247
223 }
248 }
224
249
250 foreach (var message in this.playSoundMessages) {
251 SendMessage(message);
252 }
253
254 foreach (var message in this.debugAlterTreesMessages) {
255 SendMessage(message);
256 }
257
225 foreach (var entity in ReadEntities<WindowTypeComponent>())
258 foreach (var entity in ReadEntities<WindowTypeComponent>())
226 {
259 {
227 var type = GetComponent<WindowTypeComponent>(entity).type;
260 var type = GetComponent<WindowTypeComponent>(entity).type;
@@ -229,6 +262,12
229 windowStatuses[type] = visibility;
262 windowStatuses[type] = visibility;
230 }
263 }
231
264
265 foreach (var entity in ReadEntities<ToolComponent>()) {
266 var tool = GetComponent<ToolComponent>(entity).Tool;
267 var selected = HasComponent<SelectedComponent>(entity) ? GetComponent<SelectedComponent>(entity).selected : false;
268 toolStatuses[tool] = selected;
269 }
270
232 //reset
271 //reset
233 this.showContractIndicator = false;
272 this.showContractIndicator = false;
234 this.contracts.Clear();
273 this.contracts.Clear();
@@ -277,6 +316,9
277 this.gameRateMessages.Clear();
316 this.gameRateMessages.Clear();
278 this.setOptionMessages.Clear();
317 this.setOptionMessages.Clear();
279 this.quitGameMessages.Clear();
318 this.quitGameMessages.Clear();
319 this.toggleToolMessages.Clear();
320 this.playSoundMessages.Clear();
321 this.debugAlterTreesMessages.Clear();
280 }
322 }
281 }
323 }
282 }
324 }
@@ -1,9 +1,12
1
1
2 using System;
2 using System;
3 using Microsoft.Xna.Framework;
3 using Microsoft.Xna.Framework;
4 using Microsoft.Xna.Framework.Audio;
4 using Microsoft.Xna.Framework.Graphics;
5 using Microsoft.Xna.Framework.Graphics;
5 using Microsoft.Xna.Framework.Input;
6 using Microsoft.Xna.Framework.Input;
6
7
8 using ImGuiNET;
9
7 using Encompass;
10 using Encompass;
8
11
9 using isometricparkfna.Messages;
12 using isometricparkfna.Messages;
@@ -20,10 +23,15
20 typeof(TogglePauseMessage),
23 typeof(TogglePauseMessage),
21 typeof(GameRateMessage),
24 typeof(GameRateMessage),
22 typeof(GameStateMessage),
25 typeof(GameStateMessage),
23 typeof(QuitGameMessage))]
26 typeof(QuitGameMessage),
27 typeof(SpawnSelection),
28 typeof(AdjustSelection),
29 typeof(PlaySoundMessage))]
24 [Reads(typeof(WindowTypeComponent),
30 [Reads(typeof(WindowTypeComponent),
25 typeof(GameStateComponent),
31 typeof(GameStateComponent),
26 typeof(VisibilityComponent))]
32 typeof(VisibilityComponent),
33 typeof(CursorComponent))]
34 [Writes(typeof(CursorComponent))]
27 public class InputEngine : Engine
35 public class InputEngine : Engine
28 {
36 {
29 private KeyboardState keyboardPrev;
37 private KeyboardState keyboardPrev;
@@ -35,15 +43,31
35
43
36 //Area to ignore:
44 //Area to ignore:
37 private int menuBarHeight;
45 private int menuBarHeight;
46 private int height;
47 private int width;
38
48
39 public InputEngine(int menuBarHeight, Camera camera,
49 public InputEngine(int menuBarHeight, Camera camera,
40 GraphicsDeviceManager gdm) {
50 GraphicsDeviceManager gdm, int height, int width) {
41 //initialize to blank for now
51 //initialize to blank for now
42 this.keyboardPrev = new KeyboardState();
52 this.keyboardPrev = new KeyboardState();
43 this.menuBarHeight = menuBarHeight;
53 this.menuBarHeight = menuBarHeight;
44 this.camera = camera;
54 this.camera = camera;
45 this.gdm = gdm;
55 this.gdm = gdm;
46 this.graphicsDevice = gdm.GraphicsDevice;
56 this.graphicsDevice = gdm.GraphicsDevice;
57 this.height = height;
58 this.width = width;
59 }
60
61
62 Vector2 calculateMousegrid(Vector2 normalizedMousePos)
63 {
64 Vector2 adjust = new Vector2(Tile.TileSpriteWidth / 2, Tile.TileSpriteHeight);
65 Vector2 adjustedMousePos = normalizedMousePos - adjust;
66
67 float boardx = ((adjustedMousePos.X / Tile.TileSpriteWidth) + (adjustedMousePos.Y / Tile.TileSpriteHeight));
68 float boardy = ((adjustedMousePos.Y / Tile.TileSpriteHeight) - (adjustedMousePos.X / Tile.TileSpriteWidth));
69
70 return new Vector2((int)boardx, (int)boardy);
47 }
71 }
48
72
49 public override void Update(double dt) {
73 public override void Update(double dt) {
@@ -52,12 +76,13
52 var mouseCur = Mouse.GetState();
76 var mouseCur = Mouse.GetState();
53 var original_point = Vector2.Transform(new Vector2(mouseCur.X, mouseCur.Y),
77 var original_point = Vector2.Transform(new Vector2(mouseCur.X, mouseCur.Y),
54 Matrix.Invert(this.camera.get_transformation(this.graphicsDevice)));
78 Matrix.Invert(this.camera.get_transformation(this.graphicsDevice)));
55
56 bool isPlaying = false;
79 bool isPlaying = false;
57
80
58 var viewWidth = gdm.PreferredBackBufferWidth;
81 var viewWidth = gdm.PreferredBackBufferWidth;
59 var viewHeight = gdm.PreferredBackBufferHeight;
82 var viewHeight = gdm.PreferredBackBufferHeight;
60
83
84 ImGuiIOPtr io = ImGui.GetIO();
85
61 foreach (var entity in ReadEntities<GameStateComponent>())
86 foreach (var entity in ReadEntities<GameStateComponent>())
62 {
87 {
63 var state = GetComponent<GameStateComponent>(entity).isPlaying;
88 var state = GetComponent<GameStateComponent>(entity).isPlaying;
@@ -187,7 +212,15
187 {
212 {
188 SendMessage(new ToggleWindowTypeMessage {Window = Window.InGameMenu});
213 SendMessage(new ToggleWindowTypeMessage {Window = Window.InGameMenu});
189 SendMessage(new GameRateMessage { paused = true, rate = null });
214 SendMessage(new GameRateMessage { paused = true, rate = null });
215 //People will probably expect escape to clear, even though its primary purpose
216 //is to open the menu:
217 SendMessage(new AdjustSelection {Type = AdjustmentType.Clear });
190 }
218 }
219
220 //Back => Backspace
221 if (keyboardCur.IsKeyDown(Keys.Back) && keyboardPrev.IsKeyUp(Keys.Back)) {
222 SendMessage(new AdjustSelection {Type = AdjustmentType.Clear });
223 }
191 }
224 }
192
225
193 if (keyboardCur.IsKeyDown(Keys.OemBackslash) && keyboardPrev.IsKeyUp(Keys.OemBackslash))
226 if (keyboardCur.IsKeyDown(Keys.OemBackslash) && keyboardPrev.IsKeyUp(Keys.OemBackslash))
@@ -233,10 +266,52
233 #endregion
266 #endregion
234 #region mouse_click
267 #region mouse_click
235
268
236 if (mouseCur.RightButton == ButtonState.Pressed && mousePrev.RightButton == ButtonState.Released)
269 if (isPlaying && !io.WantCaptureMouse) {
270 if (mouseCur.RightButton == ButtonState.Pressed && mousePrev.RightButton == ButtonState.Released)
271 {
272 SendMessage(new PlaySoundMessage { SoundName = "Click" });
273 SendMessage(new JumpCameraMessage {Movement = original_point});
274 }
275
276 if (mouseCur.LeftButton == ButtonState.Pressed && mousePrev.LeftButton == ButtonState.Released
277 // && keyboardCur.IsKeyDown(Keys.LeftShift)
278 )
279 {
280 SendMessage(new SpawnSelection {Start = CellMap.calculateMousegrid(original_point)});
281 }
282
283 if ( mouseCur.LeftButton == ButtonState.Released && mousePrev.LeftButton == ButtonState.Pressed)
284 {
285 SendMessage(new AdjustSelection {Type = AdjustmentType.Complete });
286 // SendMessage(new
287 }
288
289 if (mouseCur.LeftButton == ButtonState.Pressed && mousePrev.LeftButton == ButtonState.Pressed)
290 {
291 SendMessage(new AdjustSelection {End = CellMap.calculateMousegrid(original_point)});
292 }
293
294 var transformedPosition = Vector2.Transform(new Vector2(mouseCur.X, mouseCur.Y), Matrix.Invert(camera.get_transformation(this.graphicsDevice)));
295 var gridPosition = calculateMousegrid(transformedPosition);
296 if (MathUtils.Between(gridPosition.X, 0, this.width)
297 && MathUtils.Between(gridPosition.Y, 0, this.height))
237 {
298 {
238 SendMessage(new JumpCameraMessage {Movement = original_point});
299 foreach (ref readonly var entity in ReadEntities<CursorComponent>()) {
300 var cursorComponent = GetComponent<CursorComponent>(entity);
301
302 SetComponent(entity, new CursorComponent { position = gridPosition,
303 size = 1 });
304 }
239 }
305 }
306 }
307 else if (ImGui.IsAnyItemHovered()) {
308 if (mouseCur.LeftButton == ButtonState.Pressed && mousePrev.LeftButton == ButtonState.Released) {
309 SendMessage(new PlaySoundMessage { SoundName = "ClickPart1" });
310 }
311 else if (mouseCur.LeftButton == ButtonState.Released && mousePrev.LeftButton == ButtonState.Pressed) {
312 SendMessage(new PlaySoundMessage { SoundName = "ClickPart2" });
313 }
314 }
240
315
241 #endregion
316 #endregion
242 this.keyboardPrev = keyboardCur;
317 this.keyboardPrev = keyboardCur;
@@ -12,48 +12,42
12 [Reads(typeof(TrespassingPolicyComponent))]
12 [Reads(typeof(TrespassingPolicyComponent))]
13 [Writes(typeof(TrespassingPolicyComponent),
13 [Writes(typeof(TrespassingPolicyComponent),
14 typeof(BudgetLineComponent))]
14 typeof(BudgetLineComponent))]
15 public class PolicyEngine : Engine
15 public class PolicyEngine : Engine
16 {
16 {
17
18 public PolicyEngine()
17 public PolicyEngine()
19 {
18 {
20 }
19 }
21
20
22
23 public override void Update(double dt)
21 public override void Update(double dt)
24 {
22 {
25 foreach (ref readonly var message
23 foreach (ref readonly var message
26 in ReadMessages<SetTrespassingPolicyMessage>())
24 in ReadMessages<SetTrespassingPolicyMessage>())
27 {
25 {
28 foreach (ref readonly var entity
26 foreach (ref readonly var entity
29 in ReadEntities<TrespassingPolicyComponent>())
27 in ReadEntities<TrespassingPolicyComponent>())
30 {
28 {
31
29
32 SetComponent<TrespassingPolicyComponent>(entity,
30 SetComponent<TrespassingPolicyComponent>(entity,
33 new TrespassingPolicyComponent
31 new TrespassingPolicyComponent
34 {
32 {
35 tresspassingPolicy
33 tresspassingPolicy
36 = message.newEnforcementLevel
34 = message.newEnforcementLevel
37 });
35 });
38
36
39 var newCost = message.newEnforcementLevel switch {
37 var newCost = message.newEnforcementLevel switch {
40 EnforcementLevel.Unspecified => 0,
38 EnforcementLevel.Unspecified => 0,
41 EnforcementLevel.NoEnforcement => 0,
39 EnforcementLevel.NoEnforcement => 0,
42 EnforcementLevel.EnforcedWithWarnings => 100,
40 EnforcementLevel.EnforcedWithWarnings => 100,
43 EnforcementLevel.EnforcedWithFines => 100,
41 EnforcementLevel.EnforcedWithFines => 100,
44 _ => 0 //C# enums can take on non-declared vaues. Sigh.
42 _ => 0 //C# enums can take on non-declared vaues. Sigh.
45 };
43 };
46
44
47 SetComponent<BudgetLineComponent>(entity,
45 SetComponent<BudgetLineComponent>(entity,
48 new BudgetLineComponent
46 new BudgetLineComponent
49 {
47 {category = "Enforcement",
50 category = "Enforcement",
48 amount = newCost});
51 amount = newCost
52 });
53 }
49 }
54 }
50 }
55
56 }
51 }
57
58 }
52 }
59 }
53 }
@@ -1,4 +1,5
1 using System;
1 using System;
2 using System.Diagnostics;
2 using System.Linq;
3 using System.Linq;
3 using System.Collections.Generic;
4 using System.Collections.Generic;
4
5
@@ -17,8 +18,10
17 typeof(BudgetComponent),
18 typeof(BudgetComponent),
18 typeof(BudgetLineComponent),
19 typeof(BudgetLineComponent),
19 typeof(ContractStatusComponent),
20 typeof(ContractStatusComponent),
20 typeof(TreeDeltaComponent))]
21 typeof(TreeDeltaComponent),
22 typeof(PreserveComponent))]
21 [Writes(typeof(BudgetComponent))]
23 [Writes(typeof(BudgetComponent))]
24 [Receives(typeof(SingleExpenseMessage), typeof(DebugAlterTreesMessage))]
22 public class SimulationBridgeEngine : Engine
25 public class SimulationBridgeEngine : Engine
23 {
26 {
24 public Simulation simulation;
27 public Simulation simulation;
@@ -53,6 +56,11
53 public override void Update(double dt)
56 public override void Update(double dt)
54 {
57 {
55
58
59 foreach (ref readonly var message in ReadMessages<SingleExpenseMessage>())
60 {
61 this.simulation.AddConstruction(message.amount);
62 }
63
56 foreach (ref readonly var entity in ReadEntities<BudgetComponent>())
64 foreach (ref readonly var entity in ReadEntities<BudgetComponent>())
57 {
65 {
58 ref readonly var budgetComponent = ref GetComponent<BudgetComponent>(entity);
66 ref readonly var budgetComponent = ref GetComponent<BudgetComponent>(entity);
@@ -67,7 +75,6
67 decimal new_contract_amount = 0M;
75 decimal new_contract_amount = 0M;
68 decimal new_enforcement_amount = 0M;
76 decimal new_enforcement_amount = 0M;
69 decimal new_misc_amount = 0M;
77 decimal new_misc_amount = 0M;
70 // decimal new_upkeep_amount = 0M;
71
78
72 foreach (ref readonly var entity in ReadEntities<BudgetLineComponent>())
79 foreach (ref readonly var entity in ReadEntities<BudgetLineComponent>())
73 {
80 {
@@ -91,14 +98,11
91 new_misc_amount += budgetComponent.amount;
98 new_misc_amount += budgetComponent.amount;
92 break;
99 break;
93 }
100 }
94
95 }
101 }
96
102
97
103
98
99 if (this.ticksToSend > 0)
104 if (this.ticksToSend > 0)
100 {
105 {
101
102 Logging.Trace(String.Format("{0} ticks to send in update", this.ticksToSend));
106 Logging.Trace(String.Format("{0} ticks to send in update", this.ticksToSend));
103 }
107 }
104 if (this.ticksToSend > 1)
108 if (this.ticksToSend > 1)
@@ -107,36 +111,106
107 }
111 }
108 for (int i = ticksToSend; i > 0; i--)
112 for (int i = ticksToSend; i > 0; i--)
109 {
113 {
110 SendMessage<TickMessage>(new TickMessage { SimulationDateTime = simulation.DateTime });
114
111 //For now:
115 #region calculate_preserve_cells
112 SendMessage<SpawnContractMessage>(new SpawnContractMessage
116 var preserve_cell_coordinates = new List<(int, int)>();
113 { //max_squares = 100,
117
114 name = string.Format("#logging_company.capitalizeAll# {0}", this.simulation.DateTime.ToShortDateString())
118 Stopwatch iterPreserves = new Stopwatch();
115 });
119 iterPreserves.Start();
120
121 foreach (ref readonly var entity in ReadEntities<PreserveComponent>()) {
122 ref readonly var areaComponent = ref GetComponent<AreaComponent>(entity);
123
124 foreach (var square in areaComponent.squares) {
125 preserve_cell_coordinates.Add(((int)square.X, (int)square.Y));
126 }
127 }
128 iterPreserves.Stop();
129 Logging.Info(String.Format("Preserve entities: {0:F3}", iterPreserves.Elapsed.TotalMilliseconds.ToString()));
130
131
132 Stopwatch iterCells = new Stopwatch();
133 iterCells.Start();
134
135 //This takes about 30ms versus the .0002 ms with no preserve.
136 //When the map is filled up with preserve, about 35ms and 9ms.
137 //With a handful of cells, it's more like 0.8ms
138 /*
139 for (int j = 0; j < this.simulation.PreserveCounts.GetLength(0); j++) {
140 for (int k = 0; k < this.simulation.PreserveCounts.GetLength(0); k++) {
141 count = 0;
142 foreach (var cell in this.simulation.map.iterate_neighbor_cells(j, k)) {
143 if (preserve_cells.Contains(cell)) {
144 count++;
145 }
146 }
147 this.simulation.PreserveCounts[j, k] = count;
148 }
149 }
150 //*/
151
152 //*
153 foreach ((var x, var y) in preserve_cell_coordinates) {
154 foreach ((var newx, var newy) in this.simulation.map.iterate_neighbor_cell_locations(x, y)) {
155 this.simulation.PreserveCounts[newx, newy] += 1;
156 }
157 }
158 //*/
159 iterCells.Stop();
160 Logging.Info(String.Format("Cell loop: {0:F3}", iterCells.Elapsed.TotalMilliseconds.ToString()));
161
162 #endregion
163 SendMessage<TickMessage>(new TickMessage { SimulationDateTime = simulation.DateTime });
164 //For now:
165 SendMessage<SpawnContractMessage>(new SpawnContractMessage {name = string.Format("#logging_company.capitalizeAll# {0}",
166 this.simulation.DateTime.ToShortDateString()) });
116
167
117 #region events
168 #region events
118 if (simulation.latestBudget.DateTime != default)
169 if (simulation.latestBudget.DateTime != default)
119 {
170 {
120
171
172 var tree_count_threshold = (int)(0.05 * this.simulation.map.tree_capacity);
173
121 if (simulation.latestBudget.money < 0M
174 if (simulation.latestBudget.money < 0M
122 && simulation.previousBudget.money >= 0M)
175 && simulation.previousBudget.money >= 0M)
123 {
176 {
124 SendMessage<SpawnDialogMessage>(new SpawnDialogMessage {Path = "EndLowFunds"});
177 SendMessage<SpawnDialogMessage>(new SpawnDialogMessage {Path = "EndLowFunds"});
125 }
178 }
126 else if (simulation.latestBudget.money < 10_000M
179 else if (simulation.latestBudget.money < 10_000M
127 && simulation.previousBudget.money >= 10_000M)
180 && simulation.previousBudget.money >= 10_000M)
128 {
181 {
129 SendMessage<SpawnDialogMessage>(new SpawnDialogMessage {Path = "VeryLowFunds"});
182 SendMessage<SpawnDialogMessage>(new SpawnDialogMessage {Path = "VeryLowFunds"});
130 }
183 }
131 else if (simulation.latestBudget.money < 25_000M
184 else if (simulation.latestBudget.money < 25_000M
132 && simulation.previousBudget.money >= 25_000M)
185 && simulation.previousBudget.money >= 25_000M)
133 {
186 {
134 SendMessage<SpawnDialogMessage>(new SpawnDialogMessage {Path = "LowFunds"});
187 SendMessage<SpawnDialogMessage>(new SpawnDialogMessage {Path = "LowFunds"});
135 }
188 }
136 if (simulation.map.tree_count < 400)
189
190 if ((simulation.latestBudget.trees < tree_count_threshold)
191 && (simulation.previousBudget.trees >= tree_count_threshold))
137 {
192 {
138 SendMessage<SpawnDialogMessage>(new SpawnDialogMessage {Path = "PoorTreeHealth"});
193 SendMessage<SpawnDialogMessage>(new SpawnDialogMessage {Path = "PoorTreeHealth"});
139 }
194 }
195
196 Logging.Spy(new {count = preserve_cell_coordinates.Count(), half = (simulation.map.tree_capacity * 0.5)} );
197
198 if ((simulation.latestBudget.preserve_cells > (simulation.map.tree_capacity * 0.5))
199 && (simulation.previousBudget.preserve_cells <= (simulation.map.tree_capacity * 0.5)))
200 {
201 SendMessage<SpawnDialogMessage>(new SpawnDialogMessage {Path = "PreserveHalf"});
202 var fundraiserEntity = CreateEntity();
203
204 AddComponent(fundraiserEntity, new BudgetLineComponent {
205 category = "Misc",
206 amount = 20_000M });
207 }
208 else if ((simulation.latestBudget.preserve_cells > (simulation.map.tree_capacity * 0.25))
209 && (simulation.previousBudget.preserve_cells <= (simulation.map.tree_capacity * 0.25)))
210 {
211 SendMessage<SpawnDialogMessage>(new SpawnDialogMessage {Path = "PreserveProgress"});
212 }
213
140 }
214 }
141
215
142 #endregion
216 #endregion
@@ -151,7 +225,7
151 var squares = HasComponent<AreaComponent>(entity) ? GetComponent<AreaComponent>(entity).squares : this.all_squares;
225 var squares = HasComponent<AreaComponent>(entity) ? GetComponent<AreaComponent>(entity).squares : this.all_squares;
152 var removed = 0;
226 var removed = 0;
153 var added = 0;
227 var added = 0;
154 var tree_squares = squares.Where((square) => simulation.map.cells[(int)square.X][(int)square.Y].hasTree);
228 var tree_squares = squares.Where((square) => simulation.map.cells[(int)square.X][(int)square.Y].HasTree);
155 var to_remove = Math.Abs(delta.deltaTrees.Value);
229 var to_remove = Math.Abs(delta.deltaTrees.Value);
156
230
157 //calculate the probability in order to get the expected number of removed trees
231 //calculate the probability in order to get the expected number of removed trees
@@ -162,17 +236,18
162 foreach (var square in tree_squares)
236 foreach (var square in tree_squares)
163 {
237 {
164 var cell = simulation.map.cells[(int)square.X][(int)square.Y];
238 var cell = simulation.map.cells[(int)square.X][(int)square.Y];
165 if (cell.hasTree
239 if (cell.HasTree
166 && random_generator.NextDouble() < probability)
240 && random_generator.NextDouble() < probability)
167 {
241 {
168 if (delta.deltaTrees.Value < 0)
242 if (delta.deltaTrees.Value < 0)
169 {
243 {
170 cell.removeTree();
244 cell.RemoveTree();
171 removed++;
245 removed++;
172 }
246 }
173 else if (delta.deltaTrees.Value > 0)
247 else if (delta.deltaTrees.Value > 0)
174 {
248 {
175 cell.addTree(this.simulation.DateTime);
249 var random_type = random_generator.Next(0, 3);
250 cell.AddTree(this.simulation.DateTime, (CellMap.TreeType)random_type);
176 added++;
251 added++;
177 }
252 }
178 }
253 }
@@ -185,6 +260,7
185 Logging.Info(String.Format("Planted {0} trees, expected {1}, P(destroy)= {2}", added, (expected / 12.0), probability));
260 Logging.Info(String.Format("Planted {0} trees, expected {1}, P(destroy)= {2}", added, (expected / 12.0), probability));
186 }
261 }
187 }
262 }
263 simulation.preserve_cells = preserve_cell_coordinates.Count();
188 }
264 }
189 this.ticksToSend = 0;
265 this.ticksToSend = 0;
190
266
@@ -192,8 +268,26
192 simulation.enforcement = new_enforcement_amount;
268 simulation.enforcement = new_enforcement_amount;
193 simulation.misc = new_misc_amount;
269 simulation.misc = new_misc_amount;
194
270
271 #region debug
272
273 foreach (ref readonly var message in ReadMessages<DebugAlterTreesMessage>())
274 {
275 var trees = message.DeltaTrees;
276
277 //Probaby not very performant; used only for debug.
278 foreach (CellMap.Cell cell in this.simulation.map.iterate_cells().Where(c => c.HasTree).ToList().Shuffle())
279 {
280 if (trees > 0) {
281 trees -= 1;
282 cell.RemoveTree();
283 }
284 }
285 }
286 #endregion
287
195 //Move this here?
288 //Move this here?
196 // this.simulation.update(dt);
289 // this.simulation.update(dt);
197 }
290 }
291
198 }
292 }
199 }
293 }
@@ -24,7 +24,6
24 private Random random_generator;
24 private Random random_generator;
25
25
26 public const int DEFAULT_MIN_SQUARES = 75;
26 public const int DEFAULT_MIN_SQUARES = 75;
27 // public const int DEFAULT_SQUARES = 25;
28 public const int DEFAULT_SQUARES = 100;
27 public const int DEFAULT_SQUARES = 100;
29 public const int CONTRACT_MINIMUM = 50;
28 public const int CONTRACT_MINIMUM = 50;
30 public const int CONTRACT_MAXIMUM = 400;
29 public const int CONTRACT_MAXIMUM = 400;
@@ -45,6 +44,7
45
44
46 this.simulation = simulation;
45 this.simulation = simulation;
47 this.grammar = grammar;
46 this.grammar = grammar;
47
48 }
48 }
49 private Vector2 FindStart(HashSet<Vector2> occupied_squares)
49 private Vector2 FindStart(HashSet<Vector2> occupied_squares)
50 {
50 {
@@ -53,14 +53,13
53
53
54 for (int i = 0; i < 5; i++)
54 for (int i = 0; i < 5; i++)
55 {
55 {
56 new_square = new Vector2(random_generator.Next(0, 50), random_generator.Next(0, 50));
56 new_square = new Vector2(random_generator.Next(0, this.MapHeight), random_generator.Next(0, this.MapWidth));
57
57
58 if (!occupied_squares.Contains(new_square))
58 if (!occupied_squares.Contains(new_square))
59 {
59 {
60 return new_square;
60 return new_square;
61 }
61 }
62 }
62 }
63 // return null;
64 return Vector2.Zero;
63 return Vector2.Zero;
65 }
64 }
66
65
@@ -70,7 +69,7
70 var squares_to_add = new HashSet<Vector2>();
69 var squares_to_add = new HashSet<Vector2>();
71
70
72 var attempts = 0;
71 var attempts = 0;
73 var maxAttempts = max_size * 10;
72 var maxAttempts = max_size * this.simulation.map.LinearMultiplier * 10;
74
73
75 while (squares.Count < max_size)
74 while (squares.Count < max_size)
76 {
75 {
@@ -113,8 +112,6
113
112
114 protected override void Spawn(in SpawnContractMessage message)
113 protected override void Spawn(in SpawnContractMessage message)
115 {
114 {
116
117
118 //for now:
115 //for now:
119 var occupied = new List<Vector2>();
116 var occupied = new List<Vector2>();
120
117
@@ -132,7 +129,9
132 Logging.Debug(String.Format("Creating contract {0} without organizations.", message.name ));
129 Logging.Debug(String.Format("Creating contract {0} without organizations.", message.name ));
133 }
130 }
134
131
135 foreach (var (entity, status) in ReadEntities<AreaComponent>().SelectWhereF((e) => (e, GetComponent<ContractStatusComponent>(e)), (e) => ((e.Item2.status != ContractStatus.Broken) && (e.Item2.status != ContractStatus.Rejected) && (e.Item2.status != ContractStatus.Expired)))) {
132 foreach (var (entity, status) in ReadEntities<AreaComponent>()
133 .WhereF((e) => HasComponent<ContractStatusComponent>(e))
134 .SelectWhereF((e) => (e, GetComponent<ContractStatusComponent>(e)), (e) => ((e.Item2.status != ContractStatus.Broken) && (e.Item2.status != ContractStatus.Rejected) && (e.Item2.status != ContractStatus.Expired)))) {
136 var entitySquares = GetComponent<AreaComponent>(entity).squares;
135 var entitySquares = GetComponent<AreaComponent>(entity).squares;
137 occupied.AddRange(entitySquares);
136 occupied.AddRange(entitySquares);
138 }
137 }
@@ -143,15 +142,11
143
142
144 var image_index = random_generator.Next(1, 7);
143 var image_index = random_generator.Next(1, 7);
145
144
146 // int max_squares = (message.max_squares == 0) ? DEFAULT_SQUARES : message.max_squares;
147 // int min_squares = (message.min_squares == null) ? DEFAULT_MIN_SQUARES : (int)message.min_squares;
148
149
150 int max_squares = (organization_type, message.min_squares) switch {
145 int max_squares = (organization_type, message.min_squares) switch {
151 (OrganizationType.Family, null) => random_generator.Next(50, 100),
146 (OrganizationType.Family, null) => random_generator.Next(50, 100 * this.simulation.map.LinearMultiplier),
152 (OrganizationType.LargeCorporation, null) => random_generator.Next(90, 250),
147 (OrganizationType.LargeCorporation, null) => random_generator.Next(90, 250 * this.simulation.map.LinearMultiplier),
153 (OrganizationType.Cooperative, null) => random_generator.Next(50, 75),
148 (OrganizationType.Cooperative, null) => random_generator.Next(50, 75 * this.simulation.map.LinearMultiplier),
154 (_, null) => random_generator.Next(DEFAULT_MIN_SQUARES, DEFAULT_SQUARES),
149 (_, null) => random_generator.Next(DEFAULT_MIN_SQUARES, DEFAULT_SQUARES * this.simulation.map.LinearMultiplier),
155 _ => (message.max_squares == 0) ? DEFAULT_SQUARES : message.max_squares
150 _ => (message.max_squares == 0) ? DEFAULT_SQUARES : message.max_squares
156 };
151 };
157
152
@@ -213,7 +208,7
213 AddComponent(contract, new AreaComponent { squares = squares });
208 AddComponent(contract, new AreaComponent { squares = squares });
214 var nameAndDescription = new NameAndDescriptionComponent { DisplayName = this.grammar.Flatten(message.name) };
209 var nameAndDescription = new NameAndDescriptionComponent { DisplayName = this.grammar.Flatten(message.name) };
215 AddComponent(contract, nameAndDescription);
210 AddComponent(contract, nameAndDescription);
216 AddComponent(contract, new SelectedComponent { selected = false });
211 AddComponent(contract, new SelectedComponent { selected = false, Type = SelectionType.Window });
217 AddComponent(contract, new ContractStatusComponent { status = ContractStatus.Proposed, date = this.simulation.DateTime });
212 AddComponent(contract, new ContractStatusComponent { status = ContractStatus.Proposed, date = this.simulation.DateTime });
218 AddComponent(contract, new TreeDeltaComponent { deltaTrees = new Fact<int>(deltaTrees) });
213 AddComponent(contract, new TreeDeltaComponent { deltaTrees = new Fact<int>(deltaTrees) });
219 AddComponent(contract, new BudgetLineComponent
214 AddComponent(contract, new BudgetLineComponent
@@ -41,19 +41,83
41 protected override void Spawn(in SpawnGameMessage message)
41 protected override void Spawn(in SpawnGameMessage message)
42 {
42 {
43
43
44 #region generate_water
45
46 /*
47 * Differs from code in ContractSpawner in a few ways:
48 * β€”Not concerned with existing tilesβ€”this is one of the first things we're doing to the new map
49 * β€”Doesn't keep track of attempts (should be few and far betweet.)
50 * β€”No logging (not sure what logging is necessary here)
51 *
52 * These notes are mostly for myself in the future if I decide to unify these implementations.
53 */
54 for (int i = 0; i < Simulation.NUM_WATER_FEATURES; i++) {
55 var water_x = this.random_generator.Next(0, this.simulation.map.MapWidth);
56 var water_y = this.random_generator.Next(0, this.simulation.map.MapHeight);
57
58
59 var water_squares = new List<Vector2>(new[] { new Vector2(water_x, water_y) });
60 var squares_to_add = new HashSet<Vector2>();
61 var odds = 0.50;
62
63 var water_size = random_generator.Next(50, 250);
64
65 while (water_squares.Count < water_size) {
66 foreach (var square in water_squares)
67 {
68 foreach (var new_square in new[] {new Vector2(square.X + 1, square.Y),
69 new Vector2(square.X, square.Y + 1),
70 new Vector2(square.X - 1, square.Y),
71 new Vector2(square.X, square.Y - 1)
72 })
73 {
74 if (random_generator.NextDouble() < odds
75 && !water_squares.Contains(new_square)
76 && MathUtils.Between(new_square.X, 0, this.simulation.map.MapWidth)
77 && MathUtils.Between(new_square.Y, 0, this.simulation.map.MapHeight)
78 )
79 {
80 squares_to_add.Add(new_square);
81 }
82 }
83 }
84 water_squares.AddRange(squares_to_add);
85 squares_to_add.Clear();
86 }
87 this.simulation.map.WaterCells.AddRange(water_squares);
88
89 foreach (var square in water_squares) {
90 this.simulation.map.cells[(int)square.X][(int)square.Y].AddWater();
91
92 }
93 }
94
95 for (int i = 0; i < Simulation.NUM_PONDS; i++) {
96 var water_x = this.random_generator.Next(0, this.simulation.map.MapWidth);
97 var water_y = this.random_generator.Next(0, this.simulation.map.MapHeight);
98 this.simulation.map.WaterCells.Add(new Vector2(water_x, water_y));
99 this.simulation.map.cells[water_x][water_y].AddWater();
100 Logging.Info(String.Format("Adding water at {0},{1}", water_x, water_y));
101 }
102
103
104 #endregion
44 #region generate_trees
105 #region generate_trees
45
106
46 foreach (List<Cell> row in this.simulation.map.cells)
107 foreach (List<Cell> row in this.simulation.map.cells)
47 {
108 {
48 foreach (Cell cell in row)
109 foreach (Cell cell in row)
49 {
110 {
50 if (this.random_generator.NextDouble() > 0.75)
111 var next = this.random_generator.NextDouble();
112 if (next > 0.75 && !cell.HasWater)
51 {
113 {
52 int random_year = (int)MathHelper.Clamp((float)MathUtils.NextNormal(random_generator, 2010.0f, 40.0f), 1800, Simulation.START_YEAR);
114 int random_year = (int)MathHelper.Clamp((float)MathUtils.NextNormal(random_generator, 2010.0f, 40.0f), 1800, Simulation.START_YEAR);
53 int random_month = random_generator.Next(1, 12);
115 int random_month = random_generator.Next(1, 13);
54 DateTime random_date = new DateTime(random_year, random_month, 1);
116 DateTime random_date = new DateTime(random_year, random_month, 1);
55
117
56 cell.addTree(random_date);
118 int random_type = random_generator.Next(0, 4);
119
120 cell.AddTree(random_date, (TreeType)random_type);
57 }
121 }
58 }
122 }
59 }
123 }
@@ -123,18 +187,27
123 #endregion
187 #endregion
124 this.simulation.Subsidy = message.Difficulty switch {
188 this.simulation.Subsidy = message.Difficulty switch {
125 DifficultyLevel.Hard => 0M,
189 DifficultyLevel.Hard => 0M,
126 DifficultyLevel.Medium => 760M,
190 DifficultyLevel.Medium => 12_550M,
127 DifficultyLevel.Easy => 1000M,
191 DifficultyLevel.Easy => 15_000M,
128 _ => 1000M
192 _ => 1000M
129 };
193 };
130
194
131 this.simulation.SubsidyDelta = message.Difficulty switch {
195 this.simulation.SubsidyDelta = message.Difficulty switch {
132 DifficultyLevel.Hard => 0M,
196 DifficultyLevel.Hard => 0M,
133 DifficultyLevel.Medium => -10M,
197 DifficultyLevel.Medium => -50M,
134 DifficultyLevel.Easy => 0M,
198 DifficultyLevel.Easy => 0M,
135 _ => 1000M
199 _ => 1000M
136 };
200 };
137
201
202 #region
203
204 var cursorEntity = CreateEntity();
205 AddComponent(cursorEntity,
206 new CursorComponent { position = new Vector2(20, 20),
207 size = 1 });
208
209 #endregion
210
138 Logging.Success("Spawned new game.");
211 Logging.Success("Spawned new game.");
139 }
212 }
140 }
213 }
@@ -20,11 +20,14
20 typeof(SetWindowVisibilityMessage),
20 typeof(SetWindowVisibilityMessage),
21 typeof(SelectMessage),
21 typeof(SelectMessage),
22 typeof(SetDialogMessage),
22 typeof(SetDialogMessage),
23 typeof(DialogChoiceMessage))]
23 typeof(DialogChoiceMessage),
24 typeof(AdjustSelection),
25 typeof(ToggleToolMessage))]
24 [Reads(typeof(DialogComponent),
26 [Reads(typeof(DialogComponent),
25 typeof(WindowTypeComponent),
27 typeof(WindowTypeComponent),
26 typeof(VisibilityComponent),
28 typeof(VisibilityComponent),
27 typeof(SelectedComponent))]
29 typeof(SelectedComponent),
30 typeof(ToolComponent))]
28 [Writes(typeof(VisibilityComponent),
31 [Writes(typeof(VisibilityComponent),
29 typeof(SelectedComponent))]
32 typeof(SelectedComponent))]
30 class UIEngine : Engine
33 class UIEngine : Engine
@@ -40,15 +43,14
40 {
43 {
41 foreach (var entity in ReadEntities<SelectedComponent>())
44 foreach (var entity in ReadEntities<SelectedComponent>())
42 {
45 {
43 SetComponent(entity, new SelectedComponent { selected = false });
46 var selected = GetComponent<SelectedComponent>(entity);
47 if (selected.Type == SelectionType.Window) {
48 SetComponent(entity, new SelectedComponent { selected = false });
49 }
44 }
50 }
45
51
46 foreach (ref readonly var windowMessage in ReadMessages<SetWindowVisibilityMessage>())
52 foreach (ref readonly var windowMessage in ReadMessages<SetWindowVisibilityMessage>())
47 {
53 {
48 Logging.Spy(windowMessage, "message");
49 Logging.Spy(windowMessage.Entity, "message.Entity");
50 Logging.Spy(windowMessage.Entity.ID, "message.Entity.ID");
51 Logging.Spy(windowMessage.Visibility, "message.Visibility");
52 foreach (ref readonly var entity in ReadEntities<WindowTypeComponent>())
54 foreach (ref readonly var entity in ReadEntities<WindowTypeComponent>())
53 {
55 {
54 Logging.Spy(entity.ID, "ID");
56 Logging.Spy(entity.ID, "ID");
@@ -62,9 +64,6
62 }
64 }
63 foreach (ref readonly var windowMessage in ReadMessages<ToggleWindowMessage>())
65 foreach (ref readonly var windowMessage in ReadMessages<ToggleWindowMessage>())
64 {
66 {
65 Logging.Spy(windowMessage, "message");
66 Logging.Spy(windowMessage.Window, "message.Window");
67 Logging.Spy(windowMessage.Entity, "message.Entity");
68 foreach (ref readonly var entity in ReadEntities<WindowTypeComponent>())
67 foreach (ref readonly var entity in ReadEntities<WindowTypeComponent>())
69 {
68 {
70 if (EntityExists(windowMessage.Entity) && entity.ID == windowMessage.Entity.ID)
69 if (EntityExists(windowMessage.Entity) && entity.ID == windowMessage.Entity.ID)
@@ -77,8 +76,6
77 }
76 }
78 foreach (ref readonly var windowMessage in ReadMessages<ToggleWindowTypeMessage>())
77 foreach (ref readonly var windowMessage in ReadMessages<ToggleWindowTypeMessage>())
79 {
78 {
80 Logging.Spy(windowMessage, "message");
81 Logging.Spy(windowMessage.Window, "message.Window");
82 foreach (ref readonly var entity in ReadEntities<WindowTypeComponent>())
79 foreach (ref readonly var entity in ReadEntities<WindowTypeComponent>())
83 {
80 {
84
81
@@ -88,7 +85,30
88 var visibilityComponent = GetComponent<VisibilityComponent>(entity);
85 var visibilityComponent = GetComponent<VisibilityComponent>(entity);
89 SetComponent(entity, new VisibilityComponent { visible = !visibilityComponent.visible });
86 SetComponent(entity, new VisibilityComponent { visible = !visibilityComponent.visible });
90 }
87 }
88 }
89 }
91
90
91
92 //Set tool
93 foreach (ref readonly var toolMessage in ReadMessages<ToggleToolMessage>())
94 {
95 foreach (ref readonly var entity in ReadEntities<ToolComponent>())
96 {
97
98 var tool_type = GetComponent<ToolComponent>(entity).Tool;
99 if (tool_type == toolMessage.Tool)
100 {
101 //Clear selections
102 foreach (ref readonly var inner_entity in ReadEntities<ToolComponent>())
103 {
104 var inner_selected_component = GetComponent<SelectedComponent>(inner_entity);
105 inner_selected_component.selected = false;
106 SetComponent(inner_entity, inner_selected_component);
107 }
108 var selectedComponent = GetComponent<SelectedComponent>(entity);
109 selectedComponent.selected = !selectedComponent.selected;
110 SetComponent(entity, selectedComponent);
111 }
92 }
112 }
93 }
113 }
94
114
@@ -98,7 +118,19
98 new SelectedComponent { selected = true });
118 new SelectedComponent { selected = true });
99 }
119 }
100
120
101
121 foreach (ref readonly var message in ReadMessages<AdjustSelection>()) {
102 }
122 if(message.Type == AdjustmentType.Complete) {
103 }
123 foreach (ref readonly var entity in ReadEntities<SelectedComponent>()) {
124 var selection = GetComponent<SelectedComponent>(entity);
125 if(selection.Type == SelectionType.Area
126 && selection.selected) {
127 SetComponent(entity, new SelectedComponent {Type = SelectionType.Area,
128 selected = false
129 });
130 }
131 }
132 }
133 }
134 }
135 }
104 }
136 }
@@ -11,6 +11,7
11 using System.Collections.Generic;
11 using System.Collections.Generic;
12 using System.Linq;
12 using System.Linq;
13 using SpriteFontPlus;
13 using SpriteFontPlus;
14 using JM.LinqFaster;
14
15
15 using isometricparkfna;
16 using isometricparkfna;
16 using static isometricparkfna.CellMap;
17 using static isometricparkfna.CellMap;
@@ -25,7 +26,6
25
26
26 using ImGuiNET.SampleProgram.XNA;
27 using ImGuiNET.SampleProgram.XNA;
27 using ImGuiNET;
28 using ImGuiNET;
28 using ImPlotNET;
29 using TraceryNet;
29 using TraceryNet;
30 using Encompass;
30 using Encompass;
31 using Ink.Runtime;
31 using Ink.Runtime;
@@ -43,11 +43,13
43 private MouseState mousePrev = new MouseState();
43 private MouseState mousePrev = new MouseState();
44
44
45 private SpriteBatch batch;
45 private SpriteBatch batch;
46 #if DEBUG
46 private SpriteBatch tileBatch;
47 // #if DEBUG
47 private SoundEffect sound;
48 private SoundEffect sound;
48 #endif
49 // #endif
49 private SpriteFont monoFont;
50 private SpriteFont monoFont;
50 private SpriteFont largeMonoFont;
51 private SpriteFont largeMonoFont;
52 private SpriteFont ocrFont;
51
53
52 private Camera camera = new Camera(new float[] {0.125f, 0.25f, 0.5f, 1.0f, 2.0f, 4.0f });
54 private Camera camera = new Camera(new float[] {0.125f, 0.25f, 0.5f, 1.0f, 2.0f, 4.0f });
53
55
@@ -55,15 +57,23
55
57
56 int frameRate = 0;
58 int frameRate = 0;
57 int frameCounter = 0;
59 int frameCounter = 0;
60 long totalFrameCounter = 0; //Will cover over a billion years at 60 fps
58 TimeSpan elapsedTime = TimeSpan.Zero;
61 TimeSpan elapsedTime = TimeSpan.Zero;
59 TimeSpan drawTime = TimeSpan.Zero;
62 TimeSpan drawTime = TimeSpan.Zero;
60 TimeSpan tileDrawTime = TimeSpan.Zero;
63 TimeSpan tileDrawTime = TimeSpan.Zero;
61 TimeSpan gridDrawTime = TimeSpan.Zero;
64 TimeSpan gridDrawTime = TimeSpan.Zero;
62 TimeSpan treeDrawTime = TimeSpan.Zero;
65 TimeSpan treeDrawTime = TimeSpan.Zero;
66 TimeSpan rendererDrawTime = TimeSpan.Zero;
67 TimeSpan miscUIDrawTime = TimeSpan.Zero;
68 TimeSpan debugDrawTime = TimeSpan.Zero;
63 TimeSpan updateTime = TimeSpan.Zero;
69 TimeSpan updateTime = TimeSpan.Zero;
70 TimeSpan worldUpdateTime = TimeSpan.Zero;
71 TimeSpan simulationUpdateTime = TimeSpan.Zero;
64
72
65 Queue<float> past_fps = new Queue<float>(100);
73 Queue<float> past_fps = new Queue<float>(100);
66 Queue<TimeSpan> past_draw = new Queue<TimeSpan>(100);
74 List<float> past_fps_sorted = new List<float>(100);
75 // Queue<TimeSpan> past_draw = new Queue<TimeSpan>(100);
76 List<float> past_draw_millis = new List<float>(100);
67 int tilesDrawn = 0;
77 int tilesDrawn = 0;
68
78
69 private static int width = 1280;
79 private static int width = 1280;
@@ -81,6 +91,8
81 //for now
91 //for now
82 public bool in_zone;
92 public bool in_zone;
83 public bool in_active_zone;
93 public bool in_active_zone;
94 public bool in_preserve;
95 public bool has_tower;
84
96
85 public bool isPlaying = false;
97 public bool isPlaying = false;
86
98
@@ -116,8 +128,7
116
128
117 public bool quit = false;
129 public bool quit = false;
118
130
119
131 [STAThread]
120
121 private static void Main(string[] args)
132 private static void Main(string[] args)
122 {
133 {
123 #if NETCOREAPP
134 #if NETCOREAPP
@@ -148,8 +159,6
148 {
159 {
149 Logging.Debug("Loaded: " + assembly.ToString() + "\n");
160 Logging.Debug("Loaded: " + assembly.ToString() + "\n");
150 }
161 }
151 ;
152
153 #endif
162 #endif
154 this.gdm = new GraphicsDeviceManager(this) {
163 this.gdm = new GraphicsDeviceManager(this) {
155 // Typically you would load a config here...
164 // Typically you would load a config here...
@@ -162,7 +171,6
162
171
163 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 });
172 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 });
164
173
165
166 showBudget = false;
174 showBudget = false;
167 showGrid = true;
175 showGrid = true;
168 showTrees = true;
176 showTrees = true;
@@ -188,12 +196,17
188 protected override void LoadContent()
196 protected override void LoadContent()
189 {
197 {
190 // Create the batch...
198 // Create the batch...
191 batch = new SpriteBatch(GraphicsDevice);
199 this.batch = new SpriteBatch(GraphicsDevice);
200 this.tileBatch = new SpriteBatch(GraphicsDevice);
192
201
193 #if DEBUG
202 this.sound = SoundEffectEngine.LoadSound(Content, "FNASound");
194 sound = Content.Load<SoundEffect>("FNASound");
203 SoundEffectEngine.LoadSound(Content, "Click");
195 #endif
204 SoundEffectEngine.LoadSound(Content, "ClickPart1");
196 Tile.TileSetTexture = Content.Load<Texture2D>(@"part4_tileset");
205 SoundEffectEngine.LoadSound(Content, "ClickPart2");
206 SoundEffectEngine.LoadSound(Content, "Construction");
207 SoundEffectEngine.LoadSound(Content, "ConstructionShort");
208 SoundEffectEngine.LoadSound(Content, "Bell");
209 Tile.TileSetTexture = Content.Load<Texture2D>(@"merged_tileset");
197 var texture = Content.Load<Texture2D>(@"solid_tileset");
210 var texture = Content.Load<Texture2D>(@"solid_tileset");
198
211
199 var imageMapTexture = Content.Load<Texture2D>(@"photos_converted3");
212 var imageMapTexture = Content.Load<Texture2D>(@"photos_converted3");
@@ -238,8 +251,25
238 new CharacterRange((char) 0x00B7)
251 new CharacterRange((char) 0x00B7)
239 }
252 }
240 );
253 );
254
255 var bakedOCR = TtfFontBaker.Bake(File.OpenRead(@"Content/OCRA.ttf"),
256 18,
257 1024,
258 1024,
259 new[]
260 {
261 CharacterRange.BasicLatin,
262 CharacterRange.Latin1Supplement,
263 CharacterRange.LatinExtendedA,
264 CharacterRange.Cyrillic,
265 CharacterRange.LatinExtendedB,
266 new CharacterRange((char) 0x00B7)
267 }
268 );
269
241 monoFont = bakedMono.CreateSpriteFont(GraphicsDevice);
270 monoFont = bakedMono.CreateSpriteFont(GraphicsDevice);
242 largeMonoFont = bakedMonoLarge.CreateSpriteFont(GraphicsDevice);
271 largeMonoFont = bakedMonoLarge.CreateSpriteFont(GraphicsDevice);
272 ocrFont = bakedOCR.CreateSpriteFont(GraphicsDevice);
243
273
244 //Has to happen before Encompass stuff, because the Encompass machinery around ImGui requires debugWindow's monoFont to be loaded:
274 //Has to happen before Encompass stuff, because the Encompass machinery around ImGui requires debugWindow's monoFont to be loaded:
245 this.debugWindow = new DebugWindow(this._imGuiRenderer, GraphicsDevice, this.imageMap);
275 this.debugWindow = new DebugWindow(this._imGuiRenderer, GraphicsDevice, this.imageMap);
@@ -260,15 +290,20
260 this.imGuiWindowBridgeEngine.typeMessages.Add(new ToggleWindowTypeMessage {Window = isometricparkfna.Messages.Window.MainMenu});
290 this.imGuiWindowBridgeEngine.typeMessages.Add(new ToggleWindowTypeMessage {Window = isometricparkfna.Messages.Window.MainMenu});
261 });
291 });
262
292
263 Logging.Debug(this.Story.ContinueMaximally());
293 var gameBridgeEngine = new GameBridgeEngine(this);
294 Story.BindExternalFunction("undoPreserve", () => {
295 gameBridgeEngine.undoPreserveMessages.Add(new UndoPreserveMessage {});
296 });
264
297
265 WorldBuilder.AddEngine(new InputEngine(Menu.MENU_BAR_HEIGHT, this.camera, gdm));
298 Logging.Debug("Continuing Maximally: " + this.Story.ContinueMaximally().ToString());
299
300 WorldBuilder.AddEngine(new InputEngine(Menu.MENU_BAR_HEIGHT, this.camera, gdm,
301 this.simulation.map.MapHeight, this.simulation.map.MapWidth));
266 WorldBuilder.AddEngine(new UIEngine(this.Story));
302 WorldBuilder.AddEngine(new UIEngine(this.Story));
267 WorldBuilder.AddEngine(new DialogEngine(this.Story, this.grammar));
303 WorldBuilder.AddEngine(new DialogEngine(this.Story, this.grammar));
268
304
269 WorldBuilder.AddEngine(new EventEngine());
305 WorldBuilder.AddEngine(new EventEngine());
270
306
271 var gameBridgeEngine = new GameBridgeEngine(this);
272
307
273 WorldBuilder.AddEngine(gameBridgeEngine);
308 WorldBuilder.AddEngine(gameBridgeEngine);
274 WorldBuilder.AddEngine(new GameStateEngine());
309 WorldBuilder.AddEngine(new GameStateEngine());
@@ -285,10 +320,13
285 WorldBuilder.AddEngine(new PolicyEngine());
320 WorldBuilder.AddEngine(new PolicyEngine());
286 WorldBuilder.AddEngine(new TraceryBridgeEngine(this.grammar));
321 WorldBuilder.AddEngine(new TraceryBridgeEngine(this.grammar));
287 WorldBuilder.AddEngine(new SimulationGameRateBridgeEngine(this.simulation));
322 WorldBuilder.AddEngine(new SimulationGameRateBridgeEngine(this.simulation));
288
323 WorldBuilder.AddEngine(new BuildToolEngine(this.simulation));
324 WorldBuilder.AddEngine(new SoundEffectEngine());
289
325
290 WorldBuilder.AddGeneralRenderer(new AreaRenderer(this.batch, this.monoFont), 1);
326 WorldBuilder.AddGeneralRenderer(new AreaRenderer(this.tileBatch, this.monoFont), 1);
291 WorldBuilder.AddGeneralRenderer(new ImGuiWindowRenderer(this, this.simulation, this.imGuiWindowBridgeEngine, this.gdm), 2);
327 WorldBuilder.AddGeneralRenderer(new ImGuiWindowRenderer(this, this.simulation, this.imGuiWindowBridgeEngine, this.gdm), 2);
328 WorldBuilder.AddGeneralRenderer(new CursorRenderer(this.tileBatch, this.monoFont), 3);
329 WorldBuilder.AddGeneralRenderer(new StructureRenderer(this.tileBatch, this.monoFont), 4);
292 var contractWindow = WorldBuilder.CreateEntity();
330 var contractWindow = WorldBuilder.CreateEntity();
293 WorldBuilder.SetComponent(contractWindow, new VisibilityComponent { visible = false });
331 WorldBuilder.SetComponent(contractWindow, new VisibilityComponent { visible = false });
294 WorldBuilder.SetComponent(contractWindow, new WindowTypeComponent { type = isometricparkfna.Messages.Window.Contracts });
332 WorldBuilder.SetComponent(contractWindow, new WindowTypeComponent { type = isometricparkfna.Messages.Window.Contracts });
@@ -322,6 +360,14
322 WorldBuilder.SetComponent(graphWindow, new VisibilityComponent { visible = false });
360 WorldBuilder.SetComponent(graphWindow, new VisibilityComponent { visible = false });
323 WorldBuilder.SetComponent(graphWindow, new WindowTypeComponent { type = isometricparkfna.Messages.Window.Graph });
361 WorldBuilder.SetComponent(graphWindow, new WindowTypeComponent { type = isometricparkfna.Messages.Window.Graph });
324
362
363 //Create a tool for each tool type.
364 foreach (var tool in System.Enum.GetValues(typeof(Tool))) {
365 if ((Tool)tool != Tool.None) {
366 var toolEntity = WorldBuilder.CreateEntity();
367 WorldBuilder.SetComponent(toolEntity, new ToolComponent { Tool = (Tool)tool });
368 WorldBuilder.SetComponent(toolEntity, new SelectedComponent {Type = SelectionType.Tool, selected = ((Tool)tool == Tool.Preserve)});
369 }
370 }
325
371
326 var gameEntity = WorldBuilder.CreateEntity();
372 var gameEntity = WorldBuilder.CreateEntity();
327
373
@@ -341,9 +387,12
341 fontName = options.fontName
387 fontName = options.fontName
342 });
388 });
343
389
344 WorldBuilder.SetComponent(gameEntity, new OptionsComponent {ProfanitySetting = options.profanitySetting});
390 WorldBuilder.SetComponent(gameEntity, new OptionsComponent {ProfanitySetting = options.profanitySetting,
391 SoundEffectVolume = options.SoundEffectVolume,
392 SoundEffectMuted = options.SoundEffectMuted
393 });
345
394
346 OptionsWindow.Initialize(new Vector2(FNAGame.width, FNAGame.height), gdm.IsFullScreen, options.profanitySetting);
395 OptionsWindow.Initialize(new Vector2(FNAGame.width, FNAGame.height), gdm.IsFullScreen, options.profanitySetting, options);
347 Logging.Success("Loaded options.");
396 Logging.Success("Loaded options.");
348
397
349 }
398 }
@@ -352,6 +401,8
352 Logging.Error(String.Format("Error loading file: {0}", e.ToString()));
401 Logging.Error(String.Format("Error loading file: {0}", e.ToString()));
353 }
402 }
354
403
404 this.debugWindow.engine = this.imGuiWindowBridgeEngine;
405
355 World = WorldBuilder.Build();
406 World = WorldBuilder.Build();
356
407
357 this.output = grammar.Flatten("#greeting#");
408 this.output = grammar.Flatten("#greeting#");
@@ -379,7 +430,7
379 }
430 }
380 this.simulation.LoadContent(this.newsItems, this.grammar);
431 this.simulation.LoadContent(this.newsItems, this.grammar);
381
432
382 this.budgetWindow = new BudgetWindow(new Budget { }, this.monoFont, 0, 0);
433 this.budgetWindow = new BudgetWindow(new Budget { }, this.ocrFont, 0, 0);
383
434
384 Logging.Success("Content loaded.");
435 Logging.Success("Content loaded.");
385 }
436 }
@@ -411,9 +462,11
411 protected override void UnloadContent()
462 protected override void UnloadContent()
412 {
463 {
413 batch.Dispose();
464 batch.Dispose();
414 #if DEBUG
465 // #if DEBUG
415 sound.Dispose();
466 sound.Dispose();
416 #endif
467 SoundEffectEngine.DisposeSounds();
468
469 // #endif
417 Tile.TileSetTexture.Dispose();
470 Tile.TileSetTexture.Dispose();
418 Logging.Success("Disposed of Tile texture.");
471 Logging.Success("Disposed of Tile texture.");
419 if (Quad.PixelTexture != null)
472 if (Quad.PixelTexture != null)
@@ -439,10 +492,28
439 }
492 }
440
493
441
494
495 private String CurrentStatus() {
496
497 if (this.in_active_zone) {
498 return "Contracted";
499 }
500 else if (this.in_zone) {
501 return "Proposed Contract";
502 }
503 else if (this.in_preserve) {
504 return "Preserve";
505 }
506 else {
507 return "Unused";
508 }
509 }
510
511
442
512
443 protected override void Update(GameTime gameTime)
513 protected override void Update(GameTime gameTime)
444 {
514 {
445 Stopwatch stopWatch = new Stopwatch();
515 Stopwatch stopWatch = new Stopwatch();
516 Stopwatch stopWatch2 = new Stopwatch();
446 stopWatch.Start();
517 stopWatch.Start();
447
518
448 #if DEBUG
519 #if DEBUG
@@ -468,15 +539,22
468 #endregion misc_keys
539 #endregion misc_keys
469 #endregion input
540 #endregion input
470
541
542 stopWatch2.Start();
471 World.Update(gameTime.ElapsedGameTime.TotalSeconds);
543 World.Update(gameTime.ElapsedGameTime.TotalSeconds);
544 stopWatch2.Stop();
545 this.worldUpdateTime = stopWatch2.Elapsed;
546
547 stopWatch2 = new Stopwatch();
548 stopWatch2.Start();
472 this.simulation.update(gameTime.ElapsedGameTime);
549 this.simulation.update(gameTime.ElapsedGameTime);
550 stopWatch2.Stop();
551 this.simulationUpdateTime = stopWatch2.Elapsed;
473
552
474 if (this.showBudget)
553 if (this.showBudget)
475 {
554 {
476 this.showBudget = this.budgetWindow.update(mouseCur, this.simulation.latestBudget, this.simulation.previousBudget);
555 this.showBudget = this.budgetWindow.update(mouseCur, this.simulation.latestBudget, this.simulation.previousBudget);
477 }
556 }
478
557
479
480 this.original_point = Vector2.Transform(new Vector2(mouseCur.X, mouseCur.Y), Matrix.Invert(camera.get_transformation(GraphicsDevice)));
558 this.original_point = Vector2.Transform(new Vector2(mouseCur.X, mouseCur.Y), Matrix.Invert(camera.get_transformation(GraphicsDevice)));
481
559
482 this.mouseGrid = this.calculateMousegrid(this.original_point);
560 this.mouseGrid = this.calculateMousegrid(this.original_point);
@@ -519,23 +597,108
519 && MathUtils.BetweenExclusive(original.Y, -Tile.TileSpriteHeight, FNAGame.height)));
597 && MathUtils.BetweenExclusive(original.Y, -Tile.TileSpriteHeight, FNAGame.height)));
520 }
598 }
521
599
600
522 //Convenience method I'm not super sure about anymore.
601 //Convenience method I'm not super sure about anymore.
523 protected void drawTileAt(int x, int y, int tileIndex, int height)
602 protected void drawTileAt(int x, int y, int tileIndex, int height, Color color, SpriteBatch batch)
524 {
603 {
525 float maxdepth = ((this.squaresAcross + 1) + ((this.squaresDown + 1) * Tile.TileWidth)) * 10;
604 float maxdepth = ((this.squaresAcross + 1) + ((this.squaresDown + 1) * Tile.TileWidth)) * 10;
526
605
527 float depthOffset = 0.7f - ((0 + (0 * Tile.TileWidth)) / maxdepth);
606 float depthOffset = 0.7f - ((x + (y * Tile.TileWidth)) / maxdepth);
607
608 Tile.drawTileAt(batch, x, y, tileIndex, height, depthOffset, color);
609 }
610
611 protected void drawTileAt(int x, int y, int tileIndex, int height, Color color) {
612 drawTileAt(x, y, tileIndex, height, Color.White, this.tileBatch);
613 }
614
615 protected void drawTileAt(int x, int y, int tileIndex, int height) {
616 drawTileAt(x, y, tileIndex, height, Color.White);
617 }
618
619 protected void drawWaterTileAt(int x, int y, int height) {
620 drawWaterTileAt(x, y, height, this.tileBatch);
621 }
622
623 protected void drawWaterTileAt(int x, int y, int height, SpriteBatch batch) {
624 var tile_index = 85;
625 var cells = this.simulation.map.cells;
626
627 //Unfortunately this is tileset dependent and pretty awkward to type out :(
628 var northwest = (x != 0 && (cells[x-1][y].Status == CellStatus.Water));
629 var northeast = (y != 0 && (cells[x][y-1].Status == CellStatus.Water));
630 var southwest = (y < (this.simulation.map.MapHeight-1) && cells[x][y+1].Status == CellStatus.Water);
631 var southeast = (x < (this.simulation.map.MapWidth-1) && cells[x+1][y].Status == CellStatus.Water);
632
528
633
529 Tile.drawTileAt(this.batch, x, y, tileIndex, height, depthOffset);
634 if (northwest && northeast && southwest && southeast) {
635 //There are two "open water" squares
636 if (((y % 5) == 0) && ((x % 3) == 0)) {
637 tile_index = 84;
638 }
639 else {
640 tile_index = 85;
641 }
642 }
643 else if (northwest && northeast && southwest && !southeast) {
644 tile_index = 82;
645 }
646 else if (northwest && northeast && !southwest && southeast) {
647 tile_index = 81;
648 }
649 else if (northwest && northeast && !southwest && !southeast) {
650 tile_index = 80;
651 }
652 else if (northwest && !northeast && southwest && southeast) {
653 tile_index = 88;
654 }
655 else if (northwest && !northeast && southwest && !southeast) {
656 tile_index = 86;
657 }
658 else if (northwest && !northeast && !southwest && southeast) {
659 tile_index = 91;
660 }
661 else if (northwest && !northeast && !southwest && !southeast) {
662 tile_index = 90; //Not really correct
663 }
664 else if (!northwest && northeast && southwest && southeast) {
665 tile_index = 87;
666 }
667 else if (!northwest && northeast && southwest && !southeast) {
668 tile_index = 92;
669 }
670 else if (!northwest && northeast && !southwest && southeast) {
671 tile_index = 83;
672 }
673 else if (!northwest && northeast && !southwest && !southeast) {
674 tile_index = 95; //not really correct
675 }
676 else if (!northwest && !northeast && southwest && southeast) {
677 tile_index = 89;
678 }
679 else if (!northwest && !northeast && southwest && !southeast) {
680 tile_index = 95;
681 }
682 else if (!northwest && !northeast && !southwest && southeast) {
683 tile_index = 95;
684 }
685 //Shouldn't really exist:
686 else if (!northwest && !northeast && !southwest && !southeast) {
687 tile_index = 101;
688 }
689
690 drawTileAt(x, y, tile_index, height, Color.White, batch);
530 }
691 }
531
692
532
693
533 protected override void Draw(GameTime gameTime)
694 protected override void Draw(GameTime gameTime)
534 {
695 {
535 frameCounter++;
696 frameCounter++;
697 totalFrameCounter++;
536
698
537 string fps = string.Format("fps: {0}", frameRate);
699 string fps = string.Format("fps: {0}", frameRate);
538 bool has_tree = false;
700 bool has_tree = false;
701 Stopwatch stopWatch2 = new Stopwatch();
539
702
540 Stopwatch stopWatch = new Stopwatch();
703 Stopwatch stopWatch = new Stopwatch();
541 stopWatch.Start();
704 stopWatch.Start();
@@ -554,48 +717,28
554
717
555
718
556 #region draw_tiles
719 #region draw_tiles
557 Stopwatch stopWatch2 = new Stopwatch();
558 stopWatch2.Start();
720 stopWatch2.Start();
559 //reset
721 //reset
560 this.tilesDrawn = 0;
722 this.tilesDrawn = 0;
561
723
562 var scale_factor = 1;
724 for (int i = 0; i < this.simulation.map.MapHeight; i++)
563 var x_adjust = scale_factor > 1 ? -scale_factor : 0;
564 var y_adjust = scale_factor > 1 ? -scale_factor/2 : 0;
565
566 for (int y = y_adjust; y < this.squaresDown + y_adjust; y += scale_factor)
567 {
725 {
568 for (int x = x_adjust; x < this.squaresAcross + x_adjust; x += scale_factor)
726 for (int j = 0; j < this.simulation.map.MapWidth; j += 1)
569 {
727 {
570 int screenx = (x - y) * (Tile.TileSpriteWidth) / 2 - 3*scale_factor;
728 drawTileAt(i, j, 1, 1, Color.White, batch);
571 int screeny = (x + y) * (Tile.TileSpriteHeight) / 2;
729 this.tilesDrawn++;
572
573 // if (this.cull(x, y))
574 // {
575 batch.Draw(
576 Tile.TileSetTexture,
577 new Rectangle(
578 screenx,
579 screeny,
580 Tile.TileWidth * scale_factor, Tile.TileHeight * scale_factor),
581 Tile.GetSourceRectangle(1),
582 Color.White,
583 0.0f,
584 Vector2.Zero,
585 SpriteEffects.None,
586 0.9f);
587
588 this.tilesDrawn++;
589 // }
590 }
730 }
591 }
731 }
732 foreach (var cell in this.simulation.map.WaterCells) {
733 drawWaterTileAt((int)cell.X, (int)cell.Y, 1, batch);
734 }
592 batch.End();
735 batch.End();
593 stopWatch2.Stop();
736 stopWatch2.Stop();
594 this.tileDrawTime = stopWatch2.Elapsed;
737 this.tileDrawTime = stopWatch2.Elapsed;
595 #endregion draw_tiles
738 #endregion draw_tiles
596
739
597 #region draw_gridlines
740 #region draw_gridlines
598 batch.Begin(SpriteSortMode.BackToFront,
741 batch.Begin(SpriteSortMode.Deferred,
599 BlendState.AlphaBlend,
742 BlendState.AlphaBlend,
600 null,
743 null,
601 null,
744 null,
@@ -616,7 +759,6
616 Line.drawLine(batch,
759 Line.drawLine(batch,
617 new Vector2(((0 - y) * Tile.TileSpriteWidth / 2),
760 new Vector2(((0 - y) * Tile.TileSpriteWidth / 2),
618 (0 + y) * Tile.TileSpriteHeight / 2) + adjust,
761 (0 + y) * Tile.TileSpriteHeight / 2) + adjust,
619 //new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
620 new Vector2((this.squaresAcross - (y)) * Tile.TileSpriteWidth / 2,
762 new Vector2((this.squaresAcross - (y)) * Tile.TileSpriteWidth / 2,
621 (this.squaresAcross + (y)) * Tile.TileSpriteHeight / 2) + adjust,
763 (this.squaresAcross + (y)) * Tile.TileSpriteHeight / 2) + adjust,
622
764
@@ -631,95 +773,66
631
773
632 Line.drawLine(batch,
774 Line.drawLine(batch,
633 new Vector2(((x - 0) * Tile.TileSpriteWidth / 2), (x + 0) * Tile.TileSpriteHeight / 2) + adjust,
775 new Vector2(((x - 0) * Tile.TileSpriteWidth / 2), (x + 0) * Tile.TileSpriteHeight / 2) + adjust,
634 //new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
635 new Vector2((x - this.squaresDown) * Tile.TileSpriteWidth / 2, (x + this.squaresDown) * Tile.TileSpriteHeight / 2) + adjust,
776 new Vector2((x - this.squaresDown) * Tile.TileSpriteWidth / 2, (x + this.squaresDown) * Tile.TileSpriteHeight / 2) + adjust,
636 Color.White, 0.81f);
777 Color.White, 0.81f);
637
778
638 }
779 }
639 }
780 }
781 batch.End();
640 stopWatch2.Stop();
782 stopWatch2.Stop();
641 this.gridDrawTime = stopWatch2.Elapsed;
783 this.gridDrawTime = stopWatch2.Elapsed;
642 #endregion draw_gridlines
784 #endregion draw_gridlines
643
785
644
786 tileBatch.Begin(SpriteSortMode.BackToFront,
645 //Gridlines
787 BlendState.AlphaBlend,
646 //Lines going down and to the right:
788 null,
647 /*
789 null,
648 for (int x = (int)(-this.squaresAcross/2); x < this.squaresAcross; x++)
790 null,
649 {
791 null,
650 int rowOffset = 0;
792 camera.get_transformation(GraphicsDevice));
651
793 #if DEBUG
652 float startX = (x * Tile.TileStepX) + baseOffsetX - (Tile.TileStepX / 2);
653
654 Vector2 start = new Vector2(startX, -baseOffsetY+4);
655 Vector2 stop = new Vector2(startX + this.squaresAcross* Tile.TileStepX/2,
656 this.squaresDown*Tile.TileStepY- baseOffsetY+4);
657
658
659
794
660 Line.drawLine(batch,
795 var translucent = new Color(1.0f, 1.0f, 1.0f, 0.25f);
661 Line.departurePoint(stop, start, this.squaresAcross * Tile.TileWidth, this.squaresDown * Tile.TileHeight),
796 drawTileAt(4, 4, 140, 3, translucent);
662 Line.departurePoint(start, stop, this.squaresAcross * Tile.TileWidth, this.squaresDown * Tile.TileHeight),
797 drawTileAt(6, 4, 141, 3, translucent);
663 Color.White, 0.8f);
798 drawTileAt(8, 4, 142, 2, translucent);
664
799 drawTileAt(10, 4, 142, 3, translucent);
665 }
666 //Lines going down and to the left:
667 for (int x = 0; x < (int)(1.5*this.squaresAcross); x++)
668 {
669
670 float startX = (x * Tile.TileStepX) + baseOffsetX - (Tile.TileStepX / 2);
671
800
672 Vector2 start_reverse = new Vector2(startX, -baseOffsetY + 4);
801 for (int i = 10; i < 199; i++) {
673 Vector2 stop_reverse = new Vector2(startX + -(this.squaresAcross * Tile.TileStepX / 2),
802 drawTileAt(10, i, 281, 1, translucent);
674 (this.squaresDown * Tile.TileStepY) - baseOffsetY + 4);
803 }
675
804 drawTileAt(10, 199, 284, 1, translucent);
676 Line.drawLine(batch,
805 drawTileAt(11, 199, 280, 1, translucent);
677 Line.departurePoint(stop_reverse, start_reverse, this.squaresAcross * Tile.TileWidth, this.squaresDown * Tile.TileHeight),
806 drawTileAt(12, 199, 280, 1, translucent);
678 Line.departurePoint(start_reverse, stop_reverse, this.squaresAcross * Tile.TileWidth, this.squaresDown * Tile.TileHeight),
807 drawTileAt(13, 199, 283, 1, translucent);
679 Color.White, 0.8f);
808 drawTileAt(13, 198, 281, 1, translucent);
680
809 drawTileAt(13, 197, 282, 1, translucent);
681 }
810 drawTileAt(12, 197, 285, 1, translucent);
682 */
811 drawTileAt(12, 25, 300, 2, translucent);
812 #endif
683
813
684 #if DEBUG
814 #if DEBUG
685 drawTileAt(4, 4, 140, 3);
815 Tile.OutlineSquare(tileBatch, 1, 1, Color.Red, 2);
686 drawTileAt(6, 4, 141, 3);
816 Tile.OutlineSquare(tileBatch, 3, 1, Color.Blue, 2);
687 drawTileAt(8, 4, 142, 2);
817 Tile.OutlineSquare(tileBatch, 5, 1, Color.Green, 2);
688 drawTileAt(10, 4, 142, 3);
818 Tile.OutlineSquare(tileBatch, 7, 1, Color.Orange, 2);
689 #endif
819 Tile.OutlineSquare(tileBatch, 9, 1, Color.Orange, 3);
690
691 #region draw_cursor
692
693 if (MathUtils.Between(this.mouseGrid.X, 0, this.simulation.map.MapWidth)
694 && MathUtils.Between(this.mouseGrid.Y, 0, this.simulation.map.MapHeight))
695 {
696 Tile.OutlineSquare(batch, this.mouseGrid.X, this.mouseGrid.Y, Color.Yellow, 1);
697 }
698
699 #if DEBUG
700 Tile.OutlineSquare(batch, 1, 1, Color.Red, 2);
701 Tile.OutlineSquare(batch, 3, 1, Color.Blue, 2);
702 Tile.OutlineSquare(batch, 5, 1, Color.Green, 2);
703 Tile.OutlineSquare(batch, 7, 1, Color.Orange, 2);
704 Tile.OutlineSquare(batch, 9, 1, Color.Orange, 3);
705
820
706 //donut
821 //donut
707 Tile.DrawOutlinedSquares(batch, new Vector2[] {new Vector2(19, 1), new Vector2(19, 2), new Vector2(20, 1), new Vector2(21, 1),
822 Tile.DrawOutlinedSquares(tileBatch, new Vector2[] {new Vector2(19, 1), new Vector2(19, 2), new Vector2(20, 1), new Vector2(21, 1),
708 new Vector2(21, 2), new Vector2(19, 3), new Vector2(20, 3), new Vector2(21, 3)
823 new Vector2(21, 2), new Vector2(19, 3), new Vector2(20, 3), new Vector2(21, 3)
709 }, Color.Purple);
824 }, Color.Purple);
710
825
711 Quad.FillSquare2(batch, 7, 4, Color.Orange, 1.0f, 0.79f);
826 Quad.FillSquare2(tileBatch, 7, 4, Color.Orange, 1.0f, 0.79f);
712 Quad.FillSquare2(batch, 7, 3, Color.Yellow, 1.0f, 0.79f);
827 Quad.FillSquare2(tileBatch, 7, 3, Color.Yellow, 1.0f, 0.79f);
713 Quad.FillSquare2(batch, 7, 5, Color.Yellow, .5f, 0.79f);
828 Quad.FillSquare2(tileBatch, 7, 5, Color.Yellow, .5f, 0.79f);
714 Quad.FillSquare2(batch, 7, 6, Color.Yellow, .25f, 0.79f);
829 Quad.FillSquare2(tileBatch, 7, 6, Color.Yellow, .25f, 0.79f);
715 Quad.FillSquare2(batch, 7, 7, Color.Yellow, .125f, 0.79f);
830 Quad.FillSquare2(tileBatch, 7, 7, Color.Yellow, .125f, 0.79f);
716 Quad.FillSquare2(batch, 8, 5, Color.Teal, .5f, 0.79f);
831 Quad.FillSquare2(tileBatch, 8, 5, Color.Teal, .5f, 0.79f);
717 Quad.FillSquare2(batch, 8, 6, Color.Teal, .25f, 0.79f);
832 Quad.FillSquare2(tileBatch, 8, 6, Color.Teal, .25f, 0.79f);
718 Quad.FillSquare2(batch, 8, 7, Color.Teal, .125f, 0.79f);
833 Quad.FillSquare2(tileBatch, 8, 7, Color.Teal, .125f, 0.79f);
719 #endif
834 #endif
720
835
721 #endregion draw_cursor
722
723 stopWatch2 = new Stopwatch();
836 stopWatch2 = new Stopwatch();
724 stopWatch2.Start();
837 stopWatch2.Start();
725 #region draw_trees
838 #region draw_trees
@@ -728,21 +841,23
728 {
841 {
729 for (int j = 0; j < this.simulation.map.MapWidth; j += 1)
842 for (int j = 0; j < this.simulation.map.MapWidth; j += 1)
730 {
843 {
731 if (this.simulation.map.cells[i][j].hasTree)
844 if (this.simulation.map.cells[i][j].HasTree)
732 { //until we actually simulate:
845 { //until we actually simulate:
733 drawTileAt(i, j, 142, 2);
846 if (this.simulation.map.cells[i][j].Type == TreeType.GenericDeciduous) {
734 // if ((i + j) % 8 == 0)
847 drawTileAt(i, j, 252, 2); // 142, , 262
735 // {
848 }
736 // drawTileAt(i, j, 141, 2);
849 else if (this.simulation.map.cells[i][j].Type == TreeType.Oak) {
737 // }
850 drawTileAt(i, j, 142, 2);
738 // else
851 }
739 // {
852 else if (this.simulation.map.cells[i][j].Type == TreeType.GenericShrub) {
740 // drawTileAt(i, j, 142, 2);
853 drawTileAt(i, j, 210, 2);
741 // }
854 }
855 else {
856 drawTileAt(i, j, 122, 2); //122, 203, 221
857 }
742 }
858 }
743 else if (this.simulation.map.cells[i][j].status == CellStatus.DeadTree) {
859 else if (this.simulation.map.cells[i][j].Status == CellStatus.DeadTree) {
744 drawTileAt(i, j, 141, 2);
860 drawTileAt(i, j, 141, 2);
745 // System.Console.WriteLine(String.Format("Drew Dead Tree at {0},{1}", i, j));
746 }
861 }
747 }
862 }
748 }
863 }
@@ -757,11 +872,17
757 drawTileAt(3, 2, 140, 2);
872 drawTileAt(3, 2, 140, 2);
758 #endif
873 #endif
759
874
875 stopWatch2 = new Stopwatch();
876 stopWatch2.Start();
760 World.Draw();
877 World.Draw();
761 // _imGuiRenderer.AfterLayout();
878 // _imGuiRenderer.AfterLayout();
762 batch.End();
879 tileBatch.End();
880 stopWatch2.Stop();
881 this.rendererDrawTime = stopWatch2.Elapsed;
763
882
764 #region draw_header
883 #region draw_header
884 stopWatch2 = new Stopwatch();
885 stopWatch2.Start();
765 batch.Begin(SpriteSortMode.BackToFront,
886 batch.Begin(SpriteSortMode.BackToFront,
766 BlendState.AlphaBlend,
887 BlendState.AlphaBlend,
767 null,
888 null,
@@ -772,16 +893,37
772 if (MathUtils.BetweenExclusive(this.mouseGrid.X, 0, this.squaresAcross)
893 if (MathUtils.BetweenExclusive(this.mouseGrid.X, 0, this.squaresAcross)
773 && MathUtils.BetweenExclusive(this.mouseGrid.Y, 0, this.squaresAcross))
894 && MathUtils.BetweenExclusive(this.mouseGrid.Y, 0, this.squaresAcross))
774 {
895 {
775 has_tree = this.simulation.map.cells[(int)this.mouseGrid.X][(int)this.mouseGrid.Y].hasTree;
896 has_tree = this.simulation.map.cells[(int)this.mouseGrid.X][(int)this.mouseGrid.Y].HasTree;
776 }
897 }
777
898
778 String status_left = "";
899 String status_left = "";
779 if (MathUtils.BetweenExclusive(this.mouseGrid.X, -1, this.simulation.map.MapWidth)
900 if (MathUtils.BetweenExclusive(this.mouseGrid.X, -1, this.simulation.map.MapWidth)
780 && MathUtils.BetweenExclusive(this.mouseGrid.Y, -1, this.simulation.map.MapHeight))
901 && MathUtils.BetweenExclusive(this.mouseGrid.Y, -1, this.simulation.map.MapHeight))
781 {
902 {
782 status_left = String.Format("{0:},{1:} {2} ({3})", this.mouseGrid.X, this.mouseGrid.Y,
903 var cellStatus = this.simulation.map.cells[(int)this.mouseGrid.X][(int)this.mouseGrid.Y].Status;
783 this.simulation.map.cells[(int)this.mouseGrid.X][(int)this.mouseGrid.Y].status,
904 var treeStatusAdjective = this.simulation.map.cells[(int)this.mouseGrid.X][(int)this.mouseGrid.Y].StatusAdjective;
784 this.in_active_zone ? "Contracted" : (this.in_zone ? "Proposed Contract": "Unused"));
905 var treeType = this.simulation.map.cells[(int)this.mouseGrid.X][(int)this.mouseGrid.Y].TypeName;
906 var useStatus = this.CurrentStatus();
907 if (cellStatus == CellStatus.Water) {
908
909 status_left = String.Format("{0:},{1:} Water ({2})", this.mouseGrid.X, this.mouseGrid.Y, useStatus);
910 }
911 else if (cellStatus != CellStatus.Clear)
912 {
913 status_left = String.Format("{0:},{1:} {2} {3} ({4})", this.mouseGrid.X, this.mouseGrid.Y,
914 treeStatusAdjective,
915 treeType,
916 useStatus);
917 }
918 else if (this.has_tower) {
919 status_left = String.Format("{0:},{1:} Watch Tower ({2})", this.mouseGrid.X, this.mouseGrid.Y,
920 useStatus);
921 }
922 else {
923 status_left = String.Format("{0:},{1:} {2} ({3})", this.mouseGrid.X, this.mouseGrid.Y,
924 treeStatusAdjective,
925 useStatus);
926 }
785 }
927 }
786
928
787 String header_left = String.Format("${0:}|{1:} \ue124", this.simulation.money, this.simulation.map.tree_count);
929 String header_left = String.Format("${0:}|{1:} \ue124", this.simulation.money, this.simulation.map.tree_count);
@@ -804,22 +946,26
804 batch.DrawString(monoFont, status_left, new Vector2(1, top), Color.Black, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);
946 batch.DrawString(monoFont, status_left, new Vector2(1, top), Color.Black, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);
805 batch.DrawString(monoFont, header_left, new Vector2(1, 1), Color.Black, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);
947 batch.DrawString(monoFont, header_left, new Vector2(1, 1), Color.Black, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);
806 batch.DrawString(monoFont, header_middle, new Vector2(middle_start, 1), Color.Black, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);
948 batch.DrawString(monoFont, header_middle, new Vector2(middle_start, 1), Color.Black, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);
949
807 #endregion draw_header
950 #endregion draw_header
808
951
952
953
954 #region window
955 Menu.Render(debugWindow.monoFont, FNAGame.width, this.imGuiWindowBridgeEngine, ref quit, ref this.simulation.paused, ref this.simulation.currentRate, ref this.showBudget, header_left);
956 stopWatch2.Stop();
957 this.miscUIDrawTime = stopWatch2.Elapsed;
958
809 #region budget
959 #region budget
810
960
811 if (this.showBudget)
961 if (this.showBudget)
812 {
962 {
813 budgetWindow.draw(batch);
963 budgetWindow.draw(batch);
814 }
964 }
965 batch.End();
815
966
816 #endregion budget
967 #endregion budget
817
968
818 batch.End();
819
820 #region window
821 Menu.Render(debugWindow.monoFont, FNAGame.width, this.imGuiWindowBridgeEngine, ref quit, ref this.simulation.paused, ref this.simulation.currentRate, ref this.showBudget, header_left);
822
823 if (quit) {
969 if (quit) {
824 System.Environment.Exit(0);
970 System.Environment.Exit(0);
825 }
971 }
@@ -866,12 +1012,17
866
1012
867
1013
868 #region debug_window
1014 #region debug_window
1015 stopWatch2 = new Stopwatch();
1016 stopWatch2.Start();
869 //Calcs for debug window:
1017 //Calcs for debug window:
870 past_draw.Enqueue(this.drawTime);
1018 // past_draw.Enqueue(this.drawTime);
871 if ((this.frameCounter % 15) == 0)
1019 if (this.totalFrameCounter > 60 && ((this.frameCounter % 15) == 0))
872 {
1020 {
1021 past_draw_millis.Add((float)this.drawTime.TotalMilliseconds);
1022 past_draw_millis.Sort();
873 past_fps.Enqueue(this.frameRate);
1023 past_fps.Enqueue(this.frameRate);
874
1024 past_fps_sorted.Add(this.frameRate);
1025 past_fps_sorted.Sort();
875
1026
876 /*
1027 /*
877 if (this.frameRate > 60.0)
1028 if (this.frameRate > 60.0)
@@ -903,7 +1054,12
903 treeDrawTime = this.treeDrawTime,
1054 treeDrawTime = this.treeDrawTime,
904 gridDrawTime = this.gridDrawTime,
1055 gridDrawTime = this.gridDrawTime,
905 tileDrawTime = this.tileDrawTime,
1056 tileDrawTime = this.tileDrawTime,
1057 rendererDrawTime = this.rendererDrawTime,
1058 miscUIDrawTime = this.miscUIDrawTime,
1059 debugDrawTime = this.debugDrawTime,
906 updateTime = this.updateTime,
1060 updateTime = this.updateTime,
1061 worldUpdateTime = this.worldUpdateTime,
1062 simulationUpdateTime = this.simulationUpdateTime,
907 treeCount = this.simulation.map.tree_count,
1063 treeCount = this.simulation.map.tree_count,
908 mouseGrid = this.mouseGrid,
1064 mouseGrid = this.mouseGrid,
909 hasTree = has_tree,
1065 hasTree = has_tree,
@@ -940,15 +1096,16
940 additionalInfo.Add("Dialog entries", entries);
1096 additionalInfo.Add("Dialog entries", entries);
941 additionalInfo.Add("Metadata entries", descriptions);
1097 additionalInfo.Add("Metadata entries", descriptions);
942
1098
943 if (past_fps.Count() > 5) {
1099 if ((past_fps_sorted.Count() > 5) && show_another_window) {
944 additionalInfo.Add(".01%% fps", MathUtils.Percentile(past_fps.Skip(5).ToArray(), 0.0001f).ToString());
1100 var past_fps_floats = past_fps_sorted.ToArray();
945 additionalInfo.Add(".1%% fps", MathUtils.Percentile(past_fps.Skip(5).ToArray(), 0.001f).ToString());
1101 additionalInfo.Add(".01%% fps", MathUtils.Percentile(past_fps_floats, 0.0001f).ToString());
946 additionalInfo.Add("1%% fps", MathUtils.Percentile(past_fps.Skip(5).ToArray(), 0.01f).ToString());
1102 additionalInfo.Add(".1%% fps", MathUtils.Percentile(past_fps_floats, 0.001f).ToString());
947 additionalInfo.Add("50%% fps", MathUtils.Percentile(past_fps.Skip(5).ToArray(), 0.50f).ToString());
1103 additionalInfo.Add("1%% fps", MathUtils.Percentile(past_fps_floats, 0.01f).ToString());
1104 additionalInfo.Add("50%% fps", MathUtils.Percentile(past_fps_floats, 0.50f).ToString());
948 }
1105 }
949
1106
950 if (past_draw.Count() > 5) {
1107 if ((past_draw_millis.Count() > 5) && show_another_window) {
951 var past_draw_floats = past_draw.Skip(5).Select(ts => ts.TotalMilliseconds).ToArray();
1108 var past_draw_floats = past_draw_millis.ToArray();
952 additionalInfo.Add(".01%% draw", MathUtils.Percentile(past_draw_floats, 0.0001f).ToString());
1109 additionalInfo.Add(".01%% draw", MathUtils.Percentile(past_draw_floats, 0.0001f).ToString());
953 additionalInfo.Add(".1%% draw", MathUtils.Percentile(past_draw_floats, 0.001f).ToString());
1110 additionalInfo.Add(".1%% draw", MathUtils.Percentile(past_draw_floats, 0.001f).ToString());
954 additionalInfo.Add("1%% draw", MathUtils.Percentile(past_draw_floats, 0.01f).ToString());
1111 additionalInfo.Add("1%% draw", MathUtils.Percentile(past_draw_floats, 0.01f).ToString());
@@ -958,10 +1115,15
958 additionalInfo.Add("99.99%% draw", MathUtils.Percentile(past_draw_floats, 0.9999f).ToString());
1115 additionalInfo.Add("99.99%% draw", MathUtils.Percentile(past_draw_floats, 0.9999f).ToString());
959 }
1116 }
960
1117
1118 additionalInfo.Add("Total frames", totalFrameCounter.ToString());
1119
961 debugWindow.Layout(debugInfo, additionalInfo, ref show_another_window);
1120 debugWindow.Layout(debugInfo, additionalInfo, ref show_another_window);
962
1121
963 _imGuiRenderer.AfterLayout();
1122 _imGuiRenderer.AfterLayout();
964
1123
1124 stopWatch2.Stop();
1125 this.debugDrawTime = stopWatch2.Elapsed;
1126
965 #endregion debug_window
1127 #endregion debug_window
966
1128
967 stopWatch.Stop();
1129 stopWatch.Stop();
@@ -5,7 +5,6
5 using System.Collections.Generic;
5 using System.Collections.Generic;
6 using System.Runtime.InteropServices;
6 using System.Runtime.InteropServices;
7
7
8 using ImPlotNET;
9
8
10 namespace ImGuiNET.SampleProgram.XNA
9 namespace ImGuiNET.SampleProgram.XNA
11 {
10 {
@@ -45,9 +44,6
45 {
44 {
46 var context = ImGui.CreateContext();
45 var context = ImGui.CreateContext();
47 ImGui.SetCurrentContext(context);
46 ImGui.SetCurrentContext(context);
48 var plotContext = ImPlot.CreateContext();
49 ImPlot.SetCurrentContext(plotContext);
50 ImPlot.SetImGuiContext(context);
51
47
52 _game = game ?? throw new ArgumentNullException(nameof(game));
48 _game = game ?? throw new ArgumentNullException(nameof(game));
53 _graphicsDevice = game.GraphicsDevice;
49 _graphicsDevice = game.GraphicsDevice;
@@ -52,12 +52,12
52 private static Dictionary<LogLevel, (ConsoleColor, ConsoleColor)> mappings = new Dictionary<LogLevel, (ConsoleColor, ConsoleColor)>
52 private static Dictionary<LogLevel, (ConsoleColor, ConsoleColor)> mappings = new Dictionary<LogLevel, (ConsoleColor, ConsoleColor)>
53 {
53 {
54 {LogLevel.Critical, (ConsoleColor.White, ConsoleColor.Red)},
54 {LogLevel.Critical, (ConsoleColor.White, ConsoleColor.Red)},
55 {LogLevel.Error, (ConsoleColor.Red, ConsoleColor.Black)},
55 {LogLevel.Error, (ConsoleColor.Black, ConsoleColor.Red)},
56 {LogLevel.Warning, (ConsoleColor.Yellow, ConsoleColor.Black)},
56 {LogLevel.Warning, (ConsoleColor.Black, ConsoleColor.Yellow)},
57 {LogLevel.Success, (ConsoleColor.Green, ConsoleColor.Black)},
57 {LogLevel.Success, (ConsoleColor.White, ConsoleColor.Green)},
58 {LogLevel.Info, (ConsoleColor.Blue, ConsoleColor.Black)},
58 {LogLevel.Info, (ConsoleColor.White, ConsoleColor.Blue)},
59 {LogLevel.Debug, (ConsoleColor.White, ConsoleColor.Cyan)},
59 {LogLevel.Debug, (ConsoleColor.Blue, ConsoleColor.Black)},
60 {LogLevel.Trace, (ConsoleColor.White, ConsoleColor.Yellow)},
60 {LogLevel.Trace, (ConsoleColor.Magenta, ConsoleColor.Black)},
61 {LogLevel.Spy, (ConsoleColor.Black, ConsoleColor.White)},
61 {LogLevel.Spy, (ConsoleColor.Black, ConsoleColor.White)},
62
62
63 };
63 };
@@ -6,5 +6,7
6 public struct SetOptionMessage : IMessage
6 public struct SetOptionMessage : IMessage
7 {
7 {
8 public ProfanityLevel NewProfanitySetting;
8 public ProfanityLevel NewProfanitySetting;
9 public float NewSoundEffectVolume;
10 public bool NewSoundEffectMuted;
9 }
11 }
10 }
12 }
@@ -1,4 +1,3
1
2 using Encompass;
1 using Encompass;
3
2
4 namespace isometricparkfna.Messages
3 namespace isometricparkfna.Messages
@@ -17,7 +16,7
17 Options,
16 Options,
18 NewGame,
17 NewGame,
19 Dialog,
18 Dialog,
20 Graph,
19 Graph,
21 }
20 }
22
21
23
22
@@ -10,28 +10,34
10 Uncensored,
10 Uncensored,
11 Minced,
11 Minced,
12 Removed
12 Removed
13
14 }
13 }
15
14
16 public class Options
15 public class Options
17 {
16 {
18
19 public string fontName;
17 public string fontName;
20 public int fontSize;
18 public int fontSize;
21 public ProfanityLevel profanitySetting;
19 public ProfanityLevel profanitySetting;
22
20
23 public Options(string fontName, int fontSize, ProfanityLevel profanitySetting)
21 //Sound
22 public float SoundEffectVolume;
23 public bool SoundEffectMuted;
24
25 public Options(string fontName, int fontSize, ProfanityLevel profanitySetting,
26 float soundEffectVolume, bool soundEffectMuted)
24 {
27 {
25 this.fontName = fontName;
28 this.fontName = fontName;
26 this.fontSize = fontSize;
29 this.fontSize = fontSize;
27 this.profanitySetting = profanitySetting;
30 this.profanitySetting = profanitySetting;
28
31
32 this.SoundEffectVolume = soundEffectVolume;
33 this.SoundEffectMuted = soundEffectMuted;
29 }
34 }
30
35
31 public static void writeOptions(string fontName, int fontSize, ProfanityLevel profanitySetting)
36 public static void writeOptions(string fontName, int fontSize, ProfanityLevel profanitySetting,
37 float soundEffectVolume, bool soundEffectMuted)
32 {
38 {
33
39 var options = new Options(fontName, fontSize, profanitySetting, soundEffectVolume,
34 var options = new Options(fontName, fontSize, profanitySetting);
40 soundEffectMuted);
35
41
36 string json = JsonConvert.SerializeObject(options,
42 string json = JsonConvert.SerializeObject(options,
37 Formatting.Indented);
43 Formatting.Indented);
@@ -44,19 +50,13
44 public static Options readOptions()
50 public static Options readOptions()
45 {
51 {
46 var json = File.ReadAllText(@"options.json");
52 var json = File.ReadAllText(@"options.json");
47 Logging.Spy(new {json=json});
53 Logging.Debug(new {json=json}.ToString());
48
54
49 Options options = JsonConvert.DeserializeObject<Options>(json);
55 Options options = JsonConvert.DeserializeObject<Options>(json);
50
56
51 Logging.Spy(new {name=options.fontName,
52 size=options.fontSize
53 });
54 Logging.Success("Read options.");
57 Logging.Success("Read options.");
55
58
56 return options;
59 return options;
57 }
60 }
58
59
60
61 }
61 }
62 }
62 }
@@ -1,4 +1,3
1
2 using Microsoft.Xna.Framework;
1 using Microsoft.Xna.Framework;
3 using Microsoft.Xna.Framework.Graphics;
2 using Microsoft.Xna.Framework.Graphics;
4
3
@@ -15,7 +14,6
15 private SpriteBatch batch;
14 private SpriteBatch batch;
16 private SpriteFont font;
15 private SpriteFont font;
17
16
18
19 public AreaRenderer(SpriteBatch batch, SpriteFont font)
17 public AreaRenderer(SpriteBatch batch, SpriteFont font)
20 {
18 {
21 this.batch = batch;
19 this.batch = batch;
@@ -26,32 +24,38
26 public override void Render()
24 public override void Render()
27 {
25 {
28
26
29 var budgetWindow = new BudgetWindow(new Budget { }, this.font, 0, 0);
27 var budgetWindow = new BudgetWindow(new Budget {}, this.font, 0, 0);
30
28
31 foreach (ref readonly var entity in ReadEntities<AreaComponent>())
29 foreach (ref readonly var entity in ReadEntities<AreaComponent>())
32 {
30 {
33 var areaComponent = GetComponent<AreaComponent>(entity);
31 var areaComponent = GetComponent<AreaComponent>(entity);
34 // var SelectedComponent = GetComponent<SelectedComponent>(entity);
32 // var SelectedComponent = GetComponent<SelectedComponent>(entity);
33 var selected = GetComponent<SelectedComponent>(entity).selected;
35
34
36 if (!HasComponent<ContractStatusComponent>(entity)
35 if (HasComponent<PreserveComponent>(entity) || areaComponent.Tool == Tool.Preserve)
37 || GetComponent<ContractStatusComponent>(entity).status == ContractStatus.Accepted
36 {
38 )
37 Quad.FillSquares(batch, areaComponent.squares, Color.Blue, 0.5f, 0.79f);
38 Tile.DrawOutlinedSquares(batch, areaComponent.squares, Color.Blue);
39 }
40 else if (!HasComponent<ContractStatusComponent>(entity))
41 {
42 Quad.FillSquares(batch, areaComponent.squares, Color.Red, 0.5f, 0.79f);
43 Tile.DrawOutlinedSquares(batch, areaComponent.squares, Color.Red);
44 }
45 else if ((!HasComponent<ContractStatusComponent>(entity)
46 || GetComponent<ContractStatusComponent>(entity).status == ContractStatus.Accepted)
47 && !selected)
39 {
48 {
40 Tile.DrawOutlinedSquares(batch, areaComponent.squares, Color.Teal);
49 Tile.DrawOutlinedSquares(batch, areaComponent.squares, Color.Teal);
41 Quad.FillSquares(batch, areaComponent.squares, Color.Teal, 0.5f, 0.79f);
50 Quad.FillSquares(batch, areaComponent.squares, Color.Teal, 0.5f, 0.78f);
42 }
51 }
43
52 else if (HasComponent<ContractStatusComponent>(entity)
44 var selected = GetComponent<SelectedComponent>(entity).selected;
53 && selected)
45
46 if (HasComponent<ContractStatusComponent>(entity)
47 && selected
48 // && GetComponent<SelectedComponent>(entity).selected
49 )
50 {
54 {
51 Tile.DrawOutlinedSquares(batch, areaComponent.squares, Color.Teal);
55 Tile.DrawOutlinedSquares(batch, areaComponent.squares, Color.Teal);
52 Quad.FillSquares(batch, areaComponent.squares, Color.Gray, 0.5f, 0.80f);
56 Quad.FillSquares(batch, areaComponent.squares, Color.Gray, 0.5f, 0.78f);
53 }
57 }
54 }
58 }
55 }
59 }
56 }
60 }
57 } No newline at end of file
61 }
@@ -93,10 +93,12
93 var dialog_open = false;
93 var dialog_open = false;
94
94
95 ProfanityLevel profanityLevel = default;
95 ProfanityLevel profanityLevel = default;
96 OptionsComponent options_component = default;
96
97
97 foreach (ref readonly var entity in ReadEntities<OptionsComponent>())
98 foreach (ref readonly var entity in ReadEntities<OptionsComponent>())
98 {
99 {
99 profanityLevel = GetComponent<OptionsComponent>(entity).ProfanitySetting;
100 options_component = GetComponent<OptionsComponent>(entity);
101 profanityLevel = options_component.ProfanitySetting;
100 }
102 }
101
103
102
104
@@ -116,7 +118,9
116
118
117 foreach (var e in contracts)
119 foreach (var e in contracts)
118 {
120 {
119 contract_data.Add(getContractDetails(e));
121 if(HasComponent<ContractStatusComponent>(e)) {
122 contract_data.Add(getContractDetails(e));
123 }
120 }
124 }
121
125
122 ContractsWindow.Render(this.BridgeEngine.font, this.BridgeEngine, contract_data);
126 ContractsWindow.Render(this.BridgeEngine.font, this.BridgeEngine, contract_data);
@@ -143,13 +147,13
143 InGameMenu.Render(this.BridgeEngine.font, this.BridgeEngine, width);
147 InGameMenu.Render(this.BridgeEngine.font, this.BridgeEngine, width);
144 break;
148 break;
145 case Window.Options:
149 case Window.Options:
146 OptionsWindow.Render(this.BridgeEngine.font, this.BridgeEngine.italicFont, this.BridgeEngine, width, profanityLevel);
150 OptionsWindow.Render(this.BridgeEngine.font, this.BridgeEngine.italicFont, this.BridgeEngine, width);
147 break;
151 break;
148 case Window.NewGame:
152 case Window.NewGame:
149 NewGameWindow.Render(this.BridgeEngine.font, this.BridgeEngine.italicFont, this.BridgeEngine);
153 NewGameWindow.Render(this.BridgeEngine.font, this.BridgeEngine.italicFont, this.BridgeEngine);
150 break;
154 break;
151 case Window.Graph:
155 case Window.Graph:
152 GraphWindow.Render(this.BridgeEngine.font, this.simulation, this.BridgeEngine);
156 GraphWindow.Render(this.BridgeEngine.font, this.simulation, this.BridgeEngine);
153 break;
157 break;
154 case Window.Dialog:
158 case Window.Dialog:
155 dialog_count++;
159 dialog_count++;
@@ -29,6 +29,7
29 public decimal tree_clearing;
29 public decimal tree_clearing;
30 public decimal miscellaneous;
30 public decimal miscellaneous;
31 public decimal enforcement;
31 public decimal enforcement;
32 public decimal construction;
32
33
33
34
34 public decimal final_money;
35 public decimal final_money;
@@ -39,6 +40,8
39 public int trees;
40 public int trees;
40 public int dead_trees;
41 public int dead_trees;
41 public int crowded_trees;
42 public int crowded_trees;
43 public int preserve_cells;
44 //Kind of a hack but allows for tracking figures over time without creating a whole new infrastructure
42
45
43 }
46 }
44
47
@@ -54,16 +57,24
54 }
57 }
55 }
58 }
56
59
57
58 private const float SPONTANEOUS_NEW_TREE_CHANCE = 0.9995f;
60 private const float SPONTANEOUS_NEW_TREE_CHANCE = 0.9995f;
59 private const float NEIGHBOR_NEW_TREE_CHANCE = 0.995f;
61 private const float NEIGHBOR_NEW_TREE_CHANCE = 0.995f;
60 private const float NEIGHBOR_CROWDS_TREE_CHANCE = 0.995f;
62 private const float NEIGHBOR_CROWDS_TREE_CHANCE = 0.995f;
61
63
64 private const float PRESERVE_SPONTANEOUS_NEW_TREE_CHANCE = 0.9990f;
65 private const float PRESERVE_NEIGHBOR_NEW_TREE_CHANCE = 0.995f;
66 private const float PRESERVE_NEIGHBOR_CROWDS_TREE_CHANCE = 0.9990f;
67
62 public const int TREE_PLANT_COST = 500;
68 public const int TREE_PLANT_COST = 500;
63 public const int TREE_CLEAR_COST = 250;
69 public const int TREE_CLEAR_COST = 250;
64
70
65 public const int MAX_TREES_TO_PLANT = 25;
71 public const int MAX_TREES_TO_PLANT = 50;
66 public const int MAX_TREES_TO_CLEAR = 25;
72 public const int MAX_TREES_TO_CLEAR = 50;
73
74 public const decimal STARTING_FUNDS = 100_000M;
75
76 public const int NUM_WATER_FEATURES = 5;
77 public const int NUM_PONDS = 12;
67
78
68 public SimulationBridgeEngine BridgeEngine { get; private set; }
79 public SimulationBridgeEngine BridgeEngine { get; private set; }
69
80
@@ -102,6 +113,8
102 public decimal enforcement;
113 public decimal enforcement;
103 public decimal misc;
114 public decimal misc;
104
115
116 public int preserve_cells;
117
105 public Budget latestBudget
118 public Budget latestBudget
106 {
119 {
107 get
120 get
@@ -123,7 +136,6
123 {
136 {
124 if (this.budgets.Count >= 2) {
137 if (this.budgets.Count >= 2) {
125 return this.budgets[this.budgets.Count - 2];
138 return this.budgets[this.budgets.Count - 2];
126
127 }
139 }
128 else
140 else
129 {
141 {
@@ -134,10 +146,10
134
146
135 public System.Collections.Generic.IEnumerable<Budget> allBudgets()
147 public System.Collections.Generic.IEnumerable<Budget> allBudgets()
136 {
148 {
137 foreach(var budget in this.budgets)
149 foreach(var budget in this.budgets)
138 {
150 {
139 yield return budget;
151 yield return budget;
140 }
152 }
141
153
142 }
154 }
143 private Grammar grammar;
155 private Grammar grammar;
@@ -169,6 +181,8
169
181
170 public CellMap map;
182 public CellMap map;
171
183
184 public int[,] PreserveCounts;
185
172 public int ticksPerAdvance;
186 public int ticksPerAdvance;
173 private float lastAdvance;
187 private float lastAdvance;
174 public bool paused;
188 public bool paused;
@@ -201,22 +215,21
201 public int crowded_trees
215 public int crowded_trees
202 {
216 {
203 get {
217 get {
204 return this.map.iterate_cells_with_neighbors(7).Where(c => c.hasTree).Count();
218 return this.map.iterate_cells_with_neighbors(7).Where(c => c.HasTree).Count();
205
206 }
219 }
207 }
220 }
208
221
209 public int dead_trees
222 public int dead_trees
210 {
223 {
211 get {
224 get {
212 return this.map.iterate_cells().Where(c => (c.status == CellStatus.DeadTree)).Count();
225 return this.map.iterate_cells().Where(c => (c.Status == CellStatus.DeadTree)).Count();
213 }
226 }
214 }
227 }
215
228
216 public float healthy_percent
229 public float healthy_percent
217 {
230 {
218 get {
231 get {
219 return (float)(this.map.tree_count - this.map.iterate_cells_with_neighbors(7).Where(c => c.hasTree).Count()) / this.map.tree_count * 100;
232 return (float)(this.map.tree_count - this.map.iterate_cells_with_neighbors(7).Where(c => c.HasTree).Count()) / this.map.tree_count * 100;
220 }
233 }
221 }
234 }
222
235
@@ -224,7 +237,7
224 {
237 {
225 get
238 get
226 {
239 {
227 return this.map.iterate_cells().Where(c => c.hasTree).Select(c => (this.DateTime - c.planted).Days / 365.0).Average();
240 return this.map.iterate_cells().Where(c => c.HasTree).Select(c => (this.DateTime - c.Planted).Days / 365.0).Average();
228 }
241 }
229 }
242 }
230
243
@@ -232,13 +245,10
232 {
245 {
233 get
246 get
234 {
247 {
235 return this.map.iterate_cells().Where(c => c.hasTree).Select(c => (this.DateTime - c.planted).Days / 365.0).Max();
248 return this.map.iterate_cells().Where(c => c.HasTree).Select(c => (this.DateTime - c.Planted).Days / 365.0).Max();
236 }
249 }
237 }
250 }
238
251
239 //Historical counts
240 // public List<int> tree_count
241
242 public Simulation(int width, int height, float[] millisecondsPerAdvance)
252 public Simulation(int width, int height, float[] millisecondsPerAdvance)
243 {
253 {
244 this.random = new Random();
254 this.random = new Random();
@@ -246,7 +256,7
246 this.DateTime = new DateTime(START_YEAR, START_MONTH, START_DAY);
256 this.DateTime = new DateTime(START_YEAR, START_MONTH, START_DAY);
247
257
248 this.map = new CellMap(width, height);
258 this.map = new CellMap(width, height);
249 this.money = 100000M;
259 this.money = STARTING_FUNDS;
250 this.millisecondsPerAdvance = millisecondsPerAdvance;
260 this.millisecondsPerAdvance = millisecondsPerAdvance;
251
261
252 this.paused = true;
262 this.paused = true;
@@ -254,6 +264,16
254 this.budgets = new List<Budget>();
264 this.budgets = new List<Budget>();
255
265
256 this.BridgeEngine = new SimulationBridgeEngine(this);
266 this.BridgeEngine = new SimulationBridgeEngine(this);
267
268 this.PreserveCounts = new int[this.map.MapWidth, this.map.MapHeight];
269 }
270
271 private double interpolate(double percent, double start, double end) {
272 var low = Math.Min(start, end);
273 var high = Math.Max(start, end);
274 var range = high - low;
275
276 return range * percent + low;
257 }
277 }
258
278
259 private void advanceSimulation()
279 private void advanceSimulation()
@@ -266,30 +286,42
266
286
267 this.BridgeEngine.addTick();
287 this.BridgeEngine.addTick();
268
288
269 foreach (Cell cell in this.map.iterate_cells())
289 // foreach (Cell cell in this.map.iterate_cells())
290 for(int i = 0; i < this.map.MapWidth; i++)
270 {
291 {
271 if (random.NextDouble() > SPONTANEOUS_NEW_TREE_CHANCE)
292 for(int j = 0; j < this.map.MapHeight; j++)
272 {
293 {
273 cell.addTree(this.DateTime);
294 var cell = this.map.cells[i][j];
295 var rate = interpolate(8 - (double)this.PreserveCounts[i, j] / 8.0d, PRESERVE_SPONTANEOUS_NEW_TREE_CHANCE, SPONTANEOUS_NEW_TREE_CHANCE);
296 if (random.NextDouble() > rate)
297 {
298 var random_type = random.Next(0, 4);
299 cell.AddTree(this.DateTime, (TreeType)random_type);
300 }
274 }
301 }
275 }
302 }
276
303
277 int new_planted = 0;
304 int new_planted = 0;
278 foreach (Cell cell in this.map.iterate_cells_with_neighbors(4))
305 foreach (var (x, y) in this.map.iterate_cell_locations_with_neighbors(4))
279 {
306 {
280 if (random.NextDouble() > NEIGHBOR_NEW_TREE_CHANCE)
307 var neighbor = this.map.iterate_neighbors(x, y).First();
308
309 if (random.NextDouble() > (this.PreserveCounts[x, y] > 0 ? PRESERVE_NEIGHBOR_NEW_TREE_CHANCE : NEIGHBOR_NEW_TREE_CHANCE ))
281 {
310 {
282 cell.addTree(this.DateTime);
311 var cell = this.map.cells[x][y];
312 var random_type = random.Next(0, 4);
313 cell.AddTree(this.DateTime, neighbor.Type);
283 new_planted += 1;
314 new_planted += 1;
284 }
315 }
285 }
316 }
286
317
287 int crowded_out = 0;
318 int crowded_out = 0;
288 foreach (Cell cell in this.map.iterate_cells_with_neighbors(7))
319 foreach (var (x, y) in this.map.iterate_cell_locations_with_neighbors(7))
289 {
320 {
290 if (random.NextDouble() > NEIGHBOR_CROWDS_TREE_CHANCE)
321 if (random.NextDouble() > (this.PreserveCounts[x, y] > 0 ? PRESERVE_NEIGHBOR_CROWDS_TREE_CHANCE : NEIGHBOR_CROWDS_TREE_CHANCE ) )
291 {
322 {
292 cell.markTreeDead();
323 var cell = this.map.cells[x][y];
324 cell.MarkTreeDead();
293 crowded_out += 1;
325 crowded_out += 1;
294 }
326 }
295 }
327 }
@@ -301,18 +333,19
301 int x = random.Next(0, this.map.MapWidth);
333 int x = random.Next(0, this.map.MapWidth);
302 Cell chosen_cell = this.map.cells[x][y];
334 Cell chosen_cell = this.map.cells[x][y];
303
335
304 if (!chosen_cell.hasTree) {
336 if (!chosen_cell.HasTree) {
305 chosen_cell.addTree(this.DateTime);
337 var random_type = random.Next(0, 4);
338 chosen_cell.AddTree(this.DateTime, (TreeType)random_type);
306 trees_to_plant -= 1;
339 trees_to_plant -= 1;
307 }
340 }
308 }
341 }
309
342
310 int trees_to_clear = this.tree_clearing;
343 int trees_to_clear = this.tree_clearing;
311 foreach (Cell cell in this.map.iterate_cells_with_neighbors(7).Where(c => c.hasTree))
344 foreach (Cell cell in this.map.iterate_cells_with_neighbors(7).Where(c => c.HasTree))
312 {
345 {
313 if (trees_to_clear > 0) {
346 if (trees_to_clear > 0) {
314 cell.removeTree();
315 trees_to_clear -= 1;
347 trees_to_clear -= 1;
348 cell.RemoveTree();
316 }
349 }
317 }
350 }
318
351
@@ -329,7 +362,8
329 upkeep = (int)(this.map.tree_count * 1.5),
362 upkeep = (int)(this.map.tree_count * 1.5),
330 tree_planting = this.tree_planting * Simulation.TREE_PLANT_COST,
363 tree_planting = this.tree_planting * Simulation.TREE_PLANT_COST,
331 tree_clearing = this.tree_clearing * Simulation.TREE_CLEAR_COST,
364 tree_clearing = this.tree_clearing * Simulation.TREE_CLEAR_COST,
332 misc = this.misc
365 misc = this.misc,
366 preserve_cells = this.preserve_cells
333 };
367 };
334
368
335 newBudget = this.applyBudget(newBudget); ;
369 newBudget = this.applyBudget(newBudget); ;
@@ -342,12 +376,10
342
376
343 public Budget applyBudget(Budget budget)
377 public Budget applyBudget(Budget budget)
344 {
378 {
345
346 this.money = budget.money
379 this.money = budget.money
347 - (budget.upkeep + budget.tree_planting + budget.tree_clearing + budget.enforcement)
380 - (budget.upkeep + budget.tree_planting + budget.tree_clearing + budget.enforcement)
348 + (budget.subsidy + budget.contracts + budget.misc);
381 + (budget.subsidy + budget.contracts + budget.misc);
349
382
350
351 budget.final_money = this.money;
383 budget.final_money = this.money;
352 budget.cashflow = budget.final_money - budget.money;
384 budget.cashflow = budget.final_money - budget.money;
353
385
@@ -360,6 +392,19
360 }
392 }
361 }
393 }
362
394
395 public void AddConstruction(decimal construction_amount)
396 {
397 if (this.budgets.Count >= 1) {
398 var budget = this.budgets[this.budgets.Count - 1];
399
400 budget.final_money -= construction_amount;
401 budget.construction += construction_amount;
402 budget.cashflow -= construction_amount;
403 this.budgets[this.budgets.Count - 1] = budget;
404 }
405 this.money -= construction_amount;
406 }
407
363 public void updateNews() {
408 public void updateNews() {
364 this.latestNewsItems = this.sourceNewsItems.Select(s => s.Flatten(this.grammar)).ToList().Shuffle();
409 this.latestNewsItems = this.sourceNewsItems.Select(s => s.Flatten(this.grammar)).ToList().Shuffle();
365 }
410 }
@@ -371,6 +416,7
371 this.updateNews();
416 this.updateNews();
372 }
417 }
373
418
419
374 public void update(TimeSpan deltaTime)
420 public void update(TimeSpan deltaTime)
375 {
421 {
376 if (!this.paused)
422 if (!this.paused)
@@ -394,7 +440,6
394 //through t=120, so that's what we want to track in lastAdvance.
440 //through t=120, so that's what we want to track in lastAdvance.
395 this.lastAdvance += advancesToSimulate * millisecondsPerAdvance;
441 this.lastAdvance += advancesToSimulate * millisecondsPerAdvance;
396 }
442 }
397
398 }
443 }
399 }
444 }
400 }
445 }
@@ -1,4 +1,5
1 using System;
1 using System;
2 using System.Diagnostics;
2 using System.Collections.Generic;
3 using System.Collections.Generic;
3 using System.Linq;
4 using System.Linq;
4
5
@@ -46,7 +47,7
46
47
47 static public Texture2D TileSetTexture;
48 static public Texture2D TileSetTexture;
48
49
49
50 public const float DEPTH = 0.79f;
50
51
51
52
52 public Tile()
53 public Tile()
@@ -55,7 +56,6
55 }
56 }
56
57
57
58
58
59 static public Rectangle GetSourceRectangle(int tileIndex)
59 static public Rectangle GetSourceRectangle(int tileIndex)
60 {
60 {
61 int tileY = tileIndex / (TileSetTexture.Width / TileWidth);
61 int tileY = tileIndex / (TileSetTexture.Width / TileWidth);
@@ -91,26 +91,26
91 new Vector2(((x - y) * Tile.TileSpriteWidth / 2), (x + y) * Tile.TileSpriteHeight / 2) + adjust2,
91 new Vector2(((x - y) * Tile.TileSpriteWidth / 2), (x + y) * Tile.TileSpriteHeight / 2) + adjust2,
92 //new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
92 //new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
93 new Vector2(((x - y + size) * Tile.TileSpriteWidth / 2), (x + y + size) * Tile.TileSpriteHeight / 2) + adjust2,
93 new Vector2(((x - y + size) * Tile.TileSpriteWidth / 2), (x + y + size) * Tile.TileSpriteHeight / 2) + adjust2,
94 color, 0.79f);
94 color, 0.77f);
95
95
96 //Bottom right
96 //Bottom right
97 Line.drawLine(batch,
97 Line.drawLine(batch,
98 new Vector2(((x + size - y) * Tile.TileSpriteWidth / 2), (x + size + y) * Tile.TileSpriteHeight / 2) + adjust2,
98 new Vector2(((x + size - y) * Tile.TileSpriteWidth / 2), (x + size + y) * Tile.TileSpriteHeight / 2) + adjust2,
99 //new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
99 //new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
100 new Vector2(((x + size - (y + size)) * Tile.TileSpriteWidth / 2), (x + size + (y + size)) * Tile.TileSpriteHeight / 2) + adjust2,
100 new Vector2(((x + size - (y + size)) * Tile.TileSpriteWidth / 2), (x + size + (y + size)) * Tile.TileSpriteHeight / 2) + adjust2,
101 color, 0.79f);
101 color, 0.77f);
102 //Bottom left
102 //Bottom left
103 Line.drawLine(batch,
103 Line.drawLine(batch,
104 new Vector2(((x - (y + size)) * Tile.TileSpriteWidth / 2), (x + y + size) * Tile.TileSpriteHeight / 2) + adjust2,
104 new Vector2(((x - (y + size)) * Tile.TileSpriteWidth / 2), (x + y + size) * Tile.TileSpriteHeight / 2) + adjust2,
105 //new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
105 //new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
106 new Vector2(((x + size - (y + size)) * Tile.TileSpriteWidth / 2), (x + size + (y + size)) * Tile.TileSpriteHeight / 2) + adjust2,
106 new Vector2(((x + size - (y + size)) * Tile.TileSpriteWidth / 2), (x + size + (y + size)) * Tile.TileSpriteHeight / 2) + adjust2,
107 color, 0.79f);
107 color, 0.77f);
108 //Upper left
108 //Upper left
109 Line.drawLine(batch,
109 Line.drawLine(batch,
110 new Vector2(((x - y) * Tile.TileSpriteWidth / 2), (x + y) * Tile.TileSpriteHeight / 2) + adjust2,
110 new Vector2(((x - y) * Tile.TileSpriteWidth / 2), (x + y) * Tile.TileSpriteHeight / 2) + adjust2,
111 //new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
111 //new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
112 new Vector2(((x - (y + size)) * Tile.TileSpriteWidth / 2), (x + (y + size)) * Tile.TileSpriteHeight / 2) + adjust2,
112 new Vector2(((x - (y + size)) * Tile.TileSpriteWidth / 2), (x + (y + size)) * Tile.TileSpriteHeight / 2) + adjust2,
113 color, 0.79f);
113 color, 0.77f);
114 }
114 }
115
115
116
116
@@ -128,26 +128,26
128 new Vector2(((x - y) * Tile.TileSpriteWidth / 2), (x + y) * Tile.TileSpriteHeight / 2) + adjust2,
128 new Vector2(((x - y) * Tile.TileSpriteWidth / 2), (x + y) * Tile.TileSpriteHeight / 2) + adjust2,
129 //new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
129 //new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
130 new Vector2(((x - y + size_less_one) * Tile.TileSpriteWidth / 2), (x + y + size_less_one) * Tile.TileSpriteHeight / 2) + adjust2,
130 new Vector2(((x - y + size_less_one) * Tile.TileSpriteWidth / 2), (x + y + size_less_one) * Tile.TileSpriteHeight / 2) + adjust2,
131 color, 0.79f);
131 color, Tile.DEPTH);
132
132
133 //Bottom right
133 //Bottom right
134 Line.drawLine(batch,
134 Line.drawLine(batch,
135 new Vector2(((x + size - y) * Tile.TileSpriteWidth / 2), (x + size_less_one + y) * Tile.TileSpriteHeight / 2) + adjust2,
135 new Vector2(((x + size - y) * Tile.TileSpriteWidth / 2), (x + size_less_one + y) * Tile.TileSpriteHeight / 2) + adjust2,
136 //new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
136 //new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
137 new Vector2(((x + size - (y + size)) * Tile.TileSpriteWidth / 2), (x + size_less_one + (y + size_less_one)) * Tile.TileSpriteHeight / 2) + adjust2,
137 new Vector2(((x + size - (y + size)) * Tile.TileSpriteWidth / 2), (x + size_less_one + (y + size_less_one)) * Tile.TileSpriteHeight / 2) + adjust2,
138 color, 0.79f);
138 color, Tile.DEPTH);
139 //Bottom left
139 //Bottom left
140 Line.drawLine(batch,
140 Line.drawLine(batch,
141 new Vector2(((x - (y + size)) * Tile.TileSpriteWidth / 2), (x + y + size) * Tile.TileSpriteHeight / 2) + adjust2,
141 new Vector2(((x - (y + size)) * Tile.TileSpriteWidth / 2), (x + y + size) * Tile.TileSpriteHeight / 2) + adjust2,
142 //new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
142 //new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
143 new Vector2(((x + size - (y + size)) * Tile.TileSpriteWidth / 2), (x + size + (y + size)) * Tile.TileSpriteHeight / 2) + adjust2,
143 new Vector2(((x + size - (y + size)) * Tile.TileSpriteWidth / 2), (x + size + (y + size)) * Tile.TileSpriteHeight / 2) + adjust2,
144 color, 0.79f);
144 color, Tile.DEPTH);
145 //Upper left
145 //Upper left
146 Line.drawLine(batch,
146 Line.drawLine(batch,
147 new Vector2(((x - y) * Tile.TileSpriteWidth / 2), (x + y) * Tile.TileSpriteHeight / 2) + adjust2,
147 new Vector2(((x - y) * Tile.TileSpriteWidth / 2), (x + y) * Tile.TileSpriteHeight / 2) + adjust2,
148 //new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
148 //new Vector2(this.squaresAcross * Tile.TileSpriteWidth, (y+1) * Tile.TileSpriteHeight),
149 new Vector2(((x - (y + size)) * Tile.TileSpriteWidth / 2), (x + (y + size)) * Tile.TileSpriteHeight / 2) + adjust2,
149 new Vector2(((x - (y + size)) * Tile.TileSpriteWidth / 2), (x + (y + size)) * Tile.TileSpriteHeight / 2) + adjust2,
150 color, 0.79f);
150 color, Tile.DEPTH);
151 }
151 }
152
152
153 public static void drawOutline(SpriteBatch batch, Color color) {
153 public static void drawOutline(SpriteBatch batch, Color color) {
@@ -193,14 +193,20
193 edges.Add(new Edge {Start=square, End=square + new Vector2(0, 1)});
193 edges.Add(new Edge {Start=square, End=square + new Vector2(0, 1)});
194 }
194 }
195
195
196 //Seems to be v. slow
196 edges = edges.GroupBy(x => x).Where(grp => grp.Count() == 1).Select(grp => grp.Key).ToList<Edge>();
197 edges = edges.GroupBy(x => x).Where(grp => grp.Count() == 1).Select(grp => grp.Key).ToList<Edge>();
197
198
198 drawEdges(batch, edges.ToArray(), color);
199 drawEdges(batch, edges.ToArray(), color);
199 }
200 }
200
201
202 public static void drawTileAt(SpriteBatch batch, int x, int y, int tileIndex, int height, float depth) {
203 drawTileAt(batch, x, y, tileIndex, height, depth, Color.White);
204 }
201
205
202 public static void drawTileAt(SpriteBatch batch, int x, int y, int tileIndex, int height, float depth)
206
203 {
207 public static void drawTileAt(SpriteBatch batch, int x, int y, int tileIndex, int height, float depth, Color color)
208 {
209 //new Color(100, 100, 100, 100)
204
210
205 int height_adjust = 0;
211 int height_adjust = 0;
206
212
@@ -224,7 +230,7
224 screeny,
230 screeny,
225 Tile.TileWidth, Tile.TileHeight * height),
231 Tile.TileWidth, Tile.TileHeight * height),
226 Tile.GetExtendedSourceRectangle(tileIndex, height),
232 Tile.GetExtendedSourceRectangle(tileIndex, height),
227 Color.White,
233 color,
228 0.0f,
234 0.0f,
229 Vector2.Zero,
235 Vector2.Zero,
230 SpriteEffects.None,
236 SpriteEffects.None,
@@ -36,10 +36,10
36 this.budget = budget;
36 this.budget = budget;
37 this.previous_budget = previous_budget;
37 this.previous_budget = previous_budget;
38
38
39 if ((mouseCur.LeftButton == ButtonState.Pressed)
39 if ((mouseCur.LeftButton == ButtonState.Released)
40 && MathUtils.BetweenExclusive(mouseCur.X, width+x-20, width+x)
40 && (mousePrev.LeftButton == ButtonState.Pressed)
41 && MathUtils.BetweenExclusive(mouseCur.Y, y+bar_height, y+bar_height+20)
41 && MathUtils.BetweenExclusive(mouseCur.X, width+x-20, width+x)
42 ) {
42 && MathUtils.BetweenExclusive(mouseCur.Y, y+bar_height, y+bar_height+20)) {
43
43
44 return false;
44 return false;
45
45
@@ -68,6 +68,17
68 return true;
68 return true;
69 }
69 }
70
70
71 public String line_format(String name, decimal first, decimal second) {
72 var between_name_col = 20 - name.Length;
73 int between_cols = 6;
74 var first_formatted = String.Format("${0:}", first).PadLeft(6, '.');
75 var second_formatted = String.Format("${0:}", second).PadLeft(6, '.');
76
77 var formatted = String.Format("{0:}{1:}{2,6:}{3:}{4,6:}", name, new String('.', between_name_col), first_formatted, new String('.', between_cols), second_formatted);
78
79 return formatted;
80 }
81
71 public void draw(SpriteBatch batch)
82 public void draw(SpriteBatch batch)
72 {
83 {
73
84
@@ -93,24 +104,25
93 }
104 }
94 }
105 }
95
106
107 Vector2 dimensions = font.MeasureString("X");
108 batch.DrawString(font, "X", new Vector2(x+width -20 + (dimensions.X/2), y+bar_height), Color.Black);
96 FilledRectangle.drawFilledRectangle(batch, new Rectangle(x + width - 20, y+bar_height, 20, 20), Color.LightGray);
109 FilledRectangle.drawFilledRectangle(batch, new Rectangle(x + width - 20, y+bar_height, 20, 20), Color.LightGray);
97 Vector2 dimensions = font.MeasureString("X");
98 batch.DrawString(font, "X", new Vector2(x+width -20 + (dimensions.X/2), y+bar_height), Color.Black);
99
110
100 batch.DrawString(font, String.Format("BUDGET REPORT FOR {0:MMMMM yyyy}", this.budget.DateTime), new Vector2(x, bar_height * 1 + y), Color.Black);
111 batch.DrawString(font, String.Format("BUDGET REPORT FOR {0:MMMMM yyyy}", this.budget.DateTime), new Vector2(x, bar_height * 1 + y), Color.Black);
101
112
102 batch.DrawString(font, String.Format("Starting Funds.........${0:}", this.budget.money), new Vector2(x, bar_height * 2 + y), Color.Black);
113 batch.DrawString(font, String.Format("Starting Funds.........${0:}", this.budget.money), new Vector2(x, bar_height * 2 + y), Color.Black);
103
114
104 batch.DrawString(font, String.Format("REVENUE", this.budget.upkeep), new Vector2(x, bar_height * 4 + y), Color.Black);
115 batch.DrawString(font, String.Format("REVENUE", this.budget.upkeep), new Vector2(x, bar_height * 4 + y), Color.Black);
105 batch.DrawString(font, String.Format("Subsidy................${0:}....${1:}", this.budget.subsidy, this.previous_budget.subsidy), new Vector2(x, bar_height * 5 + y), Color.Black);
116 batch.DrawString(font, line_format("Subsidy", this.budget.subsidy, this.previous_budget.subsidy), new Vector2(x, bar_height * 5 + y), Color.Black);
106 batch.DrawString(font, String.Format("Contracts..............${0:}....${1:}", this.budget.contracts, this.previous_budget.contracts), new Vector2(x, bar_height * 6 + y), Color.Black);
117 batch.DrawString(font, line_format("Contracts", this.budget.contracts, this.previous_budget.contracts), new Vector2(x, bar_height * 6 + y), Color.Black);
107 batch.DrawString(font, String.Format("Misc...................${0:}....${1:}", this.budget.misc, this.previous_budget.misc), new Vector2(x, bar_height * 7 + y), Color.Black);
118 batch.DrawString(font, line_format("Misc", this.budget.misc, this.previous_budget.misc), new Vector2(x, bar_height * 7 + y), Color.Black);
108
119
109 batch.DrawString(font, String.Format("EXPENSES", this.budget.upkeep), new Vector2(x, bar_height * 10 + y), Color.Black);
120 batch.DrawString(font, "EXPENSES", new Vector2(x, bar_height * 10 + y), Color.Black);
110 batch.DrawString(font, String.Format("Upkeep.................${0:}....${1:}", this.budget.upkeep, this.previous_budget.upkeep), new Vector2(x, bar_height * 11 + y), Color.Black);
121 batch.DrawString(font, line_format("Upkeep", this.budget.upkeep, this.previous_budget.upkeep), new Vector2(x, bar_height * 11 + y), Color.Black);
111 batch.DrawString(font, String.Format("Tree Planting.1........${0:}....${1:}", this.budget.tree_planting, this.previous_budget.tree_planting), new Vector2(x, bar_height * 12 + y), Color.Black);
122 batch.DrawString(font, line_format("Tree Planting", this.budget.tree_planting, this.previous_budget.tree_planting), new Vector2(x, bar_height * 12 + y), Color.Black);
112 batch.DrawString(font, String.Format("Tree Clearing..........${0:}....${1:}", this.budget.tree_clearing, this.previous_budget.tree_clearing), new Vector2(x, bar_height * 13 + y), Color.Black);
123 batch.DrawString(font, line_format("Tree Clearing", this.budget.tree_clearing, this.previous_budget.tree_clearing), new Vector2(x, bar_height * 13 + y), Color.Black);
113 batch.DrawString(font, String.Format("Enforcement............${0:}....${1:}", this.budget.enforcement, this.previous_budget.enforcement), new Vector2(x, bar_height * 14 + y), Color.Black);
124 batch.DrawString(font, line_format("Enforcement", this.budget.enforcement, this.previous_budget.enforcement), new Vector2(x, bar_height * 14 + y), Color.Black);
125 batch.DrawString(font, line_format("Construction", this.budget.construction, this.previous_budget.construction), new Vector2(x, bar_height * 15 + y), Color.Black);
114
126
115 Color cashflow_color = Color.Black;
127 Color cashflow_color = Color.Black;
116 if (this.budget.cashflow < 0) {
128 if (this.budget.cashflow < 0) {
@@ -121,8 +133,8
121 final_color = Color.Red;
133 final_color = Color.Red;
122 }
134 }
123
135
124 batch.DrawString(font, String.Format("Cashflow.............${0:}....${1:}", this.budget.cashflow, this.previous_budget.cashflow), new Vector2(x, bar_height * 16 + y), cashflow_color);
136 batch.DrawString(font, line_format("Cashflow", this.budget.cashflow, this.previous_budget.cashflow), new Vector2(x, bar_height * 17 + y), cashflow_color);
125 batch.DrawString(font, String.Format("Ending Funds.........${0:}....${1:}", this.budget.final_money, this.previous_budget.final_money), new Vector2(x, bar_height * 17 + y), final_color);
137 batch.DrawString(font, line_format("Ending Funds", this.budget.final_money, this.previous_budget.final_money), new Vector2(x, bar_height * 18 + y), final_color);
126
138
127
139
128 FilledRectangle.drawFilledRectangle(batch, new Rectangle(50, 50, 50, 50), new Color (0, 0,0, 0), 0.99f);
140 FilledRectangle.drawFilledRectangle(batch, new Rectangle(50, 50, 50, 50), new Color (0, 0,0, 0), 0.99f);
@@ -1,7 +1,6
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using ImGuiNET;
3 using ImGuiNET;
4 using ImPlotNET;
5 using ImGuiNET.SampleProgram.XNA;
4 using ImGuiNET.SampleProgram.XNA;
6
5
7 using Num = System.Numerics;
6 using Num = System.Numerics;
@@ -9,6 +8,9
9 using Microsoft.Xna.Framework.Graphics;
8 using Microsoft.Xna.Framework.Graphics;
10 using System.Runtime.InteropServices;
9 using System.Runtime.InteropServices;
11
10
11 using isometricparkfna.Engines;
12 using isometricparkfna.Messages;
13
12 namespace isometricparkfna.UI
14 namespace isometricparkfna.UI
13 {
15 {
14
16
@@ -20,12 +22,18
20 public TimeSpan treeDrawTime;
22 public TimeSpan treeDrawTime;
21 public TimeSpan gridDrawTime;
23 public TimeSpan gridDrawTime;
22 public TimeSpan tileDrawTime;
24 public TimeSpan tileDrawTime;
25 public TimeSpan rendererDrawTime;
26 public TimeSpan miscUIDrawTime;
27 public TimeSpan debugDrawTime;
23 public Vector2 cameraPosition;
28 public Vector2 cameraPosition;
24 public int treeCount;
29 public int treeCount;
25 public Vector2 mouseGrid;
30 public Vector2 mouseGrid;
26 public Boolean hasTree;
31 public Boolean hasTree;
27 public int tilesDrawn;
32 public int tilesDrawn;
28 public TimeSpan updateTime;
33 public TimeSpan updateTime;
34 public TimeSpan worldUpdateTime;
35 public TimeSpan simulationUpdateTime;
36
29 }
37 }
30
38
31 public class DebugWindow
39 public class DebugWindow
@@ -34,13 +42,22
34 private Texture2D _xnaTexture;
42 private Texture2D _xnaTexture;
35 private IntPtr _imGuiTexture;
43 private IntPtr _imGuiTexture;
36 private bool show_test_window;
44 private bool show_test_window;
37 private bool show_implot_test_window;
38
45
39 public ImFontPtr monoFont;
46 public ImFontPtr monoFont;
40 public ImFontPtr italicFont;
47 public ImFontPtr italicFont;
41
48
42 public ImageMap map;
49 public ImageMap map;
43
50
51 private ImGuiWindowBridgeEngine _engine;
52 public ImGuiWindowBridgeEngine engine {
53 get {
54 return this._engine;
55 }
56 set {
57 this._engine = value;
58 }
59 }
60
44 private ImGuiRenderer renderer;
61 private ImGuiRenderer renderer;
45
62
46 public static Dictionary<string, string> fonts = new Dictionary<String, string> {{"Roboto", @"Content/Roboto-Regular.ttf"},
63 public static Dictionary<string, string> fonts = new Dictionary<String, string> {{"Roboto", @"Content/Roboto-Regular.ttf"},
@@ -92,6 +109,7
92
109
93
110
94 this.map = map;
111 this.map = map;
112 this.engine = engine;
95 _xnaTexture = map.ImageMapTexture;
113 _xnaTexture = map.ImageMapTexture;
96 // _xnaTexture = CreateTexture(graphicsDevice, 300, 150, pixel =>
114 // _xnaTexture = CreateTexture(graphicsDevice, 300, 150, pixel =>
97 // {
115 // {
@@ -103,6 +121,8
103 _imGuiTexture = _imGuiRenderer.BindTexture(_xnaTexture);
121 _imGuiTexture = _imGuiRenderer.BindTexture(_xnaTexture);
104 }
122 }
105
123
124
125
106 public void swap()
126 public void swap()
107 {
127 {
108 ImGuiIOPtr io = ImGui.GetIO();
128 ImGuiIOPtr io = ImGui.GetIO();
@@ -187,7 +207,6
187 float f = 0.0f;
207 float f = 0.0f;
188
208
189 bool show_test_window = false;
209 bool show_test_window = false;
190 bool show_implot_test_window = false;
191 bool show_another_window = false;
210 bool show_another_window = false;
192 Num.Vector3 clear_color = new Num.Vector3(114f / 255f, 144f / 255f, 154f / 255f);
211 Num.Vector3 clear_color = new Num.Vector3(114f / 255f, 144f / 255f, 154f / 255f);
193 byte[] _textBuffer = new byte[100];
212 byte[] _textBuffer = new byte[100];
@@ -201,7 +220,6
201 ImGui.SliderFloat("float", ref f, 0.0f, 1.0f, string.Empty);
220 ImGui.SliderFloat("float", ref f, 0.0f, 1.0f, string.Empty);
202 ImGui.ColorEdit3("clear color", ref clear_color);
221 ImGui.ColorEdit3("clear color", ref clear_color);
203 if (ImGui.Button("Test Window")) show_test_window = !show_test_window;
222 if (ImGui.Button("Test Window")) show_test_window = !show_test_window;
204 if (ImGui.Button("Implot Test Window")) show_implot_test_window = !show_implot_test_window;
205 if (ImGui.Button("Another Window")) show_another_window = !show_another_window;
223 if (ImGui.Button("Another Window")) show_another_window = !show_another_window;
206 ImGui.Text(string.Format("Application average {0:F3} ms/frame ({1:F1} FPS)", 1000f / ImGui.GetIO().Framerate, ImGui.GetIO().Framerate));
224 ImGui.Text(string.Format("Application average {0:F3} ms/frame ({1:F1} FPS)", 1000f / ImGui.GetIO().Framerate, ImGui.GetIO().Framerate));
207
225
@@ -227,11 +245,17
227
245
228 ImGui.Text(string.Format("fps: {0:F3}", debugInfo.fps));
246 ImGui.Text(string.Format("fps: {0:F3}", debugInfo.fps));
229 ImGui.Text(string.Format("Draw Time: {0:F3}", debugInfo.drawTime.TotalMilliseconds.ToString()));
247 ImGui.Text(string.Format("Draw Time: {0:F3}", debugInfo.drawTime.TotalMilliseconds.ToString()));
230 ImGui.Text(string.Format("\tTree: {0:F3}; Grid: {1:F3}; Tile: {2:F3}",
248 ImGui.Text(string.Format("\tTree: {0,7:F3}; Grid: {1,7:F3}; Tile: {2,7:F3}\n\tRenderer: {3,7:F3}; Misc UI: {4,7:F3}; Debug: {5,7:F3}",
231 debugInfo.treeDrawTime.TotalMilliseconds.ToString(),
249 debugInfo.treeDrawTime.TotalMilliseconds.ToString(),
232 debugInfo.gridDrawTime.TotalMilliseconds.ToString(),
250 debugInfo.gridDrawTime.TotalMilliseconds.ToString(),
233 debugInfo.tileDrawTime.TotalMilliseconds.ToString()));
251 debugInfo.tileDrawTime.TotalMilliseconds.ToString(),
252 debugInfo.rendererDrawTime.TotalMilliseconds.ToString(),
253 debugInfo.miscUIDrawTime.TotalMilliseconds.ToString(),
254 debugInfo.debugDrawTime.TotalMilliseconds.ToString()));
234 ImGui.Text(string.Format("Update Time: {0:F3}", debugInfo.updateTime.TotalMilliseconds.ToString()));
255 ImGui.Text(string.Format("Update Time: {0:F3}", debugInfo.updateTime.TotalMilliseconds.ToString()));
256 ImGui.Text(string.Format("\tWorld: {0:F3}; Simulation: {1:F3}",
257 debugInfo.worldUpdateTime.TotalMilliseconds.ToString(),
258 debugInfo.simulationUpdateTime.TotalMilliseconds.ToString()));
235 ImGui.Text(string.Format("Tiles Drawn: {0:F}", debugInfo.tilesDrawn));
259 ImGui.Text(string.Format("Tiles Drawn: {0:F}", debugInfo.tilesDrawn));
236
260
237
261
@@ -245,9 +269,6
245 this.show_test_window = !this.show_test_window;
269 this.show_test_window = !this.show_test_window;
246 }
270 }
247
271
248 if (ImGui.Button("Implot Test Window")){
249 show_implot_test_window = !show_implot_test_window;
250 }
251 if (ImGui.Button("Test Logging"))
272 if (ImGui.Button("Test Logging"))
252 {
273 {
253 Logging.Log(LogLevel.Critical, "Test");
274 Logging.Log(LogLevel.Critical, "Test");
@@ -310,6 +331,21
310
331
311 ImGui.EndTabItem();
332 ImGui.EndTabItem();
312 }
333 }
334
335 if(ImGui.BeginTabItem("Debug Controls"))
336 {
337 if (ImGui.Button("Cull 100 Trees"))
338 {
339 this.engine.debugAlterTreesMessages.Add(new DebugAlterTreesMessage {
340 DeltaTrees = 100});
341 }
342 if (ImGui.Button("Cull 1000 Trees"))
343 {
344 this.engine.debugAlterTreesMessages.Add(new DebugAlterTreesMessage {
345 DeltaTrees = 1000});
346 }
347 ImGui.EndTabItem();
348 }
313 ImGui.EndTabBar();
349 ImGui.EndTabBar();
314 ImGui.End();
350 ImGui.End();
315 }
351 }
@@ -319,10 +355,6
319 ImGui.SetNextWindowPos(new Num.Vector2(650, 20), ImGuiCond.FirstUseEver);
355 ImGui.SetNextWindowPos(new Num.Vector2(650, 20), ImGuiCond.FirstUseEver);
320 ImGui.ShowDemoWindow(ref show_test_window);
356 ImGui.ShowDemoWindow(ref show_test_window);
321 }
357 }
322 if (this.show_implot_test_window)
323 {
324 ImPlot.ShowDemoWindow(ref this.show_implot_test_window);
325 }
326 }
358 }
327 }
359 }
328 }
360 }
@@ -6,7 +6,6
6 using System.Collections.Generic;
6 using System.Collections.Generic;
7
7
8 using ImGuiNET;
8 using ImGuiNET;
9 using ImPlotNET;
10
9
11 using JM.LinqFaster;
10 using JM.LinqFaster;
12
11
@@ -26,147 +25,371
26 public static bool show_subsidies = false;
25 public static bool show_subsidies = false;
27 public static bool show_upkeep = false;
26 public static bool show_upkeep = false;
28
27
29 private static string[] money_series = { "Total Funds",
28 public static bool always_show_zero = false;
30 "Subsidies", "Upkeep", "Contracts", "Cashflow", "Misc"};
29 public static bool logarithmic = false;
31 private static string[] tree_series = { "Total trees", "Dead trees", "Crowded trees"};
30
31 private static string[] money_series = {"Total Funds",
32 "Subsidies", "Upkeep", "Contracts", "Cashflow", "Misc"};
33 private static string[] tree_series = {"Total trees", "Dead trees", "Crowded trees"};
32
34
33 public static Dictionary<string, IEnumerable<double>> data_sets = new Dictionary<string, IEnumerable<double>>();
35 public static Dictionary<string, IEnumerable<double>> data_sets = new Dictionary<string, IEnumerable<double>>();
34
36
35 public static Dictionary<String, bool> data_sets_show = new List<string>()
37 public static Dictionary<string, bool> data_sets_show = new List<string>()
36 .Concat(money_series)
38 .Concat(money_series)
37 .Concat(tree_series)
39 .Concat(tree_series)
38 .Select(e => (e, false))
40 .Select(e => (e, false))
39 .ToDictionary(t => t.Item1, t=> t.Item2);
41 .ToDictionary(t => t.Item1, t=> t.Item2);
42
43 public static ImGuiColor[] colors = {ImGuiColor.BLACK, ImGuiColor.RED, ImGuiColor.GREEN,
44 ImGuiColor.BLUE, ImGuiColor.DARKGREY, ImGuiColor.LIGHTRED, ImGuiColor.LIGHTGREEN,
45 ImGuiColor.LIGHTBLUE, ImGuiColor.BLACK };
46
47 public static Dictionary<string, ImGuiColor> data_sets_color = new List<string>()
48 .Concat(money_series)
49 .Concat(tree_series)
50 .Zip(colors, (first, second) => (first, second))
51 .ToDictionary(t => t.Item1, t => t.Item2);
52
53 public static void DrawLinearAxis(ImDrawListPtr draw_list, Num.Vector2 range, bool vertical, int points, Num.Vector2 starting_position) {
54 //See DrawLinearLabels for explanation
55 var tick_spacing = (int)Math.Abs((range.Y - range.X) / (points - 1));
56 var tick_length = 5;
57 var tick_adjust = vertical ? new Num.Vector2(tick_length, 0) : new Num.Vector2(0, tick_length);
58
59 var tick_position = starting_position;
60
61 for(int i = 0; i < points; i++) {
62 draw_list.AddLine(tick_position, Num.Vector2.Add(tick_position, tick_adjust), (uint)ImGuiColor.DARKGREY, 1.0f);
63
64 if (vertical) {
65 tick_position = new Num.Vector2(starting_position.X, starting_position.Y + ((i + 1) * tick_spacing));
66 }
67 else {
68 //We increment one, otherwise the first tick is
69 tick_position = new Num.Vector2(starting_position.X + ((i + 1) * tick_spacing), starting_position.Y);
70 }
71 }
72 }
73
74 public static void DrawLinearLabels(ImFontPtr font, ImDrawListPtr draw_list, Num.Vector2 domain, Num.Vector2 range, bool vertical, int labels, Num.Vector2 starting_position) {
75 //We need to increment by one in order to cover the entire range.
76 //For example, if our range is 0 - 100, and we want 11 ticks, 100 / 10 gives us a spacing o 10
77 //So our 11 labels become 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100.
78 var tick_spacing = (int)Math.Abs((range.Y - range.X) / (labels - 1));
79 var tick_length = 5;
80 var tick_adjust = vertical ? new Num.Vector2(tick_length, 0) : new Num.Vector2(0, tick_length);
81
82 var tick_position = new Num.Vector2(0, range.Y);
83 var tick_absolute_position = Num.Vector2.Add(starting_position, tick_position);
84
85 for(int i = 0; i < labels; i++) {
86 var value = Scale(range, domain, (int)(vertical ? tick_position.Y : tick_position.X));
87 var label = String.Format("{0}", value);
88 var height_adjust = ImGui.CalcTextSize(label).Y / 2;
89 var adjusted_position = Num.Vector2.Add(tick_absolute_position,
90 new Num.Vector2(0, -height_adjust));
91
92 draw_list.AddText(font, 11.0f, adjusted_position, (uint)ImGuiColor.BLACK, label);
93 //Logging.Info(String.Format("Drawing {0:} at {1} ({2})", label, tick_absolute_position, tick_position));
94
95 if (vertical) {
96 tick_position = new Num.Vector2(0, range.Y + ((i + 1) * tick_spacing));
97 }
98 else {
99 tick_position = new Num.Vector2(range.X + ((i + 1) * tick_spacing), 0);
100 }
101
102 tick_absolute_position = Num.Vector2.Add(starting_position, tick_position);
103 }
104 }
105
106 public static void DrawLogrithmicLabels(ImFontPtr font, ImDrawListPtr draw_list, Num.Vector2 domain, Num.Vector2 range, bool vertical, int labels, Num.Vector2 starting_position) {
107 //We need to increment by one in order to cover the entire range.
108 //For example, if our range is 0 - 100, and we want 11 ticks, 100 / 10 gives us a spacing o 10
109 //So our 11 labels become 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100.
110 var tick_spacing = (int)Math.Abs((range.Y - range.X) / (labels - 1));
111 var tick_length = 5;
112 var tick_adjust = vertical ? new Num.Vector2(tick_length, 0) : new Num.Vector2(0, tick_length);
113
114 var tick_position = new Num.Vector2(0, range.Y);
115 var tick_absolute_position = Num.Vector2.Add(starting_position, tick_position);
116
117 for(int i = 0; i < labels; i++) {
118 var value = ScaleLogarithmic(range, domain, (int)(vertical ? tick_position.Y : tick_position.X));
119 var label = String.Format("{0}", value);
120 var height_adjust = ImGui.CalcTextSize(label).Y / 2;
121 var adjusted_position = Num.Vector2.Add(tick_absolute_position,
122 new Num.Vector2(0, -height_adjust));
123
124 draw_list.AddText(font, 11.0f, adjusted_position, (uint)ImGuiColor.BLACK, label);
125 //Logging.Info(String.Format("Drawing {0:} at {1} ({2})", label, tick_absolute_position, tick_position));
40
126
127 if (vertical) {
128 tick_position = new Num.Vector2(0, range.Y + ((i + 1) * tick_spacing));
129 }
130 else {
131 tick_position = new Num.Vector2(range.X + ((i + 1) * tick_spacing), 0);
132 }
133
134 tick_absolute_position = Num.Vector2.Add(starting_position, tick_position);
135 }
136 }
137
138 public static void DrawLine(ImDrawListPtr draw_list, Num.Vector2 c, Num.Vector2[] points, ImGuiColor col) {
139 var p = Num.Vector2.Zero;
140
141 for (int i = 0; i < points.Length; i++)
142 {
143 points[i] = Num.Vector2.Add(points[i], c);
144 }
145
146 draw_list.AddPolyline(ref points[0], points.Length, (uint)col, 0, 1.0f);
147 }
148
149 public static int Scale(Num.Vector2 domain, Num.Vector2 range, int num) {
150 //https://stats.stackexchange.com/a/281164
151
152 var domain_span = Math.Sign(domain.Y - domain.X) * Math.Max(1, Math.Abs(domain.Y - domain.X));
153 var range_span = range.Y - range.X;
154
155 var start = range.X - domain.X;
156
157 return (int) (((num - domain.X) / domain_span) * range_span + range.X);
158 }
159
160 public static float Scale(Num.Vector2 domain, Num.Vector2 range, float num) {
161 //https://stats.stackexchange.com/a/281164
162
163 if (!float.IsNaN(domain.Y - domain.X)) {
164 var domain_span = Math.Sign(domain.Y - domain.X) * Math.Max(1, Math.Abs(domain.Y - domain.X));
165 var range_span = range.Y - range.X;
166
167 var start = range.X - domain.X;
168
169 return (((num - domain.X) / domain_span) * range_span + range.X);
170 }
171 else {
172 return float.NaN;
173 }
174 }
175
176 public static float ScaleLogarithmic(Num.Vector2 domain, Num.Vector2 range, float num) {
177 var scaled_domain = new Num.Vector2((float)MathUtils.SymmetricLog10(domain.X), (float)MathUtils.SymmetricLog10(domain.Y));
178 float scaled_num = num == 0 ? 0.0f : (float)MathUtils.SymmetricLog10(num);
179
180 return Scale(scaled_domain, range, scaled_num);
181 }
182
183 public static Num.Vector2 adjust_domain(int domain_min, int domain_max)
184 {
185 if (domain_max == int.MinValue) {
186 return adjust_domain(0, 0);
187 }
188 else if (domain_min != domain_max) {
189 //Significant-digits based rounding (kinda):
190 // var orders_to_round = 4;
191 // var orders = (int)Math.Log10(domain_max);
192 // var domain_max_rounded = Math.Round(domain_max / Math.Pow(10, orders - orders_to_round)) * Math.Pow(10, orders - orders_to_round);
193 //Round so breaks are even (in theory):
194 var domain_max_rounded = Math.Ceiling(domain_max / 50.0) * 50;
195 var domain_min_rounded = Math.Floor(domain_min / 50.0) * 50;
196
197 // Logging.Info("Standard rounding.");
198
199 //Throw out rounding if result is too close together:
200 if (domain_min_rounded != domain_max_rounded) {
201 return new Num.Vector2((float)domain_min_rounded, (float)domain_max_rounded);
202 }
203 else {
204 return new Num.Vector2(domain_min, domain_max);
205 }
206
207
208 }
209 else {
210 var lower = MathUtils.Clamp(domain_min, 0, 100);
211 var upper = MathUtils.Clamp(domain_min, 10, 100);
212
213 // Logging.Info("Clamped rounding.");
214
215 return new Num.Vector2(domain_min-lower, domain_max+upper);
216 }
217 }
41
218
42 public static void Render(ImFontPtr font, Simulation sim, ImGuiWindowBridgeEngine engine)
219 public static void Render(ImFontPtr font, Simulation sim, ImGuiWindowBridgeEngine engine)
43 {
220 {
44 bool newShow = true;
221 bool newShow = true;
45
222
223 ImGui.PushFont(font);
46
224
47 ImGui.PushFont(font);
225 ImGui.GetStyle().WindowMenuButtonPosition = ImGuiDir.None;
226 StyleSets.defaultSet.push();
48
227
49 ImGui.GetStyle().WindowMenuButtonPosition = ImGuiDir.None;
228 if(GraphWindow.hadFocus)
50 StyleSets.defaultSet.push();
229 {
230 ImGui.PushStyleColor(ImGuiCol.Text, StyleSets.white);
231 }
232 ImGui.SetNextWindowSize(new Num.Vector2(400, 400));
51
233
52 if(GraphWindow.hadFocus)
234 ImGui.Begin("Graph", ref newShow, ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoSavedSettings);
53 {
235 if (GraphWindow.hadFocus)
54 ImGui.PushStyleColor(ImGuiCol.Text, StyleSets.white);
236 {
55 }
237 ImGui.PopStyleColor();
56 ImGui.SetNextWindowSize(new Num.Vector2(400, 400));
238 }
239 GraphWindow.hadFocus = ImGui.IsWindowFocused();
240
241 data_sets["Total Funds"] = sim.allBudgets().Select(b => (double)b.money);
242 data_sets["Subsidies"] = sim.allBudgets().Select(b => (double)b.subsidy);
243 data_sets["Upkeep"] = sim.allBudgets().Select(b => (double)b.upkeep);
244 data_sets["Contracts"] = sim.allBudgets().Select(b => (double)b.contracts);
245 data_sets["Misc"] = sim.allBudgets().Select(b => (double)b.misc);
246 data_sets["Cashflow"] = sim.allBudgets().Select(b => (double)b.cashflow);
247
248 data_sets["Total trees"] = sim.allBudgets().Select(b => (double)b.trees);
249 data_sets["Dead trees"] = sim.allBudgets().Select(b => (double)b.dead_trees);
250 data_sets["Crowded trees"] = sim.allBudgets().Select(b => (double)b.crowded_trees);
251
252 var periods = 12.0d * GraphWindow.year;
253 var keys = data_sets_show.Keys.ToList();
57
254
58 ImGui.Begin("Graph", ref newShow, ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoSavedSettings);
255 var totals = data_sets["Total Funds"];
59 if (GraphWindow.hadFocus)
256
60 {
257 var max = 0.0d;
61 ImGui.PopStyleColor();
258 var min = 0.0d;
259
260 foreach (var key in keys) {
261 if (data_sets_show[key] && totals.Count() > 0) {
262 var series_max = data_sets[key].Max() * 1.10f;
263 max = Math.Max(series_max, max);
62 }
264 }
63 GraphWindow.hadFocus = ImGui.IsWindowFocused();
265 }
64
266
65 data_sets["Total Funds"] = sim.allBudgets().Select(b => (double)b.money);
267 foreach (var key in keys) {
66 data_sets["Subsidies"] = sim.allBudgets().Select(b => (double)b.subsidy);
268 if (data_sets_show[key] && totals.Count() > 0) {
67 data_sets["Upkeep"] = sim.allBudgets().Select(b => (double)b.upkeep);
269 var series_min = data_sets[key].Min();
68 data_sets["Contracts"] = sim.allBudgets().Select(b => (double)b.contracts);
270 series_min = series_min >= 0? series_min * 0.90f : series_min *1.10f;
69 data_sets["Misc"] = sim.allBudgets().Select(b => (double)b.misc);
271 min = Math.Min(series_min, min);
70 data_sets["Cashflow"] = sim.allBudgets().Select(b => (double)b.cashflow);
272 }
273 }
274
275 var draw_list = ImGui.GetWindowDrawList();
276 var padding = 30;
277
278 var domain_min = always_show_zero ? 0 : int.MaxValue;
279 var domain_max = int.MinValue;
280 var c = ImGui.GetCursorScreenPos();
281
282 //Y Axis
283 draw_list.AddLine(Num.Vector2.Add(new Num.Vector2(padding, padding), c),
284 Num.Vector2.Add(new Num.Vector2(padding, 200 - padding), c),
285 (uint)ImGuiColor.LIGHTGREY, 0.0f);
71
286
72 data_sets["Total trees"] = sim.allBudgets().Select(b => (double)b.trees);
287 //X Axis
73 data_sets["Dead trees"] = sim.allBudgets().Select(b => (double)b.dead_trees);
288 draw_list.AddLine(Num.Vector2.Add(new Num.Vector2(padding, 200 - padding), c),
74 data_sets["Crowded trees"] = sim.allBudgets().Select(b => (double)b.crowded_trees);
289 Num.Vector2.Add(new Num.Vector2(350, 200 - padding), c),
290 (uint)ImGuiColor.LIGHTGREY, 1.0f);
291
292
293 foreach (var key in keys)
294 {
295 if (data_sets_show[key] && data_sets[key].Count() > 0)
296 {
297 domain_min = Math.Min(domain_min, (int)data_sets[key].Min());
298 domain_max = Math.Max(domain_max, (int)data_sets[key].Max());
299 }
300 }
75
301
76 var periods = 12.0d * GraphWindow.year;
302 var domain = adjust_domain(domain_min, domain_max);
77 var keys = data_sets_show.Keys.ToList();
303 var range = new Num.Vector2(200 - padding, 0 + padding);
304
305 //Zero
306 var zero_point = logarithmic ? ScaleLogarithmic(domain, range, 0) : Scale(domain, range, 0);
307 // Logging.Spy(new {zero_point = zero_point});
308 draw_list.AddLine(Num.Vector2.Add(new Num.Vector2(padding, zero_point), c),
309 Num.Vector2.Add(new Num.Vector2(350, zero_point), c),
310 (uint)ImGuiColor.LIGHTGREY, 1.0f);
78
311
79 var totals = data_sets["Total Funds"];
312 var x_domain = new Num.Vector2((data_sets["Misc"].Count() - (int)periods),
313 data_sets["Misc"].Count());
314 var x_range = new Num.Vector2(0 + padding, 350 - padding);
80
315
81 var max = 0.0d;
316 foreach (var key in keys)
82 var min = 0.0d;
317 {
318 var show = data_sets_show[key];
319 var data = data_sets[key];
320 var color = data_sets_color[key];
83
321
84 foreach( var key in keys) {
322 if (data.Count() > 0 && show)
85 if (data_sets_show[key] && totals.Count() > 0) {
323 {
86 var series_max = data_sets[key].Max() * 1.10f;
324 IEnumerable<float> data_array = data_sets[key].Select((p) => (logarithmic ? ScaleLogarithmic(domain, range, (float)p): Scale(domain, range, (float)p)));
87 max = Math.Max(series_max, max);
325 var data_array2 = data_array.Select((p, i) => new Num.Vector2(Scale(x_domain, x_range, i), p)).ToArray();
88 }
326
327 DrawLine(draw_list, c, data_array2, color);
328 draw_list.AddText(font, 12, data_array2.Last(), (uint)color, key);
89 }
329 }
330 }
90
331
91 foreach( var key in keys) {
332 DrawLinearAxis(draw_list, range /*new Num.Vector2(0, 200)*/, true, 11, Num.Vector2.Add(c, new Num.Vector2(padding, padding)));
92 if (data_sets_show[key] && totals.Count() > 0) {
333 if (logarithmic) {
93 var series_min = data_sets[key].Min();
334 DrawLogrithmicLabels(font, draw_list, domain, range, true, 11, c);
94 series_min = series_min >= 0? series_min * 0.90f : series_min *1.10f;
335 }
95 min = Math.Min(series_min, min);
336 else {
96 }
337 DrawLinearLabels(font, draw_list, domain, range, true, 11, c);
338 }
339 DrawLinearAxis(draw_list, new Num.Vector2(0, 350), false, 12, Num.Vector2.Add(c, new Num.Vector2(padding, 200 - padding)));
340
341 ImGui.Dummy(new Num.Vector2(350, 200));
342
343 ImGui.RadioButton("1 year", ref GraphWindow.year, 1);
344 ImGui.SameLine();
345 ImGui.RadioButton("5 years", ref GraphWindow.year, 5);
346 ImGui.SameLine();
347 ImGui.RadioButton("25 years", ref GraphWindow.year, 25);
348 ImGui.SameLine();
349 ImGui.RadioButton("100 years", ref GraphWindow.year, 100);
350
351 ImGui.Text("Trees:");
352 for (int i = 0; i < tree_series.Length; i++)
353 {
354 var key = tree_series[i];
355 if (Menu.activeButton(key, data_sets_show[key], StyleSets.selected, StyleSets.white))
356 {
357 data_sets_show[key] = !data_sets_show[key];
97 }
358 }
98
359
99 ImPlot.PushStyleVar(ImPlotStyleVar.LineWeight, 2.0f);
360 if (i != tree_series.Length-1)
100 ImPlot.PushStyleVar(ImPlotStyleVar.MinorAlpha, 0.0f);
361 {
101 // ImPlot.PushStyleVar(ImPlotStyleVar.MajorGridSize, new Num.Vector2(0.0f, 0.0f));
362 ImGui.SameLine();
102 // ImPlot.PushStyleVar(ImPlotStyleVar.MinorGridSize, new Num.Vector2(0.0f, 0.0f));
363 }
364 }
103
365
104 ImPlot.SetNextPlotLimits(totals.Count()-periods, totals.Count(), min, max , ImGuiCond.Always);
366 ImGui.Text("Money:");
105 if( ImPlot.BeginPlot("My Plot", null, null, new Num.Vector2(-1,0), ImPlotFlags.NoLegend | ImPlotFlags.NoMousePos )) {
367 for (int i = 0; i < money_series.Length; i++)
106 // Span<double> totals = new Span<double>(new double[]{0.0, 1.0, 2.0, 9.0});
368 {
107 foreach (var key in keys) {
369 var key = money_series[i];
108 var show = data_sets_show[key];
370 if (Menu.activeButton(key, data_sets_show[key], StyleSets.selected, StyleSets.white))
109 var data = data_sets[key];
110 var data_array = data_sets[key].ToArray();
111 if (data_array.Length > 0 && show)
112 {
113 ImPlot.PlotLine(key, ref data_array[0], data_array.Length);
114 ImPlot.AnnotateClamped(data_array.Length-1, data_array[data_array.Length-1],
115 new Num.Vector2(5, -10), StyleSets.grey, key);
116 }
117 }
118
119 ImPlot.EndPlot();
120 }
121
122 ImPlot.PopStyleVar(2);
123
124 ImGui.RadioButton("1 year", ref GraphWindow.year, 1);
125 ImGui.SameLine();
126 ImGui.RadioButton("5 years", ref GraphWindow.year, 5);
127 ImGui.SameLine();
128 ImGui.RadioButton("25 years", ref GraphWindow.year, 25);
129 ImGui.SameLine();
130 ImGui.RadioButton("100 years", ref GraphWindow.year, 100);
131
132 ImGui.Text("Trees:");
133 for (int i = 0; i < tree_series.Length; i++)
134 {
371 {
135 var key = tree_series[i];
372 data_sets_show[key] = !data_sets_show[key];
136 if (Menu.activeButton(key, data_sets_show[key], StyleSets.selected, StyleSets.white))
137 {
138 data_sets_show[key] = !data_sets_show[key];
139 }
140
141 if (i != tree_series.Length-1)
142 {
143 ImGui.SameLine();
144 }
145
146 }
373 }
374 if ((i % 4 != 3) && (i != money_series.Length-1)) {
375 ImGui.SameLine();
376 }
377 }
147
378
148 ImGui.Text("Money:");
379 ImGui.Text("Always show zero:");
149 for (int i = 0; i < money_series.Length; i++)
380 ImGui.SameLine();
150 {
381 ImGui.Checkbox("##AlwaysShowZero", ref always_show_zero);
151 var key = money_series[i];
382 #if DEBUG
152 if (Menu.activeButton(key, data_sets_show[key], StyleSets.selected, StyleSets.white))
383 ImGui.SameLine();
153 {
384 ImGui.Text("Logarithmic: ");
154 data_sets_show[key] = !data_sets_show[key];
385 ImGui.SameLine();
155 }
386 ImGui.Checkbox("##Logarithmic", ref logarithmic);
156 if ((i % 4 != 3) && (i != money_series.Length-1)) {
387 #endif
157 ImGui.SameLine();
158 }
159
388
160 }
389 ImGui.End();
161
390 ImGui.GetStyle().WindowMenuButtonPosition = ImGuiDir.Left;
162
391 StyleSets.defaultSet.pop();
163
392 ImGui.PopFont();
164
165 ImGui.End();
166 ImGui.GetStyle().WindowMenuButtonPosition = ImGuiDir.Left;
167 StyleSets.defaultSet.pop();
168 ImGui.PopFont();
169
170 }
393 }
171 }
394 }
172 }
395 }
@@ -6,6 +6,7
6
6
7 using isometricparkfna.Engines;
7 using isometricparkfna.Engines;
8 using isometricparkfna.Messages;
8 using isometricparkfna.Messages;
9 using isometricparkfna.Components;
9
10
10 namespace isometricparkfna.UI
11 namespace isometricparkfna.UI
11 {
12 {
@@ -98,12 +99,59
98 ImGui.Text(header);
99 ImGui.Text(header);
99
100
100
101
101 var dimensions = ImGui.CalcTextSize("X Graph X Contracts $ Budget X Forest X News X | Pause 1 2 3 4 5") ;
102 var dimensions = ImGui.CalcTextSize("X Tower X Preserve X Dezone X Bulldozer | X Graph X Contracts $ Budget X Forest X News X | Pause 1 2 3 4 5") ;
102
103
103 // ImGui.SetCursorPosX(width - 520);
104 // ImGui.SetCursorPosX(width - 520);
104 // Add 12 pixels for each button, plus separator
105 // Add 12 pixels for each button, plus separator
105 ImGui.SetCursorPosX(width - (dimensions.X + 11*12));
106 ImGui.SetCursorPosX(width - (dimensions.X + 11*15));
106 if (Menu.activeButton("\ue124 Graph", bridgeEngine.windowStatuses[Window.Graph], StyleSets.selected, StyleSets.white))
107
108 if (Menu.activeButton("\ue06e Tower", bridgeEngine.toolStatuses[Tool.Tower], StyleSets.selected, StyleSets.white))
109 {
110 bridgeEngine.toggleToolMessages.Add(new ToggleToolMessage {Tool = Tool.Tower});
111 }
112 if (Menu.activeButton("\ue099 Preserve", bridgeEngine.toolStatuses[Tool.Preserve], StyleSets.selected, StyleSets.white))
113 {
114 bridgeEngine.toggleToolMessages.Add(new ToggleToolMessage {Tool = Tool.Preserve});
115 }
116 if (!bridgeEngine.toolStatuses[Tool.Dezone]) {
117 if (Menu.activeButton("\ue122 Bulldozer", bridgeEngine.toolStatuses[Tool.Bulldozer], StyleSets.selected, StyleSets.white))
118 {
119 bridgeEngine.toggleToolMessages.Add(new ToggleToolMessage {Tool = Tool.Bulldozer});
120 }
121 }
122 else {
123 if (Menu.activeButton("\ue058 Dezone", bridgeEngine.toolStatuses[Tool.Dezone], StyleSets.selected, StyleSets.white))
124 {
125 bridgeEngine.toggleToolMessages.Add(new ToggleToolMessage {Tool = Tool.Dezone});
126 }
127 }
128
129
130 ImGui.SetCursorPosX(ImGui.GetCursorPosX() - 9);
131 if (ImGui.Button("\ue01d"))
132 {
133 ImGui.OpenPopup("BulldozerChildren");
134 }
135 if (ImGui.BeginPopup("BulldozerChildren"))
136 {
137 if (Menu.activeButton("\ue122 Bulldozer", bridgeEngine.toolStatuses[Tool.Bulldozer], StyleSets.selected, StyleSets.white))
138 {
139 bridgeEngine.toggleToolMessages.Add(new ToggleToolMessage {Tool = Tool.Bulldozer});
140 }
141 if (Menu.activeButton("\ue058 Dezone", bridgeEngine.toolStatuses[Tool.Dezone], StyleSets.selected, StyleSets.white))
142 {
143 bridgeEngine.toggleToolMessages.Add(new ToggleToolMessage {Tool = Tool.Dezone});
144 ImGui.CloseCurrentPopup();
145 }
146 if (ImGui.Button("Cancel"))
147 {
148 ImGui.CloseCurrentPopup();
149 }
150 ImGui.EndPopup();
151 }
152 ImGui.Text("|");
153
154 if (Menu.activeButton("\ue03e Graph", bridgeEngine.windowStatuses[Window.Graph], StyleSets.selected, StyleSets.white))
107 {
155 {
108 bridgeEngine.typeMessages.Add(new ToggleWindowTypeMessage {Window = Window.Graph});
156 bridgeEngine.typeMessages.Add(new ToggleWindowTypeMessage {Window = Window.Graph});
109
157
@@ -46,8 +46,6
46 showModal = true;
46 showModal = true;
47
47
48 NewGameWindow.Reset();
48 NewGameWindow.Reset();
49
50
51 }
49 }
52
50
53 public static void Reset() {
51 public static void Reset() {
@@ -193,10 +191,9
193
191
194 NewGameWindow.playerName2Pos = newPlayerName2Pos;
192 NewGameWindow.playerName2Pos = newPlayerName2Pos;
195
193
196 ImGui.RadioButton("Easy: Full Funding", ref choice, ((int)DifficultyLevel.Easy));
194 ImGui.RadioButton("Easy: Social Democracy", ref choice, ((int)DifficultyLevel.Easy));
197 ImGui.RadioButton("Medium: Austerity", ref choice, ((int)DifficultyLevel.Medium));
195 ImGui.RadioButton("Medium: Austerity", ref choice, ((int)DifficultyLevel.Medium));
198 ImGui.RadioButton("Hard: Unfunded", ref choice, ((int)DifficultyLevel.Hard));
196 ImGui.RadioButton("Hard: Libertarianism", ref choice, ((int)DifficultyLevel.Hard));
199
200
197
201 if (ImGui.Button("Okay"))
198 if (ImGui.Button("Okay"))
202 {
199 {
@@ -220,13 +217,10
220 NewGameWindow.Reset();
217 NewGameWindow.Reset();
221 }
218 }
222
219
223
224 ImGui.End();
220 ImGui.End();
225
221
226
227 StyleSets.defaultSet.pop();
222 StyleSets.defaultSet.pop();
228 ImGui.PopFont();
223 ImGui.PopFont();
229
230 }
224 }
231 }
225 }
232 }
226 }
@@ -65,12 +65,31
65
65
66 public static class NewsWindow
66 public static class NewsWindow
67 {
67 {
68 public static bool wire_open = true;
69 public static bool true_open = false;
70 public static bool naturalist_open = false;
71 public static bool had_focus = false;
68
72
69 public static bool had_focus = false;
73 private static bool MenuItem(string label, bool active) {
74 if (active)
75 {
76 ImGui.PushStyleColor(ImGuiCol.Text, StyleSets.white);
77 }
78
79 var result = ImGui.BeginTabItem(label);
80
81 if (active)
82 {
83 ImGui.PopStyleColor(1);
84 }
85
86 return result;
87 }
70
88
71 public static void Render(ImFontPtr font, Simulation sim, ImGuiWindowBridgeEngine engine)
89 public static void Render(ImFontPtr font, Simulation sim, ImGuiWindowBridgeEngine engine)
72 {
90 {
73 bool newShow = true;
91 bool newShow = true;
92
74 if (newShow)
93 if (newShow)
75 {
94 {
76 ImGui.PushFont(font);
95 ImGui.PushFont(font);
@@ -98,10 +117,11
98
117
99 if (ImGui.BeginTabBar("Sources", 0))
118 if (ImGui.BeginTabBar("Sources", 0))
100 {
119 {
101
120 if (MenuItem("Wire", wire_open))
102
103 if (ImGui.BeginTabItem("Wire"))
104 {
121 {
122 wire_open = true;
123 naturalist_open = false;
124 true_open = false;
105
125
106 foreach (NewsItem story in content.Where(s => (s.source == "Wire")).Take(3))
126 foreach (NewsItem story in content.Where(s => (s.source == "Wire")).Take(3))
107 {
127 {
@@ -113,9 +133,12
113 }
133 }
114 ImGui.EndTabItem();
134 ImGui.EndTabItem();
115 }
135 }
116 ImGui.EndTabItem();
136 if (MenuItem("The Naturalist", naturalist_open))
117 if (ImGui.BeginTabItem("The Naturalist"))
118 {
137 {
138 wire_open = false;
139 naturalist_open = true;
140 true_open = false;
141
119 foreach (NewsItem story in content.Where(s => (s.source == "Arborist")).Take(3))
142 foreach (NewsItem story in content.Where(s => (s.source == "Arborist")).Take(3))
120 {
143 {
121 if (ImGui.TreeNode(story.hed))
144 if (ImGui.TreeNode(story.hed))
@@ -126,8 +149,12
126 }
149 }
127 ImGui.EndTabItem();
150 ImGui.EndTabItem();
128 }
151 }
129 if (ImGui.BeginTabItem("All True News"))
152 if (MenuItem("All True News", true_open))
130 {
153 {
154 wire_open = false;
155 naturalist_open = false;
156 true_open = true;
157
131 foreach (NewsItem story in content.Where(s => (s.source == "True")).Take(3))
158 foreach (NewsItem story in content.Where(s => (s.source == "True")).Take(3))
132 {
159 {
133 if (ImGui.TreeNode(story.hed))
160 if (ImGui.TreeNode(story.hed))
@@ -138,10 +165,9
138 }
165 }
139 ImGui.EndTabItem();
166 ImGui.EndTabItem();
140 }
167 }
168 ImGui.EndTabBar();
141 }
169 }
142
170
143 ImGui.EndTabBar();
144
145
171
146 if (ImGui.Button("Okay"))
172 if (ImGui.Button("Okay"))
147 {
173 {
@@ -5,6 +5,7
5
5
6 using Microsoft.Xna.Framework;
6 using Microsoft.Xna.Framework;
7
7
8 using isometricparkfna.Components;
8 using isometricparkfna.Engines;
9 using isometricparkfna.Engines;
9 using isometricparkfna.Messages;
10 using isometricparkfna.Messages;
10 using isometricparkfna.UI;
11 using isometricparkfna.UI;
@@ -16,24 +17,42
16 {
17 {
17
18
18 public static bool hadFocus = false;
19 public static bool hadFocus = false;
20
19 public static bool newFullscreen;
21 public static bool newFullscreen;
20 public static Vector2 newResolution;
22 public static Vector2 newResolution;
23 public static float newSoundEffectVolume;
24 public static bool newSoundEffectsMute;
21
25
22 private static string fontName = "Iosevka";
26 private static string fontName = "Iosevka";
23 private static int fontSize = 15;
27 private static int fontSize = 15;
24 private static ProfanityLevel profanityLevel = default;
28 private static ProfanityLevel profanityLevel = default;
25
29
26 public static void Initialize(Vector2 resolution, bool fullscreen, ProfanityLevel profanityLevel)
30
31 private static bool origFullscreen = OptionsWindow.newFullscreen;
32 private static Vector2 origResolution = OptionsWindow.newResolution;
33
34 private static string origFontName = OptionsWindow.fontName;
35 private static int origFontSize = OptionsWindow.fontSize;
36 private static ProfanityLevel origProfanityLevel = OptionsWindow.profanityLevel;
37 private static float origSoundEffectVolume;
38 private static bool origSoundEffectsMute;
39
40 private static float prevSoundEffectVolume; //Tracks the previously set. (As opposed to origSoundEffectVolume, which is the previously *applied* volume.
41
42 public static void Initialize(Vector2 resolution, bool fullscreen, ProfanityLevel profanityLevel, Options startingOptions)
27 {
43 {
28
44
29 OptionsWindow.newFullscreen = fullscreen;
45 OptionsWindow.newFullscreen = fullscreen;
30 OptionsWindow.newResolution = resolution;
46 OptionsWindow.newResolution = resolution;
31 OptionsWindow.profanityLevel = profanityLevel;
47 OptionsWindow.profanityLevel = profanityLevel;
48
49 newSoundEffectVolume = startingOptions.SoundEffectVolume;
50 newSoundEffectsMute = startingOptions.SoundEffectMuted;
51 prevSoundEffectVolume = startingOptions.SoundEffectVolume;
32 }
52 }
33
53
34 public static void Render(ImFontPtr font, ImFontPtr italicFont, ImGuiWindowBridgeEngine bridgeEngine, int width, ProfanityLevel profanityLevel)
54 public static void Render(ImFontPtr font, ImFontPtr italicFont, ImGuiWindowBridgeEngine bridgeEngine, int width)
35 {
55 {
36
37 ImGui.GetStyle().WindowMenuButtonPosition = ImGuiDir.None;
56 ImGui.GetStyle().WindowMenuButtonPosition = ImGuiDir.None;
38 bool newShow = true;
57 bool newShow = true;
39
58
@@ -63,7 +82,7
63 ImGui.SameLine();
82 ImGui.SameLine();
64
83
65 if (ImGui.BeginCombo("##resolutions", string.Format("{0}x{1}",
84 if (ImGui.BeginCombo("##resolutions", string.Format("{0}x{1}",
66 newResolution.X, newResolution.Y)))
85 newResolution.X, newResolution.Y)))
67 {
86 {
68
87
69 foreach(var (width_option, height_option) in new[] {(1280, 640),
88 foreach(var (width_option, height_option) in new[] {(1280, 640),
@@ -126,6 +145,26
126
145
127 ImGui.Checkbox("Fullscreen", ref newFullscreen);
146 ImGui.Checkbox("Fullscreen", ref newFullscreen);
128
147
148
149
150 ImGui.Separator();
151
152 ImGui.PushFont(italicFont);
153 ImGui.Text("Audio");
154 ImGui.PopFont();
155 ImGui.Text("Sound Effects:\t");
156
157 ImGui.SameLine();
158 ImGui.DragFloat("##Sfx", ref newSoundEffectVolume, 0.005f, 0.0f, 1.0f, "%.2f");
159
160 if ((newSoundEffectVolume != prevSoundEffectVolume) && ImGui.IsItemDeactivatedAfterEdit()) {
161 bridgeEngine.playSoundMessages.Add(new PlaySoundMessage { SoundName = "Bell", Volume = newSoundEffectVolume});
162 prevSoundEffectVolume = newSoundEffectVolume;
163 }
164
165 ImGui.SameLine();
166 ImGui.Checkbox("Mute", ref newSoundEffectsMute);
167
129 ImGui.Separator();
168 ImGui.Separator();
130
169
131 ImGui.PushFont(italicFont);
170 ImGui.PushFont(italicFont);
@@ -141,7 +180,10
141 {
180 {
142 if(ImGui.Selectable(level.ToString()))
181 if(ImGui.Selectable(level.ToString()))
143 {
182 {
144 bridgeEngine.setOptionMessages.Add(new SetOptionMessage { NewProfanitySetting = (ProfanityLevel)level});
183 bridgeEngine.setOptionMessages.Add(new SetOptionMessage { NewProfanitySetting = (ProfanityLevel)level,
184 NewSoundEffectVolume = origSoundEffectVolume,
185 NewSoundEffectMuted = origSoundEffectsMute
186 });
145 OptionsWindow.profanityLevel = (ProfanityLevel)level;
187 OptionsWindow.profanityLevel = (ProfanityLevel)level;
146 }
188 }
147 }
189 }
@@ -165,7 +207,21
165 fontName = OptionsWindow.fontName
207 fontName = OptionsWindow.fontName
166 });
208 });
167
209
168 }
210 origFullscreen = OptionsWindow.newFullscreen;
211 origResolution = OptionsWindow.newResolution;
212
213 origFontName = OptionsWindow.fontName;
214 origFontSize = OptionsWindow.fontSize;
215 origProfanityLevel = OptionsWindow.profanityLevel;
216 origSoundEffectVolume = OptionsWindow.newSoundEffectVolume;
217 origSoundEffectsMute = OptionsWindow.newSoundEffectsMute;
218
219
220 bridgeEngine.setOptionMessages.Add(new SetOptionMessage { NewProfanitySetting = (ProfanityLevel)profanityLevel,
221 NewSoundEffectVolume = newSoundEffectVolume,
222 NewSoundEffectMuted = newSoundEffectsMute});
223 }
224
169 ImGui.SameLine();
225 ImGui.SameLine();
170 if (ImGui.Button("Apply"))
226 if (ImGui.Button("Apply"))
171 {
227 {
@@ -177,6 +233,41
177 fontSize = OptionsWindow.fontSize,
233 fontSize = OptionsWindow.fontSize,
178 fontName = OptionsWindow.fontName
234 fontName = OptionsWindow.fontName
179 });
235 });
236
237 origFullscreen = OptionsWindow.newFullscreen;
238 origResolution = OptionsWindow.newResolution;
239
240 origFontName = OptionsWindow.fontName;
241 origFontSize = OptionsWindow.fontSize;
242 origProfanityLevel = OptionsWindow.profanityLevel;
243 origSoundEffectVolume = OptionsWindow.newSoundEffectVolume;
244 origSoundEffectsMute = OptionsWindow.newSoundEffectsMute;
245
246 bridgeEngine.setOptionMessages.Add(new SetOptionMessage { NewProfanitySetting = (ProfanityLevel)profanityLevel,
247 NewSoundEffectVolume = newSoundEffectVolume,
248 NewSoundEffectMuted = newSoundEffectsMute});
249 }
250
251 ImGui.SameLine();
252 if (ImGui.Button("Cancel")) {
253 bridgeEngine.typeMessages.Add(new ToggleWindowTypeMessage {Window = Window.Options});
254
255 OptionsWindow.newFullscreen = origFullscreen;
256 OptionsWindow.newResolution = origResolution;
257
258 OptionsWindow.fontName = origFontName;
259 OptionsWindow.fontSize = origFontSize;
260 OptionsWindow.profanityLevel = origProfanityLevel;
261 OptionsWindow.newSoundEffectVolume = origSoundEffectVolume;
262 OptionsWindow.newSoundEffectsMute = origSoundEffectsMute;
263
264
265 if ((origSoundEffectsMute != newSoundEffectsMute)
266 | (origSoundEffectVolume != newSoundEffectVolume)) {
267 bridgeEngine.setOptionMessages.Add(new SetOptionMessage { NewProfanitySetting = (ProfanityLevel)origProfanityLevel,
268 NewSoundEffectVolume = origSoundEffectVolume,
269 NewSoundEffectMuted = origSoundEffectsMute});
270 }
180 }
271 }
181
272
182
273
@@ -190,7 +281,7
190 {
281 {
191 bridgeEngine.typeMessages.Add(new ToggleWindowTypeMessage {Window = Window.Options});
282 bridgeEngine.typeMessages.Add(new ToggleWindowTypeMessage {Window = Window.Options});
192 }
283 }
193 }
284 }
194
285
195 public static void setFont(string fontName, int fontSize)
286 public static void setFont(string fontName, int fontSize)
196 {
287 {
@@ -55,7 +55,7
55 {ImGuiCol.Border, black},
55 {ImGuiCol.Border, black},
56 {ImGuiCol.BorderShadow, black},
56 {ImGuiCol.BorderShadow, black},
57
57
58 {ImGuiCol.PopupBg, white},
58 {ImGuiCol.PopupBg, grey},
59
59
60 {ImGuiCol.Button, grey_transparent},
60 {ImGuiCol.Button, grey_transparent},
61 {ImGuiCol.Text, black}
61 {ImGuiCol.Text, black}
@@ -2,14 +2,14
2 using JM.LinqFaster;
2 using JM.LinqFaster;
3 namespace isometricparkfna
3 namespace isometricparkfna
4 {
4 {
5 public class EmptyArrayException : Exception {
5 public class EmptyArrayException : Exception {
6 public EmptyArrayException() {
6 public EmptyArrayException() {
7 }
7 }
8
8
9 public EmptyArrayException(string message) : base(message) {
9 public EmptyArrayException(string message) : base(message) {
10 }
10 }
11
11
12 }
12 }
13 public class MathUtils
13 public class MathUtils
14 {
14 {
15 public MathUtils()
15 public MathUtils()
@@ -68,6 +68,22
68 }
68 }
69 }
69 }
70
70
71 public static float Clamp(float val, float min, float max)
72 {
73 if (val > max)
74 {
75 return max;
76 }
77 else if (val < min)
78 {
79 return min;
80 }
81 else
82 {
83 return val;
84 }
85 }
86
71 protected float Decrement(float value, float delta)
87 protected float Decrement(float value, float delta)
72 {
88 {
73 float magnitude = Math.Abs(value);
89 float magnitude = Math.Abs(value);
@@ -136,38 +152,46
136 return integers[index];
152 return integers[index];
137 }
153 }
138
154
139 public static float Percentile(float[] floats, float percentile) {
155 public static float Percentile(float[] floats, float percentile) {
140 if (floats.Length > 0) {
156 if (floats.Length > 0) {
141 Array.Sort(floats);
157 // Array.Sort(floats);
142 var raw_position = (floats.Length-1) * percentile;
158 var raw_position = (floats.Length-1) * percentile;
143
159
144 var lower_position = (int)raw_position;
160 var lower_position = (int)raw_position;
145 var higher_position = Math.Min((int)(raw_position+1), floats.Length-1);
161 var higher_position = Math.Min((int)(raw_position+1), floats.Length-1);
146
162
147 var remainder = (raw_position % 1);
163 var remainder = (raw_position % 1);
148
164
149 return (floats[lower_position] * (1-remainder)) + (floats[higher_position] * remainder);
165 return (floats[lower_position] * (1-remainder)) + (floats[higher_position] * remainder);
150 }
166 }
151 else {
167 else {
152 throw new EmptyArrayException("Array must not be empty");
168 throw new EmptyArrayException("Array must not be empty");
153 }
169 }
154 }
170 }
155
171
156 public static double Percentile(double[] doubles, double percentile) {
172 public static double Percentile(double[] doubles, double percentile) {
157 if (doubles.Length > 0) {
173 if (doubles.Length > 0) {
158 Array.Sort(doubles);
174 Array.Sort(doubles);
159 var raw_position = (doubles.Length-1) * percentile;
175 var raw_position = (doubles.Length-1) * percentile;
160
176
161 var lower_position = (int)raw_position;
177 var lower_position = (int)raw_position;
162 var higher_position = Math.Min((int)raw_position + 1, doubles.Length -1);
178 var higher_position = Math.Min((int)raw_position + 1, doubles.Length -1);
179
180 var remainder = (raw_position % 1);
163
181
164 var remainder = (raw_position % 1);
182 return (doubles[lower_position] * (1-remainder)) + (doubles[higher_position] * remainder);
183 }
184 else {
185 throw new EmptyArrayException("Array must not be empty");
186 }
187 }
165
188
166 return (doubles[lower_position] * (1-remainder)) + (doubles[higher_position] * remainder);
189 public static float SymmetricLog10(float num) {
167 }
190 return num > 0.0f ? (float)Math.Log10(num) : -(float)Math.Log10(-num);
168 else {
191 }
169 throw new EmptyArrayException("Array must not be empty");
192
170 }
193 public static double SymmetricLog10(double num) {
171 }
194 return num > 0.0f ? Math.Log10(num) : -Math.Log10(-num);
195 }
172 }
196 }
173 }
197 }
@@ -31,16 +31,12
31 <!-- <ProjectReference Include="..\encompass-cs\encompass-cs\encompass-cs.csproj" /> -->
31 <!-- <ProjectReference Include="..\encompass-cs\encompass-cs\encompass-cs.csproj" /> -->
32 <ProjectReference Include="..\SpriteFontPlus\src\SpriteFontPlus.FNA.Core.csproj" />
32 <ProjectReference Include="..\SpriteFontPlus\src\SpriteFontPlus.FNA.Core.csproj" />
33 <ProjectReference Include="..\encompass-cs\encompass-cs\encompass-cs.csproj" />
33 <ProjectReference Include="..\encompass-cs\encompass-cs\encompass-cs.csproj" />
34 <ProjectReference Include="..\ImPlot.NET\ImPlot.NET.csproj">
35 <!-- <Name>ImPlot.NET</Name> -->
36 </ProjectReference>
37 <ProjectReference Include="..\ImGui.NET\ImGui.NET.csproj">
34 <ProjectReference Include="..\ImGui.NET\ImGui.NET.csproj">
38 <!-- <Name>ImGui.NET</Name> -->
35 <!-- <Name>ImGui.NET</Name> -->
39 </ProjectReference>
36 </ProjectReference>
40 </ItemGroup>
37 </ItemGroup>
41
38
42 <ItemGroup>
39 <ItemGroup>
43 <Reference Include="System" />
44 <Reference Include="Newtonsoft.Json" Version="12.0.3">
40 <Reference Include="Newtonsoft.Json" Version="12.0.3">
45 <HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\netstandard2.0\Newtonsoft.Json.dll</HintPath>
41 <HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\netstandard2.0\Newtonsoft.Json.dll</HintPath>
46 </Reference>
42 </Reference>
@@ -75,9 +75,6
75 <Name>ImGui.NET</Name>
75 <Name>ImGui.NET</Name>
76 <HintPath>..\packages\ImGui.NET.1.78.0\lib\netstandard2.0\ImGui.NET.dll</HintPath>
76 <HintPath>..\packages\ImGui.NET.1.78.0\lib\netstandard2.0\ImGui.NET.dll</HintPath>
77 </ProjectReference>
77 </ProjectReference>
78 <ProjectReference Include="..\ImPlot.NET\ImPlot.NET.csproj">
79 <Name>ImPlot.NET</Name>
80 </ProjectReference>
81 <!-- </ProjectReference>\
78 <!-- </ProjectReference>\
82 -->
79 -->
83 <ProjectReference Include="..\encompass-cs\encompass-cs\encompass-cs.csproj">
80 <ProjectReference Include="..\encompass-cs\encompass-cs\encompass-cs.csproj">
@@ -89,8 +86,29
89 <None Include="Content\FNASound.wav">
86 <None Include="Content\FNASound.wav">
90 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
87 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
91 </None>
88 </None>
89 <None Include="Content\Click.wav">
90 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
91 </None>
92 <None Include="Content\ClickPart1.wav">
93 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
94 </None>
95 <None Include="Content\ClickPart2.wav">
96 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
97 </None>
98 <None Include="Content\ConstructionShort.wav">
99 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
100 </None>
101 <None Include="Content\Construction.wav">
102 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
103 </None>
104 <None Include="Content\Bell.wav">
105 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
106 </None>
92 <None Include="packages.config" />
107 <None Include="packages.config" />
93 <None Include="Content\part4_tileset.png">
108 <!-- <None Include="Content\part4_tileset.png"> -->
109 <!-- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> -->
110 <!-- </None> -->
111 <None Include="Content\merged_tileset.png">
94 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
112 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
95 </None>
113 </None>
96 <None Include="Content\solid_tileset.png">
114 <None Include="Content\solid_tileset.png">
@@ -102,10 +120,12
102 <None Include="Content\iosevka-medium.ttf">
120 <None Include="Content\iosevka-medium.ttf">
103 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
121 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
104 </None>
122 </None>
123 <None Include="Content\OCRA.ttf">
124 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
125 </None>
105 <Content Include="cimgui/win-x64/cimgui.dll" CopyToOutputDirectory="PreserveNewest" />
126 <Content Include="cimgui/win-x64/cimgui.dll" CopyToOutputDirectory="PreserveNewest" />
106 <Content Include="cimgui/osx-x64/cimgui.dylib" CopyToOutputDirectory="PreserveNewest" Link="libcimgui.dylib" />
127 <Content Include="cimgui/osx-x64/cimgui.dylib" CopyToOutputDirectory="PreserveNewest" Link="libcimgui.dylib" />
107 <Content Include="cimgui/linux-x64/cimgui.so" CopyToOutputDirectory="PreserveNewest" Link="libcimgui.so" />
128 <Content Include="cimgui/linux-x64/cimgui.so" CopyToOutputDirectory="PreserveNewest" Link="libcimgui.so" />
108 <Content Include="cimplot/linux-x64/cimplot.so" CopyToOutputDirectory="PreserveNewest" Link="libcimplot.so" />
109 <None Include="fnalibs\README.txt" />
129 <None Include="fnalibs\README.txt" />
110 <None Include="fnalibs\lib64\libFAudio.so.0" />
130 <None Include="fnalibs\lib64\libFAudio.so.0" />
111 <None Include="fnalibs\lib64\libmojoshader.so" />
131 <None Include="fnalibs\lib64\libmojoshader.so" />
You need to be logged in to leave comments. Login now