示例#1
0
    public static void R_SetupFrame()
    {
        // don't allow cheats in multiplayer
        if (cl.maxclients > 1)
        {
            Cvar.Cvar_Set("r_fullbright", "0");
        }

        R_AnimateLight();

        r_framecount++;

        // build the transformation matrix for the given view angles
        r_origin = r_refdef.vieworg;

        Mathlib.AngleVectors(ref r_refdef.viewangles, out vpn, out vright, out vup);

        // current viewleaf
        r_oldviewleaf = r_viewleaf;
        r_viewleaf    = Mod_PointInLeaf(ref r_origin, cl.worldmodel);

        game_engine.V_SetContentsColor(r_viewleaf.contents);
        game_engine.V_CalcBlend();

        r_cache_thrash = false;
        c_brush_polys  = 0;
        c_alias_polys  = 0;
    }
示例#2
0
    public static void Chase_Update()
    {
        // if can't see player, reset
        Vector3 forward, up, right;

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

        // calc exact destination
        chase_dest   = r_refdef.vieworg - forward * chase_back.value - right * chase_right.value;
        chase_dest.Z = r_refdef.vieworg.Z + chase_up.value;

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

        Vector3 stop;

        TraceLine(ref r_refdef.vieworg, ref dest, out stop);

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

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

        r_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
        r_refdef.vieworg = chase_dest; //VectorCopy(chase_dest, r_refdef.vieworg);
    }
示例#3
0
    static unsafe void PF_makevectors()
    {
        float * av = G_VECTOR(q_shared.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 pr_global_struct.v_forward);
        Mathlib.Copy(ref right, out pr_global_struct.v_right);
        Mathlib.Copy(ref up, out pr_global_struct.v_up);
    }
示例#4
0
    public static void R_DrawSpriteModel(entity_t e)
    {
        // don't even bother culling, because it's just a single
        // polygon without a surface cache
        mspriteframe_t frame   = R_GetSpriteFrame(e);
        msprite_t      psprite = (msprite_t)e.model.cache.data;

        Vector3 v_forward, right, up;

        if (psprite.type == q_shared.SPR_ORIENTED)
        {
            // bullet marks on walls
            Mathlib.AngleVectors(ref e.angles, out v_forward, out right, out up); // Uze: changed from _CurrentEntity to e
        }
        else
        {                   // normal sprite
            up    = vup;    // vup;
            right = vright; // vright;
        }

        GL.Color3(1f, 1, 1);

        GL_DisableMultitexture();

        GL_Bind(frame.gl_texturenum);

        GL.Enable(EnableCap.AlphaTest);
        GL.Begin(BeginMode.Quads);

        GL.TexCoord2(0f, 1);
        Vector3 point = e.origin + up * frame.down + right * frame.left;

        GL.Vertex3(point);

        GL.TexCoord2(0f, 0);
        point = e.origin + up * frame.up + right * frame.left;
        GL.Vertex3(point);

        GL.TexCoord2(1f, 0);
        point = e.origin + up * frame.up + right * frame.right;
        GL.Vertex3(point);

        GL.TexCoord2(1f, 1);
        point = e.origin + up * frame.down + right * frame.right;
        GL.Vertex3(point);

        GL.End();
        GL.Disable(EnableCap.AlphaTest);
    }
示例#5
0
    public static void SV_AirMove()
    {
        Vector3 pangles = ToVector(ref sv_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 < sv_player.v.teleport_time && fmove < 0)
        {
            fmove = 0;
        }

        Vector3 wishvel = forward * fmove + right * smove;

        if ((int)sv_player.v.movetype != q_shared.MOVETYPE_WALK)
        {
            wishvel.Z = cmd.upmove;
        }
        else
        {
            wishvel.Z = 0;
        }

        wishdir   = wishvel;
        wishspeed = Mathlib.Normalize(ref wishdir);
        if (wishspeed > sv_maxspeed.value)
        {
            wishvel  *= sv_maxspeed.value / wishspeed;
            wishspeed = sv_maxspeed.value;
        }

        if (sv_player.v.movetype == q_shared.MOVETYPE_NOCLIP)
        {
            // noclip
            Mathlib.Copy(ref wishvel, out sv_player.v.velocity);
        }
        else if (onground)
        {
            SV_UserFriction();
            SV_Accelerate();
        }
        else
        {   // not on ground, so little effect on velocity
            SV_AirAccelerate(wishvel);
        }
    }
示例#6
0
    public static float V_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 = cl_rollangle.value;

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

        return(side * sign);
    }
示例#7
0
    public static void SV_WallFriction(edict_t ent, trace_t trace)
    {
        Vector3 forward, right, up, vangle = 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  = 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);
    }
示例#8
0
    public static void V_ParseDamage()
    {
        int     armor = Reader.MSG_ReadByte();
        int     blood = Reader.MSG_ReadByte();
        Vector3 from  = Reader.ReadCoords();

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

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

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

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

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

        //
        // calculate view angle kicks
        //
        entity_t ent = cl_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);

        v_dmg_roll = count * side * v_kickroll.value;

        side        = Vector3.Dot(from, forward);
        v_dmg_pitch = count * side * v_kickpitch.value;

        v_dmg_time = v_kicktime.value;
    }
