Build 0.18.7.0
This commit is contained in:
@@ -3,7 +3,6 @@ using Barotrauma.Items.Components;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@@ -287,6 +287,11 @@ namespace Barotrauma
|
||||
InputBox.OnDeselected += (gui, Keys) =>
|
||||
{
|
||||
ChatManager.Clear();
|
||||
if (GUIFrame.IsParentOf(GUI.MouseOn))
|
||||
{
|
||||
CloseAfterMessageSent = false;
|
||||
return;
|
||||
}
|
||||
ChatMessage.GetChatMessageCommand(InputBox.Text, out var message);
|
||||
if (string.IsNullOrEmpty(message))
|
||||
{
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Barotrauma
|
||||
get { return inventoryTopY; }
|
||||
set
|
||||
{
|
||||
if (value == inventoryTopY) return;
|
||||
if (value == inventoryTopY) { return; }
|
||||
inventoryTopY = value;
|
||||
CreateAreas();
|
||||
}
|
||||
@@ -91,8 +91,6 @@ namespace Barotrauma
|
||||
if (GameMain.Instance != null)
|
||||
{
|
||||
GameMain.Instance.ResolutionChanged += CreateAreas;
|
||||
#warning TODO: reimplement
|
||||
//GameSettings.CurrentConfig.OnHUDScaleChanged += CreateAreas;
|
||||
CreateAreas();
|
||||
CharacterInfo.Init();
|
||||
}
|
||||
|
||||
@@ -1559,10 +1559,10 @@ namespace Barotrauma
|
||||
RichString missionReputationString = RichString.Rich(reputationText, wrapMissionText(GUIStyle.Font));
|
||||
RichString missionDescriptionString = RichString.Rich(descriptionText, wrapMissionText(GUIStyle.Font));
|
||||
|
||||
Vector2 missionNameSize = GUIStyle.LargeFont.MeasureString(missionNameString);
|
||||
Vector2 missionDescriptionSize = GUIStyle.Font.MeasureString(missionDescriptionString);
|
||||
Vector2 missionRewardSize = GUIStyle.Font.MeasureString(missionRewardString);
|
||||
Vector2 missionReputationSize = GUIStyle.Font.MeasureString(missionReputationString);
|
||||
Vector2 missionNameSize = GUIStyle.LargeFont.MeasureString(missionNameString.SanitizedValue);
|
||||
Vector2 missionDescriptionSize = GUIStyle.Font.MeasureString(missionDescriptionString.SanitizedValue);
|
||||
Vector2 missionRewardSize = GUIStyle.Font.MeasureString(missionRewardString.SanitizedValue);
|
||||
Vector2 missionReputationSize = GUIStyle.Font.MeasureString(missionReputationString.SanitizedValue);
|
||||
|
||||
float ySize = missionNameSize.Y + missionDescriptionSize.Y + missionRewardSize.Y + missionReputationSize.Y + missionTextGroup.AbsoluteSpacing * 4;
|
||||
bool displayDifficulty = mission.Difficulty.HasValue;
|
||||
|
||||
@@ -102,29 +102,11 @@ namespace Barotrauma.Tutorials
|
||||
radioSpeakerName = TextManager.Get("Tutorial.Radio.Watchman");
|
||||
GameMain.GameSession.CrewManager.AllowCharacterSwitch = false;
|
||||
|
||||
var revolver = FindOrGiveItem(captain, "revolver".ToIdentifier());
|
||||
revolver.Unequip(captain);
|
||||
captain.Inventory.RemoveItem(revolver);
|
||||
|
||||
var captainscap =
|
||||
captain.Inventory.FindItemByIdentifier("captainscap1".ToIdentifier()) ??
|
||||
captain.Inventory.FindItemByIdentifier("captainscap2".ToIdentifier()) ??
|
||||
captain.Inventory.FindItemByIdentifier("captainscap3".ToIdentifier());
|
||||
|
||||
if (captainscap != null)
|
||||
foreach (Item item in captain.Inventory.AllItemsMod)
|
||||
{
|
||||
captainscap.Unequip(captain);
|
||||
captain.Inventory.RemoveItem(captainscap);
|
||||
}
|
||||
|
||||
var captainsuniform =
|
||||
captain.Inventory.FindItemByIdentifier("captainsuniform1".ToIdentifier()) ??
|
||||
captain.Inventory.FindItemByIdentifier("captainsuniform2".ToIdentifier()) ??
|
||||
captain.Inventory.FindItemByIdentifier("captainsuniform3".ToIdentifier());
|
||||
if (captainsuniform != null)
|
||||
{
|
||||
captainsuniform.Unequip(captain);
|
||||
captain.Inventory.RemoveItem(captainsuniform);
|
||||
if (item.HasTag("identitycard") || item.HasTag("headset")) { continue; }
|
||||
item.Unequip(captain);
|
||||
captain.Inventory.RemoveItem(item);
|
||||
}
|
||||
|
||||
var steerOrder = OrderPrefab.Prefabs["steer"];
|
||||
|
||||
@@ -105,21 +105,12 @@ namespace Barotrauma.Tutorials
|
||||
radioSpeakerName = TextManager.Get("Tutorial.Radio.Speaker");
|
||||
doctor = Character.Controlled;
|
||||
|
||||
var bandages = FindOrGiveItem(doctor, "antibleeding1".ToIdentifier());
|
||||
bandages.Unequip(doctor);
|
||||
doctor.Inventory.RemoveItem(bandages);
|
||||
|
||||
var syringegun = FindOrGiveItem(doctor, "syringegun".ToIdentifier());
|
||||
syringegun.Unequip(doctor);
|
||||
doctor.Inventory.RemoveItem(syringegun);
|
||||
|
||||
var antibiotics = FindOrGiveItem(doctor, "antibiotics".ToIdentifier());
|
||||
antibiotics.Unequip(doctor);
|
||||
doctor.Inventory.RemoveItem(antibiotics);
|
||||
|
||||
var morphine = FindOrGiveItem(doctor, "antidama1".ToIdentifier());
|
||||
morphine.Unequip(doctor);
|
||||
doctor.Inventory.RemoveItem(morphine);
|
||||
foreach (Item item in doctor.Inventory.AllItemsMod)
|
||||
{
|
||||
if (item.HasTag("clothing") || item.HasTag("identitycard") || item.HasTag("headset")) { continue; }
|
||||
item.Unequip(doctor);
|
||||
doctor.Inventory.RemoveItem(item);
|
||||
}
|
||||
|
||||
doctor_suppliesCabinet = Item.ItemList.Find(i => i.HasTag("doctor_suppliescabinet"))?.GetComponent<ItemContainer>();
|
||||
doctor_medBayCabinet = Item.ItemList.Find(i => i.HasTag("doctor_medbaycabinet"))?.GetComponent<ItemContainer>();
|
||||
|
||||
@@ -131,9 +131,12 @@ namespace Barotrauma.Tutorials
|
||||
radioSpeakerName = TextManager.Get("Tutorial.Radio.Speaker");
|
||||
engineer = Character.Controlled;
|
||||
|
||||
var toolbelt = FindOrGiveItem(engineer, "toolbelt".ToIdentifier());
|
||||
toolbelt.Unequip(engineer);
|
||||
engineer.Inventory.RemoveItem(toolbelt);
|
||||
foreach (Item item in engineer.Inventory.AllItemsMod)
|
||||
{
|
||||
if (item.HasTag("clothing") || item.HasTag("identitycard") || item.HasTag("headset")) { continue; }
|
||||
item.Unequip(engineer);
|
||||
engineer.Inventory.RemoveItem(item);
|
||||
}
|
||||
|
||||
var repairOrder = OrderPrefab.Prefabs["repairsystems"];
|
||||
engineer_repairIcon = repairOrder.SymbolSprite;
|
||||
|
||||
@@ -160,13 +160,12 @@ namespace Barotrauma.Tutorials
|
||||
radioSpeakerName = TextManager.Get("Tutorial.Radio.Speaker");
|
||||
mechanic = Character.Controlled;
|
||||
|
||||
var toolbelt = FindOrGiveItem(mechanic, "toolbelt".ToIdentifier());
|
||||
toolbelt.Unequip(mechanic);
|
||||
mechanic.Inventory.RemoveItem(toolbelt);
|
||||
|
||||
var crowbar = FindOrGiveItem(mechanic, "crowbar".ToIdentifier());
|
||||
crowbar.Unequip(mechanic);
|
||||
mechanic.Inventory.RemoveItem(crowbar);
|
||||
foreach (Item item in mechanic.Inventory.AllItemsMod)
|
||||
{
|
||||
if (item.HasTag("clothing") || item.HasTag("identitycard") || item.HasTag("headset")) { continue; }
|
||||
item.Unequip(mechanic);
|
||||
mechanic.Inventory.RemoveItem(item);
|
||||
}
|
||||
|
||||
var repairOrder = OrderPrefab.Prefabs["repairsystems"];
|
||||
mechanic_repairIcon = repairOrder.SymbolSprite;
|
||||
@@ -297,7 +296,10 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
mechanic_brokenhull_1.WaterVolume = MathHelper.Clamp(mechanic_brokenhull_1.WaterVolume, 0, mechanic_brokenhull_1.Volume * 0.85f);
|
||||
if (mechanic_brokenhull_1 != null)
|
||||
{
|
||||
mechanic_brokenhull_1.WaterVolume = MathHelper.Clamp(mechanic_brokenhull_1.WaterVolume, 0, mechanic_brokenhull_1.Volume * 0.85f);
|
||||
}
|
||||
base.Update(deltaTime);
|
||||
}
|
||||
|
||||
@@ -413,7 +415,7 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
} while (mechanic_workingPump.FlowPercentage >= 0 || !mechanic_workingPump.IsActive); // Highlight until draining
|
||||
SetHighlight(mechanic_workingPump.Item, false);
|
||||
do { yield return null; } while (mechanic_brokenhull_1.WaterPercentage > waterVolumeBeforeOpening); // Unlock door once drained
|
||||
do { yield return null; } while (mechanic_brokenhull_1 != null && mechanic_brokenhull_1.WaterPercentage > waterVolumeBeforeOpening); // Unlock door once drained
|
||||
RemoveCompletedObjective(3);
|
||||
GameAnalyticsManager.AddDesignEvent("Tutorial:MechanicTutorial:Objective3");
|
||||
|
||||
|
||||
@@ -141,36 +141,12 @@ namespace Barotrauma.Tutorials
|
||||
radioSpeakerName = TextManager.Get("Tutorial.Radio.Speaker");
|
||||
officer = Character.Controlled;
|
||||
|
||||
var handcuffs = FindOrGiveItem(officer, "handcuffs".ToIdentifier());
|
||||
handcuffs.Unequip(officer);
|
||||
officer.Inventory.RemoveItem(handcuffs);
|
||||
|
||||
var stunbaton = FindOrGiveItem(officer, "stunbaton".ToIdentifier());
|
||||
stunbaton.Unequip(officer);
|
||||
officer.Inventory.RemoveItem(stunbaton);
|
||||
|
||||
var smg = FindOrGiveItem(officer, "smg".ToIdentifier());
|
||||
smg.Unequip(officer);
|
||||
officer.Inventory.RemoveItem(smg);
|
||||
|
||||
var divingknife = FindOrGiveItem(officer, "divingknife".ToIdentifier());
|
||||
divingknife.Unequip(officer);
|
||||
officer.Inventory.RemoveItem(divingknife);
|
||||
|
||||
var steroids = FindOrGiveItem(officer, "steroids".ToIdentifier());
|
||||
steroids.Unequip(officer);
|
||||
officer.Inventory.RemoveItem(steroids);
|
||||
|
||||
var ballistichelmet =
|
||||
officer.Inventory.FindItemByIdentifier("ballistichelmet1".ToIdentifier()) ??
|
||||
officer.Inventory.FindItemByIdentifier("ballistichelmet2".ToIdentifier()) ??
|
||||
FindOrGiveItem(officer, "ballistichelmet3".ToIdentifier());
|
||||
ballistichelmet.Unequip(officer);
|
||||
officer.Inventory.RemoveItem(ballistichelmet);
|
||||
|
||||
var bodyarmor = FindOrGiveItem(officer, "bodyarmor".ToIdentifier());
|
||||
bodyarmor.Unequip(officer);
|
||||
officer.Inventory.RemoveItem(bodyarmor);
|
||||
foreach (Item item in officer.Inventory.AllItemsMod)
|
||||
{
|
||||
if (item.HasTag("clothing") || item.HasTag("identitycard") || item.HasTag("headset")) { continue; }
|
||||
item.Unequip(officer);
|
||||
officer.Inventory.RemoveItem(item);
|
||||
}
|
||||
|
||||
var gunOrder = OrderPrefab.Prefabs["operateweapons"];
|
||||
officer_gunIcon = gunOrder.SymbolSprite;
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Barotrauma
|
||||
UserListData = "ReadyUserList",
|
||||
ReadySpriteData = "ReadySprite";
|
||||
|
||||
private int lastSecond;
|
||||
private int lastSecond = 1;
|
||||
|
||||
private GUIMessageBox? msgBox;
|
||||
private GUIMessageBox? resultsBox;
|
||||
@@ -44,7 +44,7 @@ namespace Barotrauma
|
||||
msgBox = new GUIMessageBox(readyCheckHeader, readyCheckBody(author), new[] { yesButton, noButton }, relativeSize, minSize, type: GUIMessageBox.Type.Vote) { UserData = PromptData, Draggable = true };
|
||||
|
||||
GUILayoutGroup contentLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.125f), msgBox.Content.RectTransform), childAnchor: Anchor.Center);
|
||||
new GUIProgressBar(new RectTransform(new Vector2(0.8f, 1f), contentLayout.RectTransform), time / endTime, GUIStyle.Orange) { UserData = TimerData };
|
||||
new GUIProgressBar(new RectTransform(new Vector2(0.8f, 1f), contentLayout.RectTransform), 0.0f, GUIStyle.Orange) { UserData = TimerData };
|
||||
|
||||
// Yes
|
||||
msgBox.Buttons[0].OnClicked = delegate
|
||||
@@ -116,17 +116,18 @@ namespace Barotrauma
|
||||
|
||||
private void UpdateBar()
|
||||
{
|
||||
double elapsedTime = (DateTime.Now - startTime).TotalSeconds;
|
||||
if (msgBox != null && !msgBox.Closed && GUIMessageBox.MessageBoxes.Contains(msgBox))
|
||||
{
|
||||
if (msgBox.FindChild(TimerData, true) is GUIProgressBar bar)
|
||||
{
|
||||
bar.BarSize = time / endTime;
|
||||
bar.BarSize = (float)(elapsedTime / (endTime - startTime).TotalSeconds);
|
||||
}
|
||||
}
|
||||
|
||||
// play click sound after a second has passed
|
||||
int second = (int) Math.Ceiling(time);
|
||||
if (second < lastSecond)
|
||||
int second = (int)Math.Ceiling(elapsedTime);
|
||||
if (second > lastSecond)
|
||||
{
|
||||
if (msgBox != null && !msgBox.Closed)
|
||||
{
|
||||
@@ -156,7 +157,8 @@ namespace Barotrauma
|
||||
bool isOwn = false;
|
||||
byte authorId = 0;
|
||||
|
||||
float duration = inc.ReadSingle();
|
||||
long startTime = inc.ReadInt64();
|
||||
long endTime = inc.ReadInt64();
|
||||
string author = inc.ReadString();
|
||||
bool hasAuthor = inc.ReadBoolean();
|
||||
|
||||
@@ -173,7 +175,9 @@ namespace Barotrauma
|
||||
clients.Add(inc.ReadByte());
|
||||
}
|
||||
|
||||
ReadyCheck rCheck = new ReadyCheck(clients, duration);
|
||||
ReadyCheck rCheck = new ReadyCheck(clients,
|
||||
DateTimeOffset.FromUnixTimeSeconds(startTime).LocalDateTime,
|
||||
DateTimeOffset.FromUnixTimeSeconds(endTime).LocalDateTime);
|
||||
crewManager.ActiveReadyCheck = rCheck;
|
||||
|
||||
if (isOwn)
|
||||
@@ -192,12 +196,10 @@ namespace Barotrauma
|
||||
}
|
||||
break;
|
||||
case ReadyCheckState.Update:
|
||||
float time = inc.ReadSingle();
|
||||
ReadyStatus newState = (ReadyStatus) inc.ReadByte();
|
||||
byte targetId = inc.ReadByte();
|
||||
if (crewManager.ActiveReadyCheck != null)
|
||||
{
|
||||
crewManager.ActiveReadyCheck.time = time;
|
||||
crewManager.ActiveReadyCheck?.UpdateState(targetId, newState);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -222,7 +222,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (brokenSprite != null && item.Health < item.MaxCondition)
|
||||
{
|
||||
Vector2 scale = scaleBrokenSprite ? new Vector2(1.0f, 1.0f - item.Health / item.MaxCondition) : Vector2.One;
|
||||
Vector2 scale = scaleBrokenSprite ? new Vector2(1.0f - item.Health / item.MaxCondition) : Vector2.One;
|
||||
if (IsHorizontal) { scale.X = 1; } else { scale.Y = 1; }
|
||||
float alpha = fadeBrokenSprite ? 1.0f - item.Health / item.MaxCondition : 1.0f;
|
||||
spriteBatch.Draw(brokenSprite.Texture, pos,
|
||||
getSourceRect(brokenSprite, openState, IsHorizontal),
|
||||
|
||||
@@ -405,7 +405,7 @@ namespace Barotrauma.Items.Components
|
||||
float newVolume;
|
||||
try
|
||||
{
|
||||
newVolume = property.GetFloatValue(this);
|
||||
newVolume = Math.Min(property.GetFloatValue(this), 1.0f);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@@ -58,6 +58,8 @@ namespace Barotrauma.Items.Components
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
layoutGroup.Recalculate();
|
||||
}
|
||||
|
||||
// Create fillerBlock to cover historyBox so new values appear at the bottom of historyBox
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Barotrauma
|
||||
DrawArrow(FlowTargetHull, IsHorizontal ? rect.Height: rect.Width, Math.Abs(lerpedFlowForce.Length()), Color.Red * 0.3f);
|
||||
}
|
||||
|
||||
if (outsideCollisionBlocker.Enabled && Submarine != null)
|
||||
if (Submarine != null && outsideCollisionBlocker != null && outsideCollisionBlocker.Enabled)
|
||||
{
|
||||
var edgeShape = outsideCollisionBlocker.FixtureList[0].Shape as FarseerPhysics.Collision.Shapes.EdgeShape;
|
||||
Vector2 startPos = ConvertUnits.ToDisplayUnits(outsideCollisionBlocker.GetWorldPoint(edgeShape.Vertex1)) + Submarine.Position;
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Barotrauma
|
||||
partial class SubmarineInfo : IDisposable
|
||||
{
|
||||
public Sprite PreviewImage;
|
||||
|
||||
|
||||
partial void InitProjectSpecific()
|
||||
{
|
||||
string previewImageData = SubmarineElement.GetAttributeString("previewimage", "");
|
||||
|
||||
@@ -1200,7 +1200,14 @@ namespace Barotrauma.Networking
|
||||
new LocalizedString[] { TextManager.Get("Cancel") });
|
||||
reconnectBox.Buttons[0].OnClicked += (btn, userdata) => { CancelConnect(); return true; };
|
||||
connected = false;
|
||||
|
||||
var prevContentPackages = clientPeer.ServerContentPackages;
|
||||
ConnectToServer(serverEndpoint, serverName);
|
||||
if (clientPeer != null)
|
||||
{
|
||||
//restore the previous list of content packages so we can reconnect immediately without having to recheck that the packages match
|
||||
clientPeer.ServerContentPackages = prevContentPackages;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace Barotrauma.Networking
|
||||
msg.Write((byte)ClientNetObject.CHAT_MESSAGE);
|
||||
msg.Write(NetStateID);
|
||||
msg.WriteRangedInteger((int)ChatMessageType.Order, 0, Enum.GetValues(typeof(ChatMessageType)).Length - 1);
|
||||
msg.WriteRangedInteger((int)ChatMode.None, 0, Enum.GetValues(typeof(ChatMode)).Length - 1);
|
||||
WriteOrder(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
public ImmutableArray<ServerContentPackage> ServerContentPackages { get; private set; } =
|
||||
public ImmutableArray<ServerContentPackage> ServerContentPackages { get; set; } =
|
||||
ImmutableArray<ServerContentPackage>.Empty;
|
||||
|
||||
public delegate void MessageCallback(IReadMessage message);
|
||||
|
||||
@@ -117,8 +117,6 @@ namespace Barotrauma.Networking
|
||||
|
||||
PacketHeader packetHeader = (PacketHeader)inc.ReadByte();
|
||||
|
||||
//Console.WriteLine(isCompressed + " " + isConnectionInitializationStep + " " + (int)incByte);
|
||||
|
||||
if (packetHeader.IsConnectionInitializationStep() && initializationStep != ConnectionInitialization.Success)
|
||||
{
|
||||
ReadConnectionInitializationStep(new ReadWriteMessage(inc.Data, (int)inc.Position, inc.LengthBits, false));
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace Barotrauma
|
||||
public SettingValue<GameDifficulty> Difficulty;
|
||||
public SettingValue<Identifier> StartItemSet;
|
||||
|
||||
public CampaignSettings CreateSettings()
|
||||
public readonly CampaignSettings CreateSettings()
|
||||
{
|
||||
return new CampaignSettings(element: null)
|
||||
{
|
||||
|
||||
@@ -210,8 +210,17 @@ namespace Barotrauma
|
||||
{
|
||||
CreateCustomizeWindow(CurrentSettings, settings =>
|
||||
{
|
||||
CampaignSettings prevSettings = CurrentSettings;
|
||||
CurrentSettings = settings;
|
||||
UpdateSubList(SubmarineInfo.SavedSubmarines);
|
||||
if (prevSettings.InitialMoney != settings.InitialMoney)
|
||||
{
|
||||
object selectedData = subList.SelectedData;
|
||||
UpdateSubList(SubmarineInfo.SavedSubmarines);
|
||||
if (selectedData is SubmarineInfo selectedSub && selectedSub.Price <= CurrentSettings.InitialMoney)
|
||||
{
|
||||
subList.Select(selectedData);
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
@@ -519,7 +528,7 @@ namespace Barotrauma
|
||||
subsToShow = submarines.Where(s => s.IsCampaignCompatibleIgnoreClass && Path.GetDirectoryName(Path.GetFullPath(s.FilePath)) != downloadFolder).ToList();
|
||||
}
|
||||
|
||||
subsToShow.Sort((s1, s2) =>
|
||||
subsToShow.Sort((s1, s2) =>
|
||||
{
|
||||
int p1 = s1.Price > CurrentSettings.InitialMoney ? 10 : 0;
|
||||
int p2 = s2.Price > CurrentSettings.InitialMoney ? 10 : 0;
|
||||
@@ -537,7 +546,7 @@ namespace Barotrauma
|
||||
ToolTip = sub.Description,
|
||||
UserData = sub
|
||||
};
|
||||
|
||||
|
||||
if (!sub.RequiredContentPackagesInstalled)
|
||||
{
|
||||
textBlock.TextColor = Color.Lerp(textBlock.TextColor, Color.DarkRed, .5f);
|
||||
|
||||
@@ -513,18 +513,18 @@ namespace Barotrauma
|
||||
var moduleLabel = new GUITextBlock(new RectTransform(new Point(editorContainer.Content.Rect.Width, (int)(70 * GUI.Scale))), TextManager.Get("submarinetype.outpostmodules"), font: GUIStyle.SubHeadingFont);
|
||||
outpostParamsEditor.AddCustomContent(moduleLabel, 100);
|
||||
|
||||
foreach (KeyValuePair<Identifier, int> moduleCount in outpostGenerationParams.ModuleCounts)
|
||||
foreach (var moduleCount in outpostGenerationParams.ModuleCounts)
|
||||
{
|
||||
var moduleCountGroup = new GUILayoutGroup(new RectTransform(new Point(editorContainer.Content.Rect.Width, (int)(25 * GUI.Scale))), isHorizontal: true, childAnchor: Anchor.CenterLeft);
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), moduleCountGroup.RectTransform), TextManager.Capitalize(moduleCount.Key.Value), textAlignment: Alignment.CenterLeft);
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), moduleCountGroup.RectTransform), TextManager.Capitalize(moduleCount.Identifier.Value), textAlignment: Alignment.CenterLeft);
|
||||
new GUINumberInput(new RectTransform(new Vector2(0.5f, 1f), moduleCountGroup.RectTransform), NumberType.Int)
|
||||
{
|
||||
MinValueInt = 0,
|
||||
MaxValueInt = 100,
|
||||
IntValue = moduleCount.Value,
|
||||
IntValue = moduleCount.Count,
|
||||
OnValueChanged = (numInput) =>
|
||||
{
|
||||
outpostGenerationParams.SetModuleCount(moduleCount.Key, numInput.IntValue);
|
||||
outpostGenerationParams.SetModuleCount(moduleCount.Identifier, numInput.IntValue);
|
||||
if (numInput.IntValue == 0)
|
||||
{
|
||||
outpostParamsList.Select(outpostParamsList.SelectedData);
|
||||
@@ -540,7 +540,7 @@ namespace Barotrauma
|
||||
var addModuleCountGroup = new GUILayoutGroup(new RectTransform(new Point(editorContainer.Content.Rect.Width, (int)(40 * GUI.Scale))), isHorizontal: true, childAnchor: Anchor.Center);
|
||||
|
||||
HashSet<Identifier> availableFlags = new HashSet<Identifier>();
|
||||
foreach (Identifier flag in OutpostGenerationParams.OutpostParams.SelectMany(p => p.ModuleCounts.Select(m => m.Key))) { availableFlags.Add(flag); }
|
||||
foreach (Identifier flag in OutpostGenerationParams.OutpostParams.SelectMany(p => p.ModuleCounts.Select(m => m.Identifier))) { availableFlags.Add(flag); }
|
||||
foreach (var sub in SubmarineInfo.SavedSubmarines)
|
||||
{
|
||||
if (sub.OutpostModuleInfo == null) { continue; }
|
||||
@@ -551,7 +551,7 @@ namespace Barotrauma
|
||||
text: TextManager.Get("leveleditor.addmoduletype"));
|
||||
foreach (Identifier flag in availableFlags)
|
||||
{
|
||||
if (outpostGenerationParams.ModuleCounts.Any(mc => mc.Key == flag)) { continue; }
|
||||
if (outpostGenerationParams.ModuleCounts.Any(mc => mc.Identifier == flag)) { continue; }
|
||||
moduleTypeDropDown.AddItem(TextManager.Capitalize(flag.Value), flag);
|
||||
}
|
||||
moduleTypeDropDown.OnSelected += (_, userdata) =>
|
||||
|
||||
@@ -1549,6 +1549,11 @@ namespace Barotrauma
|
||||
MapEntity.DeselectAll();
|
||||
ClearUndoBuffer();
|
||||
|
||||
GameMain.DebugDraw = false;
|
||||
GameMain.LightManager.LightingEnabled = true;
|
||||
Hull.EditWater = false;
|
||||
Hull.EditFire = false;
|
||||
|
||||
SetMode(Mode.Default);
|
||||
|
||||
SoundPlayer.OverrideMusicType = Identifier.Empty;
|
||||
@@ -1586,7 +1591,7 @@ namespace Barotrauma
|
||||
|
||||
private void CreateDummyCharacter()
|
||||
{
|
||||
if (dummyCharacter != null) RemoveDummyCharacter();
|
||||
if (dummyCharacter != null) { RemoveDummyCharacter(); }
|
||||
|
||||
dummyCharacter = Character.Create(CharacterPrefab.HumanSpeciesName, Vector2.Zero, "", id: Entity.DummyID, hasAi: false);
|
||||
dummyCharacter.Info.Name = "Galldren";
|
||||
@@ -1876,21 +1881,15 @@ namespace Barotrauma
|
||||
&& MainSub.Info.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
prevSavePath = MainSub.Info.FilePath.CleanUpPath();
|
||||
string prevDir = Path.GetDirectoryName(MainSub.Info.FilePath).CleanUpPath();
|
||||
|
||||
ModProject modProject = new ModProject { Name = name };
|
||||
string fileListPath = null;
|
||||
|
||||
ContentPackage contentPackage = GetLocalPackageThatOwnsSub(MainSub.Info);
|
||||
if (contentPackage != null)
|
||||
if (contentPackage == null)
|
||||
{
|
||||
modProject = new ModProject(contentPackage);
|
||||
fileListPath = contentPackage.Path;
|
||||
packageToSaveTo = contentPackage;
|
||||
throw new InvalidOperationException($"Tried to overwrite a submarine ({name}) that's not in a local package!");
|
||||
}
|
||||
|
||||
savePath = Path.Combine(prevDir, savePath).CleanUpPath();
|
||||
addSubAndSaveModProject(modProject, savePath, fileListPath ?? Path.Combine(Path.GetDirectoryName(savePath), ContentPackage.FileListFileName));
|
||||
ModProject modProject = new ModProject(contentPackage);
|
||||
packageToSaveTo = contentPackage;
|
||||
savePath = prevSavePath;
|
||||
addSubAndSaveModProject(modProject, savePath, contentPackage.Path);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2074,8 +2073,8 @@ namespace Barotrauma
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), outpostModuleGroup.RectTransform), TextManager.Get("outpostmoduletype"), textAlignment: Alignment.CenterLeft);
|
||||
HashSet<Identifier> availableFlags = new HashSet<Identifier>();
|
||||
foreach (Identifier flag in OutpostGenerationParams.OutpostParams.SelectMany(p => p.ModuleCounts.Select(m => m.Key))) { availableFlags.Add(flag); }
|
||||
foreach (Identifier flag in RuinGeneration.RuinGenerationParams.RuinParams.SelectMany(p => p.ModuleCounts.Select(m => m.Key))) { availableFlags.Add(flag); }
|
||||
foreach (Identifier flag in OutpostGenerationParams.OutpostParams.SelectMany(p => p.ModuleCounts.Select(m => m.Identifier))) { availableFlags.Add(flag); }
|
||||
foreach (Identifier flag in RuinGeneration.RuinGenerationParams.RuinParams.SelectMany(p => p.ModuleCounts.Select(m => m.Identifier))) { availableFlags.Add(flag); }
|
||||
foreach (var sub in SubmarineInfo.SavedSubmarines)
|
||||
{
|
||||
if (sub.OutpostModuleInfo == null) { continue; }
|
||||
@@ -2551,11 +2550,9 @@ namespace Barotrauma
|
||||
{
|
||||
MainSub.Info.BeaconStationInfo ??= new BeaconStationInfo(MainSub.Info);
|
||||
}
|
||||
previewImageButtonHolder.Children.ForEach(c => c.Enabled = type != SubmarineType.OutpostModule);
|
||||
previewImageButtonHolder.Children.ForEach(c => c.Enabled = MainSub.Info.AllowPreviewImage);
|
||||
outpostSettingsContainer.Visible = type == SubmarineType.OutpostModule;
|
||||
|
||||
beaconSettingsContainer.Visible = type == SubmarineType.BeaconStation;
|
||||
|
||||
subSettingsContainer.Visible = type == SubmarineType.Player;
|
||||
return true;
|
||||
};
|
||||
@@ -2572,6 +2569,7 @@ namespace Barotrauma
|
||||
|
||||
new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), previewImageButtonHolder.RectTransform), TextManager.Get("SubPreviewImageCreate"), style: "GUIButtonSmall")
|
||||
{
|
||||
Enabled = MainSub?.Info.AllowPreviewImage ?? false,
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
using (System.IO.MemoryStream imgStream = new System.IO.MemoryStream())
|
||||
@@ -2589,6 +2587,7 @@ namespace Barotrauma
|
||||
|
||||
new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), previewImageButtonHolder.RectTransform), TextManager.Get("SubPreviewImageBrowse"), style: "GUIButtonSmall")
|
||||
{
|
||||
Enabled = MainSub?.Info.AllowPreviewImage ?? false,
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
FileSelection.OnFileSelected = (file) =>
|
||||
|
||||
@@ -220,7 +220,7 @@ namespace Barotrauma
|
||||
};
|
||||
}
|
||||
|
||||
private string Percentage(float v) => $"{Round(v * 100)}%";
|
||||
private string Percentage(float v) => TextManager.GetWithVariable("percentageformat", "[value]", Round(v * 100).ToString()).Value;
|
||||
|
||||
private int Round(float v) => (int)MathF.Round(v);
|
||||
|
||||
@@ -647,6 +647,8 @@ namespace Barotrauma
|
||||
{
|
||||
unsavedConfig.InventoryKeyMap = GameSettings.Config.InventoryKeyMapping.GetDefault();
|
||||
unsavedConfig.KeyMap = GameSettings.Config.KeyMapping.GetDefault();
|
||||
Create(mainFrame.Parent.RectTransform);
|
||||
Instance?.SelectTab(Tab.Controls);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -253,12 +253,12 @@ namespace Barotrauma
|
||||
if (flipHorizontal)
|
||||
{
|
||||
float diff = targetSize.X % (sourceRect.Width * scale.X);
|
||||
flippedDrawOffset.X = (int)((sourceRect.Width * scale.X - diff) / scale.X);
|
||||
flippedDrawOffset.X = (int)MathF.Round((sourceRect.Width * scale.X - diff) / scale.X);
|
||||
}
|
||||
if (flipVertical)
|
||||
{
|
||||
float diff = targetSize.Y % (sourceRect.Height * scale.Y);
|
||||
flippedDrawOffset.Y = (int)((sourceRect.Height * scale.Y - diff) / scale.Y);
|
||||
flippedDrawOffset.Y = (int)MathF.Round((sourceRect.Height * scale.Y - diff) / scale.Y);
|
||||
}
|
||||
drawOffset += flippedDrawOffset;
|
||||
|
||||
|
||||
@@ -562,10 +562,10 @@ namespace Barotrauma.Steam
|
||||
= (parentList == enabledRegularModsList, parentList.AllSelected.Count > 1);
|
||||
Identifier swapLabel = (labelConditions switch
|
||||
{
|
||||
(true, true) => "EnableSelectedWorkshopMods",
|
||||
(true, false) => "EnableWorkshopMod",
|
||||
(false, true) => "DisableSelectedWorkshopMods",
|
||||
(false, false) => "DisableWorkshopMod"
|
||||
(false, true) => "EnableSelectedWorkshopMods",
|
||||
(false, false) => "EnableWorkshopMod",
|
||||
(true, true) => "DisableSelectedWorkshopMods",
|
||||
(true, false) => "DisableWorkshopMod"
|
||||
}).ToIdentifier();
|
||||
|
||||
contextMenuOptions.Add(new ContextMenuOption(swapLabel,
|
||||
|
||||
@@ -595,6 +595,12 @@ namespace Barotrauma.Steam
|
||||
{
|
||||
ContentPackageManager.WorkshopPackages.Refresh();
|
||||
ContentPackageManager.EnabledPackages.RefreshUpdatedMods();
|
||||
var package = ContentPackageManager.WorkshopPackages.FirstOrDefault(p => p.SteamWorkshopId == workshopItem.Id);
|
||||
if (package is RegularPackage regular)
|
||||
{
|
||||
ContentPackageManager.EnabledPackages.EnableRegular(regular);
|
||||
}
|
||||
PopulateInstalledModLists(forceRefreshEnabled: true);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>0.18.6.0</Version>
|
||||
<Version>0.18.7.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>0.18.6.0</Version>
|
||||
<Version>0.18.7.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>0.18.6.0</Version>
|
||||
<Version>0.18.7.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>0.18.6.0</Version>
|
||||
<Version>0.18.7.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>0.18.6.0</Version>
|
||||
<Version>0.18.7.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
|
||||
@@ -10,6 +10,11 @@ namespace Barotrauma
|
||||
{
|
||||
private readonly Dictionary<Identifier, float> prevSentSkill = new Dictionary<Identifier, float>();
|
||||
|
||||
/// <summary>
|
||||
/// The client opted to create a new character and discard this one
|
||||
/// </summary>
|
||||
public bool Discarded;
|
||||
|
||||
partial void OnSkillChanged(Identifier skillIdentifier, float prevLevel, float newLevel)
|
||||
{
|
||||
if (Character == null || Character.Removed) { return; }
|
||||
|
||||
@@ -230,7 +230,7 @@ namespace Barotrauma
|
||||
if (!matchingCharacterData.HasSpawned) { continue; }
|
||||
characterInfo ??= matchingCharacterData.CharacterInfo;
|
||||
}
|
||||
if (characterInfo == null) { continue; }
|
||||
if (characterInfo == null || characterInfo.Discarded) { continue; }
|
||||
//reduce skills if the character has died
|
||||
if (characterInfo.CauseOfDeath != null && characterInfo.CauseOfDeath.Type != CauseOfDeathType.Disconnected)
|
||||
{
|
||||
@@ -420,6 +420,8 @@ namespace Barotrauma
|
||||
{
|
||||
discardedCharacters.Add(data);
|
||||
}
|
||||
DebugConsole.Log($"Client \"{client}\" discarded the character ({data.Name})");
|
||||
data.CharacterInfo.Discarded = true;
|
||||
characterData.Remove(data);
|
||||
IncrementLastUpdateIdForFlag(NetFlags.CharacterInfo);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Barotrauma.Networking;
|
||||
@@ -18,7 +19,8 @@ namespace Barotrauma
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
msg.Write((byte) ServerPacketHeader.READY_CHECK);
|
||||
msg.Write((byte) ReadyCheckState.Start);
|
||||
msg.Write(endTime);
|
||||
msg.Write(new DateTimeOffset(startTime).ToUnixTimeSeconds());
|
||||
msg.Write(new DateTimeOffset(endTime).ToUnixTimeSeconds());
|
||||
msg.Write(author);
|
||||
|
||||
if (sender != null)
|
||||
@@ -53,10 +55,9 @@ namespace Barotrauma
|
||||
foreach (Client client in ActivePlayers)
|
||||
{
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
msg.Write((byte) ServerPacketHeader.READY_CHECK);
|
||||
msg.Write((byte) ReadyCheckState.Update);
|
||||
msg.Write(time); // sync time
|
||||
msg.Write((byte) state);
|
||||
msg.Write((byte)ServerPacketHeader.READY_CHECK);
|
||||
msg.Write((byte)ReadyCheckState.Update);
|
||||
msg.Write((byte)state);
|
||||
msg.Write(otherClient);
|
||||
GameMain.Server.ServerPeer.Send(msg, client.Connection, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class Pump : Powered, IServerSerializable, IClientSerializable
|
||||
{
|
||||
const float NetworkUpdateInterval = 5.0f;
|
||||
private float networkUpdateTimer;
|
||||
|
||||
partial void UpdateProjSpecific(float deltaTime)
|
||||
{
|
||||
networkUpdateTimer -= deltaTime;
|
||||
if (networkUpdateTimer <= 0.0f)
|
||||
{
|
||||
item.CreateServerEvent(this);
|
||||
networkUpdateTimer = NetworkUpdateInterval;
|
||||
}
|
||||
}
|
||||
|
||||
public void ServerEventRead(IReadMessage msg, Client c)
|
||||
{
|
||||
float newFlowPercentage = msg.ReadRangedInteger(-10, 10) * 10.0f;
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.MapCreatures.Behavior;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -39,9 +36,9 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
statusUpdateTimer -= deltaTime;
|
||||
decalUpdateTimer -= deltaTime;
|
||||
backgroundSectionUpdateTimer -= deltaTime;
|
||||
statusUpdateTimer += deltaTime;
|
||||
decalUpdateTimer += deltaTime;
|
||||
backgroundSectionUpdateTimer += deltaTime;
|
||||
|
||||
//update client hulls if the amount of water has changed by >10%
|
||||
//or if oxygen percentage has changed by 5%
|
||||
@@ -49,33 +46,32 @@ namespace Barotrauma
|
||||
(Math.Abs(lastSentVolume - waterVolume) > Volume * 0.1f
|
||||
|| Math.Abs(lastSentOxygen - OxygenPercentage) > 5f
|
||||
|| lastSentFireCount != FireSources.Count)
|
||||
&& statusUpdateTimer <= 0.0f;
|
||||
&& (statusUpdateTimer > NetConfig.HullUpdateInterval);
|
||||
|
||||
if (shouldSendStatusUpdate)
|
||||
//force an update every 5 seconds even if nothing's changed (in case a client's gotten out of sync somehow)
|
||||
if (shouldSendStatusUpdate || statusUpdateTimer > NetConfig.SparseHullUpdateInterval)
|
||||
{
|
||||
GameMain.NetworkMember.CreateEntityEvent(this, new StatusEventData());
|
||||
|
||||
GameMain.NetworkMember.CreateEntityEvent(this, new StatusEventData());
|
||||
lastSentVolume = waterVolume;
|
||||
lastSentOxygen = OxygenPercentage;
|
||||
lastSentFireCount = FireSources.Count;
|
||||
|
||||
statusUpdateTimer = NetConfig.SparseHullUpdateInterval;
|
||||
statusUpdateTimer = 0;
|
||||
}
|
||||
if (decalUpdatePending && decalUpdateTimer <= 0.0f)
|
||||
if (decalUpdatePending && decalUpdateTimer > NetConfig.HullUpdateInterval)
|
||||
{
|
||||
GameMain.NetworkMember.CreateEntityEvent(this, new DecalEventData());
|
||||
|
||||
decalUpdateTimer = NetConfig.HullUpdateInterval;
|
||||
decalUpdateTimer = 0;
|
||||
decalUpdatePending = false;
|
||||
}
|
||||
if (pendingSectionUpdates.Count > 0 && backgroundSectionUpdateTimer <= 0.0f)
|
||||
if (pendingSectionUpdates.Count > 0 && backgroundSectionUpdateTimer > NetConfig.HullUpdateInterval)
|
||||
{
|
||||
foreach (int pendingSectionUpdate in pendingSectionUpdates)
|
||||
{
|
||||
GameMain.NetworkMember.CreateEntityEvent(this, new BackgroundSectionsEventData(pendingSectionUpdate));
|
||||
}
|
||||
|
||||
backgroundSectionUpdateTimer = NetConfig.HullUpdateInterval;
|
||||
backgroundSectionUpdateTimer = 0;
|
||||
pendingSectionUpdates.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,9 @@ namespace Barotrauma.Networking
|
||||
characterInfo = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string PendingName;
|
||||
|
||||
public NetworkConnection Connection { get; set; }
|
||||
|
||||
public bool SpectateOnly;
|
||||
|
||||
@@ -1046,7 +1046,7 @@ namespace Barotrauma.Networking
|
||||
c.LastRecvChatMsgID = NetIdUtils.Clamp(inc.ReadUInt16(), c.LastRecvChatMsgID, c.LastChatMsgQueueID);
|
||||
c.LastRecvClientListUpdate = NetIdUtils.Clamp(inc.ReadUInt16(), c.LastRecvClientListUpdate, LastClientListUpdateID);
|
||||
|
||||
TryChangeClientName(c, inc);
|
||||
ReadClientNameChange(c, inc);
|
||||
|
||||
c.LastRecvCampaignSave = inc.ReadUInt16();
|
||||
if (c.LastRecvCampaignSave > 0)
|
||||
@@ -2675,7 +2675,7 @@ namespace Barotrauma.Networking
|
||||
base.AddChatMessage(message);
|
||||
}
|
||||
|
||||
private bool TryChangeClientName(Client c, IReadMessage inc)
|
||||
private bool ReadClientNameChange(Client c, IReadMessage inc)
|
||||
{
|
||||
UInt16 nameId = inc.ReadUInt16();
|
||||
string newName = inc.ReadString();
|
||||
@@ -2685,16 +2685,21 @@ namespace Barotrauma.Networking
|
||||
if (c == null || string.IsNullOrEmpty(newName) || !NetIdUtils.IdMoreRecent(nameId, c.NameID)) { return false; }
|
||||
|
||||
c.NameID = nameId;
|
||||
newName = Client.SanitizeName(newName);
|
||||
if (newName == c.Name && newJob == c.PreferredJob && newTeam == c.PreferredTeam) { return false; }
|
||||
c.PreferredJob = newJob;
|
||||
c.PreferredTeam = newTeam;
|
||||
|
||||
return TryChangeClientName(c, newName);
|
||||
}
|
||||
|
||||
public bool TryChangeClientName(Client c, string newName)
|
||||
{
|
||||
newName = Client.SanitizeName(newName);
|
||||
//update client list even if the name cannot be changed to the one sent by the client,
|
||||
//so the client will be informed what their actual name is
|
||||
LastClientListUpdateID++;
|
||||
|
||||
if (newName == c.Name) { return false; }
|
||||
if (newName == c.Name || string.IsNullOrEmpty(newName)) { return false; }
|
||||
|
||||
if (IsNameValid(c, newName))
|
||||
{
|
||||
@@ -2710,6 +2715,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private bool IsNameValid(Client c, string newName)
|
||||
{
|
||||
newName = Client.SanitizeName(newName);
|
||||
@@ -3542,6 +3548,10 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
newName = sender.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
sender.PendingName = newName;
|
||||
}
|
||||
}
|
||||
|
||||
int tagCount = message.ReadByte();
|
||||
|
||||
@@ -392,6 +392,14 @@ namespace Barotrauma.Networking
|
||||
bool forceSpawnInMainSub = false;
|
||||
if (!bot && campaign != null)
|
||||
{
|
||||
//the client has opted to change the name of their new character
|
||||
//when the character spawns, set the client's name to match
|
||||
if (clients[i].PendingName == characterInfos[i].Name)
|
||||
{
|
||||
GameMain.Server?.TryChangeClientName(clients[i], clients[i].PendingName);
|
||||
clients[i].PendingName = null;
|
||||
}
|
||||
|
||||
var matchingData = campaign?.GetClientCharacterData(clients[i]);
|
||||
if (matchingData != null)
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>0.18.6.0</Version>
|
||||
<Version>0.18.7.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
|
||||
@@ -227,9 +227,13 @@ namespace Barotrauma
|
||||
{
|
||||
mainLimb = Limbs.FirstOrDefault(l => IsValid(l));
|
||||
}
|
||||
if (mainLimb == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Couldn't find a valid main limb. The limb can't be hidden nor be set to ignore collisions!");
|
||||
mainLimb = Limbs.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
bool IsValid(Limb limb) => limb != null && !limb.IsSevered && !limb.IgnoreCollisions && !limb.Hidden;
|
||||
static bool IsValid(Limb limb) => limb != null && !limb.IsSevered && !limb.IgnoreCollisions && !limb.Hidden;
|
||||
return mainLimb;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,9 @@ namespace Barotrauma
|
||||
[Serialize("", IsPropertySaveable.Yes)]
|
||||
public Identifier SpawnPointTag { get; set; }
|
||||
|
||||
[Serialize(CharacterTeamType.FriendlyNPC, IsPropertySaveable.Yes)]
|
||||
public CharacterTeamType Team { get; protected set; }
|
||||
|
||||
[Serialize(false, IsPropertySaveable.Yes, description: "Should we spawn the entity even when no spawn points with matching tags were found?")]
|
||||
public bool RequireSpawnPointTag { get; set; }
|
||||
|
||||
@@ -119,7 +122,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (newCharacter == null) { return; }
|
||||
newCharacter.HumanPrefab = humanPrefab;
|
||||
newCharacter.TeamID = CharacterTeamType.FriendlyNPC;
|
||||
newCharacter.TeamID = Team;
|
||||
newCharacter.EnableDespawn = false;
|
||||
humanPrefab.GiveItems(newCharacter, newCharacter.Submarine);
|
||||
if (LootingIsStealing)
|
||||
|
||||
@@ -13,12 +13,26 @@ namespace Barotrauma
|
||||
|
||||
internal partial class ReadyCheck
|
||||
{
|
||||
private readonly float endTime;
|
||||
private float time;
|
||||
private readonly DateTime endTime;
|
||||
private readonly DateTime startTime;
|
||||
public readonly Dictionary<byte, ReadyStatus> Clients;
|
||||
public bool IsFinished = false;
|
||||
|
||||
public ReadyCheck(List<byte> clients, float duration = 30)
|
||||
public ReadyCheck(List<byte> clients, DateTime startTime, DateTime endTime)
|
||||
: this(clients)
|
||||
{
|
||||
this.startTime = startTime;
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
public ReadyCheck(List<byte> clients, float duration)
|
||||
: this(clients)
|
||||
{
|
||||
startTime = DateTime.Now;
|
||||
endTime = startTime + new TimeSpan(0, 0, 0, 0, (int)(duration * 1000));
|
||||
}
|
||||
|
||||
private ReadyCheck(List<byte> clients)
|
||||
{
|
||||
Clients = new Dictionary<byte, ReadyStatus>();
|
||||
foreach (byte client in clients)
|
||||
@@ -27,24 +41,17 @@ namespace Barotrauma
|
||||
|
||||
Clients.Add(client, ReadyStatus.Unanswered);
|
||||
}
|
||||
|
||||
time = duration;
|
||||
endTime = duration;
|
||||
#if CLIENT
|
||||
lastSecond = (int) Math.Ceiling(duration);
|
||||
#endif
|
||||
}
|
||||
|
||||
partial void EndReadyCheck();
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (time > 0)
|
||||
if (DateTime.Now < endTime)
|
||||
{
|
||||
#if CLIENT
|
||||
UpdateBar();
|
||||
#endif
|
||||
time -= deltaTime;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
using Barotrauma.Networking;
|
||||
using Barotrauma.MapCreatures.Behavior;
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.MapCreatures.Behavior;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
@@ -24,7 +23,10 @@ namespace Barotrauma.Items.Components
|
||||
if (value == hijacked) { return; }
|
||||
hijacked = value;
|
||||
#if SERVER
|
||||
item.CreateServerEvent(this);
|
||||
if (!Submarine.Unloading)
|
||||
{
|
||||
item.CreateServerEvent(this);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace Barotrauma.Items.Components
|
||||
get { return poweredList; }
|
||||
}
|
||||
|
||||
public static readonly List<Connection> ChangedConnections = new List<Connection>();
|
||||
public static readonly HashSet<Connection> ChangedConnections = new HashSet<Connection>();
|
||||
|
||||
public readonly static Dictionary<int, GridInfo> Grids = new Dictionary<int, GridInfo>();
|
||||
|
||||
@@ -158,6 +158,12 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Essentially Voltage / MinVoltage (= how much of the minimum required voltage has been satisfied), clamped between 0 and 1.
|
||||
/// Can be used by status effects or sounds to check if the item has enough power to run
|
||||
/// </summary>
|
||||
public float RelativeVoltage => minVoltage <= 0.0f ? 1.0f : MathHelper.Clamp(Voltage / minVoltage, 0.0f, 1.0f);
|
||||
|
||||
public bool PoweredByTinkering { get; set; }
|
||||
|
||||
[Editable, Serialize(true, IsPropertySaveable.Yes, description: "Can the item be damaged by electomagnetic pulses.")]
|
||||
|
||||
@@ -170,6 +170,7 @@ namespace Barotrauma.Items.Components
|
||||
public void SetRecipientsDirty()
|
||||
{
|
||||
recipientsDirty = true;
|
||||
if (IsPower) { Powered.ChangedConnections.Add(this); }
|
||||
}
|
||||
|
||||
private void RefreshRecipients()
|
||||
|
||||
@@ -399,6 +399,7 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
new XAttribute("pos", XMLExtensions.Vector2ToString(branch.Position)),
|
||||
new XAttribute("ID", branch.ID),
|
||||
new XAttribute("isroot", branch.IsRoot),
|
||||
new XAttribute("isrootgrowth", branch.IsRootGrowth),
|
||||
new XAttribute("health", branch.Health.ToString("G", CultureInfo.InvariantCulture)),
|
||||
new XAttribute("maxhealth", branch.MaxHealth.ToString("G", CultureInfo.InvariantCulture)),
|
||||
new XAttribute("sides", (int)branch.Sides),
|
||||
@@ -457,9 +458,16 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
|
||||
foreach ((BallastFloraBranch branch, int parentBranchId) in branches)
|
||||
{
|
||||
if (parentBranchId > -1 && parentBranchId < Branches.Count)
|
||||
if (parentBranchId > -1)
|
||||
{
|
||||
branch.ParentBranch = Branches[parentBranchId];
|
||||
if (parentBranchId < Branches.Count)
|
||||
{
|
||||
branch.ParentBranch = Branches[parentBranchId];
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.AddWarning($"Error while loading ballast flora: parent branch ID {parentBranchId} out of range (total {Branches.Count} branches)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -476,6 +484,7 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
{
|
||||
Vector2 pos = branchElement.GetAttributeVector2("pos", Vector2.Zero);
|
||||
bool isRoot = branchElement.GetAttributeBool("isroot", false);
|
||||
bool isRootGrowth = branchElement.GetAttributeBool("isrootgrowth", false);
|
||||
int flowerConfig = getInt("flowerconfig");
|
||||
int leafconfig = getInt("leafconfig");
|
||||
int id = getInt("ID");
|
||||
@@ -493,7 +502,8 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
MaxHealth = maxhealth,
|
||||
Sides = (TileSide) sides,
|
||||
BlockedSides = (TileSide) blockedSides,
|
||||
IsRoot = isRoot
|
||||
IsRoot = isRoot,
|
||||
IsRootGrowth = isRootGrowth
|
||||
};
|
||||
branches.Add((newBranch, parentBranchId));
|
||||
|
||||
@@ -658,11 +668,14 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
toBeRemoved.Clear();
|
||||
foreach (BallastFloraBranch branch in Branches)
|
||||
{
|
||||
if (branch.ParentBranch == null || branch.ParentBranch.DisconnectedFromRoot || branch.ParentBranch.Health <= 0.0f)
|
||||
if (!branch.IsRoot)
|
||||
{
|
||||
float parentHealth = branch.ParentBranch == null ? 0.0f : branch.ParentBranch.Health / branch.ParentBranch.MaxHealth;
|
||||
float speed = MathHelper.Lerp(5.0f, 0.1f, parentHealth);
|
||||
DamageBranch(branch, speed * speed * deltaTime, AttackType.CutFromRoot);
|
||||
if (branch.ParentBranch == null || branch.ParentBranch.DisconnectedFromRoot || branch.ParentBranch.Health <= 0.0f)
|
||||
{
|
||||
float parentHealth = branch.ParentBranch == null ? 0.0f : branch.ParentBranch.Health / branch.ParentBranch.MaxHealth;
|
||||
float speed = MathHelper.Lerp(5.0f, 0.1f, parentHealth);
|
||||
DamageBranch(branch, speed * speed * deltaTime, AttackType.CutFromRoot);
|
||||
}
|
||||
}
|
||||
if (branch.Health <= 0.0f)
|
||||
{
|
||||
@@ -1197,7 +1210,10 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
}
|
||||
});
|
||||
#if SERVER
|
||||
CreateNetworkMessage(new InfectEventData(item, InfectEventData.InfectState.No, null));
|
||||
if (!item.Removed && Parent != null && !Parent.Removed)
|
||||
{
|
||||
CreateNetworkMessage(new InfectEventData(item, InfectEventData.InfectState.No, null));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -215,16 +215,19 @@ namespace Barotrauma
|
||||
saveElement = element
|
||||
};
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(levelSeed) && levelData != null &&
|
||||
levelData.Seed != levelSeed && !linkedSub.purchasedLostShuttles)
|
||||
{
|
||||
linkedSub.loadSub = false;
|
||||
}
|
||||
else
|
||||
bool levelMatches = string.IsNullOrWhiteSpace(levelSeed) || levelData == null || levelData.Seed == levelSeed;
|
||||
|
||||
//don't load a sub that was left in this level if we have a submarine switch pending
|
||||
//to make sure it gets ignored during the submarine switch and item transfer (reloading and saving it during the switch makes it not considered "left behind")
|
||||
if ((levelMatches || linkedSub.purchasedLostShuttles) && GameMain.GameSession?.Campaign?.PendingSubmarineSwitch == null)
|
||||
{
|
||||
linkedSub.loadSub = true;
|
||||
linkedSub.rect.Location = MathUtils.ToPoint(pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
linkedSub.loadSub = false;
|
||||
}
|
||||
}
|
||||
|
||||
#warning TODO: revise
|
||||
@@ -279,14 +282,14 @@ namespace Barotrauma
|
||||
if (worldPos != Vector2.Zero)
|
||||
{
|
||||
if (GameMain.GameSession != null && GameMain.GameSession.MirrorLevel)
|
||||
{
|
||||
{
|
||||
worldPos.X = GameMain.GameSession.LevelData.Size.X - worldPos.X;
|
||||
}
|
||||
sub.SetPosition(worldPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
sub.SetPosition(WorldPosition);
|
||||
sub.SetPosition(WorldPosition);
|
||||
}
|
||||
|
||||
DockingPort linkedPort = null;
|
||||
@@ -308,8 +311,17 @@ namespace Barotrauma
|
||||
{
|
||||
linkedPort = (FindEntityByID(originalLinkedToID) as Item)?.GetComponent<DockingPort>();
|
||||
}
|
||||
if (linkedPort == null) { return; }
|
||||
}
|
||||
|
||||
if (linkedPort == null)
|
||||
{
|
||||
if (worldPos == Vector2.Zero)
|
||||
{
|
||||
DebugConsole.ThrowError("Something went wrong when loading a linked submarine - the save didn't include either a world position or a linked port for the submarine.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
originalLinkedPort = linkedPort;
|
||||
|
||||
ushort originalMyId = childRemap.GetOffsetId(originalMyPortID);
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
using Barotrauma.Extensions;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -98,9 +96,29 @@ namespace Barotrauma
|
||||
[Serialize("", IsPropertySaveable.Yes), Editable]
|
||||
public string ReplaceInRadiation { get; set; }
|
||||
|
||||
private readonly Dictionary<Identifier, int> moduleCounts = new Dictionary<Identifier, int>();
|
||||
public class ModuleCount
|
||||
{
|
||||
public Identifier Identifier;
|
||||
public int Count;
|
||||
public int Order;
|
||||
|
||||
public IReadOnlyDictionary<Identifier, int> ModuleCounts
|
||||
public ModuleCount(ContentXElement element)
|
||||
{
|
||||
Identifier = element.GetAttributeIdentifier("flag", element.GetAttributeIdentifier("moduletype", ""));
|
||||
Count = element.GetAttributeInt("count", 0);
|
||||
Order = element.GetAttributeInt("order", 0);
|
||||
}
|
||||
|
||||
public ModuleCount(Identifier id, int count)
|
||||
{
|
||||
Identifier = id;
|
||||
Count = count;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly List<ModuleCount> moduleCounts = new List<ModuleCount>();
|
||||
|
||||
public IReadOnlyList<ModuleCount> ModuleCounts
|
||||
{
|
||||
get { return moduleCounts; }
|
||||
}
|
||||
@@ -171,8 +189,7 @@ namespace Barotrauma
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
{
|
||||
case "modulecount":
|
||||
Identifier moduleFlag = subElement.GetAttributeIdentifier("flag", subElement.GetAttributeIdentifier("moduletype", ""));
|
||||
moduleCounts[moduleFlag] = subElement.GetAttributeInt("count", 0);
|
||||
moduleCounts.Add(new ModuleCount(subElement));
|
||||
break;
|
||||
case "npcs":
|
||||
var newCollection = new NpcCollection();
|
||||
@@ -200,7 +217,7 @@ namespace Barotrauma
|
||||
public int GetModuleCount(Identifier moduleFlag)
|
||||
{
|
||||
if (moduleFlag == Identifier.Empty || moduleFlag == "none") { return int.MaxValue; }
|
||||
return moduleCounts.ContainsKey(moduleFlag) ? moduleCounts[moduleFlag] : 0;
|
||||
return moduleCounts.FirstOrDefault(m => m.Identifier == moduleFlag)?.Count ?? 0;
|
||||
}
|
||||
|
||||
public void SetModuleCount(Identifier moduleFlag, int count)
|
||||
@@ -208,11 +225,19 @@ namespace Barotrauma
|
||||
if (moduleFlag == Identifier.Empty || moduleFlag == "none") { return; }
|
||||
if (count <= 0)
|
||||
{
|
||||
moduleCounts.Remove(moduleFlag);
|
||||
moduleCounts.RemoveAll(m => m.Identifier == moduleFlag);
|
||||
}
|
||||
else
|
||||
{
|
||||
moduleCounts[moduleFlag] = count;
|
||||
var moduleCount = moduleCounts.FirstOrDefault(m => m.Identifier == moduleFlag);
|
||||
if (moduleCount == null)
|
||||
{
|
||||
moduleCounts.Add(new ModuleCount(moduleFlag, count));
|
||||
}
|
||||
else
|
||||
{
|
||||
moduleCount.Count = count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace Barotrauma
|
||||
{
|
||||
//if the module doesn't have the ruin flag or any other flag used in the generation params, don't use it in ruins
|
||||
if (!subInfo.OutpostModuleInfo.ModuleFlags.Contains("ruin".ToIdentifier()) &&
|
||||
!generationParams.ModuleCounts.Any(m => subInfo.OutpostModuleInfo.ModuleFlags.Contains(m.Key)))
|
||||
!generationParams.ModuleCounts.Any(m => subInfo.OutpostModuleInfo.ModuleFlags.Contains(m.Identifier)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -141,16 +141,11 @@ namespace Barotrauma
|
||||
|
||||
selectedModules.Clear();
|
||||
//select which module types the outpost should consist of
|
||||
List<Identifier> pendingModuleFlags;
|
||||
using (var md5 = MD5.Create())
|
||||
{
|
||||
#warning TODO: cursed
|
||||
pendingModuleFlags = onlyEntrance
|
||||
? generationParams.ModuleCounts
|
||||
.Keys.OrderBy(k => ToolBox.IdentifierToUint32Hash(k, md5))
|
||||
.First().ToEnumerable().ToList()
|
||||
: SelectModules(outpostModules, generationParams);
|
||||
}
|
||||
List<Identifier> pendingModuleFlags =
|
||||
onlyEntrance ?
|
||||
generationParams.ModuleCounts.First().Identifier.ToEnumerable().ToList() :
|
||||
SelectModules(outpostModules, generationParams);
|
||||
|
||||
foreach (Identifier flag in pendingModuleFlags)
|
||||
{
|
||||
if (flag == "none") { continue; }
|
||||
@@ -437,31 +432,27 @@ namespace Barotrauma
|
||||
var pendingModuleFlags = new List<Identifier>();
|
||||
bool availableModulesFound = true;
|
||||
|
||||
Identifier initialModuleFlag = generationParams.ModuleCounts.FirstOrDefault().Key;
|
||||
Identifier initialModuleFlag = generationParams.ModuleCounts.FirstOrDefault().Identifier;
|
||||
pendingModuleFlags.Add(initialModuleFlag);
|
||||
while (pendingModuleFlags.Count < totalModuleCount && availableModulesFound)
|
||||
{
|
||||
availableModulesFound = false;
|
||||
foreach (var moduleFlag in generationParams.ModuleCounts)
|
||||
{
|
||||
if (pendingModuleFlags.Count(m => m == moduleFlag.Key) >= generationParams.GetModuleCount(moduleFlag.Key))
|
||||
if (pendingModuleFlags.Count(m => m == moduleFlag.Identifier) >= generationParams.GetModuleCount(moduleFlag.Identifier))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!modules.Any(m => m.OutpostModuleInfo.ModuleFlags.Contains(moduleFlag.Key)))
|
||||
if (!modules.Any(m => m.OutpostModuleInfo.ModuleFlags.Contains(moduleFlag.Identifier)))
|
||||
{
|
||||
DebugConsole.ThrowError($"Failed to add a module to the outpost (no modules with the flag \"{moduleFlag.Key}\" found).");
|
||||
DebugConsole.ThrowError($"Failed to add a module to the outpost (no modules with the flag \"{moduleFlag.Identifier}\" found).");
|
||||
continue;
|
||||
}
|
||||
availableModulesFound = true;
|
||||
pendingModuleFlags.Add(moduleFlag.Key);
|
||||
pendingModuleFlags.Add(moduleFlag.Identifier);
|
||||
}
|
||||
}
|
||||
using (MD5 md5 = MD5.Create())
|
||||
{
|
||||
pendingModuleFlags.Sort((i1, i2) => (int)ToolBox.StringToUInt32Hash(i1.Value.ToLowerInvariant(), md5) - (int)ToolBox.StringToUInt32Hash(i2.Value.ToLowerInvariant(), md5));
|
||||
}
|
||||
pendingModuleFlags.Shuffle(Rand.RandSync.ServerAndClient);
|
||||
pendingModuleFlags.OrderBy(f => generationParams.ModuleCounts.First(m => m.Identifier == f)).ThenBy(f => Rand.Value(Rand.RandSync.ServerAndClient));
|
||||
while (pendingModuleFlags.Count < totalModuleCount)
|
||||
{
|
||||
//don't place "none" modules at the end because
|
||||
@@ -610,7 +601,7 @@ namespace Barotrauma
|
||||
|
||||
Identifier flagToPlace = "none".ToIdentifier();
|
||||
SubmarineInfo nextModule = null;
|
||||
foreach (Identifier moduleFlag in pendingModuleFlags)
|
||||
foreach (Identifier moduleFlag in pendingModuleFlags.OrderByDescending(f => currentModule?.Info?.OutpostModuleInfo.AllowAttachToModules.Contains(f) ?? false))
|
||||
{
|
||||
flagToPlace = moduleFlag;
|
||||
nextModule = GetRandomModule(currentModule?.Info?.OutpostModuleInfo, availableModules, flagToPlace, gapPosition, locationType, allowDifferentLocationType);
|
||||
@@ -1048,6 +1039,17 @@ namespace Barotrauma
|
||||
module.ThisGapPosition == OutpostModuleInfo.GapPosition.Left ||
|
||||
module.ThisGapPosition == OutpostModuleInfo.GapPosition.Right;
|
||||
|
||||
if (!module.ThisGap.linkedTo.Any())
|
||||
{
|
||||
DebugConsole.ThrowError($"Error during outpost generation: {module.ThisGapPosition} gap in module \"{module.Info.Name}\" was not linked to any hulls.");
|
||||
continue;
|
||||
}
|
||||
if (!module.PreviousGap.linkedTo.Any())
|
||||
{
|
||||
DebugConsole.ThrowError($"Error during outpost generation: {GetOpposingGapPosition(module.ThisGapPosition)} gap in module \"{module.PreviousModule.Info.Name}\" was not linked to any hulls.");
|
||||
continue;
|
||||
}
|
||||
|
||||
MapEntity leftHull = module.ThisGap.Position.X < module.PreviousGap.Position.X ? module.ThisGap.linkedTo[0] : module.PreviousGap.linkedTo[0];
|
||||
MapEntity rightHull = module.ThisGap.Position.X > module.PreviousGap.Position.X ?
|
||||
module.ThisGap.linkedTo.Count == 1 ? module.ThisGap.linkedTo[0] : module.ThisGap.linkedTo[1] :
|
||||
|
||||
@@ -109,6 +109,8 @@ namespace Barotrauma
|
||||
public bool IsCampaignCompatible => IsPlayer && !HasTag(SubmarineTag.Shuttle) && !HasTag(SubmarineTag.HideInMenus) && SubmarineClass != SubmarineClass.Undefined;
|
||||
public bool IsCampaignCompatibleIgnoreClass => IsPlayer && !HasTag(SubmarineTag.Shuttle) && !HasTag(SubmarineTag.HideInMenus);
|
||||
|
||||
public bool AllowPreviewImage => Type == SubmarineType.Player;
|
||||
|
||||
public Md5Hash MD5Hash
|
||||
{
|
||||
get
|
||||
@@ -556,7 +558,7 @@ namespace Barotrauma
|
||||
XDocument doc = new XDocument(newElement);
|
||||
|
||||
doc.Root.Add(new XAttribute("name", Name));
|
||||
if (previewImage != null)
|
||||
if (previewImage != null && AllowPreviewImage)
|
||||
{
|
||||
doc.Root.Add(new XAttribute("previewimage", Convert.ToBase64String(previewImage.ToArray())));
|
||||
}
|
||||
|
||||
@@ -619,6 +619,11 @@ namespace Barotrauma
|
||||
if (parentObject is Powered powered) { value = powered.Voltage; return true; }
|
||||
}
|
||||
break;
|
||||
case nameof(Powered.RelativeVoltage):
|
||||
{
|
||||
if (parentObject is Powered powered) { value = powered.RelativeVoltage; return true; }
|
||||
}
|
||||
break;
|
||||
case nameof(Powered.CurrPowerConsumption):
|
||||
{
|
||||
if (parentObject is Powered powered) { value = powered.CurrPowerConsumption; return true; }
|
||||
|
||||
@@ -480,6 +480,8 @@ namespace Barotrauma
|
||||
bool voiceCaptureChanged = currentConfig.Audio.VoiceCaptureDevice != newConfig.Audio.VoiceCaptureDevice;
|
||||
bool textScaleChanged = Math.Abs(currentConfig.Graphics.TextScale - newConfig.Graphics.TextScale) > MathF.Pow(2.0f, -7);
|
||||
|
||||
bool hudScaleChanged = !MathUtils.NearlyEqual(currentConfig.Graphics.HUDScale, newConfig.Graphics.HUDScale);
|
||||
|
||||
bool setGraphicsMode =
|
||||
resolutionChanged ||
|
||||
currentConfig.Graphics.VSync != newConfig.Graphics.VSync ||
|
||||
@@ -514,6 +516,10 @@ namespace Barotrauma
|
||||
componentStyle.RefreshSize();
|
||||
}
|
||||
}
|
||||
if (hudScaleChanged)
|
||||
{
|
||||
HUDLayoutSettings.CreateAreas();
|
||||
}
|
||||
|
||||
GameMain.SoundManager?.ApplySettings();
|
||||
#endif
|
||||
|
||||
@@ -100,13 +100,23 @@ namespace Barotrauma
|
||||
}
|
||||
#endif
|
||||
|
||||
if (Path.IsPathRooted(originalFilename))
|
||||
string startPath = directory ?? "";
|
||||
|
||||
string saveFolder = SaveUtil.SaveFolder.Replace('\\', '/');
|
||||
if (originalFilename.Replace('\\', '/').StartsWith(saveFolder))
|
||||
{
|
||||
//paths that lead to the save folder might have incorrect case,
|
||||
//mainly if they come from a filelist
|
||||
startPath = saveFolder.EndsWith('/') ? saveFolder : $"{saveFolder}/";
|
||||
filename = startPath;
|
||||
subDirs = subDirs.Skip(saveFolder.Split('/').Length).ToArray();
|
||||
}
|
||||
else if (Path.IsPathRooted(originalFilename))
|
||||
{
|
||||
#warning TODO: incorrect assumption or...? Figure out what this was actually supposed to fix, if anything. Might've been a perf thing.
|
||||
return originalFilename; //assume that rooted paths have correct case since these are generated by the game
|
||||
}
|
||||
|
||||
string startPath = directory ?? "";
|
||||
|
||||
for (int i = 0; i < subDirs.Length; i++)
|
||||
{
|
||||
if (i == subDirs.Length - 1 && string.IsNullOrEmpty(subDirs[i]))
|
||||
|
||||
@@ -1,3 +1,41 @@
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v0.18.7.0
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
Unstable only:
|
||||
- Reduced depth charge scale to fit in loader/racks better.
|
||||
- Fixed ballast flora dying by itself client-side when transitioning to a new level.
|
||||
- Disallow laying in vertically flipped normal bunks.
|
||||
- Fixed broken door sprite stretching on the wrong axis when cutting a door.
|
||||
- Fixed AI orders not working in multiplayer.
|
||||
- Fixed tutorial characters starting with more items than they should.
|
||||
- Fixed chat box closing when clicking any chat box elements after opening it with the keybind.
|
||||
- Fixed submarine selection resetting when changing server settings in the campaign setup menu.
|
||||
- Fixed "enable" and "disable" being wrong way around in the mod tab's context menus.
|
||||
- Fixed sub editor always saving subs from a local mod in the root of that mod's folder instead of the actual location of that sub file.
|
||||
- Fixed decoys not being containable in wrecked coilgun ammo shelves.
|
||||
- Fixes and improvements to the new beacon stations and the enemies inside them.
|
||||
- Fixed an issue during submarine switching when a drone / linked sub has been left behind (Regalis11/Barotrauma#9172): When you were switching back to a submarine whose drone you'd left behind, in the same level where you left the drone, the drone would get loaded and resaved during the item transfer, which caused it to no longer be considered "left behind". It also removed the drone's position from the save, and since it was not docked to anything either, positioning it failed at the beginning of the next round.
|
||||
|
||||
Changes:
|
||||
- Adding preview images to wrecks, beacon stations, outposts or enemy subs isn't allowed in the sub editor (unnecessarily bloats up their file size, as the preview images aren't visible anywhere).
|
||||
|
||||
Fixes:
|
||||
- Fixed server not refreshing the power grid when a client disconnects and reconnects a power wire.
|
||||
- Fixed hull updates not being sent if the water/oxygen/fire in the hull doesn't change server-side, preventing the hull's status from getting corrected if a client somehow ends up out of sync.
|
||||
- Fixed keybinds shown in the controls tab not refreshing when resetting the binds.
|
||||
- Hopefully fixed colonies sometimes not including some modules (most often the armory module).
|
||||
- Fixed ready checks sometimes ending at a slightly different time client-side compared to the server, allowing you to answer the prompt even though the time to answer already ended server-side.
|
||||
- Fixed large terminal welcome messages going slightly outside the bounds of the listbox.
|
||||
- Fixed overlapping in the tab menu's mission tab when there's more than one mission selected.
|
||||
- Fixed fabricators and deconstructors playing the sounds even if they're out of power.
|
||||
- Fixed occasional "hash mismatch for downloaded mod" errors on Linux.
|
||||
- Fixed clients occasionally spawning as the old character after they've opted to create a new one. Only happened if the client hadn't died and was still controlling the old character at the end of the round.
|
||||
- When a client creates a character with a new name, the client's name is changed to match it after they spawn as that character.
|
||||
- Fixed enabled mods getting disabled when updating them in the mods menu.
|
||||
- Fixed a rounding error in Sprite.DrawTiled that sometimes caused an extra 1-pixel line on some scaled and flipped structures (e.g. certain wall pieces scaled to 0.6).
|
||||
- Fixed Orca 2 still using the old chaingun charge time.
|
||||
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v0.18.6.0
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user