/// <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); }
protected QuestObjectiveInfo ReachRank(SkillConst skillId, SkillRank rank) { var result = new QuestObjectiveInfo(); result.Type = ObjectiveType.ReachRank; result.Id = (uint)skillId; result.Amount = (uint)rank; return result; }
protected QuestRewardInfo Skill(SkillConst skillId, SkillRank rank) { var result = new QuestRewardInfo(); result.Type = RewardType.Skill; result.Id = (uint)skillId; result.Amount = (uint)rank; return result; }
public void AddTargetAction(MabiCreature target, CombatActionType targetType, MabiCreature attacker = null, SkillConst skillId = SkillConst.None) { var tAction = new TargetAction(targetType, target, attacker == null ? this.AttackerAction.Creature : attacker, skillId == SkillConst.None ? this.AttackerAction.SkillId : skillId); this.TargetActions.Add(tAction); this.CurrentTargetAction = tAction; }
/// <summary> /// Tries to get MabiSkill and SkillHandler based on creature /// and skillId. Prints warnings automatically, and returns both /// values (or null) via out parameter. /// </summary> /// <param name="creature"></param> /// <param name="skillId"></param> /// <param name="skill"></param> /// <param name="handler"></param> public static void CheckOutSkill(MabiCreature creature, SkillConst skillId, out MabiSkill skill, out SkillHandler handler) { skill = creature.Skills.Get(skillId); if (skill == null) { Logger.Warning("'{0}' tried to use skill '{1}' without having it.", creature.Name, skillId); } handler = SkillManager.GetHandler(skillId); if (handler == null) { Logger.Unimplemented("Skill handler for '{0}'.", skillId); Send.SystemMessage(creature.Client, creature, Localization.Get("aura.unimplemented_skill")); // Partially unimplemented skill. } }
public SkillResults CompleteRegular(MabiCreature creature, MabiPacket packet, SkillConst skillId, uint part) { var x = packet.GetShort(); var y = packet.GetShort(); // Map for the selected slot byte map = creature.Temp.SkillItem1.DataInfo.ColorMap1; if (part == 1) map = creature.Temp.SkillItem1.DataInfo.ColorMap2; else if (part == 2) map = creature.Temp.SkillItem1.DataInfo.ColorMap3; // Imaginary index for the map switch (map) { default: case 1: map = 0xE0; break; // Cloth case 2: map = 0xE1; break; // Leather case 5: map = 0xE2; break; // Metal case 23: map = 0xE3; break; // Weapon case 24: map = 0xE4; break; // Hilt } // Random color from the available ones var rndNr = (byte)RandomProvider.Get().Next(5); x = (ushort)((x + creature.Temp.DyeCursors[rndNr * 4 + 0] - creature.Temp.DyeCursors[rndNr * 4 + 1]) & 0xFF); y = (ushort)((y + creature.Temp.DyeCursors[rndNr * 4 + 2] - creature.Temp.DyeCursors[rndNr * 4 + 3]) & 0xFF); rndNr += 1; // Change color var color = MabiData.ColorMapDb.GetAt(map, x -= 1, y -= 1); switch (part) { default: case 0: creature.Temp.SkillItem1.Info.ColorA = color; break; case 1: creature.Temp.SkillItem1.Info.ColorB = color; break; case 2: creature.Temp.SkillItem1.Info.ColorC = color; break; } this.DyeSuccess(creature); Send.AcquireDyedItem(creature.Client, creature, creature.Temp.SkillItem1.Id, rndNr); Send.DyeSkillComplete(creature.Client, creature, skillId, part, x, y); return SkillResults.Okay; }
public SkillResults CompleteFixed(MabiCreature creature, MabiPacket packet, SkillConst skillId, uint part) { // Older logs seem to have an additional byte (like Use?) //var unk = packet.GetByte(); switch (part) { default: case 0: creature.Temp.SkillItem1.Info.ColorA = creature.Temp.SkillItem2.Info.ColorA; break; case 1: creature.Temp.SkillItem1.Info.ColorB = creature.Temp.SkillItem2.Info.ColorA; break; case 2: creature.Temp.SkillItem1.Info.ColorC = creature.Temp.SkillItem2.Info.ColorA; break; } this.DyeSuccess(creature); Send.AcquireDyedItem(creature.Client, creature, creature.Temp.SkillItem1.Id); Send.DyeSkillComplete(creature.Client, creature, skillId, part); return SkillResults.Okay; }
/// <summary> /// Sends SkillStop to creature's client. /// </summary> /// <param name="creature"></param> /// <param name="skillId"></param> /// <param name="parameter"></param> public static void SkillStop(MabiCreature creature, SkillConst skillId, string parameter) { var packet = new MabiPacket(Op.SkillStop, creature.Id); packet.PutShort((ushort)skillId); packet.PutString(parameter); creature.Client.Send(packet); }
public Skill(SkillConst id, SkillRank rank = SkillRank.Novice) { this.Id = (ushort)id; this.Rank = (byte)rank; }
public MabiSkill(SkillConst skill, SkillRank rank = SkillRank.Novice, uint race = 10001) : this((ushort)skill, (byte)rank, race) { }
/// <summary> /// Updates the stack amount (how many uses left). /// </summary> /// <param name="creature"></param> /// <param name="skillId"></param> /// <param name="remaining"></param> /// <param name="max"></param> public static void SkillStackUpdate(Client client, MabiCreature creature, SkillConst skillId, byte remaining) { var packet = new MabiPacket(Op.SkillStackUpdate, creature.Id); packet.PutBytes(remaining, 1, 0); packet.PutShort((ushort)skillId); client.Send(packet); }
/// <summary> /// Returns true if the skill exists in this manager. /// </summary> /// <param name="skillId"></param> /// <returns></returns> public bool Has(SkillConst skillId) { return this.List.ContainsKey(skillId); }
/// <summary> /// Skill use with a delay? /// </summary> /// <param name="client"></param> /// <param name="creature"></param> /// <param name="skillId"></param> /// <param name="ms"></param> /// <param name="unk"></param> public static void SkillUse(Client client, MabiCreature creature, SkillConst skillId, uint ms, uint unk) { var packet = new MabiPacket(Op.SkillUse, creature.Id); packet.PutShort((ushort)skillId); packet.PutInts(ms, unk); client.Send(packet); }
private void SharpMind(MabiCreature user, SharpMindStatus state, SkillConst skill) { var inRange = WorldManager.Instance.GetPlayersInRange(user, WorldConf.SightRange); foreach (var creature in inRange) { creature.Client.Send(PacketCreator.SharpMind(user, creature, skill, state)); } }
public void UpdateExp(SkillConst skill, SkillRank rank, bool notifyRankUp = false) { var mask = (byte)this.GetRaceMask(); var exps = MabiData.TalentExpDb.Entries.Where(a => a.SkillId == (ushort)skill && a.SkillRank <= (byte)rank && (a.Race & mask) != 0); if (exps == null) return; var info = exps.FirstOrDefault(a => a.SkillRank == (ushort)rank); if (info == null) return; foreach (var talent in info.Exps.Keys) { uint exp = (uint)exps.Sum(a => a.Exps[talent]); if (!this.ExpList.ContainsKey((TalentId)talent)) this.ExpList.Add((TalentId)talent, new Dictionary<SkillConst, uint>()); var expInfo = this.ExpList[(TalentId)talent]; if (!expInfo.ContainsKey(skill)) expInfo.Add(skill, 0); expInfo[skill] = exp; if (notifyRankUp) this.SendUpdate(); } }
public TargetAction(CombatActionType type, MabiCreature creature, MabiCreature attacker, SkillConst skillId) { this.Type = type; this.Creature = creature; this.Attacker = attacker; this.SkillId = skillId; }
public CombatActionPack(MabiCreature attacker, SkillConst skillId) : this() { this.Attacker = attacker; this.SkillId = skillId; }
public AttackerAction(CombatActionType type, MabiCreature creature, SkillConst skillId, ulong targetId) { this.Type = type; this.Creature = creature; this.SkillId = skillId; this.TargetId = targetId; }
public static void SkillUse(Client client, MabiCreature creature, SkillConst skillId, ulong targetId) { var packet = new MabiPacket(Op.SkillUse, creature.Id); packet.PutShort((ushort)skillId); packet.PutLong(targetId); client.Send(packet); }
/// <summary> /// Fixed dye use complete. /// </summary> /// <param name="client"></param> /// <param name="creature"></param> /// <param name="skillId"></param> /// <param name="part"></param> /// <param name="unk"></param> public static void SkillUseDye(Client client, MabiCreature creature, SkillConst skillId, uint part, byte unk) { var packet = new MabiPacket(Op.SkillUse, creature.Id); packet.PutShort((ushort)skillId); packet.PutInt(part); packet.PutByte(unk); client.Send(packet); }
/// <summary> /// Returns skill or null. /// </summary> /// <param name="skillId"></param> /// <returns></returns> public MabiSkill Get(SkillConst skillId) { MabiSkill skill; this.List.TryGetValue(skillId, out skill); return skill; }
public static void SkillUse(Client client, MabiCreature creature, SkillConst skillId, ulong targetId, uint unk1, uint unk2) { var packet = new MabiPacket(Op.SkillUse, creature.Id); packet.PutShort((ushort)skillId); if (skillId != SkillConst.None) { packet.PutLong(targetId); packet.PutInt(unk1); packet.PutInt(unk2); } client.Send(packet); }
protected IEnumerable PrepareSkill(SkillConst skillId, bool wait, MabiPacket args) { MabiSkill skill; SkillHandler handler; SkillManager.CheckOutSkill(this.Creature, skillId, out skill, out handler); if (this.Creature.ActiveSkillId != 0) foreach (var a in CancelSkill()) yield return a; this.Creature.ActiveSkillId = skill.Id; // Save cast time when preparation is finished. var castTime = skill.RankInfo.LoadTime; this.Creature.ActiveSkillPrepareEnd = DateTime.Now.AddMilliseconds(castTime); var r = handler.Prepare(this.Creature, skill, args, castTime); if ((r & SkillResults.Okay) == 0) yield return false; this.SharpMind(this.Creature, SharpMindStatus.Loading, skillId); System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(() => { System.Threading.Thread.Sleep((int)castTime); if (Creature.ActiveSkillId == skill.Id) { handler.Ready(this.Creature, skill); this.SharpMind(this.Creature, SharpMindStatus.Loaded, skillId); } })); t.Start(); yield return true; if (wait) foreach (var a in Wait(GetBeats((int)castTime))) yield return a; }
public static SkillHandler GetHandler(SkillConst skill) { return (_handlers.ContainsKey(skill) ? _handlers[skill] : null); }
public static MabiPacket SharpMind(MabiCreature user, MabiCreature target, SkillConst skillId, SharpMindStatus state) { return new MabiPacket(Op.SharpMind, target.Id) .PutLong(user.Id) .PutByte(1) .PutByte(1) .PutShort((ushort)skillId) .PutInt((uint)state); }
public void HandleCreatureKill(MabiCreature creature, MabiCreature killer, MabiVertex position, SkillConst skillId) { if (killer != null) { // Shadow Bunshin soul counter if (skillId != SkillConst.ShadowBunshin) killer.SoulCount++; // Exp if (killer.LevelingEnabled) { // Give exp var exp = creature.BattleExp * WorldConf.ExpRate; killer.GiveExp((ulong)exp); Send.CombatMessage(killer.Client, killer, "+{0} EXP", exp); EventManager.CreatureEvents.OnCreatureKilled(creature, killer); if (killer is MabiPC) EventManager.PlayerEvents.OnKilledByPlayer(creature, killer); } } var npc = creature as MabiNPC; if (npc != null) { var rnd = RandomProvider.Get(); // Gold if (rnd.NextDouble() < WorldConf.GoldDropRate) { var amount = rnd.Next(npc.GoldMin, npc.GoldMax + 1); if (amount > 0) { var gold = new MabiItem(2000); gold.Info.Amount = (ushort)amount; gold.Info.Region = npc.Region; gold.Info.X = (uint)(position.X + rnd.Next(-50, 51)); gold.Info.Y = (uint)(position.Y + rnd.Next(-50, 51)); gold.DisappearTime = DateTime.Now.AddSeconds(60); this.AddItem(gold); } } // Drops foreach (var drop in npc.Drops) { if (rnd.NextDouble() < drop.Chance * WorldConf.DropRate) { var item = new MabiItem(drop.ItemId); item.Info.Amount = 1; item.Info.Region = npc.Region; item.Info.X = (uint)(position.X + rnd.Next(-50, 51)); item.Info.Y = (uint)(position.Y + rnd.Next(-50, 51)); item.DisappearTime = DateTime.Now.AddSeconds(60); this.AddItem(item); } } } // Set finisher? WorldManager.Instance.Broadcast(new MabiPacket(Op.CombatSetFinisher, creature.Id).PutLong(killer.Id), SendTargets.Range, creature); // Clear target Send.CombatTargetSet(killer, null); // Finish this finisher part? WorldManager.Instance.Broadcast(new MabiPacket(Op.CombatSetFinisher2, creature.Id), SendTargets.Range, creature); // TODO: There appears to be something missing to let it lay there for finish, if we don't kill it with the following packets. // TODO: Check for finishing. // Make it dead WorldManager.Instance.Broadcast(new MabiPacket(Op.IsNowDead, creature.Id), SendTargets.Range, creature); // Remove finisher? WorldManager.Instance.Broadcast(new MabiPacket(Op.CombatSetFinisher, creature.Id).PutLong(0), SendTargets.Range, creature); if (creature.ActiveSkillId != SkillConst.None) creature.CancelSkill(); if (creature.Owner != null) { Send.DeadFeather(creature, DeadMenuOptions.Here | DeadMenuOptions.FeatherUp); // TODO: Unmount. } creature.CauseOfDeath = DeathCauses.None; if (creature.ArenaPvPManager != null && creature.ArenaPvPManager == killer.ArenaPvPManager && creature.ArenaPvPManager.IsAttackableBy(creature, killer)) { creature.ArenaPvPManager.CreatureKilled(creature, killer); creature.CauseOfDeath = DeathCauses.Arena; } // TODO: Trans PvP if (creature.CauseOfDeath == DeathCauses.None && creature.EvGEnabled && killer.EvGEnabled) if (creature.EvGSupportRace != 0 && killer.EvGSupportRace != 0 && creature.EvGSupportRace != killer.EvGSupportRace) creature.CauseOfDeath = DeathCauses.EvG; if (creature.CauseOfDeath == DeathCauses.None) creature.CauseOfDeath = DeathCauses.Mob; }
/// <summary> /// Gives skills, or updates it. Updates bonuses and talent exp. /// </summary> /// <param name="skillId"></param> /// <param name="rank"></param> /// <param name="flash"></param> public void Give(SkillConst skillId, SkillRank rank, bool flash = true) { var skill = this.Get(skillId); if (skill == null) { this.Add(skill = new MabiSkill(skillId, rank, _creature.Race)); Send.SkillInfo(_creature.Client, _creature, skill); if (flash) Send.RankUp(_creature); EventManager.CreatureEvents.OnCreatureSkillChange(_creature, skill, true); } else { this.RemoveSkillBonuses(skill); skill.Info.Experience = 0; skill.Info.Rank = (byte)rank; skill.LoadRankInfo(); Send.SkillRankUp(_creature.Client, _creature, skill); if (flash) Send.RankUp(_creature, skill.Info.Id); EventManager.CreatureEvents.OnCreatureSkillChange(_creature, skill, false); } this.AddBonuses(skill); _creature.Talents.UpdateExp(skillId, rank, true); }
public bool HasSkillLoaded(SkillConst skill) { return this.ActiveSkillId == skill; }
/// <summary> /// Returns true if the skill is there and its rank exceeds rank. /// </summary> /// <param name="skillId"></param> /// <param name="rank"></param> /// <returns></returns> public bool Has(SkillConst skillId, SkillRank rank) { var skill = this.Get(skillId); return (skill != null && skill.Rank >= rank); }
/// <summary> /// Cancels active skill. /// Sends: SkillStackUpdate, SkillCancel /// </summary> public void CancelSkill() { if (this.ActiveSkillId != SkillConst.None) { MabiSkill skill; SkillHandler handler; SkillManager.CheckOutSkill(this, this.ActiveSkillId, out skill, out handler); if (skill == null || handler == null) return; var result = handler.Cancel(this, skill); if ((result & SkillResults.Okay) == 0) return; Send.SkillStackUpdate(this.Client, this, skill.Id, 0); Send.SkillCancel(this.Client, this); } this.ActiveSkillId = SkillConst.None; this.ActiveSkillStacks = 0; }