Пример #1
0
        void ICmpUpdatable.OnUpdate()
        {
            ParticleEffect effect = this.GameObj.GetComponent <ParticleEffect>();

            bool      isActive      = this.teamColor != ColorRgba.White;
            ColorHsva teamColorHsva = this.teamColor.ToHsva();

            foreach (ParticleEmitter emitter in effect.Emitters)
            {
                float spawnAlpha = 1.0f - MathF.Clamp(this.spawnTimer / 5.0f, 0.0f, 1.0f);
                float alpha      = 0.25f + 0.75f * (isActive ? spawnAlpha : 0.0f);
                emitter.MinColor = this.teamColor.WithAlpha(alpha).ToHsva();
                emitter.MaxColor = this.teamColor.WithAlpha(alpha).ToHsva();
            }

            this.spawnTimer -= Time.SPFMult * Time.TimeMult;
            if (this.spawnTimer <= 0.0f)
            {
                if (isActive)
                {
                    this.Spawn();
                }
                this.spawnTimer += this.spawnDelay;
            }
        }
Пример #2
0
        void ICmpCollisionListener.OnCollisionBegin(Component sender, CollisionEventArgs args)
        {
            Ship otherShip = args.CollideWith.GetComponent <Ship>();

            if (otherShip == null)
            {
                return;
            }
            if (args.CollideWith == this.owner)
            {
                return;
            }
            if (otherShip.TeamColor == this.TeamColor)
            {
                return;
            }

            ColorHsva  teamColorHsva = otherShip.TeamColor.ToHsva();
            GameObject obj           = this.hitEffect.Res.Instantiate();

            obj.Transform.Pos   = this.GameObj.Transform.Pos;
            obj.Transform.Angle = this.GameObj.Transform.Angle;
            foreach (ParticleEmitter emitter in obj.GetComponent <ParticleEffect>().Emitters)
            {
                emitter.BaseVel += this.GameObj.Transform.Vel;
                emitter.MinColor = emitter.MinColor.WithHue(MathF.Lerp(emitter.MinColor.H, teamColorHsva.H, teamColorHsva.S));
                emitter.MaxColor = emitter.MaxColor.WithHue(MathF.Lerp(emitter.MaxColor.H, teamColorHsva.H, teamColorHsva.S));
            }
            this.GameObj.ParentScene.AddObject(obj);
            CameraController.ApplyScreenShake(this.GameObj.Transform.Pos, 0.05f);

            otherShip.Hit(this);
            this.GameObj.DisposeLater();
        }
Пример #3
0
 /// <summary>
 /// Returns a component-wise random <see cref="ColorHsva"/>.
 /// </summary>
 /// <param name="r"></param>
 /// <param name="min"></param>
 /// <param name="max"></param>
 /// <returns></returns>
 public static ColorHsva NextColorHsva(this Random r, ColorHsva min, ColorHsva max)
 {
     return(new ColorHsva(
                r.NextFloat(min.H, max.H),
                r.NextFloat(min.S, max.S),
                r.NextFloat(min.V, max.V),
                r.NextFloat(min.A, max.A)));
 }
Пример #4
0
        protected override void OnEditedTypeChanged()
        {
            base.OnEditedTypeChanged();

            System.Drawing.Bitmap iconBitmap = this.EditedType.GetEditorImage() as System.Drawing.Bitmap;
            ColorHsva             avgClr     = iconBitmap != null?
                                               iconBitmap.GetAverageColor().ToHsva() :
                                                   Duality.Drawing.ColorHsva.TransparentWhite;

            if (avgClr.S <= 0.05f)
            {
                avgClr = new ColorHsva(
                    0.001f * (float)(this.EditedType.Name.GetHashCode() % 1000),
                    1.0f,
                    0.5f);
            }

            this.PropertyName = this.EditedType.GetTypeCSCodeName(true);
            this.HeaderIcon   = iconBitmap;
            this.HeaderColor  = ExtMethodsColor.ColorFromHSV(avgClr.H, 0.2f, 0.8f);
        }
