Beispiel #1
0
 void ICmpUpdatable.OnUpdate()
 {
     if (Path != null)
     {
         var heading = Path.GetHeading(GameObj.Transform.Pos);
         _rigidBody.ApplyWorldForce(PathfindaxMathF.Clamp(heading.Normalized * MovementSpeed, heading.Length));
     }
 }
 void ICmpUpdatable.OnUpdate()
 {
     if (_path != null)
     {
         var heading = _path.GetHeading(GameObj.Transform.Pos);
         _rigidBody.ApplyWorldForce(heading * MovementSpeed);
     }
 }
        void ICmpUpdatable.OnUpdate()
        {
            // Note: OnCollisionBegin will be called once per shape, not per object.
            // However, in this case we're interested in objects not shapes, so we'll
            // keep track of the shapes to make sense of which objects we're touching.
            foreach (GameObject obj in this.touchingObjects.Keys)
            {
                RigidBody body = obj.GetComponent <RigidBody>();

                // Apply a force at the position of the object
                Vector2 forceDirection = -Vector2.UnitY;
                Vector2 applyWorldPos  = obj.Transform.Pos.Xy;
                body.ApplyWorldForce(
                    forceDirection * 20.0f,
                    applyWorldPos);

                // Display a log to note that we did so
                VisualLogs.Default.DrawVector(new Vector3(applyWorldPos), forceDirection * 15.0f);
            }
        }
