Exemplo n.º 1
0
        public override void Update(float deltaTime, Camera cam)
        {
            UpdateProjSpecific(deltaTime, cam);

            Oxygen -= OxygenDetoriationSpeed * deltaTime;

            FireSource.UpdateAll(fireSources, deltaTime);

            aiTarget.SightRange  = Submarine == null ? 0.0f : Math.Max(Submarine.Velocity.Length() * 500.0f, 500.0f);
            aiTarget.SoundRange -= deltaTime * 1000.0f;

            //update client hulls if the amount of water has changed by >10%
            //or if oxygen percentage has changed by 5%
            if (Math.Abs(lastSentVolume - waterVolume) > Volume * 0.1f ||
                Math.Abs(lastSentOxygen - OxygenPercentage) > 5f)
            {
                if (GameMain.Server != null && !IdFreed)
                {
                    sendUpdateTimer -= deltaTime;
                    if (sendUpdateTimer < 0.0f)
                    {
                        GameMain.Server.CreateEntityEvent(this);
                        lastSentVolume  = waterVolume;
                        lastSentOxygen  = OxygenPercentage;
                        sendUpdateTimer = NetworkUpdateInterval;
                    }
                }
            }

            if (!update)
            {
                lethalPressure = 0.0f;
                return;
            }

            float surfaceY = rect.Y - rect.Height + WaterVolume / rect.Width;

            for (int i = 0; i < waveY.Length; i++)
            {
                waveY[i] = waveY[i] + waveVel[i];

                if (surfaceY + waveY[i] > rect.Y)
                {
                    waveY[i]  -= (surfaceY + waveY[i]) - rect.Y;
                    waveVel[i] = waveVel[i] * -0.5f;
                }
                else if (surfaceY + waveY[i] < rect.Y - rect.Height)
                {
                    waveY[i]  -= (surfaceY + waveY[i]) - (rect.Y - rect.Height);
                    waveVel[i] = waveVel[i] * -0.5f;
                }

                //acceleration
                float a = -WaveStiffness * waveY[i] - waveVel[i] * WaveDampening;
                waveVel[i] = waveVel[i] + a;
            }

            for (int j = 0; j < 2; j++)
            {
                for (int i = 1; i < waveY.Length - 1; i++)
                {
                    leftDelta[i]   = WaveSpread * (waveY[i] - waveY[i - 1]);
                    waveVel[i - 1] = waveVel[i - 1] + leftDelta[i];

                    rightDelta[i]  = WaveSpread * (waveY[i] - waveY[i + 1]);
                    waveVel[i + 1] = waveVel[i + 1] + rightDelta[i];
                }

                for (int i = 1; i < waveY.Length - 1; i++)
                {
                    waveY[i - 1] = waveY[i - 1] + leftDelta[i];
                    waveY[i + 1] = waveY[i + 1] + rightDelta[i];
                }
            }

            //interpolate the position of the rendered surface towards the "target surface"
            surface = Math.Max(MathHelper.Lerp(surface, surfaceY, deltaTime * 10.0f), rect.Y - rect.Height);

            if (waterVolume < Volume)
            {
                LethalPressure -= 10.0f * deltaTime;
                if (WaterVolume <= 0.0f)
                {
                    //wait for the surface to be lerped back to bottom and the waves to settle until disabling update
                    if (surface > rect.Y - rect.Height + 1)
                    {
                        return;
                    }
                    for (int i = 1; i < waveY.Length - 1; i++)
                    {
                        if (waveY[i] > 0.1f)
                        {
                            return;
                        }
                    }

                    update = false;
                }
            }
        }
