示例#1
0
        public override void EnterState()
        {
            if (!isLoaded)
            {
                Entity temp;
                buildEntities = new List <Entity>();
                temp          = Parent.Controller.EntFactory.CreateIcon(GameVariables.IconTypes.BED, LodgingBuildSelect);
                buildEntities.Add(temp);
                Parent.AddEntity(temp);

                temp = Parent.Controller.EntFactory.CreateIcon(GameVariables.IconTypes.MUG, FareBuildSelect);
                buildEntities.Add(temp);
                Parent.AddEntity(temp);

                grid = new BuildGrid(GameVariables.GRID_SIZE, Parent.Controller.ScreenWidth, Parent.Controller.ScreenHeight);

                isLoaded = true;
            }
            else
            {
                foreach (Entity ent in buildEntities)
                {
                    ent.IsVisible = true;
                }
            }
            currentEntity = null;
            base.EnterState();
        }
示例#2
0
        /// <summary>
        /// Function gets called when a collision with this object occurs.
        /// </summary>
        /// <param name="ent"> Entity this object collides with.</param>
        /// <param name="penetration"> Amount of penetration.</param>
        /// <param name="side"> The side the objects collide on.</param>
        /// <param name="axis"> The axis that is being checked.</param>
        /// <param name="fromBounds"> Where the colliding entity came from.</param>
        public override void OnCollision(Entity ent, int penetration, CollisionTester.CollisionSide side, CollisionTester.Axis axis, Rectangle fromBounds)
        {
            // Check if the entity colliding is player and came from the bottom.
            if (ent is Player && side == CollisionTester.CollisionSide.BOTTOM && axis == CollisionTester.Axis.Y)
            {
                // Check if there is a powerup inside.
                if (_item != null)
                {
                    // Get the powerup.
                    PowerUp item = _item;

                    // Set the position of the powerup.
                    item.Position = Position;

                    // Call the spawn of the powerup.
                    item.OnSpawn();

                    // Add the powerup to the level.
                    Parent.AddEntity(item);

                    // Play wood animation.
                    Animations.Play((int)GiftBlockAnimation.WOOD);

                    // Remove item.
                    _item = null;
                }
            }
        }
示例#3
0
        public void DropItem(byte slot)
        {
            UpdateInventorySlot(slot);

            if (!ValidSlot(slot))
            {
#if DEBUG
                Program.Print(PrintType.Error, "Invalid slot");
#endif
                return;
            }

            int item = Inventory[slot];
            int data = ItemDatas[slot];
            if (item == -1)
            {
#if DEBUG
                Program.Print(PrintType.Error, "Nothing to drop");
#endif
                return;
            }

            Inventory[slot] = -1;
            ItemDatas[slot] = -1;
            UpdateInventorySlot(slot);

            Container container = new Container(Container.PurpleBag, Id, 120000);
            container.Inventory[0] = item;
            container.ItemDatas[0] = data;
            container.UpdateInventorySlot(0);

            RecalculateEquipBonuses();
            Parent.AddEntity(container, Position + MathUtils.Position(.2f, .2f));
        }
示例#4
0
        /// <summary>
        /// Function gets called on enemy death.
        /// </summary>
        /// <param name="ent"> Entity that killed this enemy.</param>
        public override void OnDeath(Entity ent)
        {
            // Set not solid and disable collisions.
            Solid      = false;
            Collidable = false;

            // Start death timer.
            EnableDeathTimer();

            // Add shell on position of death.
            if (!(ent is EggEnemy))
            {
                Parent.AddEntity(new EggEnemy(new Vector2(Position.X, Position.Y + 11), 16, 16, _content, Parent));
            }

            // Play death animation.
            Animations.Play((int)ChickenEnemyAnimation.DEATH);

            // Disable the start of a new animtaion.
            Animations.Lock();

            // Call jump.
            Jump();

            // Set width and height to death sprite size.
            Height = 16;
            Width  = 15;
        }
示例#5
0
        /// <summary>
        /// Function gets called when a collision with this object occurs.
        /// </summary>
        /// <param name="ent"> Entity this object collides with.</param>
        /// <param name="penetration"> Amount of penetration.</param>
        /// <param name="side"> The side the objects collide on.</param>
        /// <param name="axis"> The axis that is being checked.</param>
        /// <param name="fromBounds"> Where the colliding entity came from.</param>
        public override void OnCollision(Entity ent, int penetration, CollisionTester.CollisionSide side, CollisionTester.Axis axis, Rectangle fromBounds)
        {
            // Check if collision is a player and came from the bottom.
            if (ent is Player && side == CollisionTester.CollisionSide.BOTTOM && axis == CollisionTester.Axis.Y)
            {
                // Check if there are any coins left.
                if (_coins > 0)
                {
                    // Remove a coin.
                    _coins--;

                    int halfHeight = (Height / 2);

                    // Create a new coin.
                    Coin coin = new Coin(new Vector2(Position.X + 2, Position.Y - halfHeight), _content, Parent);

                    // Coin should perform on free action.
                    coin.OnFree();

                    // Add coin to the level.
                    Parent.AddEntity(coin);

                    // Set the state to BUMP_START.
                    State = TileState.BUMP_START;
                }
            }
        }
