예제 #1
0
		public override void AuthoritativeChangePosition(StateUpdateData data, double time)
		{
			ServerPosition = data.Position;
			StateHistory.AddSnapshot(
				data,
				GetCurrentTimeSeconds());
		}
예제 #2
0
			public CorrectionInfo(double time, Vec2 pos, Vec2 vel, ulong lastAckId)
			{
				Time = time;
				Position = pos;
				Velocity = vel;
				LastAcknowledgedActionId = lastAckId;
			}
예제 #3
0
		public PlayerAction(ulong id, PlayerActionType type, float time, Vec2 position, Vec2 target = null)
			: this()
		{
			ID = id;
			Type = type;
			Time = time;
			Position = position;
			Target = target;
		}
예제 #4
0
        public TeamStructures(Teams team, Vec2 baseTileIds, Vec2 baseTowerTileIds,
		                      Vec2 topTowerTileIds, Vec2 bottomTowerTileIds)
        {
			Structures = Utilities.MakeList<IStructure>(
				Base = new Base(team, GetFeetPosForStructure(baseTileIds)),
				BaseTower = new Tower(StructureTypes.BaseTower, team, GetFeetPosForStructure(baseTowerTileIds)),
				TopTower = new Tower(StructureTypes.TopTower, team, GetFeetPosForStructure(topTowerTileIds)),
				BottomTower = new Tower(StructureTypes.BottomTower, team, GetFeetPosForStructure(bottomTowerTileIds)));
        }
예제 #5
0
		public void CenterCameraTowards(Vec2 position, float screenWidth, float screenHeight, float worldWidth, float worldHeight)
		{
			var before = WorldPosition;
			WorldPosition = new Vec2(position.X - screenWidth / 2f, position.Y - screenHeight / 2f);
			WorldPosition.X = Math.Min(worldWidth - screenWidth, Math.Max(0f, WorldPosition.X));
			WorldPosition.Y = Math.Min(worldHeight - screenHeight * (1f - BOTTOM_MAX_LIMIT_EXTEND), Math.Max(0f, WorldPosition.Y));

			WorldPosition = Vec2.Lerp(before, WorldPosition, CAM_LERP_FACTOR);
		}
예제 #6
0
		void ChangeClonedEntity(IEntity e, Vec2 pos, Vec2 vel, float colW, float colH, float moveSpeed)
		{
			e.Position.X = pos.X;
			e.Position.Y = pos.Y;
			e.Velocity.X = vel.X;
			e.Velocity.Y = vel.Y;
			e.CollisionWidth = colW;
			e.CollisionHeight = colH;
			e.MoveSpeed = moveSpeed;
		}
예제 #7
0
        public IEntity(ulong id, Vec2 startingPosition,
		               float moveSpeed, float width, float height)
        {
			ID = id;
			Position = startingPosition;
			MoveSpeed = moveSpeed;
			CollisionWidth = width;
			CollisionHeight = height;

			Velocity = new Vec2();
        }
예제 #8
0
		public ClientLinearSpell(ulong id, SpellTypes type, Vec2 pos, float time, Vec2 velocity, float range, float width)
        {
			ID = id;
			Type = type;
			StartingPosition = pos;
			Position = StartingPosition;
			Velocity = velocity;
			Time = Math.Max(0f, (float)Client.Instance.GetTime().TotalSeconds - time);
			Active = true;
			Range = range;
			Width = width;
        }
예제 #9
0
		public SpellCastEventData(ulong id, ulong owner, SpellTypes type, float time, Vec2 pos, 
		                          Vec2 vel, TimeSpan cooldown, float range, float width)
			: base(ServerCommand.SpellCast)
		{
			ID = id;
			OwnerID = owner;
			Type = type;
			Time = time;
			Position = pos;
			Velocity = vel;
			Cooldown = cooldown;
			Range = range;
			Width = width;
		}
