示例#1
0
    public static void SV_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 < sv_areanodes.Length; i++)
        {
            sv_areanodes[i] = new areanode_t();
        }

        sv_friction        = new cvar_t("sv_friction", "4", false, true);
        edgefriction       = new cvar_t("edgefriction", "2");
        sv_stopspeed       = new cvar_t("sv_stopspeed", "100");
        sv_gravity         = new cvar_t("sv_gravity", "800", false, true);
        sv_maxvelocity     = new cvar_t("sv_maxvelocity", "2000");
        sv_nostep          = new cvar_t("sv_nostep", "0");
        sv_maxspeed        = new cvar_t("sv_maxspeed", "320", false, true);
        sv_accelerate      = new cvar_t("sv_accelerate", "10");
        sv_aim             = new cvar_t("sv_aim", "0.93");
        sv_idealpitchscale = new cvar_t("sv_idealpitchscale", "0.8");

        for (int i = 0; i < q_shared.MAX_MODELS; i++)
        {
            localmodels[i] = "*" + i.ToString();
        }
    }
示例#2
0
        /*
         * ==================== SV_AreaEdicts_r
         *
         * ====================
         */
        public static void SV_AreaEdicts_r(areanode_t node)
        {
            link_t  l, next, start;
            edict_t check;

            // touch linked edicts
            if (SV_WORLD.area_type == Defines.AREA_SOLID)
            {
                start = node.solid_edicts;
            }
            else
            {
                start = node.trigger_edicts;
            }

            for (l = start.next; l != start; l = next)
            {
                next  = l.next;
                check = (edict_t)l.o;

                if (check.solid == Defines.SOLID_NOT)
                {
                    continue;                     // deactivated
                }
                if (check.absmin[0] > SV_WORLD.area_maxs[0] ||
                    check.absmin[1] > SV_WORLD.area_maxs[1] ||
                    check.absmin[2] > SV_WORLD.area_maxs[2] ||
                    check.absmax[0] < SV_WORLD.area_mins[0] ||
                    check.absmax[1] < SV_WORLD.area_mins[1] ||
                    check.absmax[2] < SV_WORLD.area_mins[2])
                {
                    continue;                     // not touching
                }
                if (SV_WORLD.area_count == SV_WORLD.area_maxcount)
                {
                    Com.Printf("SV_AreaEdicts: MAXCOUNT\n");

                    return;
                }

                SV_WORLD.area_list[SV_WORLD.area_count] = check;
                SV_WORLD.area_count++;
            }

            if (node.axis == -1)
            {
                return;                 // terminal node
            }
            // recurse down both sides
            if (SV_WORLD.area_maxs[node.axis] > node.dist)
            {
                SV_WORLD.SV_AreaEdicts_r(node.children[0]);
            }

            if (SV_WORLD.area_mins[node.axis] < node.dist)
            {
                SV_WORLD.SV_AreaEdicts_r(node.children[1]);
            }
        }
示例#3
0
    public static void SV_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 != q_shared.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  = pr_global_struct.self;
            int old_other = pr_global_struct.other;

            pr_global_struct.self  = EDICT_TO_PROG(touch);
            pr_global_struct.other = EDICT_TO_PROG(ent);
            pr_global_struct.time  = (float)sv.time;
            PR_ExecuteProgram(touch.v.touch);

            pr_global_struct.self  = old_self;
            pr_global_struct.other = old_other;
        }

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

        if (Mathlib.Comp(ref ent.v.absmax, node.axis) > node.dist)
        {
            SV_TouchLinks(ent, node.children[0]);
        }
        if (Mathlib.Comp(ref ent.v.absmin, node.axis) < node.dist)
        {
            SV_TouchLinks(ent, node.children[1]);
        }
    }
示例#4
0
    public static areanode_t SV_CreateAreaNode(int depth, ref Vector3 mins, ref Vector3 maxs)
    {
        areanode_t anode = sv_areanodes[sv_numareanodes];

        sv_numareanodes++;

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

        if (depth == q_shared.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] = SV_CreateAreaNode(depth + 1, ref mins2, ref maxs2);
        anode.children[1] = SV_CreateAreaNode(depth + 1, ref mins1, ref maxs1);

        return(anode);
    }
