Пример #1
0
    //for moving and rotating entities :x
    private static void CM_TransformedBoxTrace(ref TraceT trace, Vector3 start, Vector3 end, Vector3 mins, Vector3 maxs, BSPNode headnode, BrushContents brushmask, Vector3 origin, Vector3 angles)
    {
        Vector3 start_l;
        Vector3 end_l;
        bool    rotated;

        Vector3[] axes = new Vector3[3];

        start_l = start - origin;
        end_l   = end - origin;

        rotated = angles != null;

        if (rotated)
        {
            Utils.AnglesToAxis(angles, out axes[0], out axes[1], out axes[2]);
            start_l = Utils.RotatePoint(start_l, axes);
            end_l   = Utils.RotatePoint(end_l, axes);
        }

        CM_BoxTrace(out trace, start_l, end_l, mins, maxs, headnode, (int)brushmask);

        if (rotated && trace.fraction != 1 && trace.plane != null)
        {
            Utils.TransposeAxis(ref axes);
            trace.plane.normal = Utils.RotatePoint(trace.plane.normal, axes);
        }

        //Carmack: FIXME: offset plane distance? M: wut?

        trace.endpos = Vector3.Lerp(start, end, trace.fraction);
    }
Пример #2
0
    private static void CL_ClipMoveToEntities(Vector3 start, Vector3 mins, Vector3 maxs, Vector3 end, ref TraceT tr)
    {
        TraceT  trace = new TraceT();
        BSPNode headnode;
        //entity blah
        BSPModel cmodel;

        //null check for physicsModels?
        if (BSPFile.physicsModels == null)
        {
            return; //i guess so
        }
        for (int i = 0; i < BSPFile.physicsModels.Count; i++)
        {
            cmodel = BSPFile.physicsModels[i].Bmodel;

            headnode = cmodel.headnode;

            if (tr.allsolid)
            {
                return;
            }

            CM_TransformedBoxTrace(ref trace, start, end, mins, maxs, headnode, BrushContents.MASK_PLAYERSOLID,
                                   BSPFile.physicsModels[i].Ent.MoveOrigin / Globals.scale.Value, BSPFile.physicsModels[i].Ent.MoveAngles);

            CM_ClipEntity(ref tr, ref trace, cmodel);
        }
    }
Пример #3
0
    private static void CM_TestBoxInBrush(Vector3 p1, ref TraceT trace, BSPBrush brush)
    {
        BSPBrushSide[] sides = brush.Sides;
        BSPPlane       plane;
        float          dist, d1;

        for (int i = 0; i < sides.Length; i++)
        {
            plane = sides[i].Plane;

            dist = Vector3.Dot(trace_offsets[plane.Signbits], plane.normal);
            dist = plane.distance - dist;

            d1 = Vector3.Dot(p1, plane.normal) - dist;

            //completely in front of a face, no intersection
            if (d1 > 0)
            {
                return;
            }
        }

        trace.startsolid = trace.allsolid = true;
        trace.fraction   = 0;
        trace.contents   = brush.contents;
    }
Пример #4
0
    private static void CM_ClipEntity(ref TraceT dst, ref TraceT src, BSPModel model)
    {
        dst.allsolid   = src.allsolid;
        dst.startsolid = src.startsolid;

        if (src.fraction < dst.fraction)
        {
            dst.fraction  = src.fraction;
            dst.endpos    = src.endpos;
            dst.plane     = src.plane;
            dst.surface   = src.surface;
            dst.contents |= src.contents;
            dst.clipmodel = model;
        }
    }
Пример #5
0
    //only radius damage is needed
    private void Hit(TraceT trace)
    {
        //Console.DebugLog("Projectile hit at " + trace.endpos);

        Vector3 projectilePos = transform.position / scale;
        Vector3 playerPos     = PlayerState.currentOrigin;

        if ((projectilePos - playerPos).magnitude > damageRadius)
        {
            Explode();
            return;
        }

        Vector3 v = PlayerState.mins + PlayerState.maxs;

        v = playerPos + v * 0.5f;

        v = projectilePos - v;
        //Console.DebugLog("V is " + v.magnitude);

#if DEBUG
        float dmg = radiusDamage;
        if (Cvar.Exists("debug_rocketmult"))
        {
            dmg *= Cvar.Value("debug_rocketmult");
        }
        float knockback = dmg - 0.5f * v.magnitude;
#else
        float knockback = radiusDamage - 0.5f * v.magnitude;
#endif
        knockback *= 0.5f;

        if (knockback > 0)
        {
            Vector3 knockDir = playerPos - projectilePos;
            float   mass     = 200;

            Vector3 velocity = knockDir.normalized * (1600 * knockback / mass);
            //Console.DebugLog("Knockback force " + velocity.magnitude);

            PlayerState.addVelocities += velocity;
        }

        Explode();
    }
