Merge branch 'master' of https://bitbucket.org/Regalis11/subsurface-private
+ character input keys in array instead of separate variables
This commit is contained in:
Binary file not shown.
+1
-2
@@ -17,7 +17,6 @@ namespace Launcher
|
|||||||
{
|
{
|
||||||
public partial class LauncherMain : Form
|
public partial class LauncherMain : Form
|
||||||
{
|
{
|
||||||
public static string ContentPackageFolder = "Data/ContentPackages/";
|
|
||||||
private const string configPath = "config.xml";
|
private const string configPath = "config.xml";
|
||||||
private Subsurface.GameSettings settings;
|
private Subsurface.GameSettings settings;
|
||||||
|
|
||||||
@@ -42,7 +41,7 @@ namespace Launcher
|
|||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
ContentPackage.LoadAll(LauncherMain.ContentPackageFolder);
|
ContentPackage.LoadAll(ContentPackage.Folder);
|
||||||
contentPackageBox.DataSource = ContentPackage.list;
|
contentPackageBox.DataSource = ContentPackage.list;
|
||||||
|
|
||||||
supportedModes = new List<GraphicsMode>();
|
supportedModes = new List<GraphicsMode>();
|
||||||
|
|||||||
Generated
+3
@@ -102,6 +102,7 @@
|
|||||||
this.itemList.Name = "itemList";
|
this.itemList.Name = "itemList";
|
||||||
this.itemList.Size = new System.Drawing.Size(255, 134);
|
this.itemList.Size = new System.Drawing.Size(255, 134);
|
||||||
this.itemList.TabIndex = 8;
|
this.itemList.TabIndex = 8;
|
||||||
|
this.itemList.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.fileList_KeyPress);
|
||||||
//
|
//
|
||||||
// itemButton
|
// itemButton
|
||||||
//
|
//
|
||||||
@@ -161,6 +162,7 @@
|
|||||||
this.structureList.Name = "structureList";
|
this.structureList.Name = "structureList";
|
||||||
this.structureList.Size = new System.Drawing.Size(255, 121);
|
this.structureList.Size = new System.Drawing.Size(255, 121);
|
||||||
this.structureList.TabIndex = 8;
|
this.structureList.TabIndex = 8;
|
||||||
|
this.structureList.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.fileList_KeyPress);
|
||||||
//
|
//
|
||||||
// structureButton
|
// structureButton
|
||||||
//
|
//
|
||||||
@@ -189,6 +191,7 @@
|
|||||||
this.jobList.Name = "jobList";
|
this.jobList.Name = "jobList";
|
||||||
this.jobList.Size = new System.Drawing.Size(255, 134);
|
this.jobList.Size = new System.Drawing.Size(255, 134);
|
||||||
this.jobList.TabIndex = 11;
|
this.jobList.TabIndex = 11;
|
||||||
|
this.jobList.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.fileList_KeyPress);
|
||||||
//
|
//
|
||||||
// label4
|
// label4
|
||||||
//
|
//
|
||||||
|
|||||||
+17
-20
@@ -96,28 +96,25 @@ namespace Launcher
|
|||||||
fileButton.Enabled = (selectedPackage != null);
|
fileButton.Enabled = (selectedPackage != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedPackage == null)
|
|
||||||
|
foreach (ListBox fileBox in fileBoxes)
|
||||||
{
|
{
|
||||||
foreach (ListBox fileBox in fileBoxes)
|
fileBox.Items.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
foreach (ListBox fileBox in fileBoxes)
|
||||||
|
{
|
||||||
|
ContentType type = (fileBox.Tag is ContentType) ? (ContentType)fileBox.Tag : ContentType.None;
|
||||||
|
|
||||||
|
foreach (ContentFile file in selectedPackage.files)
|
||||||
{
|
{
|
||||||
fileBox.Items.Clear();
|
if (file.type != type) continue;
|
||||||
}
|
|
||||||
}
|
fileBox.Items.Add(file);
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
foreach (ListBox fileBox in fileBoxes)
|
|
||||||
{
|
|
||||||
ContentType type = (fileBox.Tag is ContentType) ? (ContentType)fileBox.Tag : ContentType.None;
|
|
||||||
|
|
||||||
foreach (ContentFile file in selectedPackage.files)
|
|
||||||
{
|
|
||||||
if (file.type != type) continue;
|
|
||||||
|
|
||||||
fileBox.Items.Add(file);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void newPackage_Click(object sender, EventArgs e)
|
private void newPackage_Click(object sender, EventArgs e)
|
||||||
@@ -145,7 +142,7 @@ namespace Launcher
|
|||||||
|
|
||||||
OpenFileDialog ofd = new OpenFileDialog();
|
OpenFileDialog ofd = new OpenFileDialog();
|
||||||
ofd.Filter = "XML files (*.xml)|*.xml;*.XML";
|
ofd.Filter = "XML files (*.xml)|*.xml;*.XML";
|
||||||
//ofd.RestoreDirectory?
|
ofd.RestoreDirectory = true;
|
||||||
|
|
||||||
if (ofd.ShowDialog() == DialogResult.OK)
|
if (ofd.ShowDialog() == DialogResult.OK)
|
||||||
{
|
{
|
||||||
@@ -256,7 +253,7 @@ namespace Launcher
|
|||||||
|
|
||||||
private void okButton_Click(object sender, EventArgs e)
|
private void okButton_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (selectedPackage!=null) selectedPackage.Save(LauncherMain.ContentPackageFolder);
|
if (selectedPackage!=null) selectedPackage.Save(ContentPackage.Folder);
|
||||||
|
|
||||||
this.Close();
|
this.Close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,27 @@
|
|||||||
|
|
||||||
<ConnectionPanel canbeselected = "true" msg="Rewire [Screwdriver]">
|
<ConnectionPanel canbeselected = "true" msg="Rewire [Screwdriver]">
|
||||||
<requireditem name="Screwdriver" type="Equipped"/>
|
<requireditem name="Screwdriver" type="Equipped"/>
|
||||||
<input name="power_in"/>
|
<input name="power"/>
|
||||||
</ConnectionPanel>
|
</ConnectionPanel>
|
||||||
</Item>
|
</Item>
|
||||||
|
|
||||||
|
<Item
|
||||||
|
name="Supercapacitor"
|
||||||
|
linkable="true"
|
||||||
|
pickdistance="150">
|
||||||
|
|
||||||
|
<Sprite texture ="supercapacitor.png" depth="0.8"/>
|
||||||
|
|
||||||
|
<PowerContainer capacity="2000.0" maxrechargespeed="2000.0" maxoutput="2000.0" canbeselected = "true">
|
||||||
|
<GuiFrame rect="0,0,0.3,0.3" alignment="Center" color="0.0,0.0,0.0,0.8"/>
|
||||||
|
</PowerContainer>
|
||||||
|
|
||||||
|
<ConnectionPanel canbeselected = "true" msg="Rewire [Screwdriver]">
|
||||||
|
<requireditem name="Screwdriver" type="Equipped"/>
|
||||||
|
<input name="power"/>
|
||||||
|
</ConnectionPanel>
|
||||||
|
</Item>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</Items>
|
</Items>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 231 B |
@@ -185,7 +185,7 @@
|
|||||||
linkable="true"
|
linkable="true"
|
||||||
price="10">
|
price="10">
|
||||||
|
|
||||||
<Sprite texture ="light.png" depth="0.8"/>
|
<Sprite texture ="regex.png" depth="0.8"/>
|
||||||
|
|
||||||
<RegExFindComponent canbeselected = "true"/>
|
<RegExFindComponent canbeselected = "true"/>
|
||||||
|
|
||||||
@@ -203,5 +203,30 @@
|
|||||||
</ConnectionPanel>
|
</ConnectionPanel>
|
||||||
</Item>
|
</Item>
|
||||||
|
|
||||||
|
<Item
|
||||||
|
name="Wifi Component"
|
||||||
|
Tags="smallitem"
|
||||||
|
pickdistance="150"
|
||||||
|
linkable="true"
|
||||||
|
price="20">
|
||||||
|
|
||||||
|
<Sprite texture ="wifi.png" depth="0.8"/>
|
||||||
|
|
||||||
|
<WifiComponent canbeselected = "true"/>
|
||||||
|
|
||||||
|
<Body width="16" height="16"/>
|
||||||
|
|
||||||
|
<Holdable aimpos="35,-10" handle1="0,0" attachable="true" aimable="true"
|
||||||
|
slots="Any,RightHand,LeftHand" msg="Detach [Wrench]">
|
||||||
|
<requireditem name="Wrench" type="Equipped"/>
|
||||||
|
</Holdable>
|
||||||
|
|
||||||
|
<ConnectionPanel canbeselected = "true" msg="Rewire [Screwdriver]">
|
||||||
|
<requireditem name="Screwdriver,Wire" type="Equipped"/>
|
||||||
|
<input name="signal_in"/>
|
||||||
|
<output name="signal_out"/>
|
||||||
|
</ConnectionPanel>
|
||||||
|
</Item>
|
||||||
|
|
||||||
</Items>
|
</Items>
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 528 B |
Binary file not shown.
|
After Width: | Height: | Size: 225 B |
@@ -34,6 +34,8 @@
|
|||||||
<ConnectionPanel canbeselected = "true" msg="Rewire [Screwdriver]">
|
<ConnectionPanel canbeselected = "true" msg="Rewire [Screwdriver]">
|
||||||
<requireditem name="Screwdriver" type="Equipped"/>
|
<requireditem name="Screwdriver" type="Equipped"/>
|
||||||
<output name="power_out"/>
|
<output name="power_out"/>
|
||||||
|
<output name="temperature_out"/>
|
||||||
|
<input name="shutdown"/>
|
||||||
</ConnectionPanel>
|
</ConnectionPanel>
|
||||||
|
|
||||||
<ItemContainer capacity="5">
|
<ItemContainer capacity="5">
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
@@ -5,9 +5,9 @@
|
|||||||
Tags="smallitem"
|
Tags="smallitem"
|
||||||
pickdistance="150">
|
pickdistance="150">
|
||||||
|
|
||||||
<Sprite texture ="idcard.png" depth="0.5f"/>
|
<Sprite texture ="idcard.png" depth="0.8f"/>
|
||||||
|
|
||||||
<Body width="16" height="16" density="10"/>
|
<Body width="16" height="16"/>
|
||||||
|
|
||||||
<Pickable/>
|
<Pickable/>
|
||||||
</Item>
|
</Item>
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
|
||||||
|
<Item
|
||||||
|
name="Label"
|
||||||
|
resizehorizontal="true"
|
||||||
|
resizevertical="true">
|
||||||
|
|
||||||
|
<Sprite texture ="blank.png" depth="0.85"/>
|
||||||
|
|
||||||
|
<ItemLabel/>
|
||||||
|
</Item>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
</Skills>
|
</Skills>
|
||||||
</Captain>
|
</Captain>
|
||||||
|
|
||||||
<Engineer>
|
<Engineer minnumber="1">
|
||||||
<Skills>
|
<Skills>
|
||||||
<Skill name="Weapons" level="10,30"/>
|
<Skill name="Weapons" level="10,30"/>
|
||||||
<Skill name="Construction" level="30,40"/>
|
<Skill name="Construction" level="30,40"/>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
<Item name="Screwdriver"/>
|
<Item name="Screwdriver"/>
|
||||||
</Engineer>
|
</Engineer>
|
||||||
|
|
||||||
<Mechanic>
|
<Mechanic minnumber="1">
|
||||||
<Skills>
|
<Skills>
|
||||||
<Skill name="Weapons" level="10,30"/>
|
<Skill name="Weapons" level="10,30"/>
|
||||||
<Skill name="Construction" level="50,60"/>
|
<Skill name="Construction" level="50,60"/>
|
||||||
|
|||||||
@@ -54,6 +54,13 @@
|
|||||||
<Sprite texture="Content\UI\uiBackground.png" size="0.0, 0.0" sourcerect ="0.0, 90.0, 0.0, 100.0"/>
|
<Sprite texture="Content\UI\uiBackground.png" size="0.0, 0.0" sourcerect ="0.0, 90.0, 0.0, 100.0"/>
|
||||||
</GUITextBox>
|
</GUITextBox>
|
||||||
|
|
||||||
|
<GUITickBox
|
||||||
|
color="0.5, 0.5, 0.5, 1.0"
|
||||||
|
|
||||||
|
outlinecolor="0.5, 0.57, 0.6, 1.0">
|
||||||
|
<Sprite texture="Content\UI\uiBackground.png" size="0.0, 0.0" sourcerect ="0.0, 90.0, 0.0, 100.0"/>
|
||||||
|
</GUITickBox>
|
||||||
|
|
||||||
<GUIMessageBox
|
<GUIMessageBox
|
||||||
padding="40.0, 40.0, 40.0, 40.0"
|
padding="40.0, 40.0, 40.0, 40.0"
|
||||||
color="1.0, 1.0, 1.0, 1.0"
|
color="1.0, 1.0, 1.0, 1.0"
|
||||||
|
|||||||
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("0.1.1.0")]
|
[assembly: AssemblyVersion("0.1.3.2")]
|
||||||
[assembly: AssemblyFileVersion("0.1.1.0")]
|
[assembly: AssemblyFileVersion("0.1.3.2")]
|
||||||
|
|||||||
+30
-12
@@ -18,12 +18,13 @@ namespace Subsurface
|
|||||||
private Vector2 position;
|
private Vector2 position;
|
||||||
private float rotation;
|
private float rotation;
|
||||||
|
|
||||||
|
private Vector2 prevPosition;
|
||||||
|
private float prevZoom;
|
||||||
|
|
||||||
public float Shake;
|
public float Shake;
|
||||||
private Vector2 shakePosition;
|
private Vector2 shakePosition;
|
||||||
private Vector2 shakeTargetPosition;
|
private Vector2 shakeTargetPosition;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//the area of the world inside the camera view
|
//the area of the world inside the camera view
|
||||||
private Rectangle worldView;
|
private Rectangle worldView;
|
||||||
|
|
||||||
@@ -130,9 +131,9 @@ namespace Subsurface
|
|||||||
|
|
||||||
private void UpdateTransform()
|
private void UpdateTransform()
|
||||||
{
|
{
|
||||||
Vector2 interpolatedPosition = position;//Physics.Interpolate(prevPosition,position);
|
Vector2 interpolatedPosition = Physics.Interpolate(prevPosition, position);
|
||||||
|
|
||||||
float interpolatedZoom = zoom;// Physics.Interpolate(prevZoom, zoom);
|
float interpolatedZoom = Physics.Interpolate(prevZoom, zoom);
|
||||||
|
|
||||||
worldView.X = (int)(interpolatedPosition.X - worldView.Width / 2.0);
|
worldView.X = (int)(interpolatedPosition.X - worldView.Width / 2.0);
|
||||||
worldView.Y = (int)(interpolatedPosition.Y + worldView.Height / 2.0);
|
worldView.Y = (int)(interpolatedPosition.Y + worldView.Height / 2.0);
|
||||||
@@ -154,13 +155,19 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
float moveSpeed = 20.0f/zoom;
|
float moveSpeed = 20.0f/zoom;
|
||||||
|
|
||||||
|
prevPosition = position;
|
||||||
|
prevZoom = zoom;
|
||||||
|
|
||||||
Vector2 moveCam = Vector2.Zero;
|
Vector2 moveCam = Vector2.Zero;
|
||||||
if (targetPos == Vector2.Zero)
|
if (targetPos == Vector2.Zero)
|
||||||
{
|
{
|
||||||
if (Keyboard.GetState().IsKeyDown(Keys.A)) moveCam.X -= moveSpeed;
|
|
||||||
if (Keyboard.GetState().IsKeyDown(Keys.D)) moveCam.X += moveSpeed;
|
if (PlayerInput.KeyDown(Keys.A)) moveCam.X -= moveSpeed;
|
||||||
if (Keyboard.GetState().IsKeyDown(Keys.S)) moveCam.Y -= moveSpeed;
|
if (PlayerInput.KeyDown(Keys.D)) moveCam.X += moveSpeed;
|
||||||
if (Keyboard.GetState().IsKeyDown(Keys.W)) moveCam.Y += moveSpeed;
|
if (PlayerInput.KeyDown(Keys.S)) moveCam.Y -= moveSpeed;
|
||||||
|
if (PlayerInput.KeyDown(Keys.W)) moveCam.Y += moveSpeed;
|
||||||
|
|
||||||
|
moveCam = moveCam * deltaTime * 60.0f;
|
||||||
|
|
||||||
Zoom = MathHelper.Clamp(Zoom + PlayerInput.ScrollWheelSpeed / 1000.0f, 0.1f, 2.0f);
|
Zoom = MathHelper.Clamp(Zoom + PlayerInput.ScrollWheelSpeed / 1000.0f, 0.1f, 2.0f);
|
||||||
}
|
}
|
||||||
@@ -179,15 +186,26 @@ namespace Subsurface
|
|||||||
|
|
||||||
float newZoom = Math.Min(DefaultZoom - Math.Min(offset.Length() / resolution.Y, 1.0f),1.0f);
|
float newZoom = Math.Min(DefaultZoom - Math.Min(offset.Length() / resolution.Y, 1.0f),1.0f);
|
||||||
Zoom += (newZoom - zoom) / ZoomSmoothness;
|
Zoom += (newZoom - zoom) / ZoomSmoothness;
|
||||||
|
|
||||||
moveCam = (targetPos + offset - position) / MoveSmoothness;
|
Vector2 diff = (targetPos + offset) - position;
|
||||||
|
|
||||||
|
if (diff == Vector2.Zero)
|
||||||
|
{
|
||||||
|
moveCam = Vector2.Zero;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float dist = diff == Vector2.Zero ? 0.0f : diff.Length();
|
||||||
|
|
||||||
|
moveCam = Vector2.Normalize(diff) * Math.Min(dist, (dist * deltaTime * 60.0f) / MoveSmoothness);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shakeTargetPosition = Rand.Vector(Shake);
|
shakeTargetPosition = Rand.Vector(Shake);
|
||||||
shakePosition = Vector2.Lerp(shakePosition, shakeTargetPosition, 0.5f);
|
shakePosition = Vector2.Lerp(shakePosition, shakeTargetPosition, 0.5f);
|
||||||
Shake = MathHelper.Lerp(Shake, 0.0f, 0.03f);
|
Shake = MathHelper.Lerp(Shake, 0.0f, 0.03f);
|
||||||
|
|
||||||
Translate((moveCam+shakePosition)*deltaTime*60.0f);
|
Translate(moveCam+shakePosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2 Position
|
public Vector2 Position
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ namespace Subsurface
|
|||||||
steeringManager = new SteeringManager(this);
|
steeringManager = new SteeringManager(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SelectTarget(IDamageable target) { }
|
public virtual void SelectTarget(AITarget target) { }
|
||||||
|
|
||||||
public virtual void Update(float deltaTime) { }
|
public virtual void Update(float deltaTime) { }
|
||||||
|
|
||||||
|
|||||||
@@ -82,11 +82,10 @@ namespace Subsurface
|
|||||||
state = AiState.None;
|
state = AiState.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SelectTarget(IDamageable target)
|
public override void SelectTarget(AITarget target)
|
||||||
{
|
{
|
||||||
targetEntity = target;
|
selectedAiTarget = target;
|
||||||
selectedAiTarget = target.AiTarget;
|
selectedTargetMemory = FindTargetMemory(target);
|
||||||
selectedTargetMemory = FindTargetMemory(target.AiTarget);
|
|
||||||
|
|
||||||
targetValue = 100.0f;
|
targetValue = 100.0f;
|
||||||
}
|
}
|
||||||
@@ -470,14 +469,21 @@ namespace Subsurface
|
|||||||
public override void FillNetworkData(NetOutgoingMessage message)
|
public override void FillNetworkData(NetOutgoingMessage message)
|
||||||
{
|
{
|
||||||
message.Write((byte)state);
|
message.Write((byte)state);
|
||||||
|
|
||||||
|
bool wallAttack = (wallAttackPos!=Vector2.Zero && state == AiState.Attack);
|
||||||
|
|
||||||
message.Write(wallAttackPos.X);
|
message.Write(wallAttack);
|
||||||
message.Write(wallAttackPos.Y);
|
|
||||||
|
|
||||||
message.Write(steeringManager.WanderAngle);
|
if (wallAttack)
|
||||||
message.Write(updateTargetsTimer);
|
{
|
||||||
message.Write(raycastTimer);
|
message.Write(wallAttackPos.X);
|
||||||
message.Write(coolDownTimer);
|
message.Write(wallAttackPos.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
message.Write(MathUtils.AngleToByte(steeringManager.WanderAngle));
|
||||||
|
message.WriteRangedSingle(MathHelper.Clamp(updateTargetsTimer,0.0f, UpdateTargetsInterval), 0.0f, UpdateTargetsInterval, 8);
|
||||||
|
message.WriteRangedSingle(MathHelper.Clamp(raycastTimer, 0.0f, RaycastInterval), 0.0f, RaycastInterval, 8);
|
||||||
|
message.WriteRangedSingle(MathHelper.Clamp(coolDownTimer, 0.0f, attackCoolDown * 2.0f), 0.0f, attackCoolDown * 2.0f, 8);
|
||||||
|
|
||||||
message.Write(targetEntity==null ? -1 : (targetEntity as Entity).ID);
|
message.Write(targetEntity==null ? -1 : (targetEntity as Entity).ID);
|
||||||
}
|
}
|
||||||
@@ -485,7 +491,7 @@ namespace Subsurface
|
|||||||
public override void ReadNetworkData(NetIncomingMessage message)
|
public override void ReadNetworkData(NetIncomingMessage message)
|
||||||
{
|
{
|
||||||
AiState newState = AiState.None;
|
AiState newState = AiState.None;
|
||||||
Vector2 newWallAttackPos;
|
Vector2 newWallAttackPos = Vector2.Zero;
|
||||||
float wanderAngle;
|
float wanderAngle;
|
||||||
float updateTargetsTimer, raycastTimer, coolDownTimer;
|
float updateTargetsTimer, raycastTimer, coolDownTimer;
|
||||||
|
|
||||||
@@ -495,12 +501,18 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
|
|
||||||
newState = (AiState)(message.ReadByte());
|
newState = (AiState)(message.ReadByte());
|
||||||
newWallAttackPos = new Vector2(message.ReadFloat(), message.ReadFloat());
|
|
||||||
|
|
||||||
wanderAngle = MathUtils.WrapAngleTwoPi(message.ReadFloat());
|
bool wallAttack = message.ReadBoolean();
|
||||||
updateTargetsTimer = MathHelper.Clamp(message.ReadFloat(), 0.0f, UpdateTargetsInterval);
|
|
||||||
raycastTimer = MathHelper.Clamp(message.ReadFloat(), 0.0f, RaycastInterval);
|
if (wallAttack)
|
||||||
coolDownTimer = MathHelper.Clamp(message.ReadFloat(), 0.0f, attackCoolDown);
|
{
|
||||||
|
newWallAttackPos = new Vector2(message.ReadFloat(), message.ReadFloat());
|
||||||
|
}
|
||||||
|
|
||||||
|
wanderAngle = MathUtils.ByteToAngle(message.ReadByte());
|
||||||
|
updateTargetsTimer = message.ReadRangedSingle(0.0f, UpdateTargetsInterval, 8);
|
||||||
|
raycastTimer = message.ReadRangedSingle(0.0f, RaycastInterval, 8);
|
||||||
|
coolDownTimer = message.ReadRangedSingle(0.0f, attackCoolDown*2.0f, 8);
|
||||||
|
|
||||||
targetID = message.ReadInt32();
|
targetID = message.ReadInt32();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,11 @@ namespace Subsurface
|
|||||||
public float StunTimer
|
public float StunTimer
|
||||||
{
|
{
|
||||||
get { return stunTimer; }
|
get { return stunTimer; }
|
||||||
set { stunTimer = value; }
|
set
|
||||||
|
{
|
||||||
|
if (float.IsNaN(value) || float.IsInfinity(value)) return;
|
||||||
|
stunTimer = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AnimController(Character character, XElement element)
|
public AnimController(Character character, XElement element)
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
private CharacterInventory inventory;
|
private CharacterInventory inventory;
|
||||||
|
|
||||||
public double LastNetworkUpdate;
|
public float LastNetworkUpdate;
|
||||||
|
|
||||||
public int LargeUpdateTimer;
|
public int LargeUpdateTimer;
|
||||||
|
|
||||||
@@ -46,9 +46,11 @@ namespace Subsurface
|
|||||||
get { return Properties; }
|
get { return Properties; }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Key selectKeyHit;
|
protected Key[] keys;
|
||||||
protected Key actionKeyHit, actionKeyDown;
|
|
||||||
protected Key secondaryKeyHit, secondaryKeyDown;
|
//protected Key selectKeyHit;
|
||||||
|
//protected Key actionKeyHit, actionKeyDown;
|
||||||
|
//protected Key secondaryKeyHit, secondaryKeyDown;
|
||||||
|
|
||||||
private Item selectedConstruction;
|
private Item selectedConstruction;
|
||||||
private Item[] selectedItems;
|
private Item[] selectedItems;
|
||||||
@@ -244,31 +246,6 @@ namespace Subsurface
|
|||||||
get { return closestItem; }
|
get { return closestItem; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Key SelectKeyHit
|
|
||||||
{
|
|
||||||
get { return selectKeyHit; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Key ActionKeyHit
|
|
||||||
{
|
|
||||||
get { return actionKeyHit; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Key ActionKeyDown
|
|
||||||
{
|
|
||||||
get { return actionKeyDown; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Key SecondaryKeyHit
|
|
||||||
{
|
|
||||||
get { return secondaryKeyHit; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Key SecondaryKeyDown
|
|
||||||
{
|
|
||||||
get { return secondaryKeyDown; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public AIController AIController
|
public AIController AIController
|
||||||
{
|
{
|
||||||
get { return aiController; }
|
get { return aiController; }
|
||||||
@@ -311,12 +288,13 @@ namespace Subsurface
|
|||||||
|
|
||||||
public Character(string file, Vector2 position, CharacterInfo characterInfo = null, bool isNetworkPlayer = false)
|
public Character(string file, Vector2 position, CharacterInfo characterInfo = null, bool isNetworkPlayer = false)
|
||||||
{
|
{
|
||||||
selectKeyHit = new Key(false);
|
keys = new Key[5];
|
||||||
actionKeyDown = new Key(true);
|
keys[(int)InputType.Select] = new Key(false);
|
||||||
actionKeyHit = new Key(false);
|
keys[(int)InputType.ActionHeld] = new Key(true);
|
||||||
secondaryKeyHit = new Key(false);
|
keys[(int)InputType.ActionHit] = new Key(false);
|
||||||
secondaryKeyDown = new Key(true);
|
keys[(int)InputType.SecondaryHit] = new Key(false);
|
||||||
|
keys[(int)InputType.SecondaryHeld] = new Key(true);
|
||||||
|
|
||||||
selectedItems = new Item[2];
|
selectedItems = new Item[2];
|
||||||
|
|
||||||
IsNetworkPlayer = isNetworkPlayer;
|
IsNetworkPlayer = isNetworkPlayer;
|
||||||
@@ -426,6 +404,16 @@ namespace Subsurface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool GetInputState(InputType inputType)
|
||||||
|
{
|
||||||
|
return keys[(int)inputType].State;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return (info != null && !string.IsNullOrWhiteSpace(info.Name)) ? info.Name : SpeciesName;
|
||||||
|
}
|
||||||
|
|
||||||
public void GiveJobItems(WayPoint spawnPoint)
|
public void GiveJobItems(WayPoint spawnPoint)
|
||||||
{
|
{
|
||||||
if (info == null || info.Job == null) return;
|
if (info == null || info.Job == null) return;
|
||||||
@@ -482,7 +470,7 @@ namespace Subsurface
|
|||||||
if (closestItem != null)
|
if (closestItem != null)
|
||||||
{
|
{
|
||||||
closestItem.IsHighlighted = true;
|
closestItem.IsHighlighted = true;
|
||||||
if (selectKeyHit.State && closestItem.Pick(this, forcePick))
|
if (GetInputState(InputType.Select) && closestItem.Pick(this, forcePick))
|
||||||
{
|
{
|
||||||
new NetworkEvent(NetworkEventType.PickItem, ID, true, closestItem.ID);
|
new NetworkEvent(NetworkEventType.PickItem, ID, true, closestItem.ID);
|
||||||
}
|
}
|
||||||
@@ -492,7 +480,7 @@ namespace Subsurface
|
|||||||
if (closestCharacter != selectedCharacter) selectedCharacter = null;
|
if (closestCharacter != selectedCharacter) selectedCharacter = null;
|
||||||
if (closestCharacter!=null)
|
if (closestCharacter!=null)
|
||||||
{
|
{
|
||||||
if (selectKeyHit.State) selectedCharacter = (selectedCharacter==null) ? closestCharacter : null;
|
if (GetInputState(InputType.Select)) selectedCharacter = (selectedCharacter == null) ? closestCharacter : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -501,23 +489,22 @@ namespace Subsurface
|
|||||||
if (selectedItems[i] == null) continue;
|
if (selectedItems[i] == null) continue;
|
||||||
if (i == 1 && selectedItems[0] == selectedItems[1]) continue;
|
if (i == 1 && selectedItems[0] == selectedItems[1]) continue;
|
||||||
|
|
||||||
if (actionKeyDown.State) selectedItems[i].Use(deltaTime, this);
|
if (GetInputState(InputType.ActionHeld)) selectedItems[i].Use(deltaTime, this);
|
||||||
if (secondaryKeyDown.State && selectedItems[i] != null) selectedItems[i].SecondaryUse(deltaTime, this);
|
if (GetInputState(InputType.SecondaryHeld) && selectedItems[i] != null) selectedItems[i].SecondaryUse(deltaTime, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedConstruction != null)
|
if (selectedConstruction != null)
|
||||||
{
|
{
|
||||||
if (actionKeyDown.State) selectedConstruction.Use(deltaTime, this);
|
if (GetInputState(InputType.ActionHeld)) selectedConstruction.Use(deltaTime, this);
|
||||||
if (secondaryKeyDown.State) selectedConstruction.SecondaryUse(deltaTime, this);
|
if (GetInputState(InputType.SecondaryHeld)) selectedConstruction.SecondaryUse(deltaTime, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsNetworkPlayer)
|
if (IsNetworkPlayer)
|
||||||
{
|
{
|
||||||
selectKeyHit.Reset();
|
foreach (Key key in keys)
|
||||||
actionKeyHit.Reset();
|
{
|
||||||
actionKeyDown.Reset();
|
key.Reset();
|
||||||
secondaryKeyHit.Reset();
|
}
|
||||||
secondaryKeyDown.Reset();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -589,19 +576,19 @@ namespace Subsurface
|
|||||||
if (Keyboard.GetState().IsKeyDown(Keys.LeftShift) && Math.Sign(targetMovement.X) == Math.Sign(AnimController.Dir))
|
if (Keyboard.GetState().IsKeyDown(Keys.LeftShift) && Math.Sign(targetMovement.X) == Math.Sign(AnimController.Dir))
|
||||||
targetMovement *= 3.0f;
|
targetMovement *= 3.0f;
|
||||||
|
|
||||||
selectKeyHit.SetState(PlayerInput.KeyHit(Keys.E));
|
|
||||||
actionKeyHit.SetState(PlayerInput.LeftButtonClicked());
|
keys[(int)InputType.Select].SetState(PlayerInput.KeyHit(Keys.E));
|
||||||
actionKeyDown.SetState(PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed);
|
keys[(int)InputType.ActionHit].SetState(PlayerInput.LeftButtonClicked());
|
||||||
secondaryKeyHit.SetState(PlayerInput.RightButtonClicked());
|
keys[(int)InputType.ActionHeld].SetState(PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed);
|
||||||
secondaryKeyDown.SetState(PlayerInput.GetMouseState.RightButton == ButtonState.Pressed);
|
keys[(int)InputType.SecondaryHit].SetState(PlayerInput.RightButtonClicked());
|
||||||
|
keys[(int)InputType.SecondaryHeld].SetState(PlayerInput.GetMouseState.RightButton == ButtonState.Pressed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
selectKeyHit.SetState(false);
|
foreach (Key key in keys)
|
||||||
actionKeyHit.SetState(false);
|
{
|
||||||
actionKeyDown.SetState(false);
|
key.SetState(false);
|
||||||
secondaryKeyHit.SetState(false);
|
}
|
||||||
secondaryKeyDown.SetState(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimController.TargetMovement = targetMovement;
|
AnimController.TargetMovement = targetMovement;
|
||||||
@@ -629,7 +616,6 @@ namespace Subsurface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (AnimController.onGround &&
|
if (AnimController.onGround &&
|
||||||
!AnimController.InWater &&
|
!AnimController.InWater &&
|
||||||
AnimController.Anim != AnimController.Animation.UsingConstruction)
|
AnimController.Anim != AnimController.Animation.UsingConstruction)
|
||||||
@@ -1020,26 +1006,28 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (type== NetworkEventType.NotMoving)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
message.Write(keys[(int)InputType.ActionHeld].Dequeue);
|
||||||
//if (type == Networking.NetworkEventType.KeyHit)
|
message.Write(keys[(int)InputType.SecondaryHeld].Dequeue);
|
||||||
//{
|
|
||||||
// message.Write(selectKeyHit.Dequeue);
|
message.Write((float)NetTime.Now);
|
||||||
message.Write(actionKeyDown.Dequeue);
|
|
||||||
message.Write(secondaryKeyDown.Dequeue);
|
|
||||||
//}
|
|
||||||
|
|
||||||
message.Write(NetTime.Now);
|
|
||||||
|
|
||||||
// Write byte = move direction
|
// Write byte = move direction
|
||||||
message.Write(AnimController.TargetMovement.X);
|
message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.X, -10.0f, 10.0f), -10.0f, 10.0f, 8);
|
||||||
message.Write(AnimController.TargetMovement.Y);
|
message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.Y, -10.0f, 10.0f), -10.0f, 10.0f, 8);
|
||||||
|
|
||||||
message.Write(AnimController.TargetDir==Direction.Right);
|
message.Write(AnimController.TargetDir==Direction.Right);
|
||||||
|
|
||||||
message.Write(cursorPosition.X);
|
if (aiController==null)
|
||||||
message.Write(cursorPosition.Y);
|
{
|
||||||
|
message.Write(cursorPosition.X);
|
||||||
|
message.Write(cursorPosition.Y);
|
||||||
|
}
|
||||||
|
|
||||||
message.Write(LargeUpdateTimer <= 0);
|
message.Write(LargeUpdateTimer <= 0);
|
||||||
|
|
||||||
if (LargeUpdateTimer<=0)
|
if (LargeUpdateTimer<=0)
|
||||||
@@ -1050,32 +1038,31 @@ namespace Subsurface
|
|||||||
message.Write(limb.body.Position.X);
|
message.Write(limb.body.Position.X);
|
||||||
message.Write(limb.body.Position.Y);
|
message.Write(limb.body.Position.Y);
|
||||||
|
|
||||||
message.Write(limb.body.LinearVelocity.X);
|
//message.Write(limb.body.LinearVelocity.X);
|
||||||
message.Write(limb.body.LinearVelocity.Y);
|
//message.Write(limb.body.LinearVelocity.Y);
|
||||||
|
|
||||||
message.Write(limb.body.Rotation);
|
message.Write(limb.body.Rotation);
|
||||||
message.Write(limb.body.AngularVelocity);
|
//message.WriteRangedSingle(MathHelper.Clamp(limb.body.AngularVelocity, -10.0f, 10.0f), -10.0f, 10.0f, 8);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
message.Write(AnimController.StunTimer);
|
message.WriteRangedSingle(MathHelper.Clamp(AnimController.StunTimer,0.0f,60.0f), 0.0f, 60.0f, 8);
|
||||||
message.Write((byte)health);
|
message.Write((byte)((health/maxHealth)*255.0f));
|
||||||
|
|
||||||
LargeUpdateTimer = 5;
|
if (aiController != null) aiController.FillNetworkData(message);
|
||||||
|
|
||||||
|
LargeUpdateTimer = 10;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Limb torso = AnimController.GetLimb(LimbType.Torso);
|
Limb torso = AnimController.GetLimb(LimbType.Torso);
|
||||||
|
if (torso == null) torso = AnimController.GetLimb(LimbType.Head);
|
||||||
|
|
||||||
message.Write(torso.body.Position.X);
|
message.Write(torso.body.Position.X);
|
||||||
message.Write(torso.body.Position.Y);
|
message.Write(torso.body.Position.Y);
|
||||||
|
|
||||||
LargeUpdateTimer = Math.Max(0, LargeUpdateTimer-1);
|
LargeUpdateTimer = Math.Max(0, LargeUpdateTimer-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (aiController != null) aiController.FillNetworkData(message);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message)
|
public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message)
|
||||||
@@ -1112,10 +1099,17 @@ namespace Subsurface
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (type == NetworkEventType.NotMoving)
|
||||||
|
{
|
||||||
|
AnimController.TargetMovement = Vector2.Zero;
|
||||||
|
keys[(int)InputType.ActionHeld].State = false;
|
||||||
|
keys[(int)InputType.SecondaryHeld].State = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool actionKeyState = false;
|
bool actionKeyState = false;
|
||||||
bool secondaryKeyState = false;
|
bool secondaryKeyState = false;
|
||||||
double sendingTime = 0.0f;
|
float sendingTime = 0.0f;
|
||||||
Vector2 targetMovement = Vector2.Zero;
|
Vector2 targetMovement = Vector2.Zero;
|
||||||
bool targetDir = false;
|
bool targetDir = false;
|
||||||
Vector2 cursorPos = Vector2.Zero;
|
Vector2 cursorPos = Vector2.Zero;
|
||||||
@@ -1125,12 +1119,20 @@ namespace Subsurface
|
|||||||
actionKeyState = message.ReadBoolean();
|
actionKeyState = message.ReadBoolean();
|
||||||
secondaryKeyState = message.ReadBoolean();
|
secondaryKeyState = message.ReadBoolean();
|
||||||
|
|
||||||
sendingTime = message.ReadDouble();
|
sendingTime = message.ReadFloat();
|
||||||
|
|
||||||
|
targetMovement = new Vector2(message.ReadRangedSingle(-10.0f, 10.0f, 8), message.ReadRangedSingle(-10.0f, 10.0f, 8));
|
||||||
|
targetMovement.X = MathUtils.Round(targetMovement.X, 0.1f);
|
||||||
|
targetMovement.Y = MathUtils.Round(targetMovement.Y, 0.1f);
|
||||||
|
|
||||||
targetMovement = new Vector2 (message.ReadFloat(), message.ReadFloat());
|
|
||||||
targetDir = message.ReadBoolean();
|
targetDir = message.ReadBoolean();
|
||||||
|
|
||||||
cursorPos = new Vector2(message.ReadFloat(), message.ReadFloat());
|
if (aiController==null)
|
||||||
|
{
|
||||||
|
cursorPos = new Vector2(
|
||||||
|
message.ReadFloat(),
|
||||||
|
message.ReadFloat());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
catch
|
catch
|
||||||
@@ -1140,8 +1142,8 @@ namespace Subsurface
|
|||||||
|
|
||||||
AnimController.IsStanding = true;
|
AnimController.IsStanding = true;
|
||||||
|
|
||||||
actionKeyDown.State = actionKeyState;
|
keys[(int)InputType.ActionHeld].State = actionKeyState;
|
||||||
secondaryKeyDown.State = secondaryKeyState;
|
keys[(int)InputType.SecondaryHeld].State = secondaryKeyState;
|
||||||
|
|
||||||
if (sendingTime <= LastNetworkUpdate) return;
|
if (sendingTime <= LastNetworkUpdate) return;
|
||||||
|
|
||||||
@@ -1162,11 +1164,11 @@ namespace Subsurface
|
|||||||
pos.X = message.ReadFloat();
|
pos.X = message.ReadFloat();
|
||||||
pos.Y = message.ReadFloat();
|
pos.Y = message.ReadFloat();
|
||||||
|
|
||||||
vel.X = message.ReadFloat();
|
//vel.X = message.ReadFloat();
|
||||||
vel.Y = message.ReadFloat();
|
//vel.Y = message.ReadFloat();
|
||||||
|
|
||||||
rotation = message.ReadFloat();
|
rotation = message.ReadFloat();
|
||||||
angularVel = message.ReadFloat();
|
//angularVel = message.ReadFloat();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -1175,10 +1177,10 @@ namespace Subsurface
|
|||||||
|
|
||||||
if (limb.body != null)
|
if (limb.body != null)
|
||||||
{
|
{
|
||||||
limb.body.TargetVelocity = vel;
|
limb.body.TargetVelocity = limb.body.LinearVelocity;
|
||||||
limb.body.TargetPosition = pos;// +vel * (float)(deltaTime / 60.0);
|
limb.body.TargetPosition = pos;// +vel * (float)(deltaTime / 60.0);
|
||||||
limb.body.TargetRotation = rotation;// +angularVel * (float)(deltaTime / 60.0);
|
limb.body.TargetRotation = rotation;// +angularVel * (float)(deltaTime / 60.0);
|
||||||
limb.body.TargetAngularVelocity = angularVel;
|
limb.body.TargetAngularVelocity = limb.body.AngularVelocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1187,8 +1189,8 @@ namespace Subsurface
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
newStunTimer = message.ReadFloat();
|
newStunTimer = message.ReadRangedSingle(0.0f, 60.0f, 8);
|
||||||
newHealth = message.ReadByte();
|
newHealth = (message.ReadByte()/255.0f)*maxHealth;
|
||||||
}
|
}
|
||||||
catch { return; }
|
catch { return; }
|
||||||
|
|
||||||
@@ -1196,6 +1198,8 @@ namespace Subsurface
|
|||||||
Health = newHealth;
|
Health = newHealth;
|
||||||
|
|
||||||
LargeUpdateTimer = 1;
|
LargeUpdateTimer = 1;
|
||||||
|
|
||||||
|
if (aiController != null) aiController.ReadNetworkData(message);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1210,13 +1214,12 @@ namespace Subsurface
|
|||||||
|
|
||||||
|
|
||||||
Limb torso = AnimController.GetLimb(LimbType.Torso);
|
Limb torso = AnimController.GetLimb(LimbType.Torso);
|
||||||
|
if (torso == null) torso = AnimController.GetLimb(LimbType.Head);
|
||||||
torso.body.TargetPosition = pos;
|
torso.body.TargetPosition = pos;
|
||||||
|
|
||||||
LargeUpdateTimer = 0;
|
LargeUpdateTimer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aiController != null) aiController.ReadNetworkData(message);
|
|
||||||
|
|
||||||
LastNetworkUpdate = sendingTime;
|
LastNetworkUpdate = sendingTime;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
get { return pickedItems; }
|
get { return pickedItems; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sprite HeadSprite
|
public Sprite HeadSprite
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -156,7 +156,7 @@ namespace Subsurface
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public GUIFrame CreateInfoFrame(Rectangle rect)
|
public GUIFrame CreateInfoFrame(Rectangle rect)
|
||||||
{
|
{
|
||||||
GUIFrame frame = new GUIFrame(rect, Color.Transparent);
|
GUIFrame frame = new GUIFrame(rect, Color.Transparent);
|
||||||
@@ -269,7 +269,7 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
UpdateCharacterItems();
|
UpdateCharacterItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pickedItems.Count > 0)
|
if (pickedItems.Count > 0)
|
||||||
{
|
{
|
||||||
charElement.Add(new XAttribute("items", string.Join(",", pickedItems)));
|
charElement.Add(new XAttribute("items", string.Join(",", pickedItems)));
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Linq;
|
|||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using FarseerPhysics;
|
using FarseerPhysics;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
|
using Subsurface.Items.Components;
|
||||||
|
|
||||||
namespace Subsurface
|
namespace Subsurface
|
||||||
{
|
{
|
||||||
@@ -542,7 +543,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
void UpdateClimbing()
|
void UpdateClimbing()
|
||||||
{
|
{
|
||||||
if (character.SelectedConstruction == null)
|
if (character.SelectedConstruction == null || character.SelectedConstruction.GetComponent<Ladder>()==null)
|
||||||
{
|
{
|
||||||
Anim = Animation.None;
|
Anim = Animation.None;
|
||||||
return;
|
return;
|
||||||
@@ -623,7 +624,12 @@ namespace Subsurface
|
|||||||
torso.body.ApplyForce(climbForce * 40.0f * torso.Mass);
|
torso.body.ApplyForce(climbForce * 40.0f * torso.Mass);
|
||||||
head.body.SmoothRotate(0.0f);
|
head.body.SmoothRotate(0.0f);
|
||||||
|
|
||||||
Rectangle trigger = character.SelectedConstruction.Prefab.Triggers.First();
|
Rectangle trigger = character.SelectedConstruction.Prefab.Triggers.FirstOrDefault();
|
||||||
|
if (trigger == null)
|
||||||
|
{
|
||||||
|
character.SelectedConstruction = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
trigger = character.SelectedConstruction.TransformTrigger(trigger);
|
trigger = character.SelectedConstruction.TransformTrigger(trigger);
|
||||||
|
|
||||||
//stop climbing if:
|
//stop climbing if:
|
||||||
@@ -673,10 +679,10 @@ namespace Subsurface
|
|||||||
Limb rightHand = GetLimb(LimbType.RightHand);
|
Limb rightHand = GetLimb(LimbType.RightHand);
|
||||||
Limb rightArm = GetLimb(LimbType.RightArm);
|
Limb rightArm = GetLimb(LimbType.RightArm);
|
||||||
|
|
||||||
Vector2 itemPos = character.SecondaryKeyDown.State ? aimPos : holdPos;
|
Vector2 itemPos = character.GetInputState(InputType.SecondaryHeld) ? aimPos : holdPos;
|
||||||
|
|
||||||
float itemAngle;
|
float itemAngle;
|
||||||
if (character.SecondaryKeyDown.State && itemPos != Vector2.Zero)
|
if (character.GetInputState(InputType.SecondaryHeld) && itemPos != Vector2.Zero)
|
||||||
{
|
{
|
||||||
Vector2 mousePos = ConvertUnits.ToSimUnits(character.CursorPosition);
|
Vector2 mousePos = ConvertUnits.ToSimUnits(character.CursorPosition);
|
||||||
|
|
||||||
|
|||||||
@@ -472,7 +472,7 @@ namespace Subsurface
|
|||||||
inWater = false;
|
inWater = false;
|
||||||
headInWater = false;
|
headInWater = false;
|
||||||
|
|
||||||
if (currentHull.Volume>currentHull.FullVolume*0.95f || ConvertUnits.ToSimUnits(currentHull.Surface)-floorY> HeadPosition*0.95f)
|
if (currentHull.Volume > currentHull.FullVolume * 0.95f || ConvertUnits.ToSimUnits(currentHull.Surface) - floorY > HeadPosition * 0.95f)
|
||||||
inWater = true;
|
inWater = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -562,7 +562,7 @@ namespace Subsurface
|
|||||||
private void UpdateNetplayerPosition()
|
private void UpdateNetplayerPosition()
|
||||||
{
|
{
|
||||||
Limb refLimb = GetLimb(LimbType.Torso);
|
Limb refLimb = GetLimb(LimbType.Torso);
|
||||||
if (refLimb== null) refLimb = GetLimb(LimbType.Head);
|
if (refLimb == null) refLimb = GetLimb(LimbType.Head);
|
||||||
|
|
||||||
if (refLimb.body.TargetPosition == Vector2.Zero) return;
|
if (refLimb.body.TargetPosition == Vector2.Zero) return;
|
||||||
|
|
||||||
@@ -603,7 +603,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
if (resetAll)
|
if (resetAll)
|
||||||
{
|
{
|
||||||
System.Diagnostics.Debug.WriteLine("resetall");
|
System.Diagnostics.Debug.WriteLine("reset ragdoll limb positions");
|
||||||
|
|
||||||
foreach (Limb limb in limbs)
|
foreach (Limb limb in limbs)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ namespace Subsurface
|
|||||||
|
|
||||||
public class ContentPackage
|
public class ContentPackage
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public static string Folder = "Data/ContentPackages/";
|
||||||
|
|
||||||
public static List<ContentPackage> list = new List<ContentPackage>();
|
public static List<ContentPackage> list = new List<ContentPackage>();
|
||||||
|
|
||||||
|
|
||||||
@@ -81,6 +84,7 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
ContentPackage newPackage = new ContentPackage("Content/Data/"+name);
|
ContentPackage newPackage = new ContentPackage("Content/Data/"+name);
|
||||||
newPackage.name = name;
|
newPackage.name = name;
|
||||||
|
newPackage.Path = Folder + name;
|
||||||
list.Add(newPackage);
|
list.Add(newPackage);
|
||||||
|
|
||||||
return newPackage;
|
return newPackage;
|
||||||
|
|||||||
@@ -136,11 +136,13 @@ namespace Subsurface
|
|||||||
|
|
||||||
public static void ExecuteCommand(string command, Game1 game)
|
public static void ExecuteCommand(string command, Game1 game)
|
||||||
{
|
{
|
||||||
|
#if !DEBUG
|
||||||
if (Game1.Client!=null)
|
if (Game1.Client!=null)
|
||||||
{
|
{
|
||||||
ThrowError("Console commands are disabled in multiplayer mode");
|
ThrowError("Console commands are disabled in multiplayer mode");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (command == "") return;
|
if (command == "") return;
|
||||||
string[] commands = command.Split(' ');
|
string[] commands = command.Split(' ');
|
||||||
@@ -246,6 +248,9 @@ namespace Subsurface
|
|||||||
hull.OxygenPercentage = 100.0f;
|
hull.OxygenPercentage = 100.0f;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "tutorial":
|
||||||
|
TutorialMode.Start();
|
||||||
|
break;
|
||||||
case "lobbyscreen":
|
case "lobbyscreen":
|
||||||
case "lobby":
|
case "lobby":
|
||||||
Game1.LobbyScreen.Select();
|
Game1.LobbyScreen.Select();
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
#if WINDOWS
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
#endif
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Input;
|
using Microsoft.Xna.Framework.Input;
|
||||||
|
|
||||||
@@ -42,12 +44,14 @@ namespace EventInput
|
|||||||
//ctrl-v
|
//ctrl-v
|
||||||
if (e.Character == 0x16)
|
if (e.Character == 0x16)
|
||||||
{
|
{
|
||||||
|
#if WINDOWS
|
||||||
//XNA runs in Multiple Thread Apartment state, which cannot recieve clipboard
|
//XNA runs in Multiple Thread Apartment state, which cannot recieve clipboard
|
||||||
Thread thread = new Thread(PasteThread);
|
Thread thread = new Thread(PasteThread);
|
||||||
thread.SetApartmentState(ApartmentState.STA);
|
thread.SetApartmentState(ApartmentState.STA);
|
||||||
thread.Start();
|
thread.Start();
|
||||||
thread.Join();
|
thread.Join();
|
||||||
_subscriber.ReceiveTextInput(_pasteResult);
|
_subscriber.ReceiveTextInput(_pasteResult);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -74,6 +78,7 @@ namespace EventInput
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WINDOWS
|
||||||
//Thread has to be in Single Thread Apartment state in order to receive clipboard
|
//Thread has to be in Single Thread Apartment state in order to receive clipboard
|
||||||
string _pasteResult = "";
|
string _pasteResult = "";
|
||||||
[STAThread]
|
[STAThread]
|
||||||
@@ -81,5 +86,7 @@ namespace EventInput
|
|||||||
{
|
{
|
||||||
_pasteResult = Clipboard.ContainsText() ? Clipboard.GetText() : "";
|
_pasteResult = Clipboard.ContainsText() ? Clipboard.GetText() : "";
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace Subsurface
|
|||||||
public static GUIStyle style;
|
public static GUIStyle style;
|
||||||
|
|
||||||
static Texture2D t;
|
static Texture2D t;
|
||||||
public static SpriteFont Font, SmallFont;
|
public static SpriteFont Font, SmallFont, LargeFont;
|
||||||
|
|
||||||
private static GraphicsDevice graphicsDevice;
|
private static GraphicsDevice graphicsDevice;
|
||||||
|
|
||||||
@@ -274,7 +274,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
bool clicked = false;
|
bool clicked = false;
|
||||||
|
|
||||||
if (rect.Contains(PlayerInput.GetMouseState.Position))
|
if (rect.Contains(PlayerInput.MousePosition))
|
||||||
{
|
{
|
||||||
clicked = (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed);
|
clicked = (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed);
|
||||||
|
|
||||||
@@ -301,8 +301,16 @@ namespace Subsurface
|
|||||||
spriteBatch.DrawString(Font,
|
spriteBatch.DrawString(Font,
|
||||||
"Physics: " + Game1.World.UpdateTime
|
"Physics: " + Game1.World.UpdateTime
|
||||||
+ " - bodies: " + Game1.World.BodyList.Count
|
+ " - bodies: " + Game1.World.BodyList.Count
|
||||||
+ "Camera pos: " + Game1.GameScreen.Cam.Position,
|
+ " Camera pos: " + Game1.GameScreen.Cam.Position,
|
||||||
new Vector2(10, 30), Color.White);
|
new Vector2(10, 30), Color.White);
|
||||||
|
|
||||||
|
if (Submarine.Loaded!=null)
|
||||||
|
{
|
||||||
|
spriteBatch.DrawString(Font,
|
||||||
|
"Sub pos: " + Submarine.Loaded.Position,
|
||||||
|
new Vector2(10, 50), Color.White);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
public override void Draw(SpriteBatch spriteBatch)
|
public override void Draw(SpriteBatch spriteBatch)
|
||||||
{
|
{
|
||||||
if (rect.Contains(PlayerInput.GetMouseState.Position) && Enabled && (MouseOn == null || MouseOn == this || IsParentOf(MouseOn)))
|
if (rect.Contains(PlayerInput.MousePosition) && Enabled && (MouseOn == null || MouseOn == this || IsParentOf(MouseOn)))
|
||||||
{
|
{
|
||||||
state = ComponentState.Hover;
|
state = ComponentState.Hover;
|
||||||
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed)
|
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed)
|
||||||
|
|||||||
@@ -27,6 +27,14 @@ namespace Subsurface
|
|||||||
|
|
||||||
private bool enabled;
|
private bool enabled;
|
||||||
|
|
||||||
|
public GUIComponent Selected
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return selected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public object SelectedData
|
public object SelectedData
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -276,7 +284,7 @@ namespace Subsurface
|
|||||||
if (CheckSelected() != selected.UserData) selected = null;
|
if (CheckSelected() != selected.UserData) selected = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (enabled && (MouseOn == this || (MouseOn != null && this.IsParentOf(MouseOn))) && child.Rect.Contains(PlayerInput.GetMouseState.Position))
|
else if (enabled && (MouseOn == this || (MouseOn != null && this.IsParentOf(MouseOn))) && child.Rect.Contains(PlayerInput.MousePosition))
|
||||||
{
|
{
|
||||||
child.State = ComponentState.Hover;
|
child.State = ComponentState.Hover;
|
||||||
if (PlayerInput.LeftButtonClicked())
|
if (PlayerInput.LeftButtonClicked())
|
||||||
|
|||||||
@@ -15,6 +15,12 @@ namespace Subsurface
|
|||||||
//GUIFrame frame;
|
//GUIFrame frame;
|
||||||
public GUIButton[] Buttons;
|
public GUIButton[] Buttons;
|
||||||
|
|
||||||
|
public string Text
|
||||||
|
{
|
||||||
|
get { return (children[1] as GUITextBlock).Text; }
|
||||||
|
set { (children[1] as GUITextBlock).Text = value; }
|
||||||
|
}
|
||||||
|
|
||||||
public GUIMessageBox(string header, string text)
|
public GUIMessageBox(string header, string text)
|
||||||
: this(header, text, new string[] {"OK"})
|
: this(header, text, new string[] {"OK"})
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -155,14 +155,14 @@ namespace Subsurface
|
|||||||
int moveAmount;
|
int moveAmount;
|
||||||
if (isHorizontal)
|
if (isHorizontal)
|
||||||
{
|
{
|
||||||
moveAmount = PlayerInput.GetMouseState.Position.X - PlayerInput.GetOldMouseState.Position.X;
|
moveAmount = (int)PlayerInput.MouseSpeed.X;
|
||||||
newX = Math.Min(Math.Max(newX + moveAmount, 0), frame.Rect.Width - bar.Rect.Width);
|
newX = Math.Min(Math.Max(newX + moveAmount, 0), frame.Rect.Width - bar.Rect.Width);
|
||||||
|
|
||||||
barScroll = (float)newX / ((float)frame.Rect.Width - (float)bar.Rect.Width);
|
barScroll = (float)newX / ((float)frame.Rect.Width - (float)bar.Rect.Width);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
moveAmount = PlayerInput.GetMouseState.Position.Y - PlayerInput.GetOldMouseState.Position.Y;
|
moveAmount = (int)PlayerInput.MouseSpeed.Y;
|
||||||
newY = Math.Min(Math.Max(newY+moveAmount, 0), frame.Rect.Height - bar.Rect.Height);
|
newY = Math.Min(Math.Max(newY+moveAmount, 0), frame.Rect.Height - bar.Rect.Height);
|
||||||
|
|
||||||
barScroll = (float)newY / ((float)frame.Rect.Height - (float)bar.Rect.Height);
|
barScroll = (float)newY / ((float)frame.Rect.Height - (float)bar.Rect.Height);
|
||||||
|
|||||||
@@ -76,9 +76,12 @@ namespace Subsurface
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public GUITextBlock(Rectangle rect, string text, GUIStyle style, Alignment alignment = Alignment.TopLeft, Alignment textAlignment = Alignment.TopLeft, GUIComponent parent = null, bool wrap = false)
|
public GUITextBlock(Rectangle rect, string text, GUIStyle style, Alignment alignment = Alignment.TopLeft, Alignment textAlignment = Alignment.TopLeft, GUIComponent parent = null, bool wrap = false, SpriteFont font =null)
|
||||||
: this (rect, text, null, null, alignment, textAlignment, style, parent, wrap)
|
: this (rect, text, null, null, alignment, textAlignment, style, parent, wrap)
|
||||||
{
|
{
|
||||||
|
this.Font = font == null ? GUI.Font : font;
|
||||||
|
|
||||||
|
SetTextPos();
|
||||||
}
|
}
|
||||||
|
|
||||||
public GUITextBlock(Rectangle rect, string text, Color? color, Color? textColor, Alignment textAlignment = Alignment.Left, GUIStyle style = null, GUIComponent parent = null, bool wrap = false)
|
public GUITextBlock(Rectangle rect, string text, Color? color, Color? textColor, Alignment textAlignment = Alignment.Left, GUIStyle style = null, GUIComponent parent = null, bool wrap = false)
|
||||||
@@ -117,11 +120,7 @@ namespace Subsurface
|
|||||||
if (parent != null)
|
if (parent != null)
|
||||||
parent.AddChild(this);
|
parent.AddChild(this);
|
||||||
|
|
||||||
//if (wrap)
|
this.Wrap = wrap;
|
||||||
//{
|
|
||||||
this.Wrap = wrap;
|
|
||||||
// this.text = ToolBox.WrapText(this.text, rect.Width);
|
|
||||||
//}
|
|
||||||
|
|
||||||
SetTextPos();
|
SetTextPos();
|
||||||
}
|
}
|
||||||
@@ -135,7 +134,7 @@ namespace Subsurface
|
|||||||
if (Wrap && rect.Width>0)
|
if (Wrap && rect.Width>0)
|
||||||
{
|
{
|
||||||
//text = text.Replace("\n"," ");
|
//text = text.Replace("\n"," ");
|
||||||
text = ToolBox.WrapText(text, rect.Width, Font);
|
text = ToolBox.WrapText(text, rect.Width - padding.X - padding.Z, Font);
|
||||||
|
|
||||||
Vector2 newSize = MeasureText(text);
|
Vector2 newSize = MeasureText(text);
|
||||||
|
|
||||||
|
|||||||
@@ -146,6 +146,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
public void Deselect()
|
public void Deselect()
|
||||||
{
|
{
|
||||||
|
Selected = false;
|
||||||
if (keyboardDispatcher.Subscriber == this) keyboardDispatcher.Subscriber = null;
|
if (keyboardDispatcher.Subscriber == this) keyboardDispatcher.Subscriber = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +159,7 @@ namespace Subsurface
|
|||||||
caretTimer += deltaTime;
|
caretTimer += deltaTime;
|
||||||
caretVisible = ((caretTimer*1000.0f) % 1000) < 500;
|
caretVisible = ((caretTimer*1000.0f) % 1000) < 500;
|
||||||
|
|
||||||
if (rect.Contains(PlayerInput.GetMouseState.Position))
|
if (rect.Contains(PlayerInput.MousePosition))
|
||||||
{
|
{
|
||||||
state = ComponentState.Hover;
|
state = ComponentState.Hover;
|
||||||
if (PlayerInput.LeftButtonClicked()) Select();
|
if (PlayerInput.LeftButtonClicked()) Select();
|
||||||
|
|||||||
@@ -25,6 +25,12 @@ namespace Subsurface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool Enabled
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
public GUITickBox(Rectangle rect, string label, Alignment alignment, GUIComponent parent)
|
public GUITickBox(Rectangle rect, string label, Alignment alignment, GUIComponent parent)
|
||||||
: base(null)
|
: base(null)
|
||||||
{
|
{
|
||||||
@@ -35,15 +41,26 @@ namespace Subsurface
|
|||||||
box.HoverColor = Color.Gray;
|
box.HoverColor = Color.Gray;
|
||||||
box.SelectedColor = Color.DarkGray;
|
box.SelectedColor = Color.DarkGray;
|
||||||
|
|
||||||
text = new GUITextBlock(new Rectangle(rect.X + 40, rect.Y, 200, 30), label, Color.Transparent, Color.White, Alignment.TopLeft, null, this);
|
text = new GUITextBlock(new Rectangle(rect.X + 40, rect.Y, 200, rect.Height), label, Color.Transparent, Color.White, Alignment.TopLeft, null, this);
|
||||||
|
|
||||||
|
Enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float deltaTime)
|
public override void Update(float deltaTime)
|
||||||
{
|
{
|
||||||
base.Update(deltaTime);
|
if (rect.Width ==420)
|
||||||
|
{
|
||||||
|
int asd = 1;
|
||||||
|
}
|
||||||
|
//base.Update(deltaTime);
|
||||||
|
|
||||||
if (box.Rect.Contains(PlayerInput.GetMouseState.Position))
|
if (!Enabled) return;
|
||||||
|
|
||||||
|
if (box.Rect.Contains(PlayerInput.MousePosition))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
box.State = ComponentState.Hover;
|
box.State = ComponentState.Hover;
|
||||||
|
|
||||||
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed)
|
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed)
|
||||||
@@ -67,12 +84,16 @@ namespace Subsurface
|
|||||||
|
|
||||||
public override void Draw(SpriteBatch spriteBatch)
|
public override void Draw(SpriteBatch spriteBatch)
|
||||||
{
|
{
|
||||||
|
if (rect.Width == 420)
|
||||||
|
{
|
||||||
|
int asd = 1;
|
||||||
|
}
|
||||||
|
|
||||||
DrawChildren(spriteBatch);
|
DrawChildren(spriteBatch);
|
||||||
|
|
||||||
if (Selected)
|
GUI.DrawRectangle(spriteBatch, new Rectangle(box.Rect.X + 2, box.Rect.Y + 2, box.Rect.Width - 4, box.Rect.Height - 4),
|
||||||
{
|
selected ? Color.Green * 0.8f : Color.Black, true);
|
||||||
GUI.DrawRectangle(spriteBatch, new Rectangle(box.Rect.X + 2, box.Rect.Y + 2, box.Rect.Width - 4, box.Rect.Height - 4), Color.Green * 0.8f, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using Subsurface.Particles;
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.Xna.Framework.Input;
|
using Microsoft.Xna.Framework.Input;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
namespace Subsurface
|
namespace Subsurface
|
||||||
{
|
{
|
||||||
@@ -119,8 +120,8 @@ namespace Subsurface
|
|||||||
//TargetElapsedTime = new TimeSpan(0, 0, 0, 0, 55);
|
//TargetElapsedTime = new TimeSpan(0, 0, 0, 0, 55);
|
||||||
|
|
||||||
World = new World(new Vector2(0, -9.82f));
|
World = new World(new Vector2(0, -9.82f));
|
||||||
Settings.VelocityIterations = 2;
|
FarseerPhysics.Settings.VelocityIterations = 2;
|
||||||
Settings.PositionIterations = 1;
|
FarseerPhysics.Settings.PositionIterations = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -165,6 +166,7 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
GUI.Font = ToolBox.TryLoadFont("SpriteFont1", Content);
|
GUI.Font = ToolBox.TryLoadFont("SpriteFont1", Content);
|
||||||
GUI.SmallFont = ToolBox.TryLoadFont("SmallFont", Content);
|
GUI.SmallFont = ToolBox.TryLoadFont("SmallFont", Content);
|
||||||
|
GUI.LargeFont = ToolBox.TryLoadFont("LargeFont", Content);
|
||||||
|
|
||||||
sw = new Stopwatch();
|
sw = new Stopwatch();
|
||||||
|
|
||||||
@@ -263,7 +265,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
DebugConsole.Update(this, (float)deltaTime);
|
DebugConsole.Update(this, (float)deltaTime);
|
||||||
|
|
||||||
if ((!DebugConsole.IsOpen && !GUI.PauseMenuOpen) || NetworkMember != null) Screen.Selected.Update(deltaTime);
|
if ((!DebugConsole.IsOpen && !GUI.PauseMenuOpen) || (NetworkMember != null && NetworkMember.GameStarted)) Screen.Selected.Update(deltaTime);
|
||||||
|
|
||||||
GUI.Update((float)deltaTime);
|
GUI.Update((float)deltaTime);
|
||||||
|
|
||||||
@@ -323,4 +325,4 @@ namespace Subsurface
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,16 +30,7 @@ namespace Subsurface
|
|||||||
base.Update(deltaTime);
|
base.Update(deltaTime);
|
||||||
|
|
||||||
if (!isRunning) return;
|
if (!isRunning) return;
|
||||||
|
|
||||||
if (DateTime.Now >= endTime)
|
|
||||||
{
|
|
||||||
string endMessage = traitor.character.Info.Name + " was a traitor! ";
|
|
||||||
endMessage += (traitor.character.Info.Gender == Gender.Male) ? "His" : "Her";
|
|
||||||
endMessage += " task was to assassinate " + target.character.Info.Name + ". The task was unsuccesful.";
|
|
||||||
End(endMessage);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (traitor==null || target ==null)
|
if (traitor==null || target ==null)
|
||||||
{
|
{
|
||||||
@@ -68,6 +59,35 @@ namespace Subsurface
|
|||||||
endMessage += " task was to assassinate " + target.character.Info.Name + ". The task was succesful.";
|
endMessage += " task was to assassinate " + target.character.Info.Name + ". The task was succesful.";
|
||||||
End(endMessage);
|
End(endMessage);
|
||||||
}
|
}
|
||||||
|
else if (traitor.character.IsDead)
|
||||||
|
{
|
||||||
|
string endMessage = traitor.character.Info.Name + " was a traitor! ";
|
||||||
|
endMessage += (traitor.character.Info.Gender == Gender.Male) ? "His" : "Her";
|
||||||
|
endMessage += " task was to assassinate " + target.character.Info.Name + ", but ";
|
||||||
|
endMessage += (traitor.character.Info.Gender == Gender.Male) ? "he" : "she";
|
||||||
|
endMessage += " got " + ((traitor.character.Info.Gender == Gender.Male) ? "himself" : "herself");
|
||||||
|
endMessage += " killed before completing it.";
|
||||||
|
End(endMessage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (Level.Loaded.AtEndPosition)
|
||||||
|
{
|
||||||
|
string endMessage = traitor.character.Info.Name + " was a traitor! ";
|
||||||
|
endMessage += (traitor.character.Info.Gender == Gender.Male) ? "His" : "Her";
|
||||||
|
endMessage += " task was to assassinate " + target.character.Info.Name + ". ";
|
||||||
|
endMessage += "The task was unsuccessful - the has submarine reached its destination.";
|
||||||
|
End(endMessage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (DateTime.Now >= endTime)
|
||||||
|
{
|
||||||
|
string endMessage = traitor.character.Info.Name + " was a traitor! ";
|
||||||
|
endMessage += (traitor.character.Info.Gender == Gender.Male) ? "His" : "Her";
|
||||||
|
endMessage += " task was to assassinate " + target.character.Info.Name + ". The task was unsuccesful.";
|
||||||
|
End(endMessage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ namespace Subsurface
|
|||||||
|
|
||||||
Game1.GameSession.StartShift(TimeSpan.Zero, "tutorial");
|
Game1.GameSession.StartShift(TimeSpan.Zero, "tutorial");
|
||||||
|
|
||||||
|
Game1.GameSession.taskManager.Tasks.Clear();
|
||||||
|
|
||||||
Game1.GameScreen.Select();
|
Game1.GameScreen.Select();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +186,7 @@ namespace Subsurface
|
|||||||
+ " going into the to the power connection - that's why the monitor isn't working."
|
+ " going into the to the power connection - that's why the monitor isn't working."
|
||||||
+ " You should find a piece of wire to connect it. Try searching some of the cabinets scattered around the sub.");
|
+ " You should find a piece of wire to connect it. Try searching some of the cabinets scattered around the sub.");
|
||||||
|
|
||||||
while (Character.Controlled.Inventory.items.FirstOrDefault(i => i!=null && i.GetComponent<Wire>()!=null)==null)
|
while (!HasItem("Wire"))
|
||||||
{
|
{
|
||||||
yield return Status.Running;
|
yield return Status.Running;
|
||||||
}
|
}
|
||||||
@@ -280,32 +282,159 @@ namespace Subsurface
|
|||||||
var moloch = new Character("Content/Characters/Moloch/moloch.xml", steering.Item.SimPosition + Vector2.UnitX * 15.0f);
|
var moloch = new Character("Content/Characters/Moloch/moloch.xml", steering.Item.SimPosition + Vector2.UnitX * 15.0f);
|
||||||
moloch.PlaySound(AIController.AiState.Attack);
|
moloch.PlaySound(AIController.AiState.Attack);
|
||||||
|
|
||||||
//moloch.AIController.
|
|
||||||
|
|
||||||
infoBox = CreateInfoFrame("Uh-oh... Something enormous just appeared on the radar.");
|
infoBox = CreateInfoFrame("Uh-oh... Something enormous just appeared on the radar.");
|
||||||
|
|
||||||
Structure window = null;
|
List<Structure> windows = new List<Structure>();
|
||||||
foreach (Structure s in Structure.wallList)
|
foreach (Structure s in Structure.wallList)
|
||||||
{
|
{
|
||||||
if (s.CastShadow) continue;
|
if (s.CastShadow || !s.HasBody) continue;
|
||||||
|
|
||||||
if (window == null || s.Rect.Right > window.Rect.Right) window = s;
|
if (s.Rect.Right > steering.Item.Position.X) windows.Add(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool broken = false;
|
bool broken = false;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
moloch.AIController.SelectTarget(steering.Item);
|
moloch.AIController.SelectTarget(steering.Item.CurrentHull.AiTarget);
|
||||||
for (int i = 0; i < window.SectionCount; i++)
|
Vector2 steeringDir = windows[0].Position - moloch.Position;
|
||||||
|
if (steeringDir != Vector2.Zero) steeringDir = Vector2.Normalize(steeringDir);
|
||||||
|
|
||||||
|
foreach (Limb limb in moloch.AnimController.limbs)
|
||||||
{
|
{
|
||||||
if (!window.SectionHasHole(i)) continue;
|
limb.body.LinearVelocity = new Vector2(limb.LinearVelocity.X, limb.LinearVelocity.Y + steeringDir.Y*0.01f);
|
||||||
broken = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moloch.AIController.Steering = steeringDir;
|
||||||
|
|
||||||
|
foreach (Structure window in windows)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < window.SectionCount; i++)
|
||||||
|
{
|
||||||
|
if (!window.SectionHasHole(i)) continue;
|
||||||
|
broken = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (broken) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
yield return new WaitForSeconds(1.0f);
|
yield return new WaitForSeconds(1.0f);
|
||||||
} while (!broken);
|
} while (!broken);
|
||||||
|
|
||||||
|
yield return new WaitForSeconds(1.0f);
|
||||||
|
|
||||||
|
|
||||||
|
var capacitor1 = Item.itemList.Find(i => i.HasTag("capacitor1")).GetComponent<PowerContainer>();
|
||||||
|
var capacitor2 = Item.itemList.Find(i => i.HasTag("capacitor1")).GetComponent<PowerContainer>();
|
||||||
|
CoroutineManager.StartCoroutine(KeepEnemyAway(moloch, new PowerContainer[] { capacitor1, capacitor2 }));
|
||||||
|
|
||||||
|
|
||||||
|
infoBox = CreateInfoFrame("The hull has been breached! Close all the doors to the command room to stop the water from flooding the entire sub!");
|
||||||
|
|
||||||
|
|
||||||
|
Door commandDoor1 = Item.itemList.Find(i => i.HasTag("commanddoor1")).GetComponent<Door>();
|
||||||
|
Door commandDoor2 = Item.itemList.Find(i => i.HasTag("commanddoor2")).GetComponent<Door>();
|
||||||
|
Door commandDoor3 = Item.itemList.Find(i => i.HasTag("commanddoor3")).GetComponent<Door>();
|
||||||
|
|
||||||
|
while (commandDoor1.IsOpen && (commandDoor2.IsOpen || commandDoor3.IsOpen))
|
||||||
|
{
|
||||||
|
yield return Status.Running;
|
||||||
|
}
|
||||||
|
|
||||||
|
infoBox = CreateInfoFrame("Great! You should find yourself an diving mask or a diving suit, in case the creature causes more damage. "+
|
||||||
|
"There are some in the room next to the airlock.");
|
||||||
|
|
||||||
|
while (!HasItem("Diving Mask") && !HasItem("Diving Suit"))
|
||||||
|
{
|
||||||
|
yield return Status.Running;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasItem("Diving Mask"))
|
||||||
|
{
|
||||||
|
infoBox = CreateInfoFrame("The diving mask will let you breathe underwater, but it won't protect from the water pressure outside the sub. "+
|
||||||
|
"It should be fine for the situation at hand, but you still need to find an oxygen tank and drag it into the same slot as the mask." +
|
||||||
|
"You should grab one or two.");
|
||||||
|
}
|
||||||
|
else if (HasItem("Diving Suit"))
|
||||||
|
{
|
||||||
|
infoBox = CreateInfoFrame("In addition to letting you breathe underwater, the suit will protect you from the water pressure outside the sub " +
|
||||||
|
"(unlike the diving mask). However, you still need to drag an oxygen tank into the same slot as the suit to supply oxygen. "+
|
||||||
|
"You should grab one or two.");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!HasItem("Oxygen Tank"))
|
||||||
|
{
|
||||||
|
yield return Status.Running;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield return new WaitForSeconds(5.0f);
|
||||||
|
|
||||||
|
infoBox = CreateInfoFrame("Now it's time to stop the creature attacking the submarine. Head to the railgun room at the upper right corner of the sub.");
|
||||||
|
|
||||||
|
var railGun = Item.itemList.Find(i => i.GetComponent<Turret>()!=null);
|
||||||
|
|
||||||
|
while (Vector2.Distance(Character.Controlled.Position, railGun.Position)>500)
|
||||||
|
{
|
||||||
|
yield return new WaitForSeconds(1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
infoBox = CreateInfoFrame("The railgun requires a large power surge to fire. The reactor can't provide a surge large enough, so we need to use the "
|
||||||
|
+" supercapacitors in the railgun room. The capacitors need to be charged first; select them and crank up the recharge rate.");
|
||||||
|
|
||||||
|
while (capacitor1.RechargeSpeed<0.5f && capacitor2.RechargeSpeed<0.5f)
|
||||||
|
{
|
||||||
|
yield return new WaitForSeconds(1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
infoBox = CreateInfoFrame("The capacitors consume large amounts of power when they're being charged at a high rate. "+
|
||||||
|
"Be cautious to overload the electrical grid or the reactor. They also take some time to recharge, so now is a good "+
|
||||||
|
"time to head to the room below to load some shells into the railgun.");
|
||||||
|
|
||||||
|
|
||||||
|
var loader = Item.itemList.Find(i => i.Name == "Railgun Loader").GetComponent<ItemContainer>();
|
||||||
|
|
||||||
|
while (Math.Abs(Character.Controlled.Position.Y - loader.Item.Position.Y)>50)
|
||||||
|
{
|
||||||
|
yield return Status.Running;
|
||||||
|
}
|
||||||
|
|
||||||
|
infoBox = CreateInfoFrame("Grab one of the shells. You can load it by selecting the railgun loader and dragging the shell to. "
|
||||||
|
+"one of the free slots.");
|
||||||
|
|
||||||
|
while (loader.Item.ContainedItems.FirstOrDefault(i => i != null) != null)
|
||||||
|
{
|
||||||
|
capacitor1.Charge += 1.0f;
|
||||||
|
capacitor2.Charge += 1.0f;
|
||||||
|
yield return Status.Running;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
yield return Status.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HasItem(string itemName)
|
||||||
|
{
|
||||||
|
if (Character.Controlled == null) return false;
|
||||||
|
return Character.Controlled.Inventory.items.FirstOrDefault(i => i != null && i.Name == itemName)!=null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// keeps the enemy away from the sub until the capacitors are loaded
|
||||||
|
/// </summary>
|
||||||
|
private IEnumerable<object> KeepEnemyAway(Character enemy, PowerContainer[] capacitors)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Vector2 targetPos = Character.Controlled.Position + new Vector2(0.0f, 3000.0f);
|
||||||
|
|
||||||
|
Vector2 steering = targetPos - enemy.Position;
|
||||||
|
if (steering != Vector2.Zero) steering = Vector2.Normalize(steering);
|
||||||
|
|
||||||
|
enemy.AIController.Steering = steering*2.0f;
|
||||||
|
|
||||||
|
yield return Status.Running;
|
||||||
|
} while (capacitors.FirstOrDefault(c => c.Charge > 0.4f) == null);
|
||||||
|
|
||||||
yield return Status.Success;
|
yield return Status.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
if (Game1.Server!=null)
|
if (Game1.Server!=null)
|
||||||
{
|
{
|
||||||
Game1.Server.EndGame(endMessage);
|
CoroutineManager.StartCoroutine(Game1.Server.EndGame(endMessage));
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (Game1.Client==null)
|
else if (Game1.Client==null)
|
||||||
|
|||||||
@@ -139,12 +139,13 @@ namespace Subsurface
|
|||||||
if (items[i] != null)
|
if (items[i] != null)
|
||||||
{
|
{
|
||||||
bool combined = false;
|
bool combined = false;
|
||||||
if (item.Combine(items[i]))
|
//if (item.Combine(items[i]))
|
||||||
{
|
//{
|
||||||
//PutItem(item, i, false, false);
|
// //PutItem(item, i, false, false);
|
||||||
combined = true;
|
// combined = true;
|
||||||
}
|
//}
|
||||||
else if (items[i].Combine(item))
|
//else
|
||||||
|
if (items[i].Combine(item))
|
||||||
{
|
{
|
||||||
//PutItem(items[i], i, false, false);
|
//PutItem(items[i], i, false, false);
|
||||||
combined = true;
|
combined = true;
|
||||||
|
|||||||
@@ -119,7 +119,6 @@ namespace Subsurface.Items.Components
|
|||||||
(int)doorSprite.size.X,
|
(int)doorSprite.size.X,
|
||||||
(int)doorSprite.size.Y);
|
(int)doorSprite.size.Y);
|
||||||
|
|
||||||
|
|
||||||
body = new PhysicsBody(BodyFactory.CreateRectangle(Game1.World,
|
body = new PhysicsBody(BodyFactory.CreateRectangle(Game1.World,
|
||||||
ConvertUnits.ToSimUnits(Math.Max(doorRect.Width, 1)),
|
ConvertUnits.ToSimUnits(Math.Max(doorRect.Width, 1)),
|
||||||
ConvertUnits.ToSimUnits(Math.Max(doorRect.Height, 1)),
|
ConvertUnits.ToSimUnits(Math.Max(doorRect.Height, 1)),
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ namespace Subsurface.Items.Components
|
|||||||
Msg = "";
|
Msg = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attachedByDefault) Use(1.0f);
|
if (attachedByDefault || Screen.Selected == Game1.EditMapScreen) Use(1.0f);
|
||||||
|
|
||||||
|
|
||||||
//holdAngle = ToolBox.GetAttributeFloat(element, "holdangle", 0.0f);
|
//holdAngle = ToolBox.GetAttributeFloat(element, "holdangle", 0.0f);
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ namespace Subsurface.Items.Components
|
|||||||
public override bool Use(float deltaTime, Character character = null)
|
public override bool Use(float deltaTime, Character character = null)
|
||||||
{
|
{
|
||||||
if (character == null) return false;
|
if (character == null) return false;
|
||||||
if (!character.SecondaryKeyDown.State || reload > 0.0f) return false;
|
if (!character.GetInputState(InputType.SecondaryHeld) || reload > 0.0f) return false;
|
||||||
isActive = true;
|
isActive = true;
|
||||||
reload = 1.0f;
|
reload = 1.0f;
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ namespace Subsurface.Items.Components
|
|||||||
public override bool Use(float deltaTime, Character character = null)
|
public override bool Use(float deltaTime, Character character = null)
|
||||||
{
|
{
|
||||||
if (character == null) return false;
|
if (character == null) return false;
|
||||||
if (!character.SecondaryKeyDown.State) return false;
|
if (!character.GetInputState(InputType.SecondaryHeld)) return false;
|
||||||
|
|
||||||
if (DoesUseFail(character)) return false;
|
if (DoesUseFail(character)) return false;
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ namespace Subsurface.Items.Components
|
|||||||
}
|
}
|
||||||
else if ((targetLimb = (targetBody.UserData as Limb)) != null)
|
else if ((targetLimb = (targetBody.UserData as Limb)) != null)
|
||||||
{
|
{
|
||||||
if (character.SecondaryKeyDown.State)
|
if (character.GetInputState(InputType.SecondaryHeld))
|
||||||
{
|
{
|
||||||
targetLimb.character.Health += limbFixAmount;
|
targetLimb.character.Health += limbFixAmount;
|
||||||
//isActive = true;
|
//isActive = true;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace Subsurface.Items.Components
|
|||||||
public override bool Use(float deltaTime, Character character = null)
|
public override bool Use(float deltaTime, Character character = null)
|
||||||
{
|
{
|
||||||
if (character == null) return false;
|
if (character == null) return false;
|
||||||
if (!character.SecondaryKeyDown.State || throwing) return false;
|
if (!character.GetInputState(InputType.SecondaryHeld) || throwing) return false;
|
||||||
|
|
||||||
throwing = true;
|
throwing = true;
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ namespace Subsurface.Items.Components
|
|||||||
if (!item.body.Enabled) return;
|
if (!item.body.Enabled) return;
|
||||||
if (!picker.HasSelectedItem(item)) isActive = false;
|
if (!picker.HasSelectedItem(item)) isActive = false;
|
||||||
|
|
||||||
if (!picker.SecondaryKeyDown.State && !throwing) throwPos = 0.0f;
|
if (!picker.GetInputState(InputType.SecondaryHeld) && !throwing) throwPos = 0.0f;
|
||||||
|
|
||||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, picker);
|
ApplyStatusEffects(ActionType.OnActive, deltaTime, picker);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
namespace Subsurface.Items.Components
|
||||||
|
{
|
||||||
|
class ItemLabel : ItemComponent
|
||||||
|
{
|
||||||
|
private GUITextBlock textBlock;
|
||||||
|
|
||||||
|
[HasDefaultValue("", true), Editable(100)]
|
||||||
|
public string Text
|
||||||
|
{
|
||||||
|
get { return textBlock.Text; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == TextBlock.Text || item.Rect.Width < 5) return;
|
||||||
|
TextBlock.Text = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color textColor;
|
||||||
|
[Editable, HasDefaultValue("0.0,0.0,0.0,1.0", true)]
|
||||||
|
public string TextColor
|
||||||
|
{
|
||||||
|
get { return ToolBox.Vector4ToString(textColor.ToVector4()); }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
textColor = new Color(ToolBox.ParseToVector4(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private GUITextBlock TextBlock
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (textBlock==null)
|
||||||
|
{
|
||||||
|
textBlock = new GUITextBlock(new Rectangle(item.Rect.X,-item.Rect.Y,item.Rect.Width, item.Rect.Height), "",
|
||||||
|
Color.Transparent, Color.Black,
|
||||||
|
Alignment.TopLeft, Alignment.Center,
|
||||||
|
null, null, true);
|
||||||
|
textBlock.Font = GUI.SmallFont;
|
||||||
|
textBlock.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
|
||||||
|
}
|
||||||
|
return textBlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Move(Vector2 amount)
|
||||||
|
{
|
||||||
|
textBlock.Rect = new Rectangle(item.Rect.X, -item.Rect.Y, item.Rect.Width, item.Rect.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemLabel(Item item, XElement element)
|
||||||
|
: base(item, element)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Draw(SpriteBatch spriteBatch, bool editing = false)
|
||||||
|
{
|
||||||
|
base.Draw(spriteBatch, editing);
|
||||||
|
|
||||||
|
textBlock.Draw(spriteBatch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -92,8 +92,11 @@ namespace Subsurface.Items.Components
|
|||||||
newText = message.ReadString();
|
newText = message.ReadString();
|
||||||
}
|
}
|
||||||
|
|
||||||
catch
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
DebugConsole.ThrowError("invalid network message", e);
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,9 @@ namespace Subsurface.Items.Components
|
|||||||
{
|
{
|
||||||
this.cam = cam;
|
this.cam = cam;
|
||||||
|
|
||||||
if (character == null || character.SelectedConstruction != item)
|
if (character == null
|
||||||
|
|| character.SelectedConstruction != item
|
||||||
|
|| Vector2.Distance(character.SimPosition, item.SimPosition) > item.PickDistance * 1.5f)
|
||||||
{
|
{
|
||||||
if (character != null)
|
if (character != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,8 +22,9 @@ namespace Subsurface.Items.Components
|
|||||||
get { return flowPercentage; }
|
get { return flowPercentage; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (float.IsNaN(flowPercentage)) return;
|
if (!MathUtils.IsValid(flowPercentage)) return;
|
||||||
flowPercentage = MathHelper.Clamp(value,-100.0f,100.0f);
|
flowPercentage = MathHelper.Clamp(value,-100.0f,100.0f);
|
||||||
|
flowPercentage = MathUtils.Round(flowPercentage, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,14 +118,14 @@ namespace Subsurface.Items.Components
|
|||||||
|
|
||||||
spriteBatch.DrawString(GUI.Font, "Flow percentage: " + (int)flowPercentage + " %", new Vector2(x + 20, y + 80), Color.White);
|
spriteBatch.DrawString(GUI.Font, "Flow percentage: " + (int)flowPercentage + " %", new Vector2(x + 20, y + 80), Color.White);
|
||||||
|
|
||||||
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 200, y + 70, 40, 40), "+", true))
|
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 200, y + 70, 40, 40), "+", false))
|
||||||
{
|
{
|
||||||
FlowPercentage += 1.0f;
|
FlowPercentage += 10.0f;
|
||||||
item.NewComponentEvent(this, true);
|
item.NewComponentEvent(this, true);
|
||||||
}
|
}
|
||||||
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 250, y + 70, 40, 40), "-", true))
|
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 250, y + 70, 40, 40), "-", false))
|
||||||
{
|
{
|
||||||
FlowPercentage -= 1.0f;
|
FlowPercentage -= 10.0f;
|
||||||
item.NewComponentEvent(this, true);
|
item.NewComponentEvent(this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +167,7 @@ namespace Subsurface.Items.Components
|
|||||||
|
|
||||||
public override void FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetOutgoingMessage message)
|
public override void FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetOutgoingMessage message)
|
||||||
{
|
{
|
||||||
message.Write(flowPercentage);
|
message.Write(Convert.ToByte(flowPercentage+100));
|
||||||
message.Write(isActive);
|
message.Write(isActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,11 +178,17 @@ namespace Subsurface.Items.Components
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
newFlow = message.ReadFloat();
|
newFlow = (float)(message.ReadByte()-100);
|
||||||
newActive = message.ReadBoolean();
|
newActive = message.ReadBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
catch { return; }
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
DebugConsole.ThrowError("invalid network message", e);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
FlowPercentage = newFlow;
|
FlowPercentage = newFlow;
|
||||||
isActive = newActive;
|
isActive = newActive;
|
||||||
|
|||||||
@@ -68,19 +68,31 @@ namespace Subsurface.Items.Components
|
|||||||
public float FissionRate
|
public float FissionRate
|
||||||
{
|
{
|
||||||
get { return fissionRate; }
|
get { return fissionRate; }
|
||||||
set { fissionRate = MathHelper.Clamp(value, 0.0f, 100.0f); }
|
set
|
||||||
|
{
|
||||||
|
if (!MathUtils.IsValid(value)) return;
|
||||||
|
fissionRate = MathHelper.Clamp(value, 0.0f, 100.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float CoolingRate
|
public float CoolingRate
|
||||||
{
|
{
|
||||||
get { return coolingRate; }
|
get { return coolingRate; }
|
||||||
set { coolingRate = MathHelper.Clamp(value, 0.0f, 100.0f); }
|
set
|
||||||
|
{
|
||||||
|
if (!MathUtils.IsValid(value)) return;
|
||||||
|
coolingRate = MathHelper.Clamp(value, 0.0f, 100.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float Temperature
|
public float Temperature
|
||||||
{
|
{
|
||||||
get { return temperature; }
|
get { return temperature; }
|
||||||
set { temperature = MathHelper.Clamp(value, 0.0f, 10000.0f); }
|
set
|
||||||
|
{
|
||||||
|
if (!MathUtils.IsValid(value)) return;
|
||||||
|
temperature = MathHelper.Clamp(value, 0.0f, 10000.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsRunning()
|
public bool IsRunning()
|
||||||
@@ -100,6 +112,7 @@ namespace Subsurface.Items.Components
|
|||||||
public float ShutDownTemp
|
public float ShutDownTemp
|
||||||
{
|
{
|
||||||
get { return shutDownTemp; }
|
get { return shutDownTemp; }
|
||||||
|
private set { shutDownTemp = MathHelper.Clamp(value, 0.0f, 10000.0f); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Reactor(Item item, XElement element)
|
public Reactor(Item item, XElement element)
|
||||||
@@ -127,7 +140,7 @@ namespace Subsurface.Items.Components
|
|||||||
float heat = 100 * fissionRate * (AvailableFuel/2000.0f);
|
float heat = 100 * fissionRate * (AvailableFuel/2000.0f);
|
||||||
float heatDissipation = 50 * coolingRate + ExtraCooling;
|
float heatDissipation = 50 * coolingRate + ExtraCooling;
|
||||||
|
|
||||||
float deltaTemp = (((heat - heatDissipation) * 5) - temperature) / 1000.0f;
|
float deltaTemp = (((heat - heatDissipation) * 5) - temperature) / 10000.0f;
|
||||||
Temperature = temperature + deltaTemp;
|
Temperature = temperature + deltaTemp;
|
||||||
|
|
||||||
if (temperature > meltDownTemp)
|
if (temperature > meltDownTemp)
|
||||||
@@ -142,8 +155,7 @@ namespace Subsurface.Items.Components
|
|||||||
powerUpTask = new PropertyTask(item, IsRunning, 50.0f, "Power up the reactor");
|
powerUpTask = new PropertyTask(item, IsRunning, 50.0f, "Power up the reactor");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
item.Condition -= temperature * deltaTime * 0.00005f;
|
item.Condition -= temperature * deltaTime * 0.00005f;
|
||||||
|
|
||||||
if (temperature > shutDownTemp)
|
if (temperature > shutDownTemp)
|
||||||
@@ -188,8 +200,7 @@ namespace Subsurface.Items.Components
|
|||||||
|
|
||||||
//fission rate can't be lowered below a certain amount if the core is too hot
|
//fission rate can't be lowered below a certain amount if the core is too hot
|
||||||
FissionRate = Math.Max(fissionRate, heat / 200.0f);
|
FissionRate = Math.Max(fissionRate, heat / 200.0f);
|
||||||
|
|
||||||
|
|
||||||
//the power generated by the reactor is equal to the temperature
|
//the power generated by the reactor is equal to the temperature
|
||||||
currPowerConsumption = -temperature*powerPerTemp;
|
currPowerConsumption = -temperature*powerPerTemp;
|
||||||
|
|
||||||
@@ -203,6 +214,8 @@ namespace Subsurface.Items.Components
|
|||||||
|
|
||||||
ExtraCooling = 0.0f;
|
ExtraCooling = 0.0f;
|
||||||
AvailableFuel = 0.0f;
|
AvailableFuel = 0.0f;
|
||||||
|
|
||||||
|
item.SendSignal(((int)temperature).ToString(), "temperature_out");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateBroken(float deltaTime, Camera cam)
|
public override void UpdateBroken(float deltaTime, Camera cam)
|
||||||
@@ -239,24 +252,15 @@ namespace Subsurface.Items.Components
|
|||||||
|
|
||||||
new RepairTask(item, 60.0f, "Reactor meltdown!");
|
new RepairTask(item, 60.0f, "Reactor meltdown!");
|
||||||
item.Condition = 0.0f;
|
item.Condition = 0.0f;
|
||||||
//fissionRate = 0.0f;
|
|
||||||
//coolingRate = 0.0f;
|
|
||||||
|
|
||||||
//PlaySound(ActionType.OnFailure, item.Position);
|
var containedItems = item.ContainedItems;
|
||||||
//item.ApplyStatusEffects(ActionType.OnFailure, 1.0f, null);
|
if (containedItems == null) return;
|
||||||
|
|
||||||
//new Explosion(item.SimPosition, 6.0f, 500.0f, 600.0f, 10.0f, 2.0f).Explode();
|
|
||||||
|
|
||||||
if (item.ContainedItems!=null)
|
foreach (Item containedItem in item.ContainedItems)
|
||||||
{
|
{
|
||||||
foreach (Item containedItem in item.ContainedItems)
|
if (containedItem == null) continue;
|
||||||
{
|
containedItem.Condition = 0.0f;
|
||||||
if (containedItem == null) continue;
|
|
||||||
containedItem.Condition = 0.0f;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Pick(Character picker)
|
public override bool Pick(Character picker)
|
||||||
@@ -343,12 +347,12 @@ namespace Subsurface.Items.Components
|
|||||||
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 400, y + 180, 40, 40), "+", true))
|
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 400, y + 180, 40, 40), "+", true))
|
||||||
{
|
{
|
||||||
valueChanged = true;
|
valueChanged = true;
|
||||||
shutDownTemp += 100.0f;
|
ShutDownTemp += 100.0f;
|
||||||
}
|
}
|
||||||
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 450, y + 180, 40, 40), "-", true))
|
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 450, y + 180, 40, 40), "-", true))
|
||||||
{
|
{
|
||||||
valueChanged = true;
|
valueChanged = true;
|
||||||
shutDownTemp -= 100.0f;
|
ShutDownTemp -= 100.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valueChanged)
|
if (valueChanged)
|
||||||
@@ -398,14 +402,24 @@ namespace Subsurface.Items.Components
|
|||||||
GUI.DrawLine(spriteBatch, prevPoint, lastPoint, Color.White);
|
GUI.DrawLine(spriteBatch, prevPoint, lastPoint, Color.White);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void ReceiveSignal(string signal, Connection connection, Item sender, float power)
|
||||||
|
{
|
||||||
|
switch (connection.Name)
|
||||||
|
{
|
||||||
|
case "shutdown":
|
||||||
|
shutDownTemp = 0.0f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void FillNetworkData(NetworkEventType type, NetOutgoingMessage message)
|
public override void FillNetworkData(NetworkEventType type, NetOutgoingMessage message)
|
||||||
{
|
{
|
||||||
message.Write(autoTemp);
|
message.Write(autoTemp);
|
||||||
message.Write(temperature);
|
message.WriteRangedSingle(temperature, 0.0f, 10000.0f, 16);
|
||||||
message.Write(shutDownTemp);
|
message.WriteRangedSingle(shutDownTemp, 0.0f, 10000.0f, 16);
|
||||||
|
|
||||||
message.Write(coolingRate);
|
message.WriteRangedSingle(coolingRate, 0.0f, 100.0f, 8);
|
||||||
message.Write(fissionRate);
|
message.WriteRangedSingle(fissionRate, 0.0f, 100.0f, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message)
|
public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message)
|
||||||
@@ -417,18 +431,24 @@ namespace Subsurface.Items.Components
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
newAutoTemp = message.ReadBoolean();
|
newAutoTemp = message.ReadBoolean();
|
||||||
newTemperature = message.ReadFloat();
|
newTemperature = message.ReadRangedSingle(0.0f, 10000.0f, 16);
|
||||||
newShutDownTemp = message.ReadFloat();
|
newShutDownTemp = message.ReadRangedSingle(0.0f, 10000.0f, 16);
|
||||||
|
|
||||||
newCoolingRate = message.ReadFloat();
|
newCoolingRate = message.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||||
newFissionRate = message.ReadFloat();
|
newFissionRate = message.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
catch { return; }
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
DebugConsole.ThrowError("invalid network message", e);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
autoTemp = newAutoTemp;
|
autoTemp = newAutoTemp;
|
||||||
Temperature = newTemperature;
|
Temperature = newTemperature;
|
||||||
shutDownTemp = newShutDownTemp;
|
ShutDownTemp = newShutDownTemp;
|
||||||
|
|
||||||
CoolingRate = newCoolingRate;
|
CoolingRate = newCoolingRate;
|
||||||
FissionRate = newFissionRate;
|
FissionRate = newFissionRate;
|
||||||
|
|||||||
@@ -48,10 +48,7 @@ namespace Subsurface.Items.Components
|
|||||||
get { return targetVelocity;}
|
get { return targetVelocity;}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (float.IsNaN(value.X) || float.IsNaN(value.Y))
|
if (!MathUtils.IsValid(value)) return;
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
targetVelocity.X = MathHelper.Clamp(value.X, -100.0f, 100.0f);
|
targetVelocity.X = MathHelper.Clamp(value.X, -100.0f, 100.0f);
|
||||||
targetVelocity.Y = MathHelper.Clamp(value.Y, -100.0f, 100.0f);
|
targetVelocity.Y = MathHelper.Clamp(value.Y, -100.0f, 100.0f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -173,16 +173,19 @@ namespace Subsurface.Items.Components
|
|||||||
(float)Math.Cos(item.body.Rotation),
|
(float)Math.Cos(item.body.Rotation),
|
||||||
(float)Math.Sin(item.body.Rotation));
|
(float)Math.Sin(item.body.Rotation));
|
||||||
|
|
||||||
if (Vector2.Dot(f1.Body.LinearVelocity, normal)<0 ) return StickToTarget(f2.Body, dir);
|
if (Vector2.Dot(f1.Body.LinearVelocity, normal) < 0.0f) return StickToTarget(f2.Body, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Item contained in item.ContainedItems)
|
|
||||||
|
var containedItems = item.ContainedItems;
|
||||||
|
if (containedItems == null) return true;
|
||||||
|
foreach (Item contained in containedItems)
|
||||||
{
|
{
|
||||||
contained.Condition = 0.0f;
|
if (contained.body != null)
|
||||||
if (contained.body!=null)
|
|
||||||
{
|
{
|
||||||
contained.body.SetTransform(item.SimPosition, contained.body.Rotation);
|
contained.SetTransform(item.SimPosition, contained.body.Rotation);
|
||||||
}
|
}
|
||||||
|
contained.Condition = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -319,14 +319,13 @@ namespace Subsurface.Items.Components
|
|||||||
if (index>-1)
|
if (index>-1)
|
||||||
{
|
{
|
||||||
Wires[index].RemoveConnection(this);
|
Wires[index].RemoveConnection(this);
|
||||||
Wires[index].Item.SetTransform(item.SimPosition, 0.0f);
|
//Wires[index].Item.SetTransform(item.SimPosition, 0.0f);
|
||||||
Wires[index].Item.Drop();
|
//Wires[index].Item.Drop();
|
||||||
Wires[index].Item.body.Enabled = true;
|
//Wires[index].Item.body.Enabled = true;
|
||||||
Wires[index] = null;
|
Wires[index] = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ namespace Subsurface.Items.Components
|
|||||||
|
|
||||||
private string expression;
|
private string expression;
|
||||||
|
|
||||||
|
private string receivedSignal;
|
||||||
|
|
||||||
[InGameEditable, HasDefaultValue("1", true)]
|
[InGameEditable, HasDefaultValue("1", true)]
|
||||||
public string Output
|
public string Output
|
||||||
{
|
{
|
||||||
@@ -26,6 +28,27 @@ namespace Subsurface.Items.Components
|
|||||||
public RegExFindComponent(Item item, XElement element)
|
public RegExFindComponent(Item item, XElement element)
|
||||||
: base(item, element)
|
: base(item, element)
|
||||||
{
|
{
|
||||||
|
isActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(float deltaTime, Camera cam)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(expression)) return;
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Regex regex = new Regex(@expression);
|
||||||
|
Match match = regex.Match(receivedSignal);
|
||||||
|
success = match.Success;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
item.SendSignal("ERROR", "signal_out");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
item.SendSignal(success ? output : "0", "signal_out");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ReceiveSignal(string signal, Connection connection, Item sender, float power = 0.0f)
|
public override void ReceiveSignal(string signal, Connection connection, Item sender, float power = 0.0f)
|
||||||
@@ -33,22 +56,7 @@ namespace Subsurface.Items.Components
|
|||||||
switch (connection.Name)
|
switch (connection.Name)
|
||||||
{
|
{
|
||||||
case "signal_in":
|
case "signal_in":
|
||||||
if (string.IsNullOrWhiteSpace(expression)) return;
|
receivedSignal = signal;
|
||||||
|
|
||||||
bool success = false;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Regex regex = new Regex(@expression);
|
|
||||||
Match match = regex.Match(signal);
|
|
||||||
success = match.Success;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
item.SendSignal("ERROR", "signal_out");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
item.SendSignal(success ? output : "0", "signal_out");
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "set_output":
|
case "set_output":
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Subsurface.Items.Components
|
||||||
|
{
|
||||||
|
class WifiComponent : ItemComponent
|
||||||
|
{
|
||||||
|
|
||||||
|
private static List<WifiComponent> list = new List<WifiComponent>();
|
||||||
|
|
||||||
|
private int channel;
|
||||||
|
|
||||||
|
[InGameEditable, HasDefaultValue(1, true)]
|
||||||
|
public int Channel
|
||||||
|
{
|
||||||
|
get { return channel; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
channel = MathHelper.Clamp(value, 0, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public WifiComponent(Item item, XElement element)
|
||||||
|
: base (item, element)
|
||||||
|
{
|
||||||
|
|
||||||
|
list.Add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ReceiveSignal(string signal, Connection connection, Item sender, float power=0.0f)
|
||||||
|
{
|
||||||
|
//prevent an ininite loop of wificomponents sending messages between each other
|
||||||
|
if (sender.GetComponent<WifiComponent>()!=null) return;
|
||||||
|
|
||||||
|
switch (connection.Name)
|
||||||
|
{
|
||||||
|
case "signal_in":
|
||||||
|
foreach (WifiComponent wifiComp in list)
|
||||||
|
{
|
||||||
|
if (wifiComp == this || wifiComp.channel != channel) continue;
|
||||||
|
wifiComp.item.SendSignal(signal, "signal_out");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Remove()
|
||||||
|
{
|
||||||
|
base.Remove();
|
||||||
|
|
||||||
|
list.Remove(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -106,8 +106,31 @@ namespace Subsurface.Items.Components
|
|||||||
if (reload > 0.0f) return false;
|
if (reload > 0.0f) return false;
|
||||||
|
|
||||||
Projectile projectileComponent = null;
|
Projectile projectileComponent = null;
|
||||||
|
//search for a projectile from linked containers
|
||||||
|
Item projectile = null;
|
||||||
|
foreach (MapEntity e in item.linkedTo)
|
||||||
|
{
|
||||||
|
Item container = e as Item;
|
||||||
|
if (container == null) continue;
|
||||||
|
|
||||||
|
ItemContainer containerComponent = container.GetComponent<ItemContainer>();
|
||||||
|
if (containerComponent == null) continue;
|
||||||
|
|
||||||
|
for (int i = 0; i < containerComponent.inventory.items.Length; i++)
|
||||||
|
{
|
||||||
|
if (containerComponent.inventory.items[i] == null) continue;
|
||||||
|
if ((projectileComponent = containerComponent.inventory.items[i].GetComponent<Projectile>()) != null)
|
||||||
|
{
|
||||||
|
projectile = containerComponent.inventory.items[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (projectileComponent != null) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (projectile == null || projectileComponent == null) return false;
|
||||||
|
|
||||||
//currPowerConsumption = powerConsumption;
|
|
||||||
|
|
||||||
float availablePower = 0.0f;
|
float availablePower = 0.0f;
|
||||||
//List<PowerContainer> batteries = new List<PowerContainer>();
|
//List<PowerContainer> batteries = new List<PowerContainer>();
|
||||||
@@ -132,31 +155,6 @@ namespace Subsurface.Items.Components
|
|||||||
|
|
||||||
if (availablePower < currPowerConsumption) return false;
|
if (availablePower < currPowerConsumption) return false;
|
||||||
|
|
||||||
//search for a projectile from linked containers
|
|
||||||
Item projectile = null;
|
|
||||||
foreach (MapEntity e in item.linkedTo)
|
|
||||||
{
|
|
||||||
Item container = e as Item;
|
|
||||||
if (container == null) continue;
|
|
||||||
|
|
||||||
ItemContainer containerComponent = container.GetComponent<ItemContainer>();
|
|
||||||
if (containerComponent == null) continue;
|
|
||||||
|
|
||||||
for (int i = 0; i < containerComponent.inventory.items.Length; i++)
|
|
||||||
{
|
|
||||||
if (containerComponent.inventory.items[i] == null) continue;
|
|
||||||
if ((projectileComponent = containerComponent.inventory.items[i].GetComponent<Projectile>()) != null)
|
|
||||||
{
|
|
||||||
projectile = containerComponent.inventory.items[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (projectileComponent != null) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (projectile == null || projectileComponent==null) return false;
|
|
||||||
|
|
||||||
projectile.body.ResetDynamics();
|
projectile.body.ResetDynamics();
|
||||||
projectile.body.Enabled = true;
|
projectile.body.Enabled = true;
|
||||||
projectile.SetTransform(ConvertUnits.ToSimUnits(new Vector2(item.Rect.X + barrelPos.X, item.Rect.Y - barrelPos.Y)), -rotation);
|
projectile.SetTransform(ConvertUnits.ToSimUnits(new Vector2(item.Rect.X + barrelPos.X, item.Rect.Y - barrelPos.Y)), -rotation);
|
||||||
|
|||||||
@@ -61,6 +61,11 @@ namespace Subsurface
|
|||||||
get { return prefab.sprite; }
|
get { return prefab.sprite; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float PickDistance
|
||||||
|
{
|
||||||
|
get { return prefab.PickDistance; }
|
||||||
|
}
|
||||||
|
|
||||||
public float Condition
|
public float Condition
|
||||||
{
|
{
|
||||||
get { return condition; }
|
get { return condition; }
|
||||||
@@ -178,7 +183,7 @@ namespace Subsurface
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
ItemContainer c = GetComponent<ItemContainer>();
|
ItemContainer c = GetComponent<ItemContainer>();
|
||||||
return (c == null) ? null : c.inventory.items;
|
return (c == null) ? null : Array.FindAll(c.inventory.items, i=>i!=null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,15 +551,19 @@ namespace Subsurface
|
|||||||
Color color = (isSelected && editing) ? color = Color.Red : spriteColor;
|
Color color = (isSelected && editing) ? color = Color.Red : spriteColor;
|
||||||
if (isHighlighted) color = Color.Orange;
|
if (isHighlighted) color = Color.Orange;
|
||||||
|
|
||||||
if (body==null)
|
if (prefab.sprite!=null)
|
||||||
{
|
{
|
||||||
prefab.sprite.DrawTiled(spriteBatch, new Vector2(rect.X, -rect.Y), new Vector2(rect.Width, rect.Height), color);
|
if (body==null)
|
||||||
}
|
{
|
||||||
else if (body.Enabled)
|
prefab.sprite.DrawTiled(spriteBatch, new Vector2(rect.X, -rect.Y), new Vector2(rect.Width, rect.Height), color);
|
||||||
{
|
}
|
||||||
body.Draw(spriteBatch, prefab.sprite, color);
|
else if (body.Enabled)
|
||||||
|
{
|
||||||
|
body.Draw(spriteBatch, prefab.sprite, color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
foreach (ItemComponent component in components) component.Draw(spriteBatch, editing);
|
foreach (ItemComponent component in components) component.Draw(spriteBatch, editing);
|
||||||
|
|
||||||
if (!editing || (body!=null && !body.Enabled))
|
if (!editing || (body!=null && !body.Enabled))
|
||||||
@@ -665,7 +674,13 @@ namespace Subsurface
|
|||||||
foreach (var objectProperty in editableProperties)
|
foreach (var objectProperty in editableProperties)
|
||||||
{
|
{
|
||||||
new GUITextBlock(new Rectangle(0, y, 100, 20), objectProperty.Name, Color.Transparent, Color.White, Alignment.Left, null, editingHUD);
|
new GUITextBlock(new Rectangle(0, y, 100, 20), objectProperty.Name, Color.Transparent, Color.White, Alignment.Left, null, editingHUD);
|
||||||
GUITextBox propertyBox = new GUITextBox(new Rectangle(100, y, 200, 20), GUI.style, editingHUD);
|
|
||||||
|
int height = 20;
|
||||||
|
var editable = objectProperty.Attributes.OfType<Editable>().FirstOrDefault<Editable>();
|
||||||
|
if (editable != null) height = (int)(Math.Ceiling(editable.MaxLength / 20.0f) * 20.0f);
|
||||||
|
|
||||||
|
GUITextBox propertyBox = new GUITextBox(new Rectangle(100, y, 200, height), GUI.style, editingHUD);
|
||||||
|
if (height>20) propertyBox.Wrap = true;
|
||||||
|
|
||||||
object value = objectProperty.GetValue();
|
object value = objectProperty.GetValue();
|
||||||
if (value != null)
|
if (value != null)
|
||||||
@@ -676,7 +691,7 @@ namespace Subsurface
|
|||||||
propertyBox.UserData = objectProperty;
|
propertyBox.UserData = objectProperty;
|
||||||
propertyBox.OnEnter = EnterProperty;
|
propertyBox.OnEnter = EnterProperty;
|
||||||
propertyBox.OnTextChanged = PropertyChanged;
|
propertyBox.OnTextChanged = PropertyChanged;
|
||||||
y = y + 30;
|
y = y + height+10;
|
||||||
}
|
}
|
||||||
return editingHUD;
|
return editingHUD;
|
||||||
}
|
}
|
||||||
@@ -933,8 +948,8 @@ namespace Subsurface
|
|||||||
if (objectProperty == null) return false;
|
if (objectProperty == null) return false;
|
||||||
|
|
||||||
object prevValue = objectProperty.GetValue();
|
object prevValue = objectProperty.GetValue();
|
||||||
|
|
||||||
textBox.Selected = false;
|
textBox.Deselect();
|
||||||
|
|
||||||
if (objectProperty.TrySetValue(text))
|
if (objectProperty.TrySetValue(text))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ namespace Subsurface
|
|||||||
position = placePosition;
|
position = placePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprite.DrawTiled(spriteBatch, new Vector2(position.X, -position.Y), placeSize, Color.White);
|
if (sprite != null) sprite.DrawTiled(spriteBatch, new Vector2(position.X, -position.Y), placeSize, Color.White);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PlayerInput.GetMouseState.RightButton == ButtonState.Pressed) selected = null;
|
if (PlayerInput.GetMouseState.RightButton == ButtonState.Pressed) selected = null;
|
||||||
|
|||||||
@@ -45,6 +45,11 @@ namespace Subsurface
|
|||||||
get { return Vector2.Zero; }
|
get { return Vector2.Zero; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AITarget AiTarget
|
||||||
|
{
|
||||||
|
get { return aiTarget; }
|
||||||
|
}
|
||||||
|
|
||||||
public Entity()
|
public Entity()
|
||||||
{
|
{
|
||||||
//give an unique ID
|
//give an unique ID
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ namespace Subsurface
|
|||||||
public int GetWaveIndex(Vector2 position)
|
public int GetWaveIndex(Vector2 position)
|
||||||
{
|
{
|
||||||
int index = (int)(position.X - rect.X) / WaveWidth;
|
int index = (int)(position.X - rect.X) / WaveWidth;
|
||||||
index = MathHelper.Clamp(index, 0, waveY.Length-1);
|
index = (int)MathHelper.Clamp(index, 0, waveY.Length-1);
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -245,7 +245,10 @@ namespace Subsurface.Lights
|
|||||||
* Matrix.CreateOrthographic(Game1.GraphicsWidth, Game1.GraphicsHeight, -1, 1) * 0.5f;
|
* Matrix.CreateOrthographic(Game1.GraphicsWidth, Game1.GraphicsHeight, -1, 1) * 0.5f;
|
||||||
shadowEffect.CurrentTechnique.Passes[0].Apply();
|
shadowEffect.CurrentTechnique.Passes[0].Apply();
|
||||||
|
|
||||||
graphicsDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleList, penumbraVertices, 0, 2, VertexPositionTexture.VertexDeclaration);
|
#if WINDOWS
|
||||||
|
graphicsDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleList, penumbraVertices, 0, 2, VertexPositionTexture.VertexDeclaration);
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ namespace Subsurface
|
|||||||
private string name;
|
private string name;
|
||||||
|
|
||||||
|
|
||||||
private double lastNetworkUpdate;
|
private float lastNetworkUpdate;
|
||||||
|
|
||||||
|
|
||||||
//properties ----------------------------------------------------
|
//properties ----------------------------------------------------
|
||||||
@@ -505,7 +505,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
private void Translate(Vector2 amount)
|
private void Translate(Vector2 amount)
|
||||||
{
|
{
|
||||||
if (amount == Vector2.Zero) return;
|
if (amount == Vector2.Zero || !amount.IsValid()) return;
|
||||||
|
|
||||||
Level.Loaded.Move(-amount);
|
Level.Loaded.Move(-amount);
|
||||||
}
|
}
|
||||||
@@ -516,11 +516,6 @@ namespace Subsurface
|
|||||||
speed += force/mass;
|
speed += force/mass;
|
||||||
}
|
}
|
||||||
|
|
||||||
//public void Move(Vector2 amount)
|
|
||||||
//{
|
|
||||||
// speed = Vector2.Lerp(speed, amount, 0.05f);
|
|
||||||
//}
|
|
||||||
|
|
||||||
VoronoiCell collidingCell;
|
VoronoiCell collidingCell;
|
||||||
public bool OnCollision(Fixture f1, Fixture f2, Contact contact)
|
public bool OnCollision(Fixture f1, Fixture f2, Contact contact)
|
||||||
{
|
{
|
||||||
@@ -569,7 +564,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
public override void FillNetworkData(Networking.NetworkEventType type, NetOutgoingMessage message, object data)
|
public override void FillNetworkData(Networking.NetworkEventType type, NetOutgoingMessage message, object data)
|
||||||
{
|
{
|
||||||
message.Write(NetTime.Now);
|
message.Write((float)NetTime.Now);
|
||||||
message.Write(Position.X);
|
message.Write(Position.X);
|
||||||
message.Write(Position.Y);
|
message.Write(Position.Y);
|
||||||
|
|
||||||
@@ -580,11 +575,11 @@ namespace Subsurface
|
|||||||
|
|
||||||
public override void ReadNetworkData(Networking.NetworkEventType type, NetIncomingMessage message)
|
public override void ReadNetworkData(Networking.NetworkEventType type, NetIncomingMessage message)
|
||||||
{
|
{
|
||||||
double sendingTime;
|
float sendingTime;
|
||||||
Vector2 newTargetPosition, newSpeed;
|
Vector2 newTargetPosition, newSpeed;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
sendingTime = message.ReadDouble();
|
sendingTime = message.ReadFloat();
|
||||||
|
|
||||||
if (sendingTime <= lastNetworkUpdate) return;
|
if (sendingTime <= lastNetworkUpdate) return;
|
||||||
|
|
||||||
@@ -592,11 +587,16 @@ namespace Subsurface
|
|||||||
newSpeed = new Vector2(message.ReadFloat(), message.ReadFloat());
|
newSpeed = new Vector2(message.ReadFloat(), message.ReadFloat());
|
||||||
}
|
}
|
||||||
|
|
||||||
catch
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
DebugConsole.ThrowError("invalid network message", e);
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!newSpeed.IsValid() || !newTargetPosition.IsValid()) return;
|
||||||
|
|
||||||
//newTargetPosition = newTargetPosition + newSpeed * (float)(NetTime.Now - sendingTime);
|
//newTargetPosition = newTargetPosition + newSpeed * (float)(NetTime.Now - sendingTime);
|
||||||
|
|
||||||
targetPosition = newTargetPosition;
|
targetPosition = newTargetPosition;
|
||||||
|
|||||||
@@ -109,7 +109,12 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
pass.Apply();
|
pass.Apply();
|
||||||
|
|
||||||
graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, verts, 0, verts.Length / 3, WaterVertex.VertexDeclaration);
|
#if WINDOWS
|
||||||
|
graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, verts, 0, verts.Length / 3, WaterVertex.VertexDeclaration);
|
||||||
|
#endif
|
||||||
|
#if LINUX
|
||||||
|
//graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, verts, 0, verts.Length / 3, WaterVertex.VertexDeclaration, );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +135,9 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
pass.Apply();
|
pass.Apply();
|
||||||
|
|
||||||
graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length / 3, WaterVertex.VertexDeclaration);
|
#if WINDOWS
|
||||||
|
graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length / 3, WaterVertex.VertexDeclaration);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,9 +50,8 @@ namespace Subsurface.Networking
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConnectToServer(string hostIP)
|
public void ConnectToServer(string hostIP, string password = "")
|
||||||
{
|
{
|
||||||
|
|
||||||
string[] address = hostIP.Split(':');
|
string[] address = hostIP.Split(':');
|
||||||
if (address.Length==1)
|
if (address.Length==1)
|
||||||
{
|
{
|
||||||
@@ -65,7 +64,7 @@ namespace Subsurface.Networking
|
|||||||
|
|
||||||
if (!int.TryParse(address[1], out Port))
|
if (!int.TryParse(address[1], out Port))
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Invalid port: address[1]!");
|
DebugConsole.ThrowError("Invalid port: "+address[1]+"!");
|
||||||
Port = DefaultPort;
|
Port = DefaultPort;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,18 +72,24 @@ namespace Subsurface.Networking
|
|||||||
myCharacter = Character.Controlled;
|
myCharacter = Character.Controlled;
|
||||||
|
|
||||||
// Create new instance of configs. Parameter is "application Id". It has to be same on client and server.
|
// Create new instance of configs. Parameter is "application Id". It has to be same on client and server.
|
||||||
NetPeerConfiguration Config = new NetPeerConfiguration("subsurface");
|
NetPeerConfiguration config = new NetPeerConfiguration("subsurface");
|
||||||
|
|
||||||
//Config.SimulatedLoss = 0.2f;
|
#if DEBUG
|
||||||
//Config.SimulatedMinimumLatency = 0.25f;
|
config.SimulatedLoss = 0.2f;
|
||||||
|
config.SimulatedMinimumLatency = 0.3f;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
config.DisableMessageType(NetIncomingMessageType.DebugMessage | NetIncomingMessageType.WarningMessage | NetIncomingMessageType.Receipt
|
||||||
|
| NetIncomingMessageType.ErrorMessage | NetIncomingMessageType.Error);
|
||||||
|
|
||||||
// Create new client, with previously created configs
|
// Create new client, with previously created configs
|
||||||
client = new NetClient(Config);
|
client = new NetClient(config);
|
||||||
|
|
||||||
NetOutgoingMessage outmsg = client.CreateMessage();
|
NetOutgoingMessage outmsg = client.CreateMessage();
|
||||||
client.Start();
|
client.Start();
|
||||||
|
|
||||||
outmsg.Write((byte)PacketTypes.Login);
|
outmsg.Write((byte)PacketTypes.Login);
|
||||||
|
outmsg.Write(password);
|
||||||
outmsg.Write(Game1.Version.ToString());
|
outmsg.Write(Game1.Version.ToString());
|
||||||
outmsg.Write(Game1.SelectedPackage.Name);
|
outmsg.Write(Game1.SelectedPackage.Name);
|
||||||
outmsg.Write(Game1.SelectedPackage.MD5hash.Hash);
|
outmsg.Write(Game1.SelectedPackage.MD5hash.Hash);
|
||||||
@@ -111,8 +116,11 @@ namespace Subsurface.Networking
|
|||||||
//update.Elapsed += new System.Timers.ElapsedEventHandler(Update);
|
//update.Elapsed += new System.Timers.ElapsedEventHandler(Update);
|
||||||
|
|
||||||
// Funtion that waits for connection approval info from server
|
// Funtion that waits for connection approval info from server
|
||||||
|
if (reconnectBox==null)
|
||||||
|
{
|
||||||
|
reconnectBox = new GUIMessageBox("CONNECTING", "Connecting to " + serverIP, new string[0]);
|
||||||
|
}
|
||||||
|
|
||||||
reconnectBox = new GUIMessageBox("CONNECTING", "Connecting to " + serverIP, new string[0]);
|
|
||||||
CoroutineManager.StartCoroutine(WaitForStartingInfo());
|
CoroutineManager.StartCoroutine(WaitForStartingInfo());
|
||||||
|
|
||||||
// Start the timer
|
// Start the timer
|
||||||
@@ -141,7 +149,7 @@ namespace Subsurface.Networking
|
|||||||
// When this is set to true, we are approved and ready to go
|
// When this is set to true, we are approved and ready to go
|
||||||
bool CanStart = false;
|
bool CanStart = false;
|
||||||
|
|
||||||
DateTime timeOut = DateTime.Now + new TimeSpan(0,0,5);
|
DateTime timeOut = DateTime.Now + new TimeSpan(0,0,15);
|
||||||
|
|
||||||
// Loop untill we are approved
|
// Loop untill we are approved
|
||||||
while (!CanStart)
|
while (!CanStart)
|
||||||
@@ -239,14 +247,19 @@ namespace Subsurface.Networking
|
|||||||
|
|
||||||
if (!connected || updateTimer > DateTime.Now) return;
|
if (!connected || updateTimer > DateTime.Now) return;
|
||||||
|
|
||||||
if (client.ConnectionStatus == NetConnectionStatus.Disconnected && reconnectBox==null)
|
if (client.ConnectionStatus == NetConnectionStatus.Disconnected)
|
||||||
{
|
{
|
||||||
reconnectBox = new GUIMessageBox("CONNECTION LOST", "You have been disconnected from the server. Reconnecting...", new string[0]);
|
if (reconnectBox==null)
|
||||||
connected = false;
|
{
|
||||||
ConnectToServer(serverIP);
|
reconnectBox = new GUIMessageBox("CONNECTION LOST", "You have been disconnected from the server. Reconnecting...", new string[0]);
|
||||||
|
connected = false;
|
||||||
|
ConnectToServer(serverIP);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (reconnectBox!=null)
|
|
||||||
|
if (reconnectBox!=null)
|
||||||
{
|
{
|
||||||
reconnectBox.Close(null,null);
|
reconnectBox.Close(null,null);
|
||||||
reconnectBox = null;
|
reconnectBox = null;
|
||||||
@@ -259,9 +272,20 @@ namespace Subsurface.Networking
|
|||||||
Character.Controlled = null;
|
Character.Controlled = null;
|
||||||
Game1.GameScreen.Cam.TargetPos = Vector2.Zero;
|
Game1.GameScreen.Cam.TargetPos = Vector2.Zero;
|
||||||
}
|
}
|
||||||
else
|
else if (gameStarted)
|
||||||
{
|
{
|
||||||
if (gameStarted) new NetworkEvent(myCharacter.ID, true);
|
Vector2 charMovement = myCharacter.AnimController.TargetMovement;
|
||||||
|
if ((charMovement == Vector2.Zero || charMovement.Length() < 0.001f) &&
|
||||||
|
!myCharacter.GetInputState(InputType.ActionHeld) &&
|
||||||
|
!myCharacter.GetInputState(InputType.SecondaryHeld))
|
||||||
|
{
|
||||||
|
new NetworkEvent(NetworkEventType.NotMoving, myCharacter.ID, true);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new NetworkEvent(myCharacter.ID, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,7 +378,7 @@ namespace Subsurface.Networking
|
|||||||
break;
|
break;
|
||||||
case (byte)PacketTypes.EndGame:
|
case (byte)PacketTypes.EndGame:
|
||||||
string endMessage = inc.ReadString();
|
string endMessage = inc.ReadString();
|
||||||
EndGame(endMessage);
|
CoroutineManager.StartCoroutine(EndGame(endMessage));
|
||||||
break;
|
break;
|
||||||
case (byte)PacketTypes.PlayerJoined:
|
case (byte)PacketTypes.PlayerJoined:
|
||||||
|
|
||||||
@@ -406,19 +430,68 @@ namespace Subsurface.Networking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EndGame(string endMessage)
|
public IEnumerable<object> EndGame(string endMessage)
|
||||||
{
|
{
|
||||||
|
gameStarted = false;
|
||||||
|
|
||||||
|
var messageBox = new GUIMessageBox("The round has ended", endMessage);
|
||||||
|
|
||||||
|
Character.Controlled = null;
|
||||||
|
Game1.LightManager.LosEnabled = false;
|
||||||
|
|
||||||
|
float endPreviewLength = 10.0f;
|
||||||
|
|
||||||
|
DateTime endTime = DateTime.Now + new TimeSpan(0,0,0,0,(int)(1000.0f*endPreviewLength));
|
||||||
|
float secondsLeft = endPreviewLength;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
secondsLeft = (float)(endTime - DateTime.Now).TotalSeconds;
|
||||||
|
|
||||||
|
float camAngle = (float)((DateTime.Now - endTime).TotalSeconds / endPreviewLength) * MathHelper.TwoPi;
|
||||||
|
Vector2 offset = (new Vector2(
|
||||||
|
(float)Math.Cos(camAngle) * (Submarine.Borders.Width / 2.0f),
|
||||||
|
(float)Math.Sin(camAngle) * (Submarine.Borders.Height / 2.0f)));
|
||||||
|
|
||||||
|
Game1.GameScreen.Cam.TargetPos = offset * 0.8f;
|
||||||
|
//Game1.GameScreen.Cam.MoveCamera((float)deltaTime);
|
||||||
|
|
||||||
|
messageBox.Text = endMessage + "\nReturning to lobby in " + (int)secondsLeft + " s";
|
||||||
|
yield return Status.Running;
|
||||||
|
} while (secondsLeft > 0.0f);
|
||||||
|
|
||||||
|
messageBox.Text = endMessage;
|
||||||
|
|
||||||
Submarine.Unload();
|
Submarine.Unload();
|
||||||
|
|
||||||
Game1.NetLobbyScreen.Select();
|
Game1.NetLobbyScreen.Select();
|
||||||
|
|
||||||
if (Game1.GameSession!=null) Game1.GameSession.EndShift("");
|
if (Game1.GameSession!=null) Game1.GameSession.EndShift("");
|
||||||
|
|
||||||
new GUIMessageBox("The round has ended", endMessage);
|
|
||||||
|
|
||||||
myCharacter = null;
|
myCharacter = null;
|
||||||
|
|
||||||
gameStarted = false;
|
yield return Status.Success;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
|
||||||
|
{
|
||||||
|
base.Draw(spriteBatch);
|
||||||
|
|
||||||
|
if (!Game1.DebugDraw) return;
|
||||||
|
|
||||||
|
int width = 200, height = 300;
|
||||||
|
int x = Game1.GraphicsWidth - width, y = (int)(Game1.GraphicsHeight * 0.3f);
|
||||||
|
|
||||||
|
GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black * 0.7f, true);
|
||||||
|
spriteBatch.DrawString(GUI.Font, "Network statistics:", new Vector2(x + 10, y + 10), Color.White);
|
||||||
|
|
||||||
|
spriteBatch.DrawString(GUI.SmallFont, "Received bytes: " + client.Statistics.ReceivedBytes, new Vector2(x + 10, y + 45), Color.White);
|
||||||
|
spriteBatch.DrawString(GUI.SmallFont, "Received packets: " + client.Statistics.ReceivedPackets, new Vector2(x + 10, y + 60), Color.White);
|
||||||
|
|
||||||
|
spriteBatch.DrawString(GUI.SmallFont, "Sent bytes: " + client.Statistics.SentBytes, new Vector2(x + 10, y + 75), Color.White);
|
||||||
|
spriteBatch.DrawString(GUI.SmallFont, "Sent packets: " + client.Statistics.SentPackets, new Vector2(x + 10, y + 90), Color.White);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Disconnect()
|
public override void Disconnect()
|
||||||
@@ -514,7 +587,7 @@ namespace Subsurface.Networking
|
|||||||
msg.Write((byte)type);
|
msg.Write((byte)type);
|
||||||
msg.Write(message);
|
msg.Write(message);
|
||||||
|
|
||||||
client.SendMessage(msg, NetDeliveryMethod.Unreliable);
|
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -22,39 +22,54 @@ namespace Subsurface.Networking
|
|||||||
private TimeSpan refreshMasterInterval = new TimeSpan(0, 0, 40);
|
private TimeSpan refreshMasterInterval = new TimeSpan(0, 0, 40);
|
||||||
private DateTime refreshMasterTimer;
|
private DateTime refreshMasterTimer;
|
||||||
|
|
||||||
|
private bool masterServerResponded;
|
||||||
|
|
||||||
private bool registeredToMaster;
|
private bool registeredToMaster;
|
||||||
|
|
||||||
|
private string password;
|
||||||
|
|
||||||
private Client myClient;
|
private Client myClient;
|
||||||
|
|
||||||
public GameServer(string name, int port)
|
public GameServer(string name, int port, bool isPublic = false, string password = "", bool attemptUPnP = false, int maxPlayers = 10)
|
||||||
{
|
{
|
||||||
var endRoundButton = new GUIButton(new Rectangle(Game1.GraphicsWidth - 290, 20, 150, 25), "End round", Alignment.TopLeft, GUI.style, inGameHUD);
|
var endRoundButton = new GUIButton(new Rectangle(Game1.GraphicsWidth - 290, 20, 150, 25), "End round", Alignment.TopLeft, GUI.style, inGameHUD);
|
||||||
endRoundButton.OnClicked = EndButtonHit;
|
endRoundButton.OnClicked = EndButtonHit;
|
||||||
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
||||||
|
this.password = password;
|
||||||
|
|
||||||
config = new NetPeerConfiguration("subsurface");
|
config = new NetPeerConfiguration("subsurface");
|
||||||
|
|
||||||
//config.SimulatedLoss = 0.2f;
|
#if DEBUG
|
||||||
//config.SimulatedMinimumLatency = 0.25f;
|
config.SimulatedLoss = 0.2f;
|
||||||
|
config.SimulatedMinimumLatency = 0.3f;
|
||||||
|
#endif
|
||||||
|
|
||||||
config.Port = port;
|
config.Port = port;
|
||||||
Port = port;
|
Port = port;
|
||||||
|
|
||||||
config.EnableUPnP = true;
|
if (attemptUPnP)
|
||||||
|
{
|
||||||
|
config.EnableUPnP = true;
|
||||||
|
}
|
||||||
|
|
||||||
config.MaximumConnections = 10;
|
config.MaximumConnections = maxPlayers;
|
||||||
|
|
||||||
|
config.DisableMessageType(NetIncomingMessageType.DebugMessage | NetIncomingMessageType.WarningMessage | NetIncomingMessageType.Receipt
|
||||||
|
| NetIncomingMessageType.ErrorMessage | NetIncomingMessageType.Error);
|
||||||
|
|
||||||
config.EnableMessageType(NetIncomingMessageType.ConnectionApproval);
|
config.EnableMessageType(NetIncomingMessageType.ConnectionApproval);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
server = new NetServer(config);
|
server = new NetServer(config);
|
||||||
server.Start();
|
server.Start();
|
||||||
|
|
||||||
// attempt to forward port
|
|
||||||
server.UPnP.ForwardPort(port, "subsurface");
|
|
||||||
|
|
||||||
|
if (attemptUPnP)
|
||||||
|
{
|
||||||
|
server.UPnP.ForwardPort(port, "subsurface");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@@ -62,7 +77,11 @@ namespace Subsurface.Networking
|
|||||||
DebugConsole.ThrowError("Couldn't start the server", e);
|
DebugConsole.ThrowError("Couldn't start the server", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterToMasterServer();
|
if (isPublic)
|
||||||
|
{
|
||||||
|
RegisterToMasterServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
updateInterval = new TimeSpan(0, 0, 0, 0, 30);
|
updateInterval = new TimeSpan(0, 0, 0, 0, 30);
|
||||||
|
|
||||||
@@ -78,6 +97,7 @@ namespace Subsurface.Networking
|
|||||||
request.AddParameter("servername", name);
|
request.AddParameter("servername", name);
|
||||||
request.AddParameter("serverport", Port);
|
request.AddParameter("serverport", Port);
|
||||||
request.AddParameter("playercount", PlayerCountToByte(connectedClients.Count, config.MaximumConnections));
|
request.AddParameter("playercount", PlayerCountToByte(connectedClients.Count, config.MaximumConnections));
|
||||||
|
request.AddParameter("password", string.IsNullOrWhiteSpace(password) ? 0 : 1);
|
||||||
|
|
||||||
// execute the request
|
// execute the request
|
||||||
RestResponse response = (RestResponse)client.Execute(request);
|
RestResponse response = (RestResponse)client.Execute(request);
|
||||||
@@ -98,7 +118,7 @@ namespace Subsurface.Networking
|
|||||||
refreshMasterTimer = DateTime.Now + refreshMasterInterval;
|
refreshMasterTimer = DateTime.Now + refreshMasterInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RefreshMaster()
|
private IEnumerable<object> RefreshMaster()
|
||||||
{
|
{
|
||||||
var client = new RestClient(NetworkMember.MasterServerUrl);
|
var client = new RestClient(NetworkMember.MasterServerUrl);
|
||||||
|
|
||||||
@@ -112,17 +132,43 @@ namespace Subsurface.Networking
|
|||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
|
||||||
RestResponse response = (RestResponse)client.Execute(request);
|
masterServerResponded = false;
|
||||||
|
var restRequestHandle = client.ExecuteAsync(request, response => MasterServerCallBack(response));
|
||||||
|
|
||||||
sw.Stop();
|
DateTime timeOut = DateTime.Now + new TimeSpan(0, 0, 15);
|
||||||
|
while (!masterServerResponded)
|
||||||
|
{
|
||||||
|
if (DateTime.Now > timeOut)
|
||||||
|
{
|
||||||
|
restRequestHandle.Abort();
|
||||||
|
DebugConsole.ThrowError("Couldn't connect to master server (request timed out)");
|
||||||
|
registeredToMaster = false;
|
||||||
|
}
|
||||||
System.Diagnostics.Debug.WriteLine("took "+sw.ElapsedMilliseconds+" ms");
|
System.Diagnostics.Debug.WriteLine("took "+sw.ElapsedMilliseconds+" ms");
|
||||||
|
|
||||||
|
yield return Status.Running;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield return Status.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MasterServerCallBack(IRestResponse response)
|
||||||
|
{
|
||||||
|
masterServerResponded = true;
|
||||||
|
|
||||||
|
if (response.ErrorException != null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error while connecting to master server", response.ErrorException);
|
||||||
|
registeredToMaster = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (response.StatusCode != System.Net.HttpStatusCode.OK)
|
if (response.StatusCode != System.Net.HttpStatusCode.OK)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Error while connecting to master server (" +response.StatusCode+": "+response.StatusDescription+")");
|
DebugConsole.ThrowError("Error while connecting to master server (" + response.StatusCode + ": " + response.StatusDescription + ")");
|
||||||
|
registeredToMaster = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float deltaTime)
|
public override void Update(float deltaTime)
|
||||||
@@ -159,7 +205,7 @@ namespace Subsurface.Networking
|
|||||||
|
|
||||||
if (registeredToMaster && refreshMasterTimer < DateTime.Now)
|
if (registeredToMaster && refreshMasterTimer < DateTime.Now)
|
||||||
{
|
{
|
||||||
RefreshMaster();
|
CoroutineManager.StartCoroutine(RefreshMaster());
|
||||||
|
|
||||||
refreshMasterTimer = DateTime.Now + refreshMasterInterval;
|
refreshMasterTimer = DateTime.Now + refreshMasterInterval;
|
||||||
}
|
}
|
||||||
@@ -177,9 +223,9 @@ namespace Subsurface.Networking
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isClient)
|
if (!isClient && (c.SimPosition==Vector2.Zero || c.SimPosition.Length() < 300.0f))
|
||||||
{
|
{
|
||||||
c.LargeUpdateTimer = 0;
|
c.LargeUpdateTimer -= 2;
|
||||||
new NetworkEvent(c.ID, false);
|
new NetworkEvent(c.ID, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,9 +250,10 @@ namespace Subsurface.Networking
|
|||||||
Client existingClient = connectedClients.Find(c=> c.Connection == inc.SenderConnection);
|
Client existingClient = connectedClients.Find(c=> c.Connection == inc.SenderConnection);
|
||||||
if (existingClient==null)
|
if (existingClient==null)
|
||||||
{
|
{
|
||||||
string version = "", packageName="", packageHash="", name = "";
|
string userPassword = "", version = "", packageName="", packageHash="", name = "";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
userPassword = inc.ReadString();
|
||||||
version = inc.ReadString();
|
version = inc.ReadString();
|
||||||
packageName = inc.ReadString();
|
packageName = inc.ReadString();
|
||||||
packageHash = inc.ReadString();
|
packageHash = inc.ReadString();
|
||||||
@@ -215,27 +262,38 @@ namespace Subsurface.Networking
|
|||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
inc.SenderConnection.Deny("Connection error - server failed to read your ConnectionApproval message");
|
inc.SenderConnection.Deny("Connection error - server failed to read your ConnectionApproval message");
|
||||||
|
DebugConsole.NewMessage("Connection error - server failed to read the ConnectionApproval message", Color.Red);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version != Game1.Version.ToString())
|
if (userPassword != password)
|
||||||
|
{
|
||||||
|
inc.SenderConnection.Deny("Wrong password!");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (version != Game1.Version.ToString())
|
||||||
{
|
{
|
||||||
inc.SenderConnection.Deny("Subsurface version " + Game1.Version + " required to connect to the server (Your version: " + version + ")");
|
inc.SenderConnection.Deny("Subsurface version " + Game1.Version + " required to connect to the server (Your version: " + version + ")");
|
||||||
|
DebugConsole.NewMessage("Connection error - wrong game version", Color.Red);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (packageName != Game1.SelectedPackage.Name)
|
else if (packageName != Game1.SelectedPackage.Name)
|
||||||
{
|
{
|
||||||
inc.SenderConnection.Deny("Your content package ("+packageName+") doesn't match the server's version (" + Game1.SelectedPackage.Name + ")");
|
inc.SenderConnection.Deny("Your content package ("+packageName+") doesn't match the server's version (" + Game1.SelectedPackage.Name + ")");
|
||||||
|
DebugConsole.NewMessage("Connection error - wrong content package name", Color.Red);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (packageHash != Game1.SelectedPackage.MD5hash.Hash)
|
else if (packageHash != Game1.SelectedPackage.MD5hash.Hash)
|
||||||
{
|
{
|
||||||
inc.SenderConnection.Deny("Your content package (MD5: " + packageHash + ") doesn't match the server's version (MD5: " + Game1.SelectedPackage.MD5hash.Hash + ")");
|
inc.SenderConnection.Deny("Your content package (MD5: " + packageHash + ") doesn't match the server's version (MD5: " + Game1.SelectedPackage.MD5hash.Hash + ")");
|
||||||
|
DebugConsole.NewMessage("Connection error - wrong content package hash", Color.Red);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (connectedClients.Find(c => c.name.ToLower() == name.ToLower())!=null)
|
else if (connectedClients.Find(c => c.name.ToLower() == name.ToLower())!=null)
|
||||||
{
|
{
|
||||||
inc.SenderConnection.Deny("The name ''" + name + "'' is already in use. Please choose another name.");
|
inc.SenderConnection.Deny("The name ''" + name + "'' is already in use. Please choose another name.");
|
||||||
|
DebugConsole.NewMessage("Connection error - name already in use", Color.Red);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,7 +406,9 @@ namespace Subsurface.Networking
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (recipients.Count == 0) break;
|
if (recipients.Count == 0) break;
|
||||||
server.SendMessage(outmsg, recipients, inc.DeliveryMethod, 0);
|
server.SendMessage(outmsg, recipients, inc.DeliveryMethod, 0);
|
||||||
|
|
||||||
|
System.Diagnostics.Debug.WriteLine("Sending networkevent (" + outmsg.LengthBytes+" bytes)");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case (byte)PacketTypes.Chatmessage:
|
case (byte)PacketTypes.Chatmessage:
|
||||||
@@ -396,15 +456,42 @@ namespace Subsurface.Networking
|
|||||||
{
|
{
|
||||||
//System.Diagnostics.Debug.WriteLine("networkevent "+networkEvent.ID);
|
//System.Diagnostics.Debug.WriteLine("networkevent "+networkEvent.ID);
|
||||||
|
|
||||||
|
List<NetConnection> recipients = new List<NetConnection>();
|
||||||
|
|
||||||
|
if (!networkEvent.IsImportant)
|
||||||
|
{
|
||||||
|
Entity e = Entity.FindEntityByID(networkEvent.ID);
|
||||||
|
foreach (Client c in connectedClients)
|
||||||
|
{
|
||||||
|
if (c.character==null) continue;
|
||||||
|
if (Vector2.Distance(e.SimPosition, c.character.SimPosition) > 2000.0f) continue;
|
||||||
|
|
||||||
|
recipients.Add(c.Connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (Client c in connectedClients)
|
||||||
|
{
|
||||||
|
if (c.character == null) continue;
|
||||||
|
|
||||||
|
recipients.Add(c.Connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recipients.Count == 0) return;
|
||||||
|
|
||||||
NetOutgoingMessage message = server.CreateMessage();
|
NetOutgoingMessage message = server.CreateMessage();
|
||||||
message.Write((byte)PacketTypes.NetworkEvent);
|
message.Write((byte)PacketTypes.NetworkEvent);
|
||||||
//if (!networkEvent.IsClient) continue;
|
//if (!networkEvent.IsClient) continue;
|
||||||
|
|
||||||
networkEvent.FillData(message);
|
networkEvent.FillData(message);
|
||||||
|
|
||||||
|
System.Diagnostics.Debug.WriteLine("Sending networkevent " + Entity.FindEntityByID(networkEvent.ID).ToString() + " (" + message.LengthBytes + " bytes)");
|
||||||
|
|
||||||
if (server.ConnectionsCount>0)
|
if (server.ConnectionsCount>0)
|
||||||
{
|
{
|
||||||
server.SendMessage(message, server.Connections,
|
server.SendMessage(message, recipients,
|
||||||
(networkEvent.IsImportant) ? NetDeliveryMethod.Unreliable : NetDeliveryMethod.ReliableUnordered, 0);
|
(networkEvent.IsImportant) ? NetDeliveryMethod.Unreliable : NetDeliveryMethod.ReliableUnordered, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,13 +502,19 @@ namespace Subsurface.Networking
|
|||||||
|
|
||||||
public bool StartGame(GUIButton button, object obj)
|
public bool StartGame(GUIButton button, object obj)
|
||||||
{
|
{
|
||||||
|
Submarine selectedMap = Game1.NetLobbyScreen.SelectedMap as Submarine;
|
||||||
|
|
||||||
|
if (selectedMap == null)
|
||||||
|
{
|
||||||
|
Game1.NetLobbyScreen.SubList.Flash();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int seed = DateTime.Now.Millisecond;
|
int seed = DateTime.Now.Millisecond;
|
||||||
Rand.SetSyncedSeed(seed);
|
Rand.SetSyncedSeed(seed);
|
||||||
|
|
||||||
AssignJobs();
|
AssignJobs();
|
||||||
|
|
||||||
Submarine selectedMap = Game1.NetLobbyScreen.SelectedMap as Submarine;
|
|
||||||
|
|
||||||
//selectedMap.Load();
|
//selectedMap.Load();
|
||||||
|
|
||||||
Game1.GameSession = new GameSession(selectedMap, "", Game1.NetLobbyScreen.SelectedMode);
|
Game1.GameSession = new GameSession(selectedMap, "", Game1.NetLobbyScreen.SelectedMode);
|
||||||
@@ -518,9 +611,10 @@ namespace Subsurface.Networking
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EndGame(string endMessage)
|
public IEnumerable<object> EndGame(string endMessage)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
gameStarted = false;
|
||||||
|
|
||||||
if (connectedClients.Count > 0)
|
if (connectedClients.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -540,13 +634,34 @@ namespace Subsurface.Networking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float endPreviewLength = 10.0f;
|
||||||
|
|
||||||
|
DateTime endTime = DateTime.Now + new TimeSpan(0, 0, 0, 0, (int)(1000.0f * endPreviewLength));
|
||||||
|
float secondsLeft = endPreviewLength;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
secondsLeft = (float)(endTime - DateTime.Now).TotalSeconds;
|
||||||
|
|
||||||
|
float camAngle = (float)((DateTime.Now - endTime).TotalSeconds / endPreviewLength) * MathHelper.TwoPi;
|
||||||
|
Vector2 offset = (new Vector2(
|
||||||
|
(float)Math.Cos(camAngle) * (Submarine.Borders.Width / 2.0f),
|
||||||
|
(float)Math.Sin(camAngle) * (Submarine.Borders.Height / 2.0f)));
|
||||||
|
|
||||||
|
Game1.GameScreen.Cam.TargetPos = offset * 0.8f;
|
||||||
|
//Game1.GameScreen.Cam.MoveCamera((float)deltaTime);
|
||||||
|
|
||||||
|
yield return Status.Running;
|
||||||
|
} while (secondsLeft > 0.0f);
|
||||||
|
|
||||||
Submarine.Unload();
|
Submarine.Unload();
|
||||||
|
|
||||||
gameStarted = false;
|
|
||||||
|
|
||||||
Game1.NetLobbyScreen.Select();
|
Game1.NetLobbyScreen.Select();
|
||||||
|
|
||||||
DebugConsole.ThrowError(endMessage);
|
DebugConsole.ThrowError(endMessage);
|
||||||
|
|
||||||
|
yield return Status.Success;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisconnectClient(NetConnection senderConnection)
|
private void DisconnectClient(NetConnection senderConnection)
|
||||||
@@ -605,7 +720,7 @@ namespace Subsurface.Networking
|
|||||||
|
|
||||||
public void NewTraitor(Client traitor, Client target)
|
public void NewTraitor(Client traitor, Client target)
|
||||||
{
|
{
|
||||||
new GUIMessageBox("New traitor", traitor.name + " is the traitor and the target is " + target+".");
|
new GUIMessageBox("New traitor", traitor.name + " is the traitor and the target is " + target.name+".");
|
||||||
|
|
||||||
NetOutgoingMessage msg = server.CreateMessage();
|
NetOutgoingMessage msg = server.CreateMessage();
|
||||||
msg.Write((byte)PacketTypes.Traitor);
|
msg.Write((byte)PacketTypes.Traitor);
|
||||||
@@ -616,6 +731,36 @@ namespace Subsurface.Networking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
|
||||||
|
{
|
||||||
|
base.Draw(spriteBatch);
|
||||||
|
|
||||||
|
if (!Game1.DebugDraw) return;
|
||||||
|
|
||||||
|
int width = 200, height = 300;
|
||||||
|
int x = Game1.GraphicsWidth - width, y = (int)(Game1.GraphicsHeight*0.3f);
|
||||||
|
|
||||||
|
GUI.DrawRectangle(spriteBatch, new Rectangle(x,y,width,height), Color.Black*0.7f, true);
|
||||||
|
spriteBatch.DrawString(GUI.Font, "Network statistics:", new Vector2(x+10, y+10), Color.White);
|
||||||
|
|
||||||
|
spriteBatch.DrawString(GUI.SmallFont, "Connections: "+server.ConnectionsCount, new Vector2(x + 10, y + 30), Color.White);
|
||||||
|
spriteBatch.DrawString(GUI.SmallFont, "Received bytes: " + server.Statistics.ReceivedBytes, new Vector2(x + 10, y + 45), Color.White);
|
||||||
|
spriteBatch.DrawString(GUI.SmallFont, "Received packets: " + server.Statistics.ReceivedPackets, new Vector2(x + 10, y + 60), Color.White);
|
||||||
|
|
||||||
|
spriteBatch.DrawString(GUI.SmallFont, "Sent bytes: " + server.Statistics.SentBytes, new Vector2(x + 10, y + 75), Color.White);
|
||||||
|
spriteBatch.DrawString(GUI.SmallFont, "Sent packets: " + server.Statistics.SentPackets, new Vector2(x + 10, y + 90), Color.White);
|
||||||
|
|
||||||
|
y += 110;
|
||||||
|
foreach (Client c in connectedClients)
|
||||||
|
{
|
||||||
|
spriteBatch.DrawString(GUI.SmallFont, c.name + ":", new Vector2(x + 10, y), Color.White);
|
||||||
|
spriteBatch.DrawString(GUI.SmallFont, "- avg roundtrip " + c.Connection.AverageRoundtripTime+" s", new Vector2(x + 20, y + 15), Color.White);
|
||||||
|
y += 50;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public bool UpdateNetLobby(object obj)
|
public bool UpdateNetLobby(object obj)
|
||||||
{
|
{
|
||||||
NetOutgoingMessage msg = server.CreateMessage();
|
NetOutgoingMessage msg = server.CreateMessage();
|
||||||
@@ -650,12 +795,12 @@ namespace Subsurface.Networking
|
|||||||
}
|
}
|
||||||
if (recipients.Count>0)
|
if (recipients.Count>0)
|
||||||
{
|
{
|
||||||
server.SendMessage(msg, recipients, NetDeliveryMethod.Unreliable, 0);
|
server.SendMessage(msg, recipients, NetDeliveryMethod.ReliableUnordered, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
server.SendMessage(msg, server.Connections, NetDeliveryMethod.Unreliable, 0);
|
server.SendMessage(msg, server.Connections, NetDeliveryMethod.ReliableUnordered, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,14 +11,15 @@ namespace Subsurface.Networking
|
|||||||
DropItem = 3,
|
DropItem = 3,
|
||||||
InventoryUpdate = 4,
|
InventoryUpdate = 4,
|
||||||
PickItem = 5,
|
PickItem = 5,
|
||||||
UpdateProperty = 6
|
UpdateProperty = 6,
|
||||||
|
NotMoving = 7
|
||||||
}
|
}
|
||||||
|
|
||||||
class NetworkEvent
|
class NetworkEvent
|
||||||
{
|
{
|
||||||
public static List<NetworkEvent> events = new List<NetworkEvent>();
|
public static List<NetworkEvent> events = new List<NetworkEvent>();
|
||||||
|
|
||||||
private static bool[] isImportant = { false, true, false, true, true, true };
|
private static bool[] isImportant = { false, true, false, true, true, true, true, false };
|
||||||
|
|
||||||
private int id;
|
private int id;
|
||||||
|
|
||||||
@@ -113,6 +114,8 @@ namespace Subsurface.Networking
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
System.Diagnostics.Debug.WriteLine("Networkevent entity: "+e.ToString());
|
||||||
|
|
||||||
//System.Diagnostics.Debug.WriteLine("new message: " + eventType +" - "+e);
|
//System.Diagnostics.Debug.WriteLine("new message: " + eventType +" - "+e);
|
||||||
|
|
||||||
e.ReadNetworkData(eventType, message);
|
e.ReadNetworkData(eventType, message);
|
||||||
|
|||||||
@@ -64,6 +64,11 @@ namespace Subsurface.Networking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool GameStarted
|
||||||
|
{
|
||||||
|
get { return gameStarted; }
|
||||||
|
}
|
||||||
|
|
||||||
public GUIFrame InGameHUD
|
public GUIFrame InGameHUD
|
||||||
{
|
{
|
||||||
get { return inGameHUD; }
|
get { return inGameHUD; }
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using Microsoft.Xna.Framework;
|
|||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using Subsurface.Networking;
|
using Subsurface.Networking;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Subsurface
|
namespace Subsurface
|
||||||
{
|
{
|
||||||
@@ -48,6 +49,7 @@ namespace Subsurface
|
|||||||
get { return targetPosition; }
|
get { return targetPosition; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
if (float.IsNaN(value.X) || float.IsNaN(value.Y)) return;
|
||||||
targetPosition.X = MathHelper.Clamp(value.X, -10000.0f, 10000.0f);
|
targetPosition.X = MathHelper.Clamp(value.X, -10000.0f, 10000.0f);
|
||||||
targetPosition.Y = MathHelper.Clamp(value.Y, -10000.0f, 10000.0f);
|
targetPosition.Y = MathHelper.Clamp(value.Y, -10000.0f, 10000.0f);
|
||||||
}
|
}
|
||||||
@@ -57,7 +59,8 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
get { return targetVelocity; }
|
get { return targetVelocity; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
if (float.IsNaN(value.X) || float.IsNaN(value.Y)) return;
|
||||||
targetVelocity.X = MathHelper.Clamp(value.X, -100.0f, 100.0f);
|
targetVelocity.X = MathHelper.Clamp(value.X, -100.0f, 100.0f);
|
||||||
targetVelocity.Y = MathHelper.Clamp(value.Y, -100.0f, 100.0f);
|
targetVelocity.Y = MathHelper.Clamp(value.Y, -100.0f, 100.0f);
|
||||||
}
|
}
|
||||||
@@ -68,7 +71,7 @@ namespace Subsurface
|
|||||||
get { return targetRotation; }
|
get { return targetRotation; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (float.IsNaN(value) || float.IsInfinity(value) || float.IsNegativeInfinity(value)) return;
|
if (float.IsNaN(value) || float.IsInfinity(value)) return;
|
||||||
targetRotation = value;
|
targetRotation = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,7 +79,11 @@ namespace Subsurface
|
|||||||
public float TargetAngularVelocity
|
public float TargetAngularVelocity
|
||||||
{
|
{
|
||||||
get { return targetAngularVelocity; }
|
get { return targetAngularVelocity; }
|
||||||
set { targetAngularVelocity = value; }
|
set
|
||||||
|
{
|
||||||
|
if (float.IsNaN(value) || float.IsInfinity(value)) return;
|
||||||
|
targetAngularVelocity = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2 DrawPosition
|
public Vector2 DrawPosition
|
||||||
@@ -356,13 +363,37 @@ namespace Subsurface
|
|||||||
|
|
||||||
public void ReadNetworkData(NetworkEventType type, NetIncomingMessage message)
|
public void ReadNetworkData(NetworkEventType type, NetIncomingMessage message)
|
||||||
{
|
{
|
||||||
targetPosition.X = message.ReadFloat();
|
Vector2 newTargetPos = Vector2.Zero;
|
||||||
targetPosition.Y = message.ReadFloat();
|
Vector2 newTargetVel = Vector2.Zero;
|
||||||
targetVelocity.X = message.ReadFloat();
|
|
||||||
targetVelocity.Y = message.ReadFloat();
|
float newTargetRotation = 0.0f, newTargetAngularVel = 0.0f;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
newTargetPos = new Vector2(message.ReadFloat(),message.ReadFloat());
|
||||||
|
newTargetVel = new Vector2(message.ReadFloat(),message.ReadFloat());
|
||||||
|
|
||||||
|
newTargetRotation = message.ReadFloat();
|
||||||
|
newTargetAngularVel = message.ReadFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
DebugConsole.ThrowError("invalid network message", e);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!MathUtils.IsValid(newTargetPos) || !MathUtils.IsValid(newTargetVel) ||
|
||||||
|
!MathUtils.IsValid(newTargetRotation) || !MathUtils.IsValid(newTargetAngularVel)) return;
|
||||||
|
|
||||||
|
targetPosition = newTargetPos;
|
||||||
|
targetVelocity = newTargetVel;
|
||||||
|
|
||||||
|
targetRotation = newTargetRotation;
|
||||||
|
targetAngularVelocity = newTargetAngularVel;
|
||||||
|
|
||||||
|
|
||||||
targetRotation = message.ReadFloat();
|
|
||||||
targetAngularVelocity = message.ReadFloat();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+133
-126
@@ -3,157 +3,164 @@ using Microsoft.Xna.Framework.Input;
|
|||||||
|
|
||||||
namespace Subsurface
|
namespace Subsurface
|
||||||
{
|
{
|
||||||
class Key
|
|
||||||
{
|
public enum InputType { Select, ActionHit, ActionHeld, SecondaryHit, SecondaryHeld }
|
||||||
private bool state, stateQueue;
|
|
||||||
private bool canBeHeld;
|
class Key
|
||||||
|
{
|
||||||
public Key(bool canBeHeld)
|
private bool state, stateQueue;
|
||||||
|
private bool canBeHeld;
|
||||||
|
|
||||||
|
public bool CanBeHeld
|
||||||
{
|
{
|
||||||
this.canBeHeld = canBeHeld;
|
get { return canBeHeld; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Key(bool canBeHeld)
|
||||||
|
{
|
||||||
|
this.canBeHeld = canBeHeld;
|
||||||
|
}
|
||||||
|
|
||||||
public bool State
|
public bool State
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
//if (value == false) return;
|
//if (value == false) return;
|
||||||
state = value;
|
state = value;
|
||||||
//if (value) stateQueue = value;
|
//if (value) stateQueue = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetState(bool value)
|
public void SetState(bool value)
|
||||||
{
|
{
|
||||||
state = value;
|
state = value;
|
||||||
if (value) stateQueue = value;
|
if (value) stateQueue = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Dequeue
|
public bool Dequeue
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
bool value = stateQueue;
|
bool value = stateQueue;
|
||||||
stateQueue = false;
|
stateQueue = false;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
//set
|
//set
|
||||||
//{
|
//{
|
||||||
// stateQueue = value;
|
// stateQueue = value;
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
if (!canBeHeld) state = false;
|
if (!canBeHeld) state = false;
|
||||||
//stateQueue = false;
|
//stateQueue = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class PlayerInput
|
static class PlayerInput
|
||||||
{
|
{
|
||||||
static MouseState mouseState, oldMouseState;
|
static MouseState mouseState, oldMouseState;
|
||||||
static KeyboardState keyboardState, oldKeyboardState;
|
static KeyboardState keyboardState, oldKeyboardState;
|
||||||
|
|
||||||
static double timeSinceClick;
|
static double timeSinceClick;
|
||||||
|
|
||||||
const double doubleClickDelay = 0.4;
|
const double doubleClickDelay = 0.4;
|
||||||
|
|
||||||
static bool doubleClicked;
|
static bool doubleClicked;
|
||||||
|
|
||||||
public static Keys selectKey = Keys.E;
|
public static Keys selectKey = Keys.E;
|
||||||
|
|
||||||
public static Vector2 MousePosition
|
public static Vector2 MousePosition
|
||||||
{
|
{
|
||||||
get { return new Vector2(mouseState.Position.X, mouseState.Position.Y); }
|
get { return new Vector2(mouseState.X, mouseState.Y); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MouseState GetMouseState
|
public static MouseState GetMouseState
|
||||||
{
|
{
|
||||||
get { return mouseState; }
|
get { return mouseState; }
|
||||||
}
|
}
|
||||||
public static MouseState GetOldMouseState
|
public static MouseState GetOldMouseState
|
||||||
{
|
{
|
||||||
get { return oldMouseState; }
|
get { return oldMouseState; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector2 MouseSpeed
|
public static Vector2 MouseSpeed
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
Point speed = mouseState.Position - oldMouseState.Position;
|
return MousePosition - new Vector2(oldMouseState.X, oldMouseState.Y);
|
||||||
return new Vector2(speed.X, speed.Y);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static KeyboardState GetKeyboardState
|
public static KeyboardState GetKeyboardState
|
||||||
{
|
{
|
||||||
get { return keyboardState; }
|
get { return keyboardState; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static KeyboardState GetOldKeyboardState
|
public static KeyboardState GetOldKeyboardState
|
||||||
{
|
{
|
||||||
get { return oldKeyboardState; }
|
get { return oldKeyboardState; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int ScrollWheelSpeed
|
public static int ScrollWheelSpeed
|
||||||
{
|
{
|
||||||
get { return mouseState.ScrollWheelValue - oldMouseState.ScrollWheelValue; }
|
get { return mouseState.ScrollWheelValue - oldMouseState.ScrollWheelValue; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool LeftButtonDown()
|
public static bool LeftButtonDown()
|
||||||
{
|
{
|
||||||
return mouseState.LeftButton == ButtonState.Pressed;
|
return mouseState.LeftButton == ButtonState.Pressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool LeftButtonClicked()
|
public static bool LeftButtonClicked()
|
||||||
{
|
{
|
||||||
return (oldMouseState.LeftButton == ButtonState.Pressed
|
return (oldMouseState.LeftButton == ButtonState.Pressed
|
||||||
&& mouseState.LeftButton == ButtonState.Released);
|
&& mouseState.LeftButton == ButtonState.Released);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool RightButtonClicked()
|
public static bool RightButtonClicked()
|
||||||
{
|
{
|
||||||
return (oldMouseState.RightButton == ButtonState.Pressed
|
return (oldMouseState.RightButton == ButtonState.Pressed
|
||||||
&& mouseState.RightButton == ButtonState.Released);
|
&& mouseState.RightButton == ButtonState.Released);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool DoubleClicked()
|
public static bool DoubleClicked()
|
||||||
{
|
{
|
||||||
return doubleClicked;
|
return doubleClicked;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool KeyHit(Keys button)
|
public static bool KeyHit(Keys button)
|
||||||
{
|
{
|
||||||
return (oldKeyboardState.IsKeyDown(button) && keyboardState.IsKeyUp(button));
|
return (oldKeyboardState.IsKeyDown(button) && keyboardState.IsKeyUp(button));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool KeyDown(Keys button)
|
public static bool KeyDown(Keys button)
|
||||||
{
|
{
|
||||||
return (keyboardState.IsKeyDown(button));
|
return (keyboardState.IsKeyDown(button));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Update(double deltaTime)
|
public static void Update(double deltaTime)
|
||||||
{
|
{
|
||||||
timeSinceClick += deltaTime;
|
timeSinceClick += deltaTime;
|
||||||
|
|
||||||
oldMouseState = mouseState;
|
oldMouseState = mouseState;
|
||||||
mouseState = Mouse.GetState();
|
mouseState = Mouse.GetState();
|
||||||
|
|
||||||
oldKeyboardState = keyboardState;
|
oldKeyboardState = keyboardState;
|
||||||
keyboardState = Keyboard.GetState();
|
keyboardState = Keyboard.GetState();
|
||||||
|
|
||||||
doubleClicked = false;
|
doubleClicked = false;
|
||||||
if (LeftButtonClicked())
|
if (LeftButtonClicked())
|
||||||
{
|
{
|
||||||
if (timeSinceClick < doubleClickDelay) doubleClicked = true;
|
if (timeSinceClick < doubleClickDelay) doubleClicked = true;
|
||||||
timeSinceClick = 0.0;
|
timeSinceClick = 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,18 @@ using System.Globalization;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
|
||||||
namespace Subsurface
|
namespace Subsurface
|
||||||
{
|
{
|
||||||
[AttributeUsage(AttributeTargets.Property)]
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
public class Editable : System.Attribute
|
public class Editable : System.Attribute
|
||||||
{
|
{
|
||||||
|
public int MaxLength;
|
||||||
|
|
||||||
|
public Editable(int maxLength = 20)
|
||||||
|
{
|
||||||
|
MaxLength = maxLength;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Property)]
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ namespace Subsurface
|
|||||||
// CreateDummyCharacter();
|
// CreateDummyCharacter();
|
||||||
//}
|
//}
|
||||||
|
|
||||||
cam.MoveCamera((float)deltaTime);
|
if (GUIComponent.MouseOn==null) cam.MoveCamera((float)deltaTime);
|
||||||
cam.Zoom = MathHelper.Clamp(cam.Zoom + PlayerInput.ScrollWheelSpeed/1000.0f,0.1f, 2.0f);
|
cam.Zoom = MathHelper.Clamp(cam.Zoom + PlayerInput.ScrollWheelSpeed/1000.0f,0.1f, 2.0f);
|
||||||
|
|
||||||
if (characterMode)
|
if (characterMode)
|
||||||
|
|||||||
@@ -75,11 +75,12 @@ namespace Subsurface
|
|||||||
|
|
||||||
StatusEffect.UpdateAll((float)deltaTime);
|
StatusEffect.UpdateAll((float)deltaTime);
|
||||||
|
|
||||||
cam.MoveCamera((float)deltaTime);
|
|
||||||
|
|
||||||
Physics.accumulator = Math.Min(Physics.accumulator, Physics.step * 4);
|
Physics.accumulator = Math.Min(Physics.accumulator, Physics.step * 4);
|
||||||
while (Physics.accumulator >= Physics.step)
|
while (Physics.accumulator >= Physics.step)
|
||||||
{
|
{
|
||||||
|
cam.MoveCamera((float)Physics.step);
|
||||||
|
|
||||||
foreach (PhysicsBody pb in PhysicsBody.list)
|
foreach (PhysicsBody pb in PhysicsBody.list)
|
||||||
{
|
{
|
||||||
pb.SetPrevTransform(pb.Position, pb.Rotation);
|
pb.SetPrevTransform(pb.Position, pb.Rotation);
|
||||||
@@ -146,7 +147,7 @@ namespace Subsurface
|
|||||||
graphics.Clear(new Color(11, 18, 26, 255));
|
graphics.Clear(new Color(11, 18, 26, 255));
|
||||||
|
|
||||||
|
|
||||||
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.LinearWrap);
|
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.LinearWrap, DepthStencilState.Default, RasterizerState.CullNone);
|
||||||
|
|
||||||
Vector2 backgroundPos = cam.Position;
|
Vector2 backgroundPos = cam.Position;
|
||||||
if (Level.Loaded != null) backgroundPos -= Level.Loaded.Position;
|
if (Level.Loaded != null) backgroundPos -= Level.Loaded.Position;
|
||||||
|
|||||||
@@ -428,7 +428,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
private bool StartShift(GUIButton button, object selection)
|
private bool StartShift(GUIButton button, object selection)
|
||||||
{
|
{
|
||||||
Game1.GameSession.StartShift(TimeSpan.Zero, selectedLevel);
|
Game1.GameSession.StartShift(TimeSpan.Zero, selectedLevel, false);
|
||||||
Game1.GameScreen.Select();
|
Game1.GameScreen.Select();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -18,9 +18,8 @@ namespace Subsurface
|
|||||||
|
|
||||||
private GUITextBox saveNameBox, seedBox;
|
private GUITextBox saveNameBox, seedBox;
|
||||||
|
|
||||||
private GUITextBox clientNameBox, ipBox;
|
private GUITextBox serverNameBox, portBox, passwordBox, maxPlayersBox;
|
||||||
|
private GUITickBox isPublicBox, useUpnpBox;
|
||||||
private GUITextBox serverNameBox, portBox;
|
|
||||||
|
|
||||||
private Game1 game;
|
private Game1 game;
|
||||||
|
|
||||||
@@ -38,10 +37,10 @@ namespace Subsurface
|
|||||||
menuTabs[(int)Tabs.Main] = new GUIFrame(panelRect, GUI.style);
|
menuTabs[(int)Tabs.Main] = new GUIFrame(panelRect, GUI.style);
|
||||||
//menuTabs[(int)Tabs.Main].Padding = GUI.style.smallPadding;
|
//menuTabs[(int)Tabs.Main].Padding = GUI.style.smallPadding;
|
||||||
|
|
||||||
GUIButton button = new GUIButton(new Rectangle(0, 0, 0, 30), "Tutorial", Alignment.CenterX, GUI.style, menuTabs[(int)Tabs.Main]);
|
//GUIButton button = new GUIButton(new Rectangle(0, 0, 0, 30), "Tutorial", Alignment.CenterX, GUI.style, menuTabs[(int)Tabs.Main]);
|
||||||
button.OnClicked = TutorialButtonClicked;
|
//button.OnClicked = TutorialButtonClicked;
|
||||||
|
|
||||||
button = new GUIButton(new Rectangle(0, 70, 0, 30), "New Game", Alignment.CenterX, GUI.style, menuTabs[(int)Tabs.Main]);
|
GUIButton button = new GUIButton(new Rectangle(0, 70, 0, 30), "New Game", Alignment.CenterX, GUI.style, menuTabs[(int)Tabs.Main]);
|
||||||
button.UserData = (int)Tabs.NewGame;
|
button.UserData = (int)Tabs.NewGame;
|
||||||
button.OnClicked = SelectTab;
|
button.OnClicked = SelectTab;
|
||||||
//button.Enabled = false;
|
//button.Enabled = false;
|
||||||
@@ -112,16 +111,44 @@ namespace Subsurface
|
|||||||
menuTabs[(int)Tabs.HostServer] = new GUIFrame(panelRect, GUI.style);
|
menuTabs[(int)Tabs.HostServer] = new GUIFrame(panelRect, GUI.style);
|
||||||
//menuTabs[(int)Tabs.JoinServer].Padding = GUI.style.smallPadding;
|
//menuTabs[(int)Tabs.JoinServer].Padding = GUI.style.smallPadding;
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 0, 0, 30), "Host Server", GUI.style, Alignment.CenterX, Alignment.CenterX, menuTabs[(int)Tabs.HostServer]);
|
new GUITextBlock(new Rectangle(0, -25, 0, 30), "Host Server", GUI.style, Alignment.CenterX, Alignment.CenterX, menuTabs[(int)Tabs.HostServer], false, GUI.LargeFont);
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 30, 0, 30), "Server Name:", GUI.style, Alignment.CenterX, Alignment.CenterX, menuTabs[(int)Tabs.HostServer]);
|
new GUITextBlock(new Rectangle(0, 50, 0, 30), "Server Name:", GUI.style, Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tabs.HostServer]);
|
||||||
serverNameBox = new GUITextBox(new Rectangle(0, 60, 200, 30), Color.White, Color.Black, Alignment.CenterX, Alignment.CenterX, null, menuTabs[(int)Tabs.HostServer]);
|
serverNameBox = new GUITextBox(new Rectangle(160, 50, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, GUI.style, menuTabs[(int)Tabs.HostServer]);
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 100, 0, 30), "Server port:", GUI.style, Alignment.CenterX, Alignment.CenterX, menuTabs[(int)Tabs.HostServer]);
|
new GUITextBlock(new Rectangle(0, 100, 0, 30), "Server port:", GUI.style, Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tabs.HostServer]);
|
||||||
portBox = new GUITextBox(new Rectangle(0, 130, 200, 30), Color.White, Color.Black, Alignment.CenterX, Alignment.CenterX, null, menuTabs[(int)Tabs.HostServer]);
|
portBox = new GUITextBox(new Rectangle(160, 100, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, GUI.style, menuTabs[(int)Tabs.HostServer]);
|
||||||
portBox.Text = NetworkMember.DefaultPort.ToString();
|
portBox.Text = NetworkMember.DefaultPort.ToString();
|
||||||
portBox.ToolTip = "Server port";
|
portBox.ToolTip = "Server port";
|
||||||
|
|
||||||
|
new GUITextBlock(new Rectangle(0, 150, 100, 30), "Max players:", GUI.style, Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tabs.HostServer]);
|
||||||
|
maxPlayersBox = new GUITextBox(new Rectangle(195, 150, 30, 30), null, null, Alignment.TopLeft, Alignment.Center, GUI.style, menuTabs[(int)Tabs.HostServer]);
|
||||||
|
maxPlayersBox.Text = "8";
|
||||||
|
maxPlayersBox.Enabled = false;
|
||||||
|
|
||||||
|
var plusPlayersBox = new GUIButton(new Rectangle(230, 150, 30, 30), "+", GUI.style, menuTabs[(int)Tabs.HostServer]);
|
||||||
|
plusPlayersBox.UserData = 1;
|
||||||
|
plusPlayersBox.OnClicked = ChangeMaxPlayers;
|
||||||
|
|
||||||
|
var minusPlayersBox = new GUIButton(new Rectangle(160, 150, 30, 30), "-", GUI.style, menuTabs[(int)Tabs.HostServer]);
|
||||||
|
minusPlayersBox.UserData = -1;
|
||||||
|
minusPlayersBox.OnClicked = ChangeMaxPlayers;
|
||||||
|
|
||||||
|
new GUITextBlock(new Rectangle(0, 200, 0, 30), "Password (optional):", GUI.style, Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tabs.HostServer]);
|
||||||
|
passwordBox = new GUITextBox(new Rectangle(160, 200, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, GUI.style, menuTabs[(int)Tabs.HostServer]);
|
||||||
|
|
||||||
|
|
||||||
|
isPublicBox = new GUITickBox(new Rectangle(10, 250, 20, 20), "Public server", Alignment.TopLeft, menuTabs[(int)Tabs.HostServer]);
|
||||||
|
|
||||||
|
useUpnpBox = new GUITickBox(new Rectangle(10, 300, 20, 20), "Attempt UPnP port forwarding", Alignment.TopLeft, menuTabs[(int)Tabs.HostServer]);
|
||||||
|
new GUITextBlock(new Rectangle(0, 330, 0, 30),
|
||||||
|
"UPnP can be used for forwarding ports on your router to allow players join the server."
|
||||||
|
+ " However, UPnP isn't supported by all routers, so you may need to setup port forwards manually"
|
||||||
|
+" if players are unable to join the server (see the readme for instructions).",
|
||||||
|
GUI.style, Alignment.TopLeft, Alignment.TopLeft, menuTabs[(int)Tabs.HostServer], true, GUI.SmallFont);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GUIButton hostButton = new GUIButton(new Rectangle(0, 0, 200, 30), "Start", Alignment.BottomCenter, GUI.style, menuTabs[(int)Tabs.HostServer]);
|
GUIButton hostButton = new GUIButton(new Rectangle(0, 0, 200, 30), "Start", Alignment.BottomCenter, GUI.style, menuTabs[(int)Tabs.HostServer]);
|
||||||
hostButton.OnClicked = HostServerClicked;
|
hostButton.OnClicked = HostServerClicked;
|
||||||
|
|
||||||
@@ -159,6 +186,18 @@ namespace Subsurface
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool ChangeMaxPlayers(GUIButton button, object obj)
|
||||||
|
{
|
||||||
|
int currMaxPlayers = 10;
|
||||||
|
|
||||||
|
int.TryParse(maxPlayersBox.Text, out currMaxPlayers);
|
||||||
|
currMaxPlayers = (int)MathHelper.Clamp(currMaxPlayers+(int)button.UserData, 1, 10);
|
||||||
|
|
||||||
|
maxPlayersBox.Text = currMaxPlayers.ToString();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private bool HostServerClicked(GUIButton button, object obj)
|
private bool HostServerClicked(GUIButton button, object obj)
|
||||||
{
|
{
|
||||||
string name = serverNameBox.Text;
|
string name = serverNameBox.Text;
|
||||||
@@ -177,7 +216,7 @@ namespace Subsurface
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Game1.NetworkMember = new GameServer(name, port);
|
Game1.NetworkMember = new GameServer(name, port, isPublicBox.Selected, passwordBox.Text, useUpnpBox.Selected, int.Parse(maxPlayersBox.Text));
|
||||||
|
|
||||||
Game1.NetLobbyScreen.IsServer = true;
|
Game1.NetLobbyScreen.IsServer = true;
|
||||||
Game1.NetLobbyScreen.Select();
|
Game1.NetLobbyScreen.Select();
|
||||||
@@ -194,7 +233,7 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
menuTabs[(int)Tabs.LoadGame].ClearChildren();
|
menuTabs[(int)Tabs.LoadGame].ClearChildren();
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 0, 0, 30), "Load Game", GUI.style, Alignment.CenterX, Alignment.CenterX, menuTabs[(int)Tabs.LoadGame]);
|
new GUITextBlock(new Rectangle(0, -25, 0, 30), "Load Game", GUI.style, Alignment.CenterX, Alignment.CenterX, menuTabs[(int)Tabs.LoadGame], false, GUI.LargeFont);
|
||||||
|
|
||||||
string[] saveFiles = SaveUtil.GetSaveFiles();
|
string[] saveFiles = SaveUtil.GetSaveFiles();
|
||||||
|
|
||||||
@@ -376,26 +415,5 @@ namespace Subsurface
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private bool JoinServer(GUIButton button, object obj)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(clientNameBox.Text)) return false;
|
|
||||||
if (string.IsNullOrEmpty(ipBox.Text)) return false;
|
|
||||||
|
|
||||||
Game1.NetworkMember = new GameClient(clientNameBox.Text);
|
|
||||||
Game1.Client.ConnectToServer(ipBox.Text);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
//{
|
|
||||||
// Game1.NetLobbyScreen.Select();
|
|
||||||
// return true;
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
// Game1.NetworkMember = null;
|
|
||||||
// return false;
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ namespace Subsurface
|
|||||||
|
|
||||||
private GUITextBox textBox, seedBox;
|
private GUITextBox textBox, seedBox;
|
||||||
|
|
||||||
//GUIFrame previewPlayer;
|
|
||||||
|
|
||||||
private GUIScrollBar durationBar;
|
private GUIScrollBar durationBar;
|
||||||
|
|
||||||
private GUIFrame playerFrame;
|
private GUIFrame playerFrame;
|
||||||
@@ -36,6 +34,11 @@ namespace Subsurface
|
|||||||
|
|
||||||
private GUITextBox serverMessage;
|
private GUITextBox serverMessage;
|
||||||
|
|
||||||
|
public GUIListBox SubList
|
||||||
|
{
|
||||||
|
get { return subList; }
|
||||||
|
}
|
||||||
|
|
||||||
public Submarine SelectedMap
|
public Submarine SelectedMap
|
||||||
{
|
{
|
||||||
get { return subList.SelectedData as Submarine; }
|
get { return subList.SelectedData as Submarine; }
|
||||||
@@ -275,7 +278,7 @@ namespace Subsurface
|
|||||||
modeList.OnSelected += Game1.Server.UpdateNetLobby;
|
modeList.OnSelected += Game1.Server.UpdateNetLobby;
|
||||||
durationBar.OnMoved = Game1.Server.UpdateNetLobby;
|
durationBar.OnMoved = Game1.Server.UpdateNetLobby;
|
||||||
|
|
||||||
if (subList.CountChildren > 0) subList.Select(0);
|
if (subList.CountChildren > 0) subList.Select(-1);
|
||||||
if (GameModePreset.list.Count > 0) modeList.Select(0);
|
if (GameModePreset.list.Count > 0) modeList.Select(0);
|
||||||
}
|
}
|
||||||
else if (playerFrame.children.Count==0)
|
else if (playerFrame.children.Count==0)
|
||||||
@@ -306,9 +309,11 @@ namespace Subsurface
|
|||||||
jobList = new GUIListBox(new Rectangle(0, 180, 180, 0), GUI.style, playerFrame);
|
jobList = new GUIListBox(new Rectangle(0, 180, 180, 0), GUI.style, playerFrame);
|
||||||
jobList.Enabled = false;
|
jobList.Enabled = false;
|
||||||
|
|
||||||
|
|
||||||
|
int i = 1;
|
||||||
foreach (JobPrefab job in JobPrefab.List)
|
foreach (JobPrefab job in JobPrefab.List)
|
||||||
{
|
{
|
||||||
GUITextBlock jobText = new GUITextBlock(new Rectangle(0,0,0,20), job.Name, GUI.style, Alignment.Left, Alignment.Right, jobList);
|
GUITextBlock jobText = new GUITextBlock(new Rectangle(0,0,0,20), i+". "+job.Name, GUI.style, Alignment.Left, Alignment.Right, jobList);
|
||||||
jobText.UserData = job;
|
jobText.UserData = job;
|
||||||
|
|
||||||
GUIButton upButton = new GUIButton(new Rectangle(0, 0, 15, 15), "u", GUI.style, jobText);
|
GUIButton upButton = new GUIButton(new Rectangle(0, 0, 15, 15), "u", GUI.style, jobText);
|
||||||
@@ -443,6 +448,7 @@ namespace Subsurface
|
|||||||
((chatBox.CountChildren % 2) == 0) ? Color.Transparent : Color.Black*0.1f, color,
|
((chatBox.CountChildren % 2) == 0) ? Color.Transparent : Color.Black*0.1f, color,
|
||||||
Alignment.Left, GUI.style, null, true);
|
Alignment.Left, GUI.style, null, true);
|
||||||
msg.Font = GUI.SmallFont;
|
msg.Font = GUI.SmallFont;
|
||||||
|
msg.CanBeFocused = false;
|
||||||
|
|
||||||
msg.Padding = new Vector4(20, 0, 0, 0);
|
msg.Padding = new Vector4(20, 0, 0, 0);
|
||||||
chatBox.AddChild(msg);
|
chatBox.AddChild(msg);
|
||||||
@@ -556,13 +562,17 @@ namespace Subsurface
|
|||||||
private void UpdateJobPreferences(GUIListBox listBox)
|
private void UpdateJobPreferences(GUIListBox listBox)
|
||||||
{
|
{
|
||||||
listBox.Deselect();
|
listBox.Deselect();
|
||||||
for (int i = 1; i < listBox.children.Count; i++)
|
for (int i = 0; i < listBox.children.Count; i++)
|
||||||
{
|
{
|
||||||
float a = (float)(i - 1) / 3.0f;
|
float a = (float)(i - 1) / 3.0f;
|
||||||
a = Math.Min(a, 3);
|
a = Math.Min(a, 3);
|
||||||
Color color = new Color(1.0f - a, (1.0f - a) * 0.6f, 0.0f, 0.3f);
|
Color color = new Color(1.0f - a, (1.0f - a) * 0.6f, 0.0f, 0.3f);
|
||||||
|
|
||||||
listBox.children[i].Color = color;
|
listBox.children[i].Color = color;
|
||||||
|
listBox.children[i].HoverColor = color;
|
||||||
|
listBox.children[i].SelectedColor = color;
|
||||||
|
|
||||||
|
(listBox.children[i] as GUITextBlock).Text = (i+1) + ". " + (listBox.children[i].UserData as JobPrefab).Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Game1.Client.SendCharacterData();
|
Game1.Client.SendCharacterData();
|
||||||
@@ -658,57 +668,13 @@ namespace Subsurface
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TrySelectMap(mapName, md5Hash);
|
if (!string.IsNullOrWhiteSpace(mapName)) TrySelectMap(mapName, md5Hash);
|
||||||
|
|
||||||
modeList.Select(modeIndex);
|
modeList.Select(modeIndex);
|
||||||
|
|
||||||
durationBar.BarScroll = durationScroll;
|
durationBar.BarScroll = durationScroll;
|
||||||
|
|
||||||
LevelSeed = levelSeed;
|
LevelSeed = levelSeed;
|
||||||
|
|
||||||
//try
|
|
||||||
//{
|
|
||||||
// int playerCount = msg.ReadInt32();
|
|
||||||
|
|
||||||
// for (int i = 0; i < playerCount; i++)
|
|
||||||
// {
|
|
||||||
// int clientID = msg.ReadInt32();
|
|
||||||
// string jobName = msg.ReadString();
|
|
||||||
|
|
||||||
// Client client = null;
|
|
||||||
// GUITextBlock textBlock = null;
|
|
||||||
// foreach (GUIComponent child in playerList.children)
|
|
||||||
// {
|
|
||||||
// Client tempClient = child.UserData as Client;
|
|
||||||
// if (tempClient == null || tempClient.ID != clientID) continue;
|
|
||||||
|
|
||||||
// client = tempClient;
|
|
||||||
// textBlock = child as GUITextBlock;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// if (client == null) continue;
|
|
||||||
|
|
||||||
// client.assignedJob = JobPrefab.List.Find(jp => jp.Name == jobName);
|
|
||||||
|
|
||||||
// textBlock.Text = client.name + ((client.assignedJob==null) ? "" : " (" + client.assignedJob.Name + ")");
|
|
||||||
|
|
||||||
// if (client.assignedJob==null || jobName != client.assignedJob.Name)
|
|
||||||
// {
|
|
||||||
// if (clientID == Game1.Client.ID)
|
|
||||||
// {
|
|
||||||
// Game1.Client.CharacterInfo.Job = new Job(client.assignedJob);
|
|
||||||
// Game1.Client.CharacterInfo.Name = client.name;
|
|
||||||
// UpdatePreviewPlayer(Game1.Client.CharacterInfo);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
//catch
|
|
||||||
//{
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace Subsurface
|
|||||||
class Screen
|
class Screen
|
||||||
{
|
{
|
||||||
private static Screen selected;
|
private static Screen selected;
|
||||||
|
|
||||||
public static Screen Selected
|
public static Screen Selected
|
||||||
{
|
{
|
||||||
get { return selected; }
|
get { return selected; }
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
class ServerListScreen : Screen
|
class ServerListScreen : Screen
|
||||||
{
|
{
|
||||||
|
//how often the client is allowed to refresh servers
|
||||||
|
private TimeSpan AllowedRefreshInterval = new TimeSpan(0,0,3);
|
||||||
|
|
||||||
private GUIFrame menu;
|
private GUIFrame menu;
|
||||||
|
|
||||||
private GUIListBox serverList;
|
private GUIListBox serverList;
|
||||||
@@ -22,6 +25,15 @@ namespace Subsurface
|
|||||||
|
|
||||||
private GUITextBox clientNameBox, ipBox;
|
private GUITextBox clientNameBox, ipBox;
|
||||||
|
|
||||||
|
//private RestRequestAsyncHandle restRequestHandle;
|
||||||
|
private bool masterServerResponded;
|
||||||
|
|
||||||
|
private int[] columnX;
|
||||||
|
|
||||||
|
//a timer for
|
||||||
|
private DateTime refreshDisableTimer;
|
||||||
|
private bool waitingForRefresh;
|
||||||
|
|
||||||
public ServerListScreen()
|
public ServerListScreen()
|
||||||
{
|
{
|
||||||
int width = Math.Min(Game1.GraphicsWidth - 160, 1000);
|
int width = Math.Min(Game1.GraphicsWidth - 160, 1000);
|
||||||
@@ -30,37 +42,55 @@ namespace Subsurface
|
|||||||
Rectangle panelRect = new Rectangle(0, 0, width, height);
|
Rectangle panelRect = new Rectangle(0, 0, width, height);
|
||||||
|
|
||||||
menu = new GUIFrame(panelRect, null, Alignment.Center, GUI.style);
|
menu = new GUIFrame(panelRect, null, Alignment.Center, GUI.style);
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 0, 0, 30), "Join Server", GUI.style, Alignment.CenterX, Alignment.CenterX, menu);
|
new GUITextBlock(new Rectangle(0, -25, 0, 30), "Join Server", GUI.style, Alignment.CenterX, Alignment.CenterX, menu, false, GUI.LargeFont);
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 30, 0, 30), "Your Name:", GUI.style, menu);
|
new GUITextBlock(new Rectangle(0, 30, 0, 30), "Your Name:", GUI.style, menu);
|
||||||
clientNameBox = new GUITextBox(new Rectangle(0, 60, 200, 30), GUI.style, menu);
|
clientNameBox = new GUITextBox(new Rectangle(0, 60, 200, 30), GUI.style, menu);
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 100, 0, 30), "Server IP:", GUI.style, menu);
|
new GUITextBlock(new Rectangle(0, 100, 0, 30), "Server IP:", GUI.style, menu);
|
||||||
ipBox = new GUITextBox(new Rectangle(0, 130, 200, 30), GUI.style, menu);
|
ipBox = new GUITextBox(new Rectangle(0, 130, 200, 30), GUI.style, menu);
|
||||||
|
|
||||||
int middleX = (int)(width * 0.4f);
|
int middleX = (int)(width * 0.4f);
|
||||||
|
|
||||||
serverList = new GUIListBox(new Rectangle(middleX,60,0,(int)(height*0.7f)), GUI.style, menu);
|
serverList = new GUIListBox(new Rectangle(middleX,60,0,(int)(height*0.7f)), GUI.style, menu);
|
||||||
serverList.OnSelected = SelectServer;
|
serverList.OnSelected = SelectServer;
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(middleX, 30, 0, 30), "Name", GUI.style, menu);
|
float[] columnRelativeX = new float[] { 0.15f, 0.55f, 0.15f, 0.15f };
|
||||||
new GUITextBlock(new Rectangle(middleX, 30, 0, 30), "Players", GUI.style, Alignment.TopLeft, Alignment.TopCenter, menu);
|
columnX = new int[columnRelativeX.Length];
|
||||||
new GUITextBlock(new Rectangle(middleX, 30, 0, 30), "Game running", GUI.style, Alignment.TopLeft, Alignment.TopRight, menu);
|
for (int n = 0; n < columnX.Length; n++)
|
||||||
|
{
|
||||||
|
columnX[n] = (int)(columnRelativeX[n] * serverList.Rect.Width);
|
||||||
|
if (n > 0) columnX[n] += columnX[n - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
new GUITextBlock(new Rectangle(middleX, 30, 0, 30), "Password", GUI.style, menu);
|
||||||
|
|
||||||
|
new GUITextBlock(new Rectangle(middleX + columnX[0], 30, 0, 30), "Name", GUI.style, menu);
|
||||||
|
new GUITextBlock(new Rectangle(middleX + columnX[1], 30, 0, 30), "Players", GUI.style, menu);
|
||||||
|
new GUITextBlock(new Rectangle(middleX + columnX[2], 30, 0, 30), "Running", GUI.style, menu);
|
||||||
|
|
||||||
joinButton = new GUIButton(new Rectangle(-170, 0, 150, 30), "Refresh", Alignment.BottomRight, GUI.style, menu);
|
joinButton = new GUIButton(new Rectangle(-170, 0, 150, 30), "Refresh", Alignment.BottomRight, GUI.style, menu);
|
||||||
joinButton.OnClicked = RefreshServers;
|
joinButton.OnClicked = RefreshServers;
|
||||||
|
|
||||||
joinButton = new GUIButton(new Rectangle(0,0,150,30), "Join", Alignment.BottomRight, GUI.style, menu);
|
joinButton = new GUIButton(new Rectangle(0,0,150,30), "Join", Alignment.BottomRight, GUI.style, menu);
|
||||||
joinButton.OnClicked = JoinServer;
|
joinButton.OnClicked = JoinServer;
|
||||||
//joinButton.Enabled = false;
|
|
||||||
|
GUIButton button = new GUIButton(new Rectangle(-20, -20, 100, 30), "Back", Alignment.TopLeft, GUI.style, menu);
|
||||||
|
button.UserData = 0;
|
||||||
|
button.OnClicked = Game1.MainMenuScreen.SelectTab;
|
||||||
|
|
||||||
|
|
||||||
|
refreshDisableTimer = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Select()
|
public override void Select()
|
||||||
{
|
{
|
||||||
base.Select();
|
base.Select();
|
||||||
|
|
||||||
UpdateServerList();
|
|
||||||
|
//RefreshServers(null, null);
|
||||||
|
//UpdateServerList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool SelectServer(object obj)
|
private bool SelectServer(object obj)
|
||||||
@@ -75,16 +105,39 @@ namespace Subsurface
|
|||||||
|
|
||||||
private bool RefreshServers(GUIButton button, object obj)
|
private bool RefreshServers(GUIButton button, object obj)
|
||||||
{
|
{
|
||||||
UpdateServerList();
|
if (waitingForRefresh) return false;
|
||||||
|
serverList.ClearChildren();
|
||||||
|
|
||||||
|
new GUITextBlock(new Rectangle(0, 0, 0, 20), "Refreshing server list...", GUI.style, serverList);
|
||||||
|
|
||||||
|
CoroutineManager.StartCoroutine(WaitForRefresh());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateServerList()
|
private IEnumerable<object> WaitForRefresh()
|
||||||
|
{
|
||||||
|
waitingForRefresh = true;
|
||||||
|
if (refreshDisableTimer > DateTime.Now)
|
||||||
|
{
|
||||||
|
yield return new WaitForSeconds((float)(refreshDisableTimer - DateTime.Now).TotalSeconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
//CoroutineManager.StartCoroutine(UpdateServerList());
|
||||||
|
CoroutineManager.StartCoroutine(SendMasterServerRequest());
|
||||||
|
|
||||||
|
waitingForRefresh = false;
|
||||||
|
|
||||||
|
refreshDisableTimer = DateTime.Now + AllowedRefreshInterval;
|
||||||
|
|
||||||
|
yield return Status.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateServerList(string masterServerData)
|
||||||
{
|
{
|
||||||
serverList.ClearChildren();
|
serverList.ClearChildren();
|
||||||
|
|
||||||
string masterServerData = GetMasterServerData();
|
//string masterServerData = GetMasterServerData();
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(masterServerData))
|
if (string.IsNullOrWhiteSpace(masterServerData))
|
||||||
{
|
{
|
||||||
@@ -96,6 +149,7 @@ namespace Subsurface
|
|||||||
if (masterServerData.Substring(0,5).ToLower()=="error")
|
if (masterServerData.Substring(0,5).ToLower()=="error")
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Error while connecting to master server ("+masterServerData+")!");
|
DebugConsole.ThrowError("Error while connecting to master server ("+masterServerData+")!");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,23 +166,33 @@ namespace Subsurface
|
|||||||
string gameStarted = (arguments.Length > 3) ? arguments[3] : "";
|
string gameStarted = (arguments.Length > 3) ? arguments[3] : "";
|
||||||
string playerCountStr = (arguments.Length > 4) ? arguments[4] : "";
|
string playerCountStr = (arguments.Length > 4) ? arguments[4] : "";
|
||||||
|
|
||||||
|
string hasPassWordStr = (arguments.Length > 5) ? arguments[5] : "";
|
||||||
|
|
||||||
var serverFrame = new GUIFrame(new Rectangle(0,0,0,20), (i%2 == 0) ? Color.Transparent : Color.White*0.2f, null, serverList);
|
var serverFrame = new GUIFrame(new Rectangle(0,0,0,20), (i%2 == 0) ? Color.Transparent : Color.White*0.2f, null, serverList);
|
||||||
serverFrame.UserData = IP+":"+port;
|
serverFrame.UserData = IP+":"+port;
|
||||||
serverFrame.HoverColor = Color.Gold * 0.2f;
|
serverFrame.HoverColor = Color.Gold * 0.2f;
|
||||||
serverFrame.SelectedColor = Color.Gold * 0.5f;
|
serverFrame.SelectedColor = Color.Gold * 0.5f;
|
||||||
|
|
||||||
var nameText = new GUITextBlock(new Rectangle(0,0,0,0), serverName, GUI.style, serverFrame);
|
var passwordBox = new GUITickBox(new Rectangle(columnX[0]/2, 0, 20, 20), "", Alignment.TopLeft, serverFrame);
|
||||||
|
passwordBox.Selected = hasPassWordStr == "1";
|
||||||
|
passwordBox.Enabled = false;
|
||||||
|
passwordBox.UserData = "password";
|
||||||
|
|
||||||
|
var nameText = new GUITextBlock(new Rectangle(columnX[0], 0, 0, 0), serverName, GUI.style, serverFrame);
|
||||||
|
|
||||||
int playerCount, maxPlayers;
|
int playerCount, maxPlayers;
|
||||||
playerCount = GameClient.ByteToPlayerCount((byte)int.Parse(playerCountStr), out maxPlayers);
|
playerCount = GameClient.ByteToPlayerCount((byte)int.Parse(playerCountStr), out maxPlayers);
|
||||||
|
|
||||||
var playerCountText = new GUITextBlock(new Rectangle(0, 0, 0, 0), playerCount+"/"+maxPlayers, GUI.style, Alignment.Left, Alignment.TopCenter, serverFrame);
|
var playerCountText = new GUITextBlock(new Rectangle(columnX[1], 0, 0, 0), playerCount + "/" + maxPlayers, GUI.style, serverFrame);
|
||||||
var gameStartedText = new GUITextBlock(new Rectangle(0, 0, 0, 0), gameStarted=="1" ? "Yes" : "No", GUI.style, Alignment.Left, Alignment.TopRight, serverFrame);
|
|
||||||
|
var gameStartedBox = new GUITickBox(new Rectangle(columnX[2] + (columnX[3] - columnX[2])/ 2, 0, 20, 20), "", Alignment.TopLeft, serverFrame);
|
||||||
|
gameStartedBox.Selected = gameStarted == "1";
|
||||||
|
gameStartedBox.Enabled = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetMasterServerData()
|
private IEnumerable<object> SendMasterServerRequest()
|
||||||
{
|
{
|
||||||
RestClient client = null;
|
RestClient client = null;
|
||||||
try
|
try
|
||||||
@@ -137,10 +201,11 @@ namespace Subsurface
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Error while connecting to master server", e);
|
DebugConsole.ThrowError("Error while connecting to master server", e);
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (client == null) yield return Status.Success;
|
||||||
|
|
||||||
|
|
||||||
var request = new RestRequest("masterserver.php", Method.GET);
|
var request = new RestRequest("masterserver.php", Method.GET);
|
||||||
request.AddParameter("gamename", "subsurface"); // adds to POST or URL querystring based on Method
|
request.AddParameter("gamename", "subsurface"); // adds to POST or URL querystring based on Method
|
||||||
@@ -154,17 +219,44 @@ namespace Subsurface
|
|||||||
//request.AddFile(path);
|
//request.AddFile(path);
|
||||||
|
|
||||||
// execute the request
|
// execute the request
|
||||||
RestResponse response = (RestResponse)client.Execute(request);
|
masterServerResponded = false;
|
||||||
|
var restRequestHandle = client.ExecuteAsync(request, response => MasterServerCallBack(response));
|
||||||
|
|
||||||
|
DateTime timeOut = DateTime.Now + new TimeSpan(0, 0, 8);
|
||||||
|
while (!masterServerResponded)
|
||||||
|
{
|
||||||
|
if (DateTime.Now > timeOut)
|
||||||
|
{
|
||||||
|
serverList.ClearChildren();
|
||||||
|
restRequestHandle.Abort();
|
||||||
|
DebugConsole.ThrowError("Couldn't connect to master server (request timed out)");
|
||||||
|
}
|
||||||
|
yield return Status.Running;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield return Status.Success;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MasterServerCallBack(IRestResponse response)
|
||||||
|
{
|
||||||
|
masterServerResponded = true;
|
||||||
|
|
||||||
|
if (response.ErrorException!=null)
|
||||||
|
{
|
||||||
|
serverList.ClearChildren();
|
||||||
|
DebugConsole.ThrowError("Error while connecting to master server", response.ErrorException);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (response.StatusCode!= System.Net.HttpStatusCode.OK)
|
if (response.StatusCode!= System.Net.HttpStatusCode.OK)
|
||||||
{
|
{
|
||||||
|
serverList.ClearChildren();
|
||||||
DebugConsole.ThrowError("Error while connecting to master server (" +response.StatusCode+": "+response.StatusDescription+")");
|
DebugConsole.ThrowError("Error while connecting to master server (" +response.StatusCode+": "+response.StatusDescription+")");
|
||||||
return "";
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.Content; // raw content as string
|
UpdateServerList(response.Content);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool JoinServer(GUIButton button, object obj)
|
private bool JoinServer(GUIButton button, object obj)
|
||||||
@@ -183,12 +275,41 @@ namespace Subsurface
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Game1.NetworkMember = new GameClient(clientNameBox.Text);
|
CoroutineManager.StartCoroutine(JoinServer(ip));
|
||||||
Game1.Client.ConnectToServer(ip);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IEnumerable<object> JoinServer(string ip)
|
||||||
|
{
|
||||||
|
string selectedPassword = "";
|
||||||
|
|
||||||
|
if (serverList.Selected!=null && (serverList.Selected.GetChild("password") as GUITickBox).Selected)
|
||||||
|
{
|
||||||
|
var msgBox = new GUIMessageBox("Password required", "");
|
||||||
|
var passwordBox = new GUITextBox(new Rectangle(0,0,150,20), Alignment.BottomCenter, GUI.style, msgBox);
|
||||||
|
passwordBox.UserData = "password";
|
||||||
|
|
||||||
|
var okButton = msgBox.GetChild<GUIButton>();
|
||||||
|
|
||||||
|
while (GUIMessageBox.MessageBoxes.Contains(msgBox))
|
||||||
|
{
|
||||||
|
okButton.Enabled = !string.IsNullOrWhiteSpace(passwordBox.Text);
|
||||||
|
yield return Status.Running;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedPassword = passwordBox.Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
Game1.NetworkMember = new GameClient(clientNameBox.Text);
|
||||||
|
Game1.Client.ConnectToServer(ip, selectedPassword);
|
||||||
|
|
||||||
|
Game1.NetLobbyScreen.Select();
|
||||||
|
|
||||||
|
yield return Status.Success;
|
||||||
|
}
|
||||||
|
|
||||||
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
|
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
|
||||||
{
|
{
|
||||||
graphics.Clear(Color.CornflowerBlue);
|
graphics.Clear(Color.CornflowerBlue);
|
||||||
@@ -208,6 +329,8 @@ namespace Subsurface
|
|||||||
|
|
||||||
public override void Update(double deltaTime)
|
public override void Update(double deltaTime)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
menu.Update((float)deltaTime);
|
menu.Update((float)deltaTime);
|
||||||
|
|
||||||
GUI.Update((float)deltaTime);
|
GUI.Update((float)deltaTime);
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
if (startDrone!=null)
|
if (startDrone!=null)
|
||||||
{
|
{
|
||||||
if (!SoundManager.IsPlaying(startDrone.AlBufferId))
|
if (!startDrone.IsPlaying)
|
||||||
{
|
{
|
||||||
startDrone.Remove();
|
startDrone.Remove();
|
||||||
startDrone = null;
|
startDrone = null;
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ namespace Subsurface
|
|||||||
private OggSound oggSound;
|
private OggSound oggSound;
|
||||||
|
|
||||||
string filePath;
|
string filePath;
|
||||||
|
|
||||||
|
private int alSourceId;
|
||||||
|
|
||||||
|
|
||||||
//public float Volume
|
//public float Volume
|
||||||
@@ -71,7 +73,8 @@ namespace Subsurface
|
|||||||
|
|
||||||
public int Play(float volume = 1.0f)
|
public int Play(float volume = 1.0f)
|
||||||
{
|
{
|
||||||
return SoundManager.Play(this, volume);
|
alSourceId = SoundManager.Play(this, volume);
|
||||||
|
return alSourceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Play(float baseVolume, float range, Vector2 position)
|
public int Play(float baseVolume, float range, Vector2 position)
|
||||||
@@ -83,7 +86,9 @@ namespace Subsurface
|
|||||||
Vector2 relativePos = GetRelativePosition(position);
|
Vector2 relativePos = GetRelativePosition(position);
|
||||||
float volume = GetVolume(relativePos, range, baseVolume);
|
float volume = GetVolume(relativePos, range, baseVolume);
|
||||||
|
|
||||||
return SoundManager.Play(this, relativePos, volume, volume);
|
alSourceId = SoundManager.Play(this, relativePos, volume, volume);
|
||||||
|
|
||||||
|
return alSourceId;
|
||||||
|
|
||||||
//if (newIndex == -1) return -1;
|
//if (newIndex == -1) return -1;
|
||||||
|
|
||||||
@@ -96,7 +101,9 @@ namespace Subsurface
|
|||||||
//bodyPosition.Y = -bodyPosition.Y;
|
//bodyPosition.Y = -bodyPosition.Y;
|
||||||
|
|
||||||
|
|
||||||
return Play(volume, range, ConvertUnits.ToDisplayUnits(body.Position));
|
alSourceId = Play(volume, range, ConvertUnits.ToDisplayUnits(body.Position));
|
||||||
|
|
||||||
|
return alSourceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private float GetVolume(Vector2 relativePosition, float range, float baseVolume)
|
private float GetVolume(Vector2 relativePosition, float range, float baseVolume)
|
||||||
@@ -178,6 +185,14 @@ namespace Subsurface
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsPlaying
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return SoundManager.IsPlaying(alSourceId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//public int Loop(float volume = 1.0f)
|
//public int Loop(float volume = 1.0f)
|
||||||
//{
|
//{
|
||||||
// return SoundManager.Loop(this, volume);
|
// return SoundManager.Loop(this, volume);
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using OpenTK.Audio;
|
#if WINDOWS
|
||||||
using OpenTK.Audio.OpenAL;
|
using OpenTK.Audio.OpenAL;
|
||||||
|
#endif
|
||||||
|
using OpenTK.Audio;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Subsurface.Sounds
|
namespace Subsurface.Sounds
|
||||||
@@ -34,14 +37,14 @@ namespace Subsurface.Sounds
|
|||||||
|
|
||||||
for (int i = 0 ; i < DefaultSourceCount; i++)
|
for (int i = 0 ; i < DefaultSourceCount; i++)
|
||||||
{
|
{
|
||||||
alSources.Add(AL.GenSource());
|
alSources.Add(OpenTK.Audio.OpenAL.AL.GenSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ALHelper.Efx.IsInitialized)
|
if (ALHelper.Efx.IsInitialized)
|
||||||
{
|
{
|
||||||
lowpassFilterId = ALHelper.Efx.GenFilter();
|
lowpassFilterId = ALHelper.Efx.GenFilter();
|
||||||
//alFilters.Add(alFilterId);
|
//alFilters.Add(alFilterId);
|
||||||
ALHelper.Efx.Filter(lowpassFilterId, EfxFilteri.FilterType, (int)EfxFilterType.Lowpass);
|
ALHelper.Efx.Filter(lowpassFilterId, OpenTK.Audio.OpenAL.EfxFilteri.FilterType, (int)OpenTK.Audio.OpenAL.EfxFilterType.Lowpass);
|
||||||
|
|
||||||
//LowPassHFGain = 1;
|
//LowPassHFGain = 1;
|
||||||
}
|
}
|
||||||
@@ -129,29 +132,29 @@ namespace Subsurface.Sounds
|
|||||||
for (int i = 1; i < DefaultSourceCount; i++)
|
for (int i = 1; i < DefaultSourceCount; i++)
|
||||||
{
|
{
|
||||||
//find a source that's free to use (not playing or paused)
|
//find a source that's free to use (not playing or paused)
|
||||||
if (AL.GetSourceState(alSources[i]) == ALSourceState.Playing
|
if (OpenTK.Audio.OpenAL.AL.GetSourceState(alSources[i]) == OpenTK.Audio.OpenAL.ALSourceState.Playing
|
||||||
|| AL.GetSourceState(alSources[i]) == ALSourceState.Paused) continue;
|
|| OpenTK.Audio.OpenAL.AL.GetSourceState(alSources[i]) == OpenTK.Audio.OpenAL.ALSourceState.Paused) continue;
|
||||||
|
|
||||||
//if (position!=Vector2.Zero)
|
//if (position!=Vector2.Zero)
|
||||||
// position /= 1000.0f;
|
// position /= 1000.0f;
|
||||||
|
|
||||||
alBuffers[i] = sound.AlBufferId;
|
alBuffers[i] = sound.AlBufferId;
|
||||||
AL.Source(alSources[i], ALSourceb.Looping, false);
|
OpenTK.Audio.OpenAL.AL.Source(alSources[i], OpenTK.Audio.OpenAL.ALSourceb.Looping, false);
|
||||||
|
|
||||||
position /= 1000.0f;
|
position /= 1000.0f;
|
||||||
|
|
||||||
//System.Diagnostics.Debug.WriteLine("updatesoundpos: "+offset);
|
//System.Diagnostics.Debug.WriteLine("updatesoundpos: "+offset);
|
||||||
AL.Source(alSources[i], ALSourcef.Gain, volume);
|
OpenTK.Audio.OpenAL.AL.Source(alSources[i], OpenTK.Audio.OpenAL.ALSourcef.Gain, volume);
|
||||||
AL.Source(alSources[i], ALSource3f.Position, position.X, position.Y, 0.0f);
|
OpenTK.Audio.OpenAL.AL.Source(alSources[i], OpenTK.Audio.OpenAL.ALSource3f.Position, position.X, position.Y, 0.0f);
|
||||||
|
|
||||||
AL.Source(alSources[i], ALSourcei.Buffer, sound.AlBufferId);
|
OpenTK.Audio.OpenAL.AL.Source(alSources[i], OpenTK.Audio.OpenAL.ALSourcei.Buffer, sound.AlBufferId);
|
||||||
|
|
||||||
ALHelper.Efx.Filter(lowpassFilterId, EfxFilterf.LowpassGainHF, lowPassHfGain = Math.Min(lowPassGain, overrideLowPassGain));
|
ALHelper.Efx.Filter(lowpassFilterId, OpenTK.Audio.OpenAL.EfxFilterf.LowpassGainHF, lowPassHfGain = Math.Min(lowPassGain, overrideLowPassGain));
|
||||||
ALHelper.Efx.BindFilterToSource(alSources[i], lowpassFilterId);
|
ALHelper.Efx.BindFilterToSource(alSources[i], lowpassFilterId);
|
||||||
ALHelper.Check();
|
ALHelper.Check();
|
||||||
|
|
||||||
//AL.Source(alSources[i], ALSource3f.Position, position.X, position.Y, 0.0f);
|
//AL.Source(alSources[i], ALSource3f.Position, position.X, position.Y, 0.0f);
|
||||||
AL.SourcePlay(alSources[i]);
|
OpenTK.Audio.OpenAL.AL.SourcePlay(alSources[i]);
|
||||||
|
|
||||||
//sound.sourceIndex = i;
|
//sound.sourceIndex = i;
|
||||||
|
|
||||||
@@ -261,10 +264,10 @@ namespace Subsurface.Sounds
|
|||||||
for (int i = 0; i < DefaultSourceCount; i++)
|
for (int i = 0; i < DefaultSourceCount; i++)
|
||||||
{
|
{
|
||||||
//find a source that's free to use (not playing or paused)
|
//find a source that's free to use (not playing or paused)
|
||||||
if (AL.GetSourceState(alSources[i]) != ALSourceState.Playing
|
if (OpenTK.Audio.OpenAL.AL.GetSourceState(alSources[i]) != OpenTK.Audio.OpenAL.ALSourceState.Playing
|
||||||
&& AL.GetSourceState(alSources[i])!= ALSourceState.Paused) continue;
|
&& OpenTK.Audio.OpenAL.AL.GetSourceState(alSources[i])!= OpenTK.Audio.OpenAL.ALSourceState.Paused) continue;
|
||||||
|
|
||||||
ALHelper.Efx.Filter(lowpassFilterId, EfxFilterf.LowpassGainHF, lowPassHfGain = value);
|
ALHelper.Efx.Filter(lowpassFilterId, OpenTK.Audio.OpenAL.EfxFilterf.LowpassGainHF, lowPassHfGain = value);
|
||||||
ALHelper.Efx.BindFilterToSource(alSources[i], lowpassFilterId);
|
ALHelper.Efx.BindFilterToSource(alSources[i], lowpassFilterId);
|
||||||
ALHelper.Check();
|
ALHelper.Check();
|
||||||
}
|
}
|
||||||
@@ -293,10 +296,10 @@ namespace Subsurface.Sounds
|
|||||||
position/= 1000.0f;
|
position/= 1000.0f;
|
||||||
|
|
||||||
//System.Diagnostics.Debug.WriteLine("updatesoundpos: "+offset);
|
//System.Diagnostics.Debug.WriteLine("updatesoundpos: "+offset);
|
||||||
AL.Source(alSources[sourceIndex], ALSourcef.Gain, baseVolume);
|
OpenTK.Audio.OpenAL.AL.Source(alSources[sourceIndex], OpenTK.Audio.OpenAL.ALSourcef.Gain, baseVolume);
|
||||||
AL.Source(alSources[sourceIndex], ALSource3f.Position, position.X, position.Y, 0.0f);
|
OpenTK.Audio.OpenAL.AL.Source(alSources[sourceIndex], OpenTK.Audio.OpenAL.ALSource3f.Position, position.X, position.Y, 0.0f);
|
||||||
|
|
||||||
ALHelper.Efx.Filter(lowpassFilterId, EfxFilterf.LowpassGainHF, lowPassHfGain = Math.Min(lowPassGain, overrideLowPassGain));
|
ALHelper.Efx.Filter(lowpassFilterId, OpenTK.Audio.OpenAL.EfxFilterf.LowpassGainHF, lowPassHfGain = Math.Min(lowPassGain, overrideLowPassGain));
|
||||||
ALHelper.Efx.BindFilterToSource(alSources[sourceIndex], lowpassFilterId);
|
ALHelper.Efx.BindFilterToSource(alSources[sourceIndex], lowpassFilterId);
|
||||||
ALHelper.Check();
|
ALHelper.Check();
|
||||||
}
|
}
|
||||||
@@ -328,7 +331,7 @@ namespace Subsurface.Sounds
|
|||||||
{
|
{
|
||||||
if (alBuffers[i] == bufferId)
|
if (alBuffers[i] == bufferId)
|
||||||
{
|
{
|
||||||
AL.Source(alSources[i], ALSourcei.Buffer, 0);
|
OpenTK.Audio.OpenAL.AL.Source(alSources[i], OpenTK.Audio.OpenAL.ALSourcei.Buffer, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,11 +346,11 @@ namespace Subsurface.Sounds
|
|||||||
|
|
||||||
for (int i = 0; i < DefaultSourceCount; i++)
|
for (int i = 0; i < DefaultSourceCount; i++)
|
||||||
{
|
{
|
||||||
var state = AL.GetSourceState(alSources[i]);
|
var state = OpenTK.Audio.OpenAL.AL.GetSourceState(alSources[i]);
|
||||||
if (state == ALSourceState.Playing || state == ALSourceState.Paused)
|
if (state == OpenTK.Audio.OpenAL.ALSourceState.Playing || state == OpenTK.Audio.OpenAL.ALSourceState.Paused)
|
||||||
Stop(i);
|
Stop(i);
|
||||||
|
|
||||||
AL.DeleteSource(alSources[i]);
|
OpenTK.Audio.OpenAL.AL.DeleteSource(alSources[i]);
|
||||||
|
|
||||||
ALHelper.Check();
|
ALHelper.Check();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ namespace Subsurface
|
|||||||
|
|
||||||
public static float Round(float value, float div)
|
public static float Round(float value, float div)
|
||||||
{
|
{
|
||||||
return (float)Math.Floor(value / div) * div;
|
return (value < 0.0f) ?
|
||||||
|
(float)Math.Ceiling(value / div) * div :
|
||||||
|
(float)Math.Floor(value / div) * div;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float VectorToAngle(Vector2 vector)
|
public static float VectorToAngle(Vector2 vector)
|
||||||
@@ -25,6 +27,16 @@ namespace Subsurface
|
|||||||
return (float)Math.Atan2(vector.Y, vector.X);
|
return (float)Math.Atan2(vector.Y, vector.X);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsValid(float value)
|
||||||
|
{
|
||||||
|
return (!float.IsInfinity(value) && !float.IsNaN(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsValid(Vector2 vector)
|
||||||
|
{
|
||||||
|
return (IsValid(vector.X) && IsValid(vector.Y));
|
||||||
|
}
|
||||||
|
|
||||||
public static float CurveAngle(float from, float to, float step)
|
public static float CurveAngle(float from, float to, float step)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -55,11 +55,16 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Error saving gamesession", e);
|
DebugConsole.ThrowError("Error saving gamesession", e);
|
||||||
}
|
}
|
||||||
//Game1.GameSession.crewManager.Save(directory+"\\crew.xml");
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CompressDirectory(tempPath, fileName+".save", null);
|
||||||
|
}
|
||||||
|
|
||||||
CompressDirectory(tempPath, fileName+".save", null);
|
catch (Exception e)
|
||||||
|
{
|
||||||
//Directory.Delete(tempPath, true);
|
DebugConsole.ThrowError("Error compressing save file", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LoadGame(string fileName)
|
public static void LoadGame(string fileName)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.IO;
|
|||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using Color = Microsoft.Xna.Framework.Color;
|
using Color = Microsoft.Xna.Framework.Color;
|
||||||
using System;
|
using System;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
namespace Subsurface
|
namespace Subsurface
|
||||||
{
|
{
|
||||||
@@ -44,8 +45,15 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
#if WINDOWS
|
||||||
using (Stream fileStream = File.OpenRead(path))
|
using (Stream fileStream = File.OpenRead(path))
|
||||||
return FromStream(fileStream, preMultiplyAlpha);
|
return FromStream(fileStream, preMultiplyAlpha);
|
||||||
|
#endif
|
||||||
|
#if LINUX
|
||||||
|
using (Stream fileStream = File.OpenRead(path))
|
||||||
|
return Texture2D.FromFile(_graphicsDevice, fileStream);// .FromStream(fileStream, preMultiplyAlpha);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -55,7 +63,8 @@ namespace Subsurface
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Texture2D FromStream(Stream stream, bool preMultiplyAlpha = true)
|
#if WINDOWS
|
||||||
|
private Texture2D FromStream(Stream stream, bool preMultiplyAlpha = true)
|
||||||
{
|
{
|
||||||
Texture2D texture;
|
Texture2D texture;
|
||||||
|
|
||||||
@@ -114,6 +123,8 @@ namespace Subsurface
|
|||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
private static readonly BlendState BlendColorBlendState;
|
private static readonly BlendState BlendColorBlendState;
|
||||||
private static readonly BlendState BlendAlphaBlendState;
|
private static readonly BlendState BlendAlphaBlendState;
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
font = contentManager.Load<SpriteFont>(file);
|
font = contentManager.Load<SpriteFont>(file);
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Loading font ''"+file+"'' failed");
|
DebugConsole.ThrowError("Loading font ''"+file+"'' failed", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return font;
|
return font;
|
||||||
|
|||||||
@@ -6336,9 +6336,6 @@
|
|||||||
</timestamps>
|
</timestamps>
|
||||||
<violations />
|
<violations />
|
||||||
</sourcecode>
|
</sourcecode>
|
||||||
<project key="2115933639">
|
|
||||||
<configuration>DEBUG;TRACE;WINDOWS</configuration>
|
|
||||||
</project>
|
|
||||||
<sourcecode name="GameMode.cs" parser="StyleCop.CSharp.CsParser">
|
<sourcecode name="GameMode.cs" parser="StyleCop.CSharp.CsParser">
|
||||||
<timestamps>
|
<timestamps>
|
||||||
<styleCop>2014.04.01 10:18:24.000</styleCop>
|
<styleCop>2014.04.01 10:18:24.000</styleCop>
|
||||||
@@ -6464,4 +6461,30 @@
|
|||||||
</timestamps>
|
</timestamps>
|
||||||
<violations />
|
<violations />
|
||||||
</sourcecode>
|
</sourcecode>
|
||||||
|
<project key="2115933639">
|
||||||
|
<configuration>DEBUG;TRACE;WINDOWS</configuration>
|
||||||
|
</project>
|
||||||
|
<sourcecode name="ItemLabel.cs" parser="StyleCop.CSharp.CsParser">
|
||||||
|
<timestamps>
|
||||||
|
<styleCop>2014.04.01 10:18:24.000</styleCop>
|
||||||
|
<settingsFile>2015.07.02 21:22:42.115</settingsFile>
|
||||||
|
<sourceFile>2015.08.21 17:49:13.627</sourceFile>
|
||||||
|
<parser>2014.04.01 10:18:24.000</parser>
|
||||||
|
<StyleCop.CSharp.DocumentationRules>2014.04.01 10:18:24.000</StyleCop.CSharp.DocumentationRules>
|
||||||
|
<StyleCop.CSharp.DocumentationRules.FilesHashCode>-1945363787</StyleCop.CSharp.DocumentationRules.FilesHashCode>
|
||||||
|
<StyleCop.CSharp.LayoutRules>2014.04.01 10:18:24.000</StyleCop.CSharp.LayoutRules>
|
||||||
|
<StyleCop.CSharp.LayoutRules.FilesHashCode>0</StyleCop.CSharp.LayoutRules.FilesHashCode>
|
||||||
|
<StyleCop.CSharp.MaintainabilityRules>2014.04.01 10:18:24.000</StyleCop.CSharp.MaintainabilityRules>
|
||||||
|
<StyleCop.CSharp.MaintainabilityRules.FilesHashCode>0</StyleCop.CSharp.MaintainabilityRules.FilesHashCode>
|
||||||
|
<StyleCop.CSharp.NamingRules>2014.04.01 10:18:24.000</StyleCop.CSharp.NamingRules>
|
||||||
|
<StyleCop.CSharp.NamingRules.FilesHashCode>0</StyleCop.CSharp.NamingRules.FilesHashCode>
|
||||||
|
<StyleCop.CSharp.OrderingRules>2014.04.01 10:18:24.000</StyleCop.CSharp.OrderingRules>
|
||||||
|
<StyleCop.CSharp.OrderingRules.FilesHashCode>0</StyleCop.CSharp.OrderingRules.FilesHashCode>
|
||||||
|
<StyleCop.CSharp.ReadabilityRules>2014.04.01 10:18:24.000</StyleCop.CSharp.ReadabilityRules>
|
||||||
|
<StyleCop.CSharp.ReadabilityRules.FilesHashCode>0</StyleCop.CSharp.ReadabilityRules.FilesHashCode>
|
||||||
|
<StyleCop.CSharp.SpacingRules>2014.04.01 10:18:24.000</StyleCop.CSharp.SpacingRules>
|
||||||
|
<StyleCop.CSharp.SpacingRules.FilesHashCode>0</StyleCop.CSharp.SpacingRules.FilesHashCode>
|
||||||
|
</timestamps>
|
||||||
|
<violations />
|
||||||
|
</sourcecode>
|
||||||
</stylecopresultscache>
|
</stylecopresultscache>
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
<Optimize>true</Optimize>
|
<Optimize>true</Optimize>
|
||||||
<OutputPath>bin\Windows\Release\</OutputPath>
|
<OutputPath>bin\Windows\Release\</OutputPath>
|
||||||
@@ -76,7 +76,9 @@
|
|||||||
<Compile Include="Source\GUI\GUIMessage.cs" />
|
<Compile Include="Source\GUI\GUIMessage.cs" />
|
||||||
<Compile Include="Source\GUI\TitleScreen.cs" />
|
<Compile Include="Source\GUI\TitleScreen.cs" />
|
||||||
<Compile Include="Source\Items\Components\Label.cs" />
|
<Compile Include="Source\Items\Components\Label.cs" />
|
||||||
|
<Compile Include="Source\Items\Components\Signal\WifiComponent.cs" />
|
||||||
<Compile Include="Source\Items\Components\Signal\SignalCheckComponent.cs" />
|
<Compile Include="Source\Items\Components\Signal\SignalCheckComponent.cs" />
|
||||||
|
<Compile Include="Source\Items\Components\ItemLabel.cs" />
|
||||||
<Compile Include="Source\Items\FixRequirement.cs" />
|
<Compile Include="Source\Items\FixRequirement.cs" />
|
||||||
<Compile Include="Source\Map\Lights\Light.cs" />
|
<Compile Include="Source\Map\Lights\Light.cs" />
|
||||||
<Compile Include="Source\Map\LocationType.cs" />
|
<Compile Include="Source\Map\LocationType.cs" />
|
||||||
@@ -301,6 +303,9 @@
|
|||||||
<Content Include="Content\Items\Artifacts\artifacts.xml">
|
<Content Include="Content\Items\Artifacts\artifacts.xml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="Content\Items\blank.png">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Include="Content\Items\Clothes\captainLegs.png">
|
<Content Include="Content\Items\Clothes\captainLegs.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
@@ -310,6 +315,15 @@
|
|||||||
<Content Include="Content\Items\Electricity\lamp.png">
|
<Content Include="Content\Items\Electricity\lamp.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="Content\Items\Electricity\supercapacitor.png">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="Content\Items\Electricity\wifi.png">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="Content\Items\Electricity\regex.png">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Include="Content\Items\Electricity\lights.xml">
|
<Content Include="Content\Items\Electricity\lights.xml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
@@ -320,6 +334,9 @@
|
|||||||
<Content Include="Content\Items\Electricity\monitors.xml">
|
<Content Include="Content\Items\Electricity\monitors.xml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="Content\Items\itemlabel.xml">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Include="Content\Items\Medical\medical.xml">
|
<Content Include="Content\Items\Medical\medical.xml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
@@ -557,7 +574,7 @@
|
|||||||
<Content Include="Content\Items\Electricity\junctionbox.png">
|
<Content Include="Content\Items\Electricity\junctionbox.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="Content\Items\Ladder\item.xml">
|
<Content Include="Content\Items\Ladder\ladder.xml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="Content\Items\Ladder\ladder.png">
|
<Content Include="Content\Items\Ladder\ladder.png">
|
||||||
@@ -580,6 +597,7 @@
|
|||||||
</Content>
|
</Content>
|
||||||
<Content Include="Content\Items\Electricity\poweritems.xml">
|
<Content Include="Content\Items\Electricity\poweritems.xml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="Content\Items\Weapons\railgun.xml">
|
<Content Include="Content\Items\Weapons\railgun.xml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
|||||||
@@ -1,4 +1,58 @@
|
|||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
v0.1.3.2
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Multiplayer:
|
||||||
|
- some major opimization to networked messages (less lag)
|
||||||
|
- option to disable UPnP port forwarding (which may have prevented some from hosting a server)
|
||||||
|
- a new round can't be started if a submarine hasn't been selected (which used to crash the game)
|
||||||
|
- maximum number of players can be changed
|
||||||
|
- fixed a bug in the net lobby screen that disabled the start button when the chat box was scrolled
|
||||||
|
to a specific position
|
||||||
|
- a window that displays some network statistics when hosting a server (can be activated by entering
|
||||||
|
"debugview" to the debug console)
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
v0.1.3.1
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Multiplayer:
|
||||||
|
- chat messages are sent reliably
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
v0.1.3
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Multiplayer:
|
||||||
|
- fixed master server connection errors in server list screen
|
||||||
|
- fixed a bug that caused other characters to get "stuck" to the railgun controller, causing them
|
||||||
|
to fly back to it as they try to move away
|
||||||
|
|
||||||
|
Items:
|
||||||
|
- putting items inside other items works properly now (i.e. by pulling a spear to the same slot as
|
||||||
|
a harpoon, not the other way around)
|
||||||
|
- C4 blocks loaded inside a railgun shell won't explode inside the submarine when firing the railgun
|
||||||
|
- fixed another game-crashing railgun bug
|
||||||
|
- fixed a bug that caused characters to spawn with an incorrect number of items
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
v0.1.2
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Multiplayer:
|
||||||
|
- a "lobby screen" showing a list of servers that are currently running
|
||||||
|
- password protected servers
|
||||||
|
- traitor rounds end when the traitor dies/disconnects or if the submarine reaches the end of the level
|
||||||
|
|
||||||
|
Items:
|
||||||
|
- fixed the crashing when firing the railgun or activating a detonator
|
||||||
|
|
||||||
|
Other:
|
||||||
|
- optimized lightning and "line of sight" rendering
|
||||||
|
- an unfinished tutorial which can currently only be accessed by entering "tutorial" into the
|
||||||
|
debug console
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------
|
||||||
v0.1.1
|
v0.1.1
|
||||||
---------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -17,6 +17,31 @@ http://subsurface.gamepedia.com
|
|||||||
|
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Port forwarding:
|
||||||
|
You may try to forward ports on your router using UPnP (Universal Plug and
|
||||||
|
Play) port forwarding by selecting "Attempt UPnP port forwarding" in the
|
||||||
|
"Host Server" menu.
|
||||||
|
|
||||||
|
However, UPnP isn't supported by all routers, so you may need to setup port
|
||||||
|
forwards manually. The exact steps for forwarding a port depend on your
|
||||||
|
router's model, but you may you may be able to find a port forwarding
|
||||||
|
guide for your particular router/application on portforward.com or by
|
||||||
|
practicing your google-fu skills.
|
||||||
|
|
||||||
|
These are the values that you should use when forwarding a port to your
|
||||||
|
Subsurface server:
|
||||||
|
|
||||||
|
Service/Application: subsurface
|
||||||
|
External Port: The port you have selected for your server (14242 by default)
|
||||||
|
Internal Port: The port you have selected for your server (14242 by default)
|
||||||
|
Protocol: UDP
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
Credits:
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
Programming, graphics, sounds, game design - Joonas Rikkonen ("Regalis")
|
Programming, graphics, sounds, game design - Joonas Rikkonen ("Regalis")
|
||||||
Graphics - James Bear ("Moonsaber99")
|
Graphics - James Bear ("Moonsaber99")
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -1,4 +1,6 @@
|
|||||||
Content\SpriteFont1.xnb
|
Content\SpriteFont1.xnb
|
||||||
Content\SmallFont.xnb
|
Content\SmallFont.xnb
|
||||||
|
Content\LargeFont.xnb
|
||||||
Content\SpriteFont1.spritefont
|
Content\SpriteFont1.spritefont
|
||||||
Content\SmallFont.spritefont
|
Content\SmallFont.spritefont
|
||||||
|
Content\LargeFont.spritefont
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
Content\SpriteFont1.xnb
|
||||||
|
Content\SmallFont.xnb
|
||||||
|
Content\LargeFont.xnb
|
||||||
|
Content\SpriteFont1.spritefont
|
||||||
|
Content\SmallFont.spritefont
|
||||||
|
Content\LargeFont.spritefont
|
||||||
Binary file not shown.
Binary file not shown.
+2
@@ -1,4 +1,6 @@
|
|||||||
Content\SpriteFont1.xnb
|
Content\SpriteFont1.xnb
|
||||||
Content\SmallFont.xnb
|
Content\SmallFont.xnb
|
||||||
|
Content\LargeFont.xnb
|
||||||
Content\SpriteFont1.spritefont
|
Content\SpriteFont1.spritefont
|
||||||
Content\SmallFont.spritefont
|
Content\SmallFont.spritefont
|
||||||
|
Content\LargeFont.spritefont
|
||||||
|
|||||||
+25
-7
@@ -7,8 +7,26 @@
|
|||||||
<Importer>FontDescriptionImporter</Importer>
|
<Importer>FontDescriptionImporter</Importer>
|
||||||
<Processor>FontDescriptionProcessor</Processor>
|
<Processor>FontDescriptionProcessor</Processor>
|
||||||
<Options>None</Options>
|
<Options>None</Options>
|
||||||
<Output>C:\Users\Joonas\Desktop\SBMR_3011\Sbmr_content\Sbmr_content\bin\Windows\Content\SpriteFont1.xnb</Output>
|
<Output>E:\Subsurface\Subsurface_content\Subsurface_content\bin\Windows\Content\SpriteFont1.xnb</Output>
|
||||||
<Time>2014-08-09T18:03:17.8614245+03:00</Time>
|
<Time>2015-07-19T00:51:29.3427566+03:00</Time>
|
||||||
|
</Item>
|
||||||
|
<Item>
|
||||||
|
<Source>SmallFont.spritefont</Source>
|
||||||
|
<Name>SmallFont</Name>
|
||||||
|
<Importer>FontDescriptionImporter</Importer>
|
||||||
|
<Processor>FontDescriptionProcessor</Processor>
|
||||||
|
<Options>None</Options>
|
||||||
|
<Output>E:\Subsurface\Subsurface_content\Subsurface_content\bin\Windows\Content\SmallFont.xnb</Output>
|
||||||
|
<Time>2015-07-19T00:51:26.3565858+03:00</Time>
|
||||||
|
</Item>
|
||||||
|
<Item>
|
||||||
|
<Source>LargeFont.spritefont</Source>
|
||||||
|
<Name>LargeFont</Name>
|
||||||
|
<Importer>FontDescriptionImporter</Importer>
|
||||||
|
<Processor>FontDescriptionProcessor</Processor>
|
||||||
|
<Options>None</Options>
|
||||||
|
<Output>E:\Subsurface\Subsurface_content\Subsurface_content\bin\Windows\Content\LargeFont.xnb</Output>
|
||||||
|
<Time>2015-08-13T19:53:28.5907374+03:00</Time>
|
||||||
</Item>
|
</Item>
|
||||||
<BuildSuccessful>true</BuildSuccessful>
|
<BuildSuccessful>true</BuildSuccessful>
|
||||||
<Settings>
|
<Settings>
|
||||||
@@ -17,15 +35,15 @@
|
|||||||
<TargetProfile>HiDef</TargetProfile>
|
<TargetProfile>HiDef</TargetProfile>
|
||||||
<BuildConfiguration>Windows</BuildConfiguration>
|
<BuildConfiguration>Windows</BuildConfiguration>
|
||||||
<CompressContent>false</CompressContent>
|
<CompressContent>false</CompressContent>
|
||||||
<RootDirectory>C:\Users\Joonas\Desktop\SBMR_3011\Sbmr_content\Sbmr_contentContent\</RootDirectory>
|
<RootDirectory>E:\Subsurface\Subsurface_content\Subsurface_contentContent\</RootDirectory>
|
||||||
<LoggerRootDirectory>C:\Users\Joonas\Desktop\SBMR_3011\Sbmr_content\Sbmr_content\</LoggerRootDirectory>
|
<LoggerRootDirectory>E:\Subsurface\Subsurface_content\Subsurface_content\</LoggerRootDirectory>
|
||||||
<IntermediateDirectory>C:\Users\Joonas\Desktop\SBMR_3011\Sbmr_content\Sbmr_content\obj\Windows\</IntermediateDirectory>
|
<IntermediateDirectory>E:\Subsurface\Subsurface_content\Subsurface_content\obj\Windows\</IntermediateDirectory>
|
||||||
<OutputDirectory>C:\Users\Joonas\Desktop\SBMR_3011\Sbmr_content\Sbmr_content\bin\Windows\Content\</OutputDirectory>
|
<OutputDirectory>E:\Subsurface\Subsurface_content\Subsurface_content\bin\Windows\Content\</OutputDirectory>
|
||||||
</Settings>
|
</Settings>
|
||||||
<Assemblies>
|
<Assemblies>
|
||||||
<Assembly>
|
<Assembly>
|
||||||
<Key>C:\Program Files (x86)\MSBuild\MonoGame\v3.0\MonoGameContentProcessors.dll</Key>
|
<Key>C:\Program Files (x86)\MSBuild\MonoGame\v3.0\MonoGameContentProcessors.dll</Key>
|
||||||
<Value>2014-04-06T00:56:18+03:00</Value>
|
<Value>2015-02-12T06:10:24+02:00</Value>
|
||||||
</Assembly>
|
</Assembly>
|
||||||
<Assembly>
|
<Assembly>
|
||||||
<Key>C:\Program Files (x86)\Microsoft XNA\XNA Game Studio\v4.0\References\Windows\x86\Microsoft.Xna.Framework.Content.Pipeline.XImporter.dll</Key>
|
<Key>C:\Program Files (x86)\Microsoft XNA\XNA Game Studio\v4.0\References\Windows\x86\Microsoft.Xna.Framework.Content.Pipeline.XImporter.dll</Key>
|
||||||
|
|||||||
BIN
Binary file not shown.
Binary file not shown.
+5
@@ -1 +1,6 @@
|
|||||||
Content\SpriteFont1.xnb
|
Content\SpriteFont1.xnb
|
||||||
|
Content\SmallFont.xnb
|
||||||
|
Content\LargeFont.xnb
|
||||||
|
Content\SpriteFont1.spritefont
|
||||||
|
Content\SmallFont.spritefont
|
||||||
|
Content\LargeFont.spritefont
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
This file contains an xml description of a font, and will be read by the XNA
|
||||||
|
Framework Content Pipeline. Follow the comments to customize the appearance
|
||||||
|
of the font in your game, and to change the characters which are available to draw
|
||||||
|
with.
|
||||||
|
-->
|
||||||
|
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
|
||||||
|
<Asset Type="Graphics:FontDescription">
|
||||||
|
|
||||||
|
<FontName>Verdana</FontName>
|
||||||
|
|
||||||
|
<Size>16</Size>
|
||||||
|
|
||||||
|
<Spacing>0</Spacing>
|
||||||
|
|
||||||
|
<UseKerning>true</UseKerning>
|
||||||
|
|
||||||
|
<Style>Bold</Style>
|
||||||
|
|
||||||
|
<DefaultCharacter>_</DefaultCharacter>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
CharacterRegions control what letters are available in the font. Every
|
||||||
|
character from Start to End will be built and made available for drawing. The
|
||||||
|
default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin
|
||||||
|
character set. The characters are ordered according to the Unicode standard.
|
||||||
|
See the documentation for more information.
|
||||||
|
-->
|
||||||
|
<CharacterRegions>
|
||||||
|
<CharacterRegion>
|
||||||
|
<Start> </Start>
|
||||||
|
<End>~</End>
|
||||||
|
</CharacterRegion>
|
||||||
|
|
||||||
|
<CharacterRegion>
|
||||||
|
<Start>À</Start>
|
||||||
|
<End>ə</End>
|
||||||
|
</CharacterRegion>
|
||||||
|
</CharacterRegions>
|
||||||
|
</Asset>
|
||||||
|
</XnaContent>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user