Example #1
0
		public void Complete(Creature creature, Skill skill, Packet packet)
		{
			var itemEntityId = packet.GetLong();
			var hwEntityId = packet.GetLong();

			var item = creature.Inventory.GetItemSafe(itemEntityId);
			var hw = creature.Inventory.GetItemSafe(hwEntityId);

			var blessable = (item.HasTag("/equip/") && !item.HasTag("/not_bless/"));
			var isHolyWater = (hw.Info.Id == 63016); // There's only one item using this skill.

			// TODO: Check loading time

			if (blessable && isHolyWater)
			{
				creature.Inventory.Decrement(hw, 1);
				item.OptionInfo.Flags |= ItemFlags.Blessed;
			}
			else
				Log.Warning("Blessing.Complete: Invalid item or Holy Water.");

			Send.ItemBlessed(creature, item);
			Send.UseMotion(creature, 14, 0);
			Send.SkillComplete(creature, skill.Info.Id, itemEntityId, hwEntityId);
		}
Example #2
0
		public bool Prepare(Creature creature, Skill skill, Packet packet)
		{
			var itemEntityId = packet.GetLong();
			var hwEntityId = packet.GetLong();

			// Beware, the client uses the entity ids you send back for the
			// Complete packet. If you switch them around the handler would
			// bless the HW and delete the item without security checks.
			Send.SkillUse(creature, skill.Info.Id, itemEntityId, hwEntityId);

			return true;
		}
Example #3
0
		/// <summary>
		/// Prepares skill, skips right to used.
		/// </summary>
		/// <remarks>
		/// Doesn't check anything, like what you can gather with what,
		/// because at this point there's no chance for abuse.
		/// </remarks>
		/// <param name="creature"></param>
		/// <param name="skill"></param>
		/// <param name="packet"></param>
		/// <returns></returns>
		public bool Prepare(Creature creature, Skill skill, Packet packet)
		{
			var entityId = packet.GetLong();
			var collectId = packet.GetInt();

			// You shall stop
			creature.StopMove();
			var creaturePosition = creature.GetPosition();

			// Get target (either prop or creature)
			var targetEntity = this.GetTargetEntity(creature.Region, entityId);
			if (targetEntity != null)
				creature.Temp.GatheringTargetPosition = targetEntity.GetPosition();

			// Check distance
			if (!creaturePosition.InRange(creature.Temp.GatheringTargetPosition, MaxDistance))
			{
				Send.Notice(creature, Localization.Get("Your arms are too short to reach that from here."));
				return false;
			}

			// ? (sets creatures position on the client side)
			Send.CollectAnimation(creature, entityId, collectId, creaturePosition);

			// Use
			Send.SkillUse(creature, skill.Info.Id, entityId, collectId);
			skill.State = SkillState.Used;

			return true;
		}
Example #4
0
        public void Prepare(Creature creature, Skill skill, Packet packet)
        {
            var itemEntityId = packet.GetLong();
            var dyeEntityId = packet.GetLong();

            var item = creature.Inventory.GetItem(itemEntityId);
            var dye = creature.Inventory.GetItem(dyeEntityId);
            if (item == null || dye == null) return;

            if (!dye.Data.HasTag("/*dye_ampul/")) return;

            creature.Temp.SkillItem1 = item;
            creature.Temp.SkillItem2 = dye;

            creature.Skills.ActiveSkill = skill;

            Send.SkillReadyDye(creature, skill.Info.Id, itemEntityId, dyeEntityId);
        }
Example #5
0
File: Dye.cs Project: tkiapril/aura
		/// <summary>
		/// Prepares skill, goes straight to being ready.
		/// </summary>
		/// <param name="creature"></param>
		/// <param name="skill"></param>
		/// <param name="packet"></param>
		public bool Prepare(Creature creature, Skill skill, Packet packet)
		{
			var itemEntityId = packet.GetLong();
			var dyeEntityId = packet.GetLong();

			var item = creature.Inventory.GetItem(itemEntityId);
			var dye = creature.Inventory.GetItem(dyeEntityId);
			if (item == null || dye == null) return false;

			if (!dye.Data.HasTag("/*dye_ampul/")) return false;

			creature.Temp.SkillItem1 = item;
			creature.Temp.SkillItem2 = dye;

			Send.SkillReadyDye(creature, skill.Info.Id, itemEntityId, dyeEntityId);
			skill.State = SkillState.Ready;

			return true;
		}
