コード例 #1
0
        private void ParseInspectionList(Internal.ByteArray message)
        {
            bool isPlayer = message.ReadBoolean();

            int size = message.ReadUnsignedByte();

            for (int i = 0; i < size; i++)
            {
                var @object = ReadObjectInstance(message);
                if (isPlayer)
                {
                    var slot = message.ReadEnum <ClothSlots>();
                }


                int imbuementSlots = message.ReadUnsignedByte();
                for (int j = 0; j < imbuementSlots; j++)
                {
                    int imbuementID = message.ReadUnsignedByte();
                }

                int details = message.ReadUnsignedByte();
                for (int j = 0; j < details; j++)
                {
                    string name        = message.ReadString();
                    string description = message.ReadString();
                }
            }
        }
コード例 #2
0
ファイル: BuddyData.cs プロジェクト: Hengle/OpenTibia-Unity
        private void ParseBuddyAdd(Internal.ByteArray message)
        {
            uint   creatureID  = message.ReadUnsignedInt();
            string name        = message.ReadString();
            string desc        = string.Empty;
            uint   icon        = 0;
            bool   notifyLogin = false;

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameAdditionalVipInfo))
            {
                desc        = message.ReadString();
                icon        = message.ReadUnsignedInt();
                notifyLogin = message.ReadBoolean();
            }

            byte        status = message.ReadUnsignedByte();
            List <byte> groups;

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameBuddyGroups))
            {
                int count = message.ReadUnsignedByte();
                groups = new List <byte>(count);
                for (int i = 0; i < count; i++)
                {
                    groups.Add(message.ReadUnsignedByte());
                }
            }
        }
コード例 #3
0
        private void ParseBasicData(Internal.ByteArray message)
        {
            bool premium = message.ReadBoolean();

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GamePremiumExpiration))
            {
                uint premiumExpiration = message.ReadUnsignedInt();
            }

            byte vocation = message.ReadUnsignedByte();

            if (OpenTibiaUnity.GameManager.ClientVersion >= 1100)
            {
                bool hasReachedMain = message.ReadBoolean();
            }

            List <byte> spells      = new List <byte>();
            ushort      spellsCount = message.ReadUnsignedShort();

            for (int i = 0; i < spellsCount; i++)
            {
                spells.Add(message.ReadUnsignedByte());
            }

            if (Player)
            {
                //_player.PremiumStatus = premium;
                //_player.PremiumExpiration = premiumExpiration;
                //_player.Vocation = vocation;
                //_player.ReachedMain = hasReachedMain;
            }
        }
コード例 #4
0
        private void ParseMarketEnter(Internal.ByteArray message)
        {
            ulong balance;

            if (OpenTibiaUnity.GameManager.ClientVersion >= 981)
            {
                balance = message.ReadUnsignedLong();
            }
            else
            {
                balance = message.ReadUnsignedInt();
            }

            int vocation = -1;

            if (OpenTibiaUnity.GameManager.ClientVersion < 950)
            {
                vocation = message.ReadUnsignedByte();
            }

            int offers     = message.ReadUnsignedByte();
            int depotCount = message.ReadUnsignedByte();

            for (int i = 0; i < depotCount; i++)
            {
                message.ReadUnsignedShort(); // objectId
                message.ReadUnsignedShort(); // objectCount
            }
        }
コード例 #5
0
        private void ParseDeath(Internal.ByteArray message)
        {
            var deathType = DeathType.DeathTypeRegular;

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameDeathType))
            {
                deathType = (DeathType)message.ReadUnsignedByte();
            }

            int penalty = 100;

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GamePenalityOnDeath) && deathType == DeathType.DeathTypeRegular)
            {
                penalty = message.ReadUnsignedByte();
            }

            bool useDeathRedemption = false;

            if (OpenTibiaUnity.GameManager.ClientVersion >= 1120)
            {
                useDeathRedemption = message.ReadBoolean();
            }

            // TODO death actions...
            //LocalPlayer.OnDeath(deathType, penalty);
        }
