private void ActivateAbilityShoot(RealmTime time, Ability ability, Position target)
        {
            double arcGap = ability.ArcGap * Math.PI / 180;
            double startAngle = Math.Atan2(target.Y - Y, target.X - X) - (ability.NumProjectiles - 1) / 2 * arcGap;
            ProjectileDesc prjDesc = ability.Projectiles[0]; //Assume only one

            var batch = new Packet[ability.NumProjectiles];
            for (int i = 0; i < ability.NumProjectiles; i++)
            {
                Projectile proj = CreateProjectile(prjDesc, ObjectDesc.ObjectType,
                    (int)statsMgr.GetAttackDamage(prjDesc.MinDamage, prjDesc.MaxDamage),
                    time.tickTimes, new Position { X = X, Y = Y }, (float)(startAngle + arcGap * i), 1);
                Owner.EnterWorld(proj);
                fames.Shoot(proj);
                batch[i] = new ShootPacket
                {
                    BulletId = proj.ProjectileId,
                    OwnerId = Id,
                    ContainerType = ability.AbilityType,
                    Position = new Position { X = X, Y = Y },
                    Angle = proj.Angle,
                    Damage = (short)proj.Damage,
                    FromAbility = true
                };
            }
            BroadcastSync(batch, p => this.Dist(p) < 25);
        }
 public void BroadcastSync(Packet packet, Predicate<Player> cond)
 {
     if(worldBroadcast)
         Owner.BroadcastPacketSync(packet, cond);
     else
         pendingPackets.Enqueue(Tuple.Create(packet, cond));
 }
 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 void SendPacket(Packet pkt)
        {
            if (!skt.Connected) return;
            pendingPackets.Enqueue(pkt);
            if (CanSendPacket(send, false))
            {
                int len = (send.UserToken as SendToken).Packet.Write(parent, sendBuff, 0);

                sendState = SendState.Sending;
                send.SetBuffer(sendBuff, 0, len);
                if (!skt.SendAsync(send))
                    SendCompleted(this, send);
            }
        }
Beispiel #5
0
 internal void ProcessPacket(Packet pkt)
 {
     try
     {
         log.Logger.Log(typeof(Client), log4net.Core.Level.Verbose,
             string.Format("Handling packet '{0}'...", pkt.ID), null);
         if (pkt.ID == PacketID.Packet) return;
         IPacketHandler handler;
         if (!PacketHandlers.Handlers.TryGetValue(pkt.ID, out handler))
             log.WarnFormat("Unhandled packet '{0}'.", pkt.ID);
         else
             handler.Handle(this, (ClientPacket)pkt);
     }
     catch (Exception e)
     {
         log.Error(string.Format("Error when handling packet '{0}'...", pkt.ToString()), e);
         Disconnect();
     }
 }
 public void BroadcastSync(Packet packet, Predicate<Player> cond)
 {
     pendingPackets.Enqueue(Tuple.Create(packet, cond));
 }
 public void BroadcastSync(Packet packet)   //sync at Move
 {
     BroadcastSync(packet, _ => true);
 }
 internal void ProcessPacket(Packet pkt)
 {
     try
     {
         log.Logger.Log(typeof (Client), Level.Verbose,
            $"Handling packet '{pkt}'...", null);
         if (pkt.ID == (PacketID) 255) return;
         IPacketHandler handler;
         if (!PacketHandlers.Handlers.TryGetValue(pkt.ID, out handler))
             log.Warn($"Unhandled packet '{pkt.ID}'.");
         else
             handler.Handle(this, (ClientPacket) pkt);
     }
     catch (Exception e)
     {
         log.Error($"Error when handling packet '{pkt}'...", e);
         Disconnect();
     }
 }
        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;
        }
Beispiel #10
0
 private bool OnPacketReceived(Packet pkt)
 {
     //return parent.ProcessPacket(pkt);
     if (parent.IsReady())
     {
         RealmManager.Network.AddPendingPacket(parent, pkt);
         return true;
     }
     else
         return false;
 }
 //sync at Move
 public void BroadcastSync(Packet packet)
 {
     BroadcastSync(packet, _ => true);
 }
