(ae643deeb) Added alive checks to a couple of diving gear status effects (don't consume tanks when dead)
This commit is contained in:
@@ -79,8 +79,8 @@
|
|||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\ParamsEditor.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\ParamsEditor.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\RectTransform.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\RectTransform.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\ShapeExtensions.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\UISprite.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\VideoPlayer.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\Widget.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\Widget.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Items\CharacterInventory.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Items\CharacterInventory.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Items\Components\Door.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Items\Components\Door.cs" />
|
||||||
@@ -213,6 +213,7 @@
|
|||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Sprite\DeformAnimations\SpriteDeformation.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Sprite\DeformAnimations\SpriteDeformation.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Sprite\Sprite.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Sprite\Sprite.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Sprite\SpriteSheet.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Sprite\SpriteSheet.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Source\StatusEffects\StatusEffect.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Utils\LocalizationCSVtoXML.cs">
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Utils\LocalizationCSVtoXML.cs">
|
||||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|||||||
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("0.8.9.6")]
|
[assembly: AssemblyVersion("0.8.9.8")]
|
||||||
[assembly: AssemblyFileVersion("0.8.9.6")]
|
[assembly: AssemblyFileVersion("0.8.9.8")]
|
||||||
|
|||||||
@@ -13,13 +13,39 @@ namespace Barotrauma
|
|||||||
var pos = new Vector2(WorldPosition.X, -WorldPosition.Y);
|
var pos = new Vector2(WorldPosition.X, -WorldPosition.Y);
|
||||||
if (soundRange > 0.0f)
|
if (soundRange > 0.0f)
|
||||||
{
|
{
|
||||||
Color color = Entity is Character ? Color.Yellow : Color.Orange;
|
Color color;
|
||||||
|
if (Entity is Character)
|
||||||
|
{
|
||||||
|
color = Color.Yellow;
|
||||||
|
}
|
||||||
|
else if (Entity is Item)
|
||||||
|
{
|
||||||
|
color = Color.Orange;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
color = Color.OrangeRed;
|
||||||
|
}
|
||||||
ShapeExtensions.DrawCircle(spriteBatch, pos, SoundRange, 100, color, thickness: 1 / Screen.Selected.Cam.Zoom);
|
ShapeExtensions.DrawCircle(spriteBatch, pos, 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)
|
if (sightRange > 0.0f)
|
||||||
{
|
{
|
||||||
Color color = Entity is Character ? Color.CornflowerBlue : Color.CadetBlue;
|
Color color;
|
||||||
|
if (Entity is Character)
|
||||||
|
{
|
||||||
|
color = Color.CornflowerBlue;
|
||||||
|
}
|
||||||
|
else if (Entity is Item)
|
||||||
|
{
|
||||||
|
color = Color.CadetBlue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
color = Color.WhiteSmoke;
|
||||||
|
}
|
||||||
ShapeExtensions.DrawCircle(spriteBatch, pos, SightRange, 100, color, thickness: 1 / Screen.Selected.Cam.Zoom);
|
ShapeExtensions.DrawCircle(spriteBatch, pos, SightRange, 100, color, thickness: 1 / Screen.Selected.Cam.Zoom);
|
||||||
|
ShapeExtensions.DrawCircle(spriteBatch, pos, 6, 8, color, thickness: 2 / Screen.Selected.Cam.Zoom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,18 +16,17 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (SelectedAiTarget?.Entity != null)
|
if (SelectedAiTarget?.Entity != null)
|
||||||
{
|
{
|
||||||
GUI.DrawLine(spriteBatch, pos, new Vector2(SelectedAiTarget.WorldPosition.X, -SelectedAiTarget.WorldPosition.Y), Color.Red * 0.3f, 0, 5);
|
GUI.DrawLine(spriteBatch, pos, new Vector2(SelectedAiTarget.WorldPosition.X, -SelectedAiTarget.WorldPosition.Y), Color.Red * 0.5f, 0, 4);
|
||||||
|
|
||||||
if (wallTarget != null)
|
if (wallTarget != null)
|
||||||
{
|
{
|
||||||
Vector2 wallTargetPos = wallTarget.Position;
|
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;
|
wallTargetPos.Y = -wallTargetPos.Y;
|
||||||
GUI.DrawRectangle(spriteBatch, wallTargetPos - new Vector2(10.0f, 10.0f), new Vector2(20.0f, 20.0f), Color.Red, false);
|
GUI.DrawRectangle(spriteBatch, wallTargetPos - new Vector2(10.0f, 10.0f), new Vector2(20.0f, 20.0f), Color.Orange, false);
|
||||||
GUI.DrawLine(spriteBatch, pos, wallTargetPos, Color.Orange * 0.5f, 0, 5);
|
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);
|
/*GUI.Font.DrawString(spriteBatch, targetValue.ToString(), pos - Vector2.UnitY * 80.0f, Color.Red);
|
||||||
@@ -52,24 +51,15 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 80.0f, State.ToString(), stateColor, Color.Black);
|
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,
|
GUI.DrawLine(spriteBatch,
|
||||||
ConvertUnits.ToDisplayUnits(new Vector2(attachJoint.WorldAnchorA.X, -attachJoint.WorldAnchorA.Y)),
|
ConvertUnits.ToDisplayUnits(new Vector2(attachJoint.WorldAnchorA.X, -attachJoint.WorldAnchorA.Y)),
|
||||||
ConvertUnits.ToDisplayUnits(new Vector2(attachJoint.WorldAnchorB.X, -attachJoint.WorldAnchorB.Y)), Color.Orange * 0.6f, 0, 5);
|
ConvertUnits.ToDisplayUnits(new Vector2(attachJoint.WorldAnchorB.X, -attachJoint.WorldAnchorB.Y)), Color.Green, 0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
if (LatchOntoAI.WallAttachPos.HasValue)
|
||||||
{
|
{
|
||||||
GUI.DrawLine(spriteBatch, pos,
|
GUI.DrawLine(spriteBatch, pos,
|
||||||
@@ -77,22 +67,34 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GUI.DrawLine(spriteBatch,
|
if (steeringManager is IndoorsSteeringManager pathSteering)
|
||||||
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++)
|
|
||||||
{
|
{
|
||||||
GUI.DrawLine(spriteBatch,
|
var path = pathSteering.CurrentPath;
|
||||||
new Vector2(pathSteering.CurrentPath.Nodes[i].DrawPosition.X, -pathSteering.CurrentPath.Nodes[i].DrawPosition.Y),
|
if (path != null)
|
||||||
new Vector2(pathSteering.CurrentPath.Nodes[i - 1].DrawPosition.X, -pathSteering.CurrentPath.Nodes[i - 1].DrawPosition.Y),
|
{
|
||||||
Color.Orange * 0.6f, 0, 3);
|
if (path.CurrentNode != null)
|
||||||
|
{
|
||||||
|
GUI.DrawLine(spriteBatch, pos,
|
||||||
|
new Vector2(path.CurrentNode.DrawPosition.X, -path.CurrentNode.DrawPosition.Y),
|
||||||
|
Color.DarkViolet, 0, 3);
|
||||||
|
|
||||||
GUI.SmallFont.DrawString(spriteBatch,
|
GUI.DrawString(spriteBatch, pos - new Vector2(0, 100), "Path cost: " + path.Cost.FormatZeroDecimal(), Color.White, Color.Black * 0.5f);
|
||||||
pathSteering.CurrentPath.Nodes[i].ID.ToString(),
|
}
|
||||||
new Vector2(pathSteering.CurrentPath.Nodes[i].DrawPosition.X, -pathSteering.CurrentPath.Nodes[i].DrawPosition.Y - 10),
|
for (int i = 1; i < path.Nodes.Count; i++)
|
||||||
Color.LightGreen);
|
{
|
||||||
|
var previousNode = path.Nodes[i - 1];
|
||||||
|
var currentNode = path.Nodes[i];
|
||||||
|
GUI.DrawLine(spriteBatch,
|
||||||
|
new Vector2(currentNode.DrawPosition.X, -currentNode.DrawPosition.Y),
|
||||||
|
new Vector2(previousNode.DrawPosition.X, -previousNode.DrawPosition.Y),
|
||||||
|
Color.Red * 0.5f, 0, 3);
|
||||||
|
|
||||||
|
GUI.SmallFont.DrawString(spriteBatch,
|
||||||
|
currentNode.ID.ToString(),
|
||||||
|
new Vector2(currentNode.DrawPosition.X + 20, -currentNode.DrawPosition.Y - 20),
|
||||||
|
Color.Red);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(Character.AnimController.TargetMovement.X, -Character.AnimController.TargetMovement.Y)), Color.SteelBlue, width: 2);
|
GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(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);
|
GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(Steering.X, -Steering.Y)), Color.Blue, width: 3);
|
||||||
|
|||||||
@@ -75,11 +75,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
GUI.SmallFont.DrawString(spriteBatch,
|
GUI.SmallFont.DrawString(spriteBatch,
|
||||||
currentNode.ID.ToString(),
|
currentNode.ID.ToString(),
|
||||||
new Vector2(currentNode.DrawPosition.X, -currentNode.DrawPosition.Y - 10),
|
new Vector2(currentNode.DrawPosition.X + 20, -currentNode.DrawPosition.Y - 20),
|
||||||
Color.LightGreen);
|
Color.SkyBlue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(Character.AnimController.TargetMovement.X, -Character.AnimController.TargetMovement.Y)), Color.SteelBlue, width: 2);
|
||||||
GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(Steering.X, -Steering.Y)), Color.Blue, width: 3);
|
GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(Steering.X, -Steering.Y)), Color.Blue, width: 3);
|
||||||
|
|
||||||
//if (Character.IsKeyDown(InputType.Aim))
|
//if (Character.IsKeyDown(InputType.Aim))
|
||||||
|
|||||||
@@ -88,13 +88,13 @@ namespace Barotrauma
|
|||||||
Collider.AngularVelocity = newAngularVelocity;
|
Collider.AngularVelocity = newAngularVelocity;
|
||||||
|
|
||||||
float distSqrd = Vector2.DistanceSquared(newPosition, Collider.SimPosition);
|
float distSqrd = Vector2.DistanceSquared(newPosition, Collider.SimPosition);
|
||||||
float errorTolerance = character.AllowInput ? 0.01f : 0.2f;
|
float errorTolerance = character.AllowInput ? 0.01f : 0.1f;
|
||||||
if (distSqrd > errorTolerance)
|
if (distSqrd > errorTolerance)
|
||||||
{
|
{
|
||||||
if (distSqrd > 10.0f || !character.AllowInput)
|
if (distSqrd > 10.0f || !character.AllowInput)
|
||||||
{
|
{
|
||||||
Collider.TargetRotation = newRotation;
|
Collider.TargetRotation = newRotation;
|
||||||
SetPosition(newPosition, lerp: distSqrd < 5.0f);
|
SetPosition(newPosition, lerp: distSqrd < 1.0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -108,15 +108,8 @@ namespace Barotrauma
|
|||||||
// -> we need to correct it manually
|
// -> we need to correct it manually
|
||||||
if (!character.AllowInput)
|
if (!character.AllowInput)
|
||||||
{
|
{
|
||||||
float mainLimbDistSqrd = Vector2.DistanceSquared(MainLimb.PullJointWorldAnchorA, Collider.SimPosition);
|
MainLimb.PullJointWorldAnchorB = Collider.SimPosition;
|
||||||
float mainLimbErrorTolerance = 0.1f;
|
MainLimb.PullJointEnabled = true;
|
||||||
//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();
|
character.MemLocalState.Clear();
|
||||||
|
|||||||
@@ -224,6 +224,20 @@ 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);
|
DoInteractionUpdate(deltaTime, mouseSimPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,6 +341,8 @@ namespace Barotrauma
|
|||||||
debugInteractablesAtCursor.Clear();
|
debugInteractablesAtCursor.Clear();
|
||||||
debugInteractablesNearCursor.Clear();
|
debugInteractablesNearCursor.Clear();
|
||||||
|
|
||||||
|
bool draggingItemToWorld = CharacterInventory.DraggingItemToWorld;
|
||||||
|
|
||||||
//reduce the amount of aim assist if an item has been selected
|
//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
|
//= 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
|
//otherwise it would be too easy to accidentally switch the selected item when rewiring items
|
||||||
@@ -348,6 +364,15 @@ namespace Barotrauma
|
|||||||
if (item.body != null && !item.body.Enabled) continue;
|
if (item.body != null && !item.body.Enabled) continue;
|
||||||
if (item.ParentInventory != null) continue;
|
if (item.ParentInventory != null) continue;
|
||||||
if (ignoredItems != null && ignoredItems.Contains(item)) continue;
|
if (ignoredItems != null && ignoredItems.Contains(item)) continue;
|
||||||
|
|
||||||
|
if (draggingItemToWorld)
|
||||||
|
{
|
||||||
|
if (item.OwnInventory == null ||
|
||||||
|
!item.OwnInventory.CanBePut(CharacterInventory.draggingItem))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float distanceToItem = float.PositiveInfinity;
|
float distanceToItem = float.PositiveInfinity;
|
||||||
if (item.IsInsideTrigger(displayPosition, out Rectangle transformedTrigger))
|
if (item.IsInsideTrigger(displayPosition, out Rectangle transformedTrigger))
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ namespace Barotrauma
|
|||||||
scale: scale);
|
scale: scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GUI.DisableItemHighlights)
|
if (!GUI.DisableItemHighlights && !Inventory.DraggingItemToWorld)
|
||||||
{
|
{
|
||||||
var hudTexts = focusedItem.GetHUDTexts(character);
|
var hudTexts = focusedItem.GetHUDTexts(character);
|
||||||
|
|
||||||
|
|||||||
@@ -241,10 +241,12 @@ namespace Barotrauma
|
|||||||
if (!string.IsNullOrEmpty(jobIdentifier))
|
if (!string.IsNullOrEmpty(jobIdentifier))
|
||||||
{
|
{
|
||||||
jobPrefab = JobPrefab.List.Find(jp => jp.Identifier == jobIdentifier);
|
jobPrefab = JobPrefab.List.Find(jp => jp.Identifier == jobIdentifier);
|
||||||
for (int i = 0; i < jobPrefab.Skills.Count; i++)
|
byte skillCount = inc.ReadByte();
|
||||||
|
for (int i = 0; i < skillCount; i++)
|
||||||
{
|
{
|
||||||
|
string skillIdentifier = inc.ReadString();
|
||||||
float skillLevel = inc.ReadSingle();
|
float skillLevel = inc.ReadSingle();
|
||||||
skillLevels.Add(jobPrefab.Skills[i].Identifier, skillLevel);
|
skillLevels.Add(skillIdentifier, skillLevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +256,6 @@ namespace Barotrauma
|
|||||||
ID = infoID,
|
ID = infoID,
|
||||||
};
|
};
|
||||||
ch.RecreateHead(headSpriteID,(Race)race, (Gender)gender, hairIndex, beardIndex, moustacheIndex, faceAttachmentIndex);
|
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)
|
if (ch.Job != null)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<string, float> skill in skillLevels)
|
foreach (KeyValuePair<string, float> skill in skillLevels)
|
||||||
@@ -262,11 +263,12 @@ namespace Barotrauma
|
|||||||
Skill matchingSkill = ch.Job.Skills.Find(s => s.Identifier == skill.Key);
|
Skill matchingSkill = ch.Job.Skills.Find(s => s.Identifier == skill.Key);
|
||||||
if (matchingSkill == null)
|
if (matchingSkill == null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Skill \"" + skill.Key + "\" not found in character \"" + newName + "\"");
|
ch.Job.Skills.Add(new Skill(skill.Key, skill.Value));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
matchingSkill.Level = skill.Value;
|
matchingSkill.Level = skill.Value;
|
||||||
}
|
}
|
||||||
|
ch.Job.Skills.RemoveAll(s => !skillLevels.ContainsKey(s.Identifier));
|
||||||
}
|
}
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using Lidgren.Network;
|
|||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -68,6 +68,14 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private float dropItemAnimDuration = 0.5f;
|
private float dropItemAnimDuration = 0.5f;
|
||||||
private float dropItemAnimTimer;
|
private float dropItemAnimTimer;
|
||||||
|
|
||||||
|
public Item DroppedItem
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return droppedItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
private Item droppedItem;
|
private Item droppedItem;
|
||||||
|
|
||||||
private GUIComponent draggingMed;
|
private GUIComponent draggingMed;
|
||||||
@@ -100,13 +108,15 @@ namespace Barotrauma
|
|||||||
if (openHealthWindow == value) return;
|
if (openHealthWindow == value) return;
|
||||||
if (value != null && !value.UseHealthWindow) return;
|
if (value != null && !value.UseHealthWindow) return;
|
||||||
|
|
||||||
|
var prevOpenHealthWindow = openHealthWindow;
|
||||||
|
|
||||||
openHealthWindow = value;
|
openHealthWindow = value;
|
||||||
toggledThisFrame = true;
|
toggledThisFrame = true;
|
||||||
if (Character.Controlled == null) { return; }
|
if (Character.Controlled == null) { return; }
|
||||||
|
|
||||||
if (value == null &&
|
if (value == null &&
|
||||||
Character.Controlled?.SelectedCharacter?.CharacterHealth != null &&
|
Character.Controlled?.SelectedCharacter?.CharacterHealth != null &&
|
||||||
Character.Controlled.SelectedCharacter.CharacterHealth == openHealthWindow &&
|
Character.Controlled.SelectedCharacter.CharacterHealth == prevOpenHealthWindow &&
|
||||||
!Character.Controlled.SelectedCharacter.CanInventoryBeAccessed)
|
!Character.Controlled.SelectedCharacter.CanInventoryBeAccessed)
|
||||||
{
|
{
|
||||||
Character.Controlled.DeselectCharacter();
|
Character.Controlled.DeselectCharacter();
|
||||||
@@ -537,11 +547,13 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (PlayerInput.KeyHit(InputType.Health) && GUI.KeyboardDispatcher.Subscriber == null &&
|
if (PlayerInput.KeyHit(InputType.Health) && GUI.KeyboardDispatcher.Subscriber == null &&
|
||||||
Character.AllowInput && Character.FocusedCharacter == null && !toggledThisFrame)
|
Character.Controlled.AllowInput && !toggledThisFrame)
|
||||||
{
|
{
|
||||||
if (openHealthWindow != null)
|
if (openHealthWindow != null)
|
||||||
|
{
|
||||||
OpenHealthWindow = null;
|
OpenHealthWindow = null;
|
||||||
else
|
}
|
||||||
|
else if (Character.Controlled == Character && Character.Controlled.FocusedCharacter == null)
|
||||||
{
|
{
|
||||||
OpenHealthWindow = this;
|
OpenHealthWindow = this;
|
||||||
forceAfflictionContainerUpdate = true;
|
forceAfflictionContainerUpdate = true;
|
||||||
@@ -554,7 +566,10 @@ namespace Barotrauma
|
|||||||
HUD.CloseHUD(HUDLayoutSettings.HealthWindowAreaLeft))
|
HUD.CloseHUD(HUDLayoutSettings.HealthWindowAreaLeft))
|
||||||
{
|
{
|
||||||
//emulate a Health input to get the character to deselect the item server-side
|
//emulate a Health input to get the character to deselect the item server-side
|
||||||
Character.Keys[(int)InputType.Health].Hit = true;
|
if (GameMain.Client != null)
|
||||||
|
{
|
||||||
|
Character.Controlled.Keys[(int)InputType.Health].Hit = true;
|
||||||
|
}
|
||||||
OpenHealthWindow = null;
|
OpenHealthWindow = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -403,6 +403,11 @@ namespace Barotrauma
|
|||||||
AssignRelayToServer("help", false);
|
AssignRelayToServer("help", false);
|
||||||
AssignRelayToServer("verboselogging", false);
|
AssignRelayToServer("verboselogging", false);
|
||||||
AssignRelayToServer("freecam", false);
|
AssignRelayToServer("freecam", false);
|
||||||
|
#if DEBUG
|
||||||
|
AssignRelayToServer("simulatedlatency", false);
|
||||||
|
AssignRelayToServer("simulatedloss", false);
|
||||||
|
AssignRelayToServer("simulatedduplicateschance", false);
|
||||||
|
#endif
|
||||||
|
|
||||||
commands.Add(new Command("clientlist", "", (string[] args) => { }));
|
commands.Add(new Command("clientlist", "", (string[] args) => { }));
|
||||||
AssignRelayToServer("clientlist", true);
|
AssignRelayToServer("clientlist", true);
|
||||||
@@ -957,6 +962,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
element.Value = lines[i];
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
}, isCheat: false));
|
}, isCheat: false));
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -178,10 +178,15 @@ namespace Barotrauma
|
|||||||
|
|
||||||
string displayedText = message.TranslatedText;
|
string displayedText = message.TranslatedText;
|
||||||
string senderName = "";
|
string senderName = "";
|
||||||
|
Color senderColor = Color.White;
|
||||||
if (!string.IsNullOrWhiteSpace(message.SenderName))
|
if (!string.IsNullOrWhiteSpace(message.SenderName))
|
||||||
{
|
{
|
||||||
senderName = (message.Type == ChatMessageType.Private ? "[PM] " : "") + 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,
|
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);
|
color: ((chatBox.Content.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f);
|
||||||
@@ -191,7 +196,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
senderNameBlock = new GUITextBlock(new RectTransform(new Vector2(0.98f, 0.0f), msgHolder.RectTransform)
|
senderNameBlock = new GUITextBlock(new RectTransform(new Vector2(0.98f, 0.0f), msgHolder.RectTransform)
|
||||||
{ AbsoluteOffset = new Point((int)(5 * GUI.Scale), 0) },
|
{ AbsoluteOffset = new Point((int)(5 * GUI.Scale), 0) },
|
||||||
senderName, textColor: Color.White, font: GUI.SmallFont, textAlignment: Alignment.TopLeft, style: null)
|
senderName, textColor: senderColor, font: GUI.SmallFont, textAlignment: Alignment.TopLeft, style: null)
|
||||||
{
|
{
|
||||||
CanBeFocused = true
|
CanBeFocused = true
|
||||||
};
|
};
|
||||||
@@ -230,7 +235,7 @@ namespace Barotrauma
|
|||||||
Visible = false
|
Visible = false
|
||||||
};
|
};
|
||||||
var senderText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), popupMsg.RectTransform, Anchor.TopRight),
|
var senderText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), popupMsg.RectTransform, Anchor.TopRight),
|
||||||
senderName, textColor: Color.White, font: GUI.SmallFont, textAlignment: Alignment.TopRight)
|
senderName, textColor: senderColor, font: GUI.SmallFont, textAlignment: Alignment.TopRight)
|
||||||
{
|
{
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
@@ -328,6 +333,7 @@ namespace Barotrauma
|
|||||||
var popupMsg = popupMessages.Count > 0 ? popupMessages.Peek() : null;
|
var popupMsg = popupMessages.Count > 0 ? popupMessages.Peek() : null;
|
||||||
if (popupMsg != 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;
|
popupMsg.Visible = true;
|
||||||
//popup messages appear and disappear faster when there's more pending messages
|
//popup messages appear and disappear faster when there's more pending messages
|
||||||
popupMessageTimer += deltaTime * popupMessages.Count * popupMessages.Count;
|
popupMessageTimer += deltaTime * popupMessages.Count * popupMessages.Count;
|
||||||
@@ -335,7 +341,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
//move the message out of the screen and delete it
|
//move the message out of the screen and delete it
|
||||||
popupMsg.RectTransform.ScreenSpaceOffset =
|
popupMsg.RectTransform.ScreenSpaceOffset =
|
||||||
new Point((int)MathHelper.SmoothStep(-popupMsg.Rect.Width - toggleButton.Rect.Width * 2, 10, (popupMessageTimer - PopupMessageDuration) * 5.0f), 0);
|
new Point((int)MathHelper.SmoothStep(offset, 10, (popupMessageTimer - PopupMessageDuration) * 5.0f), 0);
|
||||||
if (popupMessageTimer > PopupMessageDuration + 1.0f)
|
if (popupMessageTimer > PopupMessageDuration + 1.0f)
|
||||||
{
|
{
|
||||||
popupMessageTimer = 0.0f;
|
popupMessageTimer = 0.0f;
|
||||||
@@ -347,7 +353,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
//move the message on the screen
|
//move the message on the screen
|
||||||
popupMsg.RectTransform.ScreenSpaceOffset = new Point(
|
popupMsg.RectTransform.ScreenSpaceOffset = new Point(
|
||||||
(int)MathHelper.SmoothStep(0, -popupMsg.Rect.Width - toggleButton.Rect.Width * 2 - (int)(35 * GUI.Scale), popupMessageTimer * 5.0f), 0);
|
(int)MathHelper.SmoothStep(0, offset, popupMessageTimer * 5.0f), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ namespace Barotrauma
|
|||||||
private static List<GUIMessage> messages = new List<GUIMessage>();
|
private static List<GUIMessage> messages = new List<GUIMessage>();
|
||||||
private static Sound[] sounds;
|
private static Sound[] sounds;
|
||||||
private static bool pauseMenuOpen, settingsMenuOpen;
|
private static bool pauseMenuOpen, settingsMenuOpen;
|
||||||
private static GUIFrame pauseMenu;
|
public static GUIFrame PauseMenu { get; private set; }
|
||||||
private static Sprite arrow, lockIcon, checkmarkIcon, timerIcon;
|
private static Sprite arrow, lockIcon, checkmarkIcon, timerIcon;
|
||||||
|
|
||||||
public static KeyboardDispatcher KeyboardDispatcher { get; set; }
|
public static KeyboardDispatcher KeyboardDispatcher { get; set; }
|
||||||
@@ -69,6 +69,9 @@ namespace Barotrauma
|
|||||||
public static ScalableFont Font => Style?.Font;
|
public static ScalableFont Font => Style?.Font;
|
||||||
public static ScalableFont SmallFont => Style?.SmallFont;
|
public static ScalableFont SmallFont => Style?.SmallFont;
|
||||||
public static ScalableFont LargeFont => Style?.LargeFont;
|
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;
|
public static UISprite UIGlow => Style.UIGlow;
|
||||||
|
|
||||||
@@ -530,14 +533,19 @@ namespace Barotrauma
|
|||||||
if (list.Count == 0) { return; }
|
if (list.Count == 0) { return; }
|
||||||
foreach (var item in list)
|
foreach (var item in list)
|
||||||
{
|
{
|
||||||
int i = updateList.Count - 1;
|
int index = 0;
|
||||||
while (updateList[i].UpdateOrder > item.UpdateOrder)
|
if (updateList.Count > 0)
|
||||||
{
|
{
|
||||||
i--;
|
index = updateList.Count - 1;
|
||||||
|
while (updateList[index].UpdateOrder > item.UpdateOrder)
|
||||||
|
{
|
||||||
|
index--;
|
||||||
|
if (index == 0) { break; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!updateListSet.Contains(item))
|
if (!updateListSet.Contains(item))
|
||||||
{
|
{
|
||||||
updateList.Insert(Math.Max(i, 0), item);
|
updateList.Insert(index, item);
|
||||||
updateListSet.Add(item);
|
updateListSet.Add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -553,7 +561,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (pauseMenuOpen)
|
if (pauseMenuOpen)
|
||||||
{
|
{
|
||||||
pauseMenu.AddToGUIUpdateList();
|
PauseMenu.AddToGUIUpdateList();
|
||||||
}
|
}
|
||||||
if (settingsMenuOpen)
|
if (settingsMenuOpen)
|
||||||
{
|
{
|
||||||
@@ -648,6 +656,7 @@ namespace Barotrauma
|
|||||||
msg.Timer -= deltaTime;
|
msg.Timer -= deltaTime;
|
||||||
msg.Pos += msg.Velocity * deltaTime;
|
msg.Pos += msg.Velocity * deltaTime;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
messages.RemoveAll(m => m.Timer <= 0.0f);
|
messages.RemoveAll(m => m.Timer <= 0.0f);
|
||||||
}
|
}
|
||||||
@@ -721,6 +730,10 @@ namespace Barotrauma
|
|||||||
Vector2 textSize = font.MeasureString(text);
|
Vector2 textSize = font.MeasureString(text);
|
||||||
DrawRectangle(sb, pos - Vector2.One * backgroundPadding, textSize + Vector2.One * 2.0f * backgroundPadding, (Color)backgroundColor, true);
|
DrawRectangle(sb, pos - Vector2.One * backgroundPadding, textSize + Vector2.One * 2.0f * backgroundPadding, (Color)backgroundColor, true);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.Draw(t, new Rectangle(rect.X + thickness, rect.Y, rect.Width - thickness * 2, thickness), null, clr, 0.0f, Vector2.Zero, SpriteEffects.None, depth);
|
||||||
|
sb.Draw(t, new Rectangle(rect.X + thickness, rect.Y + rect.Height - thickness, rect.Width - thickness * 2, thickness), null, clr, 0.0f, Vector2.Zero, SpriteEffects.None, depth);
|
||||||
|
|
||||||
font.DrawString(sb, text, pos, color);
|
font.DrawString(sb, text, pos, color);
|
||||||
}
|
}
|
||||||
@@ -1412,9 +1425,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (pauseMenuOpen)
|
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))
|
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.85f, 0.85f), pauseMenuInner.RectTransform, Anchor.Center))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ namespace Barotrauma
|
|||||||
public ScalableFont Font { get; private set; }
|
public ScalableFont Font { get; private set; }
|
||||||
public ScalableFont SmallFont { get; private set; }
|
public ScalableFont SmallFont { get; private set; }
|
||||||
public ScalableFont LargeFont { 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; }
|
public Sprite CursorSprite { get; private set; }
|
||||||
|
|
||||||
@@ -48,6 +51,15 @@ namespace Barotrauma
|
|||||||
case "largefont":
|
case "largefont":
|
||||||
LargeFont = new ScalableFont(subElement, graphicsDevice);
|
LargeFont = new ScalableFont(subElement, graphicsDevice);
|
||||||
break;
|
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":
|
case "cursor":
|
||||||
CursorSprite = new Sprite(subElement);
|
CursorSprite = new Sprite(subElement);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -50,6 +50,11 @@ namespace Barotrauma
|
|||||||
get; private set;
|
get; private set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Rectangle ObjectiveAnchor
|
||||||
|
{
|
||||||
|
get; private set;
|
||||||
|
}
|
||||||
|
|
||||||
public static Rectangle InventoryAreaLower
|
public static Rectangle InventoryAreaLower
|
||||||
{
|
{
|
||||||
get; private set;
|
get; private set;
|
||||||
@@ -156,6 +161,10 @@ namespace Barotrauma
|
|||||||
new Rectangle(Padding, CrewArea.Y, chatBoxWidth, chatBoxHeight) :
|
new Rectangle(Padding, CrewArea.Y, chatBoxWidth, chatBoxHeight) :
|
||||||
new Rectangle(GameMain.GraphicsWidth - Padding - chatBoxWidth, 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);
|
int lowerAreaHeight = (int)Math.Min(GameMain.GraphicsHeight * 0.25f, 280);
|
||||||
InventoryAreaLower = new Rectangle(Padding, GameMain.GraphicsHeight - lowerAreaHeight, GameMain.GraphicsWidth - Padding * 2, lowerAreaHeight);
|
InventoryAreaLower = new Rectangle(Padding, GameMain.GraphicsHeight - lowerAreaHeight, GameMain.GraphicsWidth - Padding * 2, lowerAreaHeight);
|
||||||
|
|
||||||
@@ -191,6 +200,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
public static bool CloseHUD(Rectangle rect)
|
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
|
//don't close when the cursor is on a UI element
|
||||||
if (GUI.MouseOn != null) return false;
|
if (GUI.MouseOn != null) return false;
|
||||||
|
|
||||||
|
|||||||
@@ -601,8 +601,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
((GUIMessageBox)GUIMessageBox.VisibleBox).Close();
|
((GUIMessageBox)GUIMessageBox.VisibleBox).Close();
|
||||||
}
|
}
|
||||||
else // Otherwise toggle pausing.
|
else if ((Character.Controlled?.SelectedConstruction == null || !Character.Controlled.SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null))
|
||||||
|
&& Inventory.SelectedSlot == null && CharacterHealth.OpenHealthWindow == null)
|
||||||
{
|
{
|
||||||
|
// Otherwise toggle pausing, unless another window/interface is open.
|
||||||
GUI.TogglePauseMenu();
|
GUI.TogglePauseMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,7 +130,12 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
OnEnterMessage = (textbox, text) =>
|
OnEnterMessage = (textbox, text) =>
|
||||||
{
|
{
|
||||||
if (Character.Controlled == null) { return true; }
|
if (Character.Controlled?.Info == null)
|
||||||
|
{
|
||||||
|
textbox.Deselect();
|
||||||
|
textbox.Text = "";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
textbox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Default];
|
textbox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Default];
|
||||||
|
|
||||||
@@ -976,7 +981,7 @@ namespace Barotrauma
|
|||||||
foreach (GUIComponent c in prevCharacterListBox.Content.Children)
|
foreach (GUIComponent c in prevCharacterListBox.Content.Children)
|
||||||
{
|
{
|
||||||
Character character = c.UserData as Character;
|
Character character = c.UserData as Character;
|
||||||
if (character == null) continue;
|
if (character == null || character.IsDead || character.Removed) continue;
|
||||||
AddCharacter(character);
|
AddCharacter(character);
|
||||||
DisplayCharacterOrder(character, character.CurrentOrder);
|
DisplayCharacterOrder(character, character.CurrentOrder);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
ContextualTutorial = Tutorial.Tutorials.Find(t => t is ContextualTutorial) as ContextualTutorial;
|
ContextualTutorial = Tutorial.Tutorials.Find(t => t is ContextualTutorial) as ContextualTutorial;
|
||||||
|
|
||||||
if (ContextualTutorial.Selected && !ContextualTutorial.Initialized) // Selected when starting a new game -> initialize
|
if (ContextualTutorial.Selected) // Selected when starting a new game -> initialize
|
||||||
{
|
{
|
||||||
ContextualTutorial.Initialize();
|
ContextualTutorial.Initialize();
|
||||||
}
|
}
|
||||||
|
|||||||
+382
-98
@@ -1,9 +1,10 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Barotrauma.Items.Components;
|
using Barotrauma.Items.Components;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Microsoft.Xna.Framework.Input;
|
||||||
|
|
||||||
namespace Barotrauma.Tutorials
|
namespace Barotrauma.Tutorials
|
||||||
{
|
{
|
||||||
@@ -13,38 +14,59 @@ namespace Barotrauma.Tutorials
|
|||||||
public static bool ContentRunning = false;
|
public static bool ContentRunning = false;
|
||||||
public static bool Initialized = false;
|
public static bool Initialized = false;
|
||||||
|
|
||||||
private enum ContentTypes { None = 0, Video = 1, Text = 2 };
|
private enum ContentTypes { None = 0, Video = 1, TextOnly = 2 };
|
||||||
|
|
||||||
private TutorialSegment activeSegment;
|
private TutorialSegment activeSegment;
|
||||||
private List<TutorialSegment> segments;
|
private List<TutorialSegment> segments;
|
||||||
|
|
||||||
private SpriteSheetPlayer spriteSheetPlayer;
|
private VideoPlayer videoPlayer;
|
||||||
|
|
||||||
private Steering navConsole;
|
private Steering navConsole;
|
||||||
private Reactor reactor;
|
private Reactor reactor;
|
||||||
private Sonar sonar;
|
private Sonar sonar;
|
||||||
private Vector2 subStartingPosition;
|
private Vector2 subStartingPosition;
|
||||||
private List<Character> crew;
|
private List<Character> crew;
|
||||||
|
private Character mechanic;
|
||||||
|
private Character engineer;
|
||||||
|
private Character injuredMember = null;
|
||||||
|
|
||||||
private List<Pair<Character, float>> characterTimeOnSonar;
|
private List<Pair<Character, float>> characterTimeOnSonar;
|
||||||
private float requiredTimeOnSonar = 5f;
|
private float requiredTimeOnSonar = 5f;
|
||||||
|
|
||||||
private bool started = false;
|
private bool started = false;
|
||||||
private string playableContentPath;
|
private string playableContentPath;
|
||||||
|
|
||||||
private float tutorialTimer;
|
private float tutorialTimer;
|
||||||
private float degrading2ActivationCountdown;
|
|
||||||
|
|
||||||
private bool disableTutorialOnDeficiencyFound = true;
|
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
|
private class TutorialSegment
|
||||||
{
|
{
|
||||||
public string Name;
|
public string Id;
|
||||||
|
public string Objective;
|
||||||
public ContentTypes ContentType;
|
public ContentTypes ContentType;
|
||||||
public XElement Content;
|
public XElement TextContent;
|
||||||
|
public XElement VideoContent;
|
||||||
public bool IsTriggered;
|
public bool IsTriggered;
|
||||||
|
public GUIButton ReplayButton;
|
||||||
|
public GUITextBlock LinkedTitle, LinkedText;
|
||||||
|
|
||||||
public TutorialSegment(XElement config)
|
public TutorialSegment(XElement config)
|
||||||
{
|
{
|
||||||
Name = config.GetAttributeString("name", "Missing Name");
|
Id = config.GetAttributeString("id", "Missing ID");
|
||||||
|
Objective = TextManager.Get(config.GetAttributeString("objective", string.Empty), true);
|
||||||
Enum.TryParse(config.GetAttributeString("contenttype", "None"), true, out ContentType);
|
Enum.TryParse(config.GetAttributeString("contenttype", "None"), true, out ContentType);
|
||||||
IsTriggered = config.GetAttributeBool("istriggered", false);
|
IsTriggered = config.GetAttributeBool("istriggered", false);
|
||||||
|
|
||||||
@@ -53,10 +75,11 @@ namespace Barotrauma.Tutorials
|
|||||||
case ContentTypes.None:
|
case ContentTypes.None:
|
||||||
break;
|
break;
|
||||||
case ContentTypes.Video:
|
case ContentTypes.Video:
|
||||||
Content = config.Element("Video");
|
VideoContent = config.Element("Video");
|
||||||
|
TextContent = config.Element("Text");
|
||||||
break;
|
break;
|
||||||
case ContentTypes.Text:
|
case ContentTypes.TextOnly:
|
||||||
Content = config.Element("Text");
|
TextContent = config.Element("Text");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,17 +100,17 @@ namespace Barotrauma.Tutorials
|
|||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
if (Initialized) return;
|
|
||||||
Initialized = true;
|
|
||||||
|
|
||||||
base.Initialize();
|
|
||||||
spriteSheetPlayer = new SpriteSheetPlayer();
|
|
||||||
characterTimeOnSonar = new List<Pair<Character, float>>();
|
|
||||||
|
|
||||||
for (int i = 0; i < segments.Count; i++)
|
for (int i = 0; i < segments.Count; i++)
|
||||||
{
|
{
|
||||||
segments[i].IsTriggered = false;
|
segments[i].IsTriggered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Initialized) return;
|
||||||
|
Initialized = true;
|
||||||
|
|
||||||
|
base.Initialize();
|
||||||
|
videoPlayer = new VideoPlayer();
|
||||||
|
characterTimeOnSonar = new List<Pair<Character, float>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadPartiallyComplete(XElement element)
|
public void LoadPartiallyComplete(XElement element)
|
||||||
@@ -111,15 +134,6 @@ 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)
|
public void SavePartiallyComplete(XElement element)
|
||||||
{
|
{
|
||||||
XElement tutorialElement = new XElement("contextualtutorial");
|
XElement tutorialElement = new XElement("contextualtutorial");
|
||||||
@@ -151,13 +165,13 @@ namespace Barotrauma.Tutorials
|
|||||||
{
|
{
|
||||||
if (!Initialized) return;
|
if (!Initialized) return;
|
||||||
|
|
||||||
PreloadVideoContent();
|
|
||||||
|
|
||||||
base.Start();
|
base.Start();
|
||||||
|
injuredMember = null;
|
||||||
|
activeObjectives.Clear();
|
||||||
|
objectiveTranslated = TextManager.Get("Objective");
|
||||||
|
CreateObjectiveFrame();
|
||||||
activeSegment = null;
|
activeSegment = null;
|
||||||
tutorialTimer = 0.0f;
|
tutorialTimer = floodTutorialTimer = medicalTutorialTimer = 0.0f;
|
||||||
degrading2ActivationCountdown = -1;
|
|
||||||
subStartingPosition = Vector2.Zero;
|
subStartingPosition = Vector2.Zero;
|
||||||
characterTimeOnSonar.Clear();
|
characterTimeOnSonar.Clear();
|
||||||
|
|
||||||
@@ -193,6 +207,9 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
|
|
||||||
crew = GameMain.GameSession.CrewManager.GetCharacters().ToList();
|
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
|
Completed = true; // Trigger completed at start to prevent the contextual tutorial from automatically activating on starting new campaigns after this one
|
||||||
started = true;
|
started = true;
|
||||||
}
|
}
|
||||||
@@ -208,71 +225,185 @@ namespace Barotrauma.Tutorials
|
|||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
started = ContentRunning = Initialized = false;
|
started = ContentRunning = Initialized = false;
|
||||||
spriteSheetPlayer.Remove();
|
videoPlayer.Remove();
|
||||||
spriteSheetPlayer = null;
|
videoPlayer = null;
|
||||||
characterTimeOnSonar = 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()
|
public override void AddToGUIUpdateList()
|
||||||
{
|
{
|
||||||
base.AddToGUIUpdateList();
|
if (videoPlayer != null)
|
||||||
if (spriteSheetPlayer != null)
|
|
||||||
{
|
{
|
||||||
spriteSheetPlayer.AddToGUIUpdateList();
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float deltaTime)
|
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;
|
if (!started || ContentRunning) return;
|
||||||
|
|
||||||
deltaTime *= 0.5f;
|
deltaTime *= 0.5f;
|
||||||
|
|
||||||
for (int i = 0; i < segments.Count; i++)
|
for (int i = 0; i < segments.Count; i++)
|
||||||
{
|
{
|
||||||
if (segments[i].IsTriggered) continue;
|
if (segments[i].IsTriggered || activeObjectives.Contains(segments[i])) continue;
|
||||||
if (CheckContextualTutorials(i, deltaTime)) // Found a relevant tutorial, halt finding new ones
|
if (CheckContextualTutorials(i, deltaTime)) // Found a relevant tutorial, halt finding new ones
|
||||||
{
|
{
|
||||||
break;
|
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()
|
private void CurrentSegmentStopCallback()
|
||||||
{
|
{
|
||||||
|
if (!string.IsNullOrEmpty(activeSegment.Objective))
|
||||||
|
{
|
||||||
|
AddNewObjective(activeSegment);
|
||||||
|
}
|
||||||
|
|
||||||
activeSegment = null;
|
activeSegment = null;
|
||||||
ContentRunning = false;
|
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)
|
private bool CheckContextualTutorials(int index, float deltaTime)
|
||||||
{
|
{
|
||||||
switch (index)
|
switch (index)
|
||||||
{
|
{
|
||||||
case 0: // Welcome: Game Start [Text]
|
case 0: // Welcome: Game Start [Text]
|
||||||
if (tutorialTimer < 0.5f)
|
if (tutorialTimer < 1.0f)
|
||||||
{
|
{
|
||||||
tutorialTimer += deltaTime;
|
tutorialTimer += deltaTime;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1: // Command Reactor: 10 seconds after 'Welcome' dismissed and only if no command given to start reactor [Video]
|
case 1: // Command Reactor: 2 seconds after 'Welcome' dismissed and only if no command given to start reactor [Video]
|
||||||
if (tutorialTimer < 10.5f)
|
if (!segments[0].IsTriggered) return false;
|
||||||
|
if (tutorialTimer < 3.0f)
|
||||||
{
|
{
|
||||||
tutorialTimer += deltaTime;
|
tutorialTimer += deltaTime;
|
||||||
|
|
||||||
if (HasOrder("operatereactor"))
|
if (HasOrder("operatereactor"))
|
||||||
{
|
{
|
||||||
segments[index].IsTriggered = true;
|
segments[index].IsTriggered = true;
|
||||||
tutorialTimer = 10.5f;
|
tutorialTimer = 2.5f;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: // Nav Console: 20 seconds after 'Command Reactor' dismissed or if nav console is activated [Video]
|
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
|
||||||
if (Character.Controlled?.SelectedConstruction != navConsole.Item)
|
if (Character.Controlled?.SelectedConstruction != navConsole.Item)
|
||||||
{
|
{
|
||||||
if (!segments[1].IsTriggered) return false; // Do not advance tutorial timer based on this segment if reactor has not been powered up
|
if (tutorialTimer < 4.5f)
|
||||||
if (tutorialTimer < 30.5f)
|
|
||||||
{
|
{
|
||||||
tutorialTimer += deltaTime;
|
tutorialTimer += deltaTime;
|
||||||
return false;
|
return false;
|
||||||
@@ -280,20 +411,13 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!segments[1].IsTriggered || !HasOrder("operatereactor")) // If reactor has not been powered up or ordered to be, default to that one first
|
tutorialTimer = 4.5f;
|
||||||
{
|
|
||||||
if (tutorialTimer < 10.5f)
|
|
||||||
{
|
|
||||||
tutorialTimer = 10.5f;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
tutorialTimer = 30.5f;
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
TriggerTutorialSegment(index, GameMain.GameSession.EndLocation.Name);
|
||||||
|
return true;
|
||||||
case 3: // Objective: Travel ~150 meters and while sub is not flooding [Text]
|
case 3: // Objective: Travel ~150 meters and while sub is not flooding [Text]
|
||||||
if (Vector2.Distance(subStartingPosition, Submarine.MainSub.WorldPosition) < 12000f || IsFlooding())
|
if (Vector2.Distance(subStartingPosition, Submarine.MainSub.WorldPosition) < 8000f || IsFlooding())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -307,6 +431,11 @@ namespace Barotrauma.Tutorials
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if (floodTutorialTimer < floodTutorialDelay)
|
||||||
|
{
|
||||||
|
floodTutorialTimer += deltaTime;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 5: // Reactor: Player uses reactor for the first time [Video]
|
case 5: // Reactor: Player uses reactor for the first time [Video]
|
||||||
if (Character.Controlled?.SelectedConstruction != reactor.Item)
|
if (Character.Controlled?.SelectedConstruction != reactor.Item)
|
||||||
@@ -321,19 +450,23 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 7: // Degrading1: Any equipment degrades to 50% health or less and player has not assigned any crew to perform maintenance [Text]
|
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;
|
bool degradedEquipmentFound = false;
|
||||||
|
|
||||||
foreach (Item item in Item.ItemList)
|
foreach (Item item in Item.ItemList)
|
||||||
{
|
{
|
||||||
if (!item.Repairables.Any() || item.ConditionPercentage > 50) continue;
|
if (!item.Repairables.Any() || item.Condition > 50.0f) continue;
|
||||||
degradedEquipmentFound = true;
|
degradedEquipmentFound = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (degradedEquipmentFound)
|
if (degradedEquipmentFound)
|
||||||
{
|
{
|
||||||
degrading2ActivationCountdown = 5f;
|
if (HasOrder("repairsystems", "jobspecific"))
|
||||||
if (HasOrder("repairsystems"))
|
|
||||||
{
|
{
|
||||||
segments[index].IsTriggered = true;
|
segments[index].IsTriggered = true;
|
||||||
return false;
|
return false;
|
||||||
@@ -344,43 +477,44 @@ namespace Barotrauma.Tutorials
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 8: // Degrading2: 5 seconds after 'Degrading1' dismissed, and only if player has not assigned any crew to perform maintenance [Video]
|
case 8: // Medical: Crewmember is injured but not killed [Video]
|
||||||
if (degrading2ActivationCountdown == -1f)
|
|
||||||
|
if (injuredMember == null)
|
||||||
{
|
{
|
||||||
return false;
|
for (int i = 0; i < crew.Count; i++)
|
||||||
}
|
|
||||||
else if (degrading2ActivationCountdown > 0.0f)
|
|
||||||
{
|
|
||||||
degrading2ActivationCountdown -= deltaTime;
|
|
||||||
if (HasOrder("repairsystems"))
|
|
||||||
{
|
{
|
||||||
segments[index].IsTriggered = true;
|
Character member = crew[i];
|
||||||
|
if (member.Vitality < member.MaxVitality && !member.IsDead)
|
||||||
|
{
|
||||||
|
injuredMember = member;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
else if (medicalTutorialTimer < medicalTutorialDelay)
|
||||||
case 9: // Medical: Crewmember is injured but not killed [Video]
|
|
||||||
bool injuredFound = false;
|
|
||||||
for (int i = 0; i < crew.Count; i++)
|
|
||||||
{
|
{
|
||||||
Character member = crew[i];
|
medicalTutorialTimer += deltaTime;
|
||||||
if (member.Vitality < member.MaxVitality && !member.IsDead)
|
return false;
|
||||||
{
|
|
||||||
injuredFound = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (!injuredFound) return false;
|
{
|
||||||
break;
|
TriggerTutorialSegment(index, new string[] { injuredMember.Info.DisplayName,
|
||||||
case 10: // Approach1: Destination is within ~100m [Video]
|
(injuredMember.Info.Gender == Gender.Male) ? TextManager.Get("PronounPossessiveMale").ToLower() : TextManager.Get("PronounPossessiveFemale").ToLower() });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case 9: // Approach1: Destination is within ~100m [Video]
|
||||||
if (Vector2.Distance(Submarine.MainSub.WorldPosition, Level.Loaded.EndPosition) > 8000f)
|
if (Vector2.Distance(Submarine.MainSub.WorldPosition, Level.Loaded.EndPosition) > 8000f)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
else
|
||||||
case 11: // Approach2: Sub is docked [Text]
|
{
|
||||||
|
TriggerTutorialSegment(index, GameMain.GameSession.EndLocation.Name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case 10: // Approach2: Sub is docked [Text]
|
||||||
if (!Submarine.MainSub.AtEndPosition || Submarine.MainSub.DockedTo.Count == 0)
|
if (!Submarine.MainSub.AtEndPosition || Submarine.MainSub.DockedTo.Count == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -392,11 +526,128 @@ namespace Barotrauma.Tutorials
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool HasOrder(string aiTag)
|
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)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < crew.Count; i++)
|
for (int i = 0; i < crew.Count; i++)
|
||||||
{
|
{
|
||||||
if (crew[i].CurrentOrder?.AITag == aiTag) return true;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -406,10 +657,12 @@ namespace Barotrauma.Tutorials
|
|||||||
{
|
{
|
||||||
foreach (Gap gap in Gap.GapList)
|
foreach (Gap gap in Gap.GapList)
|
||||||
{
|
{
|
||||||
if (gap.ConnectedWall == null) continue;
|
if (gap.ConnectedWall == null || gap.IsRoomToRoom) continue;
|
||||||
if (gap.ConnectedDoor != null || gap.Open <= 0.0f) continue;
|
if (gap.ConnectedDoor != null || gap.Open <= 0.0f) continue;
|
||||||
if (gap.Submarine == null) continue;
|
if (gap.Submarine == null) continue;
|
||||||
|
if (gap.Submarine.IsOutpost) continue;
|
||||||
if (gap.Submarine != Submarine.MainSub) continue;
|
if (gap.Submarine != Submarine.MainSub) continue;
|
||||||
|
if (gap.FlowTargetHull == null || gap.FlowTargetHull.WaterPercentage <= 0.0f) continue;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -447,27 +700,51 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return characterTimeOnSonar.Find(ct => ct.Second >= requiredTimeOnSonar) != null;
|
return characterTimeOnSonar.Find(ct => ct.Second >= requiredTimeOnSonar && !ct.First.IsDead) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TriggerTutorialSegment(int index, params object[] args)
|
private void TriggerTutorialSegment(int index, params object[] args)
|
||||||
{
|
{
|
||||||
|
Inventory.draggingItem = null;
|
||||||
ContentRunning = true;
|
ContentRunning = true;
|
||||||
activeSegment = segments[index];
|
activeSegment = segments[index];
|
||||||
activeSegment.IsTriggered = true;
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
switch (activeSegment.ContentType)
|
switch (activeSegment.ContentType)
|
||||||
{
|
{
|
||||||
case ContentTypes.None:
|
case ContentTypes.None:
|
||||||
break;
|
break;
|
||||||
case ContentTypes.Video:
|
case ContentTypes.Video:
|
||||||
spriteSheetPlayer.LoadContent(playableContentPath, activeSegment.Content, activeSegment.Name, true, true, CurrentSegmentStopCallback);
|
infoBox = CreateInfoFrame(TextManager.Get(activeSegment.Id), tutorialText,
|
||||||
|
activeSegment.TextContent.GetAttributeInt("width", 300),
|
||||||
|
activeSegment.TextContent.GetAttributeInt("height", 80),
|
||||||
|
activeSegment.TextContent.GetAttributeString("anchor", "Center"), true, ClosePreTextAndTriggerVideoCallback);
|
||||||
break;
|
break;
|
||||||
case ContentTypes.Text:
|
case ContentTypes.TextOnly:
|
||||||
infoBox = CreateInfoFrame(TextManager.Get(activeSegment.Name), TextManager.GetFormatted(activeSegment.Content.GetAttributeString("tag", ""), false, args),
|
infoBox = CreateInfoFrame(TextManager.Get(activeSegment.Id), tutorialText,
|
||||||
activeSegment.Content.GetAttributeInt("width", 300),
|
activeSegment.TextContent.GetAttributeInt("width", 300),
|
||||||
activeSegment.Content.GetAttributeInt("height", 80),
|
activeSegment.TextContent.GetAttributeInt("height", 80),
|
||||||
activeSegment.Content.GetAttributeString("anchor", "Center"), true, CurrentSegmentStopCallback);
|
activeSegment.TextContent.GetAttributeString("anchor", "Center"), true, CurrentSegmentStopCallback);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -479,6 +756,13 @@ namespace Barotrauma.Tutorials
|
|||||||
CoroutineManager.StartCoroutine(WaitToStop()); // Completed
|
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()
|
private IEnumerable<object> WaitToStop()
|
||||||
{
|
{
|
||||||
while (ContentRunning) yield return null;
|
while (ContentRunning) yield return null;
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ namespace Barotrauma.Tutorials
|
|||||||
|
|
||||||
public virtual void AddToGUIUpdateList()
|
public virtual void AddToGUIUpdateList()
|
||||||
{
|
{
|
||||||
if (infoBox != null) infoBox.AddToGUIUpdateList();
|
if (infoBox != null) infoBox.AddToGUIUpdateList(order: 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Update(float deltaTime)
|
public virtual void Update(float deltaTime)
|
||||||
@@ -188,17 +188,19 @@ namespace Barotrauma.Tutorials
|
|||||||
Anchor anchor = Anchor.TopRight;
|
Anchor anchor = Anchor.TopRight;
|
||||||
Enum.TryParse(anchorStr, out anchor);
|
Enum.TryParse(anchorStr, out anchor);
|
||||||
|
|
||||||
var infoBlock = new GUIFrame(new RectTransform(new Point(width, height), GUI.Canvas, anchor) { AbsoluteOffset = new Point(20) });
|
var infoBlock = new GUIFrame(new RectTransform(new Point((int)(width * GUI.Scale), (int)(height * GUI.Scale)), GUI.Canvas, anchor) { AbsoluteOffset = new Point(20) });
|
||||||
infoBlock.Flash(Color.Green);
|
infoBlock.Flash(Color.Green);
|
||||||
|
|
||||||
if (title.Length > 0)
|
if (title.Length > 0)
|
||||||
{
|
{
|
||||||
var titleBlock = new GUITextBlock(new RectTransform(new Vector2(1f, .35f), infoBlock.RectTransform, Anchor.TopCenter,
|
var titleBlock = new GUITextBlock(new RectTransform(new Vector2(1f, .35f), infoBlock.RectTransform, Anchor.TopCenter,
|
||||||
Pivot.TopCenter), title, font: GUI.LargeFont, textAlignment: Alignment.Center);
|
Pivot.TopCenter), title, font: GUI.VideoTitleFont, textAlignment: Alignment.Center, textColor: new Color(253, 174, 0));
|
||||||
|
titleBlock.TextScale = GUI.Scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
var textBlock = new GUITextBlock(new RectTransform(new Vector2(0.9f, 1f), infoBlock.RectTransform, Anchor.BottomCenter),
|
var textBlock = new GUITextBlock(new RectTransform(new Vector2(0.9f, 1f), infoBlock.RectTransform, Anchor.BottomCenter),
|
||||||
text, wrap: true);
|
text, wrap: true);
|
||||||
|
textBlock.TextScale = GUI.Scale;
|
||||||
|
|
||||||
infoBoxClosedCallback = callback;
|
infoBoxClosedCallback = callback;
|
||||||
|
|
||||||
|
|||||||
@@ -14,12 +14,13 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
private enum Tab
|
private enum Tab
|
||||||
{
|
{
|
||||||
General,
|
|
||||||
Graphics,
|
Graphics,
|
||||||
Audio,
|
Audio,
|
||||||
Controls,
|
Controls,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly Point MinSupportedResolution = new Point(1024, 540);
|
||||||
|
|
||||||
private GUIFrame settingsFrame;
|
private GUIFrame settingsFrame;
|
||||||
private GUIButton applyButton;
|
private GUIButton applyButton;
|
||||||
|
|
||||||
@@ -71,16 +72,79 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void CreateSettingsFrame()
|
private void CreateSettingsFrame()
|
||||||
{
|
{
|
||||||
settingsFrame = new GUIFrame(new RectTransform(new Point(500, 500), GUI.Canvas, Anchor.Center));
|
settingsFrame = new GUIFrame(new RectTransform(new Vector2(0.8f, 0.8f), GUI.Canvas, Anchor.Center));
|
||||||
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), settingsFrame.RectTransform),
|
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);
|
||||||
TextManager.Get("Settings"), textAlignment: Alignment.Center, font: GUI.LargeFont);
|
|
||||||
|
|
||||||
var paddedFrame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.8f), settingsFrame.RectTransform, Anchor.Center)
|
/// General tab --------------------------------------------------------------
|
||||||
{ RelativeOffset = new Vector2(0.0f, 0.06f) }, style: null);
|
|
||||||
|
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 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];
|
tabs = new GUIFrame[Enum.GetValues(typeof(Tab)).Length];
|
||||||
tabButtons = new GUIButton[tabs.Length];
|
tabButtons = new GUIButton[tabs.Length];
|
||||||
@@ -104,10 +168,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
var leftColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.46f, 0.95f), tabs[(int)Tab.Graphics].RectTransform, Anchor.CenterLeft)
|
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) })
|
{ RelativeOffset = new Vector2(0.02f, 0.0f) })
|
||||||
{ RelativeSpacing = 0.01f, Stretch = true };
|
{ RelativeSpacing = 0.01f };
|
||||||
var rightColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.46f, 0.95f), tabs[(int)Tab.Graphics].RectTransform, Anchor.CenterRight)
|
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) })
|
{ RelativeOffset = new Vector2(0.02f, 0.0f) })
|
||||||
{ RelativeSpacing = 0.01f, Stretch = true };
|
{ RelativeSpacing = 0.01f };
|
||||||
|
|
||||||
var supportedDisplayModes = new List<DisplayMode>();
|
var supportedDisplayModes = new List<DisplayMode>();
|
||||||
foreach (DisplayMode mode in GraphicsAdapter.DefaultAdapter.SupportedDisplayModes)
|
foreach (DisplayMode mode in GraphicsAdapter.DefaultAdapter.SupportedDisplayModes)
|
||||||
@@ -135,6 +199,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
foreach (DisplayMode mode in supportedDisplayModes)
|
foreach (DisplayMode mode in supportedDisplayModes)
|
||||||
{
|
{
|
||||||
|
if (mode.Width < MinSupportedResolution.X || mode.Height < MinSupportedResolution.Y) { continue; }
|
||||||
resolutionDD.AddItem(mode.Width + "x" + mode.Height, mode);
|
resolutionDD.AddItem(mode.Width + "x" + mode.Height, mode);
|
||||||
if (GraphicsWidth == mode.Width && GraphicsHeight == mode.Height) resolutionDD.SelectItem(mode);
|
if (GraphicsWidth == mode.Width && GraphicsHeight == mode.Height) resolutionDD.SelectItem(mode);
|
||||||
}
|
}
|
||||||
@@ -173,9 +238,6 @@ namespace Barotrauma
|
|||||||
return true;
|
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"))
|
GUITickBox vsyncTickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), TextManager.Get("EnableVSync"))
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("EnableVSyncToolTip"),
|
ToolTip = TextManager.Get("EnableVSyncToolTip"),
|
||||||
@@ -191,8 +253,6 @@ namespace Barotrauma
|
|||||||
Selected = VSyncEnabled
|
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"));
|
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),
|
GUIScrollBar particleScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform),
|
||||||
barSize: 0.1f)
|
barSize: 0.1f)
|
||||||
@@ -209,8 +269,6 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
particleScrollBar.OnMoved(particleScrollBar, particleScrollBar.BarScroll);
|
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"));
|
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));
|
var losModeDD = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform));
|
||||||
losModeDD.AddItem(TextManager.Get("LosModeNone"), LosMode.None);
|
losModeDD.AddItem(TextManager.Get("LosModeNone"), LosMode.None);
|
||||||
@@ -229,8 +287,6 @@ namespace Barotrauma
|
|||||||
return true;
|
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"))
|
GUITextBlock LightText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("LightMapScale"))
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("LightMapScaleToolTip")
|
ToolTip = TextManager.Get("LightMapScaleToolTip")
|
||||||
@@ -251,8 +307,6 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
lightScrollBar.OnMoved(lightScrollBar, lightScrollBar.BarScroll);
|
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"))
|
new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("SpecularLighting"))
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("SpecularLightingToolTip"),
|
ToolTip = TextManager.Get("SpecularLightingToolTip"),
|
||||||
@@ -265,8 +319,6 @@ 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"))
|
new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("ChromaticAberration"))
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("ChromaticAberrationToolTip"),
|
ToolTip = TextManager.Get("ChromaticAberrationToolTip"),
|
||||||
@@ -279,9 +331,6 @@ 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"));
|
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),
|
GUIScrollBar HUDScaleScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform),
|
||||||
barSize: 0.1f)
|
barSize: 0.1f)
|
||||||
@@ -300,9 +349,6 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
HUDScaleScrollBar.OnMoved(HUDScaleScrollBar, HUDScaleScrollBar.BarScroll);
|
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"));
|
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)
|
GUIScrollBar inventoryScaleScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), barSize: 0.1f)
|
||||||
{
|
{
|
||||||
@@ -319,9 +365,6 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
inventoryScaleScrollBar.OnMoved(inventoryScaleScrollBar, inventoryScaleScrollBar.BarScroll);
|
inventoryScaleScrollBar.OnMoved(inventoryScaleScrollBar, inventoryScaleScrollBar.BarScroll);
|
||||||
|
|
||||||
//spacing
|
|
||||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.2f), rightColumn.RectTransform), style: null);
|
|
||||||
|
|
||||||
/// Audio tab ----------------------------------------------------------------
|
/// Audio tab ----------------------------------------------------------------
|
||||||
|
|
||||||
var audioSliders = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.4f), tabs[(int)Tab.Audio].RectTransform, Anchor.TopCenter)
|
var audioSliders = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.4f), tabs[(int)Tab.Audio].RectTransform, Anchor.TopCenter)
|
||||||
@@ -567,9 +610,10 @@ namespace Barotrauma
|
|||||||
var inputNames = Enum.GetValues(typeof(InputType));
|
var inputNames = Enum.GetValues(typeof(InputType));
|
||||||
for (int i = 0; i < inputNames.Length; i++)
|
for (int i = 0; i < inputNames.Length; i++)
|
||||||
{
|
{
|
||||||
var inputContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.06f), inputFrame.RectTransform), style: null);
|
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.6f, 1.0f), inputContainer.RectTransform), TextManager.Get("InputType." + ((InputType)i)) + ": ", font: GUI.SmallFont);
|
new GUITextBlock(new RectTransform(new Vector2(0.3f, 1.0f), inputContainer.RectTransform, Anchor.TopLeft) { MinSize = new Point(150, 0) },
|
||||||
var keyBox = new GUITextBox(new RectTransform(new Vector2(0.4f, 1.0f), inputContainer.RectTransform, Anchor.TopRight),
|
TextManager.Get("InputType." + ((InputType)i)) + ": ", font: GUI.SmallFont) { ForceUpperCase = true };
|
||||||
|
var keyBox = new GUITextBox(new RectTransform(new Vector2(0.7f, 1.0f), inputContainer.RectTransform),
|
||||||
text: keyMapping[i].ToString(), font: GUI.SmallFont)
|
text: keyMapping[i].ToString(), font: GUI.SmallFont)
|
||||||
{
|
{
|
||||||
UserData = i
|
UserData = i
|
||||||
@@ -593,88 +637,11 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
aimAssistSlider.OnMoved(aimAssistSlider, aimAssistSlider.BarScroll);
|
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
|
//spacing
|
||||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), generalLayoutGroup.RectTransform), style: null);
|
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),
|
new GUIButton(new RectTransform(new Vector2(0.4f, 1.0f), buttonArea.RectTransform, Anchor.BottomLeft),
|
||||||
TextManager.Get("Cancel"))
|
TextManager.Get("Cancel"), style: "GUIButtonLarge")
|
||||||
{
|
{
|
||||||
IgnoreLayoutGroups = true,
|
IgnoreLayoutGroups = true,
|
||||||
OnClicked = (x, y) =>
|
OnClicked = (x, y) =>
|
||||||
@@ -690,7 +657,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
applyButton = new GUIButton(new RectTransform(new Vector2(0.4f, 1.0f), buttonArea.RectTransform, Anchor.BottomRight),
|
applyButton = new GUIButton(new RectTransform(new Vector2(0.4f, 1.0f), buttonArea.RectTransform, Anchor.BottomRight),
|
||||||
TextManager.Get("ApplySettingsButton"))
|
TextManager.Get("ApplySettingsButton"), style: "GUIButtonLarge")
|
||||||
{
|
{
|
||||||
IgnoreLayoutGroups = true,
|
IgnoreLayoutGroups = true,
|
||||||
Enabled = false
|
Enabled = false
|
||||||
@@ -698,7 +665,7 @@ namespace Barotrauma
|
|||||||
applyButton.OnClicked = ApplyClicked;
|
applyButton.OnClicked = ApplyClicked;
|
||||||
|
|
||||||
UnsavedSettings = false; // Reset unsaved settings to false once the UI has been created
|
UnsavedSettings = false; // Reset unsaved settings to false once the UI has been created
|
||||||
SelectTab(Tab.General);
|
SelectTab(Tab.Graphics);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SelectTab(Tab tab)
|
private void SelectTab(Tab tab)
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch, bool editing)
|
public void Draw(SpriteBatch spriteBatch, bool editing)
|
||||||
{
|
{
|
||||||
Color color = Color.White;
|
Color color = item.SpriteColor;
|
||||||
if (brokenSprite == null)
|
if (brokenSprite == null)
|
||||||
{
|
{
|
||||||
//broken doors turn black if no broken sprite has been configured
|
//broken doors turn black if no broken sprite has been configured
|
||||||
@@ -108,7 +108,7 @@ namespace Barotrauma.Items.Components
|
|||||||
weldSpritePos.Y = -weldSpritePos.Y;
|
weldSpritePos.Y = -weldSpritePos.Y;
|
||||||
|
|
||||||
weldedSprite.Draw(spriteBatch,
|
weldedSprite.Draw(spriteBatch,
|
||||||
weldSpritePos, Color.White * (stuck / 100.0f), scale: item.Scale);
|
weldSpritePos, item.SpriteColor * (stuck / 100.0f), scale: item.Scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (openState == 1.0f)
|
if (openState == 1.0f)
|
||||||
|
|||||||
@@ -175,63 +175,6 @@ 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;
|
private bool shouldMuffleLooping;
|
||||||
@@ -553,7 +496,11 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
msg = msg.Replace("[" + inputType.ToString().ToLowerInvariant() + "]", GameMain.Config.KeyBind(inputType).ToString());
|
msg = msg.Replace("[" + inputType.ToString().ToLowerInvariant() + "]", GameMain.Config.KeyBind(inputType).ToString());
|
||||||
}
|
}
|
||||||
Msg = msg;
|
DisplayMsg = msg;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DisplayMsg = Msg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
|
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
|
||||||
{
|
{
|
||||||
DeattachTimer = msg.ReadSingle();
|
deattachTimer = msg.ReadSingle();
|
||||||
if (deattachTimer >= DeattachDuration)
|
if (deattachTimer >= DeattachDuration)
|
||||||
{
|
{
|
||||||
holdable.DeattachFromWall();
|
holdable.DeattachFromWall();
|
||||||
|
|||||||
@@ -25,6 +25,12 @@ namespace Barotrauma.Items.Components
|
|||||||
DrawHUDBack, null);
|
DrawHUDBack, null);
|
||||||
submarineContainer = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.85f), GuiFrame.RectTransform, Anchor.Center), style: 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)),
|
hullInfoFrame = new GUIFrame(new RectTransform(new Vector2(0.13f, 0.13f), GUI.Canvas, minSize: new Point(250, 150)),
|
||||||
style: "InnerFrame")
|
style: "InnerFrame")
|
||||||
{
|
{
|
||||||
@@ -47,7 +53,7 @@ namespace Barotrauma.Items.Components
|
|||||||
public override void AddToGUIUpdateList()
|
public override void AddToGUIUpdateList()
|
||||||
{
|
{
|
||||||
base.AddToGUIUpdateList();
|
base.AddToGUIUpdateList();
|
||||||
if (hasPower) hullInfoFrame.AddToGUIUpdateList();
|
hullInfoFrame.AddToGUIUpdateList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnMapLoaded()
|
public override void OnMapLoaded()
|
||||||
@@ -96,6 +102,27 @@ 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)
|
private void DrawHUDBack(SpriteBatch spriteBatch, GUICustomComponent container)
|
||||||
{
|
{
|
||||||
Hull mouseOnHull = null;
|
Hull mouseOnHull = null;
|
||||||
@@ -221,7 +248,7 @@ namespace Barotrauma.Items.Components
|
|||||||
foreach (Submarine sub in subs)
|
foreach (Submarine sub in subs)
|
||||||
{
|
{
|
||||||
if (sub.HullVertices == null) { continue; }
|
if (sub.HullVertices == null) { continue; }
|
||||||
|
|
||||||
Rectangle worldBorders = sub.GetDockedBorders();
|
Rectangle worldBorders = sub.GetDockedBorders();
|
||||||
worldBorders.Location += sub.WorldPosition.ToPoint();
|
worldBorders.Location += sub.WorldPosition.ToPoint();
|
||||||
|
|
||||||
@@ -242,6 +269,8 @@ namespace Barotrauma.Items.Components
|
|||||||
GUI.DrawLine(spriteBatch, center + start, center + end, Color.DarkCyan * Rand.Range(0.3f, 0.35f), width: 10);
|
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)
|
private void GetLinkedHulls(Hull hull, List<Hull> linkedHulls)
|
||||||
|
|||||||
@@ -107,7 +107,10 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
var warningBtn = new GUIButton(new RectTransform(new Point(buttonWidth, buttonHeight), columnLeft.RectTransform)
|
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)) },
|
{ AbsoluteOffset = new Point((i % buttonsPerRow) * (buttonWidth + spacing), (int)Math.Floor(i / (float)buttonsPerRow) * (buttonHeight + spacing)) },
|
||||||
TextManager.Get(warningTexts[i]), style: "IndicatorButton");
|
TextManager.Get(warningTexts[i]), style: "IndicatorButton")
|
||||||
|
{
|
||||||
|
CanBeFocused = false
|
||||||
|
};
|
||||||
|
|
||||||
var btnText = warningBtn.GetChild<GUITextBlock>();
|
var btnText = warningBtn.GetChild<GUITextBlock>();
|
||||||
btnText.Font = GUI.SmallFont;
|
btnText.Font = GUI.SmallFont;
|
||||||
|
|||||||
@@ -785,8 +785,9 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
foreach (Limb limb in c.AnimController.Limbs)
|
foreach (Limb limb in c.AnimController.Limbs)
|
||||||
{
|
{
|
||||||
float pointDist = ((limb.WorldPosition - pingSource) * displayScale).LengthSquared();
|
if (!limb.body.Enabled) { continue; }
|
||||||
|
|
||||||
|
float pointDist = ((limb.WorldPosition - pingSource) * displayScale).LengthSquared();
|
||||||
if (limb.SimPosition == Vector2.Zero || pointDist > DisplayRadius * DisplayRadius) continue;
|
if (limb.SimPosition == Vector2.Zero || pointDist > DisplayRadius * DisplayRadius) continue;
|
||||||
|
|
||||||
if (pointDist > prevPingRadiusSqr && pointDist < pingRadiusSqr)
|
if (pointDist > prevPingRadiusSqr && pointDist < pingRadiusSqr)
|
||||||
|
|||||||
@@ -127,6 +127,18 @@ namespace Barotrauma.Items.Components
|
|||||||
Stretch = true,
|
Stretch = true,
|
||||||
RelativeSpacing = 0.03f
|
RelativeSpacing = 0.03f
|
||||||
};
|
};
|
||||||
|
autopilotTickBox = new GUITickBox(new RectTransform(new Vector2(0.3f, 0.3f), paddedControlContainer.RectTransform),
|
||||||
|
TextManager.Get("SteeringAutoPilot"), style: "GUIRadioButton")
|
||||||
|
{
|
||||||
|
OnSelected = (GUITickBox box) =>
|
||||||
|
{
|
||||||
|
AutoPilot = box.Selected;
|
||||||
|
if (AutoPilot && MaintainPos)
|
||||||
|
{
|
||||||
|
posToMaintain = controlledSub == null ? item.WorldPosition : controlledSub.WorldPosition;
|
||||||
|
}
|
||||||
|
unsentChanges = true;
|
||||||
|
user = Character.Controlled;
|
||||||
|
|
||||||
maintainPosTickBox = new GUITickBox(new RectTransform(new Vector2(0.2f, 0.2f), paddedAutoPilotControls.RectTransform),
|
maintainPosTickBox = new GUITickBox(new RectTransform(new Vector2(0.2f, 0.2f), paddedAutoPilotControls.RectTransform),
|
||||||
TextManager.Get("SteeringMaintainPos"), font: GUI.SmallFont)
|
TextManager.Get("SteeringMaintainPos"), font: GUI.SmallFont)
|
||||||
@@ -484,26 +496,14 @@ namespace Barotrauma.Items.Components
|
|||||||
user = Character.Controlled;
|
user = Character.Controlled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!AutoPilot && Character.DisableControls)
|
if (!AutoPilot && Character.DisableControls && GUI.KeyboardDispatcher.Subscriber == null)
|
||||||
{
|
{
|
||||||
steeringAdjustSpeed = character == null ? 0.2f : MathHelper.Lerp(0.2f, 1.0f, character.GetSkillLevel("helm") / 100.0f);
|
steeringAdjustSpeed = character == null ? 0.2f : MathHelper.Lerp(0.2f, 1.0f, character.GetSkillLevel("helm") / 100.0f);
|
||||||
Vector2 input = Vector2.Zero;
|
Vector2 input = Vector2.Zero;
|
||||||
if (PlayerInput.KeyDown(InputType.Left))
|
if (PlayerInput.KeyDown(InputType.Left)) { input -= Vector2.UnitX; }
|
||||||
{
|
if (PlayerInput.KeyDown(InputType.Right)) { input += Vector2.UnitX; }
|
||||||
input -= Vector2.UnitX;
|
if (PlayerInput.KeyDown(InputType.Up)) { input += Vector2.UnitY; }
|
||||||
}
|
if (PlayerInput.KeyDown(InputType.Down)) { input -= Vector2.UnitY; }
|
||||||
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))
|
if (PlayerInput.KeyDown(Keys.LeftShift))
|
||||||
{
|
{
|
||||||
SteeringInput += input * deltaTime * 200;
|
SteeringInput += input * deltaTime * 200;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Barotrauma.Particles;
|
using Barotrauma.Particles;
|
||||||
using FarseerPhysics;
|
using FarseerPhysics;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -11,12 +12,21 @@ using System.Xml.Linq;
|
|||||||
namespace Barotrauma.Items.Components
|
namespace Barotrauma.Items.Components
|
||||||
{
|
{
|
||||||
partial class RepairTool
|
partial class RepairTool
|
||||||
|
#if DEBUG
|
||||||
|
: IDrawableComponent
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
public ParticleEmitter ParticleEmitter
|
public ParticleEmitter ParticleEmitter
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
private set;
|
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> ParticleEmitterHitStructure = new List<ParticleEmitter>();
|
||||||
private List<ParticleEmitter> ParticleEmitterHitCharacter = new List<ParticleEmitter>();
|
private List<ParticleEmitter> ParticleEmitterHitCharacter = new List<ParticleEmitter>();
|
||||||
@@ -122,5 +132,17 @@ namespace Barotrauma.Items.Components
|
|||||||
emitter.Second.Emit(deltaTime, particlePos, item.CurrentHull, particleAngle + MathHelper.Pi, -particleAngle + MathHelper.Pi);
|
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,4 +1,6 @@
|
|||||||
using Barotrauma.Particles;
|
using Barotrauma.Networking;
|
||||||
|
using Barotrauma.Particles;
|
||||||
|
using Lidgren.Network;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -112,8 +114,7 @@ namespace Barotrauma.Items.Components
|
|||||||
System.Diagnostics.Debug.Assert(GuiFrame.GetChild(0) is GUILayoutGroup, "Repair UI hierarchy has changed, could not find skill texts");
|
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)
|
foreach (GUIComponent c in GuiFrame.GetChild(0).Children)
|
||||||
{
|
{
|
||||||
Skill skill = c.UserData as Skill;
|
if (!(c.UserData is Skill skill)) continue;
|
||||||
if (skill == null) continue;
|
|
||||||
|
|
||||||
GUITextBlock textBlock = (GUITextBlock)c;
|
GUITextBlock textBlock = (GUITextBlock)c;
|
||||||
if (character.GetSkillLevel(skill.Identifier) < skill.Level)
|
if (character.GetSkillLevel(skill.Identifier) < skill.Level)
|
||||||
@@ -126,5 +127,15 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
|
||||||
|
{
|
||||||
|
deteriorationTimer = msg.ReadSingle();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClientWrite(NetBuffer msg, object[] extraData = null)
|
||||||
|
{
|
||||||
|
//no need to write anything, just letting the server know we started repairing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -169,20 +169,6 @@ namespace Barotrauma.Items.Components
|
|||||||
if (draggingConnected.Connect(this, !alreadyConnected, true))
|
if (draggingConnected.Connect(this, !alreadyConnected, true))
|
||||||
{
|
{
|
||||||
var otherConnection = draggingConnected.OtherConnection(this);
|
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);
|
SetWire(index, draggingConnected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ namespace Barotrauma.Items.Components
|
|||||||
Dictionary<AfflictionPrefab, float> combinedAfflictionStrengths = new Dictionary<AfflictionPrefab, float>();
|
Dictionary<AfflictionPrefab, float> combinedAfflictionStrengths = new Dictionary<AfflictionPrefab, float>();
|
||||||
foreach (Affliction affliction in allAfflictions)
|
foreach (Affliction affliction in allAfflictions)
|
||||||
{
|
{
|
||||||
if (affliction.Strength < affliction.Prefab.ActivationThreshold || affliction.Strength <= 0.0f) continue;
|
if (affliction.Strength < affliction.Prefab.ShowInHealthScannerThreshold || affliction.Strength <= 0.0f) continue;
|
||||||
if (combinedAfflictionStrengths.ContainsKey(affliction.Prefab))
|
if (combinedAfflictionStrengths.ContainsKey(affliction.Prefab))
|
||||||
{
|
{
|
||||||
combinedAfflictionStrengths[affliction.Prefab] += affliction.Strength;
|
combinedAfflictionStrengths[affliction.Prefab] += affliction.Strength;
|
||||||
|
|||||||
@@ -237,13 +237,13 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
railSprite?.Draw(spriteBatch,
|
railSprite?.Draw(spriteBatch,
|
||||||
drawPos,
|
drawPos,
|
||||||
Color.White,
|
item.SpriteColor,
|
||||||
rotation + MathHelper.PiOver2, item.Scale,
|
rotation + MathHelper.PiOver2, item.Scale,
|
||||||
SpriteEffects.None, item.SpriteDepth + (railSprite.Depth - item.Sprite.Depth));
|
SpriteEffects.None, item.SpriteDepth + (railSprite.Depth - item.Sprite.Depth));
|
||||||
|
|
||||||
barrelSprite?.Draw(spriteBatch,
|
barrelSprite?.Draw(spriteBatch,
|
||||||
drawPos - new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)) * recoilOffset * item.Scale,
|
drawPos - new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)) * recoilOffset * item.Scale,
|
||||||
Color.White,
|
item.SpriteColor,
|
||||||
rotation + MathHelper.PiOver2, item.Scale,
|
rotation + MathHelper.PiOver2, item.Scale,
|
||||||
SpriteEffects.None, item.SpriteDepth + (barrelSprite.Depth - item.Sprite.Depth));
|
SpriteEffects.None, item.SpriteDepth + (barrelSprite.Depth - item.Sprite.Depth));
|
||||||
|
|
||||||
|
|||||||
@@ -301,7 +301,7 @@ namespace Barotrauma
|
|||||||
protected virtual void ControlInput(Camera cam)
|
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.
|
// 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 || draggingItem != null)
|
if (selectedSlot != null && !DraggingItemToWorld)
|
||||||
{
|
{
|
||||||
cam.Freeze = true;
|
cam.Freeze = true;
|
||||||
}
|
}
|
||||||
@@ -609,8 +609,17 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (selectedSlot == null)
|
if (selectedSlot == null)
|
||||||
{
|
{
|
||||||
draggingItem.Drop(Character.Controlled);
|
if (DraggingItemToWorld &&
|
||||||
GUI.PlayUISound(GUISoundType.DropItem);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (selectedSlot.ParentInventory.Items[selectedSlot.SlotIndex] != draggingItem)
|
else if (selectedSlot.ParentInventory.Items[selectedSlot.SlotIndex] != draggingItem)
|
||||||
{
|
{
|
||||||
@@ -702,10 +711,27 @@ namespace Barotrauma
|
|||||||
int iconSize = (int)(64 * GUI.Scale);
|
int iconSize = (int)(64 * GUI.Scale);
|
||||||
float scale = Math.Min(Math.Min(iconSize / sprite.size.X, iconSize / sprite.size.Y), 1.5f);
|
float scale = Math.Min(Math.Min(iconSize / sprite.size.X, iconSize / sprite.size.Y), 1.5f);
|
||||||
Vector2 itemPos = PlayerInput.MousePosition;
|
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 + Vector2.One * 2, Color.Black, scale: scale);
|
||||||
sprite.Draw(spriteBatch,
|
sprite.Draw(spriteBatch,
|
||||||
itemPos,
|
itemPos,
|
||||||
sprite == draggingItem.Sprite ? draggingItem.GetSpriteColor() : draggingItem.GetInventoryIconColor(),
|
sprite == draggingItem.Sprite ? draggingItem.GetSpriteColor() : draggingItem.GetInventoryIconColor(),
|
||||||
scale: scale);
|
scale: scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
protected override void ControlInput(Camera cam)
|
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);
|
base.ControlInput(cam);
|
||||||
if (BackgroundFrame.Contains(PlayerInput.MousePosition))
|
if (BackgroundFrame.Contains(PlayerInput.MousePosition))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -232,11 +232,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!ResizeHorizontal && !ResizeVertical)
|
if (!ResizeHorizontal && !ResizeVertical)
|
||||||
{
|
{
|
||||||
sprite.Draw(spriteBatch, new Vector2(placeRect.Center.X, -(placeRect.Y - placeRect.Height / 2)), SpriteColor, scale: Scale * scale);
|
sprite.Draw(spriteBatch, new Vector2(placeRect.Center.X, -(placeRect.Y - placeRect.Height / 2)), SpriteColor * 0.8f, scale: Scale * scale);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (sprite != null) sprite.DrawTiled(spriteBatch, new Vector2(placeRect.X, -placeRect.Y), placeRect.Size.ToVector2(), null, SpriteColor);
|
if (sprite != null) sprite.DrawTiled(spriteBatch, new Vector2(placeRect.X, -placeRect.Y), placeRect.Size.ToVector2(), null, SpriteColor * 0.8f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
using Barotrauma.Networking;
|
using Barotrauma.Networking;
|
||||||
using Barotrauma.Particles;
|
using Barotrauma.Particles;
|
||||||
using Barotrauma.Sounds;
|
using Barotrauma.Sounds;
|
||||||
|
using Lidgren.Network;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using Microsoft.Xna.Framework.Input;
|
using Microsoft.Xna.Framework.Input;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.Xna.Framework.Input;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Lidgren.Network;
|
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -19,6 +18,8 @@ namespace Barotrauma
|
|||||||
private List<Decal> decals = new List<Decal>();
|
private List<Decal> decals = new List<Decal>();
|
||||||
|
|
||||||
private float serverUpdateDelay;
|
private float serverUpdateDelay;
|
||||||
|
private float remoteWaterVolume, remoteOxygenPercentage;
|
||||||
|
private List<Vector3> remoteFireSources;
|
||||||
|
|
||||||
private bool networkUpdatePending;
|
private bool networkUpdatePending;
|
||||||
private float networkUpdateTimer;
|
private float networkUpdateTimer;
|
||||||
@@ -139,6 +140,10 @@ namespace Barotrauma
|
|||||||
partial void UpdateProjSpecific(float deltaTime, Camera cam)
|
partial void UpdateProjSpecific(float deltaTime, Camera cam)
|
||||||
{
|
{
|
||||||
serverUpdateDelay -= deltaTime;
|
serverUpdateDelay -= deltaTime;
|
||||||
|
if (serverUpdateDelay <= 0.0f)
|
||||||
|
{
|
||||||
|
ApplyRemoteState();
|
||||||
|
}
|
||||||
|
|
||||||
if (networkUpdatePending)
|
if (networkUpdatePending)
|
||||||
{
|
{
|
||||||
@@ -547,18 +552,18 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void ClientRead(ServerNetObject type, NetBuffer message, float sendingTime)
|
public void ClientRead(ServerNetObject type, NetBuffer message, float sendingTime)
|
||||||
{
|
{
|
||||||
float newWaterVolume = message.ReadRangedSingle(0.0f, 1.5f, 8) * Volume;
|
remoteWaterVolume = message.ReadRangedSingle(0.0f, 1.5f, 8) * Volume;
|
||||||
float newOxygenPercentage = message.ReadRangedSingle(0.0f, 100.0f, 8);
|
remoteOxygenPercentage = message.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||||
|
|
||||||
bool hasFireSources = message.ReadBoolean();
|
bool hasFireSources = message.ReadBoolean();
|
||||||
int fireSourceCount = 0;
|
int fireSourceCount = 0;
|
||||||
List<Vector3> newFireSources = new List<Vector3>();
|
remoteFireSources = new List<Vector3>();
|
||||||
if (hasFireSources)
|
if (hasFireSources)
|
||||||
{
|
{
|
||||||
fireSourceCount = message.ReadRangedInteger(0, 16);
|
fireSourceCount = message.ReadRangedInteger(0, 16);
|
||||||
for (int i = 0; i < fireSourceCount; i++)
|
for (int i = 0; i < fireSourceCount; i++)
|
||||||
{
|
{
|
||||||
newFireSources.Add(new Vector3(
|
remoteFireSources.Add(new Vector3(
|
||||||
MathHelper.Clamp(message.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f),
|
MathHelper.Clamp(message.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f),
|
||||||
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)));
|
message.ReadRangedSingle(0.0f, 1.0f, 8)));
|
||||||
@@ -567,41 +572,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (serverUpdateDelay > 0.0f) { return; }
|
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();
|
ApplyRemoteState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -247,15 +247,11 @@ namespace Barotrauma.Lights
|
|||||||
|
|
||||||
public void Rotate(Vector2 origin, float amount)
|
public void Rotate(Vector2 origin, float amount)
|
||||||
{
|
{
|
||||||
Matrix rotationMatrix = Matrix.CreateRotationZ(amount);
|
Matrix rotationMatrix =
|
||||||
|
Matrix.CreateTranslation(-origin.X, -origin.Y, 0.0f) *
|
||||||
Vector2[] newVerts = new Vector2[vertices.Length];
|
Matrix.CreateRotationZ(amount) *
|
||||||
for (int i = 0; i < vertices.Length; i++)
|
Matrix.CreateTranslation(origin.X, origin.Y, 0.0f);
|
||||||
{
|
SetVertices(vertices.Select(v => v.Pos).ToArray(), rotationMatrix);
|
||||||
newVerts[i] = Vector2.Transform(vertices[i].Pos - origin, rotationMatrix) + origin;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetVertices(newVerts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CalculateDimensions()
|
private void CalculateDimensions()
|
||||||
|
|||||||
@@ -453,7 +453,10 @@ namespace Barotrauma.Lights
|
|||||||
|
|
||||||
//raster pattern on top of everything
|
//raster pattern on top of everything
|
||||||
spriteBatch.Begin(blendState: BlendState.AlphaBlend, samplerState: SamplerState.LinearWrap);
|
spriteBatch.Begin(blendState: BlendState.AlphaBlend, samplerState: SamplerState.LinearWrap);
|
||||||
spriteBatch.Draw(highlightRaster, new Rectangle(0, 0, HighlightMap.Width, HighlightMap.Height), new Rectangle(0, 0, HighlightMap.Width, HighlightMap.Height), Color.White * 0.5f);
|
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.End();
|
spriteBatch.End();
|
||||||
|
|
||||||
DeformableSprite.Effect.CurrentTechnique = DeformableSprite.Effect.Techniques["DeformShader"];
|
DeformableSprite.Effect.CurrentTechnique = DeformableSprite.Effect.Techniques["DeformShader"];
|
||||||
|
|||||||
@@ -364,15 +364,23 @@ 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)
|
if (GUI.MouseOn == mapContainer)
|
||||||
{
|
{
|
||||||
zoom += PlayerInput.ScrollWheelSpeed / 1000.0f;
|
zoom += PlayerInput.ScrollWheelSpeed / 1000.0f;
|
||||||
zoom = MathHelper.Clamp(zoom, 1.0f, 4.0f);
|
zoom = MathHelper.Clamp(zoom, 1.0f, 4.0f);
|
||||||
|
|
||||||
if (PlayerInput.MidButtonHeld())
|
if (PlayerInput.MidButtonHeld()) { drawOffset += PlayerInput.MouseSpeed / zoom; }
|
||||||
{
|
|
||||||
drawOffset += PlayerInput.MouseSpeed / zoom;
|
|
||||||
}
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (PlayerInput.DoubleClicked() && highlightedLocation != null)
|
if (PlayerInput.DoubleClicked() && highlightedLocation != null)
|
||||||
{
|
{
|
||||||
@@ -551,11 +559,6 @@ namespace Barotrauma
|
|||||||
null, connectionColor * MathHelper.Clamp(a, 0.1f, 0.5f), MathUtils.VectorToAngle(end - start),
|
null, connectionColor * MathHelper.Clamp(a, 0.1f, 0.5f), MathUtils.VectorToAngle(end - start),
|
||||||
new Vector2(0, 16), SpriteEffects.None, 0.01f);
|
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)
|
if (GameMain.DebugDraw && zoom > 1.0f && generationParams.ShowLevelTypeNames)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace Barotrauma
|
|||||||
drawRect.Location -= Submarine.MainSub.Position.ToPoint();
|
drawRect.Location -= Submarine.MainSub.Position.ToPoint();
|
||||||
}
|
}
|
||||||
drawRect.Y = -drawRect.Y;
|
drawRect.Y = -drawRect.Y;
|
||||||
GUI.DrawRectangle(spriteBatch, drawRect, Color.DarkBlue);
|
GUI.DrawRectangle(spriteBatch, drawRect, Color.White);
|
||||||
}
|
}
|
||||||
public void DrawListLine(SpriteBatch spriteBatch, Vector2 pos, Color color)
|
public void DrawListLine(SpriteBatch spriteBatch, Vector2 pos, Color color)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -75,7 +75,10 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
var h = new ConvexHull(verts, Color.Black, this);
|
var h = new ConvexHull(verts, Color.Black, this);
|
||||||
h.Rotate(position, rotation);
|
if (Math.Abs(rotation) > 0.001f)
|
||||||
|
{
|
||||||
|
h.Rotate(position, rotation);
|
||||||
|
}
|
||||||
convexHulls.Add(h);
|
convexHulls.Add(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,8 +295,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (damageEffect != null)
|
if (damageEffect != null)
|
||||||
{
|
{
|
||||||
float newCutoff = Sections[i].damage > 0 ?
|
float newCutoff = MathHelper.Lerp(0.0f, 0.65f, Sections[i].damage / Prefab.Health);
|
||||||
MathHelper.Lerp(0.2f, 0.65f, Sections[i].damage / Prefab.Health) : 0.0f;
|
|
||||||
|
|
||||||
if (Math.Abs(newCutoff - Submarine.DamageEffectCutoff) > 0.01f || color != Submarine.DamageEffectColor)
|
if (Math.Abs(newCutoff - Submarine.DamageEffectCutoff) > 0.01f || color != Submarine.DamageEffectColor)
|
||||||
{
|
{
|
||||||
@@ -360,6 +362,7 @@ namespace Barotrauma
|
|||||||
-Bodies[i].Rotation, Color.White);
|
-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)
|
public override void DrawPlacing(SpriteBatch spriteBatch, Rectangle placeRect, float scale = 1.0f)
|
||||||
{
|
{
|
||||||
// TODO: the scale property is not used
|
// TODO: the scale property is not used
|
||||||
sprite.DrawTiled(spriteBatch, new Vector2(placeRect.X, -placeRect.Y), new Vector2(placeRect.Width, placeRect.Height), textureScale: TextureScale * Scale);
|
sprite.DrawTiled(spriteBatch, new Vector2(placeRect.X, -placeRect.Y), new Vector2(placeRect.Width, placeRect.Height), color: Color.White * 0.8f, textureScale: TextureScale * Scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,8 +141,23 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
OnClicked = (btn, userdata) =>
|
OnClicked = (btn, userdata) =>
|
||||||
{
|
{
|
||||||
if (!permissions.HasFlag(ClientPermissions.ManageRound)) return false;
|
if (!permissions.HasFlag(ClientPermissions.ManageRound)) { return false; }
|
||||||
RequestRoundEnd();
|
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();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
Visible = false
|
Visible = false
|
||||||
@@ -622,7 +637,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (gameStarted) SetRadioButtonColor();
|
if (gameStarted) SetRadioButtonColor();
|
||||||
|
|
||||||
if (ShowNetStats)
|
if (ShowNetStats && client?.ServerConnection != null)
|
||||||
{
|
{
|
||||||
netStats.AddValue(NetStats.NetStatType.ReceivedBytes, client.ServerConnection.Statistics.ReceivedBytes);
|
netStats.AddValue(NetStats.NetStatType.ReceivedBytes, client.ServerConnection.Statistics.ReceivedBytes);
|
||||||
netStats.AddValue(NetStats.NetStatType.SentBytes, client.ServerConnection.Statistics.SentBytes);
|
netStats.AddValue(NetStats.NetStatType.SentBytes, client.ServerConnection.Statistics.SentBytes);
|
||||||
@@ -1109,7 +1124,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 + ").";
|
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);
|
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(""));
|
CoroutineManager.StartCoroutine(EndGame(""));
|
||||||
yield return CoroutineStatus.Failure;
|
yield return CoroutineStatus.Failure;
|
||||||
}
|
}
|
||||||
@@ -1381,9 +1396,6 @@ namespace Barotrauma.Networking
|
|||||||
case ServerNetObject.CLIENT_LIST:
|
case ServerNetObject.CLIENT_LIST:
|
||||||
ReadClientList(inc);
|
ReadClientList(inc);
|
||||||
break;
|
break;
|
||||||
case ServerNetObject.CLIENT_LIST:
|
|
||||||
ReadClientList(inc);
|
|
||||||
break;
|
|
||||||
case ServerNetObject.CHAT_MESSAGE:
|
case ServerNetObject.CHAT_MESSAGE:
|
||||||
ChatMessage.ClientRead(inc);
|
ChatMessage.ClientRead(inc);
|
||||||
break;
|
break;
|
||||||
@@ -1439,7 +1451,11 @@ namespace Barotrauma.Networking
|
|||||||
break;
|
break;
|
||||||
case ServerNetObject.ENTITY_EVENT:
|
case ServerNetObject.ENTITY_EVENT:
|
||||||
case ServerNetObject.ENTITY_EVENT_INITIAL:
|
case ServerNetObject.ENTITY_EVENT_INITIAL:
|
||||||
if (!entityEventManager.Read(objHeader, inc, sendingTime, entities)) { break; }
|
if (!entityEventManager.Read(objHeader, inc, sendingTime, entities))
|
||||||
|
{
|
||||||
|
eventReadFailed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ServerNetObject.CHAT_MESSAGE:
|
case ServerNetObject.CHAT_MESSAGE:
|
||||||
ChatMessage.ClientRead(inc);
|
ChatMessage.ClientRead(inc);
|
||||||
@@ -1703,6 +1719,8 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
SaveUtil.LoadGame(GameMain.GameSession.SavePath, GameMain.GameSession);
|
SaveUtil.LoadGame(GameMain.GameSession.SavePath, GameMain.GameSession);
|
||||||
campaign.LastSaveID = campaign.PendingSaveID;
|
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
|
//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)
|
//(as there may have been campaign updates after the save file was created)
|
||||||
campaign.LastUpdateID--;
|
campaign.LastUpdateID--;
|
||||||
@@ -1720,7 +1738,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public override void CreateEntityEvent(INetSerializable entity, object[] extraData)
|
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);
|
entityEventManager.CreateEvent(entity as IClientSerializable, extraData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1989,7 +2007,8 @@ namespace Barotrauma.Networking
|
|||||||
msg.Write(true); msg.WritePadBits();
|
msg.Write(true); msg.WritePadBits();
|
||||||
msg.Write(savePath);
|
msg.Write(savePath);
|
||||||
msg.Write(mapSeed);
|
msg.Write(mapSeed);
|
||||||
msg.Write(sub.FilePath);
|
msg.Write(sub.Name);
|
||||||
|
msg.Write(sub.MD5Hash.Hash);
|
||||||
|
|
||||||
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
UpdateSubList(submarines);
|
UpdateSubList(submarines);
|
||||||
|
|
||||||
// New game right side
|
// New game right sideon
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), rightColumn.RectTransform), TextManager.Get("SaveName") + ":", textAlignment: Alignment.BottomLeft);
|
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);
|
saveNameBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.1f), rightColumn.RectTransform), string.Empty);
|
||||||
|
|
||||||
@@ -262,11 +262,6 @@ namespace Barotrauma
|
|||||||
saveFiles = SaveUtil.GetSaveFiles(isMultiplayer ? SaveUtil.SaveType.Multiplayer : SaveUtil.SaveType.Singleplayer);
|
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))
|
saveList = new GUIListBox(new RectTransform(new Vector2(0.5f, 1.0f), loadGameContainer.RectTransform, Anchor.CenterLeft))
|
||||||
{
|
{
|
||||||
OnSelected = SelectSaveFile
|
OnSelected = SelectSaveFile
|
||||||
@@ -274,7 +269,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
foreach (string saveFile in saveFiles)
|
foreach (string saveFile in saveFiles)
|
||||||
{
|
{
|
||||||
XDocument doc = SaveUtil.LoadGameSessionDoc(saveFile);
|
string fileName = saveFile;
|
||||||
|
string subName = "";
|
||||||
|
string saveTime = "";
|
||||||
var saveFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.1f), saveList.Content.RectTransform), style: "ListBoxElement")
|
var saveFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.1f), saveList.Content.RectTransform), style: "ListBoxElement")
|
||||||
{
|
{
|
||||||
UserData = saveFile
|
UserData = saveFile
|
||||||
@@ -282,25 +279,38 @@ namespace Barotrauma
|
|||||||
|
|
||||||
var nameText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform),
|
var nameText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform),
|
||||||
text: Path.GetFileNameWithoutExtension(saveFile));
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
string submarineName = doc.Root.GetAttributeString("submarine", "");
|
if (!isMultiplayer)
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform, Anchor.BottomLeft),
|
|
||||||
text: submarineName, font: GUI.SmallFont)
|
|
||||||
{
|
{
|
||||||
UserData = saveFile
|
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]; }
|
||||||
|
}
|
||||||
|
|
||||||
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform, Anchor.BottomLeft),
|
||||||
|
text: subName, font: GUI.SmallFont)
|
||||||
|
{
|
||||||
|
UserData = fileName
|
||||||
};
|
};
|
||||||
|
|
||||||
string saveTime = doc.Root.GetAttributeString("savetime", "");
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), saveFrame.RectTransform),
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), saveFrame.RectTransform),
|
||||||
text: saveTime, textAlignment: Alignment.Right, font: GUI.SmallFont)
|
text: saveTime, textAlignment: Alignment.Right, font: GUI.SmallFont)
|
||||||
{
|
{
|
||||||
UserData = saveFile
|
UserData = fileName
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,13 +355,6 @@ 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()
|
public void UpdateTutorialSelection()
|
||||||
{
|
{
|
||||||
if (isMultiplayer) return;
|
if (isMultiplayer) return;
|
||||||
|
|||||||
@@ -457,11 +457,14 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
IgnoreLayoutGroups = true,
|
IgnoreLayoutGroups = true,
|
||||||
OnClicked = (GUIButton btn, object obj) => { StartRound?.Invoke(); return 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);
|
OnLocationSelected?.Invoke(location, connection);
|
||||||
|
|||||||
@@ -118,6 +118,19 @@ namespace Barotrauma
|
|||||||
instance = this;
|
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()
|
public override void Deselect()
|
||||||
{
|
{
|
||||||
base.Deselect();
|
base.Deselect();
|
||||||
@@ -128,15 +141,7 @@ namespace Barotrauma
|
|||||||
isEndlessRunner = false;
|
isEndlessRunner = false;
|
||||||
if (character != null)
|
if (character != null)
|
||||||
{
|
{
|
||||||
AnimParams.ForEach(a => a.Reset(true));
|
Reset();
|
||||||
RagdollParams.Reset(true);
|
|
||||||
RagdollParams.ClearHistory();
|
|
||||||
CurrentAnimation.ClearHistory();
|
|
||||||
if (!character.Removed)
|
|
||||||
{
|
|
||||||
character.Remove();
|
|
||||||
}
|
|
||||||
character = null;
|
|
||||||
}
|
}
|
||||||
GameMain.World.ProcessChanges();
|
GameMain.World.ProcessChanges();
|
||||||
}
|
}
|
||||||
@@ -393,6 +398,12 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
if (!isFreezed)
|
if (!isFreezed)
|
||||||
{
|
{
|
||||||
|
if (character.AnimController.Invalid)
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
SpawnCharacter(currentCharacterConfig);
|
||||||
|
}
|
||||||
|
|
||||||
Submarine.MainSub.SetPrevTransform(Submarine.MainSub.Position);
|
Submarine.MainSub.SetPrevTransform(Submarine.MainSub.Position);
|
||||||
Submarine.MainSub.Update((float)deltaTime);
|
Submarine.MainSub.Update((float)deltaTime);
|
||||||
|
|
||||||
@@ -1215,7 +1226,7 @@ namespace Barotrauma
|
|||||||
Cam.Position = character.WorldPosition;
|
Cam.Position = character.WorldPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CreateCharacter(string name, bool isHumanoid, params object[] ragdollConfig)
|
private bool CreateCharacter(string name, string mainFolder, bool isHumanoid, params object[] ragdollConfig)
|
||||||
{
|
{
|
||||||
var contentPackage = GameMain.Config.SelectedContentPackages.LastOrDefault();
|
var contentPackage = GameMain.Config.SelectedContentPackages.LastOrDefault();
|
||||||
if (contentPackage == null)
|
if (contentPackage == null)
|
||||||
@@ -1228,23 +1239,22 @@ namespace Barotrauma
|
|||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (vanilla != null && contentPackage == vanilla)
|
if (vanilla != null && contentPackage == vanilla)
|
||||||
{
|
{
|
||||||
GUI.AddMessage($"Cannot edit the Vanilla content!", Color.Red, font: GUI.LargeFont);
|
GUI.AddMessage(GetCharacterEditorTranslation("CannotEditVanillaCharacters"), Color.Red, font: GUI.LargeFont);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
string speciesName = name;
|
string speciesName = name;
|
||||||
string mainFolder = $"Content/Characters/{speciesName}";
|
|
||||||
// Config file
|
// Config file
|
||||||
string configFilePath = $"{mainFolder}/{speciesName}.xml";
|
string configFilePath = Path.Combine(mainFolder, $"{speciesName}.xml").Replace(@"\", @"/");
|
||||||
if (ContentPackage.GetFilesOfType(GameMain.SelectedPackages, ContentType.Character).None(path => path.Contains(speciesName)))
|
if (ContentPackage.GetFilesOfType(GameMain.SelectedPackages, ContentType.Character).None(path => path.Contains(speciesName)))
|
||||||
{
|
{
|
||||||
// Create the config file
|
// Create the config file
|
||||||
XElement mainElement = new XElement("Character",
|
XElement mainElement = new XElement("Character",
|
||||||
new XAttribute("name", speciesName),
|
new XAttribute("name", speciesName),
|
||||||
new XAttribute("humanoid", isHumanoid),
|
new XAttribute("humanoid", isHumanoid),
|
||||||
new XElement("ragdolls"),
|
new XElement("ragdolls", new XAttribute("folder", Path.Combine(mainFolder, $"Ragdolls/").Replace(@"\", @"/"))),
|
||||||
new XElement("animations"),
|
new XElement("animations", new XAttribute("folder", Path.Combine(mainFolder, $"Animations/").Replace(@"\", @"/"))),
|
||||||
new XElement("health"),
|
new XElement("health"),
|
||||||
new XElement("ai"));
|
new XElement("ai"));
|
||||||
XDocument doc = new XDocument(mainElement);
|
XDocument doc = new XDocument(mainElement);
|
||||||
@@ -1259,13 +1269,13 @@ namespace Barotrauma
|
|||||||
DebugConsole.NewMessage(GetCharacterEditorTranslation("ContentPackageSaved").Replace("[path]", contentPackage.Path));
|
DebugConsole.NewMessage(GetCharacterEditorTranslation("ContentPackageSaved").Replace("[path]", contentPackage.Path));
|
||||||
}
|
}
|
||||||
// Ragdoll
|
// Ragdoll
|
||||||
string ragdollFolder = RagdollParams.GetDefaultFolder(speciesName);
|
string ragdollFolder = RagdollParams.GetFolder(speciesName);
|
||||||
string ragdollPath = RagdollParams.GetDefaultFile(speciesName);
|
string ragdollPath = RagdollParams.GetDefaultFile(speciesName);
|
||||||
RagdollParams ragdollParams = isHumanoid
|
RagdollParams ragdollParams = isHumanoid
|
||||||
? RagdollParams.CreateDefault<HumanRagdollParams>(ragdollPath, speciesName, ragdollConfig)
|
? RagdollParams.CreateDefault<HumanRagdollParams>(ragdollPath, speciesName, ragdollConfig)
|
||||||
: RagdollParams.CreateDefault<FishRagdollParams>(ragdollPath, speciesName, ragdollConfig) as RagdollParams;
|
: RagdollParams.CreateDefault<FishRagdollParams>(ragdollPath, speciesName, ragdollConfig) as RagdollParams;
|
||||||
// Animations
|
// Animations
|
||||||
string animFolder = AnimationParams.GetDefaultFolder(speciesName);
|
string animFolder = AnimationParams.GetFolder(speciesName);
|
||||||
foreach (AnimationType animType in Enum.GetValues(typeof(AnimationType)))
|
foreach (AnimationType animType in Enum.GetValues(typeof(AnimationType)))
|
||||||
{
|
{
|
||||||
if (animType != AnimationType.NotDefined)
|
if (animType != AnimationType.NotDefined)
|
||||||
@@ -1869,7 +1879,7 @@ namespace Barotrauma
|
|||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (VanillaCharacters != null && VanillaCharacters.Contains(currentCharacterConfig))
|
if (VanillaCharacters != null && VanillaCharacters.Contains(currentCharacterConfig))
|
||||||
{
|
{
|
||||||
GUI.AddMessage(GetCharacterEditorTranslation("CantEditVanillaContent"), Color.Red, font: GUI.LargeFont);
|
GUI.AddMessage(GetCharacterEditorTranslation("CannotEditVanillaCharacters"), Color.Red, font: GUI.LargeFont);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1884,7 +1894,7 @@ namespace Barotrauma
|
|||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (VanillaCharacters != null && VanillaCharacters.Contains(currentCharacterConfig))
|
if (VanillaCharacters != null && VanillaCharacters.Contains(currentCharacterConfig))
|
||||||
{
|
{
|
||||||
GUI.AddMessage(GetCharacterEditorTranslation("CantEditVanillaContent"), Color.Red, font: GUI.LargeFont);
|
GUI.AddMessage(GetCharacterEditorTranslation("CannotEditVanillaCharacters"), Color.Red, font: GUI.LargeFont);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1956,7 +1966,7 @@ namespace Barotrauma
|
|||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (VanillaCharacters != null && VanillaCharacters.Contains(currentCharacterConfig))
|
if (VanillaCharacters != null && VanillaCharacters.Contains(currentCharacterConfig))
|
||||||
{
|
{
|
||||||
GUI.AddMessage(GetCharacterEditorTranslation("CantEditVanillaContent"), Color.Red, font: GUI.LargeFont);
|
GUI.AddMessage(GetCharacterEditorTranslation("CannotEditVanillaCharacters"), Color.Red, font: GUI.LargeFont);
|
||||||
box.Close();
|
box.Close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2089,7 +2099,7 @@ namespace Barotrauma
|
|||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (VanillaCharacters != null && VanillaCharacters.Contains(currentCharacterConfig))
|
if (VanillaCharacters != null && VanillaCharacters.Contains(currentCharacterConfig))
|
||||||
{
|
{
|
||||||
GUI.AddMessage(GetCharacterEditorTranslation("CantEditVanillaContent"), Color.Red, font: GUI.LargeFont);
|
GUI.AddMessage(GetCharacterEditorTranslation("CannotEditVanillaCharacters"), Color.Red, font: GUI.LargeFont);
|
||||||
box.Close();
|
box.Close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -3918,7 +3928,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void DrawJointLimitWidgets(SpriteBatch spriteBatch, Limb limb, LimbJoint joint, Vector2 drawPos, bool autoFreeze, bool allowPairEditing, float rotationOffset = 0)
|
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;
|
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 =>
|
DrawRadialWidget(spriteBatch, drawPos, MathHelper.ToDegrees(joint.UpperLimit), $"joint.jointParams.Name {GetCharacterEditorTranslation("UpperLimit")}", Color.Cyan, angle =>
|
||||||
{
|
{
|
||||||
@@ -4652,7 +4662,7 @@ namespace Barotrauma
|
|||||||
LimbXElements.Values,
|
LimbXElements.Values,
|
||||||
JointXElements
|
JointXElements
|
||||||
};
|
};
|
||||||
if (CharacterEditorScreen.instance.CreateCharacter(Name, IsHumanoid, ragdollParams))
|
if (CharacterEditorScreen.instance.CreateCharacter(Name, Path.GetDirectoryName(XMLPath), IsHumanoid, ragdollParams))
|
||||||
{
|
{
|
||||||
GUI.AddMessage(GetCharacterEditorTranslation("CharacterCreated").Replace("[name]", Name), Color.Green, font: GUI.Font);
|
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) },
|
new GUIImage(new RectTransform(new Vector2(0.35f, 0.2f), Frame.RectTransform, Anchor.BottomRight) { RelativeOffset = new Vector2(0.05f, 0.05f) },
|
||||||
style: "TitleText");
|
style: "TitleText");
|
||||||
|
|
||||||
buttonsParent = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 0.85f), parent: Frame.RectTransform, anchor: Anchor.BottomLeft, pivot: Pivot.BottomLeft)
|
buttonsParent = new GUILayoutGroup(new RectTransform(new Vector2(0.3f, 0.85f), parent: Frame.RectTransform, anchor: Anchor.BottomLeft, pivot: Pivot.BottomLeft)
|
||||||
{
|
{
|
||||||
AbsoluteOffset = new Point(50, 0)
|
AbsoluteOffset = new Point(50, 0)
|
||||||
})
|
})
|
||||||
@@ -61,7 +61,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
// === CAMPAIGN
|
// === CAMPAIGN
|
||||||
var campaignHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), parent: buttonsParent.RectTransform) { RelativeOffset = new Vector2(0.1f, 0.0f) }, isHorizontal: true);
|
var campaignHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 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")
|
new GUIImage(new RectTransform(new Vector2(0.2f, 0.7f), campaignHolder.RectTransform), "MainMenuCampaignIcon")
|
||||||
{
|
{
|
||||||
@@ -107,7 +107,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
// === MULTIPLAYER
|
// === MULTIPLAYER
|
||||||
var multiplayerHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), parent: buttonsParent.RectTransform) { RelativeOffset = new Vector2(0.05f, 0.0f) }, isHorizontal: true);
|
var multiplayerHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 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")
|
new GUIImage(new RectTransform(new Vector2(0.2f, 0.7f), multiplayerHolder.RectTransform), "MainMenuMultiplayerIcon")
|
||||||
{
|
{
|
||||||
@@ -152,7 +152,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
// === CUSTOMIZE
|
// === CUSTOMIZE
|
||||||
var customizeHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), parent: buttonsParent.RectTransform) { RelativeOffset = new Vector2(0.15f, 0.0f) }, isHorizontal: true);
|
var customizeHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 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")
|
new GUIImage(new RectTransform(new Vector2(0.2f, 0.7f), customizeHolder.RectTransform), "MainMenuCustomizeIcon")
|
||||||
{
|
{
|
||||||
@@ -209,7 +209,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
// === OPTION
|
// === OPTION
|
||||||
var optionHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 0.5f), parent: buttonsParent.RectTransform), isHorizontal: true);
|
var optionHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.5f), parent: buttonsParent.RectTransform), isHorizontal: true);
|
||||||
|
|
||||||
new GUIImage(new RectTransform(new Vector2(0.15f, 0.6f), optionHolder.RectTransform), "MainMenuOptionIcon")
|
new GUIImage(new RectTransform(new Vector2(0.15f, 0.6f), optionHolder.RectTransform), "MainMenuOptionIcon")
|
||||||
{
|
{
|
||||||
@@ -219,7 +219,7 @@ namespace Barotrauma
|
|||||||
//spacing
|
//spacing
|
||||||
new GUIFrame(new RectTransform(new Vector2(0.01f, 0.0f), optionHolder.RectTransform), style: null);
|
new GUIFrame(new RectTransform(new Vector2(0.01f, 0.0f), optionHolder.RectTransform), style: null);
|
||||||
|
|
||||||
var optionButtons = new GUILayoutGroup(new RectTransform(new Vector2(0.55f, 1.0f), parent: optionHolder.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.15f) });
|
var optionButtons = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 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))
|
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
|
//debug button for quickly starting a new round
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
new GUIButton(new RectTransform(new Vector2(0.5f, 0.1f), buttonsParent.RectTransform, Anchor.TopLeft, Pivot.BottomLeft) { AbsoluteOffset = new Point(0, -40) },
|
new GUIButton(new RectTransform(new Vector2(0.8f, 0.1f), buttonsParent.RectTransform, Anchor.TopLeft, Pivot.BottomLeft) { AbsoluteOffset = new Point(0, -40) },
|
||||||
"Quickstart (dev)", style: "GUIButtonLarge", color: Color.Red)
|
"Quickstart (dev)", style: "GUIButtonLarge", color: Color.Red)
|
||||||
{
|
{
|
||||||
IgnoreLayoutGroups = true,
|
IgnoreLayoutGroups = true,
|
||||||
@@ -255,7 +255,7 @@ namespace Barotrauma
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
var minButtonSize = new Point(120, 20);
|
var minButtonSize = new Point(120, 20);
|
||||||
var maxButtonSize = new Point(240, 40);
|
var maxButtonSize = new Point(480, 80);
|
||||||
|
|
||||||
/*new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("TutorialButton"), style: "GUIButtonLarge")
|
/*new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("TutorialButton"), style: "GUIButtonLarge")
|
||||||
{
|
{
|
||||||
@@ -270,16 +270,21 @@ namespace Barotrauma
|
|||||||
SetupButtons(buttons);
|
SetupButtons(buttons);
|
||||||
buttons.ForEach(b => b.TextBlock.SetTextPos());*/
|
buttons.ForEach(b => b.TextBlock.SetTextPos());*/
|
||||||
|
|
||||||
var relativeSize = new Vector2(0.5f, 0.5f);
|
var relativeSize = new Vector2(0.6f, 0.5f);
|
||||||
var minSize = new Point(600, 400);
|
var minSize = new Point(600, 400);
|
||||||
var maxSize = new Point(900, 600);
|
var maxSize = new Point(2000, 1500);
|
||||||
var anchor = Anchor.Center;
|
var anchor = Anchor.CenterRight;
|
||||||
var pivot = Pivot.Center;
|
var pivot = Pivot.CenterRight;
|
||||||
menuTabs = new GUIFrame[Enum.GetValues(typeof(Tab)).Length + 1];
|
Vector2 relativeSpacing = new Vector2(0.05f, 0.0f);
|
||||||
|
|
||||||
menuTabs[(int)Tab.NewGame] = new GUIFrame(new RectTransform(relativeSize, GUI.Canvas, anchor, pivot, minSize, maxSize));
|
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 });
|
||||||
var paddedNewGame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), menuTabs[(int)Tab.NewGame].RectTransform, Anchor.Center), style: null);
|
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));
|
menuTabs[(int)Tab.LoadGame] = new GUIFrame(new RectTransform(relativeSize, GUI.Canvas, anchor, pivot, minSize, maxSize) { RelativeOffset = relativeSpacing });
|
||||||
var paddedLoadGame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), menuTabs[(int)Tab.LoadGame].RectTransform, Anchor.Center), style: null);
|
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)
|
campaignSetupUI = new CampaignSetupUI(false, paddedNewGame, paddedLoadGame, Submarine.SavedSubmarines)
|
||||||
@@ -290,13 +295,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
var hostServerScale = new Vector2(0.7f, 1.0f);
|
var hostServerScale = new Vector2(0.7f, 1.0f);
|
||||||
menuTabs[(int)Tab.HostServer] = new GUIFrame(new RectTransform(
|
menuTabs[(int)Tab.HostServer] = new GUIFrame(new RectTransform(
|
||||||
Vector2.Multiply(relativeSize, hostServerScale), GUI.Canvas, anchor, pivot, minSize.Multiply(hostServerScale), maxSize.Multiply(hostServerScale)));
|
Vector2.Multiply(relativeSize, hostServerScale), GUI.Canvas, anchor, pivot, minSize.Multiply(hostServerScale), maxSize.Multiply(hostServerScale)) { RelativeOffset = relativeSpacing });
|
||||||
|
|
||||||
CreateHostServerFields();
|
CreateHostServerFields();
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
menuTabs[(int)Tab.Tutorials] = new GUIFrame(new RectTransform(relativeSize, GUI.Canvas, anchor, pivot, minSize, maxSize));
|
menuTabs[(int)Tab.Tutorials] = new GUIFrame(new RectTransform(relativeSize, GUI.Canvas, anchor, pivot, minSize, maxSize) { RelativeOffset = relativeSpacing });
|
||||||
|
|
||||||
//PLACEHOLDER
|
//PLACEHOLDER
|
||||||
var tutorialList = new GUIListBox(
|
var tutorialList = new GUIListBox(
|
||||||
@@ -377,6 +382,7 @@ namespace Barotrauma
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GameMain.Config.ResetSettingsFrame();
|
||||||
selectedTab = (Tab)obj;
|
selectedTab = (Tab)obj;
|
||||||
|
|
||||||
switch (selectedTab)
|
switch (selectedTab)
|
||||||
@@ -389,8 +395,9 @@ namespace Barotrauma
|
|||||||
campaignSetupUI.UpdateLoadMenu();
|
campaignSetupUI.UpdateLoadMenu();
|
||||||
break;
|
break;
|
||||||
case Tab.Settings:
|
case Tab.Settings:
|
||||||
GameMain.Config.ResetSettingsFrame();
|
menuTabs[(int)Tab.Settings].RectTransform.ClearChildren();
|
||||||
menuTabs[(int)Tab.Settings] = GameMain.Config.SettingsFrame;
|
GameMain.Config.SettingsFrame.RectTransform.Parent = menuTabs[(int)Tab.Settings].RectTransform;
|
||||||
|
GameMain.Config.SettingsFrame.RectTransform.RelativeSize = Vector2.One;
|
||||||
break;
|
break;
|
||||||
case Tab.JoinServer:
|
case Tab.JoinServer:
|
||||||
GameMain.ServerListScreen.Select();
|
GameMain.ServerListScreen.Select();
|
||||||
|
|||||||
@@ -233,7 +233,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
levelSeed = value;
|
levelSeed = value;
|
||||||
|
|
||||||
backgroundSprite = LocationType.Random(levelSeed)?.GetPortrait(ToolBox.StringToInt(levelSeed));
|
int intSeed = ToolBox.StringToInt(levelSeed);
|
||||||
|
backgroundSprite = LocationType.Random(new MTRandom(intSeed))?.GetPortrait(intSeed);
|
||||||
seedBox.Text = levelSeed;
|
seedBox.Text = levelSeed;
|
||||||
|
|
||||||
//lastUpdateID++;
|
//lastUpdateID++;
|
||||||
@@ -726,6 +727,12 @@ namespace Barotrauma
|
|||||||
spectateButton.Visible = GameMain.Client.GameStarted;
|
spectateButton.Visible = GameMain.Client.GameStarted;
|
||||||
ReadyToStartBox.Visible = !GameMain.Client.GameStarted;
|
ReadyToStartBox.Visible = !GameMain.Client.GameStarted;
|
||||||
ReadyToStartBox.Selected = false;
|
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);
|
GameMain.Client.SetReadyToStart(ReadyToStartBox);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -847,9 +854,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (campaignUI?.StartButton != null)
|
if (campaignUI?.StartButton != null)
|
||||||
{
|
{
|
||||||
campaignUI.StartButton.Visible =
|
campaignUI.StartButton.Visible = !GameMain.Client.GameStarted &&
|
||||||
GameMain.Client.HasPermission(ClientPermissions.ManageRound) ||
|
(GameMain.Client.HasPermission(ClientPermissions.ManageRound) ||
|
||||||
GameMain.Client.HasPermission(ClientPermissions.ManageCampaign);
|
GameMain.Client.HasPermission(ClientPermissions.ManageCampaign));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -860,18 +867,21 @@ namespace Barotrauma
|
|||||||
spectateButton.Enabled = true;
|
spectateButton.Enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetCampaignCharacterInfo(CharacterInfo characterInfo)
|
public void SetCampaignCharacterInfo(CharacterInfo newCampaignCharacterInfo)
|
||||||
{
|
{
|
||||||
if (CampaignCharacterDiscarded) return;
|
if (newCampaignCharacterInfo != null)
|
||||||
|
|
||||||
campaignCharacterInfo = characterInfo;
|
|
||||||
if (campaignCharacterInfo != null)
|
|
||||||
{
|
{
|
||||||
UpdatePlayerFrame(campaignCharacterInfo, false);
|
if (CampaignCharacterDiscarded) { return; }
|
||||||
|
if (campaignCharacterInfo != newCampaignCharacterInfo)
|
||||||
|
{
|
||||||
|
campaignCharacterInfo = newCampaignCharacterInfo;
|
||||||
|
UpdatePlayerFrame(campaignCharacterInfo, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (campaignCharacterInfo != null)
|
||||||
{
|
{
|
||||||
UpdatePlayerFrame(null, true);
|
campaignCharacterInfo = null;
|
||||||
|
UpdatePlayerFrame(campaignCharacterInfo, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -337,7 +337,24 @@ namespace Barotrauma
|
|||||||
var tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowLighting"))
|
var tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowLighting"))
|
||||||
{
|
{
|
||||||
Selected = lightingEnabled,
|
Selected = lightingEnabled,
|
||||||
OnSelected = (GUITickBox obj) => { lightingEnabled = obj.Selected; return true; }
|
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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowWalls"))
|
tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowWalls"))
|
||||||
{
|
{
|
||||||
@@ -564,6 +581,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
MapEntityPrefab.Selected = null;
|
MapEntityPrefab.Selected = null;
|
||||||
|
|
||||||
|
saveFrame = null;
|
||||||
|
loadFrame = null;
|
||||||
|
|
||||||
MapEntity.DeselectAll();
|
MapEntity.DeselectAll();
|
||||||
MapEntity.SelectionGroups.Clear();
|
MapEntity.SelectionGroups.Clear();
|
||||||
|
|
||||||
@@ -766,6 +786,20 @@ namespace Barotrauma
|
|||||||
savePath = Path.Combine(Submarine.SavePath, savePath);
|
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)
|
/*foreach (var contentPackage in GameMain.Config.SelectedContentPackages)
|
||||||
{
|
{
|
||||||
Submarine.MainSub.RequiredContentPackages.Add(contentPackage.Name);
|
Submarine.MainSub.RequiredContentPackages.Add(contentPackage.Name);
|
||||||
@@ -2040,6 +2074,10 @@ namespace Barotrauma
|
|||||||
dummyCharacter.SelectedConstruction = null;
|
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);
|
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
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("0.8.9.6")]
|
[assembly: AssemblyVersion("0.8.9.8")]
|
||||||
[assembly: AssemblyFileVersion("0.8.9.6")]
|
[assembly: AssemblyFileVersion("0.8.9.8")]
|
||||||
|
|||||||
@@ -20,8 +20,10 @@ namespace Barotrauma
|
|||||||
if (Job != null)
|
if (Job != null)
|
||||||
{
|
{
|
||||||
msg.Write(Job.Prefab.Identifier);
|
msg.Write(Job.Prefab.Identifier);
|
||||||
|
msg.Write((byte)Job.Skills.Count);
|
||||||
foreach (Skill skill in Job.Skills)
|
foreach (Skill skill in Job.Skills)
|
||||||
{
|
{
|
||||||
|
msg.Write(skill.Identifier);
|
||||||
msg.Write(skill.Level);
|
msg.Write(skill.Level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private bool networkUpdateSent;
|
private bool networkUpdateSent;
|
||||||
|
|
||||||
|
private double LastInputTime;
|
||||||
|
|
||||||
public float GetPositionUpdateInterval(Client recipient)
|
public float GetPositionUpdateInterval(Client recipient)
|
||||||
{
|
{
|
||||||
if (!Enabled) { return 1000.0f; }
|
if (!Enabled) { return 1000.0f; }
|
||||||
@@ -61,6 +63,15 @@ namespace Barotrauma
|
|||||||
else if (memInput.Count == 0)
|
else if (memInput.Count == 0)
|
||||||
{
|
{
|
||||||
AnimController.Frozen = true;
|
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
|
else
|
||||||
{
|
{
|
||||||
@@ -190,6 +201,7 @@ namespace Barotrauma
|
|||||||
networkUpdateID = (ushort)(networkUpdateID - i)
|
networkUpdateID = (ushort)(networkUpdateID - i)
|
||||||
};
|
};
|
||||||
memInput.Insert(i, newMem);
|
memInput.Insert(i, newMem);
|
||||||
|
LastInputTime = Timing.TotalTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
private List<CharacterCampaignData> characterData = new List<CharacterCampaignData>();
|
private List<CharacterCampaignData> characterData = new List<CharacterCampaignData>();
|
||||||
|
|
||||||
public static void StartNewCampaign(string savePath, string subName, string seed)
|
public static void StartNewCampaign(string savePath, string subPath, string seed)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(savePath)) return;
|
if (string.IsNullOrWhiteSpace(savePath)) return;
|
||||||
|
|
||||||
GameMain.GameSession = new GameSession(new Submarine(subName, ""), savePath,
|
GameMain.GameSession = new GameSession(new Submarine(subPath, ""), savePath,
|
||||||
GameModePreset.List.Find(g => g.Identifier == "multiplayercampaign"));
|
GameModePreset.List.Find(g => g.Identifier == "multiplayercampaign"));
|
||||||
var campaign = ((MultiPlayerCampaign)GameMain.GameSession.GameMode);
|
var campaign = ((MultiPlayerCampaign)GameMain.GameSession.GameMode);
|
||||||
campaign.GenerateMap(seed);
|
campaign.GenerateMap(seed);
|
||||||
@@ -251,6 +251,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
lastSaveID++;
|
lastSaveID++;
|
||||||
|
DebugConsole.Log("Campaign saved, save ID " + lastSaveID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
using Barotrauma.Networking;
|
using Barotrauma.Networking;
|
||||||
using System;
|
using Lidgren.Network;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Barotrauma.Items.Components
|
namespace Barotrauma.Items.Components
|
||||||
{
|
{
|
||||||
@@ -14,5 +10,16 @@ namespace Barotrauma.Items.Components
|
|||||||
//let the clients know the initial deterioration delay
|
//let the clients know the initial deterioration delay
|
||||||
item.CreateServerEvent(this);
|
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,6 +20,16 @@ namespace Barotrauma
|
|||||||
partial void UpdateProjSpecific(float deltaTime, Camera cam)
|
partial void UpdateProjSpecific(float deltaTime, Camera cam)
|
||||||
{
|
{
|
||||||
if (IdFreed) { return; }
|
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%
|
//update client hulls if the amount of water has changed by >10%
|
||||||
//or if oxygen percentage has changed by 5%
|
//or if oxygen percentage has changed by 5%
|
||||||
if (Math.Abs(lastSentVolume - waterVolume) > Volume * 0.1f ||
|
if (Math.Abs(lastSentVolume - waterVolume) > Volume * 0.1f ||
|
||||||
@@ -31,8 +41,8 @@ namespace Barotrauma
|
|||||||
GameMain.NetworkMember.CreateEntityEvent(this);
|
GameMain.NetworkMember.CreateEntityEvent(this);
|
||||||
lastSentVolume = waterVolume;
|
lastSentVolume = waterVolume;
|
||||||
lastSentOxygen = OxygenPercentage;
|
lastSentOxygen = OxygenPercentage;
|
||||||
sendUpdateTimer = NetworkUpdateInterval;
|
sendUpdateTimer = NetConfig.HullUpdateInterval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
//when was a specific entity event last sent to the client
|
//when was a specific entity event last sent to the client
|
||||||
// key = event id, value = NetTime.Now when sending
|
// key = event id, value = NetTime.Now when sending
|
||||||
public readonly Dictionary<UInt16, float> EntityEventLastSent = new Dictionary<UInt16, float>();
|
public readonly Dictionary<UInt16, double> EntityEventLastSent = new Dictionary<UInt16, double>();
|
||||||
|
|
||||||
//when was a position update for a given entity last sent to the client
|
//when was a position update for a given entity last sent to the client
|
||||||
// key = entity id, value = NetTime.Now when sending
|
// key = entity id, value = NetTime.Now when sending
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ namespace Barotrauma.Networking
|
|||||||
transfer.WaitTimer -= deltaTime;
|
transfer.WaitTimer -= deltaTime;
|
||||||
if (transfer.WaitTimer > 0.0f) continue;
|
if (transfer.WaitTimer > 0.0f) continue;
|
||||||
|
|
||||||
if (!transfer.Connection.CanSendImmediately(NetDeliveryMethod.ReliableOrdered, 1)) continue;
|
if (!transfer.Connection.CanSendImmediately(NetDeliveryMethod.ReliableOrdered, transfer.SequenceChannel)) continue;
|
||||||
|
|
||||||
transfer.WaitTimer = 0.05f;// transfer.Connection.AverageRoundtripTime;
|
transfer.WaitTimer = 0.05f;// transfer.Connection.AverageRoundtripTime;
|
||||||
|
|
||||||
@@ -202,15 +202,6 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
message = peer.CreateMessage();
|
message = peer.CreateMessage();
|
||||||
message.Write((byte)ServerPacketHeader.FILE_TRANSFER);
|
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)
|
//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
|
//we don't need to send anything, the client can just read the file directly
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using System.Text;
|
|||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Barotrauma.Steam;
|
using Barotrauma.Steam;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace Barotrauma.Networking
|
namespace Barotrauma.Networking
|
||||||
{
|
{
|
||||||
@@ -715,23 +716,25 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
string savePath = inc.ReadString();
|
string savePath = inc.ReadString();
|
||||||
string seed = inc.ReadString();
|
string seed = inc.ReadString();
|
||||||
string subPath = inc.ReadString();
|
string subName = inc.ReadString();
|
||||||
|
string subHash = inc.ReadString();
|
||||||
|
|
||||||
if (!File.Exists(subPath))
|
var matchingSub = Submarine.SavedSubmarines.FirstOrDefault(s => s.Name == subName && s.MD5Hash.Hash == subHash);
|
||||||
|
|
||||||
|
if (matchingSub == null)
|
||||||
{
|
{
|
||||||
SendDirectChatMessage(
|
SendDirectChatMessage(
|
||||||
TextManager.Get("CampaignStartFailedSubNotFound").Replace("[subpath]", subPath),
|
TextManager.Get("CampaignStartFailedSubNotFound").Replace("[subname]", subName),
|
||||||
connectedClient, ChatMessageType.MessageBox);
|
connectedClient, ChatMessageType.MessageBox);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (connectedClient.HasPermission(ClientPermissions.SelectMode)) MultiPlayerCampaign.StartNewCampaign(savePath, subPath, seed);
|
if (connectedClient.HasPermission(ClientPermissions.SelectMode)) MultiPlayerCampaign.StartNewCampaign(savePath, matchingSub.FilePath, seed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string saveName = inc.ReadString();
|
string saveName = inc.ReadString();
|
||||||
|
|
||||||
if (connectedClient.HasPermission(ClientPermissions.SelectMode)) MultiPlayerCampaign.LoadCampaign(saveName);
|
if (connectedClient.HasPermission(ClientPermissions.SelectMode)) MultiPlayerCampaign.LoadCampaign(saveName);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -811,7 +814,16 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
Log(c.Name + " has reported an error: " + errorStr, ServerLog.MessageType.Error);
|
Log(c.Name + " has reported an error: " + errorStr, ServerLog.MessageType.Error);
|
||||||
GameAnalyticsManager.AddErrorEventOnce("GameServer.HandleClientError:LevelsDontMatch" + error, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorStr);
|
GameAnalyticsManager.AddErrorEventOnce("GameServer.HandleClientError:LevelsDontMatch" + error, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorStr);
|
||||||
KickClient(c, errorStr);
|
|
||||||
|
if (c.Connection == OwnerConnection)
|
||||||
|
{
|
||||||
|
SendDirectChatMessage(errorStr, c, ChatMessageType.MessageBox);
|
||||||
|
EndGame();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KickClient(c, errorStr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void CreateEntityEvent(INetSerializable entity, object[] extraData = null)
|
public override void CreateEntityEvent(INetSerializable entity, object[] extraData = null)
|
||||||
@@ -1028,7 +1040,7 @@ namespace Barotrauma.Networking
|
|||||||
if (command == ClientPermissions.ManageRound && inc.PeekBoolean() &&
|
if (command == ClientPermissions.ManageRound && inc.PeekBoolean() &&
|
||||||
GameMain.GameSession?.GameMode is MultiPlayerCampaign mpCampaign)
|
GameMain.GameSession?.GameMode is MultiPlayerCampaign mpCampaign)
|
||||||
{
|
{
|
||||||
if (!mpCampaign.AllowedToEndRound(sender.Character))
|
if (!mpCampaign.AllowedToEndRound(sender.Character) && !sender.HasPermission(command))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1114,9 +1126,22 @@ namespace Barotrauma.Networking
|
|||||||
UInt16 modeIndex = inc.ReadUInt16();
|
UInt16 modeIndex = inc.ReadUInt16();
|
||||||
if (GameMain.NetLobbyScreen.GameModes[modeIndex].Identifier.ToLowerInvariant() == "multiplayercampaign")
|
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();
|
NetOutgoingMessage msg = server.CreateMessage();
|
||||||
msg.Write((byte)ServerPacketHeader.CAMPAIGN_SETUP_INFO);
|
msg.Write((byte)ServerPacketHeader.CAMPAIGN_SETUP_INFO);
|
||||||
string[] saveFiles = SaveUtil.GetSaveFiles(SaveUtil.SaveType.Multiplayer);
|
|
||||||
msg.Write((UInt16)saveFiles.Count());
|
msg.Write((UInt16)saveFiles.Count());
|
||||||
foreach (string saveFile in saveFiles)
|
foreach (string saveFile in saveFiles)
|
||||||
{
|
{
|
||||||
@@ -1201,6 +1226,7 @@ namespace Barotrauma.Networking
|
|||||||
ClientWriteLobby(c);
|
ClientWriteLobby(c);
|
||||||
|
|
||||||
if (GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign &&
|
if (GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign &&
|
||||||
|
GameMain.NetLobbyScreen.SelectedMode == campaign.Preset &&
|
||||||
NetIdUtils.IdMoreRecent(campaign.LastSaveID, c.LastRecvCampaignSave))
|
NetIdUtils.IdMoreRecent(campaign.LastSaveID, c.LastRecvCampaignSave))
|
||||||
{
|
{
|
||||||
//already sent an up-to-date campaign save
|
//already sent an up-to-date campaign save
|
||||||
@@ -1335,10 +1361,6 @@ namespace Barotrauma.Networking
|
|||||||
WriteClientList(c, outmsg);
|
WriteClientList(c, outmsg);
|
||||||
clientListBytes = outmsg.LengthBytes - clientListBytes;
|
clientListBytes = outmsg.LengthBytes - clientListBytes;
|
||||||
|
|
||||||
int eventManagerBytes = outmsg.LengthBytes;
|
|
||||||
entityEventManager.Write(c, outmsg, out List<NetEntityEvent> sentEvents);
|
|
||||||
eventManagerBytes = outmsg.LengthBytes - eventManagerBytes;
|
|
||||||
|
|
||||||
int chatMessageBytes = outmsg.LengthBytes;
|
int chatMessageBytes = outmsg.LengthBytes;
|
||||||
WriteChatMessages(outmsg, c);
|
WriteChatMessages(outmsg, c);
|
||||||
chatMessageBytes = outmsg.LengthBytes - chatMessageBytes;
|
chatMessageBytes = outmsg.LengthBytes - chatMessageBytes;
|
||||||
@@ -1348,7 +1370,8 @@ namespace Barotrauma.Networking
|
|||||||
while (!c.NeedsMidRoundSync && c.PendingPositionUpdates.Count > 0)
|
while (!c.NeedsMidRoundSync && c.PendingPositionUpdates.Count > 0)
|
||||||
{
|
{
|
||||||
var entity = c.PendingPositionUpdates.Peek();
|
var entity = c.PendingPositionUpdates.Peek();
|
||||||
if (entity == null || entity.Removed)
|
if (entity == null || entity.Removed ||
|
||||||
|
(entity is Item item && item.PositionUpdateInterval == float.PositiveInfinity))
|
||||||
{
|
{
|
||||||
c.PendingPositionUpdates.Dequeue();
|
c.PendingPositionUpdates.Dequeue();
|
||||||
continue;
|
continue;
|
||||||
@@ -1387,25 +1410,55 @@ namespace Barotrauma.Networking
|
|||||||
errorMsg +=
|
errorMsg +=
|
||||||
" Client list size: " + clientListBytes + " bytes\n" +
|
" Client list size: " + clientListBytes + " bytes\n" +
|
||||||
" Chat message size: " + chatMessageBytes + " bytes\n" +
|
" Chat message size: " + chatMessageBytes + " bytes\n" +
|
||||||
" Event size: " + eventManagerBytes + " bytes\n" +
|
|
||||||
" Position update size: " + positionUpdateBytes + " bytes\n\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);
|
DebugConsole.ThrowError(errorMsg);
|
||||||
GameAnalyticsManager.AddErrorEventOnce("GameServer.ClientWriteIngame:PacketSizeExceeded" + outmsg.LengthBytes, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
GameAnalyticsManager.AddErrorEventOnce("GameServer.ClientWriteIngame1:PacketSizeExceeded" + outmsg.LengthBytes, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
CompressOutgoingMessage(outmsg);
|
CompressOutgoingMessage(outmsg);
|
||||||
|
|
||||||
server.SendMessage(outmsg, c.Connection, NetDeliveryMethod.Unreliable);
|
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)
|
private void WriteClientList(Client c, NetOutgoingMessage outmsg)
|
||||||
@@ -1492,7 +1545,8 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
|
|
||||||
var campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;
|
var campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;
|
||||||
if (campaign != null && NetIdUtils.IdMoreRecent(campaign.LastUpdateID, c.LastRecvCampaignUpdate))
|
if (campaign != null && campaign.Preset == GameMain.NetLobbyScreen.SelectedMode &&
|
||||||
|
NetIdUtils.IdMoreRecent(campaign.LastUpdateID, c.LastRecvCampaignUpdate))
|
||||||
{
|
{
|
||||||
outmsg.Write(true);
|
outmsg.Write(true);
|
||||||
outmsg.WritePadBits();
|
outmsg.WritePadBits();
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ namespace Barotrauma.Networking
|
|||||||
if (connectedClient != null)
|
if (connectedClient != null)
|
||||||
{
|
{
|
||||||
Log("Disconnecting client " + connectedClient.Name + " (Steam ID: " + steamID + "). Steam authentication no longer valid (" + status + ").", ServerLog.MessageType.ServerMessage);
|
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())
|
if (clVersion != GameMain.Version.ToString())
|
||||||
{
|
{
|
||||||
DisconnectUnauthClient(inc, unauthClient, DisconnectReason.InvalidVersion,
|
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);
|
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);
|
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)
|
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);
|
Log(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (missing content package " + GetPackageStr(missingPackages[0]) + ")", ServerLog.MessageType.Error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -376,7 +376,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
List<string> packageStrs = new List<string>();
|
List<string> packageStrs = new List<string>();
|
||||||
missingPackages.ForEach(cp => packageStrs.Add(GetPackageStr(cp)));
|
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);
|
Log(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (missing content packages " + string.Join(", ", packageStrs) + ")", ServerLog.MessageType.Error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -399,7 +399,7 @@ namespace Barotrauma.Networking
|
|||||||
if (incompatiblePackages.Count == 1)
|
if (incompatiblePackages.Count == 1)
|
||||||
{
|
{
|
||||||
DisconnectUnauthClient(inc, unauthClient, DisconnectReason.IncompatibleContentPackage,
|
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);
|
Log(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (incompatible content package " + GetPackageStr2(incompatiblePackages[0]) + ")", ServerLog.MessageType.Error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -408,7 +408,7 @@ namespace Barotrauma.Networking
|
|||||||
List<string> packageStrs = new List<string>();
|
List<string> packageStrs = new List<string>();
|
||||||
incompatiblePackages.ForEach(cp => packageStrs.Add(GetPackageStr2(cp)));
|
incompatiblePackages.ForEach(cp => packageStrs.Add(GetPackageStr2(cp)));
|
||||||
DisconnectUnauthClient(inc, unauthClient, DisconnectReason.IncompatibleContentPackage,
|
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);
|
Log(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (incompatible content packages " + string.Join(", ", packageStrs) + ")", ServerLog.MessageType.Error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -494,13 +494,21 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newClient.SetPermissions(ClientPermissions.None, new List<DebugConsole.Command>());
|
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>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisconnectUnauthClient(NetIncomingMessage inc, UnauthenticatedClient unauthClient, DisconnectReason reason, string message)
|
private void DisconnectUnauthClient(NetIncomingMessage inc, UnauthenticatedClient unauthClient, DisconnectReason reason, string message)
|
||||||
{
|
{
|
||||||
inc.SenderConnection.Disconnect(reason.ToString() + "/ " + message);
|
inc.SenderConnection.Disconnect(reason.ToString() + "/ " + TextManager.GetServerMessage(message));
|
||||||
if (unauthClient.SteamID > 0) { Steam.SteamManager.StopAuthSession(unauthClient.SteamID); }
|
if (unauthClient.SteamID > 0) { Steam.SteamManager.StopAuthSession(unauthClient.SteamID); }
|
||||||
if (unauthClient != null)
|
if (unauthClient != null)
|
||||||
{
|
{
|
||||||
|
|||||||
+9
-21
@@ -228,7 +228,7 @@ namespace Barotrauma.Networking
|
|||||||
GameServer.Log("Disconnecting client " + c.Name + " due to excessive desync (expected old event "
|
GameServer.Log("Disconnecting client " + c.Name + " due to excessive desync (expected old event "
|
||||||
+ (c.LastRecvEntityEventID + 1).ToString() +
|
+ (c.LastRecvEntityEventID + 1).ToString() +
|
||||||
" (created " + (Timing.TotalTime - firstEventToResend.CreateTime).ToString("0.##") + " s ago)" +
|
" (created " + (Timing.TotalTime - firstEventToResend.CreateTime).ToString("0.##") + " s ago)" +
|
||||||
" Events queued: " + events.Count + ", last sent to all: " + lastSentToAll, ServerLog.MessageType.ServerMessage);
|
" Events queued: " + events.Count + ", last sent to all: " + lastSentToAll, ServerLog.MessageType.Error);
|
||||||
server.DisconnectClient(c, "", "ServerMessage.ExcessiveDesyncOldEvent");
|
server.DisconnectClient(c, "", "ServerMessage.ExcessiveDesyncOldEvent");
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -242,7 +242,7 @@ namespace Barotrauma.Networking
|
|||||||
toKick.ForEach(c =>
|
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);
|
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.ServerMessage);
|
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);
|
||||||
server.DisconnectClient(c, "", "ServerMessage.ExcessiveDesyncRemovedEvent");
|
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);
|
var timedOutClients = clients.FindAll(c => c.InGame && c.NeedsMidRoundSync && Timing.TotalTime > c.MidRoundSyncTimeOut);
|
||||||
foreach (Client timedOutClient in timedOutClients)
|
foreach (Client timedOutClient in timedOutClients)
|
||||||
{
|
{
|
||||||
GameServer.Log("Disconnecting client " + timedOutClient.Name + ". Syncing the client with the server took too long.", ServerLog.MessageType.ServerMessage);
|
GameServer.Log("Disconnecting client " + timedOutClient.Name + ". Syncing the client with the server took too long.", ServerLog.MessageType.Error);
|
||||||
GameMain.Server.DisconnectClient(timedOutClient, "", "ServerMessage.SyncTimeout");
|
GameMain.Server.DisconnectClient(timedOutClient, "", "ServerMessage.SyncTimeout");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,19 +305,7 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
|
|
||||||
//too many events for one packet
|
//too many events for one packet
|
||||||
if (eventsToSync.Count > MaxEventsPerWrite)
|
if (eventsToSync.Count > 200)
|
||||||
{
|
|
||||||
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)
|
if (eventsToSync.Count > 200 && !client.NeedsMidRoundSync)
|
||||||
{
|
{
|
||||||
@@ -350,7 +338,7 @@ namespace Barotrauma.Networking
|
|||||||
msg.Write(client.UnreceivedEntityEventCount);
|
msg.Write(client.UnreceivedEntityEventCount);
|
||||||
msg.Write(client.FirstNewEventID);
|
msg.Write(client.FirstNewEventID);
|
||||||
|
|
||||||
Write(msg, eventsToSync, client);
|
Write(msg, eventsToSync, out sentEvents, client);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -387,10 +375,10 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
for (int i = startIndex; i < eventList.Count; i++)
|
for (int i = startIndex; i < eventList.Count; i++)
|
||||||
{
|
{
|
||||||
//find the first event that hasn't been sent in 1.5 * roundtriptime or at all
|
//find the first event that hasn't been sent in roundtriptime or at all
|
||||||
client.EntityEventLastSent.TryGetValue(eventList[i].ID, out float lastSent);
|
client.EntityEventLastSent.TryGetValue(eventList[i].ID, out double lastSent);
|
||||||
|
|
||||||
float minInterval = Math.Max(client.Connection.AverageRoundtripTime * 1.5f, (float)server.UpdateInterval.TotalSeconds * 2);
|
float minInterval = Math.Max(client.Connection.AverageRoundtripTime, (float)server.UpdateInterval.TotalSeconds * 2);
|
||||||
|
|
||||||
if (lastSent > NetTime.Now - Math.Min(minInterval, 0.5f))
|
if (lastSent > NetTime.Now - Math.Min(minInterval, 0.5f))
|
||||||
{
|
{
|
||||||
@@ -416,7 +404,7 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
double midRoundSyncTimeOut = uniqueEvents.Count / MaxEventsPerWrite * server.UpdateInterval.TotalSeconds;
|
double midRoundSyncTimeOut = uniqueEvents.Count / 100 * server.UpdateInterval.TotalSeconds;
|
||||||
midRoundSyncTimeOut = Math.Max(10.0f, midRoundSyncTimeOut * 10.0f);
|
midRoundSyncTimeOut = Math.Max(10.0f, midRoundSyncTimeOut * 10.0f);
|
||||||
|
|
||||||
client.UnreceivedEntityEventCount = (UInt16)uniqueEvents.Count;
|
client.UnreceivedEntityEventCount = (UInt16)uniqueEvents.Count;
|
||||||
|
|||||||
@@ -337,37 +337,56 @@ namespace Barotrauma.Networking
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
string permissionsStr = clientElement.GetAttributeString("permissions", "");
|
|
||||||
ClientPermissions permissions = Networking.ClientPermissions.None;
|
ClientPermissions permissions = Networking.ClientPermissions.None;
|
||||||
if (permissionsStr.ToLowerInvariant() == "all")
|
List<DebugConsole.Command> permittedCommands = new List<DebugConsole.Command>();
|
||||||
|
|
||||||
|
if (clientElement.Attribute("preset") == null)
|
||||||
{
|
{
|
||||||
foreach (ClientPermissions permission in Enum.GetValues(typeof(ClientPermissions)))
|
string permissionsStr = clientElement.GetAttributeString("permissions", "");
|
||||||
|
if (permissionsStr.ToLowerInvariant() == "all")
|
||||||
{
|
{
|
||||||
permissions |= permission;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!Enum.TryParse(permissionsStr, out permissions))
|
else
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Error in " + ClientPermissionsFile + " - \"" + permissionsStr + "\" is not a valid client permission.");
|
string presetName = clientElement.GetAttributeString("preset", "");
|
||||||
continue;
|
PermissionPreset preset = PermissionPreset.List.Find(p => p.Name == presetName);
|
||||||
}
|
if (preset == null)
|
||||||
|
|
||||||
List<DebugConsole.Command> permittedCommands = new List<DebugConsole.Command>();
|
|
||||||
if (permissions.HasFlag(Networking.ClientPermissions.ConsoleCommands))
|
|
||||||
{
|
|
||||||
foreach (XElement commandElement in clientElement.Elements())
|
|
||||||
{
|
{
|
||||||
if (commandElement.Name.ToString().ToLowerInvariant() != "command") continue;
|
DebugConsole.ThrowError("Failed to restore saved permissions to the client \"" + clientName + "\". Permission preset \"" + presetName + "\" not found.");
|
||||||
|
return;
|
||||||
string commandName = commandElement.GetAttributeString("name", "");
|
}
|
||||||
DebugConsole.Command command = DebugConsole.FindCommand(commandName);
|
else
|
||||||
if (command == null)
|
{
|
||||||
{
|
permissions = preset.Permissions;
|
||||||
DebugConsole.ThrowError("Error in " + ClientPermissionsFile + " - \"" + commandName + "\" is not a valid console command.");
|
permittedCommands = preset.PermittedCommands.ToList();
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
permittedCommands.Add(command);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,9 +459,14 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
foreach (SavedClientPermission clientPermission in ClientPermissions)
|
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",
|
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)
|
if (clientPermission.SteamID > 0)
|
||||||
{
|
{
|
||||||
@@ -453,14 +477,21 @@ namespace Barotrauma.Networking
|
|||||||
clientElement.Add(new XAttribute("ip", clientPermission.IP));
|
clientElement.Add(new XAttribute("ip", clientPermission.IP));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clientPermission.Permissions.HasFlag(Barotrauma.Networking.ClientPermissions.ConsoleCommands))
|
if (matchingPreset == null)
|
||||||
{
|
{
|
||||||
foreach (DebugConsole.Command command in clientPermission.PermittedCommands)
|
clientElement.Add(new XAttribute("permissions", clientPermission.Permissions.ToString()));
|
||||||
|
if (clientPermission.Permissions.HasFlag(Networking.ClientPermissions.ConsoleCommands))
|
||||||
{
|
{
|
||||||
clientElement.Add(new XElement("command", new XAttribute("name", command.names[0])));
|
foreach (DebugConsole.Command command in clientPermission.PermittedCommands)
|
||||||
|
{
|
||||||
|
clientElement.Add(new XElement("command", new XAttribute("name", command.names[0])));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clientElement.Add(new XAttribute("preset", matchingPreset.Name));
|
||||||
|
}
|
||||||
doc.Root.Add(clientElement);
|
doc.Root.Add(clientElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,7 @@
|
|||||||
<Character file="Content/Characters/Husk/Husk.xml" />
|
<Character file="Content/Characters/Husk/Husk.xml" />
|
||||||
<Character file="Content/Characters/Humanhusk/Humanhusk.xml" />
|
<Character file="Content/Characters/Humanhusk/Humanhusk.xml" />
|
||||||
<Character file="Content/Characters/Legacyhusk/Legacyhusk.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/Legacycrawler/Legacycrawler.xml" />
|
||||||
<Character file="Content/Characters/Legacymoloch/Legacymoloch.xml" />
|
<Character file="Content/Characters/Legacymoloch/Legacymoloch.xml" />
|
||||||
<Character file="Content/Characters/Mudraptor/Mudraptor.xml" />
|
<Character file="Content/Characters/Mudraptor/Mudraptor.xml" />
|
||||||
@@ -70,10 +71,11 @@
|
|||||||
<Outpost file="Content/Map/Outposts/Outpost.sub" />
|
<Outpost file="Content/Map/Outposts/Outpost.sub" />
|
||||||
<Submarine file="Submarines/Orca.sub" />
|
<Submarine file="Submarines/Orca.sub" />
|
||||||
<Submarine file="Submarines/Typhon.sub" />
|
<Submarine file="Submarines/Typhon.sub" />
|
||||||
<Submarine file="Submarines/Muikku.sub" />
|
<Submarine file="Submarines/Selkie.sub" />
|
||||||
<Submarine file="Submarines/Bunyip.sub" />
|
<Submarine file="Submarines/Bunyip.sub" />
|
||||||
<Submarine file="Submarines/Humpback.sub" />
|
<Submarine file="Submarines/Humpback.sub" />
|
||||||
<Submarine file="Submarines/Dugong.sub" />
|
<Submarine file="Submarines/Dugong.sub" />
|
||||||
|
<Submarine file="Submarines/PAX.sub" />
|
||||||
<Submarine file="Submarines/Remora.sub" />
|
<Submarine file="Submarines/Remora.sub" />
|
||||||
<Submarine file="Submarines/RemoraDrone.sub" />
|
<Submarine file="Submarines/RemoraDrone.sub" />
|
||||||
<Text file="Content/Texts/EnglishVanilla.xml" />
|
<Text file="Content/Texts/EnglishVanilla.xml" />
|
||||||
|
|||||||
@@ -13,6 +13,13 @@
|
|||||||
<Command name="autorestart"/>
|
<Command name="autorestart"/>
|
||||||
<Command name="autorestartinterval"/>
|
<Command name="autorestartinterval"/>
|
||||||
<Command name="autorestarttimer"/>
|
<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="difficulty"/>
|
||||||
<Command name="kick"/>
|
<Command name="kick"/>
|
||||||
<Command name="kickid"/>
|
<Command name="kickid"/>
|
||||||
@@ -28,6 +35,8 @@
|
|||||||
<Command name="autorestart"/>
|
<Command name="autorestart"/>
|
||||||
<Command name="autorestartinterval"/>
|
<Command name="autorestartinterval"/>
|
||||||
<Command name="autorestarttimer"/>
|
<Command name="autorestarttimer"/>
|
||||||
|
<Command name="botcount"/>
|
||||||
|
<Command name="botspawnmode"/>
|
||||||
<Command name="difficulty"/>
|
<Command name="difficulty"/>
|
||||||
<Command name="kick"/>
|
<Command name="kick"/>
|
||||||
<Command name="kickid"/>
|
<Command name="kickid"/>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Carrier\Animations\" />
|
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Carrier\Animations\" />
|
||||||
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Animations\" />
|
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycharybdis\" />
|
||||||
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Coelanth\Animations\" />
|
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Coelanth\Animations\" />
|
||||||
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycrawler\" />
|
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycrawler\" />
|
||||||
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Endworm\Animations\" />
|
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Endworm\Animations\" />
|
||||||
@@ -45,12 +45,27 @@
|
|||||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Carrier\Ragdolls\CarrierDefaultRagdoll.xml">
|
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Carrier\Ragdolls\CarrierDefaultRagdoll.xml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</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">
|
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Charybdis.xml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Ragdolls\CharybdisDefaultRagdoll.xml">
|
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Ragdolls\CharybdisDefaultRagdoll.xml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</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">
|
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Coelanth\Coelanth.xml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
@@ -342,6 +357,36 @@
|
|||||||
<Content Include="$(MSBuildThisFileDirectory)Content\Effects\waterbump.png">
|
<Content Include="$(MSBuildThisFileDirectory)Content\Effects\waterbump.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</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">
|
<Content Include="$(MSBuildThisFileDirectory)Content\Fonts\NotoSans\LICENSE_OFL.txt">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
@@ -897,13 +942,13 @@
|
|||||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Carrier\Animations\CarrierSwimSlow.xml">
|
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Carrier\Animations\CarrierSwimSlow.xml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\charybdis.png">
|
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycharybdis\charybdis.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Animations\CharybdisSwimFast.xml">
|
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycharybdis\Animations\LegacycharybdisSwimFast.xml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Animations\CharybdisSwimSlow.xml">
|
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycharybdis\Animations\LegacycharybdisSwimSlow.xml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Coelanth\Animations\CoelanthSwimFast.xml">
|
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Coelanth\Animations\CoelanthSwimFast.xml">
|
||||||
@@ -1955,6 +2000,9 @@
|
|||||||
<Content Include="$(MSBuildThisFileDirectory)serversettings.xml">
|
<Content Include="$(MSBuildThisFileDirectory)serversettings.xml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<None Include="$(MSBuildThisFileDirectory)Content\Items\Misc\GuitarClown.ogg">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="$(MSBuildThisFileDirectory)Content\Characters\Carrier\CARRIER_alarmLoop.ogg">
|
<None Include="$(MSBuildThisFileDirectory)Content\Characters\Carrier\CARRIER_alarmLoop.ogg">
|
||||||
@@ -2356,7 +2404,7 @@
|
|||||||
<None Include="$(MSBuildThisFileDirectory)Content\Characters\Mudraptor\MUDRAPTOR_idle3.ogg">
|
<None Include="$(MSBuildThisFileDirectory)Content\Characters\Mudraptor\MUDRAPTOR_idle3.ogg">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\charybdisattack.ogg">
|
<None Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycharybdis\charybdisattack.ogg">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="$(MSBuildThisFileDirectory)Content\Characters\Coelanth\attack1.ogg">
|
<None Include="$(MSBuildThisFileDirectory)Content\Characters\Coelanth\attack1.ogg">
|
||||||
@@ -3114,7 +3162,7 @@
|
|||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="$(MSBuildThisFileDirectory)Submarines\Muikku.sub">
|
<None Include="$(MSBuildThisFileDirectory)Submarines\Muikku.sub">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="$(MSBuildThisFileDirectory)Submarines\Orca.sub">
|
<None Include="$(MSBuildThisFileDirectory)Submarines\Orca.sub">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
@@ -3134,6 +3182,9 @@
|
|||||||
<None Include="$(MSBuildThisFileDirectory)Submarines\RemoraDrone.sub">
|
<None Include="$(MSBuildThisFileDirectory)Submarines\RemoraDrone.sub">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="$(MSBuildThisFileDirectory)Submarines\Selkie.sub">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
<None Include="$(MSBuildThisFileDirectory)Submarines\Typhon.sub">
|
<None Include="$(MSBuildThisFileDirectory)Submarines\Typhon.sub">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ namespace Barotrauma
|
|||||||
SonarLabel = element.GetAttributeString("sonarlabel", "");
|
SonarLabel = element.GetAttributeString("sonarlabel", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public AITarget(Entity e)
|
public AITarget(Entity e, float sightRange = -1, float soundRange = 0)
|
||||||
{
|
{
|
||||||
Entity = e;
|
Entity = e;
|
||||||
if (sightRange < 0)
|
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
|
// is not attached or is attached to something else
|
||||||
if (!IsAttached || IsAttached && attachJoints[0].BodyB == attachTargetBody)
|
if (!IsAttached || IsAttached && attachJoints[0].BodyB == attachTargetBody)
|
||||||
{
|
{
|
||||||
if (Vector2.DistanceSquared(ConvertUnits.ToDisplayUnits(transformedAttachPos), enemyAI.AttackingLimb.WorldPosition) < enemyAI.AttackingLimb.attack.Range * enemyAI.AttackingLimb.attack.Range)
|
if (Vector2.DistanceSquared(ConvertUnits.ToDisplayUnits(transformedAttachPos), enemyAI.AttackingLimb.WorldPosition) < enemyAI.AttackingLimb.attack.DamageRange * enemyAI.AttackingLimb.attack.DamageRange)
|
||||||
{
|
{
|
||||||
AttachToBody(character.AnimController.Collider, attachLimb, attachTargetBody, transformedAttachPos);
|
AttachToBody(character.AnimController.Collider, attachLimb, attachTargetBody, transformedAttachPos);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -115,7 +115,8 @@ namespace Barotrauma
|
|||||||
unreachable.Add(goToObjective.Target as Hull);
|
unreachable.Add(goToObjective.Target as Hull);
|
||||||
}
|
}
|
||||||
goToObjective = null;
|
goToObjective = null;
|
||||||
SteeringManager.SteeringWander();
|
HumanAIController.ObjectiveManager.GetObjective<AIObjectiveIdle>().Wander(deltaTime);
|
||||||
|
//SteeringManager.SteeringWander();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (currentHull != null)
|
else if (currentHull != null)
|
||||||
|
|||||||
@@ -99,7 +99,8 @@ namespace Barotrauma
|
|||||||
FindTargetItem();
|
FindTargetItem();
|
||||||
if (targetItem == null || moveToTarget == null)
|
if (targetItem == null || moveToTarget == null)
|
||||||
{
|
{
|
||||||
SteeringManager.SteeringWander();
|
HumanAIController.ObjectiveManager.GetObjective<AIObjectiveIdle>().Wander(deltaTime);
|
||||||
|
//SteeringManager.SteeringWander();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,63 +98,67 @@ namespace Barotrauma
|
|||||||
PathSteering.Reset();
|
PathSteering.Reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (standStillTimer < -walkDuration)
|
if (standStillTimer < -walkDuration)
|
||||||
{
|
{
|
||||||
standStillTimer = Rand.Range(standStillMin, standStillMax);
|
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);
|
Wander(deltaTime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (leftDist < WallAvoidDistance && rightDist < WallAvoidDistance)
|
|
||||||
{
|
|
||||||
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.SteeringManual(deltaTime, -Vector2.UnitX * (WallAvoidDistance-rightDist) / WallAvoidDistance);
|
|
||||||
PathSteering.WanderAngle = MathHelper.Pi;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
character.AIController.SteeringManager.SteeringWander();
|
|
||||||
if (!character.IsClimbing && !character.AnimController.InWater)
|
|
||||||
{
|
|
||||||
//reset vertical steering to prevent dropping down from platforms etc
|
|
||||||
character.AIController.SteeringManager.ResetY();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentTarget != null)
|
if (currentTarget != null)
|
||||||
{
|
{
|
||||||
character.AIController.SteeringManager.SteeringSeek(currentTarget.SimPosition);
|
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)
|
||||||
|
{
|
||||||
|
PathSteering.SteeringManual(deltaTime, Vector2.UnitX * Math.Sign(rightDist - leftDist));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PathSteering.Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (leftDist < WallAvoidDistance)
|
||||||
|
{
|
||||||
|
//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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SteeringManager.SteeringWander();
|
||||||
|
}
|
||||||
|
if (!character.IsClimbing && !character.AnimController.InWater)
|
||||||
|
{
|
||||||
|
//reset vertical steering to prevent dropping down from platforms etc
|
||||||
|
character.AIController.SteeringManager.ResetY();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private readonly List<Hull> targetHulls = new List<Hull>(20);
|
private readonly List<Hull> targetHulls = new List<Hull>(20);
|
||||||
private readonly List<float> hullWeights = new List<float>(20);
|
private readonly List<float> hullWeights = new List<float>(20);
|
||||||
|
|
||||||
|
|||||||
@@ -369,9 +369,18 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float movementAngle = MathUtils.VectorToAngle(movement) - MathHelper.PiOver2;
|
Vector2 transformedMovement = reverse ? -movement : movement;
|
||||||
|
float movementAngle = MathUtils.VectorToAngle(transformedMovement) - MathHelper.PiOver2;
|
||||||
float mainLimbAngle = (MainLimb.type == LimbType.Torso ? TorsoAngle.Value : HeadAngle.Value) * Dir;
|
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;
|
||||||
while (MainLimb.Rotation - (movementAngle + mainLimbAngle) > MathHelper.Pi)
|
while (MainLimb.Rotation - (movementAngle + mainLimbAngle) > MathHelper.Pi)
|
||||||
{
|
{
|
||||||
movementAngle += MathHelper.TwoPi;
|
movementAngle += MathHelper.TwoPi;
|
||||||
@@ -379,7 +388,7 @@ namespace Barotrauma
|
|||||||
while (MainLimb.Rotation - (movementAngle + mainLimbAngle) < -MathHelper.Pi)
|
while (MainLimb.Rotation - (movementAngle + mainLimbAngle) < -MathHelper.Pi)
|
||||||
{
|
{
|
||||||
movementAngle -= MathHelper.TwoPi;
|
movementAngle -= MathHelper.TwoPi;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CurrentSwimParams.RotateTowardsMovement)
|
if (CurrentSwimParams.RotateTowardsMovement)
|
||||||
{
|
{
|
||||||
@@ -403,7 +412,6 @@ namespace Barotrauma
|
|||||||
if (TailAngle.HasValue)
|
if (TailAngle.HasValue)
|
||||||
{
|
{
|
||||||
Limb tail = GetLimb(LimbType.Tail);
|
Limb tail = GetLimb(LimbType.Tail);
|
||||||
//tail?.body.SmoothRotate(movementAngle + TailAngle.Value * Dir, TailTorque);
|
|
||||||
if (tail != null)
|
if (tail != null)
|
||||||
{
|
{
|
||||||
SmoothRotateWithoutWrapping(tail, movementAngle + TailAngle.Value * Dir, MainLimb, TailTorque);
|
SmoothRotateWithoutWrapping(tail, movementAngle + TailAngle.Value * Dir, MainLimb, TailTorque);
|
||||||
@@ -413,6 +421,10 @@ namespace Barotrauma
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
movementAngle = Dir > 0 ? -MathHelper.PiOver2 : MathHelper.PiOver2;
|
movementAngle = Dir > 0 ? -MathHelper.PiOver2 : MathHelper.PiOver2;
|
||||||
|
if (reverse)
|
||||||
|
{
|
||||||
|
movementAngle = MathUtils.WrapAngleTwoPi(movementAngle - MathHelper.Pi);
|
||||||
|
}
|
||||||
if (MainLimb.type == LimbType.Head && HeadAngle.HasValue)
|
if (MainLimb.type == LimbType.Head && HeadAngle.HasValue)
|
||||||
{
|
{
|
||||||
Collider.SmoothRotate(HeadAngle.Value * Dir, CurrentSwimParams.SteerTorque);
|
Collider.SmoothRotate(HeadAngle.Value * Dir, CurrentSwimParams.SteerTorque);
|
||||||
@@ -442,7 +454,7 @@ namespace Barotrauma
|
|||||||
var waveAmplitude = Math.Abs(CurrentSwimParams.WaveAmplitude);
|
var waveAmplitude = Math.Abs(CurrentSwimParams.WaveAmplitude);
|
||||||
if (waveLength > 0 && waveAmplitude > 0)
|
if (waveLength > 0 && waveAmplitude > 0)
|
||||||
{
|
{
|
||||||
WalkPos -= movement.Length() / Math.Abs(waveLength);
|
WalkPos -= transformedMovement.Length() / Math.Abs(waveLength);
|
||||||
WalkPos = MathUtils.WrapAngleTwoPi(WalkPos);
|
WalkPos = MathUtils.WrapAngleTwoPi(WalkPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -685,12 +697,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
limb.body.ApplyForce(diff * (float)(Math.Sin(WalkPos) * Math.Sqrt(limb.Mass)) * 30.0f * animStrength);
|
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)
|
private void SmoothRotateWithoutWrapping(Limb limb, float angle, Limb referenceLimb, float torque)
|
||||||
|
|||||||
+1
-1
@@ -99,7 +99,7 @@ namespace Barotrauma
|
|||||||
public static string GetDefaultFolder(string speciesName) => $"Content/Characters/{speciesName.CapitaliseFirstInvariant()}/Animations/";
|
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 GetDefaultFile(string speciesName, AnimationType animType) => $"{GetFolder(speciesName)}{GetDefaultFileName(speciesName, animType)}.xml";
|
||||||
|
|
||||||
protected static string GetFolder(string speciesName)
|
public static string GetFolder(string speciesName)
|
||||||
{
|
{
|
||||||
var folder = XMLExtensions.TryLoadXml(Character.GetConfigFile(speciesName))?.Root?.Element("animations")?.GetAttributeString("folder", string.Empty);
|
var folder = XMLExtensions.TryLoadXml(Character.GetConfigFile(speciesName))?.Root?.Element("animations")?.GetAttributeString("folder", string.Empty);
|
||||||
if (string.IsNullOrEmpty(folder) || folder.ToLowerInvariant() == "default")
|
if (string.IsNullOrEmpty(folder) || folder.ToLowerInvariant() == "default")
|
||||||
|
|||||||
+1
-1
@@ -79,7 +79,7 @@ namespace Barotrauma
|
|||||||
new XAttribute("sourcerect", $"0, 0, 1, 1")))
|
new XAttribute("sourcerect", $"0, 0, 1, 1")))
|
||||||
};
|
};
|
||||||
|
|
||||||
protected static string GetFolder(string speciesName)
|
public static string GetFolder(string speciesName)
|
||||||
{
|
{
|
||||||
var folder = XMLExtensions.TryLoadXml(Character.GetConfigFile(speciesName))?.Root?.Element("ragdolls")?.GetAttributeString("folder", string.Empty);
|
var folder = XMLExtensions.TryLoadXml(Character.GetConfigFile(speciesName))?.Root?.Element("ragdolls")?.GetAttributeString("folder", string.Empty);
|
||||||
if (string.IsNullOrEmpty(folder) || folder.ToLowerInvariant() == "default")
|
if (string.IsNullOrEmpty(folder) || folder.ToLowerInvariant() == "default")
|
||||||
|
|||||||
@@ -1035,8 +1035,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
CheckValidity();
|
CheckValidity();
|
||||||
|
|
||||||
CheckValidity();
|
|
||||||
|
|
||||||
UpdateNetPlayerPosition(deltaTime);
|
UpdateNetPlayerPosition(deltaTime);
|
||||||
CheckDistFromCollider();
|
CheckDistFromCollider();
|
||||||
UpdateCollisionCategories();
|
UpdateCollisionCategories();
|
||||||
@@ -1297,17 +1295,42 @@ namespace Barotrauma
|
|||||||
UpdateProjSpecific(deltaTime);
|
UpdateProjSpecific(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckValidity()
|
public bool Invalid { get; private set; }
|
||||||
|
private int validityResets;
|
||||||
|
private bool CheckValidity()
|
||||||
{
|
{
|
||||||
CheckValidity(Collider);
|
bool isColliderValid = CheckValidity(Collider);
|
||||||
|
bool limbsValid = true;
|
||||||
foreach (Limb limb in limbs)
|
foreach (Limb limb in limbs)
|
||||||
{
|
{
|
||||||
if (limb.body == null || !limb.body.Enabled) { continue; }
|
if (limb.body == null || !limb.body.Enabled) { continue; }
|
||||||
CheckValidity(limb.body);
|
if (!CheckValidity(limb.body))
|
||||||
|
{
|
||||||
|
limbsValid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
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 void CheckValidity(PhysicsBody body)
|
private bool CheckValidity(PhysicsBody body)
|
||||||
{
|
{
|
||||||
string errorMsg = null;
|
string errorMsg = null;
|
||||||
string bodyName = body.UserData is Limb ? "Limb" : "Collider";
|
string bodyName = body.UserData is Limb ? "Limb" : "Collider";
|
||||||
@@ -1359,7 +1382,7 @@ namespace Barotrauma
|
|||||||
limb.body.ResetDynamics();
|
limb.body.ResetDynamics();
|
||||||
}
|
}
|
||||||
SetInitialLimbPositions();
|
SetInitialLimbPositions();
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ namespace Barotrauma
|
|||||||
public enum AIBehaviorAfterAttack
|
public enum AIBehaviorAfterAttack
|
||||||
{
|
{
|
||||||
FallBack,
|
FallBack,
|
||||||
|
FallBackUntilCanAttack,
|
||||||
PursueIfCanAttack,
|
PursueIfCanAttack,
|
||||||
Pursue
|
Pursue
|
||||||
}
|
}
|
||||||
@@ -81,6 +82,9 @@ namespace Barotrauma
|
|||||||
[Serialize(AIBehaviorAfterAttack.FallBack, true), Editable(ToolTip = "The preferred AI behavior after the attack.")]
|
[Serialize(AIBehaviorAfterAttack.FallBack, true), Editable(ToolTip = "The preferred AI behavior after the attack.")]
|
||||||
public AIBehaviorAfterAttack AfterAttack { get; private set; }
|
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.")]
|
[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; }
|
public float Range { get; private set; }
|
||||||
|
|
||||||
@@ -96,6 +100,9 @@ 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.")]
|
[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;
|
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)]
|
[Serialize(0.0f, true), Editable(MinValueFloat = 0.0f, MaxValueFloat = 10000.0f)]
|
||||||
public float StructureDamage { get; private set; }
|
public float StructureDamage { get; private set; }
|
||||||
|
|
||||||
@@ -182,7 +189,7 @@ namespace Barotrauma
|
|||||||
public readonly List<Affliction> Afflictions = new List<Affliction>();
|
public readonly List<Affliction> Afflictions = new List<Affliction>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Only affects ai decision making.
|
/// 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?)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<PropertyConditional> Conditionals { get; private set; } = new List<PropertyConditional>();
|
public List<PropertyConditional> Conditionals { get; private set; } = new List<PropertyConditional>();
|
||||||
|
|
||||||
@@ -444,8 +451,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void SetCoolDown()
|
public void SetCoolDown()
|
||||||
{
|
{
|
||||||
CoolDownTimer = CoolDown;
|
float randomFraction = CoolDown * CoolDownRandomFactor;
|
||||||
SecondaryCoolDownTimer = SecondaryCoolDown;
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetCoolDown()
|
public void ResetCoolDown()
|
||||||
|
|||||||
@@ -810,6 +810,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void LoadHeadAttachments()
|
public void LoadHeadAttachments()
|
||||||
{
|
{
|
||||||
|
if (Info == null) { return; }
|
||||||
if (AnimController == null) { return; }
|
if (AnimController == null) { return; }
|
||||||
var head = AnimController.GetLimb(LimbType.Head);
|
var head = AnimController.GetLimb(LimbType.Head);
|
||||||
if (head == null) { return; }
|
if (head == null) { return; }
|
||||||
@@ -1112,13 +1113,15 @@ namespace Barotrauma
|
|||||||
ViewTarget = null;
|
ViewTarget = null;
|
||||||
if (!AllowInput) return;
|
if (!AllowInput) return;
|
||||||
|
|
||||||
Vector2 smoothedCursorDiff = cursorPosition - SmoothedCursorPosition;
|
if (Controlled == this || (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer))
|
||||||
if (Controlled == this)
|
|
||||||
{
|
{
|
||||||
SmoothedCursorPosition = cursorPosition;
|
SmoothedCursorPosition = cursorPosition;
|
||||||
}
|
}
|
||||||
else
|
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);
|
smoothedCursorDiff = NetConfig.InterpolateCursorPositionError(smoothedCursorDiff);
|
||||||
SmoothedCursorPosition = cursorPosition - smoothedCursorDiff;
|
SmoothedCursorPosition = cursorPosition - smoothedCursorDiff;
|
||||||
}
|
}
|
||||||
@@ -1185,6 +1188,10 @@ namespace Barotrauma
|
|||||||
if (PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.F))
|
if (PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.F))
|
||||||
{
|
{
|
||||||
AnimController.ReleaseStuckLimbs();
|
AnimController.ReleaseStuckLimbs();
|
||||||
|
if (AIController != null && AIController is EnemyAIController enemyAI)
|
||||||
|
{
|
||||||
|
enemyAI.LatchOntoAI?.DeattachFromBody();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1264,15 +1271,7 @@ namespace Barotrauma
|
|||||||
if (IsKeyDown(InputType.Aim) && selectedItems[i] != null) selectedItems[i].SecondaryUse(deltaTime, this);
|
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 (SelectedConstruction != null)
|
||||||
{
|
{
|
||||||
if (IsKeyDown(InputType.Use)) SelectedConstruction.Use(deltaTime, this);
|
if (IsKeyDown(InputType.Use)) SelectedConstruction.Use(deltaTime, this);
|
||||||
@@ -1650,7 +1649,8 @@ namespace Barotrauma
|
|||||||
#if CLIENT
|
#if CLIENT
|
||||||
if (isLocalPlayer)
|
if (isLocalPlayer)
|
||||||
{
|
{
|
||||||
if (GUI.MouseOn == null && !CharacterInventory.IsMouseOnInventory())
|
if (GUI.MouseOn == null &&
|
||||||
|
(!CharacterInventory.IsMouseOnInventory() || CharacterInventory.DraggingItemToWorld))
|
||||||
{
|
{
|
||||||
if (findFocusedTimer <= 0.0f || Screen.Selected == GameMain.SubEditorScreen)
|
if (findFocusedTimer <= 0.0f || Screen.Selected == GameMain.SubEditorScreen)
|
||||||
{
|
{
|
||||||
@@ -1665,10 +1665,12 @@ namespace Barotrauma
|
|||||||
focusedItem = null;
|
focusedItem = null;
|
||||||
}
|
}
|
||||||
findFocusedTimer -= deltaTime;
|
findFocusedTimer -= deltaTime;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
//climb ladders automatically when pressing up/down inside their trigger area
|
//climb ladders automatically when pressing up/down inside their trigger area
|
||||||
if (SelectedConstruction == null && !AnimController.InWater && Screen.Selected != GameMain.SubEditorScreen)
|
Ladder currentLadder = SelectedConstruction?.GetComponent<Ladder>();
|
||||||
|
if ((SelectedConstruction == null || currentLadder != null) &&
|
||||||
|
!AnimController.InWater && Screen.Selected != GameMain.SubEditorScreen)
|
||||||
{
|
{
|
||||||
bool climbInput = IsKeyDown(InputType.Up) || IsKeyDown(InputType.Down);
|
bool climbInput = IsKeyDown(InputType.Up) || IsKeyDown(InputType.Down);
|
||||||
bool isControlled = Controlled == this;
|
bool isControlled = Controlled == this;
|
||||||
@@ -1679,6 +1681,19 @@ namespace Barotrauma
|
|||||||
float minDist = float.PositiveInfinity;
|
float minDist = float.PositiveInfinity;
|
||||||
foreach (Ladder ladder in Ladder.List)
|
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)
|
if (CanInteractWith(ladder.Item, out float dist, checkLinked: false) && dist < minDist)
|
||||||
{
|
{
|
||||||
minDist = dist;
|
minDist = dist;
|
||||||
@@ -1695,7 +1710,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SelectedCharacter != null && IsKeyHit(InputType.Grab)) //Let people use ladders and buttons and stuff when dragging chars
|
if (SelectedCharacter != null && (IsKeyHit(InputType.Grab) || IsKeyHit(InputType.Health))) //Let people use ladders and buttons and stuff when dragging chars
|
||||||
{
|
{
|
||||||
DeselectCharacter();
|
DeselectCharacter();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -804,6 +804,12 @@ namespace Barotrauma
|
|||||||
var newItem = Item.Load(itemElement, inventory.Owner.Submarine, createNetworkEvent: true);
|
var newItem = Item.Load(itemElement, inventory.Owner.Submarine, createNetworkEvent: true);
|
||||||
if (newItem == null) { continue; }
|
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 });
|
int[] slotIndices = itemElement.GetAttributeIntArray("i", new int[] { 0 });
|
||||||
if (!slotIndices.Any())
|
if (!slotIndices.Any())
|
||||||
{
|
{
|
||||||
|
|||||||
+6
-1
@@ -153,7 +153,10 @@ namespace Barotrauma
|
|||||||
//how high the strength has to be for the affliction icon to be shown in the UI
|
//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 ShowIconThreshold = 0.05f;
|
||||||
public readonly float MaxStrength = 100.0f;
|
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 BurnOverlayAlpha;
|
||||||
public float DamageOverlayAlpha;
|
public float DamageOverlayAlpha;
|
||||||
|
|
||||||
@@ -257,6 +260,8 @@ namespace Barotrauma
|
|||||||
ShowIconThreshold = element.GetAttributeFloat("showiconthreshold", Math.Max(ActivationThreshold, 0.05f));
|
ShowIconThreshold = element.GetAttributeFloat("showiconthreshold", Math.Max(ActivationThreshold, 0.05f));
|
||||||
MaxStrength = element.GetAttributeFloat("maxstrength", 100.0f);
|
MaxStrength = element.GetAttributeFloat("maxstrength", 100.0f);
|
||||||
|
|
||||||
|
ShowInHealthScannerThreshold = element.GetAttributeFloat("showinhealthscannerthreshold", Math.Max(ActivationThreshold, 0.05f));
|
||||||
|
|
||||||
DamageOverlayAlpha = element.GetAttributeFloat("damageoverlayalpha", 0.0f);
|
DamageOverlayAlpha = element.GetAttributeFloat("damageoverlayalpha", 0.0f);
|
||||||
BurnOverlayAlpha = element.GetAttributeFloat("burnoverlayalpha", 0.0f);
|
BurnOverlayAlpha = element.GetAttributeFloat("burnoverlayalpha", 0.0f);
|
||||||
|
|
||||||
|
|||||||
@@ -460,6 +460,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
affliction.Strength = 0.0f;
|
affliction.Strength = 0.0f;
|
||||||
}
|
}
|
||||||
|
CalculateVitality();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddLimbAffliction(Limb limb, Affliction newAffliction)
|
private void AddLimbAffliction(Limb limb, Affliction newAffliction)
|
||||||
|
|||||||
@@ -520,14 +520,15 @@ namespace Barotrauma
|
|||||||
// Ignore blocking on items, because it causes cases where a Mudraptor cannot hit the hatch, for example.
|
// Ignore blocking on items, because it causes cases where a Mudraptor cannot hit the hatch, for example.
|
||||||
wasHit = true;
|
wasHit = true;
|
||||||
}
|
}
|
||||||
else if (damageTarget is Structure && structureBody?.UserData is Structure)
|
else if (damageTarget is Structure wall && structureBody != null &&
|
||||||
|
(structureBody.UserData is Structure || (structureBody.UserData is Submarine sub && sub == wall.Submarine)))
|
||||||
{
|
{
|
||||||
// If the attack is aimed to a structure and hits a structure, it's successful
|
// If the attack is aimed to a structure (wall) and hits a structure or the sub, it's successful
|
||||||
wasHit = true;
|
wasHit = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If the attack is aimed to a character but hits a structure, the hit is blocked.
|
// If there is nothing between, the hit is successful
|
||||||
wasHit = structureBody == null;
|
wasHit = structureBody == null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,12 +103,6 @@ namespace Barotrauma
|
|||||||
if (missionType == MissionType.Random)
|
if (missionType == MissionType.Random)
|
||||||
{
|
{
|
||||||
allowedMissions.AddRange(MissionPrefab.List);
|
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)
|
else if (missionType == MissionType.None)
|
||||||
{
|
{
|
||||||
@@ -124,6 +118,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
allowedMissions.RemoveAll(m => !m.IsAllowed(locations[0], locations[1]));
|
allowedMissions.RemoveAll(m => !m.IsAllowed(locations[0], locations[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (allowedMissions.Count == 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
int probabilitySum = allowedMissions.Sum(m => m.Commonness);
|
int probabilitySum = allowedMissions.Sum(m => m.Commonness);
|
||||||
int randomNumber = rand.NextInt32() % probabilitySum;
|
int randomNumber = rand.NextInt32() % probabilitySum;
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ namespace Barotrauma
|
|||||||
MTRandom rand = new MTRandom(ToolBox.StringToInt(seed));
|
MTRandom rand = new MTRandom(ToolBox.StringToInt(seed));
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
dummyLocations[i] = Location.CreateRandom(new Vector2((float)rand.NextDouble() * 10000.0f, (float)rand.NextDouble() * 10000.0f), null);
|
dummyLocations[i] = Location.CreateRandom(new Vector2((float)rand.NextDouble() * 10000.0f, (float)rand.NextDouble() * 10000.0f), null, rand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,7 +208,7 @@ namespace Barotrauma
|
|||||||
DockingPort myPort = null, outPostPort = null;
|
DockingPort myPort = null, outPostPort = null;
|
||||||
foreach (DockingPort port in DockingPort.List)
|
foreach (DockingPort port in DockingPort.List)
|
||||||
{
|
{
|
||||||
if (port.IsHorizontal) { continue; }
|
if (port.IsHorizontal || port.Docked) { continue; }
|
||||||
if (port.Item.Submarine == level.StartOutpost)
|
if (port.Item.Submarine == level.StartOutpost)
|
||||||
{
|
{
|
||||||
outPostPort = port;
|
outPostPort = port;
|
||||||
|
|||||||
@@ -880,8 +880,7 @@ namespace Barotrauma.Items.Components
|
|||||||
List<MapEntity> linked = new List<MapEntity>(item.linkedTo);
|
List<MapEntity> linked = new List<MapEntity>(item.linkedTo);
|
||||||
foreach (MapEntity entity in linked)
|
foreach (MapEntity entity in linked)
|
||||||
{
|
{
|
||||||
Item linkedItem = entity as Item;
|
if (!(entity is Item linkedItem)) { continue; }
|
||||||
if (linkedItem == null) { continue; }
|
|
||||||
|
|
||||||
var dockingPort = linkedItem.GetComponent<DockingPort>();
|
var dockingPort = linkedItem.GetComponent<DockingPort>();
|
||||||
if (dockingPort != null)
|
if (dockingPort != null)
|
||||||
|
|||||||
@@ -426,11 +426,11 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
public override bool Use(float deltaTime, Character character = null)
|
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 != null)
|
||||||
{
|
{
|
||||||
if (!character.IsKeyDown(InputType.Aim)) return false;
|
if (!character.IsKeyDown(InputType.Aim)) { return false; }
|
||||||
if (!CanBeAttached()) return false;
|
if (!CanBeAttached()) { return false; }
|
||||||
#if SERVER
|
#if SERVER
|
||||||
if (GameMain.Server != null)
|
if (GameMain.Server != null)
|
||||||
{
|
{
|
||||||
@@ -438,7 +438,12 @@ namespace Barotrauma.Items.Components
|
|||||||
GameServer.Log(character.LogName + " attached " + item.Name + " to a wall", ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(character.LogName + " attached " + item.Name + " to a wall", ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
item.Drop(character);
|
}
|
||||||
|
|
||||||
|
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
|
||||||
|
{
|
||||||
|
if (character != null) { item.Drop(character); }
|
||||||
|
AttachToWall();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -550,7 +555,7 @@ namespace Barotrauma.Items.Components
|
|||||||
public override void ServerWrite(NetBuffer msg, Client c, object[] extraData = null)
|
public override void ServerWrite(NetBuffer msg, Client c, object[] extraData = null)
|
||||||
{
|
{
|
||||||
base.ServerWrite(msg, c, extraData);
|
base.ServerWrite(msg, c, extraData);
|
||||||
if (!attachable || body == null) return;
|
if (!attachable || body == null) { return; }
|
||||||
|
|
||||||
msg.Write(Attached);
|
msg.Write(Attached);
|
||||||
msg.Write(body.SimPosition.X);
|
msg.Write(body.SimPosition.X);
|
||||||
|
|||||||
@@ -2,12 +2,15 @@
|
|||||||
using Lidgren.Network;
|
using Lidgren.Network;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace Barotrauma.Items.Components
|
namespace Barotrauma.Items.Components
|
||||||
{
|
{
|
||||||
partial class LevelResource : ItemComponent, IServerSerializable
|
partial class LevelResource : ItemComponent, IServerSerializable
|
||||||
{
|
{
|
||||||
|
private float lastSentDeattachTimer;
|
||||||
|
|
||||||
[Serialize(1.0f, false)]
|
[Serialize(1.0f, false)]
|
||||||
public float DeattachDuration
|
public float DeattachDuration
|
||||||
{
|
{
|
||||||
@@ -21,12 +24,29 @@ namespace Barotrauma.Items.Components
|
|||||||
get { return deattachTimer; }
|
get { return deattachTimer; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
deattachTimer = Math.Max(0.0f, value);
|
|
||||||
//clients don't deattach the item until the server says so (handled in ClientRead)
|
//clients don't deattach the item until the server says so (handled in ClientRead)
|
||||||
if ((GameMain.NetworkMember == null || !GameMain.NetworkMember.IsClient) && deattachTimer >= DeattachDuration)
|
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)
|
||||||
{
|
{
|
||||||
holdable.DeattachFromWall();
|
holdable.DeattachFromWall();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +87,10 @@ namespace Barotrauma.Items.Components
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
holdable.Reattachable = false;
|
holdable.Reattachable = false;
|
||||||
holdable.PickingTime = float.MaxValue;
|
if (requiredItems.Any())
|
||||||
|
{
|
||||||
|
holdable.PickingTime = float.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
var body = item.body ?? holdable.Body;
|
var body = item.body ?? holdable.Body;
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ namespace Barotrauma.Items.Components
|
|||||||
private readonly List<string> fixableEntities;
|
private readonly List<string> fixableEntities;
|
||||||
private Vector2 pickedPosition;
|
private Vector2 pickedPosition;
|
||||||
private float activeTimer;
|
private float activeTimer;
|
||||||
|
|
||||||
|
private Vector2 debugRayStartPos, debugRayEndPos;
|
||||||
|
|
||||||
[Serialize(0.0f, false)]
|
[Serialize(0.0f, false)]
|
||||||
public float Range { get; set; }
|
public float Range { get; set; }
|
||||||
@@ -156,7 +158,7 @@ namespace Barotrauma.Items.Components
|
|||||||
var collisionCategories = Physics.CollisionWall | Physics.CollisionCharacter | Physics.CollisionItem | Physics.CollisionLevel | Physics.CollisionRepair;
|
var collisionCategories = Physics.CollisionWall | Physics.CollisionCharacter | Physics.CollisionItem | Physics.CollisionLevel | Physics.CollisionRepair;
|
||||||
if (RepairThroughWalls)
|
if (RepairThroughWalls)
|
||||||
{
|
{
|
||||||
var bodies = Submarine.PickBodies(rayStart, rayEnd, ignoredBodies, collisionCategories, ignoreSensors: false);
|
var bodies = Submarine.PickBodies(rayStart, rayEnd, ignoredBodies, collisionCategories, ignoreSensors: false, allowInsideFixture: true);
|
||||||
foreach (Body body in bodies)
|
foreach (Body body in bodies)
|
||||||
{
|
{
|
||||||
FixBody(user, deltaTime, degreeOfSuccess, body);
|
FixBody(user, deltaTime, degreeOfSuccess, body);
|
||||||
@@ -164,7 +166,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FixBody(user, deltaTime, degreeOfSuccess, Submarine.PickBody(rayStart, rayEnd, ignoredBodies, collisionCategories, ignoreSensors: false));
|
FixBody(user, deltaTime, degreeOfSuccess, Submarine.PickBody(rayStart, rayEnd, ignoredBodies, collisionCategories, ignoreSensors: false, allowInsideFixture: true));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ExtinguishAmount > 0.0f && item.CurrentHull != null)
|
if (ExtinguishAmount > 0.0f && item.CurrentHull != null)
|
||||||
@@ -247,6 +249,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
var levelResource = targetItem.GetComponent<LevelResource>();
|
var levelResource = targetItem.GetComponent<LevelResource>();
|
||||||
if (levelResource != null && levelResource.IsActive &&
|
if (levelResource != null && levelResource.IsActive &&
|
||||||
|
levelResource.requiredItems.Any() &&
|
||||||
levelResource.HasRequiredItems(user, addMessage: false))
|
levelResource.HasRequiredItems(user, addMessage: false))
|
||||||
{
|
{
|
||||||
levelResource.DeattachTimer += deltaTime;
|
levelResource.DeattachTimer += deltaTime;
|
||||||
|
|||||||
@@ -104,8 +104,8 @@ namespace Barotrauma.Items.Components
|
|||||||
#if SERVER
|
#if SERVER
|
||||||
GameServer.Log(picker.LogName + " threw " + item.Name, ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(picker.LogName + " threw " + item.Name, ServerLog.MessageType.ItemInteraction);
|
||||||
#endif
|
#endif
|
||||||
|
Character thrower = picker;
|
||||||
item.Drop(picker, createNetworkEvent: GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer);
|
item.Drop(thrower, createNetworkEvent: GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer);
|
||||||
item.body.ApplyLinearImpulse(throwVector * throwForce * item.body.Mass * 3.0f);
|
item.body.ApplyLinearImpulse(throwVector * throwForce * item.body.Mass * 3.0f);
|
||||||
|
|
||||||
ac.GetLimb(LimbType.Head).body.ApplyLinearImpulse(throwVector*10.0f);
|
ac.GetLimb(LimbType.Head).body.ApplyLinearImpulse(throwVector*10.0f);
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
get { return name; }
|
get { return name; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[Editable, Serialize("", true)]
|
[Editable, Serialize("", true)]
|
||||||
public string Msg
|
public string Msg
|
||||||
{
|
{
|
||||||
@@ -203,12 +203,6 @@ namespace Barotrauma.Items.Components
|
|||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AITarget AITarget
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AITarget AITarget
|
public AITarget AITarget
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
@@ -253,7 +247,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Invalid pick key in " + element + "!", e);
|
DebugConsole.ThrowError("Invalid pick key in " + element + "!", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
SerializableProperties = SerializableProperty.DeserializeProperties(this, element);
|
SerializableProperties = SerializableProperty.DeserializeProperties(this, element);
|
||||||
ParseMsg();
|
ParseMsg();
|
||||||
|
|
||||||
|
|||||||
@@ -155,13 +155,14 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
if (item.Container != null) { return false; }
|
if (item.Container != null) { return false; }
|
||||||
|
|
||||||
if (AutoInteractWithContained)
|
if (AutoInteractWithContained && character.SelectedConstruction == null)
|
||||||
{
|
{
|
||||||
foreach (Item contained in Inventory.Items)
|
foreach (Item contained in Inventory.Items)
|
||||||
{
|
{
|
||||||
if (contained == null) continue;
|
if (contained == null) continue;
|
||||||
if (contained.TryInteract(character))
|
if (contained.TryInteract(character))
|
||||||
{
|
{
|
||||||
|
character.FocusedItem = contained;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,6 +179,7 @@ namespace Barotrauma.Items.Components
|
|||||||
if (contained == null) continue;
|
if (contained == null) continue;
|
||||||
if (contained.TryInteract(picker))
|
if (contained.TryInteract(picker))
|
||||||
{
|
{
|
||||||
|
picker.FocusedItem = contained;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ namespace Barotrauma.Items.Components
|
|||||||
Force = MathHelper.Lerp(force, (voltage < minVoltage) ? 0.0f : targetForce, 0.1f);
|
Force = MathHelper.Lerp(force, (voltage < minVoltage) ? 0.0f : targetForce, 0.1f);
|
||||||
if (Math.Abs(Force) > 1.0f)
|
if (Math.Abs(Force) > 1.0f)
|
||||||
{
|
{
|
||||||
Vector2 currForce = new Vector2((force / 100.0f) * maxForce * Math.Min(voltage / minVoltage, 1.0f), 0.0f);
|
Vector2 currForce = new Vector2((force / 10.0f) * maxForce * Math.Min(voltage / minVoltage, 1.0f), 0.0f);
|
||||||
//less effective when in a bad condition
|
//less effective when in a bad condition
|
||||||
currForce *= MathHelper.Lerp(0.5f, 2.0f, item.Condition / item.MaxCondition);
|
currForce *= MathHelper.Lerp(0.5f, 2.0f, item.Condition / item.MaxCondition);
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
private bool shutDown;
|
private bool shutDown;
|
||||||
|
|
||||||
const float AIUpdateInterval = 1.0f;
|
const float AIUpdateInterval = 0.2f;
|
||||||
private float aiUpdateTimer;
|
private float aiUpdateTimer;
|
||||||
|
|
||||||
private Character lastUser;
|
private Character lastUser;
|
||||||
@@ -209,10 +209,10 @@ namespace Barotrauma.Items.Components
|
|||||||
allowedFissionRate = Vector2.Lerp(new Vector2(20, AvailableFuel), new Vector2(10, AvailableFuel), degreeOfSuccess);
|
allowedFissionRate = Vector2.Lerp(new Vector2(20, AvailableFuel), new Vector2(10, AvailableFuel), degreeOfSuccess);
|
||||||
allowedFissionRate.X = Math.Min(allowedFissionRate.X, allowedFissionRate.Y - 10);
|
allowedFissionRate.X = Math.Min(allowedFissionRate.X, allowedFissionRate.Y - 10);
|
||||||
|
|
||||||
float heatAmount = fissionRate * (AvailableFuel / 100.0f) * 2.0f;
|
float heatAmount = GetGeneratedHeat(fissionRate);
|
||||||
float temperatureDiff = (heatAmount - turbineOutput) - Temperature;
|
float temperatureDiff = (heatAmount - turbineOutput) - Temperature;
|
||||||
Temperature += MathHelper.Clamp(Math.Sign(temperatureDiff) * 10.0f * deltaTime, -Math.Abs(temperatureDiff), Math.Abs(temperatureDiff));
|
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);
|
FissionRate = MathHelper.Lerp(fissionRate, Math.Min(targetFissionRate, AvailableFuel), deltaTime);
|
||||||
TurbineOutput = MathHelper.Lerp(turbineOutput, targetTurbineOutput, deltaTime);
|
TurbineOutput = MathHelper.Lerp(turbineOutput, targetTurbineOutput, deltaTime);
|
||||||
@@ -313,6 +313,48 @@ 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)
|
private void UpdateFailures(float deltaTime)
|
||||||
{
|
{
|
||||||
if (temperature > allowedTemperature.Y)
|
if (temperature > allowedTemperature.Y)
|
||||||
@@ -367,6 +409,11 @@ namespace Barotrauma.Items.Components
|
|||||||
targetFissionRate = Math.Min(targetFissionRate + speed * 2 * deltaTime, 100.0f);
|
targetFissionRate = Math.Min(targetFissionRate + speed * 2 * deltaTime, 100.0f);
|
||||||
}
|
}
|
||||||
targetFissionRate = MathHelper.Clamp(targetFissionRate, 0.0f, 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)
|
public override void UpdateBroken(float deltaTime, Camera cam)
|
||||||
@@ -441,12 +488,18 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//we need more fuel
|
if (aiUpdateTimer > 0.0f)
|
||||||
if (-currPowerConsumption < load * 0.5f && prevAvailableFuel <= 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))
|
||||||
{
|
{
|
||||||
var containFuelObjective = new AIObjectiveContainItem(character, new string[] { "fuelrod", "reactorfuel" }, item.GetComponent<ItemContainer>())
|
var containFuelObjective = new AIObjectiveContainItem(character, new string[] { "fuelrod", "reactorfuel" }, item.GetComponent<ItemContainer>())
|
||||||
{
|
{
|
||||||
MinContainedAmount = containedItems.Count(i => i != null && i.Prefab.Identifier == "fuelrod" || i.HasTag("reactorfuel")) + 1,
|
MinContainedAmount = item.ContainedItems.Count(i => i != null && i.Prefab.Identifier == "fuelrod" || i.HasTag("reactorfuel")) + 1,
|
||||||
GetItemPriority = (Item fuelItem) =>
|
GetItemPriority = (Item fuelItem) =>
|
||||||
{
|
{
|
||||||
if (fuelItem.ParentInventory?.Owner is Item)
|
if (fuelItem.ParentInventory?.Owner is Item)
|
||||||
@@ -461,6 +514,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
character?.Speak(TextManager.Get("DialogReactorFuel"), null, 0.0f, "reactorfuel", 30.0f);
|
character?.Speak(TextManager.Get("DialogReactorFuel"), null, 0.0f, "reactorfuel", 30.0f);
|
||||||
|
|
||||||
|
aiUpdateTimer = AIUpdateInterval;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (TooMuchFuel())
|
else if (TooMuchFuel())
|
||||||
@@ -479,12 +533,6 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aiUpdateTimer > 0.0f)
|
|
||||||
{
|
|
||||||
aiUpdateTimer -= deltaTime;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastUser != character && lastUser != null && lastUser.SelectedConstruction == item)
|
if (lastUser != character && lastUser != null && lastUser.SelectedConstruction == item)
|
||||||
{
|
{
|
||||||
character.Speak(TextManager.Get("DialogReactorTaken"), null, 0.0f, "reactortaken", 10.0f);
|
character.Speak(TextManager.Get("DialogReactorTaken"), null, 0.0f, "reactortaken", 10.0f);
|
||||||
@@ -506,7 +554,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
AutoTemp = false;
|
AutoTemp = false;
|
||||||
unsentChanges = true;
|
unsentChanges = true;
|
||||||
UpdateAutoTemp(2.0f + degreeOfSuccess * 5.0f, 1.0f);
|
UpdateAutoTemp(MathHelper.Lerp(0.5f, 2.0f, degreeOfSuccess), 1.0f);
|
||||||
}
|
}
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
onOffSwitch.BarScroll = 0.0f;
|
onOffSwitch.BarScroll = 0.0f;
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!pt.IsActive) { continue; }
|
if (!pt.IsActive || !pt.CanTransfer) { continue; }
|
||||||
|
|
||||||
gridLoad += pt.PowerLoad;
|
gridLoad += pt.PowerLoad;
|
||||||
gridPower -= pt.CurrPowerConsumption;
|
gridPower -= pt.CurrPowerConsumption;
|
||||||
@@ -209,9 +209,9 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
Charge -= CurrPowerOutput / 3600.0f;
|
Charge -= CurrPowerOutput / 3600.0f;
|
||||||
}
|
}
|
||||||
item.SendSignal(0, Charge.ToString(), "charge", null);
|
item.SendSignal(0, ((int)Charge).ToString(), "charge", null);
|
||||||
item.SendSignal(0, ((Charge / capacity) * 100).ToString(), "charge_%", null);
|
item.SendSignal(0, ((int)((Charge / capacity) * 100)).ToString(), "charge_%", null);
|
||||||
item.SendSignal(0, ((RechargeSpeed / maxRechargeSpeed) * 100).ToString(), "charge_rate", null);
|
item.SendSignal(0, ((int)((RechargeSpeed / maxRechargeSpeed) * 100)).ToString(), "charge_rate", null);
|
||||||
|
|
||||||
foreach (Pair<Powered, Connection> connected in directlyConnected)
|
foreach (Pair<Powered, Connection> connected in directlyConnected)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -180,7 +180,8 @@ namespace Barotrauma.Items.Components
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//items in a bad condition are more sensitive to overvoltage
|
//items in a bad condition are more sensitive to overvoltage
|
||||||
float maxOverVoltage = MathHelper.Lerp(Math.Min(OverloadVoltage, 1.0f), OverloadVoltage, item.Condition / item.MaxCondition);
|
float maxOverVoltage = MathHelper.Lerp(OverloadVoltage * 0.75f, OverloadVoltage, item.Condition / item.MaxCondition);
|
||||||
|
maxOverVoltage = Math.Max(OverloadVoltage, 1.0f);
|
||||||
|
|
||||||
//if the item can't be fixed, don't allow it to break
|
//if the item can't be fixed, don't allow it to break
|
||||||
if (!item.Repairables.Any() || !CanBeOverloaded) continue;
|
if (!item.Repairables.Any() || !CanBeOverloaded) continue;
|
||||||
@@ -319,7 +320,13 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
|
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
|
||||||
|
|
||||||
float maxPower = this is RelayComponent relayComponent ? relayComponent.MaxPower : float.PositiveInfinity;
|
//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);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (Connection c in PowerConnections)
|
foreach (Connection c in PowerConnections)
|
||||||
{
|
{
|
||||||
@@ -357,6 +364,8 @@ namespace Barotrauma.Items.Components
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float addLoad = 0.0f;
|
||||||
|
float addPower = 0.0f;
|
||||||
if (powered is PowerContainer powerContainer)
|
if (powered is PowerContainer powerContainer)
|
||||||
{
|
{
|
||||||
if (recipient.Name == "power_in")
|
if (recipient.Name == "power_in")
|
||||||
@@ -365,7 +374,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fullPower += Math.Min(powerContainer.CurrPowerOutput, maxPower);
|
addPower = powerContainer.CurrPowerOutput;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -380,10 +389,16 @@ namespace Barotrauma.Items.Components
|
|||||||
//negative power consumption = the construction is a
|
//negative power consumption = the construction is a
|
||||||
//generator/battery or another junction box
|
//generator/battery or another junction box
|
||||||
{
|
{
|
||||||
fullPower -= Math.Max(powered.CurrPowerConsumption, -maxPower);
|
addPower -= powered.CurrPowerConsumption;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
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,8 +12,6 @@ namespace Barotrauma.Items.Components
|
|||||||
public static float SkillIncreaseMultiplier = 0.4f;
|
public static float SkillIncreaseMultiplier = 0.4f;
|
||||||
|
|
||||||
private string header;
|
private string header;
|
||||||
|
|
||||||
private float fixDurationLowSkill, fixDurationHighSkill;
|
|
||||||
|
|
||||||
private float deteriorationTimer;
|
private float deteriorationTimer;
|
||||||
|
|
||||||
@@ -52,17 +50,20 @@ namespace Barotrauma.Items.Components
|
|||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*private float repairProgress;
|
[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 RepairProgress
|
public float FixDurationLowSkill
|
||||||
{
|
{
|
||||||
get { return repairProgress; }
|
get;
|
||||||
set
|
set;
|
||||||
{
|
}
|
||||||
repairProgress = MathHelper.Clamp(value, 0.0f, 1.0f);
|
|
||||||
if (repairProgress >= 1.0f && currentFixer != null) currentFixer.AnimController.Anim = AnimController.Animation.None;
|
[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;
|
||||||
|
}
|
||||||
|
|
||||||
private Character currentFixer;
|
private Character currentFixer;
|
||||||
public Character CurrentFixer
|
public Character CurrentFixer
|
||||||
{
|
{
|
||||||
@@ -83,8 +84,6 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
this.item = item;
|
this.item = item;
|
||||||
header = element.GetAttributeString("name", "");
|
header = element.GetAttributeString("name", "");
|
||||||
fixDurationLowSkill = element.GetAttributeFloat("fixdurationlowskill", 100.0f);
|
|
||||||
fixDurationHighSkill = element.GetAttributeFloat("fixdurationhighskill", 5.0f);
|
|
||||||
InitProjSpecific(element);
|
InitProjSpecific(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,7 +159,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool wasBroken = !item.IsFullCondition;
|
bool wasBroken = !item.IsFullCondition;
|
||||||
float fixDuration = MathHelper.Lerp(fixDurationLowSkill, fixDurationHighSkill, successFactor);
|
float fixDuration = MathHelper.Lerp(FixDurationLowSkill, FixDurationHighSkill, successFactor);
|
||||||
if (fixDuration <= 0.0f)
|
if (fixDuration <= 0.0f)
|
||||||
{
|
{
|
||||||
item.Condition = item.MaxCondition;
|
item.Condition = item.MaxCondition;
|
||||||
@@ -186,26 +185,5 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
character.AnimController.UpdateUseItem(false, item.WorldPosition + new Vector2(0.0f, 100.0f) * ((item.Condition / item.MaxCondition) % 0.1f));
|
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,6 +163,14 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
wires[index] = wire;
|
wires[index] = wire;
|
||||||
recipientsDirty = true;
|
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)
|
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.ResetDynamics();
|
||||||
projectile.body.Enabled = true;
|
projectile.body.Enabled = true;
|
||||||
projectile.SetTransform(ConvertUnits.ToSimUnits(new Vector2(item.WorldRect.X + transformedBarrelPos.X, item.WorldRect.Y - transformedBarrelPos.Y)), -rotation);
|
projectile.SetTransform(ConvertUnits.ToSimUnits(new Vector2(item.WorldRect.X + transformedBarrelPos.X, item.WorldRect.Y - transformedBarrelPos.Y)), -rotation);
|
||||||
projectile.FindHull();
|
projectile.UpdateTransform();
|
||||||
projectile.Submarine = projectile.body.Submarine;
|
projectile.Submarine = projectile.body.Submarine;
|
||||||
|
|
||||||
Projectile projectileComponent = projectile.GetComponent<Projectile>();
|
Projectile projectileComponent = projectile.GetComponent<Projectile>();
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ namespace Barotrauma
|
|||||||
public PhysicsBody body;
|
public PhysicsBody body;
|
||||||
|
|
||||||
public readonly XElement StaticBodyConfig;
|
public readonly XElement StaticBodyConfig;
|
||||||
|
|
||||||
private float lastSentCondition;
|
private float lastSentCondition;
|
||||||
private float sendConditionUpdateTimer;
|
private float sendConditionUpdateTimer;
|
||||||
private bool conditionUpdatePending;
|
private bool conditionUpdatePending;
|
||||||
@@ -211,14 +211,14 @@ namespace Barotrauma
|
|||||||
set { spriteColor = value; }
|
set { spriteColor = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serialize("1.0,1.0,1.0,1.0", false), Editable]
|
[Serialize("1.0,1.0,1.0,1.0", true), Editable]
|
||||||
public Color InventoryIconColor
|
public Color InventoryIconColor
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
protected set;
|
protected set;
|
||||||
}
|
}
|
||||||
|
|
||||||
[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.")]
|
[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.")]
|
||||||
public Color ContainerColor
|
public Color ContainerColor
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
@@ -274,12 +274,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
SetActiveSprite();
|
SetActiveSprite();
|
||||||
|
|
||||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer && lastSentCondition != condition)
|
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer && !MathUtils.NearlyEqual(lastSentCondition, condition))
|
||||||
{
|
{
|
||||||
if (Math.Abs(lastSentCondition - condition) > 1.0f || condition == 0.0f || condition == Prefab.Health)
|
if (Math.Abs(lastSentCondition - condition) > 1.0f || condition == 0.0f || condition == Prefab.Health)
|
||||||
{
|
{
|
||||||
GameMain.NetworkMember.CreateEntityEvent(this, new object[] { NetEntityEvent.Type.Status });
|
conditionUpdatePending = true;
|
||||||
lastSentCondition = condition;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -996,6 +995,21 @@ namespace Barotrauma
|
|||||||
aiTarget.SightRange -= deltaTime * 1000.0f;
|
aiTarget.SightRange -= deltaTime * 1000.0f;
|
||||||
aiTarget.SoundRange -= 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);
|
ApplyStatusEffects(ActionType.Always, deltaTime, null);
|
||||||
|
|
||||||
@@ -1272,7 +1286,11 @@ namespace Barotrauma
|
|||||||
LastSentSignalRecipients.Clear();
|
LastSentSignalRecipients.Clear();
|
||||||
if (connections == null) return;
|
if (connections == null) return;
|
||||||
|
|
||||||
stepsTaken++;
|
public List<T> GetConnectedComponentsRecursive<T>(Connection c) where T : ItemComponent
|
||||||
|
{
|
||||||
|
List<T> connectedComponents = new List<T>();
|
||||||
|
List<Item> alreadySearched = new List<Item>() { this };
|
||||||
|
GetConnectedComponentsRecursive(c, alreadySearched, connectedComponents);
|
||||||
|
|
||||||
if (!connections.TryGetValue(connectionName, out Connection c)) return;
|
if (!connections.TryGetValue(connectionName, out Connection c)) return;
|
||||||
|
|
||||||
|
|||||||
@@ -554,6 +554,39 @@ namespace Barotrauma
|
|||||||
|
|
||||||
AllowedLinks = element.GetAttributeStringArray("allowedlinks", new string[0], convertToLowerInvariant: true).ToList();
|
AllowedLinks = element.GetAttributeStringArray("allowedlinks", new string[0], convertToLowerInvariant: true).ToList();
|
||||||
|
|
||||||
|
if (sprite == null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Item \"" + Name + "\" has no sprite!");
|
||||||
|
#if SERVER
|
||||||
|
sprite = new Sprite("", Vector2.Zero);
|
||||||
|
sprite.SourceRect = new Rectangle(0, 0, 32, 32);
|
||||||
|
#else
|
||||||
|
sprite = new Sprite(TextureLoader.PlaceHolderTexture, null, null)
|
||||||
|
{
|
||||||
|
Origin = TextureLoader.PlaceHolderTexture.Bounds.Size.ToVector2() / 2
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
size = sprite.size;
|
||||||
|
sprite.EntityID = identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!category.HasFlag(MapEntityCategory.Legacy) && string.IsNullOrEmpty(identifier))
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError(
|
||||||
|
"Item prefab \"" + name + "\" has no identifier. All item prefabs have a unique identifier string that's used to differentiate between items during saving and loading.");
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(identifier))
|
||||||
|
{
|
||||||
|
MapEntityPrefab existingPrefab = List.Find(e => e.Identifier == identifier);
|
||||||
|
if (existingPrefab != null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError(
|
||||||
|
"Map entity prefabs \"" + name + "\" and \"" + existingPrefab.Name + "\" have the same identifier!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AllowedLinks = element.GetAttributeStringArray("allowedlinks", new string[0], convertToLowerInvariant: true).ToList();
|
||||||
|
|
||||||
List.Add(this);
|
List.Add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user