Build 1.1.4.0

This commit is contained in:
Markus Isberg
2023-03-31 18:40:44 +03:00
parent efba17e0ff
commit 9470edead3
483 changed files with 17487 additions and 8548 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,
@@ -445,7 +445,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();
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());
}
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))
{
@@ -901,17 +908,16 @@ namespace Barotrauma.Items.Components
// A general purpose system could be better, but it would most likely require changes in the way we define the status effects in xml.
foreach (ISerializableEntity target in currentTargets)
{
if (!(target is Door door)) { continue; }
if (target is not Door door) { continue; }
if (!door.CanBeWelded || !door.Item.IsInteractable(user)) { continue; }
for (int i = 0; i < effect.propertyNames.Length; i++)
foreach (var propertyEffect in effect.PropertyEffects)
{
Identifier propertyName = effect.propertyNames[i];
if (propertyName != "stuck") { continue; }
if (door.SerializableProperties == null || !door.SerializableProperties.TryGetValue(propertyName, out SerializableProperty property)) { continue; }
if (propertyEffect.propertyName != "stuck") { continue; }
if (door.SerializableProperties == null || !door.SerializableProperties.TryGetValue(propertyEffect.propertyName, out SerializableProperty property)) { continue; }
object value = property.GetValue(target);
if (door.Stuck > 0)
{
bool isCutting = effect.propertyEffects[i].GetType() == typeof(float) && (float)effect.propertyEffects[i] < 0;
bool isCutting = propertyEffect.value is float and < 0;
var progressBar = user.UpdateHUDProgressBar(door, door.Item.WorldPosition, door.Stuck / 100, Color.DarkGray * 0.5f, Color.White,
textTag: isCutting ? "progressbar.cutting" : "progressbar.welding");
if (progressBar != null) { progressBar.Size = new Vector2(60.0f, 20.0f); }
@@ -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