예제 #1
0
        void AddEntToSnapshot(svEntity_t svEnt, sharedEntity gEnt, List<int> eNums)
        {
            // if we have already added this entity to this snapshot, don't add again
            if (svEnt.snapshotCounter == sv.snapshotCounter)
                return;

            svEnt.snapshotCounter = sv.snapshotCounter;

            // if we are full, silently discard entities
            if (eNums.Count > 1024)
            {
                Common.Instance.WriteLine("Snapshot is full");
                return;
            }

            eNums.Add(gEnt.s.number);
        }
예제 #2
0
 public gentity_t()
 {
     shEnt = new sharedEntity();
 }
예제 #3
0
 int ClipHandleForEntity(sharedEntity ent)
 {
     return ClipMap.Instance.TempBoxModel(ent.r.mins, ent.r.maxs);
 }
예제 #4
0
파일: Game.cs 프로젝트: maesse/CubeHags
 public Server.svEntity_t SvEntityForGentity(sharedEntity gEnt)
 {
     if (gEnt == null || gEnt.s.number < 0 || gEnt.s.number >= 1024)
         Common.Instance.Error("SvEntityForGentity: Bad gEnt");
     return Server.Instance.sv.svEntities[gEnt.s.number];
 }
예제 #5
0
파일: Server.cs 프로젝트: maesse/CubeHags
        public void UnlinkEntity(sharedEntity gEnt)
        {
            svEntity_t ent = Game.Instance.SvEntityForGentity(gEnt);
            gEnt.r.linked = false;
            worldSector_t ws = ent.worldSector;
            if (ws == null)
                return; // not linked in anywhere

            ent.worldSector = null;
            if (ws.entities == ent)
            {
                ws.entities = ent.nextEntityInWorldSector;
                return;
            }

            svEntity_t scan;
            for (scan = ent; scan != null; scan = scan.nextEntityInWorldSector)
            {
                if (scan.nextEntityInWorldSector == ent)
                {
                    scan.nextEntityInWorldSector = ent.nextEntityInWorldSector;
                    return;
                }
            }

            Common.Instance.WriteLine("Warning: SV_UnlinkEntity: not found in worldsector");
        }
예제 #6
0
파일: Server.cs 프로젝트: maesse/CubeHags
 public void LocateGameData(sharedEntity[] gEnts, int entityCount, gclient_t[] clients)
 {
     sv.gentities = gEnts;
     //sv.gentities = new List<sharedEntity>();
     //for (int i = 0; i < gEnts.Count; i++)
     //{
     //    sv.gentities.Add(Game.Instance.GEntityToSharedEntity(gEnts[i]));
     //}
     sv.num_entities = entityCount;
     sv.gameClients = clients;
 }
