Exemplo n.º 1
0
		/// <summary>
		/// Handles part of the skill training.
		/// </summary>
		/// <param name="creature"></param>
		/// <param name="item"></param>
		private void OnPlayerUsesItem(Creature creature, Item item)
		{
			// Get skill
			var skill = creature.Skills.Get(SkillId.Cooking);
			if (skill == null)
				return;

			// Check if item is food
			if (!item.HasTag("/food/"))
				return;

			// Get quality and method
			var method = item.MetaData1.GetString("MKACT");
			if (method == null)
				return;

			var quality = item.MetaData1.GetInt("QUAL");
			var rating = this.GetRating(quality);
			var isDelicious = (rating >= DeliciousRating);

			if (skill.Info.Rank == SkillRank.RF)
			{
				if (method == CookingMethod.Simmering)
					skill.Train(3); // Eat a simmered dish without sharing.
				else if (method == CookingMethod.Baking)
				{
					if (isDelicious)
						skill.Train(4); // Eat a deliciously baked dish.
				}

				return;
			}

			if (skill.Info.Rank == SkillRank.RE)
			{
				if (method == CookingMethod.Simmering)
				{
					if (isDelicious)
						skill.Train(3); // Eat a deliciously simmered dish.
				}

				return;
			}

			if (skill.Info.Rank == SkillRank.RD)
			{
				if (method == CookingMethod.Boiling)
					skill.Train(3); // Eat a boiled dish without sharing.
				else if (method == CookingMethod.Simmering)
				{
					if (isDelicious)
						skill.Train(4); // Eat a deliciously simmered dish.
				}

				return;
			}

			if (skill.Info.Rank == SkillRank.RC)
			{
				if (method == CookingMethod.Boiling)
				{
					if (isDelicious)
						skill.Train(3); // Eat a deliciously boiled dish.
				}

				return;
			}

			if (skill.Info.Rank == SkillRank.RB)
			{
				if (method == CookingMethod.DeepFrying)
					skill.Train(3); // Eat a deep-fried dish without sharing.
				else if (method == CookingMethod.Boiling)
				{
					if (isDelicious)
						skill.Train(4); // Eat a deliciously boiled dish.
				}

				return;
			}

			if (skill.Info.Rank == SkillRank.RA)
			{
				if (method == CookingMethod.StirFrying)
					skill.Train(3); // Eat a stir-fried dish without sharing.
				else if (method == CookingMethod.DeepFrying)
				{
					if (isDelicious)
						skill.Train(4); // Eat a deliciously deep-fried dish.
				}

				return;
			}

			if (skill.Info.Rank >= SkillRank.R9 && skill.Info.Rank <= SkillRank.R7)
			{
				if (method == CookingMethod.StirFrying)
				{
					if (isDelicious)
						skill.Train(3); // Eat a deliciously stir-fried dish.
				}

				return;
			}

			// TODO: Jam and pies don't have jam and pie tags,
			//   how to identify them for the last two ranks
			//   without hard-coded ids?

			if (skill.Info.Rank == SkillRank.R6)
			{
				//if (item.HasTag("/jam/"))
				//	skill.Train(3); // Eat Jam

				return;
			}

			if (skill.Info.Rank == SkillRank.R5)
			{
				//if (item.HasTag("/pie/"))
				//	skill.Train(3); // Eat a Pie

				return;
			}
		}
Exemplo n.º 2
0
		/// <summary>
		/// Unequips item in left hand/magazine, if item in right hand is moved.
		/// </summary>
		/// <param name="item"></param>
		/// <param name="source"></param>
		/// <param name="target"></param>
		private void CheckLeftHand(Item item, Pocket source, Pocket target)
		{
			var pocketOfInterest = Pocket.None;

			if (source == Pocket.RightHand1 || source == Pocket.RightHand2)
				pocketOfInterest = source;
			if (target == Pocket.RightHand1 || target == Pocket.RightHand2)
				pocketOfInterest = target;

			if (pocketOfInterest == Pocket.None)
				return;

			// Check LeftHand first, switch to Magazine if it's empty
			var leftPocket = pocketOfInterest + 2; // Left Hand 1/2
			var leftItem = _pockets[leftPocket].GetItemAt(0, 0);
			if (leftItem == null)
			{
				leftPocket += 2; // Magazine 1/2
				leftItem = _pockets[leftPocket].GetItemAt(0, 0);

				// Nothing to remove
				if (leftItem == null)
					return;
			}

			// Don't remove if combination is valid, this should allow weapons
			// to be switched while having a shield equipped.
			// Combinations of righthand/lefthand are (always?) valid,
			// unless it involves bows and their ammunition.
			if (item.HasTag("/righthand/") && leftItem.HasTag("/lefthand/"))
			{
				if (!item.HasTag("/bow/|/crossbow/") && !leftItem.HasTag("/arrow/|/bolt/"))
					return;
			}

			// Try inventory first.
			// TODO: List of pockets stuff can be auto-moved to.
			var success = _pockets[Pocket.Inventory].Add(leftItem);

			// Fallback, temp inv
			if (!success)
				success = _pockets[Pocket.Temporary].Add(leftItem);

			if (success)
			{
				_pockets[leftPocket].Remove(leftItem);

				Send.ItemMoveInfo(_creature, leftItem, leftPocket, null);
				Send.EquipmentMoved(_creature, leftPocket);
			}
		}
Exemplo n.º 3
0
		public override bool TryAdd(Item newItem, byte targetX, byte targetY, out Item collidingItem)
		{
			collidingItem = null;

			if (targetX + newItem.Data.Width > _width || targetY + newItem.Data.Height > _height)
				return false;

			var collidingItems = this.GetCollidingItems(targetX, targetY, newItem);
			if (collidingItems.Count > 1)
				return false;

			if (collidingItems.Count > 0)
				collidingItem = collidingItems[0];

			if (collidingItem != null && (
				// Colliding item is sac and new item can fill be put into it
				(collidingItem.Data.StackType == StackType.Sac && collidingItem.Data.StackItemId != 0 && (collidingItem.Data.StackItemId == newItem.Info.Id || collidingItem.Data.StackItemId == newItem.Data.StackItemId)) ||

				// Colliding item is a quiver (general arrow sac) that
				// a regular arrow can be put into.
				// Corner case, due to quiver being a sac without stack item id,
				// instead of a stackable for some reason. They possibly wanted
				// to be able to put different kinds of arrows into it,
				// otherwise they probably would have made it stackable or
				// specified a stack item id.
				(collidingItem.HasTag("/largearrowsac/") && newItem.HasTag("/arrow_bag_bundle/")) ||

				// Item is stackable and can be put into the colliding stack
				(newItem.Data.StackType == StackType.Stackable && newItem.Info.Id == collidingItem.Info.Id))
			)
			{
				if (collidingItem.Info.Amount < collidingItem.Data.StackMax)
				{
					var diff = (ushort)(collidingItem.Data.StackMax - collidingItem.Info.Amount);

					var amount = collidingItem.Info.Amount;
					collidingItem.Info.Amount += Math.Min(diff, newItem.Info.Amount);
					newItem.Info.Amount -= Math.Min(diff, newItem.Info.Amount);

					if (amount != collidingItem.Info.Amount)
						return true;
				}
			}

			if (collidingItem != null)
			{
				_items.Remove(collidingItem.EntityId);
				collidingItem.Move(newItem.Info.Pocket, newItem.Info.X, newItem.Info.Y);
				this.ClearFromMap(collidingItem);
			}

			_items.Add(newItem.EntityId, newItem);
			newItem.Move(this.Pocket, targetX, targetY);
			this.AddToMap(newItem);

			return true;
		}
