コード例 #1
0
        public static bool PF_inPHS(float[] p1, float[] p2)
        {
            int leafnum;
            int cluster;
            int area1, area2;

            byte[] mask;
            leafnum = CM.CM_PointLeafnum(p1);
            cluster = CM.CM_LeafCluster(leafnum);
            area1   = CM.CM_LeafArea(leafnum);
            mask    = CM.CM_ClusterPHS(cluster);
            leafnum = CM.CM_PointLeafnum(p2);
            cluster = CM.CM_LeafCluster(leafnum);
            area2   = CM.CM_LeafArea(leafnum);
            if (cluster == -1)
            {
                return(false);
            }
            if (mask != null && (0 == (mask[cluster >> 3] & (1 << (cluster & 7)))))
            {
                return(false);
            }
            if (!CM.CM_AreasConnected(area1, area2))
            {
                return(false);
            }
            return(true);
        }
コード例 #2
0
ファイル: SV_GAME.cs プロジェクト: optimus-code/Quake2Sharp
        /**
         * PF_inPHS.
         *
         * Also checks portalareas so that doors block sound.
         */
        public static bool PF_inPHS(float[] p1, float[] p2)
        {
            int leafnum;
            int cluster;
            int area1, area2;

            byte[] mask;

            leafnum = CM.CM_PointLeafnum(p1);
            cluster = CM.CM_LeafCluster(leafnum);
            area1   = CM.CM_LeafArea(leafnum);
            mask    = CM.CM_ClusterPHS(cluster);

            leafnum = CM.CM_PointLeafnum(p2);
            cluster = CM.CM_LeafCluster(leafnum);
            area2   = CM.CM_LeafArea(leafnum);

            // quake2 bugfix
            if (cluster == -1)
            {
                return(false);
            }

            if (mask != null && 0 == (mask[cluster >> 3] & (1 << (cluster & 7))))
            {
                return(false);                // more than one bounce away
            }
            if (!CM.CM_AreasConnected(area1, area2))
            {
                return(false);                // a door blocks hearing
            }
            return(true);
        }
コード例 #3
0
ファイル: SV_SEND.cs プロジェクト: optimus-code/Q2Sharp
        public static void SV_Multicast(Single[] origin, Int32 to)
        {
            client_t client;

            Byte[]  mask = null;
            Int32   leafnum, cluster;
            Int32   j;
            Boolean reliable;
            Int32   area1, area2;

            reliable = false;
            if (to != Defines.MULTICAST_ALL_R && to != Defines.MULTICAST_ALL)
            {
                leafnum = CM.CM_PointLeafnum(origin);
                area1   = CM.CM_LeafArea(leafnum);
            }
            else
            {
                leafnum = 0;
                area1   = 0;
            }

            if (SV_INIT.svs.demofile != null)
            {
                SZ.Write(SV_INIT.svs.demo_multicast, SV_INIT.sv.multicast.data, SV_INIT.sv.multicast.cursize);
            }
            switch (to)

            {
            case Defines.MULTICAST_ALL_R:
                reliable = true;
                break;

            case Defines.MULTICAST_ALL:
                leafnum = 0;
                mask    = null;
                break;

            case Defines.MULTICAST_PHS_R:
                reliable = true;
                break;

            case Defines.MULTICAST_PHS:
                leafnum = CM.CM_PointLeafnum(origin);
                cluster = CM.CM_LeafCluster(leafnum);
                mask    = CM.CM_ClusterPHS(cluster);
                break;

            case Defines.MULTICAST_PVS_R:
                reliable = true;
                break;

            case Defines.MULTICAST_PVS:
                leafnum = CM.CM_PointLeafnum(origin);
                cluster = CM.CM_LeafCluster(leafnum);
                mask    = CM.CM_ClusterPVS(cluster);
                break;

            default:
                mask = null;
                Com.Error(Defines.ERR_FATAL, "SV_Multicast: bad to:" + to + "\\n");
                break;
            }

            for (j = 0; j < SV_MAIN.maxclients.value; j++)
            {
                client = SV_INIT.svs.clients[j];
                if (client.state == Defines.cs_free || client.state == Defines.cs_zombie)
                {
                    continue;
                }
                if (client.state != Defines.cs_spawned && !reliable)
                {
                    continue;
                }
                if (mask != null)
                {
                    leafnum = CM.CM_PointLeafnum(client.edict.s.origin);
                    cluster = CM.CM_LeafCluster(leafnum);
                    area2   = CM.CM_LeafArea(leafnum);
                    if (!CM.CM_AreasConnected(area1, area2))
                    {
                        continue;
                    }
                    if (cluster == -1)
                    {
                        continue;
                    }
                    if (mask != null && (0 == (mask[cluster >> 3] & (1 << (cluster & 7)))))
                    {
                        continue;
                    }
                }

                if (reliable)
                {
                    SZ.Write(client.netchan.message, SV_INIT.sv.multicast.data, SV_INIT.sv.multicast.cursize);
                }
                else
                {
                    SZ.Write(client.datagram, SV_INIT.sv.multicast.data, SV_INIT.sv.multicast.cursize);
                }
            }

            SZ.Clear(SV_INIT.sv.multicast);
        }
