コード例 #1
0
ファイル: PlayerObject.cs プロジェクト: Fenarir/mir2
        public void CombineItem(ulong fromID, ulong toID)
        {
            S.CombineItem p = new S.CombineItem { IDFrom = fromID, IDTo = toID, Success = false };

            UserItem[] array = Info.Inventory;
            UserItem tempFrom = null;
            UserItem tempTo = null;
            int indexFrom = -1;
            int indexTo = -1;

            if (Dead)
            {
                Enqueue(p);
                return;
            }

            for (int i = 0; i < array.Length; i++)
            {
                if (array[i] == null || array[i].UniqueID != fromID) continue;
                indexFrom = i;
                tempFrom = array[i];
                break;
            }

            if (tempFrom == null || indexFrom == -1)
            {
                Enqueue(p);
                return;
            }

            for (int i = 0; i < array.Length; i++)
            {
                if (array[i] == null || array[i].UniqueID != toID) continue;
                indexTo = i;
                tempTo = array[i];
                break;
            }

            if (tempTo == null || indexTo == -1)
            {
                Enqueue(p);
                return;
            }

            if((byte)tempTo.Info.Type < 1 || (byte)tempTo.Info.Type > 11)
            {
                Enqueue(p);
                return;
            }

            bool canRepair = false, canUpgrade = false;

            if (tempFrom.Info.Type != ItemType.Gem)
            {
                Enqueue(p);
                return;
            }

            switch (tempFrom.Info.Shape)
            {
                case 1: //BoneHammer
                case 2: //SewingSupplies
                case 5: //SpecialHammer
                case 6: //SpecialSewingSupplies

                    if (tempTo.Info.Bind.HasFlag(BindMode.DontRepair))
                    {
                        Enqueue(p);
                        return;
                    }

                    switch (tempTo.Info.Type)
                    {
                        case ItemType.Weapon:
                        case ItemType.Necklace:
                        case ItemType.Ring:
                        case ItemType.Bracelet:
                            if (tempFrom.Info.Shape == 1 || tempFrom.Info.Shape == 5)
                                canRepair = true;
                            break;
                        case ItemType.Armour:
                        case ItemType.Helmet:
                        case ItemType.Boots:
                        case ItemType.Belt:
                            if (tempFrom.Info.Shape == 2 || tempFrom.Info.Shape == 6)
                                canRepair = true;
                            break;
                        default:
                            canRepair = false;
                            break;
                    }

                    if (canRepair != true)
                    {
                        Enqueue(p);
                        return;
                    }

                    if (tempTo.CurrentDura == tempTo.MaxDura)
                    {
                        ReceiveChat("Item does not need to be repaired.", ChatType.Hint);
                        Enqueue(p);
                        return;
                    }
                    break;
                case 3: //gems
                case 4: //orbs

                    if (tempTo.Info.Bind.HasFlag(BindMode.DontUpgrade) || tempTo.Info.Unique != SpecialItemMode.None)
                    {
                        Enqueue(p);
                        return;
                    }

                    if ((tempTo.GemCount >= tempFrom.Info.CriticalDamage) || (GetCurrentStatCount(tempFrom,tempTo) >= tempFrom.Info.HpDrainRate))
                    {
                        ReceiveChat("Item has already reached maximum added stats", ChatType.Hint);
                        Enqueue(p);
                        return;
                    }

                    int successchance = tempFrom.Info.Reflect * (int)tempTo.GemCount;
                    successchance = successchance >= tempFrom.Info.CriticalRate ? 0 : tempFrom.Info.CriticalRate - successchance;

                    //check if combine will succeed

                    bool succeeded = Envir.Random.Next(100) < successchance;
                    canUpgrade = true;

                    byte itemType = (byte)tempTo.Info.Type;

                    if (!ValidGemForItem(tempFrom, itemType))
                    {
                        ReceiveChat("Invalid combination", ChatType.Hint);
                        Enqueue(p);
                        return;
                    }

                    if ((tempFrom.Info.MaxDC + tempFrom.DC) > 0)
                    {
                        if (succeeded) tempTo.DC = (byte)Math.Min(byte.MaxValue, tempTo.DC + tempFrom.Info.MaxDC + tempFrom.DC);
                    }

                    else if ((tempFrom.Info.MaxMC + tempFrom.MC) > 0)
                    {
                        if (succeeded) tempTo.MC = (byte)Math.Min(byte.MaxValue, tempTo.MC + tempFrom.Info.MaxMC + tempFrom.MC);
                    }

                    else if ((tempFrom.Info.MaxSC + tempFrom.SC) > 0)
                    {
                        if (succeeded) tempTo.SC = (byte)Math.Min(byte.MaxValue, tempTo.SC + tempFrom.Info.MaxSC + tempFrom.SC);
                    }

                    else if ((tempFrom.Info.MaxAC + tempFrom.AC) > 0)
                    {
                        if (succeeded) tempTo.AC = (byte)Math.Min(byte.MaxValue, tempTo.AC + tempFrom.Info.MaxAC + tempFrom.AC);
                    }

                    else if ((tempFrom.Info.MaxMAC + tempFrom.MAC) > 0)
                    {
                        if (succeeded) tempTo.MAC = (byte)Math.Min(byte.MaxValue, tempTo.MAC + tempFrom.Info.MaxMAC + tempFrom.MAC);
                    }

                    else if ((tempFrom.Info.Durability) > 0)
                    {
                        if (succeeded) tempTo.MaxDura = (ushort)Math.Min(ushort.MaxValue, tempTo.MaxDura + tempFrom.MaxDura);
                    }

                    else if ((tempFrom.Info.AttackSpeed + tempFrom.AttackSpeed) > 0)
                    {
                        if (succeeded) tempTo.AttackSpeed = (sbyte)Math.Max(sbyte.MinValue, (Math.Min(sbyte.MaxValue, tempTo.AttackSpeed + tempFrom.Info.AttackSpeed + tempFrom.AttackSpeed)));
                    }

                    else if ((tempFrom.Info.Agility + tempFrom.Agility) > 0)
                    {
                        if (succeeded) tempTo.Agility = (byte)Math.Min(byte.MaxValue, tempFrom.Info.Agility + tempTo.Agility + tempFrom.Agility);
                    }

                    else if ((tempFrom.Info.Accuracy + tempFrom.Accuracy) > 0)
                    {
                        if (succeeded) tempTo.Accuracy = (byte)Math.Min(byte.MaxValue, tempFrom.Info.Accuracy + tempTo.Accuracy + tempFrom.Accuracy);
                    }

                    else if ((tempFrom.Info.PoisonAttack + tempFrom.PoisonAttack) > 0)
                    {
                        if (succeeded) tempTo.PoisonAttack = (byte)Math.Min(byte.MaxValue, tempFrom.Info.PoisonAttack + tempTo.PoisonAttack + tempFrom.PoisonAttack);
                    }

                    else if ((tempFrom.Info.Freezing + tempFrom.Freezing) > 0)
                    {
                        if (succeeded) tempTo.Freezing = (byte)Math.Min(byte.MaxValue, tempFrom.Info.Freezing + tempTo.Freezing + tempFrom.Freezing);
                    }

                    else if ((tempFrom.Info.MagicResist + tempFrom.MagicResist) > 0)
                    {
                        if (succeeded) tempTo.MagicResist = (byte)Math.Min(byte.MaxValue, tempFrom.Info.MagicResist + tempTo.MagicResist + tempFrom.MagicResist);
                    }

                    else if ((tempFrom.Info.PoisonResist + tempFrom.PoisonResist) > 0)
                    {
                        if (succeeded) tempTo.PoisonResist = (byte)Math.Min(byte.MaxValue, tempFrom.Info.PoisonResist + tempTo.PoisonResist + tempFrom.PoisonResist);
                    }
                    else
                    {
                        ReceiveChat("Cannot combine these items.", ChatType.Hint);
                        Enqueue(p);
                        return;
                    }

                    if (!succeeded)
                    {

                        if ((tempFrom.Info.Shape == 3) && (Envir.Random.Next(15) < 3))
                        {
                            //item destroyed
                            ReceiveChat("Item has been destroyed.", ChatType.Hint);
                            Report.ItemChanged("CombineItem (Item Destroyed)", Info.Inventory[indexTo], 1, 1);

                            Info.Inventory[indexTo] = null;
                            p.Destroy = true;
                        }
                        else
                        {
                            //upgrade has no effect
                            ReceiveChat("Upgrade has no effect.", ChatType.Hint);
                        }

                        canUpgrade = false;
                    }
                    break;
                default:
                    Enqueue(p);
                    return;
            }

            RefreshBagWeight();

            if (canRepair && Info.Inventory[indexTo] != null)
            {
                switch (tempTo.Info.Shape)
                {
                    case 1:
                    case 2:
                        {
                            tempTo.MaxDura = (ushort)Math.Max(0, Math.Min(tempTo.MaxDura, tempTo.MaxDura - 100 * Envir.Random.Next(10)));
                        }
                        break;
                    default:
                        break;
                }
                tempTo.CurrentDura = tempTo.MaxDura;
                tempTo.DuraChanged = false;

                ReceiveChat("Item has been repaired.", ChatType.Hint);
                Enqueue(new S.ItemRepaired { UniqueID = tempTo.UniqueID, MaxDura = tempTo.MaxDura, CurrentDura = tempTo.CurrentDura });
            }

            if (canUpgrade && Info.Inventory[indexTo] != null)
            {
                tempTo.GemCount++;
                ReceiveChat("Item has been upgraded.", ChatType.Hint);
                Enqueue(new S.ItemUpgraded { Item = tempTo });
            }

            if (tempFrom.Count > 1) tempFrom.Count--;
            else Info.Inventory[indexFrom] = null;

            Report.ItemCombined("CombineItem", tempFrom, tempTo, indexFrom, indexTo, MirGridType.Inventory);

            //item merged ok
            p.Success = true;
            Enqueue(p);
        }