Пример #5
0
        public void Explode()
        {
            if (this.Disposed)
            {
                return;
            }

            ColorHsva  teamColorHsva = this.teamColor.ToHsva();
            GameObject explosionObj  = this.explosionPrefab.Res.Instantiate(this.GameObj.Transform.Pos);

            foreach (ParticleEffect effect in explosionObj.GetComponentsDeep <ParticleEffect>())
            {
                foreach (ParticleEmitter emitter in effect.Emitters)
                {
                    emitter.MinColor = emitter.MinColor.WithHue(MathF.Lerp(emitter.MinColor.H, teamColorHsva.H, teamColorHsva.S));
                    emitter.MaxColor = emitter.MaxColor.WithHue(MathF.Lerp(emitter.MaxColor.H, teamColorHsva.H, teamColorHsva.S));
                }
            }
            this.GameObj.ParentScene.AddObject(explosionObj);
            this.GameObj.DisposeLater();
            CameraController.ApplyScreenShake(this.GameObj.Transform.Pos, 1.0f);

            if (this == this.GameObj.ParentScene.FindComponent <Player>().ControlTarget)
            {
                SoundInstance sound = DualityApp.Sound.PlaySound(this.explosionSound);
            }
            else
            {
                SoundInstance sound = DualityApp.Sound.PlaySound3D(this.explosionSound, this.GameObj.Transform.Pos);
                sound.Volume  = 0.75f;
                sound.Lowpass = 0.75f;
            }

            if (this.thrusterSoundInstance != null)
            {
                this.thrusterSoundInstance.FadeOut(0.5f);
                this.thrusterSoundInstance = null;
            }
        }
Пример #6
0
        protected override void OnEditedTypeChanged()
        {
            base.OnEditedTypeChanged();

            System.Drawing.Bitmap iconBitmap = this.EditedType.GetEditorImage() as System.Drawing.Bitmap;
            ColorHsva avgClr = iconBitmap != null ?
                iconBitmap.GetAverageColor().ToHsva() :
                Duality.Drawing.ColorHsva.TransparentWhite;
            if (avgClr.S <= 0.05f)
            {
                avgClr = new ColorHsva(
                    0.001f * (float)(this.EditedType.Name.GetHashCode() % 1000),
                    1.0f,
                    0.5f);
            }

            this.PropertyName = this.EditedType.GetTypeCSCodeName(true);
            this.HeaderIcon = iconBitmap;
            this.HeaderColor = ExtMethodsSystemDrawingColor.ColorFromHSV(avgClr.H, 0.2f, 0.8f);

            this.Hints &= ~HintFlags.HasButton;
            this.Hints &= ~HintFlags.ButtonEnabled;
        }
Пример #7
0
        protected override void OnEditedTypeChanged()
        {
            base.OnEditedTypeChanged();

            System.Drawing.Bitmap iconBitmap = CorePluginRegistry.GetTypeImage(this.EditedType) as System.Drawing.Bitmap;
            ColorHsva             avgClr     = iconBitmap != null?
                                               iconBitmap.GetAverageColor().ToHsva() :
                                                   Duality.ColorFormat.ColorHsva.TransparentWhite;

            if (avgClr.S <= 0.05f)
            {
                avgClr = new ColorHsva(
                    0.001f * (float)(this.EditedType.Name.GetHashCode() % 1000),
                    1.0f,
                    0.5f);
            }

            this.PropertyName = this.EditedType.GetTypeCSCodeName(true);
            this.HeaderIcon   = iconBitmap;
            this.HeaderColor  = ExtMethodsSystemDrawingColor.ColorFromHSV(avgClr.H, 0.2f, 0.8f);

            this.Hints &= ~HintFlags.HasButton;
            this.Hints &= ~HintFlags.ButtonEnabled;
        }
		protected override void OnEditedTypeChanged()
		{
			base.OnEditedTypeChanged();

			System.Drawing.Bitmap iconBitmap = CorePluginRegistry.RequestTypeImage(this.EditedType) as System.Drawing.Bitmap;
			ColorHsva avgClr = iconBitmap != null ? 
				iconBitmap.GetAverageColor().ToHsva() : 
				Duality.ColorFormat.ColorHsva.TransparentWhite;
			if (avgClr.S <= 0.05f)
			{
				avgClr = new ColorHsva(
					0.001f * (float)(this.EditedType.Name.GetHashCode() % 1000), 
					1.0f, 
					0.5f);
			}

			this.PropertyName = this.EditedType.GetTypeCSCodeName(true);
			this.HeaderIcon = iconBitmap;
			this.HeaderColor = ExtMethodsSystemDrawingColor.ColorFromHSV(avgClr.H, 0.2f, 0.8f);
		}
