using System;
using System.IO;
using System.Text;
using OpenTK;

namespace SharpQuake
{
	internal static class client
	{
		public static client_static_t cls
		{
			get
			{
				return client._Static;
			}
		}

		public static client_state_t cl
		{
			get
			{
				return client._State;
			}
		}

		public static entity_t[] Entities
		{
			get
			{
				return client._Entities;
			}
		}

		public static entity_t ViewEntity
		{
			get
			{
				return client._Entities[client._State.viewentity];
			}
		}

		public static entity_t ViewEnt
		{
			get
			{
				return client._State.viewent;
			}
		}

		public static float ForwardSpeed
		{
			get
			{
				return client._ForwardSpeed.Value;
			}
		}

		public static bool LookSpring
		{
			get
			{
				return client._LookSpring.Value != 0f;
			}
		}

		public static bool LookStrafe
		{
			get
			{
				return client._LookStrafe.Value != 0f;
			}
		}

		public static dlight_t[] DLights
		{
			get
			{
				return client._DLights;
			}
		}

		public static lightstyle_t[] LightStyle
		{
			get
			{
				return client._LightStyle;
			}
		}

		public static entity_t[] VisEdicts
		{
			get
			{
				return client._VisEdicts;
			}
		}

		public static float Sensitivity
		{
			get
			{
				return client._Sensitivity.Value;
			}
		}

		public static float MSide
		{
			get
			{
				return client._MSide.Value;
			}
		}

		public static float MYaw
		{
			get
			{
				return client._MYaw.Value;
			}
		}

		public static float MPitch
		{
			get
			{
				return client._MPitch.Value;
			}
		}

		public static float MForward
		{
			get
			{
				return client._MForward.Value;
			}
		}

		public static string Name
		{
			get
			{
				return client._Name.String;
			}
		}

		public static float Color
		{
			get
			{
				return client._Color.Value;
			}
		}

		public static void StopPlayback()
		{
			if (!client.cls.demoplayback)
			{
				return;
			}
			if (client.cls.demofile != null)
			{
				client.cls.demofile.Dispose();
				client.cls.demofile = null;
			}
			client.cls.demoplayback = false;
			client.cls.state = cactive_t.ca_disconnected;
			if (client.cls.timedemo)
			{
				client.FinishTimeDemo();
			}
		}

		private static void Record_f()
		{
			if (cmd.Source != cmd_source_t.src_command)
			{
				return;
			}
			int argc = cmd.Argc;
			if (argc != 2 && argc != 3 && argc != 4)
			{
				Con.Print("record <demoname> [<map> [cd track]]\n", Array.Empty<object>());
				return;
			}
			if (cmd.Argv(1).Contains(".."))
			{
				Con.Print("Relative pathnames are not allowed.\n", Array.Empty<object>());
				return;
			}
			if (argc == 2 && client.cls.state == cactive_t.ca_connected)
			{
				Con.Print("Can not record - already connected to server\nClient demo recording must be started before connecting\n", Array.Empty<object>());
				return;
			}
			int num;
			if (argc == 4)
			{
				num = common.atoi(cmd.Argv(3));
				Con.Print("Forcing CD track to {0}\n", new object[]
				{
					num
				});
			}
			else
			{
				num = -1;
			}
			string text = Path.Combine(common.GameDir, cmd.Argv(1));
			if (argc > 2)
			{
				cmd.ExecuteString(string.Format("map {0}", cmd.Argv(2)), cmd_source_t.src_command);
			}
			text = Path.ChangeExtension(text, ".dem");
			Con.Print("recording to {0}.\n", new object[]
			{
				text
			});
			FileStream fileStream = sys.FileOpenWrite(text, true);
			if (fileStream == null)
			{
				Con.Print("ERROR: couldn't open.\n", Array.Empty<object>());
				return;
			}
			BinaryWriter binaryWriter = new BinaryWriter(fileStream, Encoding.ASCII);
			client.cls.demofile = new DisposableWrapper<BinaryWriter>(binaryWriter, true);
			client.cls.forcetrack = num;
			byte[] bytes = Encoding.ASCII.GetBytes(client.cls.forcetrack.ToString());
			binaryWriter.Write(bytes);
			binaryWriter.Write('\n');
			client.cls.demorecording = true;
		}

		private static void Stop_f()
		{
			if (cmd.Source != cmd_source_t.src_command)
			{
				return;
			}
			if (!client.cls.demorecording)
			{
				Con.Print("Not recording a demo.\n", Array.Empty<object>());
				return;
			}
			net.Message.Clear();
			net.Message.WriteByte(2);
			client.WriteDemoMessage();
			if (client.cls.demofile != null)
			{
				client.cls.demofile.Dispose();
				client.cls.demofile = null;
			}
			client.cls.demorecording = false;
			Con.Print("Completed demo\n", Array.Empty<object>());
		}

		private static void PlayDemo_f()
		{
			if (cmd.Source != cmd_source_t.src_command)
			{
				return;
			}
			if (cmd.Argc != 2)
			{
				Con.Print("play <demoname> : plays a demo\n", Array.Empty<object>());
				return;
			}
			client.Disconnect();
			string text = Path.ChangeExtension(cmd.Argv(1), ".dem");
			Con.Print("Playing demo from {0}.\n", new object[]
			{
				text
			});
			if (client.cls.demofile != null)
			{
				client.cls.demofile.Dispose();
			}
			DisposableWrapper<BinaryReader> disposableWrapper;
			common.FOpenFile(text, out disposableWrapper);
			client.cls.demofile = disposableWrapper;
			if (client.cls.demofile == null)
			{
				Con.Print("ERROR: couldn't open.\n", Array.Empty<object>());
				client.cls.demonum = -1;
				return;
			}
			client.cls.demoplayback = true;
			client.cls.state = cactive_t.ca_connected;
			client.cls.forcetrack = 0;
			BinaryReader @object = disposableWrapper.Object;
			bool flag = false;
			for (;;)
			{
				int num = (int)@object.ReadByte();
				if (num == 10)
				{
					break;
				}
				if (num == 45)
				{
					flag = true;
				}
				else
				{
					client.cls.forcetrack = client.cls.forcetrack * 10 + (num - 48);
				}
			}
			if (flag)
			{
				client.cls.forcetrack = -client.cls.forcetrack;
			}
		}

		private static void TimeDemo_f()
		{
			if (cmd.Source != cmd_source_t.src_command)
			{
				return;
			}
			if (cmd.Argc != 2)
			{
				Con.Print("timedemo <demoname> : gets demo speeds\n", Array.Empty<object>());
				return;
			}
			client.PlayDemo_f();
			client._Static.timedemo = true;
			client._Static.td_startframe = host.FrameCount;
			client._Static.td_lastframe = -1;
		}

		private static int GetMessage()
		{
			if (!client.cls.demoplayback)
			{
				int message;
				for (;;)
				{
					message = net.GetMessage(client.cls.netcon);
					if (message != 1 && message != 2)
					{
						break;
					}
					if (net.Message.Length != 1 || net.Message.Data[0] != 1)
					{
						goto IL_1AF;
					}
					Con.Print("<-- server to client keepalive\n", Array.Empty<object>());
				}
				return message;
				IL_1AF:
				if (client.cls.demorecording)
				{
					client.WriteDemoMessage();
				}
				return message;
			}
			if (client.cls.signon == 4)
			{
				if (client.cls.timedemo)
				{
					if (host.FrameCount == client.cls.td_lastframe)
					{
						return 0;
					}
					client.cls.td_lastframe = host.FrameCount;
					if (host.FrameCount == client.cls.td_startframe + 1)
					{
						client.cls.td_starttime = (float)host.RealTime;
					}
				}
				else if (client.cl.time <= client.cl.mtime[0])
				{
					return 0;
				}
			}
			BinaryReader @object = ((DisposableWrapper<BinaryReader>)client.cls.demofile).Object;
			int num = common.LittleLong(@object.ReadInt32());
			if (num > 8000)
			{
				sys.Error("Demo message > MAX_MSGLEN", Array.Empty<object>());
			}
			client.cl.mviewangles[1] = client.cl.mviewangles[0];
			client.cl.mviewangles[0].X = common.LittleFloat(@object.ReadSingle());
			client.cl.mviewangles[0].Y = common.LittleFloat(@object.ReadSingle());
			client.cl.mviewangles[0].Z = common.LittleFloat(@object.ReadSingle());
			net.Message.FillFrom(@object.BaseStream, num);
			if (net.Message.Length < num)
			{
				client.StopPlayback();
				return 0;
			}
			return 1;
		}

