(38b5d9aad) Experimental changes to syncing ragdolled (unconscious/dead) characters: - Higher error tolerance when syncing the positions. It's often hard to get the main limb exactly to the same position as the collider, because the positions of the limbs aren't synced and the pose of the ragdoll may differ between the server and clients. Increasing the tolerance makes it less likely for dead/unconscious characters to "twitch" when the game attempts to force the main limb to the position of the collider. - If the position of the ragdoll differs from the position of the collider so much that CheckDistFromCollider disables limb collisions, apply an additional force to all limbs to force the ragdoll to the correct position. Otherwise the ragdoll can occasionally start "hanging" midair, clipping through solid objects, because the main limb's pull joint doesn't necessarily have enough force to pull the entire ragdoll up to the collider.
This commit is contained in:
@@ -79,8 +79,8 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\ParamsEditor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\RectTransform.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\ShapeExtensions.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\SpriteSheetPlayer.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\UISprite.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\VideoPlayer.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\Widget.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Items\CharacterInventory.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Items\Components\Door.cs" />
|
||||
@@ -213,7 +213,6 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Sprite\DeformAnimations\SpriteDeformation.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Sprite\Sprite.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Sprite\SpriteSheet.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\StatusEffects\StatusEffect.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Utils\LocalizationCSVtoXML.cs">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</Compile>
|
||||
|
||||
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.8.9.8")]
|
||||
[assembly: AssemblyFileVersion("0.8.9.8")]
|
||||
[assembly: AssemblyVersion("0.8.9.6")]
|
||||
[assembly: AssemblyFileVersion("0.8.9.6")]
|
||||
|
||||
@@ -13,39 +13,13 @@ namespace Barotrauma
|
||||
var pos = new Vector2(WorldPosition.X, -WorldPosition.Y);
|
||||
if (soundRange > 0.0f)
|
||||
{
|
||||
Color color;
|
||||
if (Entity is Character)
|
||||
{
|
||||
color = Color.Yellow;
|
||||
}
|
||||
else if (Entity is Item)
|
||||
{
|
||||
color = Color.Orange;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = Color.OrangeRed;
|
||||
}
|
||||
Color color = Entity is Character ? Color.Yellow : Color.Orange;
|
||||
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;
|
||||
if (Entity is Character)
|
||||
{
|
||||
color = Color.CornflowerBlue;
|
||||
}
|
||||
else if (Entity is Item)
|
||||
{
|
||||
color = Color.CadetBlue;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = Color.WhiteSmoke;
|
||||
}
|
||||
Color color = Entity is Character ? Color.CornflowerBlue : Color.CadetBlue;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,17 +16,18 @@ namespace Barotrauma
|
||||
|
||||
if (SelectedAiTarget?.Entity != null)
|
||||
{
|
||||
GUI.DrawLine(spriteBatch, pos, new Vector2(SelectedAiTarget.WorldPosition.X, -SelectedAiTarget.WorldPosition.Y), Color.Red * 0.5f, 0, 4);
|
||||
GUI.DrawLine(spriteBatch, pos, new Vector2(SelectedAiTarget.WorldPosition.X, -SelectedAiTarget.WorldPosition.Y), Color.Red * 0.3f, 0, 5);
|
||||
|
||||
if (wallTarget != null)
|
||||
{
|
||||
Vector2 wallTargetPos = wallTarget.Position;
|
||||
if (wallTarget.Structure.Submarine != null) { wallTargetPos += wallTarget.Structure.Submarine.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.Orange, false);
|
||||
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.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{SelectedAiTarget.Entity.ToString()} ({targetValue.FormatZeroDecimal()})", Color.Red, Color.Black);
|
||||
|
||||
GUI.Font.DrawString(spriteBatch, $"{SelectedAiTarget.Entity.ToString()} ({targetValue.ToString()})", pos - Vector2.UnitY * 20.0f, Color.Red);
|
||||
}
|
||||
|
||||
/*GUI.Font.DrawString(spriteBatch, targetValue.ToString(), pos - Vector2.UnitY * 80.0f, Color.Red);
|
||||
@@ -51,15 +52,24 @@ namespace Barotrauma
|
||||
}
|
||||
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 80.0f, State.ToString(), stateColor, Color.Black);
|
||||
|
||||
if (LatchOntoAI != null)
|
||||
if (latchOntoAI != null)
|
||||
{
|
||||
foreach (Joint attachJoint in LatchOntoAI.AttachJoints)
|
||||
foreach (Joint attachJoint in latchOntoAI.AttachJoints)
|
||||
{
|
||||
GUI.DrawLine(spriteBatch,
|
||||
ConvertUnits.ToDisplayUnits(new Vector2(attachJoint.WorldAnchorA.X, -attachJoint.WorldAnchorA.Y)),
|
||||
ConvertUnits.ToDisplayUnits(new Vector2(attachJoint.WorldAnchorB.X, -attachJoint.WorldAnchorB.Y)), Color.Green, 0, 4);
|
||||
ConvertUnits.ToDisplayUnits(new Vector2(attachJoint.WorldAnchorB.X, -attachJoint.WorldAnchorB.Y)), Color.Orange * 0.6f, 0, 5);
|
||||
}
|
||||
|
||||
if (latchOntoAI.WallAttachPos.HasValue)
|
||||
{
|
||||
GUI.DrawLine(spriteBatch, pos,
|
||||
ConvertUnits.ToDisplayUnits(new Vector2(latchOntoAI.WallAttachPos.Value.X, -latchOntoAI.WallAttachPos.Value.Y)), Color.Orange * 0.6f, 0, 3);
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
@@ -67,34 +77,22 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (steeringManager is IndoorsSteeringManager pathSteering)
|
||||
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++)
|
||||
{
|
||||
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.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);
|
||||
|
||||
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.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.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,12 +75,11 @@ namespace Barotrauma
|
||||
|
||||
GUI.SmallFont.DrawString(spriteBatch,
|
||||
currentNode.ID.ToString(),
|
||||
new Vector2(currentNode.DrawPosition.X + 20, -currentNode.DrawPosition.Y - 20),
|
||||
Color.SkyBlue);
|
||||
new Vector2(currentNode.DrawPosition.X, -currentNode.DrawPosition.Y - 10),
|
||||
Color.LightGreen);
|
||||
}
|
||||
}
|
||||
}
|
||||
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))
|
||||
|
||||
@@ -88,13 +88,13 @@ namespace Barotrauma
|
||||
Collider.AngularVelocity = newAngularVelocity;
|
||||
|
||||
float distSqrd = Vector2.DistanceSquared(newPosition, Collider.SimPosition);
|
||||
float errorTolerance = character.AllowInput ? 0.01f : 0.1f;
|
||||
float errorTolerance = character.AllowInput ? 0.01f : 0.2f;
|
||||
if (distSqrd > errorTolerance)
|
||||
{
|
||||
if (distSqrd > 10.0f || !character.AllowInput)
|
||||
{
|
||||
Collider.TargetRotation = newRotation;
|
||||
SetPosition(newPosition, lerp: distSqrd < 1.0f);
|
||||
SetPosition(newPosition, lerp: distSqrd < 5.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -108,8 +108,15 @@ namespace Barotrauma
|
||||
// -> we need to correct it manually
|
||||
if (!character.AllowInput)
|
||||
{
|
||||
MainLimb.PullJointWorldAnchorB = Collider.SimPosition;
|
||||
MainLimb.PullJointEnabled = true;
|
||||
float mainLimbDistSqrd = Vector2.DistanceSquared(MainLimb.PullJointWorldAnchorA, Collider.SimPosition);
|
||||
float mainLimbErrorTolerance = 0.1f;
|
||||
//if the main limb is roughly at the correct position and the collider isn't moving (much at least),
|
||||
//don't attempt to correct the position.
|
||||
if (mainLimbDistSqrd > mainLimbErrorTolerance || Collider.LinearVelocity.LengthSquared() > 0.05f)
|
||||
{
|
||||
MainLimb.PullJointWorldAnchorB = Collider.SimPosition;
|
||||
MainLimb.PullJointEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
character.MemLocalState.Clear();
|
||||
|
||||
@@ -224,20 +224,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (SelectedConstruction != null && SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null && HUD.CloseHUD(ic.GuiFrame.Rect)))
|
||||
{
|
||||
if (GameMain.Client != null)
|
||||
{
|
||||
//emulate a Select input to get the character to deselect the item server-side
|
||||
keys[(int)InputType.Select].Hit = true;
|
||||
}
|
||||
//reset focus to prevent us from accidentally interacting with another entity
|
||||
focusedItem = null;
|
||||
focusedCharacter = null;
|
||||
findFocusedTimer = 0.2f;
|
||||
SelectedConstruction = null;
|
||||
}
|
||||
|
||||
DoInteractionUpdate(deltaTime, mouseSimPos);
|
||||
}
|
||||
|
||||
@@ -341,8 +327,6 @@ namespace Barotrauma
|
||||
debugInteractablesAtCursor.Clear();
|
||||
debugInteractablesNearCursor.Clear();
|
||||
|
||||
bool draggingItemToWorld = CharacterInventory.DraggingItemToWorld;
|
||||
|
||||
//reduce the amount of aim assist if an item has been selected
|
||||
//= can't switch selection to another item without deselecting the current one first UNLESS the cursor is directly on the item
|
||||
//otherwise it would be too easy to accidentally switch the selected item when rewiring items
|
||||
@@ -364,15 +348,6 @@ namespace Barotrauma
|
||||
if (item.body != null && !item.body.Enabled) continue;
|
||||
if (item.ParentInventory != null) continue;
|
||||
if (ignoredItems != null && ignoredItems.Contains(item)) continue;
|
||||
|
||||
if (draggingItemToWorld)
|
||||
{
|
||||
if (item.OwnInventory == null ||
|
||||
!item.OwnInventory.CanBePut(CharacterInventory.draggingItem))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
float distanceToItem = float.PositiveInfinity;
|
||||
if (item.IsInsideTrigger(displayPosition, out Rectangle transformedTrigger))
|
||||
|
||||
@@ -248,7 +248,7 @@ namespace Barotrauma
|
||||
scale: scale);
|
||||
}
|
||||
|
||||
if (!GUI.DisableItemHighlights && !Inventory.DraggingItemToWorld)
|
||||
if (!GUI.DisableItemHighlights)
|
||||
{
|
||||
var hudTexts = focusedItem.GetHUDTexts(character);
|
||||
|
||||
|
||||
@@ -241,12 +241,10 @@ namespace Barotrauma
|
||||
if (!string.IsNullOrEmpty(jobIdentifier))
|
||||
{
|
||||
jobPrefab = JobPrefab.List.Find(jp => jp.Identifier == jobIdentifier);
|
||||
byte skillCount = inc.ReadByte();
|
||||
for (int i = 0; i < skillCount; i++)
|
||||
for (int i = 0; i < jobPrefab.Skills.Count; i++)
|
||||
{
|
||||
string skillIdentifier = inc.ReadString();
|
||||
float skillLevel = inc.ReadSingle();
|
||||
skillLevels.Add(skillIdentifier, skillLevel);
|
||||
skillLevels.Add(jobPrefab.Skills[i].Identifier, skillLevel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,6 +254,7 @@ namespace Barotrauma
|
||||
ID = infoID,
|
||||
};
|
||||
ch.RecreateHead(headSpriteID,(Race)race, (Gender)gender, hairIndex, beardIndex, moustacheIndex, faceAttachmentIndex);
|
||||
System.Diagnostics.Debug.Assert(skillLevels.Count == ch.Job.Skills.Count);
|
||||
if (ch.Job != null)
|
||||
{
|
||||
foreach (KeyValuePair<string, float> skill in skillLevels)
|
||||
@@ -263,12 +262,11 @@ namespace Barotrauma
|
||||
Skill matchingSkill = ch.Job.Skills.Find(s => s.Identifier == skill.Key);
|
||||
if (matchingSkill == null)
|
||||
{
|
||||
ch.Job.Skills.Add(new Skill(skill.Key, skill.Value));
|
||||
DebugConsole.ThrowError("Skill \"" + skill.Key + "\" not found in character \"" + newName + "\"");
|
||||
continue;
|
||||
}
|
||||
matchingSkill.Level = skill.Value;
|
||||
}
|
||||
ch.Job.Skills.RemoveAll(s => !skillLevels.ContainsKey(s.Identifier));
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Lidgren.Network;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
|
||||
@@ -68,14 +68,6 @@ namespace Barotrauma
|
||||
|
||||
private float dropItemAnimDuration = 0.5f;
|
||||
private float dropItemAnimTimer;
|
||||
|
||||
public Item DroppedItem
|
||||
{
|
||||
get
|
||||
{
|
||||
return droppedItem;
|
||||
}
|
||||
}
|
||||
private Item droppedItem;
|
||||
|
||||
private GUIComponent draggingMed;
|
||||
@@ -108,15 +100,13 @@ namespace Barotrauma
|
||||
if (openHealthWindow == value) return;
|
||||
if (value != null && !value.UseHealthWindow) return;
|
||||
|
||||
var prevOpenHealthWindow = openHealthWindow;
|
||||
|
||||
openHealthWindow = value;
|
||||
toggledThisFrame = true;
|
||||
if (Character.Controlled == null) { return; }
|
||||
|
||||
if (value == null &&
|
||||
Character.Controlled?.SelectedCharacter?.CharacterHealth != null &&
|
||||
Character.Controlled.SelectedCharacter.CharacterHealth == prevOpenHealthWindow &&
|
||||
Character.Controlled.SelectedCharacter.CharacterHealth == openHealthWindow &&
|
||||
!Character.Controlled.SelectedCharacter.CanInventoryBeAccessed)
|
||||
{
|
||||
Character.Controlled.DeselectCharacter();
|
||||
@@ -547,13 +537,11 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyHit(InputType.Health) && GUI.KeyboardDispatcher.Subscriber == null &&
|
||||
Character.Controlled.AllowInput && !toggledThisFrame)
|
||||
Character.AllowInput && Character.FocusedCharacter == null && !toggledThisFrame)
|
||||
{
|
||||
if (openHealthWindow != null)
|
||||
{
|
||||
OpenHealthWindow = null;
|
||||
}
|
||||
else if (Character.Controlled == Character && Character.Controlled.FocusedCharacter == null)
|
||||
else
|
||||
{
|
||||
OpenHealthWindow = this;
|
||||
forceAfflictionContainerUpdate = true;
|
||||
@@ -566,10 +554,7 @@ namespace Barotrauma
|
||||
HUD.CloseHUD(HUDLayoutSettings.HealthWindowAreaLeft))
|
||||
{
|
||||
//emulate a Health input to get the character to deselect the item server-side
|
||||
if (GameMain.Client != null)
|
||||
{
|
||||
Character.Controlled.Keys[(int)InputType.Health].Hit = true;
|
||||
}
|
||||
Character.Keys[(int)InputType.Health].Hit = true;
|
||||
OpenHealthWindow = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,11 +403,6 @@ 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);
|
||||
|
||||
@@ -178,15 +178,10 @@ namespace Barotrauma
|
||||
|
||||
string displayedText = message.TranslatedText;
|
||||
string senderName = "";
|
||||
Color senderColor = Color.White;
|
||||
if (!string.IsNullOrWhiteSpace(message.SenderName))
|
||||
{
|
||||
senderName = (message.Type == ChatMessageType.Private ? "[PM] " : "") + message.SenderName;
|
||||
}
|
||||
if (message.Sender?.Info?.Job != null)
|
||||
{
|
||||
senderColor = Color.Lerp(message.Sender.Info.Job.Prefab.UIColor, Color.White, 0.25f);
|
||||
}
|
||||
|
||||
var msgHolder = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.0f), chatBox.Content.RectTransform, Anchor.TopCenter), style: null,
|
||||
color: ((chatBox.Content.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f);
|
||||
@@ -196,7 +191,7 @@ namespace Barotrauma
|
||||
{
|
||||
senderNameBlock = new GUITextBlock(new RectTransform(new Vector2(0.98f, 0.0f), msgHolder.RectTransform)
|
||||
{ AbsoluteOffset = new Point((int)(5 * GUI.Scale), 0) },
|
||||
senderName, textColor: senderColor, font: GUI.SmallFont, textAlignment: Alignment.TopLeft, style: null)
|
||||
senderName, textColor: Color.White, font: GUI.SmallFont, textAlignment: Alignment.TopLeft, style: null)
|
||||
{
|
||||
CanBeFocused = true
|
||||
};
|
||||
@@ -235,7 +230,7 @@ namespace Barotrauma
|
||||
Visible = false
|
||||
};
|
||||
var senderText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), popupMsg.RectTransform, Anchor.TopRight),
|
||||
senderName, textColor: senderColor, font: GUI.SmallFont, textAlignment: Alignment.TopRight)
|
||||
senderName, textColor: Color.White, font: GUI.SmallFont, textAlignment: Alignment.TopRight)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
@@ -333,7 +328,6 @@ namespace Barotrauma
|
||||
var popupMsg = popupMessages.Count > 0 ? popupMessages.Peek() : null;
|
||||
if (popupMsg != null)
|
||||
{
|
||||
int offset = -popupMsg.Rect.Width - toggleButton.Rect.Width * 2 - (int)(50 * GUI.Scale) - (guiFrame.Rect.X - GameMain.GraphicsWidth);
|
||||
popupMsg.Visible = true;
|
||||
//popup messages appear and disappear faster when there's more pending messages
|
||||
popupMessageTimer += deltaTime * popupMessages.Count * popupMessages.Count;
|
||||
@@ -341,7 +335,7 @@ namespace Barotrauma
|
||||
{
|
||||
//move the message out of the screen and delete it
|
||||
popupMsg.RectTransform.ScreenSpaceOffset =
|
||||
new Point((int)MathHelper.SmoothStep(offset, 10, (popupMessageTimer - PopupMessageDuration) * 5.0f), 0);
|
||||
new Point((int)MathHelper.SmoothStep(-popupMsg.Rect.Width - toggleButton.Rect.Width * 2, 10, (popupMessageTimer - PopupMessageDuration) * 5.0f), 0);
|
||||
if (popupMessageTimer > PopupMessageDuration + 1.0f)
|
||||
{
|
||||
popupMessageTimer = 0.0f;
|
||||
@@ -353,7 +347,7 @@ namespace Barotrauma
|
||||
{
|
||||
//move the message on the screen
|
||||
popupMsg.RectTransform.ScreenSpaceOffset = new Point(
|
||||
(int)MathHelper.SmoothStep(0, offset, popupMessageTimer * 5.0f), 0);
|
||||
(int)MathHelper.SmoothStep(0, -popupMsg.Rect.Width - toggleButton.Rect.Width * 2 - (int)(35 * GUI.Scale), popupMessageTimer * 5.0f), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace Barotrauma
|
||||
private static List<GUIMessage> messages = new List<GUIMessage>();
|
||||
private static Sound[] sounds;
|
||||
private static bool pauseMenuOpen, settingsMenuOpen;
|
||||
public static GUIFrame PauseMenu { get; private set; }
|
||||
private static GUIFrame pauseMenu;
|
||||
private static Sprite arrow, lockIcon, checkmarkIcon, timerIcon;
|
||||
|
||||
public static KeyboardDispatcher KeyboardDispatcher { get; set; }
|
||||
@@ -69,9 +69,6 @@ namespace Barotrauma
|
||||
public static ScalableFont Font => Style?.Font;
|
||||
public static ScalableFont SmallFont => Style?.SmallFont;
|
||||
public static ScalableFont LargeFont => Style?.LargeFont;
|
||||
public static ScalableFont VideoTitleFont => Style?.VideoTitleFont;
|
||||
public static ScalableFont ObjectiveTitleFont => Style?.ObjectiveTitleFont;
|
||||
public static ScalableFont ObjectiveNameFont => Style?.ObjectiveNameFont;
|
||||
|
||||
public static UISprite UIGlow => Style.UIGlow;
|
||||
|
||||
@@ -533,19 +530,14 @@ namespace Barotrauma
|
||||
if (list.Count == 0) { return; }
|
||||
foreach (var item in list)
|
||||
{
|
||||
int index = 0;
|
||||
if (updateList.Count > 0)
|
||||
int i = updateList.Count - 1;
|
||||
while (updateList[i].UpdateOrder > item.UpdateOrder)
|
||||
{
|
||||
index = updateList.Count - 1;
|
||||
while (updateList[index].UpdateOrder > item.UpdateOrder)
|
||||
{
|
||||
index--;
|
||||
if (index == 0) { break; }
|
||||
}
|
||||
i--;
|
||||
}
|
||||
if (!updateListSet.Contains(item))
|
||||
{
|
||||
updateList.Insert(index, item);
|
||||
updateList.Insert(Math.Max(i, 0), item);
|
||||
updateListSet.Add(item);
|
||||
}
|
||||
}
|
||||
@@ -561,7 +553,7 @@ namespace Barotrauma
|
||||
|
||||
if (pauseMenuOpen)
|
||||
{
|
||||
PauseMenu.AddToGUIUpdateList();
|
||||
pauseMenu.AddToGUIUpdateList();
|
||||
}
|
||||
if (settingsMenuOpen)
|
||||
{
|
||||
@@ -1420,9 +1412,9 @@ namespace Barotrauma
|
||||
|
||||
if (pauseMenuOpen)
|
||||
{
|
||||
PauseMenu = new GUIFrame(new RectTransform(Vector2.One, Canvas), style: null, color: Color.Black * 0.5f);
|
||||
pauseMenu = new GUIFrame(new RectTransform(Vector2.One, Canvas), style: null, color: Color.Black * 0.5f);
|
||||
|
||||
var pauseMenuInner = new GUIFrame(new RectTransform(new Vector2(0.13f, 0.3f), PauseMenu.RectTransform, Anchor.Center) { MinSize = new Point(200, 300) });
|
||||
var pauseMenuInner = new GUIFrame(new RectTransform(new Vector2(0.13f, 0.3f), pauseMenu.RectTransform, Anchor.Center) { MinSize = new Point(200, 300) });
|
||||
|
||||
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.85f, 0.85f), pauseMenuInner.RectTransform, Anchor.Center))
|
||||
{
|
||||
|
||||
@@ -12,9 +12,6 @@ namespace Barotrauma
|
||||
public ScalableFont Font { get; private set; }
|
||||
public ScalableFont SmallFont { get; private set; }
|
||||
public ScalableFont LargeFont { get; private set; }
|
||||
public ScalableFont VideoTitleFont { get; private set; }
|
||||
public ScalableFont ObjectiveTitleFont { get; private set; }
|
||||
public ScalableFont ObjectiveNameFont { get; private set; }
|
||||
|
||||
public Sprite CursorSprite { get; private set; }
|
||||
|
||||
@@ -51,15 +48,6 @@ namespace Barotrauma
|
||||
case "largefont":
|
||||
LargeFont = new ScalableFont(subElement, graphicsDevice);
|
||||
break;
|
||||
case "objectivetitle":
|
||||
ObjectiveTitleFont = new ScalableFont(subElement, graphicsDevice);
|
||||
break;
|
||||
case "objectivename":
|
||||
ObjectiveNameFont = new ScalableFont(subElement, graphicsDevice);
|
||||
break;
|
||||
case "videotitle":
|
||||
VideoTitleFont = new ScalableFont(subElement, graphicsDevice);
|
||||
break;
|
||||
case "cursor":
|
||||
CursorSprite = new Sprite(subElement);
|
||||
break;
|
||||
|
||||
@@ -50,11 +50,6 @@ namespace Barotrauma
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public static Rectangle ObjectiveAnchor
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public static Rectangle InventoryAreaLower
|
||||
{
|
||||
get; private set;
|
||||
@@ -161,10 +156,6 @@ namespace Barotrauma
|
||||
new Rectangle(Padding, CrewArea.Y, chatBoxWidth, chatBoxHeight) :
|
||||
new Rectangle(GameMain.GraphicsWidth - Padding - chatBoxWidth, CrewArea.Y, chatBoxWidth, chatBoxHeight);
|
||||
|
||||
int objectiveAnchorWidth = (int)(250 * GUI.Scale);
|
||||
int objectiveAnchorOffsetY = (int)(100 * GUI.Scale);
|
||||
ObjectiveAnchor = new Rectangle(GameMain.GraphicsWidth - Padding - objectiveAnchorWidth, CrewArea.Y + crewAreaHeight + objectiveAnchorOffsetY, objectiveAnchorWidth, 0);
|
||||
|
||||
int lowerAreaHeight = (int)Math.Min(GameMain.GraphicsHeight * 0.25f, 280);
|
||||
InventoryAreaLower = new Rectangle(Padding, GameMain.GraphicsHeight - lowerAreaHeight, GameMain.GraphicsWidth - Padding * 2, lowerAreaHeight);
|
||||
|
||||
@@ -200,9 +191,6 @@ namespace Barotrauma
|
||||
{
|
||||
public static bool CloseHUD(Rectangle rect)
|
||||
{
|
||||
// Always close when hitting escape
|
||||
if (PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.Escape)) { return true; }
|
||||
|
||||
//don't close when the cursor is on a UI element
|
||||
if (GUI.MouseOn != null) return false;
|
||||
|
||||
|
||||
@@ -601,10 +601,8 @@ namespace Barotrauma
|
||||
{
|
||||
((GUIMessageBox)GUIMessageBox.VisibleBox).Close();
|
||||
}
|
||||
else if ((Character.Controlled?.SelectedConstruction == null || !Character.Controlled.SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null))
|
||||
&& Inventory.SelectedSlot == null && CharacterHealth.OpenHealthWindow == null)
|
||||
else // Otherwise toggle pausing.
|
||||
{
|
||||
// Otherwise toggle pausing, unless another window/interface is open.
|
||||
GUI.TogglePauseMenu();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,12 +130,7 @@ namespace Barotrauma
|
||||
{
|
||||
OnEnterMessage = (textbox, text) =>
|
||||
{
|
||||
if (Character.Controlled?.Info == null)
|
||||
{
|
||||
textbox.Deselect();
|
||||
textbox.Text = "";
|
||||
return true;
|
||||
}
|
||||
if (Character.Controlled == null) { return true; }
|
||||
|
||||
textbox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Default];
|
||||
|
||||
@@ -981,7 +976,7 @@ namespace Barotrauma
|
||||
foreach (GUIComponent c in prevCharacterListBox.Content.Children)
|
||||
{
|
||||
Character character = c.UserData as Character;
|
||||
if (character == null || character.IsDead || character.Removed) continue;
|
||||
if (character == null) continue;
|
||||
AddCharacter(character);
|
||||
DisplayCharacterOrder(character, character.CurrentOrder);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace Barotrauma
|
||||
|
||||
ContextualTutorial = Tutorial.Tutorials.Find(t => t is ContextualTutorial) as ContextualTutorial;
|
||||
|
||||
if (ContextualTutorial.Selected) // Selected when starting a new game -> initialize
|
||||
if (ContextualTutorial.Selected && !ContextualTutorial.Initialized) // Selected when starting a new game -> initialize
|
||||
{
|
||||
ContextualTutorial.Initialize();
|
||||
}
|
||||
|
||||
+98
-382
@@ -1,10 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Barotrauma.Items.Components;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace Barotrauma.Tutorials
|
||||
{
|
||||
@@ -14,59 +13,38 @@ namespace Barotrauma.Tutorials
|
||||
public static bool ContentRunning = false;
|
||||
public static bool Initialized = false;
|
||||
|
||||
private enum ContentTypes { None = 0, Video = 1, TextOnly = 2 };
|
||||
private enum ContentTypes { None = 0, Video = 1, Text = 2 };
|
||||
|
||||
private TutorialSegment activeSegment;
|
||||
private List<TutorialSegment> segments;
|
||||
|
||||
private VideoPlayer videoPlayer;
|
||||
|
||||
private SpriteSheetPlayer spriteSheetPlayer;
|
||||
private Steering navConsole;
|
||||
private Reactor reactor;
|
||||
private Sonar sonar;
|
||||
private Vector2 subStartingPosition;
|
||||
private List<Character> crew;
|
||||
private Character mechanic;
|
||||
private Character engineer;
|
||||
private Character injuredMember = null;
|
||||
|
||||
private List<Pair<Character, float>> characterTimeOnSonar;
|
||||
private float requiredTimeOnSonar = 5f;
|
||||
|
||||
private bool started = false;
|
||||
private string playableContentPath;
|
||||
|
||||
|
||||
private float tutorialTimer;
|
||||
private float degrading2ActivationCountdown;
|
||||
|
||||
private bool disableTutorialOnDeficiencyFound = true;
|
||||
|
||||
private GUIFrame holderFrame, objectiveFrame;
|
||||
private List<TutorialSegment> activeObjectives = new List<TutorialSegment>();
|
||||
private string objectiveTranslated;
|
||||
|
||||
private float floodTutorialTimer = 0.0f;
|
||||
private const float floodTutorialDelay = 2.0f;
|
||||
private float medicalTutorialTimer = 0.0f;
|
||||
private const float medicalTutorialDelay = 2.0f;
|
||||
|
||||
private Point screenResolution;
|
||||
private float prevUIScale;
|
||||
|
||||
private class TutorialSegment
|
||||
{
|
||||
public string Id;
|
||||
public string Objective;
|
||||
public string Name;
|
||||
public ContentTypes ContentType;
|
||||
public XElement TextContent;
|
||||
public XElement VideoContent;
|
||||
public XElement Content;
|
||||
public bool IsTriggered;
|
||||
public GUIButton ReplayButton;
|
||||
public GUITextBlock LinkedTitle, LinkedText;
|
||||
|
||||
public TutorialSegment(XElement config)
|
||||
{
|
||||
Id = config.GetAttributeString("id", "Missing ID");
|
||||
Objective = TextManager.Get(config.GetAttributeString("objective", string.Empty), true);
|
||||
Name = config.GetAttributeString("name", "Missing Name");
|
||||
Enum.TryParse(config.GetAttributeString("contenttype", "None"), true, out ContentType);
|
||||
IsTriggered = config.GetAttributeBool("istriggered", false);
|
||||
|
||||
@@ -75,11 +53,10 @@ namespace Barotrauma.Tutorials
|
||||
case ContentTypes.None:
|
||||
break;
|
||||
case ContentTypes.Video:
|
||||
VideoContent = config.Element("Video");
|
||||
TextContent = config.Element("Text");
|
||||
Content = config.Element("Video");
|
||||
break;
|
||||
case ContentTypes.TextOnly:
|
||||
TextContent = config.Element("Text");
|
||||
case ContentTypes.Text:
|
||||
Content = config.Element("Text");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -100,17 +77,17 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
for (int i = 0; i < segments.Count; i++)
|
||||
{
|
||||
segments[i].IsTriggered = false;
|
||||
}
|
||||
|
||||
if (Initialized) return;
|
||||
Initialized = true;
|
||||
|
||||
base.Initialize();
|
||||
videoPlayer = new VideoPlayer();
|
||||
spriteSheetPlayer = new SpriteSheetPlayer();
|
||||
characterTimeOnSonar = new List<Pair<Character, float>>();
|
||||
|
||||
for (int i = 0; i < segments.Count; i++)
|
||||
{
|
||||
segments[i].IsTriggered = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadPartiallyComplete(XElement element)
|
||||
@@ -134,6 +111,15 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
}
|
||||
|
||||
private void PreloadVideoContent()
|
||||
{
|
||||
for (int i = 0; i < segments.Count; i++)
|
||||
{
|
||||
if (segments[i].ContentType != ContentTypes.Video || segments[i].IsTriggered) continue;
|
||||
spriteSheetPlayer.PreloadContent(playableContentPath, "tutorial", segments[i].Name, segments[i].Content);
|
||||
}
|
||||
}
|
||||
|
||||
public void SavePartiallyComplete(XElement element)
|
||||
{
|
||||
XElement tutorialElement = new XElement("contextualtutorial");
|
||||
@@ -165,13 +151,13 @@ namespace Barotrauma.Tutorials
|
||||
{
|
||||
if (!Initialized) return;
|
||||
|
||||
PreloadVideoContent();
|
||||
|
||||
base.Start();
|
||||
injuredMember = null;
|
||||
activeObjectives.Clear();
|
||||
objectiveTranslated = TextManager.Get("Objective");
|
||||
CreateObjectiveFrame();
|
||||
|
||||
activeSegment = null;
|
||||
tutorialTimer = floodTutorialTimer = medicalTutorialTimer = 0.0f;
|
||||
tutorialTimer = 0.0f;
|
||||
degrading2ActivationCountdown = -1;
|
||||
subStartingPosition = Vector2.Zero;
|
||||
characterTimeOnSonar.Clear();
|
||||
|
||||
@@ -207,9 +193,6 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
|
||||
crew = GameMain.GameSession.CrewManager.GetCharacters().ToList();
|
||||
mechanic = CrewMemberWithJob("mechanic");
|
||||
engineer = CrewMemberWithJob("engineer");
|
||||
|
||||
Completed = true; // Trigger completed at start to prevent the contextual tutorial from automatically activating on starting new campaigns after this one
|
||||
started = true;
|
||||
}
|
||||
@@ -225,185 +208,71 @@ namespace Barotrauma.Tutorials
|
||||
public void Stop()
|
||||
{
|
||||
started = ContentRunning = Initialized = false;
|
||||
videoPlayer.Remove();
|
||||
videoPlayer = null;
|
||||
spriteSheetPlayer.Remove();
|
||||
spriteSheetPlayer = null;
|
||||
characterTimeOnSonar = null;
|
||||
}
|
||||
|
||||
private void CreateObjectiveFrame()
|
||||
{
|
||||
holderFrame = new GUIFrame(new RectTransform(new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight), GUI.Canvas, Anchor.Center));
|
||||
objectiveFrame = new GUIFrame(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ObjectiveAnchor, holderFrame.RectTransform), style: null);
|
||||
|
||||
for (int i = 0; i < activeObjectives.Count; i++)
|
||||
{
|
||||
CreateObjectiveGUI(activeObjectives[i], i);
|
||||
}
|
||||
|
||||
screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||
prevUIScale = GUI.Scale;
|
||||
}
|
||||
|
||||
public override void AddToGUIUpdateList()
|
||||
{
|
||||
if (videoPlayer != null)
|
||||
{
|
||||
videoPlayer.AddToGUIUpdateList(order: 100);
|
||||
}
|
||||
|
||||
if (GUI.DisableHUD) return;
|
||||
if (GameMain.GraphicsWidth != screenResolution.X || GameMain.GraphicsHeight != screenResolution.Y || prevUIScale != GUI.Scale)
|
||||
{
|
||||
CreateObjectiveFrame();
|
||||
}
|
||||
|
||||
if (objectiveFrame != null && activeObjectives.Count > 0)
|
||||
{
|
||||
objectiveFrame.AddToGUIUpdateList(order: -1);
|
||||
}
|
||||
base.AddToGUIUpdateList();
|
||||
if (spriteSheetPlayer != null)
|
||||
{
|
||||
spriteSheetPlayer.AddToGUIUpdateList();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
if (videoPlayer != null)
|
||||
{
|
||||
videoPlayer.Update();
|
||||
}
|
||||
|
||||
if (infoBox != null)
|
||||
{
|
||||
if (PlayerInput.KeyHit(Keys.Enter) || PlayerInput.KeyHit(Keys.Escape))
|
||||
{
|
||||
CloseInfoFrame(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
if (!started || ContentRunning) return;
|
||||
|
||||
deltaTime *= 0.5f;
|
||||
|
||||
|
||||
for (int i = 0; i < segments.Count; i++)
|
||||
{
|
||||
if (segments[i].IsTriggered || activeObjectives.Contains(segments[i])) continue;
|
||||
if (segments[i].IsTriggered) continue;
|
||||
if (CheckContextualTutorials(i, deltaTime)) // Found a relevant tutorial, halt finding new ones
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < activeObjectives.Count; i++)
|
||||
{
|
||||
CheckActiveObjectives(activeObjectives[i], deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
private void ClosePreTextAndTriggerVideoCallback()
|
||||
{
|
||||
videoPlayer.LoadContent(playableContentPath, new VideoPlayer.VideoSettings(activeSegment.VideoContent), new VideoPlayer.TextSettings(activeSegment.VideoContent), activeSegment.Id, true, activeSegment.Objective, CurrentSegmentStopCallback);
|
||||
}
|
||||
|
||||
private void CurrentSegmentStopCallback()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(activeSegment.Objective))
|
||||
{
|
||||
AddNewObjective(activeSegment);
|
||||
}
|
||||
|
||||
activeSegment = null;
|
||||
ContentRunning = false;
|
||||
}
|
||||
|
||||
private void AddNewObjective(TutorialSegment segment)
|
||||
{
|
||||
activeObjectives.Add(segment);
|
||||
CreateObjectiveGUI(segment, activeObjectives.Count - 1);
|
||||
}
|
||||
|
||||
private void CreateObjectiveGUI(TutorialSegment segment, int index)
|
||||
{
|
||||
Point replayButtonSize = new Point((int)(GUI.ObjectiveNameFont.MeasureString(segment.Objective).X * GUI.Scale), (int)(GUI.ObjectiveNameFont.MeasureString(segment.Objective).Y * 1.45f * GUI.Scale));
|
||||
|
||||
segment.ReplayButton = new GUIButton(new RectTransform(replayButtonSize, objectiveFrame.RectTransform, Anchor.TopRight, Pivot.TopRight) { AbsoluteOffset = new Point(0, (replayButtonSize.Y + (int)(20f * GUI.Scale)) * index) }, style: null);
|
||||
segment.ReplayButton.OnClicked += (GUIButton btn, object userdata) =>
|
||||
{
|
||||
ReplaySegmentVideo(segment);
|
||||
return true;
|
||||
};
|
||||
|
||||
int yOffset = (int)((GUI.ObjectiveNameFont.MeasureString(objectiveTranslated).Y / 2f + 5) * GUI.Scale);
|
||||
segment.LinkedTitle = new GUITextBlock(new RectTransform(new Point(replayButtonSize.X, yOffset), segment.ReplayButton.RectTransform, Anchor.Center, Pivot.BottomCenter) { AbsoluteOffset = new Point((int)(10 * GUI.Scale), 0) }, objectiveTranslated, textColor: Color.White, font: GUI.ObjectiveTitleFont, textAlignment: Alignment.CenterRight);
|
||||
segment.LinkedText = new GUITextBlock(new RectTransform(new Point(replayButtonSize.X, yOffset), segment.ReplayButton.RectTransform, Anchor.Center, Pivot.TopCenter) { AbsoluteOffset = new Point((int)(10 * GUI.Scale), 0) }, segment.Objective, textColor: new Color(4, 180, 108), font: GUI.ObjectiveNameFont, textAlignment: Alignment.CenterRight);
|
||||
|
||||
segment.LinkedTitle.TextScale = segment.LinkedText.TextScale = GUI.Scale;
|
||||
|
||||
segment.LinkedTitle.Color = segment.LinkedTitle.HoverColor = segment.LinkedTitle.PressedColor = segment.LinkedTitle.SelectedColor = Color.Transparent;
|
||||
segment.LinkedText.Color = segment.LinkedText.HoverColor = segment.LinkedText.PressedColor = segment.LinkedText.SelectedColor = Color.Transparent;
|
||||
segment.ReplayButton.Color = segment.ReplayButton.HoverColor = segment.ReplayButton.PressedColor = segment.ReplayButton.SelectedColor = Color.Transparent;
|
||||
}
|
||||
|
||||
private void RemoveCompletedObjective(TutorialSegment objective)
|
||||
{
|
||||
objective.IsTriggered = true;
|
||||
|
||||
int checkMarkHeight = (int)(objective.ReplayButton.Rect.Height * 1.2f);
|
||||
int checkMarkWidth = (int)(checkMarkHeight * 0.93f);
|
||||
|
||||
Color color = new Color(4, 180, 108);
|
||||
RectTransform rectTA = new RectTransform(new Point(checkMarkWidth, checkMarkHeight), objective.ReplayButton.RectTransform, Anchor.BottomLeft, Pivot.BottomLeft);
|
||||
rectTA.AbsoluteOffset = new Point(-rectTA.Rect.Width - 5, 0);
|
||||
GUIImage checkmark = new GUIImage(rectTA, "CheckMark");
|
||||
checkmark.Color = color;
|
||||
|
||||
RectTransform rectTB = new RectTransform(new Vector2(1.1f, .8f), objective.LinkedText.RectTransform, Anchor.Center, Pivot.Center);
|
||||
GUIImage stroke = new GUIImage(rectTB, "Stroke");
|
||||
stroke.Color = color;
|
||||
|
||||
CoroutineManager.StartCoroutine(WaitForObjectiveEnd(objective));
|
||||
}
|
||||
|
||||
private IEnumerable<object> WaitForObjectiveEnd(TutorialSegment objective)
|
||||
{
|
||||
yield return new WaitForSeconds(2.0f);
|
||||
objectiveFrame.RemoveChild(objective.ReplayButton);
|
||||
activeObjectives.Remove(objective);
|
||||
|
||||
for (int i = 0; i < activeObjectives.Count; i++)
|
||||
{
|
||||
activeObjectives[i].ReplayButton.RectTransform.AbsoluteOffset = new Point(0, (activeObjectives[i].ReplayButton.Rect.Height + 20) * i);
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckContextualTutorials(int index, float deltaTime)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: // Welcome: Game Start [Text]
|
||||
if (tutorialTimer < 1.0f)
|
||||
if (tutorialTimer < 0.5f)
|
||||
{
|
||||
tutorialTimer += deltaTime;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 1: // Command Reactor: 2 seconds after 'Welcome' dismissed and only if no command given to start reactor [Video]
|
||||
if (!segments[0].IsTriggered) return false;
|
||||
if (tutorialTimer < 3.0f)
|
||||
case 1: // Command Reactor: 10 seconds after 'Welcome' dismissed and only if no command given to start reactor [Video]
|
||||
if (tutorialTimer < 10.5f)
|
||||
{
|
||||
tutorialTimer += deltaTime;
|
||||
|
||||
if (HasOrder("operatereactor"))
|
||||
{
|
||||
segments[index].IsTriggered = true;
|
||||
tutorialTimer = 2.5f;
|
||||
tutorialTimer = 10.5f;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 2: // Nav Console: 2 seconds after 'Command Reactor' dismissed or if nav console is activated [Video]
|
||||
if (!IsReactorPoweredUp()) return false; // Do not advance tutorial based on this segment if reactor has not been powered up
|
||||
case 2: // Nav Console: 20 seconds after 'Command Reactor' dismissed or if nav console is activated [Video]
|
||||
if (Character.Controlled?.SelectedConstruction != navConsole.Item)
|
||||
{
|
||||
if (tutorialTimer < 4.5f)
|
||||
{
|
||||
if (!segments[1].IsTriggered) return false; // Do not advance tutorial timer based on this segment if reactor has not been powered up
|
||||
if (tutorialTimer < 30.5f)
|
||||
{
|
||||
tutorialTimer += deltaTime;
|
||||
return false;
|
||||
@@ -411,13 +280,20 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
else
|
||||
{
|
||||
tutorialTimer = 4.5f;
|
||||
}
|
||||
if (!segments[1].IsTriggered || !HasOrder("operatereactor")) // If reactor has not been powered up or ordered to be, default to that one first
|
||||
{
|
||||
if (tutorialTimer < 10.5f)
|
||||
{
|
||||
tutorialTimer = 10.5f;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
TriggerTutorialSegment(index, GameMain.GameSession.EndLocation.Name);
|
||||
return true;
|
||||
tutorialTimer = 30.5f;
|
||||
}
|
||||
break;
|
||||
case 3: // Objective: Travel ~150 meters and while sub is not flooding [Text]
|
||||
if (Vector2.Distance(subStartingPosition, Submarine.MainSub.WorldPosition) < 8000f || IsFlooding())
|
||||
if (Vector2.Distance(subStartingPosition, Submarine.MainSub.WorldPosition) < 12000f || IsFlooding())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -431,11 +307,6 @@ namespace Barotrauma.Tutorials
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (floodTutorialTimer < floodTutorialDelay)
|
||||
{
|
||||
floodTutorialTimer += deltaTime;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 5: // Reactor: Player uses reactor for the first time [Video]
|
||||
if (Character.Controlled?.SelectedConstruction != reactor.Item)
|
||||
@@ -450,23 +321,19 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
break;
|
||||
case 7: // Degrading1: Any equipment degrades to 50% health or less and player has not assigned any crew to perform maintenance [Text]
|
||||
if ((mechanic == null || mechanic.IsDead) && (engineer == null || engineer.IsDead)) // Both engineer and mechanic are dead or do not exist -> do not display
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool degradedEquipmentFound = false;
|
||||
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
if (!item.Repairables.Any() || item.Condition > 50.0f) continue;
|
||||
if (!item.Repairables.Any() || item.ConditionPercentage > 50) continue;
|
||||
degradedEquipmentFound = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (degradedEquipmentFound)
|
||||
{
|
||||
if (HasOrder("repairsystems", "jobspecific"))
|
||||
degrading2ActivationCountdown = 5f;
|
||||
if (HasOrder("repairsystems"))
|
||||
{
|
||||
segments[index].IsTriggered = true;
|
||||
return false;
|
||||
@@ -477,44 +344,43 @@ namespace Barotrauma.Tutorials
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 8: // Medical: Crewmember is injured but not killed [Video]
|
||||
|
||||
if (injuredMember == null)
|
||||
case 8: // Degrading2: 5 seconds after 'Degrading1' dismissed, and only if player has not assigned any crew to perform maintenance [Video]
|
||||
if (degrading2ActivationCountdown == -1f)
|
||||
{
|
||||
for (int i = 0; i < crew.Count; i++)
|
||||
return false;
|
||||
}
|
||||
else if (degrading2ActivationCountdown > 0.0f)
|
||||
{
|
||||
degrading2ActivationCountdown -= deltaTime;
|
||||
if (HasOrder("repairsystems"))
|
||||
{
|
||||
Character member = crew[i];
|
||||
if (member.Vitality < member.MaxVitality && !member.IsDead)
|
||||
{
|
||||
injuredMember = member;
|
||||
break;
|
||||
}
|
||||
segments[index].IsTriggered = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else if (medicalTutorialTimer < medicalTutorialDelay)
|
||||
break;
|
||||
case 9: // Medical: Crewmember is injured but not killed [Video]
|
||||
bool injuredFound = false;
|
||||
for (int i = 0; i < crew.Count; i++)
|
||||
{
|
||||
medicalTutorialTimer += deltaTime;
|
||||
return false;
|
||||
Character member = crew[i];
|
||||
if (member.Vitality < member.MaxVitality && !member.IsDead)
|
||||
{
|
||||
injuredFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TriggerTutorialSegment(index, new string[] { injuredMember.Info.DisplayName,
|
||||
(injuredMember.Info.Gender == Gender.Male) ? TextManager.Get("PronounPossessiveMale").ToLower() : TextManager.Get("PronounPossessiveFemale").ToLower() });
|
||||
return true;
|
||||
}
|
||||
case 9: // Approach1: Destination is within ~100m [Video]
|
||||
|
||||
if (!injuredFound) return false;
|
||||
break;
|
||||
case 10: // Approach1: Destination is within ~100m [Video]
|
||||
if (Vector2.Distance(Submarine.MainSub.WorldPosition, Level.Loaded.EndPosition) > 8000f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
TriggerTutorialSegment(index, GameMain.GameSession.EndLocation.Name);
|
||||
return true;
|
||||
}
|
||||
case 10: // Approach2: Sub is docked [Text]
|
||||
break;
|
||||
case 11: // Approach2: Sub is docked [Text]
|
||||
if (!Submarine.MainSub.AtEndPosition || Submarine.MainSub.DockedTo.Count == 0)
|
||||
{
|
||||
return false;
|
||||
@@ -526,128 +392,11 @@ namespace Barotrauma.Tutorials
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool HasObjective(string objectiveName)
|
||||
{
|
||||
for (int i = 0; i < activeObjectives.Count; i++)
|
||||
{
|
||||
if (activeObjectives[i].Id == objectiveName) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void CheckActiveObjectives(TutorialSegment objective, float deltaTime)
|
||||
{
|
||||
switch(objective.Id)
|
||||
{
|
||||
case "ReactorCommand": // Reactor commanded
|
||||
if (!IsReactorPoweredUp())
|
||||
{
|
||||
if (!HasOrder("operatereactor")) return;
|
||||
}
|
||||
break;
|
||||
case "NavConsole": // traveled 50 meters
|
||||
if (Vector2.Distance(subStartingPosition, Submarine.MainSub.WorldPosition) < 4000f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "Flood": // Hull breaches repaired
|
||||
if (IsFlooding()) return;
|
||||
break;
|
||||
case "Medical":
|
||||
if (injuredMember != null && !injuredMember.IsDead)
|
||||
{
|
||||
if (injuredMember.CharacterHealth.DroppedItem == null) return;
|
||||
}
|
||||
break;
|
||||
case "EnemyOnSonar": // Enemy dispatched
|
||||
if (HasEnemyOnSonarForDuration(deltaTime))
|
||||
{
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "Degrading": // Fixed
|
||||
if (mechanic != null && !mechanic.IsDead)
|
||||
{
|
||||
HumanAIController humanAI = mechanic.AIController as HumanAIController;
|
||||
if (mechanic.CurrentOrder?.AITag != "repairsystems" || humanAI.CurrentOrderOption != "jobspecific")
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (engineer != null && !engineer.IsDead)
|
||||
{
|
||||
HumanAIController humanAI = engineer.AIController as HumanAIController;
|
||||
if (engineer.CurrentOrder?.AITag != "repairsystems" || humanAI.CurrentOrderOption != "jobspecific")
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case "Approach1": // Wait until docked
|
||||
if (!Submarine.MainSub.AtEndPosition || Submarine.MainSub.DockedTo.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
RemoveCompletedObjective(objective);
|
||||
}
|
||||
|
||||
private bool IsReactorPoweredUp()
|
||||
{
|
||||
float load = 0.0f;
|
||||
List<Connection> connections = reactor.Item.Connections;
|
||||
if (connections != null && connections.Count > 0)
|
||||
{
|
||||
foreach (Connection connection in connections)
|
||||
{
|
||||
if (!connection.IsPower) continue;
|
||||
foreach (Connection recipient in connection.Recipients)
|
||||
{
|
||||
if (!(recipient.Item is Item it)) continue;
|
||||
|
||||
PowerTransfer pt = it.GetComponent<PowerTransfer>();
|
||||
if (pt == null) continue;
|
||||
|
||||
load = Math.Max(load, pt.PowerLoad);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Math.Abs(load + reactor.CurrPowerConsumption) < 10;
|
||||
}
|
||||
|
||||
private Character CrewMemberWithJob(string job)
|
||||
private bool HasOrder(string aiTag)
|
||||
{
|
||||
for (int i = 0; i < crew.Count; i++)
|
||||
{
|
||||
if (crew[i].Info.Job.Name == job) return crew[i];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool HasOrder(string aiTag, string option = null)
|
||||
{
|
||||
for (int i = 0; i < crew.Count; i++)
|
||||
{
|
||||
if (crew[i].CurrentOrder?.AITag == aiTag)
|
||||
{
|
||||
if (option == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
HumanAIController humanAI = crew[i].AIController as HumanAIController;
|
||||
return humanAI.CurrentOrderOption == option;
|
||||
}
|
||||
}
|
||||
if (crew[i].CurrentOrder?.AITag == aiTag) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -657,12 +406,10 @@ namespace Barotrauma.Tutorials
|
||||
{
|
||||
foreach (Gap gap in Gap.GapList)
|
||||
{
|
||||
if (gap.ConnectedWall == null || gap.IsRoomToRoom) continue;
|
||||
if (gap.ConnectedWall == null) continue;
|
||||
if (gap.ConnectedDoor != null || gap.Open <= 0.0f) continue;
|
||||
if (gap.Submarine == null) continue;
|
||||
if (gap.Submarine.IsOutpost) continue;
|
||||
if (gap.Submarine != Submarine.MainSub) continue;
|
||||
if (gap.FlowTargetHull == null || gap.FlowTargetHull.WaterPercentage <= 0.0f) continue;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -700,51 +447,27 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
}
|
||||
|
||||
return characterTimeOnSonar.Find(ct => ct.Second >= requiredTimeOnSonar && !ct.First.IsDead) != null;
|
||||
return characterTimeOnSonar.Find(ct => ct.Second >= requiredTimeOnSonar) != null;
|
||||
}
|
||||
|
||||
private void TriggerTutorialSegment(int index, params object[] args)
|
||||
{
|
||||
Inventory.draggingItem = null;
|
||||
ContentRunning = true;
|
||||
activeSegment = segments[index];
|
||||
|
||||
string tutorialText = TextManager.GetFormatted(activeSegment.TextContent.GetAttributeString("tag", ""), true, args);
|
||||
string objectiveText = string.Empty;
|
||||
|
||||
if (!string.IsNullOrEmpty(activeSegment.Objective))
|
||||
{
|
||||
if (args.Length == 0)
|
||||
{
|
||||
objectiveText = activeSegment.Objective;
|
||||
}
|
||||
else
|
||||
{
|
||||
objectiveText = string.Format(activeSegment.Objective, args);
|
||||
}
|
||||
|
||||
activeSegment.Objective = objectiveText;
|
||||
}
|
||||
else
|
||||
{
|
||||
activeSegment.IsTriggered = true; // Complete at this stage only if no related objective
|
||||
}
|
||||
activeSegment.IsTriggered = true;
|
||||
|
||||
switch (activeSegment.ContentType)
|
||||
{
|
||||
case ContentTypes.None:
|
||||
break;
|
||||
case ContentTypes.Video:
|
||||
infoBox = CreateInfoFrame(TextManager.Get(activeSegment.Id), tutorialText,
|
||||
activeSegment.TextContent.GetAttributeInt("width", 300),
|
||||
activeSegment.TextContent.GetAttributeInt("height", 80),
|
||||
activeSegment.TextContent.GetAttributeString("anchor", "Center"), true, ClosePreTextAndTriggerVideoCallback);
|
||||
spriteSheetPlayer.LoadContent(playableContentPath, activeSegment.Content, activeSegment.Name, true, true, CurrentSegmentStopCallback);
|
||||
break;
|
||||
case ContentTypes.TextOnly:
|
||||
infoBox = CreateInfoFrame(TextManager.Get(activeSegment.Id), tutorialText,
|
||||
activeSegment.TextContent.GetAttributeInt("width", 300),
|
||||
activeSegment.TextContent.GetAttributeInt("height", 80),
|
||||
activeSegment.TextContent.GetAttributeString("anchor", "Center"), true, CurrentSegmentStopCallback);
|
||||
case ContentTypes.Text:
|
||||
infoBox = CreateInfoFrame(TextManager.Get(activeSegment.Name), TextManager.GetFormatted(activeSegment.Content.GetAttributeString("tag", ""), false, args),
|
||||
activeSegment.Content.GetAttributeInt("width", 300),
|
||||
activeSegment.Content.GetAttributeInt("height", 80),
|
||||
activeSegment.Content.GetAttributeString("anchor", "Center"), true, CurrentSegmentStopCallback);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -756,13 +479,6 @@ namespace Barotrauma.Tutorials
|
||||
CoroutineManager.StartCoroutine(WaitToStop()); // Completed
|
||||
}
|
||||
|
||||
private void ReplaySegmentVideo(TutorialSegment segment)
|
||||
{
|
||||
if (ContentRunning) return;
|
||||
ContentRunning = true;
|
||||
videoPlayer.LoadContent(playableContentPath, new VideoPlayer.VideoSettings(segment.VideoContent), new VideoPlayer.TextSettings(segment.VideoContent), segment.Id, true, callback: () => ContentRunning = false);
|
||||
}
|
||||
|
||||
private IEnumerable<object> WaitToStop()
|
||||
{
|
||||
while (ContentRunning) yield return null;
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
public virtual void AddToGUIUpdateList()
|
||||
{
|
||||
if (infoBox != null) infoBox.AddToGUIUpdateList(order: 100);
|
||||
if (infoBox != null) infoBox.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
public virtual void Update(float deltaTime)
|
||||
@@ -188,19 +188,17 @@ namespace Barotrauma.Tutorials
|
||||
Anchor anchor = Anchor.TopRight;
|
||||
Enum.TryParse(anchorStr, out anchor);
|
||||
|
||||
var infoBlock = new GUIFrame(new RectTransform(new Point((int)(width * GUI.Scale), (int)(height * GUI.Scale)), GUI.Canvas, anchor) { AbsoluteOffset = new Point(20) });
|
||||
var infoBlock = new GUIFrame(new RectTransform(new Point(width, height), GUI.Canvas, anchor) { AbsoluteOffset = new Point(20) });
|
||||
infoBlock.Flash(Color.Green);
|
||||
|
||||
if (title.Length > 0)
|
||||
{
|
||||
var titleBlock = new GUITextBlock(new RectTransform(new Vector2(1f, .35f), infoBlock.RectTransform, Anchor.TopCenter,
|
||||
Pivot.TopCenter), title, font: GUI.VideoTitleFont, textAlignment: Alignment.Center, textColor: new Color(253, 174, 0));
|
||||
titleBlock.TextScale = GUI.Scale;
|
||||
Pivot.TopCenter), title, font: GUI.LargeFont, textAlignment: Alignment.Center);
|
||||
}
|
||||
|
||||
var textBlock = new GUITextBlock(new RectTransform(new Vector2(0.9f, 1f), infoBlock.RectTransform, Anchor.BottomCenter),
|
||||
text, wrap: true);
|
||||
textBlock.TextScale = GUI.Scale;
|
||||
|
||||
infoBoxClosedCallback = callback;
|
||||
|
||||
|
||||
@@ -14,13 +14,12 @@ namespace Barotrauma
|
||||
{
|
||||
private enum Tab
|
||||
{
|
||||
General,
|
||||
Graphics,
|
||||
Audio,
|
||||
Controls,
|
||||
}
|
||||
|
||||
private readonly Point MinSupportedResolution = new Point(1024, 540);
|
||||
|
||||
private GUIFrame settingsFrame;
|
||||
private GUIButton applyButton;
|
||||
|
||||
@@ -72,79 +71,16 @@ namespace Barotrauma
|
||||
|
||||
private void CreateSettingsFrame()
|
||||
{
|
||||
settingsFrame = new GUIFrame(new RectTransform(new Vector2(0.8f, 0.8f), GUI.Canvas, Anchor.Center));
|
||||
settingsFrame = new GUIFrame(new RectTransform(new Point(500, 500), GUI.Canvas, Anchor.Center));
|
||||
|
||||
var settingsFramePadding = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.9f), settingsFrame.RectTransform, Anchor.TopCenter) { RelativeOffset = new Vector2(0.0f, 0.05f) }, style: null);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), settingsFrame.RectTransform),
|
||||
TextManager.Get("Settings"), textAlignment: Alignment.Center, font: GUI.LargeFont);
|
||||
|
||||
/// General tab --------------------------------------------------------------
|
||||
|
||||
var leftPanel = new GUILayoutGroup(new RectTransform(new Vector2(0.25f, 1.0f), settingsFramePadding.RectTransform, Anchor.TopLeft));
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), leftPanel.RectTransform),
|
||||
TextManager.Get("Settings"), textAlignment: Alignment.TopLeft, font: GUI.LargeFont);
|
||||
|
||||
var generalLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), leftPanel.RectTransform, Anchor.TopLeft));
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), generalLayoutGroup.RectTransform), TextManager.Get("ContentPackages"));
|
||||
var contentPackageList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.75f), generalLayoutGroup.RectTransform))
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
foreach (ContentPackage contentPackage in ContentPackage.List)
|
||||
{
|
||||
var tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.067f), contentPackageList.Content.RectTransform, minSize: new Point(0, 15)), contentPackage.Name)
|
||||
{
|
||||
UserData = contentPackage,
|
||||
OnSelected = SelectContentPackage,
|
||||
Selected = SelectedContentPackages.Contains(contentPackage)
|
||||
};
|
||||
if (!contentPackage.IsCompatible())
|
||||
{
|
||||
tickBox.TextColor = Color.Red;
|
||||
tickBox.Enabled = false;
|
||||
tickBox.ToolTip = TextManager.Get(contentPackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage")
|
||||
.Replace("[packagename]", contentPackage.Name)
|
||||
.Replace("[packageversion]", contentPackage.GameVersion.ToString())
|
||||
.Replace("[gameversion]", GameMain.Version.ToString());
|
||||
}
|
||||
else if (contentPackage.CorePackage && !contentPackage.ContainsRequiredCorePackageFiles(out List<ContentType> missingContentTypes))
|
||||
{
|
||||
tickBox.TextColor = Color.Red;
|
||||
tickBox.Enabled = false;
|
||||
tickBox.ToolTip = TextManager.Get("ContentPackageMissingCoreFiles")
|
||||
.Replace("[packagename]", contentPackage.Name)
|
||||
.Replace("[missingfiletypes]", string.Join(", ", missingContentTypes));
|
||||
}
|
||||
}
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.92f, 0.05f), generalLayoutGroup.RectTransform), TextManager.Get("Language"));
|
||||
var languageDD = new GUIDropDown(new RectTransform(new Vector2(0.92f, 0.05f), generalLayoutGroup.RectTransform));
|
||||
foreach (string language in TextManager.AvailableLanguages)
|
||||
{
|
||||
languageDD.AddItem(TextManager.Get("Language." + language), language);
|
||||
}
|
||||
languageDD.SelectItem(TextManager.Language);
|
||||
languageDD.OnSelected = (guiComponent, obj) =>
|
||||
{
|
||||
string newLanguage = obj as string;
|
||||
if (newLanguage == Language) return true;
|
||||
|
||||
UnsavedSettings = true;
|
||||
Language = newLanguage;
|
||||
|
||||
new GUIMessageBox(TextManager.Get("RestartRequiredLabel"), TextManager.Get("RestartRequiredLanguage"));
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
var rightPanel = new GUILayoutGroup(new RectTransform(new Vector2(1.0f - leftPanel.RectTransform.RelativeSize.X, 0.95f),
|
||||
settingsFramePadding.RectTransform, Anchor.TopRight));
|
||||
|
||||
var tabButtonHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), rightPanel.RectTransform, Anchor.TopCenter), isHorizontal: true);
|
||||
|
||||
var paddedFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), rightPanel.RectTransform, Anchor.Center), style: null);
|
||||
var paddedFrame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.8f), settingsFrame.RectTransform, Anchor.Center)
|
||||
{ RelativeOffset = new Vector2(0.0f, 0.06f) }, style: null);
|
||||
|
||||
var tabButtonHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.05f), settingsFrame.RectTransform, Anchor.TopCenter)
|
||||
{ RelativeOffset = new Vector2(0.0f, 0.11f) }, isHorizontal: true);
|
||||
|
||||
tabs = new GUIFrame[Enum.GetValues(typeof(Tab)).Length];
|
||||
tabButtons = new GUIButton[tabs.Length];
|
||||
@@ -168,10 +104,10 @@ namespace Barotrauma
|
||||
|
||||
var leftColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.46f, 0.95f), tabs[(int)Tab.Graphics].RectTransform, Anchor.CenterLeft)
|
||||
{ RelativeOffset = new Vector2(0.02f, 0.0f) })
|
||||
{ RelativeSpacing = 0.01f };
|
||||
{ RelativeSpacing = 0.01f, Stretch = true };
|
||||
var rightColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.46f, 0.95f), tabs[(int)Tab.Graphics].RectTransform, Anchor.CenterRight)
|
||||
{ RelativeOffset = new Vector2(0.02f, 0.0f) })
|
||||
{ RelativeSpacing = 0.01f };
|
||||
{ RelativeSpacing = 0.01f, Stretch = true };
|
||||
|
||||
var supportedDisplayModes = new List<DisplayMode>();
|
||||
foreach (DisplayMode mode in GraphicsAdapter.DefaultAdapter.SupportedDisplayModes)
|
||||
@@ -199,7 +135,6 @@ namespace Barotrauma
|
||||
|
||||
foreach (DisplayMode mode in supportedDisplayModes)
|
||||
{
|
||||
if (mode.Width < MinSupportedResolution.X || mode.Height < MinSupportedResolution.Y) { continue; }
|
||||
resolutionDD.AddItem(mode.Width + "x" + mode.Height, mode);
|
||||
if (GraphicsWidth == mode.Width && GraphicsHeight == mode.Height) resolutionDD.SelectItem(mode);
|
||||
}
|
||||
@@ -238,6 +173,9 @@ namespace Barotrauma
|
||||
return true;
|
||||
};
|
||||
|
||||
//spacing
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform), style: null);
|
||||
|
||||
GUITickBox vsyncTickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), TextManager.Get("EnableVSync"))
|
||||
{
|
||||
ToolTip = TextManager.Get("EnableVSyncToolTip"),
|
||||
@@ -253,6 +191,8 @@ namespace Barotrauma
|
||||
Selected = VSyncEnabled
|
||||
};
|
||||
|
||||
//spacing
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.5f), leftColumn.RectTransform), style: null);
|
||||
GUITextBlock particleLimitText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("ParticleLimit"));
|
||||
GUIScrollBar particleScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform),
|
||||
barSize: 0.1f)
|
||||
@@ -269,6 +209,8 @@ namespace Barotrauma
|
||||
};
|
||||
particleScrollBar.OnMoved(particleScrollBar, particleScrollBar.BarScroll);
|
||||
|
||||
//spacing
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), rightColumn.RectTransform), style: null);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("LosEffect"));
|
||||
var losModeDD = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform));
|
||||
losModeDD.AddItem(TextManager.Get("LosModeNone"), LosMode.None);
|
||||
@@ -287,6 +229,8 @@ namespace Barotrauma
|
||||
return true;
|
||||
};
|
||||
|
||||
//spacing
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), style: null);
|
||||
GUITextBlock LightText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("LightMapScale"))
|
||||
{
|
||||
ToolTip = TextManager.Get("LightMapScaleToolTip")
|
||||
@@ -307,6 +251,8 @@ namespace Barotrauma
|
||||
};
|
||||
lightScrollBar.OnMoved(lightScrollBar, lightScrollBar.BarScroll);
|
||||
|
||||
//spacing
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), style: null);
|
||||
new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("SpecularLighting"))
|
||||
{
|
||||
ToolTip = TextManager.Get("SpecularLightingToolTip"),
|
||||
@@ -319,6 +265,8 @@ namespace Barotrauma
|
||||
}
|
||||
};
|
||||
|
||||
//spacing
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), rightColumn.RectTransform), style: null);
|
||||
new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("ChromaticAberration"))
|
||||
{
|
||||
ToolTip = TextManager.Get("ChromaticAberrationToolTip"),
|
||||
@@ -331,6 +279,9 @@ namespace Barotrauma
|
||||
}
|
||||
};
|
||||
|
||||
//spacing
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), style: null);
|
||||
|
||||
GUITextBlock HUDScaleText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("HUDScale"));
|
||||
GUIScrollBar HUDScaleScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform),
|
||||
barSize: 0.1f)
|
||||
@@ -349,6 +300,9 @@ namespace Barotrauma
|
||||
};
|
||||
HUDScaleScrollBar.OnMoved(HUDScaleScrollBar, HUDScaleScrollBar.BarScroll);
|
||||
|
||||
//spacing
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), rightColumn.RectTransform), style: null);
|
||||
|
||||
GUITextBlock inventoryScaleText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("InventoryScale"));
|
||||
GUIScrollBar inventoryScaleScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), barSize: 0.1f)
|
||||
{
|
||||
@@ -365,6 +319,9 @@ namespace Barotrauma
|
||||
};
|
||||
inventoryScaleScrollBar.OnMoved(inventoryScaleScrollBar, inventoryScaleScrollBar.BarScroll);
|
||||
|
||||
//spacing
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.2f), rightColumn.RectTransform), style: null);
|
||||
|
||||
/// Audio tab ----------------------------------------------------------------
|
||||
|
||||
var audioSliders = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.4f), tabs[(int)Tab.Audio].RectTransform, Anchor.TopCenter)
|
||||
@@ -610,10 +567,9 @@ namespace Barotrauma
|
||||
var inputNames = Enum.GetValues(typeof(InputType));
|
||||
for (int i = 0; i < inputNames.Length; i++)
|
||||
{
|
||||
var inputContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.06f), inputFrame.RectTransform)) { Stretch = true, IsHorizontal = true, RelativeSpacing = 0.05f };
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.3f, 1.0f), inputContainer.RectTransform, Anchor.TopLeft) { MinSize = new Point(150, 0) },
|
||||
TextManager.Get("InputType." + ((InputType)i)) + ": ", font: GUI.SmallFont) { ForceUpperCase = true };
|
||||
var keyBox = new GUITextBox(new RectTransform(new Vector2(0.7f, 1.0f), inputContainer.RectTransform),
|
||||
var inputContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.06f), inputFrame.RectTransform), style: null);
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), inputContainer.RectTransform), TextManager.Get("InputType." + ((InputType)i)) + ": ", font: GUI.SmallFont);
|
||||
var keyBox = new GUITextBox(new RectTransform(new Vector2(0.4f, 1.0f), inputContainer.RectTransform, Anchor.TopRight),
|
||||
text: keyMapping[i].ToString(), font: GUI.SmallFont)
|
||||
{
|
||||
UserData = i
|
||||
@@ -637,11 +593,88 @@ namespace Barotrauma
|
||||
};
|
||||
aimAssistSlider.OnMoved(aimAssistSlider, aimAssistSlider.BarScroll);
|
||||
|
||||
/// General tab --------------------------------------------------------------
|
||||
|
||||
var generalLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), tabs[(int)Tab.General].RectTransform, Anchor.Center)
|
||||
{ RelativeOffset = new Vector2(0.0f, 0.0f) }) { RelativeSpacing = 0.01f, Stretch = true };
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), generalLayoutGroup.RectTransform), TextManager.Get("ContentPackages"));
|
||||
var contentPackageList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.4f), generalLayoutGroup.RectTransform))
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
|
||||
foreach (ContentPackage contentPackage in ContentPackage.List)
|
||||
{
|
||||
var tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.1f), contentPackageList.Content.RectTransform, minSize: new Point(0, 15)), contentPackage.Name)
|
||||
{
|
||||
UserData = contentPackage,
|
||||
OnSelected = SelectContentPackage,
|
||||
Selected = SelectedContentPackages.Contains(contentPackage)
|
||||
};
|
||||
if (!contentPackage.IsCompatible())
|
||||
{
|
||||
tickBox.TextColor = Color.Red;
|
||||
tickBox.Enabled = false;
|
||||
tickBox.ToolTip = TextManager.Get(contentPackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage")
|
||||
.Replace("[packagename]", contentPackage.Name)
|
||||
.Replace("[packageversion]", contentPackage.GameVersion.ToString())
|
||||
.Replace("[gameversion]", GameMain.Version.ToString());
|
||||
}
|
||||
else if (contentPackage.CorePackage && !contentPackage.ContainsRequiredCorePackageFiles(out List<ContentType> missingContentTypes))
|
||||
{
|
||||
tickBox.TextColor = Color.Red;
|
||||
tickBox.Enabled = false;
|
||||
tickBox.ToolTip = TextManager.Get("ContentPackageMissingCoreFiles")
|
||||
.Replace("[packagename]", contentPackage.Name)
|
||||
.Replace("[missingfiletypes]", string.Join(", ", missingContentTypes));
|
||||
}
|
||||
}
|
||||
GUITextBlock aimAssistText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), controlsLayoutGroup.RectTransform), TextManager.Get("AimAssist"));
|
||||
GUIScrollBar aimAssistSlider = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), controlsLayoutGroup.RectTransform),
|
||||
barSize: 0.1f)
|
||||
{
|
||||
UserData = aimAssistText,
|
||||
BarScroll = MathUtils.InverseLerp(0.0f, 5.0f, AimAssistAmount),
|
||||
OnMoved = (scrollBar, scroll) =>
|
||||
{
|
||||
ChangeSliderText(scrollBar, scroll);
|
||||
AimAssistAmount = MathHelper.Lerp(0.0f, 5.0f, scroll);
|
||||
return true;
|
||||
},
|
||||
Step = 0.1f
|
||||
};
|
||||
aimAssistSlider.OnMoved(aimAssistSlider, aimAssistSlider.BarScroll);
|
||||
|
||||
//spacing
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), generalLayoutGroup.RectTransform), style: null);
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), generalLayoutGroup.RectTransform), TextManager.Get("Language"));
|
||||
var languageDD = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.05f), generalLayoutGroup.RectTransform));
|
||||
foreach (string language in TextManager.AvailableLanguages)
|
||||
{
|
||||
languageDD.AddItem(TextManager.Get("Language." + language), language);
|
||||
}
|
||||
languageDD.SelectItem(TextManager.Language);
|
||||
languageDD.OnSelected = (guiComponent, obj) =>
|
||||
{
|
||||
string newLanguage = obj as string;
|
||||
if (newLanguage == Language) return true;
|
||||
|
||||
UnsavedSettings = true;
|
||||
Language = newLanguage;
|
||||
|
||||
new GUIMessageBox(TextManager.Get("RestartRequiredLabel"), TextManager.Get("RestartRequiredLanguage"));
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
//spacing
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), generalLayoutGroup.RectTransform), style: null);
|
||||
|
||||
new GUIButton(new RectTransform(new Vector2(0.4f, 1.0f), buttonArea.RectTransform, Anchor.BottomLeft),
|
||||
TextManager.Get("Cancel"), style: "GUIButtonLarge")
|
||||
TextManager.Get("Cancel"))
|
||||
{
|
||||
IgnoreLayoutGroups = true,
|
||||
OnClicked = (x, y) =>
|
||||
@@ -657,7 +690,7 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
applyButton = new GUIButton(new RectTransform(new Vector2(0.4f, 1.0f), buttonArea.RectTransform, Anchor.BottomRight),
|
||||
TextManager.Get("ApplySettingsButton"), style: "GUIButtonLarge")
|
||||
TextManager.Get("ApplySettingsButton"))
|
||||
{
|
||||
IgnoreLayoutGroups = true,
|
||||
Enabled = false
|
||||
@@ -665,7 +698,7 @@ namespace Barotrauma
|
||||
applyButton.OnClicked = ApplyClicked;
|
||||
|
||||
UnsavedSettings = false; // Reset unsaved settings to false once the UI has been created
|
||||
SelectTab(Tab.Graphics);
|
||||
SelectTab(Tab.General);
|
||||
}
|
||||
|
||||
private void SelectTab(Tab tab)
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing)
|
||||
{
|
||||
Color color = item.SpriteColor;
|
||||
Color color = Color.White;
|
||||
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, item.SpriteColor * (stuck / 100.0f), scale: item.Scale);
|
||||
weldSpritePos, Color.White * (stuck / 100.0f), scale: item.Scale);
|
||||
}
|
||||
|
||||
if (openState == 1.0f)
|
||||
|
||||
@@ -175,6 +175,63 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyTo(RectTransform target)
|
||||
{
|
||||
if (RelativeOffset.HasValue)
|
||||
{
|
||||
target.RelativeOffset = RelativeOffset.Value;
|
||||
}
|
||||
else if (AbsoluteOffset.HasValue)
|
||||
{
|
||||
target.AbsoluteOffset = AbsoluteOffset.Value;
|
||||
}
|
||||
if (RelativeSize.HasValue)
|
||||
{
|
||||
target.RelativeSize = RelativeSize.Value;
|
||||
}
|
||||
else if (AbsoluteSize.HasValue)
|
||||
{
|
||||
target.NonScaledSize = AbsoluteSize.Value;
|
||||
}
|
||||
if (Anchor.HasValue)
|
||||
{
|
||||
target.Anchor = Anchor.Value;
|
||||
}
|
||||
if (Pivot.HasValue)
|
||||
{
|
||||
target.Pivot = Pivot.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
target.Pivot = RectTransform.MatchPivotToAnchor(target.Anchor);
|
||||
}
|
||||
target.RecalculateChildren(true, true);
|
||||
}
|
||||
}
|
||||
|
||||
public GUIFrame GuiFrame { get; protected set; }
|
||||
|
||||
[Serialize(false, false)]
|
||||
public bool AllowUIOverlap
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
private ItemComponent linkToUIComponent;
|
||||
[Serialize("", false)]
|
||||
public string LinkUIToComponent
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(0, false)]
|
||||
public int HudPriority
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
private bool shouldMuffleLooping;
|
||||
@@ -496,11 +553,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
msg = msg.Replace("[" + inputType.ToString().ToLowerInvariant() + "]", GameMain.Config.KeyBind(inputType).ToString());
|
||||
}
|
||||
DisplayMsg = msg;
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayMsg = Msg;
|
||||
Msg = msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
|
||||
{
|
||||
deattachTimer = msg.ReadSingle();
|
||||
DeattachTimer = msg.ReadSingle();
|
||||
if (deattachTimer >= DeattachDuration)
|
||||
{
|
||||
holdable.DeattachFromWall();
|
||||
|
||||
@@ -25,12 +25,6 @@ namespace Barotrauma.Items.Components
|
||||
DrawHUDBack, null);
|
||||
submarineContainer = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.85f), GuiFrame.RectTransform, Anchor.Center), style: null);
|
||||
|
||||
new GUICustomComponent(new RectTransform(new Vector2(0.9f, 0.85f), GuiFrame.RectTransform, Anchor.Center),
|
||||
DrawHUDFront, null)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
hullInfoFrame = new GUIFrame(new RectTransform(new Vector2(0.13f, 0.13f), GUI.Canvas, minSize: new Point(250, 150)),
|
||||
style: "InnerFrame")
|
||||
{
|
||||
@@ -53,7 +47,7 @@ namespace Barotrauma.Items.Components
|
||||
public override void AddToGUIUpdateList()
|
||||
{
|
||||
base.AddToGUIUpdateList();
|
||||
hullInfoFrame.AddToGUIUpdateList();
|
||||
if (hasPower) hullInfoFrame.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
public override void OnMapLoaded()
|
||||
@@ -102,27 +96,6 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawHUDFront(SpriteBatch spriteBatch, GUICustomComponent container)
|
||||
{
|
||||
foreach (GUIComponent child in submarineContainer.Children.First().Children)
|
||||
{
|
||||
if (child.UserData is Hull hull)
|
||||
{
|
||||
if (hull.Submarine == null || !hull.Submarine.IsOutpost) { continue; }
|
||||
string text = TextManager.Get("MiniMapOutpostDockingInfo").Replace("[outpost]", hull.Submarine.Name);
|
||||
Vector2 textSize = GUI.Font.MeasureString(text);
|
||||
Vector2 textPos = child.Center;
|
||||
if (textPos.X + textSize.X / 2 > submarineContainer.Rect.Right)
|
||||
textPos.X -= ((textPos.X + textSize.X / 2) - submarineContainer.Rect.Right) + 10;
|
||||
if (textPos.X - textSize.X / 2 < submarineContainer.Rect.X)
|
||||
textPos.X += (submarineContainer.Rect.X - (textPos.X - textSize.X / 2)) + 10;
|
||||
GUI.DrawString(spriteBatch, textPos - textSize / 2, text,
|
||||
Color.Orange * (float)Math.Abs(Math.Sin(Timing.TotalTime)), Color.Black * 0.8f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawHUDBack(SpriteBatch spriteBatch, GUICustomComponent container)
|
||||
{
|
||||
Hull mouseOnHull = null;
|
||||
@@ -248,7 +221,7 @@ namespace Barotrauma.Items.Components
|
||||
foreach (Submarine sub in subs)
|
||||
{
|
||||
if (sub.HullVertices == null) { continue; }
|
||||
|
||||
|
||||
Rectangle worldBorders = sub.GetDockedBorders();
|
||||
worldBorders.Location += sub.WorldPosition.ToPoint();
|
||||
|
||||
@@ -269,8 +242,6 @@ namespace Barotrauma.Items.Components
|
||||
GUI.DrawLine(spriteBatch, center + start, center + end, Color.DarkCyan * Rand.Range(0.3f, 0.35f), width: 10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void GetLinkedHulls(Hull hull, List<Hull> linkedHulls)
|
||||
|
||||
@@ -107,10 +107,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
var warningBtn = new GUIButton(new RectTransform(new Point(buttonWidth, buttonHeight), columnLeft.RectTransform)
|
||||
{ AbsoluteOffset = new Point((i % buttonsPerRow) * (buttonWidth + spacing), (int)Math.Floor(i / (float)buttonsPerRow) * (buttonHeight + spacing)) },
|
||||
TextManager.Get(warningTexts[i]), style: "IndicatorButton")
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
TextManager.Get(warningTexts[i]), style: "IndicatorButton");
|
||||
|
||||
var btnText = warningBtn.GetChild<GUITextBlock>();
|
||||
btnText.Font = GUI.SmallFont;
|
||||
|
||||
@@ -785,9 +785,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
foreach (Limb limb in c.AnimController.Limbs)
|
||||
{
|
||||
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)
|
||||
|
||||
@@ -484,14 +484,26 @@ namespace Barotrauma.Items.Components
|
||||
user = Character.Controlled;
|
||||
}
|
||||
}
|
||||
if (!AutoPilot && Character.DisableControls && GUI.KeyboardDispatcher.Subscriber == null)
|
||||
if (!AutoPilot && Character.DisableControls)
|
||||
{
|
||||
steeringAdjustSpeed = character == null ? 0.2f : MathHelper.Lerp(0.2f, 1.0f, character.GetSkillLevel("helm") / 100.0f);
|
||||
Vector2 input = Vector2.Zero;
|
||||
if (PlayerInput.KeyDown(InputType.Left)) { input -= Vector2.UnitX; }
|
||||
if (PlayerInput.KeyDown(InputType.Right)) { input += Vector2.UnitX; }
|
||||
if (PlayerInput.KeyDown(InputType.Up)) { input += Vector2.UnitY; }
|
||||
if (PlayerInput.KeyDown(InputType.Down)) { input -= Vector2.UnitY; }
|
||||
if (PlayerInput.KeyDown(InputType.Left))
|
||||
{
|
||||
input -= Vector2.UnitX;
|
||||
}
|
||||
if (PlayerInput.KeyDown(InputType.Right))
|
||||
{
|
||||
input += Vector2.UnitX;
|
||||
}
|
||||
if (PlayerInput.KeyDown(InputType.Up))
|
||||
{
|
||||
input += Vector2.UnitY;
|
||||
}
|
||||
if (PlayerInput.KeyDown(InputType.Down))
|
||||
{
|
||||
input -= Vector2.UnitY;
|
||||
}
|
||||
if (PlayerInput.KeyDown(Keys.LeftShift))
|
||||
{
|
||||
SteeringInput += input * deltaTime * 200;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using Barotrauma.Particles;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -12,21 +11,12 @@ using System.Xml.Linq;
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class RepairTool
|
||||
#if DEBUG
|
||||
: IDrawableComponent
|
||||
#endif
|
||||
{
|
||||
public ParticleEmitter ParticleEmitter
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
#if DEBUG
|
||||
public Vector2 DrawSize
|
||||
{
|
||||
get { return GameMain.DebugDraw ? Vector2.One * Range : Vector2.Zero; }
|
||||
}
|
||||
#endif
|
||||
|
||||
private List<ParticleEmitter> ParticleEmitterHitStructure = new List<ParticleEmitter>();
|
||||
private List<ParticleEmitter> ParticleEmitterHitCharacter = new List<ParticleEmitter>();
|
||||
@@ -132,17 +122,5 @@ namespace Barotrauma.Items.Components
|
||||
emitter.Second.Emit(deltaTime, particlePos, item.CurrentHull, particleAngle + MathHelper.Pi, -particleAngle + MathHelper.Pi);
|
||||
}
|
||||
}
|
||||
#if DEBUG
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing)
|
||||
{
|
||||
if (GameMain.DebugDraw && IsActive)
|
||||
{
|
||||
GUI.DrawLine(spriteBatch,
|
||||
new Vector2(debugRayStartPos.X, -debugRayStartPos.Y),
|
||||
new Vector2(debugRayEndPos.X, -debugRayEndPos.Y),
|
||||
Color.Yellow);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using Barotrauma.Networking;
|
||||
using Barotrauma.Particles;
|
||||
using Lidgren.Network;
|
||||
using Barotrauma.Particles;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System.Collections.Generic;
|
||||
@@ -114,7 +112,8 @@ 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)
|
||||
{
|
||||
if (!(c.UserData is Skill skill)) continue;
|
||||
Skill skill = c.UserData as Skill;
|
||||
if (skill == null) continue;
|
||||
|
||||
GUITextBlock textBlock = (GUITextBlock)c;
|
||||
if (character.GetSkillLevel(skill.Identifier) < skill.Level)
|
||||
@@ -127,15 +126,5 @@ 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,6 +169,20 @@ namespace Barotrauma.Items.Components
|
||||
if (draggingConnected.Connect(this, !alreadyConnected, true))
|
||||
{
|
||||
var otherConnection = draggingConnected.OtherConnection(this);
|
||||
#if SERVER
|
||||
//TODO: ffs
|
||||
if (otherConnection == null)
|
||||
{
|
||||
GameServer.Log(Character.Controlled.LogName + " connected a wire to " +
|
||||
Item.Name + " (" + Name + ")", ServerLog.MessageType.ItemInteraction);
|
||||
}
|
||||
else
|
||||
{
|
||||
GameServer.Log(Character.Controlled.LogName + " connected a wire from " +
|
||||
Item.Name + " (" + Name + ") to " + otherConnection.item.Name + " (" + otherConnection.Name + ")", ServerLog.MessageType.ItemInteraction);
|
||||
}
|
||||
#endif
|
||||
|
||||
SetWire(index, draggingConnected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.ShowInHealthScannerThreshold || affliction.Strength <= 0.0f) continue;
|
||||
if (affliction.Strength < affliction.Prefab.ActivationThreshold || 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,
|
||||
item.SpriteColor,
|
||||
Color.White,
|
||||
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,
|
||||
item.SpriteColor,
|
||||
drawPos - new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)) * recoilOffset * item.Scale,
|
||||
Color.White,
|
||||
rotation + MathHelper.PiOver2, item.Scale,
|
||||
SpriteEffects.None, item.SpriteDepth + (barrelSprite.Depth - item.Sprite.Depth));
|
||||
|
||||
|
||||
@@ -301,7 +301,7 @@ namespace Barotrauma
|
||||
protected virtual void ControlInput(Camera cam)
|
||||
{
|
||||
// Note that these targets are static. Therefore the outcome is the same if this method is called multiple times or only once.
|
||||
if (selectedSlot != null && !DraggingItemToWorld)
|
||||
if (selectedSlot != null || draggingItem != null)
|
||||
{
|
||||
cam.Freeze = true;
|
||||
}
|
||||
@@ -609,17 +609,8 @@ namespace Barotrauma
|
||||
|
||||
if (selectedSlot == null)
|
||||
{
|
||||
if (DraggingItemToWorld &&
|
||||
Character.Controlled.FocusedItem?.OwnInventory != null &&
|
||||
Character.Controlled.FocusedItem.OwnInventory.TryPutItem(draggingItem, Character.Controlled))
|
||||
{
|
||||
GUI.PlayUISound(GUISoundType.PickItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.PlayUISound(GUISoundType.DropItem);
|
||||
draggingItem.Drop(Character.Controlled);
|
||||
}
|
||||
draggingItem.Drop(Character.Controlled);
|
||||
GUI.PlayUISound(GUISoundType.DropItem);
|
||||
}
|
||||
else if (selectedSlot.ParentInventory.Items[selectedSlot.SlotIndex] != draggingItem)
|
||||
{
|
||||
@@ -711,27 +702,10 @@ namespace Barotrauma
|
||||
int iconSize = (int)(64 * GUI.Scale);
|
||||
float scale = Math.Min(Math.Min(iconSize / sprite.size.X, iconSize / sprite.size.Y), 1.5f);
|
||||
Vector2 itemPos = PlayerInput.MousePosition;
|
||||
|
||||
if (GUI.MouseOn == null && selectedSlot == null)
|
||||
{
|
||||
var shadowSprite = GUI.Style.GetComponentStyle("OuterGlow").Sprites[GUIComponent.ComponentState.None][0];
|
||||
string toolTip = Character.Controlled.FocusedItem != null ?
|
||||
TextManager.Get("PutItemIn").Replace("[itemname]", Character.Controlled.FocusedItem.Name) :
|
||||
TextManager.Get("DropItem");
|
||||
int textWidth = (int)Math.Max(GUI.Font.MeasureString(draggingItem.Name).X, GUI.SmallFont.MeasureString(toolTip).X);
|
||||
int textSpacing = (int)(15 * GUI.Scale);
|
||||
Point shadowBorders = (new Point(40, 10)).Multiply(GUI.Scale);
|
||||
shadowSprite.Draw(spriteBatch,
|
||||
new Rectangle(itemPos.ToPoint() - new Point(iconSize / 2) - shadowBorders, new Point(iconSize + textWidth + textSpacing, iconSize) + shadowBorders.Multiply(2)), Color.Black * 0.8f);
|
||||
GUI.DrawString(spriteBatch, new Vector2(itemPos.X + iconSize / 2 + textSpacing, itemPos.Y - iconSize / 2), draggingItem.Name, Color.White);
|
||||
GUI.DrawString(spriteBatch, new Vector2(itemPos.X + iconSize / 2 + textSpacing, itemPos.Y), toolTip,
|
||||
color: Character.Controlled.FocusedItem == null ? Color.Red : Color.LightGreen,
|
||||
font: GUI.SmallFont);
|
||||
}
|
||||
sprite.Draw(spriteBatch, itemPos + Vector2.One * 2, Color.Black, scale: scale);
|
||||
sprite.Draw(spriteBatch,
|
||||
itemPos,
|
||||
sprite == draggingItem.Sprite ? draggingItem.GetSpriteColor() : draggingItem.GetInventoryIconColor(),
|
||||
sprite.Draw(spriteBatch,
|
||||
itemPos,
|
||||
sprite == draggingItem.Sprite ? draggingItem.GetSpriteColor() : draggingItem.GetInventoryIconColor(),
|
||||
scale: scale);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,12 @@ namespace Barotrauma
|
||||
|
||||
protected override void ControlInput(Camera cam)
|
||||
{
|
||||
if (draggingItem == null && HUD.CloseHUD(BackgroundFrame))
|
||||
{
|
||||
// TODO: fix so that works with the server side
|
||||
Character.Controlled.SelectedConstruction = null;
|
||||
return;
|
||||
}
|
||||
base.ControlInput(cam);
|
||||
if (BackgroundFrame.Contains(PlayerInput.MousePosition))
|
||||
{
|
||||
|
||||
@@ -232,11 +232,11 @@ namespace Barotrauma
|
||||
{
|
||||
if (!ResizeHorizontal && !ResizeVertical)
|
||||
{
|
||||
sprite.Draw(spriteBatch, new Vector2(placeRect.Center.X, -(placeRect.Y - placeRect.Height / 2)), SpriteColor * 0.8f, scale: Scale * scale);
|
||||
sprite.Draw(spriteBatch, new Vector2(placeRect.Center.X, -(placeRect.Y - placeRect.Height / 2)), SpriteColor, scale: Scale * scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sprite != null) sprite.DrawTiled(spriteBatch, new Vector2(placeRect.X, -placeRect.Y), placeRect.Size.ToVector2(), null, SpriteColor * 0.8f);
|
||||
if (sprite != null) sprite.DrawTiled(spriteBatch, new Vector2(placeRect.X, -placeRect.Y), placeRect.Size.ToVector2(), null, SpriteColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
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
|
||||
{
|
||||
@@ -18,8 +19,6 @@ 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;
|
||||
@@ -140,10 +139,6 @@ namespace Barotrauma
|
||||
partial void UpdateProjSpecific(float deltaTime, Camera cam)
|
||||
{
|
||||
serverUpdateDelay -= deltaTime;
|
||||
if (serverUpdateDelay <= 0.0f)
|
||||
{
|
||||
ApplyRemoteState();
|
||||
}
|
||||
|
||||
if (networkUpdatePending)
|
||||
{
|
||||
@@ -552,18 +547,18 @@ namespace Barotrauma
|
||||
|
||||
public void ClientRead(ServerNetObject type, NetBuffer message, float sendingTime)
|
||||
{
|
||||
remoteWaterVolume = message.ReadRangedSingle(0.0f, 1.5f, 8) * Volume;
|
||||
remoteOxygenPercentage = message.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||
float newWaterVolume = message.ReadRangedSingle(0.0f, 1.5f, 8) * Volume;
|
||||
float newOxygenPercentage = message.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||
|
||||
bool hasFireSources = message.ReadBoolean();
|
||||
int fireSourceCount = 0;
|
||||
remoteFireSources = new List<Vector3>();
|
||||
List<Vector3> newFireSources = new List<Vector3>();
|
||||
if (hasFireSources)
|
||||
{
|
||||
fireSourceCount = message.ReadRangedInteger(0, 16);
|
||||
for (int i = 0; i < fireSourceCount; i++)
|
||||
{
|
||||
remoteFireSources.Add(new Vector3(
|
||||
newFireSources.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)));
|
||||
@@ -572,6 +567,41 @@ 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();
|
||||
}
|
||||
|
||||
|
||||
@@ -247,11 +247,15 @@ namespace Barotrauma.Lights
|
||||
|
||||
public void Rotate(Vector2 origin, float amount)
|
||||
{
|
||||
Matrix rotationMatrix =
|
||||
Matrix.CreateTranslation(-origin.X, -origin.Y, 0.0f) *
|
||||
Matrix.CreateRotationZ(amount) *
|
||||
Matrix.CreateTranslation(origin.X, origin.Y, 0.0f);
|
||||
SetVertices(vertices.Select(v => v.Pos).ToArray(), rotationMatrix);
|
||||
Matrix rotationMatrix = Matrix.CreateRotationZ(amount);
|
||||
|
||||
Vector2[] newVerts = new Vector2[vertices.Length];
|
||||
for (int i = 0; i < vertices.Length; i++)
|
||||
{
|
||||
newVerts[i] = Vector2.Transform(vertices[i].Pos - origin, rotationMatrix) + origin;
|
||||
}
|
||||
|
||||
SetVertices(newVerts);
|
||||
}
|
||||
|
||||
private void CalculateDimensions()
|
||||
|
||||
@@ -453,10 +453,7 @@ namespace Barotrauma.Lights
|
||||
|
||||
//raster pattern on top of everything
|
||||
spriteBatch.Begin(blendState: BlendState.AlphaBlend, samplerState: SamplerState.LinearWrap);
|
||||
spriteBatch.Draw(highlightRaster,
|
||||
new Rectangle(0, 0, HighlightMap.Width, HighlightMap.Height),
|
||||
new Rectangle(0, 0, (int)(HighlightMap.Width / currLightMapScale * 0.5f), (int)(HighlightMap.Height / currLightMapScale * 0.5f)),
|
||||
Color.White * 0.5f);
|
||||
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"];
|
||||
|
||||
@@ -364,23 +364,15 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (GUI.KeyboardDispatcher.Subscriber == null)
|
||||
{
|
||||
float moveSpeed = 1000.0f;
|
||||
Vector2 moveAmount = Vector2.Zero;
|
||||
if (PlayerInput.KeyDown(InputType.Left)) { moveAmount += Vector2.UnitX; }
|
||||
if (PlayerInput.KeyDown(InputType.Right)) { moveAmount -= Vector2.UnitX; }
|
||||
if (PlayerInput.KeyDown(InputType.Up)) { moveAmount += Vector2.UnitY; }
|
||||
if (PlayerInput.KeyDown(InputType.Down)) { moveAmount -= Vector2.UnitY; }
|
||||
drawOffset += moveAmount * moveSpeed / zoom * deltaTime;
|
||||
}
|
||||
|
||||
if (GUI.MouseOn == mapContainer)
|
||||
{
|
||||
zoom += PlayerInput.ScrollWheelSpeed / 1000.0f;
|
||||
zoom = MathHelper.Clamp(zoom, 1.0f, 4.0f);
|
||||
|
||||
if (PlayerInput.MidButtonHeld()) { drawOffset += PlayerInput.MouseSpeed / zoom; }
|
||||
if (PlayerInput.MidButtonHeld())
|
||||
{
|
||||
drawOffset += PlayerInput.MouseSpeed / zoom;
|
||||
}
|
||||
#if DEBUG
|
||||
if (PlayerInput.DoubleClicked() && highlightedLocation != null)
|
||||
{
|
||||
@@ -559,6 +551,11 @@ namespace Barotrauma
|
||||
null, connectionColor * MathHelper.Clamp(a, 0.1f, 0.5f), MathUtils.VectorToAngle(end - start),
|
||||
new Vector2(0, 16), SpriteEffects.None, 0.01f);
|
||||
}
|
||||
}
|
||||
|
||||
rect.Inflate(8, 8);
|
||||
GUI.DrawRectangle(spriteBatch, rect, Color.Black, false, 0.0f, 8);
|
||||
GUI.DrawRectangle(spriteBatch, rect, Color.LightGray);
|
||||
|
||||
if (GameMain.DebugDraw && zoom > 1.0f && generationParams.ShowLevelTypeNames)
|
||||
{
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace Barotrauma
|
||||
drawRect.Location -= Submarine.MainSub.Position.ToPoint();
|
||||
}
|
||||
drawRect.Y = -drawRect.Y;
|
||||
GUI.DrawRectangle(spriteBatch, drawRect, Color.White);
|
||||
GUI.DrawRectangle(spriteBatch, drawRect, Color.DarkBlue);
|
||||
}
|
||||
public void DrawListLine(SpriteBatch spriteBatch, Vector2 pos, Color color)
|
||||
{
|
||||
|
||||
@@ -75,10 +75,7 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
var h = new ConvexHull(verts, Color.Black, this);
|
||||
if (Math.Abs(rotation) > 0.001f)
|
||||
{
|
||||
h.Rotate(position, rotation);
|
||||
}
|
||||
h.Rotate(position, rotation);
|
||||
convexHulls.Add(h);
|
||||
}
|
||||
|
||||
@@ -295,7 +292,8 @@ namespace Barotrauma
|
||||
{
|
||||
if (damageEffect != null)
|
||||
{
|
||||
float newCutoff = MathHelper.Lerp(0.0f, 0.65f, Sections[i].damage / Prefab.Health);
|
||||
float newCutoff = Sections[i].damage > 0 ?
|
||||
MathHelper.Lerp(0.2f, 0.65f, Sections[i].damage / Prefab.Health) : 0.0f;
|
||||
|
||||
if (Math.Abs(newCutoff - Submarine.DamageEffectCutoff) > 0.01f || color != Submarine.DamageEffectColor)
|
||||
{
|
||||
@@ -362,7 +360,6 @@ namespace Barotrauma
|
||||
-Bodies[i].Rotation, Color.White);
|
||||
}
|
||||
}
|
||||
AiTarget?.Draw(spriteBatch);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Barotrauma
|
||||
public override void DrawPlacing(SpriteBatch spriteBatch, Rectangle placeRect, float scale = 1.0f)
|
||||
{
|
||||
// TODO: the scale property is not used
|
||||
sprite.DrawTiled(spriteBatch, new Vector2(placeRect.X, -placeRect.Y), new Vector2(placeRect.Width, placeRect.Height), color: Color.White * 0.8f, textureScale: TextureScale * Scale);
|
||||
sprite.DrawTiled(spriteBatch, new Vector2(placeRect.X, -placeRect.Y), new Vector2(placeRect.Width, placeRect.Height), textureScale: TextureScale * Scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,23 +141,8 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
if (!permissions.HasFlag(ClientPermissions.ManageRound)) { return false; }
|
||||
if (!Submarine.MainSub.AtStartPosition && !Submarine.MainSub.AtEndPosition)
|
||||
{
|
||||
var msgBox = new GUIMessageBox("", TextManager.Get("EndRoundSubNotAtLevelEnd"),
|
||||
new string[] { TextManager.Get("Yes"), TextManager.Get("No") });
|
||||
msgBox.Buttons[0].OnClicked = (_, __) =>
|
||||
{
|
||||
GameMain.Client.RequestRoundEnd();
|
||||
return true;
|
||||
};
|
||||
msgBox.Buttons[0].OnClicked += msgBox.Close;
|
||||
msgBox.Buttons[1].OnClicked += msgBox.Close;
|
||||
}
|
||||
else
|
||||
{
|
||||
RequestRoundEnd();
|
||||
}
|
||||
if (!permissions.HasFlag(ClientPermissions.ManageRound)) return false;
|
||||
RequestRoundEnd();
|
||||
return true;
|
||||
},
|
||||
Visible = false
|
||||
@@ -637,7 +622,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (gameStarted) SetRadioButtonColor();
|
||||
|
||||
if (ShowNetStats && client?.ServerConnection != null)
|
||||
if (ShowNetStats)
|
||||
{
|
||||
netStats.AddValue(NetStats.NetStatType.ReceivedBytes, client.ServerConnection.Statistics.ReceivedBytes);
|
||||
netStats.AddValue(NetStats.NetStatType.SentBytes, client.ServerConnection.Statistics.SentBytes);
|
||||
@@ -1124,7 +1109,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
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);
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:LevelsDontMatch"+levelSeed, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
CoroutineManager.StartCoroutine(EndGame(""));
|
||||
yield return CoroutineStatus.Failure;
|
||||
}
|
||||
@@ -1396,6 +1381,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;
|
||||
@@ -1451,11 +1439,7 @@ namespace Barotrauma.Networking
|
||||
break;
|
||||
case ServerNetObject.ENTITY_EVENT:
|
||||
case ServerNetObject.ENTITY_EVENT_INITIAL:
|
||||
if (!entityEventManager.Read(objHeader, inc, sendingTime, entities))
|
||||
{
|
||||
eventReadFailed = true;
|
||||
break;
|
||||
}
|
||||
if (!entityEventManager.Read(objHeader, inc, sendingTime, entities)) { break; }
|
||||
break;
|
||||
case ServerNetObject.CHAT_MESSAGE:
|
||||
ChatMessage.ClientRead(inc);
|
||||
@@ -1719,8 +1703,6 @@ 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--;
|
||||
@@ -1738,7 +1720,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);
|
||||
}
|
||||
|
||||
@@ -2007,8 +1989,7 @@ namespace Barotrauma.Networking
|
||||
msg.Write(true); msg.WritePadBits();
|
||||
msg.Write(savePath);
|
||||
msg.Write(mapSeed);
|
||||
msg.Write(sub.Name);
|
||||
msg.Write(sub.MD5Hash.Hash);
|
||||
msg.Write(sub.FilePath);
|
||||
|
||||
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace Barotrauma
|
||||
|
||||
UpdateSubList(submarines);
|
||||
|
||||
// New game right sideon
|
||||
// New game right side
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), rightColumn.RectTransform), TextManager.Get("SaveName") + ":", textAlignment: Alignment.BottomLeft);
|
||||
saveNameBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.1f), rightColumn.RectTransform), string.Empty);
|
||||
|
||||
@@ -262,6 +262,11 @@ namespace Barotrauma
|
||||
saveFiles = SaveUtil.GetSaveFiles(isMultiplayer ? SaveUtil.SaveType.Multiplayer : SaveUtil.SaveType.Singleplayer);
|
||||
}
|
||||
|
||||
saveList = new GUIListBox(new RectTransform(new Vector2(0.5f, 1.0f), loadGameContainer.RectTransform, Anchor.CenterLeft))
|
||||
{
|
||||
OnSelected = SelectSaveFile
|
||||
};
|
||||
|
||||
saveList = new GUIListBox(new RectTransform(new Vector2(0.5f, 1.0f), loadGameContainer.RectTransform, Anchor.CenterLeft))
|
||||
{
|
||||
OnSelected = SelectSaveFile
|
||||
@@ -269,9 +274,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (string saveFile in saveFiles)
|
||||
{
|
||||
string fileName = saveFile;
|
||||
string subName = "";
|
||||
string saveTime = "";
|
||||
XDocument doc = SaveUtil.LoadGameSessionDoc(saveFile);
|
||||
var saveFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.1f), saveList.Content.RectTransform), style: "ListBoxElement")
|
||||
{
|
||||
UserData = saveFile
|
||||
@@ -279,38 +282,25 @@ namespace Barotrauma
|
||||
|
||||
var nameText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform),
|
||||
text: Path.GetFileNameWithoutExtension(saveFile));
|
||||
if (doc?.Root == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error loading save file \"" + saveFile + "\". The file may be corrupted.");
|
||||
nameText.Color = Color.Red;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isMultiplayer)
|
||||
{
|
||||
XDocument doc = SaveUtil.LoadGameSessionDoc(saveFile);
|
||||
if (doc?.Root == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error loading save file \"" + saveFile + "\". The file may be corrupted.");
|
||||
nameText.Color = Color.Red;
|
||||
continue;
|
||||
}
|
||||
subName = doc.Root.GetAttributeString("submarine", "");
|
||||
saveTime = doc.Root.GetAttributeString("savetime", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] splitSaveFile = saveFile.Split(';');
|
||||
saveFrame.UserData = splitSaveFile[0];
|
||||
fileName = nameText.Text = Path.GetFileNameWithoutExtension(splitSaveFile[0]);
|
||||
if (splitSaveFile.Length > 1) { subName = splitSaveFile[1]; }
|
||||
if (splitSaveFile.Length > 2) { saveTime = splitSaveFile[2]; }
|
||||
}
|
||||
|
||||
string submarineName = doc.Root.GetAttributeString("submarine", "");
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform, Anchor.BottomLeft),
|
||||
text: subName, font: GUI.SmallFont)
|
||||
text: submarineName, font: GUI.SmallFont)
|
||||
{
|
||||
UserData = fileName
|
||||
UserData = saveFile
|
||||
};
|
||||
|
||||
string saveTime = doc.Root.GetAttributeString("savetime", "");
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), saveFrame.RectTransform),
|
||||
text: saveTime, textAlignment: Alignment.Right, font: GUI.SmallFont)
|
||||
{
|
||||
UserData = fileName
|
||||
UserData = saveFile
|
||||
};
|
||||
}
|
||||
|
||||
@@ -355,6 +345,13 @@ namespace Barotrauma
|
||||
};
|
||||
}
|
||||
|
||||
public void UpdateTutorialSelection()
|
||||
{
|
||||
if (isMultiplayer) return;
|
||||
Tutorial contextualTutorial = Tutorial.Tutorials.Find(t => t is ContextualTutorial);
|
||||
contextualTutorialBox.Selected = (contextualTutorial != null) ? !GameMain.Config.CompletedTutorialNames.Contains(contextualTutorial.Name) : true;
|
||||
}
|
||||
|
||||
public void UpdateTutorialSelection()
|
||||
{
|
||||
if (isMultiplayer) return;
|
||||
|
||||
@@ -457,14 +457,11 @@ namespace Barotrauma
|
||||
{
|
||||
IgnoreLayoutGroups = true,
|
||||
OnClicked = (GUIButton btn, object obj) => { StartRound?.Invoke(); return true; },
|
||||
Enabled = true
|
||||
Enabled = true,
|
||||
Visible = GameMain.Client == null ||
|
||||
GameMain.Client.HasPermission(Networking.ClientPermissions.ManageRound) ||
|
||||
GameMain.Client.HasPermission(Networking.ClientPermissions.ManageCampaign)
|
||||
};
|
||||
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);
|
||||
|
||||
@@ -118,19 +118,6 @@ namespace Barotrauma
|
||||
instance = this;
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
AnimParams.ForEach(a => a.Reset(true));
|
||||
RagdollParams.Reset(true);
|
||||
RagdollParams.ClearHistory();
|
||||
CurrentAnimation.ClearHistory();
|
||||
if (!character.Removed)
|
||||
{
|
||||
character.Remove();
|
||||
}
|
||||
character = null;
|
||||
}
|
||||
|
||||
public override void Deselect()
|
||||
{
|
||||
base.Deselect();
|
||||
@@ -141,7 +128,15 @@ namespace Barotrauma
|
||||
isEndlessRunner = false;
|
||||
if (character != null)
|
||||
{
|
||||
Reset();
|
||||
AnimParams.ForEach(a => a.Reset(true));
|
||||
RagdollParams.Reset(true);
|
||||
RagdollParams.ClearHistory();
|
||||
CurrentAnimation.ClearHistory();
|
||||
if (!character.Removed)
|
||||
{
|
||||
character.Remove();
|
||||
}
|
||||
character = null;
|
||||
}
|
||||
GameMain.World.ProcessChanges();
|
||||
}
|
||||
@@ -398,12 +393,6 @@ namespace Barotrauma
|
||||
}
|
||||
if (!isFreezed)
|
||||
{
|
||||
if (character.AnimController.Invalid)
|
||||
{
|
||||
Reset();
|
||||
SpawnCharacter(currentCharacterConfig);
|
||||
}
|
||||
|
||||
Submarine.MainSub.SetPrevTransform(Submarine.MainSub.Position);
|
||||
Submarine.MainSub.Update((float)deltaTime);
|
||||
|
||||
@@ -1226,7 +1215,7 @@ namespace Barotrauma
|
||||
Cam.Position = character.WorldPosition;
|
||||
}
|
||||
|
||||
private bool CreateCharacter(string name, string mainFolder, bool isHumanoid, params object[] ragdollConfig)
|
||||
private bool CreateCharacter(string name, bool isHumanoid, params object[] ragdollConfig)
|
||||
{
|
||||
var contentPackage = GameMain.Config.SelectedContentPackages.LastOrDefault();
|
||||
if (contentPackage == null)
|
||||
@@ -1239,22 +1228,23 @@ namespace Barotrauma
|
||||
#if !DEBUG
|
||||
if (vanilla != null && contentPackage == vanilla)
|
||||
{
|
||||
GUI.AddMessage(GetCharacterEditorTranslation("CannotEditVanillaCharacters"), Color.Red, font: GUI.LargeFont);
|
||||
GUI.AddMessage($"Cannot edit the Vanilla content!", Color.Red, font: GUI.LargeFont);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
string speciesName = name;
|
||||
string mainFolder = $"Content/Characters/{speciesName}";
|
||||
// Config file
|
||||
string configFilePath = Path.Combine(mainFolder, $"{speciesName}.xml").Replace(@"\", @"/");
|
||||
string configFilePath = $"{mainFolder}/{speciesName}.xml";
|
||||
if (ContentPackage.GetFilesOfType(GameMain.SelectedPackages, ContentType.Character).None(path => path.Contains(speciesName)))
|
||||
{
|
||||
// Create the config file
|
||||
XElement mainElement = new XElement("Character",
|
||||
new XAttribute("name", speciesName),
|
||||
new XAttribute("humanoid", isHumanoid),
|
||||
new XElement("ragdolls", new XAttribute("folder", Path.Combine(mainFolder, $"Ragdolls/").Replace(@"\", @"/"))),
|
||||
new XElement("animations", new XAttribute("folder", Path.Combine(mainFolder, $"Animations/").Replace(@"\", @"/"))),
|
||||
new XElement("ragdolls"),
|
||||
new XElement("animations"),
|
||||
new XElement("health"),
|
||||
new XElement("ai"));
|
||||
XDocument doc = new XDocument(mainElement);
|
||||
@@ -1269,13 +1259,13 @@ namespace Barotrauma
|
||||
DebugConsole.NewMessage(GetCharacterEditorTranslation("ContentPackageSaved").Replace("[path]", contentPackage.Path));
|
||||
}
|
||||
// Ragdoll
|
||||
string ragdollFolder = RagdollParams.GetFolder(speciesName);
|
||||
string ragdollFolder = RagdollParams.GetDefaultFolder(speciesName);
|
||||
string ragdollPath = RagdollParams.GetDefaultFile(speciesName);
|
||||
RagdollParams ragdollParams = isHumanoid
|
||||
? RagdollParams.CreateDefault<HumanRagdollParams>(ragdollPath, speciesName, ragdollConfig)
|
||||
: RagdollParams.CreateDefault<FishRagdollParams>(ragdollPath, speciesName, ragdollConfig) as RagdollParams;
|
||||
// Animations
|
||||
string animFolder = AnimationParams.GetFolder(speciesName);
|
||||
string animFolder = AnimationParams.GetDefaultFolder(speciesName);
|
||||
foreach (AnimationType animType in Enum.GetValues(typeof(AnimationType)))
|
||||
{
|
||||
if (animType != AnimationType.NotDefined)
|
||||
@@ -1879,7 +1869,7 @@ namespace Barotrauma
|
||||
#if !DEBUG
|
||||
if (VanillaCharacters != null && VanillaCharacters.Contains(currentCharacterConfig))
|
||||
{
|
||||
GUI.AddMessage(GetCharacterEditorTranslation("CannotEditVanillaCharacters"), Color.Red, font: GUI.LargeFont);
|
||||
GUI.AddMessage(GetCharacterEditorTranslation("CantEditVanillaContent"), Color.Red, font: GUI.LargeFont);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
@@ -1894,7 +1884,7 @@ namespace Barotrauma
|
||||
#if !DEBUG
|
||||
if (VanillaCharacters != null && VanillaCharacters.Contains(currentCharacterConfig))
|
||||
{
|
||||
GUI.AddMessage(GetCharacterEditorTranslation("CannotEditVanillaCharacters"), Color.Red, font: GUI.LargeFont);
|
||||
GUI.AddMessage(GetCharacterEditorTranslation("CantEditVanillaContent"), Color.Red, font: GUI.LargeFont);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
@@ -1966,7 +1956,7 @@ namespace Barotrauma
|
||||
#if !DEBUG
|
||||
if (VanillaCharacters != null && VanillaCharacters.Contains(currentCharacterConfig))
|
||||
{
|
||||
GUI.AddMessage(GetCharacterEditorTranslation("CannotEditVanillaCharacters"), Color.Red, font: GUI.LargeFont);
|
||||
GUI.AddMessage(GetCharacterEditorTranslation("CantEditVanillaContent"), Color.Red, font: GUI.LargeFont);
|
||||
box.Close();
|
||||
return false;
|
||||
}
|
||||
@@ -2099,7 +2089,7 @@ namespace Barotrauma
|
||||
#if !DEBUG
|
||||
if (VanillaCharacters != null && VanillaCharacters.Contains(currentCharacterConfig))
|
||||
{
|
||||
GUI.AddMessage(GetCharacterEditorTranslation("CannotEditVanillaCharacters"), Color.Red, font: GUI.LargeFont);
|
||||
GUI.AddMessage(GetCharacterEditorTranslation("CantEditVanillaContent"), Color.Red, font: GUI.LargeFont);
|
||||
box.Close();
|
||||
return false;
|
||||
}
|
||||
@@ -3928,7 +3918,7 @@ namespace Barotrauma
|
||||
|
||||
private void DrawJointLimitWidgets(SpriteBatch spriteBatch, Limb limb, LimbJoint joint, Vector2 drawPos, bool autoFreeze, bool allowPairEditing, float rotationOffset = 0)
|
||||
{
|
||||
rotationOffset += MathHelper.ToRadians(RagdollParams.SpritesheetOrientation);
|
||||
rotationOffset -= MathHelper.ToRadians(RagdollParams.SpritesheetOrientation);
|
||||
Color angleColor = joint.UpperLimit - joint.LowerLimit > 0 ? Color.LightGreen * 0.5f : Color.Red;
|
||||
DrawRadialWidget(spriteBatch, drawPos, MathHelper.ToDegrees(joint.UpperLimit), $"joint.jointParams.Name {GetCharacterEditorTranslation("UpperLimit")}", Color.Cyan, angle =>
|
||||
{
|
||||
@@ -4662,7 +4652,7 @@ namespace Barotrauma
|
||||
LimbXElements.Values,
|
||||
JointXElements
|
||||
};
|
||||
if (CharacterEditorScreen.instance.CreateCharacter(Name, Path.GetDirectoryName(XMLPath), IsHumanoid, ragdollParams))
|
||||
if (CharacterEditorScreen.instance.CreateCharacter(Name, IsHumanoid, ragdollParams))
|
||||
{
|
||||
GUI.AddMessage(GetCharacterEditorTranslation("CharacterCreated").Replace("[name]", Name), Color.Green, font: GUI.Font);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace Barotrauma
|
||||
new GUIImage(new RectTransform(new Vector2(0.35f, 0.2f), Frame.RectTransform, Anchor.BottomRight) { RelativeOffset = new Vector2(0.05f, 0.05f) },
|
||||
style: "TitleText");
|
||||
|
||||
buttonsParent = new GUILayoutGroup(new RectTransform(new Vector2(0.3f, 0.85f), parent: Frame.RectTransform, anchor: Anchor.BottomLeft, pivot: Pivot.BottomLeft)
|
||||
buttonsParent = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 0.85f), parent: Frame.RectTransform, anchor: Anchor.BottomLeft, pivot: Pivot.BottomLeft)
|
||||
{
|
||||
AbsoluteOffset = new Point(50, 0)
|
||||
})
|
||||
@@ -61,7 +61,7 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
// === CAMPAIGN
|
||||
var campaignHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 1.0f), parent: buttonsParent.RectTransform) { RelativeOffset = new Vector2(0.1f, 0.0f) }, isHorizontal: true);
|
||||
var campaignHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), parent: buttonsParent.RectTransform) { RelativeOffset = new Vector2(0.1f, 0.0f) }, isHorizontal: true);
|
||||
|
||||
new GUIImage(new RectTransform(new Vector2(0.2f, 0.7f), campaignHolder.RectTransform), "MainMenuCampaignIcon")
|
||||
{
|
||||
@@ -107,7 +107,7 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
// === MULTIPLAYER
|
||||
var multiplayerHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 1.0f), parent: buttonsParent.RectTransform) { RelativeOffset = new Vector2(0.05f, 0.0f) }, isHorizontal: true);
|
||||
var multiplayerHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), parent: buttonsParent.RectTransform) { RelativeOffset = new Vector2(0.05f, 0.0f) }, isHorizontal: true);
|
||||
|
||||
new GUIImage(new RectTransform(new Vector2(0.2f, 0.7f), multiplayerHolder.RectTransform), "MainMenuMultiplayerIcon")
|
||||
{
|
||||
@@ -152,7 +152,7 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
// === CUSTOMIZE
|
||||
var customizeHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 1.0f), parent: buttonsParent.RectTransform) { RelativeOffset = new Vector2(0.15f, 0.0f) }, isHorizontal: true);
|
||||
var customizeHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), parent: buttonsParent.RectTransform) { RelativeOffset = new Vector2(0.15f, 0.0f) }, isHorizontal: true);
|
||||
|
||||
new GUIImage(new RectTransform(new Vector2(0.2f, 0.7f), customizeHolder.RectTransform), "MainMenuCustomizeIcon")
|
||||
{
|
||||
@@ -209,7 +209,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
// === OPTION
|
||||
var optionHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.5f), parent: buttonsParent.RectTransform), isHorizontal: true);
|
||||
var optionHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 0.5f), parent: buttonsParent.RectTransform), isHorizontal: true);
|
||||
|
||||
new GUIImage(new RectTransform(new Vector2(0.15f, 0.6f), optionHolder.RectTransform), "MainMenuOptionIcon")
|
||||
{
|
||||
@@ -219,7 +219,7 @@ namespace Barotrauma
|
||||
//spacing
|
||||
new GUIFrame(new RectTransform(new Vector2(0.01f, 0.0f), optionHolder.RectTransform), style: null);
|
||||
|
||||
var optionButtons = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 1.0f), parent: optionHolder.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.15f) });
|
||||
var optionButtons = new GUILayoutGroup(new RectTransform(new Vector2(0.55f, 1.0f), parent: optionHolder.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.15f) });
|
||||
|
||||
var optionList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.15f), parent: optionButtons.RectTransform))
|
||||
{
|
||||
@@ -241,7 +241,7 @@ namespace Barotrauma
|
||||
|
||||
//debug button for quickly starting a new round
|
||||
#if DEBUG
|
||||
new GUIButton(new RectTransform(new Vector2(0.8f, 0.1f), buttonsParent.RectTransform, Anchor.TopLeft, Pivot.BottomLeft) { AbsoluteOffset = new Point(0, -40) },
|
||||
new GUIButton(new RectTransform(new Vector2(0.5f, 0.1f), buttonsParent.RectTransform, Anchor.TopLeft, Pivot.BottomLeft) { AbsoluteOffset = new Point(0, -40) },
|
||||
"Quickstart (dev)", style: "GUIButtonLarge", color: Color.Red)
|
||||
{
|
||||
IgnoreLayoutGroups = true,
|
||||
@@ -255,7 +255,7 @@ namespace Barotrauma
|
||||
#endif
|
||||
|
||||
var minButtonSize = new Point(120, 20);
|
||||
var maxButtonSize = new Point(480, 80);
|
||||
var maxButtonSize = new Point(240, 40);
|
||||
|
||||
/*new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("TutorialButton"), style: "GUIButtonLarge")
|
||||
{
|
||||
@@ -270,21 +270,16 @@ namespace Barotrauma
|
||||
SetupButtons(buttons);
|
||||
buttons.ForEach(b => b.TextBlock.SetTextPos());*/
|
||||
|
||||
var relativeSize = new Vector2(0.6f, 0.5f);
|
||||
var relativeSize = new Vector2(0.5f, 0.5f);
|
||||
var minSize = new Point(600, 400);
|
||||
var maxSize = new Point(2000, 1500);
|
||||
var anchor = Anchor.CenterRight;
|
||||
var pivot = Pivot.CenterRight;
|
||||
Vector2 relativeSpacing = new Vector2(0.05f, 0.0f);
|
||||
|
||||
var maxSize = new Point(900, 600);
|
||||
var anchor = Anchor.Center;
|
||||
var pivot = Pivot.Center;
|
||||
menuTabs = new GUIFrame[Enum.GetValues(typeof(Tab)).Length + 1];
|
||||
|
||||
menuTabs[(int)Tab.Settings] = new GUIFrame(new RectTransform(new Vector2(relativeSize.X, 0.8f), GUI.Canvas, anchor, pivot, minSize, maxSize) { RelativeOffset = relativeSpacing },
|
||||
style: null);
|
||||
|
||||
menuTabs[(int)Tab.NewGame] = new GUIFrame(new RectTransform(relativeSize, GUI.Canvas, anchor, pivot, minSize, maxSize) { RelativeOffset = relativeSpacing });
|
||||
|
||||
menuTabs[(int)Tab.NewGame] = new GUIFrame(new RectTransform(relativeSize, GUI.Canvas, anchor, pivot, minSize, maxSize));
|
||||
var paddedNewGame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), menuTabs[(int)Tab.NewGame].RectTransform, Anchor.Center), style: null);
|
||||
menuTabs[(int)Tab.LoadGame] = new GUIFrame(new RectTransform(relativeSize, GUI.Canvas, anchor, pivot, minSize, maxSize) { RelativeOffset = relativeSpacing });
|
||||
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, Submarine.SavedSubmarines)
|
||||
@@ -295,13 +290,13 @@ namespace Barotrauma
|
||||
|
||||
var hostServerScale = new Vector2(0.7f, 1.0f);
|
||||
menuTabs[(int)Tab.HostServer] = new GUIFrame(new RectTransform(
|
||||
Vector2.Multiply(relativeSize, hostServerScale), GUI.Canvas, anchor, pivot, minSize.Multiply(hostServerScale), maxSize.Multiply(hostServerScale)) { RelativeOffset = relativeSpacing });
|
||||
Vector2.Multiply(relativeSize, hostServerScale), GUI.Canvas, anchor, pivot, minSize.Multiply(hostServerScale), maxSize.Multiply(hostServerScale)));
|
||||
|
||||
CreateHostServerFields();
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
menuTabs[(int)Tab.Tutorials] = new GUIFrame(new RectTransform(relativeSize, GUI.Canvas, anchor, pivot, minSize, maxSize) { RelativeOffset = relativeSpacing });
|
||||
menuTabs[(int)Tab.Tutorials] = new GUIFrame(new RectTransform(relativeSize, GUI.Canvas, anchor, pivot, minSize, maxSize));
|
||||
|
||||
//PLACEHOLDER
|
||||
var tutorialList = new GUIListBox(
|
||||
@@ -382,7 +377,6 @@ namespace Barotrauma
|
||||
return false;
|
||||
}
|
||||
|
||||
GameMain.Config.ResetSettingsFrame();
|
||||
selectedTab = (Tab)obj;
|
||||
|
||||
switch (selectedTab)
|
||||
@@ -395,9 +389,8 @@ namespace Barotrauma
|
||||
campaignSetupUI.UpdateLoadMenu();
|
||||
break;
|
||||
case Tab.Settings:
|
||||
menuTabs[(int)Tab.Settings].RectTransform.ClearChildren();
|
||||
GameMain.Config.SettingsFrame.RectTransform.Parent = menuTabs[(int)Tab.Settings].RectTransform;
|
||||
GameMain.Config.SettingsFrame.RectTransform.RelativeSize = Vector2.One;
|
||||
GameMain.Config.ResetSettingsFrame();
|
||||
menuTabs[(int)Tab.Settings] = GameMain.Config.SettingsFrame;
|
||||
break;
|
||||
case Tab.JoinServer:
|
||||
GameMain.ServerListScreen.Select();
|
||||
|
||||
@@ -233,8 +233,7 @@ namespace Barotrauma
|
||||
|
||||
levelSeed = value;
|
||||
|
||||
int intSeed = ToolBox.StringToInt(levelSeed);
|
||||
backgroundSprite = LocationType.Random(new MTRandom(intSeed))?.GetPortrait(intSeed);
|
||||
backgroundSprite = LocationType.Random(levelSeed)?.GetPortrait(ToolBox.StringToInt(levelSeed));
|
||||
seedBox.Text = levelSeed;
|
||||
|
||||
//lastUpdateID++;
|
||||
@@ -727,12 +726,6 @@ 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
|
||||
@@ -854,9 +847,9 @@ namespace Barotrauma
|
||||
|
||||
if (campaignUI?.StartButton != null)
|
||||
{
|
||||
campaignUI.StartButton.Visible = !GameMain.Client.GameStarted &&
|
||||
(GameMain.Client.HasPermission(ClientPermissions.ManageRound) ||
|
||||
GameMain.Client.HasPermission(ClientPermissions.ManageCampaign));
|
||||
campaignUI.StartButton.Visible =
|
||||
GameMain.Client.HasPermission(ClientPermissions.ManageRound) ||
|
||||
GameMain.Client.HasPermission(ClientPermissions.ManageCampaign);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -867,21 +860,18 @@ namespace Barotrauma
|
||||
spectateButton.Enabled = true;
|
||||
}
|
||||
|
||||
public void SetCampaignCharacterInfo(CharacterInfo newCampaignCharacterInfo)
|
||||
{
|
||||
if (newCampaignCharacterInfo != null)
|
||||
public void SetCampaignCharacterInfo(CharacterInfo characterInfo)
|
||||
{
|
||||
if (CampaignCharacterDiscarded) return;
|
||||
|
||||
campaignCharacterInfo = characterInfo;
|
||||
if (campaignCharacterInfo != null)
|
||||
{
|
||||
if (CampaignCharacterDiscarded) { return; }
|
||||
if (campaignCharacterInfo != newCampaignCharacterInfo)
|
||||
{
|
||||
campaignCharacterInfo = newCampaignCharacterInfo;
|
||||
UpdatePlayerFrame(campaignCharacterInfo, false);
|
||||
}
|
||||
UpdatePlayerFrame(campaignCharacterInfo, false);
|
||||
}
|
||||
else if (campaignCharacterInfo != null)
|
||||
else
|
||||
{
|
||||
campaignCharacterInfo = null;
|
||||
UpdatePlayerFrame(campaignCharacterInfo, false);
|
||||
UpdatePlayerFrame(null, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -337,24 +337,7 @@ namespace Barotrauma
|
||||
var tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowLighting"))
|
||||
{
|
||||
Selected = lightingEnabled,
|
||||
OnSelected = (GUITickBox obj) =>
|
||||
{
|
||||
lightingEnabled = obj.Selected;
|
||||
if (lightingEnabled)
|
||||
{
|
||||
//turn off lights that are inside containers
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
foreach (LightComponent lightComponent in item.GetComponents<LightComponent>())
|
||||
{
|
||||
lightComponent.Light.Color = item.Container != null || (item.body != null && !item.body.Enabled) ?
|
||||
Color.Transparent :
|
||||
lightComponent.LightColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
OnSelected = (GUITickBox obj) => { lightingEnabled = obj.Selected; return true; }
|
||||
};
|
||||
tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowWalls"))
|
||||
{
|
||||
@@ -581,9 +564,6 @@ namespace Barotrauma
|
||||
|
||||
MapEntityPrefab.Selected = null;
|
||||
|
||||
saveFrame = null;
|
||||
loadFrame = null;
|
||||
|
||||
MapEntity.DeselectAll();
|
||||
MapEntity.SelectionGroups.Clear();
|
||||
|
||||
@@ -786,20 +766,6 @@ namespace Barotrauma
|
||||
savePath = Path.Combine(Submarine.SavePath, savePath);
|
||||
}
|
||||
|
||||
#if !DEBUG
|
||||
var vanilla = GameMain.VanillaContent;
|
||||
if (vanilla != null)
|
||||
{
|
||||
var vanillaSubs = vanilla.GetFilesOfType(ContentType.Submarine);
|
||||
string pathToCompare = savePath.Replace(@"\", @"/").ToLowerInvariant();
|
||||
if (vanillaSubs.Any(sub => sub.Replace(@"\", @"/").ToLowerInvariant() == pathToCompare))
|
||||
{
|
||||
GUI.AddMessage(TextManager.Get("CannotEditVanillaSubs"), Color.Red, font: GUI.LargeFont);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*foreach (var contentPackage in GameMain.Config.SelectedContentPackages)
|
||||
{
|
||||
Submarine.MainSub.RequiredContentPackages.Add(contentPackage.Name);
|
||||
@@ -2074,10 +2040,6 @@ namespace Barotrauma
|
||||
dummyCharacter.SelectedConstruction = null;
|
||||
}
|
||||
}
|
||||
else if (MapEntity.SelectedList.Count == 1)
|
||||
{
|
||||
(MapEntity.SelectedList[0] as Item)?.UpdateHUD(cam, dummyCharacter, (float)deltaTime);
|
||||
}
|
||||
|
||||
CharacterHUD.Update((float)deltaTime, dummyCharacter, cam);
|
||||
}
|
||||
|
||||
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.8.9.8")]
|
||||
[assembly: AssemblyFileVersion("0.8.9.8")]
|
||||
[assembly: AssemblyVersion("0.8.9.6")]
|
||||
[assembly: AssemblyFileVersion("0.8.9.6")]
|
||||
|
||||
@@ -20,10 +20,8 @@ namespace Barotrauma
|
||||
if (Job != null)
|
||||
{
|
||||
msg.Write(Job.Prefab.Identifier);
|
||||
msg.Write((byte)Job.Skills.Count);
|
||||
foreach (Skill skill in Job.Skills)
|
||||
{
|
||||
msg.Write(skill.Identifier);
|
||||
msg.Write(skill.Level);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@ namespace Barotrauma
|
||||
|
||||
private bool networkUpdateSent;
|
||||
|
||||
private double LastInputTime;
|
||||
|
||||
public float GetPositionUpdateInterval(Client recipient)
|
||||
{
|
||||
if (!Enabled) { return 1000.0f; }
|
||||
@@ -63,15 +61,6 @@ namespace Barotrauma
|
||||
else if (memInput.Count == 0)
|
||||
{
|
||||
AnimController.Frozen = true;
|
||||
if (Timing.TotalTime > LastInputTime + 0.5)
|
||||
{
|
||||
//no inputs have been received in 0.5 seconds, reset input
|
||||
//(if there's a temporary network hiccup that prevents us from receiving inputs, we assume the inputs haven't changed,
|
||||
//but if it takes too long, for example due to a client crashing/disconnecting, we don't want to keep the character
|
||||
//firing a welding tool or whatever else they were doing until the kill disconnect timer kicks in)
|
||||
prevDequeuedInput = dequeuedInput =
|
||||
dequeuedInput.HasFlag(InputNetFlags.FacingLeft) ? InputNetFlags.FacingLeft : InputNetFlags.None;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -201,7 +190,6 @@ namespace Barotrauma
|
||||
networkUpdateID = (ushort)(networkUpdateID - i)
|
||||
};
|
||||
memInput.Insert(i, newMem);
|
||||
LastInputTime = Timing.TotalTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,11 +11,11 @@ namespace Barotrauma
|
||||
{
|
||||
private List<CharacterCampaignData> characterData = new List<CharacterCampaignData>();
|
||||
|
||||
public static void StartNewCampaign(string savePath, string subPath, string seed)
|
||||
public static void StartNewCampaign(string savePath, string subName, string seed)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(savePath)) return;
|
||||
|
||||
GameMain.GameSession = new GameSession(new Submarine(subPath, ""), savePath,
|
||||
GameMain.GameSession = new GameSession(new Submarine(subName, ""), savePath,
|
||||
GameModePreset.List.Find(g => g.Identifier == "multiplayercampaign"));
|
||||
var campaign = ((MultiPlayerCampaign)GameMain.GameSession.GameMode);
|
||||
campaign.GenerateMap(seed);
|
||||
@@ -251,7 +251,6 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
lastSaveID++;
|
||||
DebugConsole.Log("Campaign saved, save ID " + lastSaveID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
using Barotrauma.Networking;
|
||||
using Lidgren.Network;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
@@ -10,16 +14,5 @@ namespace Barotrauma.Items.Components
|
||||
//let the clients know the initial deterioration delay
|
||||
item.CreateServerEvent(this);
|
||||
}
|
||||
|
||||
public void ServerRead(ClientNetObject type, NetBuffer msg, Client c)
|
||||
{
|
||||
if (c.Character == null) return;
|
||||
StartRepairing(c.Character);
|
||||
}
|
||||
|
||||
public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null)
|
||||
{
|
||||
msg.Write(deteriorationTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,16 +20,6 @@ namespace Barotrauma
|
||||
partial void UpdateProjSpecific(float deltaTime, Camera cam)
|
||||
{
|
||||
if (IdFreed) { return; }
|
||||
|
||||
//don't create updates if all clients are very far from the hull
|
||||
float hullUpdateDistanceSqr = NetConfig.HullUpdateDistance * NetConfig.HullUpdateDistance;
|
||||
if (!GameMain.Server.ConnectedClients.Any(c =>
|
||||
c.Character != null &&
|
||||
Vector2.DistanceSquared(c.Character.WorldPosition, WorldPosition) < hullUpdateDistanceSqr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//update client hulls if the amount of water has changed by >10%
|
||||
//or if oxygen percentage has changed by 5%
|
||||
if (Math.Abs(lastSentVolume - waterVolume) > Volume * 0.1f ||
|
||||
@@ -41,8 +31,8 @@ namespace Barotrauma
|
||||
GameMain.NetworkMember.CreateEntityEvent(this);
|
||||
lastSentVolume = waterVolume;
|
||||
lastSentOxygen = OxygenPercentage;
|
||||
sendUpdateTimer = NetConfig.HullUpdateInterval;
|
||||
}
|
||||
sendUpdateTimer = NetworkUpdateInterval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
//when was a specific entity event last sent to the client
|
||||
// key = event id, value = NetTime.Now when sending
|
||||
public readonly Dictionary<UInt16, double> EntityEventLastSent = new Dictionary<UInt16, double>();
|
||||
public readonly Dictionary<UInt16, float> EntityEventLastSent = new Dictionary<UInt16, float>();
|
||||
|
||||
//when was a position update for a given entity last sent to the client
|
||||
// key = entity id, value = NetTime.Now when sending
|
||||
|
||||
@@ -187,7 +187,7 @@ namespace Barotrauma.Networking
|
||||
transfer.WaitTimer -= deltaTime;
|
||||
if (transfer.WaitTimer > 0.0f) continue;
|
||||
|
||||
if (!transfer.Connection.CanSendImmediately(NetDeliveryMethod.ReliableOrdered, transfer.SequenceChannel)) continue;
|
||||
if (!transfer.Connection.CanSendImmediately(NetDeliveryMethod.ReliableOrdered, 1)) continue;
|
||||
|
||||
transfer.WaitTimer = 0.05f;// transfer.Connection.AverageRoundtripTime;
|
||||
|
||||
@@ -202,6 +202,15 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
message = peer.CreateMessage();
|
||||
message.Write((byte)ServerPacketHeader.FILE_TRANSFER);
|
||||
message.Write((byte)FileTransferMessageType.Initiate);
|
||||
message.Write((byte)transfer.FileType);
|
||||
message.Write((ushort)chunkLen);
|
||||
message.Write((ulong)transfer.Data.Length);
|
||||
message.Write(transfer.FileName);
|
||||
GameMain.Server.CompressOutgoingMessage(message);
|
||||
transfer.Connection.SendMessage(message, NetDeliveryMethod.ReliableOrdered, transfer.SequenceChannel);
|
||||
|
||||
transfer.Status = FileTransferStatus.Sending;
|
||||
|
||||
//if the recipient is the owner of the server (= a client running the server from the main exe)
|
||||
//we don't need to send anything, the client can just read the file directly
|
||||
|
||||
@@ -10,7 +10,6 @@ using System.Text;
|
||||
using System.IO.Compression;
|
||||
using System.IO;
|
||||
using Barotrauma.Steam;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
@@ -716,25 +715,23 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
string savePath = inc.ReadString();
|
||||
string seed = inc.ReadString();
|
||||
string subName = inc.ReadString();
|
||||
string subHash = inc.ReadString();
|
||||
string subPath = inc.ReadString();
|
||||
|
||||
var matchingSub = Submarine.SavedSubmarines.FirstOrDefault(s => s.Name == subName && s.MD5Hash.Hash == subHash);
|
||||
|
||||
if (matchingSub == null)
|
||||
if (!File.Exists(subPath))
|
||||
{
|
||||
SendDirectChatMessage(
|
||||
TextManager.Get("CampaignStartFailedSubNotFound").Replace("[subname]", subName),
|
||||
TextManager.Get("CampaignStartFailedSubNotFound").Replace("[subpath]", subPath),
|
||||
connectedClient, ChatMessageType.MessageBox);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (connectedClient.HasPermission(ClientPermissions.SelectMode)) MultiPlayerCampaign.StartNewCampaign(savePath, matchingSub.FilePath, seed);
|
||||
if (connectedClient.HasPermission(ClientPermissions.SelectMode)) MultiPlayerCampaign.StartNewCampaign(savePath, subPath, seed);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string saveName = inc.ReadString();
|
||||
|
||||
if (connectedClient.HasPermission(ClientPermissions.SelectMode)) MultiPlayerCampaign.LoadCampaign(saveName);
|
||||
}
|
||||
break;
|
||||
@@ -814,16 +811,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
Log(c.Name + " has reported an error: " + errorStr, ServerLog.MessageType.Error);
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameServer.HandleClientError:LevelsDontMatch" + error, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorStr);
|
||||
|
||||
if (c.Connection == OwnerConnection)
|
||||
{
|
||||
SendDirectChatMessage(errorStr, c, ChatMessageType.MessageBox);
|
||||
EndGame();
|
||||
}
|
||||
else
|
||||
{
|
||||
KickClient(c, errorStr);
|
||||
}
|
||||
KickClient(c, errorStr);
|
||||
}
|
||||
|
||||
public override void CreateEntityEvent(INetSerializable entity, object[] extraData = null)
|
||||
@@ -1040,7 +1028,7 @@ namespace Barotrauma.Networking
|
||||
if (command == ClientPermissions.ManageRound && inc.PeekBoolean() &&
|
||||
GameMain.GameSession?.GameMode is MultiPlayerCampaign mpCampaign)
|
||||
{
|
||||
if (!mpCampaign.AllowedToEndRound(sender.Character) && !sender.HasPermission(command))
|
||||
if (!mpCampaign.AllowedToEndRound(sender.Character))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1126,22 +1114,9 @@ namespace Barotrauma.Networking
|
||||
UInt16 modeIndex = inc.ReadUInt16();
|
||||
if (GameMain.NetLobbyScreen.GameModes[modeIndex].Identifier.ToLowerInvariant() == "multiplayercampaign")
|
||||
{
|
||||
string[] saveFiles = SaveUtil.GetSaveFiles(SaveUtil.SaveType.Multiplayer);
|
||||
for (int i = 0; i < saveFiles.Length; i++)
|
||||
{
|
||||
XDocument doc = SaveUtil.LoadGameSessionDoc(saveFiles[i]);
|
||||
if (doc?.Root != null)
|
||||
{
|
||||
saveFiles[i] =
|
||||
string.Join(";",
|
||||
saveFiles[i].Replace(';', ' '),
|
||||
doc.Root.GetAttributeString("submarine", ""),
|
||||
doc.Root.GetAttributeString("savetime", ""));
|
||||
}
|
||||
}
|
||||
|
||||
NetOutgoingMessage msg = server.CreateMessage();
|
||||
msg.Write((byte)ServerPacketHeader.CAMPAIGN_SETUP_INFO);
|
||||
string[] saveFiles = SaveUtil.GetSaveFiles(SaveUtil.SaveType.Multiplayer);
|
||||
msg.Write((UInt16)saveFiles.Count());
|
||||
foreach (string saveFile in saveFiles)
|
||||
{
|
||||
@@ -1226,7 +1201,6 @@ namespace Barotrauma.Networking
|
||||
ClientWriteLobby(c);
|
||||
|
||||
if (GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign &&
|
||||
GameMain.NetLobbyScreen.SelectedMode == campaign.Preset &&
|
||||
NetIdUtils.IdMoreRecent(campaign.LastSaveID, c.LastRecvCampaignSave))
|
||||
{
|
||||
//already sent an up-to-date campaign save
|
||||
@@ -1361,6 +1335,10 @@ namespace Barotrauma.Networking
|
||||
WriteClientList(c, outmsg);
|
||||
clientListBytes = outmsg.LengthBytes - clientListBytes;
|
||||
|
||||
int eventManagerBytes = outmsg.LengthBytes;
|
||||
entityEventManager.Write(c, outmsg, out List<NetEntityEvent> sentEvents);
|
||||
eventManagerBytes = outmsg.LengthBytes - eventManagerBytes;
|
||||
|
||||
int chatMessageBytes = outmsg.LengthBytes;
|
||||
WriteChatMessages(outmsg, c);
|
||||
chatMessageBytes = outmsg.LengthBytes - chatMessageBytes;
|
||||
@@ -1370,8 +1348,7 @@ namespace Barotrauma.Networking
|
||||
while (!c.NeedsMidRoundSync && c.PendingPositionUpdates.Count > 0)
|
||||
{
|
||||
var entity = c.PendingPositionUpdates.Peek();
|
||||
if (entity == null || entity.Removed ||
|
||||
(entity is Item item && item.PositionUpdateInterval == float.PositiveInfinity))
|
||||
if (entity == null || entity.Removed)
|
||||
{
|
||||
c.PendingPositionUpdates.Dequeue();
|
||||
continue;
|
||||
@@ -1410,55 +1387,25 @@ namespace Barotrauma.Networking
|
||||
errorMsg +=
|
||||
" Client list size: " + clientListBytes + " bytes\n" +
|
||||
" Chat message size: " + chatMessageBytes + " bytes\n" +
|
||||
" Event size: " + eventManagerBytes + " bytes\n" +
|
||||
" Position update size: " + positionUpdateBytes + " bytes\n\n";
|
||||
|
||||
if (sentEvents != null && sentEvents.Count > 0)
|
||||
{
|
||||
errorMsg += "Sent events: \n";
|
||||
foreach (var entityEvent in sentEvents)
|
||||
{
|
||||
errorMsg += " - " + (entityEvent.Entity?.ToString() ?? "null") + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameServer.ClientWriteIngame1:PacketSizeExceeded" + outmsg.LengthBytes, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameServer.ClientWriteIngame:PacketSizeExceeded" + outmsg.LengthBytes, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
}
|
||||
|
||||
CompressOutgoingMessage(outmsg);
|
||||
|
||||
server.SendMessage(outmsg, c.Connection, NetDeliveryMethod.Unreliable);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
for (int i = 0; i < NetConfig.MaxEventPacketsPerUpdate; i++)
|
||||
{
|
||||
outmsg = server.CreateMessage();
|
||||
outmsg.Write((byte)ServerPacketHeader.UPDATE_INGAME);
|
||||
outmsg.Write((float)NetTime.Now);
|
||||
|
||||
int eventManagerBytes = outmsg.LengthBytes;
|
||||
entityEventManager.Write(c, outmsg, out List<NetEntityEvent> sentEvents);
|
||||
eventManagerBytes = outmsg.LengthBytes - eventManagerBytes;
|
||||
|
||||
if (sentEvents.Count == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
outmsg.Write((byte)ServerNetObject.END_OF_MESSAGE);
|
||||
|
||||
if (outmsg.LengthBytes > NetPeerConfiguration.MaximumTransmissionUnit)
|
||||
{
|
||||
string errorMsg = "Maximum packet size exceeded (" + outmsg.LengthBytes + " > " + NetPeerConfiguration.MaximumTransmissionUnit + ")\n";
|
||||
errorMsg +=
|
||||
" Event size: " + eventManagerBytes + " bytes\n";
|
||||
|
||||
if (sentEvents != null && sentEvents.Count > 0)
|
||||
{
|
||||
errorMsg += "Sent events: \n";
|
||||
foreach (var entityEvent in sentEvents)
|
||||
{
|
||||
errorMsg += " - " + (entityEvent.Entity?.ToString() ?? "null") + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameServer.ClientWriteIngame2:PacketSizeExceeded" + outmsg.LengthBytes, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
}
|
||||
|
||||
CompressOutgoingMessage(outmsg);
|
||||
server.SendMessage(outmsg, c.Connection, NetDeliveryMethod.Unreliable);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteClientList(Client c, NetOutgoingMessage outmsg)
|
||||
@@ -1545,8 +1492,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
var campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;
|
||||
if (campaign != null && campaign.Preset == GameMain.NetLobbyScreen.SelectedMode &&
|
||||
NetIdUtils.IdMoreRecent(campaign.LastUpdateID, c.LastRecvCampaignUpdate))
|
||||
if (campaign != null && NetIdUtils.IdMoreRecent(campaign.LastUpdateID, c.LastRecvCampaignUpdate))
|
||||
{
|
||||
outmsg.Write(true);
|
||||
outmsg.WritePadBits();
|
||||
|
||||
@@ -164,7 +164,7 @@ namespace Barotrauma.Networking
|
||||
if (connectedClient != null)
|
||||
{
|
||||
Log("Disconnecting client " + connectedClient.Name + " (Steam ID: " + steamID + "). Steam authentication no longer valid (" + status + ").", ServerLog.MessageType.ServerMessage);
|
||||
KickClient(connectedClient, $"DisconnectMessage.SteamAuthNoLongerValid~[status]={status.ToString()}");
|
||||
KickClient(connectedClient, $"DisconnectMessage.SteamAuthNoLongerValid_[status]={status.ToString()}");
|
||||
}
|
||||
}*/
|
||||
}
|
||||
@@ -342,7 +342,7 @@ namespace Barotrauma.Networking
|
||||
if (clVersion != GameMain.Version.ToString())
|
||||
{
|
||||
DisconnectUnauthClient(inc, unauthClient, DisconnectReason.InvalidVersion,
|
||||
$"DisconnectMessage.InvalidVersion~[version]={GameMain.Version.ToString()}~[clientversion]={clVersion}");
|
||||
$"DisconnectMessage.InvalidVersion_[version]={GameMain.Version.ToString()}_[clientversion]={clVersion}");
|
||||
|
||||
Log(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (wrong game version)", ServerLog.MessageType.Error);
|
||||
DebugConsole.NewMessage(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (wrong game version)", Color.Red);
|
||||
@@ -368,7 +368,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (missingPackages.Count == 1)
|
||||
{
|
||||
DisconnectUnauthClient(inc, unauthClient, DisconnectReason.MissingContentPackage, $"DisconnectMessage.MissingContentPackage~[missingcontentpackage]={GetPackageStr(missingPackages[0])}");
|
||||
DisconnectUnauthClient(inc, unauthClient, DisconnectReason.MissingContentPackage, $"DisconnectMessage.MissingContentPackage_[missingcontentpackage]={GetPackageStr(missingPackages[0])}");
|
||||
Log(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (missing content package " + GetPackageStr(missingPackages[0]) + ")", ServerLog.MessageType.Error);
|
||||
return;
|
||||
}
|
||||
@@ -376,7 +376,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
List<string> packageStrs = new List<string>();
|
||||
missingPackages.ForEach(cp => packageStrs.Add(GetPackageStr(cp)));
|
||||
DisconnectUnauthClient(inc, unauthClient, DisconnectReason.MissingContentPackage, $"DisconnectMessage.MissingContentPackages~[missingcontentpackages]={string.Join(", ", packageStrs)}");
|
||||
DisconnectUnauthClient(inc, unauthClient, DisconnectReason.MissingContentPackage, $"DisconnectMessage.MissingContentPackages_[missingcontentpackages]={string.Join(", ", packageStrs)}");
|
||||
Log(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (missing content packages " + string.Join(", ", packageStrs) + ")", ServerLog.MessageType.Error);
|
||||
return;
|
||||
}
|
||||
@@ -399,7 +399,7 @@ namespace Barotrauma.Networking
|
||||
if (incompatiblePackages.Count == 1)
|
||||
{
|
||||
DisconnectUnauthClient(inc, unauthClient, DisconnectReason.IncompatibleContentPackage,
|
||||
$"DisconnectMessage.IncompatibleContentPackage~[incompatiblecontentpackage]={GetPackageStr2(incompatiblePackages[0])}");
|
||||
$"DisconnectMessage.IncompatibleContentPackage_[incompatiblecontentpackage]={GetPackageStr2(incompatiblePackages[0])}");
|
||||
Log(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (incompatible content package " + GetPackageStr2(incompatiblePackages[0]) + ")", ServerLog.MessageType.Error);
|
||||
return;
|
||||
}
|
||||
@@ -408,7 +408,7 @@ namespace Barotrauma.Networking
|
||||
List<string> packageStrs = new List<string>();
|
||||
incompatiblePackages.ForEach(cp => packageStrs.Add(GetPackageStr2(cp)));
|
||||
DisconnectUnauthClient(inc, unauthClient, DisconnectReason.IncompatibleContentPackage,
|
||||
$"DisconnectMessage.IncompatibleContentPackages~[incompatiblecontentpackages]={string.Join(", ", packageStrs)}");
|
||||
$"DisconnectMessage.IncompatibleContentPackages_[incompatiblecontentpackages]={string.Join(", ", packageStrs)}");
|
||||
Log(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (incompatible content packages " + string.Join(", ", packageStrs) + ")", ServerLog.MessageType.Error);
|
||||
return;
|
||||
}
|
||||
@@ -494,21 +494,13 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else
|
||||
{
|
||||
var defaultPerms = PermissionPreset.List.Find(p => p.Name == "None");
|
||||
if (defaultPerms != null)
|
||||
{
|
||||
newClient.SetPermissions(defaultPerms.Permissions, defaultPerms.PermittedCommands);
|
||||
}
|
||||
else
|
||||
{
|
||||
newClient.SetPermissions(ClientPermissions.None, new List<DebugConsole.Command>());
|
||||
}
|
||||
newClient.SetPermissions(ClientPermissions.None, new List<DebugConsole.Command>());
|
||||
}
|
||||
}
|
||||
|
||||
private void DisconnectUnauthClient(NetIncomingMessage inc, UnauthenticatedClient unauthClient, DisconnectReason reason, string message)
|
||||
{
|
||||
inc.SenderConnection.Disconnect(reason.ToString() + "/ " + TextManager.GetServerMessage(message));
|
||||
inc.SenderConnection.Disconnect(reason.ToString() + "/ " + message);
|
||||
if (unauthClient.SteamID > 0) { Steam.SteamManager.StopAuthSession(unauthClient.SteamID); }
|
||||
if (unauthClient != null)
|
||||
{
|
||||
|
||||
+22
-9
@@ -228,7 +228,7 @@ namespace Barotrauma.Networking
|
||||
GameServer.Log("Disconnecting client " + c.Name + " due to excessive desync (expected old event "
|
||||
+ (c.LastRecvEntityEventID + 1).ToString() +
|
||||
" (created " + (Timing.TotalTime - firstEventToResend.CreateTime).ToString("0.##") + " s ago)" +
|
||||
" Events queued: " + events.Count + ", last sent to all: " + lastSentToAll, ServerLog.MessageType.Error);
|
||||
" Events queued: " + events.Count + ", last sent to all: " + lastSentToAll, ServerLog.MessageType.ServerMessage);
|
||||
server.DisconnectClient(c, "", "ServerMessage.ExcessiveDesyncOldEvent");
|
||||
}
|
||||
);
|
||||
@@ -242,7 +242,7 @@ namespace Barotrauma.Networking
|
||||
toKick.ForEach(c =>
|
||||
{
|
||||
DebugConsole.NewMessage(c.Name + " was kicked due to excessive desync (expected removed event " + (c.LastRecvEntityEventID + 1).ToString() + ", last available is " + events[0].ID.ToString() + ")", Color.Red);
|
||||
GameServer.Log("Disconnecting client " + c.Name + " due to excessive desync (expected removed event " + (c.LastRecvEntityEventID + 1).ToString() + ", last available is " + events[0].ID.ToString() + ")", ServerLog.MessageType.Error);
|
||||
GameServer.Log("Disconnecting client " + c.Name + " due to excessive desync (expected removed event " + (c.LastRecvEntityEventID + 1).ToString() + ", last available is " + events[0].ID.ToString() + ")", ServerLog.MessageType.ServerMessage);
|
||||
server.DisconnectClient(c, "", "ServerMessage.ExcessiveDesyncRemovedEvent");
|
||||
});
|
||||
}
|
||||
@@ -251,7 +251,7 @@ namespace Barotrauma.Networking
|
||||
var timedOutClients = clients.FindAll(c => c.InGame && c.NeedsMidRoundSync && Timing.TotalTime > c.MidRoundSyncTimeOut);
|
||||
foreach (Client timedOutClient in timedOutClients)
|
||||
{
|
||||
GameServer.Log("Disconnecting client " + timedOutClient.Name + ". Syncing the client with the server took too long.", ServerLog.MessageType.Error);
|
||||
GameServer.Log("Disconnecting client " + timedOutClient.Name + ". Syncing the client with the server took too long.", ServerLog.MessageType.ServerMessage);
|
||||
GameMain.Server.DisconnectClient(timedOutClient, "", "ServerMessage.SyncTimeout");
|
||||
}
|
||||
|
||||
@@ -305,7 +305,19 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
//too many events for one packet
|
||||
if (eventsToSync.Count > 200)
|
||||
if (eventsToSync.Count > MaxEventsPerWrite)
|
||||
{
|
||||
if (eventsToSync.Count > MaxEventsPerWrite * 3 && !client.NeedsMidRoundSync)
|
||||
{
|
||||
Color color = eventsToSync.Count > MaxEventsPerWrite * 20 ? Color.Red : Color.Orange;
|
||||
if (eventsToSync.Count < MaxEventsPerWrite * 5) { color = Color.Yellow; }
|
||||
DebugConsole.NewMessage("WARNING: event count very high: " + eventsToSync.Count + "/" + MaxEventsPerWrite, color);
|
||||
}
|
||||
|
||||
eventsToSync.RemoveRange(MaxEventsPerWrite, eventsToSync.Count - MaxEventsPerWrite);
|
||||
}
|
||||
|
||||
foreach (NetEntityEvent entityEvent in eventsToSync)
|
||||
{
|
||||
if (eventsToSync.Count > 200 && !client.NeedsMidRoundSync)
|
||||
{
|
||||
@@ -338,7 +350,7 @@ namespace Barotrauma.Networking
|
||||
msg.Write(client.UnreceivedEntityEventCount);
|
||||
msg.Write(client.FirstNewEventID);
|
||||
|
||||
Write(msg, eventsToSync, out sentEvents, client);
|
||||
Write(msg, eventsToSync, client);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -351,6 +363,7 @@ namespace Barotrauma.Networking
|
||||
(entityEvent as ServerEntityEvent).Sent = true;
|
||||
client.EntityEventLastSent[entityEvent.ID] = NetTime.Now;
|
||||
}
|
||||
sentEvents = eventsToSync;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -374,10 +387,10 @@ namespace Barotrauma.Networking
|
||||
|
||||
for (int i = startIndex; i < eventList.Count; i++)
|
||||
{
|
||||
//find the first event that hasn't been sent in roundtriptime or at all
|
||||
client.EntityEventLastSent.TryGetValue(eventList[i].ID, out double lastSent);
|
||||
//find the first event that hasn't been sent in 1.5 * roundtriptime or at all
|
||||
client.EntityEventLastSent.TryGetValue(eventList[i].ID, out float lastSent);
|
||||
|
||||
float minInterval = Math.Max(client.Connection.AverageRoundtripTime, (float)server.UpdateInterval.TotalSeconds * 2);
|
||||
float minInterval = Math.Max(client.Connection.AverageRoundtripTime * 1.5f, (float)server.UpdateInterval.TotalSeconds * 2);
|
||||
|
||||
if (lastSent > NetTime.Now - Math.Min(minInterval, 0.5f))
|
||||
{
|
||||
@@ -403,7 +416,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else
|
||||
{
|
||||
double midRoundSyncTimeOut = uniqueEvents.Count / 100 * server.UpdateInterval.TotalSeconds;
|
||||
double midRoundSyncTimeOut = uniqueEvents.Count / MaxEventsPerWrite * server.UpdateInterval.TotalSeconds;
|
||||
midRoundSyncTimeOut = Math.Max(10.0f, midRoundSyncTimeOut * 10.0f);
|
||||
|
||||
client.UnreceivedEntityEventCount = (UInt16)uniqueEvents.Count;
|
||||
|
||||
@@ -337,56 +337,37 @@ namespace Barotrauma.Networking
|
||||
continue;
|
||||
}
|
||||
|
||||
string permissionsStr = clientElement.GetAttributeString("permissions", "");
|
||||
ClientPermissions permissions = Networking.ClientPermissions.None;
|
||||
List<DebugConsole.Command> permittedCommands = new List<DebugConsole.Command>();
|
||||
|
||||
if (clientElement.Attribute("preset") == null)
|
||||
if (permissionsStr.ToLowerInvariant() == "all")
|
||||
{
|
||||
string permissionsStr = clientElement.GetAttributeString("permissions", "");
|
||||
if (permissionsStr.ToLowerInvariant() == "all")
|
||||
foreach (ClientPermissions permission in Enum.GetValues(typeof(ClientPermissions)))
|
||||
{
|
||||
foreach (ClientPermissions permission in Enum.GetValues(typeof(ClientPermissions)))
|
||||
{
|
||||
permissions |= permission;
|
||||
}
|
||||
}
|
||||
else if (!Enum.TryParse(permissionsStr, out permissions))
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + ClientPermissionsFile + " - \"" + permissionsStr + "\" is not a valid client permission.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (permissions.HasFlag(Networking.ClientPermissions.ConsoleCommands))
|
||||
{
|
||||
foreach (XElement commandElement in clientElement.Elements())
|
||||
{
|
||||
if (commandElement.Name.ToString().ToLowerInvariant() != "command") continue;
|
||||
|
||||
string commandName = commandElement.GetAttributeString("name", "");
|
||||
DebugConsole.Command command = DebugConsole.FindCommand(commandName);
|
||||
if (command == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + ClientPermissionsFile + " - \"" + commandName + "\" is not a valid console command.");
|
||||
continue;
|
||||
}
|
||||
|
||||
permittedCommands.Add(command);
|
||||
}
|
||||
permissions |= permission;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (!Enum.TryParse(permissionsStr, out permissions))
|
||||
{
|
||||
string presetName = clientElement.GetAttributeString("preset", "");
|
||||
PermissionPreset preset = PermissionPreset.List.Find(p => p.Name == presetName);
|
||||
if (preset == null)
|
||||
DebugConsole.ThrowError("Error in " + ClientPermissionsFile + " - \"" + permissionsStr + "\" is not a valid client permission.");
|
||||
continue;
|
||||
}
|
||||
|
||||
List<DebugConsole.Command> permittedCommands = new List<DebugConsole.Command>();
|
||||
if (permissions.HasFlag(Networking.ClientPermissions.ConsoleCommands))
|
||||
{
|
||||
foreach (XElement commandElement in clientElement.Elements())
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to restore saved permissions to the client \"" + clientName + "\". Permission preset \"" + presetName + "\" not found.");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
permissions = preset.Permissions;
|
||||
permittedCommands = preset.PermittedCommands.ToList();
|
||||
if (commandElement.Name.ToString().ToLowerInvariant() != "command") continue;
|
||||
|
||||
string commandName = commandElement.GetAttributeString("name", "");
|
||||
DebugConsole.Command command = DebugConsole.FindCommand(commandName);
|
||||
if (command == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + ClientPermissionsFile + " - \"" + commandName + "\" is not a valid console command.");
|
||||
continue;
|
||||
}
|
||||
|
||||
permittedCommands.Add(command);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,14 +440,9 @@ namespace Barotrauma.Networking
|
||||
|
||||
foreach (SavedClientPermission clientPermission in ClientPermissions)
|
||||
{
|
||||
var matchingPreset = PermissionPreset.List.Find(p => p.MatchesPermissions(clientPermission.Permissions, clientPermission.PermittedCommands));
|
||||
if (matchingPreset != null && matchingPreset.Name == "None")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
XElement clientElement = new XElement("Client",
|
||||
new XAttribute("name", clientPermission.Name));
|
||||
new XAttribute("name", clientPermission.Name),
|
||||
new XAttribute("permissions", clientPermission.Permissions.ToString()));
|
||||
|
||||
if (clientPermission.SteamID > 0)
|
||||
{
|
||||
@@ -477,21 +453,14 @@ namespace Barotrauma.Networking
|
||||
clientElement.Add(new XAttribute("ip", clientPermission.IP));
|
||||
}
|
||||
|
||||
if (matchingPreset == null)
|
||||
if (clientPermission.Permissions.HasFlag(Barotrauma.Networking.ClientPermissions.ConsoleCommands))
|
||||
{
|
||||
clientElement.Add(new XAttribute("permissions", clientPermission.Permissions.ToString()));
|
||||
if (clientPermission.Permissions.HasFlag(Networking.ClientPermissions.ConsoleCommands))
|
||||
foreach (DebugConsole.Command command in clientPermission.PermittedCommands)
|
||||
{
|
||||
foreach (DebugConsole.Command command in clientPermission.PermittedCommands)
|
||||
{
|
||||
clientElement.Add(new XElement("command", new XAttribute("name", command.names[0])));
|
||||
}
|
||||
clientElement.Add(new XElement("command", new XAttribute("name", command.names[0])));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
clientElement.Add(new XAttribute("preset", matchingPreset.Name));
|
||||
}
|
||||
|
||||
doc.Root.Add(clientElement);
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
<Character file="Content/Characters/Husk/Husk.xml" />
|
||||
<Character file="Content/Characters/Humanhusk/Humanhusk.xml" />
|
||||
<Character file="Content/Characters/Legacyhusk/Legacyhusk.xml" />
|
||||
<Character file="Content/Characters/Legacycharybdis/Legacycharybdis.xml" />
|
||||
<Character file="Content/Characters/Legacycrawler/Legacycrawler.xml" />
|
||||
<Character file="Content/Characters/Legacymoloch/Legacymoloch.xml" />
|
||||
<Character file="Content/Characters/Mudraptor/Mudraptor.xml" />
|
||||
@@ -71,11 +70,10 @@
|
||||
<Outpost file="Content/Map/Outposts/Outpost.sub" />
|
||||
<Submarine file="Submarines/Orca.sub" />
|
||||
<Submarine file="Submarines/Typhon.sub" />
|
||||
<Submarine file="Submarines/Selkie.sub" />
|
||||
<Submarine file="Submarines/Muikku.sub" />
|
||||
<Submarine file="Submarines/Bunyip.sub" />
|
||||
<Submarine file="Submarines/Humpback.sub" />
|
||||
<Submarine file="Submarines/Dugong.sub" />
|
||||
<Submarine file="Submarines/PAX.sub" />
|
||||
<Submarine file="Submarines/Remora.sub" />
|
||||
<Submarine file="Submarines/RemoraDrone.sub" />
|
||||
<Text file="Content/Texts/EnglishVanilla.xml" />
|
||||
|
||||
@@ -13,13 +13,6 @@
|
||||
<Command name="autorestart"/>
|
||||
<Command name="autorestartinterval"/>
|
||||
<Command name="autorestarttimer"/>
|
||||
<Command name="botcount"/>
|
||||
<Command name="botspawnmode"/>
|
||||
<Command name="gamemode"/>
|
||||
<Command name="sub"/>
|
||||
<Command name="shuttle"/>
|
||||
<Command name="water"/>
|
||||
<Command name="fire"/>
|
||||
<Command name="difficulty"/>
|
||||
<Command name="kick"/>
|
||||
<Command name="kickid"/>
|
||||
@@ -35,8 +28,6 @@
|
||||
<Command name="autorestart"/>
|
||||
<Command name="autorestartinterval"/>
|
||||
<Command name="autorestarttimer"/>
|
||||
<Command name="botcount"/>
|
||||
<Command name="botspawnmode"/>
|
||||
<Command name="difficulty"/>
|
||||
<Command name="kick"/>
|
||||
<Command name="kickid"/>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Carrier\Animations\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycharybdis\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Animations\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Coelanth\Animations\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycrawler\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Endworm\Animations\" />
|
||||
@@ -45,27 +45,12 @@
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Carrier\Ragdolls\CarrierDefaultRagdoll.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Animations\CharybdisSwimFast.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Animations\CharybdisSwimSlow.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Charybdis.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Charybdis.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Ragdolls\CharybdisDefaultRagdoll.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycharybdis\Legacycharybdis.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycharybdis\Ragdolls\LegacycharybdisDefaultRagdoll.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Coelanth\Coelanth.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
@@ -357,36 +342,6 @@
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Effects\waterbump.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\1_CommandReactor\BaroTutorial_CommandReactor.mp4">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\2_NavConsole\BaroTutorial_NavConsole.mp4">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\3_Flood\BaroTutorial_Flood.mp4">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\4_Reactor\BaroTutorial_Reactor.mp4">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\5_EnemyOnSonar\BaroTutorial_EnemyOnSonar.mp4">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\6_Degrading2\BaroTutorial_Degrading.mp4">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\7_Medical\BaroTutorial_Medical.mp4">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\8_Approach1\BaroTutorial_Approach.mp4">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\UI\tutorialAtlas.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<None Include="$(MSBuildThisFileDirectory)Content\Fonts\BebasNeue-Regular.otf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Fonts\NotoSans\LICENSE_OFL.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
@@ -942,13 +897,13 @@
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Carrier\Animations\CarrierSwimSlow.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycharybdis\charybdis.png">
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\charybdis.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycharybdis\Animations\LegacycharybdisSwimFast.xml">
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Animations\CharybdisSwimFast.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycharybdis\Animations\LegacycharybdisSwimSlow.xml">
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Animations\CharybdisSwimSlow.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Coelanth\Animations\CoelanthSwimFast.xml">
|
||||
@@ -2000,9 +1955,6 @@
|
||||
<Content Include="$(MSBuildThisFileDirectory)serversettings.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<None Include="$(MSBuildThisFileDirectory)Content\Items\Misc\GuitarClown.ogg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="$(MSBuildThisFileDirectory)Content\Characters\Carrier\CARRIER_alarmLoop.ogg">
|
||||
@@ -2404,7 +2356,7 @@
|
||||
<None Include="$(MSBuildThisFileDirectory)Content\Characters\Mudraptor\MUDRAPTOR_idle3.ogg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycharybdis\charybdisattack.ogg">
|
||||
<None Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\charybdisattack.ogg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)Content\Characters\Coelanth\attack1.ogg">
|
||||
@@ -3162,7 +3114,7 @@
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)Submarines\Muikku.sub">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)Submarines\Orca.sub">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
@@ -3182,9 +3134,6 @@
|
||||
<None Include="$(MSBuildThisFileDirectory)Submarines\RemoraDrone.sub">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)Submarines\Selkie.sub">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)Submarines\Typhon.sub">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace Barotrauma
|
||||
SonarLabel = element.GetAttributeString("sonarlabel", "");
|
||||
}
|
||||
|
||||
public AITarget(Entity e, float sightRange = -1, float soundRange = 0)
|
||||
public AITarget(Entity e)
|
||||
{
|
||||
Entity = e;
|
||||
if (sightRange < 0)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -193,7 +193,7 @@ namespace Barotrauma
|
||||
// is not attached or is attached to something else
|
||||
if (!IsAttached || IsAttached && attachJoints[0].BodyB == attachTargetBody)
|
||||
{
|
||||
if (Vector2.DistanceSquared(ConvertUnits.ToDisplayUnits(transformedAttachPos), enemyAI.AttackingLimb.WorldPosition) < enemyAI.AttackingLimb.attack.DamageRange * enemyAI.AttackingLimb.attack.DamageRange)
|
||||
if (Vector2.DistanceSquared(ConvertUnits.ToDisplayUnits(transformedAttachPos), enemyAI.AttackingLimb.WorldPosition) < enemyAI.AttackingLimb.attack.Range * enemyAI.AttackingLimb.attack.Range)
|
||||
{
|
||||
AttachToBody(character.AnimController.Collider, attachLimb, attachTargetBody, transformedAttachPos);
|
||||
}
|
||||
|
||||
+1
-2
@@ -115,8 +115,7 @@ namespace Barotrauma
|
||||
unreachable.Add(goToObjective.Target as Hull);
|
||||
}
|
||||
goToObjective = null;
|
||||
HumanAIController.ObjectiveManager.GetObjective<AIObjectiveIdle>().Wander(deltaTime);
|
||||
//SteeringManager.SteeringWander();
|
||||
SteeringManager.SteeringWander();
|
||||
}
|
||||
}
|
||||
else if (currentHull != null)
|
||||
|
||||
@@ -99,8 +99,7 @@ namespace Barotrauma
|
||||
FindTargetItem();
|
||||
if (targetItem == null || moveToTarget == null)
|
||||
{
|
||||
HumanAIController.ObjectiveManager.GetObjective<AIObjectiveIdle>().Wander(deltaTime);
|
||||
//SteeringManager.SteeringWander();
|
||||
SteeringManager.SteeringWander();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -98,64 +98,60 @@ namespace Barotrauma
|
||||
PathSteering.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (standStillTimer < -walkDuration)
|
||||
{
|
||||
standStillTimer = Rand.Range(standStillMin, standStillMax);
|
||||
}
|
||||
|
||||
//steer away from edges of the hull
|
||||
if (character.AnimController.CurrentHull != null && !character.IsClimbing)
|
||||
{
|
||||
standStillTimer = Rand.Range(standStillMin, standStillMax);
|
||||
}
|
||||
|
||||
Wander(deltaTime);
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentTarget != null)
|
||||
{
|
||||
character.AIController.SteeringManager.SteeringSeek(currentTarget.SimPosition);
|
||||
}
|
||||
}
|
||||
|
||||
public void Wander(float deltaTime)
|
||||
{
|
||||
//steer away from edges of the hull
|
||||
if (character.AnimController.CurrentHull != null && !character.IsClimbing)
|
||||
{
|
||||
float leftDist = character.Position.X - character.AnimController.CurrentHull.Rect.X;
|
||||
float rightDist = character.AnimController.CurrentHull.Rect.Right - character.Position.X;
|
||||
if (leftDist < WallAvoidDistance && rightDist < WallAvoidDistance)
|
||||
{
|
||||
if (Math.Abs(rightDist - leftDist) > WallAvoidDistance / 2)
|
||||
if (leftDist < WallAvoidDistance && rightDist < WallAvoidDistance)
|
||||
{
|
||||
PathSteering.SteeringManual(deltaTime, Vector2.UnitX * Math.Sign(rightDist - leftDist));
|
||||
if (Math.Abs(rightDist - leftDist) > WallAvoidDistance / 2)
|
||||
{
|
||||
PathSteering.SteeringManual(deltaTime, Vector2.UnitX * Math.Sign(rightDist - leftDist));
|
||||
}
|
||||
else
|
||||
{
|
||||
PathSteering.Reset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (leftDist < WallAvoidDistance)
|
||||
{
|
||||
PathSteering.SteeringManual(deltaTime, Vector2.UnitX * (WallAvoidDistance-leftDist) / WallAvoidDistance);
|
||||
PathSteering.WanderAngle = 0.0f;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
PathSteering.Reset();
|
||||
PathSteering.SteeringManual(deltaTime, -Vector2.UnitX * (WallAvoidDistance-rightDist) / WallAvoidDistance);
|
||||
PathSteering.WanderAngle = MathHelper.Pi;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (leftDist < WallAvoidDistance)
|
||||
|
||||
character.AIController.SteeringManager.SteeringWander();
|
||||
if (!character.IsClimbing && !character.AnimController.InWater)
|
||||
{
|
||||
//PathSteering.SteeringManual(deltaTime, Vector2.UnitX * (WallAvoidDistance - leftDist) / WallAvoidDistance);
|
||||
PathSteering.SteeringManual(deltaTime, Vector2.UnitX);
|
||||
PathSteering.WanderAngle = 0.0f;
|
||||
}
|
||||
else if (rightDist < WallAvoidDistance)
|
||||
{
|
||||
//PathSteering.SteeringManual(deltaTime, -Vector2.UnitX * (WallAvoidDistance - rightDist) / WallAvoidDistance);
|
||||
PathSteering.SteeringManual(deltaTime, -Vector2.UnitX);
|
||||
PathSteering.WanderAngle = MathHelper.Pi;
|
||||
}
|
||||
else
|
||||
{
|
||||
SteeringManager.SteeringWander();
|
||||
}
|
||||
//reset vertical steering to prevent dropping down from platforms etc
|
||||
character.AIController.SteeringManager.ResetY();
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
if (currentTarget != null)
|
||||
{
|
||||
SteeringManager.SteeringWander();
|
||||
}
|
||||
if (!character.IsClimbing && !character.AnimController.InWater)
|
||||
{
|
||||
//reset vertical steering to prevent dropping down from platforms etc
|
||||
character.AIController.SteeringManager.ResetY();
|
||||
character.AIController.SteeringManager.SteeringSeek(currentTarget.SimPosition);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -369,18 +369,9 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 transformedMovement = reverse ? -movement : movement;
|
||||
float movementAngle = MathUtils.VectorToAngle(transformedMovement) - MathHelper.PiOver2;
|
||||
float mainLimbAngle = 0;
|
||||
if (MainLimb.type == LimbType.Torso && TorsoAngle.HasValue)
|
||||
{
|
||||
mainLimbAngle = TorsoAngle.Value;
|
||||
}
|
||||
else if (MainLimb.type == LimbType.Head && HeadAngle.HasValue)
|
||||
{
|
||||
mainLimbAngle = HeadAngle.Value;
|
||||
}
|
||||
mainLimbAngle *= Dir;
|
||||
float movementAngle = MathUtils.VectorToAngle(movement) - MathHelper.PiOver2;
|
||||
|
||||
float mainLimbAngle = (MainLimb.type == LimbType.Torso ? TorsoAngle.Value : HeadAngle.Value) * Dir;
|
||||
while (MainLimb.Rotation - (movementAngle + mainLimbAngle) > MathHelper.Pi)
|
||||
{
|
||||
movementAngle += MathHelper.TwoPi;
|
||||
@@ -388,7 +379,7 @@ namespace Barotrauma
|
||||
while (MainLimb.Rotation - (movementAngle + mainLimbAngle) < -MathHelper.Pi)
|
||||
{
|
||||
movementAngle -= MathHelper.TwoPi;
|
||||
}
|
||||
}
|
||||
|
||||
if (CurrentSwimParams.RotateTowardsMovement)
|
||||
{
|
||||
@@ -412,6 +403,7 @@ namespace Barotrauma
|
||||
if (TailAngle.HasValue)
|
||||
{
|
||||
Limb tail = GetLimb(LimbType.Tail);
|
||||
//tail?.body.SmoothRotate(movementAngle + TailAngle.Value * Dir, TailTorque);
|
||||
if (tail != null)
|
||||
{
|
||||
SmoothRotateWithoutWrapping(tail, movementAngle + TailAngle.Value * Dir, MainLimb, TailTorque);
|
||||
@@ -421,10 +413,6 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
movementAngle = Dir > 0 ? -MathHelper.PiOver2 : MathHelper.PiOver2;
|
||||
if (reverse)
|
||||
{
|
||||
movementAngle = MathUtils.WrapAngleTwoPi(movementAngle - MathHelper.Pi);
|
||||
}
|
||||
if (MainLimb.type == LimbType.Head && HeadAngle.HasValue)
|
||||
{
|
||||
Collider.SmoothRotate(HeadAngle.Value * Dir, CurrentSwimParams.SteerTorque);
|
||||
@@ -454,7 +442,7 @@ namespace Barotrauma
|
||||
var waveAmplitude = Math.Abs(CurrentSwimParams.WaveAmplitude);
|
||||
if (waveLength > 0 && waveAmplitude > 0)
|
||||
{
|
||||
WalkPos -= transformedMovement.Length() / Math.Abs(waveLength);
|
||||
WalkPos -= movement.Length() / Math.Abs(waveLength);
|
||||
WalkPos = MathUtils.WrapAngleTwoPi(WalkPos);
|
||||
}
|
||||
|
||||
@@ -697,6 +685,12 @@ namespace Barotrauma
|
||||
|
||||
limb.body.ApplyForce(diff * (float)(Math.Sin(WalkPos) * Math.Sqrt(limb.Mass)) * 30.0f * animStrength);
|
||||
}
|
||||
while (referenceLimb.Rotation - angle < -MathHelper.TwoPi)
|
||||
{
|
||||
angle -= MathHelper.TwoPi;
|
||||
}
|
||||
|
||||
limb?.body.SmoothRotate(angle, torque, wrapAngle: false);
|
||||
}
|
||||
|
||||
private void SmoothRotateWithoutWrapping(Limb limb, float angle, Limb referenceLimb, float torque)
|
||||
|
||||
@@ -1463,6 +1463,11 @@ namespace Barotrauma
|
||||
targetRightHand.PullJointMaxForce = 5000.0f;
|
||||
}
|
||||
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient)
|
||||
{
|
||||
Collider.ResetDynamics();
|
||||
}
|
||||
|
||||
target.AnimController.IgnorePlatforms = true;
|
||||
}
|
||||
else
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ namespace Barotrauma
|
||||
public static string GetDefaultFolder(string speciesName) => $"Content/Characters/{speciesName.CapitaliseFirstInvariant()}/Animations/";
|
||||
public static string GetDefaultFile(string speciesName, AnimationType animType) => $"{GetFolder(speciesName)}{GetDefaultFileName(speciesName, animType)}.xml";
|
||||
|
||||
public static string GetFolder(string speciesName)
|
||||
protected static string GetFolder(string speciesName)
|
||||
{
|
||||
var folder = XMLExtensions.TryLoadXml(Character.GetConfigFile(speciesName))?.Root?.Element("animations")?.GetAttributeString("folder", string.Empty);
|
||||
if (string.IsNullOrEmpty(folder) || folder.ToLowerInvariant() == "default")
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ namespace Barotrauma
|
||||
new XAttribute("sourcerect", $"0, 0, 1, 1")))
|
||||
};
|
||||
|
||||
public static string GetFolder(string speciesName)
|
||||
protected static string GetFolder(string speciesName)
|
||||
{
|
||||
var folder = XMLExtensions.TryLoadXml(Character.GetConfigFile(speciesName))?.Root?.Element("ragdolls")?.GetAttributeString("folder", string.Empty);
|
||||
if (string.IsNullOrEmpty(folder) || folder.ToLowerInvariant() == "default")
|
||||
|
||||
@@ -1035,6 +1035,8 @@ namespace Barotrauma
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
UpdateNetPlayerPosition(deltaTime);
|
||||
CheckDistFromCollider();
|
||||
UpdateCollisionCategories();
|
||||
@@ -1295,42 +1297,17 @@ namespace Barotrauma
|
||||
UpdateProjSpecific(deltaTime);
|
||||
}
|
||||
|
||||
public bool Invalid { get; private set; }
|
||||
private int validityResets;
|
||||
private bool CheckValidity()
|
||||
private void CheckValidity()
|
||||
{
|
||||
bool isColliderValid = CheckValidity(Collider);
|
||||
bool limbsValid = true;
|
||||
CheckValidity(Collider);
|
||||
foreach (Limb limb in limbs)
|
||||
{
|
||||
if (limb.body == null || !limb.body.Enabled) { continue; }
|
||||
if (!CheckValidity(limb.body))
|
||||
{
|
||||
limbsValid = false;
|
||||
break;
|
||||
}
|
||||
CheckValidity(limb.body);
|
||||
}
|
||||
bool isValid = isColliderValid && limbsValid;
|
||||
if (!isValid)
|
||||
{
|
||||
validityResets++;
|
||||
if (validityResets > 1)
|
||||
{
|
||||
Invalid = true;
|
||||
DebugConsole.ThrowError("Invalid ragdoll physics. Ragdoll freezed to prevent crashes.");
|
||||
Collider.SetTransform(Vector2.Zero, 0.0f);
|
||||
foreach (Limb limb in Limbs)
|
||||
{
|
||||
limb.body.SetTransform(Collider.SimPosition, 0.0f);
|
||||
limb.body.ResetDynamics();
|
||||
}
|
||||
Frozen = true;
|
||||
}
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
private bool CheckValidity(PhysicsBody body)
|
||||
private void CheckValidity(PhysicsBody body)
|
||||
{
|
||||
string errorMsg = null;
|
||||
string bodyName = body.UserData is Limb ? "Limb" : "Collider";
|
||||
@@ -1382,7 +1359,7 @@ namespace Barotrauma
|
||||
limb.body.ResetDynamics();
|
||||
}
|
||||
SetInitialLimbPositions();
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1524,7 +1501,8 @@ namespace Barotrauma
|
||||
float allowedDist = Math.Max(Math.Max(Collider.radius, Collider.width), Collider.height) * 2.0f;
|
||||
float resetDist = allowedDist * 5.0f;
|
||||
|
||||
float distSqrd = Vector2.DistanceSquared(Collider.SimPosition, MainLimb.SimPosition);
|
||||
Vector2 diff = Collider.SimPosition - MainLimb.SimPosition;
|
||||
float distSqrd = diff.LengthSquared();
|
||||
|
||||
if (distSqrd > resetDist * resetDist)
|
||||
{
|
||||
@@ -1535,10 +1513,13 @@ namespace Barotrauma
|
||||
{
|
||||
//ragdoll too far from the collider, disable collisions until it's close enough
|
||||
//(in case the ragdoll has gotten stuck somewhere)
|
||||
|
||||
Vector2 forceDir = diff / (float)Math.Sqrt(distSqrd);
|
||||
foreach (Limb limb in Limbs)
|
||||
{
|
||||
if (limb.IsSevered) continue;
|
||||
limb.body.CollidesWith = Physics.CollisionNone;
|
||||
limb.body.ApplyForce(forceDir * limb.Mass * 10.0f, maxVelocity: 10.0f);
|
||||
}
|
||||
|
||||
collisionsDisabled = true;
|
||||
|
||||
@@ -28,7 +28,6 @@ namespace Barotrauma
|
||||
public enum AIBehaviorAfterAttack
|
||||
{
|
||||
FallBack,
|
||||
FallBackUntilCanAttack,
|
||||
PursueIfCanAttack,
|
||||
Pursue
|
||||
}
|
||||
@@ -82,9 +81,6 @@ namespace Barotrauma
|
||||
[Serialize(AIBehaviorAfterAttack.FallBack, true), Editable(ToolTip = "The preferred AI behavior after the attack.")]
|
||||
public AIBehaviorAfterAttack AfterAttack { get; private set; }
|
||||
|
||||
[Serialize(false, true), Editable(ToolTip = "Should the ai try to reverse when aiming with this attack?")]
|
||||
public bool Reverse { get; private set; }
|
||||
|
||||
[Serialize(0.0f, true), Editable(MinValueFloat = 0.0f, MaxValueFloat = 2000.0f, ToolTip = "Min distance from the attack limb to the target before the AI tries to attack.")]
|
||||
public float Range { get; private set; }
|
||||
|
||||
@@ -100,9 +96,6 @@ namespace Barotrauma
|
||||
[Serialize(0f, true), Editable(MinValueFloat = 0.0f, MaxValueFloat = 100.0f, DecimalCount = 2, ToolTip = "Used as the attack cooldown between different kind of attacks. Does not have effect, if set to 0.")]
|
||||
public float SecondaryCoolDown { get; private set; } = 0;
|
||||
|
||||
[Serialize(0f, true), Editable(MinValueFloat = 0, MaxValueFloat = 1, DecimalCount = 2, ToolTip = "Random factor applied to all cooldowns. Example: 0.1 -> adds a random value between -10% and 10% of the cooldown. Min 0 (default), Max 1 (could disable or double the cooldown in extreme cases).")]
|
||||
public float CoolDownRandomFactor { get; private set; } = 0;
|
||||
|
||||
[Serialize(0.0f, true), Editable(MinValueFloat = 0.0f, MaxValueFloat = 10000.0f)]
|
||||
public float StructureDamage { get; private set; }
|
||||
|
||||
@@ -189,7 +182,7 @@ namespace Barotrauma
|
||||
public readonly List<Affliction> Afflictions = new List<Affliction>();
|
||||
|
||||
/// <summary>
|
||||
/// Only affects ai decision making. All the conditionals has to be met in order to select the attack. TODO: allow to define conditionals using any (implemented in StatusEffect -> move from there to PropertyConditional?)
|
||||
/// Only affects ai decision making.
|
||||
/// </summary>
|
||||
public List<PropertyConditional> Conditionals { get; private set; } = new List<PropertyConditional>();
|
||||
|
||||
@@ -451,10 +444,8 @@ namespace Barotrauma
|
||||
|
||||
public void SetCoolDown()
|
||||
{
|
||||
float randomFraction = CoolDown * CoolDownRandomFactor;
|
||||
CoolDownTimer = CoolDown + MathHelper.Lerp(-randomFraction, randomFraction, Rand.Value(Rand.RandSync.Server));
|
||||
randomFraction = SecondaryCoolDown * CoolDownRandomFactor;
|
||||
SecondaryCoolDownTimer = SecondaryCoolDown + MathHelper.Lerp(-randomFraction, randomFraction, Rand.Value(Rand.RandSync.Server));
|
||||
CoolDownTimer = CoolDown;
|
||||
SecondaryCoolDownTimer = SecondaryCoolDown;
|
||||
}
|
||||
|
||||
public void ResetCoolDown()
|
||||
|
||||
@@ -810,7 +810,6 @@ namespace Barotrauma
|
||||
|
||||
public void LoadHeadAttachments()
|
||||
{
|
||||
if (Info == null) { return; }
|
||||
if (AnimController == null) { return; }
|
||||
var head = AnimController.GetLimb(LimbType.Head);
|
||||
if (head == null) { return; }
|
||||
@@ -1113,15 +1112,13 @@ namespace Barotrauma
|
||||
ViewTarget = null;
|
||||
if (!AllowInput) return;
|
||||
|
||||
if (Controlled == this || (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer))
|
||||
Vector2 smoothedCursorDiff = cursorPosition - SmoothedCursorPosition;
|
||||
if (Controlled == this)
|
||||
{
|
||||
SmoothedCursorPosition = cursorPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
//apply some smoothing to the cursor positions of remote players when playing as a client
|
||||
//to make aiming look a little less choppy
|
||||
Vector2 smoothedCursorDiff = cursorPosition - SmoothedCursorPosition;
|
||||
smoothedCursorDiff = NetConfig.InterpolateCursorPositionError(smoothedCursorDiff);
|
||||
SmoothedCursorPosition = cursorPosition - smoothedCursorDiff;
|
||||
}
|
||||
@@ -1188,10 +1185,6 @@ namespace Barotrauma
|
||||
if (PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.F))
|
||||
{
|
||||
AnimController.ReleaseStuckLimbs();
|
||||
if (AIController != null && AIController is EnemyAIController enemyAI)
|
||||
{
|
||||
enemyAI.LatchOntoAI?.DeattachFromBody();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1271,7 +1264,15 @@ namespace Barotrauma
|
||||
if (IsKeyDown(InputType.Aim) && selectedItems[i] != null) selectedItems[i].SecondaryUse(deltaTime, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if CLIENT
|
||||
if (SelectedConstruction != null && SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null && HUD.CloseHUD(ic.GuiFrame.Rect)))
|
||||
{
|
||||
//emulate a Select input to get the character to deselect the item server-side
|
||||
keys[(int)InputType.Select].Hit = true;
|
||||
SelectedConstruction = null;
|
||||
}
|
||||
#endif
|
||||
if (SelectedConstruction != null)
|
||||
{
|
||||
if (IsKeyDown(InputType.Use)) SelectedConstruction.Use(deltaTime, this);
|
||||
@@ -1649,8 +1650,7 @@ namespace Barotrauma
|
||||
#if CLIENT
|
||||
if (isLocalPlayer)
|
||||
{
|
||||
if (GUI.MouseOn == null &&
|
||||
(!CharacterInventory.IsMouseOnInventory() || CharacterInventory.DraggingItemToWorld))
|
||||
if (GUI.MouseOn == null && !CharacterInventory.IsMouseOnInventory())
|
||||
{
|
||||
if (findFocusedTimer <= 0.0f || Screen.Selected == GameMain.SubEditorScreen)
|
||||
{
|
||||
@@ -1665,12 +1665,10 @@ namespace Barotrauma
|
||||
focusedItem = null;
|
||||
}
|
||||
findFocusedTimer -= deltaTime;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//climb ladders automatically when pressing up/down inside their trigger area
|
||||
Ladder currentLadder = SelectedConstruction?.GetComponent<Ladder>();
|
||||
if ((SelectedConstruction == null || currentLadder != null) &&
|
||||
!AnimController.InWater && Screen.Selected != GameMain.SubEditorScreen)
|
||||
if (SelectedConstruction == null && !AnimController.InWater && Screen.Selected != GameMain.SubEditorScreen)
|
||||
{
|
||||
bool climbInput = IsKeyDown(InputType.Up) || IsKeyDown(InputType.Down);
|
||||
bool isControlled = Controlled == this;
|
||||
@@ -1681,19 +1679,6 @@ namespace Barotrauma
|
||||
float minDist = float.PositiveInfinity;
|
||||
foreach (Ladder ladder in Ladder.List)
|
||||
{
|
||||
if (ladder == currentLadder)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (currentLadder != null)
|
||||
{
|
||||
//only switch from ladder to another if the ladders are above the current ladders and pressing up, or vice versa
|
||||
if (ladder.Item.WorldPosition.Y > currentLadder.Item.WorldPosition.Y != IsKeyDown(InputType.Up))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (CanInteractWith(ladder.Item, out float dist, checkLinked: false) && dist < minDist)
|
||||
{
|
||||
minDist = dist;
|
||||
@@ -1710,7 +1695,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (SelectedCharacter != null && (IsKeyHit(InputType.Grab) || IsKeyHit(InputType.Health))) //Let people use ladders and buttons and stuff when dragging chars
|
||||
if (SelectedCharacter != null && IsKeyHit(InputType.Grab)) //Let people use ladders and buttons and stuff when dragging chars
|
||||
{
|
||||
DeselectCharacter();
|
||||
}
|
||||
|
||||
@@ -804,12 +804,6 @@ namespace Barotrauma
|
||||
var newItem = Item.Load(itemElement, inventory.Owner.Submarine, createNetworkEvent: true);
|
||||
if (newItem == null) { continue; }
|
||||
|
||||
if (!MathUtils.NearlyEqual(newItem.Condition, newItem.MaxCondition) &&
|
||||
GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
||||
{
|
||||
GameMain.NetworkMember.CreateEntityEvent(newItem, new object[] { NetEntityEvent.Type.Status });
|
||||
}
|
||||
|
||||
int[] slotIndices = itemElement.GetAttributeIntArray("i", new int[] { 0 });
|
||||
if (!slotIndices.Any())
|
||||
{
|
||||
|
||||
+1
-6
@@ -153,10 +153,7 @@ namespace Barotrauma
|
||||
//how high the strength has to be for the affliction icon to be shown in the UI
|
||||
public readonly float ShowIconThreshold = 0.05f;
|
||||
public readonly float MaxStrength = 100.0f;
|
||||
|
||||
//how high the strength has to be for the affliction icon to be shown with a health scanner
|
||||
public readonly float ShowInHealthScannerThreshold = 0.05f;
|
||||
|
||||
|
||||
public float BurnOverlayAlpha;
|
||||
public float DamageOverlayAlpha;
|
||||
|
||||
@@ -260,8 +257,6 @@ namespace Barotrauma
|
||||
ShowIconThreshold = element.GetAttributeFloat("showiconthreshold", Math.Max(ActivationThreshold, 0.05f));
|
||||
MaxStrength = element.GetAttributeFloat("maxstrength", 100.0f);
|
||||
|
||||
ShowInHealthScannerThreshold = element.GetAttributeFloat("showinhealthscannerthreshold", Math.Max(ActivationThreshold, 0.05f));
|
||||
|
||||
DamageOverlayAlpha = element.GetAttributeFloat("damageoverlayalpha", 0.0f);
|
||||
BurnOverlayAlpha = element.GetAttributeFloat("burnoverlayalpha", 0.0f);
|
||||
|
||||
|
||||
@@ -460,7 +460,6 @@ namespace Barotrauma
|
||||
{
|
||||
affliction.Strength = 0.0f;
|
||||
}
|
||||
CalculateVitality();
|
||||
}
|
||||
|
||||
private void AddLimbAffliction(Limb limb, Affliction newAffliction)
|
||||
|
||||
@@ -520,15 +520,14 @@ namespace Barotrauma
|
||||
// Ignore blocking on items, because it causes cases where a Mudraptor cannot hit the hatch, for example.
|
||||
wasHit = true;
|
||||
}
|
||||
else if (damageTarget is Structure wall && structureBody != null &&
|
||||
(structureBody.UserData is Structure || (structureBody.UserData is Submarine sub && sub == wall.Submarine)))
|
||||
else if (damageTarget is Structure && structureBody?.UserData is Structure)
|
||||
{
|
||||
// If the attack is aimed to a structure (wall) and hits a structure or the sub, it's successful
|
||||
// If the attack is aimed to a structure and hits a structure, it's successful
|
||||
wasHit = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If there is nothing between, the hit is successful
|
||||
// If the attack is aimed to a character but hits a structure, the hit is blocked.
|
||||
wasHit = structureBody == null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,6 +103,12 @@ namespace Barotrauma
|
||||
if (missionType == MissionType.Random)
|
||||
{
|
||||
allowedMissions.AddRange(MissionPrefab.List);
|
||||
#if SERVER
|
||||
if (GameMain.Server != null)
|
||||
{
|
||||
allowedMissions.RemoveAll(mission => !GameMain.Server.ServerSettings.AllowedRandomMissionTypes.Contains(mission.type));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (missionType == MissionType.None)
|
||||
{
|
||||
@@ -118,11 +124,6 @@ namespace Barotrauma
|
||||
{
|
||||
allowedMissions.RemoveAll(m => !m.IsAllowed(locations[0], locations[1]));
|
||||
}
|
||||
|
||||
if (allowedMissions.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int probabilitySum = allowedMissions.Sum(m => m.Commonness);
|
||||
int randomNumber = rand.NextInt32() % probabilitySum;
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace Barotrauma
|
||||
MTRandom rand = new MTRandom(ToolBox.StringToInt(seed));
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
dummyLocations[i] = Location.CreateRandom(new Vector2((float)rand.NextDouble() * 10000.0f, (float)rand.NextDouble() * 10000.0f), null, rand);
|
||||
dummyLocations[i] = Location.CreateRandom(new Vector2((float)rand.NextDouble() * 10000.0f, (float)rand.NextDouble() * 10000.0f), null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ namespace Barotrauma
|
||||
DockingPort myPort = null, outPostPort = null;
|
||||
foreach (DockingPort port in DockingPort.List)
|
||||
{
|
||||
if (port.IsHorizontal || port.Docked) { continue; }
|
||||
if (port.IsHorizontal) { continue; }
|
||||
if (port.Item.Submarine == level.StartOutpost)
|
||||
{
|
||||
outPostPort = port;
|
||||
|
||||
@@ -880,7 +880,8 @@ namespace Barotrauma.Items.Components
|
||||
List<MapEntity> linked = new List<MapEntity>(item.linkedTo);
|
||||
foreach (MapEntity entity in linked)
|
||||
{
|
||||
if (!(entity is Item linkedItem)) { continue; }
|
||||
Item linkedItem = entity as Item;
|
||||
if (linkedItem == null) { continue; }
|
||||
|
||||
var dockingPort = linkedItem.GetComponent<DockingPort>();
|
||||
if (dockingPort != null)
|
||||
|
||||
@@ -426,11 +426,11 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public override bool Use(float deltaTime, Character character = null)
|
||||
{
|
||||
if (!attachable || item.body == null) { return character == null || character.IsKeyDown(InputType.Aim); }
|
||||
if (!attachable || item.body == null) return (character == null || character.IsKeyDown(InputType.Aim));
|
||||
if (character != null)
|
||||
{
|
||||
if (!character.IsKeyDown(InputType.Aim)) { return false; }
|
||||
if (!CanBeAttached()) { return false; }
|
||||
if (!character.IsKeyDown(InputType.Aim)) return false;
|
||||
if (!CanBeAttached()) return false;
|
||||
#if SERVER
|
||||
if (GameMain.Server != null)
|
||||
{
|
||||
@@ -438,12 +438,7 @@ namespace Barotrauma.Items.Components
|
||||
GameServer.Log(character.LogName + " attached " + item.Name + " to a wall", ServerLog.MessageType.ItemInteraction);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
|
||||
{
|
||||
if (character != null) { item.Drop(character); }
|
||||
AttachToWall();
|
||||
item.Drop(character);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -555,7 +550,7 @@ namespace Barotrauma.Items.Components
|
||||
public override void ServerWrite(NetBuffer msg, Client c, object[] extraData = null)
|
||||
{
|
||||
base.ServerWrite(msg, c, extraData);
|
||||
if (!attachable || body == null) { return; }
|
||||
if (!attachable || body == null) return;
|
||||
|
||||
msg.Write(Attached);
|
||||
msg.Write(body.SimPosition.X);
|
||||
|
||||
@@ -2,15 +2,12 @@
|
||||
using Lidgren.Network;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class LevelResource : ItemComponent, IServerSerializable
|
||||
{
|
||||
private float lastSentDeattachTimer;
|
||||
|
||||
[Serialize(1.0f, false)]
|
||||
public float DeattachDuration
|
||||
{
|
||||
@@ -24,29 +21,12 @@ namespace Barotrauma.Items.Components
|
||||
get { return deattachTimer; }
|
||||
set
|
||||
{
|
||||
//clients don't deattach the item until the server says so (handled in ClientRead)
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient)
|
||||
{
|
||||
return;
|
||||
}
|
||||
deattachTimer = Math.Max(0.0f, value);
|
||||
#if SERVER
|
||||
if (deattachTimer >= DeattachDuration)
|
||||
{
|
||||
if (holdable.Attached){ item.CreateServerEvent(this); }
|
||||
holdable.DeattachFromWall();
|
||||
}
|
||||
else if (Math.Abs(lastSentDeattachTimer - deattachTimer) > 0.1f)
|
||||
{
|
||||
item.CreateServerEvent(this);
|
||||
lastSentDeattachTimer = deattachTimer;
|
||||
}
|
||||
#else
|
||||
if (deattachTimer >= DeattachDuration)
|
||||
//clients don't deattach the item until the server says so (handled in ClientRead)
|
||||
if ((GameMain.NetworkMember == null || !GameMain.NetworkMember.IsClient) && deattachTimer >= DeattachDuration)
|
||||
{
|
||||
holdable.DeattachFromWall();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,10 +67,7 @@ namespace Barotrauma.Items.Components
|
||||
return;
|
||||
}
|
||||
holdable.Reattachable = false;
|
||||
if (requiredItems.Any())
|
||||
{
|
||||
holdable.PickingTime = float.MaxValue;
|
||||
}
|
||||
holdable.PickingTime = float.MaxValue;
|
||||
|
||||
var body = item.body ?? holdable.Body;
|
||||
|
||||
|
||||
@@ -17,8 +17,6 @@ namespace Barotrauma.Items.Components
|
||||
private readonly List<string> fixableEntities;
|
||||
private Vector2 pickedPosition;
|
||||
private float activeTimer;
|
||||
|
||||
private Vector2 debugRayStartPos, debugRayEndPos;
|
||||
|
||||
[Serialize(0.0f, false)]
|
||||
public float Range { get; set; }
|
||||
@@ -158,7 +156,7 @@ namespace Barotrauma.Items.Components
|
||||
var collisionCategories = Physics.CollisionWall | Physics.CollisionCharacter | Physics.CollisionItem | Physics.CollisionLevel | Physics.CollisionRepair;
|
||||
if (RepairThroughWalls)
|
||||
{
|
||||
var bodies = Submarine.PickBodies(rayStart, rayEnd, ignoredBodies, collisionCategories, ignoreSensors: false, allowInsideFixture: true);
|
||||
var bodies = Submarine.PickBodies(rayStart, rayEnd, ignoredBodies, collisionCategories, ignoreSensors: false);
|
||||
foreach (Body body in bodies)
|
||||
{
|
||||
FixBody(user, deltaTime, degreeOfSuccess, body);
|
||||
@@ -166,7 +164,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else
|
||||
{
|
||||
FixBody(user, deltaTime, degreeOfSuccess, Submarine.PickBody(rayStart, rayEnd, ignoredBodies, collisionCategories, ignoreSensors: false, allowInsideFixture: true));
|
||||
FixBody(user, deltaTime, degreeOfSuccess, Submarine.PickBody(rayStart, rayEnd, ignoredBodies, collisionCategories, ignoreSensors: false));
|
||||
}
|
||||
|
||||
if (ExtinguishAmount > 0.0f && item.CurrentHull != null)
|
||||
@@ -249,7 +247,6 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
var levelResource = targetItem.GetComponent<LevelResource>();
|
||||
if (levelResource != null && levelResource.IsActive &&
|
||||
levelResource.requiredItems.Any() &&
|
||||
levelResource.HasRequiredItems(user, addMessage: false))
|
||||
{
|
||||
levelResource.DeattachTimer += deltaTime;
|
||||
|
||||
@@ -104,8 +104,8 @@ namespace Barotrauma.Items.Components
|
||||
#if SERVER
|
||||
GameServer.Log(picker.LogName + " threw " + item.Name, ServerLog.MessageType.ItemInteraction);
|
||||
#endif
|
||||
Character thrower = picker;
|
||||
item.Drop(thrower, createNetworkEvent: GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer);
|
||||
|
||||
item.Drop(picker, createNetworkEvent: GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer);
|
||||
item.body.ApplyLinearImpulse(throwVector * throwForce * item.body.Mass * 3.0f);
|
||||
|
||||
ac.GetLimb(LimbType.Head).body.ApplyLinearImpulse(throwVector*10.0f);
|
||||
|
||||
@@ -189,7 +189,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
get { return name; }
|
||||
}
|
||||
|
||||
|
||||
[Editable, Serialize("", true)]
|
||||
public string Msg
|
||||
{
|
||||
@@ -203,6 +203,12 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
public AITarget AITarget
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public AITarget AITarget
|
||||
{
|
||||
get;
|
||||
@@ -247,7 +253,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
DebugConsole.ThrowError("Invalid pick key in " + element + "!", e);
|
||||
}
|
||||
|
||||
|
||||
SerializableProperties = SerializableProperty.DeserializeProperties(this, element);
|
||||
ParseMsg();
|
||||
|
||||
|
||||
@@ -155,14 +155,13 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (item.Container != null) { return false; }
|
||||
|
||||
if (AutoInteractWithContained && character.SelectedConstruction == null)
|
||||
if (AutoInteractWithContained)
|
||||
{
|
||||
foreach (Item contained in Inventory.Items)
|
||||
{
|
||||
if (contained == null) continue;
|
||||
if (contained.TryInteract(character))
|
||||
{
|
||||
character.FocusedItem = contained;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -179,7 +178,6 @@ namespace Barotrauma.Items.Components
|
||||
if (contained == null) continue;
|
||||
if (contained.TryInteract(picker))
|
||||
{
|
||||
picker.FocusedItem = contained;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace Barotrauma.Items.Components
|
||||
Force = MathHelper.Lerp(force, (voltage < minVoltage) ? 0.0f : targetForce, 0.1f);
|
||||
if (Math.Abs(Force) > 1.0f)
|
||||
{
|
||||
Vector2 currForce = new Vector2((force / 10.0f) * maxForce * Math.Min(voltage / minVoltage, 1.0f), 0.0f);
|
||||
Vector2 currForce = new Vector2((force / 100.0f) * maxForce * Math.Min(voltage / minVoltage, 1.0f), 0.0f);
|
||||
//less effective when in a bad condition
|
||||
currForce *= MathHelper.Lerp(0.5f, 2.0f, item.Condition / item.MaxCondition);
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private bool shutDown;
|
||||
|
||||
const float AIUpdateInterval = 0.2f;
|
||||
const float AIUpdateInterval = 1.0f;
|
||||
private float aiUpdateTimer;
|
||||
|
||||
private Character lastUser;
|
||||
@@ -209,10 +209,10 @@ namespace Barotrauma.Items.Components
|
||||
allowedFissionRate = Vector2.Lerp(new Vector2(20, AvailableFuel), new Vector2(10, AvailableFuel), degreeOfSuccess);
|
||||
allowedFissionRate.X = Math.Min(allowedFissionRate.X, allowedFissionRate.Y - 10);
|
||||
|
||||
float heatAmount = GetGeneratedHeat(fissionRate);
|
||||
float heatAmount = fissionRate * (AvailableFuel / 100.0f) * 2.0f;
|
||||
float temperatureDiff = (heatAmount - turbineOutput) - Temperature;
|
||||
Temperature += MathHelper.Clamp(Math.Sign(temperatureDiff) * 10.0f * deltaTime, -Math.Abs(temperatureDiff), Math.Abs(temperatureDiff));
|
||||
//if (item.InWater && AvailableFuel < 100.0f) Temperature -= 12.0f * deltaTime;
|
||||
if (item.InWater && AvailableFuel < 100.0f) Temperature -= 12.0f * deltaTime;
|
||||
|
||||
FissionRate = MathHelper.Lerp(fissionRate, Math.Min(targetFissionRate, AvailableFuel), deltaTime);
|
||||
TurbineOutput = MathHelper.Lerp(turbineOutput, targetTurbineOutput, deltaTime);
|
||||
@@ -313,48 +313,6 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
private float GetGeneratedHeat(float fissionRate)
|
||||
{
|
||||
return fissionRate * (prevAvailableFuel / 100.0f) * 2.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Do we need more fuel to generate enough power to match the current load.
|
||||
/// </summary>
|
||||
/// <param name="minimumOutputRatio">How low we allow the output/load ratio to go before loading more fuel.
|
||||
/// 1.0 = always load more fuel when maximum output is too low, 0.5 = load more if max output is 50% of the load</param>
|
||||
private bool NeedMoreFuel(float minimumOutputRatio)
|
||||
{
|
||||
if (prevAvailableFuel <= 0.0f && load > 0.0f)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//fission rate is clamped to the amount of available fuel
|
||||
float maxFissionRate = Math.Min(prevAvailableFuel, 100.0f);
|
||||
float maxTurbineOutput = 100.0f;
|
||||
|
||||
//calculate the maximum output if the fission rate is cranked as high as it goes and turbine output is at max
|
||||
float theoreticalMaxHeat = GetGeneratedHeat(fissionRate: maxFissionRate);
|
||||
float temperatureFactor = Math.Min(theoreticalMaxHeat / 50.0f, 1.0f);
|
||||
float theoreticalMaxOutput = Math.Min(maxTurbineOutput / 100.0f, temperatureFactor) * MaxPowerOutput;
|
||||
|
||||
//maximum output not enough, we need more fuel
|
||||
return theoreticalMaxOutput < load * minimumOutputRatio;
|
||||
}
|
||||
|
||||
private bool TooMuchFuel()
|
||||
{
|
||||
var containedItems = item.ContainedItems;
|
||||
if (containedItems != null && containedItems.Count() <= 1) { return false; }
|
||||
|
||||
//get the amount of heat we'd generate if the fission rate was at the low end of the optimal range
|
||||
float minimumHeat = GetGeneratedHeat(optimalFissionRate.X);
|
||||
|
||||
//if we need a very high turbine output to keep the engine from overheating, there's too much fuel
|
||||
return minimumHeat > Math.Min(correctTurbineOutput * 1.5f, 90);
|
||||
}
|
||||
|
||||
private void UpdateFailures(float deltaTime)
|
||||
{
|
||||
if (temperature > allowedTemperature.Y)
|
||||
@@ -409,11 +367,6 @@ namespace Barotrauma.Items.Components
|
||||
targetFissionRate = Math.Min(targetFissionRate + speed * 2 * deltaTime, 100.0f);
|
||||
}
|
||||
targetFissionRate = MathHelper.Clamp(targetFissionRate, 0.0f, 100.0f);
|
||||
|
||||
//don't push the target too far from the current fission rate
|
||||
//otherwise we may "overshoot", cranking the target fission rate all the way up because it takes a while
|
||||
//for the actual fission rate and temperature to follow
|
||||
targetFissionRate = MathHelper.Clamp(targetFissionRate, FissionRate - 5, FissionRate + 5);
|
||||
}
|
||||
|
||||
public override void UpdateBroken(float deltaTime, Camera cam)
|
||||
@@ -488,18 +441,12 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
if (aiUpdateTimer > 0.0f)
|
||||
{
|
||||
aiUpdateTimer -= deltaTime;
|
||||
return false;
|
||||
}
|
||||
|
||||
//load more fuel if the current maximum output is only 50% of the current load
|
||||
if (NeedMoreFuel(minimumOutputRatio: 0.5f))
|
||||
//we need more fuel
|
||||
if (-currPowerConsumption < load * 0.5f && prevAvailableFuel <= 0.0f)
|
||||
{
|
||||
var containFuelObjective = new AIObjectiveContainItem(character, new string[] { "fuelrod", "reactorfuel" }, item.GetComponent<ItemContainer>())
|
||||
{
|
||||
MinContainedAmount = item.ContainedItems.Count(i => i != null && i.Prefab.Identifier == "fuelrod" || i.HasTag("reactorfuel")) + 1,
|
||||
MinContainedAmount = containedItems.Count(i => i != null && i.Prefab.Identifier == "fuelrod" || i.HasTag("reactorfuel")) + 1,
|
||||
GetItemPriority = (Item fuelItem) =>
|
||||
{
|
||||
if (fuelItem.ParentInventory?.Owner is Item)
|
||||
@@ -514,7 +461,6 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
character?.Speak(TextManager.Get("DialogReactorFuel"), null, 0.0f, "reactorfuel", 30.0f);
|
||||
|
||||
aiUpdateTimer = AIUpdateInterval;
|
||||
return false;
|
||||
}
|
||||
else if (TooMuchFuel())
|
||||
@@ -533,6 +479,12 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
if (aiUpdateTimer > 0.0f)
|
||||
{
|
||||
aiUpdateTimer -= deltaTime;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lastUser != character && lastUser != null && lastUser.SelectedConstruction == item)
|
||||
{
|
||||
character.Speak(TextManager.Get("DialogReactorTaken"), null, 0.0f, "reactortaken", 10.0f);
|
||||
@@ -554,7 +506,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
AutoTemp = false;
|
||||
unsentChanges = true;
|
||||
UpdateAutoTemp(MathHelper.Lerp(0.5f, 2.0f, degreeOfSuccess), 1.0f);
|
||||
UpdateAutoTemp(2.0f + degreeOfSuccess * 5.0f, 1.0f);
|
||||
}
|
||||
#if CLIENT
|
||||
onOffSwitch.BarScroll = 0.0f;
|
||||
|
||||
@@ -153,7 +153,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!pt.IsActive || !pt.CanTransfer) { continue; }
|
||||
if (!pt.IsActive) { continue; }
|
||||
|
||||
gridLoad += pt.PowerLoad;
|
||||
gridPower -= pt.CurrPowerConsumption;
|
||||
@@ -209,9 +209,9 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
Charge -= CurrPowerOutput / 3600.0f;
|
||||
}
|
||||
item.SendSignal(0, ((int)Charge).ToString(), "charge", null);
|
||||
item.SendSignal(0, ((int)((Charge / capacity) * 100)).ToString(), "charge_%", null);
|
||||
item.SendSignal(0, ((int)((RechargeSpeed / maxRechargeSpeed) * 100)).ToString(), "charge_rate", null);
|
||||
item.SendSignal(0, Charge.ToString(), "charge", null);
|
||||
item.SendSignal(0, ((Charge / capacity) * 100).ToString(), "charge_%", null);
|
||||
item.SendSignal(0, ((RechargeSpeed / maxRechargeSpeed) * 100).ToString(), "charge_rate", null);
|
||||
|
||||
foreach (Pair<Powered, Connection> connected in directlyConnected)
|
||||
{
|
||||
|
||||
@@ -180,8 +180,7 @@ namespace Barotrauma.Items.Components
|
||||
#endif
|
||||
|
||||
//items in a bad condition are more sensitive to overvoltage
|
||||
float maxOverVoltage = MathHelper.Lerp(OverloadVoltage * 0.75f, OverloadVoltage, item.Condition / item.MaxCondition);
|
||||
maxOverVoltage = Math.Max(OverloadVoltage, 1.0f);
|
||||
float maxOverVoltage = MathHelper.Lerp(Math.Min(OverloadVoltage, 1.0f), OverloadVoltage, item.Condition / item.MaxCondition);
|
||||
|
||||
//if the item can't be fixed, don't allow it to break
|
||||
if (!item.Repairables.Any() || !CanBeOverloaded) continue;
|
||||
@@ -320,13 +319,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
|
||||
|
||||
//float maxPower = this is RelayComponent relayComponent ? relayComponent.MaxPower : float.PositiveInfinity;
|
||||
RelayComponent thisRelayComponent = this as RelayComponent;
|
||||
if (thisRelayComponent != null)
|
||||
{
|
||||
clampPower = Math.Min(Math.Min(clampPower, thisRelayComponent.MaxPower), powerLoad);
|
||||
clampLoad = Math.Min(clampLoad, thisRelayComponent.MaxPower);
|
||||
}
|
||||
float maxPower = this is RelayComponent relayComponent ? relayComponent.MaxPower : float.PositiveInfinity;
|
||||
|
||||
foreach (Connection c in PowerConnections)
|
||||
{
|
||||
@@ -364,8 +357,6 @@ namespace Barotrauma.Items.Components
|
||||
continue;
|
||||
}
|
||||
|
||||
float addLoad = 0.0f;
|
||||
float addPower = 0.0f;
|
||||
if (powered is PowerContainer powerContainer)
|
||||
{
|
||||
if (recipient.Name == "power_in")
|
||||
@@ -374,7 +365,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else
|
||||
{
|
||||
addPower = powerContainer.CurrPowerOutput;
|
||||
fullPower += Math.Min(powerContainer.CurrPowerOutput, maxPower);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -389,16 +380,10 @@ namespace Barotrauma.Items.Components
|
||||
//negative power consumption = the construction is a
|
||||
//generator/battery or another junction box
|
||||
{
|
||||
addPower -= powered.CurrPowerConsumption;
|
||||
fullPower -= Math.Max(powered.CurrPowerConsumption, -maxPower);
|
||||
}
|
||||
}
|
||||
|
||||
if (addPower + fullPower > clampPower) { addPower -= (addPower + fullPower) - clampPower; };
|
||||
if (addPower > 0) { fullPower += addPower; }
|
||||
|
||||
if (addLoad + fullLoad > clampLoad) { addLoad -= (addLoad + fullLoad) - clampLoad; };
|
||||
if (addLoad > 0) { fullLoad += addLoad; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ namespace Barotrauma.Items.Components
|
||||
public static float SkillIncreaseMultiplier = 0.4f;
|
||||
|
||||
private string header;
|
||||
|
||||
private float fixDurationLowSkill, fixDurationHighSkill;
|
||||
|
||||
private float deteriorationTimer;
|
||||
|
||||
@@ -50,20 +52,17 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(100.0f, true), Editable(MinValueFloat = 0.0f, MaxValueFloat = 100.0f, ToolTip = "The amount of time it takes to fix the item with insufficient skill levels.")]
|
||||
public float FixDurationLowSkill
|
||||
/*private float repairProgress;
|
||||
public float RepairProgress
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(10.0f, true), Editable(MinValueFloat = 0.0f, MaxValueFloat = 100.0f, ToolTip = "The amount of time it takes to fix the item with sufficient skill levels.")]
|
||||
public float FixDurationHighSkill
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
get { return repairProgress; }
|
||||
set
|
||||
{
|
||||
repairProgress = MathHelper.Clamp(value, 0.0f, 1.0f);
|
||||
if (repairProgress >= 1.0f && currentFixer != null) currentFixer.AnimController.Anim = AnimController.Animation.None;
|
||||
}
|
||||
}*/
|
||||
|
||||
private Character currentFixer;
|
||||
public Character CurrentFixer
|
||||
{
|
||||
@@ -84,6 +83,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
this.item = item;
|
||||
header = element.GetAttributeString("name", "");
|
||||
fixDurationLowSkill = element.GetAttributeFloat("fixdurationlowskill", 100.0f);
|
||||
fixDurationHighSkill = element.GetAttributeFloat("fixdurationhighskill", 5.0f);
|
||||
InitProjSpecific(element);
|
||||
}
|
||||
|
||||
@@ -159,7 +160,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
bool wasBroken = !item.IsFullCondition;
|
||||
float fixDuration = MathHelper.Lerp(FixDurationLowSkill, FixDurationHighSkill, successFactor);
|
||||
float fixDuration = MathHelper.Lerp(fixDurationLowSkill, fixDurationHighSkill, successFactor);
|
||||
if (fixDuration <= 0.0f)
|
||||
{
|
||||
item.Condition = item.MaxCondition;
|
||||
@@ -185,5 +186,26 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
character.AnimController.UpdateUseItem(false, item.WorldPosition + new Vector2(0.0f, 100.0f) * ((item.Condition / item.MaxCondition) % 0.1f));
|
||||
}
|
||||
|
||||
public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null)
|
||||
{
|
||||
msg.Write(deteriorationTimer);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
public void ServerRead(ClientNetObject type, NetBuffer msg, Client c)
|
||||
{
|
||||
if (c.Character == null) return;
|
||||
StartRepairing(c.Character);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,14 +163,6 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
wires[index] = wire;
|
||||
recipientsDirty = true;
|
||||
if (wire != null)
|
||||
{
|
||||
var otherConnection = wire.OtherConnection(this);
|
||||
if (otherConnection != null)
|
||||
{
|
||||
otherConnection.recipientsDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SendSignal(int stepsTaken, string signal, Item source, Character sender, float power, float signalStrength = 1.0f)
|
||||
|
||||
@@ -356,7 +356,7 @@ namespace Barotrauma.Items.Components
|
||||
projectile.body.ResetDynamics();
|
||||
projectile.body.Enabled = true;
|
||||
projectile.SetTransform(ConvertUnits.ToSimUnits(new Vector2(item.WorldRect.X + transformedBarrelPos.X, item.WorldRect.Y - transformedBarrelPos.Y)), -rotation);
|
||||
projectile.UpdateTransform();
|
||||
projectile.FindHull();
|
||||
projectile.Submarine = projectile.body.Submarine;
|
||||
|
||||
Projectile projectileComponent = projectile.GetComponent<Projectile>();
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Barotrauma
|
||||
public PhysicsBody body;
|
||||
|
||||
public readonly XElement StaticBodyConfig;
|
||||
|
||||
|
||||
private float lastSentCondition;
|
||||
private float sendConditionUpdateTimer;
|
||||
private bool conditionUpdatePending;
|
||||
@@ -211,14 +211,14 @@ namespace Barotrauma
|
||||
set { spriteColor = value; }
|
||||
}
|
||||
|
||||
[Serialize("1.0,1.0,1.0,1.0", true), Editable]
|
||||
[Serialize("1.0,1.0,1.0,1.0", false), Editable]
|
||||
public Color InventoryIconColor
|
||||
{
|
||||
get;
|
||||
protected set;
|
||||
}
|
||||
|
||||
[Serialize("1.0,1.0,1.0,1.0", true), Editable(ToolTip = "Changes the color of the item this item is contained inside. Only has an effect if either of the UseContainedSpriteColor or UseContainedInventoryIconColor property of the container is set to true.")]
|
||||
[Serialize("1.0,1.0,1.0,1.0", false), Editable(ToolTip = "Changes the color of the item this item is contained inside. Only has an effect if either of the UseContainedSpriteColor or UseContainedInventoryIconColor property of the container is set to true.")]
|
||||
public Color ContainerColor
|
||||
{
|
||||
get;
|
||||
@@ -274,11 +274,12 @@ namespace Barotrauma
|
||||
|
||||
SetActiveSprite();
|
||||
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer && !MathUtils.NearlyEqual(lastSentCondition, condition))
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer && lastSentCondition != condition)
|
||||
{
|
||||
if (Math.Abs(lastSentCondition - condition) > 1.0f || condition == 0.0f || condition == Prefab.Health)
|
||||
{
|
||||
conditionUpdatePending = true;
|
||||
GameMain.NetworkMember.CreateEntityEvent(this, new object[] { NetEntityEvent.Type.Status });
|
||||
lastSentCondition = condition;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -995,21 +996,6 @@ namespace Barotrauma
|
||||
aiTarget.SightRange -= deltaTime * 1000.0f;
|
||||
aiTarget.SoundRange -= deltaTime * 1000.0f;
|
||||
}
|
||||
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
||||
{
|
||||
sendConditionUpdateTimer -= deltaTime;
|
||||
if (conditionUpdatePending)
|
||||
{
|
||||
if (sendConditionUpdateTimer <= 0.0f)
|
||||
{
|
||||
GameMain.NetworkMember.CreateEntityEvent(this, new object[] { NetEntityEvent.Type.Status });
|
||||
lastSentCondition = condition;
|
||||
sendConditionUpdateTimer = NetConfig.ItemConditionUpdateInterval;
|
||||
conditionUpdatePending = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ApplyStatusEffects(ActionType.Always, deltaTime, null);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user