+ character input keys in array instead of separate variables
This commit is contained in:
Regalis11
2015-08-22 16:57:57 +03:00
102 changed files with 1847 additions and 709 deletions
+1 -2
View File
@@ -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>();
+3
View File
@@ -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
View File
@@ -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

+2 -2
View File
@@ -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>
+14
View File
@@ -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>
+2 -2
View File
@@ -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"/>
+7
View File
@@ -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"
+2 -2
View File
@@ -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
View File
@@ -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)
+101 -98
View File
@@ -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);
+3 -3
View File
@@ -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)
{ {
+4
View File
@@ -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;
+5
View File
@@ -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
} }
} }
+11 -3
View File
@@ -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);
}
} }
+1 -1
View File
@@ -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)
+9 -1
View File
@@ -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())
+6
View File
@@ -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"})
{ {
+2 -2
View File
@@ -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);
+6 -7
View File
@@ -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);
+2 -1
View File
@@ -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();
+28 -7
View File
@@ -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);
}
} }
} }
} }
+6 -4
View File
@@ -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;
} }
+1 -1
View File
@@ -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);
}
}
}
+4 -1
View File
@@ -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);
}
}
}
+24 -26
View File
@@ -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);
+26 -11
View File
@@ -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))
{ {
+1 -1
View File
@@ -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;
+5
View File
@@ -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
+1 -1
View File
@@ -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;
} }
+4 -1
View File
@@ -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
} }
} }
+11 -11
View File
@@ -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;
+9 -2
View File
@@ -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
} }
} }
+96 -23
View File
@@ -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>
+179 -34
View File
@@ -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);
} }
} }
+5 -2
View File
@@ -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; }
+40 -9
View File
@@ -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
View File
@@ -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;
} }
} }
} }
} }
+7
View File
@@ -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)]
+1 -1
View File
@@ -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)
+3 -2
View File
@@ -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;
+1 -1
View File
@@ -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;
+52 -34
View File
@@ -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;
//}
}
} }
} }
+16 -50
View File
@@ -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;
//}
} }
} }
+1 -1
View File
@@ -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; }
+147 -24
View File
@@ -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;
+18 -3
View File
@@ -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);
+24 -21
View File
@@ -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();
} }
+13 -1
View File
@@ -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)
{ {
+9 -4
View File
@@ -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)
+12 -1
View File
@@ -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;
+2 -2
View File
@@ -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;
+26 -3
View File
@@ -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>
+20 -2
View File
@@ -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>
+54
View File
@@ -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
--------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------
+25
View File
@@ -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
@@ -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
@@ -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>
@@ -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>&#32;</Start>
<End>&#126;</End>
</CharacterRegion>
<CharacterRegion>
<Start>&#192;</Start>
<End>&#601;</End>
</CharacterRegion>
</CharacterRegions>
</Asset>
</XnaContent>

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