コード例 #2
0
        public void CombineItem(ulong fromID, ulong toID)
        {
            S.CombineItem p = new S.CombineItem { IDFrom = fromID, IDTo = toID, Success = false };

            UserItem[] array = Info.Inventory;
            UserItem tempFrom = null;
            UserItem tempTo = null;
            int indexFrom = -1;
            int indexTo = -1;

            if (Dead)
            {
                Enqueue(p);
                return;
            }

            for (int i = 0; i < array.Length; i++)
            {
                if (array[i] == null || array[i].UniqueID != fromID) continue;
                indexFrom = i;
                tempFrom = array[i];
                break;
            }

            if (tempFrom == null || indexFrom == -1)
            {
                Enqueue(p);
                return;
            }

            for (int i = 0; i < array.Length; i++)
            {
                if (array[i] == null || array[i].UniqueID != toID) continue;
                indexTo = i;
                tempTo = array[i];
                break;
            }

            if (tempTo == null || indexTo == -1)
            {
                Enqueue(p);
                return;
            }

            if ((byte)tempTo.Info.Type < 1 || (byte)tempTo.Info.Type > 11)
            {
                Enqueue(p);
                return;
            }

            bool canRepair = false, canUpgrade = false;

            if (tempFrom.Info.Type != ItemType.Gem)
            {
                Enqueue(p);
                return;
            }

            switch (tempFrom.Info.Shape)
            {
                case 1: //BoneHammer
                case 2: //SewingSupplies
                case 5: //SpecialHammer
                case 6: //SpecialSewingSupplies

                    if (tempTo.Info.Bind.HasFlag(BindMode.DontRepair))
                    {
                        Enqueue(p);
                        return;
                    }

                    switch (tempTo.Info.Type)
                    {
                        case ItemType.Weapon:
                        case ItemType.Necklace:
                        case ItemType.Ring:
                        case ItemType.Bracelet:
                            if (tempFrom.Info.Shape == 1 || tempFrom.Info.Shape == 5)
                                canRepair = true;
                            break;
                        case ItemType.Armour:
                        case ItemType.Helmet:
                        case ItemType.Boots:
                        case ItemType.Belt:
                            if (tempFrom.Info.Shape == 2 || tempFrom.Info.Shape == 6)
                                canRepair = true;
                            break;
                        default:
                            canRepair = false;
                            break;
                    }

                    if (canRepair != true)
                    {
                        Enqueue(p);
                        return;
                    }

                    if (tempTo.CurrentDura == tempTo.MaxDura)
                    {
                        ReceiveChat("Item does not need to be repaired.", ChatType.Hint);
                        Enqueue(p);
                        return;
                    }
                    break;
                case 3: //gems
                case 4: //orbs
                    if (tempTo.Info.Bind.HasFlag(BindMode.DontUpgrade) || tempTo.Info.Unique != SpecialItemMode.None)
                    {
                        Enqueue(p);
                        return;
                    }

                    if ((tempTo.GemCount >= tempFrom.Info.CriticalDamage) || (GetCurrentStatCount(tempFrom, tempTo) >= tempFrom.Info.HpDrainRate))
                    {
                        ReceiveChat("Item has already reached maximum added stats", ChatType.Hint);
                        Enqueue(p);
                        return;
                    }

                    int successchance = tempFrom.Info.Reflect;

                    // Gem is only affected by the stat applied.
                    // Drop rate per gem won't work if gems add more than 1 stat, i.e. DC + 2 per gem.
                    if (Settings.GemStatIndependent)
                    {
                        StatType GemType = GetGemType(tempFrom);

                        switch (GemType)
                        {
                            case StatType.AC:
                                successchance *= (int)tempTo.AC;
                                break;

                            case StatType.MAC:
                                successchance *= (int)tempTo.MAC;
                                break;

                            case StatType.DC:
                                successchance *= (int)tempTo.DC;
                                break;

                            case StatType.MC:
                                successchance *= (int)tempTo.MC;
                                break;

                            case StatType.SC:
                                successchance *= (int)tempTo.SC;
                                break;

                            case StatType.ASpeed:
                                successchance *= (int)tempTo.AttackSpeed;
                                break;

                            case StatType.Accuracy:
                                successchance *= (int)tempTo.Accuracy;
                                break;

                            case StatType.Agility:
                                successchance *= (int)tempTo.Agility;
                                break;

                            case StatType.Freezing:
                                successchance *= (int)tempTo.Freezing;
                                break;

                            case StatType.PoisonAttack:
                                successchance *= (int)tempTo.PoisonAttack;
                                break;

                            case StatType.MagicResist:
                                successchance *= (int)tempTo.MagicResist;
                                break;

                            case StatType.PoisonResist:
                                successchance *= (int)tempTo.PoisonResist;
                                break;

                            // These attributes may not work as more than 1 stat is
                            // added per gem, i.e + 40 HP.

                            case StatType.HP:
                                successchance *= (int)tempTo.HP;
                                break;

                            case StatType.MP:
                                successchance *= (int)tempTo.MP;
                                break;

                            case StatType.HP_Regen:
                                successchance *= (int)tempTo.HealthRecovery;
                                break;
                                
                            // I don't know if this conflicts with benes.
                            case StatType.Luck:
                                successchance *= (int)tempTo.Luck;
                                break;

                            case StatType.Strong:
                                successchance *= (int)tempTo.Strong;
                                break;

                            case StatType.PoisonRegen:
                                successchance *= (int)tempTo.PoisonRecovery;
                                break;


                            /*
                                 Currently not supported.
                                 Missing item definitions.

                                 case StatType.HP_Precent:
                                 case StatType.MP_Precent:
                                 case StatType.MP_Regen:
                                 case StatType.Holy:
                                 case StatType.Durability:


                            */
                            default:
                                successchance *= (int)tempTo.GemCount;
                                break;

                        }
                    }
                    // Gem is affected by the total added stats on the item.
                    else
                    {
                        successchance *= (int)tempTo.GemCount;
                    }

                    successchance = successchance >= tempFrom.Info.CriticalRate ? 0 : (tempFrom.Info.CriticalRate - successchance) + (GemRate * 5);

                    //check if combine will succeed
                    bool succeeded = Envir.Random.Next(100) < successchance;
                    canUpgrade = true;

                    byte itemType = (byte)tempTo.Info.Type;

                    if (!ValidGemForItem(tempFrom, itemType))
                    {
                        ReceiveChat("Invalid combination", ChatType.Hint);
                        Enqueue(p);
                        return;
                    }

                    if ((tempFrom.Info.MaxDC + tempFrom.DC) > 0)
                    {
                        if (succeeded) tempTo.DC = (byte)Math.Min(byte.MaxValue, tempTo.DC + tempFrom.Info.MaxDC + tempFrom.DC);
                    }

                    else if ((tempFrom.Info.MaxMC + tempFrom.MC) > 0)
                    {
                        if (succeeded) tempTo.MC = (byte)Math.Min(byte.MaxValue, tempTo.MC + tempFrom.Info.MaxMC + tempFrom.MC);
                    }

                    else if ((tempFrom.Info.MaxSC + tempFrom.SC) > 0)
                    {
                        if (succeeded) tempTo.SC = (byte)Math.Min(byte.MaxValue, tempTo.SC + tempFrom.Info.MaxSC + tempFrom.SC);
                    }

                    else if ((tempFrom.Info.MaxAC + tempFrom.AC) > 0)
                    {
                        if (succeeded) tempTo.AC = (byte)Math.Min(byte.MaxValue, tempTo.AC + tempFrom.Info.MaxAC + tempFrom.AC);
                    }

                    else if ((tempFrom.Info.MaxMAC + tempFrom.MAC) > 0)
                    {
                        if (succeeded) tempTo.MAC = (byte)Math.Min(byte.MaxValue, tempTo.MAC + tempFrom.Info.MaxMAC + tempFrom.MAC);
                    }

                    else if ((tempFrom.Info.Durability) > 0)
                    {
                        if (succeeded) tempTo.MaxDura = (ushort)Math.Min(ushort.MaxValue, tempTo.MaxDura + tempFrom.MaxDura);
                    }

                    else if ((tempFrom.Info.AttackSpeed + tempFrom.AttackSpeed) > 0)
                    {
                        if (succeeded) tempTo.AttackSpeed = (sbyte)Math.Max(sbyte.MinValue, (Math.Min(sbyte.MaxValue, tempTo.AttackSpeed + tempFrom.Info.AttackSpeed + tempFrom.AttackSpeed)));
                    }

                    else if ((tempFrom.Info.Agility + tempFrom.Agility) > 0)
                    {
                        if (succeeded) tempTo.Agility = (byte)Math.Min(byte.MaxValue, tempFrom.Info.Agility + tempTo.Agility + tempFrom.Agility);
                    }

                    else if ((tempFrom.Info.Accuracy + tempFrom.Accuracy) > 0)
                    {
                        if (succeeded) tempTo.Accuracy = (byte)Math.Min(byte.MaxValue, tempFrom.Info.Accuracy + tempTo.Accuracy + tempFrom.Accuracy);
                    }

                    else if ((tempFrom.Info.PoisonAttack + tempFrom.PoisonAttack) > 0)
                    {
                        if (succeeded) tempTo.PoisonAttack = (byte)Math.Min(byte.MaxValue, tempFrom.Info.PoisonAttack + tempTo.PoisonAttack + tempFrom.PoisonAttack);
                    }

                    else if ((tempFrom.Info.Freezing + tempFrom.Freezing) > 0)
                    {
                        if (succeeded) tempTo.Freezing = (byte)Math.Min(byte.MaxValue, tempFrom.Info.Freezing + tempTo.Freezing + tempFrom.Freezing);
                    }

                    else if ((tempFrom.Info.MagicResist + tempFrom.MagicResist) > 0)
                    {
                        if (succeeded) tempTo.MagicResist = (byte)Math.Min(byte.MaxValue, tempFrom.Info.MagicResist + tempTo.MagicResist + tempFrom.MagicResist);
                    }

                    else if ((tempFrom.Info.PoisonResist + tempFrom.PoisonResist) > 0)
                    {
                        if (succeeded) tempTo.PoisonResist = (byte)Math.Min(byte.MaxValue, tempFrom.Info.PoisonResist + tempTo.PoisonResist + tempFrom.PoisonResist);
                    }
                    else if ((tempFrom.Info.Luck + tempFrom.Luck) > 0)
                    {
                        if (succeeded) tempTo.Luck = (sbyte)Math.Min(sbyte.MaxValue, tempFrom.Info.Luck + tempTo.Luck + tempFrom.Luck);
                    }
                    else
                    {
                        ReceiveChat("Cannot combine these items.", ChatType.Hint);
                        Enqueue(p);
                        return;
                    }

                    if (!succeeded)
                    {

                        if ((tempFrom.Info.Shape == 3) && (Envir.Random.Next(15) < 3))
                        {
                            //item destroyed
                            ReceiveChat("Item has been destroyed.", ChatType.Hint);
                            Report.ItemChanged("CombineItem (Item Destroyed)", Info.Inventory[indexTo], 1, 1);

                            Info.Inventory[indexTo] = null;
                            p.Destroy = true;
                        }
                        else
                        {
                            //upgrade has no effect
                            ReceiveChat("Upgrade has no effect.", ChatType.Hint);
                        }

                        canUpgrade = false;
                    }
                    break;
                default:
                    Enqueue(p);
                    return;
            }



            RefreshBagWeight();

            if (canRepair && Info.Inventory[indexTo] != null)
            {
                switch (tempTo.Info.Shape)
                {
                    case 1:
                    case 2:
                        {
                            tempTo.MaxDura = (ushort)Math.Max(0, Math.Min(tempTo.MaxDura, tempTo.MaxDura - 100 * Envir.Random.Next(10)));
                        }
                        break;
                    default:
                        break;
                }
                tempTo.CurrentDura = tempTo.MaxDura;
                tempTo.DuraChanged = false;

                ReceiveChat("Item has been repaired.", ChatType.Hint);
                Enqueue(new S.ItemRepaired { UniqueID = tempTo.UniqueID, MaxDura = tempTo.MaxDura, CurrentDura = tempTo.CurrentDura });
            }

            if (canUpgrade && Info.Inventory[indexTo] != null)
            {
                tempTo.GemCount++;
                ReceiveChat("Item has been upgraded.", ChatType.Hint);
                Enqueue(new S.ItemUpgraded { Item = tempTo });
            }

            if (tempFrom.Count > 1) tempFrom.Count--;
            else Info.Inventory[indexFrom] = null;

            Report.ItemCombined("CombineItem", tempFrom, tempTo, indexFrom, indexTo, MirGridType.Inventory);

            //item merged ok
            p.Success = true;
            Enqueue(p);
        }