Beispiel #12
0
 public void BroadcastPacket(Packet pkt, Player exclude)
 {
     foreach (var i in Players)
         if (i.Value != exclude)
             i.Value.Client.SendPacket(pkt);
 }
 public void BroadcastPacketSync(Packet pkt, Predicate<Player> exclude)
 {
     foreach (var i in Players.Where(i => exclude(i.Value)))
         i.Value.Client.SendPacket(pkt);
 }
        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++;
        }
Beispiel #15
0
 //sync at Move
 /*
 void Flush()
 {
     foreach (var i in Owner.Players.Values)
         foreach (var j in pendingPackets)
             if (j.Item2(i))
                 i.client.SendPacket(j.Item1);
     pendingPackets.Clear();
 }
 */
 private void BroadcastSync(Packet packet)
 {
     BroadcastSync(packet, _ => true);
 }
        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;
        }
 public void SendPacket(Packet packet, Player exclude)
 {
     if (Leader.Client != null && Leader != exclude)
         Leader.Client.SendPacket(packet);
     foreach (var i in Members)
         if (i.Client != null && i != exclude)
             i.Client.SendPacket(packet);
 }
Beispiel #18
0
 internal void ProcessPacket(Packet pkt)
 {
     try
     {
         if (pkt.ID == PacketID.Hello)
             ProcessHelloPacket(pkt as HelloPacket);
         else if (pkt.ID == PacketID.Create)
             ProcessCreatePacket(pkt as CreatePacket);
         else if (pkt.ID == PacketID.Load)
             ProcessLoadPacket(pkt as LoadPacket);
         else if (pkt.ID == PacketID.Pong)
             entity.Pong(pkt as PongPacket);
         else if (pkt.ID == PacketID.Move)
             RealmManager.Logic.AddPendingAction(t => entity.Move(t, pkt as MovePacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.PlayerShoot)
             RealmManager.Logic.AddPendingAction(t => entity.PlayerShoot(t, pkt as PlayerShootPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.EnemyHit)
             RealmManager.Logic.AddPendingAction(t => entity.EnemyHit(t, pkt as EnemyHitPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.OtherHit)
             RealmManager.Logic.AddPendingAction(t => entity.OtherHit(t, pkt as OtherHitPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.SquareHit)
             RealmManager.Logic.AddPendingAction(t => entity.SquareHit(t, pkt as SquareHitPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.PlayerHit)
             RealmManager.Logic.AddPendingAction(t => entity.PlayerHit(t, pkt as PlayerHitPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.ShootAck) //Spam
             RealmManager.Logic.AddPendingAction(t => entity.ShootAck(t, pkt as ShootAckPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.InvSwap)
             RealmManager.Logic.AddPendingAction(t => entity.InventorySwap(t, pkt as InvSwapPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.InvDrop)
             RealmManager.Logic.AddPendingAction(t => entity.InventoryDrop(t, pkt as InvDropPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.UseItem)
             RealmManager.Logic.AddPendingAction(t => entity.UseItem(t, pkt as UseItemPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.UsePortal)
             RealmManager.Logic.AddPendingAction(t => entity.UsePortal(t, pkt as UsePortalPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.PlayerText)
             RealmManager.Logic.AddPendingAction(t => entity.PlayerText(t, pkt as PlayerTextPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.ChooseName)
             ProcessChooseNamePacket(pkt as ChooseNamePacket);
         else if (pkt.ID == PacketID.Escape)
             ProcessEscapePacket(pkt as EscapePacket);
         else if (pkt.ID == PacketID.Teleport)
             RealmManager.Logic.AddPendingAction(t => entity.Teleport(t, pkt as TeleportPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.GotoAck)
             RealmManager.Logic.AddPendingAction(t => entity.GotoAck(t, pkt as GotoAckPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.EditAccountList)
             RealmManager.Logic.AddPendingAction(t => entity.EditAccountList(t, pkt as EditAccountListPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.Buy)
             RealmManager.Logic.AddPendingAction(t => entity.Buy(t, pkt as BuyPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.RequestTrade)
             RealmManager.Logic.AddPendingAction(t => entity.RequestTrade(t, pkt as RequestTradePacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.ChangeTrade)
             RealmManager.Logic.AddPendingAction(t => entity.ChangeTrade(t, pkt as ChangeTradePacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.AcceptTrade)
             RealmManager.Logic.AddPendingAction(t => entity.AcceptTrade(t, pkt as AcceptTradePacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.CancelTrade)
             RealmManager.Logic.AddPendingAction(t => entity.CancelTrade(t, pkt as CancelTradePacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.AOEAck)
             RealmManager.Logic.AddPendingAction(t => entity.AOEAck(t, pkt as AOEAckPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.GroundDamage)
             RealmManager.Logic.AddPendingAction(t => entity.GroundDamage(t, pkt as GroundDamagePacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.CheckCredits)
             RealmManager.Logic.AddPendingAction(t => entity.CheckCredits(t, pkt as CheckCreditsPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.GuildRemove)
             RealmManager.Logic.AddPendingAction(t => entity.GuildRemove(t, pkt as GuildRemovePacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.CreateGuild)
             RealmManager.Logic.AddPendingAction(t => entity.CreateGuild(t, pkt as CreateGuildPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.JoinGuild)
             RealmManager.Logic.AddPendingAction(t => entity.JoinGuild(t, pkt as JoinGuildPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.GuildInvite)
             RealmManager.Logic.AddPendingAction(t => entity.InviteToGuild(t, pkt as GuildInvitePacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.ChangeGuildRank)
             RealmManager.Logic.AddPendingAction(t => entity.ChangeGuildRank(t, pkt as ChangeGuildRankPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.Visibullet)
             RealmManager.Logic.AddPendingAction(t => entity.VisibulletHit(pkt as VisibulletPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.TextBoxButton)
             RealmManager.Logic.AddPendingAction(t => entity.TextBoxButton(pkt as TextBoxButtonPacket), PendingPriority.Networking);
         else if (pkt.ID == PacketID.UpdateAck)
             RealmManager.Logic.AddPendingAction(t => HandleUpdateAck(), PendingPriority.Networking);
         else
         {
             logger.Error("Unhandled packet: " + pkt.ToString());
         }
     }
     catch (Exception e)
     {
         logger.Fatal(e);
         Disconnect();
     }
 }
Beispiel #19
0
 internal void ProcessPacket(Packet pkt)
 {
     try
     {
         if (pkt.ID == PacketID.Hello)
             ProcessHelloPacket(pkt as HelloPacket);
         else if (pkt.ID == PacketID.Create)
             ProcessCreatePacket(pkt as CreatePacket);
         else if (pkt.ID == PacketID.Load)
             ProcessLoadPacket(pkt as LoadPacket);
         else if (pkt.ID == PacketID.Pong)
             entity.Pong(pkt as PongPacket);
         else if (pkt.ID == PacketID.Move)
             Manager.Logic.AddPendingAction(t => entity.Move(t, pkt as MovePacket));
         else if (pkt.ID == PacketID.PlayerShoot)
             Manager.Logic.AddPendingAction(t => entity.PlayerShoot(t, pkt as PlayerShootPacket));
         else if (pkt.ID == PacketID.EnemyHit)
             Manager.Logic.AddPendingAction(t => entity.EnemyHit(t, pkt as EnemyHitPacket));
         else if (pkt.ID == PacketID.OtherHit)
             Manager.Logic.AddPendingAction(t => entity.OtherHit(t, pkt as OtherHitPacket));
         else if (pkt.ID == PacketID.SquareHit)
             Manager.Logic.AddPendingAction(t => entity.SquareHit(t, pkt as SquareHitPacket));
         else if (pkt.ID == PacketID.PlayerHit)
             Manager.Logic.AddPendingAction(t => entity.PlayerHit(t, pkt as PlayerHitPacket));
         else if (pkt.ID == PacketID.ShootAck)   //TODO: this one is spammed when lots of bullet, special handle?
             Manager.Logic.AddPendingAction(t => entity.ShootAck(t, pkt as ShootAckPacket));
         else if (pkt.ID == PacketID.InvSwap)
             Manager.Logic.AddPendingAction(t => entity.InventorySwap(t, pkt as InvSwapPacket));
         else if (pkt.ID == PacketID.InvDrop)
             Manager.Logic.AddPendingAction(t => entity.InventoryDrop(t, pkt as InvDropPacket));
         else if (pkt.ID == PacketID.UseItem)
             Manager.Logic.AddPendingAction(t => entity.UseItem(t, pkt as UseItemPacket));
         else if (pkt.ID == PacketID.UsePortal)
             Manager.Logic.AddPendingAction(t => entity.UsePortal(t, pkt as UsePortalPacket));
         else if (pkt.ID == PacketID.PlayerText)
             Manager.Logic.AddPendingAction(t => entity.PlayerText(t, pkt as PlayerTextPacket));
         else if (pkt.ID == PacketID.ChooseName)
             ProcessChooseNamePacket(pkt as ChooseNamePacket);
         else if (pkt.ID == PacketID.Escape)
             ProcessEscapePacket(pkt as EscapePacket);
         else if (pkt.ID == PacketID.Teleport)
             Manager.Logic.AddPendingAction(t => entity.Teleport(t, pkt as TeleportPacket));
         else if (pkt.ID == PacketID.GotoAck)
             Manager.Logic.AddPendingAction(t => entity.GotoAck(t, pkt as GotoAckPacket));
         else if (pkt.ID == PacketID.EditAccountList)
             entity.EditAccountList(pkt as EditAccountListPacket);
         else if (pkt.ID == PacketID.Buy)
             entity.Buy(pkt as BuyPacket);
         else if (pkt.ID == PacketID.RequestTrade)
             Manager.Logic.AddPendingAction(t => entity.RequestTrade(t, pkt as RequestTradePacket));
         else if (pkt.ID == PacketID.ChangeTrade)
             Manager.Logic.AddPendingAction(t => entity.ChangeTrade(t, pkt as ChangeTradePacket));
         else if (pkt.ID == PacketID.AcceptTrade)
             Manager.Logic.AddPendingAction(t => entity.AcceptTrade(t, pkt as AcceptTradePacket));
         else if (pkt.ID == PacketID.CancelTrade)
             Manager.Logic.AddPendingAction(t => entity.CancelTrade(t, pkt as CancelTradePacket));
         else if (pkt.ID == PacketID.AOEAck)
             Manager.Logic.AddPendingAction(t => entity.AOEAck(t, pkt as AOEAckPacket));
         else if (pkt.ID == PacketID.GroundDamage)
             Manager.Logic.AddPendingAction(t => entity.GroundDamage(t, pkt as GroundDamagePacket));
         else if (pkt.ID == PacketID.CheckCredits)
             entity.CheckCredits(pkt as CheckCreditsPacket);
         else if (pkt.ID != PacketID.Packet)
         {
             Console.WriteLine("Unhandled packet: " + pkt.ToString());
         }
     }
     catch
     {
         Disconnect();
     }
 }
 public void AddPendingPacket(Client parrent, Packet pkt)
 {
     pendings.Enqueue(new Work(parrent, pkt));
 }
Beispiel #21
0
        public void SendPacket(Packet pkt)
        {
            try
            {
                pendingPackets.Enqueue(pkt);
                if (CanSendPacket(send, false))
                {
                    var dat = (send.UserToken as SendToken).Packet.Write(parent);

                    sendState = SendState.Sending;
                    send.SetBuffer(dat, 0, dat.Length);
                    if (!skt.SendAsync(send))
                        IOCompleted(this, send);
                }
            }
            catch
            {
                logger.Error("Error sending packet with ID " + pkt.ID.ToString());
            }
        }
 public void SendPacket(Packet pkt)
 {
     handler?.SendPacket(pkt);
 }
 private bool OnPacketReceived(Packet pkt)
 {
     if (parent.IsReady())
     {
         parent.Manager.Network.AddPendingPacket(parent, pkt);
         return true;
     }
     return false;
 }
Beispiel #24
0
 public void AddPendingPacket(Client client, Packet packet)
 {
     pendings.Add(new Tuple<Client, Packet>(client, packet));
 }