Inheritance: MappingBaseDTO
示例#1
0
文件: Map.cs 项目: OpenNos/OpenNos
        public void DropItemByMonster(long? Owner, DropDTO drop, short mapX, short mapY, int gold = 0)
        {
            try
            {
                MonsterMapItem droppedItem = null;
                short localMapX = (short)(_random.Next(mapX - 1, mapX + 1));
                short localMapY = (short)(_random.Next(mapY - 1, mapY + 1));
                List<MapCell> Possibilities = new List<MapCell>();

                for (short x = -1; x < 2; x++)
                {
                    for (short y = -1; y < 2; y++)
                    {
                        Possibilities.Add(new MapCell() { X = x, Y = y });
                    }
                }

                foreach (MapCell possibilitie in Possibilities.OrderBy(s => _random.Next()))
                {
                    localMapX = (short)(mapX + possibilitie.X);
                    localMapY = (short)(mapY + possibilitie.Y);
                    if (!IsBlockedZone(localMapX, localMapY))
                    {
                        break;
                    }
                }

                droppedItem = new MonsterMapItem(localMapX, localMapY, drop.ItemVNum, drop.Amount, Owner ?? -1);

                DroppedList[droppedItem.TransportId] = droppedItem;

                Broadcast($"drop {droppedItem.ItemVNum} {droppedItem.TransportId} {droppedItem.PositionX} {droppedItem.PositionY} {(droppedItem.GoldAmount > 1 ? droppedItem.GoldAmount : droppedItem.Amount)} 0 0 -1");
            }
            catch (Exception e)
            {
                Logger.Error(e);
            }
        }
