All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.nukkit.block.BlockBigDripleaf Maven / Gradle / Ivy

There is a newer version: 1.20.40-r1
Show newest version
package cn.nukkit.block;

import cn.nukkit.Player;
import cn.nukkit.Server;
import cn.nukkit.api.PowerNukkitOnly;
import cn.nukkit.api.PowerNukkitXOnly;
import cn.nukkit.api.Since;
import cn.nukkit.blockproperty.*;
import cn.nukkit.entity.Entity;
import cn.nukkit.event.block.BigDripleafTiltChangeEvent;
import cn.nukkit.item.Item;
import cn.nukkit.item.ItemTool;
import cn.nukkit.level.Level;
import cn.nukkit.level.ParticleEffect;
import cn.nukkit.level.Position;
import cn.nukkit.math.AxisAlignedBB;
import cn.nukkit.math.BlockFace;
import cn.nukkit.math.Vector3;
import cn.nukkit.utils.Faceable;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

@PowerNukkitXOnly
@Since("1.6.0.0-PNX")
public class BlockBigDripleaf extends BlockFlowable implements Faceable {

    public static Map actions = new HashMap<>();
    public static Set fullTiltBlocks = new HashSet<>();

    static{
        if (Server.getInstance() != null) {
            Server.getInstance().getScheduler().scheduleRepeatingTask(() -> {
                for (Map.Entry entry : actions.entrySet().toArray(new Map.Entry[actions.size()])) {
                    if (--entry.getValue().delay == 0) {
                        if (checkTiltAction(entry.getKey())) {
                            BlockBigDripleaf blockBigDripleaf = (BlockBigDripleaf) entry.getKey().getLevelBlock();
                            BigDripleafTiltChangeEvent event = new BigDripleafTiltChangeEvent(blockBigDripleaf, blockBigDripleaf.getTilt(), entry.getValue().targetState);
                            Server.getInstance().getPluginManager().callEvent(event);
                            if (event.isCancelled()) {
                                return;
                            }
                            entry.getValue().targetState = event.getNewTilt();
                            blockBigDripleaf.setTilt(entry.getValue().targetState);
                            entry.getKey().getLevel().setBlock(entry.getKey(), blockBigDripleaf, true, true);
                            if (entry.getValue().targetState == Tilt.FULL_TILT) {
                                fullTiltBlocks.add(entry.getKey());
                            }
                        }
                        actions.remove(entry.getKey());
                        if (entry.getValue().nextAction != null) {
                            actions.put(entry.getKey(), entry.getValue().nextAction);
                        }
                    }
                }
            }, 1);
            Server.getInstance().getScheduler().scheduleRepeatingTask(() -> {
                for (Position pos : fullTiltBlocks.toArray(new Position[0])) {
                    if (pos.getLevelBlock() instanceof BlockBigDripleaf blockBigDripleaf && blockBigDripleaf.getTilt() == Tilt.FULL_TILT) {
                        pos.getLevelBlock().onUpdate(Level.BLOCK_UPDATE_NORMAL);
                    } else {
                        fullTiltBlocks.remove(pos);
                    }
                }
            }, 1);
        }
    }

    @PowerNukkitXOnly
    @Since("1.6.0.0-PNX")
    public static final BlockProperty TILT = new ArrayBlockProperty<>("big_dripleaf_tilt",false,new Tilt[]{Tilt.NONE, Tilt.PARTIAL_TILT, Tilt.FULL_TILT,Tilt.UNSTABLE});

    @PowerNukkitXOnly
    @Since("1.6.0.0-PNX")
    public static final BooleanBlockProperty HEAD = new BooleanBlockProperty("big_dripleaf_head", false);

    @PowerNukkitXOnly
    @Since("1.6.0.0-PNX")
    public static final BlockProperties PROPERTIES = new BlockProperties(CommonBlockProperties.DIRECTION,TILT,HEAD);

    public static boolean checkTiltAction(Position pos){
        if (!actions.containsKey(pos)){
            return true;
        }
        TiltAction action = actions.get(pos);
        if (pos.getLevelBlock() instanceof BlockBigDripleaf blockBigDripleaf && blockBigDripleaf.isHead()){
            return true;
        }
        return false;
    }

    public static void addTiltAction(Position pos,TiltAction action){
        if (!actions.containsKey(pos) ||!checkTiltAction(pos))
            actions.put(pos,action);
    }

    public static void removeTiltAction(Position pos){
        if (actions.containsKey(pos)) {
            actions.remove(pos);
        }
    }

    protected BlockBigDripleaf() {
        super(0);
    }

    @Override
    public String getName() {
        return "Big Dripleaf";
    }

    @Override
    public int getId() {
        return BlockID.BIG_DRIPLEAF;
    }

    @Since("1.6.0.0-PNX")
    @PowerNukkitOnly
    @Nonnull
    @Override
    public BlockProperties getProperties() {
        return PROPERTIES;
    }

    @Override
    public BlockFace getBlockFace() {
        return getPropertyValue(CommonBlockProperties.DIRECTION);
    }

    @Since("1.6.0.0-PNX")
    @PowerNukkitOnly
    @Override
    public void setBlockFace(BlockFace face) {
        setPropertyValue(CommonBlockProperties.DIRECTION, face);
    }

    public boolean isHead(){
        return this.getBooleanValue(HEAD);
    }

    public void setHead(boolean isHead){
        this.setBooleanValue(HEAD,isHead);
    }

    public Tilt getTilt(){
        return this.getPropertyValue(TILT);
    }

    public void setTilt(Tilt tilt){
        this.setPropertyValue(TILT,tilt);
    }

