コード例 #1
0
        private void AddItems(Character chr)
        {
            // Note: Exchange logic, so A gets B and B gets A stuff
            for (int i = 0; i < 2; i++)
            {
                if (i == chr.RoomSlotId)
                {
                    continue;
                }
                var charFrom = Users[i];

                for (int j = 0; j < 10; j++)
                {
                    TradeItem ti = ItemList[i][j];

                    if (ti?.OriginalItem != null)
                    {
                        chr.Inventory.AddItem2(ti.OriginalItem);
                        ItemTransfer.PlayerTradeExchange(charFrom.ID, chr.ID, ti.OriginalItem.ItemID, ti.OriginalItem.Amount, _transaction, ti.OriginalItem);
                        ti.OriginalItem = null;
                    }
                }

                var mesos = Mesos[i];
                if (mesos != 0)
                {
                    chr.AddMesos(mesos);
                    MesosTransfer.PlayerTradeExchange(charFrom.ID, chr.ID, mesos, _transaction);
                }
            }
        }
コード例 #2
0
        public override void RemovePlayer(Character pCharacter, byte pReason)
        {
            // Give items back
            RevertItems();

            var mesos = Mesos[pCharacter.RoomSlotId];

            if (mesos != 0)
            {
                pCharacter.AddMesos(mesos);
                MesosTransfer.PlayerTradeReverted(pCharacter.ID, mesos, _transaction);
                Mesos[pCharacter.RoomSlotId] = 0;
            }

            base.RemovePlayer(pCharacter, pReason);
        }
コード例 #3
0
        public static void HandleStorage(Character chr, Packet pr)
        {
            if (chr.TrunkNPCID == 0)
            {
                return;
            }

            byte opcode = pr.ReadByte();

            switch ((StorageAction)opcode)
            {
            case StorageAction.Withdraw:     // Remove
            {
                byte     inventory = pr.ReadByte();
                byte     slot      = pr.ReadByte();
                BaseItem item      = chr.Storage.GetItem(inventory, slot);
                if (item == null)
                {
                    return;
                }

                short amount = item.Amount;
                if (!Constants.isStackable(item.ItemID))
                {
                    amount = 1;         // 1 'set'
                }

                if (chr.Inventory.HasSlotsFreeForItem(item.ItemID, amount, inventory != 1))
                {
                    // AddItem2 will distribute stackable items
                    chr.Inventory.AddItem2(item);
                    chr.Storage.TakeItemOut(inventory, slot);

                    ItemTransfer.PlayerStorageWithdraw(chr.ID, chr.TrunkNPCID, item.ItemID, item.Amount, null, item);

                    EncodeStorage(chr, StorageEncode.EncodeWithdraw, GetEncodeFlagForInventory(Constants.getInventory(item.ItemID)));
                }
                else
                {
                    SendError(chr, StorageErrors.InventoryFullOrNot);
                }
                break;
            }

            case StorageAction.Deposit:     // Add
            {
                byte    slot        = (byte)pr.ReadShort();
                int     itemid      = pr.ReadInt();
                short   amount      = pr.ReadShort();
                NPCData data        = DataProvider.NPCs[chr.TrunkNPCID];
                var     storageCost = data.Trunk;
                if (chr.Inventory.Mesos < storageCost)
                {
                    SendError(chr, StorageErrors.NotEnoughMesos);
                    return;
                }

                byte     inventory = Constants.getInventory(itemid);
                BaseItem item      = chr.Inventory.GetItem(inventory, slot);
                if (item == null || item.ItemID != itemid || item.CashId != 0)
                {
                    // hax
                    return;
                }
                if (!chr.Storage.SlotsAvailable())
                {
                    SendError(chr, StorageErrors.StorageIsFull);
                    return;
                }

                var isRechargable = Constants.isRechargeable(item.ItemID);
                if (isRechargable)
                {
                    amount = item.Amount;
                }

                var possibleNewItem = chr.Inventory.TakeItemAmountFromSlot(inventory, slot, amount, true);
                if (chr.AssertForHack(possibleNewItem == null, "Storage hack (amount > item.amount)"))
                {
                    return;
                }

                chr.Storage.AddItem(possibleNewItem);

                ItemTransfer.PlayerStorageStore(chr.ID, chr.TrunkNPCID, item.ItemID, item.Amount, "" + item.GetHashCode() + " " + possibleNewItem.GetHashCode(), possibleNewItem);

                EncodeStorage(chr, StorageEncode.EncodeDeposit, GetEncodeFlagForInventory(Constants.getInventory(item.ItemID)));

                chr.AddMesos(-storageCost);         //why did you forget this diamondo :P

                MesosTransfer.PlayerGaveToNPC(chr.ID, chr.TrunkNPCID, storageCost, "" + item.GetHashCode());
                break;
            }

            case StorageAction.StoreMesos:
            {
                int mesos = pr.ReadInt();
                if (mesos < 0)
                {
                    // Store
                    if (chr.AssertForHack(Math.Abs(mesos) > chr.Inventory.Mesos, "Trying to store more mesos than he has") == false)
                    {
                        Common.Tracking.MesosTransfer.PlayerStoreMesos(chr.ID, Math.Abs(mesos));
                        chr.AddMesos(mesos);
                        chr.Storage.ChangeMesos(mesos);
                    }
                }
                else
                {
                    // Withdraw
                    if (chr.AssertForHack(Math.Abs(mesos) > chr.Storage.Mesos, "Trying to withdraw more mesos than he has") == false)
                    {
                        Common.Tracking.MesosTransfer.PlayerRetrieveMesos(chr.ID, Math.Abs(mesos));
                        chr.AddMesos(mesos);
                        chr.Storage.ChangeMesos(mesos);
                    }
                }
                break;
            }

            case StorageAction.Exit:
            {
                chr.TrunkNPCID = 0;
                break;
            }

            default:
            {
                Program.MainForm.LogAppend("Unknown Storage action: {0}", pr);
                break;
            }
            }
        }
