package mhfc.net.common.ai.manager;
import java.util.Objects;
import com.github.worldsender.mcanm.common.animation.IAnimation;
import mhfc.net.MHFCMain;
import mhfc.net.common.ai.IActionManager;
import mhfc.net.common.ai.IExecutableAction;
import mhfc.net.common.ai.IManagedActions;
import mhfc.net.common.network.PacketPipeline;
import mhfc.net.common.network.message.MessageAIAction;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.ai.EntityAITasks;
public abstract class ActionManagerAdapter<EntType extends EntityLiving & IManagedActions<EntType>, C extends IAIAttackCollection<EntType>>
implements
IActionManager<EntType> {
protected IExecutableAction<? super EntType> activeAttack = null;
protected EntType entity;
protected C attackCollection;
public ActionManagerAdapter(EntType entity, C collection) {
this.entity = Objects.requireNonNull(entity);
this.attackCollection = Objects.requireNonNull(collection);
}
protected void switchAction(IExecutableAction<? super EntType> newAttack) {
swapAttacks(activeAttack, newAttack);
}
protected void swapAttacks(
IExecutableAction<? super EntType> oldAttack,
IExecutableAction<? super EntType> newAttack) {
this.entity.onAttackEnd(oldAttack);
if (oldAttack != null) {
oldAttack.finishAction();
}
this.activeAttack = newAttack;
this.entity.onAttackStart(newAttack);
if (newAttack != null) {
newAttack.beginAction();
}
MHFCMain.logger().debug("Manager for entity {} switched to attack {}", this.entity, this.activeAttack);
if (!this.entity.worldObj.isRemote) {
PacketPipeline.networkPipe.sendToAll(sendUpdate());
}
}
/**
* Return <code>true</code> to continue executing
*/
@Override
public boolean continueExecuting() {
if (this.activeAttack == null) {
IExecutableAction<? super EntType> nextAttack = chooseAttack();
if (nextAttack == null) {
return false;
}
swapAttacks(null, nextAttack);
}
if (this.activeAttack.shouldContinue()) {
return true;
}
return executeNextAttack();
}
/**
* Go to the next attack, cancel the current attack. This may for example be used when staggered.
*/
protected boolean executeNextAttack() {
IExecutableAction<? super EntType> nextAttack = chooseAttack();
swapAttacks(this.activeAttack, nextAttack);
return nextAttack != null;
}
/**
* Updates this AI every 3 ticks.<br>
*
* @see EntityAITasks#tickRate
*/
@Override
public void updateTask() {
activeAttack.updateAction();
}
@Override
public IAnimation getCurrentAnimation() {
return activeAttack == null ? null : activeAttack.getCurrentAnimation();
}
@Override
public int getCurrentFrame() {
return activeAttack == null ? -1 : activeAttack.getCurrentFrame();
}
protected MessageAIAction<EntType> sendUpdate() {
return new MessageAIAction<>(this.entity, this.attackCollection.getIndexOf(activeAttack));
}
@Override
public void switchToAction(IExecutableAction<? super EntType> attack) {
if (attackCollection.getIndexOf(attack) < 0) {
throw new IllegalArgumentException("Only registered actions may be switched to");
}
switchAction(attack);
}
@Override
public void receiveUpdate(MessageAIAction<EntType> message) {
int index = message.getAttackIndex();
IExecutableAction<? super EntType> action = index == -1 ? null : attackCollection.getAction(index);
switchAction(action);
}
}