Exemplo n.º 4
0
        /// <summary>
        /// Drops creature's drop items.
        /// </summary>
        /// <param name="killer"></param>
        /// <param name="rnd"></param>
        /// <param name="pos"></param>
        private void DropItems(Creature killer, Random rnd, Position pos)
        {
            // Normal
            var dropped = new HashSet<int>();
            foreach (var dropData in this.Drops.Drops)
            {
                if (dropData == null || !AuraData.ItemDb.Exists(dropData.ItemId))
                {
                    Log.Warning("Creature.Kill: Invalid drop '{0}' from '{1}'.", (dropData == null ? "null" : dropData.ItemId.ToString()), this.RaceId);
                    continue;
                }

                var dropRate = dropData.Chance * ChannelServer.Instance.Conf.World.DropRate;
                var dropChance = rnd.NextDouble() * 100;
                var month = ErinnTime.Now.Month;

                // Tuesday: Increase in dungeon item drop rate.
                // Wednesday: Increase in item drop rate from animals and nature.
                // +50%, bonus is unofficial.
                if ((month == ErinnMonth.Baltane && this.Region.IsDungeon) || (month == ErinnMonth.AlbanHeruin && !this.Region.IsDungeon))
                    dropRate *= 1.5f;

                if (dropChance < dropRate)
                {
                    // Only drop any item once
                    if (dropped.Contains(dropData.ItemId))
                        continue;

                    var item = new Item(dropData);

                    // Equip stat modification
                    // http://wiki.mabinogiworld.com/view/Category:Weapons
                    if (item.HasTag("/righthand/weapon/|/twohand/weapon/"))
                    {
                        var num = rnd.Next(100);

                        // Durability
                        if (num == 0)
                            item.OptionInfo.DurabilityMax += 4000;
                        else if (num <= 5)
                            item.OptionInfo.DurabilityMax += 3000;
                        else if (num <= 10)
                            item.OptionInfo.DurabilityMax += 2000;
                        else if (num <= 25)
                            item.OptionInfo.DurabilityMax += 1000;

                        // Attack
                        if (num == 0)
                        {
                            item.OptionInfo.AttackMin += 3;
                            item.OptionInfo.AttackMax += 3;
                        }
                        else if (num <= 30)
                        {
                            item.OptionInfo.AttackMin += 2;
                            item.OptionInfo.AttackMax += 2;
                        }
                        else if (num <= 60)
                        {
                            item.OptionInfo.AttackMin += 1;
                            item.OptionInfo.AttackMax += 1;
                        }

                        // Crit
                        if (num == 0)
                            item.OptionInfo.Critical += 3;
                        else if (num <= 30)
                            item.OptionInfo.Critical += 2;
                        else if (num <= 60)
                            item.OptionInfo.Critical += 1;

                        // Balance
                        if (num == 0)
                            item.OptionInfo.Balance = (byte)Math.Max(0, item.OptionInfo.Balance - 12);
                        else if (num <= 10)
                            item.OptionInfo.Balance = (byte)Math.Max(0, item.OptionInfo.Balance - 10);
                        else if (num <= 30)
                            item.OptionInfo.Balance = (byte)Math.Max(0, item.OptionInfo.Balance - 8);
                        else if (num <= 50)
                            item.OptionInfo.Balance = (byte)Math.Max(0, item.OptionInfo.Balance - 6);
                        else if (num <= 70)
                            item.OptionInfo.Balance = (byte)Math.Max(0, item.OptionInfo.Balance - 4);
                        else if (num <= 90)
                            item.OptionInfo.Balance = (byte)Math.Max(0, item.OptionInfo.Balance - 2);
                    }

                    item.Drop(this.Region, pos, Item.DropRadius, killer, false);

                    dropped.Add(dropData.ItemId);
                }
            }

            // Static
            foreach (var item in this.Drops.StaticDrops)
                item.Drop(this.Region, pos, Item.DropRadius, killer, false);

            this.Drops.ClearStaticDrops();
        }
Exemplo n.º 5
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.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);
		}
Exemplo n.º 6
0
Arquivo: Healing.cs Projeto: Rai/aura
		/// <summary>
		/// Called when player uses an item.
		/// </summary>
		/// <param name="creature"></param>
		/// <param name="item"></param>
		private void OnPlayerUsesItem(Creature creature, Item item)
		{
			var userSkill = creature.Skills.Get(SkillId.Healing);

			if (userSkill != null && userSkill.Info.Rank >= SkillRank.RF && userSkill.Info.Rank <= SkillRank.RE && item.HasTag("/potion/hp/"))
				userSkill.Train(5); // Drink a Life Potion.
		}
Exemplo n.º 7
0
		/// <summary>
		/// Handles skill training.
		/// </summary>
		/// <param name="creature"></param>
		/// <param name="skill"></param>
		/// <param name="success"></param>
		/// <param name="item"></param>
		/// <exception cref="ArgumentException"></exception>
		public void Training(Creature creature, Skill skill, bool success, Item item)
		{
			if (success && item == null)
				throw new ArgumentException("Item shouldn't be null if fishing was successful.");

			if (skill.Info.Rank == SkillRank.Novice)
			{
				skill.Train(2); // Attempt to fish.

				if (success && item.HasTag("/fish/"))
					skill.Train(1); // Catch a fish.

				if (!success)
					skill.Train(3); // Fail at fishing.

				return;
			}

			if (skill.Info.Rank >= SkillRank.RF && skill.Info.Rank <= SkillRank.R1)
			{
				if (success)
				{
					if (item.HasTag("/fish/"))
						skill.Train(1); // Catch a fish.
					else if (item.QuestId != 0)
						skill.Train(2); // Catch a quest scroll.
					else
						skill.Train(3); // Catch an item.
				}

				if (skill.Info.Rank <= SkillRank.RA)
					skill.Train(4); // Attempt to fish.

				return;
			}
		}
Exemplo n.º 8
0
		private void OnPlayerUsesItem(Creature creature, Item item)
		{
			var skill = creature.Skills.Get(SkillId.PotionMaking);
			if (skill == null)
				return;

			if (skill.Info.Rank >= SkillRank.RF && skill.Info.Rank <= SkillRank.RE)
			{
				if (item.HasTag("/potion/hp/"))
					skill.Train(1); // Drink an HP Potion.
				else if (item.HasTag("/potion/mana/"))
					skill.Train(2); // Drink an MP Potion.
				else if (item.HasTag("/potion/stamina/"))
					skill.Train(3); // Drink a Stamina Potion.

				return;
			}

			if (skill.Info.Rank == SkillRank.RB)
			{
				if (item.HasTag("/potion/wound/"))
					skill.Train(6); // Try drinking a Wound Remedy Potion.

				return;
			}
		}
Exemplo n.º 9
0
        /// <summary>
        /// Returns success chance, based on skill, option set, and powder
        /// used.
        /// <remarks>
        /// Unofficial. It kinda matches the debug output of the client,
        /// but it is a little off.
        /// </remarks>
        /// </summary>
        /// <param name="creature"></param>
        /// <param name="rightHand"></param>
        /// <param name="skill"></param>
        /// <param name="optionSetData"></param>
        /// <returns></returns>
        private float GetChance(Creature creature, Item rightHand, Skill skill, OptionSetData optionSetData)
        {
            // Check right hand, only use it if it's powder
            if (rightHand != null && !rightHand.HasTag("/enchant/powder/"))
                rightHand = null;

            // Get base chance, based on skill and powder
            var baseChance = _baseChanceB00; // (Blessed) Magic Powder/None
            if (skill.Info.Id == SkillId.Enchant && rightHand != null)
            {
                if (rightHand.HasTag("/powder02/")) // Elite Magic Powder
                    baseChance = _baseChanceB05;
                else if (rightHand.HasTag("/powder03/")) // Elven Magic Powder
                    baseChance = _baseChanceB10;
                else if (rightHand.HasTag("/powder01/")) // Ancient Magic Powder
                    baseChance = _baseChanceB50;
                else if (rightHand.HasTag("/powder04/") && rightHand.Info.Id == 85865) // Notorious Magic Powder
                    baseChance = _baseChanceB60;
            }

            // Get chance
            var rank = Math2.Clamp(0, _baseChanceB00.Length - 1, (int)optionSetData.Rank - 1);
            var chance = baseChance[rank];
            var intBonus = 1f;
            var thursdayBonus = 0f;

            // Int bonus if using powder
            if (skill.Info.Id == SkillId.Enchant && rightHand != null)
                intBonus = 1f + ((creature.Int - 35f) / 350f);

            // Thursday bonus
            if (ErinnTime.Now.Month == 4)
                thursdayBonus = Math.Max(0, (15 - rank) / 2f);

            // Result
            var result = Math2.Clamp(0, 90, chance * intBonus + thursdayBonus);

            // Debug
            if (creature.Titles.SelectedTitle == TitleId.devCAT)
            {
                Send.ServerMessage(creature,
                    "Debug: Enchant success chance: {0:0} (base: {1:0}, int: {2:0}, thu: {3:0})",
                    result, chance, (chance / 1f * (intBonus - 1f)), thursdayBonus);
            }

            return result;
        }
