示例#1
0
        /// <summary>
        /// Runs equipment updates if necessary.
        /// </summary>
        /// <param name="item"></param>
        /// <param name="source"></param>
        /// <param name="target"></param>
        private void CheckEquipMoved(Item item, Pocket source, Pocket target)
        {
            if (source.IsEquip())
            {
                Send.EquipmentMoved(_creature, source);
            }

            if (target.IsEquip())
            {
                Send.EquipmentChanged(_creature, item);
            }

            // Send stat update when moving equipment
            if (source.IsEquip() || target.IsEquip())
            {
                this.UpdateEquipStats();
            }
        }
示例#2
0
        /// <summary>
        /// Runs equipment updates if necessary.
        /// </summary>
        /// <param name="item"></param>
        /// <param name="source"></param>
        /// <param name="target"></param>
        private void CheckEquipMoved(Item item, Pocket source, Pocket target)
        {
            if (source.IsEquip())
            {
                Send.EquipmentMoved(_creature, source);
            }

            if (target.IsEquip())
            {
                Send.EquipmentChanged(_creature, item);
            }

            // Send stat update when moving equipment
            if (source.IsEquip() || target.IsEquip())
            {
                Send.StatUpdate(_creature, StatUpdateType.Private,
                                Stat.AttackMinBaseMod, Stat.AttackMaxBaseMod,
                                Stat.InjuryMinBaseMod, Stat.InjuryMaxBaseMod,
                                Stat.BalanceBaseMod, Stat.CriticalBaseMod,
                                Stat.DefenseBaseMod, Stat.ProtectionBaseMod
                                );
            }
        }
示例#3
0
        protected virtual void EquipItem(Pocket pocket, uint itemClass, uint color1 = 0, uint color2 = 0, uint color3 = 0)
        {
            if (!pocket.IsEquip())
                return;

            var item = new MabiItem(itemClass);
            item.Info.ColorA = color1;
            item.Info.ColorB = color2;
            item.Info.ColorC = color3;

            //var inPocket = this.Creature.GetItemInPocket(slot);
            //if (inPocket != null)
            //    this.Creature.Items.Remove(inPocket);

            this.Creature.Inventory.ForceAdd(item, pocket);

            Send.EquipmentChanged(this.Creature, item);
        }
示例#4
0
		/// <summary>
		/// Adds item to NPC's inventory.
		/// </summary>
		/// <param name="pocket"></param>
		/// <param name="itemId"></param>
		/// <param name="color1"></param>
		/// <param name="color2"></param>
		/// <param name="color3"></param>
		/// <param name="state">For robes and helmets</param>
		protected void EquipItem(Pocket pocket, int itemId, uint color1 = 0, uint color2 = 0, uint color3 = 0, ItemState state = ItemState.Up)
		{
			if (this.NPC == null)
				throw new InvalidOperationException("NPC's race has to be set first.");

			if (!pocket.IsEquip())
			{
				Log.Error("Pocket '{0}' is not for equipment ({1})", pocket, this.GetType().Name);
				return;
			}

			if (!AuraData.ItemDb.Exists(itemId))
			{
				Log.Error("Unknown item '{0}' ({1})", itemId, this.GetType().Name);
				return;
			}

			var item = new Item(itemId);
			item.Info.Pocket = pocket;
			item.Info.Color1 = color1;
			item.Info.Color2 = color2;
			item.Info.Color3 = color3;
			item.Info.State = (byte)state;

			this.NPC.Inventory.InitAdd(item);
		}
示例#5
0
        /// <summary>
        /// Runs equipment updates if necessary.
        /// </summary>
        /// <param name="item"></param>
        /// <param name="source"></param>
        /// <param name="target"></param>
        private void CheckEquipMoved(Item item, Pocket source, Pocket target)
        {
            if (source.IsEquip())
                Send.EquipmentMoved(_creature, source);

            if (target.IsEquip())
                Send.EquipmentChanged(_creature, item);

            // Send stat update when moving equipment
            if (source.IsEquip() || target.IsEquip())
            {
                Send.StatUpdate(_creature, StatUpdateType.Private,
                    Stat.AttackMinBaseMod, Stat.AttackMaxBaseMod,
                    Stat.WAttackMinBaseMod, Stat.WAttackMaxBaseMod,
                    Stat.BalanceBaseMod, Stat.CriticalBaseMod,
                    Stat.DefenseBaseMod, Stat.ProtectionBaseMod
                );
            }
        }
