Fixed a bunch of bugs when dragging characters up ladders (see e0504042). The dragging logic didn't take into account that the characters are not necessarily in the same sub, which caused the dragged character to launch away at a high speed when climbing from a sub to another (for example when climbing down to the shuttle in Aegir). The pull joint on the target's torso was never disabled, so the character stayed floating mid-air after getting off the ladders.

+ Made Limb.pullJoint private. Now it can only be accessed by properties of the Limb, and there's some error checks in place to prevent WorldAnchorB from being set to an invalid value.
This commit is contained in:
Joonas Rikkonen
2018-09-24 21:19:18 +03:00
parent bff2852cb6
commit fec7740378
8 changed files with 285 additions and 233 deletions

View File

@@ -100,9 +100,9 @@ namespace Barotrauma
foreach (Limb limb in Limbs)
{
if (limb.pullJoint != null)
if (limb.PullJointEnabled)
{
Vector2 pos = ConvertUnits.ToDisplayUnits(limb.pullJoint.WorldAnchorA);
Vector2 pos = ConvertUnits.ToDisplayUnits(limb.PullJointWorldAnchorA);
if (currentHull != null) pos += currentHull.Submarine.DrawPosition;
pos.Y = -pos.Y;
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)pos.Y, 5, 5), Color.Red, true, 0.01f);

View File

