package pneumaticCraft.common.ai;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Vec3;
import net.minecraft.world.ChunkPosition;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import pneumaticCraft.common.entity.living.EntityDrone;
import pneumaticCraft.common.progwidgets.ISidedWidget;
import pneumaticCraft.common.progwidgets.ProgWidgetAreaItemBase;
import pneumaticCraft.common.progwidgets.ProgWidgetPlace;
import pneumaticCraft.lib.PneumaticValues;
public class DroneAIPlace extends DroneAIBlockInteraction{
/**
* @param drone
* @param speed
* @param widget needs to implement IBlockOrdered and IDirectionalWidget.
*/
public DroneAIPlace(IDroneBase drone, ProgWidgetAreaItemBase widget){
super(drone, widget);
}
@Override
protected boolean respectClaims(){
return true;
}
@Override
protected boolean isValidPosition(ChunkPosition pos){
if(drone.getWorld().isAirBlock(pos.chunkPosX, pos.chunkPosY, pos.chunkPosZ)) {
boolean failedOnPlacement = false;
for(int i = 0; i < drone.getInventory().getSizeInventory(); i++) {
ItemStack droneStack = drone.getInventory().getStackInSlot(i);
if(droneStack != null && droneStack.getItem() instanceof ItemBlock) {
if(widget.isItemValidForFilters(droneStack)) {
if(((ItemBlock)droneStack.getItem()).field_150939_a.canPlaceBlockOnSide(drone.getWorld(), pos.chunkPosX, pos.chunkPosY, pos.chunkPosZ, ProgWidgetPlace.getDirForSides(((ISidedWidget)widget).getSides()).ordinal())) {
if(drone instanceof EntityDrone) {
EntityDrone entity = (EntityDrone)drone;
entity.setPosition(entity.posX, entity.posY + 200, entity.posZ);//Teleport the drone to make sure it isn't in the way of placing a block.
}
if(drone.getWorld().canPlaceEntityOnSide(((ItemBlock)droneStack.getItem()).field_150939_a, pos.chunkPosX, pos.chunkPosY, pos.chunkPosZ, false, 0, null, droneStack)) {
if(drone instanceof EntityDrone) {
EntityDrone entity = (EntityDrone)drone;
entity.setPosition(entity.posX, entity.posY - 200, entity.posZ);
}
return true;
} else {
if(drone instanceof EntityDrone) {
EntityDrone entity = (EntityDrone)drone;
entity.setPosition(entity.posX, entity.posY - 200, entity.posZ);
}
drone.addDebugEntry("gui.progWidget.place.debug.entityInWay", pos);
failedOnPlacement = true;
}
} else {
failedOnPlacement = true;
drone.addDebugEntry("gui.progWidget.place.debug.cantPlaceBlock", pos);
}
}
}
}
if(!failedOnPlacement) abort();
}
return false;
}
@Override
protected boolean doBlockInteraction(ChunkPosition pos, double distToBlock){
if(drone.getPathNavigator().hasNoPath()) {
ForgeDirection side = ProgWidgetPlace.getDirForSides(((ISidedWidget)widget).getSides());
for(int i = 0; i < drone.getInventory().getSizeInventory(); i++) {
ItemStack droneStack = drone.getInventory().getStackInSlot(i);
if(droneStack != null && droneStack.getItem() instanceof ItemBlock && ((ItemBlock)droneStack.getItem()).field_150939_a.canPlaceBlockOnSide(drone.getWorld(), pos.chunkPosX, pos.chunkPosY, pos.chunkPosZ, ProgWidgetPlace.getDirForSides(((ISidedWidget)widget).getSides()).ordinal())) {
if(widget.isItemValidForFilters(droneStack)) {
if(drone instanceof EntityDrone) {
EntityDrone entity = (EntityDrone)drone;
entity.setPosition(entity.posX, entity.posY + 200, entity.posZ);//Teleport the drone to make sure it isn't in the way of placing a block.
}
if(drone.getWorld().canPlaceEntityOnSide(((ItemBlock)droneStack.getItem()).field_150939_a, pos.chunkPosX, pos.chunkPosY, pos.chunkPosZ, false, 0, null, droneStack)) {
Block block = Block.getBlockFromItem(droneStack.getItem());
int meta = droneStack.getItem().getMetadata(droneStack.getItemDamage());
int newMeta = block.onBlockPlaced(drone.getWorld(), pos.chunkPosX, pos.chunkPosY, pos.chunkPosZ, side.ordinal(), side.offsetX, side.offsetY, side.offsetZ, meta);
setFakePlayerAccordingToDir();
if(placeBlockAt(droneStack, drone.getFakePlayer(), drone.getWorld(), pos.chunkPosX, pos.chunkPosY, pos.chunkPosZ, side.ordinal(), 0, 0, 0, newMeta)) {
drone.addAir(null, -PneumaticValues.DRONE_USAGE_PLACE);
drone.getWorld().playSoundEffect(pos.chunkPosX + 0.5F, pos.chunkPosY + 0.5F, pos.chunkPosZ + 0.5F, block.stepSound.func_150496_b(), (block.stepSound.getVolume() + 1.0F) / 2.0F, block.stepSound.getPitch() * 0.8F);
if(--droneStack.stackSize <= 0) {
drone.getInventory().setInventorySlotContents(i, null);
}
}
if(drone instanceof EntityDrone) {
EntityDrone entity = (EntityDrone)drone;
entity.setPosition(entity.posX, entity.posY - 200, entity.posZ);
}
return false;
}
if(drone instanceof EntityDrone) {
EntityDrone entity = (EntityDrone)drone;
entity.setPosition(entity.posX, entity.posY - 200, entity.posZ);
}
}
}
}
return false;
} else {
return true;
}
}
private void setFakePlayerAccordingToDir(){
EntityPlayer fakePlayer = drone.getFakePlayer();
Vec3 pos = drone.getPosition();
fakePlayer.posX = pos.xCoord;
fakePlayer.posZ = pos.zCoord;
switch(ProgWidgetPlace.getDirForSides(((ISidedWidget)widget).getSides())){
case UP:
fakePlayer.rotationPitch = -90;
fakePlayer.posY = pos.yCoord - 10;//do this for PistonBase.determineDirection()
return;
case DOWN:
fakePlayer.rotationPitch = 90;
fakePlayer.posY = pos.yCoord + 10;//do this for PistonBase.determineDirection()
return;
case NORTH:
fakePlayer.rotationYaw = 180;
fakePlayer.posY = pos.yCoord;//do this for PistonBase.determineDirection()
break;
case EAST:
fakePlayer.rotationYaw = 270;
fakePlayer.posY = pos.yCoord;//do this for PistonBase.determineDirection()
break;
case SOUTH:
fakePlayer.rotationYaw = 0;
fakePlayer.posY = pos.yCoord;//do this for PistonBase.determineDirection()
break;
case WEST:
fakePlayer.rotationYaw = 90;
fakePlayer.posY = pos.yCoord;//do this for PistonBase.determineDirection()
break;
}
}
/**
* Called to actually place the block, after the location is determined
* and all permission checks have been made.
*
* @param stack The item stack that was used to place the block. This can be changed inside the method.
* @param player The player who is placing the block. Can be null if the block is not being placed by a player.
* @param side The side the player (or machine) right-clicked on.
*/
private boolean placeBlockAt(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ, int metadata){
Block block = Block.getBlockFromItem(stack.getItem());
if(!world.setBlock(x, y, z, block, metadata, 3)) {
return false;
}
block.onBlockPlacedBy(world, x, y, z, player, stack);
block.onPostBlockPlaced(world, x, y, z, metadata);
return true;
}
}