Backported animcontroller-overhaul

This commit is contained in:
Regalis
2016-10-22 15:18:16 +03:00
parent bb9b2c6eb7
commit 641e579e92
39 changed files with 1169 additions and 995 deletions
@@ -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)
@@ -5,6 +5,8 @@
<ragdoll waveamplitude="150.0" wavelength="10000" swimspeed="4.0" scale="1.5" canentersubmarine="false">
<collider radius="100"/>
<!-- body -->
<limb id = "0" radius="100" height="470" type="Torso" steerforce="1.0" pullpos="0,250">
<sprite texture="Content/Characters/Charybdis/charybdis.png" sourcerect="160,0,242,688" depth="0.015" origin="0.5,0.5"/>
@@ -5,8 +5,10 @@
<sound file="Content/Characters/Scorpion/scorpionidle1.ogg" state="None" />
<sound file="Content/Characters/Scorpion/scorpionidle2.ogg" state="None" />
<ragdoll waveamplitude="50.0" wavelength="2500" swimspeed="5.0" walkspeed="3.5">
<ragdoll waveamplitude="50.0" wavelength="2500" swimspeed="5.0" walkspeed="3.5" canentersubmarine="false">
<collider radius ="50"/>
<!-- head -->
<limb id = "0" radius="50" height="270" type="Head" steerforce="1.0" impacttolerance="50.0">
<sprite texture="Content/Characters/Coelanth/coelanth.png" sourcerect="267,171,162,392" depth="0.02" origin ="0.5,0.5"/>
@@ -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>
@@ -7,6 +7,8 @@
<ragdoll waveamplitude="100.0" wavelength="1000" speed="1.5" scale ="2.0" flip="false" canentersubmarine="false">
<collider radius="300"/>
<!-- head -->
<limb id = "0" radius="300" type="Head" steerforce="3.0">
<sprite texture="Content/Characters/Endworm/endworm.png" sourcerect="0,478,720,546" depth="0.05"/>
@@ -18,27 +20,27 @@
</limb>
<!-- body -->
<limb id = "2" radius="300" type="Torso">
<limb id = "2" radius="300" type="Torso" steerforce="0.0">
<sprite texture="Content/Characters/Endworm/endworm.png" sourcerect="0,0,702,448" depth="0.02" origin="0.5,0.5"/>
</limb>
<limb id = "3" radius="300" type="Torso">
<limb id = "3" radius="300" type="Torso" steerforce="0.0">
<sprite texture="Content/Characters/Endworm/endworm.png" sourcerect="0,0,702,448" depth="0.03" origin="0.5,0.5"/>
</limb>
<limb id = "4" radius="300" type="Tail">
<limb id = "4" radius="300" type="Tail" steerforce="0.0">
<sprite texture="Content/Characters/Endworm/endworm.png" sourcerect="0,0,702,448" depth="0.04" origin="0.5,0.5"/>
</limb>
<limb id = "5" radius="300" type="Tail">
<limb id = "5" radius="300" type="Tail" steerforce="0.0">
<sprite texture="Content/Characters/Endworm/endworm.png" sourcerect="0,0,702,448" depth="0.05" origin="0.5,0.5"/>
</limb>
<limb id = "6" radius="300" type="Tail">
<limb id = "6" radius="300" type="Tail" steerforce="0.0">
<sprite texture="Content/Characters/Endworm/endworm.png" sourcerect="0,0,702,448" depth="0.06" origin="0.5,0.5"/>
</limb>
<limb id = "7" radius="150" type="Tail">
<limb id = "7" radius="150" type="Tail" steerforce="0.0">
<sprite texture="Content/Characters/Endworm/endworm.png" sourcerect="704,0,320,400" depth="0.07" origin="0.5,0.5"/>
</limb>
@@ -6,10 +6,11 @@
<ragdoll waveamplitude="50.0" wavelength="500" swimspeed="3.0" walkspeed="0.3" flip="false" canentersubmarine="false">
<collider radius="50"/>
<!-- head -->
<limb id = "0" radius="65" type="Head" steerforce="3.0" impacttolerance="100">
<sprite texture="Content/Characters/Fractalguardian/fractalguardian.png" sourcerect="0,0,129,128" depth="0.04"/>
<attack type="Hit" range="120" duration="0.2" damage="50" stun="2" force="20" damagetype="blunt" targetforce="80"/>
<attack type="Hit" range="120" duration="0.2" damage="50" stun="2" force="10" damagetype="blunt" targetforce="80"/>
</limb>
<!-- body -->
@@ -6,10 +6,12 @@
<ragdoll waveamplitude="0.0" swimspeed="1.0" walkspeed="0.3" flip="false" canentersubmarine="false" rotatetowardsmovement="false">
<collider radius="80" height="30"/>
<!-- head -->
<limb id = "0" radius="80" height="30" type="Head" steerforce="3.0" impacttolerance="100">
<sprite texture="Content/Characters/Fractalguardian/fractalguardian.png" sourcerect="299,0,171,208" depth="0.05"/>
<attack type="Hit" range="120" duration="0.2" damage="50" stun="2" force="20" damagetype="blunt" targetforce="100"/>
<attack type="Hit" range="120" duration="0.2" damage="50" stun="2" force="10" damagetype="blunt" targetforce="100"/>
</limb>
@@ -8,7 +8,11 @@
walkanimspeed="4.58"
movementlerp="0.4"
legtorque="15.0"
thightorque="-5.0">
thightorque="-5.0"
walkspeed="1.5"
swimspeed="2.0">
<collider height="100" radius="15"/>
<!-- head -->
<limb id = "0" radius="13" mass = "6" type="Head" attackpriority="2" impacttolerance="5.0">
+4 -2
View File
@@ -11,8 +11,10 @@
movementlerp="0.4"
legtorque="15.0"
thightorque="-5.0"
walkspeed="2.0"
swimspeed="2.0">
walkspeed="1.2"
swimspeed="2.5">
<collider height="100" radius="15"/>
<!-- head -->
<limb id = "0" radius="13" mass = "6" type="Head" attackpriority="2" impacttolerance="5.0">
@@ -15,6 +15,8 @@
footrotation ="180.0"
flip="true">
<collider radius="60"/>
<!-- 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"/>
@@ -8,10 +8,12 @@
<ragdoll waveamplitude="0.0" swimspeed="1.0" walkspeed="0.3" mirror="true" rotatetowardsmovement="false" headangle="-90">
<collider radius ="230"/>
<!-- head -->
<limb id = "0" radius="230" height="500" type="Head" steerforce="1.0" flip="true" armorsector="0.0,180.0" armorvalue="100.0" impacttolerance="100">
<sprite texture="Content/Characters/Moloch/moloch.png" sourcerect="0,0,628,1024" depth="0.02" origin ="0.4,0.5"/>
<attack range="700" duration="0.2" damage="200" stun="5" force="20" damagetype="blunt" targetforce="100"/>
<attack range="700" duration="0.05" damage="200" stun="5" force="20" damagetype="blunt" targetforce="100"/>
</limb>
<limb id = "1" width="50" height="440" flip="true">
@@ -5,8 +5,10 @@
<sound file="Content/Characters/Scorpion/scorpionidle1.ogg" state="None" />
<sound file="Content/Characters/Scorpion/scorpionidle2.ogg" state="None" />
<ragdoll waveamplitude="50.0" wavelength="2500" swimspeed="4.0" walkspeed="3.5">
<ragdoll waveamplitude="50.0" wavelength="2500" swimspeed="4.0" walkspeed="3.5" canentersubmarine="false">
<collider radius="50" height="320"/>
<!-- head -->
<limb id = "0" radius="12" height="100" type="Head" steerforce="1.0" impacttolerance="50.0">
<sprite texture="Content/Characters/TigerThresher/tigerthresher.png" sourcerect="371,15,66,136" depth="0.02" origin ="0.5,0.5"/>
@@ -3,30 +3,27 @@
<ragdoll waveamplitude="0.0" swimspeed="0.5" walkspeed="0.3" mirror="true" rotatetowardsmovement="false" headangle="-90">
<collider radius="100"/>
<!-- head -->
<limb id = "0" width="350" height="320" type="Head" steerforce="1.0" flip="true" armorsector="0.0,360.0" armorvalue="100.0">
<limb id = "0" type="Head" width="350" height="320" steerforce="1.0" flip="true" armorsector="0.0,360.0" armorvalue="100.0">
<sprite texture="Content/Characters/Watcher/watcher.png" sourcerect="0,0,369,348" depth="0.02" origin ="0.5,0.6"/>
<attack range="150" duration="0.2" damage="200" stun="5" force="10" damagetype="blunt" targetforce="100"/>
<attack range="150" duration="0.05" damage="200" stun="5" force="20" damagetype="blunt" targetforce="100"/>
</limb>
<limb id = "1" radius="50" height="120" flip="true">
<sprite texture="Content/Characters/Watcher/watcher.png" sourcerect="395,0,117,239" depth="0.025" origin="0.5,0.5"/>
<lightsource range="200.0" color="0.8,0.8,1.0,1.0">
<sprite texture="Content/Characters/Watcher/watcher.png" sourcerect="391,282,121,230" depth="0.025" origin="0.5,0.5"/>
</lightsource>
</lightsource>
</limb>
<limb id = "2" width="300" height="119" flip="true">
<sprite texture="Content/Characters/Watcher/watcher.png" sourcerect="0,370,302,142" depth="0.025" origin="0.5,0.5"/>
</limb>
</limb>
<joint limb1="0" limb1anchor="60,130" limb2="1" limb2anchor="-30,100" lowerlimit="70" upperlimit="80"/>
<joint limb1="0" limb1anchor="72,110" limb2="2" limb2anchor="120,-20" lowerlimit="90" upperlimit="180"/>
</ragdoll>
<ai attackhumans="0.0" attackrooms="0.0" sight="1.0" hearing="0.0" attackwhenprovoked="true"/>
@@ -41,7 +41,7 @@ namespace Barotrauma
public Vector2 Velocity
{
get { return Character.AnimController.RefLimb.LinearVelocity; }
get { return Character.AnimController.Collider.LinearVelocity; }
}
public AiState State
@@ -71,36 +71,21 @@ namespace Barotrauma
steeringManager.Update(moveSpeed);
Character.AnimController.IgnorePlatforms = Character.AnimController.TargetMovement.Y < -0.5f &&
bool ignorePlatforms = Character.AnimController.TargetMovement.Y < -0.5f &&
(-Character.AnimController.TargetMovement.Y > Math.Abs(Character.AnimController.TargetMovement.X));
var currPath = (steeringManager as IndoorsSteeringManager).CurrentPath;
if (currPath != null && currPath.CurrentNode != null)
{
if (currPath.CurrentNode.WorldPosition.Y < Character.WorldPosition.Y - 200)
if (currPath.CurrentNode.SimPosition.Y < Character.AnimController.GetColliderBottom().Y)
{
Character.AnimController.IgnorePlatforms = true;
}
if (Character.AnimController.Stairs != null)
{
float yDiff = currPath.CurrentNode.WorldPosition.Y - Character.WorldPosition.Y;
if (Math.Abs(yDiff)>10.0f)
{
int dir = Math.Sign(yDiff);
float movement = Character.AnimController.Stairs.StairDirection == Direction.Right ?
dir * Character.AnimController.TargetMovement.Length() : -dir * Character.AnimController.TargetMovement.Length();
Character.AnimController.TargetMovement = new Vector2(movement, 0.0f);
}
ignorePlatforms = true;
}
}
Character.AnimController.IgnorePlatforms = ignorePlatforms;
(Character.AnimController as HumanoidAnimController).Crouching = false;
if (!Character.AnimController.InWater)
{
Character.AnimController.TargetMovement = new Vector2(
@@ -88,6 +88,15 @@ namespace Barotrauma
Vector2 diff = DiffToCurrentNode();
var collider = character.AnimController.Collider;
//if not in water and the waypoint is between the top and bottom of the collider, no need to move vertically
if (!character.AnimController.InWater &&
character.AnimController.Anim != AnimController.Animation.Climbing &&
diff.Y < collider.height / 2 + collider.radius)
{
diff.Y = 0.0f;
}
if (diff == Vector2.Zero) return -host.Steering;
return Vector2.Normalize(diff) * speed;
@@ -95,7 +104,7 @@ namespace Barotrauma
private Vector2 DiffToCurrentNode()
{
if (currentPath == null || currentPath.Finished) return Vector2.Zero;
if (currentPath == null || currentPath.Finished || currentPath.Unreachable) return Vector2.Zero;
if (currentPath.Finished)
{
@@ -111,7 +120,7 @@ namespace Barotrauma
if (canOpenDoors && !character.LockHands) CheckDoorsInPath();
float allowedDistance = character.AnimController.InWater ? 1.0f : 0.6f;
if (currentPath.CurrentNode!=null && currentPath.CurrentNode.SimPosition.Y > character.SimPosition.Y+1.0f) allowedDistance*=0.5f;
//if (currentPath.CurrentNode!=null && currentPath.CurrentNode.SimPosition.Y > character.SimPosition.Y+1.0f) allowedDistance*=0.5f;
Vector2 pos = host.SimPosition;
@@ -139,7 +148,15 @@ namespace Barotrauma
}
}
currentPath.CheckProgress(pos, allowedDistance);
var collider = character.AnimController.Collider;
Vector2 colliderBottom = character.AnimController.GetColliderBottom();
if (Math.Abs(collider.SimPosition.X - currentPath.CurrentNode.SimPosition.X) < collider.radius*2 &&
currentPath.CurrentNode.SimPosition.Y > colliderBottom.Y &&
currentPath.CurrentNode.SimPosition.Y < colliderBottom.Y + collider.height + collider.radius*2)
{
currentPath.SkipToNextNode();
}
if (currentPath.CurrentNode == null) return Vector2.Zero;
@@ -147,20 +164,31 @@ namespace Barotrauma
if (character.AnimController.Anim == AnimController.Animation.Climbing)
{
float x = currentPath.CurrentNode.SimPosition.X - pos.X;
float y = (currentPath.CurrentNode.SimPosition.Y) - pos.Y;
Vector2 diff = currentPath.CurrentNode.SimPosition - pos;
if (Math.Abs(x) < Math.Abs(y) * 10.0f)
if (currentPath.CurrentNode.Ladders != null)
{
x = 0.0f;
}
else if (character.AnimController.LowestLimb != null && hull != null)
{
if (character.AnimController.LowestLimb.Position.Y < hull.Rect.Y - hull.Rect.Height + 10.0f) x = 0.0f;
//climbing ladders -> don't move horizontally
diff.X = 0.0f;
//at the same height as the waypoint
if (currentPath.CurrentNode.SimPosition.Y > colliderBottom.Y &&
currentPath.CurrentNode.SimPosition.Y < colliderBottom.Y + collider.height + collider.radius * 2)
{
float heightFromFloor = character.AnimController.GetColliderBottom().Y - character.AnimController.FloorY;
//we can safely skip to the next waypoint if the character is at a safe height above the floor,
//or if the next waypoint in the path is also on ladders
if ((heightFromFloor > 0.0f && heightFromFloor < collider.height) ||
(currentPath.NextNode != null && currentPath.NextNode.Ladders != null))
{
currentPath.SkipToNextNode();
}
}
}
character.AnimController.IgnorePlatforms = false;
return new Vector2(x,y);
return diff;
}
return currentPath.CurrentNode.SimPosition - pos;
@@ -90,11 +90,12 @@ namespace Barotrauma
escapeObjective.TryComplete(deltaTime);
if (Vector2.Distance(character.SimPosition, enemy.SimPosition) < 3.0f)
{
character.AIController.SteeringManager.SteeringManual(deltaTime, (character.SimPosition - enemy.SimPosition)*0.1f);
coolDownTimer = CoolDown;
}
//if (Vector2.Distance(character.SimPosition, enemy.SimPosition) < 3.0f)
//{
// character.AIController.SteeringManager.SteeringManual(deltaTime,
// new Vector2(Math.Sign(character.SimPosition.X - enemy.SimPosition.X), 0.0f));
// coolDownTimer = CoolDown;
//}
}
public override bool IsCompleted()
@@ -168,8 +168,11 @@ namespace Barotrauma
//if searching for a path inside the sub, make sure the waypoint is visible
if (insideSubmarine)
{
var body = Submarine.CheckVisibility(start, node.Waypoint.SimPosition);
if (body != null && body.UserData is Structure) continue;
var body = Submarine.PickBody(
start, node.Waypoint.SimPosition, null,
Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionStairs | Physics.CollisionPlatform);
if (body != null && body.UserData is Structure && !((Structure)body.UserData).IsPlatform) continue;
}
closestDist = dist;
@@ -62,6 +62,13 @@ namespace Barotrauma
public virtual void Update(float speed = 1.0f)
{
if (steering == Vector2.Zero || !MathUtils.IsValid(steering))
{
steering = Vector2.Zero;
host.Steering = Vector2.Zero;
return;
}
float steeringSpeed = steering.Length();
if (steeringSpeed>speed)
{
+10 -10
View File
@@ -95,8 +95,8 @@ namespace Barotrauma
return true;
case NetworkEventType.ImportantEntityUpdate:
message.Write(AnimController.RefLimb.SimPosition.X);
message.Write(AnimController.RefLimb.SimPosition.Y);
message.Write(AnimController.MainLimb.SimPosition.X);
message.Write(AnimController.MainLimb.SimPosition.Y);
//message.Write(AnimController.RefLimb.Rotation);
@@ -129,9 +129,9 @@ namespace Barotrauma
message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.Y, -1.0f, 1.0f), -1.0f, 1.0f, 4);
if (AnimController.CanEnterSubmarine) message.Write(Submarine != null);
message.Write(AnimController.RefLimb.SimPosition.X);
message.Write(AnimController.RefLimb.SimPosition.Y);
message.Write(AnimController.MainLimb.SimPosition.X);
message.Write(AnimController.MainLimb.SimPosition.Y);
return true;
case NetworkEventType.InventoryUpdate:
@@ -162,8 +162,8 @@ namespace Barotrauma
return base.ReadNetworkData(type, message, sendingTime, out data);
case NetworkEventType.ImportantEntityUpdate:
Vector2 limbPos = AnimController.RefLimb.SimPosition;
float rotation = AnimController.RefLimb.Rotation;
Vector2 limbPos = AnimController.MainLimb.SimPosition;
float rotation = AnimController.MainLimb.Rotation;
try
{
@@ -180,9 +180,9 @@ namespace Barotrauma
return false;
}
if (AnimController.RefLimb.body != null)
if (AnimController.MainLimb.body != null)
{
AnimController.RefLimb.body.TargetPosition = limbPos;
AnimController.MainLimb.body.TargetPosition = limbPos;
//AnimController.RefLimb.body.TargetRotation = rotation;
}
@@ -255,7 +255,7 @@ namespace Barotrauma
AnimController.TargetDir = (targetDir) ? Direction.Right : Direction.Left;
AnimController.TargetMovement = targetMovement;
AnimController.RefLimb.body.TargetPosition = pos;
AnimController.MainLimb.body.TargetPosition = pos;
//AnimController.EstimateCurrPosition(pos, (float)(NetTime.Now) - sendingTime);
if (inSub)
@@ -1,6 +1,7 @@
using System.Xml.Linq;
using FarseerPhysics;
using Microsoft.Xna.Framework;
using System.Collections.Generic;
namespace Barotrauma
{
@@ -9,8 +10,6 @@ namespace Barotrauma
public enum Animation { None, Climbing, UsingConstruction, Struggle, CPR };
public Animation Anim;
public Direction TargetDir;
protected Character character;
protected float walkSpeed, swimSpeed;
@@ -25,6 +24,8 @@ namespace Barotrauma
protected readonly Vector2 stepSize;
protected readonly float legTorque;
public float StunTimer
{
get { return stunTimer; }
@@ -52,6 +53,8 @@ namespace Barotrauma
//impactTolerance = ToolBox.GetAttributeFloat(element, "impacttolerance", 10.0f);
legTorque = ToolBox.GetAttributeFloat(element, "legtorque", 0.0f);
}
public virtual void UpdateAnim(float deltaTime) { }
@@ -59,5 +62,7 @@ namespace Barotrauma
public virtual void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 holdPos, Vector2 aimPos, bool aim, float holdAngle) { }
public virtual void DragCharacter(Character target, LimbType rightHandTarget = LimbType.RightHand, LimbType leftHandTarget = LimbType.LeftHand) { }
}
}
@@ -47,12 +47,34 @@ namespace Barotrauma
public override void UpdateAnim(float deltaTime)
{
if (character.IsDead)
if (Frozen) return;
if (character.IsDead || character.IsUnconscious || stunTimer > 0.0f)
{
UpdateDying(deltaTime);
collider.PhysEnabled = false;
collider.SetTransform(MainLimb.SimPosition, 0.0f);
if (stunTimer > 0.0f)
{
stunTimer -= deltaTime;
}
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;
}
ResetPullJoints();
if (strongestImpact > 0.0f)
@@ -61,31 +83,32 @@ namespace Barotrauma
strongestImpact = 0.0f;
}
if (stunTimer>0.0f)
if (inWater)
{
//UpdateStruggling(deltaTime);
stunTimer -= deltaTime;
return;
collider.FarseerBody.FixedRotation = false;
UpdateSineAnim(deltaTime);
}
else if (SimplePhysicsEnabled)
else if (currentHull != null && CanEnterSubmarine)
{
UpdateSimpleAnim();
}
else
{
if (inWater || RefLimb.inWater)
if (Math.Abs(MathUtils.GetShortestAngle(collider.Rotation, 0.0f)) > 0.001f)
{
UpdateSineAnim(deltaTime);
//rotate collider back upright
collider.AngularVelocity = MathUtils.GetShortestAngle(collider.Rotation, 0.0f) * 60.0f;
collider.FarseerBody.FixedRotation = false;
}
else if (currentHull != null && CanEnterSubmarine)
else
{
UpdateWalkAnim(deltaTime);
collider.FarseerBody.FixedRotation = true;
}
UpdateWalkAnim(deltaTime);
}
if (mirror || !inWater)
{
if (!character.IsNetworkPlayer)
if (!character.IsRemotePlayer)
{
//targetDir = (movement.X > 0.0f) ? Direction.Right : Direction.Left;
if (targetMovement.X > 0.1f && targetMovement.X > Math.Abs(targetMovement.Y) * 0.5f)
@@ -125,10 +148,10 @@ namespace Barotrauma
if (TargetDir != dir)
{
if (flipTimer>1.0f || character.IsNetworkPlayer)
if (flipTimer>1.0f || character.IsRemotePlayer)
{
Flip();
if (mirror) Mirror();
if (mirror || !inWater) Mirror();
flipTimer = 0.0f;
}
}
@@ -137,11 +160,27 @@ namespace Barotrauma
void UpdateSineAnim(float deltaTime)
{
movement = TargetMovement*swimSpeed;
Limb torso = GetLimb(LimbType.Torso);
Limb head = GetLimb(LimbType.Head);
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;
if (rotateTowardsMovement)
{
collider.SmoothRotate(movementAngle, 25.0f);
MainLimb.body.SmoothRotate(movementAngle, 25.0f);
}
else
{
collider.SmoothRotate(HeadAngle * Dir, 25.0f);
MainLimb.body.SmoothRotate(HeadAngle * Dir, 25.0f);
}
Limb tail = GetLimb(LimbType.Tail);
if (tail != null && waveAmplitude > 0.0f)
@@ -151,100 +190,28 @@ 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;
if (Limbs[i] == MainLimb) continue;
float dist = (Limbs[0].SimPosition - Limbs[i].SimPosition).Length();
float dist = (MainLimb.SimPosition - Limbs[i].SimPosition).Length();
Vector2 limbPos = Limbs[0].SimPosition - Vector2.Normalize(movement) * dist;
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()
{
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);
RefLimb.body.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);
@@ -252,102 +219,30 @@ namespace Barotrauma
IgnorePlatforms = (TargetMovement.Y < -Math.Abs(TargetMovement.X));
Limb colliderLimb;
float colliderHeight;
Limb torso = GetLimb(LimbType.Torso);
Limb head = GetLimb(LimbType.Head);
if (torso != null)
float mainLimbHeight, mainLimbAngle;
if (MainLimb.type == LimbType.Torso)
{
colliderLimb = torso;
colliderHeight = TorsoPosition;
colliderLimb.body.SmoothRotate(TorsoAngle * Dir, 10.0f);
mainLimbHeight = TorsoPosition;
mainLimbAngle = torsoAngle;
}
else
{
colliderLimb = head;
colliderHeight = HeadPosition;
if (onGround) colliderLimb.body.SmoothRotate(HeadAngle * Dir, 100.0f);
mainLimbHeight = HeadPosition;
mainLimbAngle = headAngle;
}
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)
{
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;
}
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.Move(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,
@@ -359,7 +254,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)
{
@@ -371,25 +266,25 @@ namespace Barotrauma
if (limb.type == LimbType.LeftFoot)
{
limb.Move(footPos +new Vector2(
limb.MoveToPos(footPos +new Vector2(
transformedStepSize.X + movement.X * 0.1f,
(transformedStepSize.Y > 0.0f) ? transformedStepSize.Y : 0.0f),
8.0f);
}
else if (limb.type == LimbType.RightFoot)
{
limb.Move(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;
}
}
@@ -428,49 +323,16 @@ namespace Barotrauma
}
}
public override Vector2 EstimateCurrPosition(Vector2 prevPosition, float timePassed)
{
timePassed = MathHelper.Clamp(timePassed, 0.0f, 1.0f);
Vector2 currPosition = prevPosition + targetMovement * timePassed;
return currPosition;
}
private void Mirror()
{
//float leftX = Limbs[0].SimPosition.X, rightX = Limbs[0].SimPosition.X;
//for (int i = 1; i < Limbs.Count(); i++ )
//{
// if (Limbs[i].SimPosition.X < leftX)
// {
// leftX = Limbs[i].SimPosition.X;
// }
// else if (Limbs[i].SimPosition.X > rightX)
// {
// rightX = Limbs[i].SimPosition.X;
// }
//}
float midX = GetCenterOfMass().X;
Vector2 centerOfMass = GetCenterOfMass();
foreach (Limb l in Limbs)
{
Vector2 newPos = new Vector2(midX - (l.SimPosition.X - midX), l.SimPosition.Y);
if (Submarine.CheckVisibility(l.SimPosition, newPos) != null)
{
Vector2 diff = newPos - l.SimPosition;
l.body.SetTransform(
l.SimPosition + Submarine.LastPickedFraction * diff * 0.8f, l.body.Rotation);
}
else
{
l.body.SetTransform(newPos, l.body.Rotation);
}
TrySetLimbPosition(l,
centerOfMass,
new Vector2(centerOfMass.X - (l.SimPosition.X - centerOfMass.X), l.SimPosition.Y),
true);
}
}
@@ -44,10 +44,10 @@ namespace Barotrauma
{
get
{
return Crouching ? base.TorsoAngle+0.5f : base.TorsoAngle;
return Crouching ? base.TorsoAngle + 0.5f : base.TorsoAngle;
}
}
public HumanoidAnimController(Character character, XElement element)
: base(character, element)
{
@@ -61,111 +61,68 @@ namespace Barotrauma
public override void UpdateAnim(float deltaTime)
{
if (character.IsDead) return;
Vector2 colliderPos = GetLimb(LimbType.Torso).SimPosition;
//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;
}
}
//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;
}
if (Frozen) return;
if (character.IsDead || character.IsUnconscious || stunTimer > 0.0f)
{
collider.PhysEnabled = false;
collider.SetTransform(GetLimb(LimbType.Torso).SimPosition, 0.0f);
if (stunTimer > 0)
{
stunTimer -= deltaTime;
}
return;
}
//stun (= disable the animations) if the ragdoll receives a large enough impact
if (strongestImpact > 0.0f)
{
character.StartStun(MathHelper.Min(strongestImpact * 0.5f, 5.0f));
}
strongestImpact = 0.0f;
if (stunTimer > 0)
{
stunTimer -= deltaTime;
strongestImpact = 0.0f;
return;
}
if (!character.IsRemotePlayer || true)
{
//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;
}
if (swimming)
{
collider.FarseerBody.FixedRotation = false;
}
else if (!collider.FarseerBody.FixedRotation)
{
if (Math.Abs(MathUtils.GetShortestAngle(collider.Rotation, 0.0f)) > 0.001f)
{
//rotate collider back upright
collider.AngularVelocity = MathUtils.GetShortestAngle(collider.Rotation, 0.0f) * 60.0f;
collider.FarseerBody.FixedRotation = false;
}
else
{
collider.FarseerBody.FixedRotation = true;
}
}
}
else
{
collider.FarseerBody.Enabled = false;
}
if (character.LockHands)
{
var leftHand = GetLimb(LimbType.LeftHand);
@@ -178,37 +135,31 @@ namespace Barotrauma
Vector2 midPos = waist.SimPosition;
Matrix torsoTransform = Matrix.CreateRotationZ(waist.Rotation);
midPos += Vector2.Transform(new Vector2(-0.3f*Dir,-0.2f), torsoTransform);
midPos += Vector2.Transform(new Vector2(-0.3f * Dir, -0.2f), torsoTransform);
if (rightHand.pullJoint.Enabled) midPos = (midPos + rightHand.pullJoint.WorldAnchorB) / 2.0f;
HandIK(rightHand, midPos);
HandIK(leftHand, midPos);
//rightHand.pullJoint.Enabled = true;
//rightHand.pullJoint.WorldAnchorB = midPos;
//rightHand.pullJoint.Enabled = true;
//rightHand.pullJoint.WorldAnchorB = midPos;
}
else
{
if (Anim != Animation.UsingConstruction) ResetPullJoints();
if (Anim != Animation.UsingConstruction) ResetPullJoints();
}
if (SimplePhysicsEnabled)
{
UpdateStandingSimple();
return;
}
switch (Anim)
{
case Animation.Climbing:
@@ -223,12 +174,12 @@ namespace Barotrauma
default:
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)
{
inWaterTimer = Math.Max(inWaterTimer+deltaTime, 0.5f);
inWaterTimer = Math.Max(inWaterTimer + deltaTime, 0.5f);
if (inWaterTimer >= 1.0f) swimming = true;
}
else
@@ -257,6 +208,7 @@ namespace Barotrauma
}
aiming = false;
if (character.IsRemotePlayer && GameMain.Server == null) collider.LinearVelocity = Vector2.Zero;
}
@@ -267,21 +219,21 @@ namespace Barotrauma
//if you're allergic to magic numbers, stop reading now
Limb leftFoot = GetLimb(LimbType.LeftFoot);
Limb rightFoot = GetLimb(LimbType.RightFoot);
Limb head = GetLimb(LimbType.Head);
Limb torso = GetLimb(LimbType.Torso);
Limb leftFoot = GetLimb(LimbType.LeftFoot);
Limb rightFoot = GetLimb(LimbType.RightFoot);
Limb head = GetLimb(LimbType.Head);
Limb torso = GetLimb(LimbType.Torso);
Limb waist = GetLimb(LimbType.Waist);
Limb waist = GetLimb(LimbType.Waist);
Limb leftHand = GetLimb(LimbType.LeftHand);
Limb rightHand = GetLimb(LimbType.RightHand);
Limb leftHand = GetLimb(LimbType.LeftHand);
Limb rightHand = GetLimb(LimbType.RightHand);
Limb leftLeg = GetLimb(LimbType.LeftLeg);
Limb rightLeg = GetLimb(LimbType.RightLeg);
Limb leftLeg = GetLimb(LimbType.LeftLeg);
Limb rightLeg = GetLimb(LimbType.RightLeg);
float getUpSpeed = 0.3f;
float walkCycleSpeed = head.LinearVelocity.X * walkAnimSpeed;
float walkCycleSpeed = movement.X * walkAnimSpeed;
if (stairs != null)
{
TargetMovement = new Vector2(MathHelper.Clamp(TargetMovement.X, -1.5f, 1.5f), TargetMovement.Y);
@@ -290,17 +242,11 @@ namespace Barotrauma
TargetMovement.X < 0.0f && stairs.StairDirection == Direction.Left)
{
TargetMovement *= 1.7f;
walkCycleSpeed *= 1.7f;
//walkCycleSpeed *= 1.0f;
}
else
{
TargetMovement /= 1.0f;
walkCycleSpeed *= 1.5f;
}
}
Vector2 colliderPos = new Vector2(torso.SimPosition.X, floorY);
Vector2 colliderPos = GetColliderBottom();
if (Math.Abs(TargetMovement.X) > 1.0f)
{
int limbsInWater = 0;
@@ -312,24 +258,27 @@ namespace Barotrauma
float slowdownFactor = (float)limbsInWater / (float)Limbs.Count();
float maxSpeed = Math.Max(TargetMovement.Length() - slowdownFactor, 1.0f);
// if (character.SelectedCharacter!=null) maxSpeed = Math.Min(maxSpeed, 1.0f);
// if (character.SelectedCharacter!=null) maxSpeed = Math.Min(maxSpeed, 1.0f);
TargetMovement = Vector2.Normalize(TargetMovement) * maxSpeed;
}
float walkPosX = (float)Math.Cos(walkPos);
float walkPosY = (float)Math.Sin(walkPos);
float runningModifier = (float)Math.Max(Math.Min(Math.Abs(TargetMovement.X),3.0f) / 1.5f, 1.0);
float runningModifier = (float)Math.Max(Math.Min(Math.Abs(TargetMovement.X), 3.0f) / 1.5f, 1.0);
Vector2 stepSize = new Vector2(
this.stepSize.X * walkPosX * runningModifier,
this.stepSize.Y * walkPosY * runningModifier * runningModifier);
if (Crouching) stepSize *= 0.5f;
float footMid = waist.SimPosition.X;// (leftFoot.SimPosition.X + rightFoot.SimPosition.X) / 2.0f;
movement = MathUtils.SmoothStep(movement, TargetMovement*walkSpeed, movementLerp);
float footMid = colliderPos.X;// (leftFoot.SimPosition.X + rightFoot.SimPosition.X) / 2.0f;
movement = overrideTargetMovement == Vector2.Zero ?
MathUtils.SmoothStep(movement, TargetMovement * walkSpeed, movementLerp) :
overrideTargetMovement;
movement.Y = 0.0f;
for (int i = 0; i < 2; i++)
@@ -354,17 +303,12 @@ namespace Barotrauma
}
}
if (LowestLimb == null) return;
if (!onGround || (LowestLimb.SimPosition.Y - floorY > 0.5f && stairs == null)) return;
//float? ceilingY = null;
//if (Submarine.PickBody(head.SimPosition, head.SimPosition + Vector2.UnitY, null, Physics.CollisionWall)!=null)
//{
// ceilingY = Submarine.LastPickedPosition.Y;
// if (ceilingY - floorY < HeadPosition) Crouching = true;
//}
if (onGround && (!character.IsRemotePlayer || GameMain.Server != null))
{
collider.LinearVelocity = new Vector2(
movement.X,
collider.LinearVelocity.Y > 0.0f ? collider.LinearVelocity.Y * 0.5f : collider.LinearVelocity.Y);
}
getUpSpeed = getUpSpeed * Math.Max(head.SimPosition.Y - colliderPos.Y, 0.5f);
@@ -374,32 +318,43 @@ namespace Barotrauma
if (stairs != null)
{
if (LowestLimb.SimPosition.Y < stairs.SimPosition.Y) IgnorePlatforms = true;
torso.pullJoint.WorldAnchorB = new Vector2(
MathHelper.SmoothStep(torso.SimPosition.X, footMid + movement.X * 0.35f, getUpSpeed * 0.8f),
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(
MathHelper.SmoothStep(head.SimPosition.X, footMid + movement.X * (Crouching ? 1.0f : 0.4f), getUpSpeed * 0.8f),
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;
}
else
{
if (!onGround) movement = Vector2.Zero;
torso.pullJoint.WorldAnchorB =
MathUtils.SmoothStep(torso.SimPosition,
new Vector2(footMid + movement.X * 0.3f, colliderPos.Y + TorsoPosition), getUpSpeed);
new Vector2(footMid + movement.X * 0.2f, colliderPos.Y + TorsoPosition), getUpSpeed);
head.pullJoint.WorldAnchorB =
MathUtils.SmoothStep(head.SimPosition,
new Vector2(footMid + movement.X * (Crouching && Math.Sign(movement.X)==Math.Sign(Dir) ? 1.0f : 0.3f), colliderPos.Y + HeadPosition), getUpSpeed*1.2f);
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.1f;
waist.pullJoint.WorldAnchorB = waist.SimPosition + movement * 0.06f;
}
if (!onGround)
{
Vector2 move = torso.pullJoint.WorldAnchorB - torso.SimPosition;
foreach (Limb limb in Limbs)
{
MoveLimb(limb, limb.SimPosition+move, 15.0f, true);
}
return;
}
//moving horizontally
if (TargetMovement.X != 0.0f)
@@ -461,7 +416,7 @@ namespace Barotrauma
HandIK(rightHand, torso.SimPosition + posAddition +
new Vector2(
-handPos.X,
(Math.Sign(walkPosX) == Math.Sign(Dir)) ? handPos.Y : lowerY), 0.7f*runningModifier);
(Math.Sign(walkPosX) == Math.Sign(Dir)) ? handPos.Y : lowerY), 0.7f * runningModifier);
}
if (!leftHand.Disabled)
@@ -506,7 +461,7 @@ namespace Barotrauma
var leftArm = GetLimb(LimbType.LeftArm);
leftArm.body.SmoothRotate(0.0f, 20.0f);
}
}
}
}
@@ -520,17 +475,18 @@ namespace Barotrauma
movement = Vector2.Normalize(movement);
}
RefLimb.pullJoint.Enabled = true;
RefLimb.pullJoint.WorldAnchorB =
RefLimb.SimPosition + movement * 0.15f;
return;
//RefLimb.pullJoint.Enabled = true;
//RefLimb.pullJoint.WorldAnchorB =
// RefLimb.SimPosition + movement * 0.15f;
RefLimb.body.SmoothRotate(0.0f);
//RefLimb.body.SmoothRotate(0.0f);
foreach (Limb l in Limbs)
{
if (l == RefLimb) continue;
l.body.SetTransform(RefLimb.SimPosition, RefLimb.Rotation);
}
//foreach (Limb l in Limbs)
//{
// if (l == RefLimb) continue;
// l.body.SetTransform(RefLimb.SimPosition, RefLimb.Rotation);
//}
//new Vector2(movement.X, floorY + HeadPosition), 0.5f);
}
@@ -543,26 +499,26 @@ namespace Barotrauma
float surfaceLimiter = 1.0f;
Limb head = GetLimb(LimbType.Head);
if (currentHull != null && (currentHull.Rect.Y - currentHull.Surface > 50.0f) && !head.inWater)
Limb torso = GetLimb(LimbType.Torso);
if (currentHull != null && (currentHull.Rect.Y - currentHull.Surface > 50.0f))
{
surfaceLimiter = (ConvertUnits.ToDisplayUnits(head.SimPosition.Y) - surfaceY);
surfaceLimiter = (ConvertUnits.ToDisplayUnits(collider.SimPosition.Y + 0.4f) - surfaceY);
surfaceLimiter = Math.Max(1.0f, surfaceLimiter);
if (surfaceLimiter > 20.0f) return;
if (surfaceLimiter > 50.0f) return;
}
Limb torso = GetLimb(LimbType.Torso);
Limb leftHand = GetLimb(LimbType.LeftHand);
Limb rightHand = GetLimb(LimbType.RightHand);
Limb leftFoot = GetLimb(LimbType.LeftFoot);
Limb rightFoot = GetLimb(LimbType.RightFoot);
float rotation = MathHelper.WrapAngle(torso.Rotation);
float rotation = MathHelper.WrapAngle(collider.Rotation);
rotation = MathHelper.ToDegrees(rotation);
if (rotation < 0.0f) rotation += 360;
if (!character.IsNetworkPlayer && !aiming)
if (!character.IsRemotePlayer && !aiming)
{
if (rotation > 20 && rotation < 170)
TargetDir = Direction.Left;
@@ -577,7 +533,10 @@ namespace Barotrauma
{
if (!aiming)
{
torso.body.SmoothRotate(MathUtils.VectorToAngle(TargetMovement) - MathHelper.PiOver2);
float newRotation = MathUtils.VectorToAngle(TargetMovement) - MathHelper.PiOver2;
collider.SmoothRotate(newRotation, 5.0f);
//torso.body.SmoothRotate(newRotation);
}
}
else
@@ -589,23 +548,27 @@ namespace Barotrauma
TargetMovement = new Vector2(0.0f, -0.1f);
torso.body.SmoothRotate(MathUtils.VectorToAngle(diff));
float newRotation = MathUtils.VectorToAngle(diff);
collider.SmoothRotate(newRotation, 5.0f);
}
}
torso.body.SmoothRotate(collider.Rotation);
torso.body.MoveToPos(collider.SimPosition + new Vector2((float)Math.Sin(-collider.Rotation), (float)Math.Cos(-collider.Rotation))*0.4f, 5.0f);
if (TargetMovement == Vector2.Zero) return;
movement = MathUtils.SmoothStep(movement, TargetMovement*swimSpeed, 0.3f);
movement = MathUtils.SmoothStep(movement, TargetMovement, 0.3f);
//dont try to move upwards if head is already out of water
if (surfaceLimiter > 1.0f && TargetMovement.Y > 0.0f)
{
if (TargetMovement.X == 0.0f)
{
head.body.ApplyForce(head.Mass * new Vector2(-Dir * 5.1f, -5.0f));
torso.body.ApplyForce(torso.Mass * new Vector2(-Dir * 5.1f, -15.0f));
leftFoot.body.ApplyForce(leftFoot.Mass * new Vector2(0.0f, -80.0f));
rightFoot.body.ApplyForce(rightFoot.Mass * new Vector2(0.0f, -80.0f));
//pull head above water
head.body.SmoothRotate(0.0f, 5.0f);
walkPos += 0.05f;
}
else
{
@@ -614,23 +577,20 @@ namespace Barotrauma
* Math.Sign(TargetMovement.X),
Math.Max(TargetMovement.Y, TargetMovement.Y * 0.2f));
head.body.ApplyTorque(Dir * 0.1f);
//turn head above the water
head.body.ApplyTorque(Dir);
}
movement.Y = movement.Y - (surfaceLimiter - 1.0f) * 0.01f;
}
movement.Y -= 0.05f;
head.body.ApplyForce((new Vector2(movement.X,
movement.Y / surfaceLimiter + 0.2f) - head.body.LinearVelocity * 0.2f) *
30.0f * head.body.Mass);
torso.body.ApplyForce((new Vector2(movement.X,
movement.Y / surfaceLimiter + 0.2f) - torso.body.LinearVelocity * 0.2f) * 10.0f * torso.body.Mass);
if (!character.IsRemotePlayer || GameMain.Server != null)
{
collider.LinearVelocity = Vector2.Lerp(collider.LinearVelocity, movement * swimSpeed, movementLerp);
}
walkPos += movement.Length() * 0.15f;
footPos = (leftFoot.SimPosition + rightFoot.SimPosition) / 2.0f;
footPos = collider.SimPosition - new Vector2((float)Math.Sin(-collider.Rotation), (float)Math.Cos(-collider.Rotation)) * 0.4f;
var rightThigh = GetLimb(LimbType.RightThigh);
var leftThigh = GetLimb(LimbType.LeftThigh);
@@ -641,41 +601,32 @@ namespace Barotrauma
Vector2 transformedFootPos = new Vector2((float)Math.Sin(walkPos) * 0.5f, 0.0f);
transformedFootPos = Vector2.Transform(
transformedFootPos,
Matrix.CreateRotationZ(torso.body.Rotation));
Matrix.CreateRotationZ(collider.Rotation));
if (Math.Abs(MathUtils.GetShortestAngle(torso.Rotation, rightThigh.Rotation)) < 0.3f)
{
MoveLimb(rightFoot, footPos - transformedFootPos, 1.0f);
}
if (Math.Abs(MathUtils.GetShortestAngle(torso.Rotation, leftThigh.Rotation)) < 0.3f)
{
MoveLimb(leftFoot, footPos + transformedFootPos, 1.0f);
}
MoveLimb(rightFoot, footPos - transformedFootPos, 1.0f);
MoveLimb(leftFoot, footPos + transformedFootPos, 1.0f);
handPos = (torso.SimPosition + head.SimPosition) / 2.0f;
//if (!rightHand.Disabled) rightHand.body.ApplyTorque(leftHand.body.Mass * Dir);
//if (!leftHand.Disabled) leftHand.body.ApplyTorque(leftHand.body.Mass * Dir);
//at the surface, not moving sideways -> hands just float around
if (!headInWater && TargetMovement.X == 0.0f && TargetMovement.Y > 0)
{
handPos.X = handPos.X + Dir * 0.6f;
float wobbleAmount = 0.05f;
float wobbleAmount = 0.1f;
if (!rightHand.Disabled)
{
MoveLimb(rightHand, new Vector2(
handPos.X + (float)Math.Sin(walkPos / 1.5f) * wobbleAmount,
handPos.Y + (float)Math.Sin(walkPos / 3.5f) * wobbleAmount - 0.0f), 1.5f);
handPos.Y + (float)Math.Sin(walkPos / 3.5f) * wobbleAmount - 0.25f), 1.5f);
}
if (!leftHand.Disabled)
{
MoveLimb(leftHand, new Vector2(
handPos.X + (float)Math.Sin(walkPos / 2.0f) * wobbleAmount,
handPos.Y + (float)Math.Sin(walkPos / 3.0f) * wobbleAmount - 0.0f), 1.5f);
handPos.Y + (float)Math.Sin(walkPos / 3.0f) * wobbleAmount - 0.25f), 1.5f);
}
return;
@@ -683,8 +634,8 @@ namespace Barotrauma
handPos += head.LinearVelocity * 0.1f;
float handCyclePos = walkPos / 2.0f;
float handPosX = (float)Math.Cos(handCyclePos * Dir) * 0.4f;
float handCyclePos = walkPos / 3.0f * -Dir;
float handPosX = (float)Math.Cos(handCyclePos) * 0.4f;
float handPosY = (float)Math.Sin(handCyclePos) * 1.0f;
handPosY = MathHelper.Clamp(handPosY, -0.8f, 0.8f);
@@ -693,21 +644,18 @@ namespace Barotrauma
if (!rightHand.Disabled)
{
Vector2 rightHandPos = new Vector2(-handPosX, -handPosY);
rightHandPos.X = (Dir == 1.0f) ? Math.Max(0.2f, rightHandPos.X) : Math.Min(-0.2f, rightHandPos.X);
rightHandPos.X = (Dir == 1.0f) ? Math.Max(0.3f, rightHandPos.X) : Math.Min(-0.3f, rightHandPos.X);
rightHandPos = Vector2.Transform(rightHandPos, rotationMatrix);
//MoveLimb(rightHand, handPos + rightHandPos, 1.5f);
HandIK(rightHand, handPos + rightHandPos, 0.5f);
}
if (!leftHand.Disabled)
{
Vector2 leftHandPos = new Vector2(handPosX, handPosY);
leftHandPos.X = (Dir == 1.0f) ? Math.Max(0.2f, leftHandPos.X) : Math.Min(-0.2f, leftHandPos.X);
leftHandPos.X = (Dir == 1.0f) ? Math.Max(0.3f, leftHandPos.X) : Math.Min(-0.3f, leftHandPos.X);
leftHandPos = Vector2.Transform(leftHandPos, rotationMatrix);
//MoveLimb(leftHand, handPos + leftHandPos,1.5f);
HandIK(leftHand, handPos + leftHandPos, 0.5f);
}
}
@@ -724,10 +672,9 @@ namespace Barotrauma
IgnorePlatforms = true;
Vector2 tempTargetMovement = TargetMovement;
//if (TargetMovement.Y != 0.0f)
//{
// tempTargetMovement.Y = Math.Max(Math.Abs(TargetMovement.Y), 0.6f) * Math.Sign(TargetMovement.Y);
//}
tempTargetMovement.Y = Math.Min(tempTargetMovement.Y, 1.0f);
movement = MathUtils.SmoothStep(movement, tempTargetMovement, 0.3f);
Limb leftFoot = GetLimb(LimbType.LeftFoot);
@@ -746,7 +693,7 @@ namespace Barotrauma
float stepHeight = ConvertUnits.ToSimUnits(30.0f);
if (currentHull==null && character.SelectedConstruction.Submarine!=null)
if (currentHull == null && character.SelectedConstruction.Submarine != null)
{
ladderSimPos += character.SelectedConstruction.Submarine.SimPosition;
}
@@ -754,26 +701,32 @@ namespace Barotrauma
{
ladderSimPos += character.SelectedConstruction.Submarine.SimPosition - currentHull.Submarine.SimPosition;
}
MoveLimb(head, new Vector2(ladderSimPos.X - 0.27f * Dir, head.SimPosition.Y + 0.05f), 10.5f);
MoveLimb(torso, new Vector2(ladderSimPos.X - 0.27f * Dir, torso.SimPosition.Y), 10.5f);
MoveLimb(waist, new Vector2(ladderSimPos.X - 0.35f * Dir, waist.SimPosition.Y), 10.5f);
MoveLimb(head, new Vector2(ladderSimPos.X - 0.27f * Dir, collider.SimPosition.Y + 0.7f), 10.5f);
MoveLimb(torso, new Vector2(ladderSimPos.X - 0.27f * Dir, collider.SimPosition.Y+0.5f), 10.5f);
MoveLimb(waist, new Vector2(ladderSimPos.X - 0.35f * Dir, collider.SimPosition.Y+0.4f), 10.5f);
if (!character.IsRemotePlayer)
{
collider.MoveToPos(new Vector2(ladderSimPos.X - 0.2f * Dir, collider.SimPosition.Y), 10.5f);
}
bool slide = targetMovement.Y < -1.1f;
Vector2 handPos = new Vector2(
ladderSimPos.X,
head.SimPosition.Y + movement.Y * 0.1f - ladderSimPos.Y);
collider.SimPosition.Y + 0.6f + movement.Y * 0.1f - ladderSimPos.Y);
handPos.Y = Math.Min(-0.5f, handPos.Y);
MoveLimb(leftHand,
new Vector2(handPos.X,
MathUtils.Round(handPos.Y - stepHeight, stepHeight * 2.0f) + stepHeight + ladderSimPos.Y),
(slide ? handPos.Y : MathUtils.Round(handPos.Y - stepHeight, stepHeight * 2.0f) + stepHeight) + ladderSimPos.Y),
5.2f);
MoveLimb(rightHand,
new Vector2(handPos.X,
MathUtils.Round(handPos.Y, stepHeight * 2.0f) + ladderSimPos.Y),
(slide ? handPos.Y : MathUtils.Round(handPos.Y, stepHeight * 2.0f)) + ladderSimPos.Y),
5.2f);
leftHand.body.ApplyTorque(Dir * 2.0f);
@@ -781,18 +734,18 @@ namespace Barotrauma
Vector2 footPos = new Vector2(
handPos.X - Dir * 0.05f,
head.SimPosition.Y - stepHeight * 2.7f - ladderSimPos.Y - 0.7f);
collider.SimPosition.Y + 0.7f - stepHeight * 2.7f - ladderSimPos.Y - 0.7f);
//if (movement.Y < 0) footPos.Y += 0.05f;
MoveLimb(leftFoot,
new Vector2(footPos.X,
MathUtils.Round(footPos.Y + stepHeight, stepHeight * 2.0f) - stepHeight + ladderSimPos.Y),
(slide ? footPos.Y : MathUtils.Round(footPos.Y + stepHeight, stepHeight * 2.0f) - stepHeight) + ladderSimPos.Y),
15.5f, true);
MoveLimb(rightFoot,
new Vector2(footPos.X,
MathUtils.Round(footPos.Y, stepHeight * 2.0f) + ladderSimPos.Y),
(slide ? footPos.Y : MathUtils.Round(footPos.Y, stepHeight * 2.0f)) + ladderSimPos.Y),
15.5f, true);
//apply torque to the legs to make the knees bend
@@ -802,18 +755,19 @@ namespace Barotrauma
leftLeg.body.ApplyTorque(Dir * -8.0f);
rightLeg.body.ApplyTorque(Dir * -8.0f);
//apply forces to the head and the torso to move the Character up/down
float movementFactor = (handPos.Y / stepHeight) * (float)Math.PI;
movementFactor = 0.8f + (float)Math.Abs(Math.Sin(movementFactor));
Vector2 subSpeed = currentHull != null || character.SelectedConstruction.Submarine == null
Vector2 subSpeed = currentHull != null || character.SelectedConstruction.Submarine == null
? Vector2.Zero : character.SelectedConstruction.Submarine.Velocity;
Vector2 climbForce = new Vector2(0.0f, movement.Y + (inWater ? -0.05f : 0.6f)) * movementFactor;
if (climbForce.Y > 0.5f) climbForce.Y = Math.Max(climbForce.Y, 1.3f);
torso.body.ApplyForce((climbForce * 40.0f + subSpeed*50.0f) * torso.Mass);
head.body.SmoothRotate(0.0f);
Vector2 climbForce = new Vector2(0.0f, movement.Y + 0.3f) * movementFactor;
//if (climbForce.Y > 0.5f) climbForce.Y = Math.Max(climbForce.Y, 1.3f);
//apply forces to the collider to move the Character up/down
collider.ApplyForce((climbForce * 20.0f + subSpeed * 50.0f) * collider.Mass);
head.body.SmoothRotate(0.0f);
if (!character.SelectedConstruction.Prefab.Triggers.Any())
{
character.SelectedConstruction = null;
@@ -824,7 +778,7 @@ namespace Barotrauma
trigger = character.SelectedConstruction.TransformTrigger(trigger);
bool notClimbing = false;
if (character.IsNetworkPlayer)
if (character.IsRemotePlayer)
{
notClimbing = character.IsKeyDown(InputType.Left) || character.IsKeyDown(InputType.Right);
}
@@ -861,15 +815,15 @@ namespace Barotrauma
targetMovement = new Vector2(diff.X, 0.0f);
TargetDir = headDiff.X > 0.0f ? Direction.Right : Direction.Left;
UpdateStanding();
Vector2 handPos = character.SelectedCharacter.AnimController.GetLimb(LimbType.Torso).SimPosition + Vector2.UnitY*0.2f;
Vector2 handPos = character.SelectedCharacter.AnimController.GetLimb(LimbType.Torso).SimPosition + Vector2.UnitY * 0.2f;
Grab(handPos, handPos);
float yPos = (float)Math.Sin(cprAnimState) * 0.1f;
cprAnimState += deltaTime*8.0f;
cprAnimState += deltaTime * 8.0f;
var head = GetLimb(LimbType.Head);
head.pullJoint.WorldAnchorB = new Vector2(targetHead.SimPosition.X, targetHead.SimPosition.Y + 0.6f + yPos);
@@ -879,7 +833,7 @@ namespace Barotrauma
//RefLimb.pullJoint.WorldAnchorB = new Vector2(targetHead.SimPosition.X - Math.Sign(headDiff.X) * 0.5f, targetHead.SimPosition.Y + 0.4f + yPos);
//head.pullJoint.Enabled = true;
//DragCharacter(character.SelectedCharacter, LimbType.Torso, LimbType.Head);
}
@@ -941,15 +895,15 @@ namespace Barotrauma
//only grab with one hand when swimming
leftHand.Disabled = true;
if (!inWater) rightHand.Disabled = true;
for (int i = 0; i < 2; i++ )
{
LimbType type = i == 0 ? leftHandTarget: rightHandTarget;
Limb targetLimb = target.AnimController.GetLimb(type);
Limb pullLimb = GetLimb(i == 0 ? LimbType.LeftHand: LimbType.RightHand);
if (i==1 && inWater)
for (int i = 0; i < 2; i++)
{
LimbType type = i == 0 ? leftHandTarget : rightHandTarget;
Limb targetLimb = target.AnimController.GetLimb(type);
Limb pullLimb = GetLimb(i == 0 ? LimbType.LeftHand : LimbType.RightHand);
if (i == 1 && inWater)
{
targetLimb.pullJoint.Enabled = false;
}
@@ -976,7 +930,7 @@ namespace Barotrauma
}
else if (target is AICharacter)
{
target.AnimController.TargetMovement = Vector2.Lerp(target.AnimController.TargetMovement, (character.SimPosition + Vector2.UnitX*Dir) - target.SimPosition, 0.5f);
target.AnimController.TargetMovement = Vector2.Lerp(target.AnimController.TargetMovement, (character.SimPosition + Vector2.UnitX * Dir) - target.SimPosition, 0.5f);
}
}
@@ -989,7 +943,7 @@ namespace Barotrauma
pullLimb.Disabled = true;
pullLimb.pullJoint.Enabled = true;
pullLimb.pullJoint.WorldAnchorB = (i==0) ? rightHandPos : leftHandPos;
pullLimb.pullJoint.WorldAnchorB = (i == 0) ? rightHandPos : leftHandPos;
pullLimb.pullJoint.MaxForce = 500.0f;
}
@@ -1084,7 +1038,7 @@ namespace Barotrauma
item.body.ResetDynamics();
Vector2 currItemPos = (character.SelectedItems[0]==item) ?
Vector2 currItemPos = (character.SelectedItems[0] == item) ?
rightHand.pullJoint.WorldAnchorA - transformedHandlePos[0] :
leftHand.pullJoint.WorldAnchorA - transformedHandlePos[1];
item.SetTransform(currItemPos, itemAngle);
@@ -1129,17 +1083,6 @@ namespace Barotrauma
hand.body.SmoothRotate((ang2 + handAngle * Dir), 100.0f * force);
}
public override Vector2 EstimateCurrPosition(Vector2 prevPosition, float timePassed)
{
timePassed = MathHelper.Clamp(timePassed, 0.0f, 1.0f);
Vector2 targetMovement = character.GetTargetMovement();
Vector2 currPosition = prevPosition + targetMovement * timePassed/500.0f;
return currPosition;
}
public override void Flip()
{
base.Flip();
@@ -1199,7 +1142,7 @@ namespace Barotrauma
Vector2 position = limb.SimPosition;
if ((limb.pullJoint==null || !limb.pullJoint.Enabled) && mirror)
if ((limb.pullJoint == null || !limb.pullJoint.Enabled) && mirror)
{
difference = limb.body.SimPosition - torso.SimPosition;
difference = Vector2.Transform(difference, torsoTransform);
@@ -1213,11 +1156,11 @@ namespace Barotrauma
float angle = flipAngle ? -limb.body.Rotation : limb.body.Rotation;
if (wrapAngle) angle = MathUtils.WrapAnglePi(angle);
TrySetLimbPosition(limb, RefLimb.SimPosition, position);
TrySetLimbPosition(limb, collider.SimPosition, position);
limb.body.SetTransform(limb.body.SimPosition, angle);
}
}
}
}
+374 -236
View File
@@ -9,6 +9,7 @@ using FarseerPhysics.Dynamics.Joints;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Networking;
using Lidgren.Network;
namespace Barotrauma
{
@@ -19,6 +20,25 @@ namespace Barotrauma
protected Hull currentHull;
public Limb[] Limbs;
private bool frozen;
public bool Frozen
{
get { return frozen; }
set
{
if (frozen == value) return;
frozen = value;
foreach (Limb l in Limbs)
{
l.body.PhysEnabled = !frozen;
}
collider.PhysEnabled = !frozen;
}
}
private Dictionary<LimbType, Limb> limbDictionary;
public RevoluteJoint[] limbJoints;
@@ -26,8 +46,6 @@ namespace Barotrauma
private Character character;
private Limb lowestLimb;
protected float strongestImpact;
public float headPosition, headAngle;
@@ -44,7 +62,7 @@ namespace Barotrauma
//a movement vector that overrides targetmovement if trying to steer
//a Character to the position sent by server in multiplayer mode
protected Vector2 correctionMovement;
protected Vector2 overrideTargetMovement;
protected float floorY;
protected float surfaceY;
@@ -52,25 +70,20 @@ namespace Barotrauma
protected bool inWater, headInWater;
public bool onGround;
private bool ignorePlatforms;
private Limb refLimb;
protected Structure stairs;
protected Direction dir;
//private byte ID;
public Limb LowestLimb
{
get { return lowestLimb; }
}
public Direction TargetDir;
public Limb RefLimb
protected PhysicsBody collider;
public PhysicsBody Collider
{
get
{
return refLimb;
return collider;
}
}
@@ -85,6 +98,22 @@ namespace Barotrauma
private set;
}
public Limb MainLimb
{
get;
private set;
}
public Vector2 WorldPosition
{
get
{
return character.Submarine == null ?
ConvertUnits.ToDisplayUnits(collider.SimPosition) :
ConvertUnits.ToDisplayUnits(collider.SimPosition) + character.Submarine.Position;
}
}
public bool SimplePhysicsEnabled
{
get { return simplePhysicsEnabled; }
@@ -104,7 +133,13 @@ namespace Barotrauma
joint.Enabled = !simplePhysicsEnabled;
}
refLimb.body.Enabled = true;
if (!simplePhysicsEnabled)
{
foreach (Limb limb in Limbs)
{
limb.body.SetTransform(collider.SimPosition, collider.Rotation);
}
}
}
}
@@ -112,7 +147,7 @@ namespace Barotrauma
{
get
{
return (correctionMovement == Vector2.Zero) ? targetMovement : correctionMovement;
return (overrideTargetMovement == Vector2.Zero) ? targetMovement : overrideTargetMovement;
}
set
{
@@ -167,10 +202,12 @@ namespace Barotrauma
if (value == currentHull) return;
currentHull = value;
Submarine currSubmarine = currentHull == null ? null : currentHull.Submarine;
foreach (Limb limb in Limbs)
{
limb.body.Submarine = currentHull == null ? null : currentHull.Submarine;
limb.body.Submarine = currSubmarine;
}
collider.Submarine = currSubmarine;
}
}
@@ -208,18 +245,17 @@ namespace Barotrauma
float scale = ToolBox.GetAttributeFloat(element, "scale", 1.0f);
//int limbAmount = ;
Limbs = new Limb[element.Elements("limb").Count()];
limbJoints = new RevoluteJoint[element.Elements("joint").Count()];
limbDictionary = new Dictionary<LimbType, Limb>();
headPosition = ToolBox.GetAttributeFloat(element, "headposition", 50.0f);
headPosition = ConvertUnits.ToSimUnits(headPosition);
headAngle = MathHelper.ToRadians(ToolBox.GetAttributeFloat(element, "headangle", 0.0f));
headPosition = ToolBox.GetAttributeFloat(element, "headposition", 50.0f);
headPosition = ConvertUnits.ToSimUnits(headPosition);
headAngle = MathHelper.ToRadians(ToolBox.GetAttributeFloat(element, "headangle", 0.0f));
torsoPosition = ToolBox.GetAttributeFloat(element, "torsoposition", 50.0f);
torsoPosition = ConvertUnits.ToSimUnits(torsoPosition);
torsoAngle = MathHelper.ToRadians(ToolBox.GetAttributeFloat(element, "torsoangle", 0.0f));
torsoPosition = ToolBox.GetAttributeFloat(element, "torsoposition", 50.0f);
torsoPosition = ConvertUnits.ToSimUnits(torsoPosition);
torsoAngle = MathHelper.ToRadians(ToolBox.GetAttributeFloat(element, "torsoangle", 0.0f));
CanEnterSubmarine = ToolBox.GetAttributeBool(element, "canentersubmarine", true);
@@ -241,20 +277,30 @@ namespace Barotrauma
case "joint":
AddJoint(subElement, scale);
break;
case "collider":
collider = new PhysicsBody(subElement, scale);
collider.FarseerBody.FixedRotation = true;
break;
}
}
refLimb = GetLimb(LimbType.Torso);
if (refLimb == null) refLimb = GetLimb(LimbType.Head);
if (refLimb == null) DebugConsole.ThrowError("Character \"" + character + "\" doesn't have a head or torso!");
if (collider == null)
{
DebugConsole.ThrowError("No collider configured for ''"+character.Name+"''!");
collider = new PhysicsBody(0.0f, 0.0f, 0.5f, 5.0f);
collider.BodyType = BodyType.Dynamic;
}
collider.CollisionCategories = Physics.CollisionCharacter;
collider.FarseerBody.AngularDamping = 5.0f;
collider.FarseerBody.FixedRotation = true;
collider.FarseerBody.OnCollision += OnLimbCollision;
UpdateCollisionCategories();
foreach (var joint in limbJoints)
{
joint.BodyB.SetTransform(
joint.BodyA.Position + (joint.LocalAnchorA - joint.LocalAnchorB)*0.1f,
(joint.LowerLimit + joint.UpperLimit) / 2.0f);
@@ -274,7 +320,10 @@ namespace Barotrauma
limb.sprite.Depth = startDepth + limb.sprite.Depth * 0.0001f;
}
FindLowestLimb();
Limb torso = GetLimb(LimbType.Torso);
Limb head = GetLimb(LimbType.Head);
MainLimb = torso == null ? head : torso;
}
public void AddJoint(XElement subElement, float scale = 1.0f)
@@ -341,61 +390,51 @@ namespace Barotrauma
CalculateImpact(f1, f2, contact);
return true;
}
Vector2 colliderBottom = GetColliderBottom();
if (structure.IsPlatform)
{
if (ignorePlatforms) return false;
//the collision is ignored if the lowest limb is under the platform
if (lowestLimb==null || lowestLimb.Position.Y < structure.Rect.Y) return false;
//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 && lowestLimb != null)
else if (structure.StairDirection != Direction.None)
{
float stairPosY = structure.StairDirection == Direction.Right ?
lowestLimb.Position.X - structure.Rect.X : structure.Rect.Width - (lowestLimb.Position.X - structure.Rect.X);
stairs = null;
//don't collider with stairs if
if (lowestLimb.Position.Y < structure.Rect.Y - structure.Rect.Height + stairPosY - 10.0f) return false;
//1. bottom of the collider is at the bottom of the stairs and the character isn't trying to move upwards
float stairBottomPos = ConvertUnits.ToSimUnits(structure.Rect.Y - structure.Rect.Height + 10);
if (colliderBottom.Y < stairBottomPos && targetMovement.Y < 0.5f) return false;
if (targetMovement.Y < 0.5f)
{
if (inWater || lowestLimb.Position.Y < structure.Rect.Y - structure.Rect.Height + 50.0f)
{
stairs = null;
return false;
}
}
//if (targetMovement.Y >= 0.0f && lowestLimb.SimPosition.Y > ConvertUnits.ToSimUnits(structure.Rect.Y - Submarine.GridSize.Y * 8.0f))
//{
// //stairs = null;
// //return false;
//}
Limb limb = f1.Body.UserData as Limb;
if (limb != null)// && (limb.type == LimbType.LeftFoot || limb.type == LimbType.RightFoot))
{
if (contact.Manifold.LocalNormal.Y >= 0.0f)
{
if (limb.SimPosition.Y < lowestLimb.SimPosition.Y+0.2f)
{
stairs = structure;
return true;
}
//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;
//3. collided with the stairs from below
if (contact.Manifold.LocalNormal.Y < 0.0f) return false;
}
else
{
stairs = null;
return false;
}
}
//4. contact points is above the bottom half of the collider
Vector2 normal; FarseerPhysics.Common.FixedArray2<Vector2> points;
contact.GetWorldManifold(out normal, out points);
if (points[0].Y > collider.SimPosition.Y) return false;
//5. in water
if (inWater && targetMovement.Y < 0.5f) return false;
//---------------
stairs = structure;
}
CalculateImpact(f1, f2, contact);
return true;
}
@@ -405,39 +444,40 @@ namespace Barotrauma
Vector2 normal = contact.Manifold.LocalNormal;
Vector2 avgVelocity = Vector2.Zero;
foreach (Limb limb in Limbs)
{
avgVelocity += limb.LinearVelocity;
}
//Vector2 avgVelocity = Vector2.Zero;
//foreach (Limb limb in Limbs)
//{
// avgVelocity += limb.LinearVelocity;
//}
avgVelocity = avgVelocity / Limbs.Count();
Vector2 velocity = f1.Body.LinearVelocity;
if (character.Submarine == null && f2.Body.UserData is Submarine) avgVelocity -= ((Submarine)f2.Body.UserData).Velocity;
if (character.Submarine == null && f2.Body.UserData is Submarine) velocity -= ((Submarine)f2.Body.UserData).Velocity;
float impact = Vector2.Dot(avgVelocity, -normal);
Limb l = (Limb)f1.Body.UserData;
float impact = Vector2.Dot(velocity, -normal);
float volume = stairs == null ? impact / 5.0f : impact;
volume = Math.Min(impact, 1.0f);
if (impact > 0.5f && l.HitSound != null && l.soundTimer <= 0.0f)
float volume = Math.Min(impact, 1.0f);
if (f1.Body.UserData is Limb)
{
l.soundTimer = Limb.SoundInterval;
l.HitSound.Play(volume, impact * 250.0f, l.WorldPosition);
}
if (impact > l.impactTolerance)
{
if (!character.IsNetworkPlayer || GameMain.Server != null)
Limb limb = (Limb)f1.Body.UserData;
if (impact > 0.5f && limb.HitSound != null && limb.soundTimer <= 0.0f)
{
character.AddDamage(CauseOfDeath.Damage, impact - l.impactTolerance * 0.1f, null);
strongestImpact = Math.Max(strongestImpact, impact - l.impactTolerance);
limb.soundTimer = Limb.SoundInterval;
limb.HitSound.Play(volume, impact * 250.0f, limb.WorldPosition);
}
SoundPlayer.PlayDamageSound(DamageSoundType.LimbBlunt, strongestImpact, l.body);
}
else if (f1.Body == collider.FarseerBody)
{
if (!character.IsRemotePlayer || GameMain.Server != null)
{
if (impact > 8.0f)
{
character.AddDamage(CauseOfDeath.Damage, impact - 8.0f, null);
SoundPlayer.PlayDamageSound(DamageSoundType.LimbBlunt, strongestImpact, collider);
strongestImpact = Math.Max(strongestImpact, impact - 8.0f);
}
}
if (Character.Controlled == character) GameMain.GameScreen.Cam.Shake = strongestImpact;
}
@@ -446,6 +486,8 @@ namespace Barotrauma
public virtual void Draw(SpriteBatch spriteBatch)
{
if (simplePhysicsEnabled) return;
collider.UpdateDrawPosition();
foreach (Limb limb in Limbs)
{
@@ -467,17 +509,13 @@ namespace Barotrauma
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);
//if (limb.AnimTargetPos == Vector2.Zero) continue;
//Vector2 pos2 = ConvertUnits.ToDisplayUnits(limb.AnimTargetPos);
//pos2.Y = -pos2.Y;
//GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos2.X, (int)pos2.Y, 5, 5), Color.Blue, true, 0.01f);
//GUI.DrawLine(spriteBatch, pos, pos2, Color.Green);
}
limb.body.DebugDraw(spriteBatch, inWater ? Color.Cyan : Color.White);
}
collider.DebugDraw(spriteBatch, inWater ? Color.SkyBlue : Color.Gray);
foreach (RevoluteJoint joint in limbJoints)
{
Vector2 pos = ConvertUnits.ToDisplayUnits(joint.WorldAnchorA);
@@ -496,13 +534,35 @@ namespace Barotrauma
pos.Y = -pos.Y;
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X - 10, (int)pos.Y - 10, 20, 20), Color.Cyan, false, 0.01f);
GUI.DrawLine(spriteBatch, pos, new Vector2(limb.WorldPosition.X, -limb.WorldPosition.Y), limb == RefLimb ? Color.Orange : Color.Cyan);
GUI.DrawLine(spriteBatch, pos, new Vector2(limb.WorldPosition.X, -limb.WorldPosition.Y), Color.Cyan);
}
}
if (character.MemPos.Count > 1)
{
Vector2 prevPos = ConvertUnits.ToDisplayUnits(character.MemPos[0].Position);
if (currentHull != null) prevPos += currentHull.Submarine.DrawPosition;
prevPos.Y = -prevPos.Y;
for (int i = 1; i < character.MemPos.Count; i++ )
{
Vector2 currPos = ConvertUnits.ToDisplayUnits(character.MemPos[i].Position);
if (currentHull != null) currPos += currentHull.Submarine.DrawPosition;
currPos.Y = -currPos.Y;
GUI.DrawRectangle(spriteBatch, new Rectangle((int)currPos.X - 3, (int)currPos.Y - 3, 6, 6), Color.Cyan*0.6f, true, 0.01f);
GUI.DrawLine(spriteBatch, prevPos, currPos, Color.Cyan*0.6f, 0, 3);
prevPos = currPos;
}
}
if (ignorePlatforms)
{
GUI.DrawLine(spriteBatch, new Vector2(refLimb.WorldPosition.X, -refLimb.WorldPosition.Y), new Vector2(refLimb.WorldPosition.X, -refLimb.WorldPosition.Y+50), Color.Orange, 0, 5);
GUI.DrawLine(spriteBatch,
new Vector2(collider.DrawPosition.X, -collider.DrawPosition.Y),
new Vector2(collider.DrawPosition.X, -collider.DrawPosition.Y + 50),
Color.Orange, 0, 5);
}
}
@@ -555,20 +615,16 @@ namespace Barotrauma
return centerOfMass;
}
/// <summary>
///
/// </summary>
/// <param name="pullFromCenter">if false, force is applied to the position of pullJoint</param>
protected void MoveLimb(Limb limb, Vector2 pos, float amount, bool pullFromCenter = false)
{
limb.Move(pos, amount, pullFromCenter);
limb.MoveToPos(pos, amount, pullFromCenter);
}
public void ResetPullJoints()
{
for (int i = 0; i < Limbs.Count(); i++)
for (int i = 0; i < Limbs.Length; i++)
{
if (Limbs[i] == null || Limbs[i].pullJoint == null) continue;
Limbs[i].pullJoint.Enabled = false;
@@ -590,7 +646,7 @@ namespace Barotrauma
return;
}
Vector2 findPos = worldPosition==null ? refLimb.WorldPosition : (Vector2)worldPosition;
Vector2 findPos = worldPosition==null ? this.WorldPosition : (Vector2)worldPosition;
Hull newHull = Hull.FindHull(findPos, currentHull);
@@ -642,7 +698,6 @@ namespace Barotrauma
while (ce != null && ce.Contact != null)
{
ce.Contact.Enabled = false;
ce = ce.Next;
}
}
@@ -655,10 +710,10 @@ namespace Barotrauma
//character.Stun = 0.1f;
character.DisableImpactDamageTimer = 0.25f;
SetPosition(refLimb.SimPosition + moveAmount);
SetPosition(collider.SimPosition + moveAmount);
character.CursorPosition += moveAmount;
}
private void UpdateCollisionCategories()
{
Category wall = currentHull == null ?
@@ -669,6 +724,8 @@ namespace Barotrauma
wall | Physics.CollisionProjectile | Physics.CollisionStairs
: wall | Physics.CollisionProjectile | Physics.CollisionPlatform | Physics.CollisionStairs;
collider.CollidesWith = collisionCategory;
foreach (Limb limb in Limbs)
{
if (limb.ignoreCollisions) continue;
@@ -686,14 +743,13 @@ namespace Barotrauma
public void Update(Camera cam, float deltaTime)
{
if (!character.Enabled) return;
if (!character.Enabled || Frozen) return;
UpdateNetPlayerPosition();
UpdateNetPlayerPosition(deltaTime);
CheckDistFromCollider();
Vector2 flowForce = Vector2.Zero;
FindLowestLimb();
FindHull();
splashSoundTimer -= deltaTime;
@@ -711,10 +767,27 @@ namespace Barotrauma
inWater = false;
headInWater = false;
float waterSurface = ConvertUnits.ToSimUnits(currentHull.Surface);
float floorY = GetFloorY();
if (currentHull.Volume > currentHull.FullVolume * 0.95f ||
ConvertUnits.ToSimUnits(currentHull.Surface) - floorY > HeadPosition * 0.95f)
(waterSurface - floorY > HeadPosition * 0.95f && collider.SimPosition.Y < waterSurface))
inWater = true;
}
if (flowForce.LengthSquared() > 0.001f)
{
collider.ApplyForce(flowForce);
}
if (currentHull==null ||
currentHull.Volume > currentHull.FullVolume * 0.95f ||
ConvertUnits.ToSimUnits(currentHull.Surface) > collider.SimPosition.Y)
{
collider.ApplyWaterForces();
}
foreach (Limb limb in Limbs)
{
@@ -736,10 +809,9 @@ namespace Barotrauma
{
limb.inWater = true;
if (flowForce.Length() > 0.01f)
if (flowForce.LengthSquared() > 0.001f)
{
limb.body.ApplyForce(flowForce);
if (flowForce.Length() > 15.0f) surfaceY = limbHull.Surface;
}
surfaceY = limbHull.Surface;
@@ -747,7 +819,6 @@ namespace Barotrauma
if (limb.type == LimbType.Head)
{
headInWater = true;
surfaceY = limbHull.Surface;
}
}
//the limb has gone through the surface of the water
@@ -755,9 +826,9 @@ namespace Barotrauma
{
//create a splash particle
GameMain.ParticleManager.CreateParticle("watersplash",
var p = GameMain.ParticleManager.CreateParticle("watersplash",
new Vector2(limb.Position.X, limbHull.Surface) + limbHull.Submarine.Position,
new Vector2(0.0f, Math.Abs(-limb.LinearVelocity.Y * 10.0f)),
new Vector2(0.0f, Math.Abs(-limb.LinearVelocity.Y * 20.0f)),
0.0f, limbHull);
GameMain.ParticleManager.CreateParticle("bubbles",
@@ -787,27 +858,133 @@ 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()
{
Vector2 rayStart = collider.SimPosition;
Vector2 rayEnd = rayStart - new Vector2(0.0f, TorsoPosition);
var lowestLimb = FindLowestLimb();
float closestFraction = 1;
GameMain.World.RayCast((fixture, point, normal, fraction) =>
{
switch (fixture.CollisionCategories)
{
case Physics.CollisionStairs:
if (inWater && TargetMovement.Y < 0.5f) return -1;
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;
}
if (fraction < closestFraction)
{
closestFraction = fraction;
}
return closestFraction;
}
, rayStart, rayEnd);
if (closestFraction == 1) //raycast didn't hit anything
{
return (currentHull == null) ? -1000.0f : ConvertUnits.ToSimUnits(currentHull.Rect.Y - currentHull.Rect.Height);
}
else
{
return rayStart.Y + (rayEnd.Y - rayStart.Y) * closestFraction;
}
}
public void SetPosition(Vector2 simPosition, bool lerp = false)
{
Vector2 moveAmount = simPosition - refLimb.SimPosition;
Vector2 moveAmount = simPosition - collider.SimPosition;
collider.SetTransform(simPosition, collider.Rotation);
foreach (Limb limb in Limbs)
{
if (limb == refLimb)
{
TrySetLimbPosition(limb, simPosition, simPosition, lerp);
}
else
{
//check visibility from the new position of RefLimb to the new position of this limb
Vector2 movePos = limb.SimPosition + moveAmount;
TrySetLimbPosition(limb, simPosition, movePos, lerp);
}
//check visibility from the new position of the collider to the new position of this limb
Vector2 movePos = limb.SimPosition + moveAmount;
TrySetLimbPosition(limb, simPosition, movePos, lerp);
}
}
@@ -846,118 +1023,72 @@ namespace Barotrauma
}
}
public void SetRotation(float rotation)
private bool collisionsDisabled;
protected void CheckDistFromCollider()
{
float rotateAmount = rotation - refLimb.Rotation;
float allowedDist = Math.Max(Math.Max(collider.radius, collider.width), collider.height) * 2.0f;
Matrix rotationMatrix = Matrix.CreateRotationZ(rotateAmount);
refLimb.body.SetTransform(refLimb.SimPosition, rotation);
foreach (Limb limb in Limbs)
//if the ragdoll is too far from the collider, disable collisions until it's close enough
//(in case the ragdoll has gotten stuck somewhere)
if (Vector2.Distance(collider.SimPosition, MainLimb.SimPosition) > allowedDist)
{
if (limb == refLimb) continue;
if (!collisionsDisabled)
{
foreach (Limb limb in Limbs)
{
limb.body.CollidesWith = Physics.CollisionNone;
limb.body.ResetDynamics();
}
}
Vector2 newPos = limb.SimPosition - refLimb.SimPosition;
newPos = Vector2.Transform(newPos, rotationMatrix);
collisionsDisabled = true;
}
else if (collisionsDisabled)
{
//set the position of the ragdoll to make sure limbs don't get stuck inside walls when re-enabling collisions
SetPosition(collider.SimPosition, true);
TrySetLimbPosition(limb, refLimb.SimPosition, refLimb.SimPosition + newPos);
limb.body.SetTransform(limb.SimPosition, limb.Rotation + rotateAmount);
UpdateCollisionCategories();
collisionsDisabled = false;
}
}
private void UpdateNetPlayerPosition()
private void UpdateNetPlayerPosition(float deltaTime)
{
if (refLimb.body.TargetPosition == Vector2.Zero)
if (GameMain.NetworkMember == null) return;
if (character == GameMain.NetworkMember.Character)
{
correctionMovement = Vector2.Zero;
return;
}
//if (character.MemPos.Count < 2) return;
//if the limb is closer than alloweddistance, just ignore the difference
float allowedDistance = NetConfig.AllowedRagdollDistance * ((inWater) ? 2.0f : 1.0f);
//PosInfo serverPos = character.MemPos.Last();
if (currentHull == null)
{
var overLappingHull = Hull.FindHull(ConvertUnits.ToDisplayUnits(refLimb.body.TargetPosition), null, true);
//int localPosIndex = character.MemLocalPos.FindIndex(m => m.ID == serverPos.ID);
//if (localPosIndex > -1)
//{
// PosInfo localPos = character.MemLocalPos[localPosIndex];
if (overLappingHull != null)
{
Submarine.PickBody(refLimb.SimPosition, refLimb.body.TargetPosition, null, Physics.CollisionWall);
refLimb.body.TargetPosition = refLimb.SimPosition + (refLimb.body.TargetPosition - refLimb.SimPosition) * Submarine.LastPickedFraction * 0.9f;
}
}
// if (Vector2.Distance(localPos.Position, serverPos.Position) > 0.1f)
// {
// //collider.SetTransform(collider.SimPosition + (pos.Position - remotePos), collider.Rotation);
// collider.SetTransform(serverPos.Position, collider.Rotation);
// // character.MemLocalPos.RemoveRange(localPosIndex, character.MemLocalPos.Count - localPosIndex);
// }
//}
float dist = Vector2.Distance(refLimb.body.SimPosition, refLimb.body.TargetPosition);
//if the limb is further away than resetdistance, all limbs are immediately snapped to their targetpositions
bool resetAll = dist > NetConfig.ResetRagdollDistance;
Vector2 diff = (refLimb.body.TargetPosition - refLimb.body.SimPosition);
if (diff == Vector2.Zero || diff.Length() < allowedDistance)
{
refLimb.body.TargetPosition = Vector2.Zero;
foreach (Limb limb in Limbs)
{
limb.body.TargetPosition = Vector2.Zero;
}
correctionMovement = Vector2.Zero;
return;
}
if (resetAll)
{
System.Diagnostics.Debug.WriteLine("reset ragdoll limb positions");
SetPosition(refLimb.body.TargetPosition, dist < 10.0f);
return;
}
if (inWater)
{
if (targetMovement.LengthSquared() > 0.01f)
{
correctionMovement =
Vector2.Lerp(targetMovement, Vector2.Normalize(diff) * MathHelper.Clamp(dist * 5.0f, 0.1f, 5.0f), 0.2f);
}
else
{
refLimb.body.LinearVelocity = Vector2.Lerp(
refLimb.LinearVelocity,
Vector2.Normalize(diff) * MathHelper.Clamp(dist, 0.0f, 5.0f),
0.2f);
}
//if (character.MemLocalPos.Count > 120) character.MemLocalPos.RemoveRange(0, character.MemLocalPos.Count - 120);
//character.MemPos.Clear();
}
else
{
//clamp the magnitude of the correction movement between 0.5f - 5.0f
Vector2 newCorrectionMovement = Vector2.Normalize(diff) * MathHelper.Clamp(dist * 2.0f, 0.5f, 5.0f);
//heading in the right direction -> use the \"normal\" movement if it's faster than correctionMovement
//i.e. the character is close to the targetposition but the character is still running
if (Math.Sign(targetMovement.X) == Math.Sign(newCorrectionMovement.X))
{
newCorrectionMovement.X = Math.Max(Math.Abs(targetMovement.X), Math.Abs(newCorrectionMovement.X)) * Math.Sign(targetMovement.X);
}
correctionMovement = Vector2.Lerp(correctionMovement, newCorrectionMovement, 0.5f);
if (Math.Abs(correctionMovement.Y) < 0.1f) correctionMovement.Y = 0.0f;
collider.CorrectPosition(character.MemPos, deltaTime, out overrideTargetMovement);
}
}
public virtual Vector2 EstimateCurrPosition(Vector2 prevPosition, float timePassed)
{
return prevPosition;
}
private Vector2 GetFlowForce()
{
Vector2 limbPos = ConvertUnits.ToDisplayUnits(Limbs[0].SimPosition);
@@ -985,11 +1116,16 @@ namespace Barotrauma
limbDictionary.TryGetValue(limbType, out limb);
return limb;
}
public void FindLowestLimb()
public Vector2 GetColliderBottom()
{
//find the lowest limb
lowestLimb = null;
return collider.SimPosition - Vector2.UnitY * (collider.height / 2 + collider.radius);
}
public Limb FindLowestLimb()
{
Limb lowestLimb = null;
foreach (Limb limb in Limbs)
{
if (lowestLimb == null)
@@ -997,6 +1133,8 @@ namespace Barotrauma
else if (limb.SimPosition.Y < lowestLimb.SimPosition.Y)
lowestLimb = limb;
}
return lowestLimb;
}
public void Remove()
+142 -59
View File
@@ -14,13 +14,50 @@ using System.Xml.Linq;
namespace Barotrauma
{
struct PosInfo
{
public readonly Vector2 Position;
public readonly Direction Direction;
public readonly float Timestamp;
public readonly UInt32 ID;
public PosInfo(Vector2 pos, Direction dir, float time)
{
Position = pos;
Direction = dir;
Timestamp = time;
ID = 0;
}
public PosInfo(Vector2 pos, Direction dir, UInt32 ID)
{
Position = pos;
Direction = dir;
this.ID = ID;
Timestamp = 0.0f;
}
}
class Character : Entity, IDamageable, IPropertyObject
{
public static List<Character> CharacterList = new List<Character>();
public static bool DisableControls;
private UInt32 netStateID;
public UInt32 NetStateID
{
get { return netStateID; }
}
List<PosInfo> memPos = new List<PosInfo>();
private bool networkUpdateSent;
List<PosInfo> memLocalPos = new List<PosInfo>();
//the Character that the player is currently controlling
private static Character controlled;
@@ -61,9 +98,7 @@ namespace Barotrauma
public Hull PreviousHull = null;
public Hull CurrentHull = null;
public readonly bool IsNetworkPlayer;
private bool networkUpdateSent;
public readonly bool IsRemotePlayer;
private CharacterInventory inventory;
@@ -199,6 +234,17 @@ namespace Barotrauma
get { return Submarine == null ? cursorPosition : cursorPosition + Submarine.Position; }
}
public List<PosInfo> MemPos
{
get { return memPos; }
}
public List<PosInfo> MemLocalPos
{
get { return memLocalPos; }
}
public Character ClosestCharacter
{
get { return closestCharacter; }
@@ -289,6 +335,7 @@ namespace Barotrauma
set
{
if (!MathUtils.IsValid(value)) return;
health = MathHelper.Clamp(value, minHealth, maxHealth);
}
}
@@ -416,28 +463,28 @@ namespace Barotrauma
public override Vector2 SimPosition
{
get { return AnimController.RefLimb.SimPosition; }
get { return AnimController.Collider.SimPosition; }
}
public override Vector2 Position
{
get { return AnimController.RefLimb.Position; }
get { return ConvertUnits.ToDisplayUnits(SimPosition); }
}
public override Vector2 DrawPosition
{
get { return AnimController.RefLimb.body.DrawPosition; }
get { return AnimController.MainLimb.body.DrawPosition; }
}
public delegate void OnDeathHandler(Character character, CauseOfDeath causeOfDeath);
public OnDeathHandler OnDeath;
public static Character Create(CharacterInfo characterInfo, Vector2 position, bool isNetworkPlayer = false, bool hasAi=true)
public static Character Create(CharacterInfo characterInfo, Vector2 position, bool isRemotePlayer = false, bool hasAi=true)
{
return Create(characterInfo.File, position, characterInfo, isNetworkPlayer, hasAi);
return Create(characterInfo.File, position, characterInfo, isRemotePlayer, hasAi);
}
public static Character Create(string file, Vector2 position, CharacterInfo characterInfo = null, bool isNetworkPlayer = false, bool hasAi=true)
public static Character Create(string file, Vector2 position, CharacterInfo characterInfo = null, bool isRemotePlayer = false, bool hasAi=true)
{
#if LINUX
if (!System.IO.File.Exists(file))
@@ -470,7 +517,7 @@ namespace Barotrauma
if (file != humanConfigFile)
{
var enemyCharacter = new AICharacter(file, position, characterInfo, isNetworkPlayer);
var enemyCharacter = new AICharacter(file, position, characterInfo, isRemotePlayer);
var ai = new EnemyAIController(enemyCharacter, file);
enemyCharacter.SetAI(ai);
@@ -480,7 +527,7 @@ namespace Barotrauma
}
else if (hasAi)
{
var aiCharacter = new AICharacter(file, position, characterInfo, isNetworkPlayer);
var aiCharacter = new AICharacter(file, position, characterInfo, isRemotePlayer);
var ai = new HumanAIController(aiCharacter);
aiCharacter.SetAI(ai);
@@ -489,13 +536,13 @@ namespace Barotrauma
return aiCharacter;
}
var character = new Character(file, position, characterInfo, isNetworkPlayer);
var character = new Character(file, position, characterInfo, isRemotePlayer);
character.minHealth = -100.0f;
return character;
}
protected Character(string file, Vector2 position, CharacterInfo characterInfo = null, bool isNetworkPlayer = false)
protected Character(string file, Vector2 position, CharacterInfo characterInfo = null, bool isRemotePlayer = false)
: base(null)
{
@@ -512,7 +559,7 @@ namespace Barotrauma
hudProgressBars = new Dictionary<object, HUDProgressBar>();
IsNetworkPlayer = isNetworkPlayer;
IsRemotePlayer = isRemotePlayer;
oxygen = 100.0f;
oxygenAvailable = 100.0f;
@@ -545,15 +592,10 @@ namespace Barotrauma
{
AnimController = new FishAnimController(this, doc.Root.Element("ragdoll"));
PressureProtection = 100.0f;
//FishAnimController fishAnim = (FishAnimController)animController;
}
foreach (Limb limb in AnimController.Limbs)
{
limb.body.SetTransform(ConvertUnits.ToSimUnits(position)+limb.SimPosition, 0.0f);
//limb.prevPosition = ConvertUnits.ToDisplayUnits(position);
}
AnimController.SetPosition(ConvertUnits.ToSimUnits(position));
maxHealth = ToolBox.GetAttributeFloat(doc.Root, "health", 100.0f);
health = maxHealth;
@@ -705,8 +747,13 @@ namespace Barotrauma
if (length > 0.0f) targetMovement = targetMovement / length;
}
if (Math.Sign(targetMovement.X) == Math.Sign(AnimController.Dir) && IsKeyDown(InputType.Run))
if (AnimController is HumanoidAnimController &&
!((HumanoidAnimController)AnimController).Crouching &&
Math.Sign(targetMovement.X) != -Math.Sign(AnimController.Dir) &&
IsKeyDown(InputType.Run))
{
targetMovement *= 3.0f;
}
targetMovement *= SpeedMultiplier;
SpeedMultiplier = 1.0f;
@@ -745,6 +792,25 @@ namespace Barotrauma
}
}
//if (GameMain.Server != null && Character.Controlled != this)
//{
// if ((dequeuedInput & 0x10) > 0)
// {
// AnimController.TargetDir = Direction.Left;
// }
// else
// {
// AnimController.TargetDir = Direction.Right;
// }
//}
//else if (GameMain.Client != null && Character.controlled != this)
//{
// if (memPos.Count > 0)
// {
// AnimController.TargetDir = memPos[0].Direction;
// }
//}
if (attackCoolDown >0.0f)
{
attackCoolDown -= deltaTime;
@@ -832,7 +898,7 @@ namespace Barotrauma
}
if (IsNetworkPlayer)
if (IsRemotePlayer)
{
foreach (Key key in keys)
{
@@ -1032,6 +1098,18 @@ namespace Barotrauma
}
cam.OffsetAmount = MathHelper.Lerp(cam.OffsetAmount, (Submarine == null ? 400.0f : 250.0f)+pressureEffect, 0.05f);
}
if (GameMain.NetworkMember != null && GameMain.NetworkMember.Character == this)
{
if (memLocalPos.Count == 0 || NetTime.Now > memLocalPos.Last().Timestamp + 0.1f)
{
memLocalPos.Add(
new PosInfo(
SimPosition,
AnimController.Dir > 0.0f ? Direction.Right : Direction.Left,
(float)NetTime.Now));
}
}
cursorPosition = cam.ScreenToWorld(PlayerInput.MousePosition);
if (AnimController.CurrentHull != null && AnimController.CurrentHull.Submarine != null)
@@ -1133,7 +1211,8 @@ namespace Barotrauma
{
foreach (Character c in CharacterList)
{
if (c.isDead || c.health <= 0.0f || !c.Enabled) continue;
if (!c.Enabled) continue;
c.AnimController.UpdateAnim(deltaTime);
}
}
@@ -1309,7 +1388,7 @@ namespace Barotrauma
aiTarget.SightRange = 0.0f;
aiTarget.SightRange = Mass*10.0f + AnimController.RefLimb.LinearVelocity.Length()*500.0f;
aiTarget.SightRange = Mass*10.0f + AnimController.Collider.LinearVelocity.Length()*500.0f;
}
public void ShowSpeechBubble(float duration, Color color)
@@ -1519,7 +1598,7 @@ namespace Barotrauma
// limb.Damage = 100.0f;
}
SoundPlayer.PlayDamageSound(DamageSoundType.Implode, 50.0f, AnimController.RefLimb.body);
SoundPlayer.PlayDamageSound(DamageSoundType.Implode, 50.0f, AnimController.Collider);
for (int i = 0; i < 10; i++)
{
@@ -1988,7 +2067,6 @@ namespace Barotrauma
keys[(int)InputType.Crouch].Held = crouchState;
float dir = 1.0f;
Vector2 pos = Vector2.Zero;
@@ -2023,38 +2101,41 @@ namespace Barotrauma
pos.X = message.ReadFloat();
pos.Y = message.ReadFloat();
if (inSub != (Submarine != null))
{
AnimController.Teleport(pos - SimPosition, Vector2.Zero);
}
if (inSub != (Submarine != null))
{
AnimController.Teleport(pos - SimPosition, Vector2.Zero);
memPos.Clear();
}
if ((pos-SimPosition).Length()>600.0f)
{
AnimController.Teleport(pos - SimPosition, -AnimController.RefLimb.LinearVelocity);
}
if ((pos-SimPosition).Length()>600.0f)
{
AnimController.Teleport(pos - SimPosition, -AnimController.MainLimb.LinearVelocity);
memPos.Clear();
}
if (inSub)
{
//AnimController.FindHull(ConvertUnits.ToDisplayUnits(pos) - Submarine.Loaded.WorldPosition);
Submarine prevSub = Submarine;
if (inSub)
{
//AnimController.FindHull(ConvertUnits.ToDisplayUnits(pos) - Submarine.Loaded.WorldPosition);
Submarine prevSub = Submarine;
Hull newHull = Hull.FindHull(ConvertUnits.ToDisplayUnits(pos), AnimController.CurrentHull, false);
if (newHull != null)
{
AnimController.CurrentHull = newHull;
Submarine = newHull.Submarine;
}
Hull newHull = Hull.FindHull(ConvertUnits.ToDisplayUnits(pos), AnimController.CurrentHull, false);
if (newHull != null)
{
AnimController.CurrentHull = newHull;
Submarine = newHull.Submarine;
}
if (prevSub != null && Submarine != null && prevSub!=Submarine)
{
AnimController.Teleport(pos - SimPosition, Vector2.Zero);
}
}
else
{
AnimController.CurrentHull = null;
Submarine = null;
}
if (prevSub != null && Submarine != null && prevSub!=Submarine)
{
AnimController.Teleport(pos - SimPosition, Vector2.Zero);
memPos.Clear();
}
}
else
{
AnimController.CurrentHull = null;
Submarine = null;
}
if (secondaryKeyState)
{
@@ -2068,11 +2149,13 @@ namespace Barotrauma
{
cursorPosition = Position + new Vector2(1000.0f, 0.0f) * dir;
AnimController.TargetDir = dir < 0 ? Direction.Left : Direction.Right;
//AnimController.TargetDir = dir < 0 ? Direction.Left : Direction.Right;
}
AnimController.RefLimb.body.TargetPosition =
AnimController.EstimateCurrPosition(pos, (float)(NetTime.Now) - sendingTime);
//AnimController.RefLimb.body.TargetPosition =
// AnimController.EstimateCurrPosition(pos, (float)(NetTime.Now) - sendingTime);
memPos.Add(new PosInfo(pos, dir < 0 ? Direction.Left : Direction.Right, sendingTime));
LastNetworkUpdate = sendingTime;
+5 -70
View File
@@ -28,7 +28,6 @@ namespace Barotrauma
//the physics body of the limb
public PhysicsBody body;
private Texture2D bodyShapeTexture;
private readonly int refJointIndex;
@@ -73,11 +72,6 @@ namespace Barotrauma
private List<WearableSprite> wearingItems;
private Vector2 animTargetPos;
public Texture2D BodyShapeTexture
{
get { return bodyShapeTexture; }
}
public bool DoesFlip
{
@@ -334,7 +328,7 @@ namespace Barotrauma
}
}
public void Move(Vector2 pos, float amount, bool pullFromCenter=false)
public void MoveToPos(Vector2 pos, float force, bool pullFromCenter=false)
{
Vector2 pullPos = body.SimPosition;
if (pullJoint!=null && !pullFromCenter)
@@ -344,10 +338,7 @@ namespace Barotrauma
animTargetPos = pos;
Vector2 vel = body.LinearVelocity;
Vector2 deltaPos = pos - pullPos;
deltaPos *= amount;
body.ApplyLinearImpulse((deltaPos - vel * 0.5f) * body.Mass, pullPos);
body.MoveToPos(pos, force, pullPos);
}
public AttackResult AddDamage(Vector2 position, DamageType damageType, float amount, float bleedingAmount, bool playSound)
@@ -445,36 +436,12 @@ namespace Barotrauma
{
//DebugConsole.ThrowError("CHARACTER EXPLODED");
body.ResetDynamics();
body.SetTransform(character.AnimController.RefLimb.SimPosition, 0.0f);
body.SetTransform(character.SimPosition, 0.0f);
}
if (inWater)
{
//buoyancy
Vector2 buoyancy = new Vector2(0, Mass * 9.6f);
//drag
Vector2 velDir = Vector2.Normalize(LinearVelocity);
Vector2 line = new Vector2((float)Math.Cos(body.Rotation), (float)Math.Sin(body.Rotation));
line *= ConvertUnits.ToSimUnits(sprite.size.Y);
Vector2 normal = new Vector2(-line.Y, line.X);
normal = Vector2.Normalize(-normal);
float dragDot = Math.Abs(Vector2.Dot(normal, velDir));
Vector2 dragForce = Vector2.Zero;
if (dragDot > 0)
{
float vel = LinearVelocity.Length()*2.0f;
float drag = dragDot * vel * vel
* ConvertUnits.ToSimUnits(sprite.size.Y);
dragForce = Math.Min(drag, Mass*1000.0f) * -velDir;
//if (dragForce.Length() > 100.0f) { }
}
body.ApplyForce(dragForce + buoyancy);
body.ApplyTorque(body.AngularVelocity * body.Mass * -0.08f);
body.ApplyWaterForces();
}
if (character.IsDead) return;
@@ -585,34 +552,7 @@ namespace Barotrauma
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 5, 5), Color.Red, true);
}
if (bodyShapeTexture == null)
{
switch (body.BodyShape)
{
case PhysicsBody.Shape.Rectangle:
bodyShapeTexture = GUI.CreateRectangle(
(int)ConvertUnits.ToDisplayUnits(body.width),
(int)ConvertUnits.ToDisplayUnits(body.height));
break;
case PhysicsBody.Shape.Capsule:
bodyShapeTexture = GUI.CreateCapsule(
(int)ConvertUnits.ToDisplayUnits(body.radius),
(int)ConvertUnits.ToDisplayUnits(body.height));
break;
case PhysicsBody.Shape.Circle:
bodyShapeTexture = GUI.CreateCircle((int)ConvertUnits.ToDisplayUnits(body.radius));
break;
}
}
spriteBatch.Draw(
bodyShapeTexture,
new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
null,
character.Submarine!=null ? Color.White : Color.Cyan,
-body.DrawRotation,
new Vector2(bodyShapeTexture.Width / 2, bodyShapeTexture.Height / 2), 1.0f, SpriteEffects.None, 0.0f);
}
@@ -624,11 +564,6 @@ namespace Barotrauma
body.Remove();
if (bodyShapeTexture != null)
{
bodyShapeTexture.Dispose();
}
if (hitSound != null) hitSound.Remove();
}
}
+1 -1
View File
@@ -428,7 +428,7 @@ namespace Barotrauma
characterIndex = -1;
}
var matchingCharacters = Character.CharacterList.FindAll(c => !c.IsNetworkPlayer && c.Name.ToLowerInvariant() == characterName);
var matchingCharacters = Character.CharacterList.FindAll(c => !c.IsRemotePlayer && c.Name.ToLowerInvariant() == characterName);
if (!matchingCharacters.Any())
{
@@ -151,7 +151,7 @@ namespace Barotrauma.Items.Components
StopPicking(picker);
if (!picker.IsNetworkPlayer) OnPicked(picker);
if (!picker.IsRemotePlayer) OnPicked(picker);
yield return CoroutineStatus.Success;
}
@@ -71,23 +71,18 @@ namespace Barotrauma.Items.Components
if (character.AnimController.InWater) character.AnimController.TargetMovement = dir;
if (item.body.Enabled && false)
foreach (Limb limb in character.AnimController.Limbs)
{
item.body.ApplyForce(propulsion);
if (limb.WearingItems.Find(w => w.WearableComponent.Item == this.item)==null) continue;
limb.body.ApplyForce(propulsion);
}
else
{
foreach (Limb limb in character.AnimController.Limbs)
{
if (limb.WearingItems.Find(w => w.WearableComponent.Item == this.item)==null) continue;
limb.body.ApplyForce(propulsion);
}
character.AnimController.Collider.ApplyForce(propulsion);
if (character.SelectedItems[0] == item) character.AnimController.GetLimb(LimbType.RightHand).body.ApplyForce(propulsion);
if (character.SelectedItems[1] == item) character.AnimController.GetLimb(LimbType.LeftHand).body.ApplyForce(propulsion);
}
if (character.SelectedItems[0] == item) character.AnimController.GetLimb(LimbType.RightHand).body.ApplyForce(propulsion);
if (character.SelectedItems[1] == item) character.AnimController.GetLimb(LimbType.LeftHand).body.ApplyForce(propulsion);
if (!string.IsNullOrWhiteSpace(particles))
{
@@ -92,7 +92,7 @@ namespace Barotrauma.Items.Components
if (userPos != 0.0f)
{
float torsoX = ConvertUnits.ToDisplayUnits(character.AnimController.RefLimb.SimPosition.X);
float torsoX = character.Position.X;
Vector2 diff = new Vector2(item.Rect.X + UserPos - torsoX, 0.0f);
@@ -191,7 +191,7 @@ namespace Barotrauma.Items.Components
cam.OffsetAmount = MathHelper.Lerp(cam.OffsetAmount, (focusTarget as Item).Prefab.OffsetOnSelected, deltaTime*10.0f);
}
if (!character.IsNetworkPlayer || character.ViewTarget == focusTarget)
if (!character.IsRemotePlayer || character.ViewTarget == focusTarget)
{
item.SendSignal(0, ToolBox.Vector2ToString(character.CursorWorldPosition), "position_out");
}
@@ -49,19 +49,11 @@ namespace Barotrauma.Items.Components
{
IgnoredBodies = new List<Body>();
//launchImpulse = ToolBox.GetAttributeFloat(element, "launchimpulse", 10.0f);
//characterUsable = ToolBox.GetAttributeBool(element, "characterusable", false);
foreach (XElement subElement in element.Elements())
{
if (subElement.Name.ToString().ToLowerInvariant() != "attack") continue;
attack = new Attack(subElement);
}
//bleedingDamage = ToolBox.GetAttributeFloat(element, "bleedingdamage", 0.0f);
//bluntDamage = ToolBox.GetAttributeFloat(element, "bluntdamage", 0.0f);
//doesStick = ToolBox.GetAttributeBool(element, "doesstick", false);
}
public override bool Use(float deltaTime, Character character = null)
@@ -150,6 +142,11 @@ namespace Barotrauma.Items.Components
{
if (IgnoredBodies.Contains(f2.Body)) return false;
if (f2.CollisionCategories == Physics.CollisionCharacter && !(f2.Body.UserData is Limb))
{
return false;
}
AttackResult attackResult = new AttackResult(0.0f, 0.0f);
if (attack != null)
{
-1
View File
@@ -420,7 +420,6 @@ namespace Barotrauma
Structure structure = fixture.Body.UserData as Structure;
if (structure != null)
{
if (!structure.HasBody) return -1;
if (structure.IsPlatform && collisionCategory != null && !((Category)collisionCategory).HasFlag(Physics.CollisionPlatform)) return -1;
}
+5 -4
View File
@@ -434,7 +434,7 @@ namespace Barotrauma
{
Vector2 normal = Vector2.Normalize(Body.Position - limb.SimPosition);
float impact = Math.Min(Vector2.Dot(Velocity - limb.LinearVelocity, -normal), 5.0f);
float impact = Math.Min(Vector2.Dot(Velocity - limb.LinearVelocity, -normal), 50.0f) / 5.0f;
ApplyImpact(impact * Math.Min(limb.Mass / 200.0f, 1), -normal, contact);
}
@@ -497,8 +497,8 @@ namespace Barotrauma
FixedArray2<Vector2> points;
contact.GetWorldManifold(out normal2, out points);
Vector2 normalizedVel = limb.character.AnimController.RefLimb.LinearVelocity == Vector2.Zero ?
Vector2.Zero : Vector2.Normalize(limb.character.AnimController.RefLimb.LinearVelocity);
Vector2 normalizedVel = limb.character.AnimController.Collider.LinearVelocity == Vector2.Zero ?
Vector2.Zero : Vector2.Normalize(limb.character.AnimController.Collider.LinearVelocity);
Vector2 targetPos = ConvertUnits.ToDisplayUnits(points[0] - normal2);
@@ -558,9 +558,10 @@ namespace Barotrauma
foreach (Limb limb in c.AnimController.Limbs)
{
if (c.AnimController.LowestLimb == limb) continue;
limb.body.ApplyLinearImpulse(limb.Mass * impulse);
}
c.AnimController.Collider.ApplyLinearImpulse(c.AnimController.Collider.Mass * impulse);
}
foreach (Item item in Item.ItemList)
+1 -1
View File
@@ -664,7 +664,7 @@ namespace Barotrauma.Networking
List<Character> crew = new List<Character>();
foreach (Character c in Character.CharacterList)
{
if (!c.IsNetworkPlayer || !c.IsHumanoid || c.Info==null) continue;
if (!c.IsRemotePlayer || !c.IsHumanoid || c.Info==null) continue;
crew.Add(c);
}
+1 -1
View File
@@ -394,7 +394,7 @@ namespace Barotrauma.Networking
if (!(c is AICharacter) || c.IsDead) continue;
if (Character.CharacterList.Any(
c2 => c2.IsNetworkPlayer &&
c2 => c2.IsRemotePlayer &&
Vector2.Distance(c2.WorldPosition, c.WorldPosition) < ignoreDistance))
{
new NetworkEvent(NetworkEventType.EntityUpdate, c.ID, false);
-2
View File
@@ -6,8 +6,6 @@ namespace Barotrauma
{
static class Physics
{
private static double alpha;
public const Category CollisionNone = Category.None;
public const Category CollisionAll = Category.All;
public const Category CollisionWall = Category.Cat1;
+158 -8
View File
@@ -53,6 +53,8 @@ namespace Barotrauma
Vector2 offsetFromTargetPos;
private float netInterpolationState;
public Shape BodyShape
{
get { return bodyShape; }
@@ -118,10 +120,17 @@ namespace Barotrauma
set { dir = value; }
}
private bool isEnabled = true;
private bool isPhysEnabled = true;
public bool Enabled
{
get { return isEnabled; }
set { isEnabled = value; if (isEnabled) body.Enabled = isPhysEnabled; else body.Enabled = false; }
}
public bool PhysEnabled
{
get { return body.Enabled; }
set { body.Enabled = value; }
set { isPhysEnabled = value; if (Enabled) body.Enabled = value; }
}
public Vector2 SimPosition
@@ -192,6 +201,12 @@ namespace Barotrauma
set { body.CollidesWith = value; }
}
private Texture2D bodyShapeTexture;
public Texture2D BodyShapeTexture
{
get { return bodyShapeTexture; }
}
public PhysicsBody(XElement element, float scale = 1.0f)
: this(element, Vector2.Zero, scale)
{
@@ -227,7 +242,6 @@ namespace Barotrauma
body.Restitution = 0.05f;
body.BodyType = BodyType.Dynamic;
//body.AngularDamping = Limb.LimbAngularDamping;
body.UserData = this;
@@ -245,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);
@@ -322,11 +341,51 @@ namespace Barotrauma
}
body.SetTransform(targetPosition, targetRotation == 0.0f ? body.Rotation : targetRotation);
//body.LinearVelocity = targetVelocity;
//body.AngularVelocity = targetAngularVelocity;
targetPosition = Vector2.Zero;
}
public void MoveToPos(Vector2 pos, float force, Vector2? pullPos = null)
{
if (pullPos==null) pullPos = body.Position;
Vector2 vel = body.LinearVelocity;
Vector2 deltaPos = pos - (Vector2)pullPos;
deltaPos *= force;
body.ApplyLinearImpulse((deltaPos - vel * 0.5f) * body.Mass, (Vector2)pullPos);
}
/// <summary>
/// Applies buoyancy, drag and angular drag caused by water
/// </summary>
public void ApplyWaterForces()
{
//buoyancy
Vector2 buoyancy = new Vector2(0, Mass * 9.6f);
//drag
Vector2 velDir = Vector2.Normalize(LinearVelocity);
Vector2 line = new Vector2((float)Math.Cos(body.Rotation), (float)Math.Sin(body.Rotation));
line *= Math.Max(height + radius*2, height);
Vector2 normal = new Vector2(-line.Y, line.X);
normal = Vector2.Normalize(-normal);
float dragDot = Math.Abs(Vector2.Dot(normal, velDir));
Vector2 dragForce = Vector2.Zero;
if (dragDot > 0)
{
float vel = LinearVelocity.Length() * 2.0f;
float drag = dragDot * vel * vel
* Math.Max(height + radius * 2, height);
dragForce = Math.Min(drag, Mass * 1000.0f) * -velDir;
//if (dragForce.Length() > 100.0f) { }
}
body.ApplyForce(dragForce + buoyancy);
body.ApplyTorque(body.AngularVelocity * body.Mass * -0.08f);
}
public void UpdateDrawPosition()
{
@@ -361,10 +420,88 @@ namespace Barotrauma
color = Color.Blue;
}
sprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y), color, -drawRotation, scale, spriteEffect, depth);
sprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y), color, -drawRotation, scale, spriteEffect, depth);
}
public void DebugDraw(SpriteBatch spriteBatch, Color color)
{
if (bodyShapeTexture == null)
{
switch (BodyShape)
{
case PhysicsBody.Shape.Rectangle:
bodyShapeTexture = GUI.CreateRectangle(
(int)ConvertUnits.ToDisplayUnits(width),
(int)ConvertUnits.ToDisplayUnits(height));
break;
case PhysicsBody.Shape.Capsule:
bodyShapeTexture = GUI.CreateCapsule(
(int)ConvertUnits.ToDisplayUnits(radius),
(int)ConvertUnits.ToDisplayUnits(Math.Max(height,width)));
break;
case PhysicsBody.Shape.Circle:
bodyShapeTexture = GUI.CreateCircle((int)ConvertUnits.ToDisplayUnits(radius));
break;
}
}
float rot = -DrawRotation;
if (bodyShape == PhysicsBody.Shape.Capsule && width > height)
{
rot -= MathHelper.PiOver2;
}
spriteBatch.Draw(
bodyShapeTexture,
new Vector2(DrawPosition.X, -DrawPosition.Y),
null,
color,
rot,
new Vector2(bodyShapeTexture.Width / 2, bodyShapeTexture.Height / 2),
1.0f, SpriteEffects.None, 0.0f);
}
public void CorrectPosition(List<PosInfo> positionBuffer, float deltaTime, out Vector2 newVelocity)
{
newVelocity = Vector2.Zero;
if (positionBuffer.Count < 2) return;
PosInfo prev = positionBuffer[0];
PosInfo next = positionBuffer[1];
Vector2 currPos = SimPosition;
//interpolate the position of the collider from the first position in the buffer towards the second
if (prev.Timestamp < next.Timestamp)
{
//if there are more than 2 positions in the buffer,
//increase the interpolation speed to catch up with the server
float speedMultiplier = 1.0f + (float)Math.Pow((positionBuffer.Count - 2) / 2.0f, 2.0f);
netInterpolationState += (deltaTime * speedMultiplier) / (next.Timestamp - prev.Timestamp);
currPos = Vector2.Lerp(prev.Position, next.Position, netInterpolationState);
//override the targetMovement to make the character play the walking/running animation
newVelocity = (next.Position - prev.Position) / (next.Timestamp - prev.Timestamp);
}
else
{
currPos = next.Position;
netInterpolationState = 1.0f;
}
SetTransform(currPos, Rotation);
if (netInterpolationState >= 1.0f)
{
netInterpolationState = 0.0f;
positionBuffer.RemoveAt(0);
}
}
/// <summary>
/// rotate the body towards the target rotation in the "shortest direction"
/// </summary>
@@ -374,9 +511,16 @@ namespace Barotrauma
float angle = MathUtils.GetShortestAngle(nextAngle, targetRotation);
float torque = body.Mass * angle * 60.0f * (force/100.0f);
float torque = angle * 60.0f * (force/100.0f);
body.ApplyTorque(torque);
if (body.IsKinematic)
{
body.AngularVelocity = torque;
}
else
{
body.ApplyTorque(body.Mass * torque);
}
}
@@ -440,6 +584,12 @@ namespace Barotrauma
{
list.Remove(this);
GameMain.World.RemoveBody(body);
if (bodyShapeTexture != null)
{
bodyShapeTexture.Dispose();
bodyShapeTexture = null;
}
}
}
@@ -173,12 +173,12 @@ namespace Barotrauma
DrawJoints(spriteBatch, limb, limbBodyPos);
if (limb.BodyShapeTexture == null) continue;
//if (limb.BodyShapeTexture == null) continue;
spriteBatch.Draw(limb.BodyShapeTexture, limbBodyPos,
null, Color.White, 0.0f,
new Vector2(limb.BodyShapeTexture.Width, limb.BodyShapeTexture.Height) / 2,
1.0f, SpriteEffects.None, 0.0f);
//spriteBatch.Draw(limb.BodyShapeTexture, limbBodyPos,
// null, Color.White, 0.0f,
// new Vector2(limb.BodyShapeTexture.Width, limb.BodyShapeTexture.Height) / 2,
// 1.0f, SpriteEffects.None, 0.0f);
GUI.DrawLine(spriteBatch, limbBodyPos + Vector2.UnitY * 5.0f, limbBodyPos - Vector2.UnitY * 5.0f, Color.White);
GUI.DrawLine(spriteBatch, limbBodyPos + Vector2.UnitX * 5.0f, limbBodyPos - Vector2.UnitX * 5.0f, Color.White);
+1
View File
@@ -400,6 +400,7 @@ namespace Barotrauma
spriteBatch.Begin(SpriteSortMode.Immediate,
BlendState.AlphaBlend);
float r = Math.Min(CharacterHUD.damageOverlayTimer * 0.5f, 0.5f);
spriteBatch.Draw(renderTarget, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight),
Color.Lerp(new Color(0.1f, 0.1f, 0.1f), Color.Red, r));