示例#6
0
		/// <summary>
		/// Runs equipment updates if necessary.
		/// </summary>
		/// <param name="item"></param>
		/// <param name="source"></param>
		/// <param name="target"></param>
		private void CheckEquipMoved(Item item, Pocket source, Pocket target)
		{
			if (source.IsEquip())
				Send.EquipmentMoved(_creature, source);

			if (target.IsEquip())
				Send.EquipmentChanged(_creature, item);

			// Send stat update when moving equipment
			if (source.IsEquip() || target.IsEquip())
				this.UpdateEquipStats();
		}
示例#7
0
		/// <summary>
		/// Moving item between char and pet, used from handler.
		/// </summary>
		/// <param name="pet">Always the pet</param>
		/// <param name="item"></param>
		/// <param name="other">The "other" creature, player when taking out, pet when putting in.</param>
		/// <param name="target"></param>
		/// <param name="targetX"></param>
		/// <param name="targetY"></param>
		/// <returns></returns>
		public bool MovePet(Creature pet, Item item, Creature other, Pocket target, int targetX, int targetY)
		{
			if (!this.Has(target) || !other.Inventory.Has(target))
				return false;

			var source = item.Info.Pocket;
			var amount = item.Info.Amount;

			// We have to copy the item to get a new id, otherwise there could
			// be collisions when saving, because the moved item is still in
			// the inventory of the pet/character (from the pov of the db).
			// http://dev.mabinoger.com/forum/index.php/topic/804-pet-inventory/
			var newItem = new Item(item);

			Item collidingItem = null;
			lock (_pockets)
			{
				if (!other.Inventory._pockets[target].TryAdd(newItem, (byte)targetX, (byte)targetY, out collidingItem))
					return false;

				// If amount differs (item was added to stack)
				if (collidingItem != null && newItem.Info.Amount != amount)
				{
					Send.ItemAmount(other, collidingItem);

					// Left overs, update
					if (newItem.Info.Amount > 0)
					{
						item.Info.Amount = newItem.Info.Amount;
						Send.ItemAmount(_creature, item);
					}
					// All in, remove from cursor.
					else
					{
						_pockets[item.Info.Pocket].Remove(item);
						Send.ItemRemove(_creature, item);
					}
				}
				else
				{
					// Remove the item from the source pocket
					_pockets[source].Remove(item);
					Send.ItemRemove(_creature, item, source);

					if (collidingItem != null)
					{
						// Remove colliding item
						Send.ItemRemove(other, collidingItem, target);

						var collidingItemCopy = new Item(collidingItem);

						// Toss it in, it should be the cursor.
						_pockets[source].Add(collidingItemCopy);
						Send.ItemNew(_creature, collidingItemCopy);
					}

					Send.ItemNew(other, newItem);

					Send.ItemMoveInfo(_creature, item, source, collidingItem);
				}
			}

			// Check movement
			pet.Inventory.CheckLeftHand(item, source, target);
			pet.Inventory.CheckRightHand(item, source, target);

			// Equip handling
			if (target.IsEquip())
			{
				pet.Inventory.UpdateEquipReferences();
				pet.Inventory.OnEquip(item);
				if (collidingItem != null)
					pet.Inventory.OnUnequip(collidingItem);
				pet.Inventory.UpdateEquipStats();

				Send.EquipmentChanged(pet, newItem);
			}
			else if (source.IsEquip())
			{
				pet.Inventory.UpdateEquipReferences();
				pet.Inventory.OnUnequip(item);
				pet.Inventory.UpdateEquipStats();

				Send.EquipmentMoved(pet, source);
			}

			return true;
		}
