Add skip/none block type for drawing commands.

This commit is contained in:
UnknownShadow200 2016-07-20 19:06:23 +10:00
parent 95284fab2e
commit 4853612101
15 changed files with 107 additions and 92 deletions

View File

@ -93,8 +93,9 @@ namespace MCGalaxy.Commands.World {
Player.Message(p, " %HType %T/help newlvl themes %Hto see a list of themes."); Player.Message(p, " %HType %T/help newlvl themes %Hto see a list of themes.");
Player.Message(p, "%HSeed is optional, and controls how the level is generated."); Player.Message(p, "%HSeed is optional, and controls how the level is generated.");
Player.Message(p, " %HFlat theme: Seed specifies the grass height."); Player.Message(p, " %HFlat theme: Seed specifies the grass height.");
Player.Message(p, " %HOther themes: Seed affects how terrain is generated."); Player.Message(p, " %HHeightmap theme: Seed specifies url of heightmap image.");
Player.Message(p, "%HIf the seed is the same, the generated level will be the same."); Player.Message(p, " %HOther themes: Seed affects how terrain is generated. " +
"If seed is the same, the generated level will be the same.");
} }
public override void Help(Player p, string message) { public override void Help(Player p, string message) {

View File

@ -68,8 +68,10 @@ namespace MCGalaxy.Commands.Building {
Player.Message(p, "%T/help brush [name]"); Player.Message(p, "%T/help brush [name]");
Player.Message(p, "%HOutputs the help for the brush with the given name."); Player.Message(p, "%HOutputs the help for the brush with the given name.");
Player.Message(p, "%HAvailable brushes: %S" + AvailableBrushes); Player.Message(p, "%HAvailable brushes: %S" + AvailableBrushes);
Player.Message(p, "%HThe default brush simply takes one argument specifying the block to draw with. " + Player.Message(p, "%H The default brush takes one argument specifying the block to draw with. " +
"If no arguments are given, your currently held block is used instead."); "If no arguments are given, draws with your currently held block.");
Player.Message(p, "%H If \"skip\" is used for a block name, " +
"existing blocks in the map will not be replaced by this block.");
} }
public override void Help(Player p, string message) { public override void Help(Player p, string message) {

View File

@ -32,10 +32,13 @@ namespace MCGalaxy.Commands.Building {
if (args.Length != 2) { Help(p); return; } if (args.Length != 2) { Help(p); return; }
DrawArgs dArgs = default(DrawArgs); DrawArgs dArgs = default(DrawArgs);
dArgs.type = DrawCmd.GetBlock(p, args[0], out dArgs.extType); int block = DrawCmd.GetBlock(p, args[0], out dArgs.extBlock);
if (dArgs.type == Block.Zero) return; if (block == -1) return;
dArgs.newType = DrawCmd.GetBlock(p, args[1], out dArgs.newExtType); dArgs.block = (byte)block;
if (dArgs.newType == Block.Zero) return;
int newBlock = DrawCmd.GetBlock(p, args[1], out dArgs.newExtBlock);
if (newBlock == -1) return;
dArgs.newBlock = (byte)block;
Player.Message(p, "Place two blocks to determine the edges."); Player.Message(p, "Place two blocks to determine the edges.");
p.MakeSelection(2, dArgs, DoOutline); p.MakeSelection(2, dArgs, DoOutline);
@ -44,11 +47,11 @@ namespace MCGalaxy.Commands.Building {
bool DoOutline(Player p, Vec3S32[] marks, object state, byte type, byte extType) { bool DoOutline(Player p, Vec3S32[] marks, object state, byte type, byte extType) {
DrawArgs dArgs = (DrawArgs)state; DrawArgs dArgs = (DrawArgs)state;
OutlineDrawOp op = new OutlineDrawOp(); OutlineDrawOp op = new OutlineDrawOp();
op.Type = dArgs.type; op.ExtType = dArgs.extType; op.Block = dArgs.block; op.ExtBlock = dArgs.extBlock;
op.NewType = dArgs.newType; op.NewExtType = dArgs.newExtType; op.NewBlock = dArgs.newBlock; op.NewExtBlock = dArgs.newExtBlock;
return DrawOp.DoDrawOp(op, null, p, marks); return DrawOp.DoDrawOp(op, null, p, marks);
} }
struct DrawArgs { public byte type, extType, newType, newExtType; } struct DrawArgs { public byte block, extBlock, newBlock, newExtBlock; }
public override void Help(Player p) { public override void Help(Player p) {
Player.Message(p, "%T/outline [type] [type2]"); Player.Message(p, "%T/outline [type] [type2]");

View File

@ -45,18 +45,22 @@ namespace MCGalaxy.Commands.Building {
if (cState.Y != cState.OriginY) m[0].Y -= (cState.Height - 1); if (cState.Y != cState.OriginY) m[0].Y -= (cState.Height - 1);
if (cState.Z != cState.OriginZ) m[0].Z -= (cState.Length - 1); if (cState.Z != cState.OriginZ) m[0].Z -= (cState.Length - 1);
DrawOp op;
if (message == "") { if (message == "") {
op = new SimplePasteDrawOp(); SimplePasteDrawOp simpleOp = new SimplePasteDrawOp();
((SimplePasteDrawOp)op).CopyState = p.CopyBuffer; simpleOp.CopyState = p.CopyBuffer;
} else { return DrawOp.DoDrawOp(simpleOp, null, p, m);
op = new PasteDrawOp(); }
((PasteDrawOp)op).CopyState = p.CopyBuffer;
PasteDrawOp op = new PasteDrawOp();
op.CopyState = p.CopyBuffer;
string[] args = message.Split(' '); string[] args = message.Split(' ');
if (args[0].CaselessEq("not"))
((PasteDrawOp)op).Exclude = ReplaceBrush.GetBlocks(p, 1, args.Length, args); if (args[0].CaselessEq("not")) {
else op.Exclude = ReplaceBrush.GetBlocks(p, 1, args.Length, args);
((PasteDrawOp)op).Include = ReplaceBrush.GetBlocks(p, 0, args.Length, args); if (op.Exclude == null) return false;
} else {
op.Include = ReplaceBrush.GetBlocks(p, 0, args.Length, args);
if (op.Include == null) return false;
} }
return DrawOp.DoDrawOp(op, null, p, m); return DrawOp.DoDrawOp(op, null, p, m);
} }

View File

@ -27,7 +27,8 @@ namespace MCGalaxy.Commands.Building {
public CmdPlace() { } public CmdPlace() { }
public override void Use(Player p, string message) { public override void Use(Player p, string message) {
byte type = Block.Zero, extType = 0; int type = -1;
byte extType = 0;
ushort x = p.pos[0], y = (ushort)(p.pos[1] - 32), z = p.pos[2]; ushort x = p.pos[0], y = (ushort)(p.pos[1] - 32), z = p.pos[2];
try { try {
@ -53,12 +54,12 @@ namespace MCGalaxy.Commands.Building {
Player.Message(p, "Invalid parameters"); return; Player.Message(p, "Invalid parameters"); return;
} }
if (type == Block.Zero) return; if (type == -1 || type == Block.Zero) return;
if (!Block.canPlace(p, type)) { Player.Message(p, "Cannot place that block type."); return; } if (!Block.canPlace(p, (byte)type)) { Player.Message(p, "Cannot place that block type."); return; }
Vec3U16 P = Vec3U16.ClampPos(x, y, z, p.level); Vec3U16 P = Vec3U16.ClampPos(x, y, z, p.level);
P.X /= 32; P.Y /= 32; P.Z /= 32; P.X /= 32; P.Y /= 32; P.Z /= 32;
p.level.UpdateBlock(p, P.X, P.Y, P.Z, type, extType); p.level.UpdateBlock(p, P.X, P.Y, P.Z, (byte)type, extType);
Player.Message(p, "A block was placed at (" + P.X + ", " + P.Y + ", " + P.Z + ")."); Player.Message(p, "A block was placed at (" + P.X + ", " + P.Y + ", " + P.Z + ").");
} }

View File

@ -44,9 +44,10 @@ namespace MCGalaxy.Commands.Building {
string[] parts = ((string)state).SplitSpaces(3); string[] parts = ((string)state).SplitSpaces(3);
if (parts.Length < 2) { Help(p); return false; } if (parts.Length < 2) { Help(p); return false; }
byte extTile = 0; byte extBlock = 0;
byte tile = DrawCmd.GetBlock(p, parts[0], out extTile); int block = DrawCmd.GetBlock(p, parts[0], out extBlock);
if (tile == Block.Zero) return false; if (block == -1) return false;
string brushName = CmdBrush.FindBrush(parts[1]); string brushName = CmdBrush.FindBrush(parts[1]);
if (brushName == null) { if (brushName == null) {
Player.Message(p, "No brush found with name \"" + parts[1] + "\"."); Player.Message(p, "No brush found with name \"" + parts[1] + "\".");
@ -60,8 +61,8 @@ namespace MCGalaxy.Commands.Building {
if (brush == null) return false; if (brush == null) return false;
DrawOp drawOp = null; DrawOp drawOp = null;
if (ReplaceNot) drawOp = new ReplaceNotDrawOp(tile, extTile); if (ReplaceNot) drawOp = new ReplaceNotDrawOp((byte)block, extBlock);
else drawOp = new ReplaceDrawOp(tile, extTile); else drawOp = new ReplaceDrawOp((byte)block, extBlock);
return DrawOp.DoDrawOp(drawOp, brush, p, marks); return DrawOp.DoDrawOp(drawOp, brush, p, marks);
} }

View File

@ -50,23 +50,25 @@ namespace MCGalaxy.Commands.Building {
return message == "" ? DrawMode.normal : ParseMode(parts[parts.Length - 1]); return message == "" ? DrawMode.normal : ParseMode(parts[parts.Length - 1]);
} }
internal static byte GetBlock(Player p, string msg, out byte extType, bool checkPlacePerm = true) { internal static int GetBlock(Player p, string msg, out byte extType, bool checkPlacePerm = true) {
byte type = Block.Byte(msg); byte type = Block.Byte(msg);
extType = 0; extType = 0;
if (msg.CaselessEq("skip") || msg.CaselessEq("none")) return Block.Zero;
if (type == Block.Zero) { if (type == Block.Zero) {
// try treat as a block definition id. // try treat as a block definition id.
type = BlockDefinition.GetBlock(msg, p); type = BlockDefinition.GetBlock(msg, p);
if (type == Block.Zero) { if (type == Block.Zero) {
Player.Message(p, "There is no block \"" + msg + "\"."); Player.Message(p, "There is no block \"{0}\".", msg);
return Block.Zero; return -1;
} }
extType = type; extType = type;
return Block.custom_block; return Block.custom_block;
} }
if (checkPlacePerm && !Block.canPlace(p, type)) { if (checkPlacePerm && !Block.canPlace(p, type)) {
Player.Message(p, "Cannot place the block \"" + msg + "\"."); Player.Message(p, "Cannot place the block \"{0}\".", msg);
return Block.Zero; return -1;
} }
return type; return type;
} }

View File

@ -45,16 +45,17 @@ namespace MCGalaxy.Drawing.Brushes {
if (args.Message == "") if (args.Message == "")
return new CheckeredBrush(args.Type, args.ExtType, 0, 0); return new CheckeredBrush(args.Type, args.ExtType, 0, 0);
string[] parts = args.Message.Split(' '); string[] parts = args.Message.Split(' ');
byte extType1;
byte type1 = DrawCmd.GetBlock(args.Player, parts[0], out extType1);
if (type1 == Block.Zero) return null;
if (parts.Length == 1)
return new CheckeredBrush(type1, extType1, Block.Zero, 0);
byte extType2; byte extBlock1;
byte type2 = DrawCmd.GetBlock(args.Player, parts[1], out extType2); int block1 = DrawCmd.GetBlock(args.Player, parts[0], out extBlock1);
if (type2 == Block.Zero) return null; if (block1 == -1) return null;
return new CheckeredBrush(type1, extType1, type2, extType2); if (parts.Length == 1)
return new CheckeredBrush((byte)block1, extBlock1, Block.Zero, 0);
byte extBlock2;
int block2 = DrawCmd.GetBlock(args.Player, parts[1], out extBlock2);
if (block2 == -1) return null;
return new CheckeredBrush((byte)block1, extBlock1, (byte)block2, extBlock2);
} }
public override byte NextBlock(DrawOp op) { public override byte NextBlock(DrawOp op) {

View File

@ -43,10 +43,10 @@ namespace MCGalaxy.Drawing.Brushes {
byte extType = 0; byte extType = 0;
int sepIndex = parts[i].IndexOf('/'); int sepIndex = parts[i].IndexOf('/');
string block = sepIndex >= 0 ? parts[i].Substring(0, sepIndex) : parts[i]; string block = sepIndex >= 0 ? parts[i].Substring(0, sepIndex) : parts[i];
byte type = DrawCmd.GetBlock(p, block, out extType); int type = DrawCmd.GetBlock(p, block, out extType);
if (type == Block.Zero) return null; if (type == -1) return null;
blocks[j].Type = type; blocks[j].ExtType = extType; blocks[j].Type = (byte)type; blocks[j].ExtType = extType;
if (sepIndex < 0) { j++; continue; } if (sepIndex < 0) { j++; continue; }
int chance; int chance;

View File

@ -41,16 +41,24 @@ namespace MCGalaxy.Drawing.Brushes {
}; };
public static Brush Process(BrushArgs args) { public static Brush Process(BrushArgs args) {
return ProcessReplace(args, false);
}
internal static Brush ProcessReplace(BrushArgs args, bool not) {
string[] parts = args.Message.Split(' '); string[] parts = args.Message.Split(' ');
if (parts.Length < 2) { if (parts.Length < 2) {
args.Player.SendMessage("You need to provide a target block, and at least one block to replace."); return null; args.Player.SendMessage("You need to provide a target block, and at least one block to replace."); return null;
} }
ExtBlock[] toAffect = GetBlocks(args.Player, 0, parts.Length - 1, parts); ExtBlock[] toAffect = GetBlocks(args.Player, 0, parts.Length - 1, parts);
if (toAffect == null) return null;
ExtBlock target; ExtBlock target;
target.Type = DrawCmd.GetBlock(args.Player, parts[parts.Length - 1], out target.ExtType); int block = DrawCmd.GetBlock(args.Player, parts[parts.Length - 1], out target.ExtType);
if (target.Type == Block.Zero) return null; if (block == -1) return null;
return target.Type == Block.Zero ? null : new ReplaceBrush(toAffect, target);
target.Type = (byte)block;
if (not) return new ReplaceNotBrush(toAffect, target);
return new ReplaceBrush(toAffect, target);
} }
internal static ExtBlock[] GetBlocks(Player p, int start, int max, string[] parts) { internal static ExtBlock[] GetBlocks(Player p, int start, int max, string[] parts) {
@ -58,10 +66,10 @@ namespace MCGalaxy.Drawing.Brushes {
for (int i = 0; i < blocks.Length; i++) for (int i = 0; i < blocks.Length; i++)
blocks[i].Type = Block.Zero; blocks[i].Type = Block.Zero;
for (int i = 0; start < max; start++, i++ ) { for (int i = 0; start < max; start++, i++ ) {
byte extType = 0; byte extBlock = 0;
byte type = DrawCmd.GetBlock(p, parts[start], out extType); int block = DrawCmd.GetBlock(p, parts[start], out extBlock);
if (type == Block.Zero) continue; if (block == -1) return null;
blocks[i].Type = type; blocks[i].ExtType = extType; blocks[i].Type = (byte)block; blocks[i].ExtType = extBlock;
} }
return blocks; return blocks;
} }
@ -103,16 +111,7 @@ namespace MCGalaxy.Drawing.Brushes {
}; };
public static Brush Process(BrushArgs args) { public static Brush Process(BrushArgs args) {
string[] parts = args.Message.Split(' '); return ReplaceBrush.ProcessReplace(args, true);
if (parts.Length < 2) {
args.Player.SendMessage("You need to provide a target block, and at least one block to replace."); return null;
}
ExtBlock[] toAffect = ReplaceBrush.GetBlocks(args.Player, 0, parts.Length - 1, parts);
ExtBlock target;
target.Type = DrawCmd.GetBlock(args.Player, parts[parts.Length - 1], out target.ExtType);
if (target.Type == Block.Zero) return null;
return target.Type == Block.Zero ? null : new ReplaceNotBrush(toAffect, target);
} }
public override byte NextBlock(DrawOp op) { public override byte NextBlock(DrawOp op) {

View File

@ -42,10 +42,10 @@ namespace MCGalaxy.Drawing.Brushes {
public static Brush Process(BrushArgs args) { public static Brush Process(BrushArgs args) {
if (args.Message == "") if (args.Message == "")
return new SolidBrush(args.Type, args.ExtType); return new SolidBrush(args.Type, args.ExtType);
byte extType; byte extBlock;
byte type = DrawCmd.GetBlock(args.Player, args.Message, out extType); int block = DrawCmd.GetBlock(args.Player, args.Message, out extBlock);
if (type == Block.Zero) return null; if (block == -1) return null;
return new SolidBrush(type, extType); return new SolidBrush((byte)block, extBlock);
} }
public override byte NextBlock(DrawOp op) { return type; } public override byte NextBlock(DrawOp op) { return type; }

View File

@ -45,16 +45,17 @@ namespace MCGalaxy.Drawing.Brushes {
if (args.Message == "") if (args.Message == "")
return new StripedBrush(args.Type, args.ExtType, 0, 0); return new StripedBrush(args.Type, args.ExtType, 0, 0);
string[] parts = args.Message.Split(' '); string[] parts = args.Message.Split(' ');
byte extType1;
byte type1 = DrawCmd.GetBlock(args.Player, parts[0], out extType1);
if (type1 == Block.Zero) return null;
if (parts.Length == 1)
return new StripedBrush(type1, extType1, 0, 0);
byte extType2; byte extBlock1;
byte type2 = DrawCmd.GetBlock(args.Player, parts[1], out extType2); int block1 = DrawCmd.GetBlock(args.Player, parts[0], out extBlock1);
if (type2 == Block.Zero) return null; if (block1 == -1) return null;
return new StripedBrush(type1, extType1, type2, extType2); if (parts.Length == 1)
return new StripedBrush((byte)block1, extBlock1, 0, 0);
byte extBlock2;
int block2 = DrawCmd.GetBlock(args.Player, parts[1], out extBlock2);
if (block2 == -1) return null;
return new StripedBrush((byte)block1, extBlock1, (byte)block2, extBlock2);
} }
public override byte NextBlock(DrawOp op) { public override byte NextBlock(DrawOp op) {

View File

@ -59,7 +59,7 @@ namespace MCGalaxy.Drawing.Ops {
public class OutlineDrawOp : CuboidDrawOp { public class OutlineDrawOp : CuboidDrawOp {
public override string Name { get { return "Outline"; } } public override string Name { get { return "Outline"; } }
public byte Type, ExtType, NewType, NewExtType; public byte Block, ExtBlock, NewBlock, NewExtBlock;
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max); Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
@ -76,14 +76,14 @@ namespace MCGalaxy.Drawing.Ops {
outline |= Check(lvl, x, (ushort)(y + 1), z); outline |= Check(lvl, x, (ushort)(y + 1), z);
if (outline && !Check(lvl, x, y, z)) if (outline && !Check(lvl, x, y, z))
yield return Place(x, y, z, NewType, NewExtType); yield return Place(x, y, z, NewBlock, NewExtBlock);
} }
} }
bool Check(Level lvl, ushort x, ushort y, ushort z) { bool Check(Level lvl, ushort x, ushort y, ushort z) {
byte tile = lvl.GetTile(x, y, z); byte tile = lvl.GetTile(x, y, z);
if (tile != Type) return false; if (tile != Block) return false;
return tile != Block.custom_block || lvl.GetExtTile(x, y, z) == ExtType; return tile != MCGalaxy.Block.custom_block || lvl.GetExtTile(x, y, z) == ExtBlock;
} }
} }

View File

@ -95,8 +95,8 @@ namespace MCGalaxy {
static bool CheckBlock(Player p, string value, string variable, ref byte modify) { static bool CheckBlock(Player p, string value, string variable, ref byte modify) {
byte extBlock = 0; byte extBlock = 0;
byte block = DrawCmd.GetBlock(p, value, out extBlock, false); int block = DrawCmd.GetBlock(p, value, out extBlock, false);
if (block == Block.Zero) return false; if (block == -1 || block == Block.Zero) return false;
if (block >= Block.CpeCount && block != Block.custom_block) { if (block >= Block.CpeCount && block != Block.custom_block) {
Player.Message(p, "Cannot use physics block ids for /env."); return false; Player.Message(p, "Cannot use physics block ids for /env."); return false;
} }
@ -105,7 +105,7 @@ namespace MCGalaxy {
block == Block.mushroom || block == Block.redmushroom || block == Block.rope || block == Block.fire) { block == Block.mushroom || block == Block.redmushroom || block == Block.rope || block == Block.fire) {
Player.Message(p, "Env: Cannot use {0} for {1}.", block, variable); Player.Message(p, "Env: Cannot use {0} for {1}.", block, variable);
} else { } else {
modify = block == Block.custom_block ? extBlock : block; modify = block == Block.custom_block ? extBlock : (byte)block;
Player.Message(p, "Set {0} for {1}%S to {2}", variable, p.level.name, modify); Player.Message(p, "Set {0} for {1}%S to {2}", variable, p.level.name, modify);
return true; return true;
} }