Пример #6
0
    /// <summary>
    /// Sets player extents and viewheight.
    /// </summary>
    private static void PM_CheckDuck()
    {
        mins.x = -16;
        mins.z = -16;

        maxs.x = 16;
        maxs.z = 16;

        mins.y = -24;

        if (InputContainer.upMove < 0 && pmflags.HasFlag(PMFlags.PMF_ON_GROUND))
        {
            pmflags            |= PMFlags.PMF_DUCKED;
            pmd.beginCameraLerp = true;
        }
        else
        {
            //stand up if possible
            if (pmflags.HasFlag(PMFlags.PMF_DUCKED))
            {
                //try to stand up
                maxs.y = 32;

                TraceT trace = Trace.CL_Trace(origin, mins, maxs, origin);
                if (!trace.allsolid)
                {
                    pmflags &= ~PMFlags.PMF_DUCKED;
                }
            }
        }

        if (pmflags.HasFlag(PMFlags.PMF_DUCKED))
        {
            maxs.y     = 4;
            viewheight = -2;
        }
        else
        {
            maxs.y     = 32;
            viewheight = 22;
        }
    }
Пример #7
0
    private void Fire_c(string[] args)
    {
        if (!Cvar.Boolean("console_open"))
        {
            if (args.Length > 0)
            {
                return;
            }

            Weapon w = weaponSlots[currentWeapon];

            if (!w)
            {
                return;
            }

            if (!w.IsCooldown)
            {
                float scale = Globals.scale.Value;

                Projectile p = Instantiate(w.WeaponTemplate.ProjectileModel);
                p.transform.position = w.transform.position + w.transform.forward * 0.2f;

                Vector3 far      = (playerCamera.transform.position / scale) + playerCamera.transform.forward * 10000;
                TraceT  farTrace = Trace.CL_Trace(playerCamera.transform.position / scale, Vector3.zero, Vector3.zero, far);

                if (farTrace.fraction < 1)
                {
                    p.transform.LookAt(farTrace.endpos * scale); //this will always happen if map is sealed and the player is inside the map volume
                }
                else
                {
                    p.transform.forward = w.transform.forward;
                }
                p.speed        = w.WeaponTemplate.speed;
                p.damage       = w.WeaponTemplate.damage;
                p.radiusDamage = w.WeaponTemplate.radiusDamage;
                p.damageRadius = w.WeaponTemplate.damageRadius;
                w.SetCooldown(w.WeaponTemplate.cooldown);
            }
        }
    }
Пример #8
0
    private void Update()
    {
        if (exploding)
        {
            return;
        }

        aliveTime += Time.unscaledDeltaTime;

        //stop exisiting at 8 secs...
        //TODO: add an explosion?
        if (aliveTime > 8)
        {
            Explode();
            return;
        }

        Vector3 start = transform.position / scale;
        Vector3 end   = start + transform.forward * speed * Time.unscaledDeltaTime;

        TraceT trace = Trace.CL_Trace(start, Vector3.zero, Vector3.zero, end);

        if (trace.allsolid)
        {
            Hit(trace);
            return; //shouldnt happen, add destroy here?
        }

        //move up to trace end
        transform.position = trace.endpos * scale;

        if (trace.fraction < 1)
        {
            Hit(trace);
        }
    }
Пример #9
0
    private static void CM_BoxTrace(out TraceT trace, Vector3 start, Vector3 end, Vector3 mins, Vector3 maxs, BSPNode headnode, int brushmask)
    {
        checkcount++;
        trace_trace = new TraceT
        {
            fraction = 1,
            surface  = new SurfaceT()
        };

        trace          = trace_trace;
        trace_start    = start;
        trace_end      = end;
        trace_contents = brushmask;

        Vector3[] bounds = new Vector3[]
        {
            mins, maxs
        };

        for (int k = 0; k < 8; k++)
        {
            trace_offsets[k] = new Vector3();
        }

        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                trace_offsets[i][j] = bounds[i >> j & 1][j];
            }
        }

        //check for position test special case
        if (start == end)
        {
            BSPLeaf[] leafs = new BSPLeaf[1024];
            int       numleafs;
            Vector3   c1, c2;

            //M increase bounds size
            c1 = start + mins - Vector3.one;
            c2 = start + maxs + Vector3.one;

            numleafs = CM_BoxLeafs_Headnode(c1, c2, ref leafs, 1024, headnode, out BSPNode topnode);

            for (int i = 0; i < numleafs; i++)
            {
                CM_TestInLeaf(leaf_list[i]);

                if (trace_trace.allsolid)
                {
                    break;
                }
            }

            trace_trace.endpos = start;
            return;
        }

        //check for point special case
        if (mins == Vector3.zero && maxs == Vector3.zero)
        {
            trace_ispoint = true;
            trace_extents = Vector3.zero;
        }
        else
        {
            trace_ispoint = false;
            trace_extents = new Vector3(Mathf.Max(-mins[0], maxs[0]), Mathf.Max(-mins[1], maxs[1]), Mathf.Max(-mins[2], maxs[2]));
        }

        //general sweeping through world
        CM_RecursiveHullCheck(headnode, 0, 1, start, end);

        if (trace_trace.fraction == 1)
        {
            trace_trace.endpos = end;
        }
        else
        {
            trace_trace.endpos = Vector3.Lerp(start, end, trace_trace.fraction);
        }
    }
