Backported animcontroller-overhaul

This commit is contained in:
Regalis
2016-10-22 15:18:16 +03:00
parent bb9b2c6eb7
commit 641e579e92
39 changed files with 1169 additions and 995 deletions
@@ -192,6 +192,29 @@ namespace FarseerPhysics.Factories
return body; 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> /// <summary>
/// Creates a rounded rectangle. /// Creates a rounded rectangle.
/// Note: Automatically decomposes the capsule if it contains too many vertices (controlled by Settings.MaxPolygonVertices) /// 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"> <ragdoll waveamplitude="150.0" wavelength="10000" swimspeed="4.0" scale="1.5" canentersubmarine="false">
<collider radius="100"/>
<!-- body --> <!-- body -->
<limb id = "0" radius="100" height="470" type="Torso" steerforce="1.0" pullpos="0,250"> <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"/> <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/scorpionidle1.ogg" state="None" />
<sound file="Content/Characters/Scorpion/scorpionidle2.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 --> <!-- head -->
<limb id = "0" radius="50" height="270" type="Head" steerforce="1.0" impacttolerance="50.0"> <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"/> <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"/> <sound file="Content/Characters/Crawler/idle2.ogg" state="None" range="500"/>
<ragdoll headposition="50" headangle="-70" <ragdoll headposition="50" headangle="-70"
waveamplitude="5.0" wavelength="5000" waveamplitude="2.0" wavelength="5000"
swimspeed="2.0" walkspeed="2.0" swimspeed="2.0" walkspeed="2.0"
stepsize ="15.0,20.0" stepsize ="15.0,20.0"
legtorque="10" legtorque="10"
flip="true"> flip="true">
<collider width="45" radius="22"/>
<!-- head --> <!-- 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"/> <sprite texture="Content/Characters/Crawler/crawler.png" sourcerect="0,0,51,121" depth="0.02" origin="0.45,0.63"/>
</limb> </limb>
<!-- middle part --> <!-- 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"/> <sprite texture="Content/Characters/Crawler/crawler.png" sourcerect="57,7,59,57" depth="0.021" origin="0.3,0.65"/>
</limb> </limb>
<!-- tail --> <!-- 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"/> <sprite texture="Content/Characters/Crawler/crawler.png" sourcerect="6,141,60,95" depth="0.022" origin="0.37,0.43"/>
</limb> </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"/> <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"/> <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>
<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"/> <sprite texture="Content/Characters/Crawler/crawler.png" sourcerect="82,83,11,34" depth="0.03" origin="0.5,0.5"/>
</limb> </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"/> <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"/> <sound file ="Content/Sounds/stepMetal.ogg"/>
</limb> </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"/> <sprite texture="Content/Characters/Crawler/crawler.png" sourcerect="82,83,11,34" depth="0.03" origin="0.5,0.5"/>
</limb> </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"/> <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"/> <sound file ="Content/Sounds/stepMetal.ogg"/>
</limb> </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"/> <sprite texture="Content/Characters/Crawler/crawler.png" sourcerect="82,83,11,34" depth="0.03" origin="0.5,0.5"/>
</limb> </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"/> <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"/> <sound file ="Content/Sounds/stepMetal.ogg"/>
</limb> </limb>
@@ -7,6 +7,8 @@
<ragdoll waveamplitude="100.0" wavelength="1000" speed="1.5" scale ="2.0" flip="false" canentersubmarine="false"> <ragdoll waveamplitude="100.0" wavelength="1000" speed="1.5" scale ="2.0" flip="false" canentersubmarine="false">
<collider radius="300"/>
<!-- head --> <!-- head -->
<limb id = "0" radius="300" type="Head" steerforce="3.0"> <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"/> <sprite texture="Content/Characters/Endworm/endworm.png" sourcerect="0,478,720,546" depth="0.05"/>
@@ -18,27 +20,27 @@
</limb> </limb>
<!-- body --> <!-- 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"/> <sprite texture="Content/Characters/Endworm/endworm.png" sourcerect="0,0,702,448" depth="0.02" origin="0.5,0.5"/>
</limb> </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"/> <sprite texture="Content/Characters/Endworm/endworm.png" sourcerect="0,0,702,448" depth="0.03" origin="0.5,0.5"/>
</limb> </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"/> <sprite texture="Content/Characters/Endworm/endworm.png" sourcerect="0,0,702,448" depth="0.04" origin="0.5,0.5"/>
</limb> </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"/> <sprite texture="Content/Characters/Endworm/endworm.png" sourcerect="0,0,702,448" depth="0.05" origin="0.5,0.5"/>
</limb> </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"/> <sprite texture="Content/Characters/Endworm/endworm.png" sourcerect="0,0,702,448" depth="0.06" origin="0.5,0.5"/>
</limb> </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"/> <sprite texture="Content/Characters/Endworm/endworm.png" sourcerect="704,0,320,400" depth="0.07" origin="0.5,0.5"/>
</limb> </limb>
@@ -6,10 +6,11 @@
<ragdoll waveamplitude="50.0" wavelength="500" swimspeed="3.0" walkspeed="0.3" flip="false" canentersubmarine="false"> <ragdoll waveamplitude="50.0" wavelength="500" swimspeed="3.0" walkspeed="0.3" flip="false" canentersubmarine="false">
<collider radius="50"/>
<!-- head --> <!-- head -->
<limb id = "0" radius="65" type="Head" steerforce="3.0" impacttolerance="100"> <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"/> <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> </limb>
<!-- body --> <!-- body -->
@@ -6,10 +6,12 @@
<ragdoll waveamplitude="0.0" swimspeed="1.0" walkspeed="0.3" flip="false" canentersubmarine="false" rotatetowardsmovement="false"> <ragdoll waveamplitude="0.0" swimspeed="1.0" walkspeed="0.3" flip="false" canentersubmarine="false" rotatetowardsmovement="false">
<collider radius="80" height="30"/>
<!-- head --> <!-- head -->
<limb id = "0" radius="80" height="30" type="Head" steerforce="3.0" impacttolerance="100"> <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"/> <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> </limb>
@@ -8,7 +8,11 @@
walkanimspeed="4.58" walkanimspeed="4.58"
movementlerp="0.4" movementlerp="0.4"
legtorque="15.0" legtorque="15.0"
thightorque="-5.0"> thightorque="-5.0"
walkspeed="1.5"
swimspeed="2.0">
<collider height="100" radius="15"/>
<!-- head --> <!-- head -->
<limb id = "0" radius="13" mass = "6" type="Head" attackpriority="2" impacttolerance="5.0"> <limb id = "0" radius="13" mass = "6" type="Head" attackpriority="2" impacttolerance="5.0">
+4 -2
View File
@@ -11,8 +11,10 @@
movementlerp="0.4" movementlerp="0.4"
legtorque="15.0" legtorque="15.0"
thightorque="-5.0" thightorque="-5.0"
walkspeed="2.0" walkspeed="1.2"
swimspeed="2.0"> swimspeed="2.5">
<collider height="100" radius="15"/>
<!-- head --> <!-- head -->
<limb id = "0" radius="13" mass = "6" type="Head" attackpriority="2" impacttolerance="5.0"> <limb id = "0" radius="13" mass = "6" type="Head" attackpriority="2" impacttolerance="5.0">
@@ -15,6 +15,8 @@
footrotation ="180.0" footrotation ="180.0"
flip="true"> flip="true">
<collider radius="60"/>
<!-- head --> <!-- 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"> <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"/> <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"> <ragdoll waveamplitude="0.0" swimspeed="1.0" walkspeed="0.3" mirror="true" rotatetowardsmovement="false" headangle="-90">
<collider radius ="230"/>
<!-- head --> <!-- 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"> <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"/> <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>
<limb id = "1" width="50" height="440" flip="true"> <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/scorpionidle1.ogg" state="None" />
<sound file="Content/Characters/Scorpion/scorpionidle2.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 --> <!-- head -->
<limb id = "0" radius="12" height="100" type="Head" steerforce="1.0" impacttolerance="50.0"> <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"/> <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"> <ragdoll waveamplitude="0.0" swimspeed="0.5" walkspeed="0.3" mirror="true" rotatetowardsmovement="false" headangle="-90">
<collider radius="100"/>
<!-- head --> <!-- 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"/> <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>
<limb id = "1" radius="50" height="120" flip="true"> <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"/> <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"> <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"/> <sprite texture="Content/Characters/Watcher/watcher.png" sourcerect="391,282,121,230" depth="0.025" origin="0.5,0.5"/>
</lightsource> </lightsource>
</limb> </limb>
<limb id = "2" width="300" height="119" flip="true"> <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"/> <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="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"/> <joint limb1="0" limb1anchor="72,110" limb2="2" limb2anchor="120,-20" lowerlimit="90" upperlimit="180"/>
</ragdoll> </ragdoll>
<ai attackhumans="0.0" attackrooms="0.0" sight="1.0" hearing="0.0" attackwhenprovoked="true"/> <ai attackhumans="0.0" attackrooms="0.0" sight="1.0" hearing="0.0" attackwhenprovoked="true"/>
@@ -41,7 +41,7 @@ namespace Barotrauma
public Vector2 Velocity public Vector2 Velocity
{ {
get { return Character.AnimController.RefLimb.LinearVelocity; } get { return Character.AnimController.Collider.LinearVelocity; }
} }
public AiState State public AiState State
@@ -71,36 +71,21 @@ namespace Barotrauma
steeringManager.Update(moveSpeed); 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)); (-Character.AnimController.TargetMovement.Y > Math.Abs(Character.AnimController.TargetMovement.X));
var currPath = (steeringManager as IndoorsSteeringManager).CurrentPath; var currPath = (steeringManager as IndoorsSteeringManager).CurrentPath;
if (currPath != null && currPath.CurrentNode != null) 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; 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);
}
} }
} }
Character.AnimController.IgnorePlatforms = ignorePlatforms;
(Character.AnimController as HumanoidAnimController).Crouching = false; (Character.AnimController as HumanoidAnimController).Crouching = false;
if (!Character.AnimController.InWater) if (!Character.AnimController.InWater)
{ {
Character.AnimController.TargetMovement = new Vector2( Character.AnimController.TargetMovement = new Vector2(
@@ -88,6 +88,15 @@ namespace Barotrauma
Vector2 diff = DiffToCurrentNode(); 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; if (diff == Vector2.Zero) return -host.Steering;
return Vector2.Normalize(diff) * speed; return Vector2.Normalize(diff) * speed;
@@ -95,7 +104,7 @@ namespace Barotrauma
private Vector2 DiffToCurrentNode() private Vector2 DiffToCurrentNode()
{ {
if (currentPath == null || currentPath.Finished) return Vector2.Zero; if (currentPath == null || currentPath.Finished || currentPath.Unreachable) return Vector2.Zero;
if (currentPath.Finished) if (currentPath.Finished)
{ {
@@ -111,7 +120,7 @@ namespace Barotrauma
if (canOpenDoors && !character.LockHands) CheckDoorsInPath(); if (canOpenDoors && !character.LockHands) CheckDoorsInPath();
float allowedDistance = character.AnimController.InWater ? 1.0f : 0.6f; 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; 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; if (currentPath.CurrentNode == null) return Vector2.Zero;
@@ -147,20 +164,31 @@ namespace Barotrauma
if (character.AnimController.Anim == AnimController.Animation.Climbing) if (character.AnimController.Anim == AnimController.Animation.Climbing)
{ {
float x = currentPath.CurrentNode.SimPosition.X - pos.X; Vector2 diff = currentPath.CurrentNode.SimPosition - pos;
float y = (currentPath.CurrentNode.SimPosition.Y) - pos.Y;
if (Math.Abs(x) < Math.Abs(y) * 10.0f) if (currentPath.CurrentNode.Ladders != null)
{ {
x = 0.0f; //climbing ladders -> don't move horizontally
} diff.X = 0.0f;
else if (character.AnimController.LowestLimb != null && hull != null)
{ //at the same height as the waypoint
if (character.AnimController.LowestLimb.Position.Y < hull.Rect.Y - hull.Rect.Height + 10.0f) x = 0.0f; 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; character.AnimController.IgnorePlatforms = false;
return new Vector2(x,y); return diff;
} }
return currentPath.CurrentNode.SimPosition - pos; return currentPath.CurrentNode.SimPosition - pos;
@@ -90,11 +90,12 @@ namespace Barotrauma
escapeObjective.TryComplete(deltaTime); escapeObjective.TryComplete(deltaTime);
if (Vector2.Distance(character.SimPosition, enemy.SimPosition) < 3.0f) //if (Vector2.Distance(character.SimPosition, enemy.SimPosition) < 3.0f)
{ //{
character.AIController.SteeringManager.SteeringManual(deltaTime, (character.SimPosition - enemy.SimPosition)*0.1f); // character.AIController.SteeringManager.SteeringManual(deltaTime,
coolDownTimer = CoolDown; // new Vector2(Math.Sign(character.SimPosition.X - enemy.SimPosition.X), 0.0f));
} // coolDownTimer = CoolDown;
//}
} }
public override bool IsCompleted() 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 searching for a path inside the sub, make sure the waypoint is visible
if (insideSubmarine) if (insideSubmarine)
{ {
var body = Submarine.CheckVisibility(start, node.Waypoint.SimPosition); var body = Submarine.PickBody(
if (body != null && body.UserData is Structure) continue; 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; closestDist = dist;
@@ -62,6 +62,13 @@ namespace Barotrauma
public virtual void Update(float speed = 1.0f) 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(); float steeringSpeed = steering.Length();
if (steeringSpeed>speed) if (steeringSpeed>speed)
{ {
+10 -10
View File
@@ -95,8 +95,8 @@ namespace Barotrauma
return true; return true;
case NetworkEventType.ImportantEntityUpdate: case NetworkEventType.ImportantEntityUpdate:
message.Write(AnimController.RefLimb.SimPosition.X); message.Write(AnimController.MainLimb.SimPosition.X);
message.Write(AnimController.RefLimb.SimPosition.Y); message.Write(AnimController.MainLimb.SimPosition.Y);
//message.Write(AnimController.RefLimb.Rotation); //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); message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.Y, -1.0f, 1.0f), -1.0f, 1.0f, 4);
if (AnimController.CanEnterSubmarine) message.Write(Submarine != null); if (AnimController.CanEnterSubmarine) message.Write(Submarine != null);
message.Write(AnimController.RefLimb.SimPosition.X); message.Write(AnimController.MainLimb.SimPosition.X);
message.Write(AnimController.RefLimb.SimPosition.Y); message.Write(AnimController.MainLimb.SimPosition.Y);
return true; return true;
case NetworkEventType.InventoryUpdate: case NetworkEventType.InventoryUpdate:
@@ -162,8 +162,8 @@ namespace Barotrauma
return base.ReadNetworkData(type, message, sendingTime, out data); return base.ReadNetworkData(type, message, sendingTime, out data);
case NetworkEventType.ImportantEntityUpdate: case NetworkEventType.ImportantEntityUpdate:
Vector2 limbPos = AnimController.RefLimb.SimPosition; Vector2 limbPos = AnimController.MainLimb.SimPosition;
float rotation = AnimController.RefLimb.Rotation; float rotation = AnimController.MainLimb.Rotation;
try try
{ {
@@ -180,9 +180,9 @@ namespace Barotrauma
return false; 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; //AnimController.RefLimb.body.TargetRotation = rotation;
} }
@@ -255,7 +255,7 @@ namespace Barotrauma
AnimController.TargetDir = (targetDir) ? Direction.Right : Direction.Left; AnimController.TargetDir = (targetDir) ? Direction.Right : Direction.Left;
AnimController.TargetMovement = targetMovement; AnimController.TargetMovement = targetMovement;
AnimController.RefLimb.body.TargetPosition = pos; AnimController.MainLimb.body.TargetPosition = pos;
//AnimController.EstimateCurrPosition(pos, (float)(NetTime.Now) - sendingTime); //AnimController.EstimateCurrPosition(pos, (float)(NetTime.Now) - sendingTime);
if (inSub) if (inSub)
@@ -1,6 +1,7 @@
using System.Xml.Linq; using System.Xml.Linq;
using FarseerPhysics; using FarseerPhysics;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using System.Collections.Generic;
namespace Barotrauma namespace Barotrauma
{ {
@@ -9,8 +10,6 @@ namespace Barotrauma
public enum Animation { None, Climbing, UsingConstruction, Struggle, CPR }; public enum Animation { None, Climbing, UsingConstruction, Struggle, CPR };
public Animation Anim; public Animation Anim;
public Direction TargetDir;
protected Character character; protected Character character;
protected float walkSpeed, swimSpeed; protected float walkSpeed, swimSpeed;
@@ -25,6 +24,8 @@ namespace Barotrauma
protected readonly Vector2 stepSize; protected readonly Vector2 stepSize;
protected readonly float legTorque; protected readonly float legTorque;
public float StunTimer public float StunTimer
{ {
get { return stunTimer; } get { return stunTimer; }
@@ -52,6 +53,8 @@ namespace Barotrauma
//impactTolerance = ToolBox.GetAttributeFloat(element, "impacttolerance", 10.0f); //impactTolerance = ToolBox.GetAttributeFloat(element, "impacttolerance", 10.0f);
legTorque = ToolBox.GetAttributeFloat(element, "legtorque", 0.0f); legTorque = ToolBox.GetAttributeFloat(element, "legtorque", 0.0f);
} }
public virtual void UpdateAnim(float deltaTime) { } 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 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) { } 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) 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; 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(); ResetPullJoints();
if (strongestImpact > 0.0f) if (strongestImpact > 0.0f)
@@ -61,31 +83,32 @@ namespace Barotrauma
strongestImpact = 0.0f; strongestImpact = 0.0f;
} }
if (stunTimer>0.0f)
if (inWater)
{ {
//UpdateStruggling(deltaTime); collider.FarseerBody.FixedRotation = false;
stunTimer -= deltaTime; UpdateSineAnim(deltaTime);
return;
} }
else if (SimplePhysicsEnabled) else if (currentHull != null && CanEnterSubmarine)
{ {
UpdateSimpleAnim(); if (Math.Abs(MathUtils.GetShortestAngle(collider.Rotation, 0.0f)) > 0.001f)
}
else
{
if (inWater || RefLimb.inWater)
{ {
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 (mirror || !inWater)
{ {
if (!character.IsNetworkPlayer) if (!character.IsRemotePlayer)
{ {
//targetDir = (movement.X > 0.0f) ? Direction.Right : Direction.Left; //targetDir = (movement.X > 0.0f) ? Direction.Right : Direction.Left;
if (targetMovement.X > 0.1f && targetMovement.X > Math.Abs(targetMovement.Y) * 0.5f) if (targetMovement.X > 0.1f && targetMovement.X > Math.Abs(targetMovement.Y) * 0.5f)
@@ -125,10 +148,10 @@ namespace Barotrauma
if (TargetDir != dir) if (TargetDir != dir)
{ {
if (flipTimer>1.0f || character.IsNetworkPlayer) if (flipTimer>1.0f || character.IsRemotePlayer)
{ {
Flip(); Flip();
if (mirror) Mirror(); if (mirror || !inWater) Mirror();
flipTimer = 0.0f; flipTimer = 0.0f;
} }
} }
@@ -137,11 +160,27 @@ namespace Barotrauma
void UpdateSineAnim(float deltaTime) void UpdateSineAnim(float deltaTime)
{ {
movement = TargetMovement*swimSpeed; 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 (movement.LengthSquared() < 0.00001f) return;
if (!inWater) movement.Y = Math.Min(0.0f, movement.Y);
float movementAngle = MathUtils.VectorToAngle(movement) - MathHelper.PiOver2; 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); Limb tail = GetLimb(LimbType.Tail);
if (tail != null && waveAmplitude > 0.0f) if (tail != null && waveAmplitude > 0.0f)
@@ -151,100 +190,28 @@ namespace Barotrauma
float waveRotation = (float)Math.Sin(walkPos / waveLength); float waveRotation = (float)Math.Sin(walkPos / waveLength);
tail.body.ApplyTorque(waveRotation * tail.Mass * 100.0f * waveAmplitude); 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++) 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(movement * Limbs[i].SteerForce * Limbs[i].Mass, pullPos);
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);
} if (Limbs[i] == MainLimb) continue;
if (Limbs[i].type != LimbType.Torso) 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); 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( collider.LinearVelocity = Vector2.Lerp(collider.LinearVelocity, movement, 0.5f);
(rotateTowardsMovement) ?
RefLimb.body.Rotation + MathUtils.GetShortestAngle(RefLimb.body.Rotation, movementAngle) : floorY = Limbs[0].SimPosition.Y;
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);
}
} }
void UpdateWalkAnim(float deltaTime) void UpdateWalkAnim(float deltaTime)
{ {
movement = MathUtils.SmoothStep(movement, TargetMovement * walkSpeed, 0.2f); movement = MathUtils.SmoothStep(movement, TargetMovement * walkSpeed, 0.2f);
@@ -252,102 +219,30 @@ namespace Barotrauma
IgnorePlatforms = (TargetMovement.Y < -Math.Abs(TargetMovement.X)); IgnorePlatforms = (TargetMovement.Y < -Math.Abs(TargetMovement.X));
Limb colliderLimb; float mainLimbHeight, mainLimbAngle;
float colliderHeight; if (MainLimb.type == LimbType.Torso)
Limb torso = GetLimb(LimbType.Torso);
Limb head = GetLimb(LimbType.Head);
if (torso != null)
{ {
colliderLimb = torso; mainLimbHeight = TorsoPosition;
colliderHeight = TorsoPosition; mainLimbAngle = torsoAngle;
colliderLimb.body.SmoothRotate(TorsoAngle * Dir, 10.0f);
} }
else else
{ {
colliderLimb = head; mainLimbHeight = HeadPosition;
colliderHeight = HeadPosition; mainLimbAngle = headAngle;
if (onGround) colliderLimb.body.SmoothRotate(HeadAngle * Dir, 100.0f);
} }
MainLimb.body.SmoothRotate(mainLimbAngle * Dir, 50.0f);
Vector2 colliderPos = colliderLimb.SimPosition; collider.LinearVelocity = new Vector2(
movement.X,
collider.LinearVelocity.Y > 0.0f ? collider.LinearVelocity.Y * 0.5f : collider.LinearVelocity.Y);
Vector2 rayStart = colliderPos; MainLimb.MoveToPos(GetColliderBottom() + Vector2.UnitY * mainLimbHeight, 10.0f);
Vector2 rayEnd = rayStart - new Vector2(0.0f, colliderHeight);
if (stairs != null) rayEnd.Y -= 0.5f; MainLimb.pullJoint.Enabled = true;
MainLimb.pullJoint.WorldAnchorB = GetColliderBottom() + Vector2.UnitY * mainLimbHeight;
//do a raytrace straight down from the torso to figure walkPos -= MainLimb.LinearVelocity.X * 0.05f;
//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;
Vector2 transformedStepSize = new Vector2( Vector2 transformedStepSize = new Vector2(
(float)Math.Cos(walkPos) * stepSize.X * 3.0f, (float)Math.Cos(walkPos) * stepSize.X * 3.0f,
@@ -359,7 +254,7 @@ namespace Barotrauma
{ {
case LimbType.LeftFoot: case LimbType.LeftFoot:
case LimbType.RightFoot: 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) if (limb.RefJointIndex>-1)
{ {
@@ -371,25 +266,25 @@ namespace Barotrauma
if (limb.type == LimbType.LeftFoot) if (limb.type == LimbType.LeftFoot)
{ {
limb.Move(footPos +new Vector2( limb.MoveToPos(footPos +new Vector2(
transformedStepSize.X + movement.X * 0.1f, transformedStepSize.X + movement.X * 0.1f,
(transformedStepSize.Y > 0.0f) ? transformedStepSize.Y : 0.0f), (transformedStepSize.Y > 0.0f) ? transformedStepSize.Y : 0.0f),
8.0f); 8.0f);
} }
else if (limb.type == LimbType.RightFoot) else if (limb.type == LimbType.RightFoot)
{ {
limb.Move(footPos +new Vector2( limb.MoveToPos(footPos + new Vector2(
-transformedStepSize.X + movement.X * 0.1f, -transformedStepSize.X + movement.X * 0.1f,
(-transformedStepSize.Y > 0.0f) ? -transformedStepSize.Y : 0.0f), (-transformedStepSize.Y > 0.0f) ? -transformedStepSize.Y : 0.0f),
8.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; break;
case LimbType.LeftLeg: case LimbType.LeftLeg:
case LimbType.RightLeg: 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; 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() private void Mirror()
{ {
//float leftX = Limbs[0].SimPosition.X, rightX = Limbs[0].SimPosition.X; Vector2 centerOfMass = GetCenterOfMass();
//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;
foreach (Limb l in Limbs) foreach (Limb l in Limbs)
{ {
Vector2 newPos = new Vector2(midX - (l.SimPosition.X - midX), l.SimPosition.Y); TrySetLimbPosition(l,
centerOfMass,
if (Submarine.CheckVisibility(l.SimPosition, newPos) != null) new Vector2(centerOfMass.X - (l.SimPosition.X - centerOfMass.X), l.SimPosition.Y),
{ true);
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);
}
} }
} }
@@ -44,10 +44,10 @@ namespace Barotrauma
{ {
get get
{ {
return Crouching ? base.TorsoAngle+0.5f : base.TorsoAngle; return Crouching ? base.TorsoAngle + 0.5f : base.TorsoAngle;
} }
} }
public HumanoidAnimController(Character character, XElement element) public HumanoidAnimController(Character character, XElement element)
: base(character, element) : base(character, element)
{ {
@@ -61,111 +61,68 @@ namespace Barotrauma
public override void UpdateAnim(float deltaTime) public override void UpdateAnim(float deltaTime)
{ {
if (character.IsDead) return; if (Frozen) 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 (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 //stun (= disable the animations) if the ragdoll receives a large enough impact
if (strongestImpact > 0.0f) if (strongestImpact > 0.0f)
{ {
character.StartStun(MathHelper.Min(strongestImpact * 0.5f, 5.0f)); character.StartStun(MathHelper.Min(strongestImpact * 0.5f, 5.0f));
} strongestImpact = 0.0f;
strongestImpact = 0.0f;
if (stunTimer > 0)
{
stunTimer -= deltaTime;
return; 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) if (character.LockHands)
{ {
var leftHand = GetLimb(LimbType.LeftHand); var leftHand = GetLimb(LimbType.LeftHand);
@@ -178,37 +135,31 @@ namespace Barotrauma
Vector2 midPos = waist.SimPosition; Vector2 midPos = waist.SimPosition;
Matrix torsoTransform = Matrix.CreateRotationZ(waist.Rotation); 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; if (rightHand.pullJoint.Enabled) midPos = (midPos + rightHand.pullJoint.WorldAnchorB) / 2.0f;
HandIK(rightHand, midPos); HandIK(rightHand, midPos);
HandIK(leftHand, midPos); HandIK(leftHand, midPos);
//rightHand.pullJoint.Enabled = true;
//rightHand.pullJoint.WorldAnchorB = midPos;
//rightHand.pullJoint.Enabled = true;
//rightHand.pullJoint.WorldAnchorB = midPos;
} }
else else
{ {
if (Anim != Animation.UsingConstruction) ResetPullJoints(); if (Anim != Animation.UsingConstruction) ResetPullJoints();
} }
if (SimplePhysicsEnabled) if (SimplePhysicsEnabled)
{ {
UpdateStandingSimple(); UpdateStandingSimple();
return; return;
} }
switch (Anim) switch (Anim)
{ {
case Animation.Climbing: case Animation.Climbing:
@@ -223,12 +174,12 @@ namespace Barotrauma
default: default:
if (character.SelectedCharacter != null) DragCharacter(character.SelectedCharacter); if (character.SelectedCharacter != null) DragCharacter(character.SelectedCharacter);
//0.5 second delay for switching between swimming and walking //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 //prevents rapid switches between swimming/walking if the water level is fluctuating around the minimum swimming depth
if (inWater) if (inWater)
{ {
inWaterTimer = Math.Max(inWaterTimer+deltaTime, 0.5f); inWaterTimer = Math.Max(inWaterTimer + deltaTime, 0.5f);
if (inWaterTimer >= 1.0f) swimming = true; if (inWaterTimer >= 1.0f) swimming = true;
} }
else else
@@ -257,6 +208,7 @@ namespace Barotrauma
} }
aiming = false; 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 //if you're allergic to magic numbers, stop reading now
Limb leftFoot = GetLimb(LimbType.LeftFoot); Limb leftFoot = GetLimb(LimbType.LeftFoot);
Limb rightFoot = GetLimb(LimbType.RightFoot); Limb rightFoot = GetLimb(LimbType.RightFoot);
Limb head = GetLimb(LimbType.Head); Limb head = GetLimb(LimbType.Head);
Limb torso = GetLimb(LimbType.Torso); Limb torso = GetLimb(LimbType.Torso);
Limb waist = GetLimb(LimbType.Waist); Limb waist = GetLimb(LimbType.Waist);
Limb leftHand = GetLimb(LimbType.LeftHand); Limb leftHand = GetLimb(LimbType.LeftHand);
Limb rightHand = GetLimb(LimbType.RightHand); 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 getUpSpeed = 0.3f;
float walkCycleSpeed = head.LinearVelocity.X * walkAnimSpeed; float walkCycleSpeed = movement.X * walkAnimSpeed;
if (stairs != null) if (stairs != null)
{ {
TargetMovement = new Vector2(MathHelper.Clamp(TargetMovement.X, -1.5f, 1.5f), TargetMovement.Y); 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.X < 0.0f && stairs.StairDirection == Direction.Left)
{ {
TargetMovement *= 1.7f; 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) if (Math.Abs(TargetMovement.X) > 1.0f)
{ {
int limbsInWater = 0; int limbsInWater = 0;
@@ -312,24 +258,27 @@ namespace Barotrauma
float slowdownFactor = (float)limbsInWater / (float)Limbs.Count(); float slowdownFactor = (float)limbsInWater / (float)Limbs.Count();
float maxSpeed = Math.Max(TargetMovement.Length() - slowdownFactor, 1.0f); 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; TargetMovement = Vector2.Normalize(TargetMovement) * maxSpeed;
} }
float walkPosX = (float)Math.Cos(walkPos); float walkPosX = (float)Math.Cos(walkPos);
float walkPosY = (float)Math.Sin(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( Vector2 stepSize = new Vector2(
this.stepSize.X * walkPosX * runningModifier, this.stepSize.X * walkPosX * runningModifier,
this.stepSize.Y * walkPosY * runningModifier * runningModifier); this.stepSize.Y * walkPosY * runningModifier * runningModifier);
if (Crouching) stepSize *= 0.5f; if (Crouching) stepSize *= 0.5f;
float footMid = waist.SimPosition.X;// (leftFoot.SimPosition.X + rightFoot.SimPosition.X) / 2.0f; float footMid = colliderPos.X;// (leftFoot.SimPosition.X + rightFoot.SimPosition.X) / 2.0f;
movement = MathUtils.SmoothStep(movement, TargetMovement*walkSpeed, movementLerp); movement = overrideTargetMovement == Vector2.Zero ?
MathUtils.SmoothStep(movement, TargetMovement * walkSpeed, movementLerp) :
overrideTargetMovement;
movement.Y = 0.0f; movement.Y = 0.0f;
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
@@ -354,17 +303,12 @@ namespace Barotrauma
} }
} }
if (LowestLimb == null) return; if (onGround && (!character.IsRemotePlayer || GameMain.Server != null))
{
if (!onGround || (LowestLimb.SimPosition.Y - floorY > 0.5f && stairs == null)) return; collider.LinearVelocity = new Vector2(
movement.X,
//float? ceilingY = null; collider.LinearVelocity.Y > 0.0f ? collider.LinearVelocity.Y * 0.5f : collider.LinearVelocity.Y);
//if (Submarine.PickBody(head.SimPosition, head.SimPosition + Vector2.UnitY, null, Physics.CollisionWall)!=null) }
//{
// ceilingY = Submarine.LastPickedPosition.Y;
// if (ceilingY - floorY < HeadPosition) Crouching = true;
//}
getUpSpeed = getUpSpeed * Math.Max(head.SimPosition.Y - colliderPos.Y, 0.5f); getUpSpeed = getUpSpeed * Math.Max(head.SimPosition.Y - colliderPos.Y, 0.5f);
@@ -374,32 +318,43 @@ namespace Barotrauma
if (stairs != null) if (stairs != null)
{ {
if (LowestLimb.SimPosition.Y < stairs.SimPosition.Y) IgnorePlatforms = true;
torso.pullJoint.WorldAnchorB = new Vector2( 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)); MathHelper.SmoothStep(torso.SimPosition.Y, colliderPos.Y + TorsoPosition - Math.Abs(walkPosX * 0.05f), getUpSpeed * 2.0f));
head.pullJoint.WorldAnchorB = new Vector2( 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)); MathHelper.SmoothStep(head.SimPosition.Y, colliderPos.Y + HeadPosition - Math.Abs(walkPosX * 0.05f), getUpSpeed * 2.0f));
waist.pullJoint.WorldAnchorB = waist.SimPosition;// +movement * 0.3f; waist.pullJoint.WorldAnchorB = waist.SimPosition;// +movement * 0.3f;
} }
else else
{ {
if (!onGround) movement = Vector2.Zero;
torso.pullJoint.WorldAnchorB = torso.pullJoint.WorldAnchorB =
MathUtils.SmoothStep(torso.SimPosition, 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 = head.pullJoint.WorldAnchorB =
MathUtils.SmoothStep(head.SimPosition, 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 //moving horizontally
if (TargetMovement.X != 0.0f) if (TargetMovement.X != 0.0f)
@@ -461,7 +416,7 @@ namespace Barotrauma
HandIK(rightHand, torso.SimPosition + posAddition + HandIK(rightHand, torso.SimPosition + posAddition +
new Vector2( new Vector2(
-handPos.X, -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) if (!leftHand.Disabled)
@@ -506,7 +461,7 @@ namespace Barotrauma
var leftArm = GetLimb(LimbType.LeftArm); var leftArm = GetLimb(LimbType.LeftArm);
leftArm.body.SmoothRotate(0.0f, 20.0f); leftArm.body.SmoothRotate(0.0f, 20.0f);
} }
} }
} }
@@ -520,17 +475,18 @@ namespace Barotrauma
movement = Vector2.Normalize(movement); movement = Vector2.Normalize(movement);
} }
RefLimb.pullJoint.Enabled = true; return;
RefLimb.pullJoint.WorldAnchorB = //RefLimb.pullJoint.Enabled = true;
RefLimb.SimPosition + movement * 0.15f; //RefLimb.pullJoint.WorldAnchorB =
// RefLimb.SimPosition + movement * 0.15f;
RefLimb.body.SmoothRotate(0.0f); //RefLimb.body.SmoothRotate(0.0f);
foreach (Limb l in Limbs) //foreach (Limb l in Limbs)
{ //{
if (l == RefLimb) continue; // if (l == RefLimb) continue;
l.body.SetTransform(RefLimb.SimPosition, RefLimb.Rotation); // l.body.SetTransform(RefLimb.SimPosition, RefLimb.Rotation);
} //}
//new Vector2(movement.X, floorY + HeadPosition), 0.5f); //new Vector2(movement.X, floorY + HeadPosition), 0.5f);
} }
@@ -543,26 +499,26 @@ namespace Barotrauma
float surfaceLimiter = 1.0f; float surfaceLimiter = 1.0f;
Limb head = GetLimb(LimbType.Head); Limb head = GetLimb(LimbType.Head);
Limb torso = GetLimb(LimbType.Torso);
if (currentHull != null && (currentHull.Rect.Y - currentHull.Surface > 50.0f) && !head.inWater)
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); 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 leftHand = GetLimb(LimbType.LeftHand);
Limb rightHand = GetLimb(LimbType.RightHand); Limb rightHand = GetLimb(LimbType.RightHand);
Limb leftFoot = GetLimb(LimbType.LeftFoot); Limb leftFoot = GetLimb(LimbType.LeftFoot);
Limb rightFoot = GetLimb(LimbType.RightFoot); Limb rightFoot = GetLimb(LimbType.RightFoot);
float rotation = MathHelper.WrapAngle(torso.Rotation); float rotation = MathHelper.WrapAngle(collider.Rotation);
rotation = MathHelper.ToDegrees(rotation); rotation = MathHelper.ToDegrees(rotation);
if (rotation < 0.0f) rotation += 360; if (rotation < 0.0f) rotation += 360;
if (!character.IsNetworkPlayer && !aiming) if (!character.IsRemotePlayer && !aiming)
{ {
if (rotation > 20 && rotation < 170) if (rotation > 20 && rotation < 170)
TargetDir = Direction.Left; TargetDir = Direction.Left;
@@ -577,7 +533,10 @@ namespace Barotrauma
{ {
if (!aiming) 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 else
@@ -589,23 +548,27 @@ namespace Barotrauma
TargetMovement = new Vector2(0.0f, -0.1f); 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; 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 //dont try to move upwards if head is already out of water
if (surfaceLimiter > 1.0f && TargetMovement.Y > 0.0f) if (surfaceLimiter > 1.0f && TargetMovement.Y > 0.0f)
{ {
if (TargetMovement.X == 0.0f) if (TargetMovement.X == 0.0f)
{ {
head.body.ApplyForce(head.Mass * new Vector2(-Dir * 5.1f, -5.0f)); //pull head above water
torso.body.ApplyForce(torso.Mass * new Vector2(-Dir * 5.1f, -15.0f)); head.body.SmoothRotate(0.0f, 5.0f);
leftFoot.body.ApplyForce(leftFoot.Mass * new Vector2(0.0f, -80.0f));
rightFoot.body.ApplyForce(rightFoot.Mass * new Vector2(0.0f, -80.0f)); walkPos += 0.05f;
} }
else else
{ {
@@ -614,23 +577,20 @@ namespace Barotrauma
* Math.Sign(TargetMovement.X), * Math.Sign(TargetMovement.X),
Math.Max(TargetMovement.Y, TargetMovement.Y * 0.2f)); 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 = movement.Y - (surfaceLimiter - 1.0f) * 0.01f;
} }
movement.Y -= 0.05f; if (!character.IsRemotePlayer || GameMain.Server != null)
{
head.body.ApplyForce((new Vector2(movement.X, collider.LinearVelocity = Vector2.Lerp(collider.LinearVelocity, movement * swimSpeed, movementLerp);
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);
walkPos += movement.Length() * 0.15f; 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 rightThigh = GetLimb(LimbType.RightThigh);
var leftThigh = GetLimb(LimbType.LeftThigh); var leftThigh = GetLimb(LimbType.LeftThigh);
@@ -641,41 +601,32 @@ namespace Barotrauma
Vector2 transformedFootPos = new Vector2((float)Math.Sin(walkPos) * 0.5f, 0.0f); Vector2 transformedFootPos = new Vector2((float)Math.Sin(walkPos) * 0.5f, 0.0f);
transformedFootPos = Vector2.Transform( transformedFootPos = Vector2.Transform(
transformedFootPos, 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);
{ MoveLimb(leftFoot, footPos + transformedFootPos, 1.0f);
MoveLimb(rightFoot, footPos - transformedFootPos, 1.0f);
}
if (Math.Abs(MathUtils.GetShortestAngle(torso.Rotation, leftThigh.Rotation)) < 0.3f)
{
MoveLimb(leftFoot, footPos + transformedFootPos, 1.0f);
}
handPos = (torso.SimPosition + head.SimPosition) / 2.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 //at the surface, not moving sideways -> hands just float around
if (!headInWater && TargetMovement.X == 0.0f && TargetMovement.Y > 0) if (!headInWater && TargetMovement.X == 0.0f && TargetMovement.Y > 0)
{ {
handPos.X = handPos.X + Dir * 0.6f; handPos.X = handPos.X + Dir * 0.6f;
float wobbleAmount = 0.05f; float wobbleAmount = 0.1f;
if (!rightHand.Disabled) if (!rightHand.Disabled)
{ {
MoveLimb(rightHand, new Vector2( MoveLimb(rightHand, new Vector2(
handPos.X + (float)Math.Sin(walkPos / 1.5f) * wobbleAmount, 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) if (!leftHand.Disabled)
{ {
MoveLimb(leftHand, new Vector2( MoveLimb(leftHand, new Vector2(
handPos.X + (float)Math.Sin(walkPos / 2.0f) * wobbleAmount, 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; return;
@@ -683,8 +634,8 @@ namespace Barotrauma
handPos += head.LinearVelocity * 0.1f; handPos += head.LinearVelocity * 0.1f;
float handCyclePos = walkPos / 2.0f; float handCyclePos = walkPos / 3.0f * -Dir;
float handPosX = (float)Math.Cos(handCyclePos * Dir) * 0.4f; float handPosX = (float)Math.Cos(handCyclePos) * 0.4f;
float handPosY = (float)Math.Sin(handCyclePos) * 1.0f; float handPosY = (float)Math.Sin(handCyclePos) * 1.0f;
handPosY = MathHelper.Clamp(handPosY, -0.8f, 0.8f); handPosY = MathHelper.Clamp(handPosY, -0.8f, 0.8f);
@@ -693,21 +644,18 @@ namespace Barotrauma
if (!rightHand.Disabled) if (!rightHand.Disabled)
{ {
Vector2 rightHandPos = new Vector2(-handPosX, -handPosY); 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); rightHandPos = Vector2.Transform(rightHandPos, rotationMatrix);
//MoveLimb(rightHand, handPos + rightHandPos, 1.5f);
HandIK(rightHand, handPos + rightHandPos, 0.5f); HandIK(rightHand, handPos + rightHandPos, 0.5f);
} }
if (!leftHand.Disabled) if (!leftHand.Disabled)
{ {
Vector2 leftHandPos = new Vector2(handPosX, handPosY); 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); leftHandPos = Vector2.Transform(leftHandPos, rotationMatrix);
//MoveLimb(leftHand, handPos + leftHandPos,1.5f);
HandIK(leftHand, handPos + leftHandPos, 0.5f); HandIK(leftHand, handPos + leftHandPos, 0.5f);
} }
} }
@@ -724,10 +672,9 @@ namespace Barotrauma
IgnorePlatforms = true; IgnorePlatforms = true;
Vector2 tempTargetMovement = TargetMovement; Vector2 tempTargetMovement = TargetMovement;
//if (TargetMovement.Y != 0.0f)
//{ tempTargetMovement.Y = Math.Min(tempTargetMovement.Y, 1.0f);
// tempTargetMovement.Y = Math.Max(Math.Abs(TargetMovement.Y), 0.6f) * Math.Sign(TargetMovement.Y);
//}
movement = MathUtils.SmoothStep(movement, tempTargetMovement, 0.3f); movement = MathUtils.SmoothStep(movement, tempTargetMovement, 0.3f);
Limb leftFoot = GetLimb(LimbType.LeftFoot); Limb leftFoot = GetLimb(LimbType.LeftFoot);
@@ -746,7 +693,7 @@ namespace Barotrauma
float stepHeight = ConvertUnits.ToSimUnits(30.0f); 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; ladderSimPos += character.SelectedConstruction.Submarine.SimPosition;
} }
@@ -754,26 +701,32 @@ namespace Barotrauma
{ {
ladderSimPos += character.SelectedConstruction.Submarine.SimPosition - currentHull.Submarine.SimPosition; 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( Vector2 handPos = new Vector2(
ladderSimPos.X, 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); handPos.Y = Math.Min(-0.5f, handPos.Y);
MoveLimb(leftHand, MoveLimb(leftHand,
new Vector2(handPos.X, 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); 5.2f);
MoveLimb(rightHand, MoveLimb(rightHand,
new Vector2(handPos.X, 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); 5.2f);
leftHand.body.ApplyTorque(Dir * 2.0f); leftHand.body.ApplyTorque(Dir * 2.0f);
@@ -781,18 +734,18 @@ namespace Barotrauma
Vector2 footPos = new Vector2( Vector2 footPos = new Vector2(
handPos.X - Dir * 0.05f, 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; //if (movement.Y < 0) footPos.Y += 0.05f;
MoveLimb(leftFoot, MoveLimb(leftFoot,
new Vector2(footPos.X, 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); 15.5f, true);
MoveLimb(rightFoot, MoveLimb(rightFoot,
new Vector2(footPos.X, 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); 15.5f, true);
//apply torque to the legs to make the knees bend //apply torque to the legs to make the knees bend
@@ -802,18 +755,19 @@ namespace Barotrauma
leftLeg.body.ApplyTorque(Dir * -8.0f); leftLeg.body.ApplyTorque(Dir * -8.0f);
rightLeg.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; float movementFactor = (handPos.Y / stepHeight) * (float)Math.PI;
movementFactor = 0.8f + (float)Math.Abs(Math.Sin(movementFactor)); 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.Zero : character.SelectedConstruction.Submarine.Velocity;
Vector2 climbForce = new Vector2(0.0f, movement.Y + (inWater ? -0.05f : 0.6f)) * movementFactor; Vector2 climbForce = new Vector2(0.0f, movement.Y + 0.3f) * movementFactor;
if (climbForce.Y > 0.5f) climbForce.Y = Math.Max(climbForce.Y, 1.3f); //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);
//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()) if (!character.SelectedConstruction.Prefab.Triggers.Any())
{ {
character.SelectedConstruction = null; character.SelectedConstruction = null;
@@ -824,7 +778,7 @@ namespace Barotrauma
trigger = character.SelectedConstruction.TransformTrigger(trigger); trigger = character.SelectedConstruction.TransformTrigger(trigger);
bool notClimbing = false; bool notClimbing = false;
if (character.IsNetworkPlayer) if (character.IsRemotePlayer)
{ {
notClimbing = character.IsKeyDown(InputType.Left) || character.IsKeyDown(InputType.Right); notClimbing = character.IsKeyDown(InputType.Left) || character.IsKeyDown(InputType.Right);
} }
@@ -861,15 +815,15 @@ namespace Barotrauma
targetMovement = new Vector2(diff.X, 0.0f); targetMovement = new Vector2(diff.X, 0.0f);
TargetDir = headDiff.X > 0.0f ? Direction.Right : Direction.Left; TargetDir = headDiff.X > 0.0f ? Direction.Right : Direction.Left;
UpdateStanding(); 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); Grab(handPos, handPos);
float yPos = (float)Math.Sin(cprAnimState) * 0.1f; float yPos = (float)Math.Sin(cprAnimState) * 0.1f;
cprAnimState += deltaTime*8.0f; cprAnimState += deltaTime * 8.0f;
var head = GetLimb(LimbType.Head); var head = GetLimb(LimbType.Head);
head.pullJoint.WorldAnchorB = new Vector2(targetHead.SimPosition.X, targetHead.SimPosition.Y + 0.6f + yPos); 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); //RefLimb.pullJoint.WorldAnchorB = new Vector2(targetHead.SimPosition.X - Math.Sign(headDiff.X) * 0.5f, targetHead.SimPosition.Y + 0.4f + yPos);
//head.pullJoint.Enabled = true; //head.pullJoint.Enabled = true;
//DragCharacter(character.SelectedCharacter, LimbType.Torso, LimbType.Head); //DragCharacter(character.SelectedCharacter, LimbType.Torso, LimbType.Head);
} }
@@ -941,15 +895,15 @@ namespace Barotrauma
//only grab with one hand when swimming //only grab with one hand when swimming
leftHand.Disabled = true; leftHand.Disabled = true;
if (!inWater) rightHand.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; targetLimb.pullJoint.Enabled = false;
} }
@@ -976,7 +930,7 @@ namespace Barotrauma
} }
else if (target is AICharacter) 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.Disabled = true;
pullLimb.pullJoint.Enabled = true; pullLimb.pullJoint.Enabled = true;
pullLimb.pullJoint.WorldAnchorB = (i==0) ? rightHandPos : leftHandPos; pullLimb.pullJoint.WorldAnchorB = (i == 0) ? rightHandPos : leftHandPos;
pullLimb.pullJoint.MaxForce = 500.0f; pullLimb.pullJoint.MaxForce = 500.0f;
} }
@@ -1084,7 +1038,7 @@ namespace Barotrauma
item.body.ResetDynamics(); item.body.ResetDynamics();
Vector2 currItemPos = (character.SelectedItems[0]==item) ? Vector2 currItemPos = (character.SelectedItems[0] == item) ?
rightHand.pullJoint.WorldAnchorA - transformedHandlePos[0] : rightHand.pullJoint.WorldAnchorA - transformedHandlePos[0] :
leftHand.pullJoint.WorldAnchorA - transformedHandlePos[1]; leftHand.pullJoint.WorldAnchorA - transformedHandlePos[1];
item.SetTransform(currItemPos, itemAngle); item.SetTransform(currItemPos, itemAngle);
@@ -1129,17 +1083,6 @@ namespace Barotrauma
hand.body.SmoothRotate((ang2 + handAngle * Dir), 100.0f * force); 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() public override void Flip()
{ {
base.Flip(); base.Flip();
@@ -1199,7 +1142,7 @@ namespace Barotrauma
Vector2 position = limb.SimPosition; 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 = limb.body.SimPosition - torso.SimPosition;
difference = Vector2.Transform(difference, torsoTransform); difference = Vector2.Transform(difference, torsoTransform);
@@ -1213,11 +1156,11 @@ namespace Barotrauma
float angle = flipAngle ? -limb.body.Rotation : limb.body.Rotation; float angle = flipAngle ? -limb.body.Rotation : limb.body.Rotation;
if (wrapAngle) angle = MathUtils.WrapAnglePi(angle); if (wrapAngle) angle = MathUtils.WrapAnglePi(angle);
TrySetLimbPosition(limb, RefLimb.SimPosition, position); TrySetLimbPosition(limb, collider.SimPosition, position);
limb.body.SetTransform(limb.body.SimPosition, angle); limb.body.SetTransform(limb.body.SimPosition, angle);
} }
} }
} }
} }
+374 -236
View File
@@ -9,6 +9,7 @@ using FarseerPhysics.Dynamics.Joints;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Networking; using Barotrauma.Networking;
using Lidgren.Network;
namespace Barotrauma namespace Barotrauma
{ {
@@ -19,6 +20,25 @@ namespace Barotrauma
protected Hull currentHull; protected Hull currentHull;
public Limb[] Limbs; 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; private Dictionary<LimbType, Limb> limbDictionary;
public RevoluteJoint[] limbJoints; public RevoluteJoint[] limbJoints;
@@ -26,8 +46,6 @@ namespace Barotrauma
private Character character; private Character character;
private Limb lowestLimb;
protected float strongestImpact; protected float strongestImpact;
public float headPosition, headAngle; public float headPosition, headAngle;
@@ -44,7 +62,7 @@ namespace Barotrauma
//a movement vector that overrides targetmovement if trying to steer //a movement vector that overrides targetmovement if trying to steer
//a Character to the position sent by server in multiplayer mode //a Character to the position sent by server in multiplayer mode
protected Vector2 correctionMovement; protected Vector2 overrideTargetMovement;
protected float floorY; protected float floorY;
protected float surfaceY; protected float surfaceY;
@@ -52,25 +70,20 @@ namespace Barotrauma
protected bool inWater, headInWater; protected bool inWater, headInWater;
public bool onGround; public bool onGround;
private bool ignorePlatforms; private bool ignorePlatforms;
private Limb refLimb;
protected Structure stairs; protected Structure stairs;
protected Direction dir; protected Direction dir;
//private byte ID; public Direction TargetDir;
public Limb LowestLimb
{
get { return lowestLimb; }
}
public Limb RefLimb protected PhysicsBody collider;
public PhysicsBody Collider
{ {
get get
{ {
return refLimb; return collider;
} }
} }
@@ -85,6 +98,22 @@ namespace Barotrauma
private set; 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 public bool SimplePhysicsEnabled
{ {
get { return simplePhysicsEnabled; } get { return simplePhysicsEnabled; }
@@ -104,7 +133,13 @@ namespace Barotrauma
joint.Enabled = !simplePhysicsEnabled; 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 get
{ {
return (correctionMovement == Vector2.Zero) ? targetMovement : correctionMovement; return (overrideTargetMovement == Vector2.Zero) ? targetMovement : overrideTargetMovement;
} }
set set
{ {
@@ -167,10 +202,12 @@ namespace Barotrauma
if (value == currentHull) return; if (value == currentHull) return;
currentHull = value; currentHull = value;
Submarine currSubmarine = currentHull == null ? null : currentHull.Submarine;
foreach (Limb limb in Limbs) 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); float scale = ToolBox.GetAttributeFloat(element, "scale", 1.0f);
//int limbAmount = ;
Limbs = new Limb[element.Elements("limb").Count()]; Limbs = new Limb[element.Elements("limb").Count()];
limbJoints = new RevoluteJoint[element.Elements("joint").Count()]; limbJoints = new RevoluteJoint[element.Elements("joint").Count()];
limbDictionary = new Dictionary<LimbType, Limb>(); limbDictionary = new Dictionary<LimbType, Limb>();
headPosition = ToolBox.GetAttributeFloat(element, "headposition", 50.0f); headPosition = ToolBox.GetAttributeFloat(element, "headposition", 50.0f);
headPosition = ConvertUnits.ToSimUnits(headPosition); headPosition = ConvertUnits.ToSimUnits(headPosition);
headAngle = MathHelper.ToRadians(ToolBox.GetAttributeFloat(element, "headangle", 0.0f)); headAngle = MathHelper.ToRadians(ToolBox.GetAttributeFloat(element, "headangle", 0.0f));
torsoPosition = ToolBox.GetAttributeFloat(element, "torsoposition", 50.0f); torsoPosition = ToolBox.GetAttributeFloat(element, "torsoposition", 50.0f);
torsoPosition = ConvertUnits.ToSimUnits(torsoPosition); torsoPosition = ConvertUnits.ToSimUnits(torsoPosition);
torsoAngle = MathHelper.ToRadians(ToolBox.GetAttributeFloat(element, "torsoangle", 0.0f)); torsoAngle = MathHelper.ToRadians(ToolBox.GetAttributeFloat(element, "torsoangle", 0.0f));
CanEnterSubmarine = ToolBox.GetAttributeBool(element, "canentersubmarine", true); CanEnterSubmarine = ToolBox.GetAttributeBool(element, "canentersubmarine", true);
@@ -241,20 +277,30 @@ namespace Barotrauma
case "joint": case "joint":
AddJoint(subElement, scale); AddJoint(subElement, scale);
break;
case "collider":
collider = new PhysicsBody(subElement, scale);
collider.FarseerBody.FixedRotation = true;
break; break;
} }
} }
refLimb = GetLimb(LimbType.Torso); if (collider == null)
if (refLimb == null) refLimb = GetLimb(LimbType.Head); {
if (refLimb == null) DebugConsole.ThrowError("Character \"" + character + "\" doesn't have a head or torso!"); 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(); UpdateCollisionCategories();
foreach (var joint in limbJoints) foreach (var joint in limbJoints)
{ {
joint.BodyB.SetTransform( joint.BodyB.SetTransform(
joint.BodyA.Position + (joint.LocalAnchorA - joint.LocalAnchorB)*0.1f, joint.BodyA.Position + (joint.LocalAnchorA - joint.LocalAnchorB)*0.1f,
(joint.LowerLimit + joint.UpperLimit) / 2.0f); (joint.LowerLimit + joint.UpperLimit) / 2.0f);
@@ -274,7 +320,10 @@ namespace Barotrauma
limb.sprite.Depth = startDepth + limb.sprite.Depth * 0.0001f; 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) public void AddJoint(XElement subElement, float scale = 1.0f)
@@ -341,61 +390,51 @@ namespace Barotrauma
CalculateImpact(f1, f2, contact); CalculateImpact(f1, f2, contact);
return true; return true;
} }
Vector2 colliderBottom = GetColliderBottom();
if (structure.IsPlatform) if (structure.IsPlatform)
{ {
if (ignorePlatforms) return false; if (ignorePlatforms) return false;
//the collision is ignored if the lowest limb is under the platform //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 ? stairs = null;
lowestLimb.Position.X - structure.Rect.X : structure.Rect.Width - (lowestLimb.Position.X - structure.Rect.X);
//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;
//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.5f) if (targetMovement.Y >= 0.0f && colliderBottom.Y >= ConvertUnits.ToSimUnits(structure.Rect.Y - Submarine.GridSize.Y * 5)) return false;
{
if (inWater || lowestLimb.Position.Y < structure.Rect.Y - structure.Rect.Height + 50.0f) //3. collided with the stairs from below
{ if (contact.Manifold.LocalNormal.Y < 0.0f) return false;
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;
}
} //4. contact points is above the bottom half of the collider
else Vector2 normal; FarseerPhysics.Common.FixedArray2<Vector2> points;
{ contact.GetWorldManifold(out normal, out points);
stairs = null; if (points[0].Y > collider.SimPosition.Y) return false;
return false;
} //5. in water
} if (inWater && targetMovement.Y < 0.5f) return false;
//---------------
stairs = structure;
} }
CalculateImpact(f1, f2, contact); CalculateImpact(f1, f2, contact);
return true; return true;
} }
@@ -405,39 +444,40 @@ namespace Barotrauma
Vector2 normal = contact.Manifold.LocalNormal; Vector2 normal = contact.Manifold.LocalNormal;
Vector2 avgVelocity = Vector2.Zero; //Vector2 avgVelocity = Vector2.Zero;
foreach (Limb limb in Limbs) //foreach (Limb limb in Limbs)
{ //{
avgVelocity += limb.LinearVelocity; // 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); float impact = Vector2.Dot(velocity, -normal);
Limb l = (Limb)f1.Body.UserData;
float volume = stairs == null ? impact / 5.0f : impact; float volume = Math.Min(impact, 1.0f);
volume = Math.Min(impact, 1.0f); if (f1.Body.UserData is Limb)
if (impact > 0.5f && l.HitSound != null && l.soundTimer <= 0.0f)
{ {
l.soundTimer = Limb.SoundInterval; Limb limb = (Limb)f1.Body.UserData;
l.HitSound.Play(volume, impact * 250.0f, l.WorldPosition);
} if (impact > 0.5f && limb.HitSound != null && limb.soundTimer <= 0.0f)
if (impact > l.impactTolerance)
{
if (!character.IsNetworkPlayer || GameMain.Server != null)
{ {
character.AddDamage(CauseOfDeath.Damage, impact - l.impactTolerance * 0.1f, null); limb.soundTimer = Limb.SoundInterval;
limb.HitSound.Play(volume, impact * 250.0f, limb.WorldPosition);
strongestImpact = Math.Max(strongestImpact, impact - l.impactTolerance);
} }
}
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; if (Character.Controlled == character) GameMain.GameScreen.Cam.Shake = strongestImpact;
} }
@@ -446,6 +486,8 @@ namespace Barotrauma
public virtual void Draw(SpriteBatch spriteBatch) public virtual void Draw(SpriteBatch spriteBatch)
{ {
if (simplePhysicsEnabled) return; if (simplePhysicsEnabled) return;
collider.UpdateDrawPosition();
foreach (Limb limb in Limbs) foreach (Limb limb in Limbs)
{ {
@@ -467,17 +509,13 @@ namespace Barotrauma
if (currentHull != null) pos += currentHull.Submarine.DrawPosition; if (currentHull != null) pos += currentHull.Submarine.DrawPosition;
pos.Y = -pos.Y; pos.Y = -pos.Y;
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)pos.Y, 5, 5), Color.Red, true, 0.01f); 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) foreach (RevoluteJoint joint in limbJoints)
{ {
Vector2 pos = ConvertUnits.ToDisplayUnits(joint.WorldAnchorA); Vector2 pos = ConvertUnits.ToDisplayUnits(joint.WorldAnchorA);
@@ -496,13 +534,35 @@ namespace Barotrauma
pos.Y = -pos.Y; 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.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) 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; return centerOfMass;
} }
/// <summary>
///
/// </summary>
/// <param name="pullFromCenter">if false, force is applied to the position of pullJoint</param> /// <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) 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() 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; if (Limbs[i] == null || Limbs[i].pullJoint == null) continue;
Limbs[i].pullJoint.Enabled = false; Limbs[i].pullJoint.Enabled = false;
@@ -590,7 +646,7 @@ namespace Barotrauma
return; return;
} }
Vector2 findPos = worldPosition==null ? refLimb.WorldPosition : (Vector2)worldPosition; Vector2 findPos = worldPosition==null ? this.WorldPosition : (Vector2)worldPosition;
Hull newHull = Hull.FindHull(findPos, currentHull); Hull newHull = Hull.FindHull(findPos, currentHull);
@@ -642,7 +698,6 @@ namespace Barotrauma
while (ce != null && ce.Contact != null) while (ce != null && ce.Contact != null)
{ {
ce.Contact.Enabled = false; ce.Contact.Enabled = false;
ce = ce.Next; ce = ce.Next;
} }
} }
@@ -655,10 +710,10 @@ namespace Barotrauma
//character.Stun = 0.1f; //character.Stun = 0.1f;
character.DisableImpactDamageTimer = 0.25f; character.DisableImpactDamageTimer = 0.25f;
SetPosition(refLimb.SimPosition + moveAmount); SetPosition(collider.SimPosition + moveAmount);
character.CursorPosition += moveAmount; character.CursorPosition += moveAmount;
} }
private void UpdateCollisionCategories() private void UpdateCollisionCategories()
{ {
Category wall = currentHull == null ? Category wall = currentHull == null ?
@@ -669,6 +724,8 @@ namespace Barotrauma
wall | Physics.CollisionProjectile | Physics.CollisionStairs wall | Physics.CollisionProjectile | Physics.CollisionStairs
: wall | Physics.CollisionProjectile | Physics.CollisionPlatform | Physics.CollisionStairs; : wall | Physics.CollisionProjectile | Physics.CollisionPlatform | Physics.CollisionStairs;
collider.CollidesWith = collisionCategory;
foreach (Limb limb in Limbs) foreach (Limb limb in Limbs)
{ {
if (limb.ignoreCollisions) continue; if (limb.ignoreCollisions) continue;
@@ -686,14 +743,13 @@ namespace Barotrauma
public void Update(Camera cam, float deltaTime) public void Update(Camera cam, float deltaTime)
{ {
if (!character.Enabled) return; if (!character.Enabled || Frozen) return;
UpdateNetPlayerPosition(); UpdateNetPlayerPosition(deltaTime);
CheckDistFromCollider();
Vector2 flowForce = Vector2.Zero; Vector2 flowForce = Vector2.Zero;
FindLowestLimb();
FindHull(); FindHull();
splashSoundTimer -= deltaTime; splashSoundTimer -= deltaTime;
@@ -711,10 +767,27 @@ namespace Barotrauma
inWater = false; inWater = false;
headInWater = false; headInWater = false;
float waterSurface = ConvertUnits.ToSimUnits(currentHull.Surface);
float floorY = GetFloorY();
if (currentHull.Volume > currentHull.FullVolume * 0.95f || 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; 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) foreach (Limb limb in Limbs)
{ {
@@ -736,10 +809,9 @@ namespace Barotrauma
{ {
limb.inWater = true; limb.inWater = true;
if (flowForce.Length() > 0.01f) if (flowForce.LengthSquared() > 0.001f)
{ {
limb.body.ApplyForce(flowForce); limb.body.ApplyForce(flowForce);
if (flowForce.Length() > 15.0f) surfaceY = limbHull.Surface;
} }
surfaceY = limbHull.Surface; surfaceY = limbHull.Surface;
@@ -747,7 +819,6 @@ namespace Barotrauma
if (limb.type == LimbType.Head) if (limb.type == LimbType.Head)
{ {
headInWater = true; headInWater = true;
surfaceY = limbHull.Surface;
} }
} }
//the limb has gone through the surface of the water //the limb has gone through the surface of the water
@@ -755,9 +826,9 @@ namespace Barotrauma
{ {
//create a splash particle //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(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); 0.0f, limbHull);
GameMain.ParticleManager.CreateParticle("bubbles", GameMain.ParticleManager.CreateParticle("bubbles",
@@ -787,27 +858,133 @@ namespace Barotrauma
} }
limb.Update(deltaTime); 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) 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) foreach (Limb limb in Limbs)
{ {
if (limb == refLimb) //check visibility from the new position of the collider to the new position of this limb
{ Vector2 movePos = limb.SimPosition + moveAmount;
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);
}
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); //if the ragdoll is too far from the collider, disable collisions until it's close enough
//(in case the ragdoll has gotten stuck somewhere)
refLimb.body.SetTransform(refLimb.SimPosition, rotation); if (Vector2.Distance(collider.SimPosition, MainLimb.SimPosition) > allowedDist)
foreach (Limb limb in Limbs)
{ {
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; collisionsDisabled = true;
newPos = Vector2.Transform(newPos, rotationMatrix); }
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); UpdateCollisionCategories();
limb.body.SetTransform(limb.SimPosition, limb.Rotation + rotateAmount); 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; //if (character.MemPos.Count < 2) return;
return;
}
//if the limb is closer than alloweddistance, just ignore the difference //PosInfo serverPos = character.MemPos.Last();
float allowedDistance = NetConfig.AllowedRagdollDistance * ((inWater) ? 2.0f : 1.0f);
if (currentHull == null) //int localPosIndex = character.MemLocalPos.FindIndex(m => m.ID == serverPos.ID);
{ //if (localPosIndex > -1)
var overLappingHull = Hull.FindHull(ConvertUnits.ToDisplayUnits(refLimb.body.TargetPosition), null, true); //{
// PosInfo localPos = character.MemLocalPos[localPosIndex];
if (overLappingHull != null) // if (Vector2.Distance(localPos.Position, serverPos.Position) > 0.1f)
{ // {
Submarine.PickBody(refLimb.SimPosition, refLimb.body.TargetPosition, null, Physics.CollisionWall); // //collider.SetTransform(collider.SimPosition + (pos.Position - remotePos), collider.Rotation);
// collider.SetTransform(serverPos.Position, collider.Rotation);
refLimb.body.TargetPosition = refLimb.SimPosition + (refLimb.body.TargetPosition - refLimb.SimPosition) * Submarine.LastPickedFraction * 0.9f; // // 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 (character.MemLocalPos.Count > 120) character.MemLocalPos.RemoveRange(0, character.MemLocalPos.Count - 120);
//character.MemPos.Clear();
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);
}
} }
else else
{ {
//clamp the magnitude of the correction movement between 0.5f - 5.0f collider.CorrectPosition(character.MemPos, deltaTime, out overrideTargetMovement);
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;
} }
} }
public virtual Vector2 EstimateCurrPosition(Vector2 prevPosition, float timePassed)
{
return prevPosition;
}
private Vector2 GetFlowForce() private Vector2 GetFlowForce()
{ {
Vector2 limbPos = ConvertUnits.ToDisplayUnits(Limbs[0].SimPosition); Vector2 limbPos = ConvertUnits.ToDisplayUnits(Limbs[0].SimPosition);
@@ -985,11 +1116,16 @@ namespace Barotrauma
limbDictionary.TryGetValue(limbType, out limb); limbDictionary.TryGetValue(limbType, out limb);
return limb; return limb;
} }
public void FindLowestLimb()
public Vector2 GetColliderBottom()
{ {
//find the lowest limb return collider.SimPosition - Vector2.UnitY * (collider.height / 2 + collider.radius);
lowestLimb = null; }
public Limb FindLowestLimb()
{
Limb lowestLimb = null;
foreach (Limb limb in Limbs) foreach (Limb limb in Limbs)
{ {
if (lowestLimb == null) if (lowestLimb == null)
@@ -997,6 +1133,8 @@ namespace Barotrauma
else if (limb.SimPosition.Y < lowestLimb.SimPosition.Y) else if (limb.SimPosition.Y < lowestLimb.SimPosition.Y)
lowestLimb = limb; lowestLimb = limb;
} }
return lowestLimb;
} }
public void Remove() public void Remove()
+142 -59
View File
@@ -14,13 +14,50 @@ using System.Xml.Linq;
namespace Barotrauma 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 class Character : Entity, IDamageable, IPropertyObject
{ {
public static List<Character> CharacterList = new List<Character>(); public static List<Character> CharacterList = new List<Character>();
public static bool DisableControls; 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 //the Character that the player is currently controlling
private static Character controlled; private static Character controlled;
@@ -61,9 +98,7 @@ namespace Barotrauma
public Hull PreviousHull = null; public Hull PreviousHull = null;
public Hull CurrentHull = null; public Hull CurrentHull = null;
public readonly bool IsNetworkPlayer; public readonly bool IsRemotePlayer;
private bool networkUpdateSent;
private CharacterInventory inventory; private CharacterInventory inventory;
@@ -199,6 +234,17 @@ namespace Barotrauma
get { return Submarine == null ? cursorPosition : cursorPosition + Submarine.Position; } 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 public Character ClosestCharacter
{ {
get { return closestCharacter; } get { return closestCharacter; }
@@ -289,6 +335,7 @@ namespace Barotrauma
set set
{ {
if (!MathUtils.IsValid(value)) return; if (!MathUtils.IsValid(value)) return;
health = MathHelper.Clamp(value, minHealth, maxHealth); health = MathHelper.Clamp(value, minHealth, maxHealth);
} }
} }
@@ -416,28 +463,28 @@ namespace Barotrauma
public override Vector2 SimPosition public override Vector2 SimPosition
{ {
get { return AnimController.RefLimb.SimPosition; } get { return AnimController.Collider.SimPosition; }
} }
public override Vector2 Position public override Vector2 Position
{ {
get { return AnimController.RefLimb.Position; } get { return ConvertUnits.ToDisplayUnits(SimPosition); }
} }
public override Vector2 DrawPosition 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 delegate void OnDeathHandler(Character character, CauseOfDeath causeOfDeath);
public OnDeathHandler OnDeath; 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 LINUX
if (!System.IO.File.Exists(file)) if (!System.IO.File.Exists(file))
@@ -470,7 +517,7 @@ namespace Barotrauma
if (file != humanConfigFile) 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); var ai = new EnemyAIController(enemyCharacter, file);
enemyCharacter.SetAI(ai); enemyCharacter.SetAI(ai);
@@ -480,7 +527,7 @@ namespace Barotrauma
} }
else if (hasAi) else if (hasAi)
{ {
var aiCharacter = new AICharacter(file, position, characterInfo, isNetworkPlayer); var aiCharacter = new AICharacter(file, position, characterInfo, isRemotePlayer);
var ai = new HumanAIController(aiCharacter); var ai = new HumanAIController(aiCharacter);
aiCharacter.SetAI(ai); aiCharacter.SetAI(ai);
@@ -489,13 +536,13 @@ namespace Barotrauma
return aiCharacter; return aiCharacter;
} }
var character = new Character(file, position, characterInfo, isNetworkPlayer); var character = new Character(file, position, characterInfo, isRemotePlayer);
character.minHealth = -100.0f; character.minHealth = -100.0f;
return character; 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) : base(null)
{ {
@@ -512,7 +559,7 @@ namespace Barotrauma
hudProgressBars = new Dictionary<object, HUDProgressBar>(); hudProgressBars = new Dictionary<object, HUDProgressBar>();
IsNetworkPlayer = isNetworkPlayer; IsRemotePlayer = isRemotePlayer;
oxygen = 100.0f; oxygen = 100.0f;
oxygenAvailable = 100.0f; oxygenAvailable = 100.0f;
@@ -545,15 +592,10 @@ namespace Barotrauma
{ {
AnimController = new FishAnimController(this, doc.Root.Element("ragdoll")); AnimController = new FishAnimController(this, doc.Root.Element("ragdoll"));
PressureProtection = 100.0f; 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); maxHealth = ToolBox.GetAttributeFloat(doc.Root, "health", 100.0f);
health = maxHealth; health = maxHealth;
@@ -705,8 +747,13 @@ namespace Barotrauma
if (length > 0.0f) targetMovement = targetMovement / length; 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 *= 3.0f;
}
targetMovement *= SpeedMultiplier; targetMovement *= SpeedMultiplier;
SpeedMultiplier = 1.0f; 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) if (attackCoolDown >0.0f)
{ {
attackCoolDown -= deltaTime; attackCoolDown -= deltaTime;
@@ -832,7 +898,7 @@ namespace Barotrauma
} }
if (IsNetworkPlayer) if (IsRemotePlayer)
{ {
foreach (Key key in keys) 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); 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); cursorPosition = cam.ScreenToWorld(PlayerInput.MousePosition);
if (AnimController.CurrentHull != null && AnimController.CurrentHull.Submarine != null) if (AnimController.CurrentHull != null && AnimController.CurrentHull.Submarine != null)
@@ -1133,7 +1211,8 @@ namespace Barotrauma
{ {
foreach (Character c in CharacterList) foreach (Character c in CharacterList)
{ {
if (c.isDead || c.health <= 0.0f || !c.Enabled) continue; if (!c.Enabled) continue;
c.AnimController.UpdateAnim(deltaTime); c.AnimController.UpdateAnim(deltaTime);
} }
} }
@@ -1309,7 +1388,7 @@ namespace Barotrauma
aiTarget.SightRange = 0.0f; 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) public void ShowSpeechBubble(float duration, Color color)
@@ -1519,7 +1598,7 @@ namespace Barotrauma
// limb.Damage = 100.0f; // 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++) for (int i = 0; i < 10; i++)
{ {
@@ -1988,7 +2067,6 @@ namespace Barotrauma
keys[(int)InputType.Crouch].Held = crouchState; keys[(int)InputType.Crouch].Held = crouchState;
float dir = 1.0f; float dir = 1.0f;
Vector2 pos = Vector2.Zero; Vector2 pos = Vector2.Zero;
@@ -2023,38 +2101,41 @@ namespace Barotrauma
pos.X = message.ReadFloat(); pos.X = message.ReadFloat();
pos.Y = message.ReadFloat(); pos.Y = message.ReadFloat();
if (inSub != (Submarine != null)) if (inSub != (Submarine != null))
{ {
AnimController.Teleport(pos - SimPosition, Vector2.Zero); AnimController.Teleport(pos - SimPosition, Vector2.Zero);
} memPos.Clear();
}
if ((pos-SimPosition).Length()>600.0f) if ((pos-SimPosition).Length()>600.0f)
{ {
AnimController.Teleport(pos - SimPosition, -AnimController.RefLimb.LinearVelocity); AnimController.Teleport(pos - SimPosition, -AnimController.MainLimb.LinearVelocity);
} memPos.Clear();
}
if (inSub) if (inSub)
{ {
//AnimController.FindHull(ConvertUnits.ToDisplayUnits(pos) - Submarine.Loaded.WorldPosition); //AnimController.FindHull(ConvertUnits.ToDisplayUnits(pos) - Submarine.Loaded.WorldPosition);
Submarine prevSub = Submarine; Submarine prevSub = Submarine;
Hull newHull = Hull.FindHull(ConvertUnits.ToDisplayUnits(pos), AnimController.CurrentHull, false); Hull newHull = Hull.FindHull(ConvertUnits.ToDisplayUnits(pos), AnimController.CurrentHull, false);
if (newHull != null) if (newHull != null)
{ {
AnimController.CurrentHull = newHull; AnimController.CurrentHull = newHull;
Submarine = newHull.Submarine; Submarine = newHull.Submarine;
} }
if (prevSub != null && Submarine != null && prevSub!=Submarine) if (prevSub != null && Submarine != null && prevSub!=Submarine)
{ {
AnimController.Teleport(pos - SimPosition, Vector2.Zero); AnimController.Teleport(pos - SimPosition, Vector2.Zero);
} memPos.Clear();
} }
else }
{ else
AnimController.CurrentHull = null; {
Submarine = null; AnimController.CurrentHull = null;
} Submarine = null;
}
if (secondaryKeyState) if (secondaryKeyState)
{ {
@@ -2068,11 +2149,13 @@ namespace Barotrauma
{ {
cursorPosition = Position + new Vector2(1000.0f, 0.0f) * dir; 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.RefLimb.body.TargetPosition =
AnimController.EstimateCurrPosition(pos, (float)(NetTime.Now) - sendingTime); // AnimController.EstimateCurrPosition(pos, (float)(NetTime.Now) - sendingTime);
memPos.Add(new PosInfo(pos, dir < 0 ? Direction.Left : Direction.Right, sendingTime));
LastNetworkUpdate = sendingTime; LastNetworkUpdate = sendingTime;
+5 -70
View File
@@ -28,7 +28,6 @@ namespace Barotrauma
//the physics body of the limb //the physics body of the limb
public PhysicsBody body; public PhysicsBody body;
private Texture2D bodyShapeTexture;
private readonly int refJointIndex; private readonly int refJointIndex;
@@ -73,11 +72,6 @@ namespace Barotrauma
private List<WearableSprite> wearingItems; private List<WearableSprite> wearingItems;
private Vector2 animTargetPos; private Vector2 animTargetPos;
public Texture2D BodyShapeTexture
{
get { return bodyShapeTexture; }
}
public bool DoesFlip 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; Vector2 pullPos = body.SimPosition;
if (pullJoint!=null && !pullFromCenter) if (pullJoint!=null && !pullFromCenter)
@@ -344,10 +338,7 @@ namespace Barotrauma
animTargetPos = pos; animTargetPos = pos;
Vector2 vel = body.LinearVelocity; body.MoveToPos(pos, force, pullPos);
Vector2 deltaPos = pos - pullPos;
deltaPos *= amount;
body.ApplyLinearImpulse((deltaPos - vel * 0.5f) * body.Mass, pullPos);
} }
public AttackResult AddDamage(Vector2 position, DamageType damageType, float amount, float bleedingAmount, bool playSound) public AttackResult AddDamage(Vector2 position, DamageType damageType, float amount, float bleedingAmount, bool playSound)
@@ -445,36 +436,12 @@ namespace Barotrauma
{ {
//DebugConsole.ThrowError("CHARACTER EXPLODED"); //DebugConsole.ThrowError("CHARACTER EXPLODED");
body.ResetDynamics(); body.ResetDynamics();
body.SetTransform(character.AnimController.RefLimb.SimPosition, 0.0f); body.SetTransform(character.SimPosition, 0.0f);
} }
if (inWater) if (inWater)
{ {
//buoyancy body.ApplyWaterForces();
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);
} }
if (character.IsDead) return; 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); 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(); body.Remove();
if (bodyShapeTexture != null)
{
bodyShapeTexture.Dispose();
}
if (hitSound != null) hitSound.Remove(); if (hitSound != null) hitSound.Remove();
} }
} }
+1 -1
View File
@@ -428,7 +428,7 @@ namespace Barotrauma
characterIndex = -1; 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()) if (!matchingCharacters.Any())
{ {
@@ -151,7 +151,7 @@ namespace Barotrauma.Items.Components
StopPicking(picker); StopPicking(picker);
if (!picker.IsNetworkPlayer) OnPicked(picker); if (!picker.IsRemotePlayer) OnPicked(picker);
yield return CoroutineStatus.Success; yield return CoroutineStatus.Success;
} }
@@ -71,23 +71,18 @@ namespace Barotrauma.Items.Components
if (character.AnimController.InWater) character.AnimController.TargetMovement = dir; 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[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[1] == item) character.AnimController.GetLimb(LimbType.LeftHand).body.ApplyForce(propulsion);
}
if (!string.IsNullOrWhiteSpace(particles)) if (!string.IsNullOrWhiteSpace(particles))
{ {
@@ -92,7 +92,7 @@ namespace Barotrauma.Items.Components
if (userPos != 0.0f) 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); 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); 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"); item.SendSignal(0, ToolBox.Vector2ToString(character.CursorWorldPosition), "position_out");
} }
@@ -49,19 +49,11 @@ namespace Barotrauma.Items.Components
{ {
IgnoredBodies = new List<Body>(); IgnoredBodies = new List<Body>();
//launchImpulse = ToolBox.GetAttributeFloat(element, "launchimpulse", 10.0f);
//characterUsable = ToolBox.GetAttributeBool(element, "characterusable", false);
foreach (XElement subElement in element.Elements()) foreach (XElement subElement in element.Elements())
{ {
if (subElement.Name.ToString().ToLowerInvariant() != "attack") continue; if (subElement.Name.ToString().ToLowerInvariant() != "attack") continue;
attack = new Attack(subElement); 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) 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 (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); AttackResult attackResult = new AttackResult(0.0f, 0.0f);
if (attack != null) if (attack != null)
{ {
-1
View File
@@ -420,7 +420,6 @@ namespace Barotrauma
Structure structure = fixture.Body.UserData as Structure; Structure structure = fixture.Body.UserData as Structure;
if (structure != null) if (structure != null)
{ {
if (!structure.HasBody) return -1;
if (structure.IsPlatform && collisionCategory != null && !((Category)collisionCategory).HasFlag(Physics.CollisionPlatform)) return -1; if (structure.IsPlatform && collisionCategory != null && !((Category)collisionCategory).HasFlag(Physics.CollisionPlatform)) return -1;
} }
+5 -4
View File
@@ -434,7 +434,7 @@ namespace Barotrauma
{ {
Vector2 normal = Vector2.Normalize(Body.Position - limb.SimPosition); 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); ApplyImpact(impact * Math.Min(limb.Mass / 200.0f, 1), -normal, contact);
} }
@@ -497,8 +497,8 @@ namespace Barotrauma
FixedArray2<Vector2> points; FixedArray2<Vector2> points;
contact.GetWorldManifold(out normal2, out points); contact.GetWorldManifold(out normal2, out points);
Vector2 normalizedVel = limb.character.AnimController.RefLimb.LinearVelocity == Vector2.Zero ? Vector2 normalizedVel = limb.character.AnimController.Collider.LinearVelocity == Vector2.Zero ?
Vector2.Zero : Vector2.Normalize(limb.character.AnimController.RefLimb.LinearVelocity); Vector2.Zero : Vector2.Normalize(limb.character.AnimController.Collider.LinearVelocity);
Vector2 targetPos = ConvertUnits.ToDisplayUnits(points[0] - normal2); Vector2 targetPos = ConvertUnits.ToDisplayUnits(points[0] - normal2);
@@ -558,9 +558,10 @@ namespace Barotrauma
foreach (Limb limb in c.AnimController.Limbs) foreach (Limb limb in c.AnimController.Limbs)
{ {
if (c.AnimController.LowestLimb == limb) continue;
limb.body.ApplyLinearImpulse(limb.Mass * impulse); limb.body.ApplyLinearImpulse(limb.Mass * impulse);
} }
c.AnimController.Collider.ApplyLinearImpulse(c.AnimController.Collider.Mass * impulse);
} }
foreach (Item item in Item.ItemList) foreach (Item item in Item.ItemList)
+1 -1
View File
@@ -664,7 +664,7 @@ namespace Barotrauma.Networking
List<Character> crew = new List<Character>(); List<Character> crew = new List<Character>();
foreach (Character c in Character.CharacterList) 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); crew.Add(c);
} }
+1 -1
View File
@@ -394,7 +394,7 @@ namespace Barotrauma.Networking
if (!(c is AICharacter) || c.IsDead) continue; if (!(c is AICharacter) || c.IsDead) continue;
if (Character.CharacterList.Any( if (Character.CharacterList.Any(
c2 => c2.IsNetworkPlayer && c2 => c2.IsRemotePlayer &&
Vector2.Distance(c2.WorldPosition, c.WorldPosition) < ignoreDistance)) Vector2.Distance(c2.WorldPosition, c.WorldPosition) < ignoreDistance))
{ {
new NetworkEvent(NetworkEventType.EntityUpdate, c.ID, false); new NetworkEvent(NetworkEventType.EntityUpdate, c.ID, false);
-2
View File
@@ -6,8 +6,6 @@ namespace Barotrauma
{ {
static class Physics static class Physics
{ {
private static double alpha;
public const Category CollisionNone = Category.None; public const Category CollisionNone = Category.None;
public const Category CollisionAll = Category.All; public const Category CollisionAll = Category.All;
public const Category CollisionWall = Category.Cat1; public const Category CollisionWall = Category.Cat1;
+158 -8
View File
@@ -53,6 +53,8 @@ namespace Barotrauma
Vector2 offsetFromTargetPos; Vector2 offsetFromTargetPos;
private float netInterpolationState;
public Shape BodyShape public Shape BodyShape
{ {
get { return bodyShape; } get { return bodyShape; }
@@ -118,10 +120,17 @@ namespace Barotrauma
set { dir = value; } set { dir = value; }
} }
private bool isEnabled = true;
private bool isPhysEnabled = true;
public bool Enabled 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; } get { return body.Enabled; }
set { body.Enabled = value; } set { isPhysEnabled = value; if (Enabled) body.Enabled = value; }
} }
public Vector2 SimPosition public Vector2 SimPosition
@@ -192,6 +201,12 @@ namespace Barotrauma
set { body.CollidesWith = value; } set { body.CollidesWith = value; }
} }
private Texture2D bodyShapeTexture;
public Texture2D BodyShapeTexture
{
get { return bodyShapeTexture; }
}
public PhysicsBody(XElement element, float scale = 1.0f) public PhysicsBody(XElement element, float scale = 1.0f)
: this(element, Vector2.Zero, scale) : this(element, Vector2.Zero, scale)
{ {
@@ -227,7 +242,6 @@ namespace Barotrauma
body.Restitution = 0.05f; body.Restitution = 0.05f;
body.BodyType = BodyType.Dynamic; body.BodyType = BodyType.Dynamic;
//body.AngularDamping = Limb.LimbAngularDamping;
body.UserData = this; body.UserData = this;
@@ -245,6 +259,11 @@ namespace Barotrauma
body = BodyFactory.CreateRectangle(GameMain.World, width, height, density); body = BodyFactory.CreateRectangle(GameMain.World, width, height, density);
bodyShape = Shape.Rectangle; 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) else if (radius != 0.0f && height != 0.0f)
{ {
body = BodyFactory.CreateCapsule(GameMain.World, height, radius, density); body = BodyFactory.CreateCapsule(GameMain.World, height, radius, density);
@@ -322,11 +341,51 @@ namespace Barotrauma
} }
body.SetTransform(targetPosition, targetRotation == 0.0f ? body.Rotation : targetRotation); body.SetTransform(targetPosition, targetRotation == 0.0f ? body.Rotation : targetRotation);
//body.LinearVelocity = targetVelocity;
//body.AngularVelocity = targetAngularVelocity;
targetPosition = Vector2.Zero; 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() public void UpdateDrawPosition()
{ {
@@ -361,10 +420,88 @@ namespace Barotrauma
color = Color.Blue; 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> /// <summary>
/// rotate the body towards the target rotation in the "shortest direction" /// rotate the body towards the target rotation in the "shortest direction"
/// </summary> /// </summary>
@@ -374,9 +511,16 @@ namespace Barotrauma
float angle = MathUtils.GetShortestAngle(nextAngle, targetRotation); 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); list.Remove(this);
GameMain.World.RemoveBody(body); GameMain.World.RemoveBody(body);
if (bodyShapeTexture != null)
{
bodyShapeTexture.Dispose();
bodyShapeTexture = null;
}
} }
} }
@@ -173,12 +173,12 @@ namespace Barotrauma
DrawJoints(spriteBatch, limb, limbBodyPos); DrawJoints(spriteBatch, limb, limbBodyPos);
if (limb.BodyShapeTexture == null) continue; //if (limb.BodyShapeTexture == null) continue;
spriteBatch.Draw(limb.BodyShapeTexture, limbBodyPos, //spriteBatch.Draw(limb.BodyShapeTexture, limbBodyPos,
null, Color.White, 0.0f, // null, Color.White, 0.0f,
new Vector2(limb.BodyShapeTexture.Width, limb.BodyShapeTexture.Height) / 2, // new Vector2(limb.BodyShapeTexture.Width, limb.BodyShapeTexture.Height) / 2,
1.0f, SpriteEffects.None, 0.0f); // 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.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); GUI.DrawLine(spriteBatch, limbBodyPos + Vector2.UnitX * 5.0f, limbBodyPos - Vector2.UnitX * 5.0f, Color.White);
+1
View File
@@ -400,6 +400,7 @@ namespace Barotrauma
spriteBatch.Begin(SpriteSortMode.Immediate, spriteBatch.Begin(SpriteSortMode.Immediate,
BlendState.AlphaBlend); BlendState.AlphaBlend);
float r = Math.Min(CharacterHUD.damageOverlayTimer * 0.5f, 0.5f); float r = Math.Min(CharacterHUD.damageOverlayTimer * 0.5f, 0.5f);
spriteBatch.Draw(renderTarget, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), spriteBatch.Draw(renderTarget, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight),
Color.Lerp(new Color(0.1f, 0.1f, 0.1f), Color.Red, r)); Color.Lerp(new Color(0.1f, 0.1f, 0.1f), Color.Red, r));