Example #1
0
		/// <summary>
		/// Sends SkillInfo to creature's client.
		/// </summary>
		/// <param name="client"></param>
		/// <param name="creature"></param>
		/// <param name="skill"></param>
		public static void SkillInfo(Creature creature, Skill skill)
		{
			var packet = new Packet(Op.SkillInfo, creature.EntityId);
			packet.PutBin(skill.Info);

			creature.Client.Send(packet);
		}
Example #2
0
        /// <summary>
        /// Broadcasts CreatureBodyUpdate in range of creature.
        /// </summary>
        /// <param name="creature"></param>
        public static void CreatureBodyUpdate(Creature creature)
        {
            var packet = new Packet(Op.CreatureBodyUpdate, creature.EntityId);
            packet.PutBin(creature.Body);

            creature.Region.Broadcast(packet, creature);
        }
Example #3
0
        /// <summary>
        /// Sends NpcTalk to creature's client.
        /// </summary>
        /// <param name="creature"></param>
        /// <param name="xml"></param>
        public static void NpcTalk(Creature creature, string xml)
        {
            var packet = new Packet(Op.NpcTalk, creature.EntityId);
            packet.PutString(xml);
            packet.PutBin();

            creature.Client.Send(packet);
        }
Example #4
0
        /// <summary>
        /// Broadcasts EquipmentChanged in creature's range.
        /// </summary>
        /// <param name="creature"></param>
        /// <param name="item"></param>
        public static void EquipmentChanged(Creature creature, Item item)
        {
            var packet = new Packet(Op.EquipmentChanged, creature.EntityId);
            packet.PutBin(item.Info);
            packet.PutByte(1);

            creature.Region.Broadcast(packet, creature);
        }
Example #5
0
		/// <summary>
		/// Sends SkillRankUp to creature's client.
		/// </summary>
		/// <param name="client"></param>
		/// <param name="creature"></param>
		/// <param name="skill"></param>
		public static void SkillRankUp(Creature creature, Skill skill)
		{
			var packet = new Packet(Op.SkillRankUp, creature.EntityId);
			packet.PutByte(1);
			packet.PutBin(skill.Info);
			packet.PutFloat(0);

			creature.Client.Send(packet);
		}
Example #6
0
        /// <summary>
        /// Sends DyePickColorR to creature's client.
        /// </summary>
        /// <param name="creature"></param>
        /// <param name="success"></param>
        public static void DyePickColorR(Creature creature, bool success)
        {
            var packet = new Packet(Op.DyePickColorR, creature.EntityId);
            packet.PutByte(success);
            if (success)
                packet.PutBin(creature.Temp.RegularDyePickers);

            creature.Client.Send(packet);
        }
Example #7
0
        /// <summary>
        /// Sends EntitiesAppear to client, unless entities is empty.
        /// </summary>
        /// <param name="client"></param>
        /// <param name="entities"></param>
        public static void EntitiesAppear(ChannelClient client, IEnumerable<Entity> entities)
        {
            var count = (short)entities.Count();
            if (count < 1)
                return;

            var packet = new Packet(Op.EntitiesAppear, MabiId.Broadcast);
            packet.PutShort(count);
            foreach (var entity in entities)
            {
                var data = Packet.Empty().AddPublicEntityInfo(entity).Build(false);

                packet.PutShort((short)entity.DataType);
                packet.PutInt(data.Length);
                packet.PutBin(data);
            }

            client.Send(packet);
        }
Example #8
0
		/// <summary>
		/// Sends EntitiesAppear to client, unless entities is empty.
		/// </summary>
		/// <param name="client"></param>
		/// <param name="entities"></param>
		public static void EntitiesAppear(ChannelClient client, IEnumerable<Entity> entities)
		{
			// Count() is much faster then creating a list, speed being
			// important in this method.
			var count = (short)entities.Count();
			if (count < 1)
				return;

			var packet = new Packet(Op.EntitiesAppear, MabiId.Broadcast);
			packet.PutShort(count);
			foreach (var entity in entities)
			{
				var data = Packet.Empty().AddPublicEntityInfo(entity).Build();

				packet.PutShort((short)entity.DataType);
				packet.PutInt(data.Length);
				packet.PutBin(data);
			}

			client.Send(packet);
		}
