Пример #1
0
    static unsafe void PF_traceline()
    {
        float * v1         = G_VECTOR(q_shared.OFS_PARM0);
        float * v2         = G_VECTOR(q_shared.OFS_PARM1);
        int     nomonsters = (int)G_FLOAT(q_shared.OFS_PARM2);
        edict_t ent        = G_EDICT(q_shared.OFS_PARM3);

        Vector3 vec1, vec2;

        Copy(v1, out vec1);
        Copy(v2, out vec2);
        trace_t trace = SV_Move(ref vec1, ref q_shared.ZeroVector, ref q_shared.ZeroVector, ref vec2, nomonsters, ent);

        pr_global_struct.trace_allsolid   = trace.allsolid ? 1 : 0;
        pr_global_struct.trace_startsolid = trace.startsolid ? 1 : 0;
        pr_global_struct.trace_fraction   = trace.fraction;
        pr_global_struct.trace_inwater    = trace.inwater ? 1 : 0;
        pr_global_struct.trace_inopen     = trace.inopen ? 1 : 0;
        Mathlib.Copy(ref trace.endpos, out pr_global_struct.trace_endpos);
        Mathlib.Copy(ref trace.plane.normal, out pr_global_struct.trace_plane_normal);
        pr_global_struct.trace_plane_dist = trace.plane.dist;
        if (trace.ent != null)
        {
            pr_global_struct.trace_ent = EDICT_TO_PROG(trace.ent);
        }
        else
        {
            pr_global_struct.trace_ent = EDICT_TO_PROG(sv.edicts[0]);
        }
    }
Пример #2
0
    public static void Test5_f()
    {
        entity_t p = cl_entities[cl.viewentity];

        if (p == null)
        {
            return;
        }

        OpenTK.Vector3 org = p.origin;

        for (int i = 0; i < sv.edicts.Length; i++)
        {
            edict_t ed = sv.edicts[i];

            if (ed.free)
            {
                continue;
            }

            OpenTK.Vector3 vmin, vmax;
            Mathlib.Copy(ref ed.v.absmax, out vmax);
            Mathlib.Copy(ref ed.v.absmin, out vmin);

            if (org.X >= vmin.X && org.Y >= vmin.Y && org.Z >= vmin.Z &&
                org.X <= vmax.X && org.Y <= vmax.Y && org.Z <= vmax.Z)
            {
                Con_Printf("{0}\n", i);
            }
        }
    }
Пример #3
0
    static void PF_droptofloor()
    {
        edict_t ent = PROG_TO_EDICT(pr_global_struct.self);

        Vector3 org, mins, maxs;

        Mathlib.Copy(ref ent.v.origin, out org);
        Mathlib.Copy(ref ent.v.mins, out mins);
        Mathlib.Copy(ref ent.v.maxs, out maxs);
        Vector3 end = org;

        end.Z -= 256;

        trace_t trace = SV_Move(ref org, ref mins, ref maxs, ref end, 0, ent);

        if (trace.fraction == 1 || trace.allsolid)
        {
            G_FLOAT((float)0);
        }
        else
        {
            Mathlib.Copy(ref trace.endpos, out ent.v.origin);
            SV_LinkEdict(ent, false);
            ent.v.flags        = (int)ent.v.flags | q_shared.FL_ONGROUND;
            ent.v.groundentity = EDICT_TO_PROG(trace.ent);
            G_FLOAT((float)1);
        }
    }
