public void UseAbility(RealmTime time, int abilitySlot, Position target)
 {
     if (Ability[abilitySlot] == null)
         return;
     var ability = Ability[abilitySlot];
     if (MP < ability.MpCost || AbilityCooldown[abilitySlot] != 0)
         return;
     MP -= ability.MpCost;
     AbilityCooldown[abilitySlot] = ability.Cooldown;
     foreach (ActivateEffect eff in ability.ActivateEffects)
     {
         switch (eff.Effect)
         {
             case ActivateEffects.BulletNova:
                 {
                     ProjectileDesc prjDesc = ability.Projectiles[0]; //Assume only one
                     var batch = new Packet[21];
                     uint s = Random.CurrentSeed;
                     Random.CurrentSeed = (uint)(s * time.tickTimes);
                     for (int i = 0; i < 20; i++)
                     {
                         Projectile proj = CreateProjectile(prjDesc, ability.AbilityType,
                             (int)statsMgr.GetAttackDamage(prjDesc.MinDamage, prjDesc.MaxDamage),
                             time.tickTimes, target, (float)(i * (Math.PI * 2) / 20));
                         Owner.EnterWorld(proj);
                         fames.Shoot(proj);
                         batch[i] = new ShootPacket
                         {
                             BulletId = proj.ProjectileId,
                             OwnerId = Id,
                             ContainerType = ability.AbilityType,
                             Position = target,
                             Angle = proj.Angle,
                             Damage = (short)proj.Damage,
                             FromAbility = true
                         };
                     }
                     Random.CurrentSeed = s;
                     batch[20] = new ShowEffectPacket
                     {
                         EffectType = EffectType.Trail,
                         PosA = target,
                         TargetId = Id,
                         Color = new ARGB(0xFFFF00AA)
                     };
                     BroadcastSync(batch, p => this.Dist(p) < 25);
                 } break;
             case ActivateEffects.Shoot:
                 {
                     ActivateAbilityShoot(time, ability, target);
                 } break;
         }
     }
     UpdateCount++;
 }
        public bool Activate(RealmTime time, Item item, UseItemPacket pkt)
        {
            bool endMethod = false;
            Position target = pkt.ItemUsePos;
            Mp -= item.MpCost;

            IContainer con = Owner.GetEntity(pkt.SlotObject.ObjectId) as IContainer;
            if (con == null) return true;

            if (pkt.SlotObject.SlotId != 255 && pkt.SlotObject.SlotId != 254 && con.Inventory[pkt.SlotObject.SlotId] != item)
            {
                Entity.logger.FatalFormat("Cheat engine detected for player {0},\nItem should be {1}, but its {2}.",
                    Name, Inventory[pkt.SlotObject.SlotId].ObjectId, item.ObjectId);
                foreach (Player player in Owner.Players.Values)
                    if (player.Client.Account.Rank >= 2)
                        player.SendInfo(String.Format("Cheat engine detected for player {0},\nItem should be {1}, but its {2}.",
                    Name, Inventory[pkt.SlotObject.SlotId].ObjectId, item.ObjectId));
                Client.Disconnect();
                return true;
            }

            if (item.IsBackpack)
            {
                if (HasBackpack) return true;
                Client.Character.Backpack = new[] { -1, -1, -1, -1, -1, -1, -1, -1 };
                HasBackpack = true;
                Client.Character.HasBackpack = 1;
                Manager.Database.DoActionAsync(db =>
                    db.SaveBackpacks(Client.Character, Client.Account));
                Array.Resize(ref inventory, 20);
                int[] slotTypes =
                    Utils.FromCommaSepString32(
                        Manager.GameData.ObjectTypeToElement[ObjectType].Element("SlotTypes").Value);
                Array.Resize(ref slotTypes, 20);
                for (int i = 0; i < slotTypes.Length; i++)
                    if (slotTypes[i] == 0) slotTypes[i] = 10;
                SlotTypes = slotTypes;
                return false;
            }
            if (item.XpBooster)
            {
                if (!XpBoosted)
                {
                    XpBoostTimeLeft = (float)item.Timer;
                    XpBoosted = item.XpBooster;
                    xpFreeTimer = (float)item.Timer == -1.0 ? false : true;
                    return false;
                }
                else
                {
                    SendInfo("You have already an active XP Booster.");
                    return true;
                }
            }

            if (item.LootDropBooster)
            {
                if (!LootDropBoost)
                {
                    LootDropBoostTimeLeft = (float)item.Timer;
                    lootDropBoostFreeTimer = (float)item.Timer == -1.0 ? false : true;
                    return false;
                }
                else
                {
                    SendInfo("You have already an active Loot Drop Booster.");
                    return true;
                }
            }

            if (item.LootTierBooster)
            {
                if (!LootTierBoost)
                {
                    LootTierBoostTimeLeft = (float)item.Timer;
                    lootTierBoostFreeTimer = (float)item.Timer == -1.0 ? false : true;
                    return false;
                }
                else
                {
                    SendInfo("You have already an active Loot Tier Booster.");
                    return true;
                }
            }

            foreach (ActivateEffect eff in item.ActivateEffects)
            {
                switch (eff.Effect)
                {
                    case ActivateEffects.BulletNova:
                        {
                            ProjectileDesc prjDesc = item.Projectiles[0]; //Assume only one
                            Packet[] batch = new Packet[21];
                            uint s = Random.CurrentSeed;
                            Random.CurrentSeed = (uint)(s * time.tickTimes);
                            for (int i = 0; i < 20; i++)
                            {
                                Projectile proj = CreateProjectile(prjDesc, item.ObjectType,
                                    (int)StatsManager.GetAttackDamage(prjDesc.MinDamage, prjDesc.MaxDamage),
                                    time.tickTimes, target, (float)(i * (Math.PI * 2) / 20));
                                Owner.EnterWorld(proj);
                                FameCounter.Shoot(proj);
                                batch[i] = new Shoot2Packet()
                                {
                                    BulletId = proj.ProjectileId,
                                    OwnerId = Id,
                                    ContainerType = item.ObjectType,
                                    StartingPos = target,
                                    Angle = proj.Angle,
                                    Damage = (short)proj.Damage
                                };
                            }
                            Random.CurrentSeed = s;
                            batch[20] = new ShowEffectPacket()
                            {
                                EffectType = EffectType.Trail,
                                PosA = target,
                                TargetId = Id,
                                Color = new ARGB(0xFFFF00AA)
                            };
                            BroadcastSync(batch, p => this.Dist(p) < 35);
                        }
                        break;

                    case ActivateEffects.Shoot:
                        {
                            ActivateShoot(time, item, target);
                        }
                        break;

                    case ActivateEffects.StatBoostSelf:
                        {
                            int idx = -1;

                            if (eff.Stats == StatsType.MaximumHP) idx = 0;
                            else if (eff.Stats == StatsType.MaximumMP) idx = 1;
                            else if (eff.Stats == StatsType.Attack) idx = 2;
                            else if (eff.Stats == StatsType.Defense) idx = 3;
                            else if (eff.Stats == StatsType.Speed) idx = 4;
                            else if (eff.Stats == StatsType.Vitality) idx = 5;
                            else if (eff.Stats == StatsType.Wisdom) idx = 6;
                            else if (eff.Stats == StatsType.Dexterity) idx = 7;

                            List<Packet> pkts = new List<Packet>();

                            ActivateBoostStat(this, idx, pkts);
                            int OGstat = oldstat;
                            int bit = idx + 39;

                            int s = eff.Amount;
                            Boost[idx] += s;
                            ApplyConditionEffect(new ConditionEffect
                            {
                                DurationMS = eff.DurationMS,
                                Effect = (ConditionEffectIndex)bit
                            });
                            UpdateCount++;
                            Owner.Timers.Add(new WorldTimer(eff.DurationMS, (world, t) =>
                            {
                                Boost[idx] = OGstat;
                                UpdateCount++;
                            }));
                            Owner.BroadcastPacket(new ShowEffectPacket
                            {
                                EffectType = EffectType.Potion,
                                TargetId = Id,
                                Color = new ARGB(0xffffffff)
                            }, null);
                        }
                        break;

                    case ActivateEffects.StatBoostAura:
                        {
                            int idx = -1;

                            if (eff.Stats == StatsType.MaximumHP) idx = 0;
                            if (eff.Stats == StatsType.MaximumMP) idx = 1;
                            if (eff.Stats == StatsType.Attack) idx = 2;
                            if (eff.Stats == StatsType.Defense) idx = 3;
                            if (eff.Stats == StatsType.Speed) idx = 4;
                            if (eff.Stats == StatsType.Vitality) idx = 5;
                            if (eff.Stats == StatsType.Wisdom) idx = 6;
                            if (eff.Stats == StatsType.Dexterity) idx = 7;

                            int bit = idx + 39;

                            var amountSBA = eff.Amount;
                            var durationSBA = eff.DurationMS;
                            var rangeSBA = eff.Range;
                            if (eff.UseWisMod)
                            {
                                amountSBA = (int)UseWisMod(eff.Amount, 0);
                                durationSBA = (int)(UseWisMod(eff.DurationSec) * 1000);
                                rangeSBA = UseWisMod(eff.Range);
                            }

                            this.Aoe(rangeSBA, true, player =>
                            {
                                // TODO support for noStack StatBoostAura attribute (paladin total
                                // hp increase / insta heal)
                                ApplyConditionEffect(new ConditionEffect
                                {
                                    DurationMS = durationSBA,
                                    Effect = (ConditionEffectIndex)bit
                                });
                                (player as Player).Boost[idx] += amountSBA;
                                player.UpdateCount++;
                                Owner.Timers.Add(new WorldTimer(durationSBA, (world, t) =>
                                {
                                    (player as Player).Boost[idx] -= amountSBA;
                                    player.UpdateCount++;
                                }));
                            });
                            BroadcastSync(new ShowEffectPacket()
                            {
                                EffectType = EffectType.AreaBlast,
                                TargetId = Id,
                                Color = new ARGB(0xffffffff),
                                PosA = new Position() { X = rangeSBA }
                            }, p => this.Dist(p) < 25);
                        }
                        break;

                    case ActivateEffects.ConditionEffectSelf:
                        {
                            var durationCES = eff.DurationMS;
                            if (eff.UseWisMod)
                                durationCES = (int)(UseWisMod(eff.DurationSec) * 1000);

                            var color = 0xffffffff;
                            switch (eff.ConditionEffect.Value)
                            {
                                case ConditionEffectIndex.Damaging:
                                    color = 0xffff0000;
                                    break;

                                case ConditionEffectIndex.Berserk:
                                    color = 0x808080;
                                    break;
                            }

                            ApplyConditionEffect(new ConditionEffect
                            {
                                Effect = eff.ConditionEffect.Value,
                                DurationMS = durationCES
                            });
                            Owner.BroadcastPacket(new ShowEffectPacket
                            {
                                EffectType = EffectType.AreaBlast,
                                TargetId = Id,
                                Color = new ARGB(color),
                                PosA = new Position { X = 2 }
                            }, null);
                        }
                        break;

                    case ActivateEffects.ConditionEffectAura:
                        {
                            var durationCEA = eff.DurationMS;
                            var rangeCEA = eff.Range;
                            if (eff.UseWisMod)
                            {
                                durationCEA = (int)(UseWisMod(eff.DurationSec) * 1000);
                                rangeCEA = UseWisMod(eff.Range);
                            }

                            this.Aoe(rangeCEA, true, player =>
                            {
                                player.ApplyConditionEffect(new ConditionEffect
                                {
                                    Effect = eff.ConditionEffect.Value,
                                    DurationMS = durationCEA
                                });
                            });

                            var color = 0xffffffff;
                            switch (eff.ConditionEffect.Value)
                            {
                                case ConditionEffectIndex.Damaging:
                                    color = 0xffff0000;
                                    break;

                                case ConditionEffectIndex.Berserk:
                                    color = 0x808080;
                                    break;
                            }

                            BroadcastSync(new ShowEffectPacket
                            {
                                EffectType = EffectType.AreaBlast,
                                TargetId = Id,
                                Color = new ARGB(color),
                                PosA = new Position { X = rangeCEA }
                            }, p => this.Dist(p) < 25);
                        }
                        break;

                    case ActivateEffects.Heal:
                        {
                            List<Packet> pkts = new List<Packet>();
                            ActivateHealHp(this, eff.Amount, pkts);
                            Owner.BroadcastPackets(pkts, null);
                        }
                        break;

                    case ActivateEffects.HealNova:
                        {
                            var amountHN = eff.Amount;
                            var rangeHN = eff.Range;
                            if (eff.UseWisMod)
                            {
                                amountHN = (int)UseWisMod(eff.Amount, 0);
                                rangeHN = UseWisMod(eff.Range);
                            }

                            List<Packet> pkts = new List<Packet>();
                            this.Aoe(rangeHN, true, player => { ActivateHealHp(player as Player, amountHN, pkts); });
                            pkts.Add(new ShowEffectPacket
                            {
                                EffectType = EffectType.AreaBlast,
                                TargetId = Id,
                                Color = new ARGB(0xffffffff),
                                PosA = new Position { X = rangeHN }
                            });
                            BroadcastSync(pkts, p => this.Dist(p) < 25);
                        }
                        break;

                    case ActivateEffects.Magic:
                        {
                            List<Packet> pkts = new List<Packet>();
                            ActivateHealMp(this, eff.Amount, pkts);
                            Owner.BroadcastPackets(pkts, null);
                        }
                        break;

                    case ActivateEffects.MagicNova:
                        {
                            List<Packet> pkts = new List<Packet>();
                            this.Aoe(eff.Range / 2, true, player => { ActivateHealMp(player as Player, eff.Amount, pkts); });
                            pkts.Add(new ShowEffectPacket
                            {
                                EffectType = EffectType.AreaBlast,
                                TargetId = Id,
                                Color = new ARGB(0xffffffff),
                                PosA = new Position { X = eff.Range }
                            });
                            Owner.BroadcastPackets(pkts, null);
                        }
                        break;

                    case ActivateEffects.Teleport:
                        {
                            Move(target.X, target.Y);
                            UpdateCount++;
                            Owner.BroadcastPackets(new Packet[]
                            {
                            new GotoPacket
                            {
                                ObjectId = Id,
                                Position = new Position
                                {
                                    X = X,
                                    Y = Y
                                }
                            },
                            new ShowEffectPacket
                            {
                                EffectType = EffectType.Teleport,
                                TargetId = Id,
                                PosA = new Position
                                {
                                    X = X,
                                    Y = Y
                                },
                                Color = new ARGB(0xFFFFFFFF)
                            }
                            }, null);
                        }
                        break;

                    case ActivateEffects.VampireBlast:
                        {
                            List<Packet> pkts = new List<Packet>();
                            pkts.Add(new ShowEffectPacket
                            {
                                EffectType = EffectType.Trail,
                                TargetId = Id,
                                PosA = target,
                                Color = new ARGB(0xFFFF0000)
                            });
                            pkts.Add(new ShowEffectPacket
                            {
                                EffectType = EffectType.Diffuse,
                                Color = new ARGB(0xFFFF0000),
                                TargetId = Id,
                                PosA = target,
                                PosB = new Position { X = target.X + eff.Radius, Y = target.Y }
                            });

                            int totalDmg = 0;
                            List<Enemy> enemies = new List<Enemy>();
                            Owner.Aoe(target, eff.Radius, false, enemy =>
                            {
                                enemies.Add(enemy as Enemy);
                                totalDmg += (enemy as Enemy).Damage(this, time, eff.TotalDamage, false);
                            });
                            List<Player> players = new List<Player>();
                            this.Aoe(eff.Radius, true, player =>
                            {
                                players.Add(player as Player);
                                ActivateHealHp(player as Player, totalDmg, pkts);
                            });

                            if (enemies.Count > 0)
                            {
                                Random rand = new Random();
                                for (int i = 0; i < 5; i++)
                                {
                                    Enemy a = enemies[rand.Next(0, enemies.Count)];
                                    Player b = players[rand.Next(0, players.Count)];
                                    pkts.Add(new ShowEffectPacket
                                    {
                                        EffectType = EffectType.Flow,
                                        TargetId = b.Id,
                                        PosA = new Position { X = a.X, Y = a.Y },
                                        Color = new ARGB(0xffffffff)
                                    });
                                }
                            }

                            BroadcastSync(pkts, p => this.Dist(p) < 25);
                        }
                        break;

                    case ActivateEffects.Trap:
                        {
                            BroadcastSync(new ShowEffectPacket
                            {
                                EffectType = EffectType.Throw,
                                Color = new ARGB(0xff9000ff),
                                TargetId = Id,
                                PosA = target
                            }, p => this.Dist(p) < 25);
                            Owner.Timers.Add(new WorldTimer(1500, (world, t) =>
                            {
                                Trap trap = new Trap(
                                    this,
                                    eff.Radius,
                                    eff.TotalDamage,
                                    eff.ConditionEffect ?? ConditionEffectIndex.Slowed,
                                    eff.EffectDuration);
                                trap.Move(target.X, target.Y);
                                world.EnterWorld(trap);
                            }));
                        }
                        break;

                    case ActivateEffects.StasisBlast:
                        {
                            List<Packet> pkts = new List<Packet>();

                            pkts.Add(new ShowEffectPacket
                            {
                                EffectType = EffectType.Concentrate,
                                TargetId = Id,
                                PosA = target,
                                PosB = new Position { X = target.X + 3, Y = target.Y },
                                Color = new ARGB(0xFF00D0)
                            });
                            Owner.Aoe(target, 3, false, enemy =>
                            {
                                if (IsSpecial(enemy.ObjectType)) return;
                                if (enemy.HasConditionEffect(ConditionEffectIndex.StasisImmune))
                                {
                                    if (!enemy.HasConditionEffect(ConditionEffectIndex.Invincible))
                                    {
                                        pkts.Add(new NotificationPacket
                                        {
                                            ObjectId = enemy.Id,
                                            Color = new ARGB(0xff00ff00),
                                            Text = "{\"key\":\"blank\",\"tokens\":{\"data\":\"Immune\"}}"
                                        });
                                    }
                                }
                                else if (!enemy.HasConditionEffect(ConditionEffectIndex.Stasis))
                                {
                                    enemy.ApplyConditionEffect(new ConditionEffect
                                    {
                                        Effect = ConditionEffectIndex.Stasis,
                                        DurationMS = eff.DurationMS
                                    });
                                    Owner.Timers.Add(new WorldTimer(eff.DurationMS, (world, t) =>
                                    {
                                        enemy.ApplyConditionEffect(new ConditionEffect
                                        {
                                            Effect = ConditionEffectIndex.StasisImmune,
                                            DurationMS = 3000
                                        });
                                    }));
                                    pkts.Add(new NotificationPacket
                                    {
                                        ObjectId = enemy.Id,
                                        Color = new ARGB(0xffff0000),
                                        Text = "{\"key\":\"blank\",\"tokens\":{\"data\":\"Stasis\"}}"
                                    });
                                }
                            });
                            BroadcastSync(pkts, p => this.Dist(p) < 25);
                        }
                        break;

                    case ActivateEffects.Decoy:
                        {
                            Decoy decoy = new Decoy(Manager, this, eff.DurationMS, StatsManager.GetSpeed());
                            decoy.Move(X, Y);
                            Owner.EnterWorld(decoy);
                        }
                        break;

                    case ActivateEffects.Lightning:
                        {
                            Enemy start = null;
                            double angle = Math.Atan2(target.Y - Y, target.X - X);
                            double diff = Math.PI / 3;
                            Owner.Aoe(target, 6, false, enemy =>
                            {
                                if (!(enemy is Enemy)) return;
                                double x = Math.Atan2(enemy.Y - Y, enemy.X - X);
                                if (Math.Abs(angle - x) < diff)
                                {
                                    start = enemy as Enemy;
                                    diff = Math.Abs(angle - x);
                                }
                            });
                            if (start == null)
                                break;

                            Enemy current = start;
                            Enemy[] targets = new Enemy[eff.MaxTargets];
                            for (int i = 0; i < targets.Length; i++)
                            {
                                targets[i] = current;
                                Enemy next = current.GetNearestEntity(8, false,
                                    enemy =>
                                        enemy is Enemy &&
                                        Array.IndexOf(targets, enemy) == -1 &&
                                        this.Dist(enemy) <= 6) as Enemy;

                                if (next == null) break;
                                current = next;
                            }

                            List<Packet> pkts = new List<Packet>();
                            for (int i = 0; i < targets.Length; i++)
                            {
                                if (targets[i] == null) break;
                                if (targets[i].HasConditionEffect(ConditionEffectIndex.Invincible)) continue;
                                Entity prev = i == 0 ? (Entity)this : targets[i - 1];
                                targets[i].Damage(this, time, eff.TotalDamage, false);
                                if (eff.ConditionEffect != null)
                                    targets[i].ApplyConditionEffect(new ConditionEffect
                                    {
                                        Effect = eff.ConditionEffect.Value,
                                        DurationMS = (int)(eff.EffectDuration * 1000)
                                    });
                                pkts.Add(new ShowEffectPacket
                                {
                                    EffectType = EffectType.Lightning,
                                    TargetId = prev.Id,
                                    Color = new ARGB(0xffff0088),
                                    PosA = new Position
                                    {
                                        X = targets[i].X,
                                        Y = targets[i].Y
                                    },
                                    PosB = new Position { X = 350 }
                                });
                            }
                            BroadcastSync(pkts, p => this.Dist(p) < 25);
                        }
                        break;

                    case ActivateEffects.PoisonGrenade:
                        {
                            try
                            {
                                BroadcastSync(new ShowEffectPacket
                                {
                                    EffectType = EffectType.Throw,
                                    Color = new ARGB(0xffddff00),
                                    TargetId = Id,
                                    PosA = target
                                }, p => this.Dist(p) < 25);
                                Placeholder x = new Placeholder(Manager, 1500);
                                x.Move(target.X, target.Y);
                                Owner.EnterWorld(x);
                                try
                                {
                                    Owner.Timers.Add(new WorldTimer(1500, (world, t) =>
                                    {
                                        world.BroadcastPacket(new ShowEffectPacket
                                        {
                                            EffectType = EffectType.AreaBlast,
                                            Color = new ARGB(0xffddff00),
                                            TargetId = x.Id,
                                            PosA = new Position { X = eff.Radius }
                                        }, null);
                                        world.Aoe(target, eff.Radius, false,
                                            enemy => PoisonEnemy(enemy as Enemy, eff));
                                    }));
                                }
                                catch (Exception ex)
                                {
                                    Entity.logger.ErrorFormat("Poison ShowEffect:\n{0}", ex);
                                }
                            }
                            catch (Exception ex)
                            {
                                Entity.logger.ErrorFormat("Poisons General:\n{0}", ex);
                            }
                        }
                        break;

                    case ActivateEffects.RemoveNegativeConditions:
                        {
                            this.Aoe(eff.Range / 2, true, player => { ApplyConditionEffect(NegativeEffs); });
                            BroadcastSync(new ShowEffectPacket
                            {
                                EffectType = EffectType.AreaBlast,
                                TargetId = Id,
                                Color = new ARGB(0xffffffff),
                                PosA = new Position { X = eff.Range / 2 }
                            }, p => this.Dist(p) < 25);
                        }
                        break;

                    case ActivateEffects.RemoveNegativeConditionsSelf:
                        {
                            ApplyConditionEffect(NegativeEffs);
                            Owner.BroadcastPacket(new ShowEffectPacket
                            {
                                EffectType = EffectType.AreaBlast,
                                TargetId = Id,
                                Color = new ARGB(0xffffffff),
                                PosA = new Position { X = 1 }
                            }, null);
                        }
                        break;

                    case ActivateEffects.IncrementStat:
                        {
                            int idx = -1;

                            if (eff.Stats == StatsType.MaximumHP) idx = 0;
                            else if (eff.Stats == StatsType.MaximumMP) idx = 1;
                            else if (eff.Stats == StatsType.Attack) idx = 2;
                            else if (eff.Stats == StatsType.Defense) idx = 3;
                            else if (eff.Stats == StatsType.Speed) idx = 4;
                            else if (eff.Stats == StatsType.Vitality) idx = 5;
                            else if (eff.Stats == StatsType.Wisdom) idx = 6;
                            else if (eff.Stats == StatsType.Dexterity) idx = 7;

                            Stats[idx] += eff.Amount;
                            int limit =
                                int.Parse(
                                    Manager.GameData.ObjectTypeToElement[ObjectType].Element(
                                        StatsManager.StatsIndexToName(idx))
                                        .Attribute("max")
                                        .Value);
                            if (Stats[idx] > limit)
                                Stats[idx] = limit;
                            UpdateCount++;
                        }
                        break;

                    case ActivateEffects.UnlockPortal:

                        Portal portal = this.GetNearestEntity(5, Manager.GameData.IdToObjectType[eff.LockedName]) as Portal;

                        Packet[] packets = new Packet[3];
                        packets[0] = new ShowEffectPacket
                        {
                            EffectType = EffectType.AreaBlast,
                            Color = new ARGB(0xFFFFFF),
                            PosA = new Position { X = 5 },
                            TargetId = Id
                        };
                        if (portal == null) break;

                        portal.Unlock(eff.DungeonName);

                        packets[1] = new NotificationPacket
                        {
                            Color = new ARGB(0x00FF00),
                            Text =
                                "{\"key\":\"blank\",\"tokens\":{\"data\":\"Unlocked by " +
                                Name + "\"}}",
                            ObjectId = Id
                        };

                        packets[2] = new TextPacket
                        {
                            BubbleTime = 0,
                            Stars = -1,
                            Name = "",
                            Text = eff.DungeonName + " Unlocked by " + Name + "."
                        };

                        BroadcastSync(packets);

                        break;

                    case ActivateEffects.Create: //this is a portal
                        {
                            ushort objType;
                            if (!Manager.GameData.IdToObjectType.TryGetValue(eff.Id, out objType) ||
                                !Manager.GameData.Portals.ContainsKey(objType))
                                break; // object not found, ignore
                            Entity entity = Resolve(Manager, objType);
                            World w = Manager.GetWorld(Owner.Id); //can't use Owner here, as it goes out of scope
                            int TimeoutTime = Manager.GameData.Portals[objType].TimeoutTime;
                            string DungName = Manager.GameData.Portals[objType].DungeonName;

                            ARGB c = new ARGB(0x00FF00);

                            entity.Move(X, Y);
                            w.EnterWorld(entity);

                            w.BroadcastPacket(new NotificationPacket
                            {
                                Color = c,
                                Text =
                                    "{\"key\":\"blank\",\"tokens\":{\"data\":\"" + DungName + " opened by " +
                                    Client.Account.Name + "\"}}",
                                ObjectId = Client.Player.Id
                            }, null);

                            w.BroadcastPacket(new TextPacket
                            {
                                BubbleTime = 0,
                                Stars = -1,
                                Name = "",
                                Text = DungName + " opened by " + Client.Account.Name
                            }, null);
                            w.Timers.Add(new WorldTimer(TimeoutTime * 1000,
                                (world, t) => //default portal close time * 1000
                            {
                                try
                                {
                                    w.LeaveWorld(entity);
                                }
                                catch (Exception ex)
                                //couldn't remove portal, Owner became null. Should be fixed with RealmManager implementation
                                {
                                    logger.ErrorFormat("Couldn't despawn portal.\n{0}", ex);
                                }
                            }));
                        }
                        break;

                    case ActivateEffects.Dye:
                        {
                            if (item.Texture1 != 0)
                            {
                                Texture1 = item.Texture1;
                            }
                            if (item.Texture2 != 0)
                            {
                                Texture2 = item.Texture2;
                            }
                            SaveToCharacter();
                        }
                        break;

                    case ActivateEffects.ShurikenAbility:
                        {
                            if (!ninjaShoot)
                            {
                                ApplyConditionEffect(new ConditionEffect
                                {
                                    Effect = ConditionEffectIndex.Speedy,
                                    DurationMS = -1
                                });
                                ninjaFreeTimer = true;
                                ninjaShoot = true;
                            }
                            else
                            {
                                ApplyConditionEffect(new ConditionEffect
                                {
                                    Effect = ConditionEffectIndex.Speedy,
                                    DurationMS = 0
                                });
                                ushort obj;
                                Manager.GameData.IdToObjectType.TryGetValue(item.ObjectId, out obj);
                                if (Mp >= item.MpEndCost)
                                {
                                    ActivateShoot(time, item, pkt.ItemUsePos);
                                    Mp -= (int)item.MpEndCost;
                                }
                                targetlink = target;
                                ninjaShoot = false;
                            }
                        }
                        break;

                    case ActivateEffects.UnlockSkin:
                        if (!Client.Account.OwnedSkins.Contains(item.ActivateEffects[0].SkinType))
                        {
                            Manager.Database.DoActionAsync(db =>
                            {
                                Client.Account.OwnedSkins.Add(item.ActivateEffects[0].SkinType);
                                MySqlCommand cmd = db.CreateQuery();
                                cmd.CommandText = "UPDATE accounts SET ownedSkins=@ownedSkins WHERE id=@id";
                                cmd.Parameters.AddWithValue("@ownedSkins",
                                    Utils.GetCommaSepString(Client.Account.OwnedSkins.ToArray()));
                                cmd.Parameters.AddWithValue("@id", AccountId);
                                cmd.ExecuteNonQuery();
                                SendInfo(
                                    "New skin unlocked successfully. Change skins in your Vault, or start a new character to use.");
                                Client.SendPacket(new UnlockedSkinPacket
                                {
                                    SkinID = item.ActivateEffects[0].SkinType
                                });
                            });
                            endMethod = false;
                            break;
                        }
                        SendInfo("Error.alreadyOwnsSkin");
                        endMethod = true;
                        break;

                    case ActivateEffects.PermaPet: //Doesnt exist anymore
                        {
                            //psr.Character.Pet = XmlDatas.IdToType[eff.ObjectId];
                            //GivePet(XmlDatas.IdToType[eff.ObjectId]);
                            //UpdateCount++;
                        }
                        break;

                    case ActivateEffects.Pet:
                        Entity en = Entity.Resolve(Manager, eff.ObjectId);
                        en.Move(X, Y);
                        en.SetPlayerOwner(this);
                        Owner.EnterWorld(en);
                        Owner.Timers.Add(new WorldTimer(30 * 1000, (w, t) =>
                        {
                            w.LeaveWorld(en);
                        }));
                        break;

                    case ActivateEffects.CreatePet:
                        if (!Owner.Name.StartsWith("Pet Yard"))
                        {
                            SendInfo("server.use_in_petyard");
                            return true;
                        }
                        Pet.Create(Manager, this, item);
                        break;

                    case ActivateEffects.MysteryPortal:
                        string[] dungeons = new[]
                        {
                            "Pirate Cave Portal",
                            "Forest Maze Portal",
                            "Spider Den Portal",
                            "Snake Pit Portal",
                            "Glowing Portal",
                            "Forbidden Jungle Portal",
                            "Candyland Portal",
                            "Haunted Cemetery Portal",
                            "Undead Lair Portal",
                            "Davy Jones' Locker Portal",
                            "Manor of the Immortals Portal",
                            "Abyss of Demons Portal",
                            "Lair of Draconis Portal",
                            "Mad Lab Portal",
                            "Ocean Trench Portal",
                            "Tomb of the Ancients Portal",
                            "Beachzone Portal",
                            "The Shatters",
                            "Deadwater Docks",
                            "Woodland Labyrinth",
                            "The Crawling Depths",
                            "Treasure Cave Portal",
                            "Battle Nexus Portal",
                            "Belladonna's Garden Portal",
                            "Lair of Shaitan Portal"
                        };

                        var descs = Manager.GameData.Portals.Where(_ => dungeons.Contains<string>(_.Value.ObjectId)).Select(_ => _.Value).ToArray();
                        var portalDesc = descs[Random.Next(0, descs.Count())];
                        Entity por = Entity.Resolve(Manager, portalDesc.ObjectId);
                        por.Move(this.X, this.Y);
                        Owner.EnterWorld(por);

                        Client.SendPacket(new NotificationPacket
                        {
                            Color = new ARGB(0x00FF00),
                            Text =
                                "{\"key\":\"blank\",\"tokens\":{\"data\":\"" + portalDesc.DungeonName + " opened by " +
                                Client.Account.Name + "\"}}",
                            ObjectId = Client.Player.Id
                        });

                        Owner.BroadcastPacket(new TextPacket
                        {
                            BubbleTime = 0,
                            Stars = -1,
                            Name = "",
                            Text = portalDesc.ObjectId + " opened by " + Name
                        }, null);

                        Owner.Timers.Add(new WorldTimer(portalDesc.TimeoutTime * 1000, (w, t) => //default portal close time * 1000
                        {
                            try
                            {
                                w.LeaveWorld(por);
                            }
                            catch (Exception ex)
                            {
                                Entity.logger.ErrorFormat("Couldn't despawn portal.\n{0}", ex);
                            }
                        }));
                        break;

                    case ActivateEffects.GenericActivate:
                        var targetPlayer = eff.Target.Equals("player");
                        var centerPlayer = eff.Center.Equals("player");
                        var duration = (eff.UseWisMod) ?
                            (int)(UseWisMod(eff.DurationSec) * 1000) :
                            eff.DurationMS;
                        var range = (eff.UseWisMod)
                            ? UseWisMod(eff.Range)
                            : eff.Range;

                        Owner.Aoe((eff.Center.Equals("mouse")) ? target : new Position { X = X, Y = Y }, range, targetPlayer, entity =>
                        {
                            if (IsSpecial(entity.ObjectType)) return;
                            if (!entity.HasConditionEffect(ConditionEffectIndex.Stasis) &&
                                !entity.HasConditionEffect(ConditionEffectIndex.Invincible))
                            {
                                entity.ApplyConditionEffect(
                                new ConditionEffect()
                                {
                                    Effect = eff.ConditionEffect.Value,
                                    DurationMS = duration
                                });
                            }
                        });

                        // replaced this last bit with what I had, never noticed any issue with it.
                        // Perhaps I'm wrong?
                        BroadcastSync(new ShowEffectPacket()
                        {
                            EffectType = (EffectType)eff.VisualEffect,
                            TargetId = Id,
                            Color = new ARGB(eff.Color ?? 0xffffffff),
                            PosA = centerPlayer ? new Position { X = range } : target,
                            PosB = new Position(target.X - range, target.Y)
                        }, p => this.DistSqr(p) < 25);
                        /*if (eff.VisualEffect > 0)
                        {
                            Placeholder x = null;
                            if (eff.Center == "mouse")
                            {
                                x = new Placeholder(Manager, 1500);
                                x.Move(pkt.ItemUsePos.X, pkt.ItemUsePos.Y);
                                Owner.EnterWorld(x);
                            }
                            BroadcastSync(new ShowEffectPacket
                            {
                                EffectType = EffectType.AreaBlast,
                                TargetId = x?.Id ?? Id,
                                Color = new ARGB(eff.Color ?? 0xffffffff),
                                PosA = new Position {X = eff.VisualEffect/2},
                            }, p => this.Dist(p) < 25);
                        }*/
                        break;
                }
            }
            UpdateCount++;
            return endMethod;
        }
