+ 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 static string ContentPackageFolder = "Data/ContentPackages/";
private const string configPath = "config.xml";
private Subsurface.GameSettings settings;
@@ -42,7 +41,7 @@ namespace Launcher
{
InitializeComponent();
ContentPackage.LoadAll(LauncherMain.ContentPackageFolder);
ContentPackage.LoadAll(ContentPackage.Folder);
contentPackageBox.DataSource = ContentPackage.list;
supportedModes = new List<GraphicsMode>();
+3
View File
@@ -102,6 +102,7 @@
this.itemList.Name = "itemList";
this.itemList.Size = new System.Drawing.Size(255, 134);
this.itemList.TabIndex = 8;
this.itemList.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.fileList_KeyPress);
//
// itemButton
//
@@ -161,6 +162,7 @@
this.structureList.Name = "structureList";
this.structureList.Size = new System.Drawing.Size(255, 121);
this.structureList.TabIndex = 8;
this.structureList.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.fileList_KeyPress);
//
// structureButton
//
@@ -189,6 +191,7 @@
this.jobList.Name = "jobList";
this.jobList.Size = new System.Drawing.Size(255, 134);
this.jobList.TabIndex = 11;
this.jobList.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.fileList_KeyPress);
//
// label4
//
+17 -20
View File
@@ -96,28 +96,25 @@ namespace Launcher
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();
}
}
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);
}
if (file.type != type) continue;
fileBox.Items.Add(file);
}
}
}
private void newPackage_Click(object sender, EventArgs e)
@@ -145,7 +142,7 @@ namespace Launcher
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "XML files (*.xml)|*.xml;*.XML";
//ofd.RestoreDirectory?
ofd.RestoreDirectory = true;
if (ofd.ShowDialog() == DialogResult.OK)
{
@@ -256,7 +253,7 @@ namespace Launcher
private void okButton_Click(object sender, EventArgs e)
{
if (selectedPackage!=null) selectedPackage.Save(LauncherMain.ContentPackageFolder);
if (selectedPackage!=null) selectedPackage.Save(ContentPackage.Folder);
this.Close();
}
@@ -41,7 +41,27 @@
<ConnectionPanel canbeselected = "true" msg="Rewire [Screwdriver]">
<requireditem name="Screwdriver" type="Equipped"/>
<input name="power_in"/>
<input name="power"/>
</ConnectionPanel>
</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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 231 B

@@ -185,7 +185,7 @@
linkable="true"
price="10">
<Sprite texture ="light.png" depth="0.8"/>
<Sprite texture ="regex.png" depth="0.8"/>
<RegExFindComponent canbeselected = "true"/>
@@ -203,5 +203,30 @@
</ConnectionPanel>
</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>
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]">
<requireditem name="Screwdriver" type="Equipped"/>
<output name="power_out"/>
<output name="temperature_out"/>
<input name="shutdown"/>
</ConnectionPanel>
<ItemContainer capacity="5">
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

