Example #1
0
		/// <summary>
		/// Reduces weapon's durability and increases its proficiency.
		/// Only updates weapon type items that are not null.
		/// </summary>
		/// <param name="creature"></param>
		/// <param name="weapon"></param>
		public static void UpdateWeapon(Creature attacker, Creature target, params Item[] weapons)
		{
			if (attacker == null)
				return;

			var rnd = RandomProvider.Get();

			foreach (var weapon in weapons.Where(a => a != null && a.IsTrainableWeapon))
			{
				// Durability
				if (!ChannelServer.Instance.Conf.World.NoDurabilityLoss)
				{
					var reduce = rnd.Next(1, 30);

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

					attacker.UpdateTool(weapon, reduce);
					weapon.Durability -= reduce;
					Send.ItemDurabilityUpdate(attacker, weapon);
				}

				// Proficiency
				// Only if the weapon isn't broken and the target is not "Weakest".
				if (weapon.Durability != 0 && attacker != null && attacker.GetPowerRating(target) >= PowerRating.Weak)
				{
					short prof = 0;

					if (attacker.Age >= 10 && attacker.Age <= 12)
						prof = 48;
					else if (attacker.Age >= 13 && attacker.Age <= 19)
						prof = 60;
					else
						prof = 72;

					weapon.Proficiency += prof;

					Send.ItemExpUpdate(attacker, weapon);
				}
			}
		}
Example #2
0
		/// <summary>
		/// Called once ready to pull the fish out.
		/// </summary>
		/// <remarks>
		/// When you catch something just before running out of bait,
		/// and you send MotionCancel2 from Cancel, there's a
		/// visual bug on Aura, where the item keeps flying to you until
		/// you move. This does not happen on NA for unknown reason.
		/// The workaround: Check for cancellation in advance and only
		/// send the real in effect if the skill wasn't canceled.
		/// </remarks>
		/// <param name="creature"></param>
		/// <param name="method">Method used on this try</param>
		/// <param name="success">Success of manual try</param>
		public void OnResponse(Creature creature, FishingMethod method, bool success)
		{
			// Get skill
			var skill = creature.Skills.Get(SkillId.Fishing);
			if (skill == null)
			{
				Log.Error("Fishing.OnResponse: Missing skill.");
				return;
			}

			var rnd = RandomProvider.Get();

			// Update prop state
			// TODO: update prop state method
			creature.Temp.FishingProp.SetState("empty");

			// Get auto success
			if (method == FishingMethod.Auto)
				success = rnd.NextDouble() < skill.RankData.Var3 / 100f;

			// Perfect fishing
			if (ChannelServer.Instance.Conf.World.PerfectFishing)
				success = true;

			// Check fishing ground
			if (creature.Temp.FishingDrop == null)
			{
				Send.ServerMessage(creature, "Error: No items found.");
				Log.Error("Fishing.OnResponse: Failing, no drop found.");
				success = false;
			}

			// Check equipment
			if (!this.CheckEquipment(creature))
			{
				Send.ServerMessage(creature, "Error: Missing equipment.");
				Log.Error("Fishing.OnResponse: Failing, Missing equipment.");
				// TODO: Security violation once we're sure this can't happen
				//   without modding.
				success = false;
			}

			var cancel = false;

			// Reduce durability
			if (creature.RightHand != null && !ChannelServer.Instance.Conf.World.NoDurabilityLoss)
			{
				var reduce = 15;

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

				creature.UpdateTool(creature.RightHand, reduce);

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

				// Check rod durability
				if (creature.RightHand.Durability == 0)
				{
					cancel = true;
				}
			}

			// Remove bait
			if (creature.Magazine != null && !ChannelServer.Instance.Conf.World.InfiniteBait)
			{
				creature.Inventory.Decrement(creature.Magazine);

				// Check if bait was removed because it was empty
				if (creature.Magazine == null)
					cancel = true;
			}

			// Fail
			Item item = null;
			if (!success)
			{
				Send.Notice(creature, Localization.Get("I was hesistating for a bit, and it got away...")); // More responses?
				Send.Effect(creature, Effect.Fishing, (byte)FishingEffectType.Fall, true);
			}
			// Success
			else
			{
				var propName = "prop_caught_objbox_01";
				var propSize = 0;
				var size = 0;

				// Create item
				item = new Item(creature.Temp.FishingDrop);

				// Check fish
				var fish = AuraData.FishDb.Find(creature.Temp.FishingDrop.ItemId);
				if (fish != null)
				{
					propName = fish.PropName;
					propSize = fish.PropSize;

					// Random fish size, unofficial
					if (fish.SizeMin + fish.SizeMax != 0)
					{
						var min = fish.SizeMin + (int)Math.Max(0, (item.Data.BaseSize - fish.SizeMin) / 100f * skill.RankData.Var4);
						var max = fish.SizeMax;

						size = Math2.Clamp(fish.SizeMin, fish.SizeMax, rnd.Next(min, max + 1) + (int)skill.RankData.Var1);
						var scale = (1f / item.Data.BaseSize * size);

						item.MetaData1.SetFloat("SCALE", scale);
					}
				}

				// Set equipment durability
				if (item.HasTag("/equip/") && item.OptionInfo.DurabilityMax >= 1)
					item.Durability = 0;

				// Drop if inv add failed
				List<Item> changed;
				if (!creature.Inventory.Insert(item, false, out changed))
					item.Drop(creature.Region, creature.GetPosition().GetRandomInRange(100, rnd));

				var itemEntityId = (changed == null || changed.Count == 0 ? item.EntityId : changed.First().EntityId);

				// Show acquire using the item's entity id if it wasn't added
				// to a stack, or using the stack's id if it was.
				Send.AcquireInfo2(creature, "fishing", itemEntityId);

				// Holding up fish effect
				if (!cancel)
					Send.Effect(creature, Effect.Fishing, (byte)FishingEffectType.ReelIn, true, creature.Temp.FishingProp.EntityId, item.Info.Id, size, propName, propSize);
			}

			creature.Temp.FishingDrop = null;

			// Handle training
			this.Training(creature, skill, success, item);

			// Cancel
			if (cancel)
			{
				creature.Skills.CancelActiveSkill();
				return;
			}

			// Next round
			this.StartFishing(creature, 6000);
		}
Example #3
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.UpdateTool(creature.RightHand, reduce);

				creature.RightHand.Durability -= reduce;

				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 < collectData.ResourceReduction)
				{
					this.DoComplete(creature, entityId, collectId, false, 2);
					return;
				}

				// Reduce resources on success
				if (collectSuccess)
				{
					if (!ChannelServer.Instance.Conf.World.InfiniteResources)
						targetProp.Resource -= collectData.ResourceReduction;
					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 < collectData.ResourceReduction)
					targetProp.SetState("empty");
			}
			else
			{
				var targetCreature = (Creature)targetEntity;

				if (targetCreature.Mana < collectData.ResourceReduction)
				{
					this.DoComplete(creature, entityId, collectId, false, 2);
					return;
				}

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

			// 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)
						item.Drop(creature.Region, creaturePosition.GetRandomInRange(DropRange, rnd));
					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.GetRandomInRange(DropRange, rnd));
				}
			}
			// 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.GetRandomInRange(DropRange, rnd));
			//		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.OnCreatureCollected(new CollectEventArgs(creature, collectData, collectSuccess, receiveItemId));

			// Complete
			this.DoComplete(creature, entityId, collectId, collectSuccess, 0);
		}