Compare commits

..

No commits in common. "master" and "v1.0.2" have entirely different histories.

95 changed files with 1247 additions and 13205 deletions

View file

@ -1,38 +0,0 @@
on:
push:
tags:
- '*'
jobs:
build:
runs-on: docker
steps:
- name: checkout repository
uses: actions/checkout@v3
- name: make gradle wrapper executable
run: chmod +x ./gradlew
- name: set up jdk
run: |
INSTALL_DIR="/opt/java"
mkdir -p "$INSTALL_DIR"
JDK8_URL="https://cdn.azul.com/zulu/bin/zulu8.84.0.15-ca-jdk8.0.442-linux_x64.tar.gz"
JRE17_URL="https://cdn.azul.com/zulu/bin/zulu17.56.15-ca-jre17.0.14-linux_x64.tar.gz"
echo "Downloading JDK8 from $JDK8_URL"
curl -L "$JDK8_URL" | tar -xz -C "$INSTALL_DIR"
echo "Downloading JRE17 from $JRE17_URL"
curl -L "$JRE17_URL" | tar -xz -C "$INSTALL_DIR"
- name: build
run: JDK8=/opt/java/zulu8.84.0.15-ca-jdk8.0.442-linux_x64 JAVA_HOME=/opt/java/zulu17.56.15-ca-jre17.0.14-linux_x64 ./gradlew build
- name: capture build artifacts
uses: https://code.forgejo.org/forgejo/upload-artifact@v3
with:
name: Artifacts
path: 'build/libs'

4
.gitattributes vendored
View file

@ -1,4 +0,0 @@
gradlew* linguist-vendored
gradle/wrapper/* linguist-vendored
*.bat text eol=crlf

22
.github/workflows/build.yml vendored Normal file
View file

@ -0,0 +1,22 @@
name: Run Gradle Build
on: [push, pull_request]
jobs:
gradle:
runs-on: ubuntu-latest
steps:
- name: Checkout source
uses: actions/checkout@v3
- uses: actions/setup-java@v3
name: Setup Java
with:
distribution: temurin
java-version: 17
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: Execute Gradle build
run: ./gradlew build
- uses: actions/upload-artifact@v3
name: Upload built mod JAR
with:
name: mod-jar
path: build/libs/*.jar

View file

@ -0,0 +1,10 @@
name: "Validate Gradle Wrapper"
on: [push, pull_request]
jobs:
validation:
name: "Validation"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: gradle/wrapper-validation-action@v1

3
.gitignore vendored
View file

@ -1,3 +1,6 @@
.idea/
.vscode/
run/
build/
.gradle/

View file

@ -1,80 +1,19 @@
# zombies-utils
##### Download the latest release [here](https://github.com/Stachelbeere1248/zombies-utils/releases/latest)
Hello, I am currently working on this mod. More features will come. For now it has:
- An accurate timer + Automatic splitting
- Tracking of splits & segment PBs (with custom categories)
- SLA hud
- A chat macro
- Spawn-times HUD: visual, auditory, RL-mode
- Player Visibility
#### Disclaimers
- If you are using a Hypixel language other than the selected one the mod may not work entirely. Check config.
Disclaimers
- SST v1.15.0 by @Seosean might not be compatible. Use an older version if you want to use this mod. Compatiblity might be implemented at a later date.
- If you are using a Hypixel language other than english the mod may not work entirely. Use /lang en.
## For Users
The timer automatically splits every round. The PB/Segment recorder automatically distinguishes maps and difficulties,
but not player count.
### Config
- `Language`: The selected Hypixel language. Currently supports EN,FR,DE.
- ###### Timer:
- `Default Category`: The record-category to be selected when starting the game.
- `PB Announcements`: Whether to show **\*\*\*NEW PERSONAL BEST\*\*\*** on PB in summaries.
- ###### SST:
- `Enabled`: Enables / disables this feature.
- `Auditory`: A List of tick offsets that a sound should be played. Default (-40, -20, 0) means 2s and 1s in
advance, as well as on spawn.
- `RL pre-timing`: During RL mode, how much SST times sohuld be offsetted. Defaults to 1.4s earlier. Affects HUD as
well as auditory.
- `Truncate`: Whether to show passed rounds in the HUD.
- ###### SLA:
- `Enabled`: Whether the SLA HUD should automatically be shown when starting a game.
- `Truncate`: Whether inactive windows and rooms should be shown.
- ###### Player Visibility:
- `Enabled`: Whether to enable PlayerVisibility by default.
- `Range`: The range within which players are hidden while enabled.
- `Macro Message`: The Message to be sent when pressing the Chat Macro Key. Do NOT use "§" as symbol.
- `CPS Counter`: A simple CPS Counter which shows the amount of clicks within the last 20 gameticks.
The Timer automatically splits every round. The Personal-Best-recorder automatically distinguishes between maps and difficulties.
### Commands
- /category \<name> - Switches to the category called name. All recorded times are bound to its category. Tabcomplete
suggests already existing categories, but you can insert a new (clean) one as well.
- Examples:
- /category pistol_only
- /category no_doors_solo
- note: you do NOT need to make your own categories to seperate difficulties or map
- /sla \<off|map|quick|rotate|mirror|offset>
- /sla off - Disables the SLA hud
- /sla map \<de|bb|aa|p> - forcefully set the map
- /sla quick \<mogi_a|ghxula|ghxula-garden>
- useless for most players:
- /sla rotate - rotates all windows around the axis (0,y,0)
- /sla mirror \<x|z> - mirrors all windows along the plane (0,y,z) or (x,y,0)
- /sla offset \<x> \<y> \<z> - set an offset, allowing you to use sla on map-recreations, such as housings
- /zombiesutils \<timer>
- /zombiesutils timer \<kill|split>
- /zombiesutils timer kill - Stops the running timer completely
- /zombiesutils timer split \<round> - Splits as if \<round> was passed, not recommended to use as it might
create impossible PBs.
- /qz \<de|bb|aa|p> - sends you to a new game of Dead End, Bad Blood, Alien Arcadium or Prison
### Hotkeys
- Chat Macro: Sends the message specified in the config.
- RL Mode: Toggles usage of the rocket launcher mode spawn-time offset.
- Player Visibility: Toggles whether to show players that are within a 4 block radius.
- /runCategory \<name> - Switches to the category called name. All recorded times are bound to its category. Tabcomplete suggests already existing categories, but you can insert a new (clean) one as well.
- Examples:
- /runCategory pistol_only
- /runCategory casual
- default name: general
- /sla \<toggle|set|offset>
- /sla toggle - Enables / disables the overlay
- default state: disabled
- /sla set \<de|bb|aa> - forcefully set the map
- /sla offset \<x> \<y> \<z> - set an offset, allowing you to use sla on map-recreations, such as housings
### Extra
- Managing split-categories: In your game directory (aka `.minecraft`) is a folder called `zombies` which contains the
folder `splits`. You can simply rename or delete the folders inside `splits`, they represent your categories. You can
also edit your splits, the data is stored as a list of ticks inside the `MAP_DIFFICULTY.times` files, a simple text
editor (such as Notepad on Windows) should be able to edit it (UTF-16 encoded text). The other subfolder, runs, logs
all the splits for every run you play.
- Migration of split-category names: In your minecraft folder is a folder called "zombies". You can simply rename the sub-folders.

View file

@ -1,5 +1,3 @@
import org.apache.commons.lang3.SystemUtils
plugins {
idea
java
@ -10,12 +8,11 @@ plugins {
//Constants:
val baseGroup: String by project
val baseGroup = "com.github.stachelbeere1248.zombiesutils"
val mcVersion: String by project
val version: String by project
val mixinGroup = "$baseGroup.mixin"
val modid: String by project
val transformerFile = file("src/main/resources/accesstransformer.cfg")
// Toolchains:
java {
@ -29,26 +26,14 @@ loom {
"client" {
// If you don't want mixins, remove these lines
property("mixin.debug", "true")
property("asmhelper.verbose", "true")
arg("--tweakClass", "org.spongepowered.asm.launch.MixinTweaker")
}
}
runConfigs {
"client" {
if (SystemUtils.IS_OS_MAC_OSX) {
// This argument causes a crash on macOS
vmArgs.remove("-XstartOnFirstThread")
}
}
remove(getByName("server"))
}
forge {
pack200Provider.set(dev.architectury.pack200.java.Pack200Adapter())
// If you don't want mixins, remove this lines
mixinConfig("mixins.$modid.json")
if (transformerFile.exists()) {
println("Installing access transformer")
accessTransformer(transformerFile)
}
}
// If you don't want mixins, remove these lines
mixin {
@ -65,6 +50,8 @@ sourceSets.main {
repositories {
mavenCentral()
maven("https://repo.spongepowered.org/maven/")
// If you don't want to log in with your real minecraft account, remove this line
maven("https://pkgs.dev.azure.com/djtheredstoner/DevAuth/_packaging/public/maven/v1")
}
val shadowImpl: Configuration by configurations.creating {
@ -81,6 +68,10 @@ dependencies {
isTransitive = false
}
annotationProcessor("org.spongepowered:mixin:0.8.5-SNAPSHOT")
// If you don't want to log in with your real minecraft account, remove this line
runtimeOnly("me.djtheredstoner:DevAuth-forge-legacy:1.1.2")
}
// Tasks:
@ -89,7 +80,7 @@ tasks.withType(JavaCompile::class) {
options.encoding = "UTF-8"
}
tasks.withType(org.gradle.jvm.tasks.Jar::class) {
tasks.withType(Jar::class) {
archiveBaseName.set(modid)
manifest.attributes.run {
this["FMLCorePluginContainsFMLMod"] = "true"
@ -98,8 +89,6 @@ tasks.withType(org.gradle.jvm.tasks.Jar::class) {
// If you don't want mixins, remove these lines
this["TweakClass"] = "org.spongepowered.asm.launch.MixinTweaker"
this["MixinConfigs"] = "mixins.$modid.json"
if (transformerFile.exists())
this["FMLAT"] = "${modid}_at.cfg"
}
}
@ -107,13 +96,13 @@ tasks.processResources {
inputs.property("version", project.version)
inputs.property("mcversion", mcVersion)
inputs.property("modid", modid)
inputs.property("basePackage", baseGroup)
inputs.property("mixinGroup", mixinGroup)
filesMatching(listOf("mcmod.info", "mixins.$modid.json")) {
expand(inputs.properties)
}
rename("accesstransformer.cfg", "META-INF/${modid}_at.cfg")
rename("(.+_at.cfg)", "META-INF/$1")
}
@ -125,16 +114,16 @@ val remapJar by tasks.named<net.fabricmc.loom.task.RemapJarTask>("remapJar") {
tasks.jar {
archiveClassifier.set("without-deps")
destinationDirectory.set(layout.buildDirectory.dir("intermediates"))
destinationDirectory.set(layout.buildDirectory.dir("badjars"))
}
tasks.shadowJar {
destinationDirectory.set(layout.buildDirectory.dir("intermediates"))
archiveClassifier.set("non-obfuscated-with-deps")
destinationDirectory.set(layout.buildDirectory.dir("badjars"))
archiveClassifier.set("all-dev")
configurations = listOf(shadowImpl)
doLast {
configurations.forEach {
println("Copying dependencies into mod: ${it.files}")
println("Copying jars into mod: ${it.files}")
}
}

View file

@ -1,7 +1,6 @@
loom.platform=forge
org.gradle.jvmargs=-Xmx2g
baseGroup = xyz.stachel.zombiesutils
baseGroup = com.github.stachelbeere1248.zombiesutils
mcVersion = 1.8.9
modid = zombiesutils
version = 1.4.0
org.gradle.java.installations.fromEnv=JDK8,JRE17
version = 1.0.2

Binary file not shown.

View file

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

19
gradlew vendored
View file

@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@ -83,8 +83,7 @@ done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@ -145,7 +144,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
# shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
@ -153,7 +152,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@ -202,11 +201,11 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \

20
gradlew.bat vendored
View file

@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail

View file

@ -7,7 +7,7 @@ pluginManagement {
maven("https://maven.fabricmc.net")
maven("https://maven.minecraftforge.net/")
maven("https://repo.spongepowered.org/maven/")
maven("https://repo.essential.gg/repository/maven-releases/")
maven("https://repo.sk1er.club/repository/maven-releases/")
}
resolutionStrategy {
eachPlugin {

View file

@ -0,0 +1,48 @@
package com.github.stachelbeere1248.zombiesutils;
import com.github.stachelbeere1248.zombiesutils.commands.CategoryCommand;
import com.github.stachelbeere1248.zombiesutils.commands.SlaCommand;
import com.github.stachelbeere1248.zombiesutils.handlers.ChatHandler;
import com.github.stachelbeere1248.zombiesutils.handlers.TickHandler;
import com.github.stachelbeere1248.zombiesutils.render.RenderGameOverlayHandler;
import net.minecraftforge.client.ClientCommandHandler;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import org.apache.logging.log4j.Logger;
@Mod(modid = "zombiesutils", useMetadata = true, clientSideOnly = true)
public class ZombiesUtils {
private static ZombiesUtils instance;
private Configuration config;
private Logger logger;
public ZombiesUtils() {
instance = this;
}
public static ZombiesUtils getInstance() {
return instance;
}
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event) {
logger = event.getModLog();
config = new Configuration(event.getSuggestedConfigurationFile());
config.load();
}
@Mod.EventHandler
public void init(FMLInitializationEvent event) {
MinecraftForge.EVENT_BUS.register(new RenderGameOverlayHandler());
MinecraftForge.EVENT_BUS.register(new TickHandler());
MinecraftForge.EVENT_BUS.register(new ChatHandler());
ClientCommandHandler.instance.registerCommand(new CategoryCommand());
ClientCommandHandler.instance.registerCommand(new SlaCommand());
}
public Configuration getConfig() {
return config;
}
public Logger getLogger() {
return logger;
}
}

View file

@ -0,0 +1,44 @@
package com.github.stachelbeere1248.zombiesutils.commands;
import com.github.stachelbeere1248.zombiesutils.timer.Timer;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.Category;
import net.minecraft.command.CommandBase;
import net.minecraft.command.ICommandSender;
import net.minecraft.util.BlockPos;
import net.minecraft.util.ChatComponentText;
import java.util.Arrays;
import java.util.List;
public class CategoryCommand extends CommandBase {
public CategoryCommand () {
}
@Override
public String getCommandName() {
return "runCategory";
}
@Override
public String getCommandUsage(ICommandSender sender) {
return "runCategory <category-name>";
}
@Override
public void processCommand(ICommandSender sender, String[] args) {
if (args.length == 0) sender.addChatMessage(new ChatComponentText(getCommandUsage(sender)));
else {
Category.setSelectedCategory(args[0]);
Timer.getInstance().ifPresent(timer -> timer.setCategory(new Category()));
}
}
@Override
public List<String> addTabCompletionOptions(ICommandSender sender, String[] args, BlockPos blockPos) {
return Arrays.asList(Category.getCategories());
}
@Override
public boolean canCommandSenderUseCommand(ICommandSender sender) {
return true;
}
}

View file

@ -0,0 +1,87 @@
package com.github.stachelbeere1248.zombiesutils.commands;
import com.github.stachelbeere1248.zombiesutils.game.Map;
import com.github.stachelbeere1248.zombiesutils.game.windows.Sla;
import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.util.BlockPos;
import net.minecraft.util.ChatComponentText;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class SlaCommand extends CommandBase {
@Override
public String getCommandName() {
return "sla";
}
@Override
public String getCommandUsage(ICommandSender sender) {
return "/sla toggle\n/sla offset [x] [x] [x]\n/sla set <de|bb|aa>";
}
@Override
public void processCommand(ICommandSender sender, String @NotNull [] args) throws CommandException {
if (args.length == 0) sender.addChatMessage(new ChatComponentText(getCommandUsage(sender)));
else {
switch (args[0]) {
case "toggle":
Sla.toggle();
sender.addChatMessage(new ChatComponentText("SLA active: " + Sla.isEnabled()));
break;
case "offset":
if (args.length == 1) Sla.getInstance().ifPresent(Sla::resetOffset);
else if (args.length != 4) sender.addChatMessage(new ChatComponentText("/sla offset [x] [x] [x]"));
else {
try {
double x = Double.parseDouble(args[1]);
double y = Double.parseDouble(args[2]);
double z = Double.parseDouble(args[3]);
Sla.getInstance().ifPresent(sla -> sla.setOffset(new double[]{x, y, z}));
sender.addChatMessage(new ChatComponentText(String.format("Offset set to %s %s %s", x, y, z)));
} catch (NumberFormatException ignored) {
sender.addChatMessage(new ChatComponentText("Please input valid numbers"));
}
}
break;
case "set":
switch (args[1]) {
case "de":
new Sla(Map.DEAD_END);
break;
case "bb":
new Sla(Map.BAD_BLOOD);
break;
case "aa":
new Sla(Map.ALIEN_ARCADIUM);
break;
default:
sender.addChatMessage(new ChatComponentText("/sla set <de|bb|aa>"));
}
break;
default:
sender.addChatMessage(new ChatComponentText(getCommandUsage(sender)));
break;
}
}
}
@Override
public List<String> addTabCompletionOptions(ICommandSender sender, String @NotNull [] args, BlockPos blockPos) {
List<String> options = new ArrayList<String>();
if (args.length == 1) options.addAll(Arrays.asList("toggle","offset","set"));
else if ("offset".equals(args[0]) && (args.length == 2 || args.length == 3 || args.length == 4))
options.add("0");
else if ("set".equals(args[0])) options.addAll(Arrays.asList("de", "bb", "aa"));
return options;
}
@Override
public boolean canCommandSenderUseCommand(ICommandSender sender) {
return true;
}
}

View file

@ -0,0 +1,5 @@
package com.github.stachelbeere1248.zombiesutils.game;
public enum Difficulty {
NORMAL, HARD, RIP
}

View file

@ -0,0 +1,67 @@
package com.github.stachelbeere1248.zombiesutils.game;
import org.jetbrains.annotations.NotNull;
public class GameMode {
private static GameMode currentGameMode = null;
public static final GameMode DEAD_END_NORMAL = new GameMode(Map.DEAD_END), DEAD_END_HARD = new GameMode(Map.DEAD_END, Difficulty.HARD), DEAD_END_RIP = new GameMode(Map.DEAD_END, Difficulty.RIP);
public static final GameMode BAD_BLOOD_NORMAL = new GameMode(Map.BAD_BLOOD), BAD_BLOOD_HARD = new GameMode(Map.BAD_BLOOD, Difficulty.HARD), BAD_BLOOD_RIP = new GameMode(Map.BAD_BLOOD, Difficulty.RIP);
public static final GameMode ALIEN_ARCADIUM = new GameMode(Map.ALIEN_ARCADIUM);
private final Map map;
private final Difficulty difficulty;
private GameMode (@NotNull Map map, @NotNull Difficulty difficulty) {
this.map = map;
this.difficulty = difficulty;
}
private GameMode(@NotNull Map map) {
this.map = map;
this.difficulty = Difficulty.NORMAL;
}
public static void create(@NotNull Map map) {
switch (map) {
case DEAD_END: currentGameMode = DEAD_END_NORMAL; break;
case BAD_BLOOD: currentGameMode = BAD_BLOOD_NORMAL; break;
case ALIEN_ARCADIUM: currentGameMode = ALIEN_ARCADIUM; break;
}
}
public Map getMap() {
return map;
}
public Difficulty getDifficulty() {
return difficulty;
}
public void changeDifficulty(@NotNull Difficulty difficulty) {
switch (map) {
case ALIEN_ARCADIUM:
throw new RuntimeException("Achievement Get: Alien Arcadium Hard/RIP" + Map.ALIEN_ARCADIUM);
case DEAD_END:
switch (difficulty) {
case NORMAL: currentGameMode = DEAD_END_NORMAL; break;
case HARD: currentGameMode = DEAD_END_HARD; break;
case RIP: currentGameMode = DEAD_END_RIP; break;
}
break;
case BAD_BLOOD:
switch (difficulty) {
case NORMAL: currentGameMode = BAD_BLOOD_NORMAL; break;
case HARD: currentGameMode = BAD_BLOOD_HARD; break;
case RIP: currentGameMode = BAD_BLOOD_RIP; break;
} break;
}
}
public static GameMode getCurrentGameMode() {
return currentGameMode;
}
/**
* Call to invalidate {@link #currentGameMode} to trigger the garbage collector
*/
public static void drop() {
currentGameMode = null;
}
public boolean equals(@NotNull GameMode gameMode) {
return (this.getDifficulty() == gameMode.getDifficulty() && this.getMap() == gameMode.getMap());
}
}

