use of net.minecraft.world.level.block.state.BlockState in project SpongeCommon by SpongePowered.
the class AbstractArrowMixin method onProjectileHit.
/**
* Collide impact event post for plugins to cancel impact.
*/
@Inject(method = "onHitBlock", at = @At("HEAD"), cancellable = true)
private void onProjectileHit(final BlockHitResult hitResult, final CallbackInfo ci) {
if (!((LevelBridge) this.level).bridge$isFake() && hitResult.getType() != HitResult.Type.MISS) {
if (SpongeCommonEventFactory.handleCollideImpactEvent((AbstractArrow) (Object) this, this.impl$getProjectileSource(), hitResult)) {
this.shadow$playSound(SoundEvents.ARROW_HIT, 1.0F, 1.2F / (this.random.nextFloat() * 0.2F + 0.9F));
// Make it almost look like it collided with something
final BlockHitResult blockraytraceresult = (BlockHitResult) hitResult;
final BlockState blockstate = this.level.getBlockState(blockraytraceresult.getBlockPos());
this.lastState = blockstate;
final Vec3 vec3d = blockraytraceresult.getLocation().subtract(this.shadow$getX(), this.shadow$getY(), this.shadow$getZ());
this.shadow$setDeltaMovement(vec3d);
final Vec3 vec3d1 = vec3d.normalize().scale(0.05F);
this.shadow$setPos(this.shadow$getX() - vec3d1.x, this.shadow$getY() - vec3d1.y, this.shadow$getZ() - vec3d1.z);
this.inGround = true;
this.shakeTime = 7;
this.shadow$setCritArrow(false);
this.shadow$setPierceLevel((byte) 0);
this.shadow$setShotFromCrossbow(false);
this.resetPiercedEntities();
ci.cancel();
}
}
}
use of net.minecraft.world.level.block.state.BlockState in project SpongeCommon by SpongePowered.
the class ExplosionMixin method explode.
/**
* @author gabizou
* @author zidane
* @reason Fire ExplosionEvent.Detonate
*/
@Overwrite
public void explode() {
// Sponge Start - Do not run calculation logic on client thread
if (this.level.isClientSide) {
return;
}
// Sponge Start - If the explosion should not break blocks, don't bother calculating it on server thread
if (this.impl$shouldBreakBlocks) {
final Set<BlockPos> set = Sets.newHashSet();
final int i = 16;
for (int j = 0; j < 16; ++j) {
for (int k = 0; k < 16; ++k) {
for (int l = 0; l < 16; ++l) {
if (j == 0 || j == 15 || k == 0 || k == 15 || l == 0 || l == 15) {
double d0 = (double) ((float) j / 15.0F * 2.0F - 1.0F);
double d1 = (double) ((float) k / 15.0F * 2.0F - 1.0F);
double d2 = (double) ((float) l / 15.0F * 2.0F - 1.0F);
final double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
d0 = d0 / d3;
d1 = d1 / d3;
d2 = d2 / d3;
float f = this.radius * (0.7F + this.level.random.nextFloat() * 0.6F);
double d4 = this.x;
double d6 = this.y;
double d8 = this.z;
for (final float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) {
final BlockPos blockpos = new BlockPos(d4, d6, d8);
final BlockState blockstate = this.level.getBlockState(blockpos);
final FluidState fluidstate = this.level.getFluidState(blockpos);
Optional<Float> optional = this.damageCalculator.getBlockExplosionResistance((net.minecraft.world.level.Explosion) (Object) this, this.level, blockpos, blockstate, fluidstate);
if (optional.isPresent()) {
f -= (optional.get() + 0.3F) * 0.3F;
}
if (f > 0.0F && this.damageCalculator.shouldBlockExplode((net.minecraft.world.level.Explosion) (Object) this, this.level, blockpos, blockstate, f)) {
set.add(blockpos);
}
d4 += d0 * (double) 0.3F;
d6 += d1 * (double) 0.3F;
d8 += d2 * (double) 0.3F;
}
}
}
}
}
this.toBlow.addAll(set);
}
// Sponge End
final float f3 = this.radius * 2.0F;
final int k1 = Mth.floor(this.x - (double) f3 - 1.0D);
final int l1 = Mth.floor(this.x + (double) f3 + 1.0D);
final int i2 = Mth.floor(this.y - (double) f3 - 1.0D);
final int i1 = Mth.floor(this.y + (double) f3 + 1.0D);
final int j2 = Mth.floor(this.z - (double) f3 - 1.0D);
final int j1 = Mth.floor(this.z + (double) f3 + 1.0D);
// Sponge Start - Only query for entities if we're to damage them
final List<Entity> list = this.impl$shouldDamageEntities ? this.level.getEntities(this.source, new AABB((double) k1, (double) i2, (double) j2, (double) l1, (double) i1, (double) j1)) : Collections.emptyList();
if (ShouldFire.EXPLOSION_EVENT_DETONATE) {
final List<ServerLocation> blockPositions = new ArrayList<>(this.toBlow.size());
final List<org.spongepowered.api.entity.Entity> entities = new ArrayList<>(list.size());
for (final BlockPos pos : this.toBlow) {
blockPositions.add(ServerLocation.of((org.spongepowered.api.world.server.ServerWorld) this.level, pos.getX(), pos.getY(), pos.getZ()));
}
for (final Entity entity : list) {
// Make sure to check the entity is immune first.
if (!entity.ignoreExplosion()) {
entities.add((org.spongepowered.api.entity.Entity) entity);
}
}
final Cause cause = PhaseTracker.getCauseStackManager().currentCause();
final ExplosionEvent.Detonate detonate = SpongeEventFactory.createExplosionEventDetonate(cause, blockPositions, entities, (Explosion) this, (org.spongepowered.api.world.server.ServerWorld) this.level);
SpongeCommon.post(detonate);
// Clear the positions so that they can be pulled from the event
this.toBlow.clear();
if (detonate.isCancelled()) {
return;
}
if (this.impl$shouldBreakBlocks) {
for (final ServerLocation worldLocation : detonate.affectedLocations()) {
this.toBlow.add(VecHelper.toBlockPos(worldLocation));
}
}
// Clear the list of entities so they can be pulled from the event.
list.clear();
if (this.impl$shouldDamageEntities) {
for (final org.spongepowered.api.entity.Entity entity : detonate.entities()) {
try {
list.add((Entity) entity);
} catch (final Exception e) {
// Do nothing, a plugin tried to use the wrong entity somehow.
}
}
}
}
// Sponge End
final Vec3 vec3d = new Vec3(this.x, this.y, this.z);
for (int k2 = 0; k2 < list.size(); ++k2) {
final Entity entity = list.get(k2);
if (!entity.ignoreExplosion()) {
final double d12 = (double) (Mth.sqrt(entity.distanceToSqr(vec3d)) / f3);
if (d12 <= 1.0D) {
double d5 = entity.getX() - this.x;
double d7 = entity.getEyeY() - this.y;
double d9 = entity.getZ() - this.z;
final double d13 = (double) Mth.sqrt(d5 * d5 + d7 * d7 + d9 * d9);
if (d13 != 0.0D) {
d5 = d5 / d13;
d7 = d7 / d13;
d9 = d9 / d13;
final double d14 = (double) net.minecraft.world.level.Explosion.getSeenPercent(vec3d, entity);
final double d10 = (1.0D - d12) * d14;
entity.hurt(this.shadow$getDamageSource(), (float) ((int) ((d10 * d10 + d10) / 2.0D * 7.0D * (double) f3 + 1.0D)));
double d11 = d10;
if (entity instanceof LivingEntity) {
d11 = ProtectionEnchantment.getExplosionKnockbackAfterDampener((LivingEntity) entity, d10);
}
// Sponge Start - Honor our knockback value from event
entity.setDeltaMovement(entity.getDeltaMovement().add(d5 * d11 * this.impl$knockback, d7 * d11 * this.impl$knockback, d9 * d11 * this.impl$knockback));
if (entity instanceof Player) {
final Player playerentity = (Player) entity;
if (!playerentity.isSpectator() && (!playerentity.isCreative() || !playerentity.abilities.flying)) {
this.hitPlayers.put(playerentity, new Vec3(d5 * d10 * this.impl$knockback, d7 * d10 * this.impl$knockback, d9 * d10 * this.impl$knockback));
}
}
// Sponge End
}
}
}
}
}
use of net.minecraft.world.level.block.state.BlockState in project SpongeCommon by SpongePowered.
the class ServerLevelMixin_Tracker method tracker$associatePhaseContextDataWithBlockEvent.
@Redirect(method = "blockEvent", at = @At(value = "INVOKE", target = "Lit/unimi/dsi/fastutil/objects/ObjectLinkedOpenHashSet;add(Ljava/lang/Object;)Z", remap = false))
private boolean tracker$associatePhaseContextDataWithBlockEvent(final ObjectLinkedOpenHashSet<BlockEventData> list, final Object data, final BlockPos pos, final Block blockIn, final int eventID, final int eventParam) {
final PhaseContext<@NonNull ?> currentContext = PhaseTracker.getInstance().getPhaseContext();
final BlockEventData blockEventData = (BlockEventData) data;
final TrackableBlockEventDataBridge blockEvent = (TrackableBlockEventDataBridge) blockEventData;
// Short circuit phase states who do not track during block events
if (currentContext.ignoresBlockEvent()) {
return list.add(blockEventData);
}
final BlockState state = this.shadow$getBlockState(pos);
if (((TrackableBridge) blockIn).bridge$allowsBlockEventCreation()) {
blockEvent.bridge$setSourceUserUUID(currentContext.getActiveUserUUID());
if (((BlockStateBridge) state).bridge$hasTileEntity()) {
blockEvent.bridge$setTileEntity((BlockEntity) this.shadow$getBlockEntity(pos));
}
if (blockEvent.bridge$getTileEntity() == null) {
final LocatableBlock locatable = new SpongeLocatableBlockBuilder().world((org.spongepowered.api.world.server.ServerWorld) this).position(pos.getX(), pos.getY(), pos.getZ()).state((org.spongepowered.api.block.BlockState) state).build();
blockEvent.bridge$setTickingLocatable(locatable);
}
}
// allow tracking to take place for other/future phases
if (!((TrackableBridge) blockIn).bridge$allowsBlockEventCreation()) {
return list.add((BlockEventData) data);
}
// In pursuant with our block updates management, we chose to
// effectively allow the block event get added to the list, but
// we log the transaction so that we can call the change block event
// pre, and if needed, undo the add to the list.
currentContext.appendNotifierToBlockEvent(this, pos, blockEvent);
// This is very common with pistons as they add block events while blocks are being notified.
if (ShouldFire.CHANGE_BLOCK_EVENT_PRE) {
if (blockIn instanceof PistonBaseBlock) {
// We only fire pre events for pistons
if (SpongeCommonEventFactory.handlePistonEvent(this, pos, state, eventID)) {
return false;
}
} else {
if (SpongeCommonEventFactory.callChangeBlockEventPre((ServerLevelBridge) this, pos).isCancelled()) {
return false;
}
}
}
currentContext.getTransactor().logBlockEvent(state, this, pos, blockEvent);
return list.add(blockEventData);
}
use of net.minecraft.world.level.block.state.BlockState in project SpongeCommon by SpongePowered.
the class ServerLevelMixin_Tracker method shadow$neighborChanged.
@Override
public void shadow$neighborChanged(final BlockPos pos, final Block blockIn, final BlockPos fromPos) {
final BlockPos immutableTarget = pos.immutable();
final BlockPos immutableFrom = fromPos.immutable();
// Sponge Start - Check asynchronicity,
// if not on the server thread and we're a server world, we've got problems...
final PhaseTracker server = PhaseTracker.SERVER;
if (server.getSidedThread() != Thread.currentThread()) {
// lol no, report the block change properly
new PrettyPrinter(60).add("Illegal Async PhaseTracker Access").centre().hr().addWrapped(PhasePrinter.ASYNC_TRACKER_ACCESS).add().add(new Exception("Async Block Notifcation Detected")).log(SpongeCommon.logger(), Level.ERROR);
// Maybe? I don't think this is wise to try and sync back a notification on the main thread.
return;
}
// world that Sponge isn't directly managing, so we'll just ignore trying to record on those.
if (this.bridge$isFake()) {
// If we're fake, well, we could effectively call this without recording on worlds we don't
// want to care about.
super.shadow$neighborChanged(immutableTarget, blockIn, immutableFrom);
return;
}
// Otherwise, we continue with recording, maybe.
final LevelChunk targetChunk = this.shadow$getChunkAt(immutableTarget);
final BlockState targetBlockState = targetChunk.getBlockState(immutableTarget);
// Sponge - Shortcircuit if the block has no neighbor logic
if (!((TrackableBlockBridge) targetBlockState.getBlock()).bridge$overridesNeighborNotificationLogic()) {
return;
}
// Sponge End
// Sponge start - prepare notification
final PhaseContext<@NonNull ?> peek = server.getPhaseContext();
// try { // Vanilla - We need to push the effect transactor so that it always pops
try {
final Supplier<ServerLevel> worldSupplier = VolumeStreamUtils.createWeaklyReferencedSupplier((ServerLevel) (Object) this, "ServerWorld");
final net.minecraft.world.level.block.entity.@Nullable BlockEntity existingTile = targetChunk.getBlockEntity(immutableTarget, LevelChunk.EntityCreationType.CHECK);
peek.getTransactor().logNeighborNotification(worldSupplier, immutableFrom, blockIn, immutableTarget, targetBlockState, existingTile);
peek.associateNeighborStateNotifier(immutableFrom, targetBlockState.getBlock(), immutableTarget, ((ServerLevel) (Object) this), PlayerTracker.Type.NOTIFIER);
// Sponge End
targetBlockState.neighborChanged(((ServerLevel) (Object) this), immutableTarget, blockIn, immutableFrom, false);
} catch (final Throwable throwable) {
final CrashReport crashreport = CrashReport.forThrowable(throwable, "Exception while updating neighbours");
final CrashReportCategory crashreportcategory = crashreport.addCategory("Block being updated");
crashreportcategory.setDetail("Source block type", () -> {
try {
return String.format("ID #%d (%s // %s)", Registry.BLOCK.getId(blockIn), blockIn.getDescriptionId(), blockIn.getClass().getCanonicalName());
} catch (final Throwable var2) {
return "ID #" + Registry.BLOCK.getId(blockIn);
}
});
CrashReportCategory.populateBlockDetails(crashreportcategory, immutableTarget, targetBlockState);
throw new ReportedException(crashreport);
}
}
use of net.minecraft.world.level.block.state.BlockState in project Denizen-For-Bukkit by DenizenScript.
the class ItemHelperImpl method renderFullMap.
/**
* Copied from MapItem.update, redesigned slightly to render totally rather than just relative to a player.
* Some variables manually renamed for readability.
* Also contains reflection fixes for Spigot's FluidState bug.
*/
public static void renderFullMap(MapItemSavedData worldmap, int xMin, int zMin, int xMax, int zMax) {
Level world = ((CraftWorld) worldmap.mapView.getWorld()).getHandle();
int scale = 1 << worldmap.scale;
int mapX = worldmap.x;
int mapZ = worldmap.z;
for (int x = xMin; x < xMax; x++) {
double d0 = 0.0D;
for (int z = zMin; z < zMax; z++) {
int k2 = (mapX / scale + x - 64) * scale;
int l2 = (mapZ / scale + z - 64) * scale;
Multiset<MaterialColor> multiset = LinkedHashMultiset.create();
LevelChunk chunk = world.getChunkAt(new BlockPos(k2, 0, l2));
if (!chunk.isEmpty()) {
ChunkPos chunkcoordintpair = chunk.getPos();
int i3 = k2 & 15;
int j3 = l2 & 15;
int k3 = 0;
double d1 = 0.0D;
if (world.dimensionType().hasCeiling()) {
int l3 = k2 + l2 * 231871;
l3 = l3 * l3 * 31287121 + l3 * 11;
if ((l3 >> 20 & 1) == 0) {
multiset.add(Blocks.DIRT.defaultBlockState().getMapColor(world, BlockPos.ZERO), 10);
} else {
multiset.add(Blocks.STONE.defaultBlockState().getMapColor(world, BlockPos.ZERO), 100);
}
d1 = 100.0D;
} else {
BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos();
BlockPos.MutableBlockPos blockposition_mutableblockposition1 = new BlockPos.MutableBlockPos();
for (int i4 = 0; i4 < scale; ++i4) {
for (int j4 = 0; j4 < scale; ++j4) {
int k4 = chunk.getHeight(Heightmap.Types.WORLD_SURFACE, i4 + i3, j4 + j3) + 1;
BlockState iblockdata;
if (k4 <= world.getMinBuildHeight() + 1) {
iblockdata = Blocks.BEDROCK.defaultBlockState();
} else {
do {
--k4;
blockposition_mutableblockposition.set(chunkcoordintpair.getMinBlockX() + i4 + i3, k4, chunkcoordintpair.getMinBlockZ() + j4 + j3);
iblockdata = chunk.getBlockState(blockposition_mutableblockposition);
} while (iblockdata.getMapColor(world, blockposition_mutableblockposition) == MaterialColor.NONE && k4 > world.getMinBuildHeight());
if (k4 > world.getMinBuildHeight() && !blockStateFluidIsEmpty(iblockdata)) {
int l4 = k4 - 1;
blockposition_mutableblockposition1.set(blockposition_mutableblockposition);
BlockState iblockdata1;
do {
blockposition_mutableblockposition1.t(l4--);
iblockdata1 = chunk.getBlockState(blockposition_mutableblockposition1);
k3++;
} while (l4 > world.getMinBuildHeight() && !blockStateFluidIsEmpty(iblockdata1));
iblockdata = getCorrectStateForFluidBlock(world, iblockdata, blockposition_mutableblockposition);
}
}
worldmap.checkBanners(world, chunkcoordintpair.getMinBlockX() + i4 + i3, chunkcoordintpair.getMinBlockZ() + j4 + j3);
d1 += (double) k4 / (double) (scale * scale);
multiset.add(iblockdata.getMapColor(world, blockposition_mutableblockposition));
}
}
}
k3 /= scale * scale;
double d2 = (d1 - d0) * 4.0D / (double) (scale + 4) + ((double) (x + z & 1) - 0.5D) * 0.4D;
byte b0 = 1;
if (d2 > 0.6D) {
b0 = 2;
}
if (d2 < -0.6D) {
b0 = 0;
}
MaterialColor materialmapcolor = Iterables.getFirst(Multisets.copyHighestCountFirst(multiset), MaterialColor.NONE);
if (materialmapcolor == MaterialColor.WATER) {
d2 = (double) k3 * 0.1D + (double) (x + z & 1) * 0.2D;
b0 = 1;
if (d2 < 0.5D) {
b0 = 2;
}
if (d2 > 0.9D) {
b0 = 0;
}
}
d0 = d1;
worldmap.updateColor(x, z, (byte) (materialmapcolor.id * 4 + b0));
}
}
}
}
Aggregations