Exemple #1
0
 /// <summary>
 ///     Remove the current Target from Npc.
 /// </summary>
 internal void RemoveTarget()
 {
     Target = null;
     Path   = BestFirstSearch.FindPathJagged(new Node {
         X = MapX, Y = MapY
     }, new Node {
         X = FirstX, Y = FirstY
     },
                                             MapInstance.Map.Grid); // Path To origins
 }
Exemple #2
0
        /// <summary>
        /// Remove the current Target from Npc.
        /// </summary>
        internal void RemoveTarget()
        {
            if (Target != -1)
            {
                Path.Clear();
                Target = -1;

                //return to origin
                Path = BestFirstSearch.FindPathJagged(new Node {
                    X = MapX, Y = MapY
                }, new Node {
                    X = FirstX, Y = FirstY
                }, MapInstance.Map.JaggedGrid);
            }
        }
Exemple #3
0
        /// <summary>
        ///     Remove the current Target from Monster.
        /// </summary>
        internal void RemoveTarget()
        {
            GetNearestOponent();
            if (Target != null)
            {
                Path.Clear();
                return;
            }

            Path = BestFirstSearch.FindPathJagged(new Node {
                X = MapX, Y = MapY
            }, new Node {
                X = FirstX, Y = FirstY
            },
                                                  MapInstance.Map.Grid); // Path To origins
        }
