public void AddBalloon(IFieldObject <InteractObject> balloon)
        {
            State.AddBalloon(balloon);

            Broadcast(session =>
            {
                session.Send(InteractObjectPacket.AddAdBallons(balloon));
            });
        }
Ejemplo n.º 2
0
 public void SetInteractObject(int[] interactObjectIds, byte state, bool arg4, bool arg3)
 {
     //This should be correct, but the current way of parsing interactObjects does not comply with triggerScripts. Needs changing.
     foreach (int interactObjectId in interactObjectIds)
     {
         //Field.State.InteractObjects[interactObjectId].Id = state
         Field.BroadcastPacket(InteractObjectPacket.ActivateInteractObject(interactObjectId));
     }
 }
Ejemplo n.º 3
0
    public void SetInteractObject(int[] interactObjectIds, byte state, bool arg4, bool arg3)
    {
        InteractObjectState objectState = (InteractObjectState)state;

        foreach (int interactObjectId in interactObjectIds)
        {
            InteractObject interactObject = Field.State.InteractObjects.Values.FirstOrDefault(x => x.InteractId == interactObjectId);
            if (interactObject == null)
            {
                continue;
            }
            interactObject.State = objectState;
            Field.BroadcastPacket(InteractObjectPacket.Set(interactObject));
        }
    }
        public void AddInteractObject(ICollection <IFieldObject <InteractObject> > objects)
        {
            foreach (IFieldObject <InteractObject> interactObject in objects)
            {
                State.AddInteractObject(interactObject);
            }

            if (objects.Count > 0)
            {
                Broadcast(session =>
                {
                    session.Send(InteractObjectPacket.AddInteractObjects(objects));
                });
            }
        }
Ejemplo n.º 5
0
        public static void HandleInstallBillBoard(GameSession session, PacketReader packet, Item item)
        {
            string[] parameters  = packet.ReadUnicodeString().Split("'");
            string   title       = parameters[0];
            string   description = parameters[1];
            bool     publicHouse = parameters[2].Equals("1");

            int       balloonUid = GuidGenerator.Int();
            string    id         = "AdBalloon_" + balloonUid.ToString();
            AdBalloon balloon    = new AdBalloon(id, item.Function.InstallBillboard.InteractId, InteractObjectState.Default, InteractObjectType.AdBalloon, session.FieldPlayer, item.Function.InstallBillboard, title, description, publicHouse);

            session.FieldManager.State.AddInteractObject(balloon);
            session.FieldManager.BroadcastPacket(InteractObjectPacket.LoadAdBallon(balloon));
            InventoryController.Consume(session, item.Uid, 1);
        }
