new doors
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,41 +1,41 @@
|
||||
<Items>
|
||||
<Item
|
||||
name="Door"
|
||||
linkable="true"
|
||||
pickdistance="150.0">
|
||||
|
||||
<Sprite texture ="doorframe.png" depth="0.8" origin="0.5,0.5"/>
|
||||
|
||||
<Door>
|
||||
<Sprite texture ="door.png" depth="0.4" origin="0.5,0.0"/>
|
||||
</Door>
|
||||
|
||||
<ConnectionPanel canbeselected = "true">
|
||||
<requireditem name="Screwdriver" type="Equipped"/>
|
||||
<input name="toggle"/>
|
||||
<input name="set_state"/>
|
||||
<output name="state_out"/>
|
||||
</ConnectionPanel>
|
||||
|
||||
</Item>
|
||||
|
||||
<Item
|
||||
name="Windowed Door"
|
||||
linkable="true"
|
||||
pickdistance="150.0">
|
||||
|
||||
<Sprite texture ="doorframe.png" depth="0.8" origin="0.5,0.5"/>
|
||||
|
||||
<Door window="0,-18,10,89">
|
||||
<Sprite texture ="windowedDoor.png" depth="0.4" origin="0.5,0.0"/>
|
||||
</Door>
|
||||
|
||||
<ConnectionPanel canbeselected = "true">
|
||||
<requireditem name="Screwdriver" type="Equipped"/>
|
||||
<input name="toggle"/>
|
||||
<input name="set_state"/>
|
||||
<output name="state_out"/>
|
||||
</ConnectionPanel>
|
||||
|
||||
</Item>
|
||||
<Items>
|
||||
<Item
|
||||
name="Door"
|
||||
linkable="true"
|
||||
pickdistance="150.0">
|
||||
|
||||
<Sprite texture ="door.png" sourcerect="0,0,48,208" depth="0.8" origin="0.5,0.5"/>
|
||||
|
||||
<Door>
|
||||
<Sprite texture ="door.png" sourcerect="80,0,19,208" depth="0.4" origin="0.5,0.0"/>
|
||||
</Door>
|
||||
|
||||
<ConnectionPanel canbeselected = "true">
|
||||
<requireditem name="Screwdriver" type="Equipped"/>
|
||||
<input name="toggle"/>
|
||||
<input name="set_state"/>
|
||||
<output name="state_out"/>
|
||||
</ConnectionPanel>
|
||||
|
||||
</Item>
|
||||
|
||||
<Item
|
||||
name="Windowed Door"
|
||||
linkable="true"
|
||||
pickdistance="150.0">
|
||||
|
||||
<Sprite texture ="door.png" sourcerect="0,0,48,208" depth="0.8" origin="0.5,0.5"/>
|
||||
|
||||
<Door window="0,-18,10,89">
|
||||
<Sprite texture ="door.png" sourcerect="56,0,19,208" depth="0.4" origin="0.5,0.0"/>
|
||||
</Door>
|
||||
|
||||
<ConnectionPanel canbeselected = "true">
|
||||
<requireditem name="Screwdriver" type="Equipped"/>
|
||||
<input name="toggle"/>
|
||||
<input name="set_state"/>
|
||||
<output name="state_out"/>
|
||||
</ConnectionPanel>
|
||||
|
||||
</Item>
|
||||
</Items>
|
||||
@@ -1,73 +1,73 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<prefabs>
|
||||
<watersplash sprite="Content/Particles/spatter.png"
|
||||
startsizemin="0.15,0.15" startsizemax="0.3,0.3"
|
||||
sizechangemin="0.9,0.9" sizechangemax="1.2,1.2"
|
||||
startrotationmin ="0.0" startrotationmax="3.14"
|
||||
startcolor="1.0, 1.0, 1.0" startalpha="0.8"
|
||||
colorchange="0.0, 0.0, 0.0, -0.25"
|
||||
lifetime="3"
|
||||
deleteonhit="true"
|
||||
velocitychange="0.0, -9.8"/>
|
||||
|
||||
<mist sprite="Content/Particles/spatter.png"
|
||||
startsizemin="0.2,0.2" startsizemax="0.3,0.3"
|
||||
sizechangemin="0.5,0.5" sizechangemax="0.5,0.5"
|
||||
startrotationmin ="0.0" startrotationmax="3.14"
|
||||
startcolor="1.0, 1.0, 1.0" startalpha="0.5"
|
||||
colorchange="0.0, 0.0, 0.0, -0.25"
|
||||
lifetime="3"
|
||||
velocitychange="0.0, -0.05"/>
|
||||
|
||||
<dustcloud sprite="Content/Particles/spatter.png"
|
||||
startsizemin="0.8,0.8" startsizemax="1.0,1.0"
|
||||
sizechangemin="0.0,0.0" sizechangemax="0.0,0.0"
|
||||
startrotationmin ="0.0" startrotationmax="3.14"
|
||||
startcolor="0.2, 0.2, 0.2" startalpha="0.5"
|
||||
colorchange="0.0, 0.0, 0.0, -0.3"
|
||||
lifetime="3"
|
||||
velocitychange="0.0, -5.0"/>
|
||||
|
||||
<bubbles sprite="Content/Particles/bubbles.png"
|
||||
startsizemin="0.4,0.4" startsizemax="0.5,0.5"
|
||||
sizechangemin="0.0,0.0" sizechangemax="0.1,0.1"
|
||||
startrotationmin ="0.0" startrotationmax="3.14"
|
||||
startcolor="1.0, 1.0, 1.0" startalpha="0.8"
|
||||
colorchange="0.0, 0.0, 0.0, -0.5"
|
||||
lifetime="3"
|
||||
deleteonhit="true"
|
||||
inwater="true"
|
||||
velocitychange="0.0, 0.1"/>
|
||||
|
||||
<blood sprite="Content/Particles/blood.png"
|
||||
startsizemin="0.05,0.05" startsizemax="0.6,0.6"
|
||||
sizechangemin="0.3,0.2" sizechangemax="0.4,0.2"
|
||||
startrotationmin ="0.0" startrotationmax="0.0"
|
||||
startcolor="0.5, 0.0, 0.0" startalpha="1.0"
|
||||
colorchange="0.0, 0.0, 0.0, -1.0"
|
||||
lifetime="2"
|
||||
deleteonhit="true"
|
||||
rotatetodirection="true"
|
||||
velocitychange="0.0, -9.8"/>
|
||||
|
||||
<waterblood sprite="Content/Particles/spatter.png"
|
||||
startsizemin="0.1,0.1" startsizemax="0.1,0.1"
|
||||
sizechangemin="0.15,0.15" sizechangemax="0.2,0.2"
|
||||
startrotationmin ="0.0" startrotationmax="3.14"
|
||||
startcolor="0.5, 0.0, 0.0" startalpha="1.0"
|
||||
colorchange="0.0, 0.0, 0.0, -0.25"
|
||||
lifetime="5.0"
|
||||
inwater="true"
|
||||
velocitychange="0.0, 0.0"/>
|
||||
|
||||
<explosionfire sprite="Content/Particles/explosion.png"
|
||||
startsizemin="1.5,1.5" startsizemax="3.0,3.0"
|
||||
sizechangemin="0.5,0.5" sizechangemax="0.6,0.6"
|
||||
startrotationmin ="0.0" startrotationmax="3.14"
|
||||
startcolor="1.0, 1.0, 1.0" startalpha="1.0"
|
||||
colorchange="-0.4, -0.4, -0.4, -0.3"
|
||||
lifetime="5.0"
|
||||
inwater="false"
|
||||
deleteonhit="true"
|
||||
velocitychange="0.0, 0.5"/>
|
||||
</prefabs>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<prefabs>
|
||||
<watersplash sprite="Content/Particles/spatter.png"
|
||||
startsizemin="0.15,0.15" startsizemax="0.3,0.3"
|
||||
sizechangemin="0.9,0.9" sizechangemax="1.2,1.2"
|
||||
startrotationmin ="0.0" startrotationmax="6.28"
|
||||
startcolor="1.0, 1.0, 1.0" startalpha="0.8"
|
||||
colorchange="0.0, 0.0, 0.0, -0.25"
|
||||
lifetime="3"
|
||||
deleteonhit="true"
|
||||
velocitychange="0.0, -9.8"/>
|
||||
|
||||
<mist sprite="Content/Particles/spatter.png"
|
||||
startsizemin="0.4,0.4" startsizemax="0.5,0.5"
|
||||
sizechangemin="0.25,0.25" sizechangemax="0.3,0.3"
|
||||
startrotationmin ="0.0" startrotationmax="6.28"
|
||||
startcolor="1.0, 1.0, 1.0" startalpha="0.5"
|
||||
colorchange="0.0, 0.0, 0.0, -0.25"
|
||||
lifetime="3"
|
||||
velocitychange="0.0, -0.05"/>
|
||||
|
||||
<dustcloud sprite="Content/Particles/spatter.png"
|
||||
startsizemin="0.8,0.8" startsizemax="1.0,1.0"
|
||||
sizechangemin="0.0,0.0" sizechangemax="0.0,0.0"
|
||||
startrotationmin ="0.0" startrotationmax="6.28"
|
||||
startcolor="0.2, 0.2, 0.2" startalpha="0.5"
|
||||
colorchange="0.0, 0.0, 0.0, -0.3"
|
||||
lifetime="3"
|
||||
velocitychange="0.0, -5.0"/>
|
||||
|
||||
<bubbles sprite="Content/Particles/bubbles.png"
|
||||
startsizemin="0.4,0.4" startsizemax="0.5,0.5"
|
||||
sizechangemin="0.0,0.0" sizechangemax="0.1,0.1"
|
||||
startrotationmin ="0.0" startrotationmax="3.14"
|
||||
startcolor="1.0, 1.0, 1.0" startalpha="0.8"
|
||||
colorchange="0.0, 0.0, 0.0, -0.5"
|
||||
lifetime="3"
|
||||
deleteonhit="true"
|
||||
inwater="true"
|
||||
velocitychange="0.0, 0.1"/>
|
||||
|
||||
<blood sprite="Content/Particles/blood.png"
|
||||
startsizemin="0.05,0.05" startsizemax="0.6,0.6"
|
||||
sizechangemin="0.3,0.2" sizechangemax="0.4,0.2"
|
||||
startrotationmin ="0.0" startrotationmax="0.0"
|
||||
startcolor="0.5, 0.0, 0.0" startalpha="1.0"
|
||||
colorchange="0.0, 0.0, 0.0, -1.0"
|
||||
lifetime="2"
|
||||
deleteonhit="true"
|
||||
rotatetodirection="true"
|
||||
velocitychange="0.0, -9.8"/>
|
||||
|
||||
<waterblood sprite="Content/Particles/spatter.png"
|
||||
startsizemin="0.1,0.1" startsizemax="0.1,0.1"
|
||||
sizechangemin="0.15,0.15" sizechangemax="0.2,0.2"
|
||||
startrotationmin ="0.0" startrotationmax="6.28"
|
||||
startcolor="0.5, 0.0, 0.0" startalpha="1.0"
|
||||
colorchange="0.0, 0.0, 0.0, -0.25"
|
||||
lifetime="5.0"
|
||||
inwater="true"
|
||||
velocitychange="0.0, 0.0"/>
|
||||
|
||||
<explosionfire sprite="Content/Particles/explosion.png"
|
||||
startsizemin="1.5,1.5" startsizemax="3.0,3.0"
|
||||
sizechangemin="0.5,0.5" sizechangemax="0.6,0.6"
|
||||
startrotationmin ="0.0" startrotationmax="6.28"
|
||||
startcolor="1.0, 1.0, 1.0" startalpha="1.0"
|
||||
colorchange="-0.4, -0.4, -0.4, -0.3"
|
||||
lifetime="5.0"
|
||||
inwater="false"
|
||||
deleteonhit="true"
|
||||
velocitychange="0.0, 0.5"/>
|
||||
</prefabs>
|
||||
|
||||
@@ -1,267 +1,304 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml.Linq;
|
||||
using FarseerPhysics;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using FarseerPhysics.Factories;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Subsurface.Lights;
|
||||
|
||||
namespace Subsurface.Items.Components
|
||||
{
|
||||
class Door : ItemComponent
|
||||
{
|
||||
Gap linkedGap;
|
||||
|
||||
Rectangle window;
|
||||
|
||||
ConvexHull convexHull;
|
||||
ConvexHull convexHull2;
|
||||
|
||||
Gap LinkedGap
|
||||
{
|
||||
get
|
||||
{
|
||||
if (linkedGap != null) return linkedGap;
|
||||
foreach (MapEntity e in item.linkedTo)
|
||||
{
|
||||
linkedGap = e as Gap;
|
||||
if (linkedGap != null) return linkedGap;
|
||||
}
|
||||
linkedGap = new Gap(item.Rect);
|
||||
linkedGap.Open = openState;
|
||||
item.linkedTo.Add(linkedGap);
|
||||
return linkedGap;
|
||||
}
|
||||
}
|
||||
|
||||
bool isOpen;
|
||||
float openState;
|
||||
|
||||
[HasDefaultValue("0.0,0.0,0.0,0.0", false)]
|
||||
public string Window
|
||||
{
|
||||
get { return ToolBox.Vector4ToString(new Vector4(window.X, window.Y, window.Width, window.Height)); }
|
||||
set
|
||||
{
|
||||
Vector4 vector = ToolBox.ParseToVector4(value);
|
||||
if (vector.Z!=0.0f || vector.W !=0.0f)
|
||||
{
|
||||
window = new Rectangle((int)vector.X, (int)vector.Y, (int)vector.Z, (int)vector.W);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Editable, HasDefaultValue(false, true)]
|
||||
public bool IsOpen
|
||||
{
|
||||
get { return isOpen; }
|
||||
set
|
||||
{
|
||||
isOpen = value;
|
||||
openState = (isOpen) ? 1.0f : 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
public float OpenState
|
||||
{
|
||||
get { return openState; }
|
||||
set
|
||||
{
|
||||
if (openState == value) return;
|
||||
openState = MathHelper.Clamp(value, 0.0f, 1.0f);
|
||||
|
||||
|
||||
|
||||
if (window==null)
|
||||
{
|
||||
Rectangle rect = item.Rect;
|
||||
rect.Height = (int)(rect.Height * (1.0f - openState));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//Rectangle rect = item.Rect;
|
||||
//rect.Height = (int)(rect.Height * (1.0f - openState));
|
||||
|
||||
Rectangle rect1 = item.Rect;
|
||||
rect1.Height = -window.Y;
|
||||
|
||||
rect1.Y += (int)(item.Rect.Height * openState);
|
||||
rect1.Height = Math.Max(rect1.Height - (rect1.Y - item.Rect.Y), 0);
|
||||
rect1.Y = Math.Min(item.Rect.Y, rect1.Y);
|
||||
|
||||
Rectangle rect2 = item.Rect;
|
||||
rect2.Y = rect2.Y + window.Y - window.Height;
|
||||
|
||||
rect2.Y += (int)(item.Rect.Height * openState);
|
||||
//rect2.Height = Math.Max(rect2.Height - (rect2.Y - item.Rect.Y), 0);
|
||||
rect2.Y = Math.Min(item.Rect.Y, rect2.Y);
|
||||
rect2.Height = rect2.Y - (item.Rect.Y - (int)(item.Rect.Height * (1.0f - openState)));
|
||||
|
||||
convexHull.SetVertices(GetConvexHullCorners(rect1));
|
||||
if (convexHull2!=null) convexHull2.SetVertices(GetConvexHullCorners(rect2));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
PhysicsBody body;
|
||||
|
||||
Sprite doorSprite;
|
||||
|
||||
public Door(Item item, XElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
//Vector2 position = new Vector2(newRect.X, newRect.Y);
|
||||
|
||||
// isOpen = false;
|
||||
|
||||
body = new PhysicsBody(BodyFactory.CreateRectangle(Game1.world,
|
||||
ConvertUnits.ToSimUnits(Math.Max(item.Rect.Width, 1)),
|
||||
ConvertUnits.ToSimUnits(Math.Max(item.Rect.Height, 1)),
|
||||
1.5f));
|
||||
|
||||
body.BodyType = BodyType.Static;
|
||||
body.SetTransform(
|
||||
ConvertUnits.ToSimUnits(new Vector2(item.Rect.X + item.Rect.Width / 2, item.Rect.Y - item.Rect.Height / 2)),
|
||||
0.0f);
|
||||
body.Friction = 0.5f;
|
||||
|
||||
|
||||
//string spritePath = Path.GetDirectoryName(item.Prefab.ConfigFile) + "\\"+ ToolBox.GetAttributeString(element, "sprite", "");
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
if (subElement.Name.ToString().ToLower() != "sprite") continue;
|
||||
doorSprite = new Sprite(subElement, Path.GetDirectoryName(item.Prefab.ConfigFile));
|
||||
break;
|
||||
}
|
||||
|
||||
isActive = true;
|
||||
|
||||
Vector2[] corners = GetConvexHullCorners(item.Rect);
|
||||
|
||||
convexHull = new ConvexHull(corners, Color.Black);
|
||||
if (window!=null) convexHull2 = new ConvexHull(corners, Color.Black);
|
||||
|
||||
OpenState = openState;
|
||||
//powerConsumption = -100.0f;
|
||||
|
||||
//LinkedGap.Open = openState;
|
||||
}
|
||||
|
||||
private Vector2[] GetConvexHullCorners(Rectangle rect)
|
||||
{
|
||||
Vector2[] corners = new Vector2[4];
|
||||
corners[0] = new Vector2(rect.X, rect.Y - rect.Height);
|
||||
corners[1] = new Vector2(rect.X, rect.Y);
|
||||
corners[2] = new Vector2(rect.Right, rect.Y);
|
||||
corners[3] = new Vector2(rect.Right, rect.Y - rect.Height);
|
||||
|
||||
return corners;
|
||||
}
|
||||
|
||||
public override void Move(Vector2 amount)
|
||||
{
|
||||
base.Move(amount);
|
||||
|
||||
body.SetTransform(body.Position + ConvertUnits.ToSimUnits(amount), 0.0f);
|
||||
|
||||
convexHull.Move(amount);
|
||||
}
|
||||
|
||||
|
||||
public override bool Pick(Character picker)
|
||||
{
|
||||
isActive = true;
|
||||
isOpen = !isOpen;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
OpenState += deltaTime * ((isOpen) ? 3.0f : -3.0f);
|
||||
|
||||
item.SendSignal((isOpen) ? "1" : "0", "state_out");
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
|
||||
LinkedGap.Open = openState;
|
||||
|
||||
Color color = (item.IsSelected) ? Color.Green : Color.White;
|
||||
|
||||
//prefab.sprite.Draw(spriteBatch, new Vector2(rect.X, -rect.Y), new Vector2(rect.Width, rect.Height), color);
|
||||
|
||||
if (openState == 1.0f)
|
||||
{
|
||||
body.Enabled = false;
|
||||
convexHull.Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
spriteBatch.Draw(doorSprite.Texture, new Vector2(item.Rect.Center.X, -item.Rect.Y),
|
||||
new Rectangle(0, (int)(doorSprite.size.Y * openState),
|
||||
(int)doorSprite.size.X, (int)(doorSprite.size.Y * (1.0f - openState))),
|
||||
color, 0.0f, doorSprite.Origin, 1.0f, SpriteEffects.None, doorSprite.Depth);
|
||||
|
||||
convexHull.Enabled = true;
|
||||
|
||||
if (openState == 0.0f)
|
||||
{
|
||||
body.Enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
//push characters out of the doorway when the door is closing/opening
|
||||
Vector2 simPos = ConvertUnits.ToSimUnits(new Vector2(item.Rect.X, item.Rect.Y));
|
||||
Vector2 simSize = ConvertUnits.ToSimUnits(new Vector2(item.Rect.Width,
|
||||
item.Rect.Height * (1.0f - openState)));
|
||||
|
||||
foreach (Character c in Character.characterList)
|
||||
{
|
||||
int dir = Math.Sign(c.animController.limbs[0].SimPosition.X - simPos.X);
|
||||
foreach (Limb l in c.animController.limbs)
|
||||
{
|
||||
if (l.SimPosition.Y < simPos.Y || l.SimPosition.Y > simPos.Y - simSize.Y) continue;
|
||||
if (Math.Abs(l.SimPosition.X - simPos.X) > simSize.X * 2.0f) continue;
|
||||
|
||||
l.body.ApplyForce(new Vector2(dir * 10.0f, 0.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Remove()
|
||||
{
|
||||
base.Remove();
|
||||
|
||||
Game1.world.RemoveBody(body.FarseerBody);
|
||||
|
||||
doorSprite.Remove();
|
||||
|
||||
convexHull.Remove();
|
||||
if (convexHull2 != null) convexHull2.Remove();
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(string signal, Connection connection, Item sender)
|
||||
{
|
||||
isActive = true;
|
||||
if (connection.name=="toggle")
|
||||
{
|
||||
isOpen = !isOpen;
|
||||
}
|
||||
else if (connection.name == "set_state")
|
||||
{
|
||||
isOpen = (signal!="0");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml.Linq;
|
||||
using FarseerPhysics;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using FarseerPhysics.Factories;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Subsurface.Lights;
|
||||
|
||||
namespace Subsurface.Items.Components
|
||||
{
|
||||
class Door : ItemComponent
|
||||
{
|
||||
Gap linkedGap;
|
||||
|
||||
Rectangle window;
|
||||
|
||||
ConvexHull convexHull;
|
||||
ConvexHull convexHull2;
|
||||
|
||||
Gap LinkedGap
|
||||
{
|
||||
get
|
||||
{
|
||||
if (linkedGap != null) return linkedGap;
|
||||
foreach (MapEntity e in item.linkedTo)
|
||||
{
|
||||
linkedGap = e as Gap;
|
||||
if (linkedGap != null) return linkedGap;
|
||||
}
|
||||
linkedGap = new Gap(item.Rect);
|
||||
linkedGap.Open = openState;
|
||||
item.linkedTo.Add(linkedGap);
|
||||
return linkedGap;
|
||||
}
|
||||
}
|
||||
|
||||
bool isOpen;
|
||||
float openState;
|
||||
|
||||
[HasDefaultValue("0.0,0.0,0.0,0.0", false)]
|
||||
public string Window
|
||||
{
|
||||
get { return ToolBox.Vector4ToString(new Vector4(window.X, window.Y, window.Width, window.Height)); }
|
||||
set
|
||||
{
|
||||
Vector4 vector = ToolBox.ParseToVector4(value);
|
||||
if (vector.Z!=0.0f || vector.W !=0.0f)
|
||||
{
|
||||
window = new Rectangle((int)vector.X, (int)vector.Y, (int)vector.Z, (int)vector.W);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Editable, HasDefaultValue(false, true)]
|
||||
public bool IsOpen
|
||||
{
|
||||
get { return isOpen; }
|
||||
set
|
||||
{
|
||||
isOpen = value;
|
||||
openState = (isOpen) ? 1.0f : 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
private Rectangle doorRect;
|
||||
|
||||
|
||||
public float OpenState
|
||||
{
|
||||
get { return openState; }
|
||||
set
|
||||
{
|
||||
if (openState == value) return;
|
||||
openState = MathHelper.Clamp(value, 0.0f, 1.0f);
|
||||
|
||||
|
||||
|
||||
if (window==null)
|
||||
{
|
||||
Rectangle rect = item.Rect;
|
||||
rect.Height = (int)(rect.Height * (1.0f - openState));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//Rectangle rect = item.Rect;
|
||||
//rect.Height = (int)(rect.Height * (1.0f - openState));
|
||||
|
||||
Rectangle rect1 = doorRect;
|
||||
rect1.Height = -window.Y;
|
||||
|
||||
rect1.Y += (int)(doorRect.Height * openState);
|
||||
rect1.Height = Math.Max(rect1.Height - (rect1.Y - doorRect.Y), 0);
|
||||
rect1.Y = Math.Min(doorRect.Y, rect1.Y);
|
||||
|
||||
if (rect1.Height == 0)
|
||||
{
|
||||
convexHull.Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
convexHull.SetVertices(GetConvexHullCorners(rect1));
|
||||
}
|
||||
|
||||
if (convexHull2 != null)
|
||||
{
|
||||
Rectangle rect2 = doorRect;
|
||||
rect2.Y = rect2.Y + window.Y - window.Height;
|
||||
|
||||
rect2.Y += (int)(doorRect.Height * openState);
|
||||
rect2.Y = Math.Min(doorRect.Y, rect2.Y);
|
||||
rect2.Height = rect2.Y - (doorRect.Y - (int)(doorRect.Height * (1.0f - openState)));
|
||||
convexHull2.SetVertices(GetConvexHullCorners(rect2));
|
||||
|
||||
if (rect2.Height == 0)
|
||||
{
|
||||
convexHull2.Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
convexHull2.SetVertices(GetConvexHullCorners(rect2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
PhysicsBody body;
|
||||
|
||||
Sprite doorSprite;
|
||||
|
||||
public Door(Item item, XElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
//Vector2 position = new Vector2(newRect.X, newRect.Y);
|
||||
|
||||
// isOpen = false;
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
if (subElement.Name.ToString().ToLower() != "sprite") continue;
|
||||
doorSprite = new Sprite(subElement, Path.GetDirectoryName(item.Prefab.ConfigFile));
|
||||
break;
|
||||
}
|
||||
|
||||
doorRect = new Rectangle(
|
||||
item.Rect.Center.X - (int)(doorSprite.size.X / 2),
|
||||
item.Rect.Y,
|
||||
(int)doorSprite.size.X,
|
||||
(int)doorSprite.size.Y);
|
||||
|
||||
|
||||
body = new PhysicsBody(BodyFactory.CreateRectangle(Game1.world,
|
||||
ConvertUnits.ToSimUnits(Math.Max(doorRect.Width, 1)),
|
||||
ConvertUnits.ToSimUnits(Math.Max(doorRect.Height, 1)),
|
||||
1.5f));
|
||||
|
||||
body.BodyType = BodyType.Static;
|
||||
body.SetTransform(
|
||||
ConvertUnits.ToSimUnits(new Vector2(doorRect.Center.X, doorRect.Y - doorRect.Height / 2)),
|
||||
0.0f);
|
||||
body.Friction = 0.5f;
|
||||
|
||||
|
||||
//string spritePath = Path.GetDirectoryName(item.Prefab.ConfigFile) + "\\"+ ToolBox.GetAttributeString(element, "sprite", "");
|
||||
|
||||
|
||||
|
||||
isActive = true;
|
||||
|
||||
|
||||
Vector2[] corners = GetConvexHullCorners(doorRect);
|
||||
|
||||
convexHull = new ConvexHull(corners, Color.Black);
|
||||
if (window!=null) convexHull2 = new ConvexHull(corners, Color.Black);
|
||||
|
||||
OpenState = openState;
|
||||
//powerConsumption = -100.0f;
|
||||
|
||||
//LinkedGap.Open = openState;
|
||||
}
|
||||
|
||||
private Vector2[] GetConvexHullCorners(Rectangle rect)
|
||||
{
|
||||
Vector2[] corners = new Vector2[4];
|
||||
corners[0] = new Vector2(rect.X, rect.Y - rect.Height);
|
||||
corners[1] = new Vector2(rect.X, rect.Y);
|
||||
corners[2] = new Vector2(rect.Right, rect.Y);
|
||||
corners[3] = new Vector2(rect.Right, rect.Y - rect.Height);
|
||||
|
||||
return corners;
|
||||
}
|
||||
|
||||
public override void Move(Vector2 amount)
|
||||
{
|
||||
base.Move(amount);
|
||||
|
||||
linkedGap.Move(amount);
|
||||
|
||||
body.SetTransform(body.Position + ConvertUnits.ToSimUnits(amount), 0.0f);
|
||||
|
||||
convexHull.Move(amount);
|
||||
if (convexHull2 != null) convexHull2.Move(amount);
|
||||
}
|
||||
|
||||
|
||||
public override bool Pick(Character picker)
|
||||
{
|
||||
isActive = true;
|
||||
isOpen = !isOpen;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
OpenState += deltaTime * ((isOpen) ? 3.0f : -3.0f);
|
||||
|
||||
item.SendSignal((isOpen) ? "1" : "0", "state_out");
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
|
||||
LinkedGap.Open = openState;
|
||||
|
||||
Color color = (item.IsSelected) ? Color.Green : Color.White;
|
||||
|
||||
//prefab.sprite.Draw(spriteBatch, new Vector2(rect.X, -rect.Y), new Vector2(rect.Width, rect.Height), color);
|
||||
|
||||
if (openState == 1.0f)
|
||||
{
|
||||
body.Enabled = false;
|
||||
convexHull.Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
spriteBatch.Draw(doorSprite.Texture, new Vector2(item.Rect.Center.X, -item.Rect.Y),
|
||||
new Rectangle(doorSprite.SourceRect.X, (int)(doorSprite.size.Y * openState),
|
||||
(int)doorSprite.size.X, (int)(doorSprite.size.Y * (1.0f - openState))),
|
||||
color, 0.0f, doorSprite.Origin, 1.0f, SpriteEffects.None, doorSprite.Depth);
|
||||
|
||||
convexHull.Enabled = true;
|
||||
|
||||
if (openState == 0.0f)
|
||||
{
|
||||
body.Enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//push characters out of the doorway when the door is closing/opening
|
||||
Vector2 simPos = ConvertUnits.ToSimUnits(new Vector2(item.Rect.X, item.Rect.Y));
|
||||
Vector2 simSize = ConvertUnits.ToSimUnits(new Vector2(item.Rect.Width,
|
||||
item.Rect.Height * (1.0f - openState)));
|
||||
|
||||
foreach (Character c in Character.characterList)
|
||||
{
|
||||
int dir = Math.Sign(c.animController.limbs[0].SimPosition.X - simPos.X);
|
||||
foreach (Limb l in c.animController.limbs)
|
||||
{
|
||||
if (l.SimPosition.Y < simPos.Y || l.SimPosition.Y > simPos.Y - simSize.Y) continue;
|
||||
if (Math.Abs(l.SimPosition.X - simPos.X) > simSize.X * 2.0f) continue;
|
||||
|
||||
l.body.ApplyForce(new Vector2(dir * 10.0f, 0.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Remove()
|
||||
{
|
||||
base.Remove();
|
||||
|
||||
Game1.world.RemoveBody(body.FarseerBody);
|
||||
|
||||
linkedGap.Remove();
|
||||
|
||||
doorSprite.Remove();
|
||||
|
||||
convexHull.Remove();
|
||||
if (convexHull2 != null) convexHull2.Remove();
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(string signal, Connection connection, Item sender)
|
||||
{
|
||||
isActive = true;
|
||||
if (connection.name=="toggle")
|
||||
{
|
||||
isOpen = !isOpen;
|
||||
}
|
||||
else if (connection.name == "set_state")
|
||||
{
|
||||
isOpen = (signal!="0");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,219 +1,218 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml.Linq;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class ItemPrefab : MapEntityPrefab
|
||||
{
|
||||
static string contentFolder = "Content/Items/";
|
||||
|
||||
string configFile;
|
||||
|
||||
//should the camera focus on the construction when selected
|
||||
protected bool focusOnSelected;
|
||||
//the amount of "camera offset" when selecting the construction
|
||||
protected float offsetOnSelected;
|
||||
//default size
|
||||
protected Vector2 size;
|
||||
|
||||
//how close the character has to be to the item to pick it up
|
||||
float pickDistance;
|
||||
|
||||
|
||||
public List<Sound> sounds;
|
||||
|
||||
//an area next to the construction
|
||||
//the construction can be Activated() by a character inside the area
|
||||
public List<Rectangle> triggers;
|
||||
|
||||
public string ConfigFile
|
||||
{
|
||||
get { return configFile; }
|
||||
}
|
||||
|
||||
public float PickDistance
|
||||
{
|
||||
get { return pickDistance; }
|
||||
}
|
||||
|
||||
|
||||
public override bool IsLinkable
|
||||
{
|
||||
get { return isLinkable; }
|
||||
}
|
||||
|
||||
public bool FocusOnSelected
|
||||
{
|
||||
get { return focusOnSelected; }
|
||||
}
|
||||
|
||||
public float OffsetOnSelected
|
||||
{
|
||||
get { return offsetOnSelected; }
|
||||
}
|
||||
|
||||
public override void UpdatePlacing(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
Vector2 position = new Vector2(PlayerInput.GetMouseState.X, PlayerInput.GetMouseState.Y);
|
||||
position = cam.ScreenToWorld(position);
|
||||
|
||||
if (!resizeHorizontal && !resizeVertical)
|
||||
{
|
||||
if (PlayerInput.LeftButtonClicked())
|
||||
{
|
||||
new Item(new Rectangle((int)position.X, (int)position.Y, (int)sprite.size.X, (int)sprite.size.Y), this);
|
||||
//constructor.Invoke(lobject);
|
||||
|
||||
placePosition = Vector2.Zero;
|
||||
|
||||
selected = null;
|
||||
return;
|
||||
}
|
||||
|
||||
sprite.Draw(spriteBatch, new Vector2(position.X + sprite.size.X / 2.0f, -position.Y + sprite.size.Y / 2.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 placeSize = size;
|
||||
|
||||
if (placePosition == Vector2.Zero)
|
||||
{
|
||||
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed)
|
||||
placePosition = position;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (resizeHorizontal)
|
||||
placeSize.X = Math.Max(position.X - placePosition.X, size.X);
|
||||
if (resizeVertical)
|
||||
placeSize.Y = Math.Max(placePosition.Y - position.Y, size.Y);
|
||||
|
||||
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Released)
|
||||
{
|
||||
new Item(new Rectangle((int)placePosition.X, (int)placePosition.Y, (int)placeSize.X, (int)placeSize.Y), this);
|
||||
|
||||
selected = null;
|
||||
return;
|
||||
}
|
||||
|
||||
position = placePosition;
|
||||
}
|
||||
|
||||
sprite.DrawTiled(spriteBatch, new Vector2(position.X, -position.Y), placeSize, Color.White);
|
||||
}
|
||||
|
||||
if (PlayerInput.GetMouseState.RightButton == ButtonState.Pressed) selected = null;
|
||||
|
||||
}
|
||||
|
||||
public static void LoadAll()
|
||||
{
|
||||
string[] files = Directory.GetFiles(contentFolder, "*.xml", SearchOption.AllDirectories);
|
||||
|
||||
foreach (string filePath in files)
|
||||
{
|
||||
XDocument doc = ToolBox.TryLoadXml(filePath);
|
||||
if (doc == null) return;
|
||||
|
||||
if (doc.Root.Name.ToString().ToLower() == "item")
|
||||
{
|
||||
new ItemPrefab(doc.Root, filePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (XElement element in doc.Root.Elements())
|
||||
{
|
||||
if (element.Name.ToString().ToLower() != "item") continue;
|
||||
|
||||
new ItemPrefab(element, filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ItemPrefab (XElement element, string filePath)
|
||||
{
|
||||
|
||||
configFile = filePath;
|
||||
|
||||
name = ToolBox.GetAttributeString(element, "name", "");
|
||||
if (name == "") DebugConsole.ThrowError("Unnamed item in "+filePath+"!");
|
||||
|
||||
//if (element.Attribute("sprite") != null)
|
||||
//{
|
||||
// sprite = new Sprite(Path.GetDirectoryName(filePath) + "/" + element.Attribute("sprite").Value, new Vector2(0.5f, 0.5f));
|
||||
// sprite.Depth = 0.5f;
|
||||
//}
|
||||
|
||||
//var initableProperties = GetProperties<Initable>();
|
||||
//foreach (ObjectProperty initableProperty in initableProperties)
|
||||
//{
|
||||
// object value = ToolBox.GetAttributeObject(element, initableProperty.Name.ToLower());
|
||||
// if (value == null)
|
||||
// {
|
||||
// foreach (var ini in initableProperty.Attributes.OfType<Initable>())
|
||||
// {
|
||||
// value = ini.defaultValue;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// initableProperty.TrySetValue(value);
|
||||
//}
|
||||
|
||||
pickDistance = ConvertUnits.ToSimUnits(ToolBox.GetAttributeFloat(element, "pickdistance", 0.0f));
|
||||
|
||||
isLinkable = ToolBox.GetAttributeBool(element, "linkable", false);
|
||||
|
||||
resizeHorizontal = ToolBox.GetAttributeBool(element, "resizehorizontal", false);
|
||||
resizeVertical = ToolBox.GetAttributeBool(element, "resizevertical", false);
|
||||
|
||||
focusOnSelected = ToolBox.GetAttributeBool(element, "focusonselected", false);
|
||||
|
||||
offsetOnSelected = ToolBox.GetAttributeFloat(element, "offsetonselected", 0.0f);
|
||||
|
||||
triggers = new List<Rectangle>();
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLower())
|
||||
{
|
||||
case "sprite":
|
||||
sprite = new Sprite(subElement, Path.GetDirectoryName(filePath) + "/");
|
||||
size = sprite.size;
|
||||
break;
|
||||
case "trigger":
|
||||
Rectangle trigger = new Rectangle(0, 0, 10,10);
|
||||
|
||||
trigger.X = ToolBox.GetAttributeInt(subElement, "x", 0);
|
||||
trigger.Y = ToolBox.GetAttributeInt(subElement, "y", 0);
|
||||
|
||||
trigger.Width = ToolBox.GetAttributeInt(subElement, "width", 0);
|
||||
trigger.Height = ToolBox.GetAttributeInt(subElement, "height", 0);
|
||||
|
||||
triggers.Add(trigger);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sounds = new List<Sound>();
|
||||
var soundElements = element.Descendants("Sound");
|
||||
foreach (XElement soundElement in soundElements)
|
||||
{
|
||||
string soundPath = ToolBox.GetAttributeString(soundElement, "path", "");
|
||||
if (soundPath == "") continue;
|
||||
|
||||
Sound sound = Sound.Load(soundPath);
|
||||
if (sound != null) sounds.Add(sound);
|
||||
}
|
||||
|
||||
list.Add(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml.Linq;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class ItemPrefab : MapEntityPrefab
|
||||
{
|
||||
static string contentFolder = "Content/Items/";
|
||||
|
||||
string configFile;
|
||||
|
||||
//should the camera focus on the construction when selected
|
||||
protected bool focusOnSelected;
|
||||
//the amount of "camera offset" when selecting the construction
|
||||
protected float offsetOnSelected;
|
||||
//default size
|
||||
protected Vector2 size;
|
||||
|
||||
//how close the character has to be to the item to pick it up
|
||||
float pickDistance;
|
||||
|
||||
|
||||
public List<Sound> sounds;
|
||||
|
||||
//an area next to the construction
|
||||
//the construction can be Activated() by a character inside the area
|
||||
public List<Rectangle> triggers;
|
||||
|
||||
public string ConfigFile
|
||||
{
|
||||
get { return configFile; }
|
||||
}
|
||||
|
||||
public float PickDistance
|
||||
{
|
||||
get { return pickDistance; }
|
||||
}
|
||||
|
||||
|
||||
public override bool IsLinkable
|
||||
{
|
||||
get { return isLinkable; }
|
||||
}
|
||||
|
||||
public bool FocusOnSelected
|
||||
{
|
||||
get { return focusOnSelected; }
|
||||
}
|
||||
|
||||
public float OffsetOnSelected
|
||||
{
|
||||
get { return offsetOnSelected; }
|
||||
}
|
||||
|
||||
public override void UpdatePlacing(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
Vector2 position = Map.MouseToWorldGrid(cam);
|
||||
|
||||
if (!resizeHorizontal && !resizeVertical)
|
||||
{
|
||||
if (PlayerInput.LeftButtonClicked())
|
||||
{
|
||||
new Item(new Rectangle((int)position.X, (int)position.Y, (int)sprite.size.X, (int)sprite.size.Y), this);
|
||||
//constructor.Invoke(lobject);
|
||||
|
||||
placePosition = Vector2.Zero;
|
||||
|
||||
selected = null;
|
||||
return;
|
||||
}
|
||||
|
||||
sprite.Draw(spriteBatch, new Vector2(position.X + sprite.size.X / 2.0f, -position.Y + sprite.size.Y / 2.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 placeSize = size;
|
||||
|
||||
if (placePosition == Vector2.Zero)
|
||||
{
|
||||
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed)
|
||||
placePosition = position;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (resizeHorizontal)
|
||||
placeSize.X = Math.Max(position.X - placePosition.X, size.X);
|
||||
if (resizeVertical)
|
||||
placeSize.Y = Math.Max(placePosition.Y - position.Y, size.Y);
|
||||
|
||||
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Released)
|
||||
{
|
||||
new Item(new Rectangle((int)placePosition.X, (int)placePosition.Y, (int)placeSize.X, (int)placeSize.Y), this);
|
||||
|
||||
selected = null;
|
||||
return;
|
||||
}
|
||||
|
||||
position = placePosition;
|
||||
}
|
||||
|
||||
sprite.DrawTiled(spriteBatch, new Vector2(position.X, -position.Y), placeSize, Color.White);
|
||||
}
|
||||
|
||||
if (PlayerInput.GetMouseState.RightButton == ButtonState.Pressed) selected = null;
|
||||
|
||||
}
|
||||
|
||||
public static void LoadAll()
|
||||
{
|
||||
string[] files = Directory.GetFiles(contentFolder, "*.xml", SearchOption.AllDirectories);
|
||||
|
||||
foreach (string filePath in files)
|
||||
{
|
||||
XDocument doc = ToolBox.TryLoadXml(filePath);
|
||||
if (doc == null) return;
|
||||
|
||||
if (doc.Root.Name.ToString().ToLower() == "item")
|
||||
{
|
||||
new ItemPrefab(doc.Root, filePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (XElement element in doc.Root.Elements())
|
||||
{
|
||||
if (element.Name.ToString().ToLower() != "item") continue;
|
||||
|
||||
new ItemPrefab(element, filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ItemPrefab (XElement element, string filePath)
|
||||
{
|
||||
|
||||
configFile = filePath;
|
||||
|
||||
name = ToolBox.GetAttributeString(element, "name", "");
|
||||
if (name == "") DebugConsole.ThrowError("Unnamed item in "+filePath+"!");
|
||||
|
||||
//if (element.Attribute("sprite") != null)
|
||||
//{
|
||||
// sprite = new Sprite(Path.GetDirectoryName(filePath) + "/" + element.Attribute("sprite").Value, new Vector2(0.5f, 0.5f));
|
||||
// sprite.Depth = 0.5f;
|
||||
//}
|
||||
|
||||
//var initableProperties = GetProperties<Initable>();
|
||||
//foreach (ObjectProperty initableProperty in initableProperties)
|
||||
//{
|
||||
// object value = ToolBox.GetAttributeObject(element, initableProperty.Name.ToLower());
|
||||
// if (value == null)
|
||||
// {
|
||||
// foreach (var ini in initableProperty.Attributes.OfType<Initable>())
|
||||
// {
|
||||
// value = ini.defaultValue;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// initableProperty.TrySetValue(value);
|
||||
//}
|
||||
|
||||
pickDistance = ConvertUnits.ToSimUnits(ToolBox.GetAttributeFloat(element, "pickdistance", 0.0f));
|
||||
|
||||
isLinkable = ToolBox.GetAttributeBool(element, "linkable", false);
|
||||
|
||||
resizeHorizontal = ToolBox.GetAttributeBool(element, "resizehorizontal", false);
|
||||
resizeVertical = ToolBox.GetAttributeBool(element, "resizevertical", false);
|
||||
|
||||
focusOnSelected = ToolBox.GetAttributeBool(element, "focusonselected", false);
|
||||
|
||||
offsetOnSelected = ToolBox.GetAttributeFloat(element, "offsetonselected", 0.0f);
|
||||
|
||||
triggers = new List<Rectangle>();
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLower())
|
||||
{
|
||||
case "sprite":
|
||||
sprite = new Sprite(subElement, Path.GetDirectoryName(filePath) + "/");
|
||||
size = sprite.size;
|
||||
break;
|
||||
case "trigger":
|
||||
Rectangle trigger = new Rectangle(0, 0, 10,10);
|
||||
|
||||
trigger.X = ToolBox.GetAttributeInt(subElement, "x", 0);
|
||||
trigger.Y = ToolBox.GetAttributeInt(subElement, "y", 0);
|
||||
|
||||
trigger.Width = ToolBox.GetAttributeInt(subElement, "width", 0);
|
||||
trigger.Height = ToolBox.GetAttributeInt(subElement, "height", 0);
|
||||
|
||||
triggers.Add(trigger);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sounds = new List<Sound>();
|
||||
var soundElements = element.Descendants("Sound");
|
||||
foreach (XElement soundElement in soundElements)
|
||||
{
|
||||
string soundPath = ToolBox.GetAttributeString(soundElement, "path", "");
|
||||
if (soundPath == "") continue;
|
||||
|
||||
Sound sound = Sound.Load(soundPath);
|
||||
if (sound != null) sounds.Add(sound);
|
||||
}
|
||||
|
||||
list.Add(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,436 +1,436 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
|
||||
class Hull : MapEntity
|
||||
{
|
||||
public static List<Hull> hullList = new List<Hull>();
|
||||
|
||||
public static bool EditWater;
|
||||
|
||||
public static WaterRenderer renderer;
|
||||
|
||||
public static bool DebugDraw;
|
||||
|
||||
public const float OxygenDistributionSpeed = 500.0f;
|
||||
public const float OxygenDetoriationSpeed = 0.3f;
|
||||
public const float OxygenConsumptionSpeed = 1000.0f;
|
||||
|
||||
public const int WaveWidth = 16;
|
||||
const float WaveStiffness = 0.003f;
|
||||
const float WaveSpread = 0.05f;
|
||||
const float WaveDampening = 0.01f;
|
||||
|
||||
//how much excess water the room can contain (= more than the volume of the room)
|
||||
public const float MaxCompress = 10000f;
|
||||
|
||||
public readonly Dictionary<string, PropertyDescriptor> properties;
|
||||
|
||||
float lethalPressure;
|
||||
|
||||
float surface;
|
||||
float volume;
|
||||
float pressure;
|
||||
|
||||
float oxygen;
|
||||
|
||||
bool update;
|
||||
|
||||
float[] waveY; //displacement from the surface of the water
|
||||
float[] waveVel; //velocity of the point
|
||||
|
||||
float[] leftDelta;
|
||||
float[] rightDelta;
|
||||
|
||||
public override bool IsLinkable
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public float LethalPressure
|
||||
{
|
||||
get { return lethalPressure; }
|
||||
set { lethalPressure = MathHelper.Clamp(value, 0.0f, 100.0f); }
|
||||
}
|
||||
|
||||
public Vector2 Size
|
||||
{
|
||||
get { return new Vector2(rect.Width, rect.Height); }
|
||||
}
|
||||
|
||||
public float Surface
|
||||
{
|
||||
get { return surface; }
|
||||
}
|
||||
|
||||
public float Volume
|
||||
{
|
||||
get { return volume; }
|
||||
set
|
||||
{
|
||||
volume = MathHelper.Clamp(value, 0.0f, FullVolume + MaxCompress);
|
||||
if (volume < FullVolume) Pressure = rect.Y - rect.Height + volume / rect.Width;
|
||||
if (volume > 0.0f) update = true;
|
||||
}
|
||||
}
|
||||
|
||||
public float Oxygen
|
||||
{
|
||||
get { return oxygen; }
|
||||
set { oxygen = MathHelper.Clamp(value, 0.0f, FullVolume); }
|
||||
}
|
||||
|
||||
public float OxygenPercentage
|
||||
{
|
||||
get { return oxygen / FullVolume * 100.0f; }
|
||||
set { Oxygen = (value / 100.0f) * FullVolume; }
|
||||
}
|
||||
|
||||
public float FullVolume
|
||||
{
|
||||
get { return (rect.Width * rect.Height); }
|
||||
}
|
||||
|
||||
public float Pressure
|
||||
{
|
||||
get { return pressure; }
|
||||
set { pressure = value; }
|
||||
}
|
||||
|
||||
public float[] WaveY
|
||||
{
|
||||
get { return waveY; }
|
||||
}
|
||||
|
||||
public float[] WaveVel
|
||||
{
|
||||
get { return waveVel; }
|
||||
}
|
||||
|
||||
public Hull(Rectangle rectangle)
|
||||
{
|
||||
rect = rectangle;
|
||||
|
||||
OxygenPercentage = (float)(Game1.random.NextDouble() * 100.0);
|
||||
|
||||
properties = TypeDescriptor.GetProperties(this.GetType())
|
||||
.Cast<PropertyDescriptor>()
|
||||
.ToDictionary(pr => pr.Name);
|
||||
|
||||
int arraySize = (rectangle.Width / WaveWidth + 1);
|
||||
waveY = new float[arraySize];
|
||||
waveVel = new float[arraySize];
|
||||
|
||||
leftDelta = new float[arraySize];
|
||||
rightDelta = new float[arraySize];
|
||||
|
||||
surface = rect.Y - rect.Height;
|
||||
|
||||
aiTarget = new AITarget(this);
|
||||
aiTarget.SightRange = (rect.Width + rect.Height)*10.0f;
|
||||
|
||||
hullList.Add(this);
|
||||
|
||||
Item.UpdateHulls();
|
||||
Gap.UpdateHulls();
|
||||
|
||||
Volume = 0.0f;
|
||||
|
||||
//add to list of entities as well
|
||||
mapEntityList.Add(this);
|
||||
}
|
||||
|
||||
public override bool Contains(Vector2 position)
|
||||
{
|
||||
return (Map.RectContains(rect, position) &&
|
||||
!Map.RectContains(new Rectangle(rect.X + 8, rect.Y - 8, rect.Width -16, rect.Height -16), position));
|
||||
}
|
||||
|
||||
public int GetWaveIndex(Vector2 position)
|
||||
{
|
||||
int index = (int)(position.X - rect.X) / WaveWidth;
|
||||
index = MathHelper.Clamp(index, 0, waveY.Length-1);
|
||||
return index;
|
||||
}
|
||||
|
||||
public override void Move(Vector2 amount)
|
||||
{
|
||||
rect.X += (int)amount.X;
|
||||
rect.Y += (int)amount.Y;
|
||||
|
||||
Item.UpdateHulls();
|
||||
Gap.UpdateHulls();
|
||||
}
|
||||
|
||||
public override void Remove()
|
||||
{
|
||||
base.Remove();
|
||||
|
||||
Item.UpdateHulls();
|
||||
Gap.UpdateHulls();
|
||||
|
||||
//renderer.Dispose();
|
||||
|
||||
hullList.Remove(this);
|
||||
}
|
||||
|
||||
public override void Update(Camera cam, float deltaTime)
|
||||
{
|
||||
Oxygen -= OxygenDetoriationSpeed * deltaTime;
|
||||
|
||||
if (EditWater)
|
||||
{
|
||||
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||
if (Map.RectContains(rect, position))
|
||||
{
|
||||
if (PlayerInput.LeftButtonDown())
|
||||
{
|
||||
waveY[(int)(position.X - rect.X) / Hull.WaveWidth] = 100.0f;
|
||||
Volume = Volume + 1500.0f;
|
||||
}
|
||||
else if (PlayerInput.GetMouseState.RightButton == Microsoft.Xna.Framework.Input.ButtonState.Pressed)
|
||||
{
|
||||
Volume = Volume - 1500.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!update) return;
|
||||
|
||||
float surfaceY = rect.Y - rect.Height + Volume / rect.Width;
|
||||
for (int i = 0; i < waveY.Length; i++)
|
||||
{
|
||||
float maxDelta = Math.Max(Math.Abs(rightDelta[i]), Math.Abs(leftDelta[i]));
|
||||
if (maxDelta > ToolBox.RandomFloat(0.2f,10.0f))
|
||||
{
|
||||
Game1.particleManager.CreateParticle(ConvertUnits.ToSimUnits(new Vector2(rect.X + WaveWidth * i,surface + waveY[i])),
|
||||
0.0f, new Vector2(0.0f, waveVel[i]/10.0f-1.0f), "mist");
|
||||
}
|
||||
|
||||
waveY[i] = waveY[i] + waveVel[i];
|
||||
|
||||
if (surfaceY + waveY[i] > rect.Y)
|
||||
{
|
||||
waveY[i] -= (surfaceY + waveY[i]) - rect.Y;
|
||||
waveVel[i] = waveVel[i] * -0.5f;
|
||||
}
|
||||
else if (surfaceY + waveY[i] < rect.Y - rect.Height)
|
||||
{
|
||||
waveY[i] -= (surfaceY + waveY[i]) - (rect.Y - rect.Height);
|
||||
waveVel[i] = waveVel[i] * -0.5f;
|
||||
}
|
||||
|
||||
|
||||
//acceleration
|
||||
float a = -WaveStiffness * waveY[i] - waveVel[i] * WaveDampening;
|
||||
waveVel[i] = waveVel[i] + a;
|
||||
|
||||
}
|
||||
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
for (int i = 1; i < waveY.Length - 1; i++)
|
||||
{
|
||||
leftDelta[i] = WaveSpread * (waveY[i] - waveY[i - 1]);
|
||||
waveVel[i - 1] = waveVel[i - 1] + leftDelta[i];
|
||||
|
||||
rightDelta[i] = WaveSpread * (waveY[i] - waveY[i + 1]);
|
||||
waveVel[i + 1] = waveVel[i + 1] + rightDelta[i];
|
||||
}
|
||||
|
||||
for (int i = 1; i < waveY.Length - 1; i++)
|
||||
{
|
||||
waveY[i - 1] = waveY[i - 1] + leftDelta[i];
|
||||
waveY[i + 1] = waveY[i + 1] + rightDelta[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (volume<FullVolume)
|
||||
{
|
||||
LethalPressure -= 0.5f;
|
||||
if (Volume == 0.0f)
|
||||
{
|
||||
for (int i = 1; i < waveY.Length - 1; i++)
|
||||
{
|
||||
if (waveY[i] > 0.1f) return;
|
||||
}
|
||||
update = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LethalPressure += 1.0f;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch, bool editing)
|
||||
{
|
||||
if (!editing && !DebugDraw) return;
|
||||
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Vector2(rect.X, -rect.Y),
|
||||
new Vector2(rect.Width, rect.Height),
|
||||
isHighlighted ? Color.Green : Color.Blue);
|
||||
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Rectangle(rect.X, -rect.Y, rect.Width, rect.Height),
|
||||
Color.Red*((100.0f-OxygenPercentage)/400.0f), true);
|
||||
|
||||
spriteBatch.DrawString(GUI.font, "Pressure: " + ((int)pressure - rect.Y).ToString() +
|
||||
" - Lethality: " + lethalPressure +
|
||||
" - Oxygen: "+((int)OxygenPercentage).ToString(), new Vector2(rect.X+10, -rect.Y+10), Color.Black);
|
||||
spriteBatch.DrawString(GUI.font, volume.ToString() +" / "+ FullVolume.ToString(), new Vector2(rect.X+10, -rect.Y+30), Color.Black);
|
||||
|
||||
if (isSelected && editing)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Vector2(rect.X - 5, -rect.Y - 5),
|
||||
new Vector2(rect.Width + 10, rect.Height + 10),
|
||||
Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
public void Render(GraphicsDevice graphicsDevice, Camera cam)
|
||||
{
|
||||
if (renderer.positionInBuffer > renderer.vertices.Length - 6) return;
|
||||
|
||||
//calculate where the surface should be based on the water volume
|
||||
float top = rect.Y;
|
||||
float bottom = rect.Y - rect.Height;
|
||||
float surfaceY = bottom + Volume / rect.Width;
|
||||
|
||||
//interpolate the position of the rendered surface towards the "target surface"
|
||||
surface = surface + (surfaceY - surface) / 10.0f;
|
||||
|
||||
Matrix transform =
|
||||
cam.Transform
|
||||
* Matrix.CreateOrthographic(Game1.GraphicsWidth, Game1.GraphicsHeight, -1, 1) * 0.5f;
|
||||
|
||||
if (bottom > cam.WorldView.Y || top < cam.WorldView.Y - cam.WorldView.Height) return;
|
||||
|
||||
if (!update)
|
||||
{
|
||||
// create the four corners of our triangle.
|
||||
Vector3 p1 = new Vector3(rect.X, top, 0.0f);
|
||||
Vector3 p2 = new Vector3(rect.X + rect.Width, top, 0.0f);
|
||||
|
||||
Vector3 p3 = new Vector3(p2.X, bottom, 0.0f);
|
||||
Vector3 p4 = new Vector3(p1.X, bottom, 0.0f);
|
||||
|
||||
renderer.vertices[renderer.positionInBuffer] = new WaterVertex(p1, new Vector2(p1.X, -p1.Y), transform);
|
||||
renderer.vertices[renderer.positionInBuffer + 1] = new WaterVertex(p2, new Vector2(p2.X, -p2.Y), transform);
|
||||
renderer.vertices[renderer.positionInBuffer + 2] = new WaterVertex(p3, new Vector2(p3.X, -p3.Y), transform);
|
||||
|
||||
renderer.vertices[renderer.positionInBuffer + 3] = new WaterVertex(p1, new Vector2(p1.X, -p1.Y), transform);
|
||||
renderer.vertices[renderer.positionInBuffer + 4] = new WaterVertex(p3, new Vector2(p3.X, -p3.Y), transform);
|
||||
renderer.vertices[renderer.positionInBuffer + 5] = new WaterVertex(p4, new Vector2(p4.X, -p4.Y), transform);
|
||||
|
||||
renderer.positionInBuffer += 6;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int x = rect.X;
|
||||
int start = (int)Math.Floor((float)(cam.WorldView.X - x) / WaveWidth);
|
||||
start = Math.Max(start, 0);
|
||||
|
||||
int end = (waveY.Length - 1)
|
||||
- (int)Math.Floor((float)((x + rect.Width) - (cam.WorldView.X + cam.WorldView.Width)) / WaveWidth);
|
||||
end = Math.Min(end, waveY.Length - 1);
|
||||
|
||||
x += start * WaveWidth;
|
||||
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
if (renderer.positionInBuffer > renderer.vertices.Length - 6) return;
|
||||
|
||||
Vector3 p1 = new Vector3(x, top, 0.0f);
|
||||
Vector3 p4 = new Vector3(p1.X, surface + waveY[i], 0.0f);
|
||||
|
||||
//skip adjacent "water rects" if the surface of the water is roughly at the same position
|
||||
int width = WaveWidth;
|
||||
while (i<end-1 && Math.Abs(waveY[i + 1] - waveY[i]) < 1.0f)
|
||||
{
|
||||
width += WaveWidth;
|
||||
i++;
|
||||
}
|
||||
|
||||
Vector3 p2 = new Vector3(x + width, top, 0.0f);
|
||||
Vector3 p3 = new Vector3(p2.X, surface + waveY[i+1], 0.0f);
|
||||
|
||||
renderer.vertices[renderer.positionInBuffer] = new WaterVertex(p1, new Vector2(p1.X, -p1.Y), transform);
|
||||
renderer.vertices[renderer.positionInBuffer + 1] = new WaterVertex(p2, new Vector2(p2.X, -p2.Y), transform);
|
||||
renderer.vertices[renderer.positionInBuffer + 2] = new WaterVertex(p3, new Vector2(p3.X, -p3.Y), transform);
|
||||
|
||||
renderer.vertices[renderer.positionInBuffer + 3] = new WaterVertex(p1, new Vector2(p1.X, -p1.Y), transform);
|
||||
renderer.vertices[renderer.positionInBuffer + 4] = new WaterVertex(p3, new Vector2(p3.X, -p3.Y), transform);
|
||||
renderer.vertices[renderer.positionInBuffer + 5] = new WaterVertex(p4, new Vector2(p4.X, -p4.Y), transform);
|
||||
|
||||
renderer.positionInBuffer += 6;
|
||||
|
||||
x += width;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//returns the water block which contains the point (or null if it isn't inside any)
|
||||
public static Hull FindHull(Vector2 position, Hull guess = null)
|
||||
{
|
||||
if (guess != null && hullList.Contains(guess))
|
||||
{
|
||||
if (Map.RectContains(guess.rect, position)) return guess;
|
||||
}
|
||||
|
||||
foreach (Hull w in hullList)
|
||||
{
|
||||
if (Map.RectContains(w.rect, position)) return w;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override XElement Save(XDocument doc)
|
||||
{
|
||||
XElement element = new XElement("Hull");
|
||||
|
||||
element.Add(new XAttribute("ID", ID),
|
||||
new XAttribute("x", rect.X),
|
||||
new XAttribute("y", rect.Y),
|
||||
new XAttribute("width", rect.Width),
|
||||
new XAttribute("height", rect.Height),
|
||||
new XAttribute("water", volume));
|
||||
|
||||
doc.Root.Add(element);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public static void Load(XElement element)
|
||||
{
|
||||
Rectangle rect = new Rectangle(
|
||||
int.Parse(element.Attribute("x").Value),
|
||||
int.Parse(element.Attribute("y").Value),
|
||||
int.Parse(element.Attribute("width").Value),
|
||||
int.Parse(element.Attribute("height").Value));
|
||||
|
||||
Hull h = new Hull(rect);
|
||||
|
||||
h.volume = ToolBox.GetAttributeFloat(element, "pressure", 0.0f);
|
||||
|
||||
h.ID = int.Parse(element.Attribute("ID").Value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
|
||||
class Hull : MapEntity
|
||||
{
|
||||
public static List<Hull> hullList = new List<Hull>();
|
||||
|
||||
public static bool EditWater;
|
||||
|
||||
public static WaterRenderer renderer;
|
||||
|
||||
public static bool DebugDraw;
|
||||
|
||||
public const float OxygenDistributionSpeed = 500.0f;
|
||||
public const float OxygenDetoriationSpeed = 0.3f;
|
||||
public const float OxygenConsumptionSpeed = 1000.0f;
|
||||
|
||||
public const int WaveWidth = 16;
|
||||
const float WaveStiffness = 0.003f;
|
||||
const float WaveSpread = 0.05f;
|
||||
const float WaveDampening = 0.01f;
|
||||
|
||||
//how much excess water the room can contain (= more than the volume of the room)
|
||||
public const float MaxCompress = 10000f;
|
||||
|
||||
public readonly Dictionary<string, PropertyDescriptor> properties;
|
||||
|
||||
float lethalPressure;
|
||||
|
||||
float surface;
|
||||
float volume;
|
||||
float pressure;
|
||||
|
||||
float oxygen;
|
||||
|
||||
bool update;
|
||||
|
||||
float[] waveY; //displacement from the surface of the water
|
||||
float[] waveVel; //velocity of the point
|
||||
|
||||
float[] leftDelta;
|
||||
float[] rightDelta;
|
||||
|
||||
public override bool IsLinkable
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public float LethalPressure
|
||||
{
|
||||
get { return lethalPressure; }
|
||||
set { lethalPressure = MathHelper.Clamp(value, 0.0f, 100.0f); }
|
||||
}
|
||||
|
||||
public Vector2 Size
|
||||
{
|
||||
get { return new Vector2(rect.Width, rect.Height); }
|
||||
}
|
||||
|
||||
public float Surface
|
||||
{
|
||||
get { return surface; }
|
||||
}
|
||||
|
||||
public float Volume
|
||||
{
|
||||
get { return volume; }
|
||||
set
|
||||
{
|
||||
volume = MathHelper.Clamp(value, 0.0f, FullVolume + MaxCompress);
|
||||
if (volume < FullVolume) Pressure = rect.Y - rect.Height + volume / rect.Width;
|
||||
if (volume > 0.0f) update = true;
|
||||
}
|
||||
}
|
||||
|
||||
public float Oxygen
|
||||
{
|
||||
get { return oxygen; }
|
||||
set { oxygen = MathHelper.Clamp(value, 0.0f, FullVolume); }
|
||||
}
|
||||
|
||||
public float OxygenPercentage
|
||||
{
|
||||
get { return oxygen / FullVolume * 100.0f; }
|
||||
set { Oxygen = (value / 100.0f) * FullVolume; }
|
||||
}
|
||||
|
||||
public float FullVolume
|
||||
{
|
||||
get { return (rect.Width * rect.Height); }
|
||||
}
|
||||
|
||||
public float Pressure
|
||||
{
|
||||
get { return pressure; }
|
||||
set { pressure = value; }
|
||||
}
|
||||
|
||||
public float[] WaveY
|
||||
{
|
||||
get { return waveY; }
|
||||
}
|
||||
|
||||
public float[] WaveVel
|
||||
{
|
||||
get { return waveVel; }
|
||||
}
|
||||
|
||||
public Hull(Rectangle rectangle)
|
||||
{
|
||||
rect = rectangle;
|
||||
|
||||
OxygenPercentage = (float)(Game1.random.NextDouble() * 100.0);
|
||||
|
||||
properties = TypeDescriptor.GetProperties(this.GetType())
|
||||
.Cast<PropertyDescriptor>()
|
||||
.ToDictionary(pr => pr.Name);
|
||||
|
||||
int arraySize = (rectangle.Width / WaveWidth + 1);
|
||||
waveY = new float[arraySize];
|
||||
waveVel = new float[arraySize];
|
||||
|
||||
leftDelta = new float[arraySize];
|
||||
rightDelta = new float[arraySize];
|
||||
|
||||
surface = rect.Y - rect.Height;
|
||||
|
||||
aiTarget = new AITarget(this);
|
||||
aiTarget.SightRange = (rect.Width + rect.Height)*10.0f;
|
||||
|
||||
hullList.Add(this);
|
||||
|
||||
Item.UpdateHulls();
|
||||
Gap.UpdateHulls();
|
||||
|
||||
Volume = 0.0f;
|
||||
|
||||
//add to list of entities as well
|
||||
mapEntityList.Add(this);
|
||||
}
|
||||
|
||||
public override bool Contains(Vector2 position)
|
||||
{
|
||||
return (Map.RectContains(rect, position) &&
|
||||
!Map.RectContains(new Rectangle(rect.X + 8, rect.Y - 8, rect.Width - 16, rect.Height - 16), position));
|
||||
}
|
||||
|
||||
public int GetWaveIndex(Vector2 position)
|
||||
{
|
||||
int index = (int)(position.X - rect.X) / WaveWidth;
|
||||
index = MathHelper.Clamp(index, 0, waveY.Length-1);
|
||||
return index;
|
||||
}
|
||||
|
||||
public override void Move(Vector2 amount)
|
||||
{
|
||||
rect.X += (int)amount.X;
|
||||
rect.Y += (int)amount.Y;
|
||||
|
||||
Item.UpdateHulls();
|
||||
Gap.UpdateHulls();
|
||||
}
|
||||
|
||||
public override void Remove()
|
||||
{
|
||||
base.Remove();
|
||||
|
||||
Item.UpdateHulls();
|
||||
Gap.UpdateHulls();
|
||||
|
||||
//renderer.Dispose();
|
||||
|
||||
hullList.Remove(this);
|
||||
}
|
||||
|
||||
public override void Update(Camera cam, float deltaTime)
|
||||
{
|
||||
Oxygen -= OxygenDetoriationSpeed * deltaTime;
|
||||
|
||||
if (EditWater)
|
||||
{
|
||||
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||
if (Map.RectContains(rect, position))
|
||||
{
|
||||
if (PlayerInput.LeftButtonDown())
|
||||
{
|
||||
waveY[(int)(position.X - rect.X) / Hull.WaveWidth] = 100.0f;
|
||||
Volume = Volume + 1500.0f;
|
||||
}
|
||||
else if (PlayerInput.GetMouseState.RightButton == Microsoft.Xna.Framework.Input.ButtonState.Pressed)
|
||||
{
|
||||
Volume = Volume - 1500.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!update) return;
|
||||
|
||||
float surfaceY = rect.Y - rect.Height + Volume / rect.Width;
|
||||
for (int i = 0; i < waveY.Length; i++)
|
||||
{
|
||||
float maxDelta = Math.Max(Math.Abs(rightDelta[i]), Math.Abs(leftDelta[i]));
|
||||
if (maxDelta > ToolBox.RandomFloat(0.2f,10.0f))
|
||||
{
|
||||
Game1.particleManager.CreateParticle(ConvertUnits.ToSimUnits(new Vector2(rect.X + WaveWidth * i,surface + waveY[i])),
|
||||
ToolBox.RandomFloat(0.0f,6.2f), new Vector2(0.0f, -0.5f), "mist");
|
||||
}
|
||||
|
||||
waveY[i] = waveY[i] + waveVel[i];
|
||||
|
||||
if (surfaceY + waveY[i] > rect.Y)
|
||||
{
|
||||
waveY[i] -= (surfaceY + waveY[i]) - rect.Y;
|
||||
waveVel[i] = waveVel[i] * -0.5f;
|
||||
}
|
||||
else if (surfaceY + waveY[i] < rect.Y - rect.Height)
|
||||
{
|
||||
waveY[i] -= (surfaceY + waveY[i]) - (rect.Y - rect.Height);
|
||||
waveVel[i] = waveVel[i] * -0.5f;
|
||||
}
|
||||
|
||||
|
||||
//acceleration
|
||||
float a = -WaveStiffness * waveY[i] - waveVel[i] * WaveDampening;
|
||||
waveVel[i] = waveVel[i] + a;
|
||||
|
||||
}
|
||||
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
for (int i = 1; i < waveY.Length - 1; i++)
|
||||
{
|
||||
leftDelta[i] = WaveSpread * (waveY[i] - waveY[i - 1]);
|
||||
waveVel[i - 1] = waveVel[i - 1] + leftDelta[i];
|
||||
|
||||
rightDelta[i] = WaveSpread * (waveY[i] - waveY[i + 1]);
|
||||
waveVel[i + 1] = waveVel[i + 1] + rightDelta[i];
|
||||
}
|
||||
|
||||
for (int i = 1; i < waveY.Length - 1; i++)
|
||||
{
|
||||
waveY[i - 1] = waveY[i - 1] + leftDelta[i];
|
||||
waveY[i + 1] = waveY[i + 1] + rightDelta[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (volume<FullVolume)
|
||||
{
|
||||
LethalPressure -= 0.5f;
|
||||
if (Volume == 0.0f)
|
||||
{
|
||||
for (int i = 1; i < waveY.Length - 1; i++)
|
||||
{
|
||||
if (waveY[i] > 0.1f) return;
|
||||
}
|
||||
update = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LethalPressure += 1.0f;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch, bool editing)
|
||||
{
|
||||
if (!editing && !DebugDraw) return;
|
||||
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Vector2(rect.X, -rect.Y),
|
||||
new Vector2(rect.Width, rect.Height),
|
||||
isHighlighted ? Color.Green : Color.Blue);
|
||||
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Rectangle(rect.X, -rect.Y, rect.Width, rect.Height),
|
||||
Color.Red*((100.0f-OxygenPercentage)/400.0f), true);
|
||||
|
||||
spriteBatch.DrawString(GUI.font, "Pressure: " + ((int)pressure - rect.Y).ToString() +
|
||||
" - Lethality: " + lethalPressure +
|
||||
" - Oxygen: "+((int)OxygenPercentage).ToString(), new Vector2(rect.X+10, -rect.Y+10), Color.Black);
|
||||
spriteBatch.DrawString(GUI.font, volume.ToString() +" / "+ FullVolume.ToString(), new Vector2(rect.X+10, -rect.Y+30), Color.Black);
|
||||
|
||||
if (isSelected && editing)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Vector2(rect.X - 5, -rect.Y - 5),
|
||||
new Vector2(rect.Width + 10, rect.Height + 10),
|
||||
Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
public void Render(GraphicsDevice graphicsDevice, Camera cam)
|
||||
{
|
||||
if (renderer.positionInBuffer > renderer.vertices.Length - 6) return;
|
||||
|
||||
//calculate where the surface should be based on the water volume
|
||||
float top = rect.Y;
|
||||
float bottom = rect.Y - rect.Height;
|
||||
float surfaceY = bottom + Volume / rect.Width;
|
||||
|
||||
//interpolate the position of the rendered surface towards the "target surface"
|
||||
surface = surface + (surfaceY - surface) / 10.0f;
|
||||
|
||||
Matrix transform =
|
||||
cam.Transform
|
||||
* Matrix.CreateOrthographic(Game1.GraphicsWidth, Game1.GraphicsHeight, -1, 1) * 0.5f;
|
||||
|
||||
if (bottom > cam.WorldView.Y || top < cam.WorldView.Y - cam.WorldView.Height) return;
|
||||
|
||||
if (!update)
|
||||
{
|
||||
// create the four corners of our triangle.
|
||||
Vector3 p1 = new Vector3(rect.X, top, 0.0f);
|
||||
Vector3 p2 = new Vector3(rect.X + rect.Width, top, 0.0f);
|
||||
|
||||
Vector3 p3 = new Vector3(p2.X, bottom, 0.0f);
|
||||
Vector3 p4 = new Vector3(p1.X, bottom, 0.0f);
|
||||
|
||||
renderer.vertices[renderer.positionInBuffer] = new WaterVertex(p1, new Vector2(p1.X, -p1.Y), transform);
|
||||
renderer.vertices[renderer.positionInBuffer + 1] = new WaterVertex(p2, new Vector2(p2.X, -p2.Y), transform);
|
||||
renderer.vertices[renderer.positionInBuffer + 2] = new WaterVertex(p3, new Vector2(p3.X, -p3.Y), transform);
|
||||
|
||||
renderer.vertices[renderer.positionInBuffer + 3] = new WaterVertex(p1, new Vector2(p1.X, -p1.Y), transform);
|
||||
renderer.vertices[renderer.positionInBuffer + 4] = new WaterVertex(p3, new Vector2(p3.X, -p3.Y), transform);
|
||||
renderer.vertices[renderer.positionInBuffer + 5] = new WaterVertex(p4, new Vector2(p4.X, -p4.Y), transform);
|
||||
|
||||
renderer.positionInBuffer += 6;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int x = rect.X;
|
||||
int start = (int)Math.Floor((float)(cam.WorldView.X - x) / WaveWidth);
|
||||
start = Math.Max(start, 0);
|
||||
|
||||
int end = (waveY.Length - 1)
|
||||
- (int)Math.Floor((float)((x + rect.Width) - (cam.WorldView.X + cam.WorldView.Width)) / WaveWidth);
|
||||
end = Math.Min(end, waveY.Length - 1);
|
||||
|
||||
x += start * WaveWidth;
|
||||
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
if (renderer.positionInBuffer > renderer.vertices.Length - 6) return;
|
||||
|
||||
Vector3 p1 = new Vector3(x, top, 0.0f);
|
||||
Vector3 p4 = new Vector3(p1.X, surface + waveY[i], 0.0f);
|
||||
|
||||
//skip adjacent "water rects" if the surface of the water is roughly at the same position
|
||||
int width = WaveWidth;
|
||||
while (i<end-1 && Math.Abs(waveY[i + 1] - waveY[i]) < 1.0f)
|
||||
{
|
||||
width += WaveWidth;
|
||||
i++;
|
||||
}
|
||||
|
||||
Vector3 p2 = new Vector3(x + width, top, 0.0f);
|
||||
Vector3 p3 = new Vector3(p2.X, surface + waveY[i+1], 0.0f);
|
||||
|
||||
renderer.vertices[renderer.positionInBuffer] = new WaterVertex(p1, new Vector2(p1.X, -p1.Y), transform);
|
||||
renderer.vertices[renderer.positionInBuffer + 1] = new WaterVertex(p2, new Vector2(p2.X, -p2.Y), transform);
|
||||
renderer.vertices[renderer.positionInBuffer + 2] = new WaterVertex(p3, new Vector2(p3.X, -p3.Y), transform);
|
||||
|
||||
renderer.vertices[renderer.positionInBuffer + 3] = new WaterVertex(p1, new Vector2(p1.X, -p1.Y), transform);
|
||||
renderer.vertices[renderer.positionInBuffer + 4] = new WaterVertex(p3, new Vector2(p3.X, -p3.Y), transform);
|
||||
renderer.vertices[renderer.positionInBuffer + 5] = new WaterVertex(p4, new Vector2(p4.X, -p4.Y), transform);
|
||||
|
||||
renderer.positionInBuffer += 6;
|
||||
|
||||
x += width;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//returns the water block which contains the point (or null if it isn't inside any)
|
||||
public static Hull FindHull(Vector2 position, Hull guess = null)
|
||||
{
|
||||
if (guess != null && hullList.Contains(guess))
|
||||
{
|
||||
if (Map.RectContains(guess.rect, position)) return guess;
|
||||
}
|
||||
|
||||
foreach (Hull w in hullList)
|
||||
{
|
||||
if (Map.RectContains(w.rect, position)) return w;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override XElement Save(XDocument doc)
|
||||
{
|
||||
XElement element = new XElement("Hull");
|
||||
|
||||
element.Add(new XAttribute("ID", ID),
|
||||
new XAttribute("x", rect.X),
|
||||
new XAttribute("y", rect.Y),
|
||||
new XAttribute("width", rect.Width),
|
||||
new XAttribute("height", rect.Height),
|
||||
new XAttribute("water", volume));
|
||||
|
||||
doc.Root.Add(element);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public static void Load(XElement element)
|
||||
{
|
||||
Rectangle rect = new Rectangle(
|
||||
int.Parse(element.Attribute("x").Value),
|
||||
int.Parse(element.Attribute("y").Value),
|
||||
int.Parse(element.Attribute("width").Value),
|
||||
int.Parse(element.Attribute("height").Value));
|
||||
|
||||
Hull h = new Hull(rect);
|
||||
|
||||
h.volume = ToolBox.GetAttributeFloat(element, "pressure", 0.0f);
|
||||
|
||||
h.ID = int.Parse(element.Attribute("ID").Value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,191 +1,183 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Subsurface.Lights
|
||||
{
|
||||
class ConvexHull
|
||||
{
|
||||
public static List<ConvexHull> list = new List<ConvexHull>();
|
||||
static BasicEffect drawingEffect;
|
||||
|
||||
private VertexPositionColor[] vertices;
|
||||
private short[] indices;
|
||||
int primitiveCount;
|
||||
|
||||
bool[] backFacing;
|
||||
VertexPositionColor[] shadowVertices;
|
||||
|
||||
public bool Enabled
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
//private Vector2 position = Vector2.Zero;
|
||||
//public Vector2 Position
|
||||
//{
|
||||
// get { return position; }
|
||||
// set { position = value; }
|
||||
//}
|
||||
|
||||
public ConvexHull(Vector2[] points, Color color)
|
||||
{
|
||||
int vertexCount = points.Length;
|
||||
vertices = new VertexPositionColor[vertexCount + 1];
|
||||
Vector2 center = Vector2.Zero;
|
||||
|
||||
for (int i = 0; i < vertexCount; i++)
|
||||
{
|
||||
vertices[i] = new VertexPositionColor(new Vector3(points[i], 0), color);
|
||||
center += points[i];
|
||||
}
|
||||
center /= points.Length;
|
||||
vertices[vertexCount] = new VertexPositionColor(new Vector3(center, 0), color);
|
||||
|
||||
primitiveCount = points.Length;
|
||||
indices = new short[primitiveCount * 3];
|
||||
|
||||
for (int i = 0; i < primitiveCount; i++)
|
||||
{
|
||||
indices[3 * i] = (short)i;
|
||||
indices[3 * i + 1] = (short)((i + 1) % vertexCount);
|
||||
indices[3 * i + 2] = (short)vertexCount;
|
||||
}
|
||||
backFacing = new bool[vertexCount];
|
||||
|
||||
|
||||
Enabled = true;
|
||||
|
||||
list.Add(this);
|
||||
}
|
||||
|
||||
public void Move(Vector2 amount)
|
||||
{
|
||||
for (int i = 0; i < vertices.Count(); i++)
|
||||
{
|
||||
vertices[i].Position = new Vector3(vertices[i].Position.X + amount.X, vertices[i].Position.Y + amount.Y, vertices[i].Position.Z);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetVertices(Vector2[] points)
|
||||
{
|
||||
int vertexCount = points.Length;
|
||||
vertices = new VertexPositionColor[vertexCount + 1];
|
||||
|
||||
for (int i = 0; i < vertexCount; i++)
|
||||
{
|
||||
vertices[i] = new VertexPositionColor(new Vector3(points[i], 0), Color.Black);
|
||||
}
|
||||
}
|
||||
|
||||
//public void Draw(GameTime gameTime)
|
||||
//{
|
||||
// device.RasterizerState = RasterizerState.CullNone;
|
||||
// device.BlendState = BlendState.Opaque;
|
||||
|
||||
// drawingEffect.World = Matrix.CreateTranslation(position.X, position.Y, 0);
|
||||
|
||||
// foreach (EffectPass pass in drawingEffect.CurrentTechnique.Passes)
|
||||
// {
|
||||
// pass.Apply();
|
||||
// device.DrawUserIndexedPrimitives<VertexPositionColor>(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, 0, primitiveCount);
|
||||
// }
|
||||
//}
|
||||
|
||||
public void DrawShadows(GraphicsDevice graphicsDevice, Camera cam, Vector2 lightSourcePos)
|
||||
{
|
||||
if (!Enabled) return;
|
||||
|
||||
if (drawingEffect == null)
|
||||
{
|
||||
drawingEffect = new BasicEffect(graphicsDevice);
|
||||
drawingEffect.VertexColorEnabled = true;
|
||||
}
|
||||
|
||||
//compute facing of each edge, using N*L
|
||||
for (int i = 0; i < primitiveCount; i++)
|
||||
{
|
||||
Vector2 firstVertex = new Vector2(vertices[i].Position.X, vertices[i].Position.Y);
|
||||
int secondIndex = (i + 1) % primitiveCount;
|
||||
Vector2 secondVertex = new Vector2(vertices[secondIndex].Position.X, vertices[secondIndex].Position.Y);
|
||||
Vector2 middle = (firstVertex + secondVertex) / 2;
|
||||
|
||||
Vector2 L = lightSourcePos - middle;
|
||||
|
||||
Vector2 N = new Vector2();
|
||||
N.X = -(secondVertex.Y - firstVertex.Y);
|
||||
N.Y = secondVertex.X - firstVertex.X;
|
||||
|
||||
backFacing[i] = (Vector2.Dot(N, L) < 0);
|
||||
}
|
||||
|
||||
//find beginning and ending vertices which
|
||||
//belong to the shadow
|
||||
int startingIndex = 0;
|
||||
int endingIndex = 0;
|
||||
for (int i = 0; i < primitiveCount; i++)
|
||||
{
|
||||
int currentEdge = i;
|
||||
int nextEdge = (i + 1) % primitiveCount;
|
||||
|
||||
if (backFacing[currentEdge] && !backFacing[nextEdge])
|
||||
endingIndex = nextEdge;
|
||||
|
||||
if (!backFacing[currentEdge] && backFacing[nextEdge])
|
||||
startingIndex = nextEdge;
|
||||
}
|
||||
|
||||
int shadowVertexCount;
|
||||
|
||||
//nr of vertices that are in the shadow
|
||||
if (endingIndex > startingIndex)
|
||||
shadowVertexCount = endingIndex - startingIndex + 1;
|
||||
else
|
||||
shadowVertexCount = primitiveCount + 1 - startingIndex + endingIndex;
|
||||
|
||||
shadowVertices = new VertexPositionColor[shadowVertexCount * 2];
|
||||
|
||||
//create a triangle strip that has the shape of the shadow
|
||||
int currentIndex = startingIndex;
|
||||
int svCount = 0;
|
||||
while (svCount != shadowVertexCount * 2)
|
||||
{
|
||||
Vector3 vertexPos = vertices[currentIndex].Position;
|
||||
|
||||
//one vertex on the hull
|
||||
shadowVertices[svCount] = new VertexPositionColor();
|
||||
shadowVertices[svCount].Color = Color.Black;
|
||||
shadowVertices[svCount].Position = vertexPos;
|
||||
|
||||
//one extruded by the light direction
|
||||
shadowVertices[svCount + 1] = new VertexPositionColor();
|
||||
shadowVertices[svCount + 1].Color = Color.Black;
|
||||
Vector3 L2P = vertexPos - new Vector3(lightSourcePos, 0);
|
||||
L2P.Normalize();
|
||||
shadowVertices[svCount + 1].Position = new Vector3(lightSourcePos, 0) + L2P * 9000;
|
||||
|
||||
svCount += 2;
|
||||
currentIndex = (currentIndex + 1) % primitiveCount;
|
||||
}
|
||||
|
||||
drawingEffect.World = cam.ShaderTransform
|
||||
* Matrix.CreateOrthographic(Game1.GraphicsWidth, Game1.GraphicsHeight, -1, 1) * 0.5f;
|
||||
drawingEffect.CurrentTechnique.Passes[0].Apply();
|
||||
|
||||
graphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleStrip, shadowVertices, 0, shadowVertexCount * 2 - 2);
|
||||
|
||||
}
|
||||
|
||||
public void Remove()
|
||||
{
|
||||
list.Remove(this);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Subsurface.Lights
|
||||
{
|
||||
class ConvexHull
|
||||
{
|
||||
public static List<ConvexHull> list = new List<ConvexHull>();
|
||||
static BasicEffect drawingEffect;
|
||||
|
||||
private VertexPositionColor[] vertices;
|
||||
private short[] indices;
|
||||
int primitiveCount;
|
||||
|
||||
bool[] backFacing;
|
||||
VertexPositionColor[] shadowVertices;
|
||||
|
||||
public bool Enabled
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public ConvexHull(Vector2[] points, Color color)
|
||||
{
|
||||
int vertexCount = points.Length;
|
||||
vertices = new VertexPositionColor[vertexCount + 1];
|
||||
Vector2 center = Vector2.Zero;
|
||||
|
||||
for (int i = 0; i < vertexCount; i++)
|
||||
{
|
||||
vertices[i] = new VertexPositionColor(new Vector3(points[i], 0), color);
|
||||
center += points[i];
|
||||
}
|
||||
center /= points.Length;
|
||||
vertices[vertexCount] = new VertexPositionColor(new Vector3(center, 0), color);
|
||||
|
||||
primitiveCount = points.Length;
|
||||
indices = new short[primitiveCount * 3];
|
||||
|
||||
for (int i = 0; i < primitiveCount; i++)
|
||||
{
|
||||
indices[3 * i] = (short)i;
|
||||
indices[3 * i + 1] = (short)((i + 1) % vertexCount);
|
||||
indices[3 * i + 2] = (short)vertexCount;
|
||||
}
|
||||
backFacing = new bool[vertexCount];
|
||||
|
||||
Enabled = true;
|
||||
|
||||
list.Add(this);
|
||||
}
|
||||
|
||||
public void Move(Vector2 amount)
|
||||
{
|
||||
for (int i = 0; i < vertices.Count(); i++)
|
||||
{
|
||||
vertices[i].Position = new Vector3(vertices[i].Position.X + amount.X, vertices[i].Position.Y + amount.Y, vertices[i].Position.Z);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetVertices(Vector2[] points)
|
||||
{
|
||||
int vertexCount = points.Length;
|
||||
vertices = new VertexPositionColor[vertexCount + 1];
|
||||
|
||||
for (int i = 0; i < vertexCount; i++)
|
||||
{
|
||||
vertices[i] = new VertexPositionColor(new Vector3(points[i], 0), Color.Black);
|
||||
}
|
||||
}
|
||||
|
||||
//public void Draw(GameTime gameTime)
|
||||
//{
|
||||
// device.RasterizerState = RasterizerState.CullNone;
|
||||
// device.BlendState = BlendState.Opaque;
|
||||
|
||||
// drawingEffect.World = Matrix.CreateTranslation(position.X, position.Y, 0);
|
||||
|
||||
// foreach (EffectPass pass in drawingEffect.CurrentTechnique.Passes)
|
||||
// {
|
||||
// pass.Apply();
|
||||
// device.DrawUserIndexedPrimitives<VertexPositionColor>(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, 0, primitiveCount);
|
||||
// }
|
||||
//}
|
||||
|
||||
public void DrawShadows(GraphicsDevice graphicsDevice, Camera cam, Vector2 lightSourcePos)
|
||||
{
|
||||
if (!Enabled) return;
|
||||
|
||||
if (drawingEffect == null)
|
||||
{
|
||||
drawingEffect = new BasicEffect(graphicsDevice);
|
||||
drawingEffect.VertexColorEnabled = true;
|
||||
}
|
||||
|
||||
//compute facing of each edge, using N*L
|
||||
for (int i = 0; i < primitiveCount; i++)
|
||||
{
|
||||
Vector2 firstVertex = new Vector2(vertices[i].Position.X, vertices[i].Position.Y);
|
||||
int secondIndex = (i + 1) % primitiveCount;
|
||||
Vector2 secondVertex = new Vector2(vertices[secondIndex].Position.X, vertices[secondIndex].Position.Y);
|
||||
Vector2 middle = (firstVertex + secondVertex) / 2;
|
||||
|
||||
Vector2 L = lightSourcePos - middle;
|
||||
|
||||
Vector2 N = new Vector2();
|
||||
N.X = -(secondVertex.Y - firstVertex.Y);
|
||||
N.Y = secondVertex.X - firstVertex.X;
|
||||
|
||||
backFacing[i] = (Vector2.Dot(N, L) < 0);
|
||||
}
|
||||
|
||||
//find beginning and ending vertices which
|
||||
//belong to the shadow
|
||||
int startingIndex = 0;
|
||||
int endingIndex = 0;
|
||||
for (int i = 0; i < primitiveCount; i++)
|
||||
{
|
||||
int currentEdge = i;
|
||||
int nextEdge = (i + 1) % primitiveCount;
|
||||
|
||||
if (backFacing[currentEdge] && !backFacing[nextEdge])
|
||||
endingIndex = nextEdge;
|
||||
|
||||
if (!backFacing[currentEdge] && backFacing[nextEdge])
|
||||
startingIndex = nextEdge;
|
||||
}
|
||||
|
||||
int shadowVertexCount;
|
||||
|
||||
//nr of vertices that are in the shadow
|
||||
if (endingIndex > startingIndex)
|
||||
shadowVertexCount = endingIndex - startingIndex + 1;
|
||||
else
|
||||
shadowVertexCount = primitiveCount + 1 - startingIndex + endingIndex;
|
||||
|
||||
shadowVertices = new VertexPositionColor[shadowVertexCount * 2];
|
||||
|
||||
//create a triangle strip that has the shape of the shadow
|
||||
int currentIndex = startingIndex;
|
||||
int svCount = 0;
|
||||
while (svCount != shadowVertexCount * 2)
|
||||
{
|
||||
Vector3 vertexPos = vertices[currentIndex].Position;
|
||||
|
||||
//one vertex on the hull
|
||||
shadowVertices[svCount] = new VertexPositionColor();
|
||||
shadowVertices[svCount].Color = Color.Black;
|
||||
shadowVertices[svCount].Position = vertexPos;
|
||||
|
||||
//one extruded by the light direction
|
||||
shadowVertices[svCount + 1] = new VertexPositionColor();
|
||||
shadowVertices[svCount + 1].Color = Color.Black;
|
||||
Vector3 L2P = vertexPos - new Vector3(lightSourcePos, 0);
|
||||
L2P.Normalize();
|
||||
shadowVertices[svCount + 1].Position = new Vector3(lightSourcePos, 0) + L2P * 9000;
|
||||
|
||||
svCount += 2;
|
||||
currentIndex = (currentIndex + 1) % primitiveCount;
|
||||
}
|
||||
|
||||
drawingEffect.World = cam.ShaderTransform
|
||||
* Matrix.CreateOrthographic(Game1.GraphicsWidth, Game1.GraphicsHeight, -1, 1) * 0.5f;
|
||||
drawingEffect.CurrentTechnique.Passes[0].Apply();
|
||||
|
||||
graphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleStrip, shadowVertices, 0, shadowVertexCount * 2 - 2);
|
||||
|
||||
}
|
||||
|
||||
public void Remove()
|
||||
{
|
||||
list.Remove(this);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,381 +1,398 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Xml.Linq;
|
||||
using FarseerPhysics;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using FarseerPhysics.Collision;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
public enum Direction : byte
|
||||
{
|
||||
None = 0, Left = 1, Right = 2
|
||||
}
|
||||
|
||||
static class Map
|
||||
{
|
||||
public static Vector2 gridSize = new Vector2(16.0f, 16.0f);
|
||||
|
||||
private static Vector2 lastPickedPosition;
|
||||
private static float lastPickedFraction;
|
||||
|
||||
private static Rectangle borders;
|
||||
|
||||
private static string filePath;
|
||||
|
||||
public static Vector2 LastPickedPosition
|
||||
{
|
||||
get { return lastPickedPosition; }
|
||||
}
|
||||
|
||||
public static float LastPickedFraction
|
||||
{
|
||||
get { return lastPickedFraction; }
|
||||
}
|
||||
|
||||
public static Rectangle Borders
|
||||
{
|
||||
get { return borders; }
|
||||
}
|
||||
|
||||
public static string FilePath
|
||||
{
|
||||
get { return filePath; }
|
||||
}
|
||||
|
||||
public static void Draw(SpriteBatch spriteBatch, bool editing = false)
|
||||
{
|
||||
for (int i = 0; i < MapEntity.mapEntityList.Count(); i++ )
|
||||
{
|
||||
MapEntity.mapEntityList[i].Draw(spriteBatch, editing);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawFront(SpriteBatch spriteBatch, bool editing = false)
|
||||
{
|
||||
for (int i = 0; i < MapEntity.mapEntityList.Count(); i++)
|
||||
{
|
||||
if (MapEntity.mapEntityList[i].sprite == null || MapEntity.mapEntityList[i].sprite.Depth < 0.5f)
|
||||
MapEntity.mapEntityList[i].Draw(spriteBatch, editing);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawBack(SpriteBatch spriteBatch, bool editing = false)
|
||||
{
|
||||
|
||||
for (int i = 0; i < MapEntity.mapEntityList.Count(); i++)
|
||||
{
|
||||
if (MapEntity.mapEntityList[i].sprite == null || MapEntity.mapEntityList[i].sprite.Depth >= 0.5f)
|
||||
MapEntity.mapEntityList[i].Draw(spriteBatch, editing);
|
||||
}
|
||||
}
|
||||
|
||||
public static Vector2 MouseToWorldGrid(Camera cam)
|
||||
{
|
||||
Vector2 position = new Vector2(PlayerInput.GetMouseState.X, PlayerInput.GetMouseState.Y);
|
||||
position = cam.ScreenToWorld(position);
|
||||
|
||||
return VectorToWorldGrid(position);
|
||||
}
|
||||
|
||||
public static Vector2 VectorToWorldGrid(Vector2 position)
|
||||
{
|
||||
position.X = (float)Math.Floor(Convert.ToDouble(position.X / gridSize.X)) * gridSize.X;
|
||||
position.Y = (float)Math.Ceiling(Convert.ToDouble(position.Y / gridSize.Y)) * gridSize.Y;
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
public static Rectangle AbsRect(Vector2 pos, Vector2 size)
|
||||
{
|
||||
if (size.X < 0.0f)
|
||||
{
|
||||
pos.X += size.X;
|
||||
size.X = -size.X;
|
||||
}
|
||||
if (size.Y < 0.0f)
|
||||
{
|
||||
pos.Y -= size.Y;
|
||||
size.Y = -size.Y;
|
||||
}
|
||||
|
||||
return new Rectangle((int)pos.X, (int)pos.Y, (int)size.X, (int)size.Y);
|
||||
}
|
||||
|
||||
public static bool RectContains(Rectangle rect, Vector2 pos)
|
||||
{
|
||||
return (pos.X > rect.X && pos.X < rect.X + rect.Width
|
||||
&& pos.Y < rect.Y && pos.Y > rect.Y - rect.Height);
|
||||
}
|
||||
|
||||
public static bool RectsOverlap(Rectangle rect1, Rectangle rect2)
|
||||
{
|
||||
return !(rect1.X > rect2.X + rect2.Width || rect1.X + rect1.Width < rect2.X ||
|
||||
rect1.Y < rect2.Y - rect2.Height || rect1.Y - rect1.Height > rect2.Y);
|
||||
}
|
||||
|
||||
public static Body PickBody(Vector2 rayStart, Vector2 rayEnd, List<Body> ignoredBodies = null)
|
||||
{
|
||||
float closestFraction = 1.0f;
|
||||
Body closestBody = null;
|
||||
Game1.world.RayCast((fixture, point, normal, fraction) =>
|
||||
{
|
||||
if (fixture == null || fixture.CollisionCategories == Category.None) return -1;
|
||||
if (ignoredBodies != null && ignoredBodies.Contains(fixture.Body)) return -1;
|
||||
|
||||
Structure structure = fixture.Body.UserData as Structure;
|
||||
if (structure != null && (structure.IsPlatform || !structure.HasBody)) return -1;
|
||||
|
||||
if (fraction < closestFraction)
|
||||
{
|
||||
closestFraction = fraction;
|
||||
if (fixture.Body!=null) closestBody = fixture.Body;
|
||||
}
|
||||
return fraction;
|
||||
}
|
||||
, rayStart, rayEnd);
|
||||
|
||||
lastPickedPosition = rayStart + (rayEnd - rayStart) * closestFraction;
|
||||
lastPickedFraction = closestFraction;
|
||||
return closestBody;
|
||||
}
|
||||
|
||||
|
||||
public static Structure CheckVisibility(Vector2 rayStart, Vector2 rayEnd)
|
||||
{
|
||||
Structure closestStructure = null;
|
||||
float closestFraction = 1.0f;
|
||||
|
||||
if (Vector2.Distance(rayStart,rayEnd)<0.01f)
|
||||
{
|
||||
closestFraction = 0.01f;
|
||||
return null;
|
||||
}
|
||||
|
||||
Game1.world.RayCast((fixture, point, normal, fraction) =>
|
||||
{
|
||||
if (fixture == null || fixture.CollisionCategories != Physics.CollisionWall) return -1;
|
||||
|
||||
Structure structure = fixture.Body.UserData as Structure;
|
||||
if (structure != null)
|
||||
{
|
||||
if (structure.IsPlatform || structure.StairDirection != Direction.None) return -1;
|
||||
int sectionIndex = structure.FindSectionIndex(ConvertUnits.ToDisplayUnits(point));
|
||||
if (sectionIndex > -1 && structure.SectionHasHole(sectionIndex)) return -1;
|
||||
}
|
||||
|
||||
if (fraction < closestFraction)
|
||||
{
|
||||
if (structure != null) closestStructure = structure;
|
||||
closestFraction = fraction;
|
||||
}
|
||||
return closestFraction;
|
||||
}
|
||||
, rayStart, rayEnd);
|
||||
|
||||
|
||||
lastPickedPosition = rayStart + (rayEnd - rayStart) * closestFraction;
|
||||
lastPickedFraction = closestFraction;
|
||||
return closestStructure;
|
||||
}
|
||||
|
||||
public static Body PickBody(Vector2 point)
|
||||
{
|
||||
Body foundBody = null;
|
||||
AABB aabb = new AABB(point, point);
|
||||
|
||||
Game1.world.QueryAABB(p =>
|
||||
{
|
||||
foundBody = p.Body;
|
||||
|
||||
return true;
|
||||
|
||||
}, ref aabb);
|
||||
|
||||
return foundBody;
|
||||
}
|
||||
|
||||
public static bool InsideWall(Vector2 point)
|
||||
{
|
||||
Body foundBody = Map.PickBody(point);
|
||||
if (foundBody==null) return false;
|
||||
|
||||
Structure wall = foundBody.UserData as Structure;
|
||||
if (wall == null || wall.IsPlatform) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void Save(string filePath, string fileName)
|
||||
{
|
||||
if (fileName==null)
|
||||
{
|
||||
DebugConsole.ThrowError("No save file selected");
|
||||
return;
|
||||
}
|
||||
XDocument doc = new XDocument(
|
||||
new XElement((XName)fileName));
|
||||
|
||||
foreach (MapEntity e in MapEntity.mapEntityList)
|
||||
{
|
||||
e.Save(doc);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
string docString = doc.ToString();
|
||||
ToolBox.CompressStringToFile(filePath+fileName+".gz", doc.ToString());
|
||||
}
|
||||
catch
|
||||
{
|
||||
DebugConsole.ThrowError("Saving map ''" + filePath + fileName + "'' failed!");
|
||||
}
|
||||
|
||||
|
||||
//doc.Save(filePath + fileName);
|
||||
}
|
||||
|
||||
public static string[] GetMapFilePaths()
|
||||
{
|
||||
string[] mapFilePaths;
|
||||
try
|
||||
{
|
||||
mapFilePaths = Directory.GetFiles("Content/SavedMaps");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Couldn't open directory ''Content/SavedMaps''!", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
return mapFilePaths;
|
||||
}
|
||||
|
||||
public static void Load(string filePath, string fileName)
|
||||
{
|
||||
Load(filePath + fileName);
|
||||
}
|
||||
|
||||
public static void Load(string file)
|
||||
{
|
||||
Clear();
|
||||
filePath = file;
|
||||
XDocument doc = null;
|
||||
|
||||
string extension = Path.GetExtension(file);
|
||||
|
||||
if (extension==".gz")
|
||||
{
|
||||
Stream stream = ToolBox.DecompressFiletoStream(file);
|
||||
if (stream == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Loading map ''" + file + "'' failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
stream.Position = 0;
|
||||
doc = XDocument.Load(stream); //ToolBox.TryLoadXml(file);
|
||||
stream.Close();
|
||||
stream.Dispose();
|
||||
}
|
||||
|
||||
catch
|
||||
{
|
||||
DebugConsole.ThrowError("Loading map ''" + file + "'' failed!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (extension ==".xml")
|
||||
{
|
||||
doc = XDocument.Load(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError("Couldn't load map ''"+file+"! (Unrecognized file extension)");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
foreach (XElement element in doc.Root.Elements())
|
||||
{
|
||||
string typeName = element.Name.ToString();
|
||||
|
||||
Type t;
|
||||
try
|
||||
{
|
||||
// Get the type of a specified class.
|
||||
t = Type.GetType("Subsurface." + typeName + ", Subsurface", true, true);
|
||||
if (t == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + file + "! Could not find a entity of the type ''" + typeName + "''.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + file + "! Could not find a entity of the type ''" + typeName + "''.", e);
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
MethodInfo loadMethod = t.GetMethod("Load");
|
||||
loadMethod.Invoke(t, new object[] { element });
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Could not find the method ''Load'' in " + t + ".", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
borders = new Rectangle(0, 0, 1, 1);
|
||||
foreach (Hull hull in Hull.hullList)
|
||||
{
|
||||
if (hull.Rect.X < borders.X || borders.X == 0) borders.X = hull.Rect.X;
|
||||
if (hull.Rect.Y > borders.Y || borders.Y == 0) borders.Y = hull.Rect.Y;
|
||||
|
||||
if (hull.Rect.X + hull.Rect.Width > borders.X + borders.Width) borders.Width = hull.Rect.X + hull.Rect.Width - borders.X;
|
||||
if (hull.Rect.Y - hull.Rect.Height < borders.Y - borders.Height) borders.Height = borders.Y - (hull.Rect.Y - hull.Rect.Height);
|
||||
}
|
||||
|
||||
MapEntity.LinkAll();
|
||||
foreach (Item item in Item.itemList)
|
||||
{
|
||||
foreach (ItemComponent ic in item.components)
|
||||
{
|
||||
ic.OnMapLoaded();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void Clear()
|
||||
{
|
||||
Map.filePath = "";
|
||||
|
||||
if (Game1.gameScreen.Cam != null) Game1.gameScreen.Cam.TargetPos = Vector2.Zero;
|
||||
|
||||
Entity.RemoveAll();
|
||||
|
||||
if (Game1.gameSession!=null)
|
||||
Game1.gameSession.crewManager.EndShift();
|
||||
|
||||
PhysicsBody.list.Clear();
|
||||
|
||||
Ragdoll.list.Clear();
|
||||
|
||||
Game1.world.Clear();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Xml.Linq;
|
||||
using FarseerPhysics;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using FarseerPhysics.Collision;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
public enum Direction : byte
|
||||
{
|
||||
None = 0, Left = 1, Right = 2
|
||||
}
|
||||
|
||||
static class Map
|
||||
{
|
||||
static string MapFolder = "Content/SavedMaps";
|
||||
|
||||
public static Vector2 gridSize = new Vector2(16.0f, 16.0f);
|
||||
|
||||
private static Vector2 lastPickedPosition;
|
||||
private static float lastPickedFraction;
|
||||
|
||||
private static Rectangle borders;
|
||||
|
||||
private static string filePath;
|
||||
|
||||
public static Vector2 LastPickedPosition
|
||||
{
|
||||
get { return lastPickedPosition; }
|
||||
}
|
||||
|
||||
public static float LastPickedFraction
|
||||
{
|
||||
get { return lastPickedFraction; }
|
||||
}
|
||||
|
||||
public static Rectangle Borders
|
||||
{
|
||||
get { return borders; }
|
||||
}
|
||||
|
||||
public static string FilePath
|
||||
{
|
||||
get { return filePath; }
|
||||
}
|
||||
|
||||
public static void Draw(SpriteBatch spriteBatch, bool editing = false)
|
||||
{
|
||||
for (int i = 0; i < MapEntity.mapEntityList.Count(); i++ )
|
||||
{
|
||||
MapEntity.mapEntityList[i].Draw(spriteBatch, editing);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawFront(SpriteBatch spriteBatch, bool editing = false)
|
||||
{
|
||||
for (int i = 0; i < MapEntity.mapEntityList.Count(); i++)
|
||||
{
|
||||
if (MapEntity.mapEntityList[i].sprite == null || MapEntity.mapEntityList[i].sprite.Depth < 0.5f)
|
||||
MapEntity.mapEntityList[i].Draw(spriteBatch, editing);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawBack(SpriteBatch spriteBatch, bool editing = false)
|
||||
{
|
||||
|
||||
for (int i = 0; i < MapEntity.mapEntityList.Count(); i++)
|
||||
{
|
||||
if (MapEntity.mapEntityList[i].sprite == null || MapEntity.mapEntityList[i].sprite.Depth >= 0.5f)
|
||||
MapEntity.mapEntityList[i].Draw(spriteBatch, editing);
|
||||
}
|
||||
}
|
||||
|
||||
public static Vector2 MouseToWorldGrid(Camera cam)
|
||||
{
|
||||
Vector2 position = new Vector2(PlayerInput.GetMouseState.X, PlayerInput.GetMouseState.Y);
|
||||
position = cam.ScreenToWorld(position);
|
||||
|
||||
return VectorToWorldGrid(position);
|
||||
}
|
||||
|
||||
public static Vector2 VectorToWorldGrid(Vector2 position)
|
||||
{
|
||||
position.X = (float)Math.Floor(Convert.ToDouble(position.X / gridSize.X)) * gridSize.X;
|
||||
position.Y = (float)Math.Ceiling(Convert.ToDouble(position.Y / gridSize.Y)) * gridSize.Y;
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
public static Rectangle AbsRect(Vector2 pos, Vector2 size)
|
||||
{
|
||||
if (size.X < 0.0f)
|
||||
{
|
||||
pos.X += size.X;
|
||||
size.X = -size.X;
|
||||
}
|
||||
if (size.Y < 0.0f)
|
||||
{
|
||||
pos.Y -= size.Y;
|
||||
size.Y = -size.Y;
|
||||
}
|
||||
|
||||
return new Rectangle((int)pos.X, (int)pos.Y, (int)size.X, (int)size.Y);
|
||||
}
|
||||
|
||||
public static bool RectContains(Rectangle rect, Vector2 pos)
|
||||
{
|
||||
return (pos.X > rect.X && pos.X < rect.X + rect.Width
|
||||
&& pos.Y < rect.Y && pos.Y > rect.Y - rect.Height);
|
||||
}
|
||||
|
||||
public static bool RectsOverlap(Rectangle rect1, Rectangle rect2)
|
||||
{
|
||||
return !(rect1.X > rect2.X + rect2.Width || rect1.X + rect1.Width < rect2.X ||
|
||||
rect1.Y < rect2.Y - rect2.Height || rect1.Y - rect1.Height > rect2.Y);
|
||||
}
|
||||
|
||||
public static Body PickBody(Vector2 rayStart, Vector2 rayEnd, List<Body> ignoredBodies = null)
|
||||
{
|
||||
float closestFraction = 1.0f;
|
||||
Body closestBody = null;
|
||||
Game1.world.RayCast((fixture, point, normal, fraction) =>
|
||||
{
|
||||
if (fixture == null || fixture.CollisionCategories == Category.None) return -1;
|
||||
if (ignoredBodies != null && ignoredBodies.Contains(fixture.Body)) return -1;
|
||||
|
||||
Structure structure = fixture.Body.UserData as Structure;
|
||||
if (structure != null && (structure.IsPlatform || !structure.HasBody)) return -1;
|
||||
|
||||
if (fraction < closestFraction)
|
||||
{
|
||||
closestFraction = fraction;
|
||||
if (fixture.Body!=null) closestBody = fixture.Body;
|
||||
}
|
||||
return fraction;
|
||||
}
|
||||
, rayStart, rayEnd);
|
||||
|
||||
lastPickedPosition = rayStart + (rayEnd - rayStart) * closestFraction;
|
||||
lastPickedFraction = closestFraction;
|
||||
return closestBody;
|
||||
}
|
||||
|
||||
|
||||
public static Structure CheckVisibility(Vector2 rayStart, Vector2 rayEnd)
|
||||
{
|
||||
Structure closestStructure = null;
|
||||
float closestFraction = 1.0f;
|
||||
|
||||
if (Vector2.Distance(rayStart,rayEnd)<0.01f)
|
||||
{
|
||||
closestFraction = 0.01f;
|
||||
return null;
|
||||
}
|
||||
|
||||
Game1.world.RayCast((fixture, point, normal, fraction) =>
|
||||
{
|
||||
if (fixture == null || fixture.CollisionCategories != Physics.CollisionWall) return -1;
|
||||
|
||||
Structure structure = fixture.Body.UserData as Structure;
|
||||
if (structure != null)
|
||||
{
|
||||
if (structure.IsPlatform || structure.StairDirection != Direction.None) return -1;
|
||||
int sectionIndex = structure.FindSectionIndex(ConvertUnits.ToDisplayUnits(point));
|
||||
if (sectionIndex > -1 && structure.SectionHasHole(sectionIndex)) return -1;
|
||||
}
|
||||
|
||||
if (fraction < closestFraction)
|
||||
{
|
||||
if (structure != null) closestStructure = structure;
|
||||
closestFraction = fraction;
|
||||
}
|
||||
return closestFraction;
|
||||
}
|
||||
, rayStart, rayEnd);
|
||||
|
||||
|
||||
lastPickedPosition = rayStart + (rayEnd - rayStart) * closestFraction;
|
||||
lastPickedFraction = closestFraction;
|
||||
return closestStructure;
|
||||
}
|
||||
|
||||
public static Body PickBody(Vector2 point)
|
||||
{
|
||||
Body foundBody = null;
|
||||
AABB aabb = new AABB(point, point);
|
||||
|
||||
Game1.world.QueryAABB(p =>
|
||||
{
|
||||
foundBody = p.Body;
|
||||
|
||||
return true;
|
||||
|
||||
}, ref aabb);
|
||||
|
||||
return foundBody;
|
||||
}
|
||||
|
||||
public static bool InsideWall(Vector2 point)
|
||||
{
|
||||
Body foundBody = Map.PickBody(point);
|
||||
if (foundBody==null) return false;
|
||||
|
||||
Structure wall = foundBody.UserData as Structure;
|
||||
if (wall == null || wall.IsPlatform) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void Save(string filePath, string fileName)
|
||||
{
|
||||
if (fileName==null)
|
||||
{
|
||||
DebugConsole.ThrowError("No save file selected");
|
||||
return;
|
||||
}
|
||||
XDocument doc = new XDocument(
|
||||
new XElement((XName)fileName));
|
||||
|
||||
foreach (MapEntity e in MapEntity.mapEntityList)
|
||||
{
|
||||
e.Save(doc);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
string docString = doc.ToString();
|
||||
ToolBox.CompressStringToFile(filePath+fileName+".gz", doc.ToString());
|
||||
}
|
||||
catch
|
||||
{
|
||||
DebugConsole.ThrowError("Saving map ''" + filePath + fileName + "'' failed!");
|
||||
}
|
||||
|
||||
|
||||
//doc.Save(filePath + fileName);
|
||||
}
|
||||
|
||||
public static string[] GetMapFilePaths()
|
||||
{
|
||||
string[] mapFilePaths;
|
||||
|
||||
if (!Directory.Exists(MapFolder))
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(MapFolder);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
DebugConsole.ThrowError("Directory ''Content/SavedMaps'' not found and creating the directory failed.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
mapFilePaths = Directory.GetFiles(MapFolder);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Couldn't open directory ''Content/SavedMaps''!", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
return mapFilePaths;
|
||||
}
|
||||
|
||||
public static void Load(string filePath, string fileName)
|
||||
{
|
||||
Load(filePath + fileName);
|
||||
}
|
||||
|
||||
public static void Load(string file)
|
||||
{
|
||||
Clear();
|
||||
filePath = file;
|
||||
XDocument doc = null;
|
||||
|
||||
string extension = Path.GetExtension(file);
|
||||
|
||||
if (extension==".gz")
|
||||
{
|
||||
Stream stream = ToolBox.DecompressFiletoStream(file);
|
||||
if (stream == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Loading map ''" + file + "'' failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
stream.Position = 0;
|
||||
doc = XDocument.Load(stream); //ToolBox.TryLoadXml(file);
|
||||
stream.Close();
|
||||
stream.Dispose();
|
||||
}
|
||||
|
||||
catch
|
||||
{
|
||||
DebugConsole.ThrowError("Loading map ''" + file + "'' failed!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (extension ==".xml")
|
||||
{
|
||||
doc = XDocument.Load(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError("Couldn't load map ''"+file+"! (Unrecognized file extension)");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
foreach (XElement element in doc.Root.Elements())
|
||||
{
|
||||
string typeName = element.Name.ToString();
|
||||
|
||||
Type t;
|
||||
try
|
||||
{
|
||||
// Get the type of a specified class.
|
||||
t = Type.GetType("Subsurface." + typeName + ", Subsurface", true, true);
|
||||
if (t == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + file + "! Could not find a entity of the type ''" + typeName + "''.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + file + "! Could not find a entity of the type ''" + typeName + "''.", e);
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
MethodInfo loadMethod = t.GetMethod("Load");
|
||||
loadMethod.Invoke(t, new object[] { element });
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Could not find the method ''Load'' in " + t + ".", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
borders = new Rectangle(0, 0, 1, 1);
|
||||
foreach (Hull hull in Hull.hullList)
|
||||
{
|
||||
if (hull.Rect.X < borders.X || borders.X == 0) borders.X = hull.Rect.X;
|
||||
if (hull.Rect.Y > borders.Y || borders.Y == 0) borders.Y = hull.Rect.Y;
|
||||
|
||||
if (hull.Rect.X + hull.Rect.Width > borders.X + borders.Width) borders.Width = hull.Rect.X + hull.Rect.Width - borders.X;
|
||||
if (hull.Rect.Y - hull.Rect.Height < borders.Y - borders.Height) borders.Height = borders.Y - (hull.Rect.Y - hull.Rect.Height);
|
||||
}
|
||||
|
||||
MapEntity.LinkAll();
|
||||
foreach (Item item in Item.itemList)
|
||||
{
|
||||
foreach (ItemComponent ic in item.components)
|
||||
{
|
||||
ic.OnMapLoaded();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void Clear()
|
||||
{
|
||||
Map.filePath = "";
|
||||
|
||||
if (Game1.gameScreen.Cam != null) Game1.gameScreen.Cam.TargetPos = Vector2.Zero;
|
||||
|
||||
Entity.RemoveAll();
|
||||
|
||||
if (Game1.gameSession!=null)
|
||||
Game1.gameSession.crewManager.EndShift();
|
||||
|
||||
PhysicsBody.list.Clear();
|
||||
|
||||
Ragdoll.list.Clear();
|
||||
|
||||
Game1.world.Clear();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,291 +1,291 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using System;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class EditMapScreen : Screen
|
||||
{
|
||||
Camera cam;
|
||||
|
||||
GUIComponent GUIpanel;
|
||||
|
||||
GUIComponent[] GUItabs;
|
||||
int selectedTab;
|
||||
|
||||
//a character used for picking up and manipulating items
|
||||
Character dummyCharacter;
|
||||
|
||||
bool characterMode;
|
||||
|
||||
public Camera Cam
|
||||
{
|
||||
get { return cam; }
|
||||
}
|
||||
|
||||
public EditMapScreen()
|
||||
{
|
||||
cam = new Camera();
|
||||
cam.Translate(new Vector2(-10.0f, 50.0f));
|
||||
|
||||
selectedTab = -1;
|
||||
|
||||
GUIpanel = new GUIFrame(new Rectangle(0,0, 120, Game1.GraphicsHeight), Color.DarkGray*0.8f);
|
||||
GUIpanel.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
|
||||
//GUIListBox constructionList = new GUIListBox(new Rectangle(0, 0, 0, 300), Color.White * 0.7f, GUIpanel);
|
||||
//constructionList.OnSelected = MapEntityPrefab.SelectPrefab;
|
||||
//constructionList.CheckSelected = MapEntityPrefab.GetSelected;
|
||||
|
||||
GUIButton button = new GUIButton(new Rectangle(0, 50, 100, 20), "Items", GUI.style, Alignment.Left, GUIpanel);
|
||||
button.UserData = 0;
|
||||
button.OnClicked = SelectTab;
|
||||
|
||||
button = new GUIButton(new Rectangle(0, 80, 100, 20), "Structures", GUI.style, Alignment.Left, GUIpanel);
|
||||
button.UserData = 1;
|
||||
button.OnClicked = SelectTab;
|
||||
|
||||
button = new GUIButton(new Rectangle(0, 140, 100, 20), "Character mode", GUI.style, Alignment.Left, GUIpanel);
|
||||
button.OnClicked = ToggleCharacterMode;
|
||||
|
||||
GUItabs = new GUIComponent[2];
|
||||
int width = 400, height = 400;
|
||||
GUItabs[0] = new GUIFrame(new Rectangle(Game1.GraphicsWidth/2-width/2, Game1.GraphicsHeight/2-height/2, width, height), Color.DarkGray*0.8f);
|
||||
GUItabs[0].Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
|
||||
GUIListBox itemList = new GUIListBox(new Rectangle(0, 0, 0, 0), Color.White * 0.7f, GUItabs[0]);
|
||||
itemList.OnSelected = SelectPrefab;
|
||||
itemList.CheckSelected = MapEntityPrefab.GetSelected;
|
||||
|
||||
GUItabs[1] = new GUIFrame(new Rectangle(Game1.GraphicsWidth / 2 - width / 2, Game1.GraphicsHeight / 2 - height / 2, width, height), Color.DarkGray * 0.8f);
|
||||
GUItabs[1].Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
|
||||
GUIListBox structureList = new GUIListBox(new Rectangle(0, 0, 0, 300), Color.White * 0.7f, GUItabs[1]);
|
||||
structureList.OnSelected = SelectPrefab;
|
||||
structureList.CheckSelected = MapEntityPrefab.GetSelected;
|
||||
|
||||
foreach (MapEntityPrefab ep in MapEntityPrefab.list)
|
||||
{
|
||||
GUIListBox parent = ((ep as ItemPrefab) == null) ? structureList : itemList;
|
||||
Color color = ((parent.CountChildren % 2) == 0) ? Color.White : Color.LightGray;
|
||||
|
||||
GUIFrame frame = new GUIFrame(new Rectangle(0, 0, 0, 50), Color.Transparent, parent);
|
||||
frame.UserData = ep;
|
||||
frame.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
|
||||
frame.Color = color;
|
||||
frame.HoverColor = Color.Gold * 0.2f;
|
||||
frame.SelectedColor = Color.Gold * 0.5f;
|
||||
|
||||
GUITextBlock textBlock = new GUITextBlock(
|
||||
new Rectangle(40, 0, 0, 25),
|
||||
ep.Name,
|
||||
Color.Transparent, Color.Black,
|
||||
Alignment.Left,
|
||||
Alignment.Left,
|
||||
frame);
|
||||
textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
|
||||
|
||||
if (ep.sprite != null)
|
||||
{
|
||||
GUIImage img = new GUIImage(new Rectangle(0, 0, 40, 40), ep.sprite, Alignment.Left, frame);
|
||||
img.Scale = Math.Min(Math.Min(40.0f / img.SourceRect.Width, 40.0f / img.SourceRect.Height), 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Select()
|
||||
{
|
||||
base.Select();
|
||||
|
||||
GUIComponent.MouseOn = null;
|
||||
characterMode = false;
|
||||
//CreateDummyCharacter();
|
||||
}
|
||||
|
||||
public override void Deselect()
|
||||
{
|
||||
base.Deselect();
|
||||
|
||||
GUIComponent.MouseOn = null;
|
||||
|
||||
if (dummyCharacter != null)
|
||||
{
|
||||
dummyCharacter.Remove();
|
||||
dummyCharacter = null;
|
||||
Game1.world.ProcessChanges();
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateDummyCharacter()
|
||||
{
|
||||
if (dummyCharacter != null) dummyCharacter.Remove();
|
||||
|
||||
dummyCharacter = new Character("Content/Characters/Human/human.xml", Vector2.Zero);
|
||||
Character.Controlled = dummyCharacter;
|
||||
Game1.world.ProcessChanges();
|
||||
}
|
||||
|
||||
private bool SelectTab(GUIButton button, object obj)
|
||||
{
|
||||
selectedTab = (int)obj;
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ToggleCharacterMode(GUIButton button, object obj)
|
||||
{
|
||||
characterMode = !characterMode;
|
||||
button.Color = (characterMode) ? Color.Gold : Color.White;
|
||||
|
||||
if (characterMode)
|
||||
{
|
||||
CreateDummyCharacter();
|
||||
}
|
||||
else if (dummyCharacter != null)
|
||||
{
|
||||
dummyCharacter.Remove();
|
||||
dummyCharacter = null;
|
||||
}
|
||||
|
||||
foreach (MapEntity me in MapEntity.mapEntityList)
|
||||
{
|
||||
me.IsHighlighted = false;
|
||||
me.IsSelected = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool SelectPrefab(object obj)
|
||||
{
|
||||
MapEntityPrefab.SelectPrefab(obj);
|
||||
selectedTab = -1;
|
||||
GUIComponent.MouseOn = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <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>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
//Vector2 mousePosition = new Vector2(PlayerInput.GetMouseState.X, PlayerInput.GetMouseState.Y);
|
||||
//mousePosition = cam.ScreenToWorld(mousePosition);
|
||||
|
||||
//if (!Character.characterList.Contains(dummyCharacter))
|
||||
//{
|
||||
// CreateDummyCharacter();
|
||||
//}
|
||||
|
||||
cam.MoveCamera((float)deltaTime);
|
||||
cam.Zoom = MathHelper.Clamp(cam.Zoom + PlayerInput.ScrollWheelSpeed/1000.0f,0.1f, 2.0f);
|
||||
|
||||
if (characterMode)
|
||||
{
|
||||
foreach (MapEntity me in MapEntity.mapEntityList)
|
||||
{
|
||||
me.IsHighlighted = false;
|
||||
}
|
||||
|
||||
if (dummyCharacter.SelectedConstruction==null)
|
||||
{
|
||||
Vector2 mouseSimPos = FarseerPhysics.ConvertUnits.ToSimUnits(cam.ScreenToWorld(PlayerInput.MousePosition));
|
||||
foreach (Limb limb in dummyCharacter.animController.limbs)
|
||||
{
|
||||
limb.body.SetTransform(mouseSimPos, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
dummyCharacter.ControlLocalPlayer(cam, false);
|
||||
dummyCharacter.Control(cam);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
MapEntity.UpdateSelecting(cam);
|
||||
}
|
||||
|
||||
|
||||
GUIpanel.Update((float)deltaTime);
|
||||
if (selectedTab > -1)
|
||||
{
|
||||
GUItabs[selectedTab].Update((float)deltaTime);
|
||||
if (PlayerInput.RightButtonClicked()) selectedTab = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called when the game should draw itself.
|
||||
/// </summary>
|
||||
/// <param name="gameTime">Provides a snapshot of timing values.</param>
|
||||
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
|
||||
{
|
||||
//cam.UpdateTransform();
|
||||
|
||||
spriteBatch.Begin(SpriteSortMode.BackToFront,
|
||||
BlendState.AlphaBlend,
|
||||
null, null, null, null,
|
||||
cam.Transform);
|
||||
|
||||
graphics.Clear(new Color(0.051f, 0.149f, 0.271f, 1.0f));
|
||||
|
||||
Map.Draw(spriteBatch, true);
|
||||
|
||||
if (!characterMode)
|
||||
{
|
||||
if (MapEntityPrefab.Selected != null) MapEntityPrefab.Selected.UpdatePlacing(spriteBatch, cam);
|
||||
|
||||
MapEntity.DrawSelecting(spriteBatch, cam);
|
||||
}
|
||||
|
||||
spriteBatch.End();
|
||||
|
||||
//-------------------- HUD -----------------------------
|
||||
|
||||
spriteBatch.Begin();
|
||||
|
||||
GUIpanel.Draw(spriteBatch);
|
||||
|
||||
if (selectedTab > -1) GUItabs[selectedTab].Draw(spriteBatch);
|
||||
|
||||
GUI.Draw((float)deltaTime, spriteBatch);
|
||||
|
||||
//EntityPrefab.DrawList(spriteBatch, new Vector2(20,50));
|
||||
|
||||
|
||||
|
||||
if (characterMode)
|
||||
{
|
||||
if (dummyCharacter != null && dummyCharacter.SelectedConstruction != null)
|
||||
{
|
||||
if (Character.Controlled.SelectedConstruction == dummyCharacter.ClosestItem)
|
||||
{
|
||||
dummyCharacter.SelectedConstruction.DrawHUD(spriteBatch, dummyCharacter);
|
||||
}
|
||||
else
|
||||
{
|
||||
dummyCharacter.SelectedConstruction = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (PlayerInput.GetMouseState.LeftButton != ButtonState.Pressed)
|
||||
{
|
||||
//if (Inventory.draggingItem!=null)
|
||||
//{
|
||||
// Inventory.draggingItem.see
|
||||
//}
|
||||
Inventory.draggingItem = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MapEntity.Edit(spriteBatch, cam);
|
||||
}
|
||||
|
||||
|
||||
|
||||
spriteBatch.End();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using System;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class EditMapScreen : Screen
|
||||
{
|
||||
Camera cam;
|
||||
|
||||
GUIComponent GUIpanel;
|
||||
|
||||
GUIComponent[] GUItabs;
|
||||
int selectedTab;
|
||||
|
||||
//a character used for picking up and manipulating items
|
||||
Character dummyCharacter;
|
||||
|
||||
bool characterMode;
|
||||
|
||||
public Camera Cam
|
||||
{
|
||||
get { return cam; }
|
||||
}
|
||||
|
||||
public EditMapScreen()
|
||||
{
|
||||
cam = new Camera();
|
||||
cam.Translate(new Vector2(-10.0f, 50.0f));
|
||||
|
||||
selectedTab = -1;
|
||||
|
||||
GUIpanel = new GUIFrame(new Rectangle(0,0, 120, Game1.GraphicsHeight), Color.DarkGray*0.8f);
|
||||
GUIpanel.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
|
||||
//GUIListBox constructionList = new GUIListBox(new Rectangle(0, 0, 0, 300), Color.White * 0.7f, GUIpanel);
|
||||
//constructionList.OnSelected = MapEntityPrefab.SelectPrefab;
|
||||
//constructionList.CheckSelected = MapEntityPrefab.GetSelected;
|
||||
|
||||
GUIButton button = new GUIButton(new Rectangle(0, 50, 100, 20), "Items", GUI.style, Alignment.Left, GUIpanel);
|
||||
button.UserData = 0;
|
||||
button.OnClicked = SelectTab;
|
||||
|
||||
button = new GUIButton(new Rectangle(0, 80, 100, 20), "Structures", GUI.style, Alignment.Left, GUIpanel);
|
||||
button.UserData = 1;
|
||||
button.OnClicked = SelectTab;
|
||||
|
||||
button = new GUIButton(new Rectangle(0, 140, 100, 20), "Character mode", GUI.style, Alignment.Left, GUIpanel);
|
||||
button.OnClicked = ToggleCharacterMode;
|
||||
|
||||
GUItabs = new GUIComponent[2];
|
||||
int width = 400, height = 400;
|
||||
GUItabs[0] = new GUIFrame(new Rectangle(Game1.GraphicsWidth/2-width/2, Game1.GraphicsHeight/2-height/2, width, height), Color.DarkGray*0.8f);
|
||||
GUItabs[0].Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
|
||||
GUIListBox itemList = new GUIListBox(new Rectangle(0, 0, 0, 0), Color.White * 0.7f, GUItabs[0]);
|
||||
itemList.OnSelected = SelectPrefab;
|
||||
itemList.CheckSelected = MapEntityPrefab.GetSelected;
|
||||
|
||||
GUItabs[1] = new GUIFrame(new Rectangle(Game1.GraphicsWidth / 2 - width / 2, Game1.GraphicsHeight / 2 - height / 2, width, height), Color.DarkGray * 0.8f);
|
||||
GUItabs[1].Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
|
||||
GUIListBox structureList = new GUIListBox(new Rectangle(0, 0, 0, 300), Color.White * 0.7f, GUItabs[1]);
|
||||
structureList.OnSelected = SelectPrefab;
|
||||
structureList.CheckSelected = MapEntityPrefab.GetSelected;
|
||||
|
||||
foreach (MapEntityPrefab ep in MapEntityPrefab.list)
|
||||
{
|
||||
GUIListBox parent = ((ep as ItemPrefab) == null) ? structureList : itemList;
|
||||
Color color = ((parent.CountChildren % 2) == 0) ? Color.White : Color.LightGray;
|
||||
|
||||
GUIFrame frame = new GUIFrame(new Rectangle(0, 0, 0, 50), Color.Transparent, parent);
|
||||
frame.UserData = ep;
|
||||
frame.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
|
||||
frame.Color = color;
|
||||
frame.HoverColor = Color.Gold * 0.2f;
|
||||
frame.SelectedColor = Color.Gold * 0.5f;
|
||||
|
||||
GUITextBlock textBlock = new GUITextBlock(
|
||||
new Rectangle(40, 0, 0, 25),
|
||||
ep.Name,
|
||||
Color.Transparent, Color.Black,
|
||||
Alignment.Left,
|
||||
Alignment.Left,
|
||||
frame);
|
||||
textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
|
||||
|
||||
if (ep.sprite != null)
|
||||
{
|
||||
GUIImage img = new GUIImage(new Rectangle(0, 0, 40, 40), ep.sprite, Alignment.Left, frame);
|
||||
img.Scale = Math.Min(Math.Min(40.0f / img.SourceRect.Width, 40.0f / img.SourceRect.Height), 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Select()
|
||||
{
|
||||
base.Select();
|
||||
|
||||
GUIComponent.MouseOn = null;
|
||||
characterMode = false;
|
||||
//CreateDummyCharacter();
|
||||
}
|
||||
|
||||
public override void Deselect()
|
||||
{
|
||||
base.Deselect();
|
||||
|
||||
GUIComponent.MouseOn = null;
|
||||
|
||||
if (dummyCharacter != null)
|
||||
{
|
||||
dummyCharacter.Remove();
|
||||
dummyCharacter = null;
|
||||
Game1.world.ProcessChanges();
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateDummyCharacter()
|
||||
{
|
||||
if (dummyCharacter != null) dummyCharacter.Remove();
|
||||
|
||||
dummyCharacter = new Character("Content/Characters/Human/human.xml", Vector2.Zero);
|
||||
Character.Controlled = dummyCharacter;
|
||||
Game1.world.ProcessChanges();
|
||||
}
|
||||
|
||||
private bool SelectTab(GUIButton button, object obj)
|
||||
{
|
||||
selectedTab = (int)obj;
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ToggleCharacterMode(GUIButton button, object obj)
|
||||
{
|
||||
characterMode = !characterMode;
|
||||
button.Color = (characterMode) ? Color.Gold : Color.White;
|
||||
|
||||
if (characterMode)
|
||||
{
|
||||
CreateDummyCharacter();
|
||||
}
|
||||
else if (dummyCharacter != null)
|
||||
{
|
||||
dummyCharacter.Remove();
|
||||
dummyCharacter = null;
|
||||
}
|
||||
|
||||
foreach (MapEntity me in MapEntity.mapEntityList)
|
||||
{
|
||||
me.IsHighlighted = false;
|
||||
me.IsSelected = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool SelectPrefab(object obj)
|
||||
{
|
||||
MapEntityPrefab.SelectPrefab(obj);
|
||||
selectedTab = -1;
|
||||
GUIComponent.MouseOn = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <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>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
//Vector2 mousePosition = new Vector2(PlayerInput.GetMouseState.X, PlayerInput.GetMouseState.Y);
|
||||
//mousePosition = cam.ScreenToWorld(mousePosition);
|
||||
|
||||
//if (!Character.characterList.Contains(dummyCharacter))
|
||||
//{
|
||||
// CreateDummyCharacter();
|
||||
//}
|
||||
|
||||
cam.MoveCamera((float)deltaTime);
|
||||
cam.Zoom = MathHelper.Clamp(cam.Zoom + PlayerInput.ScrollWheelSpeed/1000.0f,0.1f, 2.0f);
|
||||
|
||||
if (characterMode)
|
||||
{
|
||||
foreach (MapEntity me in MapEntity.mapEntityList)
|
||||
{
|
||||
me.IsHighlighted = false;
|
||||
}
|
||||
|
||||
if (dummyCharacter.SelectedConstruction==null)
|
||||
{
|
||||
Vector2 mouseSimPos = FarseerPhysics.ConvertUnits.ToSimUnits(cam.ScreenToWorld(PlayerInput.MousePosition));
|
||||
foreach (Limb limb in dummyCharacter.animController.limbs)
|
||||
{
|
||||
limb.body.SetTransform(mouseSimPos, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
dummyCharacter.ControlLocalPlayer(cam, false);
|
||||
dummyCharacter.Control(cam);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
MapEntity.UpdateSelecting(cam);
|
||||
}
|
||||
|
||||
|
||||
GUIpanel.Update((float)deltaTime);
|
||||
if (selectedTab > -1)
|
||||
{
|
||||
GUItabs[selectedTab].Update((float)deltaTime);
|
||||
if (PlayerInput.RightButtonClicked()) selectedTab = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called when the game should draw itself.
|
||||
/// </summary>
|
||||
/// <param name="gameTime">Provides a snapshot of timing values.</param>
|
||||
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
|
||||
{
|
||||
//cam.UpdateTransform();
|
||||
|
||||
spriteBatch.Begin(SpriteSortMode.BackToFront,
|
||||
BlendState.AlphaBlend,
|
||||
null, null, null, null,
|
||||
cam.Transform);
|
||||
|
||||
graphics.Clear(new Color(0.051f, 0.149f, 0.271f, 1.0f));
|
||||
|
||||
Map.Draw(spriteBatch, true);
|
||||
|
||||
if (!characterMode)
|
||||
{
|
||||
if (MapEntityPrefab.Selected != null) MapEntityPrefab.Selected.UpdatePlacing(spriteBatch, cam);
|
||||
|
||||
MapEntity.DrawSelecting(spriteBatch, cam);
|
||||
}
|
||||
|
||||
spriteBatch.End();
|
||||
|
||||
//-------------------- HUD -----------------------------
|
||||
|
||||
spriteBatch.Begin();
|
||||
|
||||
GUIpanel.Draw(spriteBatch);
|
||||
|
||||
if (selectedTab > -1) GUItabs[selectedTab].Draw(spriteBatch);
|
||||
|
||||
GUI.Draw((float)deltaTime, spriteBatch);
|
||||
|
||||
//EntityPrefab.DrawList(spriteBatch, new Vector2(20,50));
|
||||
|
||||
|
||||
|
||||
if (characterMode)
|
||||
{
|
||||
if (dummyCharacter != null && dummyCharacter.SelectedConstruction != null)
|
||||
{
|
||||
if (dummyCharacter.SelectedConstruction == dummyCharacter.ClosestItem)
|
||||
{
|
||||
dummyCharacter.SelectedConstruction.DrawHUD(spriteBatch, dummyCharacter);
|
||||
}
|
||||
else
|
||||
{
|
||||
dummyCharacter.SelectedConstruction = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (PlayerInput.GetMouseState.LeftButton != ButtonState.Pressed)
|
||||
{
|
||||
//if (Inventory.draggingItem!=null)
|
||||
//{
|
||||
// Inventory.draggingItem.see
|
||||
//}
|
||||
Inventory.draggingItem = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MapEntity.Edit(spriteBatch, cam);
|
||||
}
|
||||
|
||||
|
||||
|
||||
spriteBatch.End();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<PublishUrlHistory>publish\</PublishUrlHistory>
|
||||
<InstallUrlHistory />
|
||||
<SupportUrlHistory />
|
||||
<UpdateUrlHistory />
|
||||
<BootstrapperUrlHistory />
|
||||
<ErrorReportUrlHistory />
|
||||
<FallbackCulture>en-US</FallbackCulture>
|
||||
<VerifyUploadedFiles>false</VerifyUploadedFiles>
|
||||
<ProjectView>ShowAllFiles</ProjectView>
|
||||
</PropertyGroup>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<PublishUrlHistory>publish\</PublishUrlHistory>
|
||||
<InstallUrlHistory />
|
||||
<SupportUrlHistory />
|
||||
<UpdateUrlHistory />
|
||||
<BootstrapperUrlHistory />
|
||||
<ErrorReportUrlHistory />
|
||||
<FallbackCulture>en-US</FallbackCulture>
|
||||
<VerifyUploadedFiles>false</VerifyUploadedFiles>
|
||||
<ProjectView>ProjectFiles</ProjectView>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
Binary file not shown.
Reference in New Issue
Block a user