示例#1
0
        // Chase_Update
        public static void Update()
        {
            // if can't see player, reset
            Vector3 forward, up, right;

            Mathlib.AngleVectors(ref Client.cl.viewangles, out forward, out right, out up);

            // calc exact destination
            _Dest   = Render.RefDef.vieworg - forward * _Back.Value - right * _Right.Value;
            _Dest.Z = Render.RefDef.vieworg.Z + _Up.Value;

            // find the spot the player is looking at
            Vector3 dest = Render.RefDef.vieworg + forward * 4096;

            Vector3 stop;

            TraceLine(ref Render.RefDef.vieworg, ref dest, out stop);

            // calculate pitch to look at the same spot from camera
            stop -= Render.RefDef.vieworg;
            float dist;

            Vector3.Dot(ref stop, ref forward, out dist);
            if (dist < 1)
            {
                dist = 1;
            }

            Render.RefDef.viewangles.X = (float)(-Math.Atan(stop.Z / dist) / Math.PI * 180.0);
            //r_refdef.viewangles[PITCH] = -atan(stop[2] / dist) / M_PI * 180;

            // move towards destination
            Render.RefDef.vieworg = _Dest; //VectorCopy(chase_dest, r_refdef.vieworg);
        }
示例#2
0
        /*
         * ==============
         * PF_makevectors
         *
         * Writes new values for v_forward, v_up, and v_right based on angles
         * makevectors(vector)
         * ==============
         */
        static unsafe void PF_makevectors()
        {
            float * av = GetVector(OFS.OFS_PARM0);
            Vector3 a = new Vector3(av[0], av[1], av[2]);
            Vector3 fw, right, up;

            Mathlib.AngleVectors(ref a, out fw, out right, out up);
            Mathlib.Copy(ref fw, out Progs.GlobalStruct.v_forward);
            Mathlib.Copy(ref right, out Progs.GlobalStruct.v_right);
            Mathlib.Copy(ref up, out Progs.GlobalStruct.v_up);
        }
示例#3
0
        /// <summary>
        /// SV_AirMove
        /// </summary>
        static void AirMove()
        {
            Vector3 pangles = Common.ToVector(ref _Player.v.angles);

            Mathlib.AngleVectors(ref pangles, out _Forward, out _Right, out _Up);

            float fmove = _Cmd.forwardmove;
            float smove = _Cmd.sidemove;

            // hack to not let you back into teleporter
            if (sv.time < _Player.v.teleport_time && fmove < 0)
            {
                fmove = 0;
            }

            Vector3 wishvel = _Forward * fmove + _Right * smove;

            if ((int)_Player.v.movetype != Movetypes.MOVETYPE_WALK)
            {
                wishvel.Z = _Cmd.upmove;
            }
            else
            {
                wishvel.Z = 0;
            }

            _WishDir   = wishvel;
            _WishSpeed = Mathlib.Normalize(ref _WishDir);
            if (_WishSpeed > _MaxSpeed.Value)
            {
                wishvel   *= _MaxSpeed.Value / _WishSpeed;
                _WishSpeed = _MaxSpeed.Value;
            }

            if (_Player.v.movetype == Movetypes.MOVETYPE_NOCLIP)
            {
                // noclip
                Mathlib.Copy(ref wishvel, out _Player.v.velocity);
            }
            else if (_OnGround)
            {
                UserFriction();
                Accelerate();
            }
            else
            {   // not on ground, so little effect on velocity
                AirAccelerate(wishvel);
            }
        }
示例#4
0
        /// <summary>
        /// V_CalcRoll
        /// Used by view and sv_user
        /// </summary>
        public static float CalcRoll(ref Vector3 angles, ref Vector3 velocity)
        {
            Mathlib.AngleVectors(ref angles, out _Forward, out _Right, out _Up);
            float side = Vector3.Dot(velocity, _Right);
            float sign = side < 0 ? -1 : 1;

            side = Math.Abs(side);

            float value = _ClRollAngle.Value;

            if (side < _ClRollSpeed.Value)
            {
                side = side * value / _ClRollSpeed.Value;
            }
            else
            {
                side = value;
            }

            return(side * sign);
        }
