Merge remote-tracking branch 'refs/remotes/origin/master'
Conflicts: Subsurface/Barotrauma.csproj Subsurface/Source/Characters/AI/EnemyAIController.cs Subsurface/Source/Characters/AICharacter.cs Subsurface/Source/Characters/Character.cs Subsurface/Source/Items/Components/DockingPort.cs Subsurface/Source/Items/Components/Door.cs Subsurface/Source/Items/Item.cs Subsurface/Source/Networking/GameClient.cs Subsurface/Source/Networking/GameServer.cs Subsurface/Source/Physics/PhysicsBody.cs
This commit is contained in:
@@ -93,6 +93,7 @@
|
|||||||
<Compile Include="Source\Characters\CharacterInfo.cs" />
|
<Compile Include="Source\Characters\CharacterInfo.cs" />
|
||||||
<Compile Include="Source\Characters\AI\ISteerable.cs" />
|
<Compile Include="Source\Characters\AI\ISteerable.cs" />
|
||||||
<Compile Include="Source\Characters\DelayedEffect.cs" />
|
<Compile Include="Source\Characters\DelayedEffect.cs" />
|
||||||
|
<Compile Include="Source\Characters\HuskInfection.cs" />
|
||||||
<Compile Include="Source\Characters\Jobs\Job.cs" />
|
<Compile Include="Source\Characters\Jobs\Job.cs" />
|
||||||
<Compile Include="Source\Characters\Jobs\JobPrefab.cs" />
|
<Compile Include="Source\Characters\Jobs\JobPrefab.cs" />
|
||||||
<Compile Include="Source\Characters\AI\SteeringManager.cs" />
|
<Compile Include="Source\Characters\AI\SteeringManager.cs" />
|
||||||
@@ -155,6 +156,7 @@
|
|||||||
<Compile Include="Source\Networking\NetBufferExtensions.cs" />
|
<Compile Include="Source\Networking\NetBufferExtensions.cs" />
|
||||||
<Compile Include="Source\Networking\NetConfig.cs" />
|
<Compile Include="Source\Networking\NetConfig.cs" />
|
||||||
<Compile Include="Source\Networking\NetStats.cs" />
|
<Compile Include="Source\Networking\NetStats.cs" />
|
||||||
|
<Compile Include="Source\Networking\ReliableSender.cs" />
|
||||||
<Compile Include="Source\Networking\RespawnManager.cs" />
|
<Compile Include="Source\Networking\RespawnManager.cs" />
|
||||||
<Compile Include="Source\Networking\ServerLog.cs" />
|
<Compile Include="Source\Networking\ServerLog.cs" />
|
||||||
<Compile Include="Source\Particles\ParticleEmitter.cs" />
|
<Compile Include="Source\Particles\ParticleEmitter.cs" />
|
||||||
@@ -390,6 +392,14 @@
|
|||||||
<Content Include="Content\Characters\Human\head8[black].png">
|
<Content Include="Content\Characters\Human\head8[black].png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="Content\Characters\Human\humanhusk.xml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="Content\Characters\Human\huskappendage.xml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Include="Content\Characters\Human\torso[black].png">
|
<Content Include="Content\Characters\Human\torso[black].png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
@@ -481,6 +491,7 @@
|
|||||||
</Content>
|
</Content>
|
||||||
<Content Include="Content\InfoTexts.xml">
|
<Content Include="Content\InfoTexts.xml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="Content\Items\Artifacts\alientools.png">
|
<Content Include="Content\Items\Artifacts\alientools.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<!-- lower yaw -->
|
<!-- lower yaw -->
|
||||||
<limb id = "1" radius="20" height="240" impacttolerance="50.0">
|
<limb id = "1" radius="20" height="240" impacttolerance="50.0">
|
||||||
<sprite texture="Content/Characters/Coelanth/coelanth.png" sourcerect="425,1,101,309" depth="0.025" origin="0.5,0.5"/>
|
<sprite texture="Content/Characters/Coelanth/coelanth.png" sourcerect="425,1,101,309" depth="0.025" origin="0.5,0.5"/>
|
||||||
<attack type="PinchCCW" range="300" duration="0.5" damage="200" bleedingdamage="50" structuredamage="150" damagetype="slash" targetforce="-50"/>
|
<attack range="300" duration="0.5" damage="200" bleedingdamage="50" structuredamage="150" damagetype="slash" torque="100" targetforce="-50"/>
|
||||||
</limb>
|
</limb>
|
||||||
|
|
||||||
<!-- body -->
|
<!-- body -->
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
<limb id = "3" width="13" height="45" mass = "6" ignorecollisions="true" flip="true" impacttolerance="50.0">
|
<limb id = "3" width="13" height="45" mass = "6" 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 type="PinchCW" range="120" duration="0.5" damage="30" stun="0.1" bleedingdamage="3" structuredamage="50" damagetype="slash" targetforce="-30"/>
|
<attack range="120" duration="0.5" damage="30" stun="0.1" bleedingdamage="3" structuredamage="50" damagetype="slash" 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" mass = "4" type="RightLeg" flip="true">
|
||||||
|
|||||||
@@ -44,12 +44,12 @@
|
|||||||
|
|
||||||
<limb id = "8" width="50" height="320" impacttolerance="100.0">
|
<limb id = "8" width="50" height="320" impacttolerance="100.0">
|
||||||
<sprite texture="Content/Characters/Endworm/endworm.png" sourcerect="755,552,137,470" depth="0.08" origin="0.5,0.5"/>
|
<sprite texture="Content/Characters/Endworm/endworm.png" sourcerect="755,552,137,470" depth="0.08" origin="0.5,0.5"/>
|
||||||
<attack type="PinchCCW" range="800" duration="0.5" damage="30" stun="5.0" structuredamage="500" damagetype="slash"/>
|
<attack range="800" duration="0.5" damage="30" stun="5.0" torque="-100" structuredamage="500" damagetype="slash"/>
|
||||||
</limb>
|
</limb>
|
||||||
|
|
||||||
<limb id = "9" width="50" height="320" impacttolerance="100.0">
|
<limb id = "9" width="50" height="320" impacttolerance="100.0">
|
||||||
<sprite texture="Content/Characters/Endworm/endworm.png" sourcerect="892,552,137,470" depth="0.08" origin="0.6,0.5"/>
|
<sprite texture="Content/Characters/Endworm/endworm.png" sourcerect="892,552,137,470" depth="0.08" origin="0.6,0.5"/>
|
||||||
<attack type="PinchCW" range="800" duration="0.5" damage="30" stun="5.0" structuredamage="500" damagetype="slash"/>
|
<attack range="800" duration="0.5" damage="30" stun="5.0" torque="100" structuredamage="500" damagetype="slash"/>
|
||||||
</limb>
|
</limb>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,12 +28,12 @@
|
|||||||
|
|
||||||
<limb id = "4" width="30" height="239" impacttolerance="100.0">
|
<limb id = "4" width="30" height="239" impacttolerance="100.0">
|
||||||
<sprite texture="Content/Characters/Fractalguardian/fractalguardian.png" sourcerect="183,0,53,238" depth="0.05" origin="0.5,0.5"/>
|
<sprite texture="Content/Characters/Fractalguardian/fractalguardian.png" sourcerect="183,0,53,238" depth="0.05" origin="0.5,0.5"/>
|
||||||
<attack type="PinchCCW" range="150" duration="0.5" damage="30" stun="1.0" damagetype="slash"/>
|
<attack range="150" duration="0.5" damage="30" stun="1.0" torque="-150" damagetype="slash"/>
|
||||||
</limb>
|
</limb>
|
||||||
|
|
||||||
<limb id = "5" width="30" height="239" impacttolerance="100.0">
|
<limb id = "5" width="30" height="239" impacttolerance="100.0">
|
||||||
<sprite texture="Content/Characters/Fractalguardian/fractalguardian.png" sourcerect="236,0,53,238" size="-1,1" depth="0.05" origin="0.5,0.5"/>
|
<sprite texture="Content/Characters/Fractalguardian/fractalguardian.png" sourcerect="236,0,53,238" size="-1,1" depth="0.05" origin="0.5,0.5"/>
|
||||||
<attack type="PinchCW" range="150" duration="0.5" damage="30" stun="1.0" damagetype="slash"/>
|
<attack range="150" duration="0.5" damage="30" stun="1.0" torque="150" damagetype="slash"/>
|
||||||
</limb>
|
</limb>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
</limb>
|
</limb>
|
||||||
<limb id = "2" width="30" height="175" impacttolerance="100">
|
<limb id = "2" width="30" height="175" impacttolerance="100">
|
||||||
<sprite texture="Content/Characters/Fractalguardian/fractalguardian.png" sourcerect="131,0,36,175" depth="0.1" origin="0.5,0.5"/>
|
<sprite texture="Content/Characters/Fractalguardian/fractalguardian.png" sourcerect="131,0,36,175" depth="0.1" origin="0.5,0.5"/>
|
||||||
<attack type="PinchCCW" range="150" duration="0.5" damage="30" stun="1.0" damagetype="slash"/>
|
<attack range="150" duration="0.5" damage="30" stun="1.0" torque="150" damagetype="slash"/>
|
||||||
</limb>
|
</limb>
|
||||||
|
|
||||||
<limb id = "3" width="30" height="178" impacttolerance="100.0">
|
<limb id = "3" width="30" height="178" impacttolerance="100.0">
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
<limb id = "4" width="30" height="175" impacttolerance="100">
|
<limb id = "4" width="30" height="175" impacttolerance="100">
|
||||||
<sprite texture="Content/Characters/Fractalguardian/fractalguardian.png" sourcerect="131,0,36,175" depth="0.1" origin="0.5,0.5"/>
|
<sprite texture="Content/Characters/Fractalguardian/fractalguardian.png" sourcerect="131,0,36,175" depth="0.1" origin="0.5,0.5"/>
|
||||||
<attack type="PinchCW" range="150" duration="0.5" damage="30" stun="1.0" damagetype="slash"/>
|
<attack range="150" duration="0.5" damage="30" stun="1.0" torque="-150" damagetype="slash"/>
|
||||||
</limb>
|
</limb>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<Character name ="human" humanoid="true" genders="true" maleheadid="1,8" femaleheadid="1,7" needsair="false" doesbleed="false">
|
||||||
|
|
||||||
|
<name firstname="Content/Characters/Human/[GENDER]firstnames.txt" lastname="Content/Characters/Human/lastnames.txt" />
|
||||||
|
|
||||||
|
<ragdoll headposition="134" torsoposition="108"
|
||||||
|
stepsize="42.0, 12.0"
|
||||||
|
walkanimspeed="4.58"
|
||||||
|
movementlerp="0.4"
|
||||||
|
legtorque="15.0"
|
||||||
|
thightorque="-5.0"
|
||||||
|
walkspeed="2.0"
|
||||||
|
swimspeed="2.0">
|
||||||
|
|
||||||
|
<!-- head -->
|
||||||
|
<limb id = "0" radius="13" mass = "6" type="Head" attackpriority="2" impacttolerance="5.0">
|
||||||
|
<sprite texture="Content/Characters/Human/[GENDER]head[HEADID].png" sourcerect="1,1,37,38" depth="0.04" origin="0.5,0.5"/>
|
||||||
|
<damagedsprite texture="Content/Characters/Human/damagedhead.png" sourcerect="1,1,37,38" origin="0.5,0.5"/>
|
||||||
|
</limb>
|
||||||
|
<!-- body -->
|
||||||
|
<limb id = "1" radius="14" height="21" mass = "20" type="Torso" attackpriority="3" impacttolerance="10.0">
|
||||||
|
<sprite texture="Content/Characters/Human/[GENDER]torso.png" sourcerect="0,0,29,58" depth="0.05" origin="0.5,0.6"/>
|
||||||
|
<damagedsprite texture="Content/Characters/Human/damagedtorso.png" sourcerect="0,0,29,58" origin="0.5,0.6"/>
|
||||||
|
</limb>
|
||||||
|
<limb id = "12" radius="13" mass = "20" type="Waist" impacttolerance="10.0">
|
||||||
|
<sprite texture="Content/Characters/Human/[GENDER]legs.png" sourcerect="0,0,32,29" depth="0.045" origin="0.5,0.5"/>
|
||||||
|
<damagedsprite texture="Content/Characters/Human/damagedlegs.png" sourcerect="0,0,32,29" origin="0.5,0.5"/>
|
||||||
|
</limb>
|
||||||
|
|
||||||
|
<!-- left arm -->
|
||||||
|
<limb id = "2" radius="8" height="20" mass="3" type="LeftArm">
|
||||||
|
<sprite texture="Content/Characters/Human/[GENDER]torso.png" sourcerect="30,2,17,39" depth="0.15" origin="0.5,0.5"/>
|
||||||
|
<damagedsprite texture="Content/Characters/Human/damagedtorso.png" sourcerect="30,2,17,39" origin="0.5,0.5"/>
|
||||||
|
</limb>
|
||||||
|
<limb id = "3" radius="6" height="26" mass="3" type="LeftHand" pullpos="0.0,-18.0">
|
||||||
|
<sprite texture="Content/Characters/Human/[GENDER]torso.png" sourcerect="49,2,13,47" depth="0.16" origin="0.5,0.5"/>
|
||||||
|
<damagedsprite texture="Content/Characters/Human/damagedtorso.png" sourcerect="49,2,13,47" origin="0.5,0.5"/>
|
||||||
|
</limb>
|
||||||
|
|
||||||
|
<!-- right arm -->
|
||||||
|
<limb id = "4" radius="8" height="20" mass="3" type="RightArm">
|
||||||
|
<sprite texture="Content/Characters/Human/[GENDER]torso.png" sourcerect="30,2,17,39" depth="0.01" origin="0.5,0.5"/>
|
||||||
|
<damagedsprite texture="Content/Characters/Human/damagedtorso.png" sourcerect="30,2,17,39" origin="0.5,0.5"/>
|
||||||
|
</limb>
|
||||||
|
<limb id = "5" radius="6" height="26" mass ="3" type="RightHand" pullpos="0.0,-18.0">
|
||||||
|
<sprite texture="Content/Characters/Human/[GENDER]torso.png" sourcerect="49,2,13,47" origin="0.5,0.5"/>
|
||||||
|
<damagedsprite texture="Content/Characters/Human/damagedtorso.png" sourcerect="49,2,13,47" origin="0.5,0.5"/>
|
||||||
|
</limb>
|
||||||
|
|
||||||
|
<!-- left leg -->
|
||||||
|
<limb id = "6" radius="10" height="30" mass = "8" type="LeftThigh">
|
||||||
|
<sprite texture="Content/Characters/Human/[GENDER]legs.png" sourcerect="0,32,26,48" depth="0.15" origin="0.5,0.5"/>
|
||||||
|
<damagedsprite texture="Content/Characters/Human/damagedlegs.png" sourcerect="0,32,26,48" origin="0.5,0.5"/>
|
||||||
|
</limb>
|
||||||
|
<limb id = "7" radius="6" height="39" mass = "5" type="LeftLeg">
|
||||||
|
<sprite texture="Content/Characters/Human/[GENDER]legs.png" sourcerect="32,0,22,50" depth="0.16" origin="0.5,0.5"/>
|
||||||
|
<damagedsprite texture="Content/Characters/Human/damagedlegs.png" sourcerect="32,0,22,50" origin="0.5,0.5"/>
|
||||||
|
</limb>
|
||||||
|
<limb id = "8" radius="5" height="13" mass = "2" type ="LeftFoot" flip="true" pullpos="-5.0,0.0">
|
||||||
|
<sprite texture="Content/Characters/Human/[GENDER]legs.png" sourcerect="35,53,16,25" depth="0.14" origin="0.5,0.5"/>
|
||||||
|
<damagedsprite texture="Content/Characters/Human/damagedlegs.png" sourcerect="35,53,16,25" origin="0.5,0.5"/>
|
||||||
|
<sound file ="Content/step.ogg"/>
|
||||||
|
</limb>
|
||||||
|
|
||||||
|
<!-- right leg -->
|
||||||
|
<limb id = "9" radius="10" height="30" mass = "8" type="RightThigh">
|
||||||
|
<sprite texture="Content/Characters/Human/[GENDER]legs.png" sourcerect="0,32,26,48" depth="0.11" origin="0.5,0.5"/>
|
||||||
|
<damagedsprite texture="Content/Characters/Human/[GENDER]legs.png" sourcerect="0,32,26,48" origin="0.5,0.5"/>
|
||||||
|
</limb>
|
||||||
|
<limb id = "10" radius="6" height="39" mass = "5" type="RightLeg">
|
||||||
|
<sprite texture="Content/Characters/Human/[GENDER]legs.png" sourcerect="32,0,22,50" depth="0.12" origin="0.5,0.5"/>
|
||||||
|
<damagedsprite texture="Content/Characters/Human/[GENDER]legs.png" sourcerect="32,0,22,50" origin="0.5,0.5"/>
|
||||||
|
</limb>
|
||||||
|
<limb id = "11" radius="5" height="13" mass = "2" type ="RightFoot" flip="true" pullpos="-5.0,0.0">
|
||||||
|
<sprite texture="Content/Characters/Human/[GENDER]legs.png" sourcerect="35,53,16,25" origin="0.5,0.5"/>
|
||||||
|
<damagedsprite texture="Content/Characters/Human/damagedlegs.png" sourcerect="35,53,16,25" origin="0.5,0.5"/>
|
||||||
|
<sound file ="Content/step.ogg"/>
|
||||||
|
</limb>
|
||||||
|
|
||||||
|
|
||||||
|
<limb id = "13" width="10" height="30" mass = "6" attackpriority="2" flip="true" impacttolerance="5.0" pullpos="0.0,25.0">
|
||||||
|
<sprite texture="Content/Characters/Husk/DivingSuit.png" sourcerect="110,76,18,52" depth="0.5" origin="0.5,0.5"/>
|
||||||
|
<attack range="70" duration="0.1" bleedingdamage="3" damage="10" stun="0.5" torque="-50" damagetype="slash" targetforce="10">
|
||||||
|
<StatusEffect type="OnUse" target="Character" HuskInfectionState="0.01" disabledeltatime="true"/>
|
||||||
|
<StatusEffect type="OnUse" target="This" Health="20.0" disabledeltatime="true"/>
|
||||||
|
</attack>
|
||||||
|
</limb>
|
||||||
|
|
||||||
|
<!-- head to body -->
|
||||||
|
<joint limb1="0" limb1anchor="0,-7" limb2="1" limb2anchor="-1,26" lowerlimit="-90" upperlimit="45"/>
|
||||||
|
<joint limb1="1" limb1anchor="0,-17" limb2="12" limb2anchor="0,7" lowerlimit="-10" upperlimit="10"/>
|
||||||
|
|
||||||
|
<!-- body to left arm -->
|
||||||
|
<joint limb1="1" limb1anchor="-3,14" limb2="2" limb2anchor="0,12"/>
|
||||||
|
<joint limb1="2" limb1anchor="0,-16" limb2="3" limb2anchor="-2,19" lowerlimit="5" upperlimit="170"/>
|
||||||
|
<!-- body to right arm -->
|
||||||
|
<joint limb1="1" limb1anchor="-3,14" limb2="4" limb2anchor="0,12"/>
|
||||||
|
<joint limb1="4" limb1anchor="0,-16" limb2="5" limb2anchor="-2,19" lowerlimit="5" upperlimit="170"/>
|
||||||
|
|
||||||
|
<!-- body to left leg -->
|
||||||
|
<joint limb1="12" limb1anchor="0,-1" limb2="6" limb2anchor="0,14" lowerlimit="-30" upperlimit="120"/>
|
||||||
|
<joint limb1="6" limb1anchor="0,-15" limb2="7" limb2anchor="0,20" lowerlimit="-120" upperlimit="0"/>
|
||||||
|
<joint limb1="7" limb1anchor="-3,-21" limb2="8" limb2anchor="5,7" lowerlimit="20" upperlimit="90"/>
|
||||||
|
|
||||||
|
<!-- body to right leg -->
|
||||||
|
<joint limb1="12" limb1anchor="0,-1" limb2="9" limb2anchor="0,14" lowerlimit="-30" upperlimit="120"/>
|
||||||
|
<joint limb1="9" limb1anchor="0,-15" limb2="10" limb2anchor="0,20" lowerlimit="-120" upperlimit="0"/>
|
||||||
|
<joint limb1="10" limb1anchor="-3,-21" limb2="11" limb2anchor="5,7" lowerlimit="20" upperlimit="90"/>
|
||||||
|
|
||||||
|
<joint limb1="1" limb1anchor="25,10" limb2="13" limb2anchor="25,0" lowerlimit="-40" upperlimit="0"/>
|
||||||
|
|
||||||
|
</ragdoll>
|
||||||
|
|
||||||
|
<ai attackhumans="500" attackrooms="5.0" attackweaker="50" attackstronger="-30"
|
||||||
|
sight="0.5" hearing="1.0"
|
||||||
|
attackcooldown="5.0"/>
|
||||||
|
</Character>
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<huskappendage>
|
||||||
|
<!-- spike/tentacle thingy -->
|
||||||
|
<limb id = "13" width="10" height="30" mass = "6" attackpriority="2" flip="true" impacttolerance="5.0" pullpos="0.0,25.0">
|
||||||
|
<sprite texture="Content/Characters/Husk/DivingSuit.png" sourcerect="110,76,18,52" depth="0.5" origin="0.5,0.5"/>
|
||||||
|
<attack range="70" duration="0.1" bleedingdamage="0.5" damage="10" stun="0.5" torque="-50" damagetype="slash" targetforce="10">
|
||||||
|
<StatusEffect type="OnUse" target="Character" HuskInfectionState="0.01"/>
|
||||||
|
<StatusEffect type="OnUse" target="This" Health="10.0" disabledeltatime="true"/>
|
||||||
|
</attack>
|
||||||
|
</limb>
|
||||||
|
|
||||||
|
<joint limb1="1" limb1anchor="25,10" limb2="13" limb2anchor="25,0" lowerlimit="-40" upperlimit="0"/>
|
||||||
|
</huskappendage>
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 17 KiB |
@@ -16,12 +16,22 @@
|
|||||||
|
|
||||||
<!-- 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">
|
||||||
<sprite texture="Content/Characters/Husk/DivingSuit.png" sourcerect="93,1,34,31" depth="0.04" origin="0.5,0.5"/>
|
<sprite texture="Content/Characters/Husk/DivingSuit.png" sourcerect="95,0,33,25" depth="0.04" origin="0.5,0.5"/>
|
||||||
<attack type="PinchCCW" range="100" duration="0.5" damage="10" stun="0.1" bleedingdamage="3" structuredamage="30" damagetype="slash"/>
|
|
||||||
</limb>
|
</limb>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- spike/tentacle thingy -->
|
||||||
|
<limb id = "13" width="10" height="30" mass = "6" attackpriority="2" impacttolerance="5.0" flip="true" pullpos="0.0,25.0">
|
||||||
|
<sprite texture="Content/Characters/Husk/DivingSuit.png" sourcerect="110,76,18,52" depth="0.05" origin="0.5,0.5"/>
|
||||||
|
<attack range="70" duration="0.2" bleedingdamage="0.5" damage="10" stun="0.5" torque="-50" damagetype="slash" targetforce="10">
|
||||||
|
<StatusEffect type="OnUse" target="Character" HuskInfectionState="0.01" disabledeltatime="true"/>
|
||||||
|
<StatusEffect type="OnUse" target="This" Health="1.0" disabledeltatime="true"/>
|
||||||
|
</attack>
|
||||||
|
</limb>
|
||||||
|
|
||||||
<!-- body -->
|
<!-- body -->
|
||||||
<limb id = "1" radius="14" height="21" mass = "20" type="Torso" attackpriority="3" impacttolerance="10.0">
|
<limb id = "1" radius="14" height="21" mass = "20" type="Torso" attackpriority="3" impacttolerance="10.0">
|
||||||
<sprite texture="Content/Characters/Husk/DivingSuit.png" limb="Torso" sourcerect="40,0,42,97" origin="0.5,0.55"/>
|
<sprite texture="Content/Characters/Husk/DivingSuit.png" limb="Torso" sourcerect="41,1,42,96" origin="0.5,0.55"/>
|
||||||
</limb>
|
</limb>
|
||||||
<limb id = "12" radius="13" mass = "20" type="Waist" impacttolerance="10.0">
|
<limb id = "12" radius="13" mass = "20" type="Waist" impacttolerance="10.0">
|
||||||
<sprite texture="Content/Characters/Husk/DivingSuit.png" sourcerect="0,0,1,1" depth="0.045" origin="0.5,0.5"/>
|
<sprite texture="Content/Characters/Husk/DivingSuit.png" sourcerect="0,0,1,1" depth="0.045" origin="0.5,0.5"/>
|
||||||
@@ -68,12 +78,12 @@
|
|||||||
<sound file ="Content/step.ogg"/>
|
<sound file ="Content/step.ogg"/>
|
||||||
</limb>
|
</limb>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- head to body -->
|
<!-- head to body -->
|
||||||
<joint limb1="0" limb1anchor="-10,-10" limb2="1" limb2anchor="-8,33" lowerlimit="0" upperlimit="10"/>
|
<joint limb1="0" limb1anchor="-10,-10" limb2="1" limb2anchor="-3,28" lowerlimit="0" upperlimit="10"/>
|
||||||
<joint limb1="1" limb1anchor="0,-17" limb2="12" limb2anchor="0,15" lowerlimit="30" upperlimit="60"/>
|
<!-- spike to head -->
|
||||||
|
<joint limb1="0" limb1anchor="35,-8" limb2="13" limb2anchor="30,0" lowerlimit="-40" upperlimit="0"/>
|
||||||
|
|
||||||
|
<joint limb1="1" limb1anchor="0,-17" limb2="12" limb2anchor="0,15" lowerlimit="30" upperlimit="60"/>
|
||||||
|
|
||||||
<!-- body to left arm -->
|
<!-- body to left arm -->
|
||||||
<joint limb1="1" limb1anchor="-3,14" limb2="2" limb2anchor="0,12"/>
|
<joint limb1="1" limb1anchor="-3,14" limb2="2" limb2anchor="0,12"/>
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
<!-- ""claw" -->
|
<!-- ""claw" -->
|
||||||
<limb id = "6" width="15" height="63" mass = "4" flip="true" pullpos="0.0,30.0" refjoint="0">
|
<limb id = "6" width="15" height="63" mass = "4" flip="true" pullpos="0.0,30.0" refjoint="0">
|
||||||
<sprite texture="Content/Characters/Mantis/mantis.png" sourcerect="228,1,28,76" depth="0.01" origin="0.5,0.5"/>
|
<sprite texture="Content/Characters/Mantis/mantis.png" sourcerect="228,1,28,76" depth="0.01" origin="0.5,0.5"/>
|
||||||
<attack type="PinchCW" range="200" duration="0.5" damage="30" stun="0.1" bleedingdamage="5" structuredamage="50" damagetype="slash" targetforce="-50"/>
|
<attack range="200" duration="0.5" damage="30" stun="0.1" bleedingdamage="5" structuredamage="50" torque="-20" damagetype="slash" targetforce="-50"/>
|
||||||
<sound file ="Content/Sounds/stepMetal.ogg"/>
|
<sound file ="Content/Sounds/stepMetal.ogg"/>
|
||||||
</limb>
|
</limb>
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<!-- 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 type="Hit" range="700" duration="0.2" damage="200" stun="5" force="300" damagetype="blunt" targetforce="100"/>
|
<attack range="700" duration="0.2" damage="200" stun="5" force="25" damagetype="blunt" targetforce="100"/>
|
||||||
</limb>
|
</limb>
|
||||||
|
|
||||||
<limb id = "1" width="50" height="440" flip="true">
|
<limb id = "1" width="50" height="440" flip="true">
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<limb id = "1" width="16" height="103" impacttolerance="50.0">
|
<limb id = "1" width="16" height="103" impacttolerance="50.0">
|
||||||
<sprite texture="Content/Characters/TigerThresher/tigerthresher.png" sourcerect="391,169,28,110" depth="0.025" origin="0.5,0.5"/>
|
<sprite texture="Content/Characters/TigerThresher/tigerthresher.png" sourcerect="391,169,28,110" depth="0.025" origin="0.5,0.5"/>
|
||||||
<damagedsprite texture="Content/Characters/TigerThresher/damagedtigerthresher.png" sourcerect="391,169,28,110" origin="0.5,0.5"/>
|
<damagedsprite texture="Content/Characters/TigerThresher/damagedtigerthresher.png" sourcerect="391,169,28,110" origin="0.5,0.5"/>
|
||||||
<attack type="PinchCCW" range="200" duration="0.5" damage="150" bleedingdamage="10" structuredamage="200" damagetype="slash" targetforce="-50"/>
|
<attack range="200" duration="0.5" damage="150" bleedingdamage="10" structuredamage="200" damagetype="slash" torque="80" targetforce="-50"/>
|
||||||
</limb>
|
</limb>
|
||||||
|
|
||||||
<!-- body -->
|
<!-- body -->
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
<!-- 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" width="350" height="320" type="Head" 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"/>
|
||||||
</limb>
|
</limb>
|
||||||
|
|
||||||
|
|
||||||
@@ -14,7 +15,6 @@
|
|||||||
<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">
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
<CauseOfDeath.Suffocation>Suffocated</CauseOfDeath.Suffocation>
|
<CauseOfDeath.Suffocation>Suffocated</CauseOfDeath.Suffocation>
|
||||||
<CauseOfDeath.Pressure>Crushed by water pressure</CauseOfDeath.Pressure>
|
<CauseOfDeath.Pressure>Crushed by water pressure</CauseOfDeath.Pressure>
|
||||||
<CauseOfDeath.Burn>Burned to death</CauseOfDeath.Burn>
|
<CauseOfDeath.Burn>Burned to death</CauseOfDeath.Burn>
|
||||||
|
<CauseOfDeath.Husk>Taken over by a parasite</CauseOfDeath.Husk>
|
||||||
<CauseOfDeath.Disconnected>Disconnected</CauseOfDeath.Disconnected>
|
<CauseOfDeath.Disconnected>Disconnected</CauseOfDeath.Disconnected>
|
||||||
|
|
||||||
<Self_CauseOfDeath.Damage>You have succumbed to your injuries.</Self_CauseOfDeath.Damage>
|
<Self_CauseOfDeath.Damage>You have succumbed to your injuries.</Self_CauseOfDeath.Damage>
|
||||||
@@ -19,6 +20,17 @@
|
|||||||
<Self_CauseOfDeath.Suffocation>You have suffocated.</Self_CauseOfDeath.Suffocation>
|
<Self_CauseOfDeath.Suffocation>You have suffocated.</Self_CauseOfDeath.Suffocation>
|
||||||
<Self_CauseOfDeath.Pressure>You have been crushed by water pressure.</Self_CauseOfDeath.Pressure>
|
<Self_CauseOfDeath.Pressure>You have been crushed by water pressure.</Self_CauseOfDeath.Pressure>
|
||||||
<Self_CauseOfDeath.Burn>You have burned to death.</Self_CauseOfDeath.Burn>
|
<Self_CauseOfDeath.Burn>You have burned to death.</Self_CauseOfDeath.Burn>
|
||||||
|
<Self_CauseOfDeath.Husk>The parasite has taken over your body.</Self_CauseOfDeath.Husk>
|
||||||
<Self_CauseOfDeath.Disconnected>You have been disconnected from the server.</Self_CauseOfDeath.Disconnected>
|
<Self_CauseOfDeath.Disconnected>You have been disconnected from the server.</Self_CauseOfDeath.Disconnected>
|
||||||
|
|
||||||
|
<HuskDormant>Your throat feels sore</HuskDormant>
|
||||||
|
<HuskDormant>Your feel feverish</HuskDormant>
|
||||||
|
<HuskDormant>It feels as if something was stuck in your throat</HuskDormant>
|
||||||
|
<HuskDormant>Your muscles are aching</HuskDormant>
|
||||||
|
|
||||||
|
<HuskCantSpeak>You feel something moving in your throat. You try to scream but no sound comes out.</HuskCantSpeak>
|
||||||
|
|
||||||
|
<HuskActivate>A strange chitinous appendage bursts out from your mouth. Use it to inject eggs into a living body by pressing [Attack]!</HuskActivate>
|
||||||
|
|
||||||
|
|
||||||
</infotexts>
|
</infotexts>
|
||||||
@@ -132,6 +132,9 @@
|
|||||||
<RequiredSkill name="Medical" level="60"/>
|
<RequiredSkill name="Medical" level="60"/>
|
||||||
</fabricableitem>
|
</fabricableitem>
|
||||||
|
|
||||||
|
<fabricableitem name="Calyxanide" requireditems="Velonaceps Calyx Eggs, Corrigodone" requiredtime="30">
|
||||||
|
<RequiredSkill name="Medical" level="60"/>
|
||||||
|
</fabricableitem>
|
||||||
</Fabricator>
|
</Fabricator>
|
||||||
|
|
||||||
<ConnectionPanel selectkey="Action" canbeselected = "true">
|
<ConnectionPanel selectkey="Action" canbeselected = "true">
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.4 KiB |
@@ -55,7 +55,7 @@
|
|||||||
|
|
||||||
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6" color="0.2,0.2,0.2,1.0"/>
|
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6" color="0.2,0.2,0.2,1.0"/>
|
||||||
|
|
||||||
<Body width="25" height="5" density="40"/>
|
<Body width="8" height="16" density="40"/>
|
||||||
|
|
||||||
<Holdable slots="Any,RightHand,LeftHand"/>
|
<Holdable slots="Any,RightHand,LeftHand"/>
|
||||||
</Item>
|
</Item>
|
||||||
@@ -68,9 +68,9 @@
|
|||||||
pickdistance="150"
|
pickdistance="150"
|
||||||
description="A mild stimulant which is used as an incredient in the manufacture of various medicines.">
|
description="A mild stimulant which is used as an incredient in the manufacture of various medicines.">
|
||||||
|
|
||||||
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6" />
|
<Sprite texture ="med.png" sourcerect="15,15,8,17" depth="0.6" />
|
||||||
|
|
||||||
<Body width="25" height="5" density="20"/>
|
<Body width="8" height="17" density="20"/>
|
||||||
|
|
||||||
<ItemComponent>
|
<ItemComponent>
|
||||||
<StatusEffect type="OnUse" target="Character" Health="0.1" duration="20"/>
|
<StatusEffect type="OnUse" target="Character" Health="0.1" duration="20"/>
|
||||||
@@ -95,7 +95,7 @@
|
|||||||
|
|
||||||
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6" />
|
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6" />
|
||||||
|
|
||||||
<Body width="25" height="5" density="20"/>
|
<Body width="8" height="16" density="20"/>
|
||||||
|
|
||||||
<Holdable slots="Any,RightHand,LeftHand">
|
<Holdable slots="Any,RightHand,LeftHand">
|
||||||
<StatusEffect type="OnUse" target="Character" Health="-0.3" Oxygen="2.0" duration="10">
|
<StatusEffect type="OnUse" target="Character" Health="-0.3" Oxygen="2.0" duration="10">
|
||||||
@@ -115,7 +115,7 @@
|
|||||||
|
|
||||||
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6" />
|
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6" />
|
||||||
|
|
||||||
<Body width="25" height="5" density="20"/>
|
<Body width="8" height="16" density="20"/>
|
||||||
|
|
||||||
<ItemComponent>
|
<ItemComponent>
|
||||||
<StatusEffect type="OnUse" target="Character" Bleeding="-0.1" duration="10.0"/>
|
<StatusEffect type="OnUse" target="Character" Bleeding="-0.1" duration="10.0"/>
|
||||||
@@ -140,7 +140,7 @@
|
|||||||
|
|
||||||
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
||||||
|
|
||||||
<Body width="25" height="5" density="20"/>
|
<Body width="8" height="16" density="20"/>
|
||||||
|
|
||||||
<ItemComponent>
|
<ItemComponent>
|
||||||
<StatusEffect type="OnUse" target="This" Condition="-25.0" disabledeltatime="true"/>
|
<StatusEffect type="OnUse" target="This" Condition="-25.0" disabledeltatime="true"/>
|
||||||
@@ -164,7 +164,7 @@
|
|||||||
|
|
||||||
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
||||||
|
|
||||||
<Body width="25" height="5" density="20"/>
|
<Body width="8" height="16" density="20"/>
|
||||||
|
|
||||||
<Holdable slots="Any,RightHand,LeftHand">
|
<Holdable slots="Any,RightHand,LeftHand">
|
||||||
<StatusEffect type="OnUse" target="Character" Health="1.0" Oxygen="2.0" Bleeding="-0.05" duration="60.0">
|
<StatusEffect type="OnUse" target="Character" Health="1.0" Oxygen="2.0" Bleeding="-0.05" duration="60.0">
|
||||||
@@ -180,9 +180,9 @@
|
|||||||
Tags="smallitem,chem,medical"
|
Tags="smallitem,chem,medical"
|
||||||
pickdistance="150">
|
pickdistance="150">
|
||||||
|
|
||||||
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
<Sprite texture ="med.png" sourcerect="15,15,8,17" depth="0.6"/>
|
||||||
|
|
||||||
<Body width="25" height="5" density="10"/>
|
<Body width="8" height="17" density="10"/>
|
||||||
|
|
||||||
<Holdable slots="Any,RightHand,LeftHand">
|
<Holdable slots="Any,RightHand,LeftHand">
|
||||||
<StatusEffect type="OnUse" target="Character" Health="-0.1" duration="20.0">
|
<StatusEffect type="OnUse" target="Character" Health="-0.1" duration="20.0">
|
||||||
@@ -204,9 +204,9 @@
|
|||||||
<StatusEffect type="OnUse" target="Character" SpeedMultiplier="0.8" setvalue="true" duration="20.0"/>
|
<StatusEffect type="OnUse" target="Character" SpeedMultiplier="0.8" setvalue="true" duration="20.0"/>
|
||||||
</ItemComponent>
|
</ItemComponent>
|
||||||
|
|
||||||
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
<Sprite texture ="med.png" sourcerect="15,15,8,17" depth="0.6"/>
|
||||||
|
|
||||||
<Body width="25" height="5" density="10"/>
|
<Body width="8" height="7" density="10"/>
|
||||||
|
|
||||||
<Holdable slots="Any,RightHand,LeftHand">
|
<Holdable slots="Any,RightHand,LeftHand">
|
||||||
<StatusEffect type="OnUse" target="Character" SpeedMultiplier="0.8" setvalue="true" duration="20.0">
|
<StatusEffect type="OnUse" target="Character" SpeedMultiplier="0.8" setvalue="true" duration="20.0">
|
||||||
@@ -224,7 +224,7 @@
|
|||||||
|
|
||||||
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
||||||
|
|
||||||
<Body width="25" height="5" density="10"/>
|
<Body width="8" height="16" density="10"/>
|
||||||
|
|
||||||
<Holdable slots="Any,RightHand,LeftHand">
|
<Holdable slots="Any,RightHand,LeftHand">
|
||||||
<StatusEffect type="OnUse" target="Character" Health="-5.0" disabledeltatime="true">
|
<StatusEffect type="OnUse" target="Character" Health="-5.0" disabledeltatime="true">
|
||||||
@@ -242,7 +242,7 @@
|
|||||||
|
|
||||||
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
||||||
|
|
||||||
<Body width="25" height="5" density="10"/>
|
<Body width="8" height="16" density="10"/>
|
||||||
|
|
||||||
<Holdable slots="Any,RightHand,LeftHand">
|
<Holdable slots="Any,RightHand,LeftHand">
|
||||||
<StatusEffect type="OnUse" target="Character" Health="-5.0" disabledeltatime="true">
|
<StatusEffect type="OnUse" target="Character" Health="-5.0" disabledeltatime="true">
|
||||||
@@ -260,7 +260,7 @@
|
|||||||
|
|
||||||
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
||||||
|
|
||||||
<Body width="25" height="5" density="10"/>
|
<Body width="8" height="16" density="10"/>
|
||||||
|
|
||||||
<Holdable slots="Any,RightHand,LeftHand">
|
<Holdable slots="Any,RightHand,LeftHand">
|
||||||
<StatusEffect type="OnFire" target="this" condition="-50"/>
|
<StatusEffect type="OnFire" target="this" condition="-50"/>
|
||||||
@@ -278,9 +278,9 @@
|
|||||||
Tags="smallitem,chem,medical"
|
Tags="smallitem,chem,medical"
|
||||||
pickdistance="150">
|
pickdistance="150">
|
||||||
|
|
||||||
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
<Sprite texture ="med.png" sourcerect="15,15,8,17" depth="0.6"/>
|
||||||
|
|
||||||
<Body width="25" height="5" density="10"/>
|
<Body width="8" height="17" density="10"/>
|
||||||
|
|
||||||
<Holdable slots="Any,RightHand,LeftHand">
|
<Holdable slots="Any,RightHand,LeftHand">
|
||||||
<StatusEffect type="OnUse" target="Character" Health="-5.0" Stun="10" disabledeltatime="true">
|
<StatusEffect type="OnUse" target="Character" Health="-5.0" Stun="10" disabledeltatime="true">
|
||||||
@@ -298,7 +298,7 @@
|
|||||||
|
|
||||||
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
||||||
|
|
||||||
<Body width="25" height="5" density="10"/>
|
<Body width="8" height="16" density="10"/>
|
||||||
|
|
||||||
<Holdable slots="Any,RightHand,LeftHand">
|
<Holdable slots="Any,RightHand,LeftHand">
|
||||||
<StatusEffect type="OnUse" target="Character" Health="-5.0" disabledeltatime="true">
|
<StatusEffect type="OnUse" target="Character" Health="-5.0" disabledeltatime="true">
|
||||||
@@ -314,9 +314,9 @@
|
|||||||
Tags="smallitem,chem,medical"
|
Tags="smallitem,chem,medical"
|
||||||
pickdistance="150">
|
pickdistance="150">
|
||||||
|
|
||||||
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
<Sprite texture ="med.png" sourcerect="15,15,8,17" depth="0.6"/>
|
||||||
|
|
||||||
<Body width="25" height="5" density="10"/>
|
<Body width="8" height="17" density="10"/>
|
||||||
|
|
||||||
<Holdable slots="Any,RightHand,LeftHand">
|
<Holdable slots="Any,RightHand,LeftHand">
|
||||||
<StatusEffect type="OnUse" target="Character" Health="-1.0" duration="60.0">
|
<StatusEffect type="OnUse" target="Character" Health="-1.0" duration="60.0">
|
||||||
@@ -334,7 +334,7 @@
|
|||||||
|
|
||||||
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
||||||
|
|
||||||
<Body width="25" height="5" density="15"/>
|
<Body width="8" height="16" density="25"/>
|
||||||
|
|
||||||
<Holdable slots="Any,RightHand,LeftHand">
|
<Holdable slots="Any,RightHand,LeftHand">
|
||||||
<StatusEffect type="OnUse" target="Character" Health="-5.0" duration="60.0">
|
<StatusEffect type="OnUse" target="Character" Health="-5.0" duration="60.0">
|
||||||
@@ -353,7 +353,7 @@
|
|||||||
|
|
||||||
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
||||||
|
|
||||||
<Body width="25" height="5" density="15"/>
|
<Body width="8" height="16" density="15"/>
|
||||||
|
|
||||||
<Holdable slots="Any,RightHand,LeftHand">
|
<Holdable slots="Any,RightHand,LeftHand">
|
||||||
<StatusEffect type="OnUse" target="Character" SpeedMultiplier="1.5" setvalue="true" duration="60.0">
|
<StatusEffect type="OnUse" target="Character" SpeedMultiplier="1.5" setvalue="true" duration="60.0">
|
||||||
@@ -372,7 +372,7 @@
|
|||||||
|
|
||||||
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
||||||
|
|
||||||
<Body width="25" height="5" density="10"/>
|
<Body width="8" height="16" density="10"/>
|
||||||
|
|
||||||
<Holdable slots="Any,RightHand,LeftHand">
|
<Holdable slots="Any,RightHand,LeftHand">
|
||||||
<StatusEffect type="OnUse" target="Character" Health="-10.0" duration="60.0">
|
<StatusEffect type="OnUse" target="Character" Health="-10.0" duration="60.0">
|
||||||
@@ -380,6 +380,45 @@
|
|||||||
</StatusEffect>
|
</StatusEffect>
|
||||||
</Holdable>
|
</Holdable>
|
||||||
</Item>
|
</Item>
|
||||||
|
|
||||||
|
<Item
|
||||||
|
name="Velonaceps Calyx Eggs"
|
||||||
|
category="Material"
|
||||||
|
spritecolor="0.0,0.0,0.0,1.0"
|
||||||
|
Tags="smallitem,chem,medical"
|
||||||
|
pickdistance="150"
|
||||||
|
description="Dormant eggs of the Europan lifeform colloquially referred to as 'husk parasite'.">
|
||||||
|
|
||||||
|
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
||||||
|
|
||||||
|
<Body width="8" height="16" density="10"/>
|
||||||
|
|
||||||
|
<Holdable slots="Any,RightHand,LeftHand">
|
||||||
|
<StatusEffect type="OnUse" target="Character" HuskInfectionState="0.01">
|
||||||
|
<RequiredItem name="Medical Syringe" type="Container"/>
|
||||||
|
</StatusEffect>
|
||||||
|
</Holdable>
|
||||||
|
</Item>
|
||||||
|
|
||||||
|
<Item
|
||||||
|
name="Calyxanide"
|
||||||
|
category="Material"
|
||||||
|
spritecolor="0.0,0.0,0.0,1.0"
|
||||||
|
Tags="smallitem,chem,medical"
|
||||||
|
pickdistance="150"
|
||||||
|
description="An antiparasitic drug used in the treatment of husk parasite infections.">
|
||||||
|
|
||||||
|
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
|
||||||
|
|
||||||
|
<Body width="8" height="16" density="10"/>
|
||||||
|
|
||||||
|
<Holdable slots="Any,RightHand,LeftHand">
|
||||||
|
<StatusEffect type="OnUse" target="Character" HuskInfectionState="0.0" setvalue="true">
|
||||||
|
<RequiredItem name="Medical Syringe" type="Container"/>
|
||||||
|
</StatusEffect>
|
||||||
|
</Holdable>
|
||||||
|
</Item>
|
||||||
|
|
||||||
</Items>
|
</Items>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@
|
|||||||
width="24" height="32" resizevertical="true"/>
|
width="24" height="32" resizevertical="true"/>
|
||||||
|
|
||||||
<topwindow sprite="Content/Map/testroom.png" sourcerect="625,327,128,80" depth ="0.05"
|
<topwindow sprite="Content/Map/testroom.png" sourcerect="625,327,128,80" depth ="0.05"
|
||||||
width = "128" height ="80" body="true" health="100"/>
|
width = "128" height ="49" body="true" health="100"/>
|
||||||
|
|
||||||
<verticalwindow sprite="Content/Map/testroom.png" sourcerect="399,560,128,224" depth ="0.05"
|
<verticalwindow sprite="Content/Map/testroom.png" sourcerect="399,560,128,224" depth ="0.05"
|
||||||
width = "128" height ="224" body="true" health="100"/>
|
width = "128" height ="224" body="true" health="100"/>
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
@@ -8,7 +8,7 @@
|
|||||||
radarlabel="Infrasonic signal"
|
radarlabel="Infrasonic signal"
|
||||||
failuremessage="Retrieving the artifact failed"
|
failuremessage="Retrieving the artifact failed"
|
||||||
successmessage="The artifact has been succesfully retrieved"
|
successmessage="The artifact has been succesfully retrieved"
|
||||||
spawntype="ruin"
|
spawntype="ruin"
|
||||||
itemname="Skyholder Artifact">
|
itemname="Skyholder Artifact">
|
||||||
<message header="Artifact collected" text="The artifact is now on board. Navigate the submarine out of the cavern to claim the reward."/>
|
<message header="Artifact collected" text="The artifact is now on board. Navigate the submarine out of the cavern to claim the reward."/>
|
||||||
</SalvageMission>
|
</SalvageMission>
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
reward="800"
|
reward="800"
|
||||||
radarlabel="Tiger Thresher"
|
radarlabel="Tiger Thresher"
|
||||||
successmessage="The Tiger Thresher has been killed."
|
successmessage="The Tiger Thresher has been killed."
|
||||||
monsterfile="Content/Characters/TigerThresher/tigerthresher.xml">
|
monsterfile="Content/Characters/Tigerthresher/tigerthresher.xml">
|
||||||
<message header="Target terminated" text="The thresher is dead. Navigate the submarine out of the cavern to claim the reward."/>
|
<message header="Target terminated" text="The thresher is dead. Navigate the submarine out of the cavern to claim the reward."/>
|
||||||
</MonsterMission>
|
</MonsterMission>
|
||||||
|
|
||||||
@@ -113,9 +113,10 @@
|
|||||||
description="Reseachers of [location1] need someone to deliver some dangerous chemicals to [location2] for a reward of 200 credits."
|
description="Reseachers of [location1] need someone to deliver some dangerous chemicals to [location2] for a reward of 200 credits."
|
||||||
commonness="10"
|
commonness="10"
|
||||||
reward="200"
|
reward="200"
|
||||||
successmessage="The chemicals have been successfully delivered.">
|
successmessage="The chemicals have been successfully delivered."
|
||||||
|
requireddeliveryamount="20">
|
||||||
<Items>
|
<Items>
|
||||||
<Item name="Chemical Crate" requireddeliveryamount="20">
|
<Item name="Chemical Crate">
|
||||||
<Item name="Auxiliorizine" amount="5"/>
|
<Item name="Auxiliorizine" amount="5"/>
|
||||||
<Item name="Sulphuric Acid" amount="5"/>
|
<Item name="Sulphuric Acid" amount="5"/>
|
||||||
</Item>
|
</Item>
|
||||||
@@ -127,6 +128,19 @@
|
|||||||
</Items>
|
</Items>
|
||||||
</CargoMission>
|
</CargoMission>
|
||||||
|
|
||||||
|
<CargoMission
|
||||||
|
name="Biohazard"
|
||||||
|
description="Local reseachers are offering 500 credits for delivering a container of husk parasite eggs to [location2]."
|
||||||
|
commonness="10"
|
||||||
|
reward="500"
|
||||||
|
successmessage="The husk eggs have been successfully delivered.">
|
||||||
|
<Items>
|
||||||
|
<Item name="Chemical Crate">
|
||||||
|
<Item name="Velonaceps Calyx Eggs" amount="10"/>
|
||||||
|
</Item>
|
||||||
|
</Items>
|
||||||
|
</CargoMission>
|
||||||
|
|
||||||
<CargoMission
|
<CargoMission
|
||||||
name="Handle with care"
|
name="Handle with care"
|
||||||
description="Local reseachers are offering 2000 credits for delivering a large amount of nitroglycerin to [location2]."
|
description="Local reseachers are offering 2000 credits for delivering a large amount of nitroglycerin to [location2]."
|
||||||
@@ -148,8 +162,9 @@
|
|||||||
description="A local clown syndicate is offering 100 credits for delivering a shipment of clowning supplies to [location2]."
|
description="A local clown syndicate is offering 100 credits for delivering a shipment of clowning supplies to [location2]."
|
||||||
commonness="2"
|
commonness="2"
|
||||||
reward="100"
|
reward="100"
|
||||||
successmessage="The clown gear has been successfully delivered.">
|
successmessage="The clown gear has been successfully delivered."
|
||||||
<Items requireddeliveryamount="35">
|
requireddeliveryamount="35">
|
||||||
|
<Items >
|
||||||
<Item name="Metal Crate">
|
<Item name="Metal Crate">
|
||||||
<Item name="Clown Mask" amount="10"/>
|
<Item name="Clown Mask" amount="10"/>
|
||||||
<Item name="Clown Costume" amount="10"/>
|
<Item name="Clown Costume" amount="10"/>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
musictype="monster"/>
|
musictype="monster"/>
|
||||||
|
|
||||||
<MonsterEvent name="Under attack" description=""
|
<MonsterEvent name="Under attack" description=""
|
||||||
characterfile="Content/Characters/TigerThresher/tigerthresher.xml"
|
characterfile="Content/Characters/Tigerthresher/tigerthresher.xml"
|
||||||
commonness="10"
|
commonness="10"
|
||||||
difficulty="20"
|
difficulty="20"
|
||||||
minamount="1" maxamount="3"
|
minamount="1" maxamount="3"
|
||||||
|
|||||||
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("0.5.0.3")]
|
[assembly: AssemblyVersion("0.5.1.1")]
|
||||||
[assembly: AssemblyFileVersion("0.5.0.3")]
|
[assembly: AssemblyFileVersion("0.5.1.1")]
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ namespace Barotrauma
|
|||||||
public enum AiState { None, Attack, GoTo, Escape }
|
public enum AiState { None, Attack, GoTo, Escape }
|
||||||
public enum SteeringState { Wander, Seek, Escape }
|
public enum SteeringState { Wander, Seek, Escape }
|
||||||
|
|
||||||
|
public bool Enabled;
|
||||||
|
|
||||||
public readonly Character Character;
|
public readonly Character Character;
|
||||||
|
|
||||||
protected AiState state;
|
protected AiState state;
|
||||||
@@ -51,6 +53,8 @@ namespace Barotrauma
|
|||||||
public AIController (Character c)
|
public AIController (Character c)
|
||||||
{
|
{
|
||||||
Character = c;
|
Character = c;
|
||||||
|
|
||||||
|
Enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void DebugDraw(SpriteBatch spriteBatch) { }
|
public virtual void DebugDraw(SpriteBatch spriteBatch) { }
|
||||||
|
|||||||
@@ -218,24 +218,27 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
//steeringManager.SteeringAvoid(deltaTime, 1.0f);
|
//steeringManager.SteeringAvoid(deltaTime, 1.0f);
|
||||||
steeringManager.SteeringSeek(attackSimPosition);
|
|
||||||
|
|
||||||
|
Limb attackLimb = attackingLimb;
|
||||||
//check if any of the limbs is close enough to attack the target
|
//check if any of the limbs is close enough to attack the target
|
||||||
if (attackingLimb == null)
|
if (attackingLimb == null)
|
||||||
{
|
{
|
||||||
foreach (Limb limb in Character.AnimController.Limbs)
|
foreach (Limb limb in Character.AnimController.Limbs)
|
||||||
{
|
{
|
||||||
if (limb.attack==null || limb.attack.Type == AttackType.None) continue;
|
if (limb.attack==null) continue;
|
||||||
|
attackLimb = limb;
|
||||||
|
|
||||||
if (ConvertUnits.ToDisplayUnits(Vector2.Distance(limb.SimPosition, attackSimPosition)) > limb.attack.Range) continue;
|
if (ConvertUnits.ToDisplayUnits(Vector2.Distance(limb.SimPosition, attackSimPosition)) > limb.attack.Range) continue;
|
||||||
|
|
||||||
attackingLimb = limb;
|
attackingLimb = limb;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
if (attackLimb != null)
|
||||||
UpdateLimbAttack(deltaTime, attackingLimb, attackSimPosition);
|
{
|
||||||
|
steeringManager.SteeringSeek(attackSimPosition - (attackLimb.SimPosition - SimPosition));
|
||||||
|
if (attackingLimb != null) UpdateLimbAttack(deltaTime, attackingLimb, attackSimPosition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateCoolDown(Vector2 attackPosition, float deltaTime)
|
private void UpdateCoolDown(Vector2 attackPosition, float deltaTime)
|
||||||
@@ -330,84 +333,15 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void UpdateLimbAttack(float deltaTime, Limb limb, Vector2 attackPosition)
|
private void UpdateLimbAttack(float deltaTime, Limb limb, Vector2 attackPosition)
|
||||||
{
|
{
|
||||||
IDamageable damageTarget = null;
|
var damageTarget = (wallAttackPos != Vector2.Zero && targetEntity != null) ? targetEntity : selectedAiTarget.Entity as IDamageable;
|
||||||
|
|
||||||
float dist = ConvertUnits.ToDisplayUnits(Vector2.Distance(limb.SimPosition, attackPosition));
|
limb.UpdateAttack(deltaTime, attackPosition, damageTarget);
|
||||||
|
|
||||||
switch (limb.attack.Type)
|
if (limb.AttackTimer >= limb.attack.Duration)
|
||||||
{
|
|
||||||
case AttackType.PinchCW:
|
|
||||||
case AttackType.PinchCCW:
|
|
||||||
|
|
||||||
float dir = (limb.attack.Type == AttackType.PinchCW) ? 1.0f : -1.0f;
|
|
||||||
|
|
||||||
damageTarget = (wallAttackPos != Vector2.Zero && targetEntity != null) ? targetEntity : selectedAiTarget.Entity as IDamageable;
|
|
||||||
|
|
||||||
attackTimer += deltaTime*0.05f;
|
|
||||||
|
|
||||||
if (damageTarget == null)
|
|
||||||
{
|
|
||||||
attackTimer = limb.attack.Duration;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dist < limb.attack.Range * 0.5f)
|
|
||||||
{
|
|
||||||
attackTimer += deltaTime;
|
|
||||||
limb.body.ApplyTorque(limb.Mass * 50.0f * Character.AnimController.Dir * dir);
|
|
||||||
|
|
||||||
if (attackTimer >= limb.attack.Duration)
|
|
||||||
{
|
|
||||||
limb.attack.DoDamage(Character, damageTarget, limb.WorldPosition, 1.0f, (limb.soundTimer <= 0.0f));
|
|
||||||
|
|
||||||
limb.soundTimer = Limb.SoundInterval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 diff = attackPosition - limb.SimPosition;
|
|
||||||
if (diff.LengthSquared() > 0.00001f)
|
|
||||||
{
|
|
||||||
limb.body.ApplyLinearImpulse(limb.Mass * 10.0f *
|
|
||||||
Vector2.Normalize(attackPosition - limb.SimPosition));
|
|
||||||
}
|
|
||||||
|
|
||||||
steeringManager.SteeringSeek(attackPosition + (limb.SimPosition-SimPosition), 5.0f);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case AttackType.Hit:
|
|
||||||
damageTarget = (wallAttackPos != Vector2.Zero && targetEntity != null) ? targetEntity : selectedAiTarget.Entity as IDamageable;
|
|
||||||
|
|
||||||
if (damageTarget == null)
|
|
||||||
{
|
|
||||||
attackTimer = limb.attack.Duration;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dist < limb.attack.Range)
|
|
||||||
{
|
|
||||||
attackTimer += deltaTime;
|
|
||||||
limb.body.ApplyForce(limb.Mass * limb.attack.Force * Vector2.Normalize(attackPosition - limb.SimPosition));
|
|
||||||
|
|
||||||
if (damageTarget is Character && dist<limb.attack.Range*0.5f)
|
|
||||||
{
|
|
||||||
limb.attack.DoDamage(Character, damageTarget, limb.WorldPosition, deltaTime, (limb.soundTimer <= 0.0f));
|
|
||||||
limb.soundTimer = Limb.SoundInterval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
steeringManager.SteeringSeek(attackPosition + (limb.SimPosition-SimPosition), 5.0f);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
attackTimer = limb.attack.Duration;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attackTimer >= limb.attack.Duration)
|
|
||||||
{
|
{
|
||||||
wallAttackPos = Vector2.Zero;
|
wallAttackPos = Vector2.Zero;
|
||||||
attackTimer = 0.0f;
|
limb.AttackTimer = 0.0f;
|
||||||
if (Vector2.Distance(limb.SimPosition, attackPosition)<5.0) coolDownTimer = attackCoolDown;
|
if (Vector2.Distance(limb.SimPosition, attackPosition)<5.0) coolDownTimer = attackCoolDown;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (isDead || health <= 0.0f) return;
|
if (isDead || health <= 0.0f) return;
|
||||||
|
|
||||||
if (Controlled == this) return;
|
if (Controlled == this || !aiController.Enabled) return;
|
||||||
|
|
||||||
if (soundTimer > 0)
|
if (soundTimer > 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -338,13 +338,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (!onGround || (LowestLimb.SimPosition.Y - floorY > 0.5f && stairs == null)) return;
|
if (!onGround || (LowestLimb.SimPosition.Y - floorY > 0.5f && stairs == null)) return;
|
||||||
|
|
||||||
float? ceilingY = null;
|
//float? ceilingY = null;
|
||||||
if (Submarine.PickBody(head.SimPosition, head.SimPosition + Vector2.UnitY, null, Physics.CollisionWall)!=null)
|
//if (Submarine.PickBody(head.SimPosition, head.SimPosition + Vector2.UnitY, null, Physics.CollisionWall)!=null)
|
||||||
{
|
//{
|
||||||
ceilingY = Submarine.LastPickedPosition.Y;
|
// ceilingY = Submarine.LastPickedPosition.Y;
|
||||||
|
|
||||||
if (ceilingY - floorY < HeadPosition) Crouching = true;
|
// 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);
|
||||||
|
|
||||||
@@ -457,23 +457,19 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
float movementFactor = (movement.X / 4.0f) * movement.X * Math.Sign(movement.X);
|
float movementFactor = (movement.X / 4.0f) * movement.X * Math.Sign(movement.X);
|
||||||
|
|
||||||
|
for (int i = -1; i < 2; i += 2)
|
||||||
|
|
||||||
//MoveLimb(leftFoot, footPos, 2.5f);
|
|
||||||
|
|
||||||
for (int i = -1; i < 2; i+=2 )
|
|
||||||
{
|
{
|
||||||
Vector2 footPos = new Vector2(
|
Vector2 footPos = new Vector2(
|
||||||
Crouching ? waist.SimPosition.X + Math.Sign(stepSize.X*i)*Dir*0.3f : waist.SimPosition.X,
|
Crouching ? waist.SimPosition.X + Math.Sign(stepSize.X * i) * Dir * 0.3f : GetCenterOfMass().X,
|
||||||
colliderPos.Y - 0.2f);
|
colliderPos.Y - 0.1f);
|
||||||
|
|
||||||
var foot = i == -1 ? rightFoot : leftFoot;
|
var foot = i == -1 ? rightFoot : leftFoot;
|
||||||
|
|
||||||
MoveLimb(foot, footPos, Math.Abs(foot.SimPosition.X - footPos.X)*50.0f);
|
MoveLimb(foot, footPos, Math.Abs(foot.SimPosition.X - footPos.X) * 100.0f, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
leftFoot.body.SmoothRotate(Dir * MathHelper.PiOver2, 5.0f);
|
leftFoot.body.SmoothRotate(Dir * MathHelper.PiOver2, 50.0f);
|
||||||
rightFoot.body.SmoothRotate(Dir * MathHelper.PiOver2, 5.0f);
|
rightFoot.body.SmoothRotate(Dir * MathHelper.PiOver2, 50.0f);
|
||||||
|
|
||||||
if (!rightHand.Disabled)
|
if (!rightHand.Disabled)
|
||||||
{
|
{
|
||||||
@@ -1183,7 +1179,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Vector2 position = limb.SimPosition;
|
Vector2 position = limb.SimPosition;
|
||||||
|
|
||||||
if (!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);
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
protected float strongestImpact;
|
protected float strongestImpact;
|
||||||
|
|
||||||
float headPosition, headAngle;
|
public float headPosition, headAngle;
|
||||||
float torsoPosition, torsoAngle;
|
public float torsoPosition, torsoAngle;
|
||||||
|
|
||||||
protected double onFloorTimer;
|
protected double onFloorTimer;
|
||||||
|
|
||||||
@@ -232,7 +232,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Limb limb = new Limb(character, subElement, scale);
|
Limb limb = new Limb(character, subElement, scale);
|
||||||
|
|
||||||
|
|
||||||
limb.body.FarseerBody.OnCollision += OnLimbCollision;
|
limb.body.FarseerBody.OnCollision += OnLimbCollision;
|
||||||
|
|
||||||
Limbs[ID] = limb;
|
Limbs[ID] = limb;
|
||||||
@@ -240,38 +239,7 @@ namespace Barotrauma
|
|||||||
if (!limbDictionary.ContainsKey(limb.type)) limbDictionary.Add(limb.type, limb);
|
if (!limbDictionary.ContainsKey(limb.type)) limbDictionary.Add(limb.type, limb);
|
||||||
break;
|
break;
|
||||||
case "joint":
|
case "joint":
|
||||||
Byte limb1ID = Convert.ToByte(subElement.Attribute("limb1").Value);
|
AddJoint(subElement, scale);
|
||||||
Byte limb2ID = Convert.ToByte(subElement.Attribute("limb2").Value);
|
|
||||||
|
|
||||||
Vector2 limb1Pos = ToolBox.GetAttributeVector2(subElement, "limb1anchor", Vector2.Zero) * scale;
|
|
||||||
limb1Pos = ConvertUnits.ToSimUnits(limb1Pos);
|
|
||||||
|
|
||||||
Vector2 limb2Pos = ToolBox.GetAttributeVector2(subElement, "limb2anchor", Vector2.Zero) * scale;
|
|
||||||
limb2Pos = ConvertUnits.ToSimUnits(limb2Pos);
|
|
||||||
|
|
||||||
RevoluteJoint joint = new RevoluteJoint(Limbs[limb1ID].body.FarseerBody, Limbs[limb2ID].body.FarseerBody, limb1Pos, limb2Pos);
|
|
||||||
|
|
||||||
joint.CollideConnected = false;
|
|
||||||
|
|
||||||
if (subElement.Attribute("lowerlimit")!=null)
|
|
||||||
{
|
|
||||||
joint.LimitEnabled = true;
|
|
||||||
joint.LowerLimit = float.Parse(subElement.Attribute("lowerlimit").Value) * ((float)Math.PI / 180.0f);
|
|
||||||
joint.UpperLimit = float.Parse(subElement.Attribute("upperlimit").Value) * ((float)Math.PI / 180.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
joint.MotorEnabled = true;
|
|
||||||
joint.MaxMotorTorque = 0.25f;
|
|
||||||
|
|
||||||
GameMain.World.AddJoint(joint);
|
|
||||||
|
|
||||||
for (int i = 0; i < limbJoints.Length; i++ )
|
|
||||||
{
|
|
||||||
if (limbJoints[i] != null) continue;
|
|
||||||
|
|
||||||
limbJoints[i] = joint;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -309,6 +277,58 @@ namespace Barotrauma
|
|||||||
FindLowestLimb();
|
FindLowestLimb();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddJoint(XElement subElement, float scale = 1.0f)
|
||||||
|
{
|
||||||
|
byte limb1ID = Convert.ToByte(subElement.Attribute("limb1").Value);
|
||||||
|
byte limb2ID = Convert.ToByte(subElement.Attribute("limb2").Value);
|
||||||
|
|
||||||
|
Vector2 limb1Pos = ToolBox.GetAttributeVector2(subElement, "limb1anchor", Vector2.Zero) * scale;
|
||||||
|
limb1Pos = ConvertUnits.ToSimUnits(limb1Pos);
|
||||||
|
|
||||||
|
Vector2 limb2Pos = ToolBox.GetAttributeVector2(subElement, "limb2anchor", Vector2.Zero) * scale;
|
||||||
|
limb2Pos = ConvertUnits.ToSimUnits(limb2Pos);
|
||||||
|
|
||||||
|
RevoluteJoint joint = new RevoluteJoint(Limbs[limb1ID].body.FarseerBody, Limbs[limb2ID].body.FarseerBody, limb1Pos, limb2Pos);
|
||||||
|
|
||||||
|
joint.CollideConnected = false;
|
||||||
|
|
||||||
|
if (subElement.Attribute("lowerlimit") != null)
|
||||||
|
{
|
||||||
|
joint.LimitEnabled = true;
|
||||||
|
joint.LowerLimit = float.Parse(subElement.Attribute("lowerlimit").Value) * ((float)Math.PI / 180.0f);
|
||||||
|
joint.UpperLimit = float.Parse(subElement.Attribute("upperlimit").Value) * ((float)Math.PI / 180.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
joint.MotorEnabled = true;
|
||||||
|
joint.MaxMotorTorque = 0.25f;
|
||||||
|
|
||||||
|
GameMain.World.AddJoint(joint);
|
||||||
|
|
||||||
|
for (int i = 0; i < limbJoints.Length; i++)
|
||||||
|
{
|
||||||
|
if (limbJoints[i] != null) continue;
|
||||||
|
|
||||||
|
limbJoints[i] = joint;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.Resize(ref limbJoints, limbJoints.Length + 1);
|
||||||
|
limbJoints[limbJoints.Length - 1] = joint;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddLimb(Limb limb)
|
||||||
|
{
|
||||||
|
limb.body.FarseerBody.OnCollision += OnLimbCollision;
|
||||||
|
|
||||||
|
Array.Resize(ref Limbs, Limbs.Length + 1);
|
||||||
|
|
||||||
|
Limbs[Limbs.Length-1] = limb;
|
||||||
|
|
||||||
|
Mass += limb.Mass;
|
||||||
|
if (!limbDictionary.ContainsKey(limb.type)) limbDictionary.Add(limb.type, limb);
|
||||||
|
}
|
||||||
|
|
||||||
public bool OnLimbCollision(Fixture f1, Fixture f2, Contact contact)
|
public bool OnLimbCollision(Fixture f1, Fixture f2, Contact contact)
|
||||||
{
|
{
|
||||||
Structure structure = f2.Body.UserData as Structure;
|
Structure structure = f2.Body.UserData as Structure;
|
||||||
|
|||||||
@@ -2,22 +2,18 @@
|
|||||||
using Barotrauma.Particles;
|
using Barotrauma.Particles;
|
||||||
using System;
|
using System;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
enum CauseOfDeath
|
enum CauseOfDeath
|
||||||
{
|
{
|
||||||
Damage, Bloodloss, Pressure, Suffocation, Drowning, Burn, Disconnected
|
Damage, Bloodloss, Pressure, Suffocation, Drowning, Burn, Husk, Disconnected
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum DamageType { None, Blunt, Slash, Burn }
|
public enum DamageType { None, Blunt, Slash, Burn }
|
||||||
|
|
||||||
public enum AttackType
|
|
||||||
{
|
|
||||||
None, PinchCW, PinchCCW, Hit
|
|
||||||
}
|
|
||||||
|
|
||||||
struct AttackResult
|
struct AttackResult
|
||||||
{
|
{
|
||||||
public readonly float Damage;
|
public readonly float Damage;
|
||||||
@@ -36,8 +32,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
class Attack
|
class Attack
|
||||||
{
|
{
|
||||||
|
|
||||||
public readonly AttackType Type;
|
|
||||||
public readonly float Range;
|
public readonly float Range;
|
||||||
public readonly float Duration;
|
public readonly float Duration;
|
||||||
|
|
||||||
@@ -47,8 +41,12 @@ namespace Barotrauma
|
|||||||
private readonly float damage;
|
private readonly float damage;
|
||||||
private readonly float bleedingDamage;
|
private readonly float bleedingDamage;
|
||||||
|
|
||||||
|
private readonly List<StatusEffect> statusEffects;
|
||||||
|
|
||||||
public readonly float Force;
|
public readonly float Force;
|
||||||
|
|
||||||
|
public readonly float Torque;
|
||||||
|
|
||||||
public readonly float TargetForce;
|
public readonly float TargetForce;
|
||||||
|
|
||||||
private Sound sound;
|
private Sound sound;
|
||||||
@@ -74,23 +72,8 @@ namespace Barotrauma
|
|||||||
return (Duration == 0.0f) ? structureDamage : structureDamage * deltaTime;
|
return (Duration == 0.0f) ? structureDamage : structureDamage * deltaTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//public Attack(AttackType type, float range,)
|
|
||||||
//{
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
public Attack(XElement element)
|
public Attack(XElement element)
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
Type = (AttackType)Enum.Parse(typeof(AttackType), element.Attribute("type").Value, true);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
Type = AttackType.None;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DamageType = (DamageType)Enum.Parse(typeof(DamageType), ToolBox.GetAttributeString(element, "damagetype", "None"), true);
|
DamageType = (DamageType)Enum.Parse(typeof(DamageType), ToolBox.GetAttributeString(element, "damagetype", "None"), true);
|
||||||
@@ -106,9 +89,10 @@ namespace Barotrauma
|
|||||||
bleedingDamage = ToolBox.GetAttributeFloat(element, "bleedingdamage", 0.0f);
|
bleedingDamage = ToolBox.GetAttributeFloat(element, "bleedingdamage", 0.0f);
|
||||||
|
|
||||||
Force = ToolBox.GetAttributeFloat(element,"force", 0.0f);
|
Force = ToolBox.GetAttributeFloat(element,"force", 0.0f);
|
||||||
|
|
||||||
TargetForce = ToolBox.GetAttributeFloat(element, "targetforce", 0.0f);
|
TargetForce = ToolBox.GetAttributeFloat(element, "targetforce", 0.0f);
|
||||||
|
|
||||||
|
Torque = ToolBox.GetAttributeFloat(element, "torque", 0.0f);
|
||||||
|
|
||||||
Stun = ToolBox.GetAttributeFloat(element, "stun", 0.0f);
|
Stun = ToolBox.GetAttributeFloat(element, "stun", 0.0f);
|
||||||
|
|
||||||
string soundPath = ToolBox.GetAttributeString(element, "sound", "");
|
string soundPath = ToolBox.GetAttributeString(element, "sound", "");
|
||||||
@@ -123,10 +107,20 @@ namespace Barotrauma
|
|||||||
|
|
||||||
priority = ToolBox.GetAttributeFloat(element, "priority", 1.0f);
|
priority = ToolBox.GetAttributeFloat(element, "priority", 1.0f);
|
||||||
|
|
||||||
|
statusEffects = new List<StatusEffect>();
|
||||||
|
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (XElement subElement in element.Elements())
|
||||||
{
|
{
|
||||||
if (subElement.Name.ToString().ToLowerInvariant() != "particleemitter") continue;
|
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||||
particleEmitterPrefab = new ParticleEmitterPrefab(subElement);
|
{
|
||||||
|
case "particleemitter":
|
||||||
|
particleEmitterPrefab = new ParticleEmitterPrefab(subElement);
|
||||||
|
break;
|
||||||
|
case "statuseffect":
|
||||||
|
statusEffects.Add(StatusEffect.Load(subElement));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,8 +137,23 @@ namespace Barotrauma
|
|||||||
sound.Play(1.0f, 500.0f, worldPosition);
|
sound.Play(1.0f, 500.0f, worldPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
return target.AddDamage(attacker, worldPosition, this, deltaTime, playSound);
|
var attackResult = target.AddDamage(attacker, worldPosition, this, deltaTime, playSound);
|
||||||
|
|
||||||
|
var effectType = attackResult.Damage > 0.0f ? ActionType.OnUse : ActionType.OnFailure;
|
||||||
|
|
||||||
|
foreach (StatusEffect effect in statusEffects)
|
||||||
|
{
|
||||||
|
if (effect.Targets.HasFlag(StatusEffect.TargetType.This) && attacker is Character)
|
||||||
|
{
|
||||||
|
effect.Apply(effectType, deltaTime, (Character)attacker, (Character)attacker);
|
||||||
|
}
|
||||||
|
if (effect.Targets.HasFlag(StatusEffect.TargetType.Character) && target is Character)
|
||||||
|
{
|
||||||
|
effect.Apply(effectType, deltaTime, (Character)target, (Character)target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return attackResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,6 +112,8 @@ namespace Barotrauma
|
|||||||
//which AIstate each sound is for
|
//which AIstate each sound is for
|
||||||
private AIController.AiState[] soundStates;
|
private AIController.AiState[] soundStates;
|
||||||
|
|
||||||
|
private float attackCoolDown;
|
||||||
|
|
||||||
public Entity ViewTarget
|
public Entity ViewTarget
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
@@ -248,6 +250,7 @@ namespace Barotrauma
|
|||||||
public bool NeedsAir
|
public bool NeedsAir
|
||||||
{
|
{
|
||||||
get { return needsAir; }
|
get { return needsAir; }
|
||||||
|
set { needsAir = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public float Oxygen
|
public float Oxygen
|
||||||
@@ -298,6 +301,38 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HuskInfection huskInfection;
|
||||||
|
public float HuskInfectionState
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return huskInfection == null ? 0.0f : huskInfection.IncubationTimer;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (ConfigPath != humanConfigFile) return;
|
||||||
|
|
||||||
|
if (value <= 0.0f)
|
||||||
|
{
|
||||||
|
if (huskInfection != null && huskInfection.State == HuskInfection.InfectionState.Active) return;
|
||||||
|
huskInfection = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (huskInfection == null) huskInfection = new HuskInfection(this);
|
||||||
|
huskInfection.IncubationTimer = MathHelper.Clamp(value, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanSpeak
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return !IsUnconscious && Stun <= 0.0f && (huskInfection == null || huskInfection.CanSpeak);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool DoesBleed
|
public bool DoesBleed
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
@@ -310,7 +345,6 @@ namespace Barotrauma
|
|||||||
private set;
|
private set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public float PressureTimer
|
public float PressureTimer
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
@@ -474,14 +508,17 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Properties = ObjectProperty.GetProperties(this);
|
Properties = ObjectProperty.GetProperties(this);
|
||||||
|
|
||||||
if (file == humanConfigFile)
|
Info = characterInfo;
|
||||||
|
if (file == humanConfigFile && characterInfo == null)
|
||||||
{
|
{
|
||||||
Info = characterInfo == null ? new CharacterInfo(file) : characterInfo;
|
Info = new CharacterInfo(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
XDocument doc = ToolBox.TryLoadXml(file);
|
XDocument doc = ToolBox.TryLoadXml(file);
|
||||||
if (doc == null || doc.Root == null) return;
|
if (doc == null || doc.Root == null) return;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SpeciesName = ToolBox.GetAttributeString(doc.Root, "name", "Unknown");
|
SpeciesName = ToolBox.GetAttributeString(doc.Root, "name", "Unknown");
|
||||||
|
|
||||||
IsHumanoid = ToolBox.GetAttributeBool(doc.Root, "humanoid", false);
|
IsHumanoid = ToolBox.GetAttributeBool(doc.Root, "humanoid", false);
|
||||||
@@ -696,6 +733,49 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (attackCoolDown >0.0f)
|
||||||
|
{
|
||||||
|
attackCoolDown -= deltaTime;
|
||||||
|
}
|
||||||
|
else if (IsKeyDown(InputType.Attack))
|
||||||
|
{
|
||||||
|
var attackLimb = AnimController.Limbs.FirstOrDefault(l => l.attack != null);
|
||||||
|
|
||||||
|
if (attackLimb != null)
|
||||||
|
{
|
||||||
|
Vector2 attackPos =
|
||||||
|
attackLimb.SimPosition + Vector2.Normalize(cursorPosition - attackLimb.Position) * ConvertUnits.ToSimUnits(attackLimb.attack.Range);
|
||||||
|
|
||||||
|
var body = Submarine.PickBody(
|
||||||
|
attackLimb.SimPosition,
|
||||||
|
attackPos,
|
||||||
|
AnimController.Limbs.Select(l => l.body.FarseerBody).ToList(),
|
||||||
|
Physics.CollisionCharacter | Physics.CollisionWall);
|
||||||
|
|
||||||
|
IDamageable attackTarget = null;
|
||||||
|
if (body != null)
|
||||||
|
{
|
||||||
|
if (body.UserData is IDamageable)
|
||||||
|
{
|
||||||
|
attackTarget = (IDamageable)body.UserData;
|
||||||
|
}
|
||||||
|
else if (body.UserData is Limb)
|
||||||
|
{
|
||||||
|
attackTarget = ((Limb)body.UserData).character;
|
||||||
|
}
|
||||||
|
attackPos = Submarine.LastPickedPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
attackLimb.UpdateAttack(deltaTime, attackPos, attackTarget);
|
||||||
|
|
||||||
|
if (attackLimb.AttackTimer > attackLimb.attack.Duration)
|
||||||
|
{
|
||||||
|
attackLimb.AttackTimer = 0.0f;
|
||||||
|
attackCoolDown = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < selectedItems.Length; i++ )
|
for (int i = 0; i < selectedItems.Length; i++ )
|
||||||
{
|
{
|
||||||
if (selectedItems[i] == null) continue;
|
if (selectedItems[i] == null) continue;
|
||||||
@@ -784,6 +864,14 @@ namespace Barotrauma
|
|||||||
return owner.isDead || owner.IsUnconscious || owner.Stun > 0.0f || owner.LockHands;
|
return owner.isDead || owner.IsUnconscious || owner.Stun > 0.0f || owner.LockHands;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inventory.Owner is Item)
|
||||||
|
{
|
||||||
|
var owner = (Item)inventory.Owner;
|
||||||
|
if (!CanAccessItem(owner))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -791,10 +879,22 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (item.ParentInventory != null)
|
if (item.ParentInventory != null)
|
||||||
{
|
{
|
||||||
if (!CanAccessInventory(item.ParentInventory)) return false;
|
return CanAccessInventory(item.ParentInventory);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
float maxDist = item.PickDistance * 1.2f;
|
||||||
|
if (maxDist <= 0.01f)
|
||||||
|
{
|
||||||
|
maxDist = 150.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Vector2.Distance(WorldPosition, item.WorldPosition) < maxDist ||
|
||||||
|
item.IsInsideTrigger(WorldPosition))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return item.GetComponent<Items.Components.Ladder>() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Item FindClosestItem(Vector2 mouseSimPos, out float distance)
|
private Item FindClosestItem(Vector2 mouseSimPos, out float distance)
|
||||||
@@ -859,7 +959,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
foreach (Limb limb in selectedCharacter.AnimController.Limbs)
|
foreach (Limb limb in selectedCharacter.AnimController.Limbs)
|
||||||
{
|
{
|
||||||
limb.pullJoint.Enabled = false;
|
if (limb.pullJoint != null) limb.pullJoint.Enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedCharacter = null;
|
selectedCharacter = null;
|
||||||
@@ -923,7 +1023,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!LockHands)
|
if (!LockHands)
|
||||||
{
|
{
|
||||||
//find the closest item if selectkey has been hit, or if the Character is being
|
//find the closest item if selectkey has been hit, or if the Character is being
|
||||||
@@ -1014,9 +1113,9 @@ namespace Barotrauma
|
|||||||
// new Character(NewCharacterQueue.Dequeue(), Vector2.Zero);
|
// new Character(NewCharacterQueue.Dequeue(), Vector2.Zero);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
foreach (Character c in CharacterList)
|
for (int i = 0; i<CharacterList.Count; i++)
|
||||||
{
|
{
|
||||||
c.Update(cam, deltaTime);
|
CharacterList[i].Update(cam, deltaTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1039,6 +1138,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (huskInfection != null) huskInfection.Update(deltaTime, this);
|
||||||
|
|
||||||
if (isDead) return;
|
if (isDead) return;
|
||||||
|
|
||||||
if (networkUpdateSent)
|
if (networkUpdateSent)
|
||||||
@@ -1096,7 +1197,12 @@ namespace Barotrauma
|
|||||||
ControlLocalPlayer(deltaTime, cam);
|
ControlLocalPlayer(deltaTime, cam);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controlled == this || !(this is AICharacter)) Control(deltaTime, cam);
|
if (controlled == this ||
|
||||||
|
!(this is AICharacter) ||
|
||||||
|
!((AICharacter)this).AIController.Enabled)
|
||||||
|
{
|
||||||
|
Control(deltaTime, cam);
|
||||||
|
}
|
||||||
|
|
||||||
if (selectedCharacter != null && AnimController.Anim == AnimController.Animation.CPR)
|
if (selectedCharacter != null && AnimController.Anim == AnimController.Animation.CPR)
|
||||||
{
|
{
|
||||||
@@ -1323,10 +1429,18 @@ namespace Barotrauma
|
|||||||
if (GameMain.NetworkMember != null && controlled != this) return;
|
if (GameMain.NetworkMember != null && controlled != this) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 centerOfMass = AnimController.GetCenterOfMass();
|
|
||||||
|
|
||||||
health = minHealth;
|
health = minHealth;
|
||||||
|
|
||||||
|
BreakJoints();
|
||||||
|
|
||||||
|
Kill(CauseOfDeath.Pressure, isNetworkMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void BreakJoints()
|
||||||
|
{
|
||||||
|
Vector2 centerOfMass = AnimController.GetCenterOfMass();
|
||||||
|
|
||||||
foreach (Limb limb in AnimController.Limbs)
|
foreach (Limb limb in AnimController.Limbs)
|
||||||
{
|
{
|
||||||
limb.AddDamage(limb.SimPosition, DamageType.Blunt, 500.0f, 0.0f, false);
|
limb.AddDamage(limb.SimPosition, DamageType.Blunt, 500.0f, 0.0f, false);
|
||||||
@@ -1334,7 +1448,7 @@ namespace Barotrauma
|
|||||||
Vector2 diff = centerOfMass - limb.SimPosition;
|
Vector2 diff = centerOfMass - limb.SimPosition;
|
||||||
if (diff == Vector2.Zero) continue;
|
if (diff == Vector2.Zero) continue;
|
||||||
limb.body.ApplyLinearImpulse(diff * 10.0f);
|
limb.body.ApplyLinearImpulse(diff * 10.0f);
|
||||||
// limb.Damage = 100.0f;
|
// limb.Damage = 100.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundPlayer.PlayDamageSound(DamageSoundType.Implode, 50.0f, AnimController.RefLimb.body);
|
SoundPlayer.PlayDamageSound(DamageSoundType.Implode, 50.0f, AnimController.RefLimb.body);
|
||||||
@@ -1344,18 +1458,17 @@ namespace Barotrauma
|
|||||||
Particle p = GameMain.ParticleManager.CreateParticle("waterblood",
|
Particle p = GameMain.ParticleManager.CreateParticle("waterblood",
|
||||||
ConvertUnits.ToDisplayUnits(centerOfMass) + Rand.Vector(5.0f),
|
ConvertUnits.ToDisplayUnits(centerOfMass) + Rand.Vector(5.0f),
|
||||||
Rand.Vector(10.0f));
|
Rand.Vector(10.0f));
|
||||||
if (p!=null) p.Size *= 2.0f;
|
if (p != null) p.Size *= 2.0f;
|
||||||
|
|
||||||
GameMain.ParticleManager.CreateParticle("bubbles",
|
GameMain.ParticleManager.CreateParticle("bubbles",
|
||||||
ConvertUnits.ToDisplayUnits(centerOfMass) + Rand.Vector(5.0f),
|
ConvertUnits.ToDisplayUnits(centerOfMass) + Rand.Vector(5.0f),
|
||||||
new Vector2(Rand.Range(-50f, 50f), Rand.Range(-100f,50f)));
|
new Vector2(Rand.Range(-50f, 50f), Rand.Range(-100f, 50f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var joint in AnimController.limbJoints)
|
foreach (var joint in AnimController.limbJoints)
|
||||||
{
|
{
|
||||||
joint.LimitEnabled = false;
|
joint.LimitEnabled = false;
|
||||||
}
|
}
|
||||||
Kill(CauseOfDeath.Pressure, isNetworkMessage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Kill(CauseOfDeath causeOfDeath, bool isNetworkMessage = false)
|
public void Kill(CauseOfDeath causeOfDeath, bool isNetworkMessage = false)
|
||||||
|
|||||||
@@ -197,6 +197,7 @@ namespace Barotrauma
|
|||||||
if (Character.Controlled != null)
|
if (Character.Controlled != null)
|
||||||
{
|
{
|
||||||
Character.Controlled.Kill(Character.Controlled.CauseOfDeath);
|
Character.Controlled.Kill(Character.Controlled.CauseOfDeath);
|
||||||
|
Character.Controlled = null;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@@ -232,11 +233,12 @@ namespace Barotrauma
|
|||||||
healthBar.Draw(spriteBatch);
|
healthBar.Draw(spriteBatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bloodDropCount = (int)Math.Floor(character.Bleeding);
|
float bloodDropCount = character.Bleeding;
|
||||||
bloodDropCount = MathHelper.Clamp(bloodDropCount, 0, 5);
|
bloodDropCount = MathHelper.Clamp(bloodDropCount, 0.0f, 5.0f);
|
||||||
for (int i = 1; i < bloodDropCount; i++)
|
for (int i = 0; i < Math.Ceiling(bloodDropCount); i++)
|
||||||
{
|
{
|
||||||
spriteBatch.Draw(statusIcons.Texture, new Vector2(5.0f + 20 * i, healthBar.Rect.Y - 20.0f), new Rectangle(39, 3, 15, 19), Color.White * 0.8f);
|
float alpha = MathHelper.Clamp(bloodDropCount-i, 0.2f, 1.0f);
|
||||||
|
spriteBatch.Draw(statusIcons.Texture, new Vector2(25.0f + 20 * i, healthBar.Rect.Y - 20.0f), new Rectangle(39, 3, 15, 19), Color.White * alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
float pressureFactor = (character.AnimController.CurrentHull == null) ?
|
float pressureFactor = (character.AnimController.CurrentHull == null) ?
|
||||||
|
|||||||
@@ -0,0 +1,186 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma
|
||||||
|
{
|
||||||
|
class HuskInfection
|
||||||
|
{
|
||||||
|
public enum InfectionState
|
||||||
|
{
|
||||||
|
Dormant, Transition, Active
|
||||||
|
}
|
||||||
|
|
||||||
|
const float IncubationDuration = 300.0f;
|
||||||
|
|
||||||
|
private InfectionState state;
|
||||||
|
|
||||||
|
private float incubationTimer;
|
||||||
|
public float IncubationTimer
|
||||||
|
{
|
||||||
|
get { return incubationTimer; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
incubationTimer = MathHelper.Clamp(value, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public InfectionState State
|
||||||
|
{
|
||||||
|
get { return state; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanSpeak
|
||||||
|
{
|
||||||
|
get { return IncubationTimer < 0.5f; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public HuskInfection(Character character)
|
||||||
|
{
|
||||||
|
character.OnDeath += CharacterDead;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(float deltaTime, Character character)
|
||||||
|
{
|
||||||
|
if (IncubationTimer < 0.5f)
|
||||||
|
{
|
||||||
|
UpdateDormantState(deltaTime, character);
|
||||||
|
}
|
||||||
|
else if (IncubationTimer < 1.0f)
|
||||||
|
{
|
||||||
|
UpdateTransitionState(deltaTime, character);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UpdateActiveState(deltaTime, character);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateDormantState(float deltaTime, Character character)
|
||||||
|
{
|
||||||
|
float prevTimer = IncubationTimer;
|
||||||
|
|
||||||
|
state = InfectionState.Dormant;
|
||||||
|
|
||||||
|
IncubationTimer += deltaTime / IncubationDuration;
|
||||||
|
|
||||||
|
if (Character.Controlled != character) return;
|
||||||
|
|
||||||
|
if (prevTimer % 0.1f > 0.05f && IncubationTimer % 0.1f < 0.05f)
|
||||||
|
{
|
||||||
|
GUI.AddMessage(InfoTextManager.GetInfoText("HuskDormant"), Color.Red, 4.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateTransitionState(float deltaTime, Character character)
|
||||||
|
{
|
||||||
|
IncubationTimer += deltaTime / IncubationDuration;
|
||||||
|
|
||||||
|
if (state == InfectionState.Dormant && Character.Controlled == character)
|
||||||
|
{
|
||||||
|
new GUIMessageBox("", InfoTextManager.GetInfoText("HuskCantSpeak"));
|
||||||
|
}
|
||||||
|
|
||||||
|
state = InfectionState.Transition;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateActiveState(float deltaTime, Character character)
|
||||||
|
{
|
||||||
|
if (state != InfectionState.Active)
|
||||||
|
{
|
||||||
|
if (Character.Controlled==character) new GUIMessageBox("", InfoTextManager.GetInfoText("HuskActivate"));
|
||||||
|
ActivateHusk(character);
|
||||||
|
state = InfectionState.Active;
|
||||||
|
}
|
||||||
|
|
||||||
|
character.AddDamage(CauseOfDeath.Husk, 0.5f*deltaTime, null);
|
||||||
|
|
||||||
|
if (character.AnimController.limbJoints[0].LimitEnabled &&
|
||||||
|
(character.AnimController.CurrentHull == null ||
|
||||||
|
character.AnimController.CurrentHull.LethalPressure > 50.0f))
|
||||||
|
{
|
||||||
|
character.BreakJoints();
|
||||||
|
character.AnimController.limbJoints.Last().LimitEnabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void ActivateHusk(Character character)
|
||||||
|
{
|
||||||
|
character.NeedsAir = false;
|
||||||
|
AttachHuskAppendage(character);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AttachHuskAppendage(Character character)
|
||||||
|
{
|
||||||
|
XDocument doc = ToolBox.TryLoadXml(Path.Combine("Content", "Characters", "Human", "huskappendage.xml"));
|
||||||
|
if (doc == null || doc.Root == null) return;
|
||||||
|
|
||||||
|
var limbElement = doc.Root.Element("limb");
|
||||||
|
if (limbElement == null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error in huskappendage.xml - limb element not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var jointElement = doc.Root.Element("joint");
|
||||||
|
if (jointElement == null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error in huskappendage.xml - joint element not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
character.StartStun(0.5f);
|
||||||
|
if (character.AnimController.Dir < 1.0f)
|
||||||
|
{
|
||||||
|
character.AnimController.Flip();
|
||||||
|
}
|
||||||
|
|
||||||
|
var torso = character.AnimController.GetLimb(LimbType.Torso);
|
||||||
|
torso.body.SetTransform(torso.SimPosition, 0.0f);
|
||||||
|
|
||||||
|
var newLimb = new Limb(character, limbElement);
|
||||||
|
newLimb.body.Submarine = character.Submarine;
|
||||||
|
newLimb.body.SetTransform(torso.SimPosition, 0.0f);
|
||||||
|
|
||||||
|
character.AnimController.AddLimb(newLimb);
|
||||||
|
character.AnimController.AddJoint(jointElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CharacterDead(Character character, CauseOfDeath causeOfDeath)
|
||||||
|
{
|
||||||
|
var husk = Character.Create(
|
||||||
|
Path.Combine("Content", "Characters", "Human", "humanhusk.xml"),
|
||||||
|
character.WorldPosition,
|
||||||
|
character.Info,
|
||||||
|
false, true);
|
||||||
|
|
||||||
|
foreach (Limb limb in husk.AnimController.Limbs)
|
||||||
|
{
|
||||||
|
if (limb.type == LimbType.None)
|
||||||
|
{
|
||||||
|
limb.body.SetTransform(character.SimPosition, 0.0f);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var matchingLimb = character.AnimController.GetLimb(limb.type);
|
||||||
|
limb.body.SetTransform(matchingLimb.SimPosition, matchingLimb.Rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < character.Inventory.Items.Length; i++)
|
||||||
|
{
|
||||||
|
if (character.Inventory.Items[i] == null) continue;
|
||||||
|
husk.Inventory.TryPutItem(character.Inventory.Items[i], i, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
character.Enabled = false;
|
||||||
|
|
||||||
|
husk.SpawnedMidRound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -156,6 +156,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private float scale;
|
private float scale;
|
||||||
|
|
||||||
|
public float AttackTimer;
|
||||||
|
|
||||||
//public float Damage
|
//public float Damage
|
||||||
//{
|
//{
|
||||||
// get { return damage; }
|
// get { return damage; }
|
||||||
@@ -223,6 +225,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
refJointIndex = -1;
|
refJointIndex = -1;
|
||||||
|
|
||||||
|
Vector2 pullJointPos = Vector2.Zero;
|
||||||
|
|
||||||
if (element.Attribute("type") != null)
|
if (element.Attribute("type") != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -236,25 +240,26 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Vector2 jointPos = ToolBox.GetAttributeVector2(element, "pullpos", Vector2.Zero) * scale;
|
pullJointPos = ToolBox.GetAttributeVector2(element, "pullpos", Vector2.Zero) * scale;
|
||||||
jointPos = ConvertUnits.ToSimUnits(jointPos);
|
pullJointPos = ConvertUnits.ToSimUnits(pullJointPos);
|
||||||
|
|
||||||
stepOffset = ToolBox.GetAttributeVector2(element, "stepoffset", Vector2.Zero) * scale;
|
stepOffset = ToolBox.GetAttributeVector2(element, "stepoffset", Vector2.Zero) * scale;
|
||||||
stepOffset = ConvertUnits.ToSimUnits(stepOffset);
|
stepOffset = ConvertUnits.ToSimUnits(stepOffset);
|
||||||
|
|
||||||
refJointIndex = ToolBox.GetAttributeInt(element, "refjoint", -1);
|
refJointIndex = ToolBox.GetAttributeInt(element, "refjoint", -1);
|
||||||
|
|
||||||
pullJoint = new FixedMouseJoint(body.FarseerBody, jointPos);
|
|
||||||
pullJoint.Enabled = false;
|
|
||||||
pullJoint.MaxForce = ((type == LimbType.LeftHand || type == LimbType.RightHand) ? 400.0f : 150.0f) * body.Mass;
|
|
||||||
|
|
||||||
GameMain.World.AddJoint(pullJoint);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
type = LimbType.None;
|
type = LimbType.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pullJoint = new FixedMouseJoint(body.FarseerBody, pullJointPos);
|
||||||
|
pullJoint.Enabled = false;
|
||||||
|
pullJoint.MaxForce = ((type == LimbType.LeftHand || type == LimbType.RightHand) ? 400.0f : 150.0f) * body.Mass;
|
||||||
|
|
||||||
|
GameMain.World.AddJoint(pullJoint);
|
||||||
|
|
||||||
steerForce = ToolBox.GetAttributeFloat(element, "steerforce", 0.0f);
|
steerForce = ToolBox.GetAttributeFloat(element, "steerforce", 0.0f);
|
||||||
|
|
||||||
//maxHealth = Math.Max(ToolBox.GetAttributeFloat(element, "health", 100.0f),1.0f);
|
//maxHealth = Math.Max(ToolBox.GetAttributeFloat(element, "health", 100.0f),1.0f);
|
||||||
@@ -484,6 +489,36 @@ namespace Barotrauma
|
|||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ActivateDamagedSprite()
|
||||||
|
{
|
||||||
|
damage = 100.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateAttack(float deltaTime, Vector2 attackPosition, IDamageable damageTarget)
|
||||||
|
{
|
||||||
|
float dist = ConvertUnits.ToDisplayUnits(Vector2.Distance(SimPosition, attackPosition));
|
||||||
|
|
||||||
|
AttackTimer += deltaTime;
|
||||||
|
body.ApplyTorque(Mass * character.AnimController.Dir * attack.Torque);
|
||||||
|
|
||||||
|
if (dist < attack.Range * 0.5f)
|
||||||
|
{
|
||||||
|
if (AttackTimer >= attack.Duration && damageTarget != null)
|
||||||
|
{
|
||||||
|
attack.DoDamage(character, damageTarget, WorldPosition, 1.0f, (soundTimer <= 0.0f));
|
||||||
|
|
||||||
|
soundTimer = Limb.SoundInterval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 diff = attackPosition - SimPosition;
|
||||||
|
if (diff.LengthSquared() > 0.00001f)
|
||||||
|
{
|
||||||
|
Vector2 pos = pullJoint == null ? body.SimPosition : pullJoint.WorldAnchorA;
|
||||||
|
body.ApplyLinearImpulse(Mass * attack.Force *
|
||||||
|
Vector2.Normalize(attackPosition - SimPosition), pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch)
|
public void Draw(SpriteBatch spriteBatch)
|
||||||
{
|
{
|
||||||
@@ -492,7 +527,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
body.Dir = Dir;
|
body.Dir = Dir;
|
||||||
|
|
||||||
if (wearingItems.Find(w => w != null && w.HideLimb) == null)
|
bool hideLimb = wearingItems.Any(w => w != null && w.HideLimb);
|
||||||
|
|
||||||
|
if (!hideLimb)
|
||||||
{
|
{
|
||||||
body.Draw(spriteBatch, sprite, color, null, scale);
|
body.Draw(spriteBatch, sprite, color, null, scale);
|
||||||
}
|
}
|
||||||
@@ -526,7 +563,7 @@ namespace Barotrauma
|
|||||||
scale, spriteEffect, depth);
|
scale, spriteEffect, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (damage>0.0f && damagedSprite!=null)
|
if (damage>0.0f && damagedSprite!=null && !hideLimb)
|
||||||
{
|
{
|
||||||
SpriteEffects spriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
|
SpriteEffects spriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
|
||||||
|
|
||||||
|
|||||||
@@ -173,20 +173,8 @@ namespace Barotrauma
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//oxygen = ToolBox.GetAttributeFloat(element, "oxygen", 0.0f);
|
|
||||||
|
|
||||||
|
|
||||||
//deteriorateOnActive = ToolBox.GetAttributeFloat(element, "deteriorateonactive", 0.0f);
|
|
||||||
//deteriorateOnUse = ToolBox.GetAttributeFloat(element, "deteriorateonuse", 0.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//public virtual void Apply(ActionType type, float deltaTime, Item item, Character Character = null)
|
|
||||||
//{
|
|
||||||
// if (this.type == type) Apply(deltaTime, Character, item);
|
|
||||||
//}
|
|
||||||
|
|
||||||
private bool HasRequiredItems(Entity entity)
|
private bool HasRequiredItems(Entity entity)
|
||||||
{
|
{
|
||||||
if (requiredItems == null) return true;
|
if (requiredItems == null) return true;
|
||||||
|
|||||||
@@ -56,55 +56,49 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Coroutines.RemoveAll(c => c == handle);
|
Coroutines.RemoveAll(c => c == handle);
|
||||||
}
|
}
|
||||||
|
private static bool IsDone(CoroutineHandle handle)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (handle.Coroutine.Current != null)
|
||||||
|
{
|
||||||
|
WaitForSeconds wfs = handle.Coroutine.Current as WaitForSeconds;
|
||||||
|
if (wfs != null)
|
||||||
|
{
|
||||||
|
if (!wfs.CheckFinished(UnscaledDeltaTime)) return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch ((CoroutineStatus)handle.Coroutine.Current)
|
||||||
|
{
|
||||||
|
case CoroutineStatus.Success:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case CoroutineStatus.Failure:
|
||||||
|
DebugConsole.ThrowError("Coroutine ''" + handle.Name + "'' has failed");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handle.Coroutine.MoveNext();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Coroutine " + handle.Name + " threw an exception: " + e.Message);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Updating just means stepping through all the coroutines
|
// Updating just means stepping through all the coroutines
|
||||||
public static void Update(float unscaledDeltaTime, float deltaTime)
|
public static void Update(float unscaledDeltaTime, float deltaTime)
|
||||||
{
|
{
|
||||||
UnscaledDeltaTime = unscaledDeltaTime;
|
UnscaledDeltaTime = unscaledDeltaTime;
|
||||||
DeltaTime = deltaTime;
|
DeltaTime = deltaTime;
|
||||||
|
|
||||||
for (int i = Coroutines.Count-1; i>=0; i--)
|
foreach (var x in Coroutines.ToList())
|
||||||
{
|
if(IsDone(x))
|
||||||
CoroutineHandle handle = Coroutines[i];
|
Coroutines.Remove(x);
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (handle.Coroutine.Current != null)
|
|
||||||
{
|
|
||||||
WaitForSeconds wfs = handle.Coroutine.Current as WaitForSeconds;
|
|
||||||
if (wfs != null)
|
|
||||||
{
|
|
||||||
if (!wfs.CheckFinished(unscaledDeltaTime)) continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch ((CoroutineStatus)handle.Coroutine.Current)
|
|
||||||
{
|
|
||||||
case CoroutineStatus.Success:
|
|
||||||
Coroutines.RemoveAt(i);
|
|
||||||
continue;
|
|
||||||
case CoroutineStatus.Failure:
|
|
||||||
DebugConsole.ThrowError("Coroutine ''" + handle.Name + "'' has failed");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handle.Coroutine.MoveNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Coroutine " + handle.Name + " threw an exception: " + e.Message);
|
|
||||||
|
|
||||||
//#if DEBUG
|
|
||||||
// throw e;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
Coroutines.Remove(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -363,8 +363,47 @@ namespace Barotrauma
|
|||||||
case "controlcharacter":
|
case "controlcharacter":
|
||||||
case "control":
|
case "control":
|
||||||
if (commands.Length < 2) break;
|
if (commands.Length < 2) break;
|
||||||
string name = string.Join(" ", commands.Skip(1)).ToLowerInvariant();
|
|
||||||
Character.Controlled = Character.CharacterList.Find(c => !c.IsNetworkPlayer && c.Name.ToLowerInvariant() == name);
|
int characterIndex;
|
||||||
|
string characterName;
|
||||||
|
if (int.TryParse(commands.Last(), out characterIndex))
|
||||||
|
{
|
||||||
|
characterName = string.Join(" ", commands.Skip(1).Take(commands.Length-2)).ToLowerInvariant();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
characterName = string.Join(" ", commands.Skip(1)).ToLowerInvariant();
|
||||||
|
characterIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var matchingCharacters = Character.CharacterList.FindAll(c => !c.IsNetworkPlayer && c.Name.ToLowerInvariant() == characterName);
|
||||||
|
|
||||||
|
if (!matchingCharacters.Any())
|
||||||
|
{
|
||||||
|
ThrowError("Matching characters not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (characterIndex==-1)
|
||||||
|
{
|
||||||
|
Character.Controlled = matchingCharacters.First();
|
||||||
|
if (matchingCharacters.Count > 1)
|
||||||
|
{
|
||||||
|
NewMessage(
|
||||||
|
"Found multiple matching characters. "+
|
||||||
|
"Use \"control [charactername] [0-"+(matchingCharacters.Count-1)+"]\" to choose which character to control.",
|
||||||
|
Color.LightGray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (characterIndex<0 || characterIndex>= matchingCharacters.Count)
|
||||||
|
{
|
||||||
|
ThrowError("Character index out of range. Select an index between 0 and " + (matchingCharacters.Count - 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Character.Controlled = matchingCharacters[characterIndex];
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "godmode":
|
case "godmode":
|
||||||
if (Submarine.MainSub == null) return;
|
if (Submarine.MainSub == null) return;
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
protected override void Start()
|
protected override void Start()
|
||||||
{
|
{
|
||||||
Vector2 position = Level.Loaded.GetRandomItemPos(Level.PositionType.Cave, 30.0f);
|
Vector2 position = Level.Loaded.GetRandomItemPos(
|
||||||
|
Level.PositionType.Cave | Level.PositionType.MainPath | Level.PositionType.Ruin, 500.0f, 30.0f);
|
||||||
|
|
||||||
item = new Item(itemPrefab, position, null);
|
item = new Item(itemPrefab, position, null);
|
||||||
item.MoveWithLevel = true;
|
item.MoveWithLevel = true;
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public override void Start(Level level)
|
public override void Start(Level level)
|
||||||
{
|
{
|
||||||
Vector2 position = Level.Loaded.GetRandomItemPos(spawnPositionType, 30.0f);
|
Vector2 position = Level.Loaded.GetRandomItemPos(spawnPositionType, 100.0f, 30.0f);
|
||||||
|
|
||||||
item = new Item(itemPrefab, position, null);
|
item = new Item(itemPrefab, position, null);
|
||||||
item.MoveWithLevel = true;
|
item.MoveWithLevel = true;
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
SetTextPos();
|
SetTextPos();
|
||||||
|
|
||||||
if (rect.Height == 0 && !string.IsNullOrWhiteSpace(Text))
|
if (rect.Height == 0 && !string.IsNullOrEmpty(Text))
|
||||||
{
|
{
|
||||||
this.rect.Height = (int)Font.MeasureString(wrappedText).Y;
|
this.rect.Height = (int)Font.MeasureString(wrappedText).Y;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
class GameSession
|
class GameSession
|
||||||
{
|
{
|
||||||
public enum InfoFrameTab { Crew, Mission };
|
public enum InfoFrameTab { Crew, Mission, ManagePlayers };
|
||||||
|
|
||||||
public readonly TaskManager TaskManager;
|
public readonly TaskManager TaskManager;
|
||||||
|
|
||||||
@@ -244,6 +244,13 @@ namespace Barotrauma
|
|||||||
missionButton.UserData = InfoFrameTab.Mission;
|
missionButton.UserData = InfoFrameTab.Mission;
|
||||||
missionButton.OnClicked = SelectInfoFrameTab;
|
missionButton.OnClicked = SelectInfoFrameTab;
|
||||||
|
|
||||||
|
if (GameMain.Server != null)
|
||||||
|
{
|
||||||
|
var manageButton = new GUIButton(new Rectangle(200, -30, 130, 20), "Manage players", GUI.Style, infoFrame);
|
||||||
|
manageButton.UserData = InfoFrameTab.ManagePlayers;
|
||||||
|
manageButton.OnClicked = SelectInfoFrameTab;
|
||||||
|
}
|
||||||
|
|
||||||
var closeButton = new GUIButton(new Rectangle(0, 0, 80, 20), "Close", Alignment.BottomCenter, GUI.Style, infoFrame);
|
var closeButton = new GUIButton(new Rectangle(0, 0, 80, 20), "Close", Alignment.BottomCenter, GUI.Style, infoFrame);
|
||||||
closeButton.OnClicked = ToggleInfoFrame;
|
closeButton.OnClicked = ToggleInfoFrame;
|
||||||
|
|
||||||
@@ -263,6 +270,9 @@ namespace Barotrauma
|
|||||||
case InfoFrameTab.Mission:
|
case InfoFrameTab.Mission:
|
||||||
CreateMissionInfo(infoFrame);
|
CreateMissionInfo(infoFrame);
|
||||||
break;
|
break;
|
||||||
|
case InfoFrameTab.ManagePlayers:
|
||||||
|
GameMain.Server.ManagePlayersFrame(infoFrame);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
@@ -51,6 +52,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
string text = infoList[Rand.Int(infoList.Count)];
|
string text = infoList[Rand.Int(infoList.Count)];
|
||||||
|
|
||||||
|
foreach (InputType inputType in Enum.GetValues(typeof(InputType)))
|
||||||
|
{
|
||||||
|
text = text.Replace("[" + inputType.ToString() + "]", GameMain.Config.KeyBind(inputType).ToString());
|
||||||
|
}
|
||||||
|
|
||||||
if (Submarine.MainSub != null) text = text.Replace("[sub]", Submarine.MainSub.Name);
|
if (Submarine.MainSub != null) text = text.Replace("[sub]", Submarine.MainSub.Name);
|
||||||
if (GameMain.GameSession != null && GameMain.GameSession.Map != null)
|
if (GameMain.GameSession != null && GameMain.GameSession.Map != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -203,6 +203,16 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (InputType inputType in Enum.GetValues(typeof(InputType)))
|
||||||
|
{
|
||||||
|
if (keyMapping[(int)inputType]==null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Key binding for the input type ''" + inputType + " not set!");
|
||||||
|
keyMapping[(int)inputType] = new KeyOrMouse(Keys.D1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
UnsavedSettings = false;
|
UnsavedSettings = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,6 +393,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
new GUITextBlock(new Rectangle(x, y, 100, 20), inputNames[i]+": ", GUI.Style, settingsFrame);
|
new GUITextBlock(new Rectangle(x, y, 100, 20), inputNames[i]+": ", GUI.Style, settingsFrame);
|
||||||
var keyBox = new GUITextBox(new Rectangle(x + 100, y, 120, 15), GUI.Style, settingsFrame);
|
var keyBox = new GUITextBox(new Rectangle(x + 100, y, 120, 15), GUI.Style, settingsFrame);
|
||||||
|
|
||||||
keyBox.Text = keyMapping[i].ToString();
|
keyBox.Text = keyMapping[i].ToString();
|
||||||
keyBox.UserData = i;
|
keyBox.UserData = i;
|
||||||
keyBox.OnSelected += KeyBoxSelected;
|
keyBox.OnSelected += KeyBoxSelected;
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
using System.Collections.Generic;
|
using Barotrauma.Items.Components;
|
||||||
using System.Linq;
|
using Barotrauma.Networking;
|
||||||
using System.Xml.Linq;
|
|
||||||
using FarseerPhysics;
|
using FarseerPhysics;
|
||||||
|
using FarseerPhysics.Dynamics;
|
||||||
|
using FarseerPhysics.Dynamics.Contacts;
|
||||||
using Lidgren.Network;
|
using Lidgren.Network;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using Microsoft.Xna.Framework.Input;
|
using Microsoft.Xna.Framework.Input;
|
||||||
using Barotrauma.Networking;
|
|
||||||
using System;
|
using System;
|
||||||
using Barotrauma.Items.Components;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using FarseerPhysics.Dynamics;
|
using System.ComponentModel;
|
||||||
using FarseerPhysics.Dynamics.Contacts;
|
using System.Linq;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -648,7 +648,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public AttackResult AddDamage(IDamageable attacker, Vector2 worldPosition, Attack attack, float deltaTime, bool playSound = true)
|
public AttackResult AddDamage(IDamageable attacker, Vector2 worldPosition, Attack attack, float deltaTime, bool playSound = true)
|
||||||
{
|
{
|
||||||
float damageAmount = attack.GetDamage(deltaTime);
|
float damageAmount = attack.GetStructureDamage(deltaTime);
|
||||||
Condition -= damageAmount;
|
Condition -= damageAmount;
|
||||||
|
|
||||||
return new AttackResult(damageAmount, 0.0f, false);
|
return new AttackResult(damageAmount, 0.0f, false);
|
||||||
|
|||||||
@@ -203,11 +203,6 @@ namespace Barotrauma
|
|||||||
pathNodes.Add(new Vector2(x, Rand.Range(pathBorders.Y, pathBorders.Bottom, false)));
|
pathNodes.Add(new Vector2(x, Rand.Range(pathBorders.Y, pathBorders.Bottom, false)));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 2; i < pathNodes.Count; i+=3 )
|
|
||||||
{
|
|
||||||
positionsOfInterest.Add(new InterestingPosition(pathNodes[i], PositionType.MainPath));
|
|
||||||
}
|
|
||||||
|
|
||||||
pathNodes.Add(endPosition);
|
pathNodes.Add(endPosition);
|
||||||
pathNodes.Add(new Vector2(endPosition.X, borders.Height));
|
pathNodes.Add(new Vector2(endPosition.X, borders.Height));
|
||||||
|
|
||||||
@@ -277,6 +272,12 @@ namespace Barotrauma
|
|||||||
List<VoronoiCell> mainPath = CaveGenerator.GeneratePath(pathNodes, cells, cellGrid, GridCellSize,
|
List<VoronoiCell> mainPath = CaveGenerator.GeneratePath(pathNodes, cells, cellGrid, GridCellSize,
|
||||||
new Rectangle(pathBorders.X, pathBorders.Y, pathBorders.Width, borders.Height), 0.3f, mirror);
|
new Rectangle(pathBorders.X, pathBorders.Y, pathBorders.Width, borders.Height), 0.3f, mirror);
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 2; i < mainPath.Count; i += 3)
|
||||||
|
{
|
||||||
|
positionsOfInterest.Add(new InterestingPosition(mainPath[i].Center, PositionType.MainPath));
|
||||||
|
}
|
||||||
|
|
||||||
List<VoronoiCell> pathCells = new List<VoronoiCell>(mainPath);
|
List<VoronoiCell> pathCells = new List<VoronoiCell>(mainPath);
|
||||||
|
|
||||||
EnlargeMainPath(pathCells, minWidth);
|
EnlargeMainPath(pathCells, minWidth);
|
||||||
@@ -734,7 +735,7 @@ namespace Barotrauma
|
|||||||
return newCells;
|
return newCells;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2 GetRandomItemPos(PositionType spawnPosType, float offsetFromWall = 10.0f)
|
public Vector2 GetRandomItemPos(PositionType spawnPosType, float randomSpread, float offsetFromWall = 10.0f)
|
||||||
{
|
{
|
||||||
if (!positionsOfInterest.Any()) return Size*0.5f;
|
if (!positionsOfInterest.Any()) return Size*0.5f;
|
||||||
|
|
||||||
@@ -747,6 +748,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Vector2 startPos = Level.Loaded.GetRandomInterestingPosition(true, spawnPosType);
|
Vector2 startPos = Level.Loaded.GetRandomInterestingPosition(true, spawnPosType);
|
||||||
|
|
||||||
|
startPos += Rand.Vector(Rand.Range(0.0f, randomSpread, false), false);
|
||||||
|
|
||||||
Vector2 endPos = startPos - Vector2.UnitY * Size.Y;
|
Vector2 endPos = startPos - Vector2.UnitY * Size.Y;
|
||||||
|
|
||||||
if (Submarine.PickBody(
|
if (Submarine.PickBody(
|
||||||
|
|||||||
@@ -105,6 +105,19 @@ namespace Barotrauma
|
|||||||
get { return prefab.MaxHealth; }
|
get { return prefab.MaxHealth; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override Rectangle Rect
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return base.Rect;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.Rect = value;
|
||||||
|
if (prefab.HasBody) CreateSections();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void Move(Vector2 amount)
|
public override void Move(Vector2 amount)
|
||||||
{
|
{
|
||||||
base.Move(amount);
|
base.Move(amount);
|
||||||
@@ -130,15 +143,6 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
convexHulls.ForEach(x => x.Move(amount));
|
convexHulls.ForEach(x => x.Move(amount));
|
||||||
}
|
}
|
||||||
//if (gaps != null)
|
|
||||||
//{
|
|
||||||
// foreach (Gap g in gaps)
|
|
||||||
// {
|
|
||||||
// g.Move(amount);
|
|
||||||
// //g.position.X += amount.X;
|
|
||||||
// //g.position.Y -= amount.Y;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Structure(Rectangle rectangle, StructurePrefab sp, Submarine submarine)
|
public Structure(Rectangle rectangle, StructurePrefab sp, Submarine submarine)
|
||||||
@@ -174,36 +178,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
WallList.Add(this);
|
WallList.Add(this);
|
||||||
|
|
||||||
int xsections = 1;
|
CreateSections();
|
||||||
int ysections = 1;
|
|
||||||
int width, height;
|
|
||||||
if (isHorizontal)
|
|
||||||
{
|
|
||||||
xsections = (int)Math.Ceiling((float)rect.Width / wallSectionSize);
|
|
||||||
sections = new WallSection[xsections];
|
|
||||||
width = (int)wallSectionSize;
|
|
||||||
height = rect.Height;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ysections = (int)Math.Ceiling((float)rect.Height / wallSectionSize);
|
|
||||||
sections = new WallSection[ysections];
|
|
||||||
width = rect.Width;
|
|
||||||
height = (int)wallSectionSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int x = 0; x < xsections; x++ )
|
|
||||||
{
|
|
||||||
for (int y = 0; y < ysections; y++)
|
|
||||||
{
|
|
||||||
Rectangle sectionRect = new Rectangle(rect.X + x * width, rect.Y - y * height, width, height);
|
|
||||||
sectionRect.Width -= (int)Math.Max((sectionRect.X + sectionRect.Width) - (rect.X + rect.Width), 0.0f);
|
|
||||||
sectionRect.Height -= (int)Math.Max((rect.Y - rect.Height)-(sectionRect.Y - sectionRect.Height), 0.0f);
|
|
||||||
|
|
||||||
sections[x+y] = new WallSection(sectionRect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -245,6 +220,39 @@ namespace Barotrauma
|
|||||||
InsertToList();
|
InsertToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CreateSections()
|
||||||
|
{
|
||||||
|
int xsections = 1, ysections = 1;
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
if (isHorizontal)
|
||||||
|
{
|
||||||
|
xsections = (int)Math.Ceiling((float)rect.Width / wallSectionSize);
|
||||||
|
sections = new WallSection[xsections];
|
||||||
|
width = (int)wallSectionSize;
|
||||||
|
height = rect.Height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ysections = (int)Math.Ceiling((float)rect.Height / wallSectionSize);
|
||||||
|
sections = new WallSection[ysections];
|
||||||
|
width = rect.Width;
|
||||||
|
height = (int)wallSectionSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int x = 0; x < xsections; x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < ysections; y++)
|
||||||
|
{
|
||||||
|
Rectangle sectionRect = new Rectangle(rect.X + x * width, rect.Y - y * height, width, height);
|
||||||
|
sectionRect.Width -= (int)Math.Max((sectionRect.X + sectionRect.Width) - (rect.X + rect.Width), 0.0f);
|
||||||
|
sectionRect.Height -= (int)Math.Max((rect.Y - rect.Height) - (sectionRect.Y - sectionRect.Height), 0.0f);
|
||||||
|
|
||||||
|
sections[x + y] = new WallSection(sectionRect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void GenerateConvexHull()
|
private void GenerateConvexHull()
|
||||||
{
|
{
|
||||||
// If not null and not empty , remove the hulls from the system
|
// If not null and not empty , remove the hulls from the system
|
||||||
@@ -374,11 +382,14 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vector2 drawOffset = Submarine == null ? Vector2.Zero : Submarine.DrawPosition;
|
Vector2 drawOffset = Submarine == null ? Vector2.Zero : Submarine.DrawPosition;
|
||||||
prefab.sprite.DrawTiled(spriteBatch, new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)), new Vector2(rect.Width, rect.Height), Vector2.Zero, color);
|
if(sections.Length == 1)
|
||||||
|
prefab.sprite.DrawTiled(spriteBatch, new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)), new Vector2(rect.Width, rect.Height), Vector2.Zero, color,Point.Zero);
|
||||||
|
|
||||||
foreach (WallSection s in sections)
|
foreach (WallSection s in sections)
|
||||||
{
|
{
|
||||||
|
Point offset = new Point(Math.Abs(rect.Location.X - s.rect.Location.X), Math.Abs(rect.Location.Y - s.rect.Location.Y));
|
||||||
|
if (sections.Length != 1 && s.damage < prefab.MaxHealth)
|
||||||
|
prefab.sprite.DrawTiled(spriteBatch, new Vector2(s.rect.X + drawOffset.X, -(s.rect.Y + drawOffset.Y)), new Vector2(s.rect.Width, s.rect.Height), Vector2.Zero, color, offset);
|
||||||
|
|
||||||
if (s.isHighLighted)
|
if (s.isHighLighted)
|
||||||
{
|
{
|
||||||
@@ -391,9 +402,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (s.damage < 0.01f) continue;
|
if (s.damage < 0.01f) continue;
|
||||||
|
|
||||||
GUI.DrawRectangle(spriteBatch,
|
GUI.DrawRectangle(spriteBatch,
|
||||||
new Vector2(s.rect.X + drawOffset.X, -(s.rect.Y + drawOffset.Y)), new Vector2(s.rect.Width, s.rect.Height),
|
new Vector2(s.rect.X + drawOffset.X, -(s.rect.Y + drawOffset.Y)), new Vector2(s.rect.Width, s.rect.Height),
|
||||||
Color.Black * (s.damage / prefab.MaxHealth), true);
|
Color.Black * (s.damage / prefab.MaxHealth), true);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
if(_convexHulls == null) return;
|
if(_convexHulls == null) return;
|
||||||
@@ -593,7 +604,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sections[sectionIndex].gap != null)
|
if (sections[sectionIndex].gap != null)
|
||||||
sections[sectionIndex].gap.Open = (float)Math.Pow(((damage / prefab.MaxHealth)-0.5)*2.0, 2.0);
|
sections[sectionIndex].gap.Open = (damage/prefab.MaxHealth - 0.5f)*2;
|
||||||
|
|
||||||
bool hadHole = SectionBodyDisabled(sectionIndex);
|
bool hadHole = SectionBodyDisabled(sectionIndex);
|
||||||
sections[sectionIndex].damage = MathHelper.Clamp(damage, 0.0f, prefab.MaxHealth);
|
sections[sectionIndex].damage = MathHelper.Clamp(damage, 0.0f, prefab.MaxHealth);
|
||||||
|
|||||||
@@ -116,8 +116,11 @@ namespace Barotrauma.Networking
|
|||||||
public void WriteNetworkMessage(NetOutgoingMessage msg)
|
public void WriteNetworkMessage(NetOutgoingMessage msg)
|
||||||
{
|
{
|
||||||
msg.WriteRangedInteger(0, Enum.GetValues(typeof(ChatMessageType)).Length, (byte)Type);
|
msg.WriteRangedInteger(0, Enum.GetValues(typeof(ChatMessageType)).Length, (byte)Type);
|
||||||
msg.Write(Sender == null ? (ushort)0 : Sender.ID);
|
if (GameMain.Server != null)
|
||||||
msg.Write(SenderName);
|
{
|
||||||
|
msg.Write(Sender == null ? (ushort)0 : Sender.ID);
|
||||||
|
msg.Write(SenderName);
|
||||||
|
}
|
||||||
|
|
||||||
msg.Write(Text);
|
msg.Write(Text);
|
||||||
}
|
}
|
||||||
@@ -125,11 +128,33 @@ namespace Barotrauma.Networking
|
|||||||
public static ChatMessage ReadNetworkMessage(NetBuffer msg)
|
public static ChatMessage ReadNetworkMessage(NetBuffer msg)
|
||||||
{
|
{
|
||||||
ChatMessageType type = (ChatMessageType)msg.ReadRangedInteger(0, Enum.GetValues(typeof(ChatMessageType)).Length);
|
ChatMessageType type = (ChatMessageType)msg.ReadRangedInteger(0, Enum.GetValues(typeof(ChatMessageType)).Length);
|
||||||
ushort senderId = msg.ReadUInt16();
|
string senderName="";
|
||||||
string senderName = msg.ReadString();
|
Character character = null;
|
||||||
|
if (GameMain.Server == null)
|
||||||
|
{
|
||||||
|
ushort senderId = msg.ReadUInt16();
|
||||||
|
character = Entity.FindEntityByID(senderId) as Character;
|
||||||
|
senderName = msg.ReadString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NetIncomingMessage inc = msg as NetIncomingMessage;
|
||||||
|
if (inc == null) return null;
|
||||||
|
Client sender = GameMain.Server.ConnectedClients.Find(x => x.Connection == inc.SenderConnection);
|
||||||
|
if (sender == null) return null;
|
||||||
|
character = sender.Character;
|
||||||
|
if (character != null)
|
||||||
|
{
|
||||||
|
senderName = character.Name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
senderName = sender.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
string text = msg.ReadString();
|
string text = msg.ReadString();
|
||||||
|
|
||||||
return new ChatMessage(senderName, text, type, Entity.FindEntityByID(senderId) as Character);
|
return new ChatMessage(senderName, text, type, character);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,11 @@ namespace Barotrauma.Networking
|
|||||||
public string version;
|
public string version;
|
||||||
public bool inGame;
|
public bool inGame;
|
||||||
|
|
||||||
|
public List<string> ChatMessages = new List<string>();
|
||||||
|
public float ChatSpamSpeed;
|
||||||
|
public float ChatSpamTimer;
|
||||||
|
public int ChatSpamCount;
|
||||||
|
|
||||||
private List<Client> kickVoters;
|
private List<Client> kickVoters;
|
||||||
|
|
||||||
public bool ReadyToStart;
|
public bool ReadyToStart;
|
||||||
@@ -84,8 +89,21 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
name = name.Substring(0, 20);
|
name = name.Substring(0, 20);
|
||||||
}
|
}
|
||||||
|
string rName = "";
|
||||||
|
for (int i=0;i<name.Length;i++)
|
||||||
|
{
|
||||||
|
if (name[i] < 32 || name[i] > 126)
|
||||||
|
{
|
||||||
|
//TODO: allow safe unicode characters, this is just to prevent players from taking names that look similar but aren't the same
|
||||||
|
rName += '?';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rName += name[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return name;
|
return rName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPermissions(ClientPermissions permissions)
|
public void SetPermissions(ClientPermissions permissions)
|
||||||
@@ -105,7 +123,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public bool HasPermission(ClientPermissions permission)
|
public bool HasPermission(ClientPermissions permission)
|
||||||
{
|
{
|
||||||
return Permissions.HasFlag(permission);
|
return false; //Permissions.HasFlag(permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
public T GetVote<T>(VoteType voteType)
|
public T GetVote<T>(VoteType voteType)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.Collections.Generic;
|
|||||||
using FarseerPhysics;
|
using FarseerPhysics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using Barotrauma.Items.Components;
|
using Barotrauma.Items.Components;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
|
||||||
@@ -165,7 +166,12 @@ namespace Barotrauma.Networking
|
|||||||
reconnectBox.Buttons[0].OnClicked += reconnectBox.Close;
|
reconnectBox.Buttons[0].OnClicked += reconnectBox.Close;
|
||||||
}
|
}
|
||||||
|
|
||||||
CoroutineManager.StartCoroutine(WaitForStartingInfo(password));
|
String sendPw = "";
|
||||||
|
if (password.Length>0)
|
||||||
|
{
|
||||||
|
sendPw = Encoding.UTF8.GetString(NetUtility.ComputeSHAHash(Encoding.UTF8.GetBytes(password)));
|
||||||
|
}
|
||||||
|
CoroutineManager.StartCoroutine(WaitForStartingInfo(sendPw));
|
||||||
|
|
||||||
// Start the timer
|
// Start the timer
|
||||||
//update.Start();
|
//update.Start();
|
||||||
@@ -408,43 +414,7 @@ namespace Barotrauma.Networking
|
|||||||
byte characterCount = inc.ReadByte();
|
byte characterCount = inc.ReadByte();
|
||||||
for (int i = 0; i < characterCount; i++)
|
for (int i = 0; i < characterCount; i++)
|
||||||
{
|
{
|
||||||
bool isAiCharacter = inc.ReadBoolean();
|
ReadCharacterData(inc);
|
||||||
ushort id = inc.ReadUInt16();
|
|
||||||
|
|
||||||
if (isAiCharacter)
|
|
||||||
{
|
|
||||||
string configPath = inc.ReadString();
|
|
||||||
|
|
||||||
Vector2 position = new Vector2(inc.ReadFloat(), inc.ReadFloat());
|
|
||||||
|
|
||||||
var existingEntity = Entity.FindEntityByID(id);
|
|
||||||
if (existingEntity is AICharacter && existingEntity.ID == id)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var character = Character.Create(configPath, position, null, true);
|
|
||||||
if (character != null) character.ID = id;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bool hasOwner = inc.ReadBoolean();
|
|
||||||
int ownerId = -1;
|
|
||||||
if (hasOwner)
|
|
||||||
{
|
|
||||||
ownerId = inc.ReadByte();
|
|
||||||
}
|
|
||||||
|
|
||||||
Character newCharacter = ReadCharacterData(inc, ownerId == myID);
|
|
||||||
|
|
||||||
if (ownerId != myID)
|
|
||||||
{
|
|
||||||
var characterOwner = otherClients.Find(c => c.ID == ownerId);
|
|
||||||
if (characterOwner != null) characterOwner.Character = newCharacter;
|
|
||||||
}
|
|
||||||
|
|
||||||
crew.Add(newCharacter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gameStarted = true;
|
gameStarted = true;
|
||||||
@@ -509,7 +479,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public bool HasPermission(ClientPermissions permission)
|
public bool HasPermission(ClientPermissions permission)
|
||||||
{
|
{
|
||||||
return permissions.HasFlag(permission);
|
return false;// permissions.HasFlag(permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
|
public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
|
||||||
@@ -547,15 +517,23 @@ namespace Barotrauma.Networking
|
|||||||
GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black * 0.7f, true);
|
GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black * 0.7f, true);
|
||||||
spriteBatch.DrawString(GUI.Font, "Network statistics:", new Vector2(x + 10, y + 10), Color.White);
|
spriteBatch.DrawString(GUI.Font, "Network statistics:", new Vector2(x + 10, y + 10), Color.White);
|
||||||
|
|
||||||
spriteBatch.DrawString(GUI.Font, "Ping: " + (int)(client.ServerConnection.AverageRoundtripTime * 1000.0f) + " ms", new Vector2(x + 10, y + 25), Color.White);
|
if (client.ServerConnection != null)
|
||||||
|
{
|
||||||
|
spriteBatch.DrawString(GUI.Font, "Ping: " + (int)(client.ServerConnection.AverageRoundtripTime * 1000.0f) + " ms", new Vector2(x + 10, y + 25), Color.White);
|
||||||
|
|
||||||
y += 15;
|
y += 15;
|
||||||
|
|
||||||
spriteBatch.DrawString(GUI.SmallFont, "Received bytes: " + client.Statistics.ReceivedBytes, new Vector2(x + 10, y + 45), Color.White);
|
spriteBatch.DrawString(GUI.SmallFont, "Received bytes: " + client.Statistics.ReceivedBytes, new Vector2(x + 10, y + 45), Color.White);
|
||||||
spriteBatch.DrawString(GUI.SmallFont, "Received packets: " + client.Statistics.ReceivedPackets, new Vector2(x + 10, y + 60), Color.White);
|
spriteBatch.DrawString(GUI.SmallFont, "Received packets: " + client.Statistics.ReceivedPackets, new Vector2(x + 10, y + 60), Color.White);
|
||||||
|
|
||||||
|
spriteBatch.DrawString(GUI.SmallFont, "Sent bytes: " + client.Statistics.SentBytes, new Vector2(x + 10, y + 75), Color.White);
|
||||||
|
spriteBatch.DrawString(GUI.SmallFont, "Sent packets: " + client.Statistics.SentPackets, new Vector2(x + 10, y + 90), Color.White);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spriteBatch.DrawString(GUI.Font, "Disconnected", new Vector2(x + 10, y + 25), Color.White);
|
||||||
|
}
|
||||||
|
|
||||||
spriteBatch.DrawString(GUI.SmallFont, "Sent bytes: " + client.Statistics.SentBytes, new Vector2(x + 10, y + 75), Color.White);
|
|
||||||
spriteBatch.DrawString(GUI.SmallFont, "Sent packets: " + client.Statistics.SentPackets, new Vector2(x + 10, y + 90), Color.White);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -609,25 +587,6 @@ namespace Barotrauma.Networking
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReadCharacterSpawnMessage(NetIncomingMessage message)
|
|
||||||
{
|
|
||||||
string configPath = message.ReadString();
|
|
||||||
|
|
||||||
if (configPath != Character.HumanConfigFile)
|
|
||||||
{
|
|
||||||
ushort id = message.ReadUInt16();
|
|
||||||
|
|
||||||
Vector2 position = new Vector2(message.ReadFloat(), message.ReadFloat());
|
|
||||||
|
|
||||||
var character = Character.Create(configPath, position, null, true);
|
|
||||||
if (character != null) character.ID = id;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ReadCharacterData(message, false, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RequestFile(string file, FileTransferMessageType fileType)
|
public void RequestFile(string file, FileTransferMessageType fileType)
|
||||||
{
|
{
|
||||||
if (fileStreamReceiver!=null)
|
if (fileStreamReceiver!=null)
|
||||||
@@ -812,35 +771,77 @@ namespace Barotrauma.Networking
|
|||||||
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Character ReadCharacterData(NetIncomingMessage inc, bool isMyCharacter, bool hasAi = false)
|
public Character ReadCharacterData(NetIncomingMessage inc)
|
||||||
{
|
{
|
||||||
string newName = inc.ReadString();
|
bool noInfo = inc.ReadBoolean();
|
||||||
ushort ID = inc.ReadUInt16();
|
ushort id = inc.ReadUInt16();
|
||||||
bool isFemale = inc.ReadBoolean();
|
string configPath = inc.ReadString();
|
||||||
|
|
||||||
int headSpriteID = inc.ReadByte();
|
|
||||||
|
|
||||||
Vector2 position = new Vector2(inc.ReadFloat(), inc.ReadFloat());
|
Vector2 position = new Vector2(inc.ReadFloat(), inc.ReadFloat());
|
||||||
|
|
||||||
string jobName = inc.ReadString();
|
bool enabled = inc.ReadBoolean();
|
||||||
JobPrefab jobPrefab = JobPrefab.List.Find(jp => jp.Name == jobName);
|
|
||||||
|
|
||||||
CharacterInfo ch = new CharacterInfo(Character.HumanConfigFile, newName, isFemale ? Gender.Female : Gender.Male, jobPrefab);
|
Character character = null;
|
||||||
ch.HeadSpriteId = headSpriteID;
|
|
||||||
|
|
||||||
Character character = Character.Create(ch, position, !isMyCharacter, hasAi);
|
if (noInfo)
|
||||||
GameMain.GameSession.CrewManager.characters.Add(character);
|
|
||||||
|
|
||||||
character.ID = ID;
|
|
||||||
|
|
||||||
if (isMyCharacter)
|
|
||||||
{
|
{
|
||||||
myCharacter = character;
|
var existingEntity = Entity.FindEntityByID(id);
|
||||||
Character.Controlled = character;
|
if (existingEntity is AICharacter && existingEntity.ID == id)
|
||||||
GameMain.LightManager.LosEnabled = true;
|
{
|
||||||
|
return (Character)existingEntity;
|
||||||
|
}
|
||||||
|
|
||||||
if (endVoteTickBox != null) endVoteTickBox.Visible = Voting.AllowEndVoting;
|
character = Character.Create(configPath, position, null, true);
|
||||||
|
character.ID = id;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool hasOwner = inc.ReadBoolean();
|
||||||
|
int ownerId = -1;
|
||||||
|
if (hasOwner)
|
||||||
|
{
|
||||||
|
ownerId = inc.ReadByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
string newName = inc.ReadString();
|
||||||
|
|
||||||
|
bool hasAi = inc.ReadBoolean();
|
||||||
|
bool isFemale = inc.ReadBoolean();
|
||||||
|
int headSpriteID = inc.ReadByte();
|
||||||
|
string jobName = inc.ReadString();
|
||||||
|
|
||||||
|
JobPrefab jobPrefab = JobPrefab.List.Find(jp => jp.Name == jobName);
|
||||||
|
|
||||||
|
CharacterInfo ch = new CharacterInfo(configPath, newName, isFemale ? Gender.Female : Gender.Male, jobPrefab);
|
||||||
|
ch.HeadSpriteId = headSpriteID;
|
||||||
|
|
||||||
|
character = Character.Create(configPath, position, ch, ownerId != myID, hasAi);
|
||||||
|
character.ID = id;
|
||||||
|
|
||||||
|
if (configPath == Character.HumanConfigFile)
|
||||||
|
{
|
||||||
|
GameMain.GameSession.CrewManager.characters.Add(character);
|
||||||
|
}
|
||||||
|
|
||||||
|
Item.Spawner.ReadNetworkData(inc);
|
||||||
|
|
||||||
|
if (ownerId == myID)
|
||||||
|
{
|
||||||
|
myCharacter = character;
|
||||||
|
Character.Controlled = character;
|
||||||
|
GameMain.LightManager.LosEnabled = true;
|
||||||
|
|
||||||
|
if (endVoteTickBox != null) endVoteTickBox.Visible = Voting.AllowEndVoting;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var characterOwner = otherClients.Find(c => c.ID == ownerId);
|
||||||
|
if (characterOwner != null) characterOwner.Character = character;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
character.Enabled = enabled;
|
||||||
|
|
||||||
return character;
|
return character;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using Lidgren.Network;
|
using Lidgren.Network;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
@@ -54,7 +55,11 @@ namespace Barotrauma.Networking
|
|||||||
name = name.Replace(";", "");
|
name = name.Replace(";", "");
|
||||||
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.password = password;
|
this.password = "";
|
||||||
|
if (password.Length>0)
|
||||||
|
{
|
||||||
|
this.password = Encoding.UTF8.GetString(NetUtility.ComputeSHAHash(Encoding.UTF8.GetBytes(password)));
|
||||||
|
}
|
||||||
|
|
||||||
config = new NetPeerConfiguration("barotrauma");
|
config = new NetPeerConfiguration("barotrauma");
|
||||||
|
|
||||||
@@ -104,6 +109,10 @@ namespace Barotrauma.Networking
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GUIButton settingsButton = new GUIButton(new Rectangle(GameMain.GraphicsWidth - 170 - 170 - 170, 20, 150, 20), "Settings", Alignment.TopLeft, GUI.Style, inGameHUD);
|
||||||
|
settingsButton.OnClicked = ToggleSettingsFrame;
|
||||||
|
settingsButton.UserData = "settingsButton";
|
||||||
|
|
||||||
banList = new BanList();
|
banList = new BanList();
|
||||||
|
|
||||||
LoadSettings();
|
LoadSettings();
|
||||||
@@ -343,6 +352,12 @@ namespace Barotrauma.Networking
|
|||||||
foreach (Client c in connectedClients)
|
foreach (Client c in connectedClients)
|
||||||
{
|
{
|
||||||
if (c.FileStreamSender != null) UpdateFileTransfer(c, deltaTime);
|
if (c.FileStreamSender != null) UpdateFileTransfer(c, deltaTime);
|
||||||
|
|
||||||
|
c.ReliableChannel.Update(deltaTime);
|
||||||
|
|
||||||
|
//slowly reset spam timers
|
||||||
|
c.ChatSpamTimer = Math.Max(0.0f, c.ChatSpamTimer - deltaTime);
|
||||||
|
c.ChatSpamSpeed = Math.Max(0.0f, c.ChatSpamSpeed - deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
NetIncomingMessage inc = null;
|
NetIncomingMessage inc = null;
|
||||||
@@ -974,35 +989,7 @@ namespace Barotrauma.Networking
|
|||||||
msg.Write((byte)characters.Count);
|
msg.Write((byte)characters.Count);
|
||||||
foreach (Character c in characters)
|
foreach (Character c in characters)
|
||||||
{
|
{
|
||||||
msg.Write(c is AICharacter);
|
WriteCharacterData(msg, c.Name, c);
|
||||||
msg.Write(c.ID);
|
|
||||||
|
|
||||||
if (c is AICharacter)
|
|
||||||
{
|
|
||||||
msg.Write(c.ConfigPath);
|
|
||||||
|
|
||||||
msg.Write(c.Position.X);
|
|
||||||
msg.Write(c.Position.Y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Client client = connectedClients.Find(cl => cl.Character == c);
|
|
||||||
if (client != null)
|
|
||||||
{
|
|
||||||
msg.Write(true);
|
|
||||||
msg.Write(client.ID);
|
|
||||||
}
|
|
||||||
else if (myCharacter == c)
|
|
||||||
{
|
|
||||||
msg.Write(true);
|
|
||||||
msg.Write((byte)0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
msg.Write(false);
|
|
||||||
}
|
|
||||||
WriteCharacterData(msg, c.Name, c);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return msg;
|
return msg;
|
||||||
@@ -1435,12 +1422,15 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
private void ReadChatMessage(NetIncomingMessage inc)
|
private void ReadChatMessage(NetIncomingMessage inc)
|
||||||
{
|
{
|
||||||
|
Client sender = connectedClients.Find(x => x.Connection == inc.SenderConnection);
|
||||||
ChatMessage message = ChatMessage.ReadNetworkMessage(inc);
|
ChatMessage message = ChatMessage.ReadNetworkMessage(inc);
|
||||||
|
if (message == null) return;
|
||||||
|
|
||||||
List<Client> recipients = new List<Client>();
|
List<Client> recipients = new List<Client>();
|
||||||
|
|
||||||
foreach (Client c in connectedClients)
|
foreach (Client c in connectedClients)
|
||||||
{
|
{
|
||||||
|
if (!sender.inGame && c.inGame) continue; //people in lobby can't talk to people ingame
|
||||||
switch (message.Type)
|
switch (message.Type)
|
||||||
{
|
{
|
||||||
case ChatMessageType.Dead:
|
case ChatMessageType.Dead:
|
||||||
@@ -1462,7 +1452,71 @@ namespace Barotrauma.Networking
|
|||||||
recipients.Add(c);
|
recipients.Add(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddChatMessage(message);
|
//SPAM FILTER
|
||||||
|
if (sender.ChatSpamTimer > 0.0f)
|
||||||
|
{
|
||||||
|
//player has already been spamming, stop again
|
||||||
|
ChatMessage denyMsg = ChatMessage.Create("", "You have been blocked by the spam filter. Try again after 10 seconds.", ChatMessageType.Server, null);
|
||||||
|
sender.ChatSpamTimer = 10.0f;
|
||||||
|
SendChatMessage(denyMsg, sender);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float similarity = 0;
|
||||||
|
similarity += sender.ChatSpamSpeed * 0.05f; //the faster messages are being sent, the faster the filter will block
|
||||||
|
for (int i = 0; i < sender.ChatMessages.Count; i++)
|
||||||
|
{
|
||||||
|
float closeFactor = 1.0f / (20.0f - i);
|
||||||
|
|
||||||
|
int levenshteinDist = ToolBox.LevenshteinDistance(message.Text, sender.ChatMessages[i]);
|
||||||
|
similarity += Math.Max((message.Text.Length - levenshteinDist) / message.Text.Length * closeFactor, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (similarity > 5.0f)
|
||||||
|
{
|
||||||
|
sender.ChatSpamCount++;
|
||||||
|
|
||||||
|
if (sender.ChatSpamCount > 3)
|
||||||
|
{
|
||||||
|
//kick for spamming too much
|
||||||
|
KickClient(sender, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ChatMessage denyMsg = ChatMessage.Create("", "You have been blocked by the spam filter. Try again after 10 seconds.", ChatMessageType.Server, null);
|
||||||
|
sender.ChatSpamTimer = 10.0f;
|
||||||
|
SendChatMessage(denyMsg, sender);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.ChatMessages.Add(message.Text);
|
||||||
|
if (sender.ChatMessages.Count > 20)
|
||||||
|
{
|
||||||
|
sender.ChatMessages.RemoveAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sender.inGame || (Screen.Selected == GameMain.NetLobbyScreen))
|
||||||
|
{
|
||||||
|
AddChatMessage(message);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GameServer.Log(message.TextWithSender, message.Color);
|
||||||
|
}
|
||||||
|
sender.ChatSpamSpeed += 5.0f;
|
||||||
|
|
||||||
|
foreach (Client c in recipients)
|
||||||
|
{
|
||||||
|
ReliableMessage msg = c.ReliableChannel.CreateMessage();
|
||||||
|
msg.InnerMessage.Write((byte)PacketTypes.Chatmessage);
|
||||||
|
|
||||||
|
message.WriteNetworkMessage(msg.InnerMessage);
|
||||||
|
|
||||||
|
c.ReliableChannel.SendMessage(msg, c.Connection);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SendChatMessage(string message, ChatMessageType? type = null)
|
public override void SendChatMessage(string message, ChatMessageType? type = null)
|
||||||
@@ -1521,6 +1575,16 @@ namespace Barotrauma.Networking
|
|||||||
SendChatMessage(chatMessage, recipients);
|
SendChatMessage(chatMessage, recipients);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SendChatMessage(ChatMessage chatMessage, Client recipient)
|
||||||
|
{
|
||||||
|
ReliableMessage msg = recipient.ReliableChannel.CreateMessage();
|
||||||
|
msg.InnerMessage.Write((byte)PacketTypes.Chatmessage);
|
||||||
|
|
||||||
|
chatMessage.WriteNetworkMessage(msg.InnerMessage);
|
||||||
|
|
||||||
|
recipient.ReliableChannel.SendMessage(msg, recipient.Connection);
|
||||||
|
}
|
||||||
|
|
||||||
public void SendChatMessage(ChatMessage chatMessage, List<Client> recipients)
|
public void SendChatMessage(ChatMessage chatMessage, List<Client> recipients)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -1528,6 +1592,9 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
private void ReadCharacterData(NetIncomingMessage message)
|
private void ReadCharacterData(NetIncomingMessage message)
|
||||||
{
|
{
|
||||||
|
Client sender = connectedClients.Find(c => c.Connection == message.SenderConnection);
|
||||||
|
if (sender == null) return;
|
||||||
|
|
||||||
string name = "";
|
string name = "";
|
||||||
Gender gender = Gender.Male;
|
Gender gender = Gender.Male;
|
||||||
int headSpriteId = 0;
|
int headSpriteId = 0;
|
||||||
@@ -1545,6 +1612,11 @@ namespace Barotrauma.Networking
|
|||||||
headSpriteId = 0;
|
headSpriteId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sender.characterInfo != null)
|
||||||
|
{
|
||||||
|
//clients can't change their character's name once it's been set
|
||||||
|
name = sender.characterInfo.Name;
|
||||||
|
}
|
||||||
|
|
||||||
List<JobPrefab> jobPreferences = new List<JobPrefab>();
|
List<JobPrefab> jobPreferences = new List<JobPrefab>();
|
||||||
int count = message.ReadByte();
|
int count = message.ReadByte();
|
||||||
@@ -1555,50 +1627,59 @@ namespace Barotrauma.Networking
|
|||||||
if (jobPrefab != null) jobPreferences.Add(jobPrefab);
|
if (jobPrefab != null) jobPreferences.Add(jobPrefab);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Client c in connectedClients)
|
sender.characterInfo = new CharacterInfo(Character.HumanConfigFile, name, gender);
|
||||||
{
|
sender.characterInfo.HeadSpriteId = headSpriteId;
|
||||||
if (c.Connection != message.SenderConnection) continue;
|
sender.jobPreferences = jobPreferences;
|
||||||
|
|
||||||
c.characterInfo = new CharacterInfo(Character.HumanConfigFile, name, gender);
|
|
||||||
c.characterInfo.HeadSpriteId = headSpriteId;
|
|
||||||
c.jobPreferences = jobPreferences;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteCharacterData(NetOutgoingMessage message, string name, Character character)
|
public void WriteCharacterData(NetOutgoingMessage msg, string name, Character c)
|
||||||
{
|
{
|
||||||
message.Write(name);
|
msg.Write(c.Info == null);
|
||||||
message.Write(character.ID);
|
msg.Write(c.ID);
|
||||||
message.Write(character.Info.Gender == Gender.Female);
|
msg.Write(c.ConfigPath);
|
||||||
|
|
||||||
message.Write((byte)character.Info.HeadSpriteId);
|
msg.Write(c.WorldPosition.X);
|
||||||
|
msg.Write(c.WorldPosition.Y);
|
||||||
|
|
||||||
message.Write(character.WorldPosition.X);
|
msg.Write(c.Enabled);
|
||||||
message.Write(character.WorldPosition.Y);
|
|
||||||
|
|
||||||
message.Write(character.Info.Job.Name);
|
if (c.Info != null)
|
||||||
|
{
|
||||||
|
Client client = connectedClients.Find(cl => cl.Character == c);
|
||||||
|
if (client != null)
|
||||||
|
{
|
||||||
|
msg.Write(true);
|
||||||
|
msg.Write(client.ID);
|
||||||
|
}
|
||||||
|
else if (myCharacter == c)
|
||||||
|
{
|
||||||
|
msg.Write(true);
|
||||||
|
msg.Write((byte)0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg.Write(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.Write(name);
|
||||||
|
|
||||||
|
msg.Write(c is AICharacter);
|
||||||
|
msg.Write(c.Info.Gender == Gender.Female);
|
||||||
|
msg.Write((byte)c.Info.HeadSpriteId);
|
||||||
|
msg.Write(c.Info.Job == null ? "" : c.Info.Job.Name);
|
||||||
|
|
||||||
|
Item.Spawner.FillNetworkData(msg, c.SpawnItems);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendCharacterSpawnMessage(Character character, List<NetConnection> recipients = null)
|
public void SendCharacterSpawnMessage(Character character, List<NetConnection> recipients = null)
|
||||||
{
|
{
|
||||||
|
if (recipients != null && !recipients.Any()) return;
|
||||||
|
|
||||||
NetOutgoingMessage message = server.CreateMessage();
|
NetOutgoingMessage message = server.CreateMessage();
|
||||||
message.Write((byte)PacketTypes.NewCharacter);
|
message.Write((byte)PacketTypes.NewCharacter);
|
||||||
|
|
||||||
message.Write(character.ConfigPath);
|
WriteCharacterData(message, character.Name, character);
|
||||||
|
|
||||||
if (character.ConfigPath == Character.HumanConfigFile)
|
|
||||||
{
|
|
||||||
WriteCharacterData(message, character.Name, character);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
message.Write(character.ID);
|
|
||||||
|
|
||||||
message.Write(character.Position.X);
|
|
||||||
message.Write(character.Position.Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
SendMessage(message, NetDeliveryMethod.ReliableUnordered, recipients);
|
SendMessage(message, NetDeliveryMethod.ReliableUnordered, recipients);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,11 +61,14 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
unauthenticatedClients.Remove(unauthenticatedClient);
|
unauthenticatedClients.Remove(unauthenticatedClient);
|
||||||
|
|
||||||
NetEncryption algo = new NetXtea(server, password);
|
string saltedPw = password;
|
||||||
|
saltedPw = saltedPw + Convert.ToString(unauthenticatedClient.Nonce);
|
||||||
|
saltedPw = Encoding.UTF8.GetString(NetUtility.ComputeSHAHash(Encoding.UTF8.GetBytes(saltedPw)));
|
||||||
|
NetEncryption algo = new NetXtea(server, saltedPw);
|
||||||
inc.Decrypt(algo);
|
inc.Decrypt(algo);
|
||||||
|
|
||||||
int nonce = inc.ReadInt32();
|
string rdPw = inc.ReadString();
|
||||||
if (nonce != unauthenticatedClient.Nonce)
|
if (rdPw != saltedPw)
|
||||||
{
|
{
|
||||||
inc.SenderConnection.Disconnect("Wrong password!");
|
inc.SenderConnection.Disconnect("Wrong password!");
|
||||||
return;
|
return;
|
||||||
@@ -74,6 +77,13 @@ namespace Barotrauma.Networking
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
inc.SenderConnection.Disconnect("Authentication failed");
|
inc.SenderConnection.Disconnect("Authentication failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConnectedClients.Count>=config.MaximumConnections)
|
||||||
|
{
|
||||||
|
inc.SenderConnection.Disconnect("Server full");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugConsole.NewMessage("New player has joined the server", Color.White);
|
DebugConsole.NewMessage("New player has joined the server", Color.White);
|
||||||
|
|||||||
@@ -646,5 +646,38 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ManagePlayersFrame(GUIFrame infoFrame)
|
||||||
|
{
|
||||||
|
GUIListBox cList = new GUIListBox(new Rectangle(0, 0, 0, 300), Color.White * 0.7f, GUI.Style, infoFrame);
|
||||||
|
cList.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
|
||||||
|
//crewList.OnSelected = SelectCrewCharacter;
|
||||||
|
|
||||||
|
foreach (Client c in ConnectedClients)
|
||||||
|
{
|
||||||
|
GUIFrame frame = new GUIFrame(new Rectangle(0, 0, 0, 40), Color.Transparent, null, cList);
|
||||||
|
frame.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
|
||||||
|
frame.Color = (c.inGame && c.Character!=null && !c.Character.IsDead) ? Color.Gold * 0.2f : Color.Transparent;
|
||||||
|
frame.HoverColor = Color.LightGray * 0.5f;
|
||||||
|
frame.SelectedColor = Color.Gold * 0.5f;
|
||||||
|
|
||||||
|
GUITextBlock textBlock = new GUITextBlock(
|
||||||
|
new Rectangle(40, 0, 0, 25),
|
||||||
|
c.name + " (" + c.Connection.RemoteEndPoint.Address.ToString() + ")",
|
||||||
|
Color.Transparent, Color.White,
|
||||||
|
Alignment.Left, Alignment.Left,
|
||||||
|
null, frame);
|
||||||
|
|
||||||
|
var banButton = new GUIButton(new Rectangle(-120, 0, 100, 20), "Ban", Alignment.Right | Alignment.CenterY, GUI.Style, frame);
|
||||||
|
banButton.UserData = c.name;
|
||||||
|
banButton.OnClicked += GameMain.NetLobbyScreen.BanPlayer;
|
||||||
|
|
||||||
|
var kickButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Kick", Alignment.Right | Alignment.CenterY, GUI.Style, frame);
|
||||||
|
kickButton.UserData = c.name;
|
||||||
|
kickButton.OnClicked += GameMain.NetLobbyScreen.KickPlayer;
|
||||||
|
|
||||||
|
textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -264,6 +264,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public void AddChatMessage(ChatMessage message)
|
public void AddChatMessage(ChatMessage message)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (message.Type == ChatMessageType.Radio &&
|
if (message.Type == ChatMessageType.Radio &&
|
||||||
Character.Controlled != null &&
|
Character.Controlled != null &&
|
||||||
message.Sender != null && message.Sender != myCharacter)
|
message.Sender != null && message.Sender != myCharacter)
|
||||||
@@ -278,6 +279,8 @@ namespace Barotrauma.Networking
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GameServer.Log(message.TextWithSender, message.Color);
|
||||||
|
|
||||||
string displayedText = message.Text;
|
string displayedText = message.Text;
|
||||||
|
|
||||||
if (message.Sender != null)
|
if (message.Sender != null)
|
||||||
@@ -293,8 +296,6 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
GameMain.NetLobbyScreen.NewChatMessage(message);
|
GameMain.NetLobbyScreen.NewChatMessage(message);
|
||||||
|
|
||||||
GameServer.Log(message.Text, message.Color);
|
|
||||||
|
|
||||||
while (chatBox.CountChildren > 20)
|
while (chatBox.CountChildren > 20)
|
||||||
{
|
{
|
||||||
chatBox.RemoveChild(chatBox.children[1]);
|
chatBox.RemoveChild(chatBox.children[1]);
|
||||||
@@ -309,6 +310,7 @@ namespace Barotrauma.Networking
|
|||||||
((chatBox.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f, message.Color,
|
((chatBox.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f, message.Color,
|
||||||
Alignment.Left, null, null, true);
|
Alignment.Left, null, null, true);
|
||||||
msg.Font = GUI.SmallFont;
|
msg.Font = GUI.SmallFont;
|
||||||
|
msg.UserData = message.SenderName;
|
||||||
|
|
||||||
msg.Padding = new Vector4(20.0f, 0, 0, 0);
|
msg.Padding = new Vector4(20.0f, 0, 0, 0);
|
||||||
|
|
||||||
@@ -340,15 +342,12 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
if (gameStarted && Screen.Selected == GameMain.GameScreen)
|
if (gameStarted && Screen.Selected == GameMain.GameScreen)
|
||||||
{
|
{
|
||||||
chatMsgBox.Visible = Character.Controlled == null ||
|
chatMsgBox.Visible = Character.Controlled == null || Character.Controlled.CanSpeak;
|
||||||
(!Character.Controlled.IsUnconscious && Character.Controlled.Stun <= 0.0f);
|
|
||||||
|
|
||||||
inGameHUD.Update(deltaTime);
|
inGameHUD.Update(deltaTime);
|
||||||
|
|
||||||
GameMain.GameSession.CrewManager.Update(deltaTime);
|
GameMain.GameSession.CrewManager.Update(deltaTime);
|
||||||
|
|
||||||
//if (crewFrameOpen) crewFrame.Update(deltaTime);
|
|
||||||
|
|
||||||
if (Character.Controlled == null || Character.Controlled.IsDead)
|
if (Character.Controlled == null || Character.Controlled.IsDead)
|
||||||
{
|
{
|
||||||
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
|
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
|
||||||
|
|||||||
@@ -532,7 +532,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
byte clientId = inc.ReadByte();
|
byte clientId = inc.ReadByte();
|
||||||
|
|
||||||
var character = client.ReadCharacterData(inc, clientId == client.ID);
|
var character = client.ReadCharacterData(inc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state != newState)
|
if (state != newState)
|
||||||
|
|||||||
@@ -98,10 +98,10 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
float prevSize = listBox.BarSize;
|
float prevSize = listBox.BarSize;
|
||||||
|
|
||||||
var textBlock = new GUITextBlock(new Rectangle(0, 0, 0, 0), line.Text, GUI.Style, Alignment.TopLeft, Alignment.TopLeft, null, true, GUI.SmallFont);
|
var textBlock = new GUITextBlock(new Rectangle(0, 0, 0, 0), line.Text, GUI.Style, Alignment.TopLeft, Alignment.TopLeft, listBox, true, GUI.SmallFont);
|
||||||
textBlock.Rect = new Rectangle(textBlock.Rect.X, textBlock.Rect.Y, textBlock.Rect.Width, Math.Max(13, textBlock.Rect.Height));
|
textBlock.Rect = new Rectangle(textBlock.Rect.X, textBlock.Rect.Y, textBlock.Rect.Width, Math.Max(13, textBlock.Rect.Height));
|
||||||
|
|
||||||
listBox.AddChild(textBlock);
|
//listBox.AddChild(textBlock);
|
||||||
|
|
||||||
textBlock.TextColor = line.Color;
|
textBlock.TextColor = line.Color;
|
||||||
textBlock.CanBeFocused = false;
|
textBlock.CanBeFocused = false;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ namespace Barotrauma
|
|||||||
Use,
|
Use,
|
||||||
Aim,
|
Aim,
|
||||||
Up, Down, Left, Right,
|
Up, Down, Left, Right,
|
||||||
|
Attack,
|
||||||
Run, Crouch,
|
Run, Crouch,
|
||||||
Chat, CrewOrders
|
Chat, CrewOrders
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -989,6 +989,7 @@ namespace Barotrauma
|
|||||||
((chatBox.CountChildren % 2) == 0) ? Color.Transparent : Color.Black*0.1f, message.Color,
|
((chatBox.CountChildren % 2) == 0) ? Color.Transparent : Color.Black*0.1f, message.Color,
|
||||||
Alignment.Left, GUI.Style, null, true);
|
Alignment.Left, GUI.Style, null, true);
|
||||||
msg.Font = GUI.SmallFont;
|
msg.Font = GUI.SmallFont;
|
||||||
|
msg.UserData = message.SenderName;
|
||||||
msg.CanBeFocused = false;
|
msg.CanBeFocused = false;
|
||||||
|
|
||||||
msg.Padding = new Vector4(20, 0, 0, 0);
|
msg.Padding = new Vector4(20, 0, 0, 0);
|
||||||
|
|||||||
@@ -222,7 +222,56 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
DrawTiled(spriteBatch, pos, targetSize, Vector2.Zero, color);
|
DrawTiled(spriteBatch, pos, targetSize, Vector2.Zero, color);
|
||||||
}
|
}
|
||||||
|
public void DrawTiled(SpriteBatch spriteBatch, Vector2 pos, Vector2 targetSize, Vector2 startOffset, Color color, Point offset)
|
||||||
|
{
|
||||||
|
//how many times the texture needs to be drawn on the x-axis
|
||||||
|
int xTiles = (int)Math.Ceiling((targetSize.X + startOffset.X) / sourceRect.Width);
|
||||||
|
//how many times the texture needs to be drawn on the y-axis
|
||||||
|
int yTiles = (int)Math.Ceiling((targetSize.Y + startOffset.Y) / sourceRect.Height);
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle TexPerspective = sourceRect;
|
||||||
|
|
||||||
|
TexPerspective.Location += offset;
|
||||||
|
while (TexPerspective.Location.X >= sourceRect.X + sourceRect.Width)
|
||||||
|
TexPerspective.X = sourceRect.X + (TexPerspective.Location.X - (sourceRect.X + sourceRect.Width));
|
||||||
|
while (TexPerspective.Location.Y >= sourceRect.Y + sourceRect.Height)
|
||||||
|
TexPerspective.Y = sourceRect.Y + (TexPerspective.Location.Y - (sourceRect.Y + sourceRect.Height));
|
||||||
|
TexPerspective.Width = (int)Math.Min(targetSize.X, sourceRect.Width);
|
||||||
|
TexPerspective.Height = (int)Math.Min(targetSize.Y, sourceRect.Height);
|
||||||
|
for (int y = 0; y < yTiles; y++)
|
||||||
|
{
|
||||||
|
TexPerspective.Width = (int)Math.Min(targetSize.X, sourceRect.Width);
|
||||||
|
TexPerspective.Height = (int)Math.Min(targetSize.Y, sourceRect.Height);
|
||||||
|
float top = pos.Y + TexPerspective.Height * y;
|
||||||
|
for (int x = 0; x < xTiles; x++)
|
||||||
|
{
|
||||||
|
float left = pos.X + TexPerspective.Width * x;
|
||||||
|
TexPerspective.Width = Math.Min((int)(targetSize.X - TexPerspective.Width * x), TexPerspective.Width);
|
||||||
|
TexPerspective.Height = Math.Min((int)(targetSize.Y - TexPerspective.Height * y), TexPerspective.Height);
|
||||||
|
var movementX = TexPerspective.Width;
|
||||||
|
var movementY = TexPerspective.Height;
|
||||||
|
if (TexPerspective.X+TexPerspective.Width > sourceRect.X + sourceRect.Width)
|
||||||
|
{
|
||||||
|
float diff = (TexPerspective.X + TexPerspective.Width) - (sourceRect.X + sourceRect.Width);
|
||||||
|
TexPerspective.Width -= (int)diff;
|
||||||
|
spriteBatch.Draw(texture, new Vector2(left+ TexPerspective.Width, top), new Rectangle(sourceRect.X, TexPerspective.Y,(int)diff, TexPerspective.Height), color, rotation, Vector2.Zero, 1.0f, effects, depth);
|
||||||
|
}
|
||||||
|
else if (TexPerspective.Y + TexPerspective.Height > sourceRect.Y + sourceRect.Height)
|
||||||
|
{
|
||||||
|
float diff = (TexPerspective.Y + TexPerspective.Height) - (sourceRect.Y + sourceRect.Height);
|
||||||
|
TexPerspective.Height -= (int)diff;
|
||||||
|
spriteBatch.Draw(texture, new Vector2(left, top+ TexPerspective.Height), new Rectangle(TexPerspective.X, sourceRect.Y, TexPerspective.Width, (int)diff), color, rotation, Vector2.Zero, 1.0f, effects, depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
spriteBatch.Draw(texture, new Vector2(left,top),TexPerspective, color, rotation, Vector2.Zero, 1.0f, effects, depth);
|
||||||
|
if (TexPerspective.X+ movementX >= sourceRect.X + sourceRect.Width)
|
||||||
|
TexPerspective.X = sourceRect.X;
|
||||||
|
if (TexPerspective.Y + movementY >= sourceRect.Y + sourceRect.Height)
|
||||||
|
TexPerspective.Y = sourceRect.Y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
public void DrawTiled(SpriteBatch spriteBatch, Vector2 pos, Vector2 targetSize, Vector2 startOffset, Color color)
|
public void DrawTiled(SpriteBatch spriteBatch, Vector2 pos, Vector2 targetSize, Vector2 startOffset, Color color)
|
||||||
{
|
{
|
||||||
//pos.X = (int)pos.X;
|
//pos.X = (int)pos.X;
|
||||||
|
|||||||
@@ -366,6 +366,35 @@ namespace Barotrauma
|
|||||||
return inputType;
|
return inputType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the minimum number of single-character edits (i.e. insertions, deletions or substitutions) required to change one string into the other
|
||||||
|
/// </summary>
|
||||||
|
public static int LevenshteinDistance(string s, string t)
|
||||||
|
{
|
||||||
|
int n = s.Length;
|
||||||
|
int m = t.Length;
|
||||||
|
int[,] d = new int[n + 1, m + 1];
|
||||||
|
|
||||||
|
if (n == 0 || m == 0) return 0;
|
||||||
|
|
||||||
|
for (int i = 0; i <= n; d[i, 0] = i++);
|
||||||
|
for (int j = 0; j <= m; d[0, j] = j++);
|
||||||
|
|
||||||
|
for (int i = 1; i <= n; i++)
|
||||||
|
{
|
||||||
|
for (int j = 1; j <= m; j++)
|
||||||
|
{
|
||||||
|
int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
|
||||||
|
|
||||||
|
d[i, j] = Math.Min(
|
||||||
|
Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
|
||||||
|
d[i - 1, j - 1] + cost);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return d[n, m];
|
||||||
|
}
|
||||||
|
|
||||||
public static string WrapText(string text, float lineLength, SpriteFont font)
|
public static string WrapText(string text, float lineLength, SpriteFont font)
|
||||||
{
|
{
|
||||||
if (font.MeasureString(text).X < lineLength) return text;
|
if (font.MeasureString(text).X < lineLength) return text;
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,3 +1,31 @@
|
|||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
v0.5.1.1
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
- fixed non-password protected servers being impossible to join to
|
||||||
|
- some more security checks
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
v0.5.1.0
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
- getting attacked by a husk will slowly turn the victim into a husk
|
||||||
|
|
||||||
|
- spam filter
|
||||||
|
- added server options to the ingame HUD
|
||||||
|
- fixed tiger thresher spawning on Linux
|
||||||
|
- a more secure password authentication method (again)
|
||||||
|
- ingame players can't receive messages from lobby players anymore
|
||||||
|
- more server-side security checks
|
||||||
|
|
||||||
|
- medical doctors always have a high enough medical skill to fabricate any drug
|
||||||
|
- ai-controlled crew can be spawned using the console in multiplayer
|
||||||
|
- it's possible to manually attack when controlling a creature
|
||||||
|
- randomly spawned artifacts are spread out better throughout the level
|
||||||
|
- characters won't let go of a person they're dragging when entering/exiting the sub
|
||||||
|
- respawned players get the same ID card tags they would've gotten if they had spawned inside the main sub
|
||||||
|
- highlighted characters glow in the dark
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------
|
||||||
v0.5.0.3
|
v0.5.0.3
|
||||||
---------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -2,5 +2,5 @@
|
|||||||
<config masterserverurl="http://www.undertowgames.com/baromaster" autocheckupdates="true" musicvolume="0.0" soundvolume="0.0" verboselogging="true">
|
<config masterserverurl="http://www.undertowgames.com/baromaster" autocheckupdates="true" musicvolume="0.0" soundvolume="0.0" verboselogging="true">
|
||||||
<graphicsmode width="1280" height="720" fullscreen="false" />
|
<graphicsmode width="1280" height="720" fullscreen="false" />
|
||||||
<contentpackage path="Data/ContentPackages/Vanilla 0.3.xml" />
|
<contentpackage path="Data/ContentPackages/Vanilla 0.3.xml" />
|
||||||
<keymapping Select="E" Use="0" Aim="1" Up="W" Down="S" Left="A" Right="D" Run="LeftShift" Crouch="LeftControl" Chat="Tab" CrewOrders="C" />
|
<keymapping Select="E" Use="0" Aim="1" Up="W" Down="S" Left="A" Right="D" Attack="R" Run="LeftShift" Crouch="LeftControl" Chat="Tab" CrewOrders="C" />
|
||||||
</config>
|
</config>
|
||||||
Reference in New Issue
Block a user