コード例 #1
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);
        }
コード例 #2
0
        public QuestResultType TryExchange(int nIncMoney, QuestAct.ActItem[] aActItem)
        {
            if (nIncMoney == 0 && aActItem.Length <= 0)
            {
                return(QuestResultType.Success);
            }

            if (nIncMoney < 0 &&
                Parent.Stats.nMoney < nIncMoney)
            {
                return(QuestResultType.Failed_Meso);
            }

            foreach (var item in aActItem)
            {
                if (item.Item.Count > 0)
                {
                    if (!InventoryManipulator.HasSpace(Parent, item.Item.ItemID, (short)item.Item.Count))
                    {
                        return(QuestResultType.Failed_Inventory);                        // -> Etc inventory is full
                    }
                }
                else
                {
                    if (!InventoryManipulator.ContainsItem(Parent, item.Item.ItemID, (short)item.Item.Count))
                    {
                        return(QuestResultType.Failed_Unknown);                        // idk what code to give them
                    }
                }
            }

            Parent.Modify.GainMeso(nIncMoney);

            var weight = 0;

            foreach (var item in aActItem)
            {
                if (item.ProbRate != 0)
                {
                    weight += item.ProbRate;
                }
            }

            var itemGiven = false;

            foreach (var item in aActItem.Shuffle())
            {
                if (item.Item.Count < 0)
                {
                    InventoryManipulator.RemoveQuantity(Parent, item.Item.ItemID, (short)item.Item.Count);
                }
                else
                {
                    if (item.ProbRate == 0)
                    {
                        var newItem = MasterManager.CreateItem(item.Item.ItemID, false);
                        if (!newItem.IsEquip)
                        {
                            newItem.nNumber = (short)item.Item.Count;
                        }

                        InventoryManipulator.InsertInto(Parent, newItem);
                    }
                    else if (!itemGiven)
                    {
                        var rand = Constants.Rand.Next(0, weight);

                        if (rand < item.ProbRate)
                        {
                            var newItem = MasterManager.CreateItem(item.Item.ItemID, false);
                            if (!newItem.IsEquip)
                            {
                                newItem.nNumber = (short)item.Item.Count;
                            }

                            InventoryManipulator.InsertInto(Parent, newItem);
                            itemGiven = true;
                        }
                        else
                        {
                            weight -= item.ProbRate;
                        }
                    }
                }
            }

            return(QuestResultType.Success);
        }
コード例 #3
0
 public bool HasItem(int itemId, short amount                = 1) => InventoryManipulator.ContainsItem(Character, itemId, amount);
コード例 #4
0
        public bool CheckDemand(short nQuestID, int dwNpcTemplateID, int nAct)
        {
            // TODO proper response codes

            var pQuest = MasterManager.QuestTemplates[nQuestID];

            var pDemand = nAct == 0 ? pQuest.StartDemand : pQuest.EndDemand;

            if (pDemand is null)
            {
                return(true);                             // no requirements
            }
            var correctNpc = nAct == 0 ? pQuest.StartNPC : pQuest.EndNPC;

            if (correctNpc != 0 && correctNpc != dwNpcTemplateID)
            {
                return(false);
            }

            switch (nAct)
            {
            case 0 when this[nQuestID] is null:
                return(true);

            case 1 when this[nQuestID] is null:
            case 1 when this[nQuestID].nState == QuestActType.NotStarted:
            case 0 when this[nQuestID].nState == QuestActType.QuestAccept:
                return(false);

            default:
                if (this[nQuestID].IsComplete)
                {
                    return(false);
                }
                break;
            }

            if (Parent.Stats.nLevel < pDemand.LevelMin)
            {
                return(false);
            }
            if (Parent.Stats.nPOP < pDemand.Pop)
            {
                return(false);
            }
            if (pQuest.Start > DateTime.MinValue && pQuest.Start.SecondsSinceStart() < 0)
            {
                return(false);
            }

            // hmm the client is still allowing some quests that have an end date and max level to be triggered...
            //if (pQuest.End > DateTime.MinValue && pQuest.End.SecondsSinceStart() > 0) return false;
            //if (pDemand.LevelMax != 0 && Parent.Stats.nLevel > pDemand.LevelMax) return false;

            if (pDemand.SubJobFlags != 0 && Parent.Stats.nSubJob != pDemand.SubJobFlags)
            {
                return(false);
            }

            if (pDemand.Job.Length > 0 &&
                pDemand.Job.All(job => job != Parent.Stats.nJob))
            {
                return(false);
            }

            foreach (var item in pDemand.DemandItem)
            {
                if (ItemConstants.GetInventoryType(item.ItemID) == InventoryType.Equip)
                {
                    if (InventoryManipulator.ItemEquipped(Parent, item.ItemID))
                    {
                        continue;
                    }
                }

                if (!InventoryManipulator.ContainsItem(Parent, item.ItemID, (short)item.Count))
                {
                    return(false);
                }
            }

            if (pDemand.EquipAllNeed.Any(
                    item => !InventoryManipulator.ItemEquipped(Parent, item)))
            {
                return(false);
            }

            if (pDemand.EquipSelectNeed.Length > 0 && pDemand.EquipSelectNeed.All(             // TODO verify
                    item => !InventoryManipulator.ItemEquipped(Parent, item)))
            {
                return(false);
            }

            foreach (var quest in pDemand.DemandQuest)
            {
                if (quest.State == 0 && !Contains(quest.QuestID))
                {
                    return(false);
                }
                if ((QuestActType)quest.State != this[quest.QuestID].nState)
                {
                    return(false);
                }
            }

            foreach (var skill in pDemand.DemandSkill)
            {
                if (skill.Acquire == 0 && Parent.Skills[skill.SkillID]?.nSLV != 0)
                {
                    return(false);
                }
                if (Parent.Skills[skill.SkillID].nSLV == 0)
                {
                    return(false);
                }
            }

            foreach (var mob in pDemand.DemandMob)
            {
                var quest = this[nQuestID];
                if (!quest.DemandRecords.ContainsKey(mob.MobID))
                {
                    return(false);
                }
                if (quest.DemandRecords[mob.MobID].nValue != mob.Count)
                {
                    return(false);
                }
            }

            foreach (var map in pDemand.DemandMap)
            {
                var quest = this[nQuestID];
                if (!quest.DemandRecords.ContainsKey(map.MapID))
                {
                    return(false);
                }
                if (quest.DemandRecords[map.MapID].nValue <= 0)
                {
                    return(false);
                }
            }

            if (pDemand.FieldEnter.Length > 0 &&
                pDemand.FieldEnter.All(map => map == Parent.Stats.dwPosMap))
            {
                return(false);
            }

            // TODO taming mob
            // TODO pet closeness

            return(true);
        }
コード例 #5
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));
        }