示例#5
0
        /// <summary>
        /// SV_WallFriction
        /// </summary>
        static void WallFriction(edict_t ent, trace_t trace)
        {
            Vector3 forward, right, up, vangle = Common.ToVector(ref ent.v.v_angle);

            Mathlib.AngleVectors(ref vangle, out forward, out right, out up);
            float d = Vector3.Dot(trace.plane.normal, forward);

            d += 0.5f;
            if (d >= 0)
            {
                return;
            }

            // cut the tangential velocity
            Vector3 vel  = Common.ToVector(ref ent.v.velocity);
            float   i    = Vector3.Dot(trace.plane.normal, vel);
            Vector3 into = trace.plane.normal * i;
            Vector3 side = vel - into;

            ent.v.velocity.x = side.X * (1 + d);
            ent.v.velocity.y = side.Y * (1 + d);
        }
示例#6
0
        // V_ParseDamage
        public static void ParseDamage()
        {
            int     armor = Net.Reader.ReadByte();
            int     blood = Net.Reader.ReadByte();
            Vector3 from  = Net.Reader.ReadCoords();

            float count = blood * 0.5f + armor * 0.5f;

            if (count < 10)
            {
                count = 10;
            }

            client_state_t cl = Client.cl;

            cl.faceanimtime = (float)cl.time + 0.2f; // put sbar face into pain frame

            cl.cshifts[ColorShift.CSHIFT_DAMAGE].percent += (int)(3 * count);
            if (cl.cshifts[ColorShift.CSHIFT_DAMAGE].percent < 0)
            {
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].percent = 0;
            }
            if (cl.cshifts[ColorShift.CSHIFT_DAMAGE].percent > 150)
            {
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].percent = 150;
            }

            if (armor > blood)
            {
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].destcolor[0] = 200;
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].destcolor[1] = 100;
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].destcolor[2] = 100;
            }
            else if (armor != 0)
            {
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].destcolor[0] = 220;
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].destcolor[1] = 50;
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].destcolor[2] = 50;
            }
            else
            {
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].destcolor[0] = 255;
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].destcolor[1] = 0;
                cl.cshifts[ColorShift.CSHIFT_DAMAGE].destcolor[2] = 0;
            }

            //
            // calculate view angle kicks
            //
            entity_t ent = Client.Entities[cl.viewentity];

            from -= ent.origin; //  VectorSubtract (from, ent->origin, from);
            Mathlib.Normalize(ref from);

            Vector3 forward, right, up;

            Mathlib.AngleVectors(ref ent.angles, out forward, out right, out up);

            float side = Vector3.Dot(from, right);

            _DmgRoll = count * side * _KickRoll.Value;

            side      = Vector3.Dot(from, forward);
            _DmgPitch = count * side * _KickPitch.Value;

            _DmgTime = _KickTime.Value;
        }
