/// <summary> /// SV_ReadClientMove /// </summary> static void ReadClientMove(ref usercmd_t move) { client_t client = Host.HostClient; // read ping time client.ping_times[client.num_pings % NUM_PING_TIMES] = (float)(sv.time - Net.Reader.ReadFloat()); client.num_pings++; // read current angles Vector3 angles = Net.Reader.ReadAngles(); Mathlib.Copy(ref angles, out client.edict.v.v_angle); // read movement move.forwardmove = Net.Reader.ReadShort(); move.sidemove = Net.Reader.ReadShort(); move.upmove = Net.Reader.ReadShort(); // read buttons int bits = Net.Reader.ReadByte(); client.edict.v.button0 = bits & 1; client.edict.v.button2 = (bits & 2) >> 1; int i = Net.Reader.ReadByte(); if (i != 0) { client.edict.v.impulse = i; } }
/// <summary> /// SV_ClientThink /// the move fields specify an intended velocity in pix/sec /// the angle fields specify an exact angular motion in degrees /// </summary> static void ClientThink() { if (_Player.v.movetype == Movetypes.MOVETYPE_NONE) { return; } _OnGround = ((int)_Player.v.flags & EdictFlags.FL_ONGROUND) != 0; DropPunchAngle(); // // if dead, behave differently // if (_Player.v.health <= 0) { return; } // // angles // show 1/3 the pitch angle and all the roll angle _Cmd = Host.HostClient.cmd; v3f v_angle; Mathlib.VectorAdd(ref _Player.v.v_angle, ref _Player.v.punchangle, out v_angle); Vector3 pang = Common.ToVector(ref _Player.v.angles); Vector3 pvel = Common.ToVector(ref _Player.v.velocity); _Player.v.angles.z = View.CalcRoll(ref pang, ref pvel) * 4; if (_Player.v.fixangle == 0) { _Player.v.angles.x = -v_angle.x / 3; _Player.v.angles.y = v_angle.y; } if (((int)_Player.v.flags & EdictFlags.FL_WATERJUMP) != 0) { WaterJump(); return; } // // walk // if ((_Player.v.waterlevel >= 2) && (_Player.v.movetype != Movetypes.MOVETYPE_NOCLIP)) { WaterMove(); return; } AirMove(); }
// IN_Move // add additional movement on top of the keyboard move cmd public static void Move(usercmd_t cmd) { if (!MainForm.Instance.Focused) { return; } if (MainForm.Instance.WindowState == WindowState.Minimized) { return; } MouseMove(cmd); }
// CL_SendCmd public static void SendCmd() { if (cls.state != cactive_t.ca_connected) { return; } if (cls.signon == SIGNONS) { usercmd_t cmd = new usercmd_t(); // get basic movement from keyboard BaseMove(ref cmd); // allow mice or other external controllers to add to the move Input.Move(cmd); // send the unreliable message Client.SendMove(ref cmd); } if (cls.demoplayback) { cls.message.Clear();// SZ_Clear (cls.message); return; } // send the reliable message if (cls.message.IsEmpty) { return; // no message at all } if (!Net.CanSendMessage(cls.netcon)) { Con.DPrint("CL_WriteToServer: can't send\n"); return; } if (Net.SendMessage(cls.netcon, cls.message) == -1) { Host.Error("CL_WriteToServer: lost server connection"); } cls.message.Clear(); }
/// <summary> /// CL_BaseMove /// Send the intended movement message to the server /// </summary> static void BaseMove(ref usercmd_t cmd) { if (cls.signon != SIGNONS) { return; } AdjustAngles(); cmd.Clear(); if (ClientInput.StrafeBtn.IsDown) { cmd.sidemove += _SideSpeed.Value * KeyState(ref ClientInput.RightBtn); cmd.sidemove -= _SideSpeed.Value * KeyState(ref ClientInput.LeftBtn); } cmd.sidemove += _SideSpeed.Value * KeyState(ref ClientInput.MoveRightBtn); cmd.sidemove -= _SideSpeed.Value * KeyState(ref ClientInput.MoveLeftBtn); cmd.upmove += _UpSpeed.Value * KeyState(ref ClientInput.UpBtn); cmd.upmove -= _UpSpeed.Value * KeyState(ref ClientInput.DownBtn); if (!ClientInput.KLookBtn.IsDown) { cmd.forwardmove += _ForwardSpeed.Value * KeyState(ref ClientInput.ForwardBtn); cmd.forwardmove -= _BackSpeed.Value * KeyState(ref ClientInput.BackBtn); } // // adjust for speed key // if (ClientInput.SpeedBtn.IsDown) { cmd.forwardmove *= _MoveSpeedKey.Value; cmd.sidemove *= _MoveSpeedKey.Value; cmd.upmove *= _MoveSpeedKey.Value; } }
// CL_SendMove public static void SendMove(ref usercmd_t cmd) { cl.cmd = cmd; // cl.cmd = *cmd - struct copying!!! MsgWriter msg = new MsgWriter(128); // // send the movement message // msg.WriteByte(Protocol.clc_move); msg.WriteFloat((float)cl.mtime[0]); // so server can get ping times msg.WriteAngle(cl.viewangles.X); msg.WriteAngle(cl.viewangles.Y); msg.WriteAngle(cl.viewangles.Z); msg.WriteShort((short)cmd.forwardmove); msg.WriteShort((short)cmd.sidemove); msg.WriteShort((short)cmd.upmove); // // send button bits // int bits = 0; if ((ClientInput.AttackBtn.state & 3) != 0) { bits |= 1; } ClientInput.AttackBtn.state &= ~2; if ((ClientInput.JumpBtn.state & 3) != 0) { bits |= 2; } ClientInput.JumpBtn.state &= ~2; msg.WriteByte(bits); msg.WriteByte(ClientInput.Impulse); ClientInput.Impulse = 0; // // deliver the message // if (cls.demoplayback) { return; } // // allways dump the first two message, because it may contain leftover inputs // from the last level // if (++cl.movemessages <= 2) { return; } if (Net.SendUnreliableMessage(cls.netcon, msg) == -1) { Con.Print("CL_SendMove: lost server connection\n"); Disconnect(); } }
/// <summary> /// IN_MouseMove /// </summary> static void MouseMove(usercmd_t cmd) { if (!_IsMouseActive) { return; } Rectangle bounds = MainForm.Instance.Bounds; Point current_pos = Cursor.Position; Point window_center = Input.WindowCenter; int mx = (int)(current_pos.X - window_center.X + _MouseAccum.X); int my = (int)(current_pos.Y - window_center.Y + _MouseAccum.Y); _MouseAccum.X = 0; _MouseAccum.Y = 0; if (_MouseFilter.Value != 0) { _Mouse.X = (mx + _OldMouse.X) * 0.5f; _Mouse.Y = (my + _OldMouse.Y) * 0.5f; } else { _Mouse.X = mx; _Mouse.Y = my; } _OldMouse.X = mx; _OldMouse.Y = my; _Mouse *= Client.Sensitivity; // add mouse X/Y movement to cmd if (ClientInput.StrafeBtn.IsDown || (Client.LookStrafe && ClientInput.MLookBtn.IsDown)) { cmd.sidemove += Client.MSide * _Mouse.X; } else { Client.cl.viewangles.Y -= Client.MYaw * _Mouse.X; } if (ClientInput.MLookBtn.IsDown) { View.StopPitchDrift(); } if (ClientInput.MLookBtn.IsDown && !ClientInput.StrafeBtn.IsDown) { Client.cl.viewangles.X += Client.MPitch * _Mouse.Y; if (Client.cl.viewangles.X > 80) { Client.cl.viewangles.X = 80; } if (Client.cl.viewangles.X < -70) { Client.cl.viewangles.X = -70; } } else { if (ClientInput.StrafeBtn.IsDown && Host.NoClipAngleHack) { cmd.upmove -= Client.MForward * _Mouse.Y; } else { cmd.forwardmove -= Client.MForward * _Mouse.Y; } } // if the mouse has moved, force it to the center, so there's room to move if (mx != 0 || my != 0) { Cursor.Position = window_center; } }