Attack configs determine whether an attack can sever limbs (instead of the amount of damage), new blood particles

This commit is contained in:
Joonas Rikkonen
2017-06-14 19:24:49 +03:00
parent f6425a7229
commit 242da11e3f
17 changed files with 116 additions and 96 deletions
+9
View File
@@ -875,6 +875,15 @@
<Content Include="Content\Particles\SmokeParticleSheet.png"> <Content Include="Content\Particles\SmokeParticleSheet.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="Content\Particles\Spatter1.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Particles\Spatter2.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Particles\Spatter3.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Sounds\Damage\StructureBlunt10.ogg"> <Content Include="Content\Sounds\Damage\StructureBlunt10.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
@@ -24,7 +24,7 @@
<!-- lower yaw --> <!-- lower yaw -->
<limb id = "1" radius="70" height="100"> <limb id = "1" radius="70" height="100">
<sprite texture="Content/Characters/Charybdis/charybdis.png" sourcerect="416,0,192,256" depth="0.025" origin="0.65,0.5"/> <sprite texture="Content/Characters/Charybdis/charybdis.png" sourcerect="416,0,192,256" depth="0.025" origin="0.65,0.5"/>
<attack range="500" duration="0.5" damage="5.00" bleedingdamage="50" structuredamage="500" damagetype="slash" torque="200" force="50" targetforce="-50"/> <attack range="500" duration="0.5" damage="5.00" bleedingdamage="50" structuredamage="500" damagetype="slash" torque="200" force="50" targetforce="-50" severlimbsprobability="1.0"/>
</limb> </limb>
<!-- front fins --> <!-- front fins -->
@@ -26,7 +26,7 @@
<!-- lower yaw --> <!-- lower yaw -->
<limb id = "1" radius="20" height="240"> <limb id = "1" radius="20" height="240">
<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 range="300" duration="0.5" damage="200" bleedingdamage="50" structuredamage="150" damagetype="slash" torque="100" targetforce="-50"/> <attack range="300" duration="0.5" damage="200" bleedingdamage="50" structuredamage="150" damagetype="slash" torque="100" targetforce="-50" severlimbsprobability="0.8"/>
</limb> </limb>
<!-- body --> <!-- body -->
@@ -44,7 +44,7 @@
<limb id = "3" width="13" height="45" ignorecollisions="true" flip="true"> <limb id = "3" width="13" height="45" ignorecollisions="true" flip="true">
<sprite texture="Content/Characters/Crawler/crawler.png" sourcerect="65,131,36,50" depth="0.15" origin="0.4,0.5"/> <sprite texture="Content/Characters/Crawler/crawler.png" sourcerect="65,131,36,50" depth="0.15" origin="0.4,0.5"/>
<attack range="120" duration="0.5" damage="30" stun="0.1" bleedingdamage="3" structuredamage="50" damagetype="slash" force="20" torque="-20" targetforce="-30"/> <attack range="120" duration="0.5" damage="30" stun="0.1" bleedingdamage="3" structuredamage="50" damagetype="slash" force="20" torque="-20" targetforce="-30" severlimbsprobability="0.5"/>
</limb> </limb>
<limb id = "4" width="11" height="34" type="RightLeg" flip="true"> <limb id = "4" width="11" height="34" type="RightLeg" flip="true">
@@ -61,7 +61,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 range="200" duration="0.5" damage="30" stun="0.1" bleedingdamage="5" structuredamage="50" torque="-20" damagetype="slash" force="10" targetforce="-30"/> <attack range="200" duration="0.5" damage="30" stun="0.1" bleedingdamage="5" structuredamage="50" torque="-20" damagetype="slash" force="10" targetforce="-30" severlimbsprobability="0.8"/>
<sound file ="Content/Sounds/stepMetal.ogg"/> <sound file ="Content/Sounds/stepMetal.ogg"/>
</limb> </limb>
@@ -30,7 +30,7 @@
<limb id = "1" width="16" height="103"> <limb id = "1" width="16" height="103">
<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 range="300" duration="0.5" damage="150" bleedingdamage="10" structuredamage="200" damagetype="slash" force="80" torque="80" targetforce="-50"/> <attack range="300" duration="0.5" damage="150" bleedingdamage="10" structuredamage="200" damagetype="slash" force="80" torque="80" targetforce="-50" severlimbsprobability="0.8"/>
</limb> </limb>
<!-- body --> <!-- body -->
@@ -13,7 +13,7 @@
<Pickable slots="Any"> <Pickable slots="Any">
<StatusEffect type="OnBroken" target="This" Condition="-100.0" sound="Content/Items/Reactor/explosion.ogg"> <StatusEffect type="OnBroken" target="This" Condition="-100.0" sound="Content/Items/Reactor/explosion.ogg">
<Explosion range="500.0" structuredamage="250" damage="200" stun="5" force="20.0"/> <Explosion range="500.0" structuredamage="250" damage="200" stun="5" force="20.0" severlimbsprobability="0.5"/>
</StatusEffect> </StatusEffect>
</Pickable> </Pickable>
</Item> </Item>
@@ -31,7 +31,7 @@
<Pickable slots="Any"> <Pickable slots="Any">
<StatusEffect type="OnFire" target="This" Condition="-50.0"/> <StatusEffect type="OnFire" target="This" Condition="-50.0"/>
<StatusEffect type="OnBroken" target="This" Condition="-100.0" sound="Content/Items/Reactor/explosion.ogg"> <StatusEffect type="OnBroken" target="This" Condition="-100.0" sound="Content/Items/Reactor/explosion.ogg">
<Explosion range="600.0" structuredamage="150" damage="300" stun="5" force="20.0"/> <Explosion range="600.0" structuredamage="150" damage="300" stun="5" force="20.0" severlimbsprobability="0.6"/>
</StatusEffect> </StatusEffect>
</Pickable> </Pickable>
</Item> </Item>
@@ -50,7 +50,7 @@
<StatusEffect type="Always" target="This" Condition="-0.35"/> <StatusEffect type="Always" target="This" Condition="-0.35"/>
<StatusEffect type="OnFire" target="This" Condition="-50.0"/> <StatusEffect type="OnFire" target="This" Condition="-50.0"/>
<StatusEffect type="OnBroken" target="This" Condition="-100.0" sound="Content/Items/Reactor/explosion.ogg"> <StatusEffect type="OnBroken" target="This" Condition="-100.0" sound="Content/Items/Reactor/explosion.ogg">
<Explosion range="600.0" structuredamage="150" damage="300" stun="5" force="20.0"/> <Explosion range="600.0" structuredamage="150" damage="300" stun="5" force="20.0" severlimbsprobability="0.6"/>
</StatusEffect> </StatusEffect>
</Pickable> </Pickable>
</Item> </Item>
@@ -69,7 +69,7 @@
<Pickable slots="Any"> <Pickable slots="Any">
<StatusEffect type="OnFire" target="This" Condition="-50.0"/> <StatusEffect type="OnFire" target="This" Condition="-50.0"/>
<StatusEffect type="OnBroken" target="This" Condition="-100.0" sound="Content/Items/Reactor/explosion.ogg"> <StatusEffect type="OnBroken" target="This" Condition="-100.0" sound="Content/Items/Reactor/explosion.ogg">
<Explosion range="500.0" structuredamage="50" damage="300" stun="5" force="20.0"/> <Explosion range="500.0" structuredamage="50" damage="300" stun="5" force="20.0" severlimbsprobability="0.6"/>
<Fire size="500"/> <Fire size="500"/>
</StatusEffect> </StatusEffect>
</Pickable> </Pickable>
@@ -121,7 +121,7 @@
<StatusEffect type="OnFire" target="This" Condition="-50.0"/> <StatusEffect type="OnFire" target="This" Condition="-50.0"/>
<StatusEffect type="OnBroken" target="This" Condition="-100.0" sound="Content/Items/Reactor/explosion.ogg"> <StatusEffect type="OnBroken" target="This" Condition="-100.0" sound="Content/Items/Reactor/explosion.ogg">
<Explosion range="600.0" structuredamage="400" damage="300" stun="5" force="20.0"/> <Explosion range="600.0" structuredamage="400" damage="300" stun="5" force="20.0" severlimbsprobability="0.4"/>
</StatusEffect> </StatusEffect>
<StatusEffect type="OnUse" target="This" Condition="-100.0"> <StatusEffect type="OnUse" target="This" Condition="-100.0">
+3 -3
View File
@@ -83,7 +83,7 @@
<Holdable slots="RightHand+LeftHand" holdpos="0,-50" handle1="-10,0" handle2="10,0" aimable="false"/> <Holdable slots="RightHand+LeftHand" holdpos="0,-50" handle1="-10,0" handle2="10,0" aimable="false"/>
<Projectile launchimpulse="80.0"> <Projectile launchimpulse="80.0">
<Attack damage="100" bleedingdamage="10" structuredamage="200" damagetype="Blunt"/> <Attack damage="100" bleedingdamage="10" structuredamage="200" damagetype="Blunt" severlimbsprobability="1.0"/>
<StatusEffect type="OnActive" target="This"> <StatusEffect type="OnActive" target="This">
<ParticleEmitter particle="bubbles" anglemin="0" anglemax="360" particleamount="10" velocitymin="0" velocitymax="50" scalemin="2" scalemax="5"/> <ParticleEmitter particle="bubbles" anglemin="0" anglemax="360" particleamount="10" velocitymin="0" velocitymax="50" scalemin="2" scalemax="5"/>
@@ -115,10 +115,10 @@
<Holdable slots="RightHand+LeftHand" holdpos="0,-50" handle1="-10,0" handle2="10,0" aimable="false"/> <Holdable slots="RightHand+LeftHand" holdpos="0,-50" handle1="-10,0" handle2="10,0" aimable="false"/>
<Projectile launchimpulse="80.0"> <Projectile launchimpulse="80.0">
<Attack damage="1000" bleedingdamage="10" structuredamage="200" damagetype="Blunt"/> <Attack damage="1000" bleedingdamage="10" structuredamage="200" damagetype="Blunt" severlimbsprobability="1.0"/>
<StatusEffect type="OnUse" Condition="-100.0" stun="10.0" disabledeltatime="true" sound="Content/Items/Weapons/bigexplosion.ogg"> <StatusEffect type="OnUse" Condition="-100.0" stun="10.0" disabledeltatime="true" sound="Content/Items/Weapons/bigexplosion.ogg">
<Explosion range="1000.0" structuredamage="1000" damage="1000" stun="10" force="50.0"/> <Explosion range="1000.0" structuredamage="1000" damage="1000" stun="10" force="50.0" severlimbsprobability="0.8"/>
</StatusEffect> </StatusEffect>
<StatusEffect type="OnActive" target="This"> <StatusEffect type="OnActive" target="This">
@@ -57,26 +57,22 @@
</bubbles> </bubbles>
<blood <blood
startsizemin="0.05,0.05" startsizemax="0.6,0.6" startsizemin="0.5,0.5" startsizemax="1.0,1.0"
sizechangemin="0.3,0.2" sizechangemax="0.4,0.2"
startrotationmin ="0.0" startrotationmax="360" startrotationmin ="0.0" startrotationmax="360"
startcolor="0.5, 0.0, 0.0" startalpha="1.0" startcolor="0.5, 0.0, 0.0" startalpha="1.0"
colorchange="0.0, 0.0, 0.0, -1.0" lifetime="1"
lifetime="2"
growtime ="0.1" growtime ="0.1"
deleteoncollision="true" velocitychange="0.0, -0.1">
rotatetodirection="true" <animatedsprite texture="Content/Particles/Spatter1.png" sourcerect="0,0,1024,1024" columns="4" rows="8" origin="0.2,0.5"/>
velocitychange="0.0, -9.8"> <animatedsprite texture="Content/Particles/Spatter2.png" sourcerect="0,0,1024,1024" columns="4" rows="8" origin="0.5,0.5"/>
<sprite texture="Content/Particles/spatter.png" sourcerect="0,0,128,128"/> <animatedsprite texture="Content/Particles/Spatter3.png" sourcerect="0,0,1024,1024" columns="4" rows="8" origin="0.3,0.5"/>
<sprite texture="Content/Particles/spatter.png" sourcerect="128,0,128,128"/>
<sprite texture="Content/Particles/spatter.png" sourcerect="0,128,128,128"/>
</blood> </blood>
<waterblood <waterblood
startsizemin="0.1,0.1" startsizemax="0.3,0.3" startsizemin="0.1,0.1" startsizemax="0.3,0.3"
sizechangemin="0.1,0.1" sizechangemax="0.2,0.2" sizechangemin="0.1,0.1" sizechangemax="0.2,0.2"
startrotationmin ="0.0" startrotationmax="360" startrotationmin ="0.0" startrotationmax="360"
startcolor="0.5, 0.0, 0.0" startalpha="1.0" startcolor="0.3, 0.0, 0.0" startalpha="1.0"
animduration="5" animduration="5"
colorchange="0.0, 0.0, 0.0, -0.2" colorchange="0.0, 0.0, 0.0, -0.2"
growtime ="0.1" growtime ="0.1"
Binary file not shown.

