Package pneumaticCraft.common.ai

Source Code of pneumaticCraft.common.ai.DroneAIBlockInteraction

package pneumaticCraft.common.ai;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.world.ChunkPosition;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.common.util.ForgeDirection;
import pneumaticCraft.common.entity.living.EntityDrone;
import pneumaticCraft.common.progwidgets.IBlockOrdered;
import pneumaticCraft.common.progwidgets.IBlockOrdered.EnumOrder;
import pneumaticCraft.common.progwidgets.ProgWidgetAreaItemBase;
import pneumaticCraft.common.progwidgets.ProgWidgetDigAndPlace;
import pneumaticCraft.common.progwidgets.ProgWidgetPlace;
import pneumaticCraft.common.util.PneumaticCraftUtils;

public abstract class DroneAIBlockInteraction extends EntityAIBase{
    protected final EntityDrone drone;
    private final double speed;
    protected final ProgWidgetAreaItemBase widget;
    private final EnumOrder order;
    private ChunkPosition curPos;
    private final Set<ChunkPosition> area;
    private final ChunkPositionSorter sorter;
    protected final IBlockAccess worldCache;
    private final List<ChunkPosition> blacklist = new ArrayList<ChunkPosition>();//a list of position which weren't allowed to be digged in the past.
    private int curY;
    private int minY, maxY;

    /**
     *
     * @param drone
     * @param speed
     * @param widget needs to implement IBlockOrdered
     */
    public DroneAIBlockInteraction(EntityDrone drone, double speed, ProgWidgetAreaItemBase widget){
        this.drone = drone;
        this.speed = speed;
        setMutexBits(63);//binary 111111, so it won't run along with other AI tasks.
        this.widget = widget;
        order = ((IBlockOrdered)widget).getOrder();
        area = widget.getArea();
        worldCache = ProgWidgetAreaItemBase.getCache(area, drone.worldObj);
        sorter = new ChunkPositionSorter(drone);
        if(area.size() > 0) {
            Iterator<ChunkPosition> iterator = area.iterator();
            ChunkPosition pos = iterator.next();
            minY = maxY = pos.chunkPosY;
            while(iterator.hasNext()) {
                pos = iterator.next();
                minY = Math.min(minY, pos.chunkPosY);
                maxY = Math.max(maxY, pos.chunkPosY);
            }
            if(order == EnumOrder.HIGH_TO_LOW) {
                curY = maxY;
            } else if(order == EnumOrder.LOW_TO_HIGH) {
                curY = minY;
            }
        }
    }

    /**
     * Returns whether the EntityAIBase should begin execution.
     */
    @Override
    public boolean shouldExecute(){
        ChunkPosition bestPos = null;
        int startY = curY;
        boolean firstRun = true;
        while(bestPos == null && (curY != startY && order != ProgWidgetDigAndPlace.EnumOrder.CLOSEST || firstRun)) {
            firstRun = false;
            for(ChunkPosition pos : area) {
                if(isYValid(pos.chunkPosY) && !blacklist.contains(pos)) {
                    if(bestPos == null || sorter.compare(bestPos, pos) > 0) {
                        if(isValidPosition(pos)) {
                            bestPos = pos;
                        }
                    }
                }
            }
            if(bestPos == null) updateY();
        }
        if(bestPos != null) {
            for(ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
                if(drone.getNavigator().tryMoveToXYZ(bestPos.chunkPosX + dir.offsetX, bestPos.chunkPosY + dir.offsetY + 0.5, bestPos.chunkPosZ + dir.offsetZ, speed)) {
                    curPos = bestPos;
                    return true;
                }
            }
            if(((EntityPathNavigateDrone)drone.getNavigator()).isGoingToTeleport()) {
                curPos = bestPos;
                return true;
            }
        }
        blacklist.clear();//clear the list for next time (maybe the blocks/rights have changed by the time there will be dug again).
        return false;
    }

    private void updateY(){
        if(order == ProgWidgetPlace.EnumOrder.LOW_TO_HIGH) {
            if(++curY > maxY) curY = minY;
        } else if(order == ProgWidgetPlace.EnumOrder.HIGH_TO_LOW) {
            if(--curY < minY) curY = maxY;
        }
    }

    private boolean isYValid(int y){
        return order == ProgWidgetPlace.EnumOrder.CLOSEST || y == curY;
    }

    protected abstract boolean isValidPosition(ChunkPosition pos);

    protected abstract boolean doBlockInteraction(ChunkPosition pos, double distToBlock);

    /**
     * Returns whether an in-progress EntityAIBase should continue executing
     */
    @Override
    public boolean continueExecuting(){
        double dist = curPos != null ? PneumaticCraftUtils.distBetween(curPos.chunkPosX + 0.5, curPos.chunkPosY + 0.5, curPos.chunkPosZ + 0.5, drone.posX, drone.posY, drone.posZ) : 0;
        if(curPos != null && dist < 2) {
            return doBlockInteraction(curPos, dist);
        }
        return !drone.getNavigator().noPath();
    }

    protected void addToBlacklist(ChunkPosition coord){
        blacklist.add(coord);
        drone.sendWireframeToClient(coord.chunkPosX, coord.chunkPosY, coord.chunkPosZ);
    }

}
TOP

Related Classes of pneumaticCraft.common.ai.DroneAIBlockInteraction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.