Exemplo n.º 10
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="creature"></param>
		/// <param name="itemEntityId"></param>
		/// <param name="moveToInventory"></param>
		/// <param name="directBankTransaction"></param>
		/// <returns></returns>
		public bool Buy(Creature creature, long itemEntityId, bool moveToInventory, bool directBankTransaction)
		{
			var shop = this;
			var owner = creature.Temp.CurrentShopOwner;

			// Get item
			// In theory someone could buy an item without it being visible
			// to him, but he would need the current entity id that
			// changes on each restart. It's unlikely to ever be a problem.
			var item = shop.GetItem(itemEntityId);
			if (item == null)
			{
				// Don't warn, this might happen when items are moved while
				// a player has the shop open.
				Send.MsgBox(creature, Localization.Get("The item is not available."));
				return false;
			}

			// Check stock
			if (item.Stock == 0)
			{
				Send.MsgBox(creature, Localization.Get("This item is not in stock anymore."));
				return false;
			}

			// Determine which payment method to use, the same way the client
			// does to display them. Points > Stars > Ducats > Gold.
			var paymentMethod = PaymentMethod.Gold;
			if (item.OptionInfo.StarPrice > 0)
				paymentMethod = PaymentMethod.Stars;
			if (item.OptionInfo.DucatPrice > 0)
				paymentMethod = PaymentMethod.Ducats;
			if (item.OptionInfo.PointPrice > 0)
				paymentMethod = PaymentMethod.Points;

			// Allow direct transaction only for buying with gold
			if (directBankTransaction && paymentMethod != PaymentMethod.Gold)
			{
				Send.MsgBox(creature, Localization.Get("You can't by this item via direct bank transaction."));
				return false;
			}

			// Get buying price
			var price = int.MaxValue;
			switch (paymentMethod)
			{
				case PaymentMethod.Gold: price = item.OptionInfo.Price; break;
				case PaymentMethod.Stars: price = item.OptionInfo.StarPrice; break;
				case PaymentMethod.Ducats: price = item.OptionInfo.DucatPrice; break;
				case PaymentMethod.Points: price = item.OptionInfo.PointPrice; break;
			}

			// The client expects the price for a full stack to be sent in the
			// ItemOptionInfo, so we have to calculate the actual price here.
			// However, the points payment method prices are absolute, the
			// client displays them as is.
			if (item.Data.StackType == StackType.Stackable && paymentMethod != PaymentMethod.Points)
				price = (int)(price / (float)item.Data.StackMax * item.Amount);

			// Wednesday: Decrease in prices (5%) for items in NPC shops,
			// including Remote Shop Coupons and money deposit for Exploration Quests.
			if (ErinnTime.Now.Month == ErinnMonth.AlbanHeruin)
				price = (int)(price * 0.95f);

			// Check currency
			var canPay = false;
			switch (paymentMethod)
			{
				case PaymentMethod.Gold:
					// Disable direct bank transaction if price is less than 50k
					if (directBankTransaction && price < 50000)
						directBankTransaction = false;

					// Check gold
					var gold = 0;
					if (directBankTransaction)
					{
						gold = creature.Client.Account.Bank.Gold;
						price = price + (int)(price * 0.05f); // Fee
					}
					else
						gold = creature.Inventory.Gold;

					canPay = (gold >= price);
					break;

				case PaymentMethod.Stars: canPay = (creature.Inventory.Stars >= price); break;
				case PaymentMethod.Ducats: canPay = false; break; // TODO: Implement ducats.
				case PaymentMethod.Points: canPay = (creature.Points >= price); break;
			}

			if (!canPay)
			{
				switch (paymentMethod)
				{
					case PaymentMethod.Gold: Send.MsgBox(creature, Localization.Get("Insufficient amount of gold.")); break;
					case PaymentMethod.Stars: Send.MsgBox(creature, Localization.Get("Insufficient amount of stars.")); break;
					case PaymentMethod.Ducats: Send.MsgBox(creature, Localization.Get("Insufficient amount of ducats.")); break;
					case PaymentMethod.Points: Send.MsgBox(creature, Localization.Get("You don't have enough Pon.\nYou will need to buy more.")); break;
				}

				return false;
			}

			// Buy, adding item, and removing currency
			var success = false;

			var newItem = new Item(item);

			// Set guild data
			if (newItem.HasTag("/guild_robe/") && creature.Guild != null && creature.Guild.HasRobe)
			{
				// EBCL1:4:-11042446;EBCL2:4:-7965756;EBLM1:1:45;EBLM2:1:24;EBLM3:1:6;GLDNAM:s:Name;
				newItem.Info.Color1 = creature.Guild.Robe.RobeColor;
				newItem.Info.Color2 = GuildRobe.GetColor(creature.Guild.Robe.BadgeColor);
				newItem.Info.Color3 = GuildRobe.GetColor(creature.Guild.Robe.EmblemMarkColor);
				newItem.MetaData1.SetInt("EBCL1", (int)GuildRobe.GetColor(creature.Guild.Robe.EmblemOutlineColor));
				newItem.MetaData1.SetInt("EBCL2", (int)GuildRobe.GetColor(creature.Guild.Robe.StripesColor));
				newItem.MetaData1.SetByte("EBLM1", creature.Guild.Robe.EmblemMark);
				newItem.MetaData1.SetByte("EBLM2", creature.Guild.Robe.EmblemOutline);
				newItem.MetaData1.SetByte("EBLM3", creature.Guild.Robe.Stripes);
				newItem.MetaData1.SetString("GLDNAM", creature.Guild.Name);
			}

			// Cursor
			if (!moveToInventory)
				success = creature.Inventory.Add(newItem, Pocket.Cursor);
			// Inventory
			else
				success = creature.Inventory.Add(newItem, false);

			if (success)
			{
				// Reset gold price if payment method wasn't gold, as various
				// things depend on the gold price, like repair prices.
				// If any payment method but gold was used, the gold price
				// would be 0.
				if (paymentMethod != PaymentMethod.Gold)
					newItem.ResetGoldPrice();

				// Reduce gold/points
				switch (paymentMethod)
				{
					case PaymentMethod.Gold:
						if (directBankTransaction)
							creature.Client.Account.Bank.RemoveGold(creature, price);
						else
							creature.Inventory.Gold -= price;
						break;

					case PaymentMethod.Stars: creature.Inventory.Stars -= price; break;
					case PaymentMethod.Ducats: break; // TODO: Implement ducats.
					case PaymentMethod.Points: creature.Points -= price; break;
				}

				// Reduce stock
				if (item.Stock > 0)
				{
					// Don't let it go below 0, that would mean unlimited.
					item.Stock = Math.Max(0, item.Stock - 1);
					if (item.Stock == 0)
					{
						// Refresh shop, so the item disappears.
						Send.ClearNpcShop(creature);
						Send.AddToNpcShop(creature, this.GetTabs(creature, owner));
					}

					Send.ServerMessage(creature, "Debug: Stock remaining: {0}", item.Stock);
				}
			}

			return success;
		}
