- converting NetworkEvent sending time to local time before doing any comparisons
- using mersenne twister for random number generation due to differences in Mono and .NET implementations of the Random library - password prompt for password-protected private servers - fixed deconstructor, fabricator and railgun connection panels closing immediately after opening - fixed editor saving newly created subs to the root folder instead of the Submarines folder - keeping items in the same inventory slots between clients instead of just syncing which items are in the inventory - fixed crashing when swapping items between different limbslots
This commit is contained in:
@@ -142,6 +142,7 @@
|
||||
<Compile Include="Source\Networking\GameServerSettings.cs" />
|
||||
<Compile Include="Source\Screens\NetLobbyVoting.cs" />
|
||||
<Compile Include="Source\Screens\ServerListScreen.cs" />
|
||||
<Compile Include="Source\Utils\MTRandom.cs" />
|
||||
<Compile Include="Source\Utils\Rand.cs" />
|
||||
<Compile Include="Source\Events\PropertyTask.cs" />
|
||||
<Compile Include="Source\Events\RepairTask.cs" />
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<fabricableitem name="Incendium Fuel Rod" requireditems="Steel Bar, Incendium Bar"/>
|
||||
</Fabricator>
|
||||
|
||||
<ConnectionPanel canbeselected = "true">
|
||||
<ConnectionPanel selectkey="Action" canbeselected = "true">
|
||||
<requireditem name="Screwdriver" type="Equipped"/>
|
||||
<output name="power_in"/>
|
||||
</ConnectionPanel>
|
||||
@@ -73,7 +73,7 @@
|
||||
<GuiFrame rect="0,0,300,200" alignment="Center" color="0.0,0.0,0.0,0.6"/>
|
||||
</Deconstructor>
|
||||
|
||||
<ConnectionPanel canbeselected = "true">
|
||||
<ConnectionPanel selectkey="Action" canbeselected = "true">
|
||||
<requireditem name="Screwdriver" type="Equipped"/>
|
||||
<output name="power_in"/>
|
||||
</ConnectionPanel>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</StatusEffect>
|
||||
</Turret>
|
||||
|
||||
<ConnectionPanel canbeselected = "true" msg="Rewire [Screwdriver]">
|
||||
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
|
||||
<requireditem name="Screwdriver,Wire" type="Equipped"/>
|
||||
<input name="power_in"/>
|
||||
<input name="position_in"/>
|
||||
@@ -40,7 +40,7 @@
|
||||
<limbposition limb="RightHand" position="43,-85"/>
|
||||
</Controller>
|
||||
|
||||
<ConnectionPanel canbeselected = "true" msg="Rewire [Screwdriver]">
|
||||
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
|
||||
<requireditem name="Screwdriver,Wire" type="Equipped"/>
|
||||
<input name="power_in"/>
|
||||
<output name="position_out"/>
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (!character.SelectedItems.Contains(weapon))
|
||||
{
|
||||
character.Inventory.TryPutItem(weapon, 3, false);
|
||||
character.Inventory.TryPutItem(weapon, 3, true, false);
|
||||
weapon.Equip(character);
|
||||
}
|
||||
character.CursorPosition = enemy.Position;
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace Barotrauma
|
||||
|
||||
if (targetSlot>-1 && character.Inventory.IsInLimbSlot(targetItem, LimbSlot.Any))
|
||||
{
|
||||
character.Inventory.TryPutItem(targetItem, targetSlot, false);
|
||||
character.Inventory.TryPutItem(targetItem, targetSlot, true, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -875,15 +875,17 @@ namespace Barotrauma
|
||||
|
||||
Vector2 itemPos = aim ? aimPos : holdPos;
|
||||
|
||||
bool usingController = character.SelectedConstruction != null && character.SelectedConstruction.GetComponent<Controller>() != null;
|
||||
|
||||
|
||||
float itemAngle;
|
||||
if (Anim != Animation.Climbing && stunTimer <= 0.0f && aim && itemPos != Vector2.Zero)
|
||||
if (Anim != Animation.Climbing && !usingController && stunTimer <= 0.0f && aim && itemPos != Vector2.Zero)
|
||||
{
|
||||
Vector2 mousePos = ConvertUnits.ToSimUnits(character.CursorPosition);
|
||||
|
||||
Vector2 diff = (mousePos - torso.SimPosition) * Dir;
|
||||
|
||||
holdAngle = MathUtils.VectorToAngle(new Vector2(diff.X, diff.Y * Dir)) - torso.body.Rotation * Dir;
|
||||
//holdAngle = MathHelper.Clamp(MathUtils.WrapAnglePi(holdAngle), -1.3f, 1.0f);
|
||||
|
||||
itemAngle = (torso.body.Rotation + holdAngle * Dir);
|
||||
|
||||
@@ -909,7 +911,7 @@ namespace Barotrauma
|
||||
Vector2 shoulderPos = limbJoints[2].WorldAnchorA;
|
||||
Vector2 transformedHoldPos = shoulderPos;
|
||||
|
||||
if (itemPos == Vector2.Zero || Anim == Animation.Climbing || (leftHand.Disabled && rightHand.Disabled))
|
||||
if (itemPos == Vector2.Zero || Anim == Animation.Climbing || usingController)
|
||||
{
|
||||
if (character.SelectedItems[1] == item)
|
||||
{
|
||||
|
||||
@@ -487,7 +487,7 @@ namespace Barotrauma
|
||||
if (item == null) continue;
|
||||
|
||||
item.Pick(this, true, true, true);
|
||||
inventory.TryPutItem(item, i, false);
|
||||
inventory.TryPutItem(item, i, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,8 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (Screen.Selected == GameMain.EditMapScreen) return;
|
||||
|
||||
if (character.Oxygen < 50.0f && !character.IsDead)
|
||||
{
|
||||
Vector2 offset = Rand.Vector(noiseOverlay.size.X);
|
||||
|
||||
@@ -149,7 +149,7 @@ namespace Barotrauma
|
||||
return placed;
|
||||
}
|
||||
|
||||
public override bool TryPutItem(Item item, int index, bool createNetworkEvent)
|
||||
public override bool TryPutItem(Item item, int index, bool allowSwapping, bool createNetworkEvent)
|
||||
{
|
||||
//there's already an item in the slot
|
||||
if (Items[index] != null)
|
||||
@@ -173,7 +173,7 @@ namespace Barotrauma
|
||||
combined = true;
|
||||
}
|
||||
//if moving the item between slots in the same inventory
|
||||
else if (item.ParentInventory == this)
|
||||
else if (item.ParentInventory == this && allowSwapping)
|
||||
{
|
||||
int currentIndex = Array.IndexOf(Items, item);
|
||||
|
||||
@@ -182,16 +182,19 @@ namespace Barotrauma
|
||||
Items[currentIndex] = null;
|
||||
Items[index] = null;
|
||||
//if the item in the slot can be moved to the slot of the moved item
|
||||
if (TryPutItem(existingItem, currentIndex, false) &&
|
||||
TryPutItem(item, index, false))
|
||||
if (TryPutItem(existingItem, currentIndex, false, false) &&
|
||||
TryPutItem(item, index, false, false))
|
||||
{
|
||||
new Networking.NetworkEvent(Networking.NetworkEventType.InventoryUpdate, Owner.ID, true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Items[currentIndex] = null;
|
||||
Items[index] = null;
|
||||
|
||||
//swapping the items failed -> move them back to where they were
|
||||
TryPutItem(item, currentIndex, false);
|
||||
TryPutItem(existingItem, index, false);
|
||||
TryPutItem(item, currentIndex, false, false);
|
||||
TryPutItem(existingItem, index, false, false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -416,7 +419,7 @@ namespace Barotrauma
|
||||
|
||||
if (Items[i] != item && Items[i] != null) Items[i].Drop(character, false);
|
||||
|
||||
if (TryPutItem(item, i, false))
|
||||
if (TryPutItem(item, i, false, false))
|
||||
{
|
||||
if (droppedItems.Contains(item))
|
||||
{
|
||||
|
||||
@@ -241,7 +241,7 @@ namespace Barotrauma.Items.Components
|
||||
Item item = MapEntity.FindEntityByID(itemIds[i]) as Item;
|
||||
if (item == null) continue;
|
||||
|
||||
Inventory.TryPutItem(item, i, false);
|
||||
Inventory.TryPutItem(item, i, false, false);
|
||||
}
|
||||
|
||||
itemIds = null;
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace Barotrauma
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool TryPutItem(Item item, int i, bool createNetworkEvent = true)
|
||||
public virtual bool TryPutItem(Item item, int i, bool allowSwapping, bool createNetworkEvent)
|
||||
{
|
||||
if (Owner == null) return false;
|
||||
if (CanBePut(item,i))
|
||||
@@ -274,7 +274,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
//selectedSlot = slotIndex;
|
||||
TryPutItem(draggingItem, slotIndex);
|
||||
TryPutItem(draggingItem, slotIndex, true, true);
|
||||
draggingItem = null;
|
||||
}
|
||||
|
||||
@@ -351,11 +351,9 @@ namespace Barotrauma
|
||||
|
||||
public virtual bool FillNetworkData(NetworkEventType type, NetBuffer message, object data)
|
||||
{
|
||||
var foundItems = Array.FindAll(Items, i => i != null);
|
||||
message.Write((byte)foundItems.Count());
|
||||
foreach (Item item in foundItems)
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
message.Write((ushort)item.ID);
|
||||
message.Write((ushort)(Items[i]==null ? 0 : Items[i].ID));
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -368,31 +366,21 @@ namespace Barotrauma
|
||||
List<ushort> newItemIDs = new List<ushort>();
|
||||
List<Item> droppedItems = new List<Item>();
|
||||
List<Item> prevItems = new List<Item>(Items);
|
||||
|
||||
byte count = message.ReadByte();
|
||||
for (int i = 0; i<count; i++)
|
||||
{
|
||||
newItemIDs.Add(message.ReadUInt16());
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
if (Items[i] == null) continue;
|
||||
if (!newItemIDs.Contains(Items[i].ID))
|
||||
ushort itemId = message.ReadUInt16();
|
||||
if (itemId==0)
|
||||
{
|
||||
droppedItems.Add(Items[i]);
|
||||
Items[i].Drop(null, false);
|
||||
|
||||
continue;
|
||||
if (Items[i] != null) Items[i].Drop();
|
||||
}
|
||||
}
|
||||
foreach (ushort itemId in newItemIDs)
|
||||
{
|
||||
Item item = Entity.FindEntityByID(itemId) as Item;
|
||||
if (item == null) continue;
|
||||
else
|
||||
{
|
||||
var item = Entity.FindEntityByID(itemId) as Item;
|
||||
if (item == null) continue;
|
||||
|
||||
TryPutItem(item, item.AllowedSlots, false);
|
||||
if (droppedItems.Contains(item)) droppedItems.Remove(item);
|
||||
TryPutItem(item, i, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
lastUpdate = sendingTime;
|
||||
|
||||
@@ -44,9 +44,9 @@ namespace Barotrauma
|
||||
return (item!=null && Items[i]==null && container.CanBeContained(item));
|
||||
}
|
||||
|
||||
public override bool TryPutItem(Item item, int i, bool createNetworkEvent)
|
||||
public override bool TryPutItem(Item item, int i, bool allowSwapping, bool createNetworkEvent)
|
||||
{
|
||||
bool wasPut = base.TryPutItem(item, i, createNetworkEvent);
|
||||
bool wasPut = base.TryPutItem(item, i, allowSwapping, createNetworkEvent);
|
||||
|
||||
if (wasPut)
|
||||
{
|
||||
|
||||
@@ -289,7 +289,15 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
string denyMessage = inc.ReadString();
|
||||
|
||||
new GUIMessageBox("Couldn't connect to server", denyMessage);
|
||||
if (denyMessage == "Password required!" || denyMessage == "Wrong password!")
|
||||
{
|
||||
GameMain.ServerListScreen.JoinServer(serverIP, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
new GUIMessageBox("Couldn't connect to server", denyMessage);
|
||||
}
|
||||
|
||||
connectCanceled = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
restClient = new RestClient(NetConfig.MasterServerUrl);
|
||||
}
|
||||
|
||||
|
||||
var request = new RestRequest("masterserver2.php", Method.GET);
|
||||
request.AddParameter("action", "addserver");
|
||||
request.AddParameter("servername", name);
|
||||
@@ -631,12 +631,17 @@ namespace Barotrauma.Networking
|
||||
return;
|
||||
}
|
||||
|
||||
#if !DEBUG
|
||||
|
||||
if (userPassword != password)
|
||||
#if DEBUG
|
||||
if (!string.IsNullOrWhiteSpace(password) && string.IsNullOrWhiteSpace(userPassword))
|
||||
{
|
||||
inc.SenderConnection.Deny("Password required!");
|
||||
DebugConsole.NewMessage(name + " couldn't join the server (no password)", Color.Red);
|
||||
return;
|
||||
}
|
||||
else if (userPassword != password)
|
||||
{
|
||||
inc.SenderConnection.Deny("Wrong password!");
|
||||
DebugConsole.NewMessage(name +" couldn't join the server (wrong password)", Color.Red);
|
||||
DebugConsole.NewMessage(name + " couldn't join the server (wrong password)", Color.Red);
|
||||
return;
|
||||
}
|
||||
else if (version != GameMain.Version.ToString())
|
||||
@@ -657,7 +662,7 @@ namespace Barotrauma.Networking
|
||||
DebugConsole.NewMessage(name + " couldn't join the server (wrong content package hash)", Color.Red);
|
||||
return;
|
||||
}
|
||||
else if (ConnectedClients.Find(c => c.name.ToLower() == name.ToLower() && c.ID!=userID) != null)
|
||||
else if (ConnectedClients.Find(c => c.name.ToLower() == name.ToLower() && c.ID != userID) != null)
|
||||
{
|
||||
inc.SenderConnection.Deny("The name ''" + name + "'' is already in use. Please choose another name.");
|
||||
DebugConsole.NewMessage(name + " couldn't join the server (name already in use)", Color.Red);
|
||||
|
||||
@@ -160,6 +160,8 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
float sendingTime = message.ReadFloat();
|
||||
|
||||
sendingTime = (float)message.SenderConnection.GetLocalTime(sendingTime);
|
||||
|
||||
byte msgCount = message.ReadByte();
|
||||
long currPos = message.PositionInBytes;
|
||||
|
||||
|
||||
@@ -298,6 +298,10 @@ namespace Barotrauma
|
||||
{
|
||||
savePath = Path.Combine(Path.GetDirectoryName(Submarine.Loaded.FilePath), savePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
savePath = Path.Combine(Submarine.SavePath, savePath);
|
||||
}
|
||||
|
||||
Submarine.SaveCurrent(savePath);
|
||||
Submarine.Loaded.CheckForErrors();
|
||||
|
||||
@@ -293,17 +293,22 @@ namespace Barotrauma
|
||||
return false;
|
||||
}
|
||||
|
||||
CoroutineManager.StartCoroutine(JoinServer(ip));
|
||||
CoroutineManager.StartCoroutine(ConnectToServer(ip, serverList.Selected != null && (serverList.Selected.GetChild("password") as GUITickBox).Selected));
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private IEnumerable<object> JoinServer(string ip)
|
||||
public void JoinServer(string ip, bool hasPassword)
|
||||
{
|
||||
CoroutineManager.StartCoroutine(ConnectToServer(ip, hasPassword));
|
||||
}
|
||||
|
||||
private IEnumerable<object> ConnectToServer(string ip, bool hasPassword)
|
||||
{
|
||||
string selectedPassword = "";
|
||||
|
||||
if (serverList.Selected!=null && (serverList.Selected.GetChild("password") as GUITickBox).Selected)
|
||||
if (hasPassword)
|
||||
{
|
||||
var msgBox = new GUIMessageBox("Password required:", "", new string[] { "OK", "Cancel" });
|
||||
var passwordBox = new GUITextBox(new Rectangle(0,40,150,25), Alignment.TopLeft, GUI.Style, msgBox.children[0]);
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
/// <summary>
|
||||
/// Mersenne Twister based random
|
||||
/// </summary>
|
||||
public sealed class MTRandom : Random
|
||||
{
|
||||
private const int N = 624;
|
||||
private const int M = 397;
|
||||
private const uint MATRIX_A = 0x9908b0dfU;
|
||||
private const uint UPPER_MASK = 0x80000000U;
|
||||
private const uint LOWER_MASK = 0x7fffffffU;
|
||||
private const uint TEMPER1 = 0x9d2c5680U;
|
||||
private const uint TEMPER2 = 0xefc60000U;
|
||||
private const int TEMPER3 = 11;
|
||||
private const int TEMPER4 = 7;
|
||||
private const int TEMPER5 = 15;
|
||||
private const int TEMPER6 = 18;
|
||||
|
||||
private UInt32[] mt;
|
||||
private int mti;
|
||||
private UInt32[] mag01;
|
||||
|
||||
private const double c_realUnitInt = 1.0 / ((double)int.MaxValue + 1.0);
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with randomized seed
|
||||
/// </summary>
|
||||
public MTRandom()
|
||||
{
|
||||
Initialize((uint)Environment.TickCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with provided 32 bit seed
|
||||
/// </summary>
|
||||
[CLSCompliant(false)]
|
||||
public MTRandom(int seed)
|
||||
{
|
||||
Initialize((uint)Math.Abs(seed));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// (Re)initialize this instance with provided 32 bit seed
|
||||
/// </summary>
|
||||
[CLSCompliant(false)]
|
||||
private void Initialize(uint seed)
|
||||
{
|
||||
mt = new UInt32[N];
|
||||
mti = N + 1;
|
||||
mag01 = new UInt32[] { 0x0U, MATRIX_A };
|
||||
mt[0] = seed;
|
||||
for (int i = 1; i < N; i++)
|
||||
mt[i] = (UInt32)(1812433253 * (mt[i - 1] ^ (mt[i - 1] >> 30)) + i);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a random value from UInt32.MinValue to UInt32.MaxValue, inclusively
|
||||
/// </summary>
|
||||
[CLSCompliant(false)]
|
||||
private uint NextUInt32()
|
||||
{
|
||||
UInt32 y;
|
||||
if (mti >= N)
|
||||
{
|
||||
GenRandAll();
|
||||
mti = 0;
|
||||
}
|
||||
y = mt[mti++];
|
||||
y ^= (y >> TEMPER3);
|
||||
y ^= (y << TEMPER4) & TEMPER1;
|
||||
y ^= (y << TEMPER5) & TEMPER2;
|
||||
y ^= (y >> TEMPER6);
|
||||
return y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a random value that is greater or equal than 0 and less than Int32.MaxValue
|
||||
/// </summary>
|
||||
public override int Next()
|
||||
{
|
||||
var retval = (int)(0x7FFFFFFF & NextUInt32());
|
||||
if (retval == 0x7FFFFFFF)
|
||||
return NextInt32();
|
||||
return retval;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a random value is greater or equal than 0 and less than maxValue
|
||||
/// </summary>
|
||||
public override int Next(int maxValue)
|
||||
{
|
||||
return (int)(NextDouble() * maxValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a random value greater or equal than 0 and less or equal than Int32.MaxValue (inclusively)
|
||||
/// </summary>
|
||||
public int NextInt32()
|
||||
{
|
||||
return (int)(0x7FFFFFFF & NextUInt32());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns random value larger or equal to 0.0 and less than 1.0
|
||||
/// </summary>
|
||||
public override double NextDouble()
|
||||
{
|
||||
return c_realUnitInt * NextInt32();
|
||||
}
|
||||
|
||||
private void GenRandAll()
|
||||
{
|
||||
int kk = 1;
|
||||
UInt32 y;
|
||||
UInt32 p;
|
||||
y = mt[0] & UPPER_MASK;
|
||||
do
|
||||
{
|
||||
p = mt[kk];
|
||||
mt[kk - 1] = mt[kk + (M - 1)] ^ ((y | (p & LOWER_MASK)) >> 1) ^ mag01[p & 1];
|
||||
y = p & UPPER_MASK;
|
||||
} while (++kk < N - M + 1);
|
||||
do
|
||||
{
|
||||
p = mt[kk];
|
||||
mt[kk - 1] = mt[kk + (M - N - 1)] ^ ((y | (p & LOWER_MASK)) >> 1) ^ mag01[p & 1];
|
||||
y = p & UPPER_MASK;
|
||||
} while (++kk < N);
|
||||
p = mt[0];
|
||||
mt[N - 1] = mt[M - 1] ^ ((y | (p & LOWER_MASK)) >> 1) ^ mag01[p & 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Lidgren.Network;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -9,11 +10,11 @@ namespace Barotrauma
|
||||
static class Rand
|
||||
{
|
||||
private static Random localRandom = new Random();
|
||||
private static Random syncedRandom = new Random();
|
||||
private static Random syncedRandom = new MTRandom();
|
||||
|
||||
public static void SetSyncedSeed(int seed)
|
||||
{
|
||||
syncedRandom = new Random(seed);
|
||||
syncedRandom = new MTRandom(seed);
|
||||
}
|
||||
|
||||
public static float Range(float minimum, float maximum, bool local = true)
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
v0.3.4.0
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
Multiplayer:
|
||||
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v0.3.4.0
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
Multiplayer:
|
||||
- missing submarine files can be downloaded from the server host
|
||||
- player syncing bugfixes (aiming is visible to other players, smoother movement in water)
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user