/** * */ package mhfc.net.common.quests.goals; import java.util.Objects; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.RunContext; import cpw.mods.fml.common.gameevent.TickEvent.Phase; import mhfc.net.common.eventhandler.DelayedJob; import mhfc.net.common.eventhandler.MHFCTickHandler; import mhfc.net.common.eventhandler.TickPhase; import mhfc.net.common.quests.api.QuestGoal; import mhfc.net.common.quests.properties.IntProperty; /** * */ public class TimeQuestGoal extends QuestGoal implements DelayedJob { private class Timer implements Operation { private int initialTickTime; private IntProperty tickTime; private boolean isCancelled; public Timer(IntProperty timer, int ticks) { if (ticks < 0) { throw new IllegalArgumentException("ticks must be greater than 0"); } this.initialTickTime = ticks; this.tickTime = Objects.requireNonNull(timer); isCancelled = false; } public void reset() { tickTime.set(initialTickTime); } @Override public void cancel() { isCancelled = true; } @Override public Operation resume(RunContext run) throws WorldEditException { if (isCancelled) { return null; } if (!TimeQuestGoal.this.active) { return this; } tickTime.decr(); if (getRemaining() > 0) { return this; } tickTime.set(0); // Possible underflow from cancelling etc... TimeQuestGoal.this.isFailed = true; TimeQuestGoal.this.notifyOfStatus(isFulfilled(), isFailed()); return null; } public int getRemaining() { return tickTime.get(); } } protected boolean isFailed = false; protected boolean active; protected Timer timer; public TimeQuestGoal(IntProperty timer, int initialTime) { super(null); active = false; this.timer = new Timer(timer, initialTime); MHFCTickHandler.instance.registerOperation(TickPhase.SERVER_POST, this.timer); } @Override public boolean isFulfilled() { return !isFailed; } @Override public boolean isFailed() { return isFailed; } @Override public void reset() { isFailed = false; this.timer.reset(); } @Override public void setActive(boolean newActive) { if (newActive) { active = true; notifyOfStatus(isFulfilled(), isFailed()); } else { active = false; } } @Override public void executeJob(Phase phase) { if (phase != Phase.END) { return; } isFailed = true; notifyOfStatus(isFulfilled(), isFailed()); } @Override public void questGoalFinalize() { setActive(false); timer.cancel(); } }