예제 #1
0
        /*
         * ==================
         * SV_RunClients
         * ==================
         */
        public static void SV_RunClients()
        {
            int i;

            for (i = 0; i < svs.maxclients; i++)
            {
                host.host_client = svs.clients[i];
                if (!host.host_client.active)
                {
                    continue;
                }

                sv_player = host.host_client.edict;

                if (!SV_ReadClientMessage())
                {
                    continue;
                }

                if (!host.host_client.spawned)
                {
                    continue;
                }

                // always pause in single player if in console or menus
                if (!sv.paused && (svs.maxclients > 1 || keys.key_dest == keys.keydest_t.key_game))
                {
                    SV_ClientThink();
                }
            }
        }
예제 #2
0
        /*
        ==================
        SV_RunClients
        ==================
        */
        public static void SV_RunClients()
        {
            int				i;

            for (i=0 ; i<svs.maxclients ; i++)
            {
                host.host_client = svs.clients[i];
                if (!host.host_client.active)
                    continue;

                sv_player = host.host_client.edict;

                if (!SV_ReadClientMessage ())
                {
                    continue;
                }

                if (!host.host_client.spawned)
                {
                    continue;
                }

            // always pause in single player if in console or menus
                if (!sv.paused && (svs.maxclients > 1 || keys.key_dest == keys.keydest_t.key_game) )
                    SV_ClientThink ();
            }
        }
예제 #3
0
        /*
        ============
        SV_PushMove

        ============
        */
        static void SV_PushMove(prog.edict_t pusher, Double movetime)
        {
            int			i, e;
            prog.edict_t		check, block;
            double[]		mins = new double[3] {0, 0, 0}, maxs = new double[3] {0, 0, 0}, move = new double[3] {0, 0, 0};
            double[]		entorig = new double[3] {0, 0, 0}, pushorig = new double[3] {0, 0, 0};
            int			num_moved;
            prog.edict_t[] moved_edict = new prog.edict_t[quakedef.MAX_EDICTS];
            double[][]		moved_from = new double[quakedef.MAX_EDICTS][];

            if (pusher.v.velocity[0]==0 && pusher.v.velocity[1]==0 && pusher.v.velocity[2]==0)
            {
            pusher.v.ltime += movetime;
            return;
            }

            for (i=0 ; i<3 ; i++)
            {
            move[i] = pusher.v.velocity[i] * movetime;
            mins[i] = pusher.v.absmin[i] + move[i];
            maxs[i] = pusher.v.absmax[i] + move[i];
            }

            mathlib.VectorCopy (pusher.v.origin, pushorig);

            // move the pusher to it's final position

            mathlib.VectorAdd (pusher.v.origin, move, pusher.v.origin);
            pusher.v.ltime += movetime;
            world.SV_LinkEdict (pusher, false);

            // see if any solid entities are inside the final position
            num_moved = 0;
            check = prog.NEXT_EDICT(sv.edicts[0]);
            for (e=1 ; e<sv.num_edicts ; e++, check = prog.NEXT_EDICT(check))
            {
            if (check.free)
            continue;
            //Debug.WriteLine(string.Format("e: {0} movetype:{1}", e, (int)check.v.movetype));

            if (check.v.movetype == MOVETYPE_PUSH
            || check.v.movetype == MOVETYPE_NONE

            || check.v.movetype == MOVETYPE_NOCLIP)
            continue;

            // if the entity is standing on the pusher, it will definately be moved
            if ( ! ( ((int)check.v.flags & FL_ONGROUND) != 0
            && prog.PROG_TO_EDICT(check.v.groundentity) == pusher) )
            {
            if ( check.v.absmin[0] >= maxs[0]
            || check.v.absmin[1] >= maxs[1]
            || check.v.absmin[2] >= maxs[2]
            || check.v.absmax[0] <= mins[0]
            || check.v.absmax[1] <= mins[1]
            || check.v.absmax[2] <= mins[2] )
                continue;

            // see if the ent's bbox is inside the pusher's final position
            if (world.SV_TestEntityPosition (check) != null)
                continue;
            }

            // remove the onground flag for non-players
            if (check.v.movetype != MOVETYPE_WALK)
            check.v.flags = (int)check.v.flags & ~FL_ONGROUND;

            for (int j = 0; j < moved_from.Length; j++)
            {
            moved_from[j] = new double[3] {0, 0, 0};
            }

            mathlib.VectorCopy (check.v.origin, entorig);
            mathlib.VectorCopy (check.v.origin, moved_from[num_moved]);
            moved_edict[num_moved] = check;
            num_moved++;

            // try moving the contacted entity
            pusher.v.solid = SOLID_NOT;
            SV_PushEntity (check, move);
            pusher.v.solid = SOLID_BSP;

            // if it is still inside the pusher, block
            block = world.SV_TestEntityPosition (check);
            if (block != null)
            {	// fail the move
            if (check.v.mins[0] == check.v.maxs[0])
                continue;
            if (check.v.solid == SOLID_NOT || check.v.solid == SOLID_TRIGGER)
            {	// corpse
                check.v.mins[0] = check.v.mins[1] = 0;
                mathlib.VectorCopy (check.v.mins, check.v.maxs);
                continue;
            }

            mathlib.VectorCopy (entorig, check.v.origin);
            world.SV_LinkEdict (check, true);

            mathlib.VectorCopy (pushorig, pusher.v.origin);
            world.SV_LinkEdict (pusher, false);
            pusher.v.ltime -= movetime;

            // if the pusher has a "blocked" function, call it
            // otherwise, just stay in place until the obstacle is gone
            if (pusher.v.blocked != null)
            {
                prog.pr_global_struct[0].self = prog.EDICT_TO_PROG(pusher);
               prog.pr_global_struct[0].other = prog.EDICT_TO_PROG(check);
                prog.PR_ExecuteProgram (prog.pr_functions[pusher.v.blocked]);
            }

            // move back any entities we already moved
            for (i=0 ; i<num_moved ; i++)
            {
                mathlib.VectorCopy (moved_from[i], moved_edict[i].v.origin);
                world.SV_LinkEdict (moved_edict[i], false);
            }
            return;
            }
            }
        }
