
ZombieApocalypseSSS
ZombieApocalypseSSS is a comprehensive Minecraft plugin that transforms your server into a thrilling zombie survival apocalypse. Featuring advanced zombie AI, evolving variants, player infection mechanics, psychological horror elements, and dynamic events
1.6K
4
Список изменений
[4.5.2] — Bug-Fix Release
🔴 Critical Fixes
BUG-1 · Boss Zombie drops Diamond Armour on death
- File:
ZombieSpawnService.java—spawnBossZombie() - Root cause:
setArmorContents()was called without setting drop chances to 0. Bukkit's default drop chance is ~8.5%, so players could farm Diamond Helmet / Chestplate by killing the Boss. - Fix: Added explicit
setHelmetDropChance(0f),setChestplateDropChance(0f),setLeggingsDropChance(0f), andsetBootsDropChance(0f)after every armour assignment, including the custom-model-data head path.
BUG-2 · Boss HP inconsistent — evolveZombie() multiplier overridden
- File:
ZombieSpawnService.java—spawnBossZombie() - Root cause:
spawnCustomZombie()internally calledevolveZombie()which applied a tier health multiplier (up to ×2.5 for ABERRANT), butspawnBossZombie()then hard-reset the attribute toboss.healthconfig value, discarding the tier scaling entirely. - Fix:
spawnBossZombie()now setsbossHealthfirst, then callsevolveZombie()so the tier multiplier compounds on top of the intended base. Boss HP in late-game now scales correctly with the threat level.
🟡 Medium Fixes
BUG-3 · ABERRANT zombies appear ~35 days too early
- File:
ZombieEvolutionService.java—determineTier() - Root cause: The
elsebranch coveredthreat >= 30, but the class-level comment stated "Threat > 50: Aberrant possible". Players hit ABERRANT-tier enemies during Phase 3 (Day ~15) instead of Phase 5 (Day ~25+). - Fix: Inserted an explicit
threat < 50bracket (no ABERRANT, Mutated max) and moved ABERRANT tothreat >= 50only, matching the original design intent.
BUG-4 · /zapoc infect shows hardcoded "10m" regardless of config
- File:
ZombieApoc.java—onCommand()case"infect" - Root cause:
incubationTickswas read from config but immediately discarded; the player message used the literal string"10m". - Fix:
timeDisplayis now derived fromincubationTicks / 20seconds so the displayed time always reflects the actual configured value.
BUG-5 · ZombieBehaviorTask batch-skipping uses hashCode() % 2 (uneven distribution)
- File:
ZombieBehaviorTask.java—run() - Root cause:
UUID.hashCode()is a 32-bit hash with no uniformity guarantee. In practice this can result in 70 % of zombies processed on one tick and 30 % on the other, defeating the purpose of two-bucket batching. - Fix: Changed the modulus operand to
UUID.getLeastSignificantBits()which is a raw 64-bit random value from the UUID v4 spec, giving near-perfect 50/50 split.
BUG-6 · HallucinationListener double-registration on /zapoc reload
- File:
ZombieApoc.java—startTasks() - Root cause:
startTasks()checkedif (hallucinationListener == null)before creating a new instance, butcancelAllTasks()already set it tonull. In specific edge cases (e.g.psychological-horror.enabledtoggled via config between reloads) the old instance could survive unregistered yet the new instance would be registered on top. - Fix:
startTasks()now unconditionally callsHandlerList.unregisterAll()and nulls the field before constructing a freshHallucinationListener, making the lifecycle explicit and immune to ordering issues.
BUG-7 · WorldEventTask blood-moon maps leak UUID entries for unloaded worlds
- File:
WorldEventTask.java - Root cause:
bloodMoonStatesandbloodMoonRolledDayused world UUIDs as keys but never removed entries when a world was unloaded (e.g. on map rotation or/mv unload). Over time this created an unbounded set of stale entries. - Fix:
WorldEventTasknow implementsListenerand handlesWorldUnloadEventto remove both maps' entries for the unloaded world. The task is registered and unregistered as a listener instartTasks()/cancelAllTasks().
🟢 Minor Improvements
PERF-1 · ZombieBehaviorTask reads 7 YAML values every 10-tick cycle
- File:
ZombieBehaviorTask.java - Root cause:
moanEnabled,moanChance,moanVol,moanPitch,mutationEnabled,mutationInterval, andbreakingEnabledwere fetched fromFileConfigurationon every call torun(). - Fix: All seven values are now cached as class-level fields alongside the
existing sun / screamer caches and refreshed once every 100 ticks inside
reloadSunConfigCache().
PERF-2 · handleExplosive() reads explosive.power from YAML at explosion time
- File:
ZombieBehaviorTask.java - Fix: Added
cachedExplosivePowerfield, populated inreloadSunConfigCache().
PERF-3 · CampfireManager.isInsideSafeZone() reads check-radius from YAML per call
- File:
CampfireManager.java - Root cause:
plugin.getMechanicsConfig().getInt("campfires.check-radius", 100)was called on every invocation.isInsideSafeZone()is called once per second per online player fromPlayerStatusTask, making this a hot path. - Fix: Added
cachedCheckRadiusfield, initialised in the constructor and refreshed inreload().
DEPRECATION-1 · TurretListener used legacy ChatColor string API
- File:
TurretListener.java - Fix: All player messages converted to
net.kyori.adventure.text.ComponentusingNamedTextColorandTextDecoration, the standard approach on Paper 1.16+.
DEPRECATION-2 · ZombieApoc.sendActionBar() used BungeeCord spigot bridge
- File:
ZombieApoc.java - Fix: Replaced
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, ...)with the Paper-nativeplayer.sendActionBar(Component)call. Removed unusednet.md_5.bungee.api.*imports.
Метаданные
Канал релиза
Release
Номер версии
4.5.2
Загрузчики
BukkitPaperPurpurSpigot
Версии игры
1.21–1.21.11
Загрузок
237
Дата публикации
2 нед. назад