Example #6
0
		/// <summary>
		/// Prepares the skill, called after entering the MML,
		/// goes straight to Use.
		/// </summary>
		/// <param name="creature"></param>
		/// <param name="skill"></param>
		/// <param name="packet"></param>
		public bool Prepare(Creature creature, Skill skill, Packet packet)
		{
			var scrollId = packet.GetLong();
			var title = packet.GetString();
			var author = packet.GetString();
			var mml = packet.GetString();
			var song = packet.GetString(); // [180300, NA166 (18.09.2013)] Singing
			var hidden = packet.GetByte(); // bool, but the meta data is a byte

			// Get item
			var item = creature.Inventory.GetItem(scrollId);
			if (item == null) goto L_Fail;

			// Get all parts of the MML (Melody, Haromony 1+2)
			var mmlParts = mml.Split(',');

			// Check lengths
			if (mml.Length > MmlMaxLength || song.Length > MmlMaxLength) goto L_Fail; // Total
			if (mmlParts.Length > 0 && mmlParts[0].Length > skill.RankData.Var1) goto L_Fail; // Melody
			if (mmlParts.Length > 1 && mmlParts[1].Length > skill.RankData.Var2) goto L_Fail; // Harmony 1
			if (mmlParts.Length > 2 && mmlParts[2].Length > skill.RankData.Var3) goto L_Fail; // Harmony 2

			// Score level = Musical Knowledge rank
			var level = SkillRank.Novice;
			var knowledge = creature.Skills.Get(SkillId.MusicalKnowledge);
			if (knowledge != null) level = knowledge.Info.Rank;

			// Update item and send skill complete from Complete
			creature.Skills.Callback(SkillId.Composing, () =>
			{
				// Skill training
				if (skill.Info.Rank == SkillRank.Novice)
					skill.Train(1); // Try the skill.

				// Scroll information
				item.MetaData1.SetString("TITLE", title);
				item.MetaData1.SetString("AUTHOR", author);
				item.MetaData1.SetString("SCORE", MabiZip.Compress(mml));
				item.MetaData1.SetString("SCSING", MabiZip.Compress(song)); // [180300, NA166 (18.09.2013)] Singing
				item.MetaData1.SetByte("HIDDEN", hidden);
				item.MetaData1.SetShort("LEVEL", (short)level);

				// Update
				Send.ItemUpdate(creature, item);
				Send.SkillCompleteEntity(creature, skill.Info.Id, item.EntityId);
			});

			// Finish
			Send.SkillUseEntity(creature, skill.Info.Id, scrollId);
			skill.State = SkillState.Used;
			return true;

		L_Fail:
			return false;
		}
Example #7
0
		public void Complete(Creature creature, Skill skill, Packet packet)
		{
			var itemEntityId = packet.GetLong();
			var hwEntityId = packet.GetLong();

			var item = creature.Inventory.GetItemSafe(itemEntityId);
			var hw = creature.Inventory.GetItemSafe(hwEntityId);
			var isHolyWater = (hw.Info.Id == 63016); // There's only one item using this skill.

			// TODO: Check loading time

			if (item.IsBlessable && isHolyWater)
			{
				creature.Inventory.Decrement(hw, 1);
				creature.Bless(item);
			}
			else
				Log.Warning("Blessing.Complete: Invalid item or Holy Water.");

			Send.UseMotion(creature, 14, 0);
			Send.SkillComplete(creature, skill.Info.Id, itemEntityId, hwEntityId);
		}
