Search in sources :

Example 46 with BlockState

use of org.spongepowered.api.block.BlockState in project LanternServer by LanternPowered.

the class ProcessorPlayOutParticleEffect method preProcess.

private ICachedMessage preProcess(ParticleEffect effect0) {
    final LanternParticleEffect effect = (LanternParticleEffect) effect0;
    final LanternParticleType type = effect.getType();
    final OptionalInt internalType = type.getInternalType();
    // Special cases
    if (!internalType.isPresent()) {
        if (type == ParticleTypes.FIREWORKS) {
            // Create the fireworks data item
            final LanternItemStack itemStack = new LanternItemStack(ItemTypes.FIREWORKS);
            itemStack.tryOffer(Keys.FIREWORK_EFFECTS, effect.getOptionOrDefault(ParticleOptions.FIREWORK_EFFECTS).get());
            // Write the item to a parameter list
            final ByteBufParameterList parameterList = new ByteBufParameterList(ByteBufferAllocator.unpooled());
            parameterList.add(EntityParameters.Fireworks.ITEM, itemStack);
            return new CachedFireworksMessage(new MessagePlayOutEntityMetadata(CachedFireworksMessage.ENTITY_ID, parameterList));
        } else if (type == ParticleTypes.FERTILIZER) {
            final int quantity = effect.getOptionOrDefault(ParticleOptions.QUANTITY).get();
            return new CachedEffectMessage(2005, quantity, false);
        } else if (type == ParticleTypes.SPLASH_POTION) {
            final int potionId = this.potionEffectTypeToId.getInt(effect.getOptionOrDefault(ParticleOptions.POTION_EFFECT_TYPE).get());
            return new CachedEffectMessage(2002, potionId, false);
        } else if (type == ParticleTypes.BREAK_BLOCK) {
            final int state = getBlockState(effect, type.getDefaultOption(ParticleOptions.BLOCK_STATE));
            if (state == 0) {
                return EmptyCachedMessage.INSTANCE;
            }
            return new CachedEffectMessage(2001, state, false);
        } else if (type == ParticleTypes.MOBSPAWNER_FLAMES) {
            return new CachedEffectMessage(2004, 0, false);
        } else if (type == ParticleTypes.ENDER_TELEPORT) {
            return new CachedEffectMessage(2003, 0, false);
        } else if (type == ParticleTypes.DRAGON_BREATH_ATTACK) {
            return new CachedEffectMessage(2006, 0, false);
        } else if (type == ParticleTypes.FIRE_SMOKE) {
            final Direction direction = effect.getOptionOrDefault(ParticleOptions.DIRECTION).get();
            return new CachedEffectMessage(2000, getDirectionData(direction), false);
        }
        return EmptyCachedMessage.INSTANCE;
    }
    final int internalId = internalType.getAsInt();
    final Vector3f offset = effect.getOption(ParticleOptions.OFFSET).map(Vector3d::toFloat).orElse(Vector3f.ZERO);
    final int quantity = effect.getOption(ParticleOptions.QUANTITY).orElse(1);
    int[] extra = null;
    // The extra values, normal behavior offsetX, offsetY, offsetZ
    double f0 = 0f;
    double f1 = 0f;
    double f2 = 0f;
    // Depends on behavior
    // Note: If the count > 0 -> speed = 0f else if count = 0 -> speed = 1f
    final Optional<BlockState> defaultBlockState;
    if (type != ParticleTypes.ITEM_CRACK && (defaultBlockState = type.getDefaultOption(ParticleOptions.BLOCK_STATE)).isPresent()) {
        final int state = getBlockState(effect, defaultBlockState);
        if (state == 0) {
            return EmptyCachedMessage.INSTANCE;
        }
        extra = new int[] { state };
    }
    final Optional<ItemStackSnapshot> defaultItemStackSnapshot;
    if (extra == null && (defaultItemStackSnapshot = type.getDefaultOption(ParticleOptions.ITEM_STACK_SNAPSHOT)).isPresent()) {
        final Optional<ItemStackSnapshot> optItemStackSnapshot = effect.getOption(ParticleOptions.ITEM_STACK_SNAPSHOT);
        if (optItemStackSnapshot.isPresent()) {
            extra = toExtraItemData(optItemStackSnapshot.get().createStack());
        } else {
            final Optional<BlockState> optBlockState = effect.getOption(ParticleOptions.BLOCK_STATE);
            if (optBlockState.isPresent()) {
                final BlockState blockState = optBlockState.get();
                final Optional<ItemType> optItemType = blockState.getType().getItem();
                if (optItemType.isPresent()) {
                    // TODO: Item damage value
                    extra = new int[] { ItemRegistryModule.get().getInternalId(optItemType.get()), 0 };
                } else {
                    return EmptyCachedMessage.INSTANCE;
                }
            } else {
                extra = toExtraItemData(defaultItemStackSnapshot.get().createStack());
            }
        }
    }
    if (extra == null) {
        extra = new int[0];
    }
    final Optional<Double> defaultScale = type.getDefaultOption(ParticleOptions.SCALE);
    final Optional<Color> defaultColor;
    final Optional<NotePitch> defaultNote;
    final Optional<Vector3d> defaultVelocity;
    if (defaultScale.isPresent()) {
        double scale = effect.getOption(ParticleOptions.SCALE).orElse(defaultScale.get());
        // Server formula: sizeServer = (-sizeClient * 2) + 2
        if (type == ParticleTypes.LARGE_EXPLOSION || type == ParticleTypes.SWEEP_ATTACK) {
            scale = (-scale * 2f) + 2f;
        }
        if (scale == 0f) {
            return new CachedParticleMessage(internalId, offset, quantity, extra);
        }
        f0 = scale;
    } else if ((defaultColor = type.getDefaultOption(ParticleOptions.COLOR)).isPresent()) {
        final boolean isSpell = type == ParticleTypes.MOB_SPELL || type == ParticleTypes.AMBIENT_MOB_SPELL;
        Color color = effect.getOption(ParticleOptions.COLOR).orElse(null);
        if (!isSpell && (color == null || color.equals(defaultColor.get()))) {
            return new CachedParticleMessage(internalId, offset, quantity, extra);
        } else if (isSpell && color == null) {
            color = defaultColor.get();
        }
        f0 = color.getRed() / 255f;
        f1 = color.getGreen() / 255f;
        f2 = color.getBlue() / 255f;
        // but we already chose for the color, can't have both
        if (isSpell) {
            f0 = Math.max(f0, 0.001f);
            f2 = Math.max(f0, 0.001f);
        }
        // If the f0 value 0 is, the redstone will set it automatically to red 255
        if (f0 == 0f && type == ParticleTypes.REDSTONE_DUST) {
            f0 = 0.00001f;
        }
    } else if ((defaultNote = type.getDefaultOption(ParticleOptions.NOTE)).isPresent()) {
        final NotePitch notePitch = effect.getOption(ParticleOptions.NOTE).orElse(defaultNote.get());
        final float note = ((LanternNotePitch) notePitch).getInternalId();
        if (note == 0f) {
            return new CachedParticleMessage(internalId, offset, quantity, extra);
        }
        f0 = note / 24f;
    } else if ((defaultVelocity = type.getDefaultOption(ParticleOptions.VELOCITY)).isPresent()) {
        final Vector3d velocity = effect.getOption(ParticleOptions.VELOCITY).orElse(defaultVelocity.get());
        f0 = velocity.getX();
        f1 = velocity.getY();
        f2 = velocity.getZ();
        final Optional<Boolean> slowHorizontalVelocity = type.getDefaultOption(ParticleOptions.SLOW_HORIZONTAL_VELOCITY);
        if (slowHorizontalVelocity.isPresent() && effect.getOption(ParticleOptions.SLOW_HORIZONTAL_VELOCITY).orElse(slowHorizontalVelocity.get())) {
            f0 = 0f;
            f2 = 0f;
        }
        // The y value won't work for this effect, if the value isn't 0 the velocity won't work
        if (type == ParticleTypes.WATER_SPLASH) {
            f1 = 0f;
        }
        if (f0 == 0f && f1 == 0f && f2 == 0f) {
            return new CachedParticleMessage(internalId, offset, quantity, extra);
        }
    }
    // Is this check necessary?
    if (f0 == 0f && f1 == 0f && f2 == 0f) {
        return new CachedParticleMessage(internalId, offset, quantity, extra);
    }
    return new CachedOffsetParticleMessage(internalId, new Vector3f(f0, f1, f2), offset, quantity, extra);
}
Also used : ItemType(org.spongepowered.api.item.ItemType) LanternParticleEffect(org.lanternpowered.server.effect.particle.LanternParticleEffect) Direction(org.spongepowered.api.util.Direction) NotePitch(org.spongepowered.api.data.type.NotePitch) LanternNotePitch(org.lanternpowered.server.data.type.LanternNotePitch) ByteBufParameterList(org.lanternpowered.server.network.entity.parameter.ByteBufParameterList) Optional(java.util.Optional) Color(org.spongepowered.api.util.Color) OptionalInt(java.util.OptionalInt) LanternItemStack(org.lanternpowered.server.inventory.LanternItemStack) LanternNotePitch(org.lanternpowered.server.data.type.LanternNotePitch) BlockState(org.spongepowered.api.block.BlockState) Vector3d(com.flowpowered.math.vector.Vector3d) Vector3f(com.flowpowered.math.vector.Vector3f) MessagePlayOutEntityMetadata(org.lanternpowered.server.network.vanilla.message.type.play.MessagePlayOutEntityMetadata) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) LanternParticleType(org.lanternpowered.server.effect.particle.LanternParticleType)

