Example #1
0
        private void MakePredictionKillReal(RemoteBulletState state)
        {
            switch (state)
            {
            case RemoteBulletState.Dying_Explosion:
                Alive = false;
                break;

            case RemoteBulletState.Dying_ShrinkFast:
                AddEntityOperation(new BulletDelayedDieOperation(0.15f));
                break;

            case RemoteBulletState.Dying_ShrinkSlow:
                AddEntityOperation(new BulletDelayedDieOperation(0.35f));
                break;

            case RemoteBulletState.Dying_Fade:
                AddEntityOperation(new BulletDelayedDieOperation(0.05f));
                break;

            case RemoteBulletState.Dying_FadeSlow:
                AddEntityOperation(new BulletDelayedDieOperation(1f));
                break;

            case RemoteBulletState.Dying_Instant:
                Alive = false;
                break;

            case RemoteBulletState.Normal:
            default:
                SAMLog.Error("RBULL::EnumSwitch_MPKR", "Invalid value: " + state);
                break;
            }
        }
Example #2
0
        public void RemoteUpdate(RemoteBulletState state, float px, float py, Vector2 veloc, Fraction fraction, float scale, long seq, float sendertime)
        {
            if (Math.Abs(Scale - scale) > 0.01f)
            {
                SAMLog.Error("RBULL::CHANGE-SCALE", $"Remote changed scale from {Scale} to {scale} ");
            }
            if (fraction != Fraction)
            {
                SAMLog.Error("RBULL::CHANGE-FRAC", $"Remote changed fraction from {Fraction} to {fraction} ");
            }

            Scale    = scale;
            Fraction = fraction;

            var delta = GDOwner.LevelTime - sendertime;

            if (state == RemoteBulletState.Normal)
            {
                if (PredictionState == RemoteBulletState.Normal)
                {
                    // all good

                    BulletVelocity = veloc;
                    var newpos = new FPoint(px, py) + BulletVelocity * delta * GDOwner.GameSpeed;

                    ClientPredictionMiss = (newpos - BulletPosition).LengthSquared() > 1f;

                    BulletPosition = newpos;

                    LastRemotePosition         = new FPoint(px, py);
                    PhysicsBody.Position       = ConvertUnits2.ToSimUnits(BulletPosition);
                    PhysicsBody.LinearVelocity = ConvertUnits.ToSimUnits(veloc);
                    RemoteState = state;
                }
                else
                {
                    if (sendertime - DEATH_PREDICTION_TOLERANCE >= TimeOfPredictedDeath)
                    {
                        // prediction said we should be death - was wrong

                        SAMLog.Debug("Revert prediction-miss: (Revive wrongfully killed bullet)");                         // Well, I'm sorry ... I guess

                        AbortAllOperations(o => o.Name == BulletShrinkAndDieOperation.NAME);
                        AbortAllOperations(o => o.Name == BulletFadeAndDieOperation.NAME);
                        BulletAlpha      = 1f;
                        BulletExtraScale = 1f;

                        BulletVelocity = veloc;
                        BulletPosition = new FPoint(px, py) + BulletVelocity * delta * GDOwner.GameSpeed;

                        ClientPredictionMiss = true;

                        LastRemotePosition         = new FPoint(px, py);
                        PhysicsBody.Position       = ConvertUnits2.ToSimUnits(BulletPosition);
                        PhysicsBody.LinearVelocity = ConvertUnits.ToSimUnits(veloc);
                        RemoteState     = state;
                        PredictionState = state;
                    }
                    else
                    {
                        // we will (predictably) die in the future
                    }
                }
            }
            else
            {
                if (PredictionState != RemoteBulletState.Normal)
                {
                    if (state != PredictionState)
                    {
                        // Prediction was correct but death cause was wrong (wtf??)

                        AbortAllOperations(o => o.Name == BulletShrinkAndDieOperation.NAME);
                        AbortAllOperations(o => o.Name == BulletFadeAndDieOperation.NAME);
                        BulletAlpha      = 1f;
                        BulletExtraScale = 1f;


                        BulletPosition = new FPoint(px, py);
                        BulletVelocity = veloc;

                        LastRemotePosition         = BulletPosition;
                        PhysicsBody.Position       = ConvertUnits2.ToSimUnits(BulletPosition);
                        PhysicsBody.LinearVelocity = ConvertUnits.ToSimUnits(veloc);
                        RemoteState     = state;
                        PredictionState = state;

                        PredictKill(state, true);
                    }
                    else
                    {
                        // Prediction was right (lucky path)

                        BulletPosition = new FPoint(px, py);
                        BulletVelocity = veloc;

                        LastRemotePosition         = BulletPosition;
                        PhysicsBody.Position       = ConvertUnits2.ToSimUnits(BulletPosition);
                        PhysicsBody.LinearVelocity = ConvertUnits.ToSimUnits(veloc);
                        RemoteState = state;

                        MakePredictionKillReal(state);
                    }
                }
                else
                {
                    // dead but no death prediction

                    BulletPosition = new FPoint(px, py);
                    BulletVelocity = veloc;

                    LastRemotePosition         = BulletPosition;
                    PhysicsBody.Position       = ConvertUnits2.ToSimUnits(BulletPosition);
                    PhysicsBody.LinearVelocity = ConvertUnits.ToSimUnits(veloc);
                    RemoteState     = state;
                    PredictionState = state;

                    PredictKill(state, true);

                    MainGame.Inst.GDSound.PlayEffectCollision();
                }

                if (GDOwner.RemoteBulletMapping[BulletID] == this)
                {
                    GDOwner.RemoteBulletMapping[BulletID] = null;
                }
            }

            LastUpdateBigSeq = seq;
        }
Example #3
0
        private void PredictKill(RemoteBulletState prediction, bool killReal = false)
        {
            TimeOfPredictedDeath = GDOwner.LevelTime;
            PredictionState      = prediction;

            switch (prediction)
            {
            case RemoteBulletState.Dying_Explosion:

                if (MainGame.Inst.Profile.EffectsEnabled)
                {
                    for (int i = 0; i < 8; i++)
                    {
                        Manager.AddEntity(new BulletSplitter(Owner, this, (FlatAlign8)i));
                    }
                }

                if (killReal)
                {
                    Alive = false;
                }
                else
                {
                    BulletAlpha = 0f;
                }

                break;

            case RemoteBulletState.Dying_ShrinkFast:
                AddEntityOperation(new BulletShrinkAndDieOperation(0.15f, killReal));
                break;

            case RemoteBulletState.Dying_ShrinkSlow:
                AddEntityOperation(new BulletShrinkAndDieOperation(0.35f, killReal));
                break;

            case RemoteBulletState.Dying_Fade:
                AddEntityOperation(new BulletFadeAndDieOperation(0.05f, killReal));
                break;

            case RemoteBulletState.Dying_FadeSlow:
                AddEntityOperation(new BulletFadeAndDieOperation(1f, killReal));
                break;

            case RemoteBulletState.Dying_Instant:

                if (killReal)
                {
                    Alive = false;
                }
                else
                {
                    BulletAlpha = 0f;
                }

                break;

            case RemoteBulletState.Normal:
            default:
                SAMLog.Error("RBULL::EnumSwitch_PK", "Invalid value: " + prediction);
                break;
            }

            BulletVelocity             = Vector2.Zero;
            PhysicsBody.LinearVelocity = Vector2.Zero;
        }