Exemplo n.º 1
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);
                        FameCounter.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.Dye:
                {
                    if (item.Texture1 != 0)
                    {
                        Texture1 = item.Texture1;
                    }
                    if (item.Texture2 != 0)
                    {
                        Texture2 = item.Texture2;
                    }
                    SaveToCharacter();
                }
                break;

                case ActivateEffects.Create:
                {
                    ushort objType;
                    if (!Manager.GameData.IdToObjectType.TryGetValue(eff.Id, out objType) ||
                        !Manager.GameData.Portals.ContainsKey(objType))
                    {
                        break;
                    }
                    Entity entity      = Resolve(Manager, objType);
                    World  w           = Manager.GetWorld(Owner.Id);
                    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  =
                                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) =>
                        {
                            try
                            {
                                w.LeaveWorld(entity);
                            }
                            catch (Exception ex)
                            {
                                log.ErrorFormat("Couldn't despawn portal.\n{0}", ex);
                            }
                        }));
                }
                break;
                }
            }
        }