Exemplo n.º 1
0
        // SV_Init
        public void Initialise( )
        {
            for (var i = 0; i < _BoxClipNodes.Length; i++)
            {
                _BoxClipNodes[i].children = new Int16[2];
            }
            for (var i = 0; i < _BoxPlanes.Length; i++)
            {
                _BoxPlanes[i] = new Plane();
            }
            for (var i = 0; i < _AreaNodes.Length; i++)
            {
                _AreaNodes[i] = new areanode_t();
            }

            if (Host.Cvars.Friction == null)
            {
                Host.Cvars.Friction        = Host.CVars.Add("sv_friction", 4f, ClientVariableFlags.Server);
                Host.Cvars.EdgeFriction    = Host.CVars.Add("edgefriction", 2f);
                Host.Cvars.StopSpeed       = Host.CVars.Add("sv_stopspeed", 100f);
                Host.Cvars.Gravity         = Host.CVars.Add("sv_gravity", 800f, ClientVariableFlags.Server);
                Host.Cvars.MaxVelocity     = Host.CVars.Add("sv_maxvelocity", 2000f);
                Host.Cvars.NoStep          = Host.CVars.Add("sv_nostep", false);
                Host.Cvars.MaxSpeed        = Host.CVars.Add("sv_maxspeed", 320f, ClientVariableFlags.Server);
                Host.Cvars.Accelerate      = Host.CVars.Add("sv_accelerate", 10f);
                Host.Cvars.Aim             = Host.CVars.Add("sv_aim", 0.93f);
                Host.Cvars.IdealPitchScale = Host.CVars.Add("sv_idealpitchscale", 0.8f);
            }

            for (var i = 0; i < QDef.MAX_MODELS; i++)
            {
                _LocalModels[i] = "*" + i.ToString();
            }
        }