コード例 #3
0
ファイル: PlayerObject.cs プロジェクト: ufaith/cmir2
        public void CombineItem(ulong fromID, ulong toID)
        {
            S.CombineItem p = new S.CombineItem { IDFrom = fromID, IDTo = toID, Success = false };

            UserItem[] array = Info.Inventory;
            UserItem tempFrom = null;
            UserItem tempTo = null;
            int indexFrom = -1;
            int indexTo = -1;

            if (Dead)
            {
                Enqueue(p);
                return;
            }

            for (int i = 0; i < array.Length; i++)
            {
                if (array[i] == null || array[i].UniqueID != fromID) continue;
                indexFrom = i;
                tempFrom = array[i];
                break;
            }

            if (tempFrom == null || indexFrom == -1)
            {
                Enqueue(p);
                return;
            }

            for (int i = 0; i < array.Length; i++)
            {
                if (array[i] == null || array[i].UniqueID != toID) continue;
                indexTo = i;
                tempTo = array[i];
                break;
            }

            if (tempTo == null || indexTo == -1)
            {
                Enqueue(p);
                return;
            }

            if((byte)tempTo.Info.Type < 1 || (byte)tempTo.Info.Type > 11)
            {
                Enqueue(p);
                return;
            }

            bool canRepair = false, canUpgrade = false;

            if (tempFrom.Info.Type != ItemType.Gem)
            {
                Enqueue(p);
                return;
            }

            switch (tempFrom.Info.Shape)
            {
                case 1: //repair weapons
                    if (tempTo.Info.Bind.HasFlag(BindMode.DontRepair))
                    {
                        Enqueue(p);
                        return;
                    }

                    switch (tempTo.Info.Type)
                    {
                        case ItemType.Weapon:
                            canRepair = true;
                            break;
                    }
                    break;
                case 2: //repair armour + accessories
                    if (tempTo.Info.Bind.HasFlag(BindMode.DontRepair))
                    {
                        Enqueue(p);
                        return;
                    }

                    if (tempTo.CurrentDura == tempTo.MaxDura)
                    {
                        ReceiveChat("Item does not need to be repaired.", ChatType.Hint);
                        Enqueue(p);
                        return;
                    }

                    switch (tempTo.Info.Type)
                    {
                        case ItemType.Armour:
                        case ItemType.Helmet:
                        case ItemType.Ring:
                        case ItemType.Bracelet:
                        case ItemType.Boots:
                        case ItemType.Belt:
                            canRepair = true;
                            break;
                    }
                    break;
                case 3: //gems
                case 4: //orbs

                    if (tempTo.Info.Bind.HasFlag(BindMode.DontUpgrade) || tempTo.Info.Unique != SpecialItemMode.None)
                    {
                        Enqueue(p);
                        return;
                    }

                    if (tempTo.GemCount >= 7)
                    {
                        ReceiveChat("Item has already reached maximum added stats", ChatType.Hint);
                        Enqueue(p);
                        return;
                    }

                    //check if combine will succeed
                    bool succeeded = Envir.Random.Next(10) < (5 + (Luck / 2));
                    canUpgrade = true;

                    byte itemType = (byte)tempTo.Info.Type;

                    if ((tempFrom.Info.MaxDC + tempFrom.DC) > 0 && (itemType != 2 && itemType != 9 && itemType != 4 && itemType != 10))
                    {
                        if (succeeded) tempTo.DC = (byte)Math.Min(byte.MaxValue, tempTo.DC + tempFrom.Info.MaxDC + tempFrom.DC);
                    }

                    else if ((tempFrom.Info.MaxMC + tempFrom.MC) > 0 && (itemType != 2 && itemType != 9 && itemType != 4 && itemType != 10))
                    {
                        if (succeeded) tempTo.MC = (byte)Math.Min(byte.MaxValue, tempTo.MC + tempFrom.Info.MaxMC + tempFrom.MC);
                    }

                    else if ((tempFrom.Info.MaxSC + tempFrom.SC) > 0 && (itemType != 2 && itemType != 9 && itemType != 4 && itemType != 10))
                    {
                        if (succeeded) tempTo.SC = (byte)Math.Min(byte.MaxValue, tempTo.SC + tempFrom.Info.MaxSC + tempFrom.SC);
                    }

                    else if ((tempFrom.Info.MaxAC + tempFrom.AC) > 0 && (itemType != 5 && itemType != 1))
                    {
                        if (succeeded) tempTo.AC = (byte)Math.Min(byte.MaxValue, tempTo.AC + tempFrom.Info.MaxAC + tempFrom.AC);
                    }

                    else if ((tempFrom.Info.MaxMAC + tempFrom.MAC) > 0 && (itemType != 5 && itemType != 1))
                    {
                        if (succeeded) tempTo.MAC = (byte)Math.Min(byte.MaxValue, tempTo.MAC + tempFrom.Info.MaxMAC + tempFrom.MAC);
                    }

                    else if ((tempFrom.Info.Durability) > 0)
                    {
                        if (succeeded) tempTo.MaxDura = (ushort)Math.Min(ushort.MaxValue, tempTo.MaxDura + tempFrom.MaxDura);
                    }

                    else if ((tempFrom.Info.AttackSpeed + tempFrom.AttackSpeed) > 0 && (itemType == 5 || itemType == 7 || itemType == 1))
                    {
                        if (succeeded) tempTo.AttackSpeed = (sbyte)Math.Max(sbyte.MinValue, (Math.Min(sbyte.MaxValue, tempTo.AttackSpeed + tempFrom.Info.AttackSpeed + tempFrom.AttackSpeed)));
                    }

                    else if ((tempFrom.Info.Agility + tempFrom.Agility) > 0 && (itemType != 4 && itemType != 5 && itemType != 7 && itemType != 1))
                    {
                        if (succeeded) tempTo.Agility = (byte)Math.Min(byte.MaxValue, tempFrom.Info.Agility + tempTo.Agility + tempFrom.Agility);
                    }

                    else if ((tempFrom.Info.Accuracy + tempFrom.Accuracy) > 0 && (itemType != 2 && itemType != 7 && itemType != 10 && itemType != 1))
                    {
                        if (succeeded) tempTo.Accuracy = (byte)Math.Min(byte.MaxValue, tempFrom.Info.Accuracy + tempTo.Accuracy + tempFrom.Accuracy);
                    }

                    else if ((tempFrom.Info.PoisonAttack + tempFrom.PoisonAttack) > 0 && (itemType == 5 || itemType == 7 || itemType == 1))
                    {
                        if (succeeded) tempTo.PoisonAttack = (byte)Math.Min(byte.MaxValue, tempFrom.Info.PoisonAttack + tempTo.PoisonAttack + tempFrom.PoisonAttack);
                    }

                    else if ((tempFrom.Info.Freezing + tempFrom.Freezing) > 0 && (itemType == 5 || itemType == 7 || itemType == 1))
                    {
                        if (succeeded) tempTo.Freezing = (byte)Math.Min(byte.MaxValue, tempFrom.Info.Freezing + tempTo.Freezing + tempFrom.Freezing);
                    }

                    else if ((tempFrom.Info.MagicResist + tempFrom.MagicResist) > 0 && (itemType == 2 || itemType == 4 || itemType == 5))
                    {
                        if (succeeded) tempTo.MagicResist = (byte)Math.Min(byte.MaxValue, tempFrom.Info.MagicResist + tempTo.MagicResist + tempFrom.MagicResist);
                    }

                    else if ((tempFrom.Info.PoisonResist + tempFrom.PoisonResist) > 0 && (itemType == 2 || itemType == 9 || itemType == 4))
                    {
                        if (succeeded) tempTo.PoisonResist = (byte)Math.Min(byte.MaxValue, tempFrom.Info.PoisonResist + tempTo.PoisonResist + tempFrom.PoisonResist);
                    }
                    else
                    {
                        ReceiveChat("Cannot combine these items.", ChatType.Hint);
                        Enqueue(p);
                        return;
                    }

                    if (!succeeded)
                    {
                        //upgrade has no effect
                        ReceiveChat("Upgrade has no effect.", ChatType.Hint);

                        if ((tempFrom.Info.Shape == 3) && (Envir.Random.Next(15) < 3))
                        {
                            //item destroyed
                            ReceiveChat("Item has been destroyed.", ChatType.Hint);

                            Info.Inventory[indexTo] = null;
                            p.Destroy = true;
                        }

                        canUpgrade = false;
                    }
                    break;
                default:
                    Enqueue(p);
                    return;
            }

            RefreshBagWeight();

            if (canRepair && Info.Inventory[indexTo] != null)
            {
                tempTo.CurrentDura = (ushort)Math.Min(tempTo.MaxDura, tempTo.CurrentDura + tempFrom.CurrentDura);
                tempTo.DuraChanged = false;

                ReceiveChat("Item has been repaired.", ChatType.Hint);
                Enqueue(new S.ItemRepaired { UniqueID = tempTo.UniqueID, MaxDura = tempTo.MaxDura, CurrentDura = tempTo.CurrentDura });
            }

            if (canUpgrade && Info.Inventory[indexTo] != null)
            {
                tempTo.GemCount++;
                ReceiveChat("Item has been upgraded.", ChatType.Hint);
                Enqueue(new S.ItemUpgraded { Item = tempTo });
            }

            if (tempFrom.Count > 1) tempFrom.Count--;
            else Info.Inventory[indexFrom] = null;

            //item merged ok
            p.Success = true;
            Enqueue(p);
        }