示例#7
0
        // V_CalcRefdef
        static void CalcRefDef()
        {
            DriftPitch();

            // ent is the player model (visible when out of body)
            entity_t ent = Client.ViewEntity;
            // view is the weapon model (only visible from inside body)
            entity_t view = Client.ViewEnt;

            // transform the view offset by the model's matrix to get the offset from
            // model origin for the view
            ent.angles.Y = Client.cl.viewangles.Y;      // the model should face the view dir
            ent.angles.X = -Client.cl.viewangles.X;     // the model should face the view dir

            float bob = CalcBob();

            refdef_t       rdef = Render.RefDef;
            client_state_t cl   = Client.cl;

            // refresh position
            rdef.vieworg    = ent.origin;
            rdef.vieworg.Z += cl.viewheight + bob;

            // never let it sit exactly on a node line, because a water plane can
            // dissapear when viewed with the eye exactly on it.
            // the server protocol only specifies to 1/16 pixel, so add 1/32 in each axis
            rdef.vieworg   += SmallOffset;
            rdef.viewangles = cl.viewangles;

            CalcViewRoll();
            AddIdle(_IdleScale.Value);

            // offsets
            Vector3 angles = ent.angles;

            angles.X = -angles.X; // because entity pitches are actually backward

            Vector3 forward, right, up;

            Mathlib.AngleVectors(ref angles, out forward, out right, out up);

            rdef.vieworg += forward * _ScrOfsX.Value + right * _ScrOfsY.Value + up * _ScrOfsZ.Value;

            BoundOffsets();

            // set up gun position
            view.angles = cl.viewangles;

            CalcGunAngle();

            view.origin    = ent.origin;
            view.origin.Z += cl.viewheight;
            view.origin   += forward * bob * 0.4f;
            view.origin.Z += bob;

            // fudge position around to keep amount of weapon visible
            // roughly equal with different FOV
            float viewSize = Scr.ViewSize.Value; // scr_viewsize

            if (viewSize == 110)
            {
                view.origin.Z += 1;
            }
            else if (viewSize == 100)
            {
                view.origin.Z += 2;
            }
            else if (viewSize == 90)
            {
                view.origin.Z += 1;
            }
            else if (viewSize == 80)
            {
                view.origin.Z += 0.5f;
            }

            view.model    = cl.model_precache[cl.stats[QStats.STAT_WEAPON]];
            view.frame    = cl.stats[QStats.STAT_WEAPONFRAME];
            view.colormap = Scr.vid.colormap;

            // set up the refresh position
            rdef.viewangles += cl.punchangle;

            // smooth out stair step ups
            if (cl.onground && ent.origin.Z - _OldZ > 0)
            {
                float steptime = (float)(cl.time - cl.oldtime);
                if (steptime < 0)
                {
                    steptime = 0;
                }

                _OldZ += steptime * 80;
                if (_OldZ > ent.origin.Z)
                {
                    _OldZ = ent.origin.Z;
                }
                if (ent.origin.Z - _OldZ > 12)
                {
                    _OldZ = ent.origin.Z - 12;
                }
                rdef.vieworg.Z += _OldZ - ent.origin.Z;
                view.origin.Z  += _OldZ - ent.origin.Z;
            }
            else
            {
                _OldZ = ent.origin.Z;
            }

            if (Chase.IsActive)
            {
                Chase.Update();
            }
        }
示例#8
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++;
                }
            }
        }