コード例 #6
0
        private void ParseCreatureMarks(Internal.ByteArray message)
        {
            int length;

            if (OpenTibiaUnity.GameManager.ClientVersion >= 1035)
            {
                length = 1;
            }
            else
            {
                length = message.ReadUnsignedByte();
            }

            for (int i = 0; i < length; i++)
            {
                uint creatureId = message.ReadUnsignedInt();
                bool permenant  = message.ReadUnsignedByte() != 1;
                byte mark       = message.ReadUnsignedByte();

                var creature = CreatureStorage.GetCreature(creatureId);
                if (!!creature)
                {
                    creature.Marks.SetMark(permenant ? MarkType.Permenant : MarkType.OneSecondTemp, mark);
                    CreatureStorage.InvalidateOpponents();
                }
                else
                {
                    throw new System.Exception("ProtocolGame.ParseCreatureMarks: Unknown creature id: " + creatureId);
                }
            }
        }
コード例 #7
0
        private void ParsePlayerGoods(Internal.ByteArray message)
        {
            long money;

            if (OpenTibiaUnity.GameManager.ClientVersion >= 973)
            {
                money = message.ReadLong();
            }
            else
            {
                money = message.ReadInt();
            }

            var goods = new List <Container.InventoryTypeInfo>();

            int size = message.ReadUnsignedByte();

            for (int i = 0; i < size; i++)
            {
                ushort objectId = message.ReadUnsignedShort();
                int    amount   = message.ReadUnsignedByte();

                goods.Add(new Container.InventoryTypeInfo(objectId, 0, amount));
            }

            OpenTibiaUnity.ContainerStorage.PlayerGoods = goods;
            OpenTibiaUnity.ContainerStorage.PlayerMoney = money;
        }
コード例 #8
0
        private void ParseDeleteInContainer(Internal.ByteArray message)
        {
            byte   containerId = message.ReadUnsignedByte();
            ushort slot;

            Appearances.ObjectInstance appendObject = null;

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameContainerPagination))
            {
                slot = message.ReadUnsignedShort();
                ushort itemId = message.ReadUnsignedShort();

                if (itemId != 0)
                {
                    appendObject = ReadObjectInstance(message, itemId);
                }
            }
            else
            {
                slot = message.ReadUnsignedByte();
            }

            var containerView = ContainerStorage.GetContainerView(containerId);

            if (!!containerView)
            {
                containerView.RemoveObject(slot, appendObject);
            }
        }
コード例 #9
0
 private void ParsePreyPrices(Internal.ByteArray message)
 {
     message.ReadUnsignedInt(); // rerollPrice in gold
     if (OpenTibiaUnity.GameManager.ClientVersion >= 1190)
     {
         message.ReadUnsignedByte(); // unknown
         message.ReadUnsignedByte(); // selectCreatureDirectly in preyWildCards
     }
 }
コード例 #10
0
        private void ParseAmbientLight(Internal.ByteArray message)
        {
            int intensity = message.ReadUnsignedByte();
            int rawColor  = message.ReadUnsignedByte();

            var color = Colors.ColorFrom8Bit(rawColor);

            WorldMapStorage.SetAmbientLight(color, intensity);
        }
コード例 #11
0
        private void ParsePremiumTrigger(Internal.ByteArray message)
        {
            int triggers = message.ReadUnsignedByte();

            for (int i = 0; i < triggers; i++)
            {
                message.ReadUnsignedByte(); // trigger
                // TODO
            }
        }
コード例 #12
0
        private void ParseUpdateLootContainers(Internal.ByteArray message)
        {
            byte unknown = message.ReadUnsignedByte();
            int  count   = message.ReadUnsignedByte();

            for (int i = 0; i < count; i++)
            {
                var    type     = message.ReadEnum <ObjectCategory>();
                ushort objectId = message.ReadUnsignedShort();
            }
        }
コード例 #13
0
        private void ParseDailyRewardHistory(Internal.ByteArray message)
        {
            int count = message.ReadUnsignedByte();

            for (int i = 0; i < count; i++)
            {
                var timestamp = message.ReadUnsignedInt(); // timestamp
                message.ReadUnsignedByte();                // some state (0: none, 1: active[green])
                message.ReadString();                      // description
                message.ReadUnsignedShort();               // streak
            }
        }