Example 47 with BlockState

use of org.spongepowered.api.block.BlockState in project LanternServer by LanternPowered.

the class LanternChunk method createSnapshot.

@Override
public BlockSnapshot createSnapshot(int x, int y, int z) {
    final BlockState state = getBlock(x, y, z);
    final Location<World> loc = new Location<>(this.world, x, y, z);
    // TODO: Tile entity data
    return new LanternBlockSnapshot(loc, state, ((LanternBlockType) state.getType()).getExtendedBlockStateProvider().get(state, loc, null), getCreator(x, y, z), getNotifier(x, y, z), ImmutableMap.of());
}
Also used : LanternBlockSnapshot(org.lanternpowered.server.block.LanternBlockSnapshot) BlockState(org.spongepowered.api.block.BlockState) World(org.spongepowered.api.world.World) LanternWorld(org.lanternpowered.server.world.LanternWorld) LanternBlockType(org.lanternpowered.server.block.LanternBlockType) Location(org.spongepowered.api.world.Location)

Example 48 with BlockState

use of org.spongepowered.api.block.BlockState in project LanternServer by LanternPowered.

the class LanternChunk method get.

@Override
public <E> Optional<E> get(int x, int y, int z, Key<? extends BaseValue<E>> key) {
    if (!this.loaded) {
        return Optional.empty();
    }
    final BlockState blockState = getBlock(x, y, z);
    Optional<E> value = blockState.get(key);
    if (!value.isPresent()) {
        final Optional<TileEntity> tileEntity = getTileEntity(x, y, z);
        if (tileEntity.isPresent()) {
            value = tileEntity.get().get(key);
        }
    }
    return value;
}
Also used : LanternTileEntity(org.lanternpowered.server.block.tile.LanternTileEntity) TileEntity(org.spongepowered.api.block.tileentity.TileEntity) BlockState(org.spongepowered.api.block.BlockState) CHUNK_BIOME_VOLUME(org.lanternpowered.server.world.chunk.LanternChunkLayout.CHUNK_BIOME_VOLUME) CHUNK_SIZE(org.lanternpowered.server.world.chunk.LanternChunkLayout.CHUNK_SIZE)