示例#9
0
        /// <summary>
        /// R_DrawBrushModel
        /// </summary>
        private static void DrawBrushModel(entity_t e)
        {
            _CurrentEntity        = e;
            Drawer.CurrentTexture = -1;

            model_t clmodel = e.model;
            bool    rotated = false;
            Vector3 mins, maxs;

            if (e.angles.X != 0 || e.angles.Y != 0 || e.angles.Z != 0)
            {
                rotated = true;
                mins    = e.origin;
                mins.X -= clmodel.radius;
                mins.Y -= clmodel.radius;
                mins.Z -= clmodel.radius;
                maxs    = e.origin;
                maxs.X += clmodel.radius;
                maxs.Y += clmodel.radius;
                maxs.Z += clmodel.radius;
            }
            else
            {
                mins = e.origin + clmodel.mins;
                maxs = e.origin + clmodel.maxs;
            }

            if (CullBox(ref mins, ref maxs))
            {
                return;
            }

            GL.Color3(1f, 1, 1);
            Array.Clear(_LightMapPolys, 0, _LightMapPolys.Length);
            _ModelOrg = _RefDef.vieworg - e.origin;
            if (rotated)
            {
                Vector3 temp = _ModelOrg;
                Vector3 forward, right, up;
                Mathlib.AngleVectors(ref e.angles, out forward, out right, out up);
                _ModelOrg.X = Vector3.Dot(temp, forward);
                _ModelOrg.Y = -Vector3.Dot(temp, right);
                _ModelOrg.Z = Vector3.Dot(temp, up);
            }

            // calculate dynamic lighting for bmodel if it's not an
            // instanced model
            if (clmodel.firstmodelsurface != 0 && _glFlashBlend.Value == 0)
            {
                for (int k = 0; k < Client.MAX_DLIGHTS; k++)
                {
                    if ((Client.DLights[k].die < Client.cl.time) || (Client.DLights[k].radius == 0))
                    {
                        continue;
                    }

                    MarkLights(Client.DLights[k], 1 << k, clmodel.nodes[clmodel.hulls[0].firstclipnode]);
                }
            }

            GL.PushMatrix();
            e.angles.X = -e.angles.X;   // stupid quake bug
            RotateForEntity(e);
            e.angles.X = -e.angles.X;   // stupid quake bug

            int surfOffset = clmodel.firstmodelsurface;

            msurface_t[] psurf = clmodel.surfaces; //[clmodel.firstmodelsurface];

            //
            // draw texture
            //
            for (int i = 0; i < clmodel.nummodelsurfaces; i++, surfOffset++)
            {
                // find which side of the node we are on
                mplane_t pplane = psurf[surfOffset].plane;

                float dot = Vector3.Dot(_ModelOrg, pplane.normal) - pplane.dist;

                // draw the polygon
                bool planeBack = (psurf[surfOffset].flags & Surf.SURF_PLANEBACK) != 0;
                if ((planeBack && (dot < -QDef.BACKFACE_EPSILON)) || (!planeBack && (dot > QDef.BACKFACE_EPSILON)))
                {
                    if (_glTexSort.Value != 0)
                    {
                        RenderBrushPoly(psurf[surfOffset]);
                    }
                    else
                    {
                        DrawSequentialPoly(psurf[surfOffset]);
                    }
                }
            }

            BlendLightmaps();

            GL.PopMatrix();
        }
示例#10
0
        /// <summary>
        /// SV_WaterMove
        /// </summary>
        static void WaterMove()
        {
            //
            // user intentions
            //
            Vector3 pangle = Common.ToVector(ref _Player.v.v_angle);

            Mathlib.AngleVectors(ref pangle, out _Forward, out _Right, out _Up);
            Vector3 wishvel = _Forward * _Cmd.forwardmove + _Right * _Cmd.sidemove;

            if (_Cmd.forwardmove == 0 && _Cmd.sidemove == 0 && _Cmd.upmove == 0)
            {
                wishvel.Z -= 60;                // drift towards bottom
            }
            else
            {
                wishvel.Z += _Cmd.upmove;
            }

            float wishspeed = wishvel.Length;

            if (wishspeed > _MaxSpeed.Value)
            {
                wishvel  *= _MaxSpeed.Value / wishspeed;
                wishspeed = _MaxSpeed.Value;
            }
            wishspeed *= 0.7f;

            //
            // water friction
            //
            float newspeed, speed = Mathlib.Length(ref _Player.v.velocity);

            if (speed != 0)
            {
                newspeed = (float)(speed - Host.FrameTime * speed * _Friction.Value);
                if (newspeed < 0)
                {
                    newspeed = 0;
                }
                Mathlib.VectorScale(ref _Player.v.velocity, newspeed / speed, out _Player.v.velocity);
            }
            else
            {
                newspeed = 0;
            }

            //
            // water acceleration
            //
            if (wishspeed == 0)
            {
                return;
            }

            float addspeed = wishspeed - newspeed;

            if (addspeed <= 0)
            {
                return;
            }

            Mathlib.Normalize(ref wishvel);
            float accelspeed = (float)(_Accelerate.Value * wishspeed * Host.FrameTime);

            if (accelspeed > addspeed)
            {
                accelspeed = addspeed;
            }

            wishvel *= accelspeed;
            _Player.v.velocity.x += wishvel.X;
            _Player.v.velocity.y += wishvel.Y;
            _Player.v.velocity.z += wishvel.Z;
        }