Пример #1
0
 private static void HandleLeaveEnsemble(GameSession session)
 {
     session.FieldManager.BroadcastPacket(InstrumentPacket.StopScore(session.Player.Instrument));
     session.FieldManager.RemoveInstrument(session.Player.Instrument);
     session.Player.Instrument = null;
     session.Send(InstrumentPacket.LeaveEnsemble());
 }
Пример #2
0
        private static void HandlePlayScore(GameSession session, PacketReader packet)
        {
            long instrumentItemUid = packet.ReadLong();
            long scoreItemUid      = packet.ReadLong();

            if (!session.Player.Inventory.Items.ContainsKey(scoreItemUid) || !session.Player.Inventory.Items.ContainsKey(instrumentItemUid))
            {
                return;
            }

            Item instrument = session.Player.Inventory.Items[instrumentItemUid];

            InsturmentInfoMetadata         instrumentInfo     = InstrumentInfoMetadataStorage.GetMetadata(instrument.Function.Id);
            InstrumentCategoryInfoMetadata instrumentCategory = InstrumentCategoryInfoMetadataStorage.GetMetadata(instrumentInfo.Category);

            Item score = session.Player.Inventory.Items[scoreItemUid];

            if (score.PlayCount <= 0)
            {
                return;
            }

            score.PlayCount -= 1;

            session.FieldManager.BroadcastPacket(InstrumentPacket.PlayScore(session, score, instrumentCategory.GMId, instrumentCategory.PercussionId));
            session.Send(InstrumentPacket.UpdateScoreUses(scoreItemUid, score.PlayCount));
        }
        private static void HandleStartImprovise(GameSession session, PacketReader packet)
        {
            long itemUid = packet.ReadLong();

            // TODO: Verify if item is an (playable) instrument

            session.FieldManager.BroadcastPacket(InstrumentPacket.StartImprovise(session.FieldPlayer));
        }
Пример #4
0
    private static void HandleStopScore(GameSession session)
    {
        int masteryExpGain = (session.ServerTick - session.Player.Instrument.Value.InstrumentTick) / 1000;

        // TODO: Find any exp cap
        session.Player.Levels.GainMasteryExp(MasteryType.Performance, masteryExpGain);
        session.FieldManager.BroadcastPacket(InstrumentPacket.StopScore(session.Player.Instrument));
        session.FieldManager.RemoveInstrument(session.Player.Instrument);
        session.Player.Instrument = null;
    }
Пример #5
0
    private static void HandleStopImprovise(GameSession session)
    {
        if (session.Player.Instrument == null)
        {
            return;
        }

        session.FieldManager.BroadcastPacket(InstrumentPacket.StopImprovise(session.Player.FieldPlayer));
        session.FieldManager.RemoveInstrument(session.Player.Instrument);
        session.Player.Instrument = null;
    }
Пример #6
0
        private static void HandleStartImprovise(GameSession session, PacketReader packet)
        {
            long itemUid = packet.ReadLong();

            if (!session.Player.Inventory.Items.ContainsKey(itemUid))
            {
                return;
            }

            Item item = session.Player.Inventory.Items[itemUid];

            InsturmentInfoMetadata         instrument         = InstrumentInfoMetadataStorage.GetMetadata(item.Function.Id);
            InstrumentCategoryInfoMetadata instrumentCategory = InstrumentCategoryInfoMetadataStorage.GetMetadata(instrument.Category);

            session.FieldManager.BroadcastPacket(InstrumentPacket.StartImprovise(session.FieldPlayer, instrumentCategory.GMId));
        }
