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); } }
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 } } }