use of com.voxelgameslib.voxelgameslib.api.feature.Feature in project VoxelGamesLibv2 by VoxelGamesLib.
the class AbstractPhase method disable.
@Override
public void disable() {
// disable timer
duration = Duration.between(startTime, LocalDateTime.now());
log.finer("disable phase " + getName());
// only disable features that have been started to avoid errors
for (Feature feature : startedFeatures) {
log.finer("disable " + feature.getName());
try {
feature.disable();
} catch (Exception ex) {
log.severe("error while stopping " + feature.getName());
ex.printStackTrace();
return;
}
if (feature instanceof Listener) {
eventHandler.unregister((Listener) feature, getGame());
}
if (feature instanceof FeatureCommandImplementor) {
AbstractFeatureCommand cmd = injector.getInstance(((FeatureCommandImplementor) feature).getCommandClass());
commandHandler.unregister(cmd, this);
}
}
for (VictoryCondition victoryCondition : victoryConditions) {
if (victoryCondition instanceof Listener) {
eventHandler.registerEvents((Listener) victoryCondition, getGame());
}
}
phaseTickables.values().forEach(tickable -> {
tickable.disable();
if (tickable instanceof Ability) {
((Ability) tickable).unregister();
}
});
startedFeatures.clear();
}
use of com.voxelgameslib.voxelgameslib.api.feature.Feature in project VoxelGamesLibv2 by VoxelGamesLib.
the class AbstractPhase method tick.
@Override
public void tick() {
phaseTiming.startTiming();
for (Feature feature : features) {
MCTiming timing = timingManager.ofStart("Phase::Tickables::" + getName() + "::" + feature.getName(), phaseTiming);
feature.tick();
timing.stopTiming();
}
for (Tickable tickable : phaseTickables.values()) {
MCTiming timing = timingManager.ofStart("Phase::Tickables::" + getName() + "::" + tickable.getClass().getSimpleName(), phaseTiming);
tickable.tick();
timing.stopTiming();
}
phaseTiming.stopTiming();
checkEnd();
}
use of com.voxelgameslib.voxelgameslib.api.feature.Feature in project VoxelGamesLibv2 by VoxelGamesLib.
the class AbstractPhase method enable.
@Override
public void enable() {
phaseTiming = timingManager.of("Phase::Tickables::" + getName());
if (!checkDependencies()) {
game.abortGame();
return;
}
if (!checkVictoryConditionDependencies()) {
game.abortGame();
return;
}
if (victoryConditions.size() == 0) {
addVictoryCondition(getGame().createVictoryCondition(EmptyVictoryCondition.class, this));
}
// check for spec feature
if (allowSpectate && !getOptionalFeature(SpectatorFeature.class).isPresent()) {
log.warning(getName() + " does allow spectators but doesn't use the spectator feature! Did you forget to add it?");
}
// enable timer
startTime = LocalDateTime.now();
log.finer("enable phase" + getName());
phaseTickables.values().forEach(Tickable::enable);
for (Feature feature : features) {
if (game.isAborting()) {
return;
}
log.finer("enable " + feature.getName());
try {
feature.enable();
} catch (Exception ex) {
log.severe("error while starting " + feature.getName());
ex.printStackTrace();
game.abortGame();
return;
}
if (feature instanceof Listener) {
eventHandler.registerEvents((Listener) feature, getGame());
}
if (feature instanceof FeatureCommandImplementor) {
AbstractFeatureCommand cmd = injector.getInstance(((FeatureCommandImplementor) feature).getCommandClass());
// noinspection unchecked
cmd.setFeature(feature);
commandHandler.register(cmd, this);
}
startedFeatures.add(feature);
}
for (VictoryCondition victoryCondition : victoryConditions) {
if (victoryCondition instanceof Listener) {
eventHandler.registerEvents((Listener) victoryCondition, getGame());
}
}
}
use of com.voxelgameslib.voxelgameslib.api.feature.Feature in project VoxelGamesLibv2 by VoxelGamesLib.
the class AbstractPhase method checkDependencies.
private boolean checkDependencies() {
List<Class<? extends Feature>> orderedFeatures = new ArrayList<>();
List<Class<? extends Feature>> added = new ArrayList<>();
List<Class<? extends Feature>> missingSoftDependencies = new ArrayList<>();
try {
Graph<Class<? extends Feature>> graph = new Graph<>(orderedFeatures::add);
// add all dependencies to the graph
for (Feature feature : getFeatures()) {
for (Class<? extends Feature> dependency : feature.getDependencies()) {
if (dependency.equals(feature.getClass())) {
log.severe(feature.getName() + " tried to depend on itself...");
continue;
}
graph.addDependency(feature.getClass(), dependency);
added.add(feature.getClass());
added.add(dependency);
try {
getFeature(dependency);
} catch (NoSuchFeatureException ex) {
log.severe("could not find dependency " + dependency.getName() + " for feature " + feature.getClass().getName() + " in phase " + getName());
return false;
}
}
for (Class<? extends Feature> dependency : feature.getSoftDependencies()) {
if (dependency.equals(feature.getClass())) {
log.severe(feature.getName() + " tried to depend on itself...");
continue;
}
graph.addDependency(feature.getClass(), dependency);
added.add(feature.getClass());
added.add(dependency);
try {
getFeature(dependency);
} catch (NoSuchFeatureException ex) {
missingSoftDependencies.add(dependency);
}
}
}
// add features that have no dependency connection to any other feature. they can't be left out alone!
for (Feature feature : getFeatures()) {
if (!added.contains(feature.getClass())) {
orderedFeatures.add(feature.getClass());
}
}
added.clear();
if (graph.size() != 0) {
// do the magic! (but only if there are actually nodes on the graph)
graph.generateDependencies();
}
} catch (DependencyGraphException ex) {
log.severe("error while trying to generate dependency graph: " + ex.getMessage());
ex.printStackTrace();
return false;
}
// no need to keep stuff that isn't present
orderedFeatures.removeAll(missingSoftDependencies);
if (features.size() != orderedFeatures.size()) {
throw new RuntimeException("WTF HAPPENED HERE?!" + features.size() + " " + orderedFeatures.size());
}
// reverse order because dependencies need to be run before dependend features
Collections.reverse(orderedFeatures);
// remap classes to features
features = orderedFeatures.stream().map((Function<Class, Feature>) this::getFeature).collect(Collectors.toList());
return true;
}
use of com.voxelgameslib.voxelgameslib.api.feature.Feature in project VoxelGamesLibv2 by VoxelGamesLib.
the class AbstractGame method initGameFromDefinition.
@Override
public void initGameFromDefinition(@Nonnull GameDefinition gameDefinition) {
setMaxPlayers(gameDefinition.getMaxPlayers());
setMinPlayers(gameDefinition.getMinPlayers());
activePhase = gameDefinition.getPhases().get(0);
gameData = gameDefinition.getGameData();
// fix stuff
for (int i = 0; i < gameDefinition.getPhases().size(); i++) {
Phase nextPhase;
if (gameDefinition.getPhases().size() > i + 1) {
nextPhase = gameDefinition.getPhases().get(i + 1);
} else {
log.severe("Couldn't fix next phase for phase " + gameDefinition.getPhases().get(i).getName());
return;
}
Phase currPhase = gameDefinition.getPhases().get(i);
currPhase.setNextPhase(nextPhase);
currPhase.setGame(this);
for (Feature feature : currPhase.getFeatures()) {
feature.setPhase(currPhase);
}
for (Feature feature : currPhase.getFeatures()) {
feature.init();
}
}
}
Aggregations