/// <summary> /// Broadcasts Effect packet in range. Parameters can be added, /// but you have to watch the types. /// </summary> /// <param name="delay">Delay in milliseconds</param> public static void EffectDelayed(uint effect, uint delay, MabiEntity source, params object[] args) { var packet = new MabiPacket(Op.EffectDelayed, source.Id); packet.PutInt(delay); packet.PutInt(effect); foreach (var arg in args) { if (!(arg is bool)) packet.Put(arg); else packet.PutByte((bool)arg); } WorldManager.Instance.Broadcast(packet, SendTargets.Range, source); }
public static MabiPacket AcquireStat(MabiCreature creature, string statName, double amount) { var p = new MabiPacket(Op.AcquireInfo, creature.Id); p.PutString("<xml type='{0}' value='{1}' simple='true' onlyLog='false' />", statName, (uint)amount); p.PutInt(3000); return p; }
public static MabiPacket AcquireAp(MabiCreature creature, uint amount) { var p = new MabiPacket(Op.AcquireInfo, creature.Id); p.PutString("<xml type='ap' value='{0}' simple='true' onlyLog='false' />", amount); p.PutInt(3000); return p; }
public static MabiPacket AcquireExp(MabiCreature creature, uint amount) { var p = new MabiPacket(Op.AcquireInfo, creature.Id); p.PutString("<xml type='exp' value='{0}'/>", amount); p.PutInt(3000); return p; }
public static MabiPacket AcquireItem(MabiCreature creature, uint cls, uint amount) { var p = new MabiPacket(Op.AcquireInfo, creature.Id); p.PutString("<xml type='item' classid='{0}' value='{1}'/>", cls, amount); p.PutInt(3000); return p; }
/// <summary> /// Sends item box packet for fixed dyed item to client. /// </summary> /// <param name="client"></param> /// <param name="creature"></param> /// <param name="itemId"></param> public static void AcquireDyedItem(Client client, MabiCreature creature, ulong itemId) { var packet = new MabiPacket(Op.AcquireInfo2, creature.Id); packet.PutString("<xml type='fixed_color_dyeing' objectid='{0}'/>", itemId); packet.PutInt(3000); client.Send(packet); }
/// <summary> /// Fixed dye complete /// </summary> /// <param name="client"></param> /// <param name="creature"></param> /// <param name="skillId"></param> /// <param name="part"></param> public static void DyeSkillComplete(Client client, MabiCreature creature, SkillConst skillId, uint part) { var packet = new MabiPacket(Op.SkillComplete, creature.Id); packet.PutShort((ushort)skillId); packet.PutInt(part); client.Send(packet); }
/// <summary> /// Sends ConvertGpR to creature's client. /// </summary> public static void ConvertGpR(MabiCreature creature, bool success, uint amount) { var packet = new MabiPacket(Op.ConvertGpR, creature.Id); packet.PutByte(success); packet.PutInt(amount); creature.Client.Send(packet); }
/// <summary> /// Sends response to accept gift. Response will be negative if gift is null. /// </summary> /// <param name="client"></param> /// <param name="gift"></param> public static void AcceptGiftResponse(LoginClient client, Gift gift) { var packet = new MabiPacket(Op.AcceptGiftR, Id.Login); if (gift != null) { packet.PutByte(true); packet.PutByte(gift.IsCharacter); packet.PutInt(0); // ? packet.PutInt(0); // ? packet.PutInt(gift.Type); // ? } else { packet.PutByte(false); } client.Send(packet); }
public static MabiPacket AcquireItem(MabiCreature creature, ulong itemId) { var p = new MabiPacket(Op.AcquireInfo, creature.Id); p.PutString("<xml type='item' objectid='{0}'/>", itemId); p.PutInt(3000); // 001 [................] String : <xml type='stamina' value='17' simple='true' onlyLog='false' /> // 002 [........00000BB8] Int : 3000 return p; }
/// <summary> /// Sends info on guild membership status changed. Pass null for guild to remove. /// </summary> /// <param name="guild"></param> /// <param name="creature"></param> /// <returns></returns> public static MabiPacket GuildMembershipChanged(MabiGuild guild, MabiCreature creature, GuildMemberRank rank = GuildMemberRank.Member) { var p = new MabiPacket(Op.GuildMembershipChanged, creature.Id); if (guild == null) { p.PutInt(0); } else { p.PutInt(1); p.PutString(guild.Name); p.PutLong(guild.Id); p.PutInt((uint)rank); // (5) Member Rank? p.PutByte(0); } return p; }
public void AddMemberPacket(MabiPacket packet, MabiCreature member) { if (!Members.Contains(member)) return; packet.PutInt(this.GetMemberNumber(member)); packet.PutLong(member.Id); packet.PutString(member.Name); packet.PutByte(1); // ? packet.PutInt(member.Region); MabiVertex loc = member.GetPosition(); packet.PutInt(loc.X); packet.PutInt(loc.Y); packet.PutByte(0); // ? packet.PutInt((uint)((member.Life * 100) / member.LifeMax)); packet.PutInt((uint)member.LifeMax); packet.PutLong(0); // ? }
/// <summary> /// Broadcasts Phoenix Feather above dead creature effect in creature's range. /// </summary> /// <param name="client"></param> /// <param name="creature"></param> public static void DeadFeather(MabiCreature creature, DeadMenuOptions options) { var bits = (uint)options; var flags = new List<uint>(); // Break down options bit by bit, and add them to flags if set. for (uint i = 1; bits != 0; ++i, bits >>= 1) { if ((bits & 1) != 0) flags.Add(i); } var packet = new MabiPacket(Op.DeadFeather, creature.Id); packet.PutShort((ushort)flags.Count); foreach (var f in flags) packet.PutInt(f); packet.PutByte(0); WorldManager.Instance.Broadcast(packet, SendTargets.Range, creature); }
public static void OpenNPCShop(WorldClient client, MabiShop shop) { var packet = new MabiPacket(Op.OpenNPCShop, client.Character.Id); packet.PutString("shopname"); packet.PutByte(0); packet.PutByte(0); packet.PutInt(0); packet.PutByte((byte)shop.Tabs.Count); for (var i = 0; i < shop.Tabs.Count; ++i) { packet.PutString("[{0}]{1}", i, shop.Tabs[i].Name); // [160200] ? { packet.PutByte(0); } packet.PutShort((ushort)shop.Tabs[i].Items.Count); foreach (var item in shop.Tabs[i].Items) packet.AddItemInfo(item, ItemPacketType.Private); } client.Send(packet); }
/// <summary> /// Sends view equipment to client. Response is negative if items is null. /// </summary> /// <param name="client"></param> /// <param name="targetId"></param> /// <param name="items"></param> public static void ViewEquipmentResponse(WorldClient client, ulong targetId, IEnumerable<MabiItem> items) { var packet = new MabiPacket(Op.ViewEquipmentR, client.Character.Id); if (items != null) { packet.PutByte(true); packet.PutLong(targetId); packet.PutInt((ushort)items.Count()); foreach (var item in items) packet.AddItemInfo(item, ItemPacketType.Private); } else { packet.PutByte(false); } client.Send(packet); }
public static void UnreadMailCount(Client client, MabiCreature creature, uint count) { var packet = new MabiPacket(Op.UnreadMailCount, creature.Id); packet.PutInt(count); client.Send(packet); }
public static void EntitiesAppear(Client client, IEnumerable<MabiEntity> entities) { var packet = new MabiPacket(Op.EntitiesAppear, Id.Broadcast); packet.PutShort((ushort)entities.Count()); foreach (var entity in entities) { var data = new MabiPacket(0, 0); data.AddPublicEntityInfo(entity); var dataBytes = data.Build(false); packet.PutShort(entity.DataType); packet.PutInt((uint)dataBytes.Length); packet.PutBin(dataBytes); } client.Send(packet); }
// tmp public static MabiPacket StatRegenStop(MabiCreature creature, StatUpdateType type, params MabiStatRegen[] stats) { var packet = new MabiPacket((type & StatUpdateType.Public) != 0 ? Op.StatUpdatePublic : Op.StatUpdatePrivate, creature.Id); packet.PutByte((byte)type); packet.PutSInt(0); // Stats packet.PutInt(0); // Regens // Stat mod ids to remove packet.PutSInt(stats.Count()); foreach (var mod in stats) packet.PutInt(mod.ModId); packet.PutInt(0); if (type == StatUpdateType.Public) { packet.PutInt(0); // Stat mod ids to remove packet.PutSInt(stats.Count()); foreach (var mod in stats) packet.PutInt(mod.ModId); packet.PutInt(0); } return packet; }
public static MabiPacket StatUpdate(MabiCreature creature, StatUpdateType type, params Stat[] stats) { var packet = new MabiPacket((type & StatUpdateType.Public) != 0 ? Op.StatUpdatePublic : Op.StatUpdatePrivate, creature.Id); packet.PutByte((byte)type); // Stats packet.PutSInt(stats.Length); foreach (var stat in stats) { packet.PutInt((uint)stat); switch (stat) { case Stat.Height: packet.PutFloat(creature.Height); break; case Stat.Weight: packet.PutFloat(creature.Weight); break; case Stat.Upper: packet.PutFloat(creature.Upper); break; case Stat.Lower: packet.PutFloat(creature.Lower); break; case Stat.CombatPower: packet.PutFloat(creature.CombatPower); break; case Stat.Level: packet.PutShort(creature.Level); break; case Stat.AbilityPoints: packet.PutShort(creature.AbilityPoints); break; case Stat.Experience: packet.PutLong(MabiData.ExpDb.CalculateRemaining(creature.Level, creature.Experience) * 1000); break; case Stat.Life: packet.PutFloat(creature.Life); break; case Stat.LifeMax: packet.PutFloat(creature.LifeMaxBaseTotal); break; case Stat.LifeMaxMod: packet.PutFloat(creature.StatMods.GetMod(Stat.LifeMaxMod)); break; case Stat.LifeInjured: packet.PutFloat(creature.LifeInjured); break; case Stat.Mana: packet.PutFloat(creature.Mana); break; case Stat.ManaMax: packet.PutFloat(creature.ManaMaxBaseTotal); break; case Stat.ManaMaxMod: packet.PutFloat(creature.StatMods.GetMod(Stat.ManaMaxMod)); break; case Stat.Stamina: packet.PutFloat(creature.Stamina); break; case Stat.Food: packet.PutFloat(creature.StaminaHunger); break; case Stat.StaminaMax: packet.PutFloat(creature.StaminaMaxBaseTotal); break; case Stat.StaminaMaxMod: packet.PutFloat(creature.StatMods.GetMod(Stat.StaminaMaxMod)); break; case Stat.StrMod: packet.PutFloat(creature.StatMods.GetMod(Stat.StrMod)); break; case Stat.DexMod: packet.PutFloat(creature.StatMods.GetMod(Stat.DexMod)); break; case Stat.IntMod: packet.PutFloat(creature.StatMods.GetMod(Stat.IntMod)); break; case Stat.LuckMod: packet.PutFloat(creature.StatMods.GetMod(Stat.LuckMod)); break; case Stat.WillMod: packet.PutFloat(creature.StatMods.GetMod(Stat.WillMod)); break; case Stat.Str: packet.PutFloat(creature.StrBaseTotal); break; case Stat.Int: packet.PutFloat(creature.IntBaseTotal); break; case Stat.Dex: packet.PutFloat(creature.DexBaseTotal); break; case Stat.Will: packet.PutFloat(creature.WillBaseTotal); break; case Stat.Luck: packet.PutFloat(creature.LuckBaseTotal); break; case Stat.DefenseBaseMod: packet.PutShort((ushort)creature.DefensePassive); break; case Stat.ProtectBaseMod: packet.PutFloat(creature.ProtectionPassive * 100); break; case Stat.DefenseMod: packet.PutShort((ushort)creature.StatMods.GetMod(Stat.DefenseMod)); break; case Stat.ProtectMod: packet.PutFloat(creature.StatMods.GetMod(Stat.ProtectMod)); break; // Client might crash with a mismatching value, // take a chance and put an int by default. default: packet.PutInt(1); break; } } // (New?) Stat regens packet.PutSInt(creature.StatRegens.Count); foreach (var mod in creature.StatRegens) mod.AddToPacket(packet); // Stat mod ids to remove? packet.PutInt(0); packet.PutInt(0); // ? if (type == StatUpdateType.Public) { packet.PutInt(0); // ? // Stat mod ids to remove? packet.PutInt(0); packet.PutInt(0); // ? } return packet; }
public override SkillResults Prepare(MabiCreature creature, MabiSkill skill, MabiPacket packet, uint castTime) { var rnd = RandomProvider.Get(); // Check for instrument if (creature.RightHand == null || creature.RightHand.Type != ItemType.Instrument) return SkillResults.Failure; // Spawn chair for Cello if (creature.RightHand.DataInfo.Instrument == InstrumentType.Cello) { var pos = creature.GetPosition(); // Chair prop var prop = new MabiProp((!creature.IsGiant ? CelloChair : GiantCelloChair), creature.Region, pos.X, pos.Y, MabiMath.DirToRad(creature.Direction)); prop.State = "stand"; WorldManager.Instance.AddProp(prop); // Move char Send.AssignChair(creature, prop.Id, 1); // Update chair prop.ExtraData = string.Format("<xml OWNER='{0}' SITCHAR='{0}'/>", creature.Id); Send.PropUpdate(prop); creature.Temp.SittingProp = prop; } // Score scrolls go into the magazine pocket and need a SCORE tag. // XXX: Is it possbile to play random with a low durability scroll? bool hasScroll = (creature.Magazine != null && creature.Magazine.Tags.Has("SCORE") && creature.Magazine.OptionInfo.Durability >= DurabilityUse); // Random score if no usable scroll was found. uint rndScore = (!hasScroll ? (uint)rnd.Next(RandomScoreMin, RandomScoreMax + 1) : 0); // Quality seems to go from 0 (worst) to 3 (best). // Should be generated based on skills + random. var quality = (PlayingQuality)rnd.Next((int)PlayingQuality.VeryBad, (int)PlayingQuality.VeryGood + 1); // Up quality by chance, based on Musical Knowledge var knowledge = creature.Skills.Get(SkillConst.MusicalKnowledge); if (knowledge != null && rnd.Next(0, 100) < knowledge.RankInfo.Var2) quality++; if (quality > PlayingQuality.VeryGood) quality = PlayingQuality.VeryGood; // Save quality before checking perfect play option, // we want proper skill training. creature.Temp.PlayingInstrumentQuality = quality; if (WorldConf.PerfectPlay) { quality = PlayingQuality.VeryGood; Send.ServerMessage(creature.Client, creature, Localization.Get("skills.perfect_play")); // Regardless of the result, perfect play will let your performance sound perfect. } // Reduce scroll's durability. if (hasScroll) { creature.Magazine.ReduceDurability(DurabilityUse); creature.Client.Send( new MabiPacket(Op.ItemDurabilityUpdate, creature.Id) .PutLong(creature.Magazine.Id) .PutInt(creature.Magazine.OptionInfo.Durability) ); } // Music effect { var effect = hasScroll ? PacketCreator.PlayEffect(creature, creature.RightHand.DataInfo.Instrument, quality, creature.Magazine.Tags["SCORE"]) : PacketCreator.PlayEffect(creature, creature.RightHand.DataInfo.Instrument, quality, rndScore); WorldManager.Instance.Broadcast(effect, SendTargets.Range, creature); } // Use skill { var use = new MabiPacket(Op.SkillUse, creature.Id); use.PutShort(skill.Info.Id); use.PutLong(0); use.PutByte(hasScroll); if (!hasScroll) use.PutInt(rndScore); else use.PutString(creature.Magazine.Tags["SCORE"]); use.PutByte((byte)creature.RightHand.DataInfo.Instrument); use.PutByte(1); use.PutByte(0); creature.Client.Send(use); creature.ActiveSkillId = skill.Id; } // Change motion for Battle Mandolin (no idea if this official, but I like it =P) [exec] //if (creature.RightHand.Info.Class == 40367) // WorldManager.Instance.CreatureUseMotion(creature, 88, 2, true); return SkillResults.Okay; }
/// <summary> /// Playing instrument effect (sound and motion) for creature, /// based on the given score id (client:score.xml). /// </summary> /// <param name="creature"></param> /// <param name="instrument"></param> /// <param name="quality"></param> /// <param name="score"></param> /// <returns></returns> public static MabiPacket PlayEffect(MabiCreature creature, InstrumentType instrument, PlayingQuality quality, uint score) { var p = new MabiPacket(Op.Effect, creature.Id); p.PutInt(Effect.PlayMusic); p.PutByte(false); p.PutInt(score); p.PutInt(0); p.PutShort(0); p.PutInt(14113); p.PutByte((byte)quality); p.PutByte((byte)instrument); p.PutByte(0); p.PutByte(0); p.PutByte(1); return p; }
public static void UseItemResponse(Client client, MabiCreature creature, bool success, uint itemClass) { var packet = new MabiPacket(Op.UseItemR, creature.Id); packet.PutByte(success); if (success) packet.PutInt(itemClass); client.Send(packet); }
private CommandResult Command_effect(WorldClient client, MabiCreature creature, string[] args, string msg) { if (args.Length < 2) return CommandResult.WrongParameter; var p = new MabiPacket(Op.Effect, creature.Id); uint id; if (!uint.TryParse(args[1], out id)) return CommandResult.WrongParameter; p.PutInt(id); for (int i = 2; i < args.Length; ++i) { var splitted = args[i].Split(':'); if (splitted[0] == "me") { p.PutLong(creature.Id); continue; } if (splitted.Length < 2) continue; splitted[0] = splitted[0].Trim(); splitted[1] = splitted[1].Trim(); switch (splitted[0]) { case "b": { byte val; if (!byte.TryParse(splitted[1], out val)) return CommandResult.WrongParameter; p.PutByte(val); break; } case "i": { uint val; if (!uint.TryParse(splitted[1], out val)) return CommandResult.WrongParameter; p.PutInt(val); break; } case "s": { p.PutString(splitted[1]); break; } } } WorldManager.Instance.Broadcast(p, SendTargets.Range, creature); return CommandResult.Okay; }
/// <summary> /// Broadcasts current conditions of creature. /// </summary> /// <param name="wm"></param> /// <param name="creature"></param> public static void StatusEffectUpdate(MabiCreature creature) { var packet = new MabiPacket(Op.StatusEffectUpdate, creature.Id); packet.PutLong((ulong)creature.Conditions.A); packet.PutLong((ulong)creature.Conditions.B); packet.PutLong((ulong)creature.Conditions.C); // [150100] New conditions list { packet.PutLong((ulong)creature.Conditions.D); } packet.PutInt(0); WorldManager.Instance.Broadcast(packet, SendTargets.Range, creature); }
public void AddPartyPacket(MabiPacket packet) { packet.PutLong(_id); // Party ID packet.PutString(Name); packet.PutLong(Leader.Id); packet.PutByte(IsOpen); packet.PutInt((uint)Finish); packet.PutInt((uint)ExpShare); packet.PutLong(0); // Quest ID? packet.PutInt(MaxSize); packet.PutInt(Type); packet.PutString(Level); packet.PutString(Info); packet.PutInt((uint)Members.Count); foreach (var member in Members) AddMemberPacket(packet, member); packet.PutByte(0); }
/// <summary> /// Sends enter region permission, which kinda makes the client warp. /// </summary> /// <param name="client"></param> /// <param name="creature"></param> /// <param name="permission"></param> public static void EnterRegionPermission(WorldClient client, MabiCreature creature, bool permission = true) { var pos = creature.GetPosition(); var p = new MabiPacket(Op.EnterRegionPermission, Id.World); p.PutLong(creature.Id); p.PutByte(permission); if (permission) { p.PutInt(creature.Region); p.PutInt(pos.X); p.PutInt(pos.Y); } client.Send(p); }
public static void CutsceneStart(WorldClient client, MabiCutscene cutscene) { var p = new MabiPacket(Op.CutsceneStart, Id.World); p.PutLongs(client.Character.Id, cutscene.Leader.Id); p.PutString(cutscene.Name); p.PutSInt(cutscene.Actors.Count); foreach (var a in cutscene.Actors) { p.PutString(a.Item1); p.PutShort((ushort)a.Item2.Length); p.PutBin(a.Item2); } p.PutInt(1); p.PutLong(client.Character.Id); client.Send(p); }
/// <summary> /// Sends unlock for creature. /// </summary> /// <param name="client"></param> /// <param name="creature"></param> /// <param name="lockType"></param> public static void CharacterUnlock(WorldClient client, MabiCreature creature, uint lockType = 0xEFFFFFFE) { var p = new MabiPacket(Op.CharacterUnlock, creature.Id); p.PutInt(lockType); client.Send(p); }
/// <summary> /// Sends revive notice to creature's client. /// </summary> /// <param name="creature"></param> public static void Revived(MabiCreature creature) { var pos = creature.GetPosition(); var packet = new MabiPacket(Op.Revived, creature.Id); packet.PutInt(1); packet.PutInt(creature.Region); packet.PutInt(pos.X); packet.PutInt(pos.Y); creature.Client.Send(packet); }
/// <summary> /// Playing instrument effect (sound and motion) for creature, /// based on the given MML code. /// </summary> /// <param name="creature"></param> /// <param name="instrument"></param> /// <param name="quality"></param> /// <param name="compressedMML"></param> /// <returns></returns> public static MabiPacket PlayEffect(MabiCreature creature, InstrumentType instrument, PlayingQuality quality, string compressedMML) { var p = new MabiPacket(Op.Effect, creature.Id); p.PutInt(Effect.PlayMusic); p.PutByte(true); // has scroll p.PutString(compressedMML); p.PutInt(0); p.PutShort(0); p.PutInt(14113); // ? p.PutByte((byte)quality); p.PutByte((byte)instrument); p.PutByte(0); p.PutByte(0); p.PutByte(1); // loops return p; }