Ejemplo n.º 6
0
        private static void HandleInteract(GameSession session, PacketReader packet)
        {
            string         id             = packet.ReadMapleString();
            InteractObject interactObject = session.FieldManager.State.InteractObjects[id];

            if (interactObject == null)
            {
                return;
            }

            InteractObjectMetadata metadata = InteractObjectMetadataStorage.GetInteractObjectMetadata(interactObject.InteractId);

            switch (interactObject.Type)
            {
            case InteractObjectType.Binoculars:
                session.Send(InteractObjectPacket.Use(interactObject));
                QuestHelper.UpdateExplorationQuest(session, interactObject.InteractId.ToString(), "interact_object_rep");
                break;

            case InteractObjectType.Ui:
                session.Send(InteractObjectPacket.Use(interactObject));
                break;

            case InteractObjectType.RankBoard:
                session.Send(WebOpenPacket.Open(metadata.Web.Url));
                break;

            case InteractObjectType.AdBalloon:
                session.Send(PlayerHostPacket.AdBalloonWindow((AdBalloon)interactObject));
                break;

            case InteractObjectType.Gathering:
                GatheringHelper.HandleGathering(session, metadata.Gathering.RecipeId, out int numDrop);
                session.Send(InteractObjectPacket.Use(interactObject, (short)(numDrop > 0 ? 0 : 1), numDrop));
                break;
            }

            session.Send(InteractObjectPacket.Interact(interactObject));
        }
        private static void HandleUse(GameSession session, PacketReader packet)
        {
            string uuid = packet.ReadMapleString();
            IFieldObject <InteractObject> interactObject = session.FieldManager.State.InteractObjects[uuid];

            if (interactObject == null)
            {
                return;
            }

            MapInteractObject mapObject = MapEntityStorage.GetInteractObject(session.Player.MapId).FirstOrDefault(x => x.Uuid == uuid);
            int numDrop = 0;

            switch (interactObject.Value.Type)
            {
            case InteractObjectType.Binoculars:
                QuestHelper.UpdateExplorationQuest(session, mapObject.InteractId.ToString(), "interact_object_rep");
                break;

            case InteractObjectType.Gathering:
                RecipeMetadata recipe = RecipeMetadataStorage.GetRecipe(mapObject.RecipeId);

                session.Player.Levels.GainMasteryExp((MasteryType)recipe.MasteryType, 0);
                long currentMastery = session.Player.Levels.MasteryExp.FirstOrDefault(x => x.Type == (MasteryType)recipe.MasteryType).CurrentExp;
                if (currentMastery < recipe.RequireMastery)
                {
                    return;
                }

                session.Player.IncrementGatheringCount(mapObject.RecipeId, 0);
                int numCount = session.Player.GatheringCount[mapObject.RecipeId].Current;

                List <RecipeItem> items = RecipeMetadataStorage.GetResult(recipe);
                int masteryDiffFactor   = numCount switch
                {
                    int n when n < recipe.HighPropLimitCount => MasteryFactorMetadataStorage.GetFactor(0),
                    int n when n < recipe.NormalPropLimitCount => MasteryFactorMetadataStorage.GetFactor(1),
                    int n when n < (int)(recipe.NormalPropLimitCount * 1.3) => MasteryFactorMetadataStorage.GetFactor(2),
                    _ => MasteryFactorMetadataStorage.GetFactor(3),
                };

                foreach (RecipeItem item in items)
                {
                    int prob = RarityChance[item.Rarity] * masteryDiffFactor / 10000;
                    if (RandomProvider.Get().Next(100) >= prob)
                    {
                        continue;
                    }
                    for (int i = 0; i < item.Amount; i++)
                    {
                        session.FieldManager.AddItem(session, new Item(item.Id));
                    }
                    numDrop += item.Amount;
                }
                if (numDrop > 0)
                {
                    session.Player.IncrementGatheringCount(mapObject.RecipeId, numDrop);
                    session.Player.Levels.GainMasteryExp((MasteryType)recipe.MasteryType, recipe.RewardMastery);
                }
                break;

            case InteractObjectType.AdBalloon:
                session.Send(PlayerHostPacket.AdBalloonWindow(interactObject));
                return;

            default:
                break;
            }
            session.Send(InteractObjectPacket.UseObject(mapObject, (short)(numDrop > 0 ? 0 : 1), numDrop));
            session.Send(InteractObjectPacket.Extra(mapObject));
        }