Example #8
0
		public void Use(Creature creature, Skill skill, Packet packet)
		{
			var targetPos = new Position(packet.GetLong());

			// Check distance to target position
			if (!creature.GetPosition().InRange(targetPos, (int)skill.RankData.Var2 + DistanceBuffer))
			{
				Send.Notice(creature, Localization.Get("Out of range."));
				Send.SkillUse(creature, skill.Info.Id, 0);
				return;
			}

			// Stop creature's movement.
			creature.StopMove();

			// Teleport effect (does not actually teleport)
			Send.Effect(creature, Effect.SilentMoveTeleport, (byte)2, targetPos.X, targetPos.Y);

			// Teleport player to target position
			creature.SetPosition(targetPos.X, targetPos.Y);
			Send.SkillTeleport(creature, targetPos.X, targetPos.Y);

			Send.SkillUse(creature, skill.Info.Id, 1);
		}
		/// <summary>
		/// Handles skill usage.
		/// </summary>
		/// <param name="attacker"></param>
		/// <param name="skill"></param>
		/// <param name="packet"></param>
		public void Use(Creature attacker, Skill skill, Packet packet)
		{
			var targetAreaEntityId = packet.GetLong();

			Send.Effect(attacker, 5, (byte)1, targetAreaEntityId);

			var cap = new CombatActionPack(attacker, skill.Info.Id);

			var aAction = new AttackerAction(CombatActionType.Attacker, attacker, skill.Info.Id, targetAreaEntityId);
			aAction.Options |= AttackerOptions.Result;
			aAction.Stun = UseStun;
			cap.Add(aAction);

			var attackerPosition = attacker.GetPosition();

			// Calculate rectangular target area
			var targetAreaPos = new Position(targetAreaEntityId);
			var poe = targetAreaPos.GetRelative(attackerPosition, -800);
			var r = (Math.PI / 2) + Math.Atan2(attackerPosition.Y - targetAreaPos.Y, attackerPosition.X - targetAreaPos.X);
			var pivot = new Point(poe.X, poe.Y);
			var p1 = new Point(pivot.X - LaserRectWidth / 2, pivot.Y - LaserRectHeight / 2);
			var p2 = new Point(pivot.X - LaserRectWidth / 2, pivot.Y + LaserRectHeight / 2);
			var p3 = new Point(pivot.X + LaserRectWidth / 2, pivot.Y + LaserRectHeight / 2);
			var p4 = new Point(pivot.X + LaserRectWidth / 2, pivot.Y - LaserRectHeight / 2);
			p1 = this.RotatePoint(p1, pivot, r);
			p2 = this.RotatePoint(p2, pivot, r);
			p3 = this.RotatePoint(p3, pivot, r);
			p4 = this.RotatePoint(p4, pivot, r);

			// Attack targets
			var targets = attacker.Region.GetCreaturesInPolygon(p1, p2, p3, p4);
			foreach (var target in targets.Where(cr => !cr.IsDead && !cr.Has(CreatureStates.NamedNpc)))
			{
				var targetPosition = target.GetPosition();

				var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Info.Id);
				tAction.Options = TargetOptions.Result | TargetOptions.KnockDown;
				tAction.Stun = TargetStun;
				tAction.Delay = 1200;
				cap.Add(tAction);

				// Var2: 300/1000, based on rank. Could be damage?
				var damage = skill.RankData.Var2;

				// Increase damage
				CriticalHit.Handle(attacker, attacker.GetTotalCritChance(target.Protection), ref damage, tAction);

				// Reduce damage
				SkillHelper.HandleDefenseProtection(target, ref damage);
				ManaShield.Handle(target, ref damage, tAction);

				// Apply damage
				target.TakeDamage(tAction.Damage = 300, attacker);
				target.Stability = Creature.MinStability;

				// Aggro
				target.Aggro(attacker);

				// Check death
				if (target.IsDead)
					tAction.Options |= TargetOptions.FinishingKnockDown;

				// Knock back
				attacker.Shove(target, KnockbackDistance);
			}

			cap.Handle();

			Send.SkillUse(attacker, skill.Info.Id, 0);
		}
