Package pneumaticCraft.common.ai

Source Code of pneumaticCraft.common.ai.DroneAIManager$EntityAITaskEntry

package pneumaticCraft.common.ai;

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

import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.profiler.Profiler;
import pneumaticCraft.common.entity.living.EntityDrone;
import pneumaticCraft.common.progwidgets.IProgWidget;
import pneumaticCraft.common.progwidgets.ProgWidgetStart;

/**
* This class is derived from Minecraft's {link EntityAITasks} class. As the original class would need quite a few
* accesstransformers or reflection calls to do what I want, I've copied most of that class in here.
*/

public class DroneAIManager{
    /** A list of EntityAITaskEntrys in EntityAITasks. */
    public List<EntityAITaskEntry> taskEntries = new ArrayList<EntityAITaskEntry>();

    /** A list of EntityAITaskEntrys that are currently being executed. */
    private final List<EntityAITaskEntry> executingTaskEntries = new ArrayList<EntityAITaskEntry>();

    /** Instance of Profiler. */
    private final Profiler theProfiler;
    private int tickCount;
    private final int tickRate = 3;
    private static final int MIN_CYCLE_TIME = 40;//lag prevention, prevents drones from cycling very quick through their AI tasks.
    private int cycleTimeCounter;

    private final EntityDrone drone;
    private IProgWidget curActiveWidget;
    private EntityAIBase curWidgetAI;
    private EntityAIBase curWidgetTargetAI;

    public DroneAIManager(Profiler par1Profiler, EntityDrone drone){
        theProfiler = par1Profiler;
        this.drone = drone;
    }

    private void updateWidgetFlow(){
        boolean isExecuting = false;
        cycleTimeCounter++;
        for(EntityAITaskEntry entry : executingTaskEntries) {
            if(curWidgetAI == entry.action) {
                isExecuting = true;
                break;
            }
        }
        if(!isExecuting && curActiveWidget != null && (curWidgetTargetAI == null || !curWidgetTargetAI.shouldExecute())) {
            IProgWidget widget = curActiveWidget.getOutputWidget();
            if(widget != null) {
                setActiveWidget(widget);
            } else {
                if(cycleTimeCounter < MIN_CYCLE_TIME) {
                    if(curWidgetAI != null) removeTask(curWidgetAI);
                    if(curWidgetTargetAI != null) drone.targetTasks.removeTask(curWidgetTargetAI);
                    curWidgetAI = null;
                    curWidgetTargetAI = null;
                } else {
                    gotoFirstWidget();
                    cycleTimeCounter = 0;
                }
            }
        }
    }

    public void gotoFirstWidget(){
        for(IProgWidget widget : drone.progWidgets) {
            if(widget instanceof ProgWidgetStart) {
                setActiveWidget(widget);
                return;
            }
        }
    }

    private void setActiveWidget(IProgWidget widget){
        boolean first = widget instanceof ProgWidgetStart;
        EntityAIBase targetAI = widget.getWidgetTargetAI(drone, widget);
        EntityAIBase ai = widget.getWidgetAI(drone, widget);
        while(targetAI == null && ai == null) {
            widget = widget.getOutputWidget();
            if(widget == null) {
                if(first) {
                    return;
                } else {
                    gotoFirstWidget();
                    return;
                }
            }
            targetAI = widget.getWidgetTargetAI(drone, widget);
            ai = widget.getWidgetAI(drone, widget);
        }

        curActiveWidget = widget;
        drone.setActiveProgram(widget);
        if(curWidgetAI != null) removeTask(curWidgetAI);
        if(curWidgetTargetAI != null) drone.targetTasks.removeTask(curWidgetTargetAI);
        if(ai != null) addTask(2, ai);
        if(targetAI != null) drone.targetTasks.addTask(2, targetAI);
        curWidgetAI = ai;
        curWidgetTargetAI = targetAI;
    }

    public List<EntityAITaskEntry> getRunningTasks(){
        return taskEntries;
    }

    public EntityAIBase getTargetAI(){
        return curWidgetTargetAI;
    }

    /**
     *
     *
     *
     *START EntityAITasks code
     *
     *
     *
     */

    public void addTask(int par1, EntityAIBase par2EntityAIBase){
        taskEntries.add(new EntityAITaskEntry(par1, par2EntityAIBase));
    }

    /**
     * removes the indicated task from the entity's AI tasks.
     */
    public void removeTask(EntityAIBase par1EntityAIBase){
        Iterator iterator = taskEntries.iterator();

        while(iterator.hasNext()) {
            EntityAITaskEntry entityaitaskentry = (EntityAITaskEntry)iterator.next();
            EntityAIBase entityaibase1 = entityaitaskentry.action;

            if(entityaibase1 == par1EntityAIBase) {
                if(executingTaskEntries.contains(entityaitaskentry)) {
                    entityaibase1.resetTask();
                    executingTaskEntries.remove(entityaitaskentry);
                }

                iterator.remove();
            }
        }
    }