		private static void FinishTimeDemo()
		{
			client.cls.timedemo = false;
			int num = host.FrameCount - client.cls.td_startframe - 1;
			float num2 = (float)host.RealTime - client.cls.td_starttime;
			if (num2 == 0f)
			{
				num2 = 1f;
			}
			Con.Print("{0} frames {1:F5} seconds {2:F2} fps\n", new object[]
			{
				num,
				num2,
				(float)num / num2
			});
		}

		private static void WriteDemoMessage()
		{
			int value = common.LittleLong(net.Message.Length);
			BinaryWriter @object = ((DisposableWrapper<BinaryWriter>)client.cls.demofile).Object;
			@object.Write(value);
			@object.Write(common.LittleFloat(client.cl.viewangles.X));
			@object.Write(common.LittleFloat(client.cl.viewangles.Y));
			@object.Write(common.LittleFloat(client.cl.viewangles.Z));
			@object.Write(net.Message.Data, 0, net.Message.Length);
			@object.Flush();
		}

		public static void SendMove(ref usercmd_t cmd)
		{
			client.cl.cmd = cmd;
			MsgWriter msgWriter = new MsgWriter(128);
			msgWriter.WriteByte(3);
			msgWriter.WriteFloat((float)client.cl.mtime[0]);
			msgWriter.WriteAngle(client.cl.viewangles.X);
			msgWriter.WriteAngle(client.cl.viewangles.Y);
			msgWriter.WriteAngle(client.cl.viewangles.Z);
			msgWriter.WriteShort((int)((short)cmd.forwardmove));
			msgWriter.WriteShort((int)((short)cmd.sidemove));
			msgWriter.WriteShort((int)((short)cmd.upmove));
			int num = 0;
			if ((client_input.AttackBtn.state & 3) != 0)
			{
				num |= 1;
			}
			client_input.AttackBtn.state = (client_input.AttackBtn.state & -3);
			if ((client_input.JumpBtn.state & 3) != 0)
			{
				num |= 2;
			}
			client_input.JumpBtn.state = (client_input.JumpBtn.state & -3);
			msgWriter.WriteByte(num);
			msgWriter.WriteByte(client_input.Impulse);
			client_input.Impulse = 0;
			if (client.cls.demoplayback)
			{
				return;
			}
			client_state_t cl = client.cl;
			int num2 = cl.movemessages + 1;
			cl.movemessages = num2;
			if (num2 <= 2)
			{
				return;
			}
			if (net.SendUnreliableMessage(client.cls.netcon, msgWriter) == -1)
			{
				Con.Print("CL_SendMove: lost server connection\n", Array.Empty<object>());
				client.Disconnect();
			}
		}

		private static void InitInput()
		{
			client_input.Init();
		}

		private static void BaseMove(ref usercmd_t cmd)
		{
			if (client.cls.signon != 4)
			{
				return;
			}
			client.AdjustAngles();
			cmd.Clear();
			if (client_input.StrafeBtn.IsDown)
			{
				cmd.sidemove += client._SideSpeed.Value * client.KeyState(ref client_input.RightBtn);
				cmd.sidemove -= client._SideSpeed.Value * client.KeyState(ref client_input.LeftBtn);
			}
			cmd.sidemove += client._SideSpeed.Value * client.KeyState(ref client_input.MoveRightBtn);
			cmd.sidemove -= client._SideSpeed.Value * client.KeyState(ref client_input.MoveLeftBtn);
			cmd.upmove += client._UpSpeed.Value * client.KeyState(ref client_input.UpBtn);
			cmd.upmove -= client._UpSpeed.Value * client.KeyState(ref client_input.DownBtn);
			if (!client_input.KLookBtn.IsDown)
			{
				cmd.forwardmove += client._ForwardSpeed.Value * client.KeyState(ref client_input.ForwardBtn);
				cmd.forwardmove -= client._BackSpeed.Value * client.KeyState(ref client_input.BackBtn);
			}
			if (client_input.SpeedBtn.IsDown)
			{
				cmd.forwardmove *= client._MoveSpeedKey.Value;
				cmd.sidemove *= client._MoveSpeedKey.Value;
				cmd.upmove *= client._MoveSpeedKey.Value;
			}
		}

		private static void AdjustAngles()
		{
			float num = (float)host.FrameTime;
			if (client_input.SpeedBtn.IsDown)
			{
				num *= client._AngleSpeedKey.Value;
			}
			if (!client_input.StrafeBtn.IsDown)
			{
				client_state_t cl = client.cl;
				cl.viewangles.Y = cl.viewangles.Y - num * client._YawSpeed.Value * client.KeyState(ref client_input.RightBtn);
				client_state_t cl2 = client.cl;
				cl2.viewangles.Y = cl2.viewangles.Y + num * client._YawSpeed.Value * client.KeyState(ref client_input.LeftBtn);
				client.cl.viewangles.Y = mathlib.AngleMod((double)client.cl.viewangles.Y);
			}
			if (client_input.KLookBtn.IsDown)
			{
				view.StopPitchDrift();
				client_state_t cl3 = client.cl;
				cl3.viewangles.X = cl3.viewangles.X - num * client._PitchSpeed.Value * client.KeyState(ref client_input.ForwardBtn);
				client_state_t cl4 = client.cl;
				cl4.viewangles.X = cl4.viewangles.X + num * client._PitchSpeed.Value * client.KeyState(ref client_input.BackBtn);
			}
			float num2 = client.KeyState(ref client_input.LookUpBtn);
			float num3 = client.KeyState(ref client_input.LookDownBtn);
			client_state_t cl5 = client.cl;
			cl5.viewangles.X = cl5.viewangles.X - num * client._PitchSpeed.Value * num2;
			client_state_t cl6 = client.cl;
			cl6.viewangles.X = cl6.viewangles.X + num * client._PitchSpeed.Value * num3;
			if (num2 != 0f || num3 != 0f)
			{
				view.StopPitchDrift();
			}
			if (client.cl.viewangles.X > 80f)
			{
				client.cl.viewangles.X = 80f;
			}
			if (client.cl.viewangles.X < -70f)
			{
				client.cl.viewangles.X = -70f;
			}
			if (client.cl.viewangles.Z > 50f)
			{
				client.cl.viewangles.Z = 50f;
			}
			if (client.cl.viewangles.Z < -50f)
			{
				client.cl.viewangles.Z = -50f;
			}
		}

		private static float KeyState(ref kbutton_t key)
		{
			bool flag = (key.state & 2) != 0;
			bool flag2 = (key.state & 4) != 0;
			bool isDown = key.IsDown;
			float result = 0f;
			if (flag && !flag2)
			{
				if (isDown)
				{
					result = 0.5f;
				}
				else
				{
					result = 0f;
				}
			}
			if (flag2 && !flag)
			{
				if (isDown)
				{
					result = 0f;
				}
				else
				{
					result = 0f;
				}
			}
			if (!flag && !flag2)
			{
				if (isDown)
				{
					result = 1f;
				}
				else
				{
					result = 0f;
				}
			}
			if (flag && flag2)
			{
				if (isDown)
				{
					result = 0.75f;
				}
				else
				{
					result = 0.25f;
				}
			}
			key.state &= 1;
			return result;
		}

