org.diorite.impl.block.BlockImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.diorite.impl.block.BlockImpl.java

Source

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2016. Diorite (by Bartomiej Mazur (aka GotoFinal))
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package org.diorite.impl.block;

import javax.vecmath.Vector3d;

import java.util.Optional;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import org.diorite.impl.DioriteCore;
import org.diorite.impl.world.chunk.ChunkImpl;
import org.diorite.block.BlockState;
import org.diorite.entity.Player;
import org.diorite.material.BlockMaterialData;
import org.diorite.utils.lazy.LazyValue;
import org.diorite.utils.math.geometry.BoundingBox;
import org.diorite.world.Biome;
import org.diorite.block.Block;
import org.diorite.tileentity.TileEntity;
import org.diorite.world.World;

public class BlockImpl implements Block {
    private final byte x; // x pos on chunk, not map
    private final int y;
    private final byte z; // z pos on chunk, not map
    private final ChunkImpl chunk;
    private BlockMaterialData type;
    private final LazyValue<BoundingBox> lazyBox;
    private BlockState state;

    public BlockImpl(final int x, final int y, final int z, final ChunkImpl chunk, final BlockMaterialData type) {
        this.x = (byte) x;
        this.y = y;
        this.z = (byte) z;
        this.chunk = chunk;
        this.type = type;
        this.lazyBox = new LazyValue<>(() -> {
            final int x1 = this.x + (this.chunk.getX() << 4);
            final int x2 = (x1 >= 0) ? (x1 + 1) : (x1 - 1);

            final int y1 = this.z + (this.chunk.getZ() << 4);
            final int y2 = y1 + 1;

            final int z1 = this.z + (this.chunk.getZ() << 4);
            final int z2 = (z1 >= 0) ? (z1 + 1) : (z1 - 1);

            return BoundingBox.fromCorners(new Vector3d(x1, y1, z1), new Vector3d(x2, y2, z2));
        });
        this.state = getBlockState(this);
    }

    public BlockImpl(final int x, final int y, final int z, final ChunkImpl chunk) {
        this.x = (byte) x;
        this.y = y;
        this.z = (byte) z;
        this.chunk = chunk;
        if (!chunk.isLoaded()) {
            chunk.load();
        }
        this.type = chunk.getBlockType(x, y, z);
        this.lazyBox = new LazyValue<>(() -> {
            final int x1 = this.x + (this.chunk.getX() << 4);
            final int x2 = (x1 >= 0) ? (x1 + 1) : (x1 - 1);

            final int z1 = this.z + (this.chunk.getZ() << 4);
            final int z2 = (z1 >= 0) ? (z1 + 1) : (z1 - 1);

            return BoundingBox.fromCorners(new Vector3d(x1, this.y, z1), new Vector3d(x2, this.y + 1, z2));
        });
        this.state = getBlockState(this);
    }

    private static BlockState getBlockState(Block block) {
        BlockMaterialData mat = block.getType();

        if (mat == BlockMaterialData.BEACON) {
            return new BeaconImpl(block);
        } else if (mat == BlockMaterialData.BREWING_STAND_BLOCK) //TODO: what about BlockMaterialData.BREWING_STAND?
        {
            return new BrewingStandImpl(block);
        } else if (mat == BlockMaterialData.CHEST || mat == BlockMaterialData.TRAPPED_CHEST) {
            return new ChestImpl(block);
        } else if (mat == BlockMaterialData.COMMAND_BLOCK) {
            return new CommandBlockImpl(block);
        } else if (mat == BlockMaterialData.DISPENSER) {
            return new DispenserImpl(block);
        } else if (mat == BlockMaterialData.DROPPER) {
            return new DropperImpl(block);
        } else if (mat == BlockMaterialData.FURNACE) {
            return new FurnaceImpl(block);
        } else if (mat == BlockMaterialData.HOPPER) {
            return new HopperImpl(block);
        } else if (mat == BlockMaterialData.JUKEBOX) {
            return new JukeboxImpl(block);
        } else if (mat == BlockMaterialData.MOB_SPAWNER) {
            return new MobSpawnerImpl(block);
        } else if (mat == BlockMaterialData.NOTEBLOCK) {
            return new NoteBlockImpl(block);
        } else if (mat == BlockMaterialData.WALL_SIGN) //TODO: what about BlockMaterialData.SIGN?
        {
            return new SignImpl(block);
        } else if (mat == BlockMaterialData.SKULL_BLOCK) //TODO: what about BlockMaterialData.SKULL?
        {
            return new SkullImpl(block);
        } else {
            return null;
        }
    }

    @Override
    public int getX() {
        return this.x + (this.chunk.getX() << 4);
    }

    @Override
    public int getY() {
        return this.y;
    }

    @Override
    public int getZ() {
        return this.z + (this.chunk.getZ() << 4);
    }

    @Override
    public World getWorld() {
        return this.chunk.getWorld();
    }

    @Override
    public BlockMaterialData getType() {
        return this.type;
    }

    @Override
    public Optional<TileEntity> getTileEntity() {
        return Optional.ofNullable(this.chunk.getTileEntity(this));
    }

    @Override
    public BlockState getState() {
        return this.state;
    }

    @Override
    public void setType(final BlockMaterialData type) {
        this.type = type;
        this.chunk.setBlock(this.x, this.y, this.z, this.type);

        //        final PacketPlayOutBlockChange packet = new PacketPlayOutBlockChange(new BlockLocation(this.getX(), this.y, this.getZ(), this.getWorld()), type);
        //        ServerImpl.getInstance().getPlayersManager().forEach(p -> p.getWorld().equals(this.getWorld()) && p.isVisibleChunk(this.x, this.z), packet);
    }

    @Override
    public Biome getBiome() {
        return this.chunk.getBiome(this.x, this.y, this.z);
    }

    @Override
    public void update() {
        this.type = this.chunk.getBlockType(this.x, this.y, this.z);

        if (this.state != null) {
            this.state.update();
        }
    }

    @Override
    public Block getRelative(final int x, final int y, final int z) {
        return this.chunk.getWorld().getBlock(this.getX() + x, this.y + y, this.getZ() + z);
    }

    @Override
    public BoundingBox getBoundingBox() {
        return this.lazyBox.get();
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof BlockImpl)) {
            return false;
        }

        final BlockImpl block = (BlockImpl) o;

        return (this.x == block.x) && (this.y == block.y) && (this.z == block.z)
                && !((this.chunk != null) ? !this.chunk.equals(block.chunk) : (block.chunk != null))
                && !((this.type != null) ? !this.type.equals(block.type) : (block.type != null));
    }

    @Override
    public int hashCode() {
        int result = (int) this.x;
        result = (31 * result) + this.y;
        result = (31 * result) + (int) this.z;
        result = (31 * result) + ((this.chunk != null) ? this.chunk.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).appendSuper(super.toString())
                .append("x", this.getX()).append("y", this.y).append("z", this.getZ())
                .append("type", this.type.name() + ":" + this.type.getTypeName()).toString();
    }
}