Exemplo n.º 2
0
        public override void Update(Camera cam, float deltaTime)
        {
            Oxygen -= OxygenDetoriationSpeed * deltaTime;

            if (EditWater)
            {
                Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
                if (Submarine.RectContains(WorldRect, position))
                {
                    if (PlayerInput.LeftButtonHeld())
                    {
                        //waveY[GetWaveIndex(position.X - rect.X - Submarine.Position.X) / WaveWidth] = 100.0f;
                        Volume = Volume + 1500.0f;
                    }
                    else if (PlayerInput.RightButtonHeld())
                    {
                        Volume = Volume - 1500.0f;
                    }
                }
            }
            else if (EditFire)
            {
                Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
                if (Submarine.RectContains(WorldRect, position))
                {
                    if (PlayerInput.LeftButtonClicked())
                    {
                        new FireSource(position, this);
                    }
                }
            }

            FireSource.UpdateAll(fireSources, deltaTime);

            aiTarget.SightRange  = Submarine == null ? 0.0f : Math.Max(Submarine.Velocity.Length() * 500.0f, 500.0f);
            aiTarget.SoundRange -= deltaTime * 1000.0f;

            float strongestFlow = 0.0f;

            foreach (Gap gap in ConnectedGaps)
            {
                if (gap.IsRoomToRoom)
                {
                    //only the first linked hull plays the flow sound
                    if (gap.linkedTo[1] == this)
                    {
                        continue;
                    }
                }

                float gapFlow = gap.LerpedFlowForce.Length();

                if (gapFlow > strongestFlow)
                {
                    strongestFlow = gapFlow;
                }
            }

            if (strongestFlow > 1.0f)
            {
                soundVolume = soundVolume + ((strongestFlow < 100.0f) ? -deltaTime * 0.5f : deltaTime * 0.5f);
                soundVolume = MathHelper.Clamp(soundVolume, 0.0f, 1.0f);

                int index = (int)Math.Floor(strongestFlow / 100.0f);
                index = Math.Min(index, 2);

                var flowSound = SoundPlayer.flowSounds[index];
                if (flowSound != currentFlowSound && soundIndex > -1)
                {
                    Sounds.SoundManager.Stop(soundIndex);
                    currentFlowSound = null;
                    soundIndex       = -1;
                }

                currentFlowSound = flowSound;
                soundIndex       = currentFlowSound.Loop(soundIndex, soundVolume, WorldPosition, Math.Min(strongestFlow * 5.0f, 2000.0f));
            }
            else
            {
                if (soundIndex > -1)
                {
                    Sounds.SoundManager.Stop(soundIndex);
                    currentFlowSound = null;
                    soundIndex       = -1;
                }
            }

            //update client hulls if the amount of water has changed by >10%
            //or if oxygen percentage has changed by 5%
            if (Math.Abs(lastSentVolume - volume) > FullVolume * 0.1f ||
                Math.Abs(lastSentOxygen - OxygenPercentage) > 5f)
            {
                if (GameMain.Server != null)
                {
                    sendUpdateTimer -= deltaTime;
                    if (sendUpdateTimer < 0.0f)
                    {
                        GameMain.Server.CreateEntityEvent(this);
                        lastSentVolume  = volume;
                        lastSentOxygen  = OxygenPercentage;
                        sendUpdateTimer = NetworkUpdateInterval;
                    }
                }
            }

            if (!update)
            {
                lethalPressure = 0.0f;
                return;
            }


            float surfaceY = rect.Y - rect.Height + Volume / rect.Width;

            for (int i = 0; i < waveY.Length; i++)
            {
                float maxDelta = Math.Max(Math.Abs(rightDelta[i]), Math.Abs(leftDelta[i]));
                if (maxDelta > Rand.Range(1.0f, 10.0f))
                {
                    var particlePos = new Vector2(rect.X + WaveWidth * i, surface + waveY[i]);
                    if (Submarine != null)
                    {
                        particlePos += Submarine.Position;
                    }

                    GameMain.ParticleManager.CreateParticle("mist",
                                                            particlePos,
                                                            new Vector2(0.0f, -50.0f), 0.0f, this);
                }

                waveY[i] = waveY[i] + waveVel[i];

                if (surfaceY + waveY[i] > rect.Y)
                {
                    waveY[i]  -= (surfaceY + waveY[i]) - rect.Y;
                    waveVel[i] = waveVel[i] * -0.5f;
                }
                else if (surfaceY + waveY[i] < rect.Y - rect.Height)
                {
                    waveY[i]  -= (surfaceY + waveY[i]) - (rect.Y - rect.Height);
                    waveVel[i] = waveVel[i] * -0.5f;
                }

                //acceleration
                float a = -WaveStiffness * waveY[i] - waveVel[i] * WaveDampening;
                waveVel[i] = waveVel[i] + a;
            }

            for (int j = 0; j < 2; j++)
            {
                for (int i = 1; i < waveY.Length - 1; i++)
                {
                    leftDelta[i]   = WaveSpread * (waveY[i] - waveY[i - 1]);
                    waveVel[i - 1] = waveVel[i - 1] + leftDelta[i];

                    rightDelta[i]  = WaveSpread * (waveY[i] - waveY[i + 1]);
                    waveVel[i + 1] = waveVel[i + 1] + rightDelta[i];
                }

                for (int i = 1; i < waveY.Length - 1; i++)
                {
                    waveY[i - 1] = waveY[i - 1] + leftDelta[i];
                    waveY[i + 1] = waveY[i + 1] + rightDelta[i];
                }
            }

            //interpolate the position of the rendered surface towards the "target surface"
            surface = Math.Max(MathHelper.Lerp(surface, surfaceY, deltaTime * 10.0f), rect.Y - rect.Height);

            if (volume < FullVolume)
            {
                LethalPressure -= 10.0f * deltaTime;
                if (Volume == 0.0f)
                {
                    //wait for the surface to be lerped back to bottom and the waves to settle until disabling update
                    if (surface > rect.Y - rect.Height + 1)
                    {
                        return;
                    }
                    for (int i = 1; i < waveY.Length - 1; i++)
                    {
                        if (waveY[i] > 0.1f)
                        {
                            return;
                        }
                    }

                    update = false;
                }
            }
        }