예제 #10
0
		public StateUpdateEventArgs(NetBuffer msg) : base(msg)
		{
			EntitiesUpdatedState = new List<StateUpdateData>();
			RemarkableEvents = new List<RemarkableEventData>();

			LastAcknowledgedActionID = msg.ReadUInt64();
			Time = msg.ReadDouble();
			Vec2 velocity = new Vec2(msg.ReadFloat(), msg.ReadFloat());
			byte nbClients = msg.ReadByte();
			for (byte i = 0; i < nbClients; ++i) {
				ulong id = msg.ReadUInt64();
				Vec2 pos = new Vec2(msg.ReadFloat(), msg.ReadFloat());
				ChampionAnimation anim = (ChampionAnimation)msg.ReadByte();
				bool facingLeft = msg.ReadBoolean();

				EntitiesUpdatedState.Add(new StateUpdateData(id, pos, velocity, anim, facingLeft));
			}
			while (msg.Position != msg.LengthBits) {
				ServerCommand cmd = (ServerCommand)msg.ReadByte();
				RemarkableEventData data = null;
				switch (cmd) {
					case ServerCommand.SpellCast:
						data = new SpellCastEventData(
							msg.ReadUInt64(),
							msg.ReadUInt64(),
							(SpellTypes)msg.ReadByte(),
							msg.ReadFloat(),
							new Vec2(msg.ReadFloat(), msg.ReadFloat()),
							new Vec2(msg.ReadFloat(), msg.ReadFloat()),
							TimeSpan.FromSeconds(msg.ReadFloat()),
							msg.ReadFloat(),
							msg.ReadFloat());
						break;

					case ServerCommand.SpellDisappear:
						data = new SpellDisappearEventData(msg.ReadUInt64());
						break;

					case ServerCommand.StatsChanged:
						data = new StatsChangedEventData(msg.ReadUInt64(), msg.ReadFloat());
						break;

					case ServerCommand.ChampionDied:
						data = new ChampionDiedEventData(msg.ReadUInt64(),
						                                 msg.ReadUInt64(),
						                                 msg.ReadUInt32(), msg.ReadUInt32(), msg.ReadUInt32(), msg.ReadUInt32(),
						                                 TimeSpan.FromSeconds(msg.ReadUInt16()));
						break;

					case ServerCommand.StructureStatsChanged:
						data = new StructureStatsChangedEventData(msg.ReadBoolean() ? Teams.Left : Teams.Right,
						                                          (StructureTypes)msg.ReadByte(),
						                                          msg.ReadFloat());
						break;

					case ServerCommand.StructureDestroyed:
						data = new StructureDestroyedEventData(msg.ReadBoolean() ? Teams.Left : Teams.Right,
						                                       (StructureTypes)msg.ReadByte());
						break;

					case ServerCommand.EndOfGame:
						data = new EndOfGameEventData(msg.ReadBoolean() ? Teams.Left : Teams.Right);
						break;

					case ServerCommand.TowerPreparingToShoot:
						data = new TowerPreparingToShootEventData(msg.ReadBoolean() ? Teams.Left : Teams.Right,
						                                          (StructureTypes)msg.ReadByte());
						break;

					default:
						Debug.Fail("Unknown server command when updating (unknown remarkable event)");
						break;
				}
				if (data != null) {
					RemarkableEvents.Add(data);
				}
			}
		}
예제 #11
0
		public StateUpdateData(ulong id, Vec2 pos, Vec2 vel, ChampionAnimation anim, bool facingLeft)
			: this()
		{
			ID = id;
			Position = pos;
			Velocity = vel;
			Animation = anim;
			FacingLeft = facingLeft;
		}
