Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/Propulsion.cs
2024-06-18 16:50:02 +03:00

115 lines
3.9 KiB
C#

using System.Xml.Linq;
using Microsoft.Xna.Framework;
using Barotrauma.Networking;
#if CLIENT
using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Particles;
#endif
namespace Barotrauma.Items.Components
{
class Propulsion : ItemComponent
{
public enum UseEnvironment
{
Air, Water, Both, None
};
private float useState;
[Serialize(UseEnvironment.Both, IsPropertySaveable.No, description: "Can the item be used in air, underwater or both.")]
public UseEnvironment UsableIn { get; set; }
[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.")]
public string Particles
{
get { return particles; }
set { particles = value; }
}
#endif
public Propulsion(Item item, ContentXElement element)
: base(item,element)
{
}
public override bool Use(float deltaTime, Character character = null)
{
if (character == null || character.Removed) { return false; }
if (!character.IsKeyDown(InputType.Aim) || character.Stun > 0.0f) { return false; }
if (UsableIn == UseEnvironment.None) { return false; }
IsActive = true;
useState = 0.1f;
if (character.AnimController.InWater)
{
if (UsableIn == UseEnvironment.Air) { return true; }
}
else
{
if (UsableIn == UseEnvironment.Water) { return true; }
}
Vector2 dir = character.CursorPosition - character.Position;
if (!MathUtils.IsValid(dir)) { return true; }
float length = 200;
dir = dir.ClampLength(length) / length;
Vector2 propulsion = dir * Force * character.PropulsionSpeedMultiplier * (1.0f + character.GetStatValue(StatTypes.PropulsionSpeed));
if (character.AnimController.InWater && Force > 0.0f) { character.AnimController.TargetMovement = dir; }
foreach (Limb limb in character.AnimController.Limbs)
{
if (limb.WearingItems.Find(w => w.WearableComponent.Item == item) == null) { continue; }
limb.body.ApplyForce(propulsion);
}
character.AnimController.Collider.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
if (!string.IsNullOrWhiteSpace(particles))
{
GameMain.ParticleManager.CreateParticle(particles, item.WorldPosition,
item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi), 0.0f, item.CurrentHull);
}
#endif
return true;
}
public override void Update(float deltaTime, Camera cam)
{
useState -= deltaTime;
if (useState <= 0.0f)
{
IsActive = false;
}
if (item.AiTarget != null && IsActive)
{
item.AiTarget.SoundRange = item.AiTarget.MaxSoundRange;
}
}
}
}