public override void Use(ClientSession session, ref ItemInstance inv, byte Option = 0, string[] packetsplit = null) { if (session.Character.IsVehicled) { session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("CANT_DO_VEHICLED"), 10)); return; } if (session.CurrentMapInstance.MapInstanceType == MapInstanceType.TalentArenaMapInstance) { return; } if (inv.ItemVNum == 2539 || inv.ItemVNum == 10066) { session.SendPacket(session.Character.GenerateGB(3)); session.SendPacket(session.Character.GenerateSMemo(6, "A warm welcome to the Cuarry Bank. You can deposit or withdraw from 1,000 to 1 billion units of gold.")); session.Character.Inventory.RemoveItemFromInventory(inv.Id); } switch (Effect) { // airwaves - eventitems case 0: if (inv.Item.ItemType == ItemType.Shell) { if (!(inv).ShellEffects.Any()) { session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("SHELL_MUST_BE_IDENTIFIED"), 0)); return; } if (packetsplit?.Length < 9) { return; } if (!int.TryParse(packetsplit[6], out int requestType)) { return; } if (!Enum.TryParse(packetsplit[8], out InventoryType eqType)) { return; } if (inv.ShellEffects.Count != 0 && packetsplit?.Length > 9 && byte.TryParse(packetsplit[9], out byte islot)) { ItemInstance wearable = session.Character.Inventory.LoadBySlotAndType(islot, InventoryType.Equipment); if (wearable != null && (wearable.Item.ItemType == ItemType.Weapon || wearable.Item.ItemType == ItemType.Armor) && wearable.Item.LevelMinimum >= inv.Upgrade && wearable.Rare >= inv.Rare && !wearable.Item.IsHeroic) { switch (requestType) { case 0: session.SendPacket(wearable.ShellEffects.Any() ? $"qna #u_i^1^{session.Character.CharacterId}^{(short)inv.Type}^{inv.Slot}^1^1^{(short)eqType}^{islot} {Language.Instance.GetMessageFromKey("ADD_OPTION_ON_STUFF_NOT_EMPTY")}" : $"qna #u_i^1^{session.Character.CharacterId}^{(short)inv.Type}^{inv.Slot}^1^1^{(short)eqType}^{islot} {Language.Instance.GetMessageFromKey("ADD_OPTION_ON_STUFF")}"); break; case 1: if (inv.ShellEffects == null) { return; } if (wearable.BoundCharacterId != session.Character.CharacterId && wearable.BoundCharacterId != null) { session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("NEED_FRAGANCE"), 0)); return; } if (wearable.Rare < inv.Rare) { session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("SHELL_RARITY_TOO_HIGH"), 0)); return; } if (wearable.Item.LevelMinimum < inv.Upgrade) { session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("SHELL_LEVEL_TOO_HIGH"), 0)); return; } bool weapon = false; if ((inv.ItemVNum >= 565 && inv.ItemVNum <= 576) || (inv.ItemVNum >= 589 && inv.ItemVNum <= 598)) { weapon = true; } else if ((inv.ItemVNum >= 577 && inv.ItemVNum <= 588) || (inv.ItemVNum >= 656 && inv.ItemVNum <= 664) || inv.ItemVNum == 599) { weapon = false; } else { return; } if ((wearable.Item.ItemType == ItemType.Weapon && weapon) || (wearable.Item.ItemType == ItemType.Armor && !weapon)) { if (wearable.ShellEffects.Count > 0 && ServerManager.RandomNumber() < 50) { session.Character.DeleteItemByItemInstanceId(inv.Id); session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("OPTION_FAIL"), 0)); return; } wearable.BoundCharacterId = session.Character.CharacterId; wearable.ShellRarity = inv.Rare; wearable.ShellEffects.Clear(); DAOFactory.ShellEffectDAO.DeleteByEquipmentSerialId(wearable.EquipmentSerialId); wearable.ShellEffects.AddRange(inv.ShellEffects); if (wearable.EquipmentSerialId == Guid.Empty) { wearable.EquipmentSerialId = Guid.NewGuid(); } DAOFactory.ShellEffectDAO.InsertOrUpdateFromList(wearable.ShellEffects, wearable.EquipmentSerialId); session.Character.DeleteItemByItemInstanceId(inv.Id); session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("OPTION_SUCCESS"), 0)); } break; } } } return; } if (ItemType == ItemType.Event) { session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, EffectValue)); if (MappingHelper.GuriItemEffects.ContainsKey(EffectValue)) { session.CurrentMapInstance?.Broadcast(UserInterfaceHelper.GenerateGuri(19, 1, session.Character.CharacterId, MappingHelper.GuriItemEffects[EffectValue]), session.Character.PositionX, session.Character.PositionY); } session.Character.Inventory.RemoveItemFromInventory(inv.Id); } break; //respawn objects case 1: if (session.Character.MapInstance.MapInstanceType != MapInstanceType.BaseMapInstance || session.Character.IsSeal) { session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("CANT_USE_THAT"), 10)); return; } int type, secondaryType, inventoryType, slot; if (packetsplit?.Length > 6 && int.TryParse(packetsplit[2], out type) && int.TryParse(packetsplit[3], out secondaryType) && int.TryParse(packetsplit[4], out inventoryType) && int.TryParse(packetsplit[5], out slot)) { int packetType; switch (EffectValue) { case 0: if (inv.ItemVNum != 2070 && inv.ItemVNum != 10010 || (session.CurrentMapInstance.Map.MapTypes.Any(m => m.MapTypeId == (short)MapTypeEnum.Act51 || m.MapTypeId == (short)MapTypeEnum.Act52))) { return; } if (Option == 0) { if (ServerManager.Instance.ChannelId == 51) { session.SendPacket(UserInterfaceHelper.GenerateDialog($"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^2 #u_i^{type}^{secondaryType}^{inventoryType}^{slot}^0 {Language.Instance.GetMessageFromKey("WANT_TO_GO_BASE")}")); } else { session.SendPacket(UserInterfaceHelper.GenerateDialog($"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^1 #u_i^{type}^{secondaryType}^{inventoryType}^{slot}^2 {Language.Instance.GetMessageFromKey("WANT_TO_SAVE_POSITION")}")); } } else if (int.TryParse(packetsplit[6], out packetType)) { switch (packetType) { case 1: session.SendPacket(UserInterfaceHelper.GenerateDelay(5000, 7, $"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^3")); break; case 2: session.SendPacket(UserInterfaceHelper.GenerateDelay(5000, 7, $"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^4")); break; case 3: session.Character.SetReturnPoint(session.Character.MapId, session.Character.MapX, session.Character.MapY); RespawnMapTypeDTO respawn = session.Character.Respawn; if (respawn.DefaultX != 0 && respawn.DefaultY != 0 && respawn.DefaultMapId != 0) { MapCell mapCell = new MapCell(); for (int i = 0; i < 5; i++) { mapCell.X = (short)(respawn.DefaultX + ServerManager.RandomNumber(-3, 3)); mapCell.Y = (short)(respawn.DefaultY + ServerManager.RandomNumber(-3, 3)); if (ServerManager.GetMapInstanceByMapId(respawn.DefaultMapId) is MapInstance GoToMap) { if (!GoToMap.Map.IsBlockedZone(mapCell.X, mapCell.Y)) { break; } } } ServerManager.Instance.ChangeMap(session.Character.CharacterId, respawn.DefaultMapId, mapCell.X, mapCell.Y); } session.Character.Inventory.RemoveItemFromInventory(inv.Id); break; case 4: RespawnMapTypeDTO respawnObj = session.Character.Respawn; if (ServerManager.Instance.ChannelId == 51) { respawnObj.DefaultMapId = (short)(129 + session.Character.Faction); respawnObj.DefaultX = 41; respawnObj.DefaultY = 42; } if (respawnObj.DefaultX != 0 && respawnObj.DefaultY != 0 && respawnObj.DefaultMapId != 0) { MapCell mapCell = new MapCell(); for (int i = 0; i < 5; i++) { mapCell.X = (short)(respawnObj.DefaultX + ServerManager.RandomNumber(-3, 3)); mapCell.Y = (short)(respawnObj.DefaultY + ServerManager.RandomNumber(-3, 3)); if (ServerManager.GetMapInstanceByMapId(respawnObj.DefaultMapId) is MapInstance GoToMap) { if (!GoToMap.Map.IsBlockedZone(mapCell.X, mapCell.Y)) { break; } } } ServerManager.Instance.ChangeMap(session.Character.CharacterId, respawnObj.DefaultMapId, mapCell.X, mapCell.Y); } session.Character.Inventory.RemoveItemFromInventory(inv.Id); break; } } break; case 1: if (inv.ItemVNum != 2071 && inv.ItemVNum != 10011) { return; } if (int.TryParse(packetsplit[6], out packetType)) { if (ServerManager.Instance.ChannelId == 51) { session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("CANNOT_USE"), 10)); return; } RespawnMapTypeDTO respawn = session.Character.Return; switch (packetType) { case 0: if (respawn.DefaultX != 0 && respawn.DefaultY != 0 && respawn.DefaultMapId != 0) { session.SendPacket(UserInterfaceHelper.GenerateRp(respawn.DefaultMapId, respawn.DefaultX, respawn.DefaultY, $"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^1")); } break; case 1: session.SendPacket(UserInterfaceHelper.GenerateDelay(5000, 7, $"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^2")); break; case 2: if (respawn.DefaultX != 0 && respawn.DefaultY != 0 && respawn.DefaultMapId != 0) { ServerManager.Instance.ChangeMap(session.Character.CharacterId, respawn.DefaultMapId, respawn.DefaultX, respawn.DefaultY); } session.Character.Inventory.RemoveItemFromInventory(inv.Id); break; } } break; case 2: if (inv.ItemVNum != 2072 && inv.ItemVNum != 10012) { return; } if (Option == 0) { session.SendPacket(UserInterfaceHelper.GenerateDelay(5000, 7, $"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^1")); } else { ServerManager.Instance.JoinMiniland(session, session); session.Character.Inventory.RemoveItemFromInventory(inv.Id); } break; case 4: if (inv.ItemVNum != 2188 || session.Character.MapInstance.Map.MapTypes.Any(s => s.MapTypeId == (short)MapTypeEnum.Act4)) { return; } if (Option == 0) { session.SendPacket(UserInterfaceHelper.GenerateDelay(5000, 7, $"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^1")); } else { ServerManager.Instance.ChangeMap(session.Character.CharacterId, 98, 28, 34); session.Character.Inventory.RemoveItemFromInventory(inv.Id); } break; case 5: if (inv.ItemVNum != 2311 || ServerManager.Instance.ChannelId != 51) { return; } if (ServerManager.GetAllMapInstances().SelectMany(s => s.Monsters.ToList()).LastOrDefault(s => s.MonsterVNum == (short)session.Character.Faction + 964) is MapMonster flag) { if (Option == 0) { session.SendPacket(UserInterfaceHelper.GenerateDelay(5000, 7, $"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^1")); } else { ServerManager.Instance.ChangeMapInstance(session.Character.CharacterId, flag.MapInstance.MapInstanceId, flag.MapX, flag.MapY); session.Character.Inventory.RemoveItemFromInventory(inv.Id); } } break; case 6: if (inv.ItemVNum != 2384 || ServerManager.Instance.ChannelId == 51 || session.CurrentMapInstance.MapInstanceType != MapInstanceType.BaseMapInstance) { return; } if (Option == 0) { session.SendPacket(UserInterfaceHelper.GenerateDialog($"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^1 #u_i^{type}^{secondaryType}^{inventoryType}^{slot}^2 {Language.Instance.GetMessageFromKey("WANT_TO_SAVE_POSITION")}")); } else if (int.TryParse(packetsplit[6], out packetType)) { switch (packetType) { case 1: session.SendPacket(UserInterfaceHelper.GenerateDelay(5000, 7, $"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^3")); break; case 2: session.SendPacket(UserInterfaceHelper.GenerateDelay(5000, 7, $"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^4")); break; case 3: if (session.CurrentMapInstance.Map.MapTypes.Any(s => s.MapTypeId == (short)MapTypeEnum.Act51 || s.MapTypeId == (short)MapTypeEnum.Act52)) { session.Character.SetReturnPoint(session.Character.MapId, session.Character.MapX, session.Character.MapY); RespawnMapTypeDTO respawn = session.Character.Respawn; if (respawn.DefaultX != 0 && respawn.DefaultY != 0 && respawn.DefaultMapId != 0) { MapCell mapCell = new MapCell(); for (int i = 0; i < 5; i++) { mapCell.X = (short)(respawn.DefaultX + ServerManager.RandomNumber(-3, 3)); mapCell.Y = (short)(respawn.DefaultY + ServerManager.RandomNumber(-3, 3)); if (ServerManager.GetMapInstanceByMapId(respawn.DefaultMapId) is MapInstance GoToMap) { if (!GoToMap.Map.IsBlockedZone(mapCell.X, mapCell.Y)) { break; } } } ServerManager.Instance.ChangeMap(session.Character.CharacterId, respawn.DefaultMapId, mapCell.X, mapCell.Y); } session.Character.Inventory.RemoveItemFromInventory(inv.Id); } else { goto case 4; } break; case 4: MapInstance mapInstanceBackup = session.CurrentMapInstance; session.CurrentMapInstance = ServerManager.GetMapInstanceByMapId(170); RespawnMapTypeDTO respawnObj = session.Character.Respawn; session.CurrentMapInstance = mapInstanceBackup; if (ServerManager.Instance.ChannelId == 51) { respawnObj.DefaultMapId = (short)(129 + session.Character.Faction); respawnObj.DefaultX = 41; respawnObj.DefaultY = 42; } if (respawnObj.DefaultX != 0 && respawnObj.DefaultY != 0 && respawnObj.DefaultMapId != 0) { MapCell mapCell = new MapCell(); for (int i = 0; i < 5; i++) { mapCell.X = (short)(respawnObj.DefaultX + ServerManager.RandomNumber(-3, 3)); mapCell.Y = (short)(respawnObj.DefaultY + ServerManager.RandomNumber(-3, 3)); if (ServerManager.GetMapInstanceByMapId(respawnObj.DefaultMapId) is MapInstance GoToMap) { if (!GoToMap.Map.IsBlockedZone(mapCell.X, mapCell.Y)) { break; } } } ServerManager.Instance.ChangeMap(session.Character.CharacterId, respawnObj.DefaultMapId, mapCell.X, mapCell.Y); } session.Character.Inventory.RemoveItemFromInventory(inv.Id); break; } } break; } } break; // dyes or waxes case 10: case 11: if (!session.Character.IsVehicled) { if (Effect == 10) { if (EffectValue == 99) { byte nextValue = (byte)ServerManager.RandomNumber(0, 127); session.Character.HairColor = Enum.IsDefined(typeof(HairColorType), nextValue) ? (HairColorType)nextValue : 0; } else { session.Character.HairColor = Enum.IsDefined(typeof(HairColorType), (byte)EffectValue) ? (HairColorType)EffectValue : 0; } } else if (Effect == 11) { if (session.Character.Class == (byte)ClassType.Adventurer && EffectValue > 1) { session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("ADVENTURERS_CANT_USE"), 10)); return; } if (session.Character.Gender != (GenderType)Sex && (VNum < 2130 || VNum > 2162) && (VNum < 10025 || VNum > 10026)) { session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("CANNOT_USE"), 10)); return; } session.Character.HairStyle = Enum.IsDefined(typeof(HairStyleType), (byte)EffectValue) ? (HairStyleType)EffectValue : 0; } else { if (session.Character.Class == (byte)ClassType.Adventurer && EffectValue > 1) { session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("ADVENTURERS_CANT_USE"), 10)); return; } session.Character.HairStyle = Enum.IsDefined(typeof(HairStyleType), (byte)EffectValue) ? (HairStyleType)EffectValue : 0; } session.SendPacket(session.Character.GenerateEq()); session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateIn()); session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateGidx()); session.Character.Inventory.RemoveItemFromInventory(inv.Id); } break; // TS npcs health case 12: if (EffectValue > 0) { if (session.Character.Timespace != null) { session.Character.MapInstance.GetBattleEntitiesInRange(new MapCell { X = session.Character.PositionX, Y = session.Character.PositionY }, 6) .Where(s => (s.MapNpc != null || (s.Mate != null && s.Mate.IsTemporalMate)) && !session.Character.BattleEntity.CanAttackEntity(s)).ToList() .ForEach(s => { int health = EffectValue; if (s.Hp + EffectValue > s.HpMax) { health = s.HpMax - s.Hp; } s.Hp += health; session.Character.MapInstance.Broadcast(s.GenerateRc(health)); s.Mate?.Owner.Session.SendPacket(s.Mate.GenerateStatInfo()); }); session.Character.Inventory.RemoveItemFromInventory(inv.Id); session.SendPacket(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 48)); } } break; // dignity restoration case 14: if ((EffectValue == 100 || EffectValue == 200) && session.Character.Dignity < 100 && !session.Character.IsVehicled) { session.Character.Dignity += EffectValue; if (session.Character.Dignity > 100) { session.Character.Dignity = 100; } session.SendPacket(session.Character.GenerateFd()); session.SendPacket(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 49 - (byte)session.Character.Faction)); session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateIn(InEffect: 1), ReceiverType.AllExceptMe); session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateGidx(), ReceiverType.AllExceptMe); session.Character.Inventory.RemoveItemFromInventory(inv.Id); } else if (EffectValue == 2000 && session.Character.Dignity < 100 && !session.Character.IsVehicled) { session.Character.Dignity = 100; session.SendPacket(session.Character.GenerateFd()); session.SendPacket(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 49 - (byte)session.Character.Faction)); session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateIn(InEffect: 1), ReceiverType.AllExceptMe); session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateGidx(), ReceiverType.AllExceptMe); session.Character.Inventory.RemoveItemFromInventory(inv.Id); } break; // speakers case 15: if (!session.Character.IsVehicled && Option == 0) { session.SendPacket(UserInterfaceHelper.GenerateGuri(10, 3, session.Character.CharacterId, 1)); } break; // bubbles case 16: if (!session.Character.IsVehicled && Option == 0) { session.SendPacket(UserInterfaceHelper.GenerateGuri(10, 4, session.Character.CharacterId, 1)); } break; case 20: if (!session.Character.IsVehicled) { session.Character.AddBuff(new Buff(105, session.Character.Level), session.Character.BattleEntity); } break; // wigs case 30: if (!session.Character.IsVehicled) { ItemInstance wig = session.Character.Inventory.LoadBySlotAndType((byte)EquipmentType.Hat, InventoryType.Wear); if (wig != null) { wig.Design = (byte)ServerManager.RandomNumber(0, 15); session.SendPacket(session.Character.GenerateEq()); session.SendPacket(session.Character.GenerateEquipment()); session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateIn()); session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateGidx()); session.Character.Inventory.RemoveItemFromInventory(inv.Id); } else { session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("NO_WIG"), 0)); } } break; case 31: if (!session.Character.IsVehicled && session.Character.HairStyle == HairStyleType.Hair7) { session.Character.HairStyle = HairStyleType.Hair8; session.SendPacket(session.Character.GenerateEq()); session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateIn()); session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateGidx()); session.Character.Inventory.RemoveItemFromInventory(inv.Id); // idk how it works yet but seems like all characters with this hairstyle have DarkPurple hair //session.Character.HairColor = HairColorType.DarkPurple; } break; // Passive skills books case 99: if (session.Character.HeroLevel >= EffectValue) { if (session.Character.AddSkill((short)(Sex + 1))) { session.SendPacket(session.Character.GenerateSki()); session.Character.Inventory.RemoveItemFromInventory(inv.Id); } } else { session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("LOW_HERO_LVL"), 10)); } break; case 300: if (session.Character.Group != null && session.Character.Group.GroupType != GroupType.Group && session.Character.Group.IsLeader(session) && session.CurrentMapInstance.Portals.Any(s => s.Type == (short)PortalType.Raid)) { int delay = 0; foreach (ClientSession sess in session.Character.Group.Sessions.GetAllItems()) { Observable.Timer(TimeSpan.FromMilliseconds(delay)).Subscribe(o => { if (sess?.Character != null && session?.CurrentMapInstance != null && session?.Character != null && sess.Character != session.Character) { ServerManager.Instance.TeleportOnRandomPlaceInMap(sess, session.CurrentMapInstance.MapInstanceId); } }); delay += 100; } session.Character.Inventory.RemoveItemFromInventory(inv.Id); } break; case 301: if (session.Character.Channel.ChannelId == 51) { return; } if (session.Character.MapInstance.MapInstanceType != MapInstanceType.BaseMapInstance) { return; } if (session.Character.Family != null && session.HasCurrentMapInstance && session.HasSelectedCharacter && session.Character.FamilyCharacter.Authority == FamilyAuthority.Head) { ServerManager.Instance.Sessions.Where(s => s.Character != session.Character && s.Character?.MapInstance.MapInstanceType == MapInstanceType.BaseMapInstance && s.Character.Family?.FamilyId == session.Character.Family?.FamilyId).ToList().ForEach(s => s.SendPacket($"qnaml 3 #guri^301^{session.Character.CharacterId} {Language.Instance.GetMessageFromKey("FAMILYTELEPORT_QUESTION")}")); session.Character.Inventory.RemoveItemFromInventory(inv.Id); session.Character.LastCall = DateTime.Now; } break; default: Logger.Warn(string.Format(Language.Instance.GetMessageFromKey("NO_HANDLER_ITEM"), GetType(), VNum, Effect, EffectValue)); break; } }
public static int GetDistance(MapCell p, MapCell q) { return Math.Max(Math.Abs(p.X - q.X), Math.Abs(p.Y - q.Y)); }
public List <MapCell> AStar(MapCell cell1, MapCell cell2) { List <MapCell> SolutionPathList = new List <MapCell>(); SortedCostMapCellList OPEN = new SortedCostMapCellList(); SortedCostMapCellList CLOSED = new SortedCostMapCellList(); MapCellAStar cell_start = new MapCellAStar(null, null, cell1.X, cell1.Y, cell1.MapId); MapCellAStar cell_goal = new MapCellAStar(null, null, cell2.X, cell2.Y, cell2.MapId); OPEN.Push(cell_start); while (OPEN.Count > 0) { MapCellAStar cell_current = OPEN.Pop(); if (cell_current.IsMatch(cell_goal)) { cell_goal.parentcell = cell_current.parentcell; break; } List <MapCellAStar> successors = cell_current.GetSuccessors(); foreach (MapCellAStar cell_successor in successors) { int oFound = OPEN.IndexOf(cell_successor); if (oFound > 0) { MapCellAStar existing_cell = OPEN.CellAt(oFound); if (existing_cell.CompareTo(cell_current) <= 0) { continue; } } int cFound = CLOSED.IndexOf(cell_successor); if (cFound > 0) { MapCellAStar existing_cell = CLOSED.CellAt(cFound); if (existing_cell.CompareTo(cell_current) <= 0) { continue; } } if (oFound != -1) { OPEN.RemoveAt(oFound); } if (cFound != -1) { CLOSED.RemoveAt(cFound); } OPEN.Push(cell_successor); } CLOSED.Push(cell_current); } MapCellAStar p = cell_goal; while (p != null) { SolutionPathList.Insert(0, p); p = p.parentcell; } return(SolutionPathList); }
public static int GetDistance(MapCell p, MapCell q) { return(Math.Max(Math.Abs(p.X - q.X), Math.Abs(p.Y - q.Y))); }
public static int GetDistance(MapCell p, MapCell q) => (int)Heuristic.Octile(Math.Abs(p.X - q.X), Math.Abs(p.Y - q.Y));
public static void NRun(ClientSession Session, NRunPacket packet) { if (!Session.HasCurrentMapInstance) { return; } MapNpc npc = Session.CurrentMapInstance.Npcs.FirstOrDefault(s => s.MapNpcId == packet.NpcId); TeleporterDTO tp; Random rand = new Random(); switch (packet.Runner) { case 1: if (Session.Character.Class != (byte)ClassType.Adventurer) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("NOT_ADVENTURER"), 0)); return; } if (Session.Character.Level < 15 || Session.Character.JobLevel < 20) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("LOW_LVL"), 0)); return; } if (packet.Type == (byte)Session.Character.Class) { return; } if (Session.Character.Inventory.All(i => i.Value.Type != InventoryType.Wear)) { Session.Character.Inventory.AddNewToInventory((short)(4 + packet.Type * 14), type: InventoryType.Wear); Session.Character.Inventory.AddNewToInventory((short)(81 + packet.Type * 13), type: InventoryType.Wear); switch (packet.Type) { case 1: Session.Character.Inventory.AddNewToInventory(68, type: InventoryType.Wear); Session.Character.Inventory.AddNewToInventory(2082, 10); break; case 2: Session.Character.Inventory.AddNewToInventory(78, type: InventoryType.Wear); Session.Character.Inventory.AddNewToInventory(2083, 10); break; case 3: Session.Character.Inventory.AddNewToInventory(86, type: InventoryType.Wear); break; } Session.CurrentMapInstance?.Broadcast(Session.Character.GenerateEq()); Session.SendPacket(Session.Character.GenerateEquipment()); Session.Character.ChangeClass((ClassType)packet.Type); } else { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("EQ_NOT_EMPTY"), 0)); } break; case 2: Session.SendPacket("wopen 1 0"); break; case 4: Mate mate = Session.Character.Mates.FirstOrDefault(s => s.MateTransportId == packet.NpcId); switch (packet.Type) { case 2: if (mate != null) { if (Session.Character.Level >= mate.Level) { Mate teammate = Session.Character.Mates.Where(s => s.IsTeamMember).FirstOrDefault(s => s.MateType == mate.MateType); if (teammate != null) { teammate.IsTeamMember = false; teammate.MapX = teammate.PositionX; teammate.MapY = teammate.PositionY; } mate.IsTeamMember = true; } else { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("PET_HIGHER_LEVEL"), 0)); } } break; case 3: if (mate != null && Session.Character.Miniland == Session.Character.MapInstance) { mate.IsTeamMember = false; mate.MapX = mate.PositionX; mate.MapY = mate.PositionY; } break; case 4: if (mate != null) { if (Session.Character.Miniland == Session.Character.MapInstance) { mate.IsTeamMember = false; mate.MapX = mate.PositionX; mate.MapY = mate.PositionY; } else { Session.SendPacket($"qna #n_run^4^5^3^{mate.MateTransportId} {Language.Instance.GetMessageFromKey("ASK_KICK_PET")}"); } break; } break; case 5: if (mate != null) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateDelay(3000, 10, $"#n_run^4^6^3^{mate.MateTransportId}")); } break; case 6: if (mate != null) { if (Session.Character.Miniland != Session.Character.MapInstance) { mate.IsTeamMember = false; Session.CurrentMapInstance.Broadcast(mate.GenerateOut()); Session.SendPacket(Session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("PET_KICKED"), mate.Name), 11)); Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("PET_KICKED"), mate.Name), 0)); } } break; case 7: if (mate != null) { if (Session.Character.Mates.Any(s => s.MateType == mate.MateType && s.IsTeamMember)) { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ALREADY_PET_IN_TEAM"), 11)); Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("ALREADY_PET_IN_TEAM"), 0)); } else { Session.SendPacket(UserInterfaceHelper.Instance.GenerateDelay(3000, 10, $"#n_run^4^9^3^{mate.MateTransportId}")); } } break; case 9: if (mate != null) { if (Session.Character.Level >= mate.Level) { mate.PositionX = (short)(Session.Character.PositionX + 1); } mate.PositionY = (short)(Session.Character.PositionY + 1); mate.IsTeamMember = true; Session.CurrentMapInstance.Broadcast(mate.GenerateIn()); } else { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("PET_HIGHER_LEVEL"), 0)); } break; } Session.SendPacket(Session.Character.GeneratePinit()); Session.SendPackets(Session.Character.GeneratePst()); break; case 10: Session.SendPacket("wopen 3 0"); break; case 12: Session.SendPacket($"wopen {packet.Type} 0"); break; case 14: Session.SendPacket("wopen 27 0"); string recipelist = "m_list 2"; if (npc != null) { List<Recipe> tps = npc.Recipes; recipelist = tps.Where(s => s.Amount > 0).Aggregate(recipelist, (current, s) => current + $" {s.ItemVNum}"); recipelist += " -100"; Session.SendPacket(recipelist); } break; case 15: if (npc != null) { if (packet.Value == 2) { Session.SendPacket($"qna #n_run^15^1^1^{npc.MapNpcId} {Language.Instance.GetMessageFromKey("ASK_CHANGE_SPAWNLOCATION")}"); } else { switch (npc.MapId) { case 1: Session.Character.SetRespawnPoint(1, 79, 116); break; case 20: Session.Character.SetRespawnPoint(20, 9, 92); break; case 145: Session.Character.SetRespawnPoint(145, 13, 110); break; } Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("RESPAWNLOCATION_CHANGED"), 0)); } } break; case 16: tp = npc?.Teleporters?.FirstOrDefault(s => s.Index == packet.Type); if (tp != null) { if (Session.Character.Gold >= 1000 * packet.Type) { Session.Character.Gold -= 1000 * packet.Type; Session.SendPacket(Session.Character.GenerateGold()); ServerManager.Instance.ChangeMap(Session.Character.CharacterId, tp.MapId, tp.MapX, tp.MapY); } else { Session.SendPacket( Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10)); } } break; case 17: double currentRunningSeconds = (DateTime.Now - Process.GetCurrentProcess().StartTime.AddSeconds(-50)).TotalSeconds; double timeSpanSinceLastPortal = currentRunningSeconds - Session.Character.LastPortal; if (!(timeSpanSinceLastPortal >= 4) || !Session.HasCurrentMapInstance || Session.CurrentMapInstance.MapInstanceType == MapInstanceType.Act4Instance) { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("CANT_MOVE"), 10)); return; } if (Session.Character.Gold >= 500 * (1 + packet.Type)) { Session.Character.LastPortal = currentRunningSeconds; Session.Character.Gold -= 500 * (1 + packet.Type); Session.SendPacket(Session.Character.GenerateGold()); ServerManager.Instance.TeleportOnRandomPlaceInMap(Session, packet.Type == 0 ? ServerManager.Instance.ArenaInstance.MapInstanceId : ServerManager.Instance.FamilyArenaInstance.MapInstanceId); } else { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10)); } break; case 18: Session.SendPacket(Session.Character.GenerateNpcDialog(17)); break; case 26: tp = npc?.Teleporters?.FirstOrDefault(s => s.Index == packet.Type); if (tp != null) { if (Session.Character.Gold >= 5000 * packet.Type) { Session.Character.Gold -= 5000 * packet.Type; ServerManager.Instance.ChangeMap(Session.Character.CharacterId, tp.MapId, tp.MapX, tp.MapY); } else { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10)); } } break; case 45: tp = npc?.Teleporters?.FirstOrDefault(s => s.Index == packet.Type); if (tp != null) { if (Session.Character.Gold >= 500) { Session.Character.Gold -= 500; Session.SendPacket(Session.Character.GenerateGold()); ServerManager.Instance.ChangeMap(Session.Character.CharacterId, tp.MapId, tp.MapX, tp.MapY); } else { Session.SendPacket( Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10)); } } break; case 132: tp = npc?.Teleporters?.FirstOrDefault(s => s.Index == packet.Type); if (tp != null) { ServerManager.Instance.ChangeMap(Session.Character.CharacterId, tp.MapId, tp.MapX, tp.MapY); } break; case 137: Session.SendPacket("taw_open"); break; case 138: ConcurrentBag<ArenaTeamMember> at = ServerManager.Instance.ArenaTeams.OrderBy(s => rand.Next()).FirstOrDefault(); if (at != null) { ServerManager.Instance.ChangeMapInstance(Session.Character.CharacterId, at.FirstOrDefault(s => s.Session != null).Session.CurrentMapInstance.MapInstanceId, 69, 100); ArenaTeamMember zenas = at.OrderBy(s => s.Order).FirstOrDefault(s => s.Session != null && !s.Dead && s.ArenaTeamType == ArenaTeamType.ZENAS); ArenaTeamMember erenia = at.OrderBy(s => s.Order).FirstOrDefault(s => s.Session != null && !s.Dead && s.ArenaTeamType == ArenaTeamType.ERENIA); Session.SendPacket(erenia.Session.Character.GenerateTaM(0)); Session.SendPacket(erenia.Session.Character.GenerateTaM(3)); Session.SendPacket("taw_sv 0"); Session.SendPacket(zenas.Session.Character.GenerateTaP(0, true)); Session.SendPacket(erenia.Session.Character.GenerateTaP(2, true)); Session.SendPacket(zenas.Session.Character.GenerateTaFc(0)); Session.SendPacket(erenia.Session.Character.GenerateTaFc(1)); } else { Session.SendPacket(UserInterfaceHelper.Instance.GenerateInfo(Language.Instance.GetMessageFromKey("NO_TALENT_ARENA"))); } break; case 135: if (!ServerManager.Instance.StartedEvents.Contains(EventType.TALENTARENA)) { Session.SendPacket(npc?.GenerateSay(Language.Instance.GetMessageFromKey("ARENA_NOT_OPEN"), 10)); } else { int tickets = 5 - Session.Character.GeneralLogs.Count(s => s.LogType == "TalentArena" && s.Timestamp.Date == DateTime.Today); if (ServerManager.Instance.ArenaMembers.All(s => s.Session != Session) && tickets > 0) { if (ServerManager.Instance.IsCharacterMemberOfGroup(Session.Character.CharacterId)) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("TALENT_ARENA_GROUP"), 0)); Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("TALENT_ARENA_GROUP"), 10)); } else { Session.SendPacket(Session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("ARENA_TICKET_LEFT"), tickets), 10)); ServerManager.Instance.ArenaMembers.Add(new ArenaMember { ArenaType = EventType.TALENTARENA, Session = Session, GroupId = null, Time = 0 }); } } else { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("TALENT_ARENA_NO_MORE_TICKET"), 0)); Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("TALENT_ARENA_NO_MORE_TICKET"), 10)); } } break; case 150: if (npc != null) { if (Session.Character.Family != null) { if (Session.Character.Family.LandOfDeath != null && npc.EffectActivated) { if (Session.Character.Level >= 55) { ServerManager.Instance.ChangeMapInstance(Session.Character.CharacterId, Session.Character.Family.LandOfDeath.MapInstanceId, 153, 145); } else { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("LOD_REQUIERE_LVL"), 0)); } } else { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("LOD_CLOSED"), 0)); } } else { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("NEED_FAMILY"), 0)); } } break; case 301: tp = npc?.Teleporters?.FirstOrDefault(s => s.Index == packet.Type); if (tp != null) { ServerManager.Instance.ChangeMap(Session.Character.CharacterId, tp.MapId, tp.MapX, tp.MapY); } break; case 1600: Session.SendPacket(Session.Character.OpenFamilyWarehouse()); break; case 1601: Session.SendPackets(Session.Character.OpenFamilyWarehouseHist()); break; case 1602: if (Session.Character.Family != null && Session.Character.Family.FamilyLevel >= 3 && Session.Character.Family.WarehouseSize < 21) { if (Session.Character.FamilyCharacter.Authority == FamilyAuthority.Head) { if (500000 >= Session.Character.Gold) { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10)); return; } Session.Character.Family.WarehouseSize = 21; Session.Character.Gold -= 500000; Session.SendPacket(Session.Character.GenerateGold()); FamilyDTO fam = Session.Character.Family; DAOFactory.FamilyDAO.InsertOrUpdate(ref fam); ServerManager.Instance.FamilyRefresh(Session.Character.Family.FamilyId); } else { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 10)); Session.SendPacket(UserInterfaceHelper.Instance.GenerateModal(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 1)); } } break; case 1603: if (Session.Character.Family != null && Session.Character.Family.FamilyLevel >= 7 && Session.Character.Family.WarehouseSize < 49) { if (Session.Character.FamilyCharacter.Authority == FamilyAuthority.Head) { if (2000000 >= Session.Character.Gold) { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10)); return; } Session.Character.Family.WarehouseSize = 49; Session.Character.Gold -= 2000000; Session.SendPacket(Session.Character.GenerateGold()); FamilyDTO fam = Session.Character.Family; DAOFactory.FamilyDAO.InsertOrUpdate(ref fam); ServerManager.Instance.FamilyRefresh(Session.Character.Family.FamilyId); } else { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 10)); Session.SendPacket(UserInterfaceHelper.Instance.GenerateModal(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 1)); } } break; case 1604: if (Session.Character.Family != null && Session.Character.Family.FamilyLevel >= 5 && Session.Character.Family.MaxSize < 70) { if (Session.Character.FamilyCharacter.Authority == FamilyAuthority.Head) { if (5000000 >= Session.Character.Gold) { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10)); return; } Session.Character.Family.MaxSize = 70; Session.Character.Gold -= 5000000; Session.SendPacket(Session.Character.GenerateGold()); FamilyDTO fam = Session.Character.Family; DAOFactory.FamilyDAO.InsertOrUpdate(ref fam); ServerManager.Instance.FamilyRefresh(Session.Character.Family.FamilyId); } else { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 10)); Session.SendPacket(UserInterfaceHelper.Instance.GenerateModal(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 1)); } } break; case 1605: if (Session.Character.Family != null && Session.Character.Family.FamilyLevel >= 9 && Session.Character.Family.MaxSize < 100) { if (Session.Character.FamilyCharacter.Authority == FamilyAuthority.Head) { if (10000000 >= Session.Character.Gold) { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10)); return; } Session.Character.Family.MaxSize = 100; Session.Character.Gold -= 10000000; Session.SendPacket(Session.Character.GenerateGold()); FamilyDTO fam = Session.Character.Family; DAOFactory.FamilyDAO.InsertOrUpdate(ref fam); ServerManager.Instance.FamilyRefresh(Session.Character.Family.FamilyId); } else { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 10)); Session.SendPacket(UserInterfaceHelper.Instance.GenerateModal(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 1)); } } break; case 23: if (packet.Type == 0) { if (Session.Character.Group != null && Session.Character.Group.CharacterCount == 3) { if (Session.Character.Group.Characters.Any(s => s.Character.Family != null)) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateInfo(Language.Instance.GetMessageFromKey("GROUP_MEMBER_ALREADY_IN_FAMILY"))); return; } } if (Session.Character.Group == null || Session.Character.Group.CharacterCount != 3) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateInfo(Language.Instance.GetMessageFromKey("FAMILY_GROUP_NOT_FULL"))); return; } Session.SendPacket(UserInterfaceHelper.Instance.GenerateInbox($"#glmk^ {14} 1 {Language.Instance.GetMessageFromKey("CREATE_FAMILY").Replace(' ', '^')}")); } else { if (Session.Character.Family == null) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateInfo(Language.Instance.GetMessageFromKey("NOT_IN_FAMILY"))); return; } if (Session.Character.Family != null && Session.Character.FamilyCharacter != null && Session.Character.FamilyCharacter.Authority != FamilyAuthority.Head) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateInfo(Language.Instance.GetMessageFromKey("NOT_FAMILY_HEAD"))); return; } Session.SendPacket($"qna #glrm^1 {Language.Instance.GetMessageFromKey("DISMISS_FAMILY")}"); } break; case 60: StaticBonusDTO medal = Session.Character.StaticBonusList.FirstOrDefault(s => s.StaticBonusType == StaticBonusType.BazaarMedalGold || s.StaticBonusType == StaticBonusType.BazaarMedalSilver); byte Medal = 0; int Time = 0; if (medal != null) { Medal = medal.StaticBonusType == StaticBonusType.BazaarMedalGold ? (byte)MedalType.Gold : (byte)MedalType.Silver; Time = (int)(medal.DateEnd - DateTime.Now).TotalHours; } Session.SendPacket($"wopen 32 {Medal} {Time}"); break; case 5001: if (npc != null) { MapInstance map = null; switch (Session.Character.Faction) { case FactionType.Neutral: Session.SendPacket(UserInterfaceHelper.Instance.GenerateInfo("NEED_FACTION_ACT4")); return; case FactionType.Angel: map = ServerManager.Instance.Act4ShipAngel; break; case FactionType.Demon: map = ServerManager.Instance.Act4ShipDemon; break; } if (map == null || !npc.EffectActivated) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("SHIP_NOTARRIVED"), 0)); return; } if (3000 > Session.Character.Gold) { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10)); return; } Session.Character.Gold -= 3000; MapCell pos = map.Map.GetRandomPosition(); ServerManager.Instance.ChangeMapInstance(Session.Character.CharacterId, map.MapInstanceId, pos.X, pos.Y); } break; case 5002: if (npc != null) { tp = npc.Teleporters?.FirstOrDefault(s => s.Index == packet.Type); if (tp != null) { Session.SendPacket("it 3"); SerializableWorldServer connection = CommunicationServiceClient.Instance.GetPreviousChannelByAccountId(Session.Account.AccountId); Session.Character.MapId = tp.MapId; Session.Character.MapX = tp.MapX; Session.Character.MapY = tp.MapY; Session.Character.ChangeChannel(connection.EndPointIp, connection.EndPointPort, 3); } } break; case 5011: if (npc != null) { ServerManager.Instance.ChangeMap(Session.Character.CharacterId, 170, 127, 46); } break; case 5012: tp = npc?.Teleporters?.FirstOrDefault(s => s.Index == packet.Type); if (tp != null) { ServerManager.Instance.ChangeMap(Session.Character.CharacterId, tp.MapId, tp.MapX, tp.MapY); } break; default: Logger.Log.Warn(string.Format(Language.Instance.GetMessageFromKey("NO_NRUN_HANDLER"), packet.Runner)); break; } }
public void ApplyBCards(object session, object sender = null) { //Console.WriteLine($"BCardId: {BCardId} Type: {(BCardType.CardType)Type} SubType: {SubType} CardId: {CardId?.ToString() ?? "null"} ItemVNum: {ItemVNum?.ToString() ?? "null"} SkillVNum: {SkillVNum?.ToString() ?? "null"} SessionType: {session?.GetType().ToString() ?? "null"} SenderType: {sender?.GetType().ToString() ?? "null"}"); switch ((BCardType.CardType)Type) { case BCardType.CardType.Buff: { if (ServerManager.RandomNumber() < FirstData) { Character senderCharacter = sender is ClientSession senderSession ? senderSession.Character : sender as Character; if (session is Character character) { short cardId = (short)SecondData; // If either Berserk Spirit or Strong Berserk Spirit is active // then don't add Weak Berserk Spirit if (cardId == 601 && character.Buff?.Any(s => s?.Card?.CardId == 602 || s?.Card?.CardId == 603) == true) { break; } if (senderCharacter != null) { // TODO: Get anti stats from BCard character.AddBuff(new Buff((short)SecondData, senderCharacter.Level, senderCharacter)); } else { character.AddBuff(new Buff((short)SecondData, character.Level)); } } else if (session is MapMonster mapMonster) { if (senderCharacter != null) { mapMonster.AddBuff(new Buff((short)SecondData, senderCharacter.Level, senderCharacter)); } else { mapMonster.AddBuff(new Buff((short)SecondData, mapMonster.Monster.Level)); } } } } break; case BCardType.CardType.Move: { if (session is Character character) { character.LastSpeedChange = DateTime.Now; character.Session.SendPacket(character.GenerateCond()); } } break; case BCardType.CardType.Summons: { if (session is Character character) { if (character.MapInstance != null) { List <MonsterToSummon> monsterList = new List <MonsterToSummon>(); if (SubType == (byte)AdditionalTypes.Summons.Summons / 10) { int aliveTime = ServerManager.GetNpc((short)SecondData).RespawnTime; for (int i = 0; i < FirstData; i++) { MapCell mapCell = new MapCell { X = (short)(ServerManager.RandomNumber(-1, 2) + character.PositionX), Y = (short)(ServerManager.RandomNumber(-1, 2) + character.PositionY), }; monsterList.Add(new MonsterToSummon((short)SecondData, mapCell, -1, true, false, false, true, false, -1, character, aliveTime, false)); } } if (monsterList.Any()) { EventHelper.Instance.RunEvent(new EventContainer(character.MapInstance, EventActionType.SPAWNMONSTERS, monsterList)); } } } } break; case BCardType.CardType.SpecialAttack: break; case BCardType.CardType.SpecialDefence: break; case BCardType.CardType.AttackPower: break; case BCardType.CardType.Target: break; case BCardType.CardType.Critical: break; case BCardType.CardType.SpecialCritical: break; case BCardType.CardType.Element: break; case BCardType.CardType.IncreaseDamage: break; case BCardType.CardType.Defence: break; case BCardType.CardType.DodgeAndDefencePercent: break; case BCardType.CardType.Block: break; case BCardType.CardType.Absorption: break; case BCardType.CardType.ElementResistance: break; case BCardType.CardType.EnemyElementResistance: break; case BCardType.CardType.Damage: break; case BCardType.CardType.GuarantedDodgeRangedAttack: break; case BCardType.CardType.Morale: break; case BCardType.CardType.Casting: break; case BCardType.CardType.Reflection: break; case BCardType.CardType.DrainAndSteal: break; case BCardType.CardType.HealingBurningAndCasting: { Character senderCharacter = sender is ClientSession senderSession ? senderSession.Character : sender as Character; if (senderCharacter != null) { #region Character if (session is Character character) { void HealingBurningAndCastingAction() { if (!character.IsAlive || character.MapInstance == null || character.Session == null) { return; } int amount = 0; if (SubType == (byte)AdditionalTypes.HealingBurningAndCasting.RestoreHP / 10 || SubType == (byte)AdditionalTypes.HealingBurningAndCasting.DecreaseHP / 10) { if (FirstData > 0) { if (IsLevelScaled) { amount = senderCharacter.Level * FirstData; } else { amount = FirstData; } if (character.Hp + amount > character.HPMax) { amount = character.HPMax - character.Hp; } character.Hp += amount; character.MapInstance.Broadcast(character.GenerateRc(amount)); } else { if (IsLevelScaled) { amount = senderCharacter.Level * (FirstData - 1); } else { amount = FirstData; } amount *= -1; if (character.Hp - amount < 1) { amount = character.Hp - 1; } character.GetDamage(amount); character.MapInstance.Broadcast(character.GenerateDm(amount)); } character.Session.SendPacket(character.GenerateStat()); } else if (SubType == (byte)AdditionalTypes.HealingBurningAndCasting.RestoreMP / 10 || SubType == (byte)AdditionalTypes.HealingBurningAndCasting.DecreaseMP / 10) { if (FirstData > 0) { if (IsLevelScaled) { amount = senderCharacter.Level * FirstData; } else { amount = FirstData; } if (character.Mp + amount > character.MPMax) { amount = character.MPMax - character.Mp; } character.Mp += amount; } else { if (IsLevelScaled) { amount = senderCharacter.Level * (FirstData - 1); } else { amount = FirstData; } amount *= -1; if (character.Mp - amount < 1) { amount = character.Mp - 1; } character.DecreaseMp(amount); } character.Session.SendPacket(character.GenerateStat()); } } HealingBurningAndCastingAction(); if (ThirdData > 0 && CardId != null) { IDisposable disposable = Observable.Interval(TimeSpan.FromSeconds(ThirdData * 2)) .Subscribe(s => HealingBurningAndCastingAction()); character.DisposeBCard(BCardId); character.BCardDisposables[BCardId] = disposable; } } #endregion #region MapMonster else if (session is MapMonster mapMonster) { void HealingBurningAndCastingAction() { if (!mapMonster.IsAlive || mapMonster.MapInstance == null) { return; } int amount = 0; if (SubType == (byte)AdditionalTypes.HealingBurningAndCasting.RestoreHP / 10 || SubType == (byte)AdditionalTypes.HealingBurningAndCasting.DecreaseHP / 10) { if (FirstData > 0) { if (IsLevelScaled) { amount = senderCharacter.Level * FirstData; } else { amount = FirstData; } if (mapMonster.CurrentHp + amount > mapMonster.MaxHp) { amount = mapMonster.MaxHp - mapMonster.CurrentHp; } mapMonster.CurrentHp += amount; mapMonster.MapInstance.Broadcast(mapMonster.GenerateRc(amount)); } else { if (IsLevelScaled) { amount = senderCharacter.Level * (FirstData - 1); } else { amount = FirstData; } amount *= -1; if (mapMonster.CurrentHp - amount < 1) { amount = mapMonster.CurrentHp - 1; } mapMonster.CurrentHp -= amount; mapMonster.MapInstance.Broadcast(mapMonster.GenerateDm(amount)); } } if (SubType == (byte)AdditionalTypes.HealingBurningAndCasting.RestoreMP / 10 || SubType == (byte)AdditionalTypes.HealingBurningAndCasting.DecreaseMP / 10) { if (FirstData > 0) { if (IsLevelScaled) { amount = senderCharacter.Level * FirstData; } else { amount = FirstData; } if (mapMonster.CurrentMp + amount > mapMonster.MaxMp) { amount = mapMonster.MaxMp - mapMonster.CurrentMp; } mapMonster.CurrentMp += amount; } else { if (IsLevelScaled) { amount = senderCharacter.Level * (FirstData - 1); } else { amount = FirstData; } amount *= -1; if (mapMonster.CurrentMp - amount < 1) { amount = mapMonster.CurrentMp - 1; } mapMonster.CurrentMp -= amount; } } } HealingBurningAndCastingAction(); if (ThirdData > 0 && CardId != null) { IDisposable disposable = Observable.Interval(TimeSpan.FromSeconds(ThirdData * 2)) .Subscribe(s => HealingBurningAndCastingAction()); mapMonster.DisposeBCard(BCardId); mapMonster.BCardDisposables[BCardId] = disposable; } } #endregion } } break; case BCardType.CardType.HPMP: { if (SubType == (byte)AdditionalTypes.HPMP.DecreaseRemainingMP / 10) { if (FirstData < 0) { double multiplier = (FirstData * -1) / 100D; if (session is Character character) { character.DecreaseMp((int)(character.Mp * multiplier)); character.Session?.SendPacket(character.GenerateStat()); } else if (session is MapMonster mapMonster) { mapMonster.DecreaseMp((int)(mapMonster.CurrentMp * multiplier)); } } } } break; case BCardType.CardType.SpecializationBuffResistance: { if (SubType == (byte)AdditionalTypes.SpecializationBuffResistance.RemoveGoodEffects / 10) { if (session is Character character) { if (FirstData < 0) { if (ServerManager.RandomNumber() < (FirstData * -1)) { character.Buff?.GetAllItems()?.Where(s => s?.Card?.BuffType == BuffType.Bad && s.Card.Level < SecondData)? .ToList()?.ForEach(s => character.RemoveBuff(s.Card.CardId)); } } else { if (ServerManager.RandomNumber() < FirstData) { character.Buff?.GetAllItems()?.Where(s => s?.Card?.BuffType == BuffType.Good && s.Card.Level < SecondData)? .ToList()?.ForEach(s => character.RemoveBuff(s.Card.CardId)); } } } } } break; case BCardType.CardType.SpecialEffects: { if (SubType == (byte)AdditionalTypes.SpecialEffects.ShadowAppears / 10) { if (session is Character character) { character.NumberOfShadows = FirstData; character.ShadowsDistance = SecondData; character.MapInstance?.Broadcast(character.GenerateSpeed()); } } } break; case BCardType.CardType.Capture: { if (session is MapMonster mapMonster && sender is ClientSession senderSession) { NpcMonster mateNpc = ServerManager.GetNpc(mapMonster.MonsterVNum); if (mateNpc != null) { if (mapMonster.Monster.Catch) { if (mapMonster.IsAlive && mapMonster.CurrentHp <= (int)((double)mapMonster.MaxHp / 2)) { if (mapMonster.Monster.Level < senderSession.Character.Level) { // TODO: Find a new algorithm int[] chance = { 100, 80, 60, 40, 20, 0 }; if (ServerManager.RandomNumber() < chance[ServerManager.RandomNumber(0, 5)]) { Mate mate = new Mate(senderSession.Character, mateNpc, (byte)(mapMonster.Monster.Level - 15 > 0 ? mapMonster.Monster.Level - 15 : 1), MateType.Pet); if (senderSession.Character.CanAddMate(mate)) { senderSession.Character.AddPetWithSkill(mate); senderSession.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("CATCH_SUCCESS"), 0)); senderSession.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, senderSession.Character.CharacterId, 197)); senderSession.CurrentMapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Player, senderSession.Character.CharacterId, 3, mapMonster.MapMonsterId, -1, 0, 15, -1, -1, -1, true, (int)((float)mapMonster.CurrentHp / (float)mapMonster.MaxHp * 100), 0, -1, 0)); mapMonster.SetDeathStatement(); senderSession.CurrentMapInstance?.Broadcast(StaticPacketHelper.Out(UserType.Monster, mapMonster.MapMonsterId)); } else { senderSession.SendPacket(senderSession.Character.GenerateSay(Language.Instance.GetMessageFromKey("PET_SLOT_FULL"), 10)); senderSession.SendPacket(StaticPacketHelper.Cancel(2, mapMonster.MapMonsterId)); } } else { senderSession.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("CATCH_FAIL"), 0)); senderSession.CurrentMapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Player, senderSession.Character.CharacterId, 3, mapMonster.MapMonsterId, -1, 0, 15, -1, -1, -1, true, (int)((float)mapMonster.CurrentHp / (float)mapMonster.MaxHp * 100), 0, -1, 0)); } } else { senderSession.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("LEVEL_LOWER_THAN_MONSTER"), 0)); senderSession.SendPacket(StaticPacketHelper.Cancel(2, mapMonster.MapMonsterId)); } } else { senderSession.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("CURRENT_HP_TOO_HIGH"), 0)); senderSession.SendPacket(StaticPacketHelper.Cancel(2, mapMonster.MapMonsterId)); } } else { senderSession.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("MONSTER_CANT_BE_CAPTURED"), 0)); senderSession.SendPacket(StaticPacketHelper.Cancel(2, mapMonster.MapMonsterId)); } } } } break; case BCardType.CardType.SpecialDamageAndExplosions: break; case BCardType.CardType.SpecialEffects2: { if (SubType == (byte)AdditionalTypes.SpecialEffects2.TeleportInRadius / 10) { if (session is Character character) { character.Teleport((short)FirstData); } } } break; case BCardType.CardType.CalculatingLevel: break; case BCardType.CardType.Recovery: break; case BCardType.CardType.MaxHPMP: { if (session is Character character) { if (SubType == (byte)AdditionalTypes.MaxHPMP.IncreasesMaximumHP / 10) { character.HPLoad(); character.Session?.SendPacket(character.GenerateStat()); } else if (SubType == (byte)AdditionalTypes.MaxHPMP.IncreasesMaximumMP / 10) { character.MPLoad(); character.Session?.SendPacket(character.GenerateStat()); } } } break; case BCardType.CardType.MultAttack: break; case BCardType.CardType.MultDefence: break; case BCardType.CardType.TimeCircleSkills: break; case BCardType.CardType.RecoveryAndDamagePercent: break; case BCardType.CardType.Count: break; case BCardType.CardType.NoDefeatAndNoDamage: break; case BCardType.CardType.SpecialActions: { Character senderCharacter = sender is ClientSession senderSession ? senderSession.Character : sender as Character; if (SubType == (byte)AdditionalTypes.SpecialActions.PushBack / 10) { if (senderCharacter != null) { if (session is Character character) { if (character.ResistForcedMovementChance <= 0 || ServerManager.RandomNumber() < character.ResistForcedMovementChance) { character.PushBack((short)FirstData, senderCharacter); } } else if (session is MapMonster mapMonster) { mapMonster.PushBack((short)FirstData, senderCharacter); } } } else if (SubType == (byte)AdditionalTypes.SpecialActions.FocusEnemies / 10) { if (senderCharacter != null) { if (session is Character character) { if (character.ResistForcedMovementChance <= 0 || ServerManager.RandomNumber() < character.ResistForcedMovementChance) { character.Focus((short)FirstData, senderCharacter); } } else if (session is MapMonster mapMonster) { mapMonster.Focus((short)FirstData, senderCharacter); } } } else if (SubType == (byte)AdditionalTypes.SpecialActions.Hide / 10) { if (session is Character character) { character.SetInvisible(true); } } } break; case BCardType.CardType.Transform: break; case BCardType.CardType.Mode: break; case BCardType.CardType.NoCharacteristicValue: break; case BCardType.CardType.LightAndShadow: { if (SubType == (byte)AdditionalTypes.LightAndShadow.RemoveBadEffects / 10) { if (session is Character character) { character.Buff?.GetAllItems()?.Where(s => s?.Card?.BuffType == BuffType.Bad && s.Card.Level < FirstData)? .ToList()?.ForEach(s => character.RemoveBuff(s.Card.CardId)); } } } break; case BCardType.CardType.Item: break; case BCardType.CardType.DebuffResistance: break; case BCardType.CardType.SpecialBehaviour: break; case BCardType.CardType.Quest: break; case BCardType.CardType.SecondSPCard: { if (session is Character character) { if (character.MapInstance != null) { List <MonsterToSummon> monsterList = new List <MonsterToSummon>(); if (SubType == (byte)AdditionalTypes.SecondSPCard.PlantBomb / 10) { MapMonster bomb = character.MapInstance.Monsters.FirstOrDefault(m => m?.Owner?.CharacterId == character.CharacterId && m.MonsterVNum == (short)SecondData); if (bomb == null) { for (int i = 0; i < FirstData; i++) { monsterList.Add(new MonsterToSummon((short)SecondData, new MapCell { X = character.PositionX, Y = character.PositionY }, -1, false, false, false, false, false, -1, character, 0, false)); } } else { bomb.Explode(); break; } } else if (SubType == (byte)AdditionalTypes.SecondSPCard.PlantSelfDestructionBomb / 10) { int aliveTime = ServerManager.GetNpc((short)SecondData).RespawnTime; for (int i = 0; i < FirstData; i++) { MapCell mapCell = new MapCell { X = (short)(ServerManager.RandomNumber(-1, 2) + character.PositionX), Y = (short)(ServerManager.RandomNumber(-1, 2) + character.PositionY), }; monsterList.Add(new MonsterToSummon((short)SecondData, mapCell, -1, true, false, false, true, false, -1, character, aliveTime, true)); } } if (monsterList.Any()) { EventHelper.Instance.RunEvent(new EventContainer(character.MapInstance, EventActionType.SPAWNMONSTERS, monsterList)); } } } } break; case BCardType.CardType.SPCardUpgrade: break; case BCardType.CardType.HugeSnowman: break; case BCardType.CardType.Drain: break; case BCardType.CardType.BossMonstersSkill: break; case BCardType.CardType.LordHatus: break; case BCardType.CardType.LordCalvinas: break; case BCardType.CardType.SESpecialist: { if (SubType == (byte)AdditionalTypes.SESpecialist.LowerHPStrongerEffect / 10) { Character senderCharacter = sender is ClientSession senderSession ? senderSession.Character : sender as Character; if (senderCharacter != null) { if (session is Character character) { double percentage = (character.Hp * 100) / character.HPMax; if (percentage < 35) { character.AddBuff(new Buff(274, senderCharacter.Level, senderCharacter)); } else if (percentage < 67) { character.AddBuff(new Buff(273, senderCharacter.Level, senderCharacter)); } else { character.AddBuff(new Buff(272, senderCharacter.Level, senderCharacter)); } } } } } break; case BCardType.CardType.FourthGlacernonFamilyRaid: break; case BCardType.CardType.SummonedMonsterAttack: break; case BCardType.CardType.BearSpirit: { if (session is Character character) { if (SubType == (byte)AdditionalTypes.BearSpirit.IncreaseMaximumHP / 10) { character.HPLoad(); character.Session?.SendPacket(character.GenerateStat()); } else if (SubType == (byte)AdditionalTypes.BearSpirit.IncreaseMaximumMP / 10) { character.MPLoad(); character.Session?.SendPacket(character.GenerateStat()); } } } break; case BCardType.CardType.SummonSkill: break; case BCardType.CardType.InflictSkill: break; case BCardType.CardType.HideBarrelSkill: break; case BCardType.CardType.FocusEnemyAttentionSkill: break; case BCardType.CardType.TauntSkill: break; case BCardType.CardType.FireCannoneerRangeBuff: break; case BCardType.CardType.VulcanoElementBuff: break; case BCardType.CardType.DamageConvertingSkill: break; case BCardType.CardType.MeditationSkill: { if (session is Character character) { if (SkillVNum.HasValue && SubType.Equals((byte)AdditionalTypes.MeditationSkill.CausingChance / 10) && ServerManager.RandomNumber() < FirstData) { Skill skill = ServerManager.GetSkill(SkillVNum.Value); Skill newSkill = ServerManager.GetSkill((short)SecondData); Observable.Timer(TimeSpan.FromMilliseconds(100)).Subscribe(observer => { foreach (QuicklistEntryDTO quicklistEntry in character.QuicklistEntries.Where(s => s.Pos.Equals(skill.CastId))) { character.Session.SendPacket($"qset {quicklistEntry.Q1} {quicklistEntry.Q2} {quicklistEntry.Type}.{quicklistEntry.Slot}.{newSkill.CastId}.0"); } character.Session.SendPacket($"mslot {newSkill.CastId} -1"); }); character.SkillComboCount++; character.LastSkillComboUse = DateTime.Now; if (skill.CastId > 10) { Observable.Timer(TimeSpan.FromMilliseconds((skill.GetCooldown(character) * 100) + 500)).Subscribe(observer => character.Session.SendPacket(StaticPacketHelper.SkillReset(skill.CastId))); } } switch (SubType) { case 2: character.MeditationDictionary[(short)SecondData] = DateTime.Now.AddSeconds(4); break; case 3: character.MeditationDictionary[(short)SecondData] = DateTime.Now.AddSeconds(8); break; case 4: character.MeditationDictionary[(short)SecondData] = DateTime.Now.AddSeconds(12); break; } } } break; case BCardType.CardType.FalconSkill: break; case BCardType.CardType.AbsorptionAndPowerSkill: break; case BCardType.CardType.LeonaPassiveSkill: break; case BCardType.CardType.FearSkill: break; case BCardType.CardType.SniperAttack: break; case BCardType.CardType.FrozenDebuff: break; case BCardType.CardType.JumpBackPush: break; case BCardType.CardType.FairyXPIncrease: break; case BCardType.CardType.SummonAndRecoverHP: break; case BCardType.CardType.TeamArenaBuff: break; case BCardType.CardType.ArenaCamera: break; case BCardType.CardType.DarkCloneSummon: break; case BCardType.CardType.AbsorbedSpirit: break; case BCardType.CardType.AngerSkill: break; case BCardType.CardType.MeteoriteTeleport: break; case BCardType.CardType.StealBuff: break; case BCardType.CardType.Unknown: break; case BCardType.CardType.EffectSummon: break; default: Logger.Warn($"Card Type {Type} Not Found!"); break; } }
internal List <MapCell> StraightPath(MapCell mapCell1, MapCell mapCell2) { List <MapCell> Path = new List <MapCell>(); Path.Add(mapCell1); do { if (Path.Last().X < mapCell2.X && Path.Last().Y < mapCell2.Y) { Path.Add(new MapCell() { MapId = MapId, X = (short)(Path.Last().X + 1), Y = (short)(Path.Last().Y + 1) }); } else if (Path.Last().X > mapCell2.X && Path.Last().Y > mapCell2.Y) { Path.Add(new MapCell() { MapId = MapId, X = (short)(Path.Last().X - 1), Y = (short)(Path.Last().Y - 1) }); } else if (Path.Last().X < mapCell2.X && Path.Last().Y > mapCell2.Y) { Path.Add(new MapCell() { MapId = MapId, X = (short)(Path.Last().X + 1), Y = (short)(Path.Last().Y - 1) }); } else if (Path.Last().X > mapCell2.X && Path.Last().Y < mapCell2.Y) { Path.Add(new MapCell() { MapId = MapId, X = (short)(Path.Last().X - 1), Y = (short)(Path.Last().Y + 1) }); } else if (Path.Last().X > mapCell2.X) { Path.Add(new MapCell() { MapId = MapId, X = (short)(Path.Last().X - 1), Y = (short)(Path.Last().Y) }); } else if (Path.Last().X < mapCell2.X) { Path.Add(new MapCell() { MapId = MapId, X = (short)(Path.Last().X + 1), Y = (short)(Path.Last().Y) }); } else if (Path.Last().Y > mapCell2.Y) { Path.Add(new MapCell() { MapId = MapId, X = (short)(Path.Last().X), Y = (short)(Path.Last().Y - 1) }); } else if (Path.Last().Y < mapCell2.Y) { Path.Add(new MapCell() { MapId = MapId, X = (short)(Path.Last().X), Y = (short)(Path.Last().Y + 1) }); } }while ((Path.Last().X != mapCell2.X || Path.Last().Y != mapCell2.Y) && (!IsBlockedZone(Path.Last().X, Path.Last().Y))); if (IsBlockedZone(Path.Last().X, Path.Last().Y)) { if (Path.Any()) { Path.Remove(Path.Last()); } } Path.RemoveAt(0); return(Path); }
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 - LastSay).Seconds; if (Delay != 0) { if (time > Delay) { if (Say != null) { MapInstance.Broadcast(StaticPacketHelper.Say(2, MapNpcId, 0, $"{Say}")); LastSay = 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(); } } } } }
public void Initialize() { if (MapInstance.MapInstanceType == MapInstanceType.BaseMapInstance && ServerManager.Instance.MapBossVNums.Contains(NpcVNum)) { MapCell randomCell = MapInstance.Map.GetRandomPosition(); if (randomCell != null) { if (MapInstance.Portals.Any(s => Map.GetDistance(new MapCell { X = s.SourceX, Y = s.SourceY }, new MapCell { X = randomCell.X, Y = randomCell.Y }) < 5)) { randomCell = MapInstance.Map.GetRandomPosition(); } MapX = randomCell.X; MapY = randomCell.Y; } } _random = new Random(MapNpcId); Npc = ServerManager.GetNpcMonster(NpcVNum); MaxHp = Npc.MaxHP; MaxMp = Npc.MaxMP; if (MapInstance?.MapInstanceType == MapInstanceType.TimeSpaceInstance) { if (IsProtected) { MaxHp *= 8; MaxMp *= 8; } } LastSay = DateTime.Now; EffectDelay = (short)(EffectDelay == 0 ? 4750 : EffectDelay); Delay = (short)(Delay == 0 ? 4750 : Delay); IsAlive = true; CurrentHp = MaxHp; CurrentMp = MaxMp; LastEffect = DateTime.Now; LastProtectedEffect = DateTime.Now; LastMove = DateTime.Now; LastSkill = DateTime.Now; IsHostile = Npc.IsHostile; ShouldRespawn = ShouldRespawn ?? true; FirstX = MapX; FirstY = MapY; EffectActivated = true; _movetime = ServerManager.RandomNumber(500, 3000); Path = new List <Node>(); Recipes = ServerManager.Instance.GetRecipesByMapNpcId(MapNpcId); Target = -1; Teleporters = ServerManager.Instance.GetTeleportersByNpcVNum(MapNpcId); Shop shop = ServerManager.Instance.GetShopByMapNpcId(MapNpcId); if (shop != null) { shop.Initialize(); Shop = shop; } Skills = new List <NpcMonsterSkill>(); foreach (NpcMonsterSkill ski in Npc.Skills) { Skills.Add(new NpcMonsterSkill { SkillVNum = ski.SkillVNum, Rate = ski.Rate }); } BattleEntity = new BattleEntity(this); if (AliveTime > 0) { Thread AliveTimeThread = new Thread(() => AliveTimeCheck()); AliveTimeThread.Start(); } if (NpcVNum == 1408) { OnDeathEvents.Add(new EventContainer(MapInstance, EventActionType.SPAWNMONSTER, new MonsterToSummon(621, new MapCell { X = MapX, Y = MapY }, null, move: true))); } if (NpcVNum == 1409) { OnDeathEvents.Add(new EventContainer(MapInstance, EventActionType.SPAWNMONSTER, new MonsterToSummon(622, new MapCell { X = MapX, Y = MapY }, null, move: true))); } if (NpcVNum == 1410) { OnDeathEvents.Add(new EventContainer(MapInstance, EventActionType.SPAWNMONSTER, new MonsterToSummon(623, new MapCell { X = MapX, Y = MapY }, null, move: true))); } if (OnSpawnEvents.Any()) { OnSpawnEvents.ToList().ForEach(e => { EventHelper.Instance.RunEvent(e, npc: this); }); OnSpawnEvents.Clear(); } }
internal int SummonMonster(MonsterToSummon summon) { NpcMonster npcMonster = ServerManager.GetNpcMonster(summon.VNum); if (npcMonster != null) { short mapX = summon.SpawnCell.X; short mapY = summon.SpawnCell.Y; if (mapX == 0 && mapY == 0) { MapCell cell = Map.GetRandomPosition(); if (cell != null) { mapX = cell.X; mapY = cell.Y; } } MapMonster mapMonster = new MapMonster { MonsterVNum = npcMonster.NpcMonsterVNum, MapX = mapX, MapY = mapY, Position = 2, MapId = Map.MapId, IsMoving = summon.IsMoving, MapMonsterId = GetNextMonsterId(), ShouldRespawn = false, OnNoticeEvents = summon.NoticingEvents, UseSkillOnDamage = summon.UseSkillOnDamage, OnSpawnEvents = summon.SpawnEvents, IsTarget = summon.IsTarget, Target = summon.Target, IsBonus = summon.IsBonus, IsBoss = summon.IsBoss, NoticeRange = summon.NoticeRange, Owner = summon.Owner, AliveTime = summon.AliveTime, AliveTimeMp = summon.AliveTimeMp, BaseMaxHp = summon.MaxHp, BaseMaxMp = summon.MaxMp }; if (summon.HasDelay > 0) { AddDelayedMonster(mapMonster); } Observable.Timer(TimeSpan.FromSeconds(summon.HasDelay)) .Subscribe(o => { mapMonster.Initialize(this); mapMonster.BattleEntity.OnDeathEvents.AddRange(summon.DeathEvents); mapMonster.IsHostile = summon.IsHostile; AddMonster(mapMonster); Broadcast(mapMonster.GenerateIn()); RemoveDelayedMonster(mapMonster); if (summon.AfterSpawnEvents.Any()) { summon.AfterSpawnEvents.ForEach(e => EventHelper.Instance.RunEvent(e, monster: mapMonster)); } if (summon.IsMeteorite) { OnMeteoriteEvents(summon, mapMonster); } }); return(mapMonster.MapMonsterId); } return(default);
public IEnumerable <BattleEntity> GetBattleEntitiesInRange(MapCell pos, byte distance) { return(BattleEntities.Where(b => Map.GetDistance(b.GetPos(), pos) <= distance)); }
public static void NRun(ClientSession Session, NRunPacket packet) { if (!Session.HasCurrentMapInstance) { return; } MapNpc npc = Session.CurrentMapInstance.Npcs.Find(s => s.MapNpcId == packet.NpcId); TeleporterDTO tp; MapNpcDTO npcTp; switch (packet.Runner) { case 1: if (packet.Type > 4 || packet.Type < 1) { return; } if (Session.Character.Class != (byte)ClassType.Adventurer) { Session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("NOT_ADVENTURER"), 0)); return; } if (Session.Character.Level < 15 || Session.Character.JobLevel < 20) { Session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("LOW_LVL"), 0)); return; } if (packet.Type == (byte)Session.Character.Class || packet.Type > 3 && Session.Account.Authority < AuthorityType.GameMaster || packet.Type < 0) { return; } if (Session.Character.Inventory.All(i => i.Type != InventoryType.Wear)) { Session.Character.Inventory.AddNewToInventory((short)(4 + (packet.Type * 14)), type: InventoryType.Wear); Session.Character.Inventory.AddNewToInventory((short)(81 + (packet.Type * 13)), type: InventoryType.Wear); switch (packet.Type) { case 1: Session.Character.Inventory.AddNewToInventory(68, type: InventoryType.Wear); Session.Character.Inventory.AddNewToInventory(2082, 10); break; case 2: Session.Character.Inventory.AddNewToInventory(78, type: InventoryType.Wear); Session.Character.Inventory.AddNewToInventory(2083, 10); break; case 3: Session.Character.Inventory.AddNewToInventory(86, type: InventoryType.Wear); break; } Session.CurrentMapInstance?.Broadcast(Session.Character.GenerateEq()); Session.SendPacket(Session.Character.GenerateEquipment()); Session.Character.ChangeClass((ClassType)packet.Type); } else { Session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("EQ_NOT_EMPTY"), 0)); } break; case 2: Session.SendPacket("wopen 1 0"); break; case 4: Mate mate = Session.Character.Mates.Find(s => s.MateTransportId == packet.NpcId); switch (packet.Type) { case 2: if (mate != null) { if (Session.Character.Level >= mate.Level) { Mate teammate = Session.Character.Mates.Where(s => s.IsTeamMember).FirstOrDefault(s => s.MateType == mate.MateType); if (teammate != null) { teammate.IsTeamMember = false; teammate.MapX = teammate.PositionX; teammate.MapY = teammate.PositionY; } mate.IsTeamMember = true; } else { Session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("PET_HIGHER_LEVEL"), 0)); } } break; case 3: if (mate != null && Session.Character.Miniland == Session.Character.MapInstance) { mate.IsTeamMember = false; mate.MapX = mate.PositionX; mate.MapY = mate.PositionY; } break; case 4: if (mate != null) { if (Session.Character.Miniland == Session.Character.MapInstance) { mate.IsTeamMember = false; mate.MapX = mate.PositionX; mate.MapY = mate.PositionY; } else { Session.SendPacket($"qna #n_run^4^5^3^{mate.MateTransportId} {Language.Instance.GetMessageFromKey("ASK_KICK_PET")}"); } break; } break; case 5: if (mate != null) { Session.SendPacket(UserInterfaceHelper.GenerateDelay(3000, 10, $"#n_run^4^6^3^{mate.MateTransportId}")); } break; case 6: if (mate != null && Session.Character.Miniland != Session.Character.MapInstance) { mate.IsTeamMember = false; Session.CurrentMapInstance.Broadcast(mate.GenerateOut()); Session.SendPacket(Session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("PET_KICKED"), mate.Name), 11)); Session.SendPacket(UserInterfaceHelper.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("PET_KICKED"), mate.Name), 0)); } break; case 7: if (mate != null) { if (Session.Character.Mates.Any(s => s.MateType == mate.MateType && s.IsTeamMember)) { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ALREADY_PET_IN_TEAM"), 11)); Session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("ALREADY_PET_IN_TEAM"), 0)); } else { Session.SendPacket(UserInterfaceHelper.GenerateDelay(3000, 10, $"#n_run^4^9^3^{mate.MateTransportId}")); } } break; case 9: if (mate != null && Session.Character.Level >= mate.Level) { mate.PositionX = (short)(Session.Character.PositionX + (mate.MateType == MateType.Partner ? -1 : 1)); mate.PositionY = (short)(Session.Character.PositionY + 1); mate.IsTeamMember = true; Session.CurrentMapInstance?.Broadcast(mate.GenerateIn()); } else { Session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("PET_HIGHER_LEVEL"), 0)); } break; } Session.SendPacket(Session.Character.GeneratePinit()); Session.SendPackets(Session.Character.GeneratePst()); break; case 10: Session.SendPacket("wopen 3 0"); break; case 12: Session.SendPacket($"wopen {packet.Type} 0"); break; case 14: Session.SendPacket("wopen 27 0"); string recipelist = "m_list 2"; if (npc != null) { List <Recipe> tps = npc.Recipes; recipelist = tps.Where(s => s.Amount > 0).Aggregate(recipelist, (current, s) => current + $" {s.ItemVNum}"); recipelist += " -100"; Session.SendPacket(recipelist); } break; case 15: if (npc != null) { if (packet.Value == 2) { Session.SendPacket($"qna #n_run^15^1^1^{npc.MapNpcId} {Language.Instance.GetMessageFromKey("ASK_CHANGE_SPAWNLOCATION")}"); } else { switch (npc.MapId) { case 1: Session.Character.SetRespawnPoint(1, 79, 116); break; case 20: Session.Character.SetRespawnPoint(20, 9, 92); break; case 145: Session.Character.SetRespawnPoint(145, 13, 110); break; } Session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("RESPAWNLOCATION_CHANGED"), 0)); } } break; case 16: tp = npc?.Teleporters?.FirstOrDefault(s => s.Index == packet.Type); if (tp != null) { if (Session.Character.Gold >= 1000 * packet.Type && packet.Type > 0) { Session.Character.Gold -= 1000 * packet.Type; Session.SendPacket(Session.Character.GenerateGold()); ServerManager.Instance.ChangeMap(Session.Character.CharacterId, tp.MapId, tp.MapX, tp.MapY); } else { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10)); } } break; case 17: double currentRunningSeconds = (DateTime.Now - Process.GetCurrentProcess().StartTime.AddSeconds(-50)).TotalSeconds; double timeSpanSinceLastPortal = currentRunningSeconds - Session.Character.LastPortal; if (!(timeSpanSinceLastPortal >= 4) || !Session.HasCurrentMapInstance || ServerManager.Instance.ChannelId == 51 || Session.CurrentMapInstance.MapInstanceId == ServerManager.Instance.ArenaInstance.MapInstanceId || Session.CurrentMapInstance.MapInstanceId == ServerManager.Instance.FamilyArenaInstance.MapInstanceId) { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("CANT_MOVE"), 10)); return; } if (packet.Type < 0) { Logger.Log.Debug($"Admin: user {Session.Character.Name} tried an Gold Bug: NRun"); return; } if (Session.Character.Gold >= 500 * (1 + packet.Type)) { Session.Character.LastPortal = currentRunningSeconds; Session.Character.Gold -= 500 * (1 + packet.Type); Session.SendPacket(Session.Character.GenerateGold()); MapCell pos = packet.Type == 0 ? ServerManager.Instance.ArenaInstance.Map.GetRandomPosition() : ServerManager.Instance.FamilyArenaInstance.Map.GetRandomPosition(); ServerManager.Instance.ChangeMapInstance(Session.Character.CharacterId, packet.Type == 0 ? ServerManager.Instance.ArenaInstance.MapInstanceId : ServerManager.Instance.FamilyArenaInstance.MapInstanceId, pos.X, pos.Y); } else { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10)); } break; case 18: Session.SendPacket(Session.Character.GenerateNpcDialog(17)); break; case 26: tp = npc?.Teleporters?.FirstOrDefault(s => s.Index == packet.Type); if (tp != null) { if (Session.Character.Gold >= 5000 * packet.Type && packet.Type > 0) { Session.Character.Gold -= 5000 * packet.Type; ServerManager.Instance.ChangeMap(Session.Character.CharacterId, tp.MapId, tp.MapX, tp.MapY); } else { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10)); } } break; case 45: tp = npc?.Teleporters?.FirstOrDefault(s => s.Index == packet.Type); if (tp != null) { if (Session.Character.Gold >= 500) { Session.Character.Gold -= 500; Session.SendPacket(Session.Character.GenerateGold()); ServerManager.Instance.ChangeMap(Session.Character.CharacterId, tp.MapId, tp.MapX, tp.MapY); } else { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10)); } } break; case 132: tp = npc?.Teleporters?.FirstOrDefault(s => s.Index == packet.Type); if (tp != null) { ServerManager.Instance.ChangeMap(Session.Character.CharacterId, tp.MapId, tp.MapX, tp.MapY); } break; case 150: if (npc == null || !npc.EffectActivated && ServerManager.Instance.LodTimes || Session.Character.Level < ServerManager.Instance.MinLodLevel) { return; } if (Session.Character?.Family == null) { Session.SendPacket( UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("NEED_FAMILY"), 0)); break; } if (Session.Character?.Family?.LandOfDeath != null) { ServerManager.Instance.ChangeMapInstance(Session.Character.CharacterId, Session.Character.Family.LandOfDeath.MapInstanceId, 153, 145); } break; case 301: tp = npc?.Teleporters?.FirstOrDefault(s => s.Index == packet.Type); if (tp != null) { ServerManager.Instance.ChangeMap(Session.Character.CharacterId, tp.MapId, tp.MapX, tp.MapY); } break; case 1600: Session.SendPacket(Session.Character.OpenFamilyWarehouse()); break; case 1601: Session.SendPackets(Session.Character.OpenFamilyWarehouseHist()); break; case 1602: if (Session.Character.Family?.FamilyLevel >= 3 && Session.Character.Family.WarehouseSize < 21) { if (Session.Character.FamilyCharacter.Authority == FamilyAuthority.Head) { if (500000 >= Session.Character.Gold) { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10)); return; } Session.Character.Family.WarehouseSize = 21; Session.Character.Gold -= 500000; Session.SendPacket(Session.Character.GenerateGold()); FamilyDTO fam = Session.Character.Family; DAOFactory.FamilyDAO.InsertOrUpdate(ref fam); ServerManager.Instance.FamilyRefresh(Session.Character.Family.FamilyId); } else { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 10)); Session.SendPacket(UserInterfaceHelper.GenerateModal(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 1)); } } break; case 1603: if (Session.Character.Family?.FamilyLevel >= 7 && Session.Character.Family.WarehouseSize < 49) { if (Session.Character.FamilyCharacter.Authority == FamilyAuthority.Head) { if (2000000 >= Session.Character.Gold) { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10)); return; } Session.Character.Family.WarehouseSize = 49; Session.Character.Gold -= 2000000; Session.SendPacket(Session.Character.GenerateGold()); FamilyDTO fam = Session.Character.Family; DAOFactory.FamilyDAO.InsertOrUpdate(ref fam); ServerManager.Instance.FamilyRefresh(Session.Character.Family.FamilyId); } else { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 10)); Session.SendPacket(UserInterfaceHelper.GenerateModal(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 1)); } } break; case 1604: if (Session.Character.Family?.FamilyLevel >= 5 && Session.Character.Family.MaxSize < 70) { if (Session.Character.FamilyCharacter.Authority == FamilyAuthority.Head) { if (5000000 >= Session.Character.Gold) { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10)); return; } Session.Character.Family.MaxSize = 70; Session.Character.Gold -= 5000000; Session.SendPacket(Session.Character.GenerateGold()); FamilyDTO fam = Session.Character.Family; DAOFactory.FamilyDAO.InsertOrUpdate(ref fam); ServerManager.Instance.FamilyRefresh(Session.Character.Family.FamilyId); } else { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 10)); Session.SendPacket(UserInterfaceHelper.GenerateModal(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 1)); } } break; case 1605: if (Session.Character.Family?.FamilyLevel >= 9 && Session.Character.Family.MaxSize < 100) { if (Session.Character.FamilyCharacter.Authority == FamilyAuthority.Head) { if (10000000 >= Session.Character.Gold) { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10)); return; } Session.Character.Family.MaxSize = 100; Session.Character.Gold -= 10000000; Session.SendPacket(Session.Character.GenerateGold()); FamilyDTO fam = Session.Character.Family; DAOFactory.FamilyDAO.InsertOrUpdate(ref fam); ServerManager.Instance.FamilyRefresh(Session.Character.Family.FamilyId); } else { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 10)); Session.SendPacket(UserInterfaceHelper.GenerateModal(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 1)); } } break; case 23: if (packet.Type == 0) { if (Session.Character.Group?.CharacterCount == 3) { foreach (ClientSession s in Session.Character.Group.Characters.GetAllItems()) { if (s.Character.Family != null) { Session.SendPacket(UserInterfaceHelper.GenerateInfo(Language.Instance.GetMessageFromKey("GROUP_MEMBER_ALREADY_IN_FAMILY"))); return; } } } if (Session.Character.Group == null || Session.Character.Group.CharacterCount != 3) { Session.SendPacket(UserInterfaceHelper.GenerateInfo(Language.Instance.GetMessageFromKey("FAMILY_GROUP_NOT_FULL"))); return; } Session.SendPacket(UserInterfaceHelper.GenerateInbox($"#glmk^ {14} 1 {Language.Instance.GetMessageFromKey("CREATE_FAMILY").Replace(' ', '^')}")); } else { if (Session.Character.Family == null) { Session.SendPacket(UserInterfaceHelper.GenerateInfo(Language.Instance.GetMessageFromKey("NOT_IN_FAMILY"))); return; } if (Session.Character.Family != null && Session.Character.FamilyCharacter != null && Session.Character.FamilyCharacter.Authority != FamilyAuthority.Head) { Session.SendPacket(UserInterfaceHelper.GenerateInfo(Language.Instance.GetMessageFromKey("NOT_FAMILY_HEAD"))); return; } Session.SendPacket($"qna #glrm^1 {Language.Instance.GetMessageFromKey("DISMISS_FAMILY")}"); } break; case 60: StaticBonusDTO medal = Session.Character.StaticBonusList.Find(s => s.StaticBonusType == StaticBonusType.BazaarMedalGold || s.StaticBonusType == StaticBonusType.BazaarMedalSilver); byte Medal = 0; int Time = 0; if (medal != null) { Medal = medal.StaticBonusType == StaticBonusType.BazaarMedalGold ? (byte)MedalType.Gold : (byte)MedalType.Silver; Time = (int)(medal.DateEnd - DateTime.Now).TotalHours; } Session.SendPacket($"wopen 32 {Medal} {Time}"); break; case 5002: npcTp = DAOFactory.MapNpcDAO.LoadAll().Where(n => n.NpcVNum == 540).FirstOrDefault(); if (npcTp != null) { if (ServerManager.Instance.ChannelId == 51) { Session.SendPacket("it 3"); string connection = CommunicationServiceClient.Instance.RetrieveOriginWorld(Session.Account.AccountId); if (string.IsNullOrWhiteSpace(connection)) { return; } Session.Character.MapId = npcTp.MapId; Session.Character.MapX = npcTp.MapX; Session.Character.MapY = npcTp.MapY; int port = Convert.ToInt32(connection.Split(':')[1]); Session.Character.ChangeChannel(connection.Split(':')[0], port, 3); } else { ServerManager.Instance.ChangeMap(Session.Character.CharacterId, npcTp.MapId, npcTp.MapX, npcTp.MapY); } } break; case 5001: if (npc != null) { MapInstance map = null; switch (Session.Character.Faction) { case FactionType.None: Session.SendPacket(UserInterfaceHelper.GenerateInfo("You need to be part of a faction to join Act 4")); return; case FactionType.Angel: map = ServerManager.GetAllMapInstances().Find(s => s.MapInstanceType.Equals(MapInstanceType.Act4ShipAngel)); break; case FactionType.Demon: map = ServerManager.GetAllMapInstances().Find(s => s.MapInstanceType.Equals(MapInstanceType.Act4ShipDemon)); break; } if (map == null /* || npc.EffectActivated*/) { Session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("SHIP_NOTARRIVED"), 0)); return; } if (3000 > Session.Character.Gold) { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10)); return; } Session.Character.Gold -= 3000; MapCell pos = map.Map.GetRandomPosition(); ServerManager.Instance.ChangeMapInstance(Session.Character.CharacterId, map.MapInstanceId, pos.X, pos.Y); } break; case 5004: if (npc != null) { ServerManager.Instance.ChangeMap(Session.Character.CharacterId, 261, 113, 160); } break; case 5011: if (npc != null) { ServerManager.Instance.ChangeMap(Session.Character.CharacterId, 170, 127, 46); } break; case 5012: tp = npc?.Teleporters?.FirstOrDefault(s => s.Index == packet.Type); if (tp != null) { ServerManager.Instance.ChangeMap(Session.Character.CharacterId, tp.MapId, tp.MapX, tp.MapY); } break; default: Logger.Warn(string.Format(Language.Instance.GetMessageFromKey("NO_NRUN_HANDLER"), packet.Runner)); break; } }