/// <summary> /// Returns true if the attack successfully hit something. If the distance is not given, it will be calculated. /// </summary> public bool UpdateAttack(float deltaTime, Vector2 attackSimPos, IDamageable damageTarget, out AttackResult attackResult, float distance = -1, Limb targetLimb = null) { attackResult = default(AttackResult); float dist = distance > -1 ? distance : ConvertUnits.ToDisplayUnits(Vector2.Distance(SimPosition, attackSimPos)); bool wasRunning = attack.IsRunning; attack.UpdateAttackTimer(deltaTime); bool wasHit = false; Body structureBody = null; if (damageTarget != null) { switch (attack.HitDetectionType) { case HitDetection.Distance: if (dist < attack.DamageRange) { if (ignoredBodies == null) { ignoredBodies = character.AnimController.Limbs.Select(l => l.body.FarseerBody).ToList(); ignoredBodies.Add(character.AnimController.Collider.FarseerBody); } structureBody = Submarine.PickBody( SimPosition, attackSimPos, ignoredBodies, Physics.CollisionWall); if (damageTarget is Item) { // If the attack is aimed to an item and hits an item, it's successful. // Ignore blocking on items, because it causes cases where a Mudraptor cannot hit the hatch, for example. wasHit = true; } else if (damageTarget is Structure wall && structureBody != null && (structureBody.UserData is Structure || (structureBody.UserData is Submarine sub && sub == wall.Submarine))) { // If the attack is aimed to a structure (wall) and hits a structure or the sub, it's successful wasHit = true; } else { // If there is nothing between, the hit is successful wasHit = structureBody == null; } } break;
/// <summary> /// Returns true if the attack successfully hit something. If the distance is not given, it will be calculated. /// </summary> public bool UpdateAttack(float deltaTime, Vector2 attackSimPos, IDamageable damageTarget, out AttackResult attackResult, float distance = -1, Limb targetLimb = null) { attackResult = default(AttackResult); float dist = distance > -1 ? distance : ConvertUnits.ToDisplayUnits(Vector2.Distance(SimPosition, attackSimPos)); bool wasRunning = attack.IsRunning; attack.UpdateAttackTimer(deltaTime); bool wasHit = false; Body structureBody = null; if (damageTarget != null) { switch (attack.HitDetectionType) { case HitDetection.Distance: if (dist < attack.DamageRange) { structureBody = Submarine.PickBody(SimPosition, attackSimPos, collisionCategory: Physics.CollisionWall | Physics.CollisionLevel, allowInsideFixture: true); if (damageTarget is Item i && i.GetComponent <Items.Components.Door>() != null) { // If the attack is aimed to an item and hits an item, it's successful. // Ignore blocking checks on doors, because it causes cases where a Mudraptor cannot hit the hatch, for example. wasHit = true; } else if (damageTarget is Structure wall && structureBody != null && (structureBody.UserData is Structure || (structureBody.UserData is Submarine sub && sub == wall.Submarine))) { // If the attack is aimed to a structure (wall) and hits a structure or the sub, it's successful wasHit = true; } else { // If there is nothing between, the hit is successful wasHit = structureBody == null; } }