Пример #7
0
    private static void HandleStopScore(GameSession session)
    {
        // get Mastery exp
        ItemMusicMetadata metadata = ItemMetadataStorage.GetMetadata(session.Player.Instrument.Value.Score.Id)?.Music;
        int masteryExpGain         = Math.Min(((session.ServerTick - session.Player.Instrument.Value.InstrumentTick) * metadata.MasteryValue) / 1000, metadata.MasteryValueMax);

        session.Player.Levels.GainMasteryExp(MasteryType.Performance, masteryExpGain);

        // get prestige exp
        int prestigeExpGain = (session.ServerTick - session.Player.Instrument.Value.InstrumentTick) / 1000 * 250;

        session.Player.Levels.GainPrestigeExp(prestigeExpGain);

        //TODO: get exp for normal level

        // remove instrument from field
        session.FieldManager.BroadcastPacket(InstrumentPacket.StopScore(session.Player.Instrument));
        session.FieldManager.RemoveInstrument(session.Player.Instrument);
        session.Player.Instrument = null;
    }
        private static void HandlePlayScore(GameSession session, PacketReader packet)
        {
            long instrumentItemUid = packet.ReadLong();
            long scoreItemUid      = packet.ReadLong();

            if (!session.Player.Inventory.Items.ContainsKey(scoreItemUid))
            {
                return;
            }

            Item score = session.Player.Inventory.Items[scoreItemUid];

            if (score.PlayCount <= 0)
            {
                return;
            }

            score.PlayCount -= 1;

            session.Send(InstrumentPacket.PlayScore(session.FieldPlayer, score.FileName));
            session.FieldManager.BroadcastPacket(InstrumentPacket.PlayScore(session.FieldPlayer, score.FileName));
            session.Send(InstrumentPacket.UpdateScoreUses(scoreItemUid, score.PlayCount));
        }
Пример #9
0
        private static void HandleCompose(GameSession session, PacketReader packet)
        {
            long   itemUid        = packet.ReadLong();
            int    length         = packet.ReadInt();
            int    instrumentType = packet.ReadInt();
            string scoreName      = packet.ReadUnicodeString();
            string scoreNotes     = packet.ReadMapleString();

            if (!session.Player.Inventory.Items.ContainsKey(itemUid))
            {
                return;
            }

            Item item = session.Player.Inventory.Items[itemUid];

            item.Score.Length              = length;
            item.Score.Type                = instrumentType;
            item.Score.Title               = scoreName;
            item.Score.Composer            = session.Player.Name;
            item.Score.ComposerCharacterId = session.Player.CharacterId;
            item.Score.Notes               = scoreNotes;

            session.Send(InstrumentPacket.Compose(item));
        }
Пример #10
0
    private static void HandleStartImprovise(GameSession session, PacketReader packet)
    {
        long itemUid = packet.ReadLong();

        if (!session.Player.Inventory.HasItem(itemUid))
        {
            return;
        }

        Item item = session.Player.Inventory.GetByUid(itemUid);

        InstrumentInfoMetadata         instrumentInfo     = InstrumentInfoMetadataStorage.GetMetadata(item.Function.Id);
        InstrumentCategoryInfoMetadata instrumentCategory = InstrumentCategoryInfoMetadataStorage.GetMetadata(instrumentInfo.Category);

        Instrument instrument = new(instrumentCategory.GMId, instrumentCategory.PercussionId, false, session.Player.FieldPlayer.ObjectId)
        {
            Improvise = true
        };

        session.Player.Instrument       = session.FieldManager.RequestFieldObject(instrument);
        session.Player.Instrument.Coord = session.Player.FieldPlayer.Coord;
        session.FieldManager.AddInstrument(session.Player.Instrument);
        session.FieldManager.BroadcastPacket(InstrumentPacket.StartImprovise(session.Player.Instrument));
    }
