예제 #1
0
        private void OnUnlockObject(TSPlayer player, BinaryReader reader)
        {
            var unlockType = reader.ReadByte();

            if (unlockType == 1)
            {
                var x    = reader.ReadInt16();
                var y    = reader.ReadInt16();
                var tile = Main.tile[x, y];
                // Shadow chests don't consume the shadow key, so we shouldn't debit it.
                if (tile.frameX >= 144 && tile.frameX <= 178)
                {
                    return;
                }

                int keyId = ItemID.GoldenKey;
                if (tile.frameX >= 828 && tile.frameX <= 1006)
                {
                    keyId = ItemID.JungleKey + (tile.frameX / 36 - 23);
                }

                var balanceSheet = player.GetOrCreateBalanceSheet();
                balanceSheet.AddTransaction(-1, keyId, -1);
            }
            else if (unlockType == 2)
            {
                var balanceSheet = player.GetOrCreateBalanceSheet();
                balanceSheet.AddTransaction(-1, ItemID.TempleKey, -1);
            }
        }
예제 #2
0
        private void OnSendTileSquare(TSPlayer player, BinaryReader reader)
        {
            var size = reader.ReadUInt16();

            if (size != 1)
            {
                return;
            }

            reader.ReadInt16();
            reader.ReadInt16();
            var tile = new NetTile(reader.BaseStream);

            if (tile.Type == TileID.Mannequin || tile.Type == TileID.Womannequin)
            {
                var baseFrameX = tile.FrameX / 100;
                ILookup <int, Item> lookup;
                if (tile.FrameY == 0)
                {
                    lookup = _headSlotLookup;
                }
                else if (tile.FrameY == 18)
                {
                    lookup = _bodySlotLookup;
                }
                else
                {
                    lookup = _legSlotLookup;
                }

                var armorItem = lookup[baseFrameX].FirstOrDefault();
                if (armorItem != null)
                {
                    var balanceSheet = player.GetOrCreateBalanceSheet();
                    balanceSheet.AddTransaction(Transaction.WorldSlot, armorItem.type, -1);
                }
            }
            else if (tile.Type == TileID.WeaponsRack)
            {
                var baseFrameX = tile.FrameX - 5000 * (tile.FrameX / 5000);
                // When placing a weapon an a weapon rack, the client will send two SendTileSquare packets; the first
                // gives the item ID, and the second gives the item prefix. We know which one is the item ID since the
                // base frameX is over 100.
                if (baseFrameX > 100)
                {
                    player.SetWeaponRackItemId(baseFrameX - 100);
                }
                else
                {
                    var balanceSheet     = player.GetOrCreateBalanceSheet();
                    var weaponRackItemId = player.GetWeaponRackItemId();
                    balanceSheet.AddTransaction(Transaction.WorldSlot, weaponRackItemId, -1, (byte)baseFrameX);
                }
            }
        }
예제 #3
0
        private void OnUpdateTile(TSPlayer player, BinaryReader reader)
        {
            var action = reader.ReadByte();

            reader.ReadInt16();
            reader.ReadInt16();
            var data  = reader.ReadInt16();
            var style = reader.ReadByte();

            switch (action)
            {
            case 1:
                var tileItem = _createTileLookup[data].FirstOrDefault(i => i.placeStyle == style);
                if (tileItem != null)
                {
                    var balanceSheet = player.GetOrCreateBalanceSheet();
                    balanceSheet.AddTransaction(
                        Transaction.WorldSlot, tileItem.tileWand >= 0 ? tileItem.tileWand : tileItem.type, -1);
                }
                return;

            case 3:
                var wallItem = _createWallLookup[data].FirstOrDefault();
                if (wallItem != null)
                {
                    var balanceSheet = player.GetOrCreateBalanceSheet();
                    balanceSheet.AddTransaction(Transaction.WorldSlot, wallItem.type, -1);
                }
                return;

            case 5:
            case 10:
            case 12:
            case 16:
            {
                var balanceSheet = player.GetOrCreateBalanceSheet();
                balanceSheet.AddTransaction(Transaction.WorldSlot, ItemID.Wire, -1);
                return;
            }

            case 8:
            {
                var balanceSheet = player.GetOrCreateBalanceSheet();
                balanceSheet.AddTransaction(Transaction.WorldSlot, ItemID.Actuator, -1);
                return;
            }
            }
        }