Exemplo n.º 11
0
		/// <summary>
		/// Checks if creature is able to enter a dungeon with the given item,
		/// at his current position, if so, a dungeon is created and the
		/// party is moved inside.
		/// </summary>
		/// <param name="creature"></param>
		/// <param name="item"></param>
		/// <returns></returns>
		public bool CheckDrop(Creature creature, Item item)
		{
			var currentRegionId = creature.RegionId;
			if (!_entryRegionIds.Contains(currentRegionId))
				return false;

			var pos = creature.GetPosition();

			var clientEvent = creature.Region.GetClientEvent(a => a.Data.IsAltar);
			if (clientEvent == null)
			{
				Log.Warning("DungeonManager.CheckDrop: No altar found.");
				return false;
			}

			if (!clientEvent.IsInside(pos.X, pos.Y))
			{
				// Tell player to step on altar?
				return false;
			}

			var parameter = clientEvent.Data.Parameters.FirstOrDefault(a => a.EventType == EventType.Altar);
			if (parameter == null || parameter.XML == null || parameter.XML.Attribute("dungeonname") == null)
			{
				Log.Warning("DungeonManager.CheckDrop: No dungeon name found in altar event '{0:X16}'.", clientEvent.EntityId);
				return false;
			}

			var dungeonName = parameter.XML.Attribute("dungeonname").Value.ToLower();

			// Check script
			var dungeonScript = ChannelServer.Instance.ScriptManager.DungeonScripts.Get(dungeonName);
			if (dungeonScript == null)
			{
				Send.ServerMessage(creature, "This dungeon hasn't been added yet.");
				Log.Warning("DungeonManager.CheckDrop: No routing dungeon script found for '{0}'.", dungeonName);
				return false;
			}

			// Check arenas
			if (dungeonScript.Name == "tircho_alby_dungeon" && item.HasTag("/alby_battle_arena/"))
			{
				creature.Warp(28, 1174, 795);
				return true;
			}

			// Check route
			if (!dungeonScript.Route(creature, item, ref dungeonName))
			{
				// The response in case of a fail is handled by the router.
				return false;
			}

			// Check party
			if (creature.IsInParty && creature.Party.Leader != creature)
			{
				// Unofficial
				Send.Notice(creature, Localization.Get("Only the leader may create the dungeon."));
				return false;
			}

			return this.CreateDungeonAndWarp(dungeonName, item.Info.Id, creature);
		}
Exemplo n.º 12
0
		/// <summary>
		/// Warps creature, based on the item's properties.
		/// </summary>
		/// <param name="creature"></param>
		/// <param name="item"></param>
		/// <param name="warpPartyMembers"></param>
		/// <returns>Whether a warp happened or not.</returns>
		public static bool Warp(Creature creature, Item item, bool warpPartyMembers)
		{
			if (creature == null)
				throw new ArgumentNullException("creature");

			if (item == null)
				throw new ArgumentNullException("item");

			// Check meta data
			if (!item.MetaData1.Has("TARGET"))
			{
				Send.ServerMessage(creature, Localization.Get("No target found."));
				return false;
			}

			// Get target
			var target = item.MetaData1.GetString("TARGET");

			// Get location based on target
			Location loc;
			if (target.StartsWith("pos")) // pos@regionId,x,y
			{
				var match = Regex.Match(target, @"pos@(?<regionId>[0-9]+),(?<x>[0-9]+),(?<y>[0-9]+)");
				if (!match.Success)
				{
					Log.Warning("HiddenTownBack: Invalid position target: {0}", target);
					Send.ServerMessage(creature, Localization.Get("Invalid target."));
					return false;
				}

				loc.RegionId = Convert.ToInt32(match.Groups["regionId"].Value);
				loc.X = Convert.ToInt32(match.Groups["x"].Value);
				loc.Y = Convert.ToInt32(match.Groups["y"].Value);
			}
			else if (target.StartsWith("portal")) // portal@name
			{
				// Remove "portal@" prefix
				target = target.Substring(7).Trim();

				// Get portal data
				var portalData = AuraData.PortalDb.Find(target);
				if (portalData == null)
				{
					Log.Warning("HiddenTownBack: Unknown target: {0}", target);
					Send.ServerMessage(creature, Localization.Get("Unknown target."));
					return false;
				}

				// Get location
				try
				{
					loc = new Location(portalData.Location);
				}
				catch
				{
					Log.Warning("HiddenTownBack: Invalid portal location: {0}", target);
					Send.ServerMessage(creature, Localization.Get("Invalid portal location."));
					return false;
				}
			}
			else if (target == "last_town")
			{
				loc = new Location(creature.LastTown);
			}
			else
			{
				Log.Warning("HiddenTownBack: Unknown target type: {0}", target);
				Send.ServerMessage(creature, Localization.Get("Unknown target type."));
				return false;
			}

			// Warp party
			if (warpPartyMembers && item.HasTag("/party_enable/") && creature.Party.Leader == creature)
			{
				var partyMembers = creature.Party.GetMembersInRange(creature);
				foreach (var member in partyMembers)
					member.Warp(loc);
			}

			// Warp user after we got the party members
			creature.Warp(loc);

			return true;
		}
Exemplo n.º 13
0
		/// <summary>
		/// Returns stability reduction for creature and weapon.
		/// </summary>
		/// <remarks>
		/// http://wiki.mabinogiworld.com/view/Knock_down_gauge#Knockdown_Timer_Rates
		/// </remarks>
		/// <param name="weapon"></param>
		/// <returns></returns>
		public float GetStabilityReduction(Creature creature, Item weapon)
		{
			var count = weapon != null && (weapon.HasTag("/weapon/") || weapon.HasTag("/ego_weapon/") || weapon.HasTag("/instrument/")) ? weapon.Info.KnockCount + 1 : creature.RaceData.KnockCount + 1;
			var speed = weapon != null && (weapon.HasTag("/weapon/") || weapon.HasTag("/ego_weapon/") || weapon.HasTag("/instrument/")) ? (AttackSpeed)weapon.Data.AttackSpeed : (AttackSpeed)creature.RaceData.AttackSpeed;

			// All values have been taken from the weapons data, the values in
			// comments were estimates, mainly based on logs.

			switch (count)
			{
				default:
				case 1:
					return 105;

				case 2:
					switch (speed)
					{
						default:
						case AttackSpeed.VerySlow: return 67; // 70
						case AttackSpeed.Slow: return 65; // 68
						case AttackSpeed.Normal: return 65; // 68
						case AttackSpeed.Fast: return 65; // 68
						case AttackSpeed.VeryFast: return 65;
					}

				case 3:
					switch (speed)
					{
						default:
						case AttackSpeed.VerySlow: return 55; // 60
						case AttackSpeed.Slow: return 52; // 56
						case AttackSpeed.Normal: return 50; // 53
						case AttackSpeed.Fast: return 49; // 50
						case AttackSpeed.VeryFast: return 48;
					}

				case 4:
					switch (speed)
					{
						default:
						case AttackSpeed.VerySlow: return 42;
						case AttackSpeed.Slow: return 40;
						case AttackSpeed.Normal: return 39;
						case AttackSpeed.Fast: return 36;
						case AttackSpeed.VeryFast: return 37;
					}

				case 5:
					switch (speed)
					{
						default:
						case AttackSpeed.VerySlow: return 36;
						case AttackSpeed.Slow: return 33;
						case AttackSpeed.Normal: return 31.5f;
						case AttackSpeed.Fast: return 30; // 40
						case AttackSpeed.VeryFast: return 29.5f; // 35
					}
			}
		}
Exemplo n.º 14
0
		/// <summary>
		/// Returns stun time for the target.
		/// </summary>
		/// <param name="weapon"></param>
		/// <param name="knockback"></param>
		/// <returns></returns>
		public static short GetTargetStun(Creature creature, Item weapon, bool knockback)
		{
			var count = weapon != null && (weapon.HasTag("/weapon/") || weapon.HasTag("/ego_weapon/") || weapon.HasTag("/instrument/")) ? weapon.Info.KnockCount + 1 : creature.RaceData.KnockCount + 1;
			var speed = weapon != null && (weapon.HasTag("/weapon/") || weapon.HasTag("/ego_weapon/") || weapon.HasTag("/instrument/")) ? (AttackSpeed)weapon.Data.AttackSpeed : (AttackSpeed)creature.RaceData.AttackSpeed;

			return GetTargetStun(count, speed, knockback);
		}