Ejemplo n.º 8
0
        private static void HandleUse(GameSession session, PacketReader packet)
        {
            string            uuid           = packet.ReadMapleString();
            MapInteractObject interactObject = MapEntityStorage.GetInteractObject(session.Player.MapId).FirstOrDefault(x => x.Uuid == uuid);
            int numDrop = 0;

            if (interactObject == null)
            {
                return;
            }
            if (interactObject.Type == InteractObjectType.Binoculars)
            {
                QuestHelper.UpdateExplorationQuest(session, interactObject.InteractId.ToString(), "interact_object_rep");
            }
            else if (interactObject.Type == InteractObjectType.Gathering)
            {
                RecipeMetadata    recipe         = RecipeMetadataStorage.GetRecipe(interactObject.RecipeId);
                long              requireMastery = int.Parse(recipe.RequireMastery);
                Enums.MasteryType type           = (Enums.MasteryType) int.Parse(recipe.MasteryType);

                session.Player.Levels.GainMasteryExp(type, 0);
                long currentMastery = session.Player.Levels.MasteryExp.FirstOrDefault(x => x.Type == type).CurrentExp;
                if (currentMastery < requireMastery)
                {
                    return;
                }

                session.Player.IncrementGatheringCount(interactObject.RecipeId, 0);
                int numCount = session.Player.GatheringCount[interactObject.RecipeId].Current;

                List <RecipeItem> items = RecipeMetadataStorage.GetResult(recipe);
                Random            rand  = new Random();
                int masteryDiffFactor   = numCount switch
                {
                    int n when n < recipe.HighPropLimitCount => MasteryFactorMetadataStorage.GetFactor(0),
                    int n when n < recipe.NormalPropLimitCount => MasteryFactorMetadataStorage.GetFactor(1),
                    int n when n < (int)(recipe.NormalPropLimitCount * 1.3) => MasteryFactorMetadataStorage.GetFactor(2),
                    _ => MasteryFactorMetadataStorage.GetFactor(3),
                };

                foreach (RecipeItem item in items)
                {
                    int prob = (int)(RarityChance[item.Rarity] * masteryDiffFactor) / 10000;
                    if (rand.Next(100) >= prob)
                    {
                        continue;
                    }
                    for (int i = 0; i < item.Amount; i++)
                    {
                        session.FieldManager.AddItem(session, new Item(item.Id));
                    }
                    numDrop += item.Amount;
                }
                if (numDrop > 0)
                {
                    session.Player.IncrementGatheringCount(interactObject.RecipeId, numDrop);
                    session.Player.Levels.GainMasteryExp(type, recipe.RewardMastery);
                }
            }
            session.Send(InteractObjectPacket.UseObject(interactObject, (short)(numDrop > 0 ? 0 : 1), numDrop));
            session.Send(InteractObjectPacket.Extra(interactObject));
        }
