Aura.Channel.Skills.Life.Gathering.Complete C# (CSharp) Метод

Complete() публичный Метод

Completes skill, handling the whole item gathering process.
public Complete ( Creature creature, Skill skill, Aura.Shared.Network.Packet packet ) : void
creature Aura.Channel.World.Entities.Creature
skill Skill
packet Aura.Shared.Network.Packet
Результат void
		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;
			}

			// Update tool if it's a breakable item (i.e. it had a durability once)
			if (creature.RightHand != null && creature.RightHand.IsBreakable)
			{
				var tool = creature.RightHand;

				// No gathering with a broken tool.
				if (tool.Durability == 0)
				{
					this.DoComplete(creature, entityId, collectId, false, 4);
					return;
				}

				// Durability
				if (collectData.DurabilityLoss > 0)
				{
					var reduce = collectData.DurabilityLoss;
					creature.Inventory.ReduceDurability(tool, reduce);
				}

				// Prof
				if (tool.Durability != 0)
				{
					var amount = Item.GetProficiencyGain(creature.Age, ProficiencyGainType.Gathering);
					creature.Inventory.AddProficiency(tool, amount);
				}
			}

			// 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)
			{
				// Get collection bonuses
				var collectionBonus = 0;
				var collectionBonusProduct = 0;

				if (creature.RightHand != null)
				{
					collectionBonus = creature.RightHand.MetaData1.GetShort("CTBONUS");
					collectionBonusProduct = creature.RightHand.MetaData1.GetInt("CTBONUSPT");
				}

				// Product
				var itemId = receiveItemId = collectData.GetRndProduct(rnd, new ProductBonus(collectionBonusProduct, collectionBonus));
				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);

						// Collection Bonus Upgrade
						// CTBONUS is only used for the double drop upgrade if
						// CTBONUSPT is not set, which makes use of CTBONUS
						// for the increased chance of getting a certain
						// product.
						if (collectionBonusProduct == 0 && collectionBonus != 0)
						{
							if (rnd.Next(100) < collectionBonus)
								new Item(item).Drop(creature.Region, creaturePosition, DropRange, creature, false);
						}
					}
					else
					{
						creature.Inventory.Remove(creature.RightHand);
						creature.Inventory.Add(item, creature.Inventory.RightHandPocket);
					}
				}

				// Product2
				itemId = collectData.GetRndProduct2(rnd, null);
				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);
		}