Target practice

- Improved position of rendered blocks launched by Schematicannon
- Fixed Schematicannon play button having to be pressed twice to start printing
- Schematicannon no longer moves while searching for the next location to shoot at
- Schematicannon now skips through empty sections more quickly
- Fixed Creative players losing items used on block application recipes
- Fixed blocks used in item application recipes briefly being placed on the client
- Blaze burners now create less light updates
- Goggle overlay fade-in no longer repeats when looking at adjacent blocks with information
- Reduced particle amount produced by active steam engine setups
This commit is contained in:
simibubi 2022-12-08 14:07:03 +01:00
parent ef6c6beb27
commit 579bddc5af
8 changed files with 75 additions and 63 deletions

View File

@ -43,8 +43,6 @@ public class ManualApplicationRecipe extends ItemApplicationRecipe {
BlockPos pos = event.getPos();
BlockState blockState = level.getBlockState(pos);
if (level.isClientSide())
return;
if (heldItem.isEmpty())
return;
if (blockState.isAir())
@ -65,6 +63,12 @@ public class ManualApplicationRecipe extends ItemApplicationRecipe {
if (foundRecipe.isEmpty())
return;
event.setCancellationResult(InteractionResult.SUCCESS);
event.setCanceled(true);
if (level.isClientSide())
return;
level.playSound(null, pos, SoundEvents.COPPER_BREAK, SoundSource.PLAYERS, 1, 1.45f);
ManualApplicationRecipe recipe = (ManualApplicationRecipe) foundRecipe.get();
@ -75,9 +79,11 @@ public class ManualApplicationRecipe extends ItemApplicationRecipe {
recipe.rollResults()
.forEach(stack -> Block.popResource(level, pos, stack));
boolean creative = event.getPlayer() != null && event.getPlayer()
.isCreative();
boolean unbreakable = heldItem.hasTag() && heldItem.getTag()
.getBoolean("Unbreakable");
boolean keepHeld = recipe.shouldKeepHeldItem();
boolean keepHeld = recipe.shouldKeepHeldItem() || creative;
if (!unbreakable && !keepHeld) {
if (heldItem.isDamageableItem())
@ -87,9 +93,6 @@ public class ManualApplicationRecipe extends ItemApplicationRecipe {
}
awardAdvancements(event.getPlayer(), transformedBlock);
event.setCancellationResult(InteractionResult.SUCCESS);
event.setCanceled(true);
}
private static void awardAdvancements(Player player, BlockState placed) {

View File

@ -219,18 +219,16 @@ public class SteamEngineTileEntity extends SmartTileEntity implements IHaveGoggl
Direction facing = SteamEngineBlock.getFacing(getBlockState());
for (int i = 0; i < 2; i++) {
Vec3 offset = VecHelper.rotate(new Vec3(0, 0, 1).add(VecHelper.offsetRandomly(Vec3.ZERO, level.random, 1)
.multiply(1, 1, 0)
.normalize()
.scale(.5f)), AngleHelper.verticalAngle(facing), Axis.X);
offset = VecHelper.rotate(offset, AngleHelper.horizontalAngle(facing), Axis.Y);
Vec3 v = offset.scale(.5f)
.add(Vec3.atCenterOf(worldPosition));
Vec3 m = offset.subtract(Vec3.atLowerCornerOf(facing.getNormal())
.scale(.75f));
level.addParticle(new SteamJetParticleData(1), v.x, v.y, v.z, m.x, m.y, m.z);
}
Vec3 offset = VecHelper.rotate(new Vec3(0, 0, 1).add(VecHelper.offsetRandomly(Vec3.ZERO, level.random, 1)
.multiply(1, 1, 0)
.normalize()
.scale(.5f)), AngleHelper.verticalAngle(facing), Axis.X);
offset = VecHelper.rotate(offset, AngleHelper.horizontalAngle(facing), Axis.Y);
Vec3 v = offset.scale(.5f)
.add(Vec3.atCenterOf(worldPosition));
Vec3 m = offset.subtract(Vec3.atLowerCornerOf(facing.getNormal())
.scale(.75f));
level.addParticle(new SteamJetParticleData(1), v.x, v.y, v.z, m.x, m.y, m.z);
prevAngle = angle;
}

View File

@ -77,10 +77,7 @@ public class GoggleOverlayRenderer {
BlockEntity te = world.getBlockEntity(pos);
int prevHoverTicks = hoverTicks;
if (lastHovered == null || lastHovered.equals(pos))
hoverTicks++;
else
hoverTicks = 0;
hoverTicks++;
lastHovered = pos;
boolean wearingGoggles = GogglesItem.isWearingGoggles(mc.player);
@ -122,8 +119,10 @@ public class GoggleOverlayRenderer {
hoverTicks = prevHoverTicks + 1;
// break early if goggle or hover returned false when present
if ((hasGoggleInformation && !goggleAddedInformation) && (hasHoveringInformation && !hoverAddedInformation))
if ((hasGoggleInformation && !goggleAddedInformation) && (hasHoveringInformation && !hoverAddedInformation)) {
hoverTicks = 0;
return;
}
// check for piston poles if goggles are worn
BlockState state = world.getBlockState(pos);
@ -140,8 +139,10 @@ public class GoggleOverlayRenderer {
.getBlock() instanceof MechanicalPistonBlock;
}
if (!pistonFound)
if (!pistonFound) {
hoverTicks = 0;
return;
}
if (!tooltip.isEmpty())
tooltip.add(Components.immutableEmpty());
@ -150,8 +151,10 @@ public class GoggleOverlayRenderer {
.append(Components.literal(" " + poles)));
}
if (tooltip.isEmpty())
if (tooltip.isEmpty()) {
hoverTicks = 0;
return;
}
poseStack.pushPose();
@ -175,7 +178,7 @@ public class GoggleOverlayRenderer {
posX = Math.min(posX, width - tooltipTextWidth - 20);
posY = Math.min(posY, height - tooltipHeight - 20);
float fade = Mth.clamp((hoverTicks + partialTicks) / 12f, 0, 1);
float fade = Mth.clamp((hoverTicks + partialTicks) / 24f, 0, 1);
Boolean useCustom = cfg.overlayCustomColor.get();
Color colorBackground = useCustom ? new Color(cfg.overlayBackgroundColor.get())
: Theme.c(Theme.Key.VANILLA_TOOLTIP_BACKGROUND)
@ -188,7 +191,7 @@ public class GoggleOverlayRenderer {
.copy();
if (fade < 1) {
poseStack.translate((1 - fade) * Math.signum(cfg.overlayOffsetX.get() + .5f) * 4, 0, 0);
poseStack.translate(Math.pow(1 - fade, 3) * Math.signum(cfg.overlayOffsetX.get() + .5f) * 8, 0, 0);
colorBackground.scaleAlpha(fade);
colorBorderTop.scaleAlpha(fade);
colorBorderBot.scaleAlpha(fade);

View File

@ -20,7 +20,6 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.NonNullList;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
@ -252,8 +251,12 @@ public class BlazeBurnerBlock extends HorizontalDirectionalBlock implements ITE<
}
public static int getLight(BlockState state) {
return Mth.clamp(state.getValue(HEAT_LEVEL)
.ordinal() * 4 - 1, 0, 15);
HeatLevel level = state.getValue(HEAT_LEVEL);
return switch (level) {
case NONE -> 0;
case SMOULDERING -> 8;
default -> 15;
};
}
public static LootTable.Builder buildLootTable() {

View File

@ -192,7 +192,7 @@ public class BlazeBurnerTileEntity extends SmartTileEntity {
newBurnTime = 1000;
newFuel = FuelType.SPECIAL;
} else {
newBurnTime = (int)Math.min(ForgeHooks.getBurnTime(itemStack, null), (float)(MAX_HEAT_CAPACITY) * 0.98);
newBurnTime = (int) Math.min(ForgeHooks.getBurnTime(itemStack, null), MAX_HEAT_CAPACITY * 0.95f);
if (newBurnTime > 0)
newFuel = FuelType.NORMAL;
else if (AllItemTags.BLAZE_BURNER_FUEL_REGULAR.matches(itemStack)) {
@ -296,15 +296,16 @@ public class BlazeBurnerTileEntity extends SmartTileEntity {
Vec3 c = VecHelper.getCenterOf(worldPosition);
Vec3 v = c.add(VecHelper.offsetRandomly(Vec3.ZERO, r, .125f)
.multiply(1, 0, 1));
if (r.nextInt(3) == 0)
level.addParticle(ParticleTypes.LARGE_SMOKE, v.x, v.y, v.z, 0, 0, 0);
if (r.nextInt(2) != 0)
if (r.nextInt(4) != 0)
return;
boolean empty = level.getBlockState(worldPosition.above())
.getCollisionShape(level, worldPosition.above())
.isEmpty();
if (empty || r.nextInt(8) == 0)
level.addParticle(ParticleTypes.LARGE_SMOKE, v.x, v.y, v.z, 0, 0, 0);
double yMotion = empty ? .0625f : r.nextDouble() * .0125f;
Vec3 v2 = c.add(VecHelper.offsetRandomly(Vec3.ZERO, r, .5f)

View File

@ -133,29 +133,29 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
continue;
// Calculate position of flying block
Vec3 start = Vec3.atLowerCornerOf(tileEntityIn.getBlockPos()
.offset(.5f, 1, .5f));
Vec3 target = Vec3.atLowerCornerOf(launched.target)
.add(-.5, 0, 1);
Vec3 start = Vec3.atCenterOf(tileEntityIn.getBlockPos()
.above());
Vec3 target = Vec3.atCenterOf(launched.target);
Vec3 distance = target.subtract(start);
double targetY = target.y - start.y;
double throwHeight = Math.sqrt(distance.lengthSqr()) * .6f + targetY;
double yDifference = target.y - start.y;
double throwHeight = Math.sqrt(distance.lengthSqr()) * .6f + yDifference;
Vec3 cannonOffset = distance.add(0, throwHeight, 0)
.normalize()
.scale(2);
start = start.add(cannonOffset);
yDifference = target.y - start.y;
float progress =
((float) launched.totalTicks - (launched.ticksRemaining + 1 - partialTicks)) / launched.totalTicks;
Vec3 blockLocationXZ = new Vec3(.5, .5, .5).add(target.subtract(start)
Vec3 blockLocationXZ = target.subtract(start)
.scale(progress)
.multiply(1, 0, 1));
.multiply(1, 0, 1);
// Height is determined through a bezier curve
float t = progress;
double yOffset = 2 * (1 - t) * t * throwHeight + t * t * targetY;
Vec3 blockLocation = blockLocationXZ.add(0, yOffset + 1, 0)
double yOffset = 2 * (1 - t) * t * throwHeight + t * t * yDifference;
Vec3 blockLocation = blockLocationXZ.add(0.5, yOffset + 1.5, 0.5)
.add(cannonOffset);
// Offset to position
@ -180,8 +180,7 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
ms.scale(scale, scale, scale);
Minecraft.getInstance()
.getBlockRenderer()
.renderSingleBlock(state, ms, buffer, light, overlay,
VirtualEmptyModelData.INSTANCE);
.renderSingleBlock(state, ms, buffer, light, overlay, VirtualEmptyModelData.INSTANCE);
} else if (launched instanceof ForEntity) {
// Render the item
float scale = 1.2f;
@ -195,6 +194,7 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
// Render particles for launch
if (launched.ticksRemaining == launched.totalTicks && tileEntityIn.firstRenderTick) {
start = start.subtract(.5, .5, .5);
tileEntityIn.firstRenderTick = false;
for (int i = 0; i < 10; i++) {
Random r = tileEntityIn.getLevel()

View File

@ -279,7 +279,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements MenuPro
refillFuelIfPossible();
// Update Printer
skipsLeft = config().schematicannonSkips.get();
skipsLeft = 1000;
blockSkipped = true;
while (blockSkipped && skipsLeft-- > 0)
@ -303,6 +303,13 @@ public class SchematicannonTileEntity extends SmartTileEntity implements MenuPro
protected void tickPrinter() {
ItemStack blueprint = inventory.getStackInSlot(0);
blockSkipped = false;
if (blueprint.isEmpty() && !statusMsg.equals("idle")) {
state = State.STOPPED;
statusMsg = "idle";
sendUpdate = true;
return;
}
// Skip if not Active
if (state == State.STOPPED) {
@ -311,13 +318,6 @@ public class SchematicannonTileEntity extends SmartTileEntity implements MenuPro
return;
}
if (blueprint.isEmpty()) {
state = State.STOPPED;
statusMsg = "idle";
sendUpdate = true;
return;
}
if (state == State.PAUSED && !positionNotLoaded && missingItem == null && fuelLevel > getFuelUsageRate())
return;
@ -374,6 +374,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements MenuPro
// Get item requirement
ItemRequirement requirement = printer.getCurrentRequirement();
if (requirement.isInvalid() || !printer.shouldPlaceCurrent(level, this::shouldPlace)) {
sendUpdate = !statusMsg.equals("searching");
statusMsg = "searching";
blockSkipped = true;
return;
@ -641,6 +642,11 @@ public class SchematicannonTileEntity extends SmartTileEntity implements MenuPro
inventory.getStackInSlot(4)
.shrink(1);
fuelLevel += getFuelAddedByGunPowder();
if (statusMsg.equals("noGunpowder")) {
if (blocksPlaced > 0)
state = State.RUNNING;
statusMsg = "ready";
}
sendUpdate = true;
}
@ -656,6 +662,12 @@ public class SchematicannonTileEntity extends SmartTileEntity implements MenuPro
ItemStack paper = inventory.extractItem(BookInput, 1, true);
boolean outputFull = inventory.getStackInSlot(BookOutput)
.getCount() == inventory.getSlotLimit(BookOutput);
if (!printer.isLoaded()) {
if (!blueprint.isEmpty())
initializePrinter(blueprint);
return;
}
if (paper.isEmpty() || outputFull) {
if (bookPrintingProgress != 0)
@ -665,12 +677,6 @@ public class SchematicannonTileEntity extends SmartTileEntity implements MenuPro
return;
}
if (!printer.isLoaded()) {
if (!blueprint.isEmpty())
initializePrinter(blueprint);
return;
}
if (bookPrintingProgress >= 1) {
bookPrintingProgress = 0;

View File

@ -11,7 +11,6 @@ public class CSchematics extends ConfigBase {
public final ConfigGroup schematicannon = group(0, "schematicannon", "Schematicannon");
public final ConfigInt schematicannonDelay = i(10, 1, "schematicannonDelay", Comments.delay);
public final ConfigInt schematicannonSkips = i(10, 1, "schematicannonSkips", Comments.skips);
public final ConfigFloat schematicannonGunpowderWorth =
f(20, 0, 100, "schematicannonGunpowderWorth", Comments.gunpowderWorth);
public final ConfigFloat schematicannonFuelUsage = f(0.05f, 0, 100, "schematicannonFuelUsage", Comments.fuelUsage);
@ -31,7 +30,6 @@ public class CSchematics extends ConfigBase {
static String idleTimeout =
"Amount of game ticks without new packets arriving until an active schematic upload process is discarded.";
static String delay = "Amount of game ticks between shots of the cannon. Higher => Slower";
static String skips = "Amount of block positions per tick scanned by a running cannon. Higher => Faster";
static String gunpowderWorth = "% of Schematicannon's Fuel filled by 1 Gunpowder.";
static String fuelUsage = "% of Schematicannon's Fuel used for each fired block.";
static String creativePrintIncludesAir =