Ejemplo n.º 9
0
        public void AddPlayer(GameSession sender, IFieldObject <Player> player)
        {
            Debug.Assert(player.ObjectId > 0, "Player was added to field without initialized objectId.");
            player.Coord       = player.Value.Coord;
            player.Value.MapId = MapId;
            // TODO: Determine new coordinates for player as well
            lock (Sessions)
            {
                Sessions.Add(sender);
            }

            // TODO: Send the initialization state of the field
            foreach (IFieldObject <Player> existingPlayer in State.Players.Values)
            {
                sender.Send(FieldPacket.AddPlayer(existingPlayer));
                sender.Send(FieldObjectPacket.LoadPlayer(existingPlayer));
            }

            State.AddPlayer(player);
            // Broadcast new player to all players in map
            Broadcast(session =>
            {
                session.Send(FieldPacket.AddPlayer(player));
                session.Send(FieldObjectPacket.LoadPlayer(player));
            });

            foreach (IFieldObject <Item> existingItem in State.Items.Values)
            {
                sender.Send(FieldPacket.AddItem(existingItem, 123456));
            }
            foreach (IFieldObject <Npc> existingNpc in State.Npcs.Values)
            {
                sender.Send(FieldPacket.AddNpc(existingNpc));
                sender.Send(FieldObjectPacket.LoadNpc(existingNpc));
            }
            foreach (IFieldObject <Portal> existingPortal in State.Portals.Values)
            {
                sender.Send(FieldPacket.AddPortal(existingPortal));
            }
            foreach (IFieldObject <Mob> existingMob in State.Mobs.Values)
            {
                sender.Send(FieldPacket.AddMob(existingMob));
                sender.Send(FieldObjectPacket.LoadMob(existingMob));
            }

            if (player.Value.MapId == (int)Map.PrivateResidence && !player.Value.IsInDecorPlanner)
            {
                // Send function cubes
                List <Cube> functionCubes = State.Cubes.Values.Where(x => x.Value.PlotNumber == 1 &&
                                                                     (x.Value.Item.HousingCategory is ItemHousingCategory.Farming or ItemHousingCategory.Ranching))
                                            .Select(x => x.Value).ToList();

                if (functionCubes.Count > 0)
                {
                    sender.Send(FunctionCubePacket.SendCubes(functionCubes));
                }
            }

            foreach (IFieldObject <GuideObject> guide in State.Guide.Values)
            {
                sender.Send(GuideObjectPacket.Add(guide));
            }

            foreach (IFieldObject <HealingSpot> healingSpot in State.HealingSpots.Values)
            {
                sender.Send(RegionSkillPacket.Send(healingSpot.ObjectId, healingSpot.Value.Coord, new SkillCast(70000018, 1, 0, 1)));
            }

            foreach (IFieldObject <Instrument> instrument in State.Instruments.Values)
            {
                if (instrument.Value.Improvise)
                {
                    sender.Send(InstrumentPacket.StartImprovise(instrument));
                }
                else
                {
                    sender.Send(InstrumentPacket.PlayScore(instrument));
                }
            }

            List <BreakableObject> breakables = new List <BreakableObject>();

            breakables.AddRange(State.BreakableActors.Values.ToList());
            breakables.AddRange(State.BreakableNifs.Values.ToList());
            sender.Send(BreakablePacket.LoadBreakables(breakables));

            List <InteractObject> interactObjects = new List <InteractObject>();

            interactObjects.AddRange(State.InteractObjects.Values.Where(t => t is not AdBalloon).ToList());
            sender.Send(InteractObjectPacket.LoadInteractObject(interactObjects));

            List <AdBalloon> adBalloons = new List <AdBalloon>();

            adBalloons.AddRange(State.InteractObjects.Values.OfType <AdBalloon>().ToList());
            foreach (AdBalloon balloon in adBalloons)
            {
                sender.Send(InteractObjectPacket.LoadAdBallon(balloon));
            }

            List <TriggerObject> triggerObjects = new List <TriggerObject>();

            triggerObjects.AddRange(State.TriggerMeshes.Values.ToList());
            triggerObjects.AddRange(State.TriggerEffects.Values.ToList());
            triggerObjects.AddRange(State.TriggerCameras.Values.ToList());
            triggerObjects.AddRange(State.TriggerActors.Values.ToList());
            triggerObjects.AddRange(State.TriggerCubes.Values.ToList());
            triggerObjects.AddRange(State.TriggerLadders.Values.ToList());
            triggerObjects.AddRange(State.TriggerRopes.Values.ToList());
            triggerObjects.AddRange(State.TriggerSounds.Values.ToList());
            sender.Send(TriggerPacket.LoadTriggers(triggerObjects));

            if (MapLoopTask == null)
            {
                MapLoopTask = StartMapLoop(); //TODO: find a better place to initialise MapLoopTask
            }
        }
        public void AddPlayer(GameSession sender, IFieldObject <Player> player)
        {
            Debug.Assert(player.ObjectId > 0, "Player was added to field without initialized objectId.");
            player.Coord       = player.Value.Coord;
            player.Value.MapId = MapId;
            // TODO: Determine new coordinates for player as well
            lock (Sessions)
            {
                Sessions.Add(sender);
            }

            // TODO: Send the initialization state of the field
            foreach (IFieldObject <Player> existingPlayer in State.Players.Values)
            {
                sender.Send(FieldPacket.AddPlayer(existingPlayer));
                sender.Send(FieldObjectPacket.LoadPlayer(existingPlayer));
            }
            foreach (IFieldObject <Item> existingItem in State.Items.Values)
            {
                sender.Send(FieldPacket.AddItem(existingItem, 123456));
            }
            foreach (IFieldObject <Npc> existingNpc in State.Npcs.Values)
            {
                sender.Send(FieldPacket.AddNpc(existingNpc));
                sender.Send(FieldObjectPacket.LoadNpc(existingNpc));
            }
            foreach (IFieldObject <Portal> existingPortal in State.Portals.Values)
            {
                sender.Send(FieldPacket.AddPortal(existingPortal));
            }
            foreach (IFieldObject <Mob> existingMob in State.Mobs.Values)
            {
                sender.Send(FieldPacket.AddMob(existingMob));
                sender.Send(FieldObjectPacket.LoadMob(existingMob));
            }
            if (State.InteractObjects.Values.Count > 0)
            {
                ICollection <IFieldObject <InteractObject> > balloons = State.InteractObjects.Values.Where(x => x.Value.Type == InteractObjectType.AdBalloon).ToList();
                if (balloons.Count > 0)
                {
                    foreach (IFieldObject <InteractObject> balloon in balloons)
                    {
                        sender.Send(InteractObjectPacket.AddAdBallons(balloon));
                    }
                }
                ICollection <IFieldObject <InteractObject> > objects = State.InteractObjects.Values.Where(x => x.Value.Type != InteractObjectType.AdBalloon).ToList();
                if (objects.Count > 0)
                {
                    sender.Send(InteractObjectPacket.AddInteractObjects(objects));
                }
            }

            if (State.Cubes.IsEmpty && !player.Value.IsInDecorPlanner)
            {
                if (MapId == (int)Map.PrivateResidence)
                {
                    Home home = GameServer.HomeManager.GetHome(player.Value.VisitingHomeId);
                    if (home != null)
                    {
                        Dictionary <long, Cube> cubes = home.FurnishingInventory;
                        foreach (Cube cube in cubes.Values.Where(x => x.PlotNumber == 1))
                        {
                            IFieldObject <Cube> ugcCube = RequestFieldObject(cube);
                            ugcCube.Coord    = cube.CoordF;
                            ugcCube.Rotation = cube.Rotation;
                            State.AddCube(ugcCube);
                        }
                    }
                }
                else
                {
                    List <Home> homes = GameServer.HomeManager.GetPlots(MapId);
                    foreach (Home home in homes)
                    {
                        Dictionary <long, Cube> cubes = home.FurnishingInventory;
                        foreach (Cube cube in cubes.Values.Where(x => x.PlotNumber != 1))
                        {
                            IFieldObject <Cube> ugcCube = RequestFieldObject(cube);
                            ugcCube.Coord    = cube.CoordF;
                            ugcCube.Rotation = cube.Rotation;
                            State.AddCube(ugcCube);
                        }
                    }
                }
            }

            foreach (IFieldObject <GuideObject> guide in State.Guide.Values)
            {
                sender.Send(GuideObjectPacket.Add(guide));
            }

            foreach (IFieldObject <HealingSpot> healingSpot in State.HealingSpots.Values)
            {
                sender.Send(RegionSkillPacket.Send(healingSpot.ObjectId, healingSpot.Value.Coord, new SkillCast(70000018, 1, 0, 1)));
            }

            foreach (IFieldObject <Instrument> instrument in State.Instruments.Values)
            {
                if (instrument.Value.Improvise)
                {
                    sender.Send(InstrumentPacket.StartImprovise(instrument));
                }
                else
                {
                    sender.Send(InstrumentPacket.PlayScore(instrument));
                }
            }

            List <BreakableObject> breakables = new List <BreakableObject>();

            breakables.AddRange(State.BreakableActors.Values.ToList());
            breakables.AddRange(State.BreakableNifs.Values.ToList());
            sender.Send(BreakablePacket.LoadBreakables(breakables));

            List <TriggerObject> triggerObjects = new List <TriggerObject>();

            triggerObjects.AddRange(State.TriggerMeshes.Values.ToList());
            triggerObjects.AddRange(State.TriggerEffects.Values.ToList());
            triggerObjects.AddRange(State.TriggerCameras.Values.ToList());
            triggerObjects.AddRange(State.TriggerActors.Values.ToList());
            triggerObjects.AddRange(State.TriggerCubes.Values.ToList());
            triggerObjects.AddRange(State.TriggerLadders.Values.ToList());
            triggerObjects.AddRange(State.TriggerRopes.Values.ToList());
            triggerObjects.AddRange(State.TriggerSounds.Values.ToList());
            sender.Send(TriggerPacket.LoadTriggers(triggerObjects));
            State.AddPlayer(player);

            if (MapLoopTask == null)
            {
                MapLoopTask = StartMapLoop(); //TODO: find a better place to initialise MapLoopTask
            }

            // Broadcast new player to all players in map
            Broadcast(session =>
            {
                session.Send(FieldPacket.AddPlayer(player));
                session.Send(FieldObjectPacket.LoadPlayer(player));
            });
        }
    private static void HandleInteract(GameSession session, PacketReader packet)
    {
        Player player = session.Player;

        string id = packet.ReadString();

        session.FieldManager.State.InteractObjects.TryGetValue(id, out IFieldObject <InteractObject> fieldInteractObject);
        if (fieldInteractObject is null)
        {
            return;
        }

        InteractObject interactObject = fieldInteractObject.Value;

        InteractObjectMetadata metadata = InteractObjectMetadataStorage.GetInteractObjectMetadata(interactObject.InteractId);

        QuestManager.OnInteractObject(player, interactObject.InteractId);

        switch (interactObject.Type)
        {
        case InteractObjectType.Binoculars:
            session.Send(InteractObjectPacket.Use(interactObject));
            break;

        case InteractObjectType.Ui:
            session.Send(InteractObjectPacket.Use(interactObject));
            break;

        case InteractObjectType.RankBoard:
            session.Send(WebOpenPacket.Open(metadata.Web.Url));
            break;

        case InteractObjectType.AdBalloon:
            session.Send(PlayerHostPacket.AdBalloonWindow((AdBalloon)interactObject));
            break;

        case InteractObjectType.Gathering:
            GatheringHelper.HandleGathering(session, metadata.Gathering.RecipeId, out int numDrop);
            session.Send(InteractObjectPacket.Use(interactObject, (short)(numDrop > 0 ? 0 : 1), numDrop));
            break;

        case InteractObjectType.Common:
            // Unsure if all interact objects need to be set as disabled.
            interactObject.State = InteractObjectState.Disable;

            session.Send(InteractObjectPacket.Update(interactObject));
            session.Send(InteractObjectPacket.Interact(interactObject));

            foreach ((int questId, QuestState state) in metadata.Quests)
            {
                if (!player.QuestData.TryGetValue(questId, out QuestStatus questStatus) || questStatus.State != state)
                {
                    continue;
                }

                interactObject.State = InteractObjectState.Activated;
                session.Send(InteractObjectPacket.Update(interactObject));
            }

            DropItems();

            TrophyManager.OnObjectInteract(player, interactObject.InteractId);

            if (interactObject is MapChest)
            {
                // Unsure if setting as activated is specific of map chests
                interactObject.State = InteractObjectState.Activated;

                // Delayed removal of the chest
                Task.Run(async() =>
                {
                    await Task.Delay(TimeSpan.FromSeconds(10));
                    session.FieldManager.State.RemoveInteractObject(interactObject.Id);

                    session.FieldManager.BroadcastPacket(InteractObjectPacket.Update(interactObject));
                    session.FieldManager.BroadcastPacket(InteractObjectPacket.Remove(interactObject));
                });
            }

            return;
        }

        session.Send(InteractObjectPacket.Interact(interactObject));

        void DropItems()
        {
            foreach (int boxId in metadata.Drop.IndividualDropBoxId)
            {
                ItemDropMetadata itemDropMetadataStorage = ItemDropMetadataStorage.GetItemDropMetadata(boxId);
                if (itemDropMetadataStorage is null)
                {
                    continue;
                }

                foreach (DropGroup dropGroup in itemDropMetadataStorage.DropGroups)
                {
                    foreach (DropGroupContent dropGroupContent in dropGroup.Contents)
                    {
                        foreach (int itemId in dropGroupContent.ItemIds)
                        {
                            int  amount = Random.Shared.Next((int)dropGroupContent.MinAmount, (int)dropGroupContent.MaxAmount);
                            Item item   = new(itemId, amount, dropGroupContent.Rarity);

                            session.FieldManager.AddItem(session.Player.FieldPlayer, item);
                        }
                    }
                }
            }

            foreach (int boxId in metadata.Drop.GlobalDropBoxId)
            {
                ItemDropMetadata itemDropMetadataStorage = ItemDropMetadataStorage.GetItemDropMetadata(boxId);
                if (itemDropMetadataStorage is null)
                {
                    continue;
                }

                foreach (DropGroup dropGroup in itemDropMetadataStorage.DropGroups)
                {
                    foreach (DropGroupContent dropGroupContent in dropGroup.Contents)
                    {
                        foreach (int itemId in dropGroupContent.ItemIds)
                        {
                            int  amount = Random.Shared.Next((int)dropGroupContent.MinAmount, (int)dropGroupContent.MaxAmount);
                            Item item   = new(itemId, amount, dropGroupContent.Rarity);

                            session.FieldManager.AddItem(session.Player.FieldPlayer, item);
                        }
                    }
                }
            }
        }
    }
