Ejemplo n.º 1
0
    static void PF_aim()
    {
        edict_t ent   = G_EDICT(q_shared.OFS_PARM0);
        float   speed = G_FLOAT(q_shared.OFS_PARM1);

        Vector3 start = ToVector(ref ent.v.origin);

        start.Z += 20;

        // try sending a trace straight
        Vector3 dir;

        Mathlib.Copy(ref pr_global_struct.v_forward, out dir);
        Vector3 end = start + dir * 2048;
        trace_t tr  = SV_Move(ref start, ref q_shared.ZeroVector, ref q_shared.ZeroVector, ref end, 0, ent);

        if (tr.ent != null && tr.ent.v.takedamage == q_shared.DAMAGE_AIM &&
            (teamplay.value == 0 || ent.v.team <= 0 || ent.v.team != tr.ent.v.team))
        {
            G_VECTOR(ref pr_global_struct.v_forward);
            return;
        }

        // try all possible entities
        Vector3 bestdir  = dir;
        float   bestdist = sv_aim.value;
        edict_t bestent  = null;

        for (int i = 1; i < sv.num_edicts; i++)
        {
            edict_t check = sv.edicts[i];
            if (check.v.takedamage != q_shared.DAMAGE_AIM)
            {
                continue;
            }
            if (check == ent)
            {
                continue;
            }
            if (teamplay.value != 0 && ent.v.team > 0 && ent.v.team == check.v.team)
            {
                continue;       // don't aim at teammate
            }
            v3f tmp;
            Mathlib.VectorAdd(ref check.v.mins, ref check.v.maxs, out tmp);
            Mathlib.VectorMA(ref check.v.origin, 0.5f, ref tmp, out tmp);
            Mathlib.Copy(ref tmp, out end);

            dir = end - start;
            Mathlib.Normalize(ref dir);
            float dist = Vector3.Dot(dir, ToVector(ref pr_global_struct.v_forward));
            if (dist < bestdist)
            {
                continue;       // to far to turn
            }
            tr = SV_Move(ref start, ref q_shared.ZeroVector, ref q_shared.ZeroVector, ref end, 0, ent);
            if (tr.ent == check)
            {   // can shoot at this one
                bestdist = dist;
                bestent  = check;
            }
        }

        if (bestent != null)
        {
            v3f dir2, end2;
            Mathlib.VectorSubtract(ref bestent.v.origin, ref ent.v.origin, out dir2);
            float dist = Mathlib.DotProduct(ref dir2, ref pr_global_struct.v_forward);
            Mathlib.VectorScale(ref pr_global_struct.v_forward, dist, out end2);
            end2.z = dir2.z;
            Mathlib.Normalize(ref end2);
            G_VECTOR(ref end2);
        }
        else
        {
            G_VECTOR(ref bestdir);
        }
    }
Ejemplo n.º 2
0
    public static void SV_WriteEntitiesToClient(edict_t clent, MsgWriter msg)
    {
        // find the client's PVS
        Vector3 org = ToVector(ref clent.v.origin) + ToVector(ref clent.v.view_ofs);

        byte[] pvs = SV_FatPVS(ref org);

        // send over all entities (except the client) that touch the pvs
        for (int e = 1; e < sv.num_edicts; e++)
        {
            edict_t ent = sv.edicts[e];
            // ignore if not touching a PV leaf
            if (ent != clent)   // clent is ALLWAYS sent
            {
                // ignore ents without visible models
                string mname = GetString(ent.v.model);
                if (String.IsNullOrEmpty(mname))
                {
                    continue;
                }

                int i;
                for (i = 0; i < ent.num_leafs; i++)
                {
                    if ((pvs[ent.leafnums[i] >> 3] & (1 << (ent.leafnums[i] & 7))) != 0)
                    {
                        break;
                    }
                }

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

            if (msg.Capacity - msg.Length < 16)
            {
                Con_Printf("packet overflow\n");
                return;
            }

            // send an update
            int bits = 0;
            v3f miss;
            Mathlib.VectorSubtract(ref ent.v.origin, ref ent.baseline.origin, out miss);
            if (miss.x < -0.1f || miss.x > 0.1f)
            {
                bits |= q_shared.U_ORIGIN1;
            }
            if (miss.y < -0.1f || miss.y > 0.1f)
            {
                bits |= q_shared.U_ORIGIN2;
            }
            if (miss.z < -0.1f || miss.z > 0.1f)
            {
                bits |= q_shared.U_ORIGIN3;
            }

            if (ent.v.angles.x != ent.baseline.angles.x)
            {
                bits |= q_shared.U_ANGLE1;
            }

            if (ent.v.angles.y != ent.baseline.angles.y)
            {
                bits |= q_shared.U_ANGLE2;
            }

            if (ent.v.angles.z != ent.baseline.angles.z)
            {
                bits |= q_shared.U_ANGLE3;
            }

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

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

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

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

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

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

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

            //
            // write the message
            //
            msg.MSG_WriteByte(bits | q_shared.U_SIGNAL);

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

            if ((bits & q_shared.U_MODEL) != 0)
            {
                msg.MSG_WriteByte((int)ent.v.modelindex);
            }
            if ((bits & q_shared.U_FRAME) != 0)
            {
                msg.MSG_WriteByte((int)ent.v.frame);
            }
            if ((bits & q_shared.U_COLORMAP) != 0)
            {
                msg.MSG_WriteByte((int)ent.v.colormap);
            }
            if ((bits & q_shared.U_SKIN) != 0)
            {
                msg.MSG_WriteByte((int)ent.v.skin);
            }
            if ((bits & q_shared.U_EFFECTS) != 0)
            {
                msg.MSG_WriteByte((int)ent.v.effects);
            }
            if ((bits & q_shared.U_ORIGIN1) != 0)
            {
                msg.MSG_WriteCoord(ent.v.origin.x);
            }
            if ((bits & q_shared.U_ANGLE1) != 0)
            {
                msg.MSG_WriteAngle(ent.v.angles.x);
            }
            if ((bits & q_shared.U_ORIGIN2) != 0)
            {
                msg.MSG_WriteCoord(ent.v.origin.y);
            }
            if ((bits & q_shared.U_ANGLE2) != 0)
            {
                msg.MSG_WriteAngle(ent.v.angles.y);
            }
            if ((bits & q_shared.U_ORIGIN3) != 0)
            {
                msg.MSG_WriteCoord(ent.v.origin.z);
            }
            if ((bits & q_shared.U_ANGLE3) != 0)
            {
                msg.MSG_WriteAngle(ent.v.angles.z);
            }
        }
    }