示例#8
0
		// Handlers
		// ------------------------------------------------------------------

		/// <summary>
		/// Used from MoveItem handler.
		/// </summary>
		/// <remarks>
		/// The item is the one that's interacted with, the one picked up
		/// when taking it, the one being put into a packet when it's one
		/// the cursor. Colliding items switch places with it.
		/// </remarks>
		/// <param name="item">Item to move</param>
		/// <param name="target">Pocket to move it to</param>
		/// <param name="targetX"></param>
		/// <param name="targetY"></param>
		/// <returns></returns>
		public bool Move(Item item, Pocket target, byte targetX, byte targetY)
		{
			if (!this.Has(target))
				return false;

			var source = item.Info.Pocket;
			var amount = item.Info.Amount;

			Item collidingItem = null;
			var collidingItemTarget = source;

			lock (_pockets)
			{
				// Hotfix for #200, ctrl+click-equipping.
				// If an item is moved from the inventory to a filled equip
				// slot, but there's not enough space in the source pocket
				// for the colliding item, it would vanish, because the Add
				// failed. ("Toss it in, it should be the cursor.")
				//
				// The following code tries to prevent that, by explicitly
				// checking if this is a ctrl+click-equip move, and whether
				// the potentially colliding item fits into the inventory.
				// 
				// Is there a better way to solve this? Maybe a more
				// generalized one? *Without* reverting the move on fail?
				if (source != Pocket.Cursor && target.IsEquip())
				{
					//Log.Debug("Inv2EqMove: {0} -> {1}", source, target);

					if ((collidingItem = _pockets[target].GetItemAt(0, 0)) != null)
					{
						var success = false;

						// Cursor will work by default, as it will be
						// empty after moving the new item out of it.
						if (source == Pocket.Cursor)
						{
							success = true;
							collidingItemTarget = Pocket.Cursor;
						}

						// Try main inv
						if (!success)
						{
							if (_pockets.ContainsKey(Pocket.Inventory))
							{
								success = _pockets[Pocket.Inventory].HasSpace(collidingItem);
								collidingItemTarget = Pocket.Inventory;
							}
						}

						// VIP inv
						if (!success)
						{
							if (_pockets.ContainsKey(Pocket.VIPInventory))
							{
								success = _pockets[Pocket.VIPInventory].HasSpace(collidingItem);
								collidingItemTarget = Pocket.VIPInventory;
							}
						}

						// Try bags
						if (_creature.Client.Account.PremiumServices.CanUseBags)
						{
							for (var i = Pocket.ItemBags; i <= Pocket.ItemBagsMax && !success; ++i)
							{
								if (_pockets.ContainsKey(i))
								{
									success = _pockets[i].HasSpace(collidingItem);
									collidingItemTarget = i;
								}
							}
						}

						if (!success)
						{
							Send.Notice(_creature, Localization.Get("There is no room in your inventory."));
							return false;
						}
					}
				}

				if (!_pockets[target].TryAdd(item, targetX, targetY, out collidingItem))
					return false;

				// If amount differs (item was added to stack)
				if (collidingItem != null && (item.Info.Amount != amount || (item.Info.Amount == 0 && item.Data.Type != ItemType.Sac)))
				{
					Send.ItemAmount(_creature, collidingItem);

					// Left overs or sac, update
					if (item.Info.Amount > 0 || item.Data.Type == ItemType.Sac)
					{
						Send.ItemAmount(_creature, item);
					}
					// All in, remove from cursor.
					else
					{
						_pockets[item.Info.Pocket].Remove(item);
						Send.ItemRemove(_creature, item);
					}
				}
				else
				{
					// Remove the item from the source pocket
					_pockets[source].Remove(item);

					if (collidingItem != null)
					{
						// Move colliding item into the pocket ascertained to
						// be free in the beginning.
						if (!_pockets[collidingItemTarget].Add(collidingItem))
						{
							// Should never happen, as it was checked above.
							Log.Error("CreatureInventory: Inv2EqMove error? Please report. {0} -> {1}", source, target);
						}
					}

					Send.ItemMoveInfo(_creature, item, source, collidingItem);
				}
			}

			// Inform about temp moves (items in temp don't count for quest objectives?)
			if (source == Pocket.Temporary && target == Pocket.Cursor)
			{
				this.OnItemEntersInventory(item);
				ChannelServer.Instance.Events.OnPlayerReceivesItem(_creature, item.Info.Id, item.Info.Amount);
			}

			// Check movement
			this.CheckLeftHand(item, source, target);
			this.CheckRightHand(item, source, target);

			// Equip handling
			if (target.IsEquip())
			{
				this.UpdateEquipReferences();
				this.OnEquip(item);
				if (collidingItem != null)
					this.OnUnequip(collidingItem);
				this.UpdateEquipStats();

				Send.EquipmentChanged(_creature, item);
			}
			else if (source.IsEquip())
			{
				this.UpdateEquipReferences();
				this.OnUnequip(item);
				this.UpdateEquipStats();

				Send.EquipmentMoved(_creature, source);
			}

			// Update trade window
			if (target == Pocket.Trade)
			{
				if (collidingItem != null)
					_creature.Temp.ActiveTrade.RemoveItem(_creature, collidingItem);
				_creature.Temp.ActiveTrade.AddItem(_creature, item);
			}
			if (source == Pocket.Trade) _creature.Temp.ActiveTrade.RemoveItem(_creature, item);

			// Update entrustment window
			if (target >= Pocket.EntrustmentItem1 && target <= Pocket.EntrustmentReward)
			{
				if (collidingItem != null)
					_creature.Temp.ActiveEntrustment.RemoveItem(collidingItem, target);
				_creature.Temp.ActiveEntrustment.AddItem(item, target);
			}
			if (source >= Pocket.EntrustmentItem1 && source <= Pocket.EntrustmentReward) _creature.Temp.ActiveEntrustment.RemoveItem(item, source);

			return true;
		}