Exemplo n.º 15
0
		/// <summary>
		/// Gets the prop ID
		/// </summary>
		/// <param name="item"></param>
		/// <returns></returns>
		private int GetPropId(Item item)
		{
			if (item != null)
			{
				if (item.HasTag("/halloween_campfire_kit/"))
				{
					return HalloweenPropId;
				}
				else if (item.HasTag("/burner/"))
				{
					return ChristmasPropId;
				}
				else if (item.Info.Id == 63291)
				{
					return SeventhAnnvPropId;
				}
				else if (item.Info.Id == 63343)
				{
					return EighthAnnvPropId;
				}
			}

			return PropId;
		}
Exemplo n.º 16
0
        /// <summary>
        /// Returns option set id from "enchant scrolls", based on their data.
        /// </summary>
        /// <param name="enchant"></param>
        /// <returns></returns>
        private int GetOptionSetid(Item enchant)
        {
            var optionSetId = 0;

            // Elementals
            if (enchant.HasTag("/elemental/"))
            {
                optionSetId = enchant.MetaData1.GetInt("ENELEM");
            }
            // Enchants
            else if (enchant.MetaData1.Has("ENPFIX") || enchant.MetaData1.Has("ENSFIX"))
            {
                var prefixId = enchant.MetaData1.GetInt("ENPFIX");
                var suffixId = enchant.MetaData1.GetInt("ENSFIX");

                if (prefixId != 0)
                    optionSetId = prefixId;
                else if (suffixId != 0)
                    optionSetId = suffixId;
            }
            // Fallback? (Pages)
            else
            {
                var prefixId = enchant.OptionInfo.Prefix;
                var suffixId = enchant.OptionInfo.Suffix;

                if (prefixId != 0)
                    optionSetId = prefixId;
                else if (suffixId != 0)
                    optionSetId = suffixId;
            }

            return optionSetId;
        }
Exemplo n.º 17
0
		/// <summary>
		/// Updates equip objectives.
		/// </summary>
		/// <param name="creature"></param>
		/// <param name="item"></param>
		private void OnPlayerEquipsItem(Creature creature, Item item)
		{
			if (creature == null || !creature.IsPlayer || item == null || !item.Info.Pocket.IsEquip())
				return;

			var quests = creature.Quests.GetAllIncomplete(this.Id);
			foreach (var quest in quests)
			{
				var progress = quest.CurrentObjectiveOrLast;
				if (progress == null) return;

				var objective = this.Objectives[progress.Ident];
				if (objective == null || objective.Type != ObjectiveType.Equip) return;

				var equipObjective = (objective as QuestObjectiveEquip);
				if (!progress.Done && item.HasTag(equipObjective.Tag))
				{
					quest.SetDone(progress.Ident);
					Send.QuestUpdate(creature, quest);
				}
			}
		}
Exemplo n.º 18
0
        /// <summary>
        /// Handles item burning, retruns whether it was successful.
        /// </summary>
        /// <param name="creature"></param>
        /// <param name="item"></param>
        /// <param name="campfire"></param>
        /// <param name="enchantersBurn"></param>
        public bool Burn(Creature creature, Item item, Prop campfire, bool enchantersBurn)
        {
            var skill = creature.Skills.Get(SkillId.Enchant);
            var enchantBurnSuccess = false;
            var powderBurnSuccess = false;
            var exp = 0;

            // Enchanter's Burn
            if (enchantersBurn)
            {
                var rnd = RandomProvider.Get();

                var isEquip = item.HasTag("/equip/");
                var hasEnchantBurnItems = (creature.Inventory.Has(51102) && creature.Inventory.Has(63016)); // Mana Herb + Holy Water

                // Enchant burning
                if (!isEquip || !hasEnchantBurnItems)
                {
                    // Unofficial
                    Send.SystemMessage(creature, Localization.Get("You don't the necessary items."));
                    return false;
                }

                // Get chances
                // All unofficial
                var rank = (skill == null ? 16 : (int)skill.Info.Rank);
                var enchantChance = (skill == null ? 0 : skill.RankData.Var3);

                // Campfire r8+ bonus
                if (enchantChance > 0 && campfire.Temp.CampfireSkillRank.Rank >= SkillRank.R8)
                    enchantChance += (16 - rank);

                // Powder = double enchant chance, based on the Wiki saying
                // r1 doesn't guarantee getting the enchants, but it does
                // guarantee getting powder.
                var powderChance = enchantChance * 2;

                // Debug
                if (creature.Titles.SelectedTitle == TitleId.devCAT)
                    Send.ServerMessage(creature, "Debug: Chance for enchant: {0:0}, chance for powder: {1:0}", enchantChance, powderChance);

                // Try prefix
                if (item.OptionInfo.Prefix != 0 && rnd.Next(100) < enchantChance)
                {
                    var enchant = Item.CreateEnchant(item.OptionInfo.Prefix);
                    creature.AcquireItem(enchant);
                    enchantBurnSuccess = true;
                }

                // Try suffix
                if (item.OptionInfo.Suffix != 0 && rnd.Next(100) < enchantChance)
                {
                    var enchant = Item.CreateEnchant(item.OptionInfo.Suffix);
                    creature.AcquireItem(enchant);
                    enchantBurnSuccess = true;
                }

                // Try suffix
                if (item.OptionInfo.Prefix + item.OptionInfo.Suffix != 0 && rnd.Next(100) < powderChance)
                {
                    var powder = new Item(62003); // Blessed Magic Powder
                    creature.AcquireItem(powder);
                    powderBurnSuccess = true;
                }

                // Reduce items
                creature.Inventory.Remove(51102, 1); // Mana Herb
                creature.Inventory.Remove(63016, 1); // Holy Water

                // Training
                this.BurnTraining(skill, enchantBurnSuccess, powderBurnSuccess);

                // Success/Fail motion
                Send.UseMotion(creature, 14, enchantBurnSuccess ? 0 : 3);
            }

            // Add exp based on item buying price (random+unofficial)
            if (item.OptionInfo.Price > 0)
            {
                exp = 40 + (int)(item.OptionInfo.Price / (float)item.Data.StackMax / 100f * item.Info.Amount);
                creature.GiveExp(exp);
            }

            // Remove item from cursor
            creature.Inventory.Remove(item);

            // Effect
            Send.Effect(MabiId.Broadcast, creature, Effect.BurnItem, campfire.EntityId, enchantBurnSuccess);
            Send.Notice(creature, NoticeType.MiddleSystem, Localization.Get("Burning EXP {0}"), exp);

            return true;
        }
