コード例 #1
0
        public void UseLotteryItem(short nPOS, int nItemID)
        {
            if (Parent.Stats.nHP <= 0)
            {
                return;
            }

            var pItemRaw = InventoryManipulator.GetItem(Parent, ItemConstants.GetInventoryType(nItemID), nPOS);             // TODO determine if we can hardcode the inventory type

            var itemResult = MasterManager.CreateItem(RandomBoxes.GetRandom(nItemID));

            if (itemResult != null && pItemRaw is GW_ItemSlotBundle pItem)
            {
                if (InventoryManipulator.CountFreeSlots(Parent, InventoryType.Equip) > 0 && InventoryManipulator.CountFreeSlots(Parent, InventoryType.Consume) > 0)
                {
                    InventoryManipulator.RemoveFrom(Parent, pItemRaw.InvType, nPOS);
                    InventoryManipulator.InsertInto(Parent, itemResult);
                }
                else
                {
                    Parent.SendMessage("Please make some room in your inventory.");
                }
            }
            else
            {
                Parent.SendMessage("This item has not been implemented yet. If you believe this to be an error, please report it on the discord server.");
            }
        }
コード例 #2
0
        public bool ActivateSinglePet(short nPos, bool bForce = false)
        {
            if (Pets[0] != null && !bForce)
            {
                DeactivateSinglePet();

                return(true);
            }

            if (Parent.Field.Template.HasNoPetLimit())
            {
                Parent.SendMessage("Pets are not allowed in this map");
                return(false);
            }

            var pItemRaw = InventoryManipulator.GetItem(Parent, InventoryType.Cash, nPos);

            if (pItemRaw is GW_ItemSlotPet pet)
            {
                if (pet.PetTemplate.EvolNo > 0)
                {
                    Parent.SendMessage("Evolving have not been coded yet, sorry :(");
                    return(false);
                }

                ActivatePet(pet, nPos, 0);

                return(true);
            }

            return(false);
        }
コード例 #3
0
ファイル: CShop.cs プロジェクト: yeethawe/Rebirth95.Server
        private static void SellItem(Character pChar, short nSlot, int nItemId, short nCount)
        {
            var pItem = InventoryManipulator.GetItem(pChar, ItemConstants.GetInventoryType(nItemId), nSlot);

            if (pItem is null)
            {
                pChar.SendMessage("Trying to sell null item.");
                pChar.SendPacket(CPacket.CShopDlg.ShopResult(ShopRes.SellIncorrectRequest));
                return;
            }

            if (pItem.CashItem || pItem.NotSale)
            {
                pChar.SendMessage("Cannot trade cash items.");
                return;
            }

            var nCostPerItem = pItem.Template.Price;

            nCount = ItemConstants.is_treat_singly(nItemId) ? (short)1 : nCount;

            var nFinalCost = nCostPerItem * nCount;

            if (pItem.IsRechargeable)
            {
                var dUnitPrice = ((ConsumeItemTemplate)pItem.Template).UnitPrice;

                nFinalCost += (int)Math.Floor(dUnitPrice * pItem.nNumber);
            }

            if (pItem is GW_ItemSlotBundle && !pItem.IsRechargeable)
            {
                if (pItem.nNumber < nCount)
                {
                    pChar.SendMessage("Trying to sell more than you possess.");
                    pChar.SendPacket(CPacket.CShopDlg.ShopResult(ShopRes.SellIncorrectRequest));
                    return;
                }

                if (nCount <= 0)
                {
                    pChar.SendMessage("Trying to sell negative amount.");
                    pChar.SendPacket(CPacket.CShopDlg.ShopResult(ShopRes.SellIncorrectRequest));
                    return;
                }
            }
            else
            {
                nCount = -1;
            }

            pChar.SendPacket(CPacket.CShopDlg.ShopResult(ShopRes.SellSuccess));

            //pChar.SendMessage("final price: " + nFinalCost);

            InventoryManipulator.RemoveFrom(pChar, pItem.InvType, nSlot, nCount);
            pChar.Modify.GainMeso(nFinalCost, false);
        }
