/// <summary> /// Sends BlacksmithingMiniGame to creature's client, which starts /// the Blacksmithing mini-game. /// </summary> /// <remarks> /// The position of the dots is relative to the upper left of the /// field. They land exactly on those spots after "wavering" for a /// moment. This wavering is randomized on the client side and /// doesn't affect anything. /// /// The time bar is always the same, but the time it takes to fill /// up changes based on the "time displacement". The lower the value, /// the longer it takes to fill up. Using values that are too high /// or too low mess up the calculations and cause confusing results. /// The official range seems to be between ~0.81 and ~0.98. /// </remarks> /// <param name="creature"></param> /// <param name="prop"></param> /// <param name="item"></param> /// <param name="dots"></param> /// <param name="deviation"></param> public static void BlacksmithingMiniGame(Creature creature, Prop prop, Item item, List<BlacksmithDot> dots, int deviation) { if (dots == null || dots.Count != 5) throw new ArgumentException("5 dots required."); var packet = new Packet(Op.BlacksmithingMiniGame, creature.EntityId); // Untested if this is actually the deviation/cursor size, // but Tailoring does something very similar. Just like with // Tailoring, wrong values cause failed games. packet.PutShort((short)deviation); foreach (var dot in dots) { packet.PutShort((short)dot.X); packet.PutShort((short)dot.Y); packet.PutFloat(dot.TimeDisplacement); packet.PutShort((short)dot.Deviation); } packet.PutLong(prop.EntityId); packet.PutInt(0); packet.PutLong(item.EntityId); packet.PutInt(0); creature.Client.Send(packet); }
/// <summary> /// Sends TradeInfo to creature's client. /// </summary> /// <param name="creature"></param> /// <param name="tradeId"></param> /// <param name="tradePartnerEntityId"></param> public static void TradeInfo(Creature creature, long tradeId, long tradePartnerEntityId) { var packet = new Packet(Op.TradeInfo, creature.EntityId); packet.PutLong(tradeId); packet.PutLong(tradePartnerEntityId); creature.Client.Send(packet); }
/// <summary> /// Sends Weather. /// </summary> private static void Weather(Action<Packet> sender, IWeatherProvider provider) { var packet = new Packet(Op.Weather, MabiId.Broadcast); packet.PutByte(0); packet.PutInt(provider.RegionId); if (provider is IWeatherProviderTable) { var table = (IWeatherProviderTable)provider; packet.PutByte(0); packet.PutInt(table.GroupId); packet.PutByte(2); packet.PutByte(1); packet.PutString("table"); packet.PutString(table.Name); packet.PutLong(0); packet.PutByte(0); } else if (provider is IWeatherProviderConstant) { var constant = (IWeatherProviderConstant)provider; // Packet structure is guessed, even though it works, // based on constant_smooth. packet.PutByte(2); packet.PutByte(0); packet.PutByte(1); packet.PutString("constant"); packet.PutFloat(constant.Weather); packet.PutLong(0); packet.PutByte(0); } else if (provider is IWeatherProviderConstantSmooth) { var constantSmooth = (IWeatherProviderConstantSmooth)provider; packet.PutByte(2); packet.PutByte(0); packet.PutByte(1); packet.PutString("constant_smooth"); packet.PutFloat(constantSmooth.Weather); packet.PutLong(DateTime.Now); // Start packet.PutLong(DateTime.MinValue); // End packet.PutFloat(constantSmooth.WeatherBefore); packet.PutFloat(constantSmooth.WeatherBefore); packet.PutLong(constantSmooth.TransitionTime); packet.PutByte(false); // bool? Is table appended? byte? Appended type? packet.PutLong(DateTime.MinValue); // End packet.PutInt(2); // Append a table packet here to go back to that after end packet.PutByte(0); } sender(packet); }
/// <summary> /// Sends ChannelLoginR to client. /// </summary> /// <remarks> /// Sending a negative response doesn't do anything. /// </remarks> public static void ChannelLoginR(ChannelClient client, long creatureId) { var packet = new Packet(Op.ChannelLoginR, MabiId.Channel); packet.PutByte(true); packet.PutLong(creatureId); packet.PutLong(DateTime.Now); packet.PutInt((int)DateTime.Now.DayOfWeek); packet.PutString(""); // http://211.218.233.238/korea/ client.Send(packet); }
/// <summary> /// Sends GuildInfoApplied to creature's client. /// </summary> /// <param name="creature"></param> /// <param name="guild"></param> public static void GuildInfoApplied(Creature creature, Guild guild) { // The fields of this packet were guessed, something might be missing. var packet = new Packet(Op.GuildInfoApplied, creature.EntityId); packet.PutLong(guild.Id); packet.PutString(guild.Server); packet.PutLong(creature.EntityId); packet.PutString(guild.Name); creature.Client.Send(packet); }
/// <summary> /// Sends BankAddItem to creature's client. /// </summary> /// <param name="creature"></param> /// <param name="item"></param> /// <param name="bankId"></param> /// <param name="tabName"></param> public static void BankAddItem(Creature creature, Item item, string bankId, string tabName) { var packet = new Packet(Op.BankAddItem, creature.EntityId); packet.PutString(tabName); packet.PutString(bankId); packet.PutLong(0); packet.PutLong(0); packet.AddItemInfo(item, ItemPacketType.Private); creature.Client.Send(packet); }
/// <summary> /// Sends EnterDynamicRegion to creature's client. /// </summary> /// <param name="creature"></param> /// <param name="warpFromRegionId"></param> /// <param name="warpToRegion"></param> public static void EnterDynamicRegion(Creature creature, int warpFromRegionId, Region warpToRegion, int x, int y) { var warpTo = warpToRegion as DynamicRegion; if (warpTo == null) throw new ArgumentException("EnterDynamicRegion requires a dynamic region."); var pos = creature.GetPosition(); var packet = new Packet(Op.EnterDynamicRegion, MabiId.Broadcast); packet.PutLong(creature.EntityId); packet.PutInt(warpFromRegionId); // creature's current region or 0? packet.PutInt(warpToRegion.Id); packet.PutString(warpToRegion.Name); // dynamic region name packet.PutUInt(0x80000000); // bitmask? (|1 = time difference?) packet.PutInt(warpTo.BaseId); packet.PutString(warpTo.BaseName); packet.PutInt(200); // 100|200 (100 changes the lighting?) packet.PutByte(0); // 1 = next is empty? packet.PutString("data/world/{0}/{1}", warpTo.BaseName, warpTo.Variation); packet.PutByte(0); //if (^ true) //{ // pp.PutByte(1); // pp.PutInt(3100); // some region id? //} packet.PutInt(x); // target x pos packet.PutInt(y); // target y pos creature.Client.Send(packet); }
/// <summary> /// Sends Disappear to creature's client. /// </summary> /// <remarks> /// Should this be broadcasted? What does it even do? TODO. /// </remarks> /// <param name="creature"></param> public static void Disappear(Creature creature) { var packet = new Packet(Op.Disappear, MabiId.Channel); packet.PutLong(creature.EntityId); creature.Client.Send(packet); }
/// <summary> /// Sends GuildPanel to creature's client. /// </summary> /// <param name="creature"></param> /// <param name="guild"></param> public static void GuildPanel(Creature creature, Guild guild) { var packet = new Packet(Op.GuildPanel, creature.EntityId); packet.PutLong(guild.Id); packet.PutByte(creature.GuildMember.IsLeader); if (creature.GuildMember.IsLeader) { packet.PutInt(guild.WithdrawMaxAmount); packet.PutLong(guild.WithdrawDeadline); packet.PutInt(guild.MaxMembers); } packet.PutByte(0); packet.PutByte(0); // 1: Go To Guild Hall, 2: Go To Guild Stone creature.Client.Send(packet); }
/// <summary> /// Sends PetUnregister to creature's client. /// </summary> /// <param name="creature"></param> /// <param name="pet"></param> public static void PetUnregister(Creature creature, Creature pet) { var packet = new Packet(Op.PetUnregister, creature.EntityId); packet.PutLong(pet.EntityId); creature.Client.Send(packet); }
/// <summary> /// Broadcasts PartySetActiveQuest in party. /// </summary> /// <param name="party"></param> /// <param name="uniqueQuestId"></param> public static void PartySetActiveQuest(Party party, long uniqueQuestId) { var packet = new Packet(Op.PartySetActiveQuest, 0); packet.PutLong(uniqueQuestId); party.Broadcast(packet, true); }
/// <summary> /// Broadcasts PropDisappears in prop's region. /// </summary> /// <param name="prop"></param> public static void PropDisappears(Prop prop) { var packet = new Packet(Op.PropDisappears, MabiId.Broadcast); packet.PutLong(prop.EntityId); prop.Region.Broadcast(packet, prop, false); }
/// <summary> /// Sends QuestClear to creature's client. /// </summary> /// <remarks> /// Removes quest from quest log. /// </remarks> /// <param name="creature"></param> /// <param name="questId"></param> public static void QuestClear(Creature creature, long questId) { var packet = new Packet(Op.QuestClear, creature.EntityId); packet.PutLong(questId); creature.Client.Send(packet); }
/// <summary> /// Sends PersonalShopCustomerPriceUpdate to creature's client. /// </summary> /// <param name="creature"></param> /// <param name="itemEntityId"></param> /// <param name="price"></param> public static void PersonalShopCustomerPriceUpdate(Creature creature, long itemEntityId, int price) { var packet = new Packet(Op.PersonalShopCustomerPriceUpdate, creature.EntityId); packet.PutLong(itemEntityId); packet.PutInt(price); creature.Client.Send(packet); }
/// <summary> /// Sends CutsceneEnd to cutscene's leader. /// </summary> /// <param name="cutscene"></param> public static void CutsceneEnd(Cutscene cutscene) { var packet = new Packet(Op.CutsceneEnd, MabiId.Channel); packet.PutLong(cutscene.Leader.EntityId); // TODO: Send to whole party? cutscene.Leader.Client.Send(packet); }
/// <summary> /// Sends EntrustmentRequest to creature's client. /// </summary> /// <param name="creature"></param> /// <param name="partnerEntityId"></param> /// <param name="unkByte"></param> public static void EntrustmentRequest(Creature creature, long partnerEntityId, byte unkByte) { var packet = new Packet(Op.EntrustmentRequest, creature.EntityId); packet.PutLong(partnerEntityId); packet.PutByte(unkByte); creature.Client.Send(packet); }
/// <summary> /// Broadcasts AssignSittingProp in range of creature. /// </summary> /// <remarks> /// Moves creature into position, to sit down on the prop. /// Pass 0 for the parameters to undo. /// </remarks> /// <param name="creature"></param> /// <param name="propEntityId"></param> /// <param name="unk"></param> public static void AssignSittingProp(Creature creature, long propEntityId, int unk) { var packet = new Packet(Op.AssignSittingProp, creature.EntityId); packet.PutLong(propEntityId); packet.PutInt(unk); creature.Region.Broadcast(packet); }
/// <summary> /// Sends PetRegister to creature's client. /// </summary> /// <remarks> /// TODO: Test, does this tell the client it can control this creature? /// </remarks> /// <param name="creature"></param> /// <param name="pet"></param> public static void PetRegister(Creature creature, Creature pet, SubordinateType type) { var packet = new Packet(Op.PetRegister, creature.EntityId); packet.PutLong(pet.EntityId); packet.PutByte((byte)type); creature.Client.Send(packet); }
/// <summary> /// Sends ClientIdentR to client. /// </summary> /// <param name="client"></param> /// <param name="success"></param> public static void CheckIdentR(LoginClient client, bool success) { var packet = new Packet(Op.ClientIdentR, MabiId.Login); packet.PutByte(success); packet.PutLong(DateTime.Now); client.Send(packet); }
/// <summary> /// Sends PetRegister to creature's client. /// </summary> /// <remarks> /// TODO: Test, does this tell the client it can control this creature? /// </remarks> /// <param name="creature"></param> /// <param name="pet"></param> public static void PetRegister(Creature creature, Creature pet) { var packet = new Packet(Op.PetRegister, creature.EntityId); packet.PutLong(pet.EntityId); packet.PutByte(2); // Probably the follower type, see 5209 creature.Client.Send(packet); }
/// <summary> /// Sends UnsummonPetR to creature's client. /// </summary> /// <param name="creature"></param> /// <param name="success"></param> /// <param name="entityId"></param> public static void UnsummonPetR(Creature creature, bool success, long entityId) { var packet = new Packet(Op.UnsummonPetR, creature.EntityId); packet.PutByte(success); packet.PutLong(entityId); creature.Client.Send(packet); }
/// <summary> /// Broadcasts ChatSticker in range of creature, activating the sticker. /// </summary> /// <param name="creature"></param> /// <param name="sticker"></param> /// <param name="end"></param> public static void ChatSticker(Creature creature, ChatSticker sticker, DateTime end) { var packet = new Packet(Op.ChatSticker, creature.EntityId); packet.PutInt((int)sticker); packet.PutLong(end); creature.Region.Broadcast(packet, creature); }
/// <summary> /// Sends NpcTalkEndR to creature's client. /// </summary> /// <remarks> /// If no message is specified "<end/>" is sent, /// to close the dialog box immediately. /// </remarks> /// <param name="creature"></param> /// <param name="npcId"></param> /// <param name="message">Last message before closing.</param> public static void NpcTalkEndR(Creature creature, long npcId, string message = null) { var p = new Packet(Op.NpcTalkEndR, creature.EntityId); p.PutByte(true); p.PutLong(npcId); p.PutString(message ?? "<end/>"); creature.Client.Send(p); }
/// <summary> /// Sends NpcTalkStartR to creature's client. /// </summary> /// <param name="creature"></param> /// <param name="npcId">Negative response if 0.</param> public static void NpcTalkStartR(Creature creature, long npcId) { var packet = new Packet(Op.NpcTalkStartR, creature.EntityId); packet.PutByte(npcId != 0); if (npcId != 0) packet.PutLong(npcId); creature.Client.Send(packet); }
/// <summary> /// Sends BankRemoveItem to creature's client. /// </summary> /// <param name="creature"></param> /// <param name="tabName"></param> /// <param name="itemEntityId"></param> public static void BankRemoveItem(Creature creature, string tabName, long itemEntityId) { var packet = new Packet(Op.BankRemoveItem, creature.EntityId); packet.PutString(tabName); packet.PutLong(itemEntityId); creature.Client.Send(packet); }
/// <summary> /// Broadcasts QuestOwlNew in range of creature. /// </summary> /// <remarks> /// Effect of an owl delivering the new quest. /// </remarks> /// <param name="creature"></param> /// <param name="questId"></param> public static void QuestOwlNew(Creature creature, long questId) { var packet = new Packet(Op.QuestOwlNew, creature.EntityId); packet.PutLong(questId); // Creature don't have a region in Soul Stream. if (creature.Region != Region.Limbo) creature.Region.Broadcast(packet, creature); }
/// <summary> /// Sends EntrustmentR to creature's client. /// </summary> /// <param name="creature"></param> /// <param name="success"></param> /// <param name="partner"></param> public static void EntrustmentR(Creature creature, bool success, Creature partner) { var packet = new Packet(Op.EntrustmentR, creature.EntityId); packet.PutByte(success); packet.PutLong(partner.EntityId); packet.PutString(partner.Name); creature.Client.Send(packet); }
/// <summary> /// Sends SummonPetR to creature's client. /// </summary> /// <param name="creature"></param> /// <param name="pet">Negative response if null</param> public static void SummonPetR(Creature creature, Creature pet) { var packet = new Packet(Op.SummonPetR, creature.EntityId); packet.PutByte(pet != null); if (pet != null) packet.PutLong(pet.EntityId); creature.Client.Send(packet); }
/// <summary> /// Broadcasts PetAction in range of pet. /// </summary> /// <param name="pet"></param> /// <param name="action"></param> public static void PetActionEffect(Creature pet, PetAction action) { var packet = new Packet(Op.Effect, pet.EntityId); packet.PutInt(E.PetAction); packet.PutLong(pet.Master.EntityId); packet.PutByte((byte)action); packet.PutByte(0); pet.Region.Broadcast(packet, pet); }
/// <summary> /// Sends GuildInfoNoGuild to creature's client. /// </summary> /// <param name="creature"></param> /// <param name="guild"></param> public static void GuildInfoNoGuild(Creature creature, Guild guild) { var packet = new Packet(Op.GuildInfoNoGuild, creature.EntityId); packet.PutLong(guild.Id); packet.PutString(guild.Name); packet.PutString(guild.LeaderName); packet.PutInt(guild.MemberCount); packet.PutString(guild.IntroMessage); creature.Client.Send(packet); }