		public static void Init()
		{
			client.InitInput();
			client.InitTempEntities();
			if (client._Name == null)
			{
				client._Name = new cvar("_cl_name", "player", true);
				client._Color = new cvar("_cl_color", "0", true);
				client._ShowNet = new cvar("cl_shownet", "0");
				client._NoLerp = new cvar("cl_nolerp", "0");
				client._LookSpring = new cvar("lookspring", "0", true);
				client._LookStrafe = new cvar("lookstrafe", "0", true);
				client._Sensitivity = new cvar("sensitivity", "3", true);
				client._MPitch = new cvar("m_pitch", "0.022", true);
				client._MYaw = new cvar("m_yaw", "0.022", true);
				client._MForward = new cvar("m_forward", "1", true);
				client._MSide = new cvar("m_side", "0.8", true);
				client._UpSpeed = new cvar("cl_upspeed", "200");
				client._ForwardSpeed = new cvar("cl_forwardspeed", "200", true);
				client._BackSpeed = new cvar("cl_backspeed", "200", true);
				client._SideSpeed = new cvar("cl_sidespeed", "350");
				client._MoveSpeedKey = new cvar("cl_movespeedkey", "2.0");
				client._YawSpeed = new cvar("cl_yawspeed", "140");
				client._PitchSpeed = new cvar("cl_pitchspeed", "150");
				client._AngleSpeedKey = new cvar("cl_anglespeedkey", "1.5");
			}
			for (int i = 0; i < client._EFrags.Length; i++)
			{
				client._EFrags[i] = new efrag_t();
			}
			for (int j = 0; j < client._Entities.Length; j++)
			{
				client._Entities[j] = new entity_t();
			}
			for (int k = 0; k < client._StaticEntities.Length; k++)
			{
				client._StaticEntities[k] = new entity_t();
			}
			for (int l = 0; l < client._DLights.Length; l++)
			{
				client._DLights[l] = new dlight_t();
			}
			cmd.Add("entities", new xcommand_t(client.PrintEntities_f));
			cmd.Add("disconnect", new xcommand_t(client.Disconnect_f));
			cmd.Add("record", new xcommand_t(client.Record_f));
			cmd.Add("stop", new xcommand_t(client.Stop_f));
			cmd.Add("playdemo", new xcommand_t(client.PlayDemo_f));
			cmd.Add("timedemo", new xcommand_t(client.TimeDemo_f));
		}

		public static void EstablishConnection(string host)
		{
			if (client.cls.state == cactive_t.ca_dedicated)
			{
				return;
			}
			if (client.cls.demoplayback)
			{
				return;
			}
			client.Disconnect();
			client.cls.netcon = net.Connect(host);
			if (client.cls.netcon == null)
			{
				host.Error("CL_Connect: connect failed\n", Array.Empty<object>());
			}
			Con.DPrint("CL_EstablishConnection: connected to {0}\n", new object[]
			{
				host
			});
			client.cls.demonum = -1;
			client.cls.state = cactive_t.ca_connected;
			client.cls.signon = 0;
		}

		public static void NextDemo()
		{
			if (client.cls.demonum == -1)
			{
				return;
			}
			Scr.BeginLoadingPlaque();
			if (string.IsNullOrEmpty(client.cls.demos[client.cls.demonum]) || client.cls.demonum == 8)
			{
				client.cls.demonum = 0;
				if (string.IsNullOrEmpty(client.cls.demos[client.cls.demonum]))
				{
					Con.Print("No demos listed with startdemos\n", Array.Empty<object>());
					client.cls.demonum = -1;
					return;
				}
			}
			Cbuf.InsertText(string.Format("playdemo {0}\n", client.cls.demos[client.cls.demonum]));
			client.cls.demonum++;
		}

		public static dlight_t AllocDlight(int key)
		{
			dlight_t dlight_t;
			if (key != 0)
			{
				for (int i = 0; i < 32; i++)
				{
					dlight_t = client._DLights[i];
					if (dlight_t.key == key)
					{
						dlight_t.Clear();
						dlight_t.key = key;
						return dlight_t;
					}
				}
			}
			for (int j = 0; j < 32; j++)
			{
				dlight_t = client._DLights[j];
				if ((double)dlight_t.die < client.cl.time)
				{
					dlight_t.Clear();
					dlight_t.key = key;
					return dlight_t;
				}
			}
			dlight_t = client._DLights[0];
			dlight_t.Clear();
			dlight_t.key = key;
			return dlight_t;
		}

		public static void DecayLights()
		{
			float num = (float)(client.cl.time - client.cl.oldtime);
			for (int i = 0; i < 32; i++)
			{
				dlight_t dlight_t = client._DLights[i];
				if ((double)dlight_t.die >= client.cl.time && dlight_t.radius != 0f)
				{
					dlight_t.radius -= num * dlight_t.decay;
					if (dlight_t.radius < 0f)
					{
						dlight_t.radius = 0f;
					}
				}
			}
		}

		public static void Disconnect_f()
		{
			client.Disconnect();
			if (server.IsActive)
			{
				host.ShutdownServer(false);
			}
		}

		public static void SendCmd()
		{
			if (client.cls.state != cactive_t.ca_connected)
			{
				return;
			}
			if (client.cls.signon == 4)
			{
				usercmd_t cmd = default(usercmd_t);
				client.BaseMove(ref cmd);
				input.Move(cmd);
				client.SendMove(ref cmd);
			}
			if (client.cls.demoplayback)
			{
				client.cls.message.Clear();
				return;
			}
			if (client.cls.message.IsEmpty)
			{
				return;
			}
			if (!net.CanSendMessage(client.cls.netcon))
			{
				Con.DPrint("CL_WriteToServer: can't send\n", Array.Empty<object>());
				return;
			}
			if (net.SendMessage(client.cls.netcon, client.cls.message) == -1)
			{
				host.Error("CL_WriteToServer: lost server connection", Array.Empty<object>());
			}
			client.cls.message.Clear();
		}

		public static int ReadFromServer()
		{
			client.cl.oldtime = client.cl.time;
			client.cl.time += host.FrameTime;
			int message;
			do
			{
				message = client.GetMessage();
				if (message == -1)
				{
					host.Error("CL_ReadFromServer: lost server connection", Array.Empty<object>());
				}
				if (message == 0)
				{
					break;
				}
				client.cl.last_received_message = (float)host.RealTime;
				client.ParseServerMessage();
			}
			while (message != 0 && client.cls.state == cactive_t.ca_connected);
			if (client._ShowNet.Value != 0f)
			{
				Con.Print("\n", Array.Empty<object>());
			}
			client.RelinkEntities();
			client.UpdateTempEntities();
			return 0;
		}

		public static void Disconnect()
		{
			snd.StopAllSounds(true);
			if (client.cls.demoplayback)
			{
				client.StopPlayback();
			}
			else if (client.cls.state == cactive_t.ca_connected)
			{
				if (client.cls.demorecording)
				{
					client.Stop_f();
				}
				Con.DPrint("Sending clc_disconnect\n", Array.Empty<object>());
				client.cls.message.Clear();
				client.cls.message.WriteByte(2);
				net.SendUnreliableMessage(client.cls.netcon, client.cls.message);
				client.cls.message.Clear();
				net.Close(client.cls.netcon);
				client.cls.state = cactive_t.ca_disconnected;
				if (server.sv.active)
				{
					host.ShutdownServer(false);
				}
			}
			client.cls.demoplayback = (client.cls.timedemo = false);
			client.cls.signon = 0;
		}

		private static void PrintEntities_f()
		{
			for (int i = 0; i < client._State.num_entities; i++)
			{
				entity_t entity_t = client._Entities[i];
				Con.Print("{0:d3}:", new object[]
				{
					i
				});
				if (entity_t.model == null)
				{
					Con.Print("EMPTY\n", Array.Empty<object>());
				}
				else
				{
					Con.Print("{0}:{1:d2}  ({2}) [{3}]\n", new object[]
					{
						entity_t.model.name,
						entity_t.frame,
						entity_t.origin,
						entity_t.angles
					});
				}
			}
		}

