I’ve adapted the following for use in my roguelike and am liking it quite a bit: http://roguebasin.roguelikedevelopment.org/index.php/A_simple_turn_scheduling_system_--_Python_implementation
It essentially keeps a list of which events occur on each tick. When advanceTime() is called (For example, when the player moves, he might call advanceTime(5)), it cycles through each tick and calls whatever AI or Events need updating until it reaches the new tick. Unfortunately I need to leave for class now, but this should hopefully help point you in the right direction when creating your system.
I’m sure that there’s improvements to be made here, as I’ve only been learning Java for a couple of months now, so just remember that this is probably not as well written as it could be.
package net.krazyweb.dungeoncrawler;
import java.util.ArrayList;
import java.util.HashMap;
import net.krazyweb.dungeoncrawler.entity.LivingEntity;
import net.krazyweb.dungeoncrawler.entity.livingentities.Player;
import net.krazyweb.dungeoncrawler.event.Event;
public class Ticker {
private long ticks;
private HashMap<Long, ArrayList<LivingEntity>> schedule;
private HashMap<Long, ArrayList<Event>> eventSchedule;
public Ticker(long ticks) {
this.ticks = ticks;
this.schedule = new HashMap<Long, ArrayList<LivingEntity>>();
this.eventSchedule = new HashMap<Long, ArrayList<Event>>();
}
public void advanceTime(int time) {
for (int t = 0; t < time; t++) {
ticks += 1;
if (schedule.containsKey(ticks)) {
for (int e = 0; e < schedule.get(ticks).size(); e++) {
LivingEntity entity = schedule.get(ticks).get(e);
if (!(entity instanceof Player))
entity.ai.action(entity);
}
}
if (eventSchedule.containsKey(ticks)) {
for (int e = 0; e < eventSchedule.get(ticks).size(); e++) {
Event event = eventSchedule.get(ticks).get(e);
event.action();
}
}
}
}
public long scheduleTurn(int interval, LivingEntity entity) {
if (!schedule.containsKey(ticks + interval)) {
schedule.put((ticks + interval), new ArrayList<LivingEntity>());
schedule.get(ticks + interval).add(entity);
} else {
schedule.get(ticks + interval).add(entity);
}
return ticks + interval;
}
public long scheduleEvent(int interval, Event event) {
if (!eventSchedule.containsKey(ticks + interval)) {
eventSchedule.put((ticks + interval), new ArrayList<Event>());
eventSchedule.get(ticks + interval).add(event);
} else {
eventSchedule.get(ticks + interval).add(event);
}
return ticks + interval;
}
public void unScheduleTurn(long nextMoveTick, LivingEntity entity) {
if (schedule.containsKey(nextMoveTick)) {
schedule.get(nextMoveTick).remove(entity);
}
}
public void unScheduleEvent(long nextMoveTick, Event event) {
if (eventSchedule.containsKey(nextMoveTick)) {
eventSchedule.get(nextMoveTick).remove(event);
}
}
public void scheduleTurnLoad(long tickToAdd, LivingEntity entity) {
if (!schedule.containsKey(tickToAdd)) {
schedule.put((tickToAdd), new ArrayList<LivingEntity>());
schedule.get(tickToAdd).add(entity);
} else {
schedule.get(tickToAdd).add(entity);
}
}
public long getTicks() {
return ticks;
}
}