Пример #4
0
    public static trace_t PushEntity(edict_t ent, ref v3f push)
    {
        v3f end;

        Mathlib.VectorAdd(ref ent.v.origin, ref push, out end);

        trace_t trace;

        if (ent.v.movetype == q_shared.MOVETYPE_FLYMISSILE)
        {
            trace = Move(ref ent.v.origin, ref ent.v.mins, ref ent.v.maxs, ref end, q_shared.MOVE_MISSILE, ent);
        }
        else if (ent.v.solid == q_shared.SOLID_TRIGGER || ent.v.solid == q_shared.SOLID_NOT)
        {
            // only clip against bmodels
            trace = Move(ref ent.v.origin, ref ent.v.mins, ref ent.v.maxs, ref end, q_shared.MOVE_NOMONSTERS, ent);
        }
        else
        {
            trace = Move(ref ent.v.origin, ref ent.v.mins, ref ent.v.maxs, ref end, q_shared.MOVE_NORMAL, ent);
        }

        Mathlib.Copy(ref trace.endpos, out ent.v.origin);
        SV_LinkEdict(ent, true);

        if (trace.ent != null)
        {
            SV_Impact(ent, trace.ent);
        }

        return(trace);
    }
Пример #5
0
    public static void SV_ReadClientMove(ref usercmd_t move)
    {
        client_t client = host_client;

        // read ping time
        client.ping_times[client.num_pings % q_shared.NUM_PING_TIMES] = (float)(sv.time - Reader.MSG_ReadFloat());
        client.num_pings++;

        // read current angles
        Vector3 angles = Reader.ReadAngles();

        Mathlib.Copy(ref angles, out client.edict.v.v_angle);

        // read movement
        move.forwardmove = Reader.MSG_ReadShort();
        move.sidemove    = Reader.MSG_ReadShort();
        move.upmove      = Reader.MSG_ReadShort();

        // read buttons
        int bits = Reader.MSG_ReadByte();

        client.edict.v.button0 = bits & 1;
        client.edict.v.button2 = (bits & 2) >> 1;

        int i = Reader.MSG_ReadByte();

        if (i != 0)
        {
            client.edict.v.impulse = i;
        }
    }
Пример #6
0
    public static trace_t Move(ref v3f start, ref v3f mins, ref v3f maxs, ref v3f end, int type, edict_t passedict)
    {
        Vector3 vstart, vmins, vmaxs, vend;

        Mathlib.Copy(ref start, out vstart);
        Mathlib.Copy(ref mins, out vmins);
        Mathlib.Copy(ref maxs, out vmaxs);
        Mathlib.Copy(ref end, out vend);
        return(SV_Move(ref vstart, ref vmins, ref vmaxs, ref vend, type, passedict));
    }
Пример #7
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);
    }
Пример #8
0
    public static void DropPunchAngle()
    {
        Vector3 v   = ToVector(ref sv_player.v.punchangle);
        double  len = Mathlib.Normalize(ref v) - 10 * host_framtime;

        if (len < 0)
        {
            len = 0;
        }
        v *= (float)len;
        Mathlib.Copy(ref v, out sv_player.v.punchangle);
    }
Пример #9
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);
        }
    }
Пример #10
0
    static void SetMinMaxSize(edict_t e, ref Vector3 min, ref Vector3 max, bool rotate)
    {
        if (min.X > max.X || min.Y > max.Y || min.Z > max.Z)
        {
            PR_RunError("backwards mins/maxs");
        }

        rotate = false;         // FIXME: implement rotation properly again

        Vector3 rmin = min, rmax = max;

        if (!rotate)
        {
            //rmin = min;
            //rmax = max;
        }
        else
        {
            // find min / max for rotations
            //angles = e.v.angles;

            //a = angles[1] / 180 * M_PI;

            //xvector[0] = cos(a);
            //xvector[1] = sin(a);
            //yvector[0] = -sin(a);
            //yvector[1] = cos(a);

            //VectorCopy(min, bounds[0]);
            //VectorCopy(max, bounds[1]);

            //rmin[0] = rmin[1] = rmin[2] = 9999;
            //rmax[0] = rmax[1] = rmax[2] = -9999;

            //for (i = 0; i <= 1; i++)
            //{
            //    base[0] = bounds[i][0];
            //    for (j = 0; j <= 1; j++)
            //    {
            //        base[1] = bounds[j][1];
            //        for (k = 0; k <= 1; k++)
            //        {
            //            base[2] = bounds[k][2];

            //            // transform the point
            //            transformed[0] = xvector[0] * base[0] + yvector[0] * base[1];
            //            transformed[1] = xvector[1] * base[0] + yvector[1] * base[1];
            //            transformed[2] = base[2];

            //            for (l = 0; l < 3; l++)
            //            {
            //                if (transformed[l] < rmin[l])
            //                    rmin[l] = transformed[l];
            //                if (transformed[l] > rmax[l])
            //                    rmax[l] = transformed[l];
            //            }
            //        }
            //    }
            //}
        }

        // set derived values
        Mathlib.Copy(ref rmin, out e.v.mins);
        Mathlib.Copy(ref rmax, out e.v.maxs);
        Vector3 s = max - min;

        Mathlib.Copy(ref s, out e.v.size);

        SV_LinkEdict(e, false);
    }
