private void ApplyForce(PhysicsBody body, float deltaTime)
        {
            float distFactor = 1.0f;

            if (ForceFalloff)
            {
                distFactor = 1.0f - ConvertUnits.ToDisplayUnits(Vector2.Distance(body.SimPosition, PhysicsBody.SimPosition)) / ColliderRadius;
                if (distFactor < 0.0f)
                {
                    return;
                }
            }

            switch (ForceMode)
            {
            case TriggerForceMode.Force:
                if (ForceVelocityLimit < 1000.0f)
                {
                    body.ApplyForce(Force * currentForceFluctuation * distFactor, ForceVelocityLimit);
                }
                else
                {
                    body.ApplyForce(Force * currentForceFluctuation * distFactor, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
                }
                break;

            case TriggerForceMode.Acceleration:
                if (ForceVelocityLimit < 1000.0f)
                {
                    body.ApplyForce(Force * body.Mass * currentForceFluctuation * distFactor, ForceVelocityLimit);
                }
                else
                {
                    body.ApplyForce(Force * body.Mass * currentForceFluctuation * distFactor, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
                }
                break;

            case TriggerForceMode.Impulse:
                if (ForceVelocityLimit < 1000.0f)
                {
                    body.ApplyLinearImpulse(Force * currentForceFluctuation * distFactor, maxVelocity: ForceVelocityLimit);
                }
                else
                {
                    body.ApplyLinearImpulse(Force * currentForceFluctuation * distFactor, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
                }
                break;

            case TriggerForceMode.LimitVelocity:
                float maxVel = ForceVelocityLimit * currentForceFluctuation * distFactor;
                if (body.LinearVelocity.LengthSquared() > maxVel * maxVel)
                {
                    body.ApplyForce(
                        Vector2.Normalize(-body.LinearVelocity) *
                        Force.Length() * body.Mass * currentForceFluctuation * distFactor,
                        maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
                }
                break;
            }
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        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.DamageRange)
            {
                if (AttackTimer >= attack.Duration && damageTarget != null)
                {
                    attack.DoDamage(character, damageTarget, WorldPosition, 1.0f, (SoundTimer <= 0.0f));

                    SoundTimer = SoundInterval;
                }
            }

            Vector2 diff = attackPosition - SimPosition;

            if (diff.LengthSquared() < 0.00001f)
            {
                return;
            }

            if (attack.ApplyForceOnLimbs != null)
            {
                foreach (int limbIndex in attack.ApplyForceOnLimbs)
                {
                    if (limbIndex < 0 || limbIndex >= character.AnimController.Limbs.Length)
                    {
                        continue;
                    }

                    Limb    limb     = character.AnimController.Limbs[limbIndex];
                    Vector2 forcePos = limb.pullJoint == null ? limb.body.SimPosition : limb.pullJoint.WorldAnchorA;
                    limb.body.ApplyLinearImpulse(
                        limb.Mass * attack.Force * Vector2.Normalize(attackPosition - SimPosition), forcePos);
                }
            }
            else
            {
                Vector2 forcePos = pullJoint == null ? body.SimPosition : pullJoint.WorldAnchorA;
                body.ApplyLinearImpulse(Mass * attack.Force *
                                        Vector2.Normalize(attackPosition - SimPosition), forcePos);
            }
        }
Beispiel #4
0
        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);

            bool wasHit = false;

            if (damageTarget != null)
            {
                switch (attack.HitDetectionType)
                {
                case HitDetection.Distance:
                    wasHit = dist < attack.DamageRange;
                    break;

                case HitDetection.Contact:
                    List <Body> targetBodies = new List <Body>();
                    if (damageTarget is Character)
                    {
                        Character targetCharacter = (Character)damageTarget;
                        foreach (Limb limb in targetCharacter.AnimController.Limbs)
                        {
                            if (!limb.IsSevered && limb.body?.FarseerBody != null)
                            {
                                targetBodies.Add(limb.body.FarseerBody);
                            }
                        }
                    }
                    else if (damageTarget is Structure)
                    {
                        Structure targetStructure = (Structure)damageTarget;

                        if (character.Submarine == null && targetStructure.Submarine != null)
                        {
                            targetBodies.Add(targetStructure.Submarine.PhysicsBody.FarseerBody);
                        }
                        else
                        {
                            targetBodies.AddRange(targetStructure.Bodies);
                        }
                    }
                    else if (damageTarget is Item)
                    {
                        Item targetItem = damageTarget as Item;
                        if (targetItem.body?.FarseerBody != null)
                        {
                            targetBodies.Add(targetItem.body.FarseerBody);
                        }
                    }

                    if (targetBodies != null)
                    {
                        ContactEdge contactEdge = body.FarseerBody.ContactList;
                        while (contactEdge != null)
                        {
                            if (contactEdge.Contact != null &&
                                contactEdge.Contact.IsTouching &&
                                targetBodies.Any(b => b == contactEdge.Contact.FixtureA?.Body || b == contactEdge.Contact.FixtureB?.Body))
                            {
                                wasHit = true;
                                break;
                            }

                            contactEdge = contactEdge.Next;
                        }
                    }
                    break;
                }
            }

            if (wasHit)
            {
                if (AttackTimer >= attack.Duration && damageTarget != null)
                {
                    attack.DoDamage(character, damageTarget, WorldPosition, 1.0f, (SoundTimer <= 0.0f));
                    SoundTimer = SoundInterval;
                }
            }

            Vector2 diff = attackPosition - SimPosition;

            if (diff.LengthSquared() < 0.00001f)
            {
                return;
            }

            if (attack.ApplyForceOnLimbs != null)
            {
                foreach (int limbIndex in attack.ApplyForceOnLimbs)
                {
                    if (limbIndex < 0 || limbIndex >= character.AnimController.Limbs.Length)
                    {
                        continue;
                    }

                    Limb    limb     = character.AnimController.Limbs[limbIndex];
                    Vector2 forcePos = limb.pullJoint == null ? limb.body.SimPosition : limb.pullJoint.WorldAnchorA;
                    limb.body.ApplyLinearImpulse(
                        limb.Mass * attack.Force * Vector2.Normalize(attackPosition - SimPosition), forcePos);
                }
            }
            else
            {
                Vector2 forcePos = pullJoint == null ? body.SimPosition : pullJoint.WorldAnchorA;
                body.ApplyLinearImpulse(Mass * attack.Force *
                                        Vector2.Normalize(attackPosition - SimPosition), forcePos);
            }
        }