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 bool ApplyStatus(MapleCharacter from, MonsterStatusEffect status, bool poison, long duration) { return(ApplyStatus(from, status, poison, duration, false)); }