    @PowerNukkitOnly
    @Override
    public int getWaterloggingLevel() {
        return 2;
    }

    @Override
    public int getToolType() {
        return ItemTool.TYPE_NONE;
    }

    @Override
    public boolean canBeActivated() {
        return true;
    }

    @Override
    public boolean place(@Nonnull Item item, @Nonnull Block block, @Nonnull Block target, @Nonnull BlockFace face, double fx, double fy, double fz, @Nullable Player player) {
        BlockBigDripleaf blockBigDripleafTop = new BlockBigDripleaf();
        blockBigDripleafTop.setHead(true);
        blockBigDripleafTop.setBlockFace(player.getDirection().getOpposite());
        if(canKeepAlive(block)){
            this.level.setBlock(block,blockBigDripleafTop,true,true);
            return true;
        }
        if (block.getSide(BlockFace.DOWN) instanceof BlockBigDripleaf) {
            BlockBigDripleaf blockDown = (BlockBigDripleaf) this.level.getBlock(block.getSide(BlockFace.DOWN));
            blockDown.setHead(false);
            blockBigDripleafTop.setBlockFace(((BlockBigDripleaf) block.getSide(BlockFace.DOWN)).getBlockFace());
            this.level.setBlock(blockDown,blockDown,true,true);
            this.level.setBlock(block,blockBigDripleafTop,true,true);
            return true;
        }
        return false;
    }

    @Override
    public boolean onActivate(@Nonnull Item item, Player player) {
        if (item.isFertilizer()) {
            boolean state = this.grow(this,1);
            if(state) {
                this.level.addParticleEffect(this.add(0.5, 0.5, 0.5), ParticleEffect.CROP_GROWTH);
                item.count--;
                return true;
            }
            return false;
        }
        return false;
    }

    @Override
    public boolean onBreak(@Nonnull Item item) {
        removeTiltAction(this);
        this.level.setBlock(this, new BlockAir(), true, true);
        this.level.dropItem(this, this.toItem());
        if(this.getSide(BlockFace.UP).getId() == BlockID.BIG_DRIPLEAF){
            this.level.getBlock(this.getSide(BlockFace.UP)).onBreak(null);
        }
        if(this.getSide(BlockFace.DOWN).getId() == BlockID.BIG_DRIPLEAF){
            this.level.getBlock(this.getSide(BlockFace.DOWN)).onBreak(null);
        }
        return true;
    }


    @Override
    public int onUpdate(int type) {
        if (this.isGettingPower()) {
            removeTiltAction(this);
            this.setTilt(Tilt.NONE);
            this.level.setBlock(this,this,true,true);
            return 0;
        }
        if (!canKeepAlive(this)) {
            this.level.setBlock(this, new BlockAir(), true, true);
            removeTiltAction(this);
            this.level.dropItem(this, this.toItem());
        }
        if (this.isHead()) {
            AtomicBoolean hasEntityOn = new AtomicBoolean(false);
            this.getChunk().getEntities().values().stream().parallel().forEach(entity -> {
                if (entity.asBlockVector3().equals(this.asBlockVector3()))
                    hasEntityOn.set(true);
            });
            if (hasEntityOn.get() && this.getLevelBlock() instanceof BlockBigDripleaf blockBigDripleaf && blockBigDripleaf.getTilt() == Tilt.NONE) {
                addTiltAction(this, new TiltAction(Tilt.PARTIAL_TILT,15,new TiltAction(Tilt.FULL_TILT,15,null)));
            }else {
                if (this.getLevelBlock() instanceof BlockBigDripleaf blockBigDripleaf && blockBigDripleaf.getTilt() == Tilt.FULL_TILT) {
                    addTiltAction(this, new TiltAction(Tilt.NONE,100,null));
                }
            }
        }
        return super.onUpdate(type);
    }

    public boolean canKeepAlive(Position pos){
        Block blockDown = this.level.getBlock(pos.getSide(BlockFace.DOWN));
        if (this.level.getBlock(blockDown) instanceof BlockBigDripleaf && !((BlockBigDripleaf)this.level.getBlock(blockDown)).isHead()){
            return true;
        }
        if (blockDown instanceof BlockDirt || blockDown instanceof BlockDirtWithRoots || blockDown instanceof BlockMoss || blockDown instanceof BlockClay){
            return true;
        }
        return false;
    }

    @PowerNukkitXOnly
    @Since("1.6.0.0-PNX")
    public boolean grow(Position pos,int heightIncreased){
        Block block = pos.getLevelBlock();
        if (block instanceof BlockBigDripleaf) {
            while (block.getSide(BlockFace.UP) instanceof BlockBigDripleaf) {
                block = block.getSide(BlockFace.UP);
            }
        }
        removeTiltAction(block);

        int maxHeightIncreased = 0;
        Block blockUp = block.getBlock();
        for(int i = 1;i<=heightIncreased;i++){
            if ((blockUp = blockUp.getSide(BlockFace.UP)) instanceof BlockAir && blockUp.getY() < 320)
                maxHeightIncreased++;
        }
        BlockBigDripleaf blockBigDripleafDown = new BlockBigDripleaf();
        BlockBigDripleaf blockBigDripleafHead = new BlockBigDripleaf();
        blockBigDripleafDown.setBlockFace(((BlockBigDripleaf)block).getBlockFace());
        blockBigDripleafHead.setBlockFace(((BlockBigDripleaf)block).getBlockFace());
        blockBigDripleafHead.setHead(true);
        for(int height = 0;height




© 2015 - 2024 Weber Informatics LLC | Privacy Policy