Пример #1
0
        /// <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;
Пример #2
0
        /// <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;
                        }
                    }