예제 #7
0
파일: Server.cs 프로젝트: maesse/CubeHags
        public void LinkEntity(sharedEntity gEnt)
        {
            svEntity_t ent =  sv.svEntities[gEnt.s.number];
            if (ent.worldSector != null)
            {
                UnlinkEntity(gEnt);
            }

            // encode the size into the entityState_t for client prediction
            if (gEnt.r.bmodel)
            {
                gEnt.s.solid = 0xffffff; // SOLID_BMODEL
            }
            else if ((gEnt.r.contents & (int)(brushflags.CONTENTS_SOLID | brushflags.CONTENTS_MONSTER)) > 0)
            {
                // assume that x/y are equal and symetric
                int i = (int)gEnt.r.maxs[0];
                if (i < 1)
                    i = 1;
                if (i > 255)
                    i = 255;

                int j = (int)-gEnt.r.mins[2];
                if (j < 1)
                    j = 1;
                if (j > 255)
                    j = 255;

                int k = (int)gEnt.r.maxs[2] + 32;
                if (k < 1)
                    k = 1;
                if (k > 255)
                    k = 255;

                gEnt.s.solid = (k << 16) | (j << 8) | i;
            }
            else
            {
                gEnt.s.solid = 0;
            }

            // set the abs box
            if (gEnt.r.bmodel && (gEnt.r.currentAngles[0] != 0 || gEnt.r.currentAngles[1] != 0 || gEnt.r.currentAngles[2] != 0))
            {
                // expand for rotation
                float max = RadiusFromBounds(gEnt.r.mins, gEnt.r.maxs);
                for (int i = 0; i < 3; i++)
                {
                    gEnt.r.absmin[i] = gEnt.r.currentOrigin[i] - max;
                    gEnt.r.absmax[i] = gEnt.r.currentOrigin[i] + max;
                }
            }
            else
            {
                // normal
                gEnt.r.absmin = Vector3.Add(gEnt.r.currentOrigin, gEnt.r.mins);
                gEnt.r.absmax = Vector3.Add(gEnt.r.currentOrigin, gEnt.r.maxs);
            }

            // because movement is clipped an epsilon away from an actual edge,
            // we must fully check even when bounding boxes don't quite touch
            gEnt.r.absmin[0] -= 1;
            gEnt.r.absmin[1] -= 1;
            gEnt.r.absmin[2] -= 1;
            gEnt.r.absmax[0] += 1;
            gEnt.r.absmax[1] += 1;
            gEnt.r.absmax[2] += 1;

            // link to PVS leafs
            ent.numClusters = 0;
            ent.lastCluster = 0;
            ent.areanum = -1;
            ent.areanum2 = -1;

            //get all leafs, including solids
            ClipMap.leafList_t ll = new ClipMap.leafList_t();
            ll.lastLeaf = -1;
            ll.bounds = new Vector3[2];
            ll.maxcount = 128;
            ll.bounds[0] = gEnt.r.absmin;
            ll.bounds[1] = gEnt.r.absmax;
            ll.list = new int[128];
            ClipMap.Instance.BoxLeafnums(ll, 0);

            // if none of the leafs were inside the map, the
            // entity is outside the world and can be considered unlinked
            if (ll.count <= 0)
                return;

            // set areas, even from clusters that don't fit in the entity array
            for (int i = 0; i < ll.count; i++)
            {
                int area = ClipMap.Instance.LeafArea(ll.list[i]);
                if (area != -1)
                {
                    // doors may legally straggle two areas,
                    // but nothing should evern need more than that
                    if (ent.areanum != -1 && ent.areanum != area)
                    {
                        if (ent.areanum2 != -1 && ent.areanum2 != area && sv.state == serverState_t.SS_LOADING)
                        {
                            Common.Instance.WriteLine("Object {0} touching 3 areas at {1}", gEnt.s.number, gEnt.r.absmin);
                        }
                        ent.areanum2 = area;
                    }
                }
                else
                {
                    ent.areanum = area;
                }
            }

            // store as many explicit clusters as we can
            ent.numClusters = 0;
            int actual = 0;
            for (int i = 0; i < ll.count; i++)
            {
                actual = i;
                int cluster = ClipMap.Instance.LeafCluster(ll.list[i]);
                if (cluster != -1)
                {
                    ent.clusternums[ent.numClusters++] = cluster;
                    if (ent.numClusters == 16)
                        break;
                }
            }

            // store off a last cluster if we need to
            if (actual != ll.count && ll.lastLeaf != -1)
                ent.lastCluster = ClipMap.Instance.LeafCluster(ll.lastLeaf);

            gEnt.r.linkcount++;

            // find the first world sector node that the ent's box crosses
            worldSector_t node = sv_worldSectors[0];
            while (true)
            {
                if (node.axis == -1)
                    break;
                if (gEnt.r.absmin[node.axis] > node.dist)
                    node = node.children[0];
                else if (gEnt.r.absmax[node.axis] < node.dist)
                    node = node.children[1];
                else
                    break; // crosses the node
            }

            // link it in
            ent.worldSector = node;
            ent.nextEntityInWorldSector = node.entities;
            node.entities = ent;

            // find the first world sector node that the ent's box crosses
            gEnt.r.linked = true;
        }