예제 #4
0
        private void OnUpdateChestItem(TSPlayer player, BinaryReader reader)
        {
            var chestIndex = reader.ReadInt16();
            var itemIndex  = reader.ReadByte();
            var stackSize  = reader.ReadInt16();
            var prefix     = reader.ReadByte();
            var itemId     = reader.ReadInt16();

            NetItem item;

            if (_infiniteChests)
            {
                item = player.GetChestItem(itemIndex);
                player.SetChestItem(itemIndex, new NetItem(itemId, stackSize, prefix));
            }
            else
            {
                item = (NetItem)Main.chest[chestIndex].item[itemIndex];
            }

            var balanceSheet = player.GetOrCreateBalanceSheet();

            if (item.NetId == itemId)
            {
                balanceSheet.AddTransaction(1000 + itemIndex, item.NetId, item.Stack - stackSize, item.PrefixId);
            }
            else
            {
                balanceSheet.AddTransaction(1000 + itemIndex, item.NetId, item.Stack, item.PrefixId);
                balanceSheet.AddTransaction(1000 + itemIndex, itemId, -stackSize, prefix);
            }
        }
예제 #5
0
        private void OnUpdateInventory(TSPlayer player, BinaryReader reader)
        {
            reader.ReadByte();
            var slot      = reader.ReadByte();
            var stackSize = reader.ReadInt16();
            var prefix    = reader.ReadByte();
            var itemId    = reader.ReadInt16();

            var tplayer = player.TPlayer;
            var items   = tplayer.inventory.Concat(tplayer.armor).Concat(tplayer.dye).Concat(tplayer.miscEquips)
                          .Concat(tplayer.miscDyes).Concat(tplayer.bank.item).Concat(tplayer.bank2.item)
                          .Concat(new[] { tplayer.trashItem }).Concat(tplayer.bank3.item);
            var item = items.ElementAt(slot);

            var balanceSheet = player.GetOrCreateBalanceSheet();

            if (item.type == itemId)
            {
                balanceSheet.AddTransaction(slot, item.type, item.stack - stackSize, item.prefix);
            }
            else
            {
                // Don't credit the player for a trashed item that gets overriden.
                if (slot != Transaction.TrashCanSlot || itemId == 0)
                {
                    balanceSheet.AddTransaction(slot, item.type, item.stack, item.prefix);
                }
                balanceSheet.AddTransaction(slot, itemId, -stackSize, prefix);
            }
        }
예제 #6
0
        private void OnUpdateChest(TSPlayer player, BinaryReader reader)
        {
            var action = reader.ReadByte();

            reader.ReadInt16();
            reader.ReadInt16();
            var style = reader.ReadInt16();

            var containerId = -1;

            if (action == 0)
            {
                containerId = TileID.Containers;
            }
            else if (action == 2)
            {
                containerId = TileID.Dressers;
            }
            else if (action == 4)
            {
                containerId = TileID.Containers2;
            }

            var containerItem = _createTileLookup[containerId].FirstOrDefault(i => i.placeStyle == style);

            if (containerItem != null)
            {
                var balanceSheet = player.GetOrCreateBalanceSheet();
                balanceSheet.AddTransaction(Transaction.WorldSlot, containerItem.type, -1);
            }
        }