Beispiel #4
0
        void ICmpUpdatable.OnUpdate()
        {
            Transform     transform = this.GameObj.Transform;
            RigidBody     body      = this.GameObj.GetComponent <RigidBody>();
            ShipBlueprint blueprint = this.blueprint.Res;

            // Heal when damaged
            if (this.hitpoints < 1.0f)
            {
                this.hitpoints = MathF.Clamp(this.hitpoints + blueprint.HealRate * Time.SPFMult * Time.TimeMult / blueprint.MaxHitpoints, 0.0f, 1.0f);
            }

            // Apply force according to the desired thrust
            Vector2 actualVelocity      = body.LinearVelocity;
            Vector2 targetVelocity      = this.targetThrust * blueprint.MaxSpeed;
            Vector2 velocityDiff        = (targetVelocity - actualVelocity);
            float   sameDirectionFactor = Vector2.Dot(
                velocityDiff / MathF.Max(0.001f, velocityDiff.Length),
                this.targetThrust / MathF.Max(0.001f, this.targetThrust.Length));
            Vector2 thrusterActivity = this.targetThrust.Length * MathF.Max(sameDirectionFactor, 0.0f) * velocityDiff / MathF.Max(velocityDiff.Length, 1.0f);

            if (thrusterActivity.Length > 0.00001f)             // Don't wake physics without actually doing work
            {
                body.ApplyWorldForce(thrusterActivity * blueprint.ThrusterPower);
            }

            // Turn to the desired fire angle
            if (this.targetAngleRatio > 0.0f)
            {
                float shortestTurnDirection = MathF.TurnDir(transform.Angle, this.targetAngle);
                float shortestTurnLength    = MathF.CircularDist(transform.Angle, this.targetAngle);
                float turnDirection;
                float turnLength;
                if (MathF.Abs(body.AngularVelocity) > blueprint.MaxTurnSpeed * 0.25f)
                {
                    turnDirection = MathF.Sign(body.AngularVelocity);
                    turnLength    = (turnDirection == shortestTurnDirection) ? shortestTurnLength : (MathF.RadAngle360 - shortestTurnLength);
                }
                else
                {
                    turnDirection = shortestTurnDirection;
                    turnLength    = shortestTurnLength;
                }
                float turnSpeedRatio        = MathF.Min(turnLength * 0.25f, MathF.RadAngle30) / MathF.RadAngle30;
                float turnVelocity          = turnSpeedRatio * turnDirection * blueprint.MaxTurnSpeed * this.targetAngleRatio;
                float angularVelocityChange = (turnVelocity - body.AngularVelocity) * blueprint.TurnPower;
                if (MathF.Abs(angularVelocityChange) > 0.0000001f)                 // Don't wake physics without actually doing work
                {
                    body.AngularVelocity += angularVelocityChange * Time.TimeMult;
                }
            }

            // Weapon cooldown
            this.weaponTimer = MathF.Max(0.0f, this.weaponTimer - Time.MsPFMult * Time.TimeMult);

            // Play the owners special flight sound, when available
            if (this.owner != null && this.owner.FlightLoop != null)
            {
                SoundListener listener    = Scene.Current.FindComponent <SoundListener>();
                Vector3       listenerPos = listener.GameObj.Transform.Pos;

                // Determine the target panning manually, because we don't want a true 3D sound here (doppler, falloff, ...)
                float targetPanning;
                if (listenerPos.Xy == transform.Pos.Xy || Player.AlivePlayers.Count() <= 1)
                {
                    targetPanning = 0.0f;
                }
                else
                {
                    targetPanning = -Vector2.Dot(Vector2.UnitX, (listenerPos - transform.Pos).Xy.Normalized);
                }

                // Determine the target volume
                float targetVolume = MathF.Clamp(this.targetThrust.Length, 0.0f, 1.0f);

                // Clean up disposed flight loop
                if (this.flightLoop != null && this.flightLoop.Disposed)
                {
                    this.flightLoop = null;
                }

                // Start the flight loop when requested
                if (targetVolume > 0.0f && this.flightLoop == null)
                {
                    if ((int)Time.MainTimer.TotalMilliseconds % 2976 <= (int)Time.MsPFMult)
                    {
                        this.flightLoop        = DualityApp.Sound.PlaySound(this.owner.FlightLoop);
                        this.flightLoop.Looped = true;
                    }
                }

                // Configure existing flight loop
                if (this.flightLoop != null)
                {
                    this.flightLoop.Volume  += (targetVolume - this.flightLoop.Volume) * 0.05f * Time.TimeMult;
                    this.flightLoop.Panning += (targetPanning - this.flightLoop.Panning) * 0.05f * Time.TimeMult;
                }
            }

            // Display the damage effect when damaged
            if (this.hitpoints < 0.85f && blueprint.DamageEffect != null)
            {
                // Create a new damage effect instance, if not present yet
                if (this.damageEffect == null)
                {
                    GameObject damageObj = blueprint.DamageEffect.Res.Instantiate(transform.Pos);
                    damageObj.Parent = this.GameObj;

                    this.damageEffect = damageObj.GetComponent <ParticleEffect>();
                    if (this.damageEffect == null)
                    {
                        throw new NullReferenceException();
                    }
                }

                // Configure the damage effect
                foreach (ParticleEmitter emitter in this.damageEffect.Emitters)
                {
                    if (emitter == null)
                    {
                        continue;
                    }
                    emitter.BurstDelay = new Range(50.0f + this.hitpoints * 50.0f, 100.0f + this.hitpoints * 300.0f);
                    if (this.owner != null)
                    {
                        ColorHsva targetColor = this.owner.Color.ToHsva();
                        emitter.MinColor = new ColorHsva(targetColor.H, targetColor.S, emitter.MinColor.V, emitter.MinColor.A);
                        emitter.MaxColor = new ColorHsva(targetColor.H, targetColor.S, emitter.MaxColor.V, emitter.MaxColor.A);
                    }
                }
            }
            // Get rid of existing damage effects, if no longer needed
            else if (this.damageEffect != null)
            {
                // Stop emitting and dispose when empty
                foreach (ParticleEmitter emitter in this.damageEffect.Emitters)
                {
                    if (emitter == null)
                    {
                        continue;
                    }
                    emitter.BurstDelay = float.MaxValue;
                }
                this.damageEffect.DisposeWhenEmpty = true;
                this.damageEffect = null;
            }
        }