Example #9
0
		/// <summary>
		/// Broadcasts CombatActionPack in range of pack's attacker.
		/// </summary>
		/// <param name="pack"></param>
		public static void CombatAction(CombatActionPack pack)
		{
			var attackerPos = pack.Attacker.GetPosition();

			var packet = new Packet(Op.CombatActionPack, MabiId.Broadcast);
			packet.PutInt(pack.Id);
			packet.PutInt(pack.PrevId);
			packet.PutByte(pack.Hit);
			packet.PutByte((byte)pack.Type);
			packet.PutByte(pack.Flags);
			if ((pack.Flags & 1) == 1)
			{
				packet.PutInt(pack.BlockedByShieldPosX);
				packet.PutInt(pack.BlockedByShieldPosY);
				packet.PutLong(pack.ShieldCasterId);
			}

			// Actions
			packet.PutInt(pack.Actions.Count);
			Packet actionPacket = null;
			foreach (var action in pack.Actions)
			{
				var pos = action.Creature.GetPosition();

				if (actionPacket == null)
					actionPacket = new Packet(Op.CombatAction, action.Creature.EntityId);
				else
					actionPacket.Clear(Op.CombatAction, action.Creature.EntityId);
				actionPacket.PutInt(pack.Id);
				actionPacket.PutLong(action.Creature.EntityId);
				actionPacket.PutByte((byte)action.Flags);
				actionPacket.PutShort(action.Stun);
				actionPacket.PutUShort((ushort)action.SkillId);
				actionPacket.PutUShort((ushort)action.SecondarySkillId);

				// Official name for CombatAction is CombatScene, and both Actions are Combatant.
				// Official client distinguish between Attacker and Defender simply by checking Flags. tachiorz

				// AttackerAction
				//if ((action.Flags & CombatActionFlags.Attacker) != 0)
				if (action.Category == CombatActionCategory.Attack)
				{
					var aAction = action as AttackerAction;

					actionPacket.PutLong(aAction.TargetId);
					actionPacket.PutUInt((uint)aAction.Options);
					actionPacket.PutByte(aAction.UsedWeaponSet);
					actionPacket.PutByte(aAction.WeaponParameterType); // !aAction.Has(AttackerOptions.KnockBackHit2) ? 2 : 1)); // ?
					actionPacket.PutInt(pos.X);
					actionPacket.PutInt(pos.Y);

					if ((aAction.Options & AttackerOptions.Dashed) != 0)
					{
						actionPacket.PutFloat(0); // DashedPosX
						actionPacket.PutFloat(0); // DashedPosY
						actionPacket.PutUInt(0); // DashDelay
					}

					if ((aAction.Options & AttackerOptions.PhaseAttack) != 0)
						actionPacket.PutByte(aAction.Phase);

					if ((aAction.Options & AttackerOptions.UseEffect) != 0)
						actionPacket.PutLong(aAction.PropId);
				}
				// TargetAction
				//if ((action.Flags & CombatActionFlags.TakeHit) != 0)
				else if (action.Category == CombatActionCategory.Target && !action.Is(CombatActionType.None))
				{
					var tAction = action as TargetAction;

					// Target used Defense or Counter
					if ((action.Flags & CombatActionType.Attacker) != 0)
					{
						actionPacket.PutLong(tAction.Attacker.EntityId);
						actionPacket.PutInt(0); // attacker Options
						actionPacket.PutByte(tAction.UsedWeaponSet);
						actionPacket.PutByte(tAction.WeaponParameterType);
						actionPacket.PutInt(pos.X);
						actionPacket.PutInt(pos.Y);
					}

					actionPacket.PutUInt((uint)tAction.Options);
					actionPacket.PutFloat(tAction.Damage);
					actionPacket.PutFloat(tAction.Wound);
					actionPacket.PutInt((int)tAction.ManaDamage);

					actionPacket.PutFloat(attackerPos.X - pos.X);
					actionPacket.PutFloat(attackerPos.Y - pos.Y);
					if (tAction.IsKnockBack)
					{
						actionPacket.PutFloat(pos.X);
						actionPacket.PutFloat(pos.Y);

						// [190200, NA203 (22.04.2015)]
						{
							actionPacket.PutInt(0);
						}
					}

					if ((tAction.Options & TargetOptions.MultiHit) != 0)
					{
						actionPacket.PutUInt(0); // MultiHitDamageCount
						actionPacket.PutUInt(0); // MultiHitDamageShowTime
					}
					actionPacket.PutByte((byte)tAction.EffectFlags);
					actionPacket.PutInt(tAction.Delay);
					actionPacket.PutLong(tAction.Attacker.EntityId);
				}

				packet.PutBin(actionPacket);
			}

			pack.Attacker.Region.Broadcast(packet, pack.Attacker);
		}