コード例 #4
0
ファイル: CShop.cs プロジェクト: yeethawe/Rebirth95.Server
        private static void RechargeItem(Character pChar, short nSlot)
        {
            var pItem = InventoryManipulator.GetItem(pChar, InventoryType.Consume, nSlot);

            if (pItem is null)
            {
                pChar.SendMessage("Trying to recharge null item.");
                pChar.SendPacket(CPacket.CShopDlg.ShopResult(ShopRes.RechargeIncorrectRequest));
                return;
            }

            if (!ItemConstants.IsRechargeableItem(pItem.nItemID))
            {
                pChar.SendMessage("Trying to recharge item that isn't rechargeable.");
                pChar.SendPacket(CPacket.CShopDlg.ShopResult(ShopRes.RechargeIncorrectRequest));
                return;
            }

            var slotmax = pItem.SlotMax;

            if (pChar.Skills.Get(false,
                                 (int)Skills.NIGHTWALKER_JAVELIN_MASTERY,
                                 (int)Skills.ASSASSIN_JAVELIN_MASTERY) is SkillEntry se)
            {
                slotmax += (short)se.Y_Effect;
            }

            if (pItem.nNumber >= slotmax)
            {
                pChar.SendMessage("Trying to recharge item that is fully charged.");
                pChar.SendPacket(CPacket.CShopDlg.ShopResult(ShopRes.RechargeIncorrectRequest));
                return;
            }

            var dUnitPrice = (pItem.Template as ConsumeItemTemplate).UnitPrice;

            var nRechargeNeeded     = slotmax - pItem.nNumber;
            var nTotalRechargePrice = (int)Math.Floor(nRechargeNeeded * dUnitPrice);

            if (pChar.Stats.nMoney < nTotalRechargePrice)
            {
                pChar.SendPacket(CPacket.CShopDlg.ShopResult(ShopRes.RechargeNoMoney));
                return;
            }

            pChar.Modify.GainMeso(-nTotalRechargePrice);

            pItem.nNumber = slotmax;

            pChar.Modify.Inventory(ctx =>
            {
                ctx.UpdateQuantity(InventoryType.Consume, nSlot, pItem.nNumber);
            });

            pChar.SendPacket(CPacket.CShopDlg.ShopResult(ShopRes.RechargeSuccess));
        }
コード例 #5
0
        private static void HandleDisassembleOp(Character pChar, InventoryType nInvType, int nItemID, int nSlotPos)
        {
            var pItem = InventoryManipulator.GetItem(pChar, nInvType, (short)nSlotPos);

            if (pItem is GW_ItemSlotEquip pItemEquip)
            {
                var nCost = pItemEquip.Template.Price * 0.1363;
            }
            else
            {
            }
        }
コード例 #6
0
        public void EncodeEquippedRings(COutPacket p)
        {
            #region COUPLE_RING

            p.Encode1(0);             // TODO

            #endregion

            #region FRIENDSHIP_RING

            GW_FriendRecord pFriendshipRing   = null;
            var             nFriendshipRingID = 0;
            long            nFriendShipSN     = 0;

            for (var bp = BodyPart.BP_RING1; bp < BodyPart.BP_RING4; bp++)
            {
                var item = InventoryManipulator.GetItem(Parent, bp, true);

                if (item is null)
                {
                    continue;
                }

                if (ItemConstants.is_friendship_equip_item(item.nItemID))
                {
                    pFriendshipRing = lFriendRecord.FirstOrDefault(ring => ring.liSN == item.liSN);
                    break;
                }
            }

            p.Encode1(pFriendshipRing != null);

            if (pFriendshipRing != null)
            {
                p.Encode8(pFriendshipRing.liSN);
                p.Encode8(pFriendshipRing.liPairSN);
                p.Encode4(pFriendshipRing.dwFriendItemID);
            }

            #endregion

            #region MARRIAGE_RING

            p.Encode1(0);             // TODO

            #endregion
        }
