Example #1
0
        static void Test5_f()
        {
            entity_t p = Client.ViewEntity;

            if (p == null)
            {
                return;
            }

            OpenTK.Vector3 org = p.origin;

            for (int i = 0; i < Server.sv.edicts.Length; i++)
            {
                edict_t ed = Server.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.Print("{0}\n", i);
                }
            }
        }
Example #2
0
        /// <summary>
        /// PushEntity
        /// Does not change the entities velocity at all
        /// </summary>
        private 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 == Movetypes.MOVETYPE_FLYMISSILE)
            {
                trace = Move(ref ent.v.origin, ref ent.v.mins, ref ent.v.maxs, ref end, MOVE_MISSILE, ent);
            }
            else if (ent.v.solid == Solids.SOLID_TRIGGER || ent.v.solid == Solids.SOLID_NOT)
            {
                // only clip against bmodels
                trace = Move(ref ent.v.origin, ref ent.v.mins, ref ent.v.maxs, ref end, MOVE_NOMONSTERS, ent);
            }
            else
            {
                trace = Move(ref ent.v.origin, ref ent.v.mins, ref ent.v.maxs, ref end, MOVE_NORMAL, ent);
            }

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

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

            return(trace);
        }
Example #3
0
        /*
         * ===============
         * PF_droptofloor
         *
         * void() droptofloor
         * ===============
         */
        static void PF_droptofloor()
        {
            edict_t ent = Server.ProgToEdict(Progs.GlobalStruct.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 = Server.Move(ref org, ref mins, ref maxs, ref end, 0, ent);

            if (trace.fraction == 1 || trace.allsolid)
            {
                ReturnFloat(0);
            }
            else
            {
                Mathlib.Copy(ref trace.endpos, out ent.v.origin);
                Server.LinkEdict(ent, false);
                ent.v.flags        = (int)ent.v.flags | EdictFlags.FL_ONGROUND;
                ent.v.groundentity = Server.EdictToProg(trace.ent);
                ReturnFloat(1);
            }
        }
Example #4
0
        /*
         * =================
         * PF_traceline
         *
         * Used for use tracing and shot targeting
         * Traces are blocked by bbox and exact bsp entityes, and also slide box entities
         * if the tryents flag is set.
         *
         * traceline (vector1, vector2, tryents)
         * =================
         */
        static unsafe void PF_traceline()
        {
            float * v1         = GetVector(OFS.OFS_PARM0);
            float * v2         = GetVector(OFS.OFS_PARM1);
            int     nomonsters = (int)GetFloat(OFS.OFS_PARM2);
            edict_t ent        = GetEdict(OFS.OFS_PARM3);

            Vector3 vec1, vec2;

            Copy(v1, out vec1);
            Copy(v2, out vec2);
            trace_t trace = Server.Move(ref vec1, ref Common.ZeroVector, ref Common.ZeroVector, ref vec2, nomonsters, ent);

            Progs.GlobalStruct.trace_allsolid   = trace.allsolid ? 1 : 0;
            Progs.GlobalStruct.trace_startsolid = trace.startsolid ? 1 : 0;
            Progs.GlobalStruct.trace_fraction   = trace.fraction;
            Progs.GlobalStruct.trace_inwater    = trace.inwater ? 1 : 0;
            Progs.GlobalStruct.trace_inopen     = trace.inopen ? 1 : 0;
            Mathlib.Copy(ref trace.endpos, out Progs.GlobalStruct.trace_endpos);
            Mathlib.Copy(ref trace.plane.normal, out Progs.GlobalStruct.trace_plane_normal);
            Progs.GlobalStruct.trace_plane_dist = trace.plane.dist;
            if (trace.ent != null)
            {
                Progs.GlobalStruct.trace_ent = Server.EdictToProg(trace.ent);
            }
            else
            {
                Progs.GlobalStruct.trace_ent = Server.EdictToProg(Server.sv.edicts[0]);
            }
        }
Example #5
0
        /// <summary>
        /// SV_ReadClientMove
        /// </summary>
        static void ReadClientMove(ref usercmd_t move)
        {
            client_t client = Host.HostClient;

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

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

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

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

            // read buttons
            int bits = Net.Reader.ReadByte();

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

            int i = Net.Reader.ReadByte();

            if (i != 0)
            {
                client.edict.v.impulse = i;
            }
        }
Example #6
0
        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(Move(ref vstart, ref vmins, ref vmaxs, ref vend, type, passedict));
        }
Example #7
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);
        }
