Compare commits

91 Commits

Author SHA1 Message Date
Simon Holmberg 31394b1e7c Panic works with death. Press P to spawn an enemy below group 2. 2012-11-01 00:33:49 +00:00
Simon Holmberg d9bff905b5 Proper bullet origin and offset. 2012-10-31 23:40:59 +00:00
Simon Holmberg dee5ed9e69 Open door 1 with O, door 2 with P 2012-10-31 23:40:46 +00:00
Simon Holmberg e85f98bb2c Destructible doors 2012-10-31 23:04:20 +00:00
Jace 23814c45ad Merge branch 'master' of github.com:sippeangelo/DepthsBelow 2012-10-31 19:56:31 +01:00
Jace bfeb94f9cb Merge branch 'master' of github.com:sippeangelo/DepthsBelow 2012-10-31 19:56:08 +01:00
Jace 1a9d27d9e3 Dead soldiers aren't visible on the UI 2012-10-31 19:56:00 +01:00
Niklas Ulf Anders Cullberg 5757d818fd Rocket and Boss Fixed 2012-10-31 19:55:53 +01:00
Niklas Ulf Anders Cullberg 778869ce44 BUB now appears. And Rocket Texture. 2012-10-31 19:44:50 +01:00
Jace b7f5b103fb Merge branch 'master' of github.com:sippeangelo/DepthsBelow 2012-10-31 19:22:42 +01:00
Jace be5b073f31 AP on UI, and bub is moving! 2012-10-31 19:22:28 +01:00
Niklas Ulf Anders Cullberg 105a31d38b The hell did I do? 2012-10-31 19:20:15 +01:00
Niklas Ulf Anders Cullberg 5179088158 BUB and PROTOTYPE 2012-10-31 19:18:32 +01:00
Jace 7ecf6dabce AP fixed 2012-10-31 18:21:54 +01:00
Niklas Ulf Anders Cullberg 3106c0ea63 Monster som inte dyker upp förren runda X
This almost looks like a game now!
2012-10-31 12:00:55 +01:00
Niklas Ulf Anders Cullberg 1c7c8b600d Added a few enemies... 2012-10-31 00:45:39 +01:00
Niklas Ulf Anders Cullberg e8353e2002 ... BUB Without transparency 2012-10-31 00:24:27 +01:00
Niklas Ulf Anders Cullberg 450ffdb68c BossPreperation 2012-10-31 00:19:07 +01:00
Simon Holmberg 2dbad13a64 Merge branch 'master' of github.com:sippeangelo/DepthsBelow
Conflicts:
	DepthsBelow/DepthsBelow/KeyboardInput.cs
	DepthsBelow/DepthsBelow/SmallEnemy.cs
2012-10-30 23:40:24 +00:00
Simon Holmberg adb18a6e77 A solid door! 2012-10-30 23:38:31 +00:00
Simon Holmberg 860637fb20 Entities with collision components can now be solid to the pathfinder. 2012-10-30 22:02:22 +00:00
Simon Holmberg d80a2104bf EntityManager now static. 2012-10-30 21:50:48 +00:00
Niklas Ulf Anders Cullberg a785067218 What? I just added a few extra surprises... 2012-10-30 22:50:40 +01:00
Niklas Ulf Anders Cullberg 8f0b981bd3 Monster Autokill disabled, HP in bars Updated 2012-10-30 22:22:45 +01:00
Niklas Ulf Anders Cullberg f14623c882 HitChance displayed, Stats Rearranged 2012-10-30 22:04:16 +01:00
Niklas Ulf Anders Cullberg f2b1b731e5 Start the game with full Action Points...
Dang, I freaked out when the soldiers couldn't move...
2012-10-30 21:34:54 +01:00
Niklas Ulf Anders Cullberg d1b3661eed Action Points Movement Perfected 2012-10-29 16:44:59 +01:00
Niklas Ulf Anders Cullberg 82ad94eb4f Converted shooting to Action Points 2012-10-29 15:31:00 +01:00
Jace e708c62a50 Merge branch 'master' of github.com:sippeangelo/DepthsBelow 2012-10-29 15:29:22 +01:00
Jace 81e102fe44 UI is no longer being stupid with bubbling 2012-10-29 15:15:33 +01:00
Niklas Ulf Anders Cullberg 9ba26cae70 People die when they are killed
This means that enemies can now kill the players without mercy.
2012-10-29 15:05:10 +01:00
Jace ed0953ff50 Silly static texture... 2012-10-29 14:36:51 +01:00
Jace ef13987044 Yay pathfinding! (AGAIN (YES IT ACTUALLY WORKS NOW)) 2012-10-29 14:36:42 +01:00
Simon Holmberg 3c40dd354e Map is not leaking anymore -.- 2012-10-29 02:52:41 +00:00
Simon Holmberg 600661b911 SPIRAL BY CHRISTIAN 2012-10-29 02:49:26 +00:00
Niklas Ulf Anders Cullberg 236d6c2859 Enemies die when shot, also, rockets with R 2012-10-29 00:56:25 +01:00
Niklas Ulf Anders Cullberg 9a0ff658b4 The hell. Vi kan skjuta med S. 2012-10-29 00:51:14 +01:00
Niklas Ulf Anders Cullberg 4a60e4e2d5 All Monsters now move 2012-10-28 22:48:06 +01:00
Niklas Ulf Anders Cullberg 5c59a2277b Monsters turn in direction walking 2012-10-27 15:53:02 +02:00
Simon Holmberg 7d42fb1bf0 Scratch that. NOW they're working properly. 2012-10-24 01:27:20 +02:00
Simon Holmberg b9f49712db Mouse controls are working properly again. 2012-10-24 00:10:12 +02:00
Simon Holmberg c62a00ab80 Tileset modifications 2012-10-23 22:57:01 +02:00
Jace 723215294b Panic works. Variable brightness. Brighter lights. Updated tileset. 2012-10-23 16:40:19 +02:00
Simon Holmberg 5007e0b50e New tilesets, entities won't be drawn unless illuminated. 2012-10-23 01:28:46 +02:00
Jace cd913a8401 Mouse buttons properly recognized in interface.
Also file mode changes. I don't care.
2012-10-22 17:05:26 +02:00
Simon Holmberg 5f44eb257b Monster test spawn added to map 2012-10-22 02:30:07 +02:00
Simon Holmberg 35bcd8d9cc fixup! Merge branch 'master' of github.com:sippeangelo/DepthsBelow 2012-10-22 02:29:51 +02:00
Simon Holmberg 10d2160a8b Merge branch 'master' of github.com:sippeangelo/DepthsBelow 2012-10-22 02:10:38 +02:00
Simon Holmberg 89376478b0 Fake lights! Yay! 2012-10-22 02:10:19 +02:00
Niklas Ulf Anders Cullberg d36592318f MonsterSpawn added, reacts to a distance...
Have not tested, I think I failed, I don't think I should transfer
around lists like that... But I didn't make the things static at
least..!
2012-10-22 00:36:54 +02:00
Simon Holmberg dca73efe29 Merge branch 'master' of github.com:sippeangelo/DepthsBelow
Conflicts:
	DepthsBelow/DepthsBelow/KeyboardInput.cs
	DepthsBelow/DepthsBelow/MouseInput.cs
	DepthsBelow/DepthsBelow/Soldier.cs
	DepthsBelow/DepthsBelow/Utility.cs
2012-10-21 22:55:10 +02:00
Simon Holmberg cf3bc09a4a Working unit frames and dynamic soldier grouping 2012-10-21 22:50:18 +02:00
Niklas Ulf Anders Cullberg 6f6ee2d340 Steps taken and distance taken into account 2012-10-20 17:31:26 +02:00
Niklas Ulf Anders Cullberg 2fe63f51c0 Shooting calculation displayed, needs work 2012-10-20 13:01:57 +02:00
Niklas Ulf Anders Cullberg 6034dbf3b2 Inserted calculation if hover over enemy
Though text is not displayed, only the calculation is done.
2012-10-20 11:56:06 +02:00
Simon Holmberg f8c1422eeb Events bubble down the frame stack until it finds a frame with a handler.
For example, this allows you to have an OnClick handler on a parent frame, and child frames who cover the parent frame, but the parent frame still receives the click events (unless the child subscribes to the event).
2012-10-19 23:40:03 +02:00
Simon Holmberg 9d92736932 Frame field "Layer" controls render order and prevents event bubbling.
Reworked GUI events.
2012-10-19 23:27:51 +02:00
Simon Holmberg 0c923357b4 fixup! Moved DrawLine from RenderHelpers to Utility. 2012-10-19 03:46:22 +02:00
Simon Holmberg ce2264c737 Moved DrawLine from RenderHelpers to Utility. 2012-10-19 03:45:17 +02:00
Simon Holmberg 5cb05d1c3f Created a turn manager. 2012-10-19 03:01:50 +02:00
Simon Holmberg d376031193 Shorthands for exposing objects and functions to Lua. 2012-10-19 03:01:26 +02:00
Simon Holmberg 9f47ad9a57 Documentation added to Component.*, Entity, EntityManager, Grid, GUI.* and Utility classes.
Minor cleanups.
2012-10-18 01:34:46 +02:00
Simon Holmberg c59ff9778a Created and implemented EntityManager. PixelTransform and GridTransform phased out. 2012-10-17 23:44:58 +02:00
Jace 8e1f18d233 Renamed some stuff 2012-10-17 11:54:48 +02:00
Niklas Ulf Anders Cullberg c7a1317a32 Nothing 2012-10-17 11:39:07 +02:00
Jace 28b6e20f94 Merge branch 'master' of github.com:sippeangelo/DepthsBelow 2012-10-17 11:28:05 +02:00
Jace 00159095ed Lua tooltips 2012-10-17 11:27:31 +02:00
Niklas Ulf Anders Cullberg 2a12df147b Cannot Walk Through Monsters 2012-10-17 11:26:59 +02:00
Niklas Ulf Anders Cullberg 092dc176a8 Added Stats, damage code, stuff 2012-10-17 11:20:09 +02:00
Niklas Ulf Anders Cullberg 4f8a5ccdb2 Added Utility, Stat, removed FindDistance(Core) 2012-10-17 10:52:05 +02:00
Simon Holmberg bcbddf1b2c Merge branch 'lua'
Conflicts:
	DepthsBelow/DepthsBelow/Core.cs
	DepthsBelow/DepthsBelowContent/DepthsBelowContent.contentproj
