diff --git a/build.gradle b/build.gradle
index 0b57d410..ca1f51e8 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,6 +5,7 @@ plugins {
id 'maven-publish'
id 'com.modrinth.minotaur' version '2.+'
id 'com.github.breadmoirai.github-release' version '2.4.1'
+ id 'checkstyle'
}
base {
@@ -81,6 +82,12 @@ dependencies {
testImplementation "com.code-intelligence:jazzer-junit:${project.jazzer_junit_version}"
}
+checkstyle {
+ toolVersion = project.checkstyle_version
+ configFile = rootProject.file("checkstyle.xml")
+ ignoreFailures = false
+}
+
test {
useJUnitPlatform()
systemProperty('clientcommands.regressionTestDir', file('regressionTests').absolutePath)
diff --git a/checkstyle.xml b/checkstyle.xml
new file mode 100644
index 00000000..c5181e29
--- /dev/null
+++ b/checkstyle.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gradle.properties b/gradle.properties
index abb10479..c247dd42 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -27,6 +27,7 @@ org.gradle.jvmargs=-Xmx2G
seedfinding_feature_version=1.171.9
seedfinding_seed_version=1.171.2
latticg_version=1.07
+ checkstyle_version=10.21.1
jazzer_junit_version=0.22.1
junit_version=5.11.3
diff --git a/src/main/java/net/earthcomputer/clientcommands/ClientCommands.java b/src/main/java/net/earthcomputer/clientcommands/ClientCommands.java
index 1ce694cb..fba30693 100644
--- a/src/main/java/net/earthcomputer/clientcommands/ClientCommands.java
+++ b/src/main/java/net/earthcomputer/clientcommands/ClientCommands.java
@@ -1,3 +1,4 @@
+// CHECKSTYLE:OFF: AvoidStarImport allow commands to be wildcard imported
package net.earthcomputer.clientcommands;
import com.mojang.brigadier.CommandDispatcher;
diff --git a/src/main/java/net/earthcomputer/clientcommands/command/AliasCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/AliasCommand.java
index 8388c6c2..b7d2731e 100644
--- a/src/main/java/net/earthcomputer/clientcommands/command/AliasCommand.java
+++ b/src/main/java/net/earthcomputer/clientcommands/command/AliasCommand.java
@@ -151,7 +151,7 @@ private static int listAliases(FabricClientCommandSource source) {
} else {
source.sendFeedback(Component.translatable("commands.calias.listAliases.success", aliasMap.size()));
for (String key : aliasMap.keySet()) {
- source.sendFeedback(Component.literal(ChatFormatting.BOLD + key + ChatFormatting.RESET + ": " + aliasMap.get(key).replace("%","%%")));
+ source.sendFeedback(Component.literal(ChatFormatting.BOLD + key + ChatFormatting.RESET + ": " + aliasMap.get(key).replace("%", "%%")));
}
}
return Command.SINGLE_SUCCESS;
diff --git a/src/main/java/net/earthcomputer/clientcommands/command/CEnchantCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/CEnchantCommand.java
index 678e2b83..dbc6aa99 100644
--- a/src/main/java/net/earthcomputer/clientcommands/command/CEnchantCommand.java
+++ b/src/main/java/net/earthcomputer/clientcommands/command/CEnchantCommand.java
@@ -95,7 +95,7 @@ private static int cenchant(FabricClientCommandSource source, ItemAndEnchantment
if (result.itemThrows() < 0) {
source.sendFeedback(Component.translatable("enchCrack.insn.itemThrows.noDummy"));
} else {
- source.sendFeedback(Component.translatable("enchCrack.insn.itemThrows", result.itemThrows(), (float)result.itemThrows() / (Configs.itemThrowsPerTick * 20)));
+ source.sendFeedback(Component.translatable("enchCrack.insn.itemThrows", result.itemThrows(), (float) result.itemThrows() / (Configs.itemThrowsPerTick * 20)));
}
source.sendFeedback(Component.translatable("enchCrack.insn.bookshelves", result.bookshelves()));
source.sendFeedback(Component.translatable("enchCrack.insn.slot", result.slot() + 1));
diff --git a/src/main/java/net/earthcomputer/clientcommands/command/CTitleCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/CTitleCommand.java
index 826477aa..84dd03f5 100644
--- a/src/main/java/net/earthcomputer/clientcommands/command/CTitleCommand.java
+++ b/src/main/java/net/earthcomputer/clientcommands/command/CTitleCommand.java
@@ -77,4 +77,4 @@ private static int executeTimes(FabricClientCommandSource source, int fadeIn, in
sendFeedback(Component.translatable("commands.ctitle.times"));
return Command.SINGLE_SUCCESS;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/net/earthcomputer/clientcommands/command/LookCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/LookCommand.java
index f013a12e..f0fd9f71 100644
--- a/src/main/java/net/earthcomputer/clientcommands/command/LookCommand.java
+++ b/src/main/java/net/earthcomputer/clientcommands/command/LookCommand.java
@@ -30,7 +30,7 @@ public static void register(CommandDispatcher dispatc
.then(literal("west")
.executes(ctx -> lookCardinal(ctx.getSource(), 90, 0)))
.then(literal("east")
- .executes(ctx -> lookCardinal(ctx.getSource(),-90, 0)))
+ .executes(ctx -> lookCardinal(ctx.getSource(), -90, 0)))
.then(literal("north")
.executes(ctx -> lookCardinal(ctx.getSource(), -180, 0)))
.then(literal("south")
diff --git a/src/main/java/net/earthcomputer/clientcommands/command/arguments/ExpressionArgument.java b/src/main/java/net/earthcomputer/clientcommands/command/arguments/ExpressionArgument.java
index 8494cbee..8ded622d 100644
--- a/src/main/java/net/earthcomputer/clientcommands/command/arguments/ExpressionArgument.java
+++ b/src/main/java/net/earthcomputer/clientcommands/command/arguments/ExpressionArgument.java
@@ -246,8 +246,9 @@ private Expression parseConstantOrFunction() throws CommandSyntaxException {
reader.setCursor(cursor);
- if (reader.canRead() && reader.peek() == '(')
+ if (reader.canRead() && reader.peek() == '(') {
suggestor = null;
+ }
Expression ret = parseParenthesized();
suggestor = null;
@@ -437,10 +438,10 @@ public boolean isAcceptableInputCount(int count) {
}
})
.put("acoth", (UnaryFunction) n -> 0.5 * Math.log((n + 1) / (n - 1)))
- .put("and", (TwoOrMoreFunction) vals -> (double)Arrays.stream(vals).mapToInt(val -> (int) val).reduce(~0, (a, b) -> a & b))
- .put("or", (TwoOrMoreFunction) vals -> (double)Arrays.stream(vals).mapToInt(val -> (int) val).reduce(0, (a, b) -> a | b))
- .put("xor", (TwoOrMoreFunction) vals -> (double)Arrays.stream(vals).mapToInt(val -> (int) val).reduce(0, (a, b) -> a ^ b))
- .put("not", (UnaryFunction) val -> (double)(~((int)val)))
+ .put("and", (TwoOrMoreFunction) vals -> (double) Arrays.stream(vals).mapToInt(val -> (int) val).reduce(~0, (a, b) -> a & b))
+ .put("or", (TwoOrMoreFunction) vals -> (double) Arrays.stream(vals).mapToInt(val -> (int) val).reduce(0, (a, b) -> a | b))
+ .put("xor", (TwoOrMoreFunction) vals -> (double) Arrays.stream(vals).mapToInt(val -> (int) val).reduce(0, (a, b) -> a ^ b))
+ .put("not", (UnaryFunction) val -> (double) (~((int) val)))
.build();
private final String type;
diff --git a/src/main/java/net/earthcomputer/clientcommands/features/FishingCracker.java b/src/main/java/net/earthcomputer/clientcommands/features/FishingCracker.java
index d8f709f4..9f123929 100644
--- a/src/main/java/net/earthcomputer/clientcommands/features/FishingCracker.java
+++ b/src/main/java/net/earthcomputer/clientcommands/features/FishingCracker.java
@@ -201,7 +201,7 @@ private static OptionalLong getSeed(UUID uuid) {
long b = (-4824621L * upperBits + 7847617L * lowerBits + 7847617L) >> 32;
long seed = 7847617L * a - 18218081L * b;
- if ((seed >>> 16 << 32) + (int)(((seed * 0x5deece66dL + 0xbL) & ((1L << 48) - 1)) >>> 16) == nextLongOutput) {
+ if ((seed >>> 16 << 32) + (int) (((seed * 0x5deece66dL + 0xbL) & ((1L << 48) - 1)) >>> 16) == nextLongOutput) {
// advance by -3
seed = (seed * 0x13A1F16F099DL + 0x95756C5D2097L) & ((1L << 48) - 1);
RandomSource rand = RandomSource.create(seed ^ 0x5deece66dL);
@@ -985,12 +985,12 @@ public void tick() {
} else {
if (this.state == State.BOBBING) {
Vec3 vec3 = this.velocity;
- double d = this.pos.y + vec3.y - (double)blockPos.getY() - (double)f;
+ double d = this.pos.y + vec3.y - (double) blockPos.getY() - (double) f;
if (Math.abs(d) < 0.01D) {
d += Math.signum(d) * 0.1D;
}
- this.velocity = new Vec3(vec3.x * 0.9D, vec3.y - d * (double)this.random.nextFloat() * 0.2D, vec3.z * 0.9D);
+ this.velocity = new Vec3(vec3.x * 0.9D, vec3.y - d * (double) this.random.nextFloat() * 0.2D, vec3.z * 0.9D);
if (this.hookCountdown <= 0 && this.fishTravelCountdown <= 0) {
this.inOpenWater = true;
} else {
@@ -1059,7 +1059,7 @@ private void onSwimmingStart() {
g = 1.0F;
}
- if ((double)g < 0.25D) {
+ if ((double) g < 0.25D) {
random.nextFloat();
random.nextFloat();
//this.playSound(this.getSplashSound(), g, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F);
@@ -1069,21 +1069,21 @@ private void onSwimmingStart() {
//this.playSound(this.getHighSpeedSplashSound(), g, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F);
}
- float h = (float)Mth.floor(this.pos.y);
+ float h = (float) Mth.floor(this.pos.y);
int j;
double k;
double l;
- for(j = 0; (float)j < 1.0F + FISHING_BOBBER_DIMENSIONS.width() * 20.0F; ++j) {
- k = (this.random.nextDouble() * 2.0D - 1.0D) * (double)FISHING_BOBBER_DIMENSIONS.width();
- l = (this.random.nextDouble() * 2.0D - 1.0D) * (double)FISHING_BOBBER_DIMENSIONS.width();
+ for (j = 0; (float) j < 1.0F + FISHING_BOBBER_DIMENSIONS.width() * 20.0F; ++j) {
+ k = (this.random.nextDouble() * 2.0D - 1.0D) * (double) FISHING_BOBBER_DIMENSIONS.width();
+ l = (this.random.nextDouble() * 2.0D - 1.0D) * (double) FISHING_BOBBER_DIMENSIONS.width();
random.nextDouble();
//this.world.addParticle(ParticleTypes.BUBBLE, this.pos.x + k, (double)(h + 1.0F), this.pos.z + l, vec3d.x, vec3d.y - this.random.nextDouble() * 0.20000000298023224D, vec3d.z);
}
- for(j = 0; (float)j < 1.0F + FISHING_BOBBER_DIMENSIONS.width() * 20.0F; ++j) {
- k = (this.random.nextDouble() * 2.0D - 1.0D) * (double)FISHING_BOBBER_DIMENSIONS.width();
- l = (this.random.nextDouble() * 2.0D - 1.0D) * (double)FISHING_BOBBER_DIMENSIONS.width();
+ for (j = 0; (float) j < 1.0F + FISHING_BOBBER_DIMENSIONS.width() * 20.0F; ++j) {
+ k = (this.random.nextDouble() * 2.0D - 1.0D) * (double) FISHING_BOBBER_DIMENSIONS.width();
+ l = (this.random.nextDouble() * 2.0D - 1.0D) * (double) FISHING_BOBBER_DIMENSIONS.width();
//this.world.addParticle(ParticleTypes.SPLASH, this.getX() + k, (double)(h + 1.0F), this.getZ() + l, vec3d.x, vec3d.y, vec3d.z);
}
}
@@ -1111,7 +1111,7 @@ private boolean updateMovementInFluid(TagKey tag, double d) {
mutable.set(p, q, r);
FluidState fluidState = this.level.getFluidState(mutable);
if (fluidState.is(tag)) {
- double f = (float)q + fluidState.getHeight(this.level, mutable);
+ double f = (float) q + fluidState.getHeight(this.level, mutable);
if (f >= aabb.minY) {
bl2 = true;
e = Math.max(f - aabb.minY, e);
@@ -1123,7 +1123,7 @@ private boolean updateMovementInFluid(TagKey tag, double d) {
if (vec3.length() > 0.0D) {
if (o > 0) {
- vec3 = vec3.scale(1.0D / (double)o);
+ vec3 = vec3.scale(1.0D / (double) o);
}
vec3 = vec3.normalize();
@@ -1185,7 +1185,7 @@ private void move(Vec3 movement) {
//this.checkBlockCollision(); // no interesting blocks
float i = this.getVelocityMultiplier();
- this.velocity = this.velocity.multiply((double)i, 1.0D, (double)i);
+ this.velocity = this.velocity.multiply(i, 1.0D, i);
if (this.level.getBlockStatesIfLoaded(this.boundingBox.deflate(0.001D)).anyMatch((blockStatex) -> blockStatex.is(BlockTags.FIRE) || blockStatex.is(Blocks.LAVA))) {
failedReason = "fire";
}
@@ -1212,7 +1212,7 @@ private float getVelocityMultiplier() {
Block block = this.level.getBlockState(BlockPos.containing(pos)).getBlock();
float f = block.getSpeedFactor();
if (block != Blocks.WATER && block != Blocks.BUBBLE_COLUMN) {
- return (double)f == 1.0D ? this.level
+ return (double) f == 1.0D ? this.level
.getBlockState(BlockPos.containing(this.pos.x, this.boundingBox.minY - 0.5000001D, this.pos.z)).getBlock().getSpeedFactor() : f;
} else {
return f;
@@ -1318,9 +1318,9 @@ private void tickFishingLogic(BlockPos pos) {
n = this.fishAngle * 0.017453292F;
o = Mth.sin(n);
p = Mth.cos(n);
- q = this.pos.x + (double)(o * (float)this.fishTravelCountdown * 0.1F);
- r = (double)((float)Mth.floor(this.pos.y) + 1.0F);
- s = this.pos.z + (double)(p * (float)this.fishTravelCountdown * 0.1F);
+ q = this.pos.x + (double) (o * (float) this.fishTravelCountdown * 0.1F);
+ r = (float) Mth.floor(this.pos.y) + 1.0F;
+ s = this.pos.z + (double) (p * (float) this.fishTravelCountdown * 0.1F);
blockState2 = level.getBlockState(BlockPos.containing(q, r - 1.0D, s));
if (blockState2.is(Blocks.WATER)) {
if (this.random.nextFloat() < 0.15F) {
@@ -1347,19 +1347,19 @@ private void tickFishingLogic(BlockPos pos) {
this.waitCountdown -= i;
n = 0.15F;
if (this.waitCountdown < 20) {
- n = (float)((double)n + (double)(20 - this.waitCountdown) * 0.05D);
+ n = (float) ((double) n + (double) (20 - this.waitCountdown) * 0.05D);
} else if (this.waitCountdown < 40) {
- n = (float)((double)n + (double)(40 - this.waitCountdown) * 0.02D);
+ n = (float) ((double) n + (double) (40 - this.waitCountdown) * 0.02D);
} else if (this.waitCountdown < 60) {
- n = (float)((double)n + (double)(60 - this.waitCountdown) * 0.01D);
+ n = (float) ((double) n + (double) (60 - this.waitCountdown) * 0.01D);
}
if (this.random.nextFloat() < n) {
o = Mth.nextFloat(this.random, 0.0F, 360.0F) * 0.017453292F;
p = Mth.nextFloat(this.random, 25.0F, 60.0F);
- q = this.pos.x + (double)(Mth.sin(o) * p * 0.1F);
- r = (float)Mth.floor(this.pos.y) + 1.0F;
- s = this.pos.z + (double)(Mth.cos(o) * p * 0.1F);
+ q = this.pos.x + (double) (Mth.sin(o) * p * 0.1F);
+ r = (float) Mth.floor(this.pos.y) + 1.0F;
+ s = this.pos.z + (double) (Mth.cos(o) * p * 0.1F);
blockState2 = level.getBlockState(BlockPos.containing(q, r - 1.0D, s));
if (blockState2.is(Blocks.WATER)) {
random.nextInt(2);
diff --git a/src/main/java/net/earthcomputer/clientcommands/features/PacketDumper.java b/src/main/java/net/earthcomputer/clientcommands/features/PacketDumper.java
index 5095d4c0..1369e86f 100644
--- a/src/main/java/net/earthcomputer/clientcommands/features/PacketDumper.java
+++ b/src/main/java/net/earthcomputer/clientcommands/features/PacketDumper.java
@@ -494,7 +494,7 @@ public void writeFixedBitSet(BitSet bitSet, int size) {
@Override
public @NotNull PacketDumpByteBuf writeChar(int value) {
- return dumpSimple("char", Character.toString((char)value), JsonWriter::value);
+ return dumpSimple("char", Character.toString((char) value), JsonWriter::value);
}
@Override
diff --git a/src/main/java/net/earthcomputer/clientcommands/features/PlayerRandCracker.java b/src/main/java/net/earthcomputer/clientcommands/features/PlayerRandCracker.java
index e80bf2bd..d93c6215 100644
--- a/src/main/java/net/earthcomputer/clientcommands/features/PlayerRandCracker.java
+++ b/src/main/java/net/earthcomputer/clientcommands/features/PlayerRandCracker.java
@@ -61,7 +61,7 @@ public static int nextInt() {
public static int nextInt(int bound) {
if ((bound & -bound) == bound) {
- return (int) ((bound * (long)next(31)) >> 31);
+ return (int) ((bound * (long) next(31)) >> 31);
}
int bits, val;
@@ -311,8 +311,8 @@ public static void onItemDamage(int amount, LivingEntity holder, ItemStack stack
if (Configs.toolBreakWarning && stack.getDamageValue() + amount >= stack.getMaxDamage() - 30) {
- if(stack.getDamageValue() + amount >= stack.getMaxDamage() - 15) {
- Minecraft.getInstance().player.playSound(SoundEvents.EXPERIENCE_ORB_PICKUP, 10,0.1f);
+ if (stack.getDamageValue() + amount >= stack.getMaxDamage() - 15) {
+ Minecraft.getInstance().player.playSound(SoundEvents.EXPERIENCE_ORB_PICKUP, 10, 0.1f);
}
MutableComponent durability = Component.literal(String.valueOf(stack.getMaxDamage() - stack.getDamageValue() - 1)).withStyle(ChatFormatting.RED);
@@ -326,10 +326,12 @@ public static void onItemDamage(int amount, LivingEntity holder, ItemStack stack
int unbreakingLevel_f = unbreakingLevel;
Runnable action = () -> throwItemsUntil(rand -> {
for (int i = 0; i < amount; i++) {
- if (stack.getItem() instanceof ArmorItem && rand.nextFloat() < 0.6)
+ if (stack.getItem() instanceof ArmorItem && rand.nextFloat() < 0.6) {
return false;
- if (rand.nextInt(unbreakingLevel_f + 1) == 0)
+ }
+ if (rand.nextInt(unbreakingLevel_f + 1) == 0) {
return false;
+ }
}
return true;
}, 64);
diff --git a/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java b/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java
index 78425230..ef036744 100644
--- a/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java
+++ b/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java
@@ -199,11 +199,13 @@ public static String getWikiSummary(String pageName) {
return null;
}
- if (result.query.pages.isEmpty())
+ if (result.query.pages.isEmpty()) {
return null;
+ }
var page = result.query.pages.values().iterator().next();
- if (page.missing != null || page.extract == null)
+ if (page.missing != null || page.extract == null) {
return null;
+ }
String html = page.extract;
return decode(html);
}
diff --git a/src/main/java/net/earthcomputer/clientcommands/util/MathUtil.java b/src/main/java/net/earthcomputer/clientcommands/util/MathUtil.java
index 812c06c0..12acc2a9 100644
--- a/src/main/java/net/earthcomputer/clientcommands/util/MathUtil.java
+++ b/src/main/java/net/earthcomputer/clientcommands/util/MathUtil.java
@@ -137,8 +137,9 @@ private static Vec3 getClosestVisiblePoint(BlockGetter level, Iterable obs
AABB obscurerFace = getFace(obscurer, obscurerSide);
Path2D.Double path = getShadow(sourcePos, obscurerFace, obscurerSide, f, dir,
minX + (maxX - minX) * .5, minY + (maxY - minY) * .5, xAxis, yAxis);
- if (path != null)
+ if (path != null) {
area.subtract(new Area(path));
+ }
}
}
@@ -198,7 +199,9 @@ private static Vec3 getClosestVisiblePoint(BlockGetter level, Iterable obs
}
}
- if (Double.isNaN(closestX)) return null;
+ if (Double.isNaN(closestX)) {
+ return null;
+ }
return createFromComponents(closestX, xAxis, closestY, yAxis, f, dir.getAxis());
}
@@ -232,11 +235,9 @@ private static Path2D.Double getShadow(Vec3 sourcePos, AABB obscurerFace, Direct
lastInFront = behindSource[1] ? 0 : 1;
} else {
//noinspection StatementWithEmptyBody
- for (firstInFront = 0; behindSource[firstInFront]; firstInFront++)
- ;
+ for (firstInFront = 0; behindSource[firstInFront]; firstInFront++);
//noinspection StatementWithEmptyBody
- for (lastInFront = 3; behindSource[lastInFront]; lastInFront--)
- ;
+ for (lastInFront = 3; behindSource[lastInFront]; lastInFront--);
}
double firstShadowX = 0, firstShadowY = 0, lastShadowX = 0, lastShadowY = 0;
@@ -298,7 +299,9 @@ private static Path2D.Double getShadow(Vec3 sourcePos, AABB obscurerFace, Direct
double dy = getComponent(a, b, c, yAxis);
// normalize (dx, dy)
double n = Math.sqrt(dx * dx + dy * dy);
- if (n < EPSILON) return null; // only possible if the player is inside the obstacle
+ if (n < EPSILON) {
+ return null; // only possible if the player is inside the obstacle
+ }
lastDx = dx / n;
lastDy = dy / n;
}
@@ -317,7 +320,9 @@ private static Path2D.Double getShadow(Vec3 sourcePos, AABB obscurerFace, Direct
double dx = -getComponent(a, b, c, xAxis);
double dy = getComponent(a, b, c, yAxis);
double n = Math.sqrt(dx * dx + dy * dy);
- if (n < EPSILON) return null;
+ if (n < EPSILON) {
+ return null;
+ }
firstDx = dx / n;
firstDy = dy / n;
}
@@ -381,7 +386,9 @@ private static Path2D.Double getShadow(Vec3 sourcePos, AABB obscurerFace, Direct
double firstAngle = Math.atan2(firstInfiniteY - targetCenterY, firstInfiniteX - targetCenterX);
double targetAngle = Math.atan2(lastInfiniteY - targetCenterY, lastInfiniteX - targetCenterX);
double angleDifference = (clockwise ? firstAngle - targetAngle : targetAngle - firstAngle) % Math.PI * 2;
- if (angleDifference < 0) angleDifference += Math.PI * 2;
+ if (angleDifference < 0) {
+ angleDifference += Math.PI * 2;
+ }
for (double dTheta = 0; dTheta < angleDifference; dTheta += Math.PI / 3) {
double theta = clockwise ? firstAngle - dTheta : firstAngle + dTheta;
path.moveTo(10 * Math.cos(theta) + targetCenterX, 10 * Math.sin(theta) + targetCenterY);