Unstable 1.1.14.0

This commit is contained in:
Markus Isberg
2023-10-02 16:43:54 +03:00
parent 94f5a93a0c
commit cf8f0de659
606 changed files with 21906 additions and 11456 deletions
@@ -50,9 +50,9 @@ namespace Barotrauma
}
else if (Entity is Item i)
{
if (i.Submarine != null && i.GetComponent<Items.Components.Door>() == null)
if (i.Submarine != null && i.Container != null)
{
// Don't show items that are inside the submarine, because monsters shouldn't target them when they are inside and the monsters are outside.
// Don't show contained items that are inside the submarine, because they shouldn't attract monsters.
return;
}
color = Color.CadetBlue;
@@ -82,15 +82,20 @@ namespace Barotrauma
{
var previousNode = path.Nodes[i - 1];
var currentNode = path.Nodes[i];
bool isPathActive = !path.Finished && !path.IsAtEndNode;
Color pathColor = isPathActive ? Color.Blue * 0.5f : Color.Gray;
GUI.DrawLine(spriteBatch,
new Vector2(currentNode.DrawPosition.X, -currentNode.DrawPosition.Y),
new Vector2(previousNode.DrawPosition.X, -previousNode.DrawPosition.Y),
Color.Blue * 0.5f, 0, 3);
pathColor, 0, 3);
GUIStyle.SmallFont.DrawString(spriteBatch,
currentNode.ID.ToString(),
new Vector2(currentNode.DrawPosition.X - 10, -currentNode.DrawPosition.Y - 30),
Color.Blue);
if (isPathActive)
{
GUIStyle.SmallFont.DrawString(spriteBatch,
currentNode.ID.ToString(),
new Vector2(currentNode.DrawPosition.X - 10, -currentNode.DrawPosition.Y - 30),
Color.Blue);
}
}
if (path.CurrentNode != null)
{
@@ -469,6 +469,7 @@ namespace Barotrauma
float gibParticleAmount = MathHelper.Clamp(limb.Mass / character.AnimController.Mass, 0.1f, 1.0f);
foreach (ParticleEmitter emitter in character.GibEmitters)
{
if (emitter?.Prefab == null) { continue; }
if (inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Air) { continue; }
if (!inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Water) { continue; }
@@ -23,8 +23,6 @@ namespace Barotrauma
protected float hudInfoTimer = 1.0f;
protected bool hudInfoVisible = false;
private float pressureParticleTimer;
private float findFocusedTimer;
protected float lastRecvPositionUpdateTime;
@@ -299,7 +297,9 @@ namespace Barotrauma
keys[i].SetState();
}
if (CharacterInventory.IsMouseOnInventory && CharacterHUD.ShouldDrawInventory(this))
if (CharacterInventory.IsMouseOnInventory &&
!keys[(int)InputType.Aim].Held &&
CharacterHUD.ShouldDrawInventory(this))
{
ResetInputIfPrimaryMouse(InputType.Use);
ResetInputIfPrimaryMouse(InputType.Shoot);
@@ -340,13 +340,6 @@ namespace Barotrauma
cam.Zoom = MathHelper.Lerp(cam.Zoom,
cam.DefaultZoom + (Math.Max(pressure, 10) / 150.0f) * Rand.Range(0.9f, 1.1f),
zoomInEffectStrength);
pressureParticleTimer += pressure * deltaTime;
if (pressureParticleTimer > 10.0f)
{
GameMain.ParticleManager.CreateParticle(Params.BleedParticleWater, WorldPosition + Rand.Vector(5.0f), Rand.Vector(10.0f));
pressureParticleTimer = 0.0f;
}
}
}
@@ -722,7 +715,8 @@ namespace Barotrauma
break;
default:
var petBehavior = enemyAI.PetBehavior;
if (petBehavior != null && petBehavior.Happiness < petBehavior.MaxHappiness * 0.25f)
if (petBehavior != null &&
(petBehavior.Happiness < petBehavior.UnhappyThreshold || petBehavior.Hunger > petBehavior.HungryThreshold))
{
PlaySound(CharacterSound.SoundType.Unhappy);
}
@@ -859,21 +853,11 @@ namespace Barotrauma
if (Controlled.AnimController.Stairs != null)
{
//consider the bottom of the stairs the "floor of the room the controlled character is in"
yPos = Controlled.AnimController.Stairs.SimPosition.Y - Controlled.AnimController.Stairs.RectHeight * 0.5f;
}
foreach (var ladder in Ladder.List)
{
if (CanInteractWith(ladder.Item) && Controlled.CanInteractWith(ladder.Item))
{
float xPos = ladder.Item.SimPosition.X;
if (Math.Abs(xPos - SimPosition.X) < 3.0)
{
yPos = ladder.Item.SimPosition.Y - ladder.Item.RectHeight * 0.5f;
}
break;
}
}
//don't show the HUD texts if the character is below the floor of the room the controlled character is in
if (AnimController.FloorY < yPos) { return; }
}
@@ -99,7 +99,7 @@ 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 ?
Character.CharacterHealth.GetAfflictionStrengthByType(AfflictionPrefab.PoisonType) > 0 || Character.CharacterHealth.GetAfflictionStrengthByType(AfflictionPrefab.ParalysisType) > 0 ?
GUIStyle.HealthBarColorPoisoned : GUIStyle.Red;
public override string NumberToDisplay => string.Empty;
@@ -19,7 +19,6 @@ namespace Barotrauma
public bool LastControlled;
public int CrewListIndex { get; set; } = -1;
#warning TODO: Refactor
private Sprite disguisedPortrait;
private List<WearableSprite> disguisedAttachmentSprites;
private Vector2? disguisedSheetIndex;
@@ -609,7 +608,6 @@ namespace Barotrauma
CharacterInfo = info;
parentComponent = parent;
HasIcon = hasIcon;
RecreateFrameContents();
}
@@ -848,6 +846,12 @@ namespace Barotrauma
var info = CharacterInfo;
if (info.HeadSprite == null)
{
DebugConsole.ThrowError($"Head Selection: the head sprite is null! Failed to open the head selection.");
return false;
}
float characterHeightWidthRatio = info.HeadSprite.size.Y / info.HeadSprite.size.X;
HeadSelectionList ??= new GUIListBox(
new RectTransform(
@@ -885,8 +889,13 @@ namespace Barotrauma
GUILayoutGroup row = null;
int itemsInRow = 0;
ContentXElement headElement = info.Ragdoll.MainElement.Elements().FirstOrDefault(e =>
ContentXElement headElement = info.Ragdoll.MainElement?.Elements().FirstOrDefault(e =>
e.GetAttributeString("type", "").Equals("head", StringComparison.OrdinalIgnoreCase));
if (headElement == null)
{
DebugConsole.ThrowError($"Head Selection: the head element is null in {info.ragdoll.FileName}! Failed to open the head selection.");
return false;
}
ContentXElement headSpriteElement = headElement.GetChildElement("sprite");
ContentPath spritePathWithTags = headSpriteElement.GetAttributeContentPath("texture");
@@ -963,7 +972,7 @@ namespace Barotrauma
private bool SwitchAttachment(GUIScrollBar scrollBar, WearableType type)
{
var info = CharacterInfo;
int index = (int)scrollBar.BarScrollValue;
int index = (int)Math.Round(scrollBar.BarScrollValue);
switch (type)
{
case WearableType.Beard:
@@ -201,9 +201,9 @@ namespace Barotrauma
keys[(int)InputType.Use].Held = useInput;
keys[(int)InputType.Use].SetState(false, useInput);
bool crouching = msg.ReadBoolean();
if (AnimController is HumanoidAnimController)
{
bool crouching = msg.ReadBoolean();
keys[(int)InputType.Crouch].Held = crouching;
keys[(int)InputType.Crouch].SetState(false, crouching);
}
@@ -269,7 +269,34 @@ namespace Barotrauma
if (readStatus)
{
ReadStatus(msg);
AIController?.ClientRead(msg);
bool isEnemyAi = msg.ReadBoolean();
if (isEnemyAi)
{
byte aiState = msg.ReadByte();
if (AIController is EnemyAIController enemyAi)
{
enemyAi.State = (AIState)aiState;
}
else
{
DebugConsole.AddWarning($"Received enemy AI data for a character with no {nameof(EnemyAIController)}. Ignoring...");
}
bool isPet = msg.ReadBoolean();
if (isPet)
{
byte happiness = msg.ReadByte();
byte hunger = msg.ReadByte();
if ((AIController as EnemyAIController)?.PetBehavior is PetBehavior petBehavior)
{
petBehavior.Happiness = (float)happiness / byte.MaxValue * petBehavior.MaxHappiness;
petBehavior.Hunger = (float)hunger / byte.MaxValue * petBehavior.MaxHunger;
}
else
{
DebugConsole.AddWarning($"Received pet AI data for a character with no {nameof(PetBehavior)}. Ignoring...");
}
}
}
}
msg.ReadPadBits();
@@ -323,7 +350,7 @@ namespace Barotrauma
}
else
{
Inventory.ClientEventRead(msg, sendingTime);
Inventory.ClientEventRead(msg);
}
break;
case EventType.Control:
@@ -379,7 +406,7 @@ namespace Barotrauma
float targetY = msg.ReadSingle();
Vector2 targetSimPos = new Vector2(targetX, targetY);
//255 = entity already removed, no need to do anything
if (attackLimbIndex == 255 || Removed) { break; }
if (attackLimbIndex == 255 || targetEntityID == NullEntityID || Removed) { break; }
if (attackLimbIndex >= AnimController.Limbs.Length)
{
//it's possible to get these errors when mid-round syncing, as the client may not
@@ -639,7 +666,7 @@ namespace Barotrauma
}
else
{
DebugConsole.ThrowError("Could not set order \"" + orderPrefab.Identifier + "\" for character \"" + character.Name + "\" because required target entity was not found.");
DebugConsole.AddSafeError("Could not set order \"" + orderPrefab.Identifier + "\" for character \"" + character.Name + "\" because required target entity was not found.");
}
}
else
@@ -257,7 +257,8 @@ namespace Barotrauma
{
for (int i = 0; i < character.Inventory.Capacity; i++)
{
if (character.Inventory.SlotTypes[i] != InvSlotType.HealthInterface || Character.Controlled != Character) { continue; }
if (character.Inventory.SlotTypes[i] != InvSlotType.HealthInterface) { continue; }
if (character.Inventory.HideSlot(i)) { continue; }
//don't draw the item if it's being dragged out of the slot
bool drawItem = !Inventory.DraggingItems.Any() || !Character.Inventory.GetItemsAt(i).All(it => Inventory.DraggingItems.Contains(it)) || character.Inventory.visualSlots[i].MouseOn();
@@ -479,6 +480,17 @@ namespace Barotrauma
inventoryScale = Inventory.UIScale;
uiScale = GUI.Scale;
showHiddenAfflictionsButton.RectTransform.NonScaledSize = new Point(afflictionIconContainer.Rect.Height);
//remove affliction icons so we recreate and resize them
for (int i = afflictionIconContainer.CountChildren - 1; i >= 0; i--)
{
var child = afflictionIconContainer.GetChild(i);
if (child.UserData is AfflictionPrefab)
{
afflictionIconContainer.RemoveChild(child);
}
}
healthBarHolder.RectTransform.AbsoluteOffset = HUDLayoutSettings.HealthBarArea.Location;
healthBarHolder.RectTransform.NonScaledSize = HUDLayoutSettings.HealthBarArea.Size;
healthBarHolder.RectTransform.RelativeOffset = Vector2.Zero;
@@ -496,6 +508,8 @@ namespace Barotrauma
}
healthWindow.RectTransform.RecalculateChildren(false);
Character.Inventory?.RefreshSlotPositions();
}
public void UpdateClientSpecific(float deltaTime)
@@ -579,7 +593,7 @@ namespace Barotrauma
bool inWater = Character.AnimController.InWater;
var drawTarget = inWater ? Particles.ParticlePrefab.DrawTargetType.Water : Particles.ParticlePrefab.DrawTargetType.Air;
var emitter = Character.BloodEmitters.FirstOrDefault(e => e.Prefab.ParticlePrefab.DrawTarget == drawTarget || e.Prefab.ParticlePrefab.DrawTarget == Particles.ParticlePrefab.DrawTargetType.Both);
var emitter = Character.BloodEmitters.FirstOrDefault(e => e.Prefab.ParticlePrefab?.DrawTarget == drawTarget || e.Prefab.ParticlePrefab?.DrawTarget == Particles.ParticlePrefab.DrawTargetType.Both);
float particleMinScale = emitter?.Prefab.Properties.ScaleMin ?? 0.5f;
float particleMaxScale = emitter?.Prefab.Properties.ScaleMax ?? 1;
float severity = Math.Min(affliction.Strength / affliction.Prefab.MaxStrength * Character.Params.BleedParticleMultiplier, 1);
@@ -2129,7 +2143,7 @@ namespace Barotrauma
{
var affliction = kvp.Key;
float burnStrength = affliction.Strength / Math.Min(affliction.Prefab.MaxStrength, 100) * affliction.Prefab.BurnOverlayAlpha;
if (kvp.Value == limbHealths[limb.HealthIndex])
if (kvp.Value == limbHealths[limb.HealthIndex] || !affliction.Prefab.LimbSpecific)
{
limb.BurnOverlayStrength += burnStrength;
limb.DamageOverlayStrength += affliction.Strength / Math.Min(affliction.Prefab.MaxStrength, 100) * affliction.Prefab.DamageOverlayAlpha;
@@ -12,8 +12,6 @@ namespace Barotrauma
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);
@@ -432,20 +432,20 @@ namespace Barotrauma
{
if (Sprite != null)
{
Sprite.Remove();
var source = Sprite.SourceElement;
Sprite.Remove();
Sprite = new Sprite(source, file: GetSpritePath(source, Params.normalSpriteParams, ref _texturePath));
}
if (_deformSprite != null)
{
_deformSprite.Remove();
var source = _deformSprite.Sprite.SourceElement;
_deformSprite.Remove();
_deformSprite = new DeformableSprite(source, filePath: GetSpritePath(source, Params.deformSpriteParams, ref _texturePath));
}
if (DamagedSprite != null)
{
DamagedSprite.Remove();
var source = DamagedSprite.SourceElement;
DamagedSprite.Remove();
DamagedSprite = new Sprite(source, file: GetSpritePath(source, Params.damagedSpriteParams, ref _damagedTexturePath));
}
for (int i = 0; i < ConditionalSprites.Count; i++)
@@ -458,8 +458,8 @@ namespace Barotrauma
for (int i = 0; i < DecorativeSprites.Count; i++)
{
var decorativeSprite = DecorativeSprites[i];
decorativeSprite.Remove();
var source = decorativeSprite.Sprite.SourceElement;
decorativeSprite.Remove();
DecorativeSprites[i] = new DecorativeSprite(source, file: GetSpritePath(source, Params.decorativeSpriteParams[i], ref _texturePath));
}
}
@@ -478,9 +478,18 @@ namespace Barotrauma
{
if (spriteParams != null)
{
ContentPath texturePath =
character.Params.VariantFile?.Root?.GetAttributeContentPath("texture", character.Prefab.ContentPackage)
?? ContentPath.FromRaw(spriteParams.Element.ContentPackage ?? character.Prefab.ContentPackage, spriteParams.GetTexturePath());
//1. check if the variant file redefines the texture
ContentPath texturePath = character.Params.VariantFile?.Root?.GetAttributeContentPath("texture", character.Prefab.ContentPackage);
//2. check if the base prefab defines the texture
if (texturePath.IsNullOrEmpty() && !character.Prefab.VariantOf.IsEmpty)
{
RagdollParams parentRagdollParams = character.IsHumanoid ?
RagdollParams.GetRagdollParams<HumanRagdollParams>(character.Prefab.VariantOf) :
RagdollParams.GetRagdollParams<FishRagdollParams>(character.Prefab.VariantOf);
texturePath = parentRagdollParams.OriginalElement?.GetAttributeContentPath("texture");
}
//3. "default case", get the texture from this character's XML
texturePath ??= ContentPath.FromRaw(spriteParams.Element.ContentPackage ?? character.Prefab.ContentPackage, spriteParams.GetTexturePath());
path = GetSpritePath(texturePath);
}
else
@@ -592,6 +601,7 @@ namespace Barotrauma
{
foreach (ParticleEmitter emitter in character.DamageEmitters)
{
if (emitter?.Prefab == null) { continue; }
if (InWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Air) { continue; }
if (!InWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Water) { continue; }
ParticlePrefab overrideParticle = null;
@@ -614,6 +624,7 @@ namespace Barotrauma
foreach (ParticleEmitter emitter in character.BloodEmitters)
{
if (emitter?.Prefab == null) { continue; }
if (InWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Air) { continue; }
if (!InWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Water) { continue; }
emitter.Emit(1.0f, WorldPosition, character.CurrentHull, sizeMultiplier: bloodParticleSize, amountMultiplier: bloodParticleAmount);
@@ -727,7 +738,7 @@ namespace Barotrauma
}
}
float herpesStrength = character.CharacterHealth.GetAfflictionStrength(AfflictionPrefab.SpaceHerpesType);
float herpesStrength = character.CharacterHealth.GetAfflictionStrengthByType(AfflictionPrefab.SpaceHerpesType);
bool hideLimb = Hide ||
OtherWearables.Any(w => w.HideLimb) ||
@@ -890,6 +901,28 @@ namespace Barotrauma
foreach (WearableSprite wearable in WearingItems)
{
if (onlyDrawable != null && onlyDrawable != wearable && wearable.CanBeHiddenByOtherWearables) { continue; }
if (wearable.CanBeHiddenByItem.Any())
{
bool hiddenByOtherItem = false;
foreach (var otherWearable in WearingItems)
{
if (otherWearable == wearable) { continue; }
if (wearable.CanBeHiddenByItem.Contains(otherWearable.WearableComponent.Item.Prefab.Identifier))
{
hiddenByOtherItem = true;
break;
}
foreach (Identifier tag in wearable.CanBeHiddenByItem)
{
if (otherWearable.WearableComponent.Item.HasTag(tag))
{
hiddenByOtherItem = true;
break;
}
}
}
if (hiddenByOtherItem) { continue; }
}
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;
@@ -1260,12 +1293,11 @@ namespace Barotrauma
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);
if (wearable.Sprite?.Texture == null) { return; }
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;
bool shouldApplyAlphaClip = alphaClipper?.Sprite?.Texture != null && wearable != alphaClipper;
if (shouldApplyAlphaClip)
{
ApplyAlphaClip(spriteBatch, wearable, alphaClipper, spriteEffect);
@@ -1308,13 +1340,13 @@ namespace Barotrauma
OtherWearables.ForEach(w => w.Sprite.Remove());
OtherWearables.Clear();
HuskSprite?.Sprite.Remove();
HuskSprite?.Sprite?.Remove();
HuskSprite = null;
HairWithHatSprite?.Sprite.Remove();
HairWithHatSprite?.Sprite?.Remove();
HairWithHatSprite = null;
HerpesSprite?.Sprite.Remove();
HerpesSprite?.Sprite?.Remove();
HerpesSprite = null;
TintMask?.Remove();