Merge remote-tracking branch 'upstream/master' into develop
This commit is contained in:
@@ -29,7 +29,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (SelectedAiTarget?.Entity != null)
|
||||
else if (SelectedAiTarget?.Entity != null && AttackLimb != null)
|
||||
{
|
||||
Vector2 targetPos = SelectedAiTarget.Entity.DrawPosition;
|
||||
if (State == AIState.Attack)
|
||||
@@ -37,15 +37,16 @@ namespace Barotrauma
|
||||
targetPos = attackWorldPos;
|
||||
}
|
||||
targetPos.Y = -targetPos.Y;
|
||||
|
||||
GUI.DrawLine(spriteBatch, pos, targetPos, GUIStyle.Red * 0.5f, 0, 4);
|
||||
Vector2 attackLimbPos = AttackLimb.DrawPosition;
|
||||
attackLimbPos.Y = -attackLimbPos.Y;
|
||||
GUI.DrawLine(spriteBatch, attackLimbPos, targetPos, GUIStyle.Red * 0.75f, 0, 4);
|
||||
if (wallTarget != null && !IsCoolDownRunning)
|
||||
{
|
||||
Vector2 wallTargetPos = wallTarget.Position;
|
||||
if (wallTarget.Structure.Submarine != null) { wallTargetPos += wallTarget.Structure.Submarine.DrawPosition; }
|
||||
wallTargetPos.Y = -wallTargetPos.Y;
|
||||
GUI.DrawRectangle(spriteBatch, wallTargetPos - new Vector2(10.0f, 10.0f), new Vector2(20.0f, 20.0f), Color.Orange, false);
|
||||
GUI.DrawLine(spriteBatch, pos, wallTargetPos, Color.Orange * 0.5f, 0, 5);
|
||||
GUI.DrawLine(spriteBatch, attackLimbPos, wallTargetPos, Color.Orange * 0.75f, 0, 5);
|
||||
}
|
||||
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{SelectedAiTarget.Entity}", GUIStyle.Red, Color.Black);
|
||||
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 40.0f, $"{targetValue.FormatZeroDecimal()} (M: {CurrentTargetMemory?.Priority.FormatZeroDecimal()}, P: {CurrentTargetingParams?.Priority.FormatZeroDecimal()})", GUIStyle.Red, Color.Black);
|
||||
|
||||
@@ -23,6 +23,8 @@ namespace Barotrauma
|
||||
//GUI.DrawString(spriteBatch, pos + textOffset, $"AI TARGET: {SelectedAiTarget.Entity.ToString()}", Color.White, Color.Black);
|
||||
}
|
||||
|
||||
Vector2 spacing = new Vector2(0, GUIStyle.Font.MeasureChar('T').Y);
|
||||
|
||||
Vector2 stringDrawPos = pos + textOffset;
|
||||
GUI.DrawString(spriteBatch, stringDrawPos, Character.Name, Color.White, Color.Black);
|
||||
|
||||
@@ -33,14 +35,14 @@ namespace Barotrauma
|
||||
currentOrders.Sort((x, y) => y.ManualPriority.CompareTo(x.ManualPriority));
|
||||
for (int i = 0; i < currentOrders.Count; i++)
|
||||
{
|
||||
stringDrawPos += new Vector2(0, 20);
|
||||
stringDrawPos += spacing;
|
||||
var order = currentOrders[i];
|
||||
GUI.DrawString(spriteBatch, stringDrawPos, $"ORDER {i + 1}: {order.Objective.DebugTag} ({order.Objective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
}
|
||||
}
|
||||
else if (ObjectiveManager.WaitTimer > 0)
|
||||
{
|
||||
stringDrawPos += new Vector2(0, 20);
|
||||
stringDrawPos += spacing;
|
||||
GUI.DrawString(spriteBatch, stringDrawPos - textOffset, $"Waiting... {ObjectiveManager.WaitTimer.FormatZeroDecimal()}", Color.White, Color.Black);
|
||||
}
|
||||
var currentObjective = ObjectiveManager.CurrentObjective;
|
||||
@@ -49,19 +51,19 @@ namespace Barotrauma
|
||||
int offset = currentOrder != null ? 20 + ((ObjectiveManager.CurrentOrders.Count - 1) * 20) : 0;
|
||||
if (currentOrder == null || currentOrder.Priority <= 0)
|
||||
{
|
||||
stringDrawPos += new Vector2(0, 20);
|
||||
stringDrawPos += spacing;
|
||||
GUI.DrawString(spriteBatch, stringDrawPos, $"MAIN OBJECTIVE: {currentObjective.DebugTag} ({currentObjective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
}
|
||||
var subObjective = currentObjective.CurrentSubObjective;
|
||||
if (subObjective != null)
|
||||
{
|
||||
stringDrawPos += new Vector2(0, 20);
|
||||
stringDrawPos += spacing;
|
||||
GUI.DrawString(spriteBatch, stringDrawPos, $"SUBOBJECTIVE: {subObjective.DebugTag} ({subObjective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
}
|
||||
var activeObjective = ObjectiveManager.GetActiveObjective();
|
||||
if (activeObjective != null)
|
||||
{
|
||||
stringDrawPos += new Vector2(0, 20);
|
||||
stringDrawPos += spacing;
|
||||
GUI.DrawString(spriteBatch, stringDrawPos, $"ACTIVE OBJECTIVE: {activeObjective.DebugTag} ({activeObjective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
}
|
||||
if (currentObjective is AIObjectiveCombat
|
||||
@@ -85,12 +87,12 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 objectiveStringDrawPos = stringDrawPos + new Vector2(120, 40);
|
||||
Vector2 objectiveStringDrawPos = stringDrawPos + new Vector2(120, spacing.Y * 2);
|
||||
for (int i = 0; i < ObjectiveManager.Objectives.Count; i++)
|
||||
{
|
||||
var objective = ObjectiveManager.Objectives[i];
|
||||
GUI.DrawString(spriteBatch, objectiveStringDrawPos, $"{objective.DebugTag} ({objective.Priority.FormatZeroDecimal()})", Color.White, Color.Black * 0.5f);
|
||||
objectiveStringDrawPos += new Vector2(0, 18);
|
||||
objectiveStringDrawPos += spacing * 0.8f;
|
||||
}
|
||||
|
||||
if (steeringManager is IndoorsSteeringManager pathSteering)
|
||||
|
||||
@@ -547,7 +547,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, Camera cam)
|
||||
public void Draw(SpriteBatch spriteBatch, Camera cam, bool onlyDrawSeveredLimbs)
|
||||
{
|
||||
if (simplePhysicsEnabled) { return; }
|
||||
|
||||
@@ -573,8 +573,12 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (Limb limb in limbs) { limb.ActiveSprite.Depth += depthOffset; }
|
||||
}
|
||||
for (int i = 0; i < limbs.Length; i++)
|
||||
for (int i = 0; i < inversedLimbDrawOrder.Length; i++)
|
||||
{
|
||||
if (onlyDrawSeveredLimbs && !inversedLimbDrawOrder[i].IsSevered)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
inversedLimbDrawOrder[i].Draw(spriteBatch, cam, color);
|
||||
}
|
||||
if (!MathUtils.NearlyEqual(depthOffset, 0.0f))
|
||||
|
||||
@@ -938,8 +938,8 @@ namespace Barotrauma
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
if (!Enabled || InvisibleTimer > 0.0f) { return; }
|
||||
AnimController.Draw(spriteBatch, cam);
|
||||
if (!Enabled) { return; }
|
||||
AnimController.Draw(spriteBatch, cam, onlyDrawSeveredLimbs: InvisibleTimer > 0.0f);
|
||||
}
|
||||
|
||||
public void DrawHUD(SpriteBatch spriteBatch, Camera cam, bool drawHealth = true)
|
||||
|
||||
@@ -4,6 +4,7 @@ using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System.Collections.Generic;
|
||||
using Barotrauma.Items.Components;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma;
|
||||
|
||||
@@ -106,12 +107,17 @@ public static class InteractionLabelManager
|
||||
}
|
||||
|
||||
RectangleF textRect = GetLabelRect(interactableInRange, cam);
|
||||
|
||||
if (labels.None(l => l.Item == interactableInRange))
|
||||
var existingLabel = labels.FirstOrDefault(l => l.Item == interactableInRange);
|
||||
if (existingLabel == null)
|
||||
{
|
||||
var labelData = new LabelData(interactableInRange, textRect, RichString.Rich(interactableInRange.Prefab.Name), cam);
|
||||
labels.Add(labelData);
|
||||
}
|
||||
//size of the label doesn't match - can happen when we're using a CJK font which we asynchronously render new symbols for
|
||||
else if (existingLabel.TextRect.Size != textRect.Size)
|
||||
{
|
||||
existingLabel.TextRect = textRect;
|
||||
}
|
||||
}
|
||||
|
||||
PreventInteractionLabelOverlap(centerPos: character.Position);
|
||||
@@ -127,7 +133,11 @@ public static class InteractionLabelManager
|
||||
private static RectangleF GetLabelRect(Item item, Camera cam)
|
||||
{
|
||||
// create rectangle for overlap prevention
|
||||
Vector2 itemTextSizeScreen = GUIStyle.SubHeadingFont.MeasureString(RichString.Rich(item.Prefab.Name).SanitizedValue) * LabelScale;
|
||||
|
||||
string nameText = RichString.Rich(item.Prefab.Name).SanitizedValue;
|
||||
|
||||
var font = GUIStyle.SubHeadingFont.GetFontForStr(nameText)!;
|
||||
Vector2 itemTextSizeScreen = font.MeasureString(nameText) * LabelScale;
|
||||
Vector2 interactablePosScreen = cam.WorldToScreen(item.Position);
|
||||
RectangleF textRect = new RectangleF(interactablePosScreen.X, interactablePosScreen.Y, itemTextSizeScreen.X, itemTextSizeScreen.Y);
|
||||
// center the rectangle on the item
|
||||
|
||||
@@ -340,10 +340,6 @@ namespace Barotrauma
|
||||
break;
|
||||
case "randomcolor":
|
||||
randomColor = subElement.GetAttributeColorArray("colors", null)?.GetRandomUnsynced();
|
||||
if (randomColor.HasValue)
|
||||
{
|
||||
Params.GetSprite().Color = randomColor.Value;
|
||||
}
|
||||
break;
|
||||
case "lightsource":
|
||||
LightSource = new LightSource(subElement, GetConditionalTarget())
|
||||
@@ -631,6 +627,8 @@ namespace Barotrauma
|
||||
SoundPlayer.PlayDamageSound(damageSoundType, Math.Max(damage, bleedingDamage), WorldPosition);
|
||||
}
|
||||
|
||||
if (character.InvisibleTimer > 0.0f) { return; }
|
||||
|
||||
// spawn damage particles
|
||||
float damageParticleAmount = damage < 1 ? 0 : Math.Min(damage / 5, 1.0f) * damageMultiplier;
|
||||
if (damageParticleAmount > 0.001f)
|
||||
@@ -734,7 +732,8 @@ namespace Barotrauma
|
||||
if (spriteParams == null || Alpha <= 0) { return; }
|
||||
float burn = spriteParams.IgnoreTint ? 0 : burnOverLayStrength;
|
||||
float brightness = Math.Max(1.0f - burn, 0.2f);
|
||||
Color tintedColor = spriteParams.Color;
|
||||
Color baseColor = randomColor ?? spriteParams.Color;
|
||||
Color tintedColor = baseColor;
|
||||
if (!spriteParams.IgnoreTint)
|
||||
{
|
||||
tintedColor = tintedColor.Multiply(ragdoll.RagdollParams.Color);
|
||||
@@ -752,7 +751,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
Color color = new Color(tintedColor.Multiply(brightness), tintedColor.A);
|
||||
Color colorWithoutTint = new Color(spriteParams.Color.Multiply(brightness), spriteParams.Color.A);
|
||||
Color colorWithoutTint = new Color(baseColor.Multiply(brightness), baseColor.A);
|
||||
Color blankColor = new Color(brightness, brightness, brightness, 1);
|
||||
if (deadTimer > 0)
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Barotrauma
|
||||
|
||||
GUILayoutGroup connLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.12f), labelList.Content.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.4f, 1f), connLayout.RectTransform), text: conn.Connection.DisplayName, font: GUIStyle.SubHeadingFont);
|
||||
GUITextBox box = GUI.CreateTextBoxWithPlaceholder(new RectTransform(new Vector2(0.6f, 1f), connLayout.RectTransform), text: found ? labelOverride : string.Empty, conn.Connection.DisplayName.Value);
|
||||
GUITextBox box = GUI.CreateTextBoxWithPlaceholder(new RectTransform(new Vector2(0.6f, 1f), connLayout.RectTransform), text: found ? labelOverride : string.Empty, conn.Connection.DefaultDisplayName.Value);
|
||||
box.MaxTextLength = MaxConnectionLabelLength;
|
||||
|
||||
textBoxes.Add(conn.Name, box);
|
||||
|
||||
@@ -277,6 +277,14 @@ namespace Barotrauma
|
||||
int selectedOption = (userdata as int?) ?? 0;
|
||||
if (actionInstance != null)
|
||||
{
|
||||
var option = actionInstance.Options[selectedOption];
|
||||
if (GameMain.Client == null && option.ForceSay)
|
||||
{
|
||||
Character.Controlled.ForceSay(
|
||||
option.ForceSayText.IsNullOrEmpty() ? TextManager.Get(option.Text).Fallback(option.Text) : TextManager.Get(option.ForceSayText).Fallback(option.ForceSayText),
|
||||
option.ForceSayInRadio,
|
||||
option.ForceSayRemoveQuotes);
|
||||
}
|
||||
actionInstance.selectedOption = selectedOption;
|
||||
DisableButtons(optionButtons, btn);
|
||||
btn.ExternalHighlight = true;
|
||||
@@ -340,7 +348,8 @@ namespace Barotrauma
|
||||
if (speaker?.Info != null && drawChathead)
|
||||
{
|
||||
// chathead
|
||||
new GUICustomComponent(new RectTransform(new Vector2(0.15f, 0.8f), content.RectTransform), onDraw: (sb, customComponent) =>
|
||||
int chatHeadWidth = (int)(content.RectTransform.Rect.Width * 0.15f);
|
||||
new GUICustomComponent(new RectTransform(new Point(chatHeadWidth, chatHeadWidth), content.RectTransform, isFixedSize: true), onDraw: (sb, customComponent) =>
|
||||
{
|
||||
speaker.Info.DrawIcon(sb, customComponent.Rect.Center.ToVector2(), customComponent.Rect.Size.ToVector2());
|
||||
});
|
||||
@@ -382,7 +391,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
textContent.RectTransform.MinSize = new Point(0, textContent.Children.Sum(c => c.Rect.Height + textContent.AbsoluteSpacing) + GUI.IntScale(16));
|
||||
content.RectTransform.MinSize = new Point(0, content.Children.Sum(c => c.Rect.Height));
|
||||
content.RectTransform.MinSize = textContent.RectTransform.MinSize;
|
||||
|
||||
// Recalculate the text size as it is scaled up and no longer matching the text height due to the textContent's minSize increasing
|
||||
textBlock.CalculateHeightFromText();
|
||||
|
||||
+2
-10
@@ -61,17 +61,9 @@ namespace Barotrauma
|
||||
{
|
||||
Item.ReadSpawnData(msg);
|
||||
}
|
||||
if (character.Submarine != null && character.AIController is EnemyAIController enemyAi)
|
||||
if (character.AIController is EnemyAIController enemyAi && character.Submarine is Submarine ownSub)
|
||||
{
|
||||
enemyAi.UnattackableSubmarines.Add(character.Submarine);
|
||||
if (Submarine.MainSub != null)
|
||||
{
|
||||
enemyAi.UnattackableSubmarines.Add(Submarine.MainSub);
|
||||
foreach (Submarine sub in Submarine.MainSub.DockedTo)
|
||||
{
|
||||
enemyAi.UnattackableSubmarines.Add(sub);
|
||||
}
|
||||
}
|
||||
enemyAi.SetUnattackableSubmarines(ownSub);
|
||||
}
|
||||
}
|
||||
if (characters.Contains(null))
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#nullable enable
|
||||
namespace Barotrauma;
|
||||
|
||||
internal sealed partial class CustomMission : Mission
|
||||
{
|
||||
public override bool DisplayAsCompleted => State == SuccessState;
|
||||
public override bool DisplayAsFailed => State == FailureState;
|
||||
}
|
||||
@@ -14,7 +14,7 @@ namespace Barotrauma
|
||||
|
||||
private void TryShowRetrievedMessage()
|
||||
{
|
||||
if (DetermineCompleted())
|
||||
if (DetermineCompleted(CampaignMode.TransitionType.None))
|
||||
{
|
||||
HandleMessage(ref allRetrievedMessage);
|
||||
}
|
||||
|
||||
@@ -1435,8 +1435,15 @@ namespace Barotrauma
|
||||
Uri baseAddress = new Uri(url);
|
||||
Uri remoteDirectory = new Uri(baseAddress, ".");
|
||||
string remoteFileName = Path.GetFileName(baseAddress.LocalPath);
|
||||
IRestClient client = new RestClient(remoteDirectory);
|
||||
var response = client.Execute(new RestRequest(remoteFileName, Method.GET));
|
||||
var client = RestFactory.CreateClient(remoteDirectory.ToString());
|
||||
var request = RestFactory.CreateRequest(remoteFileName);
|
||||
var response = client.Execute(request);
|
||||
if (response.ErrorException != null)
|
||||
{
|
||||
DebugConsole.AddWarning($"Connection error: Failed to load remote sprite from {url} " +
|
||||
$"({response.ErrorException.Message}).");
|
||||
return null;
|
||||
}
|
||||
if (response.ResponseStatus != ResponseStatus.Completed) { return null; }
|
||||
if (response.StatusCode != HttpStatusCode.OK) { return null; }
|
||||
|
||||
|
||||
@@ -26,7 +26,9 @@ namespace Barotrauma
|
||||
|
||||
public OnSelectedHandler OnDropped;
|
||||
|
||||
private readonly GUIButton button;
|
||||
private readonly GUIButton button;
|
||||
public GUIButton Button => button;
|
||||
|
||||
private readonly GUIImage icon;
|
||||
private readonly GUIListBox listBox;
|
||||
|
||||
|
||||
@@ -710,19 +710,24 @@ namespace Barotrauma
|
||||
|
||||
if (listBox == pendingList || listBox == crewList)
|
||||
{
|
||||
nameBlock.RectTransform.Resize(new Point(nameBlock.Rect.Width - nameBlock.Rect.Height, nameBlock.Rect.Height));
|
||||
nameBlock.Text = ToolBox.LimitString(characterName, nameBlock.Font, nameBlock.Rect.Width);
|
||||
nameBlock.RectTransform.Resize(new Point((int)(nameBlock.Padding.X + nameBlock.TextSize.X + nameBlock.Padding.Z), nameBlock.Rect.Height));
|
||||
Point size = new Point((int)(0.7f * nameBlock.Rect.Height));
|
||||
new GUIImage(new RectTransform(size, nameGroup.RectTransform), "EditIcon") { CanBeFocused = false };
|
||||
size = new Point(3 * mainGroup.AbsoluteSpacing + icon.Rect.Width + nameAndJobGroup.Rect.Width, mainGroup.Rect.Height);
|
||||
new GUIButton(new RectTransform(size, frame.RectTransform) { RelativeOffset = new Vector2(0.025f) }, style: null)
|
||||
//if the character is already in the crew, only check permissions - reputation doesn't matter for renaming an already-hired bot
|
||||
bool canRename = listBox == crewList ? HasPermissionToHire : CanHire(characterInfo);
|
||||
if (canRename)
|
||||
{
|
||||
Enabled = CanHire(characterInfo),
|
||||
ToolTip = TextManager.GetWithVariable("campaigncrew.givenicknametooltip", "[mouseprimary]", PlayerInput.PrimaryMouseLabel),
|
||||
UserData = characterInfo,
|
||||
OnClicked = CreateRenamingComponent
|
||||
};
|
||||
nameBlock.RectTransform.Resize(new Point(nameBlock.Rect.Width - nameBlock.Rect.Height, nameBlock.Rect.Height));
|
||||
nameBlock.Text = ToolBox.LimitString(characterName, nameBlock.Font, nameBlock.Rect.Width);
|
||||
nameBlock.RectTransform.Resize(new Point((int)(nameBlock.Padding.X + nameBlock.TextSize.X + nameBlock.Padding.Z), nameBlock.Rect.Height));
|
||||
Point iconSize = new Point((int)(0.7f * nameBlock.Rect.Height));
|
||||
new GUIImage(new RectTransform(iconSize, nameGroup.RectTransform), "EditIcon") { CanBeFocused = false };
|
||||
Point buttonSize = new Point(3 * mainGroup.AbsoluteSpacing + icon.Rect.Width + nameAndJobGroup.Rect.Width + (int)(iconSize.X * 1.5f), mainGroup.Rect.Height);
|
||||
new GUIButton(new RectTransform(buttonSize, frame.RectTransform) { RelativeOffset = new Vector2(0.025f) }, style: null)
|
||||
{
|
||||
ClampMouseRectToParent = false,
|
||||
ToolTip = TextManager.GetWithVariable("campaigncrew.givenicknametooltip", "[mouseprimary]", PlayerInput.PrimaryMouseLabel),
|
||||
UserData = characterInfo,
|
||||
OnClicked = CreateRenamingComponent
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
//recalculate everything and truncate texts if needed
|
||||
|
||||
@@ -487,7 +487,21 @@ namespace Barotrauma.Items.Components
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
public virtual bool ShouldDrawHUD(Character character)
|
||||
public bool ShouldDrawHUD(Character character)
|
||||
{
|
||||
if (Character.Controlled?.SelectedItem != null)
|
||||
{
|
||||
Controller controller = item.GetComponent<Controller>();
|
||||
if (controller != null && controller.User == Character.Controlled && controller.HideAllItemComponentHUDs)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return ShouldDrawHUDComponentSpecific(character);
|
||||
}
|
||||
|
||||
protected virtual bool ShouldDrawHUDComponentSpecific(Character character)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -552,9 +552,9 @@ namespace Barotrauma.Items.Components
|
||||
if (flippedY) { origin.Y = contained.Item.Sprite.SourceRect.Height - origin.Y; }
|
||||
|
||||
float containedSpriteDepth = ContainedSpriteDepth < 0.0f ? contained.Item.Sprite.Depth : ContainedSpriteDepth;
|
||||
if (i < containedSpriteDepths.Length)
|
||||
if (targetSlotIndex < containedSpriteDepths.Length)
|
||||
{
|
||||
containedSpriteDepth = containedSpriteDepths[i];
|
||||
containedSpriteDepth = containedSpriteDepths[targetSlotIndex];
|
||||
}
|
||||
containedSpriteDepth = itemDepth + (containedSpriteDepth - (item.Sprite?.Depth ?? item.SpriteDepth)) / 10000.0f;
|
||||
|
||||
|
||||
@@ -52,10 +52,12 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
partial void SetLightSourceTransformProjSpecific()
|
||||
{
|
||||
Vector2 offset = Vector2.Zero;
|
||||
if (LightOffset != Vector2.Zero)
|
||||
Vector2 offset = LightOffset * item.Scale;
|
||||
if (offset != Vector2.Zero)
|
||||
{
|
||||
offset = Vector2.Transform(LightOffset, Matrix.CreateRotationZ(item.FlippedY ? -item.RotationRad - MathHelper.Pi : -item.RotationRad)) * item.Scale;
|
||||
if (item.FlippedX) { offset.X *= -1; }
|
||||
if (item.FlippedY) { offset.Y *= -1; }
|
||||
offset = Vector2.Transform(offset, Matrix.CreateRotationZ(-item.RotationRad));
|
||||
}
|
||||
|
||||
if (ParentBody != null)
|
||||
@@ -101,7 +103,10 @@ namespace Barotrauma.Items.Components
|
||||
if (Light?.LightSprite == null) { return; }
|
||||
if ((item.body == null || item.body.Enabled) && lightBrightness > 0.0f && IsOn && Light.Enabled)
|
||||
{
|
||||
Vector2 offset = Vector2.Transform(LightOffset, Matrix.CreateRotationZ(item.FlippedY ? -item.RotationRad - MathHelper.Pi : -item.RotationRad)) * item.Scale;
|
||||
Vector2 offset = LightOffset * item.Scale;
|
||||
if (item.FlippedX) { offset.X *= -1; }
|
||||
if (item.FlippedY) { offset.Y *= -1; }
|
||||
offset = Vector2.Transform(offset, Matrix.CreateRotationZ(-item.RotationRad));
|
||||
|
||||
Vector2 origin = Light.LightSprite.Origin;
|
||||
if ((Light.LightSpriteEffect & SpriteEffects.FlipHorizontally) == SpriteEffects.FlipHorizontally) { origin.X = Light.LightSprite.SourceRect.Width - origin.X; }
|
||||
@@ -114,6 +119,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
color = new Color(lightColor, Light.OverrideLightSpriteAlpha.Value);
|
||||
}
|
||||
|
||||
Light.LightSprite.Draw(spriteBatch,
|
||||
new Vector2(drawPos.X, -drawPos.Y),
|
||||
color * lightBrightness,
|
||||
@@ -128,8 +134,16 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (Light?.LightSprite != null && item.Prefab.CanSpriteFlipX)
|
||||
{
|
||||
Light.LightSpriteEffect = Light.LightSpriteEffect == SpriteEffects.None ?
|
||||
SpriteEffects.FlipHorizontally : SpriteEffects.None;
|
||||
Light.LightSpriteEffect ^= SpriteEffects.FlipHorizontally;
|
||||
}
|
||||
SetLightSourceTransformProjSpecific();
|
||||
}
|
||||
|
||||
public override void FlipY(bool relativeToSub)
|
||||
{
|
||||
if (Light?.LightSprite != null && item.Prefab.CanSpriteFlipY)
|
||||
{
|
||||
Light.LightSpriteEffect ^= SpriteEffects.FlipVertically;
|
||||
}
|
||||
SetLightSourceTransformProjSpecific();
|
||||
}
|
||||
|
||||
@@ -8,6 +8,30 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
private bool isHUDsHidden;
|
||||
|
||||
public void UpdateMsg()
|
||||
{
|
||||
if (Character.Controlled == null) { return; }
|
||||
|
||||
if (!string.IsNullOrEmpty(KickOutCharacterMsg) &&
|
||||
SelectingKicksCharacterOut &&
|
||||
User != null && !User.Removed)
|
||||
{
|
||||
DisplayMsg = TextManager.ParseInputTypes(TextManager.Get(KickOutCharacterMsg));
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(PutOtherCharacterMsg) &&
|
||||
AllowPuttingInOtherCharacters &&
|
||||
CanPutSelectedCharacter(Character.Controlled.SelectedCharacter))
|
||||
{
|
||||
DisplayMsg = TextManager.ParseInputTypes(TextManager.Get(PutOtherCharacterMsg));
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayMsg = TextManager.ParseInputTypes(TextManager.Get(Msg));
|
||||
}
|
||||
|
||||
CharacterHUD.RecreateHudTextsIfControlling(Character.Controlled);
|
||||
}
|
||||
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
base.DrawHUD(spriteBatch, character);
|
||||
@@ -69,21 +93,33 @@ namespace Barotrauma.Items.Components
|
||||
ushort userID = msg.ReadUInt16();
|
||||
if (userID == 0)
|
||||
{
|
||||
if (user != null)
|
||||
if (User != null)
|
||||
{
|
||||
IsActive = false;
|
||||
CancelUsing(user);
|
||||
user = null;
|
||||
CancelUsing(User);
|
||||
User = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Character newUser = Entity.FindEntityByID(userID) as Character;
|
||||
if (newUser != user)
|
||||
if (newUser != User)
|
||||
{
|
||||
CancelUsing(user);
|
||||
CancelUsing(User);
|
||||
}
|
||||
user = newUser;
|
||||
User = newUser;
|
||||
|
||||
// If the server assigned a user to this controller but the character is not selecting the item
|
||||
// on the client-side, force the selection to prevent desync. This is required for force attaching,
|
||||
// since the character placed into the controller may be unconscious, and in that state
|
||||
// the server no longer syncs the current SelectedItem to clients.
|
||||
if (ForceUserToStayAttached &&
|
||||
user != null &&
|
||||
!user.IsAnySelectedItem(Item))
|
||||
{
|
||||
user.SelectedItem = Item;
|
||||
}
|
||||
|
||||
IsActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,18 +434,13 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
foreach (FabricationRecipe fi in fabricationRecipes.Values)
|
||||
{
|
||||
RichString recipeTooltip =
|
||||
fi.RequiresRecipe ?
|
||||
RichString.Rich(fi.TargetItem.Description + "\n\n" + $"‖color:{XMLExtensions.ToStringHex(GUIStyle.Red)}‖{TextManager.Get("fabricatorrequiresrecipe")}‖color:end‖") :
|
||||
RichString.Rich(fi.TargetItem.Description);
|
||||
|
||||
var frame = new GUIFrame(new RectTransform(new Point(itemList.Content.Rect.Width, (int)(40 * GUI.yScale)), itemList.Content.RectTransform), style: null)
|
||||
{
|
||||
UserData = fi,
|
||||
HoverColor = Color.Gold * 0.2f,
|
||||
SelectedColor = Color.Gold * 0.5f,
|
||||
ToolTip = recipeTooltip
|
||||
};
|
||||
SetRecipeTooltip(frame, fi);
|
||||
|
||||
var container = new GUILayoutGroup(new RectTransform(Vector2.One, frame.RectTransform),
|
||||
childAnchor: Anchor.CenterLeft, isHorizontal: true) { RelativeSpacing = 0.02f };
|
||||
@@ -457,7 +452,7 @@ namespace Barotrauma.Items.Components
|
||||
itemIcon, scaleToFit: true)
|
||||
{
|
||||
Color = itemIcon == fi.TargetItem.Sprite ? fi.TargetItem.SpriteColor : fi.TargetItem.InventoryIconColor,
|
||||
ToolTip = recipeTooltip
|
||||
CanBeFocused = false
|
||||
};
|
||||
}
|
||||
|
||||
@@ -466,7 +461,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
Padding = Vector4.Zero,
|
||||
AutoScaleVertical = true,
|
||||
ToolTip = recipeTooltip
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.85f, 1f), frame.RectTransform, Anchor.BottomRight),
|
||||
@@ -478,6 +473,20 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
private void SetRecipeTooltip(GUIComponent component, FabricationRecipe recipe)
|
||||
{
|
||||
if (!recipe.RequiresRecipe)
|
||||
{
|
||||
component.ToolTip = RichString.Rich(recipe.TargetItem.Description);
|
||||
}
|
||||
else
|
||||
{
|
||||
component.ToolTip = AnyOneHasRecipeForItem(Character.Controlled, recipe.TargetItem) ?
|
||||
RichString.Rich(recipe.TargetItem.Description + "\n\n" + $"‖color:{XMLExtensions.ToStringHex(GUIStyle.Green)}‖{TextManager.Get("unlockedrecipe.true")}‖color:end‖") :
|
||||
RichString.Rich(recipe.TargetItem.Description + "\n\n" + $"‖color:{XMLExtensions.ToStringHex(GUIStyle.Red)}‖{TextManager.Get("fabricatorrequiresrecipe")}‖color:end‖");
|
||||
}
|
||||
}
|
||||
|
||||
private void InitInventoryUIs()
|
||||
{
|
||||
if (inputInventoryHolder != null)
|
||||
@@ -927,16 +936,24 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
if (recipe.RequiresRecipe && recipe.HideIfNoRecipe)
|
||||
if (recipe.RequiresRecipe)
|
||||
{
|
||||
if (Character.Controlled != null)
|
||||
if (recipe.HideIfNoRecipe)
|
||||
{
|
||||
if (!AnyOneHasRecipeForItem(Character.Controlled, recipe.TargetItem))
|
||||
bool anyOneHasRecipe = AnyOneHasRecipeForItem(Character.Controlled, recipe.TargetItem);
|
||||
if (Character.Controlled != null)
|
||||
{
|
||||
child.Visible = false;
|
||||
continue;
|
||||
if (!anyOneHasRecipe)
|
||||
{
|
||||
child.Visible = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetRecipeTooltip(child, recipe);
|
||||
}
|
||||
}
|
||||
|
||||
child.Visible =
|
||||
@@ -1147,7 +1164,16 @@ namespace Barotrauma.Items.Components
|
||||
var lines = description.WrappedText.Split('\n');
|
||||
if (lines.Count <= 1) { break; }
|
||||
string newString = string.Join('\n', lines.Take(lines.Count - 1));
|
||||
description.Text = newString.Substring(0, newString.Length - 4) + "...";
|
||||
|
||||
if (newString.Length > 4)
|
||||
{
|
||||
description.Text = newString.Substring(0, newString.Length - 4) + "...";
|
||||
}
|
||||
else
|
||||
{
|
||||
description.Text = newString + "...";
|
||||
}
|
||||
|
||||
description.CalculateHeightFromText();
|
||||
description.ToolTip = richDescription;
|
||||
}
|
||||
|
||||
@@ -443,6 +443,7 @@ namespace Barotrauma.Items.Components
|
||||
var wire = targetItem.GetComponent<Wire>();
|
||||
if (wire != null && wire.Connections.Any(c => c != null)) { return false; }
|
||||
|
||||
if (targetItem.Container is { NonInteractable: true }) { return false; }
|
||||
if (targetItem.Container?.GetComponent<ItemContainer>() is { DrawInventory: false } or { AllowAccess: false }) { return false; }
|
||||
|
||||
if (targetItem.HasTag(Tags.TraitorMissionItem)) { return false; }
|
||||
|
||||
@@ -575,6 +575,22 @@ namespace Barotrauma.Items.Components
|
||||
pos /= c.Resources.Count;
|
||||
MineralClusters.Add((center: pos, resources: c.Resources));
|
||||
}
|
||||
|
||||
if (GameMain.GameSession != null)
|
||||
{
|
||||
foreach (var mission in GameMain.GameSession.Missions)
|
||||
{
|
||||
if (mission is MineralMission mineralMission)
|
||||
{
|
||||
foreach (var minerals in mineralMission.SpawnedResources)
|
||||
{
|
||||
MineralClusters.Add((
|
||||
center: new Vector2(minerals.Average(m => m.WorldPosition.X), minerals.Average(m => m.WorldPosition.Y)),
|
||||
resources: minerals));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -823,18 +839,20 @@ namespace Barotrauma.Items.Components
|
||||
if (t.Entity is Character c && !c.IsUnconscious && c.Params.HideInSonar) { continue; }
|
||||
if (t.SoundRange <= 0.0f || float.IsNaN(t.SoundRange) || float.IsInfinity(t.SoundRange)) { continue; }
|
||||
|
||||
float sonarSoundRange = t.SoundRange * t.SoundRangeOnSonarMultiplier;
|
||||
|
||||
float distSqr = Vector2.DistanceSquared(t.WorldPosition, transducerCenter);
|
||||
if (distSqr > t.SoundRange * t.SoundRange * 2) { continue; }
|
||||
if (distSqr > sonarSoundRange * sonarSoundRange * 2) { continue; }
|
||||
|
||||
float dist = (float)Math.Sqrt(distSqr);
|
||||
if (dist > prevPassivePingRadius * Range && dist <= passivePingRadius * Range && Rand.Int(sonarBlips.Count) < 500)
|
||||
{
|
||||
Ping(t.WorldPosition, transducerCenter,
|
||||
t.SoundRange * DisplayScale, 0, DisplayScale, range,
|
||||
sonarSoundRange * DisplayScale, 0, DisplayScale, range,
|
||||
passive: true, pingStrength: 0.5f, needsToBeInSector: t);
|
||||
if (t.IsWithinSector(transducerCenter))
|
||||
{
|
||||
sonarBlips.Add(new SonarBlip(t.WorldPosition, fadeTimer: 1.0f, scale: MathHelper.Clamp(t.SoundRange / 2000, 1.0f, 5.0f)));
|
||||
sonarBlips.Add(new SonarBlip(t.WorldPosition, fadeTimer: 1.0f, scale: MathHelper.Clamp(sonarSoundRange / 2000, 1.0f, 5.0f)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -977,7 +995,9 @@ namespace Barotrauma.Items.Components
|
||||
if (aiTarget.InDetectable) { continue; }
|
||||
if (aiTarget.SonarLabel.IsNullOrEmpty() || aiTarget.SoundRange <= 0.0f) { continue; }
|
||||
|
||||
if (Vector2.DistanceSquared(aiTarget.WorldPosition, transducerCenter) < aiTarget.SoundRange * aiTarget.SoundRange)
|
||||
float sonarSoundRange = aiTarget.SoundRange * aiTarget.SoundRangeOnSonarMultiplier;
|
||||
|
||||
if (Vector2.DistanceSquared(aiTarget.WorldPosition, transducerCenter) < sonarSoundRange * sonarSoundRange)
|
||||
{
|
||||
DrawMarker(spriteBatch,
|
||||
aiTarget.SonarLabel.Value,
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace Barotrauma.Items.Components
|
||||
get { return Vector2.Zero; }
|
||||
}
|
||||
|
||||
public override bool ShouldDrawHUD(Character character)
|
||||
protected override bool ShouldDrawHUDComponentSpecific(Character character)
|
||||
{
|
||||
if (item.IsHidden) { return false; }
|
||||
if (!HasRequiredItems(character, false) || character.SelectedItem != item) { return false; }
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public override bool ShouldDrawHUD(Character character)
|
||||
protected override bool ShouldDrawHUDComponentSpecific(Character character)
|
||||
=> character == Character.Controlled && (character.SelectedItem == item || character.SelectedSecondaryItem == item);
|
||||
|
||||
public override void UpdateHUDComponentSpecific(Character character, float deltaTime, Camera cam)
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace Barotrauma.Items.Components
|
||||
MoveConnectedWires(amount);
|
||||
}
|
||||
|
||||
public override bool ShouldDrawHUD(Character character)
|
||||
protected override bool ShouldDrawHUDComponentSpecific(Character character)
|
||||
{
|
||||
return character == Character.Controlled && character == user && (character.SelectedItem == item || character.SelectedSecondaryItem == item);
|
||||
}
|
||||
|
||||
@@ -287,20 +287,24 @@ namespace Barotrauma.Items.Components
|
||||
texts.Add(target.CustomInteractHUDText);
|
||||
textColors.Add(GUIStyle.Green);
|
||||
}
|
||||
if (!target.IsIncapacitated && target.IsPet)
|
||||
if (equipper?.FocusedCharacter == target)
|
||||
{
|
||||
texts.Add(CharacterHUD.GetCachedHudText("PlayHint", InputType.Use));
|
||||
textColors.Add(GUIStyle.Green);
|
||||
}
|
||||
if (equipper?.FocusedCharacter == target && target.CanBeHealedBy(equipper, checkFriendlyTeam: false))
|
||||
{
|
||||
texts.Add(CharacterHUD.GetCachedHudText("HealHint", InputType.Health));
|
||||
textColors.Add(GUIStyle.Green);
|
||||
}
|
||||
if (target.CanBeDraggedBy(Character.Controlled))
|
||||
{
|
||||
texts.Add(CharacterHUD.GetCachedHudText("GrabHint", InputType.Grab));
|
||||
textColors.Add(GUIStyle.Green);
|
||||
if (!target.IsIncapacitated && target.IsPet &&
|
||||
target.AIController is EnemyAIController enemyAI && enemyAI.PetBehavior.CanPlayWith(Character.Controlled))
|
||||
{
|
||||
texts.Add(CharacterHUD.GetCachedHudText("PlayHint", InputType.Use));
|
||||
textColors.Add(GUIStyle.Green);
|
||||
}
|
||||
if (target.CanBeHealedBy(equipper, checkFriendlyTeam: false))
|
||||
{
|
||||
texts.Add(CharacterHUD.GetCachedHudText("HealHint", InputType.Health));
|
||||
textColors.Add(GUIStyle.Green);
|
||||
}
|
||||
if (target.CanBeDraggedBy(Character.Controlled))
|
||||
{
|
||||
texts.Add(CharacterHUD.GetCachedHudText("GrabHint", InputType.Grab));
|
||||
textColors.Add(GUIStyle.Green);
|
||||
}
|
||||
}
|
||||
|
||||
if (target.IsUnconscious)
|
||||
|
||||
@@ -1597,7 +1597,8 @@ namespace Barotrauma
|
||||
{
|
||||
if (DraggingSlot == null || (!DraggingSlot.MouseOn()))
|
||||
{
|
||||
Sprite sprite = DraggingItems.First().Prefab.InventoryIcon ?? DraggingItems.First().Sprite;
|
||||
Item firstDraggingItem = DraggingItems.First();
|
||||
Sprite sprite = firstDraggingItem.OverrideInventorySprite ?? firstDraggingItem.Prefab.InventoryIcon ?? firstDraggingItem.Sprite;
|
||||
|
||||
int iconSize = (int)(64 * GUI.Scale);
|
||||
float scale = Math.Min(Math.Min(iconSize / sprite.size.X, iconSize / sprite.size.Y), 1.5f);
|
||||
@@ -1854,7 +1855,7 @@ namespace Barotrauma
|
||||
|
||||
if (item != null && drawItem)
|
||||
{
|
||||
Sprite sprite = item.Prefab.InventoryIcon ?? item.Sprite;
|
||||
Sprite sprite = item.OverrideInventorySprite ?? item.Prefab.InventoryIcon ?? item.Sprite;
|
||||
float scale = Math.Min(Math.Min((rect.Width - 10) / sprite.size.X, (rect.Height - 10) / sprite.size.Y), 2.0f);
|
||||
Vector2 itemPos = rect.Center.ToVector2();
|
||||
if (itemPos.Y > GameMain.GraphicsHeight)
|
||||
|
||||
@@ -419,7 +419,7 @@ namespace Barotrauma
|
||||
|
||||
if (fadeInBrokenSprite != null)
|
||||
{
|
||||
float d = Math.Min(depth + (fadeInBrokenSprite.Sprite.Depth - activeSprite.Depth - 0.000001f), 0.999f);
|
||||
float d = MathHelper.Clamp(depth + (fadeInBrokenSprite.Sprite.Depth - activeSprite.Depth - 0.000001f), 0.0f, 0.999f);
|
||||
fadeInBrokenSprite.Sprite.DrawTiled(spriteBatch, new Vector2(DrawPosition.X - rect.Width / 2, -(DrawPosition.Y + rect.Height / 2)) + fadeInBrokenSprite.Offset.ToVector2() * Scale, size, color: color * fadeInBrokenSpriteAlpha,
|
||||
textureScale: Vector2.One * Scale,
|
||||
depth: d);
|
||||
@@ -435,7 +435,7 @@ namespace Barotrauma
|
||||
activeSprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y) + drawOffset, color, origin, RotationRad, Scale, activeSprite.effects, depth);
|
||||
if (fadeInBrokenSprite != null)
|
||||
{
|
||||
float d = Math.Min(depth + (fadeInBrokenSprite.Sprite.Depth - activeSprite.Depth - 0.000001f), 0.999f);
|
||||
float d = MathHelper.Clamp(depth + (fadeInBrokenSprite.Sprite.Depth - activeSprite.Depth - 0.000001f), 0.0f, 0.999f);
|
||||
fadeInBrokenSprite.Sprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y) + fadeInBrokenSprite.Offset.ToVector2() * Scale, color * fadeInBrokenSpriteAlpha, origin, RotationRad, Scale, activeSprite.effects, d);
|
||||
}
|
||||
}
|
||||
@@ -885,7 +885,12 @@ namespace Barotrauma
|
||||
Spacing = (int)(25 * GUI.Scale)
|
||||
};
|
||||
|
||||
var itemEditor = new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true, titleFont: GUIStyle.LargeFont) { UserData = this };
|
||||
var itemEditor = new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true,
|
||||
titleFont: GUIStyle.LargeFont,
|
||||
dimOutDefaultValues: false)
|
||||
{
|
||||
UserData = this
|
||||
};
|
||||
activeEditors.Add(itemEditor);
|
||||
itemEditor.Children.First().Color = Color.Black * 0.7f;
|
||||
if (!inGame)
|
||||
@@ -1045,7 +1050,12 @@ namespace Barotrauma
|
||||
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), listBox.Content.RectTransform), style: "HorizontalLine");
|
||||
|
||||
var componentEditor = new SerializableEntityEditor(listBox.Content.RectTransform, ic, inGame, showName: !inGame, titleFont: GUIStyle.SubHeadingFont) { UserData = ic };
|
||||
var componentEditor = new SerializableEntityEditor(listBox.Content.RectTransform, ic, inGame, showName: !inGame,
|
||||
titleFont: GUIStyle.SubHeadingFont,
|
||||
dimOutDefaultValues: false)
|
||||
{
|
||||
UserData = ic
|
||||
};
|
||||
componentEditor.Children.First().Color = Color.Black * 0.7f;
|
||||
activeEditors.Add(componentEditor);
|
||||
|
||||
@@ -1064,7 +1074,12 @@ namespace Barotrauma
|
||||
requiredItems.Add(relatedItem);
|
||||
}
|
||||
}
|
||||
requiredItems.AddRange(ic.DisabledRequiredItems);
|
||||
//if we have some actual requirements, no need to keep the empty requirement
|
||||
//as a "placeholder" for the user to add requirements in the sub editor
|
||||
if (ic.RequiredItems.None())
|
||||
{
|
||||
requiredItems.AddRange(ic.DisabledRequiredItems);
|
||||
}
|
||||
|
||||
foreach (RelatedItem relatedItem in requiredItems)
|
||||
{
|
||||
@@ -1626,12 +1641,16 @@ namespace Barotrauma
|
||||
activeComponents.Clear();
|
||||
activeComponents.AddRange(components);
|
||||
|
||||
foreach (MapEntity entity in linkedTo)
|
||||
Controller controller = GetComponent<Controller>();
|
||||
if (controller == null || controller.User != Character.Controlled || !controller.HideAllItemComponentHUDs)
|
||||
{
|
||||
if (Prefab.IsLinkAllowed(entity.Prefab) && entity is Item i)
|
||||
foreach (MapEntity entity in linkedTo)
|
||||
{
|
||||
if (!i.DisplaySideBySideWhenLinked) { continue; }
|
||||
activeComponents.AddRange(i.components);
|
||||
if (Prefab.IsLinkAllowed(entity.Prefab) && entity is Item i)
|
||||
{
|
||||
if (!i.DisplaySideBySideWhenLinked) { continue; }
|
||||
activeComponents.AddRange(i.components);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1701,7 +1720,9 @@ namespace Barotrauma
|
||||
foreach (Character otherCharacter in Character.CharacterList)
|
||||
{
|
||||
if (otherCharacter != character &&
|
||||
otherCharacter.SelectedItem == this)
|
||||
otherCharacter.SelectedItem == this &&
|
||||
// Prevent the in use message from being shown if a character is, for example, inside the deconstructor
|
||||
!otherCharacter.IsAttachedToController())
|
||||
{
|
||||
ItemInUseWarning.Visible = true;
|
||||
if (mergedHUDRect.Width > GameMain.GraphicsWidth / 2) { mergedHUDRect.Inflate(-GameMain.GraphicsWidth / 4, 0); }
|
||||
@@ -1751,6 +1772,11 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearActiveHUDs()
|
||||
{
|
||||
activeHUDs.Clear();
|
||||
}
|
||||
|
||||
readonly List<ColoredText> texts = new();
|
||||
public List<ColoredText> GetHUDTexts(Character character, bool recreateHudTexts = true)
|
||||
{
|
||||
|
||||
@@ -166,6 +166,14 @@ namespace Barotrauma
|
||||
subElement.GetAttributeBool("fadein", false),
|
||||
subElement.GetAttributePoint("offset", Point.Zero));
|
||||
|
||||
if (brokenSprite.FadeIn && brokenSprite.MaxConditionPercentage <= 0.0f)
|
||||
{
|
||||
DebugConsole.AddWarning(
|
||||
$"Potential error in item {Identifier}: a broken sprite that's set to fade in despite the max condition being 0."+
|
||||
" The sprite cannot fade in if it's set to only appear when the item is fully broken.",
|
||||
ContentPackage);
|
||||
}
|
||||
|
||||
int spriteIndex = 0;
|
||||
for (int i = 0; i < brokenSprites.Count && brokenSprites[i].MaxConditionPercentage < brokenSprite.MaxConditionPercentage; i++)
|
||||
{
|
||||
|
||||
@@ -16,15 +16,17 @@ namespace Barotrauma
|
||||
{
|
||||
public readonly UInt32 DecalId;
|
||||
public readonly int SpriteIndex;
|
||||
public Vector2 NormalizedPos;
|
||||
public readonly Vector2 NormalizedPos;
|
||||
public readonly float Scale;
|
||||
public readonly float DecalAlpha;
|
||||
|
||||
public RemoteDecal(UInt32 decalId, int spriteIndex, Vector2 normalizedPos, float scale)
|
||||
public RemoteDecal(UInt32 decalId, int spriteIndex, Vector2 normalizedPos, float scale, float decalAlpha)
|
||||
{
|
||||
DecalId = decalId;
|
||||
SpriteIndex = spriteIndex;
|
||||
NormalizedPos = normalizedPos;
|
||||
Scale = scale;
|
||||
DecalAlpha = decalAlpha;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -696,7 +698,7 @@ namespace Barotrauma
|
||||
var decal = decalEventData.Decal;
|
||||
int decalIndex = decals.IndexOf(decal);
|
||||
msg.WriteByte((byte)(decalIndex < 0 ? 255 : decalIndex));
|
||||
msg.WriteRangedSingle(decal.BaseAlpha, 0.0f, 1.0f, 8);
|
||||
msg.WriteRangedSingle(decal.BaseAlpha, 0f, 1f, 8);
|
||||
break;
|
||||
default:
|
||||
throw new Exception($"Malformed hull event: did not expect {eventData.GetType().Name}");
|
||||
@@ -752,7 +754,9 @@ namespace Barotrauma
|
||||
float normalizedXPos = msg.ReadRangedSingle(0.0f, 1.0f, 8);
|
||||
float normalizedYPos = msg.ReadRangedSingle(0.0f, 1.0f, 8);
|
||||
float decalScale = msg.ReadRangedSingle(0.0f, 2.0f, 12);
|
||||
remoteDecals.Add(new RemoteDecal(decalId, spriteIndex, new Vector2(normalizedXPos, normalizedYPos), decalScale));
|
||||
float decalAlpha = msg.ReadRangedSingle(0f, 1f, 8);
|
||||
|
||||
remoteDecals.Add(new RemoteDecal(decalId, spriteIndex, new Vector2(normalizedXPos, normalizedYPos), decalScale, decalAlpha));
|
||||
}
|
||||
break;
|
||||
case EventType.BallastFlora:
|
||||
@@ -804,7 +808,8 @@ namespace Barotrauma
|
||||
decalPosX += Submarine.Position.X;
|
||||
decalPosY += Submarine.Position.Y;
|
||||
}
|
||||
AddDecal(remoteDecal.DecalId, new Vector2(decalPosX, decalPosY), remoteDecal.Scale, isNetworkEvent: true, spriteIndex: remoteDecal.SpriteIndex);
|
||||
Decal decal = AddDecal(remoteDecal.DecalId, new Vector2(decalPosX, decalPosY), remoteDecal.Scale, isNetworkEvent: true, spriteIndex: remoteDecal.SpriteIndex);
|
||||
decal.BaseAlpha = remoteDecal.DecalAlpha;
|
||||
}
|
||||
remoteDecals.Clear();
|
||||
}
|
||||
|
||||
@@ -296,13 +296,9 @@ namespace Barotrauma.Lights
|
||||
|
||||
light.Priority = lightPriority(range, light);
|
||||
|
||||
int i = 0;
|
||||
while (i < activeLights.Count && light.Priority < activeLights[i].Priority)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
activeLights.Insert(i, light);
|
||||
activeLights.Add(light);
|
||||
}
|
||||
activeLights.Sort(static (a, b) => b.Priority.CompareTo(a.Priority));
|
||||
ActiveLightCount = activeLights.Count;
|
||||
|
||||
float lightPriority(float range, LightSource light)
|
||||
@@ -332,7 +328,7 @@ namespace Barotrauma.Lights
|
||||
activeLights.Remove(activeShadowCastingLights[i]);
|
||||
}
|
||||
}
|
||||
activeLights.Sort((l1, l2) => l1.LastRecalculationTime.CompareTo(l2.LastRecalculationTime));
|
||||
activeLights.Sort(static (l1, l2) => l1.LastRecalculationTime.CompareTo(l2.LastRecalculationTime));
|
||||
|
||||
//draw light sprites attached to characters
|
||||
//render into a separate rendertarget using alpha blending (instead of on top of everything else with alpha blending)
|
||||
|
||||
@@ -50,8 +50,14 @@ namespace Barotrauma.Lights
|
||||
[Serialize("0, 0", IsPropertySaveable.Yes), Editable(ValueStep = 1, DecimalCount = 1, MinValueFloat = -1000f, MaxValueFloat = 1000f)]
|
||||
public Vector2 Offset { get; set; }
|
||||
|
||||
public float RotationRad { get; private set; }
|
||||
|
||||
[Serialize(0f, IsPropertySaveable.Yes), Editable(MinValueFloat = -360, MaxValueFloat = 360, ValueStep = 1, DecimalCount = 0)]
|
||||
public float Rotation { get; set; }
|
||||
public float Rotation
|
||||
{
|
||||
get => MathHelper.ToDegrees(RotationRad);
|
||||
set => RotationRad = MathHelper.ToRadians(value);
|
||||
}
|
||||
|
||||
[Serialize(false, IsPropertySaveable.Yes, "Directional lights only shine in \"one direction\", meaning no shadows are cast behind them."+
|
||||
" Note that this does not affect how the light texture is drawn: if you want something like a conical spotlight, you should use an appropriate texture for that.")]
|
||||
@@ -314,6 +320,10 @@ namespace Barotrauma.Lights
|
||||
|
||||
private float prevCalculatedRotation;
|
||||
private float rotation;
|
||||
|
||||
/// <summary>
|
||||
/// Current rotation in radians. Note that LightSourceParams.RotationRad also affects the final rotation of the light.
|
||||
/// </summary>
|
||||
public float Rotation
|
||||
{
|
||||
get { return rotation; }
|
||||
@@ -322,7 +332,7 @@ namespace Barotrauma.Lights
|
||||
if (Math.Abs(value - rotation) < 0.001f) { return; }
|
||||
rotation = value;
|
||||
|
||||
dir = new Vector2(MathF.Cos(rotation), -MathF.Sin(rotation));
|
||||
RefreshDirection();
|
||||
|
||||
if (Math.Abs(rotation - prevCalculatedRotation) < RotationRecalculationThreshold && vertices != null)
|
||||
{
|
||||
@@ -486,6 +496,9 @@ namespace Barotrauma.Lights
|
||||
break;
|
||||
}
|
||||
}
|
||||
//make sure the rotation defined in the parameters is taken into account
|
||||
RefreshDirection();
|
||||
NeedsRecalculation = true;
|
||||
}
|
||||
|
||||
public LightSource(LightSourceParams lightSourceParams)
|
||||
@@ -497,6 +510,9 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
DeformableLightSprite = new DeformableSprite(lightSourceParams.DeformableLightSpriteElement, invert: true);
|
||||
}
|
||||
//make sure the rotation defined in the parameters is taken into account
|
||||
RefreshDirection();
|
||||
NeedsRecalculation = true;
|
||||
}
|
||||
|
||||
public LightSource(Vector2 position, float range, Color color, Submarine submarine, bool addLight=true)
|
||||
@@ -511,6 +527,14 @@ namespace Barotrauma.Lights
|
||||
if (addLight) { GameMain.LightManager.AddLight(this); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refresh the direction vector of the light (which is used for calculating shadows) based on the rotation and <see cref="LightSourceParams.RotationRad"/>
|
||||
/// </summary>
|
||||
private void RefreshDirection()
|
||||
{
|
||||
dir = new Vector2(MathF.Cos(rotation - LightSourceParams.RotationRad), -MathF.Sin(rotation - LightSourceParams.RotationRad));
|
||||
}
|
||||
|
||||
public void Update(float time)
|
||||
{
|
||||
float brightness = 1.0f;
|
||||
@@ -773,9 +797,6 @@ namespace Barotrauma.Lights
|
||||
float boundsExtended = TextureRange;
|
||||
if (OverrideLightTexture != null)
|
||||
{
|
||||
float cosAngle = (float)Math.Cos(rotation);
|
||||
float sinAngle = -(float)Math.Sin(rotation);
|
||||
|
||||
var overrideTextureDims = new Vector2(OverrideLightTexture.SourceRect.Width, OverrideLightTexture.SourceRect.Height);
|
||||
|
||||
Vector2 origin = OverrideLightTextureOrigin;
|
||||
@@ -790,8 +811,11 @@ namespace Barotrauma.Lights
|
||||
|
||||
origin *= TextureRange;
|
||||
|
||||
drawOffset.X = -origin.X * cosAngle - origin.Y * sinAngle;
|
||||
drawOffset.Y = origin.X * sinAngle + origin.Y * cosAngle;
|
||||
//rotate the origin based on the direction
|
||||
float cos = dir.X;
|
||||
float sin = dir.Y;
|
||||
drawOffset.X = -origin.X * cos - origin.Y * sin;
|
||||
drawOffset.Y = origin.X * sin + origin.Y * cos;
|
||||
}
|
||||
|
||||
//add a square-shaped boundary to make sure we've got something to construct the triangles from
|
||||
@@ -1536,7 +1560,6 @@ namespace Barotrauma.Lights
|
||||
Vector2 offset = ParentSub == null ? Vector2.Zero : ParentSub.DrawPosition;
|
||||
lightEffect.World =
|
||||
Matrix.CreateTranslation(-new Vector3(position, 0.0f)) *
|
||||
Matrix.CreateRotationZ(MathHelper.ToRadians(LightSourceParams.Rotation)) *
|
||||
Matrix.CreateTranslation(new Vector3(position + offset + translateVertices, 0.0f)) *
|
||||
transform;
|
||||
|
||||
|
||||
@@ -193,7 +193,12 @@ namespace Barotrauma
|
||||
{
|
||||
CanTakeKeyBoardFocus = false
|
||||
};
|
||||
var editor = new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true, titleFont: GUIStyle.LargeFont) { UserData = this };
|
||||
var editor = new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true,
|
||||
titleFont: GUIStyle.LargeFont,
|
||||
dimOutDefaultValues: false)
|
||||
{
|
||||
UserData = this
|
||||
};
|
||||
|
||||
if (editor.Fields.TryGetValue(nameof(Scale).ToIdentifier(), out GUIComponent[] scaleFields) &&
|
||||
scaleFields.FirstOrDefault() is GUINumberInput scaleInput)
|
||||
|
||||
+7
@@ -30,6 +30,13 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
DualStack = GameSettings.CurrentConfig.UseDualModeSockets
|
||||
};
|
||||
if (NetConfig.UseLenientHandshake)
|
||||
{
|
||||
// More lenient timeouts for local testing, so the server would start even without perfect conditions
|
||||
netPeerConfiguration.ConnectionTimeout = 60.0f;
|
||||
netPeerConfiguration.ResendHandshakeInterval = 5.0f;
|
||||
netPeerConfiguration.MaximumHandshakeAttempts = 20;
|
||||
}
|
||||
if (endpoint.NetEndpoint.Address.AddressFamily == AddressFamily.InterNetworkV6)
|
||||
{
|
||||
netPeerConfiguration.LocalAddress = System.Net.IPAddress.IPv6Any;
|
||||
|
||||
@@ -352,7 +352,7 @@ namespace Barotrauma
|
||||
{
|
||||
Level.Loaded.DrawBack(graphics, spriteBatch, cam);
|
||||
}
|
||||
else if (GameMain.GameSession.GameMode is TestGameMode testMode)
|
||||
else if (GameMain.GameSession?.GameMode is TestGameMode testMode)
|
||||
{
|
||||
graphics.Clear(testMode.BackgroundParams.BackgroundColor);
|
||||
|
||||
|
||||
@@ -49,6 +49,9 @@ namespace Barotrauma
|
||||
private GUITextBox serverNameBox, passwordBox, maxPlayersBox;
|
||||
private GUITickBox isPublicBox, wrongPasswordBanBox, karmaBox;
|
||||
private GUIDropDown languageDropdown, serverExecutableDropdown;
|
||||
#if DEBUG
|
||||
private GUITickBox lenientHandshakeBox;
|
||||
#endif
|
||||
private readonly GUIButton joinServerButton, hostServerButton;
|
||||
|
||||
private readonly GUIFrame modsButtonContainer;
|
||||
@@ -1081,7 +1084,7 @@ namespace Barotrauma
|
||||
"-public", isPublicBox.Selected.ToString(),
|
||||
"-playstyle", ((PlayStyle)playstyleBanner.UserData).ToString(),
|
||||
"-banafterwrongpassword", wrongPasswordBanBox.Selected.ToString(),
|
||||
"-karmaenabled", (!karmaBox.Selected).ToString(),
|
||||
"-karmaenabled", (karmaBox.Selected).ToString(),
|
||||
"-maxplayers", maxPlayersBox.Text,
|
||||
"-language", languageDropdown.SelectedData.ToString()
|
||||
};
|
||||
@@ -1120,6 +1123,13 @@ namespace Barotrauma
|
||||
int ownerKey = Math.Max(CryptoRandom.Instance.Next(), 1);
|
||||
arguments.Add("-ownerkey");
|
||||
arguments.Add(ownerKey.ToString());
|
||||
#if DEBUG
|
||||
if (lenientHandshakeBox.Selected)
|
||||
{
|
||||
arguments.Add("-lenienthandshake");
|
||||
NetConfig.UseLenientHandshake = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
var processInfo = new ProcessStartInfo
|
||||
{
|
||||
@@ -1374,7 +1384,7 @@ namespace Barotrauma
|
||||
}
|
||||
int maxPlayers = Math.Clamp(maxPlayersElement, min: 1, max: NetConfig.MaxPlayers);
|
||||
|
||||
var karmaEnabled = serverSettings.GetAttributeBool("karmaenabled", true);
|
||||
var karmaEnabled = serverSettings.GetAttributeBool("karmaenabled", false);
|
||||
var selectedPlayStyle = serverSettings.GetAttributeEnum("playstyle", PlayStyle.Casual);
|
||||
|
||||
Vector2 textLabelSize = new Vector2(1.0f, 0.05f);
|
||||
@@ -1585,10 +1595,18 @@ namespace Barotrauma
|
||||
|
||||
karmaBox = new GUITickBox(new RectTransform(new Vector2(0.5f, 1.0f), tickboxAreaLower.RectTransform), TextManager.Get("HostServerKarmaSetting"))
|
||||
{
|
||||
Selected = !karmaEnabled,
|
||||
Selected = karmaEnabled,
|
||||
ToolTip = TextManager.Get("hostserverkarmasettingtooltip")
|
||||
};
|
||||
|
||||
#if DEBUG
|
||||
lenientHandshakeBox = new GUITickBox(new RectTransform(new Vector2(0.5f, 1.0f), tickboxAreaLower.RectTransform), "DEBUG: Lenient server startup timeouts")
|
||||
{
|
||||
Selected = true,
|
||||
ToolTip = "Start with more lenient Lidgren handshake timeouts. The server is more likely to start even when running multiple instances on the same machine under heavy load."
|
||||
};
|
||||
#endif
|
||||
|
||||
tickboxAreaLower.RectTransform.IsFixedSize = true;
|
||||
|
||||
//spacing
|
||||
@@ -1677,8 +1695,8 @@ namespace Barotrauma
|
||||
if (string.IsNullOrEmpty(remoteContentUrl)) { return; }
|
||||
try
|
||||
{
|
||||
var client = new RestClient(remoteContentUrl);
|
||||
var request = new RestRequest("MenuContent.xml", Method.GET);
|
||||
var client = RestFactory.CreateClient(remoteContentUrl);
|
||||
var request = RestFactory.CreateRequest("MenuContent.xml");
|
||||
TaskPool.Add("RequestMainMenuRemoteContent", client.ExecuteAsync(request),
|
||||
RemoteContentReceived);
|
||||
}
|
||||
@@ -1699,12 +1717,17 @@ namespace Barotrauma
|
||||
try
|
||||
{
|
||||
if (!t.TryGetResult(out IRestResponse remoteContentResponse)) { throw new Exception("Task did not return a valid result"); }
|
||||
if (remoteContentResponse.ErrorException != null)
|
||||
{
|
||||
DebugConsole.AddWarning($"Connection error: Failed to fetch remote main menu content " +
|
||||
$"({remoteContentResponse.ErrorException.Message}).");
|
||||
return;
|
||||
}
|
||||
if (remoteContentResponse.StatusCode != HttpStatusCode.OK)
|
||||
{
|
||||
DebugConsole.AddWarning(
|
||||
"Failed to receive remote main menu content. " +
|
||||
"There may be an issue with your internet connection, or the master server might be temporarily unavailable " +
|
||||
$"(error code: {remoteContentResponse.StatusCode})");
|
||||
$"The master server might be temporarily unavailable (HTTP error: {remoteContentResponse.StatusCode})");
|
||||
return;
|
||||
}
|
||||
string xml = remoteContentResponse.Content;
|
||||
|
||||
@@ -399,7 +399,7 @@ namespace Barotrauma
|
||||
string dir = path.RemoveFromEnd(ModReceiver.Extension, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
SaveUtil.DecompressToDirectory(path, dir);
|
||||
var result = ContentPackage.TryLoad(Path.Combine(dir, ContentPackage.FileListFileName));
|
||||
var result = ContentPackage.TryLoad(Path.Combine(dir, ContentPackage.FileListFileName).CleanUpPathCrossPlatform());
|
||||
|
||||
if (!result.TryUnwrapSuccess(out var newPackage))
|
||||
{
|
||||
|
||||
@@ -734,6 +734,8 @@ namespace Barotrauma
|
||||
AutoHideScrollBar = false,
|
||||
OnSelected = (component, userdata) =>
|
||||
{
|
||||
//if we're clicking on a checkbox (toggle visibility) on the list, don't select the entry on the list
|
||||
if (GUI.MouseOn is GUITickBox) { return false; }
|
||||
//toggling selection is not how listboxes normally work, need to do that manually here
|
||||
SoundPlayer.PlayUISound(GUISoundType.Select);
|
||||
if (layerList.SelectedData == userdata)
|
||||
@@ -3254,6 +3256,20 @@ namespace Barotrauma
|
||||
= new GUITextBox(new RectTransform((1.0f, 0.15f), saveInPackageLayout.RectTransform),
|
||||
createClearButton: true);
|
||||
|
||||
packToSaveInFilter.OnTextChanged += (GUITextBox textBox, string text) =>
|
||||
{
|
||||
|
||||
foreach (GUIComponent child in packageToSaveInList.Content.Children)
|
||||
{
|
||||
child.Visible =
|
||||
// Get the pkgText from below
|
||||
!(child.GetChild<GUILayoutGroup>()?.GetChild<GUITextBlock>() is GUITextBlock textBlock &&
|
||||
!textBlock.Text.Contains(packToSaveInFilter.Text, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
GUILayoutGroup addItemToPackageToSaveList(LocalizedString itemText, ContentPackage p)
|
||||
{
|
||||
var listItem = new GUIFrame(new RectTransform((1.0f, 0.15f), packageToSaveInList.Content.RectTransform),
|
||||
@@ -3274,28 +3290,26 @@ namespace Barotrauma
|
||||
return retVal;
|
||||
}
|
||||
|
||||
ContentPackage ownerPkg = null;
|
||||
|
||||
#if DEBUG
|
||||
//this is a debug-only option so I won't bother submitting it for localization
|
||||
var modifyVanillaListItem = addItemToPackageToSaveList("Modify Vanilla content package", ContentPackageManager.VanillaCorePackage);
|
||||
var modifyVanillaListIcon = modifyVanillaListItem.GetChild<GUIFrame>();
|
||||
GUIStyle.Apply(modifyVanillaListIcon, "WorkshopMenu.EditButton");
|
||||
|
||||
if (MainSub?.Info != null && IsVanillaSub(MainSub.Info))
|
||||
{
|
||||
ownerPkg = ContentPackageManager.VanillaCorePackage;
|
||||
}
|
||||
#endif
|
||||
|
||||
var newPackageListItem = addItemToPackageToSaveList(TextManager.Get("CreateNewLocalPackage"), null);
|
||||
var newPackageListIcon = newPackageListItem.GetChild<GUIFrame>();
|
||||
var newPackageListText = newPackageListItem.GetChild<GUITextBlock>();
|
||||
GUIStyle.Apply(newPackageListIcon, "NewContentPackageIcon");
|
||||
new GUICustomComponent(new RectTransform(Vector2.Zero, saveInPackageLayout.RectTransform),
|
||||
onUpdate: (f, component) =>
|
||||
{
|
||||
foreach (GUIComponent contentChild in packageToSaveInList.Content.Children)
|
||||
{
|
||||
contentChild.Visible &= !(contentChild.GetChild<GUILayoutGroup>()?.GetChild<GUITextBlock>() is GUITextBlock tb &&
|
||||
!tb.Text.Contains(packToSaveInFilter.Text, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
});
|
||||
ContentPackage ownerPkg = null;
|
||||
if (MainSub?.Info != null) { ownerPkg = GetLocalPackageThatOwnsSub(MainSub.Info); }
|
||||
|
||||
if (ownerPkg == null && MainSub?.Info != null) { ownerPkg = GetLocalPackageThatOwnsSub(MainSub.Info); }
|
||||
foreach (var p in ContentPackageManager.LocalPackages)
|
||||
{
|
||||
var packageListItem = addItemToPackageToSaveList(p.Name, p);
|
||||
@@ -3850,6 +3864,10 @@ namespace Barotrauma
|
||||
return true;
|
||||
};
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), deleteButtonHolder.RectTransform), TextManager.Get("DragAndDropSubmarineTip").Fallback(LocalizedString.EmptyString), textAlignment: Alignment.Center, font: GUIStyle.Font)
|
||||
{
|
||||
Wrap = true
|
||||
};
|
||||
|
||||
if (AutoSaveInfo?.Root != null)
|
||||
{
|
||||
@@ -4487,6 +4505,7 @@ namespace Barotrauma
|
||||
|
||||
public void ReconstructLayers()
|
||||
{
|
||||
Dictionary<string, LayerData> previousLayers = Layers.ToDictionary();
|
||||
ClearLayers();
|
||||
foreach (MapEntity entity in MapEntity.MapEntityList)
|
||||
{
|
||||
@@ -4495,6 +4514,13 @@ namespace Barotrauma
|
||||
Layers.TryAdd(entity.Layer, new LayerData(!entity.IsLayerHidden));
|
||||
}
|
||||
}
|
||||
foreach ((string layerName, LayerData data) in previousLayers)
|
||||
{
|
||||
if (Layers.ContainsKey(layerName))
|
||||
{
|
||||
Layers[layerName] = data;
|
||||
}
|
||||
}
|
||||
UpdateLayerPanel();
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ namespace Barotrauma
|
||||
public static DateTime NextCommandPush;
|
||||
public static Tuple<SerializableProperty, PropertyCommand> CommandBuffer;
|
||||
|
||||
private bool dimOutDefaultValues;
|
||||
|
||||
private bool isReadonly;
|
||||
public bool Readonly
|
||||
{
|
||||
@@ -316,16 +318,17 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public SerializableEntityEditor(RectTransform parent, ISerializableEntity entity, bool inGame, bool showName, string style = "", int elementHeight = 24, GUIFont titleFont = null)
|
||||
public SerializableEntityEditor(RectTransform parent, ISerializableEntity entity, bool inGame, bool showName, string style = "", int elementHeight = 24, GUIFont titleFont = null, bool dimOutDefaultValues = true)
|
||||
: this(parent, entity, inGame ?
|
||||
SerializableProperty.GetProperties<InGameEditable>(entity).Union(SerializableProperty.GetProperties<ConditionallyEditable>(entity).Where(p => p.GetAttribute<ConditionallyEditable>()?.IsEditable(entity) ?? false))
|
||||
: SerializableProperty.GetProperties<Editable>(entity).Where(p => p.GetAttribute<ConditionallyEditable>()?.IsEditable(entity) ?? true), showName, style, elementHeight, titleFont)
|
||||
: SerializableProperty.GetProperties<Editable>(entity).Where(p => p.GetAttribute<ConditionallyEditable>()?.IsEditable(entity) ?? true), showName, style, elementHeight, titleFont, dimOutDefaultValues)
|
||||
{
|
||||
}
|
||||
|
||||
public SerializableEntityEditor(RectTransform parent, ISerializableEntity entity, IEnumerable<SerializableProperty> properties, bool showName, string style = "", int elementHeight = 24, GUIFont titleFont = null)
|
||||
public SerializableEntityEditor(RectTransform parent, ISerializableEntity entity, IEnumerable<SerializableProperty> properties, bool showName, string style = "", int elementHeight = 24, GUIFont titleFont = null, bool dimOutDefaultValues = true)
|
||||
: base(style, new RectTransform(Vector2.One, parent))
|
||||
{
|
||||
this.dimOutDefaultValues = dimOutDefaultValues;
|
||||
elementHeight = (int)(elementHeight * GUI.Scale);
|
||||
var tickBoxStyle = GUIStyle.GetComponentStyle("GUITickBox");
|
||||
var textBoxStyle = GUIStyle.GetComponentStyle("GUITextBox");
|
||||
@@ -523,9 +526,67 @@ namespace Barotrauma
|
||||
{
|
||||
propertyField = CreateStringField(entity, property, value.ToString(), displayName, toolTip);
|
||||
}
|
||||
if (propertyField != null && dimOutDefaultValues)
|
||||
{
|
||||
UpdateTextColors(property, entity, propertyField);
|
||||
}
|
||||
return propertyField;
|
||||
}
|
||||
|
||||
|
||||
private void UpdateTextColors(SerializableProperty property, object parentObject, GUIComponent parentElement)
|
||||
{
|
||||
if (!dimOutDefaultValues) { return; }
|
||||
|
||||
bool isSetToDefaultValue = false;
|
||||
object currentValue = property.GetValue(parentObject);
|
||||
foreach (var attribute in property.Attributes.OfType<Serialize>())
|
||||
{
|
||||
if (XMLExtensions.DefaultValueEquals(attribute.DefaultValue, currentValue) ||
|
||||
//treat null and empty strings as identical, because there's no way to differentiate between those in the editor
|
||||
(currentValue == null && attribute.DefaultValue is string defaultValueStr && defaultValueStr.IsNullOrEmpty()))
|
||||
{
|
||||
isSetToDefaultValue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach (var component in parentElement.GetAllChildren())
|
||||
{
|
||||
UpdateTextColors(component, isSetToDefaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTextColors(GUIComponent component, bool isSetToDefaultValue)
|
||||
{
|
||||
if (!dimOutDefaultValues) { return; }
|
||||
|
||||
if (component is GUINumberInput numberInput)
|
||||
{
|
||||
SetTextColor(numberInput.TextBox.TextBlock);
|
||||
}
|
||||
else if (component is GUIDropDown dropDown)
|
||||
{
|
||||
SetTextColor(dropDown.Button.TextBlock);
|
||||
}
|
||||
else if (component is GUITextBox textBox)
|
||||
{
|
||||
SetTextColor(textBox.TextBlock);
|
||||
}
|
||||
else if (component is GUITextBlock textBlock)
|
||||
{
|
||||
SetTextColor(textBlock);
|
||||
}
|
||||
else if (component is GUITickBox tickBox)
|
||||
{
|
||||
SetTextColor(tickBox.TextBlock);
|
||||
}
|
||||
|
||||
void SetTextColor(GUITextBlock textBlock)
|
||||
{
|
||||
textBlock.TextColor = new Color(textBlock.TextColor, alpha: isSetToDefaultValue ? 0.5f : 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
public GUIComponent CreateBoolField(ISerializableEntity entity, SerializableProperty property, bool value, LocalizedString displayName, LocalizedString toolTip)
|
||||
{
|
||||
var editableAttribute = property.GetAttribute<Editable>();
|
||||
@@ -564,6 +625,7 @@ namespace Barotrauma
|
||||
tickBox.Selected = propertyValue;
|
||||
tickBox.Flash(Color.Red);
|
||||
}
|
||||
UpdateTextColors(property, entity, tickBox);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -611,6 +673,7 @@ namespace Barotrauma
|
||||
{
|
||||
TrySendNetworkUpdate(entity, property);
|
||||
}
|
||||
UpdateTextColors(property, entity, frame);
|
||||
};
|
||||
refresh += () =>
|
||||
{
|
||||
@@ -654,6 +717,7 @@ namespace Barotrauma
|
||||
{
|
||||
TrySendNetworkUpdate(entity, property);
|
||||
}
|
||||
UpdateTextColors(property, entity, frame);
|
||||
};
|
||||
|
||||
HandleSetterValueTampering(numberInput, () => property.GetFloatValue(entity));
|
||||
@@ -711,6 +775,7 @@ namespace Barotrauma
|
||||
{
|
||||
TrySendNetworkUpdate(entity, property);
|
||||
}
|
||||
UpdateTextColors(property, entity, frame);
|
||||
return true;
|
||||
};
|
||||
refresh += () =>
|
||||
@@ -829,6 +894,7 @@ namespace Barotrauma
|
||||
TrySendNetworkUpdate(entity, property);
|
||||
textBox.Text = StripPrefabTags(property.GetValue(entity).ToString());
|
||||
textBox.Flash(GUIStyle.Green, flashDuration: 1f);
|
||||
UpdateTextColors(property, entity, frame);
|
||||
}
|
||||
//restore the entities that were selected before applying
|
||||
MapEntity.SelectedList.Clear();
|
||||
@@ -973,6 +1039,7 @@ namespace Barotrauma
|
||||
{
|
||||
TrySendNetworkUpdate(entity, property);
|
||||
}
|
||||
UpdateTextColors(property, entity, frame);
|
||||
};
|
||||
fields[i] = numberInput;
|
||||
}
|
||||
@@ -1046,6 +1113,7 @@ namespace Barotrauma
|
||||
{
|
||||
TrySendNetworkUpdate(entity, property);
|
||||
}
|
||||
UpdateTextColors(property, entity, frame);
|
||||
};
|
||||
HandleSetterValueTampering(numberInput, () =>
|
||||
{
|
||||
@@ -1126,6 +1194,7 @@ namespace Barotrauma
|
||||
{
|
||||
TrySendNetworkUpdate(entity, property);
|
||||
}
|
||||
UpdateTextColors(property, entity, frame);
|
||||
};
|
||||
fields[i] = numberInput;
|
||||
}
|
||||
@@ -1206,6 +1275,7 @@ namespace Barotrauma
|
||||
{
|
||||
TrySendNetworkUpdate(entity, property);
|
||||
}
|
||||
UpdateTextColors(property, entity, frame);
|
||||
};
|
||||
fields[i] = numberInput;
|
||||
}
|
||||
@@ -1299,6 +1369,7 @@ namespace Barotrauma
|
||||
TrySendNetworkUpdate(entity, property);
|
||||
colorBox.Color = colorBox.HoverColor = colorBox.PressedColor = colorBox.SelectedTextColor = newVal;
|
||||
}
|
||||
UpdateTextColors(property, entity, frame);
|
||||
};
|
||||
colorBox.Color = colorBox.HoverColor = colorBox.PressedColor = colorBox.SelectedTextColor = (Color)property.GetValue(entity);
|
||||
fields[i] = numberInput;
|
||||
@@ -1373,6 +1444,7 @@ namespace Barotrauma
|
||||
{
|
||||
TrySendNetworkUpdate(entity, property);
|
||||
}
|
||||
UpdateTextColors(property, entity, frame);
|
||||
};
|
||||
fields[i] = numberInput;
|
||||
}
|
||||
@@ -1437,6 +1509,7 @@ namespace Barotrauma
|
||||
TrySendNetworkUpdate(entity, property);
|
||||
textBox.Flash(color: GUIStyle.Green, flashDuration: 1f);
|
||||
}
|
||||
UpdateTextColors(property, entity, frame);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -387,13 +387,11 @@ These will hide all servers that have a discord.gg link in their name or descrip
|
||||
|
||||
try
|
||||
{
|
||||
var client = new RestClient($"{remoteContentUrl}spamfilter")
|
||||
{
|
||||
CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore)
|
||||
};
|
||||
var client = RestFactory.CreateClient($"{remoteContentUrl}spamfilter");
|
||||
client.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
|
||||
client.AddDefaultHeader("Cache-Control", "no-cache");
|
||||
client.AddDefaultHeader("Pragma", "no-cache");
|
||||
var request = new RestRequest("serve_spamlist.php", Method.GET);
|
||||
var request = RestFactory.CreateRequest("serve_spamlist.php");
|
||||
TaskPool.Add("RequestGlobalSpamFilter", client.ExecuteAsync(request), RemoteContentReceived);
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -410,12 +408,18 @@ These will hide all servers that have a discord.gg link in their name or descrip
|
||||
try
|
||||
{
|
||||
if (!t.TryGetResult(out IRestResponse? remoteContentResponse)) { throw new Exception("Task did not return a valid result"); }
|
||||
if (remoteContentResponse.ErrorException != null)
|
||||
{
|
||||
DebugConsole.AddWarning(
|
||||
"Connection error: Failed to receive global spam filter " +
|
||||
$"({remoteContentResponse.ErrorException.Message}).");
|
||||
return;
|
||||
}
|
||||
if (remoteContentResponse.StatusCode != HttpStatusCode.OK)
|
||||
{
|
||||
DebugConsole.AddWarning(
|
||||
"Failed to receive global spam filter." +
|
||||
"There may be an issue with your internet connection, or the master server might be temporarily unavailable " +
|
||||
$"(error code: {remoteContentResponse.StatusCode})");
|
||||
"Failed to receive global spam filter. " +
|
||||
$"The master server might be temporarily unavailable, HTTP status: {remoteContentResponse.StatusCode}");
|
||||
return;
|
||||
}
|
||||
string data = remoteContentResponse.Content;
|
||||
|
||||
@@ -23,13 +23,27 @@ namespace Barotrauma.Steam
|
||||
"submarine",
|
||||
"item",
|
||||
"monster",
|
||||
"art",
|
||||
"mission",
|
||||
"outpost",
|
||||
"beaconstation",
|
||||
"wreck",
|
||||
"ruin",
|
||||
"weapons",
|
||||
"medical",
|
||||
"equipment",
|
||||
"art",
|
||||
"event set",
|
||||
"total conversion",
|
||||
"gamemode",
|
||||
"gameplaymechanics",
|
||||
"environment",
|
||||
"item assembly",
|
||||
"language",
|
||||
"qol",
|
||||
"clientside",
|
||||
"serverside",
|
||||
"outdated",
|
||||
"library"
|
||||
}.ToIdentifiers().ToImmutableArray();
|
||||
|
||||
public class ItemThumbnail : IDisposable
|
||||
@@ -113,10 +127,14 @@ namespace Barotrauma.Steam
|
||||
|
||||
string? thumbnailUrl = item.PreviewImageUrl;
|
||||
if (thumbnailUrl.IsNullOrWhiteSpace()) { return null; }
|
||||
var client = new RestClient(thumbnailUrl);
|
||||
var request = new RestRequest(".", Method.GET);
|
||||
var client = RestFactory.CreateClient(thumbnailUrl);
|
||||
var request = RestFactory.CreateRequest(".");
|
||||
IRestResponse response = await client.ExecuteAsync(request, cancellationToken);
|
||||
if (response is { StatusCode: System.Net.HttpStatusCode.OK, ResponseStatus: ResponseStatus.Completed })
|
||||
if (response.ErrorException != null)
|
||||
{
|
||||
DebugConsole.NewMessage($"Connection error: Failed to load workshop item thumbnail for {item.Id} ({response.ErrorException.Message}).");
|
||||
}
|
||||
else if (response is { StatusCode: System.Net.HttpStatusCode.OK, ResponseStatus: ResponseStatus.Completed })
|
||||
{
|
||||
using var dataStream = new System.IO.MemoryStream();
|
||||
await dataStream.WriteAsync(response.RawBytes, cancellationToken);
|
||||
|
||||
@@ -535,9 +535,9 @@ namespace Barotrauma.Steam
|
||||
= new GUIListBox(rectT, style: null, isHorizontal: false)
|
||||
{
|
||||
UseGridLayout = true,
|
||||
ScrollBarEnabled = false,
|
||||
ScrollBarEnabled = true,
|
||||
ScrollBarVisible = false,
|
||||
HideChildrenOutsideFrame = false,
|
||||
HideChildrenOutsideFrame = true,
|
||||
Spacing = GUI.IntScale(4)
|
||||
};
|
||||
tagsList.Content.ClampMouseRectToParent = false;
|
||||
|
||||
Reference in New Issue
Block a user