示例#6
0
        void FareBuildSelect()
        {
            if (currentEntity != null)
            {
                Parent.RemoveEntity(currentEntity);
                currentEntity = null;
            }
            currentEntity = Parent.Controller.EntFactory.CreateRoom(GameVariables.RoomTypes.GREATHALL);
            currentEntity.SetPosition(new Vector2(64, 64));

            // This should really only be called after the room is set
            Parent.Controller.CurrentInn.IncreaseCustomerChance(40);

            Parent.AddEntity(currentEntity);
        }
示例#7
0
        public void TryUseItem(int time, SlotData slot, Position target)
        {
            if (!ValidTime(time))
            {
#if DEBUG
                Program.Print(PrintType.Error, "Invalid time useitem");
#endif
                Client.Disconnect();
                return;
            }

            if (slot.SlotId == HealthPotionSlotId)
            {
                if (HealthPotions > 0 && !HasConditionEffect(ConditionEffectIndex.Sick))
                {
                    Heal(100, false);
                    HealthPotions--;
                }
                return;
            }
            else if (slot.SlotId == MagicPotionSlotId)
            {
                if (MagicPotions > 0 && !HasConditionEffect(ConditionEffectIndex.Quiet))
                {
                    Heal(100, true);
                    MagicPotions--;
                }
                return;
            }

            Entity en = Parent.GetEntity(slot.ObjectId);
            if (slot.SlotId != 1)
            {
                (en as IContainer)?.UpdateInventorySlot(slot.SlotId);
            }
            if (en == null || !(en is IContainer))
            {
#if DEBUG
                Program.Print(PrintType.Error, "Undefined entity");
#endif
                return;
            }

            if (en is Player && !en.Equals(this))
            {
#if DEBUG
                Program.Print(PrintType.Error, "Trying to use items from another players inventory");
#endif
                return;
            }

            if (en is Container c)
            {
                if ((en as Container).OwnerId != -1 && (en as Container).OwnerId != Id)
                {
#if DEBUG
                    Program.Print(PrintType.Error, "Trying to use items from another players container/bag");
#endif
                    return;
                }

                if (en.Position.Distance(this) > ContainerMinimumDistance)
                {
#if DEBUG
                    Program.Print(PrintType.Error, "Too far away from container");
#endif
                    return;
                }
            }

            IContainer con  = en as IContainer;
            ItemDesc   desc = null;
            if (con.Inventory[slot.SlotId] != -1)
            {
                desc = Resources.Type2Item[(ushort)con.Inventory[slot.SlotId]];
            }

            if (desc == null)
            {
#if DEBUG
                Program.Print(PrintType.Error, "Invalid use item");
#endif
                return;
            }

            bool isAbility = slot.SlotId == 1;
            if (isAbility)
            {
                if (slot.ObjectId != Id)
                {
#if DEBUG
                    Program.Print(PrintType.Error, "Trying to use ability from a container?");
#endif
                    return;
                }

                if (UseTime + (UseDuration * (1f / UseCooldownThreshold)) > time)
                {
#if DEBUG
                    Program.Print(PrintType.Error, "Used ability too soon");
#endif
                    return;
                }

                if (MP - desc.MpCost < 0)
                {
#if DEBUG
                    Program.Print(PrintType.Error, "Not enough MP");
#endif
                    return;
                }
            }

            bool   inRange  = Position.Distance(target) <= MaxAbilityDist && Parent.GetTileF(target.X, target.Y) != null;
            Action callback = null;
            foreach (ActivateEffectDesc eff in desc.ActivateEffects)
            {
                switch (eff.Index)
                {
                case ActivateEffectIndex.Shuriken:     //Could be optimized too, it's not great..
                {
                    byte[] nova = GameServer.ShowEffect(ShowEffectIndex.Nova, Id, 0xffeba134, new Position(2.5f, 0));

                    foreach (Entity j in Parent.EntityChunks.HitTest(Position, 2.5f))
                    {
                        if (j is Enemy k &&
                            !k.HasConditionEffect(ConditionEffectIndex.Invincible) &&
                            !k.HasConditionEffect(ConditionEffectIndex.Stasis))
                        {
                            k.ApplyConditionEffect(ConditionEffectIndex.Dazed, 1000);
                        }
                    }

                    List <byte[]>    stars  = new List <byte[]>();
                    HashSet <Entity> seeked = new HashSet <Entity>();
                    int startId             = NextAEProjectileId;
                    NextAEProjectileId += eff.Amount;

                    float angle = Position.Angle(target);
                    float cone  = MathF.PI / 8;
                    for (int i = 0; i < eff.Amount; i++)
                    {
                        Entity t = this.GetNearestEnemy(8, angle, cone, target, seeked) ?? this.GetNearestEnemy(6, seeked);
                        if (t != null)
                        {
                            seeked.Add(t);
                        }
                        int   d = GetNextDamage(desc.Projectile.MinDamage, desc.Projectile.MaxDamage, ItemDatas[slot.SlotId]);
                        float a = t == null?MathUtils.NextAngle() : Position.Angle(t.Position);

                        List <Projectile> p = new List <Projectile>()
                        {
                            new Projectile(this, desc.Projectile, startId + i, time, a, Position, d)
                        };

                        stars.Add(GameServer.ServerPlayerShoot(startId + i, Id, desc.Type, Position, a, 0, p));
                        AwaitProjectiles(p);
                    }

                    foreach (Entity j in Parent.PlayerChunks.HitTest(Position, SightRadius))
                    {
                        if (j is Player k)
                        {
                            if (k.Client.Account.Effects || k.Equals(this))
                            {
                                k.Client.Send(nova);
                            }
                            if (k.Client.Account.AllyShots || k.Equals(this))
                            {
                                foreach (byte[] s in stars)
                                {
                                    k.Client.Send(s);
                                }
                            }
                        }
                    }
                }
                break;

                case ActivateEffectIndex.VampireBlast:     //Maybe optimize this...?
                    if (inRange)
                    {
                        byte[] line       = GameServer.ShowEffect(ShowEffectIndex.Line, Id, 0xFFFF0000, target);
                        byte[] burst      = GameServer.ShowEffect(ShowEffectIndex.Burst, Id, 0xFFFF0000, target, new Position(target.X + eff.Radius, target.Y));
                        int    lifeSucked = 0;

                        List <Entity> enemies = new List <Entity>();
                        List <Entity> players = new List <Entity>();
                        List <byte[]> flows   = new List <byte[]>();

                        foreach (Entity j in Parent.EntityChunks.HitTest(target, eff.Radius))
                        {
                            if (j is Enemy k &&
                                !k.HasConditionEffect(ConditionEffectIndex.Invincible) &&
                                !k.HasConditionEffect(ConditionEffectIndex.Stasis))
                            {
                                k.Damage(this, eff.TotalDamage, eff.Effects, true, true);
                                lifeSucked += eff.TotalDamage;
                                enemies.Add(k);
                            }
                        }

                        foreach (Entity j in Parent.PlayerChunks.HitTest(Position, eff.Radius))
                        {
                            if (j is Player k)
                            {
                                players.Add(k);
                                k.Heal(lifeSucked, false);
                            }
                        }

                        if (enemies.Count > 0)
                        {
                            for (int i = 0; i < 5; i++)
                            {
                                Entity a = enemies[MathUtils.Next(enemies.Count)];
                                Entity b = players[MathUtils.Next(players.Count)];
                                flows.Add(GameServer.ShowEffect(ShowEffectIndex.Flow, b.Id, 0xffffffff, a.Position));
                            }
                        }

                        foreach (Entity j in Parent.PlayerChunks.HitTest(Position, SightRadius))
                        {
                            if (j is Player k)
                            {
                                if (k.Client.Account.Effects)
                                {
                                    k.Client.Send(line);
                                    foreach (byte[] p in flows)
                                    {
                                        k.Client.Send(p);
                                    }
                                }

                                if (k.Client.Account.Effects || k.Equals(this))
                                {
                                    k.Client.Send(burst);
                                }
                            }
                        }
                    }
                    break;

                case ActivateEffectIndex.StasisBlast:
                    if (inRange)
                    {
                        byte[] blast = GameServer.ShowEffect(ShowEffectIndex.Collapse, Id, 0xffffffff,
                                                             target,
                                                             new Position(target.X + 3, target.Y));
                        List <byte[]> notifications = new List <byte[]>();

                        foreach (Entity j in Parent.EntityChunks.HitTest(target, 3))
                        {
                            if (j is Enemy k)
                            {
                                if (k.HasConditionEffect(ConditionEffectIndex.StasisImmune))
                                {
                                    notifications.Add(GameServer.Notification(k.Id, "Immune", 0xff00ff00));
                                    continue;
                                }

                                if (k.HasConditionEffect(ConditionEffectIndex.Stasis))
                                {
                                    continue;
                                }

                                notifications.Add(GameServer.Notification(k.Id, "Stasis", 0xffff0000));
                                k.ApplyConditionEffect(ConditionEffectIndex.Stasis, eff.DurationMS);
                                k.ApplyConditionEffect(ConditionEffectIndex.StasisImmune, eff.DurationMS + 3000);
                            }
                        }

                        foreach (Entity j in Parent.PlayerChunks.HitTest(Position, SightRadius))
                        {
                            if (j is Player k)
                            {
                                if (k.Client.Account.Effects || k.Equals(this))
                                {
                                    k.Client.Send(blast);
                                }
                                if (k.Client.Account.Notifications || k.Equals(this))
                                {
                                    foreach (byte[] n in notifications)
                                    {
                                        k.Client.Send(n);
                                    }
                                }
                            }
                        }
                    }
                    break;

                case ActivateEffectIndex.Trap:
                    if (inRange)
                    {
                        byte[] @throw = GameServer.ShowEffect(ShowEffectIndex.Throw, Id, 0xff9000ff, target);
                        foreach (Entity j in Parent.PlayerChunks.HitTest(Position, SightRadius))
                        {
                            if (j is Player k && (k.Client.Account.Effects || k.Equals(this)))
                            {
                                k.Client.Send(@throw);
                            }
                        }

                        Manager.AddTimedAction(1500, () =>
                        {
                            if (Parent != null)
                            {
                                Parent.AddEntity(new Trap(this, eff.Radius, eff.TotalDamage, eff.Effects), target);
                            }
                        });
                    }
                    break;

                case ActivateEffectIndex.Lightning:
                {
                    float  angle = Position.Angle(target);
                    float  cone  = MathF.PI / 4;
                    Entity start = this.GetNearestEnemy(MaxAbilityDist, angle, cone, target);

                    if (start == null)
                    {
                        float[] angles = new float[3] {
                            angle, angle - cone, angle + cone
                        };
                        byte[][] lines = new byte[3][];
                        for (int i = 0; i < 3; i++)
                        {
                            float x = (int)(MaxAbilityDist * MathF.Cos(angles[i])) + Position.X;
                            float y = (int)(MaxAbilityDist * MathF.Sin(angles[i])) + Position.Y;
                            lines[i] = GameServer.ShowEffect(ShowEffectIndex.Line, Id, 0xffff0088, new Position(x, y), new Position(350, 0));
                        }

                        foreach (Entity j in Parent.PlayerChunks.HitTest(Position, SightRadius))
                        {
                            if (j is Player k && k.Client.Account.Effects)
                            {
                                k.Client.Send(lines[0]);
                                k.Client.Send(lines[1]);
                                k.Client.Send(lines[2]);
                            }
                        }
                    }
                    else
                    {
                        Entity           prev    = this;
                        Entity           current = start;
                        HashSet <Entity> targets = new HashSet <Entity>();
                        List <byte[]>    pkts    = new List <byte[]>();
                        targets.Add(current);
                        (current as Enemy).Damage(this, eff.TotalDamage, eff.Effects, false, true);
                        for (int i = 1; i < eff.MaxTargets + 1; i++)
                        {
                            pkts.Add(GameServer.ShowEffect(ShowEffectIndex.Lightning, prev.Id, 0xffff0088,
                                                           new Position(current.Position.X, current.Position.Y),
                                                           new Position(350, 0)));

                            if (i == eff.MaxTargets)
                            {
                                break;
                            }

                            Entity next = current.GetNearestEnemy(10, targets);
                            if (next == null)
                            {
                                break;
                            }

                            targets.Add(next);
                            (next as Enemy).Damage(this, eff.TotalDamage, eff.Effects, false, true);
                            prev    = current;
                            current = next;
                        }

                        foreach (Entity j in Parent.PlayerChunks.HitTest(Position, SightRadius))
                        {
                            if (j is Player k && k.Client.Account.Effects)
                            {
                                foreach (byte[] p in pkts)
                                {
                                    Console.WriteLine(p.Length);
                                    k.Client.Send(p);
                                }
                            }
                        }
                    }
                }
                break;

                case ActivateEffectIndex.PoisonGrenade:
                    if (inRange)
                    {
                        Placeholder placeholder = new Placeholder();
                        Parent.AddEntity(placeholder, target);

                        byte[] @throw = GameServer.ShowEffect(ShowEffectIndex.Throw, Id, 0xffddff00, target);
                        byte[] nova   = GameServer.ShowEffect(ShowEffectIndex.Nova, placeholder.Id, 0xffddff00, new Position(eff.Radius, 0));

                        foreach (Entity j in Parent.PlayerChunks.HitTest(Position, SightRadius))
                        {
                            if (j is Player k && (k.Client.Account.Effects || k.Equals(this)))
                            {
                                k.Client.Send(@throw);
                            }
                        }

                        Manager.AddTimedAction(1500, () =>
                        {
                            if (placeholder.Parent != null)
                            {
                                if (Parent != null)
                                {
                                    foreach (Entity j in Parent.PlayerChunks.HitTest(Position, SightRadius))
                                    {
                                        if (j is Player k && (k.Client.Account.Effects || k.Equals(this)))
                                        {
                                            k.Client.Send(nova);
                                        }
                                    }
                                    foreach (Entity j in Parent.EntityChunks.HitTest(placeholder.Position, eff.Radius))
                                    {
                                        if (j is Enemy e)
                                        {
                                            e.ApplyPoison(this, new ConditionEffectDesc[0], (int)(eff.TotalDamage / (eff.DurationMS / 1000f)), eff.TotalDamage);
                                        }
                                    }
                                }
                                placeholder.Parent.RemoveEntity(placeholder);
                            }
                        });
示例#8
0
        public void Death(string killer)
        {
#if DEBUG
            if (Parent.Name.Equals("Dreamland"))
            {
                return;
            }
#endif
            if (Dead)
            {
                return;
            }

            Client.Active = false;
            Dead          = true;

            SaveToCharacter();
            Database.Death(killer, Client.Account, Client.Character);

            byte[] death = GameServer.Death(Client.Account.Id, Client.Character.Id, killer);
            Client.Send(death);

            byte[] text  = GameServer.Text("", 0, -1, 0, "", $"{Name} died at level {Level} killed by {killer}!");
            byte[] sound = GameServer.PlaySound("quack");

            foreach (Player p in Parent.Players.Values)
            {
                p.Client.Send(text);
                if (p.Client.Account.Sounds)
                {
                    p.Client.Send(sound);
                }
            }

            ushort type;
            int    time;
            switch (GetMaxedStats())
            {
            case 8: type = 0x0735; time = 600000; break;

            case 7: type = 0x0734; time = 600000; break;

            case 6: type = 0x072b; time = 600000; break;

            case 5: type = 0x072a; time = 600000; break;

            case 4: type = 0x0729; time = 600000; break;

            case 3: type = 0x0728; time = 600000; break;

            case 2: type = 0x0727; time = 600000; break;

            case 1: type = 0x0726; time = 600000; break;

            default:
                type = 0x0725; time = 300000;
                if (Level < 20)
                {
                    type = 0x0724; time = 60000;
                }
                if (Level <= 1)
                {
                    type = 0x0723; time = 30000;
                }
                break;
            }

            Entity grave = new Entity(type, time);
            grave.TrySetSV(StatType.Name, Name);
            Parent.AddEntity(grave, Position);
            Parent.RemoveEntity(this);

            Manager.AddTimedAction(1500, () =>
            {
                Client.Disconnect();
            });
        }
示例#9
0
        public void Death(Player killer)
        {
#if DEBUG
            if (killer == null)
            {
                throw new Exception("Undefined killer");
            }
#endif

            int baseExp = (int)Math.Ceiling(MaxHP / 10f);
            if (baseExp != 0)
            {
                List <Entity> l;
                foreach (Entity en in l = Parent.PlayerChunks.HitTest(Position, Player.SightRadius))
                {
                    if (!(en is Player player))
                    {
                        continue;
                    }
                    int exp = baseExp;
                    if (exp > Player.GetNextLevelEXP(player.Level) / 10)
                    {
                        exp = Player.GetNextLevelEXP(player.Level) / 10;
                    }
                    if (player.GainEXP(exp))
                    {
                        foreach (Entity p in l)
                        {
                            if (!p.Equals(player))
                            {
                                (p as Player).FameStats.LevelUpAssists++;
                            }
                        }
                    }
                }
            }

            int position = 0;
            foreach (KeyValuePair <int, int> i in DamageStorage.OrderByDescending(k => k.Value))
            {
                Entity en = Parent.GetEntity(i.Key);
                if (en == null)
                {
                    continue;
                }
                Player player = en as Player;

                if (Desc.Quest)
                {
                    player.HealthPotions = Math.Min(Player.MaxPotions, player.HealthPotions + 1);
                    player.MagicPotions  = Math.Min(Player.MaxPotions, player.MagicPotions + 1);
                }
                else
                {
                    if (MathUtils.Chance(.05f))
                    {
                        player.HealthPotions = Math.Min(Player.MaxPotions, player.HealthPotions + 1);
                    }
                    if (MathUtils.Chance(.05f))
                    {
                        player.MagicPotions = Math.Min(Player.MaxPotions, player.MagicPotions + 1);
                    }
                }

                if (!player.Equals(killer))
                {
                    player.FameStats.MonsterAssists++;
                    if (Desc.Cube)
                    {
                        player.FameStats.CubeAssists++;
                    }
                    if (Desc.Oryx)
                    {
                        player.FameStats.OryxAssists++;
                    }
                    if (Desc.God)
                    {
                        player.FameStats.GodAssists++;
                    }
                }

                if (Behavior != null && Behavior.Loots.Count > 0)
                {
                    List <int> items = new List <int>();
                    foreach (Loot l in Behavior.Loots)
                    {
                        float t = Math.Min(1f, i.Value / MaxHP);
                        int   j = l.TryObtainItem(this, player, position, t);
                        if (j != -1)
                        {
                            items.Add(j);
                        }
                        if (items.Count == Container.MaxSlots)
                        {
                            break;
                        }
                    }

                    if (items.Count > 0)
                    {
                        int bagType = 1;
                        for (int k = 0; k < items.Count; k++)
                        {
                            ItemDesc d = Resources.Type2Item[(ushort)items[k]];
                            if (d.BagType > bagType)
                            {
                                bagType = d.BagType;
                            }
                        }

                        if (bagType == 2)
                        {
                            player.FameStats.CyanBags++;
                        }
                        else if (bagType == 3)
                        {
                            player.FameStats.BlueBags++;
                        }
                        else if (bagType == 4)
                        {
                            player.FameStats.WhiteBags++;
                        }

                        Container c = new Container(Container.FromBagType(bagType), player.Id, 40000 * bagType);
                        for (int k = 0; k < items.Count; k++)
                        {
                            Tuple <bool, ItemData> roll = Resources.Type2Item[(ushort)items[k]].Roll();
                            c.Inventory[k] = items[k];
                            c.ItemDatas[k] = roll.Item1 ? (int)roll.Item2 : -1;
                            c.UpdateInventorySlot(k);
                        }
                        Parent.AddEntity(c, Position + MathUtils.Position(0.2f, 0.2f));
                    }
                }

                position++;
            }

            killer.FameStats.MonsterKills++;
            if (Desc.Cube)
            {
                killer.FameStats.CubeKills++;
            }
            if (Desc.Oryx)
            {
                killer.FameStats.OryxKills++;
            }
            if (Desc.God)
            {
                killer.FameStats.GodKills++;
            }

            if (Behavior != null)
            {
                foreach (Behavior b in Behavior.Behaviors)
                {
                    b.Death(this);
                }
                foreach (State s in CurrentStates)
                {
                    foreach (Behavior b in s.Behaviors)
                    {
                        b.Death(this);
                    }
                }
            }

            Dead = true;
            Parent.RemoveEntity(this);
        }
示例#10
0
        public void Chat(string text)
        {
            if (text.Length <= 0 || text.Length > 128)
            {
#if DEBUG
                Program.Print(PrintType.Error, "Text too short or too long");
#endif
                Client.Disconnect();
                return;
            }

            string validText = Regex.Replace(text, @"[^a-zA-Z0-9`!@#$%^&* ()_+|\-=\\{}\[\]:"";'<>?,./]", "");
            if (validText.Length <= 0)
            {
                SendError("Invalid text.");
                return;
            }

            if (LastChatTime + ChatCooldownMS > Manager.TotalTimeUnsynced)
            {
                SendError("Message sent too soon after previous one.");
                return;
            }

            LastChatTime = Manager.TotalTimeUnsynced;

            if (validText[0] == '/')
            {
                string[] s = validText.Split(' ');
                string[] j = new string[s.Length - 1];
                for (int i = 1; i < s.Length; i++)
                {
                    j[i - 1] = s[i];
                }
                string command = s[0];
                string input   = string.Join(' ', j);
                switch (command.ToLower())
                {
                case "/legendary":
                    if (Client.Account.Ranked)
                    {
                        int slot = int.Parse(j[0]);
                        if (Inventory[slot] != -1)
                        {
                            Tuple <bool, ItemData> roll = Resources.Type2Item[(ushort)Inventory[slot]].Roll();
                            while ((roll.Item2 & ItemData.T7) == 0)
                            {
                                roll = Resources.Type2Item[(ushort)Inventory[slot]].Roll();
                            }
                            ItemDatas[slot] = !roll.Item1 ? -1 : (int)roll.Item2;
                            UpdateInventorySlot(slot);
                            RecalculateEquipBonuses();
                        }
                    }
                    break;

                case "/roll":
                    if (Client.Account.Ranked)
                    {
                        for (int k = 0; k < 20; k++)
                        {
                            if (Inventory[k] != -1)
                            {
                                Tuple <bool, ItemData> roll = Resources.Type2Item[(ushort)Inventory[k]].Roll();
                                ItemDatas[k] = !roll.Item1 ? -1 : (int)roll.Item2;
                                UpdateInventorySlot(k);
                                RecalculateEquipBonuses();
                            }
                        }
                    }
                    break;

                case "/disconnect":
                case "/dcAll":
                case "/dc":
                    if (Client.Account.Ranked)
                    {
                        foreach (Client c in Manager.Clients.Values.ToArray())
                        {
                            try { c.Disconnect(); }
                            catch { }
                        }
                    }
                    break;

                case "/terminate":
                case "/stop":
                    if (Client.Account.Ranked)
                    {
                        Program.StartTerminating();
                        return;
                    }
                    break;

                case "/gimme":
                case "/give":
                    if (!Client.Account.Ranked)
                    {
                        SendError("Not ranked");
                        return;
                    }
                    if (Resources.IdLower2Item.TryGetValue(input.ToLower(), out ItemDesc item))
                    {
                        if (GiveItem(item.Type))
                        {
                            SendInfo("Success");
                        }
                        else
                        {
                            SendError("No inventory slots");
                        }
                    }
                    else
                    {
                        SendError($"Item <{input}> not found in GameData");
                    }
                    break;

                case "/create":
                case "/spawn":
                    if (!Client.Account.Ranked)
                    {
                        SendError("Not ranked");
                        return;
                    }
                    if (string.IsNullOrWhiteSpace(input))
                    {
                        SendHelp("/spawn <count> <entity>");
                        return;
                    }
                    int spawnCount;
                    if (!int.TryParse(j[0], out spawnCount))
                    {
                        spawnCount = -1;
                    }
                    if (Resources.IdLower2Object.TryGetValue((spawnCount == -1 ? input : string.Join(' ', j.Skip(1))).ToLower(), out ObjectDesc desc))
                    {
                        if (spawnCount == -1)
                        {
                            spawnCount = 1;
                        }
                        if (desc.Player || desc.Static)
                        {
                            SendError("Can't spawn this entity");
                            return;
                        }
                        SendInfo($"Spawning <{spawnCount}> <{desc.DisplayId}> in 2 seconds");
                        Position pos = Position;
                        Manager.AddTimedAction(2000, () =>
                        {
                            for (int i = 0; i < spawnCount; i++)
                            {
                                Entity entity = Resolve(desc.Type);
                                Parent?.AddEntity(entity, pos);
                            }
                        });
                    }
                    else
                    {
                        SendError($"Entity <{input}> not found in Game Data");
                    }
                    break;

                case "/max":
                    if (!Client.Account.Ranked)
                    {
                        SendError("Not ranked");
                        return;
                    }
                    for (int i = 0; i < Stats.Length; i++)
                    {
                        Stats[i] = (Desc as PlayerDesc).Stats[i].MaxValue;
                    }
                    UpdateStats();
                    SendInfo("Maxed");
                    break;

                case "/god":
                    if (!Client.Account.Ranked)
                    {
                        SendError("Not ranked");
                        return;
                    }
                    ApplyConditionEffect(ConditionEffectIndex.Invincible, HasConditionEffect(ConditionEffectIndex.Invincible) ? 0 : -1);
                    SendInfo($"Godmode set to {HasConditionEffect(ConditionEffectIndex.Invincible)}");
                    break;

                case "/allyshots":
                    Client.Account.AllyShots = !Client.Account.AllyShots;
                    SendInfo($"Ally shots set to {Client.Account.AllyShots}");
                    break;

                case "/allydamage":
                    Client.Account.AllyDamage = !Client.Account.AllyDamage;
                    SendInfo($"Ally damage set to {Client.Account.AllyDamage}");
                    break;

                case "/effects":
                    Client.Account.Effects = !Client.Account.Effects;
                    SendInfo($"Effects set to {Client.Account.Effects}");
                    break;

                case "/sounds":
                    Client.Account.Sounds = !Client.Account.Sounds;
                    SendInfo($"Sounds set to {Client.Account.Sounds}");
                    break;

                case "/notifications":
                    Client.Account.Notifications = !Client.Account.Notifications;
                    SendInfo($"Notifications set to {Client.Account.Notifications}");
                    break;

                case "/online":
                case "/who":
                    SendInfo($"" +
                             $"<{Manager.Clients.Values.Count(k => k.Player != null)} Player(s)> " +
                             $"<{string.Join(", ", Manager.Clients.Values.Where(k => k.Player != null).Select(k => k.Player.Name))}>");
                    break;

                case "/server":
                case "/pos":
                case "/loc":
                    SendInfo(this.ToString());
                    break;

                case "/where":
                case "/find":
                    Player findTarget = Manager.GetPlayer(input);
                    if (findTarget == null)
                    {
                        SendError("Couldn't find player");
                    }
                    else
                    {
                        SendInfo(findTarget.ToString());
                    }
                    break;

                case "/fame":
                case "/famestats":
                case "/stats":
                    SaveToCharacter();
                    FameStats fameStats = Database.CalculateStats(Client.Account, Client.Character, "");
                    SendInfo($"Active: {FameStats.MinutesActive} minutes");
                    SendInfo($"Shots: {FameStats.Shots}");
                    SendInfo($"Accuracy: {(int)(((float)FameStats.ShotsThatDamage / FameStats.Shots) * 100f)}% ({FameStats.ShotsThatDamage}/{FameStats.Shots})");
                    SendInfo($"Abilities Used: {FameStats.AbilitiesUsed}");
                    SendInfo($"Tiles Seen: {FameStats.TilesUncovered}");
                    SendInfo($"Monster Kills: {FameStats.MonsterKills} ({FameStats.MonsterAssists} Assists, {(int)(((float)FameStats.MonsterKills / (FameStats.MonsterKills + FameStats.MonsterAssists)) * 100f)}% Final Blows)");
                    SendInfo($"God Kills: {FameStats.GodKills} ({(int)(((float)FameStats.GodKills / FameStats.MonsterKills) * 100f)}%) ({FameStats.GodKills}/{FameStats.MonsterKills})");
                    SendInfo($"Oryx Kills: {FameStats.OryxKills} ({(int)(((float)FameStats.OryxKills / FameStats.MonsterKills) * 100f)}%) ({FameStats.OryxKills}/{FameStats.MonsterKills})");
                    SendInfo($"Cube Kills: {FameStats.CubeKills} ({(int)(((float)FameStats.CubeKills / FameStats.MonsterKills) * 100f)}%) ({FameStats.CubeKills}/{FameStats.MonsterKills})");
                    SendInfo($"Cyan Bags: {FameStats.CyanBags}");
                    SendInfo($"Blue Bags: {FameStats.BlueBags}");
                    SendInfo($"White Bags: {FameStats.WhiteBags}");
                    SendInfo($"Damage Taken: {FameStats.DamageTaken}");
                    SendInfo($"Damage Dealt: {FameStats.DamageDealt}");
                    SendInfo($"Teleports: {FameStats.Teleports}");
                    SendInfo($"Potions Drank: {FameStats.PotionsDrank}");
                    SendInfo($"Quests Completed: {FameStats.QuestsCompleted}");
                    SendInfo($"Pirate Caves Completed: {FameStats.PirateCavesCompleted}");
                    SendInfo($"Spider Dens Completed: {FameStats.SpiderDensCompleted}");
                    SendInfo($"Snake Pits Completed: {FameStats.SnakePitsCompleted}");
                    SendInfo($"Sprite Worlds Completed: {FameStats.SpriteWorldsCompleted}");
                    SendInfo($"Undead Lairs Completed: {FameStats.UndeadLairsCompleted}");
                    SendInfo($"Abyss Of Demons Completed: {FameStats.AbyssOfDemonsCompleted}");
                    SendInfo($"Tombs Completed: {FameStats.TombsCompleted}");
                    SendInfo($"Escapes: {FameStats.Escapes}");
                    SendInfo($"Near Death Escapes: {FameStats.NearDeathEscapes}");
                    SendInfo($"Party Member Level Ups: {FameStats.LevelUpAssists}");
                    foreach (FameBonus bonus in fameStats.Bonuses)
                    {
                        SendHelp($"{bonus.Name}: +{bonus.Fame}");
                    }
                    SendInfo($"Base Fame: {fameStats.BaseFame}");
                    SendInfo($"Total Fame: {fameStats.TotalFame}");
                    break;

                default:
                    SendError("Unknown command");
                    break;
                }
                return;
            }

            if (Client.Account.Muted)
            {
                SendError("You are muted");
                return;
            }

            byte[] packet = GameServer.Text(Name, Id, NumStars, 5, "", validText);

            foreach (Player player in Parent.Players.Values)
            {
                if (!player.Client.Account.IgnoredIds.Contains(AccountId))
                {
                    player.Client.Send(packet);
                }
            }
        }