コード例 #4
0
        public static void SV_BuildClientFrame(client_t client)
        {
            Int32 e, i;

            Single[]       org = new Single[] { 0, 0, 0 };
            edict_t        ent;
            edict_t        clent;
            client_frame_t frame;
            entity_state_t state;
            Int32          l;
            Int32          clientarea, clientcluster;
            Int32          leafnum;
            Int32          c_fullsend;

            Byte[] clientphs;
            Byte[] bitvector;
            clent = client.edict;
            if (clent.client == null)
            {
                return;
            }
            frame          = client.frames[SV_INIT.sv.framenum & Defines.UPDATE_MASK];
            frame.senttime = SV_INIT.svs.realtime;
            for (i = 0; i < 3; i++)
            {
                org[i] = clent.client.ps.pmove.origin[i] * 0.125F + clent.client.ps.viewoffset[i];
            }
            leafnum         = CM.CM_PointLeafnum(org);
            clientarea      = CM.CM_LeafArea(leafnum);
            clientcluster   = CM.CM_LeafCluster(leafnum);
            frame.areabytes = CM.CM_WriteAreaBits(frame.areabits, clientarea);
            frame.ps.Set(clent.client.ps);
            SV_FatPVS(org);
            clientphs          = CM.CM_ClusterPHS(clientcluster);
            frame.num_entities = 0;
            frame.first_entity = SV_INIT.svs.next_client_entities;
            c_fullsend         = 0;
            for (e = 1; e < GameBase.num_edicts; e++)
            {
                ent = GameBase.g_edicts[e];
                if ((ent.svflags & Defines.SVF_NOCLIENT) != 0)
                {
                    continue;
                }
                if (0 == ent.s.modelindex && 0 == ent.s.effects && 0 == ent.s.sound && 0 == ent.s.event_renamed)
                {
                    continue;
                }
                if (ent != clent)
                {
                    if (!CM.CM_AreasConnected(clientarea, ent.areanum))
                    {
                        if (0 == ent.areanum2 || !CM.CM_AreasConnected(clientarea, ent.areanum2))
                        {
                            continue;
                        }
                    }

                    if ((ent.s.renderfx & Defines.RF_BEAM) != 0)
                    {
                        l = ent.clusternums[0];
                        if (0 == (clientphs[l >> 3] & (1 << (l & 7))))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (ent.s.sound == 0)
                        {
                            bitvector = SV_ENTS.fatpvs;
                        }
                        else
                        {
                            bitvector = SV_ENTS.fatpvs;
                        }
                        if (ent.num_clusters == -1)
                        {
                            if (!CM.CM_HeadnodeVisible(ent.headnode, bitvector))
                            {
                                continue;
                            }
                            c_fullsend++;
                        }
                        else
                        {
                            for (i = 0; i < ent.num_clusters; i++)
                            {
                                l = ent.clusternums[i];
                                if ((bitvector[l >> 3] & (1 << (l & 7))) != 0)
                                {
                                    break;
                                }
                            }

                            if (i == ent.num_clusters)
                            {
                                continue;
                            }
                        }

                        if (ent.s.modelindex == 0)
                        {
                            Single[] delta = new Single[] { 0, 0, 0 };
                            Single   len;
                            Math3D.VectorSubtract(org, ent.s.origin, delta);
                            len = Math3D.VectorLength(delta);
                            if (len > 400)
                            {
                                continue;
                            }
                        }
                    }
                }

                var ix = SV_INIT.svs.next_client_entities % SV_INIT.svs.num_client_entities;
                state = SV_INIT.svs.client_entities[ix];
                if (ent.s.number != e)
                {
                    Com.DPrintf("FIXING ENT.S.NUMBER!!!\\n");
                    ent.s.number = e;
                }

                SV_INIT.svs.client_entities[ix].Set(ent.s);
                if (ent.owner == client.edict)
                {
                    state.solid = 0;
                }
                SV_INIT.svs.next_client_entities++;
                frame.num_entities++;
            }
        }
