Collider-controlled monster movement
This commit is contained in:
@@ -192,6 +192,29 @@ namespace FarseerPhysics.Factories
|
||||
return body;
|
||||
}
|
||||
|
||||
public static Body CreateCapsuleHorizontal(World world, float width, float endRadius, float density,
|
||||
object userData = null)
|
||||
{
|
||||
//Create the middle rectangle
|
||||
Vertices rectangle = PolygonTools.CreateRectangle(width / 2, endRadius);
|
||||
|
||||
List<Vertices> list = new List<Vertices>();
|
||||
list.Add(rectangle);
|
||||
|
||||
Body body = CreateCompoundPolygon(world, list, density, userData);
|
||||
body.UserData = userData;
|
||||
|
||||
//Create the two circles
|
||||
CircleShape topCircle = new CircleShape(endRadius, density);
|
||||
topCircle.Position = new Vector2(width / 2, 0);
|
||||
body.CreateFixture(topCircle);
|
||||
|
||||
CircleShape bottomCircle = new CircleShape(endRadius, density);
|
||||
bottomCircle.Position = new Vector2(-(width / 2), 0);
|
||||
body.CreateFixture(bottomCircle);
|
||||
return body;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a rounded rectangle.
|
||||
/// Note: Automatically decomposes the capsule if it contains too many vertices (controlled by Settings.MaxPolygonVertices)
|
||||
|
||||
@@ -7,52 +7,54 @@
|
||||
<sound file="Content/Characters/Crawler/idle2.ogg" state="None" range="500"/>
|
||||
|
||||
<ragdoll headposition="50" headangle="-70"
|
||||
waveamplitude="5.0" wavelength="5000"
|
||||
waveamplitude="2.0" wavelength="5000"
|
||||
swimspeed="2.0" walkspeed="2.0"
|
||||
stepsize ="15.0,20.0"
|
||||
legtorque="10"
|
||||
flip="true">
|
||||
|
||||
<collider width="45" radius="22"/>
|
||||
|
||||
<!-- head -->
|
||||
<limb id = "0" radius="22" height="45" mass = "6" type="Head" flip="true" steerforce="1.0" armorsector="0.0,180.0" armorvalue="30.0" impacttolerance="50.0">
|
||||
<limb id = "0" radius="22" height="45" type="Head" flip="true" steerforce="1.0" armorsector="0.0,180.0" armorvalue="30.0" impacttolerance="50.0">
|
||||
<sprite texture="Content/Characters/Crawler/crawler.png" sourcerect="0,0,51,121" depth="0.02" origin="0.45,0.63"/>
|
||||
</limb>
|
||||
|
||||
<!-- middle part -->
|
||||
<limb id = "1" width="36" height="40" mass = "6" flip="true" armorsector="0.0,180.0" armorvalue="20.0">
|
||||
<limb id = "1" radius="22" height="40" flip="true" armorsector="0.0,180.0" armorvalue="20.0">0
|
||||
<sprite texture="Content/Characters/Crawler/crawler.png" sourcerect="57,7,59,57" depth="0.021" origin="0.3,0.65"/>
|
||||
</limb>
|
||||
|
||||
<!-- tail -->
|
||||
<limb id = "2" width="41" height="63" mass = "6" type="Tail" flip="true" armorsector="0.0,180.0" armorvalue="20.0">
|
||||
<limb id = "2" radius="22" height="45" type="Tail" flip="true" armorsector="0.0,180.0" armorvalue="20.0">
|
||||
<sprite texture="Content/Characters/Crawler/crawler.png" sourcerect="6,141,60,95" depth="0.022" origin="0.37,0.43"/>
|
||||
</limb>
|
||||
|
||||
<limb id = "3" width="13" height="45" mass = "6" ignorecollisions="true" flip="true" impacttolerance="50.0">
|
||||
<limb id = "3" width="13" height="45" ignorecollisions="true" flip="true" impacttolerance="50.0">
|
||||
<sprite texture="Content/Characters/Crawler/crawler.png" sourcerect="65,131,36,50" depth="0.15" origin="0.4,0.5"/>
|
||||
<attack range="120" duration="0.5" damage="30" stun="0.1" bleedingdamage="3" structuredamage="50" damagetype="slash" force="20" torque="-20" targetforce="-30"/>
|
||||
</limb>
|
||||
|
||||
<limb id = "4" width="11" height="34" mass = "4" type="RightLeg" flip="true">
|
||||
<limb id = "4" width="11" height="34" type="RightLeg" flip="true">
|
||||
<sprite texture="Content/Characters/Crawler/crawler.png" sourcerect="82,83,11,34" depth="0.03" origin="0.5,0.5"/>
|
||||
</limb>
|
||||
<limb id = "5" width="5" height="40" mass = "4" type="RightFoot" flip="true" pullpos="0.0,15.0" refjoint="3" stepoffset="20.0,0.0" impacttolerance="50.0">
|
||||
<limb id = "5" width="5" height="40" type="RightFoot" flip="true" pullpos="0.0,15.0" refjoint="3" stepoffset="20.0,0.0" impacttolerance="50.0">
|
||||
<sprite texture="Content/Characters/Crawler/crawler.png" sourcerect="59,78,19,43" depth="0.03" origin="0.5,0.5"/>
|
||||
<sound file ="Content/Sounds/stepMetal.ogg"/>
|
||||
</limb>
|
||||
|
||||
<limb id = "6" width="13" height="35" mass = "4" type="LeftLeg" flip="true">
|
||||
<limb id = "6" width="13" height="35" type="LeftLeg" flip="true">
|
||||
<sprite texture="Content/Characters/Crawler/crawler.png" sourcerect="82,83,11,34" depth="0.03" origin="0.5,0.5"/>
|
||||
</limb>
|
||||
<limb id = "7" width="5" height="40" mass = "4" type="LeftFoot" flip="true" pullpos="0.0,15.0" refjoint="5" stepoffset="20.0,0.0" impacttolerance="50.0">
|
||||
<limb id = "7" width="5" height="40" type="LeftFoot" flip="true" pullpos="0.0,15.0" refjoint="5" stepoffset="20.0,0.0" impacttolerance="50.0">
|
||||
<sprite texture="Content/Characters/Crawler/crawler.png" sourcerect="59,78,19,43" depth="0.03" origin="0.5,0.5"/>
|
||||
<sound file ="Content/Sounds/stepMetal.ogg"/>
|
||||
</limb>
|
||||
|
||||
<limb id = "8" width="13" height="35" mass = "4" type="RightLeg" flip="true">
|
||||
<limb id = "8" width="13" height="35" type="RightLeg" flip="true">
|
||||
<sprite texture="Content/Characters/Crawler/crawler.png" sourcerect="82,83,11,34" depth="0.03" origin="0.5,0.5"/>
|
||||
</limb>
|
||||
<limb id = "9" width="5" height="40" mass = "4" type="RightFoot" flip="true" pullpos="0.0,15.0" refjoint="7" stepoffset="20.0,0.0" impacttolerance="50.0">
|
||||
<limb id = "9" width="5" height="40" type="RightFoot" flip="true" pullpos="0.0,15.0" refjoint="7" stepoffset="20.0,0.0" impacttolerance="50.0">
|
||||
<sprite texture="Content/Characters/Crawler/crawler.png" sourcerect="59,78,19,43" depth="0.03" origin="0.5,0.5"/>
|
||||
<sound file ="Content/Sounds/stepMetal.ogg"/>
|
||||
</limb>
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
footrotation ="180.0"
|
||||
flip="true">
|
||||
|
||||
<collider radius="70"/>
|
||||
|
||||
<!-- head -->
|
||||
<limb id = "0" radius="30" height="86" mass = "6" type="Head" flip="true" steerforce="1.0" armorsector="0.0,180.0" armor="10.0">
|
||||
<sprite texture="Content/Characters/Mantis/mantis.png" sourcerect="0,0,101,168" depth="0.02" origin="0.4,0.53"/>
|
||||
|
||||
@@ -63,14 +63,9 @@ namespace Barotrauma
|
||||
|
||||
if (stunTimer>0.0f)
|
||||
{
|
||||
//UpdateStruggling(deltaTime);
|
||||
stunTimer -= deltaTime;
|
||||
return;
|
||||
}
|
||||
else if (SimplePhysicsEnabled)
|
||||
{
|
||||
UpdateSimpleAnim();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inWater)// || RefLimb.inWater)
|
||||
@@ -128,7 +123,7 @@ namespace Barotrauma
|
||||
if (flipTimer>1.0f || character.IsNetworkPlayer)
|
||||
{
|
||||
Flip();
|
||||
if (mirror) Mirror();
|
||||
if (mirror || !inWater) Mirror();
|
||||
flipTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
@@ -137,12 +132,26 @@ namespace Barotrauma
|
||||
void UpdateSineAnim(float deltaTime)
|
||||
{
|
||||
movement = TargetMovement*swimSpeed;
|
||||
|
||||
Limb torso = GetLimb(LimbType.Torso);
|
||||
Limb head = GetLimb(LimbType.Head);
|
||||
|
||||
Limb mainLimb = torso == null ? head : torso;
|
||||
|
||||
mainLimb.pullJoint.Enabled = true;
|
||||
mainLimb.pullJoint.WorldAnchorB = collider.SimPosition;
|
||||
|
||||
if (movement.LengthSquared() < 0.00001f) return;
|
||||
|
||||
if (!inWater) movement.Y = Math.Min(0.0f, movement.Y);
|
||||
|
||||
float movementAngle = MathUtils.VectorToAngle(movement) - MathHelper.PiOver2;
|
||||
|
||||
float angle = (rotateTowardsMovement) ?
|
||||
mainLimb.body.Rotation + MathUtils.GetShortestAngle(mainLimb.body.Rotation, movementAngle) :
|
||||
HeadAngle * Dir;
|
||||
|
||||
collider.SmoothRotate(angle, 25.0f);
|
||||
mainLimb.body.SmoothRotate(angle, 25.0f);
|
||||
|
||||
Limb tail = GetLimb(LimbType.Tail);
|
||||
if (tail != null && waveAmplitude > 0.0f)
|
||||
{
|
||||
@@ -151,102 +160,30 @@ namespace Barotrauma
|
||||
float waveRotation = (float)Math.Sin(walkPos / waveLength);
|
||||
|
||||
tail.body.ApplyTorque(waveRotation * tail.Mass * 100.0f * waveAmplitude);
|
||||
|
||||
//limbs[tailIndex].body.ApplyTorque((Math.Sign(angle) + Math.Max(Math.Min(angle * 10.0f, 10.0f), -10.0f)) * limbs[tailIndex].body.Mass);
|
||||
//limbs[tailIndex].body.ApplyTorque(-limbs[tailIndex].body.AngularVelocity * 0.5f * limbs[tailIndex].body.Mass);
|
||||
}
|
||||
|
||||
Vector2 steerForce = Vector2.Zero;
|
||||
|
||||
Limb head = GetLimb(LimbType.Head);
|
||||
if (head == null) head = GetLimb(LimbType.Torso);
|
||||
|
||||
if (head != null)
|
||||
{
|
||||
float angle = (rotateTowardsMovement) ?
|
||||
head.body.Rotation+ MathUtils.GetShortestAngle(head.body.Rotation, movementAngle) :
|
||||
HeadAngle*Dir;
|
||||
|
||||
|
||||
head.body.SmoothRotate(angle, 25.0f);
|
||||
//rotate head towards the angle of movement
|
||||
//float torque = (Math.Sign(angle)*10.0f + MathHelper.Clamp(angle * 10.0f, -10.0f, 10.0f));
|
||||
//angular drag
|
||||
//torque -= head.body.AngularVelocity * 0.5f;
|
||||
//head.body.ApplyTorque(torque * head.body.Mass);
|
||||
|
||||
|
||||
//the movement vector if going to the direction of the head
|
||||
//Vector2 headMovement = new Vector2(
|
||||
// (float)Math.Cos(head.body.Rotation - MathHelper.PiOver2),
|
||||
// (float)Math.Sin(head.body.Rotation - MathHelper.PiOver2));
|
||||
//headMovement *= movement.Length();
|
||||
|
||||
//the movement angle is between direction of the head and the direction
|
||||
//where the Character is actually trying to go
|
||||
|
||||
//current * (float)alpha + previous * (1.0f - (float)alpha);
|
||||
|
||||
|
||||
steerForce = (movement+correctionMovement) * 50.0f - head.LinearVelocity * 30.0f;
|
||||
// force += (headMovement - movement) * Math.Min(head.LinearVelocity.Length()/movement.Length(), 1.0f);
|
||||
|
||||
if (!inWater) steerForce.Y = 0.0f;
|
||||
}
|
||||
|
||||
for (int i = 0; i < Limbs.Count(); i++)
|
||||
{
|
||||
if (steerForce != Vector2.Zero)
|
||||
{
|
||||
Vector2 pullPos = Limbs[i].pullJoint == null ? Limbs[i].SimPosition : Limbs[i].pullJoint.WorldAnchorA;
|
||||
Limbs[i].body.ApplyForce(steerForce * Limbs[i].SteerForce * Limbs[i].Mass, pullPos);
|
||||
Vector2 pullPos = Limbs[i].pullJoint == null ? Limbs[i].SimPosition : Limbs[i].pullJoint.WorldAnchorA;
|
||||
Limbs[i].body.ApplyForce(movement * Limbs[i].SteerForce * Limbs[i].Mass, pullPos);
|
||||
|
||||
}
|
||||
|
||||
if (Limbs[i].type != LimbType.Torso) continue;
|
||||
|
||||
|
||||
float dist = (Limbs[0].SimPosition - Limbs[i].SimPosition).Length();
|
||||
if (Limbs[i] == mainLimb) continue;
|
||||
|
||||
Vector2 limbPos = Limbs[0].SimPosition - Vector2.Normalize(movement) * dist;
|
||||
float dist = (mainLimb.SimPosition - Limbs[i].SimPosition).Length();
|
||||
|
||||
Vector2 limbPos = mainLimb.SimPosition - Vector2.Normalize(movement) * dist;
|
||||
|
||||
Limbs[i].body.ApplyForce(((limbPos - Limbs[i].SimPosition) * 3.0f - Limbs[i].LinearVelocity * 3.0f) * Limbs[i].Mass);
|
||||
}
|
||||
|
||||
if (!inWater)
|
||||
{
|
||||
UpdateWalkAnim(deltaTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
floorY = Limbs[0].SimPosition.Y;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateSimpleAnim()
|
||||
{
|
||||
//todo: reimplement
|
||||
|
||||
//movement = MathUtils.SmoothStep(movement, TargetMovement*swimSpeed, 1.0f);
|
||||
//if (movement == Vector2.Zero) return;
|
||||
|
||||
//float movementAngle = MathUtils.VectorToAngle(movement) - MathHelper.PiOver2;
|
||||
|
||||
//RefLimb.body.SmoothRotate(
|
||||
// (rotateTowardsMovement) ?
|
||||
// RefLimb.body.Rotation + MathUtils.GetShortestAngle(RefLimb.body.Rotation, movementAngle) :
|
||||
// HeadAngle*Dir);
|
||||
|
||||
//collider.LinearVelocity = movement;
|
||||
|
||||
////RefLimb.body.SmoothRotate(0.0f);
|
||||
|
||||
//foreach (Limb l in Limbs)
|
||||
//{
|
||||
// if (l == RefLimb) continue;
|
||||
// l.body.SetTransform(RefLimb.SimPosition, RefLimb.Rotation);
|
||||
//}
|
||||
collider.LinearVelocity = Vector2.Lerp(collider.LinearVelocity, movement, 0.5f);
|
||||
|
||||
floorY = Limbs[0].SimPosition.Y;
|
||||
}
|
||||
|
||||
|
||||
void UpdateWalkAnim(float deltaTime)
|
||||
{
|
||||
movement = MathUtils.SmoothStep(movement, TargetMovement * walkSpeed, 0.2f);
|
||||
@@ -254,104 +191,38 @@ namespace Barotrauma
|
||||
|
||||
IgnorePlatforms = (TargetMovement.Y < -Math.Abs(TargetMovement.X));
|
||||
|
||||
Limb colliderLimb;
|
||||
float colliderHeight;
|
||||
Limb mainLimb;
|
||||
float mainLimbHeight, mainLimbAngle;
|
||||
|
||||
Limb torso = GetLimb(LimbType.Torso);
|
||||
Limb head = GetLimb(LimbType.Head);
|
||||
|
||||
if (torso != null)
|
||||
{
|
||||
colliderLimb = torso;
|
||||
colliderHeight = TorsoPosition;
|
||||
|
||||
colliderLimb.body.SmoothRotate(TorsoAngle * Dir, 10.0f);
|
||||
mainLimb = torso;
|
||||
mainLimbHeight = TorsoPosition;
|
||||
mainLimbAngle = torsoAngle;
|
||||
}
|
||||
else
|
||||
{
|
||||
colliderLimb = head;
|
||||
colliderHeight = HeadPosition;
|
||||
|
||||
if (onGround) colliderLimb.body.SmoothRotate(HeadAngle * Dir, 100.0f);
|
||||
mainLimb = head;
|
||||
mainLimbHeight = HeadPosition;
|
||||
mainLimbAngle = headAngle;
|
||||
}
|
||||
|
||||
//collider.SmoothRotate(TorsoAngle * Dir, 10.0f);
|
||||
mainLimb.body.SmoothRotate(mainLimbAngle * Dir, 50.0f);
|
||||
|
||||
Vector2 colliderPos = colliderLimb.SimPosition;
|
||||
collider.LinearVelocity = new Vector2(
|
||||
movement.X,
|
||||
collider.LinearVelocity.Y > 0.0f ? collider.LinearVelocity.Y * 0.5f : collider.LinearVelocity.Y);
|
||||
|
||||
Vector2 rayStart = colliderPos;
|
||||
Vector2 rayEnd = rayStart - new Vector2(0.0f, colliderHeight);
|
||||
if (stairs != null) rayEnd.Y -= 0.5f;
|
||||
mainLimb.MoveToPos(GetColliderBottom() + Vector2.UnitY * mainLimbHeight, 10.0f);
|
||||
|
||||
mainLimb.pullJoint.Enabled = true;
|
||||
mainLimb.pullJoint.WorldAnchorB = GetColliderBottom() + Vector2.UnitY * mainLimbHeight;
|
||||
|
||||
//do a raytrace straight down from the torso to figure
|
||||
//out whether the ragdoll is standing on ground
|
||||
float closestFraction = 1;
|
||||
//Structure closestStructure = null;
|
||||
|
||||
GameMain.World.RayCast((fixture, point, normal, fraction) =>
|
||||
{
|
||||
switch (fixture.CollisionCategories)
|
||||
{
|
||||
case Physics.CollisionStairs:
|
||||
if (inWater && TargetMovement.Y < 0.5f) return -1;
|
||||
Structure structure = fixture.Body.UserData as Structure;
|
||||
if (stairs == null && structure != null)
|
||||
{
|
||||
//TODO: fix
|
||||
//if (LowestLimb.SimPosition.Y < structure.SimPosition.Y)
|
||||
//{
|
||||
// return -1;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// stairs = structure;
|
||||
//}
|
||||
}
|
||||
break;
|
||||
case Physics.CollisionPlatform:
|
||||
Structure platform = fixture.Body.UserData as Structure;
|
||||
//TODO: fix
|
||||
//if (IgnorePlatforms || LowestLimb.Position.Y < platform.Rect.Y) return -1;
|
||||
break;
|
||||
case Physics.CollisionWall:
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
onGround = true;
|
||||
if (fraction < closestFraction)
|
||||
{
|
||||
closestFraction = fraction;
|
||||
}
|
||||
onFloorTimer = 0.05f;
|
||||
return closestFraction;
|
||||
} , rayStart, rayEnd);
|
||||
|
||||
//the ragdoll "stays on ground" for 50 millisecs after separation
|
||||
if (onFloorTimer <= 0.0f)
|
||||
{
|
||||
onGround = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
onFloorTimer -= deltaTime;
|
||||
}
|
||||
|
||||
if (!onGround) return;
|
||||
|
||||
if (closestFraction == 1) //raycast didn't hit anything
|
||||
floorY = (currentHull == null) ? -1000.0f : ConvertUnits.ToSimUnits(currentHull.Rect.Y - currentHull.Rect.Height);
|
||||
else
|
||||
floorY = rayStart.Y + (rayEnd.Y - rayStart.Y) * closestFraction;
|
||||
|
||||
|
||||
if (Math.Abs(colliderPos.Y - floorY) < colliderHeight * 1.2f)
|
||||
{
|
||||
colliderLimb.MoveToPos(new Vector2(colliderPos.X + movement.X * 0.2f, floorY + colliderHeight), 5.0f);
|
||||
}
|
||||
|
||||
float walkCycleSpeed = head.LinearVelocity.X * 0.05f;
|
||||
|
||||
walkPos -= walkCycleSpeed;
|
||||
walkPos -= mainLimb.LinearVelocity.X * 0.05f;
|
||||
|
||||
Vector2 transformedStepSize = new Vector2(
|
||||
(float)Math.Cos(walkPos) * stepSize.X * 3.0f,
|
||||
@@ -363,7 +234,7 @@ namespace Barotrauma
|
||||
{
|
||||
case LimbType.LeftFoot:
|
||||
case LimbType.RightFoot:
|
||||
Vector2 footPos = new Vector2(limb.SimPosition.X, colliderPos.Y - colliderHeight);
|
||||
Vector2 footPos = new Vector2(limb.SimPosition.X, mainLimb.SimPosition.Y - mainLimbHeight);
|
||||
|
||||
if (limb.RefJointIndex>-1)
|
||||
{
|
||||
@@ -382,18 +253,18 @@ namespace Barotrauma
|
||||
}
|
||||
else if (limb.type == LimbType.RightFoot)
|
||||
{
|
||||
limb.MoveToPos(footPos +new Vector2(
|
||||
limb.MoveToPos(footPos + new Vector2(
|
||||
-transformedStepSize.X + movement.X * 0.1f,
|
||||
(-transformedStepSize.Y > 0.0f) ? -transformedStepSize.Y : 0.0f),
|
||||
8.0f);
|
||||
}
|
||||
|
||||
if (footRotation!=null) limb.body.SmoothRotate((float)footRotation*Dir, 50.0f);
|
||||
if (footRotation != null) limb.body.SmoothRotate((float)footRotation * Dir, 50.0f);
|
||||
|
||||
break;
|
||||
case LimbType.LeftLeg:
|
||||
case LimbType.RightLeg:
|
||||
if (legTorque!=0.0f) limb.body.ApplyTorque(limb.Mass*legTorque*Dir);
|
||||
if (legTorque != 0.0f) limb.body.ApplyTorque(limb.Mass * legTorque * Dir);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +76,18 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
//re-enable collider
|
||||
if (!collider.FarseerBody.Enabled)
|
||||
{
|
||||
var lowestLimb = FindLowestLimb();
|
||||
|
||||
collider.SetTransform(new Vector2(
|
||||
collider.SimPosition.X,
|
||||
Math.Max(lowestLimb.SimPosition.Y + (collider.radius + collider.height / 2), collider.SimPosition.Y)),
|
||||
0.0f);
|
||||
|
||||
collider.FarseerBody.Enabled = true;
|
||||
}
|
||||
|
||||
//stun (= disable the animations) if the ragdoll receives a large enough impact
|
||||
if (strongestImpact > 0.0f)
|
||||
@@ -85,157 +97,6 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
//if (inWater) stairs = null;
|
||||
|
||||
//if (onFloorTimer <= 0.0f && !SimplePhysicsEnabled)
|
||||
//{
|
||||
// Vector2 rayStart = colliderPos; // at the bottom of the player sprite
|
||||
// Vector2 rayEnd = rayStart - new Vector2(0.0f, TorsoPosition);
|
||||
// if (stairs != null) rayEnd.Y -= 0.5f;
|
||||
// //do a raytrace straight down from the torso to figure
|
||||
// //out whether the ragdoll is standing on ground
|
||||
// float closestFraction = 1;
|
||||
// Structure closestStructure = null;
|
||||
// GameMain.World.RayCast((fixture, point, normal, fraction) =>
|
||||
// {
|
||||
// switch (fixture.CollisionCategories)
|
||||
// {
|
||||
// case Physics.CollisionStairs:
|
||||
// if (inWater && TargetMovement.Y < 0.5f) return -1;
|
||||
// Structure structure = fixture.Body.UserData as Structure;
|
||||
// if (stairs == null && structure != null)
|
||||
// {
|
||||
// if (LowestLimb.SimPosition.Y < structure.SimPosition.Y)
|
||||
// {
|
||||
// return -1;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// stairs = structure;
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
// case Physics.CollisionPlatform:
|
||||
// Structure platform = fixture.Body.UserData as Structure;
|
||||
// if (IgnorePlatforms || LowestLimb.Position.Y < platform.Rect.Y) return -1;
|
||||
// break;
|
||||
// case Physics.CollisionWall:
|
||||
// break;
|
||||
// default:
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// onGround = true;
|
||||
// if (fraction < closestFraction)
|
||||
// {
|
||||
// closestFraction = fraction;
|
||||
|
||||
// Structure structure = fixture.Body.UserData as Structure;
|
||||
// if (structure != null) closestStructure = structure;
|
||||
// }
|
||||
// onFloorTimer = 0.05f;
|
||||
// return closestFraction;
|
||||
// }
|
||||
// , rayStart, rayEnd);
|
||||
|
||||
// if (closestStructure != null && closestStructure.StairDirection != Direction.None)
|
||||
// {
|
||||
// stairs = closestStructure;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// stairs = null;
|
||||
// }
|
||||
|
||||
// if (closestFraction == 1) //raycast didn't hit anything
|
||||
// {
|
||||
// floorY = (currentHull == null) ? -1000.0f : ConvertUnits.ToSimUnits(currentHull.Rect.Y - currentHull.Rect.Height);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// floorY = rayStart.Y + (rayEnd.Y - rayStart.Y) * closestFraction;
|
||||
// }
|
||||
//}
|
||||
bool onStairs = stairs != null;
|
||||
stairs = null;
|
||||
|
||||
var contacts = collider.FarseerBody.ContactList;
|
||||
while (collider.FarseerBody.Enabled && contacts != null && contacts.Contact != null)
|
||||
{
|
||||
if (contacts.Contact.Enabled && contacts.Contact.IsTouching)
|
||||
{
|
||||
Vector2 normal;
|
||||
FarseerPhysics.Common.FixedArray2<Vector2> points;
|
||||
|
||||
contacts.Contact.GetWorldManifold(out normal, out points);
|
||||
|
||||
switch (contacts.Contact.FixtureA.CollisionCategories)
|
||||
{
|
||||
case Physics.CollisionStairs:
|
||||
Structure structure = contacts.Contact.FixtureA.Body.UserData as Structure;
|
||||
if (structure != null && onStairs)
|
||||
{
|
||||
stairs = structure;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// case Physics.CollisionPlatform:
|
||||
// Structure platform = contacts.Contact.FixtureA.Body.UserData as Structure;
|
||||
// if (IgnorePlatforms || colliderBottom.Y < ConvertUnits.ToSimUnits(platform.Rect.Y - 15))
|
||||
// {
|
||||
// contacts = contacts.Next;
|
||||
// continue;
|
||||
// }
|
||||
// break;
|
||||
// case Physics.CollisionWall:
|
||||
// break;
|
||||
// default:
|
||||
// contacts = contacts.Next;
|
||||
// continue;
|
||||
//}
|
||||
|
||||
|
||||
if (points[0].Y < collider.SimPosition.Y)
|
||||
{
|
||||
|
||||
floorY = Math.Max(floorY, points[0].Y);
|
||||
|
||||
onGround = true;
|
||||
onFloorTimer = 0.1f;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
contacts = contacts.Next;
|
||||
|
||||
}
|
||||
|
||||
//the ragdoll "stays on ground" for 50 millisecs after separation
|
||||
if (onFloorTimer <= 0.0f)
|
||||
{
|
||||
onGround = false;
|
||||
//if (GetLimb(LimbType.Torso).inWater) inWater = true;
|
||||
//TODO: joku järkevämpi systeemi
|
||||
//if (!inWater && lastTimeOnFloor + 200 < gameTime.TotalGameTime.Milliseconds)
|
||||
// stunTimer = Math.Max(stunTimer, (float)gameTime.TotalGameTime.TotalMilliseconds + 100.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
onFloorTimer -= deltaTime;
|
||||
}
|
||||
|
||||
|
||||
//re-enable collider (unless swimming)
|
||||
if (!collider.FarseerBody.Enabled)
|
||||
{
|
||||
var lowestLimb = FindLowestLimb();
|
||||
collider.SetTransform(new Vector2(
|
||||
collider.SimPosition.X,
|
||||
Math.Max(lowestLimb.SimPosition.Y + (collider.radius + collider.height / 2), collider.SimPosition.Y)),
|
||||
0.0f);
|
||||
collider.FarseerBody.Enabled = true;
|
||||
}
|
||||
|
||||
if (swimming)
|
||||
{
|
||||
|
||||
@@ -112,24 +112,27 @@ namespace Barotrauma
|
||||
get { return simplePhysicsEnabled; }
|
||||
set
|
||||
{
|
||||
//TODO: reimplement
|
||||
|
||||
return;
|
||||
//if (value == simplePhysicsEnabled) return;
|
||||
if (value == simplePhysicsEnabled) return;
|
||||
|
||||
//simplePhysicsEnabled = value;
|
||||
simplePhysicsEnabled = value;
|
||||
|
||||
//foreach (Limb limb in Limbs)
|
||||
//{
|
||||
// limb.body.Enabled = !simplePhysicsEnabled;
|
||||
//}
|
||||
foreach (Limb limb in Limbs)
|
||||
{
|
||||
limb.body.Enabled = !simplePhysicsEnabled;
|
||||
}
|
||||
|
||||
//foreach (RevoluteJoint joint in limbJoints)
|
||||
//{
|
||||
// joint.Enabled = !simplePhysicsEnabled;
|
||||
//}
|
||||
foreach (RevoluteJoint joint in limbJoints)
|
||||
{
|
||||
joint.Enabled = !simplePhysicsEnabled;
|
||||
}
|
||||
|
||||
//refLimb.body.Enabled = true;
|
||||
if (!simplePhysicsEnabled)
|
||||
{
|
||||
foreach (Limb limb in Limbs)
|
||||
{
|
||||
limb.body.SetTransform(collider.SimPosition, collider.Rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,7 +282,8 @@ namespace Barotrauma
|
||||
if (collider == null)
|
||||
{
|
||||
DebugConsole.ThrowError("No collider configured for ''"+character.Name+"''!");
|
||||
collider = new PhysicsBody(0.0f, 0.0f, 0.1f, 5.0f);
|
||||
collider = new PhysicsBody(0.0f, 0.0f, 0.5f, 5.0f);
|
||||
collider.BodyType = BodyType.Dynamic;
|
||||
}
|
||||
|
||||
collider.CollisionCategories = Physics.CollisionCharacter;
|
||||
@@ -384,7 +388,10 @@ namespace Barotrauma
|
||||
|
||||
//the collision is ignored if the lowest limb is under the platform
|
||||
//if (lowestLimb==null || lowestLimb.Position.Y < structure.Rect.Y) return false;
|
||||
|
||||
if (colliderBottom.Y < ConvertUnits.ToSimUnits(structure.Rect.Y - 5)) return false;
|
||||
if (f1.Body.Position.Y < ConvertUnits.ToSimUnits(structure.Rect.Y - 5)) return false;
|
||||
|
||||
}
|
||||
else if (structure.StairDirection != Direction.None)
|
||||
{
|
||||
@@ -397,8 +404,8 @@ namespace Barotrauma
|
||||
if (colliderBottom.Y < stairBottomPos && targetMovement.Y < 0.5f) return false;
|
||||
|
||||
//2. bottom of the collider is at the top of the stairs and the character isn't trying to move downwards
|
||||
if (targetMovement.Y >= 0.0f && colliderBottom.Y >= ConvertUnits.ToSimUnits(structure.Rect.Y - Submarine.GridSize.Y*5)) return false;
|
||||
|
||||
if (targetMovement.Y >= 0.0f && colliderBottom.Y >= ConvertUnits.ToSimUnits(structure.Rect.Y - Submarine.GridSize.Y * 5)) return false;
|
||||
|
||||
//3. collided with the stairs from below
|
||||
if (contact.Manifold.LocalNormal.Y < 0.0f) return false;
|
||||
|
||||
@@ -820,7 +827,73 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
limb.Update(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool onStairs = stairs != null;
|
||||
stairs = null;
|
||||
|
||||
var contacts = collider.FarseerBody.ContactList;
|
||||
while (collider.FarseerBody.Enabled && contacts != null && contacts.Contact != null)
|
||||
{
|
||||
if (contacts.Contact.Enabled && contacts.Contact.IsTouching)
|
||||
{
|
||||
Vector2 normal;
|
||||
FarseerPhysics.Common.FixedArray2<Vector2> points;
|
||||
|
||||
contacts.Contact.GetWorldManifold(out normal, out points);
|
||||
|
||||
switch (contacts.Contact.FixtureA.CollisionCategories)
|
||||
{
|
||||
case Physics.CollisionStairs:
|
||||
Structure structure = contacts.Contact.FixtureA.Body.UserData as Structure;
|
||||
if (structure != null && onStairs)
|
||||
{
|
||||
stairs = structure;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// case Physics.CollisionPlatform:
|
||||
// Structure platform = contacts.Contact.FixtureA.Body.UserData as Structure;
|
||||
// if (IgnorePlatforms || colliderBottom.Y < ConvertUnits.ToSimUnits(platform.Rect.Y - 15))
|
||||
// {
|
||||
// contacts = contacts.Next;
|
||||
// continue;
|
||||
// }
|
||||
// break;
|
||||
// case Physics.CollisionWall:
|
||||
// break;
|
||||
// default:
|
||||
// contacts = contacts.Next;
|
||||
// continue;
|
||||
//}
|
||||
|
||||
|
||||
if (points[0].Y < collider.SimPosition.Y)
|
||||
{
|
||||
floorY = Math.Max(floorY, points[0].Y);
|
||||
|
||||
onGround = true;
|
||||
onFloorTimer = 0.1f;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
contacts = contacts.Next;
|
||||
}
|
||||
|
||||
//the ragdoll "stays on ground" for 50 millisecs after separation
|
||||
if (onFloorTimer <= 0.0f)
|
||||
{
|
||||
onGround = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
onFloorTimer -= deltaTime;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private float GetFloorY()
|
||||
|
||||
@@ -242,7 +242,6 @@ namespace Barotrauma
|
||||
body.Restitution = 0.05f;
|
||||
|
||||
body.BodyType = BodyType.Dynamic;
|
||||
//body.AngularDamping = Limb.LimbAngularDamping;
|
||||
|
||||
body.UserData = this;
|
||||
|
||||
@@ -260,6 +259,11 @@ namespace Barotrauma
|
||||
body = BodyFactory.CreateRectangle(GameMain.World, width, height, density);
|
||||
bodyShape = Shape.Rectangle;
|
||||
}
|
||||
else if (radius != 0.0f && width != 0.0f)
|
||||
{
|
||||
body = BodyFactory.CreateCapsuleHorizontal(GameMain.World, width, radius, density);
|
||||
bodyShape = Shape.Capsule;
|
||||
}
|
||||
else if (radius != 0.0f && height != 0.0f)
|
||||
{
|
||||
body = BodyFactory.CreateCapsule(GameMain.World, height, radius, density);
|
||||
@@ -436,7 +440,7 @@ namespace Barotrauma
|
||||
case PhysicsBody.Shape.Capsule:
|
||||
bodyShapeTexture = GUI.CreateCapsule(
|
||||
(int)ConvertUnits.ToDisplayUnits(radius),
|
||||
(int)ConvertUnits.ToDisplayUnits(height));
|
||||
(int)ConvertUnits.ToDisplayUnits(Math.Max(height,width)));
|
||||
break;
|
||||
case PhysicsBody.Shape.Circle:
|
||||
bodyShapeTexture = GUI.CreateCircle((int)ConvertUnits.ToDisplayUnits(radius));
|
||||
@@ -444,12 +448,18 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
float rot = -DrawRotation;
|
||||
if (bodyShape == PhysicsBody.Shape.Capsule && width > height)
|
||||
{
|
||||
rot -= MathHelper.PiOver2;
|
||||
}
|
||||
|
||||
spriteBatch.Draw(
|
||||
bodyShapeTexture,
|
||||
new Vector2(DrawPosition.X, -DrawPosition.Y),
|
||||
null,
|
||||
color,
|
||||
-DrawRotation,
|
||||
rot,
|
||||
new Vector2(bodyShapeTexture.Width / 2, bodyShapeTexture.Height / 2),
|
||||
1.0f, SpriteEffects.None, 0.0f);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user