Пример #11
0
    static void PF_aim()
    {
        edict_t ent   = G_EDICT(q_shared.OFS_PARM0);
        float   speed = G_FLOAT(q_shared.OFS_PARM1);

        Vector3 start = ToVector(ref ent.v.origin);

        start.Z += 20;

        // try sending a trace straight
        Vector3 dir;

        Mathlib.Copy(ref pr_global_struct.v_forward, out dir);
        Vector3 end = start + dir * 2048;
        trace_t tr  = SV_Move(ref start, ref q_shared.ZeroVector, ref q_shared.ZeroVector, ref end, 0, ent);

        if (tr.ent != null && tr.ent.v.takedamage == q_shared.DAMAGE_AIM &&
            (teamplay.value == 0 || ent.v.team <= 0 || ent.v.team != tr.ent.v.team))
        {
            G_VECTOR(ref pr_global_struct.v_forward);
            return;
        }

        // try all possible entities
        Vector3 bestdir  = dir;
        float   bestdist = sv_aim.value;
        edict_t bestent  = null;

        for (int i = 1; i < sv.num_edicts; i++)
        {
            edict_t check = sv.edicts[i];
            if (check.v.takedamage != q_shared.DAMAGE_AIM)
            {
                continue;
            }
            if (check == ent)
            {
                continue;
            }
            if (teamplay.value != 0 && ent.v.team > 0 && ent.v.team == check.v.team)
            {
                continue;       // don't aim at teammate
            }
            v3f tmp;
            Mathlib.VectorAdd(ref check.v.mins, ref check.v.maxs, out tmp);
            Mathlib.VectorMA(ref check.v.origin, 0.5f, ref tmp, out tmp);
            Mathlib.Copy(ref tmp, out end);

            dir = end - start;
            Mathlib.Normalize(ref dir);
            float dist = Vector3.Dot(dir, ToVector(ref pr_global_struct.v_forward));
            if (dist < bestdist)
            {
                continue;       // to far to turn
            }
            tr = SV_Move(ref start, ref q_shared.ZeroVector, ref q_shared.ZeroVector, ref end, 0, ent);
            if (tr.ent == check)
            {   // can shoot at this one
                bestdist = dist;
                bestent  = check;
            }
        }

        if (bestent != null)
        {
            v3f dir2, end2;
            Mathlib.VectorSubtract(ref bestent.v.origin, ref ent.v.origin, out dir2);
            float dist = Mathlib.DotProduct(ref dir2, ref pr_global_struct.v_forward);
            Mathlib.VectorScale(ref pr_global_struct.v_forward, dist, out end2);
            end2.z = dir2.z;
            Mathlib.Normalize(ref end2);
            G_VECTOR(ref end2);
        }
        else
        {
            G_VECTOR(ref bestdir);
        }
    }