예제 #4
0
        /*
         * ==================
         * SV_WriteClientdataToMessage
         *
         * ==================
         */
        public static void SV_WriteClientdataToMessage(prog.edict_t ent, common.sizebuf_t msg)
        {
            int bits;
            int i;

            prog.edict_t other;
            int          items;

            //
            // send a damage message
            //
            if (ent.v.dmg_take != 0 || ent.v.dmg_save != 0)
            {
                other = prog.PROG_TO_EDICT(ent.v.dmg_inflictor);
                common.MSG_WriteByte(msg, net.svc_damage);
                common.MSG_WriteByte(msg, (int)ent.v.dmg_save);
                common.MSG_WriteByte(msg, (int)ent.v.dmg_take);
                for (i = 0; i < 3; i++)
                {
                    common.MSG_WriteCoord(msg, other.v.origin[i] + 0.5 * (other.v.mins[i] + other.v.maxs[i]));
                }

                ent.v.dmg_take = 0;
                ent.v.dmg_save = 0;
            }

            //
            // send the current viewpos offset from the view entity
            //
            SV_SetIdealPitch();                 // how much to look up / down ideally

            // a fixangle might get lost in a dropped packet.  Oh well.
            if (ent.v.fixangle != 0)
            {
                common.MSG_WriteByte(msg, net.svc_setangle);
                for (i = 0; i < 3; i++)
                {
                    common.MSG_WriteAngle(msg, ent.v.angles[i]);
                }
                ent.v.fixangle = 0;
            }

            bits = 0;

            if (ent.v.view_ofs[2] != net.DEFAULT_VIEWHEIGHT)
            {
                bits |= net.SU_VIEWHEIGHT;
            }

            if (ent.v.idealpitch != 0)
            {
                bits |= net.SU_IDEALPITCH;
            }

            // stuff the sigil bits into the high bits of items for sbar, or else
            // mix in items2
            //val = GetEdictFieldValue(ent, "items2");

            /*if (val)
             *      items = (int)ent->v.items | ((int)val->_float << 23);
             * else*/
            items = (int)ent.v.items | ((int)prog.pr_global_struct[0].serverflags << 28);

            bits |= net.SU_ITEMS;

            if (((int)ent.v.flags & FL_ONGROUND) != 0)
            {
                bits |= net.SU_ONGROUND;
            }

            if (ent.v.waterlevel >= 2)
            {
                bits |= net.SU_INWATER;
            }

            for (i = 0; i < 3; i++)
            {
                if (ent.v.punchangle[i] != 0)
                {
                    bits |= (net.SU_PUNCH1 << i);
                }
                if (ent.v.velocity[i] != 0)
                {
                    bits |= (net.SU_VELOCITY1 << i);
                }
            }

            if (ent.v.weaponframe != 0)
            {
                bits |= net.SU_WEAPONFRAME;
            }

            if (ent.v.armorvalue != 0)
            {
                bits |= net.SU_ARMOR;
            }

            //	if (ent.v.weapon != 0)
            bits |= net.SU_WEAPON;

            // send the data

            common.MSG_WriteByte(msg, net.svc_clientdata);
            common.MSG_WriteShort(msg, bits);

            if ((bits & net.SU_VIEWHEIGHT) != 0)
            {
                common.MSG_WriteChar(msg, (int)ent.v.view_ofs[2]);
            }

            if ((bits & net.SU_IDEALPITCH) != 0)
            {
                common.MSG_WriteChar(msg, (int)ent.v.idealpitch);
            }

            for (i = 0; i < 3; i++)
            {
                if ((bits & (net.SU_PUNCH1 << i)) != 0)
                {
                    common.MSG_WriteChar(msg, (int)ent.v.punchangle[i]);
                }
                if ((bits & (net.SU_VELOCITY1 << i)) != 0)
                {
                    common.MSG_WriteChar(msg, (int)ent.v.velocity[i] / 16);
                }
            }

            // [always sent]	if (bits & SU_ITEMS)
            common.MSG_WriteLong(msg, items);

            if ((bits & net.SU_WEAPONFRAME) != 0)
            {
                common.MSG_WriteByte(msg, (int)ent.v.weaponframe);
            }
            if ((bits & net.SU_ARMOR) != 0)
            {
                common.MSG_WriteByte(msg, (int)ent.v.armorvalue);
            }
            if ((bits & net.SU_WEAPON) != 0)
            {
                common.MSG_WriteByte(msg, SV_ModelIndex(prog.pr_string(ent.v.weaponmodel)));
            }

            common.MSG_WriteShort(msg, (int)ent.v.health);
            common.MSG_WriteByte(msg, (int)ent.v.currentammo);
            common.MSG_WriteByte(msg, (int)ent.v.ammo_shells);
            common.MSG_WriteByte(msg, (int)ent.v.ammo_nails);
            common.MSG_WriteByte(msg, (int)ent.v.ammo_rockets);
            common.MSG_WriteByte(msg, (int)ent.v.ammo_cells);

            if (common.standard_quake)
            {
                common.MSG_WriteByte(msg, (int)ent.v.weapon);
            }
            else
            {
                for (i = 0; i < 32; i++)
                {
                    if ((((int)ent.v.weapon) & (1 << i)) != 0)
                    {
                        common.MSG_WriteByte(msg, i);
                        break;
                    }
                }
            }
        }
