diff --git a/src/main/java/nl/requios/effortlessbuilding/RadialMirror.java b/src/main/java/nl/requios/effortlessbuilding/RadialMirror.java index d64dc68..d85c70f 100644 --- a/src/main/java/nl/requios/effortlessbuilding/RadialMirror.java +++ b/src/main/java/nl/requios/effortlessbuilding/RadialMirror.java @@ -5,7 +5,10 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; +import net.minecraft.util.Mirror; +import net.minecraft.util.Rotation; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraftforge.items.IItemHandler; import nl.requios.effortlessbuilding.item.ItemRandomizerBag; @@ -48,19 +51,25 @@ public class RadialMirror { RadialMirrorSettings r = BuildSettingsManager.getBuildSettings(player).getRadialMirrorSettings(); if (!isEnabled(r, startPos)) return coordinates; - //get angle - float angle = 2f * ((float) Math.PI) / r.slices; + //get angle between slices + double sliceAngle = 2 * Math.PI / r.slices; Vec3d startVec = new Vec3d(startPos.getX() + 0.5f, startPos.getY() + 0.5f, startPos.getZ() + 0.5f); Vec3d relStartVec = startVec.subtract(r.position); + double startAngleToCenter = MathHelper.atan2(relStartVec.x, relStartVec.z); + if (startAngleToCenter < 0) startAngleToCenter += Math.PI; + double startAngleInSlice = startAngleToCenter % sliceAngle; + for (int i = 1; i < r.slices; i++) { - float curAngle = angle * i; - if (r.alternate) { - //TODO alternate - // get angle in slice + double curAngle = sliceAngle * i; + + //alternate mirroring of slices + if (r.alternate && i%2 == 1) { + curAngle = curAngle - startAngleInSlice + (sliceAngle - startAngleInSlice); } - Vec3d relNewVec = relStartVec.rotateYaw(curAngle); + + Vec3d relNewVec = relStartVec.rotateYaw((float) curAngle); Vec3d newVec = r.position.add(relNewVec); coordinates.add(new BlockPos(newVec)); } @@ -76,31 +85,75 @@ public class RadialMirror { if (!isEnabled(r, startPos)) return blockStates; - //get angle - float angle = 2f * ((float) Math.PI) / r.slices; + //get angle between slices + double sliceAngle = 2 * Math.PI / r.slices; Vec3d startVec = new Vec3d(startPos.getX() + 0.5f, startPos.getY() + 0.5f, startPos.getZ() + 0.5f); Vec3d relStartVec = startVec.subtract(r.position); + double startAngleToCenter = MathHelper.atan2(relStartVec.x, relStartVec.z); + if (startAngleToCenter < 0) startAngleToCenter += Math.PI; + double startAngleInSlice = startAngleToCenter % sliceAngle; + + //Rotate the original blockstate + if (startAngleToCenter < -0.75 * Math.PI || startAngleToCenter > 0.75 * Math.PI) { + blockState = blockState.withRotation(Rotation.CLOCKWISE_180); + } else if (startAngleToCenter < -0.25 * Math.PI) { + blockState = blockState.withRotation(Rotation.CLOCKWISE_90); + } else if (startAngleToCenter > 0.25 * Math.PI) { + blockState = blockState.withRotation(Rotation.COUNTERCLOCKWISE_90); + } + //Randomizer bag synergy IItemHandler bagInventory = null; if (!itemStack.isEmpty() && itemStack.getItem() instanceof ItemRandomizerBag) { bagInventory = ItemRandomizerBag.getBagInventory(itemStack); } + IBlockState newBlockState; for (int i = 1; i < r.slices; i++) { - Vec3d relNewVec = relStartVec.rotateYaw(angle * i); - Vec3d newVec = startVec.add(relNewVec); + newBlockState = blockState; + double curAngle = sliceAngle * i; + + //alternate mirroring of slices + if (r.alternate && i%2 == 1) { + curAngle = curAngle - startAngleInSlice + (sliceAngle - startAngleInSlice); + } + + Vec3d relNewVec = relStartVec.rotateYaw((float) curAngle); + Vec3d newVec = r.position.add(relNewVec); //Randomizer bag synergy if (bagInventory != null) { itemStack = ItemRandomizerBag.pickRandomStack(bagInventory); - blockState = BuildModifiers.getBlockStateFromItem(itemStack, player, startPos, EnumFacing.UP, new Vec3d(0, 0, 0), EnumHand.MAIN_HAND); + newBlockState = BuildModifiers.getBlockStateFromItem(itemStack, player, startPos, EnumFacing.UP, new Vec3d(0, 0, 0), EnumHand.MAIN_HAND); } - //TODO rotate + //rotate + double angleToCenter = MathHelper.atan2(relNewVec.x, relNewVec.z); //between -PI and PI - blockStates.add(blockState); + if (angleToCenter < -0.75 * Math.PI || angleToCenter > 0.75 * Math.PI) { + newBlockState = newBlockState.withRotation(Rotation.CLOCKWISE_180); + if (r.alternate && i%2 == 1) { + newBlockState = newBlockState.withMirror(Mirror.FRONT_BACK); + } + } else if (angleToCenter < -0.25 * Math.PI) { + newBlockState = newBlockState.withRotation(Rotation.CLOCKWISE_90); + if (r.alternate && i%2 == 1) { + newBlockState = newBlockState.withMirror(Mirror.LEFT_RIGHT); + } + } else if (angleToCenter > 0.25 * Math.PI) { + newBlockState = newBlockState.withRotation(Rotation.COUNTERCLOCKWISE_90); + if (r.alternate && i%2 == 1) { + newBlockState = newBlockState.withMirror(Mirror.LEFT_RIGHT); + } + } else { + if (r.alternate && i%2 == 1) { + newBlockState = newBlockState.withMirror(Mirror.FRONT_BACK); + } + } + + blockStates.add(newBlockState); itemStacks.add(itemStack); } @@ -110,10 +163,8 @@ public class RadialMirror { public static boolean isEnabled(RadialMirrorSettings r, BlockPos startPos) { if (r == null || !r.enabled) return false; - //within mirror distance - if (startPos.getX() + 0.5 < r.position.x - r.radius || startPos.getX() + 0.5 > r.position.x + r.radius || - startPos.getY() + 0.5 < r.position.y - r.radius || startPos.getY() + 0.5 > r.position.y + r.radius || - startPos.getZ() + 0.5 < r.position.z - r.radius || startPos.getZ() + 0.5 > r.position.z + r.radius) + if (new Vec3d(startPos.getX() + 0.5, startPos.getY() + 0.5, startPos.getZ() + 0.5).subtract(r.position).lengthSquared() > + r.radius * r.radius) return false; return true; diff --git a/src/main/java/nl/requios/effortlessbuilding/capability/BuildModifierCapabilityManager.java b/src/main/java/nl/requios/effortlessbuilding/capability/BuildModifierCapabilityManager.java index 9666079..4be938f 100644 --- a/src/main/java/nl/requios/effortlessbuilding/capability/BuildModifierCapabilityManager.java +++ b/src/main/java/nl/requios/effortlessbuilding/capability/BuildModifierCapabilityManager.java @@ -54,6 +54,7 @@ public class BuildModifierCapabilityManager { //MIRROR Mirror.MirrorSettings m = buildSettings.getMirrorSettings(); + if (m == null) m = new Mirror.MirrorSettings(); compound.setBoolean("mirrorEnabled", m.enabled); compound.setDouble("mirrorPosX", m.position.x); compound.setDouble("mirrorPosY", m.position.y); @@ -67,6 +68,7 @@ public class BuildModifierCapabilityManager { //ARRAY Array.ArraySettings a = buildSettings.getArraySettings(); + if (a == null) a = new Array.ArraySettings(); compound.setBoolean("arrayEnabled", a.enabled); compound.setInteger("arrayOffsetX", a.offset.getX()); compound.setInteger("arrayOffsetY", a.offset.getY()); @@ -79,6 +81,7 @@ public class BuildModifierCapabilityManager { //RADIAL MIRROR RadialMirror.RadialMirrorSettings r = buildSettings.getRadialMirrorSettings(); + if (r == null) r = new RadialMirror.RadialMirrorSettings(); compound.setBoolean("radialMirrorEnabled", r.enabled); compound.setDouble("radialMirrorPosX", r.position.x); compound.setDouble("radialMirrorPosY", r.position.y); diff --git a/src/main/java/nl/requios/effortlessbuilding/network/BuildSettingsMessage.java b/src/main/java/nl/requios/effortlessbuilding/network/BuildSettingsMessage.java index 76906a7..fd18167 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/BuildSettingsMessage.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/BuildSettingsMessage.java @@ -26,24 +26,30 @@ public class BuildSettingsMessage implements IMessage { public void toBytes(ByteBuf buf) { //MIRROR Mirror.MirrorSettings m = buildSettings.getMirrorSettings(); - buf.writeBoolean(m.enabled); - buf.writeDouble(m.position.x); - buf.writeDouble(m.position.y); - buf.writeDouble(m.position.z); - buf.writeBoolean(m.mirrorX); - buf.writeBoolean(m.mirrorY); - buf.writeBoolean(m.mirrorZ); - buf.writeInt(m.radius); - buf.writeBoolean(m.drawLines); - buf.writeBoolean(m.drawPlanes); + buf.writeBoolean(m != null); + if (m != null) { + buf.writeBoolean(m.enabled); + buf.writeDouble(m.position.x); + buf.writeDouble(m.position.y); + buf.writeDouble(m.position.z); + buf.writeBoolean(m.mirrorX); + buf.writeBoolean(m.mirrorY); + buf.writeBoolean(m.mirrorZ); + buf.writeInt(m.radius); + buf.writeBoolean(m.drawLines); + buf.writeBoolean(m.drawPlanes); + } //ARRAY Array.ArraySettings a = buildSettings.getArraySettings(); - buf.writeBoolean(a.enabled); - buf.writeInt(a.offset.getX()); - buf.writeInt(a.offset.getY()); - buf.writeInt(a.offset.getZ()); - buf.writeInt(a.count); + buf.writeBoolean(a != null); + if (a != null) { + buf.writeBoolean(a.enabled); + buf.writeInt(a.offset.getX()); + buf.writeInt(a.offset.getY()); + buf.writeInt(a.offset.getZ()); + buf.writeInt(a.count); + } buf.writeBoolean(buildSettings.doQuickReplace()); @@ -51,50 +57,63 @@ public class BuildSettingsMessage implements IMessage { //RADIAL MIRROR RadialMirror.RadialMirrorSettings r = buildSettings.getRadialMirrorSettings(); - buf.writeBoolean(r.enabled); - buf.writeDouble(r.position.x); - buf.writeDouble(r.position.y); - buf.writeDouble(r.position.z); - buf.writeInt(r.slices); - buf.writeBoolean(r.alternate); - buf.writeInt(r.radius); - buf.writeBoolean(r.drawLines); - buf.writeBoolean(r.drawPlanes); + buf.writeBoolean(r != null); + if (r != null) { + buf.writeBoolean(r.enabled); + buf.writeDouble(r.position.x); + buf.writeDouble(r.position.y); + buf.writeDouble(r.position.z); + buf.writeInt(r.slices); + buf.writeBoolean(r.alternate); + buf.writeInt(r.radius); + buf.writeBoolean(r.drawLines); + buf.writeBoolean(r.drawPlanes); + } } @Override public void fromBytes(ByteBuf buf) { //MIRROR - boolean mirrorEnabled = buf.readBoolean(); - Vec3d mirrorPosition = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble()); - boolean mirrorX = buf.readBoolean(); - boolean mirrorY = buf.readBoolean(); - boolean mirrorZ = buf.readBoolean(); - int mirrorRadius = buf.readInt(); - boolean mirrorDrawLines = buf.readBoolean(); - boolean mirrorDrawPlanes = buf.readBoolean(); - Mirror.MirrorSettings m = new Mirror.MirrorSettings(mirrorEnabled, mirrorPosition, mirrorX, mirrorY, mirrorZ, mirrorRadius, mirrorDrawLines, mirrorDrawPlanes); + Mirror.MirrorSettings m = new Mirror.MirrorSettings(); + if (buf.readBoolean()) { + boolean mirrorEnabled = buf.readBoolean(); + Vec3d mirrorPosition = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble()); + boolean mirrorX = buf.readBoolean(); + boolean mirrorY = buf.readBoolean(); + boolean mirrorZ = buf.readBoolean(); + int mirrorRadius = buf.readInt(); + boolean mirrorDrawLines = buf.readBoolean(); + boolean mirrorDrawPlanes = buf.readBoolean(); + m = new Mirror.MirrorSettings(mirrorEnabled, mirrorPosition, mirrorX, mirrorY, mirrorZ, mirrorRadius, + mirrorDrawLines, mirrorDrawPlanes); + } //ARRAY - boolean arrayEnabled = buf.readBoolean(); - BlockPos arrayOffset = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt()); - int arrayCount = buf.readInt(); - Array.ArraySettings a = new Array.ArraySettings(arrayEnabled, arrayOffset, arrayCount); + Array.ArraySettings a = new Array.ArraySettings(); + if (buf.readBoolean()) { + boolean arrayEnabled = buf.readBoolean(); + BlockPos arrayOffset = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt()); + int arrayCount = buf.readInt(); + a = new Array.ArraySettings(arrayEnabled, arrayOffset, arrayCount); + } boolean quickReplace = buf.readBoolean(); int reachUpgrade = buf.readInt(); //RADIAL MIRROR - boolean radialMirrorEnabled = buf.readBoolean(); - Vec3d radialMirrorPosition = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble()); - int radialMirrorSlices = buf.readInt(); - boolean radialMirrorAlternate = buf.readBoolean(); - int radialMirrorRadius = buf.readInt(); - boolean radialMirrorDrawLines = buf.readBoolean(); - boolean radialMirrorDrawPlanes = buf.readBoolean(); - RadialMirror.RadialMirrorSettings r = new RadialMirror.RadialMirrorSettings(radialMirrorEnabled, radialMirrorPosition, radialMirrorSlices, - radialMirrorAlternate, radialMirrorRadius, radialMirrorDrawLines, radialMirrorDrawPlanes); + RadialMirror.RadialMirrorSettings r = new RadialMirror.RadialMirrorSettings(); + if (buf.readBoolean()) { + boolean radialMirrorEnabled = buf.readBoolean(); + Vec3d radialMirrorPosition = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble()); + int radialMirrorSlices = buf.readInt(); + boolean radialMirrorAlternate = buf.readBoolean(); + int radialMirrorRadius = buf.readInt(); + boolean radialMirrorDrawLines = buf.readBoolean(); + boolean radialMirrorDrawPlanes = buf.readBoolean(); + r = new RadialMirror.RadialMirrorSettings(radialMirrorEnabled, radialMirrorPosition, radialMirrorSlices, + radialMirrorAlternate, radialMirrorRadius, radialMirrorDrawLines, radialMirrorDrawPlanes); + } buildSettings = new BuildSettings(m, a, r, quickReplace, reachUpgrade); } @@ -107,19 +126,18 @@ public class BuildSettingsMessage implements IMessage { public IMessage onMessage(BuildSettingsMessage message, MessageContext ctx) { //EffortlessBuilding.log("message received on " + ctx.side + " side"); - // This is the player the packet was sent to the server from - EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); // The value that was sent BuildSettings buildSettings = message.buildSettings; - // Sanitize - BuildSettingsManager.sanitize(buildSettings, player); - // Execute the action on the main server thread by adding it as a scheduled task IThreadListener threadListener = EffortlessBuilding.proxy.getThreadListenerFromContext(ctx); threadListener.addScheduledTask(() -> { - EntityPlayer p = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); - BuildSettingsManager.setBuildSettings(p, buildSettings); + EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); + + // Sanitize + BuildSettingsManager.sanitize(buildSettings, player); + + BuildSettingsManager.setBuildSettings(player, buildSettings); }); // No response packet return null;