예제 #3
0
        private bool Activate(RealmTime time, Item item, ItemData data, int itemSlot, Position target)
        {
            if (MP < item.MpCost)
                return false;
            MP -= item.MpCost;
            bool success = true;
            foreach (ActivateEffect eff in item.ActivateEffects)
            {
                switch (eff.Effect)
                {
                    case ActivateEffects.BulletNova:
                    {
                        ProjectileDesc prjDesc = item.Projectiles[0]; //Assume only one
                        var batch = new Packet[21];
                        uint s = Random.CurrentSeed;
                        Random.CurrentSeed = (uint) (s*time.tickTimes);
                        for (int i = 0; i < 20; i++)
                        {
                            Projectile proj = CreateProjectile(prjDesc, item.ObjectType,
                                (int) statsMgr.GetAttackDamage(prjDesc.MinDamage, prjDesc.MaxDamage),
                                time.tickTimes, target, (float) (i*(Math.PI*2)/20));
                            Owner.EnterWorld(proj);
                            fames.Shoot(proj);
                            batch[i] = new ShootPacket
                            {
                                BulletId = proj.ProjectileId,
                                OwnerId = Id,
                                ContainerType = item.ObjectType,
                                Position = target,
                                Angle = proj.Angle,
                                Damage = (short) proj.Damage,
                                FromAbility = false
                            };
                        }
                        Random.CurrentSeed = s;
                        batch[20] = new ShowEffectPacket
                        {
                            EffectType = EffectType.Trail,
                            PosA = target,
                            TargetId = Id,
                            Color = new ARGB(0xFFFF00AA)
                        };
                        BroadcastSync(batch, p => this.Dist(p) < 25);
                    }
                        break;
                    case ActivateEffects.Shoot:
                    {
                        ActivateShoot(time, item, target);
                    }
                        break;
                    case ActivateEffects.StatBoostSelf:
                    {
                        var idx = -1;
                        switch ((StatsType) eff.Stats)
                        {
                            case StatsType.MaximumHP: idx = 0; break;
                            case StatsType.MaximumMP: idx = 1; break;
                            case StatsType.Attack: idx = 2; break;
                            case StatsType.Defense: idx = 3; break;
                            case StatsType.Speed: idx = 4; break;
                            case StatsType.Vitality: idx = 5; break;
                            case StatsType.Wisdom: idx = 6; break;
                            case StatsType.Dexterity: idx = 7; break;
                        }
                        var s = eff.Amount;
                        ActivateBoost[idx].Push(s);
                        CalculateBoost();
                        (this as Player).UpdateCount++;
                        Owner.Timers.Add(new WorldTimer(eff.DurationMS, (world, t) =>
                        {
                            ActivateBoost[idx].Pop(s);
                            CalculateBoost();
                            (this as Player).UpdateCount++;
                        }));
                        BroadcastSync(new ShowEffectPacket
                        {
                            EffectType = EffectType.Potion,
                            TargetId = Id,
                            Color = new ARGB(0xffffffff)
                        }, p => this.Dist(p) < 25);
                    }
                        break;
                    case ActivateEffects.StatBoostAura:
                    {
                        int idx = -1;
                        switch ((StatsType) eff.Stats)
                        {
                            case StatsType.MaximumHP: idx = 0; break;
                            case StatsType.MaximumMP: idx = 1; break;
                            case StatsType.Attack: idx = 2; break;
                            case StatsType.Defense: idx = 3; break;
                            case StatsType.Speed: idx = 4; break;
                            case StatsType.Vitality: idx = 5; break;
                            case StatsType.Wisdom: idx = 6; break;
                            case StatsType.Dexterity: idx = 7; break;
                        }
                        int s = eff.Amount;
                        this.AOE(eff.Range, true, player =>
                        {
                            var plr = (player as Player);
                            if (PvP && (plr.Team == 0 || plr.Team != Team) && plr != this)
                                return;
                            ActivateBoost[idx].Push(s);
                            CalculateBoost();
                            player.UpdateCount++;
                            Owner.Timers.Add(new WorldTimer(eff.DurationMS, (world, t) =>
                            {
                                ActivateBoost[idx].Pop(s);
                                CalculateBoost();
                                player.UpdateCount++;
                            }));
                        });
                        BroadcastSync(new ShowEffectPacket
                        {
                            EffectType = EffectType.AreaBlast,
                            TargetId = Id,
                            Color = new ARGB(0xffffffff),
                            PosA = new Position {X = eff.Range}
                        }, p => this.Dist(p) < 25);
                    }
                        break;
                    case ActivateEffects.ConditionEffectSelf:
                    {
                        ApplyConditionEffect(new ConditionEffect
                        {
                            Effect = eff.ConditionEffect.Value,
                            DurationMS = eff.DurationMS
                        });
                        BroadcastSync(new ShowEffectPacket
                        {
                            EffectType = EffectType.AreaBlast,
                            TargetId = Id,
                            Color = new ARGB(0xffffffff),
                            PosA = new Position {X = 1}
                        }, p => this.Dist(p) < 25);
                    }
                        break;
                    case ActivateEffects.ConditionEffectAura:
                    {
                        this.AOE(eff.Range, true, player =>
                        {
                            var plr = (player as Player);
                            if (PvP && (plr.Team == 0 || plr.Team != Team) && plr != this)
                                return;
                            player.ApplyConditionEffect(new ConditionEffect
                            {
                                Effect = eff.ConditionEffect.Value,
                                DurationMS = eff.DurationMS
                            });
                        });
                        uint color = 0xffffffff;
                        if (eff.ConditionEffect.Value == ConditionEffectIndex.Damaging)
                            color = 0xffff0000;
                        BroadcastSync(new ShowEffectPacket
                        {
                            EffectType = EffectType.AreaBlast,
                            TargetId = Id,
                            Color = new ARGB(color),
                            PosA = new Position {X = eff.Range}
                        }, p => this.Dist(p) < 25);
                    }
                        break;
                    case ActivateEffects.Heal:
                    {
                        var pkts = new List<Packet>();
                        ActivateHealHp(this, this, eff.Amount, pkts);
                        BroadcastSync(pkts, p => this.Dist(p) < 25);
                    }
                        break;
                    case ActivateEffects.HealNova:
                    {
                        var pkts = new List<Packet>();
                        this.AOE(eff.Range, true,
                            player => { ActivateHealHp(player as Player, this, eff.Amount, pkts); });
                        pkts.Add(new ShowEffectPacket
                        {
                            EffectType = EffectType.AreaBlast,
                            TargetId = Id,
                            Color = new ARGB(0xffffffff),
                            PosA = new Position {X = eff.Range}
                        });
                        BroadcastSync(pkts, p => this.Dist(p) < 25);
                    }
                        break;
                    case ActivateEffects.Magic:
                    {
                        var pkts = new List<Packet>();
                        ActivateHealMp(this, this, eff.Amount, pkts);
                        BroadcastSync(pkts, p => this.Dist(p) < 25);
                    }
                        break;
                    case ActivateEffects.MagicNova:
                    {
                        var pkts = new List<Packet>();
                        this.AOE(eff.Range, true,
                            player => { ActivateHealMp(player as Player, this, eff.Amount, pkts); });
                        pkts.Add(new ShowEffectPacket
                        {
                            EffectType = EffectType.AreaBlast,
                            TargetId = Id,
                            Color = new ARGB(0xffffffff),
                            PosA = new Position {X = eff.Range}
                        });
                        BroadcastSync(pkts, p => this.Dist(p) < 25);
                    }
                        break;
                    case ActivateEffects.Teleport:
                    {
                        if (!Owner.AllowAbilityTeleport)
                        {
                            SendError("Teleporting is disabled.");
                            break;
                        }
                        Move(target.X, target.Y);
                        UpdateCount++;
                        Owner.BroadcastPacket(new GotoPacket
                        {
                            ObjectId = Id,
                            Position = new Position
                            {
                                X = X,
                                Y = Y
                            }
                        }, null);
                        foreach (Player i in Owner.Players.Values)
                            if (this.Dist(i) < 25)
                                if ((PvP && i.Team != 0 && i.Team == Team) || !PvP)
                                    i.Client.SendPackets(new Packet[]
                                    {
                                        new ShowEffectPacket
                                        {
                                            EffectType = EffectType.Teleport,
                                            TargetId = Id,
                                            PosA = new Position
                                            {
                                                X = X,
                                                Y = Y
                                            },
                                            Color = new ARGB(0xFFFFFFFF)
                                        }
                                    });
                    }
                        break;
                    case ActivateEffects.VampireBlast:
                    {
                        var pkts = new List<Packet>();
                        pkts.Add(new ShowEffectPacket
                        {
                            EffectType = EffectType.Trail,
                            TargetId = Id,
                            PosA = target,
                            Color = new ARGB(0xFFFF0000)
                        });
                        pkts.Add(new ShowEffectPacket
                        {
                            EffectType = EffectType.Diffuse,
                            TargetId = Id,
                            PosA = target,
                            PosB = new Position {X = target.X + eff.Radius, Y = target.Y},
                            Color = new ARGB(0xFFFF0000)
                        });
                        BroadcastSync(pkts, p => this.Dist(p) < 25);

                        pkts = new List<Packet>();

                        int totalDmg = 0;
                        var enemies = new List<Entity>();
                        var targets = new List<Player>();
                        Owner.AOE(target, eff.Radius, false, enemy =>
                        {
                            enemies.Add(enemy);
                            totalDmg += (enemy as Enemy).Damage(this, time, eff.TotalDamage, false, false, null);
                            pkts.Add(new DamagePacket
                            {
                                BulletId = 0,
                                ObjectId = Id,
                                TargetId = enemy.Id,
                                Effects = 0,
                                Damage = (ushort) eff.TotalDamage,
                                Killed = (enemy as Enemy).HP <= 0
                            });
                        });
                        if (PvP)
                        {
                            Owner.AOE(target, eff.Radius, true, enemy =>
                            {
                                var plr = (enemy as Player);
                                if (!plr.PvP || (plr.PvP && plr.Team != 0 && plr.Team == Team) || plr == this)
                                    return;
                                enemies.Add(enemy);
                                (enemy as Player).Damage(eff.TotalDamage, enemy as Character, false, true, 0.20f);
                                totalDmg +=
                                    (int)
                                        Math.Max(1, (enemy as Player).statsMgr.GetDefenseDamage(eff.TotalDamage, false) * 0.20);
                            });
                        }
                        var players = new List<Player>();

                        this.AOE(eff.Radius, true, player =>
                        {
                            var plr = (player as Player);
                            if (PvP && (plr.Team == 0 || plr.Team != Team) && plr != this)
                                return;
                            players.Add(player as Player);
                            ActivateHealHp(player as Player, this, totalDmg, pkts);
                        });

                        var rand = new Random();
                        for (int i = 0; i < 5; i++)
                        {
                            Entity a = enemies[rand.Next(0, enemies.Count)];
                            Player b = players[rand.Next(0, players.Count)];
                            pkts.Add(new ShowEffectPacket
                            {
                                EffectType = EffectType.Flow,
                                TargetId = b.Id,
                                PosA = new Position {X = a.X, Y = a.Y},
                                Color = new ARGB(0xffffffff)
                            });
                        }

                        BroadcastSync(pkts, p => this.Dist(p) < 25);
                    }
                        break;
                    case ActivateEffects.Trap:
                    {
                        BroadcastSync(new ShowEffectPacket
                        {
                            EffectType = EffectType.Throw,
                            Color = new ARGB(0xff9000ff),
                            TargetId = Id,
                            PosA = target
                        }, p => this.Dist(p) < 25);
                        Owner.Timers.Add(new WorldTimer(1500, (world, t) =>
                        {
                            var trap = new Trap(
                                this,
                                eff.Radius,
                                eff.TotalDamage,
                                eff.ConditionEffect ?? ConditionEffectIndex.Slowed,
                                eff.EffectDuration);
                            trap.Move(target.X, target.Y);
                            world.EnterWorld(trap);
                        }));
                    }
                        break;
                    case ActivateEffects.StasisBlast:
                    {
                        var pkts = new List<Packet>();

                        pkts.Add(new ShowEffectPacket
                        {
                            EffectType = EffectType.Concentrate,
                            TargetId = Id,
                            PosA = target,
                            PosB = new Position {X = target.X + 3, Y = target.Y},
                            Color = new ARGB(0xffffffff)
                        });
                        Owner.AOE(target, 3, false, enemy =>
                        {
                            if (enemy.HasConditionEffect(ConditionEffects.StasisImmune))
                            {
                                pkts.Add(new NotificationPacket
                                {
                                    ObjectId = enemy.Id,
                                    Color = new ARGB(0xff00ff00),
                                    Text = "Immune"
                                });
                            }
                            else if (!enemy.HasConditionEffect(ConditionEffects.Stasis))
                            {
                                enemy.ApplyConditionEffect(
                                    new ConditionEffect
                                    {
                                        Effect = ConditionEffectIndex.Stasis,
                                        DurationMS = eff.DurationMS
                                    },
                                    new ConditionEffect
                                    {
                                        Effect = ConditionEffectIndex.Paused,
                                        DurationMS = eff.DurationMS
                                    },
                                    new ConditionEffect
                                    {
                                        Effect = ConditionEffectIndex.Confused,
                                        DurationMS = eff.DurationMS
                                    }
                                    );
                            }
                            Owner.Timers.Add(new WorldTimer(eff.DurationMS, (world, t) => enemy.ApplyConditionEffect(new ConditionEffect
                            {
                                Effect = ConditionEffectIndex.StasisImmune,
                                DurationMS = 3000
                            })));
                            pkts.Add(new NotificationPacket
                            {
                                ObjectId = enemy.Id,
                                Color = new ARGB(0xffff0000),
                                Text = "Stasis"
                            });
                        });
                        if (PvP)
                        {
                            Owner.AOE(target, 3, true, enemy =>
                            {
                                var plr = (enemy as Player);
                                if (!plr.PvP || (plr.PvP && plr.Team != 0 && plr.Team == Team) || plr == this)
                                    return;
                                if (enemy.HasConditionEffect(ConditionEffects.StasisImmune))
                                {
                                    pkts.Add(new NotificationPacket
                                    {
                                        ObjectId = enemy.Id,
                                        Color = new ARGB(0xff00ff00),
                                        Text = "Immune"
                                    });
                                }
                                else if (!enemy.HasConditionEffect(ConditionEffects.Stasis))
                                {
                                    if (enemy is Player && Owner.PvP)
                                    {
                                        if (enemy.Id == Id)
                                            return;
                                        enemy.ApplyConditionEffect(
                                            new ConditionEffect
                                            {
                                                Effect = ConditionEffectIndex.Stasis,
                                                DurationMS = eff.DurationMS
                                            },
                                            new ConditionEffect
                                            {
                                                Effect = ConditionEffectIndex.Paused,
                                                DurationMS = eff.DurationMS
                                            },
                                            new ConditionEffect
                                            {
                                                Effect = ConditionEffectIndex.Confused,
                                                DurationMS = eff.DurationMS
                                            }
                                            );
                                    }
                                    Owner.Timers.Add(new WorldTimer(eff.DurationMS, (world, t) => enemy.ApplyConditionEffect(new ConditionEffect
                                    {
                                        Effect = ConditionEffectIndex.StasisImmune,
                                        DurationMS = 3000
                                    })));
                                    pkts.Add(new NotificationPacket
                                    {
                                        ObjectId = enemy.Id,
                                        Color = new ARGB(0xffff0000),
                                        Text = "Stasis"
                                    });
                                }
                            });
                        }
                        BroadcastSync(pkts, p => this.Dist(p) < 25);
                    }
                        break;
                    case ActivateEffects.Decoy:
                    {
                        var decoy = new Decoy(this, eff.DurationMS, statsMgr.GetSpeed());
                        decoy.Move(X, Y);
                        Owner.EnterWorld(decoy);
                    }
                        break;
                    case ActivateEffects.Lightning:
                    {
                        if (!PvP)
                        {
                            Enemy start = null;
                            double angle = Math.Atan2(target.Y - Y, target.X - X);
                            double diff = Math.PI/3;
                            Owner.AOE(target, 6, false, enemy =>
                            {
                                if (!(enemy is Enemy)) return;
                                double x = Math.Atan2(enemy.Y - Y, enemy.X - X);
                                if (Math.Abs(angle - x) < diff)
                                {
                                    start = enemy as Enemy;
                                    diff = Math.Abs(angle - x);
                                }
                            });
                            if (start == null)
                                break;

                            Enemy current = start;
                            var targets = new Enemy[eff.MaxTargets];
                            for (int i = 0; i < targets.Length; i++)
                            {
                                targets[i] = current;
                                var next = current.GetNearestEntity(8, false,
                                    enemy =>
                                        enemy is Enemy &&
                                        Array.IndexOf(targets, enemy) == -1 &&
                                        this.Dist(enemy) <= 6) as Enemy;

                                if (next == null) break;
                                current = next;
                            }

                            var pkts = new List<Packet>();
                            for (int i = 0; i < targets.Length; i++)
                            {
                                if (targets[i] == null) break;
                                Entity prev = i == 0 ? (Entity) this : targets[i - 1];
                                targets[i].Damage(this, time, eff.TotalDamage, false, false, null);
                                if (eff.ConditionEffect != null)
                                    targets[i].ApplyConditionEffect(new ConditionEffect
                                    {
                                        Effect = eff.ConditionEffect.Value,
                                        DurationMS = (int) (eff.EffectDuration*1000)
                                    });
                                pkts.Add(new ShowEffectPacket
                                {
                                    EffectType = EffectType.Lightning,
                                    TargetId = prev.Id,
                                    Color = new ARGB(0xffff0088),
                                    PosA = new Position
                                    {
                                        X = targets[i].X,
                                        Y = targets[i].Y
                                    },
                                    PosB = new Position {X = 350}
                                });
                            }
                            BroadcastSync(pkts, p => this.Dist(p) < 25);
                        }
                        if (PvP)
                        {
                            Player start = null;
                            double angle = Math.Atan2(target.Y - Y, target.X - X);
                            double diff = Math.PI/3;
                            Owner.AOE(target, 6, true, enemy =>
                            {
                                //if (!(enemy is Player)) return;
                                var plr = (enemy as Player);
                                if (!plr.PvP || (plr.PvP && plr.Team != 0 && plr.Team == Team) || plr == this)
                                    return;
                                double x = Math.Atan2(enemy.Y - Y, enemy.X - X);
                                if (Math.Abs(angle - x) < diff)
                                {
                                    start = enemy as Player;
                                    diff = Math.Abs(angle - x);
                                }
                            });
                            if (start == null)
                                break;

                            Player current = start;
                            var targets = new Player[eff.MaxTargets];
                            for (int i = 0; i < targets.Length; i++)
                            {
                                targets[i] = current;
                                var next = current.GetNearestEntity(8, true,
                                    enemy =>
                                        enemy is Player && enemy.Id != Id &&
                                        Array.IndexOf(targets, enemy) == -1 &&
                                        (enemy as Player).PvP &&
                                        ((enemy as Player).Team == 0 || (enemy as Player).Team != Team) &&
                                        this.Dist(enemy) <= 6) as Player;

                                if (next == null) break;
                                current = next;
                            }

                            var pkts = new List<Packet>();
                            for (int i = 0; i < targets.Length; i++)
                            {
                                if (targets[i] == null) break;
                                Entity prev = i == 0 ? this : targets[i - 1];
                                targets[i].Damage(eff.TotalDamage, targets[i], false, true, 0.20f);
                                if (eff.ConditionEffect != null)
                                    targets[i].ApplyConditionEffect(new ConditionEffect
                                    {
                                        Effect = eff.ConditionEffect.Value,
                                        DurationMS = (int) (eff.EffectDuration*1000)
                                    });
                                pkts.Add(new ShowEffectPacket
                                {
                                    EffectType = EffectType.Lightning,
                                    TargetId = prev.Id,
                                    Color = new ARGB(0xffff0088),
                                    PosA = new Position
                                    {
                                        X = targets[i].X,
                                        Y = targets[i].Y
                                    },
                                    PosB = new Position {X = 350}
                                });
                            }
                            BroadcastSync(pkts, p => this.Dist(p) < 25);
                        }
                    }
                        break;
                    case ActivateEffects.PoisonGrenade:
                    {
                        BroadcastSync(new ShowEffectPacket
                        {
                            EffectType = EffectType.Throw,
                            Color = new ARGB(0xffddff00),
                            TargetId = Id,
                            PosA = target
                        }, p => this.Dist(p) < 25);
                        var x = new Placeholder(Manager, 1500);
                        x.Move(target.X, target.Y);
                        Owner.EnterWorld(x);
                        Owner.Timers.Add(new WorldTimer(1500, (world, t) =>
                        {
                            if (Owner != null)
                            {
                                Owner.BroadcastPacket(new ShowEffectPacket
                                {
                                    EffectType = EffectType.AreaBlast,
                                    TargetId = x.Id,
                                    Color = new ARGB(0xffddff00),
                                    PosA = new Position { X = eff.Radius }
                                }, null);
                                if (PvP)
                                {
                                    var players = new List<Player>();
                                    Owner.AOE(target, eff.Radius, true,
                                        enemy =>
                                        {
                                            var plr = (enemy as Player);
                                            if (!plr.PvP || (plr.PvP && plr.Team != 0 && plr.Team == Team) || plr == this)
                                                return;
                                            players.Add(enemy as Player);
                                            foreach (Player i in players)
                                                if (i.Id != Id)
                                                    PoisonPlayer(i, eff);
                                        });
                                }
                                var enemies = new List<Enemy>();
                                Owner.AOE(target, eff.Radius, false,
                                    enemy => PoisonEnemy(enemy as Enemy, eff));
                            }
                        }));
                    }
                        break;
                    case ActivateEffects.RemoveNegativeConditions:
                    {
                        this.AOE(eff.Range, true, player =>
                        {
                            var plr = (player as Player);
                            if (PvP && (plr.Team == 0 || plr.Team != Team) && plr != this)
                                return;
                            ApplyConditionEffect(NegativeEffs);
                        });
                        BroadcastSync(new ShowEffectPacket
                        {
                            EffectType = EffectType.AreaBlast,
                            TargetId = Id,
                            Color = new ARGB(0xffffffff),
                            PosA = new Position {X = eff.Range}
                        }, p => this.Dist(p) < 25);
                    }
                        break;
                    case ActivateEffects.RemoveNegativeConditionsSelf:
                    {
                        ApplyConditionEffect(NegativeEffs);
                        BroadcastSync(new ShowEffectPacket
                        {
                            EffectType = EffectType.AreaBlast,
                            TargetId = Id,
                            Color = new ARGB(0xffffffff),
                            PosA = new Position {X = 1}
                        }, p => this.Dist(p) < 25);
                    }
                        break;
                    case ActivateEffects.IncrementStat:
                    {
                        int idx = -1;
                        switch ((StatsType) eff.Stats)
                        {
                            case StatsType.MaximumHP:
                                idx = 0;
                                break;
                            case StatsType.MaximumMP:
                                idx = 1;
                                break;
                            case StatsType.Attack:
                                idx = 2;
                                break;
                            case StatsType.Defense:
                                idx = 3;
                                break;
                            case StatsType.Speed:
                                idx = 4;
                                break;
                            case StatsType.Vitality:
                                idx = 5;
                                break;
                            case StatsType.Wisdom:
                                idx = 6;
                                break;
                            case StatsType.Dexterity:
                                idx = 7;
                                break;
                        }
                        if (eff.Amount > 0)
                            Stats[idx] += eff.Amount;
                        else
                            Stats[idx] -= eff.Amount;
                        int limit =
                            int.Parse(
                                Manager.GameData.ObjectTypeToElement[ObjectType].Element(
                                    StatsManager.StatsIndexToName(idx)).Attribute("max").Value);
                        if (Stats[idx] > limit)
                            Stats[idx] = limit;
                        UpdateCount++;
                    }
                        break;
                    case ActivateEffects.Create: //this is a portal
                    {
                        ushort objType;
                        if (!Manager.GameData.IdToObjectType.TryGetValue(eff.Id, out objType) ||
                            !Manager.GameData.Portals.ContainsKey(objType))
                            break; // object not found, ignore
                        Entity entity = Resolve(Manager, objType);
                        entity.Move(X, Y);
                        int TimeoutTime = Manager.GameData.Portals[objType].TimeoutTime;
                        string DungeonName = Manager.GameData.Portals[objType].DungeonName;

                        Owner.EnterWorld(entity);
                        World w = Manager.GetWorld(Owner.Id); //can't use Owner here, as it goes out of scope

                        Client.SendPacket(new NotificationPacket
                        {
                            Color = new ARGB(0xff00ff00),
                            Text = "Opened by " + Client.Account.Name,
                            ObjectId = Client.Player.Id,
                        });
                        w.BroadcastPacket(new TextPacket
                        {
                            BubbleTime = 0,
                            Stars = -1,
                            Name = "",
                            Text = DungeonName + " opened by " + Client.Account.Name
                        }, null);

                        w.Timers.Add(new WorldTimer(TimeoutTime*1000, (world, t) => //default portal close time * 1000
                        {
                            try
                            {
                                w.LeaveWorld(entity);
                            }
                            catch
                                //couldn't remove portal, Owner became null. Should be fixed with RealmManager implementation
                            {
                                Console.WriteLine("Couldn't despawn portal.");
                            }
                        }));
                    }
                        break;
                    case ActivateEffects.PermaPet:
                        client.Character.Pet = Manager.GameData.IdToObjectType[eff.ObjectId];
                        GivePet(Manager.GameData.IdToObjectType[eff.ObjectId]);
                        UpdateCount++;
                        break;
                    case ActivateEffects.UnlockPortal:
                        break;
                    case ActivateEffects.Dye:
                        if (item.Texture1 != 0)
                        {
                            Texture1 = item.Texture1;
                        }
                        if (item.Texture2 != 0)
                        {
                            Texture2 = item.Texture2;
                        }
                        SaveToCharacter();
                        break;
                    case ActivateEffects.UnlockSkin:
                        if (Manager.GameData.Skins.ContainsKey((ushort) eff.SkinType))
                        {
                            SkinDesc skin = Manager.GameData.Skins[(ushort) eff.SkinType];
                            if (skin.PlayerClassType == -1 || skin.PlayerClassType == ObjectType)
                            {
                                Skin = eff.SkinType;
                                PermaSkin = !item.Consumable || (data != null ? data.MultiUse : false);
                                if (data != null && data.Effect != "")
                                {
                                    Effect = (data.FullEffect == "" ? UnusualEffects.Save(data.Effect) : data.FullEffect);
                                }
                                else
                                {
                                    Effect = "";
                                }
                                SendInfo("Successfully changed skin.");
                            }
                            else
                            {
                                success = false;
                                SendError("Your class cannot use this skin.");
                            }
                        }
                        else
                        {
                            success = false;
                            SendError("Invalid skin type.");
                        }
                        break;
                    case ActivateEffects.ShurikenAbility:
                    {
                        usingShuriken = !usingShuriken;
                        if (usingShuriken)
                        {
                            ApplyConditionEffect(new ConditionEffect
                            {
                                Effect = ConditionEffectIndex.Speedy,
                                DurationMS = -1
                            });
                        }
                        else
                        {
                            ApplyConditionEffect(new ConditionEffect
                            {
                                Effect = ConditionEffectIndex.Speedy,
                                DurationMS = 0
                            });
                            if (MP >= item.MpEndCost)
                            {
                                MP -= item.MpEndCost;
                                ActivateShoot(time, item, target);
                            }
                        }
                    }
                        break;
                    case ActivateEffects.SwitchMusic:
                        {
                            Client.SendPacket(new SwitchMusicPacket
                            {
                                Music = eff.Id
                            });
                        } break;
                    case ActivateEffects.OpenCrate:
                        {
                            success = false;
                            try
                            {
                                this.ItemSelect((_item, _data) =>
                                {
                                    return _item.IsCrate;
                                }, _slot =>
                                {
                                    bool succeeded = false;
                                    for (int i = 0; i < Inventory.Length; i++)
                                    {
                                        if (Inventory[i] == null) continue;
                                        if (Inventory[i].ObjectId == "Supply Crate Key")
                                        {
                                            Inventory[i] = null;
                                            Inventory.Data[i] = null;
                                            succeeded = true;
                                            break;
                                        }
                                    }
                                    if (succeeded)
                                    {
                                        Item originalItem = Inventory[_slot];
                                        Random rand1 = new Random();

                                        int choice = rand1.Next(1, 101);
                                        if (choice > 20 && !originalItem.UnusualCrate)
                                        {
                                            if (rand1.Next(0,5) != 0)
                                            {
                                                int[] types = new int[] { 1, 2, 3, 8, 17, 24 };
                                                List<Item> candidates = Manager.GameData.Items
                                                    .Where(_item => Array.IndexOf(types, _item.Value.SlotType) != -1)
                                                    .Where(_item => _item.Value.Tier == rand1.Next(8, 11 + 1))
                                                    .Select(_item => _item.Value)
                                                    .ToList();

                                                candidates.Shuffle();

                                                Inventory[_slot] = Manager.GameData.Items[Manager.GameData.IdToObjectType["Strangifier"]];
                                                Inventory.Data[_slot] = new ItemData
                                                {
                                                    NamePrefix = candidates[0].ObjectId,
                                                    NameColor = 0xFF5A28
                                                };
                                            }
                                            else
                                            {
                                                List<string> Parts = new List<string>(){
                                                    "God Kills",
                                                    "Quest Kills",
                                                    "Oryx Kills",
                                                    "Kills While Cloaked",
                                                    "Kills Near Death"
                                                };
                                                Parts.Shuffle();

                                                Inventory[_slot] = Manager.GameData.Items[Manager.GameData.IdToObjectType["Strange Part"]];
                                                Inventory.Data[_slot] = new ItemData
                                                {
                                                    NamePrefix = Parts[0]
                                                };
                                            }
                                        }
                                        else
                                        {
                                            List<Item> candidates = Manager.GameData.Items
                                                .Where(_item =>
                                                {
                                                    foreach (var activEff in _item.Value.ActivateEffects)
                                                        if (activEff.Effect == ActivateEffects.UnlockSkin)
                                                            return true;
                                                    return false;
                                                })
                                                .Where(_item =>
                                                {
                                                    if (originalItem.Premium && !_item.Value.Premium)
                                                        return false;
                                                    if (!originalItem.Premium && _item.Value.Premium)
                                                        return false;
                                                    return true;
                                                })
                                                .Select(_item => _item.Value)
                                                .ToList();

                                            candidates.Shuffle();

                                            Inventory[_slot] = candidates[0];
                                            Inventory.Data[_slot] = null;

                                            if (rand1.Next(0, 6) == 0 || originalItem.UnusualCrate)
                                            {
                                                List<string> effects = new List<string>();
                                                if (originalItem.Crate != 0)
                                                    effects = UnusualEffects.Series[originalItem.Crate];
                                                else if (!this.Client.Account.Admin)
                                                {
                                                    foreach (var i in UnusualEffects.Series)
                                                        if (i.Key > 0 && i.Key <= UnusualEffects.CurrentSeries)
                                                            effects.AddRange(i.Value);
                                                }
                                                else
                                                {
                                                    foreach (var i in UnusualEffects.Series)
                                                        if (i.Key != 0)
                                                            effects.AddRange(i.Value);
                                                }
                                                Inventory.Data[_slot] = new ItemData
                                                {
                                                    NamePrefix = "Unusual",
                                                    NameColor = 0x8000FF,
                                                    Effect = effects.RandomElement(rand1),
                                                };
                                                Inventory.Data[_slot].FullEffect = UnusualEffects.Save(Inventory.Data[_slot].Effect);
                                            }
                                        }

                                        client.SendPacket(new ItemResultPacket
                                        {
                                            ItemID = Inventory[_slot].ObjectType,
                                            Data = Inventory.Data[_slot] != null ? Inventory.Data[_slot].GetJson() : "{}"
                                        });

                                        string msg = "{c}" + this.GetNameColor() + "{/c}" + Name + "{c}0xFFFFFF{/c} has unboxed: {c}" +
                                                    ((Inventory.Data[_slot] != null && Inventory.Data[_slot].NameColor != 0xFFFFFF) ? Inventory.Data[_slot].NameColor.ToString() : "0xFFFF00") + "{/c}" +
                                                    ((Inventory.Data[_slot] != null && Inventory.Data[_slot].NamePrefix != "") ? Inventory.Data[_slot].NamePrefix + " " : "") +
                                                    ((Inventory.Data[_slot] != null && Inventory.Data[_slot].Name != "") ?
                                                        Inventory.Data[_slot].Name :
                                                        Inventory[_slot].DisplayId ?? Inventory[_slot].ObjectId);

                                        Owner.BroadcastPacket(new TextPacket
                                        {
                                            BubbleTime = 0,
                                            Stars = -1,
                                            Name = "",
                                            Text = msg
                                        }, null);

                                        UpdateCount++;
                                    }
                                });
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine(e);
                            }
                        } break;
                    case ActivateEffects.RenameItem:
                        {
                            success = false;
                            this.ItemSelect((_item, _data) =>
                                {
                                    return _item != item;
                                }, _slot =>
                                {
                                    client.SendPacket(new GetTextInputPacket
                                    {
                                        Name = "Choose a new item name",
                                        Action = "renameSlot" + _slot.ToString()
                                    });
                                });
                        } break;
                    case ActivateEffects.RemoveSkin:
                        {
                            success = false;
                            if (Skin == -1)
                            {
                                SendError("No skin equipped");
                                break;
                            }
                            if (Manager.GameData.SkinToItem.ContainsKey((ushort)Skin) && !PermaSkin)
                            {
                                Inventory[itemSlot] = Manager.GameData.SkinToItem[(ushort)Skin];
                                Inventory.Data[itemSlot] = null;
                                if (Effect != "")
                                {
                                    string effId = Utils.FromCommaSepString(Effect)[0];
                                    Inventory.Data[itemSlot] = new ItemData()
                                    {
                                        NamePrefix = "Unusual",
                                        NameColor = 0x8000FF,
                                        Effect = effId,
                                        FullEffect = Effect
                                    };
                                }
                            }
                            Damage((int)Math.Ceiling((double)HP / 2), this, true, true, 1.0f);
                            Skin = -1;
                            PermaSkin = false;
                            Effect = "";
                            UpdateCount++;
                        } break;
                    case ActivateEffects.BindSkin:
                        {
                            success = false;
                            this.ItemSelect((_item, _data) =>
                            {
                                foreach (var activEff in _item.ActivateEffects)
                                    if (activEff.Effect == ActivateEffects.UnlockSkin)
                                        return (_data != null) ? !_data.Soulbound : true;
                                return false;
                            }, _slot =>
                            {
                                if(Inventory[_slot] == null)
                                {
                                    SendError("Item no longer exists");
                                    return;
                                }
                                bool isSkin = false;
                                foreach (var activEff in Inventory[_slot].ActivateEffects)
                                    if (activEff.Effect == ActivateEffects.UnlockSkin)
                                        isSkin = (Inventory.Data[_slot] != null) ? !Inventory.Data[_slot].Soulbound : true;
                                if (!isSkin)
                                {
                                    SendError("Item is not a valid skin");
                                    return;
                                }
                                if (Inventory[itemSlot] == null)
                                {
                                    SendError("Skin keeper no longer exists");
                                    return;
                                }
                                bool succeeded = false;
                                foreach (var activEff in Inventory[itemSlot].ActivateEffects)
                                    if (activEff.Effect == ActivateEffects.BindSkin)
                                        succeeded = true;
                                if (!succeeded)
                                {
                                    SendError("Invalid skin keeper");
                                    return;
                                }
                                if (Inventory.Data[_slot] == null)
                                    Inventory.Data[_slot] = new ItemData();
                                Inventory.Data[_slot].Soulbound = true;
                                Inventory.Data[_slot].MultiUse = true;

                                Inventory[itemSlot] = null;
                                Inventory.Data[itemSlot] = null;

                                UpdateCount++;
                            });
                        } break;
                    case ActivateEffects.StrangePart:
                        {
                            success = false;
                            this.ItemSelect((_item, _data) =>
                            {
                                return _item != null && _data != null && _data.Strange && !data.StrangeParts.ContainsKey(data.NamePrefix);
                            }, _slot =>
                            {
                                if (Inventory[_slot] == null || Inventory.Data[_slot] == null)
                                {
                                    SendError("Item no longer exists");
                                    return;
                                }
                                if (Inventory[itemSlot] == null || Inventory.Data[itemSlot] == null)
                                {
                                    SendError("Strange part no longer exists");
                                    return;
                                }
                                bool succeeded = false;
                                foreach (var activEff in Inventory[itemSlot].ActivateEffects)
                                    if (activEff.Effect == ActivateEffects.StrangePart)
                                        succeeded = true;
                                if (!succeeded || Inventory.Data[itemSlot].NamePrefix == "")
                                {
                                    SendError("Invalid strange part");
                                    return;
                                }
                                Inventory.Data[_slot].StrangeParts.TryAdd(Inventory.Data[itemSlot].NamePrefix, 0);
                                Inventory[itemSlot] = null;
                                Inventory.Data[itemSlot] = null;

                                UpdateCount++;
                            });
                        } break;
                    case ActivateEffects.Strangify:
                        {
                            success = false;
                            if(data.NamePrefix == "")
                                break;
                            this.ItemSelect((_item, _data) =>
                            {
                                return _item != null && _item.ObjectId == data.NamePrefix && ((_data != null && !_data.Strange) || (_data == null));
                            }, _slot =>
                            {
                                if (Inventory[_slot] == null)
                                {
                                    SendError("Item no longer exists");
                                    return;
                                }
                                if (Inventory[itemSlot] == null || Inventory.Data[itemSlot] == null)
                                {
                                    SendError("Strangifier no longer exists");
                                    return;
                                }
                                bool succeeded = false;
                                foreach (var activEff in Inventory[itemSlot].ActivateEffects)
                                    if (activEff.Effect == ActivateEffects.Strangify)
                                        succeeded = true;
                                if (!succeeded || Inventory.Data[itemSlot].NamePrefix != Inventory[_slot].ObjectId)
                                {
                                    SendError("Invalid strangifier");
                                    return;
                                }
                                if (Inventory.Data[_slot] == null)
                                    Inventory.Data[_slot] = new ItemData();
                                Inventory.Data[_slot].Strange = true;
                                Inventory.Data[_slot].NamePrefix = "Strange";
                                Inventory.Data[_slot].NameColor = 0xFF5A28;
                                Inventory[itemSlot] = null;
                                Inventory.Data[itemSlot] = null;

                                UpdateCount++;
                            });
                        } break;
                    case ActivateEffects.UnbindSkin:
                        {
                            success = false;
                            if (Skin != -1)
                            {
                                SendError("You cannot wear a skin while unbinding a skin item.");
                                break;
                            }
                            this.ItemSelect((_item, _data) =>
                            {
                                foreach (var activEff in _item.ActivateEffects)
                                    if (activEff.Effect == ActivateEffects.UnlockSkin)
                                        return _data != null && _data.Soulbound && _data.MultiUse;
                                return false;
                            }, _slot =>
                            {
                                if (Skin != -1)
                                {
                                    SendError("You cannot wear a skin while unbinding a skin item.");
                                    return;
                                }
                                if (Inventory[_slot] == null)
                                {
                                    SendError("Item no longer exists");
                                    return;
                                }
                                bool isSkin = false;
                                foreach (var activEff in Inventory[_slot].ActivateEffects)
                                    if (activEff.Effect == ActivateEffects.UnlockSkin)
                                        isSkin = Inventory.Data[_slot] != null && Inventory.Data[_slot].Soulbound && Inventory.Data[_slot].MultiUse;
                                if (!isSkin)
                                {
                                    SendError("Item is not a valid skin");
                                    return;
                                }
                                if (Inventory[itemSlot] == null)
                                {
                                    SendError("Skin disowner no longer exists");
                                    return;
                                }
                                bool succeeded = false;
                                foreach (var activEff in Inventory[itemSlot].ActivateEffects)
                                    if (activEff.Effect == ActivateEffects.UnbindSkin)
                                        succeeded = true;
                                if (!succeeded)
                                {
                                    SendError("Invalid skin disowner");
                                    return;
                                }
                                if (Inventory.Data[_slot] != null)
                                {
                                    Inventory.Data[_slot].Soulbound = false;
                                    Inventory.Data[_slot].MultiUse = false;
                                }

                                Inventory[itemSlot] = null;
                                Inventory.Data[itemSlot] = null;

                                UpdateCount++;
                            });
                        } break;
                }
            }
            UpdateCount++;
            return success;
        }