Пример #12
0
    public static int SV_FlyMove(edict_t ent, float time, trace_t steptrace)
    {
        v3f original_velocity = ent.v.velocity;
        v3f primal_velocity   = ent.v.velocity;

        int numbumps = 4;
        int blocked  = 0;

        Vector3[] planes    = new Vector3[q_shared.MAX_CLIP_PLANES];
        int       numplanes = 0;
        float     time_left = time;

        for (int bumpcount = 0; bumpcount < numbumps; bumpcount++)
        {
            if (ent.v.velocity.IsEmpty)
            {
                break;
            }

            v3f end;
            Mathlib.VectorMA(ref ent.v.origin, time_left, ref ent.v.velocity, out end);

            trace_t trace = Move(ref ent.v.origin, ref ent.v.mins, ref ent.v.maxs, ref end, 0, ent);

            if (trace.allsolid)
            {   // entity is trapped in another solid
                ent.v.velocity = default(v3f);
                return(3);
            }

            if (trace.fraction > 0)
            {   // actually covered some distance
                Mathlib.Copy(ref trace.endpos, out ent.v.origin);
                original_velocity = ent.v.velocity;
                numplanes         = 0;
            }

            if (trace.fraction == 1)
            {
                break;          // moved the entire distance
            }
            if (trace.ent == null)
            {
                Sys_Error("SV_FlyMove: !trace.ent");
            }

            if (trace.plane.normal.Z > 0.7)
            {
                blocked |= 1;           // floor
                if (trace.ent.v.solid == q_shared.SOLID_BSP)
                {
                    ent.v.flags        = (int)ent.v.flags | q_shared.FL_ONGROUND;
                    ent.v.groundentity = EDICT_TO_PROG(trace.ent);
                }
            }

            if (trace.plane.normal.Z == 0)
            {
                blocked |= 2;           // step
                if (steptrace != null)
                {
                    steptrace.CopyFrom(trace);  // save for player extrafriction
                }
            }

            //
            // run the impact function
            //
            SV_Impact(ent, trace.ent);
            if (ent.free)
            {
                break;          // removed by the impact function
            }
            time_left -= time_left * trace.fraction;

            // cliped to another plane
            if (numplanes >= q_shared.MAX_CLIP_PLANES)
            {
                // this shouldn't really happen
                ent.v.velocity = default(v3f);
                return(3);
            }

            planes[numplanes] = trace.plane.normal;
            numplanes++;

            //
            // modify original_velocity so it parallels all of the clip planes
            //
            v3f new_velocity = default(v3f);
            int i, j;
            for (i = 0; i < numplanes; i++)
            {
                ClipVelocity(ref original_velocity, ref planes[i], out new_velocity, 1);
                for (j = 0; j < numplanes; j++)
                {
                    if (j != i)
                    {
                        float dot = new_velocity.x * planes[j].X + new_velocity.y * planes[j].Y + new_velocity.z * planes[j].Z;
                        if (dot < 0)
                        {
                            break;      // not ok
                        }
                    }
                }
                if (j == numplanes)
                {
                    break;
                }
            }

            if (i != numplanes)
            {
                // go along this plane
                ent.v.velocity = new_velocity;
            }
            else
            {
                // go along the crease
                if (numplanes != 2)
                {
                    ent.v.velocity = default(v3f);
                    return(7);
                }
                Vector3 dir = Vector3.Cross(planes[0], planes[1]);
                float   d   = dir.X * ent.v.velocity.x + dir.Y * ent.v.velocity.y + dir.Z * ent.v.velocity.z;
                Mathlib.Copy(ref dir, out ent.v.velocity);
                Mathlib.VectorScale(ref ent.v.velocity, d, out ent.v.velocity);
            }

            //
            // if original velocity is against the original velocity, stop dead
            // to avoid tiny occilations in sloping corners
            //
            if (Mathlib.DotProduct(ref ent.v.velocity, ref primal_velocity) <= 0)
            {
                ent.v.velocity = default(v3f);
                return(blocked);
            }
        }

        return(blocked);
    }