コード例 #14
0
        private Creatures.Skill ReadSkill(Internal.ByteArray message, bool special = false)
        {
            int level;

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameDoubleSkills))
            {
                level = message.ReadUnsignedShort();
            }
            else
            {
                level = message.ReadUnsignedByte();
            }

            int baseLevel;

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameSkillsBase))
            {
                if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameBaseSkillU16))
                {
                    baseLevel = message.ReadUnsignedShort();
                }
                else
                {
                    baseLevel = message.ReadUnsignedByte();
                }
            }
            else
            {
                baseLevel = level;
            }

            if (!special && OpenTibiaUnity.GameManager.GetFeature(GameFeature.GamePercentSkillU16))
            {
                ushort loyaltyBonus = message.ReadUnsignedShort();
            }

            float percentage = 0.0f;

            if (!special)
            {
                if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GamePercentSkillU16))
                {
                    percentage = message.ReadUnsignedShort() / 100f;
                }
                else
                {
                    percentage = message.ReadUnsignedByte();
                }
            }

            return(new Creatures.Skill(level, baseLevel, percentage));
        }
コード例 #15
0
        private void ParseOpenContainer(Internal.ByteArray message)
        {
            byte   containerId     = message.ReadUnsignedByte();
            var    objectIcon      = ReadObjectInstance(message);
            string name            = message.ReadString();
            byte   nOfSlotsPerPage = message.ReadUnsignedByte(); // capacity of shown view
            bool   isSubContainer  = message.ReadBoolean();

            bool isDragAndDropEnabled = true;
            bool isPaginationEnabled  = false;
            int  nOfTotalObjects      = 0;
            int  indexOfFirstObject   = 0;
            int  nOfContentObjects    = 0; // objects in the current shown view //

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameContainerPagination))
            {
                isDragAndDropEnabled = message.ReadBoolean();
                isPaginationEnabled  = message.ReadBoolean();
                nOfTotalObjects      = message.ReadUnsignedShort();
                indexOfFirstObject   = message.ReadUnsignedShort();
                nOfContentObjects    = message.ReadUnsignedByte();

                if (nOfContentObjects > nOfSlotsPerPage)
                {
                    throw new System.Exception("ProtocolGame.ParseOpenContainer: Number of content objects " + nOfContentObjects + " exceeds number of slots per page " + nOfSlotsPerPage);
                }

                if (nOfContentObjects > nOfTotalObjects)
                {
                    throw new System.Exception("Connection.readSCONTAINER: Number of content objects " + nOfContentObjects + " exceeds number of total objects " + nOfTotalObjects);
                }
            }
            else
            {
                nOfContentObjects = message.ReadUnsignedByte();
                nOfTotalObjects   = nOfContentObjects;

                if (nOfContentObjects > nOfSlotsPerPage)
                {
                    throw new System.Exception("ProtocolGame.ParseOpenContainer: Number of content objects " + nOfContentObjects + " exceeds the capaciy " + nOfSlotsPerPage);
                }
            }

            var containerView = ContainerStorage.CreateContainerView(containerId, objectIcon, name, isSubContainer,
                                                                     isDragAndDropEnabled, isPaginationEnabled, nOfSlotsPerPage,
                                                                     nOfTotalObjects - nOfContentObjects, indexOfFirstObject);

            for (int i = 0; i < nOfContentObjects; i++)
            {
                containerView.AddObject(indexOfFirstObject + i, ReadObjectInstance(message));
            }
        }
コード例 #16
0
        private void ParseSetTactics(Internal.ByteArray message)
        {
            int attackMode = message.ReadUnsignedByte();
            int chaseMode  = message.ReadUnsignedByte();
            int secureMode = message.ReadUnsignedByte();
            int pvpMode    = message.ReadUnsignedByte();

            OpenTibiaUnity.GameManager.onTacticsChangeEvent.Invoke(
                (CombatAttackModes)attackMode,
                (CombatChaseModes)chaseMode,
                secureMode == 1,
                (CombatPvPModes)pvpMode);
        }
コード例 #17
0
ファイル: BuddyData.cs プロジェクト: Hengle/OpenTibia-Unity
        private void ParseBuddyGroupData(Internal.ByteArray message)
        {
            int groups = message.ReadUnsignedByte();

            for (int i = 0; i < groups; i++)
            {
                message.ReadUnsignedByte(); // id
                message.ReadString();       // name
                message.ReadUnsignedByte(); // idk
            }

            message.ReadUnsignedByte(); // premium/free iirc (since free players are allowed only for 5 groups)
        }
