Stage 4-5: Survivor and Generator systems

This commit is contained in:
loki5512344 2026-05-31 20:47:39 +02:00
parent 4fd7955d56
commit 5a53620b3a
2 changed files with 193 additions and 0 deletions

View file

@ -0,0 +1,125 @@
package dev.loki.killer;
import dev.loki.player.Killer;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
public class KillerVision extends BukkitRunnable {
private static final long PARTICLE_INTERVAL = 5L;
private static final int PARTICLE_COUNT = 5;
private static final double PARTICLE_SPACING = 0.3;
private final JavaPlugin plugin;
private Killer killer;
private boolean active;
public KillerVision(JavaPlugin plugin) {
this.plugin = plugin;
this.active = false;
}
public void setKiller(Killer killer) {
this.killer = killer;
}
public void start() {
this.active = true;
runTaskTimer(plugin, 0L, PARTICLE_INTERVAL);
}
public void stop() {
this.active = false;
cancel();
}
public boolean isActive() {
return active;
}
@Override
public void run() {
if (!active || killer == null || !killer.isOnline()) {
return;
}
Player player = killer.getPlayer();
if (player == null) return;
spawnRedStain(player);
}
private void spawnRedStain(Player player) {
Location eyeLoc = player.getEyeLocation();
Vector direction = eyeLoc.getDirection();
World world = player.getWorld();
for (int i = 0; i < PARTICLE_COUNT; i++) {
double distance = 1.0 + (i * PARTICLE_SPACING);
Location particleLoc = eyeLoc.clone().add(direction.clone().multiply(distance));
particleLoc.setY(particleLoc.getY() - 0.5);
world.spawnParticle(
Particle.REDSTONE,
particleLoc,
1,
0, 0, 0,
0,
new Particle.DustOptions(org.bukkit.Color.RED, 1.0f)
);
}
world.spawnParticle(
Particle.DRIPPING_LAVA,
eyeLoc.clone().add(direction.clone().multiply(0.5)),
2,
0.1, 0.1, 0.1,
0
);
}
public void spawnAttackEffect(Location location) {
World world = location.getWorld();
if (world == null) return;
world.spawnParticle(
Particle.CRIT,
location,
20,
0.5, 0.5, 0.5,
0.1
);
world.spawnParticle(
Particle.REDSTONE,
location,
15,
0.3, 0.3, 0.3,
0,
new Particle.DustOptions(org.bukkit.Color.MAROON, 1.5f)
);
}
public void spawnLungeEffect(Player player) {
Location loc = player.getLocation();
World world = player.getWorld();
Vector direction = loc.getDirection();
for (int i = 0; i < 10; i++) {
Location particleLoc = loc.clone().add(direction.clone().multiply(i * 0.3));
world.spawnParticle(
Particle.SWEEP_ATTACK,
particleLoc,
1,
0.2, 0.2, 0.2,
0
);
}
}
}

View file

@ -0,0 +1,68 @@
package dev.loki.objective;
import dev.loki.config.GameConfig;
public class GeneratorRegression {
private final GameConfig config;
private static final double NORMAL_REGRESSION_PER_TICK = 0.25 / 20.0;
private static final double KICK_REGRESSION_PER_TICK = 2.5 / 20.0;
public GeneratorRegression(GameConfig config) {
this.config = config;
}
public void applyRegression(Generator generator) {
if (generator.isCompleted() || generator.isBeingRepaired()) {
return;
}
double rate = generator.wasKicked() ? getKickRegressionRate() : getNormalRegressionRate();
generator.removeProgress(rate);
}
public void onGeneratorKicked(Generator generator) {
generator.setKicked(true);
generator.setRegressionTicks(config.getKickDuration() * 20);
}
public void tick(Generator generator) {
if (!generator.isUnderRegression()) {
return;
}
applyRegression(generator);
generator.decrementRegression();
if (generator.getRegressionTicks() <= 0) {
generator.setKicked(false);
}
}
public void tickAll(GeneratorManager manager) {
for (Generator gen : manager.getAllGenerators()) {
if (!gen.isCompleted() && !gen.isBeingRepaired()) {
tick(gen);
}
}
}
private double getNormalRegressionRate() {
return config.getRegressionRate() / 20.0;
}
private double getKickRegressionRate() {
return config.getKickRegressionRate() / 20.0;
}
public static boolean shouldStartRegression(Generator generator) {
return !generator.isCompleted()
&& !generator.isBeingRepaired()
&& generator.getProgress() > 0;
}
public static double calculateRegressionLoss(double progress, int regressionTicks, boolean wasKicked) {
double rate = wasKicked ? KICK_REGRESSION_PER_TICK : NORMAL_REGRESSION_PER_TICK;
return Math.min(progress, rate * regressionTicks);
}
}