示例#9
0
		// TODO: Add central "Add" method that all others use, for central stuff
		//   like adding bag pockets. This wil require a GetFreePosition
		//   method in the pockets.

		/// <summary>
		/// Tries to add item to pocket. Returns false if the pocket
		/// doesn't exist or there was no space.
		/// </summary>
		public bool Add(Item item, Pocket pocket)
		{
			var success = false;

			lock (_pockets)
			{
				if (!_pockets.ContainsKey(pocket))
					return success;

				success = _pockets[pocket].Add(item);
			}

			if (success)
			{
				this.PrepareBags(item);

				Send.ItemNew(_creature, item);

				if (_creature.IsPlayer && pocket != Pocket.Temporary)
				{
					this.OnItemEntersInventory(item);

					// Notify everybody about receiving the item.
					ChannelServer.Instance.Events.OnPlayerReceivesItem(_creature, item.Info.Id, item.Amount);

					// If item was a sac, we have to notify the server about
					// receiving its *contents* as well.
					if (item.Data.StackType == StackType.Sac)
						ChannelServer.Instance.Events.OnPlayerReceivesItem(_creature, item.Data.StackItemId, item.Info.Amount);
				}

				if (pocket.IsEquip())
				{
					this.UpdateEquipReferences();
					this.OnEquip(item);
					this.UpdateEquipStats();

					if (_creature.Region != Region.Limbo)
						Send.EquipmentChanged(_creature, item);
				}
			}

			return success;
		}
示例#10
0
        /// <summary>
        /// Sends EquipmentMoved and EquipmentChanged, if necessary.
        /// </summary>
        /// <param name="item"></param>
        /// <param name="source"></param>
        /// <param name="target"></param>
        private void CheckEquipMoved(MabiItem item, Pocket source, Pocket target)
        {
            if (source.IsEquip())
                Send.EquipmentMoved(_creature, source);

            if (target.IsEquip())
            {
                Send.EquipmentChanged(_creature, item);

                // TODO: Equip/Unequip item scripts
                switch (item.Info.Class)
                {
                    // Umbrella Skill
                    case 41021:
                    case 41022:
                    case 41023:
                    case 41025:
                    case 41026:
                    case 41027:
                    case 41061:
                    case 41062:
                    case 41063:
                        if (!_creature.Skills.Has(SkillConst.Umbrella))
                            _creature.Skills.Give(SkillConst.Umbrella, SkillRank.Novice);
                        break;

                    // Spread Wings
                    case 19138:
                    case 19139:
                    case 19140:
                    case 19141:
                    case 19142:
                    case 19143:
                    case 19157:
                    case 19158:
                    case 19159:
                        if (!_creature.Skills.Has(SkillConst.SpreadWings))
                            _creature.Skills.Give(SkillConst.SpreadWings, SkillRank.Novice);
                        break;
                }
            }
        }
示例#11
0
文件: NpcScript.cs 项目: pie3467/aura
		/// <summary>
		/// Adds item to NPC's inventory.
		/// </summary>
		/// <param name="pocket"></param>
		/// <param name="itemId"></param>
		/// <param name="color1"></param>
		/// <param name="color2"></param>
		/// <param name="color3"></param>
		/// <param name="state">For robes and helmets</param>
		protected void EquipItem(Pocket pocket, int itemId, uint color1 = 0, uint color2 = 0, uint color3 = 0, ItemState state = ItemState.Up)
		{
			if (!pocket.IsEquip())
			{
				Log.Error("Pocket '{0}' is not for equipment ({1})", pocket, this.ScriptFilePath);
				return;
			}

			if (!AuraData.ItemDb.Exists(itemId))
			{
				Log.Error("Unknown item '{0}' ({1})", itemId, this.ScriptFilePath);
				return;
			}

			var item = new Item(itemId);
			item.Info.Pocket = pocket;
			item.Info.Color1 = color1;
			item.Info.Color2 = color2;
			item.Info.Color3 = color3;
			item.Info.State = (byte)state;

			this.NPC.Inventory.InitAdd(item);
		}