feat: Mobs following player logic
This commit is contained in:
@@ -6,6 +6,6 @@ import lombok.Getter;
|
||||
@Getter
|
||||
@Config
|
||||
public class Debugging {
|
||||
private final boolean renderColliders = false;
|
||||
private final boolean renderPlayerCollider = false;
|
||||
private final boolean renderColliders = true;
|
||||
private final boolean renderPlayerCollider = true;
|
||||
}
|
||||
|
||||
@@ -28,31 +28,28 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
@EventHandler(FullRoomDraw.class)
|
||||
public class FullRoomDrawHandler extends AbstractEventHandler<FullRoomDraw> {
|
||||
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
||||
@InjectState
|
||||
private GameState gameState;
|
||||
|
||||
@InjectState
|
||||
private ScreenBuffer screenBuffer;
|
||||
|
||||
@InjectDependency
|
||||
private ResourceManager resourceManager;
|
||||
|
||||
@InjectState
|
||||
private TerminalState terminalState;
|
||||
|
||||
@InjectDependency
|
||||
private EventManager eventManager;
|
||||
|
||||
@InjectState
|
||||
private RenderState renderState;
|
||||
|
||||
@InjectConfig
|
||||
private Debugging debugging;
|
||||
|
||||
@InjectDependency
|
||||
private RoomTaskScheduler roomTaskScheduler;
|
||||
|
||||
@@ -90,7 +87,9 @@ public class FullRoomDrawHandler extends AbstractEventHandler<FullRoomDraw> {
|
||||
if (renderState.isFirstRender() || event.isFullRerender()) {
|
||||
eventManager.emitEvent(RerenderScreen.full(terminalSize));
|
||||
renderState.setFirstRender(false);
|
||||
roomTaskScheduler.setupNewSchedulers(currentRoom);
|
||||
scheduler.schedule(() -> {
|
||||
roomTaskScheduler.setupNewSchedulers(currentRoom);
|
||||
}, 200, TimeUnit.MILLISECONDS);
|
||||
} else {
|
||||
eventManager.emitEvent(new RerenderScreen(partsToRerender.toArray(RerenderScreen.ScreenPart[]::new)));
|
||||
}
|
||||
|
||||
@@ -14,22 +14,25 @@ import cz.jzitnik.utils.events.EventManager;
|
||||
import cz.jzitnik.utils.roomtasks.RoomTaskScheduler;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
@EventHandler(RoomChangeEvent.class)
|
||||
public class RoomChangeEventHandler extends AbstractEventHandler<RoomChangeEvent> {
|
||||
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
||||
@InjectState
|
||||
private GameState gameState;
|
||||
@InjectDependency
|
||||
private EventManager eventManager;
|
||||
@InjectDependency
|
||||
private RoomTaskScheduler roomTaskScheduler;
|
||||
|
||||
public RoomChangeEventHandler(DependencyManager dm) {
|
||||
super(dm);
|
||||
}
|
||||
|
||||
@InjectState
|
||||
private GameState gameState;
|
||||
|
||||
@InjectDependency
|
||||
private EventManager eventManager;
|
||||
|
||||
@InjectDependency
|
||||
private RoomTaskScheduler roomTaskScheduler;
|
||||
|
||||
@Override
|
||||
public void handle(RoomChangeEvent event) {
|
||||
RoomCords playerCords = gameState.getPlayer().getPlayerCords();
|
||||
@@ -53,7 +56,9 @@ public class RoomChangeEventHandler extends AbstractEventHandler<RoomChangeEvent
|
||||
}
|
||||
|
||||
gameState.setCurrentRoom(newRoom);
|
||||
roomTaskScheduler.setupNewSchedulers(newRoom);
|
||||
scheduler.schedule(() -> {
|
||||
roomTaskScheduler.setupNewSchedulers(newRoom);
|
||||
}, 200, TimeUnit.MILLISECONDS);
|
||||
eventManager.emitEvent(new FullRoomDraw());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import cz.jzitnik.utils.DependencyManager;
|
||||
import cz.jzitnik.utils.RerenderUtils;
|
||||
import cz.jzitnik.utils.events.EventManager;
|
||||
import cz.jzitnik.utils.roomtasks.RoomTask;
|
||||
import cz.jzitnik.utils.roomtasks.RoomTaskScheduler;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@@ -49,6 +50,8 @@ public abstract class HittableMob extends Mob {
|
||||
private ScreenBuffer screenBuffer;
|
||||
@InjectConfig
|
||||
private Debugging debugging;
|
||||
@InjectDependency
|
||||
private RoomTaskScheduler roomTaskScheduler;
|
||||
|
||||
public HittableMob(BufferedImage texture, RoomTask task, RoomCords cords, int initialHealth) {
|
||||
super(texture, task, cords);
|
||||
@@ -66,6 +69,9 @@ public abstract class HittableMob extends Mob {
|
||||
|
||||
if (health <= 0) {
|
||||
onKilled();
|
||||
if (task != null) {
|
||||
roomTaskScheduler.stopTask(task);
|
||||
}
|
||||
gameState.getCurrentRoom().getMobs().remove(this);
|
||||
rerender();
|
||||
return;
|
||||
|
||||
@@ -5,18 +5,24 @@ import cz.jzitnik.game.utils.RoomCords;
|
||||
import cz.jzitnik.game.utils.Selectable;
|
||||
import cz.jzitnik.utils.roomtasks.RoomTask;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public abstract class Mob implements Renderable, Selectable {
|
||||
protected final BufferedImage texture;
|
||||
private final RoomTask task;
|
||||
|
||||
@Setter
|
||||
protected RoomTask task;
|
||||
protected final RoomCords cords;
|
||||
|
||||
public Mob(BufferedImage texture, RoomTask task, RoomCords cords) {
|
||||
this.texture = texture;
|
||||
this.task = task;
|
||||
this.cords = cords;
|
||||
}
|
||||
|
||||
@Setter
|
||||
private boolean selected = false;
|
||||
}
|
||||
|
||||
133
src/main/java/cz/jzitnik/game/mobs/tasks/AStarAlg.java
Normal file
133
src/main/java/cz/jzitnik/game/mobs/tasks/AStarAlg.java
Normal file
@@ -0,0 +1,133 @@
|
||||
package cz.jzitnik.game.mobs.tasks;
|
||||
|
||||
import cz.jzitnik.game.GameRoomPart;
|
||||
import cz.jzitnik.game.utils.RoomCords;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class AStarAlg {
|
||||
|
||||
// Boundaries matching your Player switch statement
|
||||
// Player: if (x <= 30) return -> means 30 is the edge, valid area is > 30?
|
||||
// User Update: "he can be on 30". So valid range is [30, 155]
|
||||
private static final int MIN_X = 30;
|
||||
private static final int MAX_X = 155;
|
||||
private static final int MIN_Y = 10;
|
||||
private static final int MAX_Y = 113;
|
||||
|
||||
public static List<RoomCords> findPath(RoomCords start, RoomCords target, List<GameRoomPart> colliders) {
|
||||
PriorityQueue<Node> openSet = new PriorityQueue<>(Comparator.comparingInt(n -> n.f));
|
||||
Set<String> closedSet = new HashSet<>();
|
||||
|
||||
// We use Chebyshev distance for the heuristic (best for 8-way movement)
|
||||
Node startNode = new Node(start.getX(), start.getY(), 0, getHeuristic(start, target), null);
|
||||
openSet.add(startNode);
|
||||
|
||||
while (!openSet.isEmpty()) {
|
||||
Node current = openSet.poll();
|
||||
|
||||
// Reached target?
|
||||
if (current.x == target.getX() && current.y == target.getY()) {
|
||||
return reconstructPath(current);
|
||||
}
|
||||
|
||||
String key = current.x + "," + current.y;
|
||||
if (closedSet.contains(key)) continue;
|
||||
closedSet.add(key);
|
||||
|
||||
for (Node neighbor : getNeighbors(current, target)) {
|
||||
String neighborKey = neighbor.x + "," + neighbor.y;
|
||||
if (closedSet.contains(neighborKey)) continue;
|
||||
|
||||
// Check collisions and boundaries
|
||||
if (!isValidPosition(neighbor.x, neighbor.y, colliders)) {
|
||||
// EDGE CASE FIX:
|
||||
// If the Player (target) is standing exactly on a wall/edge that the Mob considers invalid,
|
||||
// A* will usually fail.
|
||||
// We add a check: if this neighbor IS the target, we allow it.
|
||||
// This lets the mob walk right up to the player's face even if they are hugging the wall.
|
||||
if (neighbor.x != target.getX() || neighbor.y != target.getY()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
int newG = current.g + 1;
|
||||
neighbor.g = newG;
|
||||
neighbor.f = newG + neighbor.h;
|
||||
neighbor.parent = current;
|
||||
|
||||
openSet.add(neighbor);
|
||||
}
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
private static List<Node> getNeighbors(Node current, RoomCords target) {
|
||||
List<Node> neighbors = new ArrayList<>();
|
||||
|
||||
// Added Diagonal Directions
|
||||
int[][] directions = {
|
||||
{0, 1}, {0, -1}, {1, 0}, {-1, 0}, // Up, Down, Right, Left
|
||||
{1, 1}, {1, -1}, {-1, 1}, {-1, -1} // Diagonals
|
||||
};
|
||||
|
||||
for (int[] dir : directions) {
|
||||
int newX = current.x + dir[0];
|
||||
int newY = current.y + dir[1];
|
||||
int h = getHeuristic(new RoomCords(newX, newY), target);
|
||||
neighbors.add(new Node(newX, newY, 0, h, null));
|
||||
}
|
||||
return neighbors;
|
||||
}
|
||||
|
||||
private static boolean isValidPosition(int x, int y, List<GameRoomPart> colliders) {
|
||||
// Updated checks to be inclusive so 30 is valid.
|
||||
// Valid X: 30 to 155
|
||||
if (x < MIN_X || x > MAX_X) return false;
|
||||
|
||||
// Valid Y: 10 to 110
|
||||
if (y < MIN_Y || y > MAX_Y) return false;
|
||||
|
||||
// Check Colliders
|
||||
RoomCords temp = new RoomCords(x, y);
|
||||
for (GameRoomPart part : colliders) {
|
||||
if (part.isWithin(temp)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static List<RoomCords> reconstructPath(Node endNode) {
|
||||
List<RoomCords> path = new ArrayList<>();
|
||||
Node current = endNode;
|
||||
while (current != null) {
|
||||
path.add(new RoomCords(current.x, current.y));
|
||||
current = current.parent;
|
||||
}
|
||||
Collections.reverse(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
// Changed to Chebyshev Distance for better diagonal estimation
|
||||
private static int getHeuristic(RoomCords a, RoomCords b) {
|
||||
int dx = Math.abs(a.getX() - b.getX());
|
||||
int dy = Math.abs(a.getY() - b.getY());
|
||||
return Math.max(dx, dy);
|
||||
}
|
||||
|
||||
private static class Node {
|
||||
int x, y;
|
||||
int g, h, f;
|
||||
Node parent;
|
||||
|
||||
public Node(int x, int y, int g, int h, Node parent) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.g = g;
|
||||
this.h = h;
|
||||
this.f = g + h;
|
||||
this.parent = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package cz.jzitnik.game.mobs.tasks;
|
||||
|
||||
import cz.jzitnik.annotations.injectors.InjectConfig;
|
||||
import cz.jzitnik.annotations.injectors.InjectDependency;
|
||||
import cz.jzitnik.annotations.injectors.InjectState;
|
||||
import cz.jzitnik.config.Debugging;
|
||||
import cz.jzitnik.game.GameState;
|
||||
import cz.jzitnik.game.ResourceManager;
|
||||
import cz.jzitnik.game.mobs.Mob;
|
||||
import cz.jzitnik.game.utils.RoomCords;
|
||||
import cz.jzitnik.states.ScreenBuffer;
|
||||
import cz.jzitnik.states.SoundState;
|
||||
import cz.jzitnik.states.TerminalState;
|
||||
import cz.jzitnik.utils.events.EventManager;
|
||||
import cz.jzitnik.utils.roomtasks.RoomTask;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class BlindMobFollowingPlayerTask extends RoomTask {
|
||||
public BlindMobFollowingPlayerTask(Mob mob, int speed, int updateRate) {
|
||||
super(new Task(mob, speed), updateRate, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
private static class Task implements Runnable {
|
||||
private final Mob mob;
|
||||
private final int speed;
|
||||
private RoomCords playerCords;
|
||||
@InjectState
|
||||
private GameState gameState;
|
||||
|
||||
@InjectDependency
|
||||
private EventManager eventManager;
|
||||
|
||||
@InjectDependency
|
||||
private ResourceManager resourceManager;
|
||||
|
||||
@InjectState
|
||||
private TerminalState terminalState;
|
||||
|
||||
@InjectState
|
||||
private ScreenBuffer screenBuffer;
|
||||
|
||||
@InjectConfig
|
||||
private Debugging debugging;
|
||||
|
||||
@InjectState
|
||||
private SoundState soundState;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (playerCords == null || (soundState.isMicrophoneSetup() && soundState.getSoundVolume() > 2f)) {
|
||||
playerCords = gameState.getPlayer().getPlayerCords().clone();
|
||||
}
|
||||
|
||||
MobFollowingPlayerTask.Task.moveMob(playerCords, mob, gameState, speed, resourceManager, terminalState, screenBuffer, debugging, eventManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package cz.jzitnik.game.mobs.tasks;
|
||||
|
||||
import com.googlecode.lanterna.TerminalPosition;
|
||||
import cz.jzitnik.annotations.injectors.InjectConfig;
|
||||
import cz.jzitnik.annotations.injectors.InjectDependency;
|
||||
import cz.jzitnik.annotations.injectors.InjectState;
|
||||
import cz.jzitnik.config.Debugging;
|
||||
import cz.jzitnik.events.RerenderScreen;
|
||||
import cz.jzitnik.game.GameRoomPart;
|
||||
import cz.jzitnik.game.GameState;
|
||||
import cz.jzitnik.game.Player;
|
||||
import cz.jzitnik.game.ResourceManager;
|
||||
import cz.jzitnik.game.mobs.Mob;
|
||||
import cz.jzitnik.game.utils.RoomCords;
|
||||
import cz.jzitnik.states.ScreenBuffer;
|
||||
import cz.jzitnik.states.TerminalState;
|
||||
import cz.jzitnik.utils.RerenderUtils;
|
||||
import cz.jzitnik.utils.events.EventManager;
|
||||
import cz.jzitnik.utils.roomtasks.RoomTask;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
public class MobFollowingPlayerTask extends RoomTask {
|
||||
public MobFollowingPlayerTask(Mob mob, int speed, int updateRate) {
|
||||
super(new Task(mob, speed), updateRate, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
static class Task implements Runnable {
|
||||
private final Mob mob;
|
||||
private final int speed;
|
||||
|
||||
@InjectState
|
||||
private GameState gameState;
|
||||
|
||||
@InjectDependency
|
||||
private EventManager eventManager;
|
||||
|
||||
@InjectDependency
|
||||
private ResourceManager resourceManager;
|
||||
|
||||
@InjectState
|
||||
private TerminalState terminalState;
|
||||
|
||||
@InjectState
|
||||
private ScreenBuffer screenBuffer;
|
||||
|
||||
@InjectConfig
|
||||
private Debugging debugging;
|
||||
|
||||
protected static void moveMob(RoomCords playerCords, Mob mob, GameState gameState, int speed, ResourceManager resourceManager, TerminalState terminalState, ScreenBuffer screenBuffer, Debugging debugging, EventManager eventManager) {
|
||||
RoomCords mobCords = mob.getCords();
|
||||
List<GameRoomPart> solidParts = gameState.getCurrentRoom().getColliders();
|
||||
List<RoomCords> path = AStarAlg.findPath(mobCords, playerCords, solidParts);
|
||||
|
||||
if (path.size() > 1) {
|
||||
int targetIndex = Math.min(speed, path.size() - 1);
|
||||
|
||||
RoomCords newCords = path.get(targetIndex);
|
||||
|
||||
mob.getCords().updateCords(newCords.getX(), newCords.getY());
|
||||
|
||||
int forStartX = Math.min(mobCords.getX(), newCords.getX());
|
||||
int forStartY = Math.min(mobCords.getY(), newCords.getY());
|
||||
int forEndX = Math.max(mobCords.getX(), newCords.getX()) + mob.getTexture().getWidth() + 1;
|
||||
int forEndY = Math.max(mobCords.getY(), newCords.getY()) + mob.getTexture().getHeight() + 1;
|
||||
|
||||
BufferedImage room = resourceManager.getResource(gameState.getCurrentRoom().getTexture());
|
||||
var start = RerenderUtils.getStart(room, terminalState.getTerminalScreen().getTerminalSize());
|
||||
int startX = start.getX();
|
||||
int startY = start.getY();
|
||||
|
||||
Player player = gameState.getPlayer();
|
||||
BufferedImage playerTexture = RerenderUtils.getPlayer(resourceManager, player);
|
||||
|
||||
RerenderUtils.rerenderPart(forStartX, forEndX, forStartY, forEndY, startX, startY, gameState.getCurrentRoom(), room, player, playerTexture, screenBuffer, resourceManager, debugging);
|
||||
|
||||
eventManager.emitEvent(new RerenderScreen(
|
||||
new RerenderScreen.ScreenPart(
|
||||
new TerminalPosition(forStartX + startX, forStartY + startY),
|
||||
new TerminalPosition(forEndX + 1 + startX, forEndY + startY)
|
||||
)
|
||||
));
|
||||
} else {
|
||||
log.debug("Mob is effectively at the target or trapped.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
moveMob(gameState.getPlayer().getPlayerCords(), mob, gameState, speed, resourceManager, terminalState, screenBuffer, debugging, eventManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package cz.jzitnik.game.setup.mobs;
|
||||
|
||||
import cz.jzitnik.game.ResourceManager;
|
||||
import cz.jzitnik.game.mobs.HittableMob;
|
||||
import cz.jzitnik.game.mobs.tasks.MobFollowingPlayerTask;
|
||||
import cz.jzitnik.game.utils.RoomCords;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@@ -9,7 +10,9 @@ import lombok.extern.slf4j.Slf4j;
|
||||
public class Zombie extends HittableMob {
|
||||
|
||||
public Zombie(ResourceManager resourceManager, RoomCords cords) {
|
||||
super(resourceManager.getResource(ResourceManager.Resource.CHEST), null, cords, 10);
|
||||
super(resourceManager.getResource(ResourceManager.Resource.PLAYER_FRONT), null, cords, 10);
|
||||
//setTask(new BlindMobFollowingPlayerTask(this, 1, 100));
|
||||
setTask(new MobFollowingPlayerTask(this, 1, 100));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,7 +10,7 @@ import java.util.List;
|
||||
@Slf4j
|
||||
@ToString
|
||||
@Getter
|
||||
public class RoomCords {
|
||||
public class RoomCords implements Cloneable {
|
||||
private int x;
|
||||
private int y;
|
||||
|
||||
@@ -29,4 +29,13 @@ public class RoomCords {
|
||||
}
|
||||
updateCords(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoomCords clone() {
|
||||
try {
|
||||
return (RoomCords) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,4 +7,5 @@ import lombok.Data;
|
||||
@State
|
||||
public class SoundState {
|
||||
private double soundVolume;
|
||||
private boolean microphoneSetup = false;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ public class MicrophoneThread extends ShutdownableThread {
|
||||
if (bytesRead > 0) {
|
||||
double volume = calculateRMS(buffer, bytesRead);
|
||||
soundState.setSoundVolume(volume);
|
||||
soundState.setMicrophoneSetup(true);
|
||||
}
|
||||
}
|
||||
} catch (LineUnavailableException e) {
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
package cz.jzitnik.utils.roomtasks;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public record RoomTask(Runnable task, long rate, TimeUnit rateUnit) {
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public class RoomTask {
|
||||
private final Runnable task;
|
||||
private final long rate;
|
||||
private final TimeUnit rateUnit;
|
||||
}
|
||||
|
||||
@@ -3,13 +3,17 @@ package cz.jzitnik.utils.roomtasks;
|
||||
import cz.jzitnik.annotations.Dependency;
|
||||
import cz.jzitnik.annotations.PostInit;
|
||||
import cz.jzitnik.annotations.injectors.InjectConfig;
|
||||
import cz.jzitnik.annotations.injectors.InjectDependency;
|
||||
import cz.jzitnik.config.ThreadPoolConfig;
|
||||
import cz.jzitnik.game.GameRoom;
|
||||
import cz.jzitnik.game.mobs.Mob;
|
||||
import cz.jzitnik.utils.DependencyManager;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
@@ -18,6 +22,10 @@ public class RoomTaskScheduler {
|
||||
ScheduledExecutorService scheduler;
|
||||
@InjectConfig
|
||||
private ThreadPoolConfig threadPoolConfig;
|
||||
@InjectDependency
|
||||
private DependencyManager dependencyManager;
|
||||
|
||||
private HashMap<RoomTask, ScheduledFuture<?>> tasks = new HashMap<>();
|
||||
|
||||
private boolean firstRun = true;
|
||||
|
||||
@@ -46,6 +54,16 @@ public class RoomTaskScheduler {
|
||||
shutdownAll();
|
||||
}
|
||||
|
||||
public void stopTask(RoomTask task) {
|
||||
if (!tasks.containsKey(task)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ScheduledFuture<?> future = tasks.get(task);
|
||||
future.cancel(true);
|
||||
tasks.remove(task);
|
||||
}
|
||||
|
||||
public void setupNewSchedulers(GameRoom currentRoom) {
|
||||
if (!firstRun) {
|
||||
shutdownAll();
|
||||
@@ -54,8 +72,11 @@ public class RoomTaskScheduler {
|
||||
|
||||
for (Mob mob : currentRoom.getMobs()) {
|
||||
RoomTask task = mob.getTask();
|
||||
|
||||
if (task != null) {
|
||||
scheduler.scheduleAtFixedRate(task.task(), 0, task.rate(), task.rateUnit());
|
||||
dependencyManager.inject(task.getTask());
|
||||
ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(task.getTask(), 0, task.getRate(), task.getRateUnit());
|
||||
tasks.put(task, future);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user