예제 #12
0
		public MainClientChampion(ChampionSpawnInfo spawnInfo, GameMatch match)
			: base(spawnInfo)
        {
			Match = match;

			ServerPosition = Position;
			ServerCorrectionUsed = Position;

			PackagedActions = new Queue<PlayerAction>();
			RecentActions = new List<PlayerAction>();
			Corrections = new List<CorrectionInfo>();
			Corrected = false;
			PreviousLastAck = IDGenerator.NO_ID;


			NoCorrections = (IEntity)this.Clone();
        }
예제 #13
0
        public CameraService()
        {
			WorldPosition = new Vec2();
        }
예제 #14
0
		void CastSpell(LinearSpell spell, Vec2 target)
		{
			Match.CurrentState.AddEntity(spell);
			ActiveSpells.Add(spell);

			float castTime = (float)Server.Instance.GetTime().TotalSeconds;
			LinearSpell copy = (LinearSpell)spell.Clone();

			AddRemarkableEvent(ServerCommand.SpellCast,
			                   (NetBuffer msg) => {
				ulong id = copy.ID;
				ulong owner = copy.Owner != null ? copy.Owner.ID : IDGenerator.NO_ID;
				byte type = (byte)copy.Type;
				float time = castTime;
				float px = copy.Position.X;
				float py = copy.Position.Y;
				float vx = copy.Velocity.X;
				float vy = copy.Velocity.Y;
				float cd = (float)copy.Info.Cooldown.TotalSeconds;
				float range = copy.Info.Range;
				float width = copy.CollisionWidth;

				msg.Write(id);
				msg.Write(owner);
				msg.Write(type);
				msg.Write(time);
				msg.Write(px);
				msg.Write(py);
				msg.Write(vx);
				msg.Write(vy);
				msg.Write(cd);
				msg.Write(range);
				msg.Write(width);
			});
		}
예제 #15
0
		public Vec2 ToWorld(Vec2 screenPos)
		{
			return screenPos + WorldPosition;
		}
예제 #16
0
		public static float DistanceSquared(Vec2 a, Vec2 b)
		{
			return (b - a).GetLengthSquared();
		}
예제 #17
0
		public static float Distance(Vec2 a, Vec2 b)
		{
			return (b - a).GetLength();
		}
예제 #18
0
		void OnActionPackage(NetIncomingMessage message)
		{
			Debug.Assert(Clients.ContainsKey(message.SenderConnection));

			try {
				while (message.Position < message.LengthBits) {
					ulong id = message.ReadUInt64();
					float time = message.ReadFloat();
					PlayerActionType type = (PlayerActionType)message.ReadByte();
					Vec2 position = new Vec2(message.ReadFloat(), message.ReadFloat());
					Vec2 target = ActionTypeHelper.IsSpell(type) ? new Vec2(message.ReadFloat(), message.ReadFloat()) : null;

					PlayerAction action = new PlayerAction(id, type, time, position, target);

					Clients[message.SenderConnection].ActionsPackage.Add(action);
				}
			} catch (Exception e) {
				ILogger.Log("Action package badly formatted: " + e.ToString(), LogPriority.Error);
			}
		}
예제 #19
0
		public void TestDistance(Vec2 a, Vec2 b, float dist, string msg, float eps = float.Epsilon)
		{
			Assert.AreEqual(dist, Vec2.Distance(a, b), eps, msg);
			Assert.AreEqual(dist * dist, Vec2.DistanceSquared(a, b), eps, msg + " squared");
		}
예제 #20
0
		void TestLength(Vec2 v, float length, string msg, float eps = float.Epsilon)
		{
			Assert.AreEqual(length, v.GetLength(), eps, msg);
			Assert.AreEqual(length * length, v.GetLengthSquared(), eps, msg + " squared");
		}
예제 #21
0
		void TestCtor(Vec2 v, float x, float y, string ctor)
		{
			Assert.AreEqual(x, v.X, float.Epsilon, "X " + ctor);
			Assert.AreEqual(y, v.Y, float.Epsilon, "Y " + ctor);
		}
예제 #22
0
		void PlaySound(Sounds s, Vec2 source = null)
		{
			var screen = (ScreenService)Services.GetService(typeof(ScreenService));
			Sound.PlaySound(SoundsHelper.GetSoundPath(s),
			                screen.GameWindowSize.X, screen.GameWindowSize.Y,
			                source != null ? (Vector2?)GameLibHelper.ToVector2(source) : null);
		}
예제 #23
0
		public ServerChampion(ulong id, Vec2 pos, ChampionTypes type, Teams team)
			: base(id, pos, type, team)
        {
        }
예제 #24
0
		void CastTowerSpell(Teams team, Vec2 origin, Vec2 target)
		{
			LinearSpell spell = new LinearSpell(
                IDGenerator.GenerateID(),
                team,
                origin,
                target,
                SpellTypes.Tower_Shot,
                null);

			CastSpell(spell, target);
		}
예제 #25
0
		private static Vec2 GetFeetPosForStructure(Vec2 tileIds)
		{
			return tileIds * new Vec2(Tile.WIDTH, Tile.HEIGHT) + new Vec2(Tile.WIDTH / 2f, Tile.HEIGHT);
		}
예제 #26
0
		public PlayerData(NetBuffer msg) : this()
		{
			ID = msg.ReadUInt64();
			Position = new Vec2(msg.ReadFloat(), msg.ReadFloat());
			Type = (ChampionTypes)msg.ReadByte();
			Team = msg.ReadBoolean() ? Teams.Left : Teams.Right;
			MaxHealth = msg.ReadFloat();
			Health = msg.ReadFloat();
		}
예제 #27
0
		/// <summary>
		/// Linear interpolation from a vector to another using a specified factor.
		/// </summary>
		/// <param name="start">Start vector.</param>
		/// <param name="goal">Goal vector.</param>
		/// <param name="factor">Factor of the linear interpolation.</param>
		public static Vec2 Lerp(Vec2 start, Vec2 goal, float factor)
		{
			return new Vec2(start.X + factor * (goal.X - start.X),
			                start.Y + factor * (goal.Y - start.Y));
		}
예제 #28
0
		/// <summary>
		/// Takes the acknowledge info from the server (the position and velocity correction along with
		/// the last acknowledged action) and incorporate it in our game.
		/// The way that this works is that we take the most recent usable correction (that is to say, the
		/// correction that happened before any of our not-yet-acknowledged actions), and resimulate the
		/// world along with the unacknowledged actions up until now. This should give results very similar
		/// to a game without correction without external interaction.
		/// </summary>
		void ApplyCorrection(double currentTime)
		{
			// get a correction from the server to work with
			CorrectionInfo corr = GetCorrectionBeforeUnackAction();
			if (corr == null) { // no correction to use.
				return;
			}

			ServerCorrectionUsed = corr.Position;

			// go back to our last acknowledged state (if any)
			double time = corr.Time;

			// apply the server's correction
			Position = corr.Position;
			Velocity = corr.Velocity;

			// resimulate up until the given state update
			for (int i = 0; i < RecentActions.Count; ++i) {
				if (RecentActions[i].ID > corr.LastAcknowledgedActionId) {
					var deltaT = RecentActions[i].Time - time;

					if (deltaT > 0) {
						Match.CurrentState.ApplyPhysicsUpdate(ID, deltaT);
					}

					ExecuteAction(RecentActions[i].Type);

					time = RecentActions[i].Time;
				}
			}

			var deltaTime = currentTime - time;
			if (deltaTime > 0) {
				Match.CurrentState.ApplyPhysicsUpdate(ID, deltaTime);
			}
		}
예제 #29
0
		public Vec2 ToScreen(Vec2 worldPos)
		{
			return worldPos - WorldPosition;
		}
예제 #30
0
		public static Vec2 Normalize(Vec2 vec)
		{
			Vec2 v = new Vec2(vec.X, vec.Y);
			v.Normalize();
			return v;
		}