Example #10
0
		/// <summary>
		/// Sends PlayCutscene to creature's client.
		/// </summary>
		/// <param name="creature"></param>
		/// <param name="cutscene"></param>
		public static void PlayCutscene(Creature creature, Cutscene cutscene)
		{
			var packet = new Packet(Op.PlayCutscene, MabiId.Channel);
			packet.PutLong(creature.EntityId);
			packet.PutLong(cutscene.Leader.EntityId);
			packet.PutString(cutscene.Name);

			packet.PutInt(cutscene.Actors.Count);
			foreach (var actor in cutscene.Actors)
			{
				var subPacket = Packet.Empty();
				subPacket.AddCreatureInfo(actor.Value, CreaturePacketType.Public);
				var bArr = subPacket.Build();

				packet.PutString(actor.Key);
				packet.PutShort((short)bArr.Length);
				packet.PutBin(bArr);
			}

			packet.PutInt(1); // count?
			packet.PutLong(creature.EntityId);

			// TODO: Send to whole party?
			creature.Client.Send(packet);
		}
Example #11
0
		/// <summary>
		/// Broadcasts CombatActionPack in range of pack's attacker.
		/// </summary>
		/// <param name="pack"></param>
		public static void CombatAction(CombatActionPack pack)
		{
			var attackerPos = pack.Attacker.GetPosition();

			var packet = new Packet(Op.CombatActionPack, MabiId.Broadcast);
			packet.PutInt(pack.Id);
			packet.PutInt(pack.PrevId);
			packet.PutByte(pack.Hit);
			packet.PutByte(pack.MaxHits);
			packet.PutByte(0);

			// Actions
			packet.PutInt(pack.Actions.Count);
			Packet actionPacket = null;
			foreach (var action in pack.Actions)
			{
				var pos = action.Creature.GetPosition();

				if (actionPacket == null)
					actionPacket = new Packet(Op.CombatAction, action.Creature.EntityId);
				else
					actionPacket.Clear(Op.CombatAction, action.Creature.EntityId);
				actionPacket.PutInt(pack.Id);
				actionPacket.PutLong(action.Creature.EntityId);
				actionPacket.PutByte((byte)action.Type);
				actionPacket.PutShort(action.Stun);
				actionPacket.PutUShort((ushort)action.SkillId);
				actionPacket.PutShort(0);

				// AttackerAction
				if (action.Category == CombatActionCategory.Attack)
				{
					var aAction = action as AttackerAction;

					actionPacket.PutLong(aAction.TargetId);
					actionPacket.PutUInt((uint)aAction.Options);
					actionPacket.PutByte(0);
					actionPacket.PutByte((byte)(!aAction.Has(AttackerOptions.KnockBackHit2) ? 2 : 1)); // ?
					actionPacket.PutInt(pos.X);
					actionPacket.PutInt(pos.Y);
					if (aAction.PropId != 0)
						actionPacket.PutLong(aAction.PropId);
				}
				// TargetAction
				else if (action.Category == CombatActionCategory.Target && !action.Is(CombatActionType.None))
				{
					var tAction = action as TargetAction;

					// Target used Defense or Counter
					if (tAction.Is(CombatActionType.Defended) || tAction.Is(CombatActionType.CounteredHit) || tAction.Is(CombatActionType.CounteredHit2))
					{
						actionPacket.PutLong(tAction.Attacker.EntityId);
						actionPacket.PutInt(0);
						actionPacket.PutByte(0);
						actionPacket.PutByte(1);
						actionPacket.PutInt(pos.X);
						actionPacket.PutInt(pos.Y);
					}

					actionPacket.PutUInt((uint)tAction.Options);
					actionPacket.PutFloat(tAction.Damage);
					actionPacket.PutFloat(0); // Related to mana damage?
					actionPacket.PutInt((int)tAction.ManaDamage);

					actionPacket.PutFloat(attackerPos.X - pos.X);
					actionPacket.PutFloat(attackerPos.Y - pos.Y);
					if (tAction.IsKnockBack)
					{
						actionPacket.PutFloat(pos.X);
						actionPacket.PutFloat(pos.Y);

						// [190200, NA203 (22.04.2015)]
						{
							actionPacket.PutInt(0);
						}
					}

					actionPacket.PutByte(0); // PDef? Seen as 0x20 in a normal attack (G18)
					actionPacket.PutInt(tAction.Delay);
					actionPacket.PutLong(tAction.Attacker.EntityId);
				}

				packet.PutBin(actionPacket);
			}

			pack.Attacker.Region.Broadcast(packet, pack.Attacker);
		}