After

Width:  |  Height:  |  Size: 750 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

+12 -13
View File
@@ -49,6 +49,8 @@ namespace Barotrauma
public readonly float TargetForce; public readonly float TargetForce;
public readonly float SeverLimbsProbability;
private Sound sound; private Sound sound;
private ParticleEmitterPrefab particleEmitterPrefab; private ParticleEmitterPrefab particleEmitterPrefab;
@@ -83,17 +85,16 @@ namespace Barotrauma
DamageType = DamageType.None; DamageType = DamageType.None;
} }
damage = ToolBox.GetAttributeFloat(element, "damage", 0.0f);
damage = ToolBox.GetAttributeFloat(element, "damage", 0.0f);
structureDamage = ToolBox.GetAttributeFloat(element, "structuredamage", 0.0f); structureDamage = ToolBox.GetAttributeFloat(element, "structuredamage", 0.0f);
bleedingDamage = ToolBox.GetAttributeFloat(element, "bleedingdamage", 0.0f); bleedingDamage = ToolBox.GetAttributeFloat(element, "bleedingdamage", 0.0f);
Stun = ToolBox.GetAttributeFloat(element, "stun", 0.0f);
Force = ToolBox.GetAttributeFloat(element,"force", 0.0f); SeverLimbsProbability = ToolBox.GetAttributeFloat(element, "severlimbsprobability", 0.0f);
TargetForce = ToolBox.GetAttributeFloat(element, "targetforce", 0.0f);
Torque = ToolBox.GetAttributeFloat(element, "torque", 0.0f); Force = ToolBox.GetAttributeFloat(element,"force", 0.0f);
TargetForce = ToolBox.GetAttributeFloat(element, "targetforce", 0.0f);
Stun = ToolBox.GetAttributeFloat(element, "stun", 0.0f); Torque = ToolBox.GetAttributeFloat(element, "torque", 0.0f);
string soundPath = ToolBox.GetAttributeString(element, "sound", ""); string soundPath = ToolBox.GetAttributeString(element, "sound", "");
if (!string.IsNullOrWhiteSpace(soundPath)) if (!string.IsNullOrWhiteSpace(soundPath))
@@ -101,14 +102,12 @@ namespace Barotrauma
sound = Sound.Load(soundPath); sound = Sound.Load(soundPath);
} }
Range = ToolBox.GetAttributeFloat(element, "range", 0.0f); Range = ToolBox.GetAttributeFloat(element, "range", 0.0f);
Duration = ToolBox.GetAttributeFloat(element, "duration", 0.0f);
Duration = ToolBox.GetAttributeFloat(element, "duration", 0.0f); priority = ToolBox.GetAttributeFloat(element, "priority", 1.0f);
priority = ToolBox.GetAttributeFloat(element, "priority", 1.0f);
statusEffects = new List<StatusEffect>(); statusEffects = new List<StatusEffect>();
foreach (XElement subElement in element.Elements()) foreach (XElement subElement in element.Elements())
{ {
switch (subElement.Name.ToString().ToLowerInvariant()) switch (subElement.Name.ToString().ToLowerInvariant())
+38 -29
View File
@@ -1719,7 +1719,9 @@ namespace Barotrauma
public virtual AttackResult AddDamage(IDamageable attacker, Vector2 worldPosition, Attack attack, float deltaTime, bool playSound = false) public virtual AttackResult AddDamage(IDamageable attacker, Vector2 worldPosition, Attack attack, float deltaTime, bool playSound = false)
{ {
var attackResult = AddDamage(worldPosition, attack.DamageType, attack.GetDamage(deltaTime), attack.GetBleedingDamage(deltaTime), attack.Stun, playSound, attack.TargetForce); Limb limbHit = null;
var attackResult = AddDamage(worldPosition, attack.DamageType, attack.GetDamage(deltaTime), attack.GetBleedingDamage(deltaTime), attack.Stun, playSound, attack.TargetForce, out limbHit);
if (limbHit == null) return new AttackResult();
var attackingCharacter = attacker as Character; var attackingCharacter = attacker as Character;
if (attackingCharacter != null && attackingCharacter.AIController == null) if (attackingCharacter != null && attackingCharacter.AIController == null)
@@ -1727,56 +1729,63 @@ namespace Barotrauma
GameServer.Log(Name + " attacked by " + attackingCharacter.Name+". Damage: "+attackResult.Damage+" Bleeding damage: "+attackResult.Bleeding, ServerLog.MessageType.Attack); GameServer.Log(Name + " attacked by " + attackingCharacter.Name+". Damage: "+attackResult.Damage+" Bleeding damage: "+attackResult.Bleeding, ServerLog.MessageType.Attack);
} }
if (GameMain.Client == null &&
health - attackResult.Damage <= minHealth && Rand.Range(0.0f, 1.0f) < attack.SeverLimbsProbability)
{
foreach (LimbJoint joint in AnimController.LimbJoints)
{
if (joint.CanBeSevered && (joint.LimbA == limbHit || joint.LimbB == limbHit))
{
AnimController.SeverLimbJoint(joint);
if (joint.LimbA == limbHit)
{
joint.LimbB.body.LinearVelocity += limbHit.LinearVelocity * 0.5f;
}
else
{
joint.LimbA.body.LinearVelocity += limbHit.LinearVelocity * 0.5f;
}
}
}
}
return attackResult; return attackResult;
} }
public AttackResult AddDamage(Vector2 worldPosition, DamageType damageType, float amount, float bleedingAmount, float stun, bool playSound, float attackForce = 0.0f) public AttackResult AddDamage(Vector2 worldPosition, DamageType damageType, float amount, float bleedingAmount, float stun, bool playSound, float attackForce = 0.0f)
{ {
Limb temp = null;
return AddDamage(worldPosition, damageType, amount, bleedingAmount, stun, playSound, attackForce, out temp);
}
public AttackResult AddDamage(Vector2 worldPosition, DamageType damageType, float amount, float bleedingAmount, float stun, bool playSound, float attackForce, out Limb hitLimb)
{
hitLimb = null;
if (Removed) return new AttackResult(); if (Removed) return new AttackResult();
SetStun(stun); SetStun(stun);
Limb closestLimb = null;
float closestDistance = 0.0f; float closestDistance = 0.0f;
foreach (Limb limb in AnimController.Limbs) foreach (Limb limb in AnimController.Limbs)
{ {
float distance = Vector2.Distance(worldPosition, limb.WorldPosition); float distance = Vector2.Distance(worldPosition, limb.WorldPosition);
if (closestLimb == null || distance < closestDistance) if (hitLimb == null || distance < closestDistance)
{ {
closestLimb = limb; hitLimb = limb;
closestDistance = distance; closestDistance = distance;
} }
} }
if (Math.Abs(attackForce) > 0.0f) if (Math.Abs(attackForce) > 0.0f)
{ {
closestLimb.body.ApplyForce((closestLimb.WorldPosition - worldPosition) * attackForce); Vector2 diff = hitLimb.WorldPosition - worldPosition;
if (diff == Vector2.Zero) diff = Rand.Vector(1.0f);
hitLimb.body.ApplyForce(Vector2.Normalize(diff) * attackForce, hitLimb.SimPosition + ConvertUnits.ToSimUnits(diff));
} }
AttackResult attackResult = closestLimb.AddDamage(worldPosition, damageType, amount, bleedingAmount, playSound); AttackResult attackResult = hitLimb.AddDamage(worldPosition, damageType, amount, bleedingAmount, playSound);
//sever joints connected to the limb if the character was killed
//with an attack stronger than 50% of the characters max health
//TODO: maybe add a "CanSever" option to attacks
if (health - attackResult.Damage <= minHealth && attackResult.Damage >= MaxHealth * 0.5f)
{
foreach (LimbJoint joint in AnimController.LimbJoints)
{
if (joint.CanBeSevered && (joint.LimbA == closestLimb || joint.LimbB == closestLimb))
{
AnimController.SeverLimbJoint(joint);
if (joint.LimbA == closestLimb)
{
joint.LimbB.body.LinearVelocity = closestLimb.LinearVelocity*0.5f;
}
else
{
joint.LimbA.body.LinearVelocity = closestLimb.LinearVelocity * 0.5f;
}
}
}
}
AddDamage(damageType == DamageType.Burn ? CauseOfDeath.Burn : causeOfDeath, attackResult.Damage, null); AddDamage(damageType == DamageType.Burn ? CauseOfDeath.Burn : causeOfDeath, attackResult.Damage, null);
+8 -14
View File
@@ -333,7 +333,7 @@ namespace Barotrauma
bool hitArmor = false; bool hitArmor = false;
float totalArmorValue = 0.0f; float totalArmorValue = 0.0f;
if (armorValue>0.0f && SectorHit(armorSector, position)) if (armorValue > 0.0f && SectorHit(armorSector, position))
{ {
hitArmor = true; hitArmor = true;
totalArmorValue += armorValue; totalArmorValue += armorValue;
@@ -349,7 +349,6 @@ namespace Barotrauma
} }
} }
if (hitArmor) if (hitArmor)
{ {
totalArmorValue = Math.Max(totalArmorValue, 0.0f); totalArmorValue = Math.Max(totalArmorValue, 0.0f);
@@ -364,24 +363,19 @@ namespace Barotrauma
SoundPlayer.PlayDamageSound(damageSoundType, amount, position); SoundPlayer.PlayDamageSound(damageSoundType, amount, position);
} }
float bloodAmount = hitArmor || bleedingAmount <= 0.0f ? 0 : (int)Math.Min((int)(amount * 2.0f), 20); float bloodParticleAmount = hitArmor || bleedingAmount <= 0.0f ? 0 : (int)Math.Min(amount / 5, 10);
float bloodParticleSize = MathHelper.Clamp(amount / 50.0f, 0.1f, 1.0f);
for (int i = 0; i < bloodAmount; i++) for (int i = 0; i < bloodParticleAmount; i++)
{ {
Vector2 particleVel = WorldPosition - position; var blood = GameMain.ParticleManager.CreateParticle(inWater ? "waterblood" : "blood", WorldPosition, Vector2.Zero, 0.0f, character.AnimController.CurrentHull);
if (particleVel != Vector2.Zero) particleVel = Vector2.Normalize(particleVel); if (blood != null)
GameMain.ParticleManager.CreateParticle("blood",
WorldPosition,
particleVel * Rand.Range(100.0f, 300.0f), 0.0f, character.AnimController.CurrentHull);
if (i < bloodAmount / 5)
{ {
GameMain.ParticleManager.CreateParticle("waterblood", WorldPosition, Rand.Vector(10), 0.0f, character.AnimController.CurrentHull); blood.Size *= bloodParticleSize;
} }
} }
damage += Math.Max(amount,bleedingAmount) / character.MaxHealth * 100.0f; damage += Math.Max(amount, bleedingAmount) / character.MaxHealth * 100.0f;
return new AttackResult(amount, bleedingAmount, hitArmor); return new AttackResult(amount, bleedingAmount, hitArmor);
} }
@@ -149,7 +149,7 @@ namespace Barotrauma.Items.Components
return false; return false;
} }
AttackResult attackResult = new AttackResult(0.0f, 0.0f); AttackResult attackResult = new AttackResult();
if (attack != null) if (attack != null)
{ {
var submarine = f2.Body.UserData as Submarine; var submarine = f2.Body.UserData as Submarine;
+22 -9
View File
@@ -81,7 +81,7 @@ namespace Barotrauma
if (force == 0.0f && attack.Stun == 0.0f && attack.GetDamage(1.0f) == 0.0f) return; if (force == 0.0f && attack.Stun == 0.0f && attack.GetDamage(1.0f) == 0.0f) return;
ApplyExplosionForces(worldPosition, attack.Range, force, attack.GetDamage(1.0f), attack.Stun); ApplyExplosionForces(worldPosition, attack, force);
if (flames && GameMain.Client == null) if (flames && GameMain.Client == null)
{ {
@@ -132,9 +132,9 @@ namespace Barotrauma
yield return CoroutineStatus.Success; yield return CoroutineStatus.Success;
} }
public static void ApplyExplosionForces(Vector2 worldPosition, float range, float force, float damage = 0.0f, float stun = 0.0f) public static void ApplyExplosionForces(Vector2 worldPosition, Attack attack, float force)
{ {
if (range <= 0.0f) return; if (attack.Range <= 0.0f) return;
foreach (Character c in Character.CharacterList) foreach (Character c in Character.CharacterList)
{ {
@@ -143,6 +143,7 @@ namespace Barotrauma
explosionPos = ConvertUnits.ToSimUnits(explosionPos); explosionPos = ConvertUnits.ToSimUnits(explosionPos);
bool wasDead = c.IsDead;
foreach (Limb limb in c.AnimController.Limbs) foreach (Limb limb in c.AnimController.Limbs)
{ {
float dist = Vector2.Distance(limb.WorldPosition, worldPosition); float dist = Vector2.Distance(limb.WorldPosition, worldPosition);
@@ -152,23 +153,35 @@ namespace Barotrauma
float limbRadius = Math.Max(Math.Max(limb.body.width * 0.5f, limb.body.height * 0.5f), limb.body.radius); float limbRadius = Math.Max(Math.Max(limb.body.width * 0.5f, limb.body.height * 0.5f), limb.body.radius);
dist = Math.Max(0.0f, dist - FarseerPhysics.ConvertUnits.ToDisplayUnits(limbRadius)); dist = Math.Max(0.0f, dist - FarseerPhysics.ConvertUnits.ToDisplayUnits(limbRadius));
if (dist > range) continue; if (dist > attack.Range) continue;
float distFactor = 1.0f - dist / range; float distFactor = 1.0f - dist / attack.Range;
//solid obstacles between the explosion and the limb reduce the effect of the explosion by 90% //solid obstacles between the explosion and the limb reduce the effect of the explosion by 90%
if (Submarine.CheckVisibility(limb.SimPosition, explosionPos) != null) distFactor *= 0.1f; if (Submarine.CheckVisibility(limb.SimPosition, explosionPos) != null) distFactor *= 0.1f;
c.AddDamage(limb.WorldPosition, DamageType.None, c.AddDamage(limb.WorldPosition, DamageType.None,
damage / c.AnimController.Limbs.Length * distFactor, 0.0f, stun * distFactor, false); attack.GetDamage(1.0f) / c.AnimController.Limbs.Length * distFactor,
attack.GetBleedingDamage(1.0f) / c.AnimController.Limbs.Length * distFactor,
attack.Stun * distFactor,
false);
if (limb.WorldPosition == worldPosition) continue; if (limb.WorldPosition != worldPosition && force > 0.0f)
if (force > 0.0f)
{ {
limb.body.ApplyLinearImpulse(Vector2.Normalize(limb.WorldPosition - worldPosition) * distFactor * force); limb.body.ApplyLinearImpulse(Vector2.Normalize(limb.WorldPosition - worldPosition) * distFactor * force);
} }
} }
if (!wasDead && c.IsDead)
{
foreach (LimbJoint joint in c.AnimController.LimbJoints)
{
if (Rand.Range(0.0f, 1.0f) < attack.SeverLimbsProbability)
{
c.AnimController.SeverLimbJoint(joint);
}
}
}
} }
} }