Example #8
0
        static void DropPunchAngle()
        {
            Vector3 v   = Common.ToVector(ref _Player.v.punchangle);
            double  len = Mathlib.Normalize(ref v) - 10 * Host.FrameTime;

            if (len < 0)
            {
                len = 0;
            }
            v *= (float)len;
            Mathlib.Copy(ref v, out _Player.v.punchangle);
        }
Example #9
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);
            }
        }
Example #10
0
        /// <summary>
        /// SV_FlyMove
        /// The basic solid body movement clip that slides along multiple planes
        /// Returns the clipflags if the velocity was modified (hit something solid)
        /// 1 = floor
        /// 2 = wall / step
        /// 4 = dead stop
        /// If steptrace is not NULL, the trace of any vertical wall hit will be stored
        /// </summary>
        static int 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[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 == Solids.SOLID_BSP)
                    {
                        ent.v.flags        = (int)ent.v.flags | EdictFlags.FL_ONGROUND;
                        ent.v.groundentity = EdictToProg(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
                //
                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 >= 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);
        }
Example #11
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)
            {
                Progs.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);

            Server.LinkEdict(e, false);
        }
Example #12
0
        /*
         * =============
         * PF_aim
         *
         * Pick a vector for the player to shoot along
         * vector aim(entity, missilespeed)
         * =============
         */
        static void PF_aim()
        {
            edict_t ent   = GetEdict(OFS.OFS_PARM0);
            float   speed = GetFloat(OFS.OFS_PARM1);

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

            start.Z += 20;

            // try sending a trace straight
            Vector3 dir;

            Mathlib.Copy(ref Progs.GlobalStruct.v_forward, out dir);
            Vector3 end = start + dir * 2048;
            trace_t tr  = Server.Move(ref start, ref Common.ZeroVector, ref Common.ZeroVector, ref end, 0, ent);

            if (tr.ent != null && tr.ent.v.takedamage == Damages.DAMAGE_AIM &&
                (Host.TeamPlay == 0 || ent.v.team <= 0 || ent.v.team != tr.ent.v.team))
            {
                ReturnVector(ref Progs.GlobalStruct.v_forward);
                return;
            }

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

            for (int i = 1; i < Server.sv.num_edicts; i++)
            {
                edict_t check = Server.sv.edicts[i];
                if (check.v.takedamage != Damages.DAMAGE_AIM)
                {
                    continue;
                }
                if (check == ent)
                {
                    continue;
                }
                if (Host.TeamPlay != 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, Common.ToVector(ref Progs.GlobalStruct.v_forward));
                if (dist < bestdist)
                {
                    continue;   // to far to turn
                }
                tr = Server.Move(ref start, ref Common.ZeroVector, ref Common.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 Progs.GlobalStruct.v_forward);
                Mathlib.VectorScale(ref Progs.GlobalStruct.v_forward, dist, out end2);
                end2.z = dir2.z;
                Mathlib.Normalize(ref end2);
                ReturnVector(ref end2);
            }
            else
            {
                ReturnVector(ref bestdir);
            }
        }
Example #13
0
        /// <summary>
        /// SV_movestep
        /// Called by monster program code.
        /// The move will be adjusted for slopes and stairs, but if the move isn't
        /// possible, no move is done, false is returned, and
        /// pr_global_struct.trace_normal is set to the normal of the blocking wall
        /// </summary>
        public static bool 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 & (EdictFlags.FL_SWIM | EdictFlags.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 = ProgToEdict(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 & EdictFlags.FL_SWIM) != 0 &&
                            PointContents(ref trace.endpos) == Contents.CONTENTS_EMPTY)
                        {
                            return(false);       // swim monster left water
                        }
                        Mathlib.Copy(ref trace.endpos, out ent.v.origin);
                        if (relink)
                        {
                            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 += STEPSIZE;
            v3f end = neworg;

            end.z -= 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 -= 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 & EdictFlags.FL_PARTIALGROUND) != 0)
                {
                    Mathlib.VectorAdd(ref ent.v.origin, ref move, out ent.v.origin);
                    if (relink)
                    {
                        LinkEdict(ent, true);
                    }
                    ent.v.flags = (int)ent.v.flags & ~EdictFlags.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 (!CheckBottom(ent))
            {
                if (((int)ent.v.flags & EdictFlags.FL_PARTIALGROUND) != 0)
                {
                    // entity had floor mostly pulled out from underneath it
                    // and is trying to correct
                    if (relink)
                    {
                        LinkEdict(ent, true);
                    }
                    return(true);
                }
                ent.v.origin = oldorg;
                return(false);
            }

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

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