		private static void RelinkEntities()
		{
			float num = client.LerpPoint();
			client.NumVisEdicts = 0;
			client.cl.velocity = client.cl.mvelocity[1] + num * (client.cl.mvelocity[0] - client.cl.mvelocity[1]);
			if (client.cls.demoplayback)
			{
				Vector3 vec = client.cl.mviewangles[0] - client.cl.mviewangles[1];
				mathlib.CorrectAngles180(ref vec);
				client.cl.viewangles = client.cl.mviewangles[1] + num * vec;
			}
			float y = mathlib.AngleMod(100.0 * client.cl.time);
			for (int i = 1; i < client.cl.num_entities; i++)
			{
				entity_t entity_t = client._Entities[i];
				if (entity_t.model == null)
				{
					if (entity_t.forcelink)
					{
						render.RemoveEfrags(entity_t);
					}
				}
				else if (entity_t.msgtime != client.cl.mtime[0])
				{
					entity_t.model = null;
				}
				else
				{
					Vector3 origin = entity_t.origin;
					if (entity_t.forcelink)
					{
						entity_t.origin = entity_t.msg_origins[0];
						entity_t.angles = entity_t.msg_angles[0];
					}
					else
					{
						float scale = num;
						Vector3 vector = entity_t.msg_origins[0] - entity_t.msg_origins[1];
						if (Math.Abs(vector.X) > 100f || Math.Abs(vector.Y) > 100f || Math.Abs(vector.Z) > 100f)
						{
							scale = 1f;
						}
						entity_t.origin = entity_t.msg_origins[1] + scale * vector;
						Vector3 vec2 = entity_t.msg_angles[0] - entity_t.msg_angles[1];
						mathlib.CorrectAngles180(ref vec2);
						entity_t.angles = entity_t.msg_angles[1] + scale * vec2;
					}
					if ((entity_t.model.flags & 8) != 0)
					{
						entity_t.angles.Y = y;
					}
					if ((entity_t.effects & EntityEffects.EF_BRIGHTFIELD) != 0)
					{
						render.EntityParticles(entity_t);
					}
					if ((entity_t.effects & EntityEffects.EF_MUZZLEFLASH) != 0)
					{
						dlight_t dlight_t = client.AllocDlight(i);
						dlight_t.origin = entity_t.origin;
						dlight_t.origin.Z = dlight_t.origin.Z + 16f;
						Vector3 vec3;
						Vector3 vector2;
						Vector3 vector3;
						mathlib.AngleVectors(ref entity_t.angles, out vec3, out vector2, out vector3);
						dlight_t.origin += vec3 * 18f;
						dlight_t.radius = (float)(200 + (sys.Random() & 31));
						dlight_t.minlight = 32f;
						dlight_t.die = (float)client.cl.time + 0.1f;
					}
					if ((entity_t.effects & EntityEffects.EF_BRIGHTLIGHT) != 0)
					{
						dlight_t dlight_t2 = client.AllocDlight(i);
						dlight_t2.origin = entity_t.origin;
						dlight_t2.origin.Z = dlight_t2.origin.Z + 16f;
						dlight_t2.radius = (float)(400 + (sys.Random() & 31));
						dlight_t2.die = (float)client.cl.time + 0.001f;
					}
					if ((entity_t.effects & EntityEffects.EF_DIMLIGHT) != 0)
					{
						dlight_t dlight_t3 = client.AllocDlight(i);
						dlight_t3.origin = entity_t.origin;
						dlight_t3.radius = (float)(200 + (sys.Random() & 31));
						dlight_t3.die = (float)client.cl.time + 0.001f;
					}
					if ((entity_t.model.flags & 4) != 0)
					{
						render.RocketTrail(ref origin, ref entity_t.origin, 2);
					}
					else if ((entity_t.model.flags & 32) != 0)
					{
						render.RocketTrail(ref origin, ref entity_t.origin, 4);
					}
					else if ((entity_t.model.flags & 16) != 0)
					{
						render.RocketTrail(ref origin, ref entity_t.origin, 3);
					}
					else if ((entity_t.model.flags & 64) != 0)
					{
						render.RocketTrail(ref origin, ref entity_t.origin, 5);
					}
					else if ((entity_t.model.flags & 1) != 0)
					{
						render.RocketTrail(ref origin, ref entity_t.origin, 0);
						dlight_t dlight_t4 = client.AllocDlight(i);
						dlight_t4.origin = entity_t.origin;
						dlight_t4.radius = 200f;
						dlight_t4.die = (float)client.cl.time + 0.01f;
					}
					else if ((entity_t.model.flags & 2) != 0)
					{
						render.RocketTrail(ref origin, ref entity_t.origin, 1);
					}
					else if ((entity_t.model.flags & 128) != 0)
					{
						render.RocketTrail(ref origin, ref entity_t.origin, 6);
					}
					entity_t.forcelink = false;
					if ((i != client.cl.viewentity || chase.IsActive) && client.NumVisEdicts < 256)
					{
						client._VisEdicts[client.NumVisEdicts] = entity_t;
						client.NumVisEdicts++;
					}
				}
			}
		}

		private static void SignonReply()
		{
			Con.DPrint("CL_SignonReply: {0}\n", new object[]
			{
				client.cls.signon
			});
			switch (client.cls.signon)
			{
			case 1:
				client.cls.message.WriteByte(4);
				client.cls.message.WriteString("prespawn");
				return;
			case 2:
				client.cls.message.WriteByte(4);
				client.cls.message.WriteString(string.Format("name \"{0}\"\n", client._Name.String));
				client.cls.message.WriteByte(4);
				client.cls.message.WriteString(string.Format("color {0} {1}\n", (int)client._Color.Value >> 4, (int)client._Color.Value & 15));
				client.cls.message.WriteByte(4);
				client.cls.message.WriteString("spawn " + client.cls.spawnparms);
				return;
			case 3:
				client.cls.message.WriteByte(4);
				client.cls.message.WriteString("begin");
				Cache.Report();
				return;
			case 4:
				Scr.EndLoadingPlaque();
				return;
			default:
				return;
			}
		}