コード例 #7
0
        public void HandleAddItem(CInPacket p, Character pChar)
        {
            if (dwFirstLockerId == pChar.dwId || !acceptedInvite)
            {
                return;
            }

            var nTI         = (InventoryType)p.Decode1();
            var nCurInvSlot = p.Decode2(); // in inventory
            var nCount      = p.Decode2();
            var nTargetSlot = p.Decode1(); // in trade window

            var pItem = InventoryManipulator.GetItem(pChar, nTI, nCurInvSlot);

            var tempInv = GetTempInv(pChar);

            if (pItem is null || !tempInv.CanAddToSlot(nTargetSlot))
            {
                return;
            }

            if (ItemConstants.is_treat_singly(pItem.nItemID))
            {
                nCount = -1; // negative amount clears the slot
            }
            else
            {
                nCount = Math.Min(pItem.nNumber, Math.Abs(nCount));
            }

            InventoryManipulator.RemoveFrom(pChar, nTI, nCurInvSlot, nCount);

            if (pItem is GW_ItemSlotBundle pBundle && !pBundle.IsRechargeable)
            {
                pItem         = pItem.DeepCopy();
                pItem.nNumber = nCount;
            }

            var pTempItem = new TempItem(pItem, nCurInvSlot, nTargetSlot);

            tempInv.Add(pTempItem);

            Parent.SendPacket(AddItemPacket(pTempItem, !IsOwner(pChar)));
            Partner.SendPacket(AddItemPacket(pTempItem, IsOwner(pChar)));
        }
コード例 #8
0
        // use this when we implement mulit-pet
        public bool ActivatePet(short nPos, bool bLeader)
        {
            throw new InvalidOperationException("Multipet not active");
            var pItemRaw = InventoryManipulator.GetItem(Parent, InventoryType.Cash, nPos);

            if (pItemRaw is GW_ItemSlotPet cPetItem)
            {
                if (cPetItem.PetTemplate.EvolNo > 0)
                {
                    Parent.SendMessage("Evolving pets are not currently handled. Please try again later.");
                    return(false);
                }

                if (DeactivatePet(cPetItem.liCashItemSN))
                {
                    return(true);
                }

                byte nIdx = 0xFF;

                for (byte i = 0; i < 3; i++)
                {
                    if (Pets[i] == null)
                    {
                        nIdx = i;
                        break;
                    }
                }

                if (nIdx == 0xFF)
                {
                    return(false);
                }

                ActivatePet(cPetItem, nPos, nIdx);
                Parent.Modify.UpdatePetLocker();

                return(true);
            }

            return(false);
        }
コード例 #9
0
        public void EncodeMultiPetInfo(COutPacket p)         // this is just used for the CharacterInfo packet
        {
            for (byte i = 0; i < 3; i++)
            {
                if (Pets[i] != null)
                {
                    p.Encode1(1);

                    var cp = Pets[i];
                    p.Encode4(cp.dwTemplateID);
                    p.EncodeString(cp.sName);
                    p.Encode1(cp.Level);
                    p.Encode2(cp.Tameness);
                    p.Encode1(cp.Repleteness);                                                            //i think
                    p.Encode2(cp.Skill);
                    p.Encode4(InventoryManipulator.GetItem(Parent, petwearparts[i], true)?.nItemID ?? 0); // TODO verify
                }
            }

            p.Encode1(0);
        }
コード例 #10
0
        /// <summary>
        /// Teleport scroll handling.
        /// </summary>
        /// <param name="nPOS"></param>
        /// <param name="nItemID"></param>
        public void UsePortalScroll(int nItemID, short nPOS)
        {
            if (Parent.Stats.nHP <= 0)
            {
                return;
            }

            if (Parent.Field.Template.HasPortalScrollLimit())
            {
                return;
            }

            if (InventoryManipulator.GetItem(Parent, InventoryType.Consume, nPOS)?.Template is ConsumeItemTemplate template)
            {
                if (template.MoveTo > 0)
                {
                    Parent.Action.SetField(template.MoveTo == 999999999 ? Parent.Field.ReturnMapId : template.MoveTo);
                }
            }

            InventoryManipulator.RemoveFrom(Parent, InventoryType.Consume, nPOS);
        }
