public static void Proc(ref Actor sActor, ref Actor dActor, ref Map.SkillArgs args) { ActorPC pc = (ActorPC)sActor; ActorEventHandlers.PC_EventHandler eh = (SagaMap.ActorEventHandlers.PC_EventHandler)pc.e; if (sActor.type == ActorType.PC) { if (!SkillHandler.CheckSkillSP(pc, args.skillID)) { SkillHandler.SetSkillFailed(ref args); return; } args.damage = 0; args.isCritical = Map.SkillArgs.AttackResult.Heal; ActorPC targetPC; args.damage = CalcDamage(sActor, dActor, args); if (dActor.type == ActorType.PC) { targetPC = (ActorPC)dActor; eh = (SagaMap.ActorEventHandlers.PC_EventHandler)targetPC.e; targetPC.HP += (ushort)args.damage; eh.C.SendSkillEffect(SkillFactory.GetSkill((uint)args.skillID).addition, SkillEffects.HP, args.damage); if (targetPC.HP > targetPC.maxHP) { targetPC.HP = targetPC.maxHP; } eh.C.SendCharStatus(0); } } }
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 IEnumerator Start() { Responsible.JobFinished = false; Responsible.TargetInRange = false; if (Target) { Responsible.Target = Target.gameObject; } Responsible.StartCoroutine(Coroutine); if (!Responsible.Inventory.InInventory(Target.gameObject)) { yield return(new WaitUntil(() => Responsible.TargetInRange)); } if (Target == null || Target.InUse <= 0 || !Target.Methods.Contains(Method)) { Debug.Log("Target is already in use!"); Stop(true); yield break; } _started = true; Debug.Log("Reached to the target now I'm gonna start doing my job!"); Target.InUse--; SkillManager.AddSkill(Responsible, SkillFactory.GetSkill(SkillType)); EffectManager.Apply(Responsible, Effects); }
public static void Proc(ref Actor sActor, ref Actor dActor, ref Map.SkillArgs args) { if (sActor.type == ActorType.PC) { ActorPC pc = (ActorPC)sActor; if (pc.SP < SkillFactory.GetSkill((uint)args.skillID).sp) { args.damage = 0; args.isCritical = Map.SkillArgs.AttackResult.Miss; args.failed = true; return; } else { ActorEventHandlers.PC_EventHandler eh = (ActorEventHandlers.PC_EventHandler)pc.e; pc.SP -= (ushort)SkillFactory.GetSkill((uint)args.skillID).sp; pc.LP += 1; if (pc.LP > 5) { pc.LP = 5; } eh.C.SendCharStatus(0); } } args.damage = 0; args.isCritical = Map.SkillArgs.AttackResult.Nodamage; byte level = (byte)(args.skillID - baseID + 1); ActorPC targetpc = (ActorPC)dActor; Tasks.PassiveSkillStatus ss; if (targetpc.Tasks.ContainsKey("VenomCoat")) { ss = (PassiveSkillStatus)targetpc.Tasks["VenomCoat"]; ss.level = level; SkillHandler.RemoveStatusIcon(dActor, (uint)1457400 + ss.level); targetpc.BattleStatus.atkskill -= CalcDamage(ss.level); ss.Deactivate(); ss.dueTime = 1; ss.period = 600000; targetpc.BattleStatus.atkskill += CalcDamage(level); SkillHandler.AddStatusIcon(dActor, (uint)args.skillID, 600000); ss.Activate(); } else { ss = new PassiveSkillStatus(level); ss.dueTime = 1; ss.period = 600000; ss.client = dActor; ss.Func = new PassiveSkillStatus.CallBackFunc(Callback); targetpc.Tasks.Add("VenomCoat", ss); targetpc.BattleStatus.atkskill += CalcDamage(level); SkillHandler.AddStatusIcon(dActor, (uint)args.skillID, 600000); ss.Activate(); } }
public IActionResult GetSkill(int skillId) { Skill desc = SkillFactory.GetSkill(skillId); if (desc == null) { return(NotFound()); } return(Json(desc)); }
public MapleStatEffect GetAttackEffect(MapleCharacter chr, ISkill theSkill) { var mySkill = theSkill ?? SkillFactory.GetSkill(Skill); var skillLevel = chr.GetSkillLevel(mySkill); if (mySkill.SkillId == 1009 || mySkill.SkillId == 10001009) { skillLevel = 1; } return(skillLevel == 0 ? null : mySkill.GetEffect(skillLevel)); }
public MapleSummon(MapleCharacter owner, int skill, Point pos, SummonMovementType movementType) { Owner = owner; SkillId = skill; SkillLevel = owner.GetSkillLevel(SkillFactory.GetSkill(skill)); if (SkillLevel == 0) { Console.WriteLine("Trying to create a summon for a char without the skill"); } MovementType = movementType; Position = pos; }
public void AddSkill(SkillName name) { if (!HasSkill(name)) { Skill s = SkillFactory.GetSkill(name); Skills.Add(s); } else { Console.WriteLine($"{Name} already knows {name}"); } }
public void OnChangeStatus(Actor sActor, MapEventArgs args) { Map.StatusArgs arg = (Map.StatusArgs)args; switch (arg.type) { case Map.StatusArgs.EventType.Add: foreach (Map.StatusArgs.StatusInfo i in arg.StatusList) { Packets.Server.ExchangeAddition p1 = new SagaMap.Packets.Server.ExchangeAddition(); p1.SetID(sActor.id); Skill info = SkillFactory.GetSkill(i.SkillID); if (info != null) { p1.SetStatusID(info.addition); } else { p1.SetStatusID(i.SkillID); } p1.SetTime(i.time); this.C.netIO.SendPacket(p1, C.SessionID); } break; case Map.StatusArgs.EventType.Remove: foreach (Map.StatusArgs.StatusInfo i in arg.StatusList) { Packets.Server.DeleteExchangeAddition p1 = new SagaMap.Packets.Server.DeleteExchangeAddition(); p1.SetID(sActor.id); Skill info = SkillFactory.GetSkill(i.SkillID); if (info != null) { p1.SetStatusID(info.addition); } else { p1.SetStatusID(i.SkillID); } this.C.netIO.SendPacket(p1, C.SessionID); } break; } }
public void TestSkillFacotry(SkillName s) { Skill expected = null; switch (s) { case SkillName.Learning: expected = new Learning(); break; case SkillName.Logistics: expected = new Logistics(); break; case SkillName.Offense: expected = new Offense(); break; } Skill actual = SkillFactory.GetSkill(s); Assert.Equal(expected.Name, actual.Name); }
public static void Proc(ref Actor sActor, ref Actor dActor, ref Map.SkillArgs args) { if (sActor.type == ActorType.PC) { ActorPC pc = (ActorPC)sActor; if (pc.SP < SkillFactory.GetSkill((uint)args.skillID).sp) { args.damage = 0; args.isCritical = Map.SkillArgs.AttackResult.Miss; args.failed = true; return; } else { ActorEventHandlers.PC_EventHandler eh = (ActorEventHandlers.PC_EventHandler)pc.e; pc.SP -= (ushort)SkillFactory.GetSkill((uint)args.skillID).sp; pc.LP += 1; if (pc.LP > 5) { pc.LP = 5; } eh.C.SendCharStatus(0); } } args.damage = 0; args.isCritical = SkillHandler.CalcCrit(sActor, dActor, args, SkillHandler.AttackType.Physical); if (args.isCritical != Map.SkillArgs.AttackResult.Miss && args.isCritical != Map.SkillArgs.AttackResult.Block) { ActorPC targetPC = (ActorPC)sActor; args.damage = CalcDamage(sActor, dActor, args); } if (args.damage <= 0) { args.damage = 1; } SkillHandler.PhysicalAttack(ref sActor, ref dActor, args.damage, SkillHandler.AttackElements.HOLY, ref args); }
public bool ApplyStatus(MapleCharacter from, MonsterStatusEffect status, bool poison, long duration, bool venom) { switch (Stats.GetEffectiveness(status.GetSkill().Element).Value) { case 1: //IMMUNE: case 2: //STRONG: return(false); case 0: //NORMAL: case 3: //WEAK: break; default: throw new Exception( $"Unknown elemental effectiveness:{Stats.GetEffectiveness(status.GetSkill().Element)}"); } // compos don't have an elemental (they have 2 - so we have to hack here...) ElementalEffectiveness effectiveness = null; switch (status.GetSkill().SkillId) { case 2111006: effectiveness = Stats.GetEffectiveness(Element.Poison); if (effectiveness == ElementalEffectiveness.Immune || effectiveness == ElementalEffectiveness.Strong) { return(false); } break; case 2211006: effectiveness = Stats.GetEffectiveness(Element.Ice); if (effectiveness == ElementalEffectiveness.Strong || effectiveness == ElementalEffectiveness.Strong) { return(false); } break; case 4120005: case 4220005: effectiveness = Stats.GetEffectiveness(Element.Poison); if (effectiveness == ElementalEffectiveness.Weak) { return(false); } break; } if (poison && Hp <= 1) { return(false); } if (IsBoss && !status.Stati.ContainsKey(MonsterStatus.Speed)) { return(false); } status.Stati.Keys.ToList().ForEach(stat => { MonsterStatusEffect oldEffect; if (m_stati.TryGetValue(stat, out oldEffect)) { oldEffect.RemoveActiveStatus(stat); if (!oldEffect.Stati.Any()) { //oldEffect.getCancelTask().cancel(false); //oldEffect.cancelPoisonSchedule(); m_activeEffects.Remove(oldEffect); } } }); var timerManager = TimerManager.Instance; Action cancelTask = () => { if (IsAlive) { var packet = PacketCreator.CancelMonsterStatus(ObjectId, status.Stati); Map.BroadcastMessage(packet, Position); if (GetController() != null && !GetController().VisibleMapObjects.Contains(this)) { GetController().Client.Send(packet); } } try { m_activeEffects.Remove(status); status.Stati.Keys.ToList().ForEach(stat => { m_stati.Remove(stat); }); } catch (Exception e) { Console.WriteLine(e); } VenomMultiplier = 0; //status.cancelPoisonSchedule(); }; if (!Map.HasEvent) { if (poison) { var poisonLevel = from.GetSkillLevel(status.GetSkill()); var poisonDamage = Math.Min(short.MaxValue, (int)(MaxHp / (70.0 - poisonLevel) + 0.999)); status.SetValue(MonsterStatus.Poison, poisonDamage); //status.setPoisonSchedule(timerManager.register(new PoisonTask(poisonDamage, from, status, cancelTask, false), 1000, 1000)); } else if (venom) { if (from.Job == MapleJob.Nightlord || from.Job == MapleJob.Shadower) { var poisonLevel = 0; var matk = 0; if (from.Job == MapleJob.Nightlord) { poisonLevel = from.GetSkillLevel(SkillFactory.GetSkill(4120005)); if (poisonLevel <= 0) { return(false); } matk = SkillFactory.GetSkill(4120005).GetEffect(poisonLevel).Matk; } else if (from.Job == MapleJob.Shadower) { poisonLevel = from.GetSkillLevel(SkillFactory.GetSkill(4220005)); if (poisonLevel <= 0) { return(false); } matk = SkillFactory.GetSkill(4220005).GetEffect(poisonLevel).Matk; } else { return(false); } int luk = from.Luk; var maxDmg = (int)Math.Ceiling(Math.Min(short.MaxValue, 0.2 * luk * matk)); var minDmg = (int)Math.Ceiling(Math.Min(short.MaxValue, 0.1 * luk * matk)); var gap = maxDmg - minDmg; if (gap == 0) { gap = 1; } var poisonDamage = 0; for (var i = 0; i < VenomMultiplier; i++) { poisonDamage = poisonDamage + Randomizer.Next(gap) + minDmg; } poisonDamage = Math.Min(short.MaxValue, poisonDamage); status.SetValue(MonsterStatus.Poison, poisonDamage); //status.setPoisonSchedule(timerManager.register(new PoisonTask(poisonDamage, from, status, cancelTask, false), 1000, 1000)); } else { return(false); } } else if (status.GetSkill().SkillId == 4111003) { // shadow web var webDamage = (int)(MaxHp / 50.0 + 0.999); // actually shadow web works different but similar... //status.setPoisonSchedule(timerManager.schedule(new PoisonTask(webDamage, from, status, cancelTask, true), 3500)); } foreach (var stat in status.Stati.Keys) { if (m_stati.ContainsKey(stat)) { m_stati[stat] = status; } else { m_stati.Add(stat, status); } } m_activeEffects.Add(status); var animationTime = status.GetSkill().AnimationTime; var packet = PacketCreator.ApplyMonsterStatus(ObjectId, status.Stati, status.GetSkill().SkillId, false, 0); Map.BroadcastMessage(packet, Position); if (GetController() != null && !GetController().VisibleMapObjects.Contains(this)) { GetController().Client.Send(packet); } //ScheduledFuture <?> schedule = timerManager.schedule(cancelTask, duration + animationTime); //status.setCancelTask(schedule); } return(true); }
public void Run(MapleCharacter c, int?extSelection) { MapleQuestStatus status; switch (Type) { case MapleQuestActionType.Exp: status = c.GetQuest(m_quest); if (status.Status == MapleQuestStatusType.NotStarted && status.Forfeited > 0) { break; } c.GainExp(MapleDataTool.GetInt(Data) * c.Client.ChannelServer.ExpRate, true, true); break; case MapleQuestActionType.Item: var ii = MapleItemInformationProvider.Instance; var props = new Dictionary <int, int>(); foreach (var iEntry in Data.Children) { if (iEntry.GetChildByPath("prop") != null && MapleDataTool.GetInt(iEntry.GetChildByPath("prop")) != -1 && CanGetItem(iEntry, c)) { for (var i = 0; i < MapleDataTool.GetInt(iEntry.GetChildByPath("prop")); i++) { props.Add(props.Count, MapleDataTool.GetInt(iEntry.GetChildByPath("id"))); } } } var selection = 0; var extNum = 0; if (props.Any()) { props.TryGetValue((int)(Randomizer.NextDouble() * props.Count), out selection); } foreach (var iEntry in Data.Children) { if (!CanGetItem(iEntry, c)) { continue; } if (iEntry.GetChildByPath("prop") != null) { if (MapleDataTool.GetInt(iEntry.GetChildByPath("prop")) == -1) { if (extSelection.HasValue && extSelection.Value != extNum++) { continue; } } else if (MapleDataTool.GetInt(iEntry.GetChildByPath("id")) != selection) { continue; } } if (MapleDataTool.GetInt(iEntry.GetChildByPath("count"), 0) < 0) { // remove items var itemId = MapleDataTool.GetInt(iEntry.GetChildByPath("id")); var iType = ii.GetInventoryType(itemId); var quantity = (short)(MapleDataTool.GetInt(iEntry.GetChildByPath("count"), 0) * -1); try { //MapleInventoryManipulator.removeById(c.Client, iType, itemId, quantity, true, false); } catch { Console.WriteLine("Completing a quest without meeting the requirements"); } c.Client.Send(PacketCreator.GetShowItemGain(itemId, (short)MapleDataTool.GetInt(iEntry.GetChildByPath("count"), 0), true)); } else { // add items var itemId = MapleDataTool.GetInt(iEntry.GetChildByPath("id")); var quantity = (short)MapleDataTool.GetInt(iEntry.GetChildByPath("count"), 0); var logInfo = new StringBuilder(c.Name); logInfo.Append(" received "); logInfo.Append(quantity); logInfo.Append(" as reward from a quest"); // MapleInventoryManipulator.addById(c.Client, itemId, quantity, logInfo.ToString(), null, -1); c.Client.Send(PacketCreator.GetShowItemGain(itemId, quantity, true)); } } break; case MapleQuestActionType.Nextquest: status = c.GetQuest(m_quest); var nextQuest = MapleDataTool.GetInt(Data); if (status.Status == MapleQuestStatusType.NotStarted && status.Forfeited > 0) { break; } c.Client.Send(PacketCreator.UpdateQuestFinish((short)m_quest.GetQuestId(), status.Npcid, (short)nextQuest)); MapleQuest.GetInstance(nextQuest).Start(c, status.Npcid); break; case MapleQuestActionType.Meso: status = c.GetQuest(m_quest); if (status.Status == MapleQuestStatusType.NotStarted && status.Forfeited > 0) { break; } c.GainMeso(MapleDataTool.GetInt(Data), true, false, true); break; case MapleQuestActionType.Quest: foreach (var qEntry in Data) { var questid = MapleDataTool.GetInt(qEntry.GetChildByPath("id")); var stat = MapleDataTool.GetInt(qEntry.GetChildByPath("state"), 0); c.UpdateQuest(new MapleQuestStatus(MapleQuest.GetInstance(questid), (MapleQuestStatusType)stat)); } break; case MapleQuestActionType.Skill: foreach (var sEntry in Data) { var skillid = MapleDataTool.GetInt(sEntry.GetChildByPath("id")); var skillLevel = (byte)MapleDataTool.GetInt(sEntry.GetChildByPath("skillLevel")); var masterLevel = (byte)MapleDataTool.GetInt(sEntry.GetChildByPath("masterLevel")); var skillObject = SkillFactory.GetSkill(skillid); var shouldLearn = false; var applicableJobs = sEntry.GetChildByPath("job"); foreach (var applicableJob in applicableJobs) { var job = MapleJob.GetByJobId(MapleDataTool.GetShort(applicableJob)); if (c.Job == job) { shouldLearn = true; break; } } if (skillObject.IsBeginnerSkill) { shouldLearn = true; } skillLevel = Math.Max(skillLevel, c.GetSkillLevel(skillObject)); masterLevel = Math.Max(masterLevel, skillObject.MaxLevel); if (shouldLearn) { c.ChangeSkillLevel(skillObject, skillLevel, masterLevel); c.DropMessage( $"你已获得 {SkillFactory.GetSkillName(skillid)} 当前等级 {skillLevel} 最高等级 {masterLevel}"); } } break; case MapleQuestActionType.Fame: status = c.GetQuest(m_quest); if (status.Status == MapleQuestStatusType.NotStarted && status.Forfeited > 0) { break; } c.Fame += MapleDataTool.GetShort(Data); c.UpdateSingleStat(MapleStat.Fame, c.Fame); var fameGain = MapleDataTool.GetInt(Data); c.Client.Send(PacketCreator.GetShowFameGain(fameGain)); break; case MapleQuestActionType.Buff: status = c.GetQuest(m_quest); if (status.Status == MapleQuestStatusType.NotStarted && status.Forfeited > 0) { break; } var mii = MapleItemInformationProvider.Instance; //mii.GetItemEffect(MapleDataTool.GetInt(data)).applyTo(c); break; case MapleQuestActionType.Petskill: status = c.GetQuest(m_quest); if (status.Status == MapleQuestStatusType.NotStarted && status.Forfeited > 0) { break; } var flag = MapleDataTool.GetInt("petskill", Data); //c.getPet(0).setFlag((byte)(c.getPet(0).getFlag() | InventoryConstants.Items.Flags.getFlagByInt(flag))); break; default: break; } }
public static AttackInfo ParseDamage(MapleCharacter c, InPacket p, bool ranged) { var ret = new AttackInfo(); p.ReadByte(); p.Skip(8); ret.NumAttackedAndDamage = p.ReadByte(); p.Skip(8); ret.NumAttacked = RightMove(ret.NumAttackedAndDamage, 4) & 0xF; ret.NumDamage = ret.NumAttackedAndDamage & 0xF; ret.AllDamage = new List <Tuple <int, List <int> > >(); ret.Skill = p.ReadInt(); p.Skip(8); if ((ret.Skill == 2121001) || (ret.Skill == 2221001) || (ret.Skill == 2321001) || (ret.Skill == 5201002) || (ret.Skill == 14111006) || (ret.Skill == 5101004) || (ret.Skill == 15101003)) { ret.Charge = p.ReadInt(); } else { ret.Charge = 0; } if (ret.Skill == 1221011) { ret.IsHh = true; } p.ReadInt(); ret.AresCombo = p.ReadByte(); //记录目前的Combo点数 var sourceid = ret.Skill; //以下�?能为Combo专用�?�? if ((sourceid == 21100004) || (sourceid == 21100005) || (sourceid == 21110003) || (sourceid == 21110004) || (sourceid == 21120006) || (sourceid == 21120007)) { //c.setCombo(1); } ret.Pos = p.ReadByte(); //动作 ret.Stance = p.ReadByte(); //姿势 if (ret.Skill == 4211006) { //return parseMesoExplosion(lea, ret); } if (ranged) { p.ReadByte(); ret.Speed = p.ReadByte(); p.ReadByte(); ret.Direction = p.ReadByte(); p.Skip(7); if ((ret.Skill == 3121004) || (ret.Skill == 3221001) || (ret.Skill == 5221004) || (ret.Skill == 13111002)) { p.Skip(4); } } else { p.ReadByte(); ret.Speed = p.ReadByte(); p.Skip(4); } for (var i = 0; i < ret.NumAttacked; ++i) { var oid = p.ReadInt(); p.Skip(14); var allDamageNumbers = new List <int>(); for (var j = 0; j < ret.NumDamage; ++j) { var damage = p.ReadInt(); MapleStatEffect effect = null; if (ret.Skill != 0) { effect = SkillFactory.GetSkill(ret.Skill) .GetEffect(c.GetSkillLevel(SkillFactory.GetSkill(ret.Skill))); } if ((damage != 0) && (effect != null) && (effect.GetFixedDamage() != 0)) { damage = effect.GetFixedDamage(); } allDamageNumbers.Add(damage); } if (ret.Skill != 5221004) { p.Skip(4); } ret.AllDamage.Add(Tuple.Create(oid, allDamageNumbers)); } 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 SetSkill(SkillEnum s, Level l) { skill = SkillFactory.GetSkill(s, l); }
public static void ApplyAttack(AttackInfo attack, MapleCharacter player, int maxDamagePerMonster, int attackCount) { //应用攻击 player.AntiCheatTracker.ResetHpRegen(); //player.resetAfkTimer(); player.AntiCheatTracker.CheckAttack(attack.Skill); ISkill theSkill = null; MapleStatEffect attackEffect = null; if (attack.Skill != 0) { theSkill = SkillFactory.GetSkill(attack.Skill); attackEffect = attack.GetAttackEffect(player, theSkill); if (attackEffect == null) { AutobanManager.Instance.Autoban(player.Client, $"使用了没有的技能ID:{attack.Skill}"); } else if (attack.Skill != 2301002) { if (player.IsAlive) { attackEffect.ApplyTo(player); } else { player.Client.Send(PacketCreator.EnableActions()); } } } if (!player.IsAlive) { player.AntiCheatTracker.RegisterOffense(CheatingOffense.AttackingWhileDead); return; } if (attackCount != attack.NumDamage && attack.Skill != 4211006 && attack.NumDamage != attackCount * 2) { player.AntiCheatTracker.RegisterOffense(CheatingOffense.MismatchingBulletcount, attack.NumDamage + "/" + attackCount); return; } var totDamage = 0; var map = player.Map; if (attack.Skill == 4211006) { // meso explosion long delay = 0; foreach (var oned in attack.AllDamage) { var mapobject = map.Mapobjects[oned.Item1]; if (mapobject != null && mapobject.GetType() == MapleMapObjectType.Item) { var mapitem = (MapleMapItem)mapobject; if (mapitem.Meso > 0) { lock (mapitem) { if (mapitem.IsPickedUp) { return; } TimerManager.Instance.RunOnceTask(() => { map.RemoveMapObject(mapitem); map.BroadcastMessage(PacketCreator.RemoveItemFromMap(mapitem.ObjectId, 4, 0), mapitem.Position); mapitem.IsPickedUp = true; }, delay); delay += 100; } } else if (mapitem.Meso == 0) { player.AntiCheatTracker.RegisterOffense(CheatingOffense.EtcExplosion); return; } } else if (mapobject != null && mapobject.GetType() != MapleMapObjectType.Monster) { player.AntiCheatTracker.RegisterOffense(CheatingOffense.ExplodingNonexistant); return; // etc explosion, exploding nonexistant things, etc. } } } foreach (var oned in attack.AllDamage) { var monster = map.GetMonsterByOid(oned.Item1); if (monster != null) { var totDamageToOneMonster = 0; foreach (var eachd in oned.Item2) { totDamageToOneMonster += eachd; } totDamage += totDamageToOneMonster; player.CheckMonsterAggro(monster); if (totDamageToOneMonster > attack.NumDamage + 1) { var dmgCheck = player.AntiCheatTracker.CheckDamage(totDamageToOneMonster); if (dmgCheck > 5 && totDamageToOneMonster < 99999 && monster.Id < 9500317 && monster.Id > 9500319) { player.AntiCheatTracker .RegisterOffense(CheatingOffense.SameDamage, dmgCheck + " times: " + totDamageToOneMonster); } } // �?测单次攻击�?�,这里不会�?! if (player.IsGm || player.Job == MapleJob.Ares && player.Level <= 10) { //log.info("这里不进行操�?"); } else { if (player.Level < 10) { if (totDamageToOneMonster > 10000) { AutobanManager.Instance.BroadcastMessage(player.Client, player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + ")"); //player.ban(player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + " (IP: " + player.Client.getSession().getRemoteAddress().toString().split(":")[0] + ")"); return; } } if (player.Level < 20) { if (totDamageToOneMonster > 20000) { AutobanManager.Instance.BroadcastMessage(player.Client, player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + ")"); //player.ban(player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + " (IP: " + player.Client.getSession().getRemoteAddress().toString().split(":")[0] + ")"); return; } } if (player.Level < 30) { if (totDamageToOneMonster > 30000) { AutobanManager.Instance.BroadcastMessage(player.Client, player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + ")"); //player.ban(player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + " (IP: " + player.Client.getSession().getRemoteAddress().toString().split(":")[0] + ")"); return; } } if (player.Level < 50) { if (totDamageToOneMonster > 50000) { AutobanManager.Instance.BroadcastMessage(player.Client, player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + ")"); //player.ban(player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + " (IP: " + player.Client.getSession().getRemoteAddress().toString().split(":")[0] + ")"); return; } } if (player.Level < 70) { if (totDamageToOneMonster > 150000) { AutobanManager.Instance.BroadcastMessage(player.Client, player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + ")"); //player.ban(player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + " (IP: " + player.Client.getSession().getRemoteAddress().toString().split(":")[0] + ")"); return; } } if (player.Level < 150) { if (totDamageToOneMonster > 350000) { AutobanManager.Instance.BroadcastMessage(player.Client, player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + ")"); //player.ban(player.Name + " 被系统封�?.(异常攻击伤害�?: " + totDamageToOneMonster + " 当前等级 " + player.Level + " (IP: " + player.Client.getSession().getRemoteAddress().toString().split(":")[0] + ")"); return; } } } CheckHighDamage(player, monster, attack, theSkill, attackEffect, totDamageToOneMonster, maxDamagePerMonster); var distance = player.Position.DistanceSquare(monster.Position); if (distance > 400000.0) { // 600^2, 550 is approximatly the range of ultis player.AntiCheatTracker.RegisterOffense(CheatingOffense.AttackFarawayMonster, Math.Sqrt(distance).ToString(CultureInfo.InvariantCulture)); } //遥远的�?�物袭击 if (attack.Skill == 5111004) { // 能量转换 var edrain = SkillFactory.GetSkill(5111004); var gainhp = (int) (totDamage * (double)edrain.GetEffect(player.GetSkillLevel(edrain)).X / 100.0); gainhp = Math.Min(monster.MaxHp, Math.Min(gainhp, player.MaxHp / 2)); player.Hp += (short)gainhp; } else if (attack.Skill == 15100004) { //光�?�拳 var edrain = SkillFactory.GetSkill(15100004); var gainhp = (int) (totDamage * (double)edrain.GetEffect(player.GetSkillLevel(edrain)).X / 100.0); gainhp = Math.Min(monster.MaxHp, Math.Min(gainhp, player.MaxHp / 2)); player.Hp += (short)gainhp; } if (!monster.ControllerHasAggro) { if (monster.GetController() == player) { monster.ControllerHasAggro = true; } else { monster.SwitchController(player, true); } } if (attack.Skill == 2301002 && !monster.Stats.IsUndead) { player.AntiCheatTracker.RegisterOffense(CheatingOffense.HealAttackingUndead); //医治攻击亡灵 return; } // Pickpocket if ((attack.Skill == 4001334 || attack.Skill == 4201005 || attack.Skill == 0 || attack.Skill == 4211002 || attack.Skill == 4211004) && player.GetBuffedValue(MapleBuffStat.Pickpocket) != null) { HandlePickPocket(player, monster, oned); } if (attack.Skill == 21100005) { // 生命吸收21100005 var drain = SkillFactory.GetSkill(21100005); var gainhp = (int) (totDamageToOneMonster * (double)drain.GetEffect(player.GetSkillLevel(drain)).X / 100.0); gainhp = Math.Min(monster.MaxHp, Math.Min(gainhp, player.MaxHp / 2)); player.Hp += (short)gainhp; } if (attack.Skill == 4101005) { // 生命吸收21100005 var drain = SkillFactory.GetSkill(4101005); var gainhp = (int) (totDamageToOneMonster * (double)drain.GetEffect(player.GetSkillLevel(drain)).X / 100.0); gainhp = Math.Min(monster.MaxHp, Math.Min(gainhp, player.MaxHp / 2)); player.Hp += (short)gainhp; } if (attack.Skill == 14101006) { // 吸血 var drain = SkillFactory.GetSkill(14101006); var gainhp = (int) (totDamageToOneMonster * (double)drain.GetEffect(player.GetSkillLevel(drain)).X / 100.0); gainhp = Math.Min(monster.MaxHp, Math.Min(gainhp, player.MaxHp / 2)); player.Hp += (short)gainhp; } if (player.GetBuffedValue(MapleBuffStat.Hamstring) != null) { var hamstring = SkillFactory.GetSkill(3121007); //降低速度的击�?�? if (hamstring.GetEffect(player.GetSkillLevel(hamstring)).MakeChanceResult()) { var monsterStatusEffect = new MonsterStatusEffect( new Dictionary <MonsterStatus, int> { { MonsterStatus.Speed, hamstring.GetEffect(player.GetSkillLevel(hamstring)).X } }, hamstring, false); monster.ApplyStatus(player, monsterStatusEffect, false, hamstring.GetEffect(player.GetSkillLevel(hamstring)).Y *1000); } } if (player.GetBuffedValue(MapleBuffStat.Blind) != null) { //刺眼�? var blind = SkillFactory.GetSkill(3221006); if (blind.GetEffect(player.GetSkillLevel(blind)).MakeChanceResult()) { var monsterStatusEffect = new MonsterStatusEffect( new Dictionary <MonsterStatus, int> { { MonsterStatus.Acc, blind.GetEffect(player.GetSkillLevel(blind)).X } } , blind, false); monster.ApplyStatus(player, monsterStatusEffect, false, blind.GetEffect(player.GetSkillLevel(blind)).Y *1000); } } if (player.Job == MapleJob.Whiteknight) { int[] charges = { 1211005, 1211006 }; //寒冰钝器 foreach (var charge in charges) { var chargeSkill = SkillFactory.GetSkill(charge); if (player.IsBuffFrom(MapleBuffStat.WkCharge, chargeSkill)) { var iceEffectiveness = monster.GetEffectiveness(Element.Ice); if (totDamageToOneMonster > 0 && iceEffectiveness == ElementalEffectiveness.Normal || iceEffectiveness == ElementalEffectiveness.Weak) { var chargeEffect = chargeSkill.GetEffect(player.GetSkillLevel(chargeSkill)); var monsterStatusEffect = new MonsterStatusEffect( new Dictionary <MonsterStatus, int> { { MonsterStatus.Freeze, 1 } }, chargeSkill, false); monster.ApplyStatus(player, monsterStatusEffect, false, chargeEffect.Y * 2000); } break; } } } var venomNl = SkillFactory.GetSkill(4120005); //武器用毒�? if (player.GetSkillLevel(venomNl) <= 0) { venomNl = SkillFactory.GetSkill(14110004); //武器用毒�? } var venomShadower = SkillFactory.GetSkill(4220005); if (player.GetSkillLevel(venomNl) > 0) { var venomEffect = venomNl.GetEffect(player.GetSkillLevel(venomNl)); for (var i = 0; i < attackCount; i++) { if (venomEffect.MakeChanceResult()) { if (monster.VenomMultiplier < 3) { monster.VenomMultiplier += 1; var monsterStatusEffect = new MonsterStatusEffect( new Dictionary <MonsterStatus, int> { { MonsterStatus.Poison, 1 } }, venomNl, false); monster.ApplyStatus(player, monsterStatusEffect, false, venomEffect.Duration, true); } } } } else if (player.GetSkillLevel(venomShadower) > 0) { var venomEffect = venomShadower.GetEffect(player.GetSkillLevel(venomShadower)); for (var i = 0; i < attackCount; i++) { if (venomEffect.MakeChanceResult()) { if (monster.VenomMultiplier < 3) { monster.VenomMultiplier += 1; var monsterStatusEffect = new MonsterStatusEffect( new Dictionary <MonsterStatus, int> { { MonsterStatus.Poison, 1 } }, venomShadower, false); monster.ApplyStatus(player, monsterStatusEffect, false, venomEffect.Duration, true); } } } } if (totDamageToOneMonster > 0 && attackEffect != null && attackEffect.MonsterStatus.Any()) { if (attackEffect.MakeChanceResult()) { var monsterStatusEffect = new MonsterStatusEffect(attackEffect.MonsterStatus, theSkill, false); monster.ApplyStatus(player, monsterStatusEffect, attackEffect.IsPoison(), attackEffect.Duration); } } if (attack.IsHh && !monster.IsBoss) { map.DamageMonster(player, monster, monster.Hp - 1); } else if (attack.IsHh && monster.IsBoss) { var weaponItem = player.Inventorys[MapleInventoryType.Equipped.Value].Inventory[0xF5]; //装备 MapleItemInformationProvider.Instance.GetWeaponType(weaponItem.ItemId); } else { map.DamageMonster(player, monster, totDamageToOneMonster); } } } if (totDamage > 1) { player.AntiCheatTracker.SetAttacksWithoutHit(player.AntiCheatTracker.GetAttacksWithoutHit() + 1); int offenseLimit; if (attack.Skill != 3121004) { //暴风箭雨 offenseLimit = 100; } else { offenseLimit = 300; } if (player.AntiCheatTracker.GetAttacksWithoutHit() > offenseLimit) { player.AntiCheatTracker .RegisterOffense(CheatingOffense.AttackWithoutGettingHit, player.AntiCheatTracker.GetAttacksWithoutHit().ToString()); } //没有受到撞击攻击 //if (player.hasEnergyCharge()) //{ // player.increaseEnergyCharge(attack.numAttacked); //} } }