- multiple submarines can be "merged" into one file (to be used as escape vessels etc)
- WIP docking ports
This commit is contained in:
@@ -118,6 +118,7 @@
|
|||||||
<Compile Include="Source\GUI\GUIDropDown.cs" />
|
<Compile Include="Source\GUI\GUIDropDown.cs" />
|
||||||
<Compile Include="Source\GUI\GUIMessage.cs" />
|
<Compile Include="Source\GUI\GUIMessage.cs" />
|
||||||
<Compile Include="Source\GUI\LoadingScreen.cs" />
|
<Compile Include="Source\GUI\LoadingScreen.cs" />
|
||||||
|
<Compile Include="Source\Items\Components\DockingPort.cs" />
|
||||||
<Compile Include="Source\Items\Components\Holdable\MeleeWeapon.cs" />
|
<Compile Include="Source\Items\Components\Holdable\MeleeWeapon.cs" />
|
||||||
<Compile Include="Source\Items\Components\Holdable\Propulsion.cs" />
|
<Compile Include="Source\Items\Components\Holdable\Propulsion.cs" />
|
||||||
<Compile Include="Source\Items\Components\Machines\Deconstructor.cs" />
|
<Compile Include="Source\Items\Components\Machines\Deconstructor.cs" />
|
||||||
@@ -143,6 +144,7 @@
|
|||||||
<Compile Include="Source\Map\Lights\LightSource.cs" />
|
<Compile Include="Source\Map\Lights\LightSource.cs" />
|
||||||
<Compile Include="Source\Map\Map\LocationType.cs" />
|
<Compile Include="Source\Map\Map\LocationType.cs" />
|
||||||
<Compile Include="Source\Map\SubmarineBody.cs" />
|
<Compile Include="Source\Map\SubmarineBody.cs" />
|
||||||
|
<Compile Include="Source\Map\SubmarineLink.cs" />
|
||||||
<Compile Include="Source\Map\TransitionCinematic.cs" />
|
<Compile Include="Source\Map\TransitionCinematic.cs" />
|
||||||
<Compile Include="Source\Networking\BanList.cs" />
|
<Compile Include="Source\Networking\BanList.cs" />
|
||||||
<Compile Include="Source\Networking\ChatMessage.cs" />
|
<Compile Include="Source\Networking\ChatMessage.cs" />
|
||||||
@@ -492,6 +494,9 @@
|
|||||||
<Content Include="Content\Items\blank.png">
|
<Content Include="Content\Items\blank.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="Content\Items\Door\dockingport.png">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Include="Content\Items\Jobgear\captainLegs.png">
|
<Content Include="Content\Items\Jobgear\captainLegs.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
@@ -82,4 +82,29 @@
|
|||||||
<output name="state_out"/>
|
<output name="state_out"/>
|
||||||
</ConnectionPanel>
|
</ConnectionPanel>
|
||||||
</Item>
|
</Item>
|
||||||
|
|
||||||
|
<Item
|
||||||
|
name="Docking Port"
|
||||||
|
linkable="true"
|
||||||
|
pickdistance="150.0">
|
||||||
|
|
||||||
|
<Sprite texture ="dockingport.png" sourcerect="0,0,112,208" depth="0.95" origin="0.5,0.5"/>
|
||||||
|
|
||||||
|
<DockingPort IsHorizontal="true" DistanceTolerance="128,64" DockedDistance="64">
|
||||||
|
<Sprite texture ="dockingport.png" sourcerect="112,0,112,208" depth="0.05" origin="0.5,0.5"/>
|
||||||
|
<sound file="door.ogg" type="OnUse" range="500.0"/>
|
||||||
|
</DockingPort>
|
||||||
|
|
||||||
|
<fixrequirement name="Mechanical repairs">
|
||||||
|
<skill name="Construction" level="60"/>
|
||||||
|
<item name="Welding Tool"/>
|
||||||
|
</fixrequirement>
|
||||||
|
|
||||||
|
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
|
||||||
|
<requireditem name="Screwdriver" type="Equipped"/>
|
||||||
|
<input name="toggle"/>
|
||||||
|
<input name="set_state"/>
|
||||||
|
<output name="state_out"/>
|
||||||
|
</ConnectionPanel>
|
||||||
|
</Item>
|
||||||
</Items>
|
</Items>
|
||||||
@@ -103,7 +103,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private Vector2 DiffToCurrentNode()
|
private Vector2 DiffToCurrentNode()
|
||||||
{
|
{
|
||||||
if (currentPath == null) return Vector2.Zero;
|
if (currentPath == null || currentPath.Finished) return Vector2.Zero;
|
||||||
|
|
||||||
if (currentPath.Finished)
|
if (currentPath.Finished)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -616,20 +616,7 @@ namespace Barotrauma
|
|||||||
while (ce != null && ce.Contact != null)
|
while (ce != null && ce.Contact != null)
|
||||||
{
|
{
|
||||||
ce.Contact.Enabled = false;
|
ce.Contact.Enabled = false;
|
||||||
//if (ce.Contact.IsTouching && ce.Contact.Enabled &&
|
|
||||||
// ((inToOut && ce.Contact.FixtureA.Body.UserData is Structure) || (!inToOut && ce.Contact.FixtureA.Body.UserData is Submarine)))
|
|
||||||
//{
|
|
||||||
// Vector2 normal;
|
|
||||||
// FarseerPhysics.Common.FixedArray2<Vector2> worldPoints;
|
|
||||||
// ce.Contact.GetWorldManifold(out normal, out worldPoints);
|
|
||||||
|
|
||||||
// foreach (Limb limb2 in Limbs)
|
|
||||||
// {
|
|
||||||
// limb2.body.FarseerBody.ApplyLinearImpulse(limb2.Mass * normal);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return false;
|
|
||||||
//}
|
|
||||||
ce = ce.Next;
|
ce = ce.Next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -639,7 +626,7 @@ namespace Barotrauma
|
|||||||
limb.body.LinearVelocity += velocityChange;
|
limb.body.LinearVelocity += velocityChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
character.Stun = 0.1f;
|
//character.Stun = 0.1f;
|
||||||
character.DisableImpactDamageTimer = 0.25f;
|
character.DisableImpactDamageTimer = 0.25f;
|
||||||
|
|
||||||
SetPosition(refLimb.SimPosition + moveAmount);
|
SetPosition(refLimb.SimPosition + moveAmount);
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (parent != null) parent.AddChild(this);
|
if (parent != null) parent.AddChild(this);
|
||||||
|
|
||||||
button = new GUIButton(Rectangle.Empty, "", Color.White, Alignment.TopLeft, Alignment.TopLeft, null, this);
|
button = new GUIButton(Rectangle.Empty, text, Color.White, Alignment.TopLeft, Alignment.TopLeft, null, this);
|
||||||
|
|
||||||
button.TextColor = Color.White;
|
button.TextColor = Color.White;
|
||||||
button.Color = Color.Black * 0.8f;
|
button.Color = Color.Black * 0.8f;
|
||||||
|
|||||||
@@ -0,0 +1,367 @@
|
|||||||
|
using FarseerPhysics;
|
||||||
|
using FarseerPhysics.Dynamics;
|
||||||
|
using FarseerPhysics.Dynamics.Joints;
|
||||||
|
using FarseerPhysics.Factories;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma.Items.Components
|
||||||
|
{
|
||||||
|
|
||||||
|
class DockingPort : ItemComponent, IDrawableComponent
|
||||||
|
{
|
||||||
|
private static List<DockingPort> list = new List<DockingPort>();
|
||||||
|
|
||||||
|
private Sprite overlaySprite;
|
||||||
|
|
||||||
|
private Vector2 distanceTolerance;
|
||||||
|
|
||||||
|
private DockingPort dockingTarget;
|
||||||
|
|
||||||
|
private float dockingState;
|
||||||
|
|
||||||
|
private Joint joint;
|
||||||
|
|
||||||
|
private int dockingDir;
|
||||||
|
|
||||||
|
private Hull[] hulls;
|
||||||
|
|
||||||
|
private Body[] bodies;
|
||||||
|
|
||||||
|
private Gap gap;
|
||||||
|
|
||||||
|
[HasDefaultValue("32.0,32.0", false)]
|
||||||
|
public string DistanceTolerance
|
||||||
|
{
|
||||||
|
get { return ToolBox.Vector2ToString(distanceTolerance); }
|
||||||
|
set { distanceTolerance = ToolBox.ParseToVector2(value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
[HasDefaultValue(32.0f, false)]
|
||||||
|
public float DockedDistance
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HasDefaultValue(true, false)]
|
||||||
|
public bool IsHorizontal
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool IsActive
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return base.IsActive;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (!IsActive && value)
|
||||||
|
{
|
||||||
|
if (dockingTarget == null) AttemptDock();
|
||||||
|
if (dockingTarget == null) return;
|
||||||
|
|
||||||
|
base.IsActive = value;
|
||||||
|
}
|
||||||
|
else if (IsActive && !value)
|
||||||
|
{
|
||||||
|
Undock();
|
||||||
|
}
|
||||||
|
|
||||||
|
//base.IsActive = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DockingPort(Item item, XElement element)
|
||||||
|
: base(item, element)
|
||||||
|
{
|
||||||
|
// isOpen = false;
|
||||||
|
foreach (XElement subElement in element.Elements())
|
||||||
|
{
|
||||||
|
string texturePath = ToolBox.GetAttributeString(subElement, "texture", "");
|
||||||
|
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||||
|
{
|
||||||
|
case "sprite":
|
||||||
|
overlaySprite = new Sprite(subElement, texturePath.Contains("/") ? "" : Path.GetDirectoryName(item.Prefab.ConfigFile));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list.Add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AttemptDock()
|
||||||
|
{
|
||||||
|
foreach (DockingPort port in list)
|
||||||
|
{
|
||||||
|
if (port == this || port.item.Submarine == item.Submarine) continue;
|
||||||
|
|
||||||
|
if (Math.Abs(port.item.WorldPosition.X - item.WorldPosition.X) > distanceTolerance.X) continue;
|
||||||
|
if (Math.Abs(port.item.WorldPosition.Y - item.WorldPosition.Y) > distanceTolerance.Y) continue;
|
||||||
|
|
||||||
|
Dock(port);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Dock(DockingPort target)
|
||||||
|
{
|
||||||
|
if (dockingTarget!=null)
|
||||||
|
{
|
||||||
|
Undock();
|
||||||
|
}
|
||||||
|
|
||||||
|
dockingTarget = target;
|
||||||
|
dockingTarget.dockingTarget = this;
|
||||||
|
dockingTarget.IsActive = true;
|
||||||
|
|
||||||
|
dockingDir = Math.Sign(dockingTarget.item.WorldPosition.X - item.WorldPosition.X);
|
||||||
|
dockingTarget.dockingDir = -dockingDir;
|
||||||
|
|
||||||
|
CreateJoint(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void CreateJoint(bool useWeldJoint)
|
||||||
|
{
|
||||||
|
Vector2 offset = (IsHorizontal ?
|
||||||
|
Vector2.UnitX * Math.Sign(dockingTarget.item.WorldPosition.X - item.WorldPosition.X) :
|
||||||
|
Vector2.UnitY * Math.Sign(dockingTarget.item.WorldPosition.Y - item.WorldPosition.Y));
|
||||||
|
offset *= DockedDistance * 0.5f;
|
||||||
|
|
||||||
|
Vector2 pos1 = item.WorldPosition + offset;
|
||||||
|
|
||||||
|
Vector2 pos2 = dockingTarget.item.WorldPosition - offset;
|
||||||
|
|
||||||
|
if (useWeldJoint)
|
||||||
|
{
|
||||||
|
joint = JointFactory.CreateWeldJoint(GameMain.World,
|
||||||
|
item.Submarine.SubBody.Body, dockingTarget.item.Submarine.SubBody.Body,
|
||||||
|
ConvertUnits.ToSimUnits(pos1), FarseerPhysics.ConvertUnits.ToSimUnits(pos2), true);
|
||||||
|
|
||||||
|
((WeldJoint)joint).FrequencyHz = 1.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var distanceJoint = JointFactory.CreateDistanceJoint(GameMain.World,
|
||||||
|
item.Submarine.SubBody.Body, dockingTarget.item.Submarine.SubBody.Body,
|
||||||
|
ConvertUnits.ToSimUnits(pos1), FarseerPhysics.ConvertUnits.ToSimUnits(pos2), true);
|
||||||
|
|
||||||
|
distanceJoint.Length = 0.01f;
|
||||||
|
distanceJoint.Frequency = 1.0f;
|
||||||
|
distanceJoint.DampingRatio = 0.8f;
|
||||||
|
|
||||||
|
joint = distanceJoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
joint.CollideConnected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateHull()
|
||||||
|
{
|
||||||
|
var hullRects = new Rectangle[] { item.WorldRect, dockingTarget.item.WorldRect };
|
||||||
|
var subs = new Submarine[] { item.Submarine, dockingTarget.item.Submarine };
|
||||||
|
|
||||||
|
hulls = new Hull[2];
|
||||||
|
bodies = new Body[4];
|
||||||
|
if (IsHorizontal)
|
||||||
|
{
|
||||||
|
if (hullRects[0].Center.X > hullRects[1].Center.X)
|
||||||
|
{
|
||||||
|
hullRects = new Rectangle[] { dockingTarget.item.WorldRect, item.WorldRect };
|
||||||
|
subs = new Submarine[] { dockingTarget.item.Submarine,item.Submarine };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
hullRects[0] = new Rectangle(hullRects[0].Center.X, hullRects[0].Y, ((int)DockedDistance / 2), hullRects[0].Height);
|
||||||
|
hullRects[1] = new Rectangle(hullRects[1].Center.X - ((int)DockedDistance / 2), hullRects[1].Y, ((int)DockedDistance / 2), hullRects[1].Height);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < 2;i++ )
|
||||||
|
{
|
||||||
|
hullRects[i].Location -= (subs[i].WorldPosition - subs[i].HiddenSubPosition).ToPoint();
|
||||||
|
hulls[i] = new Hull(MapEntityPrefab.list.Find(m => m.Name == "Hull"), hullRects[i], subs[i]);
|
||||||
|
hulls[i].AddToGrid(subs[i]);
|
||||||
|
|
||||||
|
|
||||||
|
for (int j = 0; j < 2; j++)
|
||||||
|
{
|
||||||
|
bodies[i + j * 2] = BodyFactory.CreateEdge(GameMain.World,
|
||||||
|
ConvertUnits.ToSimUnits(new Vector2(hullRects[i].X, hullRects[i].Y - hullRects[i].Height * j)),
|
||||||
|
ConvertUnits.ToSimUnits(new Vector2(hullRects[i].Right, hullRects[i].Y - hullRects[i].Height * j)));
|
||||||
|
|
||||||
|
//bodies[i + j * 2] = BodyFactory.CreateRectangle(GameMain.World, ConvertUnits.ToSimUnits(hullRects[i].Width), 0.1f, 5.0f);
|
||||||
|
//bodies[i + j * 2].SetTransform(ConvertUnits.ToSimUnits(new Vector2(hullRects[i].Center.X, hullRects[i].Y - (hullRects[i].Height+5) * j)), 0.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gap = new Gap(new Rectangle(hullRects[0].Right-2, hullRects[0].Y, 4, hullRects[0].Height), true, item.Submarine);
|
||||||
|
gap.linkedTo.Clear();
|
||||||
|
gap.linkedTo.Add(hulls[0]);
|
||||||
|
gap.linkedTo.Add(hulls[1]);
|
||||||
|
|
||||||
|
//var hullRect1 = new Rectangle(hullRects.Min(h => h.Center.X), hullRect.Y, ((int)DockedDistance / 2), hullRects[0].Height);
|
||||||
|
//var hullRect2 = new Rectangle(hullRects.Max(h => h.Center.X), hullRect.Y, ((int)DockedDistance / 2), hullRects[0].Height);
|
||||||
|
|
||||||
|
//var sub1 = hullRect.Center.X < targetRect.Center.X ? item.Submarine : dockingTarget.item.Submarine;
|
||||||
|
//var sub2 = hullRect.Center.X > targetRect.Center.X ? item.Submarine : dockingTarget.item.Submarine;
|
||||||
|
|
||||||
|
// hullRect1.Location -= (sub1.WorldPosition - sub1.HiddenSubPosition).ToPoint();
|
||||||
|
//hulls[0] = new Hull(MapEntityPrefab.list.Find(m => m.Name == "Hull"), hullRect1, sub1);
|
||||||
|
//hulls[0].AddToGrid(sub1);
|
||||||
|
|
||||||
|
//hullRect2.Location -= (sub2.WorldPosition - sub2.HiddenSubPosition).ToPoint();
|
||||||
|
//hulls[1] = new Hull(MapEntityPrefab.list.Find(m => m.Name == "Hull"), hullRect2, sub2);
|
||||||
|
//hulls[1].AddToGrid(sub2);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//hullRect = new Rectangle(hullRect.X,
|
||||||
|
// Math.Max(hullRect.Y - hullRect.Height / 2, targetRect.Y - targetRect.Height / 2), hullRect.Width, (int)DockedDistance);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Body body in bodies)
|
||||||
|
{
|
||||||
|
body.BodyType = BodyType.Static;
|
||||||
|
body.Friction = 0.5f;
|
||||||
|
|
||||||
|
body.CollisionCategories = Physics.CollisionWall;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Undock()
|
||||||
|
{
|
||||||
|
if (dockingTarget == null) return;
|
||||||
|
|
||||||
|
dockingTarget.dockingTarget = null;
|
||||||
|
dockingTarget.IsActive = false;
|
||||||
|
|
||||||
|
dockingTarget = null;
|
||||||
|
|
||||||
|
GameMain.World.RemoveJoint(joint);
|
||||||
|
joint = null;
|
||||||
|
|
||||||
|
hulls[0].Remove();
|
||||||
|
hulls[1].Remove();
|
||||||
|
|
||||||
|
gap.Remove();
|
||||||
|
gap = null;
|
||||||
|
|
||||||
|
foreach (Body body in bodies)
|
||||||
|
{
|
||||||
|
GameMain.World.RemoveBody(body);
|
||||||
|
}
|
||||||
|
bodies = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//foreach (Gap g in hulls[0].ConnectedGaps)
|
||||||
|
//{
|
||||||
|
// g.Remove();
|
||||||
|
//}
|
||||||
|
|
||||||
|
//foreach (Gap g in hulls[1].ConnectedGaps)
|
||||||
|
//{
|
||||||
|
// g.Remove();
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
hulls = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(float deltaTime, Camera cam)
|
||||||
|
{
|
||||||
|
if (dockingTarget==null)
|
||||||
|
{
|
||||||
|
dockingState = MathHelper.Lerp(dockingState, 0.0f, deltaTime * 10.0f);
|
||||||
|
if (dockingState < 0.01f) base.IsActive = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (joint is DistanceJoint && Vector2.Distance(joint.WorldAnchorA, joint.WorldAnchorB) < 0.05f)
|
||||||
|
{
|
||||||
|
GameMain.World.RemoveJoint(joint);
|
||||||
|
|
||||||
|
CreateJoint(true);
|
||||||
|
CreateHull();
|
||||||
|
}
|
||||||
|
|
||||||
|
dockingState = MathHelper.Lerp(dockingState, 1.0f, deltaTime * 10.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Draw(SpriteBatch spriteBatch, bool editing)
|
||||||
|
{
|
||||||
|
if (dockingState == 0.0f) return;
|
||||||
|
|
||||||
|
Vector2 drawPos = item.DrawPosition;
|
||||||
|
drawPos.Y = -drawPos.Y;
|
||||||
|
|
||||||
|
var rect = overlaySprite.SourceRect;
|
||||||
|
drawPos.Y -= rect.Height / 2;
|
||||||
|
|
||||||
|
if (IsHorizontal)
|
||||||
|
{
|
||||||
|
if (dockingDir == 1)
|
||||||
|
{
|
||||||
|
spriteBatch.Draw(overlaySprite.Texture,
|
||||||
|
drawPos,
|
||||||
|
new Rectangle(
|
||||||
|
rect.Center.X + (int)(rect.Width / 2 * (1.0f - dockingState)), rect.Y,
|
||||||
|
(int)(rect.Width / 2 * dockingState), rect.Height), Color.White);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spriteBatch.Draw(overlaySprite.Texture,
|
||||||
|
drawPos - Vector2.UnitX * (rect.Width / 2 * dockingState),
|
||||||
|
new Rectangle(
|
||||||
|
rect.X, rect.Y,
|
||||||
|
(int)(rect.Width / 2 * dockingState), rect.Height), Color.Red);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dockingDir == 1)
|
||||||
|
{
|
||||||
|
spriteBatch.Draw(overlaySprite.Texture,
|
||||||
|
drawPos,
|
||||||
|
new Rectangle(
|
||||||
|
rect.X, rect.Y + rect.Height/2 + (int)(rect.Height / 2 * (1.0f - dockingState)),
|
||||||
|
rect.Width, (int)(rect.Height / 2 * dockingState)), Color.White);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spriteBatch.Draw(overlaySprite.Texture,
|
||||||
|
drawPos - Vector2.UnitY * (rect.Height / 2 * dockingState),
|
||||||
|
new Rectangle(
|
||||||
|
rect.X, rect.Y,
|
||||||
|
rect.Width, (int)(rect.Height / 2 * dockingState)), Color.Red);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void RemoveComponentSpecific()
|
||||||
|
{
|
||||||
|
list.Remove(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1432,7 +1432,7 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override XElement Save(XDocument doc)
|
public override XElement Save(XElement parentElement)
|
||||||
{
|
{
|
||||||
XElement element = new XElement("Item");
|
XElement element = new XElement("Item");
|
||||||
|
|
||||||
@@ -1475,7 +1475,7 @@ namespace Barotrauma
|
|||||||
ic.Save(element);
|
ic.Save(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
doc.Root.Add(element);
|
parentElement.Add(element);
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -639,7 +639,7 @@ namespace Barotrauma
|
|||||||
FindHulls();
|
FindHulls();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override XElement Save(XDocument doc)
|
public override XElement Save(XElement parentElement)
|
||||||
{
|
{
|
||||||
XElement element = new XElement("Gap");
|
XElement element = new XElement("Gap");
|
||||||
|
|
||||||
@@ -663,7 +663,7 @@ namespace Barotrauma
|
|||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
doc.Root.Add(element);
|
parentElement.Add(element);
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -260,6 +260,21 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddToGrid(Submarine submarine)
|
||||||
|
{
|
||||||
|
foreach (EntityGrid grid in entityGrids)
|
||||||
|
{
|
||||||
|
if (grid.Submarine != submarine) continue;
|
||||||
|
|
||||||
|
rect.Location -= submarine.HiddenSubPosition.ToPoint();
|
||||||
|
|
||||||
|
grid.InsertEntity(this);
|
||||||
|
|
||||||
|
rect.Location += submarine.HiddenSubPosition.ToPoint();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override bool IsMouseOn(Vector2 position)
|
public override bool IsMouseOn(Vector2 position)
|
||||||
{
|
{
|
||||||
if (!GameMain.DebugDraw && !ShowHulls) return false;
|
if (!GameMain.DebugDraw && !ShowHulls) return false;
|
||||||
@@ -295,6 +310,7 @@ namespace Barotrauma
|
|||||||
public override void Remove()
|
public override void Remove()
|
||||||
{
|
{
|
||||||
base.Remove();
|
base.Remove();
|
||||||
|
hullList.Remove(this);
|
||||||
|
|
||||||
if (Submarine == null || !Submarine.Loading)
|
if (Submarine == null || !Submarine.Loading)
|
||||||
{
|
{
|
||||||
@@ -324,7 +340,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
hullList.Remove(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddFireSource(FireSource fireSource, bool createNetworkEvent = true)
|
public void AddFireSource(FireSource fireSource, bool createNetworkEvent = true)
|
||||||
@@ -712,7 +727,7 @@ namespace Barotrauma
|
|||||||
// return gaps;
|
// return gaps;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
public override XElement Save(XDocument doc)
|
public override XElement Save(XElement parentElement)
|
||||||
{
|
{
|
||||||
XElement element = new XElement("Hull");
|
XElement element = new XElement("Hull");
|
||||||
|
|
||||||
@@ -725,8 +740,8 @@ namespace Barotrauma
|
|||||||
rect.Width + "," + rect.Height),
|
rect.Width + "," + rect.Height),
|
||||||
new XAttribute("water", volume)
|
new XAttribute("water", volume)
|
||||||
);
|
);
|
||||||
|
|
||||||
doc.Root.Add(element);
|
parentElement.Add(element);
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -596,7 +596,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public virtual XElement Save(XDocument doc)
|
public virtual XElement Save(XElement parentElement)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Saving entity " + GetType() + " failed.");
|
DebugConsole.ThrowError("Saving entity " + GetType() + " failed.");
|
||||||
return null;
|
return null;
|
||||||
@@ -625,15 +625,29 @@ namespace Barotrauma
|
|||||||
if (linked != null) e.linkedTo.Add(linked);
|
if (linked != null) e.linkedTo.Add(linked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<LinkedSubmarine> linkedSubs = new List<LinkedSubmarine>();
|
||||||
|
|
||||||
for (int i = 0; i<mapEntityList.Count; i++)
|
for (int i = 0; i<mapEntityList.Count; i++)
|
||||||
{
|
{
|
||||||
if (mapEntityList[i].Submarine != sub) continue;
|
if (mapEntityList[i].Submarine != sub) continue;
|
||||||
|
|
||||||
|
if (mapEntityList[i] is LinkedSubmarine)
|
||||||
|
{
|
||||||
|
linkedSubs.Add((LinkedSubmarine)mapEntityList[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
mapEntityList[i].OnMapLoaded();
|
mapEntityList[i].OnMapLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
Item.UpdateHulls();
|
Item.UpdateHulls();
|
||||||
Gap.UpdateHulls();
|
Gap.UpdateHulls();
|
||||||
|
|
||||||
|
foreach (LinkedSubmarine linkedSub in linkedSubs)
|
||||||
|
{
|
||||||
|
linkedSub.OnMapLoaded();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -114,6 +114,11 @@ namespace Barotrauma
|
|||||||
ep.name = "Spawnpoint";
|
ep.name = "Spawnpoint";
|
||||||
ep.constructor = typeof(WayPoint).GetConstructor(new Type[] { typeof(MapEntityPrefab), typeof(Rectangle) });
|
ep.constructor = typeof(WayPoint).GetConstructor(new Type[] { typeof(MapEntityPrefab), typeof(Rectangle) });
|
||||||
list.Add(ep);
|
list.Add(ep);
|
||||||
|
|
||||||
|
//ep = new MapEntityPrefab();
|
||||||
|
//ep.name = "Linked Submarine";
|
||||||
|
//ep.Category = 0;
|
||||||
|
//list.Add(ep);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,8 +159,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (PlayerInput.LeftButtonReleased())
|
if (PlayerInput.LeftButtonReleased())
|
||||||
{
|
{
|
||||||
object[] lobject = new object[] { this, newRect };
|
CreateInstance(newRect);
|
||||||
constructor.Invoke(lobject);
|
|
||||||
placePosition = Vector2.Zero;
|
placePosition = Vector2.Zero;
|
||||||
selected = null;
|
selected = null;
|
||||||
}
|
}
|
||||||
@@ -170,7 +174,12 @@ namespace Barotrauma
|
|||||||
selected = null;
|
selected = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void CreateInstance(Rectangle rect)
|
||||||
|
{
|
||||||
|
object[] lobject = new object[] { this, rect };
|
||||||
|
constructor.Invoke(lobject);
|
||||||
|
}
|
||||||
|
|
||||||
public static bool SelectPrefab(object selection)
|
public static bool SelectPrefab(object selection)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -668,7 +668,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override XElement Save(XDocument doc)
|
public override XElement Save(XElement parentElement)
|
||||||
{
|
{
|
||||||
XElement element = new XElement("Structure");
|
XElement element = new XElement("Structure");
|
||||||
|
|
||||||
@@ -696,7 +696,7 @@ namespace Barotrauma
|
|||||||
element.Add(sectionElement);
|
element.Add(sectionElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
doc.Root.Add(element);
|
parentElement.Add(element);
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (hash != null) return hash;
|
if (hash != null) return hash;
|
||||||
|
|
||||||
XDocument doc = OpenDoc(filePath);
|
XDocument doc = OpenFile(filePath);
|
||||||
hash = new Md5Hash(doc);
|
hash = new Md5Hash(doc);
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
@@ -223,7 +223,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (tryLoad)
|
if (tryLoad)
|
||||||
{
|
{
|
||||||
XDocument doc = OpenDoc(filePath);
|
XDocument doc = OpenFile(filePath);
|
||||||
|
|
||||||
if (doc != null && doc.Root != null)
|
if (doc != null && doc.Root != null)
|
||||||
{
|
{
|
||||||
@@ -438,7 +438,19 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!MathUtils.IsValid(position)) return;
|
if (!MathUtils.IsValid(position)) return;
|
||||||
|
|
||||||
|
Vector2 prevPos = subBody.Position;
|
||||||
|
|
||||||
subBody.SetPosition(position);
|
subBody.SetPosition(position);
|
||||||
|
|
||||||
|
foreach (Submarine sub in loaded)
|
||||||
|
{
|
||||||
|
if (sub != this && sub.Submarine == this)
|
||||||
|
{
|
||||||
|
sub.SetPosition(position + sub.WorldPosition);
|
||||||
|
sub.Submarine = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
//Level.Loaded.SetPosition(-position);
|
//Level.Loaded.SetPosition(-position);
|
||||||
//prevPosition = position;
|
//prevPosition = position;
|
||||||
}
|
}
|
||||||
@@ -532,7 +544,7 @@ namespace Barotrauma
|
|||||||
foreach (MapEntity e in MapEntity.mapEntityList)
|
foreach (MapEntity e in MapEntity.mapEntityList)
|
||||||
{
|
{
|
||||||
if (e.MoveWithLevel ||e.Submarine != this) continue;
|
if (e.MoveWithLevel ||e.Submarine != this) continue;
|
||||||
e.Save(doc);
|
e.Save(doc.Root);
|
||||||
}
|
}
|
||||||
|
|
||||||
hash = new Md5Hash(doc);
|
hash = new Md5Hash(doc);
|
||||||
@@ -648,7 +660,7 @@ namespace Barotrauma
|
|||||||
//if (GameMain.NetLobbyScreen!=null) GameMain.NetLobbyScreen.UpdateSubList(Submarine.SavedSubmarines);
|
//if (GameMain.NetLobbyScreen!=null) GameMain.NetLobbyScreen.UpdateSubList(Submarine.SavedSubmarines);
|
||||||
}
|
}
|
||||||
|
|
||||||
private XDocument OpenDoc(string file)
|
public static XDocument OpenFile(string file)
|
||||||
{
|
{
|
||||||
XDocument doc = null;
|
XDocument doc = null;
|
||||||
string extension = "";
|
string extension = "";
|
||||||
@@ -718,16 +730,21 @@ namespace Barotrauma
|
|||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Load(bool unloadPrevious)
|
public void Load(bool unloadPrevious, XElement submarineElement = null)
|
||||||
{
|
{
|
||||||
if (unloadPrevious) Unload();
|
if (unloadPrevious) Unload();
|
||||||
|
|
||||||
Loading = true;
|
Loading = true;
|
||||||
|
|
||||||
XDocument doc = OpenDoc(filePath);
|
if (submarineElement == null)
|
||||||
if (doc == null || doc.Root == null) return;
|
{
|
||||||
|
XDocument doc = OpenFile(filePath);
|
||||||
|
if (doc == null || doc.Root == null) return;
|
||||||
|
|
||||||
Description = ToolBox.GetAttributeString(doc.Root, "description", "");
|
submarineElement = doc.Root;
|
||||||
|
}
|
||||||
|
|
||||||
|
Description = ToolBox.GetAttributeString(submarineElement, "description", "");
|
||||||
|
|
||||||
|
|
||||||
HiddenSubPosition = HiddenSubStartPosition;
|
HiddenSubPosition = HiddenSubStartPosition;
|
||||||
@@ -742,7 +759,7 @@ namespace Barotrauma
|
|||||||
IdOffset = Math.Max(IdOffset, me.ID);
|
IdOffset = Math.Max(IdOffset, me.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (XElement element in doc.Root.Elements())
|
foreach (XElement element in submarineElement.Elements())
|
||||||
{
|
{
|
||||||
string typeName = element.Name.ToString();
|
string typeName = element.Name.ToString();
|
||||||
|
|
||||||
@@ -836,7 +853,19 @@ namespace Barotrauma
|
|||||||
|
|
||||||
GameMain.LightManager.OnMapLoaded();
|
GameMain.LightManager.OnMapLoaded();
|
||||||
|
|
||||||
ID = ushort.MaxValue;
|
ID = (ushort)(ushort.MaxValue - Submarine.loaded.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Submarine Load(XElement element, bool unloadPrevious)
|
||||||
|
{
|
||||||
|
if (unloadPrevious) Unload();
|
||||||
|
|
||||||
|
//tryload -> false
|
||||||
|
|
||||||
|
Submarine sub = new Submarine(ToolBox.GetAttributeString(element, "name", ""));
|
||||||
|
sub.Load(unloadPrevious, element);
|
||||||
|
|
||||||
|
return sub;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Submarine Load(string fileName, bool unloadPrevious)
|
public static Submarine Load(string fileName, bool unloadPrevious)
|
||||||
@@ -851,7 +880,7 @@ namespace Barotrauma
|
|||||||
string path = string.IsNullOrWhiteSpace(folder) ? fileName : System.IO.Path.Combine(SavePath, fileName);
|
string path = string.IsNullOrWhiteSpace(folder) ? fileName : System.IO.Path.Combine(SavePath, fileName);
|
||||||
|
|
||||||
Submarine sub = new Submarine(path);
|
Submarine sub = new Submarine(path);
|
||||||
sub.Load(false);
|
sub.Load(unloadPrevious);
|
||||||
|
|
||||||
//Entity.dictionary.Add(int.MaxValue, sub);
|
//Entity.dictionary.Add(int.MaxValue, sub);
|
||||||
|
|
||||||
|
|||||||
@@ -125,30 +125,16 @@ namespace Barotrauma
|
|||||||
Body, this);
|
Body, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
//foreach (Hull hull in Hull.hullList)
|
foreach (Hull hull in Hull.hullList)
|
||||||
//{
|
{
|
||||||
// Rectangle rect = hull.Rect;
|
Rectangle rect = hull.Rect;
|
||||||
// foreach (Structure wall in Structure.WallList)
|
FixtureFactory.AttachRectangle(
|
||||||
// {
|
ConvertUnits.ToSimUnits(rect.Width),
|
||||||
// if (!Submarine.RectsOverlap(wall.Rect, hull.Rect)) continue;
|
ConvertUnits.ToSimUnits(rect.Height),
|
||||||
|
5.0f,
|
||||||
// Rectangle wallRect = wall.IsHorizontal ?
|
ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height / 2)),
|
||||||
// new Rectangle(hull.Rect.X, wall.Rect.Y, hull.Rect.Width, wall.Rect.Height) :
|
Body, this);
|
||||||
// new Rectangle(wall.Rect.X, hull.Rect.Y, wall.Rect.Width, hull.Rect.Height);
|
}
|
||||||
|
|
||||||
// rect = Rectangle.Union(
|
|
||||||
// new Rectangle(wallRect.X, wallRect.Y - wallRect.Height, wallRect.Width, wallRect.Height),
|
|
||||||
// new Rectangle(rect.X, rect.Y - rect.Height, rect.Width, rect.Height));
|
|
||||||
// rect.Y = rect.Y + rect.Height;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// FixtureFactory.AttachRectangle(
|
|
||||||
// ConvertUnits.ToSimUnits(rect.Width),
|
|
||||||
// ConvertUnits.ToSimUnits(rect.Height),
|
|
||||||
// 5.0f,
|
|
||||||
// ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height / 2)),
|
|
||||||
// body, this);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -183,50 +169,17 @@ namespace Barotrauma
|
|||||||
|
|
||||||
List<Vector2> points = new List<Vector2>();
|
List<Vector2> points = new List<Vector2>();
|
||||||
|
|
||||||
Vector2 leftMost = Vector2.Zero;
|
|
||||||
|
|
||||||
foreach (Structure wall in Structure.WallList)
|
foreach (Structure wall in Structure.WallList)
|
||||||
{
|
{
|
||||||
if (wall.Submarine != submarine) continue;
|
if (wall.Submarine != submarine) continue;
|
||||||
|
|
||||||
for (int x = -1; x <= 1; x += 2)
|
points.Add(new Vector2(wall.Rect.X, wall.Rect.Y));
|
||||||
{
|
points.Add(new Vector2(wall.Rect.X + wall.Rect.Width, wall.Rect.Y));
|
||||||
for (int y = -1; y <= 1; y += 2)
|
points.Add(new Vector2(wall.Rect.X, wall.Rect.Y - wall.Rect.Height));
|
||||||
{
|
points.Add(new Vector2(wall.Rect.X + wall.Rect.Width, wall.Rect.Y - wall.Rect.Height));
|
||||||
Vector2 corner = new Vector2(wall.Rect.X + wall.Rect.Width / 2.0f, wall.Rect.Y - wall.Rect.Height / 2.0f);
|
|
||||||
corner.X += x * wall.Rect.Width / 2.0f;
|
|
||||||
corner.Y += y * wall.Rect.Height / 2.0f;
|
|
||||||
|
|
||||||
if (points.Contains(corner)) continue;
|
|
||||||
|
|
||||||
points.Add(corner);
|
|
||||||
if (leftMost == Vector2.Zero || corner.X < leftMost.X) leftMost = corner;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Vector2> hullPoints = new List<Vector2>();
|
List<Vector2> hullPoints = MathUtils.GiftWrap(points);
|
||||||
|
|
||||||
Vector2 currPoint = leftMost;
|
|
||||||
Vector2 endPoint;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
hullPoints.Add(currPoint);
|
|
||||||
endPoint = points[0];
|
|
||||||
|
|
||||||
for (int i = 1; i < points.Count; i++)
|
|
||||||
{
|
|
||||||
if ((currPoint == endPoint)
|
|
||||||
|| (MathUtils.VectorOrientation(currPoint, endPoint, points[i]) == -1))
|
|
||||||
{
|
|
||||||
endPoint = points[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
currPoint = endPoint;
|
|
||||||
|
|
||||||
}
|
|
||||||
while (endPoint != hullPoints[0]);
|
|
||||||
|
|
||||||
return hullPoints;
|
return hullPoints;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,171 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma
|
||||||
|
{
|
||||||
|
|
||||||
|
class LinkedSubmarinePrefab : MapEntityPrefab
|
||||||
|
{
|
||||||
|
public readonly Submarine mainSub;
|
||||||
|
|
||||||
|
public LinkedSubmarinePrefab(Submarine submarine)
|
||||||
|
{
|
||||||
|
this.mainSub = submarine;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void CreateInstance(Rectangle rect)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.Assert(Submarine.MainSub != null);
|
||||||
|
|
||||||
|
LinkedSubmarine.Create(Submarine.MainSub, mainSub.FilePath, rect.Location.ToVector2());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LinkedSubmarine : MapEntity
|
||||||
|
{
|
||||||
|
private List<Vector2> wallVertices;
|
||||||
|
|
||||||
|
private string filePath;
|
||||||
|
|
||||||
|
private XElement saveElement;
|
||||||
|
|
||||||
|
public LinkedSubmarine(Submarine submarine)
|
||||||
|
: base(null, submarine)
|
||||||
|
{
|
||||||
|
InsertToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LinkedSubmarine Create(Submarine mainSub, string filePath, Vector2 position)
|
||||||
|
{
|
||||||
|
LinkedSubmarine sl = new LinkedSubmarine(mainSub);
|
||||||
|
sl.filePath = filePath;
|
||||||
|
|
||||||
|
XDocument doc = Submarine.OpenFile(filePath);
|
||||||
|
if (doc == null || doc.Root == null) return null;
|
||||||
|
|
||||||
|
sl.GenerateWallVertices(doc.Root);
|
||||||
|
|
||||||
|
//for (int i = 0; i < sl.wallVertices.Count; i++)
|
||||||
|
//{
|
||||||
|
// sl.wallVertices[i] = sl.wallVertices[i] += position;
|
||||||
|
//}
|
||||||
|
|
||||||
|
sl.Rect = new Rectangle(
|
||||||
|
(int)sl.wallVertices.Min(v => v.X + position.X),
|
||||||
|
(int)sl.wallVertices.Max(v => v.Y + position.Y),
|
||||||
|
(int)sl.wallVertices.Max(v => v.X + position.X),
|
||||||
|
(int)sl.wallVertices.Min(v => v.Y + position.Y));
|
||||||
|
|
||||||
|
sl.rect = new Rectangle(sl.rect.X, sl.rect.Y, sl.rect.Width - sl.rect.X, sl.rect.Y - sl.rect.Height);
|
||||||
|
|
||||||
|
return sl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool IsMouseOn(Vector2 position)
|
||||||
|
{
|
||||||
|
return Vector2.Distance(position, WorldPosition) < 50.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true)
|
||||||
|
{
|
||||||
|
if (!editing || wallVertices == null) return;
|
||||||
|
|
||||||
|
Color color = (isHighlighted) ? Color.Orange : Color.Green;
|
||||||
|
if (isSelected) color = Color.Red;
|
||||||
|
|
||||||
|
Vector2 pos = new Vector2(rect.X + rect.Width/2, rect.Y - rect.Height/2);
|
||||||
|
|
||||||
|
for (int i = 0; i < wallVertices.Count; i++)
|
||||||
|
{
|
||||||
|
Vector2 startPos = wallVertices[i] + pos;
|
||||||
|
startPos.Y = -startPos.Y;
|
||||||
|
|
||||||
|
Vector2 endPos = wallVertices[(i + 1) % wallVertices.Count] + pos;
|
||||||
|
endPos.Y = -endPos.Y;
|
||||||
|
|
||||||
|
GUI.DrawLine(spriteBatch,
|
||||||
|
startPos,
|
||||||
|
endPos,
|
||||||
|
color, 0.0f, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
pos.Y = -pos.Y;
|
||||||
|
GUI.DrawLine(spriteBatch, pos + Vector2.UnitY * 50.0f, pos - Vector2.UnitY * 50.0f, color, 0.0f, 5);
|
||||||
|
GUI.DrawLine(spriteBatch, pos + Vector2.UnitX * 50.0f, pos - Vector2.UnitX * 50.0f, color, 0.0f, 5);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenerateWallVertices(XElement rootElement)
|
||||||
|
{
|
||||||
|
List<Vector2> points = new List<Vector2>();
|
||||||
|
|
||||||
|
var wallPrefabs =
|
||||||
|
MapEntityPrefab.list.FindAll(mp => (mp is StructurePrefab) && ((StructurePrefab)mp).HasBody);
|
||||||
|
|
||||||
|
foreach (XElement element in rootElement.Elements())
|
||||||
|
{
|
||||||
|
if (element.Name != "Structure") continue;
|
||||||
|
|
||||||
|
string name = ToolBox.GetAttributeString(element, "name", "");
|
||||||
|
if (!wallPrefabs.Any(wp => wp.Name == name)) continue;
|
||||||
|
|
||||||
|
var rect = ToolBox.GetAttributeVector4(element, "rect", Vector4.Zero);
|
||||||
|
|
||||||
|
points.Add(new Vector2(rect.X, rect.Y));
|
||||||
|
points.Add(new Vector2(rect.X + rect.Z, rect.Y));
|
||||||
|
points.Add(new Vector2(rect.X, rect.Y - rect.W));
|
||||||
|
points.Add(new Vector2(rect.X + rect.Z, rect.Y - rect.W));
|
||||||
|
}
|
||||||
|
|
||||||
|
wallVertices = MathUtils.GiftWrap(points);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override XElement Save(XElement parentElement)
|
||||||
|
{
|
||||||
|
var doc = Submarine.OpenFile(filePath);
|
||||||
|
|
||||||
|
doc.Root.Name = "LinkedSubmarine";
|
||||||
|
|
||||||
|
doc.Root.Add(
|
||||||
|
new XAttribute("filepath", filePath),
|
||||||
|
new XAttribute("pos", ToolBox.Vector2ToString(Position - Submarine.HiddenSubPosition)));
|
||||||
|
|
||||||
|
parentElement.Add(doc.Root);
|
||||||
|
|
||||||
|
return doc.Root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Load(XElement element, Submarine submarine)
|
||||||
|
{
|
||||||
|
Vector2 pos = ToolBox.GetAttributeVector2(element, "pos", Vector2.Zero);
|
||||||
|
|
||||||
|
if (Screen.Selected == GameMain.EditMapScreen)
|
||||||
|
{
|
||||||
|
string filePath = ToolBox.GetAttributeString(element, "filepath", "");
|
||||||
|
|
||||||
|
Create(submarine, filePath, pos);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ls = new LinkedSubmarine(submarine);
|
||||||
|
ls.saveElement = element;
|
||||||
|
|
||||||
|
ls.rect.Location = pos.ToPoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnMapLoaded()
|
||||||
|
{
|
||||||
|
if (saveElement == null) return;
|
||||||
|
var sub = Submarine.Load(saveElement, false);
|
||||||
|
sub.SetPosition(WorldPosition - Submarine.WorldPosition);
|
||||||
|
sub.Submarine = Submarine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -718,7 +718,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override XElement Save(XDocument doc)
|
public override XElement Save(XElement parentElement)
|
||||||
{
|
{
|
||||||
if (MoveWithLevel) return null;
|
if (MoveWithLevel) return null;
|
||||||
XElement element = new XElement("WayPoint");
|
XElement element = new XElement("WayPoint");
|
||||||
@@ -739,7 +739,7 @@ namespace Barotrauma
|
|||||||
if (ConnectedGap != null) element.Add(new XAttribute("gap", ConnectedGap.ID));
|
if (ConnectedGap != null) element.Add(new XAttribute("gap", ConnectedGap.ID));
|
||||||
if (Ladders != null) element.Add(new XAttribute("ladders", Ladders.Item.ID));
|
if (Ladders != null) element.Add(new XAttribute("ladders", Ladders.Item.ID));
|
||||||
|
|
||||||
doc.Root.Add(element);
|
parentElement.Add(element);
|
||||||
|
|
||||||
if (linkedTo != null)
|
if (linkedTo != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -94,13 +94,23 @@ namespace Barotrauma
|
|||||||
button = new GUIButton(new Rectangle(310,0,70,20), "Save", GUI.Style, topPanel);
|
button = new GUIButton(new Rectangle(310,0,70,20), "Save", GUI.Style, topPanel);
|
||||||
button.OnClicked = SaveSub;
|
button.OnClicked = SaveSub;
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(400, 0, 100, 20), "Description: ", GUI.Style, topPanel);
|
new GUITextBlock(new Rectangle(390, 0, 100, 20), "Description: ", GUI.Style, topPanel);
|
||||||
|
|
||||||
descriptionBox = new GUITextBox(new Rectangle(500, 0, 200, 20), null, null, Alignment.TopLeft,
|
descriptionBox = new GUITextBox(new Rectangle(490, 0, 200, 20), null, null, Alignment.TopLeft,
|
||||||
Alignment.TopLeft, GUI.Style, topPanel);
|
Alignment.TopLeft, GUI.Style, topPanel);
|
||||||
descriptionBox.Wrap = true;
|
descriptionBox.Wrap = true;
|
||||||
descriptionBox.OnSelected += ExpandDescriptionBox;
|
descriptionBox.OnSelected += ExpandDescriptionBox;
|
||||||
descriptionBox.OnTextChanged = ChangeSubDescription;
|
descriptionBox.OnTextChanged = ChangeSubDescription;
|
||||||
|
|
||||||
|
|
||||||
|
//new GUITextBlock(new Rectangle(390, 0, 100, 20), "Link ", GUI.Style, topPanel);
|
||||||
|
|
||||||
|
var linkedSubBox = new GUIDropDown(new Rectangle(750,0,200,20), "Add submarine", GUI.Style, topPanel);
|
||||||
|
foreach (Submarine sub in Submarine.SavedSubmarines)
|
||||||
|
{
|
||||||
|
linkedSubBox.AddItem(sub.Name, sub);
|
||||||
|
}
|
||||||
|
linkedSubBox.OnSelected += SelectLinkedSub;
|
||||||
|
|
||||||
leftPanel = new GUIFrame(new Rectangle(0, 30, 150, GameMain.GraphicsHeight-30), GUI.Style);
|
leftPanel = new GUIFrame(new Rectangle(0, 30, 150, GameMain.GraphicsHeight-30), GUI.Style);
|
||||||
leftPanel.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
|
leftPanel.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
|
||||||
@@ -524,6 +534,18 @@ namespace Barotrauma
|
|||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool SelectLinkedSub(GUIComponent selected)
|
||||||
|
{
|
||||||
|
var submarine = selected.UserData as Submarine;
|
||||||
|
if (submarine == null) return false;
|
||||||
|
|
||||||
|
var prefab = new LinkedSubmarinePrefab(submarine);
|
||||||
|
|
||||||
|
MapEntityPrefab.SelectPrefab(prefab);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private bool SelectWire(GUIComponent component, object userData)
|
private bool SelectWire(GUIComponent component, object userData)
|
||||||
{
|
{
|
||||||
if (dummyCharacter == null) return false;
|
if (dummyCharacter == null) return false;
|
||||||
|
|||||||
@@ -288,6 +288,41 @@ namespace Barotrauma
|
|||||||
return triangles;
|
return triangles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<Vector2> GiftWrap(List<Vector2> points)
|
||||||
|
{
|
||||||
|
Vector2 leftMost = points[0];
|
||||||
|
foreach (Vector2 point in points)
|
||||||
|
{
|
||||||
|
if (point.X < leftMost.X) leftMost = point;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Vector2> wrappedPoints = new List<Vector2>();
|
||||||
|
|
||||||
|
Vector2 currPoint = leftMost;
|
||||||
|
Vector2 endPoint;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
wrappedPoints.Add(currPoint);
|
||||||
|
endPoint = points[0];
|
||||||
|
|
||||||
|
for (int i = 1; i < points.Count; i++)
|
||||||
|
{
|
||||||
|
if (points[i] == currPoint) continue;
|
||||||
|
if (currPoint == endPoint ||
|
||||||
|
MathUtils.VectorOrientation(currPoint, endPoint, points[i]) == -1)
|
||||||
|
{
|
||||||
|
endPoint = points[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currPoint = endPoint;
|
||||||
|
|
||||||
|
}
|
||||||
|
while (endPoint != leftMost);
|
||||||
|
|
||||||
|
return wrappedPoints;
|
||||||
|
}
|
||||||
|
|
||||||
public static List<Vector2[]> GenerateJaggedLine(Vector2 start, Vector2 end, int generations, float offsetAmount)
|
public static List<Vector2[]> GenerateJaggedLine(Vector2 start, Vector2 end, int generations, float offsetAmount)
|
||||||
{
|
{
|
||||||
List<Vector2[]> segments = new List<Vector2[]>();
|
List<Vector2[]> segments = new List<Vector2[]>();
|
||||||
|
|||||||
Reference in New Issue
Block a user