// angledelta() static float AngleDelta(float a) { a = Mathlib.AngleMod(a); if (a > 180) { a -= 360; } return(a); }
// CL_AdjustAngles // // Moves the local angle positions static void AdjustAngles() { float speed = (float)Host.FrameTime; if (ClientInput.SpeedBtn.IsDown) { speed *= _AngleSpeedKey.Value; } if (!ClientInput.StrafeBtn.IsDown) { cl.viewangles.Y -= speed * _YawSpeed.Value * KeyState(ref ClientInput.RightBtn); cl.viewangles.Y += speed * _YawSpeed.Value * KeyState(ref ClientInput.LeftBtn); cl.viewangles.Y = Mathlib.AngleMod(cl.viewangles.Y); } if (ClientInput.KLookBtn.IsDown) { View.StopPitchDrift(); cl.viewangles.X -= speed * _PitchSpeed.Value * KeyState(ref ClientInput.ForwardBtn); cl.viewangles.X += speed * _PitchSpeed.Value * KeyState(ref ClientInput.BackBtn); } float up = KeyState(ref ClientInput.LookUpBtn); float down = KeyState(ref ClientInput.LookDownBtn); cl.viewangles.X -= speed * _PitchSpeed.Value * up; cl.viewangles.X += speed * _PitchSpeed.Value * down; if (up != 0 || down != 0) { View.StopPitchDrift(); } if (cl.viewangles.X > 80) { cl.viewangles.X = 80; } if (cl.viewangles.X < -70) { cl.viewangles.X = -70; } if (cl.viewangles.Z > 50) { cl.viewangles.Z = 50; } if (cl.viewangles.Z < -50) { cl.viewangles.Z = -50; } }
/* * ============== * PF_changeyaw * * This was a major timewaster in progs, so it was converted to C * ============== */ public static void PF_changeyaw() { edict_t ent = Server.ProgToEdict(Progs.GlobalStruct.self); float current = Mathlib.AngleMod(ent.v.angles.y); float ideal = ent.v.ideal_yaw; float speed = ent.v.yaw_speed; if (current == ideal) { return; } float move = ideal - current; if (ideal > current) { if (move >= 180) { move = move - 360; } } else { if (move <= -180) { move = move + 360; } } if (move > 0) { if (move > speed) { move = speed; } } else { if (move < -speed) { move = -speed; } } ent.v.angles.y = Mathlib.AngleMod(current + move); }
/// <summary> /// CL_RelinkEntities /// </summary> static void RelinkEntities() { // determine partial update time float frac = LerpPoint(); NumVisEdicts = 0; // // interpolate player info // cl.velocity = cl.mvelocity[1] + frac * (cl.mvelocity[0] - cl.mvelocity[1]); if (cls.demoplayback) { // interpolate the angles Vector3 angleDelta = cl.mviewangles[0] - cl.mviewangles[1]; Mathlib.CorrectAngles180(ref angleDelta); cl.viewangles = cl.mviewangles[1] + frac * angleDelta; } float bobjrotate = Mathlib.AngleMod(100 * cl.time); // start on the entity after the world for (int i = 1; i < cl.num_entities; i++) { entity_t ent = _Entities[i]; if (ent.model == null) { // empty slot if (ent.forcelink) { Render.RemoveEfrags(ent); // just became empty } continue; } // if the object wasn't included in the last packet, remove it if (ent.msgtime != cl.mtime[0]) { ent.model = null; ent.FrameStartTime = 0; ent.TranslateStartTime = 0; ent.RotateStartTime = 0; continue; } Vector3 oldorg = ent.origin; if (ent.forcelink) { // the entity was not updated in the last message // so move to the final spot ent.origin = ent.msg_origins[0]; ent.angles = ent.msg_angles[0]; } else { // if the delta is large, assume a teleport and don't lerp float f = frac; Vector3 delta = ent.msg_origins[0] - ent.msg_origins[1]; if (Math.Abs(delta.X) > 100 || Math.Abs(delta.Y) > 100 || Math.Abs(delta.Z) > 100) { f = 1; // assume a teleportation, not a motion } // [email protected]: model transform interpolation // interpolation should be reset in the event of a large delta if (f >= 1) { ent.FrameStartTime = 0; ent.TranslateStartTime = 0; ent.RotateStartTime = 0; } // interpolate the origin and angles ent.origin = ent.msg_origins[1] + f * delta; Vector3 angleDelta = ent.msg_angles[0] - ent.msg_angles[1]; Mathlib.CorrectAngles180(ref angleDelta); ent.angles = ent.msg_angles[1] + f * angleDelta; } // rotate binary objects locally if ((ent.model.flags & EF.EF_ROTATE) != 0) { ent.angles.Y = bobjrotate; } if ((ent.effects & EntityEffects.EF_BRIGHTFIELD) != 0) { Render.EntityParticles(ent); } if ((ent.effects & EntityEffects.EF_MUZZLEFLASH) != 0) { dlight_t dl = AllocDlight(i); dl.origin = ent.origin; dl.origin.Z += 16; Vector3 fv, rv, uv; Mathlib.AngleVectors(ref ent.angles, out fv, out rv, out uv); dl.origin += fv * 18; dl.radius = 200 + (Sys.Random() & 31); dl.minlight = 32; dl.die = (float)cl.time + 0.1f; } if ((ent.effects & EntityEffects.EF_BRIGHTLIGHT) != 0) { dlight_t dl = AllocDlight(i); dl.origin = ent.origin; dl.origin.Z += 16; dl.radius = 400 + (Sys.Random() & 31); dl.die = (float)cl.time + 0.001f; } if ((ent.effects & EntityEffects.EF_DIMLIGHT) != 0) { dlight_t dl = AllocDlight(i); dl.origin = ent.origin; dl.radius = 200 + (Sys.Random() & 31); dl.die = (float)cl.time + 0.001f; } if ((ent.model.flags & EF.EF_GIB) != 0) { Render.RocketTrail(ref oldorg, ref ent.origin, 2); } else if ((ent.model.flags & EF.EF_ZOMGIB) != 0) { Render.RocketTrail(ref oldorg, ref ent.origin, 4); } else if ((ent.model.flags & EF.EF_TRACER) != 0) { Render.RocketTrail(ref oldorg, ref ent.origin, 3); } else if ((ent.model.flags & EF.EF_TRACER2) != 0) { Render.RocketTrail(ref oldorg, ref ent.origin, 5); } else if ((ent.model.flags & EF.EF_ROCKET) != 0) { Render.RocketTrail(ref oldorg, ref ent.origin, 0); dlight_t dl = AllocDlight(i); dl.origin = ent.origin; dl.radius = 200; dl.die = (float)cl.time + 0.01f; } else if ((ent.model.flags & EF.EF_GRENADE) != 0) { Render.RocketTrail(ref oldorg, ref ent.origin, 1); } else if ((ent.model.flags & EF.EF_TRACER3) != 0) { Render.RocketTrail(ref oldorg, ref ent.origin, 6); } ent.forcelink = false; if (i == cl.viewentity && !Chase.IsActive) { continue; } if (NumVisEdicts < MAX_VISEDICTS) { _VisEdicts[NumVisEdicts] = ent; NumVisEdicts++; } } }
/// <summary> /// SV_NewChaseDir /// </summary> static void NewChaseDir(edict_t actor, edict_t enemy, float dist) { float olddir = Mathlib.AngleMod((int)(actor.v.ideal_yaw / 45) * 45); float turnaround = Mathlib.AngleMod(olddir - 180); float deltax = enemy.v.origin.x - actor.v.origin.x; float deltay = enemy.v.origin.y - actor.v.origin.y; v3f d; if (deltax > 10) { d.y = 0; } else if (deltax < -10) { d.y = 180; } else { d.y = DI_NODIR; } if (deltay < -10) { d.z = 270; } else if (deltay > 10) { d.z = 90; } else { d.z = DI_NODIR; } // try direct route float tdir; if (d.y != DI_NODIR && d.z != DI_NODIR) { if (d.y == 0) { tdir = (d.z == 90 ? 45 : 315); } else { tdir = (d.z == 90 ? 135 : 215); } if (tdir != turnaround && StepDirection(actor, tdir, dist)) { return; } } // try other directions if (((Sys.Random() & 3) & 1) != 0 || Math.Abs(deltay) > Math.Abs(deltax)) { tdir = d.y; d.y = d.z; d.z = tdir; } if (d.y != DI_NODIR && d.y != turnaround && StepDirection(actor, d.y, dist)) { return; } if (d.z != DI_NODIR && d.z != turnaround && StepDirection(actor, d.z, dist)) { return; } // there is no direct path to the player, so pick another direction if (olddir != DI_NODIR && StepDirection(actor, olddir, dist)) { return; } if ((Sys.Random() & 1) != 0) //randomly determine direction of search { for (tdir = 0; tdir <= 315; tdir += 45) { if (tdir != turnaround && StepDirection(actor, tdir, dist)) { return; } } } else { for (tdir = 315; tdir >= 0; tdir -= 45) { if (tdir != turnaround && StepDirection(actor, tdir, dist)) { return; } } } if (turnaround != DI_NODIR && StepDirection(actor, turnaround, dist)) { return; } actor.v.ideal_yaw = olddir; // can't move // if a bridge was pulled out from underneath a monster, it may not have // a valid standing position at all if (!CheckBottom(actor)) { FixCheckBottom(actor); } }