Limb attack refactoring (moved attack update logic from EnemyAIController to Limb, removed the Hit/PinchCW/PinchCCW attacktypes)

This commit is contained in:
Regalis
2016-08-26 20:38:28 +03:00
parent 712953cc9e
commit fda251898b
14 changed files with 127 additions and 148 deletions
@@ -218,24 +218,27 @@ namespace Barotrauma
}
//steeringManager.SteeringAvoid(deltaTime, 1.0f);
steeringManager.SteeringSeek(attackSimPosition);
Limb attackLimb = attackingLimb;
//check if any of the limbs is close enough to attack the target
if (attackingLimb == null)
{
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;
attackingLimb = limb;
break;
}
return;
}
UpdateLimbAttack(deltaTime, attackingLimb, attackSimPosition);
if (attackLimb != null)
{
steeringManager.SteeringSeek(attackSimPosition - (attackLimb.SimPosition - SimPosition));
if (attackingLimb != null) UpdateLimbAttack(deltaTime, attackingLimb, attackSimPosition);
}
}
private void UpdateCoolDown(Vector2 attackPosition, float deltaTime)
@@ -330,84 +333,15 @@ namespace Barotrauma
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)
{
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)
if (limb.AttackTimer >= limb.attack.Duration)
{
wallAttackPos = Vector2.Zero;
attackTimer = 0.0f;
if (Vector2.Distance(limb.SimPosition, attackPosition)<5.0) coolDownTimer = attackCoolDown;
limb.AttackTimer = 0.0f;
if (Vector2.Distance(limb.SimPosition, attackPosition)<5.0) coolDownTimer = attackCoolDown;
}
}
+32 -25
View File
@@ -2,6 +2,7 @@
using Barotrauma.Particles;
using System;
using System.Xml.Linq;
using System.Collections.Generic;
namespace Barotrauma
@@ -13,11 +14,6 @@ namespace Barotrauma
public enum DamageType { None, Blunt, Slash, Burn }
public enum AttackType
{
None, PinchCW, PinchCCW, Hit
}
struct AttackResult
{
public readonly float Damage;
@@ -36,8 +32,6 @@ namespace Barotrauma
class Attack
{
public readonly AttackType Type;
public readonly float Range;
public readonly float Duration;
@@ -47,8 +41,12 @@ namespace Barotrauma
private readonly float damage;
private readonly float bleedingDamage;
private readonly List<StatusEffect> statusEffects;
public readonly float Force;
public readonly float Torque;
public readonly float TargetForce;
private Sound sound;
@@ -74,23 +72,8 @@ namespace Barotrauma
return (Duration == 0.0f) ? structureDamage : structureDamage * deltaTime;
}
//public Attack(AttackType type, float range,)
//{
//}
public Attack(XElement element)
{
try
{
Type = (AttackType)Enum.Parse(typeof(AttackType), element.Attribute("type").Value, true);
}
catch
{
Type = AttackType.None;
}
try
{
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);
Force = ToolBox.GetAttributeFloat(element,"force", 0.0f);
TargetForce = ToolBox.GetAttributeFloat(element, "targetforce", 0.0f);
Torque = ToolBox.GetAttributeFloat(element, "torque", 0.0f);
Stun = ToolBox.GetAttributeFloat(element, "stun", 0.0f);
string soundPath = ToolBox.GetAttributeString(element, "sound", "");
@@ -123,10 +107,20 @@ namespace Barotrauma
priority = ToolBox.GetAttributeFloat(element, "priority", 1.0f);
statusEffects = new List<StatusEffect>();
foreach (XElement subElement in element.Elements())
{
if (subElement.Name.ToString().ToLowerInvariant() != "particleemitter") continue;
particleEmitterPrefab = new ParticleEmitterPrefab(subElement);
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "particleemitter":
particleEmitterPrefab = new ParticleEmitterPrefab(subElement);
break;
case "statuseffect":
statusEffects.Add(StatusEffect.Load(subElement));
break;
}
}
}
@@ -143,6 +137,19 @@ namespace Barotrauma
sound.Play(1.0f, 500.0f, worldPosition);
}
foreach (StatusEffect effect in statusEffects)
{
if (effect.Targets.HasFlag(StatusEffect.TargetType.This) && attacker is Character)
{
effect.Apply(ActionType.OnUse, deltaTime, (Character)attacker, (Character)attacker);
}
if (effect.Targets.HasFlag(StatusEffect.TargetType.Character) && target is Character)
{
effect.Apply(ActionType.OnUse, deltaTime, (Character)target, (Character)target);
}
}
return target.AddDamage(attacker, worldPosition, this, deltaTime, playSound);
}
+49 -9
View File
@@ -156,6 +156,8 @@ namespace Barotrauma
private float scale;
public float AttackTimer;
//public float Damage
//{
// get { return damage; }
@@ -223,6 +225,8 @@ namespace Barotrauma
refJointIndex = -1;
Vector2 pullJointPos = Vector2.Zero;
if (element.Attribute("type") != null)
{
try
@@ -236,25 +240,26 @@ namespace Barotrauma
}
Vector2 jointPos = ToolBox.GetAttributeVector2(element, "pullpos", Vector2.Zero) * scale;
jointPos = ConvertUnits.ToSimUnits(jointPos);
pullJointPos = ToolBox.GetAttributeVector2(element, "pullpos", Vector2.Zero) * scale;
pullJointPos = ConvertUnits.ToSimUnits(pullJointPos);
stepOffset = ToolBox.GetAttributeVector2(element, "stepoffset", Vector2.Zero) * scale;
stepOffset = ConvertUnits.ToSimUnits(stepOffset);
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
{
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);
//maxHealth = Math.Max(ToolBox.GetAttributeFloat(element, "health", 100.0f),1.0f);
@@ -484,6 +489,39 @@ 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;
if (dist < attack.Range * 0.5f)
{
AttackTimer += deltaTime;
body.ApplyTorque(Mass * character.AnimController.Dir * attack.Torque);
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)
{
@@ -492,7 +530,9 @@ namespace Barotrauma
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);
}
@@ -526,7 +566,7 @@ namespace Barotrauma
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;
@@ -173,20 +173,8 @@ namespace Barotrauma
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)
{
if (requiredItems == null) return true;