(5c35a640e) Update tutorial-rework with dev

This commit is contained in:
Joonas Rikkonen
2019-03-27 20:52:47 +02:00
parent 47b16f4f9e
commit 080ac78ded
113 changed files with 3206 additions and 1298 deletions
@@ -13,13 +13,39 @@ namespace Barotrauma
var pos = new Vector2(WorldPosition.X, -WorldPosition.Y);
if (soundRange > 0.0f)
{
Color color = Entity is Character ? Color.Yellow : Color.Orange;
Color color;
if (Entity is Character)
{
color = Color.Yellow;
}
else if (Entity is Item)
{
color = Color.Orange;
}
else
{
color = Color.OrangeRed;
}
ShapeExtensions.DrawCircle(spriteBatch, pos, SoundRange, 100, color, thickness: 1 / Screen.Selected.Cam.Zoom);
ShapeExtensions.DrawCircle(spriteBatch, pos, 3, 8, color, thickness: 2 / Screen.Selected.Cam.Zoom);
}
if (sightRange > 0.0f)
{
Color color = Entity is Character ? Color.CornflowerBlue : Color.CadetBlue;
Color color;
if (Entity is Character)
{
color = Color.CornflowerBlue;
}
else if (Entity is Item)
{
color = Color.CadetBlue;
}
else
{
color = Color.WhiteSmoke;
}
ShapeExtensions.DrawCircle(spriteBatch, pos, SightRange, 100, color, thickness: 1 / Screen.Selected.Cam.Zoom);
ShapeExtensions.DrawCircle(spriteBatch, pos, 6, 8, color, thickness: 2 / Screen.Selected.Cam.Zoom);
}
}
}
@@ -21,13 +21,11 @@ namespace Barotrauma
if (wallTarget != null)
{
Vector2 wallTargetPos = wallTarget.Position;
if (wallTarget.Structure.Submarine != null) wallTargetPos += wallTarget.Structure.Submarine.Position;
wallTargetPos.Y = -wallTargetPos.Y;
GUI.DrawRectangle(spriteBatch, wallTargetPos - new Vector2(10.0f, 10.0f), new Vector2(20.0f, 20.0f), Color.Red, false);
GUI.DrawLine(spriteBatch, pos, wallTargetPos, Color.Orange * 0.5f, 0, 5);
GUI.DrawLine(spriteBatch, pos, wallTargetPos, Color.Orange * 0.5f, 0, 5);
}
GUI.Font.DrawString(spriteBatch, $"{SelectedAiTarget.Entity.ToString()} ({targetValue.ToString()})", pos - Vector2.UnitY * 20.0f, Color.Red);
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{SelectedAiTarget.Entity.ToString()} ({targetValue.FormatZeroDecimal()})", Color.Red, Color.Black);
}
/*GUI.Font.DrawString(spriteBatch, targetValue.ToString(), pos - Vector2.UnitY * 80.0f, Color.Red);
@@ -70,29 +68,34 @@ namespace Barotrauma
GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(Steering.X, -Steering.Y)), Color.Blue, width: 3);
if (latchOntoAI.WallAttachPos.HasValue)
{
GUI.DrawLine(spriteBatch, pos,
ConvertUnits.ToDisplayUnits(new Vector2(latchOntoAI.WallAttachPos.Value.X, -latchOntoAI.WallAttachPos.Value.Y)), Color.Green, 0, 3);
}
}
GUI.DrawLine(spriteBatch,
new Vector2(Character.DrawPosition.X, -Character.DrawPosition.Y),
new Vector2(pathSteering.CurrentPath.CurrentNode.DrawPosition.X, -pathSteering.CurrentPath.CurrentNode.DrawPosition.Y),
Color.Orange * 0.6f, 0, 3);
for (int i = 1; i < pathSteering.CurrentPath.Nodes.Count; i++)
if (steeringManager is IndoorsSteeringManager pathSteering)
{
GUI.DrawLine(spriteBatch,
new Vector2(pathSteering.CurrentPath.Nodes[i].DrawPosition.X, -pathSteering.CurrentPath.Nodes[i].DrawPosition.Y),
new Vector2(pathSteering.CurrentPath.Nodes[i - 1].DrawPosition.X, -pathSteering.CurrentPath.Nodes[i - 1].DrawPosition.Y),
Color.Orange * 0.6f, 0, 3);
var path = pathSteering.CurrentPath;
if (path != null)
{
if (path.CurrentNode != null)
{
GUI.DrawLine(spriteBatch, pos,
new Vector2(path.CurrentNode.DrawPosition.X, -path.CurrentNode.DrawPosition.Y),
Color.DarkViolet, 0, 3);
GUI.SmallFont.DrawString(spriteBatch,
pathSteering.CurrentPath.Nodes[i].ID.ToString(),
new Vector2(pathSteering.CurrentPath.Nodes[i].DrawPosition.X, -pathSteering.CurrentPath.Nodes[i].DrawPosition.Y - 10),
Color.LightGreen);
GUI.DrawString(spriteBatch, pos - new Vector2(0, 100), "Path cost: " + path.Cost.FormatZeroDecimal(), Color.White, Color.Black * 0.5f);
}
for (int i = 1; i < path.Nodes.Count; i++)
{
var previousNode = path.Nodes[i - 1];
var currentNode = path.Nodes[i];
GUI.DrawLine(spriteBatch,
new Vector2(currentNode.DrawPosition.X, -currentNode.DrawPosition.Y),
new Vector2(previousNode.DrawPosition.X, -previousNode.DrawPosition.Y),
Color.Red * 0.5f, 0, 3);
GUI.SmallFont.DrawString(spriteBatch,
currentNode.ID.ToString(),
new Vector2(currentNode.DrawPosition.X + 20, -currentNode.DrawPosition.Y - 20),
Color.Red);
}
}
}
GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(Character.AnimController.TargetMovement.X, -Character.AnimController.TargetMovement.Y)), Color.SteelBlue, width: 2);
GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(Steering.X, -Steering.Y)), Color.Blue, width: 3);
@@ -75,11 +75,12 @@ namespace Barotrauma
GUI.SmallFont.DrawString(spriteBatch,
currentNode.ID.ToString(),
new Vector2(currentNode.DrawPosition.X, -currentNode.DrawPosition.Y - 10),
Color.LightGreen);
new Vector2(currentNode.DrawPosition.X + 20, -currentNode.DrawPosition.Y - 20),
Color.SkyBlue);
}
}
}
GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(Character.AnimController.TargetMovement.X, -Character.AnimController.TargetMovement.Y)), Color.SteelBlue, width: 2);
GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(Steering.X, -Steering.Y)), Color.Blue, width: 3);
//if (Character.IsKeyDown(InputType.Aim))
@@ -210,7 +210,9 @@ namespace Barotrauma
else
{
Vector2 positionError = serverPos.Position - localPos.Position;
float rotationError = serverPos.Rotation - localPos.Rotation;
float rotationError = serverPos.Rotation.HasValue && localPos.Rotation.HasValue ?
serverPos.Rotation.Value - localPos.Rotation.Value :
0.0f;
for (int i = localPosIndex; i < character.MemLocalState.Count; i++)
{
@@ -214,8 +214,8 @@ namespace Barotrauma
msg.ReadRangedSingle(-MaxVel, MaxVel, 12));
bool fixedRotation = msg.ReadBoolean();
float rotation = AnimController.Collider.Rotation;
float angularVelocity = AnimController.Collider.AngularVelocity;
float? rotation = null;
float? angularVelocity = null;
if (!fixedRotation)
{
rotation = msg.ReadFloat();
File diff suppressed because it is too large Load Diff
@@ -403,6 +403,11 @@ namespace Barotrauma
AssignRelayToServer("help", false);
AssignRelayToServer("verboselogging", false);
AssignRelayToServer("freecam", false);
#if DEBUG
AssignRelayToServer("simulatedlatency", false);
AssignRelayToServer("simulatedloss", false);
AssignRelayToServer("simulatedduplicateschance", false);
#endif
commands.Add(new Command("clientlist", "", (string[] args) => { }));
AssignRelayToServer("clientlist", true);
@@ -439,7 +444,7 @@ namespace Barotrauma
AssignOnExecute("ambientlight", (string[] args) =>
{
Color color = XMLExtensions.ParseColor(string.Join("", args));
Color color = XMLExtensions.ParseColor(string.Join(",", args));
if (Level.Loaded != null)
{
Level.Loaded.GenerationParams.AmbientLightColor = color;
@@ -528,6 +533,28 @@ namespace Barotrauma
}
}, isCheat: true));
commands.Add(new Command("resetall", "Reset all items and structures to prefabs. Only applicable in the subeditor.", args =>
{
if (Screen.Selected == GameMain.SubEditorScreen)
{
Item.ItemList.ForEach(i => i.Reset());
Structure.WallList.ForEach(s => s.Reset());
foreach (MapEntity entity in MapEntity.SelectedList)
{
if (entity is Item item)
{
item.CreateEditingHUD();
break;
}
else if (entity is Structure structure)
{
structure.CreateEditingHUD();
break;
}
}
}
}));
commands.Add(new Command("alpha", "Change the alpha (as bytes from 0 to 255) of the selected item/structure instances. Applied only in the subeditor.", (string[] args) =>
{
if (Screen.Selected == GameMain.SubEditorScreen)
@@ -3786,6 +3813,201 @@ namespace Barotrauma
NPCConversation.WriteToCSV();
}));
commands.Add(new Command("csvtoxml", "csvtoxml [language] -> Converts .csv localization files in Content/NPCConversations & Content/Texts to .xml for use in-game.", (string[] args) =>
{
if (args.Length == 0) return;
LocalizationCSVtoXML.Convert(args[0]);
}));
#endif
commands.Add(new Command("cleanbuild", "", (string[] args) =>
{
GameMain.Config.MusicVolume = 0.5f;
GameMain.Config.SoundVolume = 0.5f;
NewMessage("Music and sound volume set to 0.5", Color.Green);
commands.Add(new Command("camerasettings", "camerasettings [defaultzoom] [zoomsmoothness] [movesmoothness] [minzoom] [maxzoom]: debug command for testing camera settings. The values default to 1.1, 8.0, 8.0, 0.1 and 2.0.", (string[] args) =>
{
float defaultZoom = Screen.Selected.Cam.DefaultZoom;
if (args.Length > 0) float.TryParse(args[0], NumberStyles.Number, CultureInfo.InvariantCulture, out defaultZoom);
float zoomSmoothness = Screen.Selected.Cam.ZoomSmoothness;
if (args.Length > 1) float.TryParse(args[1], NumberStyles.Number, CultureInfo.InvariantCulture, out zoomSmoothness);
float moveSmoothness = Screen.Selected.Cam.MoveSmoothness;
if (args.Length > 2) float.TryParse(args[2], NumberStyles.Number, CultureInfo.InvariantCulture, out moveSmoothness);
float minZoom = Screen.Selected.Cam.MinZoom;
if (args.Length > 3) float.TryParse(args[3], NumberStyles.Number, CultureInfo.InvariantCulture, out minZoom);
float maxZoom = Screen.Selected.Cam.MaxZoom;
if (args.Length > 4) float.TryParse(args[4], NumberStyles.Number, CultureInfo.InvariantCulture, out maxZoom);
Screen.Selected.Cam.DefaultZoom = defaultZoom;
Screen.Selected.Cam.ZoomSmoothness = zoomSmoothness;
Screen.Selected.Cam.MoveSmoothness = moveSmoothness;
Screen.Selected.Cam.MinZoom = minZoom;
Screen.Selected.Cam.MaxZoom = maxZoom;
}));
GameMain.Config.SaveNewPlayerConfig();
commands.Add(new Command("refreshrect", "Updates the dimensions of the selected items to match the ones defined in the prefab. Applied only in the subeditor.", (string[] args) =>
{
//TODO: maybe do this automatically during loading when possible?
if (Screen.Selected == GameMain.SubEditorScreen)
{
if (!MapEntity.SelectedAny)
{
ThrowError("You have to select item(s) first!");
}
else
{
foreach (var mapEntity in MapEntity.SelectedList)
{
if (mapEntity is Item item)
{
item.Rect = new Rectangle(item.Rect.X, item.Rect.Y,
(int)(item.Prefab.sprite.size.X * item.Prefab.Scale),
(int)(item.Prefab.sprite.size.Y * item.Prefab.Scale));
}
else if (mapEntity is Structure structure)
{
if (!structure.ResizeHorizontal)
{
structure.Rect = new Rectangle(structure.Rect.X, structure.Rect.Y,
(int)structure.Prefab.ScaledSize.X,
structure.Rect.Height);
}
if (!structure.ResizeVertical)
{
structure.Rect = new Rectangle(structure.Rect.X, structure.Rect.Y,
structure.Rect.Width,
(int)structure.Prefab.ScaledSize.Y);
}
}
}
}
}
}, isCheat: false));
#endif
commands.Add(new Command("dumptexts", "dumptexts [filepath]: Extracts all the texts from the given text xml and writes them into a file (using the same filename, but with the .txt extension). If the filepath is omitted, the EnglishVanilla.xml file is used.", (string[] args) =>
{
string filePath = args.Length > 0 ? args[0] : "Content/Texts/EnglishVanilla.xml";
var doc = XMLExtensions.TryLoadXml(filePath);
if (doc?.Root == null) return;
List<string> lines = new List<string>();
foreach (XElement element in doc.Root.Elements())
{
lines.Add(element.ElementInnerText());
}
File.WriteAllLines(Path.GetFileNameWithoutExtension(filePath) + ".txt", lines);
},
() =>
{
var files = TextManager.GetTextFiles().Select(f => f.Replace("\\", "/"));
return new string[][]
{
TextManager.GetTextFiles().Where(f => Path.GetExtension(f)==".xml").ToArray()
};
}));
commands.Add(new Command("loadtexts", "loadtexts [sourcefile] [destinationfile]: Loads all lines of text from a given .txt file and inserts them sequientially into the elements of an xml file. If the file paths are omitted, EnglishVanilla.txt and EnglishVanilla.xml are used.", (string[] args) =>
{
string sourcePath = args.Length > 0 ? args[0] : "Content/Texts/EnglishVanilla.txt";
string destinationPath = args.Length > 1 ? args[1] : "Content/Texts/EnglishVanilla.xml";
string[] lines;
try
{
lines = File.ReadAllLines(sourcePath);
}
catch (Exception e)
{
ThrowError("Reading the file \"" + sourcePath + "\" failed.", e);
return;
}
var doc = XMLExtensions.TryLoadXml(destinationPath);
int i = 0;
foreach (XElement element in doc.Root.Elements())
{
if (i >= lines.Length)
{
ThrowError("Error while loading texts to the xml file. The xml has more elements than the number of lines in the text file.");
return;
}
element.Value = lines[i];
i++;
}
doc.Save(destinationPath);
},
() =>
{
var files = TextManager.GetTextFiles().Select(f => f.Replace("\\", "/"));
return new string[][]
{
files.Where(f => Path.GetExtension(f)==".txt").ToArray(),
files.Where(f => Path.GetExtension(f)==".xml").ToArray()
};
}));
commands.Add(new Command("updatetextfile", "updatetextfile [sourcefile] [destinationfile]: Inserts all the xml elements that are only present in the source file into the destination file. Can be used to update outdated translation files more easily.", (string[] args) =>
{
if (args.Length < 2) return;
string sourcePath = args[0];
string destinationPath = args[1];
var sourceDoc = XMLExtensions.TryLoadXml(sourcePath);
var destinationDoc = XMLExtensions.TryLoadXml(destinationPath);
XElement destinationElement = destinationDoc.Root.Elements().First();
foreach (XElement element in sourceDoc.Root.Elements())
{
if (destinationDoc.Root.Element(element.Name) == null)
{
element.Value = "!!!!!!!!!!!!!" + element.Value;
destinationElement.AddAfterSelf(element);
}
XNode nextNode = destinationElement.NextNode;
while ((!(nextNode is XElement) || nextNode == element) && nextNode != null) nextNode = nextNode.NextNode;
destinationElement = nextNode as XElement;
}
destinationDoc.Save(destinationPath);
},
() =>
{
var files = TextManager.GetTextFiles().Where(f => Path.GetExtension(f) == ".xml").Select(f => f.Replace("\\", "/")).ToArray();
return new string[][]
{
files,
files
};
}));
commands.Add(new Command("dumpentitytexts", "dumpentitytexts [filepath]: gets the names and descriptions of all entity prefabs and writes them into a file along with xml tags that can be used in translation files. If the filepath is omitted, the file is written to Content/Texts/EntityTexts.txt", (string[] args) =>
{
string filePath = args.Length > 0 ? args[0] : "Content/Texts/EntityTexts.txt";
List<string> lines = new List<string>();
foreach (MapEntityPrefab me in MapEntityPrefab.List)
{
lines.Add("<EntityName." + me.Identifier + ">" + me.Name + "</" + me.Identifier + ".Name>");
lines.Add("<EntityDescription." + me.Identifier + ">" + me.Description + "</" + me.Identifier + ".Description>");
}
File.WriteAllLines(filePath, lines);
}));
#if DEBUG
commands.Add(new Command("checkduplicates", "Checks the given language for duplicate translation keys and writes to file.", (string[] args) =>
{
if (args.Length != 1) return;
TextManager.CheckForDuplicates(args[0]);
}));
commands.Add(new Command("writetocsv", "Writes the default language (English) to a .csv file.", (string[] args) =>
{
TextManager.WriteToCSV();
NPCConversation.WriteToCSV();
}));
commands.Add(new Command("csvtoxml", "csvtoxml [language] -> Converts .csv localization files in Content/NPCConversations & Content/Texts to .xml for use in-game.", (string[] args) =>
{
if (args.Length == 0) return;
@@ -663,20 +663,6 @@ namespace Barotrauma
msg.Timer -= deltaTime;
msg.Pos += msg.Velocity * deltaTime;
}
foreach (GUIMessage msg in messages)
{
if (!msg.WorldSpace) continue;
msg.Timer -= deltaTime;
msg.Pos += msg.Velocity * deltaTime;
}
foreach (GUIMessage msg in messages)
{
if (!msg.WorldSpace) continue;
msg.Timer -= deltaTime;
msg.Pos += msg.Velocity * deltaTime;
}
}
messages.RemoveAll(m => m.Timer <= 0.0f);
@@ -12,7 +12,7 @@ namespace Barotrauma
{
private UInt16 startWatchmanID, endWatchmanID;
public static GUIComponent StartCampaignSetup(IEnumerable<string> saveFiles)
public static GUIComponent StartCampaignSetup( IEnumerable<Submarine> submarines, IEnumerable<string> saveFiles)
{
GUIFrame background = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), style: "GUIBackgroundBlocker");
@@ -35,7 +35,7 @@ namespace Barotrauma
var newCampaignContainer = new GUIFrame(new RectTransform(Vector2.One, campaignContainer.RectTransform, Anchor.BottomLeft), style: null);
var loadCampaignContainer = new GUIFrame(new RectTransform(Vector2.One, campaignContainer.RectTransform, Anchor.BottomLeft), style: null);
var campaignSetupUI = new CampaignSetupUI(true, newCampaignContainer, loadCampaignContainer, saveFiles);
var campaignSetupUI = new CampaignSetupUI(true, newCampaignContainer, loadCampaignContainer, submarines, saveFiles);
var newCampaignButton = new GUIButton(new RectTransform(new Vector2(0.3f, 1.0f), buttonContainer.RectTransform),
TextManager.Get("NewCampaign"))
@@ -92,8 +92,7 @@ namespace Barotrauma
if (endWatchman != null) { InitializeWatchman(endWatchman); }
}
}
protected override void WatchmanInteract(Character watchman, Character interactor)
{
if ((watchman.Submarine == Level.Loaded.StartOutpost && !Submarine.MainSub.AtStartPosition) ||
@@ -107,8 +106,7 @@ namespace Barotrauma
return;
}
if (GameMain.Client != null && interactor == Character.Controlled &&
(GameMain.Client.HasPermission(ClientPermissions.ManageRound) || GameMain.Client.HasPermission(ClientPermissions.ManageCampaign)))
if (GameMain.Client != null && interactor == Character.Controlled)
{
var msgBox = new GUIMessageBox("", TextManager.Get("CampaignEnterOutpostPrompt")
.Replace("[locationname]", Submarine.MainSub.AtStartPosition ? Map.CurrentLocation.Name : Map.SelectedLocation.Name),
@@ -122,8 +120,7 @@ namespace Barotrauma
return true;
};
msgBox.Buttons[0].OnClicked += msgBox.Close;
msgBox.Buttons[1].OnClicked += msgBox.Close;
msgBox.Buttons[1].OnClicked += msgBox.Close;
}
}
@@ -47,7 +47,7 @@ namespace Barotrauma
//if "%" is found
if (index > 0)
{
while (true)
while (index > 0)
{
//search for end of label
index -= 1;
@@ -439,7 +439,6 @@ namespace Barotrauma
}
};
#endif
var radioButtonFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.6f), voiceSettings.RectTransform))
{
Stretch = true,
@@ -458,6 +457,24 @@ namespace Barotrauma
voiceMode.AddRadioButton((VoiceMode)i, tick);
}
var micVolumeText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.18f), voiceSettings.RectTransform), TextManager.Get("MicrophoneVolume"));
var micVolumeSlider = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.18f), voiceSettings.RectTransform),
barSize: 0.1f)
{
UserData = micVolumeText,
BarScroll = (float)Math.Sqrt(MathUtils.InverseLerp(0.2f, 5.0f, MicrophoneVolume)),
OnMoved = (scrollBar, scroll) =>
{
MicrophoneVolume = MathHelper.Lerp(0.2f, 5.0f, scroll * scroll);
MicrophoneVolume = (float)Math.Round(MicrophoneVolume, 1);
ChangeSliderText(scrollBar, MicrophoneVolume);
scrollBar.Step = 0.05f;
return true;
},
Step = 0.05f
};
micVolumeSlider.OnMoved(micVolumeSlider, micVolumeSlider.BarScroll);
var voiceInputContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 0.2f), voiceSettings.RectTransform, Anchor.BottomCenter));
new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), voiceInputContainer.RectTransform), TextManager.Get("InputType.Voice") + ": ");
var voiceKeyBox = new GUITextBox(new RectTransform(new Vector2(0.4f, 1.0f), voiceInputContainer.RectTransform, Anchor.TopRight),
@@ -469,7 +486,6 @@ namespace Barotrauma
voiceKeyBox.SelectedColor = Color.Gold * 0.3f;
var voiceActivityGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.3f), voiceSettings.RectTransform));
GUITextBlock noiseGateText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), voiceActivityGroup.RectTransform), TextManager.Get("NoiseGateThreshold"))
{
TextGetter = () =>
@@ -509,13 +525,13 @@ namespace Barotrauma
if (GameMain.Client == null && VoipCapture.Instance == null)
{
VoipCapture.Create(GameMain.Config.VoiceCaptureDevice);
}
if (VoipCapture.Instance == null)
{
VoiceSetting = vMode = VoiceMode.Disabled;
voiceInputContainer.Visible = false;
voiceActivityGroup.Visible = false;
return;
if (VoipCapture.Instance == null)
{
VoiceSetting = vMode = VoiceMode.Disabled;
voiceInputContainer.Visible = false;
voiceActivityGroup.Visible = false;
return;
}
}
}
else
@@ -93,7 +93,7 @@ namespace Barotrauma.Items.Components
public void Draw(SpriteBatch spriteBatch, bool editing)
{
Color color = Color.White;
Color color = item.SpriteColor;
if (brokenSprite == null)
{
//broken doors turn black if no broken sprite has been configured
@@ -108,7 +108,7 @@ namespace Barotrauma.Items.Components
weldSpritePos.Y = -weldSpritePos.Y;
weldedSprite.Draw(spriteBatch,
weldSpritePos, Color.White * (stuck / 100.0f), scale: item.Scale);
weldSpritePos, item.SpriteColor * (stuck / 100.0f), scale: item.Scale);
}
if (openState == 1.0f)
@@ -313,7 +313,7 @@ namespace Barotrauma.Items.Components
if (sound == null) { return 0.0f; }
if (sound.VolumeProperty == "") { return sound.VolumeMultiplier; }
if (properties.TryGetValue(sound.VolumeProperty, out SerializableProperty property))
if (SerializableProperties.TryGetValue(sound.VolumeProperty, out SerializableProperty property))
{
float newVolume = 0.0f;
try
@@ -331,8 +331,18 @@ namespace Barotrauma.Items.Components
spriteBatch.GraphicsDevice.ScissorRectangle = container.Rect;
spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
//make the pointer jitter a bit if it's at the upper limit of the fission rate
float jitter = 0.0f;
if (FissionRate > allowedFissionRate.Y - 5.0f)
{
float jitterAmount = Math.Min(targetFissionRate - allowedFissionRate.Y, 10.0f);
float t = graphTimer / updateGraphInterval;
jitter = (PerlinNoise.GetPerlin(t * 0.5f, t * 0.1f) - 0.5f) * jitterAmount;
}
DrawMeter(spriteBatch, container.Rect,
fissionRateMeter, FissionRate, new Vector2(0.0f, 100.0f), optimalFissionRate, allowedFissionRate);
fissionRateMeter, FissionRate + jitter, new Vector2(0.0f, 100.0f), optimalFissionRate, allowedFissionRate);
spriteBatch.End();
spriteBatch.GraphicsDevice.ScissorRectangle = prevScissorRect;
@@ -392,12 +402,12 @@ namespace Barotrauma.Items.Components
Vector2 pos = new Vector2(rect.Center.X, rect.Y + meterSprite.Origin.Y * scale);
Vector2 optimalRangeNormalized = new Vector2(
(optimalRange.X - range.X) / (range.Y - range.X),
(optimalRange.Y - range.X) / (range.Y - range.X));
MathHelper.Clamp((optimalRange.X - range.X) / (range.Y - range.X), 0.0f, 0.95f),
MathHelper.Clamp((optimalRange.Y - range.X) / (range.Y - range.X), 0.0f, 1.0f));
Vector2 allowedRangeNormalized = new Vector2(
(allowedRange.X - range.X) / (range.Y - range.X),
(allowedRange.Y - range.X) / (range.Y - range.X));
MathHelper.Clamp((allowedRange.X - range.X) / (range.Y - range.X), 0.0f, 0.95f),
MathHelper.Clamp((allowedRange.Y - range.X) / (range.Y - range.X), 0.0f, 1.0f));
Vector2 sectorRad = new Vector2(-1.57f, 1.57f);
@@ -417,10 +427,10 @@ namespace Barotrauma.Items.Components
{
spriteBatch.End();
Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
spriteBatch.GraphicsDevice.ScissorRectangle = new Rectangle(0,0,GameMain.GraphicsWidth, (int)(pos.Y + (meterSprite.size.Y - meterSprite.Origin.Y) * scale));
spriteBatch.GraphicsDevice.ScissorRectangle = new Rectangle(0, 0, GameMain.GraphicsWidth, (int)(pos.Y + (meterSprite.size.Y - meterSprite.Origin.Y) * scale) - 3);
spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
sectorSprite.Draw(spriteBatch, pos, Color.LightGreen, MathHelper.PiOver2, scale);
sectorSprite.Draw(spriteBatch, pos, Color.LightGreen, MathHelper.PiOver2 + (allowedSectorRad.X + allowedSectorRad.Y) / 2.0f, scale);
sectorSprite.Draw(spriteBatch, pos, Color.Orange, optimalSectorRad.X, scale);
sectorSprite.Draw(spriteBatch, pos, Color.Red, allowedSectorRad.X, scale);
@@ -785,8 +785,9 @@ namespace Barotrauma.Items.Components
foreach (Limb limb in c.AnimController.Limbs)
{
float pointDist = ((limb.WorldPosition - pingSource) * displayScale).LengthSquared();
if (!limb.body.Enabled) { continue; }
float pointDist = ((limb.WorldPosition - pingSource) * displayScale).LengthSquared();
if (limb.SimPosition == Vector2.Zero || pointDist > DisplayRadius * DisplayRadius) continue;
if (pointDist > prevPingRadiusSqr && pointDist < pingRadiusSqr)
@@ -1,4 +1,6 @@
using Barotrauma.Particles;
using Barotrauma.Networking;
using Barotrauma.Particles;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;
@@ -112,8 +114,7 @@ namespace Barotrauma.Items.Components
System.Diagnostics.Debug.Assert(GuiFrame.GetChild(0) is GUILayoutGroup, "Repair UI hierarchy has changed, could not find skill texts");
foreach (GUIComponent c in GuiFrame.GetChild(0).Children)
{
Skill skill = c.UserData as Skill;
if (skill == null) continue;
if (!(c.UserData is Skill skill)) continue;
GUITextBlock textBlock = (GUITextBlock)c;
if (character.GetSkillLevel(skill.Identifier) < skill.Level)
@@ -126,5 +127,15 @@ namespace Barotrauma.Items.Components
}
}
}
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
{
deteriorationTimer = msg.ReadSingle();
}
public void ClientWrite(NetBuffer msg, object[] extraData = null)
{
//no need to write anything, just letting the server know we started repairing
}
}
}
@@ -181,7 +181,7 @@ namespace Barotrauma.Items.Components
Dictionary<AfflictionPrefab, float> combinedAfflictionStrengths = new Dictionary<AfflictionPrefab, float>();
foreach (Affliction affliction in allAfflictions)
{
if (affliction.Strength < affliction.Prefab.ActivationThreshold || affliction.Strength <= 0.0f) continue;
if (affliction.Strength < affliction.Prefab.ShowInHealthScannerThreshold || affliction.Strength <= 0.0f) continue;
if (combinedAfflictionStrengths.ContainsKey(affliction.Prefab))
{
combinedAfflictionStrengths[affliction.Prefab] += affliction.Strength;
@@ -237,13 +237,13 @@ namespace Barotrauma.Items.Components
railSprite?.Draw(spriteBatch,
drawPos,
Color.White,
item.SpriteColor,
rotation + MathHelper.PiOver2, item.Scale,
SpriteEffects.None, item.SpriteDepth + (railSprite.Depth - item.Sprite.Depth));
barrelSprite?.Draw(spriteBatch,
drawPos - new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)) * recoilOffset * item.Scale,
Color.White,
drawPos - new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)) * recoilOffset * item.Scale,
item.SpriteColor,
rotation + MathHelper.PiOver2, item.Scale,
SpriteEffects.None, item.SpriteDepth + (barrelSprite.Depth - item.Sprite.Depth));
@@ -288,7 +288,10 @@ namespace Barotrauma.Items.Components
availableAmmo.AddRange(itemContainer.Inventory.Items);
}
float chargeRate = powerConsumption <= 0.0f ? 1.0f : batteryCharge / batteryCapacity;
float chargeRate =
powerConsumption <= 0.0f ?
1.0f :
batteryCapacity > 0.0f ? batteryCharge / batteryCapacity : 0.0f;
bool charged = batteryCharge * 3600.0f > powerConsumption;
bool readyToFire = reload <= 0.0f && charged && availableAmmo.Any(p => p != null);
if (ShowChargeIndicator && PowerConsumption > 0.0f)
@@ -448,7 +448,7 @@ namespace Barotrauma
}
}
private GUIComponent CreateEditingHUD(bool inGame = false)
public GUIComponent CreateEditingHUD(bool inGame = false)
{
editingHUD = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GUI.Canvas, Anchor.CenterRight) { MinSize = new Point(400, 0) }) { UserData = this };
GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(0.95f, 0.8f), editingHUD.RectTransform, Anchor.Center), style: null)
@@ -457,40 +457,42 @@ namespace Barotrauma
};
var itemEditor = new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true);
if (!inGame && Linkable)
{
var linkText = new GUITextBlock(new RectTransform(new Point(editingHUD.Rect.Width, 20)), TextManager.Get("HoldToLink"), font: GUI.SmallFont);
var itemsText = new GUITextBlock(new RectTransform(new Point(editingHUD.Rect.Width, 20)), TextManager.Get("AllowedLinks") + ": ", font: GUI.SmallFont);
if (AllowedLinks.None())
{
itemsText.Text += TextManager.Get("None");
}
else
{
for (int i = 0; i < AllowedLinks.Count; i++)
{
itemsText.Text += AllowedLinks[i];
if (i < AllowedLinks.Count - 1)
{
itemsText.Text += ", ";
}
}
}
itemEditor.AddCustomContent(linkText, 1);
itemEditor.AddCustomContent(itemsText, 2);
linkText.TextColor = Color.Yellow;
itemsText.TextColor = Color.Yellow;
}
if (!inGame)
{
if (Linkable)
{
var linkText = new GUITextBlock(new RectTransform(new Point(editingHUD.Rect.Width, 20)), TextManager.Get("HoldToLink"), font: GUI.SmallFont);
var itemsText = new GUITextBlock(new RectTransform(new Point(editingHUD.Rect.Width, 20)), TextManager.Get("AllowedLinks") + ": ", font: GUI.SmallFont);
if (AllowedLinks.None())
{
itemsText.Text += TextManager.Get("None");
}
};
new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), buttonContainer.RectTransform), TextManager.Get("MirrorEntityY"))
{
ToolTip = TextManager.Get("MirrorEntityYToolTip"),
OnClicked = (button, data) =>
{
for (int i = 0; i < AllowedLinks.Count; i++)
{
itemsText.Text += AllowedLinks[i];
if (i < AllowedLinks.Count - 1)
{
itemsText.Text += ", ";
}
}
}
itemEditor.AddCustomContent(linkText, 1);
itemEditor.AddCustomContent(itemsText, 2);
linkText.TextColor = Color.Yellow;
itemsText.TextColor = Color.Yellow;
}
var buttonContainer = new GUILayoutGroup(new RectTransform(new Point(listBox.Content.Rect.Width, 20)), isHorizontal: true)
{
Stretch = true,
RelativeSpacing = 0.02f
};
new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), buttonContainer.RectTransform), TextManager.Get("MirrorEntityX"))
new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("MirrorEntityX"))
{
ToolTip = TextManager.Get("MirrorEntityXToolTip"),
OnClicked = (button, data) =>
@@ -499,7 +501,7 @@ namespace Barotrauma
return true;
}
};
new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), buttonContainer.RectTransform), TextManager.Get("MirrorEntityY"))
new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("MirrorEntityY"))
{
ToolTip = TextManager.Get("MirrorEntityYToolTip"),
OnClicked = (button, data) =>
@@ -510,7 +512,7 @@ namespace Barotrauma
};
if (Sprite != null)
{
var reloadTextureButton = new GUIButton(new RectTransform(new Vector2(0.3f, 1.0f), buttonContainer.RectTransform), TextManager.Get("ReloadSprite"));
var reloadTextureButton = new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("ReloadSprite"));
reloadTextureButton.OnClicked += (button, data) =>
{
Sprite.ReloadXML();
@@ -518,6 +520,15 @@ namespace Barotrauma
return true;
};
}
new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("ResetToPrefab"))
{
OnClicked = (button, data) =>
{
Reset();
CreateEditingHUD();
return true;
}
};
itemEditor.AddCustomContent(buttonContainer, itemEditor.ContentCount);
}
+11 -41
View File
@@ -1,14 +1,13 @@
using Barotrauma.Networking;
using Barotrauma.Particles;
using Barotrauma.Sounds;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Input;
using System.Linq;
using Lidgren.Network;
namespace Barotrauma
{
@@ -19,6 +18,8 @@ namespace Barotrauma
private List<Decal> decals = new List<Decal>();
private float serverUpdateDelay;
private float remoteWaterVolume, remoteOxygenPercentage;
private List<Vector3> remoteFireSources;
private bool networkUpdatePending;
private float networkUpdateTimer;
@@ -139,6 +140,10 @@ namespace Barotrauma
partial void UpdateProjSpecific(float deltaTime, Camera cam)
{
serverUpdateDelay -= deltaTime;
if (serverUpdateDelay <= 0.0f)
{
ApplyRemoteState();
}
if (networkUpdatePending)
{
@@ -547,18 +552,18 @@ namespace Barotrauma
public void ClientRead(ServerNetObject type, NetBuffer message, float sendingTime)
{
float newWaterVolume = message.ReadRangedSingle(0.0f, 1.5f, 8) * Volume;
float newOxygenPercentage = message.ReadRangedSingle(0.0f, 100.0f, 8);
remoteWaterVolume = message.ReadRangedSingle(0.0f, 1.5f, 8) * Volume;
remoteOxygenPercentage = message.ReadRangedSingle(0.0f, 100.0f, 8);
bool hasFireSources = message.ReadBoolean();
int fireSourceCount = 0;
List<Vector3> newFireSources = new List<Vector3>();
remoteFireSources = new List<Vector3>();
if (hasFireSources)
{
fireSourceCount = message.ReadRangedInteger(0, 16);
for (int i = 0; i < fireSourceCount; i++)
{
newFireSources.Add(new Vector3(
remoteFireSources.Add(new Vector3(
MathHelper.Clamp(message.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f),
MathHelper.Clamp(message.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f),
message.ReadRangedSingle(0.0f, 1.0f, 8)));
@@ -567,41 +572,6 @@ namespace Barotrauma
if (serverUpdateDelay > 0.0f) { return; }
WaterVolume = newWaterVolume;
OxygenPercentage = newOxygenPercentage;
for (int i = 0; i < fireSourceCount; i++)
{
Vector2 pos = new Vector2(
rect.X + rect.Width * newFireSources[i].X,
rect.Y - rect.Height + (rect.Height * newFireSources[i].Y));
float size = newFireSources[i].Z * rect.Width;
var newFire = i < FireSources.Count ?
FireSources[i] :
new FireSource(Submarine == null ? pos : pos + Submarine.Position, null, true);
newFire.Position = pos;
newFire.Size = new Vector2(size, newFire.Size.Y);
//ignore if the fire wasn't added to this room (invalid position)?
if (!FireSources.Contains(newFire))
{
newFire.Remove();
continue;
}
}
for (int i = FireSources.Count - 1; i >= fireSourceCount; i--)
{
FireSources[i].Remove();
if (i < FireSources.Count)
{
FireSources.RemoveAt(i);
}
}
if (serverUpdateDelay > 0.0f) { return; }
ApplyRemoteState();
}
@@ -404,12 +404,15 @@ namespace Barotrauma.Lights
}
}
if (highlightedEntities.Count == 0) { return false; }
//draw characters in solid white first
//draw characters in light blue first
graphics.SetRenderTarget(HighlightMap);
SolidColorEffect.CurrentTechnique = SolidColorEffect.Techniques["SolidColor"];
SolidColorEffect.Parameters["color"].SetValue(Color.LightBlue.ToVector4());
SolidColorEffect.CurrentTechnique.Passes[0].Apply();
DeformableSprite.Effect.CurrentTechnique = DeformableSprite.Effect.Techniques["DeformShaderSolidColor"];
DeformableSprite.Effect.Parameters["solidColor"].SetValue(Color.LightBlue.ToVector4());
DeformableSprite.Effect.CurrentTechnique.Passes[0].Apply();
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, samplerState: SamplerState.LinearWrap, effect: SolidColorEffect, transformMatrix: spriteBatchTransform);
foreach (Entity highlighted in highlightedEntities)
{
@@ -426,9 +429,12 @@ namespace Barotrauma.Lights
//draw characters in black with a bit of blur, leaving the white edges visible
float phase = (float)(Math.Sin(Timing.TotalTime * 3.0f) + 1.0f) / 2.0f; //phase oscillates between 0 and 1
SolidColorEffect.Parameters["color"].SetValue(Color.Black.ToVector4() * MathHelper.Lerp(0.5f, 0.9f, phase));
Vector4 overlayColor = Color.Black.ToVector4() * MathHelper.Lerp(0.5f, 0.9f, phase);
SolidColorEffect.Parameters["color"].SetValue(overlayColor);
SolidColorEffect.CurrentTechnique = SolidColorEffect.Techniques["SolidColorBlur"];
SolidColorEffect.CurrentTechnique.Passes[0].Apply();
DeformableSprite.Effect.Parameters["solidColor"].SetValue(overlayColor);
DeformableSprite.Effect.CurrentTechnique.Passes[0].Apply();
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, samplerState: SamplerState.LinearWrap, effect: SolidColorEffect, transformMatrix: spriteBatchTransform);
foreach (Entity highlighted in highlightedEntities)
{
@@ -450,6 +456,8 @@ namespace Barotrauma.Lights
spriteBatch.Draw(highlightRaster, new Rectangle(0, 0, HighlightMap.Width, HighlightMap.Height), new Rectangle(0, 0, HighlightMap.Width, HighlightMap.Height), Color.White * 0.5f);
spriteBatch.End();
DeformableSprite.Effect.CurrentTechnique = DeformableSprite.Effect.Techniques["DeformShader"];
return true;
}
@@ -471,6 +479,10 @@ namespace Barotrauma.Lights
Level.Loaded?.Renderer?.RenderWalls(graphics, cam, specular: true);
DeformableSprite.Effect.CurrentTechnique = DeformableSprite.Effect.Techniques["DeformShaderSolidColor"];
DeformableSprite.Effect.Parameters["solidColor"].SetValue(Color.Gray.ToVector4());
DeformableSprite.Effect.CurrentTechnique.Passes[0].Apply();
//obstruct specular maps behind the sub and characters by drawing them on the map in solid gray
SolidColorEffect.CurrentTechnique = SolidColorEffect.Techniques["SolidColor"];
SolidColorEffect.Parameters["color"].SetValue(Color.Gray.ToVector4());
@@ -487,6 +499,9 @@ namespace Barotrauma.Lights
}
spriteBatch.End();
DeformableSprite.Effect.CurrentTechnique = DeformableSprite.Effect.Techniques["DeformShader"];
graphics.SetRenderTarget(null);
graphics.BlendState = BlendState.AlphaBlend;
}
@@ -98,7 +98,7 @@ namespace Barotrauma
Stretch = true,
RelativeSpacing = 0.02f
};
new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), buttonContainer.RectTransform), TextManager.Get("MirrorEntityX"))
new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("MirrorEntityX"))
{
ToolTip = TextManager.Get("MirrorEntityXToolTip"),
OnClicked = (button, data) =>
@@ -107,7 +107,7 @@ namespace Barotrauma
return true;
}
};
new GUIButton(new RectTransform(new Vector2(0.3f, 1.0f), buttonContainer.RectTransform), TextManager.Get("MirrorEntityY"))
new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("MirrorEntityY"))
{
ToolTip = TextManager.Get("MirrorEntityYToolTip"),
OnClicked = (button, data) =>
@@ -116,7 +116,7 @@ namespace Barotrauma
return true;
}
};
var reloadTextureButton = new GUIButton(new RectTransform(new Vector2(0.3f, 1.0f), buttonContainer.RectTransform), TextManager.Get("ReloadSprite"))
var reloadTextureButton = new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("ReloadSprite"))
{
OnClicked = (button, data) =>
{
@@ -125,6 +125,15 @@ namespace Barotrauma
return true;
}
};
new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("ResetToPrefab"))
{
OnClicked = (button, data) =>
{
Reset();
CreateEditingHUD();
return true;
}
};
editor.AddCustomContent(buttonContainer, editor.ContentCount);
PositionEditingHUD();
@@ -351,6 +360,7 @@ namespace Barotrauma
-Bodies[i].Rotation, Color.White);
}
}
AiTarget?.Draw(spriteBatch);
}
}
@@ -132,6 +132,7 @@ namespace Barotrauma.Networking
var buttonContainer = new GUILayoutGroup(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ButtonAreaTop, inGameHUD.RectTransform),
isHorizontal: true, childAnchor: Anchor.CenterRight)
{
AbsoluteSpacing = 5,
CanBeFocused = false
};
@@ -147,9 +148,10 @@ namespace Barotrauma.Networking
Visible = false
};
EndVoteTickBox = new GUITickBox(new RectTransform(new Vector2(0.1f, 0.6f), buttonContainer.RectTransform) { MinSize = new Point(150, 0) },
EndVoteTickBox = new GUITickBox(new RectTransform(new Vector2(0.1f, 0.4f), buttonContainer.RectTransform) { MinSize = new Point(150, 0) },
TextManager.Get("EndRound"))
{
UserData = TextManager.Get("EndRound"),
OnSelected = ToggleEndRoundVote,
Visible = false
};
@@ -323,18 +325,17 @@ namespace Barotrauma.Networking
// Loop until we are approved
//TODO: show the name of the server instead of IP when connecting through the server list (more streamer-friendly)
string connectingText = TextManager.Get("ConnectingTo").Replace("[serverip]", serverIP);
string connectingText = TextManager.Get("Connecting");
while (!CanStart && !connectCancelled)
{
if (reconnectBox == null)
{
reconnectBox = new GUIMessageBox(TextManager.Get("Connecting"), connectingText, new string[] { TextManager.Get("Cancel") });
reconnectBox = new GUIMessageBox(connectingText, TextManager.Get("ConnectingTo").Replace("[serverip]", serverIP), new string[] { TextManager.Get("Cancel") });
reconnectBox.Buttons[0].OnClicked += CancelConnect;
reconnectBox.Buttons[0].OnClicked += reconnectBox.Close;
}
reconnectBox.Text.Text = connectingText + new string('.', ((int)Timing.TotalTime % 3 + 1));
reconnectBox.Header.Text = connectingText + new string('.', ((int)Timing.TotalTime % 3 + 1));
if (DateTime.Now > reqAuthTime)
{
@@ -621,7 +622,7 @@ namespace Barotrauma.Networking
if (gameStarted) SetRadioButtonColor();
if (ShowNetStats)
if (ShowNetStats && client?.ServerConnection != null)
{
netStats.AddValue(NetStats.NetStatType.ReceivedBytes, client.ServerConnection.Statistics.ReceivedBytes);
netStats.AddValue(NetStats.NetStatType.SentBytes, client.ServerConnection.Statistics.SentBytes);
@@ -782,7 +783,7 @@ namespace Barotrauma.Networking
saveFiles.Add(inc.ReadString());
}
GameMain.NetLobbyScreen.CampaignSetupUI = MultiPlayerCampaign.StartCampaignSetup(saveFiles);
GameMain.NetLobbyScreen.CampaignSetupUI = MultiPlayerCampaign.StartCampaignSetup(serverSubmarines, saveFiles);
break;
case ServerPacketHeader.PERMISSIONS:
ReadPermissions(inc);
@@ -835,6 +836,8 @@ namespace Barotrauma.Networking
DisconnectReason disconnectReason = DisconnectReason.Unknown;
if (splitMsg.Length > 0) Enum.TryParse(splitMsg[0], out disconnectReason);
DebugConsole.NewMessage("Received a disconnect message (" + disconnectMsg + ")");
if (disconnectReason == DisconnectReason.ServerFull)
{
//already waiting for a slot to free up, do nothing
@@ -864,22 +867,19 @@ namespace Barotrauma.Networking
waitInServerQueueBox = null;
CoroutineManager.StopCoroutines("WaitInServerQueue");
}
else
{
string msg = "";
if (disconnectReason == DisconnectReason.Unknown)
{
msg = disconnectMsg;
}
else
{
msg = TextManager.Get("DisconnectReason." + disconnectReason.ToString());
if (allowReconnect && disconnectReason == DisconnectReason.Unknown)
{
DebugConsole.NewMessage("Attempting to reconnect...");
string msg = TextManager.GetServerMessage(disconnectMsg);
msg = string.IsNullOrWhiteSpace(msg) ?
TextManager.Get("ConnectionLostReconnecting") :
msg + '\n' + TextManager.Get("ConnectionLostReconnecting");
reconnectBox = new GUIMessageBox(
TextManager.Get("ConnectionLost"),
TextManager.Get("ConnectionLostReconnecting"), new string[0]);
msg, new string[0]);
connected = false;
ConnectToServer(serverIP);
}
@@ -888,10 +888,12 @@ namespace Barotrauma.Networking
string msg = "";
if (disconnectReason == DisconnectReason.Unknown)
{
DebugConsole.NewMessage("Do not attempt reconnect (not allowed).");
msg = disconnectMsg;
}
else
{
DebugConsole.NewMessage("Do not attempt to reconnect (DisconnectReason doesn't allow reconnection).");
msg = TextManager.Get("DisconnectReason." + disconnectReason.ToString());
for (int i = 1; i < splitMsg.Length; i++)
@@ -1031,9 +1033,10 @@ namespace Barotrauma.Networking
EndVoteTickBox.Selected = false;
int seed = inc.ReadInt32();
string levelSeed = inc.ReadString();
float levelDifficulty = inc.ReadFloat();
int seed = inc.ReadInt32();
string levelSeed = inc.ReadString();
int levelEqualityCheckVal = inc.ReadInt32();
float levelDifficulty = inc.ReadFloat();
byte losMode = inc.ReadByte();
@@ -1102,6 +1105,15 @@ namespace Barotrauma.Networking
mirrorLevel: campaign.Map.CurrentLocation != campaign.Map.SelectedConnection.Locations[0]);
}
if (Level.Loaded.EqualityCheckVal != levelEqualityCheckVal)
{
string errorMsg = "Level equality check failed. The level generated at your end doesn't match the level generated by the server (seed " + Level.Loaded.Seed + ").";
DebugConsole.ThrowError(errorMsg, createMessageBox: true);
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:LevelsDontMatch" + levelSeed, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
CoroutineManager.StartCoroutine(EndGame(""));
yield return CoroutineStatus.Failure;
}
if (respawnAllowed) respawnManager = new RespawnManager(this, GameMain.NetLobbyScreen.UsingShuttle ? GameMain.NetLobbyScreen.SelectedShuttle : null);
gameStarted = true;
@@ -1171,8 +1183,8 @@ namespace Barotrauma.Networking
}
}
GameMain.NetLobbyScreen.UpdateSubList(GameMain.NetLobbyScreen.SubList, submarines);
GameMain.NetLobbyScreen.UpdateSubList(GameMain.NetLobbyScreen.ShuttleList.ListBox, submarines);
GameMain.NetLobbyScreen.UpdateSubList(GameMain.NetLobbyScreen.SubList, serverSubmarines);
GameMain.NetLobbyScreen.UpdateSubList(GameMain.NetLobbyScreen.ShuttleList.ListBox, serverSubmarines);
gameStarted = inc.ReadBoolean();
bool allowSpectating = inc.ReadBoolean();
@@ -1458,6 +1470,9 @@ namespace Barotrauma.Networking
case ServerNetObject.CLIENT_LIST:
ReadClientList(inc);
break;
case ServerNetObject.CLIENT_LIST:
ReadClientList(inc);
break;
case ServerNetObject.CHAT_MESSAGE:
ChatMessage.ClientRead(inc);
break;
@@ -1781,6 +1796,8 @@ namespace Barotrauma.Networking
SaveUtil.LoadGame(GameMain.GameSession.SavePath, GameMain.GameSession);
campaign.LastSaveID = campaign.PendingSaveID;
DebugConsole.Log("Campaign save received, save ID " + campaign.LastSaveID);
//decrement campaign update ID so the server will send us the latest data
//(as there may have been campaign updates after the save file was created)
campaign.LastUpdateID--;
@@ -1798,7 +1815,7 @@ namespace Barotrauma.Networking
public override void CreateEntityEvent(INetSerializable entity, object[] extraData)
{
if (!(entity is IClientSerializable)) throw new InvalidCastException("entity is not IClientSerializable");
if (!(entity is IClientSerializable)) throw new InvalidCastException("Entity is not IClientSerializable");
entityEventManager.CreateEvent(entity as IClientSerializable, extraData);
}
@@ -2067,7 +2084,8 @@ namespace Barotrauma.Networking
msg.Write(true); msg.WritePadBits();
msg.Write(savePath);
msg.Write(mapSeed);
msg.Write(sub.FilePath);
msg.Write(sub.Name);
msg.Write(sub.MD5Hash.Hash);
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
@@ -2305,13 +2323,25 @@ namespace Barotrauma.Networking
if (EndVoteCount > 0)
{
string endVoteText = TextManager.Get("EndRoundVotes")
.Replace("[y]", EndVoteCount.ToString())
.Replace("[n]", (EndVoteMax - EndVoteCount).ToString());
GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - 10.0f - GUI.SmallFont.MeasureString(endVoteText).X, 40),
endVoteText,
Color.White,
font: GUI.SmallFont);
if (EndVoteTickBox.Visible)
{
EndVoteTickBox.Text =
(EndVoteTickBox.UserData as string) + " " + EndVoteCount + "/" + EndVoteMax;
}
else
{
string endVoteText = TextManager.Get("EndRoundVotes")
.Replace("[votes]", EndVoteCount.ToString())
.Replace("[max]", EndVoteMax.ToString());
GUI.DrawString(spriteBatch, EndVoteTickBox.Rect.Center.ToVector2() - GUI.SmallFont.MeasureString(endVoteText) / 2,
endVoteText,
Color.White,
font: GUI.SmallFont);
}
}
else
{
EndVoteTickBox.Text = EndVoteTickBox.UserData as string;
}
if (respawnManager != null)
@@ -1,4 +1,5 @@
using Lidgren.Network;
using Microsoft.Xna.Framework;
using OpenTK.Audio.OpenAL;
using System;
using System.Linq;
@@ -26,6 +27,11 @@ namespace Barotrauma.Networking
get;
private set;
}
public float Gain
{
get { return GameMain.Config?.MicrophoneVolume ?? 1.0f; }
}
public DateTime LastEnqueueAudio;
@@ -69,6 +75,7 @@ namespace Barotrauma.Networking
{
if (!GUIMessageBox.MessageBoxes.Any(mb => mb.UserData as string == "capturedevicenotfound"))
{
GUI.SettingsMenuOpen = false;
new GUIMessageBox(TextManager.Get("Error"), TextManager.Get("VoipCaptureDeviceNotFound"))
{
UserData = "capturedevicenotfound"
@@ -160,8 +167,9 @@ namespace Barotrauma.Networking
double maxAmplitude = 0.0f;
for (int i = 0; i < VoipConfig.BUFFER_SIZE; i++)
{
double sampleVal = (double)uncompressedBuffer[i] / (double)short.MaxValue;
maxAmplitude = Math.Max(maxAmplitude, Math.Abs(sampleVal));
uncompressedBuffer[i] = (short)MathHelper.Clamp((uncompressedBuffer[i] * Gain), -short.MaxValue, short.MaxValue);
double sampleVal = uncompressedBuffer[i] / (double)short.MaxValue;
maxAmplitude = Math.Max(maxAmplitude, Math.Abs(sampleVal));
}
double dB = Math.Min(20 * Math.Log10(maxAmplitude), 0.0);
@@ -150,10 +150,10 @@ namespace Barotrauma
float MaxAngularVel = NetConfig.MaxPhysicsBodyAngularVelocity;
Vector2 newPosition = SimPosition;
float newRotation = Rotation;
float? newRotation = null;
bool awake = body.Awake;
Vector2 newVelocity = LinearVelocity;
float newAngularVelocity = AngularVelocity;
float? newAngularVelocity = null;
newPosition = new Vector2(
msg.ReadFloat(),
@@ -179,12 +179,12 @@ namespace Barotrauma
msg.ReadPadBits();
if (!MathUtils.IsValid(newPosition) ||
!MathUtils.IsValid(newRotation) ||
!MathUtils.IsValid(newVelocity) ||
!MathUtils.IsValid(newAngularVelocity))
(newRotation.HasValue && !MathUtils.IsValid(newRotation.Value)) ||
(newAngularVelocity.HasValue && !MathUtils.IsValid(newAngularVelocity.Value)))
{
string errorMsg = "Received invalid position data for \"" + parentDebugName
+ "\" (position: " + newPosition + ", rotation: " + newRotation + ", velocity: " + newVelocity + ", angular velocity: " + newAngularVelocity + ")";
+ "\" (position: " + newPosition + ", rotation: " + (newRotation ?? 0) + ", velocity: " + newVelocity + ", angular velocity: " + (newAngularVelocity ?? 0) + ")";
#if DEBUG
DebugConsole.ThrowError(errorMsg);
#endif
@@ -33,7 +33,7 @@ namespace Barotrauma
private readonly bool isMultiplayer;
public CampaignSetupUI(bool isMultiplayer, GUIComponent newGameContainer, GUIComponent loadGameContainer, IEnumerable<string> saveFiles=null)
public CampaignSetupUI(bool isMultiplayer, GUIComponent newGameContainer, GUIComponent loadGameContainer, IEnumerable<Submarine> submarines, IEnumerable<string> saveFiles = null)
{
this.isMultiplayer = isMultiplayer;
this.newGameContainer = newGameContainer;
@@ -45,6 +45,12 @@ namespace Barotrauma
RelativeSpacing = 0.05f
};
var columnContainer = new GUILayoutGroup(new RectTransform(Vector2.One, newGameContainer.RectTransform), isHorizontal: true)
{
Stretch = true,
RelativeSpacing = 0.05f
};
var leftColumn = new GUILayoutGroup(new RectTransform(Vector2.One, columnContainer.RectTransform))
{
Stretch = true,
@@ -63,7 +69,7 @@ namespace Barotrauma
OnSelected = CheckForPax
};
UpdateSubList();
UpdateSubList(submarines);
// New game right sideon
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), rightColumn.RectTransform), TextManager.Get("SaveName") + ":", textAlignment: Alignment.BottomLeft);
@@ -90,9 +96,8 @@ namespace Barotrauma
return false;
}
Submarine selectedSub = subList.SelectedData as Submarine;
if (selectedSub == null) return false;
if (!(subList.SelectedData is Submarine selectedSub)) { return false; }
if (string.IsNullOrEmpty(selectedSub.MD5Hash.Hash))
{
((GUITextBlock)subList.SelectedComponent).TextColor = Color.DarkRed * 0.8f;
@@ -199,9 +204,9 @@ namespace Barotrauma
public void UpdateSubList(IEnumerable<Submarine> submarines)
{
#if DEBUG
var subsToShow = Submarine.SavedSubmarines.Where(s => !s.HasTag(SubmarineTag.HideInMenus));
var subsToShow = submarines.Where(s => !s.HasTag(SubmarineTag.HideInMenus));
#else
var subsToShow = Submarine.SavedSubmarines;
var subsToShow = submarines;
#endif
subList.ClearChildren();
@@ -459,6 +459,12 @@ namespace Barotrauma
OnClicked = (GUIButton btn, object obj) => { StartRound?.Invoke(); return true; },
Enabled = true
};
if (GameMain.Client != null)
{
startButton.Visible = !GameMain.Client.GameStarted &&
(GameMain.Client.HasPermission(Networking.ClientPermissions.ManageRound) ||
GameMain.Client.HasPermission(Networking.ClientPermissions.ManageCampaign));
}
}
OnLocationSelected?.Invoke(location, connection);
@@ -502,7 +508,13 @@ namespace Barotrauma
CanBeFocused = false
};
if (startButton != null) { startButton.Enabled = true; }
if (startButton != null)
{
startButton.Enabled = true;
startButton.Visible = GameMain.Client == null ||
GameMain.Client.HasPermission(Networking.ClientPermissions.ManageRound) ||
GameMain.Client.HasPermission(Networking.ClientPermissions.ManageCampaign);
}
}
private void CreateItemFrame(PurchasedItem pi, PriceInfo priceInfo, GUIListBox listBox, int width)
@@ -282,7 +282,7 @@ namespace Barotrauma
menuTabs[(int)Tab.LoadGame] = new GUIFrame(new RectTransform(relativeSize, GUI.Canvas, anchor, pivot, minSize, maxSize));
var paddedLoadGame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), menuTabs[(int)Tab.LoadGame].RectTransform, Anchor.Center), style: null);
campaignSetupUI = new CampaignSetupUI(false, paddedNewGame, paddedLoadGame)
campaignSetupUI = new CampaignSetupUI(false, paddedNewGame, paddedLoadGame, Submarine.SavedSubmarines)
{
LoadGame = LoadGame,
StartNewGame = StartGame
@@ -336,7 +336,7 @@ namespace Barotrauma
UpdateTutorialList();
campaignSetupUI.UpdateSubList();
campaignSetupUI.UpdateSubList(Submarine.SavedSubmarines);
ResetButtonStates(null);
@@ -632,6 +632,13 @@ namespace Barotrauma
Visible = false
};
campaignViewButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), rightInfoColumn.RectTransform),
TextManager.Get("CampaignView"), style: "GUIButtonLarge")
{
OnClicked = (btn, obj) => { ToggleCampaignView(true); return true; },
Visible = false
};
StartButton = new GUIButton(new RectTransform(new Vector2(0.3f, 0.1f), infoFrameContent.RectTransform, Anchor.BottomRight),
TextManager.Get("StartGameButton"), style: "GUIButtonLarge")
{
@@ -644,13 +651,6 @@ namespace Barotrauma
};
clientHiddenElements.Add(StartButton);
campaignViewButton = new GUIButton(new RectTransform(new Vector2(0.3f, 0.1f), infoFrameContent.RectTransform, Anchor.BottomRight) { RelativeOffset = new Vector2(0.0f, 0.06f) },
TextManager.Get("CampaignView"), style: "GUIButtonLarge")
{
OnClicked = (btn, obj) => { ToggleCampaignView(true); return true; },
Visible = false
};
spectateButton = new GUIButton(new RectTransform(new Vector2(0.3f, 0.1f), infoFrameContent.RectTransform, Anchor.BottomRight),
TextManager.Get("SpectateButton"), style: "GUIButtonLarge");
}
@@ -726,6 +726,12 @@ namespace Barotrauma
spectateButton.Visible = GameMain.Client.GameStarted;
ReadyToStartBox.Visible = !GameMain.Client.GameStarted;
ReadyToStartBox.Selected = false;
if (campaignUI?.StartButton != null)
{
campaignUI.StartButton.Visible = !GameMain.Client.GameStarted &&
(GameMain.Client.HasPermission(ClientPermissions.ManageRound) ||
GameMain.Client.HasPermission(ClientPermissions.ManageCampaign));
}
GameMain.Client.SetReadyToStart(ReadyToStartBox);
}
else
@@ -844,6 +850,13 @@ namespace Barotrauma
GameMain.Client.ShowLogButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog);
GameMain.Client.EndRoundButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ManageRound);
if (campaignUI?.StartButton != null)
{
campaignUI.StartButton.Visible = !GameMain.Client.GameStarted &&
(GameMain.Client.HasPermission(ClientPermissions.ManageRound) ||
GameMain.Client.HasPermission(ClientPermissions.ManageCampaign));
}
}
public void ShowSpectateButton()
@@ -1191,7 +1204,7 @@ namespace Barotrauma
if (sub.HasTag(SubmarineTag.Shuttle))
{
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), frame.RectTransform, Anchor.CenterRight),
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), frame.RectTransform, Anchor.CenterRight) { RelativeOffset = new Vector2(0.1f, 0.0f) },
TextManager.Get("Shuttle"), textAlignment: Alignment.CenterRight, font: GUI.SmallFont)
{
TextColor = subTextBlock.TextColor * 0.8f,
@@ -716,7 +716,7 @@ namespace Barotrauma
catch (PingException ex)
{
string errorMsg = "Failed to ping a server (" + serverInfo.ServerName + ", " + serverInfo.IP + ") - " + (ex?.InnerException?.Message ?? ex.Message);
GameAnalyticsManager.AddErrorEventOnce("ServerListScreen.PingServer:PingException" + serverInfo.IP, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
GameAnalyticsManager.AddErrorEventOnce("ServerListScreen.PingServer:PingException" + serverInfo.IP, GameAnalyticsSDK.Net.EGAErrorSeverity.Warning, errorMsg);
#if DEBUG
DebugConsole.NewMessage(errorMsg, Color.Red);
#endif
@@ -26,6 +26,10 @@ namespace Barotrauma
private int subDivX, subDivY;
private static Effect effect;
public static Effect Effect
{
get { return effect; }
}
private Point spritePos;
private Point spriteSize;