示例#1
0
        /// <summary>
        /// CL_RelinkEntities
        /// </summary>
        static void RelinkEntities()
        {
            // determine partial update time
            float frac = LerpPoint();

            NumVisEdicts = 0;

            //
            // interpolate player info
            //
            cl.velocity = cl.mvelocity[1] + frac * (cl.mvelocity[0] - cl.mvelocity[1]);

            if (cls.demoplayback)
            {
                // interpolate the angles
                Vector3 angleDelta = cl.mviewangles[0] - cl.mviewangles[1];
                Mathlib.CorrectAngles180(ref angleDelta);
                cl.viewangles = cl.mviewangles[1] + frac * angleDelta;
            }

            float bobjrotate = Mathlib.AngleMod(100 * cl.time);

            // start on the entity after the world
            for (int i = 1; i < cl.num_entities; i++)
            {
                entity_t ent = _Entities[i];
                if (ent.model == null)
                {
                    // empty slot
                    if (ent.forcelink)
                    {
                        Render.RemoveEfrags(ent);       // just became empty
                    }
                    continue;
                }

                // if the object wasn't included in the last packet, remove it
                if (ent.msgtime != cl.mtime[0])
                {
                    ent.model              = null;
                    ent.FrameStartTime     = 0;
                    ent.TranslateStartTime = 0;
                    ent.RotateStartTime    = 0;
                    continue;
                }

                Vector3 oldorg = ent.origin;

                if (ent.forcelink)
                {
                    // the entity was not updated in the last message
                    // so move to the final spot
                    ent.origin = ent.msg_origins[0];
                    ent.angles = ent.msg_angles[0];
                }
                else
                {
                    // if the delta is large, assume a teleport and don't lerp
                    float   f     = frac;
                    Vector3 delta = ent.msg_origins[0] - ent.msg_origins[1];
                    if (Math.Abs(delta.X) > 100 || Math.Abs(delta.Y) > 100 || Math.Abs(delta.Z) > 100)
                    {
                        f = 1; // assume a teleportation, not a motion
                    }
                    // [email protected]: model transform interpolation
                    // interpolation should be reset in the event of a large delta
                    if (f >= 1)
                    {
                        ent.FrameStartTime     = 0;
                        ent.TranslateStartTime = 0;
                        ent.RotateStartTime    = 0;
                    }

                    // interpolate the origin and angles
                    ent.origin = ent.msg_origins[1] + f * delta;
                    Vector3 angleDelta = ent.msg_angles[0] - ent.msg_angles[1];
                    Mathlib.CorrectAngles180(ref angleDelta);
                    ent.angles = ent.msg_angles[1] + f * angleDelta;
                }

                // rotate binary objects locally
                if ((ent.model.flags & EF.EF_ROTATE) != 0)
                {
                    ent.angles.Y = bobjrotate;
                }

                if ((ent.effects & EntityEffects.EF_BRIGHTFIELD) != 0)
                {
                    Render.EntityParticles(ent);
                }

                if ((ent.effects & EntityEffects.EF_MUZZLEFLASH) != 0)
                {
                    dlight_t dl = AllocDlight(i);
                    dl.origin    = ent.origin;
                    dl.origin.Z += 16;
                    Vector3 fv, rv, uv;
                    Mathlib.AngleVectors(ref ent.angles, out fv, out rv, out uv);
                    dl.origin  += fv * 18;
                    dl.radius   = 200 + (Sys.Random() & 31);
                    dl.minlight = 32;
                    dl.die      = (float)cl.time + 0.1f;
                }
                if ((ent.effects & EntityEffects.EF_BRIGHTLIGHT) != 0)
                {
                    dlight_t dl = AllocDlight(i);
                    dl.origin    = ent.origin;
                    dl.origin.Z += 16;
                    dl.radius    = 400 + (Sys.Random() & 31);
                    dl.die       = (float)cl.time + 0.001f;
                }
                if ((ent.effects & EntityEffects.EF_DIMLIGHT) != 0)
                {
                    dlight_t dl = AllocDlight(i);
                    dl.origin = ent.origin;
                    dl.radius = 200 + (Sys.Random() & 31);
                    dl.die    = (float)cl.time + 0.001f;
                }

                if ((ent.model.flags & EF.EF_GIB) != 0)
                {
                    Render.RocketTrail(ref oldorg, ref ent.origin, 2);
                }
                else if ((ent.model.flags & EF.EF_ZOMGIB) != 0)
                {
                    Render.RocketTrail(ref oldorg, ref ent.origin, 4);
                }
                else if ((ent.model.flags & EF.EF_TRACER) != 0)
                {
                    Render.RocketTrail(ref oldorg, ref ent.origin, 3);
                }
                else if ((ent.model.flags & EF.EF_TRACER2) != 0)
                {
                    Render.RocketTrail(ref oldorg, ref ent.origin, 5);
                }
                else if ((ent.model.flags & EF.EF_ROCKET) != 0)
                {
                    Render.RocketTrail(ref oldorg, ref ent.origin, 0);
                    dlight_t dl = AllocDlight(i);
                    dl.origin = ent.origin;
                    dl.radius = 200;
                    dl.die    = (float)cl.time + 0.01f;
                }
                else if ((ent.model.flags & EF.EF_GRENADE) != 0)
                {
                    Render.RocketTrail(ref oldorg, ref ent.origin, 1);
                }
                else if ((ent.model.flags & EF.EF_TRACER3) != 0)
                {
                    Render.RocketTrail(ref oldorg, ref ent.origin, 6);
                }

                ent.forcelink = false;

                if (i == cl.viewentity && !Chase.IsActive)
                {
                    continue;
                }

                if (NumVisEdicts < MAX_VISEDICTS)
                {
                    _VisEdicts[NumVisEdicts] = ent;
                    NumVisEdicts++;
                }
            }
        }