Faction Test v1.0.1.0
This commit is contained in:
@@ -109,7 +109,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
float distSqrd = Vector2.DistanceSquared(newPosition, Collider.SimPosition);
|
||||
float errorTolerance = character.CanMove ? 0.01f : 0.2f;
|
||||
float errorTolerance = character.CanMove && !character.IsRagdolled ? 0.01f : 0.2f;
|
||||
if (distSqrd > errorTolerance)
|
||||
{
|
||||
if (distSqrd > 10.0f || !character.CanMove)
|
||||
@@ -147,6 +147,7 @@ namespace Barotrauma
|
||||
{
|
||||
MainLimb.PullJointWorldAnchorB = Collider.SimPosition;
|
||||
MainLimb.PullJointEnabled = true;
|
||||
MainLimb.body.LinearVelocity = newVelocity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,6 +298,21 @@ namespace Barotrauma
|
||||
{
|
||||
keys[i].SetState();
|
||||
}
|
||||
|
||||
if (CharacterInventory.IsMouseOnInventory && CharacterHUD.ShouldDrawInventory(this))
|
||||
{
|
||||
ResetInputIfPrimaryMouse(InputType.Use);
|
||||
ResetInputIfPrimaryMouse(InputType.Shoot);
|
||||
ResetInputIfPrimaryMouse(InputType.Select);
|
||||
void ResetInputIfPrimaryMouse(InputType inputType)
|
||||
{
|
||||
if (GameSettings.CurrentConfig.KeyMap.Bindings[inputType].MouseButton == MouseButton.PrimaryMouse)
|
||||
{
|
||||
keys[(int)inputType].Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if we were firing (= pressing the aim and shoot keys at the same time)
|
||||
//and the fire key is the same as Select or Use, reset the key to prevent accidentally selecting/using items
|
||||
if (wasFiring && !keys[(int)InputType.Shoot].Held)
|
||||
@@ -316,8 +331,7 @@ namespace Barotrauma
|
||||
float targetOffsetAmount = 0.0f;
|
||||
if (moveCam)
|
||||
{
|
||||
if (NeedsAir && !IsProtectedFromPressure() &&
|
||||
(AnimController.CurrentHull == null || AnimController.CurrentHull.LethalPressure > 0.0f))
|
||||
if (!IsProtectedFromPressure && (AnimController.CurrentHull == null || AnimController.CurrentHull.LethalPressure > 0.0f))
|
||||
{
|
||||
float pressure = AnimController.CurrentHull == null ? 100.0f : AnimController.CurrentHull.LethalPressure;
|
||||
if (pressure > 0.0f)
|
||||
@@ -636,7 +650,7 @@ namespace Barotrauma
|
||||
return closestItem;
|
||||
}
|
||||
|
||||
private Character FindCharacterAtPosition(Vector2 mouseSimPos, float maxDist = 150.0f)
|
||||
private Character FindCharacterAtPosition(Vector2 mouseSimPos, float maxDist = MaxHighlightDistance)
|
||||
{
|
||||
Character closestCharacter = null;
|
||||
|
||||
@@ -646,7 +660,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (!CanInteractWith(c, checkVisibility: false) || (c.AnimController?.SimplePhysicsEnabled ?? true)) { continue; }
|
||||
|
||||
float dist = Vector2.DistanceSquared(mouseSimPos, c.SimPosition);
|
||||
float dist = c.GetDistanceToClosestLimb(mouseSimPos);
|
||||
if (dist < closestDist ||
|
||||
(c.CampaignInteractionType != CampaignMode.InteractionType.None && closestCharacter?.CampaignInteractionType == CampaignMode.InteractionType.None && dist * 0.9f < closestDist))
|
||||
{
|
||||
|
||||
@@ -29,6 +29,10 @@ namespace Barotrauma
|
||||
|
||||
public abstract float State { get; }
|
||||
|
||||
public abstract string NumberToDisplay { get; }
|
||||
|
||||
public abstract Color Color { get; }
|
||||
|
||||
public BossProgressBar(LocalizedString label)
|
||||
{
|
||||
FadeTimer = BossHealthBarDuration;
|
||||
@@ -46,6 +50,7 @@ namespace Barotrauma
|
||||
{
|
||||
Color = GUIStyle.Red
|
||||
};
|
||||
CreateNumberText(TopHealthBar);
|
||||
|
||||
SideContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), bossHealthContainer.RectTransform)
|
||||
{
|
||||
@@ -56,12 +61,28 @@ namespace Barotrauma
|
||||
{
|
||||
Color = GUIStyle.Red
|
||||
};
|
||||
CreateNumberText(SideHealthBar);
|
||||
|
||||
TopContainer.Visible = SideContainer.Visible = false;
|
||||
TopContainer.CanBeFocused = false;
|
||||
TopContainer.Children.ForEach(c => c.CanBeFocused = false);
|
||||
SideContainer.CanBeFocused = false;
|
||||
SideContainer.Children.ForEach(c => c.CanBeFocused = false);
|
||||
|
||||
void CreateNumberText(GUIComponent parent)
|
||||
{
|
||||
new GUITextBlock(new RectTransform(Vector2.One, parent.RectTransform)
|
||||
{ AbsoluteOffset = new Point(2) },
|
||||
string.Empty, textAlignment: Alignment.Center, textColor: GUIStyle.TextColorDark)
|
||||
{
|
||||
TextGetter = () => NumberToDisplay
|
||||
};
|
||||
new GUITextBlock(new RectTransform(Vector2.One, parent.RectTransform),
|
||||
string.Empty, textAlignment: Alignment.Center, textColor: GUIStyle.TextColorBright)
|
||||
{
|
||||
TextGetter = () => NumberToDisplay
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public abstract bool IsDuplicate(BossProgressBar progressBar);
|
||||
@@ -77,6 +98,12 @@ namespace Barotrauma
|
||||
|
||||
public override bool Interrupted => Character.Removed || !Character.Enabled;
|
||||
|
||||
public override Color Color =>
|
||||
Character.CharacterHealth.GetAfflictionStrength(AfflictionPrefab.PoisonType) > 0 || Character.CharacterHealth.GetAfflictionStrength(AfflictionPrefab.ParalysisType) > 0 ?
|
||||
GUIStyle.HealthBarColorPoisoned : GUIStyle.Red;
|
||||
|
||||
public override string NumberToDisplay => string.Empty;
|
||||
|
||||
public BossHealthBar(Character character) : base(character.DisplayName)
|
||||
{
|
||||
Character = character;
|
||||
@@ -96,7 +123,13 @@ namespace Barotrauma
|
||||
|
||||
public override bool Completed => Mission.State >= Mission.Prefab.MaxProgressState;
|
||||
|
||||
public override bool Interrupted => Mission.Failed;
|
||||
public override bool Interrupted => Mission.Failed || GameMain.GameSession?.Missions == null || !GameMain.GameSession.Missions.Contains(Mission);
|
||||
|
||||
public override Color Color => GUIStyle.Red;
|
||||
|
||||
public override string NumberToDisplay => Mission.Prefab.ShowProgressInNumbers ?
|
||||
$"{Mission.State}/{Mission.Prefab.MaxProgressState}" :
|
||||
string.Empty;
|
||||
|
||||
public MissionProgressBar(Mission mission) : base(mission.Prefab.ProgressBarLabel)
|
||||
{
|
||||
@@ -155,7 +188,7 @@ namespace Barotrauma
|
||||
GameMain.GameSession?.Campaign != null &&
|
||||
(GameMain.GameSession.Campaign.ShowCampaignUI || GameMain.GameSession.Campaign.ForceMapUI);
|
||||
|
||||
private static bool ShouldDrawInventory(Character character)
|
||||
public static bool ShouldDrawInventory(Character character)
|
||||
{
|
||||
var controller = character.SelectedItem?.GetComponent<Controller>();
|
||||
|
||||
@@ -656,7 +689,8 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 startPos = character.DrawPosition + (character.FocusedCharacter.DrawPosition - character.DrawPosition) * 0.7f;
|
||||
float dist = Vector2.Distance(character.FocusedCharacter.DrawPosition, character.DrawPosition);
|
||||
Vector2 startPos = character.DrawPosition + (character.FocusedCharacter.DrawPosition - character.DrawPosition) / dist * Math.Min(dist, Character.MaxDragDistance);
|
||||
startPos = cam.WorldToScreen(startPos);
|
||||
|
||||
string focusName = character.FocusedCharacter.Info == null ? character.FocusedCharacter.DisplayName : character.FocusedCharacter.Info.DisplayName;
|
||||
@@ -722,6 +756,11 @@ namespace Barotrauma
|
||||
AddBossProgressBar(new MissionProgressBar(mission));
|
||||
}
|
||||
|
||||
public static void ClearBossHealthBars()
|
||||
{
|
||||
bossHealthBars.Clear();
|
||||
}
|
||||
|
||||
private static void AddBossProgressBar(BossProgressBar progressBar, float damage = 0.0f)
|
||||
{
|
||||
var healthBarMode = GameMain.NetworkMember?.ServerSettings.ShowEnemyHealthBars ?? GameSettings.CurrentConfig.ShowEnemyHealthBars;
|
||||
@@ -791,7 +830,7 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (var component in container.GetAllChildren())
|
||||
{
|
||||
component.Color = new Color(component.Color, (byte)(alpha * 255));
|
||||
component.Color = new Color(bossHealthBar.Color, (byte)(alpha * 255));
|
||||
if (component is GUITextBlock textBlock)
|
||||
{
|
||||
textBlock.TextColor = new Color(bossHealthBar.Completed ? Color.Gray : textBlock.TextColor, (byte)(alpha * 255));
|
||||
|
||||
@@ -555,6 +555,10 @@ namespace Barotrauma
|
||||
if (jobIdentifier > 0)
|
||||
{
|
||||
jobPrefab = JobPrefab.Prefabs.Find(jp => jp.UintIdentifier == jobIdentifier);
|
||||
if (jobPrefab == null)
|
||||
{
|
||||
throw new Exception($"Error while reading {nameof(CharacterInfo)} received from the server: could not find a job prefab with the identifier \"{jobIdentifier}\".");
|
||||
}
|
||||
foreach (SkillPrefab skillPrefab in jobPrefab.Skills.OrderBy(s => s.Identifier))
|
||||
{
|
||||
float skillLevel = inc.ReadSingle();
|
||||
@@ -562,7 +566,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: animations
|
||||
CharacterInfo ch = new CharacterInfo(speciesName, newName, originalName, jobPrefab, ragdollFile, variant, npcIdentifier: npcId)
|
||||
{
|
||||
ID = infoID,
|
||||
@@ -573,10 +576,7 @@ namespace Barotrauma
|
||||
ch.Head.HairColor = hairColor;
|
||||
ch.Head.FacialHairColor = facialHairColor;
|
||||
ch.SetPersonalityTrait();
|
||||
if (ch.Job != null)
|
||||
{
|
||||
ch.Job.OverrideSkills(skillLevels);
|
||||
}
|
||||
ch.Job?.OverrideSkills(skillLevels);
|
||||
|
||||
ch.ExperiencePoints = inc.ReadUInt16();
|
||||
ch.AdditionalTalentPoints = inc.ReadRangedInteger(0, MaxAdditionalTalentPoints);
|
||||
|
||||
@@ -593,6 +593,7 @@ namespace Barotrauma
|
||||
{
|
||||
character.MerchantIdentifier = inc.ReadIdentifier();
|
||||
}
|
||||
character.Faction = inc.ReadIdentifier();
|
||||
character.HumanPrefabHealthMultiplier = humanPrefabHealthMultiplier;
|
||||
character.Wallet.Balance = balance;
|
||||
character.Wallet.RewardDistribution = rewardDistribution;
|
||||
|
||||
@@ -87,6 +87,8 @@ namespace Barotrauma
|
||||
/// Container for the icons above the health bar
|
||||
/// </summary>
|
||||
private GUIComponent afflictionIconContainer;
|
||||
private float afflictionIconRefreshTimer;
|
||||
const float AfflictionIconRefreshInterval = 1.0f;
|
||||
|
||||
private GUIButton showHiddenAfflictionsButton;
|
||||
|
||||
@@ -861,7 +863,7 @@ namespace Barotrauma
|
||||
{
|
||||
treatmentButton.ToolTip =
|
||||
RichString.Rich(
|
||||
$"‖color:gui.green‖[{TextManager.Get(PlayerInput.MouseButtonsSwapped() ? "input.rightmouse" : "input.leftmouse")}] "
|
||||
$"‖color:gui.green‖[{PlayerInput.PrimaryMouseLabel}] "
|
||||
+ $"{TextManager.Get("quickuseaction.usetreatment")}‖color:end‖" + '\n'
|
||||
+ treatmentButton.ToolTip.NestedStr);
|
||||
}
|
||||
@@ -1157,15 +1159,20 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
afflictionIconContainer.RectTransform.SortChildren((r1, r2) =>
|
||||
afflictionIconRefreshTimer -= deltaTime;
|
||||
if (afflictionIconRefreshTimer <= 0.0f)
|
||||
{
|
||||
if (r1.GUIComponent.UserData is not AfflictionPrefab prefab1) { return -1; }
|
||||
if (r2.GUIComponent.UserData is not AfflictionPrefab prefab2) { return 1; }
|
||||
var index1 = statusIcons.IndexOf(s => s.Prefab == prefab1);
|
||||
var index2 = statusIcons.IndexOf(s => s.Prefab == prefab2);
|
||||
return index1.CompareTo(index2);
|
||||
});
|
||||
(afflictionIconContainer as GUILayoutGroup).NeedsToRecalculate = true;
|
||||
afflictionIconContainer.RectTransform.SortChildren((r1, r2) =>
|
||||
{
|
||||
if (r1.GUIComponent.UserData is not AfflictionPrefab prefab1) { return -1; }
|
||||
if (r2.GUIComponent.UserData is not AfflictionPrefab prefab2) { return 1; }
|
||||
var index1 = statusIcons.IndexOf(s => s.Prefab == prefab1);
|
||||
var index2 = statusIcons.IndexOf(s => s.Prefab == prefab2);
|
||||
return index1.CompareTo(index2);
|
||||
});
|
||||
(afflictionIconContainer as GUILayoutGroup).NeedsToRecalculate = true;
|
||||
afflictionIconRefreshTimer = AfflictionIconRefreshInterval;
|
||||
}
|
||||
|
||||
Rectangle hiddenAfflictionHoverArea = showHiddenAfflictionsButton.Rect;
|
||||
foreach (GUIComponent child in hiddenAfflictionIconContainer.Children)
|
||||
@@ -1983,6 +1990,7 @@ namespace Barotrauma
|
||||
{
|
||||
newAfflictions.Clear();
|
||||
newPeriodicEffects.Clear();
|
||||
bool newAdded = false;
|
||||
byte afflictionCount = inc.ReadByte();
|
||||
for (int i = 0; i < afflictionCount; i++)
|
||||
{
|
||||
@@ -2062,6 +2070,7 @@ namespace Barotrauma
|
||||
{
|
||||
existingAffliction = afflictionPrefab.Instantiate(strength);
|
||||
afflictions.Add(existingAffliction, limb);
|
||||
newAdded = true;
|
||||
}
|
||||
existingAffliction.SetStrength(strength);
|
||||
if (existingAffliction == stunAffliction)
|
||||
@@ -2071,6 +2080,8 @@ namespace Barotrauma
|
||||
foreach (var periodicEffect in newPeriodicEffects)
|
||||
{
|
||||
if (!existingAffliction.Prefab.PeriodicEffects.Contains(periodicEffect.effect)) { continue; }
|
||||
if (existingAffliction.Strength < periodicEffect.effect.MinStrength) { continue; }
|
||||
if (periodicEffect.effect.MaxStrength > 0 && existingAffliction.Strength > periodicEffect.effect.MaxStrength) { continue; }
|
||||
//timer has wrapped around, apply the effect
|
||||
if (periodicEffect.timer - existingAffliction.PeriodicEffectTimers[periodicEffect.effect] > periodicEffect.effect.MinInterval / 2)
|
||||
{
|
||||
@@ -2086,6 +2097,11 @@ namespace Barotrauma
|
||||
|
||||
CalculateVitality();
|
||||
DisplayedVitality = Vitality;
|
||||
|
||||
if (newAdded)
|
||||
{
|
||||
MedicalClinic.OnAfflictionCountChanged(Character);
|
||||
}
|
||||
}
|
||||
|
||||
partial void UpdateSkinTint()
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
internal static class HealingCooldown
|
||||
{
|
||||
public static float NormalizedCooldown => MathF.Min((float) (DateTimeOffset.UtcNow - OnCooldownUntil).TotalSeconds / CooldownDuration, 0f);
|
||||
public static bool IsOnCooldown => DateTimeOffset.UtcNow < OnCooldownUntil;
|
||||
|
||||
private static DateTimeOffset OnCooldownUntil = DateTimeOffset.MinValue;
|
||||
private const float CooldownDuration = 0.5f;
|
||||
|
||||
public static readonly Identifier MedicalItemTag = new Identifier("medical");
|
||||
|
||||
public static void PutOnCooldown()
|
||||
{
|
||||
OnCooldownUntil = DateTimeOffset.UtcNow.AddSeconds(CooldownDuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Barotrauma.IO;
|
||||
using Barotrauma.Utils;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using SpriteParams = Barotrauma.RagdollParams.SpriteParams;
|
||||
@@ -260,9 +261,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (enableHuskSprite)
|
||||
{
|
||||
List<WearableSprite> otherWearablesWithHusk = new List<WearableSprite>() { HuskSprite };
|
||||
otherWearablesWithHusk.AddRange(OtherWearables);
|
||||
OtherWearables = otherWearablesWithHusk;
|
||||
OtherWearables.Insert(0, HuskSprite);
|
||||
UpdateWearableTypesToHide();
|
||||
}
|
||||
else
|
||||
@@ -546,7 +545,7 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (var affliction in result.Afflictions)
|
||||
{
|
||||
if (affliction is AfflictionBleeding)
|
||||
if (affliction is AfflictionBleeding bleeding && bleeding.Prefab.DamageParticles)
|
||||
{
|
||||
bleedingDamage += affliction.GetVitalityDecrease(null);
|
||||
}
|
||||
@@ -555,7 +554,7 @@ namespace Barotrauma
|
||||
float damage = 0;
|
||||
foreach (var affliction in result.Afflictions)
|
||||
{
|
||||
if (affliction.Prefab.AfflictionType == "damage")
|
||||
if (affliction.Prefab.DamageParticles && affliction.Prefab.AfflictionType == AfflictionPrefab.DamageType)
|
||||
{
|
||||
damage += affliction.GetVitalityDecrease(null);
|
||||
}
|
||||
@@ -564,11 +563,11 @@ namespace Barotrauma
|
||||
float bleedingDamageMultiplier = 1;
|
||||
foreach (DamageModifier damageModifier in result.AppliedDamageModifiers)
|
||||
{
|
||||
if (damageModifier.MatchesAfflictionType("damage"))
|
||||
if (damageModifier.MatchesAfflictionType(AfflictionPrefab.DamageType))
|
||||
{
|
||||
damageMultiplier *= damageModifier.DamageMultiplier;
|
||||
}
|
||||
else if (damageModifier.MatchesAfflictionType("bleeding"))
|
||||
else if (damageModifier.MatchesAfflictionType(AfflictionPrefab.BleedingType))
|
||||
{
|
||||
bleedingDamageMultiplier *= damageModifier.DamageMultiplier;
|
||||
}
|
||||
@@ -728,11 +727,11 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
float herpesStrength = character.CharacterHealth.GetAfflictionStrength("spaceherpes");
|
||||
float herpesStrength = character.CharacterHealth.GetAfflictionStrength(AfflictionPrefab.SpaceHerpesType);
|
||||
|
||||
bool hideLimb = Hide ||
|
||||
OtherWearables.Any(w => w.HideLimb) ||
|
||||
wearingItems.Any(w => w != null && w.HideLimb);
|
||||
WearingItems.Any(w => w.HideLimb);
|
||||
|
||||
bool drawHuskSprite = HuskSprite != null && !wearableTypesToHide.Contains(WearableType.Husk);
|
||||
|
||||
@@ -828,7 +827,7 @@ namespace Barotrauma
|
||||
LightSource.LightSpriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipVertically;
|
||||
}
|
||||
float step = depthStep;
|
||||
WearableSprite onlyDrawable = wearingItems.Find(w => w.HideOtherWearables);
|
||||
WearableSprite onlyDrawable = WearingItems.Find(w => w.HideOtherWearables);
|
||||
if (Params.MirrorHorizontally)
|
||||
{
|
||||
spriteEffect = spriteEffect == SpriteEffects.None ? SpriteEffects.FlipHorizontally : SpriteEffects.None;
|
||||
@@ -965,31 +964,28 @@ namespace Barotrauma
|
||||
|
||||
public void UpdateWearableTypesToHide()
|
||||
{
|
||||
alphaClipEffectParams?.Clear();
|
||||
|
||||
wearableTypeHidingSprites.Clear();
|
||||
if (WearingItems != null && WearingItems.Count > 0)
|
||||
|
||||
void addWearablesFrom(IReadOnlyList<WearableSprite> wearableSprites)
|
||||
{
|
||||
if (wearableSprites.Count <= 0) { return; }
|
||||
|
||||
wearableTypeHidingSprites.AddRange(
|
||||
WearingItems.FindAll(w => w.HideWearablesOfType != null && w.HideWearablesOfType.Count > 0));
|
||||
}
|
||||
if (OtherWearables != null && OtherWearables.Count > 0)
|
||||
{
|
||||
wearableTypeHidingSprites.AddRange(
|
||||
OtherWearables.FindAll(w => w.HideWearablesOfType != null && w.HideWearablesOfType.Count > 0));
|
||||
wearableSprites.Where(w => w.HideWearablesOfType.Count > 0));
|
||||
}
|
||||
|
||||
addWearablesFrom(WearingItems);
|
||||
addWearablesFrom(OtherWearables);
|
||||
|
||||
wearableTypesToHide.Clear();
|
||||
if (wearableTypeHidingSprites.Count > 0)
|
||||
|
||||
if (wearableTypeHidingSprites.Count <= 0) { return; }
|
||||
|
||||
foreach (WearableSprite sprite in wearableTypeHidingSprites)
|
||||
{
|
||||
foreach (WearableSprite sprite in wearableTypeHidingSprites)
|
||||
{
|
||||
foreach (WearableType type in sprite.HideWearablesOfType)
|
||||
{
|
||||
if (!wearableTypesToHide.Contains(type))
|
||||
{
|
||||
wearableTypesToHide.Add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
wearableTypesToHide.UnionWith(sprite.HideWearablesOfType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1071,7 +1067,13 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawWearable(WearableSprite wearable, float depthStep, SpriteBatch spriteBatch, Color color, float alpha, SpriteEffects spriteEffect)
|
||||
private (
|
||||
Color FinalColor,
|
||||
Vector2 Origin,
|
||||
float Rotation,
|
||||
float Scale,
|
||||
float Depth)
|
||||
CalculateDrawParameters(WearableSprite wearable, float depthStep, Color color, float alpha)
|
||||
{
|
||||
var sprite = ActiveSprite;
|
||||
if (wearable.InheritSourceRect)
|
||||
@@ -1163,27 +1165,118 @@ namespace Barotrauma
|
||||
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);
|
||||
|
||||
return (finalColor, origin, rotation, scale, depth);
|
||||
}
|
||||
|
||||
private WearableSprite GetWearableSprite(WearableType type)//, bool random = false)
|
||||
private static Effect alphaClipEffect;
|
||||
private Dictionary<WearableSprite, Dictionary<string, object>> alphaClipEffectParams;
|
||||
private void ApplyAlphaClip(SpriteBatch spriteBatch, WearableSprite wearable, WearableSprite alphaClipper, SpriteEffects spriteEffect)
|
||||
{
|
||||
SpriteRecorder.Command makeCommand(WearableSprite w)
|
||||
{
|
||||
var (_, origin, rotation, scale, _)
|
||||
= CalculateDrawParameters(w, 0f, Color.White, 0f);
|
||||
|
||||
var command = SpriteRecorder.Command.FromTransform(
|
||||
texture: w.Sprite.Texture,
|
||||
pos: new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
|
||||
srcRect: w.Sprite.SourceRect,
|
||||
color: Color.White,
|
||||
rotation: rotation,
|
||||
origin: origin,
|
||||
scale: new Vector2(scale, scale),
|
||||
effects: spriteEffect,
|
||||
depth: 0f,
|
||||
index: 0);
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
void spacesFromCommand(WearableSprite w, SpriteRecorder.Command command, out CoordinateSpace2D textureSpace, out CoordinateSpace2D worldSpace)
|
||||
{
|
||||
var (topLeft, bottomLeft, topRight) = spriteEffect switch
|
||||
{
|
||||
SpriteEffects.None
|
||||
=> (command.VertexTL, command.VertexBL, command.VertexTR),
|
||||
SpriteEffects.FlipHorizontally | SpriteEffects.FlipVertically
|
||||
=> (command.VertexBR, command.VertexTR, command.VertexBL),
|
||||
SpriteEffects.FlipHorizontally
|
||||
=> (command.VertexTR, command.VertexBR, command.VertexTL),
|
||||
SpriteEffects.FlipVertically
|
||||
=> (command.VertexBL, command.VertexTL, command.VertexBR)
|
||||
};
|
||||
|
||||
textureSpace = new CoordinateSpace2D
|
||||
{
|
||||
Origin = topLeft.TextureCoordinate,
|
||||
I = topRight.TextureCoordinate - topLeft.TextureCoordinate,
|
||||
J = bottomLeft.TextureCoordinate - topLeft.TextureCoordinate
|
||||
};
|
||||
|
||||
worldSpace = new CoordinateSpace2D
|
||||
{
|
||||
Origin = topLeft.Position.DiscardZ(),
|
||||
I = topRight.Position.DiscardZ() - topLeft.Position.DiscardZ(),
|
||||
J = bottomLeft.Position.DiscardZ() - topLeft.Position.DiscardZ()
|
||||
};
|
||||
}
|
||||
|
||||
var wearableCommand = makeCommand(wearable);
|
||||
var clipperCommand = makeCommand(alphaClipper);
|
||||
|
||||
spacesFromCommand(wearable, wearableCommand, out var wearableTextureSpace, out var wearableWorldSpace);
|
||||
spacesFromCommand(alphaClipper, clipperCommand, out var clipperTextureSpace, out var clipperWorldSpace);
|
||||
|
||||
var wearableUvToClipperUv =
|
||||
wearableTextureSpace.CanonicalToLocal
|
||||
* wearableWorldSpace.LocalToCanonical
|
||||
* clipperWorldSpace.CanonicalToLocal
|
||||
* clipperTextureSpace.LocalToCanonical;
|
||||
|
||||
alphaClipEffect ??= EffectLoader.Load("Effects/wearableclip");
|
||||
alphaClipEffectParams ??= new Dictionary<WearableSprite, Dictionary<string, object>>();
|
||||
if (!alphaClipEffectParams.ContainsKey(wearable)) { alphaClipEffectParams.Add(wearable, new Dictionary<string, object>()); }
|
||||
|
||||
var paramsToPass = new SpriteBatch.EffectWithParams
|
||||
{
|
||||
Effect = alphaClipEffect,
|
||||
Params = alphaClipEffectParams[wearable]
|
||||
};
|
||||
|
||||
paramsToPass.Params["wearableUvToClipperUv"] = wearableUvToClipperUv;
|
||||
paramsToPass.Params["clipperTexelSize"] = 2f / alphaClipper.Sprite.Texture.Width;
|
||||
paramsToPass.Params["aCutoff"] = 2f / 255f;
|
||||
paramsToPass.Params["xTexture"] = wearable.Sprite.Texture;
|
||||
paramsToPass.Params["xStencil"] = alphaClipper.Sprite.Texture;
|
||||
spriteBatch.SwapEffect(paramsToPass);
|
||||
}
|
||||
|
||||
private void DrawWearable(WearableSprite wearable, float depthStep, SpriteBatch spriteBatch, Color color, float alpha, SpriteEffects spriteEffect)
|
||||
{
|
||||
var (finalColor, origin, rotation, scale, depth)
|
||||
= CalculateDrawParameters(wearable, depthStep, color, alpha);
|
||||
|
||||
var prevEffect = spriteBatch.GetCurrentEffect();
|
||||
var alphaClipper = WearingItems.Find(w => w.AlphaClipOtherWearables);
|
||||
bool shouldApplyAlphaClip = alphaClipper != null && wearable != alphaClipper;
|
||||
if (shouldApplyAlphaClip)
|
||||
{
|
||||
ApplyAlphaClip(spriteBatch, wearable, alphaClipper, spriteEffect);
|
||||
}
|
||||
wearable.Sprite.Draw(spriteBatch, new Vector2(body.DrawPosition.X, -body.DrawPosition.Y), finalColor, origin, rotation, scale, spriteEffect, depth);
|
||||
if (shouldApplyAlphaClip)
|
||||
{
|
||||
spriteBatch.SwapEffect(effect: prevEffect);
|
||||
}
|
||||
}
|
||||
|
||||
private WearableSprite GetWearableSprite(WearableType type)
|
||||
{
|
||||
var info = character.Info;
|
||||
if (info == null) { return null; }
|
||||
ContentXElement element;
|
||||
/*if (random)
|
||||
{
|
||||
element = info.FilterElements(info.Wearables, info.Head.Preset.TagSet)?.GetRandom(Rand.RandSync.ClientOnly);
|
||||
}
|
||||
else
|
||||
{*/
|
||||
element = info.FilterElements(info.Wearables, info.Head.Preset.TagSet, type)?.FirstOrDefault();
|
||||
//}
|
||||
if (element != null)
|
||||
{
|
||||
return new WearableSprite(element.GetChildElement("sprite"), type);
|
||||
}
|
||||
return null;
|
||||
ContentXElement element = info.FilterElements(info.Wearables, info.Head.Preset.TagSet, type)?.FirstOrDefault();
|
||||
return element != null ? new WearableSprite(element.GetChildElement("sprite"), type) : null;
|
||||
}
|
||||
|
||||
partial void RemoveProjSpecific()
|
||||
@@ -1206,8 +1299,8 @@ namespace Barotrauma
|
||||
LightSource?.Remove();
|
||||
LightSource = null;
|
||||
|
||||
OtherWearables?.ForEach(w => w.Sprite.Remove());
|
||||
OtherWearables = null;
|
||||
OtherWearables.ForEach(w => w.Sprite.Remove());
|
||||
OtherWearables.Clear();
|
||||
|
||||
HuskSprite?.Sprite.Remove();
|
||||
HuskSprite = null;
|
||||
|
||||
Reference in New Issue
Block a user