示例#9
0
    static void V_CalcRefdef()
    {
        V_DriftPitch();

        // ent is the player model (visible when out of body)
        entity_t ent = cl_entities[cl.viewentity];
        // view is the weapon model (only visible from inside body)
        entity_t view = cl.viewent;

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

        float bob = V_CalcBob();

        refdef_t rdef = r_refdef;

        // 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   += q_shared.SmallOffset;
        rdef.viewangles = cl.viewangles;

        V_CalcViewRoll();
        V_AddIdle(v_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 * scr_ofsx.value + right * scr_ofsy.value + up * scr_ofsz.value;

        V_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[q_shared.STAT_WEAPON]];
        view.frame    = cl.stats[q_shared.STAT_WEAPONFRAME];
        view.colormap = 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_active.value != 0)
        {
            Chase_Update();
        }
    }
示例#10
0
    public static void R_DrawBrushModel(entity_t e)
    {
        currententity  = e;
        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 (R_CullBox(ref mins, ref maxs))
        {
            return;
        }

        GL.Color3(1f, 1, 1);
        Array.Clear(lightmap_polys, 0, lightmap_polys.Length);
        modelorg = r_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 && gl_flashblend.value == 0)
        {
            for (int k = 0; k < q_shared.MAX_DLIGHTS; k++)
            {
                if ((cl_dlights[k].die < cl.time) || (cl_dlights[k].radius == 0))
                {
                    continue;
                }

                R_MarkLights(cl_dlights[k], 1 << k, clmodel.nodes[clmodel.hulls[0].firstclipnode]);
            }
        }

        GL.PushMatrix();
        e.angles.X = -e.angles.X;       // stupid quake bug
        R_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 & q_shared.SURF_PLANEBACK) != 0;
            if ((planeBack && (dot < -q_shared.BACKFACE_EPSILON)) || (!planeBack && (dot > q_shared.BACKFACE_EPSILON)))
            {
                if (gl_texsort.value != 0)
                {
                    R_RenderBrushPoly(psurf[surfOffset]);
                }
                else
                {
                    R_DrawSequentialPoly(psurf[surfOffset]);
                }
            }
        }

        R_BlendLightmaps();

        GL.PopMatrix();
    }
示例#11
0
    public static void SV_WaterMove()
    {
        //
        // user intentions
        //
        Vector3 pangle = ToVector(ref sv_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 > sv_maxspeed.value)
        {
            wishvel  *= sv_maxspeed.value / wishspeed;
            wishspeed = sv_maxspeed.value;
        }
        wishspeed *= 0.7f;

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

        if (speed != 0)
        {
            newspeed = (float)(speed - host_framtime * speed * sv_friction.value);
            if (newspeed < 0)
            {
                newspeed = 0;
            }
            Mathlib.VectorScale(ref sv_player.v.velocity, newspeed / speed, out sv_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)(sv_accelerate.value * wishspeed * host_framtime);

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

        wishvel *= accelspeed;
        sv_player.v.velocity.x += wishvel.X;
        sv_player.v.velocity.y += wishvel.Y;
        sv_player.v.velocity.z += wishvel.Z;
    }
示例#12
0
    public static void CL_RelinkEntities()
    {
        // determine partial update time
        float frac = CL_LerpPoint();

        cl_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 = cl_entities[i];
            if (ent.model == null)
            {
                // empty slot
                if (ent.forcelink)
                {
                    R_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;
                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
                }
                // 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 & q_shared.EF_ROTATE) != 0)
            {
                ent.angles.Y = bobjrotate;
            }

            if ((ent.effects & q_shared.EF_BRIGHTFIELD) != 0)
            {
                R_EntityParticles(ent);
            }

            if ((ent.effects & q_shared.EF_MUZZLEFLASH) != 0)
            {
                dlight_t dl = CL_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 + (Random() & 31);
                dl.minlight = 32;
                dl.die      = (float)cl.time + 0.1f;
            }
            if ((ent.effects & q_shared.EF_BRIGHTLIGHT) != 0)
            {
                dlight_t dl = CL_AllocDlight(i);
                dl.origin    = ent.origin;
                dl.origin.Z += 16;
                dl.radius    = 400 + (Random() & 31);
                dl.die       = (float)cl.time + 0.001f;
            }
            if ((ent.effects & q_shared.EF_DIMLIGHT) != 0)
            {
                dlight_t dl = CL_AllocDlight(i);
                dl.origin = ent.origin;
                dl.radius = 200 + (Random() & 31);
                dl.die    = (float)cl.time + 0.001f;
            }

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

            ent.forcelink = false;

            if (i == cl.viewentity && chase_active.value == 0)
            {
                continue;
            }

            if (cl_numvisedicts < q_shared.MAX_VISEDICTS)
            {
                cl_visedicts[cl_numvisedicts] = ent;
                cl_numvisedicts++;
            }
        }
    }