示例#5
0
        static void SV_ClipToLinks(areanode_t node, moveclip_t clip)
        {
            common.link_t		l, next;
            prog.edict_t		touch;
            trace_t		trace;

        // touch linked edicts
            for (l = node.solid_edicts.next; l != node.solid_edicts; l = next)
            {
                //Debug.WriteLine("ClipToLinks_for_num " + ClipToLinks_for_num);
                ClipToLinks_for_num++;
                next = l.next;
                touch = prog. EDICT_FROM_AREA(l);
                if (touch.v.solid == server.SOLID_NOT)
                {
                    continue;
                }
                if (touch == clip.passedict)
                {
                    continue;
                }
                if (touch.v.solid == server. SOLID_TRIGGER)
                  sys_linux.  Sys_Error ("Trigger in clipping list");

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

                if (clip.boxmins[0] > touch.v.absmax[0]
                || clip.boxmins[1] > touch.v.absmax[1]
                || clip.boxmins[2] > touch.v.absmax[2]
                || clip.boxmaxs[0] < touch.v.absmin[0]
                || clip.boxmaxs[1] < touch.v.absmin[1]
                || clip.boxmaxs[2] < touch.v.absmin[2])
                {
                    continue;
                }

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

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

                if (((int)touch.v.flags & server.FL_MONSTER) != 0)
                    trace = SV_ClipMoveToEntity (touch, clip.start, clip.mins2, clip.maxs2, clip.end);
                else
                    trace = SV_ClipMoveToEntity (touch, clip.start, clip.mins, clip.maxs, 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 (clip.boxmaxs[node.axis] > node.dist)
            {
                SV_ClipToLinks(node.children[0], clip);
            }
            if (clip.boxmins[node.axis] < node.dist)
            {
                SV_ClipToLinks(node.children[1], clip);
            }
        }
示例#6
0
       static void SV_TouchLinks(prog.edict_t ent, areanode_t node)
       {
           common.link_t l, next;
           prog.edict_t touch;
           int old_self, old_other;

           tchlinksFunc++;

           // touch linked edicts
           for (l = node.trigger_edicts.next; l != node.trigger_edicts; l = next)
           {
               //Debug.WriteLine("SV_TouchLinks loop "+ tchlinks);
               tchlinks++;

               next = l.next;
               touch = prog.EDICT_FROM_AREA(l);
               if (touch == ent)
                   continue;
               if (!(touch.v.touch != 0) || touch.v.solid != server.SOLID_TRIGGER)
                   continue;
               if (ent.v.absmin[0] > touch.v.absmax[0]
               || ent.v.absmin[1] > touch.v.absmax[1]
               || ent.v.absmin[2] > touch.v.absmax[2]
               || ent.v.absmax[0] < touch.v.absmin[0]
               || ent.v.absmax[1] < touch.v.absmin[1]
               || ent.v.absmax[2] < touch.v.absmin[2])
                   continue;
               old_self = prog.pr_global_struct[0].self;
               old_other = prog.pr_global_struct[0].other;

               prog.pr_global_struct[0].self = prog.EDICT_TO_PROG(touch);
               prog.pr_global_struct[0].other = prog.EDICT_TO_PROG(ent);
               prog.pr_global_struct[0].time = server.sv.time;
               prog.PR_ExecuteProgram(prog.pr_functions[touch.v.touch]);

               prog.pr_global_struct[0].self = old_self;
               prog.pr_global_struct[0].other = old_other;
           }

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

           if (ent.v.absmax[node.axis] > node.dist)
           {
               SV_TouchLinks(ent, node.children[0]);
           }
           if (ent.v.absmin[node.axis] < node.dist)
           {
               SV_TouchLinks(ent, node.children[1]);
           }
       }
示例#7
0
        /*
        ===============
        SV_CreateAreaNode

        ===============
        */
        static areanode_t SV_CreateAreaNode(int depth, double[] mins, double[] maxs)
        {
            areanode_t anode= new areanode_t();
            double[] size = new double[3] {0, 0, 0};
            double[] mins1 = new double[3] {0, 0, 0}, maxs1 = new double[3] {0, 0, 0}, mins2 = new double[3] {0, 0, 0}, maxs2 = new double[3] {0, 0, 0};

            anode = sv_areanodes[sv_numareanodes];
            sv_numareanodes++;
            //Debug.WriteLine("SV_CreateAreaNode");
            common.ClearLink(anode.trigger_edicts);
            common.ClearLink(anode.solid_edicts);

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

            mathlib.VectorSubtract(maxs, mins, size);
            if (size[0] > size[1])
                anode.axis = 0;
            else
                anode.axis = 1;

            anode.dist = 0.5 * (maxs[anode.axis] + mins[anode.axis]);
            mathlib. VectorCopy(mins, mins1);
            mathlib. VectorCopy(mins, mins2);
            mathlib. VectorCopy(maxs, maxs1);
            mathlib. VectorCopy(maxs, maxs2);

            maxs1[anode.axis] = mins2[anode.axis] = anode.dist;

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

            return anode;
        }
示例#8
0
 private static areanode_t[] Init_areanode_t(int count)
 {
     var nodes = new areanode_t[count];
     for (int i = 0; i < count; i++)
         nodes[i] = new areanode_t();
     return nodes;
 }
示例#9
0
    public static void SV_LinkEdict(edict_t ent, bool touch_triggers)
    {
        if (ent.area.Prev != null)
        {
            SV_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 & q_shared.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)
        {
            SV_FindTouchedLeafs(ent, sv.worldmodel.nodes[0]);
        }

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

        // find the first node that the ent's box crosses
        areanode_t node = sv_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 == q_shared.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)
        {
            SV_TouchLinks(ent, sv_areanodes[0]);
        }
    }
示例#10
0
    public static void SV_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 == q_shared.SOLID_NOT)
            {
                continue;
            }
            if (touch == clip.passedict)
            {
                continue;
            }
            if (touch.v.solid == q_shared.SOLID_TRIGGER)
            {
                Sys_Error("Trigger in clipping list");
            }

            if (clip.type == q_shared.MOVE_NOMONSTERS && touch.v.solid != q_shared.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 (PROG_TO_EDICT(touch.v.owner) == clip.passedict)
                {
                    continue;   // don't clip against own missiles
                }
                if (PROG_TO_EDICT(clip.passedict.v.owner) == touch)
                {
                    continue;   // don't clip against owner
                }
            }

            if (((int)touch.v.flags & q_shared.FL_MONSTER) != 0)
            {
                trace = SV_ClipMoveToEntity(touch, ref clip.start, ref clip.mins2, ref clip.maxs2, ref clip.end);
            }
            else
            {
                trace = SV_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)
        {
            SV_ClipToLinks(node.children[0], clip);
        }
        if (Mathlib.Comp(ref clip.boxmins, node.axis) < node.dist)
        {
            SV_ClipToLinks(node.children[1], clip);
        }
    }