void ResetProps(Player p, BlockProps[] scope, BlockID block)
        {
            scope[block] = BlockOptions.DefaultProps(scope, p.level, block);
            string name = BlockOptions.Name(scope, p, block);

            p.Message("Reset properties of {0} to default", name);
            BlockOptions.ApplyChanges(scope, p.level, block, true);
        }
        void ListProps(Player p, BlockProps[] scope, string[] args)
        {
            List <BlockID> filtered = FilterProps(scope);
            string         cmd      = "BlockProps " + args[0] + " list";
            string         modifier = args.Length > 2 ? args[2] : "";

            MultiPageOutput.Output(p, filtered, b => BlockOptions.Name(scope, p, b),
                                   cmd, "modified blocks", modifier, false);
        }
        void CopyProps(Player p, BlockProps[] scope, BlockID block, string[] args)
        {
            if (args.Length < 4)
            {
                Help(p); return;
            }
            BlockID dst = GetBlock(p, scope, args[3]);

            if (dst == Block.Invalid)
            {
                return;
            }

            scope[dst] = scope[block];
            scope[dst].ChangedScope |= BlockOptions.ScopeId(scope);

            p.Message("Copied properties of {0} to {1}",
                      BlockOptions.Name(scope, p, block),
                      BlockOptions.Name(scope, p, dst));
            BlockOptions.ApplyChanges(scope, p.level, block, true);
        }
        internal static void Detail(Player p, BlockProps[] scope, BlockID block)
        {
            BlockProps props = scope[block];
            string     name  = BlockOptions.Name(scope, p, block);

            p.Message("&TProperties of {0}:", name);

            if (props.KillerBlock)
            {
                p.Message("  Kills players who collide with this block");
            }
            if (props.DeathMessage != null)
            {
                p.Message("  Death message: &S" + props.DeathMessage);
            }

            if (props.IsDoor)
            {
                p.Message("  Is an ordinary door");
            }
            if (props.IsTDoor)
            {
                p.Message("  Is a tdoor (allows other blocks through when open)");
            }
            if (props.oDoorBlock != Block.Invalid)
            {
                p.Message("  Is an odoor (can be toggled by doors, and toggles other odoors)");
            }

            if (props.IsPortal)
            {
                p.Message("  Can be used as a &T/Portal");
            }
            if (props.IsMessageBlock)
            {
                p.Message("  Can be used as a &T/MessageBlock");
            }

            if (props.WaterKills)
            {
                p.Message("  Is destroyed by flooding water");
            }
            if (props.LavaKills)
            {
                p.Message("  Is destroyed by flooding lava");
            }

            if (props.OPBlock)
            {
                p.Message("  Is not affected by explosions");
            }
            if (props.IsRails)
            {
                p.Message("  Can be used as rails for &T/Train");
            }

            if (props.AnimalAI != AnimalAI.None)
            {
                p.Message("  Has the {0} AI behaviour", props.AnimalAI);
            }
            if (props.StackBlock != Block.Air)
            {
                p.Message("  Stacks as {0} when placed on top of itself",
                          BlockOptions.Name(scope, p, props.StackBlock));
            }
            if (props.Drownable)
            {
                p.Message("&H  Players can drown in this block");
            }

            if (props.GrassBlock != Block.Invalid)
            {
                p.Message("  Grows into {0} when in sunlight",
                          BlockOptions.Name(scope, p, props.GrassBlock));
            }
            if (props.DirtBlock != Block.Invalid)
            {
                p.Message("  Decays into {0} when in shadow",
                          BlockOptions.Name(scope, p, props.DirtBlock));
            }
        }