Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Holdable 'Swing' Refactor #14657

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ public void Grab(Vector2 rightHandPos, Vector2 leftHandPos)
private Direction previousDirection;
private readonly Vector2[] transformedHandlePos = new Vector2[2];
//TODO: refactor this method, it's way too convoluted
public void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 itemPos, bool aim, float holdAngle, float itemAngleRelativeToHoldAngle = 0.0f, bool aimMelee = false, Vector2? targetPos = null)
public void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 itemPos, bool aim, float holdAngle, float itemAngleRelativeToHoldAngle = 0.0f, bool aimMelee = false, Vector2? targetPos = null, float armAngle = 0f)
{
aimingMelee = aimMelee;
if (character.Stun > 0.0f || character.IsIncapacitated)
Expand Down Expand Up @@ -473,7 +473,7 @@ public void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 it
MathUtils.RotatePoint(Vector2.UnitX, torsoRotation);

holdAngle = MathUtils.VectorToAngle(new Vector2(diff.X, diff.Y * Dir)) - torsoRotation * Dir;
holdAngle += GetAimWobble(rightHand, leftHand, item);
holdAngle += armAngle + GetAimWobble(rightHand, leftHand, item);
itemAngle = torsoRotation + holdAngle * Dir;

if (holdable.ControlPose)
Expand All @@ -490,6 +490,7 @@ public void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 it
}
else
{
holdAngle += armAngle;
if (holdable.UseHandRotationForHoldAngle)
{
if (equippedInRightHand)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ public EventData(Vector2 attachPos)
private LocalizedString prevMsg;
private Dictionary<RelatedItem.RelationType, List<RelatedItem>> prevRequiredItems;

private float swingState;

private Character prevEquipper;

public override bool IsAttached => Attached;
Expand Down Expand Up @@ -145,74 +143,50 @@ public Vector2 AimPos
protected Vector2 aimPos;

protected float holdAngle;
#if DEBUG
[Editable, Serialize(0.0f, IsPropertySaveable.No, description: "The rotation at which the character holds the item (in degrees, relative to the rotation of the character's hand).")]
#else
[Serialize(0.0f, IsPropertySaveable.No)]
#endif
[Serialize(0f, IsPropertySaveable.No, description: "The rotation at which the character holds the item (in degrees, relative to the rotation of the character's hand).")]
public float HoldAngle
{
get { return MathHelper.ToDegrees(holdAngle); }
set { holdAngle = MathHelper.ToRadians(value); }
}

protected float aimAngle;
#if DEBUG
[Editable, Serialize(0.0f, IsPropertySaveable.No, description: "The rotation at which the character holds the item while aiming (in degrees, relative to the rotation of the character's hand).")]
#else
[Serialize(0.0f, IsPropertySaveable.No)]
#endif
[Serialize(0f, IsPropertySaveable.No, description: "The rotation at which the character holds the item while aiming (in degrees, relative to the rotation of the character's hand).")]
public float AimAngle
{
get { return MathHelper.ToDegrees(aimAngle); }
set { aimAngle = MathHelper.ToRadians(value); }
}

private Vector2 swingAmount;
#if DEBUG
[Editable, Serialize("0.0,0.0", IsPropertySaveable.No, description: "How much the item swings around when aiming/holding it (in pixels, as an offset from AimPos/HoldPos).")]
#else
[Serialize("0.0,0.0", IsPropertySaveable.No)]
#endif
[Serialize("0,0", IsPropertySaveable.No, description: "How much the item swings around when aiming/holding it (in pixels, as an offset from AimPos/HoldPos).")]
public Vector2 SwingAmount
{
get { return ConvertUnits.ToDisplayUnits(swingAmount); }
set { swingAmount = ConvertUnits.ToSimUnits(value); }
get => ConvertUnits.ToDisplayUnits(swingAmount);
set => swingAmount = ConvertUnits.ToSimUnits(value);
}
#if DEBUG
[Editable, Serialize(0.0f, IsPropertySaveable.No, description: "How fast the item swings around when aiming/holding it (only valid if SwingAmount is set).")]
#else
[Serialize(0.0f, IsPropertySaveable.No)]
#endif

private float swingRotation;
[Serialize(0f, IsPropertySaveable.No, description: "How much the item swings around while aiming/holding it (in degrees, as an offset from the angle between the shoulder and the cursor.")]
public float SwingRotation
{
get => MathHelper.ToDegrees(swingRotation);
set => swingRotation = MathHelper.ToRadians(value);
}

[Serialize(1f, IsPropertySaveable.No, description: "How fast the item swings around when aiming/holding it (only valid if SwingAmount is set).")]
public float SwingSpeed { get; set; }

#if DEBUG
[Editable, Serialize(false, IsPropertySaveable.No, description: "Should the item swing around when it's being held.")]
#else
[Serialize(false, IsPropertySaveable.No)]
#endif
[Serialize(false, IsPropertySaveable.No, description: "Should the item swing around when it's being held.")]
public bool SwingWhenHolding { get; set; }

#if DEBUG
[Editable, Serialize(false, IsPropertySaveable.No, description: "Should the item swing around when it's being aimed.")]
#else
[Serialize(false, IsPropertySaveable.No)]
#endif
[Serialize(false, IsPropertySaveable.No, description: "Should the item swing around when it's being aimed.")]
public bool SwingWhenAiming { get; set; }

#if DEBUG
[Editable, Serialize(false, IsPropertySaveable.No, description: "Should the item swing around when it's being used (for example, when firing a weapon or a welding tool).")]
#else
[Serialize(false, IsPropertySaveable.No)]
#endif
[Serialize(false, IsPropertySaveable.No, description: "Should the item swing around when it's being used (for example, when firing a weapon or a welding tool).")]
public bool SwingWhenUsing { get; set; }

#if DEBUG
[Editable, Serialize(false, IsPropertySaveable.No)]
#else
[Serialize(false, IsPropertySaveable.No)]
#endif
public bool DisableHeadRotation { get; set; }

[Serialize(false, IsPropertySaveable.No, description: "If true, this item can't be used if the character is also holding a ranged weapon.")]
Expand Down Expand Up @@ -921,7 +895,7 @@ public override void Update(float deltaTime, Camera cam)
Drawable = true;
}

UpdateSwingPos(deltaTime, out Vector2 swingPos);
UpdateSwing(deltaTime, out Vector2 swingPos, out float swingAngle);
if (item.body.Dir != picker.AnimController.Dir)
{
item.FlipX(relativeToSub: false);
Expand All @@ -943,12 +917,12 @@ public override void Update(float deltaTime, Camera cam)
}
else
{
picker.AnimController.HoldItem(deltaTime, item, scaledHandlePos, itemPos: aimPos + swingPos, aim: true, holdAngle, aimAngle);
picker.AnimController.HoldItem(deltaTime, item, scaledHandlePos, itemPos: aimPos + swingPos, aim: true, holdAngle, aimAngle, armAngle: swingAngle);
}
}
else
{
picker.AnimController.HoldItem(deltaTime, item, scaledHandlePos, itemPos: holdPos + swingPos, aim: false, holdAngle);
picker.AnimController.HoldItem(deltaTime, item, scaledHandlePos, itemPos: holdPos + swingPos, aim: false, holdAngle, armAngle: swingAngle);
if (GetRope() is { SnapWhenNotAimed: true } rope)
{
if (rope.Item.ParentInventory == null)
Expand Down Expand Up @@ -985,20 +959,21 @@ public override void Update(float deltaTime, Camera cam)
}
}