View file

@ -0,0 +1,4 @@
package com.github.stachelbeere1248.zombiesutils.game;
public enum Map {
DEAD_END, BAD_BLOOD, ALIEN_ARCADIUM
}

View file

@ -0,0 +1,56 @@
package com.github.stachelbeere1248.zombiesutils.game;
import org.jetbrains.annotations.NotNull;
public class Waves {
private static final byte[][] deadEndWaveTimes = {{10,20},{10,20},{10,20,35},{10,20,35},{10,22,37},{10,22,44},{10,25,47},{10,25,50},{10,22,38},{10,24,45},{10,25,48},{10,25,50},{10,25,50},{10,25,45},{10,25,46},{10,24,47},{10,24,47},{10,24,47},{10,24,47},{10,24,49},{10,23,44},{10,23,45},{10,23,42},{10,23,43},{10,23,43},{10,23,36},{10,24,44},{10,24,42},{10,24,42},{10,24,45}},
badBloodWaveTimes = {{10,22},{10,22},{10,22},{10,22,34},{10,22,34},{10,22,34},{10,22,34},{10,22,34},{10,22,34},{10,22,34},{10,22,34},{10,22,34},{10,22,34},{10,22,34},{10,22,34},{10,22,34},{10,22,34},{10,22,34},{10,22,34},{10,22,34},{10,22,34},{10,22,34},{10,22,34},{10,22,34},{10,22,34},{10,24,38},{10,24,38},{10,22,34},{10,24,38},{10,22,34}},
alienArcadiumWaveTimes = {{10,13,16,19},{10,14,18,22},{10,13,16,19},{10,14,17,21,25,28},{10,14,18,22,26,30},{10,14,19,23,28,32},{10,15,19,23,27,31},{10,15,20,25,30,35},{10,14,19,23,28,32},{10,16,22,27,33,38},{10,16,21,27,32,38},{10,16,22,28,34,40},{10,16,22,28,34,40},{10,16,21,26,31,36},{10,17,24,31,38,46},{10,16,22,27,33,38},{10,14,19,23,28,32},{10,14,19,23,28,32},{10,14,18,22,26,30},{10,15,21,26,31,36},{10,14,19,23,28,32},{10,14,19,23,28,34},{10,14,18,22,26,30},{10,14,19,23,28,32},{10},{10,23,36},{10,22,34},{10,20,30},{10,24,38},{10,22,34},{10,22,34},{10,21,32},{10,22,34},{10,22,34},{10},{10,22,34},{10,20,31},{10,22,34},{10,22,34},{10,22,34,37,45},{10,21,32},{10,22,34},{10,13,22,25,34,37},{10,22,34},{10,22,34,35},{10,21,32,35},{10,20,30},{10,20,30,33},{10,21,32},{10,22,34,37},{10,20,30,33},{10,22,34,37},{10,22,34,37},{10,20,32,35,39},{10,16,22,28,34,40},{10,14,18},{10,14,18},{10,22,34,37,38},{10,14,18,22,26,30},{10,20,30,33},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,27,32},{10,14,18,22,27,32},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{10,14,18,22,26,30},{5},{5},{5},{5},{5}}
;
private static final short[] deadEndRoundTimesSum = {0,20,40,75,110,147,191,238,288,326,371,419,469,519,564,610,657,704,751,798,847,891,936,978,1021,1064,1100,1144,1186,1228,1273},
badBloodRoundTimesSum = {0,22,44,66,100,134,168,202,236,270,304,338,372,406,440,474,508,542,576,610,644,678,712,746,780,814,852,890,924,962,996},
alienArcadiumRoundTimesSum = {0,19,41,60,88,118,150,181,216,248,286,324,364,404,440,486,524,556,588,618,654,686,720,750,782,792,828,862,892,930,964,998,1030,1064,1098,1108,1142,1173,1207,1241,1286,1318,1352,1389,1423,1458,1493,1523,1556,1588,1625,1658,1695,1732,1771,1811,1829,1847,1885,1915,1948,1978,2008,2038,2068,2098,2128,2158,2188,2218,2248,2278,2308,2338,2368,2400,2432,2462,2492,2522,2552,2582,2612,2642,2672,2702,2732,2762,2792,2822,2852,2882,2912,2942,2972,3002,3032,3062,3092,3122,3152,3157,3162,3167,3172,3177}
;
public static byte[] get(@NotNull Map map, byte round) {
byte[] waves;
switch (map) {
case DEAD_END:
waves = deadEndWaveTimes[round - 1];
break;
case BAD_BLOOD:
waves = badBloodWaveTimes[round - 1];
break;
case ALIEN_ARCADIUM:
waves = alienArcadiumWaveTimes[round - 1];
break;
default:
throw new IllegalStateException("Unexpected value: " + map);
}
return waves;
}
public static short getSum(@NotNull Map map, byte round) {
short sum;
switch (map) {
case DEAD_END:
sum = deadEndRoundTimesSum[round - 1];
break;
case BAD_BLOOD:
sum = badBloodRoundTimesSum[round - 1];
break;
case ALIEN_ARCADIUM:
sum = alienArcadiumRoundTimesSum[round - 1];
break;
default:
throw new IllegalStateException("Unexpected value: " + map);
}
return sum;
}
public static byte getLastWave(@NotNull Map map, byte round) {
byte[] aByte = get(map, round);
return aByte[aByte.length-1];
}
}

View file

@ -0,0 +1,161 @@
package com.github.stachelbeere1248.zombiesutils.game.windows;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
public class Room {
private final Window[] windows;
private final String alias;
private int activeWindowCount;
public Room(String alias, Window[] windows) {
this.windows = windows;
this.alias = alias;
}
public String getAlias() {
return alias;
}
public Window[] getWindows() {
return windows;
}
@Contract(" -> new")
public static Room @NotNull [] getDE() {
return new Room[]{
new Room("Alley", new Window[]{
new Window(1,13,138,63),
new Window(2,9,138,87),
new Window(3,79,140,17),
new Window(4,85,140,59),
}),
new Room("Office", new Window[]{
new Window(1,85,152,53),
new Window(2,105,152,63),
new Window(3,115,152,129),
}),
new Room("Hotel", new Window[]{
new Window(1,1,136,93),
new Window(2,-19,136,29),
new Window(3,51,138,-7),
new Window(4,53,138,7),
new Window(5,-7,152,-43),
new Window(6,51,152,-11),
}),
new Room("Apartments", new Window[]{
new Window(1,39,152,19),
new Window(2,-31,152,31),
new Window(3,-27,152,103),
new Window(4,-9,152,125),
}),
new Room("Power Station", new Window[]{
new Window(1,7,166,125),
new Window(2,-5,166,65),
new Window(3,-11,136,133),
}),
new Room("Rooftop", new Window[]{
new Window(1,-31,166,129),
new Window(2,-27,166,61),
new Window(3,-99,166,77),
new Window(4,-75,166,51),
}),
new Room("Gallery", new Window[]{
new Window(1,45,152,155),
new Window(2,61,152,109),
new Window(3,31,152,131),
}),
new Room("Garden", new Window[]{
new Window(1,1,136,-33),
new Window(2,49,136,-67),
new Window(3,69,136,-33),
})
};
}
@Contract(" -> new")
public static Room @NotNull [] getBB() {
return new Room[]{
new Room("Courtyard", new Window[]{
new Window(1,49,138,-37),
new Window(2,61,138,21),
new Window(3,39,138,41),
new Window(4,25,138,-35),
}),
new Room("Mansion", new Window[]{
new Window(1,1,148,-35),
new Window(2,1,148,37),
new Window(3,-25,146,57),
}),
new Room("Library", new Window[]{
new Window(1,3,148,-89),
new Window(2,-41,148,-59),
new Window(3,-81,148,-61),
new Window(4,-79,148,-115),
new Window(5,-109,148,-93),
new Window(6,-107,148,-67),
}),
new Room("Dungeon", new Window[]{
new Window(1,-57,136,-69),
new Window(2,-73,136,-23),
new Window(3,-19,136,-37),
new Window(4,-19,136,-45),
new Window(5,-21,136,-99),
}),
new Room("Crypts", new Window[]{
new Window(1,-7,136,-5),
new Window(2,-31,136,1),
new Window(3,-57,136,41),
}),
new Room("Graveyard", new Window[]{
new Window(1,-13,136,67),
new Window(2,-71,136,63),
new Window(3,-33,136,101),
}),
new Room("Balcony", new Window[]{
new Window(1,-83,136,55),
new Window(2,-107,144,25),
new Window(3,-113,148,5),
new Window(4,-65,148,-37),
}),
new Room("Great Hall", new Window[]{
new Window(1,-39,148,-27),
new Window(2,-63,152,31),
new Window(3,-55,148,31),
})
};
}
@Contract(" -> new")
public static Room @NotNull [] getAA() {
return new Room[]{
new Room("Park Entrance", new Window[]{
new Window(1,13,144,63),
new Window(2,-21,144,-11),
new Window(3,-43,144,21),
new Window(4,-45,144,31),
new Window(5,45,144,27),
}),
new Room("Roller Coaster", new Window[]{
new Window(1,-57,144,55),
new Window(2,-25,144,79),
}),
new Room("Ferris Wheel", new Window[]{
new Window(1,35,144,89),
new Window(2,55,144,63),
}),
new Room("Bumper Cars", new Window[]{
new Window(1,67,146,-3),
new Window(2,45,146,-27),
})
};
}
public void increaseActiveWindowCount() {
this.activeWindowCount++;
}
public void resetActiveWindowCount() {
this.activeWindowCount = 0;
}
public int getActiveWindowCount() {
return activeWindowCount;
}
}

View file

@ -0,0 +1,76 @@
package com.github.stachelbeere1248.zombiesutils.game.windows;
import com.github.stachelbeere1248.zombiesutils.game.Map;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Optional;
public class Sla {
private static Sla instance = null;
private static boolean enabled = false;
private final double[] offset = new double[3];
private final Room[] rooms;
public Sla(@NotNull Map map) {
switch (map) {
case DEAD_END: this.rooms = Room.getDE(); break;
case BAD_BLOOD: this.rooms = Room.getBB(); break;
case ALIEN_ARCADIUM: this.rooms = Room.getAA(); break;
default: throw new IllegalStateException("Unexpected value: " + map);
}
instance = this;
}
public void refreshActives() {
final EntityPlayerSP player = Minecraft.getMinecraft().thePlayer;
final double[] playerCoords = {
player.posX + offset[0],
player.posY + offset[1],
player.posZ + offset[2]
};
for (Room room: rooms
) {
room.resetActiveWindowCount();
for (Window window: room.getWindows()
) {
double distanceDoubledThenSquared = 0;
for (int i = 0; i < 3; i++) {
distanceDoubledThenSquared += ((playerCoords[i]*2 - window.getXYZ()[i]) * (playerCoords[i]*2 - window.getXYZ()[i]));
}
// (2x)² + (2y)² + (2z)² = 4 (x²+y²+z²)
if (distanceDoubledThenSquared < 10000) {
window.setActive(true);
room.increaseActiveWindowCount();
} else window.setActive(false);
}
}
}
public static Optional<Sla> getInstance() {
return Optional.ofNullable(instance);
}
public static void drop() {
instance = null;
}
public Room[] getRooms() {
return rooms;
}
public static boolean isEnabled() {
return enabled;
}
public static void toggle() {
Sla.enabled = !Sla.enabled;
}
public void resetOffset() {
Arrays.fill(this.offset, 0);
}
public void setOffset(double[] offset) {
System.arraycopy(offset, 0, this.offset, 0, 3);
}
}

View file

@ -0,0 +1,26 @@
package com.github.stachelbeere1248.zombiesutils.game.windows;
public class Window {
private final short[] xyz = new short[3];
private final int alias;
private boolean isActive;
public Window(int alias, int x, int y, int z) {
this.alias = alias;
xyz[0] = (short) x; xyz[1] = (short) y; xyz[2] = (short) z;
}
public int getAlias() {
return alias;
}
public short[] getXYZ() {
return xyz;
}
public boolean isActive() {
return isActive;
}
public void setActive(boolean active) {
isActive = active;
}
}

View file

@ -0,0 +1,34 @@
package com.github.stachelbeere1248.zombiesutils.handlers;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.game.Difficulty;
import com.github.stachelbeere1248.zombiesutils.game.GameMode;
import net.minecraftforge.client.event.ClientChatReceivedEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import java.util.regex.Pattern;
public class ChatHandler {
public ChatHandler () {
}
private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("§[0-9A-FK-ORZ]", Pattern.CASE_INSENSITIVE);
@SubscribeEvent
public void difficultyChange(ClientChatReceivedEvent event) {
String message = STRIP_COLOR_PATTERN.matcher(event.message.getUnformattedText()).replaceAll("").trim();
GameMode gameMode = GameMode.getCurrentGameMode();
if (message.contains(":")) return;
if (gameMode == null) return;
if (message.contains("Hard Difficulty") || message.contains("困难") || message.contains("困難")) {
gameMode.changeDifficulty(Difficulty.HARD);
ZombiesUtils.getInstance().getLogger().debug("Changed to Hard");
} else if (message.contains("RIP Difficulty") || message.contains("安息") || message.contains("RIP")) {
gameMode.changeDifficulty(Difficulty.RIP);
ZombiesUtils.getInstance().getLogger().debug("Changed to RIP");
}
}
}

View file