コード例 #11
0
        public void AddItem(CInPacket p)
        {
            var nTI             = (InventoryType)p.Decode1();
            var nPOS            = p.Decode2();
            var nBundles        = Math.Max((short)1, p.Decode2());
            var nPricePerBundle = Math.Max((short)1, p.Decode2());
            var nPrice          = Math.Max(1, p.Decode4());

            var pItem = InventoryManipulator.GetItem(Parent, nTI, nPOS);

            if (pItem is null)
            {
                Parent.SendMessage("item is null u fucc");
                return;
            }

            var nQuantityRequested = -1; // negative so its removed completely from inventory

            if (!ItemConstants.is_treat_singly(pItem.nItemID))
            {
                nQuantityRequested = nBundles * nPricePerBundle;

                if (pItem.nNumber < nQuantityRequested)
                {
                    return; // f*****g retard
                }
            }

            InventoryManipulator.RemoveFrom(Parent, nTI, nPOS, (short)nQuantityRequested);
            Inventory.Add(new TempItem(pItem, nPrice, nPricePerBundle, nBundles));

            Refresh(Parent);

            Parent.SendMessage($"Bundles: {nBundles}, PricePerBundle: {nPricePerBundle}, Price: {nPrice}");

            // TODO packet editing checks
        }
コード例 #12
0
        public void PickUp(Character pChar, int dwDropId, short pX, short pY, bool bByPet = false)
        {
            var pDrop = this[dwDropId];

            if (pDrop is null)
            {
                return;
            }

            switch (pDrop.DropOwnType)
            {
            case DropOwnType.PartyOwn when pChar.Party?.PartyID != pDrop.DropOwnerID:
            case DropOwnType.UserOwn when pChar.dwId != pDrop.DropOwnerID:
                pChar.SendMessage("Trying to pick up a drop that doesn't belong to you.");
                return;
            }

            if (pDrop.Item != null)
            {
                if (InventoryManipulator.CountFreeSlots(pChar, ItemConstants.GetInventoryType(pDrop.Item.nItemID)) <= 0)
                {
                    return;
                }
            }

            if (bByPet)
            {
                if (Constants.MULTIPET_ACTIVATED)
                {
                    throw new NotImplementedException();                     // since we arent checking multiple pet equip slots
                }

                if (pDrop.bIsMoney == 1)
                {
                    if (InventoryManipulator.GetItem(pChar, BodyPart.BP_PETABIL_MESO, true) is null)
                    {
                        return;
                    }
                }
                else
                {
                    if (InventoryManipulator.GetItem(pChar, BodyPart.BP_PETABIL_ITEM, true) is null)
                    {
                        return;
                    }
                }

                pDrop.nLeaveType = DropLeaveType.PetPickup;
            }
            else
            {
                pDrop.nLeaveType = DropLeaveType.UserPickup;
            }

            pDrop.OwnerCharId = pChar.dwId;

            if (pDrop.bIsMoney > 0)
            {
                pChar.Modify.GainMeso(pDrop.nMesoVal);
            }
            else
            {
                if (pDrop.Item.Template is CashItemTemplate itemDataTemplate)
                {
                    if (itemDataTemplate.Max > 0 &&
                        InventoryManipulator.ContainsItem(pChar, pDrop.ItemId, (short)itemDataTemplate.Max))
                    {
                        pChar.SendMessage("Can't hold anymore of this item..");
                        return;
                    }
                }

                if (!Field.TryDropPickup(pChar, pDrop))
                {
                    return;
                }

                pChar.SendPacket(CPacket.DropPickUpMessage_Item(pDrop.ItemId, pDrop.Item.nNumber, false));

                if (pDrop.Item.Template.PickupMessage.Length > 0)
                {
                    pChar.SendMessage(pDrop.Item.Template.PickupMessage);
                }
            }

            Remove(dwDropId);
        }
