private static AttackInfo CreateAttackInfo(PacketReader pr, byte attackByte, int targets, int attacks, int skillId, byte skillLevel, int charge, byte speed, short display, int fixedDamage, BuffedCharacterStats stats, double skillDamage) { AttackInfo attackInfo = new AttackInfo(); attackInfo.AttacksByte = attackByte; attackInfo.Targets = targets; attackInfo.Attacks = attacks; attackInfo.SkillId = skillId; attackInfo.SkillLevel = skillLevel; attackInfo.Charge = charge; attackInfo.Speed = speed; attackInfo.Display = display; for (int i = 0; i < targets; i++) { AttackPair ap = new AttackPair(); ap.TargetObjectId = pr.ReadInt(); pr.Skip(20); for (int j = 0; j < attacks; j++) { int damage = pr.ReadInt(); if (fixedDamage != -1 && fixedDamage != damage) { ServerConsole.Warning("Incorrect fixed damage, damage hack. Probably due to packet or wz editing."); return(null); } ap.Damage.Add(damage); ap.Crits.Add(fixedDamage != -1 ? false : stats.IsCrit(damage, skillDamage)); } pr.Skip(8); attackInfo.TargetDamageList.Add(ap); } attackInfo.Position = pr.ReadPoint(); return(attackInfo); }
public void AttackMonster(int damage, byte speed, MapleMonster monster) { AttackInfo info = new AttackInfo(); info.Attacks = 1; info.Targets = 1; info.AttacksByte = 0x11; info.Speed = speed; AttackPair attackPair = new AttackPair(); attackPair.TargetObjectId = monster.ObjectId; attackPair.Damage = new List <int>() { damage }; info.TargetDamageList = new List <AttackPair>() { attackPair }; Owner.Map.BroadcastPacket(GetAttackPacket(info, true)); monster.Damage(Owner, damage); }
public static void HandleAttack(MapleClient c, PacketReader pr) { int objectId = pr.ReadInt(); MapleCharacter chr = c.Account.Character; MapleSummon summon = chr.Map.GetSummon(objectId); if (summon != null) { if (summon.Owner.Id != chr.Id) { return; } int tickCount = pr.ReadInt(); WzCharacterSkill skillInfo = DataBuffer.GetCharacterSkillById(summon.SourceSkillId); if (skillInfo == null || skillInfo.SummonInfo == null) { return; } WzCharacterSkill.SummonAttackInfo summonAttackInfo = skillInfo.SummonInfo; byte animation = pr.ReadByte(); byte attackByte = pr.ReadByte(); int attacks = (attackByte & 0x0F); int targets = ((attackByte >> 4) & 0x0F); if (summonAttackInfo.MobCount < targets || summonAttackInfo.AttackCount < attacks) { ServerConsole.Warning("Player " + chr.Name + "'s summon: " + summon.SourceSkillId + "has mismatching targets- or attackcount: " + attacks + "/" + summonAttackInfo.AttackCount + " attacks, " + targets + "/" + summonAttackInfo.MobCount + " mobs"); return; } pr.Skip(12); List <AttackPair> attackList = new List <AttackPair>(); for (int i = 0; i < targets; i++) { int targetObjectId = pr.ReadInt(); MapleMonster target = chr.Map.GetMob(targetObjectId); if (target == null) { ServerConsole.Debug("Error parsing summon attack, summon skillId: " + summon.SourceSkillId + " attack byte: " + attackByte); return; } AttackPair ap = new AttackPair(); ap.TargetObjectId = targetObjectId; pr.Skip(24); int damage = pr.ReadInt(); //only supports 1 damage count, not sure if there are summons with attackcount > 1 ap.Damage.Add(damage); attackList.Add(ap); pr.Skip(4); } AttackInfo attackInfo = new AttackInfo(); attackInfo.Attacks = attacks; attackInfo.AttacksByte = attackByte; attackInfo.Speed = animation; attackInfo.Targets = targets; attackInfo.TargetDamageList = attackList; foreach (AttackPair ap in attackList) { MapleMonster mob = chr.Map.GetMob(ap.TargetObjectId); if (mob != null) { long totalDamage = 0; foreach (int i in ap.Damage) { totalDamage += i; } if (totalDamage > int.MaxValue) { totalDamage = int.MaxValue; } mob.Damage(chr, (int)totalDamage); } } bool darkFlare = summon.SourceSkillId == ChiefBandit.DARK_FLARE || summon.SourceSkillId == Hermit.DARK_FLARE || summon.SourceSkillId == NightWalker3.DARK_FLARE; chr.Map.BroadcastPacket(summon.GetAttackPacket(attackInfo, darkFlare)); } }