mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-23 20:53:40 -04:00
Add a real /sphere command.
This commit is contained in:
parent
783cb226dc
commit
5c3cb9d16e
@ -27,9 +27,9 @@ namespace MCGalaxy.Commands
|
||||
public override string name { get { return "cuboid"; } }
|
||||
public override string shortcut { get { return "z"; } }
|
||||
public override CommandAlias[] Aliases {
|
||||
get { return new[] { new CommandAlias("cw", "wire"),
|
||||
new CommandAlias("ch", "hollow"), new CommandAlias("walls", "walls"),
|
||||
new CommandAlias("box"), new CommandAlias("hbox", "hollow") }; }
|
||||
get { return new[] { new CommandAlias("cw", null, "wire"),
|
||||
new CommandAlias("ch", null, "hollow"), new CommandAlias("walls", null, "walls"),
|
||||
new CommandAlias("box"), new CommandAlias("hbox", null, "hollow") }; }
|
||||
}
|
||||
|
||||
protected override void Blockchange2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
|
||||
|
@ -73,22 +73,22 @@ namespace MCGalaxy.Commands {
|
||||
default:
|
||||
Help(p); return;
|
||||
}
|
||||
ushort radius = 0, height = 0;
|
||||
string[] args = cpos.message.Split(' ');
|
||||
if ((op.UsesHeight && !CheckTwoArgs(p, op, args)) ||
|
||||
(!op.UsesHeight && !CheckOneArg(p, op, args))) return;
|
||||
if ((op.UsesHeight && !CheckTwoArgs(p, ref radius, ref height, args)) ||
|
||||
(!op.UsesHeight && !CheckOneArg(p, ref radius, args))) return;
|
||||
|
||||
int brushOffset = op.UsesHeight ? 3 : 2;
|
||||
Brush brush = GetBrush(p, cpos, brushOffset);
|
||||
if (brush == null) return;
|
||||
|
||||
Vec3S32[] marks = {
|
||||
new Vec3S32(x - op.Radius, y, z - op.Radius),
|
||||
new Vec3S32(x + op.Radius, y, z + op.Radius) };
|
||||
new Vec3S32(x - radius, y, z - radius),
|
||||
new Vec3S32(x + radius, y, z + radius) };
|
||||
if (op.UsesHeight) {
|
||||
marks[1].Y += op.Height;
|
||||
marks[1].Y += height;
|
||||
} else {
|
||||
marks[0].Y -= op.Radius;
|
||||
marks[1].Y += op.Radius;
|
||||
marks[0].Y -= radius; marks[1].Y += radius;
|
||||
}
|
||||
|
||||
if (!DrawOp.DoDrawOp(op, brush, p, marks))
|
||||
@ -99,18 +99,18 @@ namespace MCGalaxy.Commands {
|
||||
|
||||
protected override void Blockchange2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) { }
|
||||
|
||||
bool CheckTwoArgs(Player p, AdvDrawOp op, string[] parts) {
|
||||
bool CheckTwoArgs(Player p, ref ushort radius, ref ushort height, string[] parts) {
|
||||
if (parts.Length < 3) { Help(p); return false; }
|
||||
if (!ushort.TryParse(parts[parts.Length - 3], out op.Height) || op.Height > 2000 ||
|
||||
!ushort.TryParse(parts[parts.Length - 2], out op.Radius) || op.Radius > 2000) {
|
||||
if (!ushort.TryParse(parts[parts.Length - 3], out height) || height > 2000 ||
|
||||
!ushort.TryParse(parts[parts.Length - 2], out radius) || radius > 2000) {
|
||||
Player.Message(p, "Radius and height must be positive integers less than 2000."); return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CheckOneArg(Player p, AdvDrawOp op, string[] parts) {
|
||||
bool CheckOneArg(Player p, ref ushort radius, string[] parts) {
|
||||
if (parts.Length < 2) { Help(p); return false; }
|
||||
if (!ushort.TryParse(parts[parts.Length - 2], out op.Radius) || op.Radius > 2000) {
|
||||
if (!ushort.TryParse(parts[parts.Length - 2], out radius) || radius > 2000) {
|
||||
Player.Message(p, "Radius must be a positive integer less than 2000."); return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -26,7 +26,8 @@ namespace MCGalaxy.Commands {
|
||||
public sealed class CmdLine : DrawCmd {
|
||||
|
||||
public override string name { get { return "line"; } }
|
||||
public override string shortcut { get { return "l"; } }
|
||||
public override string shortcut { get { return "l"; } }
|
||||
protected override string PlaceMessage { get { return "Place two blocks to determine the endpoints."; } }
|
||||
|
||||
protected override DrawMode ParseMode(string msg) {
|
||||
if (msg == "normal") return DrawMode.solid;
|
||||
|
79
Commands/building/CmdSphere.cs
Normal file
79
Commands/building/CmdSphere.cs
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
Copyright 2015 MCGalaxy
|
||||
|
||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||
not use this file except in compliance with the Licenses. You may
|
||||
obtain a copy of the Licenses at
|
||||
|
||||
http://www.opensource.org/licenses/ecl2.php
|
||||
http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the Licenses are distributed on an "AS IS"
|
||||
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
or implied. See the Licenses for the specific language governing
|
||||
permissions and limitations under the Licenses.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MCGalaxy.Drawing;
|
||||
using MCGalaxy.Drawing.Ops;
|
||||
using MCGalaxy.Drawing.Brushes;
|
||||
|
||||
namespace MCGalaxy.Commands {
|
||||
public sealed class CmdSphere : DrawCmd {
|
||||
|
||||
public override string name { get { return "sphere"; } }
|
||||
public override string shortcut { get { return "sp"; } }
|
||||
public override LevelPermission defaultRank { get { return LevelPermission.AdvBuilder; } }
|
||||
public override CommandAlias[] Aliases {
|
||||
get { return new[] { new CommandAlias("sphereh", null, "hollow"), new CommandAlias("sph", null, "hollow") }; }
|
||||
}
|
||||
protected override string PlaceMessage { get { return "Place a block for the centre, then another for the radius."; } }
|
||||
|
||||
protected override DrawMode ParseMode(string msg) {
|
||||
if (msg == "solid") return DrawMode.solid;
|
||||
else if (msg == "hollow") return DrawMode.hollow;
|
||||
return DrawMode.normal;
|
||||
}
|
||||
|
||||
protected override void Blockchange2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
|
||||
RevertAndClearState(p, x, y, z);
|
||||
CatchPos cpos = (CatchPos)p.blockchangeObject;
|
||||
GetRealBlock(type, extType, p, ref cpos);
|
||||
|
||||
int dx = cpos.x - x, dy = cpos.y - y, dz = cpos.z - z;
|
||||
int radius = (int)Math.Sqrt(dx * dx + dy * dy + dz * dz);
|
||||
Vec3S32[] marks = { new Vec3S32(cpos.x - radius, cpos.y - radius, cpos.z - radius),
|
||||
new Vec3S32(cpos.x + radius, cpos.y + radius, cpos.z + radius) };
|
||||
|
||||
DrawOp op = null;
|
||||
Func<BrushArgs, Brush> constructor = null;
|
||||
switch (cpos.mode) {
|
||||
case DrawMode.solid:
|
||||
op = new AdvSphereDrawOp();
|
||||
constructor = SolidBrush.Process; break;
|
||||
case DrawMode.hollow:
|
||||
op = new AdvHollowSphereDrawOp(); break;
|
||||
default:
|
||||
op = new AdvSphereDrawOp(); break;
|
||||
}
|
||||
int brushOffset = cpos.mode == DrawMode.normal ? 0 : 1;
|
||||
Brush brush = GetBrush(p, cpos, brushOffset, constructor);
|
||||
if (brush == null) return;
|
||||
|
||||
if (!DrawOp.DoDrawOp(op, brush, p, marks))
|
||||
return;
|
||||
if (p.staticCommands)
|
||||
p.Blockchange += new Player.BlockchangeEventHandler(Blockchange1);
|
||||
}
|
||||
|
||||
public override void Help(Player p) {
|
||||
Player.Message(p, "%T/sphere [brush args] <mode>");
|
||||
Player.Message(p, "%HCreates a sphere, using the first point as the centre, and the second point as the radius.");
|
||||
Player.Message(p, " %HFor help about brushes, type %T/help brush%H.");
|
||||
Player.Message(p, " %HModes: &fsolid/hollow");
|
||||
}
|
||||
}
|
||||
}
|
@ -27,8 +27,7 @@ namespace MCGalaxy.Commands {
|
||||
public override string name { get { return "spheroid"; } }
|
||||
public override string shortcut { get { return "e"; } }
|
||||
public override CommandAlias[] Aliases {
|
||||
get { return new[] { new CommandAlias("sphere"), new CommandAlias("eh", "hollow"),
|
||||
new CommandAlias("cylinder", "vertical") }; }
|
||||
get { return new[] { new CommandAlias("eh", null, "hollow"), new CommandAlias("cylinder", null, "vertical") }; }
|
||||
}
|
||||
|
||||
protected override void Blockchange2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
|
||||
|
@ -30,23 +30,24 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
public override string Name { get { return "Adv Cone"; } }
|
||||
|
||||
public override long GetBlocksAffected(Level lvl, Vec3S32[] marks) {
|
||||
long R = Radius, H = Height;
|
||||
long R = Radius, H = Max.Y - Min.Y;
|
||||
return (long)(Math.PI / 3 * (R * R * H));
|
||||
}
|
||||
|
||||
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
|
||||
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
|
||||
Vec3S32 C = (Min + Max) / 2;
|
||||
int height = Max.Y - Min.Y;
|
||||
|
||||
for (ushort y = p1.Y; y <= p2.Y; y++)
|
||||
for (ushort z = p1.Z; z <= p2.Z; z++)
|
||||
for (ushort x = p1.X; x <= p2.X; x++)
|
||||
{
|
||||
int xx = C.X - x, yy = y - Min.Y, zz = C.Z - z;
|
||||
int curHeight = Invert ? yy : Height - yy;
|
||||
int curHeight = Invert ? yy : height - yy;
|
||||
if (curHeight == 0) continue;
|
||||
|
||||
double curRadius = Radius * ((double)curHeight / (double)Height);
|
||||
double curRadius = Radius * ((double)curHeight / (double)height);
|
||||
int dist = xx * xx + zz * zz;
|
||||
if (dist > curRadius * curRadius) continue;
|
||||
|
||||
@ -62,7 +63,7 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
public override string Name { get { return "Adv Hollow Cone"; } }
|
||||
|
||||
public override long GetBlocksAffected(Level lvl, Vec3S32[] marks) {
|
||||
long R = Radius, H = Height;
|
||||
long R = Radius, H = Max.Y - Min.Y;
|
||||
double outer = (int)(Math.PI / 3 * (R * R * H));
|
||||
double inner = (int)(Math.PI / 3 * ((R - 1) * (R - 1) * (H - 1)));
|
||||
return (long)(outer - inner);
|
||||
@ -71,16 +72,17 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
|
||||
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
|
||||
Vec3S32 C = (Min + Max) / 2;
|
||||
int height = Max.Y - Min.Y;
|
||||
|
||||
for (ushort y = p1.Y; y <= p2.Y; y++)
|
||||
for (ushort z = p1.Z; z <= p2.Z; z++)
|
||||
for (ushort x = p1.X; x <= p2.X; x++)
|
||||
{
|
||||
int xx = C.X - x, yy = y - Min.Y, zz = C.Z - z;
|
||||
int curHeight = Invert ? yy : Height - yy;
|
||||
int curHeight = Invert ? yy : height - yy;
|
||||
if (curHeight == 0) continue;
|
||||
|
||||
double curRadius = Radius * ((double)curHeight / (double)Height);
|
||||
double curRadius = Radius * ((double)curHeight / (double)height);
|
||||
int dist = xx * xx + zz * zz;
|
||||
if (dist > curRadius * curRadius || dist < (curRadius - 1) * (curRadius - 1))
|
||||
continue;
|
||||
@ -97,23 +99,24 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
public override string Name { get { return "Adv Volcano"; } }
|
||||
|
||||
public override long GetBlocksAffected(Level lvl, Vec3S32[] marks) {
|
||||
long R = Radius, H = Height;
|
||||
long R = Radius, H = Max.Y - Min.Y;
|
||||
return (long)(Math.PI / 3 * (R * R * H));
|
||||
}
|
||||
|
||||
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
|
||||
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
|
||||
Vec3S32 C = (Min + Max) / 2;
|
||||
int height = Max.Y - Min.Y;
|
||||
|
||||
for (ushort y = p1.Y; y <= p2.Y; y++)
|
||||
for (ushort z = p1.Z; z <= p2.Z; z++)
|
||||
for (ushort x = p1.X; x <= p2.X; x++)
|
||||
{
|
||||
int xx = C.X - x, yy = y - Min.Y, zz = C.Z - z;
|
||||
int curHeight = Height - yy;
|
||||
int curHeight = height - yy;
|
||||
if (curHeight == 0) continue;
|
||||
|
||||
double curRadius = Radius * ((double)curHeight / (double)Height);
|
||||
double curRadius = Radius * ((double)curHeight / (double)height);
|
||||
int dist = xx * xx + zz * zz;
|
||||
if (dist > curRadius * curRadius) continue;
|
||||
|
||||
|
@ -26,7 +26,8 @@ using MCGalaxy.Drawing.Brushes;
|
||||
namespace MCGalaxy.Drawing.Ops {
|
||||
|
||||
public abstract class AdvDrawOp : DrawOp {
|
||||
public ushort Radius, Height;
|
||||
public int Radius { get { return (Max.X - Min.X) / 2; } }
|
||||
|
||||
public bool Invert;
|
||||
public virtual bool UsesHeight { get { return true; } }
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
public override string Name { get { return "Adv Pyramid"; } }
|
||||
|
||||
public override long GetBlocksAffected(Level lvl, Vec3S32[] marks) {
|
||||
long R = Radius, H = Height;
|
||||
long R = Radius, H = Max.Y - Min.Y;
|
||||
return (R * R * H) / 3;
|
||||
}
|
||||
|
||||
@ -42,11 +42,12 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
for (ushort z = p1.Z; z <= p2.Z; z++)
|
||||
for (ushort x = p1.X; x <= p2.X; x++)
|
||||
{
|
||||
int height = Max.Y - Min.Y;
|
||||
int xx = C.X - x, yy = y - Min.Y, zz = C.Z - z;
|
||||
int curHeight = Invert ? yy : Height - yy;
|
||||
int curHeight = Invert ? yy : height - yy;
|
||||
if (curHeight == 0) continue;
|
||||
|
||||
double curRadius = Radius * ((double)curHeight / (double)Height);
|
||||
double curRadius = Radius * ((double)curHeight / (double)height);
|
||||
if (Math.Abs(xx) > curRadius || Math.Abs(zz) > curRadius)
|
||||
continue;
|
||||
byte ctile = lvl.GetTile(x, y, z);
|
||||
@ -61,7 +62,7 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
public override string Name { get { return "Adv Hollow Pyramid"; } }
|
||||
|
||||
public override long GetBlocksAffected(Level lvl, Vec3S32[] marks) {
|
||||
long R = Radius, H = Height;
|
||||
long R = Radius, H = Max.Y - Min.Y;
|
||||
long outer = (R * R * H) / 3;
|
||||
long inner = ((R - 1) * (R - 1) * (H - 1)) / 3;
|
||||
return outer - inner;
|
||||
@ -70,16 +71,17 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
|
||||
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
|
||||
Vec3S32 C = (Min + Max) / 2;
|
||||
int height = Max.Y - Min.Y;
|
||||
|
||||
for (ushort y = p1.Y; y <= p2.Y; y++)
|
||||
for (ushort z = p1.Z; z <= p2.Z; z++)
|
||||
for (ushort x = p1.X; x <= p2.X; x++)
|
||||
{
|
||||
int xx = C.X - x, yy = y - Min.Y, zz = C.Z - z;
|
||||
int curHeight = Invert ? yy : Height - yy;
|
||||
int curHeight = Invert ? yy : height - yy;
|
||||
if (curHeight == 0) continue;
|
||||
|
||||
double curRadius = Radius * ((double)curHeight / (double)Height);
|
||||
double curRadius = Radius * ((double)curHeight / (double)height);
|
||||
int absx = Math.Abs(xx), absz = Math.Abs(zz);
|
||||
if (absx > curRadius || absz > curRadius) continue;
|
||||
if (absx < (curRadius - 1) && absz < (curRadius - 1)) continue;
|
||||
|
@ -143,6 +143,7 @@
|
||||
<Compile Include="Commands\building\CmdRainbow.cs" />
|
||||
<Compile Include="Commands\building\CmdRedo.cs" />
|
||||
<Compile Include="Commands\building\CmdReplaceBrush.cs" />
|
||||
<Compile Include="Commands\building\CmdSphere.cs" />
|
||||
<Compile Include="Commands\building\CmdTriangle.cs" />
|
||||
<Compile Include="Commands\building\ReplaceCmd.cs" />
|
||||
<Compile Include="Commands\building\CmdRestartPhysics.cs" />
|
||||
|
Loading…
x
Reference in New Issue
Block a user