		private static void ClearState()
		{
			if (!server.sv.active)
			{
				host.ClearMemory();
			}
			client._State.Clear();
			client.cls.message.Clear();
			efrag_t[] efrags = client._EFrags;
			for (int i = 0; i < efrags.Length; i++)
			{
				efrags[i].Clear();
			}
			entity_t[] array = client._Entities;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].Clear();
			}
			dlight_t[] dlights = client._DLights;
			for (int i = 0; i < dlights.Length; i++)
			{
				dlights[i].Clear();
			}
			Array.Clear(client._LightStyle, 0, client._LightStyle.Length);
			array = client._TempEntities;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].Clear();
			}
			beam_t[] beams = client._Beams;
			for (int i = 0; i < beams.Length; i++)
			{
				beams[i].Clear();
			}
			client.cl.free_efrags = client._EFrags[0];
			for (int j = 0; j < 639; j++)
			{
				client._EFrags[j].entnext = client._EFrags[j + 1];
			}
			client._EFrags[639].entnext = null;
		}

		private static float LerpPoint()
		{
			double num = client.cl.mtime[0] - client.cl.mtime[1];
			if (num == 0.0 || client._NoLerp.Value != 0f || client.cls.timedemo || server.IsActive)
			{
				client.cl.time = client.cl.mtime[0];
				return 1f;
			}
			if (num > 0.1)
			{
				client.cl.mtime[1] = client.cl.mtime[0] - 0.1;
				num = 0.1;
			}
			double num2 = (client.cl.time - client.cl.mtime[1]) / num;
			if (num2 < 0.0)
			{
				if (num2 < -0.01)
				{
					client.cl.time = client.cl.mtime[1];
				}
				num2 = 0.0;
			}
			else if (num2 > 1.0)
			{
				if (num2 > 1.01)
				{
					client.cl.time = client.cl.mtime[0];
				}
				num2 = 1.0;
			}
			return (float)num2;
		}

		private static void ParseServerMessage()
		{
			if (client._ShowNet.Value == 1f)
			{
				Con.Print("{0} ", new object[]
				{
					net.Message.Length
				});
			}
			else if (client._ShowNet.Value == 2f)
			{
				Con.Print("------------------\n", Array.Empty<object>());
			}
			client.cl.onground = false;
			net.Reader.Reset();
			for (;;)
			{
				if (net.Reader.IsBadRead)
				{
					host.Error("CL_ParseServerMessage: Bad server message", Array.Empty<object>());
				}
				int num = net.Reader.ReadByte();
				if (num == -1)
				{
					break;
				}
				if ((num & 128) != 0)
				{
					client.ShowNet("fast update");
					client.ParseUpdate(num & 127);
				}
				else
				{
					client.ShowNet(client._SvcStrings[num]);
					switch (num)
					{
					case 1:
						break;
					case 2:
						host.EndGame("Server disconnected\n", Array.Empty<object>());
						break;
					case 3:
					{
						int num2 = net.Reader.ReadByte();
						if (num2 < 0 || num2 >= QStats.MAX_CL_STATS)
						{
							sys.Error("svc_updatestat: {0} is invalid", new object[]
							{
								num2
							});
						}
						client.cl.stats[num2] = net.Reader.ReadLong();
						break;
					}
					case 4:
					{
						int num2 = net.Reader.ReadLong();
						if (num2 != 15)
						{
							host.Error("CL_ParseServerMessage: Server is protocol {0} instead of {1}\n", new object[]
							{
								num2,
								15
							});
						}
						break;
					}
					case 5:
						client.cl.viewentity = net.Reader.ReadShort();
						break;
					case 6:
						client.ParseStartSoundPacket();
						break;
					case 7:
						client.cl.mtime[1] = client.cl.mtime[0];
						client.cl.mtime[0] = (double)net.Reader.ReadFloat();
						break;
					case 8:
						Con.Print(net.Reader.ReadString(), Array.Empty<object>());
						break;
					case 9:
						Cbuf.AddText(net.Reader.ReadString());
						break;
					case 10:
						client.cl.viewangles.X = net.Reader.ReadAngle();
						client.cl.viewangles.Y = net.Reader.ReadAngle();
						client.cl.viewangles.Z = net.Reader.ReadAngle();
						break;
					case 11:
						client.ParseServerInfo();
						Scr.vid.recalc_refdef = true;
						break;
					case 12:
					{
						int num2 = net.Reader.ReadByte();
						if (num2 >= 64)
						{
							sys.Error("svc_lightstyle > MAX_LIGHTSTYLES", Array.Empty<object>());
						}
						client._LightStyle[num2].map = net.Reader.ReadString();
						break;
					}
					case 13:
					{
						sbar.Changed();
						int num2 = net.Reader.ReadByte();
						if (num2 >= client.cl.maxclients)
						{
							host.Error("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD", Array.Empty<object>());
						}
						client.cl.scores[num2].name = net.Reader.ReadString();
						break;
					}
					case 14:
					{
						sbar.Changed();
						int num2 = net.Reader.ReadByte();
						if (num2 >= client.cl.maxclients)
						{
							host.Error("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD", Array.Empty<object>());
						}
						client.cl.scores[num2].frags = net.Reader.ReadShort();
						break;
					}
					case 15:
					{
						int num2 = net.Reader.ReadShort();
						client.ParseClientData(num2);
						break;
					}
					case 16:
					{
						int num2 = net.Reader.ReadShort();
						snd.StopSound(num2 >> 3, num2 & 7);
						break;
					}
					case 17:
					{
						sbar.Changed();
						int num2 = net.Reader.ReadByte();
						if (num2 >= client.cl.maxclients)
						{
							host.Error("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD", Array.Empty<object>());
						}
						client.cl.scores[num2].colors = net.Reader.ReadByte();
						client.NewTranslation(num2);
						break;
					}
					case 18:
						render.ParseParticleEffect();
						break;
					case 19:
						view.ParseDamage();
						break;
					case 20:
						client.ParseStatic();
						break;
					default:
						host.Error("CL_ParseServerMessage: Illegible server message\n", Array.Empty<object>());
						break;
					case 22:
					{
						int num2 = net.Reader.ReadShort();
						client.ParseBaseline(client.EntityNum(num2));
						break;
					}
					case 23:
						client.ParseTempEntity();
						break;
					case 24:
						client.cl.paused = (net.Reader.ReadByte() != 0);
						if (client.cl.paused)
						{
							cd_audio.Pause();
						}
						else
						{
							cd_audio.Resume();
						}
						break;
					case 25:
					{
						int num2 = net.Reader.ReadByte();
						if (num2 <= client.cls.signon)
						{
							host.Error("Received signon {0} when at {1}", new object[]
							{
								num2,
								client.cls.signon
							});
						}
						client.cls.signon = num2;
						client.SignonReply();
						break;
					}
					case 26:
						Scr.CenterPrint(net.Reader.ReadString());
						break;
					case 27:
						client.cl.stats[QStats.STAT_MONSTERS]++;
						break;
					case 28:
						client.cl.stats[QStats.STAT_SECRETS]++;
						break;
					case 29:
						client.ParseStaticSound();
						break;
					case 30:
						client.cl.intermission = 1;
						client.cl.completed_time = (int)client.cl.time;
						Scr.vid.recalc_refdef = true;
						break;
					case 31:
						client.cl.intermission = 2;
						client.cl.completed_time = (int)client.cl.time;
						Scr.vid.recalc_refdef = true;
						Scr.CenterPrint(net.Reader.ReadString());
						break;
					case 32:
						client.cl.cdtrack = net.Reader.ReadByte();
						client.cl.looptrack = net.Reader.ReadByte();
						if ((client.cls.demoplayback || client.cls.demorecording) && client.cls.forcetrack != -1)
						{
							cd_audio.Play((byte)client.cls.forcetrack, true);
						}
						else
						{
							cd_audio.Play((byte)client.cl.cdtrack, true);
						}
						break;
					case 33:
						cmd.ExecuteString("help", cmd_source_t.src_command);
						break;
					case 34:
						client.cl.intermission = 3;
						client.cl.completed_time = (int)client.cl.time;
						Scr.vid.recalc_refdef = true;
						Scr.CenterPrint(net.Reader.ReadString());
						break;
					}
				}
			}
			client.ShowNet("END OF MESSAGE");
		}

		private static void ShowNet(string s)
		{
			if (client._ShowNet.Value == 2f)
			{
				Con.Print("{0,3}:{1}\n", new object[]
				{
					net.Reader.Position - 1,
					s
				});
			}
		}

		private static void ParseUpdate(int bits)
		{
			if (client.cls.signon == 3)
			{
				client.cls.signon = 4;
				client.SignonReply();
			}
			int i;
			if ((bits & 1) != 0)
			{
				i = net.Reader.ReadByte();
				bits |= i << 8;
			}
			int num;
			if ((bits & 16384) != 0)
			{
				num = net.Reader.ReadShort();
			}
			else
			{
				num = net.Reader.ReadByte();
			}
			entity_t entity_t = client.EntityNum(num);
			for (i = 0; i < 16; i++)
			{
				if ((bits & 1 << i) != 0)
				{
					client._BitCounts[i]++;
				}
			}
			bool flag = false;
			if (entity_t.msgtime != client.cl.mtime[1])
			{
				flag = true;
			}
			entity_t.msgtime = client.cl.mtime[0];
			int num2;
			if ((bits & 1024) != 0)
			{
				num2 = net.Reader.ReadByte();
				if (num2 >= 256)
				{
					host.Error("CL_ParseModel: bad modnum", Array.Empty<object>());
				}
			}
			else
			{
				num2 = entity_t.baseline.modelindex;
			}
			model_t model_t = client.cl.model_precache[num2];
			if (model_t != entity_t.model)
			{
				entity_t.model = model_t;
				if (model_t != null)
				{
					if (model_t.synctype == synctype_t.ST_RAND)
					{
						entity_t.syncbase = (float)(sys.Random() & 32767) / 32767f;
					}
					else
					{
						entity_t.syncbase = 0f;
					}
				}
				else
				{
					flag = true;
				}
				if (num > 0 && num <= client.cl.maxclients)
				{
					render.TranslatePlayerSkin(num - 1);
				}
			}
			if ((bits & 64) != 0)
			{
				entity_t.frame = net.Reader.ReadByte();
			}
			else
			{
				entity_t.frame = entity_t.baseline.frame;
			}
			if ((bits & 2048) != 0)
			{
				i = net.Reader.ReadByte();
			}
			else
			{
				i = entity_t.baseline.colormap;
			}
			if (i == 0)
			{
				entity_t.colormap = Scr.vid.colormap;
			}
			else
			{
				if (i > client.cl.maxclients)
				{
					sys.Error("i >= cl.maxclients", Array.Empty<object>());
				}
				entity_t.colormap = client.cl.scores[i - 1].translations;
			}
			int num3;
			if ((bits & 4096) != 0)
			{
				num3 = net.Reader.ReadByte();
			}
			else
			{
				num3 = entity_t.baseline.skin;
			}
			if (num3 != entity_t.skinnum)
			{
				entity_t.skinnum = num3;
				if (num > 0 && num <= client.cl.maxclients)
				{
					render.TranslatePlayerSkin(num - 1);
				}
			}
			if ((bits & 8192) != 0)
			{
				entity_t.effects = net.Reader.ReadByte();
			}
			else
			{
				entity_t.effects = entity_t.baseline.effects;
			}
			entity_t.msg_origins[1] = entity_t.msg_origins[0];
			entity_t.msg_angles[1] = entity_t.msg_angles[0];
			if ((bits & 2) != 0)
			{
				entity_t.msg_origins[0].X = net.Reader.ReadCoord();
			}
			else
			{
				entity_t.msg_origins[0].X = entity_t.baseline.origin.x;
			}
			if ((bits & 256) != 0)
			{
				entity_t.msg_angles[0].X = net.Reader.ReadAngle();
			}
			else
			{
				entity_t.msg_angles[0].X = entity_t.baseline.angles.x;
			}
			if ((bits & 4) != 0)
			{
				entity_t.msg_origins[0].Y = net.Reader.ReadCoord();
			}
			else
			{
				entity_t.msg_origins[0].Y = entity_t.baseline.origin.y;
			}
			if ((bits & 16) != 0)
			{
				entity_t.msg_angles[0].Y = net.Reader.ReadAngle();
			}
			else
			{
				entity_t.msg_angles[0].Y = entity_t.baseline.angles.y;
			}
			if ((bits & 8) != 0)
			{
				entity_t.msg_origins[0].Z = net.Reader.ReadCoord();
			}
			else
			{
				entity_t.msg_origins[0].Z = entity_t.baseline.origin.z;
			}
			if ((bits & 512) != 0)
			{
				entity_t.msg_angles[0].Z = net.Reader.ReadAngle();
			}
			else
			{
				entity_t.msg_angles[0].Z = entity_t.baseline.angles.z;
			}
			if ((bits & 32) != 0)
			{
				entity_t.forcelink = true;
			}
			if (flag)
			{
				entity_t.msg_origins[1] = entity_t.msg_origins[0];
				entity_t.origin = entity_t.msg_origins[0];
				entity_t.msg_angles[1] = entity_t.msg_angles[0];
				entity_t.angles = entity_t.msg_angles[0];
				entity_t.forcelink = true;
			}
		}

		private static void ParseClientData(int bits)
		{
			if ((bits & 1) != 0)
			{
				client.cl.viewheight = (float)net.Reader.ReadChar();
			}
			else
			{
				client.cl.viewheight = 22f;
			}
			if ((bits & 2) != 0)
			{
				client.cl.idealpitch = (float)net.Reader.ReadChar();
			}
			else
			{
				client.cl.idealpitch = 0f;
			}
			client.cl.mvelocity[1] = client.cl.mvelocity[0];
			for (int i = 0; i < 3; i++)
			{
				if ((bits & 4 << i) != 0)
				{
					mathlib.SetComp(ref client.cl.punchangle, i, (float)net.Reader.ReadChar());
				}
				else
				{
					mathlib.SetComp(ref client.cl.punchangle, i, 0f);
				}
				if ((bits & 32 << i) != 0)
				{
					mathlib.SetComp(ref client.cl.mvelocity[0], i, (float)(net.Reader.ReadChar() * 16));
				}
				else
				{
					mathlib.SetComp(ref client.cl.mvelocity[0], i, 0f);
				}
			}
			int j = net.Reader.ReadLong();
			if (client.cl.items != j)
			{
				sbar.Changed();
				for (int k = 0; k < 32; k++)
				{
					if ((j & 1 << k) != 0 && (client.cl.items & 1 << k) == 0)
					{
						client.cl.item_gettime[k] = (float)client.cl.time;
					}
				}
				client.cl.items = j;
			}
			client.cl.onground = ((bits & 1024) != 0);
			client.cl.inwater = ((bits & 2048) != 0);
			if ((bits & 4096) != 0)
			{
				client.cl.stats[QStats.STAT_WEAPONFRAME] = net.Reader.ReadByte();
			}
			else
			{
				client.cl.stats[QStats.STAT_WEAPONFRAME] = 0;
			}
			if ((bits & 8192) != 0)
			{
				j = net.Reader.ReadByte();
			}
			else
			{
				j = 0;
			}
			if (client.cl.stats[QStats.STAT_ARMOR] != j)
			{
				client.cl.stats[QStats.STAT_ARMOR] = j;
				sbar.Changed();
			}
			if ((bits & 16384) != 0)
			{
				j = net.Reader.ReadByte();
			}
			else
			{
				j = 0;
			}
			if (client.cl.stats[QStats.STAT_WEAPON] != j)
			{
				client.cl.stats[QStats.STAT_WEAPON] = j;
				sbar.Changed();
			}
			j = net.Reader.ReadShort();
			if (client.cl.stats[QStats.STAT_HEALTH] != j)
			{
				client.cl.stats[QStats.STAT_HEALTH] = j;
				sbar.Changed();
			}
			j = net.Reader.ReadByte();
			if (client.cl.stats[QStats.STAT_AMMO] != j)
			{
				client.cl.stats[QStats.STAT_AMMO] = j;
				sbar.Changed();
			}
			for (j = 0; j < 4; j++)
			{
				int num = net.Reader.ReadByte();
				if (client.cl.stats[QStats.STAT_SHELLS + j] != num)
				{
					client.cl.stats[QStats.STAT_SHELLS + j] = num;
					sbar.Changed();
				}
			}
			j = net.Reader.ReadByte();
			if (common.GameKind == GameKind.StandardQuake)
			{
				if (client.cl.stats[QStats.STAT_ACTIVEWEAPON] != j)
				{
					client.cl.stats[QStats.STAT_ACTIVEWEAPON] = j;
					sbar.Changed();
					return;
				}
			}
			else if (client.cl.stats[QStats.STAT_ACTIVEWEAPON] != 1 << j)
			{
				client.cl.stats[QStats.STAT_ACTIVEWEAPON] = 1 << j;
				sbar.Changed();
			}
		}

		private static void ParseServerInfo()
		{
			Con.DPrint("Serverinfo packet received.\n", Array.Empty<object>());
			client.ClearState();
			int i = net.Reader.ReadLong();
			if (i != 15)
			{
				Con.Print("Server returned version {0}, not {1}", new object[]
				{
					i,
					15
				});
				return;
			}
			client.cl.maxclients = net.Reader.ReadByte();
			if (client.cl.maxclients < 1 || client.cl.maxclients > 16)
			{
				Con.Print("Bad maxclients ({0}) from server\n", new object[]
				{
					client.cl.maxclients
				});
				return;
			}
			client.cl.scores = new scoreboard_t[client.cl.maxclients];
			for (i = 0; i < client.cl.scores.Length; i++)
			{
				client.cl.scores[i] = new scoreboard_t();
			}
			client.cl.gametype = net.Reader.ReadByte();
			string text = net.Reader.ReadString();
			client.cl.levelname = common.Copy(text, 40);
			Con.Print("\n\n\u001d\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001f\n\n", Array.Empty<object>());
			Con.Print("{0}{1}\n", new object[]
			{
				'\u0002',
				text
			});
			Array.Clear(client.cl.model_precache, 0, client.cl.model_precache.Length);
			string[] array = new string[256];
			int num = 1;
			for (;;)
			{
				text = net.Reader.ReadString();
				if (string.IsNullOrEmpty(text))
				{
					goto IL_19C;
				}
				if (num == 256)
				{
					break;
				}
				array[num] = text;
				Mod.TouchModel(text);
				num++;
			}
			Con.Print("Server sent too many model precaches\n", Array.Empty<object>());
			return;
			IL_19C:
			Array.Clear(client.cl.sound_precache, 0, client.cl.sound_precache.Length);
			string[] array2 = new string[256];
			int num2 = 1;
			for (;;)
			{
				text = net.Reader.ReadString();
				if (string.IsNullOrEmpty(text))
				{
					goto IL_207;
				}
				if (num2 == 256)
				{
					break;
				}
				array2[num2] = text;
				snd.TouchSound(text);
				num2++;
			}
			Con.Print("Server sent too many sound precaches\n", Array.Empty<object>());
			return;
			IL_207:
			for (i = 1; i < num; i++)
			{
				client.cl.model_precache[i] = Mod.ForName(array[i], false);
				if (client.cl.model_precache[i] == null)
				{
					Con.Print("Model {0} not found\n", new object[]
					{
						array[i]
					});
					return;
				}
				client.KeepaliveMessage();
			}
			snd.BeginPrecaching();
			for (i = 1; i < num2; i++)
			{
				client.cl.sound_precache[i] = snd.PrecacheSound(array2[i]);
				client.KeepaliveMessage();
			}
			snd.EndPrecaching();
			client._Entities[0].model = (client.cl.worldmodel = client.cl.model_precache[1]);
			render.NewMap();
			host.NoClipAngleHack = false;
			GC.Collect();
		}

		private static void ParseStartSoundPacket()
		{
			int num = net.Reader.ReadByte();
			int num2;
			if ((num & 1) != 0)
			{
				num2 = net.Reader.ReadByte();
			}
			else
			{
				num2 = 255;
			}
			float attenuation;
			if ((num & 2) != 0)
			{
				attenuation = (float)net.Reader.ReadByte() / 64f;
			}
			else
			{
				attenuation = 1f;
			}
			int num3 = net.Reader.ReadShort();
			int num4 = net.Reader.ReadByte();
			int num5 = num3 >> 3;
			num3 &= 7;
			if (num5 > 600)
			{
				host.Error("CL_ParseStartSoundPacket: ent = {0}", new object[]
				{
					num5
				});
			}
			Vector3 vector = net.Reader.ReadCoords();
			snd.StartSound(num5, num3, client.cl.sound_precache[num4], ref vector, (float)num2 / 255f, attenuation);
		}

		private static void NewTranslation(int slot)
		{
			if (slot > client.cl.maxclients)
			{
				sys.Error("CL_NewTranslation: slot > cl.maxclients", Array.Empty<object>());
			}
			byte[] translations = client.cl.scores[slot].translations;
			byte[] colormap = Scr.vid.colormap;
			Array.Copy(colormap, translations, translations.Length);
			int num = client.cl.scores[slot].colors & 240;
			int num2 = (client.cl.scores[slot].colors & 15) << 4;
			render.TranslatePlayerSkin(slot);
			int i = 0;
			int num3 = 0;
			while (i < 64)
			{
				if (num < 128)
				{
					Buffer.BlockCopy(colormap, num3 + num, translations, num3 + 16, 16);
				}
				else
				{
					for (int j = 0; j < 16; j++)
					{
						translations[num3 + 16 + j] = colormap[num3 + num + 15 - j];
					}
				}
				if (num2 < 128)
				{
					Buffer.BlockCopy(colormap, num3 + num2, translations, num3 + 96, 16);
				}
				else
				{
					for (int k = 0; k < 16; k++)
					{
						translations[num3 + 96 + k] = colormap[num3 + num2 + 15 - k];
					}
				}
				num3 += 256;
				i++;
			}
		}

		private static entity_t EntityNum(int num)
		{
			if (num >= client.cl.num_entities)
			{
				if (num >= 600)
				{
					host.Error("CL_EntityNum: %i is an invalid number", new object[]
					{
						num
					});
				}
				while (client.cl.num_entities <= num)
				{
					client._Entities[client.cl.num_entities].colormap = Scr.vid.colormap;
					client.cl.num_entities++;
				}
			}
			return client._Entities[num];
		}

		private static void ParseBaseline(entity_t ent)
		{
			ent.baseline.modelindex = net.Reader.ReadByte();
			ent.baseline.frame = net.Reader.ReadByte();
			ent.baseline.colormap = net.Reader.ReadByte();
			ent.baseline.skin = net.Reader.ReadByte();
			ent.baseline.origin.x = net.Reader.ReadCoord();
			ent.baseline.angles.x = net.Reader.ReadAngle();
			ent.baseline.origin.y = net.Reader.ReadCoord();
			ent.baseline.angles.y = net.Reader.ReadAngle();
			ent.baseline.origin.z = net.Reader.ReadCoord();
			ent.baseline.angles.z = net.Reader.ReadAngle();
		}

		private static void ParseStatic()
		{
			int num_statics = client.cl.num_statics;
			if (num_statics >= 128)
			{
				host.Error("Too many static entities", Array.Empty<object>());
			}
			entity_t entity_t = client._StaticEntities[num_statics];
			client.cl.num_statics++;
			client.ParseBaseline(entity_t);
			entity_t.model = client.cl.model_precache[entity_t.baseline.modelindex];
			entity_t.frame = entity_t.baseline.frame;
			entity_t.colormap = Scr.vid.colormap;
			entity_t.skinnum = entity_t.baseline.skin;
			entity_t.effects = entity_t.baseline.effects;
			entity_t.origin = common.ToVector(ref entity_t.baseline.origin);
			entity_t.angles = common.ToVector(ref entity_t.baseline.angles);
			render.AddEfrags(entity_t);
		}

		private static void ParseStaticSound()
		{
			Vector3 vector = net.Reader.ReadCoords();
			int num = net.Reader.ReadByte();
			int num2 = net.Reader.ReadByte();
			int num3 = net.Reader.ReadByte();
			snd.StaticSound(client.cl.sound_precache[num], ref vector, (float)num2, (float)num3);
		}

		private static void KeepaliveMessage()
		{
			if (server.IsActive)
			{
				return;
			}
			if (client.cls.demoplayback)
			{
				return;
			}
			net.Message.SaveState(ref client._MsgState);
			int message;
			do
			{
				message = client.GetMessage();
				switch (message)
				{
				case 0:
					break;
				case 1:
					host.Error("CL_KeepaliveMessage: received a message", Array.Empty<object>());
					break;
				case 2:
					if (net.Reader.ReadByte() != 1)
					{
						host.Error("CL_KeepaliveMessage: datagram wasn't a nop", Array.Empty<object>());
					}
					break;
				default:
					host.Error("CL_KeepaliveMessage: CL_GetMessage failed", Array.Empty<object>());
					break;
				}
			}
			while (message != 0);
			net.Message.RestoreState(client._MsgState);
			float num = (float)sys.GetFloatTime();
			if (num - client._LastMsg < 5f)
			{
				return;
			}
			client._LastMsg = num;
			Con.Print("--> client to server keepalive\n", Array.Empty<object>());
			client.cls.message.WriteByte(1);
			net.SendMessage(client.cls.netcon, client.cls.message);
			client.cls.message.Clear();
		}

		private static void InitTempEntities()
		{
			client._SfxWizHit = snd.PrecacheSound("wizard/hit.wav");
			client._SfxKnigtHit = snd.PrecacheSound("hknight/hit.wav");
			client._SfxTink1 = snd.PrecacheSound("weapons/tink1.wav");
			client._SfxRic1 = snd.PrecacheSound("weapons/ric1.wav");
			client._SfxRic2 = snd.PrecacheSound("weapons/ric2.wav");
			client._SfxRic3 = snd.PrecacheSound("weapons/ric3.wav");
			client._SfxRExp3 = snd.PrecacheSound("weapons/r_exp3.wav");
			for (int i = 0; i < client._TempEntities.Length; i++)
			{
				client._TempEntities[i] = new entity_t();
			}
			for (int j = 0; j < client._Beams.Length; j++)
			{
				client._Beams[j] = new beam_t();
			}
		}

		private static void UpdateTempEntities()
		{
			client._NumTempEntities = 0;
			for (int i = 0; i < 24; i++)
			{
				beam_t beam_t = client._Beams[i];
				if (beam_t.model != null && (double)beam_t.endtime >= client.cl.time)
				{
					if (beam_t.entity == client.cl.viewentity)
					{
						beam_t.start = client._Entities[client.cl.viewentity].origin;
					}
					Vector3 vector = beam_t.end - beam_t.start;
					float num;
					float num2;
					if (vector.Y == 0f && vector.X == 0f)
					{
						num = 0f;
						if (vector.Z > 0f)
						{
							num2 = 90f;
						}
						else
						{
							num2 = 270f;
						}
					}
					else
					{
						num = (float)((int)(Math.Atan2((double)vector.Y, (double)vector.X) * 180.0 / 3.1415926535897931));
						if (num < 0f)
						{
							num += 360f;
						}
						float num3 = (float)Math.Sqrt((double)(vector.X * vector.X + vector.Y * vector.Y));
						num2 = (float)((int)(Math.Atan2((double)vector.Z, (double)num3) * 180.0 / 3.1415926535897931));
						if (num2 < 0f)
						{
							num2 += 360f;
						}
					}
					Vector3 vector2 = beam_t.start;
					for (float num4 = mathlib.Normalize(ref vector); num4 > 0f; num4 -= 30f)
					{
						entity_t entity_t = client.NewTempEntity();
						if (entity_t == null)
						{
							return;
						}
						entity_t.origin = vector2;
						entity_t.model = beam_t.model;
						entity_t.angles.X = num2;
						entity_t.angles.Y = num;
						entity_t.angles.Z = (float)(sys.Random() % 360);
						vector2 += vector * 30f;
					}
				}
			}
		}

		private static entity_t NewTempEntity()
		{
			if (client.NumVisEdicts == 256)
			{
				return null;
			}
			if (client._NumTempEntities == 64)
			{
				return null;
			}
			entity_t entity_t = client._TempEntities[client._NumTempEntities];
			client._NumTempEntities++;
			client._VisEdicts[client.NumVisEdicts] = entity_t;
			client.NumVisEdicts++;
			entity_t.colormap = Scr.vid.colormap;
			return entity_t;
		}

		private static void ParseTempEntity()
		{
			switch (net.Reader.ReadByte())
			{
			case 0:
			{
				Vector3 origin = net.Reader.ReadCoords();
				render.RunParticleEffect(ref origin, ref common.ZeroVector, 0, 10);
				if (sys.Random() % 5 != 0)
				{
					snd.StartSound(-1, 0, client._SfxTink1, ref origin, 1f, 1f);
					return;
				}
				int num = sys.Random() & 3;
				if (num == 1)
				{
					snd.StartSound(-1, 0, client._SfxRic1, ref origin, 1f, 1f);
					return;
				}
				if (num == 2)
				{
					snd.StartSound(-1, 0, client._SfxRic2, ref origin, 1f, 1f);
					return;
				}
				snd.StartSound(-1, 0, client._SfxRic3, ref origin, 1f, 1f);
				return;
			}
			case 1:
			{
				Vector3 origin = net.Reader.ReadCoords();
				render.RunParticleEffect(ref origin, ref common.ZeroVector, 0, 20);
				if (sys.Random() % 5 != 0)
				{
					snd.StartSound(-1, 0, client._SfxTink1, ref origin, 1f, 1f);
					return;
				}
				int num2 = sys.Random() & 3;
				if (num2 == 1)
				{
					snd.StartSound(-1, 0, client._SfxRic1, ref origin, 1f, 1f);
					return;
				}
				if (num2 == 2)
				{
					snd.StartSound(-1, 0, client._SfxRic2, ref origin, 1f, 1f);
					return;
				}
				snd.StartSound(-1, 0, client._SfxRic3, ref origin, 1f, 1f);
				return;
			}
			case 2:
			{
				Vector3 origin = net.Reader.ReadCoords();
				render.RunParticleEffect(ref origin, ref common.ZeroVector, 0, 20);
				return;
			}
			case 3:
			{
				Vector3 origin = net.Reader.ReadCoords();
				render.ParticleExplosion(ref origin);
				dlight_t dlight_t = client.AllocDlight(0);
				dlight_t.origin = origin;
				dlight_t.radius = 350f;
				dlight_t.die = (float)client.cl.time + 0.5f;
				dlight_t.decay = 300f;
				snd.StartSound(-1, 0, client._SfxRExp3, ref origin, 1f, 1f);
				return;
			}
			case 4:
			{
				Vector3 origin = net.Reader.ReadCoords();
				render.BlobExplosion(ref origin);
				snd.StartSound(-1, 0, client._SfxRExp3, ref origin, 1f, 1f);
				return;
			}
			case 5:
				client.ParseBeam(Mod.ForName("progs/bolt.mdl", true));
				return;
			case 6:
				client.ParseBeam(Mod.ForName("progs/bolt2.mdl", true));
				return;
			case 7:
			{
				Vector3 origin = net.Reader.ReadCoords();
				render.RunParticleEffect(ref origin, ref common.ZeroVector, 20, 30);
				snd.StartSound(-1, 0, client._SfxWizHit, ref origin, 1f, 1f);
				return;
			}
			case 8:
			{
				Vector3 origin = net.Reader.ReadCoords();
				render.RunParticleEffect(ref origin, ref common.ZeroVector, 226, 20);
				snd.StartSound(-1, 0, client._SfxKnigtHit, ref origin, 1f, 1f);
				return;
			}
			case 9:
				client.ParseBeam(Mod.ForName("progs/bolt3.mdl", true));
				return;
			case 10:
			{
				Vector3 origin = net.Reader.ReadCoords();
				render.LavaSplash(ref origin);
				return;
			}
			case 11:
			{
				Vector3 origin = net.Reader.ReadCoords();
				render.TeleportSplash(ref origin);
				return;
			}
			case 12:
			{
				Vector3 origin = net.Reader.ReadCoords();
				int colorStart = net.Reader.ReadByte();
				int colorLength = net.Reader.ReadByte();
				render.ParticleExplosion(ref origin, colorStart, colorLength);
				dlight_t dlight_t2 = client.AllocDlight(0);
				dlight_t2.origin = origin;
				dlight_t2.radius = 350f;
				dlight_t2.die = (float)client.cl.time + 0.5f;
				dlight_t2.decay = 300f;
				snd.StartSound(-1, 0, client._SfxRExp3, ref origin, 1f, 1f);
				return;
			}
			case 13:
				client.ParseBeam(Mod.ForName("progs/beam.mdl", true));
				return;
			default:
				sys.Error("CL_ParseTEnt: bad type", Array.Empty<object>());
				return;
			}
		}

		private static void ParseBeam(model_t m)
		{
			int num = net.Reader.ReadShort();
			Vector3 start = net.Reader.ReadCoords();
			Vector3 end = net.Reader.ReadCoords();
			for (int i = 0; i < 24; i++)
			{
				beam_t beam_t = client._Beams[i];
				if (beam_t.entity == num)
				{
					beam_t.entity = num;
					beam_t.model = m;
					beam_t.endtime = (float)(client.cl.time + 0.2);
					beam_t.start = start;
					beam_t.end = end;
					return;
				}
			}
			for (int j = 0; j < 24; j++)
			{
				beam_t beam_t2 = client._Beams[j];
				if (beam_t2.model == null || (double)beam_t2.endtime < client.cl.time)
				{
					beam_t2.entity = num;
					beam_t2.model = m;
					beam_t2.endtime = (float)(client.cl.time + 0.2);
					beam_t2.start = start;
					beam_t2.end = end;
					return;
				}
			}
			Con.Print("beam list overflow!\n", Array.Empty<object>());
		}

		public const int SIGNONS = 4;

		public const int MAX_DLIGHTS = 32;

		public const int MAX_BEAMS = 24;

		public const int MAX_EFRAGS = 640;

		public const int MAX_MAPSTRING = 2048;

		public const int MAX_DEMOS = 8;

		public const int MAX_DEMONAME = 16;

		public const int MAX_VISEDICTS = 256;

		public static int NumVisEdicts;

		private const int MAX_TEMP_ENTITIES = 64;

		private const int MAX_STATIC_ENTITIES = 128;

		private static client_static_t _Static = new client_static_t();

		private static client_state_t _State = new client_state_t();

		private static efrag_t[] _EFrags = new efrag_t[640];

		private static entity_t[] _Entities = new entity_t[600];

		private static entity_t[] _StaticEntities = new entity_t[128];

		private static lightstyle_t[] _LightStyle = new lightstyle_t[64];

		private static dlight_t[] _DLights = new dlight_t[32];

		private static cvar _Name;

		private static cvar _Color;

		private static cvar _ShowNet;

		private static cvar _NoLerp;

		private static cvar _LookSpring;

		private static cvar _LookStrafe;

		private static cvar _Sensitivity;

		private static cvar _MPitch;

		private static cvar _MYaw;

		private static cvar _MForward;

		private static cvar _MSide;

		private static cvar _UpSpeed;

		private static cvar _ForwardSpeed;

		private static cvar _BackSpeed;

		private static cvar _SideSpeed;

		private static cvar _MoveSpeedKey;

		private static cvar _YawSpeed;

		private static cvar _PitchSpeed;

		private static cvar _AngleSpeedKey;

		private static entity_t[] _VisEdicts = new entity_t[256];

		private const string ConsoleBar = "\n\n\u001d\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001e\u001f\n\n";

		private static string[] _SvcStrings = new string[]
		{
			"svc_bad",
			"svc_nop",
			"svc_disconnect",
			"svc_updatestat",
			"svc_version",
			"svc_setview",
			"svc_sound",
			"svc_time",
			"svc_print",
			"svc_stufftext",
			"svc_setangle",
			"svc_serverinfo",
			"svc_lightstyle",
			"svc_updatename",
			"svc_updatefrags",
			"svc_clientdata",
			"svc_stopsound",
			"svc_updatecolors",
			"svc_particle",
			"svc_damage",
			"svc_spawnstatic",
			"OBSOLETE svc_spawnbinary",
			"svc_spawnbaseline",
			"svc_temp_entity",
			"svc_setpause",
			"svc_signonnum",
			"svc_centerprint",
			"svc_killedmonster",
			"svc_foundsecret",
			"svc_spawnstaticsound",
			"svc_intermission",
			"svc_finale",
			"svc_cdtrack",
			"svc_sellscreen",
			"svc_cutscene"
		};

		private static int[] _BitCounts = new int[16];

		private static object _MsgState;

		private static float _LastMsg;

		private static int _NumTempEntities;

		private static entity_t[] _TempEntities = new entity_t[64];

		private static beam_t[] _Beams = new beam_t[24];

		private static sfx_t _SfxWizHit;

		private static sfx_t _SfxKnigtHit;

		private static sfx_t _SfxTink1;

		private static sfx_t _SfxRic1;

		private static sfx_t _SfxRic2;

		private static sfx_t _SfxRic3;

		private static sfx_t _SfxRExp3;
	}
}
