//!spawnmob [mobId] optional:[mobAmount] public static void SpawnMob(string[] split, MapleClient c) { int mobId = int.Parse(split[1]); WzMob mobInfo = DataBuffer.GetMobById(mobId); if (mobInfo == null) { return; } int amount = 1; if (split.Length > 2) { amount = int.Parse(split[2]); } if (amount > 1) { List <MapleMonster> mobs = new List <MapleMonster>(); for (int i = 0; i < amount; i++) { MapleMonster mob = new MapleMonster(mobInfo, c.Account.Character.Map); mobs.Add(mob); } c.Account.Character.Map.SpawnMobsOnGroundBelow(mobs, new Point(c.Account.Character.Position.X, c.Account.Character.Position.Y - 1)); } else { MapleMonster mob = new MapleMonster(mobInfo, c.Account.Character.Map); c.Account.Character.Map.SpawnMobOnGroundBelow(mob, new Point(c.Account.Character.Position.X, c.Account.Character.Position.Y - 1)); } }
private static void HandlePickPocket(MapleCharacter player, MapleMonster monster, Tuple <int, List <int> > oned) { //金钱炸弹 var pickpocket = SkillFactory.GetSkill(4211003); var delay = 0; var maxmeso = player.GetBuffedValue(MapleBuffStat.Pickpocket); var reqdamage = 20000; var monsterPosition = monster.Position; if (maxmeso == null) { return; } foreach (var eachd in oned.Item2) { if (pickpocket.GetEffect(player.GetSkillLevel(pickpocket)).MakeChanceResult()) { var perc = eachd / (double)reqdamage; var todrop = Math.Min((int)Math.Max(perc * maxmeso.Value, 1), maxmeso.Value); var tdmap = player.Map; var tdpos = new Point((int)(monsterPosition.X + Randomizer.NextDouble() * 100 - 50), monsterPosition.Y); var tdmob = monster; var tdchar = player; TimerManager.Instance.RunOnceTask( () => { tdmap.SpawnMesoDrop(todrop, tdpos, tdmob, tdchar, false); }, delay); delay += 1000; } } }
public MapleMonster SpawnMonster(MapleMap mapleMap) { var mob = new MapleMonster(m_monster) { Position = Pos }; m_spawnedMonsters.Increment(); mob.Listeners.Add((kak, args) => { m_nextPossibleSpawn = DateTime.Now.GetTimeMilliseconds(); if (m_mobTime > 0) { m_nextPossibleSpawn += m_mobTime * 1000; } else { m_nextPossibleSpawn += args.Monster.Stats.GetAnimationTime("die1"); } m_spawnedMonsters.Decrement(); }); mapleMap.SpawnMonster(mob); if (m_mobTime == 0) { m_nextPossibleSpawn = DateTime.Now.GetTimeMilliseconds() + 5000; } return(mob); }
public SpawnPoint(MapleMonster monster, Point pos, int mobTime) { m_monster = monster; Pos = pos; m_mobTime = mobTime; m_immobile = !monster.Stats.IsMobile; m_nextPossibleSpawn = DateTime.Now.GetTimeMilliseconds(); }
public static void Handle(MapleClient c, PacketReader pr) { MapleMonster mob = c.Account.Character.Map.GetMob(pr.ReadInt()); if (mob == null) { return; } mob.ControllerHasAggro = true; }
public static MobAttackInfo GetMobAttackInfo(MapleMonster mob, int attack) { MobAttackInfo ret; var key = Tuple.Create(mob.Id, attack); if (MobAttacks.TryGetValue(key, out ret)) { return(ret); } lock (MobAttacks) { if (!MobAttacks.TryGetValue(key, out ret)) { var mobData = DataSource.GetData((mob.Id + ".img").PadLeft(11, '0')); if (mobData != null) { var linkedmob = MapleDataTool.GetString("link", mobData, ""); if (linkedmob != "") { mobData = DataSource.GetData((linkedmob + ".img").PadLeft(11, '0')); } var attackData = mobData.GetChildByPath($"attack{attack + 1}/info"); if (attackData != null) { var deadlyAttack = attackData.GetChildByPath("deadlyAttack"); var mpBurn = MapleDataTool.GetInt("mpBurn", attackData, 0); var disease = MapleDataTool.GetInt("disease", attackData, 0); var level = MapleDataTool.GetInt("level", attackData, 0); var mpCon = MapleDataTool.GetInt("conMP", attackData, 0); ret = new MobAttackInfo(mob.Id, attack) { IsDeadlyAttack = deadlyAttack != null, MpBurn = mpBurn, DiseaseSkill = (byte)disease, DiseaseLevel = (byte)level, MpCon = mpCon }; } } if (MobAttacks.ContainsKey(key)) { MobAttacks[key] = ret; } else { MobAttacks.Add(key, ret); } } return(ret); } }
public static void updatePosition(List <MapleMovementFragment> movements, MapleMonster mob, int yOffset) { if (movements == null) { return; } for (int i = movements.Count - 1; i >= 0; i--) //loop from the back { if (movements[i] is AbsoluteLifeMovement) { //ServerConsole.Info("Monster position updated :" + Mob.Position + " => " + Move.Position); Point position = movements[i].Position; position.Y += yOffset; mob.Position = position; mob.Stance = movements[i].State; break; } } }
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 void KillTrigger(MapleMonster mob) { Boolean ForceReturn = false; if (FirstMobPoint == null) { FirstMobPoint = mob.Position; ForceReturn = true; } if (KillTracker == 0) { KillCountTracker = 0; KillTracker = DateTime.UtcNow.Ticks / TimeSpan.TicksPerMillisecond; ForceReturn = true; } if (ForceReturn) { return; } TimeSpan Current = TimeSpan.FromMilliseconds(DateTime.UtcNow.Ticks / TimeSpan.TicksPerMillisecond); if ((Current - TimeSpan.FromMilliseconds(KillTracker)).TotalMinutes >= 1) { KillTriggerReset(); return; } if (Functions.Distance((Point)FirstMobPoint, mob.Position) < 5) { KillCountTracker++; } //50 kills on basicly the same position (~4px) if (KillCountTracker > 50) { AddOffence(OffenceType.MobVac); KillTriggerReset(); } }
private static void HandleAttackInfo(MapleClient c, AttackInfo attackInfo, SendHeader type, SkillEffect effect) { //Anti-cheat //c.CheatTracker.Trigger(AntiCheat.TriggerType.Attack); WzCharacterSkill wzSkill = effect != null ? effect.Parent : null; MapleCharacter chr = c.Account.Character; if (attackInfo.SkillId > 0) { if (!SkillEffect.CheckAndApplySkillEffect(c.Account.Character, attackInfo.SkillId, wzSkill, -1, attackInfo.Targets, attackInfo.Attacks)) { return; } } chr.Map.BroadcastPacket(GenerateAttackInfo(type, c.Account.Character, attackInfo), c.Account.Character, false); long totalDamage = 0; #region DoTs and Pickpocket int pickPocketProp = 0; int dotSkillId = 0; int dotChance = 0; int dotDamage = 0; int dotTimeMS = 0; int dotMaxStacks = 1; #region Thief if (chr.IsThief) { byte venomSkillLevel = 0; if (chr.IsBandit) { Buff pickPocket = chr.GetBuff(ChiefBandit.PICKPOCKET); if (pickPocket != null) { pickPocketProp = pickPocket.Effect.Info[CharacterSkillStat.prop]; } venomSkillLevel = chr.GetSkillLevel(ChiefBandit.VENOM); if (venomSkillLevel > 0) { dotSkillId = ChiefBandit.VENOM; byte toxicVenomSkillLevel = chr.GetSkillLevel(Shadower.TOXIC_VENOM); if (toxicVenomSkillLevel > 0) { venomSkillLevel = toxicVenomSkillLevel; dotSkillId = Shadower.TOXIC_VENOM; } } } else if (chr.IsAssassin) { #region Assassin venomSkillLevel = chr.GetSkillLevel(Hermit.VENOM); if (venomSkillLevel > 0) { dotSkillId = Hermit.VENOM; byte toxicVenomSkillLevel = chr.GetSkillLevel(NightLord.TOXIC_VENOM); if (toxicVenomSkillLevel > 0) { venomSkillLevel = toxicVenomSkillLevel; dotSkillId = NightLord.TOXIC_VENOM; } } #endregion } else if (chr.IsDualBlade) { #region DualBlade venomSkillLevel = chr.GetSkillLevel(DualBlade3.VENOM); if (venomSkillLevel > 0) { dotSkillId = DualBlade3.VENOM; byte toxicVenomSkillLevel = chr.GetSkillLevel(DualBlade4.TOXIC_VENOM); if (toxicVenomSkillLevel > 0) { venomSkillLevel = toxicVenomSkillLevel; dotSkillId = DualBlade4.TOXIC_VENOM; } } #endregion } if (venomSkillLevel > 0) { SkillEffect venomEffect = DataBuffer.GetCharacterSkillById(dotSkillId).GetEffect(venomSkillLevel); dotChance = venomEffect.Info[CharacterSkillStat.prop]; dotDamage = (int)(chr.Stats.GetDamage() * (venomEffect.Info[CharacterSkillStat.dot] / 100.0)); dotTimeMS = venomEffect.Info[CharacterSkillStat.dotTime] * 1000; if (!venomEffect.Info.TryGetValue(CharacterSkillStat.dotSuperpos, out dotMaxStacks)) { dotMaxStacks = 1; } } } #endregion if (attackInfo.SkillId > 0 && effect.Info.TryGetValue(CharacterSkillStat.dot, out dotDamage)) //Skill has/is dot { dotTimeMS = effect.Info[CharacterSkillStat.dotTime] * 1000; if (!effect.Info.TryGetValue(CharacterSkillStat.prop, out dotChance)) { dotChance = 100; } dotSkillId = attackInfo.SkillId; dotDamage = (int)(chr.Stats.GetDamage() * (dotDamage / 100.0)); if (!effect.Info.TryGetValue(CharacterSkillStat.dotSuperpos, out dotMaxStacks)) { dotMaxStacks = 1; } } #endregion foreach (AttackPair ap in attackInfo.TargetDamageList) { MapleMonster mob = chr.Map.GetMob(ap.TargetObjectId); if (mob != null && mob.Alive) { long totalMobDamage = 0; foreach (int damage in ap.Damage) { totalMobDamage += damage; } if (totalMobDamage > 0) { totalDamage += totalMobDamage; if (totalDamage > int.MaxValue) { totalDamage = int.MaxValue; } #region Status effects if (effect != null) { foreach (MonsterBuffApplication mba in effect.MonsterBuffs) { if (Functions.MakeChance(mba.Prop)) { foreach (var kvp in mba.Buffs) { mob.ApplyStatusEffect(attackInfo.SkillId, kvp.Key, kvp.Value, mba.Duration, chr); } } } } #endregion #region MP Eater if (chr.Stats.MpEaterProp > 0) { if (Functions.MakeChance(chr.Stats.MpEaterProp)) { int mpSteal = (int)((chr.Stats.MpEaterR / 100.0) * mob.WzInfo.MP); chr.AddMP(mpSteal); } } #endregion #region Bandit if (chr.IsBandit) { if (Functions.MakeChance(pickPocketProp)) { chr.Map.SpawnMesoMapItem(1, mob.Position, chr.Map.GetDropPositionBelow(mob.Position, mob.Position), false, MapleDropType.Player, chr); } if (attackInfo.SkillId == Bandit.STEAL) { int prop = DataBuffer.GetCharacterSkillById(Bandit.STEAL).GetEffect(chr.GetSkillLevel(Bandit.STEAL)).Info[CharacterSkillStat.prop]; if (Functions.MakeChance(prop)) { MapleItem item = mob.TryGetStealableItem(chr.Id, chr.Name); if (item != null) { chr.Map.SpawnMapItem(item, mob.Position, chr.Map.GetDropPositionBelow(chr.Position, mob.Position), false, Map.MapleDropType.Player, chr); } } } } #endregion if (Functions.MakeChance(dotChance)) { mob.ApplyPoison(dotSkillId, dotTimeMS, dotDamage, 1000, chr, dotMaxStacks); } mob.Damage(chr, (int)totalDamage); } } } #region special skill handling if (type == SendHeader.RangedAttack) { if (attackInfo.Targets > 0 && chr.IsHunter) { #region QuiverCartridge QuiverCartridgeSystem qcs = chr.Resource as QuiverCartridgeSystem; if (qcs != null && qcs.ChosenArrow > -1) { int usedArrow = qcs.HandleUse(c); switch (usedArrow) { case 0: // Blood if (Functions.MakeChance(50)) //50% chance to heal 20% of damage as hp { chr.AddHP((int)(totalDamage * 0.2)); } break; case 1: // Poison //TODO: poison, 90% damage, 8 seconds, stacks 3 times break; case 2: // Magic, don't need handling I think break; } } #endregion } } if (totalDamage > 0) { BuffedCharacterStats stats = chr.Stats; if (stats.LifeStealProp > 0 && stats.LifeStealR > 0) { if (Functions.MakeChance(stats.LifeStealProp)) { int lifesteal = (int)((stats.LifeStealR / 100.0) * totalDamage); chr.AddHP(lifesteal); } } if (chr.IsMagician) { #region ArcaneAim int arcaneAimId = 0; if (chr.Job == JobConstants.FIREPOISON4) { arcaneAimId = FirePoison4.ARCANE_AIM; } else if (chr.Job == JobConstants.ICELIGHTNING4) { arcaneAimId = IceLightning4.ARCANE_AIM; } else if (chr.Job == JobConstants.BISHOP) { arcaneAimId = Bishop.ARCANE_AIM; } if (arcaneAimId > 0) { byte skillLevel = chr.GetSkillLevel(arcaneAimId); if (skillLevel > 0) { if ((DateTime.UtcNow.Subtract(chr.LastAttackTime).TotalMilliseconds) < 5000) { Buff oldBuff = chr.GetBuff(arcaneAimId); if (oldBuff != null) { int prop = oldBuff.Effect.Info[CharacterSkillStat.prop]; if (Functions.MakeChance(prop)) { Buff newBuff = new Buff(arcaneAimId, oldBuff.Effect, oldBuff.Duration, chr); int oldStacks = oldBuff.Stacks / 6; newBuff.Stacks = Math.Min(30, (oldStacks + 1) * 6); chr.GiveBuff(newBuff); } } else { SkillEffect arcaneAimEffect = DataBuffer.GetCharacterSkillById(arcaneAimId).GetEffect(skillLevel); int prop = arcaneAimEffect.Info[CharacterSkillStat.prop]; if (Functions.MakeChance(prop)) { Buff newBuff = new Buff(arcaneAimId, arcaneAimEffect, 5000, chr); newBuff.Stacks = 6; chr.GiveBuff(newBuff); } } } } } #endregion } else if (chr.IsThief) { if (chr.IsBandit) { chr.IncreaseCriticalGrowth(true); byte skillLevel = chr.GetSkillLevel(Shadower.SHADOWER_INSTINCT); if (skillLevel > 0) { ((BodyCountSystem)chr.Resource).IncreaseBodyCount(c); } } } } #endregion chr.LastAttackTime = DateTime.UtcNow; }
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)); } }
public void RegisterMonster(MapleMonster mob) { m_mobs.Add(mob); mob.EventInstanceManager = this; }
public static void Handle(MapleClient c, PacketReader pr) { if (c.Account.Character.Map != null) { int objectId = pr.ReadInt(); MapleMonster Mob = c.Account.Character.Map.GetMob(objectId); if (Mob == null) { return; } lock (Mob.MobLock) { if (!Mob.Alive) { return; } if (Mob.GetController() != c.Account.Character) { c.SendPacket(MapleMonster.RemoveMobControl(objectId)); return; } pr.Skip(1); short moveID = pr.ReadShort(); bool useSkill = pr.ReadBool(); byte skill = pr.ReadByte(); int unk = pr.ReadInt(); Point startPos = Mob.Position; int skillid = 0; int skilllevel = 0; if (useSkill) { if (Mob.WzInfo.Skills.Count > 0) { if (skill >= 0 && skill < Mob.WzInfo.Skills.Count) { MobSkill mobSkill = Mob.WzInfo.Skills[skill]; if ((DateTime.UtcNow - Mob.SkillTimes[mobSkill]).TotalMilliseconds > mobSkill.interval)// && mobSkill.summonOnce { Mob.SkillTimes[mobSkill] = DateTime.UtcNow; if (mobSkill.hp <= Mob.HpPercent) { //supposed to apply efffect here :/ //todo $$ //mobSkill.applyEffect(chr, monster, true); skillid = mobSkill.Skill; skilllevel = mobSkill.Level; } } } else { return;//hacking? } } } List <int> unkList = new List <int>(); List <short> unkList2 = new List <short>(); byte count = pr.ReadByte(); for (int i = 0; i < count; i++) { unkList.Add(pr.ReadInt()); } count = pr.ReadByte(); for (int i = 0; i < count; i++) { unkList.Add(pr.ReadShort()); } pr.Skip(30); List <MapleMovementFragment> Res = ParseMovement.Parse(pr); if (Res != null && Res.Count > 0) { updatePosition(Res, Mob, -1); if (Mob.Alive) { MoveResponse(c, objectId, moveID, Mob.ControllerHasAggro, (short)Mob.WzInfo.MP, 0, 0); MoveMob(c, objectId, useSkill, skill, unk, startPos, Res, unkList, unkList2); } } else { ServerConsole.Warning("Monster Res == null or empty!"); } } } }
public List <DropEntry> RetrieveDropChances(int monsterid) { if (m_drops.ContainsKey(monsterid)) { return(m_drops[monsterid]); } var ret = new List <DropEntry>(); if (monsterid > 9300183 && monsterid < 9300216) { for (var i = 2022359; i < 2022367; i++) { ret.Add(new DropEntry(i, 10)); } if (m_drops.ContainsKey(monsterid)) { m_drops[monsterid] = ret; } else { m_drops.Add(monsterid, ret); } return(ret); } if (monsterid > 9300215 && monsterid < 9300269) { for (var i = 2022430; i < 2022434; i++) { ret.Add(new DropEntry(i, 3)); } if (m_drops.ContainsKey(monsterid)) { m_drops[monsterid] = ret; } else { m_drops.Add(monsterid, ret); } return(ret); } MapleMonster theMonster = null; var dropItems = JsonConvert.DeserializeObject <List <DropItem> >(File.ReadAllText($"{Environment.CurrentDirectory}\\Json\\MonsterDrops.json")); var dropQuery = dropItems.Where(x => x.MonsterId == monsterid).Select(x => x); foreach (var dropInfo in dropQuery) { var rowmonsterid = dropInfo.MonsterId; var chance = dropInfo.Chance; var questid = dropInfo.QuestId; if (rowmonsterid != monsterid && rowmonsterid != 0) { if (theMonster == null) { theMonster = MapleLifeFactory.GetMonster(monsterid); } chance += theMonster.Stats.Level * rowmonsterid; } ret.Add(new DropEntry(dropInfo.ItemId, chance, questid)); } if (m_drops.ContainsKey(monsterid)) { m_drops[monsterid] = ret; } else { m_drops.Add(monsterid, ret); } return(ret); }
private static void CheckHighDamage(MapleCharacter player, MapleMonster monster, AttackInfo attack, ISkill theSkill, MapleStatEffect attackEffect, int damageToMonster, int maximumDamageToMonster) { //检查高攻击伤害 int elementalMaxDamagePerMonster; var element = Element.Neutral; if (theSkill != null) { element = theSkill.Element; var skillId = theSkill.SkillId; if (skillId == 3221007) { maximumDamageToMonster = 99999; } else if (skillId == 4221001) { maximumDamageToMonster = 400000; } } if (player.GetBuffedValue(MapleBuffStat.WkCharge) != null) { var chargeSkillId = player.GetBuffSource(MapleBuffStat.WkCharge); switch (chargeSkillId) { case 1211003: case 1211004: element = Element.Fire; break; case 1211005: case 1211006: element = Element.Ice; break; case 1211007: case 1211008: element = Element.Lighting; break; case 1221003: case 1221004: element = Element.Holy; break; } var chargeSkill = SkillFactory.GetSkill(chargeSkillId); maximumDamageToMonster *= (int)(chargeSkill.GetEffect(player.GetSkillLevel(chargeSkill)).Damage / 100.0); } if (element != Element.Neutral) { double elementalEffect; if (attack.Skill == 3211003 || attack.Skill == 3111003) { //烈火箭和寒冰�? elementalEffect = attackEffect.X / 200.0; } else { elementalEffect = 0.5; } switch (monster.GetEffectiveness(element).Value) { case 1: //immue elementalMaxDamagePerMonster = 1; break; case 0: //normal elementalMaxDamagePerMonster = maximumDamageToMonster; break; case 3: //weak elementalMaxDamagePerMonster = (int)(maximumDamageToMonster * (1.0 + elementalEffect)); break; case 2: //strong elementalMaxDamagePerMonster = (int)(maximumDamageToMonster * (1.0 - elementalEffect)); break; default: throw new Exception("Effectiveness不正确"); } } else { elementalMaxDamagePerMonster = maximumDamageToMonster; } if (damageToMonster > elementalMaxDamagePerMonster) { player.AntiCheatTracker.RegisterOffense(CheatingOffense.HighDamage); //高伤�? if (attack.Skill != 1009 && attack.Skill != 10001009 && attack.Skill != 20001009) { // * 3 until implementation of lagsafe pingchecks for buff expiration if (damageToMonster <= elementalMaxDamagePerMonster * 4) { return; } if (player.IsGm || player.Job == MapleJob.Ares && player.Level <= 10) { //log.info("这里不进行操�?"); } else { if (player.Level < 70) { AutobanManager.Instance.BroadcastMessage(player.Client, $" {player.Name} 被系统封号 封号原因:伤害异常({damageToMonster}) 当前等级:{player.Level}"); //player.ban(player.getName() + " 被系统封�?.(异常攻击伤害�?: " + damageToMonster + " 当前等级 " + player.getLevel() + " ElementalMaxDamage: " + elementalMaxDamagePerMonster * 4 + " (IP: " + player.getClient().getSession().getRemoteAddress().toString().split(":")[0] + ")"); } } } else { var maxDamage = (int)Math.Floor(monster.MaxHp * 0.3); if (damageToMonster > 500000) { AutobanManager.Instance.Autoban(player.Client, damageToMonster + $"伤害异常 等级: {player.Level} 攻击力: {player.Watk} 技能ID: {attack.Skill} 攻击怪物ID: {monster.Id} 造成最大伤害: {maxDamage}"); } } } }
public static void Handle(MapleClient c, PacketReader pr) { //6800 29939E7B 81BFD40F FD 00 60000000 00 00 037B 00 //6800 418AE151 6BE4D40F FF 00 01000000 00 00 47357C00 FE77AD00 00 00000000 00000000 00 00 00 //C101 CA566800 FD 60000000 00 60000000 //C101 68EB7A00 FF 01000000 00 F6761200 00 00000000 00000000 00 00 01000000 //effect //CD01 CA566800 [000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200] 0100 7B000300 00 00 00 00000000 00000000 00000000 00000000 00000000 0000 MapleCharacter chr = c.Account.Character; if (chr.Hidden) { return; } pr.Skip(4); //rnd num pr.Skip(4); //tickcount byte type = pr.ReadByte(); int damage = 0; pr.ReadByte(); damage = pr.ReadInt(); pr.Skip(2); int fake = 0; if (damage == -1) { fake = 4020002 + (chr.Job / 10 - 40) * 100000; if ((fake != NightLord.SHADOW_SHIFTER) && (fake != Shadower.SHADOW_SHIFTER)) { fake = NightLord.SHADOW_SHIFTER; } } switch (type) { case 0xFF: //mob damage { int mobid = pr.ReadInt(); int oid = pr.ReadInt(); MapleMonster mob = chr.Map.GetMob(oid); if (mob == null) { return; } byte direction = pr.ReadByte(); int skillid = pr.ReadInt(); int pDmg = pr.ReadInt(); byte defType = pr.ReadByte(); bool pPhysical = false; int pId = 0; byte pType = 0; Point pPos = Point.Empty; pr.ReadByte(); if (skillid != 0) { pPhysical = pr.ReadBool(); pId = pr.ReadInt(); pType = pr.ReadByte(); pr.Skip(4); pPos = pr.ReadPoint(); } byte offset = 0; int offsetD = 0; if (pr.Available == 1L) { offset = pr.ReadByte(); if ((offset == 1) && (pr.Available >= 4L)) { offsetD = pr.ReadInt(); } if ((offset < 0) || (offset > 2)) { offset = 0; } } BroadcastDamagePlayerPacket(chr, type, damage, mobid, direction, skillid, pDmg, pPhysical, pId, pType, pPos, offset, offsetD, fake); damage = DoMonsterDamageModifiers(damage, chr, mob, oid); if (damage > 0) { chr.AddHP(-damage); } } break; case 0xFD: //no mob, such as fall damage { short skill = pr.ReadShort(); //skill pr.ReadByte(); //? byte offset = 0; int offsetD = 0; if (pr.Available >= 1) { offset = pr.ReadByte(); if ((offset == 1) && (pr.Available >= 4)) { offsetD = pr.ReadInt(); } if ((sbyte)offset < 0 || offset > 2) { offset = 0; } } BroadcastDamagePlayerPacket(chr, type, damage, 0, 0, 0, 0, false, 0, 0, System.Drawing.Point.Empty, offset, offsetD, fake); if (damage > 0) { chr.AddHP(-damage); } } break; default: ServerConsole.Error("Invalid CharacterReceiveDamage type {0} ", type); break; } }
private static int DoMonsterDamageModifiers(int damage, MapleCharacter chr, MapleMonster mobFrom, int mobFromOID) { if (damage == 0) //guard/miss etc { Buff buff = chr.GetBuff(Priest.HOLY_MAGIC_SHELL); if (buff != null) { buff.Stacks -= 1; if (buff.Stacks == 0) { chr.CancelBuff(Priest.HOLY_MAGIC_SHELL); } } } #region Spearman if (chr.IsSpearman) { if (chr.Job >= JobConstants.BERSERKER) { if (chr.Job == JobConstants.DARKKNIGHT) { byte evilEyeRevengeLevel = chr.GetSkillLevel(DarkKnight.REVENGE_OF_THE_EVIL_EYE); if (evilEyeRevengeLevel > 0 && !chr.HasSkillOnCooldown(DarkKnight.REVENGE_OF_THE_EVIL_EYE)) { MapleSummon evilEye = chr.GetSummon(Spearman.EVIL_EYE); Buff evilEyebuff = chr.GetBuff(Spearman.EVIL_EYE); if (evilEye != null && evilEyebuff != null && evilEyebuff.Stacks != Berserker.EVIL_EYE_OF_DOMINATION) { SkillEffect effect = DataBuffer.GetCharacterSkillById(DarkKnight.REVENGE_OF_THE_EVIL_EYE).GetEffect(evilEyeRevengeLevel); int summonDamage = (int)((effect.Info[CharacterSkillStat.damage] / 100.0) * chr.Stats.GetDamage()); int healHp = (int)((effect.Info[CharacterSkillStat.x] / 100.0) * summonDamage); chr.AddHP(healHp); //instant KO: if (!mobFrom.IsBoss && summonDamage < mobFrom.HP) { if (Functions.MakeChance(effect.Info[CharacterSkillStat.z])) { summonDamage = mobFrom.HP; } } evilEye.AttackMonster(summonDamage, 0x84, mobFrom); chr.AddCooldownSilent(DarkKnight.REVENGE_OF_THE_EVIL_EYE, (uint)effect.Info[CharacterSkillStat.cooltime] * 1000, DateTime.UtcNow, false); } } if (chr.HasBuff(DarkKnight.FINAL_PACT2)) { return(0); //Invincible } } Buff crossSurgeBuff = chr.GetBuff(Berserker.CROSS_SURGE); if (crossSurgeBuff != null) { int absorbPercent = crossSurgeBuff.Effect.Info[CharacterSkillStat.y]; int absorb = (int)((chr.Stats.MaxHp - chr.Hp) * (absorbPercent / 100.0)); absorb = Math.Min(absorb, crossSurgeBuff.Effect.Info[CharacterSkillStat.z]); //normally z = 4000 damage -= absorb; } } } #endregion #region Magician else if (chr.IsMagician) { Buff buff = chr.GetBuff(Magician.MAGIC_GUARD); if (buff != null) { if (chr.Mp > 0) { int absorb = (int)((buff.Effect.Info[CharacterSkillStat.x] / 100.0) * damage); if (chr.Mp < absorb) { absorb = chr.Mp; } chr.AddMP(-absorb); damage -= absorb; } } } #endregion #region Bandit else if (chr.IsBandit) { Buff mesoGuard = chr.GetBuff(Bandit.MESOGUARD); if (mesoGuard != null) { double absorb = 0.5; double mesoLoss = mesoGuard.Effect.Info[CharacterSkillStat.x] / 100.0; double mesoLossReduction = 0.0; byte MesoMasteryLevel = chr.GetSkillLevel(ChiefBandit.MESO_MASTERY); if (MesoMasteryLevel > 0) { SkillEffect effect = DataBuffer.GetCharacterSkillById(ChiefBandit.MESO_MASTERY).GetEffect(MesoMasteryLevel); absorb += effect.Info[CharacterSkillStat.v] / 100.0; mesoLossReduction = effect.Info[CharacterSkillStat.v] / 100.0; } int damageAbsorbed = (int)(damage * absorb); if (damageAbsorbed > 0) { int mesoUse = (int)(damageAbsorbed * mesoLoss); mesoUse -= (int)(mesoUse * mesoLossReduction); if (chr.Mesos >= mesoUse) { chr.Inventory.RemoveMesos(mesoUse, false); damage -= damageAbsorbed; int mesoDrops = Functions.Random(1, 4); for (int i = 0; i < mesoDrops; i++) { chr.Map.SpawnMesoMapItem(1, chr.Position, chr.Map.GetDropPositionBelow(chr.Position, chr.Position), false, MapleDropType.Player, chr); } } } } } #endregion #region Luminous else if (chr.IsLuminous) { Buff oldBuff = chr.GetBuff(Luminous2.BLACK_BLESSING); if (oldBuff != null) { int remove = (int)(damage * 0.7); damage -= remove; if (oldBuff.Stacks < 2) { chr.CancelBuff(Luminous2.BLACK_BLESSING); } else { chr.CancelBuffSilent(Luminous2.BLACK_BLESSING); Buff newBuff = new Buff(oldBuff.SkillId, oldBuff.Effect, oldBuff.Duration, chr); newBuff.Stacks = oldBuff.Stacks - 1; chr.GiveBuff(newBuff); } } byte skillLevel = 0; if ((skillLevel = chr.GetSkillLevel(Luminous1.STANDARD_MAGIC_GUARD)) > 0) { SkillEffect effect = DataBuffer.GetCharacterSkillById(Luminous1.STANDARD_MAGIC_GUARD).GetEffect(skillLevel); double percent = effect.Info[CharacterSkillStat.x] / 100.0; int absorb = (int)(percent * damage); if (chr.Mp >= absorb) { chr.AddMP(absorb); damage -= absorb; } } } #endregion return(damage); }