Example #10
0
		/// <summary>
		/// Completes skill, handling the whole item gathering process.
		/// </summary>
		/// <param name="creature"></param>
		/// <param name="skill"></param>
		/// <param name="packet"></param>
		public void Complete(Creature creature, Skill skill, Packet packet)
		{
			var entityId = packet.GetLong();
			var collectId = packet.GetInt();

			var rnd = RandomProvider.Get();

			// Check data
			var collectData = AuraData.CollectingDb.Find(collectId);
			if (collectData == null)
			{
				Log.Warning("Gathering.Complete: Unknown collect id '{0}'", collectId);
				this.DoComplete(creature, entityId, collectId, false, 1);
				return;
			}

			// Check tools
			if (!this.CheckHand(collectData.RightHand, creature.RightHand) || !this.CheckHand(collectData.LeftHand, creature.LeftHand))
			{
				Log.Warning("Gathering.Complete: Collecting using invalid tool.", collectId);
				this.DoComplete(creature, entityId, collectId, false, 1);
				return;
			}

			// Reduce tool's durability
			if (creature.RightHand != null && collectData.DurabilityLoss > 0)
			{
				var reduce = collectData.DurabilityLoss;

				// Half dura loss if blessed
				if (creature.RightHand.IsBlessed)
					reduce = Math.Max(1, reduce / 2);

				creature.RightHand.Durability -= reduce;
				Send.ItemDurabilityUpdate(creature, creature.RightHand);
				Send.ItemExpUpdate(creature, creature.RightHand);
			}

			// Get target (either prop or creature)
			var targetEntity = this.GetTargetEntity(creature.Region, entityId);

			// Check target
			if (targetEntity == null || !targetEntity.HasTag(collectData.Target))
			{
				Log.Warning("Gathering.Complete: Collecting from invalid entity '{0:X16}'", entityId);
				this.DoComplete(creature, entityId, collectId, false, 1);
				return;
			}

			// Check position
			var creaturePosition = creature.GetPosition();
			var targetPosition = targetEntity.GetPosition();

			if (!creaturePosition.InRange(targetPosition, MaxDistance))
			{
				Send.Notice(creature, Localization.Get("Your arms are too short to reach that from here."));
				this.DoComplete(creature, entityId, collectId, false, 1);
				return;
			}

			// Check if moved
			if (creature.Temp.GatheringTargetPosition.GetDistance(targetPosition) > MaxMoveDistance)
			{
				this.DoComplete(creature, entityId, collectId, false, 3);
				return;
			}

			// Determine success
			var successChance = this.GetSuccessChance(creature, collectData);
			var collectSuccess = rnd.NextDouble() * 100 < successChance;

			// Get reduction
			var reduction = collectData.ResourceReduction;
			if (ChannelServer.Instance.Weather.GetWeatherType(creature.RegionId) == WeatherType.Rain)
				reduction += collectData.ResourceReductionRainBonus;

			// Check resource
			if (targetEntity is Prop)
			{
				var targetProp = (Prop)targetEntity;

				// Check if prop was emptied
				if (targetProp.State == "empty")
				{
					this.DoComplete(creature, entityId, collectId, false, 2);
					return;
				}

				// Regenerate resources
				targetProp.Resource += (float)((DateTime.Now - targetProp.LastCollect).TotalMinutes * collectData.ResourceRecovering);

				// Fail if currently no resources available
				if (targetProp.Resource < reduction)
				{
					this.DoComplete(creature, entityId, collectId, false, 2);
					return;
				}

				// Reduce resources on success
				if (collectSuccess)
				{
					if (!ChannelServer.Instance.Conf.World.InfiniteResources)
						targetProp.Resource -= reduction;
					targetProp.LastCollect = DateTime.Now;
				}

				// Set prop's state to "empty" if it was emptied and is not
				// regenerating resources.
				if (collectData.ResourceRecovering == 0 && targetProp.Resource < reduction)
					targetProp.SetState("empty");
			}
			else
			{
				var targetCreature = (Creature)targetEntity;

				// Fail if creature doesn't have enough mana
				if (targetCreature.Mana < reduction)
				{
					this.DoComplete(creature, entityId, collectId, false, 2);
					return;
				}

				if (collectSuccess && !ChannelServer.Instance.Conf.World.InfiniteResources)
					targetCreature.Mana -= reduction;
			}

			// Drop
			var receiveItemId = 0;
			if (collectSuccess)
			{
				// Product
				var itemId = receiveItemId = collectData.GetRndProduct(rnd);
				if (itemId != 0)
				{
					var item = new Item(itemId);
					if (collectData.Source == 0)
					{
						// Try to drop item in the middle, between creature
						// and target. If there already is an item on that
						// position, find another random one.
						var pos = targetPosition.GetRelative(creaturePosition, -FeetDropDistance);
						for (int i = 0; creature.Region.GetItem(a => a.GetPosition() == pos) != null && i < 10; ++i)
							pos = creaturePosition.GetRandomInRange(DropRange, rnd);

						item.Drop(creature.Region, pos, 0, creature, false);
					}
					else
					{
						creature.Inventory.Remove(creature.RightHand);
						creature.Inventory.Add(item, creature.Inventory.RightHandPocket);
					}
				}

				// Product2
				itemId = collectData.GetRndProduct2(rnd);
				if (itemId != 0)
				{
					var item = new Item(itemId);
					item.Drop(creature.Region, creaturePosition, DropRange, creature, false);
				}
			}
			// TODO: Figure out how fail products work.
			//else
			//{
			//	// FailProduct
			//	var itemId = receiveItemId = collectData.GetRndFailProduct(rnd);
			//	if (itemId != 0)
			//	{
			//		var item = new Item(itemId);
			//		if (collectData.Source == 0)
			//			item.Drop(creature.Region, creaturePosition, DropRange);
			//		else
			//		{
			//			creature.Inventory.Remove(creature.RightHand);
			//			creature.Inventory.Add(item, creature.Inventory.RightHandPocket);
			//		}
			//	}

			//	// FailProduct2
			//	itemId = collectData.GetRndFailProduct2(rnd);
			//	if (itemId != 0)
			//	{
			//		var item = new Item(itemId);
			//		item.Drop(creature.Region, creaturePosition.GetRandomInRange(DropRange, rnd));
			//	}
			//}

			// Events
			ChannelServer.Instance.Events.OnCreatureGathered(new CollectEventArgs(creature, collectData, collectSuccess, receiveItemId));

			// Complete
			this.DoComplete(creature, entityId, collectId, collectSuccess, 0);
		}