コード例 #18
0
        private void ParseMarketDetail(Internal.ByteArray message)
        {
            ushort objectId = message.ReadUnsignedShort();

            var last = MarketDetails.Weight;

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameImbuing))
            {
                last = MarketDetails.ImbuementSlots;
            }

            Dictionary <MarketDetails, string> details = new Dictionary <MarketDetails, string>();

            for (var i = MarketDetails.First; i <= last; i++)
            {
                int strLen = message.ReadUnsignedShort();
                if (strLen == 0)
                {
                    continue;
                }

                details.Add(i, message.ReadString(strLen));
            }

            int time  = DateTime.Now.Second / 1000 * Constants.SecondsPerDay;
            int ctime = time;

            int count = message.ReadUnsignedByte();

            for (int i = 0; i < count; i++)
            {
                uint transactions = message.ReadUnsignedInt();
                uint totalPrice   = message.ReadUnsignedInt();
                uint maximumPrice = message.ReadUnsignedInt();
                uint minimumPrice = message.ReadUnsignedInt();

                ctime -= Constants.SecondsPerDay;
            }

            ctime = time;
            count = message.ReadUnsignedByte();
            for (int i = 0; i < count; i++)
            {
                uint transactions = message.ReadUnsignedInt();
                uint totalPrice   = message.ReadUnsignedInt();
                uint maximumPrice = message.ReadUnsignedInt();
                uint minimumPrice = message.ReadUnsignedInt();

                ctime -= Constants.SecondsPerDay;
            }
        }
コード例 #19
0
ファイル: Trade.cs プロジェクト: Hengle/OpenTibia-Unity
        private void ParseNPCOffer(Internal.ByteArray message)
        {
            // todo, i believe tibia added extra data to detect currency

            string npcName = null;

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameNameOnNpcTrade))
            {
                npcName = message.ReadString();
            }

            var buyObjects  = new List <Trade.TradeObjectRef>();
            var sellObjects = new List <Trade.TradeObjectRef>();

            int listCount;

            if (OpenTibiaUnity.GameManager.ClientVersion >= 900)
            {
                listCount = message.ReadUnsignedShort();
            }
            else
            {
                listCount = message.ReadUnsignedByte();
            }

            for (int i = 0; i < listCount; i++)
            {
                ushort objectID   = message.ReadUnsignedShort();
                ushort objectData = message.ReadUnsignedByte();

                string name      = message.ReadString();
                uint   weight    = message.ReadUnsignedInt();
                uint   buyPrice  = message.ReadUnsignedInt();
                uint   sellPrice = message.ReadUnsignedInt();

                if (buyPrice > 0)
                {
                    buyObjects.Add(new Trade.TradeObjectRef(objectID, objectData, name, buyPrice, weight));
                }

                if (sellPrice > 0)
                {
                    sellObjects.Add(new Trade.TradeObjectRef(objectID, objectData, name, sellPrice, weight));
                }
            }

            OpenTibiaUnity.GameManager.onRequestNPCTrade.Invoke(npcName, buyObjects, sellObjects);
        }
コード例 #20
0
        private ObjectInstance ReadObjectInstance(Internal.ByteArray message, int id = -1)
        {
            if (id == -1)
            {
                id = message.ReadUnsignedShort();
            }

            if (id == 0)
            {
                return(null);
            }
            else if (id <= AppearanceInstance.Creature)
            {
                throw new System.Exception("ProtocolGameUtility.ReadObjectInstance: Invalid type (id = " + id + ")");
            }

            var @object = AppearanceStorage.CreateObjectInstance((uint)id, 0);

            if (!@object)
            {
                throw new System.Exception("ProtocolGameUtility.ReadObjectInstance: Invalid instance with id " + id);
            }

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameObjectMarks))
            {
                @object.Marks.SetMark(MarkType.Permenant, message.ReadUnsignedByte());
            }

            if (@object.Type.IsStackable || @object.Type.IsFluidContainer || @object.Type.IsSplash)
            {
                @object.Data = message.ReadUnsignedByte();
            }

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameItemAnimationPhase))
            {
                if (@object.Type.FrameGroups[(int)Protobuf.Shared.FrameGroupType.Idle].SpriteInfo.IsAnimation)
                {
                    int phase = message.ReadUnsignedByte();
                    @object.Phase = phase == 0 ? Constants.PhaseAutomatic : phase;
                }
            }

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameQuickLoot) && @object.Type.IsContainer)
            {
                message.ReadUnsignedByte(); // autolootIndex
            }
            return(@object);
        }