Ejemplo n.º 12
0
        public void AddPlayer(GameSession sender, IFieldObject <Player> player)
        {
            Debug.Assert(player.ObjectId > 0, "Player was added to field without initialized objectId.");
            player.Coord       = player.Value.Coord;
            player.Value.MapId = MapId;
            // TODO: Determine new coordinates for player as well
            lock (Sessions)
            {
                Sessions.Add(sender);
            }

            // TODO: Send the initialization state of the field
            foreach (IFieldObject <Player> existingPlayer in State.Players.Values)
            {
                sender.Send(FieldPacket.AddPlayer(existingPlayer));
                sender.Send(FieldObjectPacket.LoadPlayer(existingPlayer));
            }
            foreach (IFieldObject <Item> existingItem in State.Items.Values)
            {
                sender.Send(FieldPacket.AddItem(existingItem, 123456));
            }
            foreach (IFieldObject <Npc> existingNpc in State.Npcs.Values)
            {
                sender.Send(FieldPacket.AddNpc(existingNpc));
                sender.Send(FieldObjectPacket.LoadNpc(existingNpc));
            }
            foreach (IFieldObject <Portal> existingPortal in State.Portals.Values)
            {
                sender.Send(FieldPacket.AddPortal(existingPortal));
            }
            foreach (IFieldObject <Mob> existingMob in State.Mobs.Values)
            {
                sender.Send(FieldPacket.AddMob(existingMob));
                sender.Send(FieldObjectPacket.LoadMob(existingMob));
            }
            if (State.InteractObjects.Values.Count > 0)
            {
                ICollection <IFieldObject <InteractObject> > balloons = State.InteractObjects.Values.Where(x => x.Value.Type == InteractObjectType.AdBalloon).ToList();
                if (balloons.Count > 0)
                {
                    foreach (IFieldObject <InteractObject> balloon in balloons)
                    {
                        sender.Send(InteractObjectPacket.AddAdBallons(balloon));
                    }
                }
                ICollection <IFieldObject <InteractObject> > objects = State.InteractObjects.Values.Where(x => x.Value.Type != InteractObjectType.AdBalloon).ToList();
                if (objects.Count > 0)
                {
                    sender.Send(InteractObjectPacket.AddInteractObjects(objects));
                }
            }
            if (State.Cubes.Values.Count > 0)
            {
                sender.Send(CubePacket.LoadCubes(State.Cubes.Values));
            }
            foreach (IFieldObject <GuideObject> guide in State.Guide.Values)
            {
                sender.Send(GuideObjectPacket.Add(guide));
            }

            foreach (IFieldObject <HealingSpot> healingSpot in State.HealingSpots.Values)
            {
                sender.Send(RegionSkillPacket.Send(healingSpot.ObjectId, healingSpot.Value.Coord, new SkillCast(70000018, 1, 0, 1)));
            }

            foreach (IFieldObject <Instrument> instrument in State.Instruments.Values)
            {
                if (instrument.Value.Improvise)
                {
                    sender.Send(InstrumentPacket.StartImprovise(instrument));
                }
                else
                {
                    sender.Send(InstrumentPacket.PlayScore(instrument));
                }
            }

            State.AddPlayer(player);

            if (!State.HealingSpots.IsEmpty)
            {
                if (HealingSpotThread == null)
                {
                    HealingSpotThread = StartHealingSpot();
                }
            }

            // Broadcast new player to all players in map
            Broadcast(session =>
            {
                session.Send(FieldPacket.AddPlayer(player));
                session.Send(FieldObjectPacket.LoadPlayer(player));
            });
        }