Exemplo n.º 3
0
        public override void Update(float deltaTime, Camera cam)
        {
            UpdateProjSpecific(deltaTime, cam);

            Oxygen -= OxygenDeteriorationSpeed * deltaTime;

            FireSource.UpdateAll(FireSources, deltaTime);

            aiTarget.SightRange  = Submarine == null ? 0.0f : Math.Max(Submarine.Velocity.Length() * 2000.0f, AITarget.StaticSightRange);
            aiTarget.SoundRange -= deltaTime * 1000.0f;

            if (!update)
            {
                lethalPressure = 0.0f;
                return;
            }

            surface = Math.Max(MathHelper.Lerp(
                                   surface,
                                   rect.Y - rect.Height + WaterVolume / rect.Width,
                                   deltaTime * 10.0f), rect.Y - rect.Height);
            //interpolate the position of the rendered surface towards the "target surface"
            drawSurface = Math.Max(MathHelper.Lerp(
                                       drawSurface,
                                       rect.Y - rect.Height + WaterVolume / rect.Width,
                                       deltaTime * 10.0f), rect.Y - rect.Height);

            for (int i = 0; i < waveY.Length; i++)
            {
                //apply velocity
                waveY[i] = waveY[i] + waveVel[i];

                //if the wave attempts to go "through" the top of the hull, make it bounce back
                if (surface + waveY[i] > rect.Y)
                {
                    float excess = (surface + waveY[i]) - rect.Y;
                    waveY[i]  -= excess;
                    waveVel[i] = waveVel[i] * -0.5f;
                }
                //if the wave attempts to go "through" the bottom of the hull, make it bounce back
                else if (surface + waveY[i] < rect.Y - rect.Height)
                {
                    float excess = (surface + waveY[i]) - (rect.Y - rect.Height);
                    waveY[i]  -= excess;
                    waveVel[i] = waveVel[i] * -0.5f;
                }

                //acceleration
                float a = -WaveStiffness * waveY[i] - waveVel[i] * WaveDampening;
                waveVel[i] = waveVel[i] + a;
            }

            //apply spread (two iterations)
            for (int j = 0; j < 2; j++)
            {
                for (int i = 1; i < waveY.Length - 1; i++)
                {
                    leftDelta[i]    = WaveSpread * (waveY[i] - waveY[i - 1]);
                    waveVel[i - 1] += leftDelta[i];

                    rightDelta[i]   = WaveSpread * (waveY[i] - waveY[i + 1]);
                    waveVel[i + 1] += rightDelta[i];
                }

                for (int i = 1; i < waveY.Length - 1; i++)
                {
                    waveY[i - 1] += leftDelta[i];
                    waveY[i + 1] += rightDelta[i];
                }
            }

            //make waves propagate through horizontal gaps
            foreach (Gap gap in ConnectedGaps)
            {
                if (!gap.IsRoomToRoom || !gap.IsHorizontal || gap.Open <= 0.0f)
                {
                    continue;
                }
                if (surface > gap.Rect.Y || surface < gap.Rect.Y - gap.Rect.Height)
                {
                    continue;
                }

                Hull  hull2         = this == gap.linkedTo[0] as Hull ? (Hull)gap.linkedTo[1] : (Hull)gap.linkedTo[0];
                float otherSurfaceY = hull2.surface;
                if (otherSurfaceY > gap.Rect.Y || otherSurfaceY < gap.Rect.Y - gap.Rect.Height)
                {
                    continue;
                }

                float surfaceDiff = (surface - otherSurfaceY) * gap.Open;
                if (this != gap.linkedTo[0] as Hull)
                {
                    //the first hull linked to the gap handles the wave propagation,
                    //the second just updates the surfaces to the same level
                    if (surfaceDiff < 32.0f)
                    {
                        hull2.waveY[hull2.waveY.Length - 1] = surfaceDiff * 0.5f;
                        waveY[0] = -surfaceDiff * 0.5f;
                    }
                    continue;
                }

                for (int j = 0; j < 2; j++)
                {
                    int i = waveY.Length - 1;

                    leftDelta[i]    = WaveSpread * (waveY[i] - waveY[i - 1]);
                    waveVel[i - 1] += leftDelta[i];

                    rightDelta[i]     = WaveSpread * (waveY[i] - hull2.waveY[0] + surfaceDiff);
                    hull2.waveVel[0] += rightDelta[i];

                    i = 0;

                    hull2.leftDelta[i]           = WaveSpread * (hull2.waveY[i] - waveY[waveY.Length - 1] - surfaceDiff);
                    waveVel[waveVel.Length - 1] += hull2.leftDelta[i];

                    hull2.rightDelta[i]   = WaveSpread * (hull2.waveY[i] - hull2.waveY[i + 1]);
                    hull2.waveVel[i + 1] += hull2.rightDelta[i];
                }

                if (surfaceDiff < 32.0f)
                {
                    //update surfaces to the same level
                    hull2.waveY[0]          = surfaceDiff * 0.5f;
                    waveY[waveY.Length - 1] = -surfaceDiff * 0.5f;
                }
                else
                {
                    hull2.waveY[0]          += rightDelta[waveY.Length - 1];
                    waveY[waveY.Length - 1] += hull2.leftDelta[0];
                }
            }

            if (waterVolume < Volume)
            {
                LethalPressure -= 10.0f * deltaTime;
                if (WaterVolume <= 0.0f)
                {
                    //wait for the surface to be lerped back to bottom and the waves to settle until disabling update
                    if (drawSurface > rect.Y - rect.Height + 1)
                    {
                        return;
                    }
                    for (int i = 1; i < waveY.Length - 1; i++)
                    {
                        if (waveY[i] > 0.1f)
                        {
                            return;
                        }
                    }

                    update = false;
                }
            }
        }