コード例 #21
0
        private void ParseResourceBalance(Internal.ByteArray message)
        {
            byte  type    = message.ReadUnsignedByte();
            ulong balance = message.ReadUnsignedLong();

            switch (type)
            {
            case (int)ResourceTypes.BankGold:
                //_player.BankGold = balance;
                break;

            case (int)ResourceTypes.InventoryGold:
                //_player.InventoryGold = balance;
                break;

            case (int)ResourceTypes.PreyBonusRerolls:
                if (!OpenTibiaUnity.GameManager.GetFeature(GameFeature.GamePrey))
                {
                    throw new System.Exception("ProtocolGame.ParseResourceBalance: Invalid resource type: " + type + ".");
                }
                //PreyManager.Insance.BonusRerollAmount = balance;
                break;

            case (int)ResourceTypes.CollectionTokens:
                if (!OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameRewardWall))
                {
                    throw new System.Exception("ProtocolGame.ParseResourceBalance: Invalid resource type: " + type + ".");
                }
                break;

            default:
                throw new System.Exception("ProtocolGame.ParseResourceBalance: Invalid resource type: " + type + ".");
            }
        }
コード例 #22
0
        private void ParseCancelWalk(Internal.ByteArray message)
        {
            int direction = message.ReadUnsignedByte();

            var absolutePosition = Player.Position;

            if (absolutePosition == _lastSnapback)
            {
                _snapbackCount++;
            }
            else
            {
                _snapbackCount = 0;
            }

            _lastSnapback.Set(absolutePosition.x, absolutePosition.y, absolutePosition.z);
            if (_snapbackCount >= 16)
            {
                Player.StopAutowalk(true);
                CreatureStorage.SetAttackTarget(null, false);
                SendCancel();
                _snapbackCount = 0;
            }

            Player.AbortAutowalk((Direction)direction);
        }
コード例 #23
0
        private void ParseOpenRewardWall(Internal.ByteArray message)
        {
            message.ReadBoolean();                                            // openedFromShrine
            message.ReadUnsignedInt();                                        // timestamp for the player to be able to take the reward (0 = able)
            message.ReadUnsignedByte();                                       // currentRewardIndex
            bool showWarningWhenCollecting = message.ReadUnsignedByte() != 0; // showWarningWhenCollecting

            if (showWarningWhenCollecting)
            {
                message.ReadString(); // warningMessage
            }

            message.ReadUnsignedInt();   // timestamp for the streak to expire (0 = won't expire until server save)
            message.ReadUnsignedShort(); // current streak
            message.ReadUnsignedShort(); // unknown
        }
コード例 #24
0
        public static uint CalculateAdler32Checksum(Internal.ByteArray byteArray, int offset = 0, int length = 0)
        {
            if (byteArray == null)
            {
                throw new ArgumentNullException("Adler32Checksum.CalculateAdler32Checksum: Invalid input.");
            }

            if (offset >= byteArray.Length)
            {
                throw new ArgumentOutOfRangeException("Adler32Checksum.CalculateAdler32Checksum: Invalid offset.");
            }

            uint a = 1;
            uint b = 0;
            int  i = 0;

            byteArray.Position = offset;
            while (byteArray.BytesAvailable > 0 && (length == 0 || i < length))
            {
                a = (a + byteArray.ReadUnsignedByte()) % ModAdler;
                b = (b + a) % ModAdler;
                i++;
            }

            a &= 65535;
            b &= 65535;
            return((b << 16) | a);
        }