Exemple #4
0
        public void RunEvent(EventContainer evt, ClientSession session = null, MapMonster monster = null)
        {
            if (evt != null)
            {
                if (session != null)
                {
                    evt.MapInstance = session.CurrentMapInstance;
                    switch (evt.EventActionType)
                    {
                        #region EventForUser

                    case EventActionType.NPCDIALOG:
                        session.SendPacket(session.Character.GenerateNpcDialog((int)evt.Parameter));
                        break;

                    case EventActionType.SENDPACKET:
                        session.SendPacket((string)evt.Parameter);
                        break;

                        #endregion
                    }
                }
                if (evt.MapInstance != null)
                {
                    switch (evt.EventActionType)
                    {
                        #region EventForUser

                    case EventActionType.NPCDIALOG:
                    case EventActionType.SENDPACKET:
                        if (session == null)
                        {
                            evt.MapInstance.Sessions.ToList().ForEach(e => RunEvent(evt, e));
                        }
                        break;

                        #endregion

                        #region MapInstanceEvent

                    case EventActionType.REGISTEREVENT:
                        Tuple <string, List <EventContainer> > even = (Tuple <string, List <EventContainer> >)evt.Parameter;
                        switch (even.Item1)
                        {
                        case "OnCharacterDiscoveringMap":
                            even.Item2.ForEach(s => evt.MapInstance.OnCharacterDiscoveringMapEvents.Add(new Tuple <EventContainer, List <long> >(s, new List <long>())));
                            break;

                        case "OnMoveOnMap":
                            evt.MapInstance.OnMoveOnMapEvents.AddRange(even.Item2);
                            break;

                        case "OnMapClean":
                            evt.MapInstance.OnMapClean.AddRange(even.Item2);
                            break;

                        case "OnLockerOpen":
                            evt.MapInstance.UnlockEvents.AddRange(even.Item2);
                            break;
                        }
                        break;

                    case EventActionType.REGISTERWAVE:
                        evt.MapInstance.WaveEvents.Add((EventWave)evt.Parameter);
                        break;

                    case EventActionType.SETAREAENTRY:
                        ZoneEvent even2 = (ZoneEvent)evt.Parameter;
                        evt.MapInstance.OnAreaEntryEvents.Add(even2);
                        break;

                    case EventActionType.REMOVEMONSTERLOCKER:
                        EventContainer evt2 = (EventContainer)evt.Parameter;
                        if (evt.MapInstance.InstanceBag.MonsterLocker.Current > 0)
                        {
                            evt.MapInstance.InstanceBag.MonsterLocker.Current--;
                        }
                        if (evt.MapInstance.InstanceBag.MonsterLocker.Current == 0 && evt.MapInstance.InstanceBag.ButtonLocker.Current == 0)
                        {
                            evt.MapInstance.UnlockEvents.ForEach(s => RunEvent(s));
                            evt.MapInstance.UnlockEvents.RemoveAll(s => s != null);
                        }
                        break;

                    case EventActionType.REMOVEBUTTONLOCKER:
                        evt2 = (EventContainer)evt.Parameter;
                        if (evt.MapInstance.InstanceBag.ButtonLocker.Current > 0)
                        {
                            evt.MapInstance.InstanceBag.ButtonLocker.Current--;
                        }
                        if (evt.MapInstance.InstanceBag.MonsterLocker.Current == 0 && evt.MapInstance.InstanceBag.ButtonLocker.Current == 0)
                        {
                            evt.MapInstance.UnlockEvents.ForEach(s => RunEvent(s));
                            evt.MapInstance.UnlockEvents.RemoveAll(s => s != null);
                        }
                        break;

                    case EventActionType.EFFECT:
                        short evt3 = (short)evt.Parameter;
                        if (monster != null)
                        {
                            monster.LastEffect = DateTime.Now;
                            evt.MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Monster, monster.MapMonsterId, evt3));
                        }
                        break;

                    case EventActionType.CONTROLEMONSTERINRANGE:
                        if (monster != null)
                        {
                            Tuple <short, byte, List <EventContainer> > evnt = (Tuple <short, byte, List <EventContainer> >)evt.Parameter;
                            List <MapMonster> MapMonsters = evt.MapInstance.GetListMonsterInRange(monster.MapX, monster.MapY, evnt.Item2);
                            if (evnt.Item1 != 0)
                            {
                                MapMonsters.RemoveAll(s => s.MonsterVNum != evnt.Item1);
                            }
                            MapMonsters.ForEach(s => evnt.Item3.ForEach(e => RunEvent(e, monster: s)));
                        }
                        break;

                    case EventActionType.ONTARGET:
                        if (monster.MoveEvent?.InZone(monster.MapX, monster.MapY) == true)
                        {
                            monster.MoveEvent = null;
                            monster.Path      = new List <Node>();
                            ((List <EventContainer>)evt.Parameter).ForEach(s => RunEvent(s, monster: monster));
                        }
                        break;

                    case EventActionType.MOVE:
                        ZoneEvent evt4 = (ZoneEvent)evt.Parameter;
                        if (monster != null)
                        {
                            monster.MoveEvent = evt4;
                            monster.Path      = BestFirstSearch.FindPathJagged(new Node {
                                X = monster.MapX, Y = monster.MapY
                            }, new Node {
                                X = evt4.X, Y = evt4.Y
                            }, evt.MapInstance?.Map.JaggedGrid);
                        }
                        break;

                    case EventActionType.CLOCK:
                        evt.MapInstance.InstanceBag.Clock.TotalSecondsAmount = Convert.ToInt32(evt.Parameter);
                        evt.MapInstance.InstanceBag.Clock.SecondsRemaining   = Convert.ToInt32(evt.Parameter);
                        break;

                    case EventActionType.SETMONSTERLOCKERS:
                        evt.MapInstance.InstanceBag.MonsterLocker.Current = Convert.ToByte(evt.Parameter);
                        evt.MapInstance.InstanceBag.MonsterLocker.Initial = Convert.ToByte(evt.Parameter);
                        break;

                    case EventActionType.SETBUTTONLOCKERS:
                        evt.MapInstance.InstanceBag.ButtonLocker.Current = Convert.ToByte(evt.Parameter);
                        evt.MapInstance.InstanceBag.ButtonLocker.Initial = Convert.ToByte(evt.Parameter);
                        break;

                    case EventActionType.SCRIPTEND:
                        switch (evt.MapInstance.MapInstanceType)
                        {
                        case MapInstanceType.TimeSpaceInstance:
                            evt.MapInstance.InstanceBag.EndState = (byte)evt.Parameter;
                            ClientSession client = evt.MapInstance.Sessions.FirstOrDefault();
                            if (client != null)
                            {
                                Guid             MapInstanceId = ServerManager.GetBaseMapInstanceIdByMapId(client.Character.MapId);
                                MapInstance      map           = ServerManager.GetMapInstance(MapInstanceId);
                                ScriptedInstance si            = map.ScriptedInstances.Find(s => s.PositionX == client.Character.MapX && s.PositionY == client.Character.MapY);
                                byte             penalty       = 0;
                                if (penalty > (client.Character.Level - si.LevelMinimum) * 2)
                                {
                                    penalty = penalty > 100 ? (byte)100 : penalty;
                                    client.SendPacket(client.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("TS_PENALTY"), penalty), 10));
                                }
                                int    point      = evt.MapInstance.InstanceBag.Point * (100 - penalty) / 100;
                                string perfection = string.Empty;
                                perfection += evt.MapInstance.InstanceBag.MonstersKilled >= si.MonsterAmount ? 1 : 0;
                                perfection += evt.MapInstance.InstanceBag.NpcsKilled == 0 ? 1 : 0;
                                perfection += evt.MapInstance.InstanceBag.RoomsVisited >= si.RoomAmount ? 1 : 0;
                                evt.MapInstance.Broadcast($"score  {evt.MapInstance.InstanceBag.EndState} {point} 27 47 18 {si.DrawItems.Count} {evt.MapInstance.InstanceBag.MonstersKilled} {si.NpcAmount - evt.MapInstance.InstanceBag.NpcsKilled} {evt.MapInstance.InstanceBag.RoomsVisited} {perfection} 1 1");
                            }
                            break;

                        case MapInstanceType.RaidInstance:
                            evt.MapInstance.InstanceBag.EndState = (byte)evt.Parameter;
                            client = evt.MapInstance.Sessions.FirstOrDefault();
                            if (client != null)
                            {
                                Group grp = client?.Character?.Group;
                                if (grp == null)
                                {
                                    return;
                                }
                                if (evt.MapInstance.InstanceBag.EndState == 1 && evt.MapInstance.Monsters.Any(s => s.IsBoss))
                                {
                                    foreach (ClientSession sess in grp.Characters.Where(s => s.CurrentMapInstance.Monsters.Any(e => e.IsBoss)))
                                    {
                                        foreach (Gift gift in grp?.Raid?.GiftItems)
                                        {
                                            const byte rare = 0;

                                            // TODO: add random rarity for some object
                                            sess.Character.GiftAdd(gift.VNum, gift.Amount, rare, 0, gift.Design, gift.IsRandomRare);
                                        }
                                    }
                                    foreach (MapMonster mon in evt.MapInstance.Monsters)
                                    {
                                        mon.CurrentHp = 0;
                                        evt.MapInstance.Broadcast(StaticPacketHelper.Out(UserType.Monster, mon.MapMonsterId));
                                        evt.MapInstance.RemoveMonster(mon);
                                    }
                                    Logger.LogUserEvent("RAID_SUCCESS", grp.Characters.ElementAt(0).Character.Name, $"RaidId: {grp.GroupId}");

                                    ServerManager.Instance.Broadcast(UserInterfaceHelper.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("RAID_SUCCEED"), grp?.Raid?.Label, grp.Characters.ElementAt(0).Character.Name), 0));
                                }

                                Observable.Timer(TimeSpan.FromSeconds(evt.MapInstance.InstanceBag.EndState == 1 ? 30 : 0)).Subscribe(o =>
                                {
                                    ClientSession[] grpmembers = new ClientSession[40];
                                    grp.Characters.CopyTo(grpmembers);
                                    foreach (ClientSession targetSession in grpmembers)
                                    {
                                        if (targetSession != null)
                                        {
                                            if (targetSession.Character.Hp <= 0)
                                            {
                                                targetSession.Character.Hp = 1;
                                                targetSession.Character.Mp = 1;
                                            }
                                            targetSession.SendPacket(Character.GenerateRaidBf(evt.MapInstance.InstanceBag.EndState));
                                            targetSession.SendPacket(targetSession.Character.GenerateRaid(1, true));
                                            targetSession.SendPacket(targetSession.Character.GenerateRaid(2, true));
                                            grp.LeaveGroup(targetSession);
                                        }
                                    }
                                    ServerManager.Instance.GroupList.RemoveAll(s => s.GroupId == grp.GroupId);
                                    ServerManager.Instance.GroupsThreadSafe.Remove(grp.GroupId);
                                    evt.MapInstance.Dispose();
                                });
                            }
                            break;

                        case MapInstanceType.Act4Morcos:
                        case MapInstanceType.Act4Hatus:
                        case MapInstanceType.Act4Calvina:
                        case MapInstanceType.Act4Berios:
                            client = evt.MapInstance.Sessions.FirstOrDefault();
                            if (client != null)
                            {
                                Family fam = evt.MapInstance.Sessions.FirstOrDefault(s => s?.Character?.Family != null)?.Character.Family;
                                if (fam != null)
                                {
                                    fam.Act4Raid.Portals.RemoveAll(s => s.DestinationMapInstanceId.Equals(fam.Act4RaidBossMap.MapInstanceId));
                                    short destX      = 38;
                                    short destY      = 179;
                                    short rewardVNum = 882;
                                    switch (evt.MapInstance.MapInstanceType)
                                    {
                                    //Morcos is default
                                    case MapInstanceType.Act4Hatus:
                                        destX      = 18;
                                        destY      = 10;
                                        rewardVNum = 185;
                                        break;

                                    case MapInstanceType.Act4Calvina:
                                        destX      = 25;
                                        destY      = 7;
                                        rewardVNum = 942;
                                        break;

                                    case MapInstanceType.Act4Berios:
                                        destX      = 16;
                                        destY      = 25;
                                        rewardVNum = 999;
                                        break;
                                    }
                                    int count = evt.MapInstance.Sessions.Count(s => s?.Character != null);
                                    foreach (ClientSession sess in evt.MapInstance.Sessions)
                                    {
                                        if (sess?.Character != null)
                                        {
                                            sess.Character.GiftAdd(rewardVNum, 1, forceRandom: true, minRare: 1, design: 255);
                                            sess.Character.GenerateFamilyXp(10000 / count);
                                        }
                                    }
                                    Logger.LogEvent("FAMILYRAID_SUCCESS", $"[fam.Name]FamilyRaidId: {evt.MapInstance.MapInstanceType.ToString()}");

                                    //TODO: Famlog
                                    CommunicationServiceClient.Instance.SendMessageToCharacter(new SCSCharacterMessage
                                    {
                                        DestinationCharacterId = fam.FamilyId,
                                        SourceCharacterId      = client.Character.CharacterId,
                                        SourceWorldId          = ServerManager.Instance.WorldId,
                                        Message = UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("FAMILYRAID_SUCCESS"), 0),
                                        Type    = MessageType.Family
                                    });
                                    //ServerManager.Instance.Broadcast(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("FAMILYRAID_SUCCESS"), grp?.Raid?.Label, grp.Characters.ElementAt(0).Character.Name), 0));

                                    Observable.Timer(TimeSpan.FromSeconds(30)).Subscribe(o =>
                                    {
                                        foreach (ClientSession targetSession in evt.MapInstance.Sessions.ToArray())
                                        {
                                            if (targetSession != null)
                                            {
                                                if (targetSession.Character.Hp <= 0)
                                                {
                                                    targetSession.Character.Hp = 1;
                                                    targetSession.Character.Mp = 1;
                                                }

                                                ServerManager.Instance.ChangeMapInstance(targetSession.Character.CharacterId, fam.Act4Raid.MapInstanceId, destX, destY);
                                            }
                                        }
                                        evt.MapInstance.Dispose();
                                    });
                                }
                            }
                            break;

                        case MapInstanceType.CaligorInstance:

                            FactionType winningFaction = CaligorRaid.AngelDamage > CaligorRaid.DemonDamage ? FactionType.Angel : FactionType.Demon;

                            foreach (ClientSession sess in evt.MapInstance.Sessions)
                            {
                                if (sess?.Character != null)
                                {
                                    if (CaligorRaid.RemainingTime > 2400)
                                    {
                                        if (sess.Character.Faction == winningFaction)
                                        {
                                            sess.Character.GiftAdd(302, 1, 0, 0, 51);
                                        }
                                        else
                                        {
                                            sess.Character.GiftAdd(302, 1, 0, 0, 51);
                                        }
                                    }
                                    else
                                    {
                                        if (sess.Character.Faction == winningFaction)
                                        {
                                            sess.Character.GiftAdd(302, 1, 0, 0, 51);
                                        }
                                        else
                                        {
                                            sess.Character.GiftAdd(302, 1, 0, 0, 51);
                                        }
                                    }
                                    sess.Character.GiftAdd(1244, 50);
                                    sess.Character.GiftAdd(1134, 1);
                                    sess.Character.GenerateFamilyXp(500);
                                }
                            }
                            evt.MapInstance.Broadcast(UserInterfaceHelper.GenerateCHDM(ServerManager.GetNpc(2305).MaxHP, CaligorRaid.AngelDamage, CaligorRaid.DemonDamage, CaligorRaid.RemainingTime));
                            break;
                        }
                        break;

                    case EventActionType.MAPCLOCK:
                        evt.MapInstance.Clock.TotalSecondsAmount = Convert.ToInt32(evt.Parameter);
                        evt.MapInstance.Clock.SecondsRemaining   = Convert.ToInt32(evt.Parameter);
                        break;

                    case EventActionType.STARTCLOCK:
                        Tuple <List <EventContainer>, List <EventContainer> > eve = (Tuple <List <EventContainer>, List <EventContainer> >)evt.Parameter;
                        evt.MapInstance.InstanceBag.Clock.StopEvents    = eve.Item1;
                        evt.MapInstance.InstanceBag.Clock.TimeoutEvents = eve.Item2;
                        evt.MapInstance.InstanceBag.Clock.StartClock();
                        evt.MapInstance.Broadcast(evt.MapInstance.InstanceBag.Clock.GetClock());
                        break;

                    case EventActionType.TELEPORT:
                        Tuple <short, short, short, short> tp = (Tuple <short, short, short, short>)evt.Parameter;
                        List <Character> characters           = evt.MapInstance.GetCharactersInRange(tp.Item1, tp.Item2, 5).ToList();
                        characters.ForEach(s =>
                        {
                            s.PositionX = tp.Item3;
                            s.PositionY = tp.Item4;
                            evt.MapInstance?.Broadcast(s.Session, s.GenerateTp(), ReceiverType.Group);
                        });
                        break;

                    case EventActionType.STOPCLOCK:
                        evt.MapInstance.InstanceBag.Clock.StopClock();
                        evt.MapInstance.Broadcast(evt.MapInstance.InstanceBag.Clock.GetClock());
                        break;

                    case EventActionType.STARTMAPCLOCK:
                        eve = (Tuple <List <EventContainer>, List <EventContainer> >)evt.Parameter;
                        evt.MapInstance.Clock.StopEvents    = eve.Item1;
                        evt.MapInstance.Clock.TimeoutEvents = eve.Item2;
                        evt.MapInstance.Clock.StartClock();
                        evt.MapInstance.Broadcast(evt.MapInstance.Clock.GetClock());
                        break;

                    case EventActionType.STOPMAPCLOCK:
                        evt.MapInstance.Clock.StopClock();
                        evt.MapInstance.Broadcast(evt.MapInstance.Clock.GetClock());
                        break;

                    case EventActionType.SPAWNPORTAL:
                        evt.MapInstance.CreatePortal((Portal)evt.Parameter);
                        break;

                    case EventActionType.REFRESHMAPITEMS:
                        evt.MapInstance.MapClear();
                        break;

                    case EventActionType.NPCSEFFECTCHANGESTATE:
                        evt.MapInstance.Npcs.ForEach(s => s.EffectActivated = (bool)evt.Parameter);
                        break;

                    case EventActionType.CHANGEPORTALTYPE:
                        Tuple <int, PortalType> param = (Tuple <int, PortalType>)evt.Parameter;
                        Portal portal = evt.MapInstance.Portals.Find(s => s.PortalId == param.Item1);
                        if (portal != null)
                        {
                            portal.Type = (short)param.Item2;
                        }
                        break;

                    case EventActionType.CHANGEDROPRATE:
                        evt.MapInstance.DropRate = (int)evt.Parameter;
                        break;

                    case EventActionType.CHANGEXPRATE:
                        evt.MapInstance.XpRate = (int)evt.Parameter;
                        break;

                    case EventActionType.DISPOSEMAP:
                        evt.MapInstance.Dispose();
                        break;

                    case EventActionType.SPAWNBUTTON:
                        evt.MapInstance.SpawnButton((MapButton)evt.Parameter);
                        break;

                    case EventActionType.UNSPAWNMONSTERS:
                        evt.MapInstance.DespawnMonster((int)evt.Parameter);
                        break;

                    case EventActionType.SPAWNMONSTER:
                        evt.MapInstance.SummonMonster((MonsterToSummon)evt.Parameter);
                        break;

                    case EventActionType.SPAWNMONSTERS:
                        evt.MapInstance.SummonMonsters((List <MonsterToSummon>)evt.Parameter);
                        break;

                    case EventActionType.REFRESHRAIDGOAL:
                        ClientSession cl = evt.MapInstance.Sessions.FirstOrDefault();
                        if (cl?.Character != null)
                        {
                            ServerManager.Instance.Broadcast(cl, cl.Character?.Group?.GeneraterRaidmbf(cl), ReceiverType.Group);
                            ServerManager.Instance.Broadcast(cl, UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("NEW_MISSION"), 0), ReceiverType.Group);
                        }
                        break;

                    case EventActionType.SPAWNNPC:
                        evt.MapInstance.SummonNpc((NpcToSummon)evt.Parameter);
                        break;

                    case EventActionType.SPAWNNPCS:
                        evt.MapInstance.SummonNpcs((List <NpcToSummon>)evt.Parameter);
                        break;

                    case EventActionType.DROPITEMS:
                        evt.MapInstance.DropItems((List <Tuple <short, int, short, short> >)evt.Parameter);
                        break;

                    case EventActionType.THROWITEMS:
                        Tuple <int, short, byte, int, int> parameters = (Tuple <int, short, byte, int, int>)evt.Parameter;
                        if (monster != null)
                        {
                            parameters = new Tuple <int, short, byte, int, int>(monster.MapMonsterId, parameters.Item2, parameters.Item3, parameters.Item4, parameters.Item5);
                        }
                        evt.MapInstance.ThrowItems(parameters);
                        break;

                    case EventActionType.SPAWNONLASTENTRY:
                        Character lastincharacter = evt.MapInstance.Sessions.OrderByDescending(s => s.RegisterTime).FirstOrDefault()?.Character;
                        List <MonsterToSummon> summonParameters = new List <MonsterToSummon>();
                        MapCell hornSpawn = new MapCell
                        {
                            X = lastincharacter?.PositionX ?? 154,
                            Y = lastincharacter?.PositionY ?? 140
                        };
                        long hornTarget = lastincharacter?.CharacterId ?? -1;
                        summonParameters.Add(new MonsterToSummon(Convert.ToInt16(evt.Parameter), hornSpawn, hornTarget, true));
                        evt.MapInstance.SummonMonsters(summonParameters);
                        break;

                        #endregion
                    }
                }
            }
        }
