Merge branch 'master' of https://github.com/Regalis11/Barotrauma into develop

This commit is contained in:
EvilFactory
2023-03-13 13:32:14 -03:00
335 changed files with 11052 additions and 5179 deletions
@@ -226,7 +226,7 @@ namespace Barotrauma.Items.Components
Pusher = null;
if (element.GetAttributeBool("blocksplayers", false))
{
Pusher = new PhysicsBody(item.body.width, item.body.height, item.body.radius,
Pusher = new PhysicsBody(item.body.Width, item.body.Height, item.body.Radius,
item.body.Density,
BodyType.Dynamic,
Physics.CollisionItemBlocking,
@@ -427,10 +427,11 @@ namespace Barotrauma.Items.Components
return;
}
//cannot hold and wear an item at the same time
//(unless the slot in which it's held and worn are equal - e.g. a suit with built-in tool or weapon on one hand)
var wearable = item.GetComponent<Wearable>();
if (wearable != null)
if (wearable != null && !wearable.AllowedSlots.SequenceEqual(allowedSlots))
{
//cannot hold and wear an item at the same time
wearable.Unequip(character);
}
@@ -558,10 +559,16 @@ namespace Barotrauma.Items.Components
public override bool OnPicked(Character picker)
{
#if CLIENT
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient)
{
if (!picker.Inventory.CanBeAutoMovedToCorrectSlots(item))
{
picker.Inventory.FlashAllowedSlots(item, Color.Red);
}
return false;
}
#endif
bool wasAttached = IsAttached;
if (base.OnPicked(picker))
{
@@ -128,7 +128,7 @@ namespace Barotrauma.Items.Components
if (body != null)
{
trigger = new PhysicsBody(body.width, body.height, body.radius,
trigger = new PhysicsBody(body.Width, body.Height, body.Radius,
body.Density,
BodyType.Static,
Physics.CollisionWall,
@@ -446,7 +446,7 @@ namespace Barotrauma.Items.Components
targetItem.Condition / targetItem.MaxCondition,
emptyColor: GUIStyle.HealthBarColorLow,
fullColor: GUIStyle.HealthBarColorHigh,
textTag: targetItem.Name);
textTag: targetItem.Prefab.ShowNameInHealthBar ? targetItem.Name : string.Empty);
}
#endif
}
@@ -5,9 +5,7 @@ using FarseerPhysics.Dynamics;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
@@ -98,6 +96,9 @@ namespace Barotrauma.Items.Components
private set;
}
private readonly IReadOnlySet<Identifier> suitableProjectiles;
private enum ChargingState
{
Inactive,
@@ -130,12 +131,11 @@ namespace Barotrauma.Items.Components
// TODO: should define this in xml if we have ranged weapons that don't require aim to use
item.RequireAimToUse = true;
characterUsable = true;
suitableProjectiles = element.GetAttributeIdentifierArray(nameof(suitableProjectiles), Array.Empty<Identifier>()).ToHashSet();
if (ReloadSkillRequirement > 0 && ReloadNoSkill <= reload)
{
DebugConsole.AddWarning($"Invalid XML at {item.Name}: ReloadNoSkill is lower or equal than it's reload skill, despite having ReloadSkillRequirement.");
}
InitProjSpecific(element);
}
@@ -143,7 +143,8 @@ namespace Barotrauma.Items.Components
public override void Equip(Character character)
{
ReloadTimer = Math.Min(reload, 1.0f);
//clamp above 1 to prevent rapid-firing by swapping weapons
ReloadTimer = Math.Max(Math.Min(reload, 1.0f), ReloadTimer);
IsActive = true;
}
@@ -259,7 +260,8 @@ namespace Barotrauma.Items.Components
{
Vector2 barrelPos = TransformedBarrelPos + item.body.SimPosition;
float rotation = (Item.body.Dir == 1.0f) ? Item.body.Rotation : Item.body.Rotation - MathHelper.Pi;
float spread = GetSpread(character) * Rand.Range(-0.5f, 0.5f);
float spread = GetSpread(character) * Projectile.GetSpreadFromPool(projectile.SpreadCounter);
var lastProjectile = LastProjectile;
if (lastProjectile != projectile)
{
@@ -275,7 +277,7 @@ namespace Barotrauma.Items.Components
{
Item.body.ApplyLinearImpulse(new Vector2((float)Math.Cos(projectile.Item.body.Rotation), (float)Math.Sin(projectile.Item.body.Rotation)) * Item.body.Mass * -50.0f, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
}
projectile.Item.body.ApplyTorque(projectile.Item.body.Mass * degreeOfFailure * Rand.Range(-10.0f, 10.0f));
projectile.Item.body.ApplyTorque(projectile.Item.body.Mass * degreeOfFailure * 20.0f * Projectile.GetSpreadFromPool(projectile.SpreadCounter));
}
Item.RemoveContained(projectile.Item);
}
@@ -294,39 +296,41 @@ namespace Barotrauma.Items.Components
public Projectile FindProjectile(bool triggerOnUseOnContainers = false)
{
var containedItems = item.OwnInventory?.AllItemsMod;
if (containedItems == null) { return null; }
foreach (Item item in containedItems)
foreach (ItemContainer container in item.GetComponents<ItemContainer>())
{
if (item == null) { continue; }
Projectile projectile = item.GetComponent<Projectile>();
if (projectile != null) { return projectile; }
}
//projectile not found, see if one of the contained items contains projectiles
foreach (Item it in containedItems)
{
if (it == null) { continue; }
var containedSubItems = it.OwnInventory?.AllItemsMod;
if (containedSubItems == null) { continue; }
foreach (Item subItem in containedSubItems)
foreach (Item containedItem in container.Inventory.AllItemsMod)
{
if (subItem == null) { continue; }
Projectile projectile = subItem.GetComponent<Projectile>();
//apply OnUse statuseffects to the container in case it has to react to it somehow
//(play a sound, spawn more projectiles, reduce condition...)
if (triggerOnUseOnContainers && subItem.Condition > 0.0f)
if (containedItem == null) { continue; }
Projectile projectile = containedItem.GetComponent<Projectile>();
if (IsSuitableProjectile(projectile)) { return projectile; }
//projectile not found, see if the contained item contains projectiles
var containedSubItems = containedItem.OwnInventory?.AllItemsMod;
if (containedSubItems == null) { continue; }
foreach (Item subItem in containedSubItems)
{
subItem.GetComponent<ItemContainer>()?.Item.ApplyStatusEffects(ActionType.OnUse, 1.0f);
}
if (projectile != null) { return projectile; }
if (subItem == null) { continue; }
Projectile subProjectile = subItem.GetComponent<Projectile>();
//apply OnUse statuseffects to the container in case it has to react to it somehow
//(play a sound, spawn more projectiles, reduce condition...)
if (triggerOnUseOnContainers && subItem.Condition > 0.0f)
{
subItem.GetComponent<ItemContainer>()?.Item.ApplyStatusEffects(ActionType.OnUse, 1.0f);
}
if (IsSuitableProjectile(subProjectile)) { return subProjectile; }
}
}
}
return null;
}
private bool IsSuitableProjectile(Projectile projectile)
{
if (projectile?.Item == null) { return false; }
if (!suitableProjectiles.Any()) { return true; }
return suitableProjectiles.Any(s => projectile.Item.Prefab.Identifier == s || projectile.Item.HasTag(s));
}
partial void LaunchProjSpecific();
}
class AbilityRangedWeapon : AbilityObject, IAbilityItem
@@ -100,6 +100,9 @@ namespace Barotrauma.Items.Components
[Serialize(false, IsPropertySaveable.No, description: "Can the item hit broken doors.")]
public bool HitBrokenDoors { get; set; }
[Serialize(false, IsPropertySaveable.No, description: "Should the tool ignore characters? Enabled e.g. for fire extinguisher.")]
public bool IgnoreCharacters { get; set; }
[Serialize(0.0f, IsPropertySaveable.No, description: "The probability of starting a fire somewhere along the ray fired from the barrel (for example, 0.1 = 10% chance to start a fire during a second of use).")]
public float FireProbability { get; set; }
@@ -313,7 +316,11 @@ namespace Barotrauma.Items.Components
private readonly List<FireSource> fireSourcesInRange = new List<FireSource>();
private void Repair(Vector2 rayStart, Vector2 rayEnd, float deltaTime, Character user, float degreeOfSuccess, List<Body> ignoredBodies)
{
var collisionCategories = Physics.CollisionWall | Physics.CollisionCharacter | Physics.CollisionItem | Physics.CollisionLevel | Physics.CollisionRepair;
var collisionCategories = Physics.CollisionWall | Physics.CollisionItem | Physics.CollisionLevel | Physics.CollisionRepair;
if (!IgnoreCharacters)
{
collisionCategories |= Physics.CollisionCharacter;
}
//if the item can cut off limbs, activate nearby bodies to allow the raycast to hit them
if (statusEffectLists != null)
@@ -703,7 +710,7 @@ namespace Barotrauma.Items.Components
private float repairTimer;
private Gap previousGap;
private readonly float repairTimeOut = 5;
public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective)
public override bool CrewAIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective)
{
if (!(objective.OperateTarget is Gap leak))
{
@@ -42,6 +42,8 @@ namespace Barotrauma.Items.Components
}
}
public const float WaterDragCoefficient = 0.5f;
public override bool Use(float deltaTime, Character character = null)
{
//actual throwing logic is handled in Update
@@ -59,6 +61,7 @@ namespace Barotrauma.Items.Components
base.Drop(dropper);
throwState = ThrowState.None;
throwAngle = ThrowAngleStart;
Item.ResetWaterDragCoefficient();
}
public override void UpdateBroken(float deltaTime, Camera cam)
@@ -97,6 +100,7 @@ namespace Barotrauma.Items.Components
}
item.body.CollidesWith = Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionPlatform;
midAir = false;
Item.ResetWaterDragCoefficient();
}
return;
}
@@ -188,6 +192,7 @@ namespace Barotrauma.Items.Components
}
item.Drop(CurrentThrower, createNetworkEvent: GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer);
item.WaterDragCoefficient = WaterDragCoefficient;
item.body.ApplyLinearImpulse(throwVector * ThrowForce * item.body.Mass * 3.0f, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
//disable platform collisions until the item comes back to rest again