Пример #9
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;
            }
        }
Пример #10
0
        void ICmpCollisionListener.OnCollisionBegin(Component sender, CollisionEventArgs args)
        {
            RigidBodyCollisionEventArgs bodyArgs = args as RigidBodyCollisionEventArgs;

            if (bodyArgs == null)
            {
                return;
            }
            if (bodyArgs.OtherShape.IsSensor)
            {
                return;
            }

            // Did we collide with a ship? If it's the same that fired the bullet, ignore this
            Ship otherShip = args.CollideWith.GetComponent <Ship>();

            if (otherShip != null && otherShip.Owner == this.owner)
            {
                return;
            }

            // Get all the objet references we'll need
            RigidBody       otherBody = args.CollideWith.RigidBody;
            Transform       transform = this.GameObj.Transform;
            RigidBody       body      = this.GameObj.RigidBody;
            BulletBlueprint blueprint = this.blueprint.Res;

            // Okay, let's determine where *exactly* our bullet hit
            RayCastData firstHit;
            bool        hitAnything = RigidBody.RayCast(transform.Pos.Xy - body.LinearVelocity * 2, transform.Pos.Xy + body.LinearVelocity * 2, data =>
            {
                if (data.Shape.IsSensor)
                {
                    return(-1.0f);
                }
                return(data.Fraction);
            }, out firstHit);

            Vector3 hitPos;
            float   hitAngle;

            if (hitAnything)
            {
                hitPos   = new Vector3(firstHit.Pos, 0.0f);
                hitAngle = (-firstHit.Normal).Angle;
            }
            else
            {
                // Note that it is possible for the raycast to not hit anything,
                // because it is essentially a line, while our bullet is wider than zero.
                hitPos   = transform.Pos;
                hitAngle = transform.Angle;
            }

            // Push around whatever we've just hit and do damage, if it was a ship
            otherBody.ApplyWorldImpulse(body.LinearVelocity * MathF.Min(otherBody.Mass, blueprint.ImpactMass), transform.Pos.Xy);
            if (otherShip != null)
            {
                otherShip.DoDamage(blueprint.Damage);
            }

            // If we hit a part of the world, spawn the world hit effect
            if (otherShip == null && blueprint.HitWorldEffect != null)
            {
                GameObject effectObj = blueprint.HitWorldEffect.Res.Instantiate(hitPos, hitAngle);
                Scene.Current.AddObject(effectObj);
            }

            // Also spawn a generic hit effect in the color of the bullet
            if (blueprint.HitEffect != null)
            {
                GameObject     effectObj = blueprint.HitEffect.Res.Instantiate(hitPos, hitAngle);
                ParticleEffect effect    = effectObj.GetComponent <ParticleEffect>();
                if (effect != null && this.owner != null)
                {
                    ColorHsva color = this.owner.Color.ToHsva();
                    foreach (ParticleEmitter emitter in effect.Emitters)
                    {
                        emitter.MaxColor = emitter.MaxColor.WithSaturation(color.S).WithHue(color.H);
                        emitter.MinColor = emitter.MinColor.WithSaturation(color.S).WithHue(color.H);
                    }
                }
                Scene.Current.AddObject(effectObj);
            }

            // Play hit sounds
            if (blueprint.HitSound != null)
            {
                SoundInstance inst = DualityApp.Sound.PlaySound3D(blueprint.HitSound, hitPos);
                inst.Pitch = MathF.Rnd.NextFloat(0.95f, 1.05f);
            }
            HitSoundController otherHitSound = otherBody.GameObj.GetComponent <HitSoundController>();

            if (otherHitSound != null)
            {
                otherHitSound.NotifyHit(MathF.Rnd.NextFloat(0.75f, 1.0f));
            }

            // Delete the bullet
            this.GameObj.DisposeLater();
        }