(3dc4135ce) v0.9.5.1

This commit is contained in:
Regalis
2019-11-21 18:22:25 +01:00
parent b39922a074
commit 5c95c53118
287 changed files with 12655 additions and 5048 deletions

View File

@@ -219,6 +219,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Source\Sounds\SoundPlayer.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Sounds\VideoSound.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Sounds\VoipSound.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Sprite\ConditionalSprite.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Sprite\DecorativeSprite.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Sprite\DeformableSprite.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Sprite\DeformAnimations\CustomDeformation.cs" />

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ShowAllFiles>true</ShowAllFiles>
</PropertyGroup>

View File

@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.9.4.0")]
[assembly: AssemblyFileVersion("0.9.4.0")]
[assembly: AssemblyVersion("0.9.5.1")]
[assembly: AssemblyFileVersion("0.9.5.1")]

View File

@@ -14,10 +14,27 @@ namespace Barotrauma
Vector2 pos = Character.WorldPosition;
pos.Y = -pos.Y;
if (SelectedAiTarget?.Entity != null)
if (State == AIState.Idle && PreviousState == AIState.Attack)
{
GUI.DrawLine(spriteBatch, pos, new Vector2(SelectedAiTarget.WorldPosition.X, -SelectedAiTarget.WorldPosition.Y), Color.Red * 0.5f, 0, 4);
var target = _selectedAiTarget ?? _lastAiTarget;
if (target != null)
{
var memory = GetTargetMemory(target);
Vector2 targetPos = memory.Location;
targetPos.Y = -targetPos.Y;
GUI.DrawLine(spriteBatch, pos, targetPos, Color.White * 0.5f, 0, 4);
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{target.Entity.ToString()} ({memory.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
}
}
else if (SelectedAiTarget?.Entity != null)
{
Vector2 targetPos = SelectedAiTarget.WorldPosition;
if (State == AIState.Attack)
{
targetPos = attackWorldPos;
}
targetPos.Y = -targetPos.Y;
GUI.DrawLine(spriteBatch, pos, targetPos, Color.Red * 0.5f, 0, 4);
if (wallTarget != null)
{
Vector2 wallTargetPos = wallTarget.Position;
@@ -26,7 +43,8 @@ namespace Barotrauma
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.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{SelectedAiTarget.Entity.ToString()} ({targetValue.FormatZeroDecimal()})", Color.Red, Color.Black);
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{SelectedAiTarget.Entity.ToString()} ({GetTargetMemory(SelectedAiTarget).Priority.FormatZeroDecimal()})", Color.Red, Color.Black);
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 40.0f, $"({targetValue.FormatZeroDecimal()})", Color.Red, Color.Black);
}
/*GUI.Font.DrawString(spriteBatch, targetValue.ToString(), pos - Vector2.UnitY * 80.0f, Color.Red);
@@ -42,6 +60,9 @@ namespace Barotrauma
case AIState.Escape:
stateColor = Color.LightBlue;
break;
case AIState.Flee:
stateColor = Color.White;
break;
case AIState.Eat:
stateColor = Color.Brown;
break;
@@ -59,8 +80,8 @@ namespace Barotrauma
if (LatchOntoAI.WallAttachPos.HasValue)
{
GUI.DrawLine(spriteBatch, pos,
ConvertUnits.ToDisplayUnits(new Vector2(LatchOntoAI.WallAttachPos.Value.X, -LatchOntoAI.WallAttachPos.Value.Y)), Color.Green, 0, 3);
//GUI.DrawLine(spriteBatch, pos,
// ConvertUnits.ToDisplayUnits(new Vector2(LatchOntoAI.WallAttachPos.Value.X, -LatchOntoAI.WallAttachPos.Value.Y)), Color.Green, 0, 3);
}
}
@@ -93,6 +114,17 @@ namespace Barotrauma
}
}
}
else
{
if (steeringManager.AvoidDir.LengthSquared() > 0.0001f)
{
Vector2 hitPos = ConvertUnits.ToDisplayUnits(steeringManager.AvoidRayCastHitPosition);
hitPos.Y = -hitPos.Y;
GUI.DrawLine(spriteBatch, hitPos, hitPos + new Vector2(steeringManager.AvoidDir.X, -steeringManager.AvoidDir.Y) * 100, Color.Red, width: 5);
//GUI.DrawLine(spriteBatch, pos, ConvertUnits.ToDisplayUnits(steeringManager.AvoidLookAheadPos.X, -steeringManager.AvoidLookAheadPos.Y), Color.Orange, width: 4);
}
}
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);
}

View File

@@ -25,7 +25,7 @@ namespace Barotrauma
{
Vector2 pos = Character.WorldPosition;
pos.Y = -pos.Y;
Vector2 textOffset = new Vector2(-40, -120);
Vector2 textOffset = new Vector2(-40, -160);
if (SelectedAiTarget?.Entity != null)
{
@@ -33,26 +33,36 @@ namespace Barotrauma
//GUI.DrawString(spriteBatch, pos + textOffset, $"AI TARGET: {SelectedAiTarget.Entity.ToString()}", Color.White, Color.Black);
}
GUI.DrawString(spriteBatch, pos + textOffset, Character.Name, Color.White, Color.Black);
if (ObjectiveManager != null)
{
var currentOrder = ObjectiveManager.CurrentOrder;
if (currentOrder != null)
{
GUI.DrawString(spriteBatch, pos + textOffset, $"ORDER: {currentOrder.DebugTag} ({currentOrder.GetPriority().FormatZeroDecimal()})", Color.White, Color.Black);
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 20), $"ORDER: {currentOrder.DebugTag} ({currentOrder.GetPriority().FormatZeroDecimal()})", Color.White, Color.Black);
}
else if (ObjectiveManager.WaitTimer > 0)
{
GUI.DrawString(spriteBatch, pos + textOffset, $"Waiting... {ObjectiveManager.WaitTimer.FormatZeroDecimal()}", Color.White, Color.Black);
GUI.DrawString(spriteBatch, pos + new Vector2(0, 20), $"Waiting... {ObjectiveManager.WaitTimer.FormatZeroDecimal()}", Color.White, Color.Black);
}
var currentObjective = ObjectiveManager.CurrentObjective;
if (currentObjective != null)
{
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 20), $"OBJECTIVE: {currentObjective.DebugTag} ({currentObjective.GetPriority().FormatZeroDecimal()})", Color.White, Color.Black);
if (currentOrder == null)
{
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 20), $"MAIN OBJECTIVE: {currentObjective.DebugTag} ({currentObjective.GetPriority().FormatZeroDecimal()})", Color.White, Color.Black);
}
var subObjective = currentObjective.SubObjectives.FirstOrDefault();
if (subObjective != null)
{
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 40), $"SUBOBJECTIVE: {subObjective.DebugTag} ({subObjective.GetPriority().FormatZeroDecimal()})", Color.White, Color.Black);
}
var activeObjective = ObjectiveManager.GetActiveObjective();
if (activeObjective != null)
{
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 60), $"ACTIVE OBJECTIVE: {activeObjective.DebugTag} ({activeObjective.GetPriority().FormatZeroDecimal()})", Color.White, Color.Black);
}
}
}
@@ -81,7 +91,7 @@ namespace Barotrauma
new Vector2(path.CurrentNode.DrawPosition.X, -path.CurrentNode.DrawPosition.Y),
Color.BlueViolet, 0, 3);
GUI.DrawString(spriteBatch, pos + textOffset - new Vector2(0, 20), "Path cost: " + path.Cost.FormatZeroDecimal(), Color.White, Color.Black * 0.5f);
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 80), "Path cost: " + path.Cost.FormatZeroDecimal(), Color.White, Color.Black * 0.5f);
}
}
}

View File

@@ -24,7 +24,7 @@ namespace Barotrauma
partial void UpdateNetPlayerPositionProjSpecific(float deltaTime, float lowestSubPos)
{
if (character != GameMain.Client.Character || !character.AllowInput)
if (character != GameMain.Client.Character || !character.CanMove)
{
//remove states without a timestamp (there may still be ID-based states
//in the list when the controlled character switches to timestamp-based interpolation)
@@ -92,10 +92,10 @@ namespace Barotrauma
Collider.AngularVelocity = newAngularVelocity;
float distSqrd = Vector2.DistanceSquared(newPosition, Collider.SimPosition);
float errorTolerance = character.AllowInput ? 0.01f : 0.2f;
float errorTolerance = character.CanMove ? 0.01f : 0.2f;
if (distSqrd > errorTolerance)
{
if (distSqrd > 10.0f || !character.AllowInput)
if (distSqrd > 10.0f || !character.CanMove)
{
Collider.TargetRotation = newRotation;
SetPosition(newPosition, lerp: distSqrd < 5.0f, ignorePlatforms: false);
@@ -108,9 +108,9 @@ namespace Barotrauma
}
}
//unconscious/dead characters can't correct their position using AnimController movement
//immobilized characters can't correct their position using AnimController movement
// -> we need to correct it manually
if (!character.AllowInput)
if (!character.CanMove)
{
float mainLimbDistSqrd = Vector2.DistanceSquared(MainLimb.PullJointWorldAnchorA, Collider.SimPosition);
float mainLimbErrorTolerance = 0.1f;

View File

@@ -343,7 +343,7 @@ namespace Barotrauma
partial void OnAttackedProjSpecific(Character attacker, AttackResult attackResult)
{
if (attackResult.Damage <= 1.0f) { return; }
if (attackResult.Damage <= 1.0f || IsDead) { return; }
if (soundTimer < soundInterval * 0.5f)
{
PlaySound(CharacterSound.SoundType.Damage);
@@ -524,6 +524,8 @@ namespace Barotrauma
partial void UpdateProjSpecific(float deltaTime, Camera cam)
{
if (!enabled) { return; }
if (!IsDead && !IsUnconscious)
{
if (soundTimer > 0)

View File

@@ -50,7 +50,7 @@ namespace Barotrauma
Job.Name, textColor: Job.Prefab.UIColor, font: font);
}
if (personalityTrait != null && TextManager.Language == "English")
if (personalityTrait != null)
{
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), headerTextArea.RectTransform),
TextManager.AddPunctuation(':', TextManager.Get("PersonalityTrait"), TextManager.Get("personalitytrait." + personalityTrait.Name.Replace(" ", ""))), font: font);
@@ -125,7 +125,7 @@ namespace Barotrauma
}
}
partial void LoadAttachmentSprites()
partial void LoadAttachmentSprites(bool omitJob)
{
if (attachmentSprites == null)
{
@@ -139,7 +139,25 @@ namespace Barotrauma
BeardElement?.Elements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.Beard)));
MoustacheElement?.Elements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.Moustache)));
HairElement?.Elements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.Hair)));
Job?.Prefab.ClothingElement?.Elements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.JobIndicator)));
if (omitJob)
{
JobPrefab.NoJobElement?.Element("PortraitClothing")?.Elements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.JobIndicator)));
}
else
{
Job?.Prefab.ClothingElement?.Elements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.JobIndicator)));
}
}
// Doesn't work if the head's source rect does not start at 0,0.
public static Point CalculateOffset(Sprite sprite, Point offset) => sprite.SourceRect.Size * offset;
public void CalculateHeadPosition(Sprite sprite)
{
if (sprite == null) { return; }
if (Head.SheetIndex == null) { return; }
Point location = CalculateOffset(sprite, Head.SheetIndex.Value.ToPoint());
sprite.SourceRect = new Rectangle(location, sprite.SourceRect.Size);
}
public void DrawPortrait(SpriteBatch spriteBatch, Vector2 screenPos, float targetWidth)
@@ -155,6 +173,10 @@ namespace Barotrauma
// Scale down the head sprite 10%
float scale = targetWidth * 0.9f / Portrait.size.X;
Vector2 offset = Portrait.size * backgroundScale / 4;
if (Head.SheetIndex.HasValue)
{
Portrait.SourceRect = new Rectangle(CalculateOffset(Portrait, Head.SheetIndex.Value.ToPoint()), Portrait.SourceRect.Size);
}
Portrait.Draw(spriteBatch, screenPos + offset, scale: scale, spriteEffect: SpriteEffects.FlipHorizontally);
if (AttachmentSprites != null)
{
@@ -170,16 +192,21 @@ namespace Barotrauma
public void DrawIcon(SpriteBatch spriteBatch, Vector2 screenPos, Vector2 targetAreaSize)
{
if (HeadSprite != null)
var headSprite = HeadSprite;
if (headSprite != null)
{
float scale = Math.Min(targetAreaSize.X / HeadSprite.size.X, targetAreaSize.Y / HeadSprite.size.Y);
HeadSprite.Draw(spriteBatch, screenPos, scale: scale);
float scale = Math.Min(targetAreaSize.X / headSprite.size.X, targetAreaSize.Y / headSprite.size.Y);
if (Head.SheetIndex.HasValue)
{
headSprite.SourceRect = new Rectangle(CalculateOffset(headSprite, Head.SheetIndex.Value.ToPoint()), headSprite.SourceRect.Size);
}
headSprite.Draw(spriteBatch, screenPos, scale: scale);
if (AttachmentSprites != null)
{
float depthStep = 0.000001f;
foreach (var attachment in AttachmentSprites)
{
DrawAttachmentSprite(spriteBatch, attachment, HeadSprite, screenPos, scale, depthStep);
DrawAttachmentSprite(spriteBatch, attachment, headSprite, screenPos, scale, depthStep);
depthStep += depthStep;
}
}
@@ -188,13 +215,15 @@ namespace Barotrauma
private void DrawAttachmentSprite(SpriteBatch spriteBatch, WearableSprite attachment, Sprite head, Vector2 drawPos, float scale, float depthStep, SpriteEffects spriteEffects = SpriteEffects.None)
{
var list = AttachmentSprites.ToList();
if (attachment.InheritSourceRect)
{
if (attachment.SheetIndex.HasValue)
{
Point location = (head.SourceRect.Location + head.SourceRect.Size) * attachment.SheetIndex.Value;
attachment.Sprite.SourceRect = new Rectangle(location, head.SourceRect.Size);
attachment.Sprite.SourceRect = new Rectangle(CalculateOffset(head, attachment.SheetIndex.Value), head.SourceRect.Size);
}
else if (Head.SheetIndex.HasValue)
{
attachment.Sprite.SourceRect = new Rectangle(CalculateOffset(head, Head.SheetIndex.Value.ToPoint()), head.SourceRect.Size);
}
else
{
@@ -219,7 +248,6 @@ namespace Barotrauma
attachment.Sprite.Draw(spriteBatch, drawPos, Color.White, origin, rotate: 0, scale: scale, depth: depth, spriteEffect: spriteEffects);
}
public static CharacterInfo ClientRead(string speciesName, IReadMessage inc)
{
ushort infoID = inc.ReadUInt16();
@@ -234,6 +262,8 @@ namespace Barotrauma
string ragdollFile = inc.ReadString();
string jobIdentifier = inc.ReadString();
int variant = inc.ReadByte();
JobPrefab jobPrefab = null;
Dictionary<string, float> skillLevels = new Dictionary<string, float>();
if (!string.IsNullOrEmpty(jobIdentifier))
@@ -249,7 +279,7 @@ namespace Barotrauma
}
// TODO: animations
CharacterInfo ch = new CharacterInfo(speciesName, newName, jobPrefab, ragdollFile)
CharacterInfo ch = new CharacterInfo(speciesName, newName, jobPrefab, ragdollFile, variant)
{
ID = infoID,
};

View File

@@ -249,7 +249,7 @@ namespace Barotrauma
msg.ReadPadBits();
int index = 0;
if (GameMain.Client.Character == this && AllowInput)
if (GameMain.Client.Character == this && CanMove)
{
var posInfo = new CharacterStateInfo(
pos, rotation,
@@ -309,7 +309,7 @@ namespace Barotrauma
LastNetworkUpdateID = controlled.LastNetworkUpdateID;
}
Controlled = this;
if (!IsDead) { Controlled = this; }
IsRemotePlayer = false;
GameMain.Client.HasSpawned = true;
GameMain.Client.Character = this;
@@ -342,7 +342,7 @@ namespace Barotrauma
}
}
public static Character ReadSpawnData(IReadMessage inc, bool spawn = true)
public static Character ReadSpawnData(IReadMessage inc)
{
DebugConsole.Log("Reading character spawn data");
@@ -362,10 +362,9 @@ namespace Barotrauma
Character character = null;
if (noInfo)
{
if (!spawn) return null;
character = Create(speciesName, position, seed, null, true);
character.ID = id;
character.ReadStatus(inc);
}
else
{
@@ -375,15 +374,14 @@ namespace Barotrauma
bool hasAi = inc.ReadBoolean();
string infoSpeciesName = inc.ReadString();
if (!spawn) return null;
CharacterInfo info = CharacterInfo.ClientRead(infoSpeciesName, inc);
character = Create(infoSpeciesName, position, seed, info, GameMain.Client.ID != ownerId, hasAi);
character = Create(speciesName, position, seed, info, GameMain.Client.ID != ownerId, hasAi);
character.ID = id;
character.TeamID = (TeamType)teamID;
character.ReadStatus(inc);
if (character.IsHuman && character.TeamID != TeamType.FriendlyNPC)
if (character.IsHuman && character.TeamID != TeamType.FriendlyNPC && !character.IsDead)
{
CharacterInfo duplicateCharacterInfo = GameMain.GameSession.CrewManager.GetCharacterInfos().FirstOrDefault(c => c.ID == info.ID);
GameMain.GameSession.CrewManager.RemoveCharacterInfo(duplicateCharacterInfo);
@@ -394,7 +392,7 @@ namespace Barotrauma
{
GameMain.Client.HasSpawned = true;
GameMain.Client.Character = character;
Controlled = character;
if (!character.IsDead) { Controlled = character; }
GameMain.LightManager.LosEnabled = true;

View File

@@ -13,7 +13,7 @@ namespace Barotrauma
{
private static bool toggledThisFrame;
private static Sprite damageOverlay;
public static Sprite DamageOverlay;
private static string[] strengthTexts;
@@ -153,12 +153,7 @@ namespace Barotrauma
get { return healthBarPulsateTimer; }
set { healthBarPulsateTimer = MathHelper.Clamp(value, 0.0f, 10.0f); }
}
static CharacterHealth()
{
damageOverlay = new Sprite("Content/UI/damageOverlay.png", Vector2.Zero);
}
partial void InitProjSpecific(XElement element, Character character)
{
DisplayedVitality = MaxVitality;
@@ -837,8 +832,8 @@ namespace Barotrauma
if (damageOverlayAlpha > 0.0f)
{
damageOverlay.Draw(spriteBatch, Vector2.Zero, Color.White * damageOverlayAlpha, Vector2.Zero, 0.0f,
new Vector2(GameMain.GraphicsWidth / damageOverlay.size.X, GameMain.GraphicsHeight / damageOverlay.size.Y));
DamageOverlay?.Draw(spriteBatch, Vector2.Zero, Color.White * damageOverlayAlpha, Vector2.Zero, 0.0f,
new Vector2(GameMain.GraphicsWidth / DamageOverlay.size.X, GameMain.GraphicsHeight / DamageOverlay.size.Y));
}
if (Character.Inventory != null)
@@ -997,30 +992,7 @@ namespace Barotrauma
//key = item identifier
//float = suitability
Dictionary<string, float> treatmentSuitability = new Dictionary<string, float>();
float minSuitability = -10, maxSuitability = 10;
foreach (Affliction affliction in afflictions)
{
foreach (KeyValuePair<string, float> treatment in affliction.Prefab.TreatmentSuitability)
{
if (!treatmentSuitability.ContainsKey(treatment.Key))
{
treatmentSuitability[treatment.Key] = treatment.Value * affliction.Strength;
}
else
{
treatmentSuitability[treatment.Key] += treatment.Value * affliction.Strength;
}
minSuitability = Math.Min(treatmentSuitability[treatment.Key], minSuitability);
maxSuitability = Math.Max(treatmentSuitability[treatment.Key], maxSuitability);
}
}
//normalize the suitabilities to a range of 0 to 1
foreach (string treatment in treatmentSuitability.Keys.ToList())
{
treatmentSuitability[treatment] = (treatmentSuitability[treatment] - minSuitability) / (maxSuitability - minSuitability);
//lerp towards a random value if the medical skill is low
treatmentSuitability[treatment] = MathHelper.Lerp(treatmentSuitability[treatment], Rand.Range(0.0f, 1.0f), randomVariance);
}
GetSuitableTreatments(treatmentSuitability, normalize: true, randomization: randomVariance);
foreach (Affliction affliction in afflictions)
{

View File

@@ -2,7 +2,7 @@
{
partial class DamageModifier
{
[Serialize("", false)]
[Serialize("", false), Editable]
public string DamageSound
{
get;

View File

@@ -119,7 +119,24 @@ namespace Barotrauma
public List<SpriteDeformation> Deformations { get; private set; } = new List<SpriteDeformation>();
public Sprite Sprite { get; protected set; }
public DeformableSprite DeformSprite { get; protected set; }
protected DeformableSprite _deformSprite;
public DeformableSprite DeformSprite
{
get
{
var conditionalSprite = ConditionalSprites.FirstOrDefault(c => c.IsActive && c.DeformableSprite != null);
if (conditionalSprite != null)
{
return conditionalSprite.DeformableSprite;
}
else
{
return _deformSprite;
}
}
}
public List<DecorativeSprite> DecorativeSprites { get; private set; } = new List<DecorativeSprite>();
@@ -127,15 +144,14 @@ namespace Barotrauma
{
get
{
// TODO: should we optimize this? No need to check all the conditionals each time the property is accessed.
var conditionalSprite = ConditionalSprites.FirstOrDefault(c => c.IsActive);
var conditionalSprite = ConditionalSprites.FirstOrDefault(c => c.IsActive && c.ActiveSprite != null);
if (conditionalSprite != null)
{
return conditionalSprite;
return conditionalSprite.ActiveSprite;
}
else
{
return DeformSprite != null ? DeformSprite.Sprite : Sprite;
return _deformSprite != null ? _deformSprite.Sprite : Sprite;
}
}
}
@@ -215,40 +231,53 @@ namespace Barotrauma
DamagedSprite = new Sprite(subElement, file: GetSpritePath(subElement, Params.damagedSpriteParams));
break;
case "conditionalsprite":
ConditionalSprites.Add(new ConditionalSprite(subElement, character, file: GetSpritePath(subElement, null)));
var conditionalSprite = new ConditionalSprite(subElement, character, file: GetSpritePath(subElement, null));
ConditionalSprites.Add(conditionalSprite);
if (conditionalSprite.DeformableSprite != null)
{
CreateDeformations(subElement.GetChildElement("deformablesprite"));
}
break;
case "deformablesprite":
DeformSprite = new DeformableSprite(subElement, filePath: GetSpritePath(subElement, Params.deformSpriteParams));
foreach (XElement animationElement in subElement.Elements())
{
int sync = animationElement.GetAttributeInt("sync", -1);
SpriteDeformation deformation = null;
if (sync > -1)
{
// if the element is marked with the sync attribute, use a deformation of the same type with the same sync value, if there is one already.
string typeName = animationElement.GetAttributeString("type", "").ToLowerInvariant();
deformation = ragdoll.Limbs
.Where(l => l != null)
.SelectMany(l => l.Deformations)
.Where(d => d.TypeName == typeName && d.Sync == sync)
.FirstOrDefault();
}
if (deformation == null)
{
deformation = SpriteDeformation.Load(animationElement, character.SpeciesName);
if (deformation != null)
{
ragdoll.SpriteDeformations.Add(deformation);
}
}
if (deformation != null) Deformations.Add(deformation);
}
_deformSprite = new DeformableSprite(subElement, filePath: GetSpritePath(subElement, Params.deformSpriteParams));
CreateDeformations(subElement);
break;
case "lightsource":
LightSource = new LightSource(subElement);
InitialLightSourceColor = LightSource.Color;
break;
}
void CreateDeformations(XElement e)
{
foreach (XElement animationElement in e.GetChildElements("spritedeformation"))
{
int sync = animationElement.GetAttributeInt("sync", -1);
SpriteDeformation deformation = null;
if (sync > -1)
{
// if the element is marked with the sync attribute, use a deformation of the same type with the same sync value, if there is one already.
string typeName = animationElement.GetAttributeString("type", "").ToLowerInvariant();
deformation = ragdoll.Limbs
.Where(l => l != null)
.SelectMany(l => l.Deformations)
.Where(d => d.TypeName == typeName && d.Sync == sync)
.FirstOrDefault();
}
if (deformation == null)
{
deformation = SpriteDeformation.Load(animationElement, character.SpeciesName);
if (deformation != null)
{
ragdoll.SpriteDeformations.Add(deformation);
}
}
if (deformation != null)
{
Deformations.Add(deformation);
}
}
}
}
}
@@ -260,11 +289,11 @@ namespace Barotrauma
var source = Sprite.SourceElement;
Sprite = new Sprite(source, file: GetSpritePath(source, Params.normalSpriteParams));
}
if (DeformSprite != null)
if (_deformSprite != null)
{
DeformSprite.Remove();
var source = DeformSprite.Sprite.SourceElement;
DeformSprite = new DeformableSprite(source, filePath: GetSpritePath(source, Params.deformSpriteParams));
_deformSprite.Remove();
var source = _deformSprite.Sprite.SourceElement;
_deformSprite = new DeformableSprite(source, filePath: GetSpritePath(source, Params.deformSpriteParams));
}
if (DamagedSprite != null)
{
@@ -275,9 +304,8 @@ namespace Barotrauma
for (int i = 0; i < ConditionalSprites.Count; i++)
{
var conditionalSprite = ConditionalSprites[i];
var source = conditionalSprite.ActiveSprite.SourceElement;
conditionalSprite.Remove();
var source = conditionalSprite.SourceElement;
// TODO: lazy load?
ConditionalSprites[i] = new ConditionalSprite(source, character, file: GetSpritePath(source, null));
}
for (int i = 0; i < DecorativeSprites.Count; i++)
@@ -289,6 +317,12 @@ namespace Barotrauma
}
}
private void CalculateHeadPosition(Sprite sprite)
{
if (type != LimbType.Head) { return; }
character.Info?.CalculateHeadPosition(sprite);
}
private string GetSpritePath(XElement element, SpriteParams spriteParams)
{
string texturePath = element.GetAttributeString("texture", null);
@@ -330,7 +364,7 @@ namespace Barotrauma
bool isFlipped = dir == Direction.Left;
Sprite?.LoadParams(Params.normalSpriteParams, isFlipped);
DamagedSprite?.LoadParams(Params.damagedSpriteParams, isFlipped);
DeformSprite?.Sprite.LoadParams(Params.deformSpriteParams, isFlipped);
_deformSprite?.Sprite.LoadParams(Params.deformSpriteParams, isFlipped);
for (int i = 0; i < DecorativeSprites.Count; i++)
{
DecorativeSprites[i].Sprite?.LoadParams(Params.decorativeSpriteParams[i], isFlipped);
@@ -461,24 +495,31 @@ namespace Barotrauma
enableHuskSprite && HuskSprite != null && HuskSprite.HideLimb ||
OtherWearables.Any(w => w.HideLimb) ||
wearingItems.Any(w => w != null && w.HideLimb);
var activeSprite = ActiveSprite;
if (type == LimbType.Head)
{
CalculateHeadPosition(activeSprite);
}
// TODO: there's now two calls to this, because body.Draw() method calls this too -> is this an issue?
body.UpdateDrawPosition();
if (!hideLimb)
{
var activeSprite = ActiveSprite;
if (DeformSprite != null && activeSprite == DeformSprite.Sprite)
var deformSprite = DeformSprite;
if (deformSprite != null)
{
if (Deformations != null && Deformations.Any())
{
var deformation = SpriteDeformation.GetDeformation(Deformations, DeformSprite.Size);
DeformSprite.Deform(deformation);
var deformation = SpriteDeformation.GetDeformation(Deformations, deformSprite.Size);
deformSprite.Deform(deformation);
}
else
{
DeformSprite.Reset();
deformSprite.Reset();
}
body.Draw(DeformSprite, cam, Vector2.One * Scale * TextureScale, color, Params.MirrorHorizontally);
body.Draw(deformSprite, cam, Vector2.One * Scale * TextureScale, color, Params.MirrorHorizontally);
}
else
{
@@ -489,15 +530,16 @@ namespace Barotrauma
if (LightSource != null)
{
LightSource.Position = body.DrawPosition;
if (LightSource.ParentSub != null) { LightSource.Position -= LightSource.ParentSub.DrawPosition; }
LightSource.LightSpriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipVertically;
}
if (damageOverlayStrength > 0.0f && DamagedSprite != null && !hideLimb)
{
DamagedSprite.Draw(spriteBatch,
new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
color * Math.Min(damageOverlayStrength, 1.0f), ActiveSprite.Origin,
color * Math.Min(damageOverlayStrength, 1.0f), activeSprite.Origin,
-body.DrawRotation,
Scale, spriteEffect, ActiveSprite.Depth - 0.0000015f);
Scale, spriteEffect, activeSprite.Depth - 0.0000015f);
}
foreach (var decorativeSprite in DecorativeSprites)
{
@@ -636,48 +678,58 @@ namespace Barotrauma
{
foreach (var modifier in damageModifiers)
{
float rotation = -body.TransformedRotation + GetArmorSectorRotationOffset(modifier.ArmorSectorInRadians) * Dir;
Vector2 forward = VectorExtensions.Forward(rotation);
//Vector2 up = VectorExtensions.Backward(-body.TransformedRotation + Params.GetSpriteOrientation() * Dir);
//int width = 4;
//if (!isScreenSpace)
//{
// width = (int)Math.Round(width / cam.Zoom);
//}
//GUI.DrawLine(spriteBatch, startPos, startPos + Vector2.Normalize(up) * size, Color.Red, width: width);
Color color = modifier.DamageMultiplier > 1 ? Color.Red : Color.GreenYellow;
float size = ConvertUnits.ToDisplayUnits(body.GetSize().Length() / 2);
if (isScreenSpace)
{
size *= cam.Zoom;
}
Color color = modifier.DamageMultiplier > 1 ? Color.Red : Color.GreenYellow;
int width = 4;
if (!isScreenSpace)
{
width = (int)Math.Round(width / cam.Zoom);
}
GUI.DrawLine(spriteBatch, startPos, startPos + Vector2.Normalize(forward) * size, color, width: width);
int thickness = 2;
if (!isScreenSpace)
{
thickness = (int)Math.Round(thickness / cam.Zoom);
}
ShapeExtensions.DrawSector(spriteBatch, startPos, size, GetArmorSectorSize(modifier.ArmorSectorInRadians) * Dir, 40, color, rotation + MathHelper.Pi, thickness);
float bodyRotation = -body.Rotation;
float constantOffset = -MathHelper.PiOver2;
Vector2 armorSector = modifier.ArmorSectorInRadians;
float armorSectorSize = Math.Abs(armorSector.X - armorSector.Y);
float radians = armorSectorSize * Dir;
float armorSectorOffset = armorSector.X * Dir;
float finalOffset = bodyRotation + constantOffset + armorSectorOffset;
ShapeExtensions.DrawSector(spriteBatch, startPos, size, radians, 40, color, finalOffset, thickness);
}
}
private void DrawWearable(WearableSprite wearable, float depthStep, SpriteBatch spriteBatch, Color color, SpriteEffects spriteEffect)
{
var sprite = ActiveSprite;
if (wearable.InheritSourceRect)
{
if (wearable.SheetIndex.HasValue)
{
Point location = (ActiveSprite.SourceRect.Location + ActiveSprite.SourceRect.Size) * wearable.SheetIndex.Value;
wearable.Sprite.SourceRect = new Rectangle(location, ActiveSprite.SourceRect.Size);
wearable.Sprite.SourceRect = new Rectangle(CharacterInfo.CalculateOffset(sprite, wearable.SheetIndex.Value), sprite.SourceRect.Size);
}
else if (type == LimbType.Head && character.Info != null && character.Info.Head.SheetIndex.HasValue)
{
wearable.Sprite.SourceRect = new Rectangle(CharacterInfo.CalculateOffset(sprite, character.Info.Head.SheetIndex.Value.ToPoint()), sprite.SourceRect.Size);
}
else
{
wearable.Sprite.SourceRect = ActiveSprite.SourceRect;
wearable.Sprite.SourceRect = sprite.SourceRect;
}
}
Vector2 origin = wearable.Sprite.Origin;
if (wearable.InheritOrigin)
{
origin = ActiveSprite.Origin;
origin = sprite.Origin;
wearable.Sprite.Origin = origin;
}
else
@@ -694,7 +746,7 @@ namespace Barotrauma
if (wearable.InheritLimbDepth)
{
depth = ActiveSprite.Depth - depthStep;
depth = sprite.Depth - depthStep;
Limb depthLimb = (wearable.DepthLimb == LimbType.None) ? this : character.AnimController.GetLimb(wearable.DepthLimb);
if (depthLimb != null)
{
@@ -728,11 +780,11 @@ namespace Barotrauma
XElement element;
if (random)
{
element = info.FilterByTypeAndHeadID(character.Info.FilterElementsByGenderAndRace(character.Info.Wearables), type)?.FirstOrDefault();
element = info.FilterByTypeAndHeadID(character.Info.FilterElementsByGenderAndRace(character.Info.Wearables), type)?.GetRandom(Rand.RandSync.ClientOnly);
}
else
{
element = info.FilterByTypeAndHeadID(character.Info.FilterElementsByGenderAndRace(character.Info.Wearables), type)?.GetRandom(Rand.RandSync.ClientOnly);
element = info.FilterByTypeAndHeadID(character.Info.FilterElementsByGenderAndRace(character.Info.Wearables), type)?.FirstOrDefault();
}
if (element != null)
{
@@ -749,8 +801,8 @@ namespace Barotrauma
DamagedSprite?.Remove();
DamagedSprite = null;
DeformSprite?.Sprite?.Remove();
DeformSprite = null;
_deformSprite?.Sprite?.Remove();
_deformSprite = null;
DecorativeSprites.ForEach(s => s.Remove());
ConditionalSprites.Clear();

View File

@@ -10,6 +10,7 @@ using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Globalization;
using Barotrauma.Extensions;
namespace Barotrauma
{
@@ -56,6 +57,7 @@ namespace Barotrauma
private static GUIFrame frame;
private static GUIListBox listBox;
private static GUITextBox textBox;
private const int maxLength = 1000;
public static GUITextBox TextBox => textBox;
@@ -92,6 +94,7 @@ namespace Barotrauma
{
IsFixedSize = false
});
textBox.MaxTextLength = maxLength;
textBox.OnKeyHit += (sender, key) =>
{
if (key != Keys.Tab)
@@ -109,7 +112,7 @@ namespace Barotrauma
}
}
public static void Update(GameMain game, float deltaTime)
public static void Update(float deltaTime)
{
lock (queuedMessages)
{
@@ -162,6 +165,16 @@ namespace Barotrauma
textBox.Text = AutoComplete(textBox.Text, increment: string.IsNullOrEmpty(currentAutoCompletedCommand) ? 0 : 1 );
}
if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))
{
if ((PlayerInput.KeyDown(Keys.C) || PlayerInput.KeyDown(Keys.D) || PlayerInput.KeyDown(Keys.Z)) && activeQuestionCallback != null)
{
activeQuestionCallback = null;
activeQuestionText = null;
NewMessage(PlayerInput.KeyDown(Keys.C) ? "^C" : PlayerInput.KeyDown(Keys.D) ? "^D" : "^Z", Color.White, true);
}
}
if (PlayerInput.KeyHit(Keys.Enter))
{
ExecuteCommand(textBox.Text);
@@ -185,41 +198,6 @@ namespace Barotrauma
}
}
public static void Draw(SpriteBatch spriteBatch)
{
if (!isOpen) return;
frame.DrawManually(spriteBatch);
}
private static bool IsCommandPermitted(string command, GameClient client)
{
switch (command)
{
case "kick":
return client.HasPermission(ClientPermissions.Kick);
case "ban":
case "banip":
case "banendpoint":
return client.HasPermission(ClientPermissions.Ban);
case "unban":
case "unbanip":
return client.HasPermission(ClientPermissions.Unban);
case "netstats":
case "help":
case "dumpids":
case "admin":
case "entitylist":
case "togglehud":
case "toggleupperhud":
case "togglecharacternames":
case "fpscounter":
return true;
default:
return client.HasConsoleCommandPermission(command);
}
}
public static void DequeueMessages()
{
while (queuedMessages.Count > 0)
@@ -294,7 +272,7 @@ namespace Barotrauma
};
textContainer.RectTransform.NonScaledSize = new Point(textContainer.RectTransform.NonScaledSize.X, textBlock.RectTransform.NonScaledSize.Y + 5);
textBlock.SetTextPos();
var nameBlock = new GUITextBlock(new RectTransform(new Point(150, textContainer.Rect.Height), textContainer.RectTransform),
new GUITextBlock(new RectTransform(new Point(150, textContainer.Rect.Height), textContainer.RectTransform),
command.names[0], textAlignment: Alignment.TopLeft);
listBox.UpdateScrollBarSize();
@@ -509,14 +487,22 @@ namespace Barotrauma
AssignOnExecute("los", (string[] args) =>
{
GameMain.LightManager.LosEnabled = !GameMain.LightManager.LosEnabled;
if (args.None() || !bool.TryParse(args[0], out bool state))
{
state = !GameMain.LightManager.LosEnabled;
}
GameMain.LightManager.LosEnabled = state;
NewMessage("Line of sight effect " + (GameMain.LightManager.LosEnabled ? "enabled" : "disabled"), Color.White);
});
AssignRelayToServer("los", false);
AssignOnExecute("lighting|lights", (string[] args) =>
{
GameMain.LightManager.LightingEnabled = !GameMain.LightManager.LightingEnabled;
if (args.None() || !bool.TryParse(args[0], out bool state))
{
state = !GameMain.LightManager.LightingEnabled;
}
GameMain.LightManager.LightingEnabled = state;
NewMessage("Lighting " + (GameMain.LightManager.LightingEnabled ? "enabled" : "disabled"), Color.White);
});
AssignRelayToServer("lighting|lights", false);
@@ -635,10 +621,61 @@ namespace Barotrauma
}
}));
commands.Add(new Command("resetentitiesbyidentifier", "resetentitiesbyidentifier [tag/identifier]: Reset items and structures with the given tag/identifier to prefabs. Only applicable in the subeditor.", args =>
{
if (args.Length == 0) { return; }
if (Screen.Selected == GameMain.SubEditorScreen)
{
bool entityFound = false;
foreach (MapEntity entity in MapEntity.mapEntityList)
{
if (entity is Item item)
{
if (item.prefab.Identifier != args[0] && !item.Tags.Contains(args[0])) { continue; }
item.Reset();
if (MapEntity.SelectedList.Contains(item)) { item.CreateEditingHUD(); }
entityFound = true;
}
else if (entity is Structure structure)
{
if (structure.prefab.Identifier != args[0] && !structure.Tags.Contains(args[0])) { continue; }
structure.Reset();
if (MapEntity.SelectedList.Contains(structure)) { structure.CreateEditingHUD(); }
entityFound = true;
}
else
{
continue;
}
NewMessage($"Reset {entity.Name}.");
}
if (!entityFound)
{
if (MapEntity.SelectedList.Count == 0)
{
NewMessage("No entities selected.");
return;
}
}
}
}, () =>
{
return new string[][]
{
MapEntityPrefab.List.Select(me => me.Identifier).ToArray()
};
}));
commands.Add(new Command("resetselected", "Reset selected items and structures to prefabs. Only applicable in the subeditor.", args =>
{
if (Screen.Selected == GameMain.SubEditorScreen)
{
if (MapEntity.SelectedList.Count == 0)
{
NewMessage("No entities selected.");
return;
}
foreach (MapEntity entity in MapEntity.SelectedList)
{
if (entity is Item item)
@@ -649,6 +686,11 @@ namespace Barotrauma
{
structure.Reset();
}
else
{
continue;
}
NewMessage($"Reset {entity.Name}.");
}
foreach (MapEntity entity in MapEntity.SelectedList)
{
@@ -787,7 +829,11 @@ namespace Barotrauma
AssignOnExecute("debugdraw", (string[] args) =>
{
GameMain.DebugDraw = !GameMain.DebugDraw;
if (args.None() || !bool.TryParse(args[0], out bool state))
{
state = !GameMain.DebugDraw;
}
GameMain.DebugDraw = state;
NewMessage("Debug draw mode " + (GameMain.DebugDraw ? "enabled" : "disabled"), Color.White);
});
AssignRelayToServer("debugdraw", false);
@@ -1012,22 +1058,38 @@ namespace Barotrauma
commands.Add(new Command("checkmissingloca", "", (string[] args) =>
{
foreach (MapEntityPrefab me in MapEntityPrefab.List)
//key = text tag, value = list of languages the tag is missing from
Dictionary<string, List<string>> missingTags = new Dictionary<string, List<string>>();
Dictionary<string, HashSet<string>> tags = new Dictionary<string, HashSet<string>>();
foreach (string language in TextManager.AvailableLanguages)
{
string name = TextManager.Get("entityname." + me.Identifier, returnNull: true);
if (!string.IsNullOrEmpty(name)) { continue; }
TextManager.Language = language;
tags.Add(language, new HashSet<string>(TextManager.GetAllTagTextPairs().Select(t => t.Key)));
}
if (me is ItemPrefab itemPrefab)
foreach (string englishTag in tags["English"])
{
if (englishTag == "entitydescription.reinforceddoor")
{
string nameIdentifier = itemPrefab.ConfigElement?.GetAttributeString("nameidentifier", "");
if (nameIdentifier != null)
int asdfsdf = 1;
}
foreach (string language in TextManager.AvailableLanguages)
{
if (language == "English") { continue; }
if (!tags[language].Contains(englishTag))
{
name = TextManager.Get("entityname." + nameIdentifier, returnNull: true);
if (!string.IsNullOrEmpty(name)) { continue; }
if (!missingTags.ContainsKey(englishTag))
{
missingTags[englishTag] = new List<string>();
}
missingTags[englishTag].Add(language);
}
}
NewMessage("Entity name not translated (" + me.Name + ", " + me.Identifier + ")!", me is ItemPrefab ? Color.Red : Color.Yellow);
}
string filePath = "missingloca.txt";
File.WriteAllLines(filePath, missingTags.Select(t => "\""+t.Key + "\"\n missing from " + string.Join(", ", t.Value)));
System.Diagnostics.Process.Start(Path.GetFullPath(filePath));
TextManager.Language = "English";
}));
commands.Add(new Command("spamchatmessages", "", (string[] args) =>
@@ -1107,21 +1169,32 @@ namespace Barotrauma
{
if (!structure.ResizeHorizontal)
{
structure.Rect = new Rectangle(structure.Rect.X, structure.Rect.Y,
structure.Rect = structure.DefaultRect = new Rectangle(structure.Rect.X, structure.Rect.Y,
(int)structure.Prefab.ScaledSize.X,
structure.Rect.Height);
}
if (!structure.ResizeVertical)
{
structure.Rect = new Rectangle(structure.Rect.X, structure.Rect.Y,
structure.Rect = structure.DefaultRect = new Rectangle(structure.Rect.X, structure.Rect.Y,
structure.Rect.Width,
(int)structure.Prefab.ScaledSize.Y);
}
}
}
}
}
}, isCheat: false));
commands.Add(new Command("flip", "Flip the currently controlled character.", (string[] args) =>
{
Character.Controlled?.AnimController.Flip();
}, isCheat: false));
commands.Add(new Command("mirror", "Mirror the currently controlled character.", (string[] args) =>
{
(Character.Controlled?.AnimController as FishAnimController)?.Mirror(lerp: false);
}, isCheat: false));
#endif
commands.Add(new Command("dumptexts", "dumptexts [filepath]: Extracts all the texts from the given text xml and writes them into a file (using the same filename, but with the .txt extension). If the filepath is omitted, the EnglishVanilla.xml file is used.", (string[] args) =>
@@ -1237,21 +1310,53 @@ namespace Barotrauma
{
Dictionary<string, string> typeNames = new Dictionary<string, string>
{
{ "Single", "float"},
{ "Int32", "integer"},
{ "Boolean", "true/false"},
{ "String", "text"},
{ "Single", "Float"},
{ "Int32", "Integer"},
{ "Boolean", "True/False"},
{ "String", "Text"},
};
var itemComponentTypes = typeof(ItemComponent).Assembly.GetTypes().Where(type => type.IsSubclassOf(typeof(ItemComponent)));
var itemComponentTypes = typeof(ItemComponent).Assembly.GetTypes().Where(type => type.IsSubclassOf(typeof(ItemComponent))).ToList();
itemComponentTypes.Sort((i1, i2) => { return i1.Name.CompareTo(i2.Name); });
itemComponentTypes.Insert(0, typeof(ItemComponent));
string filePath = args.Length > 0 ? args[0] : "ItemComponentDocumentation.txt";
List<string> lines = new List<string>();
foreach (Type t in itemComponentTypes)
{
lines.Add($"[b]{t.Name}[/b]");
lines.Add($"[h1]{t.Name}[/h1]");
lines.Add("");
var properties = t.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly);//.Cast<System.ComponentModel.PropertyDescriptor>();
var properties = t.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly).ToList();//.Cast<System.ComponentModel.PropertyDescriptor>();
Type baseType = t.BaseType;
while (baseType != null && baseType != typeof(ItemComponent))
{
properties.AddRange(baseType.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly));
baseType = baseType.BaseType;
}
if (!properties.Any(p => p.GetCustomAttributes(true).Any(a => a is Serialize)))
{
lines.Add("No editable properties.");
lines.Add("");
continue;
}
lines.Add("[table]");
lines.Add(" [tr]");
lines.Add(" [th]Name[/th]");
lines.Add(" [th]Type[/th]");
lines.Add(" [th]Default value[/th]");
//lines.Add(" [th]Range[/th]");
lines.Add(" [th]Description[/th]");
lines.Add(" [/tr]");
Dictionary<string, SerializableProperty> dictionary = new Dictionary<string, SerializableProperty>();
foreach (var property in properties)
{
@@ -1273,29 +1378,41 @@ namespace Barotrauma
}
propertyTypeName = string.Join("/", valueNames);
}
lines.Add($"{property.Name} ({propertyTypeName})");
if (!string.IsNullOrEmpty(serialize.Description))
string defaultValueString = serialize.defaultValue?.ToString() ?? "";
if (property.PropertyType == typeof(float))
{
lines.Add(serialize.Description);
defaultValueString = ((float)serialize.defaultValue).ToString(CultureInfo.InvariantCulture);
}
lines.Add(" [tr]");
lines.Add($" [td]{property.Name}[/td]");
lines.Add($" [td]{propertyTypeName}[/td]");
lines.Add($" [td]{defaultValueString}[/td]");
Editable editable = attributes.FirstOrDefault(a => a is Editable) as Editable;
string rangeText = "-";
if (editable != null)
{
if (editable.MinValueFloat > float.MinValue || editable.MaxValueFloat < float.MaxValue)
{
lines.Add("Range: " + editable.MinValueFloat+"-"+editable.MaxValueFloat);
rangeText = editable.MinValueFloat + "-" + editable.MaxValueFloat;
}
else if (editable.MinValueInt > int.MinValue || editable.MaxValueInt < int.MaxValue)
{
lines.Add("Range: " + editable.MinValueInt + "-" + editable.MaxValueInt);
rangeText = editable.MinValueInt + "-" + editable.MaxValueInt;
}
}
//lines.Add($" [td]{rangeText}[/td]");
lines.Add("Default value: " + serialize.defaultValue);
lines.Add("");
if (!string.IsNullOrEmpty(serialize.Description))
{
lines.Add($" [td]{serialize.Description}[/td]");
}
lines.Add(" [/tr]");
}
lines.Add("[/table]");
lines.Add("");
}
File.WriteAllLines(filePath, lines);
@@ -1546,10 +1663,12 @@ namespace Barotrauma
(string[] args) =>
{
if (GameMain.Client == null || args.Length == 0) return;
ShowQuestionPrompt("Reason for banning the endpoint \"" + args[0] + "\"?", (reason) =>
ShowQuestionPrompt("Reason for banning the endpoint \"" + args[0] + "\"? (Enter c to cancel)", (reason) =>
{
ShowQuestionPrompt("Enter the duration of the ban (leave empty to ban permanently, or use the format \"[days] d [hours] h\")", (duration) =>
if (reason == "c" || reason == "C") { return; }
ShowQuestionPrompt("Enter the duration of the ban (leave empty to ban permanently, or use the format \"[days] d [hours] h\") (Enter c to cancel)", (duration) =>
{
if (duration == "c" || duration == "C") { return; }
TimeSpan? banDuration = null;
if (!string.IsNullOrWhiteSpace(duration))
{
@@ -1866,10 +1985,17 @@ namespace Barotrauma
{
character.Info.Race = race;
character.ReloadHead();
foreach (var limb in character.AnimController.Limbs)
{
if (limb.type != LimbType.Head)
{
limb.RecreateSprites();
}
}
}
}, isCheat: true));
commands.Add(new Command("loadhead|head", "Load head sprite(s). Required argument: head id. Optional arguments: hair index, beard index, moustache index, face attachment index.", args =>
commands.Add(new Command("head", "Load the head sprite and the wearables (hair etc). Required argument: head id. Optional arguments: hair index, beard index, moustache index, face attachment index.", args =>
{
var character = Character.Controlled;
if (character == null)
@@ -1903,6 +2029,13 @@ namespace Barotrauma
int.TryParse(args[4], out faceAttachmentIndex);
}
character.ReloadHead(id, hairIndex, beardIndex, moustacheIndex, faceAttachmentIndex);
foreach (var limb in character.AnimController.Limbs)
{
if (limb.type != LimbType.Head)
{
limb.RecreateSprites();
}
}
}
}, isCheat: true));
@@ -1948,13 +2081,13 @@ namespace Barotrauma
{
wearable.Variant = variant;
}
wearable.RefreshPath();
wearable.ParsePath(true);
wearable.Sprite.ReloadXML();
wearable.Sprite.ReloadTexture();
}
foreach (var wearable in limb.OtherWearables)
{
wearable.RefreshPath();
wearable.ParsePath(true);
wearable.Sprite.ReloadXML();
wearable.Sprite.ReloadTexture();
}

View File

@@ -1,4 +1,6 @@
namespace Barotrauma
using Barotrauma.Networking;
namespace Barotrauma
{
partial class Mission
{
@@ -14,5 +16,10 @@
IconColor = Prefab.IconColor
};
}
public void ClientRead(IReadMessage msg)
{
State = msg.ReadInt16();
}
}
}

View File

@@ -1,4 +1,5 @@
using Barotrauma.Items.Components;
using Barotrauma.Extensions;
using Barotrauma.Items.Components;
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
@@ -52,6 +53,8 @@ namespace Barotrauma
public GUIButton ToggleButton { get; private set; }
private GUIButton showNewMessagesButton;
public ChatBox(GUIComponent parent, bool isSinglePlayer)
{
this.IsSinglePlayer = isSinglePlayer;
@@ -65,8 +68,9 @@ namespace Barotrauma
int toggleButtonWidth = (int)(30 * GUI.Scale);
GUIFrame = new GUIFrame(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ChatBoxArea, parent.RectTransform), style: null);
var chatBoxHolder = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.9f), GUIFrame.RectTransform), style: "ChatBox");
var chatBoxHolder = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.875f), GUIFrame.RectTransform), style: "ChatBox");
chatBox = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.95f), chatBoxHolder.RectTransform, Anchor.CenterRight), style: null);
ToggleButton = new GUIButton(new RectTransform(new Point(toggleButtonWidth, HUDLayoutSettings.ChatBoxArea.Height), parent.RectTransform),
style: "UIToggleButton");
@@ -76,7 +80,7 @@ namespace Barotrauma
return true;
};
InputBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.1f), GUIFrame.RectTransform, Anchor.BottomCenter),
InputBox = new GUITextBox(new RectTransform(new Vector2(0.925f, 0.125f), GUIFrame.RectTransform, Anchor.BottomLeft),
style: "ChatTextBox")
{
Font = GUI.SmallFont,
@@ -84,9 +88,25 @@ namespace Barotrauma
};
InputBox.OnDeselected += (gui, Keys) =>
{
gui.Text = "";
//gui.Text = "";
};
var chatSendButton = new GUIButton(new RectTransform(new Vector2(0.075f, 0.125f), GUIFrame.RectTransform, Anchor.BottomRight) { RelativeOffset = new Vector2(0.0f, -0.01f) }, ">");
chatSendButton.OnClicked += (GUIButton btn, object userdata) =>
{
InputBox.OnEnterPressed(InputBox, InputBox.Text);
return true;
};
showNewMessagesButton = new GUIButton(new RectTransform(new Vector2(1f, 0.125f), GUIFrame.RectTransform, Anchor.BottomCenter) { RelativeOffset = new Vector2(0.0f, -0.125f) }, TextManager.Get("chat.shownewmessages"));
showNewMessagesButton.OnClicked += (GUIButton btn, object userdata) =>
{
chatBox.ScrollBar.BarScrollValue = 1f;
showNewMessagesButton.Visible = false;
return true;
};
showNewMessagesButton.Visible = false;
ToggleOpen = GameMain.Config.ChatOpen;
}
@@ -133,7 +153,7 @@ namespace Barotrauma
public void AddMessage(ChatMessage message)
{
while (chatBox.Content.CountChildren > 20)
while (chatBox.Content.CountChildren > 60)
{
chatBox.RemoveChild(chatBox.Content.Children.First());
}
@@ -155,18 +175,21 @@ namespace Barotrauma
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);
GUITextBlock senderNameBlock = null;
GUITextBlock senderNameBlock = new GUITextBlock(new RectTransform(new Vector2(0.98f, 0.0f), msgHolder.RectTransform) { AbsoluteOffset = new Point((int)(5 * GUI.Scale), 0) },
ChatMessage.GetTimeStamp(), textColor: Color.LightGray, font: GUI.SmallFont, textAlignment: Alignment.TopLeft, style: null)
{
CanBeFocused = true
};
if (!string.IsNullOrEmpty(senderName))
{
senderNameBlock = new GUITextBlock(new RectTransform(new Vector2(0.98f, 0.0f), msgHolder.RectTransform)
{ AbsoluteOffset = new Point((int)(5 * GUI.Scale), 0) },
new GUITextBlock(new RectTransform(new Vector2(0.8f, 1.0f), senderNameBlock.RectTransform) { AbsoluteOffset = new Point((int)(senderNameBlock.TextSize.X), 0) },
senderName, textColor: senderColor, font: GUI.SmallFont, textAlignment: Alignment.TopLeft, style: null)
{
CanBeFocused = true
};
}
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), msgHolder.RectTransform)
var msgText =new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), msgHolder.RectTransform)
{ AbsoluteOffset = new Point((int)(10 * GUI.Scale), senderNameBlock == null ? 0 : senderNameBlock.Rect.Height) },
displayedText, textColor: message.Color, font: GUI.SmallFont, textAlignment: Alignment.TopLeft, style: null, wrap: true,
color: ((chatBox.Content.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f)
@@ -185,12 +208,28 @@ namespace Barotrauma
{
msgHolder.Flash(Color.Yellow * 0.6f);
}
//resize the holder to match the size of the message and add some spacing
msgHolder.RectTransform.Resize(new Point(msgHolder.Rect.Width, msgHolder.Children.Sum(c => c.Rect.Height) + (int)(10 * GUI.Scale)), resizeChildren: false);
msgHolder.RectTransform.SizeChanged += Recalculate;
Recalculate();
void Recalculate()
{
msgHolder.RectTransform.SizeChanged -= Recalculate;
//resize the holder to match the size of the message and add some spacing
msgText.RectTransform.MaxSize = new Point(msgHolder.Rect.Width - msgText.RectTransform.AbsoluteOffset.X, int.MaxValue);
senderNameBlock.RectTransform.MaxSize = new Point(msgHolder.Rect.Width - senderNameBlock.RectTransform.AbsoluteOffset.X, int.MaxValue);
msgHolder.Children.ForEach(c => (c as GUITextBlock)?.CalculateHeightFromText());
msgHolder.RectTransform.Resize(new Point(msgHolder.Rect.Width, msgHolder.Children.Sum(c => c.Rect.Height) + (int)(10 * GUI.Scale)), resizeChildren: false);
msgHolder.RectTransform.SizeChanged += Recalculate;
chatBox.RecalculateChildren();
}
CoroutineManager.StartCoroutine(UpdateMessageAnimation(msgHolder, 0.5f));
chatBox.UpdateScrollBarSize();
if (chatBox.ScrollBar.Visible && chatBox.ScrollBar.BarScroll < 1f)
{
showNewMessagesButton.Visible = true;
}
if (!ToggleOpen)
{
@@ -203,16 +242,16 @@ namespace Barotrauma
{
CanBeFocused = false
};
var msgText = new GUITextBlock(new RectTransform(new Vector2(0.8f, 0.0f), popupMsg.RectTransform, Anchor.TopRight)
var msgPopupText = new GUITextBlock(new RectTransform(new Vector2(0.8f, 0.0f), popupMsg.RectTransform, Anchor.TopRight)
{ AbsoluteOffset = new Point(0, senderText.Rect.Height) },
displayedText, textColor: message.Color, font: GUI.SmallFont, textAlignment: Alignment.TopRight, style: null, wrap: true)
{
CanBeFocused = false
};
int textWidth = (int)Math.Max(
msgText.Font.MeasureString(msgText.WrappedText).X,
msgPopupText.Font.MeasureString(msgPopupText.WrappedText).X,
senderText.Font.MeasureString(senderText.WrappedText).X);
popupMsg.RectTransform.Resize(new Point(textWidth + 20, msgText.Rect.Bottom - senderText.Rect.Y), resizeChildren: false);
popupMsg.RectTransform.Resize(new Point(textWidth + 20, msgPopupText.Rect.Bottom - senderText.Rect.Y), resizeChildren: false);
popupMessages.Enqueue(popupMsg);
}
@@ -277,6 +316,11 @@ namespace Barotrauma
prevUIScale = GUI.Scale;
}
if (showNewMessagesButton.Visible && chatBox.ScrollBar.BarScroll == 1f)
{
showNewMessagesButton.Visible = false;
}
if (ToggleOpen || (InputBox != null && InputBox.Selected))
{
openState += deltaTime * 5.0f;

View File

@@ -19,12 +19,16 @@ namespace Barotrauma
public readonly Color OutlineColor;
public readonly XElement Element;
public readonly Dictionary<GUIComponent.ComponentState, List<UISprite>> Sprites;
public Dictionary<string, GUIComponentStyle> ChildStyles;
public GUIComponentStyle(XElement element)
{
Element = element;
Sprites = new Dictionary<GUIComponent.ComponentState, List<UISprite>>();
foreach (GUIComponent.ComponentState state in Enum.GetValues(typeof(GUIComponent.ComponentState)))
{

View File

@@ -29,6 +29,35 @@ namespace Barotrauma
{
public static GUICanvas Canvas => GUICanvas.Instance;
public static readonly SamplerState SamplerState = new SamplerState()
{
Filter = TextureFilter.Linear,
AddressU = TextureAddressMode.Wrap,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
BorderColor = Color.White,
MaxAnisotropy = 4,
MaxMipLevel = 0,
MipMapLevelOfDetailBias = -0.8f,
ComparisonFunction = CompareFunction.Never,
FilterMode = TextureFilterMode.Default,
};
public static readonly SamplerState SamplerStateClamp = new SamplerState()
{
Filter = TextureFilter.Linear,
AddressU = TextureAddressMode.Clamp,
AddressV = TextureAddressMode.Clamp,
AddressW = TextureAddressMode.Clamp,
BorderColor = Color.White,
MaxAnisotropy = 4,
MaxMipLevel = 0,
MipMapLevelOfDetailBias = -0.8f,
ComparisonFunction = CompareFunction.Never,
FilterMode = TextureFilterMode.Default,
};
public static readonly string[] vectorComponentLabels = { "X", "Y", "Z", "W" };
public static readonly string[] rectComponentLabels = { "X", "Y", "W", "H" };
public static readonly string[] colorComponentLabels = { "R", "G", "B", "A" };
@@ -455,7 +484,11 @@ namespace Barotrauma
if (GameMain.WindowActive)
{
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerStateClamp, rasterizerState: GameMain.ScissorTestEnable);
Cursor.Draw(spriteBatch, PlayerInput.LatestMousePosition, 0, Scale / 2f);
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
}
}
@@ -664,6 +697,7 @@ namespace Barotrauma
/// </summary>
public static GUIComponent UpdateMouseOn()
{
GUIComponent prevMouseOn = MouseOn;
MouseOn = null;
int inventoryIndex = -1;
if (Inventory.IsMouseOnInventory())
@@ -673,9 +707,13 @@ namespace Barotrauma
for (int i = updateList.Count - 1; i > inventoryIndex; i--)
{
GUIComponent c = updateList[i];
if (!c.CanBeFocused) { continue; }
if (c.MouseRect.Contains(PlayerInput.MousePosition))
{
MouseOn = c;
if ((!PlayerInput.LeftButtonHeld() && !PlayerInput.LeftButtonClicked()) || c == prevMouseOn)
{
MouseOn = c;
}
break;
}
}
@@ -1629,42 +1667,9 @@ namespace Barotrauma
return true;
}
private static bool QuitClicked(GUIButton button, object obj)
public static bool QuitClicked(GUIButton button, object obj)
{
bool save = button.UserData as string == "save";
if (save)
{
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
}
if (GameMain.Client != null)
{
GameMain.Client.Disconnect();
GameMain.Client = null;
}
CoroutineManager.StopCoroutines("EndCinematic");
if (GameMain.GameSession != null)
{
if (Tutorial.Initialized)
{
((TutorialMode)GameMain.GameSession.GameMode).Tutorial.Stop();
}
if (GameSettings.SendUserStatistics)
{
Mission mission = GameMain.GameSession.Mission;
GameAnalyticsManager.AddDesignEvent("QuitRound:" + (save ? "Save" : "NoSave"));
GameAnalyticsManager.AddDesignEvent("EndRound:" + (mission == null ? "NoMission" : (mission.Completed ? "MissionCompleted" : "MissionFailed")));
}
GameMain.GameSession = null;
}
GUIMessageBox.CloseAll();
GameMain.MainMenuScreen.Select();
GameMain.QuitToMainMenu(button.UserData as string == "save");
return true;
}

View File

@@ -153,15 +153,18 @@ namespace Barotrauma
public GUIButton(RectTransform rectT, string text = "", Alignment textAlignment = Alignment.Center, string style = "", Color? color = null) : base(style, rectT)
{
CanBeFocused = true;
if (color.HasValue)
{
this.color = color.Value;
}
frame = new GUIFrame(new RectTransform(Vector2.One, rectT), style);
frame = new GUIFrame(new RectTransform(Vector2.One, rectT), style) { CanBeFocused = false };
if (style != null) GUI.Style.Apply(frame, style == "" ? "GUIButton" : style);
textBlock = new GUITextBlock(new RectTransform(Vector2.One, rectT), text, textAlignment: textAlignment, style: null)
{
TextColor = this.style == null ? Color.Black : this.style.textColor
TextColor = this.style == null ? Color.Black : this.style.textColor,
CanBeFocused = false
};
if (rectT.Rect.Height == 0 && !string.IsNullOrEmpty(text))
{

View File

@@ -106,11 +106,21 @@ namespace Barotrauma
return Children.Where(c => c.userData == userData);
}
public IEnumerable<GUIComponent> FindChildren(Func<GUIComponent, bool> predicate)
{
return Children.Where(c => predicate(c));
}
public virtual void ClearChildren()
{
RectTransform.ClearChildren();
}
public void SetAsFirstChild()
{
RectTransform.SetAsFirstChild();
}
public void SetAsLastChild()
{
RectTransform.SetAsLastChild();
@@ -319,7 +329,7 @@ namespace Barotrauma
Font = GUI.Font;
CanBeFocused = true;
CanBeFocused = true; //TODO: change default to false?
if (style != null)
GUI.Style.Apply(this, style);
@@ -729,9 +739,10 @@ namespace Barotrauma
private static GUITextBlock LoadGUITextBlock(XElement element, RectTransform parent, string overrideText = null, Anchor? anchor = null)
{
string text = element.Attribute("text") == null ?
element.ElementInnerText() :
element.GetAttributeString("text", "");
string text = overrideText ??
(element.Attribute("text") == null ?
element.ElementInnerText() :
element.GetAttributeString("text", ""));
text = text.Replace(@"\n", "\n");
string style = element.GetAttributeString("style", "");

View File

@@ -29,7 +29,7 @@ namespace Barotrauma
{
spriteBatch.End();
spriteBatch.GraphicsDevice.ScissorRectangle = Rectangle.Intersect(prevScissorRect, Rect);
spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
}
OnDraw?.Invoke(spriteBatch, this);
@@ -38,7 +38,7 @@ namespace Barotrauma
{
spriteBatch.End();
spriteBatch.GraphicsDevice.ScissorRectangle = prevScissorRect;
spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
}
}

View File

@@ -16,7 +16,7 @@ namespace Barotrauma
private GUIButton button;
private GUIListBox listBox;
private RectTransform currentListBoxParent;
private RectTransform currentHighestParent;
private List<RectTransform> parentHierarchy = new List<RectTransform>();
private bool selectMultiple;
@@ -141,6 +141,8 @@ namespace Barotrauma
public GUIDropDown(RectTransform rectT, string text = "", int elementCount = 4, string style = "", bool selectMultiple = false) : base(style, rectT)
{
CanBeFocused = true;
this.selectMultiple = selectMultiple;
button = new GUIButton(new RectTransform(Vector2.One, rectT), text, Alignment.CenterLeft, style: "GUIDropDown")
@@ -149,7 +151,7 @@ namespace Barotrauma
};
GUI.Style.Apply(button, "", this);
listBox = new GUIListBox(new RectTransform(new Point(Rect.Width, Rect.Height * MathHelper.Clamp(elementCount, 2, 10)), rectT, Anchor.BottomLeft, Pivot.TopLeft)
listBox = new GUIListBox(new RectTransform(new Point(Rect.Width, Rect.Height * MathHelper.Clamp(elementCount, 2, 10)), rectT, Anchor.BottomCenter, Pivot.TopCenter)
{ IsFixedSize = false }, style: null)
{
Enabled = !selectMultiple,
@@ -157,48 +159,55 @@ namespace Barotrauma
};
GUI.Style.Apply(listBox.Content, "GUIListBox", this);
currentListBoxParent = FindListBoxParent();
currentListBoxParent.GUIComponent.OnAddedToGUIUpdateList += AddListBoxToGUIUpdateList;
currentHighestParent = FindHighestParent();
currentHighestParent.GUIComponent.OnAddedToGUIUpdateList += AddListBoxToGUIUpdateList;
rectT.ParentChanged += (RectTransform newParent) =>
{
currentListBoxParent.GUIComponent.OnAddedToGUIUpdateList -= AddListBoxToGUIUpdateList;
currentHighestParent.GUIComponent.OnAddedToGUIUpdateList -= AddListBoxToGUIUpdateList;
if (newParent != null)
{
currentListBoxParent = FindListBoxParent();
currentListBoxParent.GUIComponent.OnAddedToGUIUpdateList += AddListBoxToGUIUpdateList;
currentHighestParent = FindHighestParent();
currentHighestParent.GUIComponent.OnAddedToGUIUpdateList += AddListBoxToGUIUpdateList;
}
};
}
/// <summary>
/// Finds the component after which the listbox should be drawn. Usually the parent of the dropdown, but if the dropdown
/// is the child of another GUIListBox, we need to draw our listbox after that because listboxes clip everything outside their rect.
/// Finds the component after which the listbox should be drawn
/// //(= the component highest in the hierarchy, to get the listbox
/// //to be rendered on top of all of it's children)
/// </summary>
private RectTransform FindListBoxParent()
private RectTransform FindHighestParent()
{
parentHierarchy.Clear();
//collect entire parent hierarchy to a list
parentHierarchy = new List<RectTransform>() { RectTransform.Parent };
while (parentHierarchy.Last().Parent != null)
RectTransform parent = parentHierarchy.Last();
while (parent?.Parent != null)
{
parentHierarchy.Add(parentHierarchy.Last().Parent);
parentHierarchy.Add(parent.Parent);
parent = parent.Parent;
}
//find the parent GUIListBox highest in the hierarchy
for (int i = parentHierarchy.Count - 1; i >= 0; i--)
//find the highest parent that has a guicomponent with a style
//(and so should be rendered and not just some empty parent/root element used for constructing a layout)
for (int i = parentHierarchy.Count - 1; i > 0; i--)
{
if (parentHierarchy[i].GUIComponent is GUIListBox)
if (parentHierarchy[i] is GUICanvas ||
parentHierarchy[i].GUIComponent == null ||
parentHierarchy[i].GUIComponent.Style == null ||
parentHierarchy[i].GUIComponent == Screen.Selected?.Frame)
{
if (parentHierarchy[i].Parent != null && parentHierarchy[i].Parent.GUIComponent != null)
{
return parentHierarchy[i].Parent;
}
return parentHierarchy[i];
parentHierarchy.RemoveAt(i);
}
else
{
break;
}
}
//or just go with the direct parent if there are no listboxes in the hierarchy
parentHierarchy.Clear();
parentHierarchy.Add(RectTransform.Parent);
return RectTransform.Parent;
return parentHierarchy.Last();
}
public void AddItem(string text, object userData = null, string toolTip = "")

View File

@@ -20,7 +20,7 @@ namespace Barotrauma
Color currColor = GetCurrentColor(state);
if (sprites == null || !sprites.Any()) GUI.DrawRectangle(spriteBatch, Rect, currColor * (currColor.A/255.0f), true);
if (sprites == null || !sprites.Any(s => s.Value.Any())) GUI.DrawRectangle(spriteBatch, Rect, currColor * (currColor.A/255.0f), true);
base.Draw(spriteBatch);
if (OutlineColor != Color.Transparent)

View File

@@ -1,6 +1,7 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Linq;
namespace Barotrauma
{
@@ -57,6 +58,10 @@ namespace Barotrauma
}
}
public BlendState BlendState;
public ComponentState? OverrideState = null;
public GUIImage(RectTransform rectT, string style, bool scaleToFit = false)
: this(rectT, null, null, scaleToFit, style)
{
@@ -82,9 +87,7 @@ namespace Barotrauma
}
if (style == null)
{
color = Color.White;
hoverColor = Color.White;
selectedColor = Color.White;
color = hoverColor = selectedColor = pressedColor = Color.White;
}
if (!scaleToFit)
{
@@ -99,7 +102,17 @@ namespace Barotrauma
protected override void Draw(SpriteBatch spriteBatch)
{
if (!Visible) return;
if (Parent != null) { state = Parent.State; }
if (OverrideState != null) { state = OverrideState.Value; }
Color currColor = GetCurrentColor(state);
if (BlendState != null)
{
spriteBatch.End();
spriteBatch.Begin(blendState: BlendState, samplerState: GUI.SamplerState);
}
if (style != null)
{
foreach (UISprite uiSprite in style.Sprites[state])
@@ -121,6 +134,12 @@ namespace Barotrauma
spriteBatch.Draw(sprite.Texture, Rect.Center.ToVector2(), sourceRect, currColor * (currColor.A / 255.0f), Rotation, sprite.size / 2,
Scale, SpriteEffects, 0.0f);
}
if (BlendState != null)
{
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
}
}
private void RecalculateScale()

View File

@@ -1,4 +1,5 @@
using Microsoft.Xna.Framework;
using System;
using System.Linq;
namespace Barotrauma
@@ -71,6 +72,8 @@ namespace Barotrauma
public GUILayoutGroup(RectTransform rectT, bool isHorizontal = false, Anchor childAnchor = Anchor.TopLeft) : base(null, rectT)
{
CanBeFocused = false;
this.isHorizontal = isHorizontal;
this.childAnchor = childAnchor;
rectT.ChildrenChanged += (child) => needsToRecalculate = true;
@@ -83,17 +86,25 @@ namespace Barotrauma
float stretchFactor = 1.0f;
if (stretch && RectTransform.Children.Count() > 0)
{
float minSize = RectTransform.Children
.Where(c => !c.GUIComponent.IgnoreLayoutGroups)
.Sum(c => isHorizontal ? c.MinSize.X : c.MinSize.Y);
float totalSize = RectTransform.Children
.Where(c => !c.GUIComponent.IgnoreLayoutGroups)
.Sum(c => isHorizontal ?
MathHelper.Clamp(c.Rect.Width, c.MinSize.X, c.MaxSize.X) :
MathHelper.Clamp(c.Rect.Height, c.MinSize.Y, c.MaxSize.Y));
float thisSize = (isHorizontal ? Rect.Width : Rect.Height);
totalSize +=
(RectTransform.Children.Count() - 1) *
(absoluteSpacing + relativeSpacing * (isHorizontal ? Rect.Width : Rect.Height));
(absoluteSpacing + relativeSpacing * thisSize);
stretchFactor = totalSize <= 0.0f ? 1.0f : (isHorizontal ? Rect.Width: Rect.Height) / totalSize;
stretchFactor = totalSize <= 0.0f || minSize >= thisSize ?
1.0f :
(thisSize - minSize) / (totalSize - minSize);
}
int absPos = 0;
@@ -106,7 +117,7 @@ namespace Barotrauma
{
child.RelativeOffset = new Vector2(relPos, child.RelativeOffset.Y);
child.AbsoluteOffset = new Point(absPos, child.AbsoluteOffset.Y);
absPos += (int)((child.Rect.Width + absoluteSpacing) * stretchFactor);
absPos += (int)Math.Max((child.Rect.Width + absoluteSpacing) * stretchFactor, child.MinSize.X);
if (stretch)
{
child.RelativeSize = new Vector2(child.RelativeSize.X * stretchFactor, child.RelativeSize.Y);
@@ -116,7 +127,7 @@ namespace Barotrauma
{
child.RelativeOffset = new Vector2(child.RelativeOffset.X, relPos);
child.AbsoluteOffset = new Point(child.AbsoluteOffset.X, absPos);
absPos += (int)((child.Rect.Height + absoluteSpacing) * stretchFactor);
absPos += (int)Math.Max((child.Rect.Height + absoluteSpacing) * stretchFactor, child.MinSize.Y);
if (stretch)
{
child.RelativeSize = new Vector2(child.RelativeSize.X, child.RelativeSize.Y * stretchFactor);

View File

@@ -135,6 +135,8 @@ namespace Barotrauma
public GUIListBox(RectTransform rectT, bool isHorizontal = false, Color? color = null, string style = "") : base(style, rectT)
{
CanBeFocused = true;
selected = new List<GUIComponent>();
Point frameSize = isHorizontal ?
@@ -176,7 +178,7 @@ namespace Barotrauma
private void UpdateDimensions()
{
if (!ScrollBarEnabled)
if (!ScrollBar.Visible)
{
Content.RectTransform.NonScaledSize = Rect.Size;
}
@@ -295,7 +297,7 @@ namespace Barotrauma
if (child == null) continue;
// selecting
if (Enabled && child.CanBeFocused && (GUI.IsMouseOn(child)) && child.Rect.Contains(PlayerInput.MousePosition))
if (Enabled && CanBeFocused && child.CanBeFocused && (GUI.IsMouseOn(child)) && child.Rect.Contains(PlayerInput.MousePosition))
{
child.State = ComponentState.Hover;
if (PlayerInput.LeftButtonClicked())
@@ -322,6 +324,15 @@ namespace Barotrauma
public override void AddToGUIUpdateList(bool ignoreChildren = false, int order = 0)
{
if (!Visible) { return; }
if (!ignoreChildren)
{
foreach (GUIComponent child in Children)
{
if (child == Content || child == ScrollBar) { continue; }
child.AddToGUIUpdateList(ignoreChildren, order);
}
}
foreach (GUIComponent child in Content.Children)
{
@@ -406,12 +417,16 @@ namespace Barotrauma
scrollBarNeedsRecalculation = false;
}
bool prevScrollBarVisible = ScrollBar.Visible;
ScrollBar.Enabled = ScrollBarEnabled && ScrollBar.BarSize < 1.0f;
if (AutoHideScrollBar)
{
ScrollBar.Visible = ScrollBar.BarSize < 1.0f;
}
if (ScrollBar.Visible != prevScrollBarVisible) { UpdateDimensions(); }
if ((GUI.IsMouseOn(this) || GUI.IsMouseOn(ScrollBar)) && PlayerInput.ScrollWheelSpeed != 0)
{
ScrollBar.BarScroll -= (PlayerInput.ScrollWheelSpeed / 500.0f) * BarSize;
@@ -594,7 +609,7 @@ namespace Barotrauma
{
spriteBatch.End();
spriteBatch.GraphicsDevice.ScissorRectangle = Rectangle.Intersect(prevScissorRect, Content.Rect);
spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
}
var children = Content.Children;
@@ -618,7 +633,7 @@ namespace Barotrauma
{
spriteBatch.End();
spriteBatch.GraphicsDevice.ScissorRectangle = prevScissorRect;
spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: prevRasterizerState);
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: prevRasterizerState);
}
if (ScrollBar.Visible) ScrollBar.DrawManually(spriteBatch, alsoChildren: true, recursive: true);

View File

@@ -119,6 +119,19 @@ namespace Barotrauma
}
}
public override ScalableFont Font
{
get
{
return base.Font;
}
set
{
base.Font = value;
if (TextBox != null) { TextBox.Font = value; }
}
}
public GUILayoutGroup LayoutGroup
{
get;
@@ -147,11 +160,11 @@ namespace Barotrauma
};
TextBox.OnTextChanged += TextChanged;
var buttonArea = new GUIFrame(new RectTransform(new Vector2(_relativeButtonAreaWidth, 1.0f), LayoutGroup.RectTransform, Anchor.CenterRight), style: null);
if (!relativeButtonAreaWidth.HasValue)
/*if (!relativeButtonAreaWidth.HasValue)
{
// Not sure what's the point of this
buttonArea.RectTransform.MinSize = new Point(Rect.Height, 0);
}
}*/
PlusButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.5f), buttonArea.RectTransform), "+");
PlusButton.OnButtonDown += () =>
{

View File

@@ -94,7 +94,7 @@ namespace Barotrauma
{
spriteBatch.End();
spriteBatch.GraphicsDevice.ScissorRectangle = Rectangle.Intersect(prevScissorRect, sliderRect);
spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
}
Color currColor = GetCurrentColor(state);

View File

@@ -9,11 +9,12 @@ namespace Barotrauma
{
public class GUIRadioButtonGroup : GUIComponent
{
private Dictionary<Enum, GUITickBox> radioButtons; //TODO: use children list instead?
private Dictionary<int, GUITickBox> radioButtons; //TODO: use children list instead?
public GUIRadioButtonGroup() : base("GUIFrame")
public GUIRadioButtonGroup() : base(null)
{
radioButtons = new Dictionary<Enum, GUITickBox>();
radioButtons = new Dictionary<int, GUITickBox>();
selected = null;
}
public override bool Enabled
@@ -22,28 +23,28 @@ namespace Barotrauma
set
{
base.Enabled = value;
foreach(KeyValuePair<Enum, GUITickBox> rbPair in radioButtons)
foreach(KeyValuePair<int, GUITickBox> rbPair in radioButtons)
{
rbPair.Value.Enabled = value;
}
}
}
public void AddRadioButton(Enum key, GUITickBox radioButton)
public void AddRadioButton(int key, GUITickBox radioButton)
{
if (selected == key) radioButton.Selected = true;
else if (radioButton.Selected) selected = key;
radioButton.SetRadioButtonGroup(this);
radioButtons.Add(key, radioButton);
radioButtons.Add((int)key, radioButton);
}
public delegate void RadioButtonGroupDelegate(GUIRadioButtonGroup rbg, Enum val);
public delegate void RadioButtonGroupDelegate(GUIRadioButtonGroup rbg, int? val);
public RadioButtonGroupDelegate OnSelect = null;
public void SelectRadioButton(GUITickBox radioButton)
{
foreach (KeyValuePair<Enum, GUITickBox> rbPair in radioButtons)
foreach (KeyValuePair<int, GUITickBox> rbPair in radioButtons)
{
if (radioButton == rbPair.Value)
{
@@ -53,8 +54,8 @@ namespace Barotrauma
}
}
private Enum selected;
public Enum Selected
private int? selected;
public int? Selected
{
get
{
@@ -63,11 +64,11 @@ namespace Barotrauma
set
{
OnSelect?.Invoke(this, value);
if (selected != null && selected.Equals((Enum)value)) return;
if (selected != null && selected.Equals(value)) return;
selected = value;
foreach (KeyValuePair<Enum, GUITickBox> radioButton in radioButtons)
foreach (KeyValuePair<int, GUITickBox> radioButton in radioButtons)
{
if (radioButton.Key.Equals((Enum)value))
if (radioButton.Key.Equals(value))
{
radioButton.Value.Selected = true;
}
@@ -80,7 +81,7 @@ namespace Barotrauma
{
get
{
return radioButtons[selected];
return selected.HasValue ? radioButtons[selected.Value] : null;
}
}
}

View File

@@ -17,6 +17,8 @@ namespace Barotrauma
private float barScroll;
private float step;
private Vector2? dragStartPos;
public delegate bool OnMovedHandler(GUIScrollBar scrollBar, float barScroll);
public OnMovedHandler OnMoved;
@@ -162,6 +164,18 @@ namespace Barotrauma
}
}
public float StepValue
{
get
{
return step * (Range.Y - Range.X);
}
set
{
Step = value / (Range.Y - Range.X);
}
}
public float BarSize
{
get { return barSize; }
@@ -174,6 +188,8 @@ namespace Barotrauma
public GUIScrollBar(RectTransform rectT, float barSize = 1, Color? color = null, string style = "", bool? isHorizontal = null) : base(style, rectT)
{
CanBeFocused = true;
this.isHorizontal = isHorizontal ?? (Rect.Width > Rect.Height);
Frame = new GUIFrame(new RectTransform(Vector2.One, rectT));
GUI.Style.Apply(Frame, IsHorizontal ? "GUIFrameHorizontal" : "GUIFrameVertical", this);
@@ -201,11 +217,11 @@ namespace Barotrauma
protected override void Update(float deltaTime)
{
if (!Visible) return;
if (!Visible) { return; }
base.Update(deltaTime);
if (!enabled) return;
if (!enabled) { return; }
if (IsBooleanSwitch &&
(!PlayerInput.LeftButtonHeld() || (GUI.MouseOn != this && !IsParentOf(GUI.MouseOn))))
@@ -221,10 +237,19 @@ namespace Barotrauma
if (draggingBar == this)
{
if (dragStartPos == null) { dragStartPos = PlayerInput.MousePosition; }
if (!PlayerInput.LeftButtonHeld())
{
if (IsBooleanSwitch && GUI.MouseOn == Bar && Vector2.Distance(dragStartPos.Value, PlayerInput.MousePosition) < 5)
{
BarScroll = BarScroll > 0.5f ? 0.0f : 1.0f;
OnMoved?.Invoke(this, BarScroll);
}
OnReleased?.Invoke(this, BarScroll);
draggingBar = null;
dragStartPos = null;
}
if ((isHorizontal && PlayerInput.MousePosition.X > Rect.X && PlayerInput.MousePosition.X < Rect.Right) ||
(!isHorizontal && PlayerInput.MousePosition.Y > Rect.Y && PlayerInput.MousePosition.Y < Rect.Bottom))
@@ -237,9 +262,18 @@ namespace Barotrauma
if (PlayerInput.LeftButtonClicked())
{
draggingBar?.OnReleased?.Invoke(draggingBar, draggingBar.BarScroll);
MoveButton(new Vector2(
Math.Sign(PlayerInput.MousePosition.X - Bar.Rect.Center.X) * Bar.Rect.Width,
Math.Sign(PlayerInput.MousePosition.Y - Bar.Rect.Center.Y) * Bar.Rect.Height));
if (IsBooleanSwitch)
{
MoveButton(new Vector2(
Math.Sign(PlayerInput.MousePosition.X - Bar.Rect.Center.X) * Rect.Width,
Math.Sign(PlayerInput.MousePosition.Y - Bar.Rect.Center.Y) * Rect.Height));
}
else
{
MoveButton(new Vector2(
Math.Sign(PlayerInput.MousePosition.X - Bar.Rect.Center.X) * Bar.Rect.Width,
Math.Sign(PlayerInput.MousePosition.Y - Bar.Rect.Center.Y) * Bar.Rect.Height));
}
}
}
}
@@ -270,7 +304,7 @@ namespace Barotrauma
BarScroll = newScroll;
if (moveAmount != Vector2.Zero && OnMoved != null) OnMoved(this, BarScroll);
if (moveAmount != Vector2.Zero && OnMoved != null) { OnMoved(this, BarScroll); }
}
}
}

View File

@@ -242,10 +242,10 @@ namespace Barotrauma
Censor = false;
}
public void CalculateHeightFromText()
public void CalculateHeightFromText(int padding = 0)
{
if (wrappedText == null) { return; }
RectTransform.Resize(new Point(RectTransform.Rect.Width, (int)Font.MeasureString(wrappedText).Y));
RectTransform.Resize(new Point(RectTransform.Rect.Width, (int)Font.MeasureString(wrappedText).Y + padding));
}
public override void ApplyStyle(GUIComponentStyle style)
@@ -262,7 +262,7 @@ namespace Barotrauma
if (text == null) return;
censoredText = "";
for (int i=0;i<text.Length;i++)
for (int i = 0; i < text.Length; i++)
{
censoredText += "\u2022";
}
@@ -367,7 +367,7 @@ namespace Barotrauma
spriteBatch.End();
Rectangle scissorRect = new Rectangle(rect.X + (int)padding.X, rect.Y, rect.Width - (int)padding.X - (int)padding.Z, rect.Height);
spriteBatch.GraphicsDevice.ScissorRectangle = scissorRect;
spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
}
if (!string.IsNullOrEmpty(text))
@@ -391,7 +391,7 @@ namespace Barotrauma
{
spriteBatch.End();
spriteBatch.GraphicsDevice.ScissorRectangle = prevScissorRect;
spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
}
if (OutlineColor.A * currColor.A > 0.0f) GUI.DrawRectangle(spriteBatch, rect, OutlineColor * (currColor.A / 255.0f), false);

View File

@@ -9,9 +9,9 @@ using System.Linq;
namespace Barotrauma
{
delegate void TextBoxEvent(GUITextBox sender, Keys key);
public delegate void TextBoxEvent(GUITextBox sender, Keys key);
class GUITextBox : GUIComponent, IKeyboardSubscriber
public class GUITextBox : GUIComponent, IKeyboardSubscriber
{
public event TextBoxEvent OnSelected;
public event TextBoxEvent OnDeselected;
@@ -38,6 +38,7 @@ namespace Barotrauma
public bool CaretEnabled { get; set; }
public Color? CaretColor { get; set; }
public bool DeselectAfterMessage = true;
private int? maxTextLength;
@@ -232,6 +233,8 @@ namespace Barotrauma
Alignment textAlignment = Alignment.Left, bool wrap = false, string style = "", Color? color = null)
: base(style, rectT)
{
CanBeFocused = true;
Enabled = true;
this.color = color ?? Color.White;
frame = new GUIFrame(new RectTransform(Vector2.One, rectT, Anchor.Center), style, color);
@@ -477,7 +480,7 @@ namespace Barotrauma
}
else
{
if (PlayerInput.LeftButtonClicked() && selected) Deselect();
if ((PlayerInput.LeftButtonClicked() || PlayerInput.RightButtonClicked()) && selected) Deselect();
isSelecting = false;
state = ComponentState.None;
}
@@ -656,7 +659,12 @@ namespace Barotrauma
switch (command)
{
case '\b': //backspace
if (selectedCharacters > 0)
if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))
{
SetText(string.Empty, false);
CaretIndex = Text.Length;
}
else if (selectedCharacters > 0)
{
RemoveSelectedText();
}
@@ -692,6 +700,7 @@ namespace Barotrauma
text = memento.Undo();
if (text != Text)
{
ClearSelection();
SetText(text, false);
CaretIndex = Text.Length;
OnTextChanged?.Invoke(this, Text);
@@ -701,6 +710,7 @@ namespace Barotrauma
text = memento.Redo();
if (text != Text)
{
ClearSelection();
SetText(text, false);
CaretIndex = Text.Length;
OnTextChanged?.Invoke(this, Text);
@@ -860,16 +870,12 @@ namespace Barotrauma
private void RemoveSelectedText()
{
if (selectedText.Length == 0) { return; }
if (IsLeftToRight)
{
SetText(Text.Remove(selectionStartIndex, selectedText.Length));
CaretIndex = Math.Min(Text.Length, selectionStartIndex);
}
else
{
SetText(Text.Remove(selectionEndIndex, selectedText.Length));
CaretIndex = Math.Min(Text.Length, selectionEndIndex);
}
selectionStartIndex = Math.Max(0, Math.Min(selectionEndIndex, Math.Min(selectionStartIndex, Text.Length - 1)));
int selectionLength = Math.Min(Text.Length - selectionStartIndex, selectedText.Length);
SetText(Text.Remove(selectionStartIndex, selectionLength));
CaretIndex = Math.Min(Text.Length, selectionStartIndex);
ClearSelection();
OnTextChanged?.Invoke(this, Text);
}

View File

@@ -1,11 +1,13 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
namespace Barotrauma
{
public class GUITickBox : GUIComponent
{
private GUILayoutGroup layoutGroup;
private GUIFrame box;
private GUITextBlock text;
@@ -69,14 +71,19 @@ namespace Barotrauma
set { text.TextColor = value; }
}
public override Rectangle MouseRect
/*public override Rectangle MouseRect
{
get
{
if (!CanBeFocused) return Rectangle.Empty;
return ClampMouseRectToParent ? ClampRect(box.Rect) : box.Rect;
Rectangle union = Rectangle.Union(box.Rect, TextBlock.Rect);
Vector2 textPos = TextBlock.Rect.Location.ToVector2() + TextBlock.TextPos + TextBlock.TextOffset;
Vector2 textSize = TextBlock.Font.MeasureString(TextBlock.Text);
union = Rectangle.Union(union, new Rectangle(textPos.ToPoint(), textSize.ToPoint()));
union = Rectangle.Union(union, Rect);
return ClampMouseRectToParent ? ClampRect(union) : union;
}
}
}*/
public override ScalableFont Font
{
@@ -121,7 +128,11 @@ namespace Barotrauma
public GUITickBox(RectTransform rectT, string label, ScalableFont font = null, string style = "") : base(null, rectT)
{
box = new GUIFrame(new RectTransform(new Point(rectT.Rect.Height, rectT.Rect.Height), rectT, Anchor.CenterLeft)
CanBeFocused = true;
layoutGroup = new GUILayoutGroup(new RectTransform(Vector2.One, rectT), true);
box = new GUIFrame(new RectTransform(Vector2.One, layoutGroup.RectTransform, scaleBasis: ScaleBasis.BothHeight)
{
IsFixedSize = false
}, string.Empty, Color.DarkGray)
@@ -131,7 +142,11 @@ namespace Barotrauma
CanBeFocused = false
};
GUI.Style.Apply(box, style == "" ? "GUITickBox" : style);
text = new GUITextBlock(new RectTransform(Vector2.One, rectT, Anchor.CenterLeft) { AbsoluteOffset = new Point(box.Rect.Width, 0) }, label, font: font, textAlignment: Alignment.CenterLeft);
Vector2 textBlockScale = new Vector2((float)(Rect.Width - Rect.Height) / (float)Math.Max(Rect.Width, 1.0), 1.0f);
text = new GUITextBlock(new RectTransform(textBlockScale, layoutGroup.RectTransform), label, font: font, textAlignment: Alignment.CenterLeft)
{
CanBeFocused = false
};
GUI.Style.Apply(text, "GUIButtonHorizontal", this);
Enabled = true;
@@ -148,9 +163,9 @@ namespace Barotrauma
private void ResizeBox()
{
box.RectTransform.NonScaledSize = new Point(RectTransform.NonScaledSize.Y);
text.RectTransform.NonScaledSize = new Point(Rect.Width - box.Rect.Width, text.Rect.Height);
text.RectTransform.AbsoluteOffset = new Point(box.Rect.Width, 0);
Vector2 textBlockScale = new Vector2(Math.Max(Rect.Width - box.Rect.Width, 0.0f) / Math.Max(Rect.Width, 1.0f), 1.0f);
text.RectTransform.RelativeSize = textBlockScale;
text.SetTextPos();
}
protected override void Update(float deltaTime)

View File

@@ -21,11 +21,11 @@ namespace Barotrauma
private Video currSplashScreen;
private DateTime videoStartTime;
private Queue<Pair<string, Point>> pendingSplashScreens = new Queue<Pair<string, Point>>();
private Queue<Triplet<string, Point, float>> pendingSplashScreens = new Queue<Triplet<string, Point, float>>();
/// <summary>
/// Pair.first = filepath, Pair.second = resolution
/// Triplet.first = filepath, Triplet.second = resolution, Triplet.third = audio gain
/// </summary>
public Queue<Pair<string, Point>> PendingSplashScreens
public Queue<Triplet<string, Point, float>> PendingSplashScreens
{
get
{
@@ -49,7 +49,7 @@ namespace Barotrauma
{
lock (loadMutex)
{
return currSplashScreen != null;
return currSplashScreen != null || pendingSplashScreens.Count > 0;
}
}
}
@@ -149,7 +149,7 @@ namespace Barotrauma
TitlePosition = new Vector2(GameMain.GraphicsWidth * 0.5f, GameMain.GraphicsHeight * 0.45f);
}
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, samplerState: GUI.SamplerState);
graphics.Clear(Color.Black);
spriteBatch.Draw(backgroundTexture, BackgroundPosition, null, Color.White * Math.Min(state / 5.0f, 1.0f), 0.0f,
@@ -168,7 +168,7 @@ namespace Barotrauma
WaterRenderer.Instance.RenderWater(spriteBatch, renderTarget, null);
}
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, samplerState: GUI.SamplerState);
titleSprite?.Draw(spriteBatch, TitlePosition, Color.White * Math.Min((state - 1.0f) / 5.0f, 1.0f), scale: titleScale);
@@ -280,6 +280,7 @@ namespace Barotrauma
try
{
currSplashScreen = new Video(graphics, GameMain.SoundManager, fileName, (uint)resolution.X, (uint)resolution.Y);
currSplashScreen.AudioGain = newSplashScreen.Third;
videoStartTime = DateTime.Now;
}
catch (Exception e)

View File

@@ -166,6 +166,8 @@ namespace Barotrauma
get { return loadingScreenOpen; }
}
private const GraphicsProfile GfxProfile = GraphicsProfile.Reach;
public GameMain(string[] args)
{
Content.RootDirectory = "Content";
@@ -173,6 +175,7 @@ namespace Barotrauma
GraphicsDeviceManager = new GraphicsDeviceManager(this);
GraphicsDeviceManager.IsFullScreen = false;
GraphicsDeviceManager.GraphicsProfile = GfxProfile;
GraphicsDeviceManager.ApplyChanges();
Window.Title = "Barotrauma";
@@ -222,7 +225,7 @@ namespace Barotrauma
GraphicsHeight = Math.Min(GraphicsDevice.DisplayMode.Height, GraphicsHeight);
break;
}
GraphicsDeviceManager.GraphicsProfile = GraphicsProfile.Reach;
GraphicsDeviceManager.GraphicsProfile = GfxProfile;
GraphicsDeviceManager.PreferredBackBufferFormat = SurfaceFormat.Color;
GraphicsDeviceManager.PreferMultiSampling = false;
GraphicsDeviceManager.SynchronizeWithVerticalRetrace = Config.VSyncEnabled;
@@ -292,6 +295,8 @@ namespace Barotrauma
GraphicsWidth = GraphicsDevice.Viewport.Width;
GraphicsHeight = GraphicsDevice.Viewport.Height;
ApplyGraphicsSettings();
ConvertUnits.SetDisplayUnitToSimUnitRatio(Physics.DisplayToSimRation);
spriteBatch = new SpriteBatch(GraphicsDevice);
@@ -308,8 +313,6 @@ namespace Barotrauma
bool canLoadInSeparateThread = true;
ApplyGraphicsSettings();
loadingCoroutine = CoroutineManager.StartCoroutine(Load(canLoadInSeparateThread), "Load", canLoadInSeparateThread);
}
@@ -382,9 +385,10 @@ namespace Barotrauma
if (Config.EnableSplashScreen)
{
var pendingSplashScreens = TitleScreen.PendingSplashScreens;
pendingSplashScreens?.Enqueue(new Pair<string, Point>("Content/Splash_UTG.mp4", new Point(1280, 720)));
pendingSplashScreens?.Enqueue(new Pair<string, Point>("Content/Splash_FF.mp4", new Point(1280, 720)));
pendingSplashScreens?.Enqueue(new Pair<string, Point>("Content/Splash_Daedalic.mp4", new Point(1920, 1080)));
float baseVolume = MathHelper.Clamp(Config.SoundVolume * 2.0f, 0.0f, 1.0f);
pendingSplashScreens?.Enqueue(new Triplet<string, Point, float>("Content/Splash_UTG.mp4", new Point(1280, 720), baseVolume * 0.5f));
pendingSplashScreens?.Enqueue(new Triplet<string, Point, float>("Content/Splash_FF.mp4", new Point(1280, 720), baseVolume));
pendingSplashScreens?.Enqueue(new Triplet<string, Point, float>("Content/Splash_Daedalic.mp4", new Point(1920, 1080), baseVolume * 0.15f));
}
//if not loading in a separate thread, wait for the splash screens to finish before continuing the loading
@@ -477,11 +481,6 @@ namespace Barotrauma
yield return CoroutineStatus.Running;
JobPrefab.LoadAll(GetFilesOfType(ContentType.Jobs));
// Add any missing jobs from the prefab into Config.JobNamePreferences.
foreach (string job in JobPrefab.List.Keys)
{
if (!Config.JobPreferences.Contains(job)) { Config.JobPreferences.Add(job); }
}
NPCConversation.LoadAll(GetFilesOfType(ContentType.NPCConversations));
@@ -779,7 +778,17 @@ namespace Barotrauma
}
}
GUI.ClearUpdateList();
#if DEBUG
if (GameMain.NetworkMember == null)
{
if (PlayerInput.KeyHit(Keys.P) && !(GUI.KeyboardDispatcher.Subscriber is GUITextBox))
{
DebugConsole.Paused = !DebugConsole.Paused;
}
}
#endif
GUI.ClearUpdateList();
paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen || Tutorial.ContentRunning || DebugConsole.Paused) &&
(NetworkMember == null || !NetworkMember.GameStarted);
@@ -800,7 +809,7 @@ namespace Barotrauma
DebugConsole.AddToGUIUpdateList();
DebugConsole.Update(this, (float)Timing.Step);
DebugConsole.Update((float)Timing.Step);
paused = paused || (DebugConsole.IsOpen && (NetworkMember == null || !NetworkMember.GameStarted));
if (!paused)
@@ -878,6 +887,7 @@ namespace Barotrauma
{
spriteBatch.Begin();
GUI.DrawRectangle(spriteBatch, GUI.MouseOn.MouseRect, Color.Lime);
GUI.DrawRectangle(spriteBatch, GUI.MouseOn.Rect, Color.Cyan);
spriteBatch.End();
}
@@ -887,6 +897,61 @@ namespace Barotrauma
PerformanceCounter.DrawTimeGraph.Update(sw.ElapsedTicks / (float)TimeSpan.TicksPerMillisecond);
}
public static void QuitToMainMenu(bool save, bool showVerificationPrompt)
{
if (showVerificationPrompt)
{
string text = (Screen.Selected is CharacterEditor.CharacterEditorScreen || Screen.Selected is SubEditorScreen) ? "PauseMenuQuitVerificationEditor" : "PauseMenuQuitVerification";
var msgBox = new GUIMessageBox("", TextManager.Get(text), new string[] { TextManager.Get("Yes"), TextManager.Get("Cancel") })
{
UserData = "verificationprompt"
};
msgBox.Buttons[0].OnClicked = (yesBtn, userdata) =>
{
QuitToMainMenu(save);
return true;
};
msgBox.Buttons[0].OnClicked += msgBox.Close;
msgBox.Buttons[1].OnClicked += msgBox.Close;
}
}
public static void QuitToMainMenu(bool save)
{
if (save)
{
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
}
if (GameMain.Client != null)
{
GameMain.Client.Disconnect();
GameMain.Client = null;
}
CoroutineManager.StopCoroutines("EndCinematic");
if (GameMain.GameSession != null)
{
if (Tutorial.Initialized)
{
((TutorialMode)GameMain.GameSession.GameMode).Tutorial?.Stop();
}
if (GameSettings.SendUserStatistics)
{
Mission mission = GameMain.GameSession.Mission;
GameAnalyticsManager.AddDesignEvent("QuitRound:" + (save ? "Save" : "NoSave"));
GameAnalyticsManager.AddDesignEvent("EndRound:" + (mission == null ? "NoMission" : (mission.Completed ? "MissionCompleted" : "MissionFailed")));
}
GameMain.GameSession = null;
}
GUIMessageBox.CloseAll();
GameMain.MainMenuScreen.Select();
}
public void ShowCampaignDisclaimer(Action onContinue = null)
{
var msgBox = new GUIMessageBox(TextManager.Get("CampaignDisclaimerTitle"), TextManager.Get("CampaignDisclaimerText"),
@@ -986,8 +1051,19 @@ namespace Barotrauma
{
if (NetworkMember != null) NetworkMember.Disconnect();
SteamManager.ShutDown();
if (GameSettings.SendUserStatistics) GameAnalytics.OnQuit();
if (GameSettings.SaveDebugConsoleLogs) DebugConsole.SaveLogs();
try
{
SaveUtil.CleanUnnecessarySaveFiles();
}
catch (Exception e)
{
DebugConsole.ThrowError("Error while cleaning unnecessary save files", e);
}
if (GameSettings.SendUserStatistics){ GameAnalytics.OnQuit(); }
if (GameSettings.SaveDebugConsoleLogs) { DebugConsole.SaveLogs(); }
base.OnExiting(sender, args);
}

View File

@@ -116,7 +116,8 @@ namespace Barotrauma
//Spacing = (int)(3 * GUI.Scale),
ScrollBarEnabled = false,
ScrollBarVisible = false,
CanBeFocused = false
CanBeFocused = true,
OnSelected = (component, userdata) => false
};
scrollButtonUp = new GUIButton(new RectTransform(scrollButtonSize, crewArea.RectTransform, Anchor.TopLeft, Pivot.TopLeft), "", Alignment.Center, "GUIButtonVerticalArrow")
@@ -443,6 +444,13 @@ namespace Barotrauma
ToolTip = characterToolTip
};
if (GameMain.GameSession?.GameMode?.Mission is CombatMission combatMission)
{
new GUIFrame(new RectTransform(Vector2.One, characterArea.RectTransform), style: "InnerGlow",
color: character.TeamID == Character.TeamType.Team1 ? Color.SteelBlue : Color.OrangeRed);
}
var characterName = new GUITextBlock(new RectTransform(new Point(characterArea.Rect.Width - characterImage.Rect.Width - soundIcon.Rect.Width - 10, characterArea.Rect.Height),
characterArea.RectTransform, Anchor.CenterRight) { AbsoluteOffset = new Point(soundIcon.Rect.Width + 10, 0) },
character.Name, textColor: frame.Color, font: GUI.SmallFont, wrap: true)
@@ -1016,7 +1024,7 @@ namespace Barotrauma
ToggleCrewAreaOpen = true;
var characterElement = characterListBox.Content.FindChild(character);
GUIButton orderBtn = characterElement.FindChild(order, recursive: true) as GUIButton;
if (orderBtn.Frame.FlashTimer <= 0)
if (orderBtn.FlashTimer <= 0)
{
orderBtn.Flash(color, 1.5f, false, flashRectInflate);
}
@@ -1360,7 +1368,7 @@ namespace Barotrauma
public void UpdateReports(float deltaTime)
{
bool canIssueOrders = false;
if (Character.Controlled?.CurrentHull != null && Character.Controlled.SpeechImpediment < 100.0f)
if (Character.Controlled?.CurrentHull?.Submarine != null && Character.Controlled.SpeechImpediment < 100.0f)
{
WifiComponent radio = GetHeadset(Character.Controlled, true);
canIssueOrders = radio != null && radio.CanTransmit();

View File

@@ -4,6 +4,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Barotrauma.Extensions;
namespace Barotrauma
{
@@ -13,25 +14,24 @@ namespace Barotrauma
private UInt16 startWatchmanID, endWatchmanID;
public static GUIComponent StartCampaignSetup( IEnumerable<Submarine> submarines, IEnumerable<string> saveFiles)
public static void StartCampaignSetup(IEnumerable<string> saveFiles)
{
GUIFrame background = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), style: "GUIBackgroundBlocker");
var parent = GameMain.NetLobbyScreen.CampaignSetupFrame;
parent.ClearChildren();
parent.Visible = true;
GameMain.NetLobbyScreen.HighlightMode(2);
GUIFrame setupBox = new GUIFrame(new RectTransform(new Vector2(0.25f, 0.45f), background.RectTransform, Anchor.Center) { MinSize = new Point(500, 550) });
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), setupBox.RectTransform, Anchor.Center))
var layout = new GUILayoutGroup(new RectTransform(Vector2.One, parent.RectTransform, Anchor.Center))
{
Stretch = true
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), paddedFrame.RectTransform,Anchor.TopCenter),
TextManager.Get("CampaignSetup"), font: GUI.LargeFont);
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.07f), paddedFrame.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.1f) }, isHorizontal: true)
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.07f), layout.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.1f) }, isHorizontal: true)
{
RelativeSpacing = 0.02f
};
var campaignContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.9f), paddedFrame.RectTransform, Anchor.BottomLeft), style: "InnerFrame")
var campaignContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.9f), layout.RectTransform, Anchor.BottomLeft), style: "InnerFrame")
{
CanBeFocused = false
};
@@ -39,9 +39,9 @@ namespace Barotrauma
var newCampaignContainer = new GUIFrame(new RectTransform(Vector2.One, campaignContainer.RectTransform, Anchor.BottomLeft), style: null);
var loadCampaignContainer = new GUIFrame(new RectTransform(Vector2.One, campaignContainer.RectTransform, Anchor.BottomLeft), style: null);
var campaignSetupUI = new CampaignSetupUI(true, newCampaignContainer, loadCampaignContainer, submarines, saveFiles);
var campaignSetupUI = new CampaignSetupUI(true, newCampaignContainer, loadCampaignContainer, null, saveFiles);
var newCampaignButton = new GUIButton(new RectTransform(new Vector2(0.3f, 1.0f), buttonContainer.RectTransform),
var newCampaignButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), buttonContainer.RectTransform),
TextManager.Get("NewCampaign"), style: "GUITabButton")
{
OnClicked = (btn, obj) =>
@@ -52,7 +52,7 @@ namespace Barotrauma
}
};
var loadCampaignButton = new GUIButton(new RectTransform(new Vector2(0.3f, 1.00f), buttonContainer.RectTransform),
var loadCampaignButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1.00f), buttonContainer.RectTransform),
TextManager.Get("LoadCampaign"), style: "GUITabButton")
{
OnClicked = (btn, obj) =>
@@ -67,20 +67,6 @@ namespace Barotrauma
campaignSetupUI.StartNewGame = GameMain.Client.SetupNewCampaign;
campaignSetupUI.LoadGame = GameMain.Client.SetupLoadCampaign;
var cancelButton = new GUIButton(new RectTransform(new Vector2(0.25f, 0.1f), paddedFrame.RectTransform, Anchor.BottomLeft),
TextManager.Get("Cancel"), style: "GUIButtonLarge")
{
IgnoreLayoutGroups = true,
OnClicked = (btn, obj) =>
{
background.Visible = false;
return true;
}
};
return background;
}
public override void Update(float deltaTime)

View File

@@ -255,9 +255,9 @@ namespace Barotrauma.Tutorials
}
if (order.Options[orderIndex] == option)
{
if (GameMain.GameSession.CrewManager.OrderOptionButtons[i].Frame.FlashTimer <= 0)
if (GameMain.GameSession.CrewManager.OrderOptionButtons[i].FlashTimer <= 0)
{
GameMain.GameSession.CrewManager.OrderOptionButtons[i].Frame.Flash(highlightColor);
GameMain.GameSession.CrewManager.OrderOptionButtons[i].Flash(highlightColor);
}
}

View File

@@ -370,9 +370,9 @@ namespace Barotrauma.Tutorials
}
else if (IsSelectedItem(engineer_brokenJunctionBox) && repairableJunctionBoxComponent.CurrentFixer == null)
{
if (repairableJunctionBoxComponent.RepairButton.Frame.FlashTimer <= 0)
if (repairableJunctionBoxComponent.RepairButton.FlashTimer <= 0)
{
repairableJunctionBoxComponent.RepairButton.Frame.Flash();
repairableJunctionBoxComponent.RepairButton.Flash();
}
}
yield return null;

View File

@@ -416,9 +416,9 @@ namespace Barotrauma.Tutorials
if (mechanic_deconstructor.InputContainer.Inventory.FindItemByIdentifier("oxygentank") != null && !mechanic_deconstructor.IsActive)
{
if (mechanic_deconstructor.ActivateButton.Frame.FlashTimer <= 0)
if (mechanic_deconstructor.ActivateButton.FlashTimer <= 0)
{
mechanic_deconstructor.ActivateButton.Frame.Flash(highlightColor, 1.5f, false);
mechanic_deconstructor.ActivateButton.Flash(highlightColor, 1.5f, false);
}
}
}
@@ -452,9 +452,9 @@ namespace Barotrauma.Tutorials
}
else if (mechanic_fabricator.InputContainer.Inventory.FindItemByIdentifier("aluminium") != null && mechanic_fabricator.InputContainer.Inventory.FindItemByIdentifier("sodium") != null && !mechanic_fabricator.IsActive)
{
if (mechanic_fabricator.ActivateButton.Frame.FlashTimer <= 0)
if (mechanic_fabricator.ActivateButton.FlashTimer <= 0)
{
mechanic_fabricator.ActivateButton.Frame.Flash(highlightColor, 1.5f, false);
mechanic_fabricator.ActivateButton.Flash(highlightColor, 1.5f, false);
}
}
else if (mechanic.Inventory.FindItemByIdentifier("aluminium") != null || mechanic.Inventory.FindItemByIdentifier("sodium") != null)
@@ -544,9 +544,9 @@ namespace Barotrauma.Tutorials
}
else if (IsSelectedItem(mechanic_brokenPump.Item) && repairablePumpComponent.CurrentFixer == null)
{
if (repairablePumpComponent.RepairButton.Frame.FlashTimer <= 0)
if (repairablePumpComponent.RepairButton.FlashTimer <= 0)
{
repairablePumpComponent.RepairButton.Frame.Flash();
repairablePumpComponent.RepairButton.Flash();
}
}
}

View File

@@ -18,6 +18,11 @@ namespace Barotrauma
private bool ToggleInfoFrame()
{
if (GameMain.NetworkMember != null && GameMain.NetLobbyScreen != null)
{
if (GameMain.NetLobbyScreen.HeadSelectionList != null) { GameMain.NetLobbyScreen.HeadSelectionList.Visible = false; }
if (GameMain.NetLobbyScreen.JobSelectionFrame != null) { GameMain.NetLobbyScreen.JobSelectionFrame.Visible = false; }
}
if (infoFrame == null)
{
CreateInfoFrame();
@@ -37,7 +42,7 @@ namespace Barotrauma
infoFrame = new GUIButton(new RectTransform(Vector2.One, GUI.Canvas), style: "GUIBackgroundBlocker");
var innerFrame = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.35f), infoFrame.RectTransform, Anchor.Center) { MinSize = new Point(width, height) });
var innerFrame = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.35f), infoFrame.RectTransform, Anchor.Center) { MinSize = new Point(width, height), RelativeOffset = new Vector2(0.0f, 0.033f) });
var paddedFrame = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.9f), innerFrame.RectTransform, Anchor.Center), style: null);
var buttonArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.08f), paddedFrame.RectTransform), isHorizontal: true)
@@ -144,6 +149,12 @@ namespace Barotrauma
if (GUI.DisableHUD) return;
GameMode?.AddToGUIUpdateList();
infoFrame?.AddToGUIUpdateList();
if (GameMain.NetworkMember != null)
{
GameMain.NetLobbyScreen?.HeadSelectionList?.AddToGUIUpdateList();
GameMain.NetLobbyScreen?.JobSelectionFrame?.AddToGUIUpdateList();
}
}
partial void UpdateProjSpecific(float deltaTime)
@@ -163,7 +174,24 @@ namespace Barotrauma
ToggleInfoFrame();
}
infoFrame?.UpdateManually(deltaTime);
if (GameMain.NetworkMember != null)
{
if (GameMain.NetLobbyScreen?.HeadSelectionList != null)
{
if (PlayerInput.LeftButtonDown() && !GUI.IsMouseOn(GameMain.NetLobbyScreen.HeadSelectionList))
{
if (GameMain.NetLobbyScreen.HeadSelectionList != null) { GameMain.NetLobbyScreen.HeadSelectionList.Visible = false; }
}
}
if (GameMain.NetLobbyScreen?.JobSelectionFrame != null)
{
if (PlayerInput.LeftButtonDown() && !GUI.IsMouseOn(GameMain.NetLobbyScreen.JobSelectionFrame))
{
GameMain.NetLobbyScreen.JobList.Deselect();
if (GameMain.NetLobbyScreen.JobSelectionFrame != null) { GameMain.NetLobbyScreen.JobSelectionFrame.Visible = false; }
}
}
}
}
public void Draw(SpriteBatch spriteBatch)
@@ -171,7 +199,7 @@ namespace Barotrauma
if (GUI.DisableHUD) return;
GameMode?.Draw(spriteBatch);
infoFrame?.DrawManually(spriteBatch);
//infoFrame?.DrawManually(spriteBatch);
}
}
}

View File

@@ -152,8 +152,7 @@ namespace Barotrauma
var languageDD = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.045f), generalLayoutGroup.RectTransform));
foreach (string language in TextManager.AvailableLanguages)
{
//TODO: display the name of the language in the target language?
languageDD.AddItem(language, language);
languageDD.AddItem(TextManager.GetTranslatedLanguageName(language), language);
}
languageDD.SelectItem(TextManager.Language);
languageDD.OnSelected = (guiComponent, obj) =>
@@ -356,7 +355,7 @@ namespace Barotrauma
};
lightScrollBar.OnMoved(lightScrollBar, lightScrollBar.BarScroll);
new GUITickBox(new RectTransform(tickBoxScale, rightColumn.RectTransform, scaleBasis: ScaleBasis.BothHeight), TextManager.Get("SpecularLighting"))
/*new GUITickBox(new RectTransform(tickBoxScale, rightColumn.RectTransform, scaleBasis: ScaleBasis.BothHeight), TextManager.Get("SpecularLighting"))
{
ToolTip = TextManager.Get("SpecularLightingToolTip"),
Selected = SpecularityEnabled,
@@ -366,7 +365,7 @@ namespace Barotrauma
UnsavedSettings = true;
return true;
}
};
};*/
new GUITickBox(new RectTransform(tickBoxScale, rightColumn.RectTransform, scaleBasis: ScaleBasis.BothHeight), TextManager.Get("ChromaticAberration"))
{
@@ -508,8 +507,8 @@ namespace Barotrauma
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), voipSettings.RectTransform), TextManager.Get("VoiceChat"));
IList<string> deviceNames = Alc.GetStringList((IntPtr)null, Alc.CaptureDeviceSpecifier);
foreach (string name in deviceNames)
CaptureDeviceNames = Alc.GetStringList((IntPtr)null, Alc.CaptureDeviceSpecifier);
foreach (string name in CaptureDeviceNames)
{
DebugConsole.NewMessage(name + " " + name.Length.ToString(), Color.Lime);
}
@@ -524,19 +523,19 @@ namespace Barotrauma
return true;
};
if (string.IsNullOrWhiteSpace(VoiceCaptureDevice) || !(deviceNames?.Contains(VoiceCaptureDevice) ?? false))
if (string.IsNullOrWhiteSpace(VoiceCaptureDevice) || !(CaptureDeviceNames?.Contains(VoiceCaptureDevice) ?? false))
{
VoiceCaptureDevice = deviceNames?.Count > 0 ? deviceNames[0] : null;
VoiceCaptureDevice = CaptureDeviceNames?.Count > 0 ? CaptureDeviceNames[0] : null;
}
if (string.IsNullOrWhiteSpace(VoiceCaptureDevice))
{
VoiceSetting = VoiceMode.Disabled;
}
#if (!OSX)
var deviceList = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.15f), voipSettings.RectTransform), TrimAudioDeviceName(VoiceCaptureDevice), deviceNames.Count);
if (deviceNames?.Count > 0)
var deviceList = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.15f), voipSettings.RectTransform), TrimAudioDeviceName(VoiceCaptureDevice), CaptureDeviceNames.Count);
if (CaptureDeviceNames?.Count > 0)
{
foreach (string name in deviceNames)
foreach (string name in CaptureDeviceNames)
{
deviceList.AddItem(TrimAudioDeviceName(name), name);
}
@@ -571,12 +570,12 @@ namespace Barotrauma
ToolTip = TextManager.Get("RefreshDefaultDeviceToolTip"),
OnClicked = (bt, userdata) =>
{
deviceNames = Alc.GetStringList((IntPtr)null, Alc.CaptureDeviceSpecifier);
if (deviceNames?.Count > 0)
CaptureDeviceNames = Alc.GetStringList((IntPtr)null, Alc.CaptureDeviceSpecifier);
if (CaptureDeviceNames?.Count > 0)
{
if (VoiceCaptureDevice == deviceNames[0]) return true;
if (VoiceCaptureDevice == CaptureDeviceNames[0]) return true;
VoipCapture.ChangeCaptureDevice(deviceNames[0]);
VoipCapture.ChangeCaptureDevice(CaptureDeviceNames[0]);
currentDeviceTextBlock.Text = TextManager.AddPunctuation(':', TextManager.Get("CurrentDevice"), TrimAudioDeviceName(VoiceCaptureDevice));
currentDeviceTextBlock.Flash(Color.Blue);
}
@@ -598,12 +597,12 @@ namespace Barotrauma
for (int i = 0; i < 3; i++)
{
string langStr = "VoiceMode." + ((VoiceMode)i).ToString();
var tick = new GUITickBox(new RectTransform(tickBoxScale / 0.4f, voipSettings.RectTransform, scaleBasis: ScaleBasis.BothHeight), TextManager.Get(langStr))
var tick = new GUITickBox(new RectTransform(tickBoxScale / 0.4f, voipSettings.RectTransform, scaleBasis: ScaleBasis.BothHeight), TextManager.Get(langStr), style: "GUIRadioButton")
{
ToolTip = TextManager.Get(langStr + "ToolTip")
};
voiceMode.AddRadioButton((VoiceMode)i, tick);
voiceMode.AddRadioButton(i, tick);
}
var micVolumeText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), voipSettings.RectTransform), TextManager.Get("MicrophoneVolume"));
@@ -611,10 +610,10 @@ namespace Barotrauma
barSize: 0.05f)
{
UserData = micVolumeText,
BarScroll = (float)Math.Sqrt(MathUtils.InverseLerp(0.2f, 5.0f, MicrophoneVolume)),
BarScroll = (float)Math.Sqrt(MathUtils.InverseLerp(0.2f, MaxMicrophoneVolume, MicrophoneVolume)),
OnMoved = (scrollBar, scroll) =>
{
MicrophoneVolume = MathHelper.Lerp(0.2f, 10.0f, scroll * scroll);
MicrophoneVolume = MathHelper.Lerp(0.2f, MaxMicrophoneVolume, scroll * scroll);
MicrophoneVolume = (float)Math.Round(MicrophoneVolume, 1);
ChangeSliderText(scrollBar, MicrophoneVolume);
scrollBar.Step = 0.05f;
@@ -667,7 +666,7 @@ namespace Barotrauma
return true;
};
voiceMode.OnSelect = (GUIRadioButtonGroup rbg, Enum value) =>
voiceMode.OnSelect = (GUIRadioButtonGroup rbg, int? value) =>
{
if (rbg.Selected != null && rbg.Selected.Equals(value)) return;
try
@@ -708,7 +707,7 @@ namespace Barotrauma
VoiceSetting = VoiceMode.Disabled;
}
};
voiceMode.Selected = VoiceSetting;
voiceMode.Selected = (int)VoiceSetting;
if (string.IsNullOrWhiteSpace(VoiceCaptureDevice))
{
voiceMode.Enabled = false;
@@ -1157,7 +1156,7 @@ namespace Barotrauma
{
ApplySettings();
if (Screen.Selected != GameMain.MainMenuScreen) GUI.SettingsMenuOpen = false;
if (contentPackageSelectionDirty)
if (contentPackageSelectionDirty || ContentPackage.List.Any(cp => cp.NeedsRestart))
{
new GUIMessageBox(TextManager.Get("RestartRequiredLabel"), TextManager.Get("RestartRequiredGeneric"));
}

View File

@@ -718,11 +718,11 @@ namespace Barotrauma
if (item.ParentInventory != this)
{
//in another inventory -> attempt to place in the character's inventory
if (item.ParentInventory.Locked || item.ParentInventory == null)
if (item.ParentInventory == null || item.ParentInventory.Locked)
{
return QuickUseAction.None;
}
//in another inventory -> attempt to place in the character's inventory
else if (allowInventorySwap)
{
if (item.Container == null || character.Inventory.FindIndex(item.Container) == -1) // Not a subinventory in the character's inventory

View File

@@ -64,6 +64,10 @@ namespace Barotrauma.Items.Components
[Serialize(null, false, description: "An optional text displayed above the item's inventory.")]
public string UILabel { get; set; }
[Serialize(true, false, description: "Should an indicator displaying the state of the contained items be displayed on this item's inventory slot. "+
"If this item can only contain one item, the indicator will display the condition of the contained item, otherwise it will indicate how full the item is.")]
public bool ShowContainedStateIndicator { get; set; }
[Serialize(false, false, description: "If enabled, the condition of this item is displayed in the indicator that would normally show the state of the contained items." +
" May be useful for items such as ammo boxes and magazines that spawn projectiles as needed," +
" and use the condition to determine how many projectiles can be spawned in total.")]

View File

@@ -38,7 +38,7 @@ namespace Barotrauma.Items.Components
private void ToggleCrewArea(bool value, bool storeOriginalState)
{
var crewManager = GameMain.GameSession.CrewManager;
var crewManager = GameMain.GameSession?.CrewManager;
if (crewManager == null) { return; }
if (storeOriginalState)
@@ -50,7 +50,7 @@ namespace Barotrauma.Items.Components
private void ToggleChatBox(bool value, bool storeOriginalState)
{
var crewManager = GameMain.GameSession.CrewManager;
var crewManager = GameMain.GameSession?.CrewManager;
if (crewManager == null) { return; }
if (crewManager.IsSinglePlayer)

View File

@@ -114,7 +114,7 @@ namespace Barotrauma.Items.Components
private void DrawHUDFront(SpriteBatch spriteBatch, GUICustomComponent container)
{
if (voltage < minVoltage)
if (Voltage < MinVoltage)
{
Vector2 textSize = GUI.Font.MeasureString(noPowerTip);
Vector2 textPos = GuiFrame.Rect.Center.ToVector2();
@@ -164,7 +164,7 @@ namespace Barotrauma.Items.Components
}
}
if (voltage < minVoltage)
if (Voltage < MinVoltage)
{
return;
}

View File

@@ -128,6 +128,7 @@ namespace Barotrauma.Items.Components
public override void OnItemLoaded()
{
base.OnItemLoaded();
if (pumpSpeedSlider != null)
{
pumpSpeedSlider.BarScroll = (flowPercentage + 100.0f) / 200.0f;

View File

@@ -290,6 +290,7 @@ namespace Barotrauma.Items.Components
public override void OnItemLoaded()
{
base.OnItemLoaded();
turbineOutputScrollBar.BarScroll = targetTurbineOutput / 100.0f;
fissionRateScrollBar.BarScroll = targetFissionRate / 100.0f;
var itemContainer = item.GetComponent<ItemContainer>();
@@ -604,14 +605,15 @@ namespace Barotrauma.Items.Components
protected override void RemoveComponentSpecific()
{
graphLine.Remove();
fissionRateMeter.Remove();
turbineOutputMeter.Remove();
meterPointer.Remove();
sectorSprite.Remove();
tempMeterFrame.Remove();
tempMeterBar.Remove();
tempRangeIndicator.Remove();
base.RemoveComponentSpecific();
graphLine?.Remove();
fissionRateMeter?.Remove();
turbineOutputMeter?.Remove();
meterPointer?.Remove();
sectorSprite?.Remove();
tempMeterFrame?.Remove();
tempMeterBar?.Remove();
tempRangeIndicator?.Remove();
}
public void ClientWrite(IWriteMessage msg, object[] extraData = null)

View File

@@ -54,7 +54,7 @@ namespace Barotrauma.Items.Components
//float = strength of the disruption, between 0-1
List<Pair<Vector2, float>> disruptedDirections = new List<Pair<Vector2, float>>();
private static Color[] blipColorGradient =
private static readonly Color[] blipColorGradient =
{
Color.TransparentBlack,
new Color(0, 50, 160),
@@ -162,9 +162,9 @@ namespace Barotrauma.Items.Components
signalWarningText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), paddedControlContainer.RectTransform), "", Color.Orange, textAlignment: Alignment.Center);
GUIRadioButtonGroup sonarMode = new GUIRadioButtonGroup();
sonarMode.AddRadioButton(Mode.Active, activeTickBox);
sonarMode.AddRadioButton(Mode.Passive, passiveTickBox);
sonarMode.Selected = Mode.Passive;
sonarMode.AddRadioButton((int)Mode.Active, activeTickBox);
sonarMode.AddRadioButton((int)Mode.Passive, passiveTickBox);
sonarMode.Selected = (int)Mode.Passive;
GuiFrame.CanBeFocused = false;
@@ -226,6 +226,7 @@ namespace Barotrauma.Items.Components
public override void OnItemLoaded()
{
base.OnItemLoaded();
zoomSlider.BarScroll = MathUtils.InverseLerp(MinZoom, MaxZoom, zoom);
//make the sonarView customcomponent render the steering view so it gets drawn in front of the sonar
item.GetComponent<Steering>()?.AttachToSonarHUD(sonarView);
@@ -434,7 +435,7 @@ namespace Barotrauma.Items.Components
if (distSqr > t.SoundRange * t.SoundRange * 2) { continue; }
float dist = (float)Math.Sqrt(distSqr);
if (dist > prevPassivePingRadius * Range && dist <= passivePingRadius * Range)
if (dist > prevPassivePingRadius * Range && dist <= passivePingRadius * Range && Rand.Int(sonarBlips.Count) < 500)
{
Ping(t.WorldPosition, transducerCenter,
Math.Min(t.SoundRange, range * 0.5f) * displayScale, 0, displayScale, Math.Min(t.SoundRange, range * 0.5f),
@@ -675,14 +676,14 @@ namespace Barotrauma.Items.Components
}
else if (startOutside)
{
if (MathUtils.GetLineCircleIntersections(Vector2.Zero, DisplayRadius, end, start, true, out Vector2? intersection1, out Vector2? intersection2) == 1)
if (MathUtils.GetLineCircleIntersections(Vector2.Zero, DisplayRadius, end, start, true, out Vector2? intersection1, out _) == 1)
{
DrawLineSprite(spriteBatch, center + intersection1.Value, center + end, color, width: width);
}
}
else if (endOutside)
{
if (MathUtils.GetLineCircleIntersections(Vector2.Zero, DisplayRadius, start, end, true, out Vector2? intersection1, out Vector2? intersection2) == 1)
if (MathUtils.GetLineCircleIntersections(Vector2.Zero, DisplayRadius, start, end, true, out Vector2? intersection1, out _) == 1)
{
DrawLineSprite(spriteBatch, center + start, center + intersection1.Value, color, width: width);
}
@@ -750,7 +751,7 @@ namespace Barotrauma.Items.Components
{
size.Y = 0.0f;
}
GUI.DrawLine(spriteBatch, center + offset - size, center + offset + size, Color.LightGreen, width: (int)(zoom * 2.5f));
GUI.DrawLine(spriteBatch, center + offset - size, center + offset + size, Color.LightGreen * signalStrength, width: (int)(zoom * 2.5f));
}
}
@@ -769,8 +770,6 @@ namespace Barotrauma.Items.Components
Vector2 targetPortDiff = (steering.DockingTarget.Item.WorldPosition - transducerCenter) * scale;
Vector2 targetPortPos = new Vector2(targetPortDiff.X, -targetPortDiff.Y);
Vector2 midPos = (sourcePortPos + targetPortPos) / 2.0f;
System.Diagnostics.Debug.Assert(steering.ActiveDockingSource.IsHorizontal == steering.DockingTarget.IsHorizontal);
Vector2 diff = steering.DockingTarget.Item.WorldPosition - steering.ActiveDockingSource.Item.WorldPosition;
float dist = diff.Length();
@@ -851,7 +850,6 @@ namespace Barotrauma.Items.Components
private void UpdateDisruptions(Vector2 pingSource, float worldPingRadius, float worldPrevPingRadius)
{
float worldPingRadiusSqr = worldPingRadius * worldPingRadius;
float worldPrevPingRadiusSqr = worldPrevPingRadius * worldPrevPingRadius;
disruptedDirections.Clear();
if (Level.Loaded == null) { return; }

View File

@@ -159,9 +159,9 @@ namespace Barotrauma.Items.Components
};
GUIRadioButtonGroup modes = new GUIRadioButtonGroup();
modes.AddRadioButton(Mode.AutoPilot, autopilotTickBox);
modes.AddRadioButton(Mode.Manual, manualTickBox);
modes.Selected = Mode.Manual;
modes.AddRadioButton((int)Mode.AutoPilot, autopilotTickBox);
modes.AddRadioButton((int)Mode.Manual, manualTickBox);
modes.Selected = (int)Mode.Manual;
var autoPilotControls = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.6f), paddedControlContainer.RectTransform), "InnerFrame");
var paddedAutoPilotControls = new GUILayoutGroup(new RectTransform(new Vector2(0.8f), autoPilotControls.RectTransform, Anchor.Center))
@@ -171,7 +171,7 @@ namespace Barotrauma.Items.Components
};
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, style: "GUIRadioButton")
{
Enabled = false,
Selected = maintainPos,
@@ -208,7 +208,7 @@ namespace Barotrauma.Items.Components
levelStartTickBox = new GUITickBox(new RectTransform(new Vector2(0.2f, 0.2f), paddedAutoPilotControls.RectTransform),
GameMain.GameSession?.StartLocation == null ? "" : ToolBox.LimitString(GameMain.GameSession.StartLocation.Name, 20),
font: GUI.SmallFont)
font: GUI.SmallFont, style: "GUIRadioButton")
{
Enabled = false,
Selected = levelStartSelected,
@@ -235,7 +235,7 @@ namespace Barotrauma.Items.Components
levelEndTickBox = new GUITickBox(new RectTransform(new Vector2(0.2f, 0.2f), paddedAutoPilotControls.RectTransform),
GameMain.GameSession?.EndLocation == null ? "" : ToolBox.LimitString(GameMain.GameSession.EndLocation.Name, 20),
font: GUI.SmallFont)
font: GUI.SmallFont, style: "GUIRadioButton")
{
Enabled = false,
Selected = levelEndSelected,
@@ -263,11 +263,11 @@ namespace Barotrauma.Items.Components
autoPilotControlsDisabler = new GUIFrame(new RectTransform(Vector2.One, autoPilotControls.RectTransform), "InnerFrame");
GUIRadioButtonGroup destinations = new GUIRadioButtonGroup();
destinations.AddRadioButton(Destination.MaintainPos, maintainPosTickBox);
destinations.AddRadioButton(Destination.LevelStart, levelStartTickBox);
destinations.AddRadioButton(Destination.LevelEnd, levelEndTickBox);
destinations.Selected = maintainPos ? Destination.MaintainPos :
levelStartSelected ? Destination.LevelStart : Destination.LevelEnd;
destinations.AddRadioButton((int)Destination.MaintainPos, maintainPosTickBox);
destinations.AddRadioButton((int)Destination.LevelStart, levelStartTickBox);
destinations.AddRadioButton((int)Destination.LevelEnd, levelEndTickBox);
destinations.Selected = (int)(maintainPos ? Destination.MaintainPos :
levelStartSelected ? Destination.LevelStart : Destination.LevelEnd);
string steeringVelX = TextManager.Get("SteeringVelocityX");
string steeringVelY = TextManager.Get("SteeringVelocityY");
@@ -442,7 +442,7 @@ namespace Barotrauma.Items.Components
int x = rect.X;
int y = rect.Y;
if (voltage < minVoltage && currPowerConsumption > 0.0f) return;
if (Voltage < MinVoltage) { return; }
Rectangle velRect = new Rectangle(x + 20, y + 20, width - 40, height - 40);
Vector2 displaySubPos = (-sonar.DisplayOffset * sonar.Zoom) / sonar.Range * sonar.DisplayRadius * sonar.Zoom;
@@ -649,7 +649,7 @@ namespace Barotrauma.Items.Components
autoPilotControlsDisabler.Visible = !AutoPilot;
if (voltage < minVoltage && currPowerConsumption > 0.0f)
if (Voltage < MinVoltage)
{
tipContainer.Visible = true;
tipContainer.Text = noPowerTip;
@@ -819,6 +819,7 @@ namespace Barotrauma.Items.Components
protected override void RemoveComponentSpecific()
{
base.RemoveComponentSpecific();
maintainPosIndicator?.Remove();
maintainPosOriginIndicator?.Remove();
steeringIndicator?.Remove();

View File

@@ -80,6 +80,7 @@ namespace Barotrauma.Items.Components
public override void OnItemLoaded()
{
base.OnItemLoaded();
if (rechargeSpeedSlider != null)
{
rechargeSpeedSlider.BarScroll = rechargeSpeed / MaxRechargeSpeed;

View File

@@ -1,5 +1,6 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
@@ -46,19 +47,26 @@ namespace Barotrauma.Items.Components
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.2f), textContainer.RectTransform), "", textColor: Color.LightGreen)
{
ToolTip = TextManager.Get("PowerTransferTipPower"),
TextGetter = () => { return powerStr.Replace("[power]", ((int)(-currPowerConsumption)).ToString()); }
TextGetter = () => { return powerStr.Replace("[power]", ((int)Math.Round(-currPowerConsumption)).ToString()); }
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), textContainer.RectTransform),
TextManager.Get("PowerTransferLoadLabel"), font: GUI.LargeFont)
{
ToolTip = TextManager.Get("PowerTransferTipLoad")
};
string loadStr = TextManager.Get("PowerTransferLoad");
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.2f), textContainer.RectTransform), "", textColor: Color.LightBlue)
{
ToolTip = TextManager.Get("PowerTransferTipLoad"),
TextGetter = () => { return loadStr.Replace("[load]", ((int)(powerLoad)).ToString()); }
TextGetter = () =>
{
return loadStr.Replace("[load]",
this is RelayComponent relay ?
((int)Math.Round(relay.DisplayLoad)).ToString() :
((int)Math.Round(powerLoad)).ToString());
}
};
}

View File

@@ -5,6 +5,7 @@ using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
@@ -12,32 +13,34 @@ namespace Barotrauma.Items.Components
{
partial class WireSection
{
public void Draw(SpriteBatch spriteBatch, Color color, Vector2 offset, float depth, float width = 0.3f)
public void Draw(SpriteBatch spriteBatch, Wire wire, Color color, Vector2 offset, float depth, float width = 0.3f)
{
spriteBatch.Draw(wireSprite.Texture,
spriteBatch.Draw(wire.wireSprite.Texture,
new Vector2(start.X + offset.X, -(start.Y + offset.Y)), null, color,
-angle,
new Vector2(0.0f, wireSprite.size.Y / 2.0f),
new Vector2(length / wireSprite.Texture.Width, width),
new Vector2(0.0f, wire.wireSprite.size.Y / 2.0f),
new Vector2(length / wire.wireSprite.Texture.Width, width),
SpriteEffects.None,
depth);
}
public static void Draw(SpriteBatch spriteBatch, Vector2 start, Vector2 end, Color color, float depth, float width = 0.3f)
public static void Draw(SpriteBatch spriteBatch, Wire wire, Vector2 start, Vector2 end, Color color, float depth, float width = 0.3f)
{
start.Y = -start.Y;
end.Y = -end.Y;
spriteBatch.Draw(wireSprite.Texture,
spriteBatch.Draw(wire.wireSprite.Texture,
start, null, color,
MathUtils.VectorToAngle(end - start),
new Vector2(0.0f, wireSprite.size.Y / 2.0f),
new Vector2((Vector2.Distance(start, end)) / wireSprite.Texture.Width, width),
new Vector2(0.0f, wire.wireSprite.size.Y / 2.0f),
new Vector2((Vector2.Distance(start, end)) / wire.wireSprite.Texture.Width, width),
SpriteEffects.None,
depth);
}
}
private static Sprite wireSprite;
private static Sprite defaultWireSprite;
private Sprite overrideSprite;
private Sprite wireSprite;
private static Wire draggingWire;
private static int? selectedNodeIndex;
@@ -48,6 +51,28 @@ namespace Barotrauma.Items.Components
get { return sectionExtents; }
}
partial void InitProjSpecific(XElement element)
{
if (defaultWireSprite == null)
{
defaultWireSprite = new Sprite("Content/Items/wireHorizontal.png", new Vector2(0.5f, 0.5f))
{
Depth = 0.85f
};
}
foreach (XElement subElement in element.Elements())
{
if (subElement.Name.ToString().ToLowerInvariant() == "wiresprite")
{
overrideSprite = new Sprite(subElement);
break;
}
}
wireSprite = overrideSprite ?? defaultWireSprite;
}
public void Draw(SpriteBatch spriteBatch, bool editing, float itemDepth = -1)
{
if (sections.Count == 0 && !IsActive || Hidden)
@@ -75,20 +100,20 @@ namespace Barotrauma.Items.Components
{
foreach (WireSection section in sections)
{
section.Draw(spriteBatch, Color.Gold, drawOffset, depth + 0.00001f, 0.7f);
section.Draw(spriteBatch, this, Color.Gold, drawOffset, depth + 0.00001f, 0.7f);
}
}
else if (item.IsSelected)
{
foreach (WireSection section in sections)
{
section.Draw(spriteBatch, Color.Red, drawOffset, depth + 0.00001f, 0.7f);
section.Draw(spriteBatch, this, Color.Red, drawOffset, depth + 0.00001f, 0.7f);
}
}
foreach (WireSection section in sections)
{
section.Draw(spriteBatch, item.Color, drawOffset, depth, 0.3f);
section.Draw(spriteBatch, this, item.Color, drawOffset, depth, 0.3f);
}
if (nodes.Count > 0)
@@ -101,7 +126,8 @@ namespace Barotrauma.Items.Components
if (IsActive && Vector2.Distance(newNodePos, nodes[nodes.Count - 1]) > nodeDistance)
{
WireSection.Draw(
spriteBatch,
spriteBatch,
this,
new Vector2(nodes[nodes.Count - 1].X, nodes[nodes.Count - 1].Y) + drawOffset,
new Vector2(newNodePos.X, newNodePos.Y) + drawOffset,
item.Color * 0.5f,
@@ -141,12 +167,12 @@ namespace Barotrauma.Items.Components
Vector2 endPos = start + new Vector2((float)Math.Sin(angle), -(float)Math.Cos(angle)) * 50.0f;
WireSection.Draw(
spriteBatch,
spriteBatch, this,
start, endPos,
Color.Orange, depth + 0.00001f, 0.2f);
WireSection.Draw(
spriteBatch,
spriteBatch, this,
start, start + (endPos - start) * 0.7f,
item.Color, depth, 0.3f);
}

View File

@@ -993,7 +993,7 @@ namespace Barotrauma
Color.Lerp(Color.Red, Color.Green, item.Condition / item.MaxCondition) * 0.8f, true);
}
if (itemContainer != null)
if (itemContainer != null && itemContainer.ShowContainedStateIndicator)
{
float containedState = 0.0f;
if (itemContainer.ShowConditionInContainedStateIndicator)
@@ -1156,7 +1156,7 @@ namespace Barotrauma
private void ApplyReceivedState()
{
if (receivedItemIDs == null) return;
if (receivedItemIDs == null || (Owner != null && Owner.Removed)) { return; }
for (int i = 0; i < capacity; i++)
{
@@ -1171,7 +1171,7 @@ namespace Barotrauma
{
if (receivedItemIDs[i] > 0)
{
if (!(Entity.FindEntityByID(receivedItemIDs[i]) is Item item) || Items[i] == item) continue;
if (!(Entity.FindEntityByID(receivedItemIDs[i]) is Item item) || Items[i] == item) { continue; }
TryPutItem(item, i, true, true, null, false);
for (int j = 0; j < capacity; j++)

View File

@@ -19,7 +19,7 @@ namespace Barotrauma
private readonly List<PosInfo> positionBuffer = new List<PosInfo>();
private List<ItemComponent> activeHUDs = new List<ItemComponent>();
private readonly List<ItemComponent> activeHUDs = new List<ItemComponent>();
public IEnumerable<ItemComponent> ActiveHUDs => activeHUDs;
@@ -230,9 +230,6 @@ namespace Barotrauma
if (body == null)
{
bool flipHorizontal = (SpriteEffects & SpriteEffects.FlipHorizontally) != 0;
bool flipVertical = (SpriteEffects & SpriteEffects.FlipVertically) != 0;
if (prefab.ResizeHorizontal || prefab.ResizeVertical)
{
activeSprite.DrawTiled(spriteBatch, new Vector2(DrawPosition.X - rect.Width / 2, -(DrawPosition.Y + rect.Height / 2)), new Vector2(rect.Width, rect.Height), color: color,
@@ -570,7 +567,7 @@ namespace Barotrauma
}
else
{
if (ic.requiredItems.Count == 0 && SerializableProperty.GetProperties<Editable>(ic).Count == 0) continue;
if (ic.requiredItems.Count == 0 && ic.DisabledRequiredItems.Count == 0 && SerializableProperty.GetProperties<Editable>(ic).Count == 0) continue;
}
var componentEditor = new SerializableEntityEditor(listBox.Content.RectTransform, ic, inGame, showName: !inGame);
@@ -582,37 +579,44 @@ namespace Barotrauma
continue;
}
List<RelatedItem> requiredItems = new List<RelatedItem>();
foreach (var kvp in ic.requiredItems)
{
foreach (RelatedItem relatedItem in kvp.Value)
{
var textBlock = new GUITextBlock(new RectTransform(new Point(editingHUD.Rect.Width, heightScaled)),
relatedItem.Type.ToString() + " required", font: GUI.SmallFont)
{
Padding = new Vector4(10.0f, 0.0f, 10.0f, 0.0f)
};
componentEditor.AddCustomContent(textBlock, 1);
GUITextBox namesBox = new GUITextBox(new RectTransform(new Vector2(0.5f, 1.0f), textBlock.RectTransform, Anchor.CenterRight))
{
Font = GUI.SmallFont,
Text = relatedItem.JoinedIdentifiers
};
namesBox.OnDeselected += (textBox, key) =>
{
relatedItem.JoinedIdentifiers = textBox.Text;
textBox.Text = relatedItem.JoinedIdentifiers;
};
namesBox.OnEnterPressed += (textBox, text) =>
{
relatedItem.JoinedIdentifiers = text;
textBox.Text = relatedItem.JoinedIdentifiers;
return true;
};
requiredItems.Add(relatedItem);
}
}
requiredItems.AddRange(ic.DisabledRequiredItems);
foreach (RelatedItem relatedItem in requiredItems)
{
var textBlock = new GUITextBlock(new RectTransform(new Point(editingHUD.Rect.Width, heightScaled)),
relatedItem.Type.ToString() + " required", font: GUI.SmallFont)
{
Padding = new Vector4(10.0f, 0.0f, 10.0f, 0.0f)
};
componentEditor.AddCustomContent(textBlock, 1);
GUITextBox namesBox = new GUITextBox(new RectTransform(new Vector2(0.5f, 1.0f), textBlock.RectTransform, Anchor.CenterRight))
{
Font = GUI.SmallFont,
Text = relatedItem.JoinedIdentifiers
};
namesBox.OnDeselected += (textBox, key) =>
{
relatedItem.JoinedIdentifiers = textBox.Text;
textBox.Text = relatedItem.JoinedIdentifiers;
};
namesBox.OnEnterPressed += (textBox, text) =>
{
relatedItem.JoinedIdentifiers = text;
textBox.Text = relatedItem.JoinedIdentifiers;
return true;
};
}
ic.CreateEditingHUD(componentEditor);
componentEditor.Recalculate();
@@ -782,7 +786,7 @@ namespace Barotrauma
}
}
List<ColoredText> texts = new List<ColoredText>();
readonly List<ColoredText> texts = new List<ColoredText>();
public List<ColoredText> GetHUDTexts(Character character)
{
texts.Clear();

View File

@@ -216,7 +216,7 @@ namespace Barotrauma.Lights
if (GameMain.Config.SpecularityEnabled)
{
UpdateSpecularMap(graphics, spriteBatch, spriteBatchTransform, cam, backgroundObstructor);
//UpdateSpecularMap(graphics, spriteBatch, spriteBatchTransform, cam, backgroundObstructor);
}
graphics.SetRenderTarget(LightMap);
@@ -302,19 +302,38 @@ namespace Barotrauma.Lights
//draw characters to obstruct the highlighted items/characters and light sprites
//---------------------------------------------------------------------------------------------------
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, transformMatrix: spriteBatchTransform);
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, effect: SolidColorEffect, transformMatrix: spriteBatchTransform);
foreach (Character character in Character.CharacterList)
{
if (character.CurrentHull == null || !character.Enabled) continue;
if (Character.Controlled?.FocusedCharacter == character) continue;
if (Character.Controlled?.FocusedCharacter == character) continue;
foreach (Limb limb in character.AnimController.Limbs)
{
if (limb.DeformSprite != null) continue;
limb.Draw(spriteBatch, cam, Color.Black);
}
}
spriteBatch.End();
graphics.BlendState = BlendState.Additive;
DeformableSprite.Effect.CurrentTechnique = DeformableSprite.Effect.Techniques["DeformShaderSolidColor"];
DeformableSprite.Effect.Parameters["solidColor"].SetValue(Color.Black.ToVector4());
DeformableSprite.Effect.CurrentTechnique.Passes[0].Apply();
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, transformMatrix: spriteBatchTransform);
foreach (Character character in Character.CharacterList)
{
if (character.CurrentHull == null || !character.Enabled) continue;
if (Character.Controlled?.FocusedCharacter == character) continue;
foreach (Limb limb in character.AnimController.Limbs)
{
if (limb.DeformSprite == null) continue;
limb.Draw(spriteBatch, cam, Color.Black);
}
}
spriteBatch.End();
DeformableSprite.Effect.CurrentTechnique = DeformableSprite.Effect.Techniques["DeformShader"];
graphics.BlendState = BlendState.Additive;
//draw the actual light volumes, additive particles, hull ambient lights and the halo around the player
//---------------------------------------------------------------------------------------------------
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, transformMatrix: spriteBatchTransform);
@@ -372,10 +391,10 @@ namespace Barotrauma.Lights
if (GameMain.Config.SpecularityEnabled)
{
spriteBatch.Begin(blendState: CustomBlendStates.Multiplicative);
/*spriteBatch.Begin(blendState: CustomBlendStates.Multiplicative);
spriteBatch.Draw(SpecularMap, Vector2.Zero, Color.White);
//spriteBatch.Draw(SpecularMap, Vector2.Zero, Color.White);
spriteBatch.End();
spriteBatch.End();*/
}
//draw the actual light volumes, additive particles, hull ambient lights and the halo around the player

View File

@@ -47,6 +47,7 @@ namespace Barotrauma
private Vector2 drawOffset;
private Vector2 drawOffsetNoise;
private float subReticleAnimState;
private float targetReticleAnimState;
private Vector2 subReticlePosition;
@@ -57,6 +58,9 @@ namespace Barotrauma
private MapTile[,] mapTiles;
private bool messageBoxOpen;
public Vector2 CenterOffset;
#if DEBUG
private GUIComponent editor;
@@ -316,7 +320,7 @@ namespace Barotrauma
hudOpenState = Math.Min(hudOpenState + deltaTime, 0.75f + (float)Math.Sin(Timing.TotalTime * 3.0f) * 0.25f);
Vector2 rectCenter = new Vector2(rect.Center.X, rect.Center.Y);
Vector2 rectCenter = new Vector2(rect.Center.X, rect.Center.Y) + CenterOffset;
float closestDist = 0.0f;
highlightedLocation = null;
@@ -327,7 +331,7 @@ namespace Barotrauma
Location location = Locations[i];
Vector2 pos = rectCenter + (location.MapPosition + drawOffset) * zoom;
if (!rect.Contains(pos)) continue;
if (!rect.Contains(pos)) { continue; }
float iconScale = MapGenerationParams.Instance.LocationIconSize / location.Type.Sprite.size.X;
@@ -348,28 +352,6 @@ namespace Barotrauma
}
}
foreach (LocationConnection connection in connections)
{
if (highlightedLocation != CurrentLocation &&
connection.Locations.Contains(highlightedLocation) && connection.Locations.Contains(CurrentLocation))
{
if (PlayerInput.LeftButtonClicked() &&
SelectedLocation != highlightedLocation && highlightedLocation != null)
{
//clients aren't allowed to select the location without a permission
if (GameMain.Client == null || GameMain.Client.HasPermission(Networking.ClientPermissions.ManageCampaign))
{
SelectedConnection = connection;
SelectedLocation = highlightedLocation;
targetReticleAnimState = 0.0f;
OnLocationSelected?.Invoke(SelectedLocation, SelectedConnection);
GameMain.Client?.SendCampaignState();
}
}
}
}
if (GUI.KeyboardDispatcher.Subscriber == null)
{
float moveSpeed = 1000.0f;
@@ -383,6 +365,28 @@ namespace Barotrauma
if (GUI.MouseOn == mapContainer)
{
foreach (LocationConnection connection in connections)
{
if (highlightedLocation != CurrentLocation &&
connection.Locations.Contains(highlightedLocation) && connection.Locations.Contains(CurrentLocation))
{
if (PlayerInput.LeftButtonClicked() &&
SelectedLocation != highlightedLocation && highlightedLocation != null)
{
//clients aren't allowed to select the location without a permission
if (GameMain.Client == null || GameMain.Client.HasPermission(Networking.ClientPermissions.ManageCampaign))
{
SelectedConnection = connection;
SelectedLocation = highlightedLocation;
targetReticleAnimState = 0.0f;
OnLocationSelected?.Invoke(SelectedLocation, SelectedConnection);
GameMain.Client?.SendCampaignState();
}
}
}
}
zoom += PlayerInput.ScrollWheelSpeed / 1000.0f;
zoom = MathHelper.Clamp(zoom, 1.0f, 4.0f);
@@ -425,12 +429,12 @@ namespace Barotrauma
Vector2 viewOffset = drawOffset + drawOffsetNoise;
Vector2 rectCenter = new Vector2(rect.Center.X, rect.Center.Y);
Vector2 rectCenter = new Vector2(rect.Center.X, rect.Center.Y) + CenterOffset;
Rectangle prevScissorRect = GameMain.Instance.GraphicsDevice.ScissorRectangle;
spriteBatch.End();
spriteBatch.GraphicsDevice.ScissorRectangle = Rectangle.Intersect(prevScissorRect, rect);
spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
for (int x = 0; x < mapTiles.GetLength(0); x++)
{
@@ -662,15 +666,15 @@ namespace Barotrauma
Vector2 size = GUI.LargeFont.MeasureString(location.Name);
GUI.Style.GetComponentStyle("OuterGlow").Sprites[GUIComponent.ComponentState.None][0].Draw(
spriteBatch, new Rectangle((int)pos.X - 30, (int)pos.Y, (int)size.X + 60, (int)(size.Y + 25 * GUI.Scale)), Color.Black * hudOpenState * 0.7f);
GUI.DrawString(spriteBatch, pos,
GUI.DrawString(spriteBatch, pos,
location.Name, Color.White * hudOpenState * 1.5f, font: GUI.LargeFont);
GUI.DrawString(spriteBatch, pos + Vector2.UnitY * 25 * GUI.Scale,
GUI.DrawString(spriteBatch, pos + Vector2.UnitY * 25 * GUI.Scale,
location.Type.Name, Color.White * hudOpenState * 1.5f);
}
GameMain.Instance.GraphicsDevice.ScissorRectangle = prevScissorRect;
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred);
GameMain.Instance.GraphicsDevice.ScissorRectangle = prevScissorRect;
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
}
private IEnumerable<object> WaitForMessageBoxClosed(GUIMessageBox box)
@@ -687,11 +691,13 @@ namespace Barotrauma
private void DrawDecorativeHUD(SpriteBatch spriteBatch, Rectangle rect)
{
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, null, null, GameMain.ScissorTestEnable);
spriteBatch.Begin(SpriteSortMode.Deferred, blendState: BlendState.Additive, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
Vector2 rectCenter = rect.Center.ToVector2() + CenterOffset;
if (generationParams.ShowOverlay)
{
Vector2 mapCenter = rect.Center.ToVector2() + (new Vector2(size, size) / 2 + drawOffset + drawOffsetNoise) * zoom;
Vector2 mapCenter = rectCenter + (new Vector2(size, size) / 2 + drawOffset + drawOffsetNoise) * zoom;
Vector2 centerDiff = CurrentLocation.MapPosition - new Vector2(size) / 2;
int currentZone = (int)Math.Floor((centerDiff.Length() / (size * 0.5f) * generationParams.DifficultyZones));
for (int i = 0; i < generationParams.DifficultyZones; i++)
@@ -754,21 +760,21 @@ namespace Barotrauma
//reticles
generationParams.ReticleLarge.Draw(spriteBatch, (int)(subReticleAnimState * generationParams.ReticleLarge.FrameCount),
rect.Center.ToVector2() + (subReticlePosition + drawOffset - drawOffsetNoise * 2) * zoom, Color.White,
rectCenter + (subReticlePosition + drawOffset - drawOffsetNoise * 2) * zoom, Color.White,
generationParams.ReticleLarge.Origin, 0, Vector2.One * (float)Math.Sqrt(zoom) * 0.4f);
generationParams.ReticleMedium.Draw(spriteBatch, (int)(subReticleAnimState * generationParams.ReticleMedium.FrameCount),
rect.Center.ToVector2() + (subReticlePosition + drawOffset - drawOffsetNoise) * zoom, Color.White,
rectCenter + (subReticlePosition + drawOffset - drawOffsetNoise) * zoom, Color.White,
generationParams.ReticleMedium.Origin, 0, new Vector2(1.0f, 0.7f) * (float)Math.Sqrt(zoom) * 0.4f);
if (SelectedLocation != null)
{
generationParams.ReticleSmall.Draw(spriteBatch, (int)(targetReticleAnimState * generationParams.ReticleSmall.FrameCount),
rect.Center.ToVector2() + (SelectedLocation.MapPosition + drawOffset + drawOffsetNoise * 2) * zoom, Color.White,
rectCenter + (SelectedLocation.MapPosition + drawOffset + drawOffsetNoise * 2) * zoom, Color.White,
generationParams.ReticleSmall.Origin, 0, new Vector2(1.0f, 0.7f) * (float)Math.Sqrt(zoom) * 0.4f);
}
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, GameMain.ScissorTestEnable);
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
}
private void UpdateMapAnim(MapAnim anim, float deltaTime)
@@ -788,8 +794,6 @@ namespace Barotrauma
anim.StartPos = (anim.StartLocation == null) ? -drawOffset : anim.StartLocation.MapPosition;
anim.Timer = Math.Min(anim.Timer + deltaTime, anim.Duration);
float t = anim.Duration <= 0.0f ? 1.0f : Math.Max(anim.Timer / anim.Duration, 0.0f);
drawOffset = -Vector2.SmoothStep(anim.StartPos.Value, anim.EndLocation.MapPosition, t);

View File

@@ -91,9 +91,7 @@ namespace Barotrauma
}
public virtual void Draw(SpriteBatch spriteBatch, bool editing, bool back = true) { }
public virtual void DrawDamage(SpriteBatch spriteBatch, Effect damageEffect, bool editing) { }
/// <summary>
/// Update the selection logic in submarine editor
/// </summary>

View File

@@ -170,11 +170,18 @@ namespace Barotrauma
Draw(spriteBatch, editing, back, null);
}
public override void DrawDamage(SpriteBatch spriteBatch, Effect damageEffect, bool editing)
public void DrawDamage(SpriteBatch spriteBatch, Effect damageEffect, bool editing)
{
Draw(spriteBatch, editing, false, damageEffect);
}
public float GetDrawDepth()
{
float depth = SpriteDepthOverrideIsSet ? SpriteOverrideDepth : prefab.sprite.Depth;
depth -= (ID % 255) * 0.000001f;
return depth;
}
private void Draw(SpriteBatch spriteBatch, bool editing, bool back = true, Effect damageEffect = null)
{
if (prefab.sprite == null) return;
@@ -202,8 +209,7 @@ namespace Barotrauma
Vector2 drawOffset = Submarine == null ? Vector2.Zero : Submarine.DrawPosition;
float depth = SpriteDepthOverrideIsSet ? SpriteOverrideDepth : prefab.sprite.Depth;
depth -= (ID % 255) * 0.000001f;
float depth = GetDrawDepth();
Vector2 textureOffset = this.textureOffset;
if (FlippedX) textureOffset.X = -textureOffset.X;
@@ -247,7 +253,7 @@ namespace Barotrauma
color: color,
textureScale: TextureScale * Scale,
startOffset: backGroundOffset,
depth: Math.Max(Prefab.BackgroundSprite.Depth, depth + 0.000001f));
depth: Math.Max(Prefab.BackgroundSprite.Depth + (ID % 255) * 0.000001f, depth + 0.000001f));
if (UseDropShadow)
{

View File

@@ -228,20 +228,38 @@ namespace Barotrauma
public static float DamageEffectCutoff;
public static Color DamageEffectColor;
private static readonly List<Structure> depthSortedDamageable = new List<Structure>();
public static void DrawDamageable(SpriteBatch spriteBatch, Effect damageEffect, bool editing = false)
{
var entitiesToRender = !editing && visibleEntities != null ? visibleEntities : MapEntity.mapEntityList;
depthSortedDamageable.Clear();
//insertion sort according to draw depth
foreach (MapEntity e in entitiesToRender)
{
if (e.DrawDamageEffect)
e.DrawDamage(spriteBatch, damageEffect, editing);
if (e is Structure structure && structure.DrawDamageEffect)
{
float drawDepth = structure.GetDrawDepth();
int i = 0;
while (i < depthSortedDamageable.Count)
{
float otherDrawDepth = depthSortedDamageable[i].GetDrawDepth();
if (otherDrawDepth < drawDepth) { break; }
i++;
}
depthSortedDamageable.Insert(i, structure);
}
}
foreach (Structure s in depthSortedDamageable)
{
s.DrawDamage(spriteBatch, damageEffect, editing);
}
if (damageEffect != null)
{
damageEffect.Parameters["aCutoff"].SetValue(0.0f);
damageEffect.Parameters["cCutoff"].SetValue(0.0f);
DamageEffectCutoff = 0.0f;
}
}
@@ -274,18 +292,6 @@ namespace Barotrauma
return MainSub.SaveAs(filePath, previewImage);
}
public void CreatePreviewWindow(GUIMessageBox messageBox)
{
var background = new GUIButton(new RectTransform(Vector2.One, messageBox.RectTransform), style: "GUIBackgroundBlocker")
{
OnClicked = (btn, userdata) => { if (GUI.MouseOn == btn || GUI.MouseOn == btn.TextBlock) messageBox.Close(); return true; }
};
background.RectTransform.SetAsFirstChild();
var holder = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.85f), messageBox.Content.RectTransform), style: null);
CreatePreviewWindow(holder);
}
public void CreatePreviewWindow(GUIComponent parent)
{
var upperPart = new GUILayoutGroup(new RectTransform(new Vector2(1, 0.5f), parent.RectTransform, Anchor.Center, Pivot.BottomCenter));
@@ -297,7 +303,7 @@ namespace Barotrauma
if (PreviewImage == null)
{
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1), upperPart.RectTransform), TextManager.Get("SubPreviewImageNotFound"));
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1), upperPart.RectTransform), TextManager.Get(SavedSubmarines.Contains(this) ? "SubPreviewImageNotFound" : "SubNotDownloaded"));
}
else
{
@@ -310,49 +316,54 @@ namespace Barotrauma
new GUITextBlock(new RectTransform(new Vector2(1, 0), descriptionBox.Content.RectTransform), Name, font: GUI.LargeFont, wrap: true) { ForceUpperCase = true, CanBeFocused = false };
float leftPanelWidth = 0.6f;
float rightPanelWidth = 0.4f / leftPanelWidth;
ScalableFont font = descriptionBox.Rect.Width < 350 ? GUI.SmallFont : GUI.Font;
Vector2 realWorldDimensions = Dimensions * Physics.DisplayToRealWorldRatio;
if (realWorldDimensions != Vector2.Zero)
{
string dimensionsStr = TextManager.GetWithVariables("DimensionsFormat", new string[2] { "[width]", "[height]" }, new string[2] { ((int)realWorldDimensions.X).ToString(), ((int)realWorldDimensions.Y).ToString() });
var dimensionsText = new GUITextBlock(new RectTransform(new Vector2(1, 0), descriptionBox.Content.RectTransform),
TextManager.Get("Dimensions"), textAlignment: Alignment.TopLeft, font: GUI.Font, wrap: true)
var dimensionsText = new GUITextBlock(new RectTransform(new Vector2(leftPanelWidth, 0), descriptionBox.Content.RectTransform),
TextManager.Get("Dimensions"), textAlignment: Alignment.TopLeft, font: font, wrap: true)
{ CanBeFocused = false };
new GUITextBlock(new RectTransform(new Vector2(0.45f, 0.0f), dimensionsText.RectTransform, Anchor.TopRight),
dimensionsStr, textAlignment: Alignment.TopLeft, font: GUI.Font, wrap: true)
new GUITextBlock(new RectTransform(new Vector2(rightPanelWidth, 0.0f), dimensionsText.RectTransform, Anchor.TopRight, Pivot.TopLeft),
dimensionsStr, textAlignment: Alignment.TopLeft, font: font, wrap: true)
{ CanBeFocused = false };
dimensionsText.RectTransform.MinSize = new Point(0, dimensionsText.Children.First().Rect.Height);
}
if (RecommendedCrewSizeMax > 0)
{
var crewSizeText = new GUITextBlock(new RectTransform(new Vector2(1, 0), descriptionBox.Content.RectTransform),
TextManager.Get("RecommendedCrewSize"), textAlignment: Alignment.TopLeft, font: GUI.Font, wrap: true)
var crewSizeText = new GUITextBlock(new RectTransform(new Vector2(leftPanelWidth, 0), descriptionBox.Content.RectTransform),
TextManager.Get("RecommendedCrewSize"), textAlignment: Alignment.TopLeft, font: font, wrap: true)
{ CanBeFocused = false };
new GUITextBlock(new RectTransform(new Vector2(0.45f, 0.0f), crewSizeText.RectTransform, Anchor.TopRight),
RecommendedCrewSizeMin + " - " + RecommendedCrewSizeMax, textAlignment: Alignment.TopLeft, font: GUI.Font, wrap: true)
new GUITextBlock(new RectTransform(new Vector2(rightPanelWidth, 0.0f), crewSizeText.RectTransform, Anchor.TopRight, Pivot.TopLeft),
RecommendedCrewSizeMin + " - " + RecommendedCrewSizeMax, textAlignment: Alignment.TopLeft, font: font, wrap: true)
{ CanBeFocused = false };
crewSizeText.RectTransform.MinSize = new Point(0, crewSizeText.Children.First().Rect.Height);
}
if (!string.IsNullOrEmpty(RecommendedCrewExperience))
{
var crewExperienceText = new GUITextBlock(new RectTransform(new Vector2(1, 0), descriptionBox.Content.RectTransform),
TextManager.Get("RecommendedCrewExperience"), textAlignment: Alignment.TopLeft, font: GUI.Font, wrap: true)
var crewExperienceText = new GUITextBlock(new RectTransform(new Vector2(leftPanelWidth, 0), descriptionBox.Content.RectTransform),
TextManager.Get("RecommendedCrewExperience"), textAlignment: Alignment.TopLeft, font: font, wrap: true)
{ CanBeFocused = false };
new GUITextBlock(new RectTransform(new Vector2(0.45f, 0.0f), crewExperienceText.RectTransform, Anchor.TopRight),
TextManager.Get(RecommendedCrewExperience), textAlignment: Alignment.TopLeft, font: GUI.Font, wrap: true)
new GUITextBlock(new RectTransform(new Vector2(rightPanelWidth, 0.0f), crewExperienceText.RectTransform, Anchor.TopRight, Pivot.TopLeft),
TextManager.Get(RecommendedCrewExperience), textAlignment: Alignment.TopLeft, font: font, wrap: true)
{ CanBeFocused = false };
crewExperienceText.RectTransform.MinSize = new Point(0, crewExperienceText.Children.First().Rect.Height);
}
if (RequiredContentPackages.Any())
{
var contentPackagesText = new GUITextBlock(new RectTransform(new Vector2(1, 0), descriptionBox.Content.RectTransform),
TextManager.Get("RequiredContentPackages"), textAlignment: Alignment.TopLeft, font: GUI.Font)
var contentPackagesText = new GUITextBlock(new RectTransform(new Vector2(leftPanelWidth, 0), descriptionBox.Content.RectTransform),
TextManager.Get("RequiredContentPackages"), textAlignment: Alignment.TopLeft, font: font)
{ CanBeFocused = false };
new GUITextBlock(new RectTransform(new Vector2(0.45f, 0.0f), contentPackagesText.RectTransform, Anchor.TopRight),
string.Join(", ", RequiredContentPackages), textAlignment: Alignment.TopLeft, font: GUI.Font, wrap: true)
new GUITextBlock(new RectTransform(new Vector2(rightPanelWidth, 0.0f), contentPackagesText.RectTransform, Anchor.TopRight, Pivot.TopLeft),
string.Join(", ", RequiredContentPackages), textAlignment: Alignment.TopLeft, font: font, wrap: true)
{ CanBeFocused = false };
contentPackagesText.RectTransform.MinSize = new Point(0, contentPackagesText.Children.First().Rect.Height);
}
@@ -362,13 +373,13 @@ namespace Barotrauma
//space
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), descriptionBox.Content.RectTransform), style: null);
if (Description.Length != 0)
if (!string.IsNullOrEmpty(Description))
{
new GUITextBlock(new RectTransform(new Vector2(1, 0), descriptionBox.Content.RectTransform),
TextManager.Get("SaveSubDialogDescription", fallBackTag: "WorkshopItemDescription"), font: GUI.Font, wrap: true) { CanBeFocused = false, ForceUpperCase = true };
}
new GUITextBlock(new RectTransform(new Vector2(1, 0), descriptionBox.Content.RectTransform), Description, font: GUI.Font, wrap: true)
new GUITextBlock(new RectTransform(new Vector2(1, 0), descriptionBox.Content.RectTransform), Description, font: font, wrap: true)
{
CanBeFocused = false
};

View File

@@ -108,7 +108,13 @@ namespace Barotrauma.Media
public uint Width { get; private set; }
public uint Height { get; private set; }
public Video(GraphicsDevice graphicsDevice,SoundManager soundManager,string filename,uint width,uint height)
public float AudioGain
{
get { return sound == null ? 0.0f : sound.BaseGain; }
set { if (sound != null) { sound.BaseGain = value; } }
}
public Video(GraphicsDevice graphicsDevice, SoundManager soundManager, string filename, uint width, uint height)
{
Init();

View File

@@ -9,6 +9,7 @@ namespace Barotrauma.Networking
struct TempClient
{
public string Name;
public string PreferredJob;
public UInt16 NameID;
public UInt64 SteamID;
public byte ID;

View File

@@ -31,7 +31,7 @@ namespace Barotrauma
Item.ReadSpawnData(message, true);
break;
case (byte)SpawnableType.Character:
Character.ReadSpawnData(message, true);
Character.ReadSpawnData(message);
break;
default:
DebugConsole.ThrowError("Received invalid entity spawn message (unknown spawnable type)");

View File

@@ -164,8 +164,8 @@ namespace Barotrauma.Networking
private Dictionary<FileTransferType, string> downloadFolders = new Dictionary<FileTransferType, string>()
{
{ FileTransferType.Submarine, "Submarines/Downloaded" },
{ FileTransferType.CampaignSave, "Data/Saves/Multiplayer" }
{ FileTransferType.Submarine, SaveUtil.SubmarineDownloadFolder },
{ FileTransferType.CampaignSave, SaveUtil.CampaignDownloadFolder }
};
public List<FileTransferIn> ActiveTransfers

View File

@@ -29,8 +29,14 @@ namespace Barotrauma.Networking
public void SetName(string value)
{
value = value.Replace(":", "").Replace(";", "");
if (string.IsNullOrEmpty(value)) { return; }
name = value.Replace(":", "").Replace(";", "");
name = value;
nameId++;
}
public void ForceNameAndJobUpdate()
{
nameId++;
}
@@ -265,9 +271,9 @@ namespace Barotrauma.Networking
private void ConnectToServer(object endpoint, string hostName)
{
chatBox.InputBox.Enabled = false;
if (GameMain.NetLobbyScreen?.TextBox != null)
if (GameMain.NetLobbyScreen?.ChatInput != null)
{
GameMain.NetLobbyScreen.TextBox.Enabled = false;
GameMain.NetLobbyScreen.ChatInput.Enabled = false;
}
serverName = hostName;
@@ -334,7 +340,7 @@ namespace Barotrauma.Networking
{
SteamManager.Instance.User.ClearRichPresence();
SteamManager.Instance.User.SetRichPresence("status", "Playing on " + serverName);
SteamManager.Instance.User.SetRichPresence("connect", "-connect \"" + serverName.Replace("\"","\\\"") + "\" " + serverEndpoint);
SteamManager.Instance.User.SetRichPresence("connect", "-connect \"" + serverName.Replace("\"", "\\\"") + "\" " + serverEndpoint);
}
canStart = true;
@@ -348,9 +354,9 @@ namespace Barotrauma.Networking
}
chatBox.InputBox.Enabled = true;
if (GameMain.NetLobbyScreen?.TextBox != null)
if (GameMain.NetLobbyScreen?.ChatInput != null)
{
GameMain.NetLobbyScreen.TextBox.Enabled = true;
GameMain.NetLobbyScreen.ChatInput.Enabled = true;
}
};
clientPeer.OnRequestPassword = (int salt, int retries) =>
@@ -370,9 +376,9 @@ namespace Barotrauma.Networking
DebugConsole.ThrowError("Couldn't connect to " + endpoint.ToString() + ". Error message: " + e.Message);
Disconnect();
chatBox.InputBox.Enabled = true;
if (GameMain.NetLobbyScreen?.TextBox != null)
if (GameMain.NetLobbyScreen?.ChatInput != null)
{
GameMain.NetLobbyScreen.TextBox.Enabled = true;
GameMain.NetLobbyScreen.ChatInput.Enabled = true;
}
GameMain.ServerListScreen.Select();
return;
@@ -630,11 +636,14 @@ namespace Barotrauma.Networking
if (IsServerOwner && connected && !connectCancelled)
{
if (GameMain.ServerChildProcess?.HasExited ?? true)
if (GameMain.WindowActive)
{
Disconnect();
var msgBox = new GUIMessageBox(TextManager.Get("ConnectionLost"), TextManager.Get("ServerProcessClosed"));
msgBox.Buttons[0].OnClicked += ReturnToPreviousMenu;
if (GameMain.ServerChildProcess?.HasExited ?? true)
{
Disconnect();
var msgBox = new GUIMessageBox(TextManager.Get("ConnectionLost"), TextManager.Get("ServerProcessClosed"));
msgBox.Buttons[0].OnClicked += ReturnToPreviousMenu;
}
}
}
@@ -747,7 +756,7 @@ namespace Barotrauma.Networking
{
saveFiles.Add(inc.ReadString());
}
GameMain.NetLobbyScreen.CampaignSetupUI = MultiPlayerCampaign.StartCampaignSetup(serverSubmarines, saveFiles);
MultiPlayerCampaign.StartCampaignSetup(saveFiles);
break;
case ServerPacketHeader.PERMISSIONS:
ReadPermissions(inc);
@@ -768,7 +777,12 @@ namespace Barotrauma.Networking
SteamAchievementManager.CheatsEnabled = cheatsEnabled;
if (cheatsEnabled)
{
new GUIMessageBox(TextManager.Get("CheatsEnabledTitle"), TextManager.Get("CheatsEnabledDescription"));
var cheatMessageBox = new GUIMessageBox(TextManager.Get("CheatsEnabledTitle"), TextManager.Get("CheatsEnabledDescription"));
cheatMessageBox.Buttons[0].OnClicked += (btn, userdata) =>
{
DebugConsole.TextBox.Select();
return true;
};
}
}
break;
@@ -778,6 +792,9 @@ namespace Barotrauma.Networking
case ServerPacketHeader.TRAITOR_MESSAGE:
ReadTraitorMessage(inc);
break;
case ServerPacketHeader.MISSION:
GameMain.GameSession.Mission?.ClientRead(inc);
break;
}
}
@@ -958,16 +975,13 @@ namespace Barotrauma.Networking
switch(messageType) {
case TraitorMessageType.Objective:
var isTraitor = !string.IsNullOrEmpty(message);
SpawnAsTraitor = isTraitor;
TraitorFirstObjective = message;
if (Character != null)
{
Character.IsTraitor = isTraitor;
Character.TraitorCurrentObjective = message;
}
else
{
SpawnAsTraitor = isTraitor;
TraitorFirstObjective = message;
}
break;
case TraitorMessageType.Console:
GameMain.Client.AddChatMessage(ChatMessage.Create("", message, ChatMessageType.Console, null));
@@ -1153,6 +1167,21 @@ namespace Barotrauma.Networking
GameMain.NetLobbyScreen.SelectedSub.MD5Hash?.Hash != subHash)
{
string errorMsg = "Failed to select submarine \"" + subName + "\" (hash: " + subHash + ").";
if (GameMain.NetLobbyScreen.SelectedSub == null)
{
errorMsg += "\n" + "SelectedSub is null";
}
else
{
if (GameMain.NetLobbyScreen.SelectedSub.Name != subName)
{
errorMsg += "\n" + "Name mismatch: " + GameMain.NetLobbyScreen.SelectedSub.Name + " != " + subName;
}
if (GameMain.NetLobbyScreen.SelectedSub.MD5Hash?.Hash != subHash)
{
errorMsg += "\n" + "Hash mismatch: " + GameMain.NetLobbyScreen.SelectedSub.MD5Hash?.Hash + " != " + subHash;
}
}
DebugConsole.ThrowError(errorMsg);
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:FailedToSelectSub" + subName, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
CoroutineManager.StartCoroutine(EndGame(""));
@@ -1316,6 +1345,7 @@ namespace Barotrauma.Networking
UInt64 steamId = inc.ReadUInt64();
UInt16 nameId = inc.ReadUInt16();
string name = inc.ReadString();
string preferredJob = inc.ReadString();
UInt16 characterID = inc.ReadUInt16();
bool muted = inc.ReadBoolean();
bool allowKicking = inc.ReadBoolean();
@@ -1327,6 +1357,7 @@ namespace Barotrauma.Networking
NameID = nameId,
SteamID = steamId,
Name = name,
PreferredJob = preferredJob,
CharacterID = characterID,
Muted = muted,
AllowKicking = allowKicking
@@ -1353,9 +1384,11 @@ namespace Barotrauma.Networking
GameMain.NetLobbyScreen.AddPlayer(existingClient);
}
existingClient.NameID = tc.NameID;
existingClient.PreferredJob = tc.PreferredJob;
existingClient.Character = null;
existingClient.Muted = tc.Muted;
existingClient.AllowKicking = tc.AllowKicking;
GameMain.NetLobbyScreen.SetPlayerNameAndJobPreference(existingClient);
if (tc.CharacterID > 0)
{
existingClient.Character = Entity.FindEntityByID(tc.CharacterID) as Character;
@@ -1443,7 +1476,7 @@ namespace Barotrauma.Networking
bool allowSpectating = inc.ReadBoolean();
YesNoMaybe traitorsEnabled = (YesNoMaybe)inc.ReadRangedInteger(0, 2);
int missionTypeIndex = inc.ReadRangedInteger(0, Enum.GetValues(typeof(MissionType)).Length - 1);
MissionType missionType = (MissionType)inc.ReadRangedInteger(0, (int)MissionType.All);
int modeIndex = inc.ReadByte();
string levelSeed = inc.ReadString();
@@ -1461,7 +1494,11 @@ namespace Barotrauma.Networking
ReadWriteMessage settingsBuf = new ReadWriteMessage();
settingsBuf.Write(settingsData, 0, settingsLen); settingsBuf.BitPosition = 0;
serverSettings.ClientRead(settingsBuf);
if (!IsServerOwner)
{
ServerInfo info = GameMain.ServerListScreen.UpdateServerInfoWithServerSettings(serverEndpoint, serverSettings);
GameMain.ServerListScreen.AddToRecentServers(info);
}
GameMain.NetLobbyScreen.LastUpdateID = updateID;
@@ -1475,7 +1512,7 @@ namespace Barotrauma.Networking
GameMain.NetLobbyScreen.TrySelectSub(selectShuttleName, selectShuttleHash, GameMain.NetLobbyScreen.ShuttleList.ListBox);
GameMain.NetLobbyScreen.SetTraitorsEnabled(traitorsEnabled);
GameMain.NetLobbyScreen.SetMissionType(missionTypeIndex);
GameMain.NetLobbyScreen.SetMissionType(missionType);
if (!allowModeVoting) GameMain.NetLobbyScreen.SelectMode(modeIndex);
@@ -1649,6 +1686,15 @@ namespace Barotrauma.Networking
outmsg.Write(LastClientListUpdateID);
outmsg.Write(nameId);
outmsg.Write(name);
var jobPreferences = GameMain.NetLobbyScreen.JobPreferences;
if (jobPreferences.Count > 0)
{
outmsg.Write(jobPreferences[0].First.Identifier);
}
else
{
outmsg.Write("");
}
var campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;
if (campaign == null || campaign.LastSaveID == 0)
@@ -1722,7 +1768,7 @@ namespace Barotrauma.Networking
public void SendChatMessage(ChatMessage msg)
{
if (clientPeer.ServerConnection == null) return;
if (clientPeer?.ServerConnection == null) { return; }
lastQueueChatMsgID++;
msg.NetStateID = lastQueueChatMsgID;
chatMsgQueue.Add(msg);
@@ -1730,7 +1776,7 @@ namespace Barotrauma.Networking
public void SendChatMessage(string message, ChatMessageType type = ChatMessageType.Default)
{
if (clientPeer.ServerConnection == null) return;
if (clientPeer?.ServerConnection == null) { return; }
ChatMessage chatMessage = ChatMessage.Create(
gameStarted && myCharacter != null ? myCharacter.Name : name,
@@ -1809,19 +1855,6 @@ namespace Barotrauma.Networking
subElement.GetChild<GUITextBlock>().TextColor = new Color(subElement.GetChild<GUITextBlock>().TextColor, 1.0f);
subElement.UserData = newSub;
subElement.ToolTip = newSub.Description;
GUIButton infoButton = subElement.GetChild<GUIButton>();
if (infoButton == null)
{
int buttonSize = (int)(subElement.Rect.Height * 0.8f);
infoButton = new GUIButton(new RectTransform(new Point(buttonSize), subElement.RectTransform, Anchor.CenterLeft) { AbsoluteOffset = new Point((int)(buttonSize * 0.2f), 0) }, "?");
}
infoButton.UserData = newSub;
infoButton.OnClicked = (component, userdata) =>
{
((Submarine)userdata).CreatePreviewWindow(new GUIMessageBox("", "", new Vector2(0.25f, 0.25f), new Point(500, 400)));
return true;
};
}
if (GameMain.NetLobbyScreen.FailedSelectedSub != null &&
@@ -1850,9 +1883,12 @@ namespace Barotrauma.Networking
string subPath = Path.Combine(SaveUtil.TempPath, gameSessionDoc.Root.GetAttributeString("submarine", "")) + ".sub";
GameMain.GameSession.Submarine = new Submarine(subPath, "");
}
SaveUtil.LoadGame(GameMain.GameSession.SavePath, GameMain.GameSession);
GameMain.GameSession?.Submarine?.CheckSubsLeftBehind();
if (GameMain.GameSession?.Submarine?.Name != null)
{
GameMain.NetLobbyScreen.TryDisplayCampaignSubmarine(GameMain.GameSession.Submarine);
}
campaign.LastSaveID = campaign.PendingSaveID;
DebugConsole.Log("Campaign save received, save ID " + campaign.LastSaveID);
@@ -1940,6 +1976,8 @@ namespace Barotrauma.Networking
GameMain.ServerChildProcess = null;
}
characterInfo?.Remove();
VoipClient?.Dispose();
VoipClient = null;
GameMain.Client = null;
@@ -1963,7 +2001,8 @@ namespace Barotrauma.Networking
msg.Write((byte)count);
for (int i = 0; i < count; i++)
{
msg.Write(jobPreferences[i].Identifier);
msg.Write(jobPreferences[i].First.Identifier);
msg.Write((byte)jobPreferences[i].Second);
}
}
@@ -2137,6 +2176,8 @@ namespace Barotrauma.Networking
public void SetupNewCampaign(Submarine sub, string saveName, string mapSeed)
{
GameMain.NetLobbyScreen.CampaignSetupFrame.Visible = false;
saveName = Path.GetFileNameWithoutExtension(saveName);
IWriteMessage msg = new WriteOnlyMessage();
@@ -2149,12 +2190,12 @@ namespace Barotrauma.Networking
msg.Write(sub.MD5Hash.Hash);
clientPeer.Send(msg, DeliveryMethod.Reliable);
GameMain.NetLobbyScreen.CampaignSetupUI = null;
}
public void SetupLoadCampaign(string saveName)
{
GameMain.NetLobbyScreen.CampaignSetupFrame.Visible = false;
IWriteMessage msg = new WriteOnlyMessage();
msg.Write((byte)ClientPacketHeader.CAMPAIGN_SETUP_INFO);
@@ -2162,8 +2203,6 @@ namespace Barotrauma.Networking
msg.Write(saveName);
clientPeer.Send(msg, DeliveryMethod.Reliable);
GameMain.NetLobbyScreen.CampaignSetupUI = null;
}
/// <summary>
@@ -2278,7 +2317,11 @@ namespace Barotrauma.Networking
SendChatMessage(message);
textBox.Deselect();
if (textBox.DeselectAfterMessage)
{
textBox.Deselect();
}
textBox.Text = "";
return true;
@@ -2292,6 +2335,7 @@ namespace Barotrauma.Networking
Screen.Selected == GameMain.GameScreen)
{
inGameHUD.AddToGUIUpdateList();
GameMain.NetLobbyScreen.FileTransferFrame?.AddToGUIUpdateList();
}
}
@@ -2305,7 +2349,7 @@ namespace Barotrauma.Networking
}
else if (Screen.Selected == GameMain.NetLobbyScreen)
{
msgBox = GameMain.NetLobbyScreen.TextBox;
msgBox = GameMain.NetLobbyScreen.ChatInput;
}
if (gameStarted && Screen.Selected == GameMain.GameScreen)
@@ -2358,46 +2402,26 @@ namespace Barotrauma.Networking
public virtual void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
{
if (GUI.DisableHUD || GUI.DisableUpperHUD) return;
if (fileReceiver != null && fileReceiver.ActiveTransfers.Count > 0)
{
Vector2 downloadBarSize = new Vector2(250, 35) * GUI.Scale;
Vector2 pos = new Vector2(GameMain.NetLobbyScreen.InfoFrame.Rect.X, GameMain.GraphicsHeight - downloadBarSize.Y - 5);
GUI.DrawRectangle(spriteBatch, new Rectangle(
(int)pos.X,
(int)pos.Y,
(int)(fileReceiver.ActiveTransfers.Count * (downloadBarSize.X + 10)),
(int)downloadBarSize.Y),
Color.Black * 0.8f, true);
for (int i = 0; i < fileReceiver.ActiveTransfers.Count; i++)
{
var transfer = fileReceiver.ActiveTransfers[i];
GUI.DrawString(spriteBatch,
pos,
ToolBox.LimitString(TextManager.GetWithVariable("DownloadingFile", "[filename]", transfer.FileName), GUI.SmallFont, (int)downloadBarSize.X),
Color.White, null, 0, GUI.SmallFont);
GUI.DrawProgressBar(spriteBatch, new Vector2(pos.X, -pos.Y - downloadBarSize.Y / 2), new Vector2(downloadBarSize.X * 0.7f, downloadBarSize.Y / 2), transfer.Progress, Color.Green);
GUI.DrawString(spriteBatch, pos + new Vector2(5, downloadBarSize.Y / 2),
MathUtils.GetBytesReadable((long)transfer.Received) + " / " + MathUtils.GetBytesReadable((long)transfer.FileSize),
Color.White, null, 0, GUI.SmallFont);
if (GUI.DrawButton(spriteBatch, new Rectangle(
(int)(pos.X + downloadBarSize.X * 0.7f), (int)(pos.Y + downloadBarSize.Y / 2),
(int)(downloadBarSize.X * 0.3f), (int)(downloadBarSize.Y / 2)),
TextManager.Get("Cancel"), new Color(0.47f, 0.13f, 0.15f, 0.08f)))
{
CancelFileTransfer(transfer);
fileReceiver.StopTransfer(transfer);
}
pos.X += (downloadBarSize.X + 10);
}
var transfer = fileReceiver.ActiveTransfers.First();
GameMain.NetLobbyScreen.FileTransferFrame.Visible = true;
GameMain.NetLobbyScreen.FileTransferTitle.Text =
ToolBox.LimitString(
TextManager.GetWithVariable("DownloadingFile", "[filename]", transfer.FileName),
GameMain.NetLobbyScreen.FileTransferTitle.Font,
GameMain.NetLobbyScreen.FileTransferTitle.Rect.Width);
GameMain.NetLobbyScreen.FileTransferProgressBar.BarSize = transfer.Progress;
GameMain.NetLobbyScreen.FileTransferProgressText.Text =
MathUtils.GetBytesReadable((long)transfer.Received) + " / " + MathUtils.GetBytesReadable((long)transfer.FileSize);
}
if (!gameStarted || Screen.Selected != GameMain.GameScreen) return;
else
{
GameMain.NetLobbyScreen.FileTransferFrame.Visible = false;
}
if (!gameStarted || Screen.Selected != GameMain.GameScreen) { return; }
inGameHUD.DrawManually(spriteBatch);

View File

@@ -169,7 +169,7 @@ namespace Barotrauma.Networking
outMsg.Write(GameMain.Version.ToString());
IEnumerable<ContentPackage> mpContentPackages = GameMain.SelectedPackages.Where(cp => cp.HasMultiplayerIncompatibleContent);
IEnumerable<ContentPackage> mpContentPackages = GameMain.SelectedPackages.Where(cp => cp.HasMultiplayerIncompatibleContent && !cp.NeedsRestart);
outMsg.WriteVariableInt32(mpContentPackages.Count());
foreach (ContentPackage contentPackage in mpContentPackages)
{

View File

@@ -202,7 +202,7 @@ namespace Barotrauma.Networking
outMsg.Write(GameMain.Version.ToString());
IEnumerable<ContentPackage> mpContentPackages = GameMain.SelectedPackages.Where(cp => cp.HasMultiplayerIncompatibleContent);
IEnumerable<ContentPackage> mpContentPackages = GameMain.SelectedPackages.Where(cp => cp.HasMultiplayerIncompatibleContent && !cp.NeedsRestart);
outMsg.WriteVariableUInt32((UInt32)mpContentPackages.Count());
foreach (ContentPackage contentPackage in mpContentPackages)
{

View File

@@ -3,6 +3,8 @@ using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Xml.Linq;
namespace Barotrauma.Networking
{
@@ -10,8 +12,11 @@ namespace Barotrauma.Networking
{
public string IP;
public string Port;
public string QueryPort;
public UInt64 LobbyID;
public UInt64 OwnerID;
public bool OwnerVerified;
public string ServerName;
public string ServerMessage;
@@ -30,12 +35,22 @@ namespace Barotrauma.Networking
public SelectionMode? SubSelectionMode;
public bool? AllowSpectating;
public bool? VoipEnabled;
public bool? KarmaEnabled;
public bool? FriendlyFireEnabled;
public bool? AllowRespawn;
public YesNoMaybe? TraitorsEnabled;
public string GameMode;
public PlayStyle? PlayStyle;
public bool Recent;
public bool Favorite;
public bool? RespondedToSteamQuery = null;
public Facepunch.Steamworks.SteamFriend SteamFriend;
public Facepunch.Steamworks.ISteamMatchmakingPingResponse MatchmakingPingResponse;
public int? PingHQuery;
public string GameVersion;
public List<string> ContentPackageNames
{
@@ -85,59 +100,100 @@ namespace Barotrauma.Networking
if (frame == null) return;
var previewContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 1.0f), frame.RectTransform, Anchor.Center))
var previewContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), frame.RectTransform, Anchor.Center))
{
Stretch = true
};
var columnContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.5f), previewContainer.RectTransform))
var titleContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.035f), previewContainer.RectTransform), true)
{
Color = Color.White * 0.2f
};
var title = new GUITextBlock(new RectTransform(new Vector2(0.9f, 0.0f), titleContainer.RectTransform, Anchor.CenterLeft), ServerName, font: GUI.LargeFont)
{
ToolTip = ServerName
};
title.Text = ToolBox.LimitString(title.Text, title.Font, title.Rect.Width);
title.Padding = new Vector4(10, 0, 0, 10);
GUITickBox favoriteTickBox = new GUITickBox(new RectTransform(new Vector2(0.9f, 0.85f), titleContainer.RectTransform, Anchor.CenterRight, scaleBasis: ScaleBasis.BothHeight) { RelativeOffset = new Vector2(0.0f, 0.1f) }, "", null, "GUIServerListFavoriteTickBox")
{
Selected = Favorite,
ToolTip = TextManager.Get(Favorite ? "removefromfavorites" : "addtofavorites"),
OnSelected = (tickbox) =>
{
if (tickbox.Selected)
{
GameMain.ServerListScreen.AddToFavoriteServers(this);
}
else
{
GameMain.ServerListScreen.RemoveFromFavoriteServers(this);
}
tickbox.ToolTip = TextManager.Get(tickbox.Selected ? "removefromfavorites" : "addtofavorites");
return true;
}
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), previewContainer.RectTransform),
TextManager.AddPunctuation(':', TextManager.Get("ServerListVersion"), string.IsNullOrEmpty(GameVersion) ? TextManager.Get("Unknown") : GameVersion));
PlayStyle playStyle = PlayStyle ?? Networking.PlayStyle.Serious;
Sprite playStyleBannerSprite = GameMain.ServerListScreen.PlayStyleBanners[(int)playStyle];
float playStyleBannerAspectRatio = playStyleBannerSprite.SourceRect.Width / (playStyleBannerSprite.SourceRect.Height * 0.65f);
var playStyleBanner = new GUIImage(new RectTransform(new Vector2(1.0f, 1.0f / playStyleBannerAspectRatio), previewContainer.RectTransform, Anchor.TopCenter, scaleBasis: ScaleBasis.BothWidth),
playStyleBannerSprite, null, true);
var playStyleName = new GUITextBlock(new RectTransform(new Vector2(0.15f, 0.0f), playStyleBanner.RectTransform) { RelativeOffset = new Vector2(0.01f, 0.06f) },
TextManager.AddPunctuation(':', TextManager.Get("serverplaystyle"), TextManager.Get("servertag."+ playStyle)), textColor: Color.White,
font: GUI.SmallFont, textAlignment: Alignment.Center,
color: GameMain.ServerListScreen.PlayStyleColors[(int)playStyle], style: "GUISlopedHeader");
playStyleName.RectTransform.NonScaledSize = (playStyleName.Font.MeasureString(playStyleName.Text) + new Vector2(20, 5) * GUI.Scale).ToPoint();
playStyleName.RectTransform.IsFixedSize = true;
var columnContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.45f), previewContainer.RectTransform), isHorizontal: true)
{
Stretch = true
};
// Left column -------------------------------------------------------------------------------
var leftColumnHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.75f, 1.0f), columnContainer.RectTransform), childAnchor: Anchor.Center)
{
Stretch = true
};
var leftColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 1.0f), leftColumnHolder.RectTransform))
{
Stretch = true
};
float elementHeight = 0.075f;
var title = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), columnContainer.RectTransform), ServerName, font: GUI.LargeFont);
title.Text = ToolBox.LimitString(title.Text, title.Font, title.Rect.Width);
// Spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.025f), leftColumn.RectTransform), style: null);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), columnContainer.RectTransform),
TextManager.AddPunctuation(':', TextManager.Get("ServerListVersion"), string.IsNullOrEmpty(GameVersion) ? TextManager.Get("Unknown") : GameVersion));
var serverMsg = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.3f), leftColumn.RectTransform)) { ScrollBarVisible = true };
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), serverMsg.Content.RectTransform), ServerMessage, font: GUI.SmallFont, wrap: true) { CanBeFocused = false };
// left column -----------------------------------------------------------------------------
//new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), columnLeft.RectTransform), IP + ":" + Port);
var serverMsg = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.5f), columnContainer.RectTransform)) { ScrollBarVisible = true };
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), serverMsg.Content.RectTransform), ServerMessage, wrap: true) { CanBeFocused = false };
// right column -----------------------------------------------------------------------------
/*var playerCount = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), columnRight.RectTransform), TextManager.Get("ServerListPlayers"));
new GUITextBlock(new RectTransform(Vector2.One, playerCount.RectTransform), PlayerCount + "/" + MaxPlayers, textAlignment: Alignment.Right);
new GUITickBox(new RectTransform(new Vector2(1, elementHeight), columnRight.RectTransform), "Round running")
{
Selected = GameStarted,
CanBeFocused = false
};*/
var gameMode = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), columnContainer.RectTransform), TextManager.Get("GameMode"));
var gameMode = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), leftColumn.RectTransform), TextManager.Get("GameMode"));
new GUITextBlock(new RectTransform(Vector2.One, gameMode.RectTransform),
TextManager.Get(string.IsNullOrEmpty(GameMode) ? "Unknown" : "GameMode." + GameMode, returnNull: true) ?? GameMode,
textAlignment: Alignment.Right);
var traitors = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), columnContainer.RectTransform), TextManager.Get("Traitors"));
/*var traitors = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), bodyContainer.RectTransform), TextManager.Get("Traitors"));
new GUITextBlock(new RectTransform(Vector2.One, traitors.RectTransform), TextManager.Get(!TraitorsEnabled.HasValue ? "Unknown" : TraitorsEnabled.Value.ToString()), textAlignment: Alignment.Right);*/
new GUITextBlock(new RectTransform(Vector2.One, traitors.RectTransform), TextManager.Get(!TraitorsEnabled.HasValue ? "Unknown" : TraitorsEnabled.Value.ToString()), textAlignment: Alignment.Right);
var subSelection = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), columnContainer.RectTransform), TextManager.Get("ServerListSubSelection"));
var subSelection = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), leftColumn.RectTransform), TextManager.Get("ServerListSubSelection"));
new GUITextBlock(new RectTransform(Vector2.One, subSelection.RectTransform), TextManager.Get(!SubSelectionMode.HasValue ? "Unknown" : SubSelectionMode.Value.ToString()), textAlignment: Alignment.Right);
var modeSelection = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), columnContainer.RectTransform), TextManager.Get("ServerListModeSelection"));
var modeSelection = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), leftColumn.RectTransform), TextManager.Get("ServerListModeSelection"));
new GUITextBlock(new RectTransform(Vector2.One, modeSelection.RectTransform), TextManager.Get(!ModeSelectionMode.HasValue ? "Unknown" : ModeSelectionMode.Value.ToString()), textAlignment: Alignment.Right);
var allowSpectating = new GUITickBox(new RectTransform(new Vector2(1, elementHeight), columnContainer.RectTransform), TextManager.Get("ServerListAllowSpectating"))
var allowSpectating = new GUITickBox(new RectTransform(new Vector2(1, elementHeight), leftColumn.RectTransform), TextManager.Get("ServerListAllowSpectating"))
{
CanBeFocused = false
};
@@ -146,7 +202,7 @@ namespace Barotrauma.Networking
else
allowSpectating.Selected = AllowSpectating.Value;
var allowRespawn = new GUITickBox(new RectTransform(new Vector2(1, elementHeight), columnContainer.RectTransform), TextManager.Get("ServerSettingsAllowRespawning"))
var allowRespawn = new GUITickBox(new RectTransform(new Vector2(1, elementHeight), leftColumn.RectTransform), TextManager.Get("ServerSettingsAllowRespawning"))
{
CanBeFocused = false
};
@@ -155,16 +211,16 @@ namespace Barotrauma.Networking
else
allowRespawn.Selected = AllowRespawn.Value;
var voipEnabledTickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), columnContainer.RectTransform), TextManager.Get("serversettingsvoicechatenabled"))
/*var voipEnabledTickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), bodyContainer.RectTransform), TextManager.Get("serversettingsvoicechatenabled"))
{
CanBeFocused = false
};
if (!VoipEnabled.HasValue)
new GUITextBlock(new RectTransform(new Vector2(0.8f, 0.8f), voipEnabledTickBox.Box.RectTransform, Anchor.Center), "?", textAlignment: Alignment.Center);
else
voipEnabledTickBox.Selected = VoipEnabled.Value;
voipEnabledTickBox.Selected = VoipEnabled.Value;*/
var usingWhiteList = new GUITickBox(new RectTransform(new Vector2(1, elementHeight), columnContainer.RectTransform), TextManager.Get("ServerListUsingWhitelist"))
var usingWhiteList = new GUITickBox(new RectTransform(new Vector2(1, elementHeight), leftColumn.RectTransform), TextManager.Get("ServerListUsingWhitelist"))
{
CanBeFocused = false
};
@@ -174,15 +230,15 @@ namespace Barotrauma.Networking
usingWhiteList.Selected = UsingWhiteList.Value;
columnContainer.RectTransform.SizeChanged += () =>
leftColumn.RectTransform.SizeChanged += () =>
{
GUITextBlock.AutoScaleAndNormalize(allowSpectating.TextBlock, allowRespawn.TextBlock, voipEnabledTickBox.TextBlock, usingWhiteList.TextBlock);
GUITextBlock.AutoScaleAndNormalize(allowSpectating.TextBlock, allowRespawn.TextBlock, usingWhiteList.TextBlock);
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), columnContainer.RectTransform),
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), leftColumn.RectTransform),
TextManager.Get("ServerListContentPackages"));
var contentPackageList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.3f), columnContainer.RectTransform)) { ScrollBarVisible = true };
var contentPackageList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.2f), leftColumn.RectTransform)) { ScrollBarVisible = true };
if (ContentPackageNames.Count == 0)
{
new GUITextBlock(new RectTransform(Vector2.One, contentPackageList.Content.RectTransform), TextManager.Get("Unknown"), textAlignment: Alignment.Center)
@@ -231,7 +287,7 @@ namespace Barotrauma.Networking
}
if (availableWorkshopUrls.Count > 0)
{
var workshopBtn = new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), columnContainer.RectTransform), TextManager.Get("ServerListSubscribeMissingPackages"))
var workshopBtn = new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), leftColumn.RectTransform), TextManager.Get("ServerListSubscribeMissingPackages"))
{
ToolTip = TextManager.Get(SteamManager.IsInitialized ? "ServerListSubscribeMissingPackagesTooltip" : "ServerListSubscribeMissingPackagesTooltipNoSteam"),
Enabled = SteamManager.IsInitialized,
@@ -246,12 +302,237 @@ namespace Barotrauma.Networking
}
}
// Spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform), style: null);
// Right column ------------------------------------------------------------------------------
var rightColumnBackground = new GUIFrame(new RectTransform(new Vector2(0.2f, 1.0f), columnContainer.RectTransform), style: null)
{
Color = Color.Black * 0.25f
};
var rightColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 1.0f), rightColumnBackground.RectTransform, Anchor.Center));
// playstyle tags -----------------------------------------------------------------------------
var playStyleTags = GetPlayStyleTags();
foreach (string tag in playStyleTags)
{
if (!GameMain.ServerListScreen.PlayStyleIcons.ContainsKey(tag)) { continue; }
new GUIImage(new RectTransform(Vector2.One, rightColumn.RectTransform, scaleBasis: ScaleBasis.BothWidth),
GameMain.ServerListScreen.PlayStyleIcons[tag], scaleToFit: true)
{
ToolTip = TextManager.Get("servertagdescription." + tag),
Color = GameMain.ServerListScreen.PlayStyleIconColors[tag]
};
}
/*var playerCount = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), columnRight.RectTransform), TextManager.Get("ServerListPlayers"));
new GUITextBlock(new RectTransform(Vector2.One, playerCount.RectTransform), PlayerCount + "/" + MaxPlayers, textAlignment: Alignment.Right);
new GUITickBox(new RectTransform(new Vector2(1, elementHeight), columnRight.RectTransform), "Round running")
{
Selected = GameStarted,
CanBeFocused = false
};*/
// -----------------------------------------------------------------------------
foreach (GUIComponent c in columnContainer.Children)
foreach (GUIComponent c in leftColumn.Children)
{
if (c is GUITextBlock textBlock) textBlock.Padding = Vector4.Zero;
}
}
public IEnumerable<string> GetPlayStyleTags()
{
List<string> tags = new List<string>();
if (KarmaEnabled.HasValue)
{
tags.Add(KarmaEnabled.Value ? "karma.true" : "karma.false");
}
if (TraitorsEnabled.HasValue)
{
tags.Add(TraitorsEnabled.Value == YesNoMaybe.Maybe ?
"traitors.maybe" :
(TraitorsEnabled.Value == YesNoMaybe.Yes ? "traitors.true" : "traitors.false"));
}
if (VoipEnabled.HasValue)
{
tags.Add(VoipEnabled.Value ? "voip.true" : "voip.false");
}
if (FriendlyFireEnabled.HasValue)
{
tags.Add(FriendlyFireEnabled.Value ? "friendlyfire.true" : "friendlyfire.false");
}
if (ContentPackageNames.Count > 0)
{
tags.Add(ContentPackageNames.Count > 1 || ContentPackageNames[0] != GameMain.VanillaContent?.Name ? "modded.true" : "modded.false");
}
return tags;
}
public static ServerInfo FromXElement(XElement element)
{
ServerInfo info = new ServerInfo()
{
ServerName = element.GetAttributeString("ServerName", ""),
ServerMessage = element.GetAttributeString("ServerMessage", ""),
IP = element.GetAttributeString("IP", ""),
Port = element.GetAttributeString("Port", ""),
QueryPort = element.GetAttributeString("QueryPort", ""),
OwnerID = element.GetAttributeSteamID("OwnerID",0)
};
info.RespondedToSteamQuery = null;
info.GameMode = element.GetAttributeString("GameMode", "");
info.GameVersion = element.GetAttributeString("GameVersion", "");
info.MaxPlayers = element.GetAttributeInt("MaxPlayers", 0);
if (Enum.TryParse(element.GetAttributeString("PlayStyle", ""), out PlayStyle playStyleTemp)) { info.PlayStyle = playStyleTemp; }
if (bool.TryParse(element.GetAttributeString("UsingWhiteList", ""), out bool whitelistTemp)) { info.UsingWhiteList = whitelistTemp; }
if (Enum.TryParse(element.GetAttributeString("TraitorsEnabled", ""), out YesNoMaybe traitorsTemp)) { info.TraitorsEnabled = traitorsTemp; }
if (Enum.TryParse(element.GetAttributeString("SubSelectionMode", ""), out SelectionMode subSelectionTemp)) { info.SubSelectionMode = subSelectionTemp; }
if (Enum.TryParse(element.GetAttributeString("ModeSelectionMode", ""), out SelectionMode modeSelectionTemp)) { info.ModeSelectionMode = subSelectionTemp; }
if (bool.TryParse(element.GetAttributeString("VoipEnabled", ""), out bool voipTemp)) { info.VoipEnabled = voipTemp; }
if (bool.TryParse(element.GetAttributeString("KarmaEnabled", ""), out bool karmaTemp)) { info.KarmaEnabled = karmaTemp; }
if (bool.TryParse(element.GetAttributeString("FriendlyFireEnabled", ""), out bool friendlyFireTemp)) { info.FriendlyFireEnabled = friendlyFireTemp; }
info.HasPassword = element.GetAttributeBool("HasPassword", false);
return info;
}
public void QueryLiveInfo(Action<Networking.ServerInfo> onServerRulesReceived)
{
if (!SteamManager.IsInitialized) { return; }
if (int.TryParse(QueryPort, out _))
{
if (PingHQuery != null)
{
SteamManager.Instance.ServerList.CancelHQuery(PingHQuery.Value);
PingHQuery = null;
}
MatchmakingPingResponse = new Facepunch.Steamworks.ISteamMatchmakingPingResponse(
SteamManager.Instance.Client,
(server) =>
{
ServerName = server.Name;
RespondedToSteamQuery = true;
PlayerCount = server.Players;
MaxPlayers = server.MaxPlayers;
HasPassword = server.Passworded;
PingChecked = true;
Ping = server.Ping;
LobbyID = 0;
server.FetchRules();
server.OnReceivedRules += (bool received) => { SteamManager.OnReceivedRules(server, this, received); onServerRulesReceived?.Invoke(this); };
},
() =>
{
RespondedToSteamQuery = false;
});
PingHQuery = SteamManager.Instance.ServerList.HQueryPing(MatchmakingPingResponse, IPAddress.Parse(IP), int.Parse(QueryPort));
}
else if (OwnerID != 0)
{
if (SteamFriend == null)
{
SteamFriend = SteamManager.Instance.Friends.Get(OwnerID);
}
if (LobbyID == 0)
{
SteamFriend.Refresh();
if (SteamFriend.IsPlayingThisGame && SteamFriend.ServerLobbyId != 0)
{
LobbyID = SteamFriend.ServerLobbyId;
SteamManager.Instance.LobbyList.SetManualLobbyDataCallback(LobbyID, (lobby) =>
{
SteamManager.Instance.LobbyList.SetManualLobbyDataCallback(LobbyID, null);
if (string.IsNullOrWhiteSpace(lobby.GetData("haspassword"))) { return; }
bool.TryParse(lobby.GetData("haspassword"), out bool hasPassword);
int.TryParse(lobby.GetData("playercount"), out int currPlayers);
int.TryParse(lobby.GetData("maxplayernum"), out int maxPlayers);
//UInt64.TryParse(lobby.GetData("connectsteamid"), out ulong connectSteamId);
string ip = lobby.GetData("hostipaddress");
UInt64 ownerId = SteamManager.SteamIDStringToUInt64(lobby.GetData("lobbyowner"));
if (OwnerID != ownerId) { return; }
if (string.IsNullOrWhiteSpace(ip)) { ip = ""; }
ServerName = lobby.Name;
Port = "";
QueryPort = "";
IP = ip;
PlayerCount = currPlayers;
MaxPlayers = maxPlayers;
HasPassword = hasPassword;
RespondedToSteamQuery = true;
LobbyID = lobby.LobbyID;
OwnerID = ownerId;
PingChecked = false;
OwnerVerified = true;
SteamManager.AssignLobbyDataToServerInfo(lobby, this);
onServerRulesReceived?.Invoke(this);
});
SteamManager.Instance.LobbyList.RequestLobbyData(LobbyID);
}
else
{
RespondedToSteamQuery = false;
}
}
}
}
public XElement ToXElement()
{
if (OwnerID == 0 && string.IsNullOrEmpty(Port))
{
return null; //can't save this one since it's not set up correctly
}
XElement element = new XElement("ServerInfo");
element.SetAttributeValue("ServerName", ServerName);
element.SetAttributeValue("ServerMessage", ServerMessage);
if (OwnerID == 0)
{
element.SetAttributeValue("IP", IP);
element.SetAttributeValue("Port", Port);
element.SetAttributeValue("QueryPort", QueryPort);
}
else
{
element.SetAttributeValue("OwnerID", SteamManager.SteamIDUInt64ToString(OwnerID));
}
element.SetAttributeValue("GameMode", GameMode ?? "");
element.SetAttributeValue("GameVersion", GameVersion ?? "");
element.SetAttributeValue("MaxPlayers", MaxPlayers);
if (PlayStyle.HasValue) { element.SetAttributeValue("PlayStyle", PlayStyle.Value.ToString()); }
if (UsingWhiteList.HasValue) { element.SetAttributeValue("UsingWhiteList", UsingWhiteList.Value.ToString()); }
if (TraitorsEnabled.HasValue) { element.SetAttributeValue("TraitorsEnabled", TraitorsEnabled.Value.ToString()); }
if (SubSelectionMode.HasValue) { element.SetAttributeValue("SubSelectionMode", SubSelectionMode.Value.ToString()); }
if (ModeSelectionMode.HasValue) { element.SetAttributeValue("ModeSelectionMode", ModeSelectionMode.Value.ToString()); }
if (VoipEnabled.HasValue) { element.SetAttributeValue("VoipEnabled", VoipEnabled.Value.ToString()); }
if (KarmaEnabled.HasValue) { element.SetAttributeValue("KarmaEnabled", KarmaEnabled.Value.ToString()); }
if (FriendlyFireEnabled.HasValue) { element.SetAttributeValue("FriendlyFireEnabled", FriendlyFireEnabled.Value.ToString()); }
element.SetAttributeValue("HasPassword", HasPassword.ToString());
return element;
}
}
}

View File

@@ -67,7 +67,10 @@ namespace Barotrauma.Networking
y += 20;
}
GUITextBlock.AutoScaleAndNormalize(tickBoxes.Select(t => t.TextBlock));
tickBoxes.Last().TextBlock.RectTransform.SizeChanged += () =>
{
GUITextBlock.AutoScaleAndNormalize(tickBoxes.Select(t => t.TextBlock));
};
var currLines = lines.ToList();
@@ -81,26 +84,76 @@ namespace Barotrauma.Networking
if (listBox.BarScroll == 0.0f || listBox.BarScroll == 1.0f) listBox.BarScroll = 1.0f;
GUIButton closeButton = new GUIButton(new RectTransform(new Vector2(0.25f, 0.05f), innerFrame.RectTransform, Anchor.BottomRight) { RelativeOffset = new Vector2(0.02f, 0.03f) }, TextManager.Get("Close"));
closeButton.OnClicked = (button, userData) =>
GUIButton closeButton = new GUIButton(new RectTransform(new Vector2(0.25f, 0.05f), innerFrame.RectTransform, Anchor.BottomRight) { RelativeOffset = new Vector2(0.02f, 0.03f) }, TextManager.Get("Close"))
{
LogFrame = null;
return true;
OnClicked = (button, userData) =>
{
LogFrame = null;
return true;
}
};
msgFilter = "";
}
public void AssignLogFrame(GUIListBox inListBox, GUIComponent tickBoxContainer, GUITextBox searchBox)
{
searchBox.OnTextChanged += (textBox, text) =>
{
msgFilter = text;
FilterMessages();
return true;
};
tickBoxContainer.ClearChildren();
List<GUITickBox> tickBoxes = new List<GUITickBox>();
foreach (MessageType msgType in Enum.GetValues(typeof(MessageType)))
{
var tickBox = new GUITickBox(new RectTransform(new Point(tickBoxContainer.Rect.Width, 16), tickBoxContainer.RectTransform), TextManager.Get("ServerLog." + messageTypeName[(int)msgType]), font: GUI.SmallFont)
{
Selected = true,
TextColor = messageColor[(int)msgType],
OnSelected = (GUITickBox tb) =>
{
msgTypeHidden[(int)msgType] = !tb.Selected;
FilterMessages();
return true;
}
};
tickBox.Selected = !msgTypeHidden[(int)msgType];
tickBoxes.Add(tickBox);
}
tickBoxes.Last().TextBlock.RectTransform.SizeChanged += () =>
{
GUITextBlock.AutoScaleAndNormalize(tickBoxes.Select(t => t.TextBlock));
};
inListBox.ClearChildren();
listBox = inListBox;
var currLines = lines.ToList();
foreach (LogMessage line in currLines)
{
AddLine(line);
}
FilterMessages();
listBox.UpdateScrollBarSize();
}
private void AddLine(LogMessage line)
{
float prevSize = listBox.BarSize;
var textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), listBox.Content.RectTransform),
line.Text, wrap: true, font: GUI.SmallFont);
textBlock.TextColor = messageColor[(int)line.Type];
textBlock.Visible = !msgTypeHidden[(int)line.Type];
textBlock.CanBeFocused = false;
textBlock.UserData = line;
var textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), listBox.Content.RectTransform),
line.Text, wrap: true, font: GUI.SmallFont)
{
TextColor = messageColor[(int)line.Type],
Visible = !msgTypeHidden[(int)line.Type],
CanBeFocused = false,
UserData = line
};
if ((prevSize == 1.0f && listBox.BarScroll == 0.0f) || (prevSize < 1.0f && listBox.BarScroll == 1.0f)) listBox.BarScroll = 1.0f;
}

View File

@@ -52,7 +52,7 @@ namespace Barotrauma.Networking
scrollBar.BarScrollValue = (float)value;
}
}
else if (GUIComponent is GUIRadioButtonGroup radioButtonGroup) radioButtonGroup.Selected = (Enum)value;
else if (GUIComponent is GUIRadioButtonGroup radioButtonGroup) radioButtonGroup.Selected = (int)value;
else if (GUIComponent is GUIDropDown dropdown) dropdown.SelectItem(value);
else if (GUIComponent is GUINumberInput numInput)
{
@@ -147,7 +147,7 @@ namespace Barotrauma.Networking
}
}
public void ClientAdminWrite(NetFlags dataToSend, int missionType = 0, float? levelDifficulty = null, bool? autoRestart = null, int traitorSetting = 0, int botCount = 0, int botSpawnMode = 0, bool? useRespawnShuttle = null)
public void ClientAdminWrite(NetFlags dataToSend, int? missionTypeOr = null, int? missionTypeAnd = null, float? levelDifficulty = null, bool? autoRestart = null, int traitorSetting = 0, int botCount = 0, int botSpawnMode = 0, bool? useRespawnShuttle = null)
{
if (!GameMain.Client.HasPermission(Networking.ClientPermissions.ManageSettings)) return;
@@ -200,7 +200,8 @@ namespace Barotrauma.Networking
if (dataToSend.HasFlag(NetFlags.Misc))
{
outMsg.Write((byte)(missionType + 1));
outMsg.WriteRangedInteger(missionTypeOr ?? (int)Barotrauma.MissionType.None, 0, (int)Barotrauma.MissionType.All);
outMsg.WriteRangedInteger(missionTypeAnd ?? (int)Barotrauma.MissionType.All, 0, (int)Barotrauma.MissionType.All);
outMsg.Write((byte)(traitorSetting + 1));
outMsg.Write((byte)(botCount + 1));
outMsg.Write((byte)(botSpawnMode + 1));
@@ -330,7 +331,30 @@ namespace Barotrauma.Networking
};
//***********************************************
// Play Style Selection
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), TextManager.Get("ServerSettingsPlayStyle"));
var playStyleSelection = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.16f), serverTab.RectTransform))
{
AutoHideScrollBar = true,
UseGridLayout = true
};
List<GUITickBox> playStyleTickBoxes = new List<GUITickBox>();
GUIRadioButtonGroup selectionPlayStyle = new GUIRadioButtonGroup();
foreach (PlayStyle playStyle in Enum.GetValues(typeof(PlayStyle)))
{
var selectionTick = new GUITickBox(new RectTransform(new Vector2(0.32f, 0.49f), playStyleSelection.Content.RectTransform), TextManager.Get("servertag." + playStyle), font: GUI.SmallFont, style: "GUIRadioButton")
{
ToolTip = TextManager.Get("servertagdescription." + playStyle)
};
selectionPlayStyle.AddRadioButton((int)playStyle, selectionTick);
playStyleTickBoxes.Add(selectionTick);
}
GetPropertyData("PlayStyle").AssignGUIComponent(selectionPlayStyle);
GUITextBlock.AutoScaleAndNormalize(playStyleTickBoxes.Select(t => t.TextBlock));
// Sub Selection
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), TextManager.Get("ServerSettingsSubSelection"));
var selectionFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), isHorizontal: true)
{
@@ -341,12 +365,13 @@ namespace Barotrauma.Networking
GUIRadioButtonGroup selectionMode = new GUIRadioButtonGroup();
for (int i = 0; i < 3; i++)
{
var selectionTick = new GUITickBox(new RectTransform(new Vector2(0.3f, 1.0f), selectionFrame.RectTransform), TextManager.Get(((SelectionMode)i).ToString()), font: GUI.SmallFont);
selectionMode.AddRadioButton((SelectionMode)i, selectionTick);
var selectionTick = new GUITickBox(new RectTransform(new Vector2(0.3f, 1.0f), selectionFrame.RectTransform), TextManager.Get(((SelectionMode)i).ToString()), font: GUI.SmallFont, style: "GUIRadioButton");
selectionMode.AddRadioButton(i, selectionTick);
}
DebugConsole.NewMessage(SubSelectionMode.ToString(), Color.White);
GetPropertyData("SubSelectionMode").AssignGUIComponent(selectionMode);
// Mode Selection
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), TextManager.Get("ServerSettingsModeSelection"));
selectionFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), isHorizontal: true)
{
@@ -357,8 +382,8 @@ namespace Barotrauma.Networking
selectionMode = new GUIRadioButtonGroup();
for (int i = 0; i < 3; i++)
{
var selectionTick = new GUITickBox(new RectTransform(new Vector2(0.3f, 1.0f), selectionFrame.RectTransform), TextManager.Get(((SelectionMode)i).ToString()), font: GUI.SmallFont);
selectionMode.AddRadioButton((SelectionMode)i, selectionTick);
var selectionTick = new GUITickBox(new RectTransform(new Vector2(0.3f, 1.0f), selectionFrame.RectTransform), TextManager.Get(((SelectionMode)i).ToString()), font: GUI.SmallFont, style: "GUIRadioButton");
selectionMode.AddRadioButton(i, selectionTick);
}
GetPropertyData("ModeSelectionMode").AssignGUIComponent(selectionMode);
@@ -715,6 +740,18 @@ namespace Barotrauma.Networking
RelativeSpacing = 0.02f
};
var allowFriendlyFire = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), antigriefingTab.RectTransform),
TextManager.Get("ServerSettingsAllowFriendlyFire"));
GetPropertyData("AllowFriendlyFire").AssignGUIComponent(allowFriendlyFire);
var allowRewiring = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), antigriefingTab.RectTransform),
TextManager.Get("ServerSettingsAllowRewiring"));
GetPropertyData("AllowRewiring").AssignGUIComponent(allowRewiring);
var allowDisguises = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), antigriefingTab.RectTransform),
TextManager.Get("ServerSettingsAllowDisguises"));
GetPropertyData("AllowDisguises").AssignGUIComponent(allowDisguises);
var voteKickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), antigriefingTab.RectTransform), TextManager.Get("ServerSettingsAllowVoteKick"));
GetPropertyData("AllowVoteKick").AssignGUIComponent(voteKickBox);

View File

@@ -20,6 +20,8 @@ namespace Barotrauma.Steam
public Facepunch.Steamworks.Auth Auth => client?.Auth;
public Facepunch.Steamworks.Lobby Lobby => client?.Lobby;
public Facepunch.Steamworks.LobbyList LobbyList => client?.LobbyList;
public Facepunch.Steamworks.ServerList ServerList => client?.ServerList;
public Facepunch.Steamworks.Client Client => client;
private SteamManager()
{
@@ -75,7 +77,8 @@ namespace Barotrauma.Steam
Joining,
Joined
}
private static UInt64 lobbyID = 0;
public static UInt64 LobbyID { get; private set; } = 0;
private static LobbyState lobbyState = LobbyState.NotConnected;
private static string lobbyIP = "";
private static Thread lobbyIPRetrievalThread;
@@ -167,7 +170,7 @@ namespace Barotrauma.Steam
lobbyIPRetrievalThread.Start();
lobbyState = LobbyState.Owner;
lobbyID = instance.client.Lobby.CurrentLobby;
LobbyID = instance.client.Lobby.CurrentLobby;
UpdateLobby(serverSettings);
};
if (lobbyState != LobbyState.NotConnected) { return; }
@@ -192,16 +195,16 @@ namespace Barotrauma.Steam
{
return;
}
var contentPackages = GameMain.Config.SelectedContentPackages.Where(cp => cp.HasMultiplayerIncompatibleContent);
instance.client.Lobby.Name = serverSettings.ServerName;
instance.client.Lobby.Owner = Steam.SteamManager.GetSteamID();
instance.client.Lobby.MaxMembers = serverSettings.MaxPlayers+10;
instance.client.Lobby.CurrentLobbyData.SetData("playercount", (GameMain.Client?.ConnectedClients?.Count??0).ToString());
instance.client.Lobby.Owner = GetSteamID();
instance.client.Lobby.MaxMembers = serverSettings.MaxPlayers + 10;
instance.client.Lobby.CurrentLobbyData.SetData("playercount", (GameMain.Client?.ConnectedClients?.Count ?? 0).ToString());
instance.client.Lobby.CurrentLobbyData.SetData("maxplayernum", serverSettings.MaxPlayers.ToString());
instance.client.Lobby.CurrentLobbyData.SetData("hostipaddress", lobbyIP);
//instance.client.Lobby.CurrentLobbyData.SetData("connectsteamid", Steam.SteamManager.GetSteamID().ToString());
instance.client.Lobby.CurrentLobbyData.SetData("lobbyowner", SteamIDUInt64ToString(GetSteamID()));
instance.client.Lobby.CurrentLobbyData.SetData("haspassword", serverSettings.HasPassword.ToString());
instance.client.Lobby.CurrentLobbyData.SetData("message", serverSettings.ServerMessageText);
@@ -216,9 +219,12 @@ namespace Barotrauma.Steam
instance.client.Lobby.CurrentLobbyData.SetData("voicechatenabled", serverSettings.VoiceChatEnabled.ToString());
instance.client.Lobby.CurrentLobbyData.SetData("allowspectating", serverSettings.AllowSpectating.ToString());
instance.client.Lobby.CurrentLobbyData.SetData("allowrespawn", serverSettings.AllowRespawn.ToString());
instance.client.Lobby.CurrentLobbyData.SetData("karmaenabled", serverSettings.KarmaEnabled.ToString());
instance.client.Lobby.CurrentLobbyData.SetData("friendlyfireenabled", serverSettings.AllowFriendlyFire.ToString());
instance.client.Lobby.CurrentLobbyData.SetData("traitors", serverSettings.TraitorsEnabled.ToString());
instance.client.Lobby.CurrentLobbyData.SetData("gamestarted", GameMain.Client.GameStarted.ToString());
instance.client.Lobby.CurrentLobbyData.SetData("gamemode", GameMain.NetLobbyScreen?.SelectedMode?.Identifier??"");
instance.client.Lobby.CurrentLobbyData.SetData("playstyle", serverSettings.PlayStyle.ToString());
instance.client.Lobby.CurrentLobbyData.SetData("gamemode", GameMain.NetLobbyScreen?.SelectedMode?.Identifier ?? "");
DebugConsole.Log("Lobby updated!");
}
@@ -232,7 +238,7 @@ namespace Barotrauma.Steam
lobbyIPRetrievalThread = null;
instance.client.Lobby.Leave();
lobbyID = 0;
LobbyID = 0;
lobbyIP = "";
lobbyState = LobbyState.NotConnected;
@@ -242,7 +248,7 @@ namespace Barotrauma.Steam
public static void JoinLobby(UInt64 id, bool joinServer)
{
if (instance.client.Lobby.CurrentLobby == id) { return; }
if (lobbyID == id) { return; }
if (LobbyID == id) { return; }
instance.client.Lobby.OnLobbyJoined = (success) =>
{
try
@@ -253,7 +259,7 @@ namespace Barotrauma.Steam
return;
}
lobbyState = LobbyState.Joined;
lobbyID = instance.client.Lobby.CurrentLobby;
LobbyID = instance.client.Lobby.CurrentLobby;
if (joinServer)
{
GameMain.Instance.ConnectLobby = 0;
@@ -267,7 +273,7 @@ namespace Barotrauma.Steam
}
};
lobbyState = LobbyState.Joining;
lobbyID = id;
LobbyID = id;
instance.client.Lobby.Join(id);
}
@@ -314,9 +320,11 @@ namespace Barotrauma.Steam
query.OnUpdate = () => { UpdateServerQuery(query, onServerFound, onServerRulesReceived, includeUnresponsive: true); };
query.OnFinished = onFinished;
#if !DEBUG
var localQuery = instance.client.ServerList.Local(filter);
localQuery.OnUpdate = () => { UpdateServerQuery(localQuery, onServerFound, onServerRulesReceived, includeUnresponsive: true); };
localQuery.OnFinished = onFinished;
#endif
instance.client.LobbyList.OnLobbiesUpdated = () => { UpdateLobbyQuery(onServerFound, onServerRulesReceived, onFinished); };
instance.client.LobbyList.Refresh();
@@ -382,6 +390,7 @@ namespace Barotrauma.Steam
bool.TryParse(lobby.GetData("haspassword"), out bool hasPassword);
int.TryParse(lobby.GetData("playercount"), out int currPlayers);
int.TryParse(lobby.GetData("maxplayernum"), out int maxPlayers);
UInt64 ownerId = SteamIDStringToUInt64(lobby.GetData("lobbyowner"));
//UInt64.TryParse(lobby.GetData("connectsteamid"), out ulong connectSteamId);
string ip = lobby.GetData("hostipaddress");
if (string.IsNullOrWhiteSpace(ip)) { ip = ""; }
@@ -390,41 +399,17 @@ namespace Barotrauma.Steam
{
ServerName = lobby.Name,
Port = "",
QueryPort = "",
IP = ip,
PlayerCount = currPlayers,
MaxPlayers = maxPlayers,
HasPassword = hasPassword,
RespondedToSteamQuery = true,
LobbyID = lobby.LobbyID
LobbyID = lobby.LobbyID,
OwnerID = ownerId
};
serverInfo.PingChecked = false;
serverInfo.ServerMessage = lobby.GetData("message");
serverInfo.GameVersion = lobby.GetData("version");
serverInfo.ContentPackageNames.AddRange(lobby.GetData("contentpackage").Split(','));
serverInfo.ContentPackageHashes.AddRange(lobby.GetData("contentpackagehash").Split(','));
serverInfo.ContentPackageWorkshopUrls.AddRange(lobby.GetData("contentpackageurl").Split(','));
serverInfo.UsingWhiteList = lobby.GetData("usingwhitelist") == "True";
SelectionMode selectionMode;
if (Enum.TryParse(lobby.GetData("modeselectionmode"), out selectionMode)) serverInfo.ModeSelectionMode = selectionMode;
if (Enum.TryParse(lobby.GetData("subselectionmode"), out selectionMode)) serverInfo.SubSelectionMode = selectionMode;
serverInfo.AllowSpectating = lobby.GetData("allowspectating") == "True";
serverInfo.AllowRespawn = lobby.GetData("allowrespawn") == "True";
serverInfo.VoipEnabled = lobby.GetData("voicechatenabled") == "True";
if (Enum.TryParse(lobby.GetData("traitors"), out YesNoMaybe traitorsEnabled)) serverInfo.TraitorsEnabled = traitorsEnabled;
serverInfo.GameStarted = lobby.GetData("gamestarted") == "True";
serverInfo.GameMode = lobby.GetData("gamemode");
if (serverInfo.ContentPackageNames.Count != serverInfo.ContentPackageHashes.Count ||
serverInfo.ContentPackageHashes.Count != serverInfo.ContentPackageWorkshopUrls.Count)
{
//invalid contentpackage info
serverInfo.ContentPackageNames.Clear();
serverInfo.ContentPackageHashes.Clear();
}
AssignLobbyDataToServerInfo(lobby, serverInfo);
onServerFound(serverInfo);
//onServerRulesReceived(serverInfo);
@@ -433,6 +418,47 @@ namespace Barotrauma.Steam
onFinished();
}
public static void AssignLobbyDataToServerInfo(LobbyList.Lobby lobby, ServerInfo serverInfo)
{
serverInfo.ServerMessage = lobby.GetData("message");
serverInfo.GameVersion = lobby.GetData("version");
serverInfo.ContentPackageNames.AddRange(lobby.GetData("contentpackage").Split(','));
serverInfo.ContentPackageHashes.AddRange(lobby.GetData("contentpackagehash").Split(','));
serverInfo.ContentPackageWorkshopUrls.AddRange(lobby.GetData("contentpackageurl").Split(','));
serverInfo.UsingWhiteList = getLobbyBool("usingwhitelist");
SelectionMode selectionMode;
if (Enum.TryParse(lobby.GetData("modeselectionmode"), out selectionMode)) { serverInfo.ModeSelectionMode = selectionMode; }
if (Enum.TryParse(lobby.GetData("subselectionmode"), out selectionMode)) { serverInfo.SubSelectionMode = selectionMode; }
serverInfo.AllowSpectating = getLobbyBool("allowspectating");
serverInfo.AllowRespawn = getLobbyBool("allowrespawn");
serverInfo.VoipEnabled = getLobbyBool("voicechatenabled");
serverInfo.KarmaEnabled = getLobbyBool("karmaenabled");
serverInfo.FriendlyFireEnabled = getLobbyBool("friendlyfireenabled");
if (Enum.TryParse(lobby.GetData("traitors"), out YesNoMaybe traitorsEnabled)) { serverInfo.TraitorsEnabled = traitorsEnabled; }
serverInfo.GameStarted = lobby.GetData("gamestarted") == "True";
serverInfo.GameMode = lobby.GetData("gamemode");
if (Enum.TryParse(lobby.GetData("playstyle"), out PlayStyle playStyle)) serverInfo.PlayStyle = playStyle;
if (serverInfo.ContentPackageNames.Count != serverInfo.ContentPackageHashes.Count ||
serverInfo.ContentPackageHashes.Count != serverInfo.ContentPackageWorkshopUrls.Count)
{
//invalid contentpackage info
serverInfo.ContentPackageNames.Clear();
serverInfo.ContentPackageHashes.Clear();
}
bool? getLobbyBool(string key)
{
string data = lobby.GetData(key);
if (string.IsNullOrEmpty(data)) { return null; }
return data == "True" || data == "true";
}
}
private static void UpdateServerQuery(ServerList.Request query, Action<Networking.ServerInfo> onServerFound, Action<Networking.ServerInfo> onServerRulesReceived, bool includeUnresponsive)
{
IEnumerable<ServerList.Server> servers = includeUnresponsive ?
@@ -459,6 +485,7 @@ namespace Barotrauma.Steam
{
ServerName = s.Name,
Port = s.ConnectionPort.ToString(),
QueryPort = s.QueryPort.ToString(),
IP = s.Address.ToString(),
PlayerCount = s.Players,
MaxPlayers = s.MaxPlayers,
@@ -472,60 +499,72 @@ namespace Barotrauma.Steam
{
s.FetchRules();
}
s.OnReceivedRules += (bool rulesReceived) =>
{
if (!rulesReceived || s.Rules == null) { return; }
if (s.Rules.ContainsKey("message")) serverInfo.ServerMessage = s.Rules["message"];
if (s.Rules.ContainsKey("version")) serverInfo.GameVersion = s.Rules["version"];
if (s.Rules.ContainsKey("playercount"))
{
if (int.TryParse(s.Rules["playercount"], out int playerCount)) serverInfo.PlayerCount = playerCount;
}
if (s.Rules.ContainsKey("contentpackage")) serverInfo.ContentPackageNames.AddRange(s.Rules["contentpackage"].Split(','));
if (s.Rules.ContainsKey("contentpackagehash")) serverInfo.ContentPackageHashes.AddRange(s.Rules["contentpackagehash"].Split(','));
if (s.Rules.ContainsKey("contentpackageurl")) serverInfo.ContentPackageWorkshopUrls.AddRange(s.Rules["contentpackageurl"].Split(','));
if (s.Rules.ContainsKey("usingwhitelist")) serverInfo.UsingWhiteList = s.Rules["usingwhitelist"] == "True";
if (s.Rules.ContainsKey("modeselectionmode"))
{
if (Enum.TryParse(s.Rules["modeselectionmode"], out SelectionMode selectionMode)) serverInfo.ModeSelectionMode = selectionMode;
}
if (s.Rules.ContainsKey("subselectionmode"))
{
if (Enum.TryParse(s.Rules["subselectionmode"], out SelectionMode selectionMode)) serverInfo.SubSelectionMode = selectionMode;
}
if (s.Rules.ContainsKey("allowspectating")) serverInfo.AllowSpectating = s.Rules["allowspectating"] == "True";
if (s.Rules.ContainsKey("allowrespawn")) serverInfo.AllowRespawn = s.Rules["allowrespawn"] == "True";
if (s.Rules.ContainsKey("voicechatenabled")) serverInfo.VoipEnabled = s.Rules["voicechatenabled"] == "True";
if (s.Rules.ContainsKey("traitors"))
{
if (Enum.TryParse(s.Rules["traitors"], out YesNoMaybe traitorsEnabled)) serverInfo.TraitorsEnabled = traitorsEnabled;
}
if (s.Rules.ContainsKey("gamestarted")) serverInfo.GameStarted = s.Rules["gamestarted"] == "True";
if (s.Rules.ContainsKey("gamemode"))
{
serverInfo.GameMode = s.Rules["gamemode"];
}
if (serverInfo.ContentPackageNames.Count != serverInfo.ContentPackageHashes.Count ||
serverInfo.ContentPackageHashes.Count != serverInfo.ContentPackageWorkshopUrls.Count)
{
//invalid contentpackage info
serverInfo.ContentPackageNames.Clear();
serverInfo.ContentPackageHashes.Clear();
}
onServerRulesReceived(serverInfo);
};
s.OnReceivedRules += (bool received) => { OnReceivedRules(s, serverInfo, received); onServerRulesReceived(serverInfo); };
onServerFound(serverInfo);
}
query.Responded.Clear();
}
public static void OnReceivedRules(ServerList.Server s, ServerInfo serverInfo, bool rulesReceived)
{
if (!rulesReceived || s.Rules == null) { return; }
if (s.Rules.ContainsKey("message")) serverInfo.ServerMessage = s.Rules["message"];
if (s.Rules.ContainsKey("version")) serverInfo.GameVersion = s.Rules["version"];
if (s.Rules.ContainsKey("playercount"))
{
if (int.TryParse(s.Rules["playercount"], out int playerCount)) serverInfo.PlayerCount = playerCount;
}
serverInfo.ContentPackageNames.Clear();
serverInfo.ContentPackageHashes.Clear();
serverInfo.ContentPackageWorkshopUrls.Clear();
if (s.Rules.ContainsKey("contentpackage")) serverInfo.ContentPackageNames.AddRange(s.Rules["contentpackage"].Split(','));
if (s.Rules.ContainsKey("contentpackagehash")) serverInfo.ContentPackageHashes.AddRange(s.Rules["contentpackagehash"].Split(','));
if (s.Rules.ContainsKey("contentpackageurl")) serverInfo.ContentPackageWorkshopUrls.AddRange(s.Rules["contentpackageurl"].Split(','));
if (s.Rules.ContainsKey("usingwhitelist")) serverInfo.UsingWhiteList = s.Rules["usingwhitelist"] == "True";
if (s.Rules.ContainsKey("modeselectionmode"))
{
if (Enum.TryParse(s.Rules["modeselectionmode"], out SelectionMode selectionMode)) serverInfo.ModeSelectionMode = selectionMode;
}
if (s.Rules.ContainsKey("subselectionmode"))
{
if (Enum.TryParse(s.Rules["subselectionmode"], out SelectionMode selectionMode)) serverInfo.SubSelectionMode = selectionMode;
}
if (s.Rules.ContainsKey("allowspectating")) serverInfo.AllowSpectating = s.Rules["allowspectating"] == "True";
if (s.Rules.ContainsKey("allowrespawn")) serverInfo.AllowRespawn = s.Rules["allowrespawn"] == "True";
if (s.Rules.ContainsKey("voicechatenabled")) serverInfo.VoipEnabled = s.Rules["voicechatenabled"] == "True";
if (s.Rules.ContainsKey("karmaenabled")) serverInfo.KarmaEnabled = s.Rules["karmaenabled"] == "True";
if (s.Rules.ContainsKey("friendlyfireenabled")) serverInfo.FriendlyFireEnabled = s.Rules["friendlyfireenabled"] == "True";
if (s.Rules.ContainsKey("traitors"))
{
if (Enum.TryParse(s.Rules["traitors"], out YesNoMaybe traitorsEnabled)) serverInfo.TraitorsEnabled = traitorsEnabled;
}
if (s.Rules.ContainsKey("gamestarted")) serverInfo.GameStarted = s.Rules["gamestarted"] == "True";
if (s.Rules.ContainsKey("gamemode"))
{
serverInfo.GameMode = s.Rules["gamemode"];
}
if (s.Rules.ContainsKey("playstyle"))
{
if (Enum.TryParse(s.Rules["playstyle"], out PlayStyle playStyle)) serverInfo.PlayStyle = playStyle;
}
if (serverInfo.ContentPackageNames.Count != serverInfo.ContentPackageHashes.Count ||
serverInfo.ContentPackageHashes.Count != serverInfo.ContentPackageWorkshopUrls.Count)
{
//invalid contentpackage info
serverInfo.ContentPackageNames.Clear();
serverInfo.ContentPackageHashes.Clear();
}
}
private static bool ValidateServerInfo(ServerList.Server server)
{
if (string.IsNullOrWhiteSpace(server.Name)) { return false; }

View File

@@ -26,7 +26,13 @@ namespace Barotrauma.Networking
get;
private set;
}
public double LastAmplitude
{
get;
private set;
}
public float Gain
{
get { return GameMain.Config?.MicrophoneVolume ?? 1.0f; }
@@ -191,6 +197,7 @@ namespace Barotrauma.Networking
double dB = Math.Min(20 * Math.Log10(maxAmplitude), 0.0);
LastdB = dB;
LastAmplitude = maxAmplitude;
bool allowEnqueue = false;
if (GameMain.WindowActive)

View File

@@ -16,7 +16,7 @@ namespace Barotrauma
allowSubVoting = value;
GameMain.NetLobbyScreen.SubList.Enabled = value ||
(GameMain.Client != null && GameMain.Client.HasPermission(ClientPermissions.SelectSub));
GameMain.NetLobbyScreen.InfoFrame.FindChild("subvotes", true).Visible = value;
GameMain.NetLobbyScreen.Frame.FindChild("subvotes", true).Visible = value;
UpdateVoteTexts(null, VoteType.Sub);
GameMain.NetLobbyScreen.SubList.Deselect();
@@ -33,7 +33,7 @@ namespace Barotrauma
value ||
(GameMain.Client != null && GameMain.Client.HasPermission(ClientPermissions.SelectMode));
GameMain.NetLobbyScreen.InfoFrame.FindChild("modevotes", true).Visible = value;
GameMain.NetLobbyScreen.Frame.FindChild("modevotes", true).Visible = value;
//gray out modes that can't be voted
foreach (GUITextBlock comp in GameMain.NetLobbyScreen.ModeList.Content.Children)

View File

@@ -25,7 +25,7 @@ namespace Barotrauma.Particles
public void Emit(float deltaTime, Vector2 position, Hull hullGuess = null, float angle = 0.0f, float particleRotation = 0.0f, float velocityMultiplier = 1.0f, float sizeMultiplier = 1.0f, float amountMultiplier = 1.0f)
{
emitTimer += deltaTime * amountMultiplier;
burstEmitTimer += deltaTime;
burstEmitTimer -= deltaTime;
if (Prefab.ParticlesPerSecond > 0)
{
@@ -37,9 +37,9 @@ namespace Barotrauma.Particles
}
}
if (burstEmitTimer < Prefab.EmitInterval) return;
burstEmitTimer = 0.0f;
if (burstEmitTimer > 0.0f) { return; }
burstEmitTimer = Prefab.EmitInterval;
for (int i = 0; i < Prefab.ParticleAmount * amountMultiplier; i++)
{
Emit(position, hullGuess, angle, particleRotation, velocityMultiplier, sizeMultiplier);

View File

@@ -31,10 +31,12 @@ namespace Barotrauma
static void Main(string[] args)
{
GameMain game = null;
string executableDir = "";
#if !DEBUG
try
{
#endif
executableDir = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
SteamManager.Initialize();
game = new GameMain(args);
game.Run();
@@ -45,7 +47,7 @@ namespace Barotrauma
{
try
{
CrashDump(game, "crashreport.log", e);
CrashDump(game, Path.Combine(executableDir,"crashreport.log"), e);
}
catch (Exception e2)
{

View File

@@ -62,25 +62,35 @@ namespace Barotrauma
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, TextManager.Get("MapSeed"));
seedBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, ToolBox.RandomSeed(8));
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, TextManager.Get("SelectedSub"));
var filterContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), isHorizontal: true)
if (!isMultiplayer)
{
Stretch = true
};
subList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.65f), leftColumn.RectTransform)) { ScrollBarVisible = true };
var searchTitle = new GUITextBlock(new RectTransform(new Vector2(0.001f, 1.0f), filterContainer.RectTransform), TextManager.Get("serverlog.filter"), textAlignment: Alignment.CenterLeft, font: GUI.Font);
var searchBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 1.0f), filterContainer.RectTransform, Anchor.CenterRight), font: GUI.Font);
searchBox.OnSelected += (sender, userdata) => { searchTitle.Visible = false; };
searchBox.OnDeselected += (sender, userdata) => { searchTitle.Visible = true; };
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, TextManager.Get("SelectedSub"));
searchBox.OnTextChanged += (textBox, text) => { FilterSubs(subList, text); return true; };
var clearButton = new GUIButton(new RectTransform(new Vector2(0.075f, 1.0f), filterContainer.RectTransform), "x")
var filterContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), isHorizontal: true)
{
Stretch = true
};
subList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.65f), leftColumn.RectTransform)) { ScrollBarVisible = true };
var searchTitle = new GUITextBlock(new RectTransform(new Vector2(0.001f, 1.0f), filterContainer.RectTransform), TextManager.Get("serverlog.filter"), textAlignment: Alignment.CenterLeft, font: GUI.Font);
var searchBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 1.0f), filterContainer.RectTransform, Anchor.CenterRight), font: GUI.Font);
searchBox.OnSelected += (sender, userdata) => { searchTitle.Visible = false; };
searchBox.OnDeselected += (sender, userdata) => { searchTitle.Visible = true; };
searchBox.OnTextChanged += (textBox, text) => { FilterSubs(subList, text); return true; };
var clearButton = new GUIButton(new RectTransform(new Vector2(0.075f, 1.0f), filterContainer.RectTransform), "x")
{
OnClicked = (btn, userdata) => { searchBox.Text = ""; FilterSubs(subList, ""); searchBox.Flash(Color.White); return true; }
};
subList.OnSelected = OnSubSelected;
}
else // Spacing to fix the multiplayer campaign setup layout
{
OnClicked = (btn, userdata) => { searchBox.Text = ""; FilterSubs(subList, ""); searchBox.Flash(Color.White); return true; }
};
if (!isMultiplayer) { subList.OnSelected = OnSubSelected; }
//spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.25f), leftColumn.RectTransform), style: null);
}
// New game right side
subPreviewContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.8f), rightColumn.RectTransform))
@@ -103,7 +113,18 @@ namespace Barotrauma
return false;
}
if (!(subList.SelectedData is Submarine selectedSub)) { return false; }
Submarine selectedSub = null;
if (!isMultiplayer)
{
if (!(subList.SelectedData is Submarine)) { return false; }
selectedSub = subList.SelectedData as Submarine;
}
else
{
if (GameMain.NetLobbyScreen.SelectedSub == null) { return false; }
selectedSub = GameMain.NetLobbyScreen.SelectedSub;
}
if (string.IsNullOrEmpty(selectedSub.MD5Hash.Hash))
{
@@ -189,7 +210,7 @@ namespace Barotrauma
leftColumn.Recalculate();
rightColumn.Recalculate();
UpdateSubList(submarines);
if (submarines != null) { UpdateSubList(submarines); }
UpdateLoadMenu(saveFiles);
}
@@ -228,7 +249,8 @@ namespace Barotrauma
msgBox.Buttons[0].OnClicked = (btn, userdata) =>
{
GameMain.NetLobbyScreen.SelectMode(0);
GameMain.NetLobbyScreen.HighlightMode(GameMain.NetLobbyScreen.SelectedModeIndex);
GameMain.NetLobbyScreen.SelectMode(GameMain.NetLobbyScreen.SelectedModeIndex);
CoroutineManager.StopCoroutines("WaitForCampaignSetup");
return true;
};

View File

@@ -12,28 +12,33 @@ namespace Barotrauma
{
public enum Tab { Map, Crew, Store, Repair }
private Tab selectedTab;
private GUIFrame[] tabs;
private GUIFrame topPanel;
private readonly GUIFrame[] tabs;
private readonly GUIFrame topPanel;
private GUIListBox characterList;
private readonly GUIListBox characterList;
private MapEntityCategory selectedItemCategory = MapEntityCategory.Equipment;
private GUIListBox myItemList;
private GUIListBox storeItemList;
private GUITextBox searchBox;
private readonly GUIListBox myItemList;
private readonly GUIListBox storeItemList;
private readonly GUITextBox searchBox;
private GUIComponent missionPanel;
private GUIComponent selectedLocationInfo;
private GUIListBox selectedMissionInfo;
private readonly GUIComponent missionPanel;
private readonly GUIComponent selectedLocationInfo;
private readonly GUIListBox selectedMissionInfo;
private GUIButton repairHullsButton, replaceShuttlesButton, repairItemsButton;
private readonly GUIButton repairHullsButton, replaceShuttlesButton, repairItemsButton;
private GUIFrame characterPreviewFrame;
private List<GUIButton> tabButtons = new List<GUIButton>();
private List<GUIButton> itemCategoryButtons = new List<GUIButton>();
private List<GUITickBox> missionTickBoxes = new List<GUITickBox>();
private bool displayMissionPanelInMapTab;
private readonly List<GUIButton> tabButtons = new List<GUIButton>();
private readonly List<GUIButton> itemCategoryButtons = new List<GUIButton>();
private readonly List<GUITickBox> missionTickBoxes = new List<GUITickBox>();
private GUIRadioButtonGroup missionRadioButtonGroup = new GUIRadioButtonGroup();
private Location selectedLocation;
public Action StartRound;
public Action<Location, LocationConnection> OnLocationSelected;
@@ -41,12 +46,12 @@ namespace Barotrauma
public Level SelectedLevel { get; private set; }
public GUIComponent MapContainer { get; private set; }
public GUIButton StartButton { get; private set; }
public CampaignMode Campaign { get; }
public CampaignUI(CampaignMode campaign, GUIFrame container)
public CampaignUI(CampaignMode campaign, GUIComponent container)
{
this.Campaign = campaign;
@@ -99,7 +104,8 @@ namespace Barotrauma
new GUITextBlock(new RectTransform(new Vector2(0.8f, 0.9f), tabButton.RectTransform, i == 0 ? Anchor.CenterLeft : Anchor.CenterRight) { RelativeOffset = new Vector2(0.05f, 0.0f) },
TextManager.Get(tab.ToString()), textColor: tabButton.TextColor, font: GUI.LargeFont, textAlignment: Alignment.Center, style: null)
{
UserData = "buttontext"
UserData = "buttontext",
Padding = new Vector4(GUI.Scale * 1)
};
}
else
@@ -107,7 +113,8 @@ namespace Barotrauma
new GUITextBlock(new RectTransform(new Vector2(0.7f, 0.9f), tabButton.RectTransform, Anchor.Center),
TextManager.Get(tab.ToString()), textColor: tabButton.TextColor, font: GUI.LargeFont, textAlignment: Alignment.Center, style: null)
{
UserData = "buttontext"
UserData = "buttontext",
Padding = new Vector4(GUI.Scale * 1)
};
}
@@ -129,6 +136,7 @@ namespace Barotrauma
}, color: Color.Black * 0.9f);
new GUIFrame(new RectTransform(new Vector2(1.25f, 1.25f), tabs[(int)Tab.Crew].RectTransform, Anchor.Center), style: "OuterGlow", color: Color.Black * 0.7f)
{
UserData = "outerglow",
CanBeFocused = false
};
@@ -174,21 +182,18 @@ namespace Barotrauma
}, color: Color.Black * 0.9f);
new GUIFrame(new RectTransform(new Vector2(1.25f, 1.25f), tabs[(int)Tab.Store].RectTransform, Anchor.Center), style: "OuterGlow", color: Color.Black * 0.7f)
{
UserData = "outerglow",
CanBeFocused = false
};
List<MapEntityCategory> itemCategories = Enum.GetValues(typeof(MapEntityCategory)).Cast<MapEntityCategory>().ToList();
//don't show categories with no buyable items
itemCategories.RemoveAll(c =>
!MapEntityPrefab.List.Any(ep => ep.Category.HasFlag(c) && (ep is ItemPrefab) && ((ItemPrefab)ep).CanBeBought));
var storeContent = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), tabs[(int)Tab.Store].RectTransform, Anchor.Center))
{
UserData = "content",
Stretch = true,
RelativeSpacing = 0.02f
RelativeSpacing = 0.015f
};
var storeContentTop = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), storeContent.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft)
var storeContentTop = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), storeContent.RectTransform) { MinSize = new Point(0, (int)(30 * GUI.Scale)) }, isHorizontal: true, childAnchor: Anchor.CenterLeft)
{
Stretch = true
};
@@ -197,7 +202,7 @@ namespace Barotrauma
{
TextGetter = GetMoney
};
var filterContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 0.4f), storeContentTop.RectTransform), isHorizontal: true)
var filterContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 0.4f), storeContentTop.RectTransform) { MinSize = new Point(0, (int)(25 * GUI.Scale)) }, isHorizontal: true)
{
Stretch = true
};
@@ -214,6 +219,7 @@ namespace Barotrauma
var storeItemLists = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.8f), storeContent.RectTransform), isHorizontal: true)
{
RelativeSpacing = 0.03f,
Stretch = true
};
myItemList = new GUIListBox(new RectTransform(new Vector2(0.5f, 1.0f), storeItemLists.RectTransform));
@@ -226,6 +232,11 @@ namespace Barotrauma
{
RelativeSpacing = 0.02f
};
List<MapEntityCategory> itemCategories = Enum.GetValues(typeof(MapEntityCategory)).Cast<MapEntityCategory>().ToList();
//don't show categories with no buyable items
itemCategories.RemoveAll(c =>
!MapEntityPrefab.List.Any(ep => ep.Category.HasFlag(c) && (ep is ItemPrefab) && ((ItemPrefab)ep).CanBeBought));
foreach (MapEntityCategory category in itemCategories)
{
var categoryButton = new GUIButton(new RectTransform(new Point(categoryButtonContainer.Rect.Width), categoryButtonContainer.RectTransform),
@@ -268,6 +279,7 @@ namespace Barotrauma
}, color: Color.Black * 0.9f);
new GUIFrame(new RectTransform(new Vector2(1.25f, 1.25f), tabs[(int)Tab.Repair].RectTransform, Anchor.Center), style: "OuterGlow", color: Color.Black * 0.7f)
{
UserData = "outerglow",
CanBeFocused = false
};
@@ -293,7 +305,7 @@ namespace Barotrauma
IgnoreLayoutGroups = true,
CanBeFocused = false
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), repairHullsHolder.RectTransform), TextManager.Get("RepairAllWalls"), textAlignment: Alignment.Right, font: GUI.LargeFont)
var repairHullsLabel = new GUITextBlock(new RectTransform(new Vector2(0.7f, 0.3f), repairHullsHolder.RectTransform), TextManager.Get("RepairAllWalls"), textAlignment: Alignment.Right, font: GUI.LargeFont)
{
ForceUpperCase = true
};
@@ -338,7 +350,7 @@ namespace Barotrauma
IgnoreLayoutGroups = true,
CanBeFocused = false
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), repairItemsHolder.RectTransform), TextManager.Get("RepairAllItems"), textAlignment: Alignment.Right, font: GUI.LargeFont)
var repairItemsLabel = new GUITextBlock(new RectTransform(new Vector2(0.7f, 0.3f), repairItemsHolder.RectTransform), TextManager.Get("RepairAllItems"), textAlignment: Alignment.Right, font: GUI.LargeFont)
{
ForceUpperCase = true
};
@@ -383,7 +395,7 @@ namespace Barotrauma
IgnoreLayoutGroups = true,
CanBeFocused = false
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), replaceShuttlesHolder.RectTransform), TextManager.Get("ReplaceLostShuttles"), textAlignment: Alignment.Right, font: GUI.LargeFont)
var replaceShuttlesLabel = new GUITextBlock(new RectTransform(new Vector2(0.7f, 0.3f), replaceShuttlesHolder.RectTransform), TextManager.Get("ReplaceLostShuttles"), textAlignment: Alignment.Right, font: GUI.LargeFont)
{
ForceUpperCase = true
};
@@ -422,6 +434,7 @@ namespace Barotrauma
{
CanBeFocused = false
};
GUITextBlock.AutoScaleAndNormalize(repairHullsLabel, repairItemsLabel, replaceShuttlesLabel);
// mission info -------------------------------------------------------------------------
@@ -436,6 +449,7 @@ namespace Barotrauma
new GUIFrame(new RectTransform(new Vector2(1.25f, 1.25f), missionPanel.RectTransform, Anchor.Center), style: "OuterGlow", color: Color.Black * 0.7f)
{
UserData = "outerglow",
CanBeFocused = false
};
@@ -443,6 +457,7 @@ namespace Barotrauma
{ RelativeOffset = new Vector2(0.1f, -0.05f) }, TextManager.Get("Mission"),
textAlignment: Alignment.Center, font: GUI.LargeFont, style: "GUISlopedHeader")
{
UserData = "missionlabel",
AutoScale = true
};
var missionPanelContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), missionPanel.RectTransform, Anchor.Center))
@@ -460,6 +475,11 @@ namespace Barotrauma
{
Visible = false
};
new GUIFrame(new RectTransform(new Vector2(1.25f, 1.25f), selectedMissionInfo.RectTransform, Anchor.Center), style: "OuterGlow", color: Color.Black * 0.9f)
{
UserData = "outerglow",
CanBeFocused = false
};
// -------------------------------------------------------------------------
@@ -473,15 +493,57 @@ namespace Barotrauma
campaign.Map.OnLocationChanged += (prevLocation, newLocation) => UpdateLocationView(newLocation);
campaign.Map.OnMissionSelected += (connection, mission) =>
{
var selectedTickBox = missionTickBoxes.Find(tb => tb.UserData == mission);
if (selectedTickBox != null)
var selectedTickBox = (missionRadioButtonGroup.UserData as List<Mission>).FindIndex(m => m == mission);
if (selectedTickBox >= 0)
{
selectedTickBox.Selected = true;
missionRadioButtonGroup.Selected = selectedTickBox;
}
};
campaign.CargoManager.OnItemsChanged += RefreshMyItems;
}
public void SetMissionPanelParent(RectTransform parent)
{
missionPanel.RectTransform.Parent = parent;
missionPanel.RectTransform.RelativeOffset = Vector2.Zero;
missionPanel.RectTransform.RelativeSize = Vector2.One;
var outerGlow = missionPanel.GetChildByUserData("outerglow");
if (outerGlow != null) { outerGlow.Visible = false; }
var label = missionPanel.GetChildByUserData("missionlabel");
if (label != null) { label.Visible = false; }
displayMissionPanelInMapTab = true;
selectedMissionInfo.RectTransform.RelativeOffset = Vector2.Zero;
selectedMissionInfo.RectTransform.SetPosition(Anchor.BottomLeft, Pivot.BottomRight);
}
public void SetMenuPanelParent(RectTransform parent)
{
for (int i = 0; i < tabs.Length; i++)
{
var panel = tabs[i];
if (panel == null) { continue; }
panel.RectTransform.Parent = parent;
panel.RectTransform.RelativeOffset = Vector2.Zero;
panel.RectTransform.RelativeSize = Vector2.One;
var outerGlow = panel.GetChildByUserData("outerglow");
if (outerGlow != null) { outerGlow.Visible = false; }
if (i == (int)Tab.Store)
{
panel.RectTransform.RelativeSize *= new Vector2(1.5f, 1.0f);
panel.RectTransform.SetPosition(Anchor.TopRight);
var content = panel.GetChildByUserData("content");
if (content != null) { content.RectTransform.RelativeSize = Vector2.One; }
new GUIFrame(new RectTransform(new Vector2(1.107f, 1.0f), panel.RectTransform, Anchor.TopRight), style: null)
{
Color = Color.Black,
CanBeFocused = false
}.SetAsFirstChild();
}
}
}
private void UpdateLocationView(Location location)
{
if (location == null)
@@ -606,8 +668,14 @@ namespace Barotrauma
public void SelectLocation(Location location, LocationConnection connection)
{
selectedLocationInfo.ClearChildren();
missionPanel.Visible = location != null;
//don't select the map panel if the tabs are displayed in the same place as the map, and we're looking at some other tab
if (!displayMissionPanelInMapTab || selectedTab == Tab.Map)
{
SelectTab(Tab.Map);
missionPanel.Visible = location != null;
}
selectedLocation = location;
if (location == null) { return; }
var container = selectedLocationInfo;
@@ -643,30 +711,43 @@ namespace Barotrauma
Mission selectedMission = Campaign.Map.CurrentLocation.SelectedMission != null && availableMissions.Contains(Campaign.Map.CurrentLocation.SelectedMission) ?
Campaign.Map.CurrentLocation.SelectedMission : null;
missionTickBoxes.Clear();
foreach (Mission mission in availableMissions)
missionRadioButtonGroup = new GUIRadioButtonGroup
{
UserData = availableMissions
};
for (int i = 0; i < availableMissions.Count; i++)
{
var mission = availableMissions[i];
var tickBox = new GUITickBox(new RectTransform(new Vector2(0.1f, 0.1f), missionContent.RectTransform) { MaxSize = maxTickBoxSize },
mission?.Name ?? TextManager.Get("NoMission"))
mission?.Name ?? TextManager.Get("NoMission"), style: "GUIRadioButton")
{
UserData = mission,
Enabled = GameMain.Client == null || GameMain.Client.HasPermission(Networking.ClientPermissions.ManageCampaign),
Selected = mission == selectedMission,
OnSelected = (tb) =>
{
if (!tb.Selected) { return false; }
RefreshMissionTab(tb.UserData as Mission);
Campaign.Map.OnMissionSelected?.Invoke(connection, mission);
if ((Campaign is MultiPlayerCampaign multiPlayerCampaign) && !multiPlayerCampaign.SuppressStateSending &&
GameMain.Client != null && GameMain.Client.HasPermission(Networking.ClientPermissions.ManageCampaign))
{
GameMain.Client?.SendCampaignState();
}
return true;
}
Enabled = GameMain.Client == null || GameMain.Client.HasPermission(Networking.ClientPermissions.ManageCampaign)
};
missionTickBoxes.Add(tickBox);
missionRadioButtonGroup.AddRadioButton(i, tickBox);
}
if (GameMain.Client == null || GameMain.Client.HasPermission(Networking.ClientPermissions.ManageCampaign))
{
missionRadioButtonGroup.OnSelect = (rbg, missionInd) =>
{
int ind = missionInd ?? -1;
if (ind < 0) { return; }
var mission = availableMissions[ind];
if (Campaign.Map.CurrentLocation.SelectedMission == mission) { return; }
if (rbg.Selected == missionInd) { return; }
RefreshMissionTab(mission);
if ((Campaign is MultiPlayerCampaign multiPlayerCampaign) && !multiPlayerCampaign.SuppressStateSending &&
GameMain.Client != null && GameMain.Client.HasPermission(Networking.ClientPermissions.ManageCampaign))
{
GameMain.Client?.SendCampaignState();
}
};
}
missionRadioButtonGroup.Selected = availableMissions.IndexOf(selectedMission);
RefreshMissionTab(selectedMission);
StartButton = new GUIButton(new RectTransform(new Vector2(0.3f, 0.7f), missionContent.RectTransform, Anchor.CenterRight),
@@ -697,9 +778,10 @@ namespace Barotrauma
GameMain.GameSession.Map.CurrentLocation.SelectedMission = selectedMission;
foreach (GUITickBox missionTickBox in missionTickBoxes)
var selectedTickBoxIndex = (missionRadioButtonGroup.UserData as List<Mission>).FindIndex(m => m == selectedMission);
if (selectedTickBoxIndex >= 0)
{
missionTickBox.Selected = missionTickBox.UserData == selectedMission;
missionRadioButtonGroup.Selected = selectedTickBoxIndex;
}
selectedMissionInfo.ClearChildren();
@@ -734,7 +816,7 @@ namespace Barotrauma
}
}
private GUIComponent CreateItemFrame(PurchasedItem pi, PriceInfo priceInfo, GUIListBox listBox, int width)
private GUIComponent CreateItemFrame(PurchasedItem pi, PriceInfo priceInfo, GUIListBox listBox)
{
GUIFrame frame = new GUIFrame(new RectTransform(new Point(listBox.Content.Rect.Width, (int)(GUI.Scale * 50)), listBox.Content.RectTransform), style: "ListBoxElement")
{
@@ -865,7 +947,7 @@ namespace Barotrauma
var itemFrame = myItemList.Content.GetChildByUserData(pi);
if (itemFrame == null)
{
itemFrame = CreateItemFrame(pi, pi.ItemPrefab.GetPrice(Campaign.Map.CurrentLocation), myItemList, myItemList.Rect.Width);
itemFrame = CreateItemFrame(pi, pi.ItemPrefab.GetPrice(Campaign.Map.CurrentLocation), myItemList);
}
itemFrame.GetChild(0).GetChild<GUINumberInput>().IntValue = pi.Quantity;
existingItemFrames.Add(itemFrame);
@@ -894,6 +976,9 @@ namespace Barotrauma
tabs[i].Visible = (int)selectedTab == i;
}
}
missionPanel.Visible = tab == Tab.Map && selectedLocation != null;
foreach (GUIButton button in tabButtons)
{
button.Selected = (Tab)button.UserData == tab;
@@ -932,7 +1017,6 @@ namespace Barotrauma
float prevStoreItemScroll = storeItemList.BarScroll;
float prevMyItemScroll = myItemList.BarScroll;
int width = storeItemList.Rect.Width;
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
foreach (MapEntityPrefab mapEntityPrefab in MapEntityPrefab.List)
{
@@ -943,7 +1027,7 @@ namespace Barotrauma
var itemFrame = myItemList.Content.GetChildByUserData(priceInfo);
if (itemFrame == null)
{
itemFrame = CreateItemFrame(new PurchasedItem(itemPrefab, 0), priceInfo, storeItemList, width);
itemFrame = CreateItemFrame(new PurchasedItem(itemPrefab, 0), priceInfo, storeItemList);
}
existingItemFrames.Add(itemFrame);
}
@@ -1005,7 +1089,7 @@ namespace Barotrauma
if (characterPreviewFrame == null || characterPreviewFrame.UserData != characterInfo)
{
characterPreviewFrame = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.5f), tabs[(int)selectedTab].RectTransform, Anchor.TopRight, Pivot.TopLeft))
characterPreviewFrame = new GUIFrame(new RectTransform(new Vector2(0.75f, 0.5f), tabs[(int)selectedTab].RectTransform, Anchor.TopRight, Pivot.TopLeft))
{
UserData = characterInfo
};

View File

@@ -121,6 +121,7 @@ namespace Barotrauma.CharacterEditor
ResetVariables();
Submarine.MainSub = new Submarine("Content/AnimEditor.sub");
Submarine.MainSub.Load(unloadPrevious: false, showWarningMessages: false);
Submarine.MainSub.PhysicsBody.Enabled = false;
originalWall = new WallGroup(new List<Structure>(Structure.WallList));
CloneWalls();
CalculateMovementLimits();
@@ -716,13 +717,13 @@ namespace Barotrauma.CharacterEditor
limbEditWidgets.Values.ForEach(w => w.Update((float)deltaTime));
animationWidgets.Values.ForEach(w => w.Update((float)deltaTime));
// Handle limb selection
if (editLimbs && PlayerInput.LeftButtonDown() && GUI.MouseOn == null && Widget.selectedWidgets.None())
if (PlayerInput.LeftButtonDown() && GUI.MouseOn == null && Widget.selectedWidgets.None())
{
foreach (Limb limb in character.AnimController.Limbs)
{
if (limb == null || limb.ActiveSprite == null) { continue; }
// Select limbs on ragdoll
if (!spriteSheetRect.Contains(PlayerInput.MousePosition) && MathUtils.RectangleContainsPoint(GetLimbPhysicRect(limb), PlayerInput.MousePosition))
if (editLimbs && !spriteSheetRect.Contains(PlayerInput.MousePosition) && MathUtils.RectangleContainsPoint(GetLimbPhysicRect(limb), PlayerInput.MousePosition))
{
HandleLimbSelection(limb);
}
@@ -795,7 +796,7 @@ namespace Barotrauma.CharacterEditor
}
// GUI
spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
if (drawDamageModifiers)
{
foreach (Limb limb in character.AnimController.Limbs)
@@ -926,14 +927,14 @@ namespace Barotrauma.CharacterEditor
{
UpdateOtherLimbs(lastLimb, l => TryUpdateSubParam(l.Params, "spriteorientation", angle));
}
}, circleRadius: 40, widgetSize: 15, rotationOffset: MathHelper.Pi, autoFreeze: false);
}, circleRadius: 40, widgetSize: 15, rotationOffset: MathHelper.Pi, autoFreeze: false, rounding: 10);
}
else
{
var topLeft = spriteSheetControls.RectTransform.TopLeft;
GUI.DrawString(spriteBatch, new Vector2(topLeft.X + 350 * GUI.xScale, GameMain.GraphicsHeight - 95 * GUI.yScale), GetCharacterEditorTranslation("SpriteSheetOrientation") + ":", Color.White, Color.Gray * 0.5f, 10, GUI.Font);
DrawRadialWidget(spriteBatch, new Vector2(topLeft.X + 560 * GUI.xScale, GameMain.GraphicsHeight - 75 * GUI.yScale), RagdollParams.SpritesheetOrientation, string.Empty, Color.White,
angle => TryUpdateRagdollParam("spritesheetorientation", angle), circleRadius: 40, widgetSize: 15, rotationOffset: MathHelper.Pi, autoFreeze: false);
angle => TryUpdateRagdollParam("spritesheetorientation", angle), circleRadius: 40, widgetSize: 15, rotationOffset: MathHelper.Pi, autoFreeze: false, rounding: 10);
}
}
// Debug
@@ -1763,7 +1764,7 @@ namespace Barotrauma.CharacterEditor
{
case AnimationType.Walk:
case AnimationType.Run:
if (!ragdollParams.CanEnterSubmarine) { continue; }
if (!ragdollParams.CanWalk) { continue; }
break;
case AnimationType.SwimSlow:
case AnimationType.SwimFast:
@@ -1903,7 +1904,7 @@ namespace Barotrauma.CharacterEditor
};
Vector2 buttonSize = new Vector2(1, 0.04f);
Vector2 toggleSize = new Vector2(0.03f, 0.03f);
Vector2 toggleSize = new Vector2(1.0f, 0.03f);
CreateCharacterSelectionPanel();
CreateMinorModesPanel(toggleSize);
@@ -3212,6 +3213,10 @@ namespace Barotrauma.CharacterEditor
{
CreateCloseButton(emitter.SerializableEntityEditor, () => CharacterParams.RemoveGibEmitter(emitter));
}
foreach (var emitter in CharacterParams.DamageEmitters)
{
CreateCloseButton(emitter.SerializableEntityEditor, () => CharacterParams.RemoveDamageEmitter(emitter));
}
foreach (var sound in CharacterParams.Sounds)
{
CreateCloseButton(sound.SerializableEntityEditor, () => CharacterParams.RemoveSound(sound));
@@ -3228,6 +3233,7 @@ namespace Barotrauma.CharacterEditor
}
CreateAddButtonAtLast(mainEditor, () => CharacterParams.AddBloodEmitter(), GetCharacterEditorTranslation("AddBloodEmitter"));
CreateAddButtonAtLast(mainEditor, () => CharacterParams.AddGibEmitter(), GetCharacterEditorTranslation("AddGibEmitter"));
CreateAddButtonAtLast(mainEditor, () => CharacterParams.AddDamageEmitter(), GetCharacterEditorTranslation("AddDamageEmitter"));
CreateAddButtonAtLast(mainEditor, () => CharacterParams.AddSound(), GetCharacterEditorTranslation("AddSound"));
CreateAddButtonAtLast(mainEditor, () => CharacterParams.AddInventory(), GetCharacterEditorTranslation("AddInventory"));
}
@@ -3590,6 +3596,10 @@ namespace Barotrauma.CharacterEditor
private void HandleLimbSelection(Limb limb)
{
if (!editLimbs)
{
SetToggle(limbsToggle, true);
}
if (!selectedLimbs.Contains(limb))
{
if (!Widget.EnableMultiSelect)
@@ -4103,7 +4113,7 @@ namespace Barotrauma.CharacterEditor
// Fish swim only -->
else if (tail != null && fishSwimParams != null)
{
float amplitudeMultiplier = 0.5f;
float amplitudeMultiplier = 20;
float lengthMultiplier = 20;
int points = 1000;
float GetAmplitude() => ConvertUnits.ToDisplayUnits(fishSwimParams.WaveAmplitude) * Cam.Zoom / amplitudeMultiplier;
@@ -4120,7 +4130,7 @@ namespace Barotrauma.CharacterEditor
w.MouseHeld += dTime =>
{
float input = Vector2.Multiply(ConvertUnits.ToSimUnits(PlayerInput.MouseSpeed), GetScreenSpaceForward()).Combine() / Cam.Zoom * lengthMultiplier;
TryUpdateAnimParam("wavelength", MathHelper.Clamp(fishSwimParams.WaveLength - input, 0, 150));
TryUpdateAnimParam("wavelength", MathHelper.Clamp(fishSwimParams.WaveLength - input, 0, 200));
};
// Additional
w.PreDraw += (sp, dTime) =>
@@ -4138,7 +4148,7 @@ namespace Barotrauma.CharacterEditor
w.MouseHeld += dTime =>
{
float input = Vector2.Multiply(ConvertUnits.ToSimUnits(PlayerInput.MouseSpeed), GetScreenSpaceForward().Right()).Combine() * character.AnimController.Dir / Cam.Zoom * amplitudeMultiplier;
TryUpdateAnimParam("waveamplitude", MathHelper.Clamp(fishSwimParams.WaveAmplitude + input, -4, 4));
TryUpdateAnimParam("waveamplitude", MathHelper.Clamp(fishSwimParams.WaveAmplitude + input, -100, 100));
};
// Additional
w.PreDraw += (sp, dTime) =>
@@ -4407,7 +4417,7 @@ namespace Barotrauma.CharacterEditor
DrawJointLimitWidgets(spriteBatch, limb, joint, tformedJointPos, autoFreeze: true, allowPairEditing: true, rotationOffset: limb.Rotation, holdPosition: true);
}
// Is the direction inversed incorrectly?
Vector2 to = tformedJointPos + VectorExtensions.ForwardFlipped(joint.LimbB.Rotation + MathHelper.ToRadians(-joint.LimbB.Params.GetSpriteOrientation()), 20);
Vector2 to = tformedJointPos + VectorExtensions.ForwardFlipped(joint.LimbB.Rotation - joint.LimbB.Params.GetSpriteOrientation(), 20);
GUI.DrawLine(spriteBatch, tformedJointPos, to, Color.Magenta, width: 2);
var dotSize = new Vector2(5, 5);
var rect = new Rectangle((tformedJointPos - dotSize / 2).ToPoint(), dotSize.ToPoint());
@@ -5010,7 +5020,7 @@ namespace Barotrauma.CharacterEditor
private void DrawJointLimitWidgets(SpriteBatch spriteBatch, Limb limb, LimbJoint joint, Vector2 drawPos, bool autoFreeze, bool allowPairEditing, bool holdPosition, float rotationOffset = 0)
{
rotationOffset += limb.Params.GetSpriteOrientation();
rotationOffset -= limb.Params.GetSpriteOrientation();
Color angleColor = joint.UpperLimit - joint.LowerLimit > 0 ? Color.LightGreen * 0.5f : Color.Red;
DrawRadialWidget(spriteBatch, drawPos, MathHelper.ToDegrees(joint.UpperLimit), $"{joint.Params.Name}: {GetCharacterEditorTranslation("UpperLimit")}", Color.Cyan, angle =>
{
@@ -5176,7 +5186,7 @@ namespace Barotrauma.CharacterEditor
#region Widgets as methods
private void DrawRadialWidget(SpriteBatch spriteBatch, Vector2 drawPos, float value, string toolTip, Color color, Action<float> onClick,
float circleRadius = 30, int widgetSize = 10, float rotationOffset = 0, bool clockWise = true, bool displayAngle = true, bool? autoFreeze = null, bool wrapAnglePi = false, bool holdPosition = false)
float circleRadius = 30, int widgetSize = 10, float rotationOffset = 0, bool clockWise = true, bool displayAngle = true, bool? autoFreeze = null, bool wrapAnglePi = false, bool holdPosition = false, int rounding = 1)
{
var angle = value;
if (!MathUtils.IsValid(angle))
@@ -5195,6 +5205,8 @@ namespace Barotrauma.CharacterEditor
? MathUtils.VectorToAngle(d) - MathHelper.PiOver2 + rotationOffset
: -MathUtils.VectorToAngle(d) + MathHelper.PiOver2 - rotationOffset;
angle = MathHelper.ToDegrees(wrapAnglePi ? MathUtils.WrapAnglePi(newAngle) : MathUtils.WrapAngleTwoPi(newAngle));
angle = (float)Math.Round(angle / rounding) * rounding;
if (angle >= 360 || angle <= -360) { angle = 0; }
if (displayAngle)
{
GUI.DrawString(spriteBatch, drawPos, angle.FormatZeroDecimal(), Color.Black, backgroundColor: color, font: GUI.SmallFont);

View File

@@ -15,6 +15,7 @@ namespace Barotrauma.CharacterEditor
private string name;
private bool isHumanoid;
private bool canEnterSubmarine = true;
private bool canWalk;
private string texturePath;
private string xmlPath;
private ContentPackage contentPackage;
@@ -37,6 +38,7 @@ namespace Barotrauma.CharacterEditor
name = character.SpeciesName;
isHumanoid = character.Humanoid;
canEnterSubmarine = ragdoll.CanEnterSubmarine;
canWalk = ragdoll.CanWalk;
texturePath = ragdoll.Texture;
}
@@ -165,7 +167,7 @@ namespace Barotrauma.CharacterEditor
texturePathElement.Text = TexturePath;
}
}
for (int i = 0; i < 6; i++)
for (int i = 0; i < 7; i++)
{
var mainElement = new GUIFrame(new RectTransform(new Point(topGroup.RectTransform.Rect.Width, elementSize), topGroup.RectTransform), style: null, color: Color.Gray * 0.25f);
fields.Add(mainElement);
@@ -212,6 +214,19 @@ namespace Barotrauma.CharacterEditor
}
break;
case 3:
var lbl = new GUITextBlock(leftElement, GetCharacterEditorTranslation("CanWalk"));
var txt = new GUITickBox(rightElement, string.Empty)
{
Selected = CanWalk,
Enabled = !IsCopy,
OnSelected = (tB) => CanWalk = tB.Selected
};
if (!txt.Enabled)
{
lbl.TextColor *= 0.6f;
}
break;
case 4:
new GUITextBlock(leftElement, GetCharacterEditorTranslation("ConfigFileOutput"));
xmlPathElement = new GUITextBox(rightElement, string.Empty)
{
@@ -224,7 +239,7 @@ namespace Barotrauma.CharacterEditor
return true;
};
break;
case 4:
case 5:
//new GUITextBlock(leftElement, GetCharacterEditorTranslation("TexturePath"));
texturePathElement = new GUITextBox(rightElement, string.Empty)
{
@@ -257,7 +272,7 @@ namespace Barotrauma.CharacterEditor
}
};
break;
case 5:
case 6:
mainElement.RectTransform.NonScaledSize = new Point(
mainElement.RectTransform.NonScaledSize.X,
mainElement.RectTransform.NonScaledSize.Y * 2);
@@ -356,6 +371,7 @@ namespace Barotrauma.CharacterEditor
{
SourceRagdoll.Texture = TexturePath;
SourceRagdoll.CanEnterSubmarine = CanEnterSubmarine;
SourceRagdoll.CanWalk = CanWalk;
SourceRagdoll.Serialize();
Wizard.Instance.CreateCharacter(SourceRagdoll.MainElement, SourceCharacter.MainElement, SourceAnimations);
}
@@ -754,6 +770,7 @@ namespace Barotrauma.CharacterEditor
new XAttribute("type", Name),
new XAttribute("texture", TexturePath),
new XAttribute("canentersubmarine", CanEnterSubmarine),
new XAttribute("canwalk", CanWalk),
colliderElements,
LimbXElements.Values,
JointXElements);
@@ -873,6 +890,11 @@ namespace Barotrauma.CharacterEditor
get => Instance.canEnterSubmarine;
set => Instance.canEnterSubmarine = value;
}
public bool CanWalk
{
get => Instance.canWalk;
set => Instance.canWalk = value;
}
public ContentPackage ContentPackage
{
get => Instance.contentPackage;

View File

@@ -37,7 +37,7 @@ namespace Barotrauma
{
GUIComponent.FromXML(subElement, listBox.Content.RectTransform);
}
foreach (GUIComponent child in listBox.Children)
foreach (GUIComponent child in listBox.Content.Children)
{
child.CanBeFocused = false;
}

View File

@@ -94,7 +94,7 @@ namespace Barotrauma
GameMain.PerformanceCounter.AddElapsedTicks("DrawMap", sw.ElapsedTicks);
sw.Restart();
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, GameMain.ScissorTestEnable);
spriteBatch.Begin(SpriteSortMode.Deferred, null, GUI.SamplerState, null, GameMain.ScissorTestEnable);
if (Character.Controlled != null && cam != null) Character.Controlled.DrawHUD(spriteBatch, cam);

View File

@@ -471,7 +471,7 @@ namespace Barotrauma
GameMain.SpriteEditorScreen.Draw(deltaTime, graphics, spriteBatch);
}
spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
GUI.Draw(Cam, spriteBatch);
spriteBatch.End();
}

View File

@@ -55,7 +55,7 @@ namespace Barotrauma
GUI.DrawBackgroundSprite(spriteBatch,
GameMain.GameSession.Map.CurrentLocation.Type.GetPortrait(GameMain.GameSession.Map.CurrentLocation.PortraitId));
spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
GUI.Draw(Cam, spriteBatch);
spriteBatch.End();
}

View File

@@ -1,4 +1,6 @@
using Barotrauma.Extensions;
//#define TEST_REMOTE_CONTENT
using Barotrauma.Extensions;
using Barotrauma.Networking;
using Barotrauma.Tutorials;
using Lidgren.Network;
@@ -19,27 +21,28 @@ namespace Barotrauma
{
public enum Tab { NewGame = 1, LoadGame = 2, HostServer = 3, Settings = 4, Tutorials = 5, JoinServer = 6, CharacterEditor = 7, SubmarineEditor = 8, QuickStartDev = 9, SteamWorkshop = 10, Credits = 11, Empty = 12 }
private GUIComponent buttonsParent;
private readonly GUIComponent buttonsParent;
private readonly GUIFrame[] menuTabs;
private CampaignSetupUI campaignSetupUI;
private readonly CampaignSetupUI campaignSetupUI;
private GUITextBox serverNameBox, /*portBox, queryPortBox,*/ passwordBox, maxPlayersBox;
private GUITickBox isPublicBox/*, useUpnpBox*/;
private readonly GUIButton joinServerButton, hostServerButton, steamWorkshopButton;
private readonly GameMain game;
private GUIButton joinServerButton, hostServerButton, steamWorkshopButton;
private GameMain game;
private GUIImage playstyleBanner;
private GUITextBlock playstyleDescription;
private Tab selectedTab;
private Sprite backgroundSprite;
private Sprite backgroundVignette;
private GUIComponent titleText;
private readonly GUIComponent titleText;
private CreditsPlayer creditsPlayer;
private readonly CreditsPlayer creditsPlayer;
#if OSX
private bool firstLoadOnMac = true;
@@ -70,15 +73,20 @@ namespace Barotrauma
RelativeSpacing = 0.02f
};
FetchRemoteContent(Frame.RectTransform);
/*var doc = XMLExtensions.TryLoadXml("Content/UI/MenuTextTest.xml");
#if TEST_REMOTE_CONTENT
var doc = XMLExtensions.TryLoadXml("Content/UI/MenuTextTest.xml");
if (doc?.Root != null)
{
foreach (XElement subElement in doc?.Root.Elements())
{
GUIComponent.FromXML(subElement, Frame.RectTransform);
}
}*/
}
#else
FetchRemoteContent(Frame.RectTransform);
#endif
// === CAMPAIGN
var campaignHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 1.0f), parent: buttonsParent.RectTransform) { RelativeOffset = new Vector2(0.1f, 0.0f) }, isHorizontal: true);
@@ -331,7 +339,7 @@ namespace Barotrauma
StartNewGame = StartGame
};
var hostServerScale = new Vector2(0.7f, 0.6f);
var hostServerScale = new Vector2(0.7f, 1.2f);
menuTabs[(int)Tab.HostServer] = new GUIFrame(new RectTransform(
Vector2.Multiply(relativeSize, hostServerScale), GUI.Canvas, anchor, pivot, minSize.Multiply(hostServerScale), maxSize.Multiply(hostServerScale)) { RelativeOffset = relativeSpacing });
@@ -374,9 +382,9 @@ namespace Barotrauma
};
}
#endregion
#endregion
#region Selection
#region Selection
public override void Select()
{
base.Select();
@@ -393,7 +401,7 @@ namespace Barotrauma
GameAnalyticsManager.SetCustomDimension01("");
#if OSX
#if OSX
// Hack for adjusting the viewport properly after splash screens on older Macs
if (firstLoadOnMac)
{
@@ -410,7 +418,7 @@ namespace Barotrauma
SelectTab(null, Tab.Empty);
}
#endif
#endif
}
public override void Deselect()
@@ -482,6 +490,7 @@ namespace Barotrauma
GameMain.ServerListScreen.Select();
break;
case Tab.HostServer:
SetServerPlayStyle(PlayStyle.Serious);
if (!GameMain.Config.CampaignDisclaimerShown)
{
selectedTab = 0;
@@ -661,13 +670,15 @@ namespace Barotrauma
{
GameMain.Config.SaveNewPlayerConfig();
if (userData is Tab) SelectTab(button, (Tab)userData);
if (userData is Tab) { SelectTab(button, (Tab)userData); }
if (GameMain.GraphicsWidth != GameMain.Config.GraphicsWidth || GameMain.GraphicsHeight != GameMain.Config.GraphicsHeight)
if (GameMain.GraphicsWidth != GameMain.Config.GraphicsWidth ||
GameMain.GraphicsHeight != GameMain.Config.GraphicsHeight ||
ContentPackage.List.Any(cp => cp.NeedsRestart))
{
new GUIMessageBox(
TextManager.Get("RestartRequiredLabel"),
TextManager.Get("RestartRequiredText"));
TextManager.Get("RestartRequiredGeneric"));
}
return true;
@@ -744,6 +755,7 @@ namespace Barotrauma
string arguments = "-name \"" + name.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"" +
" -public " + isPublicBox.Selected.ToString() +
" -playstyle " + ((PlayStyle)playstyleBanner.UserData).ToString() +
" -password \"" + passwordBox.Text.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"" +
" -maxplayers " + maxPlayersBox.Text;
@@ -856,7 +868,7 @@ namespace Barotrauma
{
DrawBackground(graphics, spriteBatch);
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, GameMain.ScissorTestEnable);
spriteBatch.Begin(SpriteSortMode.Deferred, null, GUI.SamplerState, null, GameMain.ScissorTestEnable);
GUI.Draw(Cam, spriteBatch);
@@ -981,22 +993,79 @@ namespace Barotrauma
Alignment textAlignment = Alignment.CenterLeft;
Vector2 textFieldSize = new Vector2(0.5f, 1.0f);
Vector2 tickBoxSize = new Vector2(0.4f, 0.07f);
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.85f, 0.75f), menuTabs[(int)Tab.HostServer].RectTransform, Anchor.TopCenter) { RelativeOffset = new Vector2(0.0f, 0.05f) })
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.85f, 0.8f), menuTabs[(int)Tab.HostServer].RectTransform, Anchor.TopCenter) { RelativeOffset = new Vector2(0.0f, 0.05f) })
{
RelativeSpacing = 0.02f,
Stretch = true
};
GUIComponent parent = paddedFrame;
new GUITextBlock(new RectTransform(textLabelSize, parent.RectTransform), TextManager.Get("HostServerButton"), textAlignment: Alignment.Center, font: GUI.LargeFont) { ForceUpperCase = true };
//play style -----------------------------------------------------
var playstyleContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.5f), parent.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft)
{
Stretch = true,
Color = Color.Black
//RelativeSpacing = 0.02f
};
new GUIButton(new RectTransform(new Vector2(0.05f, 1.0f), playstyleContainer.RectTransform), style: "UIToggleButton")
{
OnClicked = (btn, userdata) =>
{
int playStyleIndex = (int)playstyleBanner.UserData - 1;
if (playStyleIndex < 0) { playStyleIndex = Enum.GetValues(typeof(PlayStyle)).Length - 1; }
SetServerPlayStyle((PlayStyle)playStyleIndex);
return true;
}
}.Children.ForEach(c => c.SpriteEffects = SpriteEffects.FlipHorizontally);
playstyleBanner = new GUIImage(new RectTransform(new Vector2(0.8f, 1.0f), playstyleContainer.RectTransform), style: null, scaleToFit: true)
{
UserData = PlayStyle.Serious
};
new GUITextBlock(new RectTransform(new Vector2(0.15f, 0.05f), playstyleBanner.RectTransform) { RelativeOffset = new Vector2(0.01f, 0.06f) },
"playstyle name goes here", font: GUI.SmallFont, textAlignment: Alignment.Center, textColor: Color.White, style: "GUISlopedHeader");
new GUIButton(new RectTransform(new Vector2(0.05f, 1.0f), playstyleContainer.RectTransform), style: "UIToggleButton")
{
OnClicked = (btn, userdata) =>
{
int playStyleIndex = (int)playstyleBanner.UserData + 1;
if (playStyleIndex >= Enum.GetValues(typeof(PlayStyle)).Length) { playStyleIndex = 0; }
SetServerPlayStyle((PlayStyle)playStyleIndex);
return true;
}
};
string longestPlayStyleStr = "";
foreach (PlayStyle playStyle in Enum.GetValues(typeof(PlayStyle)))
{
string playStyleStr = TextManager.Get("servertagdescription." + playStyle);
if (playStyleStr.Length > longestPlayStyleStr.Length) { longestPlayStyleStr = playStyleStr; }
}
playstyleDescription = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), playstyleBanner.RectTransform, Anchor.BottomCenter),
"playstyle description goes here", style: null, wrap: true)
{
Color = Color.Black * 0.8f,
TextColor = Color.White
};
playstyleDescription.Padding = Vector4.One * 10.0f * GUI.Scale;
playstyleDescription.CalculateHeightFromText(padding: (int)(15 * GUI.Scale));
playstyleDescription.RectTransform.MinSize = new Point(0, playstyleDescription.Rect.Height);
//other settings -----------------------------------------------------
var label = new GUITextBlock(new RectTransform(textLabelSize, parent.RectTransform), TextManager.Get("ServerName"), textAlignment: textAlignment);
serverNameBox = new GUITextBox(new RectTransform(textFieldSize, label.RectTransform, Anchor.CenterRight), textAlignment: textAlignment)
{
MaxTextLength = NetConfig.ServerNameMaxLength,
OverflowClip = true
};
/* TODO: allow lidgren servers from client?
label = new GUITextBlock(new RectTransform(textLabelSize, parent.RectTransform), TextManager.Get("ServerPort"), textAlignment: textAlignment);
portBox = new GUITextBox(new RectTransform(textFieldSize, label.RectTransform, Anchor.CenterRight), textAlignment: textAlignment)
@@ -1064,7 +1133,21 @@ namespace Barotrauma
OnClicked = HostServerClicked
};
}
#endregion
private void SetServerPlayStyle(PlayStyle playStyle)
{
playstyleBanner.Sprite = GameMain.ServerListScreen.PlayStyleBanners[(int)playStyle];
playstyleBanner.UserData = playStyle;
var nameText = playstyleBanner.GetChild<GUITextBlock>();
nameText.Text = TextManager.AddPunctuation(':', TextManager.Get("serverplaystyle"), TextManager.Get("servertag." + playStyle));
nameText.Color = GameMain.ServerListScreen.PlayStyleColors[(int)playStyle];
nameText.RectTransform.NonScaledSize = (nameText.Font.MeasureString(nameText.Text) + new Vector2(25, 10) * GUI.Scale).ToPoint();
playstyleDescription.Text = TextManager.Get("servertagdescription." + playStyle);
playstyleDescription.CalculateHeightFromText(padding: (int)(15 * GUI.Scale));
}
#endregion
private void FetchRemoteContent(RectTransform parent)
{

File diff suppressed because it is too large Load Diff

View File

@@ -300,7 +300,7 @@ namespace Barotrauma
//-------------------------------------------------------
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, GameMain.ScissorTestEnable);
spriteBatch.Begin(SpriteSortMode.Deferred, null, GUI.SamplerState, null, GameMain.ScissorTestEnable);
GUI.Draw(Cam, spriteBatch);

File diff suppressed because it is too large Load Diff

View File

@@ -332,7 +332,7 @@ namespace Barotrauma
string spriteFolder = "";
string textureElement = element.GetAttributeString("texture", "");
// TODO: parse and create?
if (textureElement.Contains("[GENDER]") || textureElement.Contains("[HEADID]") || textureElement.Contains("[RACE]")) { return; }
if (textureElement.Contains("[GENDER]") || textureElement.Contains("[HEADID]") || textureElement.Contains("[RACE]") || textureElement.Contains("[VARIANT]")) { return; }
if (!textureElement.Contains("/"))
{
var parsedPath = element.ParseContentPathFromUri();
@@ -428,42 +428,23 @@ namespace Barotrauma
viewAreaOffset += moveSpeed.ToPoint();
}
}
if (PlayerInput.KeyHit(Keys.Left))
if (GUI.KeyboardDispatcher.Subscriber == null)
{
foreach (var sprite in selectedSprites)
Point moveAmount = Point.Zero;
if (PlayerInput.KeyHit(Keys.Left)) { moveAmount.X--; }
if (PlayerInput.KeyHit(Keys.Right)) { moveAmount.X++; }
if (PlayerInput.KeyHit(Keys.Up)) { moveAmount.Y--; }
if (PlayerInput.KeyHit(Keys.Down)) { moveAmount.Y++; }
if (moveAmount != Point.Zero)
{
var newRect = sprite.SourceRect;
newRect.X--;
UpdateSourceRect(sprite, newRect);
foreach (var sprite in selectedSprites)
{
var newRect = sprite.SourceRect;
newRect.Location += moveAmount;
UpdateSourceRect(sprite, newRect);
}
}
}
if (PlayerInput.KeyHit(Keys.Right))
{
foreach (var sprite in selectedSprites)
{
var newRect = sprite.SourceRect;
newRect.X++;
UpdateSourceRect(sprite, newRect);
}
}
if (PlayerInput.KeyHit(Keys.Down))
{
foreach (var sprite in selectedSprites)
{
var newRect = sprite.SourceRect;
newRect.Y++;
UpdateSourceRect(sprite, newRect);
}
}
if (PlayerInput.KeyHit(Keys.Up))
{
foreach (var sprite in selectedSprites)
{
var newRect = sprite.SourceRect;
newRect.Y--;
UpdateSourceRect(sprite, newRect);
}
}
}
}
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)

View File

@@ -1492,7 +1492,7 @@ namespace Barotrauma
else
{
string errorMsg = item.ErrorCode.HasValue ?
TextManager.Get("WorkshopPublishError." + item.ErrorCode.Value.ToString(), returnNull: true) :
TextManager.GetWithVariable("WorkshopPublishError." + item.ErrorCode.Value.ToString(), "[savepath]", SaveUtil.SaveFolder, returnNull: true) :
null;
if (errorMsg == null)
@@ -1520,7 +1520,7 @@ namespace Barotrauma
GameMain.MainMenuScreen.DrawBackground(graphics, spriteBatch);
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, GameMain.ScissorTestEnable);
spriteBatch.Begin(SpriteSortMode.Deferred, null, GUI.SamplerState, null, GameMain.ScissorTestEnable);
GUI.Draw(Cam, spriteBatch);
spriteBatch.End();
}

View File

@@ -87,6 +87,13 @@ namespace Barotrauma
return (Submarine.MainSub == null) ? "" : Submarine.MainSub.Name;
}
public string GetSubDescription()
{
string localizedDescription = TextManager.Get("submarine.description." + GetSubName(), true);
if (localizedDescription != null) return localizedDescription;
return (Submarine.MainSub == null) ? "" : Submarine.MainSub.Description;
}
private string GetItemCount()
{
return TextManager.AddPunctuation(':', TextManager.Get("Items"), Item.ItemList.Count.ToString());
@@ -1048,8 +1055,10 @@ namespace Barotrauma
submarineDescriptionCharacterCount = new GUITextBlock(new RectTransform(new Vector2(.5f, 1f), descriptionHeaderGroup.RectTransform), string.Empty, textAlignment: Alignment.TopRight);
var descriptionContainer = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.25f), leftColumn.RectTransform));
descriptionBox = new GUITextBox(new RectTransform(Vector2.One, descriptionContainer.Content.RectTransform, Anchor.Center), font: GUI.SmallFont, wrap: true, textAlignment: Alignment.TopLeft);
descriptionBox.Padding = new Vector4(10 * GUI.Scale);
descriptionBox = new GUITextBox(new RectTransform(Vector2.One, descriptionContainer.Content.RectTransform, Anchor.Center), font: GUI.SmallFont, wrap: true, textAlignment: Alignment.TopLeft)
{
Padding = new Vector4(10 * GUI.Scale)
};
descriptionBox.OnTextChanged += (textBox, text) =>
{
@@ -1068,6 +1077,8 @@ namespace Barotrauma
return true;
};
descriptionBox.Text = GetSubDescription();
var crewSizeArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.03f), leftColumn.RectTransform), isHorizontal: true) { AbsoluteSpacing = 5 };
new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), crewSizeArea.RectTransform),
@@ -2478,7 +2489,7 @@ namespace Barotrauma
//-------------------- HUD -----------------------------
spriteBatch.Begin(SpriteSortMode.Deferred);
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState);
if (Submarine.MainSub != null)
{

View File

@@ -808,16 +808,19 @@ namespace Barotrauma
AbsoluteOffset = new Point(label.Rect.Width, 0)
}, color: Color.Black, style: null);
var colorBox = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), colorBoxBack.RectTransform, Anchor.Center), style: null);
var inputArea = new GUILayoutGroup(new RectTransform(new Vector2(0.7f, 1), frame.RectTransform, Anchor.TopRight), isHorizontal: true, childAnchor: Anchor.CenterRight)
var inputArea = new GUILayoutGroup(new RectTransform(new Vector2(Math.Max((frame.Rect.Width - label.Rect.Width - colorBoxBack.Rect.Width) / (float)frame.Rect.Width, 0.5f), 1), frame.RectTransform, Anchor.TopRight), isHorizontal: true, childAnchor: Anchor.CenterRight)
{
Stretch = true,
RelativeSpacing = 0.01f
RelativeSpacing = 0.001f
};
var fields = new GUIComponent[4];
for (int i = 3; i >= 0; i--)
{
var element = new GUIFrame(new RectTransform(new Vector2(0.2f, 1), inputArea.RectTransform) { MinSize = new Point(40, 0), MaxSize = new Point(100, 50) }, style: null);
new GUITextBlock(new RectTransform(new Vector2(0.3f, 1), element.RectTransform, Anchor.CenterLeft), GUI.colorComponentLabels[i], font: GUI.SmallFont, textAlignment: Alignment.CenterLeft);
var element = new GUILayoutGroup(new RectTransform(new Vector2(0.2f, 1), inputArea.RectTransform), isHorizontal: true)
{
Stretch = true
};
new GUITextBlock(new RectTransform(new Vector2(0.2f, 1), element.RectTransform, Anchor.CenterLeft) { MinSize = new Point(15, 0) }, GUI.colorComponentLabels[i], font: GUI.SmallFont, textAlignment: Alignment.Center);
GUINumberInput numberInput = new GUINumberInput(new RectTransform(new Vector2(0.7f, 1), element.RectTransform, Anchor.CenterRight),
GUINumberInput.NumberType.Int)
{

View File

@@ -83,6 +83,8 @@ namespace Barotrauma.Sounds
private const int STREAM_BUFFER_SIZE = 8820;
private short[] streamShortBuffer;
private string debugName = "SoundChannel";
private Vector3? position;
public Vector3? Position
{
@@ -91,7 +93,7 @@ namespace Barotrauma.Sounds
{
position = value;
if (ALSourceIndex < 0) return;
if (ALSourceIndex < 0) { return; }
if (position != null)
{
@@ -100,14 +102,14 @@ namespace Barotrauma.Sounds
int alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to enable source's relative flag: " + Al.GetErrorString(alError));
throw new Exception("Failed to enable source's relative flag: " + debugName + ", " + Al.GetErrorString(alError));
}
Al.Source3f(alSource, Al.Position, position.Value.X, position.Value.Y, position.Value.Z);
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to set source's position: " + Al.GetErrorString(alError));
throw new Exception("Failed to set source's position: " + debugName + ", " + Al.GetErrorString(alError));
}
}
else
@@ -117,14 +119,14 @@ namespace Barotrauma.Sounds
int alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to disable source's relative flag: " + Al.GetErrorString(alError));
throw new Exception("Failed to disable source's relative flag: " + debugName + ", " + Al.GetErrorString(alError));
}
Al.Source3f(alSource, Al.Position, 0.0f, 0.0f, 0.0f);
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to reset source's position: " + Al.GetErrorString(alError));
throw new Exception("Failed to reset source's position: " + debugName + ", " + Al.GetErrorString(alError));
}
}
}
@@ -138,7 +140,7 @@ namespace Barotrauma.Sounds
{
near = value;
if (ALSourceIndex < 0) return;
if (ALSourceIndex < 0) { return; }
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
Al.Sourcef(alSource, Al.ReferenceDistance, near);
@@ -146,7 +148,7 @@ namespace Barotrauma.Sounds
int alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to set source's reference distance: " + Al.GetErrorString(alError));
throw new Exception("Failed to set source's reference distance: " + debugName + ", " + Al.GetErrorString(alError));
}
}
}
@@ -159,14 +161,14 @@ namespace Barotrauma.Sounds
{
far = value;
if (ALSourceIndex < 0) return;
if (ALSourceIndex < 0) { return; }
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
Al.Sourcef(alSource, Al.MaxDistance, far);
int alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to set source's max distance: " + Al.GetErrorString(alError));
throw new Exception("Failed to set source's max distance: " + debugName + ", " + Al.GetErrorString(alError));
}
}
}
@@ -179,7 +181,7 @@ namespace Barotrauma.Sounds
{
gain = Math.Max(Math.Min(value, 1.0f), 0.0f);
if (ALSourceIndex < 0) return;
if (ALSourceIndex < 0) { return; }
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
@@ -190,7 +192,7 @@ namespace Barotrauma.Sounds
int alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to set source's gain: " + Al.GetErrorString(alError));
throw new Exception("Failed to set source's gain: " + debugName + ", " + Al.GetErrorString(alError));
}
}
}
@@ -203,7 +205,7 @@ namespace Barotrauma.Sounds
{
looping = value;
if (ALSourceIndex < 0) return;
if (ALSourceIndex < 0) { return; }
if (!IsStream)
{
@@ -212,7 +214,7 @@ namespace Barotrauma.Sounds
int alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to set source's looping state: " + Al.GetErrorString(alError));
throw new Exception("Failed to set source's looping state: " + debugName + ", " + Al.GetErrorString(alError));
}
}
}
@@ -232,11 +234,11 @@ namespace Barotrauma.Sounds
get { return muffled; }
set
{
if (muffled == value) return;
if (muffled == value) { return; }
muffled = value;
if (ALSourceIndex < 0) return;
if (ALSourceIndex < 0) { return; }
if (!IsPlaying) return;
@@ -247,7 +249,7 @@ namespace Barotrauma.Sounds
int alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to get source's playback position: " + Al.GetErrorString(alError));
throw new Exception("Failed to get source's playback position: " + debugName + ", " + Al.GetErrorString(alError));
}
Al.SourceStop(alSource);
@@ -255,7 +257,7 @@ namespace Barotrauma.Sounds
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to stop source: " + Al.GetErrorString(alError));
throw new Exception("Failed to stop source: " + debugName + ", " + Al.GetErrorString(alError));
}
Al.Sourcei(alSource, Al.Buffer, muffled ? (int)Sound.ALMuffledBuffer : (int)Sound.ALBuffer);
@@ -263,21 +265,21 @@ namespace Barotrauma.Sounds
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to bind buffer to source: " + Al.GetErrorString(alError));
throw new Exception("Failed to bind buffer to source: " + debugName + ", " + Al.GetErrorString(alError));
}
Al.SourcePlay(alSource);
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to replay source: " + Al.GetErrorString(alError));
throw new Exception("Failed to replay source: " + debugName + ", " + Al.GetErrorString(alError));
}
Al.Sourcei(alSource, Al.SampleOffset, playbackPos);
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to reset playback position: " + Al.GetErrorString(alError));
throw new Exception("Failed to reset playback position: " + debugName + ", " + Al.GetErrorString(alError));
}
}
}
@@ -290,7 +292,7 @@ namespace Barotrauma.Sounds
{
if (!IsPlaying) { return 0.0f; }
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
uint alSource = Sound?.Owner?.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex) ?? 0;
if (alSource == 0) { return 0.0f; }
@@ -300,7 +302,7 @@ namespace Barotrauma.Sounds
int alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to get source's playback position: " + Al.GetErrorString(alError));
throw new Exception("Failed to get source's playback position: " + debugName + ", " + Al.GetErrorString(alError));
}
return Sound.GetAmplitudeAtPlaybackPos(playbackPos);
}
@@ -367,7 +369,7 @@ namespace Barotrauma.Sounds
int alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to determine playing state from source: " + Al.GetErrorString(alError));
throw new Exception("Failed to determine playing state from source: " + debugName + ", " + Al.GetErrorString(alError));
}
return playing;
}
@@ -377,6 +379,10 @@ namespace Barotrauma.Sounds
{
Sound = sound;
debugName = sound == null ?
"SoundChannel (null)" :
$"SoundChannel ({(string.IsNullOrEmpty(sound.Filename) ? "filename empty" : sound.Filename) })";
IsStream = sound.Stream;
FilledByNetwork = sound is VoipSound;
decayTimer = 0;
@@ -405,7 +411,7 @@ namespace Barotrauma.Sounds
int alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to reset source buffer: " + Al.GetErrorString(alError));
throw new Exception("Failed to reset source buffer: " + debugName + ", " + Al.GetErrorString(alError));
}
if (!Al.IsBuffer(sound.ALBuffer))
@@ -418,14 +424,14 @@ namespace Barotrauma.Sounds
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to bind buffer to source (" + ALSourceIndex.ToString() + ":" + sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex) + "," + sound.ALBuffer.ToString() + "): " + Al.GetErrorString(alError));
throw new Exception("Failed to bind buffer to source (" + ALSourceIndex.ToString() + ":" + sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex) + "," + sound.ALBuffer.ToString() + "): " + debugName + ", " + Al.GetErrorString(alError));
}
Al.SourcePlay(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex));
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to play source: " + Al.GetErrorString(alError));
throw new Exception("Failed to play source: " + debugName + ", " + Al.GetErrorString(alError));
}
}
else
@@ -435,14 +441,14 @@ namespace Barotrauma.Sounds
int alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to reset source buffer: " + Al.GetErrorString(alError));
throw new Exception("Failed to reset source buffer: " + debugName + ", " + Al.GetErrorString(alError));
}
Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Looping, Al.False);
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to set stream looping state: " + Al.GetErrorString(alError));
throw new Exception("Failed to set stream looping state: " + debugName + ", " + Al.GetErrorString(alError));
}
streamShortBuffer = new short[STREAM_BUFFER_SIZE];
@@ -457,12 +463,12 @@ namespace Barotrauma.Sounds
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to generate stream buffers: " + Al.GetErrorString(alError));
throw new Exception("Failed to generate stream buffers: " + debugName + ", " + Al.GetErrorString(alError));
}
if (!Al.IsBuffer(streamBuffers[i]))
{
throw new Exception("Generated streamBuffer[" + i.ToString() + "] is invalid!");
throw new Exception("Generated streamBuffer[" + i.ToString() + "] is invalid! " + debugName);
}
}
Sound.Owner.InitStreamThread();
@@ -488,6 +494,11 @@ namespace Barotrauma.Sounds
Sound.Owner.Update();
}
public override string ToString()
{
return debugName;
}
public bool FadingOutAndDisposing;
public void FadeOutAndDispose()
{
@@ -505,7 +516,7 @@ namespace Barotrauma.Sounds
int alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to stop source: " + Al.GetErrorString(alError));
throw new Exception("Failed to stop source: " + debugName + ", " + Al.GetErrorString(alError));
}
if (IsStream)
@@ -516,7 +527,7 @@ namespace Barotrauma.Sounds
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to stop streamed source: " + Al.GetErrorString(alError));
throw new Exception("Failed to stop streamed source: " + debugName + ", " + Al.GetErrorString(alError));
}
int buffersToRequeue = 0;
@@ -526,21 +537,21 @@ namespace Barotrauma.Sounds
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to determine processed buffers from streamed source: " + Al.GetErrorString(alError));
throw new Exception("Failed to determine processed buffers from streamed source: " + debugName + ", " + Al.GetErrorString(alError));
}
Al.SourceUnqueueBuffers(alSource, buffersToRequeue, unqueuedBuffers);
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to unqueue buffers from streamed source: " + Al.GetErrorString(alError));
throw new Exception("Failed to unqueue buffers from streamed source: " + debugName + ", " + Al.GetErrorString(alError));
}
Al.Sourcei(alSource, Al.Buffer, 0);
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to reset buffer for streamed source: " + Al.GetErrorString(alError));
throw new Exception("Failed to reset buffer for streamed source: " + debugName + ", " + Al.GetErrorString(alError));
}
for (int i = 0; i < 4; i++)
@@ -549,7 +560,7 @@ namespace Barotrauma.Sounds
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to delete streamBuffers[" + i.ToString() + "] ("+streamBuffers[i].ToString()+"): " + Al.GetErrorString(alError));
throw new Exception("Failed to delete streamBuffers[" + i.ToString() + "] (" + streamBuffers[i].ToString() + "): " + debugName + ", " + Al.GetErrorString(alError));
}
}
@@ -561,11 +572,12 @@ namespace Barotrauma.Sounds
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to unbind buffer to non-streamed source: " + Al.GetErrorString(alError));
throw new Exception("Failed to unbind buffer to non-streamed source: " + debugName + ", " + Al.GetErrorString(alError));
}
}
ALSourceIndex = -1;
debugName += " [DISPOSED]";
}
}
finally
@@ -576,7 +588,7 @@ namespace Barotrauma.Sounds
public void UpdateStream()
{
if (!IsStream) throw new Exception("Called UpdateStream on a non-streamed sound channel!");
if (!IsStream) { throw new Exception("Called UpdateStream on a non-streamed sound channel!"); }
try
{
@@ -591,7 +603,7 @@ namespace Barotrauma.Sounds
int alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to determine playing state from streamed source: " + Al.GetErrorString(alError));
throw new Exception("Failed to determine playing state from streamed source: " + debugName + ", " + Al.GetErrorString(alError));
}
int unqueuedBufferCount;
@@ -599,16 +611,16 @@ namespace Barotrauma.Sounds
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to determine processed buffers from streamed source: " + Al.GetErrorString(alError));
throw new Exception("Failed to determine processed buffers from streamed source: " + debugName + ", " + Al.GetErrorString(alError));
}
Al.SourceUnqueueBuffers(alSource, unqueuedBufferCount, unqueuedBuffers);
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to unqueue buffers from streamed source: " + Al.GetErrorString(alError));
throw new Exception("Failed to unqueue buffers from streamed source: " + debugName + ", " + Al.GetErrorString(alError));
}
buffersToRequeue += unqueuedBufferCount;
int iterCount = buffersToRequeue;
@@ -619,7 +631,7 @@ namespace Barotrauma.Sounds
int readSamples = Sound.FillStreamBuffer(streamSeekPos, buffer);
float readAmplitude = 0.0f;
for (int i=0;i<Math.Min(readSamples, buffer.Length);i++)
for (int i = 0; i < Math.Min(readSamples, buffer.Length); i++)
{
float sampleF = ((float)buffer[i]) / ((float)short.MaxValue);
readAmplitude = Math.Max(readAmplitude, Math.Abs(sampleF));
@@ -672,7 +684,7 @@ namespace Barotrauma.Sounds
if (alError != Al.NoError)
{
throw new Exception("Failed to assign data to stream buffer: " +
Al.GetErrorString(alError) + ": " + streamBuffers[index].ToString() + "/" + streamBuffers.Length + ", readSamples: " + readSamples);
Al.GetErrorString(alError) + ": " + streamBuffers[index].ToString() + "/" + streamBuffers.Length + ", readSamples: " + readSamples + ", " + debugName);
}
Al.SourceQueueBuffer(alSource, streamBuffers[index]);
@@ -681,7 +693,7 @@ namespace Barotrauma.Sounds
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to queue streamBuffer[" + index.ToString() + "] to stream: " + Al.GetErrorString(alError));
throw new Exception("Failed to queue streamBuffer[" + index.ToString() + "] to stream: " + debugName + ", " + Al.GetErrorString(alError));
}
}
else

View File

@@ -19,8 +19,8 @@ namespace Barotrauma.Sounds
private set;
}
private IntPtr alcDevice;
private IntPtr alcContext;
private readonly IntPtr alcDevice;
private readonly IntPtr alcContext;
public enum SourcePoolIndex
{
@@ -29,7 +29,7 @@ namespace Barotrauma.Sounds
}
private readonly SoundSourcePool[] sourcePools;
private List<Sound> loadedSounds;
private readonly List<Sound> loadedSounds;
private readonly SoundChannel[][] playingChannels = new SoundChannel[2][];
private Thread streamingThread;
@@ -51,7 +51,7 @@ namespace Barotrauma.Sounds
}
}
private float[] listenerOrientation = new float[6];
private readonly float[] listenerOrientation = new float[6];
public Vector3 ListenerTargetVector
{
get { return new Vector3(listenerOrientation[0], listenerOrientation[1], listenerOrientation[2]); }
@@ -245,8 +245,6 @@ namespace Barotrauma.Sounds
return;
}
int alError = Al.NoError;
sourcePools = new SoundSourcePool[2];
sourcePools[(int)SourcePoolIndex.Default] = new SoundSourcePool(SOURCE_COUNT);
playingChannels[(int)SourcePoolIndex.Default] = new SoundChannel[SOURCE_COUNT];
@@ -256,7 +254,7 @@ namespace Barotrauma.Sounds
Al.DistanceModel(Al.LinearDistanceClamped);
alError = Al.GetError();
int alError = Al.GetError();
if (alError != Al.NoError)
{
DebugConsole.ThrowError("Error setting distance model: " + Al.GetErrorString(alError) + ". Disabling audio playback...");
@@ -488,7 +486,7 @@ namespace Barotrauma.Sounds
if (index < 0)
{
float accumulatedMultipliers = 1.0f;
for (int i=0;i<categoryModifiers[category].GainMultipliers.Length;i++)
for (int i = 0; i < categoryModifiers[category].GainMultipliers.Length; i++)
{
accumulatedMultipliers *= categoryModifiers[category].GainMultipliers[i];
}

View File

@@ -86,7 +86,7 @@ namespace Barotrauma.Sounds
public override SoundChannel Play()
{
return Play(0.5f);
return Play(BaseGain);
}
public override int FillStreamBuffer(int samplePos, short[] buffer)

View File

@@ -0,0 +1,17 @@
using System.Collections.Generic;
using System.Xml.Linq;
using System.Linq;
namespace Barotrauma
{
partial class ConditionalSprite
{
public void Remove()
{
Sprite?.Remove();
Sprite = null;
DeformableSprite?.Remove();
DeformableSprite = null;
}
}
}

View File

@@ -43,8 +43,19 @@ namespace Barotrauma
}
}
private float rotationRadians;
[Serialize(0.0f, true), Editable]
public float Rotation { get; private set; }
public float Rotation
{
get
{
return MathHelper.ToDegrees(rotationRadians);
}
private set
{
rotationRadians = MathHelper.ToRadians(value);
}
}
[Serialize(AnimationType.None, false), Editable]
public AnimationType RotationAnim { get; private set; }
@@ -118,16 +129,16 @@ namespace Barotrauma
{
if (rotationSpeedRadians <= 0.0f)
{
return Rotation;
return rotationRadians;
}
switch (OffsetAnim)
switch (RotationAnim)
{
case AnimationType.Sine:
rotationState = rotationState % (MathHelper.TwoPi / rotationSpeedRadians);
return Rotation * (float)Math.Sin(rotationState * rotationSpeedRadians);
return rotationRadians * (float)Math.Sin(rotationState * rotationSpeedRadians);
case AnimationType.Noise:
rotationState = rotationState % (1.0f / rotationSpeedRadians);
return Rotation * PerlinNoise.GetPerlin(rotationState * rotationSpeedRadians, rotationState * rotationSpeedRadians);
return rotationRadians * (PerlinNoise.GetPerlin(rotationState * rotationSpeedRadians, rotationState * rotationSpeedRadians) - 0.5f);
default:
return rotationState * rotationSpeedRadians;
}

View File

@@ -6,9 +6,9 @@ namespace Barotrauma.SpriteDeformations
{
class InflateParams : SpriteDeformationParams
{
[Serialize(0.0f, true), Editable(MinValueFloat = 0.0f, MaxValueFloat = 100.0f)]
[Serialize(0.0f, true), Editable(MinValueFloat = 0.0f, MaxValueFloat = 100.0f, DecimalCount = 2, ValueStep = 1)]
public override float Frequency { get; set; } = 1;
[Serialize(1.0f, true), Editable(MinValueFloat = 0.01f, MaxValueFloat = 10.0f)]
[Serialize(1.0f, true), Editable(MinValueFloat = 0.01f, MaxValueFloat = 10.0f, DecimalCount = 2, ValueStep = 0.1f)]
public float Scale { get; set; }
public InflateParams(XElement element) : base(element)

View File

@@ -5,7 +5,7 @@ namespace Barotrauma.SpriteDeformations
{
class NoiseDeformationParams : SpriteDeformationParams
{
[Serialize(0.0f, true, description: "The frequency of the noise."), Editable(MinValueFloat = 0.0f, MaxValueFloat = 100.0f)]
[Serialize(0.0f, true, description: "The frequency of the noise."), Editable(MinValueFloat = 0.0f, MaxValueFloat = 100.0f, DecimalCount = 2, ValueStep = 1f)]
public override float Frequency { get; set; }
[Serialize(1.0f, true, description: "How much the noise distorts the sprite."), Editable(MinValueFloat = 0.0f, MaxValueFloat = 10.0f, DecimalCount = 2, ValueStep = 0.01f)]

View File

@@ -52,7 +52,7 @@ namespace Barotrauma
}
}
partial void ApplyProjSpecific(float deltaTime, Entity entity, List<ISerializableEntity> targets, Hull hull)
partial void ApplyProjSpecific(float deltaTime, Entity entity, List<ISerializableEntity> targets, Hull hull, Vector2 worldPosition)
{
if (entity == null) { return; }
@@ -70,7 +70,7 @@ namespace Barotrauma
GameAnalyticsManager.AddErrorEventOnce("StatusEffect.ApplyProjSpecific:SoundNull1" + Environment.StackTrace, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
return;
}
soundChannel = SoundPlayer.PlaySound(sound.Sound, entity.WorldPosition, sound.Volume, sound.Range, hull);
soundChannel = SoundPlayer.PlaySound(sound.Sound, worldPosition, sound.Volume, sound.Range, hull);
if (soundChannel != null) { soundChannel.Looping = loopSound; }
}
}
@@ -96,7 +96,7 @@ namespace Barotrauma
GameAnalyticsManager.AddErrorEventOnce("StatusEffect.ApplyProjSpecific:SoundNull2" + Environment.StackTrace, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
return;
}
soundChannel = SoundPlayer.PlaySound(selectedSound.Sound, entity.WorldPosition, selectedSound.Volume, selectedSound.Range, hull);
soundChannel = SoundPlayer.PlaySound(selectedSound.Sound, worldPosition, selectedSound.Volume, selectedSound.Range, hull);
if (soundChannel != null) { soundChannel.Looping = loopSound; }
}
}
@@ -120,7 +120,7 @@ namespace Barotrauma
}
}
emitter.Emit(deltaTime, entity.WorldPosition, hull, angle);
emitter.Emit(deltaTime, worldPosition, hull, angle);
}
}

View File

@@ -57,13 +57,13 @@ namespace Barotrauma
});
}
public static Texture2D FromFile(string path, bool preMultiplyAlpha = true)
public static Texture2D FromFile(string path, bool preMultiplyAlpha = true, bool mipmap=false)
{
try
{
using (Stream fileStream = File.OpenRead(path))
{
return FromStream(fileStream, preMultiplyAlpha, path);
return FromStream(fileStream, preMultiplyAlpha, path, mipmap);
}
}
@@ -74,7 +74,7 @@ namespace Barotrauma
}
}
public static Texture2D FromStream(Stream fileStream, bool preMultiplyAlpha = true, string path=null)
public static Texture2D FromStream(Stream fileStream, bool preMultiplyAlpha = true, string path=null, bool mipmap=false)
{
try
{
@@ -88,7 +88,7 @@ namespace Barotrauma
Texture2D tex = null;
CrossThread.RequestExecutionOnMainThread(() =>
{
tex = new Texture2D(_graphicsDevice, width, height);
tex = new Texture2D(_graphicsDevice, width, height, mipmap, SurfaceFormat.Color);
tex.SetData(textureData);
});
return tex;

View File

@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.9.4.0")]
[assembly: AssemblyFileVersion("0.9.4.0")]
[assembly: AssemblyVersion("0.9.5.1")]
[assembly: AssemblyFileVersion("0.9.5.1")]

Some files were not shown because too many files have changed in this diff Show More