Example #12
0
		/// <summary>
		/// Sends xInfoRequestR to client.
		/// </summary>
		/// <param name="client"></param>
		/// <param name="op"></param>
		/// <param name="character"></param>
		/// <param name="items"></param>
		public static void CharacterInfoRequestR(LoginClient client, int op, Character character, List<Item> items)
		{
			var packet = new Packet(op, MabiId.Login);
			packet.PutByte(character != null);

			if (character != null)
			{
				packet.PutString(character.Server);
				packet.PutLong(character.EntityId);
				packet.PutByte(1);
				packet.PutString(character.Name);
				packet.PutString("");
				packet.PutString("");
				packet.PutInt(character.Race);
				packet.PutByte(character.SkinColor);
				packet.PutShort(character.EyeType);
				packet.PutByte(character.EyeColor);
				packet.PutByte(character.MouthType);
				packet.PutUInt((uint)character.State);
				packet.PutFloat(character.Height);
				packet.PutFloat(character.Weight);
				packet.PutFloat(character.Upper);
				packet.PutFloat(character.Lower);
				packet.PutInt(0);
				packet.PutInt(0);
				packet.PutInt(0);
				packet.PutByte(0);
				packet.PutInt(0);
				packet.PutByte(0);
				packet.PutInt((int)character.Color1);
				packet.PutInt((int)character.Color2);
				packet.PutInt((int)character.Color3);
				packet.PutFloat(0.0f);
				packet.PutString("");
				packet.PutFloat(49.0f);
				packet.PutFloat(49.0f);
				packet.PutFloat(0.0f);
				packet.PutFloat(49.0f);
				// [180800, NA196 (14.10.2014)] ?
				{
					packet.PutShort(0);
				}
				packet.PutInt(0);
				packet.PutInt(0);
				packet.PutShort(0);
				packet.PutLong(0);
				packet.PutString("");
				packet.PutByte(0);

				packet.PutInt(items.Count);
				foreach (var item in items)
				{
					packet.PutLong(item.Id);
					packet.PutBin(item.Info);
				}

				packet.PutInt(0);  // PetRemainingTime
				packet.PutLong(0); // PetLastTime
				packet.PutLong(0); // PetExpireTime
			}

			client.Send(packet);
		}
Example #13
0
        /// <summary>
        /// Sends SkillTrainingUp to creature's client.
        /// </summary>
        /// <param name="creature"></param>
        /// <param name="skill"></param>
        /// <param name="exp">Exp gained</param>
        public static void SkillTrainingUp(Creature creature, Skill skill, float exp, string bonus = "")
        {
            var packet = new Packet(Op.SkillTrainingUp, creature.EntityId);
            packet.PutBin(skill.Info);
            packet.PutFloat(exp);
            packet.PutByte(1);
            packet.PutString(bonus); // (Specialized Skill Bonus: x2)

            creature.Client.Send(packet);
        }
Example #14
0
        /// <summary>
        /// Sends TailoringMiniGame to creature's client to start tailoring minigame.
        /// </summary>
        /// <remarks>
        /// The offsets specify the distance of the "stitch points" from the
        /// center of the 200x200px minigame field. X is 1:1 the distance
        /// from the center for each point, while Y gets added up.
        /// The point closest to the center is Y/2 px away, the second Y/2+Y,
        /// and the third Y/2+Y*2.
        /// 
        /// Deviation is an array of 6 values, one for each point, that specify
        /// the amount of pixels your clicks can deviate from the actual
        /// position you clicked. For example, if you click on 60x180 for the
        /// first point, and the first byte in deviation is 3, the actual
        /// position sent to the server is between 57x177 and 63x183,
        /// randomized by the client.
        /// If the deviation values are too big, the minigame glitches and is
        /// likely to fail, the biggest value seen in logs was 4.
        /// </remarks>
        /// <param name="creature"></param>
        /// <param name="item">Item that is to be finished.</param>
        /// <param name="xOffset">Offset of stitch points on the x-axis.</param>
        /// <param name="yOffset">Offset of stitch points on the y-axis.</param>
        /// <param name="deviation">Randomization for the 6 stitch points.</param>
        public static void TailoringMiniGame(Creature creature, Item item, int xOffset, int yOffset, byte[] deviation, byte deviation2)
        {
            if (deviation == null || deviation.Length != 6)
                throw new ArgumentException("rng needs exactly 6 values.");

            var packet = new Packet(Op.TailoringMiniGame, creature.EntityId);

            packet.PutShort((short)xOffset);
            packet.PutShort((short)yOffset);
            packet.PutBin(deviation);

            // Modifies cursor size, glitches the minigame if smaller than
            // deviation? Seems to be a general deviation that applies to
            // all points? Setting all deviations, incl this, to 0 gives
            // the most spot-on results.
            packet.PutByte(deviation2);

            packet.PutLong(0);
            packet.PutInt(0);
            packet.PutLong(item.EntityId);
            packet.PutInt(0);

            creature.Client.Send(packet);
        }