@ -1,18 +1,13 @@
package com.github.stachelbeere1248.zombiesutils.handlers;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.game.waves.WaveTiming;
import com.github.stachelbeere1248.zombiesutils.utils.Scoreboard;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import org.jetbrains.annotations.NotNull;
public class TickHandler {
@SubscribeEvent
public void onTick(TickEvent.@NotNull ClientTickEvent event) {
public void onTick(TickEvent.ClientTickEvent event) {
if (event.phase == TickEvent.Phase.START) return;
Scoreboard.refresh();
WaveTiming.onTick();
ZombiesUtils.getInstance().getHandlers().getRenderer().tick();
}
}

View file

@ -0,0 +1,87 @@
package com.github.stachelbeere1248.zombiesutils.mixin;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.game.GameMode;
import com.github.stachelbeere1248.zombiesutils.timer.Timer;
import com.github.stachelbeere1248.zombiesutils.utils.Scoreboard;
import net.minecraft.client.network.NetHandlerPlayClient;
import net.minecraft.network.play.server.S29PacketSoundEffect;
import net.minecraft.network.play.server.S45PacketTitle;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(NetHandlerPlayClient.class)
public class MixinNetHandlerPlayClient {
public MixinNetHandlerPlayClient() {}
@Unique
private boolean zombies_utils$alienUfoOpened;
@Inject(method = "handleSoundEffect", at = @At(value = "HEAD"))
private void handleSound(S29PacketSoundEffect packetIn, CallbackInfo ci) {
zombies_utils$handleSound(packetIn);
}
@Inject(method = "handleTitle", at = @At(value = "HEAD"))
private void handleTitle(S45PacketTitle packetIn, CallbackInfo ci) {
zombies_utils$handleTitle(packetIn);
}
@Unique
private void zombies_utils$handleSound(@NotNull S29PacketSoundEffect packet) {
if (!Scoreboard.isZombies()) return;
String soundEffect = packet.getSoundName();
if (!(
soundEffect.equals("mob.wither.spawn")
|| (soundEffect.equals("mob.guardian.curse") && !zombies_utils$alienUfoOpened)
)) return;
zombies_utils$alienUfoOpened = soundEffect.equals("mob.guardian.curse");
if (!Timer.getInstance().isPresent()) {
ZombiesUtils.getInstance().getLogger().info("Attempting creation of new timer");
new Timer(
Scoreboard.getServerNumber().orElseThrow(() -> new RuntimeException("cannot figure out servernumber")),
Scoreboard.getMap().orElseThrow(() -> new RuntimeException("cannot figure out map"))
);
} else {
Timer timer = Timer.getInstance().get();
if (timer.equalsServerOrNull(Scoreboard.getServerNumber().orElse(null))) timer.split(Scoreboard.getRound());
else {
ZombiesUtils.getInstance().getLogger().info("Attempting creation of new timer");
//also kills the previous timer using the garbage collector
new Timer(
Scoreboard.getServerNumber().orElseThrow(() -> new RuntimeException("cannot figure out servernumber")),
Scoreboard.getMap().orElseThrow(() -> new RuntimeException("cannot figure out map"))
);
}
}
}
@Unique
private void zombies_utils$handleTitle(S45PacketTitle packet) {
if (packet.getType() != S45PacketTitle.Type.TITLE) return;
if (!Scoreboard.isZombies()) return;
final String message = packet.getMessage().getUnformattedText().trim();
if (message.equals("\u00a7aYou Win!")) {
switch (GameMode.getCurrentGameMode().getMap()) {
case DEAD_END: case BAD_BLOOD:
Timer.getInstance().ifPresent(timer -> {
timer.split((byte) 30);
Timer.dropInstances();
});
break;
case ALIEN_ARCADIUM:
Timer.getInstance().ifPresent(timer -> {
timer.split((byte) 105);
Timer.dropInstances();
});
break;
}
} else if (message.equals("\u00a7cGame Over!")) {
Timer.dropInstances();
} else {
ZombiesUtils.getInstance().getLogger().debug(message);
}
}
}

View file

@ -0,0 +1,57 @@
package com.github.stachelbeere1248.zombiesutils.render;
import com.github.stachelbeere1248.zombiesutils.game.windows.Room;
import com.github.stachelbeere1248.zombiesutils.game.windows.Sla;
import com.github.stachelbeere1248.zombiesutils.timer.Timer;
import com.github.stachelbeere1248.zombiesutils.utils.Scoreboard;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
public class RenderGameOverlayHandler {
private final FontRenderer fontRenderer;
public RenderGameOverlayHandler() {
this.fontRenderer = Objects.requireNonNull(Minecraft.getMinecraft().fontRendererObj, "FontRenderer must not be null!");
}
@SubscribeEvent
public void onRenderGameOverlay(RenderGameOverlayEvent.Post event) {
if (event.type != RenderGameOverlayEvent.ElementType.TEXT) return;
Timer.getInstance().ifPresent(timer -> renderTime(timer.roundTime()));
if (Sla.isEnabled()) Sla.getInstance().ifPresent(sla -> {
sla.refreshActives();
renderSla(sla.getRooms());
});
}
private void renderTime(long timerTicks) {
if (!Scoreboard.isZombies()) return;
long minutesPart = (timerTicks*50) / 60000;
long secondsPart = ((timerTicks*50) % 60000) / 1000;
long tenthSecondsPart = ((timerTicks*50) % 1000) / 100;
String time = String.format("%d:%02d.%d", minutesPart, secondsPart, tenthSecondsPart);
int width = fontRenderer.getStringWidth(time);
ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
int screenWidth = scaledResolution.getScaledWidth();
int screenHeight = scaledResolution.getScaledHeight();
final int color = 0xFFFFFF;
fontRenderer.drawStringWithShadow(time, screenWidth - width, screenHeight - fontRenderer.FONT_HEIGHT, color);
}
private void renderSla(Room @NotNull [] rooms) {
int y = 0;
for (Room room: rooms) {
int actives = room.getActiveWindowCount();
if (actives == 0) continue;
String roomString = String.format("%s: %x",room.getAlias(), actives);
fontRenderer.drawStringWithShadow(roomString,1,1+y*fontRenderer.FONT_HEIGHT,0xFFFFFF);
y++;
}
}
}

View file

@ -0,0 +1,86 @@
package com.github.stachelbeere1248.zombiesutils.timer;
import com.github.stachelbeere1248.zombiesutils.game.GameMode;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.Category;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.TimesFile;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ChatComponentText;
import org.jetbrains.annotations.NotNull;
public class RecordManager {
public static void compareSegment(byte round, short roundTime, @NotNull Category category) {
sendBar();
TimesFile timesFile = category.getByGameMode(GameMode.getCurrentGameMode());
short bestSegment = timesFile.getBestSegment(round);
if (bestSegment == (short) 0) {
timesFile.setBestSegment(round, roundTime);
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
"\u00a7l\u00a7e Category: " + category.getName() + " - ***" + "\u00a7l\u00a76 NEW BEST SEGMENT! " + "\u00a7l\u00a7e***"
));
final String timeString = formattedTime(roundTime);
final String message = "\u00a7cRound " + round + "\u00a7e took \u00a7a" + timeString + "\u00a7e!";
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(message));
} else {
if (roundTime<bestSegment) {
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
"\u00a7l\u00a7e Category: " + category.getName() + " - ***" + "\u00a7l\u00a76 NEW BEST SEGMENT! " + "\u00a7l\u00a7e***"
));
timesFile.setBestSegment(round, roundTime);
}
final String timeString = formattedTime(roundTime);
final String message = "\u00a7cRound " + round + "\u00a7e took \u00a7a" + timeString + " \u00a79" + formattedDelta(roundTime,bestSegment);
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(message));
}
sendBar();
}
public static void compareBest(byte round, int gameTime, @NotNull Category category) {
sendBar();
TimesFile timesFile = category.getByGameMode(GameMode.getCurrentGameMode());
int personalBest = timesFile.getPersonalBest(round);
if (personalBest == 0) {
timesFile.setPersonalBest(round, gameTime);
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
"\u00a7l\u00a7e Category: " + category.getName() + " - ***" + "\u00a7l\u00a76 NEW PERSONAL BEST! " + "\u00a7l\u00a7e***"
));
final String timeString = formattedTime(gameTime);
final String message = "\u00a7cRound " + round + "\u00a7e finished at \u00a7a" + timeString + "\u00a7e!";
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(message));
} else {
if (gameTime<personalBest) {
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
"\u00a7l\u00a7e Category: " + category.getName() + " - ***" + "\u00a7l\u00a76 NEW PERSONAL BEST! " + "\u00a7l\u00a7e***"
));
timesFile.setPersonalBest(round, gameTime);
}
final String timeString = formattedTime(gameTime);
final String message = "\u00a7cRound " + round + "\u00a7e finished at \u00a7a" + timeString + " \u00a79" + formattedDelta(gameTime, personalBest);
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(message));
}
sendBar();
}
private static String formattedTime(int gameTime) {
return String.format("%d:%02d.%d",
(gameTime *50) / 60000,
((gameTime *50) % 60000) / 1000,
((gameTime *50) % 1000) / 100
);
}
private static String formattedDelta(int newTime, int prevTime) {
double delta = (double) (newTime - prevTime) / 20;
if (delta<0) {
return String.valueOf(delta);
} else return ("+" + delta);
}
private static void sendBar() {
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
"\u00a7l\u00a7a▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬"
));
}
}

View file

@ -0,0 +1,95 @@
package com.github.stachelbeere1248.zombiesutils.timer;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.game.GameMode;
import com.github.stachelbeere1248.zombiesutils.game.Map;
import com.github.stachelbeere1248.zombiesutils.game.windows.Sla;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.Category;
import net.minecraft.client.Minecraft;
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
public class Timer {
private static Timer instance;
private final long savedTotalWorldTime;
private int passedRoundsTickSum = 0;
private final String serverNumber;
public Category category;
private boolean pbTracking = false;
private byte dontDupeSplitPlease = 0;
/**
* Constructs a timer and saves it to {@link #instance}.
* @param serverNumber The game's server the timer should be bound to.
* @param map The map the timer should be started for.
*/
public Timer (@NotNull String serverNumber, @NotNull Map map) {
instance = this;
savedTotalWorldTime = getCurrentTotalWorldTime();
if (!serverNumber.trim().isEmpty()) this.serverNumber = serverNumber.trim();
else throw new RuntimeException("invalid servernumber");
this.category = new Category();
GameMode.create(map);
new Sla(map);
}
/**
* The main splitting function.
* Cancels on the second occurring sound-effect, important for {@link RecordManager} to not override values incorrectly.
* @param passedRound The round that has been passed.
*/
public void split(byte passedRound) {
if (dontDupeSplitPlease == passedRound) {
ZombiesUtils.getInstance().getLogger().debug("SPLIT CANCELLED");
return;
}
if (passedRound == (byte) 1) pbTracking = true;
final int gameTime = gameTime();
final short roundTime = (short) (gameTime - passedRoundsTickSum);
ZombiesUtils.getInstance().getLogger().debug("Passed round: " + passedRound);
RecordManager.compareSegment(passedRound, roundTime, category);
if (pbTracking) RecordManager.compareBest(passedRound, gameTime, category);
passedRoundsTickSum = gameTime;
dontDupeSplitPlease = passedRound;
}
private long getCurrentTotalWorldTime() {
if (Minecraft.getMinecraft() == null) return 0;
if (Minecraft.getMinecraft().theWorld == null) return 0;
return Minecraft.getMinecraft().theWorld.getTotalWorldTime();
}
public int gameTime() {
return (int) (getCurrentTotalWorldTime() - savedTotalWorldTime);
}
public short roundTime() {
return (short) (gameTime() - passedRoundsTickSum);
}
public boolean equalsServerOrNull(String serverNumber) {
return (serverNumber == null || serverNumber.equals(this.serverNumber) || serverNumber.isEmpty());
}
public void setCategory(Category category) {
this.category = category;
}
public static Optional<Timer> getInstance() {
return Optional.ofNullable(instance);
}
/**
* Call to invalidate {@link #instance} to trigger the garbage collector
*/
public static void dropInstances() {
instance = null;
GameMode.drop();
Sla.drop();
}
}

View file

@ -0,0 +1,53 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder;
import com.github.stachelbeere1248.zombiesutils.game.GameMode;
import com.github.stachelbeere1248.zombiesutils.timer.Timer;
import org.jetbrains.annotations.NotNull;
import java.io.File;
public class Category {
private static String selectedCategory = "general"; // read from config ?
public final TimesFile[] timesFiles = new TimesFile[7];
private final String name;
public Category() {
timesFiles[0] = new TimesFile(selectedCategory, GameMode.DEAD_END_NORMAL);
timesFiles[1] = new TimesFile(selectedCategory, GameMode.DEAD_END_HARD);
timesFiles[2] = new TimesFile(selectedCategory, GameMode.DEAD_END_RIP);
timesFiles[3] = new TimesFile(selectedCategory, GameMode.BAD_BLOOD_NORMAL);
timesFiles[4] = new TimesFile(selectedCategory, GameMode.BAD_BLOOD_HARD);
timesFiles[5] = new TimesFile(selectedCategory, GameMode.BAD_BLOOD_RIP);
timesFiles[6] = new TimesFile(selectedCategory, GameMode.ALIEN_ARCADIUM);
name = selectedCategory;
}
public TimesFile getByGameMode(@NotNull GameMode gameMode) {
if (gameMode.equals(GameMode.DEAD_END_NORMAL)) return timesFiles[0];
if (gameMode.equals(GameMode.DEAD_END_HARD)) return timesFiles[1];
if (gameMode.equals(GameMode.DEAD_END_RIP)) return timesFiles[2];
if (gameMode.equals(GameMode.BAD_BLOOD_NORMAL)) return timesFiles[3];
if (gameMode.equals(GameMode.BAD_BLOOD_HARD)) return timesFiles[4];
if (gameMode.equals(GameMode.BAD_BLOOD_RIP)) return timesFiles[5];
if (gameMode.equals(GameMode.ALIEN_ARCADIUM)) return timesFiles[6];
throw new IllegalStateException("Unexpected value: " + gameMode);
}
public static void setSelectedCategory(String selectedCategory) {
Category.selectedCategory = selectedCategory;
if (!Timer.getInstance().isPresent()) return;
Timer.getInstance().get().category = new Category();
}
public static String[] getCategories() {
File dir = new File("zombies");
if (dir.isDirectory()) return dir.list();
else return new String[0];
}
public String getName() {
return name;
}
}

View file

@ -0,0 +1,39 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder;
import com.github.stachelbeere1248.zombiesutils.game.Map;
import com.google.gson.Gson;
import java.util.Arrays;
public class FileData{
private final short[] bestSegments; //in ticks, max ~27 min
private final int[] personalBests; //in ticks,
public FileData(Map map) {
if (map == Map.ALIEN_ARCADIUM) {
bestSegments = new short[105];
personalBests = new int[105];
} else {
bestSegments = new short[30];
personalBests = new int[30];
}
Arrays.fill(bestSegments, (short) 0);
Arrays.fill(personalBests, 0);
}
String getAsJsonString() {
Gson gson = new Gson();
return gson.toJson(this, FileData.class);
}
public short getBestSegment(int index) {
return bestSegments[index];
}
public int getPersonalBest(int index) {
return personalBests[index];
}
void setBestSegment(int index, short ticks) {
bestSegments[index] = ticks;
}
void setPersonalBest(int index, int ticks) {
personalBests[index] = ticks;
}
}

View file