コード例 #13
0
        public static void Handle_UserSkillLearnItemUseRequest(WvsGameClient c, CInPacket p)
        {
            int   dwTickCount = p.Decode4();
            short nPOS        = p.Decode2();
            int   nItemID     = p.Decode4();

            c.Character.Action.Enable();

            if (c.Character.Stats.nHP <= 0)
            {
                return;
            }

            if (InventoryManipulator.GetItem(c.Character, ItemConstants.GetInventoryType(nItemID), nPOS) is GW_ItemSlotBundle item &&
                item.Template is ConsumeItemTemplate template)
            {
                var jobroot = Math.Floor(c.Character.Stats.nJob * 0.01);                 // 3500 -> 35

                var bUsed         = false;
                var bSuccess      = false;
                var bIsMasterBook = item.nItemID / 10000 == 229;

                foreach (var skillId in template.SkillData)
                {
                    var skillJob  = (int)Math.Floor(skillId / 10000f); // 35111010 -> 3511
                    var skillRoot = (int)Math.Floor(skillJob / 100f);  // 3511 -> 35

                    if (skillRoot == jobroot)                          // this can only be true once
                    {
                        if (skillJob > c.Character.Stats.nJob)
                        {
                            break;
                        }

                        var skill = c.Character.Skills.FirstOrDefault(s => s.nSkillID == skillId);

                        if (bIsMasterBook)
                        {
                            if (skill is null || skill.nSLV < template.ReqSkillLevel || skill.CurMastery >= template.MasterLevel)
                            {
                                return;
                            }
                        }
                        else
                        {
                            if (skill != null && skill.CurMastery > 0)
                            {
                                break;
                            }
                        }

                        bUsed = true;

                        if (template.SuccessRate != 100)
                        {
                            if (Constants.Rand.Next() % 100 > template.SuccessRate)
                            {
                                break;
                            }
                        }

                        c.Character.Modify.Skills(mod => mod.AddEntry(skillId, s => s.CurMastery = (byte)template.MasterLevel));
                        bSuccess = true;
                        break;
                    }
                }

                if (bUsed)
                {
                    InventoryManipulator.RemoveFrom(c.Character, item.InvType, nPOS);                     // always remove
                }

                c.Character.Field.Broadcast(CPacket.SkillLearnItemResult(c.dwCharId, bIsMasterBook, bUsed, bSuccess));
            }
        }
コード例 #14
0
        /**
         * Consumeable item buffs will be routed here.
         * This includes HP/MP items along with temp stat increase items
         */
        public void UsePotion(int nItemID, short nPOS)
        {
            if (Parent.Stats.nHP <= 0)
            {
                return;
            }

            if (InventoryManipulator.GetItem(Parent, InventoryType.Consume, nPOS)?.Template is ConsumeItemTemplate template)
            {
                if (Parent.Field is CField_Battlefield bf)                 // if not remove item anyway cuz they shouldnt have it
                {
                    // TODO effects => Effect/BasicEff/ItemSkill/Success

                    if (template.BFSkill < 0)
                    {
                        if (BattlefieldData.SheepConsumable(nItemID) || BattlefieldData.WolfConsumable(nItemID))
                        {
                            var newBuff = new BuffConsume(nItemID);
                            newBuff.GenerateConsumeable(Parent);
                        }
                    }
                    else
                    {
                        switch (template.BFSkill)                         // we hardcodin' bois
                        {
                        case 0:
                            Parent.SendMessage("You cry at the Wolf, and it slows down as if it's in shock.");
                            bf.Users.ForEach(u =>
                            {
                                if (bf.GetPlayerTeam(u.dwId) == BattlefieldData.BattlefieldTeams.Wolves)
                                {
                                    u.Buffs.OnStatChangeByMobSkill(MasterManager.MobSkillTemplates[126][9], 0, 0);
                                }
                            });
                            break;

                        case 1:
                            Parent.SendMessage("You attack the Wolf. He should be momentarily stunned.");
                            bf.Users.ForEach(u =>
                            {
                                if (bf.GetPlayerTeam(u.dwId) == BattlefieldData.BattlefieldTeams.Wolves)
                                {
                                    u.Buffs.OnStatChangeByMobSkill(MasterManager.MobSkillTemplates[123][14], 0, 0);
                                }
                            });
                            break;

                        case 2:
                            Parent.Field.BroadcastNotice("The Sheep are in a state of confusion.");
                            bf.Users.ForEach(u =>
                            {
                                if (bf.GetPlayerTeam(u.dwId) != BattlefieldData.BattlefieldTeams.Wolves)
                                {
                                    u.Buffs.OnStatChangeByMobSkill(MasterManager.MobSkillTemplates[132][4], 0, 0);
                                }
                            });
                            break;

                        case 3:
                            Parent.Field.BroadcastNotice("The Wolves have slowed down.");
                            bf.Users.ForEach(u =>
                            {
                                if (bf.GetPlayerTeam(u.dwId) == BattlefieldData.BattlefieldTeams.Wolves)
                                {
                                    u.Buffs.OnStatChangeByMobSkill(MasterManager.MobSkillTemplates[126][10], 0, 0);
                                }
                            });
                            break;

                        case 4:
                            Parent.Field.BroadcastNotice("The Sheep are momentarily stunned.");
                            bf.Users.ForEach(u =>
                            {
                                if (bf.GetPlayerTeam(u.dwId) != BattlefieldData.BattlefieldTeams.Wolves)
                                {
                                    u.Buffs.OnStatChangeByMobSkill(MasterManager.MobSkillTemplates[123][15], 0, 0);
                                }
                            });
                            break;

                        case 5:
                            Parent.Field.BroadcastNotice("The Sheep have momentarily weakened.");
                            bf.Users.ForEach(u =>
                            {
                                if (bf.GetPlayerTeam(u.dwId) != BattlefieldData.BattlefieldTeams.Wolves)
                                {
                                    u.Buffs.OnStatChangeByMobSkill(MasterManager.MobSkillTemplates[122][12], 0, 0);
                                }
                            });
                            break;
                        }
                    }
                }
                else
                {
                    if (Parent.Field.Template.HasStatChangeItemLimit())
                    {
                        Parent.SendMessage("Not allowed in this map.");
                        return;
                    }

                    var newBuff = new BuffConsume(nItemID);
                    newBuff.GenerateConsumeable(Parent);
                    // buff gets added in the generator if it has bufftime
                }
            }

            InventoryManipulator.RemoveFrom(Parent, InventoryType.Consume, nPOS);             // remove regardless
        }
