Compress the stages so the endless part starts at 1000, keep the stage in the action bar permanently and let the bridge cover the next 10 blocks from the current position
This commit is contained in:
1 parent
40bedc3c43
commit
7e85a6d229
4 files changed
+56
-37
No files matched your search
@@ -12,11 +12,11 @@ import java.util.Random;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Joker-Items in der Hotbar, die Anzahl ist die Stapelgröße.
|
* Joker-Items in der Hotbar, die Anzahl ist die Stapelgröße.
|
||||||
* Brücke: Rechtsklick baut einen Weg bis zum nächsten Checkpoint.
|
* Brücke: Rechtsklick baut einen Weg über die nächsten 10 Blöcke.
|
||||||
* Totem: rettet automatisch beim Runterfallen (Plattform mit Leiter).
|
* Totem: rettet automatisch beim Runterfallen (Plattform mit Leiter).
|
||||||
*/
|
*/
|
||||||
public enum Jokers {
|
public enum Jokers {
|
||||||
BRIDGE(0, Material.BRICK, "Brücke", NamedTextColor.AQUA, "Rechtsklick: Weg bis zum nächsten Checkpoint"),
|
BRIDGE(0, Material.BRICK, "Brücke", NamedTextColor.AQUA, "Rechtsklick: Weg über die nächsten 10 Blöcke"),
|
||||||
TOTEM(8, Material.TOTEM_OF_UNDYING, "Rettungstotem", NamedTextColor.GOLD, "Rettet dich automatisch beim Runterfallen");
|
TOTEM(8, Material.TOTEM_OF_UNDYING, "Rettungstotem", NamedTextColor.GOLD, "Rettet dich automatisch beim Runterfallen");
|
||||||
|
|
||||||
private final int slot;
|
private final int slot;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import java.util.Random;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Abschnitte entlang des Fortschritts: einmal durch das komplette Spiel, von der Wiese über
|
* Abschnitte entlang des Fortschritts: einmal durch das komplette Spiel, von der Wiese über
|
||||||
* Untergrund, Nether und Stronghold bis ins End (ab Sprung 1000). Jeder Abschnitt hat eigene
|
* Untergrund, Nether und Stronghold bis ins End; ab Sprung 1000 geht es endlos weiter. Jeder Abschnitt hat eigene
|
||||||
* Blöcke und eine eigene Stimmung (Tageszeit, Partikel, Musik).
|
* Blöcke und eine eigene Stimmung (Tageszeit, Partikel, Musik).
|
||||||
*/
|
*/
|
||||||
public class BlockPalette {
|
public class BlockPalette {
|
||||||
@@ -23,47 +23,47 @@ public class BlockPalette {
|
|||||||
new Stage(0, "Wiese", MORNING, null, SoundEvent.MUSIC_OVERWORLD_MEADOW, List.of(
|
new Stage(0, "Wiese", MORNING, null, SoundEvent.MUSIC_OVERWORLD_MEADOW, List.of(
|
||||||
Block.GRASS_BLOCK, Block.GRASS_BLOCK, Block.MOSS_BLOCK, Block.PODZOL, Block.ROOTED_DIRT
|
Block.GRASS_BLOCK, Block.GRASS_BLOCK, Block.MOSS_BLOCK, Block.PODZOL, Block.ROOTED_DIRT
|
||||||
)),
|
)),
|
||||||
new Stage(75, "Wald", NOON, Particle.CHERRY_LEAVES, SoundEvent.MUSIC_OVERWORLD_FOREST, List.of(
|
new Stage(70, "Wald", NOON, Particle.CHERRY_LEAVES, SoundEvent.MUSIC_OVERWORLD_FOREST, List.of(
|
||||||
Block.OAK_LOG, Block.BIRCH_LOG, Block.SPRUCE_LOG, Block.CHERRY_LOG,
|
Block.OAK_LOG, Block.BIRCH_LOG, Block.SPRUCE_LOG, Block.CHERRY_LOG,
|
||||||
Block.OAK_LEAVES, Block.BIRCH_LEAVES, Block.SPRUCE_LEAVES, Block.CHERRY_LEAVES
|
Block.OAK_LEAVES, Block.BIRCH_LEAVES, Block.SPRUCE_LEAVES, Block.CHERRY_LEAVES
|
||||||
)),
|
)),
|
||||||
new Stage(150, "Untergrund", NIGHT, null, SoundEvent.MUSIC_OVERWORLD_DRIPSTONE_CAVES, List.of(
|
new Stage(140, "Untergrund", NIGHT, null, SoundEvent.MUSIC_OVERWORLD_DRIPSTONE_CAVES, List.of(
|
||||||
Block.DIRT, Block.COARSE_DIRT, Block.STONE, Block.STONE, Block.ANDESITE,
|
Block.DIRT, Block.COARSE_DIRT, Block.STONE, Block.STONE, Block.ANDESITE,
|
||||||
Block.GRANITE, Block.DIORITE, Block.COBBLESTONE
|
Block.GRANITE, Block.DIORITE, Block.COBBLESTONE
|
||||||
)),
|
)),
|
||||||
new Stage(250, "Höhlen", NIGHT, Particle.DRIPPING_WATER, SoundEvent.MUSIC_OVERWORLD_LUSH_CAVES, List.of(
|
new Stage(220, "Höhlen", NIGHT, Particle.DRIPPING_WATER, SoundEvent.MUSIC_OVERWORLD_LUSH_CAVES, List.of(
|
||||||
Block.STONE, Block.COAL_ORE, Block.IRON_ORE, Block.COPPER_ORE,
|
Block.STONE, Block.COAL_ORE, Block.IRON_ORE, Block.COPPER_ORE,
|
||||||
Block.GOLD_ORE, Block.REDSTONE_ORE, Block.LAPIS_ORE
|
Block.GOLD_ORE, Block.REDSTONE_ORE, Block.LAPIS_ORE
|
||||||
)),
|
)),
|
||||||
new Stage(350, "Tiefenschiefer", NIGHT, Particle.SCULK_SOUL, SoundEvent.MUSIC_OVERWORLD_DEEP_DARK, List.of(
|
new Stage(300, "Tiefenschiefer", NIGHT, Particle.SCULK_SOUL, SoundEvent.MUSIC_OVERWORLD_DEEP_DARK, List.of(
|
||||||
Block.DEEPSLATE, Block.DEEPSLATE, Block.TUFF, Block.DEEPSLATE_DIAMOND_ORE,
|
Block.DEEPSLATE, Block.DEEPSLATE, Block.TUFF, Block.DEEPSLATE_DIAMOND_ORE,
|
||||||
Block.DEEPSLATE_IRON_ORE, Block.AMETHYST_BLOCK
|
Block.DEEPSLATE_IRON_ORE, Block.AMETHYST_BLOCK
|
||||||
)),
|
)),
|
||||||
new Stage(450, "Netherportal", NIGHT, Particle.PORTAL, SoundEvent.MUSIC_NETHER_NETHER_WASTES, List.of(
|
new Stage(390, "Netherportal", NIGHT, Particle.PORTAL, SoundEvent.MUSIC_NETHER_NETHER_WASTES, List.of(
|
||||||
Block.OBSIDIAN, Block.OBSIDIAN, Block.CRYING_OBSIDIAN
|
Block.OBSIDIAN, Block.OBSIDIAN, Block.CRYING_OBSIDIAN
|
||||||
)),
|
)),
|
||||||
new Stage(475, "Nether", NIGHT, Particle.CRIMSON_SPORE, SoundEvent.MUSIC_NETHER_CRIMSON_FOREST, List.of(
|
new Stage(410, "Nether", NIGHT, Particle.CRIMSON_SPORE, SoundEvent.MUSIC_NETHER_CRIMSON_FOREST, List.of(
|
||||||
Block.NETHERRACK, Block.NETHERRACK, Block.CRIMSON_NYLIUM, Block.WARPED_NYLIUM,
|
Block.NETHERRACK, Block.NETHERRACK, Block.CRIMSON_NYLIUM, Block.WARPED_NYLIUM,
|
||||||
Block.SOUL_SOIL, Block.GLOWSTONE, Block.NETHER_QUARTZ_ORE, Block.NETHER_GOLD_ORE
|
Block.SOUL_SOIL, Block.GLOWSTONE, Block.NETHER_QUARTZ_ORE, Block.NETHER_GOLD_ORE
|
||||||
)),
|
)),
|
||||||
new Stage(625, "Festung & Bastion", NIGHT, Particle.WHITE_ASH, SoundEvent.MUSIC_NETHER_BASALT_DELTAS, List.of(
|
new Stage(540, "Festung & Bastion", NIGHT, Particle.WHITE_ASH, SoundEvent.MUSIC_NETHER_BASALT_DELTAS, List.of(
|
||||||
Block.NETHER_BRICKS, Block.RED_NETHER_BRICKS, Block.BLACKSTONE,
|
Block.NETHER_BRICKS, Block.RED_NETHER_BRICKS, Block.BLACKSTONE,
|
||||||
Block.POLISHED_BLACKSTONE_BRICKS, Block.GILDED_BLACKSTONE, Block.BASALT
|
Block.POLISHED_BLACKSTONE_BRICKS, Block.GILDED_BLACKSTONE, Block.BASALT
|
||||||
)),
|
)),
|
||||||
new Stage(750, "Stronghold", NIGHT, Particle.ENCHANT, SoundEvent.MUSIC_DISC_MELLOHI, List.of(
|
new Stage(660, "Stronghold", NIGHT, Particle.ENCHANT, SoundEvent.MUSIC_DISC_MELLOHI, List.of(
|
||||||
Block.STONE_BRICKS, Block.MOSSY_STONE_BRICKS, Block.CRACKED_STONE_BRICKS,
|
Block.STONE_BRICKS, Block.MOSSY_STONE_BRICKS, Block.CRACKED_STONE_BRICKS,
|
||||||
Block.CHISELED_STONE_BRICKS, Block.BOOKSHELF
|
Block.CHISELED_STONE_BRICKS, Block.BOOKSHELF
|
||||||
)),
|
)),
|
||||||
new Stage(925, "Portalraum", NIGHT, Particle.REVERSE_PORTAL, SoundEvent.MUSIC_DRAGON, List.of(
|
new Stage(800, "Portalraum", NIGHT, Particle.REVERSE_PORTAL, SoundEvent.MUSIC_DRAGON, List.of(
|
||||||
Block.END_PORTAL_FRAME, Block.END_PORTAL_FRAME.withProperty("eye", "true"),
|
Block.END_PORTAL_FRAME, Block.END_PORTAL_FRAME.withProperty("eye", "true"),
|
||||||
Block.STONE_BRICKS, Block.MOSSY_STONE_BRICKS
|
Block.STONE_BRICKS, Block.MOSSY_STONE_BRICKS
|
||||||
)),
|
)),
|
||||||
new Stage(1000, "End", NIGHT, Particle.END_ROD, SoundEvent.MUSIC_END, List.of(
|
new Stage(850, "End", NIGHT, Particle.END_ROD, SoundEvent.MUSIC_END, List.of(
|
||||||
Block.END_STONE, Block.END_STONE, Block.END_STONE_BRICKS,
|
Block.END_STONE, Block.END_STONE, Block.END_STONE_BRICKS,
|
||||||
Block.PURPUR_BLOCK, Block.PURPUR_PILLAR, Block.OBSIDIAN
|
Block.PURPUR_BLOCK, Block.PURPUR_PILLAR, Block.OBSIDIAN
|
||||||
)),
|
)),
|
||||||
// nach dem End endlos weiter mit einem neutralen Block
|
// nach dem End endlos weiter mit einem neutralen Block
|
||||||
new Stage(1100, "Unendlich", NIGHT, null, SoundEvent.MUSIC_MENU, List.of(
|
new Stage(1000, "Unendlich", NIGHT, null, SoundEvent.MUSIC_MENU, List.of(
|
||||||
Block.SMOOTH_QUARTZ
|
Block.SMOOTH_QUARTZ
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -48,13 +48,13 @@ public class JumpGenerator {
|
|||||||
|
|
||||||
private static final Block BRIDGE_BLOCK = Block.WHITE_STAINED_GLASS;
|
private static final Block BRIDGE_BLOCK = Block.WHITE_STAINED_GLASS;
|
||||||
private static final int BRIDGE_STEP_TICKS = 4;
|
private static final int BRIDGE_STEP_TICKS = 4;
|
||||||
|
private static final int BRIDGE_LENGTH = 10;
|
||||||
private static final Block RESCUE_BLOCK = Block.OAK_PLANKS;
|
private static final Block RESCUE_BLOCK = Block.OAK_PLANKS;
|
||||||
private static final int RESCUE_DEPTH = 6;
|
private static final int RESCUE_DEPTH = 6;
|
||||||
|
|
||||||
private static final TextColor COMBO_COLOR = TextColor.color(255, 69, 0);
|
private static final TextColor COMBO_COLOR = TextColor.color(255, 69, 0);
|
||||||
private static final Title CHECKPOINT_TITLE = Title.title(Component.empty(), Component.text("Checkpoint", NamedTextColor.GREEN));
|
private static final Title CHECKPOINT_TITLE = Title.title(Component.empty(), Component.text("Checkpoint", NamedTextColor.GREEN));
|
||||||
private static final Component ENDLESS_HINT = Component.text(" · /reset für einen Neustart", NamedTextColor.DARK_GRAY);
|
private static final Title FINALE_TITLE = Title.title(Component.text("Geschafft!", NamedTextColor.GOLD), Component.text("Durchgespielt – ab jetzt geht es endlos weiter", NamedTextColor.YELLOW));
|
||||||
private static final Title FINALE_TITLE = Title.title(Component.text("Geschafft!", NamedTextColor.GOLD), Component.text("Du hast das End erreicht", NamedTextColor.YELLOW));
|
|
||||||
private static final Sound CHECKPOINT_SOUND = Sound.sound(SoundEvent.ENTITY_PLAYER_LEVELUP, Sound.Source.BLOCK, 0.3f, 1f);
|
private static final Sound CHECKPOINT_SOUND = Sound.sound(SoundEvent.ENTITY_PLAYER_LEVELUP, Sound.Source.BLOCK, 0.3f, 1f);
|
||||||
private static final Sound STAGE_SOUND = Sound.sound(SoundEvent.UI_TOAST_CHALLENGE_COMPLETE, Sound.Source.MASTER, 0.4f, 1f);
|
private static final Sound STAGE_SOUND = Sound.sound(SoundEvent.UI_TOAST_CHALLENGE_COMPLETE, Sound.Source.MASTER, 0.4f, 1f);
|
||||||
private static final Sound BRIDGE_SOUND = Sound.sound(SoundEvent.BLOCK_AMETHYST_BLOCK_CHIME, Sound.Source.MASTER, 1f, 1f);
|
private static final Sound BRIDGE_SOUND = Sound.sound(SoundEvent.BLOCK_AMETHYST_BLOCK_CHIME, Sound.Source.MASTER, 1f, 1f);
|
||||||
@@ -73,7 +73,8 @@ public class JumpGenerator {
|
|||||||
private int standing;
|
private int standing;
|
||||||
private int combo = 0;
|
private int combo = 0;
|
||||||
private Pos checkpoint;
|
private Pos checkpoint;
|
||||||
// bis zu diesem Index wurde per Brücke gebaut: diese Blöcke zählen nicht zur Combo
|
// zuletzt per Brücke überbrückter Bereich: diese Blöcke zählen nicht zur Combo
|
||||||
|
private int bridgeStart = -1;
|
||||||
private int bridgeEnd = -1;
|
private int bridgeEnd = -1;
|
||||||
|
|
||||||
// Rettung durch das Totem: Plattform mit Leiter unter dem Block, von dem man gefallen ist
|
// Rettung durch das Totem: Plattform mit Leiter unter dem Block, von dem man gefallen ist
|
||||||
@@ -139,7 +140,7 @@ public class JumpGenerator {
|
|||||||
this.player.setLevel(index);
|
this.player.setLevel(index);
|
||||||
ScoreTab.update(this.player, index);
|
ScoreTab.update(this.player, index);
|
||||||
|
|
||||||
if(index > this.bridgeEnd) {
|
if(index < this.bridgeStart || index > this.bridgeEnd) {
|
||||||
this.combo++;
|
this.combo++;
|
||||||
this.player.playSound(Sound.sound(SoundEvent.BLOCK_NOTE_BLOCK_PLING, Sound.Source.MASTER, 0.1f, 1 + this.combo * 0.025f));
|
this.player.playSound(Sound.sound(SoundEvent.BLOCK_NOTE_BLOCK_PLING, Sound.Source.MASTER, 0.1f, 1 + this.combo * 0.025f));
|
||||||
this.player.showTitle(Title.title(Component.empty(), Component.text(this.combo, COMBO_COLOR)));
|
this.player.showTitle(Title.title(Component.empty(), Component.text(this.combo, COMBO_COLOR)));
|
||||||
@@ -155,23 +156,19 @@ public class JumpGenerator {
|
|||||||
this.player.sendPacket(new ParticlePacket(Particle.CRIT, this.checkpoint, this.checkpoint.add(0.5), 1.5f, 50));
|
this.player.sendPacket(new ParticlePacket(Particle.CRIT, this.checkpoint, this.checkpoint.add(0.5), 1.5f, 50));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Abschnitt dauerhaft in der Actionbar (Titel werden von der Combo-Anzeige überschrieben)
|
// neuer Abschnitt: Stimmung wechseln (die Actionbar zeigt der Abschnitt selbst dauerhaft)
|
||||||
BlockPalette.Stage stage = BlockPalette.stageAt(index);
|
BlockPalette.Stage stage = BlockPalette.stageAt(index);
|
||||||
boolean newStage = stage != BlockPalette.stageAt(previous);
|
if(stage != BlockPalette.stageAt(previous)) {
|
||||||
if(newStage) {
|
|
||||||
this.atmosphere.enter(stage);
|
this.atmosphere.enter(stage);
|
||||||
this.player.playSound(STAGE_SOUND);
|
this.player.playSound(STAGE_SOUND);
|
||||||
}
|
}
|
||||||
Component stageText = Component.text(stage.name(), newStage ? NamedTextColor.GOLD : NamedTextColor.GRAY);
|
|
||||||
if(BlockPalette.isEndless(stage)) stageText = stageText.append(ENDLESS_HINT);
|
|
||||||
this.player.sendActionBar(stageText);
|
|
||||||
|
|
||||||
if(previous < FINALE_AT && index >= FINALE_AT) this.celebrate();
|
if(previous < FINALE_AT && index >= FINALE_AT) this.celebrate();
|
||||||
|
|
||||||
this.ensureGenerated(index + PREVIEW + 1, 0);
|
this.ensureGenerated(index + PREVIEW + 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Ankunft im End: Feuerwerk rund um den Spieler. Danach geht es endlos weiter. */
|
/** Durchgespielt (Beginn von „Unendlich“): Feuerwerk rund um den Spieler. */
|
||||||
private void celebrate() {
|
private void celebrate() {
|
||||||
this.player.showTitle(FINALE_TITLE);
|
this.player.showTitle(FINALE_TITLE);
|
||||||
for(int i = 0; i < 6; i++) {
|
for(int i = 0; i < 6; i++) {
|
||||||
@@ -249,20 +246,22 @@ public class JumpGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Joker „Brücke“: erzeugt die Strecke bis zum nächsten Checkpoint und verbindet sie mit einem
|
* Joker „Brücke“: verbindet die nächsten {@link #BRIDGE_LENGTH} Blöcke ab der aktuellen Position
|
||||||
* begehbaren Weg. Diese Blöcke zählen nicht zur Combo. Mehrfacher Aufruf baut nichts doppelt.
|
* mit einem begehbaren Weg, auch über früher schon geschaffte Stücke (z. B. nach einem Reset).
|
||||||
|
* Diese Blöcke zählen nicht zur Combo. Ist der Bereich schon überbrückt, passiert nichts.
|
||||||
*/
|
*/
|
||||||
public boolean useBridge() {
|
public boolean useBridge() {
|
||||||
int nextCheckpoint = (this.standing / 10 + 1) * 10;
|
int target = this.standing + BRIDGE_LENGTH;
|
||||||
if(this.rescueSafe != null || this.bridgeEnd >= nextCheckpoint) return false;
|
if(this.rescueSafe != null || (this.standing >= this.bridgeStart && target <= this.bridgeEnd)) return false;
|
||||||
this.bridgeEnd = nextCheckpoint;
|
this.bridgeStart = this.standing;
|
||||||
|
this.bridgeEnd = target;
|
||||||
|
|
||||||
// bereits stehende Abschnitte sofort, neue Blöcke bekommen ihren Weg bei Ankunft
|
// bereits stehende Abschnitte sofort, neue Blöcke bekommen ihren Weg bei Ankunft
|
||||||
for(int i = this.standing + 1; i < this.generated() && i <= nextCheckpoint; i++) {
|
for(int i = this.standing + 1; i < this.generated() && i <= target; i++) {
|
||||||
this.buildPath(this.step(i - 1).pos(), this.step(i).pos());
|
this.buildPath(this.step(i - 1).pos(), this.step(i).pos());
|
||||||
}
|
}
|
||||||
int delay = 0;
|
int delay = 0;
|
||||||
while(this.generated() <= nextCheckpoint) {
|
while(this.generated() <= target) {
|
||||||
Pos from = this.course.getLast().pos();
|
Pos from = this.course.getLast().pos();
|
||||||
int index = this.generated();
|
int index = this.generated();
|
||||||
this.generateStep(delay, () -> this.buildPath(from, this.step(index).pos()));
|
this.generateStep(delay, () -> this.buildPath(from, this.step(index).pos()));
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package eu.mhsl.minecraft.endlessjumper.generator;
|
|||||||
|
|
||||||
import net.kyori.adventure.sound.Sound;
|
import net.kyori.adventure.sound.Sound;
|
||||||
import net.kyori.adventure.sound.SoundStop;
|
import net.kyori.adventure.sound.SoundStop;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import net.minestom.server.coordinate.Vec;
|
import net.minestom.server.coordinate.Vec;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.instance.Instance;
|
import net.minestom.server.instance.Instance;
|
||||||
@@ -12,20 +14,27 @@ import net.minestom.server.timer.TaskSchedule;
|
|||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stimmung des aktuellen Abschnitts: Tageszeit (fließender Übergang), Musik und Partikel,
|
* Stimmung des aktuellen Abschnitts: Tageszeit (fließender Übergang), Musik, Partikel auf der
|
||||||
* die dauerhaft um den Spieler schweben.
|
* Strecke voraus und der Abschnittsname dauerhaft in der Actionbar.
|
||||||
*/
|
*/
|
||||||
class StageAtmosphere {
|
class StageAtmosphere {
|
||||||
private static final int TIME_TRANSITION_TICKS = 100;
|
private static final int TIME_TRANSITION_TICKS = 100;
|
||||||
// die Strecke läuft immer in +z: Partikel vom Spieler bis etwa 10 Sprünge voraus
|
// die Strecke läuft immer in +z: Partikel vom Spieler bis etwa 10 Sprünge voraus
|
||||||
private static final Vec AMBIENT_AHEAD = new Vec(0, 1.5, 14);
|
private static final Vec AMBIENT_AHEAD = new Vec(0, 1.5, 14);
|
||||||
private static final Vec AMBIENT_SPREAD = new Vec(7, 4, 16);
|
private static final Vec AMBIENT_SPREAD = new Vec(7, 4, 16);
|
||||||
|
private static final int AMBIENT_EVERY_TICKS = 4;
|
||||||
|
// die Actionbar blendet nach ~3 s aus: jede Sekunde erneuern, nach einem Wechsel 5 s golden
|
||||||
|
private static final int ACTION_BAR_TICKS = 20;
|
||||||
|
private static final int HIGHLIGHT_TICKS = 100;
|
||||||
|
private static final Component ENDLESS_HINT = Component.text(" · /reset für einen Neustart", NamedTextColor.DARK_GRAY);
|
||||||
|
|
||||||
private final Player player;
|
private final Player player;
|
||||||
private final Instance world;
|
private final Instance world;
|
||||||
private BlockPalette.Stage stage;
|
private BlockPalette.Stage stage;
|
||||||
private Task timeTransition;
|
private Task timeTransition;
|
||||||
private final Task ambient;
|
private final Task ambient;
|
||||||
|
private int ticks = 0;
|
||||||
|
private int highlightUntil = 0;
|
||||||
|
|
||||||
StageAtmosphere(Player player, Instance world, BlockPalette.Stage initial) {
|
StageAtmosphere(Player player, Instance world, BlockPalette.Stage initial) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
@@ -35,7 +44,7 @@ class StageAtmosphere {
|
|||||||
this.world.refreshTime();
|
this.world.refreshTime();
|
||||||
this.playMusic();
|
this.playMusic();
|
||||||
// an den Spieler gebunden, endet also mit ihm
|
// an den Spieler gebunden, endet also mit ihm
|
||||||
this.ambient = player.scheduler().buildTask(this::spawnAmbient).repeat(TaskSchedule.tick(4)).schedule();
|
this.ambient = player.scheduler().buildTask(this::tick).repeat(TaskSchedule.tick(AMBIENT_EVERY_TICKS)).schedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop() {
|
void stop() {
|
||||||
@@ -47,8 +56,10 @@ class StageAtmosphere {
|
|||||||
void enter(BlockPalette.Stage next) {
|
void enter(BlockPalette.Stage next) {
|
||||||
if(next == this.stage) return;
|
if(next == this.stage) return;
|
||||||
this.stage = next;
|
this.stage = next;
|
||||||
|
this.highlightUntil = this.ticks + HIGHLIGHT_TICKS;
|
||||||
this.playMusic();
|
this.playMusic();
|
||||||
this.fadeTimeTo(next.time());
|
this.fadeTimeTo(next.time());
|
||||||
|
this.showStage();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void playMusic() {
|
private void playMusic() {
|
||||||
@@ -76,8 +87,17 @@ class StageAtmosphere {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void spawnAmbient() {
|
private void tick() {
|
||||||
if(this.stage.ambient() == null) return;
|
this.ticks += AMBIENT_EVERY_TICKS;
|
||||||
|
if(this.ticks % ACTION_BAR_TICKS == 0) this.showStage();
|
||||||
|
if(this.stage.ambient() != null) {
|
||||||
this.player.sendPacket(new ParticlePacket(this.stage.ambient(), this.player.getPosition().add(AMBIENT_AHEAD), AMBIENT_SPREAD, 0.02f, 8));
|
this.player.sendPacket(new ParticlePacket(this.stage.ambient(), this.player.getPosition().add(AMBIENT_AHEAD), AMBIENT_SPREAD, 0.02f, 8));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showStage() {
|
||||||
|
Component text = Component.text(this.stage.name(), this.ticks < this.highlightUntil ? NamedTextColor.GOLD : NamedTextColor.GRAY);
|
||||||
|
if(BlockPalette.isEndless(this.stage)) text = text.append(ENDLESS_HINT);
|
||||||
|
this.player.sendActionBar(text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user