private static bool PM_GoodPositionUnscaled(Vector3 pos) { TraceT trace; trace = Trace.CL_Trace(pos, mins, maxs, pos); return(!trace.allsolid); }
/// <summary> /// Moves the player along velocity vector and try to step up. /// </summary> private static void PM_StepSlideMove() { Vector3 start_o, start_v; Vector3 down_o, down_v; TraceT trace; float down_dist, up_dist; Vector3 up, down; start_o = origin; start_v = velocity; PM_StepSlideMove_(); down_o = origin; down_v = velocity; up = start_o; up += new Vector3(0, 18, 0); trace = Trace.CL_Trace(up, mins, maxs, up); if (trace.allsolid) { return; //can't step up } origin = up; velocity = start_v; PM_StepSlideMove_(); //push down the final amount down = origin; down.y -= 18; trace = Trace.CL_Trace(origin, mins, maxs, down); if (!trace.allsolid) { origin = trace.endpos; } up = origin; down_dist = Mathf.Pow(down_o.x - start_o.x, 2) + Mathf.Pow(down_o.z - start_o.z, 2); up_dist = Mathf.Pow(up.x - start_o.x, 2) + Mathf.Pow(up.z - start_o.z, 2); if (down_dist > up_dist || trace.plane == null || trace.plane.normal.y < 0.7f) { origin = down_o; velocity = down_v; return; } //special case blah blah velocity.y = down_v.y; pmd.beginCameraLerp = true; }
/// <summary> /// Check if climbing a ladder or jumping out of water. /// </summary> private static void PM_CheckSpecialMovement() { Vector3 spot; BrushContents cont; Vector3 flatforward; TraceT trace; if (timer > 0) { return; } ladder = false; //check for ladder flatforward = pmd.inForward; flatforward.y = 0; flatforward.Normalize(); spot = origin + flatforward * 1; trace = Trace.CL_Trace(origin, mins, maxs, spot); if ((trace.fraction < 1) && trace.contents.HasFlag(BrushContents.CONTENTS_LADDER)) { ladder = true; } //check for waterjump if (waterlevel != 2) { return; } spot = origin + flatforward * 30; spot.y += 4; cont = Utils.NodePointSearch(BSPFile.headnode, spot).contents; if (!cont.HasFlag(BrushContents.CONTENTS_SOLID)) { return; } spot.y += 16; cont = Utils.NodePointSearch(BSPFile.headnode, spot).contents; if (cont != 0) { return; } //jump out of water velocity = flatforward * 50; velocity.y = 350; pmflags |= PMFlags.PMF_TIME_WATERJUMP; timer = 0.255f; }
/// <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; } }
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); } } }
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); } }
/// <summary> /// Moves the player along velocity vector while clipping it by the collided level geometry. /// </summary> private static void PM_StepSlideMove_() { int bumpcount, numbumps; Vector3 dir; float d; int numplanes; Vector3[] planes = new Vector3[5]; Vector3 primal_velocity; int i, j; TraceT trace; Vector3 end; float time_left; numbumps = 4; primal_velocity = velocity; numplanes = 0; time_left = frametime; for (bumpcount = 0; bumpcount < numbumps; bumpcount++) { end = origin + time_left * velocity; trace = Trace.CL_Trace(origin, mins, maxs, end); if (trace.allsolid) { //entity is trapped in another solid velocity.y = 0; return; } if (trace.fraction > 0) { //actually covered some distance origin = trace.endpos; numplanes = 0; } if (trace.fraction == 1) { break; } //entity touch blah blah time_left -= time_left * trace.fraction; if (numplanes >= 5) { //this shouldn't really happen velocity = Vector3.zero; break; } for (i = 0; i < numplanes; i++) { if (planes[i] != null && Vector3.Dot(trace.plane.normal, planes[i]) > 0.99f) { velocity += trace.plane.normal; break; } } if (i < numplanes) { continue; } planes[numplanes] = trace.plane.normal; numplanes++; //modify original velocity so it parallels all of the clip planes for (i = 0; i < numplanes; i++) { PM_ClipVelocity(velocity, planes[i], out velocity, 1.01f); for (j = 0; j < numplanes; j++) { if (j != i) { if (Vector3.Dot(velocity, planes[j]) < 0) { break; //not ok (lol?) } } } if (j == numplanes) { break; } } if (i != numplanes) { //go along this plane } else { //go along the crease if (numplanes != 2) { velocity = Vector3.zero; break; } dir = Vector3.Cross(planes[0], planes[1]); d = Vector3.Dot(dir, velocity); velocity = dir * d; } if (Vector3.Dot(velocity, primal_velocity) <= 0) { velocity = Vector3.zero; break; } } }
/// <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; } } } }