예제 #7
0
        private void OnUpdateItem(TSPlayer player, BinaryReader reader)
        {
            var itemIndex = reader.ReadInt16();

            reader.ReadVector2();
            reader.ReadVector2();
            var stackSize = reader.ReadInt16();
            var prefixId  = reader.ReadByte();

            reader.ReadByte();
            var itemId = reader.ReadInt16();

            if (itemIndex == Main.maxItems)
            {
                // Ignore hay created by the sickle, up to a certain stack size.
                if (player.SelectedItem.type == ItemID.Sickle && itemId == ItemID.Hay && stackSize <= 4)
                {
                    return;
                }

                var balanceSheet = player.GetOrCreateBalanceSheet();
                balanceSheet.AddTransaction(Transaction.WorldSlot, itemId, -stackSize, prefixId);
            }
            else
            {
                var item         = Main.item[itemIndex];
                var balanceSheet = player.GetOrCreateBalanceSheet();
                var netItem      = new NetItem(item.type, item.stack - stackSize, item.prefix);
                var lastNetItem  = player.GetLastUpdatedItem();
                // We need to specially detect if the client is stacking items, and adjust appropriately.
                if (netItem.NetId == lastNetItem.NetId && netItem.Stack == -lastNetItem.Stack && netItem.Stack > 0 &&
                    netItem.PrefixId == lastNetItem.PrefixId)
                {
                    Debug.WriteLine($"DEBUG: Stack update at {itemIndex}");
                    balanceSheet.AddTransaction(Transaction.StackUpdateSlot, item.type, item.stack - stackSize,
                                                item.prefix);
                }
                else
                {
                    balanceSheet.AddTransaction(Transaction.WorldSlot, item.type, item.stack - stackSize, item.prefix);
                }
                player.SetLastUpdatedItem(netItem);
            }
        }
예제 #8
0
 private void OnStrikeNpc(TSPlayer player)
 {
     if (player.TPlayer.coins)
     {
         var balanceSheet = player.GetOrCreateBalanceSheet();
         balanceSheet.ForgetDebit(ItemID.CopperCoin, 10_00_00);
     }
     if (player.TPlayer.setNebula)
     {
         var balanceSheet = player.GetOrCreateBalanceSheet();
         foreach (var itemId in NebulaBuffIdToItemId.Values)
         {
             if (balanceSheet.ForgetDebit(itemId, 1))
             {
                 break;
             }
         }
     }
 }
예제 #9
0
        private void OnRemoveProjectile(TSPlayer player, BinaryReader reader)
        {
            var identity = reader.ReadInt16();

            var projectile = Main.projectile.FirstOrDefault(
                p => p.active && p.identity == identity && p.owner == player.Index);

            if (projectile == null)
            {
                return;
            }

            // Handle rope coils, since they can actually create tiles.
            if (projectile.aiStyle == 35)
            {
                var balanceSheet = player.GetOrCreateBalanceSheet();
                balanceSheet.AddTransaction(
                    player.TPlayer.selectedItem, RopeCoilProjectileIdToRopeId[projectile.type], 10);
            }
            // Handle fishing poles being reeled in. Note that we don't actually check what item is on the hook, as that
            // can be done in a separate module.
            else if (projectile.aiStyle == 61)
            {
                var itemId = (int)projectile.ai[1];
                if (itemId <= 0)
                {
                    return;
                }

                var stackSize = 1;
                if (itemId == ItemID.BombFish)
                {
                    stackSize = player.TPlayer.FishingLevel() / 20 + 7;
                }
                else if (itemId == ItemID.FrostDaggerfish)
                {
                    stackSize = player.TPlayer.FishingLevel() / 4 + 31;
                }
                var balanceSheet = player.GetOrCreateBalanceSheet();
                balanceSheet.AddTransaction(Transaction.WorldSlot, itemId, stackSize);
            }
        }
예제 #10
0
        private void OnUpdateItemFrame(TSPlayer player, BinaryReader reader)
        {
            reader.ReadInt16();
            reader.ReadInt16();
            var itemId   = reader.ReadInt16();
            var prefixId = reader.ReadByte();

            var balanceSheet = player.GetOrCreateBalanceSheet();

            balanceSheet.AddTransaction(Transaction.WorldSlot, itemId, -1, prefixId);
        }
예제 #11
0
        private void OnSummon(TSPlayer player, BinaryReader reader)
        {
            reader.ReadInt16();
            var summonId = reader.ReadInt16();

            if (SummonIdToItemId.TryGetValue(summonId, out var itemId))
            {
                var balanceSheet = player.GetOrCreateBalanceSheet();
                balanceSheet.AddTransaction(Transaction.WorldSlot, itemId, -1);
            }
        }
