Пример #1
0
        public void CreateMiniRoom(Character c, MR_Type nType, CInPacket p)
        {
            switch (nType)
            {
            case MR_Type.Omok:
                // todo
                break;

            case MR_Type.MemoryGame:
                // todo
                break;

            case MR_Type.TradingRoom:
                if (c.CurMiniRoom != null)
                {
                    c.SendPacket(CPacket.SystemMessage("You are already in a trade."));
                }
                else
                {
                    Log.Debug($"Adding trade mini room to field minirooms.");
                    Add(new CTradingRoom(c));
                }
                break;

            // Recv [CP_MiniRoom] 90 00 00 05 07 00 70 65 65 66 61 63 65 00 01 00 76 C0 4C 00
            case MR_Type.PersonalShop:
                c.SendMessage("no");
                break;

            case MR_Type.EntrustedShop:
            {
                // TODO check closeness to other shops
                var sTitle = p.DecodeString();
                p.Skip(3);         // TODO what is this
                var nShopTemplateId = p.Decode4();

                var(nItemSlot, pItem) = InventoryManipulator.GetAnyItem(c, InventoryType.Cash, nShopTemplateId);

                Log.Info($"Player [{c.Stats.sCharacterName}] attempting to create a shop with ItemID [{nShopTemplateId}] and Title [{sTitle}]");

                if (pItem == null || nItemSlot == 0)
                {
                    c.SendPacket(CPacket.SystemMessage("Invalid item or item slot."));         // packet editing?
                }
                else if (!c.Field.MapId.InRange(910000000, 910000023))
                {
                    c.SendPacket(CPacket.SystemMessage("Item does not work in this map."));
                }
                else if (!ItemConstants.is_entrusted_shop_item(pItem.nItemID))
                {
                    c.SendPacket(CPacket.SystemMessage("Invalid shop item."));         // packet editing??
                }
                else
                {
                    var pMiniRoom = new CEntrustedShop(c, nShopTemplateId, sTitle);

                    if (pMiniRoom.HasItems())
                    {
                        c.SendMessage("Please retrieve items from fredrick before opening a shop.");
                    }
                    else
                    {
                        //Add(pMiniRoom); // packet is sent in here
                    }
                }
                break;
            }

            case MR_Type.CashTradingRoom:
                // todo
                break;

            default:
                break;
            }
        }
 //
 // -------------- Inventory Manipulators
 //
 public int GetItemCount(int nItemID) => InventoryManipulator.GetAnyItem(Character, nItemID).Item2?.nNumber ?? 0;         // TODO count all items instead of just one
Пример #3
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));
        }
