- 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\Networking\GameServerSettings.cs" />
|
||||||
<Compile Include="Source\Screens\NetLobbyVoting.cs" />
|
<Compile Include="Source\Screens\NetLobbyVoting.cs" />
|
||||||
<Compile Include="Source\Screens\ServerListScreen.cs" />
|
<Compile Include="Source\Screens\ServerListScreen.cs" />
|
||||||
|
<Compile Include="Source\Utils\MTRandom.cs" />
|
||||||
<Compile Include="Source\Utils\Rand.cs" />
|
<Compile Include="Source\Utils\Rand.cs" />
|
||||||
<Compile Include="Source\Events\PropertyTask.cs" />
|
<Compile Include="Source\Events\PropertyTask.cs" />
|
||||||
<Compile Include="Source\Events\RepairTask.cs" />
|
<Compile Include="Source\Events\RepairTask.cs" />
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
<fabricableitem name="Incendium Fuel Rod" requireditems="Steel Bar, Incendium Bar"/>
|
<fabricableitem name="Incendium Fuel Rod" requireditems="Steel Bar, Incendium Bar"/>
|
||||||
</Fabricator>
|
</Fabricator>
|
||||||
|
|
||||||
<ConnectionPanel canbeselected = "true">
|
<ConnectionPanel selectkey="Action" canbeselected = "true">
|
||||||
<requireditem name="Screwdriver" type="Equipped"/>
|
<requireditem name="Screwdriver" type="Equipped"/>
|
||||||
<output name="power_in"/>
|
<output name="power_in"/>
|
||||||
</ConnectionPanel>
|
</ConnectionPanel>
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
<GuiFrame rect="0,0,300,200" alignment="Center" color="0.0,0.0,0.0,0.6"/>
|
<GuiFrame rect="0,0,300,200" alignment="Center" color="0.0,0.0,0.0,0.6"/>
|
||||||
</Deconstructor>
|
</Deconstructor>
|
||||||
|
|
||||||
<ConnectionPanel canbeselected = "true">
|
<ConnectionPanel selectkey="Action" canbeselected = "true">
|
||||||
<requireditem name="Screwdriver" type="Equipped"/>
|
<requireditem name="Screwdriver" type="Equipped"/>
|
||||||
<output name="power_in"/>
|
<output name="power_in"/>
|
||||||
</ConnectionPanel>
|
</ConnectionPanel>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
</StatusEffect>
|
</StatusEffect>
|
||||||
</Turret>
|
</Turret>
|
||||||
|
|
||||||
<ConnectionPanel canbeselected = "true" msg="Rewire [Screwdriver]">
|
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
|
||||||
<requireditem name="Screwdriver,Wire" type="Equipped"/>
|
<requireditem name="Screwdriver,Wire" type="Equipped"/>
|
||||||
<input name="power_in"/>
|
<input name="power_in"/>
|
||||||
<input name="position_in"/>
|
<input name="position_in"/>
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
<limbposition limb="RightHand" position="43,-85"/>
|
<limbposition limb="RightHand" position="43,-85"/>
|
||||||
</Controller>
|
</Controller>
|
||||||
|
|
||||||
<ConnectionPanel canbeselected = "true" msg="Rewire [Screwdriver]">
|
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
|
||||||
<requireditem name="Screwdriver,Wire" type="Equipped"/>
|
<requireditem name="Screwdriver,Wire" type="Equipped"/>
|
||||||
<input name="power_in"/>
|
<input name="power_in"/>
|
||||||
<output name="position_out"/>
|
<output name="position_out"/>
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!character.SelectedItems.Contains(weapon))
|
if (!character.SelectedItems.Contains(weapon))
|
||||||
{
|
{
|
||||||
character.Inventory.TryPutItem(weapon, 3, false);
|
character.Inventory.TryPutItem(weapon, 3, true, false);
|
||||||
weapon.Equip(character);
|
weapon.Equip(character);
|
||||||
}
|
}
|
||||||
character.CursorPosition = enemy.Position;
|
character.CursorPosition = enemy.Position;
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (targetSlot>-1 && character.Inventory.IsInLimbSlot(targetItem, LimbSlot.Any))
|
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;
|
Vector2 itemPos = aim ? aimPos : holdPos;
|
||||||
|
|
||||||
|
bool usingController = character.SelectedConstruction != null && character.SelectedConstruction.GetComponent<Controller>() != null;
|
||||||
|
|
||||||
|
|
||||||
float itemAngle;
|
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 mousePos = ConvertUnits.ToSimUnits(character.CursorPosition);
|
||||||
|
|
||||||
Vector2 diff = (mousePos - torso.SimPosition) * Dir;
|
Vector2 diff = (mousePos - torso.SimPosition) * Dir;
|
||||||
|
|
||||||
holdAngle = MathUtils.VectorToAngle(new Vector2(diff.X, diff.Y * Dir)) - torso.body.Rotation * 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);
|
itemAngle = (torso.body.Rotation + holdAngle * Dir);
|
||||||
|
|
||||||
@@ -909,7 +911,7 @@ namespace Barotrauma
|
|||||||
Vector2 shoulderPos = limbJoints[2].WorldAnchorA;
|
Vector2 shoulderPos = limbJoints[2].WorldAnchorA;
|
||||||
Vector2 transformedHoldPos = shoulderPos;
|
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)
|
if (character.SelectedItems[1] == item)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -487,7 +487,7 @@ namespace Barotrauma
|
|||||||
if (item == null) continue;
|
if (item == null) continue;
|
||||||
|
|
||||||
item.Pick(this, true, true, true);
|
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)
|
if (character.Oxygen < 50.0f && !character.IsDead)
|
||||||
{
|
{
|
||||||
Vector2 offset = Rand.Vector(noiseOverlay.size.X);
|
Vector2 offset = Rand.Vector(noiseOverlay.size.X);
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ namespace Barotrauma
|
|||||||
return placed;
|
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
|
//there's already an item in the slot
|
||||||
if (Items[index] != null)
|
if (Items[index] != null)
|
||||||
@@ -173,7 +173,7 @@ namespace Barotrauma
|
|||||||
combined = true;
|
combined = true;
|
||||||
}
|
}
|
||||||
//if moving the item between slots in the same inventory
|
//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);
|
int currentIndex = Array.IndexOf(Items, item);
|
||||||
|
|
||||||
@@ -182,16 +182,19 @@ namespace Barotrauma
|
|||||||
Items[currentIndex] = null;
|
Items[currentIndex] = null;
|
||||||
Items[index] = null;
|
Items[index] = null;
|
||||||
//if the item in the slot can be moved to the slot of the moved item
|
//if the item in the slot can be moved to the slot of the moved item
|
||||||
if (TryPutItem(existingItem, currentIndex, false) &&
|
if (TryPutItem(existingItem, currentIndex, false, false) &&
|
||||||
TryPutItem(item, index, false))
|
TryPutItem(item, index, false, false))
|
||||||
{
|
{
|
||||||
new Networking.NetworkEvent(Networking.NetworkEventType.InventoryUpdate, Owner.ID, true, true);
|
new Networking.NetworkEvent(Networking.NetworkEventType.InventoryUpdate, Owner.ID, true, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Items[currentIndex] = null;
|
||||||
|
Items[index] = null;
|
||||||
|
|
||||||
//swapping the items failed -> move them back to where they were
|
//swapping the items failed -> move them back to where they were
|
||||||
TryPutItem(item, currentIndex, false);
|
TryPutItem(item, currentIndex, false, false);
|
||||||
TryPutItem(existingItem, index, 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 (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))
|
if (droppedItems.Contains(item))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ namespace Barotrauma.Items.Components
|
|||||||
Item item = MapEntity.FindEntityByID(itemIds[i]) as Item;
|
Item item = MapEntity.FindEntityByID(itemIds[i]) as Item;
|
||||||
if (item == null) continue;
|
if (item == null) continue;
|
||||||
|
|
||||||
Inventory.TryPutItem(item, i, false);
|
Inventory.TryPutItem(item, i, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
itemIds = null;
|
itemIds = null;
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ namespace Barotrauma
|
|||||||
return true;
|
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 (Owner == null) return false;
|
||||||
if (CanBePut(item,i))
|
if (CanBePut(item,i))
|
||||||
@@ -274,7 +274,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
//selectedSlot = slotIndex;
|
//selectedSlot = slotIndex;
|
||||||
TryPutItem(draggingItem, slotIndex);
|
TryPutItem(draggingItem, slotIndex, true, true);
|
||||||
draggingItem = null;
|
draggingItem = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,11 +351,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public virtual bool FillNetworkData(NetworkEventType type, NetBuffer message, object data)
|
public virtual bool FillNetworkData(NetworkEventType type, NetBuffer message, object data)
|
||||||
{
|
{
|
||||||
var foundItems = Array.FindAll(Items, i => i != null);
|
for (int i = 0; i < capacity; i++)
|
||||||
message.Write((byte)foundItems.Count());
|
|
||||||
foreach (Item item in foundItems)
|
|
||||||
{
|
{
|
||||||
message.Write((ushort)item.ID);
|
message.Write((ushort)(Items[i]==null ? 0 : Items[i].ID));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -368,31 +366,21 @@ namespace Barotrauma
|
|||||||
List<ushort> newItemIDs = new List<ushort>();
|
List<ushort> newItemIDs = new List<ushort>();
|
||||||
List<Item> droppedItems = new List<Item>();
|
List<Item> droppedItems = new List<Item>();
|
||||||
List<Item> prevItems = new List<Item>(Items);
|
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++)
|
for (int i = 0; i < capacity; i++)
|
||||||
{
|
{
|
||||||
if (Items[i] == null) continue;
|
ushort itemId = message.ReadUInt16();
|
||||||
if (!newItemIDs.Contains(Items[i].ID))
|
if (itemId==0)
|
||||||
{
|
{
|
||||||
droppedItems.Add(Items[i]);
|
if (Items[i] != null) Items[i].Drop();
|
||||||
Items[i].Drop(null, false);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
foreach (ushort itemId in newItemIDs)
|
{
|
||||||
{
|
var item = Entity.FindEntityByID(itemId) as Item;
|
||||||
Item item = Entity.FindEntityByID(itemId) as Item;
|
if (item == null) continue;
|
||||||
if (item == null) continue;
|
|
||||||
|
|
||||||
TryPutItem(item, item.AllowedSlots, false);
|
TryPutItem(item, i, true, false);
|
||||||
if (droppedItems.Contains(item)) droppedItems.Remove(item);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastUpdate = sendingTime;
|
lastUpdate = sendingTime;
|
||||||
|
|||||||
@@ -44,9 +44,9 @@ namespace Barotrauma
|
|||||||
return (item!=null && Items[i]==null && container.CanBeContained(item));
|
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)
|
if (wasPut)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -289,7 +289,15 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
string denyMessage = inc.ReadString();
|
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;
|
connectCanceled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
restClient = new RestClient(NetConfig.MasterServerUrl);
|
restClient = new RestClient(NetConfig.MasterServerUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
var request = new RestRequest("masterserver2.php", Method.GET);
|
var request = new RestRequest("masterserver2.php", Method.GET);
|
||||||
request.AddParameter("action", "addserver");
|
request.AddParameter("action", "addserver");
|
||||||
request.AddParameter("servername", name);
|
request.AddParameter("servername", name);
|
||||||
@@ -631,12 +631,17 @@ namespace Barotrauma.Networking
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !DEBUG
|
#if DEBUG
|
||||||
|
if (!string.IsNullOrWhiteSpace(password) && string.IsNullOrWhiteSpace(userPassword))
|
||||||
if (userPassword != password)
|
{
|
||||||
|
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!");
|
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;
|
return;
|
||||||
}
|
}
|
||||||
else if (version != GameMain.Version.ToString())
|
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);
|
DebugConsole.NewMessage(name + " couldn't join the server (wrong content package hash)", Color.Red);
|
||||||
return;
|
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.");
|
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);
|
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();
|
float sendingTime = message.ReadFloat();
|
||||||
|
|
||||||
|
sendingTime = (float)message.SenderConnection.GetLocalTime(sendingTime);
|
||||||
|
|
||||||
byte msgCount = message.ReadByte();
|
byte msgCount = message.ReadByte();
|
||||||
long currPos = message.PositionInBytes;
|
long currPos = message.PositionInBytes;
|
||||||
|
|
||||||
|
|||||||
@@ -298,6 +298,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
savePath = Path.Combine(Path.GetDirectoryName(Submarine.Loaded.FilePath), savePath);
|
savePath = Path.Combine(Path.GetDirectoryName(Submarine.Loaded.FilePath), savePath);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
savePath = Path.Combine(Submarine.SavePath, savePath);
|
||||||
|
}
|
||||||
|
|
||||||
Submarine.SaveCurrent(savePath);
|
Submarine.SaveCurrent(savePath);
|
||||||
Submarine.Loaded.CheckForErrors();
|
Submarine.Loaded.CheckForErrors();
|
||||||
|
|||||||
@@ -293,17 +293,22 @@ namespace Barotrauma
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CoroutineManager.StartCoroutine(JoinServer(ip));
|
CoroutineManager.StartCoroutine(ConnectToServer(ip, serverList.Selected != null && (serverList.Selected.GetChild("password") as GUITickBox).Selected));
|
||||||
|
|
||||||
|
|
||||||
return true;
|
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 = "";
|
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 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]);
|
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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -9,11 +10,11 @@ namespace Barotrauma
|
|||||||
static class Rand
|
static class Rand
|
||||||
{
|
{
|
||||||
private static Random localRandom = new Random();
|
private static Random localRandom = new Random();
|
||||||
private static Random syncedRandom = new Random();
|
private static Random syncedRandom = new MTRandom();
|
||||||
|
|
||||||
public static void SetSyncedSeed(int seed)
|
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)
|
public static float Range(float minimum, float maximum, bool local = true)
|
||||||
|
|||||||
@@ -2,6 +2,12 @@
|
|||||||
v0.3.4.0
|
v0.3.4.0
|
||||||
---------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Multiplayer:
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
v0.3.4.0
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
Multiplayer:
|
Multiplayer:
|
||||||
- missing submarine files can be downloaded from the server host
|
- missing submarine files can be downloaded from the server host
|
||||||
- player syncing bugfixes (aiming is visible to other players, smoother movement in water)
|
- player syncing bugfixes (aiming is visible to other players, smoother movement in water)
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user