예제 #5
0
        /*
         * =============
         * SV_WriteEntitiesToClient
         *
         * =============
         */
        static void SV_WriteEntitiesToClient(prog.edict_t clent, common.sizebuf_t msg)
        {
            int e, i;
            int bits;

            double[] org = new double[3];
            double   miss;

            prog.edict_t ent;

            // send over all entities (excpet the client) that touch the pvs
            for (e = 1; e < sv.num_edicts; e++)
            {
                ent = sv.edicts[e];

                // ignore if not touching a PV leaf
                if (ent != clent)               // clent is ALLWAYS sent
                {
                    // ignore ents without visible models
                    if (ent.v.modelindex == 0 || prog.pr_string(ent.v.model) == null)
                    {
                        continue;
                    }
                }

                if (msg.maxsize - msg.cursize < 16)
                {
                    console.Con_Printf("packet overflow\n");
                    return;
                }

                // send an update
                bits = 0;

                for (i = 0; i < 3; i++)
                {
                    miss = ent.v.origin[i] - ent.baseline.origin[i];
                    if (miss < -0.1 || miss > 0.1)
                    {
                        bits |= net.U_ORIGIN1 << i;
                    }
                }

                if (ent.v.angles[0] != ent.baseline.angles[0])
                {
                    bits |= net.U_ANGLE1;
                }

                if (ent.v.angles[1] != ent.baseline.angles[1])
                {
                    bits |= net.U_ANGLE2;
                }

                if (ent.v.angles[2] != ent.baseline.angles[2])
                {
                    bits |= net.U_ANGLE3;
                }

                if (ent.v.movetype == MOVETYPE_STEP)
                {
                    bits |= net.U_NOLERP;       // don't mess up the step animation
                }
                if (ent.baseline.colormap != ent.v.colormap)
                {
                    bits |= net.U_COLORMAP;
                }

                if (ent.baseline.skin != ent.v.skin)
                {
                    bits |= net.U_SKIN;
                }

                if (ent.baseline.frame != ent.v.frame)
                {
                    bits |= net.U_FRAME;
                }

                if (ent.baseline.effects != ent.v.effects)
                {
                    bits |= net.U_EFFECTS;
                }

                if (ent.baseline.modelindex != ent.v.modelindex)
                {
                    bits |= net.U_MODEL;
                }

                if (e >= 256)
                {
                    bits |= net.U_LONGENTITY;
                }

                if (bits >= 256)
                {
                    bits |= net.U_MOREBITS;
                }

                //
                // write the message
                //
                common.MSG_WriteByte(msg, bits | net.U_SIGNAL);

                if ((bits & net.U_MOREBITS) != 0)
                {
                    common.MSG_WriteByte(msg, bits >> 8);
                }
                if ((bits & net.U_LONGENTITY) != 0)
                {
                    common.MSG_WriteShort(msg, e);
                }
                else
                {
                    common.MSG_WriteByte(msg, e);
                }

                if ((bits & net.U_MODEL) != 0)
                {
                    common.MSG_WriteByte(msg, (int)ent.v.modelindex);
                }
                if ((bits & net.U_FRAME) != 0)
                {
                    common.MSG_WriteByte(msg, (int)ent.v.frame);
                }
                if ((bits & net.U_COLORMAP) != 0)
                {
                    common.MSG_WriteByte(msg, (int)ent.v.colormap);
                }
                if ((bits & net.U_SKIN) != 0)
                {
                    common.MSG_WriteByte(msg, (int)ent.v.skin);
                }
                if ((bits & net.U_EFFECTS) != 0)
                {
                    common.MSG_WriteByte(msg, (int)ent.v.effects);
                }
                if ((bits & net.U_ORIGIN1) != 0)
                {
                    common.MSG_WriteCoord(msg, ent.v.origin[0]);
                }
                if ((bits & net.U_ANGLE1) != 0)
                {
                    common.MSG_WriteAngle(msg, ent.v.angles[0]);
                }
                if ((bits & net.U_ORIGIN2) != 0)
                {
                    common.MSG_WriteCoord(msg, ent.v.origin[1]);
                }
                if ((bits & net.U_ANGLE2) != 0)
                {
                    common.MSG_WriteAngle(msg, ent.v.angles[1]);
                }
                if ((bits & net.U_ORIGIN3) != 0)
                {
                    common.MSG_WriteCoord(msg, ent.v.origin[2]);
                }
                if ((bits & net.U_ANGLE3) != 0)
                {
                    common.MSG_WriteAngle(msg, ent.v.angles[2]);
                }
            }
        }