コード例 #4
0
ファイル: PlayerShop.cs プロジェクト: zhuomingliang/WvsGlobal
        public void BuyItem(Character pCharacter, byte slot, short quantity)
        {
            //This may seem confusing, but the client calculates the amount left itself.
            //The formula is bundles * bundleamount, so if you have 2 bundles with 25 in each, it will obviously show 50. If you have 100 items in 1 bundle, it will show you 100
            PlayerShopItem pst = Items[slot];
            PlayerShop     ps  = MiniRoomBase.PlayerShops[pCharacter.Room.ID];

            if (pst == null)
            {
                return;
            }

            if (pCharacter.AssertForHack(
                    quantity < 0,
                    $"PlayerShop hack: trying to buy negative amount. Requested {quantity}"
                    ))
            {
                return;
            }

            if (pst.sItem.Amount <= 0)
            {
                // TODO: Get packet?
                return;
            }


            var cost       = quantity * pst.Price;
            var realAmount = (short)(quantity * pst.BundleAmount);

            if (cost > pCharacter.Inventory.Mesos)
            {
                // TODO: Get packet?
                return;
            }

            if (pCharacter.AssertForHack(
                    pst.Bundles < quantity,
                    $"PlayerShop hack: buying more than there's in store. Bundle: {pst.Bundles}, requested {quantity}"
                    ))
            {
                return;
            }

            if (pCharacter.AssertForHack(
                    pst.sItem.Amount < realAmount,
                    $"PlayerShop hack: buying more than there's in store. Item amount: {pst.sItem.Amount}, requested {realAmount}"
                    ))
            {
                return;
            }


            pCharacter.Inventory.AddNewItem(pst.sItem.ItemID, realAmount);
            pCharacter.AddMesos(-cost);
            Owner.AddMesos(cost);

            MesosTransfer.PlayerBuysFromPersonalShop(pCharacter.ID, Owner.ID, cost, _transaction);
            ItemTransfer.PersonalShopBoughtItem(Owner.ID, pCharacter.ID, pst.sItem.ItemID, realAmount, TransactionID, pst.sItem);



            pst.Bundles      -= quantity;
            pst.sItem.Amount -= realAmount;

            PlayerShopPackets.PersonalShopRefresh(pCharacter, ps);
            PlayerShopPackets.SoldItemResult(Owner, pCharacter, slot, quantity);
        }
