示例#1
0
        public IEnumerable <CommandChainEntry> EnumerateChain()
        {
            CommandChainEntry retVal = this;

            do
            {
                yield return(retVal);

                retVal = retVal.NextElement;
            } while (retVal != null);
        }
示例#2
0
        /// <summary>
        /// Saves a command block chain to a structure file at the given path. Does not attempt to modify it (e.g. for conditionals on turns).
        /// The file argument will be overwritten with a GZip-compressed NBT format structure file.
        /// </summary>
        /// <param name="chainStart">The beginning of the command block chain.</param>
        /// <param name="savePath">The path to the structure file where this command chain will be saved.</param>
        public void Save(CommandChainEntry chainStart, string savePath)
        {
            CommandChainEntry[]   chain = chainStart.EnumerateChain().ToArray();
            CommandBlockDirection dir   = CommandBlockDirection.East;

            int rowFlat    = 0;
            int height     = 0;
            int columnFlat = 0;

            NbtFile file = new NbtFile();

            file.RootTag = new NbtCompound("")
            {
                new NbtList("size")
                {
                    // TODO calculate size dynamically
                    new NbtInt(32),
                    new NbtInt(32),
                    new NbtInt(32)
                },
                //new NbtList("entities") { },
                new NbtList("palette")
                {
                },
                new NbtList("blocks")
                {
                },
                new NbtString("author", "MCCBL Compiler"),
                new NbtInt("version", 1)
            };

            for (int i = 0; i < chain.Length; i++)
            {
                int state = -1;
                rowFlat    = i / 32;
                columnFlat = i % 32;
                dir        = rowFlat % 2 == 0 ? CommandBlockDirection.East : CommandBlockDirection.West;
                if (columnFlat == 31)
                {
                    dir = height % 2 == 0 ? CommandBlockDirection.South : CommandBlockDirection.North;
                }

                //foreach (NbtCompound paletteE in ((NbtList)file.RootTag.Get("palette")))
                //{
                //    if (paletteE == GetPaletteSignature(CommandBlockInfo.FromEnums(chain[i].Data, dir)))
                //    {
                //        alreadyInPalette = true;
                //        break;
                //    }
                //    state++;
                //}

                NbtCompound palSig      = GetPaletteSignature(CommandBlockInfo.FromEnums(chain[i].Data, dir));
                var         paletteList = file.RootTag.Get <NbtList>("palette");

                // TODO does NbtCompound implement value equality? If not, we may have to use the general purpose IndexOf with our own comparison interface
                // Tested and does not

                // state = paletteList.IndexOf(palSig);

                for (int j = 0; j < paletteList.Count; j++)
                {
                    NbtCompound curPal = paletteList[j] as NbtCompound;
                    if (curPal == null)
                    {
                        continue;
                    }

                    if (AreCompoundsEqual(curPal, palSig))
                    {
                        // We found an equivalent palette entry
                        state = j;
                        break;
                    }
                }

                if (state == -1)
                {
                    paletteList.Add(palSig);
                    // TODO is this needed?
                    // file.RootTag["palette"] = paletteList;
                    state = paletteList.Count - 1;
                }
                NbtCompound block = new NbtCompound();
                if (rowFlat % 2 == 0)
                {
                    block.Add(new NbtList("pos")
                    {
                        new NbtInt(columnFlat), new NbtInt(height), new NbtInt(rowFlat)
                    });
                }
                else
                {
                    block.Add(new NbtList("pos")
                    {
                        new NbtInt(31 - columnFlat), new NbtInt(height), new NbtInt(rowFlat)
                    });
                }
                block.Add(new NbtCompound("nbt")
                {
                    new NbtByte("auto", Convert.ToByte(chain[i].Data.HasFlag(CommandBlockFlags.AlwaysOn))),
                    new NbtString("Command", chain[i].Command),
                    new NbtString("id", "Control"),
                    new NbtString("CustomName", "@"),
                    new NbtByte("TrackOutput", 0),
                    new NbtByte("powered", 0),
                    new NbtByte("conditionMet", 1),
                    new NbtInt("SuccessCount", 0)
                });


                block.Add(new NbtInt("state", state));
                file.RootTag.Get <NbtList>("blocks").Add(block);
            }
            file.SaveToFile(savePath, NbtCompression.GZip);
        }
示例#3
0
 /// <summary>
 /// Preprocesses a command chain to work around turn-conditionals and other quirks that may occur in the underlying compilation.
 /// </summary>
 /// <param name="chain">The chain which will be preprocessed in place.</param>
 public void Preprocess(CommandChainEntry chain)
 {
 }