Exemplo n.º 4
0
        public override void Update(float deltaTime, Camera cam)
        {
            base.Update(deltaTime, cam);
            UpdateProjSpecific(deltaTime, cam);

            Oxygen -= OxygenDeteriorationSpeed * deltaTime;

            FireSource.UpdateAll(FireSources, deltaTime);

            if (aiTarget != null)
            {
                aiTarget.SightRange  = Submarine == null ? aiTarget.MinSightRange : Submarine.Velocity.Length() / 2 * aiTarget.MaxSightRange;
                aiTarget.SoundRange -= deltaTime * 1000.0f;
            }

            if (!update)
            {
                lethalPressure = 0.0f;
                return;
            }

            float waterDepth = WaterVolume / rect.Width;

            if (waterDepth < 1.0f)
            {
                //if there's only a minuscule amount of water, consider the surface to be at the bottom of the hull
                //otherwise unnoticeable amounts of water can for example cause magnesium to explode
                waterDepth = 0.0f;
            }

            surface = Math.Max(MathHelper.Lerp(
                                   surface,
                                   rect.Y - rect.Height + waterDepth,
                                   deltaTime * 10.0f), rect.Y - rect.Height);
            //interpolate the position of the rendered surface towards the "target surface"
            drawSurface = Math.Max(MathHelper.Lerp(
                                       drawSurface,
                                       rect.Y - rect.Height + waterDepth,
                                       deltaTime * 10.0f), rect.Y - rect.Height);

            for (int i = 0; i < waveY.Length; i++)
            {
                //apply velocity
                waveY[i] = waveY[i] + waveVel[i];

                //if the wave attempts to go "through" the top of the hull, make it bounce back
                if (surface + waveY[i] > rect.Y)
                {
                    float excess = (surface + waveY[i]) - rect.Y;
                    waveY[i]  -= excess;
                    waveVel[i] = waveVel[i] * -0.5f;
                }
                //if the wave attempts to go "through" the bottom of the hull, make it bounce back
                else if (surface + waveY[i] < rect.Y - rect.Height)
                {
                    float excess = (surface + waveY[i]) - (rect.Y - rect.Height);
                    waveY[i]  -= excess;
                    waveVel[i] = waveVel[i] * -0.5f;
                }

                //acceleration
                float a = -WaveStiffness * waveY[i] - waveVel[i] * WaveDampening;
                waveVel[i] = waveVel[i] + a;
            }

            //apply spread (two iterations)
            for (int j = 0; j < 2; j++)
            {
                for (int i = 1; i < waveY.Length - 1; i++)
                {
                    leftDelta[i]    = WaveSpread * (waveY[i] - waveY[i - 1]);
                    waveVel[i - 1] += leftDelta[i];

                    rightDelta[i]   = WaveSpread * (waveY[i] - waveY[i + 1]);
                    waveVel[i + 1] += rightDelta[i];
                }
            }

            //make waves propagate through horizontal gaps
            foreach (Gap gap in ConnectedGaps)
            {
                if (this != gap.linkedTo[0] as Hull)
                {
                    //let the first linked hull handle the water propagation
                    continue;
                }

                if (!gap.IsRoomToRoom || !gap.IsHorizontal || gap.Open <= 0.0f)
                {
                    continue;
                }
                if (surface > gap.Rect.Y || surface < gap.Rect.Y - gap.Rect.Height)
                {
                    continue;
                }

                // ReSharper refuses to compile this if it's using "as Hull" since "as" means it can be null and you can't compare null to true or false
                Hull  hull2         = this == gap.linkedTo[0] ? (Hull)gap.linkedTo[1] : (Hull)gap.linkedTo[0];
                float otherSurfaceY = hull2.surface;
                if (otherSurfaceY > gap.Rect.Y || otherSurfaceY < gap.Rect.Y - gap.Rect.Height)
                {
                    continue;
                }

                float surfaceDiff = (surface - otherSurfaceY) * gap.Open;
                for (int j = 0; j < 2; j++)
                {
                    rightDelta[waveY.Length - 1] = WaveSpread * (hull2.waveY[0] - waveY[waveY.Length - 1] - surfaceDiff) * 0.5f;
                    waveVel[waveY.Length - 1]   += rightDelta[waveY.Length - 1];
                    waveY[waveY.Length - 1]     += rightDelta[waveY.Length - 1];

                    hull2.leftDelta[0] = WaveSpread * (waveY[waveY.Length - 1] - hull2.waveY[0] + surfaceDiff) * 0.5f;
                    hull2.waveVel[0]  += hull2.leftDelta[0];
                    hull2.waveY[0]    += hull2.leftDelta[0];
                }

                if (surfaceDiff < 32.0f)
                {
                    //update surfaces to the same level
                    hull2.waveY[0]          = surfaceDiff * 0.5f;
                    waveY[waveY.Length - 1] = -surfaceDiff * 0.5f;
                }
            }


            //apply spread (two iterations)
            for (int j = 0; j < 2; j++)
            {
                for (int i = 1; i < waveY.Length - 1; i++)
                {
                    waveY[i - 1] += leftDelta[i];
                    waveY[i + 1] += rightDelta[i];
                }
            }

            if (waterVolume < Volume)
            {
                LethalPressure -= 10.0f * deltaTime;
                if (WaterVolume <= 0.0f)
                {
                    //wait for the surface to be lerped back to bottom and the waves to settle until disabling update
                    if (drawSurface > rect.Y - rect.Height + 1)
                    {
                        return;
                    }
                    for (int i = 1; i < waveY.Length - 1; i++)
                    {
                        if (waveY[i] > 0.1f)
                        {
                            return;
                        }
                    }

                    update = false;
                }
            }
        }