Backported animcontroller-overhaul
This commit is contained in:
@@ -192,6 +192,29 @@ namespace FarseerPhysics.Factories
|
||||
return body;
|
||||
}
|
||||
|
||||
public static Body CreateCapsuleHorizontal(World world, float width, float endRadius, float density,
|
||||
object userData = null)
|
||||
{
|
||||
//Create the middle rectangle
|
||||
Vertices rectangle = PolygonTools.CreateRectangle(width / 2, endRadius);
|
||||
|
||||
List<Vertices> list = new List<Vertices>();
|
||||
list.Add(rectangle);
|
||||
|
||||
Body body = CreateCompoundPolygon(world, list, density, userData);
|
||||
body.UserData = userData;
|
||||
|
||||
//Create the two circles
|
||||
CircleShape topCircle = new CircleShape(endRadius, density);
|
||||
topCircle.Position = new Vector2(width / 2, 0);
|
||||
body.CreateFixture(topCircle);
|
||||
|
||||
CircleShape bottomCircle = new CircleShape(endRadius, density);
|
||||
bottomCircle.Position = new Vector2(-(width / 2), 0);
|
||||
body.CreateFixture(bottomCircle);
|
||||
return body;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a rounded rectangle.
|
||||
/// Note: Automatically decomposes the capsule if it contains too many vertices (controlled by Settings.MaxPolygonVertices)
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user