+2 -2
View File
@@ -5,9 +5,9 @@
Tags="smallitem"
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/>
</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>
</Captain>
<Engineer>
<Engineer minnumber="1">
<Skills>
<Skill name="Weapons" level="10,30"/>
<Skill name="Construction" level="30,40"/>
@@ -24,7 +24,7 @@
<Item name="Screwdriver"/>
</Engineer>
<Mechanic>
<Mechanic minnumber="1">
<Skills>
<Skill name="Weapons" level="10,30"/>
<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"/>
</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
padding="40.0, 40.0, 40.0, 40.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
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.1.1.0")]
[assembly: AssemblyFileVersion("0.1.1.0")]
[assembly: AssemblyVersion("0.1.3.2")]
[assembly: AssemblyFileVersion("0.1.3.2")]
+30 -12
View File
@@ -18,12 +18,13 @@ namespace Subsurface
private Vector2 position;
private float rotation;
private Vector2 prevPosition;
private float prevZoom;
public float Shake;
private Vector2 shakePosition;
private Vector2 shakeTargetPosition;
//the area of the world inside the camera view
private Rectangle worldView;
@@ -130,9 +131,9 @@ namespace Subsurface
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.Y = (int)(interpolatedPosition.Y + worldView.Height / 2.0);
@@ -154,13 +155,19 @@ namespace Subsurface
{
float moveSpeed = 20.0f/zoom;
prevPosition = position;
prevZoom = zoom;
Vector2 moveCam = 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 (Keyboard.GetState().IsKeyDown(Keys.S)) moveCam.Y -= moveSpeed;
if (Keyboard.GetState().IsKeyDown(Keys.W)) moveCam.Y += moveSpeed;
if (PlayerInput.KeyDown(Keys.A)) moveCam.X -= moveSpeed;
if (PlayerInput.KeyDown(Keys.D)) moveCam.X += 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);
}
@@ -179,15 +186,26 @@ namespace Subsurface
float newZoom = Math.Min(DefaultZoom - Math.Min(offset.Length() / resolution.Y, 1.0f),1.0f);
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);
shakePosition = Vector2.Lerp(shakePosition, shakeTargetPosition, 0.5f);
Shake = MathHelper.Lerp(Shake, 0.0f, 0.03f);
Translate((moveCam+shakePosition)*deltaTime*60.0f);
Translate(moveCam+shakePosition);
}
public Vector2 Position
@@ -43,7 +43,7 @@ namespace Subsurface
steeringManager = new SteeringManager(this);
}
public virtual void SelectTarget(IDamageable target) { }
public virtual void SelectTarget(AITarget target) { }
public virtual void Update(float deltaTime) { }
@@ -82,11 +82,10 @@ namespace Subsurface
state = AiState.None;
}
public override void SelectTarget(IDamageable target)
public override void SelectTarget(AITarget target)
{
targetEntity = target;
selectedAiTarget = target.AiTarget;
selectedTargetMemory = FindTargetMemory(target.AiTarget);
selectedAiTarget = target;
selectedTargetMemory = FindTargetMemory(target);
targetValue = 100.0f;
}
@@ -470,14 +469,21 @@ namespace Subsurface
public override void FillNetworkData(NetOutgoingMessage message)
{
message.Write((byte)state);
bool wallAttack = (wallAttackPos!=Vector2.Zero && state == AiState.Attack);
message.Write(wallAttackPos.X);
message.Write(wallAttackPos.Y);
message.Write(wallAttack);
message.Write(steeringManager.WanderAngle);
message.Write(updateTargetsTimer);
message.Write(raycastTimer);
message.Write(coolDownTimer);
if (wallAttack)
{
message.Write(wallAttackPos.X);
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);
}
@@ -485,7 +491,7 @@ namespace Subsurface
public override void ReadNetworkData(NetIncomingMessage message)
{
AiState newState = AiState.None;
Vector2 newWallAttackPos;
Vector2 newWallAttackPos = Vector2.Zero;
float wanderAngle;
float updateTargetsTimer, raycastTimer, coolDownTimer;
@@ -495,12 +501,18 @@ namespace Subsurface
{
newState = (AiState)(message.ReadByte());
newWallAttackPos = new Vector2(message.ReadFloat(), message.ReadFloat());
wanderAngle = MathUtils.WrapAngleTwoPi(message.ReadFloat());
updateTargetsTimer = MathHelper.Clamp(message.ReadFloat(), 0.0f, UpdateTargetsInterval);
raycastTimer = MathHelper.Clamp(message.ReadFloat(), 0.0f, RaycastInterval);
coolDownTimer = MathHelper.Clamp(message.ReadFloat(), 0.0f, attackCoolDown);
bool wallAttack = message.ReadBoolean();
if (wallAttack)
{
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();
}
@@ -31,7 +31,11 @@ namespace Subsurface
public float StunTimer
{
get { return stunTimer; }
set { stunTimer = value; }
set
{
if (float.IsNaN(value) || float.IsInfinity(value)) return;
stunTimer = value;
}
}
public AnimController(Character character, XElement element)
+101 -98
View File
@@ -36,7 +36,7 @@ namespace Subsurface
private CharacterInventory inventory;
public double LastNetworkUpdate;
public float LastNetworkUpdate;
public int LargeUpdateTimer;
@@ -46,9 +46,11 @@ namespace Subsurface
get { return Properties; }
}
protected Key selectKeyHit;
protected Key actionKeyHit, actionKeyDown;
protected Key secondaryKeyHit, secondaryKeyDown;
protected Key[] keys;
//protected Key selectKeyHit;
//protected Key actionKeyHit, actionKeyDown;
//protected Key secondaryKeyHit, secondaryKeyDown;
private Item selectedConstruction;
private Item[] selectedItems;
@@ -244,31 +246,6 @@ namespace Subsurface
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
{
get { return aiController; }
@@ -311,12 +288,13 @@ namespace Subsurface
public Character(string file, Vector2 position, CharacterInfo characterInfo = null, bool isNetworkPlayer = false)
{
selectKeyHit = new Key(false);
actionKeyDown = new Key(true);
actionKeyHit = new Key(false);
secondaryKeyHit = new Key(false);
secondaryKeyDown = new Key(true);
keys = new Key[5];
keys[(int)InputType.Select] = new Key(false);
keys[(int)InputType.ActionHeld] = new Key(true);
keys[(int)InputType.ActionHit] = new Key(false);
keys[(int)InputType.SecondaryHit] = new Key(false);
keys[(int)InputType.SecondaryHeld] = new Key(true);
selectedItems = new Item[2];
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)
{
if (info == null || info.Job == null) return;
@@ -482,7 +470,7 @@ namespace Subsurface
if (closestItem != null)
{
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);
}
@@ -492,7 +480,7 @@ namespace Subsurface
if (closestCharacter != selectedCharacter) selectedCharacter = 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 (i == 1 && selectedItems[0] == selectedItems[1]) continue;
if (actionKeyDown.State) selectedItems[i].Use(deltaTime, this);
if (secondaryKeyDown.State && selectedItems[i] != null) selectedItems[i].SecondaryUse(deltaTime, this);
if (GetInputState(InputType.ActionHeld)) selectedItems[i].Use(deltaTime, this);
if (GetInputState(InputType.SecondaryHeld) && selectedItems[i] != null) selectedItems[i].SecondaryUse(deltaTime, this);
}
if (selectedConstruction != null)
{
if (actionKeyDown.State) selectedConstruction.Use(deltaTime, this);
if (secondaryKeyDown.State) selectedConstruction.SecondaryUse(deltaTime, this);
if (GetInputState(InputType.ActionHeld)) selectedConstruction.Use(deltaTime, this);
if (GetInputState(InputType.SecondaryHeld)) selectedConstruction.SecondaryUse(deltaTime, this);
}
if (IsNetworkPlayer)
{
selectKeyHit.Reset();
actionKeyHit.Reset();
actionKeyDown.Reset();
secondaryKeyHit.Reset();
secondaryKeyDown.Reset();
foreach (Key key in keys)
{
key.Reset();
}
}
}
@@ -589,19 +576,19 @@ namespace Subsurface
if (Keyboard.GetState().IsKeyDown(Keys.LeftShift) && Math.Sign(targetMovement.X) == Math.Sign(AnimController.Dir))
targetMovement *= 3.0f;
selectKeyHit.SetState(PlayerInput.KeyHit(Keys.E));
actionKeyHit.SetState(PlayerInput.LeftButtonClicked());
actionKeyDown.SetState(PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed);
secondaryKeyHit.SetState(PlayerInput.RightButtonClicked());
secondaryKeyDown.SetState(PlayerInput.GetMouseState.RightButton == ButtonState.Pressed);
keys[(int)InputType.Select].SetState(PlayerInput.KeyHit(Keys.E));
keys[(int)InputType.ActionHit].SetState(PlayerInput.LeftButtonClicked());
keys[(int)InputType.ActionHeld].SetState(PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed);
keys[(int)InputType.SecondaryHit].SetState(PlayerInput.RightButtonClicked());
keys[(int)InputType.SecondaryHeld].SetState(PlayerInput.GetMouseState.RightButton == ButtonState.Pressed);
}
else
{
selectKeyHit.SetState(false);
actionKeyHit.SetState(false);
actionKeyDown.SetState(false);
secondaryKeyHit.SetState(false);
secondaryKeyDown.SetState(false);
foreach (Key key in keys)
{
key.SetState(false);
}
}
AnimController.TargetMovement = targetMovement;
@@ -629,7 +616,6 @@ namespace Subsurface
}
}
if (AnimController.onGround &&
!AnimController.InWater &&
AnimController.Anim != AnimController.Animation.UsingConstruction)
@@ -1020,26 +1006,28 @@ namespace Subsurface
{
return;
}
else if (type== NetworkEventType.NotMoving)
{
return;
}
//if (type == Networking.NetworkEventType.KeyHit)
//{
// message.Write(selectKeyHit.Dequeue);
message.Write(actionKeyDown.Dequeue);
message.Write(secondaryKeyDown.Dequeue);
//}
message.Write(NetTime.Now);
message.Write(keys[(int)InputType.ActionHeld].Dequeue);
message.Write(keys[(int)InputType.SecondaryHeld].Dequeue);
message.Write((float)NetTime.Now);
// Write byte = move direction
message.Write(AnimController.TargetMovement.X);
message.Write(AnimController.TargetMovement.Y);
message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.X, -10.0f, 10.0f), -10.0f, 10.0f, 8);
message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.Y, -10.0f, 10.0f), -10.0f, 10.0f, 8);
message.Write(AnimController.TargetDir==Direction.Right);
message.Write(cursorPosition.X);
message.Write(cursorPosition.Y);
if (aiController==null)
{
message.Write(cursorPosition.X);
message.Write(cursorPosition.Y);
}
message.Write(LargeUpdateTimer <= 0);
if (LargeUpdateTimer<=0)
@@ -1050,32 +1038,31 @@ namespace Subsurface
message.Write(limb.body.Position.X);
message.Write(limb.body.Position.Y);
message.Write(limb.body.LinearVelocity.X);
message.Write(limb.body.LinearVelocity.Y);
//message.Write(limb.body.LinearVelocity.X);
//message.Write(limb.body.LinearVelocity.Y);
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++;
}
message.Write(AnimController.StunTimer);
message.Write((byte)health);
message.WriteRangedSingle(MathHelper.Clamp(AnimController.StunTimer,0.0f,60.0f), 0.0f, 60.0f, 8);
message.Write((byte)((health/maxHealth)*255.0f));
LargeUpdateTimer = 5;
if (aiController != null) aiController.FillNetworkData(message);
LargeUpdateTimer = 10;
}
else
{
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.Y);
LargeUpdateTimer = Math.Max(0, LargeUpdateTimer-1);
}
if (aiController != null) aiController.FillNetworkData(message);
}
}
public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message)
@@ -1112,10 +1099,17 @@ namespace Subsurface
}
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 secondaryKeyState = false;
double sendingTime = 0.0f;
float sendingTime = 0.0f;
Vector2 targetMovement = Vector2.Zero;
bool targetDir = false;
Vector2 cursorPos = Vector2.Zero;
@@ -1125,12 +1119,20 @@ namespace Subsurface
actionKeyState = 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();
cursorPos = new Vector2(message.ReadFloat(), message.ReadFloat());
if (aiController==null)
{
cursorPos = new Vector2(
message.ReadFloat(),
message.ReadFloat());
}
}
catch
@@ -1140,8 +1142,8 @@ namespace Subsurface
AnimController.IsStanding = true;
actionKeyDown.State = actionKeyState;
secondaryKeyDown.State = secondaryKeyState;
keys[(int)InputType.ActionHeld].State = actionKeyState;
keys[(int)InputType.SecondaryHeld].State = secondaryKeyState;
if (sendingTime <= LastNetworkUpdate) return;
@@ -1162,11 +1164,11 @@ namespace Subsurface
pos.X = message.ReadFloat();
pos.Y = message.ReadFloat();
vel.X = message.ReadFloat();
vel.Y = message.ReadFloat();
//vel.X = message.ReadFloat();
//vel.Y = message.ReadFloat();
rotation = message.ReadFloat();
angularVel = message.ReadFloat();
//angularVel = message.ReadFloat();
}
catch
{
@@ -1175,10 +1177,10 @@ namespace Subsurface
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.TargetRotation = rotation;// +angularVel * (float)(deltaTime / 60.0);
limb.body.TargetAngularVelocity = angularVel;
limb.body.TargetAngularVelocity = limb.body.AngularVelocity;
}
}
@@ -1187,8 +1189,8 @@ namespace Subsurface
try
{
newStunTimer = message.ReadFloat();
newHealth = message.ReadByte();
newStunTimer = message.ReadRangedSingle(0.0f, 60.0f, 8);
newHealth = (message.ReadByte()/255.0f)*maxHealth;
}
catch { return; }
@@ -1196,6 +1198,8 @@ namespace Subsurface
Health = newHealth;
LargeUpdateTimer = 1;
if (aiController != null) aiController.ReadNetworkData(message);
}
else
{
@@ -1210,13 +1214,12 @@ namespace Subsurface
Limb torso = AnimController.GetLimb(LimbType.Torso);
if (torso == null) torso = AnimController.GetLimb(LimbType.Head);
torso.body.TargetPosition = pos;
LargeUpdateTimer = 0;
}
if (aiController != null) aiController.ReadNetworkData(message);
LastNetworkUpdate = sendingTime;
}
@@ -34,7 +34,7 @@ namespace Subsurface
{
get { return pickedItems; }
}
public Sprite HeadSprite
{
get
@@ -156,7 +156,7 @@ namespace Subsurface
break;
}
}
public GUIFrame CreateInfoFrame(Rectangle rect)
{
GUIFrame frame = new GUIFrame(rect, Color.Transparent);
@@ -269,7 +269,7 @@ namespace Subsurface
{
UpdateCharacterItems();
}
if (pickedItems.Count > 0)
{
charElement.Add(new XAttribute("items", string.Join(",", pickedItems)));
@@ -3,6 +3,7 @@ using System.Linq;
using System.Xml.Linq;
using FarseerPhysics;
using Microsoft.Xna.Framework;
using Subsurface.Items.Components;
namespace Subsurface
{
@@ -542,7 +543,7 @@ namespace Subsurface
void UpdateClimbing()
{
if (character.SelectedConstruction == null)
if (character.SelectedConstruction == null || character.SelectedConstruction.GetComponent<Ladder>()==null)
{
Anim = Animation.None;
return;
@@ -623,7 +624,12 @@ namespace Subsurface
torso.body.ApplyForce(climbForce * 40.0f * torso.Mass);
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);
//stop climbing if:
@@ -673,10 +679,10 @@ namespace Subsurface
Limb rightHand = GetLimb(LimbType.RightHand);
Limb rightArm = GetLimb(LimbType.RightArm);
Vector2 itemPos = character.SecondaryKeyDown.State ? aimPos : holdPos;
Vector2 itemPos = character.GetInputState(InputType.SecondaryHeld) ? aimPos : holdPos;
float itemAngle;
if (character.SecondaryKeyDown.State && itemPos != Vector2.Zero)
if (character.GetInputState(InputType.SecondaryHeld) && itemPos != Vector2.Zero)
{
Vector2 mousePos = ConvertUnits.ToSimUnits(character.CursorPosition);
+3 -3
View File
@@ -472,7 +472,7 @@ namespace Subsurface
inWater = 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;
}
@@ -562,7 +562,7 @@ namespace Subsurface
private void UpdateNetplayerPosition()
{
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;
@@ -603,7 +603,7 @@ namespace Subsurface
if (resetAll)
{
System.Diagnostics.Debug.WriteLine("resetall");
System.Diagnostics.Debug.WriteLine("reset ragdoll limb positions");
foreach (Limb limb in limbs)
{
+4
View File
@@ -15,6 +15,9 @@ namespace Subsurface
public class ContentPackage
{
public static string Folder = "Data/ContentPackages/";
public static List<ContentPackage> list = new List<ContentPackage>();
@@ -81,6 +84,7 @@ namespace Subsurface
{
ContentPackage newPackage = new ContentPackage("Content/Data/"+name);
newPackage.name = name;
newPackage.Path = Folder + name;
list.Add(newPackage);
return newPackage;
+5
View File
@@ -136,11 +136,13 @@ namespace Subsurface
public static void ExecuteCommand(string command, Game1 game)
{
#if !DEBUG
if (Game1.Client!=null)
{
ThrowError("Console commands are disabled in multiplayer mode");
return;
}
#endif
if (command == "") return;
string[] commands = command.Split(' ');
@@ -246,6 +248,9 @@ namespace Subsurface
hull.OxygenPercentage = 100.0f;
}
break;
case "tutorial":
TutorialMode.Start();
break;
case "lobbyscreen":
case "lobby":
Game1.LobbyScreen.Select();
@@ -1,6 +1,8 @@
using System;
using System.Threading;
#if WINDOWS
using System.Windows;
#endif
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
@@ -42,12 +44,14 @@ namespace EventInput
//ctrl-v
if (e.Character == 0x16)
{
#if WINDOWS
//XNA runs in Multiple Thread Apartment state, which cannot recieve clipboard
Thread thread = new Thread(PasteThread);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
_subscriber.ReceiveTextInput(_pasteResult);
#endif
}
else
{
@@ -74,6 +78,7 @@ namespace EventInput
}
}
#if WINDOWS
//Thread has to be in Single Thread Apartment state in order to receive clipboard
string _pasteResult = "";
[STAThread]
@@ -81,5 +86,7 @@ namespace EventInput
{
_pasteResult = Clipboard.ContainsText() ? Clipboard.GetText() : "";
}
#endif
}
}
+11 -3
View File
@@ -20,7 +20,7 @@ namespace Subsurface
public static GUIStyle style;
static Texture2D t;
public static SpriteFont Font, SmallFont;
public static SpriteFont Font, SmallFont, LargeFont;
private static GraphicsDevice graphicsDevice;
@@ -274,7 +274,7 @@ namespace Subsurface
bool clicked = false;
if (rect.Contains(PlayerInput.GetMouseState.Position))
if (rect.Contains(PlayerInput.MousePosition))
{
clicked = (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed);
@@ -301,8 +301,16 @@ namespace Subsurface
spriteBatch.DrawString(Font,
"Physics: " + Game1.World.UpdateTime
+ " - bodies: " + Game1.World.BodyList.Count
+ "Camera pos: " + Game1.GameScreen.Cam.Position,
+ " Camera pos: " + Game1.GameScreen.Cam.Position,
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)
{
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;
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed)
+9 -1
View File
@@ -27,6 +27,14 @@ namespace Subsurface
private bool enabled;
public GUIComponent Selected
{
get
{
return selected;
}
}
public object SelectedData
{
get
@@ -276,7 +284,7 @@ namespace Subsurface
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;
if (PlayerInput.LeftButtonClicked())
+6
View File
@@ -15,6 +15,12 @@ namespace Subsurface
//GUIFrame frame;
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)
: this(header, text, new string[] {"OK"})
{
+2 -2
View File
@@ -155,14 +155,14 @@ namespace Subsurface
int moveAmount;
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);
barScroll = (float)newX / ((float)frame.Rect.Width - (float)bar.Rect.Width);
}
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);
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.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)
@@ -117,11 +120,7 @@ namespace Subsurface
if (parent != null)
parent.AddChild(this);
//if (wrap)
//{
this.Wrap = wrap;
// this.text = ToolBox.WrapText(this.text, rect.Width);
//}
this.Wrap = wrap;
SetTextPos();
}
@@ -135,7 +134,7 @@ namespace Subsurface
if (Wrap && rect.Width>0)
{
//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);
+2 -1
View File
@@ -146,6 +146,7 @@ namespace Subsurface
public void Deselect()
{
Selected = false;
if (keyboardDispatcher.Subscriber == this) keyboardDispatcher.Subscriber = null;
}
@@ -158,7 +159,7 @@ namespace Subsurface
caretTimer += deltaTime;
caretVisible = ((caretTimer*1000.0f) % 1000) < 500;
if (rect.Contains(PlayerInput.GetMouseState.Position))
if (rect.Contains(PlayerInput.MousePosition))
{
state = ComponentState.Hover;
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)
: base(null)
{
@@ -35,15 +41,26 @@ namespace Subsurface
box.HoverColor = Color.Gray;
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)
{
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;
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed)
@@ -67,12 +84,16 @@ namespace Subsurface
public override void Draw(SpriteBatch spriteBatch)
{
if (rect.Width == 420)
{
int asd = 1;
}
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), Color.Green * 0.8f, true);
}
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);
}
}
}
+6 -4
View File
@@ -10,6 +10,7 @@ using Subsurface.Particles;
using System.Collections;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Input;
using System.Xml;
namespace Subsurface
{
@@ -119,8 +120,8 @@ namespace Subsurface
//TargetElapsedTime = new TimeSpan(0, 0, 0, 0, 55);
World = new World(new Vector2(0, -9.82f));
Settings.VelocityIterations = 2;
Settings.PositionIterations = 1;
FarseerPhysics.Settings.VelocityIterations = 2;
FarseerPhysics.Settings.PositionIterations = 1;
}
/// <summary>
@@ -165,6 +166,7 @@ namespace Subsurface
{
GUI.Font = ToolBox.TryLoadFont("SpriteFont1", Content);
GUI.SmallFont = ToolBox.TryLoadFont("SmallFont", Content);
GUI.LargeFont = ToolBox.TryLoadFont("LargeFont", Content);
sw = new Stopwatch();
@@ -263,7 +265,7 @@ namespace Subsurface
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);
@@ -323,4 +325,4 @@ namespace Subsurface
}
}
}
}
@@ -30,16 +30,7 @@ namespace Subsurface
base.Update(deltaTime);
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)
{
@@ -68,6 +59,35 @@ namespace Subsurface
endMessage += " task was to assassinate " + target.character.Info.Name + ". The task was succesful.";
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.taskManager.Tasks.Clear();
Game1.GameScreen.Select();
}
@@ -184,7 +186,7 @@ namespace Subsurface
+ " 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.");
while (Character.Controlled.Inventory.items.FirstOrDefault(i => i!=null && i.GetComponent<Wire>()!=null)==null)
while (!HasItem("Wire"))
{
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);
moloch.PlaySound(AIController.AiState.Attack);
//moloch.AIController.
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)
{
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;
do
{
moloch.AIController.SelectTarget(steering.Item);
for (int i = 0; i < window.SectionCount; i++)
moloch.AIController.SelectTarget(steering.Item.CurrentHull.AiTarget);
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;
broken = true;
break;
limb.body.LinearVelocity = new Vector2(limb.LinearVelocity.X, limb.LinearVelocity.Y + steeringDir.Y*0.01f);
}
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);
} 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;
}
+1 -1
View File
@@ -132,7 +132,7 @@ namespace Subsurface
if (Game1.Server!=null)
{
Game1.Server.EndGame(endMessage);
CoroutineManager.StartCoroutine(Game1.Server.EndGame(endMessage));
}
else if (Game1.Client==null)
@@ -139,12 +139,13 @@ namespace Subsurface
if (items[i] != null)
{
bool combined = false;
if (item.Combine(items[i]))
{
//PutItem(item, i, false, false);
combined = true;
}
else if (items[i].Combine(item))
//if (item.Combine(items[i]))
//{
// //PutItem(item, i, false, false);
// combined = true;
//}
//else
if (items[i].Combine(item))
{
//PutItem(items[i], i, false, false);
combined = true;
@@ -119,7 +119,6 @@ namespace Subsurface.Items.Components
(int)doorSprite.size.X,
(int)doorSprite.size.Y);
body = new PhysicsBody(BodyFactory.CreateRectangle(Game1.World,
ConvertUnits.ToSimUnits(Math.Max(doorRect.Width, 1)),
ConvertUnits.ToSimUnits(Math.Max(doorRect.Height, 1)),
@@ -101,7 +101,7 @@ namespace Subsurface.Items.Components
Msg = "";
}
if (attachedByDefault) Use(1.0f);
if (attachedByDefault || Screen.Selected == Game1.EditMapScreen) Use(1.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)
{
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;
reload = 1.0f;
@@ -102,7 +102,7 @@ namespace Subsurface.Items.Components
public override bool Use(float deltaTime, Character character = null)
{
if (character == null) return false;
if (!character.SecondaryKeyDown.State) return false;
if (!character.GetInputState(InputType.SecondaryHeld)) return false;
if (DoesUseFail(character)) return false;
@@ -146,7 +146,7 @@ namespace Subsurface.Items.Components
}
else if ((targetLimb = (targetBody.UserData as Limb)) != null)
{
if (character.SecondaryKeyDown.State)
if (character.GetInputState(InputType.SecondaryHeld))
{
targetLimb.character.Health += limbFixAmount;
//isActive = true;
@@ -28,7 +28,7 @@ namespace Subsurface.Items.Components
public override bool Use(float deltaTime, Character character = null)
{
if (character == null) return false;
if (!character.SecondaryKeyDown.State || throwing) return false;
if (!character.GetInputState(InputType.SecondaryHeld) || throwing) return false;
throwing = true;
@@ -60,7 +60,7 @@ namespace Subsurface.Items.Components
if (!item.body.Enabled) return;
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);
@@ -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();
}
catch
catch (Exception e)
{
#if DEBUG
DebugConsole.ThrowError("invalid network message", e);
#endif
return;
}
@@ -66,7 +66,9 @@ namespace Subsurface.Items.Components
{
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)
{
@@ -22,8 +22,9 @@ namespace Subsurface.Items.Components
get { return flowPercentage; }
set
{
if (float.IsNaN(flowPercentage)) return;
flowPercentage = MathHelper.Clamp(value,-100.0f,100.0f);
if (!MathUtils.IsValid(flowPercentage)) return;
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);
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);
}
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);
}
@@ -166,7 +167,7 @@ namespace Subsurface.Items.Components
public override void FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetOutgoingMessage message)
{
message.Write(flowPercentage);
message.Write(Convert.ToByte(flowPercentage+100));
message.Write(isActive);
}
@@ -177,11 +178,17 @@ namespace Subsurface.Items.Components
try
{
newFlow = message.ReadFloat();
newFlow = (float)(message.ReadByte()-100);
newActive = message.ReadBoolean();
}
catch { return; }
catch (Exception e)
{
#if DEBUG
DebugConsole.ThrowError("invalid network message", e);
#endif
return;
}
FlowPercentage = newFlow;
isActive = newActive;
@@ -68,19 +68,31 @@ namespace Subsurface.Items.Components
public float 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
{
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
{
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()
@@ -100,6 +112,7 @@ namespace Subsurface.Items.Components
public float ShutDownTemp
{
get { return shutDownTemp; }
private set { shutDownTemp = MathHelper.Clamp(value, 0.0f, 10000.0f); }
}
public Reactor(Item item, XElement element)
@@ -127,7 +140,7 @@ namespace Subsurface.Items.Components
float heat = 100 * fissionRate * (AvailableFuel/2000.0f);
float heatDissipation = 50 * coolingRate + ExtraCooling;
float deltaTemp = (((heat - heatDissipation) * 5) - temperature) / 1000.0f;
float deltaTemp = (((heat - heatDissipation) * 5) - temperature) / 10000.0f;
Temperature = temperature + deltaTemp;
if (temperature > meltDownTemp)
@@ -142,8 +155,7 @@ namespace Subsurface.Items.Components
powerUpTask = new PropertyTask(item, IsRunning, 50.0f, "Power up the reactor");
}
}
item.Condition -= temperature * deltaTime * 0.00005f;
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
FissionRate = Math.Max(fissionRate, heat / 200.0f);
//the power generated by the reactor is equal to the temperature
currPowerConsumption = -temperature*powerPerTemp;
@@ -203,6 +214,8 @@ namespace Subsurface.Items.Components
ExtraCooling = 0.0f;
AvailableFuel = 0.0f;
item.SendSignal(((int)temperature).ToString(), "temperature_out");
}
public override void UpdateBroken(float deltaTime, Camera cam)
@@ -239,24 +252,15 @@ namespace Subsurface.Items.Components
new RepairTask(item, 60.0f, "Reactor meltdown!");
item.Condition = 0.0f;
//fissionRate = 0.0f;
//coolingRate = 0.0f;
//PlaySound(ActionType.OnFailure, item.Position);
//item.ApplyStatusEffects(ActionType.OnFailure, 1.0f, null);
//new Explosion(item.SimPosition, 6.0f, 500.0f, 600.0f, 10.0f, 2.0f).Explode();
var containedItems = item.ContainedItems;
if (containedItems == null) return;
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)
@@ -343,12 +347,12 @@ namespace Subsurface.Items.Components
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 400, y + 180, 40, 40), "+", true))
{
valueChanged = true;
shutDownTemp += 100.0f;
ShutDownTemp += 100.0f;
}
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 450, y + 180, 40, 40), "-", true))
{
valueChanged = true;
shutDownTemp -= 100.0f;
ShutDownTemp -= 100.0f;
}
if (valueChanged)
@@ -398,14 +402,24 @@ namespace Subsurface.Items.Components
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)
{
message.Write(autoTemp);
message.Write(temperature);
message.Write(shutDownTemp);
message.WriteRangedSingle(temperature, 0.0f, 10000.0f, 16);
message.WriteRangedSingle(shutDownTemp, 0.0f, 10000.0f, 16);
message.Write(coolingRate);
message.Write(fissionRate);
message.WriteRangedSingle(coolingRate, 0.0f, 100.0f, 8);
message.WriteRangedSingle(fissionRate, 0.0f, 100.0f, 8);
}
public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message)
@@ -417,18 +431,24 @@ namespace Subsurface.Items.Components
try
{
newAutoTemp = message.ReadBoolean();
newTemperature = message.ReadFloat();
newShutDownTemp = message.ReadFloat();
newTemperature = message.ReadRangedSingle(0.0f, 10000.0f, 16);
newShutDownTemp = message.ReadRangedSingle(0.0f, 10000.0f, 16);
newCoolingRate = message.ReadFloat();
newFissionRate = message.ReadFloat();
newCoolingRate = message.ReadRangedSingle(0.0f, 100.0f, 8);
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;
Temperature = newTemperature;
shutDownTemp = newShutDownTemp;
ShutDownTemp = newShutDownTemp;
CoolingRate = newCoolingRate;
FissionRate = newFissionRate;
@@ -48,10 +48,7 @@ namespace Subsurface.Items.Components
get { return targetVelocity;}
set
{
if (float.IsNaN(value.X) || float.IsNaN(value.Y))
{
return;
}
if (!MathUtils.IsValid(value)) return;
targetVelocity.X = MathHelper.Clamp(value.X, -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.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;
@@ -319,14 +319,13 @@ namespace Subsurface.Items.Components
if (index>-1)
{
Wires[index].RemoveConnection(this);
Wires[index].Item.SetTransform(item.SimPosition, 0.0f);
Wires[index].Item.Drop();
Wires[index].Item.body.Enabled = true;
//Wires[index].Item.SetTransform(item.SimPosition, 0.0f);
//Wires[index].Item.Drop();
//Wires[index].Item.body.Enabled = true;
Wires[index] = null;
}
}
}
}
}
@@ -9,6 +9,8 @@ namespace Subsurface.Items.Components
private string expression;
private string receivedSignal;
[InGameEditable, HasDefaultValue("1", true)]
public string Output
{
@@ -26,6 +28,27 @@ namespace Subsurface.Items.Components
public RegExFindComponent(Item item, XElement 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)
@@ -33,22 +56,7 @@ namespace Subsurface.Items.Components
switch (connection.Name)
{
case "signal_in":
if (string.IsNullOrWhiteSpace(expression)) return;
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");
receivedSignal = signal;
break;
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;
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;
//List<PowerContainer> batteries = new List<PowerContainer>();
@@ -132,31 +155,6 @@ namespace Subsurface.Items.Components
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.Enabled = true;
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; }
}
public float PickDistance
{
get { return prefab.PickDistance; }
}
public float Condition
{
get { return condition; }
@@ -178,7 +183,7 @@ namespace Subsurface
get
{
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;
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);
}
else if (body.Enabled)
{
body.Draw(spriteBatch, prefab.sprite, color);
if (body==null)
{
prefab.sprite.DrawTiled(spriteBatch, new Vector2(rect.X, -rect.Y), new Vector2(rect.Width, rect.Height), color);
}
else if (body.Enabled)
{
body.Draw(spriteBatch, prefab.sprite, color);
}
}
foreach (ItemComponent component in components) component.Draw(spriteBatch, editing);
if (!editing || (body!=null && !body.Enabled))
@@ -665,7 +674,13 @@ namespace Subsurface
foreach (var objectProperty in editableProperties)
{
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();
if (value != null)
@@ -676,7 +691,7 @@ namespace Subsurface
propertyBox.UserData = objectProperty;
propertyBox.OnEnter = EnterProperty;
propertyBox.OnTextChanged = PropertyChanged;
y = y + 30;
y = y + height+10;
}
return editingHUD;
}
@@ -933,8 +948,8 @@ namespace Subsurface
if (objectProperty == null) return false;
object prevValue = objectProperty.GetValue();
textBox.Selected = false;
textBox.Deselect();
if (objectProperty.TrySetValue(text))
{
+1 -1
View File
@@ -106,7 +106,7 @@ namespace Subsurface
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;
+5
View File
@@ -45,6 +45,11 @@ namespace Subsurface
get { return Vector2.Zero; }
}
public AITarget AiTarget
{
get { return aiTarget; }
}
public Entity()
{
//give an unique ID
+1 -1
View File
@@ -156,7 +156,7 @@ namespace Subsurface
public int GetWaveIndex(Vector2 position)
{
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;
}
+4 -1
View File
@@ -245,7 +245,10 @@ namespace Subsurface.Lights
* Matrix.CreateOrthographic(Game1.GraphicsWidth, Game1.GraphicsHeight, -1, 1) * 0.5f;
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 double lastNetworkUpdate;
private float lastNetworkUpdate;
//properties ----------------------------------------------------
@@ -505,7 +505,7 @@ namespace Subsurface
private void Translate(Vector2 amount)
{
if (amount == Vector2.Zero) return;
if (amount == Vector2.Zero || !amount.IsValid()) return;
Level.Loaded.Move(-amount);
}
@@ -516,11 +516,6 @@ namespace Subsurface
speed += force/mass;
}
//public void Move(Vector2 amount)
//{
// speed = Vector2.Lerp(speed, amount, 0.05f);
//}
VoronoiCell collidingCell;
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)
{
message.Write(NetTime.Now);
message.Write((float)NetTime.Now);
message.Write(Position.X);
message.Write(Position.Y);
@@ -580,11 +575,11 @@ namespace Subsurface
public override void ReadNetworkData(Networking.NetworkEventType type, NetIncomingMessage message)
{
double sendingTime;
float sendingTime;
Vector2 newTargetPosition, newSpeed;
try
{
sendingTime = message.ReadDouble();
sendingTime = message.ReadFloat();
if (sendingTime <= lastNetworkUpdate) return;
@@ -592,11 +587,16 @@ namespace Subsurface
newSpeed = new Vector2(message.ReadFloat(), message.ReadFloat());
}
catch
catch (Exception e)
{
#if DEBUG
DebugConsole.ThrowError("invalid network message", e);
#endif
return;
}
if (!newSpeed.IsValid() || !newTargetPosition.IsValid()) return;
//newTargetPosition = newTargetPosition + newSpeed * (float)(NetTime.Now - sendingTime);
targetPosition = newTargetPosition;
+9 -2
View File
@@ -109,7 +109,12 @@ namespace Subsurface
{
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();
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(':');
if (address.Length==1)
{
@@ -65,7 +64,7 @@ namespace Subsurface.Networking
if (!int.TryParse(address[1], out Port))
{
DebugConsole.ThrowError("Invalid port: address[1]!");
DebugConsole.ThrowError("Invalid port: "+address[1]+"!");
Port = DefaultPort;
}
}
@@ -73,18 +72,24 @@ namespace Subsurface.Networking
myCharacter = Character.Controlled;
// Create new instance of configs. Parameter is "application Id". It has to be same on client and server.
NetPeerConfiguration Config = new NetPeerConfiguration("subsurface");
//Config.SimulatedLoss = 0.2f;
//Config.SimulatedMinimumLatency = 0.25f;
NetPeerConfiguration config = new NetPeerConfiguration("subsurface");
#if DEBUG
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
client = new NetClient(Config);
client = new NetClient(config);
NetOutgoingMessage outmsg = client.CreateMessage();
client.Start();
outmsg.Write((byte)PacketTypes.Login);
outmsg.Write(password);
outmsg.Write(Game1.Version.ToString());
outmsg.Write(Game1.SelectedPackage.Name);
outmsg.Write(Game1.SelectedPackage.MD5hash.Hash);
@@ -111,8 +116,11 @@ namespace Subsurface.Networking
//update.Elapsed += new System.Timers.ElapsedEventHandler(Update);
// 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());
// Start the timer
@@ -141,7 +149,7 @@ namespace Subsurface.Networking
// When this is set to true, we are approved and ready to go
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
while (!CanStart)
@@ -239,14 +247,19 @@ namespace Subsurface.Networking
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]);
connected = false;
ConnectToServer(serverIP);
if (reconnectBox==null)
{
reconnectBox = new GUIMessageBox("CONNECTION LOST", "You have been disconnected from the server. Reconnecting...", new string[0]);
connected = false;
ConnectToServer(serverIP);
}
return;
}
else if (reconnectBox!=null)
if (reconnectBox!=null)
{
reconnectBox.Close(null,null);
reconnectBox = null;
@@ -259,9 +272,20 @@ namespace Subsurface.Networking
Character.Controlled = null;
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;
case (byte)PacketTypes.EndGame:
string endMessage = inc.ReadString();
EndGame(endMessage);
CoroutineManager.StartCoroutine(EndGame(endMessage));
break;
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();
Game1.NetLobbyScreen.Select();
if (Game1.GameSession!=null) Game1.GameSession.EndShift("");
new GUIMessageBox("The round has ended", endMessage);
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()
@@ -514,7 +587,7 @@ namespace Subsurface.Networking
msg.Write((byte)type);
msg.Write(message);
client.SendMessage(msg, NetDeliveryMethod.Unreliable);
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
}
/// <summary>
+179 -34
View File
@@ -22,39 +22,54 @@ namespace Subsurface.Networking
private TimeSpan refreshMasterInterval = new TimeSpan(0, 0, 40);
private DateTime refreshMasterTimer;
private bool masterServerResponded;
private bool registeredToMaster;
private string password;
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);
endRoundButton.OnClicked = EndButtonHit;
this.name = name;
this.password = password;
config = new NetPeerConfiguration("subsurface");
//config.SimulatedLoss = 0.2f;
//config.SimulatedMinimumLatency = 0.25f;
#if DEBUG
config.SimulatedLoss = 0.2f;
config.SimulatedMinimumLatency = 0.3f;
#endif
config.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);
try
{
server = new NetServer(config);
server.Start();
// attempt to forward port
server.UPnP.ForwardPort(port, "subsurface");
if (attemptUPnP)
{
server.UPnP.ForwardPort(port, "subsurface");
}
}
catch (Exception e)
@@ -62,7 +77,11 @@ namespace Subsurface.Networking
DebugConsole.ThrowError("Couldn't start the server", e);
}
RegisterToMasterServer();
if (isPublic)
{
RegisterToMasterServer();
}
updateInterval = new TimeSpan(0, 0, 0, 0, 30);
@@ -78,6 +97,7 @@ namespace Subsurface.Networking
request.AddParameter("servername", name);
request.AddParameter("serverport", Port);
request.AddParameter("playercount", PlayerCountToByte(connectedClients.Count, config.MaximumConnections));
request.AddParameter("password", string.IsNullOrWhiteSpace(password) ? 0 : 1);
// execute the request
RestResponse response = (RestResponse)client.Execute(request);
@@ -98,7 +118,7 @@ namespace Subsurface.Networking
refreshMasterTimer = DateTime.Now + refreshMasterInterval;
}
private void RefreshMaster()
private IEnumerable<object> RefreshMaster()
{
var client = new RestClient(NetworkMember.MasterServerUrl);
@@ -112,17 +132,43 @@ namespace Subsurface.Networking
var sw = new Stopwatch();
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");
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)
{
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)
@@ -159,7 +205,7 @@ namespace Subsurface.Networking
if (registeredToMaster && refreshMasterTimer < DateTime.Now)
{
RefreshMaster();
CoroutineManager.StartCoroutine(RefreshMaster());
refreshMasterTimer = DateTime.Now + refreshMasterInterval;
}
@@ -177,9 +223,9 @@ namespace Subsurface.Networking
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);
}
}
@@ -204,9 +250,10 @@ namespace Subsurface.Networking
Client existingClient = connectedClients.Find(c=> c.Connection == inc.SenderConnection);
if (existingClient==null)
{
string version = "", packageName="", packageHash="", name = "";
string userPassword = "", version = "", packageName="", packageHash="", name = "";
try
{
userPassword = inc.ReadString();
version = inc.ReadString();
packageName = inc.ReadString();
packageHash = inc.ReadString();
@@ -215,27 +262,38 @@ namespace Subsurface.Networking
catch
{
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;
}
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 + ")");
DebugConsole.NewMessage("Connection error - wrong game version", Color.Red);
break;
}
else if (packageName != 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;
}
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 + ")");
DebugConsole.NewMessage("Connection error - wrong content package hash", Color.Red);
break;
}
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.");
DebugConsole.NewMessage("Connection error - name already in use", Color.Red);
break;
}
@@ -348,7 +406,9 @@ namespace Subsurface.Networking
}
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;
case (byte)PacketTypes.Chatmessage:
@@ -396,15 +456,42 @@ namespace Subsurface.Networking
{
//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();
message.Write((byte)PacketTypes.NetworkEvent);
//if (!networkEvent.IsClient) continue;
networkEvent.FillData(message);
System.Diagnostics.Debug.WriteLine("Sending networkevent " + Entity.FindEntityByID(networkEvent.ID).ToString() + " (" + message.LengthBytes + " bytes)");
if (server.ConnectionsCount>0)
{
server.SendMessage(message, server.Connections,
server.SendMessage(message, recipients,
(networkEvent.IsImportant) ? NetDeliveryMethod.Unreliable : NetDeliveryMethod.ReliableUnordered, 0);
}
@@ -415,13 +502,19 @@ namespace Subsurface.Networking
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;
Rand.SetSyncedSeed(seed);
AssignJobs();
Submarine selectedMap = Game1.NetLobbyScreen.SelectedMap as Submarine;
AssignJobs();
//selectedMap.Load();
Game1.GameSession = new GameSession(selectedMap, "", Game1.NetLobbyScreen.SelectedMode);
@@ -518,9 +611,10 @@ namespace Subsurface.Networking
return true;
}
public void EndGame(string endMessage)
public IEnumerable<object> EndGame(string endMessage)
{
gameStarted = false;
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();
gameStarted = false;
Game1.NetLobbyScreen.Select();
DebugConsole.ThrowError(endMessage);
yield return Status.Success;
}
private void DisconnectClient(NetConnection senderConnection)
@@ -605,7 +720,7 @@ namespace Subsurface.Networking
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();
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)
{
NetOutgoingMessage msg = server.CreateMessage();
@@ -650,12 +795,12 @@ namespace Subsurface.Networking
}
if (recipients.Count>0)
{
server.SendMessage(msg, recipients, NetDeliveryMethod.Unreliable, 0);
server.SendMessage(msg, recipients, NetDeliveryMethod.ReliableUnordered, 0);
}
}
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,
InventoryUpdate = 4,
PickItem = 5,
UpdateProperty = 6
UpdateProperty = 6,
NotMoving = 7
}
class 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;
@@ -113,6 +114,8 @@ namespace Subsurface.Networking
return false;
}
System.Diagnostics.Debug.WriteLine("Networkevent entity: "+e.ToString());
//System.Diagnostics.Debug.WriteLine("new message: " + eventType +" - "+e);
e.ReadNetworkData(eventType, message);
@@ -64,6 +64,11 @@ namespace Subsurface.Networking
}
}
public bool GameStarted
{
get { return gameStarted; }
}
public GUIFrame InGameHUD
{
get { return inGameHUD; }
+40 -9
View File
@@ -7,6 +7,7 @@ using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Subsurface.Networking;
using System.Collections.Generic;
using System;
namespace Subsurface
{
@@ -48,6 +49,7 @@ namespace Subsurface
get { return targetPosition; }
set
{
if (float.IsNaN(value.X) || float.IsNaN(value.Y)) return;
targetPosition.X = MathHelper.Clamp(value.X, -10000.0f, 10000.0f);
targetPosition.Y = MathHelper.Clamp(value.Y, -10000.0f, 10000.0f);
}
@@ -57,7 +59,8 @@ namespace Subsurface
{
get { return targetVelocity; }
set
{
{
if (float.IsNaN(value.X) || float.IsNaN(value.Y)) return;
targetVelocity.X = MathHelper.Clamp(value.X, -100.0f, 100.0f);
targetVelocity.Y = MathHelper.Clamp(value.Y, -100.0f, 100.0f);
}
@@ -68,7 +71,7 @@ namespace Subsurface
get { return targetRotation; }
set
{
if (float.IsNaN(value) || float.IsInfinity(value) || float.IsNegativeInfinity(value)) return;
if (float.IsNaN(value) || float.IsInfinity(value)) return;
targetRotation = value;
}
}
@@ -76,7 +79,11 @@ namespace Subsurface
public float TargetAngularVelocity
{
get { return targetAngularVelocity; }
set { targetAngularVelocity = value; }
set
{
if (float.IsNaN(value) || float.IsInfinity(value)) return;
targetAngularVelocity = value;
}
}
public Vector2 DrawPosition
@@ -356,13 +363,37 @@ namespace Subsurface
public void ReadNetworkData(NetworkEventType type, NetIncomingMessage message)
{
targetPosition.X = message.ReadFloat();
targetPosition.Y = message.ReadFloat();
targetVelocity.X = message.ReadFloat();
targetVelocity.Y = message.ReadFloat();
Vector2 newTargetPos = Vector2.Zero;
Vector2 newTargetVel = Vector2.Zero;
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
{
class Key
{
private bool state, stateQueue;
private bool canBeHeld;
public Key(bool canBeHeld)
public enum InputType { Select, ActionHit, ActionHeld, SecondaryHit, SecondaryHeld }
class Key
{
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
{
get
{
return state;
}
set
{
//if (value == false) return;
state = value;
//if (value) stateQueue = value;
}
}
public bool State
{
get
{
return state;
}
set
{
//if (value == false) return;
state = value;
//if (value) stateQueue = value;
}
}
public void SetState(bool value)
{
state = value;
if (value) stateQueue = value;
}
public void SetState(bool value)
{
state = value;
if (value) stateQueue = value;
}
public bool Dequeue
{
get
{
bool value = stateQueue;
stateQueue = false;
return value;
}
//set
//{
// stateQueue = value;
//}
}
public bool Dequeue
{
get
{
bool value = stateQueue;
stateQueue = false;
return value;
}
//set
//{
// stateQueue = value;
//}
}
public void Reset()
{
if (!canBeHeld) state = false;
//stateQueue = false;
}
}
public void Reset()
{
if (!canBeHeld) state = false;
//stateQueue = false;
}
}
static class PlayerInput
{
static MouseState mouseState, oldMouseState;
static KeyboardState keyboardState, oldKeyboardState;
static class PlayerInput
{
static MouseState mouseState, oldMouseState;
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
{
get { return new Vector2(mouseState.Position.X, mouseState.Position.Y); }
}
public static Vector2 MousePosition
{
get { return new Vector2(mouseState.X, mouseState.Y); }
}
public static MouseState GetMouseState
{
get { return mouseState; }
}
public static MouseState GetOldMouseState
{
get { return oldMouseState; }
}
public static MouseState GetMouseState
{
get { return mouseState; }
}
public static MouseState GetOldMouseState
{
get { return oldMouseState; }
}
public static Vector2 MouseSpeed
{
get
{
Point speed = mouseState.Position - oldMouseState.Position;
return new Vector2(speed.X, speed.Y);
}
}
public static Vector2 MouseSpeed
{
get
{
return MousePosition - new Vector2(oldMouseState.X, oldMouseState.Y);
}
}
public static KeyboardState GetKeyboardState
{
get { return keyboardState; }
}
public static KeyboardState GetKeyboardState
{
get { return keyboardState; }
}
public static KeyboardState GetOldKeyboardState
{
get { return oldKeyboardState; }
}
public static KeyboardState GetOldKeyboardState
{
get { return oldKeyboardState; }
}
public static int ScrollWheelSpeed
{
get { return mouseState.ScrollWheelValue - oldMouseState.ScrollWheelValue; }
}
public static int ScrollWheelSpeed
{
get { return mouseState.ScrollWheelValue - oldMouseState.ScrollWheelValue; }
}
public static bool LeftButtonDown()
{
return mouseState.LeftButton == ButtonState.Pressed;
}
public static bool LeftButtonDown()
{
return mouseState.LeftButton == ButtonState.Pressed;
}
public static bool LeftButtonClicked()
{
return (oldMouseState.LeftButton == ButtonState.Pressed
&& mouseState.LeftButton == ButtonState.Released);
}
public static bool LeftButtonClicked()
{
return (oldMouseState.LeftButton == ButtonState.Pressed
&& mouseState.LeftButton == ButtonState.Released);
}
public static bool RightButtonClicked()
{
return (oldMouseState.RightButton == ButtonState.Pressed
&& mouseState.RightButton == ButtonState.Released);
}
public static bool RightButtonClicked()
{
return (oldMouseState.RightButton == ButtonState.Pressed
&& mouseState.RightButton == ButtonState.Released);
}
public static bool DoubleClicked()
{
return doubleClicked;
}
public static bool DoubleClicked()
{
return doubleClicked;
}
public static bool KeyHit(Keys button)
{
return (oldKeyboardState.IsKeyDown(button) && keyboardState.IsKeyUp(button));
}
public static bool KeyHit(Keys button)
{
return (oldKeyboardState.IsKeyDown(button) && keyboardState.IsKeyUp(button));
}
public static bool KeyDown(Keys button)
{
return (keyboardState.IsKeyDown(button));
}
public static bool KeyDown(Keys button)
{
return (keyboardState.IsKeyDown(button));
}
public static void Update(double deltaTime)
{
timeSinceClick += deltaTime;
public static void Update(double deltaTime)
{
timeSinceClick += deltaTime;
oldMouseState = mouseState;
mouseState = Mouse.GetState();
oldMouseState = mouseState;
mouseState = Mouse.GetState();
oldKeyboardState = keyboardState;
keyboardState = Keyboard.GetState();
oldKeyboardState = keyboardState;
keyboardState = Keyboard.GetState();
doubleClicked = false;
if (LeftButtonClicked())
{
if (timeSinceClick < doubleClickDelay) doubleClicked = true;
timeSinceClick = 0.0;
}
}
}
doubleClicked = false;
if (LeftButtonClicked())
{
if (timeSinceClick < doubleClickDelay) doubleClicked = true;
timeSinceClick = 0.0;
}
}
}
}
+7
View File
@@ -5,11 +5,18 @@ using System.Globalization;
using System.Linq;
using System.Xml.Linq;
namespace Subsurface
{
[AttributeUsage(AttributeTargets.Property)]
public class Editable : System.Attribute
{
public int MaxLength;
public Editable(int maxLength = 20)
{
MaxLength = maxLength;
}
}
[AttributeUsage(AttributeTargets.Property)]
+1 -1
View File
@@ -176,7 +176,7 @@ namespace Subsurface
// 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);
if (characterMode)
+3 -2
View File
@@ -75,11 +75,12 @@ namespace Subsurface
StatusEffect.UpdateAll((float)deltaTime);
cam.MoveCamera((float)deltaTime);
Physics.accumulator = Math.Min(Physics.accumulator, Physics.step * 4);
while (Physics.accumulator >= Physics.step)
{
cam.MoveCamera((float)Physics.step);
foreach (PhysicsBody pb in PhysicsBody.list)
{
pb.SetPrevTransform(pb.Position, pb.Rotation);
@@ -146,7 +147,7 @@ namespace Subsurface
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;
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)
{
Game1.GameSession.StartShift(TimeSpan.Zero, selectedLevel);
Game1.GameSession.StartShift(TimeSpan.Zero, selectedLevel, false);
Game1.GameScreen.Select();
return true;
+52 -34
View File
@@ -18,9 +18,8 @@ namespace Subsurface
private GUITextBox saveNameBox, seedBox;
private GUITextBox clientNameBox, ipBox;
private GUITextBox serverNameBox, portBox;
private GUITextBox serverNameBox, portBox, passwordBox, maxPlayersBox;
private GUITickBox isPublicBox, useUpnpBox;
private Game1 game;
@@ -38,10 +37,10 @@ namespace Subsurface
menuTabs[(int)Tabs.Main] = new GUIFrame(panelRect, GUI.style);
//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]);
button.OnClicked = TutorialButtonClicked;
//GUIButton button = new GUIButton(new Rectangle(0, 0, 0, 30), "Tutorial", Alignment.CenterX, GUI.style, menuTabs[(int)Tabs.Main]);
//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.OnClicked = SelectTab;
//button.Enabled = false;
@@ -112,16 +111,44 @@ namespace Subsurface
menuTabs[(int)Tabs.HostServer] = new GUIFrame(panelRect, GUI.style);
//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]);
serverNameBox = new GUITextBox(new Rectangle(0, 60, 200, 30), Color.White, Color.Black, Alignment.CenterX, Alignment.CenterX, null, 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(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]);
portBox = new GUITextBox(new Rectangle(0, 130, 200, 30), Color.White, Color.Black, Alignment.CenterX, Alignment.CenterX, null, 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(160, 100, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, GUI.style, menuTabs[(int)Tabs.HostServer]);
portBox.Text = NetworkMember.DefaultPort.ToString();
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]);
hostButton.OnClicked = HostServerClicked;
@@ -159,6 +186,18 @@ namespace Subsurface
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)
{
string name = serverNameBox.Text;
@@ -177,7 +216,7 @@ namespace Subsurface
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.Select();
@@ -194,7 +233,7 @@ namespace Subsurface
{
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();
@@ -376,26 +415,5 @@ namespace Subsurface
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;
//GUIFrame previewPlayer;
private GUIScrollBar durationBar;
private GUIFrame playerFrame;
@@ -36,6 +34,11 @@ namespace Subsurface
private GUITextBox serverMessage;
public GUIListBox SubList
{
get { return subList; }
}
public Submarine SelectedMap
{
get { return subList.SelectedData as Submarine; }
@@ -275,7 +278,7 @@ namespace Subsurface
modeList.OnSelected += 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);
}
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.Enabled = false;
int i = 1;
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;
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,
Alignment.Left, GUI.style, null, true);
msg.Font = GUI.SmallFont;
msg.CanBeFocused = false;
msg.Padding = new Vector4(20, 0, 0, 0);
chatBox.AddChild(msg);
@@ -556,13 +562,17 @@ namespace Subsurface
private void UpdateJobPreferences(GUIListBox listBox)
{
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;
a = Math.Min(a, 3);
Color color = new Color(1.0f - a, (1.0f - a) * 0.6f, 0.0f, 0.3f);
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();
@@ -658,57 +668,13 @@ namespace Subsurface
return;
}
TrySelectMap(mapName, md5Hash);
if (!string.IsNullOrWhiteSpace(mapName)) TrySelectMap(mapName, md5Hash);
modeList.Select(modeIndex);
durationBar.BarScroll = durationScroll;
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
{
private static Screen selected;
public static Screen Selected
{
get { return selected; }
+147 -24
View File
@@ -14,6 +14,9 @@ namespace Subsurface
{
class ServerListScreen : Screen
{
//how often the client is allowed to refresh servers
private TimeSpan AllowedRefreshInterval = new TimeSpan(0,0,3);
private GUIFrame menu;
private GUIListBox serverList;
@@ -22,6 +25,15 @@ namespace Subsurface
private GUITextBox clientNameBox, ipBox;
//private RestRequestAsyncHandle restRequestHandle;
private bool masterServerResponded;
private int[] columnX;
//a timer for
private DateTime refreshDisableTimer;
private bool waitingForRefresh;
public ServerListScreen()
{
int width = Math.Min(Game1.GraphicsWidth - 160, 1000);
@@ -30,37 +42,55 @@ namespace Subsurface
Rectangle panelRect = new Rectangle(0, 0, width, height);
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);
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);
ipBox = new GUITextBox(new Rectangle(0, 130, 200, 30), GUI.style, menu);
int middleX = (int)(width * 0.4f);
serverList = new GUIListBox(new Rectangle(middleX,60,0,(int)(height*0.7f)), GUI.style, menu);
serverList.OnSelected = SelectServer;
new GUITextBlock(new Rectangle(middleX, 30, 0, 30), "Name", GUI.style, menu);
new GUITextBlock(new Rectangle(middleX, 30, 0, 30), "Players", GUI.style, Alignment.TopLeft, Alignment.TopCenter, menu);
new GUITextBlock(new Rectangle(middleX, 30, 0, 30), "Game running", GUI.style, Alignment.TopLeft, Alignment.TopRight, menu);
float[] columnRelativeX = new float[] { 0.15f, 0.55f, 0.15f, 0.15f };
columnX = new int[columnRelativeX.Length];
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.OnClicked = RefreshServers;
joinButton = new GUIButton(new Rectangle(0,0,150,30), "Join", Alignment.BottomRight, GUI.style, menu);
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()
{
base.Select();
UpdateServerList();
//RefreshServers(null, null);
//UpdateServerList();
}
private bool SelectServer(object obj)
@@ -75,16 +105,39 @@ namespace Subsurface
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;
}
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();
string masterServerData = GetMasterServerData();
//string masterServerData = GetMasterServerData();
if (string.IsNullOrWhiteSpace(masterServerData))
{
@@ -96,6 +149,7 @@ namespace Subsurface
if (masterServerData.Substring(0,5).ToLower()=="error")
{
DebugConsole.ThrowError("Error while connecting to master server ("+masterServerData+")!");
return;
}
@@ -112,23 +166,33 @@ namespace Subsurface
string gameStarted = (arguments.Length > 3) ? arguments[3] : "";
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);
serverFrame.UserData = IP+":"+port;
serverFrame.HoverColor = Color.Gold * 0.2f;
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;
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 gameStartedText = new GUITextBlock(new Rectangle(0, 0, 0, 0), gameStarted=="1" ? "Yes" : "No", GUI.style, Alignment.Left, Alignment.TopRight, serverFrame);
var playerCountText = new GUITextBlock(new Rectangle(columnX[1], 0, 0, 0), playerCount + "/" + maxPlayers, GUI.style, 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;
try
@@ -137,10 +201,11 @@ namespace Subsurface
}
catch (Exception e)
{
DebugConsole.ThrowError("Error while connecting to master server", e);
return "";
DebugConsole.ThrowError("Error while connecting to master server", e);
}
if (client == null) yield return Status.Success;
var request = new RestRequest("masterserver.php", Method.GET);
request.AddParameter("gamename", "subsurface"); // adds to POST or URL querystring based on Method
@@ -154,17 +219,44 @@ namespace Subsurface
//request.AddFile(path);
// 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)
{
serverList.ClearChildren();
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)
@@ -183,12 +275,41 @@ namespace Subsurface
return false;
}
Game1.NetworkMember = new GameClient(clientNameBox.Text);
Game1.Client.ConnectToServer(ip);
CoroutineManager.StartCoroutine(JoinServer(ip));
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)
{
graphics.Clear(Color.CornflowerBlue);
@@ -208,6 +329,8 @@ namespace Subsurface
public override void Update(double deltaTime)
{
menu.Update((float)deltaTime);
GUI.Update((float)deltaTime);
@@ -155,7 +155,7 @@ namespace Subsurface
if (startDrone!=null)
{
if (!SoundManager.IsPlaying(startDrone.AlBufferId))
if (!startDrone.IsPlaying)
{
startDrone.Remove();
startDrone = null;
+18 -3
View File
@@ -19,6 +19,8 @@ namespace Subsurface
private OggSound oggSound;
string filePath;
private int alSourceId;
//public float Volume
@@ -71,7 +73,8 @@ namespace Subsurface
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)
@@ -83,7 +86,9 @@ namespace Subsurface
Vector2 relativePos = GetRelativePosition(position);
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;
@@ -96,7 +101,9 @@ namespace Subsurface
//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)
@@ -178,6 +185,14 @@ namespace Subsurface
}
public bool IsPlaying
{
get
{
return SoundManager.IsPlaying(alSourceId);
}
}
//public int Loop(float volume = 1.0f)
//{
// return SoundManager.Loop(this, volume);
+24 -21
View File
@@ -1,8 +1,11 @@
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using OpenTK.Audio;
#if WINDOWS
using OpenTK.Audio.OpenAL;
#endif
using OpenTK.Audio;
using System;
namespace Subsurface.Sounds
@@ -34,14 +37,14 @@ namespace Subsurface.Sounds
for (int i = 0 ; i < DefaultSourceCount; i++)
{
alSources.Add(AL.GenSource());
alSources.Add(OpenTK.Audio.OpenAL.AL.GenSource());
}
if (ALHelper.Efx.IsInitialized)
{
lowpassFilterId = ALHelper.Efx.GenFilter();
//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;
}
@@ -129,29 +132,29 @@ namespace Subsurface.Sounds
for (int i = 1; i < DefaultSourceCount; i++)
{
//find a source that's free to use (not playing or paused)
if (AL.GetSourceState(alSources[i]) == ALSourceState.Playing
|| AL.GetSourceState(alSources[i]) == ALSourceState.Paused) continue;
if (OpenTK.Audio.OpenAL.AL.GetSourceState(alSources[i]) == OpenTK.Audio.OpenAL.ALSourceState.Playing
|| OpenTK.Audio.OpenAL.AL.GetSourceState(alSources[i]) == OpenTK.Audio.OpenAL.ALSourceState.Paused) continue;
//if (position!=Vector2.Zero)
// position /= 1000.0f;
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;
//System.Diagnostics.Debug.WriteLine("updatesoundpos: "+offset);
AL.Source(alSources[i], 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.ALSourcef.Gain, volume);
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.Check();
//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;
@@ -261,10 +264,10 @@ namespace Subsurface.Sounds
for (int i = 0; i < DefaultSourceCount; i++)
{
//find a source that's free to use (not playing or paused)
if (AL.GetSourceState(alSources[i]) != ALSourceState.Playing
&& AL.GetSourceState(alSources[i])!= ALSourceState.Paused) continue;
if (OpenTK.Audio.OpenAL.AL.GetSourceState(alSources[i]) != OpenTK.Audio.OpenAL.ALSourceState.Playing
&& 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.Check();
}
@@ -293,10 +296,10 @@ namespace Subsurface.Sounds
position/= 1000.0f;
//System.Diagnostics.Debug.WriteLine("updatesoundpos: "+offset);
AL.Source(alSources[sourceIndex], 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.ALSourcef.Gain, baseVolume);
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.Check();
}
@@ -328,7 +331,7 @@ namespace Subsurface.Sounds
{
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++)
{
var state = AL.GetSourceState(alSources[i]);
if (state == ALSourceState.Playing || state == ALSourceState.Paused)
var state = OpenTK.Audio.OpenAL.AL.GetSourceState(alSources[i]);
if (state == OpenTK.Audio.OpenAL.ALSourceState.Playing || state == OpenTK.Audio.OpenAL.ALSourceState.Paused)
Stop(i);
AL.DeleteSource(alSources[i]);
OpenTK.Audio.OpenAL.AL.DeleteSource(alSources[i]);
ALHelper.Check();
}
+13 -1
View File
@@ -17,7 +17,9 @@ namespace Subsurface
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)
@@ -25,6 +27,16 @@ namespace Subsurface
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)
{
+9 -4
View File
@@ -55,11 +55,16 @@ namespace Subsurface
{
DebugConsole.ThrowError("Error saving gamesession", e);
}
//Game1.GameSession.crewManager.Save(directory+"\\crew.xml");
try
{
CompressDirectory(tempPath, fileName+".save", null);
}
CompressDirectory(tempPath, fileName+".save", null);
//Directory.Delete(tempPath, true);
catch (Exception e)
{
DebugConsole.ThrowError("Error compressing save file", e);
}
}
public static void LoadGame(string fileName)
+12 -1
View File
@@ -4,6 +4,7 @@ using System.IO;
using Microsoft.Xna.Framework.Graphics;
using Color = Microsoft.Xna.Framework.Color;
using System;
using Microsoft.Xna.Framework;
namespace Subsurface
{
@@ -44,8 +45,15 @@ namespace Subsurface
{
try
{
#if WINDOWS
using (Stream fileStream = File.OpenRead(path))
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)
{
@@ -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;
@@ -114,6 +123,8 @@ namespace Subsurface
return texture;
}
#endif
private static readonly BlendState BlendColorBlendState;
private static readonly BlendState BlendAlphaBlendState;
+2 -2
View File
@@ -36,9 +36,9 @@ namespace Subsurface
{
font = contentManager.Load<SpriteFont>(file);
}
catch
catch (Exception e)
{
DebugConsole.ThrowError("Loading font ''"+file+"'' failed");
DebugConsole.ThrowError("Loading font ''"+file+"'' failed", e);
}
return font;
+26 -3
View File
@@ -6336,9 +6336,6 @@
</timestamps>
<violations />
</sourcecode>
<project key="2115933639">
<configuration>DEBUG;TRACE;WINDOWS</configuration>
</project>
<sourcecode name="GameMode.cs" parser="StyleCop.CSharp.CsParser">
<timestamps>
<styleCop>2014.04.01 10:18:24.000</styleCop>
@@ -6464,4 +6461,30 @@
</timestamps>
<violations />
</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>
+20 -2
View File
@@ -38,7 +38,7 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x64</PlatformTarget>
<PlatformTarget>x86</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Windows\Release\</OutputPath>
@@ -76,7 +76,9 @@
<Compile Include="Source\GUI\GUIMessage.cs" />
<Compile Include="Source\GUI\TitleScreen.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\ItemLabel.cs" />
<Compile Include="Source\Items\FixRequirement.cs" />
<Compile Include="Source\Map\Lights\Light.cs" />
<Compile Include="Source\Map\LocationType.cs" />
@@ -301,6 +303,9 @@
<Content Include="Content\Items\Artifacts\artifacts.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\blank.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\Clothes\captainLegs.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -310,6 +315,15 @@
<Content Include="Content\Items\Electricity\lamp.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</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">
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@@ -320,6 +334,9 @@
<Content Include="Content\Items\Electricity\monitors.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\itemlabel.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\Medical\medical.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<SubType>Designer</SubType>
@@ -557,7 +574,7 @@
<Content Include="Content\Items\Electricity\junctionbox.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\Ladder\item.xml">
<Content Include="Content\Items\Ladder\ladder.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\Ladder\ladder.png">
@@ -580,6 +597,7 @@
</Content>
<Content Include="Content\Items\Electricity\poweritems.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<SubType>Designer</SubType>
</Content>
<Content Include="Content\Items\Weapons\railgun.xml">
<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
---------------------------------------------------------------------------------------------------------
+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")
Graphics - James Bear ("Moonsaber99")
Binary file not shown.
@@ -1,4 +1,6 @@
Content\SpriteFont1.xnb
Content\SmallFont.xnb
Content\LargeFont.xnb
Content\SpriteFont1.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\SmallFont.xnb
Content\LargeFont.xnb
Content\SpriteFont1.spritefont
Content\SmallFont.spritefont
Content\LargeFont.spritefont
@@ -7,8 +7,26 @@
<Importer>FontDescriptionImporter</Importer>
<Processor>FontDescriptionProcessor</Processor>
<Options>None</Options>
<Output>C:\Users\Joonas\Desktop\SBMR_3011\Sbmr_content\Sbmr_content\bin\Windows\Content\SpriteFont1.xnb</Output>
<Time>2014-08-09T18:03:17.8614245+03:00</Time>
<Output>E:\Subsurface\Subsurface_content\Subsurface_content\bin\Windows\Content\SpriteFont1.xnb</Output>
<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>
<BuildSuccessful>true</BuildSuccessful>
<Settings>
@@ -17,15 +35,15 @@
<TargetProfile>HiDef</TargetProfile>
<BuildConfiguration>Windows</BuildConfiguration>
<CompressContent>false</CompressContent>
<RootDirectory>C:\Users\Joonas\Desktop\SBMR_3011\Sbmr_content\Sbmr_contentContent\</RootDirectory>
<LoggerRootDirectory>C:\Users\Joonas\Desktop\SBMR_3011\Sbmr_content\Sbmr_content\</LoggerRootDirectory>
<IntermediateDirectory>C:\Users\Joonas\Desktop\SBMR_3011\Sbmr_content\Sbmr_content\obj\Windows\</IntermediateDirectory>
<OutputDirectory>C:\Users\Joonas\Desktop\SBMR_3011\Sbmr_content\Sbmr_content\bin\Windows\Content\</OutputDirectory>
<RootDirectory>E:\Subsurface\Subsurface_content\Subsurface_contentContent\</RootDirectory>
<LoggerRootDirectory>E:\Subsurface\Subsurface_content\Subsurface_content\</LoggerRootDirectory>
<IntermediateDirectory>E:\Subsurface\Subsurface_content\Subsurface_content\obj\Windows\</IntermediateDirectory>
<OutputDirectory>E:\Subsurface\Subsurface_content\Subsurface_content\bin\Windows\Content\</OutputDirectory>
</Settings>
<Assemblies>
<Assembly>
<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>
<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\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