Build 0.18.0.0
This commit is contained in:
@@ -400,7 +400,7 @@ namespace Barotrauma
|
||||
|
||||
partial void UpdateControlled(float deltaTime, Camera cam)
|
||||
{
|
||||
if (controlled != this) return;
|
||||
if (controlled != this) { return; }
|
||||
|
||||
ControlLocalPlayer(deltaTime, cam);
|
||||
|
||||
|
||||
@@ -2008,8 +2008,27 @@ namespace Barotrauma
|
||||
DisplayedVitality = Vitality;
|
||||
}
|
||||
|
||||
partial void UpdateSkinTint()
|
||||
{
|
||||
if (!Character.IsVisible) { return; }
|
||||
FaceTint = DefaultFaceTint;
|
||||
BodyTint = Color.TransparentBlack;
|
||||
|
||||
if (!(Character?.Params?.Health.ApplyAfflictionColors ?? false)) { return; }
|
||||
|
||||
foreach (KeyValuePair<Affliction, LimbHealth> kvp in afflictions)
|
||||
{
|
||||
var affliction = kvp.Key;
|
||||
Color faceTint = affliction.GetFaceTint();
|
||||
if (faceTint.A > FaceTint.A) { FaceTint = faceTint; }
|
||||
Color bodyTint = affliction.GetBodyTint();
|
||||
if (bodyTint.A > BodyTint.A) { BodyTint = bodyTint; }
|
||||
}
|
||||
}
|
||||
|
||||
partial void UpdateLimbAfflictionOverlays()
|
||||
{
|
||||
if (!Character.IsVisible) { return; }
|
||||
foreach (Limb limb in Character.AnimController.Limbs)
|
||||
{
|
||||
if (limb.HealthIndex < 0 || limb.HealthIndex >= limbHealths.Count) { continue; }
|
||||
|
||||
@@ -58,21 +58,19 @@ namespace Barotrauma
|
||||
|
||||
public class OutfitPreview
|
||||
{
|
||||
/// <summary>
|
||||
/// Pair.First = sprite, Pair.Second = draw offset
|
||||
/// </summary>
|
||||
public readonly List<Pair<Sprite, Vector2>> Sprites;
|
||||
public readonly List<(Sprite sprite, Vector2 drawOffset)> Sprites;
|
||||
|
||||
public Vector2 Dimensions;
|
||||
|
||||
public OutfitPreview()
|
||||
{
|
||||
Sprites = new List<Pair<Sprite, Vector2>>();
|
||||
Sprites = new List<(Sprite sprite, Vector2 drawOffset)>();
|
||||
Dimensions = Vector2.One;
|
||||
}
|
||||
|
||||
public void AddSprite(Sprite sprite, Vector2 drawOffset)
|
||||
{
|
||||
Sprites.Add(new Pair<Sprite, Vector2>(sprite, drawOffset));
|
||||
Sprites.Add((sprite, drawOffset));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -224,14 +224,14 @@ namespace Barotrauma
|
||||
public float DamageOverlayStrength
|
||||
{
|
||||
get { return damageOverlayStrength; }
|
||||
set { damageOverlayStrength = MathHelper.Clamp(value, 0.0f, 100.0f); }
|
||||
set { damageOverlayStrength = MathHelper.Clamp(value, 0.0f, 1.0f); }
|
||||
}
|
||||
|
||||
private float burnOverLayStrength;
|
||||
public float BurnOverlayStrength
|
||||
{
|
||||
get { return burnOverLayStrength; }
|
||||
set { burnOverLayStrength = MathHelper.Clamp(value, 0.0f, 100.0f); }
|
||||
set { burnOverLayStrength = MathHelper.Clamp(value, 0.0f, 1.0f); }
|
||||
}
|
||||
|
||||
public string HitSoundTag => Params?.Sound?.Tag;
|
||||
@@ -279,7 +279,7 @@ namespace Barotrauma
|
||||
for (int i = 0; i < Params.decorativeSpriteParams.Count; i++)
|
||||
{
|
||||
var param = Params.decorativeSpriteParams[i];
|
||||
var decorativeSprite = new DecorativeSprite(param.Element, file: GetSpritePath(param.Element, param));
|
||||
var decorativeSprite = new DecorativeSprite(param.Element, file: GetSpritePath(param.Element, param, ref _texturePath));
|
||||
DecorativeSprites.Add(decorativeSprite);
|
||||
int groupID = decorativeSprite.RandomGroupID;
|
||||
if (!DecorativeSpriteGroups.ContainsKey(groupID))
|
||||
@@ -295,13 +295,13 @@ namespace Barotrauma
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
{
|
||||
case "sprite":
|
||||
Sprite = new Sprite(subElement, file: GetSpritePath(subElement, Params.normalSpriteParams));
|
||||
Sprite = new Sprite(subElement, file: GetSpritePath(subElement, Params.normalSpriteParams, ref _texturePath));
|
||||
break;
|
||||
case "damagedsprite":
|
||||
DamagedSprite = new Sprite(subElement, file: GetSpritePath(subElement, Params.damagedSpriteParams));
|
||||
case "damagedsprite":
|
||||
DamagedSprite = new Sprite(subElement, file: GetSpritePath(subElement, Params.damagedSpriteParams, ref _damagedTexturePath));
|
||||
break;
|
||||
case "conditionalsprite":
|
||||
var conditionalSprite = new ConditionalSprite(subElement, GetConditionalTarget(), file: GetSpritePath(subElement, null));
|
||||
var conditionalSprite = new ConditionalSprite(subElement, GetConditionalTarget(), file: GetSpritePath(subElement, null, ref _texturePath));
|
||||
ConditionalSprites.Add(conditionalSprite);
|
||||
if (conditionalSprite.DeformableSprite != null)
|
||||
{
|
||||
@@ -311,7 +311,7 @@ namespace Barotrauma
|
||||
}
|
||||
break;
|
||||
case "deformablesprite":
|
||||
_deformSprite = new DeformableSprite(subElement, filePath: GetSpritePath(subElement, Params.deformSpriteParams));
|
||||
_deformSprite = new DeformableSprite(subElement, filePath: GetSpritePath(subElement, Params.deformSpriteParams, ref _texturePath));
|
||||
var deformations = CreateDeformations(subElement);
|
||||
Deformations.AddRange(deformations);
|
||||
NonConditionalDeformations.AddRange(deformations);
|
||||
@@ -435,33 +435,33 @@ namespace Barotrauma
|
||||
{
|
||||
Sprite.Remove();
|
||||
var source = Sprite.SourceElement;
|
||||
Sprite = new Sprite(source, file: GetSpritePath(source, Params.normalSpriteParams));
|
||||
Sprite = new Sprite(source, file: GetSpritePath(source, Params.normalSpriteParams, ref _texturePath));
|
||||
}
|
||||
if (_deformSprite != null)
|
||||
{
|
||||
_deformSprite.Remove();
|
||||
var source = _deformSprite.Sprite.SourceElement;
|
||||
_deformSprite = new DeformableSprite(source, filePath: GetSpritePath(source, Params.deformSpriteParams));
|
||||
_deformSprite = new DeformableSprite(source, filePath: GetSpritePath(source, Params.deformSpriteParams, ref _texturePath));
|
||||
}
|
||||
if (DamagedSprite != null)
|
||||
{
|
||||
DamagedSprite.Remove();
|
||||
var source = DamagedSprite.SourceElement;
|
||||
DamagedSprite = new Sprite(source, file: GetSpritePath(source, Params.damagedSpriteParams));
|
||||
DamagedSprite = new Sprite(source, file: GetSpritePath(source, Params.damagedSpriteParams, ref _damagedTexturePath));
|
||||
}
|
||||
for (int i = 0; i < ConditionalSprites.Count; i++)
|
||||
{
|
||||
var conditionalSprite = ConditionalSprites[i];
|
||||
var source = conditionalSprite.ActiveSprite.SourceElement;
|
||||
conditionalSprite.Remove();
|
||||
ConditionalSprites[i] = new ConditionalSprite(source, character, file: GetSpritePath(source, null));
|
||||
ConditionalSprites[i] = new ConditionalSprite(source, character, file: GetSpritePath(source, null, ref _texturePath));
|
||||
}
|
||||
for (int i = 0; i < DecorativeSprites.Count; i++)
|
||||
{
|
||||
var decorativeSprite = DecorativeSprites[i];
|
||||
decorativeSprite.Remove();
|
||||
var source = decorativeSprite.Sprite.SourceElement;
|
||||
DecorativeSprites[i] = new DecorativeSprite(source, file: GetSpritePath(source, Params.decorativeSpriteParams[i]));
|
||||
DecorativeSprites[i] = new DecorativeSprite(source, file: GetSpritePath(source, Params.decorativeSpriteParams[i], ref _texturePath));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -472,16 +472,17 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
private string _texturePath;
|
||||
private string GetSpritePath(ContentXElement element, SpriteParams spriteParams)
|
||||
private string _damagedTexturePath;
|
||||
private string GetSpritePath(ContentXElement element, SpriteParams spriteParams, ref string path)
|
||||
{
|
||||
if (_texturePath == null)
|
||||
if (path == null)
|
||||
{
|
||||
if (spriteParams != null)
|
||||
{
|
||||
ContentPath texturePath =
|
||||
character.Params.VariantFile?.Root?.GetAttributeContentPath("texture", character.Prefab.ContentPackage)
|
||||
?? ContentPath.FromRaw(character.Prefab.ContentPackage, spriteParams.GetTexturePath());
|
||||
_texturePath = GetSpritePath(texturePath);
|
||||
path = GetSpritePath(texturePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -489,10 +490,10 @@ namespace Barotrauma
|
||||
texturePath = texturePath.IsNullOrWhiteSpace()
|
||||
? ContentPath.FromRaw(character.Prefab.ContentPackage, ragdoll.RagdollParams.Texture)
|
||||
: texturePath;
|
||||
_texturePath = GetSpritePath(texturePath);
|
||||
path = GetSpritePath(texturePath);
|
||||
}
|
||||
}
|
||||
return _texturePath;
|
||||
return path;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -625,12 +626,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (!body.Enabled) { return; }
|
||||
|
||||
if (!IsDead)
|
||||
{
|
||||
DamageOverlayStrength -= deltaTime;
|
||||
BurnOverlayStrength -= deltaTime;
|
||||
}
|
||||
else
|
||||
if (IsDead)
|
||||
{
|
||||
var spriteParams = Params.GetSprite();
|
||||
if (spriteParams != null && spriteParams.DeadColorTime > 0 && deadTimer < spriteParams.DeadColorTime)
|
||||
@@ -688,7 +684,7 @@ namespace Barotrauma
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, Camera cam, Color? overrideColor = null, bool disableDeformations = false)
|
||||
{
|
||||
float brightness = 1.0f - (burnOverLayStrength / 100.0f) * 0.5f;
|
||||
float brightness = Math.Max(1.0f - burnOverLayStrength, 0.2f);
|
||||
var spriteParams = Params.GetSprite();
|
||||
if (spriteParams == null) { return; }
|
||||
|
||||
@@ -831,32 +827,6 @@ namespace Barotrauma
|
||||
{
|
||||
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,
|
||||
-body.DrawRotation,
|
||||
Scale, spriteEffect, activeSprite.Depth - (depthStep * 90));
|
||||
}
|
||||
foreach (var decorativeSprite in DecorativeSprites)
|
||||
{
|
||||
if (!spriteAnimState[decorativeSprite].IsActive) { continue; }
|
||||
Color c = new Color(decorativeSprite.Color.R / 255f * brightness, decorativeSprite.Color.G / 255f * brightness, decorativeSprite.Color.B / 255f * brightness, decorativeSprite.Color.A / 255f);
|
||||
if (deadTimer > 0)
|
||||
{
|
||||
c = Color.Lerp(c, spriteParams.DeadColor, MathUtils.InverseLerp(0, Params.GetSprite().DeadColorTime, deadTimer));
|
||||
}
|
||||
c = overrideColor ?? c;
|
||||
float rotation = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState, spriteAnimState[decorativeSprite].RandomRotationFactor);
|
||||
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState, spriteAnimState[decorativeSprite].RandomOffsetMultiplier) * Scale;
|
||||
var ca = (float)Math.Cos(-body.Rotation);
|
||||
var sa = (float)Math.Sin(-body.Rotation);
|
||||
Vector2 transformedOffset = new Vector2(ca * offset.X + sa * offset.Y, -sa * offset.X + ca * offset.Y);
|
||||
decorativeSprite.Sprite.Draw(spriteBatch, new Vector2(body.DrawPosition.X + transformedOffset.X, -(body.DrawPosition.Y + transformedOffset.Y)), c,
|
||||
-body.Rotation + rotation, decorativeSprite.GetScale(spriteAnimState[decorativeSprite].RandomScaleFactor) * Scale, spriteEffect,
|
||||
depth: activeSprite.Depth - (depthStep * 100));
|
||||
}
|
||||
float step = depthStep;
|
||||
WearableSprite onlyDrawable = wearingItems.Find(w => w.HideOtherWearables);
|
||||
if (Params.MirrorHorizontally)
|
||||
@@ -925,6 +895,36 @@ namespace Barotrauma
|
||||
//if there are multiple sprites on this limb, make the successive ones be drawn in front
|
||||
depthStep += step;
|
||||
}
|
||||
if (!Hide && onlyDrawable == null)
|
||||
{
|
||||
foreach (var decorativeSprite in DecorativeSprites)
|
||||
{
|
||||
if (!spriteAnimState[decorativeSprite].IsActive) { continue; }
|
||||
Color c = new Color(decorativeSprite.Color.R / 255f * brightness, decorativeSprite.Color.G / 255f * brightness, decorativeSprite.Color.B / 255f * brightness, decorativeSprite.Color.A / 255f);
|
||||
if (deadTimer > 0)
|
||||
{
|
||||
c = Color.Lerp(c, spriteParams.DeadColor, MathUtils.InverseLerp(0, Params.GetSprite().DeadColorTime, deadTimer));
|
||||
}
|
||||
c = overrideColor ?? c;
|
||||
float rotation = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState, spriteAnimState[decorativeSprite].RandomRotationFactor);
|
||||
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState, spriteAnimState[decorativeSprite].RandomOffsetMultiplier) * Scale;
|
||||
var ca = (float)Math.Cos(-body.Rotation);
|
||||
var sa = (float)Math.Sin(-body.Rotation);
|
||||
Vector2 transformedOffset = new Vector2(ca * offset.X + sa * offset.Y, -sa * offset.X + ca * offset.Y);
|
||||
decorativeSprite.Sprite.Draw(spriteBatch, new Vector2(body.DrawPosition.X + transformedOffset.X, -(body.DrawPosition.Y + transformedOffset.Y)), c,
|
||||
-body.Rotation + rotation, decorativeSprite.GetScale(spriteAnimState[decorativeSprite].RandomScaleFactor) * Scale, spriteEffect,
|
||||
depth: activeSprite.Depth - depthStep);
|
||||
depthStep += step;
|
||||
}
|
||||
if (damageOverlayStrength > 0.0f && DamagedSprite != null)
|
||||
{
|
||||
DamagedSprite.Draw(spriteBatch,
|
||||
new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
|
||||
color * damageOverlayStrength, activeSprite.Origin,
|
||||
-body.DrawRotation,
|
||||
Scale, spriteEffect, activeSprite.Depth - depthStep * Math.Max(1, WearingItems.Count * 2)); // Multiply by 2 to get rid of z-fighting with some clothing combos
|
||||
}
|
||||
}
|
||||
|
||||
if (GameMain.DebugDraw)
|
||||
{
|
||||
|
||||
+1
-1
@@ -359,7 +359,7 @@ namespace Barotrauma.Transition
|
||||
else
|
||||
{
|
||||
//copying a mod: we have a neat method for that!
|
||||
await SteamManager.Workshop.CopyDirectory(path, Path.GetFileName(path), path, destPath);
|
||||
await SteamManager.Workshop.CopyDirectory(path, Path.GetFileName(path), path, destPath, SteamManager.Workshop.ShouldCorrectPaths.Yes);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (isOpen)
|
||||
{
|
||||
frame.AddToGUIUpdateList();
|
||||
frame.AddToGUIUpdateList(order: 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1714,9 +1714,47 @@ namespace Barotrauma
|
||||
//check missing mission texts
|
||||
foreach (var missionPrefab in MissionPrefab.Prefabs)
|
||||
{
|
||||
Identifier missionId = (missionPrefab.ConfigElement.GetAttribute("textidentifier") == null ? missionPrefab.Identifier : missionPrefab.ConfigElement.GetAttributeIdentifier("textidentifier", Identifier.Empty));
|
||||
addIfMissing($"missionname.{missionId}".ToIdentifier(), language);
|
||||
addIfMissing($"missiondescription.{missionId}".ToIdentifier(), language);
|
||||
Identifier missionId = missionPrefab.ConfigElement.GetAttribute("textidentifier") == null ?
|
||||
missionPrefab.Identifier :
|
||||
missionPrefab.ConfigElement.GetAttributeIdentifier("textidentifier", Identifier.Empty);
|
||||
|
||||
if (!tags[language].Contains(missionPrefab.ConfigElement.GetAttributeIdentifier("name", Identifier.Empty)))
|
||||
{
|
||||
addIfMissing($"missionname.{missionId}".ToIdentifier(), language);
|
||||
}
|
||||
|
||||
if (missionPrefab.Type == MissionType.Combat)
|
||||
{
|
||||
addIfMissing($"MissionDescriptionNeutral.{missionId}".ToIdentifier(), language);
|
||||
addIfMissing($"MissionDescription1.{missionId}".ToIdentifier(), language);
|
||||
addIfMissing($"MissionDescription2.{missionId}".ToIdentifier(), language);
|
||||
addIfMissing($"MissionTeam1.{missionId}".ToIdentifier(), language);
|
||||
addIfMissing($"MissionTeam2.{missionId}".ToIdentifier(), language);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!tags[language].Contains(missionPrefab.ConfigElement.GetAttributeIdentifier("description", Identifier.Empty)))
|
||||
{
|
||||
addIfMissing($"missiondescription.{missionId}".ToIdentifier(), language);
|
||||
}
|
||||
if (!tags[language].Contains(missionPrefab.ConfigElement.GetAttributeIdentifier("successmessage", Identifier.Empty)))
|
||||
{
|
||||
addIfMissing($"missionsuccess.{missionId}".ToIdentifier(), language);
|
||||
}
|
||||
//only check failure message if there's something defined in the xml (otherwise we just use the generic "missionfailed" text)
|
||||
if (missionPrefab.ConfigElement.GetAttribute("failuremessage") != null &&
|
||||
!tags[language].Contains(missionPrefab.ConfigElement.GetAttributeIdentifier("failuremessage", Identifier.Empty)))
|
||||
{
|
||||
addIfMissing($"missionfailure.{missionId}".ToIdentifier(), language);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i<missionPrefab.Messages.Length; i++)
|
||||
{
|
||||
if (missionPrefab.Messages[i].IsNullOrWhiteSpace())
|
||||
{
|
||||
addIfMissing($"MissionMessage{i}.{missionId}".ToIdentifier(), language);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Type itemComponentType in typeof(ItemComponent).Assembly.GetTypes().Where(type => type.IsSubclassOf(typeof(ItemComponent))))
|
||||
@@ -2503,7 +2541,7 @@ namespace Barotrauma
|
||||
var entity = MapEntity.mapEntityList[i] as ISerializableEntity;
|
||||
if (entity != null)
|
||||
{
|
||||
List<Pair<object, SerializableProperty>> allProperties = new List<Pair<object, SerializableProperty>>();
|
||||
List<(object obj, SerializableProperty property)> allProperties = new List<(object obj, SerializableProperty property)>();
|
||||
|
||||
if (entity is Item item)
|
||||
{
|
||||
@@ -2518,14 +2556,14 @@ namespace Barotrauma
|
||||
|
||||
for (int k = 0; k < properties.Count; k++)
|
||||
{
|
||||
allProperties.Add(new Pair<object, SerializableProperty>(entity, properties[k]));
|
||||
allProperties.Add((entity, properties[k]));
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < allProperties.Count; j++)
|
||||
{
|
||||
var property = allProperties[j].Second;
|
||||
string propertyName = (allProperties[j].First.GetType().Name + "." + property.PropertyInfo.Name).ToLowerInvariant();
|
||||
var property = allProperties[j].property;
|
||||
string propertyName = (allProperties[j].obj.GetType().Name + "." + property.PropertyInfo.Name).ToLowerInvariant();
|
||||
LocalizedString displayName = TextManager.Get($"sp.{propertyName}.name");
|
||||
if (displayName.IsNullOrEmpty())
|
||||
{
|
||||
|
||||
@@ -35,7 +35,6 @@ namespace Barotrauma
|
||||
public TextGetterHandler TextGetter;
|
||||
|
||||
public bool Wrap;
|
||||
private bool playerInput;
|
||||
|
||||
public bool RoundToNearestPixel = true;
|
||||
|
||||
@@ -287,8 +286,7 @@ namespace Barotrauma
|
||||
/// If the rectT height is set 0, the height is calculated from the text.
|
||||
/// </summary>
|
||||
public GUITextBlock(RectTransform rectT, RichString text, Color? textColor = null, GUIFont font = null,
|
||||
Alignment textAlignment = Alignment.Left, bool wrap = false, string style = "", Color? color = null,
|
||||
bool playerInput = false)
|
||||
Alignment textAlignment = Alignment.Left, bool wrap = false, string style = "", Color? color = null)
|
||||
: base(style, rectT)
|
||||
{
|
||||
if (color.HasValue)
|
||||
@@ -307,7 +305,6 @@ namespace Barotrauma
|
||||
this.textAlignment = textAlignment;
|
||||
this.Wrap = wrap;
|
||||
this.Text = text ?? "";
|
||||
this.playerInput = playerInput;
|
||||
if (rectT.Rect.Height == 0 && !text.IsNullOrEmpty())
|
||||
{
|
||||
CalculateHeightFromText();
|
||||
|
||||
@@ -261,7 +261,7 @@ namespace Barotrauma
|
||||
this.color = color ?? Color.White;
|
||||
frame = new GUIFrame(new RectTransform(Vector2.One, rectT, Anchor.Center), style, color);
|
||||
GUIStyle.Apply(frame, style == "" ? "GUITextBox" : style);
|
||||
textBlock = new GUITextBlock(new RectTransform(Vector2.One, frame.RectTransform, Anchor.CenterLeft), text ?? "", textColor, font, textAlignment, wrap, playerInput: true);
|
||||
textBlock = new GUITextBlock(new RectTransform(Vector2.One, frame.RectTransform, Anchor.CenterLeft), text ?? "", textColor, font, textAlignment, wrap);
|
||||
GUIStyle.Apply(textBlock, "", this);
|
||||
if (font != null) { textBlock.Font = font; }
|
||||
CaretEnabled = true;
|
||||
|
||||
@@ -657,6 +657,7 @@ namespace Barotrauma
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
GUILayoutGroup parentLayout = new GUILayoutGroup(new RectTransform(Vector2.One, backgroundFrame.RectTransform), isHorizontal: true) { Stretch = true };
|
||||
|
||||
if (!(affliction.Prefab is { } prefab)) { return; }
|
||||
@@ -676,7 +677,7 @@ namespace Barotrauma
|
||||
GUIFrame textContainer = new GUIFrame(new RectTransform(new Vector2(0.6f, 1f), textLayout.RectTransform), style: null);
|
||||
GUITextBlock afflictionName = new GUITextBlock(new RectTransform(Vector2.One, textContainer.RectTransform), name, font: GUIStyle.SubHeadingFont);
|
||||
|
||||
GUITextBlock healCost = new GUITextBlock(new RectTransform(new Vector2(0.2f, 1f), textLayout.RectTransform), TextManager.FormatCurrency(affliction.Price), textAlignment: Alignment.Center, font: GUIStyle.LargeFont)
|
||||
GUITextBlock healCost = new GUITextBlock(new RectTransform(new Vector2(0.2f, 1f), textLayout.RectTransform), TextManager.FormatCurrency(affliction.Price), textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont)
|
||||
{
|
||||
Padding = Vector4.Zero
|
||||
};
|
||||
@@ -746,12 +747,12 @@ namespace Barotrauma
|
||||
|
||||
ClosePopup();
|
||||
|
||||
GUIFrame mainFrame = new GUIFrame(new RectTransform(new Vector2(0.28f, 0.45f), container.RectTransform)
|
||||
GUIFrame mainFrame = new GUIFrame(new RectTransform(new Vector2(0.28f, 0.5f), container.RectTransform)
|
||||
{
|
||||
ScreenSpaceOffset = location.ToPoint()
|
||||
});
|
||||
|
||||
GUILayoutGroup mainLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.95f), mainFrame.RectTransform, Anchor.Center)) { RelativeSpacing = 0.01f, Stretch = true };
|
||||
GUILayoutGroup mainLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), mainFrame.RectTransform, Anchor.Center)) { RelativeSpacing = 0.01f, Stretch = true };
|
||||
|
||||
if (mainFrame.Rect.Bottom > GameMain.GraphicsHeight)
|
||||
{
|
||||
@@ -819,7 +820,9 @@ namespace Barotrauma
|
||||
if (!(affliction.Prefab is { } prefab)) { return ImmutableArray<GUIComponent>.Empty; }
|
||||
|
||||
GUIFrame backgroundFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.33f), parent.RectTransform), style: "ListBoxElement");
|
||||
GUILayoutGroup mainLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.95f), backgroundFrame.RectTransform, Anchor.Center))
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.01f), backgroundFrame.RectTransform, Anchor.BottomCenter), style: "HorizontalLine");
|
||||
|
||||
GUILayoutGroup mainLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), backgroundFrame.RectTransform, Anchor.Center))
|
||||
{
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
@@ -862,13 +865,27 @@ namespace Barotrauma
|
||||
|
||||
GUILayoutGroup bottomLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.66f), mainLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
|
||||
|
||||
GUILayoutGroup bottomTextLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 1f), bottomLayout.RectTransform));
|
||||
GUITextBlock descriptionBlock = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), bottomTextLayout.RectTransform), ToolBox.LimitString(prefab.Description, GUIStyle.Font, GUI.IntScale(64)), wrap: true)
|
||||
GUILayoutGroup bottomTextLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 1f), bottomLayout.RectTransform))
|
||||
{
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
GUITextBlock descriptionBlock = new GUITextBlock(new RectTransform(new Vector2(1f, 0.6f), bottomTextLayout.RectTransform), prefab.Description, font: GUIStyle.SmallFont, wrap: true)
|
||||
{
|
||||
ToolTip = prefab.Description
|
||||
};
|
||||
bool truncated = false;
|
||||
while (descriptionBlock.TextSize.Y > descriptionBlock.Rect.Height && descriptionBlock.WrappedText.Contains('\n'))
|
||||
{
|
||||
var split = descriptionBlock.WrappedText.Value.Split('\n');
|
||||
descriptionBlock.Text = string.Join('\n', split.Take(split.Length - 1));
|
||||
truncated = true;
|
||||
}
|
||||
if (truncated)
|
||||
{
|
||||
descriptionBlock.Text += "...";
|
||||
}
|
||||
|
||||
GUITextBlock priceBlock = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), bottomTextLayout.RectTransform), TextManager.FormatCurrency(affliction.Price), font: GUIStyle.LargeFont);
|
||||
GUITextBlock priceBlock = new GUITextBlock(new RectTransform(new Vector2(1f, 0.25f), bottomTextLayout.RectTransform), TextManager.FormatCurrency(affliction.Price), font: GUIStyle.SubHeadingFont);
|
||||
|
||||
GUIButton buyButton = new GUIButton(new RectTransform(new Vector2(0.2f, 0.75f), bottomLayout.RectTransform), style: "CrewManagementAddButton");
|
||||
|
||||
@@ -923,6 +940,7 @@ namespace Barotrauma
|
||||
});
|
||||
}
|
||||
|
||||
#warning TODO: this doesn't seem like the right place for this, and it's not clear from the method signature how this differs from ToolBox.LimitString
|
||||
public static void EnsureTextDoesntOverflow(string? text, GUITextBlock textBlock, Rectangle bounds, ImmutableArray<GUILayoutGroup>? layoutGroups = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text)) { return; }
|
||||
|
||||
@@ -46,9 +46,7 @@ namespace Barotrauma
|
||||
private int buyTotal, sellTotal, sellFromSubTotal;
|
||||
|
||||
private GUITextBlock storeNameBlock;
|
||||
private GUITextBlock merchantBalanceBlock;
|
||||
private GUITextBlock currentSellValueBlock, newSellValueBlock;
|
||||
private GUIImage sellValueChangeArrow;
|
||||
private GUITextBlock reputationEffectBlock;
|
||||
private GUIDropDown sortingDropDown;
|
||||
private GUITextBox searchBox;
|
||||
private GUILayoutGroup categoryButtonContainer;
|
||||
@@ -376,41 +374,29 @@ namespace Barotrauma
|
||||
AutoScaleVertical = true,
|
||||
ForceUpperCase = ForceUpperCase.Yes
|
||||
};
|
||||
merchantBalanceBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), merchantBalanceContainer.RectTransform),
|
||||
"", font: GUIStyle.SubHeadingFont)
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), merchantBalanceContainer.RectTransform), "",
|
||||
color: Color.White, font: GUIStyle.SubHeadingFont)
|
||||
{
|
||||
AutoScaleVertical = true,
|
||||
TextScale = 1.1f,
|
||||
TextGetter = () =>
|
||||
{
|
||||
merchantBalanceBlock.TextColor = ActiveStore?.BalanceColor ?? Color.Red;
|
||||
return GetMerchantBalanceText();
|
||||
}
|
||||
TextGetter = () => GetMerchantBalanceText()
|
||||
};
|
||||
|
||||
// Item sell value ------------------------------------------------
|
||||
var sellValueContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), balanceAndValueGroup.RectTransform))
|
||||
var reputationEffectContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), balanceAndValueGroup.RectTransform))
|
||||
{
|
||||
CanBeFocused = true,
|
||||
RelativeSpacing = 0.005f
|
||||
RelativeSpacing = 0.005f,
|
||||
ToolTip = TextManager.Get("campaignstore.reputationtooltip")
|
||||
};
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), sellValueContainer.RectTransform),
|
||||
TextManager.Get("campaignstore.sellvalue"), font: GUIStyle.Font, textAlignment: Alignment.BottomLeft)
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), reputationEffectContainer.RectTransform),
|
||||
TextManager.Get("reputation"), font: GUIStyle.Font, textAlignment: Alignment.BottomLeft)
|
||||
{
|
||||
AutoScaleVertical = true,
|
||||
CanBeFocused = false,
|
||||
ForceUpperCase = ForceUpperCase.Yes
|
||||
ForceUpperCase = ForceUpperCase.Yes,
|
||||
};
|
||||
|
||||
var valueChangeGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.5f), sellValueContainer.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
RelativeSpacing = 0.02f
|
||||
};
|
||||
float blockWidth = GUI.IsFourByThree() ? 0.32f : 0.28f;
|
||||
Point blockMaxSize = new Point((int)(GameSettings.CurrentConfig.Graphics.TextScale * 60), valueChangeGroup.Rect.Height);
|
||||
currentSellValueBlock = new GUITextBlock(new RectTransform(new Vector2(blockWidth, 1.0f), valueChangeGroup.RectTransform) { MaxSize = blockMaxSize },
|
||||
"", font: GUIStyle.SubHeadingFont)
|
||||
reputationEffectBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), reputationEffectContainer.RectTransform), "", font: GUIStyle.SubHeadingFont)
|
||||
{
|
||||
AutoScaleVertical = true,
|
||||
CanBeFocused = false,
|
||||
@@ -419,64 +405,27 @@ namespace Barotrauma
|
||||
{
|
||||
if (CurrentLocation != null)
|
||||
{
|
||||
int balanceAfterTransaction = activeTab switch
|
||||
Color textColor = GUIStyle.ColorReputationNeutral;
|
||||
string sign = "";
|
||||
int reputationModifier = (int)MathF.Round((CurrentLocation.GetStoreReputationModifier(activeTab == StoreTab.Buy) - 1) * 100);
|
||||
if (reputationModifier > 0)
|
||||
{
|
||||
StoreTab.Buy => ActiveStore.Balance + buyTotal,
|
||||
StoreTab.Sell => ActiveStore.Balance - sellTotal,
|
||||
StoreTab.SellSub => ActiveStore.Balance - sellFromSubTotal,
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
if (balanceAfterTransaction != ActiveStore.Balance)
|
||||
{
|
||||
var newStatus = CurrentLocation.GetStoreBalanceStatus(balanceAfterTransaction);
|
||||
if (ActiveStore.ActiveBalanceStatus.SellPriceModifier != newStatus.SellPriceModifier)
|
||||
{
|
||||
string tooltipTag = newStatus.SellPriceModifier > ActiveStore.ActiveBalanceStatus.SellPriceModifier ?
|
||||
"campaingstore.valueincreasetooltip" : "campaingstore.valuedecreasetooltip";
|
||||
sellValueContainer.ToolTip = TextManager.Get(tooltipTag);
|
||||
currentSellValueBlock.TextColor = newStatus.Color;
|
||||
sellValueChangeArrow.Color = newStatus.Color;
|
||||
sellValueChangeArrow.Visible = true;
|
||||
newSellValueBlock.TextColor = newStatus.Color;
|
||||
newSellValueBlock.Text = $"{(newStatus.SellPriceModifier * 100).FormatZeroDecimal()} %";
|
||||
return $"{(ActiveStore.ActiveBalanceStatus.SellPriceModifier * 100).FormatZeroDecimal()} %";
|
||||
}
|
||||
textColor = IsBuying ? GUIStyle.ColorReputationLow : GUIStyle.ColorReputationHigh;
|
||||
sign = "+";
|
||||
}
|
||||
sellValueContainer.ToolTip = TextManager.Get("campaignstore.sellvaluetooltip");
|
||||
currentSellValueBlock.TextColor = ActiveStore.BalanceColor;
|
||||
sellValueChangeArrow.Visible = false;
|
||||
newSellValueBlock.Text = null;
|
||||
return $"{(ActiveStore.ActiveBalanceStatus.SellPriceModifier * 100).FormatZeroDecimal()} %";
|
||||
else if (reputationModifier < 0)
|
||||
{
|
||||
textColor = IsBuying ? GUIStyle.ColorReputationHigh : GUIStyle.ColorReputationLow;
|
||||
}
|
||||
reputationEffectBlock.TextColor = textColor;
|
||||
return $"{sign}{reputationModifier}%";
|
||||
}
|
||||
else
|
||||
{
|
||||
sellValueContainer.ToolTip = null;
|
||||
sellValueChangeArrow.Visible = false;
|
||||
newSellValueBlock.Text = null;
|
||||
return null;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
};
|
||||
Vector4 newPadding = currentSellValueBlock.Padding;
|
||||
newPadding.Z = 0;
|
||||
currentSellValueBlock.Padding = newPadding;
|
||||
float relativeHeight = 0.45f;
|
||||
float relativeWidth = (relativeHeight * valueChangeGroup.Rect.Height) / valueChangeGroup.Rect.Width;
|
||||
sellValueChangeArrow = new GUIImage(new RectTransform(new Vector2(relativeWidth, relativeHeight), valueChangeGroup.RectTransform), "StoreArrow", scaleToFit: true)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
Visible = false
|
||||
};
|
||||
newSellValueBlock = new GUITextBlock(new RectTransform(new Vector2(blockWidth, 1.0f), valueChangeGroup.RectTransform) { MaxSize = blockMaxSize },
|
||||
"", font: GUIStyle.SubHeadingFont)
|
||||
{
|
||||
AutoScaleVertical = true,
|
||||
CanBeFocused = false,
|
||||
TextScale = 1.1f
|
||||
};
|
||||
newPadding = newSellValueBlock.Padding;
|
||||
newPadding.X = 0;
|
||||
newSellValueBlock.Padding = newPadding;
|
||||
|
||||
// Store mode buttons ------------------------------------------------
|
||||
var modeButtonFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.4f / 14.0f), storeContent.RectTransform), style: null);
|
||||
|
||||
@@ -626,7 +626,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (GameMain.Client == null)
|
||||
{
|
||||
SubmarineInfo newSub = GameMain.GameSession.SwitchSubmarine(selectedSubmarine, deliveryFee);
|
||||
GameMain.GameSession.SwitchSubmarine(selectedSubmarine, deliveryFee);
|
||||
RefreshSubmarineDisplay(true);
|
||||
}
|
||||
else
|
||||
@@ -664,7 +664,7 @@ namespace Barotrauma
|
||||
if (GameMain.Client == null)
|
||||
{
|
||||
GameMain.GameSession.PurchaseSubmarine(selectedSubmarine);
|
||||
SubmarineInfo newSub = GameMain.GameSession.SwitchSubmarine(selectedSubmarine, 0);
|
||||
GameMain.GameSession.SwitchSubmarine(selectedSubmarine, 0);
|
||||
RefreshSubmarineDisplay(true);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -54,47 +54,65 @@ namespace Barotrauma
|
||||
|
||||
private ushort currentPing;
|
||||
private readonly Character character;
|
||||
private readonly bool hasCharacter;
|
||||
private readonly bool wasCharacterAlive;
|
||||
private readonly GUITextBlock textBlock;
|
||||
private readonly GUIFrame frame;
|
||||
|
||||
private readonly GUIImage permissionIcon;
|
||||
|
||||
public LinkedGUI(Client client, GUIFrame frame, bool hasCharacter, GUITextBlock textBlock, GUIImage permissionIcon)
|
||||
public LinkedGUI(Client client, GUIFrame frame, GUITextBlock textBlock, GUIImage permissionIcon)
|
||||
{
|
||||
this.Client = client;
|
||||
this.textBlock = textBlock;
|
||||
this.frame = frame;
|
||||
this.hasCharacter = hasCharacter;
|
||||
this.permissionIcon = permissionIcon;
|
||||
character = client?.Character;
|
||||
wasCharacterAlive = client.Character != null && !client.Character.IsDead;
|
||||
}
|
||||
|
||||
public LinkedGUI(Character character, GUIFrame frame, bool hasCharacter, GUITextBlock textBlock)
|
||||
public LinkedGUI(Character character, GUIFrame frame, GUITextBlock textBlock)
|
||||
{
|
||||
this.character = character;
|
||||
this.textBlock = textBlock;
|
||||
this.frame = frame;
|
||||
this.hasCharacter = hasCharacter;
|
||||
wasCharacterAlive = character != null && !character.IsDead;
|
||||
}
|
||||
|
||||
public bool HasMultiplayerCharacterChanged()
|
||||
{
|
||||
if (Client == null) { return false; }
|
||||
bool characterState = Client.Character != null;
|
||||
if (characterState && Client.Character.IsDead) characterState = false;
|
||||
return hasCharacter != characterState;
|
||||
|
||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
if (Client.Character != character)
|
||||
{
|
||||
DebugConsole.Log($"Refreshing tab menu crew list (client \"{Client.Name}\"'s character changed from \"{character?.Name ?? "null"}\" to \"{Client.Character?.Name ?? "null"}\")");
|
||||
}
|
||||
}
|
||||
return Client.Character != character;
|
||||
}
|
||||
|
||||
public bool HasMultiplayerCharacterDied()
|
||||
{
|
||||
if (Client == null || !hasCharacter || Client.Character == null) { return false; }
|
||||
return Client.Character.IsDead;
|
||||
}
|
||||
|
||||
public bool HasAICharacterDied()
|
||||
public bool HasCharacterDied()
|
||||
{
|
||||
if (character == null) { return false; }
|
||||
return character.IsDead;
|
||||
bool isAlive = !(character?.IsDead ?? true);
|
||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
if (wasCharacterAlive && !isAlive)
|
||||
{
|
||||
DebugConsole.Log(Client == null ?
|
||||
$"Refreshing tab menu crew list (character \"{character?.Name ?? "null"}\" died)" :
|
||||
$"Refreshing tab menu crew list (client \"{Client.Name}\"'s character \"{character?.Name ?? "null"}\" died)");
|
||||
}
|
||||
else if (!wasCharacterAlive && isAlive)
|
||||
{
|
||||
DebugConsole.Log(Client == null ?
|
||||
|
||||
$"Refreshing tab menu crew list (character \"{character?.Name ?? "null"}\" came back to life)" :
|
||||
$"Refreshing tab menu crew list (client \"{Client.Name}\"'s character \"{character?.Name ?? "null"}\" came back to life)");
|
||||
}
|
||||
}
|
||||
return isAlive != wasCharacterAlive;
|
||||
}
|
||||
|
||||
public void TryPingRefresh()
|
||||
@@ -207,7 +225,7 @@ namespace Barotrauma
|
||||
{
|
||||
linkedGUIList[i].TryPingRefresh();
|
||||
linkedGUIList[i].TryPermissionIconRefresh(GetPermissionIcon(linkedGUIList[i].Client));
|
||||
if (linkedGUIList[i].HasMultiplayerCharacterChanged() || linkedGUIList[i].HasMultiplayerCharacterDied() || linkedGUIList[i].HasAICharacterDied())
|
||||
if (linkedGUIList[i].HasMultiplayerCharacterChanged() || linkedGUIList[i].HasCharacterDied())
|
||||
{
|
||||
RemoveCurrentElements();
|
||||
CreateMultiPlayerList(true);
|
||||
@@ -219,10 +237,11 @@ namespace Barotrauma
|
||||
{
|
||||
for (int i = 0; i < linkedGUIList.Count; i++)
|
||||
{
|
||||
if (linkedGUIList[i].HasAICharacterDied())
|
||||
if (linkedGUIList[i].HasCharacterDied())
|
||||
{
|
||||
RemoveCurrentElements();
|
||||
CreateSinglePlayerList(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -297,6 +316,10 @@ namespace Barotrauma
|
||||
|
||||
var balanceFrame = new GUIFrame(new RectTransform(new Point(innerLayoutGroup.Rect.Width, innerLayoutGroup.Rect.Height - infoFrameHolderHeight), parent: innerLayoutGroup.RectTransform), style: "InnerFrame");
|
||||
GUITextBlock balanceText = new GUITextBlock(new RectTransform(Vector2.One, balanceFrame.RectTransform), string.Empty, textAlignment: Alignment.Right);
|
||||
if (GameMain.IsMultiplayer)
|
||||
{
|
||||
balanceText.ToolTip = TextManager.Get("bankdescription");
|
||||
}
|
||||
GUIFrame bottomDisclaimerFrame = new GUIFrame(new RectTransform(new Vector2(contentFrameSize.X, 0.1f), infoFrame.RectTransform)
|
||||
{
|
||||
AbsoluteOffset = new Point(contentFrame.Rect.X, contentFrame.Rect.Bottom + GUI.IntScale(8))
|
||||
@@ -337,7 +360,7 @@ namespace Barotrauma
|
||||
var talentsButton = createTabButton(InfoFrameTab.Talents, "tabmenu.character");
|
||||
talentsButton.OnAddedToGUIUpdateList += (component) =>
|
||||
{
|
||||
talentsButton.Enabled = Character.Controlled?.Info != null;
|
||||
talentsButton.Enabled = Character.Controlled?.Info != null || (GameMain.Client?.CharacterInfo != null && GameMain.GameSession?.GameMode is MultiPlayerCampaign);
|
||||
if (!talentsButton.Enabled && selectedTab == InfoFrameTab.Talents)
|
||||
{
|
||||
SelectInfoFrameTab(InfoFrameTab.Crew);
|
||||
@@ -560,7 +583,7 @@ namespace Barotrauma
|
||||
GUITextBlock characterNameBlock = new GUITextBlock(new RectTransform(new Point(characterColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform),
|
||||
ToolBox.LimitString(character.Info.Name, GUIStyle.Font, characterColumnWidth), textAlignment: Alignment.Center, textColor: character.Info.Job.Prefab.UIColor);
|
||||
|
||||
linkedGUIList.Add(new LinkedGUI(character, frame, !character.IsDead, textBlock: null));
|
||||
linkedGUIList.Add(new LinkedGUI(character, frame, textBlock: null));
|
||||
}
|
||||
|
||||
private void CreateMultiPlayerListContentHolder(GUILayoutGroup headerFrame)
|
||||
@@ -657,7 +680,7 @@ namespace Barotrauma
|
||||
if (client != null)
|
||||
{
|
||||
CreateNameWithPermissionIcon(client, paddedFrame, out GUIImage permissionIcon);
|
||||
linkedGUIList.Add(new LinkedGUI(client, frame, true,
|
||||
linkedGUIList.Add(new LinkedGUI(client, frame,
|
||||
new GUITextBlock(new RectTransform(new Point(pingColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform), client.Ping.ToString(), textAlignment: Alignment.Center),
|
||||
permissionIcon));
|
||||
}
|
||||
@@ -668,12 +691,12 @@ namespace Barotrauma
|
||||
|
||||
if (character is AICharacter)
|
||||
{
|
||||
linkedGUIList.Add(new LinkedGUI(character, frame, !character.IsDead,
|
||||
linkedGUIList.Add(new LinkedGUI(character, frame,
|
||||
new GUITextBlock(new RectTransform(new Point(pingColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform), TextManager.Get("tabmenu.bot"), textAlignment: Alignment.Center) { ForceUpperCase = ForceUpperCase.Yes }));
|
||||
}
|
||||
else
|
||||
{
|
||||
linkedGUIList.Add(new LinkedGUI(client: null, frame, true, textBlock: null, permissionIcon: null));
|
||||
linkedGUIList.Add(new LinkedGUI(client: null, frame, textBlock: null, permissionIcon: null));
|
||||
|
||||
new GUICustomComponent(new RectTransform(new Point(pingColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform, Anchor.Center), onDraw: (sb, component) => DrawDisconnectedIcon(sb, component.Rect))
|
||||
{
|
||||
@@ -718,7 +741,7 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
CreateNameWithPermissionIcon(client, paddedFrame, out GUIImage permissionIcon);
|
||||
linkedGUIList.Add(new LinkedGUI(client, frame, false,
|
||||
linkedGUIList.Add(new LinkedGUI(client, frame,
|
||||
new GUITextBlock(new RectTransform(new Point(pingColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform), client.Ping.ToString(), textAlignment: Alignment.Center),
|
||||
permissionIcon));
|
||||
|
||||
@@ -775,19 +798,27 @@ namespace Barotrauma
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
new GUIFrame(new RectTransform(Vector2.One, paddedLayoutGroup.RectTransform), style: null)
|
||||
{
|
||||
IgnoreLayoutGroups = true,
|
||||
ToolTip = TextManager.Get("walletdescription")
|
||||
};
|
||||
|
||||
if (character.IsBot) { return; }
|
||||
|
||||
Sprite walletSprite = GUIStyle.CrewWalletIconSmall.Value.Sprite;
|
||||
|
||||
GUIImage icon = new GUIImage(new RectTransform(Vector2.One, paddedLayoutGroup.RectTransform, scaleBasis: ScaleBasis.BothHeight), walletSprite, scaleToFit: true);
|
||||
GUIImage icon = new GUIImage(new RectTransform(Vector2.One, paddedLayoutGroup.RectTransform, scaleBasis: ScaleBasis.BothHeight), walletSprite, scaleToFit: true) { CanBeFocused = false };
|
||||
GUITextBlock walletBlock = new GUITextBlock(new RectTransform(Vector2.One, paddedLayoutGroup.RectTransform), string.Empty, textAlignment: Alignment.Right, font: GUIStyle.Font)
|
||||
{
|
||||
AutoScaleHorizontal = true,
|
||||
Padding = Vector4.Zero
|
||||
Padding = Vector4.Zero,
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
GUIImage largeIcon = new GUIImage(new RectTransform(Vector2.One, paddedLayoutGroup.RectTransform), walletSprite, scaleToFit: true)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
IgnoreLayoutGroups = true,
|
||||
Visible = false
|
||||
};
|
||||
@@ -971,16 +1002,25 @@ namespace Barotrauma
|
||||
float relativeX = icon.RectTransform.NonScaledSize.X / (float)icon.Parent.RectTransform.NonScaledSize.X;
|
||||
GUILayoutGroup headerTextLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f - relativeX, 1f), headerLayout.RectTransform), isHorizontal: true) { Stretch = true };
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), headerTextLayout.RectTransform), TextManager.Get("crewwallet.wallet"), font: GUIStyle.LargeFont);
|
||||
GUIFrame walletTooltipFrame = new GUIFrame(new RectTransform(Vector2.One, headerLayout.RectTransform), style: null)
|
||||
{
|
||||
IgnoreLayoutGroups = true,
|
||||
ToolTip = TextManager.Get("walletdescription")
|
||||
};
|
||||
GUITextBlock moneyBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), headerTextLayout.RectTransform), TextManager.FormatCurrency(targetWallet.Balance), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Right);
|
||||
|
||||
GUILayoutGroup middleLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.66f), walletLayout.RectTransform));
|
||||
GUILayoutGroup salaryTextLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), middleLayout.RectTransform), isHorizontal: true);
|
||||
GUITextBlock salaryTitle = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), salaryTextLayout.RectTransform), TextManager.Get("crewwallet.salary"), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.BottomLeft);
|
||||
GUITextBlock rewardBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), salaryTextLayout.RectTransform), string.Empty, textAlignment: Alignment.BottomRight);
|
||||
GUIFrame salaryTooltipFrame = new GUIFrame(new RectTransform(Vector2.One, middleLayout.RectTransform), style: null)
|
||||
{
|
||||
IgnoreLayoutGroups = true,
|
||||
ToolTip = TextManager.Get("crewwallet.salary.tooltip")
|
||||
};
|
||||
GUILayoutGroup sliderLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), middleLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.Center);
|
||||
GUIScrollBar salarySlider = new GUIScrollBar(new RectTransform(new Vector2(0.9f, 1f), sliderLayout.RectTransform), style: "GUISlider", barSize: 0.03f)
|
||||
{
|
||||
ToolTip = TextManager.Get("crewwallet.salary.tooltip"),
|
||||
Range = new Vector2(0, 1),
|
||||
BarScrollValue = targetWallet.RewardDistribution / 100f,
|
||||
Step = 0.01f,
|
||||
@@ -1050,149 +1090,195 @@ namespace Barotrauma
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
Identifier eventIdentifier = nameof(CreateWalletFrame).ToIdentifier();
|
||||
|
||||
ToggleTransferMenuIcon(transferMenuButton, open: isTransferMenuOpen);
|
||||
ToggleCenterButton(centerButton, isSending);
|
||||
|
||||
|
||||
if (!(Character.Controlled is { } myCharacter))
|
||||
{
|
||||
salarySlider.Enabled = false;
|
||||
transferAmountInput.Enabled = false;
|
||||
centerButton.Enabled = false;
|
||||
confirmButton.Enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
bool hasMoneyPermissions = CampaignMode.AllowedToManageWallets();
|
||||
salarySlider.Enabled = hasMoneyPermissions;
|
||||
Wallet otherWallet;
|
||||
GameMain.Client?.OnPermissionChanged.RegisterOverwriteExisting(eventIdentifier, e => UpdateWalletInterface(registerEvents: false));
|
||||
UpdateWalletInterface(registerEvents: true);
|
||||
|
||||
switch (hasMoneyPermissions)
|
||||
void UpdateWalletInterface(bool registerEvents)
|
||||
{
|
||||
case true:
|
||||
rightName.Text = TextManager.Get("crewwallet.bank");
|
||||
otherWallet = campaign.Bank;
|
||||
break;
|
||||
case false when character == myCharacter:
|
||||
rightName.Text = TextManager.Get("crewwallet.bank");
|
||||
otherWallet = campaign.Bank;
|
||||
isSending = true;
|
||||
ToggleCenterButton(centerButton, isSending);
|
||||
break;
|
||||
default:
|
||||
rightName.Text = myCharacter.Name;
|
||||
otherWallet = campaign.PersonalWallet;
|
||||
break;
|
||||
}
|
||||
|
||||
MedicalClinicUI.EnsureTextDoesntOverflow(rightName.Text.ToString(), rightName, rightLayout.Rect, layoutGroups);
|
||||
updateButtonText();
|
||||
if (!hasMoneyPermissions)
|
||||
{
|
||||
if (character != Character.Controlled)
|
||||
if (!(Character.Controlled is { } myCharacter))
|
||||
{
|
||||
centerButton.Enabled = centerButton.CanBeFocused = false;
|
||||
salarySlider.Enabled = false;
|
||||
transferAmountInput.Enabled = false;
|
||||
centerButton.Enabled = false;
|
||||
confirmButton.Enabled = false;
|
||||
return;
|
||||
}
|
||||
salarySlider.Enabled = salarySlider.CanBeFocused = false;
|
||||
}
|
||||
|
||||
leftBalance.Text = TextManager.FormatCurrency(otherWallet.Balance);
|
||||
bool hasMoneyPermissions = CampaignMode.AllowedToManageWallets();
|
||||
salarySlider.Enabled = hasMoneyPermissions;
|
||||
|
||||
UpdateAllInputs();
|
||||
switch (hasMoneyPermissions)
|
||||
{
|
||||
case true:
|
||||
rightName.Text = TextManager.Get("crewwallet.bank");
|
||||
otherWallet = campaign.Bank;
|
||||
break;
|
||||
case false when character == myCharacter:
|
||||
rightName.Text = TextManager.Get("crewwallet.bank");
|
||||
otherWallet = campaign.Bank;
|
||||
isSending = true;
|
||||
ToggleCenterButton(centerButton, isSending);
|
||||
break;
|
||||
default:
|
||||
rightName.Text = myCharacter.Name;
|
||||
otherWallet = campaign.PersonalWallet;
|
||||
break;
|
||||
}
|
||||
|
||||
MedicalClinicUI.EnsureTextDoesntOverflow(rightName.Text.ToString(), rightName, rightLayout.Rect, layoutGroups);
|
||||
|
||||
UpdatedConfirmButtonText();
|
||||
|
||||
if (!hasMoneyPermissions)
|
||||
{
|
||||
if (character != Character.Controlled)
|
||||
{
|
||||
centerButton.Enabled = centerButton.CanBeFocused = false;
|
||||
}
|
||||
|
||||
salarySlider.Enabled = salarySlider.CanBeFocused = false;
|
||||
}
|
||||
|
||||
leftBalance.Text = TextManager.FormatCurrency(otherWallet.Balance);
|
||||
|
||||
centerButton.OnClicked = (btn, o) =>
|
||||
{
|
||||
isSending = !isSending;
|
||||
updateButtonText();
|
||||
ToggleCenterButton(btn, isSending);
|
||||
UpdateAllInputs();
|
||||
return true;
|
||||
};
|
||||
|
||||
void updateButtonText()
|
||||
{
|
||||
confirmButton.Text = TextManager.Get(hasMoneyPermissions || isSending ? "confirm" : "crewwallet.requestmoney");
|
||||
}
|
||||
if (!registerEvents) { return; }
|
||||
|
||||
transferAmountInput.OnValueChanged = input =>
|
||||
{
|
||||
UpdateInputs();
|
||||
};
|
||||
|
||||
transferAmountInput.OnValueEntered = input =>
|
||||
{
|
||||
UpdateAllInputs();
|
||||
};
|
||||
|
||||
Identifier eventIdentifier = nameof(CreateWalletFrame).ToIdentifier();
|
||||
campaign.OnMoneyChanged.RegisterOverwriteExisting(eventIdentifier, e =>
|
||||
{
|
||||
if (e.Wallet == targetWallet)
|
||||
centerButton.OnClicked = (btn, o) =>
|
||||
{
|
||||
moneyBlock.Text = TextManager.FormatCurrency(e.Info.Balance);
|
||||
salarySlider.BarScrollValue = e.Info.RewardDistribution / 100f;
|
||||
isSending = !isSending;
|
||||
UpdatedConfirmButtonText();
|
||||
ToggleCenterButton(btn, isSending);
|
||||
UpdateAllInputs();
|
||||
return true;
|
||||
};
|
||||
|
||||
transferAmountInput.OnValueChanged = input =>
|
||||
{
|
||||
UpdateInputs();
|
||||
};
|
||||
|
||||
transferAmountInput.OnValueEntered = input =>
|
||||
{
|
||||
UpdateAllInputs();
|
||||
};
|
||||
|
||||
resetButton.OnClicked = (button, o) =>
|
||||
{
|
||||
transferAmountInput.IntValue = 0;
|
||||
UpdateAllInputs();
|
||||
return true;
|
||||
};
|
||||
|
||||
confirmButton.OnClicked = (button, o) =>
|
||||
{
|
||||
int amount = transferAmountInput.IntValue;
|
||||
if (amount == 0) { return false; }
|
||||
|
||||
Option<Character> target1 = Option<Character>.Some(character),
|
||||
target2 = otherWallet == campaign.Bank ? Option<Character>.None() : Option<Character>.Some(myCharacter);
|
||||
if (isSending) { (target1, target2) = (target2, target1); }
|
||||
|
||||
SendTransaction(target1, target2, amount);
|
||||
isTransferMenuOpen = false;
|
||||
ToggleTransferMenuIcon(transferMenuButton, isTransferMenuOpen);
|
||||
return true;
|
||||
};
|
||||
|
||||
campaign.OnMoneyChanged.RegisterOverwriteExisting(eventIdentifier, e =>
|
||||
{
|
||||
if (e.Wallet == targetWallet)
|
||||
{
|
||||
moneyBlock.Text = TextManager.FormatCurrency(e.Info.Balance);
|
||||
salarySlider.BarScrollValue = e.Info.RewardDistribution / 100f;
|
||||
}
|
||||
|
||||
UpdateAllInputs();
|
||||
});
|
||||
|
||||
registeredEvents.Add(eventIdentifier);
|
||||
|
||||
void UpdatedConfirmButtonText()
|
||||
{
|
||||
confirmButton.Text = TextManager.Get(hasMoneyPermissions || isSending ? "confirm" : "crewwallet.requestmoney");
|
||||
}
|
||||
UpdateAllInputs();
|
||||
});
|
||||
registeredEvents.Add(eventIdentifier);
|
||||
|
||||
resetButton.OnClicked = (button, o) =>
|
||||
{
|
||||
transferAmountInput.IntValue = 0;
|
||||
UpdateAllInputs();
|
||||
return true;
|
||||
};
|
||||
|
||||
confirmButton.OnClicked = (button, o) =>
|
||||
{
|
||||
int amount = transferAmountInput.IntValue;
|
||||
if (amount == 0) { return false; }
|
||||
|
||||
Option<Character> target1 = Option<Character>.Some(character),
|
||||
target2 = otherWallet == campaign.Bank ? Option<Character>.None() : Option<Character>.Some(myCharacter);
|
||||
if (isSending) { (target1, target2) = (target2, target1); }
|
||||
|
||||
SendTransaction(target1, target2, amount);
|
||||
isTransferMenuOpen = false;
|
||||
ToggleTransferMenuIcon(transferMenuButton, isTransferMenuOpen);
|
||||
return true;
|
||||
};
|
||||
|
||||
void UpdateAllInputs()
|
||||
{
|
||||
UpdateInputs();
|
||||
UpdateMaxInput();
|
||||
}
|
||||
|
||||
void UpdateInputs()
|
||||
{
|
||||
confirmButton.Enabled = resetButton.Enabled = transferAmountInput.IntValue > 0;
|
||||
if (transferAmountInput.IntValue == 0)
|
||||
void UpdateAllInputs()
|
||||
{
|
||||
rightBalance.Text = TextManager.FormatCurrency(otherWallet.Balance);
|
||||
rightBalance.TextColor = GUIStyle.TextColorNormal;
|
||||
leftBalance.Text = TextManager.FormatCurrency(targetWallet.Balance);
|
||||
leftBalance.TextColor = GUIStyle.TextColorNormal;
|
||||
UpdateInputs();
|
||||
UpdateMaxInput();
|
||||
}
|
||||
else if (isSending)
|
||||
|
||||
void UpdateInputs()
|
||||
{
|
||||
rightBalance.Text = TextManager.FormatCurrency(otherWallet.Balance + transferAmountInput.IntValue);
|
||||
rightBalance.TextColor = GUIStyle.Blue;
|
||||
leftBalance.Text = TextManager.FormatCurrency(targetWallet.Balance - transferAmountInput.IntValue);
|
||||
leftBalance.TextColor = GUIStyle.Red;
|
||||
confirmButton.Enabled = resetButton.Enabled = transferAmountInput.IntValue > 0;
|
||||
if (transferAmountInput.IntValue == 0)
|
||||
{
|
||||
rightBalance.Text = TextManager.FormatCurrency(otherWallet.Balance);
|
||||
rightBalance.TextColor = GUIStyle.TextColorNormal;
|
||||
leftBalance.Text = TextManager.FormatCurrency(targetWallet.Balance);
|
||||
leftBalance.TextColor = GUIStyle.TextColorNormal;
|
||||
}
|
||||
else if (isSending)
|
||||
{
|
||||
rightBalance.Text = TextManager.FormatCurrency(otherWallet.Balance + transferAmountInput.IntValue);
|
||||
rightBalance.TextColor = GUIStyle.Blue;
|
||||
leftBalance.Text = TextManager.FormatCurrency(targetWallet.Balance - transferAmountInput.IntValue);
|
||||
leftBalance.TextColor = GUIStyle.Red;
|
||||
}
|
||||
else
|
||||
{
|
||||
rightBalance.Text = TextManager.FormatCurrency(otherWallet.Balance - transferAmountInput.IntValue);
|
||||
rightBalance.TextColor = GUIStyle.Red;
|
||||
leftBalance.Text = TextManager.FormatCurrency(targetWallet.Balance + transferAmountInput.IntValue);
|
||||
leftBalance.TextColor = GUIStyle.Blue;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
void UpdateMaxInput()
|
||||
{
|
||||
rightBalance.Text = TextManager.FormatCurrency(otherWallet.Balance - transferAmountInput.IntValue);
|
||||
rightBalance.TextColor = GUIStyle.Red;
|
||||
leftBalance.Text = TextManager.FormatCurrency(targetWallet.Balance + transferAmountInput.IntValue);
|
||||
leftBalance.TextColor = GUIStyle.Blue;
|
||||
int maxValue = isSending ? targetWallet.Balance : otherWallet.Balance;
|
||||
transferAmountInput.MaxValueInt = maxValue;
|
||||
|
||||
transferAmountInput.Enabled = true;
|
||||
transferAmountInput.ToolTip = string.Empty;
|
||||
|
||||
if (!hasMoneyPermissions && GameMain.Client?.ServerSettings is { } serverSettings)
|
||||
{
|
||||
transferAmountInput.MaxValueInt = Math.Min(maxValue, serverSettings.MaximumTransferRequest);
|
||||
if (serverSettings.MaximumTransferRequest <= 0)
|
||||
{
|
||||
transferAmountInput.Enabled = false;
|
||||
transferAmountInput.ToolTip = TextManager.Get("wallettransferrequestdisabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateMaxInput()
|
||||
void SetRewardText(int value, GUITextBlock block)
|
||||
{
|
||||
transferAmountInput.MaxValueInt = isSending ? targetWallet.Balance : otherWallet.Balance;
|
||||
var (_, percentage, sum) = Mission.GetRewardShare(value, salaryCrew, Option<int>.None());
|
||||
LocalizedString tooltip = string.Empty;
|
||||
block.TextColor = GUIStyle.TextColorNormal;
|
||||
|
||||
if (sum > 100)
|
||||
{
|
||||
tooltip = TextManager.GetWithVariables("crewwallet.salary.over100toolitp", ("[sum]", $"{(int)sum}"), ("[newvalue]", $"{percentage}"));
|
||||
block.TextColor = GUIStyle.Orange;
|
||||
}
|
||||
|
||||
LocalizedString text = TextManager.GetWithVariable("percentageformat", "[value]", $"{value}");
|
||||
|
||||
block.Text = text;
|
||||
block.ToolTip = RichString.Rich(tooltip);
|
||||
}
|
||||
|
||||
static void ToggleTransferMenuIcon(GUIButton btn, bool open)
|
||||
@@ -1235,24 +1321,6 @@ namespace Barotrauma
|
||||
transfer.Write(msg);
|
||||
GameMain.Client?.ClientPeer?.Send(msg, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
void SetRewardText(int value, GUITextBlock block)
|
||||
{
|
||||
var (_, percentage, sum) = Mission.GetRewardShare(value, salaryCrew, Option<int>.None());
|
||||
LocalizedString tooltip = string.Empty;
|
||||
block.TextColor = GUIStyle.TextColorNormal;
|
||||
|
||||
if (sum > 100)
|
||||
{
|
||||
tooltip = TextManager.GetWithVariables("crewwallet.salary.over100toolitp", ("[sum]", $"{(int)sum}"), ("[newvalue]", $"{percentage}"));
|
||||
block.TextColor = GUIStyle.Orange;
|
||||
}
|
||||
|
||||
LocalizedString text = TextManager.GetWithVariable("percentageformat", "[value]", $"{value}");
|
||||
|
||||
block.Text = text;
|
||||
block.ToolTip = RichString.Rich(tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
private GUIComponent CreateClientInfoFrame(GUIFrame frame, Client client, Sprite permissionIcon = null)
|
||||
@@ -1740,9 +1808,6 @@ namespace Barotrauma
|
||||
talentButtons.Clear();
|
||||
talentCornerIcons.Clear();
|
||||
|
||||
Character controlledCharacter = Character.Controlled;
|
||||
if (controlledCharacter == null) { return; }
|
||||
|
||||
GUIFrame talentFrameBackground = new GUIFrame(new RectTransform(Vector2.One, infoFrame.RectTransform, Anchor.TopCenter), style: "GUIFrameListBox");
|
||||
int padding = GUI.IntScale(15);
|
||||
GUIFrame talentFrameContent = new GUIFrame(new RectTransform(new Point(talentFrameBackground.Rect.Width - padding, talentFrameBackground.Rect.Height - padding), infoFrame.RectTransform, Anchor.Center), style: null);
|
||||
@@ -1762,13 +1827,20 @@ namespace Barotrauma
|
||||
GameMain.NetLobbyScreen.CreatePlayerFrame(playerFrame, alwaysAllowEditing: true, createPendingText: false);
|
||||
}
|
||||
|
||||
/*Character controlledCharacter = Character.Controlled;
|
||||
if (controlledCharacter == null) { return; }
|
||||
|
||||
if (controlledCharacter.Info is null)
|
||||
{
|
||||
DebugConsole.ThrowError("No character info found for talent UI");
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
|
||||
selectedTalents = controlledCharacter.Info.GetUnlockedTalentsInTree().ToList();
|
||||
Character controlledCharacter = Character.Controlled;
|
||||
CharacterInfo info = controlledCharacter?.Info ?? GameMain.Client?.CharacterInfo;
|
||||
if (info == null) { return; }
|
||||
|
||||
Job job = info.Job;
|
||||
|
||||
GUILayoutGroup talentFrameLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), talentFrameMain.RectTransform, anchor: Anchor.Center), childAnchor: Anchor.TopCenter)
|
||||
{
|
||||
@@ -1776,9 +1848,7 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
GUILayoutGroup talentInfoLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.25f), talentFrameLayoutGroup.RectTransform, Anchor.Center), isHorizontal: true);
|
||||
|
||||
CharacterInfo info = controlledCharacter.Info;
|
||||
Job job = info.Job;
|
||||
|
||||
|
||||
new GUICustomComponent(new RectTransform(new Vector2(0.25f, 1f), talentInfoLayoutGroup.RectTransform), onDraw: (batch, component) =>
|
||||
{
|
||||
@@ -1801,11 +1871,11 @@ namespace Barotrauma
|
||||
GUITextBlock traitBlock = new GUITextBlock(new RectTransform(Vector2.One, nameLayout.RectTransform), traitString, font: GUIStyle.SmallFont);
|
||||
traitBlock.RectTransform.NonScaledSize = traitSize.Pad(traitBlock.Padding).ToPoint();
|
||||
|
||||
GUIFrame endocrineFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.35f), nameLayout.RectTransform, Anchor.BottomCenter), style: null);
|
||||
GUIFrame talentsOutsideTreeFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.35f), nameLayout.RectTransform, Anchor.BottomCenter), style: null);
|
||||
|
||||
if (!(GameMain.NetworkMember is null))
|
||||
{
|
||||
GUIButton newCharacterBox = new GUIButton(new RectTransform(new Vector2(0.675f, 1f), endocrineFrame.RectTransform, Anchor.TopLeft), text: GameMain.NetLobbyScreen.CampaignCharacterDiscarded ? TextManager.Get("settings") : TextManager.Get("createnew"))
|
||||
GUIButton newCharacterBox = new GUIButton(new RectTransform(new Vector2(0.675f, 1f), talentsOutsideTreeFrame.RectTransform, Anchor.TopLeft), text: GameMain.NetLobbyScreen.CampaignCharacterDiscarded ? TextManager.Get("settings") : TextManager.Get("createnew"))
|
||||
{
|
||||
IgnoreLayoutGroups = true
|
||||
};
|
||||
@@ -1852,13 +1922,14 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<TalentPrefab> endocrineTalents = info.GetEndocrineTalents().Select(e => TalentPrefab.TalentPrefabs.Find(c => c.Identifier == e));
|
||||
IEnumerable<TalentPrefab> talentsOutsideTree = info.GetUnlockedTalentsOutsideTree().Select(e => TalentPrefab.TalentPrefabs.Find(c => c.Identifier == e));
|
||||
|
||||
if (endocrineTalents.Count() > 0)
|
||||
if (talentsOutsideTree.Count() > 0)
|
||||
{
|
||||
GUIImage endocrineIcon = new GUIImage(new RectTransform(new Vector2(0.275f, 1f), endocrineFrame.RectTransform, anchor: Anchor.TopRight, scaleBasis: ScaleBasis.Normal), style: "EndocrineReminderIcon")
|
||||
//TODO: replace with something more generic
|
||||
GUIImage endocrineIcon = new GUIImage(new RectTransform(new Vector2(0.275f, 1f), talentsOutsideTreeFrame.RectTransform, anchor: Anchor.TopRight, scaleBasis: ScaleBasis.Normal), style: "EndocrineReminderIcon")
|
||||
{
|
||||
ToolTip = $"{TextManager.Get("afflictionname.endocrineboost")}\n\n{string.Join(", ", endocrineTalents.Select(e => e.DisplayName))}"
|
||||
ToolTip = $"{TextManager.Get("afflictionname.endocrineboost")}\n\n{string.Join(", ", talentsOutsideTree.Select(e => e.DisplayName))}"
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1870,49 +1941,55 @@ namespace Barotrauma
|
||||
skillBlock.RectTransform.NonScaledSize = skillSize.Pad(skillBlock.Padding).ToPoint();
|
||||
|
||||
skillListBox = new GUIListBox(new RectTransform(new Vector2(1f, 1f - skillBlock.RectTransform.RelativeSize.Y), skillLayout.RectTransform), style: null);
|
||||
CreateTalentSkillList(controlledCharacter, skillListBox);
|
||||
CreateTalentSkillList(controlledCharacter, info, skillListBox);
|
||||
|
||||
if (!TalentTree.JobTalentTrees.TryGet(controlledCharacter.Info.Job.Prefab.Identifier, out TalentTree talentTree)) { return; }
|
||||
|
||||
new GUIFrame(new RectTransform(new Vector2(1f, 1f), talentFrameLayoutGroup.RectTransform), style: "HorizontalLine");
|
||||
|
||||
GUIListBox talentTreeListBox = new GUIListBox(new RectTransform(new Vector2(1f, 0.7f), talentFrameLayoutGroup.RectTransform, Anchor.TopCenter), isHorizontal: true, style: null);
|
||||
|
||||
List<GUITextBlock> subTreeNames = new List<GUITextBlock>();
|
||||
foreach (var subTree in talentTree.TalentSubTrees)
|
||||
if (controlledCharacter != null)
|
||||
{
|
||||
GUIFrame subTreeFrame = new GUIFrame(new RectTransform(new Vector2(0.333f, 1f), talentTreeListBox.Content.RectTransform, anchor: Anchor.TopLeft), style: null);
|
||||
GUILayoutGroup subTreeLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(1f, 1f), subTreeFrame.RectTransform, Anchor.Center), false, childAnchor: Anchor.TopCenter);
|
||||
if (!TalentTree.JobTalentTrees.TryGet(info.Job.Prefab.Identifier, out TalentTree talentTree)) { return; }
|
||||
|
||||
GUIFrame subtreeTitleFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.111f), subTreeLayoutGroup.RectTransform, anchor: Anchor.TopCenter), style: null);
|
||||
int elementPadding = GUI.IntScale(8);
|
||||
Point headerSize = subtreeTitleFrame.RectTransform.NonScaledSize;
|
||||
GUIFrame subTreeTitleBackground = new GUIFrame(new RectTransform(new Point(headerSize.X - elementPadding, headerSize.Y), subtreeTitleFrame.RectTransform, anchor: Anchor.Center), style: "SubtreeHeader");
|
||||
subTreeNames.Add(new GUITextBlock(new RectTransform(Vector2.One, subTreeTitleBackground.RectTransform, anchor: Anchor.TopCenter), subTree.DisplayName, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Center));
|
||||
new GUIFrame(new RectTransform(new Vector2(1f, 1f), talentFrameLayoutGroup.RectTransform), style: "HorizontalLine");
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
GUIListBox talentTreeListBox = new GUIListBox(new RectTransform(new Vector2(1f, 0.7f), talentFrameLayoutGroup.RectTransform, Anchor.TopCenter), isHorizontal: true, style: null);
|
||||
|
||||
selectedTalents = info.GetUnlockedTalentsInTree().ToList();
|
||||
|
||||
List<GUITextBlock> subTreeNames = new List<GUITextBlock>();
|
||||
foreach (var subTree in talentTree.TalentSubTrees)
|
||||
{
|
||||
GUIFrame talentOptionFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.222f), subTreeLayoutGroup.RectTransform, anchor: Anchor.TopCenter), style: null);
|
||||
GUIFrame subTreeFrame = new GUIFrame(new RectTransform(new Vector2(0.333f, 1f), talentTreeListBox.Content.RectTransform, anchor: Anchor.TopLeft), style: null);
|
||||
GUILayoutGroup subTreeLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(1f, 1f), subTreeFrame.RectTransform, Anchor.Center), false, childAnchor: Anchor.TopCenter);
|
||||
|
||||
Point talentFrameSize = talentOptionFrame.RectTransform.NonScaledSize;
|
||||
GUIFrame subtreeTitleFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.111f), subTreeLayoutGroup.RectTransform, anchor: Anchor.TopCenter), style: null);
|
||||
int elementPadding = GUI.IntScale(8);
|
||||
Point headerSize = subtreeTitleFrame.RectTransform.NonScaledSize;
|
||||
GUIFrame subTreeTitleBackground = new GUIFrame(new RectTransform(new Point(headerSize.X - elementPadding, headerSize.Y), subtreeTitleFrame.RectTransform, anchor: Anchor.Center), style: "SubtreeHeader");
|
||||
subTreeNames.Add(new GUITextBlock(new RectTransform(Vector2.One, subTreeTitleBackground.RectTransform, anchor: Anchor.TopCenter), subTree.DisplayName, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Center));
|
||||
|
||||
GUIFrame talentBackground = new GUIFrame(new RectTransform(new Point(talentFrameSize.X - elementPadding, talentFrameSize.Y - elementPadding), talentOptionFrame.RectTransform, anchor: Anchor.Center), style: "TalentBackground");
|
||||
GUIFrame talentBackgroundHighlight = new GUIFrame(new RectTransform(Vector2.One, talentBackground.RectTransform, anchor: Anchor.Center), style: "TalentBackgroundGlow") { Visible = false };
|
||||
|
||||
GUIImage cornerIcon = new GUIImage(new RectTransform(new Vector2(0.2f), talentOptionFrame.RectTransform, anchor: Anchor.BottomRight, scaleBasis: ScaleBasis.BothHeight) { MaxSize = new Point(16) }, style: null)
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
GUIFrame talentOptionFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.222f), subTreeLayoutGroup.RectTransform, anchor: Anchor.TopCenter), style: null);
|
||||
|
||||
Point iconSize = cornerIcon.RectTransform.NonScaledSize;
|
||||
cornerIcon.RectTransform.AbsoluteOffset = new Point(iconSize.X / 2, iconSize.Y / 2);
|
||||
Point talentFrameSize = talentOptionFrame.RectTransform.NonScaledSize;
|
||||
|
||||
GUIFrame talentBackground = new GUIFrame(new RectTransform(new Point(talentFrameSize.X - elementPadding, talentFrameSize.Y - elementPadding), talentOptionFrame.RectTransform, anchor: Anchor.Center), style: "TalentBackground")
|
||||
{
|
||||
Color = talentStageBackgroundColors[TalentTree.TalentTreeStageState.Locked]
|
||||
};
|
||||
GUIFrame talentBackgroundHighlight = new GUIFrame(new RectTransform(Vector2.One, talentBackground.RectTransform, anchor: Anchor.Center), style: "TalentBackgroundGlow") { Visible = false };
|
||||
|
||||
GUIImage cornerIcon = new GUIImage(new RectTransform(new Vector2(0.2f), talentOptionFrame.RectTransform, anchor: Anchor.BottomRight, scaleBasis: ScaleBasis.BothHeight) { MaxSize = new Point(16) }, style: null)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
Color = talentStageBackgroundColors[TalentTree.TalentTreeStageState.Locked]
|
||||
};
|
||||
|
||||
Point iconSize = cornerIcon.RectTransform.NonScaledSize;
|
||||
cornerIcon.RectTransform.AbsoluteOffset = new Point(iconSize.X / 2, iconSize.Y / 2);
|
||||
|
||||
if (subTree.TalentOptionStages.Count <= i) { continue; }
|
||||
|
||||
if (subTree.TalentOptionStages.Count > i)
|
||||
{
|
||||
TalentOption talentOption = subTree.TalentOptionStages[i];
|
||||
|
||||
GUILayoutGroup talentOptionCenterGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.75f, 0.7f), talentOptionFrame.RectTransform, Anchor.Center), childAnchor: Anchor.CenterLeft);
|
||||
|
||||
GUILayoutGroup talentOptionLayoutGroup = new GUILayoutGroup(new RectTransform(Vector2.One, talentOptionCenterGroup.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft) { Stretch = true };
|
||||
|
||||
foreach (TalentPrefab talent in talentOption.Talents.OrderBy(t => t.Identifier))
|
||||
@@ -1929,6 +2006,7 @@ namespace Barotrauma
|
||||
ToolTip = RichString.Rich(talent.DisplayName + "\n\n" + talent.Description),
|
||||
UserData = talent.Identifier,
|
||||
PressedColor = pressedColor,
|
||||
Enabled = controlledCharacter != null,
|
||||
OnClicked = (button, userData) =>
|
||||
{
|
||||
// deselect other buttons in tier by removing their selected talents from pool
|
||||
@@ -1961,7 +2039,7 @@ namespace Barotrauma
|
||||
},
|
||||
};
|
||||
|
||||
talentButton.Color = talentButton.HoverColor = talentButton.PressedColor = talentButton.SelectedColor = Color.Transparent;
|
||||
talentButton.Color = talentButton.HoverColor = talentButton.PressedColor = talentButton.SelectedColor = talentButton.DisabledColor = Color.Transparent;
|
||||
|
||||
GUIComponent iconImage;
|
||||
if (talent.Icon is null)
|
||||
@@ -1971,6 +2049,7 @@ namespace Barotrauma
|
||||
OutlineColor = GUIStyle.Red,
|
||||
TextColor = GUIStyle.Red,
|
||||
PressedColor = unselectableColor,
|
||||
DisabledColor = unselectableColor,
|
||||
CanBeFocused = false,
|
||||
};
|
||||
}
|
||||
@@ -1979,63 +2058,63 @@ namespace Barotrauma
|
||||
iconImage = new GUIImage(new RectTransform(Vector2.One, talentButton.RectTransform, anchor: Anchor.Center), sprite: talent.Icon, scaleToFit: true)
|
||||
{
|
||||
PressedColor = unselectableColor,
|
||||
DisabledColor = unselectableColor * 0.5f,
|
||||
CanBeFocused = false,
|
||||
};
|
||||
}
|
||||
|
||||
iconImage.Enabled = talentButton.Enabled;
|
||||
talentButtons.Add((talentButton, iconImage));
|
||||
}
|
||||
|
||||
talentCornerIcons.Add((subTree.Identifier, i, cornerIcon, talentBackground, talentBackgroundHighlight));
|
||||
talentCornerIcons.Add((subTree.Identifier, i, cornerIcon, talentBackground, talentBackgroundHighlight));
|
||||
}
|
||||
}
|
||||
}
|
||||
GUITextBlock.AutoScaleAndNormalize(subTreeNames);
|
||||
GUITextBlock.AutoScaleAndNormalize(subTreeNames);
|
||||
|
||||
GUILayoutGroup talentBottomFrame = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.07f), talentFrameLayoutGroup.RectTransform, Anchor.TopCenter), isHorizontal: true) { RelativeSpacing = 0.01f };
|
||||
GUILayoutGroup talentBottomFrame = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.07f), talentFrameLayoutGroup.RectTransform, Anchor.TopCenter), isHorizontal: true) { RelativeSpacing = 0.01f };
|
||||
|
||||
GUILayoutGroup experienceLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.59f, 1f), talentBottomFrame.RectTransform));
|
||||
GUIFrame experienceBarFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.5f), experienceLayout.RectTransform), style: null);
|
||||
GUILayoutGroup experienceLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.59f, 1f), talentBottomFrame.RectTransform));
|
||||
GUIFrame experienceBarFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.5f), experienceLayout.RectTransform), style: null);
|
||||
|
||||
experienceBar = new GUIProgressBar(new RectTransform(new Vector2(1f, 1f), experienceBarFrame.RectTransform, Anchor.CenterLeft),
|
||||
barSize: controlledCharacter.Info.GetProgressTowardsNextLevel(), color: GUIStyle.Green)
|
||||
{
|
||||
IsHorizontal = true,
|
||||
};
|
||||
experienceBar = new GUIProgressBar(new RectTransform(new Vector2(1f, 1f), experienceBarFrame.RectTransform, Anchor.CenterLeft),
|
||||
barSize: info.GetProgressTowardsNextLevel(), color: GUIStyle.Green)
|
||||
{
|
||||
IsHorizontal = true,
|
||||
};
|
||||
|
||||
experienceText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), experienceBarFrame.RectTransform, anchor: Anchor.Center), "", font: GUIStyle.Font, textAlignment: Alignment.CenterRight)
|
||||
{
|
||||
Shadow = true,
|
||||
ToolTip = TextManager.Get("experiencetooltip")
|
||||
};
|
||||
experienceText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), experienceBarFrame.RectTransform, anchor: Anchor.Center), "", font: GUIStyle.Font, textAlignment: Alignment.CenterRight)
|
||||
{
|
||||
Shadow = true,
|
||||
ToolTip = TextManager.Get("experiencetooltip")
|
||||
};
|
||||
|
||||
talentPointText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), experienceLayout.RectTransform, anchor: Anchor.Center), "", font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterRight) { AutoScaleVertical = true };
|
||||
talentPointText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), experienceLayout.RectTransform, anchor: Anchor.Center), "", font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterRight) { AutoScaleVertical = true };
|
||||
|
||||
talentResetButton = new GUIButton(new RectTransform(new Vector2(0.19f, 1f), talentBottomFrame.RectTransform), text: TextManager.Get("reset"), style: "GUIButtonFreeScale")
|
||||
{
|
||||
OnClicked = ResetTalentSelection
|
||||
};
|
||||
talentApplyButton = new GUIButton(new RectTransform(new Vector2(0.19f, 1f), talentBottomFrame.RectTransform), text: TextManager.Get("applysettingsbutton"), style: "GUIButtonFreeScale")
|
||||
{
|
||||
OnClicked = ApplyTalentSelection,
|
||||
};
|
||||
GUITextBlock.AutoScaleAndNormalize(talentResetButton.TextBlock, talentApplyButton.TextBlock);
|
||||
talentResetButton = new GUIButton(new RectTransform(new Vector2(0.19f, 1f), talentBottomFrame.RectTransform), text: TextManager.Get("reset"), style: "GUIButtonFreeScale")
|
||||
{
|
||||
OnClicked = ResetTalentSelection
|
||||
};
|
||||
talentApplyButton = new GUIButton(new RectTransform(new Vector2(0.19f, 1f), talentBottomFrame.RectTransform), text: TextManager.Get("applysettingsbutton"), style: "GUIButtonFreeScale")
|
||||
{
|
||||
OnClicked = ApplyTalentSelection,
|
||||
};
|
||||
GUITextBlock.AutoScaleAndNormalize(talentResetButton.TextBlock, talentApplyButton.TextBlock);
|
||||
}
|
||||
|
||||
UpdateTalentInfo();
|
||||
}
|
||||
|
||||
private void CreateTalentSkillList(Character character, GUIListBox parent)
|
||||
private void CreateTalentSkillList(Character character, CharacterInfo info, GUIListBox parent)
|
||||
{
|
||||
parent.Content.ClearChildren();
|
||||
List<GUITextBlock> skillNames = new List<GUITextBlock>();
|
||||
foreach (Skill skill in character.Info.Job.GetSkills())
|
||||
foreach (Skill skill in info.Job.GetSkills())
|
||||
{
|
||||
GUILayoutGroup skillContainer = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.2f), parent.Content.RectTransform), isHorizontal: true) { CanBeFocused = false };
|
||||
|
||||
skillNames.Add(new GUITextBlock(new RectTransform(new Vector2(0.7f, 1f), skillContainer.RectTransform), TextManager.Get($"skillname.{skill.Identifier}").Fallback(skill.Identifier.Value)));
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.15f, 1.0f), skillContainer.RectTransform), Math.Floor(skill.Level).ToString("F0"), textAlignment: Alignment.CenterRight) { Padding = new Vector4(0, 0, 4, 0) };
|
||||
|
||||
float modifiedSkillLevel = character.GetSkillLevel(skill.Identifier);
|
||||
float modifiedSkillLevel = character?.GetSkillLevel(skill.Identifier) ?? skill.Level;
|
||||
if (!MathUtils.NearlyEqual(MathF.Floor(modifiedSkillLevel), MathF.Floor(skill.Level)))
|
||||
{
|
||||
int skillChange = (int)MathF.Floor(modifiedSkillLevel - skill.Level);
|
||||
@@ -2129,7 +2208,7 @@ namespace Barotrauma
|
||||
talentButton.icon.HoverColor = hoverColor;
|
||||
}
|
||||
|
||||
CreateTalentSkillList(controlledCharacter, skillListBox);
|
||||
CreateTalentSkillList(controlledCharacter, controlledCharacter.Info, skillListBox);
|
||||
}
|
||||
|
||||
private void ApplyTalents(Character controlledCharacter)
|
||||
@@ -2157,6 +2236,7 @@ namespace Barotrauma
|
||||
private bool ResetTalentSelection(GUIButton guiButton, object userData)
|
||||
{
|
||||
Character controlledCharacter = Character.Controlled;
|
||||
if (controlledCharacter?.Info == null) { return false; }
|
||||
selectedTalents = controlledCharacter.Info.GetUnlockedTalentsInTree().ToList();
|
||||
UpdateTalentInfo();
|
||||
return true;
|
||||
|
||||
@@ -546,6 +546,10 @@ namespace Barotrauma
|
||||
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
#if DEBUG
|
||||
LevelGenerationParams.CheckValidity();
|
||||
#endif
|
||||
|
||||
MainMenuScreen.Select();
|
||||
|
||||
foreach (Identifier steamError in SteamManager.InitializationErrors)
|
||||
@@ -1033,11 +1037,6 @@ namespace Barotrauma
|
||||
{
|
||||
GUI.SetSavingIndicatorState(true);
|
||||
|
||||
if (GameSession.Submarine != null && !GameSession.Submarine.Removed)
|
||||
{
|
||||
GameSession.SubmarineInfo = new SubmarineInfo(GameSession.Submarine);
|
||||
}
|
||||
|
||||
// Update store stock when saving and quitting in an outpost (normally updated when CampaignMode.End() is called)
|
||||
if (GameSession?.Campaign is SinglePlayerCampaign spCampaign && Level.IsLoadedOutpost && spCampaign.Map?.CurrentLocation != null && spCampaign.CargoManager != null)
|
||||
{
|
||||
|
||||
@@ -81,7 +81,6 @@ namespace Barotrauma
|
||||
: this(isSinglePlayer)
|
||||
{
|
||||
AddCharacterElements(element);
|
||||
ActiveOrdersElement = element.GetChildElement("activeorders");
|
||||
}
|
||||
|
||||
partial void InitProjectSpecific()
|
||||
@@ -3661,9 +3660,9 @@ namespace Barotrauma
|
||||
crewList.ClearChildren();
|
||||
}
|
||||
|
||||
public void Save(XElement parentElement)
|
||||
public XElement Save(XElement parentElement)
|
||||
{
|
||||
XElement element = new XElement("crew");
|
||||
var element = new XElement("crew");
|
||||
for (int i = 0; i < characterInfos.Count; i++)
|
||||
{
|
||||
var ci = characterInfos[i];
|
||||
@@ -3674,8 +3673,8 @@ namespace Barotrauma
|
||||
infoElement.Add(new XAttribute("crewlistindex", ci.CrewListIndex));
|
||||
if (ci.LastControlled) { infoElement.Add(new XAttribute("lastcontrolled", true)); }
|
||||
}
|
||||
SaveActiveOrders(element);
|
||||
parentElement.Add(element);
|
||||
parentElement?.Add(element);
|
||||
return element;
|
||||
}
|
||||
|
||||
public static void ClientReadActiveOrders(IReadMessage inc)
|
||||
|
||||
@@ -13,6 +13,11 @@ namespace Barotrauma
|
||||
|
||||
partial void SettingsChanged(Option<int> balanceChanged, Option<int> rewardChanged)
|
||||
{
|
||||
if (Owner is Some<Character> { Value: var character })
|
||||
{
|
||||
if (!character.IsPlayer) { return; }
|
||||
}
|
||||
|
||||
CampaignMode campaign = GameMain.GameSession?.Campaign;
|
||||
WalletChangedData data = new WalletChangedData
|
||||
{
|
||||
|
||||
+8
-43
@@ -92,6 +92,7 @@ namespace Barotrauma
|
||||
break;
|
||||
case "crew":
|
||||
GameMain.GameSession.CrewManager = new CrewManager(subElement, true);
|
||||
ActiveOrdersElement = element.GetChildElement("activeorders");
|
||||
break;
|
||||
case "map":
|
||||
map = Map.Load(this, subElement, Settings);
|
||||
@@ -242,11 +243,10 @@ namespace Barotrauma
|
||||
crewDead = false;
|
||||
endTimer = 5.0f;
|
||||
CrewManager.InitSinglePlayerRound();
|
||||
if (petsElement != null)
|
||||
{
|
||||
PetBehavior.LoadPets(petsElement);
|
||||
}
|
||||
CrewManager.LoadActiveOrders();
|
||||
LoadPets();
|
||||
LoadActiveOrders();
|
||||
|
||||
CargoManager.InitPurchasedIDCards();
|
||||
|
||||
GUI.DisableSavingIndicatorDelayed();
|
||||
}
|
||||
@@ -461,41 +461,7 @@ namespace Barotrauma
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (leavingSub != Submarine.MainSub && !leavingSub.DockedTo.Contains(Submarine.MainSub))
|
||||
{
|
||||
Submarine.MainSub = leavingSub;
|
||||
GameMain.GameSession.Submarine = leavingSub;
|
||||
GameMain.GameSession.SubmarineInfo = leavingSub.Info;
|
||||
leavingSub.Info.FilePath = System.IO.Path.Combine(SaveUtil.TempPath, leavingSub.Info.Name + ".sub");
|
||||
var subsToLeaveBehind = GetSubsToLeaveBehind(leavingSub);
|
||||
GameMain.GameSession.OwnedSubmarines.Add(leavingSub.Info);
|
||||
foreach (Submarine sub in subsToLeaveBehind)
|
||||
{
|
||||
GameMain.GameSession.OwnedSubmarines.RemoveAll(s => s != leavingSub.Info && s.Name == sub.Info.Name);
|
||||
MapEntity.mapEntityList.RemoveAll(e => e.Submarine == sub && e is LinkedSubmarine);
|
||||
LinkedSubmarine.CreateDummy(leavingSub, sub);
|
||||
}
|
||||
}
|
||||
|
||||
GameMain.GameSession.SubmarineInfo = new SubmarineInfo(GameMain.GameSession.Submarine);
|
||||
|
||||
if (PendingSubmarineSwitch != null)
|
||||
{
|
||||
SubmarineInfo previousSub = GameMain.GameSession.SubmarineInfo;
|
||||
GameMain.GameSession.SubmarineInfo = PendingSubmarineSwitch;
|
||||
|
||||
for (int i = 0; i < GameMain.GameSession.OwnedSubmarines.Count; i++)
|
||||
{
|
||||
if (GameMain.GameSession.OwnedSubmarines[i].Name == previousSub.Name)
|
||||
{
|
||||
GameMain.GameSession.OwnedSubmarines[i] = previousSub;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
|
||||
PendingSubmarineSwitch = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -766,11 +732,10 @@ namespace Barotrauma
|
||||
c.Info.SaveOrderData();
|
||||
}
|
||||
|
||||
petsElement = new XElement("pets");
|
||||
PetBehavior.SavePets(petsElement);
|
||||
modeElement.Add(petsElement);
|
||||
SavePets(modeElement);
|
||||
var crewManagerElement = CrewManager.Save(modeElement);
|
||||
SaveActiveOrders(crewManagerElement);
|
||||
|
||||
CrewManager.Save(modeElement);
|
||||
CampaignMetadata.Save(modeElement);
|
||||
Map.Save(modeElement);
|
||||
CargoManager?.SavePurchasedItems(modeElement);
|
||||
|
||||
+1
-1
@@ -257,7 +257,7 @@ namespace Barotrauma.Tutorials
|
||||
yield return new WaitForSeconds(2.0f);
|
||||
}*/
|
||||
|
||||
TriggerTutorialSegment(0, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Select), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Deselect), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.ToggleInventory)); // Medical supplies objective
|
||||
TriggerTutorialSegment(0, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Select), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Deselect)); // Medical supplies objective
|
||||
|
||||
do
|
||||
{
|
||||
|
||||
+1
-1
@@ -275,7 +275,7 @@ namespace Barotrauma.Tutorials
|
||||
do { yield return null; } while (!engineer_equipmentObjectiveSensor.MotionDetected);
|
||||
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Engineer.Radio.Equipment"), ChatMessageType.Radio, null);
|
||||
yield return new WaitForSeconds(0.5f, false);
|
||||
TriggerTutorialSegment(0, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Select), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Deselect), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.ToggleInventory)); // Retrieve equipment
|
||||
TriggerTutorialSegment(0, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Select), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Deselect)); // Retrieve equipment
|
||||
bool firstSlotRemoved = false;
|
||||
bool secondSlotRemoved = false;
|
||||
bool thirdSlotRemoved = false;
|
||||
|
||||
+2
-2
@@ -330,7 +330,7 @@ namespace Barotrauma.Tutorials
|
||||
yield return new WaitForSeconds(0.0f, false);
|
||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.Equipment"), ChatMessageType.Radio, null);
|
||||
do { yield return null; } while (!mechanic_equipmentObjectiveSensor.MotionDetected);
|
||||
TriggerTutorialSegment(1, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Select), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Deselect), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.ToggleInventory)); // Equipment & inventory objective
|
||||
TriggerTutorialSegment(1, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Select), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Deselect)); // Equipment & inventory objective
|
||||
SetHighlight(mechanic_equipmentCabinet.Item, true);
|
||||
bool firstSlotRemoved = false;
|
||||
bool secondSlotRemoved = false;
|
||||
@@ -372,7 +372,7 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
// Room 3
|
||||
do { yield return null; } while (!mechanic_weldingObjectiveSensor.MotionDetected);
|
||||
TriggerTutorialSegment(2, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Aim), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Shoot), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.ToggleInventory)); // Welding objective
|
||||
TriggerTutorialSegment(2, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Aim), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Shoot)); // Welding objective
|
||||
do
|
||||
{
|
||||
if (!mechanic.HasEquippedItem("divingmask".ToIdentifier()))
|
||||
|
||||
+1
-1
@@ -106,7 +106,7 @@ namespace Barotrauma.Tutorials
|
||||
Character.Controlled = character;
|
||||
character.GiveJobItems(null);
|
||||
|
||||
var idCard = character.Inventory.FindItemByIdentifier("idcard".ToIdentifier());
|
||||
var idCard = character.Inventory.FindItemByTag("identitycard".ToIdentifier());
|
||||
if (idCard == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Item prefab \"ID Card\" not found!");
|
||||
|
||||
@@ -525,6 +525,7 @@ namespace Barotrauma
|
||||
if (!AccessibleWhenAlive && !character.IsDead && !AccessibleByOwner)
|
||||
{
|
||||
syncItemsDelay = Math.Max(syncItemsDelay - deltaTime, 0.0f);
|
||||
doubleClickedItems.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -931,7 +932,7 @@ namespace Barotrauma
|
||||
// Move the item from the subinventory to the selected container
|
||||
return QuickUseAction.PutToContainer;
|
||||
}
|
||||
else
|
||||
else if (character.Inventory.AccessibleWhenAlive || character.Inventory.AccessibleByOwner)
|
||||
{
|
||||
// Take from the subinventory and place it in the character's main inventory if no target container is selected
|
||||
return QuickUseAction.TakeFromContainer;
|
||||
@@ -959,7 +960,8 @@ namespace Barotrauma
|
||||
}
|
||||
else if (character.SelectedBy?.Inventory != null &&
|
||||
Character.Controlled == character.SelectedBy &&
|
||||
!character.SelectedBy.Inventory.Locked &&
|
||||
!character.SelectedBy.Inventory.Locked &&
|
||||
(character.SelectedBy.Inventory.AccessibleWhenAlive || character.SelectedBy.Inventory.AccessibleByOwner) &&
|
||||
allowInventorySwap)
|
||||
{
|
||||
return QuickUseAction.TakeFromCharacter;
|
||||
|
||||
@@ -66,6 +66,9 @@ namespace Barotrauma.Items.Components
|
||||
rect.Height = (int)(rect.Height * (1.0f - openState));
|
||||
}
|
||||
|
||||
//only merge the door's convex hull with overlapping wall segments if it's fully open or fully closed
|
||||
//it's the heaviest part of changing the convex hull, and doesn't need to be done while the door is still in motion
|
||||
bool mergeOverlappingSegments = openState <= 0.0f || openState >= 1.0f;
|
||||
if (Window.Height > 0 && Window.Width > 0)
|
||||
{
|
||||
if (IsHorizontal)
|
||||
@@ -88,7 +91,7 @@ namespace Barotrauma.Items.Components
|
||||
else
|
||||
{
|
||||
convexHull2.Enabled = true;
|
||||
convexHull2.SetVertices(GetConvexHullCorners(rect2));
|
||||
convexHull2.SetVertices(GetConvexHullCorners(rect2), mergeOverlappingSegments);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,7 +115,7 @@ namespace Barotrauma.Items.Components
|
||||
else
|
||||
{
|
||||
convexHull2.Enabled = true;
|
||||
convexHull2.SetVertices(GetConvexHullCorners(rect2));
|
||||
convexHull2.SetVertices(GetConvexHullCorners(rect2), mergeOverlappingSegments);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,7 +130,7 @@ namespace Barotrauma.Items.Components
|
||||
else
|
||||
{
|
||||
convexHull.Enabled = true;
|
||||
convexHull.SetVertices(GetConvexHullCorners(rect));
|
||||
convexHull.SetVertices(GetConvexHullCorners(rect), mergeOverlappingSegments);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+16
-5
@@ -1,4 +1,5 @@
|
||||
using Barotrauma.Networking;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System.Linq;
|
||||
@@ -78,7 +79,7 @@ namespace Barotrauma.Items.Components
|
||||
activateButton = new GUIButton(new RectTransform(new Vector2(0.95f, 0.8f), buttonContainer.RectTransform), TextManager.Get("DeconstructorDeconstruct"), style: "DeviceButton")
|
||||
{
|
||||
TextBlock = { AutoScaleHorizontal = true },
|
||||
OnClicked = ToggleActive
|
||||
OnClicked = OnActivateButtonClicked
|
||||
};
|
||||
inSufficientPowerWarning = new GUITextBlock(new RectTransform(Vector2.One, activateButton.RectTransform),
|
||||
TextManager.Get("DeconstructorNoPower"), textColor: GUIStyle.Orange, textAlignment: Alignment.Center, color: Color.Black, style: "OuterGlow", wrap: true)
|
||||
@@ -164,7 +165,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
}
|
||||
activateButton.Enabled = outputsFound;
|
||||
activateButton.Enabled = outputsFound || !InputContainer.Inventory.IsEmpty();
|
||||
activateButton.Text = TextManager.Get(ActivateButtonText);
|
||||
};
|
||||
}
|
||||
@@ -236,8 +237,19 @@ namespace Barotrauma.Items.Components
|
||||
inSufficientPowerWarning.Visible = IsActive && !hasPower;
|
||||
}
|
||||
|
||||
private bool ToggleActive(GUIButton button, object obj)
|
||||
private bool OnActivateButtonClicked(GUIButton button, object obj)
|
||||
{
|
||||
var disallowedItem = inputContainer.Inventory.FindItem(i => !i.AllowDeconstruct, recursive: false);
|
||||
if (disallowedItem != null)
|
||||
{
|
||||
int index = inputContainer.Inventory.FindIndex(disallowedItem);
|
||||
if (index >= 0 && index < inputContainer.Inventory.visualSlots.Length)
|
||||
{
|
||||
var slot = inputContainer.Inventory.visualSlots[index];
|
||||
slot?.ShowBorderHighlight(GUIStyle.Red, 0.1f, 0.9f);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (GameMain.Client != null)
|
||||
{
|
||||
pendingState = !IsActive;
|
||||
@@ -247,7 +259,6 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
SetActive(!IsActive, Character.Controlled);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1367,6 +1367,15 @@ namespace Barotrauma.Items.Components
|
||||
pingRadius, prevPingRadius,
|
||||
250.0f, 150.0f, range, pingStrength, passive);
|
||||
}
|
||||
if (pingSource.Y - Level.Loaded.BottomPos < range)
|
||||
{
|
||||
CreateBlipsForLine(
|
||||
new Vector2(pingSource.X - range, Level.Loaded.BottomPos),
|
||||
new Vector2(pingSource.X + range, Level.Loaded.BottomPos),
|
||||
pingSource, transducerPos,
|
||||
pingRadius, prevPingRadius,
|
||||
250.0f, 150.0f, range, pingStrength, passive);
|
||||
}
|
||||
|
||||
List<Voronoi2.VoronoiCell> cells = Level.Loaded.GetCells(pingSource, 7);
|
||||
foreach (Voronoi2.VoronoiCell cell in cells)
|
||||
|
||||
@@ -23,10 +23,10 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
#endif
|
||||
|
||||
private List<ParticleEmitter> particleEmitters = new List<ParticleEmitter>();
|
||||
private List<ParticleEmitter> particleEmitterHitStructure = new List<ParticleEmitter>();
|
||||
private List<ParticleEmitter> particleEmitterHitCharacter = new List<ParticleEmitter>();
|
||||
private List<Pair<RelatedItem, ParticleEmitter>> particleEmitterHitItem = new List<Pair<RelatedItem, ParticleEmitter>>();
|
||||
private readonly List<ParticleEmitter> particleEmitters = new List<ParticleEmitter>();
|
||||
private readonly List<ParticleEmitter> particleEmitterHitStructure = new List<ParticleEmitter>();
|
||||
private readonly List<ParticleEmitter> particleEmitterHitCharacter = new List<ParticleEmitter>();
|
||||
private readonly List<(RelatedItem relatedItem, ParticleEmitter emitter)> particleEmitterHitItem = new List<(RelatedItem relatedItem, ParticleEmitter emitter)>();
|
||||
|
||||
private float prevProgressBarState;
|
||||
private Item prevProgressBarTarget = null;
|
||||
@@ -46,10 +46,7 @@ namespace Barotrauma.Items.Components
|
||||
Identifier[] excludedIdentifiers = subElement.GetAttributeIdentifierArray("excludedidentifiers", Array.Empty<Identifier>());
|
||||
if (excludedIdentifiers.Length == 0) { excludedIdentifiers = subElement.GetAttributeIdentifierArray("excludedidentifier", Array.Empty<Identifier>()); }
|
||||
|
||||
particleEmitterHitItem.Add(
|
||||
new Pair<RelatedItem, ParticleEmitter>(
|
||||
new RelatedItem(identifiers, excludedIdentifiers),
|
||||
new ParticleEmitter(subElement)));
|
||||
particleEmitterHitItem.Add((new RelatedItem(identifiers, excludedIdentifiers), new ParticleEmitter(subElement)));
|
||||
break;
|
||||
case "particleemitterhitstructure":
|
||||
particleEmitterHitStructure.Add(new ParticleEmitter(subElement));
|
||||
@@ -139,11 +136,11 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
Vector2 particlePos = ConvertUnits.ToDisplayUnits(pickedPosition);
|
||||
if (targetItem.Submarine != null) particlePos += targetItem.Submarine.DrawPosition;
|
||||
foreach (var emitter in particleEmitterHitItem)
|
||||
foreach ((RelatedItem relatedItem, ParticleEmitter emitter) in particleEmitterHitItem)
|
||||
{
|
||||
if (!emitter.First.MatchesItem(targetItem)) { continue; }
|
||||
if (!relatedItem.MatchesItem(targetItem)) { continue; }
|
||||
float particleAngle = item.body.Rotation + MathHelper.ToRadians(BarrelRotation) + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
|
||||
emitter.Second.Emit(deltaTime, particlePos, item.CurrentHull, particleAngle + MathHelper.Pi, -particleAngle + MathHelper.Pi);
|
||||
emitter.Emit(deltaTime, particlePos, item.CurrentHull, particleAngle + MathHelper.Pi, -particleAngle + MathHelper.Pi);
|
||||
}
|
||||
}
|
||||
#if DEBUG
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Barotrauma.Items.Components
|
||||
int totalWireCount = 0;
|
||||
foreach (Connection c in panel.Connections)
|
||||
{
|
||||
totalWireCount += c.Wires.Count(w => w != null);
|
||||
totalWireCount += c.Wires.Count;
|
||||
}
|
||||
|
||||
Wire equippedWire = null;
|
||||
@@ -87,8 +87,8 @@ namespace Barotrauma.Items.Components
|
||||
(DraggingConnected.Connections[0] == null && DraggingConnected.Connections[1] == null) ||
|
||||
(DraggingConnected.Connections.Contains(c) && DraggingConnected.Connections.Contains(null)))
|
||||
{
|
||||
int linkIndex = c.FindWireIndex(DraggingConnected.Item);
|
||||
if (linkIndex > -1 || panel.DisconnectedWires.Contains(DraggingConnected))
|
||||
var linkedWire = c.FindWireByItem(DraggingConnected.Item);
|
||||
if (linkedWire != null || panel.DisconnectedWires.Contains(DraggingConnected))
|
||||
{
|
||||
Inventory.DraggingItems.Clear();
|
||||
Inventory.DraggingItems.Add(DraggingConnected.Item);
|
||||
@@ -108,7 +108,7 @@ namespace Barotrauma.Items.Components
|
||||
c.DrawWires(spriteBatch, panel, rightPos, rightWirePos, mouseInRect, equippedWire, wireInterval);
|
||||
}
|
||||
rightPos.Y += connectorIntervalLeft;
|
||||
rightWirePos.Y += c.Wires.Count(w => w != null) * wireInterval;
|
||||
rightWirePos.Y += c.Wires.Count * wireInterval;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -121,7 +121,7 @@ namespace Barotrauma.Items.Components
|
||||
c.DrawWires(spriteBatch, panel, leftPos, leftWirePos, mouseInRect, equippedWire, wireInterval);
|
||||
}
|
||||
leftPos.Y += connectorIntervalRight;
|
||||
leftWirePos.Y += c.Wires.Count(w => w != null) * wireInterval;
|
||||
leftWirePos.Y += c.Wires.Count * wireInterval;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -228,15 +228,15 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
float connectorSpriteScale = (35.0f / connectionSprite.SourceRect.Width) * panel.Scale;
|
||||
|
||||
for (int i = 0; i < MaxWires; i++)
|
||||
foreach (var wire in wires)
|
||||
{
|
||||
if (wires[i] == null || wires[i].Hidden || (DraggingConnected == wires[i] && (mouseIn || Screen.Selected == GameMain.SubEditorScreen))) { continue; }
|
||||
if (wires[i].HiddenInGame && Screen.Selected == GameMain.GameScreen) { continue; }
|
||||
if (wire.Hidden || (DraggingConnected == wire && (mouseIn || Screen.Selected == GameMain.SubEditorScreen))) { continue; }
|
||||
if (wire.HiddenInGame && Screen.Selected == GameMain.GameScreen) { continue; }
|
||||
|
||||
Connection recipient = wires[i].OtherConnection(this);
|
||||
Connection recipient = wire.OtherConnection(this);
|
||||
LocalizedString label = recipient == null ? "" : recipient.item.Name + $" ({recipient.DisplayName})";
|
||||
if (wires[i].Locked) { label += "\n" + TextManager.Get("ConnectionLocked"); }
|
||||
DrawWire(spriteBatch, wires[i], position, wirePosition, equippedWire, panel, label);
|
||||
if (wire.Locked) { label += "\n" + TextManager.Get("ConnectionLocked"); }
|
||||
DrawWire(spriteBatch, wire, position, wirePosition, equippedWire, panel, label);
|
||||
|
||||
wirePosition.Y += wireInterval;
|
||||
}
|
||||
@@ -248,18 +248,17 @@ namespace Barotrauma.Items.Components
|
||||
if (!PlayerInput.PrimaryMouseButtonHeld())
|
||||
{
|
||||
if ((GameMain.NetworkMember != null || panel.CheckCharacterSuccess(Character.Controlled)) &&
|
||||
Wires.Count(w => w != null) < MaxPlayerConnectableWires)
|
||||
Wires.Count < MaxPlayerConnectableWires)
|
||||
{
|
||||
//find an empty cell for the new connection
|
||||
int index = FindEmptyIndex();
|
||||
if (index > -1 && !Wires.Contains(DraggingConnected))
|
||||
if (WireSlotsAvailable() && !Wires.Contains(DraggingConnected))
|
||||
{
|
||||
bool alreadyConnected = DraggingConnected.IsConnectedTo(panel.Item);
|
||||
DraggingConnected.RemoveConnection(panel.Item);
|
||||
if (DraggingConnected.Connect(this, !alreadyConnected, true))
|
||||
{
|
||||
var otherConnection = DraggingConnected.OtherConnection(this);
|
||||
SetWire(index, DraggingConnected);
|
||||
ConnectWire(DraggingConnected);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -284,7 +283,7 @@ namespace Barotrauma.Items.Components
|
||||
flashColor * (float)Math.Sin(FlashTimer % flashCycleDuration / flashCycleDuration * MathHelper.Pi * 0.8f), scale: connectorSpriteScale);
|
||||
}
|
||||
|
||||
if (Wires.Any(w => w != null && w != DraggingConnected && !w.Hidden && (!w.HiddenInGame || Screen.Selected != GameMain.GameScreen)))
|
||||
if (Wires.Any(w => w != DraggingConnected && !w.Hidden && (!w.HiddenInGame || Screen.Selected != GameMain.GameScreen)))
|
||||
{
|
||||
int screwIndex = (int)Math.Floor(position.Y / 30.0f) % screwSprites.Count;
|
||||
screwSprites[screwIndex].Draw(spriteBatch, position, scale: connectorSpriteScale);
|
||||
|
||||
+17
-7
@@ -77,7 +77,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public override void Move(Vector2 amount)
|
||||
public override void Move(Vector2 amount, bool ignoreContacts = false)
|
||||
{
|
||||
if (item.Submarine == null || item.Submarine.Loading || Screen.Selected != GameMain.SubEditorScreen) { return; }
|
||||
MoveConnectedWires(amount);
|
||||
@@ -173,9 +173,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private void ApplyRemoteState(IReadMessage msg)
|
||||
{
|
||||
List<Wire> prevWires = Connections.SelectMany(c => c.Wires.Where(w => w != null)).ToList();
|
||||
List<Wire> newWires = new List<Wire>();
|
||||
|
||||
List<Wire> prevWires = Connections.SelectMany(c => c.Wires).ToList();
|
||||
|
||||
ushort userID = msg.ReadUInt16();
|
||||
|
||||
if (userID == 0)
|
||||
@@ -195,7 +194,9 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
foreach (Connection connection in Connections)
|
||||
{
|
||||
for (int i = 0; i < connection.MaxWires; i++)
|
||||
HashSet<Wire> newWires = new HashSet<Wire>();
|
||||
uint wireCount = msg.ReadVariableUInt32();
|
||||
for (int i = 0; i < wireCount; i++)
|
||||
{
|
||||
ushort wireId = msg.ReadUInt16();
|
||||
|
||||
@@ -204,9 +205,18 @@ namespace Barotrauma.Items.Components
|
||||
if (wireComponent == null) { continue; }
|
||||
|
||||
newWires.Add(wireComponent);
|
||||
}
|
||||
|
||||
connection.SetWire(i, wireComponent);
|
||||
wireComponent.Connect(connection, false);
|
||||
Wire[] oldWires = connection.Wires.Where(w => !newWires.Contains(w)).ToArray();
|
||||
foreach (var wire in oldWires)
|
||||
{
|
||||
connection.DisconnectWire(wire);
|
||||
}
|
||||
|
||||
foreach (var wire in newWires.Where(w => !connection.Wires.Contains(w)).ToArray())
|
||||
{
|
||||
connection.ConnectWire(wire);
|
||||
wire.Connect(connection, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -205,7 +205,7 @@ namespace Barotrauma.Items.Components
|
||||
foreach (var uiElement in uiElements)
|
||||
{
|
||||
if (!(uiElement.UserData is CustomInterfaceElement element)) { continue; }
|
||||
bool visible = Screen.Selected == GameMain.SubEditorScreen || element.StatusEffects.Any() || element.HasPropertyName || (element.Connection != null && element.Connection.Wires.Any(w => w != null));
|
||||
bool visible = Screen.Selected == GameMain.SubEditorScreen || element.StatusEffects.Any() || element.HasPropertyName || (element.Connection != null && element.Connection.Wires.Count > 0);
|
||||
if (visible) { visibleElementCount++; }
|
||||
if (uiElement.Visible != visible)
|
||||
{
|
||||
|
||||
@@ -526,7 +526,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public override void Move(Vector2 amount)
|
||||
public override void Move(Vector2 amount, bool ignoreContacts = false)
|
||||
{
|
||||
//only used in the sub editor, hence only in the client project
|
||||
if (!item.IsSelected) { return; }
|
||||
|
||||
@@ -175,7 +175,7 @@ namespace Barotrauma.Items.Components
|
||||
};
|
||||
}
|
||||
|
||||
public override void Move(Vector2 amount)
|
||||
public override void Move(Vector2 amount, bool ignoreContacts = false)
|
||||
{
|
||||
widgets.Clear();
|
||||
}
|
||||
|
||||
@@ -6,8 +6,10 @@ using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class DockingPort : ItemComponent, IDrawableComponent, IServerSerializable
|
||||
partial class DockingPort : ItemComponent, IDrawableComponent, IServerSerializable, IClientSerializable
|
||||
{
|
||||
private GUIMessageBox autodockingVerification;
|
||||
|
||||
public Vector2 DrawSize
|
||||
{
|
||||
//use the extents of the item as the draw size
|
||||
@@ -180,5 +182,10 @@ namespace Barotrauma.Items.Components
|
||||
Undock();
|
||||
}
|
||||
}
|
||||
|
||||
public void ClientEventWrite(IWriteMessage msg, NetEntityEvent.IData extraData = null)
|
||||
{
|
||||
msg.Write((byte)allowOutpostAutoDocking);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
LocalizedString description = item.Description;
|
||||
if (item.Prefab.Identifier == "idcard" || item.Tags.Contains("despawncontainer"))
|
||||
if (item.HasTag("identitycard") || item.HasTag("despawncontainer"))
|
||||
{
|
||||
string[] readTags = item.Tags.Split(',');
|
||||
string idName = null;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Barotrauma.Items.Components;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.Items.Components;
|
||||
using Barotrauma.MapCreatures.Behavior;
|
||||
using Barotrauma.Networking;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
@@ -6,13 +8,8 @@ using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.MapCreatures.Behavior;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using FarseerPhysics.Dynamics.Contacts;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -720,7 +717,7 @@ namespace Barotrauma
|
||||
//remove identifiers from the available container tags
|
||||
//(otherwise the list will include many irrelevant options,
|
||||
//e.g. "weldingtool" because a welding fuel tank can be placed inside the container, etc)
|
||||
.Where(t => !ItemPrefab.Prefabs.Any(ip => ip.Identifier == t))
|
||||
.Where(t => !ItemPrefab.Prefabs.ContainsKey(t))
|
||||
.ToImmutableHashSet();
|
||||
new GUIButton(new RectTransform(new Vector2(0.1f, 1), tagsField.RectTransform, Anchor.TopRight), "...")
|
||||
{
|
||||
@@ -1174,7 +1171,7 @@ namespace Barotrauma
|
||||
texts.Clear();
|
||||
|
||||
string nameText = Name;
|
||||
if (Prefab.Identifier == "idcard" || Tags.Contains("despawncontainer"))
|
||||
if (Prefab.Tags.Contains("identitycard") || Tags.Contains("despawncontainer"))
|
||||
{
|
||||
string[] readTags = Tags.Split(',');
|
||||
string idName = null;
|
||||
|
||||
@@ -80,15 +80,17 @@ namespace Barotrauma
|
||||
}
|
||||
Vector2 center = new Vector2((minX + maxX) / 2.0f, (minY + maxY) / 2.0f);
|
||||
if (Submarine.MainSub != null) { center -= Submarine.MainSub.HiddenSubPosition; }
|
||||
center.X -= MathUtils.RoundTowardsClosest(center.X, Submarine.GridSize.X);
|
||||
center.Y -= MathUtils.RoundTowardsClosest(center.Y, Submarine.GridSize.Y);
|
||||
|
||||
Vector2 offsetFromGrid = new Vector2(
|
||||
MathUtils.RoundTowardsClosest(center.X, Submarine.GridSize.X) - center.X,
|
||||
MathUtils.RoundTowardsClosest(center.Y, Submarine.GridSize.Y) - center.Y - Submarine.GridSize.Y / 2);
|
||||
|
||||
MapEntity.SelectedList.Clear();
|
||||
assemblyEntities.ForEach(e => MapEntity.AddSelection(e));
|
||||
|
||||
foreach (MapEntity mapEntity in assemblyEntities)
|
||||
{
|
||||
mapEntity.Move(-center);
|
||||
mapEntity.Move(-center - offsetFromGrid);
|
||||
mapEntity.Submarine = Submarine.MainSub;
|
||||
var entityElement = mapEntity.Save(element);
|
||||
if (disabledEntities.Contains(mapEntity))
|
||||
|
||||
@@ -461,7 +461,7 @@ namespace Barotrauma.Lights
|
||||
Matrix.CreateTranslation(-origin.X, -origin.Y, 0.0f) *
|
||||
Matrix.CreateRotationZ(amount) *
|
||||
Matrix.CreateTranslation(origin.X, origin.Y, 0.0f);
|
||||
SetVertices(vertices.Select(v => v.Pos).ToArray(), rotationMatrix);
|
||||
SetVertices(vertices.Select(v => v.Pos).ToArray(), rotationMatrix: rotationMatrix);
|
||||
}
|
||||
|
||||
private void CalculateDimensions()
|
||||
@@ -541,7 +541,7 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
}
|
||||
|
||||
public void SetVertices(Vector2[] points, Matrix? rotationMatrix = null)
|
||||
public void SetVertices(Vector2[] points, bool mergeOverlappingSegments = true, Matrix? rotationMatrix = null)
|
||||
{
|
||||
Debug.Assert(points.Length == 4, "Only rectangular convex hulls are supported");
|
||||
|
||||
@@ -594,13 +594,16 @@ namespace Barotrauma.Lights
|
||||
|
||||
if (ParentEntity == null) { return; }
|
||||
|
||||
var chList = HullLists.Find(h => h.Submarine == ParentEntity.Submarine);
|
||||
if (chList != null)
|
||||
if (mergeOverlappingSegments)
|
||||
{
|
||||
overlappingHulls.Clear();
|
||||
foreach (ConvexHull ch in chList.List)
|
||||
var chList = HullLists.Find(h => h.Submarine == ParentEntity.Submarine);
|
||||
if (chList != null)
|
||||
{
|
||||
MergeOverlappingSegments(ch);
|
||||
overlappingHulls.Clear();
|
||||
foreach (ConvexHull ch in chList.List)
|
||||
{
|
||||
MergeOverlappingSegments(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,11 +81,18 @@ namespace Barotrauma
|
||||
}
|
||||
catch (System.IO.FileNotFoundException e)
|
||||
{
|
||||
string errorMsg = "Failed to load sound file \"" + filename + "\".";
|
||||
string errorMsg = "Failed to load sound file \"" + filename + "\" (file not found).";
|
||||
DebugConsole.ThrowError(errorMsg, e);
|
||||
GameAnalyticsManager.AddErrorEventOnce("RoundSound.LoadRoundSound:FileNotFound" + filename, GameAnalyticsManager.ErrorSeverity.Error, errorMsg + "\n" + Environment.StackTrace.CleanupStackTrace());
|
||||
return null;
|
||||
}
|
||||
catch (System.IO.InvalidDataException e)
|
||||
{
|
||||
string errorMsg = "Failed to load sound file \"" + filename + "\" (invalid data).";
|
||||
DebugConsole.ThrowError(errorMsg, e);
|
||||
GameAnalyticsManager.AddErrorEventOnce("RoundSound.LoadRoundSound:InvalidData" + filename, GameAnalyticsManager.ErrorSeverity.Error, errorMsg + "\n" + Environment.StackTrace.CleanupStackTrace());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
RoundSound newSound = new RoundSound(element, existingSound);
|
||||
|
||||
@@ -525,7 +525,7 @@ namespace Barotrauma
|
||||
Item.ItemList.Count(it2 => it2.linkedTo.Contains(item) && !item.linkedTo.Contains(it2));
|
||||
for (int i = 0; i < item.Connections.Count; i++)
|
||||
{
|
||||
int wireCount = item.Connections[i].Wires.Count(w => w != null);
|
||||
int wireCount = item.Connections[i].Wires.Count;
|
||||
if (doorLinks + wireCount > item.Connections[i].MaxWires)
|
||||
{
|
||||
errorMsgs.Add(TextManager.GetWithVariables("InsufficientFreeConnectionsWarning",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Barotrauma.Items.Components;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
@@ -183,6 +184,11 @@ namespace Barotrauma.Networking
|
||||
break;
|
||||
default:
|
||||
GameMain.Client.AddChatMessage(txt, type, senderName, senderClient, senderCharacter, changeType, textColor: textColor);
|
||||
if (type == ChatMessageType.Radio && CanUseRadio(senderCharacter, out WifiComponent radio))
|
||||
{
|
||||
Signal s = new Signal(txt, sender: senderCharacter, source: radio.Item);
|
||||
radio.TransmitSignal(s, sentFromChat: true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
LastID = id;
|
||||
|
||||
@@ -3,6 +3,7 @@ using Barotrauma.Steam;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using Barotrauma.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
@@ -11,6 +12,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
@@ -182,6 +184,20 @@ namespace Barotrauma.Networking
|
||||
get { return ownerKey > 0 || steamP2POwner; }
|
||||
}
|
||||
|
||||
internal readonly struct PermissionChangedEvent
|
||||
{
|
||||
public readonly ClientPermissions NewPermissions;
|
||||
public readonly ImmutableArray<string> NewPermittedConsoleCommands;
|
||||
|
||||
public PermissionChangedEvent(ClientPermissions newPermissions, IReadOnlyList<string> newPermittedConsoleCommands)
|
||||
{
|
||||
NewPermissions = newPermissions;
|
||||
NewPermittedConsoleCommands = newPermittedConsoleCommands.ToImmutableArray();
|
||||
}
|
||||
}
|
||||
|
||||
public readonly NamedEvent<PermissionChangedEvent> OnPermissionChanged = new NamedEvent<PermissionChangedEvent>();
|
||||
|
||||
public GameClient(string newName, string ip, UInt64 steamId, string serverName = null, int ownerKey = 0, bool steamP2POwner = false)
|
||||
{
|
||||
//TODO: gui stuff should probably not be here?
|
||||
@@ -570,7 +586,12 @@ namespace Barotrauma.Networking
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
#if DEBUG
|
||||
if (PlayerInput.GetKeyboardState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.P)) return;
|
||||
if (PlayerInput.GetKeyboardState.IsKeyDown(Keys.P)) return;
|
||||
|
||||
if (PlayerInput.KeyHit(Keys.Home))
|
||||
{
|
||||
OnPermissionChanged.Invoke(new PermissionChangedEvent(permissions, permittedConsoleCommands));
|
||||
}
|
||||
#endif
|
||||
|
||||
foreach (Client c in ConnectedClients)
|
||||
@@ -1019,40 +1040,25 @@ namespace Barotrauma.Networking
|
||||
GameMain.GameSession.EnforceMissionOrder(serverMissionIdentifiers);
|
||||
}
|
||||
|
||||
byte equalityCheckValueCount = inc.ReadByte();
|
||||
List<int> levelEqualityCheckValues = new List<int>();
|
||||
for (int i = 0; i < equalityCheckValueCount; i++)
|
||||
var levelEqualityCheckValues = new Dictionary<Level.LevelGenStage, int>();
|
||||
foreach (Level.LevelGenStage stage in Enum.GetValues(typeof(Level.LevelGenStage)).OfType<Level.LevelGenStage>().OrderBy(s => s))
|
||||
{
|
||||
levelEqualityCheckValues.Add(inc.ReadInt32());
|
||||
levelEqualityCheckValues.Add(stage, inc.ReadInt32());
|
||||
}
|
||||
|
||||
if (Level.Loaded.EqualityCheckValues.Count != levelEqualityCheckValues.Count)
|
||||
foreach (var stage in levelEqualityCheckValues.Keys)
|
||||
{
|
||||
string errorMsg = "Level equality check failed. The level generated at your end doesn't match the level generated by the server" +
|
||||
" (client value count: " + Level.Loaded.EqualityCheckValues.Count +
|
||||
", level value count: " + levelEqualityCheckValues.Count +
|
||||
", seed: " + Level.Loaded.Seed +
|
||||
", sub: " + Submarine.MainSub.Info.Name + " (" + Submarine.MainSub.Info.MD5Hash.ShortRepresentation + ")" +
|
||||
", mirrored: " + Level.Loaded.Mirrored + ").";
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:LevelsDontMatch" + Level.Loaded.Seed, GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||
throw new Exception(errorMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < equalityCheckValueCount; i++)
|
||||
if (Level.Loaded.EqualityCheckValues[stage] != levelEqualityCheckValues[stage])
|
||||
{
|
||||
if (Level.Loaded.EqualityCheckValues[i] != levelEqualityCheckValues[i])
|
||||
{
|
||||
string errorMsg = "Level equality check failed. The level generated at your end doesn't match the level generated by the server" +
|
||||
" (client value #" + i + ": " + Level.Loaded.EqualityCheckValues[i] +
|
||||
", server value #" + i + ": " + levelEqualityCheckValues[i].ToString("X") +
|
||||
", level value count: " + levelEqualityCheckValues.Count +
|
||||
", seed: " + Level.Loaded.Seed +
|
||||
", sub: " + Submarine.MainSub.Info.Name + " (" + Submarine.MainSub.Info.MD5Hash.ShortRepresentation + ")" +
|
||||
", mirrored: " + Level.Loaded.Mirrored + ").";
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:LevelsDontMatch" + Level.Loaded.Seed, GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||
throw new Exception(errorMsg);
|
||||
}
|
||||
string errorMsg = "Level equality check failed. The level generated at your end doesn't match the level generated by the server" +
|
||||
" (client value " + stage + ": " + Level.Loaded.EqualityCheckValues[stage].ToString("X") +
|
||||
", server value " + stage + ": " + levelEqualityCheckValues[stage].ToString("X") +
|
||||
", level value count: " + levelEqualityCheckValues.Count +
|
||||
", seed: " + Level.Loaded.Seed +
|
||||
", sub: " + Submarine.MainSub.Info.Name + " (" + Submarine.MainSub.Info.MD5Hash.ShortRepresentation + ")" +
|
||||
", mirrored: " + Level.Loaded.Mirrored + ").";
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:LevelsDontMatch" + Level.Loaded.Seed, GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||
throw new Exception(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1076,6 +1082,7 @@ namespace Barotrauma.Networking
|
||||
reconnectBox?.Close();
|
||||
reconnectBox = null;
|
||||
|
||||
GameMain.ModDownloadScreen.Reset();
|
||||
ContentPackageManager.EnabledPackages.Restore();
|
||||
|
||||
GUI.ClearCursorWait();
|
||||
@@ -1380,18 +1387,13 @@ namespace Barotrauma.Networking
|
||||
private void SetMyPermissions(ClientPermissions newPermissions, IEnumerable<string> permittedConsoleCommands)
|
||||
{
|
||||
if (!(this.permittedConsoleCommands.Any(c => !permittedConsoleCommands.Contains(c)) ||
|
||||
permittedConsoleCommands.Any(c => !this.permittedConsoleCommands.Contains(c))))
|
||||
permittedConsoleCommands.Any(c => !this.permittedConsoleCommands.Contains(c))))
|
||||
{
|
||||
if (newPermissions == permissions) return;
|
||||
}
|
||||
|
||||
bool refreshCampaignUI = false;
|
||||
|
||||
if (permissions.HasFlag(ClientPermissions.ManageCampaign) != newPermissions.HasFlag(ClientPermissions.ManageCampaign) ||
|
||||
permissions.HasFlag(ClientPermissions.ManageRound) != newPermissions.HasFlag(ClientPermissions.ManageRound))
|
||||
{
|
||||
refreshCampaignUI = true;
|
||||
}
|
||||
bool refreshCampaignUI = permissions.HasFlag(ClientPermissions.ManageCampaign) != newPermissions.HasFlag(ClientPermissions.ManageCampaign) ||
|
||||
permissions.HasFlag(ClientPermissions.ManageRound) != newPermissions.HasFlag(ClientPermissions.ManageRound);
|
||||
|
||||
permissions = newPermissions;
|
||||
this.permittedConsoleCommands = new List<string>(permittedConsoleCommands);
|
||||
@@ -1430,7 +1432,7 @@ namespace Barotrauma.Networking
|
||||
if (newPermissions.HasFlag(ClientPermissions.ConsoleCommands))
|
||||
{
|
||||
var commandsLabel = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), rightColumn.RectTransform),
|
||||
TextManager.Get("PermittedConsoleCommands"), wrap: true, font: GUIStyle.SubHeadingFont);
|
||||
TextManager.Get("PermittedConsoleCommands"), wrap: true, font: GUIStyle.SubHeadingFont);
|
||||
var commandList = new GUIListBox(new RectTransform(new Vector2(1.0f, 1.0f), rightColumn.RectTransform));
|
||||
foreach (string permittedCommand in permittedConsoleCommands)
|
||||
{
|
||||
@@ -1469,6 +1471,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
GameMain.NetLobbyScreen.RefreshEnabledElements();
|
||||
OnPermissionChanged.Invoke(new PermissionChangedEvent(permissions, this.permittedConsoleCommands));
|
||||
}
|
||||
|
||||
private IEnumerable<CoroutineStatus> StartGame(IReadMessage inc)
|
||||
@@ -3680,7 +3683,9 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
if (Level.Loaded != null)
|
||||
{
|
||||
errorLines.Add("Level: " + Level.Loaded.Seed + ", " + string.Join(", ", Level.Loaded.EqualityCheckValues.Select(cv => cv.ToString("X"))));
|
||||
errorLines.Add("Level: " + Level.Loaded.Seed + ", "
|
||||
+ string.Join("; ", Level.Loaded.EqualityCheckValues.Select(cv
|
||||
=> cv.Key + "=" + cv.Value.ToString("X"))));
|
||||
errorLines.Add("Entity count before generating level: " + Level.Loaded.EntityCountBeforeGenerate);
|
||||
errorLines.Add("Entities:");
|
||||
foreach (Entity e in Level.Loaded.EntitiesBeforeGenerate.OrderBy(e => e.CreationIndex))
|
||||
|
||||
@@ -621,7 +621,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
|
||||
var losModeRadioButtonGroup = new GUIRadioButtonGroup();
|
||||
LosMode[] losModes = (LosMode[])Enum.GetValues(typeof(LosMode));
|
||||
for (int i = 0; i < losModes.Length; i++)
|
||||
@@ -634,6 +634,14 @@ namespace Barotrauma.Networking
|
||||
var traitorsMinPlayerCount = CreateLabeledNumberInput(roundsTab, "ServerSettingsTraitorsMinPlayerCount", 1, 16, "ServerSettingsTraitorsMinPlayerCountToolTip");
|
||||
GetPropertyData(nameof(TraitorsMinPlayerCount)).AssignGUIComponent(traitorsMinPlayerCount);
|
||||
|
||||
var maximumTransferAmount = CreateLabeledNumberInput(roundsTab, "serversettingsmaximumtransferrequest", 0, CampaignMode.MaxMoney, "serversettingsmaximumtransferrequesttooltip");
|
||||
GetPropertyData(nameof(MaximumTransferRequest)).AssignGUIComponent(maximumTransferAmount);
|
||||
|
||||
var lootedMoneyDestination = CreateLabeledDropdown(roundsTab, "serversettingslootedmoneydestination", numElements: 2, "serversettingslootedmoneydestinationtooltip");
|
||||
lootedMoneyDestination.AddItem(TextManager.Get("lootedmoneydestination.bank"), LootedMoneyDestination.Bank);
|
||||
lootedMoneyDestination.AddItem(TextManager.Get("lootedmoneydestination.wallet"), LootedMoneyDestination.Wallet);
|
||||
GetPropertyData(nameof(LootedMoneyDestination)).AssignGUIComponent(lootedMoneyDestination);
|
||||
|
||||
var ragdollButtonBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), roundsTab.RectTransform), TextManager.Get("ServerSettingsAllowRagdollButton"));
|
||||
GetPropertyData(nameof(AllowRagdollButton)).AssignGUIComponent(ragdollButtonBox);
|
||||
|
||||
@@ -991,6 +999,32 @@ namespace Barotrauma.Networking
|
||||
return input;
|
||||
}
|
||||
|
||||
private GUIDropDown CreateLabeledDropdown(GUIComponent parent, string labelTag, int numElements, string toolTipTag = null)
|
||||
{
|
||||
var container = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), parent.RectTransform), isHorizontal: true)
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.05f,
|
||||
ToolTip = TextManager.Get(labelTag)
|
||||
};
|
||||
|
||||
var label = new GUITextBlock(new RectTransform(new Vector2(0.7f, 1.0f), container.RectTransform),
|
||||
TextManager.Get(labelTag), textAlignment: Alignment.CenterLeft, font: GUIStyle.SmallFont)
|
||||
{
|
||||
AutoScaleHorizontal = true
|
||||
};
|
||||
if (!string.IsNullOrEmpty(toolTipTag))
|
||||
{
|
||||
label.ToolTip = TextManager.Get(toolTipTag);
|
||||
}
|
||||
var input = new GUIDropDown(new RectTransform(new Vector2(0.3f, 1.0f), container.RectTransform), elementCount: numElements);
|
||||
|
||||
container.RectTransform.MinSize = new Point(0, input.RectTransform.MinSize.Y);
|
||||
container.RectTransform.MaxSize = new Point(int.MaxValue, input.RectTransform.MaxSize.Y);
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
private bool SelectSettingsTab(GUIButton button, object obj)
|
||||
{
|
||||
settingsTabIndex = (int)obj;
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace Barotrauma.Particles
|
||||
{
|
||||
return debugName;
|
||||
}
|
||||
public void Init(ParticlePrefab prefab, Vector2 position, Vector2 speed, float rotation, Hull hullGuess = null, bool drawOnTop = false, float collisionIgnoreTimer = 0f, Tuple<Vector2, Vector2> tracerPoints = null)
|
||||
public void Init(ParticlePrefab prefab, Vector2 position, Vector2 speed, float rotation, Hull hullGuess = null, bool drawOnTop = false, float collisionIgnoreTimer = 0f, float lifeTimeMultiplier = 1f, Tuple<Vector2, Vector2> tracerPoints = null)
|
||||
{
|
||||
this.prefab = prefab;
|
||||
#if DEBUG
|
||||
@@ -149,13 +149,13 @@ namespace Barotrauma.Particles
|
||||
|
||||
if (prefab.LifeTimeMin <= 0.0f)
|
||||
{
|
||||
totalLifeTime = prefab.LifeTime;
|
||||
lifeTime = prefab.LifeTime;
|
||||
totalLifeTime = prefab.LifeTime * lifeTimeMultiplier;
|
||||
lifeTime = prefab.LifeTime * lifeTimeMultiplier;
|
||||
}
|
||||
else
|
||||
{
|
||||
totalLifeTime = Rand.Range(prefab.LifeTimeMin, prefab.LifeTime);
|
||||
lifeTime = totalLifeTime;
|
||||
totalLifeTime = Rand.Range(prefab.LifeTimeMin, prefab.LifeTime) * lifeTimeMultiplier;
|
||||
lifeTime = totalLifeTime * lifeTimeMultiplier;
|
||||
}
|
||||
|
||||
startDelay = Rand.Range(prefab.StartDelayMin, prefab.StartDelayMax);
|
||||
|
||||
@@ -85,6 +85,9 @@ namespace Barotrauma.Particles
|
||||
[Editable, Serialize("1,1,1,1", IsPropertySaveable.Yes)]
|
||||
public Color ColorMultiplier { get; set; }
|
||||
|
||||
[Editable, Serialize(1f, IsPropertySaveable.Yes)]
|
||||
public float LifeTimeMultiplier { get; set; }
|
||||
|
||||
[Editable, Serialize(false, IsPropertySaveable.Yes)]
|
||||
public bool DrawOnTop { get; set; }
|
||||
|
||||
@@ -197,7 +200,7 @@ namespace Barotrauma.Particles
|
||||
position += dir * Rand.Range(Prefab.Properties.DistanceMin, Prefab.Properties.DistanceMax);
|
||||
}
|
||||
|
||||
var particle = GameMain.ParticleManager.CreateParticle(particlePrefab, position, velocity, particleRotation, hullGuess, Prefab.DrawOnTop, tracerPoints: tracerPoints);
|
||||
var particle = GameMain.ParticleManager.CreateParticle(particlePrefab, position, velocity, particleRotation, hullGuess, Prefab.DrawOnTop, lifeTimeMultiplier: Prefab.Properties.LifeTimeMultiplier, tracerPoints: tracerPoints);
|
||||
|
||||
if (particle != null)
|
||||
{
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Barotrauma.Particles
|
||||
return CreateParticle(prefab, position, velocity, rotation, hullGuess, collisionIgnoreTimer: collisionIgnoreTimer, tracerPoints:tracerPoints);
|
||||
}
|
||||
|
||||
public Particle CreateParticle(ParticlePrefab prefab, Vector2 position, Vector2 velocity, float rotation = 0.0f, Hull hullGuess = null, bool drawOnTop = false, float collisionIgnoreTimer = 0f, Tuple<Vector2, Vector2> tracerPoints = null)
|
||||
public Particle CreateParticle(ParticlePrefab prefab, Vector2 position, Vector2 velocity, float rotation = 0.0f, Hull hullGuess = null, bool drawOnTop = false, float collisionIgnoreTimer = 0f, float lifeTimeMultiplier = 1f, Tuple<Vector2, Vector2> tracerPoints = null)
|
||||
{
|
||||
if (prefab == null || prefab.Sprites.Count == 0) { return null; }
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace Barotrauma.Particles
|
||||
|
||||
if (particles[particleCount] == null) { particles[particleCount] = new Particle(); }
|
||||
|
||||
particles[particleCount].Init(prefab, position, velocity, rotation, hullGuess, drawOnTop, collisionIgnoreTimer, tracerPoints: tracerPoints);
|
||||
particles[particleCount].Init(prefab, position, velocity, rotation, hullGuess, drawOnTop, collisionIgnoreTimer, lifeTimeMultiplier, tracerPoints: tracerPoints);
|
||||
|
||||
particleCount++;
|
||||
|
||||
|
||||
@@ -77,9 +77,20 @@ namespace Barotrauma
|
||||
if (remoteContentDoc?.Root != null)
|
||||
{
|
||||
remoteContentContainer.ClearChildren();
|
||||
foreach (var subElement in remoteContentDoc.Root.Elements())
|
||||
try
|
||||
{
|
||||
GUIComponent.FromXML(subElement.FromPackage(null), remoteContentContainer.RectTransform);
|
||||
foreach (var subElement in remoteContentDoc.Root.Elements())
|
||||
{
|
||||
GUIComponent.FromXML(subElement.FromPackage(null), remoteContentContainer.RectTransform);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError("Reading received remote main menu content failed.", e);
|
||||
#endif
|
||||
GameAnalyticsManager.AddErrorEventOnce("MainMenuScreen.RemoteContentParse:Exception", GameAnalyticsManager.ErrorSeverity.Error,
|
||||
"Reading received remote main menu content failed. " + e.Message);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -20,10 +20,11 @@ namespace Barotrauma
|
||||
private ServerContentPackage? currentDownload;
|
||||
|
||||
private readonly List<ContentPackage> downloadedPackages = new List<ContentPackage>();
|
||||
public IEnumerable<ContentPackage> DownloadedPackages => downloadedPackages;
|
||||
|
||||
private bool confirmDownload;
|
||||
|
||||
private void Reset()
|
||||
public void Reset()
|
||||
{
|
||||
pendingDownloads.Clear();
|
||||
downloadedPackages.Clear();
|
||||
@@ -255,12 +256,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deselect()
|
||||
{
|
||||
Reset();
|
||||
base.Deselect();
|
||||
}
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
|
||||
@@ -1400,7 +1400,7 @@ namespace Barotrauma
|
||||
public void CreatePlayerFrame(GUIComponent parent, bool createPendingText = true, bool alwaysAllowEditing = false)
|
||||
{
|
||||
UpdatePlayerFrame(
|
||||
Character.Controlled?.Info ?? playerInfoContainer.Children?.First().UserData as CharacterInfo,
|
||||
Character.Controlled?.Info ?? playerInfoContainer.Children?.First().UserData as CharacterInfo ?? GameMain.Client.CharacterInfo,
|
||||
allowEditing: alwaysAllowEditing || campaignCharacterInfo == null,
|
||||
parent: parent,
|
||||
createPendingText: createPendingText);
|
||||
@@ -3131,10 +3131,11 @@ namespace Barotrauma
|
||||
retVal[i] = new GUIImage[outfitPreview.Sprites.Count];
|
||||
for (int j = 0; j < outfitPreview.Sprites.Count; j++)
|
||||
{
|
||||
Pair<Sprite, Vector2> sprite = outfitPreview.Sprites[j];
|
||||
Sprite sprite = outfitPreview.Sprites[j].sprite;
|
||||
Vector2 drawOffset = outfitPreview.Sprites[j].drawOffset;
|
||||
float aspectRatio = outfitPreview.Dimensions.Y / outfitPreview.Dimensions.X;
|
||||
retVal[i][j] = new GUIImage(new RectTransform(new Vector2(0.7f / aspectRatio, 0.7f), innerFrame.RectTransform, Anchor.Center)
|
||||
{ RelativeOffset = sprite.Second / outfitPreview.Dimensions }, sprite.First, scaleToFit: true)
|
||||
{ RelativeOffset = drawOffset / outfitPreview.Dimensions }, sprite, scaleToFit: true)
|
||||
{
|
||||
PressedColor = Color.White,
|
||||
CanBeFocused = false
|
||||
|
||||
@@ -1190,18 +1190,23 @@ namespace Barotrauma
|
||||
frame.RectTransform.MaxSize = new Point(int.MaxValue, frame.Rect.Width);
|
||||
|
||||
LocalizedString name = legacy ? TextManager.GetWithVariable("legacyitemformat", "[name]", ep.Name) : ep.Name;
|
||||
frame.ToolTip = ep.Description.IsNullOrEmpty() ? name : name + '\n' + ep.Description;
|
||||
frame.ToolTip = $"{frame.ToolTip}\n‖color:{XMLExtensions.ToStringHex(GUIStyle.TextColorBright)}‖{name}‖color:end‖";
|
||||
if (!ep.Description.IsNullOrEmpty())
|
||||
{
|
||||
frame.ToolTip += '\n' + ep.Description;
|
||||
}
|
||||
|
||||
if (ep.ContentPackage != GameMain.VanillaContent && ep.ContentPackage != null)
|
||||
{
|
||||
frame.Color = Color.Magenta;
|
||||
frame.ToolTip = RichString.Rich($"{frame.ToolTip}\n‖color:{XMLExtensions.ToStringHex(Color.MediumPurple)}‖{ep.ContentPackage?.Name}‖color:end‖");
|
||||
frame.ToolTip = $"{frame.ToolTip}\n‖color:{XMLExtensions.ToStringHex(Color.MediumPurple)}‖{ep.ContentPackage?.Name}‖color:end‖";
|
||||
}
|
||||
if (ep.HideInMenus)
|
||||
{
|
||||
frame.Color = Color.Red;
|
||||
name = "[HIDDEN] " + name;
|
||||
}
|
||||
frame.ToolTip = RichString.Rich(frame.ToolTip);
|
||||
|
||||
GUILayoutGroup paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.8f), frame.RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter)
|
||||
{
|
||||
@@ -1976,7 +1981,7 @@ namespace Barotrauma
|
||||
return true;
|
||||
};
|
||||
|
||||
nameBox.Text = subNameLabel?.Text?.SanitizedValue ?? "";
|
||||
nameBox.Text = MainSub?.Info.Name ?? "";
|
||||
|
||||
submarineNameCharacterCount.Text = nameBox.Text.Length + " / " + submarineNameLimit;
|
||||
|
||||
@@ -2750,6 +2755,8 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
nameBox.Text = nameBox.Text.Trim();
|
||||
|
||||
bool hideInMenus = nameBox.Parent.GetChildByUserData("hideinmenus") is GUITickBox hideInMenusTickBox && hideInMenusTickBox.Selected;
|
||||
string saveFolder = Path.Combine(ContentPackage.LocalModsDir, nameBox.Text);
|
||||
string filePath = Path.Combine(saveFolder, $"{nameBox.Text}.xml").CleanUpPathCrossPlatform();
|
||||
@@ -2884,8 +2891,30 @@ namespace Barotrauma
|
||||
{
|
||||
if (deleteButtonHolder.FindChild("delete") is GUIButton deleteBtn)
|
||||
{
|
||||
deleteBtn.Enabled = userData is SubmarineInfo subInfo
|
||||
&& GetContentPackageIntrinsicallyTiedToSub(subInfo) != null;
|
||||
deleteBtn.ToolTip = string.Empty;
|
||||
if (!(userData is SubmarineInfo subInfo))
|
||||
{
|
||||
deleteBtn.Enabled = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
var package = GetContentPackageIntrinsicallyTiedToSub(subInfo);
|
||||
if (package != null)
|
||||
{
|
||||
deleteBtn.Enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
deleteBtn.Enabled = false;
|
||||
if (ContentPackageManager.VanillaCorePackage?.Files.Any(f => f.Path == subInfo.FilePath) ?? false)
|
||||
{
|
||||
deleteBtn.ToolTip = TextManager.Get("cantdeletevanillasub");
|
||||
}
|
||||
else if (ContentPackageManager.AllPackages.FirstOrDefault(p => p.Files.Any(f => f.Path == subInfo.FilePath)) is ContentPackage subPackage)
|
||||
{
|
||||
deleteBtn.ToolTip = TextManager.GetWithVariable("cantdeletemodsub", "[modname]", subPackage.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -2925,6 +2954,21 @@ namespace Barotrauma
|
||||
ToolTip = sub.FilePath
|
||||
};
|
||||
|
||||
if (!(ContentPackageManager.VanillaCorePackage?.Files.Any(f => f.Path == sub.FilePath) ?? false))
|
||||
{
|
||||
if (GetContentPackageIntrinsicallyTiedToSub(sub) == null &&
|
||||
ContentPackageManager.AllPackages.FirstOrDefault(p => p.Files.Any(f => f.Path == sub.FilePath)) is ContentPackage subPackage)
|
||||
{
|
||||
//workshop mod
|
||||
textBlock.OverrideTextColor(Color.MediumPurple);
|
||||
}
|
||||
else
|
||||
{
|
||||
//local mod
|
||||
textBlock.OverrideTextColor(GUIStyle.TextColorBright);
|
||||
}
|
||||
}
|
||||
|
||||
if (sub.HasTag(SubmarineTag.Shuttle))
|
||||
{
|
||||
var shuttleText = new GUITextBlock(new RectTransform(new Vector2(0.2f, 1.0f), textBlock.RectTransform, Anchor.CenterRight),
|
||||
@@ -3037,6 +3081,24 @@ namespace Barotrauma
|
||||
if (!(child.UserData is SubmarineInfo sub)) { continue; }
|
||||
child.Visible = string.IsNullOrEmpty(filter) || sub.Name.ToLower().Contains(filter.ToLower());
|
||||
}
|
||||
|
||||
//go through the elements backwards, and disable the labels for sub categories if there's no subs visible in them
|
||||
bool subVisibleInCategory = false;
|
||||
foreach (GUIComponent child in subList.Content.Children.Reverse())
|
||||
{
|
||||
if (!(child.UserData is SubmarineInfo sub))
|
||||
{
|
||||
if (child.Enabled)
|
||||
{
|
||||
child.Visible = subVisibleInCategory;
|
||||
}
|
||||
subVisibleInCategory = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
subVisibleInCategory |= child.Visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -4828,7 +4890,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (GameSettings.CurrentConfig.KeyMap.Bindings[InputType.ToggleInventory].IsHit() && mode == Mode.Default)
|
||||
if (PlayerInput.KeyHit(Keys.Q) && mode == Mode.Default)
|
||||
{
|
||||
toggleEntityMenuButton.OnClicked?.Invoke(toggleEntityMenuButton, toggleEntityMenuButton.UserData);
|
||||
}
|
||||
|
||||
@@ -233,16 +233,18 @@ namespace Barotrauma
|
||||
|
||||
float dist = diff.Length();
|
||||
float distFallOff = dist / FlowSoundRange;
|
||||
if (distFallOff >= 0.99f) continue;
|
||||
if (distFallOff >= 0.99f) { continue; }
|
||||
|
||||
float gain = MathHelper.Clamp(gapFlow / 100.0f, 0.0f, 1.0f);
|
||||
|
||||
//flow at the left side
|
||||
if (diff.X < 0)
|
||||
{
|
||||
targetFlowLeft[flowSoundIndex] += 1.0f - distFallOff;
|
||||
targetFlowLeft[flowSoundIndex] += gain - distFallOff;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetFlowRight[flowSoundIndex] += 1.0f - distFallOff;
|
||||
targetFlowRight[flowSoundIndex] += gain - distFallOff;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -287,7 +289,7 @@ namespace Barotrauma
|
||||
flowSoundChannels[i] = FlowSounds[i].Sound.Play(1.0f, FlowSoundRange, soundPos);
|
||||
flowSoundChannels[i].Looping = true;
|
||||
}
|
||||
flowSoundChannels[i].Gain = Math.Min(Math.Max(flowVolumeRight[i], flowVolumeLeft[i]), 1.0f);
|
||||
flowSoundChannels[i].Gain = Math.Max(flowVolumeRight[i], flowVolumeLeft[i]);
|
||||
flowSoundChannels[i].Position = new Vector3(soundPos, 0.0f);
|
||||
}
|
||||
}
|
||||
@@ -853,7 +855,7 @@ namespace Barotrauma
|
||||
if (SplashSounds.Count == 0) { return; }
|
||||
int splashIndex = MathHelper.Clamp((int)(strength + Rand.Range(-2.0f, 2.0f)), 0, SplashSounds.Count - 1);
|
||||
float range = 800.0f;
|
||||
var channel = SplashSounds[splashIndex].Sound.Play(1.0f, range, worldPosition, muffle: ShouldMuffleSound(Character.Controlled, worldPosition, range, null));
|
||||
SplashSounds[splashIndex].Sound?.Play(1.0f, range, worldPosition, muffle: ShouldMuffleSound(Character.Controlled, worldPosition, range, null));
|
||||
}
|
||||
|
||||
public static void PlayDamageSound(string damageType, float damage, PhysicsBody body)
|
||||
|
||||
@@ -39,9 +39,8 @@ namespace Barotrauma
|
||||
get { return texture != null && !cannotBeLoaded; }
|
||||
}
|
||||
|
||||
public Sprite(Sprite other) : this(other.texture, other.sourceRect, other.offset, other.rotation)
|
||||
public Sprite(Sprite other) : this(other.texture, other.sourceRect, other.offset, other.rotation, other.FilePath.Value)
|
||||
{
|
||||
FilePath = other.FilePath;
|
||||
Compress = other.Compress;
|
||||
size = other.size;
|
||||
effects = other.effects;
|
||||
@@ -58,6 +57,17 @@ namespace Barotrauma
|
||||
rotation = newRotation;
|
||||
FilePath = ContentPath.FromRaw(path);
|
||||
AddToList(this);
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
Identifier fullPath = Path.GetFullPath(path).CleanUpPathCrossPlatform(correctFilenameCase: false).ToIdentifier();
|
||||
lock (list)
|
||||
{
|
||||
if (!textureRefCounts.TryAdd(fullPath, new TextureRefCounter { RefCount = 1, Texture = texture }))
|
||||
{
|
||||
textureRefCounts[fullPath].RefCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
partial void LoadTexture(ref Vector4 sourceVector, ref bool shouldReturn)
|
||||
|
||||
@@ -16,6 +16,8 @@ namespace Barotrauma.Steam
|
||||
{
|
||||
public static partial class Workshop
|
||||
{
|
||||
public const int MaxThumbnailSize = 1024 * 1024;
|
||||
|
||||
public static readonly ImmutableArray<Identifier> Tags = new []
|
||||
{
|
||||
"submarine",
|
||||
@@ -177,7 +179,7 @@ namespace Barotrauma.Steam
|
||||
|
||||
DeletePublishStagingCopy();
|
||||
Directory.CreateDirectory(PublishStagingDir);
|
||||
await CopyDirectory(contentPackage.Dir, contentPackage.Name, Path.GetDirectoryName(contentPackage.Path)!, PublishStagingDir);
|
||||
await CopyDirectory(contentPackage.Dir, contentPackage.Name, Path.GetDirectoryName(contentPackage.Path)!, PublishStagingDir, ShouldCorrectPaths.No);
|
||||
|
||||
//Load filelist.xml and write the hash into it so anyone downloading this mod knows what it should be
|
||||
ModProject modProject = new ModProject(contentPackage)
|
||||
@@ -218,7 +220,7 @@ namespace Barotrauma.Steam
|
||||
throw new Exception($"{newPath} already exists");
|
||||
}
|
||||
|
||||
await CopyDirectory(contentPackage.Dir, contentPackage.Name, Path.GetDirectoryName(contentPackage.Path)!, newPath);
|
||||
await CopyDirectory(contentPackage.Dir, contentPackage.Name, Path.GetDirectoryName(contentPackage.Path)!, newPath, ShouldCorrectPaths.Yes);
|
||||
|
||||
ModProject modProject = new ModProject(contentPackage);
|
||||
modProject.DiscardHashAndInstallTime();
|
||||
|
||||
@@ -197,6 +197,11 @@ namespace Barotrauma.Steam
|
||||
|
||||
FileSelection.OnFileSelected = (fn) =>
|
||||
{
|
||||
if (new FileInfo(fn).Length > SteamManager.Workshop.MaxThumbnailSize)
|
||||
{
|
||||
new GUIMessageBox(TextManager.Get("Error"), TextManager.Get("WorkshopItemPreviewImageTooLarge"));
|
||||
return;
|
||||
}
|
||||
thumbnailPath = fn;
|
||||
CreateLocalThumbnail(thumbnailPath, thumbnailContainer);
|
||||
};
|
||||
|
||||
@@ -119,6 +119,11 @@ namespace Barotrauma.Steam
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
new GUICustomComponent(new RectTransform(Vector2.Zero, searchHolder.RectTransform), onUpdate:
|
||||
(f, component) =>
|
||||
{
|
||||
searchTitle.RectTransform.NonScaledSize = searchBox.Frame.RectTransform.NonScaledSize;
|
||||
});
|
||||
searchBox.OnSelected += (sender, userdata) => { searchTitle.Visible = false; };
|
||||
searchBox.OnDeselected += (sender, userdata) => { searchTitle.Visible = searchBox.Text.IsNullOrWhiteSpace(); };
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ namespace Barotrauma
|
||||
private readonly int maxWidth;
|
||||
|
||||
private ScalableFont? cachedFont = null;
|
||||
private uint cachedFontSize = 0;
|
||||
|
||||
public LimitLString(LocalizedString text, GUIFont font, int maxWidth)
|
||||
{
|
||||
@@ -27,7 +26,6 @@ namespace Barotrauma
|
||||
{
|
||||
cachedValue = ToolBox.LimitString(nestedStr.Value, font.Value, maxWidth);
|
||||
cachedFont = font.Value;
|
||||
cachedFontSize = font.Size;
|
||||
UpdateLanguage();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,7 +404,7 @@ namespace Barotrauma
|
||||
|
||||
public static string LimitString(string str, ScalableFont font, int maxWidth)
|
||||
{
|
||||
if (maxWidth <= 0 || string.IsNullOrWhiteSpace(str)) return "";
|
||||
if (maxWidth <= 0 || string.IsNullOrWhiteSpace(str)) { return ""; }
|
||||
|
||||
float currWidth = font.MeasureString("...").X;
|
||||
for (int i = 0; i < str.Length; i++)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>0.17.15.0</Version>
|
||||
<Version>0.18.0.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>0.17.15.0</Version>
|
||||
<Version>0.18.0.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>0.17.15.0</Version>
|
||||
<Version>0.18.0.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
Reference in New Issue
Block a user