Exemple #5
0
        private void npcLife()
        {
            // Respawn
            if (CurrentHp <= 0 && ShouldRespawn != null && !ShouldRespawn.Value)
            {
                MapInstance.RemoveNpc(this);
                MapInstance.Broadcast(GenerateOut());
            }

            if (!IsAlive && ShouldRespawn != null && ShouldRespawn.Value)
            {
                double timeDeath = (DateTime.Now - Death).TotalSeconds;
                if (timeDeath >= Npc.RespawnTime / 10d)
                {
                    Respawn();
                }
            }

            if (LastProtectedEffect.AddMilliseconds(6000) <= DateTime.Now)
            {
                LastProtectedEffect = DateTime.Now;
                if (IsMate || IsProtected)
                {
                    MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, MapNpcId, 825), MapX, MapY);
                }
            }

            double time = (DateTime.Now - LastEffect).TotalMilliseconds;

            if (EffectDelay > 0)
            {
                if (time > EffectDelay)
                {
                    if (Effect > 0 && EffectActivated)
                    {
                        MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, MapNpcId, Effect), MapX, MapY);
                    }

                    LastEffect = DateTime.Now;
                }
            }

            time = (DateTime.Now - LastMove).TotalMilliseconds;
            if (Target == -1 && IsMoving && Npc.Speed > 0 && time > _movetime && !HasBuff(CardType.Move, (byte)AdditionalTypes.Move.MovementImpossible))
            {
                _movetime = ServerManager.RandomNumber(500, 3000);
                int maxindex = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                if (maxindex < 1)
                {
                    maxindex = 1;
                }
                if (Path.Count == 0 || Path.Count >= maxindex && maxindex > 0 && Path[maxindex - 1] == null)
                {
                    short xoffset = (short)ServerManager.RandomNumber(-1, 1);
                    short yoffset = (short)ServerManager.RandomNumber(-1, 1);

                    MapCell moveToPosition = new MapCell {
                        X = FirstX, Y = FirstY
                    };
                    if (RunToX != 0 || RunToY != 0)
                    {
                        moveToPosition = new MapCell {
                            X = RunToX, Y = RunToY
                        };
                        _movetime = ServerManager.RandomNumber(300, 1200);
                    }
                    Path = BestFirstSearch.FindPathJagged(new GridPos {
                        X = MapX, Y = MapY
                    }, new GridPos {
                        X = (short)ServerManager.RandomNumber(moveToPosition.X - 3, moveToPosition.X + 3), Y = (short)ServerManager.RandomNumber(moveToPosition.Y - 3, moveToPosition.Y + 3)
                    }, MapInstance.Map.JaggedGrid);
                    maxindex = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                }
                if (DateTime.Now > LastMove && Npc.Speed > 0 && Path.Count > 0)
                {
                    byte speedIndex = (byte)(Npc.Speed / 2.5 < 1 ? 1 : Npc.Speed / 2.5);
                    maxindex = Path.Count > speedIndex ? speedIndex : Path.Count;
                    short mapX = (short)ServerManager.RandomNumber(Path[maxindex - 1].X - 1, Path[maxindex - 1].X + 1);
                    short mapY = (short)_random.Next(Path[maxindex - 1].Y - 1, Path[maxindex - 1].Y + 1);

                    //short mapX = Path[maxindex - 1].X;
                    //short mapY = Path[maxindex - 1].Y;
                    double waitingtime = Map.GetDistance(new MapCell {
                        X = mapX, Y = mapY
                    }, new MapCell {
                        X = MapX, Y = MapY
                    }) / (double)Npc.Speed;
                    MapInstance.Broadcast(new BroadcastPacket(null, PacketFactory.Serialize(StaticPacketHelper.Move(UserType.Npc, MapNpcId, mapX, mapY, Npc.Speed)), ReceiverType.All, xCoordinate: mapX, yCoordinate: mapY));
                    LastMove = DateTime.Now.AddSeconds(waitingtime > 1 ? 1 : waitingtime);

                    Observable.Timer(TimeSpan.FromMilliseconds((int)((waitingtime > 1 ? 1 : waitingtime) * 1000))).Subscribe(x =>
                    {
                        MapX = mapX;
                        MapY = mapY;
                    });

                    Path.RemoveRange(0, maxindex);
                }
            }
            if (Target == -1)
            {
                if (IsHostile && Shop == null)
                {
                    MapMonster    monster = MapInstance.GetMonsterInRangeList(MapX, MapY, (byte)(Npc.NoticeRange > 5 ? Npc.NoticeRange / 2 : Npc.NoticeRange)).Where(s => BattleEntity.CanAttackEntity(s.BattleEntity)).FirstOrDefault();
                    ClientSession session = MapInstance.Sessions.FirstOrDefault(s => BattleEntity.CanAttackEntity(s.Character.BattleEntity) && MapInstance == s.Character.MapInstance && Map.GetDistance(new MapCell {
                        X = MapX, Y = MapY
                    }, new MapCell {
                        X = s.Character.PositionX, Y = s.Character.PositionY
                    }) < Npc.NoticeRange);

                    if (monster != null)
                    {
                        Target = monster.MapMonsterId;
                    }
                    if (session?.Character != null)
                    {
                        Target = session.Character.CharacterId;
                    }
                }
            }
            else if (Target != -1)
            {
                MapMonster monster = MapInstance.Monsters.Find(s => s.MapMonsterId == Target);
                if (monster == null || monster.CurrentHp < 1)
                {
                    Target = -1;
                    return;
                }
                NpcMonsterSkill npcMonsterSkill = null;
                if (ServerManager.RandomNumber(0, 10) > 8)
                {
                    npcMonsterSkill = Skills.Where(s => (DateTime.Now - s.LastSkillUse).TotalMilliseconds >= 100 * s.Skill.Cooldown).OrderBy(rnd => _random.Next()).FirstOrDefault();
                }
                int  hitmode   = 0;
                bool onyxWings = false;
                int  damage    = DamageHelper.Instance.CalculateDamage(new BattleEntity(this), new BattleEntity(monster), npcMonsterSkill?.Skill, ref hitmode, ref onyxWings);
                if (monster.Monster.BCards.Find(s => s.Type == (byte)CardType.LightAndShadow && s.SubType == (byte)AdditionalTypes.LightAndShadow.InflictDamageToMP) is BCard card)
                {
                    int reduce = damage / 100 * card.FirstData;
                    if (monster.CurrentMp < reduce)
                    {
                        reduce            = (int)monster.CurrentMp;
                        monster.CurrentMp = 0;
                    }
                    else
                    {
                        monster.DecreaseMp(reduce);
                    }
                    damage -= reduce;
                }
                int distance = Map.GetDistance(new MapCell {
                    X = MapX, Y = MapY
                }, new MapCell {
                    X = monster.MapX, Y = monster.MapY
                });
                if (monster.CurrentHp > 0 && ((npcMonsterSkill != null && distance < npcMonsterSkill.Skill.Range) || distance <= Npc.BasicRange) && !HasBuff(CardType.SpecialAttack, (byte)AdditionalTypes.SpecialAttack.NoAttack))
                {
                    if (((DateTime.Now - LastSkill).TotalMilliseconds >= 1000 + (Npc.BasicCooldown * 200) /* && Skills.Count == 0*/) || npcMonsterSkill != null)
                    {
                        if (npcMonsterSkill != null)
                        {
                            npcMonsterSkill.LastSkillUse = DateTime.Now;
                            MapInstance.Broadcast(StaticPacketHelper.CastOnTarget(UserType.Npc, MapNpcId, UserType.Monster, Target, npcMonsterSkill.Skill.CastAnimation, npcMonsterSkill.Skill.CastEffect, npcMonsterSkill.Skill.SkillVNum));
                        }

                        if (npcMonsterSkill != null && npcMonsterSkill.Skill.CastEffect != 0)
                        {
                            MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, MapNpcId, Effect));
                        }
                        monster.BattleEntity.GetDamage(damage, BattleEntity);
                        lock (monster.DamageList)
                        {
                            if (!monster.DamageList.Any(s => s.Key.MapEntityId == MapNpcId))
                            {
                                monster.AddToAggroList(BattleEntity);
                            }
                        }
                        MapInstance.Broadcast(npcMonsterSkill != null
                            ? StaticPacketHelper.SkillUsed(UserType.Npc, MapNpcId, 3, Target, npcMonsterSkill.SkillVNum, npcMonsterSkill.Skill.Cooldown, npcMonsterSkill.Skill.AttackAnimation, npcMonsterSkill.Skill.Effect, 0, 0, monster.CurrentHp > 0, (int)((float)monster.CurrentHp / (float)monster.MaxHp * 100), damage, hitmode, 0)
                            : StaticPacketHelper.SkillUsed(UserType.Npc, MapNpcId, 3, Target, 0, Npc.BasicCooldown, 11, Npc.BasicSkill, 0, 0, monster.CurrentHp > 0, (int)((float)monster.CurrentHp / (float)monster.MaxHp * 100), damage, hitmode, 0));
                        LastSkill = DateTime.Now;

                        if (npcMonsterSkill?.Skill.TargetType == 1 && npcMonsterSkill?.Skill.HitType == 2)
                        {
                            IEnumerable <ClientSession> clientSessions =
                                MapInstance.Sessions?.Where(s =>
                                                            s.Character.IsInRange(MapX,
                                                                                  MapY, npcMonsterSkill.Skill.TargetRange));
                            IEnumerable <Mate> mates = MapInstance.GetListMateInRange(MapX, MapY, npcMonsterSkill.Skill.TargetRange);

                            foreach (BCard skillBcard in npcMonsterSkill.Skill.BCards)
                            {
                                if (skillBcard.Type == 25 && skillBcard.SubType == 1 && new Buff((short)skillBcard.SecondData, Npc.Level)?.Card?.BuffType == BuffType.Good)
                                {
                                    if (clientSessions != null)
                                    {
                                        foreach (ClientSession clientSession in clientSessions)
                                        {
                                            if (clientSession.Character != null)
                                            {
                                                if (!BattleEntity.CanAttackEntity(clientSession.Character.BattleEntity))
                                                {
                                                    skillBcard.ApplyBCards(clientSession.Character.BattleEntity, BattleEntity);
                                                }
                                            }
                                        }
                                    }
                                    if (mates != null)
                                    {
                                        foreach (Mate mate in mates)
                                        {
                                            if (!BattleEntity.CanAttackEntity(mate.BattleEntity))
                                            {
                                                skillBcard.ApplyBCards(mate.BattleEntity, BattleEntity);
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        if (monster.CurrentHp < 1 && monster.SetDeathStatement())
                        {
                            monster.RunDeathEvent();
                            RemoveTarget();
                        }
                    }
                }
                else
                {
                    int maxdistance = Npc.NoticeRange > 5 ? Npc.NoticeRange / 2 : Npc.NoticeRange;
                    if (IsMoving && !HasBuff(CardType.Move, (byte)AdditionalTypes.Move.MovementImpossible))
                    {
                        const short maxDistance = 5;
                        int         maxindex    = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                        if (maxindex < 1)
                        {
                            maxindex = 1;
                        }
                        if ((Path.Count == 0 && distance >= 1 && distance < maxDistance) || (Path.Count >= maxindex && maxindex > 0 && Path[maxindex - 1] == null))
                        {
                            short xoffset = (short)ServerManager.RandomNumber(-1, 1);
                            short yoffset = (short)ServerManager.RandomNumber(-1, 1);

                            //go to monster
                            Path = BestFirstSearch.FindPathJagged(new GridPos {
                                X = MapX, Y = MapY
                            }, new GridPos {
                                X = (short)(monster.MapX + xoffset), Y = (short)(monster.MapY + yoffset)
                            }, MapInstance.Map.JaggedGrid);
                            maxindex = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                        }
                        if (DateTime.Now > LastMove && Npc.Speed > 0 && Path.Count > 0)
                        {
                            byte speedIndex = (byte)(Npc.Speed / 2.5 < 1 ? 1 : Npc.Speed / 2.5);
                            maxindex = Path.Count > speedIndex ? speedIndex : Path.Count;
                            //short mapX = (short)ServerManager.RandomNumber(Path[maxindex - 1].X - 1, Path[maxindex - 1].X + 1);
                            //short mapY = (short)_random.Next(Path[maxindex - 1].Y - 1, Path[maxindex - 1].Y + 1);

                            short  mapX        = Path[maxindex - 1].X;
                            short  mapY        = Path[maxindex - 1].Y;
                            double waitingtime = Map.GetDistance(new MapCell {
                                X = mapX, Y = mapY
                            }, new MapCell {
                                X = MapX, Y = MapY
                            }) / (double)Npc.Speed;
                            MapInstance.Broadcast(new BroadcastPacket(null, PacketFactory.Serialize(StaticPacketHelper.Move(UserType.Npc, MapNpcId, mapX, mapY, Npc.Speed)), ReceiverType.All, xCoordinate: mapX, yCoordinate: mapY));
                            LastMove = DateTime.Now.AddSeconds(waitingtime > 1 ? 1 : waitingtime);

                            Observable.Timer(TimeSpan.FromMilliseconds((int)((waitingtime > 1 ? 1 : waitingtime) * 1000))).Subscribe(x =>
                            {
                                MapX = mapX;
                                MapY = mapY;
                            });

                            Path.RemoveRange(0, maxindex);
                        }
                        if (Target != -1 && (MapId != monster.MapId || distance > maxDistance))
                        {
                            RemoveTarget();
                        }
                    }
                }
            }
        }
Exemple #6
0
        private void npcLife()
        {
            double time = (DateTime.Now - LastEffect).TotalMilliseconds;

            if (time > EffectDelay)
            {
                if (IsMate || IsProtected)
                {
                    MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, MapNpcId, 825), MapX, MapY);
                }
                if (Effect > 0 && EffectActivated)
                {
                    MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, MapNpcId, Effect), MapX, MapY);
                }
                LastEffect = DateTime.Now;
            }

            time = (DateTime.Now - LastMove).TotalMilliseconds;
            if (IsMoving && Npc.Speed > 0 && time > _movetime)
            {
                _movetime = ServerManager.RandomNumber(500, 3000);
                byte point  = (byte)ServerManager.RandomNumber(2, 4);
                byte fpoint = (byte)ServerManager.RandomNumber(0, 2);

                byte xpoint = (byte)ServerManager.RandomNumber(fpoint, point);
                byte ypoint = (byte)(point - xpoint);

                short mapX = FirstX;
                short mapY = FirstY;

                if (MapInstance.Map.GetFreePosition(ref mapX, ref mapY, xpoint, ypoint))
                {
                    double value = (xpoint + ypoint) / (double)(2 * Npc.Speed);
                    Observable.Timer(TimeSpan.FromMilliseconds(1000 * value)).Subscribe(x =>
                    {
                        MapX = mapX;
                        MapY = mapY;
                    });
                    LastMove = DateTime.Now.AddSeconds(value);
                    MapInstance.Broadcast(new BroadcastPacket(null, PacketFactory.Serialize(StaticPacketHelper.Move(UserType.Npc, MapNpcId, MapX, MapY, Npc.Speed)), ReceiverType.All, xCoordinate: mapX, yCoordinate: mapY));
                }
            }
            if (Target == -1)
            {
                if (IsHostile && Shop == null)
                {
                    MapMonster monster = MapInstance.Monsters.Find(s => MapInstance == s.MapInstance && Map.GetDistance(new MapCell {
                        X = MapX, Y = MapY
                    }, new MapCell {
                        X = s.MapX, Y = s.MapY
                    }) < (Npc.NoticeRange > 5 ? Npc.NoticeRange / 2 : Npc.NoticeRange));
                    ClientSession session = MapInstance.Sessions.FirstOrDefault(s => MapInstance == s.Character.MapInstance && Map.GetDistance(new MapCell {
                        X = MapX, Y = MapY
                    }, new MapCell {
                        X = s.Character.PositionX, Y = s.Character.PositionY
                    }) < Npc.NoticeRange);

                    if (monster != null && session != null)
                    {
                        Target = monster.MapMonsterId;
                    }
                }
            }
            else if (Target != -1)
            {
                MapMonster monster = MapInstance.Monsters.Find(s => s.MapMonsterId == Target);
                if (monster == null || monster.CurrentHp < 1)
                {
                    Target = -1;
                    return;
                }
                NpcMonsterSkill npcMonsterSkill = null;
                if (ServerManager.RandomNumber(0, 10) > 8)
                {
                    npcMonsterSkill = Npc.Skills.Where(s => (DateTime.Now - s.LastSkillUse).TotalMilliseconds >= 100 * s.Skill.Cooldown).OrderBy(rnd => _random.Next()).FirstOrDefault();
                }
                int  hitmode   = 0;
                bool onyxWings = false;
                int  damage    = DamageHelper.Instance.CalculateDamage(new BattleEntity(this), new BattleEntity(monster), npcMonsterSkill?.Skill, ref hitmode, ref onyxWings);
                if (monster.Monster.BCards.Find(s => s.Type == (byte)CardType.LightAndShadow && s.SubType == (byte)AdditionalTypes.LightAndShadow.InflictDamageToMP) is BCard card)
                {
                    int reduce = damage / 100 * card.FirstData;
                    if (monster.CurrentMp < reduce)
                    {
                        monster.CurrentMp = 0;
                    }
                    else
                    {
                        monster.CurrentMp -= reduce;
                    }
                }
                int distance = Map.GetDistance(new MapCell {
                    X = MapX, Y = MapY
                }, new MapCell {
                    X = monster.MapX, Y = monster.MapY
                });
                if (monster.CurrentHp > 0 && ((npcMonsterSkill != null && distance < npcMonsterSkill.Skill.Range) || distance <= Npc.BasicRange))
                {
                    if (((DateTime.Now - LastEffect).TotalMilliseconds >= 1000 + (Npc.BasicCooldown * 200) && Npc.Skills.Count == 0) || npcMonsterSkill != null)
                    {
                        if (npcMonsterSkill != null)
                        {
                            npcMonsterSkill.LastSkillUse = DateTime.Now;
                            MapInstance.Broadcast(StaticPacketHelper.CastOnTarget(UserType.Npc, MapNpcId, 3, Target, npcMonsterSkill.Skill.CastAnimation, npcMonsterSkill.Skill.CastEffect, npcMonsterSkill.Skill.SkillVNum));
                        }

                        if (npcMonsterSkill != null && npcMonsterSkill.Skill.CastEffect != 0)
                        {
                            MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, MapNpcId, Effect));
                        }
                        monster.CurrentHp -= damage;
                        MapInstance.Broadcast(npcMonsterSkill != null
                            ? StaticPacketHelper.SkillUsed(UserType.Npc, MapNpcId, 3, Target, npcMonsterSkill.SkillVNum, npcMonsterSkill.Skill.Cooldown, npcMonsterSkill.Skill.AttackAnimation, npcMonsterSkill.Skill.Effect, 0, 0, monster.CurrentHp > 0, (int)((float)monster.CurrentHp / (float)monster.Monster.MaxHP * 100), damage, hitmode, 0)
                            : StaticPacketHelper.SkillUsed(UserType.Npc, MapNpcId, 3, Target, 0, Npc.BasicCooldown, 11, Npc.BasicSkill, 0, 0, monster.CurrentHp > 0, (int)((float)monster.CurrentHp / (float)monster.Monster.MaxHP * 100), damage, hitmode, 0));
                        LastEffect = DateTime.Now;
                        if (monster.CurrentHp < 1)
                        {
                            RemoveTarget();
                            monster.IsAlive   = false;
                            monster.LastMove  = DateTime.Now;
                            monster.CurrentHp = 0;
                            monster.CurrentMp = 0;
                            monster.Death     = DateTime.Now;
                            Target            = -1;
                        }
                    }
                }
                else
                {
                    int maxdistance = Npc.NoticeRange > 5 ? Npc.NoticeRange / 2 : Npc.NoticeRange;
                    if (IsMoving)
                    {
                        const short maxDistance = 5;
                        int         maxindex    = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                        if (maxindex < 1)
                        {
                            maxindex = 1;
                        }
                        if ((Path.Count == 0 && distance >= 1 && distance < maxDistance) || (Path.Count >= maxindex && maxindex > 0 && Path[maxindex - 1] == null))
                        {
                            short xoffset = (short)ServerManager.RandomNumber(-1, 1);
                            short yoffset = (short)ServerManager.RandomNumber(-1, 1);

                            //go to monster
                            Path = BestFirstSearch.FindPathJagged(new GridPos {
                                X = MapX, Y = MapY
                            }, new GridPos {
                                X = (short)(monster.MapX + xoffset), Y = (short)(monster.MapY + yoffset)
                            }, MapInstance.Map.JaggedGrid);
                            maxindex = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                        }
                        if (DateTime.Now > LastMove && Npc.Speed > 0 && Path.Count > 0)
                        {
                            short  mapX        = Path[maxindex - 1].X;
                            short  mapY        = Path[maxindex - 1].Y;
                            double waitingtime = Map.GetDistance(new MapCell {
                                X = mapX, Y = mapY
                            }, new MapCell {
                                X = MapX, Y = MapY
                            }) / (double)Npc.Speed;
                            MapInstance.Broadcast(new BroadcastPacket(null, PacketFactory.Serialize(StaticPacketHelper.Move(UserType.Npc, MapNpcId, MapX, MapY, Npc.Speed)), ReceiverType.All, xCoordinate: mapX, yCoordinate: mapY));
                            LastMove = DateTime.Now.AddSeconds(waitingtime > 1 ? 1 : waitingtime);

                            Observable.Timer(TimeSpan.FromMilliseconds((int)((waitingtime > 1 ? 1 : waitingtime) * 1000))).Subscribe(x =>
                            {
                                MapX = mapX;
                                MapY = mapY;
                            });

                            Path.RemoveRange(0, maxindex);
                        }
                        if (Target != -1 && (MapId != monster.MapId || distance > maxDistance))
                        {
                            RemoveTarget();
                        }
                    }
                }
            }
        }
        public void RunEvent(EventContainer evt, ClientSession session = null, MapMonster monster = null)
        {
            if (evt != null)
            {
                if (session != null)
                {
                    evt.MapInstance = session.CurrentMapInstance;
                    switch (evt.EventActionType)
                    {
                        #region EventForUser

                    case EventActionType.NpcDialog:
                        session.SendPacket(session.Character.GenerateNpcDialog((int)evt.Parameter));
                        break;

                    case EventActionType.SendPacket:
                        session.SendPacket((string)evt.Parameter);
                        break;

                        #endregion
                    }
                }
                if (evt.MapInstance != null)
                {
                    switch (evt.EventActionType)
                    {
                        #region EventForUser

                    case EventActionType.NpcDialog:
                    case EventActionType.SendPacket:
                        if (session == null)
                        {
                            evt.MapInstance.Sessions.ToList().ForEach(e => RunEvent(evt, e));
                        }
                        break;

                        #endregion

                        #region MapInstanceEvent

                    case EventActionType.RegisterEvent:
                        Tuple <string, List <EventContainer> > even = (Tuple <string, List <EventContainer> >)evt.Parameter;
                        switch (even.Item1)
                        {
                        case "OnCharacterDiscoveringMap":
                            even.Item2.ForEach(s => evt.MapInstance.OnCharacterDiscoveringMapEvents.Add(new Tuple <EventContainer, List <long> >(s, new List <long>())));
                            break;

                        case "OnMoveOnMap":
                            evt.MapInstance.OnMoveOnMapEvents.AddRange(even.Item2);
                            break;

                        case "OnMapClean":
                            evt.MapInstance.OnMapClean.AddRange(even.Item2);
                            break;

                        case "OnLockerOpen":
                            evt.MapInstance.UnlockEvents.AddRange(even.Item2);
                            break;
                        }
                        break;

                    case EventActionType.RegisterWave:
                        evt.MapInstance.WaveEvents.Add((EventWave)evt.Parameter);
                        break;

                    case EventActionType.SetAreaEntry:
                        ZoneEvent even2 = (ZoneEvent)evt.Parameter;
                        evt.MapInstance.OnAreaEntryEvents.Add(even2);
                        break;

                    case EventActionType.RemoveMonsterLocker:
                        if (evt.MapInstance.InstanceBag.MonsterLocker.Current > 0)
                        {
                            evt.MapInstance.InstanceBag.MonsterLocker.Current--;
                        }
                        if (evt.MapInstance.InstanceBag.MonsterLocker.Current == 0 && evt.MapInstance.InstanceBag.ButtonLocker.Current == 0)
                        {
                            evt.MapInstance.UnlockEvents.ForEach(s => RunEvent(s));
                            evt.MapInstance.UnlockEvents.RemoveAll(s => s != null);
                        }
                        break;

                    case EventActionType.RemoveButtonLocker:
                        if (evt.MapInstance.InstanceBag.ButtonLocker.Current > 0)
                        {
                            evt.MapInstance.InstanceBag.ButtonLocker.Current--;
                        }
                        if (evt.MapInstance.InstanceBag.MonsterLocker.Current == 0 && evt.MapInstance.InstanceBag.ButtonLocker.Current == 0)
                        {
                            evt.MapInstance.UnlockEvents.ForEach(s => RunEvent(s));
                            evt.MapInstance.UnlockEvents.RemoveAll(s => s != null);
                        }
                        break;

                    case EventActionType.Effect:
                        short evt3 = (short)evt.Parameter;
                        if (monster != null)
                        {
                            monster.LastEffect = DateTime.UtcNow;
                            evt.MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Monster, monster.MapMonsterId, evt3));
                        }
                        break;

                    case EventActionType.ControleMonsterInRange:
                        if (monster != null)
                        {
                            Tuple <short, byte, List <EventContainer> > evnt = (Tuple <short, byte, List <EventContainer> >)evt.Parameter;
                            List <MapMonster> mapMonsters = evt.MapInstance.GetListMonsterInRange(monster.MapX, monster.MapY, evnt.Item2);
                            if (evnt.Item1 != 0)
                            {
                                mapMonsters.RemoveAll(s => s.MonsterVNum != evnt.Item1);
                            }
                            mapMonsters.ForEach(s => evnt.Item3.ForEach(e => RunEvent(e, monster: s)));
                        }
                        break;

                    case EventActionType.OnTarget:
                        if (monster?.MoveEvent?.InZone(monster.MapX, monster.MapY) == true)
                        {
                            monster.MoveEvent = null;
                            monster.Path      = new List <Node>();
                            ((List <EventContainer>)evt.Parameter).ForEach(s => RunEvent(s, monster: monster));
                        }
                        break;

                    case EventActionType.Move:
                        ZoneEvent evt4 = (ZoneEvent)evt.Parameter;
                        if (monster != null)
                        {
                            monster.MoveEvent = evt4;
                            monster.Path      = BestFirstSearch.FindPathJagged(new Node {
                                X = monster.MapX, Y = monster.MapY
                            }, new Node {
                                X = evt4.X, Y = evt4.Y
                            }, evt.MapInstance?.Map.JaggedGrid);
                        }
                        break;

                    case EventActionType.Clock:
                        evt.MapInstance.InstanceBag.Clock.TotalSecondsAmount = Convert.ToInt32(evt.Parameter);
                        evt.MapInstance.InstanceBag.Clock.SecondsRemaining   = Convert.ToInt32(evt.Parameter);
                        break;

                    case EventActionType.SetMonsterLockers:
                        evt.MapInstance.InstanceBag.MonsterLocker.Current = Convert.ToByte(evt.Parameter);
                        evt.MapInstance.InstanceBag.MonsterLocker.Initial = Convert.ToByte(evt.Parameter);
                        break;

                    case EventActionType.SetButtonLockers:
                        evt.MapInstance.InstanceBag.ButtonLocker.Current = Convert.ToByte(evt.Parameter);
                        evt.MapInstance.InstanceBag.ButtonLocker.Initial = Convert.ToByte(evt.Parameter);
                        break;

                    case EventActionType.ScriptEnd:
                        switch (evt.MapInstance.MapInstanceType)
                        {
                        case MapInstanceType.TimeSpaceInstance:
                            evt.MapInstance.InstanceBag.EndState = (byte)evt.Parameter;
                            ClientSession client = evt.MapInstance.Sessions.FirstOrDefault();
                            if (client != null)
                            {
                                Guid             mapInstanceId = ServerManager.GetBaseMapInstanceIdByMapId(client.Character.MapId);
                                MapInstance      map           = ServerManager.GetMapInstance(mapInstanceId);
                                ScriptedInstance si            = map.ScriptedInstances.Find(s => s.PositionX == client.Character.MapX && s.PositionY == client.Character.MapY);
                                byte             penalty       = 0;
                                if (penalty > (client.Character.Level - si.LevelMinimum) * 2)
                                {
                                    penalty = penalty > 100 ? (byte)100 : penalty;
                                    client.SendPacket(client.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("TS_PENALTY"), penalty), 10));
                                }
                                int    point      = evt.MapInstance.InstanceBag.Point * (100 - penalty) / 100;
                                string perfection = string.Empty;
                                perfection += evt.MapInstance.InstanceBag.MonstersKilled >= si.MonsterAmount ? 1 : 0;
                                perfection += evt.MapInstance.InstanceBag.NpcsKilled == 0 ? 1 : 0;
                                perfection += evt.MapInstance.InstanceBag.RoomsVisited >= si.RoomAmount ? 1 : 0;
                                evt.MapInstance.Broadcast($"score  {evt.MapInstance.InstanceBag.EndState} {point} 27 47 18 {si.DrawItems.Count} {evt.MapInstance.InstanceBag.MonstersKilled} {si.NpcAmount - evt.MapInstance.InstanceBag.NpcsKilled} {evt.MapInstance.InstanceBag.RoomsVisited} {perfection} 1 1");
                                client.Character.OnFinishScriptedInstance(
                                    new FinishScriptedInstanceEventArgs(ScriptedInstanceType.TimeSpace, si.Id,
                                                                        point));
                            }
                            break;

                        case MapInstanceType.RaidInstance:
                            evt.MapInstance.InstanceBag.EndState = (byte)evt.Parameter;
                            client = evt.MapInstance.Sessions.FirstOrDefault();
                            if (client != null)
                            {
                                Group grp = client.Character?.Group;
                                if (grp == null)
                                {
                                    return;
                                }
                                if (evt.MapInstance.InstanceBag.EndState == 1 && evt.MapInstance.Monsters.Any(s => s.IsBoss))
                                {
                                    foreach (ClientSession sess in grp.Characters.Where(s => s.CurrentMapInstance.Monsters.Any(e => e.IsBoss)))
                                    {
                                        if (grp.Raid?.GiftItems != null)
                                        {
                                            foreach (Gift gift in grp.Raid.GiftItems)
                                            {
                                                const sbyte rare = 0;
                                                sess.Character.GiftAdd(gift.VNum, gift.Amount, rare, 0,
                                                                       gift.Design, gift.IsRandomRare);
                                            }
                                        }

                                        if (grp.Raid != null)
                                        {
                                            sess.Character.OnFinishScriptedInstance(
                                                new FinishScriptedInstanceEventArgs(ScriptedInstanceType.Raid,
                                                                                    grp.Raid.Id));
                                        }
                                    }
                                    foreach (MapMonster mon in evt.MapInstance.Monsters)
                                    {
                                        mon.CurrentHp = 0;
                                        evt.MapInstance.Broadcast(StaticPacketHelper.Out(UserType.Monster, mon.MapMonsterId));
                                        evt.MapInstance.RemoveMonster(mon);
                                    }

                                    ClientSession leader = grp.Characters.ElementAt(0);

                                    GameLogger.Instance.LogRaidSuccess(ServerManager.Instance.ChannelId,
                                                                       leader.Character.Name, leader.Character.CharacterId, grp.GroupId,
                                                                       grp.Characters.GetAllItems().Select(s => s.Character)
                                                                       .Cast <CharacterDTO>().ToList());

                                    ServerManager.Instance.Broadcast(UserInterfaceHelper.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("RAID_SUCCEED"), grp.Raid?.Label, grp.Characters.ElementAt(0).Character.Name), 0));
                                }

                                Observable.Timer(TimeSpan.FromSeconds(evt.MapInstance.InstanceBag.EndState == 1 ? 30 : 0)).Subscribe(o =>
                                {
                                    ClientSession[] grpmembers = new ClientSession[40];
                                    grp.Characters.CopyTo(grpmembers);
                                    foreach (ClientSession targetSession in grpmembers)
                                    {
                                        if (targetSession != null)
                                        {
                                            if (targetSession.Character.Hp <= 0)
                                            {
                                                targetSession.Character.Hp = 1;
                                                targetSession.Character.Mp = 1;
                                            }
                                            targetSession.SendPacket(Character.GenerateRaidBf(evt.MapInstance.InstanceBag.EndState));
                                            targetSession.SendPacket(targetSession.Character.GenerateRaid(1, true));
                                            targetSession.SendPacket(targetSession.Character.GenerateRaid(2, true));
                                            grp.LeaveGroup(targetSession);
                                        }
                                    }
                                    ServerManager.Instance.GroupList.RemoveAll(s => s.GroupId == grp.GroupId);
                                    ServerManager.Instance.GroupsThreadSafe.Remove(grp.GroupId);
                                    evt.MapInstance.Dispose();
                                });
                            }
                            break;

                        case MapInstanceType.Act4Morcos:
                        case MapInstanceType.Act4Hatus:
                        case MapInstanceType.Act4Calvina:
                        case MapInstanceType.Act4Berios:
                            client = evt.MapInstance.Sessions.FirstOrDefault();
                            if (client != null)
                            {
                                Family fam = evt.MapInstance.Sessions.FirstOrDefault(s => s?.Character?.Family != null)?.Character.Family;
                                if (fam != null)
                                {
                                    fam.Act4Raid.Portals.RemoveAll(s => s.DestinationMapInstanceId.Equals(fam.Act4RaidBossMap.MapInstanceId));
                                    short destX      = 38;
                                    short destY      = 179;
                                    short rewardVNum = 882;
                                    switch (evt.MapInstance.MapInstanceType)
                                    {
                                    //Morcos is default
                                    case MapInstanceType.Act4Hatus:
                                        destX      = 18;
                                        destY      = 10;
                                        rewardVNum = 185;
                                        break;

                                    case MapInstanceType.Act4Calvina:
                                        destX      = 25;
                                        destY      = 7;
                                        rewardVNum = 942;
                                        break;

                                    case MapInstanceType.Act4Berios:
                                        destX      = 16;
                                        destY      = 25;
                                        rewardVNum = 999;
                                        break;
                                    }
                                    int count = evt.MapInstance.Sessions.Count(s => s?.Character != null);
                                    foreach (ClientSession sess in evt.MapInstance.Sessions)
                                    {
                                        if (sess?.Character != null)
                                        {
                                            sess.Character.GiftAdd(rewardVNum, 1, forceRandom: true, minRare: 1, design: 255);
                                            sess.Character.GenerateFamilyXp(10000 / count);
                                        }
                                    }

                                    GameLogger.Instance.LogGuildRaidSuccess(ServerManager.Instance.ChannelId,
                                                                            fam.Name, fam.FamilyId, evt.MapInstance.MapInstanceType,
                                                                            evt.MapInstance.Sessions.Select(s => s.Character).Cast <CharacterDTO>()
                                                                            .ToList());

                                    //TODO: Famlog
                                    CommunicationServiceClient.Instance.SendMessageToCharacter(new ScsCharacterMessage
                                    {
                                        DestinationCharacterId = fam.FamilyId,
                                        SourceCharacterId      = client.Character.CharacterId,
                                        SourceWorldId          = ServerManager.Instance.WorldId,
                                        Message = UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("FAMILYRAID_SUCCESS"), 0),
                                        Type    = MessageType.Family
                                    });

                                    //ServerManager.Instance.Broadcast(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("FAMILYRAID_SUCCESS"), grp?.Raid?.Label, grp.Characters.ElementAt(0).Character.Name), 0));

                                    Observable.Timer(TimeSpan.FromSeconds(30)).Subscribe(o =>
                                    {
                                        foreach (ClientSession targetSession in evt.MapInstance.Sessions.ToArray())
                                        {
                                            if (targetSession != null)
                                            {
                                                if (targetSession.Character.Hp <= 0)
                                                {
                                                    targetSession.Character.Hp = 1;
                                                    targetSession.Character.Mp = 1;
                                                }

                                                ServerManager.Instance.ChangeMapInstance(targetSession.Character.CharacterId, fam.Act4Raid.MapInstanceId, destX, destY);
                                            }
                                        }
                                        evt.MapInstance.Dispose();
                                    });
                                }
                            }
                            break;

                        case MapInstanceType.CaligorInstance:
                            FactionType winningFaction = CaligorRaid.AngelDamage > CaligorRaid.DemonDamage ? FactionType.Angel : FactionType.Demon;
                            foreach (ClientSession sess in evt.MapInstance.Sessions)
                            {
                                if (sess?.Character == null)
                                {
                                    continue;
                                }

                                if (CaligorRaid.RemainingTime > 2400)
                                {
                                    sess.Character.GiftAdd(
                                        sess.Character.Faction == winningFaction
                                                    ? (short)5960
                                                    : (short)5961, 1);
                                }
                                else
                                {
                                    sess.Character.GiftAdd(
                                        sess.Character.Faction == winningFaction
                                                    ? (short)5961
                                                    : (short)5958, 1);
                                }
                                sess.Character.GiftAdd(5959, 1);
                                sess.Character.GenerateFamilyXp(500);
                            }
                            evt.MapInstance.Broadcast(UserInterfaceHelper.GenerateChdm(ServerManager.GetNpcMonster(2305).MaxHP, CaligorRaid.AngelDamage, CaligorRaid.DemonDamage, CaligorRaid.RemainingTime));
                            break;
                        }
                        break;

                    case EventActionType.MapClock:
                        evt.MapInstance.Clock.TotalSecondsAmount = Convert.ToInt32(evt.Parameter);
                        evt.MapInstance.Clock.SecondsRemaining   = Convert.ToInt32(evt.Parameter);
                        break;

                    case EventActionType.StartClock:
                        Tuple <List <EventContainer>, List <EventContainer> > eve = (Tuple <List <EventContainer>, List <EventContainer> >)evt.Parameter;
                        evt.MapInstance.InstanceBag.Clock.StopEvents    = eve.Item1;
                        evt.MapInstance.InstanceBag.Clock.TimeoutEvents = eve.Item2;
                        evt.MapInstance.InstanceBag.Clock.StartClock();
                        evt.MapInstance.Broadcast(evt.MapInstance.InstanceBag.Clock.GetClock());
                        break;

                    case EventActionType.Teleport:
                        Tuple <short, short, short, short> tp = (Tuple <short, short, short, short>)evt.Parameter;
                        List <Character> characters           = evt.MapInstance.GetCharactersInRange(tp.Item1, tp.Item2, 5).ToList();
                        characters.ForEach(s =>
                        {
                            s.PositionX = tp.Item3;
                            s.PositionY = tp.Item4;
                            evt.MapInstance?.Broadcast(s.Session, s.GenerateTp(), ReceiverType.Group);
                        });
                        break;

                    case EventActionType.StopClock:
                        evt.MapInstance.InstanceBag.Clock.StopClock();
                        evt.MapInstance.Broadcast(evt.MapInstance.InstanceBag.Clock.GetClock());
                        break;

                    case EventActionType.StartMapClock:
                        eve = (Tuple <List <EventContainer>, List <EventContainer> >)evt.Parameter;
                        evt.MapInstance.Clock.StopEvents    = eve.Item1;
                        evt.MapInstance.Clock.TimeoutEvents = eve.Item2;
                        evt.MapInstance.Clock.StartClock();
                        evt.MapInstance.Broadcast(evt.MapInstance.Clock.GetClock());
                        break;

                    case EventActionType.StopMapClock:
                        evt.MapInstance.Clock.StopClock();
                        evt.MapInstance.Broadcast(evt.MapInstance.Clock.GetClock());
                        break;

                    case EventActionType.SpawnPortal:
                        evt.MapInstance.CreatePortal((Portal)evt.Parameter);
                        break;

                    case EventActionType.RefreshMapItems:
                        evt.MapInstance.MapClear();
                        break;

                    case EventActionType.NpcsEffectChangeState:
                        evt.MapInstance.Npcs.ForEach(s => s.EffectActivated = (bool)evt.Parameter);
                        break;

                    case EventActionType.ChangePortalType:
                        Tuple <int, PortalType> param = (Tuple <int, PortalType>)evt.Parameter;
                        Portal portal = evt.MapInstance.Portals.Find(s => s.PortalId == param.Item1);
                        if (portal != null)
                        {
                            portal.Type = (short)param.Item2;
                        }
                        break;

                    case EventActionType.ChangeDropRate:
                        evt.MapInstance.DropRate = (int)evt.Parameter;
                        break;

                    case EventActionType.ChangExpRate:
                        evt.MapInstance.XpRate = (int)evt.Parameter;
                        break;

                    case EventActionType.DisposeMap:
                        evt.MapInstance.Dispose();
                        break;

                    case EventActionType.SpawnButton:
                        evt.MapInstance.SpawnButton((MapButton)evt.Parameter);
                        break;

                    case EventActionType.UnspawnMonsters:
                        evt.MapInstance.DespawnMonster((int)evt.Parameter);
                        break;

                    case EventActionType.SpawnMonster:
                        evt.MapInstance.SummonMonster((MonsterToSummon)evt.Parameter);
                        break;

                    case EventActionType.SpawnMonsters:
                        evt.MapInstance.SummonMonsters((List <MonsterToSummon>)evt.Parameter);
                        break;

                    case EventActionType.RefreshRaidGoal:
                        ClientSession cl = evt.MapInstance.Sessions.FirstOrDefault();
                        if (cl?.Character != null)
                        {
                            ServerManager.Instance.Broadcast(cl, cl.Character?.Group?.GeneraterRaidmbf(cl), ReceiverType.Group);
                            ServerManager.Instance.Broadcast(cl, UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("NEW_MISSION"), 0), ReceiverType.Group);
                        }
                        break;

                    case EventActionType.SpawnNpc:
                        evt.MapInstance.SummonNpc((NpcToSummon)evt.Parameter);
                        break;

                    case EventActionType.SpawnNpcs:
                        evt.MapInstance.SummonNpcs((List <NpcToSummon>)evt.Parameter);
                        break;

                    case EventActionType.DropItems:
                        evt.MapInstance.DropItems((List <Tuple <short, int, short, short> >)evt.Parameter);
                        break;

                    case EventActionType.ThrowItems:
                        Tuple <int, short, byte, int, int> parameters = (Tuple <int, short, byte, int, int>)evt.Parameter;
                        if (monster != null)
                        {
                            parameters = new Tuple <int, short, byte, int, int>(monster.MapMonsterId, parameters.Item2, parameters.Item3, parameters.Item4, parameters.Item5);
                        }
                        evt.MapInstance.ThrowItems(parameters);
                        break;

                    case EventActionType.SpawnOnLastEntry:
                        Character lastincharacter = evt.MapInstance.Sessions.OrderByDescending(s => s.RegisterTime).FirstOrDefault()?.Character;
                        List <MonsterToSummon> summonParameters = new List <MonsterToSummon>();
                        MapCell hornSpawn = new MapCell
                        {
                            X = lastincharacter?.PositionX ?? 154,
                            Y = lastincharacter?.PositionY ?? 140
                        };
                        long hornTarget = lastincharacter?.CharacterId ?? -1;
                        summonParameters.Add(new MonsterToSummon(Convert.ToInt16(evt.Parameter), hornSpawn, hornTarget, true));
                        evt.MapInstance.SummonMonsters(summonParameters);
                        break;

                        #endregion
                    }
                }
            }
        }