2012-10-17 01:55:30 +02:00
Simon Holmberg 9f838a6d39 Lua stuffs is working :D 2012-10-17 01:52:58 +02:00
Jace a6391527ec Lua stuffs 2012-10-16 20:55:13 +02:00
Niklas Ulf Anders Cullberg 275727f861 Working on calculation of chance to hit 2012-10-16 17:27:35 +02:00
Niklas Ulf Anders Cullberg 16f2d57aec You can now fire selected units with S 2012-10-16 16:18:30 +02:00
Jace 9df0077257 More GUI stuff 2012-10-16 13:22:24 +02:00
Niklas Ulf Anders Cullberg d38e93dc19 Still working on Shooting (shouldn't work yet) 2012-10-11 13:03:19 +02:00
Niklas Ulf Anders Cullberg 0a4eafefa3 Shot and Shooting Classes added (not working yet) 2012-10-11 12:38:45 +02:00
Simon Holmberg 0b98d60753 Merge branch 'master' of github.com:sippeangelo/DepthsBelow
Conflicts:
	DepthsBelow/DepthsBelow/Core.cs
2012-10-09 19:20:13 +02:00
Simon Holmberg ff17d421fe Basic GUI library! 2012-10-09 19:18:14 +02:00
Niklas Ulf Anders Cullberg 047899b43d Monster will stop beside soldier and not on top 2012-10-09 19:11:48 +02:00
Niklas Ulf Anders Cullberg 29288df309 Enemy hunt closest soldier on enter 2012-10-09 19:01:14 +02:00
Niklas Ulf Anders Cullberg ff4e874d47 Made that last more efficient... 2012-10-09 16:19:44 +02:00
Niklas Ulf Anders Cullberg 7ea3b0be99 Doesn't move when changing direction looking 2012-10-09 16:14:11 +02:00
Niklas Ulf Anders Cullberg 6e3b2f2f94 NumberOfSteps, CurrentStep, Enter = Next Turn
Also, added KeyboardInput
2012-10-09 15:43:07 +02:00
Jace 0c9e99b146 Some pathfinding stuff, modifications to small enemy 2012-10-05 12:13:37 +02:00
Jace e89a657740 DrawLine part of RenderHelper 2012-10-05 12:12:24 +02:00
Jace b1f723580d Merge branch 'master' of github.com:sippeangelo/DepthsBelow 2012-10-05 11:06:17 +02:00
Niklas Ulf Anders Cullberg b4dc13e420 Tried making Enemy by copying Soldier. +Monster
... I think I failed, though...

Oh, that monster was made by Christian
2012-10-03 12:33:22 +02:00
Jace 2d554faeb3 Pathfinder IsMoving, Stop 2012-10-03 11:17:01 +02:00
Niklas Ulf Anders Cullberg 4658decf32 SelectionRectangle forms in all directions 2012-10-03 11:01:41 +02:00
134 changed files with 5138 additions and 8005 deletions
Regular → Executable
View File
Regular → Executable
+1 -14
View File
@@ -13,8 +13,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AStar", "AStar\AStar.csproj
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{FF7D4CEE-291C-4F85-9630-977446A466D3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Krypton", "Krypton\Krypton\Krypton.csproj", "{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -71,23 +69,12 @@ Global
{CD3F949D-54AA-4D38-99DB-92905A375D84}.Release|Mixed Platforms.Build.0 = Release|x86
{CD3F949D-54AA-4D38-99DB-92905A375D84}.Release|x86.ActiveCfg = Release|x86
{CD3F949D-54AA-4D38-99DB-92905A375D84}.Release|x86.Build.0 = Release|x86
{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}.Debug|Any CPU.ActiveCfg = Debug|x86
{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}.Debug|Mixed Platforms.Build.0 = Debug|x86
{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}.Debug|x86.ActiveCfg = Debug|x86
{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}.Debug|x86.Build.0 = Debug|x86
{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}.Release|Any CPU.ActiveCfg = Release|x86
{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}.Release|Mixed Platforms.ActiveCfg = Release|x86
{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}.Release|Mixed Platforms.Build.0 = Release|x86
{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}.Release|x86.ActiveCfg = Release|x86
{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{CD3F949D-54AA-4D38-99DB-92905A375D84} = {FF7D4CEE-291C-4F85-9630-977446A466D3}
{EC3F6988-459C-4783-89E9-F34C0CC731C7} = {FF7D4CEE-291C-4F85-9630-977446A466D3}
{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3} = {FF7D4CEE-291C-4F85-9630-977446A466D3}
{CD3F949D-54AA-4D38-99DB-92905A375D84} = {FF7D4CEE-291C-4F85-9630-977446A466D3}
EndGlobalSection
EndGlobal
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0"/>
</startup>
</configuration>
+21 -5
View File
@@ -35,28 +35,39 @@ namespace DepthsBelow
return Vector2.Transform(screenPos, Matrix.Invert(Transform));
}
public Rectangle ScreenToWorld(Rectangle screenRectangle)
{
var pos = ScreenToWorld(new Vector2(screenRectangle.X, screenRectangle.Y));
var size = ScreenToWorld(new Vector2(screenRectangle.X + screenRectangle.Width, screenRectangle.Y + screenRectangle.Height)) - pos;
return new Rectangle((int)pos.X, (int)pos.Y, (int)size.X, (int)size.Y);
}
public Vector2 WorldToScreen(Vector2 worldPos)
{
return Vector2.Transform(worldPos, Transform);
}
public Rectangle WorldToScreen(Rectangle worldRectangle)
{
var pos = WorldToScreen(new Vector2(worldRectangle.X, worldRectangle.Y));
var size = WorldToScreen(new Vector2(worldRectangle.X + worldRectangle.Width, worldRectangle.Y + worldRectangle.Height)) - pos;
return new Rectangle((int)pos.X, (int)pos.Y, (int)size.X, (int)size.Y);
}
public void Update(GameTime gameTime)
{
if (!core.IsActive)
return;
float elapsed = gameTime.ElapsedGameTime.Milliseconds / 1000.0f;
MouseState ms = Mouse.GetState();
if (ms.X < 20)
Position.X += Speed * elapsed;
if (ms.X > Core.GraphicsDevice.Viewport.Width - 20)
if (ms.X > core.GraphicsDevice.Viewport.Width - 20)
Position.X -= Speed * elapsed;
if (ms.Y < 20)
Position.Y += Speed * elapsed;
if (ms.Y > Core.GraphicsDevice.Viewport.Height - 20)
if (ms.Y > core.GraphicsDevice.Viewport.Height - 20)
Position.Y -= Speed * elapsed;
int scrollChange = ms.ScrollWheelValue - lastMouseState.ScrollWheelValue;
@@ -88,6 +99,11 @@ namespace DepthsBelow
Transform *= Matrix.CreateTranslation(new Vector3(change.X, change.Y, 0));
}
Transform = Matrix.Identity
* Matrix.CreateRotationZ(Rotation)
* Matrix.CreateScale(Zoom)
* Matrix.CreateTranslation(new Vector3(Position.X, Position.Y, 0));
lastMouseState = ms;
}
}
+39 -6
View File
@@ -8,25 +8,58 @@ using Microsoft.Xna.Framework.Graphics;
namespace DepthsBelow.Component
{
/// <summary>
/// Component for handling collisions.
/// Contains a rectangle which defines its hitbox.
/// </summary>
public class Collision : Component
{
/// <summary>
/// The collision rectangle.
/// </summary>
public Rectangle Rectangle;
public int Width;
public int Height;
/// <summary>
/// Whether the entity is solid to other entities.
/// </summary>
public bool Solid = false;
/// <summary>
/// Width of the collision rectangle.
/// </summary>
public int Width
{
get { return this.Rectangle.Width; }
set { this.Rectangle.Width = value; }
}
/// <summary>
/// Height of the collision rectangle.
/// </summary>
public int Height
{
get { return this.Rectangle.Height; }
set { this.Rectangle.Height = value; }
}
/// <summary>
/// Create a collision component.
/// </summary>
/// <param name="parent">Parent entity.</param>
/// <param name="width">Width of the collision rectangle.</param>
/// <param name="height">Height of the collision rectangle.</param>
public Collision(Entity parent, int width, int height)
: base(parent)
{
this.Width = width;
this.Height = height;
this.Rectangle = new Rectangle(0, 0, width, height);
}
/// <summary>
/// Updates the position of the collision rectangle to the position of its parent entity.
/// </summary>
/// <param name="gameTime"></param>
public override void Update(GameTime gameTime)
{
Transform transform = this.Parent.GetComponent<Transform>();
var transform = this.Parent.GetComponent<Transform>();
this.Rectangle.X = (int)transform.World.X;
this.Rectangle.Y = (int)transform.World.Y;
}
+10
View File
@@ -6,8 +6,14 @@ using Microsoft.Xna.Framework;
namespace DepthsBelow.Component
{
/// <summary>
/// Base component.
/// </summary>
public class Component
{
/// <summary>
/// Parent entity of which the component belongs.
/// </summary>
public Entity Parent;
public Component(Entity parent)
@@ -15,6 +21,10 @@ namespace DepthsBelow.Component
Parent = parent;
}
/// <summary>
/// Virtual component update function.
/// </summary>
/// <param name="gameTime"></param>
public virtual void Update(GameTime gameTime)
{
+19 -61
View File
@@ -3,77 +3,29 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace DepthsBelow.Component
{
public class Flashlight : Component
{
public float Range
{
get { return KryptonLight.Range; }
set { KryptonLight.Range = value; }
}
public float Fov
{
get { return KryptonLight.Fov; }
set { KryptonLight.Fov = value; }
}
public float Intensity
{
get { return KryptonLight.Intensity; }
set { KryptonLight.Intensity = value; }
}
public float Angle
{
get { return KryptonLight.Angle; }
set { KryptonLight.Angle = value; }
}
public Vector2 Position
{
get { return KryptonLight.Position; }
set { KryptonLight.Position = value; }
}
public float Scale = 1f;
public float Intensity = 1f;
public float Angle = 0;
public Vector2 Position { get; private set; }
public Vector2 Origin;
public Texture2D Texture;
public Color Color;
public Color Color
{
get { return KryptonLight.Color; }
set { KryptonLight.Color = value; }
}
public bool IsOn
{
get { return KryptonLight.IsOn; }
set { KryptonLight.IsOn = value; }
}
public Krypton.Lights.ShadowType ShadowType
{
get { return KryptonLight.ShadowType; }
set { KryptonLight.ShadowType = value; }
}
public Krypton.Lights.Light2D KryptonLight;
public bool IsOn = true;
public Flashlight(Entity parent)
: base(parent)
{
KryptonLight = new Krypton.Lights.Light2D()
{
Texture = Krypton.LightTextureBuilder.CreatePointLight(Core.GraphicsDevice, 512),
Range = (float)(100),
Position = parent.Transform.World + Parent.Transform.World.Origin,
Angle = parent.Transform.World.Rotation,
Color = Color.White,
Intensity = 1f,
Fov = MathHelper.TwoPi,
IsOn = true,
ShadowType = Krypton.Lights.ShadowType.Illuminated
};
}
public static explicit operator Krypton.Lights.Light2D(Flashlight flashlight)
{
return flashlight.KryptonLight;
Texture = GameServices.GetService<ContentManager>().Load<Texture2D>("images/lights/spot_wide");
Color = Color.White;
Origin = new Vector2(50, Texture.Height / 2f);
}
public override void Update(GameTime gameTime)
@@ -82,5 +34,11 @@ namespace DepthsBelow.Component
Angle = Parent.Transform.World.Rotation;
}
public void Draw(SpriteBatch spriteBatch)
{
if (IsOn)
spriteBatch.Draw(Texture, Position, null, Color * Intensity, Angle, Origin, Scale, SpriteEffects.None, 0);
}
}
}
@@ -1,46 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
namespace DepthsBelow.Component
{
[Obsolete("Deprecated in favour of Component.Transform")]
public class GridTransform : Component
{
public Point Position;
public int X
{
get
{
return Position.X;
}
set
{
Position.X = value;
}
}
public int Y
{
get
{
return Position.Y;
}
set
{
Position.Y = value;
}
}
public GridTransform(Entity parent) : base(parent)
{
Position = Point.Zero;
}
public Vector2 ToWorld()
{
return Grid.GridToWorld(Position);
}
}
}
+210 -116
View File
@@ -1,118 +1,212 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using AStar;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using AStar;
using Microsoft.Xna.Framework;
namespace DepthsBelow.Component
{
/// <summary>
/// Component that handles pathfinding.
/// </summary>
public class PathFinder : Component
{
/// <summary>
/// A pathfinder node.
/// </summary>
public class Node
{
/// <summary>
/// Grid position of the node.
/// </summary>
public Point Position;
/// <summary>
/// A* F-score
/// </summary>
public int F;
/// <summary>
/// A* G-score
/// </summary>
public int G;
/// <summary>
/// Explicit conversion between A* library node and Node object.
/// </summary>
/// <param name="aStarNode"></param>
/// <returns></returns>
public static explicit operator Node(AStar.PathFinderNode aStarNode)
{
return new Node
{
Position = new Point(aStarNode.X, aStarNode.Y),
F = aStarNode.F,
G = aStarNode.G
};
}
}
/// <summary>
/// Start position of the path.
/// </summary>
public Point Start { get; private set; }
/// <summary>
/// A collision bytemap.
/// 0 = unwalkable node
/// 1 = walkable node
/// </summary>
public byte[,] CollisionMap;
private Point goal;
/// <summary>
/// Sets a goal point and finds a path to it.
/// After a path is created, call Next() go get the next node in the path.
/// </summary>
public Point Goal
{
get { return goal; }
set
{
this.goal = value;
this.FindPath(this.Parent.GetComponent<Transform>().Grid.Position, value, null);
}
}
/// <summary>
/// Is a path in progress?
/// </summary>
public bool IsMoving
{
get
{
return path != null && path.Count() != 0;
}
}
public int Length
{
get
{
return (path != null) ? path.Count : 0;
}
}
private AStar.PathFinderFast pathFinder;
private List<AStar.PathFinderNode> path;
public PathFinder(Entity parent)
: base(parent)
{
}
public override void Update(GameTime gameTime)
{
/*if (path != null && path.Count != 0)
{
var nextNode = path.Last();
var nodePos = new Point(nextNode.X, nextNode.Y);
Parent.Transform.Grid.Position = nodePos;
if (Parent.Transform.World == (Vector2)Parent.Transform.Grid)
path.Remove(nextNode);
}*/
base.Update(gameTime);
}
/// <summary>
/// Gets the next node of the current path.
/// </summary>
/// <returns>The next node in the path.</returns>
public Node Next()
{
if (path == null)
return null;
if (path.Count == 0)
return null;
var nextNode = path.Last();
path.Remove(nextNode);
return (Node)nextNode;
}
/// <summary>
/// Cancels the current path in memory.
/// </summary>
public void Stop()
{
path = null;
}
/// <summary>
/// Finds a path between two points.
/// </summary>
/// <param name="start">The start point.</param>
/// <param name="goal">The goal point.</param>
/// <param name="appendCollisionMap">A list of unwalkable points that will be joined with the original collision map.</param>
/// <returns></returns>
private List<AStar.PathFinderNode> FindPath(Point start, Point goal, List<Point> appendCollisionMap)
{
byte[,] mapCollisionMap = Core.Map.GetCollisionMap();
// Add solid collision component entities
foreach (var collision in EntityManager.GetComponents<Collision>())
{
if (collision.Solid && collision.Parent != this.Parent)
{
var pos = Grid.WorldToGrid(new Vector2(collision.Rectangle.X, collision.Rectangle.Y));
namespace DepthsBelow.Component
{
public class PathFinder : Component
{
public class Node
{
public Point Position;
public int F;
public int G;
public static explicit operator Node(AStar.PathFinderNode aStarNode)
{
return new Node
for (int x = 0; x < Math.Ceiling(collision.Rectangle.Width / (double)Grid.TileSize); x++)
for (int y = 0; y < Math.Ceiling(collision.Rectangle.Height / (double)Grid.TileSize); y++)
{
try
{
Position = new Point(aStarNode.X, aStarNode.Y),
F = aStarNode.F,
G = aStarNode.G
};
}
}
public Point Start { get; private set; }
public byte[,] CollisionMap;
private Point goal;
public Point Goal
{
get { return goal; }
set
{
this.goal = value;
//this.Start = this.Parent.GetComponent<Transform>().Grid.Position;
this.FindPath(this.Parent.GetComponent<Transform>().Grid.Position, value, null);
}
}
private AStar.PathFinderFast pathFinder;
private List<AStar.PathFinderNode> path;
public PathFinder(Entity parent)
: base(parent)
{
}
public override void Update(GameTime gameTime)
{
/*if (path != null && path.Count != 0)
{
var nextNode = path.Last();
var nodePos = new Point(nextNode.X, nextNode.Y);
Parent.Transform.Grid.Position = nodePos;
if (Parent.Transform.World == (Vector2)Parent.Transform.Grid)
path.Remove(nextNode);
}*/
base.Update(gameTime);
}
public Node Next()
{
if (path == null)
return null;
if (path.Count == 0)
return null;
var nextNode = path.Last();
path.Remove(nextNode);
return (Node)nextNode;
}
private List<AStar.PathFinderNode> FindPath(Point start, Point goal, List<Point> appendCollisionMap)
{
byte[,] mapCollisionMap = Core.Map.GetCollisionMap();
if (appendCollisionMap != null)
foreach (var point in appendCollisionMap)
mapCollisionMap[point.X, point.Y] = 0;
pathFinder = new AStar.PathFinderFast(mapCollisionMap);
pathFinder.Formula = AStar.HeuristicFormula.Manhattan;
pathFinder.Diagonals = false;
pathFinder.HeavyDiagonals = false;
pathFinder.HeuristicEstimate = 2;
pathFinder.PunishChangeDirection = false;
pathFinder.TieBreaker = false;
pathFinder.SearchLimit = 50000;
pathFinder.DebugProgress = false;
pathFinder.DebugFoundPath = false;
var _start = new System.Drawing.Point(start.X, start.Y);
var _goal = new System.Drawing.Point(goal.X, goal.Y);
//path = Core.PathFinder.FindPath(_start, _goal);
path = pathFinder.FindPath(_start, _goal);
if (path == null)
Debug.WriteLine(this.Parent.ToString() + ": Path not found!");
this.CollisionMap = new byte[100, 100];
return path;
}
public void RecreatePath(List<Point> appendCollisionMap)
{
FindPath(this.Parent.GetComponent<Transform>().Grid.Position, this.Goal, appendCollisionMap);
}
}
}
mapCollisionMap[pos.X + x, pos.Y + y] = 0;
}
catch
{
}
}
}
}
if (appendCollisionMap != null)
foreach (var point in appendCollisionMap)
mapCollisionMap[point.X, point.Y] = 0;
pathFinder = new AStar.PathFinderFast(mapCollisionMap);
pathFinder.Formula = AStar.HeuristicFormula.Manhattan;
pathFinder.Diagonals = false;
pathFinder.HeavyDiagonals = false;
pathFinder.HeuristicEstimate = 2;
pathFinder.PunishChangeDirection = false;
pathFinder.TieBreaker = false;
pathFinder.SearchLimit = 50000;
pathFinder.DebugProgress = false;
pathFinder.DebugFoundPath = false;
var _start = new System.Drawing.Point(start.X, start.Y);
var _goal = new System.Drawing.Point(goal.X, goal.Y);
//path = Core.PathFinder.FindPath(_start, _goal);
path = pathFinder.FindPath(_start, _goal);
if (path == null)
Debug.WriteLine(this.Parent.ToString() + ": Path not found!");
//this.CollisionMap = new byte[100, 100];
return path;
}
/// <summary>
/// Recreate the current path in memory with a list of unwalkable points that will be joined with the original collision map.
/// </summary>
/// <param name="appendCollisionMap">A list of unwalkable points that will be joined with the collision map.</param>
public void RecreatePath(List<Point> appendCollisionMap)
{
FindPath(this.Parent.GetComponent<Transform>().Grid.Position, this.Goal, appendCollisionMap);
}
}
}
@@ -1,51 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
namespace DepthsBelow.Component
{
[Obsolete("Deprecated in favour of Component.Transform")]
public class PixelTransform : Component
{
public Vector2 Position;
public float X
{
get
{
return Position.X;
}
set
{
Position.X = value;
}
}
public float Y
{
get
{
return Position.Y;
}
set
{
Position.Y = value;
}
}
public float Rotation;
public Vector2 Origin;
public PixelTransform(Entity parent)
: base(parent)
{
Position = Vector2.Zero;
Rotation = 0.0f;
Origin = Vector2.Zero;
}
public Point ToGrid()
{
return Grid.WorldToGrid(Position);
}
}
}
+21 -4
View File
@@ -7,14 +7,32 @@ using Microsoft.Xna.Framework.Graphics;
namespace DepthsBelow.Component
{
/// <summary>
/// Sprite render component.
/// Handles rendering of a 2D texture.
/// </summary>
public class SpriteRenderer : Component
{
/// <summary>
/// The texture to be rendered.
/// </summary>
public Texture2D Texture;
public Texture2D AlternativeTexture;
/// <summary>
/// Color modifier.
/// </summary>
public Color Color;
/// <summary>
/// Scale of the texture.
/// </summary>
public float Scale;
public Vector2 Offset;
public SpriteEffects SpriteEffects;
public SpriteRenderer(Entity parent) : base(parent)
public SpriteRenderer(Entity parent)
: base(parent)
{
this.Color = Color.White;
this.Scale = 1;
@@ -23,9 +41,8 @@ namespace DepthsBelow.Component
public void Draw(SpriteBatch spriteBatch)
{
Transform transform = this.Parent.GetComponent<Transform>();
//spriteBatch.Draw(Texture, tc.Position, this.Color);
spriteBatch.Draw(Texture, transform.World.Position + transform.World.Origin, null, Color, transform.World.Rotation, transform.World.Origin, Scale, SpriteEffects, 0);
var transform = this.Parent.GetComponent<Transform>();
spriteBatch.Draw(Texture, transform.World.Position + transform.World.Origin + Offset, null, Color, transform.World.Rotation, transform.World.Origin, Scale, SpriteEffects, 0);
}
}
}
+141
View File
@@ -0,0 +1,141 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
namespace DepthsBelow.Component
{
public class Stat : Component
{
/// <summary>
/// The current health points of the unit
/// </summary>
public float HP = 0;
public float _MaxHP = 100;
/// <summary>
/// Gets or sets the max HP.
/// </summary>
public float MaxHP
{
get { return _MaxHP; }
set
{
_MaxHP = value;
if (HP == 0)
HP = value;
}
}
public int MaxPanic = 100;
protected int hp = 0;
protected int defence = 0;
protected int stepsTaken = 0;
protected int distanceToTarget = 0;
protected int panic = 0;
protected int soldierAim = 100;
protected int weaponAccuracy = 0;
protected int weaponStrength = 0;
protected int ammo = 0;
protected int enemyDodge = 0;
protected int penaltyRange = 5;
Vector2 rememberedPosition = Vector2.Zero;
public Vector2 Remember
{
get { return rememberedPosition; }
set { rememberedPosition = value; }
}
public int GetAim
{
get { return soldierAim + weaponAccuracy; }
set { weaponAccuracy = value; }
}
public int GetStep
{
get { return stepsTaken; }
set { stepsTaken = value; }
}
public int GetDodge
{
get { return enemyDodge; }
set { enemyDodge = value; }
}
public int Life
{
get { return hp; }
set
{
hp = value;
if (hp <= 0) {
//If you kill me, I will become stronger than you can ever imagine.
Kill();
}
}
}
public int Defence
{
get { return defence; }
set { defence = value; }
}
public int Strength
{
get { return weaponStrength; }
set { weaponStrength = value; }
}
public void Kill()
{
hp = 0;
Parent.Remove();
//Console.WriteLine("Blargh! I am dead!");
}
public int Penalty(int distance)
{
return panic/* + GetPenalty(stepsTaken)*/ + (int)(GetPenalty(distance));
}
public Stat(Entity parent)
: base (parent)
{
rememberedPosition = Vector2.Zero;
}
public bool targetInSight()
{
return false;
}
public int GetPenalty(int distance)
{
int penalty = 0;
if (distance >= penaltyRange * 3)
{
distance -= penaltyRange * 3;
penalty = penaltyRange + penaltyRange * 3 + penaltyRange * 5 + distance * 10;
}
else if (distance >= penaltyRange * 2)
{
distance -= penaltyRange * 2;
penalty = penaltyRange + penaltyRange * 3 + distance * 5;
}
else if (distance >= penaltyRange)
{
distance -= penaltyRange;
penalty = penaltyRange + distance * 3;
}
else
{
penalty = distance;
}
return penalty;
}
}
}
+73 -5
View File
@@ -7,11 +7,21 @@ using Microsoft.Xna.Framework;
namespace DepthsBelow.Component
{
/// <summary>
/// Transform component.
/// Handles both grid and world positions and rotations, while keeping them in sync.
/// </summary>
public class Transform : Component
{
/// <summary>
/// Represents a grid position.
/// </summary>
public class GridTransform
{
private Point position;
/// <summary>
/// Sets the grid position and updates the world position of WorldTransform.
/// </summary>
public Point Position
{
get { return position; }
@@ -22,6 +32,9 @@ namespace DepthsBelow.Component
}
}
/// <summary>
/// Shorthand for the grid x-position.
/// </summary>
public int X
{
get { return position.X; }
@@ -31,6 +44,10 @@ namespace DepthsBelow.Component
masterTransform.World.SetWithoutRelation((Vector2)this);
}
}
/// <summary>
/// Shorthand for the grid y-position.
/// </summary>
public int Y
{
get { return position.Y; }
@@ -41,11 +58,17 @@ namespace DepthsBelow.Component
}
}
/// <summary>
/// Implicit conversion between GridTransform and a Point grid position.
/// </summary>
public static implicit operator Point(GridTransform gridTransform)
{
return gridTransform.position;
}
/// <summary>
/// Explicit conversion between GridTransform and a Vector2 world position.
/// </summary>
public static explicit operator Vector2(GridTransform gridTransform)
{
var worldPosition = DepthsBelow.Grid.GridToWorld(gridTransform.Position);
@@ -53,11 +76,19 @@ namespace DepthsBelow.Component
}
private readonly Transform masterTransform;
/// <summary>
/// Create a GridTransform within a master Transform component.
/// </summary>
/// <param name="masterTransform">The master Transform component.</param>
public GridTransform(Transform masterTransform)
{
this.masterTransform = masterTransform;
}
/// <summary>
/// Sets the position data without updating the associated world position.
/// </summary>
/// <param name="position">The grid position.</param>
public void SetWithoutRelation(Point position)
{
this.position = position;
@@ -67,6 +98,9 @@ namespace DepthsBelow.Component
public class WorldTransform
{
private Vector2 position;
/// <summary>
/// Sets the world position and updates the grid position of GridTransform.
/// </summary>
public Vector2 Position
{
get { return position; }
@@ -77,6 +111,9 @@ namespace DepthsBelow.Component
}
}
/// <summary>
/// Shorthand for the world x-position.
/// </summary>
public float X
{
get { return position.X; }
@@ -86,6 +123,10 @@ namespace DepthsBelow.Component
masterTransform.Grid.SetWithoutRelation((Point)this);
}
}
/// <summary>
/// Shorthand for the world y-position.
/// </summary>
public float Y
{
get { return position.Y; }
@@ -96,20 +137,27 @@ namespace DepthsBelow.Component
}
}
/// <summary>
/// Rotation in radians.
/// </summary>
public float Rotation;
public void Rotate(int directionX, int directionY)
{
Rotation = (float)Math.Atan(directionY/directionX);
}
/// <summary>
/// Origin to rotate around.
/// </summary>
public Vector2 Origin;
/// <summary>
/// Implicit conversion between WorldTransform and a Vector2 world position.
/// </summary>
public static implicit operator Vector2(WorldTransform worldTransform)
{
return worldTransform.Position;
}
/// <summary>
/// Explicit conversion between WorldTransform and a Point grid position.
/// </summary>
public static explicit operator Point(WorldTransform worldTransform)
{
var gridPosition = DepthsBelow.Grid.WorldToGrid(worldTransform.Position);
@@ -117,18 +165,32 @@ namespace DepthsBelow.Component
}
private readonly Transform masterTransform;
/// <summary>
/// Create a WorldTransform within a master Transform component.
/// </summary>
/// <param name="masterTransform">The master Transform component.</param>
public WorldTransform(Transform masterTransform)
{
this.masterTransform = masterTransform;
}
/// <summary>
/// Sets the position data without updating the associated grid position.
/// </summary>
/// <param name="position">The world position.</param>
public void SetWithoutRelation(Vector2 position)
{
this.position = position;
}
}
/// <summary>
/// The grid position.
/// </summary>
public GridTransform Grid;
/// <summary>
/// The world position.
/// </summary>
public WorldTransform World;
public Transform(Entity parent)
@@ -138,11 +200,17 @@ namespace DepthsBelow.Component
World = new WorldTransform(this);
}
/// <summary>
/// Implicit conversion between Transform and a Point grid position.
/// </summary>
public static implicit operator Point(Transform transform)
{
return transform.Grid;
}
/// <summary>
/// Implicit conversion between Transform and a Vector2 world position.
/// </summary>
public static implicit operator Vector2(Transform transform)
{
return transform.World;
+261 -207
View File
@@ -1,207 +1,261 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Krypton.Lights;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace DepthsBelow
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Core : Microsoft.Xna.Framework.Game
{
public static GraphicsDevice GraphicsDevice;
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
public Krypton.KryptonEngine KryptonEngine;
public Camera Camera;
public static MouseInput MouseInput;
public List<Soldier> Squad;
public static Map Map;
public Core()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferWidth = 1280;
graphics.PreferredBackBufferHeight = 720;
graphics.IsFullScreen = false;
//graphics.SynchronizeWithVerticalRetrace = false;
this.IsFixedTimeStep = false;
graphics.ApplyChanges();
this.IsMouseVisible = true;
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
GraphicsDevice = graphics.GraphicsDevice;
KryptonEngine = new Krypton.KryptonEngine(this, "KryptonEffect");
// Initialize lighting engine
this.KryptonEngine.Initialize();
this.KryptonEngine.SpriteBatchCompatablityEnabled = true;
this.KryptonEngine.CullMode = CullMode.CullClockwiseFace;
this.KryptonEngine.AmbientColor = new Color(35, 35, 35);
Camera = new Camera(this);
Squad = new List<Soldier>();
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(Core.GraphicsDevice);
Map = Content.Load<Map>("maps/Cave.Level1");
// Load map objects
Map.Initialize(this, KryptonEngine);
// DEBUG: Test lights
/*var light = new Krypton.Lights.Light2D()
{
Texture = Krypton.LightTextureBuilder.CreatePointLight(Core.GraphicsDevice, 512),
Range = (float)(500),
Color = Color.White,
Intensity = 1f,
Angle = MathHelper.TwoPi,
X = 17 * Grid.TileSize,
Y = 7 * Grid.TileSize,
Fov = MathHelper.TwoPi / 15,
IsOn = true,
ShadowType = ShadowType.Illuminated
};
this.KryptonEngine.Lights.Add(light);*/
var light = new Krypton.Lights.Light2D()
{
Texture = Krypton.LightTextureBuilder.CreatePointLight(Core.GraphicsDevice, 512),
Range = (float)(100),
Color = Color.White,
Intensity = 1f,
Angle = MathHelper.TwoPi,
X = 17 * Grid.TileSize,
Y = 7 * Grid.TileSize,
Fov = MathHelper.TwoPi,
IsOn = true,
ShadowType = ShadowType.Illuminated
};
this.KryptonEngine.Lights.Add(light);
// TODO: use this.Content to load your game content here
Soldier.LoadContent(this);
MouseInput = new MouseInput(this);
MouseInput.LoadContent();
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
Camera.Update(gameTime);
MouseInput.Update(gameTime);
// Update soldiers in squad
foreach (var soldier in Squad)
soldier.Update(gameTime);
//foreach (Krypton.Lights.Light2D light in KryptonEngine.Lights)
// light.Position = Camera.ScreenToWorld(new Vector2(Mouse.GetState().X, Mouse.GetState().Y));
base.Update(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
// Assign the matrix and pre-render the lightmap.
this.KryptonEngine.Matrix = Camera.Transform;
this.KryptonEngine.Bluriness = 1;
this.KryptonEngine.LightMapPrepare();
GraphicsDevice.Clear(Color.Black);
/*
* Draw game world
*/
//GraphicsDevice.BlendState = BlendState.AlphaBlend;
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, SamplerState.PointClamp, null, null, null, Camera.Transform);
// Draw the level
Map.Draw(spriteBatch);
// Draw units
foreach (var soldier in Squad)
{
var sr = soldier.GetComponent<Component.SpriteRenderer>();
if (sr != null)
sr.Draw(spriteBatch);
}
spriteBatch.End();
/*
* Draw Krypton lighting
*/
this.KryptonEngine.Draw(gameTime);
/*
* Draw HUD elements
*/
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null, null, Camera.Transform);
// Draw mouse input visuals
MouseInput.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using DepthsBelow.GUI;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace DepthsBelow
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Core : Microsoft.Xna.Framework.Game
{
public static GraphicsDeviceManager GraphicsDeviceManager;
private SpriteBatch spriteBatch;
private Effect lightShader;
private RenderTarget2D lightRenderTarget;
private RenderTarget2D sceneRenderTarget;
public Lua Lua;
public TurnManager TurnManager;
public Camera Camera;
public Interface Interface;
public/* static*/ MouseInput MouseInput;
public static KeyboardInput KeyboardInput;
public List<Soldier> Squad;
public DynamicGroupManager GroupManager;
public List<SmallEnemy> Swarm;
public List<Shot> Volley;
public List<MonsterSpawn> Spawn;
public static Map Map;
public SmallEnemy TestMonster;
public int Brightness = 30;
public Core()
{
GraphicsDeviceManager = new GraphicsDeviceManager(this);
GraphicsDeviceManager.PreferredBackBufferWidth = 1280;
GraphicsDeviceManager.PreferredBackBufferHeight = 720;
GraphicsDeviceManager.IsFullScreen = false;
//graphics.SynchronizeWithVerticalRetrace = false;
GraphicsDeviceManager.ApplyChanges();
this.IsFixedTimeStep = false;
this.IsMouseVisible = true;
Content.RootDirectory = "Content";
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
GameServices.AddService<GraphicsDevice>(GraphicsDevice);
GameServices.AddService<ContentManager>(Content);
Lua = new Lua();
TurnManager = new TurnManager(new string[] { "Player", "Computer" });
Camera = new Camera(this);
Interface = new Interface(this);
Squad = new List<Soldier>();
Swarm = new List<SmallEnemy>();
Volley = new List<Shot>();
Spawn = new List<MonsterSpawn>();
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
lightShader = Content.Load<Effect>("shaders/LightEffect");
lightRenderTarget = new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, false, SurfaceFormat.Color, DepthFormat.None, 0, RenderTargetUsage.PreserveContents);
sceneRenderTarget = new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height);
Map = Content.Load<Map>("maps/prototyp2");
//Map = Content.Load<Map>("maps/Aztek.Test");
//Map = Content.Load<Map>("maps/Cave.Level1");
// Load map objects
Map.ParseObjects(this);
Squad[0].Name = "Dean H. Jones";
Squad[0].Transform.World.Rotation = -MathHelper.PiOver2;
Squad[1].Name = "Walter L. Verville";
Squad[1].Transform.World.Rotation = -MathHelper.PiOver2;
Squad[2].Name = "Patrick Y. Southerland";
Squad[2].Transform.World.Rotation = -MathHelper.PiOver2;
Squad[3].Name = "Andrew C. Friend";
Squad[3].Transform.World.Rotation = -MathHelper.PiOver2;
Squad[4].Name = "Gary B. Whitley";
Squad[4].Transform.World.Rotation = -MathHelper.PiOver2;
// Center the camera on a unit
Camera.Position = Squad[0].Transform.World.Position * -1 + new Vector2(GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2);
GroupManager = new DynamicGroupManager(Squad.Cast<Entity>().ToList(), (float)Grid.TileSize * 3.5f);
Interface.CreateUnitFrames(Squad);
// TODO: use this.Content to load your game content here
Soldier.LoadContent();
//SmallEnemy.LoadContent();
//Shot.LoadContent();
MouseInput = new MouseInput(this);
MouseInput.LoadContent();
KeyboardInput = new KeyboardInput(this);
TestMonster = new SmallEnemy(ref Swarm);
TestMonster.X = 12;
TestMonster.Y = 4;
Swarm.Add(TestMonster);
// Load Lua scripts after everything is created
Lua.LoadScripts();
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
Camera.Update(gameTime);
MouseInput.Update(gameTime);
KeyboardInput.Update(gameTime);
EntityManager.Update(gameTime);
Interface.Update(gameTime);
GUIManager.Update(gameTime);
base.Update(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
MouseState ms = Mouse.GetState();
// Draw to the lighting render target
GraphicsDevice.SetRenderTarget(lightRenderTarget);
GraphicsDevice.Clear(new Color(Brightness, Brightness, Brightness));
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Additive, SamplerState.PointClamp, null, null, null,
Camera.Transform);
// Draw flashlights
foreach (var light in EntityManager.GetComponents<Component.Flashlight>())
light.Draw(spriteBatch);
spriteBatch.End();
GraphicsDevice.SetRenderTarget(null);
// Draw the scene to a render target
GraphicsDevice.SetRenderTarget(sceneRenderTarget);
GraphicsDevice.Clear(Color.Black);
// Start drawing using the Camera transform
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, SamplerState.PointClamp, null, null, null,
Camera.Transform);
// Draw the level
Map.Draw(spriteBatch);
// Draw entities
foreach (var spriteRenderer in EntityManager.GetComponents<Component.SpriteRenderer>())
{
// Only render illuminated entities
var position = Camera.WorldToScreen(spriteRenderer.Parent.Transform.World + spriteRenderer.Parent.Transform.World.Origin);
var sourceRect = new Rectangle((int)position.X, (int)position.Y, 1, 1);
if (
sourceRect.X >= 0
&& sourceRect.Y >= 0
&& sourceRect.X < lightRenderTarget.Width
&& sourceRect.Y < lightRenderTarget.Height
)
{
var lightData = new Color[1];
lightRenderTarget.GetData<Color>(0, sourceRect, lightData, 0, 1);
if (lightData[0] != new Color(Brightness, Brightness, Brightness))
spriteRenderer.Draw(spriteBatch);
}
}
#if DEBUG
var debugTexture = new Texture2D(GraphicsDevice, 1, 1);
debugTexture.SetData(new Color[] { Color.White });
foreach (var collisionComponent in EntityManager.GetComponents<Component.Collision>())
{
spriteBatch.Draw(debugTexture, collisionComponent.Rectangle, Color.Red * 0.5f);
}
#endif
// Draw mouse input visuals
MouseInput.Draw(spriteBatch);
spriteBatch.End();
GraphicsDevice.SetRenderTarget(null);
// Draw the scene from the render target with the light shader
lightShader.Parameters["LightsTexture"].SetValue(lightRenderTarget);
lightShader.CurrentTechnique.Passes[0].Apply();
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.PointClamp, null, null, lightShader,
Matrix.Identity);
spriteBatch.Draw(sceneRenderTarget, Vector2.Zero, Color.White);
spriteBatch.End();
// Draw GUI components
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.AnisotropicClamp, null, null, null, Matrix.Identity);
GUIManager.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
+47
View File
@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;
namespace DepthsBelow
{
static class CustomExtensions
{
/// <summary>
/// Load all content within a certain folder. The function
/// returns a dictionary where the file name, without type
/// extension, is the key and the texture object is the value.
///
/// The contentFolder parameter has to be relative to the
/// game.Content.RootDirectory folder.
///
/// http://danielsaidi.wordpress.com/2010/01/26/xna-load-all-content-files-in-a-folder/
/// </summary>
/// <typeparam name="T">The content type.</typeparam>
/// <param name="contentManager">The content manager for which content is to be loaded.</param>
/// <param name="contentFolder">The game project root folder relative folder path.</param>
/// <returns>A list of loaded content objects.</returns>
public static Dictionary<String, T> LoadContent<T>(this ContentManager contentManager, string contentFolder)
{
//Load directory info, abort if none
DirectoryInfo dir = new DirectoryInfo(contentManager.RootDirectory + "\\" + contentFolder);
if (!dir.Exists)
throw new DirectoryNotFoundException();
//Init the resulting list
Dictionary<String, T> result = new Dictionary<String, T>();
//Load all files that matches the file filter
FileInfo[] files = dir.GetFiles("*.*");
foreach (FileInfo file in files)
{
string key = Path.GetFileNameWithoutExtension(file.Name);
result[key] = contentManager.Load<T>(contentFolder + "/" + key);
}
//Return the result
return result;
}
}
}
+33 -21
View File
@@ -47,6 +47,7 @@
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>x86</PlatformTarget>
<XnaCompressContent>false</XnaCompressContent>
<DocumentationFile>bin\x86\Debug\DepthsBelow.XML</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>pdbonly</DebugType>
@@ -70,9 +71,13 @@
<GenerateManifests>true</GenerateManifests>
</PropertyGroup>
<PropertyGroup>
<SignManifests>true</SignManifests>
<SignManifests>false</SignManifests>
</PropertyGroup>
<ItemGroup>
<Reference Include="LuaInterface, Version=2.0.0.16708, Culture=neutral, processorArchitecture=x86">
<HintPath>..\..\LuaInterface\LuaInterface.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
</Reference>
<Reference Include="Microsoft.Xna.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
<Private>False</Private>
</Reference>
@@ -107,15 +112,9 @@
<Private>False</Private>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Xml">
<Private>False</Private>
</Reference>
<Reference Include="System.Core">
<Private>False</Private>
</Reference>
<Reference Include="System.Xml.Linq">
<Private>False</Private>
</Reference>
<Reference Include="System.Net">
<Private>False</Private>
</Reference>
@@ -123,12 +122,27 @@
<ItemGroup>
<Compile Include="Camera.cs" />
<Compile Include="Component\Flashlight.cs" />
<Compile Include="Door.cs" />
<Compile Include="DynamicGroupManager.cs" />
<Compile Include="MonsterSpawn.cs" />
<Compile Include="TurnManager.cs" />
<Compile Include="CustomExtensions.cs" />
<Compile Include="EntityManager.cs" />
<Compile Include="GameServices.cs" />
<Compile Include="Interface.cs" />
<Compile Include="Lua.cs" />
<Compile Include="Shot.cs" />
<Compile Include="Component\Stat.cs" />
<Compile Include="GUIManager.cs" />
<Compile Include="GUI\Button.cs" />
<Compile Include="GUI\Frame.cs" />
<Compile Include="GUI\Text.cs" />
<Compile Include="KeyboardInput.cs" />
<Compile Include="Component\PathFinder.cs" />
<Compile Include="Component\Transform.cs" />
<Compile Include="Grid.cs" />
<Compile Include="Component\Collision.cs" />
<Compile Include="Component\Component.cs" />
<Compile Include="Component\GridTransform.cs" />
<Compile Include="Core.cs" />
<Compile Include="Entity.cs" />
<Compile Include="Map.cs" />
@@ -136,8 +150,9 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Program.cs" />
<Compile Include="Component\SpriteRenderer.cs" />
<Compile Include="SmallEnemy.cs" />
<Compile Include="Soldier.cs" />
<Compile Include="Component\PixelTransform.cs" />
<Compile Include="Utility.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Game.ico" />
@@ -148,10 +163,6 @@
<Project>{CD3F949D-54AA-4D38-99DB-92905A375D84}</Project>
<Name>AStar</Name>
</ProjectReference>
<ProjectReference Include="..\..\Krypton\Krypton\Krypton.csproj">
<Project>{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}</Project>
<Name>Krypton</Name>
</ProjectReference>
<ProjectReference Include="..\DepthsBelowContent\DepthsBelowContent.contentproj">
<Name>DepthsBelowContent %28Content%29</Name>
<XnaReferenceType>Content</XnaReferenceType>
@@ -186,16 +197,17 @@
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<None Include="DepthsBelow_TemporaryKey.pfx" />
<None Include="App.config" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\Microsoft.Xna.GameStudio.targets" />
<!--
To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
<!--
To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
View File
Binary file not shown.
+91
View File
@@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DepthsBelow.Component;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace DepthsBelow
{
public class Door : Entity
{
public Texture2D Texture;
public static Texture2D TextureOpen;
public static Texture2D TextureClosed;
public static Texture2D TextureDestroyed;
public bool Alive = true;
public bool IsOpen;
public Door(bool horizontal)
: base()
{
LoadContent();
IsOpen = false;
if (horizontal)
Transform.World.Rotation = -MathHelper.PiOver2;
var rc = new SpriteRenderer(this) { Texture = Texture, Color = Color.White };
if (horizontal)
rc.Offset.Y += Texture.Width;
AddComponent(rc);
Collision cc;
if (horizontal)
cc = new Collision(this, Texture.Height, Texture.Width);
else
cc = new Collision(this, Texture.Width, Texture.Height);
cc.Solid = true;
AddComponent(cc);
}
public void LoadContent()
{
TextureOpen = GameServices.GetService<ContentManager>().Load<Texture2D>("images/door_open");
TextureClosed = GameServices.GetService<ContentManager>().Load<Texture2D>("images/door_closed");
TextureDestroyed = GameServices.GetService<ContentManager>().Load<Texture2D>("images/door_destroyed");
Texture = TextureClosed;
}
public void Open()
{
if (Alive && !IsOpen)
{
IsOpen = true;
this.GetComponent<SpriteRenderer>().Texture = TextureOpen;
this.GetComponent<Collision>().Solid = false;
}
}
public void Close()
{
if (Alive && IsOpen)
{
IsOpen = false;
this.GetComponent<SpriteRenderer>().Texture = TextureClosed;
this.GetComponent<Collision>().Solid = true;
}
}
public void Toggle()
{
if (IsOpen)
Close();
else
Open();
}
public void Kill()
{
Alive = false;
this.GetComponent<SpriteRenderer>().Texture = TextureDestroyed;
this.GetComponent<Collision>().Solid = false;
}
}
}
+130
View File
@@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
namespace DepthsBelow
{
public class DynamicGroupManager
{
public class Group
{
public List<Entity> Entities;
public float Panic;
public float MaxPanic
{
get
{
float maxPanic = 0;
foreach (var entity in Entities)
{
var stats = entity.GetComponent<Component.Stat>();
if (stats != null && stats.Life > 0)
maxPanic += stats.MaxPanic;
}
return maxPanic;
}
}
}
private List<Entity> entities;
public float MaxRange;
public List<Group> Groups;
public DynamicGroupManager(List<Entity> entities, float maxRange)
{
this.entities = entities;
this.MaxRange = maxRange;
UpdateGroups();
}
public void UpdateGroups()
{
if (Groups == null)
Groups = new List<Group>();
var newGroups = CreateGroups(MaxRange);
foreach (var newGroup in newGroups)
{
for (int index = 0; index < newGroup.Entities.Count; index++)
{
var entity = newGroup.Entities[index];
Group oldGroup = null;
// Find the group the entity belonged to before
foreach (var group in Groups)
{
if (@group.Entities.Contains(entity))
{
oldGroup = @group;
break;
}
}
if (oldGroup != null)
{
if (entity.GetComponent<Component.Stat>().Life > 0)
{
newGroup.Panic += (oldGroup.Panic/oldGroup.MaxPanic)*(float) entity.GetComponent<Component.Stat>().MaxPanic;
//if (entity.GetComponent<Component.Stat>().Life > 0)
oldGroup.Panic -= (oldGroup.Panic/oldGroup.MaxPanic)*(float) entity.GetComponent<Component.Stat>().MaxPanic;
oldGroup.Entities.Remove(entity);
}
}
else
newGroup.Panic = 125;
}
}
Groups = newGroups;
}
private List<Group> CreateGroups(float maxRange)
{
var alreadyGrouped = new List<Entity>();
var groups = new List<Group>();
for (int index = 0; index < entities.Count; index++)
{
var soldier = entities[index];
if (!alreadyGrouped.Contains(soldier) && soldier.GetComponent<Component.Stat>().Life > 0)
{
var group = new List<Entity>();
GetNearChain(ref group, soldier, maxRange);
alreadyGrouped.AddRange(group);
if (group.Count > 0)
groups.Add(new Group() { Entities = group });
}
}
return groups;
}
// Get all entities who are close to each other in a chain
private void GetNearChain(ref List<Entity> group, Entity entity, float maxRange)
{
for (int index = 0; index < entities.Count; index++)
{
var nearSoldier = entities[index];
if (!group.Contains(nearSoldier) && nearSoldier.GetComponent<Component.Stat>().Life > 0)
{
float distance = Vector2.Distance(nearSoldier.Transform.World + nearSoldier.Transform.World.Origin,
entity.Transform.World + entity.Transform.World.Origin);
if (distance <= maxRange)
{
group.Add(nearSoldier);
GetNearChain(ref group, nearSoldier, maxRange);
}
}
}
}
}
}
+77 -19
View File
@@ -6,44 +6,94 @@ using Microsoft.Xna.Framework;
namespace DepthsBelow
{
public class Entity
/// <summary>
/// Game object.
/// </summary>
public class Entity : IDisposable
{
List<Component.Component> Components;
/// <summary>
/// Shorthand for transform component.
/// </summary>
public Component.Transform Transform;
public Component.PixelTransform pixelTransform;
public Component.GridTransform gridTransform;
/// <summary>
/// Shorthand to the grid transform position.
/// </summary>
public Point Position
{
get { return this.Transform.Grid.Position; }
set { this.Transform.Grid.Position = value; }
}
/// <summary>
/// Shorthand to the grid transform x-position.
/// </summary>
public int X
{
get { return this.Transform.Grid.X; }
set
{
this.Transform.Grid.X = value;
}
set { this.Transform.Grid.X = value; }
}
/// <summary>
/// Shorthand to the grid transform y-position.
/// </summary>
public int Y
{
get { return this.Transform.Grid.Y; }
set
{
this.Transform.Grid.Y = value;
}
set { this.Transform.Grid.Y = value; }
}
protected Core core;
public Entity(Core core)
/// <summary>
/// Storage for property data
/// </summary>
public Dictionary<string, object> Properties = new Dictionary<string, object>();
/// <summary>
/// Shorthand for frame properties.
/// </summary>
public object this[string key]
{
this.core = core;
get { return Properties[key]; }
set { Properties[key] = value; }
}
/// <summary>
/// Creates a game object and adds it to the referenced entity manager.
/// </summary>
///
public Entity()
{
EntityManager.Add(this);
Components = new List<Component.Component>();
Transform = new Component.Transform(this);
AddComponent(Transform);
pixelTransform = new Component.PixelTransform(this);
AddComponent(pixelTransform);
gridTransform = new Component.GridTransform(this);
AddComponent(gridTransform);
}
/// <summary>
/// Implementation of IDisposable.
/// Dispose of any unmanaged resources.
/// </summary>
public virtual void Dispose()
{
}
/// <summary>
/// Removes the entity from the game world and disposes
/// potential unmanaged resources.
/// </summary>
public virtual void Remove()
{
EntityManager.Remove(this);
Dispose();
}
/// <summary>
/// Get the reference to a component contained in the entity.
/// </summary>
/// <typeparam name="T">The component type.</typeparam>
/// <returns>Returns the component of requested type.</returns>
public T GetComponent<T>() where T : Component.Component
{
foreach (Component.Component c in Components)
@@ -55,11 +105,19 @@ namespace DepthsBelow
return null;
}
/// <summary>
/// Add a component to the entity.
/// </summary>
/// <param name="c">the component to add</param>
public void AddComponent(Component.Component c)
{
Components.Add(c);
}
/// <summary>
/// Update the entity and all child components.
/// </summary>
/// <param name="gameTime"></param>
public virtual void Update(GameTime gameTime)
{
// Update components
+104
View File
@@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace DepthsBelow
{
/// <summary>
/// Manages a group of entities.
/// </summary>
public static class EntityManager
{
public static List<Entity> Entities = new List<Entity>();
/// <summary>
/// Implementation of IDisposable.
/// Dispose of the entity manager, and all entities it contains.
/// </summary>
public static void Dispose()
{
foreach (var entity in Entities)
entity.Dispose();
Entities = null;
}
/// <summary>
/// Add an entity to the entity manager.
/// </summary>
/// <param name="entity">The entity to add.</param>
public static void Add(Entity entity)
{
Entities.Add(entity);
}
/// <summary>
/// Remove an entity from the entity manager.
/// </summary>
/// <param name="entity">The entity to remove.</param>
public static void Remove(Entity entity)
{
Entities.Remove(entity);
}
/// <summary>
/// Reset the entity manager, disposing any entities it contains.
/// </summary>
public static void Reset()
{
foreach (var entity in Entities)
entity.Dispose();
Entities.Clear();
}
/// <summary>
/// Get the reference to a component contained in the entity.
/// </summary>
/// <typeparam name="T">The component type.</typeparam>
/// <returns>Returns the component of requested type.</returns>
public static List<T> GetComponents<T>() where T : Component.Component
{
List<T> components = new List<T>();
foreach (var entity in Entities)
{
var component = entity.GetComponent<T>();
if (component != null)
components.Add(component);
}
return components;
}
public static List<T> GetEntities<T>() where T : Entity
{
return Entities.OfType<T>().ToList();
}
/// <summary>
/// Update all entities handled by the entity manager.
/// </summary>
/// <param name="gameTime"></param>
public static void Update(GameTime gameTime)
{
foreach (var entity in Entities.ToList())
entity.Update(gameTime);
}
/// <summary>
/// Draw all entities handled by the entity manager.
/// </summary>
/// <param name="spriteBatch"></param>
public static void Draw(SpriteBatch spriteBatch)
{
foreach (var entity in Entities)
{
entity.GetComponent<Component.SpriteRenderer>().Draw(spriteBatch);
}
}
}
}
+64
View File
@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace DepthsBelow.GUI
{
/// <summary>
/// A button frame which can handle clicks.
/// </summary>
public class Button : Frame
{
//public delegate void OnClickHandler(Point pos);
/// <summary>
/// Handler of OnClick events.
/// </summary>
//public OnClickHandler OnClick;
private MouseState lastMouseState;
public Button()
: base()
{
}
public Button(Frame parent)
: base(parent)
{
}
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
/*MouseState ms = Mouse.GetState();
if (ms.LeftButton == ButtonState.Released && lastMouseState.LeftButton == ButtonState.Pressed)
{
// HACK: This should be handled globally somewhere else to prevent event bubbling
if (
ms.X >= AbsoluteRectangle.Left
&& ms.X < AbsoluteRectangle.Right
&& ms.Y >= AbsoluteRectangle.Top
&& ms.Y < AbsoluteRectangle.Bottom)
{
if (OnClick != null)
{
var clickPos = new Point(ms.X - AbsoluteRectangle.X, ms.Y - AbsoluteRectangle.Y);
OnClick(clickPos);
}
}
}
lastMouseState = ms;*/
}
}
}
+401
View File
@@ -0,0 +1,401 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace DepthsBelow.GUI
{
/// <summary>
/// A generic GUI frame.
/// </summary>
public class Frame
{
public string Name;
/// <summary>
/// Width of the frame.
/// </summary>
public int Width
{
get { return this.Rectangle.Width; }
set { this.Rectangle.Width = value; }
}
/// <summary>
/// Height of the frame.
/// </summary>
public int Height
{
get { return this.Rectangle.Height; }
set { this.Rectangle.Height = value; }
}
/// <summary>
/// X-position of the frame.
/// </summary>
public int X
{
get { return this.Rectangle.X; }
set { this.Rectangle.X = value; }
}
/// <summary>
/// Y-position of the frame.
/// </summary>
public int Y
{
get { return this.Rectangle.Y; }
set { this.Rectangle.Y = value; }
}
/// <summary>
/// The x-coordinate of the left side of the frame.
/// </summary>
public int Left
{
get { return this.Rectangle.Left; }
}
/// <summary>
/// The y-coordinate of the top side of the frame.
/// </summary>
public int Top
{
get { return this.Rectangle.Top; }
}
/// <summary>
/// The x-coordinate of the right side of the frame.
/// </summary>
public int Right
{
get { return this.Rectangle.Right; }
}
/// <summary>
/// The y-coordinate of the bottom side of the frame.
/// </summary>
public int Bottom
{
get { return this.Rectangle.Bottom; }
}
/// <summary>
/// Rectangle of the frame.
/// </summary>
public Rectangle Rectangle;
/// <summary>
/// Absolute rectangle of the frame.
/// Takes parent frame positions in consideration and converts negative widths and heights.
/// </summary>
public Rectangle AbsoluteRectangle
{
get
{
if (Parent != null)
return Utility.MakeRectanglePositive(new Rectangle(Parent.AbsoluteRectangle.X + Rectangle.X, Parent.AbsoluteRectangle.Y + Rectangle.Y, Rectangle.Width, Rectangle.Height));
else
return Utility.MakeRectanglePositive(Rectangle);
}
}
/// <summary>
/// Optional background texture of the frame.
/// </summary>
public Texture2D Texture;
/// <summary>
/// Texture color tint.
/// </summary>
public Color Color;
public bool _Visible = true;
/// <summary>
/// If the frame is visible or not.
/// </summary>
public bool Visible
{
get { return (Parent != null) ? _Visible && Parent.Visible : _Visible; }
set { _Visible = value; }
}
/// <summary>
/// The layer of the frame.
/// Bigger number means closer to the screen.
/// </summary>
public int Layer = 0;
/// <summary>
/// Gets the sum of this frame and all parent layers.
/// </summary>
public int LayerSum
{
get { return (Parent != null) ? this.Layer + Parent.LayerSum : this.Layer; }
}
/// <summary>
/// The unique identifier of the frame.
/// </summary>
public int UID { get; private set; }
/// <summary>
/// Potential parent frame.
/// </summary>
public Frame Parent;
/// <summary>
/// Potential children frames.
/// </summary>
public List<Frame> Children;
/// <summary>
/// Storage for property data
/// </summary>
public Dictionary<string, object> Properties = new Dictionary<string, object>();
/// <summary>
/// Shorthand for frame properties.
/// </summary>
public object this[string key]
{
get { return Properties[key]; }
set { Properties[key] = value; }
}
/// <summary>
/// Controls whether mouse events can be handled by the frame.
/// </summary>
public bool MouseEnabled = false;
#region Events
/// <summary>
/// Handler for click events.
/// </summary>
/// <param name="frame">The frame.</param>
/// <param name="args">The <see cref="GUIManager.MouseEventArgs" /> instance containing the event data.</param>
public delegate void OnClickHandler(Frame frame, GUIManager.MouseEventArgs args);
/// <summary>
/// Occurs when the frame is clicked inside it's bounding rectangle.
/// </summary>
public event OnClickHandler OnClick;
/// <summary>
/// Handler for press events.
/// </summary>
/// <param name="frame">The frame.</param>
/// <param name="args">The <see cref="GUIManager.MouseEventArgs" /> instance containing the event data.</param>
public delegate void OnPressHandler(Frame frame, GUIManager.MouseEventArgs args);
/// <summary>
/// Occurs when the frame is clicked inside it's bounding rectangle.
/// </summary>
public event OnPressHandler OnPress;
/// <summary>
/// Handler for release events.
/// </summary>
/// <param name="frame">The frame.</param>
/// <param name="args">The <see cref="GUIManager.MouseEventArgs" /> instance containing the event data.</param>
public delegate void OnReleaseHandler(Frame frame, GUIManager.MouseEventArgs args);
/// <summary>
/// Occurs when the frame is clicked inside it's bounding rectangle.
/// </summary>
public event OnReleaseHandler OnRelease;
/// <summary>
/// Handler for mouse over events.
/// </summary>
/// <param name="frame">The frame.</param>
/// <param name="args">The <see cref="GUIManager.MouseEventArgs" /> instance containing the event data.</param>
public delegate void OnMouseOverHandler(Frame frame, GUIManager.MouseEventArgs args);
/// <summary>
/// Occurs when the frame is clicked inside it's bounding rectangle.
/// </summary>
public event OnMouseOverHandler OnMouseOver;
/// <summary>
/// Handler for mouse out events.
/// </summary>
/// <param name="frame">The frame.</param>
/// <param name="args">The <see cref="GUIManager.MouseEventArgs" /> instance containing the event data.</param>
public delegate void OnMouseOutHandler(Frame frame, GUIManager.MouseEventArgs args);
/// <summary>
/// Occurs when the frame is clicked inside it's bounding rectangle.
/// </summary>
public event OnMouseOutHandler OnMouseOut;
/// <summary>
/// Raises the specified event by name.
/// </summary>
/// <param name="eventName">Name of the event.</param>
/// <param name="eventArgs">The <see cref="EventArgs" /> instance containing the event data.</param>
/// <returns>Returns true if any event was raised.</returns>
public bool Raise(string eventName, EventArgs eventArgs)
{
// Get the event field info
var fieldInfo = this.GetType().GetField(eventName, BindingFlags.NonPublic | BindingFlags.Instance);
// If the event exists
if (fieldInfo != null)
{
var eventDelegate = (MulticastDelegate)fieldInfo.GetValue(this);
// If there's any subscribed events...
if (eventDelegate != null)
{
// Invoke their raise methods
foreach (var handler in eventDelegate.GetInvocationList())
{
try
{
handler.Method.Invoke(handler.Target, new object[] { this, eventArgs });
}
catch (Exception)
{
return false;
}
}
return true;
}
return false;
}
return false;
}
/// <summary>
/// Gets the subscriber count for a specific event.
/// </summary>
/// <param name="eventName">Name of the event.</param>
/// <returns>Returns the number of subscribers of the event.</returns>
public int GetSubscriberCount(string eventName)
{
// Get the event field info
var fieldInfo = this.GetType().GetField(eventName, BindingFlags.NonPublic | BindingFlags.Instance);
// If the event exists
if (fieldInfo != null)
{
var eventDelegate = (MulticastDelegate)fieldInfo.GetValue(this);
// If there's any subscribed events...
if (eventDelegate != null)
return eventDelegate.GetInvocationList().Length;
return 0;
}
return 0;
}
#endregion
private MouseState lastMouseState;
/// <summary>
/// Create a blank frame.
/// </summary>
public Frame()
{
this.Rectangle = Rectangle.Empty;
this.Texture = null;
this.Color = Color.White;
this.Children = new List<Frame>();
this.UID = GUIManager.Add(this);
}
/// <summary>
/// Create a blank frame as the child of a frame.
/// </summary>
/// <param name="parentFrame">The parent frame.</param>
public Frame(Frame parentFrame)
: this()
{
this.Parent = parentFrame;
}
/// <summary>
/// Add a child frame to the frame.
/// </summary>
/// <param name="childFrame">The child frame to add.</param>
public void AddChild(Frame childFrame)
{
childFrame.Parent = this;
if (!Children.Contains(childFrame))
Children.Add(childFrame);
}
/// <summary>
/// Remove a child frame from the frame.
/// </summary>
/// <param name="childFrame">The child frame to remove.</param>
public void RemoveChild(Frame childFrame)
{
if (Children.Contains(childFrame))
Children.Remove(childFrame);
}
/// <summary>
/// Destroys the frame and all its children.
/// </summary>
public void Destroy()
{
if (Parent != null)
Parent.RemoveChild(this);
GUIManager.Remove(this);
}
/// <summary>
/// Set the background texture of the frame.
/// </summary>
/// <param name="fileName">Filename of the texture.</param>
public void SetTexture(string fileName)
{
Texture = GameServices.GetService<ContentManager>().Load<Texture2D>(fileName);
}
public virtual void Update(GameTime gameTime)
{
/*MouseState ms = Mouse.GetState();
if (ms.LeftButton == ButtonState.Released && lastMouseState.LeftButton == ButtonState.Pressed)
{
// HACK: This should be handled globally somewhere else to prevent event bubbling
if (
ms.X >= AbsoluteRectangle.Left
&& ms.X < AbsoluteRectangle.Right
&& ms.Y >= AbsoluteRectangle.Top
&& ms.Y < AbsoluteRectangle.Bottom)
{
if (OnClick != null)
{
var args = new MouseEventArgs()
{
Position = new Point(ms.X - AbsoluteRectangle.X, ms.Y - AbsoluteRectangle.Y),
Time = gameTime.TotalGameTime
};
OnClick(this, args);
}
}
}
lastMouseState = ms;*/
/*foreach (var child in Children)
child.Update(gameTime);*/
}
public virtual void Draw(SpriteBatch spriteBatch)
{
if (Visible)
{
if (Texture != null)
spriteBatch.Draw(Texture,
AbsoluteRectangle,
null,
Color,
0,
Vector2.Zero,
((Width < 0) ? SpriteEffects.FlipHorizontally : 0)
| ((Height < 0) ? SpriteEffects.FlipVertically : 0),
0);
/*foreach (var child in Children)
child.Draw(spriteBatch);*/
}
}
}
}
+54
View File
@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace DepthsBelow.GUI
{
/// <summary>
/// A basic text control.
/// </summary>
class Text : Frame
{
/// <summary>
/// Text to display.
/// </summary>
public String Value;
/// <summary>
/// Font to use while rendering.
/// </summary>
public SpriteFont Font;
public Text()
: base()
{
this.Color = Color.White;
}
public Text(Frame parent)
: base(parent)
{
this.Color = Color.White;
}
/// <summary>
/// Set the font to use while rendering.
/// </summary>
/// <param name="spriteFontName">Filename of the font.</param>
public void SetFont(string spriteFontName)
{
Font = GameServices.GetService<ContentManager>().Load<SpriteFont>(spriteFontName);
}
public override void Draw(SpriteBatch spriteBatch)
{
base.Draw(spriteBatch);
if (Visible && Font != null)
spriteBatch.DrawString(Font, Value, new Vector2(Rectangle.X + Parent.AbsoluteRectangle.X, Rectangle.Y + Parent.AbsoluteRectangle.Y), Color);
}
}
}
+143
View File
@@ -0,0 +1,143 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DepthsBelow.GUI;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace DepthsBelow
{
public static class GUIManager
{
/// <summary>
/// GUI mouse event arguments.
/// </summary>
public class MouseEventArgs : EventArgs
{
/// <summary>
/// The XNA mouse state.
/// </summary>
public MouseState MouseState;
public ButtonState LeftButton;
public ButtonState MiddleButton;
public ButtonState RightButton;
public int ScrollWheelValue;
/// <summary>
/// The time of the click, since the start of the program.
/// </summary>
public TimeSpan Time;
}
public static List<Frame> Frames = new List<Frame>();
private static int uidIndex = 0;
public static int Add(Frame frame)
{
Frames.Add(frame);
return CreateUID();
}
public static void Remove(Frame frame)
{
Frames.Remove(frame);
}
public static int CreateUID()
{
return uidIndex++;
}
/// <summary>
/// Calculates which frames are intersecting a point.
/// </summary>
/// <param name="point">A point on the screen.</param>
/// <returns>Returns a list of frames intersecting the point.</returns>
public static List<Frame> FramesIntersectingPoint(Point point)
{
var rect = new Rectangle(point.X, point.Y, 1, 1);
return Frames.Where(frame => rect.Intersects(frame.AbsoluteRectangle)).ToList();
}
public static bool RaiseAt(string eventName, EventArgs eventArgs, Point position)
{
// Create a list of all frames which intersects with the click position
var intersections = FramesIntersectingPoint(position);
// Filter it by event
intersections = intersections.Where(frame => frame.GetSubscriberCount(eventName) > 0).ToList();
// Get the topmost frame of that list
var topFrame = GetTopFrame(intersections);
if (topFrame != null)
return topFrame.Raise(eventName, eventArgs);
else
return false;
}
/// <summary>
/// Gets the top frame in the frame stack.
/// </summary>
/// <param name="frames">A list of frames to check.</param>
/// <returns>Returns the topmost frame.</returns>
private static Frame GetTopFrame(List<Frame> frames)
{
if (frames.Count == 0)
return null;
if (frames.Count == 1)
return frames.First();
return frames.OrderByDescending(f => f, new FrameSort()).First();
}
public static void Update(GameTime gameTime)
{
foreach (var frame in Frames)
frame.Update(gameTime);
}
public static void Draw(SpriteBatch spriteBatch)
{
foreach (var frame in Frames.OrderBy(f => f, new FrameSort()))
{
frame.Draw(spriteBatch);
}
}
/// <summary>
/// Sort frames based on layer, using UID as tie breaker.
/// </summary>
private class FrameSort : IComparer<Frame>
{
public int Compare(Frame a, Frame b)
{
var aLayerSum = a.LayerSum;
var bLayerSum = b.LayerSum;
// Compare the layer sum
if (aLayerSum > bLayerSum)
return 1;
if (aLayerSum < bLayerSum)
return -1;
// If the result is indecisive, pick the frame with the biggest UID
if (aLayerSum == bLayerSum)
{
if (a.UID > b.UID)
return 1;
if (a.UID < b.UID)
return -1;
}
return 0;
}
}
}
}
Regular → Executable
View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

+35
View File
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
namespace DepthsBelow
{
/*
* http://roy-t.nl/index.php/2010/08/25/xna-accessing-contentmanager-and-graphicsdevice-anywhere-anytime-the-gameservicecontainer/
*/
public static class GameServices
{
private static GameServiceContainer container;
public static GameServiceContainer Instance
{
get { return container ?? (container = new GameServiceContainer()); }
}
public static T GetService<T>()
{
return (T)Instance.GetService(typeof(T));
}
public static void AddService<T>(T service)
{
Instance.AddService(typeof(T), service);
}
public static void RemoveService<T>()
{
Instance.RemoveService(typeof(T));
}
}
}
View File

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Regular → Executable
+16
View File
@@ -3,15 +3,31 @@ using Microsoft.Xna.Framework;
namespace DepthsBelow
{
/// <summary>
/// Global grid utility functions.
/// </summary>
public static class Grid
{
/// <summary>
/// The size of a tile in pixels.
/// </summary>
public const int TileSize = 32;
/// <summary>
/// Converts a grid position into a world position.
/// </summary>
/// <param name="gridPos">The grid position to convert.</param>
/// <returns>Returns a Vector2 world position.</returns>
public static Vector2 GridToWorld(Point gridPos)
{
return new Vector2(gridPos.X * TileSize, gridPos.Y * TileSize);
}
/// <summary>
/// Converts a world position into a grid position.
/// </summary>
/// <param name="screenPos">The world position to convert.</param>
/// <returns>Returns a Point grid position.</returns>
public static Point WorldToGrid(Vector2 screenPos)
{
return new Point(
+664
View File
@@ -0,0 +1,664 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DepthsBelow.GUI;
using Microsoft.Xna.Framework;
using System.Diagnostics;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;
namespace DepthsBelow
{
public class Interface
{
Core core;
/// <summary>
/// The master frame covering the whole game screen. Parent of all frames.
/// This frame handles all mouse interaction with the game world
/// </summary>
public Frame UIParent;
public List<Frame> PanicFrames = new List<Frame>();
public List<Frame> UnitFrames = new List<Frame>();
public Dictionary<Soldier, Frame> SoldierToFrame = new Dictionary<Soldier, Frame>();
Random random = new Random();
private bool checkingDirection;
private Vector2 directionStart;
GUI.Text hitChance;
public Interface(Core core)
{
this.core = core;
UIParent = new Frame();
UIParent.Width = GameServices.GetService<GraphicsDevice>().Viewport.Width;
UIParent.Height = GameServices.GetService<GraphicsDevice>().Viewport.Height;
// Selection rectangle
var selectionFrame = new Frame(UIParent);
selectionFrame.Texture = Utility.GetSolidTexture();
selectionFrame.Color = Color.Red * 0.5f;
selectionFrame.Visible = false;
UIParent["selectionFrame"] = selectionFrame;
// OnPress
UIParent.OnPress += delegate(Frame frame, GUIManager.MouseEventArgs args)
{
//KeyboardState ks = Keyboard.GetState();
MouseState ms = args.MouseState;
var mousePos = new Point(ms.X, ms.Y);
var mouseRectangle = new Rectangle(mousePos.X, mousePos.Y, 1, 1);
var mouseWorldPos = core.Camera.ScreenToWorld(new Vector2(mousePos.X, mousePos.Y));
var mouseWorldRectangle = new Rectangle((int)mouseWorldPos.X, (int)mouseWorldPos.Y, 1, 1);
// Show the selection frame
if (args.LeftButton == ButtonState.Pressed)
{
var selectFrame = (GUI.Frame)frame["selectionFrame"];
if (!selectFrame.Visible)
{
selectFrame.X = mousePos.X;
selectFrame.Y = mousePos.Y;
selectFrame.Visible = true;
}
}
if (args.RightButton == ButtonState.Pressed)
{
// Unit rotation
foreach (var unit in core.Squad)
{
if (unit.Selected && mouseWorldRectangle.Intersects(unit.GetComponent<Component.Collision>().Rectangle))
{
checkingDirection = true;
directionStart = unit.Transform.World + unit.Transform.World.Origin;
}
}
}
};
// OnRelease
UIParent.OnRelease += delegate(Frame frame, GUIManager.MouseEventArgs args)
{
KeyboardState ks = Keyboard.GetState();
MouseState ms = args.MouseState;
var mousePos = new Point(ms.X, ms.Y);
var mouseRectangle = new Rectangle(mousePos.X, mousePos.Y, 1, 1);
var mouseWorldPos = core.Camera.ScreenToWorld(new Vector2(mousePos.X, mousePos.Y));
var mouseGridPos= Grid.WorldToGrid(mouseWorldPos);
var mouseWorldRectangle = new Rectangle((int)mouseWorldPos.X, (int)mouseWorldPos.Y, 1, 1);
if (args.LeftButton == ButtonState.Pressed)
{
// Deselect all units
if (!ks.IsKeyDown(Keys.LeftControl))
{
foreach (var unit in core.Squad)
unit.Selected = false;
foreach (var unitFrame in UnitFrames)
unitFrame.Color = Color.Black;
}
// Select all soldier units inside the selection rectangle
var selectFrame = (GUI.Frame)frame["selectionFrame"];
if (selectFrame.Visible)
{
Console.WriteLine("Before: " + selectFrame.AbsoluteRectangle.X + ", " + selectFrame.AbsoluteRectangle.Y + ", " + selectFrame.AbsoluteRectangle.Width + ", " + selectFrame.AbsoluteRectangle.Height);
var intersectionRectangle = core.Camera.ScreenToWorld(selectFrame.AbsoluteRectangle);
Console.WriteLine("After: " + intersectionRectangle.X + ", " + intersectionRectangle.Y + ", " + intersectionRectangle.Width + ", " + intersectionRectangle.Height);
// Select all units in the rectangle
foreach (var soldier in core.Squad)
{
if (intersectionRectangle.Intersects(soldier.GetComponent<Component.Collision>().Rectangle))
{
soldier.Selected = true;
foreach (var unitFrame in UnitFrames)
{
if (unitFrame["soldier"] == soldier)
unitFrame.Color = Color.Blue;
}
}
}
selectFrame.Visible = false;
}
}
// Send orders with right click
if (args.RightButton == ButtonState.Pressed)
{
if (checkingDirection)
{
checkingDirection = false;
}
else
{
Debug.WriteLine("Right button pressed on UIParent");
Point mainpath = Point.Zero;
Stack<Soldier> soldierStack = new Stack<Soldier>();
//core.Squad.Where(a=>a.Selected).ToList().ForEach(a => soldierStack.Push(a));
/*foreach (var soldier in core.Squad)
{
if (soldier.Selected)
{
soldierStack.Push(soldier);
}
}*/
// Don't move into other soldiers
bool blocked = false;
foreach (var soldier in core.Squad)
if (soldier.Position == mouseGridPos)
blocked = true;
if (!blocked)
{
byte[,] collisionMap = Core.Map.GetCollisionMap();
// Try pathfinding
foreach (var unit in core.Squad)
{
if (unit.Selected)
{
if (mainpath == Point.Zero)
{
mainpath = unit.Position;
}
Vector2 fromMain = new Vector2((mainpath.X - unit.Position.X)*Grid.TileSize,
(mainpath.Y - unit.Position.Y)*Grid.TileSize);
var goal = Grid.WorldToGrid(mouseWorldPos - fromMain);
Console.WriteLine("First " + unit.AP);
unit.GetComponent<Component.PathFinder>().Goal = goal;
var length = unit.GetComponent<Component.PathFinder>().Length - 1;
if (unit.AP >= length)
{
if (unit.GetComponent<Component.PathFinder>().IsMoving == false)
{
// If a path was not found, add the unit to the stack
soldierStack.Push(unit);
}
else
{
unit.AP -= length;
Console.WriteLine("then " + unit.AP);
collisionMap[goal.X, goal.Y] = 0;
}
}
else
{
unit.GetComponent<Component.PathFinder>().Stop();
}
}
}
// Loop in a spiral and assign the soldiers in the stack their own unblocked positions
int X = 10;
int Y = 10;
int x, y, dx, dy;
x = y = dx = 0;
dy = -1;
int t = (int) MathHelper.Max(X, Y);
int maxI = t*t;
for (int i = 0; i < maxI; i++)
{
if ((-X/2 < x && x <= X/2) && (-Y/2 < y && y <= Y/2))
{
Point point = new Point(x + mouseGridPos.X, y + mouseGridPos.Y);
if (collisionMap[point.X, point.Y] == 1)
{
if (soldierStack.Count == 0)
{
break;
}
var soldier = soldierStack.Pop();
if (soldier == null)
{
break;
}
else
{
Console.WriteLine("before " + soldier.AP);
soldier.GetComponent<Component.PathFinder>().Goal = point;
var length = soldier.GetComponent<Component.PathFinder>().Length - 1;
if (soldier.GetComponent<Component.PathFinder>().IsMoving == true)
{
if (soldier.AP >= length)
{
soldier.AP -= length;
Console.WriteLine("then " + soldier.AP);
}
else
{
soldier.GetComponent<Component.PathFinder>().Stop();
}
}
}
}
}
if ((x == y) || ((x < 0) && (x == -y)) || ((x > 0) && (x == 1 - y)))
{
t = dx;
dx = -dy;
dy = t;
}
x += dx;
y += dy;
}
}
}
}
};
hitChance = new Text(UIParent);
hitChance.SetFont("Arial");
hitChance.Value = "";
var button = new GUI.Button(UIParent);
button.SetTexture("images/Enter");
button.X = 200;
button.Y = 100;
button.Width = 55;
button.Height = 40;
// Test GUI frames
/*var frame = new GUI.Frame()
{
Y = 100
};
var button = new GUI.Button(frame)
{
Width = 48,
Height = 23,
Texture = core.Content.Load<Texture2D>("images/Enter"),
OnClick = delegate(Point clickPos)
{
Debug.WriteLine("That ugly button was clicked at (" + clickPos.X + "," + clickPos.Y + ")");
}
};
var text = new GUI.Text(frame);
text.SetFont("Arial");
text.Value = "Hello world!";*/
// Create some unit frames
/*var panicFrame = CreatePanicFrame();
var unit1 = CreateUnitFrame("Flight captain Rainbow");
unit1.X = panicFrame.X;
unit1.Y = panicFrame.Y + panicFrame.Height;
unit1.OnClick += delegate(Frame frame, Frame.MouseEventArgs args)
{
frame.Color = Color.Red;
};
var unit2 = CreateUnitFrame("Mr. Sparkle");
unit2.X = unit1.X;
unit2.Y = unit1.Y + unit1.Height;
unit2.OnClick += delegate(Frame frame, Frame.MouseEventArgs args)
{
frame.Color = Color.Red;
};*/
/*var frame1 = new GUI.Frame();
frame1.Layer = 0;
frame1.SetTexture("images/Enter");
frame1.Color = Color.Red;
frame1.Width = 100;
frame1.Height = 100;
frame1.OnClick += delegate(Frame frame, Frame.MouseEventArgs args)
{
if (frame.Color == Color.Red)
frame.Color = Color.Green;
else
frame.Color = Color.Red;
};
var frame1_child = new GUI.Frame(frame1);
frame1_child.SetTexture("images/Enter");
frame1_child.Color = Color.Purple;
frame1_child.Width = 60;
frame1_child.Height = 60;
frame1_child.X = 20;
frame1_child.Y = 20;
var frame2 = new GUI.Frame();
frame2.Layer = 0;
frame2.SetTexture("images/Enter");
frame2.Color = Color.Blue;
frame2.Width = 100;
frame2.Height = 100;
frame2.X = 50;
frame2.Y = 50;
frame2.OnClick += delegate(Frame frame, Frame.MouseEventArgs args)
{
if (frame.Color == Color.Blue)
frame.Color = Color.Yellow;
else
frame.Color = Color.Blue;
};*/
}
private GUI.Frame CreatePanicFrame()
{
var frame = new GUI.Frame(UIParent);
frame.SetTexture("images/GUI/unit_background");
frame.Color = Color.Black;
frame.Width = 164;
frame.Height = 19;
frame.OnClick += delegate(Frame frame1, GUIManager.MouseEventArgs args)
{
DynamicGroupManager.Group group = (DynamicGroupManager.Group)frame1["group"];
if (group != null)
group.Panic += 5;
};
var panicBarBg = new GUI.Frame(frame);
panicBarBg.SetTexture("images/GUI/health_background");
panicBarBg.Width = 136;
panicBarBg.Height = 13;
panicBarBg.X = 3;
panicBarBg.Y = 3;
frame["panicBarBg"] = panicBarBg;
var panicBar = new GUI.Frame(panicBarBg);
panicBar.SetTexture("images/GUI/bar_solid");
panicBar.Color = new Color(87, 55, 253);
panicBar.Width = (int)(panicBarBg.Width * 0.5);
panicBar.Height = 11;
panicBar.X = 1;
panicBar.Y = 1;
frame["panicBar"] = panicBar;
var text = new GUI.Text(frame);
text.SetFont("fonts/UnitName");
text.Value = "0%";
text.X = 4;
text.Y = 1;
frame["text"] = text;
return frame;
}
private GUI.Frame CreateUnitFrame(Soldier soldier)
{
var frame = new GUI.Frame(UIParent);
frame.SetTexture("images/GUI/unit_background");
frame.Color = Color.Black;
frame.Width = 164;
frame.Height = 42;
var nameText = new GUI.Text(frame);
nameText.SetFont("fonts/UnitName");
nameText.Value = soldier.Name + " "/* + soldier.GetHashCode()*/;
nameText.X = 4;
nameText.Y = 1;
frame["nameText"] = nameText;
var healthBarBg = new GUI.Frame(frame);
healthBarBg.SetTexture("images/GUI/health_background");
healthBarBg.Width = 136;
healthBarBg.Height = 13;
healthBarBg.X = 3;
healthBarBg.Y = 19;
frame["healthBarBg"] = healthBarBg;
var healthBar = new GUI.Frame(healthBarBg);
healthBar.SetTexture("images/GUI/bar_solid");
healthBar.Color = Color.Red;
healthBar.Width = (int)((healthBarBg.Width - 2) * (soldier.GetComponent<Component.Stat>().HP / soldier.GetComponent<Component.Stat>().MaxHP));
healthBar.Height = 11;
healthBar.X = 1;
healthBar.Y = 1;
frame["healthBar"] = healthBar;
var actionBarBg = new GUI.Frame(frame);
actionBarBg.SetTexture("images/GUI/health_background");
actionBarBg.Width = 136;
actionBarBg.Height = 8;
actionBarBg.X = 3;
actionBarBg.Y = 31;
frame["actionBarBg"] = actionBarBg;
var actionBar = new GUI.Frame(actionBarBg);
actionBar.SetTexture("images/GUI/bar_solid");
actionBar.Color = Color.Orange;
actionBar.Width = (int)((healthBarBg.Width - 2) * (soldier.GetComponent<Component.Stat>().HP / soldier.GetComponent<Component.Stat>().MaxHP));
actionBar.Height = 6;
actionBar.X = 1;
actionBar.Y = 1;
frame["actionBar"] = actionBar;
for (int i = 1; i < 10; i++)
{
var line = new GUI.Frame(actionBar);
line.Texture = Utility.GetSolidTexture();
line.Color = Color.Black;
line.Height = 6;
line.Width = 1;
line.X = (int)(i * ((float)actionBarBg.Width/10f)) - 1;
}
return frame;
}
public void CreateUnitFrames(List<Soldier> squad)
{
// TODO: ForEach squad in Squads...
/*GUI.Frame lastFrame = null;
foreach (Soldier soldier in squad)
{
// TODO: Remove this test ;)
soldier.GetComponent<Component.Stat>().HP = random.Next(0, (int) soldier.GetComponent<Component.Stat>().MaxHP - 1);
var uFrame = CreateUnitFrame(soldier);
uFrame["soldier"] = soldier;
soldier["unitFrame"] = uFrame;
if (lastFrame != null)
{
uFrame.X = lastFrame.X;
uFrame.Y = lastFrame.Y + lastFrame.Height;
}
uFrame.OnClick += delegate(Frame f, GUIManager.MouseEventArgs e)
{
var s = (Soldier) f["soldier"];
KeyboardState ks = Keyboard.GetState();
if (!ks.IsKeyDown(Keys.LeftControl))
{
// Deselect all units
foreach (var unitFrame in UnitFrames)
{
((Soldier) unitFrame["soldier"]).Selected = false;
unitFrame.Color = Color.Black;
}
}
if (!s.Selected)
{
s.Selected = true;
uFrame.Color = Color.Blue;
}
};
UnitFrames.Add(uFrame);
lastFrame = uFrame;
}*/
foreach (var soldier in squad)
{
PanicFrames.Add(CreatePanicFrame());
// TODO: Remove this test ;)
//soldier.GetComponent<Component.Stat>().HP = random.Next(0, (int)soldier.GetComponent<Component.Stat>().MaxHP - 1);
var uFrame = CreateUnitFrame(soldier);
uFrame["soldier"] = soldier;
soldier["unitFrame"] = uFrame;
uFrame.OnPress += delegate(Frame frame, GUIManager.MouseEventArgs args) { };
uFrame.OnRelease += delegate(Frame f, GUIManager.MouseEventArgs e)
{
var s = (Soldier)f["soldier"];
KeyboardState ks = Keyboard.GetState();
if (!ks.IsKeyDown(Keys.LeftControl))
{
// Deselect all units
foreach (var unitFrame in UnitFrames)
{
((Soldier)unitFrame["soldier"]).Selected = false;
unitFrame.Color = Color.Black;
}
}
if (!s.Selected)
{
s.Selected = true;
uFrame.Color = Color.Blue;
}
};
UnitFrames.Add(uFrame);
}
}
public void UpdateUnitFrames()
{
core.GroupManager.UpdateGroups();
var groups = core.GroupManager.Groups;
foreach (var panicFrame in PanicFrames)
panicFrame.Visible = false;
foreach (var unitFrame in UnitFrames)
{
unitFrame.Visible = false;
}
GUI.Frame lastFrame = null;
for (int index = 0; index < groups.Count; index++)
{
var group = groups[index];
var pFrame = PanicFrames[index];
pFrame["group"] = group;
var pFrameBarBg = (GUI.Frame)pFrame["panicBarBg"];
var pFrameBar = (GUI.Frame)pFrame["panicBar"];
var pFrameText = (GUI.Text)pFrame["text"];
pFrameBar.Width = (int)(pFrameBarBg.Width * (group.Panic / group.MaxPanic));
pFrameText.Value = Math.Round(group.Panic).ToString() + "/" + group.MaxPanic.ToString() + " (" + Math.Round(group.Panic / group.MaxPanic * 100f).ToString() + "%)";
pFrame.Visible = true;
if (lastFrame != null)
{
pFrame.X = lastFrame.X;
pFrame.Y = lastFrame.Y + lastFrame.Height + 15;
}
lastFrame = pFrame;
foreach (Soldier soldier in @group.Entities)
{
var frame = (GUI.Frame) soldier["unitFrame"];
frame.X = lastFrame.X;
frame.Y = lastFrame.Y + lastFrame.Height;
frame.Visible = true;
// Update HP
var healthBarBg = (GUI.Frame)frame["healthBarBg"];
var healthBar = (GUI.Frame)frame["healthBar"];
healthBar.Width = (int)((healthBarBg.Width - 2) * (soldier.GetComponent<Component.Stat>().Life / soldier.GetComponent<Component.Stat>().MaxHP));
// Update Action Points
var actionBarBg = (GUI.Frame)frame["actionBarBg"];
var actionBar = (GUI.Frame)frame["actionBar"];
actionBar.Width = (int)(((float)actionBarBg.Width - 2f) * ((float)soldier.AP / (float)soldier.MaxActionPoints));
lastFrame = frame;
}
}
}
public void Update(GameTime gameTime)
{
MouseState ms = Mouse.GetState();
var mousePos = new Point(ms.X, ms.Y);
var mouseRectangle = new Rectangle(mousePos.X, mousePos.Y, 1, 1);
var mouseWorldPos = core.Camera.ScreenToWorld(new Vector2(mousePos.X, mousePos.Y));
var mouseWorldRectangle = new Rectangle((int)mouseWorldPos.X, (int)mouseWorldPos.Y, 1, 1);
// Update the selection rectangle
var selectionFrame = (GUI.Frame)UIParent["selectionFrame"];
if (selectionFrame.Visible)
{
selectionFrame.Width = (int)mousePos.X - selectionFrame.X;
selectionFrame.Height = (int)mousePos.Y - selectionFrame.Y;
}
// Update rotations
if (checkingDirection)
{
foreach (var unit in core.Squad)
if (unit.Selected)
{
float directionX = mouseWorldPos.X - unit.Transform.World.X;
float directionY = mouseWorldPos.Y - unit.Transform.World.Y;
//var mouseDirection = mouseWorldPos;
//mouseDirection.Normalize();
unit.GetComponent<Component.Transform>().World.Rotation =
(float)
Math.Atan2(mouseWorldPos.Y - unit.Transform.World.Y - unit.Transform.World.Origin.Y,
mouseWorldPos.X - unit.Transform.World.X - unit.Transform.World.Origin.X);
}
}
bool onSomething = false;
foreach (var unit in core.Squad)
{
if (unit.Selected == true && unit.Fired == false)
{
foreach (var enemy in core.Swarm)
{
if (core.MouseInput.gridRectangle.Intersects(enemy.GetComponent<Component.Collision>().Rectangle))
{
onSomething = true;
hitChance.Visible = true;
int chanceToHit = Utility.CalculateHitChance(unit.GetComponent<Component.Stat>(), unit.GetComponent<Component.Transform>().World.Position, enemy);
hitChance.Value = chanceToHit.ToString() + "%";
hitChance.X = ms.X - 15;
hitChance.Y = ms.Y - 15;
break;
}
}
if (onSomething == true)
{
break;
}
}
}
if (onSomething == false)
{
hitChance.Visible = false;
}
UpdateUnitFrames();
}
}
}
+350
View File
@@ -0,0 +1,350 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace DepthsBelow
{
public class KeyboardInput
{
Core core;
private KeyboardState lastKeyboardState;
int checkerSpeed = 2;
int bulletCost = 5;
int rocketCost = 10;
public KeyboardInput(Core core)
{
this.core = core;
}
/*public List<List<Soldier>> GetGroups(List<Soldier> soldiers)
{
var ungrouped = soldiers.ToList();
var groups = new List<List<Soldier>>();
for (int index = 0; index < soldiers.Count; index++)
{
var checkingSoldier = soldiers[index];
var group = new List<Soldier>();
for (int i = 0; i < soldiers.Count; i++)
{
var soldier = soldiers[i];
if (ungrouped.Contains(soldier))
{
float distance = Vector2.Distance(checkingSoldier.Transform.World + checkingSoldier.Transform.World.Origin,
soldier.Transform.World + soldier.Transform.World.Origin);
if (distance <= ((float) Grid.TileSize * 1f))
{
ungrouped.Remove(soldier);
group.Add(soldier);
}
}
}
if (group.Count > 0)
groups.Add(group);
}
return groups;
}*/
// Get a list of dynamic soldier groups
public List<List<Soldier>> GetGroups(List<Soldier> soldiers, float maxRange)
{
var alreadyGrouped = new List<Soldier>();
var groups = new List<List<Soldier>>();
for (int index = 0; index < soldiers.Count; index++)
{
var soldier = soldiers[index];
if (!alreadyGrouped.Contains(soldier))
{
var group = new List<Soldier>();
GetNearChain(ref group, soldiers, soldier, maxRange);
alreadyGrouped.AddRange(group);
if (group.Count > 0)
groups.Add(group);
}
}
return groups;
}
// Get all soldiers who are close to each other in a chain
public void GetNearChain(ref List<Soldier> group, List<Soldier> soldiers, Soldier soldier, float maxRange)
{
for (int index = 0; index < soldiers.Count; index++)
{
var nearSoldier = soldiers[index];
if (!group.Contains(nearSoldier))
{
float distance = Vector2.Distance(nearSoldier.Transform.World + nearSoldier.Transform.World.Origin,
soldier.Transform.World + soldier.Transform.World.Origin);
if (distance <= maxRange)
{
group.Add(nearSoldier);
GetNearChain(ref group, soldiers, nearSoldier, maxRange);
}
}
}
}
private DynamicGroupManager groupManager;
public void Update(GameTime gameTime)
{
KeyboardState ks = Keyboard.GetState();
// Brightness
if (ks.IsKeyUp(Keys.Up) && lastKeyboardState.IsKeyDown(Keys.Up))
core.Brightness = (int)MathHelper.Clamp(core.Brightness + 5, 0, 254);
if (ks.IsKeyUp(Keys.Down) && lastKeyboardState.IsKeyDown(Keys.Down))
core.Brightness = (int)MathHelper.Clamp(core.Brightness - 5, 0, 254);
// Debug test: grouping
if (ks.IsKeyUp(Keys.K) && lastKeyboardState.IsKeyDown(Keys.K))
{
if (groupManager == null)
groupManager = new DynamicGroupManager(core.Squad.Cast<Entity>().ToList(), Grid.TileSize * 1.5f);
groupManager.UpdateGroups();
//var groups = GetGroups(core.Squad, (float)Grid.TileSize * 1.5f);
var groups = groupManager.Groups;
foreach (var group in groups)
{
Debug.WriteLine("Group #" + groups.IndexOf(group) + " Panic: " + group.Panic);
foreach (var entity in group.Entities)
{
var soldier = (Soldier)entity;
Debug.WriteLine(soldier.Name + " " + soldier.GetHashCode());
}
}
}
// Next turn
if (ks.IsKeyDown(Keys.Enter) && lastKeyboardState.IsKeyUp(Keys.Enter))
{
if (core.TurnManager.CurrentTurn == core.TurnManager["Player"])
{
foreach (var unit in core.Squad)
{
unit.AP = unit.MaxActionPoints;
unit.Fired = false;
}
core.TurnManager.EndTurn();
}
if (core.TurnManager.CurrentTurn == core.TurnManager["Computer"])
{
foreach (var enemy in core.Swarm)
{
enemy.step = 0;
enemy.AttackedThisTurn = false;
Point target = Point.Zero;
float distance = 7000;
foreach (var unit in core.Squad)
{
Vector2 soldier = new Vector2(unit.Transform.Grid.X, unit.Transform.Grid.Y);
Vector2 monster = new Vector2(enemy.Transform.Grid.X, enemy.Transform.Grid.Y);
float newDistance = Vector2.Distance(soldier, monster);
if (newDistance < distance)
{
target = unit.Transform.Grid;
distance = newDistance;
}
}
enemy.GetComponent<Component.PathFinder>().Goal = target;
distance = 7000;
}
core.TestMonster.step = 0;
Point testTarget = Point.Zero;
float testDistance = 7000;
foreach (var unit in core.Squad)
{
Vector2 soldier = new Vector2(unit.Transform.Grid.X, unit.Transform.Grid.Y);
Vector2 monster = new Vector2(core.TestMonster.Transform.Grid.X, core.TestMonster.Transform.Grid.Y);
float newDistance = Vector2.Distance(soldier, monster);
if (newDistance < testDistance)
{
testTarget = unit.Transform.Grid;
testDistance = newDistance;
}
}
core.TestMonster.GetComponent<Component.PathFinder>().Goal = testTarget;
testDistance = 7000;
core.TurnManager.EndTurn();
}
}
if (ks.IsKeyDown(Keys.A))
{
/*foreach (var unit in core.Swarm)
{
unit.X = 200;
unit.Y = 200;
}*/
core.TestMonster.X = 12;
core.TestMonster.Y = 4;
}
if (ks.IsKeyUp(Keys.O) && lastKeyboardState.IsKeyDown(Keys.O))
{
try
{
EntityManager.GetEntities<Door>()[0].Toggle();
}
catch
{
}
}
if (ks.IsKeyUp(Keys.P) && lastKeyboardState.IsKeyDown(Keys.P))
{
try
{
var pos = core.GroupManager.Groups[1].Entities[0].Transform.World.Position;
var enemy = new SmallEnemy(ref core.Swarm);
enemy.Transform.World.Position = pos + new Vector2(0, Grid.TileSize*3);
core.Swarm.Add(enemy);
}
catch
{
}
}
if (ks.IsKeyDown(Keys.S) || ks.IsKeyDown(Keys.R))
{
foreach (var soldier in core.Squad)
{
if (soldier.Selected == true && soldier.Fired == false)
{
bool enoughActionPoints = true;
int cost = 0;
string type = "";
if (ks.IsKeyDown(Keys.S))
{
cost = bulletCost;
type = "bullet";
}
else if (ks.IsKeyDown(Keys.R))
{
cost = rocketCost;
type = "Rocket";
}
if (soldier.AP >= cost)
{
core.Volley.Add(new Shot(soldier.GetComponent<Component.Stat>(), type));
soldier.AP -= cost;
soldier.Fired = true;
}
else
{
enoughActionPoints = false;
}
if (enoughActionPoints == true)
{
foreach (var shot in core.Volley)
{
if (shot.select == false)
{
shot.select = true;
shot.X = soldier.X;
shot.Y = soldier.Y;
//shot.Transform.World.Position += soldier.Transform.World.Origin;
//shot.Transform.World.X += Grid.TileSize / 2;
//shot.Transform.World.Y += Grid.TileSize / 2;
}
if (shot.direction == Vector2.Zero)
{
double directionX = Math.Cos(soldier.Transform.World.Rotation);
double directionY = Math.Sin(soldier.Transform.World.Rotation);
shot.direction = new Vector2((float)directionX, (float)directionY);
shot.Transform.World.Rotation = soldier.Transform.World.Rotation;
Vector2 yo = soldier.Transform.World.Position;
shot.Stat.Remember = yo;
}
}
}
}
}
}
if (ks.IsKeyDown(Keys.C))
{
foreach (var soldier in core.Squad)
{
if (soldier.Selected == true && soldier.Fired == false)
{
Point checker = Point.Zero;
double directionX = Math.Cos(soldier.GetComponent<Component.Transform>().World.Rotation);
double directionY = Math.Sin(soldier.GetComponent<Component.Transform>().World.Rotation);
Vector2 direction = new Vector2((int)directionX, (int)directionY);
int range = 120;
int current = 0;
bool hit = false;
checker = new Point((int)soldier.Transform.World.Origin.X, (int)soldier.Transform.World.Origin.Y);
do
{
checker.X += (int)direction.X * checkerSpeed;
checker.Y += (int)direction.Y * checkerSpeed;
foreach (var creature in core.Swarm)
{
if (creature.GetComponent<Component.Collision>().Rectangle.Contains(checker))
{
hit = true;
}
}
if (core.TestMonster.GetComponent<Component.Collision>().Rectangle.Contains(checker))
{
}
current++;
} while (hit == false && current < range);
current = 0;
if (soldier.Selected == true && soldier.Fired == false && hit == true)
{
core.Volley.Add(new Shot(soldier.GetComponent<Component.Stat>(), "Bullet"));
soldier.Fired = true;
foreach (var shot in core.Volley)
{
if (shot.select == false)
{
shot.select = true;
shot.X = soldier.X;
shot.Y = soldier.Y;
//shot.Transform.World.X += Grid.TileSize / 2;
//shot.Transform.World.Y += Grid.TileSize / 2;
}
if (shot.direction == Vector2.Zero)
{
shot.direction = new Vector2((float)directionX, (float)directionY);
shot.Transform.World.Rotation = soldier.Transform.World.Rotation;
}
}
}
hit = false;
}
}
}
lastKeyboardState = ks;
}
}
}
+178
View File
@@ -0,0 +1,178 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DepthsBelow.GUI;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;
namespace DepthsBelow
{
// TODO: The frames created here must be disposed correctly when the Lua context is disposed
static class LuaGUI
{
public static GUI.Frame CreateFrame()
{
return new Frame();
}
public static GUI.Frame CreateFrame(GUI.Frame parent)
{
return new GUI.Frame(parent);
}
public static GUI.Button CreateButton()
{
return new Button();
}
public static GUI.Button CreateButton(GUI.Frame parent)
{
return new GUI.Button(parent);
}
public static GUI.Text CreateText()
{
return new Text();
}
public static GUI.Text CreateText(GUI.Frame parent)
{
return new GUI.Text(parent);
}
}
static class LuaMouse
{
public static Point GetPos()
{
var ms = Mouse.GetState();
return new Point(ms.X, ms.Y);
}
}
public class Lua
{
private LuaInterface.Lua lua;
private List<string> filesToRun;
public Lua()
{
filesToRun = new List<string>();
Initialize();
/*lua.DoString(@"
local frame = CreateFrame('Frame');
frame.X = 100;
local button = CreateFrame('Button', frame);
button:SetTexture('images/Enter');
button.Width = 100;
button.Height = 50;
button.OnClick = function(clickPos)
Console.WriteLine(clickPos.X .. ' ' .. clickPos.Y);
end
");*/
}
private void Initialize()
{
if (lua == null)
{
lua = new LuaInterface.Lua();
ExposeLibraries();
}
}
public void ExposeLibraries()
{
lua.NewTable("Console");
lua.RegisterFunction("Console.Write", null, typeof(System.Console).GetMethod("Write", new Type[] { typeof(string) }));
lua.RegisterFunction("Console.WriteLine", null, typeof(System.Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
lua.NewTable("Mouse");
lua.RegisterFunction("Mouse.GetPos", null, typeof(LuaMouse).GetMethod("GetPos"));
// Register GUI creation functions
lua.RegisterFunction("_CreateFrame", null, typeof(LuaGUI).GetMethod("CreateFrame", new Type[] { }));
lua.RegisterFunction("_CreateFrameAsChild", null, typeof(LuaGUI).GetMethod("CreateFrame", new Type[] { typeof(GUI.Frame) }));
lua.RegisterFunction("_CreateButton", null, typeof(LuaGUI).GetMethod("CreateButton", new Type[] { }));
lua.RegisterFunction("_CreateButtonAsChild", null, typeof(LuaGUI).GetMethod("CreateButton", new Type[] { typeof(GUI.Frame) }));
lua.RegisterFunction("_CreateText", null, typeof(LuaGUI).GetMethod("CreateText", new Type[] { }));
lua.RegisterFunction("_CreateTextAsChild", null, typeof(LuaGUI).GetMethod("CreateText", new Type[] { typeof(GUI.Frame) }));
lua.NewTable("GUI");
/*
* Because Lua can't dynamically call overloads of registered functions, a generic Lua function needs to do the decision making.
* This way we can also dynamically create different frame classes with the same function.
*/
lua.DoString(@"
CreateFrame = function(frameType, parent)
frameType = string.lower(frameType):gsub('^%l', string.upper)
if (parent == nil) then
return _G['_Create' .. frameType]()
else
return _G['_Create' .. frameType .. 'AsChild'](parent)
end
end
");
}
public LuaInterface.LuaFunction Expose(string path, object target, System.Reflection.MethodBase function)
{
return lua.RegisterFunction(path, target, function);
}
public void Expose(string path, object obj)
{
lua[path] = obj;
}
public void ResetContext()
{
if (lua != null)
lua.Dispose();
Initialize();
}
public void Reload()
{
ResetContext();
LoadScripts();
}
public void LoadScripts()
{
// Load scripts from script folder
// HACK: This needs to load files on the fly instead of loading precompiled files by the content manager.
// http://xbox.create.msdn.com/en-US/education/catalog/sample/winforms_series_2 maybe?
/*var scripts = GameServices.GetService<ContentManager>().LoadContent<string>("scripts");
foreach (var script in scripts)
{
try
{
lua.DoString(script.Value);
}
catch (LuaInterface.LuaException e)
{
Console.WriteLine("Lua error: " + e.Message);
}
}*/
foreach (var fileName in filesToRun)
{
lua.DoFile(GameServices.GetService<ContentManager>().RootDirectory + "/" + fileName);
}
}
public void AddFile(string fileName)
{
filesToRun.Add(fileName);
}
public T GetObject<T>(string obj)
{
return (T)lua[obj];
}
}
}
+197 -198
View File
@@ -1,198 +1,197 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace DepthsBelow
{
public class MapTile
{
public int LocalId;
public Texture2D Texture;
public Rectangle SourceRectangle;
public SpriteEffects SpriteEffects;
}
public enum MapObjectType : byte
{
Plain,
Tile,
Polygon,
Polyline
}
public class MapObject
{
//public MapObjectType ObjectType;
public string Name;
public string Type;
public Rectangle Bounds;
public List<Vector2> Points;
}
public class MapLayer
{
public int Width;
public int Height;
public string Name;
}
public class MapTileLayer : MapLayer
{
public MapTile[] Tiles;
}
public class MapObjectLayer : MapLayer
{
public MapObject[] Objects;
}
public class Map
{
public int TileWidth;
public int TileHeight;
public List<MapLayer> Layers = new List<MapLayer>();
public Map()
{
}
public void Initialize(Core core, Krypton.KryptonEngine kryptonEngine)
{
foreach (var layer in Layers)
{
var objectLayer = layer as MapObjectLayer;
if (objectLayer != null)
{
// Parse lighting engine hulls
/*if (objectLayer.Name == "Opaque")
{
foreach (var hullObject in objectLayer.Objects)
{
Console.WriteLine("Width: " + hullObject.Bounds.Width);
Console.WriteLine("Height: " + hullObject.Bounds.Height);
Console.WriteLine(hullObject.Bounds.X + ", " + hullObject.Bounds.Y);
Krypton.ShadowHull hull = Krypton.ShadowHull.CreateRectangle(new Vector2(hullObject.Bounds.Width, hullObject.Bounds.Height));
hull.Position.X = hullObject.Bounds.X + hullObject.Bounds.Width / 2;
hull.Position.Y = hullObject.Bounds.Y + hullObject.Bounds.Height / 2;
kryptonEngine.Hulls.Add(hull);
}
}*/
// Parse general objects
foreach (var mapObject in objectLayer.Objects)
{
if (mapObject.Type == "SquadStart")
{
// HACK: Move the entity creation to an entity factory
var soldier = new Soldier(core, ref core.Squad);
core.KryptonEngine.Lights.Add((Krypton.Lights.Light2D)soldier.GetComponent<Component.Flashlight>());
// HACK: For some reason, the tile object coordinates are offset by one tile on the Y-axis in the Tiled map file (https://github.com/bjorn/tiled/issues/91)
var mapObjectPos = new Vector2(mapObject.Bounds.X, mapObject.Bounds.Y - Grid.TileSize);
var mapObjectGridPos = Grid.WorldToGrid(mapObjectPos);
soldier.X = mapObjectGridPos.X;
soldier.Y = mapObjectGridPos.Y;
core.Squad.Add(soldier);
}
}
}
var tileLayer = layer as MapTileLayer;
if (tileLayer != null)
{
// Prepare collision hulls for lighting engine
if (tileLayer.Name == "Collision")
{
for (int y = 0; y < tileLayer.Height; y++)
{
for (int x = 0; x < tileLayer.Width; x++)
{
MapTile mapTile = tileLayer.Tiles[y * layer.Width + x];
if (mapTile != null && mapTile.LocalId != 0)
{
var hull = Krypton.ShadowHull.CreateRectangle(new Vector2(TileWidth, TileHeight));
hull.Position.X = x * TileWidth + TileWidth/2;
hull.Position.Y = y * TileHeight + TileWidth / 2;
kryptonEngine.Hulls.Add(hull);
}
}
}
}
}
}
}
public void Draw(SpriteBatch spriteBatch)
{
foreach (var layer in Layers)
{
var tileLayer = layer as MapTileLayer;
if (tileLayer == null)
continue;
// Don't draw the collision layer
if (tileLayer.Name == "Collision")
continue;
for (int y = 0; y < tileLayer.Height; y++)
{
for (int x = 0; x < tileLayer.Width; x++)
{
MapTile mapTile = tileLayer.Tiles[y * layer.Width + x];
if (mapTile != null)
{
spriteBatch.Draw(
mapTile.Texture,
new Rectangle(x * TileWidth, y * TileHeight, TileWidth, TileHeight),
mapTile.SourceRectangle,
Color.White,
0,
Vector2.Zero,
mapTile.SpriteEffects,
0);
}
}
}
}
}
public byte[,] GetCollisionMap()
{
byte[,] collisionMap = null;
foreach (var layer in Layers)
{
var tileLayer = layer as MapTileLayer;
if (tileLayer != null && tileLayer.Name == "Collision")
{
collisionMap = new byte[1024,1024];
for (int y = 0; y < tileLayer.Height; y++)
{
for (int x = 0; x < tileLayer.Width; x++)
{
MapTile tile = tileLayer.Tiles[y * layer.Width + x];
if (tile == null || tile.LocalId == 0)
collisionMap[x, y] = 1;
else
collisionMap[x, y] = 0;
}
}
break;
}
}
if (collisionMap == null)
Debug.WriteLine("Map lacks a Collision layer! Pathfinding won't work.");
return collisionMap;
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace DepthsBelow
{
public class MapTile
{
public int LocalId;
public Texture2D Texture;
public Rectangle SourceRectangle;
public SpriteEffects SpriteEffects;
}
public enum MapObjectType : byte
{
Plain,
Tile,
Polygon,
Polyline
}
public class MapObject
{
//public MapObjectType ObjectType;
public string Name;
public string Type;
public Rectangle Bounds;
public List<Vector2> Points;
}
public class MapLayer
{
public int Width;
public int Height;
public string Name;
}
public class MapTileLayer : MapLayer
{
public MapTile[] Tiles;
}
public class MapObjectLayer : MapLayer
{
public MapObject[] Objects;
}
public class Map
{
public int TileWidth;
public int TileHeight;
public List<MapLayer> Layers = new List<MapLayer>();
public Map()
{
}
public void ParseObjects(Core core)
{
foreach (var layer in Layers)
{
var objectLayer = layer as MapObjectLayer;
if (objectLayer == null)
continue;
foreach (var mapObject in objectLayer.Objects)
{
if (mapObject.Type == "SquadStart")
{
var soldier = new Soldier(ref core.Squad);
soldier.Name = "Derp";
// HACK: For some reason, the tile object coordinates are offset by one tile on the Y-axis in the Tiled map file (https://github.com/bjorn/tiled/issues/91)
var mapObjectPos = new Vector2(mapObject.Bounds.X, mapObject.Bounds.Y - Grid.TileSize);
var mapObjectGridPos = Grid.WorldToGrid(mapObjectPos);
soldier.X = mapObjectGridPos.X;
soldier.Y = mapObjectGridPos.Y;
core.Squad.Add(soldier);
}
if (mapObject.Type == "MonsterSpawn" || mapObject.Type == "EnemySpawn")
{
var enemy = new MonsterSpawn("Monster", 14, 0, ref core.Swarm);
var mapObjectPos = new Vector2(mapObject.Bounds.X, mapObject.Bounds.Y - Grid.TileSize);
var mapObjectGridPos = Grid.WorldToGrid(mapObjectPos);
enemy.X = mapObjectGridPos.X;
enemy.Y = mapObjectGridPos.Y;
}
if (mapObject.Type == "AmbushMonsterSpawn" || mapObject.Type == "AmbushEnemySpawn")
{
var enemy = new MonsterSpawn("Monster", 2, 0, ref core.Swarm);
var mapObjectPos = new Vector2(mapObject.Bounds.X, mapObject.Bounds.Y - Grid.TileSize);
var mapObjectGridPos = Grid.WorldToGrid(mapObjectPos);
enemy.X = mapObjectGridPos.X;
enemy.Y = mapObjectGridPos.Y;
}
if (mapObject.Type == "DelayedMonsterSpawn" || mapObject.Type == "DelayedEnemySpawn")
{
var enemy = new MonsterSpawn("Monster", 200, 4, ref core.Swarm);
var mapObjectPos = new Vector2(mapObject.Bounds.X, mapObject.Bounds.Y - Grid.TileSize);
var mapObjectGridPos = Grid.WorldToGrid(mapObjectPos);
enemy.X = mapObjectGridPos.X;
enemy.Y = mapObjectGridPos.Y;
}
if (mapObject.Type == "BossSpawn")
{
var enemy = new MonsterSpawn("BUB", 12, 0, ref core.Swarm);
var mapObjectPos = new Vector2(mapObject.Bounds.X, mapObject.Bounds.Y - Grid.TileSize);
var mapObjectGridPos = Grid.WorldToGrid(mapObjectPos);
enemy.X = mapObjectGridPos.X;
enemy.Y = mapObjectGridPos.Y;
}
if (mapObject.Type == "Door")
{
var door = new Door(true);
var mapObjectPos = new Vector2(mapObject.Bounds.X, mapObject.Bounds.Y);
var mapObjectGridPos = Grid.WorldToGrid(mapObjectPos);
door.X = mapObjectGridPos.X;
door.Y = mapObjectGridPos.Y;
}
}
}
}
public void Draw(SpriteBatch spriteBatch)
{
foreach (var layer in Layers)
{
var tileLayer = layer as MapTileLayer;
if (tileLayer == null)
continue;
// Don't draw the collision layer
if (tileLayer.Name == "Collision")
continue;
for (int y = 0; y < tileLayer.Height; y++)
{
for (int x = 0; x < tileLayer.Width; x++)
{
MapTile mapTile = tileLayer.Tiles[y * layer.Width + x];
if (mapTile != null)
{
spriteBatch.Draw(
mapTile.Texture,
new Rectangle(x * TileWidth, y * TileHeight, TileWidth, TileHeight),
mapTile.SourceRectangle,
Color.White,
0,
Vector2.Zero,
mapTile.SpriteEffects,
0);
}
}
}
}
}
public byte[,] GetCollisionMap()
{
byte[,] collisionMap = null;
foreach (var layer in Layers)
{
var tileLayer = layer as MapTileLayer;
if (tileLayer != null && tileLayer.Name == "Collision")
{
collisionMap = new byte[1024,1024];
for (int y = 0; y < tileLayer.Height; y++)
{
for (int x = 0; x < tileLayer.Width; x++)
{
MapTile tile = tileLayer.Tiles[y * layer.Width + x];
if (tile == null || tile.LocalId == 0)
collisionMap[x, y] = 1;
else
collisionMap[x, y] = 0;
}
}
break;
}
}
if (collisionMap == null)
Debug.WriteLine("Map lacks a Collision layer! Pathfinding won't work.");
return collisionMap;
}
}
}
+60
View File
@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
namespace DepthsBelow
{
public class MonsterSpawn : Entity
{
//EntityManager entityManager;
int wakingDistance = 12;
int sleepingDistance = 6;
int wakingTurn = 0;
string type;
List<SmallEnemy> swarm;
public MonsterSpawn(string _type, int _wakingDistance, int _wakingTurn, ref List<SmallEnemy> Swarm)
: base()
{
//this.entityManager = entityManager;
type = _type;
swarm = Swarm;
wakingDistance = _wakingDistance;
wakingTurn = _wakingTurn;
}
public override void Update(GameTime gameTime)
{
for (int index = 0; index < EntityManager.Entities.Count; index++)
{
var entity = EntityManager.Entities[index];
if (entity is Soldier)
{
Vector2 distance1 = new Vector2(this.GetComponent<Component.Transform>().Grid.Position.X,
this.GetComponent<Component.Transform>().Grid.Position.Y);
Vector2 distance2 = new Vector2(entity.GetComponent<Component.Transform>().Grid.Position.X,
entity.GetComponent<Component.Transform>().Grid.Position.Y);
if (Vector2.Distance(distance1, distance2) < wakingDistance && TurnManager.currentTurn >= wakingTurn/* && Vector2.Distance(distance1, distance2) > sleepingDistance*/)
{
var enemy = new SmallEnemy(ref swarm);
if (type == "BUB")
{
enemy.LoadBoss();
}
enemy.X = this.X;
enemy.Y = this.Y;
swarm.Add(enemy);
this.Remove();
break;
}
}
}
}
}
}
+322 -162
View File
@@ -1,173 +1,333 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace DepthsBelow
{
public class MouseInput
{
Core core;
MouseState lastMouseState;
Rectangle selectionRectangle;
Texture2D selectionTexture;
public Rectangle gridRectangle;
Texture2D gridTexture;
Vector2 directionStart;
Vector2 directionNow;
bool checkingDirection = false;
bool readjust = false;
private Point pressLocation;
public MouseInput(Core core)
{
this.core = core;
selectionRectangle = Rectangle.Empty;
gridRectangle = Rectangle.Empty;
}
public void LoadContent()
{
selectionTexture = new Texture2D(core.GraphicsDevice, 1, 1);
selectionTexture.SetData(new Color[] { Color.White });
//gridTexture = new Texture2D(core.GraphicsDevice, 1, 1);
//gridTexture.SetData(new Color[] { Color.White });
gridTexture = GameServices.GetService<ContentManager>().Load<Texture2D>("images/selection");
}
public void OnPress(MouseState ms, GameTime gameTime)
{
pressLocation = new Point(ms.X, ms.Y);
var mouseEvent = new GUIManager.MouseEventArgs()
{
MouseState = ms,
Time = gameTime.TotalGameTime
};
bool handledByUI = GUIManager.RaiseAt("OnPress", mouseEvent, pressLocation);
if (handledByUI)
return;
// If the mouse event is above a GUI frame that handles mouse events, do nothing
//if (GUIManager.FramesIntersectingPoint(mousePos).Any(frame => frame.MouseEnabled))
// return;
}
public void OnRelease(MouseState ms, GameTime gameTime)
{
var mouseEvent = new GUIManager.MouseEventArgs()
{
MouseState = ms,
Time = gameTime.TotalGameTime
};
bool handledByUI = GUIManager.RaiseAt("OnRelease", mouseEvent, pressLocation);
if (handledByUI)
return;
}
public void OnClick(MouseState ms, GameTime gameTime)
{
var mouseEvent = new GUIManager.MouseEventArgs()
{
MouseState = ms,
Time = gameTime.TotalGameTime
};
namespace DepthsBelow
{
public class MouseInput
{
Core core;
MouseState lastMouseState;
Rectangle selectionRectangle;
Texture2D selectionTexture;
Rectangle gridRectangle;
Texture2D gridTexture;
Vector2 directionStart;
Vector2 directionNow;
bool checkingDirection = false;
public MouseInput(Core core)
{
this.core = core;
selectionRectangle = Rectangle.Empty;
gridRectangle = Rectangle.Empty;
}
public void LoadContent()
{
selectionTexture = new Texture2D(Core.GraphicsDevice, 1, 1);
selectionTexture.SetData(new Color[] { Color.White });
gridTexture = new Texture2D(Core.GraphicsDevice, 1, 1);
gridTexture.SetData(new Color[] { Color.White });
}
public void Update(GameTime gameTime)
{
// Only capture input if the game window is in focus
if (!core.IsActive)
return;
MouseState ms = Mouse.GetState();
Vector2 mouseWorldPos = core.Camera.ScreenToWorld(new Vector2(ms.X, ms.Y));
KeyboardState ks = Keyboard.GetState();
// Selection rectangle
if (ms.LeftButton == ButtonState.Pressed)
//Console.WriteLine(Grid.GridToWorld(new Point()));
bool handledByUI = GUIManager.RaiseAt("OnClick", mouseEvent, new Point(ms.X, ms.Y));
if (handledByUI)
return;
}
public void Update(GameTime gameTime)
{
MouseState ms = Mouse.GetState();
Vector2 mouseWorldPos = core.Camera.ScreenToWorld(new Vector2(ms.X, ms.Y));
Rectangle mouseWorldRectangle = new Rectangle((int)mouseWorldPos.X, (int)mouseWorldPos.Y, 1, 1);
KeyboardState ks = Keyboard.GetState();
// OnPress events
if (ms.LeftButton == ButtonState.Pressed && lastMouseState.LeftButton == ButtonState.Released)
{
if (selectionRectangle == Rectangle.Empty)
var mouseEvent = new GUIManager.MouseEventArgs()
{
selectionRectangle = new Rectangle((int)mouseWorldPos.X, (int)mouseWorldPos.Y, 0, 0);
}
else
{
selectionRectangle.Width = (int)mouseWorldPos.X - selectionRectangle.X;
selectionRectangle.Height = (int)mouseWorldPos.Y - selectionRectangle.Y;
}
MouseState = ms,
Time = gameTime.TotalGameTime,
LeftButton = ButtonState.Pressed
};
GUIManager.RaiseAt("OnPress", mouseEvent, new Point(ms.X, ms.Y));
}
// When the mouse is released
if (ms.LeftButton == ButtonState.Released && selectionRectangle != Rectangle.Empty)
if (ms.MiddleButton == ButtonState.Pressed && lastMouseState.MiddleButton == ButtonState.Released)
{
// Deselect all units
if (!ks.IsKeyDown(Keys.LeftControl))
var mouseEvent = new GUIManager.MouseEventArgs()
{
foreach (var unit in core.Squad)
unit.Selected = false;
}
MouseState = ms,
Time = gameTime.TotalGameTime,
MiddleButton = ButtonState.Pressed
};
GUIManager.RaiseAt("OnPress", mouseEvent, new Point(ms.X, ms.Y));
// Select all units in the rectangle
foreach (var unit in core.Squad)
}
if (ms.RightButton == ButtonState.Pressed && lastMouseState.RightButton == ButtonState.Released)
{
var mouseEvent = new GUIManager.MouseEventArgs()
{
if (selectionRectangle.Intersects(unit.GetComponent<Component.Collision>().Rectangle))
unit.Selected = true;
}
// Hide the selection rectangle
selectionRectangle = Rectangle.Empty;
MouseState = ms,
Time = gameTime.TotalGameTime,
RightButton = ButtonState.Pressed
};
GUIManager.RaiseAt("OnPress", mouseEvent, new Point(ms.X, ms.Y));
}
// OnRelease events
if (ms.LeftButton == ButtonState.Released && lastMouseState.LeftButton == ButtonState.Pressed)
{
var mouseEvent = new GUIManager.MouseEventArgs()
{
MouseState = ms,
Time = gameTime.TotalGameTime,
LeftButton = ButtonState.Pressed
};
//GUIManager.RaiseAt("OnClick", mouseEvent, new Point(ms.X, ms.Y));
GUIManager.RaiseAt("OnRelease", mouseEvent, new Point(ms.X, ms.Y));
}
if (ms.MiddleButton == ButtonState.Released && lastMouseState.MiddleButton == ButtonState.Pressed)
{
var mouseEvent = new GUIManager.MouseEventArgs()
{
MouseState = ms,
Time = gameTime.TotalGameTime,
MiddleButton = ButtonState.Pressed
};
//GUIManager.RaiseAt("OnClick", mouseEvent, new Point(ms.X, ms.Y));
GUIManager.RaiseAt("OnRelease", mouseEvent, new Point(ms.X, ms.Y));
}
// Send orders with right click
if (ms.RightButton == ButtonState.Released && lastMouseState.RightButton == ButtonState.Pressed)
{
foreach (var unit in core.Squad)
if (unit.Selected)
{
unit.GetComponent<Component.PathFinder>().Goal = Grid.WorldToGrid(mouseWorldPos);
}
}
if (ms.RightButton == ButtonState.Pressed)
{
foreach (var unit in core.Squad)
{
if (unit.Selected && gridRectangle.Intersects(unit.GetComponent<Component.Collision>().Rectangle))
{
checkingDirection = true;
directionStart = unit.Transform.World + unit.Transform.World.Origin;
}
}
}
if (checkingDirection == true && ms.RightButton == ButtonState.Pressed)
{
foreach (var unit in core.Squad)
if (unit.Selected)
{
directionNow.X = mouseWorldPos.X;
directionNow.Y = mouseWorldPos.Y;
float directionX = mouseWorldPos.X - unit.Transform.World.X;
float directionY = mouseWorldPos.Y - unit.Transform.World.Y;
var mouseDirection = mouseWorldPos;
mouseDirection.Normalize();
//float angle = (float)Math.Acos(Vector2.Dot(new Vector2(0, 1), mouseDirection)) * MathHelper.TwoPi;
/*if (directionX < 0)
{
directionX *= -1;
unit.GetComponent<Component.Transform>().World.Rotation = (float)Math.Atan(directionY / directionX);
}
else
{
*/unit.GetComponent<Component.Transform>().World.Rotation = (float)Math.Atan2(mouseWorldPos.Y - unit.Transform.World.Y, mouseWorldPos.X - unit.Transform.World.X);/*
}*/
//Console.WriteLine(angle);
//unit.GetComponent<Component.Transform>().World.Rotation = angle;
}
}
else
{
checkingDirection = false;
}
// Grid highlighting
Point mouseGridPos = Grid.WorldToGrid(mouseWorldPos);
Vector2 rectWorldPos = Grid.GridToWorld(mouseGridPos);
gridRectangle = new Rectangle((int)rectWorldPos.X, (int)rectWorldPos.Y, Grid.TileSize, Grid.TileSize);
lastMouseState = ms;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(selectionTexture, selectionRectangle, Color.Red * 0.5f);
spriteBatch.Draw(gridTexture, gridRectangle, Color.Yellow * 0.3f);
if (checkingDirection == true)
{
Texture2D blank = new Texture2D(Core.GraphicsDevice, 1, 1, false, SurfaceFormat.Color);
blank.SetData(new[] { Color.White });
DrawLine(spriteBatch, blank, 2, Color.White, directionStart, directionNow);
}
}
void DrawLine(SpriteBatch batch, Texture2D blank, float width, Color color, Vector2 point1, Vector2 point2)
{
float angle = (float)Math.Atan2(point2.Y - point1.Y, point2.X - point1.X);
float length = Vector2.Distance(point1, point2);
batch.Draw(blank, point1, null, color,
angle, Vector2.Zero, new Vector2(length, width),
SpriteEffects.None, 0);
}
}
}
var mouseEvent = new GUIManager.MouseEventArgs()
{
MouseState = ms,
Time = gameTime.TotalGameTime,
RightButton = ButtonState.Pressed
};
//GUIManager.RaiseAt("OnClick", mouseEvent, new Point(ms.X, ms.Y));
GUIManager.RaiseAt("OnRelease", mouseEvent, new Point(ms.X, ms.Y));
}
// TODO: OnClick events
// Tooltip stuff
/*var tooltip = core.Lua.GetObject<GUI.Frame>("ToolTip");
if (tooltip != null)
{
tooltip.Visible = false;
foreach(var entity in core.Squad)
{
if (mouseWorldRectangle.Intersects(entity.GetComponent<Component.Collision>().Rectangle))
{
tooltip.Visible = true;
break;
}
}
if (tooltip.Visible)
{
tooltip.X = ms.X + 10;
tooltip.Y = ms.Y + 15;
}
}*/
if (core.TurnManager.CurrentTurn == core.TurnManager["Player"])
{
// Selection rectangle
/*if (ms.LeftButton == ButtonState.Pressed)
{
if (selectionRectangle == Rectangle.Empty)
{
directionStart = mouseWorldPos;
selectionRectangle = new Rectangle((int)mouseWorldPos.X, (int)mouseWorldPos.Y, 0, 0);
readjust = false;
}
else
{
if (mouseWorldPos.X > directionStart.X && mouseWorldPos.Y < directionStart.Y || mouseWorldPos.X < directionStart.X && mouseWorldPos.Y > directionStart.Y)
{
int rectangleX = (int)mouseWorldPos.X - ((int)mouseWorldPos.X - (int)directionStart.X);
int rectangleY = (int)mouseWorldPos.Y;
int rectangleWidth = (int)mouseWorldPos.X - (int)directionStart.X;
int rectangleHeight = (int)directionStart.Y - (int)mouseWorldPos.Y;
selectionRectangle = new Rectangle(rectangleX, rectangleY, rectangleWidth, rectangleHeight);
readjust = true;
}
else
{
if (readjust == true)
{
selectionRectangle = new Rectangle((int)directionStart.X, (int)directionStart.Y, 0, 0);
}
selectionRectangle.Width = (int)mouseWorldPos.X - selectionRectangle.X;
selectionRectangle.Height = (int)mouseWorldPos.Y - selectionRectangle.Y;
readjust = false;
}
}
}*/
//Calculating chance to hit if holding cursor over enemy
foreach (var unit in core.Squad)
{
if (unit.Selected == true && unit.Fired == false)
{
foreach (var enemy in core.Swarm)
{
if (gridRectangle.Intersects(enemy.GetComponent<Component.Collision>().Rectangle))
{
Console.WriteLine(Utility.CalculateHitChance(unit.GetComponent<Component.Stat>(), unit.GetComponent<Component.Transform>().World.Position, enemy));
}
}
}
}
// When the mouse is released
/*if (ms.LeftButton == ButtonState.Released && selectionRectangle != Rectangle.Empty)
{
// Deselect all units
if (!ks.IsKeyDown(Keys.LeftControl))
{
foreach (var unit in core.Squad)
unit.Selected = false;
}
// Select all units in the rectangle
foreach (var unit in core.Squad)
{
if (selectionRectangle.Intersects(unit.GetComponent<Component.Collision>().Rectangle))
unit.Selected = true;
}
// Hide the selection rectangle
selectionRectangle = Rectangle.Empty;
}*/
// Send orders with right click
/*if (ms.RightButton == ButtonState.Released && lastMouseState.RightButton == ButtonState.Pressed)
{
if (checkingDirection == false)
{
foreach (var unit in core.Squad)
if (unit.Selected)
{
unit.GetComponent<Component.PathFinder>().Goal = Grid.WorldToGrid(mouseWorldPos);
}
}
}*/
/*if (ms.RightButton == ButtonState.Pressed)
{
foreach (var unit in core.Squad)
{
if (unit.Selected && gridRectangle.Intersects(unit.GetComponent<Component.Collision>().Rectangle))
{
checkingDirection = true;
directionStart = unit.Transform.World + unit.Transform.World.Origin;
}
}
}
if (checkingDirection == true && ms.RightButton == ButtonState.Pressed)
{
foreach (var unit in core.Squad)
if (unit.Selected)
{
directionNow.X = mouseWorldPos.X;
directionNow.Y = mouseWorldPos.Y;
float directionX = mouseWorldPos.X - unit.Transform.World.X;
float directionY = mouseWorldPos.Y - unit.Transform.World.Y;
var mouseDirection = mouseWorldPos;
mouseDirection.Normalize();
unit.GetComponent<Component.Transform>().World.Rotation = (float)Math.Atan2(mouseWorldPos.Y - unit.Transform.World.Y - unit.Transform.World.Origin.Y, mouseWorldPos.X - unit.Transform.World.X - unit.Transform.World.Origin.X);
}
}
else
{
checkingDirection = false;
}*/
}
// Grid highlighting
Point mouseGridPos = Grid.WorldToGrid(mouseWorldPos);
Vector2 rectWorldPos = Grid.GridToWorld(mouseGridPos);
gridRectangle = new Rectangle((int)rectWorldPos.X, (int)rectWorldPos.Y, Grid.TileSize, Grid.TileSize);
lastMouseState = ms;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(selectionTexture, selectionRectangle, Color.Red * 0.5f);
spriteBatch.Draw(gridTexture, gridRectangle, Color.White * 0.7f);
if (checkingDirection == true)
{
Utility.DrawLine(spriteBatch, Color.White, 2, directionStart, directionNow);
}
}
}
}
View File
View File
+122
View File
@@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
using DepthsBelow.Component;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace DepthsBelow
{
public class Shot : Entity
{
public Texture2D Texture;
public Color Color;
public static Point Origin;
string type = "";
Stat soldierStat;
public Stat Stat
{
get { return soldierStat; }
set { soldierStat = value; }
}
public string Type
{
get { return type; }
set { type = value; }
}
private bool _selected = false; //I guess as in "currently doing something"
public bool select
{
get { return _selected; }
set
{
_selected = value;
}
}
public List<Shot> Volley;
public Vector2 direction = Vector2.Zero;
public Shot(Stat _soldierStat, string _type)
: base()
{
type = _type;
if (Texture == null)
LoadContent();
//Transform.World.Origin = new Vector2(16, 16);
Stat = _soldierStat;
if (type == "Rocket")
{
Stat.Strength = 50000;
}
this.Color = Color.White;
var rc = new SpriteRenderer(this) { Texture = Texture, Color = Color.White };
rc.Offset = new Vector2(16, 16);
AddComponent(rc);
var cc = new Collision(this, 32, 32);
AddComponent(cc);
}
public void LoadContent()
{
if (type == "Rocket")
{
Texture = GameServices.GetService<ContentManager>().Load<Texture2D>("images/RocketProjectile");
}
else
{
Texture = GameServices.GetService<ContentManager>().Load<Texture2D>("images/Shot3");
}
}
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
float elapsed = gameTime.ElapsedGameTime.Milliseconds / 1000.0f;
List<Point> soldierCollisions = new List<Point>();
// HACK: Make this work properly with other speeds...
float speed = 4f;
Transform.World.Position += speed * direction;
foreach (var entity in EntityManager.Entities)
{
var collision = entity.GetComponent<Component.Collision>();
if (collision == null)
continue;
if (this.GetComponent<Component.Collision>().Rectangle.Intersects(collision.Rectangle))
{
if (entity is SmallEnemy)
{
if (Utility.AttackTest(Stat, entity, Utility.CalculateHitChance(Stat, this.Stat.Remember, entity)))
{
this.Remove();
return;
}
}
if (entity is Door && type == "Rocket")
{
((Door)entity).Kill();
this.Remove();
return;
}
}
}
}
}
}
+194
View File
@@ -0,0 +1,194 @@
using System;
using System.Collections.Generic;
using DepthsBelow.Component;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace DepthsBelow
{
public class SmallEnemy : Entity
{
public Texture2D Texture;
public Color Color;
public static Point Origin;
private bool _selected; //I guess as in "currently doing something"
public List<SmallEnemy> Swarm;
private PathFinder.Node nextNode;
public int numberOfSteps = 8;
public int currentStep = 0;
public bool AttackedThisTurn = false;
public int step
{
get { return currentStep; }
set
{
currentStep = value;
}
}
public SmallEnemy(ref List<SmallEnemy> swarm)
: base()
{
if (Texture == null)
LoadContent();
this.Swarm = swarm;
Transform.World.Origin = new Vector2(20, 16);
this.Color = Color.White;
var rc = new SpriteRenderer(this) { Texture = Texture, Color = Color.White };
AddComponent(rc);
var cc = new Collision(this, 32, 32);
cc.Solid = true;
AddComponent(cc);
var pfc = new PathFinder(this);
AddComponent(pfc);
var stat = new Component.Stat(this)
{
Life = 50,
Defence = 25,
Strength = 70,
GetAim = 100,
GetDodge = 50
};
AddComponent(stat);
}
public override void Remove()
{
Swarm.Remove(this);
base.Remove();
}
public bool Selected
{
get { return _selected; }
set
{
_selected = value;
GetComponent<SpriteRenderer>().Color = (value) ? Color.Blue : this.Color;
}
}
public void LoadContent()
{
Texture = GameServices.GetService<ContentManager>().Load<Texture2D>("images/Monster");
}
public void LoadBoss()
{
Texture = GameServices.GetService<ContentManager>().Load<Texture2D>("images/Pineapple");
GetComponent<SpriteRenderer>().Texture = Texture;
Transform.World.Origin = new Vector2(((float)Texture.Width) / 2f, ((float)Texture.Height) / 2f);
GetComponent<SpriteRenderer>().Offset = (new Vector2(Texture.Width / 2f, Texture.Height / 2f) - new Vector2(Grid.TileSize / 2, Grid.TileSize / 2)) * -1;
GetComponent<Stat>()._MaxHP = 500;
GetComponent<Stat>().MaxHP = 500;
GetComponent<Stat>().Life = 500;
GetComponent<Stat>().Defence = 15;
GetComponent<Stat>().Strength = 70;
GetComponent<Stat>().GetAim = 80;
GetComponent<Stat>().GetDodge = 5;
}
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
float elapsed = gameTime.ElapsedGameTime.Milliseconds / 1000.0f;
if (nextNode == null)
nextNode = GetComponent<PathFinder>().Next();
if (nextNode != null)
{
List<Point> soldierCollisions = new List<Point>();
// Collision with moving units
foreach (var body in Swarm)
{
if (body != this)
{
if (body.Transform.Grid == nextNode.Position)
{
soldierCollisions.Add(body.Transform.Grid);
GetComponent<PathFinder>().RecreatePath(soldierCollisions);
nextNode = GetComponent<PathFinder>().Next();
break;
}
}
}
if (nextNode != null)
{
var nodeWorldPos = Grid.GridToWorld(nextNode.Position);
// HACK: Make this work properly with other speeds...
float speed = 4f;
if (Transform.World.X < nodeWorldPos.X)
{
Transform.World.X += speed;
GetComponent<Component.Transform>().World.Rotation = MathHelper.ToRadians(0);
}
if (Transform.World.X > nodeWorldPos.X)
{
Transform.World.X -= speed;
GetComponent<Component.Transform>().World.Rotation = MathHelper.ToRadians(180);
}
if (Transform.World.Y < nodeWorldPos.Y)
{
Transform.World.Y += speed;
GetComponent<Component.Transform>().World.Rotation = MathHelper.ToRadians(90);
}
if (Transform.World.Y > nodeWorldPos.Y)
{
Transform.World.Y -= speed;
GetComponent<Component.Transform>().World.Rotation = MathHelper.ToRadians(270);
}
if (Transform.World == nodeWorldPos)
{
if (currentStep < numberOfSteps)
{
currentStep++;
//lastLastNode = lastNode;
//lastNode = nextNode;
nextNode = GetComponent<PathFinder>().Next();
}
else
{
GetComponent<PathFinder>().Stop();
}
foreach (var entity in EntityManager.Entities)
{
if (entity is Soldier)
{
if (entity.GetComponent<Component.Collision>().Rectangle.Intersects(this.GetComponent<Component.Collision>().Rectangle))
{
if (AttackedThisTurn == false)
{
if (Utility.AttackTest(this.GetComponent<Component.Stat>(), entity, Utility.CalculateHitChance(this.GetComponent<Component.Stat>(), this.Transform.World.Position, entity)))
{
AttackedThisTurn = true;
break;
}
}
}
}
}
}
}
}
}
}
}
+117 -29
View File
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using DepthsBelow.Component;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
@@ -11,17 +12,47 @@ namespace DepthsBelow
{
public static Texture2D Texture;
public Color Color;
public static Point Origin;
public string Name;
private bool _selected;
public List<Soldier> Squad;
private PathFinder.Node nextNode;
private PathFinder.Node lastNode;
private PathFinder.Node lastLastNode;
public Soldier(Core core, ref List<Soldier> squad) : base(core)
private bool hasFiredAlready = false;
int fireTimer = 0;
int timeSpentFired = 1000;
public bool Fired
{
get { return hasFiredAlready; }
set
{
hasFiredAlready = value;
}
}
public int MaxActionPoints = 10;
int actionPointsLeft = 10;
public int AP
{
get { return actionPointsLeft; }
set
{
actionPointsLeft = value;
GetComponent<Component.Stat>().GetStep = actionPointsLeft;
}
}
public Soldier(ref List<Soldier> squad)
: base()
{
if (Texture == null)
LoadContent(core);
LoadContent();
this.Squad = squad;
@@ -37,11 +68,30 @@ namespace DepthsBelow
var pfc = new PathFinder(this);
AddComponent(pfc);
AddComponent(new Flashlight(this)
{
Range = 200,
Fov = MathHelper.PiOver4
});
var flashlight = new Flashlight(this)
{
Intensity = 0.8f
};
AddComponent(flashlight);
var stat = new Component.Stat(this)
{
MaxHP = 100,
MaxPanic = 100,
Life = 100,
Defence = 25,
Strength = 50,
GetAim = 40,
GetDodge = 20
};
AddComponent(stat);
}
public override void Remove()
{
Squad.Remove(this);
base.Remove();
}
public bool Selected
@@ -54,9 +104,9 @@ namespace DepthsBelow
}
}
public static void LoadContent(Core core)
public static void LoadContent()
{
Texture = core.Content.Load<Texture2D>("images/soldier2");
Texture = GameServices.GetService<ContentManager>().Load<Texture2D>("images/soldier5");
}
public override void Update(GameTime gameTime)
@@ -64,7 +114,7 @@ namespace DepthsBelow
base.Update(gameTime);
float elapsed = gameTime.ElapsedGameTime.Milliseconds / 1000.0f;
if (nextNode == null)
nextNode = GetComponent<PathFinder>().Next();
@@ -72,21 +122,41 @@ namespace DepthsBelow
{
List<Point> soldierCollisions = new List<Point>();
foreach (var soldier in Squad)
{
if (soldier != this)
{
if (soldier.Transform.Grid == nextNode.Position)
{
soldierCollisions.Add(soldier.Transform.Grid);
GetComponent<PathFinder>().RecreatePath(soldierCollisions);
nextNode = GetComponent<PathFinder>().Next();
break;
}
}
}
// Collision with units at a standstill
//foreach (var soldier in Squad)
//{
// if (soldier != this)
// {
// if (!soldier.GetComponent<PathFinder>().IsMoving)
// {
// soldierCollisions.Add(soldier.Transform.Grid);
// }
// if (soldier.Transform.Grid == nextNode.Position)
// {
// GetComponent<PathFinder>().RecreatePath(soldierCollisions);
// nextNode = GetComponent<PathFinder>().Next();
// break;
// }
// }
//}
// Collision with moving units
//foreach (var soldier in Squad)
//{
// if (soldier != this)
// {
// var pathFinder = soldier.GetComponent<PathFinder>();
// var position = nextNode.Position;
// if (soldier.Transform.Grid == position)
// {
// soldierCollisions.Add(soldier.Transform.Grid);
// GetComponent<PathFinder>().RecreatePath(soldierCollisions);
// nextNode = GetComponent<PathFinder>().Next();
// break;
// }
// }
//}
if (nextNode != null)
{
@@ -103,12 +173,30 @@ namespace DepthsBelow
Transform.World.Y -= speed;
if (Transform.World == nodeWorldPos)
nextNode = GetComponent<PathFinder>().Next();
{
//if (AP < NumberOfActionPoints)
//{
//AP++;
lastLastNode = lastNode;
lastNode = nextNode;
nextNode = GetComponent<PathFinder>().Next();
//}
/*else
{
GetComponent<PathFinder>().Stop();
}*/
}
}
}
/**/
if (Fired == true)
{
fireTimer += gameTime.ElapsedGameTime.Milliseconds;
if (fireTimer > timeSpentFired)
{
fireTimer = 0;
Fired = false;
}
}
}
}
}
+122
View File
@@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
namespace DepthsBelow
{
/// <summary>
/// Keeps track of whose turn it is.
/// </summary>
public class TurnManager
{
public static int currentTurn = 0;
/// <summary>
/// A player turn token.
/// </summary>
public class Token
{
/// <summary>
/// Unique identifying name of the token.
/// </summary>
public string Name { get; private set; }
private TurnManager turnManager;
/// <summary>
/// Initializes a new instance of the <see cref="Token" /> class.
/// Preferably use <see cref="TurnManager.CreateToken" /> instead.
/// </summary>
/// <param name="turnManager">The turn manager the token belongs to.</param>
/// <param name="name">Unique identifying name of the token.</param>
public Token(TurnManager turnManager, string name)
{
this.turnManager = turnManager;
this.Name = name;
turnManager.AddToken(this);
}
}
/// <summary>
/// Dictionary of turn tokens.
/// </summary>
public Dictionary<string, Token> Tokens;
private int currentTokenIndex;
/// <summary>
/// The turn token belonging to a player.
/// </summary>
public Token CurrentTurn
{
get { return Tokens.ElementAt(currentTokenIndex).Value; }
}
/// <summary>
/// Get the turn token by the specified name.
/// </summary>
/// <param name="name">The identifying name of the player.</param>
/// <returns>Returns a player turn token.</returns>
public Token this[string name]
{
get { return this.Tokens[name]; }
}
/// <summary>
/// Create a turn manager.
/// </summary>
public TurnManager()
{
Tokens = new Dictionary<string, Token>();
}
/// <summary>
/// Create a turn manager.
/// </summary>
/// <param name="tokenNames">Tokens of players.</param>
public TurnManager(string[] tokenNames)
: this()
{
foreach (var tokenName in tokenNames)
CreateToken(tokenName);
}
/// <summary>
/// Create a turn token.
/// </summary>
/// <param name="name">Name of the token.</param>
/// <returns>Returns a player turn token.</returns>
public Token CreateToken(string name)
{
return Tokens.ContainsKey(name) ? Tokens[name] : new Token(this, name);
}
/// <summary>
/// Add a turn token to
/// </summary>
/// <param name="token"></param>
public void AddToken(Token token)
{
if (!Tokens.ContainsKey(token.Name))
Tokens.Add(token.Name, token);
}
/// <summary>
/// End the current turn, skipping to the next token in the dictionary.
/// </summary>
public void EndTurn()
{
var prevTurn = CurrentTurn;
if (++currentTokenIndex > Tokens.Count - 1)
currentTokenIndex = 0;
Debug.WriteLine(prevTurn.Name + " turn ended. Current turn: " + CurrentTurn.Name);
if (CurrentTurn.Name == "Player")
{
currentTurn++;
Console.WriteLine("Turn: " + currentTurn);
}
}
}
}
+107
View File
@@ -0,0 +1,107 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DepthsBelow.Component;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace DepthsBelow
{
/// <summary>
/// Various global utility functions.
/// </summary>
static class Utility
{
/// <summary>
/// Calculate the chance of an entity with a Stat component to hit another unit.
/// </summary>
/// <param name="attacker">The attacking unit.</param>
/// <param name="defender">The recieving unit.</param>
/// <returns>Returns a hit chance percentage.</returns>
public static int CalculateHitChance(Stat attacker, Vector2 attackerPosition, Entity defender)
{
Stat shooting = attacker;
Stat dodging = defender.GetComponent<Stat>();
if (shooting == null || dodging == null)
{
return 0;
}
int baseHitChance = shooting.GetAim;
int baseDodgeChance = dodging.GetDodge;
int distance = (int)Vector2.Distance(attackerPosition, defender.Transform.World.Position);
int basePenalty = shooting.Penalty(distance / (Grid.TileSize));
Console.WriteLine("Penalty = " + basePenalty);
int chanceToHit = baseHitChance - baseDodgeChance - basePenalty;
//Console.WriteLine(chanceToHit);
return chanceToHit;
}
public static bool AttackTest(Stat attacker, Entity defender, int chanceToHit)
{
Component.Stat shooting = attacker;
Component.Stat dodging = defender.GetComponent<Component.Stat>();
Random rand = new Random();
if (rand.Next(0, 100) < chanceToHit)
{
dodging.Life -= shooting.Strength - dodging.Defence / 2;
return true;
}
return false;
}
private static Texture2D blank;
public static void DrawLine(SpriteBatch batch, Color color, float width, Vector2 start, Vector2 end)
{
if (blank == null)
{
blank = new Texture2D(Core.GraphicsDeviceManager.GraphicsDevice, 1, 1, false, SurfaceFormat.Color);
blank.SetData(new[] { color });
}
float angle = (float)Math.Atan2(end.Y - start.Y, end.X - start.X);
float length = Vector2.Distance(start, end);
batch.Draw(blank, start, null, color,
angle, Vector2.Zero, new Vector2(length, width),
SpriteEffects.None, 0);
}
private static Texture2D solidTexture = null;
/// <summary>
/// Creates a 1x1 solid white XNA texture.
/// </summary>
/// <returns>Returns a 1x1 solid white Texture2D object.</returns>
public static Texture2D GetSolidTexture()
{
if (solidTexture == null)
{
solidTexture = new Texture2D(GameServices.GetService<GraphicsDevice>(), 1, 1);
solidTexture.SetData(new Color[] { Color.White });
}
return solidTexture;
}
/// <summary>
/// Converts rectangles with negative sizes to positive sizes with its position offset.
/// </summary>
/// <param name="rect">The rectangle with potentially negative sizes.</param>
/// <returns>Returns a rectangle with positive sizes.</returns>
public static Rectangle MakeRectanglePositive(Rectangle rect)
{
if (rect.Width < 0)
{
rect.X += rect.Width;
rect.Width = -rect.Width;
}
if (rect.Height < 0)
{
rect.Y += rect.Height;
rect.Height = -rect.Height;
}
return rect;
}
}
}
+60
View File
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file contains an xml description of a font, and will be read by the XNA
Framework Content Pipeline. Follow the comments to customize the appearance
of the font in your game, and to change the characters which are available to draw
with.
-->
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
<Asset Type="Graphics:FontDescription">
<!--
Modify this string to change the font that will be imported.
-->
<FontName>Arial</FontName>
<!--
Size is a float value, measured in points. Modify this value to change
the size of the font.
-->
<Size>11</Size>
<!--
Spacing is a float value, measured in pixels. Modify this value to change
the amount of spacing in between characters.
-->
<Spacing>0</Spacing>
<!--
UseKerning controls the layout of the font. If this value is true, kerning information
will be used when placing characters.
-->
<UseKerning>true</UseKerning>
<!--
Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",
and "Bold, Italic", and are case sensitive.
-->
<Style>Regular</Style>
<!--
If you uncomment this line, the default character will be substituted if you draw
or measure text that contains characters which were not included in the font.
-->
<!-- <DefaultCharacter>*</DefaultCharacter> -->
<!--
CharacterRegions control what letters are available in the font. Every
character from Start to End will be built and made available for drawing. The
default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin
character set. The characters are ordered according to the Unicode standard.
See the documentation for more information.
-->
<CharacterRegions>
<CharacterRegion>
<Start>&#32;</Start>
<End>&#126;</End>
</CharacterRegion>
</CharacterRegions>
</Asset>
</XnaContent>
+272 -117
View File
@@ -1,118 +1,273 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{433A77A2-DE52-4875-A4EF-232CF59C2DD3}</ProjectGuid>
<ProjectTypeGuids>{96E2B04D-8817-42c6-938A-82C39BA4D311};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<XnaFrameworkVersion>v4.0</XnaFrameworkVersion>
<OutputPath>bin\$(Platform)\$(Configuration)</OutputPath>
<ContentRootDirectory>Content</ContentRootDirectory>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup>
<RootNamespace>DepthsBelowContent</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.EffectImporter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.FBXImporter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.TextureImporter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.XImporter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.AudioImporters, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.VideoImporters, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="images\soldier.png">
<Name>soldier</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
<Compile Include="maps\test.tmx">
<Name>test</Name>
<Importer>TmxImporter</Importer>
<Processor>MapProcessor</Processor>
<SubType>Designer</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\TiledLib\TiledLib\TiledLib.csproj">
<Project>{EC3F6988-459C-4783-89E9-F34C0CC731C7}</Project>
<Name>TiledLib</Name>
</ProjectReference>
<ProjectReference Include="..\DepthsBelowContentPipeline\DepthsBelowContentPipeline.csproj">
<Project>{D054E3A6-7E05-4255-984F-69FE40D9137F}</Project>
<Name>DepthsBelowContentPipeline</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Compile Include="maps\tilesets\aztek.jpg">
<Name>aztek</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="images\soldier2.png">
<Name>soldier2</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="maps\tilesets\collision.png">
<Name>collision</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="maps\Cave.Level1.tmx">
<Name>Cave.Level1</Name>
<Processor>MapProcessor</Processor>
<Importer>TmxImporter</Importer>
<SubType>Designer</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="maps\tilesets\cave.png">
<Name>cave</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="KryptonEffect.fx">
<Name>KryptonEffect</Name>
<Importer>EffectImporter</Importer>
<Processor>EffectProcessor</Processor>
</Compile>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\$(XnaFrameworkVersion)\Microsoft.Xna.GameStudio.ContentPipeline.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{433A77A2-DE52-4875-A4EF-232CF59C2DD3}</ProjectGuid>
<ProjectTypeGuids>{96E2B04D-8817-42c6-938A-82C39BA4D311};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<XnaFrameworkVersion>v4.0</XnaFrameworkVersion>
<OutputPath>bin\$(Platform)\$(Configuration)</OutputPath>
<ContentRootDirectory>Content</ContentRootDirectory>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup>
<RootNamespace>DepthsBelowContent</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.EffectImporter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.FBXImporter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.TextureImporter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.XImporter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.AudioImporters, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.VideoImporters, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="images\soldier.png">
<Name>soldier</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\TiledLib\TiledLib\TiledLib.csproj">
<Project>{EC3F6988-459C-4783-89E9-F34C0CC731C7}</Project>
<Name>TiledLib</Name>
</ProjectReference>
<ProjectReference Include="..\DepthsBelowContentPipeline\DepthsBelowContentPipeline.csproj">
<Project>{D054E3A6-7E05-4255-984F-69FE40D9137F}</Project>
<Name>DepthsBelowContentPipeline</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Compile Include="images\soldier2.png">
<Name>soldier2</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="images\Monster.png">
<Name>Monster</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="images\Enter.bmp">
<Name>Enter</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="Arial.spritefont">
<Name>Arial</Name>
<Importer>FontDescriptionImporter</Importer>
<Processor>FontDescriptionProcessor</Processor>
<SubType>Designer</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="images\Shot2.bmp">
<Name>Shot2</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="images\FireBall.PNG">
<Name>Shot</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="scripts\gui.lua">
<Name>gui</Name>
<Importer>LuaImporter</Importer>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Compile>
<Compile Include="scripts\test.lua">
<Name>test</Name>
<Importer>LuaImporter</Importer>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="scripts\tooltip.lua">
<Name>tooltip</Name>
<Importer>LuaImporter</Importer>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="images\GUI\bar_solid.png">
<Name>bar_solid</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
<Compile Include="images\GUI\bar_transparent.png">
<Name>bar_transparent</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
<Compile Include="images\GUI\health_background.png">
<Name>health_background</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
<Compile Include="images\GUI\unit_background.png">
<Name>unit_background</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="fonts\UnitName.spritefont">
<Name>UnitName</Name>
<Importer>FontDescriptionImporter</Importer>
<Processor>FontDescriptionProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="shaders\LightEffect.fx">
<Name>LightEffect</Name>
<Importer>EffectImporter</Importer>
<Processor>EffectProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="images\lights\point.png">
<Name>point</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
<Compile Include="images\lights\spot.png">
<Name>spot</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="maps\Aztek.Test.tmx">
<Name>Aztek.Test</Name>
<Importer>TmxImporter</Importer>
<Processor>MapProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="images\soldier3.png">
<Name>soldier3</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="images\soldier5.png">
<Name>soldier5</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="images\lights\spot_wide.png">
<Name>spot_wide</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="images\selection.png">
<Name>selection</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="images\Shot3.bmp">
<Name>Shot3</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="maps\prototyp.tmx">
<Name>prototyp</Name>
<Importer>TmxImporter</Importer>
<Processor>MapProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="images\door_closed.png">
<Name>door_closed</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
<Compile Include="images\door_destroyed.png">
<Name>door_destroyed</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
<Compile Include="images\door_open.png">
<Name>door_open</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="images\Pineapple.png">
<Name>Pineapple</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="images\Pineapple%282%29.png">
<Name>Pineapple%282%29</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="maps\prototyp2.tmx">
<Name>prototyp2</Name>
<Importer>TmxImporter</Importer>
<Processor>MapProcessor</Processor>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="images\RocketProjectile.png">
<Name>RocketProjectile</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\$(XnaFrameworkVersion)\Microsoft.Xna.GameStudio.ContentPipeline.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
@@ -1,438 +0,0 @@
// ------------------------------------------------------------------------------------------------ //
// ----- Copyright 2011 Christopher Harris --------------------- http://krypton.codeplex.com/ ----- //
// ----------------------------------------------------------------- mailto:xixonia@gmail.com ----- //
// ------------------------------------------------------------------------------------------------ //
// ------------------------------------------------------------------------------------------------ //
// ----- Parameters ------------------------------------------------------------------------------- //
float4x4 Matrix;
texture Texture0;
texture Texture1;
float2 LightPosition;
float LightIntensityFactor = 1;
float ShadowStrech = 1000000;
float2 TexelBias;
float4 AmbientColor;
float Bluriness = 0.5f;
float BlurFactorU = 0;
float BlurFactorV = 0;
// ------------------------------------------------------------------------------------------------ //
// ----- Samplers --------------------------------------------------------------------------------- //
sampler2D tex0 = sampler_state
{
Texture = <Texture0>;
AddressU = Clamp;
AddressV = Clamp;
};
sampler2D tex1 = sampler_state
{
Texture = <Texture1>;
AddressU = Clamp;
AddressV = Clamp;
};
// ------------------------------------------------------------------------------------------------ //
// ----- Structures ------------------------------------------------------------------------------- //
struct ShadowHullVertex
{
float4 Position : POSITION0;
float2 Normal : NORMAL0;
float4 Color : COLOR0;
};
struct VertexPositionColor
{
float4 Position : POSITION0;
float4 Color : COLOR0;
};
struct VertexPositionColorTexture
{
float4 Position : POSITION0;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
};
struct VertexPositionTexture
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
};
struct Color2
{
float4 Color0 : COLOR0;
float4 Color1 : COLOR1;
};
// ------------------------------------------------------------------------------------------------ //
// ----- Vertex Shaders --------------------------------------------------------------------------- //
VertexPositionTexture VS_TextureNoTransform(VertexPositionTexture input)
{
return input;
};
VertexPositionColorTexture VS_ColorTexture(VertexPositionColorTexture input)
{
input.Position = mul(input.Position, Matrix);
return input;
};
VertexPositionColor VS_Hull(ShadowHullVertex input)
{
VertexPositionColor output;
output.Position = mul(input.Position, Matrix);
output.Color = input.Color;
return output;
};
VertexPositionColor VS_Hull_RadialStretch(ShadowHullVertex input)
{
float2 direction = normalize(LightPosition.xy - input.Position.xy);
if(dot(input.Normal.xy, direction) < 0)
{
// Stretch backfacing vertices
input.Position.xy -= direction * ShadowStrech;
}
VertexPositionColor output;
output.Position = mul(input.Position, Matrix);
output.Color = input.Color;
return output;
};
// ------------------------------------------------------------------------------------------------ //
// ----- Pixel Shaders ---------------------------------------------------------------------------- //
// ------------------------------------------------------------------------------------------------ //
// ----- Techniques ------------------------------------------------------------------------------- //
float4 PS_Texture(in float2 texCoord : TEXCOORD0) : COLOR0
{
return tex2D(tex0, texCoord + TexelBias);
};
float4 PS_ColorTexture(in float4 color : COLOR0, in float2 texCoord : TEXCOORD0) : COLOR0
{
return tex2D(tex0, texCoord) * color;
};
float4 PS_LightTexture(VertexPositionColorTexture input) : COLOR0
{
return pow(abs(tex2D(tex0, input.TexCoord)) * input.Color, LightIntensityFactor);
};
float4 PS_Color(in float4 color : COLOR0) : COLOR0
{
return color;
};
float4 PS_White() : COLOR0
{
return float4(1, 1, 1, 1);
};
float4 PS_Black() : COLOR0
{
return float4(0, 0, 0, 1);
};
float4 PS_Debug() : COLOR0
{
return float4(1, 0, 0, 1);
};
float4 PS_BlurH(in float2 texCoord : TEXCOORD0) : COLOR0
{
float blurFactor = Bluriness * BlurFactorU / 4.0f;
return
tex2D(tex0, float2(texCoord.x - blurFactor * 4, texCoord.y) + TexelBias) * 0.05f +
tex2D(tex0, float2(texCoord.x - blurFactor * 3, texCoord.y) + TexelBias) * 0.09f +
tex2D(tex0, float2(texCoord.x - blurFactor * 2, texCoord.y) + TexelBias) * 0.12f +
tex2D(tex0, float2(texCoord.x - blurFactor, texCoord.y) + TexelBias) * 0.15f +
tex2D(tex0, float2(texCoord.x, texCoord.y) + TexelBias) * 0.18f +
tex2D(tex0, float2(texCoord.x + blurFactor, texCoord.y) + TexelBias) * 0.15f +
tex2D(tex0, float2(texCoord.x + blurFactor * 2, texCoord.y) + TexelBias) * 0.12f +
tex2D(tex0, float2(texCoord.x + blurFactor * 3, texCoord.y) + TexelBias) * 0.09f +
tex2D(tex0, float2(texCoord.x + blurFactor * 4, texCoord.y) + TexelBias) * 0.05f;
}
float4 PS_BlurV(in float2 texCoord : TEXCOORD0) : COLOR0
{
float blurFactor = Bluriness * BlurFactorV / 4.0f;
return
tex2D(tex0, float2(texCoord.x, texCoord.y - blurFactor * 4) + TexelBias) * 0.05f +
tex2D(tex0, float2(texCoord.x, texCoord.y - blurFactor * 3) + TexelBias) * 0.09f +
tex2D(tex0, float2(texCoord.x, texCoord.y - blurFactor * 2) + TexelBias) * 0.12f +
tex2D(tex0, float2(texCoord.x, texCoord.y - blurFactor) + TexelBias) * 0.15f +
tex2D(tex0, float2(texCoord.x, texCoord.y) + TexelBias) * 0.18f +
tex2D(tex0, float2(texCoord.x, texCoord.y + blurFactor) + TexelBias) * 0.15f +
tex2D(tex0, float2(texCoord.x, texCoord.y + blurFactor * 2) + TexelBias) * 0.12f +
tex2D(tex0, float2(texCoord.x, texCoord.y + blurFactor * 3) + TexelBias) * 0.09f +
tex2D(tex0, float2(texCoord.x, texCoord.y + blurFactor * 4) + TexelBias) * 0.05f;
}
// ------------------------------------------------------------------------------------------------
// ----- Technique: TextureToTarget ---------------------------------------------------------------
technique TextureToTarget_Add
{
pass Pass1
{
StencilEnable = False;
BlendOp = Add;
SrcBlend = One;
DestBlend = One;
AlphaBlendEnable = True;
CullMode = CCW;
VertexShader = compile vs_2_0 VS_TextureNoTransform();
PixelShader = compile ps_2_0 PS_Texture();
}
};
technique TextureToTarget_Multiply
{
pass Pass1
{
StencilEnable = False;
BlendOp = Add;
SrcBlend = Zero;
DestBlend = SrcColor;
AlphaBlendEnable = True;
CullMode = CCW;
VertexShader = compile vs_2_0 VS_TextureNoTransform();
PixelShader = compile ps_2_0 PS_Texture();
}
};
technique LightTexture
{
pass Pass1
{
StencilEnable = False;
BlendOp = Add;
DestBlend = Zero;
SrcBlend = SrcAlpha;
AlphaBlendEnable = True;
VertexShader = compile vs_2_0 VS_ColorTexture();
PixelShader = compile ps_2_0 PS_LightTexture();
}
};
// ------------------------------------------------------------------------------------------------
// ----- Technique: PointLight_Shadow -------------------------------------------------------------
technique PointLight_Shadow_Solid
{
pass Shadow
{
StencilEnable = False;
ScissorTestEnable = True;
AlphaBlendEnable = True;
BlendOp = Add;
SrcBlend = DestColor;
DestBlend = Zero;
ColorWriteEnable = Alpha;
VertexShader = compile vs_2_0 VS_Hull_RadialStretch();
PixelShader = compile ps_2_0 PS_Color();
}
};
technique PointLight_Shadow_Illuminated
{
pass Shadow
{
StencilEnable = False;
ScissorTestEnable = True;
AlphaBlendEnable = True;
BlendOp = Add;
SrcBlend = DestAlpha;
DestBlend = Zero;
ColorWriteEnable = Alpha;
VertexShader = compile vs_2_0 VS_Hull_RadialStretch();
PixelShader = compile ps_2_0 PS_Color();
}
pass Hull
{
StencilEnable = False;
ScissorTestEnable = True;
AlphaBlendEnable = True;
BlendOp = Add;
SrcBlend = One;
DestBlend = Zero;
ColorWriteEnable = Alpha;
VertexShader = compile vs_2_0 VS_Hull();
PixelShader = compile ps_2_0 PS_White();
}
};
technique PointLight_Shadow_Occluded
{
pass Shadow
{
StencilEnable = True;
StencilFunc = Always;
StencilPass = IncrSat;
StencilFail = Keep;
ScissorTestEnable = True;
AlphaBlendEnable = True;
BlendOp = Add;
SrcBlend = DestAlpha;
DestBlend = Zero;
ColorWriteEnable = Alpha;
VertexShader = compile vs_2_0 VS_Hull_RadialStretch();
PixelShader = compile ps_2_0 PS_Color();
}
pass Hull
{
StencilEnable = True;
StencilFunc = Equal;
StencilRef = 1;
StencilPass = Keep;
ScissorTestEnable = True;
AlphaBlendEnable = True;
BlendOp = Add;
SrcBlend = One;
DestBlend = Zero;
ColorWriteEnable = Alpha;
VertexShader = compile vs_2_0 VS_Hull();
PixelShader = compile ps_2_0 PS_White();
}
};
technique PointLight_Light
{
pass Light
{
StencilEnable = False;
ScissorTestEnable = False;
AlphaBlendEnable = True;
BlendOp = Add;
SrcBlend = DestAlpha;
DestBlend = One;
ColorWriteEnable = Red | Green | Blue;
VertexShader = compile vs_2_0 VS_ColorTexture();
PixelShader = compile ps_2_0 PS_LightTexture();
}
};
technique ClearTarget_Alpha
{
pass Pass1
{
StencilEnable = False;
AlphaBlendEnable = True;
BlendOp = Add;
SrcBlend = One;
DestBlend = One;
ScissorTestEnable = True;
ColorWriteEnable = Red | Green | Blue | Alpha;
VertexShader = compile vs_2_0 VS_TextureNoTransform();
PixelShader = compile ps_2_0 PS_Black();
}
};
// ------------------------------------------------------------------------------------------------
// ----- Technique: Blur --------------------------------------------------------------------------
technique Blur
{
pass HorizontalBlur
{
ScissorTestEnable = False;
StencilEnable = False;
AlphaBlendEnable = False;
CullMode = CCW;
VertexShader = compile vs_2_0 VS_TextureNoTransform();
PixelShader = compile ps_2_0 PS_BlurH();
}
pass VerticalBlur
{
ScissorTestEnable = False;
StencilEnable = False;
AlphaBlendEnable = False;
CullMode = CCW;
VertexShader = compile vs_2_0 VS_TextureNoTransform();
PixelShader = compile ps_2_0 PS_BlurV();
}
}
// ------------------------------------------------------------------------------------------------
// ----- Technique: DebugDraw ---------------------------------------------------------------------
technique DebugDraw
{
pass Solid
{
StencilEnable = False;
AlphaBlendEnable = False;
VertexShader = compile vs_2_0 VS_Hull();
PixelShader = compile ps_2_0 PS_Debug();
}
};
+60
View File
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file contains an xml description of a font, and will be read by the XNA
Framework Content Pipeline. Follow the comments to customize the appearance
of the font in your game, and to change the characters which are available to draw
with.
-->
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
<Asset Type="Graphics:FontDescription">
<!--
Modify this string to change the font that will be imported.
-->
<FontName>Arial</FontName>
<!--
Size is a float value, measured in points. Modify this value to change
the size of the font.
-->
<Size>10</Size>
<!--
Spacing is a float value, measured in pixels. Modify this value to change
the amount of spacing in between characters.
-->
<Spacing>0</Spacing>
<!--
UseKerning controls the layout of the font. If this value is true, kerning information
will be used when placing characters.
-->
<UseKerning>true</UseKerning>
<!--
Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",
and "Bold, Italic", and are case sensitive.
-->
<Style>Regular</Style>
<!--
If you uncomment this line, the default character will be substituted if you draw
or measure text that contains characters which were not included in the font.
-->
<!-- <DefaultCharacter>*</DefaultCharacter> -->
<!--
CharacterRegions control what letters are available in the font. Every
character from Start to End will be built and made available for drawing. The
default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin
character set. The characters are ordered according to the Unicode standard.
See the documentation for more information.
-->
<CharacterRegions>
<CharacterRegion>
<Start>&#32;</Start>
<End>&#126;</End>
</CharacterRegion>
</CharacterRegions>
</Asset>
</XnaContent>
Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 977 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 983 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1008 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 B

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 405 B

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

+45
View File
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" width="100" height="100" tilewidth="32" tileheight="32">
<tileset firstgid="1" name="Aztek" tilewidth="32" tileheight="32">
<image source="tilesets/aztek.png" width="480" height="693"/>
</tileset>
<tileset firstgid="316" name="Collision" tilewidth="32" tileheight="32">
<image source="tilesets/collision.png" width="32" height="32"/>
</tileset>
<layer name="Floor" width="100" height="100">
<data encoding="base64" compression="zlib">
eJzt1sEJgEAMAMED++/ZCsTzYVxhBtJA9pGsBQAA0HVsDHP0aNjpoMccPZr0aNGjS4MWPVr0aHjya2n1Pj2a7nauxyw9WvRouerhjnxDjxY9WvRocc9b9GjRo0WPFj1a9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4M9ODsMCBQ==
</data>
</layer>
<layer name="Tile Layer 1" width="100" height="100">
<data encoding="base64" compression="zlib">
eJzt2MlOwzAQBmA/Ajvc2OEGYr0BLcuN7f2fhqlUS1GqNCfHQfk+6ZeqxAdLk2TGTQkAAMg2IpuRrTXZjuzU2uDEHEaOIsdrchI5rbS/KVk8+w+Rx551N5Hb8tuZvMWz/x756FmnHsN4iexHDnrWqccwviMXkcuedeoxnKfIc1p9V3Yje8vrs8i8xuYm6DPylVbflbPI+fL6Ir9VdjdtV5Hr5W/fqHrymbA5+95F7pPzYQ35TNicfV8jb8n5sIbc07v6eU6+71tWVu7p6/p5s9+rxzD6+nm+rx7D6KpHu9/nXq+vl9VVj3a/z71eXy+rqx7N602+W2Wpx7h01aM9D+dZeJb8r1VSVz3a83CehX+S/7VKMu+Oi3qMi3qMi3qMi3oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDf/QHD8yhT
</data>
</layer>
<layer name="Tile Layer 2" width="100" height="100">
<data encoding="base64" compression="zlib">
eJzt0bEJgEAQRNHrx6tAq/BswP6rcCODC0Qw2BXeg58PTGsAAADwbERH9ghu/qjFH7X4AwAAgLfWaMseAQB8skQ9ewQAv7JPkeucAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAai5YqQYl
</data>
</layer>
<objectgroup name="Object Layer 1" width="100" height="100" visible="0">
<object type="SquadStart" gid="4" x="352" y="352"/>
<object type="SquadStart" gid="4" x="416" y="352"/>
<object type="SquadStart" gid="4" x="352" y="384"/>
<object type="SquadStart" gid="4" x="384" y="384"/>
<object type="SquadStart" gid="4" x="384" y="352"/>
<object type="MonsterSpawn" gid="5" x="544" y="480"/>
<object type="MonsterSpawn" gid="5" x="768" y="608"/>
<object type="MonsterSpawn" gid="5" x="768" y="576"/>
<object type="MonsterSpawn" gid="5" x="672" y="288"/>
<object type="MonsterSpawn" gid="5" x="704" y="832"/>
<object type="MonsterSpawn" gid="5" x="864" y="832"/>
<object type="MonsterSpawn" gid="5" x="576" y="896"/>
<object type="MonsterSpawn" gid="5" x="448" y="576"/>
<object type="MonsterSpawn" gid="5" x="560" y="670"/>
</objectgroup>
<layer name="Collision" width="100" height="100">
<data encoding="base64" compression="zlib">
eJzt1rENAyEQAMF3X+6/LpdgeA5pgxnpUoJbCXgeAJj1/dwd9ujRokeLHi0ne9Rknh4tJ7vTY54eLe6rFj1advfpz3vX7R7s0aNlcpd6nLvdQ5M9E/fVv7NYp0eLHi0nPVbPZJ0eLXq06NFy+z1njx49erTo0aJHix49K+/6m+EdPVr06LFHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoO4HZimKNQ==
</data>
</layer>
</map>
@@ -1,224 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" width="100" height="100" tilewidth="32" tileheight="32">
<tileset firstgid="1" name="tilese Depths Below" tilewidth="32" tileheight="32">
<image source="tilesets/cave.png" trans="ff00ff" width="512" height="288"/>
</tileset>
<tileset firstgid="145" name="Collision" tilewidth="32" tileheight="32">
<image source="tilesets/collision.png" width="32" height="32"/>
</tileset>
<layer name="Tile Layer 1" width="100" height="100">
<data encoding="csv">
81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
81,52,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,54,54,54,54,54,54,54,54,54,53,53,53,55,81,
81,68,69,69,69,69,101,102,103,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,70,69,69,69,71,81,
81,84,85,85,85,129,117,118,119,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,86,85,85,85,87,81,
81,37,7,8,21,21,133,134,135,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,7,8,7,7,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,7,8,21,21,21,21,21,21,7,8,8,7,8,21,21,21,21,21,21,21,133,134,135,87,81,
81,37,7,8,21,21,21,21,21,21,21,21,21,18,18,18,18,18,18,18,18,2,2,2,18,5,8,8,89,7,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,2,2,2,2,18,18,19,20,4,4,4,4,4,4,2,7,8,8,8,8,8,8,8,8,8,7,7,8,8,24,7,8,3,4,4,20,4,18,18,133,134,135,87,81,
81,37,7,8,19,20,20,1,1,1,1,1,21,21,1,18,19,20,20,20,20,18,18,18,5,5,7,8,89,89,5,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,18,18,18,18,18,18,19,20,20,20,20,20,20,3,4,7,8,24,24,24,24,24,24,24,24,8,8,8,24,19,7,7,8,4,20,3,2,2,18,133,134,135,49,81,
81,37,7,8,7,8,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5,7,8,8,89,89,5,4,20,4,17,17,17,17,17,17,17,1,1,1,1,1,17,17,17,1,2,3,5,5,5,5,5,6,2,3,4,7,8,8,2,3,2,18,2,2,2,23,24,2,2,2,3,18,19,23,24,24,24,24,20,18,23,7,8,4,4,4,2,18,19,2,3,2,39,81,
81,37,7,8,23,24,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,17,17,5,7,8,24,89,89,21,3,4,20,4,4,4,4,5,6,22,17,17,17,17,17,17,18,1,2,3,4,5,5,5,21,5,5,2,7,7,8,8,24,2,2,18,19,18,18,18,18,18,2,2,2,2,2,18,19,20,3,4,20,20,20,19,7,8,4,2,2,2,18,19,2,2,18,39,81,
81,37,7,8,24,24,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5,7,8,8,89,89,89,7,7,7,7,7,7,7,7,7,6,6,6,1,2,3,4,5,6,5,7,7,7,21,21,5,7,7,7,7,7,8,7,7,7,7,8,5,20,2,3,4,2,2,18,18,18,18,2,18,19,20,3,4,20,20,18,19,7,7,8,18,18,18,18,19,2,18,19,39,81,
81,37,23,24,23,24,1,1,1,7,7,7,7,7,7,8,7,7,7,8,1,1,1,5,7,8,24,89,89,89,23,7,23,23,23,23,23,23,7,4,22,22,4,5,6,6,6,6,6,23,23,23,24,8,21,23,23,23,7,7,7,23,23,23,23,7,7,8,4,2,2,2,18,19,20,20,20,18,19,20,3,4,20,20,4,2,19,23,7,8,2,3,4,4,2,2,18,19,39,81,
81,37,7,7,7,7,7,7,7,23,23,7,7,7,7,7,23,23,7,8,1,1,1,21,7,8,8,89,89,89,89,7,7,7,7,7,7,7,7,20,4,22,6,6,6,22,22,22,22,23,23,23,7,24,24,24,24,24,23,23,23,23,23,23,24,23,7,7,8,4,18,18,19,20,4,20,3,2,3,4,4,20,4,20,2,2,3,19,7,8,2,3,4,4,2,18,19,2,39,81,
81,37,23,23,23,23,23,23,23,23,24,23,23,23,23,23,23,7,7,8,1,1,1,21,7,7,8,8,89,89,89,23,7,23,23,23,23,23,23,4,20,4,22,22,22,18,19,20,21,23,7,7,23,23,7,7,8,8,8,8,8,8,8,8,8,8,23,23,7,8,20,20,3,4,20,2,2,18,19,20,20,19,20,4,2,18,19,19,7,7,8,4,20,20,2,3,3,4,39,81,
81,37,8,8,3,1,1,1,1,1,1,1,1,1,1,1,1,23,23,24,1,1,1,19,7,8,8,24,89,89,89,23,23,23,23,23,23,23,23,20,4,20,4,6,18,19,5,5,5,23,23,7,6,22,23,23,24,24,8,24,24,24,24,24,24,8,8,8,23,24,8,8,8,9,2,18,18,19,20,4,19,20,4,4,2,3,4,19,23,7,7,8,20,2,3,3,3,4,39,81,
81,37,24,8,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,19,7,8,8,24,89,7,89,89,89,19,3,3,3,23,7,7,20,4,20,4,4,6,5,5,5,7,7,23,22,2,3,17,18,19,8,8,22,6,22,2,2,24,24,24,24,24,24,24,24,7,8,19,18,19,20,20,19,20,4,2,2,3,4,19,20,23,7,8,20,3,3,4,4,20,39,81,
81,37,8,8,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,7,7,8,89,89,89,7,19,19,19,19,19,19,19,7,7,7,7,7,7,20,4,4,5,22,23,23,23,2,1,1,17,18,19,8,8,22,22,2,3,2,2,18,18,19,20,19,20,20,7,8,8,8,2,3,18,19,20,4,2,3,4,20,19,20,3,7,8,3,19,3,4,20,20,39,81,
81,37,8,8,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,23,7,8,8,89,7,23,3,3,19,20,20,19,19,23,23,23,23,23,7,19,20,20,5,6,7,89,89,133,134,135,18,19,20,8,24,22,22,2,2,18,18,19,20,18,19,20,20,2,23,24,24,24,8,8,3,4,20,2,18,19,20,3,19,20,19,7,7,8,3,4,20,18,19,39,81,
81,37,8,8,3,1,1,1,7,8,8,8,8,8,1,1,1,1,1,1,1,1,1,4,23,7,7,8,89,23,23,19,19,19,19,20,20,2,3,4,5,6,7,7,19,5,5,5,5,23,89,89,133,134,135,19,20,21,8,24,6,20,2,2,2,18,19,20,19,20,20,2,18,2,3,23,24,24,24,3,4,2,18,19,20,3,4,19,20,4,23,7,8,4,20,3,4,2,39,81,
81,37,8,8,3,1,1,1,7,8,24,24,24,24,8,1,1,1,1,1,1,1,1,4,20,23,7,8,89,23,18,19,20,20,2,2,2,3,4,3,4,4,7,7,17,5,5,5,21,89,89,89,133,134,135,2,3,4,8,24,2,3,4,18,18,19,20,3,4,20,2,2,2,3,4,20,2,3,2,3,4,2,3,4,2,3,3,19,20,4,20,23,24,20,2,3,4,2,39,81,
81,37,24,8,3,1,4,4,5,7,7,8,8,24,24,8,20,20,19,20,4,3,19,20,2,23,7,7,8,23,18,18,19,20,4,18,18,19,20,19,20,20,7,7,4,4,5,5,2,89,89,89,6,6,5,2,3,4,24,24,2,3,2,18,8,8,8,3,4,18,2,3,18,19,20,20,3,2,3,4,2,3,4,3,3,19,19,19,20,4,20,3,4,2,3,4,20,2,39,81,
81,37,21,22,3,19,20,4,4,5,7,8,24,8,24,24,8,20,19,3,4,4,19,20,4,19,23,7,8,23,20,18,19,20,20,4,2,2,2,2,2,2,7,7,4,20,5,5,18,89,89,89,22,6,2,3,4,20,6,2,2,2,18,19,24,24,8,19,20,3,18,19,18,19,20,18,19,2,3,4,2,3,3,19,19,20,4,3,4,20,20,4,20,2,3,4,2,2,39,81,
81,37,21,22,19,4,4,5,4,4,5,8,24,24,8,24,24,8,20,19,20,20,4,19,20,7,8,8,8,23,20,4,18,19,20,7,7,18,18,18,2,3,7,23,20,18,19,20,17,89,89,89,7,5,2,3,4,20,6,2,18,18,19,8,8,8,24,20,4,2,3,2,2,3,4,18,2,3,4,2,3,3,19,19,20,4,20,19,20,20,4,20,19,2,3,22,2,2,39,81,
81,37,2,3,2,20,20,21,20,4,4,4,5,24,24,8,8,24,8,19,19,3,4,19,20,7,8,24,24,23,4,20,4,18,18,23,7,18,18,18,2,3,7,23,5,6,18,19,17,89,89,7,7,7,7,7,20,20,2,18,18,19,8,24,24,24,24,7,7,7,19,2,3,4,20,2,3,4,20,3,19,19,20,3,4,4,3,19,20,20,4,20,3,2,3,7,7,7,39,81,
81,37,2,3,18,20,21,21,5,5,5,5,5,7,8,24,24,8,24,8,8,19,20,4,7,8,8,89,89,23,20,4,20,4,18,7,7,7,20,2,3,4,23,23,21,22,6,18,19,89,89,23,23,23,23,7,7,7,7,7,7,7,24,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,53,54,53,53,54,54,54,54,7,7,7,7,23,7,7,39,81,
81,37,2,3,18,19,20,21,21,21,21,21,21,23,24,23,24,24,8,24,24,8,8,8,8,8,24,89,89,23,20,20,4,4,20,23,7,7,7,4,4,20,4,5,6,4,1,1,1,89,89,1,17,2,3,23,23,7,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,53,53,53,53,53,53,53,54,23,7,7,7,7,7,7,39,81,
81,37,2,2,3,20,89,7,7,7,7,89,89,89,89,89,23,24,24,23,24,24,24,24,24,24,89,89,89,23,18,19,20,20,4,19,23,7,7,20,4,4,1,1,1,1,17,17,17,89,89,17,2,3,4,20,20,23,23,23,23,20,6,2,3,2,18,19,20,2,18,19,20,18,2,3,2,2,3,4,7,7,20,20,4,20,19,20,20,3,4,7,8,23,23,23,23,23,39,81,
81,37,2,3,3,2,89,7,23,23,7,7,7,7,7,7,89,7,89,89,89,89,89,89,89,89,89,89,7,23,4,4,4,4,20,4,4,7,23,20,20,20,4,4,17,17,18,2,3,89,89,2,3,4,4,19,20,2,18,19,20,21,2,3,4,18,19,20,6,18,19,20,20,2,3,4,2,18,19,20,7,8,3,4,4,4,19,20,3,4,20,7,8,4,3,2,2,3,39,81,
81,37,2,3,3,3,89,7,21,21,5,5,5,5,2,2,2,5,4,3,4,4,89,89,89,7,7,7,7,23,20,20,20,20,4,20,4,23,23,18,19,20,20,20,4,2,3,4,4,89,89,2,3,4,20,5,6,2,18,19,20,6,2,3,2,3,4,20,2,18,19,20,2,3,4,2,18,19,20,20,7,7,8,20,4,4,19,20,3,4,3,23,24,4,4,2,2,3,39,81,
81,37,2,3,3,4,89,7,2,21,21,21,21,21,18,18,18,5,3,3,3,3,4,7,7,23,23,7,7,23,4,19,19,20,20,20,20,20,23,7,7,18,19,20,20,4,4,20,2,89,89,2,3,4,4,5,2,2,3,4,20,2,3,2,18,19,20,6,18,19,20,2,2,3,2,2,3,4,20,4,23,7,7,8,2,3,4,18,19,20,3,2,3,4,4,2,3,4,39,81,
81,37,2,3,19,4,89,7,2,3,4,5,6,6,17,3,3,5,3,19,19,3,3,7,7,7,7,7,7,23,20,4,20,4,4,18,19,20,2,23,7,7,7,19,20,4,2,3,2,89,89,4,4,20,5,6,2,2,3,4,21,2,7,8,8,20,5,2,2,3,4,2,3,2,2,3,4,20,3,4,7,23,7,8,3,4,20,2,3,4,2,3,4,20,4,2,3,4,39,81,
81,37,2,3,3,4,7,7,2,3,4,7,7,7,2,19,19,5,19,19,19,19,19,23,23,23,23,23,7,23,20,20,4,20,20,4,19,20,2,2,7,7,23,19,20,3,4,3,2,89,89,20,4,6,21,2,18,18,7,8,8,8,8,8,24,8,8,2,3,4,20,2,3,2,18,19,20,20,4,20,7,7,7,8,3,4,20,3,4,20,2,3,4,19,2,2,3,4,39,81,
81,37,2,2,3,4,7,7,3,4,5,23,23,7,2,2,3,21,3,4,3,3,3,3,4,3,19,19,7,23,19,20,20,19,20,20,3,3,4,18,21,7,7,19,20,4,4,2,3,89,89,20,4,22,2,2,7,8,8,8,7,8,8,8,24,24,24,8,3,4,2,3,2,18,19,20,4,19,20,20,23,7,7,7,8,4,2,3,4,3,2,3,4,4,2,2,3,4,39,81,
81,37,18,2,3,5,21,2,3,4,5,23,23,23,2,2,3,7,7,20,19,19,19,19,3,3,3,3,23,23,19,19,20,19,19,7,7,19,3,4,4,7,7,4,4,4,3,4,4,89,89,4,4,4,4,2,7,8,24,7,8,8,24,24,2,23,24,24,8,3,4,19,2,3,4,20,20,20,20,4,20,23,23,7,8,4,2,3,4,3,2,3,4,4,18,2,3,4,39,81,
81,37,2,2,3,5,1,2,3,2,2,2,18,18,2,18,19,7,7,18,19,20,19,20,19,19,19,19,19,19,3,19,20,19,19,23,7,4,4,20,20,7,7,7,20,20,19,20,20,7,89,20,20,20,20,18,23,24,7,8,8,24,2,18,18,2,23,24,24,8,8,8,2,3,4,20,20,20,19,20,4,2,2,7,7,8,2,3,4,3,2,3,4,20,18,2,3,4,39,81,
81,37,2,2,3,5,1,2,2,18,18,18,19,2,3,4,20,7,7,19,20,18,2,3,2,19,20,20,19,20,19,19,19,19,19,23,7,20,20,4,4,23,23,7,7,20,20,20,20,89,89,4,1,2,2,2,2,2,7,8,24,18,18,19,20,18,2,23,24,24,24,24,8,19,20,20,20,19,20,19,20,2,2,23,7,7,8,3,4,3,2,3,4,4,18,2,3,4,39,81,
81,37,1,2,3,4,2,2,18,19,20,2,3,4,19,20,19,7,7,2,3,4,18,2,3,19,3,3,3,19,20,20,20,20,20,7,7,19,20,20,4,7,7,7,7,7,4,20,20,89,89,4,17,2,3,2,2,18,7,8,20,3,4,22,1,2,3,4,20,2,23,24,24,20,18,19,20,20,18,19,20,2,2,3,23,7,7,7,8,2,3,4,20,20,2,3,4,4,39,81,
81,37,7,7,7,89,89,7,7,7,7,7,7,7,7,7,7,7,7,2,3,2,2,3,19,20,19,19,19,19,3,3,3,3,3,23,23,20,20,20,20,23,23,23,23,7,7,7,7,89,89,2,2,2,2,18,18,19,7,8,3,4,20,22,2,3,4,4,2,18,18,23,24,8,19,20,20,2,3,4,20,2,3,4,20,23,23,7,7,8,3,4,4,2,2,3,4,20,39,81,
81,37,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,89,89,89,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,23,23,23,23,89,89,5,5,5,5,5,20,22,7,8,3,4,22,22,2,3,4,20,18,18,19,23,24,24,8,20,20,2,3,4,4,4,2,3,4,2,3,23,7,7,8,4,20,2,2,3,4,4,39,81,
81,37,23,23,23,23,23,104,105,106,23,23,23,23,23,23,23,23,23,23,7,7,7,7,89,89,89,89,89,89,89,89,89,89,89,89,89,89,7,8,89,89,89,89,89,89,89,89,7,8,89,21,21,21,21,21,21,22,23,24,19,20,2,2,2,3,4,2,18,19,20,18,23,24,24,8,2,3,4,20,20,20,18,19,20,4,3,4,23,7,7,7,8,2,4,5,4,20,39,81,
81,37,7,8,3,3,4,120,121,122,2,2,2,2,2,2,18,3,4,4,4,20,19,20,18,18,19,3,19,19,19,20,19,7,7,7,7,7,7,7,7,8,7,8,7,7,8,7,7,7,8,17,18,19,20,20,21,22,2,3,2,3,4,2,2,3,4,2,3,4,20,19,20,23,24,24,8,8,20,2,2,3,4,18,2,3,4,20,2,23,23,7,7,8,4,5,4,20,39,81,
81,37,7,8,5,6,6,6,6,18,18,18,18,18,18,18,19,3,3,4,20,4,19,20,2,18,18,19,19,20,4,2,3,23,107,107,108,7,23,23,7,8,8,7,8,23,24,8,23,23,24,18,19,20,21,22,20,21,18,2,18,19,2,18,2,2,2,18,19,20,19,20,2,3,23,24,24,24,8,3,2,3,4,3,18,19,20,4,4,2,3,23,7,7,20,21,4,20,39,81,
81,37,8,8,23,24,7,22,2,2,2,3,4,17,17,2,2,19,3,3,4,20,19,20,4,4,19,20,18,2,3,2,3,4,123,107,108,23,23,23,23,24,24,8,7,8,24,24,8,7,8,22,17,18,19,20,21,22,2,18,19,2,3,4,23,7,7,7,22,22,20,2,3,4,2,18,23,24,24,8,2,3,4,3,4,18,19,20,2,3,4,20,23,7,20,21,4,20,39,81,
81,37,8,8,6,22,7,3,4,18,18,2,2,2,2,18,18,19,19,3,4,3,19,20,4,3,4,18,19,18,2,3,4,2,3,107,108,3,4,2,3,23,24,24,8,7,8,24,24,8,7,8,19,20,21,22,22,2,3,4,20,2,3,4,23,23,23,23,22,22,20,2,3,4,2,3,4,23,24,24,8,8,4,19,20,18,19,20,2,3,4,4,20,23,20,21,4,20,39,81,
81,38,8,8,22,17,7,2,2,2,2,18,18,18,18,19,20,4,2,19,3,3,4,19,20,19,20,4,4,20,2,2,3,4,19,107,108,2,2,18,19,20,23,24,24,8,7,8,24,24,7,8,19,20,21,22,2,18,19,20,18,2,3,4,23,23,24,23,22,22,20,2,3,2,3,4,20,3,23,24,24,24,8,8,20,18,19,20,3,4,20,4,2,3,20,21,3,4,39,81,
81,38,8,8,23,24,7,18,7,8,8,8,19,20,17,7,8,8,3,8,8,8,3,19,20,21,19,20,20,4,4,3,4,20,20,107,108,2,18,19,20,2,3,23,24,24,8,7,8,24,8,7,8,21,2,2,18,19,20,4,2,3,4,2,23,23,23,23,22,22,2,3,4,2,3,4,2,2,2,2,23,24,24,24,8,18,19,20,3,4,4,20,3,4,20,21,3,4,39,81,
81,38,8,8,4,1,7,17,23,2,2,23,4,6,2,23,1,2,3,23,5,5,3,19,20,5,1,1,19,20,20,4,4,19,20,107,108,18,19,20,20,2,3,4,7,8,24,8,7,8,24,8,8,8,3,4,19,20,3,4,2,3,4,18,23,23,23,23,22,22,2,3,2,3,4,20,18,7,8,8,8,20,23,24,24,8,8,8,8,8,20,2,3,4,20,21,4,4,39,81,
81,38,8,8,4,1,7,1,7,1,2,7,4,4,5,8,8,7,3,8,8,7,19,19,20,1,17,17,18,2,19,20,20,19,20,107,108,19,20,4,2,3,4,20,7,7,8,24,8,8,24,24,24,8,8,7,8,3,4,2,3,4,20,23,23,23,23,24,6,22,2,2,18,19,20,7,8,8,8,24,24,2,3,23,24,24,24,24,24,24,8,2,3,4,2,2,3,4,39,81,
81,38,8,7,89,89,23,1,23,8,8,8,20,1,2,3,4,23,3,4,2,23,4,20,17,17,18,19,2,3,4,19,20,4,2,107,108,20,4,20,2,3,4,3,8,7,8,23,24,24,8,24,8,24,7,7,8,8,4,2,3,4,23,23,23,23,23,24,22,2,3,18,19,20,7,8,8,24,24,4,4,3,4,2,3,4,2,3,23,24,24,8,4,20,2,2,3,4,39,81,
81,38,8,7,89,89,17,1,2,2,3,4,20,17,1,8,8,8,3,8,8,8,4,20,2,3,4,21,2,3,4,2,19,20,4,107,108,3,4,2,3,4,20,19,20,7,8,4,23,24,24,24,8,24,8,7,8,7,8,2,3,4,23,23,23,23,23,24,4,4,4,3,4,20,7,8,24,4,4,20,4,3,2,3,4,20,2,3,4,23,24,24,8,3,18,18,19,20,39,81,
81,38,8,7,89,89,2,3,4,2,3,4,4,1,17,17,17,2,3,4,2,3,4,20,2,3,4,2,3,4,20,2,3,19,20,107,108,2,2,18,19,20,2,2,18,19,20,20,4,2,3,23,24,8,24,7,7,8,7,8,3,23,23,23,23,23,23,24,20,20,20,4,4,7,8,8,4,4,20,20,4,2,18,19,20,2,2,3,4,20,23,24,24,8,8,8,20,4,39,81,
81,38,8,7,89,89,2,3,4,2,3,4,20,17,18,19,2,3,4,2,3,4,20,2,2,3,2,3,4,20,4,3,19,19,20,107,108,4,18,19,19,20,2,2,18,19,20,20,4,2,3,23,24,8,24,23,7,7,7,8,23,23,23,23,23,23,23,24,2,19,20,20,20,7,8,24,4,20,19,20,20,18,19,20,4,2,2,3,4,20,2,23,24,24,24,24,8,8,39,81,
81,38,8,7,89,89,2,3,4,2,3,4,3,4,1,17,2,3,4,2,3,4,20,2,3,2,2,3,4,2,3,19,19,20,107,108,108,4,20,3,19,19,20,2,2,18,19,20,2,3,4,23,24,24,8,8,23,23,7,7,8,7,7,7,7,23,24,18,2,3,4,20,19,7,7,8,4,2,2,3,4,19,20,4,20,2,3,4,20,2,3,4,20,3,23,24,24,24,39,81,
81,38,8,7,89,89,2,3,4,2,3,4,3,4,17,2,3,4,20,2,3,4,2,2,3,2,3,4,20,3,19,19,20,2,107,108,124,20,3,4,3,19,20,2,2,18,19,20,18,19,20,19,23,24,24,24,8,8,8,7,7,8,23,23,23,23,24,2,3,3,3,4,20,23,7,8,4,2,18,19,20,4,3,4,4,2,3,4,20,2,3,4,2,3,4,18,19,20,39,81,
81,38,8,7,89,89,3,4,20,2,3,4,4,20,20,2,3,4,20,2,3,4,2,2,3,2,3,3,3,19,20,19,2,3,107,108,20,2,3,4,3,19,20,2,2,18,19,20,19,20,1,2,1,23,24,24,24,24,24,8,8,7,8,7,8,4,18,2,3,19,3,4,20,3,7,7,8,4,19,20,19,20,3,2,2,3,4,4,4,2,3,4,2,3,4,18,19,20,39,81,
81,38,8,7,89,89,3,4,3,3,4,20,4,20,6,2,3,4,2,2,3,2,3,2,3,3,19,19,19,20,3,2,3,4,107,108,4,3,4,2,19,19,20,2,2,18,19,20,20,1,1,1,17,2,3,23,24,23,24,24,24,8,8,8,24,4,2,3,4,20,19,3,4,3,23,7,8,20,4,3,3,4,3,2,3,4,20,4,4,2,3,4,2,3,4,2,2,3,39,81,
81,38,8,7,89,4,3,2,19,19,3,3,3,3,3,3,3,3,3,3,3,3,3,3,19,19,20,4,2,3,4,4,19,107,108,108,20,19,20,18,19,19,20,2,2,18,19,20,4,4,4,4,18,2,3,4,23,24,24,23,24,24,24,24,24,3,4,4,20,2,3,19,3,3,4,7,7,8,20,4,19,20,4,2,3,4,4,20,2,3,4,20,2,3,4,3,2,3,39,81,
81,38,8,7,89,3,4,2,19,20,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20,3,2,3,4,4,20,20,107,108,124,3,4,20,2,2,19,20,2,2,18,19,20,4,4,4,20,17,18,19,20,18,19,23,24,24,24,24,23,24,8,3,4,2,2,3,4,19,3,4,23,7,7,8,4,4,19,20,3,4,20,4,7,8,3,4,4,2,3,4,3,18,2,39,81,
81,38,8,7,89,19,3,3,4,19,20,4,3,4,2,3,4,2,2,3,4,2,2,3,4,2,2,3,4,20,20,20,107,108,108,2,3,4,2,3,4,19,20,2,2,18,19,20,20,20,3,4,6,2,3,4,6,5,6,2,2,3,7,23,24,24,8,4,18,18,3,4,19,3,4,19,23,7,7,8,4,19,20,3,4,4,4,7,8,8,4,4,2,3,4,3,2,2,39,81,
81,38,8,7,89,2,19,3,3,19,20,20,19,20,2,3,4,2,2,3,2,2,3,4,20,2,3,4,4,3,4,20,107,108,124,3,4,2,2,3,4,19,20,2,2,18,19,20,4,18,19,20,4,4,4,20,22,2,3,4,2,2,23,7,23,24,24,3,4,4,3,4,19,3,3,3,4,23,23,24,4,19,20,3,4,4,20,23,24,24,20,4,2,3,4,3,2,2,39,81,
81,38,8,7,89,3,19,19,19,3,19,20,4,2,3,4,20,18,2,3,2,2,3,4,2,2,3,4,20,4,20,4,107,108,2,3,4,18,2,3,4,19,20,2,8,8,19,20,4,18,18,19,20,20,4,2,2,3,4,20,18,18,19,23,7,23,24,8,3,4,3,4,3,19,3,3,4,20,20,19,20,19,3,4,4,20,4,7,23,24,4,20,2,3,4,2,3,4,39,81,
81,38,8,7,89,3,3,4,19,3,3,19,20,4,3,4,4,18,2,2,3,4,2,2,2,3,4,4,4,20,2,107,108,108,3,2,3,4,2,3,4,3,19,20,8,8,18,19,20,3,4,3,18,19,20,4,18,19,20,2,18,19,20,2,23,23,24,24,8,3,4,4,19,20,3,4,20,3,3,19,20,20,19,20,4,20,4,7,23,24,4,4,2,3,4,2,3,4,39,81,
81,38,8,7,89,3,19,3,4,19,3,19,20,20,3,4,20,2,2,2,3,4,2,18,2,2,2,3,4,20,2,107,108,124,4,4,4,4,2,3,4,3,19,8,23,8,8,8,20,19,20,19,20,18,19,20,4,2,2,18,19,20,2,2,18,23,23,24,24,8,3,4,5,5,3,4,19,19,3,3,19,20,3,4,4,20,2,7,23,24,4,4,2,3,4,2,3,4,39,81,
81,38,8,7,89,3,2,3,3,4,19,3,19,20,4,4,2,3,2,2,3,4,18,18,18,18,2,3,4,4,18,107,108,2,2,2,2,3,4,4,4,19,19,23,23,7,8,8,8,8,8,2,3,18,19,20,20,18,18,19,20,2,18,18,19,20,23,23,24,24,8,3,21,5,4,20,4,20,19,19,19,20,19,20,20,3,2,23,23,24,4,4,2,3,4,2,3,4,39,81,
81,38,8,8,89,4,2,19,3,4,3,19,19,20,20,4,2,3,2,3,4,2,18,19,20,20,18,19,20,20,107,108,108,18,18,18,18,2,2,2,3,4,19,23,7,7,7,7,8,8,8,8,2,18,8,8,20,19,20,2,18,18,19,20,2,2,18,23,23,24,24,8,8,21,4,4,20,4,18,19,20,20,19,20,20,3,3,23,24,7,20,20,2,3,4,2,3,4,39,81,
81,38,8,8,89,2,3,4,19,3,3,4,19,20,4,4,4,4,2,3,2,18,2,18,18,2,2,18,19,107,108,108,124,3,4,20,4,18,18,18,2,19,20,23,7,18,7,7,7,8,8,8,8,18,8,8,8,8,8,18,19,20,2,18,18,18,19,20,23,23,24,24,24,24,8,3,3,3,4,3,3,3,3,3,3,3,7,23,24,7,20,4,2,3,4,2,3,4,39,81,
81,38,8,8,89,2,3,4,3,19,3,4,20,19,20,20,4,20,4,2,18,19,2,3,2,18,18,18,107,108,108,124,18,19,20,3,4,4,3,4,19,20,2,23,7,19,20,7,7,7,7,8,8,8,7,7,7,7,7,8,8,18,18,19,20,3,4,4,20,2,23,7,23,24,24,8,8,3,3,19,19,19,19,3,4,7,23,23,24,4,3,4,2,3,4,2,3,4,39,81,
81,38,8,8,89,2,3,3,4,20,19,3,4,19,20,19,20,4,20,4,19,2,3,4,2,3,4,107,108,108,124,3,4,3,3,3,4,20,19,19,20,2,2,23,7,20,20,3,8,7,7,7,7,7,8,8,8,7,7,7,7,3,3,3,3,3,3,3,3,3,3,23,7,8,7,7,7,7,8,4,3,4,4,19,7,23,23,24,19,20,3,4,2,3,2,3,4,4,39,81,
81,38,8,8,89,8,3,3,4,19,3,19,3,4,19,20,19,20,4,20,4,3,3,3,3,107,108,108,108,124,2,3,3,3,4,4,3,4,19,20,2,2,18,23,7,20,3,19,7,8,7,7,7,7,7,7,8,8,8,7,7,19,19,3,3,3,3,3,3,3,19,19,7,8,23,23,23,7,7,7,7,7,7,7,23,23,24,20,3,4,3,4,2,3,2,2,3,4,39,81,
81,38,8,8,89,8,19,3,3,4,19,3,3,3,4,19,20,19,20,4,20,4,107,108,108,108,108,124,124,20,4,4,5,5,5,5,5,5,19,20,2,2,8,23,7,3,19,3,7,7,8,7,7,7,8,8,7,8,8,7,7,8,5,3,4,3,4,19,19,19,20,4,8,8,8,20,20,23,23,23,23,23,23,23,23,24,4,18,19,20,19,20,2,3,2,2,3,4,39,81,
81,38,8,8,89,89,19,19,19,3,3,19,19,19,3,4,20,5,5,5,5,5,107,108,124,124,124,5,5,5,5,5,5,5,5,5,5,5,3,3,3,8,23,23,7,19,3,5,7,7,7,7,7,7,8,7,8,8,8,7,7,7,19,19,20,19,3,3,4,3,4,4,7,7,8,20,3,4,4,2,18,19,20,4,2,3,4,3,4,20,2,3,2,3,18,2,3,4,39,81,
81,38,8,8,89,89,3,4,19,19,19,19,19,3,19,3,3,3,19,20,20,19,123,124,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3,8,8,23,23,7,19,3,5,5,7,7,7,7,7,7,7,7,8,7,8,8,7,7,8,3,19,19,19,19,20,19,20,20,23,7,8,4,4,4,2,2,18,19,20,20,3,4,20,3,4,2,18,19,2,3,4,2,3,4,39,81,
81,38,8,8,89,89,3,4,19,3,3,3,19,19,3,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,19,23,23,23,7,4,3,19,20,19,20,20,7,8,8,7,7,7,7,8,8,8,7,7,7,19,20,20,19,19,19,19,19,19,23,7,8,20,20,20,2,3,18,19,20,4,3,4,3,4,20,2,2,3,2,3,4,2,3,4,39,81,
81,38,8,8,89,89,3,4,3,19,19,19,19,19,19,19,19,20,19,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,7,8,8,8,4,4,4,4,4,3,4,2,2,7,8,7,7,8,7,8,7,8,8,7,7,20,20,4,20,20,3,4,20,2,23,7,8,3,4,2,2,3,2,3,4,20,4,20,3,4,4,2,2,3,2,3,4,2,7,8,39,81,
81,38,8,8,89,89,3,4,3,4,5,2,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,20,5,5,5,7,8,8,8,20,20,20,20,20,20,4,4,4,18,19,7,7,7,7,8,7,8,8,7,7,7,19,20,20,2,2,3,4,18,18,23,7,8,3,4,2,3,4,18,19,20,3,4,18,19,20,4,2,18,19,2,3,4,7,7,8,39,81,
81,38,8,8,7,89,3,4,3,4,5,2,3,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,7,8,8,8,8,20,20,3,4,18,19,20,20,20,20,4,18,18,18,7,7,7,7,7,7,7,7,19,20,19,20,4,3,4,20,19,20,4,7,7,8,4,2,3,2,3,4,20,3,4,2,3,4,4,2,2,3,7,8,8,23,23,24,39,81,
81,38,8,8,7,89,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,23,23,23,7,8,8,8,8,5,5,18,19,20,20,20,18,20,19,20,20,19,20,20,20,7,7,2,18,18,18,19,20,2,18,19,20,4,20,4,4,2,2,23,7,8,4,4,3,18,19,20,7,7,8,8,8,8,8,8,8,8,8,24,24,24,24,4,39,81,
81,38,8,8,8,89,5,5,5,5,5,5,5,5,5,5,2,2,2,2,3,2,5,5,5,5,5,23,23,23,23,8,8,8,23,8,8,19,20,20,20,20,20,20,19,20,20,19,20,20,3,4,4,2,2,18,18,18,19,20,18,18,18,18,19,19,20,20,4,20,20,3,4,23,7,8,20,20,4,3,4,4,23,23,24,24,24,24,24,24,24,24,24,3,4,2,3,4,39,81,
81,38,8,8,8,89,5,5,5,5,2,2,5,5,19,20,2,18,18,2,3,2,3,4,2,23,7,8,8,8,8,8,23,7,8,8,19,20,20,20,20,20,20,20,20,20,19,20,20,3,2,2,2,18,18,19,20,18,18,19,20,3,4,20,19,20,19,20,20,19,20,19,20,23,7,7,8,19,20,19,20,20,20,4,2,3,4,20,4,18,2,3,2,3,4,2,3,4,39,81,
81,38,8,8,8,89,5,5,3,4,2,3,4,2,3,4,2,18,19,2,3,2,3,4,23,23,7,8,23,19,19,20,2,18,18,19,20,2,20,20,20,19,20,20,20,19,20,20,3,19,18,18,18,19,20,19,20,2,2,2,3,4,4,20,20,20,20,4,3,2,3,4,19,23,23,7,8,2,18,18,19,20,20,4,2,3,4,3,4,3,18,19,2,3,4,2,3,4,39,81,
81,38,8,8,8,89,3,4,19,20,2,3,2,3,4,20,2,2,3,2,3,2,3,23,8,8,23,18,18,18,18,18,18,19,20,2,20,20,19,20,20,20,20,19,20,19,20,8,8,8,8,20,18,19,20,18,18,18,2,3,4,20,20,2,2,2,2,2,2,2,2,2,2,18,23,7,7,8,19,20,4,4,3,4,18,19,20,3,4,3,2,3,2,3,4,2,3,4,39,81,
81,38,8,8,8,89,89,4,19,20,2,3,2,3,4,18,2,18,2,3,4,8,7,89,8,23,2,3,2,19,19,20,20,19,20,20,19,20,20,20,20,20,19,20,20,19,8,8,8,8,8,8,8,8,8,8,8,8,8,4,20,18,2,2,2,2,2,2,18,18,18,18,8,8,23,23,7,8,2,2,2,2,3,4,2,3,4,3,4,3,2,3,2,3,4,2,3,4,39,81,
81,38,8,8,8,89,89,4,19,20,2,3,2,3,4,2,2,18,2,3,8,7,89,89,23,4,2,2,18,4,4,20,20,20,19,20,20,20,20,20,20,19,20,20,20,2,8,8,8,8,8,7,7,7,7,7,7,7,7,8,8,8,8,18,18,18,18,18,19,8,8,8,8,7,23,24,7,7,8,18,2,3,4,4,2,3,4,2,3,4,2,3,2,3,4,2,3,4,39,81,
81,38,8,8,8,89,89,3,4,20,2,3,18,19,20,2,18,18,8,7,89,89,89,89,23,20,2,18,19,20,20,20,19,20,20,20,20,20,20,18,20,20,20,8,8,8,8,8,7,7,7,3,4,18,19,20,20,23,7,7,7,7,7,8,8,8,8,8,8,8,7,7,7,2,3,23,23,7,8,4,4,4,4,20,2,3,4,2,3,4,2,3,2,3,4,2,3,4,39,81,
81,38,8,8,8,8,89,89,4,2,2,2,3,4,20,2,3,8,7,89,89,89,89,89,23,2,18,19,20,20,20,19,20,20,3,20,20,18,18,20,8,8,8,7,8,7,7,7,3,4,3,4,20,20,18,18,18,19,20,3,4,23,7,7,7,7,7,7,7,7,4,4,4,4,19,23,24,7,7,8,20,20,20,4,2,3,4,2,3,4,18,19,2,3,4,2,3,4,39,81,
81,38,8,8,8,8,89,89,4,2,2,2,3,4,8,7,89,89,89,89,89,89,89,23,4,2,2,3,2,20,19,20,20,20,20,20,18,18,8,8,7,7,7,7,7,7,7,20,19,20,19,20,19,20,20,18,19,20,18,19,20,20,18,19,20,2,3,4,4,19,20,20,20,20,2,2,23,23,7,8,20,4,4,4,2,3,4,2,3,4,18,19,2,3,4,2,3,4,39,81,
81,38,8,8,8,8,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,2,3,4,20,2,3,4,4,20,2,20,20,20,8,8,8,7,7,7,7,7,8,8,20,20,18,18,19,20,20,19,20,18,18,18,18,18,18,18,18,18,18,18,18,2,3,4,4,18,18,18,19,20,18,2,3,4,7,7,7,7,8,7,7,7,7,7,7,7,7,7,8,3,2,2,3,4,39,81,
81,38,8,8,89,8,8,89,89,89,89,89,89,89,89,89,89,89,89,89,2,2,3,4,20,2,3,4,4,20,2,8,8,8,8,8,7,7,7,7,8,8,7,7,18,18,19,20,2,18,18,18,18,19,20,20,19,20,19,20,18,19,20,20,18,2,3,4,19,20,3,4,2,2,18,18,19,20,23,23,23,7,8,23,23,7,23,23,23,23,23,7,8,3,18,2,3,4,39,81,
81,38,8,8,89,8,8,89,89,89,89,89,89,89,89,89,89,2,3,2,3,2,3,4,4,2,3,4,4,20,2,7,7,7,8,8,7,8,7,7,7,7,7,2,2,2,2,2,2,18,18,18,2,3,4,20,18,19,20,19,20,2,2,2,2,2,3,4,18,2,3,4,2,3,18,18,19,20,3,4,7,8,8,23,24,23,23,24,7,7,8,23,24,3,2,2,3,4,39,81,
81,38,8,8,8,89,8,2,2,2,2,18,19,20,2,18,19,2,3,2,3,2,3,4,20,2,3,4,4,20,2,7,7,7,8,8,7,7,4,4,20,2,2,2,2,2,18,18,18,2,3,4,4,19,20,2,2,2,2,2,2,2,2,2,2,3,4,4,2,2,3,4,18,19,2,18,19,20,19,7,8,8,24,2,3,4,19,2,8,8,8,20,2,3,2,2,3,4,39,81,
81,38,8,8,8,89,8,2,2,2,2,3,4,20,18,19,20,2,3,18,19,2,3,4,4,18,19,4,4,20,2,2,2,2,7,7,7,4,4,4,4,18,2,2,18,18,19,2,2,18,19,20,20,20,4,2,2,2,8,8,2,2,2,2,2,2,3,4,3,2,3,4,18,2,3,4,20,2,3,7,8,24,3,2,3,4,3,18,18,18,19,20,2,2,18,2,3,4,39,81,
81,38,8,8,8,89,8,2,2,2,18,19,20,20,18,19,20,2,2,18,19,2,3,4,2,2,3,18,4,4,18,18,18,18,2,2,2,2,4,4,18,18,18,18,19,2,2,18,18,19,20,2,3,4,20,18,18,18,8,8,8,18,18,18,2,3,4,4,2,3,4,20,19,2,3,4,18,2,7,8,24,2,2,18,19,20,3,4,4,3,2,3,2,18,19,2,3,4,39,81,
81,38,8,8,89,7,8,18,2,18,18,19,20,19,19,19,19,19,19,19,19,19,3,4,2,2,2,3,2,2,4,4,4,18,18,18,18,18,4,18,2,2,3,4,3,4,18,19,20,18,2,3,4,20,2,2,2,2,7,7,7,2,2,2,3,4,4,4,2,3,4,18,19,2,3,4,18,7,23,24,4,2,18,19,20,2,3,4,20,19,18,19,18,18,19,2,3,4,39,81,
81,38,8,8,89,7,89,19,18,19,20,20,20,20,20,19,20,20,20,20,20,20,2,3,4,2,18,19,18,18,18,19,20,19,20,20,2,2,3,4,18,18,19,20,19,20,20,18,18,2,3,4,20,2,2,2,2,8,7,7,7,2,2,3,4,4,4,4,2,3,4,18,19,2,3,4,2,7,8,20,4,4,5,5,5,18,19,20,20,2,3,4,20,19,20,2,3,4,39,81,
81,38,8,8,89,89,89,2,2,3,4,20,20,19,19,20,20,20,19,19,18,19,2,2,2,18,18,19,20,20,20,18,18,2,2,3,4,18,19,20,19,20,18,19,20,18,18,2,2,3,7,8,8,8,8,3,4,7,7,7,2,3,4,4,4,4,19,20,2,3,4,2,2,4,5,4,18,19,2,4,5,5,5,21,21,18,19,20,5,18,19,20,18,20,18,2,3,4,39,81,
81,38,8,8,89,89,89,2,89,89,4,20,20,20,20,19,19,19,19,20,18,18,18,7,8,8,8,8,8,8,8,2,2,18,18,19,20,20,2,2,2,2,3,4,7,8,8,8,8,8,8,8,8,8,8,8,8,7,7,3,4,4,4,4,4,19,20,2,2,3,4,2,2,20,21,4,18,19,2,5,5,21,21,20,3,2,3,4,21,18,19,7,7,7,7,7,8,4,39,81,
81,38,8,8,89,89,8,8,8,8,8,7,7,7,7,20,20,20,20,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,20,2,2,3,7,8,8,8,8,8,8,8,8,8,8,8,8,8,3,8,8,8,8,8,8,8,8,8,8,7,8,8,2,18,2,3,4,2,2,4,5,4,2,2,4,5,5,5,19,20,2,18,19,20,7,8,7,23,23,23,23,7,7,8,39,81,
81,38,8,8,8,8,7,7,7,7,7,7,8,8,8,8,7,8,8,8,8,8,8,8,8,4,4,4,4,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,4,4,20,20,20,18,19,20,20,19,8,8,8,8,8,8,8,8,8,8,2,2,2,3,2,2,3,4,4,4,5,5,5,5,21,21,4,4,4,4,20,3,8,8,7,7,8,8,8,8,8,8,39,81,
81,84,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,20,20,20,20,20,20,20,20,20,20,20,8,8,8,8,8,8,8,8,20,20,20,20,20,20,20,20,18,18,18,19,20,18,18,18,18,2,3,4,2,8,8,8,8,18,18,18,2,3,18,18,19,20,20,20,21,21,21,21,20,20,20,20,20,20,4,3,8,8,23,23,24,24,24,24,24,24,39,81,
81,66,34,34,35,35,34,34,34,34,34,34,34,8,8,8,8,8,34,34,34,34,34,34,34,34,34,35,34,34,34,34,34,34,34,34,34,35,34,34,34,34,34,34,34,34,34,34,34,34,34,35,34,34,34,34,34,34,34,34,34,35,34,34,34,34,34,34,34,35,34,34,34,34,34,34,34,34,34,35,34,34,34,34,34,34,35,34,34,34,34,34,34,34,35,34,34,35,67,81,
81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81
</data>
</layer>
<layer name="Collision" width="100" height="100" visible="0">
<data encoding="csv">
0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,145,145,145,145,145,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,145,145,145,145,145,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,
0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,0,0,0,0,0,0,0,0,0,0,145,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,0,0,0,145,145,0,145,145,145,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,145,145,145,145,145,0,0,145,145,145,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,145,145,145,145,145,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,0,0,0,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,145,0,145,145,145,0,145,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,145,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,145,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,145,0,
0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,145,0,145,0,0,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,145,0,
0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,145,0,145,0,0,0,0,0,0,145,145,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,145,0,
0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,0,0,0,0,0,0,0,145,145,145,145,145,145,0,0,0,0,0,145,0,145,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,145,0,
0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,0,0,0,0,0,0,0,145,145,145,145,145,145,0,0,0,0,0,145,0,145,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,145,0,
0,145,145,145,0,0,0,0,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,145,0,145,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,145,0,
0,145,145,145,0,0,0,0,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,145,0,145,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,145,0,
0,145,145,145,0,0,0,0,0,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,145,0,145,0,0,0,0,0,0,145,145,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,145,0,145,0,0,0,0,0,0,0,0,0,0,0,0,145,0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,145,145,0,0,0,0,0,145,145,0,0,0,0,0,145,0,145,145,0,0,0,0,0,0,0,0,0,0,145,145,0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,145,145,0,0,0,0,0,145,145,0,0,0,0,0,145,0,0,145,145,145,145,0,0,0,0,0,0,145,145,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,
0,145,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,0,0,0,145,145,145,145,145,145,0,0,0,0,0,145,145,145,0,0,0,0,145,145,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,145,145,145,145,145,0,145,145,0,
0,145,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,145,145,145,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,145,145,0,0,0,0,145,145,0,
0,145,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,0,
0,145,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,145,0,
0,145,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,145,0,
0,145,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,0,0,0,0,145,145,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,145,145,145,145,145,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,0,0,0,0,145,145,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,145,145,0,0,0,0,0,145,145,145,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,145,145,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,145,145,0,0,0,0,145,145,0,0,0,0,0,0,145,145,0,0,0,0,0,145,0,0,0,0,145,145,145,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,145,145,145,0,0,0,0,0,145,145,0,0,0,0,0,145,145,145,0,145,145,0,0,0,0,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,145,145,145,145,0,0,0,0,145,145,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,145,145,145,145,145,0,0,0,145,145,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,145,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,145,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,145,0,
0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,145,0,
0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,145,0,
0,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,145,0,
0,145,145,145,0,0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,145,145,145,145,145,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,145,0,0,145,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,145,0,0,0,0,145,0,
0,145,145,145,0,0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,145,145,145,145,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,145,0,0,145,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,0,145,145,145,145,0,0,0,145,145,145,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,145,145,145,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,145,0,0,145,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,0,0,145,0,145,0,0,145,0,0,0,145,0,0,0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,145,0,0,145,0,0,0,0,0,0,0,0,0,145,145,145,145,0,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,0,0,145,0,145,0,0,145,0,0,0,145,145,145,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,145,145,0,0,145,0,0,0,0,0,0,0,145,145,145,145,145,145,0,0,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,0,145,145,145,145,0,0,0,0,0,145,0,0,0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,145,145,0,0,0,0,145,145,0,0,0,145,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,145,145,145,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,145,145,0,145,145,145,145,0,0,0,0,0,145,145,0,0,0,145,0,0,0,0,145,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,0,0,0,0,0,145,145,0,145,145,0,0,0,0,145,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,0,0,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,0,0,0,0,0,0,145,145,145,0,0,0,0,145,145,0,0,0,0,0,145,0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,0,0,0,0,0,145,0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,145,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,145,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,145,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,145,145,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,145,145,0,145,145,145,145,145,145,145,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,145,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,145,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,145,145,145,145,145,145,145,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,145,0,0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,0,0,0,0,0,145,145,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,145,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,145,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,145,145,145,145,145,145,145,0,145,145,145,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,0,0,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,0,0,0,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,0,145,0,
0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,145,145,145,145,145,0,0,0,0,0,0,145,145,145,145,0,0,0,0,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,0,0,0,0,145,145,145,0,
0,145,145,145,145,145,145,145,145,145,145,145,0,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,0,0,0,0,0,0,0,0,0,145,0,
0,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
</data>
</layer>
<objectgroup name="Object Layer 1" width="100" height="100">
<object name="Spawn1" type="SquadStart" gid="143" x="320" y="256"/>
<object name="Spawn2" type="SquadStart" gid="143" x="288" y="192"/>
<object name="Spawn4" type="SquadStart" gid="143" x="224" y="160"/>
<object name="Spawn3" type="SquadStart" gid="143" x="256" y="288"/>
<object name="Spawn5" type="SquadStart" gid="143" x="224" y="224"/>
</objectgroup>
</map>
+76
View File
@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" width="256" height="256" tilewidth="32" tileheight="32">
<tileset firstgid="1" name="Aztek Temple" tilewidth="32" tileheight="32">
<image source="tilesets/aztek.png" width="480" height="693"/>
</tileset>
<tileset firstgid="316" name="collision" tilewidth="32" tileheight="32">
<image source="tilesets/collision.png" width="32" height="32"/>
</tileset>
<layer name="Floor" width="256" height="256">
<data encoding="base64" compression="zlib">
eJzt2jFqA0EQRUGB7n9n40CgzEh4ebv7q6DDCV8HzTweAAAAAAAAAAAAAAAAAAAbnm8DnMvzJgN8ru5W/9Cpu9U/dOpu9Q+dulv9Q6fuVv/QqbvVP3TqbvUPnbpb/UOn7lb/0Km71T906m71D526W/1Dp+5W/9Cpu9U/dOpu9Q+dulv9Q6fuVv/QqbvVP3TqbvUPnbpb/UOn7lb/0Km71T906m71D526W/1Dp+5W/9Cpu9U/dOpu9Q+dulv9Q6fuVv/QqbvVP9yTPmGX/mGX/mGX/uF4Z7236R+Op3/YpX/YdYX+v3kP/E3/sEv/sOsK/QPH0D/s0j/cR9Gz/uEc6rarfQH0reofOp+2o2e4D/3DLv3DLv3DLv3DLv3DLv3DLv3DDu3BLv3DLv0DL3qHXfqHXfqHXfqHXfqH6/PXBnbpH3bpH3bpH3bpH7b8V/P6h+vRP/BL/7BL/7BL/7BL/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUfgD7Ih3C
</data>
</layer>
<layer name="Interior" width="256" height="256">
<data encoding="base64" compression="zlib">
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
</data>
</layer>
<layer name="Interior 2" width="256" height="256">
<data encoding="base64" compression="zlib">
eJzt08ENADAIAzFmhP13KVOAKmwp/3wuAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgJ9lr7ZPACv0D3fpH+7SPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACTHpGaApU=
</data>
</layer>
<objectgroup name="Object Layer 1" width="256" height="256">
<object type="SquadStart" x="704" y="2624" width="32" height="32"/>
<object type="SquadStart" x="736" y="2656" width="32" height="32"/>
<object type="SquadStart" x="704" y="2720" width="32" height="32"/>
<object type="SquadStart" x="800" y="2656" width="32" height="32"/>
<object type="SquadStart" x="768" y="2720" width="32" height="32"/>
<object type="BossSpawn" x="832" y="2720" width="32" height="32"/>
<object type="Door" x="640" y="2656" width="32" height="64"/>
<object type="MonsterSpawn" x="992" y="2304" width="32" height="32"/>
<object type="EnemySpawn" x="1184" y="2144" width="32" height="32"/>
<object type="EnemySpawn" x="992" y="2688" width="32" height="32"/>
<object type="EnemySpawn" x="1088" y="2560" width="32" height="32"/>
<object type="EnemySpawn" x="1120" y="1888" width="32" height="32"/>
<object type="EnemySpawn" x="1632" y="1664" width="32" height="32"/>
<object type="EnemySpawn" x="1600" y="2112" width="32" height="32"/>
<object type="EnemySpawn" x="1760" y="1824" width="32" height="32"/>
<object type="EnemySpawn" x="1824" y="1920" width="32" height="32"/>
<object type="EnemySpawn" x="1984" y="1696" width="32" height="32"/>
<object type="EnemySpawn" x="1984" y="2048" width="32" height="32"/>
<object type="EnemySpawn" x="1824" y="2208" width="32" height="32"/>
<object type="EnemySpawn" x="2080" y="1792" width="32" height="32"/>
<object type="EnemySpawn" x="2272" y="1664" width="32" height="32"/>
<object type="EnemySpawn" x="2336" y="1728" width="32" height="32"/>
<object type="EnemySpawn" x="2272" y="2112" width="32" height="32"/>
<object type="EnemySpawn" x="2304" y="2016" width="32" height="32"/>
<object type="EnemySpawn" x="2720" y="1888" width="32" height="32"/>
<object type="EnemySpawn" x="2720" y="1824" width="32" height="32"/>
<object type="EnemySpawn" x="2752" y="1856" width="32" height="32"/>
<object type="EnemySpawn" x="2112" y="800" width="32" height="32"/>
<object type="EnemySpawn" x="2112" y="960" width="32" height="32"/>
<object type="EnemySpawn" x="2112" y="1120" width="32" height="32"/>
<object type="EnemySpawn" x="2112" y="1280" width="32" height="32"/>
<object type="EnemySpawn" x="3424" y="1280" width="32" height="32"/>
<object type="EnemySpawn" x="3424" y="1120" width="32" height="32"/>
<object type="EnemySpawn" x="3424" y="960" width="32" height="32"/>
<object type="EnemySpawn" x="3424" y="800" width="32" height="32"/>
<object type="EnemySpawn" x="3424" y="640" width="32" height="32"/>
<object type="EnemySpawn" x="2112" y="640" width="32" height="32"/>
<object type="DelayedEnemySpawn" x="704" y="2624" width="32" height="32"/>
<object type="DelayedEnemySpawn" x="736" y="2656" width="32" height="32"/>
<object type="DelayedEnemySpawn" x="704" y="2720" width="32" height="32"/>
<object type="DelayedEnemySpawn" x="800" y="2656" width="32" height="32"/>
<object type="DelayedEnemySpawn" x="768" y="2720" width="32" height="32"/>
<object type="DelayedEnemySpawn" x="832" y="2720" width="32" height="32"/>
</objectgroup>
<layer name="Collision" width="256" height="256">
<data encoding="base64" compression="zlib">
eJzt20FuwjAURVG6r+5/XRWjDkqRE75j5/1zpEwYID+JKyUIHg8AAAAAAAAAAAAAgH18f/W6gF+re9Q/rLO6R/3DOqsb1D+sk9xI8jaokNxI8jaokNxI8jaokNxI8jaokNxI8jaoMNrIrv2MnFn/8Jr+oa/kRpK3QYXkRpK3QYXkRpK3QYWK5//ZbX16Lv3Da/qHvpIbSd4GFZIbSd4GFZIbSd4GFWY+/x9t7sz7eP6H8/QPfSU3krwNKiQ3krwNKiQ3krwNKnj+h770D30lN5K8DSokN5K8DSokN5K8DSp4/oe+9A99JTeSvA0qJDeSvA0qJDeSvA0qJDeSvA2eXn3Gd75Wnx2SrO5Z/7DO6p71D+us7ln/sM5On/MZ/QP/26kb/cO1dupG/3CtI53NfO3dWUZ71j8co3/IMtLRjvfN+ofPdel/1x2wkv71T1/61z993bUD/cPnunTQZScc0aWLLjvhiJEudrxvvuv3FrAT/UNf1f1f8drImfQPf53pQv+QYXb/V9nlHHAn+oe+9A996R/6quim4ru3GRfwnv6hL/1DX2c6Wt21/mFcdUeru9Y/jLuif2BP+oe+9A99VTeqf7gP/UNf+odeZjaqf9ib/qGvmV3qH/amf+jL/T/0pX/gSf/Ql/6hr09//3/mPwLAHvQPfekf+tI/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAu/sBxwzVAA==
</data>
</layer>
</map>
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" width="256" height="256" tilewidth="32" tileheight="32">
<tileset firstgid="1" name="Aztek Temple" tilewidth="32" tileheight="32">
<image source="tilesets/aztek.png" width="480" height="693"/>
</tileset>
<tileset firstgid="316" name="collision" tilewidth="32" tileheight="32">
<image source="tilesets/collision.png" width="32" height="32"/>
</tileset>
<layer name="Floor" width="256" height="256">
<data encoding="base64" compression="zlib">
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
</data>
</layer>
<layer name="Interior" width="256" height="256">
<data encoding="base64" compression="zlib">
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
</data>
</layer>
<layer name="Interior 2" width="256" height="256">
<data encoding="base64" compression="zlib">
eJzt1LENg0AMQNHrYBcoWIUNMgELHZCMGhdUJxGlOEGie0/6lSXLlVMCAAAAAAAAAAAAAAAAAAAAAAAAAPgvSxHQliEa7z4CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALtRX2JGjNdqiPXpGrwp7gd/QfZjl5AcAAAAAAAAAAAAAAAAAAAAAAAAAAMCZ6Qhoy1wEtONRBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMB33mp4DUA=
</data>
</layer>
<objectgroup name="Object Layer 1" width="256" height="256">
<object type="SquadStart" x="2688" y="2336" width="32" height="32"/>
<object type="SquadStart" x="2720" y="2368" width="32" height="32"/>
<object type="SquadStart" x="2688" y="2432" width="32" height="32"/>
<object type="SquadStart" x="2752" y="2432" width="32" height="32"/>
<object type="EnemySpawn" x="2560" y="1856" width="32" height="32"/>
<object type="EnemySpawn" x="2816" y="1568" width="32" height="32"/>
<object type="EnemySpawn" x="2944" y="2016" width="32" height="32"/>
<object type="DelayedEnemySpawn" x="2816" y="2304" width="32" height="32"/>
<object type="BossSpawn" x="2752" y="800" width="32" height="32"/>
<object type="Door" x="2720" y="1728" width="64" height="32"/>
<object type="Door" x="2720" y="1504" width="64" height="32"/>
<object type="EnemySpawn" x="2656" y="1600" width="32" height="32"/>
<object type="SquadStart" x="2784" y="2368" width="32" height="32"/>
</objectgroup>
<layer name="Collision" width="256" height="256" visible="0">
<data encoding="base64" compression="zlib">
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
</data>
</layer>
</map>
@@ -1,223 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" width="100" height="100" tilewidth="32" tileheight="32">
<tileset firstgid="1" name="Aztek" tilewidth="32" tileheight="32">
<image source="tilesets/aztek.jpg" width="160" height="160"/>
</tileset>
<tileset firstgid="26" name="Collision" tilewidth="32" tileheight="32">
<image source="tilesets/collision.png" width="32" height="32"/>
</tileset>
<tileset firstgid="27" name="Aztek Transparent" tilewidth="32" tileheight="32">
<image source="tilesets/aztek_transparent.png" width="160" height="160"/>
</tileset>
<tileset firstgid="52" name="Aztek 2" tilewidth="32" tileheight="32">
<image source="tilesets/aztek2.png" width="320" height="320"/>
</tileset>
<layer name="Tile Layer 1" width="100" height="100">
<data encoding="csv">
52,53,54,54,54,54,54,54,56,0,0,52,54,54,54,54,54,54,55,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
62,63,64,64,64,64,64,65,76,0,0,72,63,64,64,64,64,64,65,66,52,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,55,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72,73,74,74,74,74,74,75,76,0,0,72,73,74,74,74,74,74,75,76,62,63,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,65,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72,73,74,74,74,74,74,75,76,0,0,72,73,74,74,74,74,74,75,76,72,73,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,75,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72,73,74,74,74,74,74,75,76,0,0,72,73,74,74,74,74,74,75,76,72,73,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,75,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72,73,74,74,74,74,74,75,124,54,54,125,73,74,74,74,74,74,75,76,72,73,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,75,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72,73,74,74,74,74,74,133,64,64,64,64,136,74,74,74,74,74,75,76,72,73,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,75,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72,73,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,75,76,72,73,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,75,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72,73,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,75,76,72,73,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,75,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72,73,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,75,76,72,73,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,75,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
82,83,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,85,86,82,83,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,85,86,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
92,93,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,95,96,92,93,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,95,96,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
52,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,55,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
62,63,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,65,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72,73,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,75,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72,73,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,75,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72,73,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,75,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72,73,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,75,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72,73,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,75,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72,73,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,75,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72,73,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,75,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
82,83,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,85,86,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
92,93,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,95,96,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
</data>
</layer>
<layer name="Collision" width="100" height="100">
<data encoding="csv">
26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,26,26,26,26,0,0,0,0,0,0,0,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,26,26,26,26,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,26,26,26,26,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,26,26,26,26,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,26,26,26,26,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
</data>
</layer>
</map>
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

+81
View File
@@ -0,0 +1,81 @@
luanet.load_assembly("Microsoft.Xna.Framework")
Color = luanet.import_type("Microsoft.Xna.Framework.Color")
local frame = CreateFrame('Frame');
frame.X = 100;
local button = CreateFrame('Button', frame);
button:SetTexture('images/Enter');
button.Width = 100;
button.Height = 50;
button.OnClick = function(clickPos)
Console.WriteLine(clickPos.X .. ' ' .. clickPos.Y)
end
function CreatePanicFrame(x, y)
local frame = CreateFrame("Frame")
frame:SetTexture("images/GUI/unit_background")
frame.Width = 154
frame.Height = 19
frame.X = x
frame.Y = y
local healthBg = CreateFrame("Frame", frame)
healthBg:SetTexture("images/GUI/health_background")
healthBg.Width = 136
healthBg.Height = 13
healthBg.X = 3
healthBg.Y = 3
local healthBar = CreateFrame("Frame", healthBg)
healthBar:SetTexture("images/GUI/bar_solid")
healthBar.Color = Color(87, 55, 253)
healthBar.Width = healthBg.Width * 0.5
healthBar.Height = 11
healthBar.X = 1
healthBar.Y = 1
return frame
end
function CreateUnitFrame(name, x, y)
-- Frames for one unit
local frame = CreateFrame("Frame")
frame:SetTexture("images/GUI/unit_background")
frame.Width = 164;
frame.Height = 35;
frame.X = x
frame.Y = y
local nameText = CreateFrame("Text", frame)
nameText:SetFont("fonts/UnitName")
nameText.Value = name
nameText.X = 4
nameText.Y = 1
local healthBg = CreateFrame("Frame", frame)
healthBg:SetTexture("images/GUI/health_background")
healthBg.Width = 136
healthBg.Height = 13
healthBg.X = 3
healthBg.Y = 19
local healthBar = CreateFrame("Frame", healthBg)
healthBar:SetTexture("images/GUI/bar_solid")
healthBar.Color = Color.Red
healthBar.Width = healthBg.Width * 0.5
healthBar.Height = 11
healthBar.X = 1
healthBar.Y = 1
return frame
end
--[[local frame;
frame = CreatePanicFrame(0, 0)
frame = CreateUnitFrame("Flight captain Rainbow Dash", frame.X, frame.Y + frame.Height)
CreateUnitFrame("Mr. Sparkle", frame.X, frame.Y + frame.Height)]]--
local testFrame = CreateTestFrame()
testFrame:SetWidth(1337)
+1
View File
@@ -0,0 +1 @@
Console.WriteLine("Test.lua loaded");
+5
View File
@@ -0,0 +1,5 @@
ToolTip = CreateFrame("Frame")
local text = CreateFrame("Text", ToolTip)
text:SetFont("Arial")
text.Value = "99%"
+31
View File
@@ -0,0 +1,31 @@
texture LightsTexture;
sampler ColorSampler : register(s0);
sampler LightsSampler = sampler_state{
Texture = <LightsTexture>;
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
};
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
float2 tex = input.TexCoord;
float4 color = tex2D(ColorSampler, tex);
float4 alpha = tex2D(LightsSampler, tex);
return color * alpha;
}
technique Technique1
{
pass Pass1
{
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}
@@ -27,6 +27,7 @@
<Private>False</Private>
<SpecificVersion>True</SpecificVersion>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Game, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL" />
<Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
<Private>False</Private>
<SpecificVersion>True</SpecificVersion>
@@ -49,6 +50,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="LuaImporter.cs" />
<Compile Include="MapProcessor.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
+31
View File
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
// TODO: replace this with the type you want to import.
using TImport = System.String;
namespace DepthsBelowContentPipeline
{
/// <summary>
/// This class will be instantiated by the XNA Framework Content Pipeline
/// to import a file from disk into the specified type, TImport.
///
/// This should be part of a Content Pipeline Extension Library project.
///
/// TODO: change the ContentImporter attribute to specify the correct file
/// extension, display name, and default processor for this importer.
/// </summary>
[ContentImporter(".lua", DisplayName = "LUA Importer", DefaultProcessor = "LuaProcessor")]
public class LuaImporter : ContentImporter<TImport>
{
public override TImport Import(string filename, ContentImporterContext context)
{
return System.IO.File.ReadAllText(filename);
}
}
}
-38
View File
@@ -1,38 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Krypton", "Krypton\Krypton.csproj", "{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KryptonTestbed", "KryptonTestbed\KryptonTestbed\KryptonTestbed.csproj", "{E9787BEE-7290-4C74-B919-79DC70AABE87}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KryptonTestbedContent", "KryptonTestbed\KryptonTestbedContent\KryptonTestbedContent.contentproj", "{EA878F1A-4714-4377-8E6A-4947ACFF386A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}.Debug|Any CPU.ActiveCfg = Debug|x86
{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}.Debug|x86.ActiveCfg = Debug|x86
{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}.Debug|x86.Build.0 = Debug|x86
{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}.Release|Any CPU.ActiveCfg = Release|x86
{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}.Release|x86.ActiveCfg = Release|x86
{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}.Release|x86.Build.0 = Release|x86
{E9787BEE-7290-4C74-B919-79DC70AABE87}.Debug|Any CPU.ActiveCfg = Debug|x86
{E9787BEE-7290-4C74-B919-79DC70AABE87}.Debug|x86.ActiveCfg = Debug|x86
{E9787BEE-7290-4C74-B919-79DC70AABE87}.Debug|x86.Build.0 = Debug|x86
{E9787BEE-7290-4C74-B919-79DC70AABE87}.Release|Any CPU.ActiveCfg = Release|x86
{E9787BEE-7290-4C74-B919-79DC70AABE87}.Release|x86.ActiveCfg = Release|x86
{E9787BEE-7290-4C74-B919-79DC70AABE87}.Release|x86.Build.0 = Release|x86
{EA878F1A-4714-4377-8E6A-4947ACFF386A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EA878F1A-4714-4377-8E6A-4947ACFF386A}.Debug|x86.ActiveCfg = Debug|Any CPU
{EA878F1A-4714-4377-8E6A-4947ACFF386A}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{EA878F1A-4714-4377-8E6A-4947ACFF386A}.Release|x86.ActiveCfg = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
-278
View File
@@ -1,278 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using System.Globalization;
using System.Runtime.InteropServices;
namespace Krypton.Common
{
/// <summary>
/// Much like Rectangle, but stored as two Vector2s
/// </summary>
public struct BoundingRect
{
public Vector2 Min;
public Vector2 Max;
public float Left { get { return this.Min.X; } }
public float Right { get { return this.Max.X; } }
public float Top { get { return this.Max.Y; } }
public float Bottom { get { return this.Min.Y; } }
public float Width { get { return this.Max.X - this.Min.X; } }
public float Height { get { return this.Max.Y - this.Min.Y; } }
private static BoundingRect mEmpty;
private static BoundingRect mMinMax;
static BoundingRect()
{
BoundingRect.mEmpty = new BoundingRect();
BoundingRect.mMinMax = new BoundingRect(Vector2.One * float.MinValue, Vector2.One * float.MaxValue);
}
public Vector2 Center
{
get { return (this.Min + this.Max) / 2; }
}
public static BoundingRect Empty
{
get { return BoundingRect.mEmpty; }
}
public static BoundingRect MinMax
{
get { return BoundingRect.mMinMax; }
}
public bool IsZero
{
get
{
return
(this.Min.X == 0) &&
(this.Min.Y == 0) &&
(this.Max.X == 0) &&
(this.Max.Y == 0);
}
}
public BoundingRect(float x, float y, float width, float height)
{
this.Min.X = x;
this.Min.Y = y;
this.Max.X = x + width;
this.Max.Y = y + height;
}
public BoundingRect(Vector2 min, Vector2 max)
{
this.Min = min;
this.Max = max;
}
public bool Contains(float x, float y)
{
return
(this.Min.X <= x) &&
(this.Min.Y <= y) &&
(this.Max.X >= x) &&
(this.Max.Y >= y);
}
public bool Contains(Vector2 vector)
{
return
(this.Min.X <= vector.X) &&
(this.Min.Y <= vector.Y) &&
(this.Max.X >= vector.X) &&
(this.Max.Y >= vector.Y);
}
public void Contains(ref Vector2 rect, out bool result)
{
result =
(this.Min.X <= rect.X) &&
(this.Min.Y <= rect.Y) &&
(this.Max.X >= rect.X) &&
(this.Max.Y >= rect.Y);
}
public bool Contains(BoundingRect rect)
{
return
(this.Min.X <= rect.Min.X) &&
(this.Min.Y <= rect.Min.Y) &&
(this.Max.X >= rect.Max.X) &&
(this.Max.Y >= rect.Max.Y);
}
public void Contains(ref BoundingRect rect, out bool result)
{
result =
(this.Min.X <= rect.Min.X) &&
(this.Min.Y <= rect.Min.Y) &&
(this.Max.X >= rect.Max.X) &&
(this.Max.Y >= rect.Max.Y) ;
}
public bool Intersects(BoundingRect rect)
{
return
(this.Min.X < rect.Max.X) &&
(this.Min.Y < rect.Max.Y) &&
(this.Max.X > rect.Min.X) &&
(this.Max.Y > rect.Min.Y);
}
public void Intersects(ref BoundingRect rect, out bool result)
{
result =
(this.Min.X < rect.Max.X) &&
(this.Min.Y < rect.Max.Y) &&
(this.Max.X > rect.Min.X) &&
(this.Max.Y > rect.Min.Y);
}
public static BoundingRect Intersect(BoundingRect rect1, BoundingRect rect2)
{
BoundingRect result;
float num8 = rect1.Max.X;
float num7 = rect2.Max.X;
float num6 = rect1.Max.Y;
float num5 = rect2.Max.Y;
float num2 = (rect1.Min.X > rect2.Min.X) ? rect1.Min.X : rect2.Min.X;
float num = (rect1.Min.Y > rect2.Min.Y) ? rect1.Min.Y : rect2.Min.Y;
float num4 = (num8 < num7) ? num8 : num7;
float num3 = (num6 < num5) ? num6 : num5;
if ((num4 > num2) && (num3 > num))
{
result.Min.X = num2;
result.Min.Y = num;
result.Max.X = num4;
result.Max.Y = num3;
return result;
}
result.Min.X = 0;
result.Min.Y = 0;
result.Max.X = 0;
result.Max.Y = 0;
return result;
}
public static void Intersect(ref BoundingRect rect1, ref BoundingRect rect2, out BoundingRect result)
{
float num8 = rect1.Max.X;
float num7 = rect2.Max.X;
float num6 = rect1.Max.Y;
float num5 = rect2.Max.Y;
float num2 = (rect1.Min.X > rect2.Min.X) ? rect1.Min.X : rect2.Min.X;
float num = (rect1.Min.Y > rect2.Min.Y) ? rect1.Min.Y : rect2.Min.Y;
float num4 = (num8 < num7) ? num8 : num7;
float num3 = (num6 < num5) ? num6 : num5;
if ((num4 > num2) && (num3 > num))
{
result.Min.X = num2;
result.Min.Y = num;
result.Max.X = num4;
result.Max.Y = num3;
}
result.Min.X = 0;
result.Min.Y = 0;
result.Max.X = 0;
result.Max.Y = 0;
}
public static BoundingRect Union(BoundingRect rect1, BoundingRect rect2)
{
BoundingRect result;
float num6 = rect1.Max.X;
float num5 = rect2.Max.X;
float num4 = rect1.Max.Y;
float num3 = rect2.Max.Y;
float num2 = (rect1.Min.X < rect2.Min.X) ? rect1.Min.X : rect2.Min.X;
float num = (rect1.Min.Y < rect2.Min.Y) ? rect1.Min.Y : rect2.Min.Y;
float num8 = (num6 > num5) ? num6 : num5;
float num7 = (num4 > num3) ? num4 : num3;
result.Min.X = num2;
result.Min.Y = num;
result.Max.X = num8;
result.Max.Y = num7;
return result;
}
public static void Union(ref BoundingRect rect1, ref BoundingRect rect2, out BoundingRect result)
{
float num6 = rect1.Max.X;
float num5 = rect2.Max.X;
float num4 = rect1.Max.Y;
float num3 = rect2.Max.Y;
float num2 = (rect1.Min.X < rect2.Min.X) ? rect1.Min.X : rect2.Min.X;
float num = (rect1.Min.Y < rect2.Min.Y) ? rect1.Min.Y : rect2.Min.Y;
float num8 = (num6 > num5) ? num6 : num5;
float num7 = (num4 > num3) ? num4 : num3;
result.Min.X = num2;
result.Min.Y = num;
result.Max.X = num8;
result.Max.Y = num7;
}
public bool Equals(BoundingRect other)
{
return
(this.Min.X == other.Min.X) &&
(this.Min.Y == other.Min.Y) &&
(this.Max.X == other.Max.X) &&
(this.Max.Y == other.Max.Y);
}
public override int GetHashCode()
{
return this.Min.GetHashCode() + this.Max.GetHashCode();
}
public static bool operator ==(BoundingRect a, BoundingRect b)
{
return
(a.Min.X == b.Min.X) &&
(a.Min.Y == b.Min.Y) &&
(a.Max.X == b.Max.X) &&
(a.Max.Y == b.Max.Y);
}
public static bool operator !=(BoundingRect a, BoundingRect b)
{
return
(a.Min.X != b.Min.X) ||
(a.Min.Y != b.Min.Y) ||
(a.Max.X != b.Max.X) ||
(a.Max.Y != b.Max.Y);
}
public override bool Equals(object obj)
{
if (obj is BoundingRect)
{
return this == (BoundingRect)obj;
}
return false;
}
}
}
-98
View File
@@ -1,98 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3}</ProjectGuid>
<ProjectTypeGuids>{6D335F3A-9D43-41b4-9D22-F6F17C4BE596};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Krypton</RootNamespace>
<AssemblyName>Krypton</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<XnaFrameworkVersion>v4.0</XnaFrameworkVersion>
<XnaPlatform>Windows</XnaPlatform>
<XnaProfile>HiDef</XnaProfile>
<XnaCrossPlatformGroupID>f22a3b67-7b26-4bcf-9fa4-831713f618f0</XnaCrossPlatformGroupID>
<XnaOutputType>Library</XnaOutputType>
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\x86\Debug</OutputPath>
<DefineConstants>DEBUG;TRACE;WINDOWS</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>x86</PlatformTarget>
<XnaCompressContent>false</XnaCompressContent>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\x86\Release</OutputPath>
<DefineConstants>TRACE;WINDOWS</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>x86</PlatformTarget>
<XnaCompressContent>true</XnaCompressContent>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Xna.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
<Reference Include="Microsoft.Xna.Framework.Game, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
<Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
<Reference Include="mscorlib">
<Private>False</Private>
</Reference>
<Reference Include="System">
<Private>False</Private>
</Reference>
<Reference Include="System.Xml">
<Private>False</Private>
</Reference>
<Reference Include="System.Core">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
<Private>False</Private>
</Reference>
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Common\BoundingRect.cs" />
<Compile Include="KryptonEngine.cs" />
<Compile Include="Lights\ILight2D.cs" />
<Compile Include="LightTextureBuilder.cs" />
<Compile Include="Lights\Light2D.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="KryptonRenderHelper.cs" />
<Compile Include="ShadowHull.cs" />
<Compile Include="ShadowHullPoint.cs" />
<Compile Include="ShadowHullVertex.cs" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\Microsoft.Xna.GameStudio.targets" />
<!--
To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
-423
View File
@@ -1,423 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Krypton.Lights;
using Krypton.Common;
namespace Krypton
{
public enum LightMapSize
{
Full = 1,
Fourth = 2,
Eighth = 4,
}
/// <summary>
/// A GPU-based 2D lighting engine
/// </summary>
public class KryptonEngine : DrawableGameComponent
{
// The Krypton Effect
private string mEffectAssetName;
private Effect mEffect;
private CullMode mCullMode = CullMode.CullCounterClockwiseFace;
// The goods
private List<ShadowHull> mHulls = new List<ShadowHull>();
private List<ILight2D> mLights = new List<ILight2D>();
// World View Projection matrix, and it's min and max view bounds
private Matrix mWVP = Matrix.Identity;
private bool mSpriteBatchCompatabilityEnabled = false;
private BoundingRect mBounds = BoundingRect.MinMax;
// Blur
private float mBluriness = 0.25f;
private RenderTarget2D mMapBlur;
// Light maps
private RenderTarget2D mMap;
private Color mAmbientColor = new Color(35,35,35);
private LightMapSize mLightMapSize = LightMapSize.Full;
/// <summary>
/// Krypton's render helper. It helps render. It also needs to be re-written.
/// </summary>
public KryptonRenderHelper RenderHelper { get; private set; }
/// <summary>
/// Gets or sets a value indicating how Krypton should cull geometry. The default value is CullMode.CounterClockwise
/// </summary>
public CullMode CullMode
{
get { return this.mCullMode; }
set { this.mCullMode = value; }
}
/// <summary>
/// The collection of lights krypton uses to render shadows
/// </summary>
public List<ILight2D> Lights { get { return this.mLights; } }
/// <summary>
/// The collection of hulls krypton uses to render shadows
/// </summary>
public List<ShadowHull> Hulls { get { return this.mHulls; } }
/// <summary>
/// Gets or sets the matrix used to draw the light map. This should match your scene's matrix.
/// </summary>
public Matrix Matrix
{
get { return this.mWVP; }
set
{
if (this.mWVP != value)
{
this.mWVP = value;
// This is totally ghetto, but it works for now. :)
// Compute the world-space bounds of the given matrix
var inverse = Matrix.Invert(value);
var v1 = Vector2.Transform(new Vector2(1, 1), inverse);
var v2 = Vector2.Transform(new Vector2(1, -1), inverse);
var v3 = Vector2.Transform(new Vector2(-1, -1), inverse);
var v4 = Vector2.Transform(new Vector2(-1, 1), inverse);
this.mBounds.Min = v1;
this.mBounds.Min = Vector2.Min(this.mBounds.Min, v2);
this.mBounds.Min = Vector2.Min(this.mBounds.Min, v3);
this.mBounds.Min = Vector2.Min(this.mBounds.Min, v4);
this.mBounds.Max = v1;
this.mBounds.Max = Vector2.Max(this.mBounds.Max, v2);
this.mBounds.Max = Vector2.Max(this.mBounds.Max, v3);
this.mBounds.Max = Vector2.Max(this.mBounds.Max, v4);
this.mBounds = BoundingRect.MinMax;
}
}
}
/// <summary>
/// Gets or sets a value indicating weither or not to use SpriteBatch's matrix when drawing lightmaps
/// </summary>
public bool SpriteBatchCompatablityEnabled
{
get { return this.mSpriteBatchCompatabilityEnabled; }
set { this.mSpriteBatchCompatabilityEnabled = value; }
}
/// <summary>
/// Ambient color of the light map. Lights + AmbientColor = Final
/// </summary>
public Color AmbientColor
{
get { return this.mAmbientColor; }
set { this.mAmbientColor = value; }
}
/// <summary>
/// Gets or sets the value used to determine light map size
/// </summary>
public LightMapSize LightMapSize
{
get { return this.mLightMapSize; }
set
{
if (this.mLightMapSize != value)
{
this.mLightMapSize = value;
this.DisposeRenderTargets();
this.CreateRenderTargets();
}
}
}
/// <summary>
/// Gets or sets a value indicating how much to blur the final light map. If the value is zero, the lightmap will not be blurred
/// </summary>
public float Bluriness
{
get { return this.mBluriness; }
set { this.mBluriness = Math.Max(0, value); }
}
/// <summary>
/// Constructs a new instance of krypton
/// </summary>
/// <param name="game">Your game object</param>
/// <param name="effectAssetName">The asset name of Krypton's effect file, which must be included in your content project</param>
public KryptonEngine(Game game, string effectAssetName)
: base(game)
{
this.mEffectAssetName = effectAssetName;
}
/// <summary>
/// Initializes Krpyton, and hooks itself to the graphics device
/// </summary>
public override void Initialize()
{
base.Initialize();
this.GraphicsDevice.DeviceReset += new EventHandler<EventArgs>(GraphicsDevice_DeviceReset);
}
/// <summary>
/// Resets kryptons graphics device resources
/// </summary>
private void GraphicsDevice_DeviceReset(object sender, EventArgs e)
{
this.DisposeRenderTargets();
this.CreateRenderTargets();
}
/// <summary>
/// Load's the graphics related content required to draw light maps
/// </summary>
protected override void LoadContent()
{
// This needs to better handle content loading...
// if the window is resized, Krypton needs to notice.
this.mEffect = this.Game.Content.Load<Effect>(this.mEffectAssetName);
this.RenderHelper = new KryptonRenderHelper(this.GraphicsDevice, this.mEffect);
this.CreateRenderTargets();
}
/// <summary>
/// Unload's the graphics content required to draw light maps
/// </summary>
protected override void UnloadContent()
{
this.DisposeRenderTargets();
}
/// <summary>
/// Creates render targets
/// </summary>
private void CreateRenderTargets()
{
var targetWidth = GraphicsDevice.Viewport.Width / (int)(this.mLightMapSize);
var targetHeight = GraphicsDevice.Viewport.Height / (int)(this.mLightMapSize);
this.mMap = new RenderTarget2D(GraphicsDevice, targetWidth, targetHeight, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8, 0, RenderTargetUsage.PlatformContents);
this.mMapBlur = new RenderTarget2D(GraphicsDevice, targetWidth, targetHeight, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8, 0, RenderTargetUsage.PlatformContents);
}
/// <summary>
/// Disposes of render targets
/// </summary>
private void DisposeRenderTargets()
{
KryptonEngine.TryDispose(this.mMap);
KryptonEngine.TryDispose(this.mMapBlur);
}
/// <summary>
/// Attempts to dispose of disposable objects, and assigns them a null value afterward
/// </summary>
/// <param name="obj"></param>
private static void TryDispose(IDisposable obj)
{
if (obj != null)
{
obj.Dispose();
obj = null;
}
}
/// <summary>
/// Draws the light map to the current render target
/// </summary>
/// <param name="gameTime">N/A - Required</param>
public override void Draw(GameTime gameTime)
{
this.LightMapPresent();
}
/// <summary>
/// Prepares the light map to be drawn (pre-render)
/// </summary>
public void LightMapPrepare()
{
// Prepare and set the matrix
var viewWidth = this.GraphicsDevice.ScissorRectangle.Width;
var viewHeight = this.GraphicsDevice.ScissorRectangle.Height;
// Prepare the matrix with optional settings and assign it to an effect parameter
Matrix lightMapMatrix = this.LightmapMatrixGet();
this.mEffect.Parameters["Matrix"].SetValue(lightMapMatrix);
// Obtain the original rendering states
var originalRenderTargets = this.GraphicsDevice.GetRenderTargets();
// Set and clear the target
this.GraphicsDevice.SetRenderTarget(this.mMap);
this.GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.Stencil, this.mAmbientColor, 0, 1);
// Make sure we're culling the right way!
this.GraphicsDevice.RasterizerState = KryptonEngine.RasterizerStateGetFromCullMode(this.mCullMode);
// put the render target's size into a more friendly format
var targetSize = new Vector2(this.mMap.Width, this.mMap.Height);
// Render Light Maps
foreach (var light in this.mLights)
{
// Loop through each light within the view frustum
if (light.Bounds.Intersects(this.mBounds))
{
// Clear the stencil and set the scissor rect (because we're stretching geometry past the light's reach)
this.GraphicsDevice.Clear(ClearOptions.Stencil, Color.Black, 0, 1);
this.GraphicsDevice.ScissorRectangle = KryptonEngine.ScissorRectCreateForLight(light, lightMapMatrix, targetSize);
// Draw the light!
light.Draw(this.RenderHelper, this.mHulls);
}
}
if (this.mBluriness > 0)
{
// Blur the shadow map horizontally to the blur target
this.GraphicsDevice.SetRenderTarget(this.mMapBlur);
this.RenderHelper.BlurTextureToTarget(this.mMap, LightMapSize.Full, BlurTechnique.Horizontal, this.mBluriness);
// Blur the shadow map vertically back to the final map
this.GraphicsDevice.SetRenderTarget(this.mMap);
this.RenderHelper.BlurTextureToTarget(this.mMapBlur, LightMapSize.Full, BlurTechnique.Vertical, this.mBluriness);
}
// Reset to the original rendering states
this.GraphicsDevice.SetRenderTargets(originalRenderTargets);
}
/// <summary>
/// Returns the final, modified matrix used to render the lightmap.
/// </summary>
/// <returns></returns>
private Matrix LightmapMatrixGet()
{
if (this.mSpriteBatchCompatabilityEnabled)
{
float xScale = (this.GraphicsDevice.Viewport.Width > 0) ? (1f / this.GraphicsDevice.Viewport.Width) : 0f;
float yScale = (this.GraphicsDevice.Viewport.Height > 0) ? (-1f / this.GraphicsDevice.Viewport.Height) : 0f;
// This is the default matrix used to render sprites via spritebatch
var matrixSpriteBatch = new Matrix()
{
M11 = xScale * 2f,
M22 = yScale * 2f,
M33 = 1f,
M44 = 1f,
M41 = -1f - xScale,
M42 = 1f - yScale,
};
// Return krypton's matrix, compensated for use with SpriteBatch
return this.mWVP * matrixSpriteBatch;
}
else
{
// Return krypton's matrix
return this.mWVP;
}
}
/// <summary>
/// Gets a pixel-space rectangle which contains the light passed in
/// </summary>
/// <param name="light">The light used to create the rectangle</param>
/// <param name="matrix">the WorldViewProjection matrix being used to render</param>
/// <param name="targetSize">The rendertarget's size</param>
/// <returns></returns>
private static Rectangle ScissorRectCreateForLight(ILight2D light, Microsoft.Xna.Framework.Matrix matrix, Vector2 targetSize)
{
// This needs refining, but it works as is (I believe)
var lightBounds = light.Bounds;
var min = KryptonEngine.VectorToPixel(lightBounds.Min, matrix, targetSize);
var max = KryptonEngine.VectorToPixel(lightBounds.Max, matrix, targetSize);
var min2 = Vector2.Min(min, max);
var max2 = Vector2.Max(min, max);
min = Vector2.Clamp(min2, Vector2.Zero, targetSize);
max = Vector2.Clamp(max2, Vector2.Zero, targetSize);
return new Rectangle((int)(min.X), (int)(min.Y), (int)(max.X - min.X), (int)(max.Y - min.Y));
}
/// <summary>
/// Takes a screen-space vector and puts it in to pixel space
/// </summary>
/// <param name="v"></param>
/// <param name="matrix"></param>
/// <param name="targetSize"></param>
/// <returns></returns>
private static Vector2 VectorToPixel(Vector2 v, Matrix matrix, Vector2 targetSize)
{
Vector2.Transform(ref v, ref matrix, out v);
v.X = (1 + v.X) * (targetSize.X / 2f);
v.Y = (1 - v.Y) * (targetSize.Y / 2f);
return v;
}
/// <summary>
/// Takes a screen-space size vector and converts it to a pixel-space size vector
/// </summary>
/// <param name="v"></param>
/// <param name="matrix"></param>
/// <param name="targetSize"></param>
/// <returns></returns>
private static Vector2 ScaleToPixel(Vector2 v, Matrix matrix, Vector2 targetSize)
{
v.X *= matrix.M11 * (targetSize.X / 2f);
v.Y *= matrix.M22 * (targetSize.Y / 2f);
return v;
}
/// <summary>
/// Retrieves a rasterize state by using the cull mode as a lookup
/// </summary>
/// <param name="cullMode">The cullmode used to lookup the rasterize state</param>
/// <returns></returns>
private static RasterizerState RasterizerStateGetFromCullMode(CullMode cullMode)
{
switch (cullMode)
{
case (CullMode.CullCounterClockwiseFace):
return RasterizerState.CullCounterClockwise;
case (CullMode.CullClockwiseFace):
return RasterizerState.CullClockwise;
default:
return RasterizerState.CullNone;
}
}
/// <summary>
/// Presents the light map to the current render target
/// </summary>
private void LightMapPresent()
{
RenderHelper.DrawTextureToTarget(this.mMap, this.mLightMapSize, BlendTechnique.Multiply);
}
}
}
-476
View File
@@ -1,476 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Krypton.Lights;
namespace Krypton
{
public enum BlendTechnique
{
Add = 1,
Multiply = 2,
};
public enum BlurTechnique
{
Horizontal = 1,
Vertical = 2,
};
public class KryptonRenderHelper
{
#region Static Unit Quad
private static VertexPositionTexture[] UnitQuad = new VertexPositionTexture[]
{
new VertexPositionTexture()
{
Position = new Vector3(-1, 1, 0),
TextureCoordinate = new Vector2(0, 0),
},
new VertexPositionTexture()
{
Position = new Vector3(1, 1, 0),
TextureCoordinate = new Vector2(1, 0),
},
new VertexPositionTexture()
{
Position = new Vector3(-1, -1, 0),
TextureCoordinate = new Vector2(0, 1),
},
new VertexPositionTexture()
{
Position = new Vector3(1, -1, 0),
TextureCoordinate = new Vector2(1, 1),
},
};
#endregion Static Unit Quad
private GraphicsDevice mGraphicsDevice;
private Effect mEffect;
private List<ShadowHullVertex> mShadowHullVertices = new List<ShadowHullVertex>();
private List<Int32> mShadowHullIndicies = new List<Int32>();
public GraphicsDevice GraphicsDevice
{
get { return this.mGraphicsDevice; }
}
public Effect Effect
{
get { return this.mEffect; }
}
public List<ShadowHullVertex> ShadowHullVertices
{
get { return this.mShadowHullVertices; }
}
public List<Int32> ShadowHullIndicies
{
get { return this.mShadowHullIndicies; }
}
public KryptonRenderHelper(GraphicsDevice graphicsDevice, Effect effect)
{
this.mGraphicsDevice = graphicsDevice;
this.mEffect = effect;
}
public void BufferAddShadowHull(ShadowHull hull)
{
// Why do we need all of these again? (hint: we don't)
Matrix vertexMatrix = Matrix.Identity;
Matrix normalMatrix = Matrix.Identity;
float cos, sin;
ShadowHullPoint point;
ShadowHullVertex hullVertex;
// Create the matrices (3X speed boost versus prior version)
cos = (float)Math.Cos(hull.Angle);
sin = (float)Math.Sin(hull.Angle);
// vertexMatrix = scale * rotation * translation;
vertexMatrix.M11 = hull.Scale.X * cos;
vertexMatrix.M12 = hull.Scale.X * sin;
vertexMatrix.M21 = hull.Scale.Y * -sin;
vertexMatrix.M22 = hull.Scale.Y * cos;
vertexMatrix.M41 = hull.Position.X;
vertexMatrix.M42 = hull.Position.Y;
// normalMatrix = scaleInv * rotation;
normalMatrix.M11 = (1f / hull.Scale.X) * cos;
normalMatrix.M12 = (1f / hull.Scale.X) * sin;
normalMatrix.M21 = (1f / hull.Scale.Y) * -sin;
normalMatrix.M22 = (1f / hull.Scale.Y) * cos;
// Where are we in the buffer?
var vertexCount = this.mShadowHullVertices.Count;
// Add the vertices to the buffer
for (int i = 0; i < hull.NumPoints; i++)
{
// Transform the vertices to screen coordinates
point = hull.Points[i];
Vector2.Transform(ref point.Position, ref vertexMatrix, out hullVertex.Position);
Vector2.TransformNormal(ref point.Normal, ref normalMatrix, out hullVertex.Normal);
hullVertex.Color = Color.Black;
this.mShadowHullVertices.Add(hullVertex); // could this be sped up... ?
}
//// Add the indicies to the buffer
foreach (int index in hull.Indicies)
{
mShadowHullIndicies.Add(vertexCount + index); // what about this? Add range?
}
}
public void DrawSquareQuad(Vector2 position, float rotation, float size, Color color)
{
size /= 2;
size = (float)Math.Sqrt(Math.Pow(size, 2) + Math.Pow(size, 2));
rotation += (float)Math.PI / 4;
var cos = (float)Math.Cos(rotation) * size;
var sin = (float)Math.Sin(rotation) * size;
var v1 = new Vector3(+cos, +sin, 0) + new Vector3(position, 0);
var v2 = new Vector3(-sin, +cos, 0) + new Vector3(position, 0);
var v3 = new Vector3(-cos, -sin, 0) + new Vector3(position, 0);
var v4 = new Vector3(+sin, -cos, 0) + new Vector3(position, 0);
var quad = new VertexPositionColorTexture[]
{
new VertexPositionColorTexture()
{
Position = v2,
Color = color,
TextureCoordinate = new Vector2(0,0),
},
new VertexPositionColorTexture()
{
Position = v1,
Color = color,
TextureCoordinate = new Vector2(1,0),
},
new VertexPositionColorTexture()
{
Position = v3,
Color = color,
TextureCoordinate = new Vector2(0,1),
},
new VertexPositionColorTexture()
{
Position = v4,
Color = color,
TextureCoordinate = new Vector2(1,1),
},
};
this.mGraphicsDevice.DrawUserPrimitives<VertexPositionColorTexture>(PrimitiveType.TriangleStrip, quad, 0, 2);
}
public void DrawClippedFov(Vector2 position, float rotation, float size, Color color, float fov)
{
fov = MathHelper.Clamp(fov, 0, MathHelper.TwoPi);
if (fov == 0)
{
return;
}
else if (fov == MathHelper.TwoPi)
{
this.DrawSquareQuad(position, rotation, size, color);
return;
}
else
{
var ccw = ClampToBox(fov / 2);
var cw = ClampToBox(-fov / 2);
var ccwTex = new Vector2(ccw.X + 1, -ccw.Y + 1) / 2f;
var cwTex = new Vector2(cw.X + 1, -cw.Y + 1) / 2f;
VertexPositionColorTexture[] vertices;
#region Vertices
vertices = new VertexPositionColorTexture[]
{
new VertexPositionColorTexture()
{
Position = Vector3.Zero,
Color = color,
TextureCoordinate = new Vector2(0.5f, 0.5f),
},
new VertexPositionColorTexture()
{
Position = new Vector3(ccw,0),
Color = color,
TextureCoordinate = ccwTex
},
new VertexPositionColorTexture()
{
Position = new Vector3(-1, 1, 0),
Color = color,
TextureCoordinate = new Vector2(0, 0),
},
new VertexPositionColorTexture()
{
Position = new Vector3(1, 1, 0),
Color = color,
TextureCoordinate = new Vector2(1, 0),
},
new VertexPositionColorTexture()
{
Position = new Vector3(1, -1, 0),
Color = color,
TextureCoordinate = new Vector2(1, 1),
},
new VertexPositionColorTexture()
{
Position = new Vector3(-1, -1, 0),
Color = color,
TextureCoordinate = new Vector2(0, 1),
},
new VertexPositionColorTexture()
{
Position = new Vector3(cw, 0),
Color = color,
TextureCoordinate = cwTex,
},
};
var r = Matrix.CreateRotationZ(rotation) * Matrix.CreateScale(size / 2) * Matrix.CreateTranslation(new Vector3(position, 0));
for (int i = 0; i < vertices.Length; i++)
{
var vertex = vertices[i];
Vector3.Transform(ref vertex.Position, ref r, out vertex.Position);
vertices[i] = vertex;
}
#endregion Vertices
Int32[] indicies;
#region Indicies
if (fov <= MathHelper.Pi / 2)
{
indicies = new Int32[]
{
0, 1, 6,
};
}
else if (fov <= 3 * MathHelper.Pi / 2)
{
indicies = new Int32[]
{
0, 1, 3,
0, 3, 4,
0, 4, 6,
};
}
else
{
indicies = new Int32[]
{
0, 1, 2,
0, 2, 3,
0, 3, 4,
0, 4, 5,
0, 5, 6,
};
}
#endregion Indicies
this.mGraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColorTexture>(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indicies, 0, indicies.Length / 3);
}
}
public static Vector2 ClampToBox(float angle)
{
var x = Math.Cos(angle);
var y = Math.Sin(angle);
var absMax = Math.Max(Math.Abs(x), Math.Abs(y));
return new Vector2((float)(x / absMax), (float)(y / absMax));
}
public void BufferDraw()
{
if (this.mShadowHullIndicies.Count >= 3)
{
this.mGraphicsDevice.DrawUserIndexedPrimitives<ShadowHullVertex>(PrimitiveType.TriangleList, this.mShadowHullVertices.ToArray(), 0, this.mShadowHullVertices.Count, this.mShadowHullIndicies.ToArray(), 0, this.mShadowHullIndicies.Count / 3);
}
}
public void DrawFullscreenQuad()
{
// Obtain the original rendering states
var originalRasterizerState = this.mGraphicsDevice.RasterizerState;
// Draw the quad
this.mEffect.CurrentTechnique = this.mEffect.Techniques["ScreenCopy"];
//this.mGraphicsDevice.RasterizerState = RasterizerState.CullNone;
this.mEffect.Parameters["TexelBias"].SetValue(new Vector2(0.5f / this.mGraphicsDevice.Viewport.Width, 0.5f / this.mGraphicsDevice.Viewport.Height));
foreach (var effectPass in this.mEffect.CurrentTechnique.Passes)
{
effectPass.Apply();
this.mGraphicsDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, KryptonRenderHelper.UnitQuad, 0, 2);
}
// Reset to the original rendering states
//this.mGraphicsDevice.RasterizerState = originalRasterizerState;
}
public void BlurTextureToTarget(Texture2D texture, LightMapSize mapSize, BlurTechnique blurTechnique, float bluriness)
{
// Get the pass to use
string passName = "";
switch (blurTechnique)
{
case (BlurTechnique.Horizontal):
this.mEffect.Parameters["BlurFactorU"].SetValue(1f / this.GraphicsDevice.PresentationParameters.BackBufferWidth);
passName = "HorizontalBlur";
break;
case (BlurTechnique.Vertical):
this.mEffect.Parameters["BlurFactorV"].SetValue(1f / this.mGraphicsDevice.PresentationParameters.BackBufferHeight);
passName = "VerticalBlur";
break;
}
var biasFactor = KryptonRenderHelper.BiasFactorFromLightMapSize(mapSize);
// Calculate the texel bias
Vector2 texelBias = new Vector2()
{
X = biasFactor / this.mGraphicsDevice.Viewport.Width,
Y = biasFactor / this.mGraphicsDevice.Viewport.Height,
};
this.mEffect.Parameters["Texture0"].SetValue(texture);
this.mEffect.Parameters["TexelBias"].SetValue(texelBias);
this.mEffect.Parameters["Bluriness"].SetValue(bluriness);
this.mEffect.CurrentTechnique = this.mEffect.Techniques["Blur"];
mEffect.CurrentTechnique.Passes[passName].Apply();
this.mGraphicsDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, KryptonRenderHelper.UnitQuad, 0, 2);
}
public void DrawTextureToTarget(Texture2D texture, LightMapSize mapSize, BlendTechnique blend)
{
// Get the technique to use
string techniqueName = "";
switch (blend)
{
case(BlendTechnique.Add):
techniqueName = "TextureToTarget_Add";
break;
case(BlendTechnique.Multiply):
techniqueName = "TextureToTarget_Multiply";
break;
}
var biasFactor = KryptonRenderHelper.BiasFactorFromLightMapSize(mapSize);
// Calculate the texel bias
Vector2 texelBias = new Vector2()
{
X = biasFactor / this.mGraphicsDevice.ScissorRectangle.Width,
Y = biasFactor / this.mGraphicsDevice.ScissorRectangle.Height,
};
this.mEffect.Parameters["Texture0"].SetValue(texture);
this.mEffect.Parameters["TexelBias"].SetValue(texelBias);
this.mEffect.CurrentTechnique = this.mEffect.Techniques[techniqueName];
// Draw the quad
foreach (var effectPass in this.mEffect.CurrentTechnique.Passes)
{
effectPass.Apply();
this.mGraphicsDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, KryptonRenderHelper.UnitQuad, 0, 2);
}
}
private static float BiasFactorFromLightMapSize(LightMapSize mapSize)
{
switch (mapSize)
{
case (LightMapSize.Full):
return 0.5f;
case (LightMapSize.Fourth):
return 0.6f;
case (LightMapSize.Eighth):
return 0.7f;
default:
return 0.0f;
}
}
public void BufferAddBoundOutline(Common.BoundingRect boundingRect)
{
var vertexCount = this.mShadowHullVertices.Count;
this.mShadowHullVertices.Add(new ShadowHullVertex()
{
Color = Color.Black,
Normal = Vector2.Zero,
Position = new Vector2(boundingRect.Left, boundingRect.Top)
});
this.mShadowHullVertices.Add(new ShadowHullVertex()
{
Color = Color.Black,
Normal = Vector2.Zero,
Position = new Vector2(boundingRect.Right, boundingRect.Top)
});
this.mShadowHullVertices.Add(new ShadowHullVertex()
{
Color = Color.Black,
Normal = Vector2.Zero,
Position = new Vector2(boundingRect.Right, boundingRect.Bottom)
});
this.mShadowHullVertices.Add(new ShadowHullVertex()
{
Color = Color.Black,
Normal = Vector2.Zero,
Position = new Vector2(boundingRect.Left, boundingRect.Bottom)
});
this.mShadowHullIndicies.Add(vertexCount + 0);
this.mShadowHullIndicies.Add(vertexCount + 1);
this.mShadowHullIndicies.Add(vertexCount + 2);
this.mShadowHullIndicies.Add(vertexCount + 0);
this.mShadowHullIndicies.Add(vertexCount + 2);
this.mShadowHullIndicies.Add(vertexCount + 3);
}
}
}
@@ -1,89 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Krypton
{
public static class LightTextureBuilder
{
/// <summary>
/// Create a Point Light based on a size.
/// </summary>
/// <param name="device">Your game's GraphicsDevice</param>
/// <param name="size">Maximum Size</param>
/// <returns>Light Texture</returns>
public static Texture2D CreatePointLight(GraphicsDevice device, int size)
{
return CreateConicLight(device, size, MathHelper.TwoPi, 0);
}
/// <summary>
/// Create a Conic Light based on the size, and field of view.
/// </summary>
/// <param name="device">Your game's GraphicsDevice</param>
/// <param name="size">Maximum Size</param>
/// <param name="FOV">Maximum Field of View</param>
/// <returns>Light Texture</returns>
public static Texture2D CreateConicLight(GraphicsDevice device, int size, float FOV)
{
return CreateConicLight(device, size, FOV, 0);
}
/// <summary>
/// Create a Conic Light based on the size, field of view, and near plane distance.
/// </summary>
/// <param name="device">Your game's GraphicsDevice</param>
/// <param name="size">Maximum size</param>
/// <param name="FOV">Maximum Field of View</param>
/// <param name="nearPlaneDistance">Prevents texture from being drawn at this plane distance, originating from the center of light</param>
/// <returns>Light Texture</returns>
public static Texture2D CreateConicLight(GraphicsDevice device, int size, float FOV, float nearPlaneDistance)
{
/*if (!IsPowerOfTwo(size))
throw new Exception("The size must be a power of 2");*/
float[,] Data = new float[size, size];
float center = size / 2;
FOV = FOV / 2;
for (int x = 0; x < size; x++)
for (int y = 0; y < size; y++)
{
float Distance = Vector2.Distance(new Vector2(x, y), new Vector2(center));
Vector2 Difference = new Vector2(x, y) - new Vector2(center);
float Angle = (float)Math.Atan2(Difference.Y, Difference.X);
if (Distance <= center && Distance >= nearPlaneDistance && Math.Abs(Angle) <= FOV)
Data[x, y] = (center - Distance) / center;
else
Data[x, y] = 0;
}
Texture2D tex = new Texture2D(device, size, size);
Color[] Data1D = new Color[size * size];
for (int x = 0; x < size; x++)
for (int y = 0; y < size; y++)
Data1D[x + y * size] = new Color(new Vector3(Data[x, y]));
tex.SetData<Color>(Data1D);
return tex;
}
/// <summary>
/// Math helper to determine if integer is a power of two
/// </summary>
/// <param name="x">Integer value</param>
private static bool IsPowerOfTwo(int x)
{
return (x & (x - 1)) == 0;
}
}
}
-17
View File
@@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Krypton.Common;
namespace Krypton.Lights
{
public interface ILight2D
{
BoundingRect Bounds { get; }
void Draw(KryptonRenderHelper renderHelper, List<ShadowHull> hulls);
}
}
-192
View File
@@ -1,192 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Krypton.Common;
namespace Krypton.Lights
{
public class Light2D : ILight2D
{
private bool mIsOn = true;
private Vector2 mPosition = Vector2.Zero;
private float mAngle = 0;
private Texture2D mTexture = null;
private Color mColor = Color.White;
private float mRange = 1;
private float mFov = MathHelper.TwoPi;
private float mIntensity = 1;
#region Parameters
/// <summary>
/// The light's position
/// </summary>
public Vector2 Position
{
get { return this.mPosition; }
set { this.mPosition = value; }
}
/// <summary>
/// The X coordinate of the light's position
/// </summary>
public float X
{
get { return this.mPosition.X; }
set { this.mPosition.X = value; }
}
/// <summary>
/// The Y coordinate of the light's position
/// </summary>
public float Y
{
get { return this.mPosition.Y; }
set { this.mPosition.Y = value; }
}
/// <summary>
/// The light's angle
/// </summary>
public float Angle
{
get { return this.mAngle; }
set { this.mAngle = value; }
}
/// <summary>
/// The texture used as the base light map, from which shadows will be subtracted
/// </summary>
public Texture2D Texture
{
get { return this.mTexture; }
set { this.mTexture = value; }
}
/// <summary>
/// The color used to tint the light's texture
/// </summary>
public Color Color
{
get { return this.mColor; }
set { this.mColor = value; }
}
/// <summary>
/// The light's maximum radius (or "half width", if you will)
/// </summary>
public float Range
{
get { return this.mRange; }
set { this.mRange = value; }
}
/// <summary>
/// Gets or sets the light's field of view. This value determines the angles at which the light will cease to draw
/// </summary>
public float Fov
{
get { return this.mFov; }
set
{
this.mFov = MathHelper.Clamp(value, 0, MathHelper.TwoPi);
}
}
/// <summary>
/// Gets or sets the light's intensity. Think pixel = (tex * color) ^ (1 / intensity)
/// </summary>
public float Intensity
{
get { return this.mIntensity; }
set { this.mIntensity = MathHelper.Clamp(value, 0.01f, 3f); }
}
#endregion Parameters
/// <summary>
/// Gets or sets a value indicating weither or not to draw the light
/// </summary>
public bool IsOn
{
get { return this.mIsOn; }
set { this.mIsOn = value; }
}
/// <summary>
/// Draws shadows from the light's position outward
/// </summary>
/// <param name="helper">A render helper for drawing shadows</param>
/// <param name="hulls">The shadow hulls used to draw shadows</param>
public void Draw(KryptonRenderHelper helper, List<ShadowHull> hulls)
{
// Draw the light only if it's on
if (!this.mIsOn)
return;
// Make sure we only render the following hulls
helper.ShadowHullVertices.Clear();
helper.ShadowHullIndicies.Clear();
// Loop through each hull
foreach (ShadowHull hull in hulls)
{
//if(hull.Bounds.Intersects(this.Bounds))
// Add the hulls to the buffer only if they are within the light's range
if (hull.Visible && Light2D.IsInRange(hull.Position - this.Position, hull.MaxRadius * Math.Max(hull.Scale.X, hull.Scale.Y) + this.Range))
{
helper.BufferAddShadowHull(hull);
}
}
var shadowEffect = helper.Effect.Techniques["PointLight_Shadow_Fast"];
helper.Effect.CurrentTechnique = shadowEffect;
// Set the effect parameters
helper.Effect.Parameters["LightPosition"].SetValue(this.mPosition);
helper.Effect.Parameters["Texture0"].SetValue(this.mTexture);
helper.Effect.Parameters["LightIntensityFactor"].SetValue(1 / (this.mIntensity * this.mIntensity));
shadowEffect.Passes["ShadowStencil"].Apply();
helper.BufferDraw();
shadowEffect.Passes["Light"].Apply();
helper.DrawClippedFov(this.mPosition, this.mAngle, this.mRange * 2, this.mColor, this.mFov);
}
/// <summary>
/// Determines if a vector's length is less than a specified value
/// </summary>
/// <param name="offset">Offset</param>
/// <param name="dist">Distance</param>
/// <returns></returns>
private static bool IsInRange(Vector2 offset, float dist)
{
if (offset.X * offset.X + offset.Y * offset.Y < dist * dist)
return true;
return false;
}
/// <summary>
/// Gets the world-space bounds which contain the light
/// </summary>
public BoundingRect Bounds
{
get
{
BoundingRect rect;
rect.Min.X = this.mPosition.X - this.mRange;
rect.Min.Y = this.mPosition.Y - this.mRange;
rect.Max.X = this.mPosition.X + this.mRange;
rect.Max.Y = this.mPosition.Y + this.mRange;
return rect;
}
}
}
}
@@ -1,34 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Krypton")]
[assembly: AssemblyProduct("Krypton")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type. Only Windows
// assemblies support COM.
[assembly: ComVisible(false)]
// On Windows, the following GUID is for the ID of the typelib if this
// project is exposed to COM. On other platforms, it unique identifies the
// title storage container when deploying this assembly to the device.
[assembly: Guid("0ce98116-fee5-4948-bdc1-edab3ed0d43e")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.0.0")]
-241
View File
@@ -1,241 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Krypton.Common;
namespace Krypton
{
/// <summary>
/// A hull used for casting shadows from a light source
/// </summary>
public class ShadowHull
{
#region Orientation
/// <summary>
/// The position of the shadow hull
/// </summary>
public Vector2 Position;
/// <summary>
/// The angle of the shadow hull
/// </summary>
public float Angle;
#endregion
#region Shape
/// <summary>
/// The maximum radius in which all of the shadow hull's vertices are contained, originating from the hull's position
/// </summary>
public float MaxRadius;
/// <summary>
/// The vertices comprising the shadow hull
/// </summary>
public ShadowHullPoint[] Points;
/// <summary>
/// The number of vertices comprising the shadow hull
/// </summary>
public int NumPoints;
/// <summary>
/// The indicies used to render the shadow hull
/// </summary>
public Int32[] Indicies;
/// <summary>
/// The number of indicies used to render the shadow hull
/// </summary>
public int NumIndicies;
/// <summary>
/// A value indicating if the hull should cast a shadow
/// </summary>
public bool Visible = true;
/// <summary>
/// A value indicating how much to stretch the hull
/// </summary>
public Vector2 Scale = Vector2.One;
#endregion
private ShadowHull(){}
#region Factory Methods
/// <summary>
/// Creates a rectangular shadow hull
/// </summary>
/// <param name="size">The dimensions of the rectangle</param>
/// <returns>A rectangular shadow hull</returns>
public static ShadowHull CreateRectangle(Vector2 size)
{
ShadowHull hull = new ShadowHull();
size *= 0.5f;
hull.MaxRadius = (float)Math.Sqrt(size.X * size.X + size.Y * size.Y);
hull.NumPoints = 4 * 2;
var numTris = hull.NumPoints - 2;
hull.NumIndicies = numTris * 3;
hull.Points = new ShadowHullPoint[hull.NumPoints];
hull.Indicies = new Int32[hull.NumIndicies];
// Vertex position
var posTR = new Vector2(+size.X, +size.Y);
var posBR = new Vector2(+size.X, -size.Y);
var posBL = new Vector2(-size.X, -size.Y);
var posTL = new Vector2(-size.X, +size.Y);
// Right
hull.Points[0] = new ShadowHullPoint(posTR, Vector2.UnitX);
hull.Points[1] = new ShadowHullPoint(posBR, Vector2.UnitX);
// Bottom
hull.Points[2] = new ShadowHullPoint(posBR, -Vector2.UnitY);
hull.Points[3] = new ShadowHullPoint(posBL, -Vector2.UnitY);
// Left
hull.Points[4] = new ShadowHullPoint(posBL, -Vector2.UnitX);
hull.Points[5] = new ShadowHullPoint(posTL, -Vector2.UnitX);
// Top
hull.Points[6] = new ShadowHullPoint(posTL, Vector2.UnitY);
hull.Points[7] = new ShadowHullPoint(posTR, Vector2.UnitY);
// Create tris
for (int i = 0; i < numTris; i++)
{
hull.Indicies[i * 3 + 0] = 0;
hull.Indicies[i * 3 + 1] = i + 1;
hull.Indicies[i * 3 + 2] = i + 2;
}
return hull;
}
/// <summary>
/// Creates a circular shadow hull
/// </summary>
/// <param name="radius">radius of the circle</param>
/// <param name="sides">number of sides the circle will be comprised of</param>
/// <returns>A circular shadow hull</returns>
public static ShadowHull CreateCircle(float radius, int sides)
{
// Validate input
if (sides < 3) { throw new ArgumentException("Shadow hull must have at least 3 sides."); }
ShadowHull hull = new ShadowHull();
hull.MaxRadius = radius;
// Calculate number of sides
hull.NumPoints = sides * 2;
var numTris = hull.NumPoints - 2;
hull.NumIndicies = numTris * 3;
hull.Points = new ShadowHullPoint[hull.NumPoints];
hull.Indicies = new Int32[hull.NumIndicies];
var angle = (float)(-Math.PI * 2) / sides; // XNA Renders Clockwise
var angleOffset = angle / 2;
for (int i = 0; i < sides; i++)
{
// Create vertices
var v1 = new ShadowHullPoint();
var v2 = new ShadowHullPoint();
// Vertex Position
v1.Position.X = (float)Math.Cos(angle * i) * radius;
v1.Position.Y = (float)Math.Sin(angle * i) * radius;
v2.Position.X = (float)Math.Cos(angle * (i + 1)) * radius;
v2.Position.Y = (float)Math.Sin(angle * (i + 1)) * radius;
// Vertex Normal
v1.Normal.X = (float)Math.Cos(angle * i + angleOffset);
v1.Normal.Y = (float)Math.Sin(angle * i + angleOffset);
v2.Normal.X = (float)Math.Cos(angle * i + angleOffset);
v2.Normal.Y = (float)Math.Sin(angle * i + angleOffset);
// Copy vertices
hull.Points[i * 2 + 0] = v1;
hull.Points[i * 2 + 1] = v2;
}
for (int i = 0; i < numTris; i++)
{
hull.Indicies[i * 3 + 0] = 0;
hull.Indicies[i * 3 + 1] = (Int32)(i + 1);
hull.Indicies[i * 3 + 2] = (Int32)(i + 2);
}
return hull;
}
/// <summary>
/// Creates a custom shadow hull based on a series of vertices
/// </summary>
/// <param name="points">The points which the shadow hull will be comprised of</param>
/// <returns>A custom shadow hulll</returns>
public static ShadowHull CreateConvex(ref Vector2[] points)
{
// Validate input
if (points == null) { throw new ArgumentNullException("Points cannot be null."); }
if (points.Length < 3) { throw new ArgumentException("Need at least 3 points to create shadow hull."); }
var numPoints = points.Length;
ShadowHull hull = new ShadowHull();
hull.NumPoints = numPoints * 2;
var numTris = hull.NumPoints - 2;
hull.NumIndicies = numTris * 3;
hull.Points = new ShadowHullPoint[hull.NumPoints];
hull.Indicies = new Int32[hull.NumIndicies];
Vector2 pointMin = points[0];
Vector2 pointMax = points[0];
for (int i = 0; i < numPoints; i++)
{
var p1 = points[(i + 0) % numPoints];
var p2 = points[(i + 1) % numPoints];
hull.MaxRadius = Math.Max(hull.MaxRadius, p1.Length());
var line = p2 - p1;
var normal = new Vector2(-line.Y, +line.X);
normal.Normalize();
hull.Points[i * 2 + 0] = new ShadowHullPoint(p1, normal);
hull.Points[i * 2 + 1] = new ShadowHullPoint(p2, normal);
}
for (Int32 i = 0; i < numTris; i++)
{
hull.Indicies[i * 3 + 0] = 0;
hull.Indicies[i * 3 + 1] = (Int32)(i + 1);
hull.Indicies[i * 3 + 2] = (Int32)(i + 2);
}
return hull;
}
#endregion
}
}
-36
View File
@@ -1,36 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
namespace Krypton
{
/// <summary>
/// A two dimensional point with normal
/// </summary>
public struct ShadowHullPoint
{
/// <summary>
/// Creates a new Shadow Hull Point
/// </summary>
/// <param name="position">The position of the point</param>
/// <param name="normal">The normal of the side which the point helps represent</param>
public ShadowHullPoint(Vector2 position, Vector2 normal)
{
this.Position = position;
this.Normal = normal;
}
/// <summary>
/// The position of the point
/// </summary>
public Vector2 Position;
/// <summary>
/// The normal of the side of the shadow hull of which the point helps represent
/// </summary>
public Vector2 Normal;
}
}
-60
View File
@@ -1,60 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Krypton
{
public struct ShadowHullVertex : IVertexType
{
/// <summary>
/// The position of the vertex
/// </summary>
public Vector2 Position;
/// <summary>
/// The normal of the vertex
/// </summary>
public Vector2 Normal;
/// <summary>
/// The color of vertex
/// </summary>
public Color Color;
private static readonly VertexDeclaration mVertexDeclaration;
/// <summary>
///
/// </summary>
public VertexDeclaration VertexDeclaration { get { return ShadowHullVertex.mVertexDeclaration; } }
static ShadowHullVertex()
{
VertexElement[] elements = new VertexElement[]
{
new VertexElement(0, VertexElementFormat.Vector2, VertexElementUsage.Position, 0),
new VertexElement(8, VertexElementFormat.Vector2, VertexElementUsage.Normal,0),
new VertexElement(16, VertexElementFormat.Color, VertexElementUsage.Color,0),
};
mVertexDeclaration = new VertexDeclaration(elements);
}
/// <summary>
///
/// </summary>
/// <param name="position"></param>
/// <param name="normal"></param>
/// <param name="opacity"></param>
public ShadowHullVertex(Vector2 position, Vector2 normal, Color color)
{
this.Position = position;
this.Normal = normal;
this.Color = color;
}
}
}

Some files were not shown because too many files have changed in this diff Show More