Example 49 with BlockState

use of org.spongepowered.api.block.BlockState in project LanternServer by LanternPowered.

the class LanternChunk method getBlockSelectionBox.

@Override
public Optional<AABB> getBlockSelectionBox(int x, int y, int z) {
    final BlockState block = getBlock(x, y, z);
    if (block.getType() == BlockTypes.AIR) {
        return Optional.empty();
    }
    final ObjectProvider<AABB> aabbObjectProvider = ((LanternBlockType) block.getType()).getBoundingBoxProvider();
    if (aabbObjectProvider == null) {
        return Optional.empty();
    }
    final AABB aabb;
    if (aabbObjectProvider instanceof ConstantObjectProvider || aabbObjectProvider instanceof CachedSimpleObjectProvider || aabbObjectProvider instanceof SimpleObjectProvider) {
        aabb = aabbObjectProvider.get(block, null, null);
    } else {
        aabb = aabbObjectProvider.get(block, new Location<>(this.world, x, y, z), null);
    }
    return aabb == null ? Optional.empty() : Optional.of(aabb.offset(x, y, z));
}
Also used : BlockState(org.spongepowered.api.block.BlockState) ConstantObjectProvider(org.lanternpowered.server.block.provider.ConstantObjectProvider) CachedSimpleObjectProvider(org.lanternpowered.server.block.provider.CachedSimpleObjectProvider) LanternBlockType(org.lanternpowered.server.block.LanternBlockType) AABB(org.spongepowered.api.util.AABB) CachedSimpleObjectProvider(org.lanternpowered.server.block.provider.CachedSimpleObjectProvider) SimpleObjectProvider(org.lanternpowered.server.block.provider.SimpleObjectProvider) Location(org.spongepowered.api.world.Location)