예제 #4
0
        void Activate(RealmTime time, Item item, Position target)
        {
            MP -= item.MpCost;
            foreach (var eff in item.ActivateEffects)
            {
                switch (eff.Effect)
                {
                    case ActivateEffects.BulletNova:
                        {
                            var prjDesc = item.Projectiles[0]; //Assume only one
                            Packet[] batch = new Packet[21];
                            uint s = Random.CurrentSeed;
                            Random.CurrentSeed = (uint)(s * time.tickTimes);
                            for (int i = 0; i < 20; i++)
                            {
                                Projectile proj = CreateProjectile(prjDesc, item.ObjectType,
                                    (int)statsMgr.GetAttackDamage(prjDesc.MinDamage, prjDesc.MaxDamage),
                                    time.tickTimes, target, (float)(i * (Math.PI * 2) / 20));
                                Owner.EnterWorld(proj);
                                fames.Shoot(proj);
                                batch[i] = new ShootPacket()
                                {
                                    BulletId = proj.ProjectileId,
                                    OwnerId = Id,
                                    ContainerType = item.ObjectType,
                                    Position = target,
                                    Angle = proj.Angle,
                                    Damage = (short)proj.Damage
                                };
                            }
                            Random.CurrentSeed = s;
                            batch[20] = new ShowEffectPacket()
                            {
                                EffectType = EffectType.Trail,
                                PosA = target,
                                TargetId = Id,
                                Color = new ARGB(0xFFFF00AA)
                            };
                            BroadcastSync(batch, p => this.Dist(p) < 25);
                        } break;
                    case ActivateEffects.Shoot:
                        {
                            ActivateShoot(time, item, target);
                        } break;
                    case ActivateEffects.StatBoostSelf:
                        {
                            int idx = -1;
                            switch ((StatsType)eff.Stats)
                            {
                                case StatsType.MaximumHP: idx = 0; break;
                                case StatsType.MaximumMP: idx = 1; break;
                                case StatsType.Attack: idx = 2; break;
                                case StatsType.Defense: idx = 3; break;
                                case StatsType.Speed: idx = 4; break;
                                case StatsType.Vitality: idx = 5; break;
                                case StatsType.Wisdom: idx = 6; break;
                                case StatsType.Dexterity: idx = 7; break;
                            }
                            int s = eff.Amount;
                            Boost[idx] += s;
                            UpdateCount++;
                            Owner.Timers.Add(new WorldTimer(eff.DurationMS, (world, t) =>
                            {
                                Boost[idx] -= s;
                                UpdateCount++;
                            }));
                            BroadcastSync(new ShowEffectPacket()
                            {
                                EffectType = EffectType.Potion,
                                TargetId = Id,
                                Color = new ARGB(0xffffffff)
                            }, null);
                        } break;
                    case ActivateEffects.StatBoostAura:
                        {
                            int idx = -1;
                            switch ((StatsType)eff.Stats)
                            {
                                case StatsType.MaximumHP: idx = 0; break;
                                case StatsType.MaximumMP: idx = 1; break;
                                case StatsType.Attack: idx = 2; break;
                                case StatsType.Defense: idx = 3; break;
                                case StatsType.Speed: idx = 4; break;
                                case StatsType.Vitality: idx = 5; break;
                                case StatsType.Wisdom: idx = 6; break;
                                case StatsType.Dexterity: idx = 7; break;
                            }
                            int s = eff.Amount;
                            this.AOE(eff.Range / 2, true, player =>
                            {
                                (player as Player).Boost[idx] += s;
                                player.UpdateCount++;
                                Owner.Timers.Add(new WorldTimer(eff.DurationMS, (world, t) =>
                                {
                                    (player as Player).Boost[idx] -= s;
                                    player.UpdateCount++;
                                }));
                            });
                            BroadcastSync(new ShowEffectPacket()
                            {
                                EffectType = EffectType.AreaBlast,
                                TargetId = Id,
                                Color = new ARGB(0xffffffff),
                                PosA = new Position() { X = eff.Range / 2 }
                            }, p => this.Dist(p) < 25);
                        } break;
                    case ActivateEffects.ConditionEffectSelf:
                        {
                            ApplyConditionEffect(new ConditionEffect()
                            {
                                Effect = eff.ConditionEffect.Value,
                                DurationMS = eff.DurationMS
                            });
                            BroadcastSync(new ShowEffectPacket()
                            {
                                EffectType = EffectType.AreaBlast,
                                TargetId = Id,
                                Color = new ARGB(0xffffffff),
                                PosA = new Position() { X = 1 }
                            }, p => this.Dist(p) < 25);
                        } break;
                    case ActivateEffects.ConditionEffectAura:
                        {
                            this.AOE(eff.Range / 2, true, player =>
                            {
                                player.ApplyConditionEffect(new ConditionEffect()
                                {
                                    Effect = eff.ConditionEffect.Value,
                                    DurationMS = eff.DurationMS
                                });
                            });
                            uint color = 0xffffffff;
                            if (eff.ConditionEffect.Value == ConditionEffectIndex.Damaging)
                                color = 0xffff0000;
                            BroadcastSync(new ShowEffectPacket()
                            {
                                EffectType = EffectType.AreaBlast,
                                TargetId = Id,
                                Color = new ARGB(color),
                                PosA = new Position() { X = eff.Range / 2 }
                            }, p => this.Dist(p) < 25);
                        } break;
                    case ActivateEffects.Heal:
                        {
                            List<Packet> pkts = new List<Packet>();
                            ActivateHealHp(this, eff.Amount, pkts);
                            BroadcastSync(pkts, p => this.Dist(p) < 25);
                        } break;
                    case ActivateEffects.HealNova:
                        {
                            List<Packet> pkts = new List<Packet>();
                            this.AOE(eff.Range / 2, true, player =>
                            {
                                ActivateHealHp(player as Player, eff.Amount, pkts);
                            });
                            pkts.Add(new ShowEffectPacket()
                            {
                                EffectType = EffectType.AreaBlast,
                                TargetId = Id,
                                Color = new ARGB(0xffffffff),
                                PosA = new Position() { X = eff.Range / 2 }
                            });
                            BroadcastSync(pkts, p => this.Dist(p) < 25);
                        } break;
                    case ActivateEffects.Magic:
                        {
                            List<Packet> pkts = new List<Packet>();
                            ActivateHealMp(this, eff.Amount, pkts);
                            BroadcastSync(pkts, p => this.Dist(p) < 25);
                        } break;
                    case ActivateEffects.MagicNova:
                        {
                            List<Packet> pkts = new List<Packet>();
                            this.AOE(eff.Range / 2, true, player =>
                            {
                                ActivateHealMp(player as Player, eff.Amount, pkts);
                            });
                            pkts.Add(new ShowEffectPacket()
                            {
                                EffectType = EffectType.AreaBlast,
                                TargetId = Id,
                                Color = new ARGB(0xffffffff),
                                PosA = new Position() { X = eff.Range / 2 }
                            });
                            BroadcastSync(pkts, p => this.Dist(p) < 25);
                        } break;
                    case ActivateEffects.Teleport:
                        {
                            Move(target.X, target.Y);
                            UpdateCount++;
                            BroadcastSync(new Packet[]
                            {
                                new GotoPacket()
                                {
                                    ObjectId = Id,
                                    Position = new Position()
                                    {
                                        X = X,
                                        Y = Y
                                    }
                                },
                                new ShowEffectPacket()
                                {
                                    EffectType = EffectType.Teleport,
                                    TargetId = Id,
                                    PosA = new Position()
                                    {
                                        X = X,
                                        Y = Y
                                    },
                                    Color = new ARGB(0xFFFFFFFF)
                                }
                            }, p => this.Dist(p) < 25);
                        } break;
                    case ActivateEffects.VampireBlast:
                        {
                            List<Packet> pkts = new List<Packet>();
                            pkts.Add(new ShowEffectPacket()
                            {
                                EffectType = EffectType.Trail,
                                TargetId = Id,
                                PosA = target,
                                Color = new ARGB(0xFFFF0000)
                            });
                            pkts.Add(new AOEPacket()
                            {
                                Position = target,
                                Radius = eff.Radius,
                                Damage = (ushort)eff.TotalDamage,
                                EffectDuration = 0,
                                Effects = 0,
                                OriginType = item.ObjectType
                            });

                            int totalDmg = 0;
                            var enemies = new List<Enemy>();
                            Owner.AOE(target, eff.Radius, false, enemy =>
                            {
                                enemies.Add(enemy as Enemy);
                                totalDmg += (enemy as Enemy).Damage(this, time, eff.TotalDamage, false);
                            });
                            var players = new List<Player>();
                            this.AOE(eff.Radius, true, player =>
                            {
                                players.Add(player as Player);
                                ActivateHealHp(player as Player, totalDmg, pkts);
                            });

                            Random rand = new System.Random();
                            for (int i = 0; i < 5; i++)
                            {
                                Enemy a = enemies[rand.Next(0, enemies.Count)];
                                Player b = players[rand.Next(0, players.Count)];
                                pkts.Add(new ShowEffectPacket()
                                {
                                    EffectType = EffectType.Flow,
                                    TargetId = b.Id,
                                    PosA = new Position() { X = a.X, Y = a.Y },
                                    Color = new ARGB(0xffffffff)
                                });
                            }

                            BroadcastSync(pkts, p => this.Dist(p) < 25);
                        } break;
                    case ActivateEffects.Trap:
                        {
                            BroadcastSync(new ShowEffectPacket()
                            {
                                EffectType = EffectType.Throw,
                                Color = new ARGB(0xff9000ff),
                                TargetId = Id,
                                PosA = target
                            }, p => this.Dist(p) < 25);
                            Owner.Timers.Add(new WorldTimer(1500, (world, t) =>
                            {
                                Trap trap = new Trap(
                                    this,
                                    eff.Radius,
                                    eff.TotalDamage,
                                    eff.ConditionEffect ?? ConditionEffectIndex.Slowed,
                                    eff.EffectDuration);
                                trap.Move(target.X, target.Y);
                                world.EnterWorld(trap);
                            }));
                        } break;
                    case ActivateEffects.StasisBlast:
                        {
                            List<Packet> pkts = new List<Packet>();

                            pkts.Add(new ShowEffectPacket()
                            {
                                EffectType = EffectType.Concentrate,
                                TargetId = Id,
                                PosA = target,
                                PosB = new Position() { X = target.X + 3, Y = target.Y },
                                Color = new ARGB(0xffffffff)
                            });
                            Owner.AOE(target, 3, false, enemy =>
                            {
                                if (enemy.HasConditionEffect(ConditionEffects.StasisImmune))
                                {
                                    pkts.Add(new NotificationPacket()
                                    {
                                        ObjectId = enemy.Id,
                                        Color = new ARGB(0xff00ff00),
                                        Text = "Immune"
                                    });
                                }
                                else if (!enemy.HasConditionEffect(ConditionEffects.Stasis))
                                {
                                    enemy.ApplyConditionEffect(
                                        new ConditionEffect()
                                        {
                                            Effect = ConditionEffectIndex.Stasis,
                                            DurationMS = eff.DurationMS
                                        },
                                        new ConditionEffect()
                                        {
                                            Effect = ConditionEffectIndex.Confused,
                                            DurationMS = eff.DurationMS
                                        }
                                    );
                                    Owner.Timers.Add(new WorldTimer(eff.DurationMS, (world, t) =>
                                    {
                                        enemy.ApplyConditionEffect(new ConditionEffect()
                                            {
                                                Effect = ConditionEffectIndex.StasisImmune,
                                                DurationMS = 3000
                                            }
                                        );
                                    }
                                    ));
                                    pkts.Add(new NotificationPacket()
                                    {
                                        ObjectId = enemy.Id,
                                        Color = new ARGB(0xffff0000),
                                        Text = "Stasis"
                                    });
                                }
                            });
                            BroadcastSync(pkts, p => this.Dist(p) < 25);
                        } break;
                    case ActivateEffects.Decoy:
                        {
                            var decoy = new Decoy(this, eff.DurationMS, statsMgr.GetSpeed());
                            decoy.Move(X, Y);
                            Owner.EnterWorld(decoy);
                        } break;
                    case ActivateEffects.Lightning:
                        {
                            Enemy start = null;
                            double angle = Math.Atan2(target.Y - Y, target.X - X);
                            double diff = Math.PI / 3;
                            Owner.AOE(target, 6, false, enemy =>
                            {
                                if (!(enemy is Enemy)) return;
                                var x = Math.Atan2(enemy.Y - Y, enemy.X - X);
                                if (Math.Abs(angle - x) < diff)
                                {
                                    start = enemy as Enemy;
                                    diff = Math.Abs(angle - x);
                                }
                            });
                            if (start == null)
                                break;

                            Enemy current = start;
                            Enemy[] targets = new Enemy[eff.MaxTargets];
                            for (int i = 0; i < targets.Length; i++)
                            {
                                targets[i] = current;
                                Enemy next = current.GetNearestEntity(8, false,
                                    enemy =>
                                        enemy is Enemy &&
                                        Array.IndexOf(targets, enemy) == -1 &&
                                        this.Dist(enemy) <= 6) as Enemy;

                                if (next == null) break;
                                else current = next;
                            }

                            List<Packet> pkts = new List<Packet>();
                            for (int i = 0; i < targets.Length; i++)
                            {
                                if (targets[i] == null) break;
                                Entity prev = i == 0 ? (Entity)this : targets[i - 1];
                                targets[i].Damage(this, time, eff.TotalDamage, false);
                                if (eff.ConditionEffect != null)
                                    targets[i].ApplyConditionEffect(new ConditionEffect()
                                    {
                                        Effect = eff.ConditionEffect.Value,
                                        DurationMS = (int)(eff.EffectDuration * 1000)
                                    });
                                pkts.Add(new ShowEffectPacket()
                                {
                                    EffectType = EffectType.Lightning,
                                    TargetId = prev.Id,
                                    Color = new ARGB(0xffff0088),
                                    PosA = new Position()
                                    {
                                        X = targets[i].X,
                                        Y = targets[i].Y
                                    },
                                    PosB = new Position() { X = 350 }
                                });
                            }
                            BroadcastSync(pkts, p => this.Dist(p) < 25);
                        } break;
                    case ActivateEffects.PoisonGrenade:
                        {
                            BroadcastSync(new ShowEffectPacket()
                            {
                                EffectType = EffectType.Throw,
                                Color = new ARGB(0xffddff00),
                                TargetId = Id,
                                PosA = target
                            }, p => this.Dist(p) < 25);
                            Placeholder x = new Placeholder(Manager, 1500);
                            x.Move(target.X, target.Y);
                            Owner.EnterWorld(x);
                            Owner.Timers.Add(new WorldTimer(1500, (world, t) =>
                            {
                                Owner.BroadcastPacket(new ShowEffectPacket()
                                {
                                    EffectType = EffectType.AreaBlast,
                                    Color = new ARGB(0xffddff00),
                                    TargetId = x.Id,
                                    PosA = new Position() { X = eff.Radius }
                                }, null);
                                List<Enemy> enemies = new List<Enemy>();
                                Owner.AOE(target, eff.Radius, false,
                                    enemy => PoisonEnemy(enemy as Enemy, eff));
                            }));
                        } break;
                    case ActivateEffects.RemoveNegativeConditions:
                        {
                            this.AOE(eff.Range / 2, true, player =>
                            {
                                ApplyConditionEffect(NegativeEffs);
                            });
                            BroadcastSync(new ShowEffectPacket()
                            {
                                EffectType = EffectType.AreaBlast,
                                TargetId = Id,
                                Color = new ARGB(0xffffffff),
                                PosA = new Position() { X = eff.Range / 2 }
                            }, p => this.Dist(p) < 25);
                        } break;
                    case ActivateEffects.RemoveNegativeConditionsSelf:
                        {
                            ApplyConditionEffect(NegativeEffs);
                            BroadcastSync(new ShowEffectPacket()
                            {
                                EffectType = EffectType.AreaBlast,
                                TargetId = Id,
                                Color = new ARGB(0xffffffff),
                                PosA = new Position() { X = 1 }
                            }, p => this.Dist(p) < 25);
                        } break;
                    case ActivateEffects.IncrementStat:
                        {
                            int idx = -1;
                            switch ((StatsType)eff.Stats)
                            {
                                case StatsType.MaximumHP: idx = 0; break;
                                case StatsType.MaximumMP: idx = 1; break;
                                case StatsType.Attack: idx = 2; break;
                                case StatsType.Defense: idx = 3; break;
                                case StatsType.Speed: idx = 4; break;
                                case StatsType.Vitality: idx = 5; break;
                                case StatsType.Wisdom: idx = 6; break;
                                case StatsType.Dexterity: idx = 7; break;
                            }
                            Stats[idx] += eff.Amount;
                            int limit = int.Parse(Manager.GameData.ObjectTypeToElement[ObjectType].Element(StatsManager.StatsIndexToName(idx)).Attribute("max").Value);
                            if (Stats[idx] > limit)
                                Stats[idx] = limit;
                            UpdateCount++;
                        } break;
                    case ActivateEffects.Create: //this is a portal
                        {
                            ushort objType;
                            if (!Manager.GameData.IdToObjectType.TryGetValue(eff.Id, out objType) ||
                                !Manager.GameData.Portals.ContainsKey(objType))
                                break;// object not found, ignore
                            var entity = Entity.Resolve(Manager, objType);
                            entity.Move(X, Y);
                            int TimeoutTime = Manager.GameData.Portals[objType].TimeoutTime;

                            Owner.EnterWorld(entity);
                            World w = Manager.GetWorld(Owner.Id); //can't use Owner here, as it goes out of scope
                            w.Timers.Add(new WorldTimer(TimeoutTime * 1000, (world, t) => //default portal close time * 1000
                            {
                                try
                                {
                                    w.LeaveWorld(entity);
                                }
                                catch //couldn't remove portal, Owner became null. Should be fixed with RealmManager implementation
                                {
                                    Console.WriteLine("Couldn't despawn portal.");
                                }
                            }));
                        } break;
                    case ActivateEffects.Pet:
                    case ActivateEffects.UnlockPortal:
                        break;
                }
            }
            UpdateCount++;
        }