Example #11
0
		/// <summary>
		/// Uses WM, attacking targets.
		/// </summary>
		/// <param name="attacker"></param>
		/// <param name="skill"></param>
		/// <param name="packet"></param>
		public void Use(Creature attacker, Skill skill, Packet packet)
		{
			var targetAreaId = packet.GetLong();

			// There exists a seemingly rare case where these parameters
			// aren't sent.
			var unkInt1 = (packet.Peek() != PacketElementType.None ? packet.GetInt() : 0);
			var unkInt2 = (packet.Peek() != PacketElementType.None ? packet.GetInt() : 0);

			this.Use(attacker, skill, targetAreaId, unkInt1, unkInt2);
		}
Example #12
0
        /// <summary>
        /// Handles skill usage.
        /// </summary>
        /// <param name="creature"></param>
        /// <param name="skill"></param>
        /// <param name="packet"></param>
        public void Use(Creature creature, Skill skill, Packet packet)
        {
            var targetEntityId = packet.GetLong();

            // Similar to WM there is a case where these aren't sent.
            // Apparently this can happen if you activate the skill while
            // targetting an enemy.
            var unk1 = (packet.Peek() != PacketElementType.None ? packet.GetInt() : 0);
            var unk2 = (packet.Peek() != PacketElementType.None ? packet.GetInt() : 0);

            if (_cm == null)
                _cm = ChannelServer.Instance.SkillManager.GetHandler<CombatMastery>(SkillId.CombatMastery);

            // TODO: Check duration

            var attackResult = false;

            var target = creature.Region.GetCreature(targetEntityId);
            if (target != null && !creature.IsStunned && creature.CanTarget(target))
            {
                var pos = creature.GetPosition();
                var targetPos = target.GetPosition();
                var inRange = pos.InRange(targetPos, creature.AttackRangeFor(target));

                if (!inRange)
                {
                    var telePos = pos.GetRelative(targetPos, -creature.AttackRangeFor(target) + 100);

                    // Check teleport distance
                    if (pos.GetDistance(telePos) > skill.RankData.Var3 + 100)
                    {
                        Send.Notice(creature, "Out of range");
                    }
                    else
                    {
                        Send.Effect(creature, Effect.SilentMoveTeleport, targetEntityId, (byte)0);

                        creature.SetPosition(telePos.X, telePos.Y);
                        Send.SkillTeleport(creature, telePos.X, telePos.Y);

                        inRange = true;
                    }
                }

                if (inRange)
                    attackResult = (_cm.Use(creature, skill, targetEntityId) == CombatSkillResult.Okay);
            }

            Send.CombatAttackR(creature, attackResult);

            Send.SkillUse(creature, skill.Info.Id, targetEntityId, unk1, unk2);
        }
Example #13
0
		/// <summary>
		/// Handles skill usage.
		/// </summary>
		/// <param name="attacker"></param>
		/// <param name="skill"></param>
		/// <param name="packet"></param>
		public void Use(Creature attacker, Skill skill, Packet packet)
		{
			var targetAreaEntityId = packet.GetLong();
			this.Use(attacker, skill, targetAreaEntityId);
		}
Example #14
0
		/// <summary>
		/// Handles skill usage.
		/// </summary>
		/// <param name="creature"></param>
		/// <param name="skill"></param>
		/// <param name="packet"></param>
		public void Use(Creature creature, Skill skill, Packet packet)
		{
			var targetEntityId = packet.GetLong();
			var unk1 = packet.GetInt();
			var unk2 = packet.GetInt();
			Use(creature, skill, targetEntityId, unk1, unk2);

		}