Search in sources :

Example 91 with BlockState

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();
        }
    }
}
Also used : BlockState(net.minecraft.world.level.block.state.BlockState) LevelBridge(org.spongepowered.common.bridge.world.level.LevelBridge) Vec3(net.minecraft.world.phys.Vec3) BlockHitResult(net.minecraft.world.phys.BlockHitResult) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 92 with BlockState

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
                }
            }
        }
    }
}
Also used : LivingEntity(net.minecraft.world.entity.LivingEntity) Entity(net.minecraft.world.entity.Entity) ServerLocation(org.spongepowered.api.world.server.ServerLocation) ExplosionEvent(org.spongepowered.api.event.world.ExplosionEvent) ArrayList(java.util.ArrayList) LivingEntity(net.minecraft.world.entity.LivingEntity) Cause(org.spongepowered.api.event.Cause) Vec3(net.minecraft.world.phys.Vec3) BlockPos(net.minecraft.core.BlockPos) Player(net.minecraft.world.entity.player.Player) Explosion(org.spongepowered.api.world.explosion.Explosion) BlockState(net.minecraft.world.level.block.state.BlockState) AABB(net.minecraft.world.phys.AABB) FluidState(net.minecraft.world.level.material.FluidState) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Example 93 with BlockState

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);
}
Also used : SpongeLocatableBlockBuilder(org.spongepowered.common.world.server.SpongeLocatableBlockBuilder) TrackableBlockEventDataBridge(org.spongepowered.common.bridge.world.level.TrackableBlockEventDataBridge) TrackableBridge(org.spongepowered.common.bridge.TrackableBridge) PistonBaseBlock(net.minecraft.world.level.block.piston.PistonBaseBlock) BlockState(net.minecraft.world.level.block.state.BlockState) LocatableBlock(org.spongepowered.api.world.LocatableBlock) ServerLevelBridge(org.spongepowered.common.bridge.server.level.ServerLevelBridge) BlockEventData(net.minecraft.world.level.BlockEventData) BlockStateBridge(org.spongepowered.common.bridge.world.level.block.state.BlockStateBridge) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Example 94 with BlockState

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);
    }
}
Also used : ServerLevel(net.minecraft.server.level.ServerLevel) CrashReport(net.minecraft.CrashReport) ReportedException(net.minecraft.ReportedException) PrettyPrinter(org.spongepowered.common.util.PrettyPrinter) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) LevelChunk(net.minecraft.world.level.chunk.LevelChunk) BlockState(net.minecraft.world.level.block.state.BlockState) BlockPos(net.minecraft.core.BlockPos) Nullable(org.checkerframework.checker.nullness.qual.Nullable) CrashReportCategory(net.minecraft.CrashReportCategory) ReportedException(net.minecraft.ReportedException)

Example 95 with BlockState

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));
            }
        }
    }
}
Also used : MaterialColor(net.minecraft.world.level.material.MaterialColor) LevelChunk(net.minecraft.world.level.chunk.LevelChunk) BlockState(net.minecraft.world.level.block.state.BlockState) Level(net.minecraft.world.level.Level) BlockPos(net.minecraft.core.BlockPos) ChunkPos(net.minecraft.world.level.ChunkPos) CraftWorld(org.bukkit.craftbukkit.v1_17_R1.CraftWorld)

Aggregations

BlockState (net.minecraft.world.level.block.state.BlockState)141 BlockPos (net.minecraft.core.BlockPos)75 Direction (net.minecraft.core.Direction)18 Level (net.minecraft.world.level.Level)14 Block (net.minecraft.world.level.block.Block)14 ArrayList (java.util.ArrayList)10 ServerLevel (net.minecraft.server.level.ServerLevel)10 SoundType (net.minecraft.world.level.block.SoundType)10 Vec3 (net.minecraft.world.phys.Vec3)10 BlockEntity (net.minecraft.world.level.block.entity.BlockEntity)9 Random (java.util.Random)8 ItemStack (net.minecraft.world.item.ItemStack)7 FluidState (net.minecraft.world.level.material.FluidState)7 AABB (net.minecraft.world.phys.AABB)6 BuildBlock (com.wuest.prefab.structures.base.BuildBlock)5 LevelChunk (net.minecraft.world.level.chunk.LevelChunk)5 SubscribeEvent (net.minecraftforge.eventbus.api.SubscribeEvent)5 LocationTag (com.denizenscript.denizen.objects.LocationTag)4 FakeBlock (com.denizenscript.denizen.utilities.blocks.FakeBlock)4 HashMap (java.util.HashMap)4