コード例 #5
0
        public void DoSkillCost(int skillid, byte level)
        {
            var data = GetSkillLevelData(skillid, level);

            if (data == null)
            {
                return;
            }

            if (skillid == Constants.DragonKnight.Skills.DragonRoar)
            {
                var lefthp = (int)(Character.PrimaryStats.MaxHP * (data.XValue / 100.0d));
                Character.DamageHP((short)lefthp);
            }

            var mp   = data.MPUsage;
            var hp   = data.HPUsage;
            var cash = data.MesosUsage;
            var item = data.ItemIDUsage;

            if (mp > 0)
            {
                mp = GetElemAmpInc(skillid, mp);
                if (Character.AssertForHack(Character.PrimaryStats.MP < mp, "MP Hack (no MP left)"))
                {
                    return;
                }
                Character.ModifyMP((short)-mp, true);
            }
            if (hp > 0)
            {
                if (Character.AssertForHack(Character.PrimaryStats.HP < hp, "HP Hack (no HP left)"))
                {
                    return;
                }
                Character.ModifyHP((short)-hp, true);
            }
            if (item > 0)
            {
                var slotsAvailable = Character.Inventory.ItemAmountAvailable(item);
                if (Character.AssertForHack(slotsAvailable < data.ItemAmountUsage,
                                            "Player tried to use skill with item consumption. Not enough items to consume."))
                {
                    return;
                }

                Character.Inventory.TakeItem(item, data.ItemAmountUsage);
                ItemTransfer.PlayerUsedSkill(Character.ID, skillid, item, data.ItemAmountUsage);
            }

            if (cash > 0 && false)
            {
                var min        = (short)(cash - (80 + level * 5));
                var max        = (short)(cash + (80 + level * 5));
                var realAmount = (short)Character.CalcDamageRandomizer.ValueBetween(min, max);
                if (Character.AssertForHack(((long)Character.Inventory.Mesos - realAmount) < 0,
                                            "Player tried to use skill with meso consumption. Not enough mesos."))
                {
                    return;
                }

                Character.AddMesos(-realAmount);
                MesosTransfer.PlayerUsedSkill(Character.ID, realAmount, skillid);
            }
        }
コード例 #6
0
        public override void OnPacket(Character pCharacter, byte pOpcode, Packet pPacket)
        {
            switch (pOpcode)
            {
            case 13:
            {
                byte charslot = pCharacter.RoomSlotId;
                // Put Item
                if (!IsFull())
                {
                    // You can't put items while the second char isn't there yet
                    InventoryPacket.NoChange(pCharacter);
                    return;
                }

                byte  inventory = pPacket.ReadByte();
                short slot      = pPacket.ReadShort();
                short amount    = pPacket.ReadShort();
                byte  toslot    = pPacket.ReadByte();

                var demItem = pCharacter.Inventory.GetItem(inventory, slot);

                if (demItem == null || toslot < 1 || toslot > 9)         // Todo: trade check
                {
                    // HAX
                    var msg = $"Player tried to add an item in trade with to an incorrect slot. Item = null? {demItem == null}; toSlot {toslot}";
                    Program.MainForm.LogAppend(msg);
                    ReportManager.FileNewReport(msg, pCharacter.ID, 0);
                    InventoryPacket.NoChange(pCharacter);
                    return;
                }

                BaseItem tehItem = pCharacter.Inventory.TakeItemAmountFromSlot(inventory, slot, amount, Constants.isRechargeable(demItem.ItemID));

                if (ItemList[charslot][toslot] == null)
                {
                    ItemList[charslot][toslot] = new TradeItem()
                    {
                        OriginalItem = tehItem
                    };
                }

                var pTradeItem = ItemList[charslot][toslot].OriginalItem;

                ItemTransfer.PlayerTradePutUp(pCharacter.ID, demItem.ItemID, slot, amount, _transaction, demItem);

                bool isUser0 = pCharacter.Name == Users[0].Name;

                TradePacket.AddItem(Users[0], toslot, pTradeItem, (byte)(isUser0 ? 0 : 1));
                TradePacket.AddItem(Users[1], toslot, pTradeItem, (byte)(isUser0 ? 1 : 0));

                InventoryPacket.NoChange(pCharacter);         // -.-
                break;
            }

            case 14:     // Put mesos
            {
                //MessagePacket.SendNotice("PUTMESO PACKET: " + pPacket.ToString(), pCharacter);
                int amount = pPacket.ReadInt();

                if (amount < 0 || pCharacter.Inventory.Mesos < amount)
                {
                    // HAX
                    var msg = "Player tried putting an incorrect meso amount in trade. Amount: " + amount;
                    Program.MainForm.LogAppend(msg);
                    ReportManager.FileNewReport(msg, pCharacter.ID, 0);
                    return;
                }

                pCharacter.AddMesos(-amount, true);
                MesosTransfer.PlayerTradePutUp(pCharacter.ID, amount, _transaction);
                Mesos[pCharacter.RoomSlotId] += amount;


                bool isUser0 = pCharacter.Name == Users[0].Name;

                TradePacket.PutCash(Users[0], Mesos[pCharacter.RoomSlotId], (byte)(isUser0 ? 0 : 1));
                TradePacket.PutCash(Users[1], Mesos[pCharacter.RoomSlotId], (byte)(isUser0 ? 1 : 0));

                break;
            }

            // Accept trade
            case 0xF:
            {
                byte charslot = pCharacter.RoomSlotId;
                Locked[charslot] = true;

                for (int i = 0; i < 2; i++)
                {
                    Character chr = Users[i];

                    if (chr != pCharacter)
                    {
                        TradePacket.SelectTrade(chr);
                    }
                }

                if (Locked[0] == true && Locked[1] == true)
                {
                    Character chr  = Users[0];
                    Character chr2 = Users[1];
                    if (ContinueTrade())
                    {
                        CompleteTrade();

                        TradePacket.TradeSuccessful(chr);
                        TradePacket.TradeSuccessful(chr2);
                    }
                    else
                    {
                        // Unsuccessful error
                        RemovePlayer(chr, 6);
                        RemovePlayer(chr2, 6);
                    }
                }
                break;
            }
            }
        }
