Unstable 0.1500.4.0 (Shrek edition)
This commit is contained in:
@@ -23,12 +23,30 @@ namespace Barotrauma
|
||||
private Sprite disguisedJobIcon;
|
||||
private Color disguisedJobColor;
|
||||
|
||||
private Sprite tintMask;
|
||||
private float tintHighlightThreshold;
|
||||
private float tintHighlightMultiplier;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
infoAreaPortraitBG = GUI.Style.GetComponentStyle("InfoAreaPortraitBG")?.GetDefaultSprite();
|
||||
new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(833, 298, 142, 98), null, 0);
|
||||
}
|
||||
|
||||
partial void LoadHeadSpriteProjectSpecific(XElement limbElement)
|
||||
{
|
||||
XElement maskElement = limbElement.Element("tintmask");
|
||||
if (maskElement != null)
|
||||
{
|
||||
string tintMaskPath = maskElement.GetAttributeString("texture", "");
|
||||
if (!string.IsNullOrWhiteSpace(tintMaskPath))
|
||||
{
|
||||
tintMask = new Sprite(maskElement, file: Limb.GetSpritePath(tintMaskPath, this));
|
||||
tintHighlightThreshold = maskElement.GetAttributeFloat("highlightthreshold", 0.6f);
|
||||
tintHighlightMultiplier = maskElement.GetAttributeFloat("highlightmultiplier", 0.8f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public GUIComponent CreateInfoFrame(GUIFrame frame, bool returnParent, Sprite permissionIcon = null)
|
||||
{
|
||||
@@ -458,6 +476,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO: disguise skin and hair colors
|
||||
sheetIndex = disguisedSheetIndex;
|
||||
portraitToDraw = disguisedPortrait;
|
||||
attachmentsToDraw = disguisedAttachmentSprites;
|
||||
@@ -465,22 +484,74 @@ namespace Barotrauma
|
||||
|
||||
if (portraitToDraw != null)
|
||||
{
|
||||
var currEffect = spriteBatch.GetCurrentEffect();
|
||||
// Scale down the head sprite 10%
|
||||
float scale = targetWidth * 0.9f / Portrait.size.X;
|
||||
if (sheetIndex.HasValue)
|
||||
{
|
||||
SetHeadEffect(spriteBatch);
|
||||
portraitToDraw.SourceRect = new Rectangle(CalculateOffset(portraitToDraw, sheetIndex.Value.ToPoint()), portraitToDraw.SourceRect.Size);
|
||||
}
|
||||
portraitToDraw.Draw(spriteBatch, screenPos + offset, Color.White, portraitToDraw.Origin, scale: scale, spriteEffect: flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None);
|
||||
portraitToDraw.Draw(spriteBatch, screenPos + offset, SkinColor, portraitToDraw.Origin, scale: scale, spriteEffect: flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None);
|
||||
if (attachmentsToDraw != null)
|
||||
{
|
||||
float depthStep = 0.000001f;
|
||||
foreach (var attachment in attachmentsToDraw)
|
||||
{
|
||||
DrawAttachmentSprite(spriteBatch, attachment, portraitToDraw, sheetIndex, screenPos + offset, scale, depthStep, flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None);
|
||||
SetAttachmentEffect(spriteBatch, attachment);
|
||||
DrawAttachmentSprite(spriteBatch, attachment, portraitToDraw, sheetIndex, screenPos + offset, scale, depthStep, GetAttachmentColor(attachment), flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None);
|
||||
depthStep += depthStep;
|
||||
}
|
||||
}
|
||||
spriteBatch.SwapEffect(currEffect);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: I hate this so much :(
|
||||
private SpriteBatch.EffectWithParams headEffectParameters;
|
||||
private Dictionary<WearableType, SpriteBatch.EffectWithParams> attachmentEffectParameters
|
||||
= new Dictionary<WearableType, SpriteBatch.EffectWithParams>();
|
||||
|
||||
private void SetHeadEffect(SpriteBatch spriteBatch)
|
||||
{
|
||||
headEffectParameters.Effect ??= GameMain.GameScreen.ThresholdTintEffect;
|
||||
headEffectParameters.Params ??= new Dictionary<string, object>();
|
||||
headEffectParameters.Params["xBaseTexture"] = headSprite.Texture;
|
||||
headEffectParameters.Params["xTintMaskTexture"] = tintMask?.Texture ?? GUI.WhiteTexture;
|
||||
headEffectParameters.Params["xCutoffTexture"] = GUI.WhiteTexture;
|
||||
headEffectParameters.Params["baseToCutoffSizeRatio"] = 1.0f;
|
||||
headEffectParameters.Params["highlightThreshold"] = tintHighlightThreshold;
|
||||
headEffectParameters.Params["highlightMultiplier"] = tintHighlightMultiplier;
|
||||
spriteBatch.SwapEffect(headEffectParameters);
|
||||
}
|
||||
|
||||
private void SetAttachmentEffect(SpriteBatch spriteBatch, WearableSprite attachment)
|
||||
{
|
||||
if (!attachmentEffectParameters.ContainsKey(attachment.Type))
|
||||
{
|
||||
attachmentEffectParameters.Add(attachment.Type, new SpriteBatch.EffectWithParams(GameMain.GameScreen.ThresholdTintEffect, new Dictionary<string, object>()));
|
||||
}
|
||||
var parameters = attachmentEffectParameters[attachment.Type].Params;
|
||||
parameters["xBaseTexture"] = attachment.Sprite.Texture;
|
||||
parameters["xTintMaskTexture"] = GUI.WhiteTexture;
|
||||
parameters["xCutoffTexture"] = GUI.WhiteTexture;
|
||||
parameters["baseToCutoffSizeRatio"] = 1.0f;
|
||||
parameters["highlightThreshold"] = tintHighlightThreshold;
|
||||
parameters["highlightMultiplier"] = tintHighlightMultiplier;
|
||||
spriteBatch.SwapEffect(attachmentEffectParameters[attachment.Type]);
|
||||
}
|
||||
|
||||
private Color GetAttachmentColor(WearableSprite attachment)
|
||||
{
|
||||
switch (attachment.Type)
|
||||
{
|
||||
case WearableType.Hair:
|
||||
return HairColor;
|
||||
case WearableType.Beard:
|
||||
case WearableType.Moustache:
|
||||
return FacialHairColor;
|
||||
default:
|
||||
return Color.White;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,34 +560,28 @@ namespace Barotrauma
|
||||
var headSprite = HeadSprite;
|
||||
if (headSprite != null)
|
||||
{
|
||||
var currEffect = spriteBatch.GetCurrentEffect();
|
||||
float scale = Math.Min(targetAreaSize.X / headSprite.size.X, targetAreaSize.Y / headSprite.size.Y);
|
||||
if (Head.SheetIndex.HasValue)
|
||||
{
|
||||
headSprite.SourceRect = new Rectangle(CalculateOffset(headSprite, Head.SheetIndex.Value.ToPoint()), headSprite.SourceRect.Size);
|
||||
}
|
||||
headSprite.Draw(spriteBatch, screenPos, scale: scale);
|
||||
SetHeadEffect(spriteBatch);
|
||||
headSprite.Draw(spriteBatch, screenPos, scale: scale, color: SkinColor);
|
||||
if (AttachmentSprites != null)
|
||||
{
|
||||
float depthStep = 0.000001f;
|
||||
foreach (var attachment in AttachmentSprites)
|
||||
{
|
||||
DrawAttachmentSprite(spriteBatch, attachment, headSprite, Head.SheetIndex, screenPos, scale, depthStep);
|
||||
SetAttachmentEffect(spriteBatch, attachment);
|
||||
DrawAttachmentSprite(spriteBatch, attachment, headSprite, Head.SheetIndex, screenPos, scale, depthStep, GetAttachmentColor(attachment));
|
||||
depthStep += depthStep;
|
||||
}
|
||||
}
|
||||
spriteBatch.SwapEffect(currEffect);
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawJobIcon(SpriteBatch spriteBatch, Vector2 pos, float scale = 1.0f, bool evaluateDisguise = false)
|
||||
{
|
||||
if (evaluateDisguise && IsDisguised) return;
|
||||
var icon = !IsDisguisedAsAnother || !evaluateDisguise ? Job?.Prefab?.Icon : disguisedJobIcon;
|
||||
if (icon == null) { return; }
|
||||
Color iconColor = !IsDisguisedAsAnother || !evaluateDisguise ? Job.Prefab.UIColor : disguisedJobColor;
|
||||
|
||||
icon.Draw(spriteBatch, pos, iconColor, scale: scale);
|
||||
}
|
||||
|
||||
public void DrawJobIcon(SpriteBatch spriteBatch, Rectangle area, bool evaluateDisguise = false)
|
||||
{
|
||||
if (evaluateDisguise && IsDisguised) return;
|
||||
@@ -527,7 +592,7 @@ namespace Barotrauma
|
||||
icon.Draw(spriteBatch, area.Center.ToVector2(), iconColor, scale: Math.Min(area.Width / (float)icon.SourceRect.Width, area.Height / (float)icon.SourceRect.Height));
|
||||
}
|
||||
|
||||
private void DrawAttachmentSprite(SpriteBatch spriteBatch, WearableSprite attachment, Sprite head, Vector2? sheetIndex, Vector2 drawPos, float scale, float depthStep, SpriteEffects spriteEffects = SpriteEffects.None)
|
||||
private void DrawAttachmentSprite(SpriteBatch spriteBatch, WearableSprite attachment, Sprite head, Vector2? sheetIndex, Vector2 drawPos, float scale, float depthStep, Color? color = null, SpriteEffects spriteEffects = SpriteEffects.None)
|
||||
{
|
||||
if (attachment.InheritSourceRect)
|
||||
{
|
||||
@@ -544,7 +609,7 @@ namespace Barotrauma
|
||||
attachment.Sprite.SourceRect = head.SourceRect;
|
||||
}
|
||||
}
|
||||
Vector2 origin = attachment.Sprite.Origin;
|
||||
Vector2 origin;
|
||||
if (attachment.InheritOrigin)
|
||||
{
|
||||
origin = head.Origin;
|
||||
@@ -559,7 +624,7 @@ namespace Barotrauma
|
||||
{
|
||||
depth = head.Depth - depthStep;
|
||||
}
|
||||
attachment.Sprite.Draw(spriteBatch, drawPos, Color.White, origin, rotate: 0, scale: scale, depth: depth, spriteEffect: spriteEffects);
|
||||
attachment.Sprite.Draw(spriteBatch, drawPos, color ?? Color.White, origin, rotate: 0, scale: scale, depth: depth, spriteEffect: spriteEffects);
|
||||
}
|
||||
|
||||
public static CharacterInfo ClientRead(string speciesName, IReadMessage inc)
|
||||
@@ -574,6 +639,9 @@ namespace Barotrauma
|
||||
int beardIndex = inc.ReadByte();
|
||||
int moustacheIndex = inc.ReadByte();
|
||||
int faceAttachmentIndex = inc.ReadByte();
|
||||
Color skinColor = inc.ReadColorR8G8B8();
|
||||
Color hairColor = inc.ReadColorR8G8B8();
|
||||
Color facialHairColor = inc.ReadColorR8G8B8();
|
||||
string ragdollFile = inc.ReadString();
|
||||
|
||||
string jobIdentifier = inc.ReadString();
|
||||
@@ -599,6 +667,9 @@ namespace Barotrauma
|
||||
ID = infoID,
|
||||
};
|
||||
ch.RecreateHead(headSpriteID,(Race)race, (Gender)gender, hairIndex, beardIndex, moustacheIndex, faceAttachmentIndex);
|
||||
ch.SkinColor = skinColor;
|
||||
ch.HairColor = hairColor;
|
||||
ch.FacialHairColor = facialHairColor;
|
||||
if (ch.Job != null)
|
||||
{
|
||||
foreach (KeyValuePair<string, float> skill in skillLevels)
|
||||
@@ -627,5 +698,384 @@ namespace Barotrauma
|
||||
ch.AdditionalTalentPoints = inc.ReadUInt16();
|
||||
return ch;
|
||||
}
|
||||
|
||||
public void CreateIcon(RectTransform rectT)
|
||||
{
|
||||
LoadHeadAttachments();
|
||||
new GUICustomComponent(rectT,
|
||||
onDraw: (sb, component) => DrawIcon(sb, component.Rect.Center.ToVector2(), targetAreaSize: component.Rect.Size.ToVector2()));
|
||||
}
|
||||
|
||||
public class AppearanceCustomizationMenu : IDisposable
|
||||
{
|
||||
public readonly CharacterInfo CharacterInfo;
|
||||
public GUIListBox HeadSelectionList = null;
|
||||
public bool HasIcon = true;
|
||||
|
||||
public GUIScrollBar.OnMovedHandler OnSliderMoved = null;
|
||||
public GUIScrollBar.OnMovedHandler OnSliderReleased = null;
|
||||
public Action<AppearanceCustomizationMenu> OnHeadSwitch = null;
|
||||
|
||||
private readonly GUIComponent parentComponent;
|
||||
private readonly List<Sprite> characterSprites = new List<Sprite>();
|
||||
|
||||
public AppearanceCustomizationMenu(CharacterInfo info, GUIComponent parent, bool hasIcon = true)
|
||||
{
|
||||
CharacterInfo = info;
|
||||
parentComponent = parent;
|
||||
HasIcon = hasIcon;
|
||||
|
||||
RecreateFrameContents();
|
||||
}
|
||||
|
||||
public void RecreateFrameContents()
|
||||
{
|
||||
var info = CharacterInfo;
|
||||
|
||||
HeadSelectionList = null;
|
||||
parentComponent.ClearChildren();
|
||||
ClearSprites();
|
||||
|
||||
float contentWidth = HasIcon ? 0.75f : 1.0f;
|
||||
var content =
|
||||
new GUIListBox(
|
||||
new RectTransform(new Vector2(contentWidth, 1.0f), parentComponent.RectTransform,
|
||||
Anchor.CenterLeft))
|
||||
{ CanBeFocused = false, CanTakeKeyBoardFocus = false }
|
||||
.Content;
|
||||
|
||||
info.LoadHeadAttachments();
|
||||
if (HasIcon)
|
||||
{
|
||||
info.CreateIcon(
|
||||
new RectTransform(new Vector2(0.25f, 1.0f), parentComponent.RectTransform, Anchor.CenterRight)
|
||||
{ RelativeOffset = new Vector2(-0.01f, 0.0f) });
|
||||
}
|
||||
|
||||
RectTransform createItemRectTransform(string labelTag, float width = 0.6f)
|
||||
{
|
||||
var layoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.2f), content.RectTransform));
|
||||
|
||||
var label = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), layoutGroup.RectTransform),
|
||||
TextManager.Get(labelTag), font: GUI.SubHeadingFont);
|
||||
|
||||
var bottomItem = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.5f), layoutGroup.RectTransform),
|
||||
style: null);
|
||||
|
||||
return new RectTransform(new Vector2(width, 1.0f), bottomItem.RectTransform, Anchor.Center);
|
||||
}
|
||||
|
||||
RectTransform genderItemRT = createItemRectTransform("Gender", 1.0f);
|
||||
|
||||
GUILayoutGroup genderContainer =
|
||||
new GUILayoutGroup(genderItemRT, isHorizontal: true)
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
|
||||
void createGenderButton(Gender gender)
|
||||
{
|
||||
new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), genderContainer.RectTransform),
|
||||
TextManager.Get(gender.ToString()), style: "ListBoxElement")
|
||||
{
|
||||
UserData = gender,
|
||||
OnClicked = OpenHeadSelection,
|
||||
Selected = info.Gender == gender
|
||||
};
|
||||
}
|
||||
|
||||
createGenderButton(Gender.Male);
|
||||
createGenderButton(Gender.Female);
|
||||
|
||||
int countAttachmentsOfType(WearableType wearableType)
|
||||
=> info.FilterByTypeAndHeadID(
|
||||
info.FilterElementsByGenderAndRace(info.Wearables, info.Head.gender, info.Head.race),
|
||||
wearableType, info.HeadSpriteId).Count();
|
||||
|
||||
void createAttachmentSlider(int initialValue, WearableType wearableType)
|
||||
{
|
||||
int attachmentCount = countAttachmentsOfType(wearableType);
|
||||
if (attachmentCount > 0)
|
||||
{
|
||||
var labelTag = wearableType == WearableType.FaceAttachment
|
||||
? "FaceAttachment.Accessories"
|
||||
: $"FaceAttachment.{wearableType}";
|
||||
var sliderItemRT = createItemRectTransform(labelTag);
|
||||
var slider =
|
||||
new GUIScrollBar(sliderItemRT, style: "GUISlider")
|
||||
{
|
||||
Range = new Vector2(0, attachmentCount),
|
||||
StepValue = 1,
|
||||
OnMoved = (bar, scroll) => SwitchAttachment(bar, wearableType),
|
||||
OnReleased = OnSliderReleased,
|
||||
BarSize = 1.0f / (float)(attachmentCount + 1)
|
||||
};
|
||||
slider.BarScrollValue = initialValue;
|
||||
}
|
||||
}
|
||||
|
||||
createAttachmentSlider(info.HairIndex, WearableType.Hair);
|
||||
createAttachmentSlider(info.BeardIndex, WearableType.Beard);
|
||||
createAttachmentSlider(info.MoustacheIndex, WearableType.Moustache);
|
||||
createAttachmentSlider(info.FaceAttachmentIndex, WearableType.FaceAttachment);
|
||||
|
||||
void createColorSelector(string labelTag, IEnumerable<Color> options, Func<Color> getter,
|
||||
Action<Color> setter)
|
||||
{
|
||||
var selectorItemRT = createItemRectTransform(labelTag, 0.4f);
|
||||
var dropdown =
|
||||
new GUIDropDown(selectorItemRT)
|
||||
{ AllowNonText = true };
|
||||
|
||||
var listBoxSize = dropdown.ListBox.RectTransform.RelativeSize;
|
||||
dropdown.ListBox.RectTransform.RelativeSize = new Vector2(listBoxSize.X * 1.75f, listBoxSize.Y);
|
||||
var dropdownButton = dropdown.GetChild<GUIButton>();
|
||||
var buttonFrame =
|
||||
new GUIFrame(
|
||||
new RectTransform(Vector2.One * 0.7f, dropdownButton.RectTransform, Anchor.CenterLeft)
|
||||
{ RelativeOffset = new Vector2(0.05f, 0.0f) }, style: null);
|
||||
dropdown.OnSelected = (component, color) =>
|
||||
{
|
||||
setter((Color)color);
|
||||
buttonFrame.Color = getter();
|
||||
buttonFrame.HoverColor = getter();
|
||||
return true;
|
||||
};
|
||||
buttonFrame.Color = getter();
|
||||
buttonFrame.HoverColor = getter();
|
||||
|
||||
dropdown.ListBox.UseGridLayout = true;
|
||||
foreach (var option in options)
|
||||
{
|
||||
var optionElement =
|
||||
new GUIFrame(
|
||||
new RectTransform(new Vector2(0.25f, 1.0f / 3.0f),
|
||||
dropdown.ListBox.Content.RectTransform),
|
||||
style: "ListBoxElement")
|
||||
{
|
||||
UserData = option,
|
||||
CanBeFocused = true
|
||||
};
|
||||
var colorElement =
|
||||
new GUIFrame(
|
||||
new RectTransform(Vector2.One * 0.75f, optionElement.RectTransform, Anchor.Center,
|
||||
scaleBasis: ScaleBasis.Smallest),
|
||||
style: null)
|
||||
{
|
||||
Color = option,
|
||||
HoverColor = option,
|
||||
OutlineColor = Color.Lerp(Color.Black, option, 0.5f),
|
||||
CanBeFocused = false
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (countAttachmentsOfType(WearableType.Hair) > 0)
|
||||
{
|
||||
createColorSelector($"Customization.{nameof(info.HairColor)}", info.HairColors,
|
||||
() => info.HairColor, (color) => info.HairColor = color);
|
||||
}
|
||||
|
||||
if (countAttachmentsOfType(WearableType.Moustache) > 0 ||
|
||||
countAttachmentsOfType(WearableType.Beard) > 0)
|
||||
{
|
||||
createColorSelector($"Customization.{nameof(info.FacialHairColor)}", info.FacialHairColors,
|
||||
() => info.FacialHairColor, (color) => info.FacialHairColor = color);
|
||||
}
|
||||
|
||||
createColorSelector($"Customization.{nameof(info.SkinColor)}", info.SkinColors, () => info.SkinColor,
|
||||
(color) => info.SkinColor = color);
|
||||
}
|
||||
|
||||
private bool OpenHeadSelection(GUIButton button, object userData)
|
||||
{
|
||||
Gender selectedGender = (Gender)userData;
|
||||
if (HeadSelectionList != null)
|
||||
{
|
||||
HeadSelectionList.Visible = true;
|
||||
foreach (GUIComponent child in HeadSelectionList.Content.Children)
|
||||
{
|
||||
child.Visible = (Gender)child.UserData == selectedGender;
|
||||
child.Children.ForEach(c =>
|
||||
c.Visible = ((Tuple<Gender, Race, int>)c.UserData).Item1 == selectedGender);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
var info = CharacterInfo;
|
||||
|
||||
float characterHeightWidthRatio = info.HeadSprite.size.Y / info.HeadSprite.size.X;
|
||||
HeadSelectionList = new GUIListBox(
|
||||
new RectTransform(
|
||||
new Point(parentComponent.Rect.Width,
|
||||
(int)(parentComponent.Rect.Width * characterHeightWidthRatio * 0.6f)), GUI.Canvas)
|
||||
{
|
||||
AbsoluteOffset = new Point(parentComponent.Rect.Right - parentComponent.Rect.Width,
|
||||
button.Rect.Bottom)
|
||||
});
|
||||
|
||||
parentComponent.RectTransform.SizeChanged += () =>
|
||||
{
|
||||
if (parentComponent == null || HeadSelectionList?.RectTransform == null || button == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HeadSelectionList.RectTransform.Resize(new Point(parentComponent.Rect.Width,
|
||||
(int)(parentComponent.Rect.Width * characterHeightWidthRatio * 0.6f)));
|
||||
HeadSelectionList.RectTransform.AbsoluteOffset =
|
||||
new Point(parentComponent.Rect.Right - parentComponent.Rect.Width, button.Rect.Bottom);
|
||||
};
|
||||
|
||||
new GUIFrame(
|
||||
new RectTransform(new Vector2(1.25f, 1.25f), HeadSelectionList.RectTransform, Anchor.Center),
|
||||
style: "OuterGlow", color: Color.Black)
|
||||
{
|
||||
UserData = "outerglow",
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
GUILayoutGroup row = null;
|
||||
int itemsInRow = 0;
|
||||
|
||||
XElement headElement = info.Ragdoll.MainElement.Elements().FirstOrDefault(e =>
|
||||
e.GetAttributeString("type", "").Equals("head", StringComparison.OrdinalIgnoreCase));
|
||||
XElement headSpriteElement = headElement.Element("sprite");
|
||||
string spritePathWithTags = headSpriteElement.Attribute("texture").Value;
|
||||
|
||||
var characterConfigElement = info.CharacterConfigElement;
|
||||
|
||||
var heads = info.Heads;
|
||||
if (heads != null)
|
||||
{
|
||||
row = null;
|
||||
itemsInRow = 0;
|
||||
foreach (var head in heads)
|
||||
{
|
||||
var headPreset = head.Key;
|
||||
Gender gender = headPreset.Gender;
|
||||
Race race = headPreset.Race;
|
||||
int headIndex = headPreset.ID;
|
||||
|
||||
string spritePath = spritePathWithTags
|
||||
.Replace("[GENDER]", gender.ToString().ToLowerInvariant())
|
||||
.Replace("[RACE]", race.ToString().ToLowerInvariant());
|
||||
|
||||
if (!File.Exists(spritePath))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Sprite headSprite = new Sprite(headSpriteElement, "", spritePath);
|
||||
headSprite.SourceRect =
|
||||
new Rectangle(CharacterInfo.CalculateOffset(headSprite, head.Value.ToPoint()),
|
||||
headSprite.SourceRect.Size);
|
||||
characterSprites.Add(headSprite);
|
||||
|
||||
if (itemsInRow >= 4 || row == null || gender != (Gender)row.UserData)
|
||||
{
|
||||
row = new GUILayoutGroup(
|
||||
new RectTransform(new Vector2(1.0f, 0.333f), HeadSelectionList.Content.RectTransform),
|
||||
true)
|
||||
{
|
||||
UserData = gender,
|
||||
Visible = gender == selectedGender
|
||||
};
|
||||
itemsInRow = 0;
|
||||
}
|
||||
|
||||
var btn = new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), row.RectTransform),
|
||||
style: "ListBoxElementSquare")
|
||||
{
|
||||
OutlineColor = Color.White * 0.5f,
|
||||
PressedColor = Color.White * 0.5f,
|
||||
UserData = new Tuple<Gender, Race, int>(gender, race, headIndex),
|
||||
OnClicked = SwitchHead,
|
||||
Selected = gender == info.Gender && race == info.Race && headIndex == info.HeadSpriteId,
|
||||
Visible = gender == selectedGender
|
||||
};
|
||||
|
||||
new GUIImage(new RectTransform(Vector2.One, btn.RectTransform), headSprite, scaleToFit: true);
|
||||
itemsInRow++;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool SwitchHead(GUIButton button, object obj)
|
||||
{
|
||||
var info = CharacterInfo;
|
||||
Gender gender = ((Tuple<Gender, Race, int>)obj).Item1;
|
||||
Race race = ((Tuple<Gender, Race, int>)obj).Item2;
|
||||
int id = ((Tuple<Gender, Race, int>)obj).Item3;
|
||||
info.Gender = gender;
|
||||
info.Race = race;
|
||||
info.HeadSpriteId = id;
|
||||
RecreateFrameContents();
|
||||
OnHeadSwitch?.Invoke(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool SwitchAttachment(GUIScrollBar scrollBar, WearableType type)
|
||||
{
|
||||
var info = CharacterInfo;
|
||||
int index = (int)scrollBar.BarScrollValue;
|
||||
switch (type)
|
||||
{
|
||||
case WearableType.Beard:
|
||||
info.BeardIndex = index;
|
||||
break;
|
||||
case WearableType.FaceAttachment:
|
||||
info.FaceAttachmentIndex = index;
|
||||
break;
|
||||
case WearableType.Hair:
|
||||
info.HairIndex = index;
|
||||
break;
|
||||
case WearableType.Moustache:
|
||||
info.MoustacheIndex = index;
|
||||
break;
|
||||
default:
|
||||
DebugConsole.ThrowError($"Wearable type not implemented: {type}");
|
||||
return false;
|
||||
}
|
||||
|
||||
info.RefreshHead();
|
||||
OnSliderMoved?.Invoke(scrollBar, scrollBar.BarScroll);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (HeadSelectionList != null && PlayerInput.PrimaryMouseButtonDown() &&
|
||||
!GUI.IsMouseOn(HeadSelectionList))
|
||||
{
|
||||
HeadSelectionList.Visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddToGUIUpdateList()
|
||||
{
|
||||
HeadSelectionList?.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
private void ClearSprites()
|
||||
{
|
||||
foreach (Sprite sprite in characterSprites) { sprite.Remove(); }
|
||||
characterSprites.Clear();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ClearSprites();
|
||||
}
|
||||
|
||||
~AppearanceCustomizationMenu()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -601,8 +601,13 @@ namespace Barotrauma
|
||||
.FindAll(a => a.ShouldShowIcon(Character) && a.Prefab.Icon != null);
|
||||
currentDisplayedAfflictions.Sort((a1, a2) =>
|
||||
{
|
||||
int dmgPerSecond = Math.Sign(a2.DamagePerSecond - a1.DamagePerSecond);
|
||||
return dmgPerSecond != 0 ? dmgPerSecond : Math.Sign(a1.Strength - a1.Strength);
|
||||
int dmgPerSecond = Math.Sign(a1.DamagePerSecond - a2.DamagePerSecond);
|
||||
if (dmgPerSecond != 0) { return dmgPerSecond; }
|
||||
return Math.Sign(GetStr(a1) - GetStr(a2));
|
||||
static float GetStr(Affliction affliction)
|
||||
{
|
||||
return affliction.Strength / affliction.Prefab.MaxStrength * (affliction.Prefab.IsBuff ? 1.0f : 10.0f);
|
||||
}
|
||||
});
|
||||
HintManager.OnAfflictionDisplayed(Character, currentDisplayedAfflictions);
|
||||
updateDisplayedAfflictionsTimer = UpdateDisplayedAfflictionsInterval;
|
||||
@@ -1131,6 +1136,8 @@ namespace Barotrauma
|
||||
|
||||
public static Color GetAfflictionIconColor(Affliction affliction) => GetAfflictionIconColor(affliction.Prefab, affliction);
|
||||
|
||||
private readonly List<(Affliction affliction, float strength)> displayedAfflictions = new List<(Affliction affliction, float strength)>();
|
||||
|
||||
private void UpdateAfflictionContainer(LimbHealth selectedLimb)
|
||||
{
|
||||
if (selectedLimb == null)
|
||||
@@ -1139,45 +1146,33 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
var currentAfflictions = GetMatchingAfflictions(selectedLimb, a => a.ShouldShowIcon(Character));
|
||||
var displayedAfflictions = afflictionIconContainer.Content.Children.Select(c => c.UserData as Affliction);
|
||||
if (currentAfflictions.Any(a => !displayedAfflictions.Contains(a)) ||
|
||||
displayedAfflictions.Any(a => !currentAfflictions.Contains(a)))
|
||||
if (currentAfflictions.Any(a => !displayedAfflictions.Any(d => d.affliction == a)) ||
|
||||
displayedAfflictions.Any(a => !currentAfflictions.Contains(a.affliction)))
|
||||
{
|
||||
CreateAfflictionInfos(currentAfflictions);
|
||||
CreateRecommendedTreatments();
|
||||
}
|
||||
//update recommended treatments if the strength of some displayed affliction has changed by > 1
|
||||
else if (displayedAfflictions.Any(d => Math.Abs(d.strength - currentAfflictions.First(a => a == d.affliction).Strength) > 1.0f))
|
||||
{
|
||||
CreateRecommendedTreatments();
|
||||
}
|
||||
|
||||
UpdateAfflictionInfos(displayedAfflictions);
|
||||
UpdateAfflictionInfos(displayedAfflictions.Select(d => d.affliction));
|
||||
}
|
||||
|
||||
private void CreateAfflictionInfos(IEnumerable<Affliction> afflictions)
|
||||
{
|
||||
afflictionIconContainer.ClearChildren();
|
||||
recommendedTreatmentContainer.Content.ClearChildren();
|
||||
|
||||
float characterSkillLevel = Character.Controlled == null ? 0.0f : Character.Controlled.GetSkillLevel("medical");
|
||||
|
||||
//key = item identifier
|
||||
//float = suitability
|
||||
Dictionary<string, float> treatmentSuitability = new Dictionary<string, float>();
|
||||
GetSuitableTreatments(treatmentSuitability,
|
||||
normalize: true,
|
||||
ignoreHiddenAfflictions: true,
|
||||
limb: selectedLimbIndex == -1 ? null : Character.AnimController.Limbs.Find(l => l.HealthIndex == selectedLimbIndex));
|
||||
|
||||
foreach (string treatment in treatmentSuitability.Keys.ToList())
|
||||
{
|
||||
//prefer suggestions for items the player has
|
||||
if (Character.Controlled.Inventory.FindItemByIdentifier(treatment) != null)
|
||||
{
|
||||
treatmentSuitability[treatment] *= 10.0f;
|
||||
}
|
||||
}
|
||||
displayedAfflictions.Clear();
|
||||
|
||||
Affliction mostSevereAffliction = SortAfflictionsBySeverity(afflictions).FirstOrDefault();
|
||||
GUIButton buttonToSelect = null;
|
||||
|
||||
foreach (Affliction affliction in afflictions)
|
||||
{
|
||||
displayedAfflictions.Add((affliction, affliction.Strength));
|
||||
|
||||
var child = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.3f), afflictionIconContainer.Content.RectTransform, Anchor.TopCenter))
|
||||
{
|
||||
Stretch = true,
|
||||
@@ -1233,6 +1228,39 @@ namespace Barotrauma
|
||||
child.Recalculate();
|
||||
}
|
||||
|
||||
buttonToSelect?.OnClicked(buttonToSelect, "selectaffliction");
|
||||
afflictionIconContainer.RecalculateChildren();
|
||||
}
|
||||
|
||||
private void CreateRecommendedTreatments()
|
||||
{
|
||||
ItemPrefab prevHighlightedItem = null;
|
||||
if (GUI.MouseOn?.UserData is ItemPrefab && recommendedTreatmentContainer.Content.IsParentOf(GUI.MouseOn))
|
||||
{
|
||||
prevHighlightedItem = (ItemPrefab)GUI.MouseOn.UserData;
|
||||
}
|
||||
|
||||
recommendedTreatmentContainer.Content.ClearChildren();
|
||||
|
||||
float characterSkillLevel = Character.Controlled == null ? 0.0f : Character.Controlled.GetSkillLevel("medical");
|
||||
|
||||
//key = item identifier
|
||||
//float = suitability
|
||||
Dictionary<string, float> treatmentSuitability = new Dictionary<string, float>();
|
||||
GetSuitableTreatments(treatmentSuitability,
|
||||
normalize: true,
|
||||
ignoreHiddenAfflictions: true,
|
||||
limb: selectedLimbIndex == -1 ? null : Character.AnimController.Limbs.Find(l => l.HealthIndex == selectedLimbIndex));
|
||||
|
||||
foreach (string treatment in treatmentSuitability.Keys.ToList())
|
||||
{
|
||||
//prefer suggestions for items the player has
|
||||
if (Character.Controlled.Inventory.FindItemByIdentifier(treatment) != null)
|
||||
{
|
||||
treatmentSuitability[treatment] *= 10.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (!treatmentSuitability.Any())
|
||||
{
|
||||
new GUITextBlock(new RectTransform(Vector2.One, recommendedTreatmentContainer.Content.RectTransform), TextManager.Get("none"), textAlignment: Alignment.Center)
|
||||
@@ -1248,10 +1276,6 @@ namespace Barotrauma
|
||||
recommendedTreatmentContainer.AutoHideScrollBar = true;
|
||||
}
|
||||
|
||||
buttonToSelect?.OnClicked(buttonToSelect, "selectaffliction");
|
||||
|
||||
afflictionIconContainer.RecalculateChildren();
|
||||
|
||||
List<KeyValuePair<string, float>> treatmentSuitabilities = treatmentSuitability.OrderByDescending(t => t.Value).ToList();
|
||||
|
||||
int count = 0;
|
||||
@@ -1286,7 +1310,7 @@ namespace Barotrauma
|
||||
new GUIImage(new RectTransform(Vector2.One, innerFrame.RectTransform, Anchor.Center), style: "TalentBackgroundGlow")
|
||||
{
|
||||
CanBeFocused = false,
|
||||
Color = Color.White * 0.7f,
|
||||
Color = GUI.Style.Green,
|
||||
HoverColor = Color.White,
|
||||
PressedColor = Color.DarkGray,
|
||||
SelectedColor = Color.Transparent,
|
||||
@@ -1304,6 +1328,12 @@ namespace Barotrauma
|
||||
SelectedColor = itemColor,
|
||||
DisabledColor = itemColor * 0.8f
|
||||
};
|
||||
|
||||
if (item == prevHighlightedItem)
|
||||
{
|
||||
innerFrame.State = GUIComponent.ComponentState.Hover;
|
||||
innerFrame.Children.ForEach(c => c.State = GUIComponent.ComponentState.Hover);
|
||||
}
|
||||
}
|
||||
|
||||
recommendedTreatmentContainer.RecalculateChildren();
|
||||
@@ -1315,6 +1345,19 @@ namespace Barotrauma
|
||||
int dmgPerSecond = Math.Sign(second.DamagePerSecond - first.DamagePerSecond);
|
||||
return dmgPerSecond != 0 ? dmgPerSecond : Math.Sign(second.Strength - first.Strength);
|
||||
});
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
var treatmentIconSize = recommendedTreatmentContainer.Content.Children.Sum(c => c.Rect.Width + recommendedTreatmentContainer.Spacing);
|
||||
if (treatmentIconSize < recommendedTreatmentContainer.Content.Rect.Width)
|
||||
{
|
||||
var spacing = new GUIFrame(new RectTransform(new Point((recommendedTreatmentContainer.Content.Rect.Width - treatmentIconSize) / 2, 0), recommendedTreatmentContainer.Content.RectTransform), style: null)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
spacing.RectTransform.SetAsFirstChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateAfflictionInfoElements(GUIComponent parent, Affliction affliction)
|
||||
|
||||
@@ -120,6 +120,15 @@ namespace Barotrauma
|
||||
public List<SpriteDeformation> ActiveDeformations { get; set; } = new List<SpriteDeformation>();
|
||||
|
||||
public Sprite Sprite { get; protected set; }
|
||||
public Sprite TintMask { get; protected set; }
|
||||
|
||||
public Sprite HuskMask { get; protected set; }
|
||||
public float TintHighlightThreshold { get; protected set; }
|
||||
public float TintHighlightMultiplier { get; protected set; }
|
||||
|
||||
private SpriteBatch.EffectWithParams tintEffectParams;
|
||||
private SpriteBatch.EffectWithParams huskSpriteParams;
|
||||
|
||||
|
||||
protected DeformableSprite _deformSprite;
|
||||
|
||||
@@ -273,6 +282,7 @@ namespace Barotrauma
|
||||
DecorativeSpriteGroups[groupID].Add(decorativeSprite);
|
||||
spriteAnimState.Add(decorativeSprite, new SpriteState());
|
||||
}
|
||||
TintMask = null;
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
@@ -308,6 +318,22 @@ namespace Barotrauma
|
||||
InitialLightSourceColor = LightSource.Color;
|
||||
InitialLightSpriteAlpha = LightSource.OverrideLightSpriteAlpha;
|
||||
break;
|
||||
case "tintmask":
|
||||
string tintMaskPath = subElement.GetAttributeString("texture", "");
|
||||
if (!string.IsNullOrWhiteSpace(tintMaskPath))
|
||||
{
|
||||
TintMask = new Sprite(subElement, file: GetSpritePath(tintMaskPath));
|
||||
TintHighlightThreshold = subElement.GetAttributeFloat("highlightthreshold", 0.6f);
|
||||
TintHighlightMultiplier = subElement.GetAttributeFloat("highlightmultiplier", 0.8f);
|
||||
}
|
||||
break;
|
||||
case "huskmask":
|
||||
string huskMaskPath = subElement.GetAttributeString("texture", "");
|
||||
if (!string.IsNullOrWhiteSpace(huskMaskPath))
|
||||
{
|
||||
HuskMask = new Sprite(subElement, file: GetSpritePath(huskMaskPath));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ISerializableEntity GetConditionalTarget()
|
||||
@@ -449,20 +475,20 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// Get the full path of a limb sprite, taking into account tags, gender and head id
|
||||
/// </summary>
|
||||
private string GetSpritePath(string texturePath)
|
||||
public static string GetSpritePath(string texturePath, CharacterInfo characterInfo)
|
||||
{
|
||||
string spritePath = texturePath;
|
||||
string spritePathWithTags = spritePath;
|
||||
if (character.Info != null && character.IsHumanoid)
|
||||
if (characterInfo != null)
|
||||
{
|
||||
spritePath = spritePath.Replace("[GENDER]", (character.Info.Gender == Gender.Female) ? "female" : "male");
|
||||
spritePath = spritePath.Replace("[RACE]", character.Info.Race.ToString().ToLowerInvariant());
|
||||
spritePath = spritePath.Replace("[HEADID]", character.Info.HeadSpriteId.ToString());
|
||||
spritePath = spritePath.Replace("[GENDER]", (characterInfo.Gender == Gender.Female) ? "female" : "male");
|
||||
spritePath = spritePath.Replace("[RACE]", characterInfo.Race.ToString().ToLowerInvariant());
|
||||
spritePath = spritePath.Replace("[HEADID]", characterInfo.HeadSpriteId.ToString());
|
||||
|
||||
if (character.Info.HeadSprite != null && character.Info.SpriteTags.Any())
|
||||
if (characterInfo.HeadSprite != null && characterInfo.SpriteTags.Any())
|
||||
{
|
||||
string tags = "";
|
||||
character.Info.SpriteTags.ForEach(tag => tags += "[" + tag + "]");
|
||||
characterInfo.SpriteTags.ForEach(tag => tags += "[" + tag + "]");
|
||||
|
||||
spritePathWithTags = Path.Combine(
|
||||
Path.GetDirectoryName(spritePath),
|
||||
@@ -472,6 +498,13 @@ namespace Barotrauma
|
||||
return File.Exists(spritePathWithTags) ? spritePathWithTags : spritePath;
|
||||
}
|
||||
|
||||
|
||||
private string GetSpritePath(string texturePath)
|
||||
{
|
||||
if (!character.IsHumanoid) { return texturePath; }
|
||||
return GetSpritePath(texturePath, character?.Info);
|
||||
}
|
||||
|
||||
partial void LoadParamsProjSpecific()
|
||||
{
|
||||
bool isFlipped = dir == Direction.Left;
|
||||
@@ -638,13 +671,24 @@ namespace Barotrauma
|
||||
var spriteParams = Params.GetSprite();
|
||||
if (spriteParams == null) { return; }
|
||||
|
||||
Color color = new Color(spriteParams.Color.R / 255f * brightness, spriteParams.Color.G / 255f * brightness, spriteParams.Color.B / 255f * brightness, spriteParams.Color.A / 255f);
|
||||
Color clr = spriteParams.Color;
|
||||
if (!spriteParams.IgnoreTint)
|
||||
{
|
||||
clr = clr.Multiply(ragdoll.RagdollParams.Color);
|
||||
if (character.Info != null)
|
||||
{
|
||||
clr = clr.Multiply(character.Info.SkinColor);
|
||||
}
|
||||
}
|
||||
Color color = new Color((byte)(clr.R * brightness), (byte)(clr.G * brightness), (byte)(clr.B * brightness), clr.A);
|
||||
Color blankColor = new Color(brightness, brightness, brightness, 1);
|
||||
if (deadTimer > 0)
|
||||
{
|
||||
color = Color.Lerp(color, spriteParams.DeadColor, MathUtils.InverseLerp(0, spriteParams.DeadColorTime, deadTimer));
|
||||
}
|
||||
|
||||
color = overrideColor ?? color;
|
||||
blankColor = overrideColor ?? blankColor;
|
||||
|
||||
if (isSevered)
|
||||
{
|
||||
@@ -667,6 +711,8 @@ namespace Barotrauma
|
||||
OtherWearables.Any(w => w.HideLimb) ||
|
||||
wearingItems.Any(w => w != null && w.HideLimb);
|
||||
|
||||
bool drawHuskSprite = HuskSprite != null && !wearableTypesToHide.Contains(WearableType.Husk);
|
||||
|
||||
var activeSprite = ActiveSprite;
|
||||
if (type == LimbType.Head)
|
||||
{
|
||||
@@ -698,7 +744,33 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
bool useTintMask = TintMask != null && spriteBatch.GetCurrentEffect() is null;
|
||||
if (useTintMask)
|
||||
{
|
||||
tintEffectParams.Effect ??= GameMain.GameScreen.ThresholdTintEffect;
|
||||
tintEffectParams.Params ??= new Dictionary<string, object>();
|
||||
var parameters = tintEffectParams.Params;
|
||||
parameters["xBaseTexture"] = Sprite.Texture;
|
||||
parameters["xTintMaskTexture"] = TintMask.Texture;
|
||||
if (drawHuskSprite && HuskMask != null)
|
||||
{
|
||||
parameters["xCutoffTexture"] = HuskMask.Texture;
|
||||
parameters["baseToCutoffSizeRatio"] = (float)Sprite.Texture.Width / (float)HuskMask.Texture.Width;
|
||||
}
|
||||
else
|
||||
{
|
||||
parameters["xCutoffTexture"] = GUI.WhiteTexture;
|
||||
parameters["baseToCutoffSizeRatio"] = 1.0f;
|
||||
}
|
||||
parameters["highlightThreshold"] = TintHighlightThreshold;
|
||||
parameters["highlightMultiplier"] = TintHighlightMultiplier;
|
||||
spriteBatch.SwapEffect(tintEffectParams);
|
||||
}
|
||||
body.Draw(spriteBatch, activeSprite, color, null, Scale * TextureScale, Params.MirrorHorizontally, Params.MirrorVertically);
|
||||
if (useTintMask)
|
||||
{
|
||||
spriteBatch.SwapEffect(null);
|
||||
}
|
||||
}
|
||||
// Handle non-exlusive, i.e. additional conditional sprites
|
||||
foreach (var conditionalSprite in ConditionalSprites)
|
||||
@@ -770,15 +842,36 @@ namespace Barotrauma
|
||||
}
|
||||
if (onlyDrawable == null)
|
||||
{
|
||||
if (HerpesSprite != null && !wearableTypesToHide.Contains(WearableType.Herpes))
|
||||
if (HerpesSprite != null && !wearableTypesToHide.Contains(WearableType.Herpes) && herpesStrength > 0)
|
||||
{
|
||||
DrawWearable(HerpesSprite, depthStep, spriteBatch, color * Math.Min(herpesStrength / 10.0f, 1.0f), spriteEffect);
|
||||
float alpha = Math.Min(herpesStrength * 2 / 100.0f, 1.0f);
|
||||
DrawWearable(HerpesSprite, depthStep, spriteBatch, blankColor, alpha: alpha, spriteEffect);
|
||||
depthStep += step;
|
||||
}
|
||||
if (drawHuskSprite)
|
||||
{
|
||||
bool useTintEffect = HuskMask != null && spriteBatch.GetCurrentEffect() is null;
|
||||
if (useTintEffect)
|
||||
{
|
||||
huskSpriteParams.Effect ??= GameMain.GameScreen.ThresholdTintEffect;
|
||||
huskSpriteParams.Params ??= new Dictionary<string, object>();
|
||||
var parameters = huskSpriteParams.Params;
|
||||
parameters["xCutoffTexture"] = GUI.WhiteTexture;
|
||||
parameters["baseToCutoffSizeRatio"] = 1.0f;
|
||||
spriteBatch.SwapEffect(huskSpriteParams);
|
||||
}
|
||||
DrawWearable(HuskSprite, depthStep, spriteBatch, color, alpha: color.A / 255f, spriteEffect);
|
||||
if (useTintEffect)
|
||||
{
|
||||
spriteBatch.SwapEffect(null);
|
||||
}
|
||||
depthStep += step;
|
||||
}
|
||||
foreach (WearableSprite wearable in OtherWearables)
|
||||
{
|
||||
if (wearable.Type == WearableType.Husk) { continue; }
|
||||
if (wearableTypesToHide.Contains(wearable.Type)) { continue; }
|
||||
DrawWearable(wearable, depthStep, spriteBatch, color, spriteEffect);
|
||||
DrawWearable(wearable, depthStep, spriteBatch, blankColor, alpha: color.A / 255f, spriteEffect);
|
||||
//if there are multiple sprites on this limb, make the successive ones be drawn in front
|
||||
depthStep += step;
|
||||
}
|
||||
@@ -786,7 +879,7 @@ namespace Barotrauma
|
||||
foreach (WearableSprite wearable in WearingItems)
|
||||
{
|
||||
if (onlyDrawable != null && onlyDrawable != wearable) continue;
|
||||
DrawWearable(wearable, depthStep, spriteBatch, color, spriteEffect);
|
||||
DrawWearable(wearable, depthStep, spriteBatch, blankColor, alpha: color.A / 255f, spriteEffect);
|
||||
//if there are multiple sprites on this limb, make the successive ones be drawn in front
|
||||
depthStep += step;
|
||||
}
|
||||
@@ -936,7 +1029,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawWearable(WearableSprite wearable, float depthStep, SpriteBatch spriteBatch, Color color, SpriteEffects spriteEffect)
|
||||
private void DrawWearable(WearableSprite wearable, float depthStep, SpriteBatch spriteBatch, Color color, float alpha, SpriteEffects spriteEffect)
|
||||
{
|
||||
var sprite = ActiveSprite;
|
||||
if (wearable.InheritSourceRect)
|
||||
@@ -955,7 +1048,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 origin = wearable.Sprite.Origin;
|
||||
Vector2 origin;
|
||||
if (wearable.InheritOrigin)
|
||||
{
|
||||
origin = sprite.Origin;
|
||||
@@ -986,7 +1079,7 @@ namespace Barotrauma
|
||||
Color wearableColor = Color.White;
|
||||
if (wearableItemComponent != null)
|
||||
{
|
||||
// Draw outer cloths on top of inner cloths.
|
||||
// Draw outer clothes on top of inner clothes.
|
||||
if (wearableItemComponent.AllowedSlots.Contains(InvSlotType.OuterClothes))
|
||||
{
|
||||
depth -= depthStep;
|
||||
@@ -997,15 +1090,38 @@ namespace Barotrauma
|
||||
}
|
||||
wearableColor = wearableItemComponent.Item.GetSpriteColor();
|
||||
}
|
||||
float textureScale = wearable.InheritTextureScale ? TextureScale : wearable.Scale;
|
||||
|
||||
else if (character.Info != null)
|
||||
{
|
||||
if (wearable.Type == WearableType.Hair)
|
||||
{
|
||||
wearableColor = character.Info.HairColor;
|
||||
}
|
||||
else if (wearable.Type == WearableType.Beard || wearable.Type == WearableType.Moustache)
|
||||
{
|
||||
wearableColor = character.Info.FacialHairColor;
|
||||
}
|
||||
}
|
||||
float scale = wearable.Scale;
|
||||
if (wearable.InheritScale)
|
||||
{
|
||||
if (!wearable.IgnoreTextureScale)
|
||||
{
|
||||
scale *= TextureScale;
|
||||
}
|
||||
if (!wearable.IgnoreLimbScale)
|
||||
{
|
||||
scale *= Params.Scale;
|
||||
}
|
||||
if (!wearable.IgnoreRagdollScale)
|
||||
{
|
||||
scale *= ragdoll.RagdollParams.LimbScale;
|
||||
}
|
||||
}
|
||||
float rotation = -body.DrawRotation - wearable.Rotation * Dir;
|
||||
|
||||
wearable.Sprite.Draw(spriteBatch,
|
||||
new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
|
||||
new Color((color.R * wearableColor.R) / (255.0f * 255.0f), (color.G * wearableColor.G) / (255.0f * 255.0f), (color.B * wearableColor.B) / (255.0f * 255.0f)) * ((color.A * wearableColor.A) / (255.0f * 255.0f)),
|
||||
origin, rotation,
|
||||
Scale * textureScale, spriteEffect, depth);
|
||||
float finalAlpha = alpha * wearableColor.A;
|
||||
Color finalColor = color.Multiply(wearableColor);
|
||||
finalColor = new Color(finalColor.R, finalColor.G, finalColor.B, (byte)finalAlpha);
|
||||
wearable.Sprite.Draw(spriteBatch, new Vector2(body.DrawPosition.X, -body.DrawPosition.Y), finalColor, origin, rotation, scale, spriteEffect, depth);
|
||||
}
|
||||
|
||||
private WearableSprite GetWearableSprite(WearableType type, bool random = false)
|
||||
@@ -1056,6 +1172,9 @@ namespace Barotrauma
|
||||
|
||||
HerpesSprite?.Sprite.Remove();
|
||||
HerpesSprite = null;
|
||||
|
||||
TintMask?.Remove();
|
||||
TintMask = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user