示例#2
0
        public void GenerateKillBonus(MapMonster monsterToAttack)
        {
            if (monsterToAttack == null || monsterToAttack.IsAlive)
            {
                return;
            }

            Random random = new Random(DateTime.Now.Millisecond & monsterToAttack.MapMonsterId);

            // owner set
            long? dropOwner = monsterToAttack.DamageList.Any() ? monsterToAttack.DamageList.First().Key : (long?)null;
            Group group = null;
            if (dropOwner != null)
            {
                group = ServerManager.Instance.Groups.FirstOrDefault(g => g.IsMemberOfGroup((long)dropOwner));
            }

            // end owner set
            int i = 1;
            if (Session.HasCurrentMap)
            {
                List<DropDTO> droplist = monsterToAttack.Monster.Drops.Where(s => Session.CurrentMap.MapTypes.Any(m => m.MapTypeId == s.MapTypeId) || (s.MapTypeId == null)).ToList();
                if (monsterToAttack.Monster.MonsterType != MonsterType.Special)
                {
                    #region item drop

                    int dropRate = ServerManager.DropRate;
                    int x = 0;
                    foreach (DropDTO drop in droplist.OrderBy(s => random.Next()))
                    {
                        if (x < 4)
                        {
                            i++;
                            double rndamount = random.Next(0, 100) * random.NextDouble();
                            if (rndamount <= ((double)drop.DropChance * dropRate) / 5000.000)
                            {
                                x++;
                                if (Session.CurrentMap != null)
                                {
                                    if (Session.CurrentMap.MapTypes.Any(s => s.MapTypeId == (short)MapTypeEnum.Act4) || monsterToAttack.Monster.MonsterType == MonsterType.Elite)
                                    {
                                        List<long> alreadyGifted = new List<long>();
                                        foreach (long charId in monsterToAttack.DamageList.Keys)
                                        {
                                            if (!alreadyGifted.Contains(charId))
                                            {
                                                ClientSession giftsession = ServerManager.Instance.GetSessionByCharacterId(charId);
                                                giftsession?.Character.GiftAdd(drop.ItemVNum, (byte)drop.Amount);
                                                alreadyGifted.Add(charId);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (group != null)
                                        {
                                            if (group.SharingMode == (byte)GroupSharingType.ByOrder)
                                            {
                                                dropOwner = group.GetNextOrderedCharacterId(this);
                                                if (dropOwner.HasValue)
                                                {
                                                    group.Characters.ForEach(s => s.SendPacket(s.Character.GenerateSay(String.Format(Language.Instance.GetMessageFromKey("ITEM_BOUND_TO"), ServerManager.GetItem(drop.ItemVNum).Name, group.Characters.Single(c => c.Character.CharacterId == (long)dropOwner).Character.Name, drop.Amount), 10)));
                                                }
                                            }
                                            else
                                            {
                                                group.Characters.ForEach(s => s.SendPacket(s.Character.GenerateSay(String.Format(Language.Instance.GetMessageFromKey("DROPPED_ITEM"), ServerManager.GetItem(drop.ItemVNum).Name, drop.Amount), 10)));
                                            }
                                        }

                                        long? owner = dropOwner;
                                        Observable.Timer(TimeSpan.FromMilliseconds(500))
                                       .Subscribe(
                                       o =>
                                       {
                                           Session.CurrentMap.DropItemByMonster(owner, drop, monsterToAttack.MapX, monsterToAttack.MapY);
                                       });
                                    }
                                }
                            }
                        }
                    }

                    #endregion

                    #region gold drop

                    // gold calculation
                    int gold = GetGold(monsterToAttack);
                    gold = gold > 1000000000 ? 1000000000 : gold;
                    double randChance = random.Next(0, 100) * random.NextDouble();

                    if (gold > 0 && randChance <= (int)((ServerManager.GoldDropRate * 10) * CharacterHelper.GoldPenalty(Level, monsterToAttack.Monster.Level)))
                    {
                        DropDTO drop2 = new DropDTO()
                        {
                            Amount = gold,
                            ItemVNum = 1046
                        };
                        if (Session.CurrentMap != null)
                        {
                            if (Session.CurrentMap.MapTypes.Any(s => s.MapTypeId == (short)MapTypeEnum.Act4) || monsterToAttack.Monster.MonsterType == MonsterType.Elite)
                            {
                                List<long> alreadyGifted = new List<long>();
                                foreach (long charId in monsterToAttack.DamageList.Keys)
                                {
                                    if (!alreadyGifted.Contains(charId))
                                    {
                                        ClientSession session = ServerManager.Instance.GetSessionByCharacterId(charId);
                                        if (session != null)
                                        {
                                            session.Character.Gold += drop2.Amount;
                                            if (session.Character.Gold > 1000000000)
                                            {
                                                session.Character.Gold = 1000000000;
                                                session.SendPacket(session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("MAX_GOLD"), 0));
                                            }
                                            session.SendPacket(session.Character.GenerateSay($"{Language.Instance.GetMessageFromKey("ITEM_ACQUIRED")}: {ServerManager.GetItem(drop2.ItemVNum).Name} x {drop2.Amount}", 10));
                                            session.SendPacket(session.Character.GenerateGold());
                                        }
                                        alreadyGifted.Add(charId);
                                    }
                                }
                            }
                            else
                            {
                                if (group != null)
                                {
                                    if (group.SharingMode == (byte)GroupSharingType.ByOrder)
                                    {
                                        dropOwner = group.GetNextOrderedCharacterId(this);

                                        if (dropOwner.HasValue)
                                        {
                                            group.Characters.ForEach(s => s.SendPacket(s.Character.GenerateSay(String.Format(Language.Instance.GetMessageFromKey("ITEM_BOUND_TO"), ServerManager.GetItem(drop2.ItemVNum).Name, group.Characters.Single(c => c.Character.CharacterId == (long)dropOwner).Character.Name, drop2.Amount), 10)));
                                        }
                                    }
                                    else
                                    {
                                        group.Characters.ForEach(s => s.SendPacket(s.Character.GenerateSay(String.Format(Language.Instance.GetMessageFromKey("DROPPED_ITEM"), ServerManager.GetItem(drop2.ItemVNum).Name, drop2.Amount), 10)));
                                    }
                                }

                                // delayed Drop
                                Observable.Timer(TimeSpan.FromMilliseconds(500))
                                      .Subscribe(
                                      o =>
                                      {
                                          Session.CurrentMap.DropItemByMonster(dropOwner, drop2, monsterToAttack.MapX, monsterToAttack.MapY);
                                      });
                            }
                        }
                    }

                    #endregion

                    #region exp

                    if (Hp > 0)
                    {
                        Group grp = ServerManager.Instance.Groups.FirstOrDefault(g => g.IsMemberOfGroup(CharacterId));
                        if (grp != null)
                        {
                            foreach (ClientSession targetSession in grp.Characters.Where(g => g.Character.MapId == MapId))
                            {
                                if (grp.IsMemberOfGroup(monsterToAttack.DamageList.FirstOrDefault().Key))
                                {
                                    targetSession.Character.GenerateXp(monsterToAttack.Monster, true);
                                }
                                else
                                {
                                    targetSession.SendPacket(targetSession.Character.GenerateSay(Language.Instance.GetMessageFromKey("XP_NOTFIRSTHIT"), 10));
                                    targetSession.Character.GenerateXp(monsterToAttack.Monster, false);
                                }
                            }
                        }
                        else
                        {
                            if (monsterToAttack.DamageList.FirstOrDefault().Key == CharacterId)
                            {
                                GenerateXp(monsterToAttack.Monster, true);
                            }
                            else
                            {
                                Session.SendPacket(GenerateSay(Language.Instance.GetMessageFromKey("XP_NOTFIRSTHIT"), 10));
                                GenerateXp(monsterToAttack.Monster, false);
                            }
                        }
                        GenerateDignity(monsterToAttack.Monster);
                    }

                    #endregion
                }
            }
        }