public static void CombatTargetSet(MabiCreature creature, MabiCreature target) { var packet = new MabiPacket(Op.CombatTargetSet, creature.Id); packet.PutLong(target != null ? target.Id : 0); WorldManager.Instance.Broadcast(packet, SendTargets.Range, creature); }
public virtual void Close(WorldClient client, string message = "<end/>") { var p = new MabiPacket(Op.NPCTalkEndR, client.Character.Id); p.PutByte(1); p.PutLong(client.NPCSession.Target.Id); p.PutString(message); client.Send(p); }
public static void ConfirmMailRecipentResponse(WorldClient client, bool success, ulong recipientId) { var packet = new MabiPacket(Op.ConfirmMailRecipentR, client.Character.Id); packet.PutByte(success); if (success) packet.PutLong(recipientId); client.Send(packet); }
public static void GetMailsResponse(WorldClient client, IEnumerable<MabiMail> mails) { var p = new MabiPacket(Op.GetMailsR, client.Character.Id); foreach (var mail in mails) p.Add(mail); p.PutLong(0); client.Send(p); }
/// <summary> /// Sends ItemAmount to creature's client. /// </summary> /// <param name="creature"></param> /// <param name="item"></param> public static void ItemAmount(MabiCreature creature, MabiItem item) { var packet = new MabiPacket(Op.ItemAmount, creature.Id); packet.PutLong(item.Id); packet.PutShort(item.Info.Amount); packet.PutByte(2); // ? (related to the 2 in move item?) creature.Client.Send(packet); }
public static void NPCTalkStartResponse(WorldClient client, bool success, ulong npcId) { var packet = new MabiPacket(Op.NPCTalkStartR, client.Character.Id); packet.PutByte(success); if (success) packet.PutLong(npcId); client.Send(packet); }
/// <summary> /// Sends positive login response. /// </summary> /// <param name="client"></param> /// <param name="creature"></param> public static void LoginResponse(Client client, MabiCreature creature) { var packet = new MabiPacket(Op.WorldLoginR, Id.World); packet.PutByte(true); packet.PutLong(creature.Id); packet.PutLong(MabiTime.Now.DateTime); packet.PutInt(1); packet.PutString(""); client.Send(packet); }
public static void RecallMailResponse(WorldClient client, bool success, ulong mailId) { var packet = new MabiPacket(Op.RecallMailR, client.Character.Id); packet.PutByte(success); if (success) { packet.PutByte(success); packet.PutLong(mailId); } client.Send(packet); }
public static void NPCTalkPartnerStartResponse(WorldClient client, bool success, ulong id, string partnerName) { var packet = new MabiPacket(Op.NPCTalkPartnerR, client.Character.Id); packet.PutByte(success); if (success) { packet.PutLong(id); packet.PutString(client.Character.Name + "'s " + partnerName); packet.PutString(client.Character.Name + "'s " + partnerName); client.Send(packet); } client.Send(packet); }
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> /// 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); }
/// <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); }
/// <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); }
/// <summary> /// Sends ItemRemove to creature's client. /// </summary> /// <param name="creature"></param> /// <param name="item"></param> public static void ItemRemove(MabiCreature creature, MabiItem item) { var packet = new MabiPacket(Op.ItemRemove, creature.Id); packet.PutLong(item.Id); packet.PutByte(item.Info.Pocket); creature.Client.Send(packet); }
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> /// Character is logged in to a client only region, with one NPC. /// Used for Soul Stream, with Nao ([...]FFF) or Tin ([...]FFE). /// </summary> /// <param name="client"></param> /// <param name="character"></param> public static void SpecialLogin(Client client, MabiPC character, uint region, uint x, uint y, ulong npcId) { var packet = new MabiPacket(Op.SpecialLogin, Id.World); packet.PutByte(true); packet.PutInt(region); packet.PutInt(x); packet.PutInt(y); packet.PutLong(npcId); packet.AddCreatureInfo(character, CreaturePacketType.Private); client.Send(packet); }
/// <summary> /// Sends GuildMessage to creature's client. /// </summary> public static void GuildMessage(MabiCreature creature, MabiGuild guild, string format, params object[] args) { var character = creature as MabiPC; var packet = new MabiPacket(Op.GuildMessage, creature.Id); packet.PutLong(guild.Id); packet.PutString(character == null ? "Aura" : character.Server); packet.PutLong(creature.Id); packet.PutString(guild.Name); packet.PutString(string.Format(format, args)); packet.PutByte(1); packet.PutByte(1); creature.Client.Send(packet); }
public static MabiPacket ItemRemove(MabiCreature creature, MabiItem item) { var p = new MabiPacket(Op.ItemRemove, creature.Id); p.PutLong(item.Id); p.PutByte(item.Info.Pocket); return p; }
public static MabiPacket ItemAmount(MabiCreature creature, MabiItem item) { var p = new MabiPacket(Op.ItemAmount, creature.Id); p.PutLong(item.Id); p.PutShort(item.Info.Amount); p.PutByte(2); return p; }
/// <summary> /// Sends ItemMoveInfo or ItemSwitchInfo to creature's client, /// depending on whether collidingItem is null. /// </summary> /// <param name="creature"></param> /// <param name="item"></param> /// <param name="source"></param> /// <param name="target"></param> /// <param name="collidingItem"></param> public static void ItemMoveInfo(MabiCreature creature, MabiItem item, Pocket source, MabiItem collidingItem) { var packet = new MabiPacket((uint)(collidingItem == null ? Op.ItemMoveInfo : Op.ItemSwitchInfo), creature.Id); packet.PutLong(item.Id); packet.PutByte((byte)source); packet.PutByte(item.Info.Pocket); packet.PutByte(2); packet.PutByte((byte)item.Info.X); packet.PutByte((byte)item.Info.Y); if (collidingItem != null) { packet.PutLong(collidingItem.Id); packet.PutByte(item.Info.Pocket); packet.PutByte(collidingItem.Info.Pocket); packet.PutByte(2); packet.PutByte((byte)collidingItem.Info.X); packet.PutByte((byte)collidingItem.Info.Y); } creature.Client.Send(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> /// 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; }
/// <summary> /// Sends list of disappearing entites to client. /// </summary> /// <param name="client"></param> /// <param name="entities"></param> public static void EntitiesDisappear(Client client, IEnumerable<MabiEntity> entities) { var packet = new MabiPacket(Op.EntitiesDisappear, Id.Broadcast); packet.PutShort((ushort)entities.Count()); foreach (var entity in entities) { packet.PutShort(entity.DataType); packet.PutLong(entity.Id); } client.Send(packet); }
private static MabiPacket GetEntityDisappears(MabiEntity entity) { uint op = Op.EntityDisappears; if (entity is MabiItem) op = Op.ItemDisappears; var packet = new MabiPacket(op, Id.Broadcast); packet.PutLong(entity.Id); packet.PutByte(0); return packet; }
public override SkillResults UseCombat(MabiCreature attacker, ulong targetId, MabiSkill skill) { var itarget = WorldManager.Instance.GetCreatureById(targetId); if (itarget == null) return SkillResults.InvalidTarget; if (!WorldManager.InRange(attacker, itarget, 2000)) return SkillResults.OutOfRange; attacker.StopMove(); WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, attacker.Id).PutInt(Effect.UseMagic).PutString("thunder").PutByte(0).PutLong(targetId).PutShort((ushort)skill.Id), SendTargets.Range, attacker); var charges = attacker.ActiveSkillStacks; List<MabiCreature> targets = new List<MabiCreature>() { itarget }; this.GetThunderChain(attacker, itarget, targets, ((byte)skill.Rank >= (byte)SkillRank.R1 ? 4 : 1) + (charges - 1) * 2); var pos = itarget.GetPosition(); var cloud = new MabiProp(280, itarget.Region, pos.X, pos.Y, 0); WorldManager.Instance.AddProp(cloud); var lbPacket = new MabiPacket(Op.Effect, Id.Broadcast).PutInt(Effect.Lightningbolt).PutLong(attacker.Id).PutInt((uint)targets.Count); foreach (var target in targets) { lbPacket.PutLong(target.Id); } WorldManager.Instance.Broadcast(lbPacket, SendTargets.Range, attacker); Send.SkillUse(attacker.Client, attacker, skill.Id, UseStun, 1); SkillHelper.ClearStack(attacker, skill); // End the lightning balls WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, attacker.Id).PutInt(Effect.StackUpdate).PutString("lightningbolt").PutBytes(0, 0), SendTargets.Range, attacker); var sAction = new AttackerAction(CombatActionType.RangeHit, attacker, skill.Id, targetId); sAction.Options |= AttackerOptions.Result; attacker.Stun = sAction.StunTime = UseStun; var cap = new CombatActionPack(attacker, skill.Id); cap.Add(sAction); var rnd = RandomProvider.Get(); foreach (var target in targets) { var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Id); tAction.Options |= TargetOptions.Result; cap.Add(tAction); var damage = attacker.GetMagicDamage(attacker.RightHand, rnd.Next((int)skill.RankInfo.Var4, (int)skill.RankInfo.Var5 + 1)); if (CombatHelper.TryAddCritical(target, ref damage, attacker.CriticalChanceAgainst(target))) tAction.Options |= TargetOptions.Critical; target.TakeDamage(tAction.Damage = damage); // Knock down if dead if (target.IsDead) { tAction.OldPosition = CombatHelper.KnockBack(target, attacker); tAction.Options |= TargetOptions.FinishingKnockDown; } else { if (target.KnockBack >= CombatHelper.LimitKnockBack) { tAction.Options |= TargetOptions.KnockDown; } else { target.KnockBack += KnockBack; if (target.KnockBack >= CombatHelper.LimitKnockBack) { tAction.OldPosition = CombatHelper.KnockBack(target, attacker); tAction.Options |= TargetOptions.KnockBack; } } target.Stun = tAction.StunTime = (ushort)skill.RankInfo.Var3; CombatHelper.SetAggro(attacker, target); } } WorldManager.Instance.HandleCombatActionPack(cap); SkillHelper.GiveSkillExp(attacker, skill, 20); System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(() => { this.ThunderProcessing(attacker, skill, targets, cloud, DateTime.Now.AddMilliseconds(skill.RankInfo.Var3), charges); })); t.Start(); return SkillResults.Okay; }
public void ThunderProcessing(MabiCreature attacker, MabiSkill skill, List<MabiCreature> targets, MabiProp cloud, DateTime stunEnd, int stack) { var lbPacket = new MabiPacket(Op.Effect, Id.Broadcast).PutInt(Effect.Lightningbolt).PutLong(attacker.Id).PutInt((uint)targets.Count); foreach (var target in targets) { lbPacket.PutLong(target.Id); } while (DateTime.Now < stunEnd) { System.Threading.Thread.Sleep(500); WorldManager.Instance.Broadcast(lbPacket, SendTargets.Range, attacker); } for (int i = 1; i < stack; i++) { HitWithThunderbolt(attacker, skill, targets, cloud); System.Threading.Thread.Sleep(500); } HitWithThunderbolt(attacker, skill, targets, cloud, (stack == 5 ? 2 : 1.5f)); WorldManager.Instance.RemoveProp(cloud); }
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 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); }
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; }
public MabiPacket GetWeatherPacket(uint region, float from, float to, uint transitionTime = Transition) { var p = new MabiPacket(Op.Weather, Id.Broadcast); p.PutByte(0); p.PutInt(region); p.PutByte(2); p.PutByte(0); p.PutByte(1); p.PutString("constant_smooth"); p.PutFloat(to); p.PutLong(DateTime.Now); p.PutLong(DateTime.MinValue); p.PutFloat(from); p.PutFloat(from); p.PutLong(transitionTime); p.PutByte(false); p.PutLong(DateTime.MinValue); p.PutInt(2); p.PutByte(0); return p; }