Example 50 with BlockState

use of org.spongepowered.api.block.BlockState in project LanternServer by LanternPowered.

the class LanternChunk method setBlock.

@Override
public boolean setBlock(int x, int y, int z, BlockState block, BlockChangeFlag flag) {
    checkNotNull(block, "block");
    checkNotNull(flag, "flag");
    checkVolumeBounds(x, y, z);
    if (!this.loaded) {
        return false;
    }
    final short type = BlockRegistryModule.get().getStateInternalIdAndData(block);
    final short type1;
    // Air doesn't have metadata values
    if (type >> 4 == 0 && type != 0) {
        type1 = 0;
    } else {
        type1 = type;
    }
    final BlockState[] changeData = new BlockState[1];
    final int rx = x & 0xf;
    final int rz = z & 0xf;
    this.chunkSections.work(y >> 4, section -> {
        if (section == null) {
            // so we can fail fast
            if (type1 == 0) {
                return section;
            }
            // Create a new section
            section = new ChunkSection();
        }
        final int index = ChunkSection.index(rx, y & 0xf, rz);
        final short oldType = section.types[index];
        if (oldType == type1) {
            return section;
        }
        if (oldType != 0) {
            short count = section.typesCountMap.get(oldType);
            if (count > 0) {
                if (--count <= 0) {
                    section.typesCountMap.remove(oldType);
                } else {
                    section.typesCountMap.put(oldType, count);
                }
            }
        }
        if (type1 != 0) {
            section.typesCountMap.put(type1, (short) (section.typesCountMap.get(type1) + 1));
            if (oldType == 0) {
                section.nonAirCount++;
            }
        } else {
            section.nonAirCount--;
        }
        final BlockState oldState = BlockRegistryModule.get().getStateByInternalIdAndData(oldType).get();
        changeData[0] = oldState;
        // The section is empty, destroy it
        if (section.nonAirCount <= 0) {
            return null;
        }
        final LanternTileEntity tileEntity = section.tileEntities.get((short) index);
        boolean remove = false;
        boolean refresh = false;
        final Optional<TileEntityProvider> tileEntityProvider = ((LanternBlockType) block.getType()).getTileEntityProvider();
        if (tileEntity != null) {
            if (oldType == 0 || type1 == 0) {
                remove = true;
            } else if (tileEntity instanceof ITileEntityRefreshBehavior) {
                if (((ITileEntityRefreshBehavior) tileEntity).shouldRefresh(oldState, block)) {
                    remove = true;
                    refresh = true;
                }
            } else if (oldType >> 4 != type1 >> 4) {
                // The default behavior will only refresh if the
                // block type is changed and not the block state
                remove = true;
                refresh = true;
            }
            if (refresh && !tileEntityProvider.isPresent()) {
                refresh = false;
            }
        } else if (tileEntityProvider.isPresent()) {
            refresh = true;
        }
        if (remove) {
            tileEntity.setValid(false);
        }
        if (refresh) {
            final Location<World> location = tileEntity != null ? tileEntity.getLocation() : new Location<>(this.world, x, y, z);
            final LanternTileEntity newTileEntity = (LanternTileEntity) tileEntityProvider.get().get(block, location, null);
            section.tileEntities.put((short) index, newTileEntity);
            newTileEntity.setLocation(location);
            newTileEntity.setValid(true);
        } else if (remove) {
            section.tileEntities.remove((short) index);
        }
        section.types[index] = type1;
        return section;
    });
    final int index = rz << 4 | rx;
    long stamp = this.heightMapLock.writeLock();
    try {
        // TODO: Check first and then use the write lock?
        if (type != 0 && (this.heightMap[index] & 0xff) < y) {
            this.heightMap[index] = (byte) y;
            this.heightMapUpdateFlags.clear(index);
        } else if (type == 0 && (this.heightMap[index] & 0xff) == y) {
            this.heightMapUpdateFlags.set(index);
        }
    } finally {
        this.heightMapLock.unlock(stamp);
    }
    if (changeData[0] != null) {
        this.world.getEventListener().onBlockChange(x, y, z, changeData[0], block);
    }
    return true;
}
Also used : TileEntityProvider(org.lanternpowered.server.block.TileEntityProvider) World(org.spongepowered.api.world.World) LanternWorld(org.lanternpowered.server.world.LanternWorld) LanternBlockType(org.lanternpowered.server.block.LanternBlockType) BlockState(org.spongepowered.api.block.BlockState) ITileEntityRefreshBehavior(org.lanternpowered.server.block.tile.ITileEntityRefreshBehavior) LanternTileEntity(org.lanternpowered.server.block.tile.LanternTileEntity)

Aggregations

BlockState (org.spongepowered.api.block.BlockState)133 World (org.spongepowered.api.world.World)39 IBlockState (net.minecraft.block.state.IBlockState)29 BlockType (org.spongepowered.api.block.BlockType)27 BlockSnapshot (org.spongepowered.api.block.BlockSnapshot)22 Direction (org.spongepowered.api.util.Direction)21 Optional (java.util.Optional)20 TileEntity (org.spongepowered.api.block.tileentity.TileEntity)20 Vector3i (com.flowpowered.math.vector.Vector3i)19 Location (org.spongepowered.api.world.Location)18 ItemStack (org.spongepowered.api.item.inventory.ItemStack)17 LocatableBlock (org.spongepowered.api.world.LocatableBlock)14 Sponge (org.spongepowered.api.Sponge)13 ItemType (org.spongepowered.api.item.ItemType)13 ArrayList (java.util.ArrayList)12 Player (org.spongepowered.api.entity.living.player.Player)12 List (java.util.List)11 InvalidDataException (org.spongepowered.api.data.persistence.InvalidDataException)11 Vector3d (com.flowpowered.math.vector.Vector3d)10 Listener (org.spongepowered.api.event.Listener)10