feat: duels player colors + elytra sub-modes (M-level)
- Add ParkourGenerator.selectBlockData() hook (forced course material); BlockSelector checks it first; SingleDuelsGenerator overrides to use the player's color (16 concrete colors) and forces only DEFAULT block type - Elytra sub-modes: SpeedDemonGenerator (max-speed score), MinSpeedGenerator (min-speed check, reset on 6 slow ticks), TimeTrialGenerator (score cap), CloseGenerator (FLAT rings); + SpeedDemon/MinSpeed/TimeTrial/Close modes, registration, locales play.elytra.*, config mode-settings.* - Config.getDouble(path, default) + ConfigAccessor overload - checkstyle 0/0, PMD 0, build green
This commit is contained in:
parent
acb884b70b
commit
5707cf2d24
21 changed files with 496 additions and 27 deletions
|
|
@ -13,7 +13,11 @@ import dev.loki.loparkour.hook.papi.PAPIHook;
|
|||
import dev.loki.loparkour.listener.gameplay.ParkourRestrictionListener;
|
||||
import dev.loki.loparkour.listener.schematic.SchematicWandListener;
|
||||
import dev.loki.loparkour.listener.player.PlayerConnectionListener;
|
||||
import dev.loki.loparkour.elytra.mode.CloseMode;
|
||||
import dev.loki.loparkour.elytra.mode.ElytraMode;
|
||||
import dev.loki.loparkour.elytra.mode.MinSpeedMode;
|
||||
import dev.loki.loparkour.elytra.mode.SpeedDemonMode;
|
||||
import dev.loki.loparkour.elytra.mode.TimeTrialMode;
|
||||
import dev.loki.loparkour.mode.base.Modes;
|
||||
import dev.loki.loparkour.mode.impl.barrier.InvisibleBarrierMode;
|
||||
import dev.loki.loparkour.mode.impl.multi.CoopMode;
|
||||
|
|
@ -79,6 +83,10 @@ public final class PluginBootstrap {
|
|||
Registry.register(new CoopMode());
|
||||
Registry.register(new GravityShiftMode());
|
||||
Registry.register(new ElytraMode());
|
||||
Registry.register(new SpeedDemonMode());
|
||||
Registry.register(new MinSpeedMode());
|
||||
Registry.register(new TimeTrialMode());
|
||||
Registry.register(new CloseMode());
|
||||
Registry.register(new DuelsMode());
|
||||
Modes.init();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,6 +99,10 @@ public enum Config {
|
|||
return accessor.getDouble(path);
|
||||
}
|
||||
|
||||
public double getDouble(@NotNull String path, double defaultValue) {
|
||||
return accessor != null ? accessor.getDouble(path, defaultValue) : defaultValue;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getString(@NotNull String path) {
|
||||
return accessor.getString(path);
|
||||
|
|
|
|||
|
|
@ -82,6 +82,14 @@ public class ConfigAccessor {
|
|||
warnIfMissing(path);
|
||||
return config.getDouble(path, 0.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get double value at path with a fallback default.
|
||||
*/
|
||||
public double getDouble(@NotNull String path, double defaultValue) {
|
||||
warnIfMissing(path);
|
||||
return config.getDouble(path, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string value at path.
|
||||
|
|
|
|||
|
|
@ -33,6 +33,23 @@ public class SingleDuelsGenerator extends ParkourGenerator {
|
|||
|
||||
public SingleDuelsGenerator(@NotNull Session session) {
|
||||
super(session);
|
||||
forceDefaultBlocks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(boolean regenerate) {
|
||||
super.reset(regenerate);
|
||||
forceDefaultBlocks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Duels courses use only plain (non-special, non-schematic) blocks so the
|
||||
* player's color is the only material on the course.
|
||||
*/
|
||||
private void forceDefaultBlocks() {
|
||||
state.defaultChances.clear();
|
||||
state.defaultChances.put(BlockGenerationType.DEFAULT, 1.0);
|
||||
state.specialChances.clear();
|
||||
}
|
||||
|
||||
public void setOwnedPlayer(@NotNull ParkourPlayer pp) {
|
||||
|
|
@ -43,6 +60,11 @@ public class SingleDuelsGenerator extends ParkourGenerator {
|
|||
this.blockData = COLORS.get(index % COLORS.size()).createBlockData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull BlockData selectBlockData() {
|
||||
return blockData == null ? Material.STONE.createBlockData() : blockData;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<ParkourPlayer> getPlayers() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
package dev.loki.loparkour.elytra.generator;
|
||||
|
||||
import dev.loki.loparkour.elytra.section.ElytraPointType;
|
||||
import dev.loki.loparkour.session.core.Session;
|
||||
|
||||
/**
|
||||
* Elytra mode that generates flat rings placed close together.
|
||||
*/
|
||||
public class CloseGenerator extends ElytraGenerator {
|
||||
|
||||
public CloseGenerator(Session session) {
|
||||
super(session, ElytraPointType.FLAT);
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,6 @@ import java.util.Map;
|
|||
import java.util.Random;
|
||||
|
||||
public class ElytraGenerator extends ParkourGenerator {
|
||||
|
||||
private static final int ASCEND_THRESHOLD_Y = 50;
|
||||
private static final double SUSTAINED_BOOST = 0.08;
|
||||
private static final int DEFAULT_RADIUS = 3;
|
||||
|
|
@ -28,18 +27,23 @@ public class ElytraGenerator extends ParkourGenerator {
|
|||
private static final double EPSILON = 1e-6;
|
||||
public final Map<Integer, ElytraSection> sections = new LinkedHashMap<>();
|
||||
public final ClientBlockChanger blockChanger = new ClientBlockChanger();
|
||||
private double movementScore = 0.0;
|
||||
protected double movementScore = 0.0;
|
||||
private Long startTime = null;
|
||||
private Vector playerSpawn;
|
||||
private Vector blockSpawn;
|
||||
private Random random;
|
||||
private final ElytraPointType pointType = ElytraPointType.CIRCLE;
|
||||
protected final ElytraPointType pointType;
|
||||
private final int radius;
|
||||
private final Material material;
|
||||
private int boostedSectionIdx = Integer.MIN_VALUE;
|
||||
|
||||
public ElytraGenerator(Session session) {
|
||||
this(session, ElytraPointType.CIRCLE);
|
||||
}
|
||||
|
||||
protected ElytraGenerator(Session session, ElytraPointType pointType) {
|
||||
super(session);
|
||||
this.pointType = pointType;
|
||||
this.radius = Config.GENERATION.getInt("elytra.radius", DEFAULT_RADIUS);
|
||||
this.material = Materials.parseOr(Config.GENERATION.getString("advanced.island.parkour.first-block-material"), Material.WHITE_STAINED_GLASS);
|
||||
}
|
||||
|
|
@ -62,21 +66,19 @@ public class ElytraGenerator extends ParkourGenerator {
|
|||
|
||||
@Override
|
||||
public void generate() {
|
||||
final int idx;
|
||||
final ElytraSection section;
|
||||
if (sections.isEmpty()) {
|
||||
idx = 0;
|
||||
section = new ElytraSection(blockSpawn.clone().add(new Vector(0, pointType.heightOffset, 0)), random,
|
||||
ElytraKnotDirector.DEFAULT_VERTICAL_BIAS);
|
||||
} else {
|
||||
final int lastIdx = sections.keySet().stream().max(Integer::compareTo).orElse(0);
|
||||
final ElytraSection previous = sections.get(lastIdx);
|
||||
final int bias = previous.end().getY() < ASCEND_THRESHOLD_Y ? ElytraKnotDirector.ASCENDING_VERTICAL_BIAS
|
||||
: ElytraKnotDirector.DEFAULT_VERTICAL_BIAS;
|
||||
idx = lastIdx + 1;
|
||||
section = new ElytraSection(previous.end(), random, bias);
|
||||
final Vector start = blockSpawn.clone().add(new Vector(0, pointType.heightOffset, 0));
|
||||
final ElytraSection section = new ElytraSection(start, random, ElytraKnotDirector.DEFAULT_VERTICAL_BIAS);
|
||||
sections.put(0, section);
|
||||
blockChanger.queue(section.generateBlocks(pointType, radius));
|
||||
return;
|
||||
}
|
||||
sections.put(idx, section);
|
||||
final int lastIdx = sections.keySet().stream().max(Integer::compareTo).orElse(0);
|
||||
final ElytraSection previous = sections.get(lastIdx);
|
||||
final int bias = previous.end().getY() < ASCEND_THRESHOLD_Y ? ElytraKnotDirector.ASCENDING_VERTICAL_BIAS
|
||||
: ElytraKnotDirector.DEFAULT_VERTICAL_BIAS;
|
||||
final ElytraSection section = new ElytraSection(previous.end(), random, bias);
|
||||
sections.put(lastIdx + 1, section);
|
||||
blockChanger.queue(section.generateBlocks(pointType, radius));
|
||||
}
|
||||
|
||||
|
|
@ -114,8 +116,8 @@ public class ElytraGenerator extends ParkourGenerator {
|
|||
@Override
|
||||
public void reset(boolean regenerate) {
|
||||
final Player player = getPlayer();
|
||||
for (final ElytraSection section : sections.values()) {
|
||||
if (player != null) {
|
||||
if (player != null) {
|
||||
for (final ElytraSection section : sections.values()) {
|
||||
section.clear(player);
|
||||
}
|
||||
}
|
||||
|
|
@ -142,16 +144,13 @@ public class ElytraGenerator extends ParkourGenerator {
|
|||
return (int) Math.round(movementScore);
|
||||
}
|
||||
|
||||
private Player getPlayer() {
|
||||
protected Player getPlayer() {
|
||||
return session.getPlayers().isEmpty() ? null : session.getPlayers().get(0).player;
|
||||
}
|
||||
|
||||
private void removeOldest(Player player) {
|
||||
if (sections.size() <= 2) {
|
||||
return;
|
||||
}
|
||||
final ElytraSection old = sections.remove(sections.keySet().stream().min(Integer::compareTo).orElse(-1));
|
||||
if (old != null) {
|
||||
if (sections.size() > 2) {
|
||||
final ElytraSection old = sections.remove(sections.keySet().stream().min(Integer::compareTo).orElse(-1));
|
||||
old.clear(player);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
package dev.loki.loparkour.elytra.generator;
|
||||
|
||||
import dev.loki.loparkour.config.core.Config;
|
||||
import dev.loki.loparkour.session.core.Session;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* Elytra mode that requires sustained minimum speed and scores horizontal distance covered.
|
||||
*/
|
||||
public class MinSpeedGenerator extends ElytraGenerator {
|
||||
|
||||
private static final double TICKS_PER_SECOND = 20.0;
|
||||
private static final double MIN_SPEED = Config.GENERATION.getDouble("mode-settings.min-speed.min-speed", 0.9);
|
||||
private static final int TOO_SLOW_LIMIT = 6;
|
||||
|
||||
private int startX = 0;
|
||||
private double maxSpeed = 0;
|
||||
private int ticksTooSlow = 0;
|
||||
|
||||
public MinSpeedGenerator(Session session) {
|
||||
super(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
final Player player = getPlayer();
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
final double speed = player.getVelocity().clone().setY(0).length() * TICKS_PER_SECOND;
|
||||
maxSpeed = Math.max(maxSpeed, speed);
|
||||
if (speed > MIN_SPEED && startX == 0) {
|
||||
startX = player.getLocation().getBlockX();
|
||||
}
|
||||
if (MIN_SPEED > speed && maxSpeed > MIN_SPEED) {
|
||||
ticksTooSlow++;
|
||||
}
|
||||
if (ticksTooSlow >= TOO_SLOW_LIMIT) {
|
||||
reset(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(boolean regenerate) {
|
||||
super.reset(regenerate);
|
||||
startX = 0;
|
||||
maxSpeed = 0;
|
||||
ticksTooSlow = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getElytraScore() {
|
||||
final Player player = getPlayer();
|
||||
if (startX == 0 || player == null) {
|
||||
return 0;
|
||||
}
|
||||
return Math.max(0, (int) Math.round(player.getLocation().getX() - startX));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package dev.loki.loparkour.elytra.generator;
|
||||
|
||||
import dev.loki.loparkour.session.core.Session;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* Elytra mode that scores the highest gliding speed reached during the run.
|
||||
*/
|
||||
public class SpeedDemonGenerator extends ElytraGenerator {
|
||||
|
||||
private static final double TICKS_PER_SECOND = 20.0;
|
||||
|
||||
private double maxSpeed = 0;
|
||||
|
||||
public SpeedDemonGenerator(Session session) {
|
||||
super(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
final Player player = getPlayer();
|
||||
if (player != null && player.isGliding() && player.getVelocity().getX() > 0) {
|
||||
maxSpeed = Math.max(maxSpeed, player.getVelocity().clone().setY(0).length() * TICKS_PER_SECOND);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(boolean regenerate) {
|
||||
super.reset(regenerate);
|
||||
maxSpeed = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getElytraScore() {
|
||||
return (int) Math.round(maxSpeed);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package dev.loki.loparkour.elytra.generator;
|
||||
|
||||
import dev.loki.loparkour.config.core.Config;
|
||||
import dev.loki.loparkour.session.core.Session;
|
||||
|
||||
/**
|
||||
* Elytra mode that restarts the course once the target score is reached.
|
||||
*/
|
||||
public class TimeTrialGenerator extends ElytraGenerator {
|
||||
|
||||
private static final int SCORE = Config.GENERATION.getInt("mode-settings.time-trial.score", 500);
|
||||
|
||||
public TimeTrialGenerator(Session session) {
|
||||
super(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (getElytraScore() >= SCORE) {
|
||||
reset(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
55
src/main/java/dev/loki/loparkour/elytra/mode/CloseMode.java
Normal file
55
src/main/java/dev/loki/loparkour/elytra/mode/CloseMode.java
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
package dev.loki.loparkour.elytra.mode;
|
||||
|
||||
import dev.loki.loparkour.config.locale.Locales;
|
||||
import dev.loki.loparkour.elytra.generator.CloseGenerator;
|
||||
import dev.loki.loparkour.leaderboard.core.Leaderboard;
|
||||
import dev.loki.loparkour.mode.base.Mode;
|
||||
import dev.loki.loparkour.mode.base.ModeMessages;
|
||||
import dev.loki.loparkour.player.core.ParkourPlayer;
|
||||
import dev.loki.loparkour.session.core.Session;
|
||||
import dev.loki.loparkour.util.item.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Elytra mode with flat rings placed close together.
|
||||
*/
|
||||
public class CloseMode implements Mode {
|
||||
|
||||
private final Leaderboard leaderboard = new Leaderboard(getName(), Leaderboard.Sort.SCORE);
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return "close";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Item getItem(String locale) {
|
||||
return Locales.getItem(locale, "play.elytra.close");
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Leaderboard getLeaderboard() {
|
||||
return leaderboard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create(Player player) {
|
||||
if (!ModeMessages.checkJoiningEnabled(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ParkourPlayer pp = ParkourPlayer.getPlayer(player);
|
||||
if (pp != null && pp.session.generator != null && pp.session.generator.getMode() instanceof CloseMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
player.closeInventory();
|
||||
|
||||
Session.create(CloseGenerator::new, null, null, player);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package dev.loki.loparkour.elytra.mode;
|
||||
|
||||
import dev.loki.loparkour.config.locale.Locales;
|
||||
import dev.loki.loparkour.elytra.generator.MinSpeedGenerator;
|
||||
import dev.loki.loparkour.leaderboard.core.Leaderboard;
|
||||
import dev.loki.loparkour.mode.base.Mode;
|
||||
import dev.loki.loparkour.mode.base.ModeMessages;
|
||||
import dev.loki.loparkour.player.core.ParkourPlayer;
|
||||
import dev.loki.loparkour.session.core.Session;
|
||||
import dev.loki.loparkour.util.item.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Elytra mode scoring distance covered while keeping a minimum speed.
|
||||
*/
|
||||
public class MinSpeedMode implements Mode {
|
||||
|
||||
private final Leaderboard leaderboard = new Leaderboard(getName(), Leaderboard.Sort.SCORE);
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return "minspeed";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Item getItem(String locale) {
|
||||
return Locales.getItem(locale, "play.elytra.minspeed");
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Leaderboard getLeaderboard() {
|
||||
return leaderboard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create(Player player) {
|
||||
if (!ModeMessages.checkJoiningEnabled(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ParkourPlayer pp = ParkourPlayer.getPlayer(player);
|
||||
if (pp != null && pp.session.generator != null && pp.session.generator.getMode() instanceof MinSpeedMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
player.closeInventory();
|
||||
|
||||
Session.create(MinSpeedGenerator::new, null, null, player);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package dev.loki.loparkour.elytra.mode;
|
||||
|
||||
import dev.loki.loparkour.config.locale.Locales;
|
||||
import dev.loki.loparkour.elytra.generator.SpeedDemonGenerator;
|
||||
import dev.loki.loparkour.leaderboard.core.Leaderboard;
|
||||
import dev.loki.loparkour.mode.base.Mode;
|
||||
import dev.loki.loparkour.mode.base.ModeMessages;
|
||||
import dev.loki.loparkour.player.core.ParkourPlayer;
|
||||
import dev.loki.loparkour.session.core.Session;
|
||||
import dev.loki.loparkour.util.item.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Elytra mode scoring the highest gliding speed reached.
|
||||
*/
|
||||
public class SpeedDemonMode implements Mode {
|
||||
|
||||
private final Leaderboard leaderboard = new Leaderboard(getName(), Leaderboard.Sort.SCORE);
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return "speeddemon";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Item getItem(String locale) {
|
||||
return Locales.getItem(locale, "play.elytra.speeddemon");
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Leaderboard getLeaderboard() {
|
||||
return leaderboard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create(Player player) {
|
||||
if (!ModeMessages.checkJoiningEnabled(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ParkourPlayer pp = ParkourPlayer.getPlayer(player);
|
||||
if (pp != null && pp.session.generator != null && pp.session.generator.getMode() instanceof SpeedDemonMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
player.closeInventory();
|
||||
|
||||
Session.create(SpeedDemonGenerator::new, null, null, player);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package dev.loki.loparkour.elytra.mode;
|
||||
|
||||
import dev.loki.loparkour.config.locale.Locales;
|
||||
import dev.loki.loparkour.elytra.generator.TimeTrialGenerator;
|
||||
import dev.loki.loparkour.leaderboard.core.Leaderboard;
|
||||
import dev.loki.loparkour.mode.base.Mode;
|
||||
import dev.loki.loparkour.mode.base.ModeMessages;
|
||||
import dev.loki.loparkour.player.core.ParkourPlayer;
|
||||
import dev.loki.loparkour.session.core.Session;
|
||||
import dev.loki.loparkour.util.item.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Elytra mode that resets the course after the target score is reached.
|
||||
*/
|
||||
public class TimeTrialMode implements Mode {
|
||||
|
||||
private final Leaderboard leaderboard = new Leaderboard(getName(), Leaderboard.Sort.SCORE);
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return "timetrial";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Item getItem(String locale) {
|
||||
return Locales.getItem(locale, "play.elytra.timetrial");
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Leaderboard getLeaderboard() {
|
||||
return leaderboard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create(Player player) {
|
||||
if (!ModeMessages.checkJoiningEnabled(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ParkourPlayer pp = ParkourPlayer.getPlayer(player);
|
||||
if (pp != null && pp.session.generator != null && pp.session.generator.getMode() instanceof TimeTrialMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
player.closeInventory();
|
||||
|
||||
Session.create(TimeTrialGenerator::new, null, null, player);
|
||||
}
|
||||
}
|
||||
|
|
@ -14,6 +14,7 @@ import dev.loki.loparkour.player.spectator.ParkourSpectator;
|
|||
import dev.loki.loparkour.session.core.Session;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
|
@ -152,6 +153,14 @@ public class ParkourGenerator {
|
|||
return state.history.get(state.history.size() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for modes to force a fixed block material on the whole course
|
||||
* (e.g. a per-player color in duels), or {@code null} to use the style.
|
||||
*/
|
||||
public @Nullable BlockData selectBlockData() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Event listener management
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -31,6 +31,10 @@ public class BlockSelector {
|
|||
*/
|
||||
@NotNull
|
||||
public BlockData selectBlockData() {
|
||||
final BlockData forced = generator.selectBlockData();
|
||||
if (forced != null) {
|
||||
return forced;
|
||||
}
|
||||
final Style style = Registry.getStyle(generator.profile.get("style").value());
|
||||
if (style == null) {
|
||||
final List<Style> styles = Registry.getStyles();
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@ package dev.loki.loparkour.mode.base;
|
|||
|
||||
import dev.loki.loparkour.api.core.Registry;
|
||||
import dev.loki.loparkour.duels.DuelsMode;
|
||||
import dev.loki.loparkour.elytra.mode.CloseMode;
|
||||
import dev.loki.loparkour.elytra.mode.ElytraMode;
|
||||
import dev.loki.loparkour.elytra.mode.MinSpeedMode;
|
||||
import dev.loki.loparkour.elytra.mode.SpeedDemonMode;
|
||||
import dev.loki.loparkour.elytra.mode.TimeTrialMode;
|
||||
import dev.loki.loparkour.mode.impl.barrier.InvisibleBarrierMode;
|
||||
import dev.loki.loparkour.mode.impl.multi.CoopMode;
|
||||
import dev.loki.loparkour.mode.impl.multi.RaceMode;
|
||||
|
|
@ -24,6 +28,10 @@ public final class Modes {
|
|||
public static CoopMode COOP;
|
||||
public static GravityShiftMode GRAVITY_SHIFT;
|
||||
public static ElytraMode ELYTRA;
|
||||
public static SpeedDemonMode SPEED_DEMON;
|
||||
public static MinSpeedMode MIN_SPEED;
|
||||
public static TimeTrialMode TIME_TRIAL;
|
||||
public static CloseMode CLOSE;
|
||||
public static DuelsMode DUELS;
|
||||
|
||||
public static void init() {
|
||||
|
|
@ -35,6 +43,10 @@ public final class Modes {
|
|||
COOP = (CoopMode) Registry.getMode("coop");
|
||||
GRAVITY_SHIFT = (GravityShiftMode) Registry.getMode("gravity-shift");
|
||||
ELYTRA = (ElytraMode) Registry.getMode("elytra");
|
||||
SPEED_DEMON = (SpeedDemonMode) Registry.getMode("speeddemon");
|
||||
MIN_SPEED = (MinSpeedMode) Registry.getMode("minspeed");
|
||||
TIME_TRIAL = (TimeTrialMode) Registry.getMode("timetrial");
|
||||
CLOSE = (CloseMode) Registry.getMode("close");
|
||||
DUELS = (DuelsMode) Registry.getMode("duels");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue