feat(gameplay): implement hook sabotage, generator kick, jump listener, and boss bar UI
- Add HookSabotage system for survivors to disable hooks temporarily - Add GeneratorKick killer ability to regress generator progress - Add PlayerJumpListener to track survivor jump actions - Add BossBarManager for displaying game state and objectives - Update generator regression logic to support killer kick mechanic - Update KillerController to integrate generator kick ability - Update PlayerInteractListener to handle new interaction types - Refactor game phases to use BossBarManager for UI updates - Update .gitignore to exclude compiled bin/ directory - Simplify PLAN.md documentation for easier maintenance
This commit is contained in:
parent
3d6204cc83
commit
89dc9eb00d
78 changed files with 2293 additions and 1210 deletions
|
|
@ -11,42 +11,42 @@ public class GameConfig {
|
|||
}
|
||||
|
||||
private void setDefaults() {
|
||||
// Lobby settings
|
||||
setDefault("lobby.min-players", 5);
|
||||
// Lobby
|
||||
setDefault("lobby.min-players", 4);
|
||||
setDefault("lobby.max-players", 5);
|
||||
setDefault("lobby.countdown-seconds", 60);
|
||||
setDefault("lobby.countdown-4-players", 45);
|
||||
setDefault("lobby.countdown-5-players", 15);
|
||||
setDefault("lobby.role-assign-delay", 5);
|
||||
setDefault("lobby.server-lobby-count", 3);
|
||||
setDefault("lobby.persist-lobbies", true);
|
||||
|
||||
// Generator settings
|
||||
// Players scale
|
||||
setDefault("players.survivor-scale", 1.0);
|
||||
setDefault("players.killer-scale", 1.5);
|
||||
|
||||
// Generators
|
||||
setDefault("generators.total-count", 7);
|
||||
setDefault("generators.required-count", 5);
|
||||
setDefault("generators.repair-seconds", 80);
|
||||
setDefault("generators.repair-seconds", 90);
|
||||
setDefault("generators.regression-rate", 0.25);
|
||||
setDefault("generators.kick-regression-rate", 2.5);
|
||||
setDefault("generators.kick-regression-percent", 20.0);
|
||||
setDefault("generators.kick-duration-seconds", 30);
|
||||
setDefault("generators.kick-cooldown-seconds", 30);
|
||||
setDefault("generators.kick-charge-seconds", 3);
|
||||
setDefault("generators.interaction-range", 3.0);
|
||||
|
||||
// Skill check settings (legacy - moved to skillcheck.yml)
|
||||
setDefault("skillcheck.zone-size", 0.15);
|
||||
setDefault("skillcheck.rotation-speed", 3.0);
|
||||
setDefault("skillcheck.success-bonus", 5.0);
|
||||
setDefault("skillcheck.fail-penalty", 10.0);
|
||||
|
||||
// Colors for UI (&#rrggbb format support)
|
||||
setDefault("colors.progress-bar-complete", "�FF00");
|
||||
setDefault("colors.progress-bar-incomplete", "&#FF0000");
|
||||
setDefault("colors.progress-bar-background", "񑘕");
|
||||
setDefault("colors.hp-healthy", "�FF00");
|
||||
setDefault("colors.hp-injured", "&#FFA500");
|
||||
setDefault("colors.hp-downed", "&#FF0000");
|
||||
setDefault("colors.hp-dead", "B0000");
|
||||
|
||||
// Hook settings
|
||||
// Hooks
|
||||
setDefault("hooks.stage1-seconds", 60);
|
||||
setDefault("hooks.stage2-seconds", 60);
|
||||
setDefault("hooks.struggle-interval", 2);
|
||||
setDefault("hooks.max-hooks", 3);
|
||||
setDefault("hooks.interaction-range", 3.0);
|
||||
setDefault("hooks.rescue-seconds", 3);
|
||||
setDefault("hooks.sabotage-seconds", 10);
|
||||
setDefault("hooks.sabotage-recovery-seconds", 60);
|
||||
|
||||
// Movement speeds (% of normal)
|
||||
// Movement
|
||||
setDefault("movement.killer", 115);
|
||||
setDefault("movement.killer-carry", 92);
|
||||
setDefault("movement.survivor-walk", 100);
|
||||
|
|
@ -55,30 +55,66 @@ public class GameConfig {
|
|||
setDefault("movement.exhaustion-duration", 3);
|
||||
setDefault("movement.exhaustion-cooldown", 5);
|
||||
|
||||
// Healing settings
|
||||
// Healing
|
||||
setDefault("healing.other-heal-seconds", 15);
|
||||
setDefault("healing.self-heal-seconds", 30);
|
||||
setDefault("healing.other-heal-seconds", 16);
|
||||
setDefault("healing.medkit-bonus", 0.5);
|
||||
setDefault("healing.interrupt-on-move", true);
|
||||
setDefault("healing.max-heals-per-match", 4);
|
||||
setDefault("healing.heal-range", 3.0);
|
||||
|
||||
// Killer settings
|
||||
// Carry / escape
|
||||
setDefault("carry.escape-jumps", 15);
|
||||
setDefault("carry.escape-speed-seconds", 3);
|
||||
setDefault("carry.jump-fill-percent", 6.67);
|
||||
|
||||
// Killer
|
||||
setDefault("killer.attack-cooldown", 2.5);
|
||||
setDefault("killer.attack-range", 3.0);
|
||||
setDefault("killer.pallet-stun-seconds", 2.5);
|
||||
setDefault("killer.pallet-stun-seconds", 2.0);
|
||||
setDefault("killer.pallet-break-seconds", 3.0);
|
||||
setDefault("killer.terror-radius", 32);
|
||||
setDefault("killer.pallet-interaction-range", 3.0);
|
||||
|
||||
// BossBar
|
||||
setDefault("bossbar.enabled", true);
|
||||
setDefault("bossbar.title", "<red>☠ МАНЬЯК РЯДОМ ☠</red>");
|
||||
setDefault("bossbar.color", "RED");
|
||||
setDefault("bossbar.style", "SOLID");
|
||||
setDefault("bossbar.appear-range", 32);
|
||||
setDefault("bossbar.full-range", 8);
|
||||
|
||||
// Window vault
|
||||
setDefault("window.vault-survivor-fast", 1.0);
|
||||
setDefault("window.vault-survivor-slow", 1.5);
|
||||
setDefault("window.vault-killer", 1.5);
|
||||
setDefault("window.vault-block-seconds", 15);
|
||||
|
||||
// Endgame
|
||||
setDefault("endgame.gate-open-seconds", 20);
|
||||
setDefault("endgame.collapse-seconds", 120);
|
||||
setDefault("endgame.chest-open-seconds", 3);
|
||||
setDefault("endgame.gate-interaction-range", 3.0);
|
||||
|
||||
// Killer notification
|
||||
setDefault("killer-notification.compass-duration-seconds", 5);
|
||||
|
||||
// Scoreboard
|
||||
setDefault("scoreboard.show-hearts", true);
|
||||
setDefault("scoreboard.heart-symbol", "♥");
|
||||
setDefault("scoreboard.color-healthy", "WHITE");
|
||||
setDefault("scoreboard.color-injured", "RED");
|
||||
setDefault("scoreboard.color-healing", "GREEN");
|
||||
setDefault("scoreboard.color-hooked", "DARK_RED");
|
||||
|
||||
// Colors for UI
|
||||
setDefault("colors.progress-bar-complete", "�FF00");
|
||||
setDefault("colors.progress-bar-incomplete", "&#FF0000");
|
||||
setDefault("colors.progress-bar-background", "񑘕");
|
||||
|
||||
// Hatch
|
||||
setDefault("hatch.min-survivors-for-open", 1);
|
||||
setDefault("hatch.require-more-gens-than-survivors", true);
|
||||
}
|
||||
|
||||
private void setDefault(String path, Object value) {
|
||||
|
|
@ -87,99 +123,130 @@ public class GameConfig {
|
|||
}
|
||||
}
|
||||
|
||||
public int getMinPlayers() {
|
||||
return config.getInt("lobby.min-players", 5);
|
||||
}
|
||||
// -------------------------------------------------------------------------
|
||||
// Lobby
|
||||
// -------------------------------------------------------------------------
|
||||
public int getMinPlayers() { return config.getInt("lobby.min-players", 4); }
|
||||
public int getMaxPlayers() { return config.getInt("lobby.max-players", 5); }
|
||||
public int getCountdown4Players() { return config.getInt("lobby.countdown-4-players", 45); }
|
||||
public int getCountdown5Players() { return config.getInt("lobby.countdown-5-players", 15); }
|
||||
/** @deprecated Use getCountdown4Players() / getCountdown5Players() */
|
||||
@Deprecated
|
||||
public int getLobbyCountdown() { return getCountdown4Players(); }
|
||||
public int getRoleAssignDelay() { return config.getInt("lobby.role-assign-delay", 5); }
|
||||
public int getServerLobbyCount() { return config.getInt("lobby.server-lobby-count", 3); }
|
||||
public boolean isPersistLobbies() { return config.getBoolean("lobby.persist-lobbies", true); }
|
||||
|
||||
public int getMaxPlayers() {
|
||||
return config.getInt("lobby.max-players", 5);
|
||||
}
|
||||
// -------------------------------------------------------------------------
|
||||
// Players
|
||||
// -------------------------------------------------------------------------
|
||||
public double getSurvivorScale() { return config.getDouble("players.survivor-scale", 1.0); }
|
||||
public double getKillerScale() { return config.getDouble("players.killer-scale", 1.5); }
|
||||
|
||||
public int getLobbyCountdown() {
|
||||
return config.getInt("lobby.countdown-seconds", 60);
|
||||
}
|
||||
// -------------------------------------------------------------------------
|
||||
// Generators
|
||||
// -------------------------------------------------------------------------
|
||||
public int getGeneratorTotal() { return config.getInt("generators.total-count", 7); }
|
||||
public int getGeneratorRequired() { return config.getInt("generators.required-count", 5); }
|
||||
public int getGeneratorRepairSeconds() { return config.getInt("generators.repair-seconds", 90); }
|
||||
public double getRegressionRate() { return config.getDouble("generators.regression-rate", 0.25); }
|
||||
public double getKickRegressionRate() { return config.getDouble("generators.kick-regression-rate", 2.5); }
|
||||
public double getKickRegressionPercent() { return config.getDouble("generators.kick-regression-percent", 20.0); }
|
||||
public int getKickDuration() { return config.getInt("generators.kick-duration-seconds", 30); }
|
||||
public int getKickCooldownSeconds() { return config.getInt("generators.kick-cooldown-seconds", 30); }
|
||||
public int getKickChargeSeconds() { return config.getInt("generators.kick-charge-seconds", 3); }
|
||||
public double getGeneratorInteractionRange() { return config.getDouble("generators.interaction-range", 3.0); }
|
||||
|
||||
public int getRoleAssignDelay() {
|
||||
return config.getInt("lobby.role-assign-delay", 5);
|
||||
}
|
||||
// -------------------------------------------------------------------------
|
||||
// Hooks
|
||||
// -------------------------------------------------------------------------
|
||||
public int getStage1Seconds() { return config.getInt("hooks.stage1-seconds", 60); }
|
||||
public int getStage2Seconds() { return config.getInt("hooks.stage2-seconds", 60); }
|
||||
public int getStruggleInterval() { return config.getInt("hooks.struggle-interval", 2); }
|
||||
public int getMaxHooks() { return config.getInt("hooks.max-hooks", 3); }
|
||||
public double getHookInteractionRange() { return config.getDouble("hooks.interaction-range", 3.0); }
|
||||
public int getRescueSeconds() { return config.getInt("hooks.rescue-seconds", 3); }
|
||||
public int getSabotageSeconds() { return config.getInt("hooks.sabotage-seconds", 10); }
|
||||
public int getSabotageRecoverySeconds() { return config.getInt("hooks.sabotage-recovery-seconds", 60); }
|
||||
|
||||
public int getGeneratorTotal() {
|
||||
return config.getInt("generators.total-count", 7);
|
||||
}
|
||||
// -------------------------------------------------------------------------
|
||||
// Movement
|
||||
// -------------------------------------------------------------------------
|
||||
public double getKillerSpeed() { return config.getDouble("movement.killer", 115) / 100.0; }
|
||||
public double getKillerCarrySpeed() { return config.getDouble("movement.killer-carry", 92) / 100.0; }
|
||||
public double getSurvivorWalkSpeed() { return config.getDouble("movement.survivor-walk", 100) / 100.0; }
|
||||
public double getSurvivorSprintSpeed() { return config.getDouble("movement.survivor-sprint", 150) / 100.0; }
|
||||
public double getSurvivorCrawlSpeed() { return config.getDouble("movement.survivor-crawl", 30) / 100.0; }
|
||||
public int getExhaustionDuration() { return config.getInt("movement.exhaustion-duration", 3); }
|
||||
public int getExhaustionCooldown() { return config.getInt("movement.exhaustion-cooldown", 5); }
|
||||
|
||||
public int getGeneratorRequired() {
|
||||
return config.getInt("generators.required-count", 5);
|
||||
}
|
||||
// -------------------------------------------------------------------------
|
||||
// Healing
|
||||
// -------------------------------------------------------------------------
|
||||
public int getOtherHealSeconds() { return config.getInt("healing.other-heal-seconds", 15); }
|
||||
public int getSelfHealSeconds() { return config.getInt("healing.self-heal-seconds", 30); }
|
||||
public double getMedkitBonus() { return config.getDouble("healing.medkit-bonus", 0.5); }
|
||||
public boolean isHealInterruptOnMove() { return config.getBoolean("healing.interrupt-on-move", true); }
|
||||
public int getMaxHealsPerMatch() { return config.getInt("healing.max-heals-per-match", 4); }
|
||||
public double getHealRange() { return config.getDouble("healing.heal-range", 3.0); }
|
||||
|
||||
public int getGeneratorRepairSeconds() {
|
||||
return config.getInt("generators.repair-seconds", 80);
|
||||
}
|
||||
// -------------------------------------------------------------------------
|
||||
// Carry / Escape
|
||||
// -------------------------------------------------------------------------
|
||||
public int getCarryEscapeJumps() { return config.getInt("carry.escape-jumps", 15); }
|
||||
public int getCarryEscapeSpeedSeconds() { return config.getInt("carry.escape-speed-seconds", 3); }
|
||||
public double getCarryJumpFillPercent() { return config.getDouble("carry.jump-fill-percent", 6.67); }
|
||||
|
||||
public double getRegressionRate() {
|
||||
return config.getDouble("generators.regression-rate", 0.25);
|
||||
}
|
||||
// -------------------------------------------------------------------------
|
||||
// Killer
|
||||
// -------------------------------------------------------------------------
|
||||
public int getAttackCooldown() { return (int)(config.getDouble("killer.attack-cooldown", 2.5) * 20); }
|
||||
public double getAttackRange() { return config.getDouble("killer.attack-range", 3.0); }
|
||||
public int getPalletStunTicks() { return (int)(config.getDouble("killer.pallet-stun-seconds", 2.0) * 20); }
|
||||
public int getPalletBreakTicks() { return (int)(config.getDouble("killer.pallet-break-seconds", 3.0) * 20); }
|
||||
public int getTerrorRadius() { return config.getInt("killer.terror-radius", 32); }
|
||||
public double getPalletInteractionRange() { return config.getDouble("killer.pallet-interaction-range", 3.0); }
|
||||
|
||||
public double getKickRegressionRate() {
|
||||
return config.getDouble("generators.kick-regression-rate", 2.5);
|
||||
}
|
||||
// -------------------------------------------------------------------------
|
||||
// BossBar
|
||||
// -------------------------------------------------------------------------
|
||||
public boolean isBossBarEnabled() { return config.getBoolean("bossbar.enabled", true); }
|
||||
public String getBossBarTitle() { return config.getString("bossbar.title", "<red>☠ МАНЬЯК РЯДОМ ☠</red>"); }
|
||||
public String getBossBarColor() { return config.getString("bossbar.color", "RED"); }
|
||||
public String getBossBarStyle() { return config.getString("bossbar.style", "SOLID"); }
|
||||
public int getBossBarAppearRange() { return config.getInt("bossbar.appear-range", 32); }
|
||||
public int getBossBarFullRange() { return config.getInt("bossbar.full-range", 8); }
|
||||
|
||||
public int getKickDuration() {
|
||||
return config.getInt("generators.kick-duration-seconds", 30);
|
||||
}
|
||||
// -------------------------------------------------------------------------
|
||||
// Window
|
||||
// -------------------------------------------------------------------------
|
||||
public int getVaultSurvivorFastTicks() { return (int)(config.getDouble("window.vault-survivor-fast", 1.0) * 20); }
|
||||
public int getVaultSurvivorSlowTicks() { return (int)(config.getDouble("window.vault-survivor-slow", 1.5) * 20); }
|
||||
public int getVaultKillerTicks() { return (int)(config.getDouble("window.vault-killer", 1.5) * 20); }
|
||||
public int getVaultBlockSeconds() { return config.getInt("window.vault-block-seconds", 15); }
|
||||
|
||||
public int getStage1Seconds() {
|
||||
return config.getInt("hooks.stage1-seconds", 60);
|
||||
}
|
||||
// -------------------------------------------------------------------------
|
||||
// Endgame
|
||||
// -------------------------------------------------------------------------
|
||||
public int getGateOpenSeconds() { return config.getInt("endgame.gate-open-seconds", 20); }
|
||||
public int getCollapseSeconds() { return config.getInt("endgame.collapse-seconds", 120); }
|
||||
public int getChestOpenSeconds() { return config.getInt("endgame.chest-open-seconds", 3); }
|
||||
public double getGateInteractionRange() { return config.getDouble("endgame.gate-interaction-range", 3.0); }
|
||||
|
||||
public int getStage2Seconds() {
|
||||
return config.getInt("hooks.stage2-seconds", 60);
|
||||
}
|
||||
// -------------------------------------------------------------------------
|
||||
// Killer notification
|
||||
// -------------------------------------------------------------------------
|
||||
public int getCompassDurationSeconds() { return config.getInt("killer-notification.compass-duration-seconds", 5); }
|
||||
|
||||
public int getMaxHooks() {
|
||||
return config.getInt("hooks.max-hooks", 3);
|
||||
}
|
||||
// -------------------------------------------------------------------------
|
||||
// Scoreboard
|
||||
// -------------------------------------------------------------------------
|
||||
public boolean isShowHearts() { return config.getBoolean("scoreboard.show-hearts", true); }
|
||||
public String getHeartSymbol() { return config.getString("scoreboard.heart-symbol", "♥"); }
|
||||
public String getColorHealthy() { return config.getString("scoreboard.color-healthy", "WHITE"); }
|
||||
public String getColorInjured() { return config.getString("scoreboard.color-injured", "RED"); }
|
||||
public String getColorHealing() { return config.getString("scoreboard.color-healing", "GREEN"); }
|
||||
public String getColorHooked() { return config.getString("scoreboard.color-hooked", "DARK_RED"); }
|
||||
|
||||
public double getKillerSpeed() {
|
||||
return config.getDouble("movement.killer", 115) / 100.0;
|
||||
}
|
||||
|
||||
public double getKillerCarrySpeed() {
|
||||
return config.getDouble("movement.killer-carry", 92) / 100.0;
|
||||
}
|
||||
|
||||
public double getSurvivorWalkSpeed() {
|
||||
return config.getDouble("movement.survivor-walk", 100) / 100.0;
|
||||
}
|
||||
|
||||
public double getSurvivorSprintSpeed() {
|
||||
return config.getDouble("movement.survivor-sprint", 150) / 100.0;
|
||||
}
|
||||
|
||||
public double getSurvivorCrawlSpeed() {
|
||||
return config.getDouble("movement.survivor-crawl", 30) / 100.0;
|
||||
}
|
||||
|
||||
public int getAttackCooldown() {
|
||||
return (int) (config.getDouble("killer.attack-cooldown", 2.5) * 20);
|
||||
}
|
||||
|
||||
public double getAttackRange() {
|
||||
return config.getDouble("killer.attack-range", 3.0);
|
||||
}
|
||||
|
||||
public int getPalletStunTicks() {
|
||||
return (int) (config.getDouble("killer.pallet-stun-seconds", 2.5) * 20);
|
||||
}
|
||||
|
||||
public int getPalletBreakTicks() {
|
||||
return (int) (config.getDouble("killer.pallet-break-seconds", 3.0) * 20);
|
||||
}
|
||||
|
||||
public int getTerrorRadius() {
|
||||
return config.getInt("killer.terror-radius", 32);
|
||||
}
|
||||
|
||||
public FileConfiguration getConfig() {
|
||||
return config;
|
||||
}
|
||||
public FileConfiguration getConfig() { return config; }
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue