Build 0.20.4.0
This commit is contained in:
@@ -843,10 +843,18 @@ namespace Barotrauma.Items.Components
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
if (item.body == null || !item.body.Enabled) { return; }
|
||||
|
||||
Character owner = picker ?? item.GetRootInventoryOwner() as Character;
|
||||
|
||||
if (owner != null)
|
||||
{
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, owner);
|
||||
}
|
||||
|
||||
if (picker == null || !picker.HasEquippedItem(item))
|
||||
{
|
||||
if (Pusher != null) { Pusher.Enabled = false; }
|
||||
if (attachTargetCell == null) { IsActive = false; }
|
||||
if (attachTargetCell == null && owner == null) { IsActive = false; }
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -855,23 +863,7 @@ namespace Barotrauma.Items.Components
|
||||
Drawable = true;
|
||||
}
|
||||
|
||||
Vector2 swing = Vector2.Zero;
|
||||
if (swingAmount != Vector2.Zero && !picker.IsUnconscious && picker.Stun <= 0.0f)
|
||||
{
|
||||
swingState += deltaTime;
|
||||
swingState %= 1.0f;
|
||||
if (SwingWhenHolding ||
|
||||
(SwingWhenAiming && picker.IsKeyDown(InputType.Aim)) ||
|
||||
(SwingWhenUsing && picker.IsKeyDown(InputType.Aim) && picker.IsKeyDown(InputType.Shoot)))
|
||||
{
|
||||
swing = swingAmount * new Vector2(
|
||||
PerlinNoise.GetPerlin(swingState * SwingSpeed * 0.1f, swingState * SwingSpeed * 0.1f) - 0.5f,
|
||||
PerlinNoise.GetPerlin(swingState * SwingSpeed * 0.1f + 0.5f, swingState * SwingSpeed * 0.1f + 0.5f) - 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, picker);
|
||||
|
||||
UpdateSwingPos(deltaTime, out Vector2 swingPos);
|
||||
if (item.body.Dir != picker.AnimController.Dir)
|
||||
{
|
||||
item.FlipX(relativeToSub: false);
|
||||
@@ -884,7 +876,7 @@ namespace Barotrauma.Items.Components
|
||||
scaledHandlePos[0] = handlePos[0] * item.Scale;
|
||||
scaledHandlePos[1] = handlePos[1] * item.Scale;
|
||||
bool aim = picker.IsKeyDown(InputType.Aim) && aimPos != Vector2.Zero && picker.CanAim;
|
||||
picker.AnimController.HoldItem(deltaTime, item, scaledHandlePos, holdPos + swing, aimPos + swing, aim, holdAngle);
|
||||
picker.AnimController.HoldItem(deltaTime, item, scaledHandlePos, holdPos + swingPos, aimPos + swingPos, aim, holdAngle);
|
||||
if (!aim)
|
||||
{
|
||||
var rope = GetRope();
|
||||
@@ -921,6 +913,24 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateSwingPos(float deltaTime, out Vector2 swingPos)
|
||||
{
|
||||
swingPos = Vector2.Zero;
|
||||
if (swingAmount != Vector2.Zero && !picker.IsUnconscious && picker.Stun <= 0.0f)
|
||||
{
|
||||
swingState += deltaTime;
|
||||
swingState %= 1.0f;
|
||||
if (SwingWhenHolding ||
|
||||
(SwingWhenAiming && picker.IsKeyDown(InputType.Aim)) ||
|
||||
(SwingWhenUsing && picker.IsKeyDown(InputType.Aim) && picker.IsKeyDown(InputType.Shoot)))
|
||||
{
|
||||
swingPos = swingAmount * new Vector2(
|
||||
PerlinNoise.GetPerlin(swingState * SwingSpeed * 0.1f, swingState * SwingSpeed * 0.1f) - 0.5f,
|
||||
PerlinNoise.GetPerlin(swingState * SwingSpeed * 0.1f + 0.5f, swingState * SwingSpeed * 0.1f + 0.5f) - 0.5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(Signal signal, Connection connection)
|
||||
{
|
||||
//do nothing
|
||||
|
||||
@@ -214,8 +214,9 @@ namespace Barotrauma.Items.Components
|
||||
bool aim = item.RequireAimToUse && picker.AllowInput && picker.IsKeyDown(InputType.Aim) && reloadTimer <= 0 && picker.CanAim;
|
||||
if (aim)
|
||||
{
|
||||
UpdateSwingPos(deltaTime, out Vector2 swingPos);
|
||||
hitPos = MathUtils.WrapAnglePi(Math.Min(hitPos + deltaTime * 3f, MathHelper.PiOver4));
|
||||
ac.HoldItem(deltaTime, item, handlePos, aimPos, Vector2.Zero, aim: false, hitPos, holdAngle + hitPos, aimMelee: true);
|
||||
ac.HoldItem(deltaTime, item, handlePos, aimPos + swingPos, Vector2.Zero, aim: false, hitPos, holdAngle + hitPos, aimMelee: true);
|
||||
if (ac.InWater)
|
||||
{
|
||||
ac.LockFlippingUntil = (float)Timing.TotalTime + Reload;
|
||||
@@ -392,34 +393,35 @@ namespace Barotrauma.Items.Components
|
||||
float damageMultiplier = 1 + User.GetStatValue(StatTypes.MeleeAttackMultiplier);
|
||||
damageMultiplier *= 1.0f + item.GetQualityModifier(Quality.StatType.StrikingPowerMultiplier);
|
||||
|
||||
Character user = User;
|
||||
Limb targetLimb = target.UserData as Limb;
|
||||
Character targetCharacter = targetLimb?.character ?? target.UserData as Character;
|
||||
if (Attack != null)
|
||||
{
|
||||
Attack.SetUser(User);
|
||||
Attack.SetUser(user);
|
||||
Attack.DamageMultiplier = damageMultiplier;
|
||||
|
||||
if (targetLimb != null)
|
||||
{
|
||||
if (targetLimb.character.Removed) { return; }
|
||||
targetLimb.character.LastDamageSource = item;
|
||||
Attack.DoDamageToLimb(User, targetLimb, item.WorldPosition, 1.0f);
|
||||
Attack.DoDamageToLimb(user, targetLimb, item.WorldPosition, 1.0f);
|
||||
}
|
||||
else if (targetCharacter != null)
|
||||
{
|
||||
if (targetCharacter.Removed) { return; }
|
||||
targetCharacter.LastDamageSource = item;
|
||||
Attack.DoDamage(User, targetCharacter, item.WorldPosition, 1.0f);
|
||||
Attack.DoDamage(user, targetCharacter, item.WorldPosition, 1.0f);
|
||||
}
|
||||
else if ((target.UserData as Structure ?? targetFixture.UserData as Structure) is Structure targetStructure)
|
||||
{
|
||||
if (targetStructure.Removed) { return; }
|
||||
Attack.DoDamage(User, targetStructure, item.WorldPosition, 1.0f);
|
||||
Attack.DoDamage(user, targetStructure, item.WorldPosition, 1.0f);
|
||||
}
|
||||
else if (target.UserData is Item targetItem && targetItem.Prefab.DamagedByMeleeWeapons && targetItem.Condition > 0)
|
||||
{
|
||||
if (targetItem.Removed) { return; }
|
||||
var attackResult = 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 && targetItem.Prefab.ShowHealthBar)
|
||||
{
|
||||
@@ -435,7 +437,7 @@ namespace Barotrauma.Items.Components
|
||||
else if (target.UserData is Holdable holdable && holdable.CanPush)
|
||||
{
|
||||
if (holdable.Item.Removed) { return; }
|
||||
Attack.DoDamage(User, holdable.Item, item.WorldPosition, 1.0f);
|
||||
Attack.DoDamage(user, holdable.Item, item.WorldPosition, 1.0f);
|
||||
RestoreCollision();
|
||||
hitting = false;
|
||||
User = null;
|
||||
@@ -448,29 +450,32 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||
|
||||
bool success = Rand.Range(0.0f, 0.5f) < DegreeOfSuccess(User);
|
||||
|
||||
#if SERVER
|
||||
if (GameMain.Server != null && targetCharacter != null) //TODO: Log structure hits
|
||||
ActionType conditionalActionType = ActionType.OnSuccess;
|
||||
if (user != null && Rand.Range(0.0f, 0.5f) > DegreeOfSuccess(user))
|
||||
{
|
||||
GameMain.Server.CreateEntityEvent(item, new Item.ApplyStatusEffectEventData(
|
||||
success ? ActionType.OnUse : ActionType.OnFailure,
|
||||
targetItemComponent: null,
|
||||
targetCharacter, targetLimb));
|
||||
|
||||
string logStr = picker?.LogName + " used " + item.Name;
|
||||
if (item.ContainedItems != null && item.ContainedItems.Any())
|
||||
{
|
||||
logStr += " (" + string.Join(", ", item.ContainedItems.Select(i => i?.Name)) + ")";
|
||||
}
|
||||
logStr += " on " + targetCharacter.LogName + ".";
|
||||
Networking.GameServer.Log(logStr, Networking.ServerLog.MessageType.Attack);
|
||||
conditionalActionType = ActionType.OnFailure;
|
||||
}
|
||||
if (GameMain.NetworkMember is { IsServer: true } server && targetCharacter != null)
|
||||
{
|
||||
server.CreateEntityEvent(item, new Item.ApplyStatusEffectEventData(conditionalActionType, targetItemComponent: null, targetCharacter, targetLimb));
|
||||
server.CreateEntityEvent(item, new Item.ApplyStatusEffectEventData(ActionType.OnUse, targetItemComponent: null, targetCharacter, targetLimb));
|
||||
#if SERVER
|
||||
if (GameMain.Server != null) //TODO: Log structure hits
|
||||
{
|
||||
string logStr = picker?.LogName + " used " + item.Name;
|
||||
if (item.ContainedItems != null && item.ContainedItems.Any())
|
||||
{
|
||||
logStr += " (" + string.Join(", ", item.ContainedItems.Select(i => i?.Name)) + ")";
|
||||
}
|
||||
logStr += " on " + targetCharacter.LogName + ".";
|
||||
Networking.GameServer.Log(logStr, Networking.ServerLog.MessageType.Attack);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
if (targetCharacter != null) //TODO: Allow OnUse to happen on structures too maybe??
|
||||
{
|
||||
ApplyStatusEffects(success ? ActionType.OnUse : ActionType.OnFailure, 1.0f, targetCharacter, targetLimb, user: User, afflictionMultiplier: damageMultiplier);
|
||||
ApplyStatusEffects(conditionalActionType, 1.0f, targetCharacter, targetLimb, user: user, afflictionMultiplier: damageMultiplier);
|
||||
ApplyStatusEffects(ActionType.OnUse, 1.0f, targetCharacter, targetLimb, user: user, afflictionMultiplier: damageMultiplier);
|
||||
}
|
||||
|
||||
if (DeleteOnUse)
|
||||
|
||||
@@ -23,6 +23,8 @@ namespace Barotrauma.Items.Components
|
||||
[Serialize(0.0f, IsPropertySaveable.No, description: "The force to apply to the user's body."), Editable(MinValueFloat = -1000.0f, MaxValueFloat = 1000.0f)]
|
||||
public float Force { get; set; }
|
||||
|
||||
[Serialize(true, IsPropertySaveable.No, description: "If the item is held in RightHand or LeftHand, apply extra force there")]
|
||||
public bool ApplyToHands { get; set; }
|
||||
#if CLIENT
|
||||
private string particles;
|
||||
[Serialize("", IsPropertySaveable.No, description: "The name of the particle prefab the item emits when used.")]
|
||||
@@ -70,13 +72,16 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
character.AnimController.Collider.ApplyForce(propulsion);
|
||||
|
||||
if (character.Inventory.IsInLimbSlot(item, InvSlotType.RightHand))
|
||||
{
|
||||
character.AnimController.GetLimb(LimbType.RightHand)?.body.ApplyForce(propulsion);
|
||||
}
|
||||
if (character.Inventory.IsInLimbSlot(item, InvSlotType.LeftHand))
|
||||
{
|
||||
character.AnimController.GetLimb(LimbType.LeftHand)?.body.ApplyForce(propulsion);
|
||||
if (ApplyToHands)
|
||||
{
|
||||
if (character.Inventory.IsInLimbSlot(item, InvSlotType.RightHand))
|
||||
{
|
||||
character.AnimController.GetLimb(LimbType.RightHand)?.body.ApplyForce(propulsion);
|
||||
}
|
||||
if (character.Inventory.IsInLimbSlot(item, InvSlotType.LeftHand))
|
||||
{
|
||||
character.AnimController.GetLimb(LimbType.LeftHand)?.body.ApplyForce(propulsion);
|
||||
}
|
||||
}
|
||||
|
||||
#if CLIENT
|
||||
|
||||
@@ -32,6 +32,20 @@ namespace Barotrauma.Items.Components
|
||||
set { reload = Math.Max(value, 0.0f); }
|
||||
}
|
||||
|
||||
[Serialize(0f, IsPropertySaveable.No, description: "Weapons skill requirement to reload at normal speed.")]
|
||||
public float ReloadSkillRequirement
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(1.0f, IsPropertySaveable.No, description: "Reload time at 0 skill level. Reload time scales with skill level up to the Weapons skill requirement.")]
|
||||
public float ReloadNoSkill
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(false, IsPropertySaveable.No, description: "Tells the AI to hold the trigger down when it uses this weapon")]
|
||||
public bool HoldTrigger
|
||||
{
|
||||
@@ -39,7 +53,7 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(1, IsPropertySaveable.No, description: "How projectiles the weapon launches when fired once.")]
|
||||
[Serialize(1, IsPropertySaveable.No, description: "How many projectiles the weapon launches when fired once.")]
|
||||
public int ProjectileCount
|
||||
{
|
||||
get;
|
||||
@@ -60,6 +74,23 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.No, description: "The impulse applied to the physics body of the projectile (the higher the impulse, the faster the projectiles are launched). Sum of weapon + projectile.")]
|
||||
public float LaunchImpulse
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.Yes, description: "Percentage of damage mitigation ignored when hitting armored body parts (deflecting limbs). Sum of weapon + projectile."), Editable(MinValueFloat = 0.0f, MaxValueFloat = 1f)]
|
||||
public float Penetration { get; private set; }
|
||||
|
||||
[Serialize(1f, IsPropertySaveable.Yes, description: "Weapon's damage modifier")]
|
||||
public float WeaponDamageModifier
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(0f, IsPropertySaveable.Yes, description: "The time required for a charge-type turret to charge up before able to fire.")]
|
||||
public float MaxChargeTime
|
||||
{
|
||||
@@ -99,6 +130,12 @@ 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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -167,7 +204,15 @@ namespace Barotrauma.Items.Components
|
||||
if (currentChargeTime < MaxChargeTime) { return false; }
|
||||
|
||||
IsActive = true;
|
||||
ReloadTimer = reload / (1 + character?.GetStatValue(StatTypes.RangedAttackSpeed) ?? 0f);
|
||||
float baseReloadTime = reload;
|
||||
float weaponSkill = character.GetSkillLevel("weapons");
|
||||
if (ReloadSkillRequirement > 0 && ReloadNoSkill > reload && weaponSkill < ReloadSkillRequirement)
|
||||
{
|
||||
//Examples, assuming 40 weapon skill required: 1 - 40/40 = 0 ... 1 - 0/40 = 1 ... 1 - 20 / 40 = 0.5
|
||||
float reloadFailure = MathHelper.Clamp(1 - (weaponSkill / ReloadSkillRequirement), 0, 1);
|
||||
baseReloadTime = MathHelper.Lerp(reload, ReloadNoSkill, reloadFailure);
|
||||
}
|
||||
ReloadTimer = baseReloadTime / (1 + character?.GetStatValue(StatTypes.RangedAttackSpeed) ?? 0f);
|
||||
currentChargeTime = 0f;
|
||||
|
||||
if (character != null)
|
||||
@@ -218,9 +263,9 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
lastProjectile?.Item.GetComponent<Rope>()?.Snap();
|
||||
}
|
||||
float damageMultiplier = 1f + item.GetQualityModifier(Quality.StatType.FirepowerMultiplier);
|
||||
float damageMultiplier = (1f + item.GetQualityModifier(Quality.StatType.FirepowerMultiplier)) * WeaponDamageModifier;
|
||||
projectile.Launcher = item;
|
||||
projectile.Shoot(character, character.AnimController.AimSourceSimPos, barrelPos, rotation + spread, ignoredBodies: ignoredBodies.ToList(), createNetworkEvent: false, damageMultiplier);
|
||||
projectile.Shoot(character, character.AnimController.AimSourceSimPos, barrelPos, rotation + spread, ignoredBodies: ignoredBodies.ToList(), createNetworkEvent: false, damageMultiplier, LaunchImpulse);
|
||||
projectile.Item.GetComponent<Rope>()?.Attach(Item, projectile.Item);
|
||||
if (i == 0)
|
||||
{
|
||||
|
||||
@@ -1,17 +1,26 @@
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
class Throwable : Holdable
|
||||
{
|
||||
private float throwPos;
|
||||
private bool throwing, throwDone;
|
||||
enum ThrowState
|
||||
{
|
||||
None,
|
||||
Initiated,
|
||||
Throwing
|
||||
}
|
||||
|
||||
private const float ThrowAngleStart = -MathHelper.PiOver2, ThrowAngleEnd = MathHelper.PiOver2;
|
||||
private float throwAngle = ThrowAngleStart;
|
||||
|
||||
private bool midAir;
|
||||
|
||||
private ThrowState throwState;
|
||||
|
||||
|
||||
//continuous collision detection is used while the item is moving faster than this
|
||||
const float ContinuousCollisionThreshold = 5.0f;
|
||||
|
||||
@@ -27,7 +36,6 @@ namespace Barotrauma.Items.Components
|
||||
public Throwable(Item item, ContentXElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
//throwForce = ToolBox.GetAttributeFloat(element, "throwforce", 1.0f);
|
||||
if (aimPos == Vector2.Zero)
|
||||
{
|
||||
aimPos = new Vector2(0.6f, 0.1f);
|
||||
@@ -36,22 +44,21 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public override bool Use(float deltaTime, Character character = null)
|
||||
{
|
||||
return characterUsable || character == null; //We do the actual throwing in Aim because Use might be used by chems
|
||||
//actual throwing logic is handled in Update
|
||||
return characterUsable || character == null;
|
||||
}
|
||||
|
||||
public override bool SecondaryUse(float deltaTime, Character character = null)
|
||||
{
|
||||
if (!throwDone) return false; //This should only be triggered in update
|
||||
throwDone = false;
|
||||
return true;
|
||||
//actual throwing logic is handled in Update - SecondaryUse only triggers when the item is thrown
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Drop(Character dropper)
|
||||
{
|
||||
base.Drop(dropper);
|
||||
|
||||
throwing = false;
|
||||
throwPos = 0.0f;
|
||||
throwState = ThrowState.None;
|
||||
throwAngle = ThrowAngleStart;
|
||||
}
|
||||
|
||||
public override void UpdateBroken(float deltaTime, Camera cam)
|
||||
@@ -100,13 +107,22 @@ namespace Barotrauma.Items.Components
|
||||
return;
|
||||
}
|
||||
|
||||
if (picker.IsKeyDown(InputType.Aim) && picker.IsKeyHit(InputType.Shoot)) { throwing = true; }
|
||||
if (!picker.IsKeyDown(InputType.Aim) && !throwing) { throwPos = 0.0f; }
|
||||
bool aim = picker.IsKeyDown(InputType.Aim) && picker.CanAim;
|
||||
if (throwState != ThrowState.Throwing)
|
||||
{
|
||||
if (picker.IsKeyDown(InputType.Aim))
|
||||
{
|
||||
if (picker.IsKeyDown(InputType.Shoot)) { throwState = ThrowState.Initiated; }
|
||||
}
|
||||
else if (throwState != ThrowState.Initiated)
|
||||
{
|
||||
throwAngle = ThrowAngleStart;
|
||||
}
|
||||
}
|
||||
|
||||
bool aim = picker.IsKeyDown(InputType.Aim) && picker.CanAim;
|
||||
if (picker.IsDead || !picker.AllowInput)
|
||||
{
|
||||
throwing = false;
|
||||
throwState = ThrowState.None;
|
||||
aim = false;
|
||||
}
|
||||
|
||||
@@ -124,25 +140,29 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
item.Submarine = picker.Submarine;
|
||||
|
||||
if (!throwing)
|
||||
if (throwState != ThrowState.Throwing)
|
||||
{
|
||||
if (aim)
|
||||
if (aim || throwState == ThrowState.Initiated)
|
||||
{
|
||||
throwPos = MathUtils.WrapAnglePi(System.Math.Min(throwPos + deltaTime * 5.0f, MathHelper.PiOver2));
|
||||
ac.HoldItem(deltaTime, item, handlePos, aimPos, Vector2.Zero, aim: false, throwPos);
|
||||
throwAngle = System.Math.Min(throwAngle + deltaTime * 8.0f, ThrowAngleEnd);
|
||||
ac.HoldItem(deltaTime, item, handlePos, aimPos, Vector2.Zero, aim: false, throwAngle);
|
||||
if (throwAngle >= ThrowAngleEnd && throwState == ThrowState.Initiated)
|
||||
{
|
||||
throwState = ThrowState.Throwing;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throwPos = 0;
|
||||
throwAngle = ThrowAngleStart;
|
||||
ac.HoldItem(deltaTime, item, handlePos, holdPos, Vector2.Zero, aim: false, holdAngle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throwPos = MathUtils.WrapAnglePi(throwPos - deltaTime * 15.0f);
|
||||
ac.HoldItem(deltaTime, item, handlePos, aimPos, Vector2.Zero, aim: false, throwPos);
|
||||
throwAngle = MathUtils.WrapAnglePi(throwAngle - deltaTime * 15.0f);
|
||||
ac.HoldItem(deltaTime, item, handlePos, aimPos, Vector2.Zero, aim: false, throwAngle);
|
||||
|
||||
if (throwPos < 0)
|
||||
if (throwAngle < 0)
|
||||
{
|
||||
Vector2 throwVector = Vector2.Normalize(picker.CursorWorldPosition - picker.WorldPosition);
|
||||
//throw upwards if cursor is at the position of the character
|
||||
@@ -180,8 +200,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
Limb rightHand = ac.GetLimb(LimbType.RightHand);
|
||||
item.body.AngularVelocity = rightHand.body.AngularVelocity;
|
||||
throwPos = 0;
|
||||
throwDone = true;
|
||||
throwAngle = ThrowAngleStart;
|
||||
IsActive = true;
|
||||
|
||||
if (GameMain.NetworkMember is { IsServer: true })
|
||||
@@ -193,7 +212,7 @@ namespace Barotrauma.Items.Components
|
||||
//Stun grenades, flares, etc. all have their throw-related things handled in "onSecondaryUse"
|
||||
ApplyStatusEffects(ActionType.OnSecondaryUse, deltaTime, CurrentThrower, user: CurrentThrower);
|
||||
}
|
||||
throwing = false;
|
||||
throwState = ThrowState.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,8 +65,16 @@ namespace Barotrauma.Items.Components
|
||||
public int Capacity
|
||||
{
|
||||
get { return capacity; }
|
||||
set { capacity = Math.Max(value, 0); }
|
||||
private set
|
||||
{
|
||||
capacity = Math.Max(value, 0);
|
||||
MainContainerCapacity = value;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The capacity of the main container without taking the sub containers into account. Only differs when there's a sub container defined for the component.
|
||||
/// </summary>
|
||||
public int MainContainerCapacity { get; private set; }
|
||||
|
||||
//how many items can be contained
|
||||
private int maxStackSize;
|
||||
@@ -229,6 +237,9 @@ namespace Barotrauma.Items.Components
|
||||
public ImmutableHashSet<Identifier> ContainableItemIdentifiers => containableItemIdentifiers;
|
||||
|
||||
public List<RelatedItem> ContainableItems { get; }
|
||||
public List<RelatedItem> AllSubContainableItems { get; }
|
||||
|
||||
public readonly bool HasSubContainers;
|
||||
|
||||
public ItemContainer(Item item, ContentXElement element)
|
||||
: base(item, element)
|
||||
@@ -251,6 +262,7 @@ namespace Barotrauma.Items.Components
|
||||
break;
|
||||
case "subcontainer":
|
||||
totalCapacity += subElement.GetAttributeInt("capacity", 1);
|
||||
HasSubContainers = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -270,7 +282,7 @@ namespace Barotrauma.Items.Components
|
||||
int subCapacity = subElement.GetAttributeInt("capacity", 1);
|
||||
int subMaxStackSize = subElement.GetAttributeInt("maxstacksize", maxStackSize);
|
||||
|
||||
List<RelatedItem> subContainableItems = null;
|
||||
var subContainableItems = new List<RelatedItem>();
|
||||
foreach (var subSubElement in subElement.Elements())
|
||||
{
|
||||
if (subSubElement.Name.ToString().ToLowerInvariant() != "containable") { continue; }
|
||||
@@ -281,8 +293,9 @@ namespace Barotrauma.Items.Components
|
||||
DebugConsole.ThrowError("Error in item config \"" + item.ConfigFilePath + "\" - containable with no identifiers.");
|
||||
continue;
|
||||
}
|
||||
subContainableItems ??= new List<RelatedItem>();
|
||||
subContainableItems.Add(containable);
|
||||
AllSubContainableItems ??= new List<RelatedItem>();
|
||||
AllSubContainableItems.Add(containable);
|
||||
}
|
||||
|
||||
for (int i = subContainerIndex; i < subContainerIndex + subCapacity; i++)
|
||||
@@ -357,6 +370,14 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
//no need to Update() if this item has no statuseffects and no physics body
|
||||
IsActive = activeContainedItems.Count > 0 || Inventory.AllItems.Any(it => it.body != null);
|
||||
|
||||
if (IsActive && item.GetRootInventoryOwner() is Character owner &&
|
||||
owner.HasEquippedItem(item, predicate: slot => slot.HasFlag(InvSlotType.LeftHand) || slot.HasFlag(InvSlotType.RightHand)))
|
||||
{
|
||||
// Set the contained items active if there's an item inserted inside the container. Enables e.g. the rifle flashlight when it's attached to the rifle (put inside of it).
|
||||
SetContainedActive(true);
|
||||
}
|
||||
|
||||
OnContainedItemsChanged.Invoke(this);
|
||||
}
|
||||
|
||||
@@ -409,6 +430,20 @@ namespace Barotrauma.Items.Components
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void FlipX(bool relativeToSub)
|
||||
{
|
||||
base.FlipX(relativeToSub);
|
||||
if (HideItems) { return; }
|
||||
if (item.body == null) { return; }
|
||||
foreach (Item containedItem in Inventory.AllItems)
|
||||
{
|
||||
if (containedItem.body != null && containedItem.body.Enabled && containedItem.body.Dir != item.body.Dir)
|
||||
{
|
||||
containedItem.FlipX(relativeToSub);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(SpawnWithId) && !alwaysContainedItemsSpawned)
|
||||
@@ -477,7 +512,7 @@ namespace Barotrauma.Items.Components
|
||||
effect.HasTargetType(StatusEffect.TargetType.NearbyCharacters))
|
||||
{
|
||||
targets.Clear();
|
||||
targets.AddRange(effect.GetNearbyTargets(item.WorldPosition, targets));
|
||||
effect.AddNearbyTargets(item.WorldPosition, targets);
|
||||
effect.Apply(ActionType.OnActive, deltaTime, item, targets);
|
||||
}
|
||||
}
|
||||
@@ -582,11 +617,53 @@ namespace Barotrauma.Items.Components
|
||||
public override void Drop(Character dropper)
|
||||
{
|
||||
IsActive = true;
|
||||
SetContainedActive(false);
|
||||
}
|
||||
|
||||
public override void Equip(Character character)
|
||||
{
|
||||
IsActive = true;
|
||||
if (character != null && character.HasEquippedItem(item, predicate: slot => slot.HasFlag(InvSlotType.LeftHand) || slot.HasFlag(InvSlotType.RightHand)))
|
||||
{
|
||||
SetContainedActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetContainedActive(bool active)
|
||||
{
|
||||
foreach (Item containedItem in Inventory.AllItems)
|
||||
{
|
||||
RelatedItem containableItem = FindContainableItem(containedItem);
|
||||
if (containableItem != null && containableItem.SetActive)
|
||||
{
|
||||
foreach (var ic in containedItem.Components)
|
||||
{
|
||||
ic.IsActive = active;
|
||||
}
|
||||
if (containedItem.body != null)
|
||||
{
|
||||
containedItem.body.Enabled = active;
|
||||
if (active)
|
||||
{
|
||||
containedItem.body.PhysEnabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (active)
|
||||
{
|
||||
FlipX(false);
|
||||
}
|
||||
}
|
||||
|
||||
private RelatedItem FindContainableItem(Item item)
|
||||
{
|
||||
var relatedItem = ContainableItems?.FirstOrDefault(ci => ci.MatchesItem(item));
|
||||
if (relatedItem == null && AllSubContainableItems != null)
|
||||
{
|
||||
relatedItem = AllSubContainableItems.FirstOrDefault(ci => ci.MatchesItem(item));
|
||||
}
|
||||
return relatedItem;
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(Signal signal, Connection connection)
|
||||
@@ -604,6 +681,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
#warning There's some code duplication here and in DrawContainedItems() method, but it's not straightforward to get rid of it, because of slightly different logic and the usage of draw positions vs. positions etc. Should probably be splitted into smaller methods.
|
||||
public void SetContainedItemPositions()
|
||||
{
|
||||
Vector2 transformedItemPos = ItemPos * item.Scale;
|
||||
@@ -657,29 +735,70 @@ namespace Barotrauma.Items.Components
|
||||
transformedItemIntervalHorizontal = Vector2.Transform(transformedItemIntervalHorizontal, transform);
|
||||
transformedItemPos += item.Position;
|
||||
}
|
||||
}
|
||||
|
||||
float currentRotation = itemRotation;
|
||||
if (item.body != null)
|
||||
{
|
||||
currentRotation *= item.body.Dir;
|
||||
currentRotation += item.body.Rotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentRotation += -item.RotationRad;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
Vector2 currentItemPos = transformedItemPos;
|
||||
foreach (Item contained in Inventory.AllItems)
|
||||
{
|
||||
Vector2 itemPos = currentItemPos;
|
||||
var relatedItem = FindContainableItem(contained);
|
||||
if (relatedItem != null)
|
||||
{
|
||||
if (relatedItem.Hide.HasValue && relatedItem.Hide.Value) { continue; }
|
||||
if (relatedItem.ItemPos.HasValue)
|
||||
{
|
||||
Vector2 pos = relatedItem.ItemPos.Value;
|
||||
if (item.body != null)
|
||||
{
|
||||
Matrix transform = Matrix.CreateRotationZ(item.body.Rotation);
|
||||
pos.X *= item.body.Dir;
|
||||
itemPos = Vector2.Transform(pos, transform) + item.body.Position;
|
||||
}
|
||||
else
|
||||
{
|
||||
itemPos = pos;
|
||||
// This code is aped based on above. Not tested.
|
||||
if (item.FlippedX)
|
||||
{
|
||||
itemPos.X = -itemPos.X;
|
||||
itemPos.X += item.Rect.Width;
|
||||
}
|
||||
if (item.FlippedY)
|
||||
{
|
||||
itemPos.Y = -itemPos.Y;
|
||||
itemPos.Y -= item.Rect.Height;
|
||||
}
|
||||
itemPos += new Vector2(item.Rect.X, item.Rect.Y);
|
||||
if (Math.Abs(item.RotationRad) > 0.01f)
|
||||
{
|
||||
Matrix transform = Matrix.CreateRotationZ(item.RotationRad);
|
||||
itemPos = Vector2.Transform(itemPos - item.Position, transform) + item.Position;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (contained.body != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Vector2 simPos = ConvertUnits.ToSimUnits(currentItemPos);
|
||||
contained.body.FarseerBody.SetTransformIgnoreContacts(ref simPos, currentRotation);
|
||||
Vector2 simPos = ConvertUnits.ToSimUnits(itemPos);
|
||||
float rotation = itemRotation;
|
||||
if (relatedItem != null && relatedItem.Rotation != 0)
|
||||
{
|
||||
rotation = MathHelper.ToRadians(relatedItem.Rotation);
|
||||
}
|
||||
if (item.body != null)
|
||||
{
|
||||
rotation *= item.body.Dir;
|
||||
rotation += item.body.Rotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
rotation += -item.RotationRad;
|
||||
}
|
||||
contained.body.FarseerBody.SetTransformIgnoreContacts(ref simPos, rotation);
|
||||
contained.body.SetPrevTransform(contained.body.SimPosition, contained.body.Rotation);
|
||||
contained.body.UpdateDrawPosition();
|
||||
}
|
||||
@@ -695,8 +814,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
contained.Rect =
|
||||
new Rectangle(
|
||||
(int)(currentItemPos.X - contained.Rect.Width / 2.0f),
|
||||
(int)(currentItemPos.Y + contained.Rect.Height / 2.0f),
|
||||
(int)(itemPos.X - contained.Rect.Width / 2.0f),
|
||||
(int)(itemPos.Y + contained.Rect.Height / 2.0f),
|
||||
contained.Rect.Width, contained.Rect.Height);
|
||||
|
||||
contained.Submarine = item.Submarine;
|
||||
|
||||
@@ -459,6 +459,12 @@ namespace Barotrauma.Items.Components
|
||||
progressTimer = 0.0f;
|
||||
progressState = 0.0f;
|
||||
}
|
||||
#if CLIENT
|
||||
else
|
||||
{
|
||||
HintManager.OnStartDeconstructing(user, this);
|
||||
}
|
||||
#endif
|
||||
|
||||
inputContainer.Inventory.Locked = IsActive;
|
||||
}
|
||||
|
||||
@@ -419,7 +419,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
var fabricationIngredients = new AbilityFabricationItemIngredients(foundAvailableItems);
|
||||
user.CheckTalents(AbilityEffectType.OnItemFabricatedIngredients, fabricationIngredients);
|
||||
user?.CheckTalents(AbilityEffectType.OnItemFabricatedIngredients, fabricationIngredients);
|
||||
|
||||
foreach (Item availableItem in fabricationIngredients.Items)
|
||||
{
|
||||
@@ -559,7 +559,7 @@ namespace Barotrauma.Items.Components
|
||||
if (fabricatedItem.TargetItem.ConfigElement.GetChildElement("Quality") == null) { return 0; }
|
||||
int quality = 0;
|
||||
float floatQuality = 0.0f;
|
||||
floatQuality += user.GetStatValue(StatTypes.IncreaseFabricationQuality);
|
||||
floatQuality += user.GetStatValue(StatTypes.IncreaseFabricationQuality, includeSaved: false);
|
||||
foreach (var tag in fabricatedItem.TargetItem.Tags)
|
||||
{
|
||||
floatQuality += user.Info.GetSavedStatValue(StatTypes.IncreaseFabricationQuality, tag);
|
||||
@@ -740,10 +740,27 @@ namespace Barotrauma.Items.Components
|
||||
//order by condition (prefer using worst-condition items)
|
||||
int index = 0;
|
||||
while (index < availableIngredients[itemIdentifier].Count &&
|
||||
availableIngredients[itemIdentifier][index].Condition < item.Condition)
|
||||
compare(item, availableIngredients[itemIdentifier][index], inputContainer.Inventory) < 0)
|
||||
{
|
||||
index++;
|
||||
}
|
||||
|
||||
static int compare(Item item1, Item item2, Inventory inputInventory)
|
||||
{
|
||||
bool item1InInputInventory = item1.ParentInventory == inputInventory;
|
||||
bool item2InInputInventory = item2.ParentInventory == inputInventory;
|
||||
//prefer items in the input inventory
|
||||
if (item1InInputInventory != item2InInputInventory)
|
||||
{
|
||||
return item1InInputInventory ? 1 : -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//prefer items in worse condition
|
||||
return Math.Sign(item2.Condition - item1.Condition);
|
||||
}
|
||||
}
|
||||
|
||||
availableIngredients[itemIdentifier].Insert(index, item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ namespace Barotrauma.Items.Components
|
||||
public float? ReceivedOxygenAmount,
|
||||
ReceivedWaterAmount;
|
||||
|
||||
public double LastOxygenDataTime, LastWaterDataTime;
|
||||
|
||||
public readonly HashSet<IdCard> Cards = new HashSet<IdCard>();
|
||||
|
||||
public bool Distort;
|
||||
@@ -83,7 +85,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
//periodically reset all hull data
|
||||
//reset data if we haven't received anything in a while
|
||||
//(so that outdated hull info won't be shown if detectors stop sending signals)
|
||||
if (DateTime.Now > resetDataTime)
|
||||
{
|
||||
@@ -91,8 +93,8 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (!hullData.Distort)
|
||||
{
|
||||
hullData.ReceivedOxygenAmount = null;
|
||||
hullData.ReceivedWaterAmount = null;
|
||||
if (Timing.TotalTime > hullData.LastOxygenDataTime + 1.0) { hullData.ReceivedOxygenAmount = null; }
|
||||
if (Timing.TotalTime > hullData.LastWaterDataTime + 1.0) { hullData.ReceivedWaterAmount = null; }
|
||||
}
|
||||
}
|
||||
resetDataTime = DateTime.Now + new TimeSpan(0, 0, 1);
|
||||
@@ -159,6 +161,7 @@ namespace Barotrauma.Items.Components
|
||||
//cheating a bit because water detectors don't actually send the water level
|
||||
bool fromWaterDetector = source.GetComponent<WaterDetector>() != null;
|
||||
hullData.ReceivedWaterAmount = null;
|
||||
hullData.LastWaterDataTime = Timing.TotalTime;
|
||||
if (fromWaterDetector)
|
||||
{
|
||||
hullData.ReceivedWaterAmount = WaterDetector.GetWaterPercentage(sourceHull);
|
||||
@@ -184,9 +187,10 @@ namespace Barotrauma.Items.Components
|
||||
oxy = Rand.Range(0.0f, 100.0f);
|
||||
}
|
||||
hullData.ReceivedOxygenAmount = oxy;
|
||||
hullData.LastOxygenDataTime = Timing.TotalTime;
|
||||
foreach (var linked in sourceHull.linkedTo)
|
||||
{
|
||||
if (!(linked is Hull linkedHull)) { continue; }
|
||||
if (linked is not Hull linkedHull) { continue; }
|
||||
if (!hullDatas.TryGetValue(linkedHull, out HullData linkedHullData))
|
||||
{
|
||||
linkedHullData = new HullData();
|
||||
|
||||
@@ -197,11 +197,6 @@ namespace Barotrauma.Items.Components
|
||||
if (currentPingIndex != -1)
|
||||
{
|
||||
var activePing = activePings[currentPingIndex];
|
||||
if (item.AiTarget != null)
|
||||
{
|
||||
float range = MathUtils.InverseLerp(item.AiTarget.MinSoundRange, item.AiTarget.MaxSoundRange, Range * activePing.State / zoom);
|
||||
item.AiTarget.SoundRange = MathHelper.Lerp(item.AiTarget.MinSoundRange, item.AiTarget.MaxSoundRange, range);
|
||||
}
|
||||
if (activePing.State > 1.0f)
|
||||
{
|
||||
aiPingCheckPending = true;
|
||||
@@ -235,6 +230,11 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
for (var pingIndex = 0; pingIndex < activePingsCount;)
|
||||
{
|
||||
if (item.AiTarget != null)
|
||||
{
|
||||
float range = MathUtils.InverseLerp(item.AiTarget.MinSoundRange, item.AiTarget.MaxSoundRange, Range * activePings[pingIndex].State / zoom);
|
||||
item.AiTarget.SoundRange = Math.Max(item.AiTarget.SoundRange, MathHelper.Lerp(item.AiTarget.MinSoundRange, item.AiTarget.MaxSoundRange, range));
|
||||
}
|
||||
if (activePings[pingIndex].State > 1.0f)
|
||||
{
|
||||
var lastIndex = --activePingsCount;
|
||||
|
||||
@@ -144,6 +144,11 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public float TargetVelocityLengthSquared
|
||||
{
|
||||
get => TargetVelocity.LengthSquared();
|
||||
}
|
||||
|
||||
public Vector2 SteeringInput
|
||||
{
|
||||
get { return steeringInput; }
|
||||
|
||||
@@ -392,6 +392,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
User = character;
|
||||
ApplyStatusEffects(ActionType.OnUse, 1.0f, User, user: User);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -916,23 +917,22 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (character != null) { character.LastDamageSource = item; }
|
||||
|
||||
ActionType actionType = ActionType.OnUse;
|
||||
if (_user != null && Rand.Range(0.0f, 0.5f) > DegreeOfSuccess(_user))
|
||||
ActionType conditionalActionType = ActionType.OnSuccess;
|
||||
if (User != null && Rand.Range(0.0f, 0.5f) > DegreeOfSuccess(User))
|
||||
{
|
||||
actionType = ActionType.OnFailure;
|
||||
conditionalActionType = ActionType.OnFailure;
|
||||
}
|
||||
|
||||
#if CLIENT
|
||||
PlaySound(actionType, user: _user);
|
||||
PlaySound(ActionType.OnImpact, user: _user);
|
||||
PlaySound(conditionalActionType, user: User);
|
||||
PlaySound(ActionType.OnImpact, user: User);
|
||||
#endif
|
||||
|
||||
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
|
||||
{
|
||||
if (target.Body.UserData is Limb targetLimb)
|
||||
{
|
||||
ApplyStatusEffects(actionType, 1.0f, character, targetLimb, user: _user);
|
||||
ApplyStatusEffects(ActionType.OnImpact, 1.0f, character, targetLimb, user: _user);
|
||||
ApplyStatusEffects(conditionalActionType, 1.0f, character, targetLimb, user: User);
|
||||
ApplyStatusEffects(ActionType.OnImpact, 1.0f, character, targetLimb, user: User);
|
||||
var attack = targetLimb.attack;
|
||||
if (attack != null)
|
||||
{
|
||||
@@ -941,8 +941,6 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (effect.type == ActionType.OnImpact)
|
||||
{
|
||||
//effect.Apply(effect.type, 1.0f, targetLimb.character, targetLimb.character, targetLimb.WorldPosition);
|
||||
|
||||
if (effect.HasTargetType(StatusEffect.TargetType.This))
|
||||
{
|
||||
effect.Apply(effect.type, 1.0f, targetLimb.character, targetLimb.character, targetLimb.WorldPosition);
|
||||
@@ -951,32 +949,27 @@ namespace Barotrauma.Items.Components
|
||||
effect.HasTargetType(StatusEffect.TargetType.NearbyCharacters))
|
||||
{
|
||||
targets.Clear();
|
||||
targets.AddRange(effect.GetNearbyTargets(targetLimb.WorldPosition, targets));
|
||||
effect.AddNearbyTargets(targetLimb.WorldPosition, targets);
|
||||
effect.Apply(ActionType.OnActive, 1.0f, targetLimb.character, targets);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#if SERVER
|
||||
if (GameMain.NetworkMember.IsServer)
|
||||
if (GameMain.NetworkMember is { IsServer: true } server)
|
||||
{
|
||||
GameMain.Server?.CreateEntityEvent(item, new Item.ApplyStatusEffectEventData(actionType, this, targetLimb.character, targetLimb, null, item.WorldPosition));
|
||||
GameMain.Server?.CreateEntityEvent(item, new Item.ApplyStatusEffectEventData(ActionType.OnImpact, this, targetLimb.character, targetLimb, null, item.WorldPosition));
|
||||
server.CreateEntityEvent(item, new Item.ApplyStatusEffectEventData(conditionalActionType, this, targetLimb.character, targetLimb, null, item.WorldPosition));
|
||||
server.CreateEntityEvent(item, new Item.ApplyStatusEffectEventData(ActionType.OnImpact, this, targetLimb.character, targetLimb, null, item.WorldPosition));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
ApplyStatusEffects(actionType, 1.0f, useTarget: target.Body.UserData as Entity, user: _user);
|
||||
ApplyStatusEffects(ActionType.OnImpact, 1.0f, useTarget: target.Body.UserData as Entity, user: _user);
|
||||
#if SERVER
|
||||
if (GameMain.NetworkMember.IsServer)
|
||||
ApplyStatusEffects(conditionalActionType, 1.0f, useTarget: target.Body.UserData as Entity, user: User);
|
||||
ApplyStatusEffects(ActionType.OnImpact, 1.0f, useTarget: target.Body.UserData as Entity, user: User);
|
||||
if (GameMain.NetworkMember is { IsServer: true } server)
|
||||
{
|
||||
GameMain.Server?.CreateEntityEvent(item, new Item.ApplyStatusEffectEventData(actionType, this, null, null, target.Body.UserData as Entity, item.WorldPosition));
|
||||
GameMain.Server?.CreateEntityEvent(item, new Item.ApplyStatusEffectEventData(ActionType.OnImpact, this, null, null, target.Body.UserData as Entity, item.WorldPosition));
|
||||
server.CreateEntityEvent(item, new Item.ApplyStatusEffectEventData(conditionalActionType, this, null, null, target.Body.UserData as Entity, item.WorldPosition));
|
||||
server.CreateEntityEvent(item, new Item.ApplyStatusEffectEventData(ActionType.OnImpact, this, null, null, target.Body.UserData as Entity, item.WorldPosition));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -289,7 +289,7 @@ namespace Barotrauma.Items.Components
|
||||
#if CLIENT
|
||||
Light.ParentSub = item.Submarine;
|
||||
#endif
|
||||
if (item.Container != null)
|
||||
if (item.Container != null && !(item.GetRootInventoryOwner() is Character))
|
||||
{
|
||||
SetLightSourceState(false, 0.0f);
|
||||
return;
|
||||
@@ -301,7 +301,7 @@ namespace Barotrauma.Items.Components
|
||||
if (body != null && !body.Enabled)
|
||||
{
|
||||
SetLightSourceState(false, 0.0f);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
//currPowerConsumption = powerConsumption;
|
||||
|
||||
Reference in New Issue
Block a user