コード例 #15
0
        public void UseMagnifyingGlass(short nMagnifyingPOS, short nEquipPOS)
        {
            if (Parent.Stats.nHP <= 0)
            {
                return;
            }

            var pTemplate = InventoryManipulator.GetItem(Parent, InventoryType.Consume, nMagnifyingPOS).Template as ConsumeItemTemplate;
            var pEquip    = InventoryManipulator.GetItem(Parent, InventoryType.Equip, nEquipPOS) as GW_ItemSlotEquip;

            if (pEquip is null || pTemplate is null)
            {
                return;
            }

            if (pEquip.HasVisiblePotential)
            {
                return;
            }
            if (pEquip.nGrade == PotentialGradeCode.Normal)
            {
                return;
            }
            if (pEquip.CashItem)
            {
                return;
            }
            if (!ItemLogic.MagnifyingGlass(pTemplate.TemplateId))
            {
                return;
            }

            if (pEquip.EquipTemplate.ReqLevel > ItemConstants.GlassRevealLevel(pTemplate.TemplateId))
            {
                return;
            }

            if (pEquip.nOption1 == 0)
            {
                pEquip.nGrade = PotentialGradeCode.Visible_Rare;                 // cant get epic on first reveal
            }
            else
            {
                switch (pEquip.nGrade)
                {
                case PotentialGradeCode.Hidden_Rare:
                    if (Constants.Rand.NextDouble() < RateConstants.ItemPotential_EpicOdds)
                    {
                        pEquip.nGrade = PotentialGradeCode.Visible_Epic;
                    }
                    else
                    {
                        pEquip.nGrade = PotentialGradeCode.Visible_Rare;
                    }
                    break;

                case PotentialGradeCode.Hidden_Epic:
                    if (Constants.Rand.NextDouble() < RateConstants.ItemPotential_UniqueOdds)
                    {
                        pEquip.nGrade = PotentialGradeCode.Visible_Unique;
                    }
                    else
                    {
                        pEquip.nGrade = PotentialGradeCode.Visible_Epic;
                    }
                    break;

                case PotentialGradeCode.Hidden_Unique:
                    pEquip.nGrade = PotentialGradeCode.Visible_Unique;
                    break;
                }
            }

            var potentialCollection = MasterManager.ItemOptionTemplates
                                      .GetAll()
                                      .Where(p
                                             => p.ReqLevel <= pEquip.EquipTemplate.ReqLevel && // throw out incorrect level range
                                             ItemConstants.OptionTypeFitsEquipType(pEquip.nItemID, p.OptionType) && // throw out incorrect equip types
                                             ItemConstants.OptionGradeFitsEquipGrade(p.TemplateId, pEquip.nGrade) && // throw out incorrect grade codes
                                             p.OptionType != 90 // these show "Hidden" for some reason o___o
                                             );

            var itemOptionTemplates = potentialCollection as ItemOptionTemplate[] ?? potentialCollection.ToArray();

            if (itemOptionTemplates.Length <= 3)
            {
                throw new IndexOutOfRangeException($"unable to put potential on item. CID: {Parent.dwId} | EPOS: {nEquipPOS} | Grade: {nameof(pEquip.nGrade)} | Level: {pEquip.EquipTemplate.ReqLevel}");
            }

            var lines = new List <int>
            {
                itemOptionTemplates.Random().TemplateId,
                itemOptionTemplates.Random().TemplateId
            };

            lines.Sort();             // so the potential grades are in order

            if (pEquip.nOption3 == 0 || pEquip.nOption1 == 0)
            {
                var odds = pEquip.nOption1 == 0
                                        ? RateConstants.ItemPotential_ThirdLineFirstReveal
                                        : RateConstants.ItemPotential_ThirdLineOdds;

                // lower odds for third line on first reveal
                if (Constants.Rand.NextDouble() < odds)
                {
                    pEquip.nOption3 = (short)lines[0];
                }
            }
            else             // option1 > 0 && option3 != 0
            {
                pEquip.nOption3 = (short)lines[0];
            }

            pEquip.nOption2 = (short)lines[1];

            // recalculate to ensure the first option is always the same grade as the equip
            pEquip.nOption1 = (short)itemOptionTemplates
                              .Where(p => ItemConstants.GradeCodeByID(p.TemplateId) == pEquip.nGrade &&
                                     p.TemplateId >= lines[1]).Random()
                              .TemplateId;

            pEquip.sTitle = $"{pEquip.nOption1}|{pEquip.nOption2}";

            Parent.Modify.Inventory(ctx =>
            {
                ctx.UpdateEquipInformation(pEquip, nEquipPOS);
            });

            InventoryManipulator.RemoveFrom(Parent, InventoryType.Consume, nMagnifyingPOS);

            Parent.SendPacket(pEquip.ShowItemReleaseEffect(Parent.dwId, nEquipPOS));
        }