    public void onUpdateTasks(){
        if(!drone.chargeAI.isExecuting && drone.gotoOwnerAI == null) {
            ArrayList<EntityAITaskEntry> arraylist = new ArrayList<EntityAITaskEntry>();
            Iterator<EntityAITaskEntry> iterator;
            EntityAITaskEntry entityaitaskentry;

            if(tickCount++ % tickRate == 0) {
                iterator = taskEntries.iterator();

                while(iterator.hasNext()) {
                    entityaitaskentry = iterator.next();
                    boolean flag = executingTaskEntries.contains(entityaitaskentry);

                    if(flag) {
                        if(canUse(entityaitaskentry) && canContinue(entityaitaskentry)) {
                            continue;
                        }

                        entityaitaskentry.action.resetTask();
                        executingTaskEntries.remove(entityaitaskentry);
                    }

                    if(canUse(entityaitaskentry) && entityaitaskentry.action.shouldExecute()) {
                        arraylist.add(entityaitaskentry);
                        executingTaskEntries.add(entityaitaskentry);
                    }
                }
                updateWidgetFlow();
            } else {
                iterator = executingTaskEntries.iterator();

                while(iterator.hasNext()) {
                    entityaitaskentry = iterator.next();

                    if(!entityaitaskentry.action.continueExecuting()) {
                        entityaitaskentry.action.resetTask();
                        iterator.remove();
                    }
                }
            }

            theProfiler.startSection("goalStart");
            iterator = arraylist.iterator();

            while(iterator.hasNext()) {
                entityaitaskentry = iterator.next();
                theProfiler.startSection(entityaitaskentry.action.getClass().getSimpleName());
                entityaitaskentry.action.startExecuting();
                theProfiler.endSection();
            }

            theProfiler.endSection();
            theProfiler.startSection("goalTick");
            iterator = executingTaskEntries.iterator();

            while(iterator.hasNext()) {
                entityaitaskentry = iterator.next();
                entityaitaskentry.action.updateTask();
            }

            theProfiler.endSection();
        } else {//drone charging ai is running
            for(EntityAITaskEntry ai : executingTaskEntries) {
                ai.action.resetTask();
            }
            executingTaskEntries.clear();
            drone.setDugBlock(0, 0, 0);
        }
    }

    /**
     * Determine if a specific AI Task should continue being executed.
     */
    private boolean canContinue(EntityAITaskEntry par1EntityAITaskEntry){
        theProfiler.startSection("canContinue");
        boolean flag = par1EntityAITaskEntry.action.continueExecuting();
        theProfiler.endSection();
        return flag;
    }

    /**
     * Determine if a specific AI Task can be executed, which means that all running higher (= lower int value) priority
     * tasks are compatible with it or all lower priority tasks can be interrupted.
     */
    private boolean canUse(EntityAITaskEntry par1EntityAITaskEntry){
        theProfiler.startSection("canUse");
        Iterator iterator = taskEntries.iterator();

        while(iterator.hasNext()) {
            EntityAITaskEntry entityaitaskentry1 = (EntityAITaskEntry)iterator.next();

            if(entityaitaskentry1 != par1EntityAITaskEntry) {
                if(par1EntityAITaskEntry.priority >= entityaitaskentry1.priority) {
                    if(executingTaskEntries.contains(entityaitaskentry1) && !areTasksCompatible(par1EntityAITaskEntry, entityaitaskentry1)) {
                        theProfiler.endSection();
                        return false;
                    }
                } else if(executingTaskEntries.contains(entityaitaskentry1) && !entityaitaskentry1.action.isInterruptible()) {
                    theProfiler.endSection();
                    return false;
                }
            }
        }

        theProfiler.endSection();
        return true;
    }

    /**
     * Returns whether two EntityAITaskEntries can be executed concurrently
     */
    private boolean areTasksCompatible(EntityAITaskEntry par1EntityAITaskEntry, EntityAITaskEntry par2EntityAITaskEntry){
        return (par1EntityAITaskEntry.action.getMutexBits() & par2EntityAITaskEntry.action.getMutexBits()) == 0;
    }

    public class EntityAITaskEntry{
        /**
         * The EntityAIBase object.
         */
        public EntityAIBase action;
        /**
         * Priority of the EntityAIBase
         */
        public int priority;

        public EntityAITaskEntry(int par2, EntityAIBase par3EntityAIBase){
            priority = par2;
            action = par3EntityAIBase;
        }
    }
}
TOP

Related Classes of pneumaticCraft.common.ai.DroneAIManager$EntityAITaskEntry

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.