コード例 #5
0
        /**
         * Decides which entities are going to be visible to the client, and copies
         * off the playerstat and areabits.
         */
        public static void SV_BuildClientFrame(client_t client)
        {
            int e, i;

            float[]        org = { 0, 0, 0 };
            edict_t        ent;
            edict_t        clent;
            client_frame_t frame;
            entity_state_t state;
            int            l;
            int            clientarea, clientcluster;
            int            leafnum;
            int            c_fullsend;

            byte[] clientphs;
            byte[] bitvector;

            clent = client.edict;

            if (clent.client == null)
            {
                return;                 // not in game yet
            }
            // this is the frame we are creating
            frame = client.frames[SV_INIT.sv.framenum & Defines.UPDATE_MASK];

            frame.senttime = SV_INIT.svs.realtime;             // save it for ping calc later

            // find the client's PVS
            for (i = 0; i < 3; i++)
            {
                org[i] = clent.client.ps.pmove.origin[i] * 0.125f + clent.client.ps.viewoffset[i];
            }

            leafnum       = CM.CM_PointLeafnum(org);
            clientarea    = CM.CM_LeafArea(leafnum);
            clientcluster = CM.CM_LeafCluster(leafnum);

            // calculate the visible areas
            frame.areabytes = CM.CM_WriteAreaBits(frame.areabits, clientarea);

            // grab the current player_state_t
            frame.ps.set(clent.client.ps);

            SV_ENTS.SV_FatPVS(org);
            clientphs = CM.CM_ClusterPHS(clientcluster);

            // build up the list of visible entities
            frame.num_entities = 0;
            frame.first_entity = SV_INIT.svs.next_client_entities;

            c_fullsend = 0;

            for (e = 1; e < GameBase.num_edicts; e++)
            {
                ent = GameBase.g_edicts[e];

                // ignore ents without visible models
                if ((ent.svflags & Defines.SVF_NOCLIENT) != 0)
                {
                    continue;
                }

                // ignore ents without visible models unless they have an effect
                if (0 == ent.s.modelindex && 0 == ent.s.effects && 0 == ent.s.sound && 0 == ent.s.@event)
                {
                    continue;
                }

                // ignore if not touching a PV leaf
                // check area
                if (ent != clent)
                {
                    if (!CM.CM_AreasConnected(clientarea, ent.areanum))
                    {
                        // doors can legally straddle two areas, so we may need to check another one
                        if (0 == ent.areanum2 || !CM.CM_AreasConnected(clientarea, ent.areanum2))
                        {
                            continue;                             // blocked by a door
                        }
                    }

                    // beams just check one point for PHS
                    if ((ent.s.renderfx & Defines.RF_BEAM) != 0)
                    {
                        l = ent.clusternums[0];

                        if (0 == (clientphs[l >> 3] & (1 << (l & 7))))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        // FIXME: if an ent has a model and a sound, but isn't
                        // in the PVS, only the PHS, clear the model
                        if (ent.s.sound == 0)
                        {
                            bitvector = SV_ENTS.fatpvs;                             //clientphs;
                        }
                        else
                        {
                            bitvector = SV_ENTS.fatpvs;
                        }

                        if (ent.num_clusters == -1)
                        {
                            // too many leafs for
                            // individual check, go by
                            // headnode
                            if (!CM.CM_HeadnodeVisible(ent.headnode, bitvector))
                            {
                                continue;
                            }

                            c_fullsend++;
                        }
                        else
                        {
                            // check individual leafs
                            for (i = 0; i < ent.num_clusters; i++)
                            {
                                l = ent.clusternums[i];

                                if ((bitvector[l >> 3] & (1 << (l & 7))) != 0)
                                {
                                    break;
                                }
                            }

                            if (i == ent.num_clusters)
                            {
                                continue;                                 // not visible
                            }
                        }

                        if (ent.s.modelindex == 0)
                        {
                            // don't send sounds if they
                            // will be attenuated away
                            float[] delta = { 0, 0, 0 };
                            float   len;

                            Math3D.VectorSubtract(org, ent.s.origin, delta);
                            len = Math3D.VectorLength(delta);

                            if (len > 400)
                            {
                                continue;
                            }
                        }
                    }
                }

                // add it to the circular client_entities array
                var ix = SV_INIT.svs.next_client_entities % SV_INIT.svs.num_client_entities;
                state = SV_INIT.svs.client_entities[ix];

                if (ent.s.number != e)
                {
                    Com.DPrintf("FIXING ENT.S.NUMBER!!!\n");
                    ent.s.number = e;
                }

                //*state = ent.s;
                SV_INIT.svs.client_entities[ix].set(ent.s);

                // don't mark players missiles as solid
                if (ent.owner == client.edict)
                {
                    state.solid = 0;
                }

                SV_INIT.svs.next_client_entities++;
                frame.num_entities++;
            }
        }