コード例 #16
0
        public void UseUpgradeScroll(short nScrollPOS, short nEquipPOS, bool bWhiteScroll)
        {
            if (Parent.Stats.nHP <= 0)
            {
                return;
            }

            var pScrollTemplate = InventoryManipulator.GetItem(Parent, InventoryType.Consume, nScrollPOS).Template as ConsumeItemTemplate;
            var pEquip          = InventoryManipulator.GetItem(Parent, InventoryType.Equip, nEquipPOS) as GW_ItemSlotEquip;
            var nWhiteScrollPOS = InventoryManipulator.GetAnyItem(Parent, InventoryType.Consume, ItemConstants.WhiteScroll).Item1;

            if (pEquip == null || pScrollTemplate == null)
            {
                return;
            }
            if (pEquip.CashItem)
            {
                return;
            }
            if (pEquip.RemainingUpgradeCount <= 0 && pScrollTemplate.Recover <= 0)
            {
                return;
            }

            var bSuccess = pScrollTemplate.ScrollSuccess(Constants.Rand);
            var bDestroy = !bSuccess && pScrollTemplate.ScrollDestroy(Constants.Rand);

            bWhiteScroll = bWhiteScroll && nWhiteScrollPOS > 0;

            if (!ItemConstants.is_correct_upgrade_equip(pScrollTemplate.TemplateId, pEquip.nItemID))             // PE, validated client-side
            {
                return;
            }

            if (bSuccess)
            {
                if (pScrollTemplate.Recover > 0)
                {
                    pEquip.RemainingUpgradeCount += (byte)pScrollTemplate.Recover;
                }
                else
                {
                    if (pScrollTemplate.PreventSlip)
                    {
                        pEquip.nAttribute |= ItemAttributeFlags.Spikes;
                    }
                    else if (pScrollTemplate.WarmSupport)
                    {
                        pEquip.nAttribute |= ItemAttributeFlags.Cold;
                    }
                    else if (pScrollTemplate.RandStat)
                    {
                        var randRange = 2 + (2 * pScrollTemplate.IncRandVol);

                        var gX = new GaussianRandom();

                        if (pEquip.niSTR > 0)
                        {
                            pEquip.niSTR = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niSTR, randRange, false));
                        }
                        if (pEquip.niLUK > 0)
                        {
                            pEquip.niLUK = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niLUK, randRange, false));
                        }
                        if (pEquip.niINT > 0)
                        {
                            pEquip.niINT = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niINT, randRange, false));
                        }
                        if (pEquip.niDEX > 0)
                        {
                            pEquip.niDEX = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niDEX, randRange, false));
                        }

                        if (pEquip.niACC > 0)
                        {
                            pEquip.niACC = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niACC, randRange, false));
                        }
                        if (pEquip.niEVA > 0)
                        {
                            pEquip.niEVA = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niEVA, randRange, false));
                        }

                        if (pEquip.niMaxHP > 0)
                        {
                            pEquip.niMaxHP = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niMaxHP, randRange, false));
                        }
                        if (pEquip.niMaxMP > 0)
                        {
                            pEquip.niMaxMP = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niMaxMP, randRange, false));
                        }

                        if (pEquip.niPAD > 0)
                        {
                            pEquip.niPAD = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niPAD, randRange, false));
                        }
                        if (pEquip.niMAD > 0)
                        {
                            pEquip.niMAD = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niMAD, randRange, false));
                        }
                        if (pEquip.niPDD > 0)
                        {
                            pEquip.niPDD = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niPDD, randRange, false));
                        }
                        if (pEquip.niMDD > 0)
                        {
                            pEquip.niMDD = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niMDD, randRange, false));
                        }

                        if (pEquip.niSpeed > 0)
                        {
                            pEquip.niSpeed = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niSpeed, randRange, false));
                        }
                        if (pEquip.niJump > 0)
                        {
                            pEquip.niJump = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niJump, randRange, false));
                        }
                    }
                    else
                    {
                        pEquip.niSTR   += (short)pScrollTemplate.IncSTR;
                        pEquip.niLUK   += (short)pScrollTemplate.IncLUK;
                        pEquip.niINT   += (short)pScrollTemplate.IncINT;
                        pEquip.niDEX   += (short)pScrollTemplate.IncDEX;
                        pEquip.niMaxHP += (short)pScrollTemplate.IncMHP;
                        pEquip.niMaxMP += (short)pScrollTemplate.IncMMP;
                        pEquip.niPAD   += (short)pScrollTemplate.IncPAD;                      // watk
                        pEquip.niMAD   += (short)pScrollTemplate.IncMAD;                      // matk
                        pEquip.niPDD   += (short)pScrollTemplate.IncPDD;                      // wdef
                        pEquip.niMDD   += (short)pScrollTemplate.IncMDD;                      // mdef
                        pEquip.niACC   += (short)pScrollTemplate.IncACC;                      // accuracy
                        pEquip.niEVA   += (short)pScrollTemplate.IncEVA;                      // avoid
                        pEquip.niCraft += (short)pScrollTemplate.IncCraft;                    // still not sure wtf this is
                        pEquip.niSpeed += (short)pScrollTemplate.IncSpeed;
                        pEquip.niJump  += (short)pScrollTemplate.IncJump;
                    }
                }
            }

            if (bDestroy)
            {
                InventoryManipulator.RemoveFrom(Parent, InventoryType.Equip, nEquipPOS);
            }
            else                                       // success or fail
            {
                if (pScrollTemplate.Recover <= 0)      // not an upgrade count recovery scroll
                {
                    pEquip.RemainingUpgradeCount -= 1; // reduce remaining upgrade count if no white scroll

                    if (bSuccess)
                    {
                        pEquip.CurrentUpgradeCount += 1;                         // increase upgrade count
                    }
                    else if (bWhiteScroll)
                    {
                        pEquip.RemainingUpgradeCount += 1;
                    }

                    if (bWhiteScroll)
                    {
                        InventoryManipulator.RemoveFrom(Parent, InventoryType.Consume, nWhiteScrollPOS);
                    }
                }

                Parent.Modify.Inventory(ctx =>
                {
                    ctx.UpdateEquipInformation(pEquip, nEquipPOS);
                });
            }

            InventoryManipulator.RemoveFrom(Parent, InventoryType.Consume, nScrollPOS);

            Parent.StatisticsTracker.IncrementScrollUse(pScrollTemplate.TemplateId, bSuccess, bDestroy);
            Parent.Field.Broadcast(pEquip.ShowItemUpgradeEffect(Parent, bSuccess, bDestroy, bWhiteScroll));
        }