コード例 #25
0
ファイル: Startup.cs プロジェクト: Hengle/OpenTibia-Unity
        private void ParseLoginWait(Internal.ByteArray message)
        {
            string waitMessage = message.ReadString();
            int    waitTime    = message.ReadUnsignedByte();

            onLoginWait.Invoke(waitMessage, waitTime);
        }
コード例 #26
0
ファイル: Startup.cs プロジェクト: Hengle/OpenTibia-Unity
        private void ParseGmActions(Internal.ByteArray message)
        {
            int numViolationReasons = 20;
            var clientVersion       = OpenTibiaUnity.GameManager.ClientVersion;

            if (clientVersion >= 850)
            {
                numViolationReasons = 20;
            }
            else if (clientVersion >= 840)
            {
                numViolationReasons = 23;
            }
            else
            {
                numViolationReasons = 32;
            }

            List <byte> actions = new List <byte>();

            for (int i = 0; i < numViolationReasons; i++)
            {
                actions.Add(message.ReadUnsignedByte());
            }
        }
コード例 #27
0
ファイル: Startup.cs プロジェクト: Hengle/OpenTibia-Unity
        private void ParseChallange(Internal.ByteArray message)
        {
            uint timestamp = message.ReadUnsignedInt();
            byte challange = message.ReadUnsignedByte();

            SendLogin(timestamp, challange);
            SetConnectionState(ConnectionState.ConnectingStage2, false);
        }
コード例 #28
0
        private void ParseTextEffect(Internal.ByteArray message)
        {
            var    position = message.ReadPosition();
            int    color    = message.ReadUnsignedByte();
            string text     = message.ReadString();

            WorldMapStorage.AddTextualEffect(position, color, text);
        }
コード例 #29
0
        private void ParseMarketBrowse(Internal.ByteArray message)
        {
            ushort var = message.ReadUnsignedShort(); // this must match the current object id

            int count = message.ReadUnsignedByte();

            for (int i = 0; i < count; i++)
            {
                ReadMarketOffer(message, MarketOfferTypes.Buy, var);
            }

            count = message.ReadUnsignedByte();
            for (int i = 0; i < count; i++)
            {
                ReadMarketOffer(message, MarketOfferTypes.Sell, var);
            }
        }
コード例 #30
0
        private void ParseCreateOnMap(Internal.ByteArray message)
        {
            var absolutePosition = message.ReadPosition();

            if (!WorldMapStorage.IsVisible(absolutePosition, true))
            {
                throw new System.Exception("ProtocolGame.ParseCreateOnMap: Co-ordinate " + absolutePosition + " is out of range.");
            }

            var mapPosition = WorldMapStorage.ToMap(absolutePosition);
            int stackPos    = 255;

            if (OpenTibiaUnity.GameManager.ClientVersion >= 841)
            {
                stackPos = message.ReadUnsignedByte();
            }

            int typeOrId = message.ReadUnsignedShort();

            Appearances.ObjectInstance @object;
            if (typeOrId == Appearances.AppearanceInstance.Creature || typeOrId == Appearances.AppearanceInstance.OutdatedCreature || typeOrId == Appearances.AppearanceInstance.UnknownCreature)
            {
                var creature = ReadCreatureInstance(message, typeOrId, absolutePosition);
                if (creature.Id == Player.Id)
                {
                    Player.StopAutowalk(true);
                }

                @object = AppearanceStorage.CreateObjectInstance(Appearances.AppearanceInstance.Creature, creature.Id);
            }
            else
            {
                @object = ReadObjectInstance(message, typeOrId);
            }

            if (stackPos == 255)
            {
                WorldMapStorage.PutObject(mapPosition, @object);
            }
            else
            {
                if (stackPos > Constants.MapSizeW)
                {
                    throw new System.Exception("ProtocolGame.ParseCreateOnMap: Invalid stack position (" + stackPos + ").");
                }

                WorldMapStorage.InsertObject(mapPosition, stackPos, @object);
            }

            if (absolutePosition.z == MiniMapStorage.PositionZ)
            {
                WorldMapStorage.UpdateMiniMap(mapPosition);
                uint color = WorldMapStorage.GetMiniMapColour(mapPosition);
                int  cost  = WorldMapStorage.GetMiniMapCost(mapPosition);
                MiniMapStorage.UpdateField(absolutePosition, color, cost, false);
            }
        }