Unstable 0.1500.5.0 (almost forgor edition 💀)
This commit is contained in:
@@ -1,13 +1,201 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.IO;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class IdCard
|
||||
{
|
||||
public Sprite StoredPortrait;
|
||||
public Vector2 StoredSheetIndex;
|
||||
public JobPrefab StoredJobPrefab;
|
||||
public List<WearableSprite> StoredAttachments;
|
||||
public struct OwnerAppearance
|
||||
{
|
||||
public Sprite Portrait;
|
||||
public Vector2 SheetIndex;
|
||||
public JobPrefab JobPrefab;
|
||||
public List<WearableSprite> Attachments;
|
||||
public Color HairColor;
|
||||
public Color FacialHairColor;
|
||||
public Color SkinColor;
|
||||
|
||||
public void ExtractJobPrefab(string[] tags)
|
||||
{
|
||||
string jobIdTag = tags.FirstOrDefault(s => s.StartsWith("jobid:"));
|
||||
|
||||
if (jobIdTag != null && jobIdTag.Length > 6)
|
||||
{
|
||||
string jobId = jobIdTag.Substring(6);
|
||||
if (jobId != string.Empty)
|
||||
{
|
||||
JobPrefab = JobPrefab.Get(jobId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ExtractAppearance(CharacterInfo characterInfo, string[] tags)
|
||||
{
|
||||
Gender disguisedGender = Gender.None;
|
||||
Race disguisedRace = Race.None;
|
||||
int disguisedHeadSpriteId = -1;
|
||||
int disguisedHairIndex = -1;
|
||||
int disguisedBeardIndex = -1;
|
||||
int disguisedMoustacheIndex = -1;
|
||||
int disguisedFaceAttachmentIndex = -1;
|
||||
Color hairColor = Color.Black;
|
||||
Color facialHairColor = Color.Black;
|
||||
Color skinColor = Color.Black;
|
||||
|
||||
foreach (string tag in tags)
|
||||
{
|
||||
string[] s = tag.Split(':');
|
||||
|
||||
switch (s[0].ToLowerInvariant())
|
||||
{
|
||||
case "haircolor":
|
||||
hairColor = XMLExtensions.ParseColor(s[1]);
|
||||
break;
|
||||
|
||||
case "facialhaircolor":
|
||||
facialHairColor = XMLExtensions.ParseColor(s[1]);
|
||||
break;
|
||||
|
||||
case "skincolor":
|
||||
skinColor = XMLExtensions.ParseColor(s[1]);
|
||||
break;
|
||||
|
||||
case "gender":
|
||||
Enum.TryParse(s[1], ignoreCase: true, out disguisedGender);
|
||||
break;
|
||||
|
||||
case "race":
|
||||
Enum.TryParse(s[1], ignoreCase: true, out disguisedRace);
|
||||
break;
|
||||
|
||||
case "headspriteid":
|
||||
int.TryParse(s[1], NumberStyles.Any, CultureInfo.InvariantCulture, out disguisedHeadSpriteId);
|
||||
break;
|
||||
|
||||
case "hairindex":
|
||||
disguisedHairIndex = int.Parse(s[1]);
|
||||
break;
|
||||
|
||||
case "beardindex":
|
||||
disguisedBeardIndex = int.Parse(s[1]);
|
||||
break;
|
||||
|
||||
case "moustacheindex":
|
||||
disguisedMoustacheIndex = int.Parse(s[1]);
|
||||
break;
|
||||
|
||||
case "faceattachmentindex":
|
||||
disguisedFaceAttachmentIndex = int.Parse(s[1]);
|
||||
break;
|
||||
|
||||
case "sheetindex":
|
||||
string[] vectorValues = s[1].Split(";");
|
||||
SheetIndex = new Vector2(float.Parse(vectorValues[0]), float.Parse(vectorValues[1]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((characterInfo.HasGenders && disguisedGender == Gender.None)
|
||||
|| (characterInfo.HasRaces && disguisedRace == Race.None)
|
||||
|| disguisedHeadSpriteId <= 0)
|
||||
{
|
||||
Portrait = null;
|
||||
Attachments = null;
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (XElement limbElement in characterInfo.Ragdoll.MainElement.Elements())
|
||||
{
|
||||
if (!limbElement.GetAttributeString("type", "").Equals("head", StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||
|
||||
XElement spriteElement = limbElement.Element("sprite");
|
||||
if (spriteElement == null) { continue; }
|
||||
|
||||
string spritePath = spriteElement.Attribute("texture").Value;
|
||||
|
||||
spritePath = spritePath.Replace("[GENDER]", disguisedGender.ToString().ToLowerInvariant());
|
||||
spritePath = spritePath.Replace("[RACE]", disguisedRace.ToString().ToLowerInvariant());
|
||||
spritePath = spritePath.Replace("[HEADID]", disguisedHeadSpriteId.ToString());
|
||||
|
||||
string fileName = Path.GetFileNameWithoutExtension(spritePath);
|
||||
|
||||
//go through the files in the directory to find a matching sprite
|
||||
foreach (string file in Directory.GetFiles(Path.GetDirectoryName(spritePath)))
|
||||
{
|
||||
if (!file.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
string fileWithoutTags = Path.GetFileNameWithoutExtension(file);
|
||||
fileWithoutTags = fileWithoutTags.Split('[', ']').First();
|
||||
if (fileWithoutTags != fileName) { continue; }
|
||||
Portrait = new Sprite(spriteElement, "", file) { RelativeOrigin = Vector2.Zero };
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (characterInfo.Wearables != null)
|
||||
{
|
||||
float baldnessChance = disguisedGender == Gender.Female ? 0.05f : 0.2f;
|
||||
|
||||
List<XElement> createElementList(WearableType wearableType, float emptyCommonness = 1.0f)
|
||||
=> CharacterInfo.AddEmpty(
|
||||
characterInfo.FilterByTypeAndHeadID(
|
||||
characterInfo.FilterElementsByGenderAndRace(characterInfo.Wearables, disguisedGender, disguisedRace),
|
||||
wearableType, disguisedHeadSpriteId),
|
||||
wearableType, emptyCommonness);
|
||||
|
||||
var disguisedHairs = createElementList(WearableType.Hair, baldnessChance);
|
||||
var disguisedBeards = createElementList(WearableType.Beard);
|
||||
var disguisedMoustaches = createElementList(WearableType.Moustache);
|
||||
var disguisedFaceAttachments = createElementList(WearableType.FaceAttachment);
|
||||
|
||||
XElement getElementFromList(List<XElement> list, int index)
|
||||
=> CharacterInfo.IsValidIndex(index, list)
|
||||
? list[index]
|
||||
: characterInfo.GetRandomElement(list);
|
||||
|
||||
var disguisedHairElement = getElementFromList(disguisedHairs, disguisedHairIndex);
|
||||
var disguisedBeardElement = getElementFromList(disguisedBeards, disguisedBeardIndex);
|
||||
var disguisedMoustacheElement = getElementFromList(disguisedMoustaches, disguisedMoustacheIndex);
|
||||
var disguisedFaceAttachmentElement = getElementFromList(disguisedFaceAttachments, disguisedFaceAttachmentIndex);
|
||||
|
||||
Attachments = new List<WearableSprite>();
|
||||
|
||||
void loadAttachments(List<WearableSprite> attachments, XElement element, WearableType wearableType)
|
||||
{
|
||||
foreach (var s in element?.Elements("sprite") ?? Enumerable.Empty<XElement>())
|
||||
{
|
||||
attachments.Add(new WearableSprite(s, wearableType));
|
||||
}
|
||||
}
|
||||
|
||||
loadAttachments(Attachments, disguisedFaceAttachmentElement, WearableType.FaceAttachment);
|
||||
loadAttachments(Attachments, disguisedBeardElement, WearableType.Beard);
|
||||
loadAttachments(Attachments, disguisedMoustacheElement, WearableType.Moustache);
|
||||
loadAttachments(Attachments, disguisedHairElement, WearableType.Hair);
|
||||
|
||||
loadAttachments(Attachments,
|
||||
characterInfo.OmitJobInPortraitClothing
|
||||
? JobPrefab.NoJobElement?.Element("PortraitClothing")
|
||||
: JobPrefab?.ClothingElement,
|
||||
WearableType.JobIndicator);
|
||||
}
|
||||
|
||||
HairColor = hairColor;
|
||||
FacialHairColor = facialHairColor;
|
||||
SkinColor = skinColor;
|
||||
}
|
||||
}
|
||||
|
||||
public OwnerAppearance StoredOwnerAppearance = default;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,7 +289,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else
|
||||
{
|
||||
Matrix transform = Matrix.CreateRotationZ(item.body.Rotation);
|
||||
Matrix transform = Matrix.CreateRotationZ(item.body.DrawRotation);
|
||||
if (item.body.Dir == -1.0f)
|
||||
{
|
||||
transformedItemPos.X = -transformedItemPos.X;
|
||||
@@ -300,7 +300,7 @@ namespace Barotrauma.Items.Components
|
||||
transformedItemPos = Vector2.Transform(transformedItemPos, transform);
|
||||
transformedItemInterval = Vector2.Transform(transformedItemInterval, transform);
|
||||
transformedItemIntervalHorizontal = Vector2.Transform(transformedItemIntervalHorizontal, transform);
|
||||
transformedItemPos += item.DrawPosition;
|
||||
transformedItemPos += item.body.DrawPosition;
|
||||
}
|
||||
|
||||
Vector2 currentItemPos = transformedItemPos;
|
||||
|
||||
@@ -380,9 +380,20 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (requiredItem.UseCondition && requiredItem.MinCondition < 1.0f)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(slotRect.X, slotRect.Bottom - 8, slotRect.Width, 8), Color.Black * 0.8f, true);
|
||||
DrawConditionBar(spriteBatch, requiredItem.MinCondition);
|
||||
}
|
||||
else if (requiredItem.MaxCondition < 1.0f)
|
||||
{
|
||||
DrawConditionBar(spriteBatch, requiredItem.MaxCondition);
|
||||
}
|
||||
|
||||
void DrawConditionBar(SpriteBatch sb, float condition)
|
||||
{
|
||||
int spacing = GUI.IntScale(4);
|
||||
int height = GUI.IntScale(10);
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(slotRect.X + spacing, slotRect.Bottom - spacing - height, slotRect.Width - spacing * 2, height), Color.Black * 0.8f, true);
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Rectangle(slotRect.X, slotRect.Bottom - 8, (int)(slotRect.Width * requiredItem.MinCondition), 8),
|
||||
new Rectangle(slotRect.X + spacing, slotRect.Bottom - spacing - height, (int)((slotRect.Width - spacing * 2) * condition), height),
|
||||
GUI.Style.Green * 0.8f, true);
|
||||
}
|
||||
|
||||
@@ -395,6 +406,10 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
toolTipText += " " + (int)Math.Round(requiredItem.MinCondition * 100) + "%";
|
||||
}
|
||||
else if(requiredItem.MaxCondition < 1.0f)
|
||||
{
|
||||
toolTipText += " 0-" + (int)Math.Round(requiredItem.MaxCondition * 100) + "%";
|
||||
}
|
||||
else if (requiredItem.MaxCondition <= 0.0f)
|
||||
{
|
||||
toolTipText = TextManager.GetWithVariable("displayname.emptyitem", "[itemname]", toolTipText);
|
||||
@@ -649,8 +664,13 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
foreach (GUIComponent child in itemList.Content.Children)
|
||||
{
|
||||
var itemPrefab = child.UserData as FabricationRecipe;
|
||||
if (itemPrefab == null) continue;
|
||||
if (!(child.UserData is FabricationRecipe itemPrefab)) { continue; }
|
||||
|
||||
if (itemPrefab != selectedItem &&
|
||||
(child.Rect.Y > itemList.Rect.Bottom || child.Rect.Bottom < itemList.Rect.Y))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool canBeFabricated = CanBeFabricated(itemPrefab, availableIngredients, character);
|
||||
if (itemPrefab == selectedItem)
|
||||
|
||||
@@ -132,7 +132,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private bool isConnectedToSteering;
|
||||
|
||||
private static string caveLabel;
|
||||
private static string caveLabel, ruinLabel;
|
||||
|
||||
private bool AllowUsingMineralScanner =>
|
||||
HasMineralScanner && !isConnectedToSteering;
|
||||
@@ -880,7 +880,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
foreach (AITarget aiTarget in AITarget.List)
|
||||
{
|
||||
if (!aiTarget.Enabled) { continue; }
|
||||
if (aiTarget.InDetectable) { continue; }
|
||||
if (string.IsNullOrEmpty(aiTarget.SonarLabel) || aiTarget.SoundRange <= 0.0f) { continue; }
|
||||
|
||||
if (Vector2.DistanceSquared(aiTarget.WorldPosition, transducerCenter) < aiTarget.SoundRange * aiTarget.SoundRange)
|
||||
@@ -1234,7 +1234,7 @@ namespace Barotrauma.Items.Components
|
||||
foreach (AITarget aiTarget in AITarget.List)
|
||||
{
|
||||
float disruption = aiTarget.Entity is Character c ? c.Params.SonarDisruption : aiTarget.SonarDisruption;
|
||||
if (disruption <= 0.0f || !aiTarget.Enabled) { continue; }
|
||||
if (disruption <= 0.0f || aiTarget.InDetectable) { continue; }
|
||||
float distSqr = Vector2.DistanceSquared(aiTarget.WorldPosition, pingSource);
|
||||
if (distSqr > worldPingRadiusSqr) { continue; }
|
||||
float disruptionDist = (float)Math.Sqrt(distSqr);
|
||||
@@ -1359,28 +1359,6 @@ namespace Barotrauma.Items.Components
|
||||
blipType : cell.IsDestructible ? BlipType.Destructible : BlipType.Default);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (RuinGeneration.Ruin ruin in Level.Loaded.Ruins)
|
||||
{
|
||||
if (!MathUtils.CircleIntersectsRectangle(pingSource, range, ruin.Area)) continue;
|
||||
|
||||
foreach (var ruinShape in ruin.RuinShapes)
|
||||
{
|
||||
foreach (RuinGeneration.Line wall in ruinShape.Walls)
|
||||
{
|
||||
float cellDot = Vector2.Dot(
|
||||
Vector2.Normalize(ruinShape.Center - pingSource),
|
||||
Vector2.Normalize((wall.A + wall.B) / 2.0f - ruinShape.Center));
|
||||
if (cellDot > 0) continue;
|
||||
|
||||
CreateBlipsForLine(
|
||||
wall.A, wall.B,
|
||||
pingSource, transducerPos,
|
||||
pingRadius, prevPingRadius,
|
||||
100.0f, 1000.0f, range, pingStrength, passive);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Item item in Item.ItemList)
|
||||
|
||||
@@ -21,6 +21,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private GUITextBlock progressBarOverlayText;
|
||||
|
||||
private GUILayoutGroup extraButtonContainer;
|
||||
|
||||
private readonly List<ParticleEmitter> particleEmitters = new List<ParticleEmitter>();
|
||||
//the corresponding particle emitter is active when the condition is within this range
|
||||
private readonly List<Vector2> particleEmitterConditionRanges = new List<Vector2>();
|
||||
@@ -145,10 +147,16 @@ namespace Barotrauma.Items.Components
|
||||
progressBarHolder.RectTransform.MinSize = RepairButton.RectTransform.MinSize;
|
||||
RepairButton.RectTransform.MinSize = new Point((int)(RepairButton.TextBlock.TextSize.X * 1.2f), RepairButton.RectTransform.MinSize.Y);
|
||||
|
||||
extraButtonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), paddedFrame.RectTransform), isHorizontal: true)
|
||||
{
|
||||
IgnoreLayoutGroups = true,
|
||||
Stretch = true,
|
||||
AbsoluteSpacing = GUI.IntScale(5)
|
||||
};
|
||||
|
||||
sabotageButtonText = TextManager.Get("SabotageButton");
|
||||
sabotagingText = TextManager.Get("Sabotaging");
|
||||
SabotageButton = new GUIButton(new RectTransform(new Vector2(0.8f, 0.15f), paddedFrame.RectTransform, Anchor.BottomCenter), sabotageButtonText, style: "GUIButtonSmall")
|
||||
SabotageButton = new GUIButton(new RectTransform(Vector2.One, extraButtonContainer.RectTransform), sabotageButtonText, style: "GUIButtonSmall")
|
||||
{
|
||||
IgnoreLayoutGroups = true,
|
||||
Visible = false,
|
||||
@@ -160,9 +168,9 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
};
|
||||
|
||||
tinkerButtonText = "Tinker";
|
||||
tinkeringText = "Tinkering";
|
||||
TinkerButton = new GUIButton(new RectTransform(new Vector2(0.8f, 0.15f), paddedFrame.RectTransform, Anchor.BottomCenter), tinkerButtonText)
|
||||
tinkerButtonText = TextManager.Get("TinkerButton", returnNull: true) ?? "Tinker";
|
||||
tinkeringText = TextManager.Get("Tinkering", returnNull: true) ?? "Tinkering";
|
||||
TinkerButton = new GUIButton(new RectTransform(Vector2.One, extraButtonContainer.RectTransform), tinkerButtonText, style: "GUIButtonSmall")
|
||||
{
|
||||
IgnoreLayoutGroups = true,
|
||||
Visible = false,
|
||||
@@ -173,6 +181,8 @@ namespace Barotrauma.Items.Components
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
extraButtonContainer.RectTransform.MinSize = new Point(0, SabotageButton.RectTransform.MinSize.Y);
|
||||
}
|
||||
|
||||
partial void UpdateProjSpecific(float deltaTime)
|
||||
@@ -274,6 +284,10 @@ namespace Barotrauma.Items.Components
|
||||
tinkeringText + new string('.', ((int)(Timing.TotalTime * 2.0f) % 3) + 1);
|
||||
|
||||
System.Diagnostics.Debug.Assert(GuiFrame.GetChild(0) is GUILayoutGroup, "Repair UI hierarchy has changed, could not find skill texts");
|
||||
|
||||
extraButtonContainer.Visible = SabotageButton.Visible || TinkerButton.Visible;
|
||||
extraButtonContainer.IgnoreLayoutGroups = !extraButtonContainer.Visible;
|
||||
|
||||
foreach (GUIComponent c in GuiFrame.GetChild(0).Children)
|
||||
{
|
||||
if (!(c.UserData is Skill skill)) continue;
|
||||
|
||||
@@ -31,6 +31,9 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize("0.5,0.5)", false)]
|
||||
public Vector2 Origin { get; set; } = new Vector2(0.5f, 0.5f);
|
||||
|
||||
public Vector2 DrawSize
|
||||
{
|
||||
get
|
||||
@@ -57,7 +60,6 @@ namespace Barotrauma.Items.Components
|
||||
sourcePos = sourceLimb.body.DrawPosition;
|
||||
}
|
||||
return sourcePos;
|
||||
|
||||
}
|
||||
|
||||
partial void InitProjSpecific(XElement element)
|
||||
@@ -87,7 +89,8 @@ namespace Barotrauma.Items.Components
|
||||
startPos.Y = -startPos.Y;
|
||||
if (source is Item sourceItem)
|
||||
{
|
||||
var turret = sourceItem?.GetComponent<Turret>();
|
||||
var turret = sourceItem.GetComponent<Turret>();
|
||||
var weapon = sourceItem.GetComponent<RangedWeapon>();
|
||||
if (turret != null)
|
||||
{
|
||||
startPos = new Vector2(sourceItem.WorldRect.X + turret.TransformedBarrelPos.X, -(sourceItem.WorldRect.Y - turret.TransformedBarrelPos.Y));
|
||||
@@ -96,8 +99,21 @@ namespace Barotrauma.Items.Components
|
||||
startPos += new Vector2((float)Math.Cos(turret.Rotation), (float)Math.Sin(turret.Rotation)) * turret.BarrelSprite.size.Y * turret.BarrelSprite.RelativeOrigin.Y * item.Scale * 0.9f;
|
||||
}
|
||||
}
|
||||
else if (weapon != null)
|
||||
{
|
||||
Vector2 barrelPos = FarseerPhysics.ConvertUnits.ToDisplayUnits(weapon.TransformedBarrelPos);
|
||||
barrelPos.Y = -barrelPos.Y;
|
||||
startPos += barrelPos * item.Scale;
|
||||
}
|
||||
}
|
||||
Vector2 endPos = new Vector2(target.DrawPosition.X, -target.DrawPosition.Y);
|
||||
Vector2 endPos = new Vector2(target.DrawPosition.X, target.DrawPosition.Y);
|
||||
Vector2 flippedPos = target.Sprite.size * target.Scale * (Origin - new Vector2(0.5f));
|
||||
if (target.body.Dir < 0.0f)
|
||||
{
|
||||
flippedPos.X = -flippedPos.X;
|
||||
}
|
||||
endPos += Vector2.Transform(flippedPos, Matrix.CreateRotationZ(target.body.Rotation));
|
||||
endPos.Y = -endPos.Y;
|
||||
|
||||
if (Snapped)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
using Barotrauma.Networking;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class Scanner : ItemComponent, IServerSerializable
|
||||
{
|
||||
partial void UpdateProjSpecific()
|
||||
{
|
||||
if (Holdable != null && Holdable.Attached && (AlwaysDisplayProgressBar || DisplayProgressBar) && !IsScanCompleted)
|
||||
{
|
||||
Character.Controlled?.UpdateHUDProgressBar(this,
|
||||
item.WorldPosition,
|
||||
ScanTimer / ScanDuration,
|
||||
GUI.Style.Red, GUI.Style.Green,
|
||||
textTag: "progressbar.scanning");
|
||||
}
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
{
|
||||
bool wasScanCompletedPreviously = IsScanCompleted;
|
||||
scanTimer = msg.ReadSingle();
|
||||
if (!wasScanCompletedPreviously && IsScanCompleted)
|
||||
{
|
||||
OnScanCompleted?.Invoke(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class ButtonTerminal : ItemComponent, IClientSerializable, IServerSerializable
|
||||
{
|
||||
private string[] terminalButtonStyles;
|
||||
private GUIFrame containerHolder;
|
||||
private GUIImage containerIndicator;
|
||||
private GUIComponentStyle indicatorStyleRed, indicatorStyleGreen;
|
||||
|
||||
partial void InitProjSpecific(XElement element)
|
||||
{
|
||||
terminalButtonStyles = new string[RequiredSignalCount];
|
||||
int i = 0;
|
||||
foreach (var childElement in element.GetChildElements("TerminalButton"))
|
||||
{
|
||||
string style = childElement.GetAttributeString("style", null);
|
||||
if (style == null) { continue; }
|
||||
terminalButtonStyles[i++] = style;
|
||||
}
|
||||
indicatorStyleRed = GUI.Style.GetComponentStyle("IndicatorLightRed");
|
||||
indicatorStyleGreen = GUI.Style.GetComponentStyle("IndicatorLightGreen");
|
||||
CreateGUI();
|
||||
}
|
||||
|
||||
protected override void CreateGUI()
|
||||
{
|
||||
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.8f), GuiFrame.RectTransform, Anchor.Center), isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.08f
|
||||
};
|
||||
paddedFrame.OnAddedToGUIUpdateList += (component) =>
|
||||
{
|
||||
bool buttonsEnabled = AllowUsingButtons;
|
||||
foreach (var child in component.Children)
|
||||
{
|
||||
if (!(child is GUIButton)) { continue; }
|
||||
if (!(child.UserData is int)) { continue; }
|
||||
child.Enabled = buttonsEnabled;
|
||||
child.Children.ForEach(c => c.Enabled = buttonsEnabled);
|
||||
}
|
||||
bool itemsContained = Container.Inventory.AllItems.Any();
|
||||
if (itemsContained)
|
||||
{
|
||||
var indicatorStyle = buttonsEnabled ? indicatorStyleGreen : indicatorStyleRed;
|
||||
if (containerIndicator.Style != indicatorStyle)
|
||||
{
|
||||
containerIndicator.ApplyStyle(indicatorStyle);
|
||||
}
|
||||
}
|
||||
containerIndicator.OverrideState = itemsContained ? GUIComponent.ComponentState.Selected : GUIComponent.ComponentState.None;
|
||||
};
|
||||
|
||||
float x = 1.0f / (1 + RequiredSignalCount);
|
||||
float y = (x * paddedFrame.Rect.Width) / paddedFrame.Rect.Height;
|
||||
Vector2 relativeSize = new Vector2(x, y);
|
||||
|
||||
var containerSection = new GUIFrame(new RectTransform(new Vector2(x, 1.0f), paddedFrame.RectTransform), style: null);
|
||||
var containerSlot = new GUIFrame(new RectTransform(new Vector2(1.0f, y), containerSection.RectTransform, anchor: Anchor.Center), style: null);
|
||||
containerHolder = new GUIFrame(new RectTransform(new Vector2(1f, 1.2f), containerSlot.RectTransform, Anchor.BottomCenter), style: null);
|
||||
containerIndicator = new GUIImage(new RectTransform(new Vector2(0.5f, 0.5f * y), containerSection.RectTransform, anchor: Anchor.Center) { RelativeOffset = new Vector2(0.0f, 0.05f + 0.5f * y) },
|
||||
style: "IndicatorLightRed", scaleToFit: true);
|
||||
|
||||
for (int i = 0; i < RequiredSignalCount; i++)
|
||||
{
|
||||
var button = new GUIButton(new RectTransform(relativeSize, paddedFrame.RectTransform), style: null)
|
||||
{
|
||||
UserData = i,
|
||||
OnClicked = (button, userData) =>
|
||||
{
|
||||
if (GameMain.IsSingleplayer)
|
||||
{
|
||||
SendSignal((int)userData);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.CreateClientEvent(this, new object[] { userData });
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
var image = new GUIImage(new RectTransform(Vector2.One, button.RectTransform), terminalButtonStyles[i], scaleToFit: true);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnResolutionChanged()
|
||||
{
|
||||
base.OnResolutionChanged();
|
||||
OnItemLoadedProjSpecific();
|
||||
}
|
||||
|
||||
partial void OnItemLoadedProjSpecific()
|
||||
{
|
||||
Container.AllowUIOverlap = true;
|
||||
Container.Inventory.RectTransform = containerHolder.RectTransform;
|
||||
}
|
||||
|
||||
public void ClientWrite(IWriteMessage msg, object[] extraData = null)
|
||||
{
|
||||
Write(msg, extraData);
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
{
|
||||
SendSignal(msg.ReadRangedInteger(0, Signals.Length - 1), isServerMessage: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user