Пример #11
0
    private static void HandlePlayScore(GameSession session, PacketReader packet)
    {
        long instrumentItemUid = packet.ReadLong();
        long scoreItemUid      = packet.ReadLong();

        if (!session.Player.Inventory.HasItem(scoreItemUid) || !session.Player.Inventory.HasItem(instrumentItemUid))
        {
            return;
        }

        Item instrumentItem = session.Player.Inventory.GetByUid(instrumentItemUid);

        InstrumentInfoMetadata         instrumentInfo     = InstrumentInfoMetadataStorage.GetMetadata(instrumentItem.Function.Id);
        InstrumentCategoryInfoMetadata instrumentCategory = InstrumentCategoryInfoMetadataStorage.GetMetadata(instrumentInfo.Category);

        Item score = session.Player.Inventory.GetByUid(scoreItemUid);

        if (score.PlayCount <= 0)
        {
            return;
        }

        Instrument instrument = new(instrumentCategory.GMId, instrumentCategory.PercussionId, score.IsCustomScore, session.Player.FieldPlayer.ObjectId)
        {
            InstrumentTick = session.ServerTick,
            Score          = score,
            Improvise      = false
        };

        score.PlayCount                -= 1;
        session.Player.Instrument       = session.FieldManager.RequestFieldObject(instrument);
        session.Player.Instrument.Coord = session.Player.FieldPlayer.Coord;
        session.FieldManager.AddInstrument(session.Player.Instrument);
        session.FieldManager.BroadcastPacket(InstrumentPacket.PlayScore(session.Player.Instrument));
        session.Send(InstrumentPacket.UpdateScoreUses(scoreItemUid, score.PlayCount));
    }
 private static void HandleFireworks(GameSession session)
 {
     session.Send(InstrumentPacket.Fireworks(session.FieldPlayer.ObjectId));
 }
 private static void HandleStopScore(GameSession session, PacketReader packet)
 {
     session.Send(InstrumentPacket.StopScore(session.FieldPlayer));
     session.FieldManager.BroadcastPacket(InstrumentPacket.StopScore(session.FieldPlayer));
 }
 private static void HandleStopImprovise(GameSession session)
 {
     session.FieldManager.BroadcastPacket(InstrumentPacket.StopImprovise(session.FieldPlayer));
 }
Пример #15
0
    private static void HandleStartEnsemble(GameSession session, PacketReader packet)
    {
        long instrumentItemUid = packet.ReadLong();
        long scoreItemUid      = packet.ReadLong();

        Party party = session.Player.Party;

        if (party == null)
        {
            return;
        }

        if (!session.Player.Inventory.HasItem(scoreItemUid) || !session.Player.Inventory.HasItem(instrumentItemUid))
        {
            return;
        }


        Item score = session.Player.Inventory.GetByUid(scoreItemUid);

        if (score.PlayCount <= 0)
        {
            return;
        }

        Item instrumentItem = session.Player.Inventory.GetByUid(instrumentItemUid);
        InstrumentInfoMetadata         instrumentInfo     = InstrumentInfoMetadataStorage.GetMetadata(instrumentItem.Function.Id);
        InstrumentCategoryInfoMetadata instrumentCategory = InstrumentCategoryInfoMetadataStorage.GetMetadata(instrumentInfo.Category);
        Instrument instrument = new(instrumentCategory.GMId, instrumentCategory.PercussionId, score.IsCustomScore, session.Player.FieldPlayer.ObjectId)
        {
            Score     = score,
            Ensemble  = true,
            Improvise = false
        };

        session.Player.Instrument       = session.FieldManager.RequestFieldObject(instrument);
        session.Player.Instrument.Coord = session.Player.FieldPlayer.Coord;

        if (session.Player != party.Leader)
        {
            return;
        }

        int instrumentTick = session.ServerTick;

        foreach (Player member in party.Members)
        {
            if (member.Instrument == null)
            {
                continue;
            }

            if (!member.Instrument.Value.Ensemble)
            {
                continue;
            }

            member.Instrument.Value.InstrumentTick = instrumentTick; // set the tick to be all the same
            member.Session.FieldManager.AddInstrument(member.Session.Player.Instrument);
            session.FieldManager.BroadcastPacket(InstrumentPacket.PlayScore(member.Session.Player.Instrument));
            member.Instrument.Value.Score.PlayCount -= 1;
            member.Session.Send(InstrumentPacket.UpdateScoreUses(member.Instrument.Value.Score.Uid, member.Instrument.Value.Score.PlayCount));
            member.Instrument.Value.Ensemble = false;
        }
    }
        private static void HandlePlayNote(GameSession session, PacketReader packet)
        {
            int note = packet.ReadInt();

            session.FieldManager.BroadcastPacket(InstrumentPacket.PlayNote(note, session.FieldPlayer));
        }
        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));
            });
        }
Пример #18
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
            }
        }
Пример #19
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));
            });
        }