@@ -182,11 +182,8 @@ namespace Barotrauma
Character.Controlled.AnimController.Anim = (Character.Controlled.AnimController.Anim == AnimController.Animation.CPR) ?
AnimController.Animation.None : AnimController.Animation.CPR;
foreach (Limb limb in Character.Controlled.SelectedCharacter.AnimController.Limbs)
{
limb.pullJoint.Enabled = false;
}
Character.Controlled.SelectedCharacter.AnimController.ResetPullJoints();
if (GameMain.Client != null)
{
GameMain.Client.CreateEntityEvent(Character.Controlled, new object[] { NetEntityEvent.Type.Repair });
@@ -208,10 +205,7 @@ namespace Barotrauma
Character.Controlled.AnimController.GrabLimb = Character.Controlled.AnimController.GrabLimb == LimbType.None ? LimbType.Torso : LimbType.None;
foreach (Limb limb in Character.Controlled.SelectedCharacter.AnimController.Limbs)
{
limb.pullJoint.Enabled = false;
}
Character.Controlled.SelectedCharacter.AnimController.ResetPullJoints();
if (GameMain.Client != null)
{

View File

@@ -59,8 +59,8 @@ namespace Barotrauma
if (character.IsRemotePlayer)
{
MainLimb.pullJoint.WorldAnchorB = Collider.SimPosition;
MainLimb.pullJoint.Enabled = true;
MainLimb.PullJointWorldAnchorB = Collider.SimPosition;
MainLimb.PullJointEnabled = true;
}
else
{
@@ -256,8 +256,8 @@ namespace Barotrauma
{
movement = TargetMovement*swimSpeed;
MainLimb.pullJoint.Enabled = true;
MainLimb.pullJoint.WorldAnchorB = Collider.SimPosition;
MainLimb.PullJointEnabled = true;
MainLimb.PullJointWorldAnchorB = Collider.SimPosition;
if (movement.LengthSquared() < 0.00001f) return;
@@ -289,7 +289,7 @@ namespace Barotrauma
{
if (Limbs[i].SteerForce <= 0.0f) continue;
Vector2 pullPos = Limbs[i].pullJoint == null ? Limbs[i].SimPosition : Limbs[i].pullJoint.WorldAnchorA;
Vector2 pullPos = Limbs[i].PullJointWorldAnchorA;
Limbs[i].body.ApplyForce(movement * Limbs[i].SteerForce * Limbs[i].Mass, pullPos);
}
@@ -322,8 +322,8 @@ namespace Barotrauma
MainLimb.MoveToPos(GetColliderBottom() + Vector2.UnitY * mainLimbHeight, 10.0f);
MainLimb.pullJoint.Enabled = true;
MainLimb.pullJoint.WorldAnchorB = GetColliderBottom() + Vector2.UnitY * mainLimbHeight;
MainLimb.PullJointEnabled = true;
MainLimb.PullJointWorldAnchorB = GetColliderBottom() + Vector2.UnitY * mainLimbHeight;
walkPos -= MainLimb.LinearVelocity.X * 0.05f;

View File

@@ -161,7 +161,7 @@ namespace Barotrauma
midPos += Vector2.Transform(new Vector2(-0.3f * Dir, -0.2f), torsoTransform);
if (rightHand.pullJoint.Enabled) midPos = (midPos + rightHand.pullJoint.WorldAnchorB) / 2.0f;
if (rightHand.PullJointEnabled) midPos = (midPos + rightHand.PullJointWorldAnchorB) / 2.0f;
HandIK(rightHand, midPos);
HandIK(leftHand, midPos);
@@ -176,8 +176,12 @@ namespace Barotrauma
UpdateStandingSimple();
return;
}
if (character.SelectedCharacter != null)
{
DragCharacter(character.SelectedCharacter);
}
switch (Anim)
{
case Animation.Climbing:
@@ -189,15 +193,12 @@ namespace Barotrauma
break;
case Animation.UsingConstruction:
default:
if (Anim == Animation.UsingConstruction)
{
useItemTimer -= deltaTime;
if (useItemTimer <= 0.0f) Anim = Animation.None;
}
if (character.SelectedCharacter != null) DragCharacter(character.SelectedCharacter);
//0.5 second delay for switching between swimming and walking
//prevents rapid switches between swimming/walking if the water level is fluctuating around the minimum swimming depth
if (inWater)
@@ -341,44 +342,44 @@ namespace Barotrauma
getUpSpeed = getUpSpeed * Math.Max(head.SimPosition.Y - colliderPos.Y, 0.5f);
torso.pullJoint.Enabled = true;
head.pullJoint.Enabled = true;
waist.pullJoint.Enabled = true;
torso.PullJointEnabled = true;
head.PullJointEnabled = true;
waist.PullJointEnabled = true;
float floorPos = GetFloorY(colliderPos + new Vector2(Math.Sign(movement.X) * 0.5f, 1.0f));
bool onSlope = floorPos > GetColliderBottom().Y + 0.05f;
if (Stairs != null || onSlope)
{
torso.pullJoint.WorldAnchorB = new Vector2(
torso.PullJointWorldAnchorB = new Vector2(
MathHelper.SmoothStep(torso.SimPosition.X, footMid + movement.X * 0.25f, getUpSpeed * 0.8f),
MathHelper.SmoothStep(torso.SimPosition.Y, colliderPos.Y + TorsoPosition - Math.Abs(walkPosX * 0.05f), getUpSpeed * 2.0f));
head.pullJoint.WorldAnchorB = new Vector2(
head.PullJointWorldAnchorB = new Vector2(
MathHelper.SmoothStep(head.SimPosition.X, footMid + movement.X * (Crouching ? 0.6f : 0.25f), getUpSpeed * 0.8f),
MathHelper.SmoothStep(head.SimPosition.Y, colliderPos.Y + HeadPosition - Math.Abs(walkPosX * 0.05f), getUpSpeed * 2.0f));
waist.pullJoint.WorldAnchorB = waist.SimPosition;// +movement * 0.3f;
waist.PullJointWorldAnchorB = waist.SimPosition;
}
else
{
if (!onGround) movement = Vector2.Zero;
torso.pullJoint.WorldAnchorB =
torso.PullJointWorldAnchorB =
MathUtils.SmoothStep(torso.SimPosition,
new Vector2(footMid + movement.X * 0.2f, colliderPos.Y + TorsoPosition), getUpSpeed);
head.pullJoint.WorldAnchorB =
head.PullJointWorldAnchorB =
MathUtils.SmoothStep(head.SimPosition,
new Vector2(footMid + movement.X * (Crouching && Math.Sign(movement.X) == Math.Sign(Dir) ? 0.6f : 0.2f), colliderPos.Y + HeadPosition), getUpSpeed * 1.2f);
waist.pullJoint.WorldAnchorB = waist.SimPosition + movement * 0.06f;
waist.PullJointWorldAnchorB = waist.SimPosition + movement * 0.06f;
}
if (!onGround)
{
Vector2 move = torso.pullJoint.WorldAnchorB - torso.SimPosition;
Vector2 move = torso.PullJointWorldAnchorB - torso.SimPosition;
foreach (Limb limb in Limbs)
{
@@ -888,34 +889,6 @@ namespace Barotrauma
character.SelectedConstruction = null;
IgnorePlatforms = false;
}
else if (character.SelectedCharacter != null && !character.SelectedCharacter.AllowInput)
{
Limb targetLeftHand = character.SelectedCharacter.AnimController.GetLimb(LimbType.LeftHand);
Limb targetRightHand = character.SelectedCharacter.AnimController.GetLimb(LimbType.RightHand);
Limb targetTorso = character.SelectedCharacter.AnimController.GetLimb(LimbType.Torso);
if (character.SelectedCharacter.AnimController.Dir != Dir)
character.SelectedCharacter.AnimController.Flip();
targetTorso.pullJoint.Enabled = true;
targetTorso.pullJoint.WorldAnchorB = torso.SimPosition + (Vector2.UnitX * -Dir) * 0.2f;
targetTorso.pullJoint.MaxForce = 5000.0f;
if (!targetLeftHand.IsSevered)
{
targetLeftHand.pullJoint.Enabled = true;
targetLeftHand.pullJoint.WorldAnchorB = torso.SimPosition + (new Vector2(1 * Dir, 1)) * 0.2f;
targetLeftHand.pullJoint.MaxForce = 5000.0f;
}
if (!targetRightHand.IsSevered)
{
targetRightHand.pullJoint.Enabled = true;
targetRightHand.pullJoint.WorldAnchorB = torso.SimPosition + (new Vector2(1 * Dir, 1)) * 0.2f;
targetRightHand.pullJoint.MaxForce = 5000.0f;
}
character.SelectedCharacter.AnimController.IgnorePlatforms = true;
}
}
private void UpdateCPR(float deltaTime)
@@ -966,10 +939,10 @@ namespace Barotrauma
if (cprAnimState % 17 > 15.0f && targetHead != null && head != null)
{
float yPos = (float)Math.Sin(cprAnimState) * 0.2f;
head.pullJoint.WorldAnchorB = new Vector2(targetHead.SimPosition.X, targetHead.SimPosition.Y + 0.3f + yPos);
head.pullJoint.Enabled = true;
torso.pullJoint.WorldAnchorB = new Vector2(torso.SimPosition.X, colliderPos.Y + (TorsoPosition - 0.2f));
torso.pullJoint.Enabled = true;
head.PullJointWorldAnchorB = new Vector2(targetHead.SimPosition.X, targetHead.SimPosition.Y + 0.3f + yPos);
head.PullJointEnabled = true;
torso.PullJointWorldAnchorB = new Vector2(torso.SimPosition.X, colliderPos.Y + (TorsoPosition - 0.2f));
torso.PullJointEnabled = true;
if (GameMain.Client == null) //Serverside code
{
@@ -985,11 +958,11 @@ namespace Barotrauma
{
if (targetHead != null && head != null)
{
head.pullJoint.WorldAnchorB = new Vector2(targetHead.SimPosition.X, targetHead.SimPosition.Y + 0.8f);
head.pullJoint.Enabled = true;
head.PullJointWorldAnchorB = new Vector2(targetHead.SimPosition.X, targetHead.SimPosition.Y + 0.8f);
head.PullJointEnabled = true;
}
torso.pullJoint.WorldAnchorB = new Vector2(torso.SimPosition.X, colliderPos.Y + (TorsoPosition - 0.1f));
torso.pullJoint.Enabled = true;
torso.PullJointWorldAnchorB = new Vector2(torso.SimPosition.X, colliderPos.Y + (TorsoPosition - 0.1f));
torso.PullJointEnabled = true;
if (cprPump >= 1)
{
torso.body.ApplyForce(new Vector2(0, -1000f));
@@ -1037,140 +1010,203 @@ namespace Barotrauma
cprAnimState += deltaTime;
}
public override void DragCharacter(Character target)
{
if (target == null) return;
Limb torso = GetLimb(LimbType.Torso);
Limb leftHand = GetLimb(LimbType.LeftHand);
Limb rightHand = GetLimb(LimbType.RightHand);
Limb targetLeftHand = target.AnimController.GetLimb(LimbType.LeftHand);
Limb targetRightHand = target.AnimController.GetLimb(LimbType.RightHand);
//only grab with one hand when swimming
leftHand.Disabled = true;
if (!inWater) rightHand.Disabled = true;
target.AnimController.ResetPullJoints();
for (int i = 0; i < 2; i++)
if (Anim == Animation.Climbing)
{
Limb targetLimb = target.AnimController.GetLimb(GrabLimb);
Limb targetTorso = target.AnimController.GetLimb(LimbType.Torso);
if (targetTorso == null) targetTorso = target.AnimController.MainLimb;
//grab hands if GrabLimb is not specified (or torso if the character has no hands)
if (GrabLimb == LimbType.None || targetLimb.IsSevered)
if (target.AnimController.Dir != Dir)
target.AnimController.Flip();
Vector2 transformedTorsoPos = torso.SimPosition;
if (character.Submarine == null && target.Submarine != null)
{
targetLimb = target.AnimController.GetLimb(LimbType.Torso);
if (i == 0)
transformedTorsoPos -= target.Submarine.SimPosition;
}
else if (character.Submarine != null && target.Submarine == null)
{
transformedTorsoPos += character.Submarine.SimPosition;
}
else if (character.Submarine != null && target.Submarine != null && character.Submarine != target.Submarine)
{
transformedTorsoPos += character.Submarine.SimPosition;
transformedTorsoPos -= target.Submarine.SimPosition;
}
targetTorso.PullJointEnabled = true;
targetTorso.PullJointWorldAnchorB = transformedTorsoPos + (Vector2.UnitX * -Dir) * 0.2f;
targetTorso.PullJointMaxForce = 5000.0f;
if (!targetLeftHand.IsSevered)
{
targetLeftHand.PullJointEnabled = true;
targetLeftHand.PullJointWorldAnchorB = transformedTorsoPos + (new Vector2(1 * Dir, 1)) * 0.2f;
targetLeftHand.PullJointMaxForce = 5000.0f;
}
if (!targetRightHand.IsSevered)
{
targetRightHand.PullJointEnabled = true;
targetRightHand.PullJointWorldAnchorB = transformedTorsoPos + (new Vector2(1 * Dir, 1)) * 0.2f;
targetRightHand.PullJointMaxForce = 5000.0f;
}
target.AnimController.IgnorePlatforms = true;
}
else
{
Limb leftHand = GetLimb(LimbType.LeftHand);
Limb rightHand = GetLimb(LimbType.RightHand);
//only grab with one hand when swimming
leftHand.Disabled = true;
if (!inWater) rightHand.Disabled = true;
for (int i = 0; i < 2; i++)
{
Limb targetLimb = target.AnimController.GetLimb(GrabLimb);
//grab hands if GrabLimb is not specified (or torso if the character has no hands)
if (GrabLimb == LimbType.None || targetLimb.IsSevered)
{
if (!targetLeftHand.IsSevered)
targetLimb = target.AnimController.GetLimb(LimbType.Torso);
if (i == 0)
{
targetLimb = targetLeftHand;
if (!targetLeftHand.IsSevered)
{
targetLimb = targetLeftHand;
}
else if (!targetRightHand.IsSevered)
{
targetLimb = targetRightHand;
}
}
else if (!targetRightHand.IsSevered)
else
{
targetLimb = targetRightHand;
if (!targetRightHand.IsSevered)
{
targetLimb = targetRightHand;
}
else if (!targetLeftHand.IsSevered)
{
targetLimb = targetLeftHand;
}
}
}
else
Limb pullLimb = i == 0 ? leftHand : rightHand;
if (GameMain.Client == null)
{
if (!targetRightHand.IsSevered)
//stop dragging if there's something between the pull limb and the target limb
Vector2 sourceSimPos = pullLimb.SimPosition;
Vector2 targetSimPos = targetLimb.SimPosition;
if (character.Submarine != null && target.Submarine == null)
{
targetLimb = targetRightHand;
targetSimPos -= character.Submarine.SimPosition;
}
else if (!targetLeftHand.IsSevered)
else if (character.Submarine == null && target.Submarine != null)
{
targetLimb = targetLeftHand;
sourceSimPos -= target.Submarine.SimPosition;
}
var body = Submarine.CheckVisibility(sourceSimPos, targetSimPos, ignoreSubs: true);
if (body != null)
{
character.DeselectCharacter();
return;
}
}
//only pull with one hand when swimming
if (i < 1 || !inWater)
{
Vector2 diff = ConvertUnits.ToSimUnits(targetLimb.WorldPosition - pullLimb.WorldPosition);
pullLimb.PullJointEnabled = true;
targetLimb.PullJointEnabled = true;
if (targetLimb.type == LimbType.Torso || targetLimb == target.AnimController.MainLimb)
{
pullLimb.PullJointWorldAnchorB = targetLimb.SimPosition;
pullLimb.PullJointMaxForce = 5000.0f;
targetMovement *= MathHelper.Clamp(Mass / target.Mass, 0.5f, 1.0f);
//hand length
float a = 37.0f;
//arm length
float b = 28.0f;
Vector2 shoulderPos = LimbJoints[2].WorldAnchorA;
Vector2 dragDir = inWater ? Vector2.Normalize(targetLimb.SimPosition - shoulderPos) : Vector2.UnitY;
targetLimb.PullJointWorldAnchorB = shoulderPos - dragDir * ConvertUnits.ToSimUnits(a + b);
targetLimb.PullJointMaxForce = 200.0f;
if (target.Submarine != character.Submarine)
{
if (character.Submarine == null)
{
pullLimb.PullJointWorldAnchorB += target.Submarine.SimPosition;
targetLimb.PullJointWorldAnchorB -= target.Submarine.SimPosition;
}
else if (target.Submarine == null)
{
pullLimb.PullJointWorldAnchorB -= character.Submarine.SimPosition;
targetLimb.PullJointWorldAnchorB += character.Submarine.SimPosition;
}
else
{
pullLimb.PullJointWorldAnchorB -= target.Submarine.SimPosition;
pullLimb.PullJointWorldAnchorB += character.Submarine.SimPosition;
targetLimb.PullJointWorldAnchorB -= character.Submarine.SimPosition;
targetLimb.PullJointWorldAnchorB += target.Submarine.SimPosition;
}
}
}
else
{
pullLimb.PullJointWorldAnchorB = pullLimb.SimPosition + diff;
pullLimb.PullJointMaxForce = 5000.0f;
targetLimb.PullJointWorldAnchorB = targetLimb.SimPosition - diff;
targetLimb.PullJointMaxForce = 5000.0f;
}
target.AnimController.movement = -diff;
}
}
Limb pullLimb = i == 0 ? leftHand : rightHand;
float dist = Vector2.Distance(target.SimPosition, Collider.SimPosition);
if (GameMain.Client == null)
//limit movement if moving away from the target
if (Vector2.Dot(target.SimPosition - Collider.SimPosition, targetMovement) < 0)
{
//stop dragging if there's something between the pull limb and the target limb
Vector2 sourceSimPos = pullLimb.SimPosition;
Vector2 targetSimPos = targetLimb.SimPosition;
if (character.Submarine != null && character.SelectedCharacter.Submarine == null)
{
targetSimPos -= character.Submarine.SimPosition;
}
else if (character.Submarine == null && character.SelectedCharacter.Submarine != null)
{
sourceSimPos -= character.SelectedCharacter.Submarine.SimPosition;
}
var body = Submarine.CheckVisibility(sourceSimPos, targetSimPos, ignoreSubs: true);
if (body != null)
{
character.DeselectCharacter();
return;
}
targetMovement *= MathHelper.Clamp(2.0f - dist, 0.0f, 1.0f);
}
if (i == 1 && inWater)
target.AnimController.IgnorePlatforms = IgnorePlatforms;
if (!target.AllowInput)
{
targetLimb.pullJoint.Enabled = false;
target.AnimController.TargetMovement = TargetMovement;
}
else
else if (target is AICharacter)
{
Vector2 diff = ConvertUnits.ToSimUnits(targetLimb.WorldPosition - pullLimb.WorldPosition);
pullLimb.pullJoint.Enabled = true;
if (targetLimb.type == LimbType.Torso)
{
pullLimb.pullJoint.WorldAnchorB = targetLimb.SimPosition;
pullLimb.pullJoint.MaxForce = 5000.0f;
targetMovement *= 0.7f; //Carrying people like that takes a lot of effort.
if (target.AnimController.Dir != Dir)
target.AnimController.Flip();
}
else
{
pullLimb.pullJoint.WorldAnchorB = pullLimb.SimPosition + diff;
pullLimb.pullJoint.MaxForce = 5000.0f;
}
targetLimb.pullJoint.Enabled = true;
if (targetLimb.type == LimbType.Torso)
{
targetLimb.pullJoint.WorldAnchorB = torso.SimPosition + (Vector2.UnitX * Dir) * 0.6f;
targetLimb.pullJoint.MaxForce = 300.0f;
}
else
{
targetLimb.pullJoint.WorldAnchorB = targetLimb.SimPosition - diff;
targetLimb.pullJoint.MaxForce = 5000.0f;
}
target.AnimController.movement = -diff;
target.AnimController.TargetMovement = Vector2.Lerp(
target.AnimController.TargetMovement,
(character.SimPosition + Vector2.UnitX * Dir) - target.SimPosition, 0.5f);
}
}
float dist = Vector2.Distance(target.SimPosition, Collider.SimPosition);
//limit movement if moving away from the target
if (Vector2.Dot(target.SimPosition - Collider.SimPosition, targetMovement)<0)
{
targetMovement *= MathHelper.Clamp(2.0f - dist, 0.0f, 1.0f);
}
target.AnimController.IgnorePlatforms = IgnorePlatforms;
if (!target.AllowInput)
{
target.AnimController.TargetMovement = TargetMovement;
}
else if (target is AICharacter)
{
target.AnimController.TargetMovement = Vector2.Lerp(
target.AnimController.TargetMovement,
(character.SimPosition + Vector2.UnitX * Dir) - target.SimPosition, 0.5f);
}
//if on stairs, make the dragged character "climb up" (= collide with stairs)
//if (Stairs != null) target.AnimController.TargetMovement = new Vector2 (target.AnimController.TargetMovement.X, 1.0f);
}
public void Grab(Vector2 rightHandPos, Vector2 leftHandPos)
@@ -1181,11 +1217,10 @@ namespace Barotrauma
pullLimb.Disabled = true;
pullLimb.pullJoint.Enabled = true;
pullLimb.pullJoint.WorldAnchorB = (i == 0) ? rightHandPos : leftHandPos;
pullLimb.pullJoint.MaxForce = 500.0f;
pullLimb.PullJointEnabled = true;
pullLimb.PullJointWorldAnchorB = (i == 0) ? rightHandPos : leftHandPos;
pullLimb.PullJointMaxForce = 500.0f;
}
}
public override void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 holdPos, Vector2 aimPos, bool aim, float holdAngle)
@@ -1246,13 +1281,13 @@ namespace Barotrauma
if (character.SelectedItems[0] == item)
{
if (rightHand.IsSevered) return;
transformedHoldPos = rightHand.pullJoint.WorldAnchorA - transformedHandlePos[0];
transformedHoldPos = rightHand.PullJointWorldAnchorA - transformedHandlePos[0];
itemAngle = (rightHand.Rotation + (holdAngle - MathHelper.PiOver2) * Dir);
}
else if (character.SelectedItems[1] == item)
{
if (leftHand.IsSevered) return;
transformedHoldPos = leftHand.pullJoint.WorldAnchorA - transformedHandlePos[1];
transformedHoldPos = leftHand.PullJointWorldAnchorA - transformedHandlePos[1];
itemAngle = (leftHand.Rotation + (holdAngle - MathHelper.PiOver2) * Dir);
}
}
@@ -1276,13 +1311,13 @@ namespace Barotrauma
item.body.ResetDynamics();
Vector2 currItemPos = (character.SelectedItems[0] == item) ?
rightHand.pullJoint.WorldAnchorA - transformedHandlePos[0] :
leftHand.pullJoint.WorldAnchorA - transformedHandlePos[1];
rightHand.PullJointWorldAnchorA - transformedHandlePos[0] :
leftHand.PullJointWorldAnchorA - transformedHandlePos[1];
if (!MathUtils.IsValid(currItemPos))
{
string errorMsg = "Attempted to move the item \"" + item + "\" to an invalid position in HumanidAnimController.HoldItem: " +
currItemPos + ", rightHandPos: " + rightHand.pullJoint.WorldAnchorA + ", leftHandPos: " + leftHand.pullJoint.WorldAnchorA +
currItemPos + ", rightHandPos: " + rightHand.PullJointWorldAnchorA + ", leftHandPos: " + leftHand.PullJointWorldAnchorA +
", handlePos[0]: " + handlePos[0] + ", handlePos[1]: " + handlePos[1] +
", transformedHandlePos[0]: " + transformedHandlePos[0] + ", transformedHandlePos[1]:" + transformedHandlePos[1] +
", item pos: " + item.SimPosition + ", itemAngle: " + itemAngle +
@@ -1357,12 +1392,12 @@ namespace Barotrauma
}
leftHand.Disabled = true;
leftHand.pullJoint.Enabled = true;
leftHand.pullJoint.WorldAnchorB = handPos;
leftHand.PullJointEnabled = true;
leftHand.PullJointWorldAnchorB = handPos;
rightHand.Disabled = true;
rightHand.pullJoint.Enabled = true;
rightHand.pullJoint.WorldAnchorB = handPos;
rightHand.PullJointEnabled = true;
rightHand.PullJointWorldAnchorB = handPos;
}
public override void Flip()
@@ -1424,7 +1459,7 @@ namespace Barotrauma
Vector2 position = limb.SimPosition;
if ((limb.pullJoint == null || !limb.pullJoint.Enabled) && mirror)
if (!limb.PullJointEnabled && mirror)
{
difference = limb.body.SimPosition - torso.SimPosition;
difference = Vector2.Transform(difference, torsoTransform);

View File

@@ -48,7 +48,7 @@ namespace Barotrauma
frozen = value;
Collider.PhysEnabled = !frozen;
if (frozen && MainLimb != null) MainLimb.pullJoint.WorldAnchorB = MainLimb.SimPosition;
if (frozen && MainLimb != null) MainLimb.PullJointWorldAnchorB = MainLimb.SimPosition;
}
}
@@ -705,13 +705,7 @@ namespace Barotrauma
limb.MouthPos.Value.Y);
}
if (limb.pullJoint != null)
{
limb.pullJoint.LocalAnchorA =
new Vector2(
-limb.pullJoint.LocalAnchorA.X,
limb.pullJoint.LocalAnchorA.Y);
}
limb.MirrorPullJoint();
}
}
@@ -742,8 +736,8 @@ namespace Barotrauma
{
for (int i = 0; i < Limbs.Length; i++)
{
if (Limbs[i] == null || Limbs[i].pullJoint == null) continue;
Limbs[i].pullJoint.Enabled = false;
if (Limbs[i] == null) continue;
Limbs[i].PullJointEnabled = false;
}
}
@@ -864,21 +858,21 @@ namespace Barotrauma
outsideCollisionBlocker.Enabled = false;
}
public void Teleport(Vector2 moveAmount, Vector2 velocityChange)
{
foreach (Limb limb in Limbs)
{
if (limb.IsSevered) continue;
if (limb.body.FarseerBody.ContactList == null) continue;
ContactEdge ce = limb.body.FarseerBody.ContactList;
while (ce != null && ce.Contact != null)
{
ce.Contact.Enabled = false;
ce = ce.Next;
}
}
}
}
foreach (Limb limb in Limbs)
{
@@ -886,13 +880,12 @@ namespace Barotrauma
limb.body.LinearVelocity += velocityChange;
}
//character.Stun = 0.1f;
character.DisableImpactDamageTimer = 0.25f;
SetPosition(Collider.SimPosition + moveAmount);
character.CursorPosition += moveAmount;
}
private void UpdateCollisionCategories()
{
Category wall = currentHull == null ?
@@ -1278,11 +1271,8 @@ namespace Barotrauma
else
{
limb.body.SetTransform(movePos, limb.Rotation);
if (limb.pullJoint != null)
{
limb.pullJoint.WorldAnchorB = limb.pullJoint.WorldAnchorA;
limb.pullJoint.Enabled = false;
}
limb.PullJointWorldAnchorB = limb.PullJointWorldAnchorA;
limb.PullJointEnabled = false;
}
}
@@ -1408,8 +1398,8 @@ namespace Barotrauma
if (!character.AllowInput)
{
Collider.LinearVelocity = overrideTargetMovement;
MainLimb.pullJoint.WorldAnchorB = Collider.SimPosition;
MainLimb.pullJoint.Enabled = true;
MainLimb.PullJointWorldAnchorB = Collider.SimPosition;
MainLimb.PullJointEnabled = true;
}
}
character.MemLocalState.Clear();