@ -0,0 +1,54 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder;
import com.google.gson.Gson;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class FileManager {
private static FileData readDataFromFile(File file) throws FileNotFoundException {
if (!file.exists()) throw new FileNotFoundException();
String dataJson;
Gson gson = new Gson();
try {
dataJson = FileUtils.readFileToString(file, StandardCharsets.UTF_16);
} catch (IOException e) {
throw new RuntimeException(e);
}
return gson.fromJson(dataJson, FileData.class);
}
private static void createDataFile(FileData fileData, File file) {
try {
//noinspection ResultOfMethodCallIgnored
file.getParentFile().mkdirs();
//noinspection ResultOfMethodCallIgnored
file.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
writeDataToFile(fileData, file);
}
public static void writeDataToFile(FileData fileData, File file) {
try {
FileUtils.writeStringToFile(file, fileData.getAsJsonString(), StandardCharsets.UTF_16);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static FileData readOrCreate(TimesFile file) {
FileData data;
try {
data = FileManager.readDataFromFile(file);
} catch (FileNotFoundException ignored) {
data = new FileData(file.getGameMode().getMap());
FileManager.createDataFile(data, file);
}
return data;
}
}

View file

@ -0,0 +1,36 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder;
import com.github.stachelbeere1248.zombiesutils.game.GameMode;
import java.io.File;
public class TimesFile extends File {
private final FileData fileData;
private final GameMode gameMode;
public TimesFile(String category, GameMode gameMode) {
// Game-directory -> custom category -> file named "MAP_DIFFICULTY.times"
// Content encoded in StandardCharsets.UTF_16
super("zombies" + File.separator + category,gameMode.getMap() + "_" + gameMode.getDifficulty() + ".times");
this.gameMode = gameMode;
fileData = FileManager.readOrCreate(this);
}
public short getBestSegment(int round) {
return fileData.getBestSegment(round-1);
}
public void setBestSegment(int round, short ticks) {
fileData.setBestSegment(round-1, ticks);
FileManager.writeDataToFile(fileData,this);
}
public int getPersonalBest(int round) {
return fileData.getPersonalBest(round-1);
}
public void setPersonalBest(int round, int ticks) {
fileData.setPersonalBest(round-1, ticks);
FileManager.writeDataToFile(fileData,this);
}
GameMode getGameMode() {
return gameMode;
}
}

View file

@ -1,6 +1,7 @@
package com.github.stachelbeere1248.zombiesutils.utils;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.game.Map;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import net.minecraft.client.Minecraft;
@ -16,10 +17,11 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class Scoreboard {
@SuppressWarnings("UnnecessaryUnicodeEscape")
private static final Pattern SIDEBAR_EMOJI_PATTERN = Pattern.compile("[\uD83D\uDD2B\uD83C\uDF6B\uD83D\uDCA3\uD83D\uDC7D\uD83D\uDD2E\uD83D\uDC0D\uD83D\uDC7E\uD83C\uDF20\uD83C\uDF6D\u26BD\uD83C\uDFC0\uD83D\uDC79\uD83C\uDF81\uD83C\uDF89\uD83C\uDF82]+");
private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("§[0-9A-FK-ORZ]", Pattern.CASE_INSENSITIVE);
private static final Pattern ROUND_LINE_PATTERN = Pattern.compile("(Round )([0-9]{1,3})");
private static final Pattern SERVER_NUMBER_PATTERN = Pattern.compile(".*([mLM][0-9A-Z]+)");
private static final Pattern MAP_PATTERN = Pattern.compile("Map:.*(Dead End|Bad Blood|Alien Arcadium)");
private static String title = null;
private static List<String> lines = null;
@ -41,32 +43,31 @@ public class Scoreboard {
// get
title = STRIP_COLOR_PATTERN.matcher(sidebar.getDisplayName().trim()).replaceAll("");
Collection<Score> scoreCollection = scoreboard.getSortedScores(sidebar);
List<Score> filteredScores = scoreCollection
.stream()
.filter(input -> input.getPlayerName() != null && !input.getPlayerName().startsWith("#"))
.collect(Collectors.toList());
List<Score> filteredScores = scoreCollection.stream().filter(input -> input.getPlayerName() != null && !input.getPlayerName().startsWith("#")).collect(Collectors.toList());
List<Score> scores = (filteredScores.size() > 15) ? Lists.newArrayList(Iterables.skip(filteredScores, scoreCollection.size() - 15)) : filteredScores;
List<Score> scores;
if (filteredScores.size() > 15) scores = Lists.newArrayList(Iterables.skip(filteredScores, scoreCollection.size() - 15));
else scores = filteredScores;
scores = Lists.reverse(scores);
lines = new ArrayList<>(scores.size());
for (Score score : scores) {
lines = new ArrayList<String>();
for (Score score: scores
) {
ScorePlayerTeam team = scoreboard.getPlayersTeam(score.getPlayerName());
String scoreboardLine = ScorePlayerTeam.formatPlayerName(team, score.getPlayerName()).trim();
lines.add(STRIP_COLOR_PATTERN.matcher(SIDEBAR_EMOJI_PATTERN.matcher(scoreboardLine).replaceAll("")).replaceAll(""));
}
}
public static int getRound() {
public static byte getRound() {
String line;
try {
line = lines.get(2);
} catch (IndexOutOfBoundsException | NullPointerException ignored) {
return 0;
}
final Pattern ROUND_LINE_PATTERN = LanguageSupport.roundPattern(ZombiesUtils.getInstance().getConfig().getLanguage());
String string = ROUND_LINE_PATTERN.matcher(line).replaceAll("$1");
String string = ROUND_LINE_PATTERN.matcher(line).replaceAll("$2");
byte round;
try {
@ -77,7 +78,6 @@ public class Scoreboard {
return 0;
}
}
public static Optional<String> getServerNumber() {
String line;
try {
@ -90,8 +90,26 @@ public class Scoreboard {
ZombiesUtils.getInstance().getLogger().debug("Servernumber: " + string);
return Optional.ofNullable(string);
}
public static boolean isNotZombies() {
return (!"ZOMBIES".equals(title));
public static Optional<Map> getMap() {
String line;
try {
line = lines.get(12);
} catch (Exception couldBePregame) {
try {
line = lines.get(2);
} catch (IndexOutOfBoundsException | NullPointerException ignored) {
return Optional.empty();
}
}
String mapString = MAP_PATTERN.matcher(line).replaceAll("$1");
switch (mapString) {
case "Dead End": return Optional.of(Map.DEAD_END);
case "Bad Blood": return Optional.of(Map.BAD_BLOOD);
case "Alien Arcadium": return Optional.of(Map.ALIEN_ARCADIUM);
default: return Optional.empty();
}
}
public static boolean isZombies() {
return ("ZOMBIES".equals(title));
}
}

View file

@ -1,22 +0,0 @@
package com.github.stachelbeere1248.zombiesutils;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ResourceLocation;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Optional;
public class ResourceLoader {
public static Optional<JsonElement> readJsonResource(final String resourcePath) {
ResourceLocation resourceLocation = new ResourceLocation("zombiesutils", resourcePath);
try (Reader reader = new InputStreamReader(Minecraft.getMinecraft().getResourceManager().getResource(resourceLocation).getInputStream())) {
return Optional.ofNullable(new JsonParser().parse(reader));
} catch (Exception e) {
ZombiesUtils.getInstance().getLogger().error(e.fillInStackTrace());
return Optional.empty();
}
}
}

View file

@ -1,83 +0,0 @@
package com.github.stachelbeere1248.zombiesutils;
import com.github.stachelbeere1248.zombiesutils.commands.CommandRegistry;
import com.github.stachelbeere1248.zombiesutils.config.Hotkeys;
import com.github.stachelbeere1248.zombiesutils.config.ZombiesUtilsConfig;
import com.github.stachelbeere1248.zombiesutils.game.GameData;
import com.github.stachelbeere1248.zombiesutils.handlers.Handlers;
import com.github.stachelbeere1248.zombiesutils.timer.GameManager;
import net.minecraft.client.Minecraft;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
@Mod(modid = "zombiesutils", useMetadata = true, clientSideOnly = true, guiFactory = "com.github.stachelbeere1248.zombiesutils.config.GuiFactory")
public class ZombiesUtils {
private static ZombiesUtils instance;
private final Hotkeys hotkeys;
private final GameManager gameManager;
private ZombiesUtilsConfig config;
private Handlers handlers;
private Logger logger;
private GameData gameData;
public ZombiesUtils() {
hotkeys = new Hotkeys();
gameManager = new GameManager();
instance = this;
}
public static ZombiesUtils getInstance() {
return instance;
}
public static boolean isHypixel() {
String ip = Minecraft.getMinecraft().getCurrentServerData().serverIP;
return (ip.equals("localhost") || ip.matches("(.+\\.)?(hypixel\\.net)(:25565)?"));
}
@Mod.EventHandler
public void preInit(@NotNull FMLPreInitializationEvent event) {
this.logger = event.getModLog();
this.config = new ZombiesUtilsConfig(new Configuration(
event.getSuggestedConfigurationFile())
);
}
@Mod.EventHandler
public void init(FMLInitializationEvent event) {
handlers = new Handlers();
handlers.registerAll();
CommandRegistry.registerAll();
hotkeys.registerAll();
gameData = new GameData();
}
public Logger getLogger() {
return logger;
}
public Hotkeys getHotkeys() {
return hotkeys;
}
public Handlers getHandlers() {
return handlers;
}
public ZombiesUtilsConfig getConfig() {
return config;
}
public GameManager getGameManager() {
return gameManager;
}
public GameData getGameData() {
return gameData;
}
}

View file

@ -1,69 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.commands;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.Category;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommand;
import net.minecraft.command.ICommandSender;
import net.minecraft.command.WrongUsageException;
import net.minecraft.util.BlockPos;
import net.minecraft.util.ChatComponentText;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.Arrays;
import java.util.List;
public class CategoryCommand implements ICommand {
public CategoryCommand() {
}
@Override
public String getCommandName() {
return "category";
}
@Override
public String getCommandUsage(ICommandSender sender) {
return "/category <category-name>";
}
@Override
public List<String> getCommandAliases() {
return Arrays.asList("runCategory", "cat");
}
@Override
public void processCommand(ICommandSender sender, String @NotNull [] args) throws CommandException {
if (args.length == 0) throw new WrongUsageException("Please enter a name for the category");
else {
String cat = args[0];
if (cat.contains(File.separator))
throw new WrongUsageException("Your name must not contain '" + File.separator + "' as this is the systems separator character for folder" + File.separator + "sub-folder");
Category.setSelectedCategory(cat);
ZombiesUtils.getInstance().getGameManager().getGame().ifPresent(game -> game.setCategory(new Category()));
sender.addChatMessage(new ChatComponentText("§eSet category to §c" + cat));
}
}
@Override
public List<String> addTabCompletionOptions(ICommandSender sender, String[] args, BlockPos blockPos) {
return Arrays.asList(Category.getCategories());
}
@Override
public boolean isUsernameIndex(String[] args, int index) {
return false;
}
@Override
public boolean canCommandSenderUseCommand(ICommandSender sender) {
return true;
}
@Override
public int compareTo(@NotNull ICommand command) {
return this.getCommandName().compareTo(command.getCommandName());
}
}

View file

@ -1,12 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.commands;
import net.minecraftforge.client.ClientCommandHandler;
public class CommandRegistry {
public static void registerAll() {
ClientCommandHandler.instance.registerCommand(new CategoryCommand());
ClientCommandHandler.instance.registerCommand(new SlaCommand());
ClientCommandHandler.instance.registerCommand(new ZombiesUtilsCommand());
ClientCommandHandler.instance.registerCommand(new QuickZombiesCommand());
}
}

View file

@ -1,61 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.commands;
import net.minecraft.client.Minecraft;
import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.command.WrongUsageException;
import net.minecraft.util.BlockPos;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class QuickZombiesCommand extends CommandBase {
@Override
public String getCommandName() {
return "qz";
}
@Override
public String getCommandUsage(ICommandSender sender) {
return "/qz <de|bb|aa|p>";
}
@Override
public void processCommand(ICommandSender sender, String @NotNull [] args) throws CommandException {
if (args.length == 0) throw new WrongUsageException(
"[Missing option] options: de, bb, aa, p");
else switch (args[0]) {
case "de":
Minecraft.getMinecraft().thePlayer.sendChatMessage("/play arcade_zombies_dead_end");
break;
case "bb":
Minecraft.getMinecraft().thePlayer.sendChatMessage("/play arcade_zombies_bad_blood");
break;
case "aa":
Minecraft.getMinecraft().thePlayer.sendChatMessage("/play arcade_zombies_alien_arcadium");
break;
case "p":
Minecraft.getMinecraft().thePlayer.sendChatMessage("/play arcade_zombies_prison");
break;
default:
throw new WrongUsageException(
"[Invalid option] options: de, bb, aa, p", args[0]);
}
}
@Override
public List<String> addTabCompletionOptions(ICommandSender sender, String @NotNull [] args, BlockPos blockPos) {
if (args.length == 1) return Arrays.asList("de", "bb", "aa");
else return Collections.emptyList();
}
@Override
public boolean canCommandSenderUseCommand(ICommandSender sender) {
return true;
}
}

View file

@ -1,152 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.commands;
import com.github.stachelbeere1248.zombiesutils.game.enums.Map;
import com.github.stachelbeere1248.zombiesutils.game.sla.QuickSLA;
import com.github.stachelbeere1248.zombiesutils.game.windows.SLA;
import net.minecraft.command.*;
import net.minecraft.util.BlockPos;
import net.minecraft.util.ChatComponentText;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class SlaCommand extends CommandBase {
@Override
public String getCommandName() {
return "sla";
}
@Override
public String getCommandUsage(ICommandSender sender) {
return "/sla off\n/sla offset [x] [x] [x]\n/sla rotate\n/sla mirror\n/sla map <de|bb|aa|p>\n/sla quick";
}
@Override
public void processCommand(ICommandSender sender, String @NotNull [] args) throws CommandException {
if (args.length == 0) throw new WrongUsageException(
"[Missing option] options: off, offset, rotate, mirror, map, quick");
else switch (args[0]) {
case "off":
SLA.drop();
sender.addChatMessage(new ChatComponentText("SLA data deleted"));
break;
case "offset":
if (args.length == 1) SLA.getInstance().ifPresent(SLA::resetOffset);
else if (args.length != 4) throw new WrongUsageException(
"An offset should have three coordinates!");
else {
try {
int x = Integer.parseInt(args[1]);
int y = Integer.parseInt(args[2]);
int z = Integer.parseInt(args[3]);
SLA.getInstance().ifPresent(sla -> sla.setOffset(new int[]{x, y, z}));
} catch (NumberFormatException ignored) {
throw new NumberInvalidException("Invalid Integer:", args[1]);
}
}
break;
case "rotate":
if (args.length == 1) SLA.getInstance().ifPresent(sla -> sla.rotate(1));
else {
int rotations;
try {
rotations = Integer.parseInt(args[1]);
} catch (NumberFormatException ignored) {
throw new NumberInvalidException("Invalid Integer:", args[1]);
}
SLA.getInstance().ifPresent(sla -> sla.rotate(rotations));
}
break;
case "mirror":
switch (args[1]) {
case "x":
SLA.getInstance().ifPresent(SLA::mirrorX);
break;
case "z":
SLA.getInstance().ifPresent(SLA::mirrorZ);
break;
default:
throw new WrongUsageException("Invalid option: available: x, z");
}
break;
case "map":
switch (args[1]) {
case "de":
SLA.instance = new SLA(Map.DEAD_END);
break;
case "bb":
SLA.instance = new SLA(Map.BAD_BLOOD);
break;
case "aa":
SLA.instance = new SLA(Map.ALIEN_ARCADIUM);
break;
case "p":
SLA.instance = new SLA(Map.PRISON);
break;
default:
throw new WrongUsageException(
"[Invalid option] options: de, bb, aa, p", args[1]);
}
break;
case "quick":
switch (args[1]) {
//noinspection SpellCheckingInspection
case "mogi_a":
QuickSLA.mogi_a();
break;
//noinspection SpellCheckingInspection
case "ghxula":
QuickSLA.ghxula();
break;
//noinspection SpellCheckingInspection
case "ghxula-garden":
QuickSLA.ghxulaGarden();
break;
default:
//noinspection SpellCheckingInspection
throw new WrongUsageException(
"[Invalid option] options: mogi_a, ghxula, ghxula-garden", args[1]);
}
break;
default:
throw new WrongUsageException(
"[Invalid option] options: off, offset, rotate, mirror, map", args[0]);
}
}
@Override
public List<String> addTabCompletionOptions(ICommandSender sender, String @NotNull [] args, BlockPos blockPos) {
List<String> options = new ArrayList<>();
if (args.length == 1) options.addAll(Arrays.asList("off", "offset", "rotate", "mirror", "map", "quick"));
else {
if (args.length >= 2) switch (args[0]) {
case "offset":
if (args.length < 5) options.add("0");
break;
case "map":
options.addAll(Arrays.asList("de", "bb", "aa", "p"));
break;
case "mirror":
options.addAll(Arrays.asList("x", "z"));
break;
case "rotate":
options.add("1");
break;
case "quick":
//noinspection SpellCheckingInspection
options.addAll(Arrays.asList("mogi_a", "ghxula", "ghxula-garden"));
default:
break;
}
}
return options;
}
@Override
public boolean canCommandSenderUseCommand(ICommandSender sender) {
return true;
}
}

View file

@ -1,88 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.commands;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.utils.InvalidMapException;
import com.github.stachelbeere1248.zombiesutils.utils.ScoardboardException;
import com.github.stachelbeere1248.zombiesutils.utils.Scoreboard;
import net.minecraft.command.*;
import net.minecraft.util.BlockPos;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class ZombiesUtilsCommand extends CommandBase {
@Override
public String getCommandName() {
return "zombiesutils";
}
@Override
public String getCommandUsage(ICommandSender sender) {
return "/zombiesutils";
}
@Override
public void processCommand(ICommandSender sender, String @NotNull [] args) throws CommandException {
if (args.length == 0) throw new WrongUsageException(
"[Missing option] options: timer");
else switch (args[0]) {
case "timer":
switch (args[1]) {
case "kill":
String serverNumber = Scoreboard.getServerNumber().orElse("");
if (args.length == 3) serverNumber = args[2];
ZombiesUtils.getInstance().getGameManager().endGame(serverNumber, false);
break;
case "killall":
ZombiesUtils.getInstance().getGameManager().killAll();
case "split":
try {
ZombiesUtils.getInstance().getGameManager().splitOrNew(Integer.parseInt(args[2]));
} catch (NumberFormatException | NullPointerException ignored) {
throw new NumberInvalidException("t", args[2]);
} catch (ScoardboardException | InvalidMapException e) {
ZombiesUtils.getInstance().getLogger().error(e.getStackTrace());
}
break;
default:
throw new WrongUsageException(
"[Invalid option] options: kill, killall, split", args[0]);
}
break;
default:
throw new WrongUsageException(
"[Invalid option] options: timer", args[0]);
}
}
@Override
public List<String> addTabCompletionOptions(ICommandSender sender, String @NotNull [] args, BlockPos blockPos) {
if (args.length == 1) return new ArrayList<>(Collections.singleton("timer"));
else if (args.length == 2) {
switch (args[0]) {
case "timer":
return new ArrayList<>(Arrays.asList("kill", "killall", "split"));
default:
return Collections.emptyList();
}
} else if (args.length == 3) {
switch (args[0]) {
case "timer":
switch (args[1]) {
case "kill":
return new ArrayList<>(ZombiesUtils.getInstance().getGameManager().getGames());
}
default:
return Collections.emptyList();
}
} else return Collections.emptyList();
}
@Override
public boolean canCommandSenderUseCommand(ICommandSender sender) {
return true;
}
}

View file

@ -1,244 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.config;
import net.minecraftforge.common.config.ConfigCategory;
import net.minecraftforge.common.config.ConfigElement;
import net.minecraftforge.common.config.Property;
import net.minecraftforge.fml.client.config.ConfigGuiType;
import net.minecraftforge.fml.client.config.GuiConfigEntries;
import net.minecraftforge.fml.client.config.GuiEditArrayEntries;
import net.minecraftforge.fml.client.config.IConfigElement;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
public class CustomConfigElement implements IConfigElement {
private final String name;
private final boolean isProperty;
private Property prop;
private ConfigCategory category;
public CustomConfigElement(String name, Property prop) {
this.prop = prop;
this.isProperty = true;
this.name = name;
}
public CustomConfigElement(String name, ConfigCategory category) {
this.category = category;
this.isProperty = false;
this.name = name;
}
public static ConfigGuiType getType(Property prop) {
return prop.getType() == Property.Type.BOOLEAN ? ConfigGuiType.BOOLEAN : prop.getType() == Property.Type.DOUBLE ? ConfigGuiType.DOUBLE :
prop.getType() == Property.Type.INTEGER ? ConfigGuiType.INTEGER : prop.getType() == Property.Type.COLOR ? ConfigGuiType.COLOR :
prop.getType() == Property.Type.MOD_ID ? ConfigGuiType.MOD_ID : ConfigGuiType.STRING;
}
@Override
public List<IConfigElement> getChildElements() {
if (!isProperty) {
List<IConfigElement> elements = new ArrayList<>();
for (Property property : category.getOrderedValues()) {
ConfigElement temp = new ConfigElement(property);
if (temp.showInGui())
elements.add(temp);
}
return elements;
}
return null;
}
@Override
public String getName() {
return this.name;
}
@Override
public boolean isProperty() {
return isProperty;
}
@Override
public Class<? extends GuiConfigEntries.IConfigEntry> getConfigEntryClass() {
return isProperty ? prop.getConfigEntryClass() : category.getConfigEntryClass();
}
@Override
public Class<? extends GuiEditArrayEntries.IArrayEntry> getArrayEntryClass() {
return isProperty ? prop.getArrayEntryClass() : null;
}
@Override
public String getQualifiedName() {
return isProperty ? prop.getName() : category.getQualifiedName();
}
@Override
public ConfigGuiType getType() {
return isProperty ? getType(this.prop) : ConfigGuiType.CONFIG_CATEGORY;
}
@Override
public boolean isList() {
return isProperty && prop.isList();
}
@Override
public boolean isListLengthFixed() {
return isProperty && prop.isListLengthFixed();
}
@Override
public int getMaxListLength() {
return isProperty ? prop.getMaxListLength() : -1;
}
@Override
public String getComment() {
return isProperty ? prop.comment : category.getComment();
}
@Override
public boolean isDefault() {
return !isProperty || prop.isDefault();
}
@Override
public void setToDefault() {
if (isProperty)
prop.setToDefault();
}
@Override
public boolean requiresWorldRestart() {
return isProperty ? prop.requiresWorldRestart() : category.requiresWorldRestart();
}
@Override
public boolean showInGui() {
return isProperty ? prop.showInGui() : category.showInGui();
}
@Override
public boolean requiresMcRestart() {
return isProperty ? prop.requiresMcRestart() : category.requiresMcRestart();
}
@Override
public String[] getValidValues() {
return isProperty ? prop.getValidValues() : null;
}
@Override
public String getLanguageKey() {
return isProperty ? prop.getLanguageKey() : category.getLanguagekey();
}
@Override
public Object getDefault() {
return isProperty ? prop.getDefault() : null;
}
@Override
public Object[] getDefaults() {
if (isProperty) {
String[] aVal = prop.getDefaults();
return getObjects(aVal);
}
return null;
}
private Object[] getObjects(String[] aVal) {
if (prop.getType() == Property.Type.BOOLEAN) {
Boolean[] ba = new Boolean[aVal.length];
for (int i = 0; i < aVal.length; i++)
ba[i] = Boolean.valueOf(aVal[i]);
return ba;
} else if (prop.getType() == Property.Type.DOUBLE) {
Double[] da = new Double[aVal.length];
for (int i = 0; i < aVal.length; i++)
da[i] = Double.valueOf(aVal[i]);
return da;
} else if (prop.getType() == Property.Type.INTEGER) {
Integer[] ia = new Integer[aVal.length];
for (int i = 0; i < aVal.length; i++)
ia[i] = Integer.valueOf(aVal[i]);
return ia;
} else
return aVal;
}
@Override
public Pattern getValidationPattern() {
return isProperty ? prop.getValidationPattern() : null;
}
@Override
public Object get() {
return isProperty ? prop.getString() : null;
}
@Override
public Object[] getList() {
if (isProperty) {
String[] aVal = prop.getStringList();
return getObjects(aVal);
}
return null;
}
@Override
public void set(Object value) {
if (isProperty) {
if (prop.getType() == Property.Type.BOOLEAN)
prop.set(Boolean.parseBoolean(value.toString()));
else if (prop.getType() == Property.Type.DOUBLE)
prop.set(Double.parseDouble(value.toString()));
else if (prop.getType() == Property.Type.INTEGER)
prop.set(Integer.parseInt(value.toString()));
else
prop.set(value.toString());
}
}
@Override
public void set(Object[] aVal) {
if (isProperty) {
if (prop.getType() == Property.Type.BOOLEAN) {
boolean[] ba = new boolean[aVal.length];
for (int i = 0; i < aVal.length; i++)
ba[i] = Boolean.parseBoolean(aVal[i].toString());
prop.set(ba);
} else if (prop.getType() == Property.Type.DOUBLE) {
double[] da = new double[aVal.length];
for (int i = 0; i < aVal.length; i++)
da[i] = Double.parseDouble(aVal[i].toString());
prop.set(da);
} else if (prop.getType() == Property.Type.INTEGER) {
int[] ia = new int[aVal.length];
for (int i = 0; i < aVal.length; i++)
ia[i] = Integer.parseInt(aVal[i].toString());
prop.set(ia);
} else {
String[] is = new String[aVal.length];
for (int i = 0; i < aVal.length; i++)
is[i] = aVal[i].toString();
prop.set(is);
}
}
}
@Override
public Object getMinValue() {
return isProperty ? prop.getMinValue() : null;
}
@Override
public Object getMaxValue() {
return isProperty ? prop.getMaxValue() : null;
}
}

View file

@ -1,17 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.config;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import net.minecraft.client.gui.GuiScreen;
public class GuiConfig extends net.minecraftforge.fml.client.config.GuiConfig {
public GuiConfig(GuiScreen parentScreen) {
super(
parentScreen,
ZombiesUtils.getInstance().getConfig().getRootElements(),
"zombiesutils",
false,
false,
"Zombies Utils"
);
}
}

View file

@ -1,29 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.config;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraftforge.fml.client.IModGuiFactory;
import java.util.Set;
public class GuiFactory implements IModGuiFactory {
@Override
public void initialize(Minecraft minecraft) {
}
@Override
public Class<? extends GuiScreen> mainConfigGuiClass() {
return GuiConfig.class;
}
@Override
public Set<RuntimeOptionCategoryElement> runtimeGuiCategories() {
return null;
}
@Override
public RuntimeOptionGuiHandler getHandlerFor(RuntimeOptionCategoryElement element) {
return null;
}
}

View file

@ -1,48 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.config;
import net.minecraft.client.settings.KeyBinding;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import org.lwjgl.input.Keyboard;
public class Hotkeys {
private final KeyBinding chatMacro;
private final KeyBinding rlSpawn;
private final KeyBinding playerVisiblity;
public Hotkeys() {
chatMacro = new KeyBinding(
"Chat Macro",
Keyboard.KEY_Q,
"Zombies Utils"
);
rlSpawn = new KeyBinding(
"Rocket Launcher Mode",
Keyboard.KEY_UP,
"Zombies Utils"
);
playerVisiblity = new KeyBinding(
"Player Visibility",
Keyboard.KEY_RIGHT,
"Zombies Utils"
);
}
public void registerAll() {
ClientRegistry.registerKeyBinding(this.chatMacro);
ClientRegistry.registerKeyBinding(this.rlSpawn);
ClientRegistry.registerKeyBinding(this.playerVisiblity);
}
public KeyBinding getChatMacro() {
return chatMacro;
}
public KeyBinding getRlSpawn() {
return rlSpawn;
}
public KeyBinding getPlayerVisiblity() {
return playerVisiblity;
}
}

View file

@ -1,242 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.config;
import com.github.stachelbeere1248.zombiesutils.utils.LanguageSupport;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;
import net.minecraftforge.fml.client.config.DummyConfigElement;
import net.minecraftforge.fml.client.config.IConfigElement;
import net.minecraftforge.fml.client.event.ConfigChangedEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
public class ZombiesUtilsConfig {
public final Configuration config;
private Property sstHud;
private Property offset;
private Property slaToggle;
private Property slaShortener;
private Property shortSpawntime;
private Property chatMacro;
private Property defaultCategory;
private Property language;
private Property auditory;
private Property cpsCounter;
private Property announcePB;
private Property playerVis;
private Property playerVisRange;
public ZombiesUtilsConfig(Configuration config) {
this.config = config;
this.read();
}
private void read() {
config.load();
//SST
sstHud = config.get(
"SST",
"enabled",
true,
"Show the spawn-time HUD?"
);
auditory = config.get(
"SST",
"auditory",
new int[]{-40, -20, 0},
"For every entry a sound will be played x ticks before the wave spawn.",
-200,
200,
false,
5
);
//noinspection SpellCheckingInspection
shortSpawntime = config.get(
"SST",
"autohide",
false,
"Hide passed rounds?"
);
offset = config.get(
"SST",
"offset",
-28,
"Offset is added while in RL-mode",
-200,
200
);
//SLA
slaToggle = config.get(
"SLA",
"autostart",
false,
"Should SLA be started when a game starts?"
);
slaShortener = config.get(
"SLA",
"shortened SLA",
true,
"If on, inactive windows / rooms will not show"
);
//Timer
defaultCategory = config.get(
"timer",
"Default Category",
"general",
"name of the category to be selected unless specified using /runCategory"
);
announcePB = config.get(
"timer",
"announce",
true,
"Whether to announce PBs."
);
//Player Visibility
playerVis = config.get(
"PlayerVis",
"default",
false,
"If players should always be visible"
);
playerVisRange = config.get(
"PlayerVis",
"range",
4,
"The range within which players are hidden",
0,
50
);
//ROOT
language = config.get(
Configuration.CATEGORY_GENERAL,
"Language",
"EN",
"Your Hypixel language",
LanguageSupport.getLanguages()
);
chatMacro = config.get(
Configuration.CATEGORY_GENERAL,
"Chat Macro",
"T",
"The Text to be sent when pressing the chat-macro hotkey"
);
cpsCounter = config.get(
Configuration.CATEGORY_GENERAL,
"cps",
false,
"whether to show cps"
);
}
private List<IConfigElement> getSpawntimeElements() {
return Arrays.asList(
new CustomConfigElement("Enabled", sstHud),
new CustomConfigElement("Auditory", auditory),
new CustomConfigElement("RL pre-timing", offset),
new CustomConfigElement("Truncate", shortSpawntime)
);
}
private List<IConfigElement> getSlaElements() {
return Arrays.asList(
new CustomConfigElement("Enabled", slaToggle),
new CustomConfigElement("Truncate", slaShortener)
);
}
private List<IConfigElement> getTimerElements() {
return Arrays.asList(
new CustomConfigElement("Default category", defaultCategory),
new CustomConfigElement("PB announcements", announcePB)
);
}
private List<IConfigElement> getPlayerVisElements() {
return Arrays.asList(
new CustomConfigElement("Enabled", playerVis),
new CustomConfigElement("Range", playerVisRange)
);
}
List<IConfigElement> getRootElements() {
return Arrays.asList(
new CustomConfigElement("Language", language),
new DummyConfigElement.DummyCategoryElement("Timer", "", getTimerElements()),
new DummyConfigElement.DummyCategoryElement("SST", "", getSpawntimeElements()),
new DummyConfigElement.DummyCategoryElement("SLA", "", getSlaElements()),
new DummyConfigElement.DummyCategoryElement("Player Visibility", "", getPlayerVisElements()),
new CustomConfigElement("Macro message", chatMacro),
new CustomConfigElement("CPS counter", cpsCounter)
);
}
public short getOffset() {
return (short) offset.getInt();
}
public boolean isSlaToggled() {
return slaToggle.getBoolean();
}
public boolean isSlaShortened() {
return slaShortener.getBoolean();
}
public boolean isSpawntimeShortened() {
return shortSpawntime.getBoolean();
}
public String getChatMacro() {
return chatMacro.getString();
}
public String getDefaultCategory() {
return defaultCategory.getString();
}
public String getLanguage() {
return language.getString();
}
public int[] getAuditory() {
return auditory.getIntList();
}
public boolean getSST() {
return sstHud.getBoolean();
}
public boolean getCpsToggle() {
return cpsCounter.getBoolean();
}
public boolean getAnnouncePB() {
return announcePB.getBoolean();
}
public boolean getPlayerVis() {
return playerVis.getBoolean();
}
public int getPlayerVisRange() {
return playerVisRange.getInt();
}
@SubscribeEvent
public void onConfigChange(ConfigChangedEvent.@NotNull OnConfigChangedEvent event) {
if (event.modID.equals("zombiesutils") && event.configID == null) {
config.save();
}
}
}

View file

@ -1,57 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.game;
import com.github.stachelbeere1248.zombiesutils.ResourceLoader;
import com.github.stachelbeere1248.zombiesutils.game.waves.Round;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import org.jetbrains.annotations.NotNull;
public class GameData {
private final Round[][] roundData;
public GameData() {
roundData = new Round[10][];
roundData[0] = readFromFile("data/rounds/DEAD_END_NORMAL.json");
roundData[1] = readFromFile("data/rounds/DEAD_END_HARD.json");
roundData[2] = readFromFile("data/rounds/DEAD_END_RIP.json");
roundData[3] = readFromFile("data/rounds/BAD_BLOOD_NORMAL.json");
roundData[4] = readFromFile("data/rounds/BAD_BLOOD_HARD.json");
roundData[5] = readFromFile("data/rounds/BAD_BLOOD_RIP.json");
roundData[6] = readFromFile("data/rounds/ALIEN_ARCADIUM.json");
roundData[7] = readFromFile("data/rounds/PRISON_NORMAL.json");
roundData[8] = readFromFile("data/rounds/PRISON_HARD.json");
roundData[9] = readFromFile("data/rounds/PRISON_RIP.json");
}
public Round getRound(@NotNull GameMode gameMode, int round) {
switch (gameMode) {
case DEAD_END:
return roundData[0][round - 1];
case DEAD_END_HARD:
return roundData[1][round - 1];
case DEAD_END_RIP:
return roundData[2][round - 1];
case BAD_BLOOD:
return roundData[3][round - 1];
case BAD_BLOOD_HARD:
return roundData[4][round - 1];
case BAD_BLOOD_RIP:
return roundData[5][round - 1];
case ALIEN_ARCADIUM:
return roundData[6][round - 1];
case PRISON:
return roundData[7][round - 1];
case PRISON_HARD:
return roundData[8][round - 1];
case PRISON_RIP:
return roundData[9][round - 1];
default:
throw new IllegalStateException("Invalid GameMode: " + gameMode);
}
}
private Round[] readFromFile(final String resourcePath) {
final JsonElement roundsJsonElement = ResourceLoader.readJsonResource(resourcePath).orElseThrow(RuntimeException::new);
return new Gson().fromJson(roundsJsonElement, Round[].class);
}
}

View file

@ -1,84 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.game;
import com.github.stachelbeere1248.zombiesutils.game.enums.Difficulty;
import com.github.stachelbeere1248.zombiesutils.game.enums.Map;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
public enum GameMode {
DEAD_END(Map.DEAD_END, Difficulty.NORMAL), DEAD_END_HARD(Map.DEAD_END, Difficulty.HARD), DEAD_END_RIP(Map.DEAD_END, Difficulty.RIP),
BAD_BLOOD(Map.BAD_BLOOD, Difficulty.NORMAL), BAD_BLOOD_HARD(Map.BAD_BLOOD, Difficulty.HARD), BAD_BLOOD_RIP(Map.BAD_BLOOD, Difficulty.RIP),
ALIEN_ARCADIUM(Map.ALIEN_ARCADIUM, Difficulty.NORMAL),
PRISON(Map.PRISON, Difficulty.NORMAL), PRISON_HARD(Map.PRISON, Difficulty.HARD), PRISON_RIP(Map.PRISON, Difficulty.RIP);
private final Map map;
private final Difficulty difficulty;
GameMode(final @NotNull Map map, final @NotNull Difficulty difficulty) {
this.map = map;
this.difficulty = difficulty;
}
@Contract(pure = true)
public static GameMode getNormalForMap(final @NotNull Map map) {
switch (map) {
case DEAD_END:
return DEAD_END;
case BAD_BLOOD:
return BAD_BLOOD;
case ALIEN_ARCADIUM:
return ALIEN_ARCADIUM;
case PRISON:
return PRISON;
default:
throw new IllegalStateException("Unexpected value: " + map);
}
}
public Map getMap() {
return this.map;
}
public Difficulty getDifficulty() {
return this.difficulty;
}
public GameMode appliedDifficulty(final Difficulty difficulty) {
switch (this.map) {
case DEAD_END:
switch (difficulty) {
case NORMAL:
return DEAD_END;
case HARD:
return DEAD_END_HARD;
case RIP:
return DEAD_END_RIP;
}
case BAD_BLOOD:
switch (difficulty) {
case NORMAL:
return BAD_BLOOD;
case HARD:
return BAD_BLOOD_HARD;
case RIP:
return BAD_BLOOD_RIP;
}
case PRISON:
switch (difficulty) {
case NORMAL:
return PRISON;
case HARD:
return PRISON_HARD;
case RIP:
return PRISON_RIP;
}
case ALIEN_ARCADIUM:
return ALIEN_ARCADIUM;
default:
throw new IllegalStateException("Invalid Map: " + this.map);
}
}
public boolean isMap(Map map) {
return this.getMap() == map;
}
}

View file

@ -1,5 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.game.enums;
public enum Difficulty {
NORMAL, HARD, RIP
}

View file

@ -1,28 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.game.enums;
import com.github.stachelbeere1248.zombiesutils.utils.Scoreboard;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos;
import net.minecraft.world.World;
import java.util.Optional;
public enum Map {
DEAD_END, BAD_BLOOD, ALIEN_ARCADIUM, PRISON;
public static Optional<Map> getMap() {
World world = Minecraft.getMinecraft().theWorld;
BlockPos pos = new BlockPos(44, 71, 0);
if (!world.isBlockLoaded(pos) || Scoreboard.isNotZombies()) return Optional.empty();
Block block = world.getBlockState(pos).getBlock();
if (block.equals(Blocks.air)) return Optional.of(Map.DEAD_END);
if (block.equals(Blocks.wool)) return Optional.of(Map.BAD_BLOOD);
if (block.equals(Blocks.stone_slab)) return Optional.of(Map.ALIEN_ARCADIUM);
if (block.equals(Blocks.wooden_slab)) return Optional.of(Map.PRISON);
else return Optional.empty();
}
}

View file

@ -1,25 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.game.sla;
import com.github.stachelbeere1248.zombiesutils.game.enums.Map;
import com.github.stachelbeere1248.zombiesutils.game.windows.SLA;
@SuppressWarnings("SpellCheckingInspection")
public class QuickSLA {
public static void mogi_a() {
SLA.instance = new SLA(Map.BAD_BLOOD);
SLA.instance.rotate(3);
SLA.instance.setOffset(new int[]{-3, 35, -9});
}
public static void ghxula() {
SLA.instance = new SLA(Map.DEAD_END);
SLA.instance.rotate(1);
SLA.instance.setOffset(new int[]{27, 35, 5});
}
public static void ghxulaGarden() {
SLA.instance = new SLA(Map.DEAD_END);
SLA.instance.rotate(1);
SLA.instance.setOffset(new int[]{13, 53, -8});
}
}

View file

@ -1,37 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.game.waves;
public enum Prefix {
BOSS(0xCC5555, "B", 0x7A3333),
BLAZES(0xEFB61F, "BL", 0x8F6D0F),
SLIME(0x88FF88, "S", 0x51A951),
HBM(0x2A415F, "HBM", 0x193241),
WITHER_SKELETON(0x888888, "WS", 0x515151),
OLD_ONE(0x55AA55, "O1", 0x336633),
GIANT(0x00FFFF, "G", 0x009999),
POLICE(0x16537E, "P", 0x0E324D),
CELL(0xFF8234, "C", 0x99501F),
WINDOW(0xAAAAAA, "W", 0x666666);
private final int color;
private final int fadedColor;
private final String prefix;
Prefix(final int color, final String prefix, final int fadedColor) {
this.color = color;
this.prefix = prefix;
this.fadedColor = fadedColor;
}
public int getColor() {
return color;
}
public String getPrefix() {
return prefix;
}
public int getFadedColor() {
return fadedColor;
}
}

View file

@ -1,21 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.game.waves;
public class Round {
private final Wave[] waves;
public Round(final Wave[] waves) {
this.waves = waves;
}
public Wave[] getWaves() {
return waves;
}
public short[] getWaveTimes() {
short[] ret = new short[waves.length];
for (int i = 0; i < waves.length; i++) {
ret[i] = waves[i].getTime();
}
return ret;
}
}

View file

@ -1,25 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.game.waves;
@SuppressWarnings("DuplicatedCode")
public class Wave {
private final short ticks;
private final Prefix[] prefixes;
public Wave(final short ticks, final Prefix[] prefixes) {
this.ticks = ticks;
this.prefixes = prefixes;
}
public Wave(final short ticks) {
this.ticks = ticks;
this.prefixes = new Prefix[]{ Prefix.WINDOW };
}
public short getTime() {
return this.ticks;
}
public Prefix[] getPrefixes() {
return this.prefixes;
}
}

View file

@ -1,34 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.game.waves;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.utils.Scoreboard;
import net.minecraft.client.Minecraft;
import java.util.Arrays;
public class WaveTiming {
public static int rl = 0;
public static void onTick() {
if (Scoreboard.isNotZombies()) return;
ZombiesUtils.getInstance().getGameManager().getGame().ifPresent(
game -> {
short[] waves = ZombiesUtils.getInstance().getGameData().getRound(game.getGameMode(), game.getRound()).getWaveTimes();
final int roundTime = game.getTimer().getRoundTime();
final int[] auditory = ZombiesUtils.getInstance().getConfig().getAuditory();
for (short wave : waves) {
wave = (short) (wave + rl);
final Integer pre = roundTime - wave;
if (Arrays.stream(auditory).anyMatch(pre::equals)) {
Minecraft.getMinecraft().thePlayer.playSound("note.pling", 1, 2);
}
}
}
);
}
public static void toggleRL() {
if (rl == 0) rl = ZombiesUtils.getInstance().getConfig().getOffset();
else rl = 0;
}
}

View file

@ -1,295 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.game.windows;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import net.minecraft.util.Vec3;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
public class Room {
private final Window[] windows;
private final String name;
private final String alias;
private int activeWindowCount;
public Room(String name, String alias, Window[] windows) {
this.windows = windows;
this.name = name;
this.alias = alias;
}
@Contract(" -> new")
public static Room @NotNull [] getDE() {
Vec3 t = new Vec3(3, 3, 3);
t.rotatePitch(3);
return new Room[]{
new Room("Alley", "al", new Window[]{
new Window(1, 9, 138, 87),
new Window(2, 13, 138, 63),
new Window(3, 85, 140, 59),
new Window(4, 79, 140, 17)
}),
new Room("Office", "o", new Window[]{
new Window(1, 85, 152, 53),
new Window(2, 105, 152, 63),
new Window(3, 115, 152, 129)
}),
new Room("Hotel", "h", new Window[]{
new Window(1, 1, 136, 93),
new Window(2, -19, 136, 29),
new Window(3, 53, 138, 7),
new Window(4, 51, 138, -7),
new Window(5, -7, 152, -43),
new Window(6, 51, 152, -11)
}),
new Room("Apartments", "a", new Window[]{
new Window(1, 39, 152, 19),
new Window(2, -31, 152, 31),
new Window(3, -27, 152, 103),
new Window(4, -9, 152, 125)
}),
new Room("Power Station", "ps", new Window[]{
new Window(1, -5, 166, 65),
new Window(2, 7, 166, 125),
new Window(3, -11, 136, 133)
}),
new Room("Rooftop", "rt", new Window[]{
new Window(1, -31, 166, 129),
new Window(2, -27, 166, 61),
new Window(3, -75, 166, 51),
new Window(4, -99, 166, 77)
}),
new Room("Garden", "g", new Window[]{
new Window(1, 1, 136, -33),
new Window(2, 49, 136, -67),
new Window(3, 69, 136, -33)
}),
new Room("Gallery", "gal", new Window[]{
new Window(1, 45, 152, 155),
new Window(2, 61, 152, 109),
new Window(3, 31, 152, 131)
})
};
}
@Contract(" -> new")
public static Room @NotNull [] getBB() {
return new Room[]{
new Room("Courtyard", "co", new Window[]{
new Window(1, 39, 138, 41),
new Window(2, 61, 138, 21),
new Window(3, 49, 138, -37),
new Window(4, 25, 138, -35)
}),
new Room("Mansion", "m", new Window[]{
new Window(1, 1, 148, -35),
new Window(2, 1, 148, 37),
new Window(3, -25, 146, 57)
}),
new Room("Library", "l", new Window[]{
new Window(1, 3, 148, -89),
new Window(2, -41, 148, -59),
new Window(3, -81, 148, -61),
new Window(4, -79, 148, -115),
new Window(5, -109, 148, -93),
new Window(6, -107, 148, -67)
}),
new Room("Dungeon", "d", new Window[]{
new Window(1, -21, 136, -99),
new Window(2, -57, 136, -69),
new Window(3, -19, 136, -45),
new Window(4, -19, 136, -37),
new Window(5, -73, 136, -23)
}),
new Room("Crypts", "cr", new Window[]{
new Window(1, -7, 136, -5),
new Window(2, -31, 136, 1),
new Window(3, -57, 136, 41)
}),
new Room("Graveyard", "gy", new Window[]{
new Window(1, -71, 136, 63),
new Window(2, -33, 136, 101),
new Window(3, -13, 136, 67)
}),
new Room("Balcony", "b", new Window[]{
new Window(1, -65, 148, -37),
new Window(2, -113, 148, 5),
new Window(3, -107, 144, 25),
new Window(4, -83, 136, 55)
}),
new Room("Great Hall", "gh", new Window[]{
new Window(1, -39, 148, -27),
new Window(2, -55, 148, 31),
new Window(3, -63, 152, 31)
})
};
}
@Contract(" -> new")
public static Room @NotNull [] getAA() {
return new Room[]{
new Room("Park Entrance", "ent", new Window[]{
new Window(1, 13, 144, 63),
new Window(2, -45, 144, 31),
new Window(3, -43, 144, 21),
new Window(4, -21, 144, -11),
new Window(5, 45, 144, 27)
}),
new Room("Roller Coaster", "rc", new Window[]{
new Window(1, -25, 144, 79),
new Window(2, -57, 144, 55)
}),
new Room("Ferris Wheel", "fw", new Window[]{
new Window(1, 55, 144, 63),
new Window(2, 35, 144, 89)
}),
new Room("Bumper Cars", "bp", new Window[]{
new Window(1, 45, 146, -27),
new Window(2, 67, 146, -3)
})
};
}
@Contract(" -> new")
public static Room @NotNull [] getP() {
return new Room[]{
new Room("Cell Blocks", "cb", new Window[]{
new Window(1, 109, 144, 21),
new Window(2, 109, 144, -19),
new Window(3, 193, 158, -17),
new Window(4, 193, 158, 19),
}),
new Room("Corridors", "co", new Window[]{
new Window(1, 189, 144, 21),
new Window(2, 251, 144, 31),
new Window(3, 219, 144, -21),
new Window(4, 233, 144, -49),
new Window(5, 221, 158, -21),
new Window(6, 255, 158, 9),
new Window(7, 273, 158, 51),
}),
new Room("Cafeteria", "ca", new Window[]{
new Window(1, 249, 144, 73),
new Window(2, 189, 144, 25),
}),
new Room("Visitor's Room", "v", new Window[]{
new Window(1, 261, 144, -45),
new Window(2, 273, 144, 13)
}),
new Room("Library", "l", new Window[]{
new Window(1, 265, 158, 9),
new Window(2, 263, 158, -47),
}),
new Room("Monitor Room", "mt", new Window[]{
new Window(1, 201, 158, 25),
new Window(2, 197, 158, 3),
}),
new Room("Medical Bay", "mt", new Window[]{
new Window(1, 249, 158, 31),
new Window(2, 223, 158, 53),
}),
new Room("The Courts", "cs", new Window[]{
new Window(1, 285, 144, 81),
new Window(2, 247, 144, 157),
new Window(3, 211, 144, 157),
}),
new Room("Offices", "o", new Window[]{
new Window(1, 153, 144, 161),
new Window(2, 151, 144, 191),
new Window(3, 99, 144, 181),
new Window(4, 123, 144, 163),
new Window(5, 71, 144, 163),
}),
new Room("Head Manager's Office", "h", new Window[]{
new Window(1, 179, 158, 169),
new Window(2, 179, 158, 177),
new Window(3, 79, 158, 177),
new Window(4, 79, 158, 169),
}),
new Room("Basement Corridor", "bc", new Window[]{
new Window(1, 231, 130, 29),
new Window(2, 193, 130, 31),
}),
new Room("The Deep", "d", new Window[]{
new Window(1, 167, 126, -45),
new Window(2, 163, 122, 13),
new Window(3, 193, 122, 13),
}),
new Room("Boiler Room", "b", new Window[]{
new Window(1, 107, 126, -11),
new Window(2, 125, 126, 25),
new Window(3, 163, 130, -45),
new Window(4, 107, 130, -45),
}),
new Room("Yard", "y", new Window[]{
new Window(1, 185, 144, 79),
new Window(2, 189, 144, 119),
new Window(3, 107, 144, 121),
}),
new Room("Alleyway", "a", new Window[]{
new Window(1, 101, 144, 133),
new Window(2, 147, 144, 117)
}),
new Room("Guard's Gunroom", "gr", new Window[]{
new Window(1, 29, 148, 75),
new Window(2, 29, 144, 43),
new Window(3, 65, 126, 5),
}),
new Room("Guard's Quarters", "q", new Window[]{
new Window(1, 83, 148, 83),
new Window(2, 57, 148, 35),
}),
new Room("Stockage", "st", new Window[]{
new Window(1, 241, 130, -25),
new Window(2, 227, 130, -45),
}),
new Room("Kitchen", "k", new Window[]{
new Window(1, 261, 144, 33),
new Window(2, 271, 144, 45),
}),
new Room("Isolation", "i", new Window[]{
new Window(1, 75, 144, 91),
new Window(2, 29, 144, 87),
}),
new Room("Showers", "sh", new Window[]{
new Window(1, 37, 144, 15),
new Window(2, 37, 144, -11),
}),
new Room("???", "?", new Window[]{
new Window(1, 191, 126, -67),
new Window(2, 207, 126, -67),
}),
};
}
public String getName() {
return name;
}
public Window[] getWindows() {
return windows;
}
public void increaseActiveWindowCount() {
this.activeWindowCount++;
}
public void resetActiveWindowCount() {
this.activeWindowCount = 0;
}
public int getActiveWindowCount() {
return activeWindowCount;
}
public String getSlaString() {
StringBuilder slaString = new StringBuilder(String.format("§6%s§r§d %x§e:", this.getName(), activeWindowCount));
for (Window window : this.windows) {
if (window.isActive()) slaString.append("§2 ").append(alias).append(window.getID());
else if (!ZombiesUtils.getInstance().getConfig().isSlaShortened())
slaString.append("§c ").append(alias).append(window.getID());
}
return slaString.toString();
}
}

View file

@ -1,110 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.game.windows;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.game.enums.Map;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Optional;
public class SLA {
public static SLA instance = null;
private final int[] offset = new int[3];
private final Room[] rooms;
public SLA(@NotNull Map map) {
switch (map) {
case DEAD_END:
this.rooms = Room.getDE();
break;
case BAD_BLOOD:
this.rooms = Room.getBB();
break;
case ALIEN_ARCADIUM:
this.rooms = Room.getAA();
break;
case PRISON:
this.rooms = new Room[0];
break;
default:
throw new IllegalStateException("Unexpected value: " + map);
}
}
public static Optional<SLA> getInstance() {
return Optional.ofNullable(instance);
}
public static void drop() {
instance = null;
}
public void rotate(int rotations) {
for (Room room : rooms) {
for (Window window : room.getWindows()) {
window.rotate(rotations);
}
}
}
public void mirrorX() {
for (Room room : rooms) {
for (Window window : room.getWindows()) {
window.mirrorX();
}
}
System.out.println("Co3 now at " + Arrays.toString(rooms[0].getWindows()[0].getXYZ()));
}
public void mirrorZ() {
for (Room room : rooms) {
for (Window window : room.getWindows()) {
window.mirrorZ();
}
}
short[] win0 = rooms[0].getWindows()[0].getXYZ();
ZombiesUtils.getInstance().getLogger().info("Window \"0\" is now at %s %s %s" + (double) win0[0] / 2 + (double) win0[1] / 2 + (double) win0[2] / 2);
}
private void refreshActives() {
final EntityPlayerSP player = Minecraft.getMinecraft().thePlayer;
final double[] playerCoords = {
(player.posX - offset[0]),
player.posY - offset[1],
player.posZ - offset[2]
};
for (Room room : rooms) {
room.resetActiveWindowCount();
for (Window window : room.getWindows()
) {
double distanceDoubledThenSquared = 0;
for (int i = 0; i < 3; i++) {
distanceDoubledThenSquared += ((playerCoords[i] * 2 - window.getXYZ()[i]) * (playerCoords[i] * 2 - window.getXYZ()[i]));
}
// (2x)²+(2y)²+(2z)² = 4(x²+y²+z²) = 4d²
final int slaRange = 50;
if (distanceDoubledThenSquared < 4 * slaRange * slaRange) {
window.setActive(true);
room.increaseActiveWindowCount();
} else window.setActive(false);
}
}
}
public Room[] getRooms() {
this.refreshActives();
return this.rooms;
}
public void resetOffset() {
Arrays.fill(this.offset, 0);
}
public void setOffset(int[] offset) {
System.arraycopy(offset, 0, this.offset, 0, 3);
}
}

View file

@ -1,75 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.game.windows;
public class Window {
private final short[] xyz = new short[3];
private final int id;
private boolean isActive;
public Window(int id, int x, int y, int z) {
this.id = id;
xyz[0] = (short) x;
xyz[1] = (short) y;
xyz[2] = (short) z;
}
public int getID() {
return id;
}
public short[] getXYZ() {
return xyz;
}
public boolean isActive() {
return isActive;
}
public void setActive(boolean active) {
isActive = active;
}
private void rotateCounterClockwise() {
final short x = xyz[0], z = xyz[2];
xyz[0] = (short) -z;
xyz[2] = x;
}
private void mirrorBoth() {
xyz[0] = (short) -xyz[0];
xyz[2] = (short) -xyz[2];
}
private void rotateClockwise() {
final short x = xyz[0], z = xyz[2];
xyz[0] = z;
xyz[2] = (short) -x;
}
public void rotate(int rotations) {
rotations %= 4;
switch (rotations) {
case -3:
case 1:
rotateCounterClockwise();
break;
case -2:
case 2:
mirrorBoth();
break;
case -1:
case 3:
rotateClockwise();
break;
case 0:
break;
}
}
public void mirrorX() {
xyz[0] = (short) -xyz[0];
}
public void mirrorZ() {
xyz[2] = (short) -xyz[2];
}
}

View file

@ -1,35 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.handlers;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.game.enums.Difficulty;
import com.github.stachelbeere1248.zombiesutils.utils.LanguageSupport;
import net.minecraftforge.client.event.ClientChatReceivedEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.jetbrains.annotations.NotNull;
import java.util.regex.Pattern;
public class ChatHandler {
private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("§[0-9A-FK-ORZ]", Pattern.CASE_INSENSITIVE);
public ChatHandler() {
}
@SubscribeEvent
public void difficultyChange(@NotNull final ClientChatReceivedEvent event) {
if (event.message.getUnformattedText().contains(":")) return;
final String message = STRIP_COLOR_PATTERN.matcher(event.message.getUnformattedText()).replaceAll("").trim();
if (LanguageSupport.containsHard(message)) {
ZombiesUtils.getInstance().getGameManager().setDifficulty(Difficulty.HARD);
} else if (LanguageSupport.containsRIP(message)) {
ZombiesUtils.getInstance().getGameManager().setDifficulty(Difficulty.RIP);
} else {
ZombiesUtils.getInstance().getGameManager().getGame().ifPresent(
game -> {
if (LanguageSupport.isHelicopterIncoming(message)) game.helicopter();
}
);
}
}
}

View file

@ -1,31 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.handlers;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import net.minecraftforge.common.MinecraftForge;
public class Handlers {
private final RenderGameOverlayHandler renderer;
private final RenderPlayerHandler renderPlayerHandler;
public Handlers() {
renderer = new RenderGameOverlayHandler();
renderPlayerHandler = new RenderPlayerHandler();
}
public void registerAll() {
MinecraftForge.EVENT_BUS.register(ZombiesUtils.getInstance().getConfig());
MinecraftForge.EVENT_BUS.register(renderer);
MinecraftForge.EVENT_BUS.register(renderPlayerHandler);
MinecraftForge.EVENT_BUS.register(new TickHandler());
MinecraftForge.EVENT_BUS.register(new ChatHandler());
MinecraftForge.EVENT_BUS.register(new KeyInputHandler());
}
public RenderGameOverlayHandler getRenderer() {
return renderer;
}
public RenderPlayerHandler getRenderPlayerHandler() {
return renderPlayerHandler;
}
}

View file

@ -1,37 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.handlers;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.config.Hotkeys;
import com.github.stachelbeere1248.zombiesutils.game.waves.WaveTiming;
import net.minecraft.client.Minecraft;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
public class KeyInputHandler {
@SubscribeEvent
public void onKeyInput(InputEvent event) {
if (Minecraft.getMinecraft().currentScreen != null) return;
if (event instanceof InputEvent.KeyInputEvent) {
if (Keyboard.getEventKey() == '\0') return;
if (Keyboard.getEventKeyState()) {
final Hotkeys hotkeys = ZombiesUtils.getInstance().getHotkeys();
if (Keyboard.getEventKey() == hotkeys.getChatMacro().getKeyCode()) Minecraft.getMinecraft().thePlayer
.sendChatMessage(ZombiesUtils.getInstance().getConfig().getChatMacro());
else if (Keyboard.getEventKey() == hotkeys.getRlSpawn().getKeyCode()) {
ZombiesUtils.getInstance().getHandlers().getRenderer().toggleRL();
WaveTiming.toggleRL();
} else if (Keyboard.getEventKey() == hotkeys.getPlayerVisiblity().getKeyCode()) {
ZombiesUtils.getInstance().getHandlers().getRenderPlayerHandler().togglePlayerVisibility();
}
}
} else if (event instanceof InputEvent.MouseInputEvent) {
if (Mouse.getEventButtonState()) {
if (Mouse.getEventButton() == 1) ZombiesUtils.getInstance().getHandlers().getRenderer().addClick();
}
}
}
}

View file

@ -1,166 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.handlers;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.game.waves.Prefix;
import com.github.stachelbeere1248.zombiesutils.game.waves.Wave;
import com.github.stachelbeere1248.zombiesutils.game.windows.Room;
import com.github.stachelbeere1248.zombiesutils.game.windows.SLA;
import com.github.stachelbeere1248.zombiesutils.timer.Game;
import com.github.stachelbeere1248.zombiesutils.utils.Scoreboard;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
public class RenderGameOverlayHandler {
private final byte[] clicks = new byte[20];
private final FontRenderer fontRenderer;
private int rl = 0;
private int clickPointer = 0;
public RenderGameOverlayHandler() {
this.fontRenderer = Objects.requireNonNull(Minecraft.getMinecraft().fontRendererObj, "FontRenderer must not be null!");
}
private static String getTimeString(long timerTicks) {
final long minutesPart = (timerTicks * 50) / 60000;
final long secondsPart = ((timerTicks * 50) % 60000) / 1000;
final long tenthSecondsPart = ((timerTicks * 50) % 1000) / 100;
return String.format("%d:%02d.%d", minutesPart, secondsPart, tenthSecondsPart);
}
void toggleRL() {
if (rl == 0) rl = ZombiesUtils.getInstance().getConfig().getOffset();
else rl = 0;
}
@SubscribeEvent
public void onRenderGameOverlay(RenderGameOverlayEvent.@NotNull Post event) {
if (event.type != RenderGameOverlayEvent.ElementType.TEXT) return;
ZombiesUtils.getInstance().getGameManager().getGame().ifPresent(
game -> {
renderTime(game.getTimer().getRoundTime());
renderSpawnTime(
game
);
}
);
if (!Minecraft.getMinecraft().gameSettings.showDebugInfo)
SLA.getInstance().ifPresent(sla -> renderSla(sla.getRooms()));
if (ZombiesUtils.getInstance().getConfig().getCpsToggle()) renderCPS();
}
private void renderTime(short timerTicks) {
if (Scoreboard.isNotZombies()) return;
final String time = getTimeString(timerTicks);
final int width = fontRenderer.getStringWidth(time);
final ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
final int screenWidth = scaledResolution.getScaledWidth();
final int screenHeight = scaledResolution.getScaledHeight();
fontRenderer.drawStringWithShadow(
time,
screenWidth - width,
screenHeight - fontRenderer.FONT_HEIGHT,
0xFFFFFF
);
}
private void renderSla(Room @NotNull [] rooms) {
int y = 0;
for (Room room : rooms) {
if (ZombiesUtils.getInstance().getConfig().isSlaShortened() && room.getActiveWindowCount() == 0) continue;
fontRenderer.drawStringWithShadow(
room.getSlaString(),
1,
1 + y * fontRenderer.FONT_HEIGHT,
0xFFFFFF
);
y++;
}
}
private void renderSpawnTime(final Game game) {
if (!ZombiesUtils.getInstance().getConfig().getSST() || Scoreboard.isNotZombies()) return;
final ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
final int screenWidth = scaledResolution.getScaledWidth();
final int screenHeight = scaledResolution.getScaledHeight();
final Wave[] round = ZombiesUtils.getInstance().getGameData().getRound(game.getGameMode(), game.getRound()).getWaves();
final int roundTime = game.getTimer().getRoundTime();
final int length = round.length + 1;
int heightIndex = 0;
int color = 0xFFFF55;
boolean faded = false;
for (Wave wave : round) {
final short spawnTime = (short) (wave.getTime() + rl);
if (roundTime > spawnTime) {
if (!ZombiesUtils.getInstance().getConfig().isSpawntimeShortened()) faded = true;
else {
heightIndex++;
continue;
}
} else faded = false;
final String spawnTimeString = " W" + (heightIndex + 1) + ": " + getTimeString(spawnTime);
int width = fontRenderer.getStringWidth(spawnTimeString);
fontRenderer.drawStringWithShadow(
spawnTimeString,
screenWidth - width,
screenHeight - fontRenderer.FONT_HEIGHT * (length - heightIndex),
faded ? 0x666666 : color
);
for (Prefix prefix : wave.getPrefixes()) {
final String prefixString = prefix.getPrefix() + " ";
width += fontRenderer.getStringWidth(prefixString);
fontRenderer.drawStringWithShadow(
prefixString,
screenWidth - width,
screenHeight - fontRenderer.FONT_HEIGHT * (length - heightIndex),
faded ? prefix.getFadedColor() : prefix.getColor()
);
}
if (!faded) color = 0xAAAAAA;
heightIndex++;
}
}
public void renderCPS() {
final String cps = String.format("%2d", getClicks());
final ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
final int screenWidth = scaledResolution.getScaledWidth();
final int width = fontRenderer.getStringWidth(cps);
fontRenderer.drawStringWithShadow(
cps,
screenWidth - width,
0,
0xAAAAAA
);
}
public int getClicks() {
int i = 0;
for (byte tick : clicks) {
i += tick;
}
return i;
}
public void addClick() {
clicks[clickPointer]++;
}
public void tick() {
clickPointer = (clickPointer + 1) % 20;
clicks[clickPointer] = 0;
}
}

View file

@ -1,43 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.handlers;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.Vec3;
import net.minecraftforge.client.event.RenderPlayerEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.jetbrains.annotations.NotNull;
public class RenderPlayerHandler {
private boolean visible;
public RenderPlayerHandler() {
this.visible = ZombiesUtils.getInstance().getConfig().getPlayerVis();
}
@SubscribeEvent
public void onRender(RenderPlayerEvent.@NotNull Pre event) {
if (event.entityPlayer.isPlayerSleeping() || event.entityPlayer.isUser()) return;
if (inRange(event.entityPlayer.getPositionVector())) {
event.setCanceled(!visible);
}
}
private boolean inRange(@NotNull Vec3 playerOther) {
final int range = ZombiesUtils.getInstance().getConfig().getPlayerVisRange();
return playerOther.squareDistanceTo(Minecraft.getMinecraft().thePlayer.getPositionVector()) <= range * range;
}
public void togglePlayerVisibility() {
this.visible = !this.visible;
final String s;
if (this.visible) {
s = "§dPlayer Visibility §e is now §rON";
} else {
s = "§dPlayer Visibility §e is now §8OFF";
}
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
s
));
}
}

View file

@ -1,36 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.handlers;
import com.github.stachelbeere1248.zombiesutils.timer.Timer;
import com.github.stachelbeere1248.zombiesutils.utils.Scoreboard;
import net.minecraft.entity.monster.EntityZombie;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
public class Round1Correction {
private final Timer timer;
private final String serverNumber;
public Round1Correction(Timer timer, String serverNumber) {
this.timer = timer;
this.serverNumber = serverNumber;
}
@SubscribeEvent
public void onWaveSpawn(@NotNull EntityJoinWorldEvent event) {
if (!(event.entity instanceof EntityZombie)) return;
if (Scoreboard.isNotZombies()) return;
final Optional<String> s = Scoreboard.getServerNumber();
if (!s.isPresent()) return;
if (!s.get().equals(serverNumber)) {
MinecraftForge.EVENT_BUS.unregister(this);
return;
}
this.timer.correctStartTick();
MinecraftForge.EVENT_BUS.unregister(this);
}
}

View file

@ -1,188 +0,0 @@
package xyz.stachel.zombiesutils.init;
import org.spongepowered.asm.lib.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* A mixin plugin to automatically discover all mixins in the current JAR.
* <p>
* This mixin plugin automatically scans your entire JAR (or class directory, in case of an in-IDE launch) for classes inside of your
* mixin package and registers those. It does this recursively for sub packages of the mixin package as well. This means you will need
* to only have mixin classes inside of your mixin package, which is good style anyway.
*
* @author Linnea Gräf
*/
public class AutoDiscoveryMixinPlugin implements IMixinConfigPlugin {
private static final List<AutoDiscoveryMixinPlugin> mixinPlugins = new ArrayList<>();
public static List<AutoDiscoveryMixinPlugin> getMixinPlugins() {
return mixinPlugins;
}
private String mixinPackage;
@Override
public void onLoad(String mixinPackage) {
this.mixinPackage = mixinPackage;
mixinPlugins.add(this);
}
/**
* Resolves the base class root for a given class URL. This resolves either the JAR root, or the class file root.
* In either case the return value of this + the class name will resolve back to the original class url, or to other
* class urls for other classes.
*/
public URL getBaseUrlForClassUrl(URL classUrl) {
String string = classUrl.toString();
if (classUrl.getProtocol().equals("jar")) {
try {
return new URL(string.substring(4).split("!")[0]);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
if (string.endsWith(".class")) {
try {
return new URL(string.replace("\\", "/")
.replace(getClass().getCanonicalName()
.replace(".", "/") + ".class", ""));
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
return classUrl;
}
/**
* Get the package that contains all the mixins. This value is set by mixin itself using {@link #onLoad}.
*/
public String getMixinPackage() {
return mixinPackage;
}
/**
* Get the path inside the class root to the mixin package
*/
public String getMixinBaseDir() {
return mixinPackage.replace(".", "/");
}
/**
* A list of all discovered mixins.
*/
private List<String> mixins = null;
/**
* Try to add mixin class ot the mixins based on the filepath inside of the class root.
* Removes the {@code .class} file suffix, as well as the base mixin package.
* <p><b>This method cannot be called after mixin initialization.</p>
*
* @param className the name or path of a class to be registered as a mixin.
*/
public void tryAddMixinClass(String className) {
String norm = (className.endsWith(".class") ? className.substring(0, className.length() - ".class".length()) : className)
.replace("\\", "/")
.replace("/", ".");
if (norm.startsWith(getMixinPackage() + ".") && !norm.endsWith(".")) {
mixins.add(norm.substring(getMixinPackage().length() + 1));
}
}
/**
* Search through the JAR or class directory to find mixins contained in {@link #getMixinPackage()}
*/
@Override
public List<String> getMixins() {
if (mixins != null) return mixins;
System.out.println("Trying to discover mixins");
mixins = new ArrayList<>();
URL classUrl = getClass().getProtectionDomain().getCodeSource().getLocation();
System.out.println("Found classes at " + classUrl);
Path file;
try {
file = Paths.get(getBaseUrlForClassUrl(classUrl).toURI());
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
System.out.println("Base directory found at " + file);
if (Files.isDirectory(file)) {
walkDir(file);
} else {
walkJar(file);
}
System.out.println("Found mixins: " + mixins);
return mixins;
}
/**
* Search through directory for mixin classes based on {@link #getMixinBaseDir}.
*
* @param classRoot The root directory in which classes are stored for the default package.
*/
private void walkDir(Path classRoot) {
System.out.println("Trying to find mixins from directory");
try (Stream<Path> classes = Files.walk(classRoot.resolve(getMixinBaseDir()))) {
classes.map(it -> classRoot.relativize(it).toString())
.forEach(this::tryAddMixinClass);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* Read through a JAR file, trying to find all mixins inside.
*/
private void walkJar(Path file) {
System.out.println("Trying to find mixins from jar file");
try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(file))) {
ZipEntry next;
while ((next = zis.getNextEntry()) != null) {
tryAddMixinClass(next.getName());
zis.closeEntry();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
@Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
@Override
public String getRefMapperConfig() {
return null;
}
@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
return true;
}
@Override
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
}
}

View file

@ -1,67 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.mixin;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.utils.InvalidMapException;
import com.github.stachelbeere1248.zombiesutils.utils.LanguageSupport;
import com.github.stachelbeere1248.zombiesutils.utils.ScoardboardException;
import com.github.stachelbeere1248.zombiesutils.utils.Scoreboard;
import net.minecraft.client.Minecraft;
import net.minecraft.client.network.NetHandlerPlayClient;
import net.minecraft.network.play.server.S29PacketSoundEffect;
import net.minecraft.network.play.server.S45PacketTitle;
import net.minecraft.util.ChatComponentText;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(NetHandlerPlayClient.class)
public class MixinNetHandlerPlayClient {
@Unique
private boolean zombies_utils$alienUfoOpened;
@Inject(method = "handleSoundEffect", at = @At(value = "HEAD"))
private void handleSound(S29PacketSoundEffect packetIn, CallbackInfo ci) {
zombies_utils$handleSound(packetIn);
}
@Inject(method = "handleTitle", at = @At(value = "HEAD"))
private void handleTitle(S45PacketTitle packetIn, CallbackInfo ci) {
zombies_utils$handleTitle(packetIn);
}
@Unique
private void zombies_utils$handleSound(@NotNull S29PacketSoundEffect packet) {
if (Scoreboard.isNotZombies()) return;
final String soundEffect = packet.getSoundName();
if (!(
soundEffect.equals("mob.wither.spawn")
|| (soundEffect.equals("mob.guardian.curse")
&& !zombies_utils$alienUfoOpened)
)) return;
zombies_utils$alienUfoOpened = soundEffect.equals("mob.guardian.curse");
try {
ZombiesUtils.getInstance().getGameManager().splitOrNew(Scoreboard.getRound());
} catch (ScoardboardException | InvalidMapException e) {
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("§cFailed to start or split timer. Please send a log to Stachelbeere1248."));
ZombiesUtils.getInstance().getLogger().error(e.fillInStackTrace());
}
}
@Unique
private void zombies_utils$handleTitle(@NotNull S45PacketTitle packet) {
if (packet.getType() != S45PacketTitle.Type.TITLE) return;
if (Scoreboard.isNotZombies()) return;
final String message = packet.getMessage().getUnformattedText().trim();
String serverNumber;
serverNumber = Scoreboard.getServerNumber().orElse("");
if (LanguageSupport.isWin(message)) ZombiesUtils.getInstance().getGameManager().endGame(serverNumber, true);
if (LanguageSupport.isLoss(message)) ZombiesUtils.getInstance().getGameManager().endGame(serverNumber, false);
}
}

View file

@ -1,129 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.timer;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.game.GameMode;
import com.github.stachelbeere1248.zombiesutils.game.enums.Difficulty;
import com.github.stachelbeere1248.zombiesutils.game.enums.Map;
import com.github.stachelbeere1248.zombiesutils.game.windows.SLA;
import com.github.stachelbeere1248.zombiesutils.handlers.Round1Correction;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.Category;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.files.CategoryFile;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.files.GameFile;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ChatComponentText;
import net.minecraftforge.common.MinecraftForge;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.jetbrains.annotations.NotNull;
public class Game {
private final Timer timer;
private final GameFile gameFile;
private final boolean roundOneRecorded;
private GameMode gameMode;
private Category category;
private int round;
private boolean escaping;
public Game(@NotNull final Map map, final String serverNumber) {
this.gameMode = GameMode.getNormalForMap(map);
this.timer = new Timer();
this.gameFile = new GameFile(serverNumber, map);
this.category = new Category();
this.round = 1;
this.roundOneRecorded = true;
MinecraftForge.EVENT_BUS.register(new Round1Correction(this.timer, serverNumber));
if (ZombiesUtils.getInstance().getConfig().isSlaToggled()) SLA.instance = new SLA(map);
}
public Game(@NotNull final Map map, final String serverNumber, final int round) {
this.gameMode = GameMode.getNormalForMap(map);
this.timer = new Timer();
this.gameFile = new GameFile(serverNumber, map);
this.category = new Category();
this.round = round;
this.roundOneRecorded = (round == 1);
MinecraftForge.EVENT_BUS.register(new Round1Correction(this.timer, serverNumber));
if (ZombiesUtils.getInstance().getConfig().isSlaToggled()) SLA.instance = new SLA(map);
}
public Timer getTimer() {
return this.timer;
}
public void setCategory(Category category) {
this.category = category;
}
public void changeDifficulty(final Difficulty difficulty) {
this.gameMode = this.gameMode.appliedDifficulty(difficulty);
}
public int getRound() {
return round;
}
public GameMode getGameMode() {
return gameMode;
}
public void pass(int round) {
if ((round == 0) || (this.round == round + 1) || (this.timer.getRoundTime() < 100)) {
ZombiesUtils.getInstance().getLogger().debug("SPLIT CANCELLED");
return;
}
try {
record();
} catch (Exception e) {
ZombiesUtils.getInstance().getLogger().error(ExceptionUtils.getStackTrace(e));
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("§cError recording splits"));
}
this.timer.split();
this.round = round + 1;
}
public void helicopter() {
if (!gameMode.isMap(Map.PRISON)) {
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("§cEscaping without playing prison???"));
ZombiesUtils.getInstance().getLogger().error(Thread.currentThread().getStackTrace());
return;
}
this.escaping = true;
this.pass(30);
}
private void record() {
this.compareSegment();
if (this.roundOneRecorded) this.compareBest();
this.gameFile.setSegment(this.round, this.timer.getRoundTime());
}
public void compareSegment() throws IndexOutOfBoundsException {
if (this.escaping) return;
final CategoryFile categoryFile = this.category.getByGameMode(this.gameMode);
final short bestSegment = categoryFile.getBestSegment(round);
final int roundTime = this.getTimer().getRoundTime();
if (bestSegment == (short) 0) categoryFile.setBestSegment(round, roundTime);
else if (roundTime < bestSegment) categoryFile.setBestSegment(round, roundTime);
final RecordMessageSender recordMessageSender = new RecordMessageSender(this.category.getName(), round, roundTime, bestSegment);
recordMessageSender.roundSplit();
recordMessageSender.sendRecordMessage();
}
public void compareBest() throws IndexOutOfBoundsException {
final CategoryFile categoryFile = this.category.getByGameMode(this.gameMode);
final int round = this.escaping ? 31 : this.round;
final int personalBest = categoryFile.getPersonalBest(round);
final int gameTime = this.timer.getGameTime();
if (personalBest == 0) categoryFile.setPersonalBest(round, gameTime);
else if (gameTime < personalBest) categoryFile.setPersonalBest(round, gameTime);
final RecordMessageSender recordMessageSender = new RecordMessageSender(category.getName(), round, gameTime, personalBest);
if (!escaping) recordMessageSender.gameSplit();
else recordMessageSender.helicopterSplit();
recordMessageSender.sendRecordMessage();
}
}

View file

@ -1,78 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.timer;
import com.github.stachelbeere1248.zombiesutils.game.enums.Difficulty;
import com.github.stachelbeere1248.zombiesutils.game.enums.Map;
import com.github.stachelbeere1248.zombiesutils.utils.InvalidMapException;
import com.github.stachelbeere1248.zombiesutils.utils.ScoardboardException;
import com.github.stachelbeere1248.zombiesutils.utils.Scoreboard;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Optional;
import java.util.Set;
public class GameManager {
private final HashMap<String, Game> GAMES;
private Optional<Difficulty> queuedDifficulty = Optional.empty();
private String queuedDifficultyServer = "INVALID";
public GameManager() {
GAMES = new HashMap<>();
}
public Optional<Game> getGame() {
return Scoreboard.getServerNumber().map(GAMES::get);
}
public void endGame(final String serverNumber, final boolean isWin) {
if (!GAMES.containsKey(serverNumber)) return;
final Game game = GAMES.get(serverNumber);
if (isWin) {
switch (game.getGameMode().getMap()) {
case DEAD_END:
case BAD_BLOOD:
case PRISON:
game.pass(30);
break;
case ALIEN_ARCADIUM:
game.pass(105);
break;
}
}
GAMES.remove(serverNumber);
}
public void splitOrNew(int round) throws ScoardboardException, InvalidMapException {
final String serverNumber = Scoreboard.getServerNumber().orElseThrow(ScoardboardException::new);
if (GAMES.containsKey(serverNumber)) {
if (round == 0) newGame(serverNumber);
else GAMES.get(serverNumber).pass(round);
} else newGame(serverNumber);
}
private void newGame(@NotNull String serverNumber) throws InvalidMapException {
final Game game = new Game(Map.getMap().orElseThrow(InvalidMapException::new), serverNumber);
if (serverNumber.equals(queuedDifficultyServer)) {
this.queuedDifficulty.ifPresent(game::changeDifficulty);
}
this.queuedDifficulty = Optional.empty();
this.GAMES.put(serverNumber, game);
}
public void setDifficulty(@NotNull Difficulty difficulty) {
this.queuedDifficultyServer = Scoreboard.getServerNumber().orElse("INVALID");
if (this.GAMES.containsKey(this.queuedDifficultyServer)) {
this.GAMES.get(this.queuedDifficultyServer).changeDifficulty(difficulty);
} else this.queuedDifficulty = Optional.of(difficulty);
}
public Set<String> getGames() {
return this.GAMES.keySet();
}
public void killAll() {
GAMES.clear();
}
}

View file

@ -1,104 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.timer;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.event.ClickEvent;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.ChatStyle;
import org.jetbrains.annotations.Contract;
public class RecordMessageSender {
private final StringBuilder recordMessage;
private final int newTime;
private final int oldTime;
private final int round;
private final String deltaString;
private final String timeString;
private String copyString;
public RecordMessageSender(final String categoryName, final int round, final int newTime, final int oldTime) {
this.recordMessage = new StringBuilder(
"§l§a▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬\n§e Category: §d" + categoryName
);
this.newTime = newTime;
this.oldTime = oldTime;
this.deltaString = oldTime != 0 ? " " + formattedDelta(newTime, oldTime) : "";
this.timeString = formattedTime(newTime);
this.round = round;
}
public void sendRecordMessage() {
final ChatComponentText message = new ChatComponentText(
this.recordMessage
.append("\n§l§a▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬")
.toString()
);
message.setChatStyle(new ChatStyle().setChatClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, this.copyString)));
Minecraft.getMinecraft().thePlayer.addChatMessage(message);
}
public void gameSplit() {
final String announcement = newTime < oldTime && ZombiesUtils.getInstance().getConfig().getAnnouncePB() ?
"\n§e§l***§6§l NEW PERSONAL BEST! §e§l***" : "";
this.recordMessage.append(announcement)
.append("\n§cRound ")
.append(round)
.append("§e finished at §a")
.append(timeString)
.append("§9")
.append(deltaString)
.append("§e!");
this.copyString = deltaString.isEmpty() ?
String.format("Round %d finished at %s!", round, timeString) :
String.format("Round %d finished at %s (%s)!", round, timeString, deltaString);
}
public void roundSplit() {
final String announcement = newTime < oldTime && ZombiesUtils.getInstance().getConfig().getAnnouncePB() ?
"\n§e§l***§6§l NEW BEST SEGMENT! §e§l***" : "";
final String timeString = formattedTime(newTime);
final String deltaString = oldTime != 0 ? formattedDelta(newTime, oldTime) : "";
this.recordMessage.append(announcement)
.append("\n§cRound ")
.append(round)
.append("§e took §a")
.append(timeString)
.append("§9")
.append(deltaString)
.append("§e!");
this.copyString = deltaString.isEmpty() ?
String.format("Round %d took %s!", round, timeString) :
String.format("Round %d took %s (%s)!", round, timeString, deltaString);
}
public void helicopterSplit() {
final String announcement = newTime < oldTime && ZombiesUtils.getInstance().getConfig().getAnnouncePB() ?
"\n§e§l***§6§l NEW PERSONAL BEST! §e§l***" : "";
this.recordMessage.append(announcement)
.append("\n§8§lHelicopter §r§ecalled at §a")
.append(timeString)
.append("§9")
.append(deltaString)
.append("§e!");
this.copyString = deltaString.isEmpty() ?
String.format("Helicopter called at %s!", timeString) :
String.format("Helicopter called at %s (%s)!", timeString, deltaString);
}
@Contract(pure = true)
private String formattedTime(int time) {
time *= 50;
return String.format("%d:%02d.%d%d",
time / 60000,
(time % 60000) / 1000,
(time % 1000) / 100,
(time % 100) / 10
);
}
@Contract(pure = true)
private String formattedDelta(int newTime, int oldTime) {
final double delta = (double) (newTime - oldTime) / 20;
return String.format("%+.2f", delta);
}
}

View file

@ -1,35 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.timer;
import net.minecraft.client.Minecraft;
public class Timer {
private long startTick;
private int roundStart;
public Timer() {
this.startTick = this.getCurrentTick();
}
public void correctStartTick() {
this.startTick = this.getCurrentTick() - 200;
}
void split() {
this.roundStart = this.getGameTime();
}
public int getGameTime() {
return (int) (getCurrentTick() - startTick);
}
public short getRoundTime() {
return (short) (getGameTime() - roundStart);
}
private long getCurrentTick() {
if (Minecraft.getMinecraft() == null || Minecraft.getMinecraft().theWorld == null) return 0;
return Minecraft.getMinecraft().theWorld.getTotalWorldTime();
}
}

View file

@ -1,79 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.game.GameMode;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.files.CategoryFile;
import org.jetbrains.annotations.NotNull;
import java.io.File;
public class Category {
private static String selectedCategory = ZombiesUtils.getInstance().getConfig().getDefaultCategory();
public final CategoryFile[] categoryFiles = new CategoryFile[10];
private final String name;
public Category() {
final File category;
if (ZombiesUtils.isHypixel()) category = new File(new File("zombies", "splits"), selectedCategory);
else category = new File(new File("zombies", "practise-splits"), selectedCategory);
categoryFiles[0] = new CategoryFile(category, GameMode.DEAD_END);
categoryFiles[1] = new CategoryFile(category, GameMode.DEAD_END_HARD);
categoryFiles[2] = new CategoryFile(category, GameMode.DEAD_END_RIP);
categoryFiles[3] = new CategoryFile(category, GameMode.BAD_BLOOD);
categoryFiles[4] = new CategoryFile(category, GameMode.BAD_BLOOD_HARD);
categoryFiles[5] = new CategoryFile(category, GameMode.BAD_BLOOD_RIP);
categoryFiles[6] = new CategoryFile(category, GameMode.ALIEN_ARCADIUM);
categoryFiles[7] = new CategoryFile(category, GameMode.PRISON);
categoryFiles[8] = new CategoryFile(category, GameMode.PRISON_HARD);
categoryFiles[9] = new CategoryFile(category, GameMode.PRISON_RIP);
this.name = Category.selectedCategory;
}
public static void setSelectedCategory(String selectedCategory) {
Category.selectedCategory = selectedCategory;
ZombiesUtils.getInstance().getGameManager().getGame().ifPresent(game -> game.setCategory(new Category()));
}
public static String[] getCategories() {
File dir;
if (ZombiesUtils.isHypixel()) dir = new File("zombies" + File.separator + "splits");
else dir = new File("zombies" + File.separator + "practise-splits");
if (dir.isDirectory()) return dir.list();
else return new String[0];
}
public CategoryFile getByGameMode(@NotNull GameMode gameMode) {
switch (gameMode) {
case DEAD_END:
return categoryFiles[0];
case DEAD_END_HARD:
return categoryFiles[1];
case DEAD_END_RIP:
return categoryFiles[2];
case BAD_BLOOD:
return categoryFiles[3];
case BAD_BLOOD_HARD:
return categoryFiles[4];
case BAD_BLOOD_RIP:
return categoryFiles[5];
case ALIEN_ARCADIUM:
return categoryFiles[6];
case PRISON:
return categoryFiles[7];
case PRISON_HARD:
return categoryFiles[8];
case PRISON_RIP:
return categoryFiles[9];
default:
throw new IllegalStateException("Unexpected value: " + gameMode);
}
}
public String getName() {
return name;
}
}

View file

@ -1,58 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.data.CategoryData;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.files.CategoryFile;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import org.apache.commons.io.FileUtils;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class FileManager {
private static CategoryData readDataFromFile(@NotNull File file) throws FileNotFoundException, JsonSyntaxException {
if (!file.exists()) throw new FileNotFoundException();
String dataJson;
Gson gson = new Gson();
try {
dataJson = FileUtils.readFileToString(file, StandardCharsets.UTF_16);
} catch (IOException e) {
throw new RuntimeException(e);
}
if (dataJson == null || dataJson.trim().isEmpty()) throw new JsonSyntaxException("File empty");
return gson.fromJson(dataJson, CategoryData.class);
}
public static void createDataFile(@NotNull File file, ISplitsData data) {
try {
//noinspection ResultOfMethodCallIgnored
file.getParentFile().mkdirs();
//noinspection ResultOfMethodCallIgnored
file.createNewFile();
writeDataToFile(file, data);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void writeDataToFile(File file, @NotNull ISplitsData data) throws IOException {
FileUtils.writeStringToFile(file, data.toJSON(), StandardCharsets.UTF_16);
}
@NotNull
public static CategoryData categoryReadOrCreate(CategoryFile file) {
CategoryData data;
try {
data = FileManager.readDataFromFile(file);
} catch (FileNotFoundException | JsonSyntaxException ignored) {
data = new CategoryData(file.getGameMode().getMap());
FileManager.createDataFile(file, data);
}
return data;
}
}

View file

@ -1,5 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder;
public interface ISplitsData {
String toJSON();
}

View file

@ -1,58 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder.data;
import com.github.stachelbeere1248.zombiesutils.game.enums.Map;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.ISplitsData;
import com.google.gson.Gson;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
public class CategoryData implements ISplitsData {
private final short[] bestSegments; //in ticks, max ~27 min
private final int[] personalBests; //in ticks,
public CategoryData(@NotNull Map map) throws IllegalStateException {
switch (map) {
case ALIEN_ARCADIUM:
bestSegments = new short[105];
personalBests = new int[105];
break;
case DEAD_END:
case BAD_BLOOD:
bestSegments = new short[30];
personalBests = new int[30];
break;
case PRISON:
bestSegments = new short[30];
personalBests = new int[31];
break;
default:
throw new IllegalStateException("Not a map: " + map);
}
Arrays.fill(bestSegments, (short) 0);
Arrays.fill(personalBests, 0);
}
@Override
@NotNull
public String toJSON() {
Gson gson = new Gson();
return gson.toJson(this, CategoryData.class);
}
public short getBestSegment(int index) {
return bestSegments[index];
}
public int getPersonalBest(int index) {
return personalBests[index];
}
public void setBestSegment(int index, int ticks) {
bestSegments[index] = (short) ticks;
}
public void setPersonalBest(int index, int ticks) {
personalBests[index] = ticks;
}
}

View file

@ -1,41 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder.data;
import com.github.stachelbeere1248.zombiesutils.game.enums.Map;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.ISplitsData;
import com.google.gson.Gson;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
public class GameData implements ISplitsData {
private final short[] segments;
public GameData(@NotNull Map map) throws IllegalStateException {
switch (map) {
case ALIEN_ARCADIUM:
segments = new short[105];
break;
case DEAD_END:
case BAD_BLOOD:
segments = new short[30];
break;
case PRISON:
segments = new short[31];
break;
default:
throw new IllegalStateException("Not a map: " + map);
}
Arrays.fill(segments, (short) 0);
}
@Override
@NotNull
public String toJSON() {
Gson gson = new Gson();
return gson.toJson(this.segments);
}
public void setSegment(int index, int ticks) {
segments[index] = (short) ticks;
}
}

View file

@ -1,60 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder.files;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.game.GameMode;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.FileManager;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.data.CategoryData;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ChatComponentText;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.jetbrains.annotations.NotNull;
import java.io.File;
public class CategoryFile extends File {
private final CategoryData data;
private final GameMode gameMode;
public CategoryFile(File category, @NotNull GameMode gameMode) {
// Game-directory -> custom category -> file named "MAP_DIFFICULTY.times"
// Content encoded in StandardCharsets.UTF_16
super(category, gameMode + ".times");
this.gameMode = gameMode;
this.data = FileManager.categoryReadOrCreate(this);
}
public short getBestSegment(int round) {
return this.data.getBestSegment(round - 1);
}
public void setBestSegment(int round, int ticks) {
this.data.setBestSegment(round - 1, ticks);
try {
FileManager.writeDataToFile(this, this.data);
} catch (Exception e) {
ZombiesUtils.getInstance().getLogger().error(ExceptionUtils.getStackTrace(e));
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Error saving segment to splits-file. Please Contact Stachelbeere1248."));
}
}
public int getPersonalBest(int round) {
return data.getPersonalBest(round - 1);
}
public void setPersonalBest(int round, int ticks) {
this.data.setPersonalBest(round - 1, ticks);
try {
FileManager.writeDataToFile(this, this.data);
} catch (Exception e) {
ZombiesUtils.getInstance().getLogger().error(ExceptionUtils.getStackTrace(e));
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Error saving pb to splits-file. Please Contact Stachelbeere1248."));
}
}
public GameMode getGameMode() {
return gameMode;
}
}

View file

@ -1,44 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder.files;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.game.enums.Map;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.FileManager;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.data.GameData;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ChatComponentText;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
public class GameFile extends File {
private final GameData data;
public GameFile(String serverNumber, Map map) {
super("zombies" + File.separator + "runs", formattedTime() + "_" + serverNumber + ".seg");
this.data = new GameData(map);
FileManager.createDataFile(this, this.data);
}
@NotNull
private static String formattedTime() {
final LocalDateTime dateTime = LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES);
return dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME).replace(':', '-').replaceFirst("T", "_");
}
public void setSegment(int round, int ticks) {
this.data.setSegment(round - 1, ticks);
try {
FileManager.writeDataToFile(this, this.data);
} catch (Exception e) {
ZombiesUtils.getInstance().getLogger().error(ExceptionUtils.getStackTrace(e));
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Error saving segment to run-file. Please Contact Stachelbeere1248."));
}
}
}

View file

@ -1,4 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.utils;
public class InvalidMapException extends Exception {
}

View file

@ -1,78 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.utils;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.regex.Pattern;
@SuppressWarnings("SpellCheckingInspection")
public class LanguageSupport {
private static final String[] LANGUAGES = {
"EN",
"FR",
"DE"
};
public static boolean isLoss(@NotNull String input) {
final String[] words = {
"§cGame Over!",
"§cPartie terminée!",
"§cDas Spiel ist vorbei!"
};
return Arrays.asList(words).contains(input);
}
public static boolean isWin(@NotNull String input) {
final String[] words = {
"§aYou Win!",
"§aVous avez gagné!",
"§aDu gewinnst!"
};
return Arrays.asList(words).contains(input);
}
public static boolean containsHard(@NotNull String input) {
final String[] words = {
"Hard Difficulty",
"Difficulté Hard",
"Hard Schwierigkeitsgrad",
"困难",
"困難"
};
return Arrays.stream(words).anyMatch(input::contains);
}
public static boolean containsRIP(@NotNull String input) {
final String[] words = {
"RIP Difficulty",
"Difficulté RIP",
"RIP Schwierigkeitsgrad",
"安息"
};
return Arrays.stream(words).anyMatch(input::contains);
}
public static boolean isHelicopterIncoming(@NotNull String input) {
final String[] words = {
"The Helicopter is on its way! Hold out for 120 more seconds!"
};
return Arrays.stream(words).anyMatch(input::contains);
}
public static @NotNull Pattern roundPattern(@NotNull String language) {
switch (language) {
case "EN":
return Pattern.compile("Round ([0-9]{1,3})");
case "FR":
return Pattern.compile("Manche ([0-9]{1,3})");
case "DE":
return Pattern.compile("Runde ([0-9]{1,3})");
default:
throw new IllegalStateException("Unexpected value: " + language);
}
}
public static String[] getLanguages() {
return LANGUAGES;
}
}

View file

@ -1,6 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.utils;
public class ScoardboardException extends Exception {
public ScoardboardException() {
}
}

View file

@ -1,2 +0,0 @@
public net.minecraft.client.renderer.GlStateManager$Color

View file

@ -1,692 +0,0 @@
[
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"SLIME"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"SLIME"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"SLIME"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"SLIME"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"SLIME"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"SLIME"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"SLIME"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"SLIME"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"SLIME"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"SLIME"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"SLIME"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON",
"BOSS"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"HBM"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"HBM"
]
},
{
"ticks": 480,
"prefixes": [
"HBM"
]
},
{
"ticks": 760,
"prefixes": [
"HBM"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 760,
"prefixes": [
"WINDOW",
"HBM"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 760,
"prefixes": [
"WINDOW",
"HBM"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"HBM",
"BOSS"
]
},
{
"ticks": 680,
"prefixes": [
"HBM",
"WINDOW"
]
}
]
}
]

View file

@ -1,687 +0,0 @@
[
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"SLIME"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"SLIME"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"SLIME"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"SLIME"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"SLIME"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"SLIME"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON",
"BOSS"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"HBM"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"HBM"
]
},
{
"ticks": 480,
"prefixes": [
"HBM"
]
},
{
"ticks": 760,
"prefixes": [
"HBM"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 760,
"prefixes": [
"WINDOW",
"HBM"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 760,
"prefixes": [
"WINDOW",
"HBM"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"HBM",
"BOSS"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"HBM"
]
}
]
}
]

View file

@ -1,697 +0,0 @@
[
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"SLIME"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"SLIME"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"SLIME"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"SLIME"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"SLIME"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"SLIME"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"SLIME"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"SLIME"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"SLIME"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"SLIME"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"SLIME"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"SLIME"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"BOSS"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"WITHER_SKELETON"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"WITHER_SKELETON",
"BOSS"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"WITHER_SKELETON",
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"HBM"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"HBM"
]
},
{
"ticks": 480,
"prefixes": [
"HBM"
]
},
{
"ticks": 760,
"prefixes": [
"HBM"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 760,
"prefixes": [
"WINDOW",
"HBM"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW",
"HBM"
]
},
{
"ticks": 760,
"prefixes": [
"WINDOW",
"HBM"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"HBM",
"BOSS"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW",
"HBM",
"BOSS"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW",
"HBM"
]
}
]
}
]

View file

@ -1,658 +0,0 @@
[
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 700,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 700,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 740,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 880,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 940,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 760,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 960,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"BLAZES"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW",
"BOSS"
]
},
{
"ticks": 920,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 940,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 940,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"BLAZES"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 940,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 940,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 980,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 460,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 880,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 460,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 460,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 840,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 460,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 860,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 460,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 860,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 460,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 720,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 880,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 840,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 840,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW",
"BOSS"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
}
]