Exemplo n.º 19
0
		/// <summary>
		/// Returns a list of bonuses that the given item would get with
		/// the given quality.
		/// </summary>
		/// <remarks>
		/// Reference: http://mabination.com/threads/85245-Player-made-Item-Quality
		/// </remarks>
		/// <param name="item"></param>
		/// <param name="quality"></param>
		/// <returns></returns>
		private Dictionary<Bonus, int> GetBonusesFor(Item item, int quality)
		{
			var bonuses = new Dictionary<Bonus, int>();

			// Weapons (except bows)
			if (item.HasTag("/weapon/") && !item.HasTag("/bow/|/bow01|/crossbow/"))
			{
				// Balance
				if (quality >= 98)
					bonuses[Bonus.Balance] = 10;
				else if (quality >= 95)
					bonuses[Bonus.Balance] = 9;
				else if (quality >= 92)
					bonuses[Bonus.Balance] = 8;
				else if (quality >= 90)
					bonuses[Bonus.Balance] = 7;
				else if (quality >= 85)
					bonuses[Bonus.Balance] = 6;
				else if (quality >= 80)
					bonuses[Bonus.Balance] = 5;
				else if (quality >= 70)
					bonuses[Bonus.Balance] = 4;
				else if (quality >= 60)
					bonuses[Bonus.Balance] = 3;
				else if (quality >= 50)
					bonuses[Bonus.Balance] = 2;
				else if (quality >= 30)
					bonuses[Bonus.Balance] = 1;

				// Critical
				if (quality >= 95)
					bonuses[Bonus.Critical] = 5;
				else if (quality >= 90)
					bonuses[Bonus.Critical] = 4;
				else if (quality >= 80)
					bonuses[Bonus.Critical] = 3;
				else if (quality >= 70)
					bonuses[Bonus.Critical] = 2;
				else if (quality >= 50)
					bonuses[Bonus.Critical] = 1;

				// Max Attack
				if (quality >= 75)
					bonuses[Bonus.AttackMax] = 2;
				else if (quality >= 20)
					bonuses[Bonus.AttackMax] = 1;
				else if (quality < -80)
					bonuses[Bonus.AttackMax] = -1;

				// Min Attack
				if (quality >= 75)
					bonuses[Bonus.AttackMin] = 2;
				else if (quality >= 20)
					bonuses[Bonus.AttackMin] = 1;
				else if (quality < -80)
					bonuses[Bonus.AttackMin] = -1;

				// Durability
				if (quality >= 80)
				{
					bonuses[Bonus.Durability] = 5;
					bonuses[Bonus.DurabilityMax] = 5;
				}
				else if (quality >= 60)
				{
					bonuses[Bonus.Durability] = 4;
					bonuses[Bonus.DurabilityMax] = 4;
				}
				else if (quality >= 50)
				{
					bonuses[Bonus.Durability] = 3;
					bonuses[Bonus.DurabilityMax] = 3;
				}
				else if (quality >= 45)
				{
					bonuses[Bonus.Durability] = 2;
					bonuses[Bonus.DurabilityMax] = 2;
				}
				else if (quality >= 40)
				{
					bonuses[Bonus.Durability] = 1;
					bonuses[Bonus.DurabilityMax] = 1;
				}
				else if (quality >= -20)
				{
				}
				else if (quality >= -60)
				{
					bonuses[Bonus.Durability] = -2;
					bonuses[Bonus.DurabilityMax] = 0;
				}
				else if (quality >= -80)
				{
					bonuses[Bonus.Durability] = -2;
					bonuses[Bonus.DurabilityMax] = -1;
				}
				else
				{
					bonuses[Bonus.Durability] = -3;
					bonuses[Bonus.DurabilityMax] = -2;
				}
			}

			// Bows
			else if (item.HasTag("/bow/|/bow01/|/crossbow/"))
			{
				// Balance
				if (quality >= 98)
					bonuses[Bonus.Balance] = 5;
				else if (quality >= 80)
					bonuses[Bonus.Balance] = 4;
				else if (quality >= 70)
					bonuses[Bonus.Balance] = 3;
				else if (quality >= 50)
					bonuses[Bonus.Balance] = 2;
				else if (quality >= 30)
					bonuses[Bonus.Balance] = 1;

				// Critical
				if (quality >= 98)
					bonuses[Bonus.Critical] = 5;
				else if (quality >= 95)
					bonuses[Bonus.Critical] = 4;
				else if (quality >= 80)
					bonuses[Bonus.Critical] = 3;
				else if (quality >= 70)
					bonuses[Bonus.Critical] = 2;
				else if (quality >= 10)
					bonuses[Bonus.Critical] = 1;

				// Max Attack
				if (quality >= 90)
					bonuses[Bonus.AttackMax] = 2;
				else if (quality >= 10)
					bonuses[Bonus.AttackMax] = 1;
				else
					bonuses[Bonus.AttackMax] = -1;

				// Min Attack
				if (quality >= 95)
					bonuses[Bonus.AttackMin] = 2;
				else if (quality >= 30)
					bonuses[Bonus.AttackMin] = 1;
				else if (quality < -10)
					bonuses[Bonus.AttackMin] = -1;

				// Durability
				if (quality >= 98)
				{
					bonuses[Bonus.Durability] = 3;
					bonuses[Bonus.DurabilityMax] = 3;
				}
				else if (quality >= 90)
				{
					bonuses[Bonus.Durability] = 2;
					bonuses[Bonus.DurabilityMax] = 2;
				}
				else if (quality >= 50)
				{
					bonuses[Bonus.Durability] = 1;
					bonuses[Bonus.DurabilityMax] = 1;
				}
				else if (quality >= -10)
				{
				}
				else if (quality >= -30)
				{
					bonuses[Bonus.Durability] = -1;
					bonuses[Bonus.DurabilityMax] = -1;
				}
				else
				{
					bonuses[Bonus.Durability] = -2;
					bonuses[Bonus.DurabilityMax] = -2;
				}
			}

			// Armors and clothes
			else if (item.HasTag("/armor/cloth/|/armor/lightarmor/|/armor/heavyarmor/"))
			{
				// Defense
				if (quality >= 90)
					bonuses[Bonus.Defense] = 1;

				// Protection
				if (quality >= 95)
					bonuses[Bonus.Protection] = 3;
				else if (quality >= 75)
					bonuses[Bonus.Protection] = 2;
				else if (quality >= 50)
					bonuses[Bonus.Protection] = 1;

				// Durability
				if (quality >= 80)
				{
					bonuses[Bonus.Durability] = 5;
					bonuses[Bonus.DurabilityMax] = 5;
				}
				else if (quality >= 70)
				{
					bonuses[Bonus.Durability] = 4;
					bonuses[Bonus.DurabilityMax] = 4;
				}
				else if (quality >= 55)
				{
					bonuses[Bonus.Durability] = 3;
					bonuses[Bonus.DurabilityMax] = 3;
				}
				else if (quality >= 35)
				{
					bonuses[Bonus.Durability] = 2;
					bonuses[Bonus.DurabilityMax] = 2;
				}
				else if (quality >= -20)
				{
				}
				else if (quality >= -60)
				{
					bonuses[Bonus.Durability] = -2;
					bonuses[Bonus.DurabilityMax] = 0;
				}
				else if (quality >= -80)
				{
					bonuses[Bonus.Durability] = -2;
					bonuses[Bonus.DurabilityMax] = -1;
				}
				else
				{
					bonuses[Bonus.Durability] = -3;
					bonuses[Bonus.DurabilityMax] = -2;
				}
			}

			// Gloves and Gauntles
			else if (item.HasTag("/hand/glove/|/hand/gauntlet/"))
			{
				// Protection
				if (quality >= 80)
					bonuses[Bonus.Protection] = 1;
			}

			// Boots, Shoes, and Greaves
			else if (item.HasTag("/foot/shoes/|/foot/armorboots/"))
			{
				// Durability
				if (quality >= 95)
				{
					bonuses[Bonus.Durability] = 5;
					bonuses[Bonus.DurabilityMax] = 5;
				}
				else if (quality >= 85)
				{
					bonuses[Bonus.Durability] = 4;
					bonuses[Bonus.DurabilityMax] = 4;
				}
				else if (quality >= 60)
				{
					bonuses[Bonus.Durability] = 3;
					bonuses[Bonus.DurabilityMax] = 3;
				}
				else if (quality >= 40)
				{
					bonuses[Bonus.Durability] = 2;
					bonuses[Bonus.DurabilityMax] = 2;
				}
				else if (quality >= 20)
				{
					bonuses[Bonus.Durability] = 1;
					bonuses[Bonus.DurabilityMax] = 1;
				}
				else if (quality >= -20)
				{
				}
				else if (quality >= -60)
				{
					bonuses[Bonus.Durability] = -2;
					bonuses[Bonus.DurabilityMax] = 0;
				}
				else if (quality >= -80)
				{
					bonuses[Bonus.Durability] = -2;
					bonuses[Bonus.DurabilityMax] = -1;
				}
				else
				{
					bonuses[Bonus.Durability] = -3;
					bonuses[Bonus.DurabilityMax] = -2;
				}
			}

			// Shields
			else if (item.HasTag("/lefthand/shield/"))
			{
				// Defense
				if (quality >= 90)
					bonuses[Bonus.Defense] = 1;

				// Durability
				if (quality >= 95)
				{
					bonuses[Bonus.Durability] = 5;
					bonuses[Bonus.DurabilityMax] = 5;
				}
				else if (quality >= 90)
				{
					bonuses[Bonus.Durability] = 4;
					bonuses[Bonus.DurabilityMax] = 4;
				}
				else if (quality >= 85)
				{
					bonuses[Bonus.Durability] = 3;
					bonuses[Bonus.DurabilityMax] = 3;
				}
				else if (quality >= 80)
				{
					bonuses[Bonus.Durability] = 2;
					bonuses[Bonus.DurabilityMax] = 2;
				}
				else if (quality >= 40)
				{
					bonuses[Bonus.Durability] = 1;
					bonuses[Bonus.DurabilityMax] = 1;
				}
				else if (quality >= -20)
				{
				}
				else if (quality >= -60)
				{
					bonuses[Bonus.Durability] = -2;
					bonuses[Bonus.DurabilityMax] = 0;
				}
				else if (quality >= -80)
				{
					bonuses[Bonus.Durability] = -2;
					bonuses[Bonus.DurabilityMax] = -1;
				}
				else
				{
					bonuses[Bonus.Durability] = -3;
					bonuses[Bonus.DurabilityMax] = -2;
				}
			}

			// Hats
			else if (item.HasTag("/headgear/"))
			{
				// Durability
				if (quality >= 90)
				{
					bonuses[Bonus.Durability] = 1;
					bonuses[Bonus.DurabilityMax] = 1;
				}
			}

			// Helmets
			else if (item.HasTag("/helmet/"))
			{
				// Durability
				if (quality >= 80)
				{
					bonuses[Bonus.Durability] = 1;
					bonuses[Bonus.DurabilityMax] = 1;
				}
			}

			// Robes
			else if (item.HasTag("/robe/"))
			{
				if (quality >= 80)
				{
					bonuses[Bonus.Durability] = 1;
					bonuses[Bonus.DurabilityMax] = 1;
				}
			}

			return bonuses;
		}