public void UpdateSwingPos(float deltaTime, out Vector2 swingPos)
public void UpdateSwing(float deltaTime, out Vector2 swingPos, out float swingAngle)
{
swingPos = Vector2.Zero;
if (swingAmount != Vector2.Zero && !picker.IsUnconscious && picker.Stun <= 0.0f)
swingAngle = 0f;
if (!picker.IsUnconscious && picker.Stun <= 0f && (SwingWhenHolding || SwingWhenAiming && picker.IsKeyDown(InputType.Aim) || SwingWhenUsing && picker.IsKeyDown(InputType.Aim) && picker.IsKeyDown(InputType.Shoot)))
{
swingState += deltaTime;
swingState %= 1.0f;
if (SwingWhenHolding ||
(SwingWhenAiming && picker.IsKeyDown(InputType.Aim)) ||
(SwingWhenUsing && picker.IsKeyDown(InputType.Aim) && picker.IsKeyDown(InputType.Shoot)))
float noisePos = (float)Timing.TotalTimeUnpaused * SwingSpeed * deltaTime;
if (swingAmount != Vector2.Zero)
{
swingPos.X = MathHelper.Lerp(-swingAmount.X, swingAmount.X, PerlinNoise.GetPerlin(noisePos));
swingPos.Y = MathHelper.Lerp(-swingAmount.Y, swingAmount.Y, PerlinNoise.GetPerlin(noisePos - 0.5f));
}
if (swingRotation != 0f)
{
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);
swingAngle = MathHelper.Lerp(-swingRotation, swingRotation, PerlinNoise.GetPerlin(noisePos));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using FarseerPhysics;
using Barotrauma.Extensions;
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Contacts;
using Microsoft.Xna.Framework;
Expand Down Expand Up @@ -223,9 +224,9 @@ public override void Update(float deltaTime, Camera cam)
bool aim = item.RequireAimToUse && picker.AllowInput && picker.IsKeyDown(InputType.Aim) && reloadTimer <= 0 && picker.CanAim && !UsageDisabledByRangedWeapon(picker);
if (aim)
{
UpdateSwingPos(deltaTime, out Vector2 swingPos);
UpdateSwing(deltaTime, out Vector2 swingPos, out float swingAngle);
hitPos = MathUtils.WrapAnglePi(Math.Min(hitPos + deltaTime * 3f, MathHelper.PiOver4));
ac.HoldItem(deltaTime, item, handlePos, itemPos: aimPos + swingPos, aim: false, hitPos, holdAngle + hitPos + aimAngle, aimMelee: true);
ac.HoldItem(deltaTime, item, handlePos, itemPos: aimPos + swingPos, aim: false, hitPos, holdAngle + hitPos + aimAngle, aimMelee: true, armAngle: swingAngle);
if (ac.InWater)
{
ac.LockFlipping();
Expand Down
42 changes: 26 additions & 16 deletions Barotrauma/BarotraumaShared/SharedSource/ProcGen/PerlinNoise.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,22 @@ public static double OctavePerlin(double x, double y, double z, double frequency
// arranged array of all numbers from 0-255 inclusive.
private static readonly int[] permutation =
{
151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
151,160,137, 91, 90, 15,131, 13,201, 95, 96, 53,194,233, 7,225,
140, 36,103, 30, 69,142, 8, 99, 37,240, 21, 10, 23,190, 6,148,
247,120,234, 75, 0, 26,197, 62, 94,252,219,203,117, 35, 11, 32,
57,177, 33, 88,237,149, 56, 87,174, 20,125,136,171,168, 68,175,
74,165, 71,134,139, 48, 27,166, 77,146,158,231, 83,111,229,122,
60,211,133,230,220,105, 92, 41, 55, 46,245, 40,244,102,143, 54,
65, 25, 63,161, 1,216, 80, 73,209, 76,132,187,208, 89, 18,169,
200,196,135,130,116,188,159, 86,164,100,109,198,173,186, 3, 64,
52,217,226,250,124,123, 5,202, 38,147,118,126,255, 82, 85,212,
207,206, 59,227, 47, 16, 58, 17,182,189, 28, 42,223,183,170,213,
119,248,152, 2, 44,154,163, 70,221,153,101,155,167, 43,172, 9,
129, 22, 39,253, 19, 98,108,110, 79,113,224,232,178,185,112,104,
218,246, 97,228,251, 34,242,193,238,210,144, 12,191,179,162,241,
81, 51,145,235,249, 14,239,107, 49,192,214, 31,181,199,106,157,
184, 84,204,176,115,121, 50, 45,127, 4,150,254,138,236,205, 93,
222,114, 67, 29, 24, 72,243,141,128,195, 78, 66,215, 61,156,180
};

private static readonly int[] p; // Doubled permutation to avoid overflow
Expand Down Expand Up @@ -85,9 +88,9 @@ static PerlinNoise()
/// <summary>
/// Sample a pre-generated perlin noise map. Faster than calculating the noise on the fly.
/// </summary>
/// <param name="x">Normalized x position. The noise map starts repeating after x > 1</param>
/// <param name="y">Normalized y position. The noise map starts repeating after y > 1</param>
/// <returns>A noise value between 0.0f and 1.0f</returns>
/// <param name="x">X position. The noise map repeats after 1.</param>
/// <param name="y">Y position. The noise map repeats after 1.</param>
/// <returns>A noise value between 0 and 1.</returns>
public static float GetPerlin(float x, float y)
{
x = Math.Abs(x) % 1.0f;
Expand All @@ -108,6 +111,13 @@ public static float GetPerlin(float x, float y)
yIndex % 1.0f);
}

/// <summary>
/// Sample a pre-generated perlin noise map. Faster than calculating the noise on the fly.
/// </summary>
/// <param name="xy">XY Position. The noise map repeats after 1.</param>
/// <returns>A noise value between 0 and 1.</returns>
public static float GetPerlin(float xy) => GetPerlin(xy, xy);

public static double CalculatePerlin(double x, double y, double z)
{
int xi = (int)x & 255; // Calculate the "unit cube" that the point asked will be located in
Expand Down