Exemplo n.º 2
0
        private static byte[] _FatPvs = new byte[bsp_file.MAX_MAP_LEAFS / 8]; // fatpvs

        // SV_Init
        public static void Init()
        {
            for (int i = 0; i < _BoxClipNodes.Length; i++)
            {
                _BoxClipNodes[i].children = new short[2];
            }
            for (int i = 0; i < _BoxPlanes.Length; i++)
            {
                _BoxPlanes[i] = new mplane_t();
            }
            for (int i = 0; i < _AreaNodes.Length; i++)
            {
                _AreaNodes[i] = new areanode_t();
            }

            if (_Friction == null)
            {
                _Friction        = new cvar("sv_friction", "4", false, true);
                _EdgeFriction    = new cvar("edgefriction", "2");
                _StopSpeed       = new cvar("sv_stopspeed", "100");
                _Gravity         = new cvar("sv_gravity", "800", false, true);
                _MaxVelocity     = new cvar("sv_maxvelocity", "2000");
                _NoStep          = new cvar("sv_nostep", "0");
                _MaxSpeed        = new cvar("sv_maxspeed", "320", false, true);
                _Accelerate      = new cvar("sv_accelerate", "10");
                _Aim             = new cvar("sv_aim", "0.93");
                _IdealPitchScale = new cvar("sv_idealpitchscale", "0.8");
            }

            for (int i = 0; i < QDef.MAX_MODELS; i++)
            {
                _LocalModels[i] = "*" + i.ToString();
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// SV_TouchLinks
        /// </summary>
        static void TouchLinks(edict_t ent, areanode_t node)
        {
            // touch linked edicts
            LinkList next;

            for (LinkList l = node.trigger_edicts.Next; l != node.trigger_edicts; l = next)
            {
                next = l.Next;
                edict_t touch = (edict_t)l.Owner;// EDICT_FROM_AREA(l);
                if (touch == ent)
                {
                    continue;
                }

                if (touch.v.touch == 0 || touch.v.solid != Solids.SOLID_TRIGGER)
                {
                    continue;
                }

                if (ent.v.absmin.x > touch.v.absmax.x || ent.v.absmin.y > touch.v.absmax.y ||
                    ent.v.absmin.z > touch.v.absmax.z || ent.v.absmax.x < touch.v.absmin.x ||
                    ent.v.absmax.y < touch.v.absmin.y || ent.v.absmax.z < touch.v.absmin.z)
                {
                    continue;
                }

                int old_self  = Progs.GlobalStruct.self;
                int old_other = Progs.GlobalStruct.other;

                Progs.GlobalStruct.self  = EdictToProg(touch);
                Progs.GlobalStruct.other = EdictToProg(ent);
                Progs.GlobalStruct.time  = (float)sv.time;
                Progs.Execute(touch.v.touch);

                Progs.GlobalStruct.self  = old_self;
                Progs.GlobalStruct.other = old_other;
            }

            // recurse down both sides
            if (node.axis == -1)
            {
                return;
            }

            if (Mathlib.Comp(ref ent.v.absmax, node.axis) > node.dist)
            {
                TouchLinks(ent, node.children[0]);
            }

            if (Mathlib.Comp(ref ent.v.absmin, node.axis) < node.dist)
            {
                TouchLinks(ent, node.children[1]);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// SV_TouchLinks
        /// </summary>
        private void TouchLinks(MemoryEdict ent, areanode_t node)
        {
            // touch linked edicts
            Link next;

            for (var l = node.trigger_edicts.Next; l != node.trigger_edicts; l = next)
            {
                next = l.Next;
                var touch = ( MemoryEdict )l.Owner;                 // EDICT_FROM_AREA(l);
                if (touch == ent)
                {
                    continue;
                }
                if (touch.v.touch == 0 || touch.v.solid != Solids.SOLID_TRIGGER)
                {
                    continue;
                }
                if (ent.v.absmin.x > touch.v.absmax.x || ent.v.absmin.y > touch.v.absmax.y ||
                    ent.v.absmin.z > touch.v.absmax.z || ent.v.absmax.x < touch.v.absmin.x ||
                    ent.v.absmax.y < touch.v.absmin.y || ent.v.absmax.z < touch.v.absmin.z)
                {
                    continue;
                }

                var old_self  = Host.Programs.GlobalStruct.self;
                var old_other = Host.Programs.GlobalStruct.other;

                Host.Programs.GlobalStruct.self  = EdictToProg(touch);
                Host.Programs.GlobalStruct.other = EdictToProg(ent);
                Host.Programs.GlobalStruct.time  = ( Single )sv.time;
                Host.Programs.Execute(touch.v.touch);

                Host.Programs.GlobalStruct.self  = old_self;
                Host.Programs.GlobalStruct.other = old_other;
            }

            // recurse down both sides
            if (node.axis == -1)
            {
                return;
            }

            if (MathLib.Comp(ref ent.v.absmax, node.axis) > node.dist)
            {
                TouchLinks(ent, node.children[0]);
            }
            if (MathLib.Comp(ref ent.v.absmin, node.axis) < node.dist)
            {
                TouchLinks(ent, node.children[1]);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// SV_CreateAreaNode
        /// </summary>
        static areanode_t CreateAreaNode(int depth, ref Vector3 mins, ref Vector3 maxs)
        {
            areanode_t anode = _AreaNodes[_NumAreaNodes];

            _NumAreaNodes++;

            anode.trigger_edicts.Clear();
            anode.solid_edicts.Clear();

            if (depth == AREA_DEPTH)
            {
                anode.axis        = -1;
                anode.children[0] = anode.children[1] = null;
                return(anode);
            }

            Vector3 size  = maxs - mins;
            Vector3 mins1 = mins;
            Vector3 mins2 = mins;
            Vector3 maxs1 = maxs;
            Vector3 maxs2 = maxs;

            if (size.X > size.Y)
            {
                anode.axis = 0;
                anode.dist = 0.5f * (maxs.X + mins.X);
                maxs1.X    = mins2.X = anode.dist;
            }
            else
            {
                anode.axis = 1;
                anode.dist = 0.5f * (maxs.Y + mins.Y);
                maxs1.Y    = mins2.Y = anode.dist;
            }

            anode.children[0] = CreateAreaNode(depth + 1, ref mins2, ref maxs2);
            anode.children[1] = CreateAreaNode(depth + 1, ref mins1, ref maxs1);

            return(anode);
        }
Exemplo n.º 6
0
        /// <summary>
        /// SV_ClipToLinks
        /// Mins and maxs enclose the entire area swept by the move
        /// </summary>
        private void ClipToLinks(areanode_t node, moveclip_t clip)
        {
            Link    next;
            Trace_t trace;

            // touch linked edicts
            for (var l = node.solid_edicts.Next; l != node.solid_edicts; l = next)
            {
                next = l.Next;
                var touch = ( MemoryEdict )l.Owner;                 // EDICT_FROM_AREA(l);
                if (touch.v.solid == Solids.SOLID_NOT)
                {
                    continue;
                }
                if (touch == clip.passedict)
                {
                    continue;
                }
                if (touch.v.solid == Solids.SOLID_TRIGGER)
                {
                    Utilities.Error("Trigger in clipping list");
                }

                if (clip.type == MOVE_NOMONSTERS && touch.v.solid != Solids.SOLID_BSP)
                {
                    continue;
                }

                if (clip.boxmins.X > touch.v.absmax.x || clip.boxmins.Y > touch.v.absmax.y ||
                    clip.boxmins.Z > touch.v.absmax.z || clip.boxmaxs.X < touch.v.absmin.x ||
                    clip.boxmaxs.Y < touch.v.absmin.y || clip.boxmaxs.Z < touch.v.absmin.z)
                {
                    continue;
                }

                if (clip.passedict != null && clip.passedict.v.size.x != 0 && touch.v.size.x == 0)
                {
                    continue;                       // points never interact
                }
                // might intersect, so do an exact clip
                if (clip.trace.allsolid)
                {
                    return;
                }
                if (clip.passedict != null)
                {
                    if (ProgToEdict(touch.v.owner) == clip.passedict)
                    {
                        continue;                           // don't clip against own missiles
                    }
                    if (ProgToEdict(clip.passedict.v.owner) == touch)
                    {
                        continue;                           // don't clip against owner
                    }
                }

                if ((( Int32 )touch.v.flags & EdictFlags.FL_MONSTER) != 0)
                {
                    trace = ClipMoveToEntity(touch, ref clip.start, ref clip.mins2, ref clip.maxs2, ref clip.end);
                }
                else
                {
                    trace = ClipMoveToEntity(touch, ref clip.start, ref clip.mins, ref clip.maxs, ref clip.end);
                }

                if (trace.allsolid || trace.startsolid || trace.fraction < clip.trace.fraction)
                {
                    trace.ent = touch;
                    if (clip.trace.startsolid)
                    {
                        clip.trace            = trace;
                        clip.trace.startsolid = true;
                    }
                    else
                    {
                        clip.trace = trace;
                    }
                }
                else if (trace.startsolid)
                {
                    clip.trace.startsolid = true;
                }
            }

            // recurse down both sides
            if (node.axis == -1)
            {
                return;
            }

            if (MathLib.Comp(ref clip.boxmaxs, node.axis) > node.dist)
            {
                ClipToLinks(node.children[0], clip);
            }
            if (MathLib.Comp(ref clip.boxmins, node.axis) < node.dist)
            {
                ClipToLinks(node.children[1], clip);
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// SV_LinkEdict
        ///
        /// Needs to be called any time an entity changes origin, mins, maxs, or solid
        /// flags ent->v.modified
        /// sets ent->v.absmin and ent->v.absmax
        /// if touchtriggers, calls prog functions for the intersected triggers
        /// </summary>
        public static void LinkEdict(edict_t ent, bool touch_triggers)
        {
            if (ent.area.Prev != null)
            {
                UnlinkEdict(ent);       // unlink from old position
            }
            if (ent == sv.edicts[0])
            {
                return;         // don't add the world
            }
            if (ent.free)
            {
                return;
            }

            // set the abs box
            Mathlib.VectorAdd(ref ent.v.origin, ref ent.v.mins, out ent.v.absmin);
            Mathlib.VectorAdd(ref ent.v.origin, ref ent.v.maxs, out ent.v.absmax);

            //
            // to make items easier to pick up and allow them to be grabbed off
            // of shelves, the abs sizes are expanded
            //
            if (((int)ent.v.flags & EdictFlags.FL_ITEM) != 0)
            {
                ent.v.absmin.x -= 15;
                ent.v.absmin.y -= 15;
                ent.v.absmax.x += 15;
                ent.v.absmax.y += 15;
            }
            else
            {   // because movement is clipped an epsilon away from an actual edge,
                // we must fully check even when bounding boxes don't quite touch
                ent.v.absmin.x -= 1;
                ent.v.absmin.y -= 1;
                ent.v.absmin.z -= 1;
                ent.v.absmax.x += 1;
                ent.v.absmax.y += 1;
                ent.v.absmax.z += 1;
            }

            // link to PVS leafs
            ent.num_leafs = 0;
            if (ent.v.modelindex != 0)
            {
                FindTouchedLeafs(ent, sv.worldmodel.nodes[0]);
            }

            if (ent.v.solid == Solids.SOLID_NOT)
            {
                return;
            }

            // find the first node that the ent's box crosses
            areanode_t node = _AreaNodes[0];

            while (true)
            {
                if (node.axis == -1)
                {
                    break;
                }
                if (Mathlib.Comp(ref ent.v.absmin, node.axis) > node.dist)
                {
                    node = node.children[0];
                }
                else if (Mathlib.Comp(ref ent.v.absmax, node.axis) < node.dist)
                {
                    node = node.children[1];
                }
                else
                {
                    break;              // crosses the node
                }
            }

            // link it in

            if (ent.v.solid == Solids.SOLID_TRIGGER)
            {
                ent.area.InsertBefore(node.trigger_edicts);
            }
            else
            {
                ent.area.InsertBefore(node.solid_edicts);
            }

            // if touch_triggers, touch all entities at this node and decend for more
            if (touch_triggers)
            {
                TouchLinks(ent, _AreaNodes[0]);
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// SV_TouchLinks
        /// </summary>
        static void TouchLinks(edict_t ent, areanode_t node)
        {
            // touch linked edicts
            link_t next;
            for (link_t l = node.trigger_edicts.Next; l != node.trigger_edicts; l = next)
            {
                next = l.Next;
                edict_t touch = (edict_t)l.Owner;// EDICT_FROM_AREA(l);
                if (touch == ent)
                    continue;
                if (touch.v.touch == 0 || touch.v.solid != Solids.SOLID_TRIGGER)
                    continue;
                if (ent.v.absmin.x > touch.v.absmax.x || ent.v.absmin.y > touch.v.absmax.y ||
                    ent.v.absmin.z > touch.v.absmax.z || ent.v.absmax.x < touch.v.absmin.x ||
                    ent.v.absmax.y < touch.v.absmin.y || ent.v.absmax.z < touch.v.absmin.z)
                    continue;

                int old_self = Progs.GlobalStruct.self;
                int old_other = Progs.GlobalStruct.other;

                Progs.GlobalStruct.self = EdictToProg(touch);
                Progs.GlobalStruct.other = EdictToProg(ent);
                Progs.GlobalStruct.time = (float)sv.time;
                Progs.Execute(touch.v.touch);

                Progs.GlobalStruct.self = old_self;
                Progs.GlobalStruct.other = old_other;
            }

            // recurse down both sides
            if (node.axis == -1)
                return;

            if (Mathlib.Comp(ref ent.v.absmax, node.axis) > node.dist)
                TouchLinks(ent, node.children[0]);
            if (Mathlib.Comp(ref ent.v.absmin, node.axis) < node.dist)
                TouchLinks(ent, node.children[1]);
        }
Exemplo n.º 9
0
        /// <summary>
        /// SV_ClipToLinks
        /// Mins and maxs enclose the entire area swept by the move
        /// </summary>
        static void ClipToLinks(areanode_t node, moveclip_t clip)
        {
            link_t next;
            trace_t trace;

            // touch linked edicts
            for (link_t l = node.solid_edicts.Next; l != node.solid_edicts; l = next)
            {
                next = l.Next;
                edict_t touch = (edict_t)l.Owner;// EDICT_FROM_AREA(l);
                if (touch.v.solid == Solids.SOLID_NOT)
                    continue;
                if (touch == clip.passedict)
                    continue;
                if (touch.v.solid == Solids.SOLID_TRIGGER)
                    Sys.Error("Trigger in clipping list");

                if (clip.type == MOVE_NOMONSTERS && touch.v.solid != Solids.SOLID_BSP)
                    continue;

                if (clip.boxmins.X > touch.v.absmax.x || clip.boxmins.Y > touch.v.absmax.y ||
                    clip.boxmins.Z > touch.v.absmax.z || clip.boxmaxs.X < touch.v.absmin.x ||
                    clip.boxmaxs.Y < touch.v.absmin.y || clip.boxmaxs.Z < touch.v.absmin.z)
                    continue;

                if (clip.passedict != null && clip.passedict.v.size.x != 0 && touch.v.size.x == 0)
                    continue;	// points never interact

                // might intersect, so do an exact clip
                if (clip.trace.allsolid)
                    return;
                if (clip.passedict != null)
                {
                    if (ProgToEdict(touch.v.owner) == clip.passedict)
                        continue;	// don't clip against own missiles
                    if (ProgToEdict(clip.passedict.v.owner) == touch)
                        continue;	// don't clip against owner
                }

                if (((int)touch.v.flags & EdictFlags.FL_MONSTER) != 0)
                    trace = ClipMoveToEntity(touch, ref clip.start, ref clip.mins2, ref clip.maxs2, ref clip.end);
                else
                    trace = ClipMoveToEntity(touch, ref clip.start, ref clip.mins, ref clip.maxs, ref clip.end);

                if (trace.allsolid || trace.startsolid || trace.fraction < clip.trace.fraction)
                {
                    trace.ent = touch;
                    if (clip.trace.startsolid)
                    {
                        clip.trace = trace;
                        clip.trace.startsolid = true;
                    }
                    else
                        clip.trace = trace;
                }
                else if (trace.startsolid)
                    clip.trace.startsolid = true;
            }

            // recurse down both sides
            if (node.axis == -1)
                return;

            if (Mathlib.Comp(ref clip.boxmaxs, node.axis) > node.dist)
                ClipToLinks(node.children[0], clip);
            if (Mathlib.Comp(ref clip.boxmins, node.axis) < node.dist)
                ClipToLinks(node.children[1], clip);
        }