private bool BrushHasFlag(int modelIndex, int solidNumber, BrushContents flag) { var model = _bsp.Models[modelIndex]; var node = _bsp.Nodes[model.HeadNode]; foreach (var leafIndex in BspUtils.GetNodeLeafs(_bsp, node)) { var leaf = _bsp.Leaves[leafIndex]; var first = leaf.FirstLeafBrush; var last = leaf.FirstLeafBrush + leaf.NumLeafBrushes; var idx = first + solidNumber; if (idx < last) { return(_bsp.Brushes[_bsp.LeafBrushes[idx]].Contents.HasFlag(flag)); } } return(false); }
/// <summary> /// Checks if player is standing on the ground and if he is in a water body. /// </summary> private static void PM_CategorizePosition() { TraceT trace; BrushContents cont; int sample1, sample2; if (velocity.y > 180) { groundentity = false; pmflags &= ~PMFlags.PMF_ON_GROUND; } else { trace = Trace.CL_Trace(origin, mins, maxs, origin - new Vector3(0, 0.25f, 0)); groundplane = trace.plane; groundsurface = trace.surface; groundcontents = trace.contents; if (trace.plane == null || (trace.plane.normal.y < 0.7f && !trace.startsolid)) { groundentity = false; pmflags &= ~PMFlags.PMF_ON_GROUND; } else { groundentity = true; //hitting solid ground will end a waterjump if (pmflags.HasFlag(PMFlags.PMF_TIME_WATERJUMP)) { pmflags &= ~PMFlags.PMF_TIME_WATERJUMP; timer = 0; } if (!pmflags.HasFlag(PMFlags.PMF_ON_GROUND)) { //just hit the ground pmflags |= PMFlags.PMF_ON_GROUND; } } } //get waterlevel waterlevel = 0; watertype = 0; sample2 = (int)viewheight - (int)mins.y; sample1 = sample2 / 2; Vector3 point = origin; point.y = origin.y + mins.y + 1; cont = Utils.NodePointSearch(BSPFile.headnode, point).contents; if ((cont & BrushContents.MASK_WATER) != 0) { watertype = cont; waterlevel = 1; point.y = origin.y + mins.y + sample1; cont = Utils.NodePointSearch(BSPFile.headnode, point).contents; if ((cont & BrushContents.MASK_WATER) != 0) { waterlevel = 2; point.y = origin.y + mins.y + sample2; cont = Utils.NodePointSearch(BSPFile.headnode, point).contents; if ((cont & BrushContents.MASK_WATER) != 0) { waterlevel = 3; } } } }
//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); }