001package net.minecraft.entity.ai; 002 003import java.util.ArrayList; 004import java.util.Iterator; 005import java.util.List; 006import net.minecraft.profiler.Profiler; 007 008public class EntityAITasks 009{ 010 /** A list of EntityAITaskEntrys in EntityAITasks. */ 011 public List taskEntries = new ArrayList(); 012 013 /** A list of EntityAITaskEntrys that are currently being executed. */ 014 private List executingTaskEntries = new ArrayList(); 015 016 /** Instance of Profiler. */ 017 private final Profiler theProfiler; 018 private int field_75778_d = 0; 019 private int field_75779_e = 3; 020 021 public EntityAITasks(Profiler par1Profiler) 022 { 023 this.theProfiler = par1Profiler; 024 } 025 026 public void addTask(int par1, EntityAIBase par2EntityAIBase) 027 { 028 this.taskEntries.add(new EntityAITaskEntry(this, par1, par2EntityAIBase)); 029 } 030 031 /** 032 * removes the indicated task from the entity's AI tasks. 033 */ 034 public void removeTask(EntityAIBase par1EntityAIBase) 035 { 036 Iterator iterator = this.taskEntries.iterator(); 037 038 while (iterator.hasNext()) 039 { 040 EntityAITaskEntry entityaitaskentry = (EntityAITaskEntry)iterator.next(); 041 EntityAIBase entityaibase1 = entityaitaskentry.action; 042 043 if (entityaibase1 == par1EntityAIBase) 044 { 045 if (this.executingTaskEntries.contains(entityaitaskentry)) 046 { 047 entityaibase1.resetTask(); 048 this.executingTaskEntries.remove(entityaitaskentry); 049 } 050 051 iterator.remove(); 052 } 053 } 054 } 055 056 public void onUpdateTasks() 057 { 058 ArrayList arraylist = new ArrayList(); 059 Iterator iterator; 060 EntityAITaskEntry entityaitaskentry; 061 062 if (this.field_75778_d++ % this.field_75779_e == 0) 063 { 064 iterator = this.taskEntries.iterator(); 065 066 while (iterator.hasNext()) 067 { 068 entityaitaskentry = (EntityAITaskEntry)iterator.next(); 069 boolean flag = this.executingTaskEntries.contains(entityaitaskentry); 070 071 if (flag) 072 { 073 if (this.canUse(entityaitaskentry) && this.canContinue(entityaitaskentry)) 074 { 075 continue; 076 } 077 078 entityaitaskentry.action.resetTask(); 079 this.executingTaskEntries.remove(entityaitaskentry); 080 } 081 082 if (this.canUse(entityaitaskentry) && entityaitaskentry.action.shouldExecute()) 083 { 084 arraylist.add(entityaitaskentry); 085 this.executingTaskEntries.add(entityaitaskentry); 086 } 087 } 088 } 089 else 090 { 091 iterator = this.executingTaskEntries.iterator(); 092 093 while (iterator.hasNext()) 094 { 095 entityaitaskentry = (EntityAITaskEntry)iterator.next(); 096 097 if (!entityaitaskentry.action.continueExecuting()) 098 { 099 entityaitaskentry.action.resetTask(); 100 iterator.remove(); 101 } 102 } 103 } 104 105 this.theProfiler.startSection("goalStart"); 106 iterator = arraylist.iterator(); 107 108 while (iterator.hasNext()) 109 { 110 entityaitaskentry = (EntityAITaskEntry)iterator.next(); 111 this.theProfiler.startSection(entityaitaskentry.action.getClass().getSimpleName()); 112 entityaitaskentry.action.startExecuting(); 113 this.theProfiler.endSection(); 114 } 115 116 this.theProfiler.endSection(); 117 this.theProfiler.startSection("goalTick"); 118 iterator = this.executingTaskEntries.iterator(); 119 120 while (iterator.hasNext()) 121 { 122 entityaitaskentry = (EntityAITaskEntry)iterator.next(); 123 entityaitaskentry.action.updateTask(); 124 } 125 126 this.theProfiler.endSection(); 127 } 128 129 /** 130 * Determine if a specific AI Task should continue being executed. 131 */ 132 private boolean canContinue(EntityAITaskEntry par1EntityAITaskEntry) 133 { 134 this.theProfiler.startSection("canContinue"); 135 boolean flag = par1EntityAITaskEntry.action.continueExecuting(); 136 this.theProfiler.endSection(); 137 return flag; 138 } 139 140 /** 141 * Determine if a specific AI Task can be executed, which means that all running higher (= lower int value) priority 142 * tasks are compatible with it or all lower priority tasks can be interrupted. 143 */ 144 private boolean canUse(EntityAITaskEntry par1EntityAITaskEntry) 145 { 146 this.theProfiler.startSection("canUse"); 147 Iterator iterator = this.taskEntries.iterator(); 148 149 while (iterator.hasNext()) 150 { 151 EntityAITaskEntry entityaitaskentry1 = (EntityAITaskEntry)iterator.next(); 152 153 if (entityaitaskentry1 != par1EntityAITaskEntry) 154 { 155 if (par1EntityAITaskEntry.priority >= entityaitaskentry1.priority) 156 { 157 if (this.executingTaskEntries.contains(entityaitaskentry1) && !this.areTasksCompatible(par1EntityAITaskEntry, entityaitaskentry1)) 158 { 159 this.theProfiler.endSection(); 160 return false; 161 } 162 } 163 else if (this.executingTaskEntries.contains(entityaitaskentry1) && !entityaitaskentry1.action.isInterruptible()) 164 { 165 this.theProfiler.endSection(); 166 return false; 167 } 168 } 169 } 170 171 this.theProfiler.endSection(); 172 return true; 173 } 174 175 /** 176 * Returns whether two EntityAITaskEntries can be executed concurrently 177 */ 178 private boolean areTasksCompatible(EntityAITaskEntry par1EntityAITaskEntry, EntityAITaskEntry par2EntityAITaskEntry) 179 { 180 return (par1EntityAITaskEntry.action.getMutexBits() & par2EntityAITaskEntry.action.getMutexBits()) == 0; 181 } 182}