View File

@@ -1358,15 +1358,7 @@ namespace Barotrauma
public void DeselectCharacter()
{
if (SelectedCharacter == null) return;
if (SelectedCharacter.AnimController != null)
{
foreach (Limb limb in SelectedCharacter.AnimController.Limbs)
{
if (limb.pullJoint != null) limb.pullJoint.Enabled = false;
}
}
SelectedCharacter.AnimController?.ResetPullJoints();
SelectedCharacter = null;
}
@@ -1977,11 +1969,7 @@ namespace Barotrauma
if (selectedItems[i] != null) selectedItems[i].Drop(this);
}
foreach (Limb limb in AnimController.Limbs)
{
if (limb.pullJoint == null) continue;
limb.pullJoint.Enabled = false;
}
AnimController.ResetPullJoints();
foreach (RevoluteJoint joint in AnimController.LimbJoints)
{

View File

@@ -57,7 +57,7 @@ namespace Barotrauma
public bool inWater;
public FixedMouseJoint pullJoint;
private readonly FixedMouseJoint pullJoint;
public readonly LimbType type;
@@ -145,7 +145,48 @@ namespace Barotrauma
{
get { return stepOffset; }
}
public bool PullJointEnabled
{
get { return pullJoint.Enabled; }
set { pullJoint.Enabled = value; }
}
public float PullJointMaxForce
{
get { return pullJoint.MaxForce; }
set { pullJoint.MaxForce = value; }
}
public Vector2 PullJointWorldAnchorA
{
get { return pullJoint.WorldAnchorA; }
}
public Vector2 PullJointWorldAnchorB
{
get { return pullJoint.WorldAnchorB; }
set
{
if (!MathUtils.IsValid(value))
{
string errorMsg = "Attempted to set the anchor of a limb's pull joint to an invalid value (" + value + ")\n" + Environment.StackTrace;
DebugConsole.ThrowError(errorMsg);
GameAnalyticsManager.AddErrorEventOnce("Limb.SetPullJointAnchor:InvalidValue", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
return;
}
if (Vector2.DistanceSquared(pullJoint.WorldAnchorA, value) > 50.0f * 50.0f)
{
string errorMsg = "Attempted to move the anchor of a limb's pull joint extremely far from the limb (" + value + ")\n" + Environment.StackTrace;
DebugConsole.ThrowError(errorMsg);
GameAnalyticsManager.AddErrorEventOnce("Limb.SetPullJointAnchor:ExcessiveValue", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
return;
}
pullJoint.WorldAnchorB = value;
}
}
public List<WearableSprite> WearingItems { get; private set; }
public Limb (Character character, XElement element, float scale = 1.0f)
@@ -208,9 +249,11 @@ namespace Barotrauma
type = LimbType.None;
}
pullJoint = new FixedMouseJoint(body.FarseerBody, pullJointPos);
pullJoint.Enabled = false;
pullJoint.MaxForce = ((type == LimbType.LeftHand || type == LimbType.RightHand) ? 400.0f : 150.0f) * body.Mass;
pullJoint = new FixedMouseJoint(body.FarseerBody, pullJointPos)
{
Enabled = false,
MaxForce = ((type == LimbType.LeftHand || type == LimbType.RightHand) ? 400.0f : 150.0f) * body.Mass
};
GameMain.World.AddJoint(pullJoint);
@@ -286,10 +329,10 @@ namespace Barotrauma
}
partial void InitProjSpecific(XElement element);
public void MoveToPos(Vector2 pos, float force, bool pullFromCenter=false)
public void MoveToPos(Vector2 pos, float force, bool pullFromCenter = false)
{
Vector2 pullPos = body.SimPosition;
if (pullJoint != null && !pullFromCenter)
if (!pullFromCenter)
{
pullPos = pullJoint.WorldAnchorA;
}
@@ -299,6 +342,11 @@ namespace Barotrauma
body.MoveToPos(pos, force, pullPos);
}
public void MirrorPullJoint()
{
pullJoint.LocalAnchorA = new Vector2(-pullJoint.LocalAnchorA.X, pullJoint.LocalAnchorA.Y);
}
public AttackResult AddDamage(Vector2 position, DamageType damageType, float amount, float bleedingAmount, bool playSound)
{
List<DamageModifier> appliedDamageModifiers = new List<DamageModifier>();

View File

@@ -145,12 +145,10 @@ namespace Barotrauma.Items.Components
if (limb == null) continue;
limb.Disabled = true;
if (limb.pullJoint == null) continue;
Vector2 position = ConvertUnits.ToSimUnits(lb.position + new Vector2(item.Rect.X, item.Rect.Y));
limb.pullJoint.Enabled = true;
limb.pullJoint.WorldAnchorB = position;
limb.PullJointEnabled = true;
limb.PullJointWorldAnchorB = position;
}
}
@@ -276,8 +274,7 @@ namespace Barotrauma.Items.Components
if (limb == null) continue;
limb.Disabled = false;
limb.pullJoint.Enabled = false;
limb.PullJointEnabled = false;
}
if (character.SelectedConstruction == this.item) character.SelectedConstruction = null;