#region Using Statements
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using ParadigmEngine;
using ParadigmEngine.ParticleSystem;
using ParadigmEngine.TileEngine;
#endregion
namespace Paradigm
{
/// <summary>
/// Static class which handles map editing
/// </summary>
public static class MapEditor
{
#region Public Methods
/// <summary>
/// Set tile collision
/// </summary>
public static void SetCollision(Map map, Vector2 tileLocation, EditorBrush brush)
{
// get the tile in question
Tile tile = map.GetTile((int)tileLocation.X, (int)tileLocation.Y);
// identify the collision layer index
int collisionIndex = tile.Layers.Count - 2;
TileCollision collisionType = TileCollision.Passable;
switch (brush)
{
case EditorBrush.Collision_Passable:
collisionType = TileCollision.Passable;
break;
case EditorBrush.Collision_Impassable:
collisionType = TileCollision.Impassable;
break;
case EditorBrush.Collision_Platform:
collisionType = TileCollision.Platform;
break;
case EditorBrush.Collision_SlopeDown:
collisionType = TileCollision.SlopeDown;
break;
case EditorBrush.Collision_SlopeUp:
collisionType = TileCollision.SlopeUp;
break;
case EditorBrush.Collision_Abnormal:
collisionType = TileCollision.Abnormal;
break;
case EditorBrush.Collision_NPC:
collisionType = TileCollision.NPC;
break;
}
tile.Layers[collisionIndex] = (int)collisionType;
tile.CollisionType = collisionType;
}
/*
/// <summary>
/// Mark tile at selected location as passable
/// </summary>
public static void CollisionPassible(Map map, Vector2 tileLocation)
{
// get the tile in question
Tile tile = map.GetTile((int)tileLocation.X, (int)tileLocation.Y);
// identify the collision layer index
int collisionIndex = tile.Layers.Count - 2;
tile.Layers[collisionIndex] = (float)TileCollision.Passable;
tile.CollisionType = TileCollision.Passable;
}
/// <summary>
/// Mark tile at selected location as impassable
/// </summary>
public static void CollisionImpassable(Map map, Vector2 tileLocation)
{
// get the tile in question
Tile tile = map.GetTile((int)tileLocation.X, (int)tileLocation.Y);
// identify the collision layer index
int collisionIndex = tile.Layers.Count - 2;
tile.Layers[collisionIndex] = (float)TileCollision.Impassable;
tile.CollisionType = TileCollision.Impassable;
}
/// <summary>
/// Mark tile at selected location as being a ladder
/// </summary>
public static void CollisionPlatform(Map map, Vector2 tileLocation)
{
// get the tile in question
Tile tile = map.GetTile((int)tileLocation.X, (int)tileLocation.Y);
// identify the collision layer index
int collisionIndex = tile.Layers.Count - 2;
tile.Layers[collisionIndex] = (float)TileCollision.Platform;
tile.CollisionType = TileCollision.Platform;
}
/// <summary>
/// Mark tile at selected location as being a downward right angle slope
/// </summary>
public static void CollisionSlopeDown(Map map, Vector2 tileLocation)
{
// get the tile in question
Tile tile = map.GetTile((int)tileLocation.X, (int)tileLocation.Y);
// identify the collision layer index
int collisionIndex = tile.Layers.Count - 2;
tile.Layers[collisionIndex] = (float)TileCollision.SlopeDown;
tile.CollisionType = TileCollision.SlopeDown;
}
/// <summary>
/// Mark tile at selected location as being an upward right angle slope
/// </summary>
public static void CollisionSlopeUp(Map map, Vector2 tileLocation)
{
// get the tile in question
Tile tile = map.GetTile((int)tileLocation.X, (int)tileLocation.Y);
// identify the collision layer index
int collisionIndex = tile.Layers.Count - 2;
tile.Layers[collisionIndex] = (float)TileCollision.SlopeUp;
tile.CollisionType = TileCollision.SlopeUp;
}
*/
/// <summary>
/// Draw tiles on our map
/// </summary>
/// <param name="map">The map</param>
/// <param name="tileLocation">Location of tile in tile coords</param>
/// <param name="currentLayer">Current layer</param>
/// <param name="selectedTile">Selected tile passed from main form</param>
/// <param name="selectedMultipleTiles">Have we selected multiple tiles?</param>
/// <param name="selectedStartTile">The starting tile of our range if multiple are selected</param>
/// <param name="selectedTileRange">The range of selected tiles if multiple are selected</param>
public static void TileDraw(Map map, Vector2 tileLocation, int currentLayer, SelectedTile selectedTile, bool selectedMultipleTiles , Vector2 selectedStartTile, Vector2 selectedTileRange)
{
if ((selectedTile.ID != -1) && (currentLayer != -1))
{
// get the tile in question
Tile tile = map.GetTile((int)tileLocation.X, (int)tileLocation.Y);
if (selectedMultipleTiles == false)
{
tile.Layers[currentLayer] = selectedTile.ID;
tile.SourceRectangles[currentLayer] = selectedTile.SourceRect;
}
else
{
int xRange = (int)selectedTileRange.X;
int yRange = (int)selectedTileRange.Y;
Vector2 clickLocation = tileLocation;
// iterate through selected range and set all source rects
for (int y = 0; y <= yRange; y++)
{
for (int x = 0; x <= xRange; x++)
{
// make sure the tile is within bounds to prevent any weirdness
if (((int)clickLocation.X + x < map.Width) && ((int)clickLocation.Y + y < map.Height))
{
Tile tempTile = map.GetTile((int)clickLocation.X + x, (int)clickLocation.Y + y);
int sourceID = (int)(((selectedStartTile.Y + y) * (map.TilesetTextures.ColorMap.Width / map.Tile_Size)) + (selectedStartTile.X + x));
// set the tile ID
tempTile.Layers[currentLayer] = sourceID;
// update source rects
tempTile.FindSourceRectangles();
}
}
}
}
}
}
/// <summary>
/// Fill the specified layer with the specified tile
/// </summary>
public static void TileLayerFill(Map map, int currentLayer, SelectedTile selectedTile)
{
if ((selectedTile.ID != -1) && (currentLayer != -1))
{
for (int y = 0; y < map.Height; y++)
{
for (int x = 0; x < map.Width; x++)
{
Tile tempTile = map.GetTile(x, y);
tempTile.Layers[currentLayer] = selectedTile.ID;
tempTile.SourceRectangles[currentLayer] = selectedTile.SourceRect;
}
}
}
}
/// <summary>
/// Draw an animated tile at the location specified
/// </summary>
public static void AnimatedTileDraw(Map map, int currentLayer, AnimatedTile selectedTile, Vector2 tileLocation)
{
if ((selectedTile != null) && (currentLayer != -1))
{
Vector2 worldPosition = new Vector2(tileLocation.X * map.Tile_Size, tileLocation.Y * map.Tile_Size);
int tileID = (int)(tileLocation.Y * map.Width) + (int)tileLocation.X;
// create a copy of the tile
AnimatedTile newTile = selectedTile.Clone();
newTile.Layer = currentLayer;
newTile.ID = tileID;
newTile.ResourcePath = selectedTile.ResourcePath;
newTile.WorldPosition = worldPosition;
newTile.TilePosition = tileLocation;
newTile.IsPlaced = true;
// initialize the new tile if needed
if (!newTile.IsInitialized)
newTile.Initialize(selectedTile.TileAnimation.Texture, selectedTile.TileDesc);
map.AddAnimatedTile(newTile);
}
}
/// <summary>
/// Fill a layer with the animated tile specified
/// </summary>
public static void AnimatedTileLayerFill(Map map, int currentLayer, AnimatedTile selectedTile, int mapTileWidth, int mapTileHeight)
{
if ((selectedTile != null) && (currentLayer != -1))
{
for (int y = 0; y < mapTileHeight; y++)
{
for (int x = 0; x < mapTileWidth; x++)
{
Vector2 worldPosition = new Vector2((float)x * map.Tile_Size, (float)y * map.Tile_Size);
int tileID = (int)(y * map.Width) + (int)x;
// create a copy of the tile
AnimatedTile newTile = selectedTile.Clone();
newTile.Layer = currentLayer;
newTile.ID = tileID;
newTile.ResourcePath = selectedTile.ResourcePath;
newTile.WorldPosition = worldPosition;
newTile.TilePosition = new Vector2((float)x, (float)y);
newTile.IsPlaced = true;
// initialize the new tile if needed
if (!newTile.IsInitialized)
newTile.Initialize(selectedTile.TileAnimation.Texture, selectedTile.TileDesc);
map.AddAnimatedTile(newTile);
}
}
}
}
/// <summary>
/// Erase tile at specified location and layer
/// </summary>
public static void TileErase(Map map, Vector2 tileLocation, int currentLayer)
{
// get the tile in question
Tile tile = map.GetTile((int)tileLocation.X, (int)tileLocation.Y);
if (currentLayer != -1)
tile.Layers[currentLayer] = -1;
tile.RemoveAnimatedTileAt(currentLayer);
}
/// <summary>
/// Mark specified tile as a hazard
/// </summary>
public static void HazardDamage(Map map, Vector2 tileLocation)
{
// get the tile in question
Tile tile = map.GetTile((int)tileLocation.X, (int)tileLocation.Y);
// identify the hazard layer index
int hazardIndex = tile.Layers.Count - 3;
tile.Layers[hazardIndex] = 1;
tile.IsHazard = true;
}
/// <summary>
/// Mark specified tile as not being a hazard
/// </summary>
public static void HazardNone(Map map, Vector2 tileLocation)
{
// get the tile in question
Tile tile = map.GetTile((int)tileLocation.X, (int)tileLocation.Y);
// identify the hazard layer index
int hazardIndex = tile.Layers.Count - 3;
tile.Layers[hazardIndex] = -1;
tile.IsHazard = false;
}
/// <summary>
/// Mark specified tile as having a terrain type
/// </summary>
public static void TerrainSet(Map map, Vector2 tileLocation, int terrainType)
{
// get the tile in question
Tile tile = map.GetTile((int)tileLocation.X, (int)tileLocation.Y);
// identify the terrain layer index
int terrainIndex = tile.Layers.Count - 1;
tile.Layers[terrainIndex] = terrainType;
tile.TerrainIndex = terrainType;
}
/// <summary>
/// Mark specified tile as not having a terrain type
/// </summary>
public static void TerrainNone(Map map, Vector2 tileLocation)
{
// get the tile in question
Tile tile = map.GetTile((int)tileLocation.X, (int)tileLocation.Y);
// identify the terrain layer index
int terrainIndex = tile.Layers.Count - 1;
tile.Layers[terrainIndex] = -1;
tile.TerrainIndex = -1;
}
/// <summary>
/// Place an entity or spawn point
/// </summary>
/// <param name="map">Current map</param>
/// <param name="entityLayer">EntityLayer object</param>
/// <param name="selectedEntity">The entity to place</param>
/// <param name="tileLocation">The location in tile coords</param>
public static void EntityDraw(Map map, EntityLayer entityLayer, MapEntity selectedEntity, Vector2 tileLocation)
{
if (selectedEntity != null)
{
Vector2 worldPosition = new Vector2((tileLocation.X * map.Tile_Size) + selectedEntity.Sprite.Origin.X,
tileLocation.Y * map.Tile_Size);
entityLayer.Add(selectedEntity, worldPosition, tileLocation);
entityLayer.Sort();
}
}
/// <summary>
/// Remove a spawn point or entity
/// </summary>
/// <param name="entityLayer">EntityLayer object</param>
/// <param name="selectionReticle">Selection reticle from our map</param>
public static void EntityErase(EntityLayer entityLayer, SelectionReticle selectionReticle)
{
for (int i = entityLayer.EntityList.Count - 1; i >= 0; i--)
{
if (entityLayer.EntityList[i].BoundingRectangle.Intersects(selectionReticle.BoundingRectangle))
{
entityLayer.Remove(i);
break;
}
}
}
/// <summary>
/// Place a particle emitter
/// </summary>
/// <param name="map">Current map</param>
/// <param name="particleLayer">ParticleLayer object</param>
/// <param name="selectedEmitter">Selected emitter</param>
/// <param name="tileLocation">Location in tile coords</param>
public static void ParticleEmitterDraw(Map map, ParticleLayer particleLayer, ParticleEmitter selectedEmitter, Vector2 tileLocation)
{
if (selectedEmitter != null)
{
Vector2 worldPosition = new Vector2(tileLocation.X * map.Tile_Size, tileLocation.Y * map.Tile_Size);
Vector2 correctedWorldPos = new Vector2(worldPosition.X + map.Tile_Size / 2, worldPosition.Y + map.Tile_Size / 2);
particleLayer.Add(selectedEmitter, correctedWorldPos, tileLocation);
}
}
/// <summary>
/// Remove a particle emitter
/// </summary>
/// <param name="map">Current map</param>
/// <param name="particleLayer">ParticleLayer object</param>
/// <param name="tileLocation">Location in tile coords</param>
public static void ParticleEmitterErase(Map map, ParticleLayer particleLayer, Vector2 tileLocation)
{
for (int i = 0; i < particleLayer.EmitterList.Count; i++)
{
if (particleLayer.EmitterList[i].TilePosition == tileLocation)
{
particleLayer.Remove(i);
break;
}
}
}
/// <summary>
/// Draw a portal
/// </summary>
/// <param name="map">Current map</param>
/// <param name="portalSelection">List of rectangles contained in our selection</param>
/// <param name="inputHandler">Input handler object</param>
/// <param name="portalInfoList">Current list of PortalInfo data structures</param>
/// <param name="portalIndex">The index of the portal in the PortalInfo list</param>
public static void PortalDraw(Map map, MouseSelectionHandler inputHandler, List<PortalInfo> portalInfoList, int portalIndex)
{
List<Rectangle> portalSelection = new List<Rectangle>();
// process selected tiles
for (int y = 0; y < map.Height; y++)
{
for (int x = 0; x < map.Width; x++)
{
Tile tempTile = map.GetTile(x, y);
if (inputHandler.MouseRec.Contains(tempTile.MapRectangle.Center))
{
portalSelection.Add(tempTile.MapRectangle);
}
}
}
// declare temp variables
int tempX = 0;
int tempY = 0;
int tempWidth = 0;
int tempHeight = 0;
// sort list to find x and width
portalSelection.Sort(delegate(Rectangle rect1, Rectangle rect2)
{
return rect1.X.CompareTo(rect2.X);
});
// get x coord and width for our new rectangle
if (portalSelection.Count > 0)
{
tempX = portalSelection[0].X;
tempWidth = portalSelection[portalSelection.Count - 1].X - tempX + (int)map.Tile_Size;
}
// sort list to find y and height
portalSelection.Sort(delegate(Rectangle rect1, Rectangle rect2)
{
return rect1.Y.CompareTo(rect2.Y);
});
// get x coord and width for our new rectangle
if (portalSelection.Count > 0)
{
tempY = portalSelection[0].Y;
tempHeight = portalSelection[portalSelection.Count - 1].Y - tempY + (int)map.Tile_Size;
}
// write bounding box to portal
if ((portalSelection.Count > 0) && (portalIndex >= 0))
{
Rectangle tempRect = new Rectangle(tempX, tempY, tempWidth, tempHeight);
// as we cannot access the elements of the list directly, create a temp copy, modify, and replace it in the list
PortalInfo tempPortalInfo = portalInfoList[portalIndex];
tempPortalInfo.boundingBox = tempRect;
portalInfoList[portalIndex] = tempPortalInfo;
}
}
/// <summary>
/// Draw an event region
/// </summary>
/// <param name="map">Current map</param>
/// <param name="effectSelection">List of rectangles contained in our selection</param>
/// <param name="inputHandler">Input handler object</param>
/// <param name="shaderRegionInfoList">Current list of MapEventInfo data structures</param>
/// <param name="shaderRegionIndex">The index of the portal in the MapEventInfo list</param>
public static void EventRegionDraw(Map map, MouseSelectionHandler inputHandler, List<MapEventInfo> mapEventInfoList, int mapEventIndex)
{
List<Rectangle> eventSelection = new List<Rectangle>();
// process selected tiles
for (int y = 0; y < map.Height; y++)
{
for (int x = 0; x < map.Width; x++)
{
Tile tempTile = map.GetTile(x, y);
if (inputHandler.MouseRec.Contains(tempTile.MapRectangle.Center))
{
eventSelection.Add(tempTile.MapRectangle);
}
}
}
// declare temp variables
int tempX = 0;
int tempY = 0;
int tempWidth = 0;
int tempHeight = 0;
// sort list to find x and width
eventSelection.Sort(delegate(Rectangle rect1, Rectangle rect2)
{
return rect1.X.CompareTo(rect2.X);
});
// get x coord and width for our new rectangle
if (eventSelection.Count > 0)
{
tempX = eventSelection[0].X;
tempWidth = eventSelection[eventSelection.Count - 1].X - tempX + (int)map.Tile_Size;
}
// sort list to find y and height
eventSelection.Sort(delegate(Rectangle rect1, Rectangle rect2)
{
return rect1.Y.CompareTo(rect2.Y);
});
// get x coord and width for our new rectangle
if (eventSelection.Count > 0)
{
tempY = eventSelection[0].Y;
tempHeight = eventSelection[eventSelection.Count - 1].Y - tempY + (int)map.Tile_Size;
}
// write bounding box to portal
if ((eventSelection.Count > 0) && (mapEventIndex >= 0))
{
Rectangle tempRect = new Rectangle(tempX, tempY, tempWidth, tempHeight);
// as we cannot access the elements of the list directly, create a temp copy, modify, and replace it in the list
MapEventInfo tempEventInfo = mapEventInfoList[mapEventIndex];
tempEventInfo.boundingBox = tempRect;
mapEventInfoList[mapEventIndex] = tempEventInfo;
}
}
/// <summary>
/// Draw a shader effect region
/// </summary>
/// <param name="map">Current map</param>
/// <param name="effectSelection">List of rectangles contained in our selection</param>
/// <param name="inputHandler">Input handler object</param>
/// <param name="shaderRegionInfoList">Current list of ShaderRegionInfo data structures</param>
/// <param name="shaderRegionIndex">The index of the portal in the ShaderRegionInfo list</param>
public static void ShaderRegionDraw(Map map, MouseSelectionHandler inputHandler, List<ShaderRegionInfo> shaderRegionInfoList, int shaderRegionIndex)
{
List<Rectangle> effectSelection = new List<Rectangle>();
// process selected tiles
for (int y = 0; y < map.Height; y++)
{
for (int x = 0; x < map.Width; x++)
{
Tile tempTile = map.GetTile(x, y);
if (inputHandler.MouseRec.Contains(tempTile.MapRectangle.Center))
{
effectSelection.Add(tempTile.MapRectangle);
}
}
}
// declare temp variables
int tempX = 0;
int tempY = 0;
int tempWidth = 0;
int tempHeight = 0;
// sort list to find x and width
effectSelection.Sort(delegate(Rectangle rect1, Rectangle rect2)
{
return rect1.X.CompareTo(rect2.X);
});
// get x coord and width for our new rectangle
if (effectSelection.Count > 0)
{
tempX = effectSelection[0].X;
tempWidth = effectSelection[effectSelection.Count - 1].X - tempX + (int)map.Tile_Size;
}
// sort list to find y and height
effectSelection.Sort(delegate(Rectangle rect1, Rectangle rect2)
{
return rect1.Y.CompareTo(rect2.Y);
});
// get x coord and width for our new rectangle
if (effectSelection.Count > 0)
{
tempY = effectSelection[0].Y;
tempHeight = effectSelection[effectSelection.Count - 1].Y - tempY + (int)map.Tile_Size;
}
// write bounding box to portal
if ((effectSelection.Count > 0) && (shaderRegionIndex >= 0))
{
Rectangle tempRect = new Rectangle(tempX, tempY, tempWidth, tempHeight);
// as we cannot access the elements of the list directly, create a temp copy, modify, and replace it in the list
ShaderRegionInfo tempShaderRegionInfo = shaderRegionInfoList[shaderRegionIndex];
tempShaderRegionInfo.boundingBox = tempRect;
shaderRegionInfoList[shaderRegionIndex] = tempShaderRegionInfo;
}
}
#endregion
}
}