Пример #13
0
    public static bool SV_movestep(edict_t ent, ref v3f move, bool relink)
    {
        trace_t trace;

        // try the move
        v3f oldorg = ent.v.origin;
        v3f neworg;

        Mathlib.VectorAdd(ref ent.v.origin, ref move, out neworg);

        // flying monsters don't step up
        if (((int)ent.v.flags & (q_shared.FL_SWIM | q_shared.FL_FLY)) != 0)
        {
            // try one move with vertical motion, then one without
            for (int i = 0; i < 2; i++)
            {
                Mathlib.VectorAdd(ref ent.v.origin, ref move, out neworg);
                edict_t enemy = PROG_TO_EDICT(ent.v.enemy);
                if (i == 0 && enemy != sv.edicts[0])
                {
                    float dz = ent.v.origin.z - enemy.v.origin.z;
                    if (dz > 40)
                    {
                        neworg.z -= 8;
                    }
                    if (dz < 30)
                    {
                        neworg.z += 8;
                    }
                }

                trace = Move(ref ent.v.origin, ref ent.v.mins, ref ent.v.maxs, ref neworg, 0, ent);
                if (trace.fraction == 1)
                {
                    if (((int)ent.v.flags & q_shared.FL_SWIM) != 0 &&
                        SV_PointContents(ref trace.endpos) == q_shared.CONTENTS_EMPTY)
                    {
                        return(false);   // swim monster left water
                    }
                    Mathlib.Copy(ref trace.endpos, out ent.v.origin);
                    if (relink)
                    {
                        SV_LinkEdict(ent, true);
                    }
                    return(true);
                }

                if (enemy == sv.edicts[0])
                {
                    break;
                }
            }

            return(false);
        }

        // push down from a step height above the wished position
        neworg.z += q_shared.STEPSIZE;
        v3f end = neworg;

        end.z -= q_shared.STEPSIZE * 2;

        trace = Move(ref neworg, ref ent.v.mins, ref ent.v.maxs, ref end, 0, ent);

        if (trace.allsolid)
        {
            return(false);
        }

        if (trace.startsolid)
        {
            neworg.z -= q_shared.STEPSIZE;
            trace     = Move(ref neworg, ref ent.v.mins, ref ent.v.maxs, ref end, 0, ent);
            if (trace.allsolid || trace.startsolid)
            {
                return(false);
            }
        }
        if (trace.fraction == 1)
        {
            // if monster had the ground pulled out, go ahead and fall
            if (((int)ent.v.flags & q_shared.FL_PARTIALGROUND) != 0)
            {
                Mathlib.VectorAdd(ref ent.v.origin, ref move, out ent.v.origin);
                if (relink)
                {
                    SV_LinkEdict(ent, true);
                }
                ent.v.flags = (int)ent.v.flags & ~q_shared.FL_ONGROUND;
                return(true);
            }

            return(false);               // walked off an edge
        }

        // check point traces down for dangling corners
        Mathlib.Copy(ref trace.endpos, out ent.v.origin);

        if (!SV_CheckBottom(ent))
        {
            if (((int)ent.v.flags & q_shared.FL_PARTIALGROUND) != 0)
            {
                // entity had floor mostly pulled out from underneath it
                // and is trying to correct
                if (relink)
                {
                    SV_LinkEdict(ent, true);
                }
                return(true);
            }
            ent.v.origin = oldorg;
            return(false);
        }

        if (((int)ent.v.flags & q_shared.FL_PARTIALGROUND) != 0)
        {
            ent.v.flags = (int)ent.v.flags & ~q_shared.FL_PARTIALGROUND;
        }
        ent.v.groundentity = EDICT_TO_PROG(trace.ent);

        // the move is ok
        if (relink)
        {
            SV_LinkEdict(ent, true);
        }
        return(true);
    }