Exemplo n.º 20
0
		/// <summary>
		/// Handles skill training.
		/// </summary>
		/// <param name="creature"></param>
		/// <param name="skill"></param>
		/// <param name="item"></param>
		/// <param name="result"></param>
		private void OnProgress(Creature creature, Skill skill, Item item, ProgressResult result)
		{
			if (skill.Info.Rank == SkillRank.RF)
			{
				if (item.HasTag("/weapon/|/tool/"))
				{
					switch (result)
					{
						case ProgressResult.VeryGood: skill.Train(1); break; // Achieve a great result forging a tool or a weapon.
						case ProgressResult.Good: skill.Train(2); break;     // Achieve a good result forging a tool or a weapon.
						case ProgressResult.VeryBad: skill.Train(3); break;  // Achieve a failing result forging a tool or a weapon.
						case ProgressResult.Bad: skill.Train(4); break;      // Achieve a bad result forging a tool or a weapon.
						case ProgressResult.Finish: skill.Train(5); break;   // Successfully forge a tool or a weapon.
					}
				}

				return;
			}

			if (skill.Info.Rank == SkillRank.RE)
			{
				if (item.HasTag("/shield/"))
				{
					switch (result)
					{
						case ProgressResult.VeryGood: skill.Train(1); break; // Achieve a great result forging a shield.
						case ProgressResult.Good: skill.Train(2); break;     // Achieve a good result forging a shield.
						case ProgressResult.VeryBad: skill.Train(3); break;  // Achieve a failing result forging a shield.
						case ProgressResult.Bad: skill.Train(4); break;      // Achieve a bad result forging a shield.
						case ProgressResult.Finish: skill.Train(5); break;   // Successfully forge a shield.
					}
				}

				return;
			}

			if (skill.Info.Rank == SkillRank.RD)
			{
				if (item.HasTag("/helmet/"))
				{
					switch (result)
					{
						case ProgressResult.VeryGood: skill.Train(1); break; // Achieve a great result forging a helmet.
						case ProgressResult.Good: skill.Train(2); break;     // Achieve a good result forging a helmet.
						case ProgressResult.VeryBad: skill.Train(3); break;  // Achieve a failing result forging a helmet.
						case ProgressResult.Bad: skill.Train(4); break;      // Achieve a bad result forging a helmet.
						case ProgressResult.Finish: skill.Train(5); break;   // Successfully forge a helmet.
					}
				}

				return;
			}

			if (skill.Info.Rank == SkillRank.RC)
			{
				if (item.HasTag("/gauntlet/"))
				{
					switch (result)
					{
						case ProgressResult.VeryGood: skill.Train(1); break; // Achieve a great result forging gauntlets.
						case ProgressResult.Good: skill.Train(2); break;     // Achieve a good result forging gauntlets.
						case ProgressResult.VeryBad: skill.Train(3); break;  // Achieve a failing result forging gauntlets.
						case ProgressResult.Bad: skill.Train(4); break;      // Achieve a bad result forging gauntlets.
						case ProgressResult.Finish: skill.Train(5); break;   // Successfully forge gauntlets.
					}
				}

				return;
			}

			if (skill.Info.Rank == SkillRank.RB)
			{
				if (item.HasTag("/armorboots/"))
				{
					switch (result)
					{
						case ProgressResult.VeryGood: skill.Train(1); break; // Achieve a great result forging greaves.
						case ProgressResult.Good: skill.Train(2); break;     // Achieve a good result forging greaves.
						case ProgressResult.VeryBad: skill.Train(3); break;  // Achieve a failing result forging greaves.
						case ProgressResult.Bad: skill.Train(4); break;      // Achieve a bad result forging greaves.
						case ProgressResult.Finish: skill.Train(5); break;   // Successfully forge greaves.
					}
				}

				return;
			}

			if (skill.Info.Rank == SkillRank.RA)
			{
				if (item.HasTag("/armor/"))
				{
					switch (result)
					{
						case ProgressResult.VeryGood: skill.Train(1); break; // Greatly successful in making Armor
						case ProgressResult.Good: skill.Train(2); break;     // Successful in making Armors
						case ProgressResult.VeryBad: skill.Train(3); break;  // If unsuccessful in making Armor
						case ProgressResult.Bad: skill.Train(4); break;      // The result of making Armor is very poor.
						case ProgressResult.Finish: skill.Train(5); break;   // Completed making Armor 100%.
					}
				}

				return;
			}

			if (skill.Info.Rank == SkillRank.R9)
			{
				if (item.HasTag("/armor/"))
				{
					switch (result)
					{
						case ProgressResult.VeryGood: skill.Train(1); break; // Greatly successful in making Armor
						case ProgressResult.Good: skill.Train(2); break;     // Successful in making Armors
						case ProgressResult.Finish: skill.Train(3); break;   // Completed making Armor 100%.
					}
				}
				else if (item.HasTag("/weapon/|/tool/"))
				{
					switch (result)
					{
						case ProgressResult.Good: skill.Train(4); break;     // Successful in making a tool or a weapon.
						case ProgressResult.Finish: skill.Train(5); break;   // Completed making tool or a weapon 100%.
					}
				}

				return;
			}

			if (skill.Info.Rank == SkillRank.R8)
			{
				if (item.HasTag("/armor/"))
				{
					switch (result)
					{
						case ProgressResult.VeryGood: skill.Train(1); break; // Greatly successful in making Armor
						case ProgressResult.Good: skill.Train(2); break;     // Successful in making Armors
						case ProgressResult.Finish: skill.Train(3); break;   // Completed making Armor 100%.
					}
				}
				else if (item.HasTag("/shield/"))
				{
					switch (result)
					{
						case ProgressResult.Good: skill.Train(4); break;     // Successful in making a Shield.
						case ProgressResult.Finish: skill.Train(5); break;   // Completed making a Shield 100%.
					}
				}

				return;
			}

			if (skill.Info.Rank == SkillRank.R7)
			{
				if (item.HasTag("/armor/"))
				{
					switch (result)
					{
						case ProgressResult.VeryGood: skill.Train(1); break; // Achieve a great result forging armor.
						case ProgressResult.Good: skill.Train(2); break;     // Achieve a good result forging armor.
						case ProgressResult.Finish: skill.Train(3); break;   // Successfully forge armor.
					}
				}
				else if (item.HasTag("/helmet/"))
				{
					switch (result)
					{
						case ProgressResult.Good: skill.Train(4); break;     // Achieve a good result forging a helmet.
						case ProgressResult.Finish: skill.Train(5); break;   // Successfully forge a helmet.
					}
				}

				return;
			}

			if (skill.Info.Rank == SkillRank.R6)
			{
				if (item.HasTag("/armor/"))
				{
					switch (result)
					{
						case ProgressResult.VeryGood: skill.Train(1); break; // Achieve a great result forging armor.
						case ProgressResult.Good: skill.Train(2); break;     // Achieve a good result forging armor.
						case ProgressResult.Finish: skill.Train(3); break;   // Successfully forge armor.
					}
				}
				else if (item.HasTag("/gauntlet/"))
				{
					switch (result)
					{
						case ProgressResult.Good: skill.Train(4); break;     // Achieve a good result forging gauntlets.
						case ProgressResult.Finish: skill.Train(5); break;   // Successfully forge gauntlets.
					}
				}

				return;
			}

			if (skill.Info.Rank == SkillRank.R5)
			{
				if (item.HasTag("/armor/"))
				{
					switch (result)
					{
						case ProgressResult.VeryGood: skill.Train(1); break; // Achieve a great result forging armor.
						case ProgressResult.Good: skill.Train(2); break;     // Achieve a good result forging armor.
						case ProgressResult.Finish: skill.Train(3); break;   // Successfully forge armor.
					}
				}
				else if (item.HasTag("/armorboots/"))
				{
					switch (result)
					{
						case ProgressResult.Good: skill.Train(4); break;     // Achieve a good result forging greaves.
						case ProgressResult.Finish: skill.Train(5); break;   // Successfully forge greaves.
					}
				}

				return;
			}

			if (skill.Info.Rank >= SkillRank.R4 && skill.Info.Rank <= SkillRank.R3)
			{
				if (item.HasTag("/armor/"))
				{
					switch (result)
					{
						case ProgressResult.VeryGood: skill.Train(1); break; // Achieve a great result forging armor.
						case ProgressResult.Good: skill.Train(2); break;     // Achieve a good result forging armor.
						case ProgressResult.Finish: skill.Train(3); break;   // Successfully forge armor.
					}
				}
				else if (item.HasTag("/weapon/|/tool/"))
				{
					switch (result)
					{
						case ProgressResult.Good: skill.Train(4); break;     // Achieve a good result forging a tool or a weapon.
						case ProgressResult.Finish: skill.Train(5); break;   // Successfully forge a tool or a weapon.
					}
				}

				return;
			}

			if (skill.Info.Rank >= SkillRank.R2 && skill.Info.Rank <= SkillRank.R1)
			{
				if (item.HasTag("/armor/"))
				{
					switch (result)
					{
						case ProgressResult.Good: skill.Train(1); break;     // Achieve a good result forging armor.
						case ProgressResult.Finish: skill.Train(2); break;   // Successfully forge armor.
					}
				}
				else if (item.HasTag("/weapon/|/tool/"))
				{
					switch (result)
					{
						case ProgressResult.Good: skill.Train(3); break;     // Achieve a good result forging a tool or a weapon.
						case ProgressResult.Finish: skill.Train(4); break;   // Successfully forge a tool or a weapon.
					}
				}

				return;
			}
		}