View file

@ -1,655 +0,0 @@
[
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 700,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 700,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 740,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 880,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 940,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 760,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 960,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"BLAZES"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 920,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 940,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 940,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"BLAZES"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 940,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 940,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 980,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 460,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 880,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 460,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 460,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 840,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 460,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 860,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 460,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 860,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 460,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 720,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 880,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 840,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 840,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
}
]

View file

@ -1,663 +0,0 @@
[
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 700,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 700,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 740,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 880,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 940,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 760,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW",
"BOSS"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 960,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"BLAZES"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW",
"BOSS"
]
},
{
"ticks": 920,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 940,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 940,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 940,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 940,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 980,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 460,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 880,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 460,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 460,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 840,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 460,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 860,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"BOSS"
]
},
{
"ticks": 460,
"prefixes": [
"WINDOW",
"BOSS"
]
},
{
"ticks": 860,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 460,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 720,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 880,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 840,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 840,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"BOSS"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW",
"BOSS"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW",
"BOSS"
]
}
]
}
]

View file

@ -1,738 +0,0 @@
[
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"CELL"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"CELL"
]
},
{
"ticks": 340,
"prefixes": [
"CELL"
]
},
{
"ticks": 480,
"prefixes": [
"CELL"
]
},
{
"ticks": 620,
"prefixes": [
"CELL",
"POLICE"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 340,
"prefixes": [
"CELL"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 620,
"prefixes": [
"CELL",
"POLICE"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW",
"POLICE"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"CELL",
"POLICE"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"CELL"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW",
"CELL"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW",
"CELL"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"CELL",
"POLICE"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 800,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 500,
"prefixes": [
"CELL"
]
},
{
"ticks": 700,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 500,
"prefixes": [
"CELL"
]
},
{
"ticks": 900,
"prefixes": [
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 800,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 740,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 740,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 800,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 740,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 840,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 800,
"prefixes": [
"BOSS",
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 700,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1100,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1500,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 800,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1100,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 0,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 300,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1200,
"prefixes": [
"BOSS",
"WINDOW"
]
},
{
"ticks": 1500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1800,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 2100,
"prefixes": [
"WINDOW"
]
}
]
}
]

View file

@ -1,738 +0,0 @@
[
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"CELL"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"CELL"
]
},
{
"ticks": 340,
"prefixes": [
"CELL"
]
},
{
"ticks": 480,
"prefixes": [
"CELL"
]
},
{
"ticks": 620,
"prefixes": [
"CELL",
"POLICE"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 340,
"prefixes": [
"CELL"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 620,
"prefixes": [
"CELL",
"POLICE"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW",
"POLICE"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"CELL",
"POLICE"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"CELL"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW",
"CELL"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW",
"CELL"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"CELL",
"POLICE"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 800,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 500,
"prefixes": [
"CELL"
]
},
{
"ticks": 700,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 500,
"prefixes": [
"CELL"
]
},
{
"ticks": 900,
"prefixes": [
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 800,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 740,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 740,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 800,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 740,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 840,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 800,
"prefixes": [
"BOSS",
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 700,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1100,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1500,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 800,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1100,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 0,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 300,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1200,
"prefixes": [
"BOSS",
"WINDOW"
]
},
{
"ticks": 1500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1800,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 2100,
"prefixes": [
"WINDOW"
]
}
]
}
]

View file

@ -1,738 +0,0 @@
[
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"CELL"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"CELL"
]
},
{
"ticks": 340,
"prefixes": [
"CELL"
]
},
{
"ticks": 480,
"prefixes": [
"CELL"
]
},
{
"ticks": 620,
"prefixes": [
"CELL",
"POLICE"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 340,
"prefixes": [
"CELL"
]
},
{
"ticks": 480,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 620,
"prefixes": [
"CELL",
"POLICE"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW",
"POLICE"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"CELL",
"POLICE"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"CELL"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW",
"CELL"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW",
"CELL"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"CELL",
"POLICE"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 800,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 500,
"prefixes": [
"CELL"
]
},
{
"ticks": 700,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 500,
"prefixes": [
"CELL"
]
},
{
"ticks": 900,
"prefixes": [
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 800,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW",
"POLICE"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 740,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 680,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 740,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 800,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 740,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 440,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 840,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 800,
"prefixes": [
"BOSS",
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 400,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 700,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1100,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1500,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 800,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1000,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1100,
"prefixes": [
"WINDOW"
]
}
]
},
{
"waves": [
{
"ticks": 200,
"prefixes": [
"BOSS"
]
}
]
},
{
"waves": [
{
"ticks": 0,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 300,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 600,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 900,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1200,
"prefixes": [
"BOSS",
"WINDOW"
]
},
{
"ticks": 1500,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 1800,
"prefixes": [
"WINDOW"
]
},
{
"ticks": 2100,
"prefixes": [
"WINDOW"
]
}
]
}
]

View file

@ -2,17 +2,17 @@
{
"modid": "${modid}",
"name": "Zombies Utils",
"description": "An all-in-one mod for Hypixel Zombies. Targets legit speed-runners.",
"description": "",
"version": "${version}",
"mcversion": "${mcversion}",
"url": "https://github.com/Stachelbeere1248/zombies-utils",
"updateUrl": "https://github.com/Stachelbeere1248/zombies-utils/blob/master/update.json",
"updateUrl": "",
"authorList": [
"Stachelbeere1248"
],
"credits": "Seosean, thamid-23",
"logoFile": "zombiesutils.png",
"logoFile": "",
"screenshots": [],
"dependencies": []
}
]
]

View file

@ -1,8 +1,11 @@
{
"package": "${basePackage}.mixin",
"plugin": "${basePackage}.init.AutoDiscoveryMixinPlugin",
"package": "com.github.stachelbeere1248.zombiesutils.mixin",
"refmap": "mixins.${modid}.refmap.json",
"minVersion": "0.7",
"compatibilityLevel": "JAVA_8",
"__comment": "You do not need to manually register mixins in this template. Check the auto discovery mixin plugin for more info."
"mixins": [
],
"client": [
"MixinNetHandlerPlayClient"
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 273 B

View file

@ -1,13 +0,0 @@
{
"homepage": "https://github.com/Stachelbeere1248/zombies-utils/releases",
"promos": {
"1.8.9-latest": "1.3.7",
"1.8.9-recommended": "1.3.7"
},
"1.8.9": {
"1.3.6": "SST Prefixes, added update checker url",
"1.3.7-PRE_1": "patch: difficiluty detection",
"1.3.7-PRE_2": "fix instant crash",
"1.3.7": "mark release, fix faded prefix colors"
}
}