smpships.entity.EntityBlock.java Source code

Java tutorial

Introduction

Here is the source code for smpships.entity.EntityBlock.java

Source

package smpships.entity;

import net.minecraft.block.Block;
import net.minecraft.entity.Entity;

import java.util.UUID;

import smpships.SMPships;
import smpships.Utils;
import net.minecraft.entity.IEntityMultiPart;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.world.World;

import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteArrayDataOutput;

import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

/**
 * An entity that looks and feels like a block, that is NOT the control block
 * (for that see {@code ControlBlockEntity}). These are the children entity,
 * and have a {@code ControlBlockEntity} as a parent. Note must implement
 * IEntityAdditionalSpawnData, because Minecraft calls constructor #1,
 * which sets all my variables in this class to 0 or null. so make sure all
 * variables are saved and loaded in read/writeSpawnData() down below.
 * <p>
 * trying to replace bounding box with anything at all results in no collisions
 * <p>
 * special block entities (e.g. chests) would probably best be done as a subclass of this, for full functionality
 * <p>
 * March 2013<br>
 * Released under the <a href=http://www.gnu.org/copyleft/gpl.html>GNU General Public License</a>
 * 
 * @author Grumdot
 * @author MineS1m0n
 * @see EntityShipBlock
 */

public class EntityBlock extends Entity implements IEntityAdditionalSpawnData {

    public EntityShipBlock parent;
    public int xOff; // offset from parent
    public int yOff;
    public int zOff;

    public int blockID;
    public int metadata;

    public EntityBlock(World w) {//constructor #1, not used by me but often called by Minecraft
        super(w);
        preventEntitySpawning = true;
        setSize(Utils.blockEntityWidth, Utils.blockEntityWidth);
        //yOffset = height / 2.0F;
        isImmuneToFire = true;
    }

    public EntityBlock(World w, double x, double y, double z, int blockID, int metadata, EntityShipBlock ship) {//constructor #2 used by me               
        this(w);

        this.parent = ship;
        this.blockID = blockID;
        this.metadata = metadata;

        setPosition(x, y, z); //note this also creates bounding box (using height and width)

        xOff = (int) (posX - ship.posX);
        yOff = (int) (posY - ship.posY);
        zOff = (int) (posZ - ship.posZ);

    }

    @Override
    protected boolean canTriggerWalking() {
        return false;
    }

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

    @Override
    public float getShadowSize() {
        return 0.0F;
    }

    @Override
    public ItemStack getPickedResult(MovingObjectPosition target) {
        return new ItemStack(Block.blocksList[blockID]);
    }

    // children do nothing (at least they don't move themselves) parents will do all calculations an movements - part of the minimization of server-client network traffic

    @Override
    protected void entityInit() {
    }

    @Override
    public String toString() {
        return "BlockEntity [ship=" + parent + ", xOff=" + xOff + ", yOff=" + yOff + ", zOff=" + zOff + ", blockId="
                + blockID + ", meta=" + metadata + "]";
    }

    // #######################
    // collision related stuff
    // #######################

    // Overridden to collide with all entities except player
    @Override
    public boolean canBeCollidedWith() {
        return true;
    }

    @Override
    public AxisAlignedBB getCollisionBox(Entity var1) { // this does NOT appear to be needed to collide with player.  other entities only?
        return var1.boundingBox; // entity default is null. Note bounding box is created when Entity.setPosition() is called
    }

    @Override
    public AxisAlignedBB getBoundingBox() { //This is the only essential one for player collision. 
        return this.boundingBox; // entity default is null. Note bounding box is created when Entity.setPosition() is called
    }

    public void applyEntityCollision(Entity par1Entity) { //pushes two entities away from each other. I've overridden so the ship doesn't get pushed.
        if (par1Entity != parent && par1Entity.riddenByEntity != this && par1Entity.ridingEntity != this) {
            double var2 = par1Entity.posX - this.posX;
            double var4 = par1Entity.posZ - this.posZ;
            double var6 = MathHelper.abs_max(var2, var4);

            if (var6 >= 0.009999999776482582D) {
                var6 = (double) MathHelper.sqrt_double(var6);
                var2 /= var6;
                var4 /= var6;
                double var8 = 1.0D / var6;

                if (var8 > 1.0D)
                    var8 = 1.0D;

                var2 *= var8;
                var4 *= var8;
                var2 *= 0.05000000074505806D;
                var4 *= 0.05000000074505806D;
                var2 *= (double) (1.0F - this.entityCollisionReduction);
                var4 *= (double) (1.0F - this.entityCollisionReduction);
                //this.addVelocity(-var2, 0.0D, -var4);  //removed     --- untested, no idea if this works
                par1Entity.addVelocity(var2, 0.0D, var4);
            }
        }
    }

    // ################################
    // reading and writing data to disk
    // ################################

    @Override
    protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) {
        // do nothing, leave it to parent
        readControlBlockEntityFromNBT(par1NBTTagCompound);
    }

    @Override
    protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) {
        // don't write kids to disk - have parent kill them all and recreate them on read
        writeControlBlockEntityToNBT(par1NBTTagCompound);
    }

    protected void writeControlBlockEntityToNBT(NBTTagCompound par1NBTTagCompound) {
    } //for ControlBlockEntitys extra fields - mc uses this style so I followed suit...

    protected void readControlBlockEntityFromNBT(NBTTagCompound par1NBTTagCompound) {
    }

    // ##################################
    // IEntityAdditionalSpawnData methods
    // ##################################

    // without this stuff, all variables in class get reset to 0/null by minecraft calling constructor #1 (on client)

    /* 
     * final note re. these two methods (later than all other notes here, above or below)
     * 
     * these should do nothing for children - the control block recreates all children on both client and server anyway...
     * 
     * but their code here is needed for parents (never got round to moving it to ControlBlockEntity)
     *
     */

    @Override
    public void writeSpawnData(ByteArrayDataOutput data) { //child (all) entities get spawned on server only, so need to be able to pass this data to their client copies
        data.writeInt(blockID);
        data.writeInt(metadata);
        data.writeInt(xOff);
        data.writeInt(yOff);
        data.writeInt(zOff);

        writeControlBlockSpawnData(data);
    }

    @Override
    public void readSpawnData(ByteArrayDataInput data) {

        blockID = data.readInt();
        metadata = data.readInt();
        xOff = data.readInt();
        yOff = data.readInt();
        zOff = data.readInt();

        readControlBlockSpawnData(data);
    }

    protected void writeControlBlockSpawnData(ByteArrayDataOutput data) {
    } //for ControlBlockEntitys extra fields

    protected void readControlBlockSpawnData(ByteArrayDataInput data) {
    }

} // end of class