예제 #1
0
        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);
        }
예제 #2
0
 public bool ApplyStatus(MapleCharacter from, MonsterStatusEffect status, bool poison, long duration)
 {
     return(ApplyStatus(from, status, poison, duration, false));
 }