Пример #10
0
    /// <summary>
    /// Checks for intersection with a brush during a moving trace.
    /// </summary>
    /// <param name="p1">Trace start.</param>
    /// <param name="p2">Trace end.</param>
    /// <param name="trace">Data struct.</param>
    /// <param name="brush">Brush to test against.</param>
    private static void CM_ClipBoxToBrush(Vector3 p1, Vector3 p2, ref TraceT trace, BSPBrush brush)
    {
        int          i;
        BSPPlane     plane;
        BSPPlane     clipplane = new BSPPlane(); //initialize this to keep c# happy...
        float        dist;
        float        enterfrac, leavefrac;
        float        d1, d2;
        bool         getout, startout;
        bool         hasclip = false;
        bool         haslead = false;
        float        f;
        BSPBrushSide leadside = new BSPBrushSide(); //initialize this to keep c# happy...

        BSPBrushSide[] sides;

        if (brush.numsides == 0)
        {
            return;
        }

        sides = brush.Sides;

        enterfrac = -1;
        leavefrac = 1;

        getout   = false;   //gets out of the brush
        startout = false;   //starts inside the brush
        for (i = 0; i < brush.numsides; i++)
        {
            plane = sides[i].Plane; //we only need plane for each side

            //get plane to bounds point distance
            if (!trace_ispoint)
            {
                //bounding box trace
                dist = Vector3.Dot(trace_offsets[plane.Signbits], plane.normal);
                dist = plane.distance - dist;
            }
            else
            {
                //point trace
                dist = plane.distance;
            }

            //get distances for start and end of the trace
            d1 = Vector3.Dot(p1, plane.normal) - dist; //start
            d2 = Vector3.Dot(p2, plane.normal) - dist; //end

            if (d2 > 0)
            {
                getout = true; //endpoint is not in solid
            }
            if (d1 > 0)
            {
                startout = true; //starts outside
            }

            //if completely in front of a face, no intersection
            if (d1 > 0 && d2 >= d1)
            {
                return; //a single face plane that is not crossed while tracing means that we never hit that brush
            }

            //?
            if (d1 <= 0 && d2 <= 0)
            {
                continue;
            }

            //crosses face
            if (d1 > d2)
            {
                //enter
                f = (d1 - DIST_EPSILON) / (d1 - d2); //fraction of the distance covered before hitting a side
                if (f > enterfrac)
                {
                    enterfrac = f;
                    clipplane = plane;
                    hasclip   = true; //plane clips the trace
                    leadside  = sides[i];
                    haslead   = true; //could be combined with hasclip? writes flags for the collided face
                }
            }
            else
            {
                //leave
                f = (d1 + DIST_EPSILON) / (d1 - d2);
                if (f < leavefrac)
                {
                    leavefrac = f;
                }
            }
        }

        //startout wasn't true for any face
        if (!startout)
        {
            //original point was inside brush
            trace.startsolid = true;
            if (!getout)
            {
                trace.allsolid = true;
                //map_allsolid_bug
                trace.fraction = 0;
                trace.contents = brush.contents;
            }
            return;
        }

        //after testing all faces we need to see which test went further
        if (enterfrac < leavefrac)
        {
            //only write the test if the brush was closer than any brushes hit before
            if (enterfrac > -1 && enterfrac < trace.fraction)
            {
                if (enterfrac < 0)
                {
                    enterfrac = 0;
                }
                trace.fraction = enterfrac;
                if (hasclip)
                {
                    trace.plane = clipplane;
                }
                if (haslead)
                {
                    if (leadside.HasTexInfo)
                    {
                        trace.surface = leadside.TexInfo.Surface;
                    }
                }
                trace.contents = brush.contents;
            }
        }
    }