Compare commits

...

8 commits

Author SHA1 Message Date
3c8478e6a0 Update README.md
Some checks failed
Run Gradle Build / gradle (push) Has been cancelled
Validate Gradle Wrapper / Validation (push) Has been cancelled
2025-03-14 21:32:30 +01:00
4792caa473
patch prefix color, reformat project, publish as release 2024-12-13 00:44:38 +01:00
263308e4a1
fix crash 2024-12-12 21:30:00 +01:00
Stachelbeere1248
5643a2dbcc
Update mcmod.info 2024-12-12 21:22:55 +01:00
a3035fadcd
fix version numbers 2024-12-12 21:12:57 +01:00
Stachelbeere1248
8ded7e50d5
Update README.md 2024-12-12 20:57:02 +01:00
13613d0003
Merge branch 'master' of https://github.com/Stachelbeere1248/zombies-utils 2024-12-12 20:53:09 +01:00
022b9b7390
perhaps patch difficulty 2024-12-12 20:52:06 +01:00
28 changed files with 240 additions and 153 deletions

View file

@ -1,53 +1,80 @@
# zombies-utils
##### Download the latest release [here](https://github.com/Stachelbeere1248/zombies-utils/releases/latest)
##### Go to release page [here](https://git.stachel.xyz/Stachelbeere1248/zombies-utils/releases)
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.
## For Users
The timer automatically splits every round. The PB/Segment recorder automatically distinguishes maps and difficulties, but not player count.
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.
- Macro Message: The Message to be sent when pressing the Chat Macro Key. Do NOT use "§" as symbol.
- Player Visibility: Whether to enable PlayerVisibility by default.
- CPS Counter: A simple CPS Counter which shows the amount of clicks within the last 20 gameticks.
- `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.
### 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
- /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>
- /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
- /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.
- /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.
### Extra
- Managing split-categories: In your game directory is a folder called "zombies" which contains the folder "splits". You can simply rename or delete the folders inside "splits". 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.
- 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.

View file

@ -1,6 +1,6 @@
loom.platform=forge
org.gradle.jvmargs=-Xmx2g
baseGroup = com.github.stachelbeere1248.zombiesutils
mcVersion = 1.8.9
modid = zombiesutils
version = 1.3.6
baseGroup=com.github.stachelbeere1248.zombiesutils
mcVersion=1.8.9
modid=zombiesutils
version=1.3.7

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<!-- Filter out Hypixel scoreboard and sound errors -->
<RegexFilter regex="Error executing task.*|Unable to play unknown soundEvent.*" onMatch="DENY" onMismatch="NEUTRAL"/>
<RegexFilter regex="Error executing task.*|Unable to play unknown soundEvent.*" onMatch="DENY"
onMismatch="NEUTRAL"/>
</Configuration>

View file

@ -19,7 +19,7 @@ pluginManagement {
}
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version("0.6.0")
id("org.gradle.toolchains.foojay-resolver-convention") version ("0.6.0")
}

View file

@ -1,8 +1,8 @@
package com.github.stachelbeere1248.zombiesutils.commands;
import com.github.stachelbeere1248.zombiesutils.game.windows.SLA;
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;

View file

@ -68,8 +68,7 @@ public class ZombiesUtilsCommand extends CommandBase {
default:
return Collections.emptyList();
}
}
else if (args.length == 3) {
} else if (args.length == 3) {
switch (args[0]) {
case "timer":
switch (args[1]) {

View file

@ -41,6 +41,7 @@ public class Hotkeys {
public KeyBinding getRlSpawn() {
return rlSpawn;
}
public KeyBinding getPlayerVisiblity() {
return playerVisiblity;
}

View file

@ -1,6 +1,5 @@
package com.github.stachelbeere1248.zombiesutils.config;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.utils.LanguageSupport;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;
@ -27,6 +26,7 @@ public class ZombiesUtilsConfig {
private Property cpsCounter;
private Property announcePB;
private Property playerVis;
private Property playerVisRange;
public ZombiesUtilsConfig(Configuration config) {
this.config = config;
@ -34,9 +34,7 @@ public class ZombiesUtilsConfig {
}
private void read() {
ZombiesUtils.getInstance().getLogger().debug("Loading config...");
config.load();
ZombiesUtils.getInstance().getLogger().debug("Config loaded.");
//SST
sstHud = config.get(
@ -99,6 +97,22 @@ public class ZombiesUtilsConfig {
"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(
@ -114,12 +128,6 @@ public class ZombiesUtilsConfig {
"T",
"The Text to be sent when pressing the chat-macro hotkey"
);
playerVis = config.get(
Configuration.CATEGORY_GENERAL,
"playervis",
false,
"If players should always be visible"
);
cpsCounter = config.get(
Configuration.CATEGORY_GENERAL,
"cps",
@ -151,14 +159,21 @@ public class ZombiesUtilsConfig {
);
}
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("Player visibility", playerVis),
new CustomConfigElement("CPS counter", cpsCounter)
);
@ -204,13 +219,19 @@ public class ZombiesUtilsConfig {
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) {

View file

@ -8,6 +8,7 @@ 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");
@ -23,28 +24,27 @@ public class GameData {
}
public Round getRound(@NotNull GameMode gameMode, int round) {
final Round[] selected;
switch (gameMode) {
case DEAD_END:
return roundData[0][round-1];
return roundData[0][round - 1];
case DEAD_END_HARD:
return roundData[1][round-1];
return roundData[1][round - 1];
case DEAD_END_RIP:
return roundData[2][round-1];
return roundData[2][round - 1];
case BAD_BLOOD:
return roundData[3][round-1];
return roundData[3][round - 1];
case BAD_BLOOD_HARD:
return roundData[4][round-1];
return roundData[4][round - 1];
case BAD_BLOOD_RIP:
return roundData[5][round-1];
return roundData[5][round - 1];
case ALIEN_ARCADIUM:
return roundData[6][round-1];
return roundData[6][round - 1];
case PRISON:
return roundData[7][round-1];
return roundData[7][round - 1];
case PRISON_HARD:
return roundData[8][round-1];
return roundData[8][round - 1];
case PRISON_RIP:
return roundData[9][round-1];
return roundData[9][round - 1];
default:
throw new IllegalStateException("Invalid GameMode: " + gameMode);
}

View file

@ -12,11 +12,28 @@ public enum GameMode {
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;
}
@ -24,6 +41,7 @@ public enum GameMode {
public Difficulty getDifficulty() {
return this.difficulty;
}
public GameMode appliedDifficulty(final Difficulty difficulty) {
switch (this.map) {
case DEAD_END:
@ -59,23 +77,8 @@ public enum GameMode {
throw new IllegalStateException("Invalid Map: " + this.map);
}
}
public boolean isMap(Map map) {
return this.getMap() == map;
}
@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);
}
}
}

View file

@ -14,7 +14,7 @@ public enum Map {
public static Optional<Map> getMap() {
World world = Minecraft.getMinecraft().theWorld;
BlockPos pos = new BlockPos(44,71,0);
BlockPos pos = new BlockPos(44, 71, 0);
if (!world.isBlockLoaded(pos) || Scoreboard.isNotZombies()) return Optional.empty();
Block block = world.getBlockState(pos).getBlock();

View file

@ -1,7 +1,7 @@
package com.github.stachelbeere1248.zombiesutils.game.sla;
import com.github.stachelbeere1248.zombiesutils.game.windows.SLA;
import com.github.stachelbeere1248.zombiesutils.game.enums.Map;
import com.github.stachelbeere1248.zombiesutils.game.windows.SLA;
@SuppressWarnings("SpellCheckingInspection")
public class QuickSLA {

View file

@ -1,39 +1,37 @@
package com.github.stachelbeere1248.zombiesutils.game.waves;
import java.util.stream.IntStream;
public enum Prefix {
BOSS(0xCC5555, "B"),
BLAZES(0xEFB61F, "BL"),
SLIME(0x88FF88,"S"),
HBM(0x2A415F, "HBM"),
WITHER_SKELETON(0x888888, "WS"),
OLD_ONE(0x55AA55, "O1"),
GIANT(0x00FFFF,"G"),
POLICE(0x16537E,"P"),
CELL(0xFF8234,"C"),
WINDOW(0xAAAAAA,"W");
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) {
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(final int fact, final int div) {
final int normalColor = this.getColor();
final int B = normalColor % 0xFF;
final int G = (normalColor - B) % (0xFF * 0xFF);
final int R = (normalColor - (B + G));
return IntStream.of(R, G, B).map(i -> (i * fact) / div).sum();
public int getFadedColor() {
return fadedColor;
}
}

View file

@ -1,8 +1,5 @@
package com.github.stachelbeere1248.zombiesutils.game.waves;
import java.util.Arrays;
import java.util.stream.Collectors;
public class Round {
private final Wave[] waves;

View file

@ -9,9 +9,10 @@ public class Wave {
this.ticks = ticks;
this.prefixes = prefixes;
}
public Wave(final short ticks) {
this.ticks = ticks;
this.prefixes = new Prefix[]{Prefix.WINDOW};
this.prefixes = new Prefix[]{ Prefix.WINDOW };
}
public short getTime() {

View file

@ -8,6 +8,7 @@ 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(

View file

@ -17,18 +17,19 @@ public class ChatHandler {
@SubscribeEvent
public void difficultyChange(@NotNull final ClientChatReceivedEvent event) {
ZombiesUtils.getInstance().getGameManager().getGame().ifPresent(
game -> {
String message = STRIP_COLOR_PATTERN.matcher(event.message.getUnformattedText()).replaceAll("").trim();
if (message.contains(":")) return;
if (LanguageSupport.containsHard(message)) {
game.changeDifficulty(Difficulty.HARD);
} else if (LanguageSupport.containsRIP(message)) {
game.changeDifficulty(Difficulty.RIP);
} else if (LanguageSupport.isHelicopterIncoming(message)) {
game.helicopter();
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

@ -2,10 +2,9 @@ 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.Round;
import com.github.stachelbeere1248.zombiesutils.game.waves.Wave;
import com.github.stachelbeere1248.zombiesutils.game.windows.SLA;
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;
@ -52,7 +51,8 @@ public class RenderGameOverlayHandler {
}
);
if (!Minecraft.getMinecraft().gameSettings.showDebugInfo) SLA.getInstance().ifPresent(sla -> renderSla(sla.getRooms()));
if (!Minecraft.getMinecraft().gameSettings.showDebugInfo)
SLA.getInstance().ifPresent(sla -> renderSla(sla.getRooms()));
if (ZombiesUtils.getInstance().getConfig().getCpsToggle()) renderCPS();
}
@ -87,6 +87,7 @@ public class RenderGameOverlayHandler {
y++;
}
}
private void renderSpawnTime(final Game game) {
if (!ZombiesUtils.getInstance().getConfig().getSST() || Scoreboard.isNotZombies()) return;
final ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
@ -123,7 +124,7 @@ public class RenderGameOverlayHandler {
prefixString,
screenWidth - width,
screenHeight - fontRenderer.FONT_HEIGHT * (length - heightIndex),
faded ? prefix.getFadedColor(3,5) : prefix.getColor()
faded ? prefix.getFadedColor() : prefix.getColor()
);
}
if (!faded) color = 0xAAAAAA;
@ -132,7 +133,7 @@ public class RenderGameOverlayHandler {
}
public void renderCPS() {
public void renderCPS() {
final String cps = String.format("%2d", getClicks());
final ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
final int screenWidth = scaledResolution.getScaledWidth();

View file

@ -24,8 +24,10 @@ public class RenderPlayerHandler {
}
private boolean inRange(@NotNull Vec3 playerOther) {
return playerOther.squareDistanceTo(Minecraft.getMinecraft().thePlayer.getPositionVector()) <= 16;
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;

View file

@ -39,8 +39,8 @@ public class MixinNetHandlerPlayClient {
if (!(
soundEffect.equals("mob.wither.spawn")
|| (soundEffect.equals("mob.guardian.curse")
&& !zombies_utils$alienUfoOpened)
|| (soundEffect.equals("mob.guardian.curse")
&& !zombies_utils$alienUfoOpened)
)) return;
zombies_utils$alienUfoOpened = soundEffect.equals("mob.guardian.curse");
@ -59,8 +59,8 @@ public class MixinNetHandlerPlayClient {
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);
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

@ -3,8 +3,8 @@ 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.windows.SLA;
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;
@ -35,6 +35,7 @@ public class Game {
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();
@ -49,17 +50,21 @@ public class Game {
}
public Timer getTimer() {
return this.timer;
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;
}
@ -78,6 +83,7 @@ public class Game {
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???"));
@ -89,9 +95,9 @@ public class Game {
}
private void record() {
this.compareSegment();
if (this.roundOneRecorded) this.compareBest();
this.gameFile.setSegment(this.round, this.timer.getRoundTime());
this.compareSegment();
if (this.roundOneRecorded) this.compareBest();
this.gameFile.setSegment(this.round, this.timer.getRoundTime());
}
public void compareSegment() throws IndexOutOfBoundsException {

View file

@ -1,17 +1,20 @@
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.List;
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<>();
@ -26,14 +29,14 @@ public class GameManager {
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;
case DEAD_END:
case BAD_BLOOD:
case PRISON:
game.pass(30);
break;
case ALIEN_ARCADIUM:
game.pass(105);
break;
}
}
GAMES.remove(serverNumber);
@ -43,11 +46,25 @@ public class GameManager {
public void splitOrNew(int round) throws ScoardboardException, InvalidMapException {
final String serverNumber = Scoreboard.getServerNumber().orElseThrow(ScoardboardException::new);
if (GAMES.containsKey(serverNumber)) {
if (round == 0) GAMES.put(serverNumber, new Game(Map.getMap().orElseThrow(InvalidMapException::new), serverNumber));
if (round == 0) newGame(serverNumber);
else GAMES.get(serverNumber).pass(round);
} else {
GAMES.put(serverNumber, new Game(Map.getMap().orElseThrow(InvalidMapException::new), serverNumber, round + 1));
} 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() {

View file

@ -15,13 +15,14 @@ public class RecordMessageSender {
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.deltaString = oldTime != 0 ? " " + formattedDelta(newTime, oldTime) : "";
this.timeString = formattedTime(newTime);
this.round = round;
}
@ -29,8 +30,8 @@ public class RecordMessageSender {
public void sendRecordMessage() {
final ChatComponentText message = new ChatComponentText(
this.recordMessage
.append("\n§l§a▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬")
.toString()
.append("\n§l§a▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬")
.toString()
);
message.setChatStyle(new ChatStyle().setChatClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, this.copyString)));
Minecraft.getMinecraft().thePlayer.addChatMessage(message);
@ -69,6 +70,7 @@ public class RecordMessageSender {
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***" : "";
@ -82,6 +84,7 @@ public class RecordMessageSender {
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;
@ -92,6 +95,7 @@ public class RecordMessageSender {
(time % 100) / 10
);
}
@Contract(pure = true)
private String formattedDelta(int newTime, int oldTime) {
final double delta = (double) (newTime - oldTime) / 20;

View file

@ -14,9 +14,11 @@ public class Timer {
public void correctStartTick() {
this.startTick = this.getCurrentTick() - 200;
}
void split() {
this.roundStart = this.getGameTime();
}
public int getGameTime() {
return (int) (getCurrentTick() - startTick);
}

View file

@ -51,6 +51,7 @@ public class LanguageSupport {
};
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!"
@ -70,6 +71,7 @@ public class LanguageSupport {
throw new IllegalStateException("Unexpected value: " + language);
}
}
public static String[] getLanguages() {
return LANGUAGES;
}

View file

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

View file

@ -1,10 +1,13 @@
{
"homepage": "https://github.com/Stachelbeere1248/zombies-utils/releases",
"promos": {
"1.8.9-latest" : "1.3.4",
"1.8.9-recommended" : "1.3.4"
"1.8.9-latest": "1.3.7",
"1.8.9-recommended": "1.3.7"
},
"1.8.9" : {
"1.3.5" : "SST Prefixes, added update checker url"
"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"
}
}