コード例 #7
0
        public static void HandleCharacterDamage(Character chr, Packet pr)
        {
            //1A FF 03 00 00 00 00 00 00 00 00 04 87 01 00 00 00
            sbyte attack         = pr.ReadSByte();
            int   damage         = pr.ReadInt();
            int   reducedDamage  = damage;
            int   actualHPEffect = -damage;
            int   actualMPEffect = 0;
            int   healSkillId    = 0;
            Mob   mob            = null;

            if (chr.AssertForHack(damage < -1, "Less than -1 (" + damage + ") damage in HandleCharacterDamage"))
            {
                return;
            }

            if (chr.PrimaryStats.HP == 0)
            {
                return;
            }

            byte mobSkillId = 0, mobSkillLevel = 0;

            if (attack <= -2)
            {
                mobSkillLevel = pr.ReadByte();
                mobSkillId    = pr.ReadByte(); // (short >> 8)

                Trace.WriteLine($"Got a hit with {attack} attack, mobSkillLevel {mobSkillLevel}, mobSkillId {mobSkillId}");
            }
            else
            {
                int magicAttackElement = 0;
                if (pr.ReadBool())
                {
                    magicAttackElement = pr.ReadInt();
                    // 0 = no element (Grendel the Really Old, 9001001)
                    // 1 = Ice (Celion? blue, 5120003)
                    // 2 = Lightning (Regular big Sentinel, 3000000)
                    // 3 = Fire (Fire sentinel, 5200002)
                }

                var mobMapId = pr.ReadInt();
                var mobId    = pr.ReadInt();

                mob = chr.Field.GetMob(mobMapId);
                if (mob == null ||
                    mobId != mob.MobID)
                {
                    return;
                }

                // Newer ver: int nCalcDamageMobStatIndex
                var stance      = pr.ReadByte();
                var isReflected = pr.ReadBool();

                byte  reflectHitAction = 0;
                short reflectX = 0, reflectY = 0;
                if (isReflected)
                {
                    reflectHitAction = pr.ReadByte();
                    reflectX         = pr.ReadShort();
                    reflectY         = pr.ReadShort();
                }

                if (chr.PrimaryStats.BuffMagicGuard.HasReferenceId(Constants.Magician.Skills.MagicGuard) &&
                    chr.PrimaryStats.MP > 0)
                {
                    // Absorbs X amount of damage. :)
                    var  skillId = chr.PrimaryStats.BuffMagicGuard.R;
                    byte skillLevel;
                    var  sld = chr.Skills.GetSkillLevelData(skillId, out skillLevel);

                    int damageEaten = (int)Math.Round((damage * (sld.XValue / 100.0d)));

                    // MagicGuard doesn't show reduced damage.


                    Trace.WriteLine($"Reducing damage by MG. Reflected {damageEaten}");

                    //Program.MainForm.LogAppend("MG Damage before change: " + actualHPEffect);
                    actualHPEffect += damageEaten;
                    //Program.MainForm.LogAppend("MG Damage after change: " + actualHPEffect);
                    actualMPEffect = -damageEaten;

                    healSkillId = skillId;
                }

                if (chr.PrimaryStats.BuffPowerGuard.HasReferenceId(Constants.Fighter.Skills.PowerGuard) ||
                    chr.PrimaryStats.BuffPowerGuard.HasReferenceId(Constants.Page.Skills.PowerGuard))
                {
                    var  skillId = chr.PrimaryStats.BuffPowerGuard.R;
                    byte skillLevel;
                    var  sld = chr.Skills.GetSkillLevelData(skillId, out skillLevel);

                    int damageReflectedBack = (int)(damage * (sld.XValue / 100.0d));

                    if (damageReflectedBack > mob.MaxHP)
                    {
                        damageReflectedBack = (int)(mob.MaxHP * 0.1);
                    }

                    if (mob.IsBoss)
                    {
                        damageReflectedBack /= 2;
                    }

                    mob.GiveDamage(chr, damageReflectedBack);
                    MobPacket.SendMobDamageOrHeal(chr, mobId, damageReflectedBack, false, false);

                    mob.CheckDead(mob.Position);

                    Trace.WriteLine($"Reducing damage by PG. Reflected {damageReflectedBack}");
                    actualHPEffect += damageReflectedBack; // Buff 'damaged' hp, so its less
                    healSkillId     = skillId;
                }


                if (chr.PrimaryStats.BuffMesoGuard.IsSet())
                {
                    var skillId = Constants.ChiefBandit.Skills.MesoGuard;
                    var sld     = chr.Skills.GetSkillLevelData(
                        skillId,
                        out var skillLevel
                        );

                    if (sld != null)
                    {
                        var percentage = sld.XValue;

                        var damageReduction = reducedDamage / 2;
                        var mesoLoss        = damageReduction * percentage / 100;
                        if (damageReduction != 0)
                        {
                            var playerMesos    = chr.Inventory.Mesos;
                            var maxMesosUsable = Math.Min(chr.PrimaryStats.BuffMesoGuard.MesosLeft, playerMesos);
                            if (mesoLoss > maxMesosUsable)
                            {
                                // New calculation. in our version it should actually 'save' the
                                // mesos for a bit.
                                damageReduction = 100 * maxMesosUsable / percentage;
                                mesoLoss        = maxMesosUsable;
                            }

                            if (mesoLoss > 0)
                            {
                                chr.PrimaryStats.BuffMesoGuard.MesosLeft -= mesoLoss;
                                MesosTransfer.PlayerUsedSkill(chr.ID, mesoLoss, skillId);

                                chr.AddMesos(-(mesoLoss), false);

                                Trace.WriteLine($"Reducing damage by mesos. Mesos: {mesoLoss}, maxMesos {maxMesosUsable}, reduction {damageReduction}");
                                actualHPEffect += damageReduction;
                                reducedDamage  -= reducedDamage;
                            }

                            if (chr.PrimaryStats.BuffMesoGuard.MesosLeft <= 0)
                            {
                                // Debuff when out of mesos
                                chr.PrimaryStats.RemoveByReference(skillId);
                            }
                        }
                    }
                }

                SendCharacterDamageByMob(
                    chr,
                    attack,
                    damage,
                    reducedDamage,
                    healSkillId,
                    mobMapId,
                    mobId,
                    stance,
                    isReflected,
                    reflectHitAction,
                    reflectX,
                    reflectY
                    );
            }

            Trace.WriteLine($"Showing damage: {reducedDamage}, {damage}");
            Trace.WriteLine($"Applying damage: HP {actualHPEffect}, MP: {actualMPEffect}");

            if (actualHPEffect < 0)
            {
                chr.ModifyHP((short)actualHPEffect);
            }
            if (actualMPEffect < 0)
            {
                chr.ModifyMP((short)actualMPEffect);
            }

            if (mobSkillLevel != 0 && mobSkillId != 0)
            {
                // Check if the skill exists and has any extra effect.

                if (!DataProvider.MobSkills.TryGetValue(mobSkillId, out var skillLevels))
                {
                    return;
                }

                // Still going strong
                if (!skillLevels.TryGetValue(mobSkillLevel, out var msld))
                {
                    return;
                }
                OnStatChangeByMobSkill(chr, msld);
            }
            else if (mob != null)
            {
                // CUser::OnStatChangeByMobAttack
                if (mob.Data.Attacks == null ||
                    !mob.Data.Attacks.TryGetValue((byte)attack, out var mad))
                {
                    return;
                }
                // Okay, we've got an attack...
                if (mad.Disease <= 0)
                {
                    return;
                }

                // Shit's poisonous!
                // Hmm... We could actually make snails give buffs... hurr

                if (!DataProvider.MobSkills.TryGetValue(mad.Disease, out var skillLevels))
                {
                    return;
                }

                // Still going strong
                if (!skillLevels.TryGetValue(mad.SkillLevel, out var msld))
                {
                    return;
                }
                OnStatChangeByMobSkill(chr, msld);
            }
        }