Merge branch 'dev' of https://github.com/Regalis11/Barotrauma into unstable

This commit is contained in:
EvilFactory
2022-09-29 12:13:55 -03:00
602 changed files with 19759 additions and 16312 deletions
@@ -295,12 +295,11 @@ namespace Barotrauma.Items.Components
if (attachable)
{
DeattachFromWall();
if (body != null)
{
item.body = body;
}
DeattachFromWall();
}
if (Pusher != null) { Pusher.Enabled = false; }
@@ -619,6 +618,10 @@ namespace Barotrauma.Items.Components
#if CLIENT
item.DrawDepthOffset = SpriteDepthWhenDropped - item.SpriteDepth;
#endif
foreach (LightComponent light in item.GetComponents<LightComponent>())
{
light.CheckIfNeedsUpdate();
}
}
public override void ParseMsg()
@@ -691,12 +694,30 @@ namespace Barotrauma.Items.Components
{
item.Drop(character);
item.SetTransform(ConvertUnits.ToSimUnits(GetAttachPosition(character)), 0.0f, findNewHull: false);
//the light source won't get properly updated if lighting is disabled (even though the light sprite is still drawn when lighting is disabled)
//so let's ensure the light source is up-to-date
RefreshLightSources(item);
}
AttachToWall();
}
return true;
static void RefreshLightSources(Item item)
{
item.body?.UpdateDrawPosition();
foreach (var light in item.GetComponents<LightComponent>())
{
light.SetLightSourceTransform();
}
item.GetComponent<ItemContainer>()?.SetContainedItemPositions();
foreach (var containedItem in item.ContainedItems)
{
RefreshLightSources(containedItem);
}
}
}
public override bool SecondaryUse(float deltaTime, Character character = null)
{
return true;
@@ -1,12 +1,11 @@
using Barotrauma.Networking;
using FarseerPhysics;
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Contacts;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
@@ -64,7 +63,7 @@ namespace Barotrauma.Items.Components
/// <summary>
/// Defines items that boost the weapon functionality, like battery cell for stun batons.
/// </summary>
public readonly Identifier[] PreferredContainedItems;
public readonly ImmutableHashSet<Identifier> PreferredContainedItems;
public MeleeWeapon(Item item, ContentXElement element)
: base(item, element)
@@ -79,7 +78,7 @@ namespace Barotrauma.Items.Components
}
item.IsShootable = true;
item.RequireAimToUse = element.Parent.GetAttributeBool("requireaimtouse", true);
PreferredContainedItems = element.GetAttributeIdentifierArray("preferredcontaineditems", Array.Empty<Identifier>());
PreferredContainedItems = element.GetAttributeIdentifierArray("preferredcontaineditems", Array.Empty<Identifier>()).ToImmutableHashSet();
}
public override void Equip(Character character)
@@ -292,7 +291,6 @@ namespace Barotrauma.Items.Components
item.body.PhysEnabled = false;
}
private bool OnCollision(Fixture f1, Fixture f2, Contact contact)
{
if (User == null || User.Removed)
@@ -390,15 +388,17 @@ namespace Barotrauma.Items.Components
User = null;
return;
}
float damageMultiplier = 1 + User.GetStatValue(StatTypes.MeleeAttackMultiplier);
damageMultiplier *= 1.0f + item.GetQualityModifier(Quality.StatType.StrikingPowerMultiplier);
Limb targetLimb = target.UserData as Limb;
Character targetCharacter = targetLimb?.character ?? target.UserData as Character;
GameMain.LuaCs.Hook.Call("meleeWeapon.handleImpact", this, target);
if (Attack != null)
{
Attack.SetUser(User);
Attack.DamageMultiplier = 1 + User.GetStatValue(StatTypes.MeleeAttackMultiplier);
Attack.DamageMultiplier *= 1.0f + item.GetQualityModifier(Quality.StatType.StrikingPowerMultiplier);
Attack.DamageMultiplier = damageMultiplier;
if (targetLimb != null)
{
@@ -420,7 +420,18 @@ namespace Barotrauma.Items.Components
else if (target.UserData is Item targetItem && targetItem.Prefab.DamagedByMeleeWeapons && targetItem.Condition > 0)
{
if (targetItem.Removed) { return; }
Attack.DoDamage(User, targetItem, item.WorldPosition, 1.0f);
var attackResult = Attack.DoDamage(User, targetItem, item.WorldPosition, 1.0f);
#if CLIENT
if (attackResult.Damage > 0.0f)
{
Character.Controlled?.UpdateHUDProgressBar(targetItem,
targetItem.WorldPosition,
targetItem.Condition / targetItem.MaxCondition,
emptyColor: GUIStyle.HealthBarColorLow,
fullColor: GUIStyle.HealthBarColorHigh,
textTag: targetItem.Name);
}
#endif
}
else if (target.UserData is Holdable holdable && holdable.CanPush)
{
@@ -460,7 +471,7 @@ namespace Barotrauma.Items.Components
if (targetCharacter != null) //TODO: Allow OnUse to happen on structures too maybe??
{
ApplyStatusEffects(success ? ActionType.OnUse : ActionType.OnFailure, 1.0f, targetCharacter, targetLimb, user: User);
ApplyStatusEffects(success ? ActionType.OnUse : ActionType.OnFailure, 1.0f, targetCharacter, targetLimb, user: User, afflictionMultiplier: damageMultiplier);
}
if (DeleteOnUse)
@@ -165,31 +165,32 @@ namespace Barotrauma.Items.Components
pickTimer = 0.0f;
while (pickTimer < requiredTime && Screen.Selected != GameMain.SubEditorScreen)
{
//cancel if the item is currently selected
//attempting to pick does not select the item, so if it is selected at this point, another ItemComponent
//must have been selected and we should not keep deattaching (happens when for example interacting with
//an electrical component while holding both a screwdriver and a wrench).
if (picker.SelectedConstruction == item ||
picker.IsKeyDown(InputType.Aim) ||
!picker.CanInteractWith(item) ||
item.Removed || item.ParentInventory != null)
if (!CoroutineManager.Paused)
{
StopPicking(picker);
yield return CoroutineStatus.Success;
}
//cancel if the item is currently selected
//attempting to pick does not select the item, so if it is selected at this point, another ItemComponent
//must have been selected and we should not keep deattaching (happens when for example interacting with
//an electrical component while holding both a screwdriver and a wrench).
if (picker.IsAnySelectedItem(item) ||
picker.IsKeyDown(InputType.Aim) ||
!picker.CanInteractWith(item) ||
item.Removed || item.ParentInventory != null)
{
StopPicking(picker);
yield return CoroutineStatus.Success;
}
#if CLIENT
Character.Controlled?.UpdateHUDProgressBar(
this,
item.WorldPosition,
pickTimer / requiredTime,
GUIStyle.Red, GUIStyle.Green,
!string.IsNullOrWhiteSpace(PickingMsg) ? PickingMsg : this is Door ? "progressbar.opening" : "progressbar.deattaching");
Character.Controlled?.UpdateHUDProgressBar(
this,
item.WorldPosition,
pickTimer / requiredTime,
GUIStyle.Red, GUIStyle.Green,
!string.IsNullOrWhiteSpace(PickingMsg) ? PickingMsg : this is Door ? "progressbar.opening" : "progressbar.deattaching");
#endif
picker.AnimController.UpdateUseItem(true, item.WorldPosition + new Vector2(0.0f, 100.0f) * ((pickTimer / 10.0f) % 0.1f));
pickTimer += CoroutineManager.DeltaTime;
picker.AnimController.UpdateUseItem(!picker.IsClimbing, item.WorldPosition + new Vector2(0.0f, 100.0f) * ((pickTimer / 10.0f) % 0.1f));
pickTimer += CoroutineManager.DeltaTime;
}
yield return CoroutineStatus.Running;
}
@@ -208,7 +209,7 @@ namespace Barotrauma.Items.Components
{
if (picker != null)
{
picker.AnimController.Anim = AnimController.Animation.None;
picker.AnimController.StopUsingItem();
picker.PickingItem = null;
}
if (pickingCoroutine != null)
@@ -286,7 +287,7 @@ namespace Barotrauma.Items.Components
public virtual void ServerEventWrite(IWriteMessage msg, Client c, NetEntityEvent.IData extraData = null)
{
msg.Write(activePicker?.ID ?? (ushort)0);
msg.WriteUInt16(activePicker?.ID ?? (ushort)0);
}
public virtual void ClientEventRead(IReadMessage msg, float sendingTime)
@@ -18,6 +18,7 @@ namespace Barotrauma.Items.Components
};
private readonly HashSet<Identifier> fixableEntities;
private readonly HashSet<Identifier> nonFixableEntities;
private Vector2 pickedPosition;
private float activeTimer;
@@ -135,6 +136,7 @@ namespace Barotrauma.Items.Components
}
fixableEntities = new HashSet<Identifier>();
nonFixableEntities = new HashSet<Identifier>();
foreach (var subElement in element.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
@@ -147,7 +149,16 @@ namespace Barotrauma.Items.Components
}
else
{
fixableEntities.Add(subElement.GetAttributeIdentifier("identifier", ""));
foreach (Identifier id in subElement.GetAttributeIdentifierArray("identifier", Array.Empty<Identifier>()))
{
fixableEntities.Add(id);
}
}
break;
case "nonfixable":
foreach (Identifier id in subElement.GetAttributeIdentifierArray("identifier", Array.Empty<Identifier>()))
{
nonFixableEntities.Add(id);
}
break;
}
@@ -523,6 +534,7 @@ namespace Barotrauma.Items.Components
if (sectionIndex < 0) { return false; }
if (!fixableEntities.Contains("structure") && !fixableEntities.Contains(targetStructure.Prefab.Identifier)) { return true; }
if (nonFixableEntities.Contains(targetStructure.Prefab.Identifier) || nonFixableEntities.Any(t => targetStructure.Tags.Contains(t))) { return false; }
ApplyStatusEffectsOnTarget(user, deltaTime, ActionType.OnUse, structure: targetStructure);
FixStructureProjSpecific(user, deltaTime, targetStructure, sectionIndex);
@@ -111,6 +111,12 @@ namespace Barotrauma.Items.Components
}
ApplyStatusEffects(ActionType.OnActive, deltaTime, picker);
//return if the status effect got rid of the picker somehow
if (picker == null || picker.Removed || !picker.HeldItems.Contains(item))
{
IsActive = false;
return;
}
if (item.body.Dir != picker.AnimController.Dir) { item.FlipX(relativeToSub: false); }