예제 #12
0
        private void OnPaintTileOrWall(TSPlayer player, BinaryReader reader)
        {
            reader.ReadInt16();
            reader.ReadInt16();
            var paint = reader.ReadByte();

            var paintItem = _paintLookup[paint].FirstOrDefault();

            if (paintItem != null)
            {
                var balanceSheet = player.GetOrCreateBalanceSheet();
                balanceSheet.AddTransaction(Transaction.WorldSlot, paintItem.type, -1);
            }
        }
예제 #13
0
        private void OnUpdateNebula(TSPlayer player, BinaryReader reader)
        {
            reader.ReadByte();
            var buffId = reader.ReadByte();

            reader.ReadVector2();

            if (NebulaBuffIdToItemId.TryGetValue(buffId, out var itemId))
            {
                var balanceSheet = player.GetOrCreateBalanceSheet();
                // We give a debit of 2 since the player earns two credits of 1 from picking up the nebula booster.
                balanceSheet.AddTransaction(Transaction.WorldSlot, itemId, -2);
            }
        }
예제 #14
0
        private void OnReleaseNpc(TSPlayer player, BinaryReader reader)
        {
            reader.ReadInt32();
            reader.ReadInt32();
            var npcId = reader.ReadInt16();

            var npcItem = _createNpcLookup[npcId].FirstOrDefault();

            if (npcItem != null)
            {
                var balanceSheet = player.GetOrCreateBalanceSheet();
                balanceSheet.AddTransaction(Transaction.WorldSlot, npcItem.type, -1);
            }
        }
예제 #15
0
        private void OnUpdateProjectile(TSPlayer player, BinaryReader reader)
        {
            var identity = reader.ReadInt16();

            reader.ReadVector2();
            reader.ReadVector2();
            reader.ReadSingle();
            reader.ReadInt16();
            reader.ReadByte();
            var projectileId = reader.ReadInt16();

            var projectile = Main.projectile.FirstOrDefault(
                p => p.active && p.identity == identity && p.owner == player.Index);

            if (projectile != null)
            {
                return;
            }

            var projectileItem = _shootLookup[projectileId].FirstOrDefault();

            if (projectileItem != null && projectileItem.consumable)
            {
                var selectedItem = player.SelectedItem;
                // Don't debit the player if there are ammo reductions in place.
                if (ReducedAmmoItemIds.Contains(selectedItem.type))
                {
                    return;
                }

                var tplayer = player.TPlayer;
                if (selectedItem.useAmmo == AmmoID.Arrow && tplayer.magicQuiver)
                {
                    return;
                }
                if (projectileItem.ranged &&
                    (tplayer.ammoCost75 || tplayer.ammoCost80 || tplayer.ammoBox || tplayer.ammoPotion))
                {
                    return;
                }
                if (projectileItem.thrown && (tplayer.thrownCost33 || tplayer.thrownCost50))
                {
                    return;
                }

                var balanceSheet = player.GetOrCreateBalanceSheet();
                balanceSheet.AddTransaction(Transaction.WorldSlot, projectileItem.type, -1);
            }
        }
예제 #16
0
        private void OnPlaceObject(TSPlayer player, BinaryReader reader)
        {
            reader.ReadInt16();
            reader.ReadInt16();
            var createObject = reader.ReadInt16();
            var style        = reader.ReadInt16();

            var objectItem = _createTileLookup[createObject].FirstOrDefault(i => i.placeStyle == style);

            if (objectItem != null)
            {
                var balanceSheet = player.GetOrCreateBalanceSheet();
                balanceSheet.AddTransaction(Transaction.WorldSlot, objectItem.type, -1);
            }
        }
예제 #17
0
        private void OnStartOldOnesInvasion(TSPlayer player)
        {
            var balanceSheet = player.GetOrCreateBalanceSheet();

            balanceSheet.AddTransaction(Transaction.WorldSlot, ItemID.DD2ElderCrystal, -1);
        }