Пример #4
0
        private static void HandleCreateItemOp(Character pChar, int nItemID, bool bStimulantUsed, List <int> aGems)
        {
            // BEGIN VERIFICATION

            //var pMakerItem = MasterManager.EtcTemplates.MakerData(nItemID);
            var makerItem = MasterManager.ItemMakeTemplates[nItemID];

            // verify maker item exists
            if (makerItem is null)
            {
                pChar.SendMessage("Null item maker template.");
                return;
            }

            // verify player is high enough level to use recipe
            if (makerItem.ReqLevel > pChar.Stats.nLevel + 6)
            {
                pChar.SendMessage("Verify the item level you're trying to craft is no more than 6 above your own.");
                return;
            }

            // verify player has enough meso
            if (makerItem.Meso > pChar.Stats.nMoney)
            {
                pChar.SendMessage("Verify you have the correct amount of mesos.");
                return;
            }

            var pCharMakerSkill = pChar.Skills.Get(Common.GameLogic.SkillLogic.get_novice_skill_as_race(Common.GameLogic.SkillLogic.NoviceSkillID.MakerSkill, pChar.Stats.nJob));

            // verify player maker skill level is high enough
            if (makerItem.ReqSkillLevel > (pCharMakerSkill?.nSLV ?? 0))
            {
                pChar.SendMessage($"Verify maker skill level. {makerItem.ReqSkillLevel} < {(pCharMakerSkill?.nSLV ?? 0)}");
                return;
            }

            var(nStimulantItemSlot, pStimulantItem) = InventoryManipulator.GetAnyItem(pChar, InventoryType.Etc, makerItem.CatalystID);

            // verify stimulant (catalyst) exists in player inventory
            if (bStimulantUsed && pStimulantItem is null)
            {
                pChar.SendMessage("Verify you possess the correct stimulant item.");
                return;
            }

            // verify equip slot availability
            if (InventoryManipulator.CountFreeSlots(pChar, InventoryType.Equip) < 1)
            {
                pChar.SendMessage("Please make more room in your equip inventory.");
                return;
            }

            if (InventoryManipulator.CountFreeSlots(pChar, InventoryType.Etc) < makerItem.RandomReward.Length)
            {
                pChar.SendMessage("Please make more room in your etc inventory.");
                return;
            }

            // verify required items exist in player inventory
            if (makerItem.Recipe.Any(item => !InventoryManipulator.ContainsItem(pChar, item.ItemID, (short)item.Count)))
            {
                pChar.SendMessage("Verify you possess all the required components.");
                return;
            }

            var aGemItemIds   = new List <int>();
            var aGemItemTypes = new List <int>();

            // remove duplicate items/types and get item slots for gems
            foreach (var entry in aGems)
            {
                var(nGemSlot, pGemItem) = InventoryManipulator.GetAnyItem(pChar, InventoryType.Etc, entry);

                if (pGemItem is null || nGemSlot == 0 || !(pGemItem.Template is GemEffectTemplate))
                {
                    continue;
                }

                // idk how it would be 0 but we check anyway
                if (!aGemItemTypes.Contains(entry / 100) &&
                    !aGemItemIds.Contains(pGemItem.nItemID) &&
                    pGemItem.nNumber > 0)
                {
                    aGemItemIds.Add(pGemItem.nItemID);
                    aGemItemTypes.Add(entry / 100);
                }
            }

            // END VERIFICATION

            // BEGIN RECIPE PROCESSING

            // remove meso cost from inventory
            if (makerItem.Meso > 0)
            {
                pChar.Modify.GainMeso(-makerItem.Meso);
            }

            // remove stimulant from inventory
            if (bStimulantUsed)
            {
                InventoryManipulator.RemoveQuantity(pChar, pStimulantItem.nItemID, 1);
            }

            // remove recipe items from inventory
            foreach (var item in makerItem.Recipe)
            {
                InventoryManipulator.RemoveQuantity(pChar, item.ItemID, (short)item.Count);
            }

            var bSuccess = true;

            if (bStimulantUsed && Constants.Rand.Next(100) >= 90)
            {
                bSuccess = false;
            }
            else
            {
                // BEGIN MAKER ITEM CREATION

                var pNewItemRaw = MasterManager.CreateItem(makerItem.TemplateId);

                if (pNewItemRaw is GW_ItemSlotEquip pNewItemEquip)
                {
                    pNewItemEquip.RemainingUpgradeCount = (byte)makerItem.TUC;

                    // remove gems from inventory
                    foreach (var nGemItemId in aGemItemIds)
                    {
                        var pGemItemRaw = InventoryManipulator.GetAnyItem(pChar, InventoryType.Etc, nGemItemId).Item2;

                        if (pGemItemRaw.Template is GemEffectTemplate pGemItem)
                        {
                            // gems only have one modifier each
                            if (pGemItem.incPAD > 0)
                            {
                                pNewItemEquip.niPAD += (short)(pGemItem.incPAD * (bStimulantUsed ? 2 : 1));
                            }
                            else if (pGemItem.incPDD > 0)
                            {
                                pNewItemEquip.niPDD += (short)(pGemItem.incPDD * (bStimulantUsed ? 2 : 1));
                            }
                            else if (pGemItem.incMAD > 0)
                            {
                                pNewItemEquip.niMAD += (short)(pGemItem.incMAD * (bStimulantUsed ? 2 : 1));
                            }
                            else if (pGemItem.incMDD > 0)
                            {
                                pNewItemEquip.niMDD += (short)(pGemItem.incMDD * (bStimulantUsed ? 2 : 1));
                            }

                            else if (pGemItem.incSTR > 0)
                            {
                                pNewItemEquip.niSTR += (short)(pGemItem.incSTR * (bStimulantUsed ? 2 : 1));
                            }
                            else if (pGemItem.incINT > 0)
                            {
                                pNewItemEquip.niINT += (short)(pGemItem.incINT * (bStimulantUsed ? 2 : 1));
                            }
                            else if (pGemItem.incDEX > 0)
                            {
                                pNewItemEquip.niDEX += (short)(pGemItem.incDEX * (bStimulantUsed ? 2 : 1));
                            }
                            else if (pGemItem.incLUK > 0)
                            {
                                pNewItemEquip.niLUK += (short)(pGemItem.incLUK * (bStimulantUsed ? 2 : 1));
                            }

                            else if (pGemItem.incACC > 0)
                            {
                                pNewItemEquip.niACC += (short)(pGemItem.incACC * (bStimulantUsed ? 2 : 1));
                            }
                            else if (pGemItem.incEVA > 0)
                            {
                                pNewItemEquip.niEVA += (short)(pGemItem.incEVA * (bStimulantUsed ? 2 : 1));
                            }
                            else if (pGemItem.incMaxHP > 0)
                            {
                                pNewItemEquip.niMaxHP += (short)(pGemItem.incMaxHP * (bStimulantUsed ? 2 : 1));
                            }
                            else if (pGemItem.incMaxMP > 0)
                            {
                                pNewItemEquip.niMaxMP += (short)(pGemItem.incMaxMP * (bStimulantUsed ? 2 : 1));
                            }

                            else if (pGemItem.incJump > 0)
                            {
                                pNewItemEquip.niJump += (short)(pGemItem.incJump * (bStimulantUsed ? 2 : 1));
                            }
                            else if (pGemItem.incSpeed > 0)
                            {
                                pNewItemEquip.niSpeed += (short)(pGemItem.incSpeed * (bStimulantUsed ? 2 : 1));
                            }

                            else if (pGemItem.incReqLevel < 0)
                            {
                                pNewItemEquip.nLevel = (byte)(pNewItemEquip.nLevel + (pGemItem.incReqLevel * (bStimulantUsed ? 2 : 1)));
                            }

                            else if (pGemItem.RandOption > 0)
                            {
                                var gX = new GaussianRandom();

                                var nRange = pGemItem.RandOption * (bStimulantUsed ? 2 : 1);

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

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

                                if (pNewItemEquip.niSpeed > 0)
                                {
                                    pNewItemEquip.niSpeed = (short)Math.Max(0, gX.GaussianDistributionVariation(pNewItemEquip.niSpeed, nRange, false));
                                }
                                if (pNewItemEquip.niJump > 0)
                                {
                                    pNewItemEquip.niJump = (short)Math.Max(0, gX.GaussianDistributionVariation(pNewItemEquip.niJump, nRange, false));
                                }
                            }
                            // pNewItemEquip.ApplyRandStatOption(pGemItem.RandOption * (bStimulantUsed ? 2 : 1), false);
                            else if (pGemItem.RandStat > 0)
                            {
                                var gX = new GaussianRandom();

                                var nRange = pGemItem.RandStat * (bStimulantUsed ? 2 : 1);

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

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

                    InventoryManipulator.InsertInto(pChar, pNewItemEquip);
                }
                else
                {
                    pNewItemRaw.nNumber = (short)makerItem.ItemNum;
                    InventoryManipulator.InsertInto(pChar, pNewItemRaw);
                }

                // remove gems if any
                foreach (var nGemItemId in aGemItemIds)
                {
                    InventoryManipulator.RemoveQuantity(pChar, nGemItemId, 1);                     //InventoryManipulator.RemoveFrom(pChar, (byte)InventoryType.Etc, itemSlot, 1);
                }

                foreach (var entry in makerItem.RandomReward)
                {
                    if (Constants.Rand.Next(100) >= entry.Prob)
                    {
                        continue;
                    }

                    var pRandRewardItem = MasterManager.CreateItem(entry.ItemID);

                    pRandRewardItem.nNumber = (short)entry.ItemNum;

                    InventoryManipulator.InsertInto(pChar, pRandRewardItem);
                }

                // END MAKER ITEM CREATION
            }

            // END RECIPE PROCESSING

            // SEND RESPONSE PACKETS

            pChar.SendPacket(CreateItemResponse(bSuccess, bStimulantUsed, makerItem, aGemItemIds));

            pChar.SendPacket(MakerItemEffectLocal(bSuccess));
            pChar.Field.Broadcast(MakerItemEffectRemote(pChar.dwId, bSuccess));
        }