Exemplo n.º 21
0
		/// <summary>
		/// Gets the prop ID
		/// </summary>
		/// <param name="item"></param>
		/// <returns></returns>
		private int GetPropId(Item item)
		{
			if (item != null)
			{
				if (item.HasTag("/halloween_campfire_kit/"))
				{
					return HalloweenPropId;
				}
				else if (item.HasTag("/burner/"))
				{
					return ChristmasPropId;
				}
				else if (item.HasTag("/anniversary_campfire_kit/"))
				{
					return SeventhAnnvPropId;
				}
			}

			return PropId;
		}
Exemplo n.º 22
0
		public static Packet AddItemInfo(this Packet packet, Item item, ItemPacketType type)
		{
			var isEgoWeapon = item.HasTag("/ego_weapon/");
			var isGuildRobe = item.HasTag("/guild_robe/");

			packet.PutLong(item.EntityId);
			packet.PutByte((byte)type);
			packet.PutBin(item.Info);

			if (isGuildRobe)
				// EBCL1:4:-16351525;EBCL2:4:-875718;EBLM1:1:46;EBLM2:1:11;EBLM3:1:4; (GLDNAM:s:European;)
				packet.PutString(item.MetaData1.ToString());

			if (type == ItemPacketType.Public)
			{
				packet.PutByte(1);

				// Affects color of dropped item's name (blue or green),
				// indicating its value.
				packet.PutByte((byte)item.UpgradeEffectCount);

				//packet.PutByte(0); // Bitmask
				// if & 1
				//     float
				packet.PutByte(1);
				packet.PutFloat(1); // Size multiplicator *hint: Server side giant key mod*

				packet.PutByte(item.FirstTimeAppear); // 0: No bouncing, 1: Bouncing, 2: Delayed bouncing
			}
			else if (type == ItemPacketType.Private)
			{
				packet.PutBin(item.OptionInfo);

				// Ego data
				if (isEgoWeapon)
				{
					packet.PutString(item.EgoInfo.Name);
					packet.PutByte((byte)item.EgoInfo.Race);
					packet.PutByte(0); // ? increased from 14 to 18 when I fed a bottle to a sword

					packet.PutByte(item.EgoInfo.SocialLevel);
					packet.PutInt(item.EgoInfo.SocialExp);
					packet.PutByte(item.EgoInfo.StrLevel);
					packet.PutInt(item.EgoInfo.StrExp);
					packet.PutByte(item.EgoInfo.IntLevel);
					packet.PutInt(item.EgoInfo.IntExp);
					packet.PutByte(item.EgoInfo.DexLevel);
					packet.PutInt(item.EgoInfo.DexExp);
					packet.PutByte(item.EgoInfo.WillLevel);
					packet.PutInt(item.EgoInfo.WillExp);
					packet.PutByte(item.EgoInfo.LuckLevel);
					packet.PutInt(item.EgoInfo.LuckExp);
					packet.PutByte(item.EgoInfo.AwakeningEnergy);
					packet.PutInt(item.EgoInfo.AwakeningExp);

					packet.PutLong(0);
					packet.PutLong(item.EgoInfo.LastFeeding); // Last feeding time?
					packet.PutInt(0);
				}

				packet.PutString(item.MetaData1.ToString());
				packet.PutString(item.MetaData2.ToString());

				// Upgrades
				var upgradeEffects = item.GetUpgradeEffects();
				packet.PutByte((byte)upgradeEffects.Length);
				foreach (var upgradeEffect in upgradeEffects)
					packet.PutBin(upgradeEffect);

				// Special upgrades? (example)
				//0608 [0000000000000000] Long   : 0
				//0609 [........00000002] Int    : 2
				//0610 [........00000024] Int    : 36
				//0611 [........00000008] Int    : 8
				//0612 [........00000026] Int    : 38
				//0613 [........00000004] Int    : 4

				packet.PutLong(item.QuestId);

				if (isGuildRobe)
					packet.PutString(item.MetaData1.GetString("GLDNAM"));

				// In NA235 (Sep. 2016) we found an additional integer for
				// Scythe that Reaps Darkness here, with no known purpose.
				// In NA236 we had to remove said int again.
				// It will be missed.
				//if (item.Info.Id == 41237)
				//	packet.PutInt(0);

				// [190100, NA200 (2015-01-15)] ?
				{
					packet.PutByte(item.IsNew);
					packet.PutByte(0);
				}
			}

			return packet;
		}