Exemple #8
0
        /// <summary>
        ///     Run Event
        /// </summary>
        /// <param name="evt">Event Container</param>
        /// <param name="session">Character Session that run the event</param>
        /// <param name="monster">Monster that run the event</param>
        public void RunEvent(EventContainer evt, ClientSession session = null, MapMonster monster = null)
        {
            if (session != null)
            {
                evt.MapInstance = session.CurrentMapInstance;
                switch (evt.EventActionType)
                {
                    #region EventForUser

                case EventActionType.NPCDIALOG:
                    session.SendPacket(session.Character.GenerateNpcDialog((int)evt.Parameter));
                    break;

                case EventActionType.SENDPACKET:
                    session.SendPacket((string)evt.Parameter);
                    break;

                    #endregion
                }
            }

            if (evt.MapInstance == null)
            {
                return;
            }

            switch (evt.EventActionType)
            {
                #region EventForUser

            case EventActionType.NPCDIALOG:
            case EventActionType.SENDPACKET:
                if (session == null)
                {
                    evt.MapInstance.Sessions.ToList().ForEach(e => { RunEvent(evt, e); });
                }

                break;

                #endregion

                #region MapInstanceEvent

            case EventActionType.REGISTEREVENT:
                Tuple <string, ConcurrentBag <EventContainer> > even =
                    (Tuple <string, ConcurrentBag <EventContainer> >)evt.Parameter;
                switch (even.Item1)
                {
                case "OnCharacterDiscoveringMap":
                    even.Item2.ToList().ForEach(s =>
                                                evt.MapInstance.OnCharacterDiscoveringMapEvents.Add(
                                                    new Tuple <EventContainer, List <long> >(s, new List <long>())));
                    break;

                case "OnMoveOnMap":
                    even.Item2.ToList().ForEach(s => evt.MapInstance.OnMoveOnMapEvents.Add(s));
                    break;

                case "OnMapClean":
                    even.Item2.ToList().ForEach(s => evt.MapInstance.OnMapClean.Add(s));
                    break;

                case "OnLockerOpen":
                    if (evt.MapInstance.MapInstanceType == MapInstanceType.RaidInstance)
                    {
                        even.Item2.ToList().ForEach(s => evt.MapInstance.UnlockEvents.Add(s));
                        break;
                    }

                    even.Item2.ToList().ForEach(s => evt.MapInstance.InstanceBag.UnlockEvents.Add(s));
                    break;
                }

                break;

            case EventActionType.REGISTERWAVE:
                evt.MapInstance.WaveEvents.Add((EventWave)evt.Parameter);
                break;

            case EventActionType.SETAREAENTRY:
                var even2 = (ZoneEvent)evt.Parameter;
                evt.MapInstance.OnAreaEntryEvents.Add(even2);
                break;

            case EventActionType.REMOVEMONSTERLOCKER:
                session = evt.MapInstance.Sessions.FirstOrDefault();
                if (evt.MapInstance.MapInstanceType == MapInstanceType.RaidInstance)
                {
                    if (evt.MapInstance.MonsterLocker.Current > 0)
                    {
                        evt.MapInstance.MonsterLocker.Current--;
                    }

                    if (evt.MapInstance.MonsterLocker.Current == 0 && evt.MapInstance.ButtonLocker.Current == 0)
                    {
                        foreach (EventContainer s in evt.MapInstance.UnlockEvents)
                        {
                            RunEvent(s);
                        }

                        evt.MapInstance.UnlockEvents.Clear();
                    }

                    evt.MapInstance.Broadcast(session?.Character?.Group?.GeneraterRaidmbf(evt.MapInstance));
                    break;
                }

                if (evt.MapInstance.InstanceBag.MonsterLocker.Current > 0)
                {
                    evt.MapInstance.InstanceBag.MonsterLocker.Current--;
                }

                if (evt.MapInstance.InstanceBag.MonsterLocker.Current == 0 &&
                    evt.MapInstance.InstanceBag.ButtonLocker.Current == 0)
                {
                    evt.MapInstance.InstanceBag.UnlockEvents.ToList().ForEach(s => RunEvent(s));
                    evt.MapInstance.InstanceBag.UnlockEvents.Clear();
                }

                break;

            case EventActionType.REMOVEBUTTONLOCKER:
                session = evt.MapInstance.Sessions.FirstOrDefault();
                if (evt.MapInstance.MapInstanceType == MapInstanceType.RaidInstance)
                {
                    if (evt.MapInstance.ButtonLocker.Current > 0)
                    {
                        evt.MapInstance.ButtonLocker.Current--;
                    }

                    if (evt.MapInstance.MonsterLocker.Current == 0 && evt.MapInstance.ButtonLocker.Current == 0)
                    {
                        evt.MapInstance.UnlockEvents.ToList().ForEach(s => RunEvent(s));
                        evt.MapInstance.UnlockEvents.Clear();
                    }

                    evt.MapInstance.Broadcast(session?.Character?.Group?.GeneraterRaidmbf(evt.MapInstance));
                    break;
                }

                if (evt.MapInstance.InstanceBag.ButtonLocker.Current > 0)
                {
                    evt.MapInstance.InstanceBag.ButtonLocker.Current--;
                }

                if (evt.MapInstance.InstanceBag.MonsterLocker.Current == 0 &&
                    evt.MapInstance.InstanceBag.ButtonLocker.Current == 0)
                {
                    evt.MapInstance.InstanceBag.UnlockEvents.ToList().ForEach(s => RunEvent(s));
                    evt.MapInstance.InstanceBag.UnlockEvents.Clear();
                }

                break;

            case EventActionType.EFFECT:
                short evt3 = (short)evt.Parameter;
                if (monster != null && (DateTime.Now - monster.LastEffect).TotalSeconds >= 5)
                {
                    evt.MapInstance.Broadcast(monster.GenerateEff(evt3));
                    monster.ShowEffect();
                }

                break;

            case EventActionType.INSTANTBATLLEREWARDS:
                RunEvent(new EventContainer(evt.MapInstance, EventActionType.SPAWNPORTAL,
                                            new Portal {
                    SourceX = 47, SourceY = 33, DestinationMapId = 1
                }));
                evt.MapInstance.Broadcast(
                    UserInterfaceHelper.Instance.GenerateMsg(
                        Language.Instance.GetMessageFromKey("INSTANTBATTLE_SUCCEEDED"), 0));
                Parallel.ForEach(evt.MapInstance.Sessions.Where(s => s.Character != null), cli =>
                {
                    cli.Character.GetReput(cli.Character.Level * 50, true);
                    cli.Character.GetGold(cli.Character.Level * 1000);
                    cli.Character.SpAdditionPoint += cli.Character.Level * 100;
                    cli.Character.SpAdditionPoint  = cli.Character.SpAdditionPoint > 1000000
                            ? 1000000
                            : cli.Character.SpAdditionPoint;
                    cli.SendPacket(cli.Character.GenerateSpPoint());
                    cli.SendPacket(cli.Character.GenerateGold());
                    cli.SendPacket(cli.Character.GenerateSay(
                                       string.Format(Language.Instance.GetMessageFromKey("WIN_SP_POINT"),
                                                     cli.Character.Level * 100), 10));
                });
                break;

            case EventActionType.CONTROLEMONSTERINRANGE:
                if (monster != null)
                {
                    Tuple <short, byte, ConcurrentBag <EventContainer> > evnt =
                        (Tuple <short, byte, ConcurrentBag <EventContainer> >)evt.Parameter;
                    List <MapMonster> mapMonsters =
                        evt.MapInstance.GetListMonsterInRange(monster.MapX, monster.MapY, evnt.Item2);
                    if (evnt.Item1 != 0)
                    {
                        mapMonsters.RemoveAll(s => s.MonsterVNum != evnt.Item1);
                    }

                    mapMonsters.ForEach(s => evnt.Item3.ToList().ForEach(e => RunEvent(e, monster: s)));
                }

                break;

            case EventActionType.ONTARGET:
                if (monster?.MoveEvent != null && monster.MoveEvent.InZone(monster.MapX, monster.MapY))
                {
                    monster.MoveEvent = null;
                    monster.Path      = null;
                    foreach (EventContainer s in (ConcurrentBag <EventContainer>)evt.Parameter)
                    {
                        RunEvent(s, monster: monster);
                    }
                }

                break;

            case EventActionType.MOVE:
                var evt4 = (ZoneEvent)evt.Parameter;
                if (monster != null)
                {
                    monster.MoveEvent = evt4;
                    monster.Path      = BestFirstSearch.FindPathJagged(new Node {
                        X = monster.MapX, Y = monster.MapY
                    },
                                                                       new Node {
                        X = evt4.X, Y = evt4.Y
                    }, evt.MapInstance?.Map.Grid);
                }

                break;

            case EventActionType.CLOCK:
                evt.MapInstance.InstanceBag.Clock.BasesSecondRemaining = Convert.ToInt32(evt.Parameter);
                evt.MapInstance.InstanceBag.Clock.DeciSecondRemaining  = Convert.ToInt32(evt.Parameter);
                break;

            case EventActionType.SETMONSTERLOCKERS:
                if (evt.MapInstance.MapInstanceType == MapInstanceType.RaidInstance)
                {
                    evt.MapInstance.MonsterLocker.Current = Convert.ToByte(evt.Parameter);
                    evt.MapInstance.MonsterLocker.Initial = Convert.ToByte(evt.Parameter);
                    break;
                }

                evt.MapInstance.InstanceBag.MonsterLocker.Current = Convert.ToByte(evt.Parameter);
                evt.MapInstance.InstanceBag.MonsterLocker.Initial = Convert.ToByte(evt.Parameter);
                break;

            case EventActionType.SETBUTTONLOCKERS:
                if (evt.MapInstance.MapInstanceType == MapInstanceType.RaidInstance)
                {
                    evt.MapInstance.ButtonLocker.Current = Convert.ToByte(evt.Parameter);
                    evt.MapInstance.ButtonLocker.Initial = Convert.ToByte(evt.Parameter);
                    break;
                }

                evt.MapInstance.InstanceBag.ButtonLocker.Current = Convert.ToByte(evt.Parameter);
                evt.MapInstance.InstanceBag.ButtonLocker.Initial = Convert.ToByte(evt.Parameter);
                break;

            case EventActionType.SCRIPTEND:
                ClientSession client = evt.MapInstance.Sessions.FirstOrDefault();
                if (client == null)
                {
                    return;
                }

                switch (evt.MapInstance.MapInstanceType)
                {
                case MapInstanceType.TimeSpaceInstance:
                    evt.MapInstance.InstanceBag.EndState = 5;
                    Guid mapInstanceId =
                        ServerManager.Instance.GetBaseMapInstanceIdByMapId(client.Character.MapId);
                    MapInstance      map = ServerManager.Instance.GetMapInstance(mapInstanceId);
                    ScriptedInstance si  = map?.ScriptedInstances?.FirstOrDefault(s =>
                                                                                  s.PositionX == client.Character.MapX && s.PositionY == client.Character.MapY);
                    if (si == null)
                    {
                        return;
                    }

                    byte penalty = (byte)(client.Character.Level - si.LevelMinimum > 50
                                ? 100
                                : (client.Character.Level - si.LevelMinimum) * 2);
                    if (penalty > 0)
                    {
                        client.SendPacket(client.Character.GenerateSay(
                                              string.Format(Language.Instance.GetMessageFromKey("TS_PENALTY"), penalty), 10));
                    }

                    int    point      = evt.MapInstance.InstanceBag.Point * (100 - penalty) / 100;
                    string perfection =
                        $"{(evt.MapInstance.InstanceBag.MonstersKilled >= si.MonsterAmount ? 1 : 0)}{(evt.MapInstance.InstanceBag.NpcsKilled == 0 ? 1 : 0)}{(evt.MapInstance.InstanceBag.RoomsVisited >= si.RoomAmount ? 1 : 0)}";
                    evt.MapInstance.Broadcast(
                        $"score  {evt.MapInstance.InstanceBag.EndState} {point} 27 47 18 {si.DrawItems.Count} {evt.MapInstance.InstanceBag.MonstersKilled} {si.NpcAmount - evt.MapInstance.InstanceBag.NpcsKilled} {evt.MapInstance.InstanceBag.RoomsVisited} {perfection} 1 1");
                    break;

                case MapInstanceType.RaidInstance:
                    evt.MapInstance.InstanceBag.EndState = (byte)evt.Parameter;

                    if (client.Character?.Family?.Act4Raid?.Maps?.FirstOrDefault(m =>
                                                                                 m != client.Character?.Family?.Act4Raid?.FirstMap) ==
                        evt.MapInstance)         // Act 4 raids
                    {
                        ScriptedInstance instance = client.Character?.Family?.Act4Raid;
                        if (instance?.FirstMap == null)
                        {
                            return;
                        }

                        Instance.RunEvent(new EventContainer(instance.FirstMap, EventActionType.REMOVEPORTAL,
                                                             instance.FirstMap.Portals.FirstOrDefault(port =>
                                                                                                      port.DestinationMapInstanceId == client.CurrentMapInstance.MapInstanceId)));
                        Instance.ScheduleEvent(TimeSpan.FromSeconds(5),
                                               new EventContainer(evt.MapInstance, EventActionType.SENDPACKET,
                                                                  UserInterfaceHelper.Instance.GenerateMsg(
                                                                      string.Format(Language.Instance.GetMessageFromKey("TELEPORTED_IN"), 10),
                                                                      0)));
                        int fxpReward = instance.Fxp * ServerManager.Instance.FamilyExpRate;
                        foreach (ClientSession cli in evt.MapInstance.Sessions)
                        {
                            if (DaoFactory.RaidLogDao.LoadByFamilyId(cli.Character.Family.FamilyId).Any(s =>
                                                                                                        s.RaidId == instance.Id && s.Time.AddHours(24) <= DateTime.Now))
                            {
                                // Raid has not been done in the last 24 hours
                                cli.Character.GenerateFamilyXp(fxpReward / evt.MapInstance.Sessions.Count());
                            }
                            else
                            {
                                // Raid has already been done in the last 24 hours
                                cli.Character.GenerateFamilyXp(
                                    fxpReward / 5 / evt.MapInstance.Sessions.Count());
                            }

                            cli.SendPacket(cli.Character.GenerateSay(
                                               string.Format(Language.Instance.GetMessageFromKey("FXP_INCREASE"),
                                                             fxpReward), 11));
                            cli.Character.IncrementQuests(QuestType.WinRaid, instance.Id);
                            if (evt.MapInstance.Sessions.Count(s => s.IpAddress.Equals(cli.IpAddress)) > 2 ||
                                instance.GiftItems == null)
                            {
                                continue;
                            }

                            foreach (Gift gift in instance.GiftItems)
                            {
                                sbyte rare = (sbyte)(gift.IsRandomRare
                                            ? ServerManager.Instance.RandomNumber()
                                            : 0);
                                if (rare > 90)
                                {
                                    rare = 7;
                                }
                                else if (rare > 80)
                                {
                                    rare = 6;
                                }
                                else
                                {
                                    rare = (sbyte)(gift.IsRandomRare
                                                ? ServerManager.Instance.RandomNumber(1, 6)
                                                : 0);
                                }

                                if (cli.Character.Level >= instance.LevelMinimum)
                                {
                                    cli.Character.GiftAdd(gift.VNum, gift.Amount, gift.Design, rare: rare);
                                }
                            }
                        }

                        LogHelper.Instance.InsertFamilyRaidLog(
                            evt.MapInstance.Sessions.FirstOrDefault(s => s.Character.Family != null).Character
                            .Family.FamilyId, instance.Id,
                            DateTime.Now);

                        Observable.Timer(TimeSpan.FromSeconds(15)).Subscribe(s =>
                        {
                            evt.MapInstance.Sessions.ToList().ForEach(cli =>
                                                                      ServerManager.Instance.ChangeMapInstance(cli.Character.CharacterId,
                                                                                                               instance.FirstMap.MapInstanceId, instance.StartX, instance.StartY));
                        });
                        return;
                    }

                    // Raids
                    Group grp = client.Character?.Group;
                    if (grp == null)
                    {
                        return;
                    }

                    if (evt.MapInstance.InstanceBag.EndState == 1 &&
                        evt.MapInstance.Monsters.Any(s => s.IsBoss && !s.IsAlive))
                    {
                        foreach (ClientSession sess in grp.Characters.Where(s =>
                                                                            s.CurrentMapInstance?.Monsters.Any(e => e.IsBoss) == true))
                        {
                            // TODO REMOTE THAT FOR PUBLIC RELEASE
                            if (grp.Characters.Count(s => s.IpAddress.Equals(sess.IpAddress)) > 2 ||
                                grp.Raid?.GiftItems == null)
                            {
                                continue;
                            }

                            if (grp.Raid.Reputation > 0 && sess.Character.Level > grp.Raid.LevelMinimum)
                            {
                                sess.Character.GetReput(grp.Raid.Reputation, true);
                            }

                            sess.Character.Dignity =
                                sess.Character.Dignity < 0 ? sess.Character.Dignity + 100 : 100;

                            if (sess.Character.Level > grp.Raid.LevelMaximum)
                            {
                                sess.Character.GiftAdd(2320, 1);         // RAID CERTIFICATE
                                continue;
                            }

                            if (grp.Raid?.GiftItems == null)
                            {
                                continue;
                            }

                            foreach (Gift gift in grp.Raid.GiftItems)
                            {
                                sbyte rare;
                                if (gift.IsHeroic)
                                {
                                    rare = (sbyte)(gift.IsRandomRare ? ServerManager.Instance.RandomNumber(-2, 9) : 0);
                                }
                                else
                                {
                                    rare = (sbyte)(gift.IsRandomRare ? ServerManager.Instance.RandomNumber(-2, 8) : 0);
                                }

                                if (sess.Character.Level >= grp.Raid.LevelMinimum)
                                {
                                    sess.Character.GiftAdd(gift.VNum, gift.Amount, gift.Design, rare: rare);
                                }
                            }

                            if (DaoFactory.RaidLogDao.LoadByCharacterId(sess.Character.CharacterId).Any(s =>
                                                                                                        s.RaidId == grp.Raid.Id && s.Time.AddHours(24) >= DateTime.Now) ||
                                sess.Character.Family == null)
                            {
                                continue;
                            }

                            int fxpReward = grp.Raid.Fxp * ServerManager.Instance.FamilyExpRate;
                            LogHelper.Instance.InsertRaidLog(sess.Character.CharacterId, grp.Raid.Id,
                                                             DateTime.Now);
                            sess.Character.GenerateFamilyXp(fxpReward);
                            sess.SendPacket(sess.Character.GenerateSay(
                                                string.Format(Language.Instance.GetMessageFromKey("FXP_INCREASE"),
                                                              fxpReward), 11));
                        }

                        // Remove monster when raid is over
                        evt.MapInstance.Monsters.Where(s => !s.IsBoss).ToList()
                        .ForEach(m => evt.MapInstance.DespawnMonster(m));
                        evt.MapInstance.WaveEvents.Clear();

                        ServerManager.Instance.Broadcast(UserInterfaceHelper.Instance.GenerateMsg(
                                                             string.Format(Language.Instance.GetMessageFromKey("RAID_SUCCEED"), grp.Raid?.Label,
                                                                           grp.Characters.ElementAt(0).Character.Name), 0));
                    }

                    Observable.Timer(TimeSpan.FromSeconds(evt.MapInstance.InstanceBag.EndState == 1 ? 30 : 0))
                    .Subscribe(obj =>
                    {
                        ClientSession[] grpmembers = new ClientSession[40];
                        grp.Characters.ToList().CopyTo(grpmembers);
                        foreach (ClientSession targetSession in grpmembers)
                        {
                            if (targetSession == null)
                            {
                                continue;
                            }

                            if (targetSession.Character.Hp <= 0)
                            {
                                targetSession.Character.Hp = 1;
                                targetSession.Character.Mp = 1;
                            }

                            targetSession.SendPacket(
                                targetSession.Character.GenerateRaidBf(evt.MapInstance.InstanceBag
                                                                       .EndState));
                            targetSession.SendPacket(targetSession.Character.GenerateRaid(1, true));
                            targetSession.SendPacket(targetSession.Character.GenerateRaid(2, true));
                            grp.LeaveGroup(targetSession);
                        }

                        ServerManager.Instance.GroupList.RemoveAll(s => s.GroupId == grp.GroupId);
                        ServerManager.Instance._groups.TryRemove(grp.GroupId, out Group _);
                        grp?.Raid?.MapInstanceDictionary?.Values?.ToList().ForEach(m => m?.Dispose());
                    });
                    break;

                case MapInstanceType.CaligorInstance:
                    FactionType winningFaction = Caligor.AngelDamage > Caligor.DemonDamage
                                ? FactionType.Angel
                                : FactionType.Demon;

                    foreach (ClientSession player in evt.MapInstance.Sessions)
                    {
                        if (player == null)
                        {
                            continue;
                        }

                        if (Caligor.RaidTime > 2400)
                        {
                            player.Character.GiftAdd(
                                player.Character.Faction == winningFaction ? (short)5960 : (short)5961, 1);
                        }
                        else
                        {
                            player.Character.GiftAdd(
                                player.Character.Faction == winningFaction ? (short)5961 : (short)5958, 1);
                        }

                        player.Character.GiftAdd(5959, 1);
                        player.Character.GenerateFamilyXp(500 * ServerManager.Instance.FamilyExpRate);
                    }

                    break;
                }

                break;

            case EventActionType.MAPCLOCK:
                evt.MapInstance.Clock.BasesSecondRemaining = Convert.ToInt32(evt.Parameter);
                evt.MapInstance.Clock.DeciSecondRemaining  = Convert.ToInt32(evt.Parameter);
                break;

            case EventActionType.STARTCLOCK:
                Tuple <ConcurrentBag <EventContainer>, ConcurrentBag <EventContainer> > eve =
                    (Tuple <ConcurrentBag <EventContainer>, ConcurrentBag <EventContainer> >)evt.Parameter;
                if (eve != null)
                {
                    evt.MapInstance.InstanceBag.Clock.StopEvents    = eve.Item2.ToList();
                    evt.MapInstance.InstanceBag.Clock.TimeoutEvents = eve.Item1.ToList();
                    evt.MapInstance.InstanceBag.Clock.StartClock();
                    evt.MapInstance.Broadcast(evt.MapInstance.InstanceBag.Clock.GetClock());
                }

                break;

            case EventActionType.TELEPORT:
                Tuple <short, short, short, short> tp = (Tuple <short, short, short, short>)evt.Parameter;
                List <Character> characters           = evt.MapInstance.GetCharactersInRange(tp.Item1, tp.Item2, 5).ToList();
                characters.ForEach(s =>
                {
                    s.PositionX = tp.Item3;
                    s.PositionY = tp.Item4;
                    evt.MapInstance?.Broadcast(s.Session, s.GenerateTp(), ReceiverType.Group);
                });
                break;

            case EventActionType.STOPCLOCK:
                evt.MapInstance.InstanceBag.Clock.StopClock();
                evt.MapInstance.Broadcast(evt.MapInstance.InstanceBag.Clock.GetClock());
                break;

            case EventActionType.STARTMAPCLOCK:
                eve = (Tuple <ConcurrentBag <EventContainer>, ConcurrentBag <EventContainer> >)evt.Parameter;
                if (eve != null)
                {
                    evt.MapInstance.Clock.StopEvents    = eve.Item2.ToList();
                    evt.MapInstance.Clock.TimeoutEvents = eve.Item1.ToList();
                    evt.MapInstance.Clock.StartClock();
                    evt.MapInstance.Broadcast(evt.MapInstance.Clock.GetClock());
                }

                break;

            case EventActionType.STOPMAPCLOCK:
                evt.MapInstance.Clock.StopClock();
                evt.MapInstance.Broadcast(evt.MapInstance.Clock.GetClock());
                break;

            case EventActionType.SPAWNPORTAL:
                evt.MapInstance.CreatePortal((Portal)evt.Parameter);
                break;

            case EventActionType.REFRESHMAPITEMS:
                evt.MapInstance.MapClear();
                break;

            case EventActionType.NPCSEFFECTCHANGESTATE:
                evt.MapInstance.Npcs.ForEach(s => s.EffectActivated = (bool)evt.Parameter);
                break;

            case EventActionType.CHANGEPORTALTYPE:
                Tuple <int, PortalType> param = (Tuple <int, PortalType>)evt.Parameter;
                Portal portal = evt.MapInstance.Portals.FirstOrDefault(s => s.PortalId == param.Item1);
                if (portal != null)
                {
                    portal.Type = (short)param.Item2;
                }

                break;

            case EventActionType.CHANGEDROPRATE:
                evt.MapInstance.DropRate = (int)evt.Parameter;
                break;

            case EventActionType.CHANGEXPRATE:
                evt.MapInstance.XpRate = (int)evt.Parameter;
                break;

            case EventActionType.DISPOSEMAP:
                evt.MapInstance.Dispose();
                break;

            case EventActionType.SPAWNBUTTON:
                evt.MapInstance.SpawnButton((MapButton)evt.Parameter);
                break;

            case EventActionType.UNSPAWNMONSTERS:
                evt.MapInstance.DespawnMonster((int)evt.Parameter);
                break;

            case EventActionType.SPAWNMONSTERS:
                evt.MapInstance.SummonMonsters(((ConcurrentBag <ToSummon>)evt.Parameter).ToList());
                break;

            case EventActionType.REFRESHRAIDGOAL:
                ClientSession cl = evt.MapInstance.Sessions.FirstOrDefault();
                if (cl?.Character != null)
                {
                    evt.MapInstance.Broadcast(cl.Character?.Group?.GeneraterRaidmbf(evt.MapInstance));
                    ServerManager.Instance.Broadcast(cl,
                                                     UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("NEW_MISSION"),
                                                                                              0), ReceiverType.Group);
                }

                break;

            case EventActionType.SPAWNNPCS:
                evt.MapInstance.SummonNpcs((List <ToSummon>)evt.Parameter);
                break;

            case EventActionType.DROPITEMS:
                evt.MapInstance.DropItems((List <Tuple <short, int, short, short> >)evt.Parameter);
                break;

            case EventActionType.THROWITEMS:
                Tuple <int, short, byte, int, int> parameters = (Tuple <int, short, byte, int, int>)evt.Parameter;
                if (monster != null)
                {
                    parameters = new Tuple <int, short, byte, int, int>(monster.MapMonsterId, parameters.Item2,
                                                                        parameters.Item3, parameters.Item4, parameters.Item5);
                }

                evt.MapInstance.ThrowItems(parameters);
                break;

            case EventActionType.SPAWNONLASTENTRY:
                Character lastincharacter = evt.MapInstance.Sessions.OrderByDescending(s => s.RegisterTime)
                                            .FirstOrDefault()?.Character;
                List <ToSummon> summonParameters = new List <ToSummon>();
                var             hornSpawn        = new MapCell
                {
                    X = lastincharacter?.PositionX ?? 154,
                    Y = lastincharacter?.PositionY ?? 140
                };
                summonParameters.Add(new ToSummon(Convert.ToInt16(evt.Parameter), hornSpawn, lastincharacter,
                                                  true));
                evt.MapInstance.SummonMonsters(summonParameters);
                break;

            case EventActionType.REMOVEPORTAL:
                Portal portalToRemove = null;
                lock (evt.MapInstance.Portals)
                {
                    portalToRemove = evt.Parameter is Portal p
                            ? evt.MapInstance.Portals.FirstOrDefault(s => s == p)
                            : evt.MapInstance.Portals.FirstOrDefault(s => s.PortalId == (int)evt.Parameter);
                }
                if (portalToRemove == null)
                {
                    return;
                }

                evt.MapInstance.Portals.Remove(portalToRemove);
                evt.MapInstance.MapClear();
                break;

            case EventActionType.ACT4RAIDEND:
                // tp // tp X // tp Y
                Tuple <MapInstance, short, short> endParameters = (Tuple <MapInstance, short, short>)evt.Parameter;
                Observable.Timer(TimeSpan.FromSeconds(5)).Subscribe(a =>
                {
                    evt.MapInstance.Broadcast(
                        $"{UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("TELEPORTED_IN"), 10), 0)}");

                    Observable.Timer(TimeSpan.FromSeconds(10)).Subscribe(s =>
                    {
                        evt.MapInstance.Sessions.ToList().ForEach(cli =>
                                                                  ServerManager.Instance.ChangeMapInstance(cli.Character.CharacterId,
                                                                                                           endParameters.Item1.MapInstanceId, endParameters.Item2, endParameters.Item3));
                    });
                });
                break;

            case EventActionType.CLEARMAPMONSTERS:
                evt.MapInstance.Monsters.ForEach(m => evt.MapInstance.DespawnMonster(m));
                break;

            case EventActionType.STARTACT4RAID:
                Tuple <byte, byte> raidParameters = (Tuple <byte, byte>)evt.Parameter;
                PercentBar         stat           = raidParameters.Item2 == (byte)FactionType.Angel
                        ? ServerManager.Instance.Act4AngelStat
                        : ServerManager.Instance.Act4DemonStat;
                stat.Mode      = 3;
                stat.TotalTime = 3600;
                Act4Raid.Instance.GenerateRaid(raidParameters.Item1, raidParameters.Item2);
                switch ((Act4RaidType)raidParameters.Item1)
                {
                case Act4RaidType.Morcos:
                    stat.IsMorcos = true;
                    break;

                case Act4RaidType.Hatus:
                    stat.IsHatus = true;
                    break;

                case Act4RaidType.Calvina:
                    stat.IsCalvina = true;
                    break;

                case Act4RaidType.Berios:
                    stat.IsBerios = true;
                    break;
                }

                break;

            case EventActionType.ONTIMEELAPSED:
                Tuple <int, ConcurrentBag <EventContainer> > timeElapsedEvts =
                    (Tuple <int, ConcurrentBag <EventContainer> >)evt.Parameter;
                Observable.Timer(TimeSpan.FromSeconds(timeElapsedEvts.Item1)).Subscribe(e => { timeElapsedEvts.Item2.ToList().ForEach(ev => RunEvent(ev)); });
                break;

                #endregion
            }
        }