Build 1.1.4.0
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
+36
-32
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user