├── src └── main │ ├── resources │ ├── icon.png │ ├── icon_aprilfools.png │ ├── assets │ │ └── scathapro │ │ │ ├── sounds │ │ │ ├── scappa.ogg │ │ │ ├── metal_pipe_falling.ogg │ │ │ ├── achievements │ │ │ │ ├── unlock.ogg │ │ │ │ └── unlock_hidden.ogg │ │ │ └── alert_modes │ │ │ │ ├── meme │ │ │ │ ├── high_heat.ogg │ │ │ │ ├── jerry_spawn.ogg │ │ │ │ ├── bedrock_wall.ogg │ │ │ │ ├── goblin_spawn.ogg │ │ │ │ ├── scatha_spawn.ogg │ │ │ │ ├── worm_prespawn.ogg │ │ │ │ ├── scatha_pet_drop.ogg │ │ │ │ ├── regular_worm_spawn.ogg │ │ │ │ └── worm_spawn_cooldown_end.ogg │ │ │ │ └── anime │ │ │ │ ├── bedrock_wall.ogg │ │ │ │ ├── scatha_spawn.ogg │ │ │ │ ├── worm_prespawn.ogg │ │ │ │ ├── scatha_pet_drop.ogg │ │ │ │ └── regular_worm_spawn.ogg │ │ │ ├── textures │ │ │ ├── lock.png │ │ │ ├── overlay │ │ │ │ ├── scatha.png │ │ │ │ ├── worm.png │ │ │ │ ├── scatha_pet.png │ │ │ │ ├── googly_eye_inner.png │ │ │ │ ├── googly_eye_outer.png │ │ │ │ ├── scatha_pet_epic.png │ │ │ │ ├── scatha_pet_rare.png │ │ │ │ ├── scatha_icons │ │ │ │ │ ├── default.png │ │ │ │ │ ├── mode_anime.png │ │ │ │ │ ├── mode_meme.png │ │ │ │ │ ├── mode_custom.png │ │ │ │ │ ├── scatha_spin.png │ │ │ │ │ └── mode_custom_overlay.png │ │ │ │ ├── scatha_pet_legendary.png │ │ │ │ └── anomalous_desire_progress_bar.png │ │ │ ├── overlay_preview_background.png │ │ │ └── gui │ │ │ │ └── achievements │ │ │ │ ├── button_icon.png │ │ │ │ ├── progress_bar.png │ │ │ │ └── dropdown_carets.png │ │ │ ├── lang │ │ │ └── en_US.lang │ │ │ └── sounds.json │ ├── mixins.scathapro.json │ └── mcmod.info │ └── java │ └── namelessju │ └── scathapro │ ├── miscellaneous │ ├── enums │ │ ├── Rarity.java │ │ ├── SkyblockArea.java │ │ ├── WormInteractionAction.java │ │ ├── DropMessageRarityMode.java │ │ ├── OldLobbyAlertTriggerMode.java │ │ ├── DropMessageStatsMode.java │ │ └── WormStatsType.java │ ├── PetDrop.java │ ├── sound │ │ ├── ScappaSound.java │ │ ├── ScathaProSound.java │ │ └── ScathaProMovingSound.java │ ├── ScathaProKeyBinding.java │ ├── OverlayIconEyePositions.java │ └── StackedScissorCheck.java │ ├── gui │ ├── elements │ │ ├── IClickActionButton.java │ │ ├── HoverArea.java │ │ ├── DoneButton.java │ │ ├── IGuiElement.java │ │ ├── BooleanSettingButton.java │ │ ├── ITooltipElement.java │ │ ├── ScappaModeButton.java │ │ ├── SubMenuButton.java │ │ ├── ImageButton.java │ │ ├── ScathaProButton.java │ │ ├── ScathaProSlider.java │ │ └── DeleteCustomAlertModeButton.java │ ├── menus │ │ ├── ConfigGui.java │ │ ├── MiscSettingsGui.java │ │ ├── CustomAlertModeGui.java │ │ ├── alerts │ │ │ ├── AlertConfigurationGui.java │ │ │ ├── AlertStatesGui.java │ │ │ ├── AlertSettingsGui.java │ │ │ └── AlertTitleSettingsGui.java │ │ ├── overlay │ │ │ ├── OverlayMiscSettingsGui.java │ │ │ ├── OverlaySettingsGui.java │ │ │ ├── OverlayGeneralSettingsGui.java │ │ │ ├── OverlayScathaPercentageSettingsGui.java │ │ │ └── OverlayPositionSettingsGui.java │ │ ├── FakeBanGui.java │ │ ├── MainSettingsGui.java │ │ ├── KeybindingsGui.java │ │ ├── AchievementsGui.java │ │ ├── InfoMessageGui.java │ │ ├── ChatMessageSettingsGui.java │ │ ├── SoundSettingsGui.java │ │ ├── AchievementSettingsGui.java │ │ └── RotationAnglesSettingsGui.java │ └── lists │ │ ├── AlertsGuiList.java │ │ └── OverlayComponentsGuiList.java │ ├── events │ ├── WormPreSpawnEvent.java │ ├── RealDayStartedEvent.java │ ├── BedrockWallDetectedEvent.java │ ├── DailyStatsResetEvent.java │ ├── DailyScathaFarmingStreakChangedEvent.java │ ├── WormKillEvent.java │ ├── WormDespawnEvent.java │ ├── CrystalHollowsDayStartedEvent.java │ ├── ScathaPetDropEvent.java │ ├── WormEvent.java │ ├── OverlayInitEvent.java │ ├── WormHitEvent.java │ ├── SkyblockAreaDetectedEvent.java │ ├── ModUpdateEvent.java │ ├── AchievementUnlockedEvent.java │ ├── DetectedEntityRegisteredEvent.java │ ├── WormSpawnEvent.java │ └── TickEvent.java │ ├── entitydetection │ ├── entitydetectors │ │ ├── EntityDetector.java │ │ ├── GoblinDetector.java │ │ ├── WormDetector.java │ │ └── JerryDetector.java │ └── detectedentities │ │ ├── DetectedGoblin.java │ │ └── DetectedJerry.java │ ├── mixins │ ├── GuiNewChatAccessor.java │ ├── EntityRendererMixin.java │ └── NetHandlerPlayClientMixin.java │ ├── parsing │ ├── ParsedValue.java │ ├── chestguiparsing │ │ ├── ChestGuiParser.java │ │ └── ProfileStatsParser.java │ └── ScoreboardParser.java │ ├── eventlisteners │ └── ScathaProListener.java │ ├── util │ ├── UnicodeSymbol.java │ ├── SoundUtil.java │ └── TimeUtil.java │ ├── alerts │ ├── alertmodes │ │ ├── PresetAlertMode.java │ │ ├── AlertModeButtonOption.java │ │ ├── AlertModeManager.java │ │ ├── AlertMode.java │ │ └── customalertmode │ │ │ ├── ICustomAlertModeSaveable.java │ │ │ └── CustomAlertMode.java │ └── AlertTitle.java │ ├── achievements │ ├── UnlockedAchievement.java │ ├── AchievementCategory.java │ └── AchievementManager.java │ ├── overlay │ └── elements │ │ ├── OverlaySpacing.java │ │ ├── OverlayText.java │ │ ├── OverlayProgressBar.java │ │ ├── AnomalousDesireEffectProgressBar.java │ │ ├── AnimatedOverlayImage.java │ │ ├── OverlayImage.java │ │ ├── OverlayContainer.java │ │ └── OverlayElement.java │ ├── ForgeConfigGuiFactory.java │ ├── commands │ ├── CommandRegistry.java │ └── AverageMoneyCommand.java │ ├── tweaker │ ├── ScathaProTweaker.java │ └── ModLoadingTweaker.java │ ├── managers │ ├── HypixelModApiManager.java │ └── FFmpegWrapper.java │ └── Constants.java ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── .gitignore ├── readme.md ├── settings.gradle.kts └── gradlew.bat /src/main/resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/icon.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/main/resources/icon_aprilfools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/icon_aprilfools.png -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/sounds/scappa.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/sounds/scappa.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/lock.png -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/overlay/scatha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/overlay/scatha.png -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/overlay/worm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/overlay/worm.png -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/sounds/metal_pipe_falling.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/sounds/metal_pipe_falling.ogg -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/miscellaneous/enums/Rarity.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.miscellaneous.enums; 2 | 3 | public enum Rarity 4 | { 5 | RARE, EPIC, LEGENDARY; 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/sounds/achievements/unlock.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/sounds/achievements/unlock.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/overlay/scatha_pet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/overlay/scatha_pet.png -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/sounds/achievements/unlock_hidden.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/sounds/achievements/unlock_hidden.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/sounds/alert_modes/meme/high_heat.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/sounds/alert_modes/meme/high_heat.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/overlay/googly_eye_inner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/overlay/googly_eye_inner.png -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/overlay/googly_eye_outer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/overlay/googly_eye_outer.png -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/overlay/scatha_pet_epic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/overlay/scatha_pet_epic.png -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/overlay/scatha_pet_rare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/overlay/scatha_pet_rare.png -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/sounds/alert_modes/meme/jerry_spawn.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/sounds/alert_modes/meme/jerry_spawn.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/overlay_preview_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/overlay_preview_background.png -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/elements/IClickActionButton.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.elements; 2 | 3 | public interface IClickActionButton 4 | { 5 | public void click(); 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/sounds/alert_modes/anime/bedrock_wall.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/sounds/alert_modes/anime/bedrock_wall.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/sounds/alert_modes/anime/scatha_spawn.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/sounds/alert_modes/anime/scatha_spawn.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/sounds/alert_modes/anime/worm_prespawn.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/sounds/alert_modes/anime/worm_prespawn.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/sounds/alert_modes/meme/bedrock_wall.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/sounds/alert_modes/meme/bedrock_wall.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/sounds/alert_modes/meme/goblin_spawn.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/sounds/alert_modes/meme/goblin_spawn.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/sounds/alert_modes/meme/scatha_spawn.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/sounds/alert_modes/meme/scatha_spawn.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/sounds/alert_modes/meme/worm_prespawn.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/sounds/alert_modes/meme/worm_prespawn.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/gui/achievements/button_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/gui/achievements/button_icon.png -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/gui/achievements/progress_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/gui/achievements/progress_bar.png -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/overlay/scatha_icons/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/overlay/scatha_icons/default.png -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/overlay/scatha_pet_legendary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/overlay/scatha_pet_legendary.png -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/sounds/alert_modes/anime/scatha_pet_drop.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/sounds/alert_modes/anime/scatha_pet_drop.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/sounds/alert_modes/meme/scatha_pet_drop.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/sounds/alert_modes/meme/scatha_pet_drop.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/overlay/scatha_icons/mode_anime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/overlay/scatha_icons/mode_anime.png -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/overlay/scatha_icons/mode_meme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/overlay/scatha_icons/mode_meme.png -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/sounds/alert_modes/anime/regular_worm_spawn.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/sounds/alert_modes/anime/regular_worm_spawn.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/sounds/alert_modes/meme/regular_worm_spawn.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/sounds/alert_modes/meme/regular_worm_spawn.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/gui/achievements/dropdown_carets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/gui/achievements/dropdown_carets.png -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/overlay/scatha_icons/mode_custom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/overlay/scatha_icons/mode_custom.png -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/overlay/scatha_icons/scatha_spin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/overlay/scatha_icons/scatha_spin.png -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/sounds/alert_modes/meme/worm_spawn_cooldown_end.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/sounds/alert_modes/meme/worm_spawn_cooldown_end.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/overlay/anomalous_desire_progress_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/overlay/anomalous_desire_progress_bar.png -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/textures/overlay/scatha_icons/mode_custom_overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NamelessJu/Scatha-Pro/HEAD/src/main/resources/assets/scathapro/textures/overlay/scatha_icons/mode_custom_overlay.png -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/events/WormPreSpawnEvent.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.events; 2 | 3 | import net.minecraftforge.fml.common.eventhandler.Event; 4 | 5 | public class WormPreSpawnEvent extends Event 6 | { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | 2 | modid = scathapro 3 | version = 1.3.2.1 4 | baseGroup = namelessju.scathapro 5 | mcVersion = 1.8.9 6 | 7 | loom.platform=forge 8 | org.gradle.jvmargs=-Xmx2g 9 | # hide deprecation warnings 10 | org.gradle.warning.mode=none -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/events/RealDayStartedEvent.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.events; 2 | 3 | import net.minecraftforge.fml.common.eventhandler.Event; 4 | 5 | public class RealDayStartedEvent extends Event 6 | { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/events/BedrockWallDetectedEvent.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.events; 2 | 3 | import net.minecraftforge.fml.common.eventhandler.Event; 4 | 5 | public class BedrockWallDetectedEvent extends Event 6 | { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/events/DailyStatsResetEvent.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.events; 2 | 3 | import net.minecraftforge.fml.common.eventhandler.Event; 4 | 5 | public class DailyStatsResetEvent extends Event 6 | { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/events/DailyScathaFarmingStreakChangedEvent.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.events; 2 | 3 | import net.minecraftforge.fml.common.eventhandler.Event; 4 | 5 | public class DailyScathaFarmingStreakChangedEvent extends Event 6 | { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/events/WormKillEvent.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.events; 2 | 3 | import namelessju.scathapro.entitydetection.detectedentities.DetectedWorm; 4 | 5 | public class WormKillEvent extends WormEvent 6 | { 7 | public WormKillEvent(DetectedWorm worm) 8 | { 9 | super(worm); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/events/WormDespawnEvent.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.events; 2 | 3 | import namelessju.scathapro.entitydetection.detectedentities.DetectedWorm; 4 | 5 | public class WormDespawnEvent extends WormEvent 6 | { 7 | public WormDespawnEvent(DetectedWorm worm) 8 | { 9 | super(worm); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/resources/mixins.scathapro.json: -------------------------------------------------------------------------------- 1 | { 2 | "package": "namelessju.scathapro.mixins", 3 | "refmap": "mixins.${modid}.refmap.json", 4 | "minVersion": "0.7", 5 | "compatibilityLevel": "JAVA_8", 6 | "client": [ 7 | "GuiNewChatAccessor", 8 | "EntityRendererMixin", 9 | "NetHandlerPlayClientMixin" 10 | ] 11 | } -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/miscellaneous/enums/SkyblockArea.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.miscellaneous.enums; 2 | 3 | public enum SkyblockArea 4 | { 5 | CRYSTAL_HOLLOWS("crystal_hollows"); 6 | 7 | public final String serverModeId; 8 | 9 | SkyblockArea(String serverModeId) 10 | { 11 | this.serverModeId = serverModeId; 12 | } 13 | } -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/events/CrystalHollowsDayStartedEvent.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.events; 2 | 3 | import net.minecraftforge.fml.common.eventhandler.Event; 4 | 5 | public class CrystalHollowsDayStartedEvent extends Event 6 | { 7 | public final int day; 8 | 9 | public CrystalHollowsDayStartedEvent(int day) 10 | { 11 | this.day = day; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # General 2 | logs/ 3 | run/ 4 | build/ 5 | .settings/ 6 | .gradle/ 7 | *.log 8 | *.lnk 9 | /*.txt 10 | 11 | # Eclipse 12 | eclipse/ 13 | bin/ 14 | *.launch 15 | .settings/ 16 | .metadata/ 17 | .classpath 18 | .project 19 | 20 | # IntelliJ 21 | out/ 22 | classes/ 23 | *.ipr 24 | *.iws 25 | *.iml 26 | .idea/ 27 | 28 | # VS Code 29 | .vscode/ 30 | 31 | # System files 32 | [Dd]esktop.ini 33 | Thumbs.db 34 | .DS_Store -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/miscellaneous/PetDrop.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.miscellaneous; 2 | 3 | import namelessju.scathapro.miscellaneous.enums.Rarity; 4 | 5 | public class PetDrop 6 | { 7 | public final Rarity rarity; 8 | public final long dropTime; 9 | 10 | public PetDrop(Rarity rarity, long dropTime) 11 | { 12 | this.rarity = rarity; 13 | this.dropTime = dropTime; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/events/ScathaPetDropEvent.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.events; 2 | 3 | import namelessju.scathapro.miscellaneous.PetDrop; 4 | import net.minecraftforge.fml.common.eventhandler.Event; 5 | 6 | public class ScathaPetDropEvent extends Event 7 | { 8 | public final PetDrop petDrop; 9 | 10 | public ScathaPetDropEvent(PetDrop petDrop) 11 | { 12 | this.petDrop = petDrop; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/events/WormEvent.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.events; 2 | 3 | import namelessju.scathapro.entitydetection.detectedentities.DetectedWorm; 4 | import net.minecraftforge.fml.common.eventhandler.Event; 5 | 6 | public abstract class WormEvent extends Event 7 | { 8 | public final DetectedWorm worm; 9 | 10 | public WormEvent(DetectedWorm worm) 11 | { 12 | this.worm = worm; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/entitydetection/entitydetectors/EntityDetector.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.entitydetection.entitydetectors; 2 | 3 | import namelessju.scathapro.entitydetection.detectedentities.DetectedEntity; 4 | import net.minecraft.entity.item.EntityArmorStand; 5 | 6 | public abstract class EntityDetector 7 | { 8 | public abstract DetectedEntity detectEntity(EntityArmorStand entity, String unformattedEntityName); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/events/OverlayInitEvent.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.events; 2 | 3 | import namelessju.scathapro.overlay.elements.OverlayContainer; 4 | import net.minecraftforge.fml.common.eventhandler.Event; 5 | 6 | public class OverlayInitEvent extends Event 7 | { 8 | public final OverlayContainer overlay; 9 | 10 | public OverlayInitEvent(OverlayContainer overlay) 11 | { 12 | this.overlay = overlay; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/events/WormHitEvent.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.events; 2 | 3 | import namelessju.scathapro.entitydetection.detectedentities.DetectedWorm; 4 | import net.minecraft.item.ItemStack; 5 | 6 | public class WormHitEvent extends WormEvent 7 | { 8 | public final ItemStack weapon; 9 | 10 | public WormHitEvent(DetectedWorm worm, ItemStack weapon) 11 | { 12 | super(worm); 13 | this.weapon = weapon; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/events/SkyblockAreaDetectedEvent.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.events; 2 | 3 | import namelessju.scathapro.miscellaneous.enums.SkyblockArea; 4 | import net.minecraftforge.fml.common.eventhandler.Event; 5 | 6 | public class SkyblockAreaDetectedEvent extends Event 7 | { 8 | public final SkyblockArea area; 9 | 10 | public SkyblockAreaDetectedEvent(SkyblockArea area) 11 | { 12 | this.area = area; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Features / Download 2 | 3 | You can read about the features and download the compiled versions of this mod on the [Scatha-Pro Modrinth page](https://modrinth.com/mod/scatha-pro). 4 | 5 | # License 6 | 7 | - You may not publish the mod or parts of it on it's own without my permission (regardless of modifications)! 8 | - You may bundle this mod in modpacks with credit 9 | - Modifying this mod for *private use* is allowed 10 | - And: you can of course share pictures/videos of the mod -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/events/ModUpdateEvent.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.events; 2 | 3 | import net.minecraftforge.fml.common.eventhandler.Event; 4 | 5 | public class ModUpdateEvent extends Event 6 | { 7 | public final String previousVersion; 8 | public final String newVersion; 9 | 10 | public ModUpdateEvent(String previousVersion, String newVersion) 11 | { 12 | this.previousVersion = previousVersion; 13 | this.newVersion = newVersion; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/mixins/GuiNewChatAccessor.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.mixins; 2 | 3 | import java.util.List; 4 | 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.gen.Accessor; 7 | 8 | import net.minecraft.client.gui.ChatLine; 9 | import net.minecraft.client.gui.GuiNewChat; 10 | 11 | @Mixin(GuiNewChat.class) 12 | public interface GuiNewChatAccessor 13 | { 14 | @Accessor("chatLines") 15 | List getChatLines$scathapro(); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/parsing/ParsedValue.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.parsing; 2 | 3 | public class ParsedValue 4 | { 5 | private T value = null; 6 | 7 | public T getValue(T nullReplacementValue) 8 | { 9 | return value != null ? value : nullReplacementValue; 10 | } 11 | 12 | public void setValue(T value) 13 | { 14 | this.value = value; 15 | } 16 | 17 | public boolean hasValue() 18 | { 19 | return value != null; 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/eventlisteners/ScathaProListener.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.eventlisteners; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import net.minecraft.client.Minecraft; 5 | 6 | public abstract class ScathaProListener 7 | { 8 | protected final ScathaPro scathaPro; 9 | protected final Minecraft mc; 10 | 11 | public ScathaProListener(ScathaPro scathaPro) 12 | { 13 | this.scathaPro = scathaPro; 14 | this.mc = scathaPro.getMinecraft(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/events/AchievementUnlockedEvent.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.events; 2 | 3 | import namelessju.scathapro.achievements.UnlockedAchievement; 4 | import net.minecraftforge.fml.common.eventhandler.Event; 5 | 6 | public class AchievementUnlockedEvent extends Event 7 | { 8 | public final UnlockedAchievement unlockedAchievement; 9 | 10 | public AchievementUnlockedEvent(UnlockedAchievement unlockedAchievement) 11 | { 12 | this.unlockedAchievement = unlockedAchievement; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/events/DetectedEntityRegisteredEvent.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.events; 2 | 3 | import namelessju.scathapro.entitydetection.detectedentities.DetectedEntity; 4 | import net.minecraftforge.fml.common.eventhandler.Event; 5 | 6 | public class DetectedEntityRegisteredEvent extends Event 7 | { 8 | public final DetectedEntity detectedEntity; 9 | 10 | public DetectedEntityRegisteredEvent(DetectedEntity detectedEntity) 11 | { 12 | this.detectedEntity = detectedEntity; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/resources/mcmod.info: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "modid": "scathapro", 4 | "name": "Scatha-Pro", 5 | "description": "A mod for pro Scatha farmers\n\"/scathapro\" for more info", 6 | "version": "${version}", 7 | "mcversion": "${mcversion}", 8 | "url": "https://modrinth.com/mod/scatha-pro", 9 | "updateUrl": "", 10 | "authorList": ["NamelessJu"], 11 | "credits": "", 12 | "logoFile": "icon.png", 13 | "screenshots": [], 14 | "dependencies": [ 15 | "required-after:hypixel-mod-api@[1.0.1.2,)" 16 | ] 17 | } 18 | ] 19 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/miscellaneous/enums/WormInteractionAction.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.miscellaneous.enums; 2 | 3 | public enum WormInteractionAction 4 | { 5 | WARDROBE("Open Wardrobe"), 6 | SKYBLOCK_MENU("Open SkyBlock Menu"); 7 | 8 | private final String displayString; 9 | 10 | WormInteractionAction(String displayString) 11 | { 12 | this.displayString = displayString; 13 | } 14 | 15 | @Override 16 | public String toString() 17 | { 18 | return displayString; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/elements/HoverArea.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.elements; 2 | 3 | public class HoverArea extends ScathaProButton 4 | { 5 | public HoverArea(int id, int x, int y, int width, int height, String text) 6 | { 7 | super(id, x, y, width, height, ""); 8 | setText(text); 9 | } 10 | 11 | public void setText(String text) 12 | { 13 | super.displayString = "[Hover] " + text; 14 | } 15 | 16 | @Override 17 | public boolean elementMouseClicked(int mouseX, int mouseY, int mouseButton) 18 | { 19 | return false; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/util/UnicodeSymbol.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.util; 2 | 3 | public class UnicodeSymbol 4 | { 5 | // Hypixel specific symbols 6 | public static final char magicFind = '\u272F'; 7 | public static final char petLuck = '\u2663'; 8 | 9 | // Generic symbols 10 | public static final char heavyArrowRight = '\u279C'; 11 | public static final char heavyBlackHeart = '\u2764'; 12 | public static final char heavyCheckMark = '\u2714'; 13 | public static final char heavyX = '\u2716'; 14 | public static final char crossedSwords = '\u2694'; 15 | 16 | private UnicodeSymbol() {} 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/ConfigGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.managers.Config; 5 | import net.minecraft.client.gui.GuiScreen; 6 | 7 | public abstract class ConfigGui extends ScathaProGui 8 | { 9 | protected final Config config; 10 | 11 | public ConfigGui(ScathaPro scathaPro, GuiScreen parentGui) 12 | { 13 | super(scathaPro, parentGui); 14 | this.config = scathaPro.getConfig(); 15 | } 16 | 17 | @Override 18 | public void onGuiClosed() 19 | { 20 | config.save(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/events/WormSpawnEvent.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.events; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.entitydetection.detectedentities.DetectedWorm; 5 | import namelessju.scathapro.util.TimeUtil; 6 | 7 | public class WormSpawnEvent extends WormEvent 8 | { 9 | public final long timeSincePreviousSpawn; 10 | 11 | public WormSpawnEvent(DetectedWorm worm) 12 | { 13 | super(worm); 14 | 15 | if (ScathaPro.getInstance().variables.lastWormSpawnTime >= 0L) 16 | { 17 | timeSincePreviousSpawn = (TimeUtil.now() - ScathaPro.getInstance().variables.lastWormSpawnTime); 18 | } 19 | else timeSincePreviousSpawn = -1L; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/elements/DoneButton.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.elements; 2 | 3 | import namelessju.scathapro.gui.menus.ScathaProGui; 4 | import net.minecraftforge.fml.relauncher.Side; 5 | import net.minecraftforge.fml.relauncher.SideOnly; 6 | 7 | @SideOnly(Side.CLIENT) 8 | public class DoneButton extends ScathaProButton implements IClickActionButton 9 | { 10 | public ScathaProGui gui; 11 | 12 | public DoneButton(int buttonId, int x, int y, int widthIn, int heightIn, String displayString, ScathaProGui gui) 13 | { 14 | super(buttonId, x, y, widthIn, heightIn, displayString); 15 | 16 | this.gui = gui; 17 | } 18 | 19 | @Override 20 | public void click() 21 | { 22 | gui.openParentGui(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/miscellaneous/enums/DropMessageRarityMode.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.miscellaneous.enums; 2 | 3 | public enum DropMessageRarityMode 4 | { 5 | SUFFIX("Suffix", false, true), PREFIX("Prefix", true, true), PREFIX_NO_BRACKETS("Prefix (No Brackets)", true, false); 6 | 7 | public final String displayName; 8 | public final boolean hasBrackets; 9 | public final boolean isPrefix; 10 | 11 | DropMessageRarityMode(String displayName, boolean isPrefix, boolean hasBrackets) 12 | { 13 | this.displayName = displayName; 14 | this.isPrefix = isPrefix; 15 | this.hasBrackets = hasBrackets; 16 | } 17 | 18 | @Override 19 | public String toString() 20 | { 21 | return displayName; 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/MiscSettingsGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.gui.lists.MiscSettingsList; 5 | import net.minecraft.client.gui.GuiScreen; 6 | 7 | public class MiscSettingsGui extends ConfigGui 8 | { 9 | public MiscSettingsGui(ScathaPro scathaPro, GuiScreen parentGui) 10 | { 11 | super(scathaPro, parentGui); 12 | } 13 | 14 | @Override 15 | public String getTitle() 16 | { 17 | return "Miscellaneous Settings"; 18 | } 19 | 20 | @Override 21 | public void initGui() 22 | { 23 | super.initGui(); 24 | 25 | this.scrollList = new MiscSettingsList(this); 26 | addScrollListDoneButton(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/alerts/alertmodes/PresetAlertMode.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.alerts.alertmodes; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.miscellaneous.OverlayIconEyePositions; 5 | import net.minecraft.util.ResourceLocation; 6 | 7 | public class PresetAlertMode extends AlertMode 8 | { 9 | public PresetAlertMode(String id, String name, OverlayIconEyePositions eyePositions) 10 | { 11 | super(id, name, eyePositions); 12 | } 13 | 14 | @Override 15 | public String getIconPath() 16 | { 17 | return "overlay/scatha_icons/mode_" + id + ".png"; 18 | } 19 | 20 | @Override 21 | public ResourceLocation getSoundBaseResourceLocation() 22 | { 23 | return new ResourceLocation(ScathaPro.MODID, "alert_modes." + id); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | mavenCentral() 4 | gradlePluginPortal() 5 | maven("https://oss.sonatype.org/content/repositories/snapshots") 6 | maven("https://maven.architectury.dev/") 7 | maven("https://maven.fabricmc.net") 8 | maven("https://maven.minecraftforge.net/") 9 | maven("https://repo.spongepowered.org/maven/") 10 | maven("https://repo.essential.gg/repository/maven-releases/") 11 | } 12 | resolutionStrategy { 13 | eachPlugin { 14 | when (requested.id.id) { 15 | "gg.essential.loom" -> useModule("gg.essential:architectury-loom:${requested.version}") 16 | } 17 | } 18 | } 19 | } 20 | 21 | plugins { 22 | id("org.gradle.toolchains.foojay-resolver-convention") version("0.6.0") 23 | } 24 | 25 | 26 | rootProject.name = "Scatha-Pro" 27 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/CustomAlertModeGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.gui.lists.CustomAlertModeGuiList; 5 | import net.minecraft.client.gui.GuiScreen; 6 | 7 | public class CustomAlertModeGui extends ScathaProGui 8 | { 9 | public CustomAlertModeGui(ScathaPro scathaPro, GuiScreen parentGui) 10 | { 11 | super(scathaPro, parentGui); 12 | } 13 | 14 | public String getTitle() 15 | { 16 | return "Custom Alert Modes"; 17 | } 18 | 19 | public boolean hasBackground() 20 | { 21 | return false; 22 | } 23 | 24 | @Override 25 | public void initGui() 26 | { 27 | super.initGui(); 28 | 29 | scrollList = new CustomAlertModeGuiList(this); 30 | addScrollListDoneButton(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/events/TickEvent.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.events; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | import net.minecraftforge.fml.common.eventhandler.Event; 5 | 6 | public abstract class TickEvent extends Event 7 | { 8 | public static class FirstIngameTickEvent extends TickEvent {} 9 | 10 | public static class FirstWorldTickEvent extends TickEvent 11 | { 12 | public final EntityPlayer player; 13 | 14 | public FirstWorldTickEvent(EntityPlayer player) 15 | { 16 | this.player = player; 17 | } 18 | } 19 | 20 | public static class FirstCrystalHollowsTickEvent extends TickEvent {} 21 | 22 | public static class CrystalHollowsTickEvent extends TickEvent 23 | { 24 | public final long now; 25 | 26 | public CrystalHollowsTickEvent(long now) 27 | { 28 | this.now = now; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/miscellaneous/sound/ScappaSound.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.miscellaneous.sound; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.util.SoundUtil; 5 | import net.minecraft.entity.Entity; 6 | 7 | public class ScappaSound extends ScathaProMovingSound 8 | { 9 | public static ScappaSound play(float volume, float pitch, Entity entity) 10 | { 11 | ScappaSound sound = new ScappaSound(volume, pitch, entity); 12 | SoundUtil.playSound(sound); 13 | return sound; 14 | } 15 | 16 | public ScappaSound(float volume, float pitch, Entity entity) 17 | { 18 | super(ScathaPro.MODID + ":scappa", volume, pitch, entity); 19 | } 20 | 21 | @Override 22 | public void update() 23 | { 24 | if (this.isDone) return; 25 | 26 | updatePosition(false); 27 | } 28 | 29 | public void stop() 30 | { 31 | this.isDone = true; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/achievements/UnlockedAchievement.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.achievements; 2 | 3 | import net.minecraft.util.EnumChatFormatting; 4 | 5 | public class UnlockedAchievement 6 | { 7 | public static final String repeatFormatting = EnumChatFormatting.LIGHT_PURPLE.toString(); 8 | 9 | 10 | public final Achievement achievement; 11 | public final long unlockedAtTimestamp; 12 | private int repeatCount = 0; 13 | 14 | public UnlockedAchievement(Achievement achievement, long unlockedAtTimestamp) 15 | { 16 | this.achievement = achievement; 17 | this.unlockedAtTimestamp = unlockedAtTimestamp; 18 | } 19 | 20 | public void setRepeatCount(int count) 21 | { 22 | repeatCount = Math.max(count, 0); 23 | } 24 | 25 | public int getRepeatCount() 26 | { 27 | return repeatCount; 28 | } 29 | 30 | public String getRepeatCountUnlockString() 31 | { 32 | return repeatFormatting + "[x" + (1 + getRepeatCount()) + "]"; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/overlay/elements/OverlaySpacing.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.overlay.elements; 2 | 3 | public class OverlaySpacing extends OverlayElement 4 | { 5 | private int width, height; 6 | 7 | public OverlaySpacing(int x, int y, int width, int height, float scale) 8 | { 9 | super(x, y, scale); 10 | 11 | setWidth(width); 12 | setHeight(height); 13 | } 14 | 15 | public void setWidth(int width) 16 | { 17 | this.width = Math.max(width, 0); 18 | } 19 | 20 | public void setHeight(int height) 21 | { 22 | this.height = Math.max(height, 0); 23 | } 24 | 25 | @Override 26 | protected void drawSpecific() 27 | { 28 | // nothing here, just emptiness... 29 | } 30 | 31 | @Override 32 | public int getWidth() 33 | { 34 | return width; 35 | } 36 | 37 | @Override 38 | public int getHeight() 39 | { 40 | return height; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/ForgeConfigGuiFactory.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro; 2 | 3 | import namelessju.scathapro.gui.menus.MainSettingsGui; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.gui.GuiScreen; 6 | import net.minecraftforge.fml.client.IModGuiFactory; 7 | 8 | import java.util.Collections; 9 | import java.util.Set; 10 | 11 | public class ForgeConfigGuiFactory implements IModGuiFactory 12 | { 13 | @Override 14 | public void initialize(Minecraft minecraft) 15 | { 16 | 17 | } 18 | 19 | @Override 20 | public Class mainConfigGuiClass() 21 | { 22 | return MainSettingsGui.class; 23 | } 24 | 25 | @Override 26 | public Set runtimeGuiCategories() 27 | { 28 | return Collections.emptySet(); 29 | } 30 | 31 | @Override 32 | public RuntimeOptionGuiHandler getHandlerFor(RuntimeOptionCategoryElement runtimeOptionCategoryElement) 33 | { 34 | return null; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/miscellaneous/enums/OldLobbyAlertTriggerMode.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.miscellaneous.enums; 2 | 3 | import namelessju.scathapro.managers.Config; 4 | 5 | public enum OldLobbyAlertTriggerMode 6 | { 7 | ALWAYS("Always"), ON_JOIN("Lobby Join"), ON_NEW_DAY("New Day Start"); 8 | 9 | private final String displayName; 10 | 11 | private OldLobbyAlertTriggerMode(String displayName) 12 | { 13 | this.displayName = displayName; 14 | } 15 | 16 | @Override 17 | public String toString() 18 | { 19 | return displayName; 20 | } 21 | 22 | public static boolean isActive(Config config, OldLobbyAlertTriggerMode mode) 23 | { 24 | OldLobbyAlertTriggerMode triggerMode = config.getEnum(Config.Key.oldLobbyAlertTriggerMode, OldLobbyAlertTriggerMode.class); 25 | if (triggerMode == null) return true; // nothing set => default to always => whatever is being checked is active 26 | return triggerMode == ALWAYS || triggerMode == mode; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/achievements/AchievementCategory.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.achievements; 2 | 3 | public enum AchievementCategory 4 | { 5 | PROGRESS("Overall Achievement Progress"), 6 | KILL_AMOUNTS("Worm & Scatha Kills"), 7 | SCATHA_PET_DROPS("Scatha Pet Drops"), 8 | ALERT_MODES("Alert Modes"), 9 | HARD_STONE("Hard Stone Mined"), 10 | LOBBY_TIMER("Lobby Time"), 11 | WORM_LIFETIME("Worm Lifetime"), 12 | TIMEFRAME_KILLS("Timeframed Worm Kills"), 13 | SCATHA_FARMING_STREAK("Scatha Farming Streak"), 14 | SPAWN_STREAK("Spawn Streak"), 15 | SCATHA_SPAWNS("Specific Scatha Spawns"), 16 | WORM_HIT_KILL("Specific Worm Hits/Kills"), 17 | ABILITY("Pickaxe Ability"), 18 | MISCELLANEOUS("Miscellaneous"); 19 | 20 | private final String name; 21 | 22 | AchievementCategory(String name) 23 | { 24 | this.name = name; 25 | } 26 | 27 | public static String getName(AchievementCategory category) 28 | { 29 | return (category != null ? category.name : "Uncategorized"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/mixins/EntityRendererMixin.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.mixins; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Redirect; 6 | 7 | import namelessju.scathapro.ScathaPro; 8 | import namelessju.scathapro.managers.Config; 9 | import net.minecraft.client.renderer.EntityRenderer; 10 | import net.minecraft.client.settings.GameSettings; 11 | 12 | @Mixin(EntityRenderer.class) 13 | public class EntityRendererMixin 14 | { 15 | @Redirect(method = {"updateCameraAndRender", "updateRenderer"}, at = @At(value = "FIELD", target = "Lnet/minecraft/client/settings/GameSettings;mouseSensitivity:F")) 16 | private float redirectMouseSensitivity(GameSettings settings) 17 | { 18 | boolean isKeyDown = ScathaPro.getInstance().getInputManager().alternativeSensitivityKeybinding.isKeyDown(); 19 | return isKeyDown 20 | ? (float) ScathaPro.getInstance().getConfig().getDouble(Config.Key.alternativeSensitivity) 21 | : settings.mouseSensitivity; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/elements/IGuiElement.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.elements; 2 | 3 | public interface IGuiElement 4 | { 5 | public void setElementX(int x); 6 | public void setElementY(int y); 7 | public void setElementWidth(int width); 8 | public void setElementHeight(int height); 9 | 10 | public int getElementX(); 11 | public int getElementY(); 12 | public int getElementWidth(); 13 | public int getElementHeight(); 14 | 15 | public default void elementTick() {} 16 | public default boolean elementMouseClicked(int mouseX, int mouseY, int mouseButton) { return false; } 17 | public default void elementMouseReleased(int mouseX, int mouseY) {} 18 | public default void elementKeyTyped(char character, int code) {} 19 | public void elementDraw(int mouseX, int mouseY); 20 | 21 | public default boolean isHovered(int mouseX, int mouseY) 22 | { 23 | return mouseX >= getElementX() && mouseY >= getElementY() 24 | && mouseX < getElementX() + getElementWidth() && mouseY < getElementY() + getElementHeight(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/mixins/NetHandlerPlayClientMixin.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.mixins; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | 8 | import namelessju.scathapro.ScathaPro; 9 | import net.minecraft.client.network.NetHandlerPlayClient; 10 | import net.minecraft.network.play.server.S03PacketTimeUpdate; 11 | 12 | @Mixin(NetHandlerPlayClient.class) 13 | public class NetHandlerPlayClientMixin 14 | { 15 | @Inject(method = "handleTimeUpdate", at=@At("HEAD")) 16 | public void injectHandleTimeUpdate(S03PacketTimeUpdate packetIn, CallbackInfo callbackInfo) 17 | { 18 | ScathaPro scathaPro = ScathaPro.getInstance(); 19 | if (scathaPro.isInCrystalHollows() && scathaPro.variables.lastCrystalHollowsDay == -1) 20 | { 21 | scathaPro.logDebug("First Crystal Hollows time update packet received"); 22 | scathaPro.variables.lastCrystalHollowsDay = -2; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/commands/CommandRegistry.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.commands; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import net.minecraftforge.client.ClientCommandHandler; 5 | 6 | public class CommandRegistry 7 | { 8 | public final MainCommand mainCommand; 9 | public final ChancesCommand chancesCommand; 10 | public final AverageMoneyCommand averageMoneyCommand; 11 | public final DevCommand devCommand; 12 | 13 | public CommandRegistry(ScathaPro scathaPro) 14 | { 15 | mainCommand = new MainCommand(scathaPro); 16 | chancesCommand = new ChancesCommand(); 17 | averageMoneyCommand = new AverageMoneyCommand(scathaPro); 18 | devCommand = new DevCommand(scathaPro); 19 | } 20 | 21 | public void registerCommands() 22 | { 23 | ClientCommandHandler.instance.registerCommand(mainCommand); 24 | ClientCommandHandler.instance.registerCommand(chancesCommand); 25 | ClientCommandHandler.instance.registerCommand(averageMoneyCommand); 26 | ClientCommandHandler.instance.registerCommand(devCommand); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/miscellaneous/enums/DropMessageStatsMode.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.miscellaneous.enums; 2 | 3 | public enum DropMessageStatsMode 4 | { 5 | ADD_PET_LUCK("Add Pet Luck", true, true, null), ADD_PET_LUCK_AND_EMF("Add Pet Luck & EMF", true, true, EmfMode.SHORT), EMF_ONLY_FULL_NAME("Replace With EMF (Full Name)", false, false, EmfMode.FULL), EMF_ONLY("Replace With EMF", false, false, EmfMode.SHORT); 6 | 7 | public final String displayName; 8 | public final boolean showMagicFind; 9 | public final boolean showPetLuck; 10 | public final EmfMode emfMode; 11 | 12 | DropMessageStatsMode(String displayName, boolean showMagicFind, boolean showPetLuck, EmfMode emfMode) 13 | { 14 | this.displayName = displayName; 15 | this.showMagicFind = showMagicFind; 16 | this.showPetLuck = showPetLuck; 17 | this.emfMode = emfMode; 18 | } 19 | 20 | @Override 21 | public String toString() 22 | { 23 | return displayName; 24 | } 25 | 26 | public static enum EmfMode 27 | { 28 | FULL, SHORT; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/alerts/alertmodes/AlertModeButtonOption.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.alerts.alertmodes; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.gui.elements.CycleButton.IOption; 5 | 6 | public class AlertModeButtonOption implements IOption 7 | { 8 | public static AlertModeButtonOption[] getAllOptions() 9 | { 10 | AlertMode[] modes = ScathaPro.getInstance().getAlertModeManager().getAllModes(); 11 | AlertModeButtonOption[] options = new AlertModeButtonOption[modes.length]; 12 | for (int i = 0; i < options.length; i ++) 13 | { 14 | options[i] = new AlertModeButtonOption(modes[i]); 15 | } 16 | return options; 17 | } 18 | 19 | public final AlertMode mode; 20 | 21 | public AlertModeButtonOption(AlertMode mode) 22 | { 23 | this.mode = mode; 24 | } 25 | 26 | @Override 27 | public String getOptionName() 28 | { 29 | return mode.name; 30 | } 31 | 32 | @Override 33 | public AlertMode getOptionValue() 34 | { 35 | return mode; 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/lists/AlertsGuiList.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.lists; 2 | 3 | import namelessju.scathapro.alerts.Alert; 4 | import namelessju.scathapro.gui.elements.BooleanSettingButton; 5 | import namelessju.scathapro.gui.menus.ScathaProGui; 6 | import net.minecraft.util.EnumChatFormatting; 7 | 8 | public class AlertsGuiList extends ScathaProGuiList 9 | { 10 | public AlertsGuiList(ScathaProGui gui) 11 | { 12 | super(gui, 25); 13 | 14 | for (Alert alert : Alert.values()) 15 | { 16 | if (alert.configKey == null) continue; 17 | this.listEntries.add(new AlertEntry(alert)); 18 | } 19 | } 20 | 21 | private class AlertEntry extends ListEntry 22 | { 23 | public AlertEntry(Alert alert) 24 | { 25 | BooleanSettingButton toggleAlertButton = new BooleanSettingButton(1, 0, 2, getListWidth(), 20, alert.alertName, alert.configKey); 26 | if (alert.description != null) toggleAlertButton.getTooltip().setText(EnumChatFormatting.GRAY + alert.description); 27 | addElement(toggleAlertButton); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/lang/en_US.lang: -------------------------------------------------------------------------------- 1 | 2 | key.categories.scathapro.main=Scatha-Pro 3 | key.categories.scathapro.playerRotation=Scatha-Pro Player Rotation 4 | key.categories.scathapro.playerRotation.short=Player Rotation 5 | key.categories.scathapro.playerControls=Scatha-Pro Player Controls 6 | key.categories.scathapro.playerControls.short=Player Controls 7 | key.categories.scathapro.screenshots=Scatha-Pro Screenshots 8 | key.categories.scathapro.screenshots.short=Screenshots 9 | 10 | 11 | key.scathapro.lockRotation=Lock Camera Rotation 12 | key.scathapro.toggleOverlay=Toggle Overlay Visibility 13 | key.scathapro.toggleRotationAngles=Toggle Pitch/Yaw Display 14 | key.scathapro.cycleSelectedWormStatsType=Cycle Worm Stats Type 15 | 16 | key.scathapro.alternativeSensitivity=Alternative Sensitivity (Hold) 17 | key.scathapro.toggleAlternativeControls=Toggle Alternative Controls 18 | key.scathapro.alternativeAttack=Alternative Attack/Destroy 19 | key.scathapro.alternativeUse=Alt. Use Item/Place Block 20 | key.scathapro.alternativeForward=Alternative Walk Forward 21 | 22 | key.scathapro.overlayScreenshot=Take Overlay Screenshot 23 | key.scathapro.chatScreenshot=Take Chat Screenshot -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/overlay/elements/OverlayText.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.overlay.elements; 2 | 3 | import namelessju.scathapro.util.TextUtil; 4 | import net.minecraft.client.Minecraft; 5 | 6 | public class OverlayText extends OverlayElement 7 | { 8 | protected String text; 9 | protected int color; 10 | 11 | public OverlayText(String text, int color, int x, int y, float scale) 12 | { 13 | super(x, y, scale); 14 | this.text = text; 15 | this.color = color; 16 | } 17 | 18 | @Override 19 | protected void drawSpecific() 20 | { 21 | if (text != null && !text.isEmpty()) Minecraft.getMinecraft().fontRendererObj.drawString(text, 0, 0, color, true); 22 | } 23 | 24 | @Override 25 | public int getWidth() 26 | { 27 | return text != null ? TextUtil.getStringWidth(text) : 0; 28 | } 29 | 30 | @Override 31 | public int getHeight() 32 | { 33 | return Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT; 34 | } 35 | 36 | public void setText(String text) 37 | { 38 | this.text = text; 39 | } 40 | 41 | public void setColor(int color) 42 | { 43 | this.color = color; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/entitydetection/entitydetectors/GoblinDetector.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.entitydetection.entitydetectors; 2 | 3 | import namelessju.scathapro.entitydetection.detectedentities.DetectedEntity; 4 | import namelessju.scathapro.entitydetection.detectedentities.DetectedGoblin; 5 | import namelessju.scathapro.util.UnicodeSymbol; 6 | import net.minecraft.entity.item.EntityArmorStand; 7 | 8 | public class GoblinDetector extends EntityDetector 9 | { 10 | @Override 11 | public DetectedEntity detectEntity(EntityArmorStand entity, String unformattedEntityName) 12 | { 13 | if (unformattedEntityName != null && unformattedEntityName.contains(String.valueOf(UnicodeSymbol.heavyBlackHeart))) 14 | { 15 | if (unformattedEntityName.contains("[Lv50] Golden Goblin ")) 16 | { 17 | return new DetectedGoblin(entity, DetectedGoblin.Type.GOLD); 18 | } 19 | 20 | if (unformattedEntityName.contains("[Lv500] Diamond Goblin ")) 21 | { 22 | return new DetectedGoblin(entity, DetectedGoblin.Type.DIAMOND); 23 | } 24 | } 25 | 26 | return null; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/entitydetection/entitydetectors/WormDetector.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.entitydetection.entitydetectors; 2 | 3 | import namelessju.scathapro.entitydetection.detectedentities.DetectedEntity; 4 | import namelessju.scathapro.entitydetection.detectedentities.DetectedWorm; 5 | import namelessju.scathapro.util.UnicodeSymbol; 6 | import net.minecraft.entity.item.EntityArmorStand; 7 | 8 | public class WormDetector extends EntityDetector 9 | { 10 | @Override 11 | public DetectedEntity detectEntity(EntityArmorStand entity, String unformattedEntityName) 12 | { 13 | if (unformattedEntityName != null && unformattedEntityName.endsWith(String.valueOf(UnicodeSymbol.heavyBlackHeart))) 14 | { 15 | DetectedWorm worm = null; 16 | 17 | if (unformattedEntityName.startsWith("[Lv5] Worm ")) 18 | { 19 | worm = new DetectedWorm(entity, false); 20 | } 21 | else if (unformattedEntityName.startsWith("[Lv10] Scatha ")) 22 | { 23 | worm = new DetectedWorm(entity, true); 24 | } 25 | 26 | return worm; 27 | } 28 | 29 | return null; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/elements/BooleanSettingButton.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.elements; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.managers.Config; 5 | 6 | public class BooleanSettingButton extends ScathaProButton implements IClickActionButton 7 | { 8 | public Config.Key configSetting; 9 | public String text; 10 | 11 | public BooleanSettingButton(int buttonId, int x, int y, int widthIn, int heightIn, String text, Config.Key configSetting) 12 | { 13 | super(buttonId, x, y, widthIn, heightIn, ""); 14 | 15 | this.text = text; 16 | this.configSetting = configSetting; 17 | 18 | updateText(); 19 | } 20 | 21 | @Override 22 | public void click() 23 | { 24 | Config config = ScathaPro.getInstance().getConfig(); 25 | config.set(configSetting, !config.getBoolean(configSetting)); 26 | updateText(); 27 | } 28 | 29 | private void updateText() 30 | { 31 | this.displayString = (text != null ? text + ": " : "") + (isSettingEnabled() ? "ON" : "OFF"); 32 | } 33 | 34 | public boolean isSettingEnabled() 35 | { 36 | return ScathaPro.getInstance().getConfig().getBoolean(configSetting); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/commands/AverageMoneyCommand.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.commands; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.gui.menus.AverageMoneyGui; 5 | import net.minecraft.command.CommandBase; 6 | import net.minecraft.command.CommandException; 7 | import net.minecraft.command.ICommandSender; 8 | 9 | public class AverageMoneyCommand extends CommandBase 10 | { 11 | public static final String COMMAND_NAME = "scathamoney"; 12 | 13 | private final ScathaPro scathaPro; 14 | 15 | public AverageMoneyCommand(ScathaPro scathaPro) 16 | { 17 | this.scathaPro = scathaPro; 18 | } 19 | 20 | @Override 21 | public String getCommandName() 22 | { 23 | return COMMAND_NAME; 24 | } 25 | 26 | @Override 27 | public String getCommandUsage(ICommandSender sender) 28 | { 29 | return "/" + COMMAND_NAME; 30 | } 31 | 32 | @Override 33 | public int getRequiredPermissionLevel() 34 | { 35 | return 0; 36 | } 37 | 38 | @Override 39 | public void processCommand(ICommandSender sender, String[] args) throws CommandException 40 | { 41 | scathaPro.variables.openGuiNextTick = new AverageMoneyGui(scathaPro, null); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/miscellaneous/ScathaProKeyBinding.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.miscellaneous; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import net.minecraft.client.settings.KeyBinding; 5 | 6 | public class ScathaProKeyBinding extends KeyBinding 7 | { 8 | public static enum Category 9 | { 10 | MAIN("main"), 11 | PLAYER_ROTATION("playerRotation"), 12 | PLAYER_CONTROLS("playerControls"), 13 | SCREENSHOTS("screenshots"); 14 | 15 | private final String categoryKey; 16 | 17 | Category(String categoryKey) 18 | { 19 | this.categoryKey = categoryKey; 20 | } 21 | 22 | public String getCategoryID() 23 | { 24 | return "key.categories." + ScathaPro.MODID + "." + categoryKey; 25 | } 26 | 27 | public String getShortNameTranslationKey() 28 | { 29 | return getCategoryID() + ".short"; 30 | } 31 | } 32 | 33 | 34 | public final Category category; 35 | 36 | public ScathaProKeyBinding(String id, int defaultKey, Category category) 37 | { 38 | super("key." + ScathaPro.MODID + "." + id, defaultKey, category.getCategoryID()); 39 | this.category = category; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/alerts/AlertConfigurationGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus.alerts; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.gui.lists.AlertConfigurationList; 5 | import namelessju.scathapro.gui.menus.ConfigGui; 6 | import namelessju.scathapro.managers.Config; 7 | import net.minecraft.client.gui.GuiScreen; 8 | 9 | public class AlertConfigurationGui extends ConfigGui 10 | { 11 | public AlertConfigurationGui(ScathaPro scathaPro, GuiScreen parentGui) 12 | { 13 | super(scathaPro, parentGui); 14 | } 15 | 16 | @Override 17 | public String getTitle() 18 | { 19 | return "Alert Configuration"; 20 | } 21 | 22 | @Override 23 | public void initGui() 24 | { 25 | super.initGui(); 26 | 27 | this.scrollList = new AlertConfigurationList(this); 28 | 29 | addScrollListDoneButton(); 30 | } 31 | 32 | @Override 33 | public void onGuiClosed() 34 | { 35 | super.onGuiClosed(); 36 | 37 | if (config.getInt(Config.Key.antiSleepAlertIntervalMax) < scathaPro.variables.nextAntiSleepAlertTriggerTickCount) 38 | { 39 | scathaPro.variables.setRandomAntiSleepAlertTriggerMinutes(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/overlay/elements/OverlayProgressBar.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.overlay.elements; 2 | 3 | import net.minecraft.client.gui.Gui; 4 | 5 | public class OverlayProgressBar extends OverlayElement 6 | { 7 | private int width; 8 | private int height; 9 | private int foregroundColor; 10 | private int backgroundColor; 11 | 12 | private float progress = 0f; 13 | 14 | public OverlayProgressBar(int x, int y, int width, int height, float scale, int foregroundColor, int backgroundColor) 15 | { 16 | super(x, y, scale); 17 | this.width = width; 18 | this.height = height; 19 | this.foregroundColor = foregroundColor; 20 | this.backgroundColor = backgroundColor; 21 | } 22 | 23 | @Override 24 | protected void drawSpecific() 25 | { 26 | if (backgroundColor >= 0) Gui.drawRect(0, 0, width, height, backgroundColor); 27 | if (foregroundColor >= 0) Gui.drawRect(0, 0, Math.round(width * progress), height, foregroundColor); 28 | } 29 | 30 | @Override 31 | public int getWidth() 32 | { 33 | return width; 34 | } 35 | 36 | @Override 37 | public int getHeight() 38 | { 39 | return height; 40 | } 41 | 42 | public void setProgress(float progress) 43 | { 44 | this.progress = Math.min(Math.max(progress, 0f), 1f); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/miscellaneous/OverlayIconEyePositions.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.miscellaneous; 2 | 3 | import net.minecraft.util.MathHelper; 4 | 5 | public class OverlayIconEyePositions 6 | { 7 | public final EyePosition leftEyePosition; 8 | public final EyePosition rightEyePosition; 9 | 10 | 11 | public OverlayIconEyePositions() 12 | { 13 | this(null, null); 14 | } 15 | public OverlayIconEyePositions(float leftX, float leftY) 16 | { 17 | this(new OverlayIconEyePositions.EyePosition(leftX, leftY), null); 18 | } 19 | public OverlayIconEyePositions(float leftX, float leftY, float rightX, float rightY) 20 | { 21 | this(new OverlayIconEyePositions.EyePosition(leftX, leftY), new OverlayIconEyePositions.EyePosition(rightX, rightY)); 22 | } 23 | 24 | private OverlayIconEyePositions(EyePosition leftEyePosition, EyePosition rightEyePosition) 25 | { 26 | this.leftEyePosition = leftEyePosition; 27 | this.rightEyePosition = rightEyePosition; 28 | } 29 | 30 | public static class EyePosition 31 | { 32 | public final float x; 33 | public final float y; 34 | 35 | private EyePosition(float x, float y) 36 | { 37 | this.x = MathHelper.clamp_float(x, 0f, 1f); 38 | this.y = MathHelper.clamp_float(y, 0f, 1f); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/elements/ITooltipElement.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.elements; 2 | 3 | import namelessju.scathapro.gui.menus.ScathaProGui; 4 | import namelessju.scathapro.util.TextUtil; 5 | import net.minecraft.client.Minecraft; 6 | 7 | public interface ITooltipElement 8 | { 9 | public Tooltip getTooltip(); 10 | 11 | public static class Tooltip 12 | { 13 | private String[] tooltipLines = null; 14 | private int maxWidth = -1; 15 | 16 | public void requestRender() 17 | { 18 | if (Minecraft.getMinecraft().currentScreen instanceof ScathaProGui) 19 | { 20 | ((ScathaProGui) Minecraft.getMinecraft().currentScreen).tooltipToRender = this; 21 | } 22 | } 23 | 24 | public void setText(String text) 25 | { 26 | setText(text, 200); 27 | } 28 | 29 | public void setText(String text, int maxWidth) 30 | { 31 | if (text != null && !text.isEmpty()) 32 | { 33 | tooltipLines = TextUtil.splitOnLineBreaks(text); 34 | } 35 | else tooltipLines = null; 36 | 37 | this.maxWidth = maxWidth; 38 | } 39 | 40 | public String[] getTextLines() 41 | { 42 | return tooltipLines; 43 | } 44 | 45 | public int getMaxWidth() 46 | { 47 | return maxWidth; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/overlay/OverlayMiscSettingsGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus.overlay; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.gui.elements.CycleButton; 5 | import namelessju.scathapro.gui.elements.SubMenuButton; 6 | import namelessju.scathapro.managers.Config; 7 | import namelessju.scathapro.miscellaneous.enums.WormStatsType; 8 | import net.minecraft.client.gui.GuiScreen; 9 | 10 | public class OverlayMiscSettingsGui extends OverlaySettingsGui 11 | { 12 | public OverlayMiscSettingsGui(ScathaPro scathaPro, GuiScreen parentGui) 13 | { 14 | super(scathaPro, parentGui); 15 | } 16 | 17 | @Override 18 | public String getTitle() 19 | { 20 | return "Overlay Miscellaneous Settings"; 21 | } 22 | 23 | @Override 24 | public void initGui() 25 | { 26 | super.initGui(); 27 | 28 | elements.add(new CycleButton(1, width / 2 - 155, height - 45 - 48 - 6, 310, 20, "Worm Stats Per", CycleButton.EnumOption.from(WormStatsType.class, false), config.getEnum(Config.Key.statsType, WormStatsType.class), button -> { 29 | config.set(Config.Key.statsType, button.getSelectedValue().name()); 30 | scathaPro.getOverlay().updateStatsType(); 31 | })); 32 | 33 | elements.add(new SubMenuButton(2, width / 2 - 155, height - 45 - 24 - 6, 310, 20, "Scatha Percentage...", this, OverlayScathaPercentageSettingsGui.class)); 34 | 35 | addDoneButton(width / 2 - 100, height - 45, 200, 20); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/elements/ScappaModeButton.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.elements; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.managers.Config; 5 | 6 | public class ScappaModeButton extends ScathaProButton implements IClickActionButton 7 | { 8 | public ScappaModeButton(int buttonId, int x, int y, int widthIn, int heightIn) 9 | { 10 | super(buttonId, x, y, widthIn, heightIn, ""); 11 | 12 | updateText(); 13 | } 14 | 15 | @Override 16 | public void click() 17 | { 18 | ScathaPro scathaPro = ScathaPro.getInstance(); 19 | 20 | if (scathaPro.variables.scappaModeActiveTemp) 21 | { 22 | scathaPro.variables.scappaModeActiveTemp = false; 23 | } 24 | else 25 | { 26 | Config config = scathaPro.getConfig(); 27 | config.set(Config.Key.scappaMode, !config.getBoolean(Config.Key.scappaMode)); 28 | } 29 | 30 | ScathaPro.getInstance().getOverlay().updateScappaMode(); 31 | 32 | updateText(); 33 | } 34 | 35 | private void updateText() 36 | { 37 | this.displayString = "Scappa Mode: "; 38 | 39 | if (ScathaPro.getInstance().variables.scappaModeActiveTemp) 40 | { 41 | this.displayString += "Temporary"; 42 | return; 43 | } 44 | 45 | boolean enabled = ScathaPro.getInstance().getConfig().getBoolean(Config.Key.scappaMode); 46 | this.displayString += enabled ? "ON" : "OFF"; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/elements/SubMenuButton.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.elements; 2 | 3 | import java.lang.reflect.Constructor; 4 | 5 | import namelessju.scathapro.ScathaPro; 6 | import namelessju.scathapro.gui.menus.ScathaProGui; 7 | import net.minecraft.client.Minecraft; 8 | import net.minecraft.client.gui.GuiScreen; 9 | import net.minecraftforge.fml.relauncher.Side; 10 | import net.minecraftforge.fml.relauncher.SideOnly; 11 | 12 | @SideOnly(Side.CLIENT) 13 | public class SubMenuButton extends ScathaProButton implements IClickActionButton 14 | { 15 | public ScathaProGui parentMenu; 16 | public Class menuClass; 17 | 18 | public SubMenuButton(int buttonId, int x, int y, int widthIn, int heightIn, String displayString, ScathaProGui parentMenu, Class menuClass) 19 | { 20 | super(buttonId, x, y, widthIn, heightIn, displayString); 21 | 22 | this.parentMenu = parentMenu; 23 | this.menuClass = menuClass; 24 | } 25 | 26 | @Override 27 | public void click() 28 | { 29 | try 30 | { 31 | Constructor constructor = menuClass.getDeclaredConstructor(ScathaPro.class, GuiScreen.class); 32 | GuiScreen screen = constructor.newInstance(parentMenu.scathaPro, parentMenu); 33 | Minecraft.getMinecraft().displayGuiScreen(screen); 34 | } 35 | catch (Exception e) 36 | { 37 | ScathaPro.getInstance().logError("Error while trying to open menu from SubMenuButton"); 38 | e.printStackTrace(); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/entitydetection/detectedentities/DetectedGoblin.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.entitydetection.detectedentities; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.alerts.Alert; 5 | import namelessju.scathapro.managers.Config; 6 | import net.minecraft.entity.item.EntityArmorStand; 7 | import net.minecraft.util.EnumChatFormatting; 8 | 9 | public class DetectedGoblin extends DetectedEntity 10 | { 11 | public static enum Type 12 | { 13 | GOLD, DIAMOND; 14 | } 15 | 16 | public final Type type; 17 | 18 | public DetectedGoblin(EntityArmorStand entity, Type type) 19 | { 20 | super(entity); 21 | this.type = type; 22 | } 23 | 24 | @Override 25 | public long getMaxLifetime() 26 | { 27 | return 30000; 28 | } 29 | 30 | @Override 31 | protected void onRegistration() 32 | { 33 | if (!ScathaPro.getInstance().getConfig().getBoolean(Config.Key.goblinSpawnAlert)) return; 34 | 35 | String typeText = EnumChatFormatting.GRAY.toString() + EnumChatFormatting.ITALIC + "Unknown type"; 36 | if (type != null) 37 | { 38 | switch (type) 39 | { 40 | case GOLD: 41 | typeText = EnumChatFormatting.GOLD + "Golden"; 42 | break; 43 | case DIAMOND: 44 | typeText = EnumChatFormatting.AQUA + "Diamond"; 45 | break; 46 | } 47 | } 48 | 49 | Alert.goblinSpawn.play(typeText); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/overlay/OverlaySettingsGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus.overlay; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.gui.menus.ConfigGui; 5 | import namelessju.scathapro.overlay.Overlay; 6 | import net.minecraft.client.gui.GuiScreen; 7 | 8 | public abstract class OverlaySettingsGui extends ConfigGui 9 | { 10 | protected final Overlay overlay; 11 | 12 | private boolean debugInfoShownBefore = false; 13 | 14 | @Override 15 | public boolean hasBackground() 16 | { 17 | return false; 18 | } 19 | 20 | @Override 21 | protected void drawCustomBackground() 22 | { 23 | overlay.drawOverlay(); 24 | } 25 | 26 | public OverlaySettingsGui(ScathaPro scathaPro, GuiScreen parentGui) 27 | { 28 | super(scathaPro, parentGui); 29 | 30 | overlay = scathaPro.getOverlay(); 31 | } 32 | 33 | @Override 34 | public void initGui() 35 | { 36 | super.initGui(); 37 | 38 | debugInfoShownBefore = scathaPro.getMinecraft().gameSettings.showDebugInfo; 39 | scathaPro.getMinecraft().gameSettings.showDebugInfo = false; 40 | 41 | overlay.updateRealtimeElements(); 42 | } 43 | 44 | @Override 45 | public void updateScreen() 46 | { 47 | super.updateScreen(); 48 | 49 | overlay.updateRealtimeElements(); 50 | } 51 | 52 | @Override 53 | public void onGuiClosed() 54 | { 55 | super.onGuiClosed(); 56 | 57 | scathaPro.getMinecraft().gameSettings.showDebugInfo = debugInfoShownBefore; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/tweaker/ScathaProTweaker.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.tweaker; 2 | 3 | import java.io.File; 4 | import java.util.List; 5 | 6 | import net.hypixel.modapi.tweaker.HypixelModAPITweaker; 7 | import org.spongepowered.asm.launch.MixinTweaker; 8 | 9 | import net.minecraft.launchwrapper.ITweaker; 10 | import net.minecraft.launchwrapper.Launch; 11 | import net.minecraft.launchwrapper.LaunchClassLoader; 12 | import net.minecraftforge.fml.relauncher.CoreModManager; 13 | 14 | public class ScathaProTweaker implements ITweaker 15 | { 16 | @Override 17 | public void acceptOptions(List args, File gameDir, File assetsDir, String profile) 18 | { 19 | @SuppressWarnings({"unchecked"}) 20 | List tweakClassNames = (List) Launch.blackboard.get("TweakClasses"); 21 | tweakClassNames.add(MixinTweaker.class.getName()); 22 | tweakClassNames.add(ModLoadingTweaker.class.getName()); 23 | tweakClassNames.add(HypixelModAPITweaker.class.getName()); 24 | 25 | // TODO: temp fix, figure out how to properly prevent 26 | // both the tweaker result and the shadowed dependency 27 | // from loading together in the dev environment 28 | CoreModManager.getIgnoredMods().add("mod-api-forge-1.0.1.2.jar"); 29 | } 30 | 31 | @Override 32 | public void injectIntoClassLoader(LaunchClassLoader classLoader) 33 | { 34 | 35 | } 36 | 37 | @Override 38 | public String getLaunchTarget() 39 | { 40 | return null; 41 | } 42 | 43 | @Override 44 | public String[] getLaunchArguments() 45 | { 46 | return new String[0]; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/entitydetection/entitydetectors/JerryDetector.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.entitydetection.entitydetectors; 2 | 3 | import namelessju.scathapro.entitydetection.detectedentities.DetectedEntity; 4 | import namelessju.scathapro.entitydetection.detectedentities.DetectedJerry; 5 | import net.minecraft.entity.item.EntityArmorStand; 6 | import net.minecraft.util.EnumChatFormatting; 7 | 8 | public class JerryDetector extends EntityDetector 9 | { 10 | @Override 11 | public DetectedEntity detectEntity(EntityArmorStand entity, String unformattedEntityName) 12 | { 13 | if (unformattedEntityName.equals("Mayor Jerry's")) 14 | { 15 | String formattedName = entity.hasCustomName() ? entity.getCustomNameTag() : ""; 16 | 17 | if (formattedName.startsWith(EnumChatFormatting.GREEN.toString())) 18 | { 19 | return new DetectedJerry(entity, DetectedJerry.Type.GREEN); 20 | } 21 | 22 | if (formattedName.startsWith(EnumChatFormatting.BLUE.toString())) 23 | { 24 | return new DetectedJerry(entity, DetectedJerry.Type.BLUE); 25 | } 26 | 27 | if (formattedName.startsWith(EnumChatFormatting.DARK_PURPLE.toString())) 28 | { 29 | return new DetectedJerry(entity, DetectedJerry.Type.PURPLE); 30 | } 31 | 32 | if (formattedName.startsWith(EnumChatFormatting.GOLD.toString())) 33 | { 34 | return new DetectedJerry(entity, DetectedJerry.Type.GOLDEN); 35 | } 36 | 37 | return new DetectedJerry(entity, null); 38 | } 39 | 40 | return null; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/alerts/alertmodes/AlertModeManager.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.alerts.alertmodes; 2 | import java.util.LinkedHashMap; 3 | 4 | import namelessju.scathapro.alerts.alertmodes.customalertmode.CustomAlertMode; 5 | import namelessju.scathapro.managers.Config; 6 | import namelessju.scathapro.miscellaneous.OverlayIconEyePositions; 7 | 8 | public class AlertModeManager 9 | { 10 | private final Config config; 11 | 12 | private LinkedHashMap modes = new LinkedHashMap(); 13 | 14 | public AlertModeManager(Config config) 15 | { 16 | this.config = config; 17 | 18 | registerMode(AlertMode.DEFAULT_MODE); 19 | registerMode(new PresetAlertMode("meme", "Meme", new OverlayIconEyePositions(0.5f, 0.42f, 0.84f, 0.32f))); 20 | registerMode(new PresetAlertMode("anime", "Anime", new OverlayIconEyePositions(0.5f, 0.48f, 0.85f, 0.34f))); 21 | registerMode(new CustomAlertMode("custom", "Custom")); 22 | } 23 | 24 | public void registerMode(AlertMode mode) 25 | { 26 | modes.put(mode.id, mode); 27 | } 28 | 29 | public AlertMode[] getAllModes() 30 | { 31 | return (AlertMode[]) modes.values().toArray(new AlertMode[0]); 32 | } 33 | 34 | public AlertMode getModeByID(String id) 35 | { 36 | return modes.get(id); 37 | } 38 | 39 | public AlertMode getCurrentMode() 40 | { 41 | String currentModeId = config.getString(Config.Key.mode); 42 | if (currentModeId.isEmpty()) return AlertMode.DEFAULT_MODE; 43 | AlertMode mode = getModeByID(currentModeId); 44 | return mode != null ? mode : AlertMode.DEFAULT_MODE; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/overlay/elements/AnomalousDesireEffectProgressBar.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.overlay.elements; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.util.TimeUtil; 5 | import namelessju.scathapro.util.Util; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.client.gui.Gui; 8 | import net.minecraft.util.ResourceLocation; 9 | 10 | public class AnomalousDesireEffectProgressBar extends OverlayElement 11 | { 12 | private static final ResourceLocation resourceLocation = new ResourceLocation(ScathaPro.MODID, "textures/overlay/anomalous_desire_progress_bar.png"); 13 | 14 | private int width; 15 | private int height; 16 | 17 | private float progress = 0f; 18 | 19 | public AnomalousDesireEffectProgressBar(int x, int y, int width, int height, float scale) 20 | { 21 | super(x, y, scale); 22 | this.width = width; 23 | this.height = height; 24 | } 25 | 26 | @Override 27 | protected void drawSpecific() 28 | { 29 | int yOffset = (int) ((TimeUtil.now() / 100L) % 32); 30 | 31 | Minecraft.getMinecraft().renderEngine.bindTexture(resourceLocation); 32 | Util.startImageRendering(); 33 | Gui.drawModalRectWithCustomSizedTexture(0, 0, 0, yOffset, Math.round(width * progress), height, 32, 32); 34 | Util.endImageRendering(); 35 | } 36 | 37 | @Override 38 | public int getWidth() 39 | { 40 | return width; 41 | } 42 | 43 | @Override 44 | public int getHeight() 45 | { 46 | return height; 47 | } 48 | 49 | public void setProgress(float progress) 50 | { 51 | this.progress = Math.min(Math.max(progress, 0f), 1f); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/util/SoundUtil.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.util; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.miscellaneous.sound.ScathaProSound; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.client.audio.ISound; 7 | import net.minecraft.client.audio.SoundEventAccessorComposite; 8 | import net.minecraft.client.audio.SoundHandler; 9 | import net.minecraft.util.ResourceLocation; 10 | 11 | public abstract class SoundUtil 12 | { 13 | public static ScathaProSound playSound(String soundId) 14 | { 15 | return playSound(soundId, 1f, 1f); 16 | } 17 | 18 | public static ScathaProSound playSound(String soundId, float volume, float pitch) 19 | { 20 | ScathaProSound sound = new ScathaProSound(soundId, volume, pitch); 21 | playSound(sound); 22 | return sound; 23 | } 24 | 25 | public static void playSound(ISound sound) 26 | { 27 | Minecraft.getMinecraft().getSoundHandler().playSound(sound); 28 | } 29 | 30 | public static ScathaProSound playModSound(String sound) 31 | { 32 | return playModSound(sound, 1f, 1f); 33 | } 34 | 35 | public static ScathaProSound playModSound(String sound, float volume, float pitch) 36 | { 37 | return playSound(ScathaPro.MODID + ":" + sound, volume, pitch); 38 | } 39 | 40 | public static boolean soundExists(String id) 41 | { 42 | SoundHandler soundHandler = Minecraft.getMinecraft().getSoundHandler(); 43 | SoundEventAccessorComposite soundeventaccessorcomposite = soundHandler.getSound(new ResourceLocation(id)); 44 | return soundeventaccessorcomposite != null && soundeventaccessorcomposite.cloneEntry() != SoundHandler.missing_sound; 45 | } 46 | 47 | 48 | private SoundUtil() {} 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/alerts/alertmodes/AlertMode.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.alerts.alertmodes; 2 | 3 | import namelessju.scathapro.alerts.Alert; 4 | import namelessju.scathapro.alerts.AlertTitle; 5 | import namelessju.scathapro.miscellaneous.OverlayIconEyePositions; 6 | import net.minecraft.util.ResourceLocation; 7 | 8 | public class AlertMode 9 | { 10 | public static final AlertMode DEFAULT_MODE = new AlertMode("normal", "Vanilla", new OverlayIconEyePositions(0.3f, 0.6f)); 11 | 12 | 13 | public final String id; 14 | public final String name; 15 | 16 | /** 17 | * Used for april fools googly eyes 18 | */ 19 | public final OverlayIconEyePositions eyePositions; 20 | 21 | protected AlertMode(String id, String name, OverlayIconEyePositions eyePositions) 22 | { 23 | this.id = id; 24 | this.name = name; 25 | 26 | this.eyePositions = eyePositions; 27 | } 28 | 29 | 30 | public String getIconPath() 31 | { 32 | return "overlay/scatha_icons/default.png"; 33 | } 34 | 35 | public String getIconOverlayPath() 36 | { 37 | return null; 38 | } 39 | 40 | public int getIconColor() 41 | { 42 | return 0xFFFFFF; 43 | } 44 | 45 | 46 | public ResourceLocation getSoundBaseResourceLocation() 47 | { 48 | return null; 49 | } 50 | 51 | public float getSoundVolume(Alert alert) 52 | { 53 | return 1f; 54 | } 55 | 56 | public AlertTitle getTitle(Alert alert) 57 | { 58 | return null; 59 | } 60 | 61 | 62 | public static OverlayIconEyePositions getDefaultIconEyePositions() 63 | { 64 | return new OverlayIconEyePositions(0.27f, 0.56f); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/alerts/AlertStatesGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus.alerts; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.alerts.Alert; 5 | import namelessju.scathapro.gui.lists.AlertsGuiList; 6 | import namelessju.scathapro.gui.menus.ConfigGui; 7 | import net.minecraft.client.gui.GuiScreen; 8 | 9 | public class AlertStatesGui extends ConfigGui 10 | { 11 | Boolean antiSleepAlertEnabledBefore = null; 12 | 13 | public AlertStatesGui(ScathaPro scathaPro, GuiScreen parentGui) 14 | { 15 | super(scathaPro, parentGui); 16 | } 17 | 18 | @Override 19 | public String getTitle() 20 | { 21 | return "Enable/Disable Alerts"; 22 | } 23 | 24 | @Override 25 | public void initGui() 26 | { 27 | super.initGui(); 28 | 29 | scrollList = new AlertsGuiList(this); 30 | 31 | addDoneButton(this.width / 2 - 100, this.height - 30, 200, 20); 32 | 33 | if (antiSleepAlertEnabledBefore == null) 34 | { 35 | antiSleepAlertEnabledBefore = config.getBoolean(Alert.antiSleep.configKey); 36 | } 37 | } 38 | 39 | @Override 40 | public void onGuiClosed() 41 | { 42 | super.onGuiClosed(); 43 | 44 | if (config.getBoolean(Alert.antiSleep.configKey)) 45 | { 46 | if (antiSleepAlertEnabledBefore != null) 47 | { 48 | if (!antiSleepAlertEnabledBefore) 49 | { 50 | scathaPro.variables.antiSleepAlertTickTimer = 0; 51 | scathaPro.variables.setRandomAntiSleepAlertTriggerMinutes(); 52 | } 53 | antiSleepAlertEnabledBefore = null; 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/managers/HypixelModApiManager.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.managers; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.events.SkyblockAreaDetectedEvent; 5 | import namelessju.scathapro.miscellaneous.enums.SkyblockArea; 6 | import net.hypixel.modapi.HypixelModAPI; 7 | import net.hypixel.modapi.packet.impl.clientbound.event.ClientboundLocationPacket; 8 | import net.minecraftforge.common.MinecraftForge; 9 | 10 | public class HypixelModApiManager 11 | { 12 | private HypixelModApiManager() {} 13 | 14 | public static void init(ScathaPro scathaPro) 15 | { 16 | HypixelModAPI modApi = HypixelModAPI.getInstance(); 17 | 18 | modApi.subscribeToEventPacket(ClientboundLocationPacket.class); 19 | modApi.createHandler(ClientboundLocationPacket.class, packet -> { 20 | 21 | if (scathaPro.getConfig().getBoolean(Config.Key.devMode)) return; 22 | 23 | scathaPro.variables.currentArea = null; 24 | 25 | String mode = packet.getMode().orElse(null); 26 | if (mode == null) return; 27 | 28 | for (SkyblockArea area : SkyblockArea.values()) 29 | { 30 | if (area.serverModeId.equals(mode)) 31 | { 32 | scathaPro.variables.currentArea = area; 33 | scathaPro.logDebug("Area detected: " + area.name()); 34 | MinecraftForge.EVENT_BUS.post(new SkyblockAreaDetectedEvent(area)); 35 | return; 36 | } 37 | } 38 | 39 | scathaPro.logDebug("Encountered unknown mode while detecting area: " + mode); 40 | }); 41 | 42 | scathaPro.logDebug("Hypixel mod API initialized"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/FakeBanGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus; 2 | 3 | import net.minecraft.client.gui.GuiButton; 4 | import net.minecraft.client.gui.GuiDisconnected; 5 | import net.minecraft.util.ChatComponentText; 6 | import net.minecraft.util.EnumChatFormatting; 7 | 8 | public class FakeBanGui extends GuiDisconnected 9 | { 10 | private Runnable guiClosedCallback; 11 | 12 | public FakeBanGui(String reason) 13 | { 14 | this(reason, null); 15 | } 16 | 17 | public FakeBanGui(String reason, Runnable guiClosedCallback) 18 | { 19 | super(null, "connect.failed", new ChatComponentText( 20 | EnumChatFormatting.RESET.toString() + EnumChatFormatting.RED + "You are permanently banned from this server!\n\n" 21 | + EnumChatFormatting.GRAY + "Reason: " + EnumChatFormatting.WHITE + reason + "\n" 22 | + EnumChatFormatting.GRAY + "Find out more: " + EnumChatFormatting.AQUA + EnumChatFormatting.UNDERLINE + "https://hypixel.net/rules\n\n" 23 | + EnumChatFormatting.GRAY + "Ban ID: " + EnumChatFormatting.WHITE + "#URB4NN3D\n" 24 | + EnumChatFormatting.GRAY + "Sharing your Ban ID may affect the processing of your appeal!" 25 | )); 26 | 27 | this.guiClosedCallback = guiClosedCallback; 28 | } 29 | 30 | @Override 31 | public boolean doesGuiPauseGame() 32 | { 33 | return false; 34 | } 35 | 36 | // Always draw dirt background 37 | @Override 38 | public void drawWorldBackground(int tint) 39 | { 40 | this.drawBackground(tint); 41 | } 42 | 43 | @Override 44 | protected void actionPerformed(GuiButton button) 45 | { 46 | super.actionPerformed(button); 47 | 48 | if (button.id == 0 && guiClosedCallback != null) guiClosedCallback.run(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/miscellaneous/sound/ScathaProSound.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.miscellaneous.sound; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.managers.Config; 5 | import net.minecraft.client.audio.ISound; 6 | import net.minecraft.util.MathHelper; 7 | import net.minecraft.util.ResourceLocation; 8 | 9 | public class ScathaProSound implements ISound 10 | { 11 | public final ResourceLocation resourceLocation; 12 | public float volume; 13 | public float pitch; 14 | 15 | public ScathaProSound(String soundPath, float volume, float pitch) 16 | { 17 | this.resourceLocation = new ResourceLocation(soundPath); 18 | this.volume = volume; 19 | this.pitch = pitch; 20 | } 21 | 22 | @Override 23 | public ResourceLocation getSoundLocation() 24 | { 25 | return resourceLocation; 26 | } 27 | 28 | @Override 29 | public boolean canRepeat() 30 | { 31 | return false; 32 | } 33 | 34 | @Override 35 | public int getRepeatDelay() 36 | { 37 | return 0; 38 | } 39 | 40 | @Override 41 | public float getVolume() 42 | { 43 | return MathHelper.clamp_float(volume * (float) ScathaPro.getInstance().getConfig().getDouble(Config.Key.soundsVolume), 0f, 1f); 44 | } 45 | 46 | @Override 47 | public float getPitch() 48 | { 49 | return pitch; 50 | } 51 | 52 | @Override 53 | public float getXPosF() 54 | { 55 | return 0.5f; 56 | } 57 | 58 | @Override 59 | public float getYPosF() 60 | { 61 | return 0.5f; 62 | } 63 | 64 | @Override 65 | public float getZPosF() 66 | { 67 | return 0.5f; 68 | } 69 | 70 | @Override 71 | public AttenuationType getAttenuationType() 72 | { 73 | return AttenuationType.NONE; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/parsing/chestguiparsing/ChestGuiParser.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.parsing.chestguiparsing; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.util.NBTUtil; 5 | import net.minecraft.item.ItemStack; 6 | import net.minecraft.nbt.NBTTagList; 7 | import net.minecraft.util.StringUtils; 8 | 9 | import java.util.function.Predicate; 10 | 11 | public abstract class ChestGuiParser 12 | { 13 | public boolean enabled = true; 14 | 15 | public abstract String getGuiName(); 16 | public abstract int[] getSlotNumbers(); 17 | 18 | public abstract void tryParse(ItemStack itemStack, int slotNumber, ScathaPro scathaPro); 19 | 20 | public void onStartParsing() {} 21 | public void onFinishParsing() {} 22 | 23 | protected String searchLoreWithExpectedIndex(ItemStack itemStack, int expectedLoreIndex, Predicate linePredicate) 24 | { 25 | NBTTagList itemLore = NBTUtil.getLore(itemStack); 26 | if (itemLore == null) return null; 27 | 28 | String line = null; 29 | 30 | int loreIndex = expectedLoreIndex; 31 | boolean isExpectedIndexCheck = true; 32 | while (loreIndex < itemLore.tagCount()) 33 | { 34 | if (isExpectedIndexCheck || loreIndex != expectedLoreIndex) 35 | { 36 | line = StringUtils.stripControlCodes(itemLore.getStringTagAt(loreIndex)); 37 | if (linePredicate.test(line)) break; 38 | line = null; 39 | } 40 | 41 | if (isExpectedIndexCheck) 42 | { 43 | isExpectedIndexCheck = false; 44 | loreIndex = 0; 45 | continue; 46 | } 47 | 48 | loreIndex ++; 49 | } 50 | 51 | return line; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/miscellaneous/enums/WormStatsType.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.miscellaneous.enums; 2 | 3 | public enum WormStatsType 4 | { 5 | PER_LOBBY("Lobby"), 6 | PER_SESSION("Session"), 7 | PER_DAY("IRL Day"); 8 | 9 | 10 | public static void addRegularWormSpawn() 11 | { 12 | for (WormStatsType stats : WormStatsType.values()) 13 | { 14 | if (stats.scathaSpawnStreak > 0) stats.scathaSpawnStreak = 0; 15 | stats.scathaSpawnStreak --; 16 | } 17 | } 18 | 19 | public static void addScathaSpawn() 20 | { 21 | for (WormStatsType stats : WormStatsType.values()) 22 | { 23 | if (stats.scathaSpawnStreak < 0) stats.scathaSpawnStreak = 0; 24 | stats.scathaSpawnStreak ++; 25 | } 26 | } 27 | 28 | public static void addRegularWormKill() 29 | { 30 | for (WormStatsType stats : WormStatsType.values()) 31 | stats.regularWormKills ++; 32 | } 33 | 34 | public static void addScathaKill() 35 | { 36 | for (WormStatsType stats : WormStatsType.values()) 37 | stats.scathaKills ++; 38 | } 39 | 40 | public static void resetForNewLobby() 41 | { 42 | PER_LOBBY.regularWormKills = 0; 43 | PER_LOBBY.scathaKills = 0; 44 | PER_LOBBY.scathaSpawnStreak = 0; 45 | } 46 | 47 | 48 | private String displayString; 49 | 50 | WormStatsType(String displayString) 51 | { 52 | this.displayString = displayString; 53 | } 54 | 55 | public int regularWormKills = 0; 56 | public int scathaKills = 0; 57 | public int scathaSpawnStreak = 0; // positive = Scatha streak; negative = regular worm streak 58 | 59 | @Override 60 | public String toString() 61 | { 62 | return displayString; 63 | } 64 | } -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/entitydetection/detectedentities/DetectedJerry.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.entitydetection.detectedentities; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.alerts.Alert; 5 | import namelessju.scathapro.managers.Config; 6 | import net.minecraft.entity.item.EntityArmorStand; 7 | import net.minecraft.util.EnumChatFormatting; 8 | 9 | // Note: this doesn't detect the Jerry itself, but the box that the hidden Jerry spawns from 10 | public class DetectedJerry extends DetectedEntity 11 | { 12 | public static enum Type 13 | { 14 | GREEN, BLUE, PURPLE, GOLDEN; 15 | } 16 | 17 | public final Type type; 18 | 19 | public DetectedJerry(EntityArmorStand entity, Type type) 20 | { 21 | super(entity); 22 | this.type = type; 23 | } 24 | 25 | @Override 26 | public long getMaxLifetime() 27 | { 28 | return 3500; 29 | } 30 | 31 | @Override 32 | protected void onRegistration() 33 | { 34 | if (!ScathaPro.getInstance().getConfig().getBoolean(Config.Key.goblinSpawnAlert)) return; 35 | 36 | String typeText = EnumChatFormatting.GRAY.toString() + EnumChatFormatting.ITALIC + "Unknown type"; 37 | if (type != null) 38 | { 39 | switch (type) 40 | { 41 | case GREEN: 42 | typeText = EnumChatFormatting.GREEN + "Green"; 43 | break; 44 | case BLUE: 45 | typeText = EnumChatFormatting.BLUE + "Blue"; 46 | break; 47 | case PURPLE: 48 | typeText = EnumChatFormatting.DARK_PURPLE + "Purple"; 49 | break; 50 | case GOLDEN: 51 | typeText = EnumChatFormatting.GOLD + "Golden"; 52 | break; 53 | } 54 | } 55 | 56 | Alert.jerrySpawn.play(typeText); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/overlay/OverlayGeneralSettingsGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus.overlay; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.gui.elements.BooleanSettingButton; 5 | import namelessju.scathapro.gui.elements.SubMenuButton; 6 | import namelessju.scathapro.managers.Config; 7 | import net.minecraft.client.gui.GuiButton; 8 | import net.minecraft.client.gui.GuiScreen; 9 | 10 | public class OverlayGeneralSettingsGui extends OverlaySettingsGui 11 | { 12 | public OverlayGeneralSettingsGui(ScathaPro scathaPro, GuiScreen parentGui) 13 | { 14 | super(scathaPro, parentGui); 15 | } 16 | 17 | @Override 18 | public String getTitle() 19 | { 20 | return "UI Overlay Settings"; 21 | } 22 | 23 | @Override 24 | public void initGui() 25 | { 26 | super.initGui(); 27 | 28 | elements.add(new BooleanSettingButton(1, width / 2 - 155, height - 45 - 48 - 6, 150, 20, "UI Overlay", Config.Key.overlayEnabled)); 29 | elements.add(new SubMenuButton(2, width / 2 + 5, height - 45 - 48 - 6, 150, 20, "Position...", this, OverlayPositionSettingsGui.class)); 30 | elements.add(new SubMenuButton(3, width / 2 - 155, height - 45 - 24 - 6, 150, 20, "Components...", this, OverlayComponentsSettingsGui.class)); 31 | elements.add(new SubMenuButton(4, width / 2 + 5, height - 45 - 24 - 6, 150, 20, "Miscellaneous...", this, OverlayMiscSettingsGui.class)); 32 | 33 | addDoneButton(width / 2 - 100, height - 45, 200, 20); 34 | 35 | overlay.updateOverlayFull(); 36 | } 37 | 38 | @Override 39 | protected void actionPerformed(GuiButton button) 40 | { 41 | super.actionPerformed(button); 42 | 43 | if (button.enabled) 44 | { 45 | switch (button.id) 46 | { 47 | case 1: 48 | overlay.updateVisibility(); 49 | break; 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/tweaker/ModLoadingTweaker.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.tweaker; 2 | 3 | import net.minecraft.launchwrapper.ITweaker; 4 | import net.minecraft.launchwrapper.LaunchClassLoader; 5 | import net.minecraftforge.fml.relauncher.CoreModManager; 6 | import org.spongepowered.asm.launch.MixinBootstrap; 7 | 8 | import namelessju.scathapro.ScathaPro; 9 | 10 | import java.io.File; 11 | import java.net.URISyntaxException; 12 | import java.net.URL; 13 | import java.util.List; 14 | 15 | /** 16 | * The mod loading tweaker makes sure that we are recognized as a Forge Mod, despite having a Tweaker. 17 | * We also add ourselves as a mixin container for integration with other mixin loaders. 18 | *

19 | * Taken from https://github.com/NotEnoughUpdates/NotEnoughUpdates/blob/20821e63057add096e314310ea8fa8e0c411e964/src/main/java/io/github/moulberry/notenoughupdates/loader/ModLoadingTweaker.java 20 | */ 21 | public class ModLoadingTweaker implements ITweaker 22 | { 23 | @Override 24 | public void acceptOptions(List args, File gameDir, File assetsDir, String profile) 25 | { 26 | URL location = ModLoadingTweaker.class.getProtectionDomain().getCodeSource().getLocation(); 27 | if (location == null) return; 28 | if (!"file".equals(location.getProtocol())) return; 29 | try 30 | { 31 | MixinBootstrap.getPlatform().addContainer(location.toURI()); 32 | String file = new File(location.toURI()).getName(); 33 | CoreModManager.getIgnoredMods().remove(file); 34 | CoreModManager.getReparseableCoremods().add(file); 35 | } 36 | catch (URISyntaxException e) 37 | { 38 | System.err.println(ScathaPro.TRUE_MODNAME + " failed to re-add itself as mod."); 39 | e.printStackTrace(); 40 | } 41 | } 42 | 43 | @Override 44 | public void injectIntoClassLoader(LaunchClassLoader classLoader) 45 | { 46 | 47 | } 48 | 49 | @Override 50 | public String getLaunchTarget() 51 | { 52 | return null; 53 | } 54 | 55 | @Override 56 | public String[] getLaunchArguments() 57 | { 58 | return new String[0]; 59 | } 60 | } -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/MainSettingsGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.gui.elements.BooleanSettingButton; 5 | import namelessju.scathapro.gui.elements.SubMenuButton; 6 | import namelessju.scathapro.gui.menus.alerts.AlertSettingsGui; 7 | import namelessju.scathapro.gui.menus.overlay.OverlayGeneralSettingsGui; 8 | import namelessju.scathapro.managers.Config; 9 | import net.minecraft.client.gui.GuiScreen; 10 | 11 | public class MainSettingsGui extends ConfigGui 12 | { 13 | public MainSettingsGui(GuiScreen parentGui) 14 | { 15 | this(ScathaPro.getInstance(), parentGui); 16 | } 17 | 18 | public MainSettingsGui(ScathaPro scathaPro, GuiScreen parentGui) 19 | { 20 | super(scathaPro, parentGui); 21 | } 22 | 23 | @Override 24 | public String getTitle() 25 | { 26 | return "Settings"; 27 | } 28 | 29 | @Override 30 | public void initGui() 31 | { 32 | super.initGui(); 33 | 34 | addGridButton(new SubMenuButton(1, 0, 0, 0, 0, "UI Overlay...", this, OverlayGeneralSettingsGui.class)); 35 | addGridButton(new SubMenuButton(2, 0, 0, 0, 0, "Alerts...", this, AlertSettingsGui.class)); 36 | addGridButton(new SubMenuButton(7, 0, 0, 0, 0, "Player Rotation...", this, RotationAnglesSettingsGui.class)); 37 | addGridButton(new SubMenuButton(9, 0, 0, 0, 0, "Drop Message Extension...", this, DropMessageExtensionGui.class)); 38 | addGridButton(new SubMenuButton(10, 0, 0, 0, 0, "Chat Messages...", this, ChatMessageSettingsGui.class)); 39 | addGridButton(new SubMenuButton(3, 0, 0, 0, 0, "Sounds...", this, SoundSettingsGui.class)); 40 | addGridButton(new SubMenuButton(8, 0, 0, 0, 0, "Key Bindings...", this, KeybindingsGui.class)); 41 | addGridButton(new SubMenuButton(4, 0, 0, 0, 0, "Miscellaneous...", this, MiscSettingsGui.class)); 42 | addGridGap(); 43 | addGridButton(new BooleanSettingButton(5, 0, 0, 0, 0, "Autom. Update Checks", Config.Key.automaticUpdateChecks)); 44 | addGridButton(new BooleanSettingButton(6, 0, 0, 0, 0, "Automatic Backups", Config.Key.automaticBackups)); 45 | 46 | addDoneButton(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/Constants.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro; 2 | 3 | import java.util.UUID; 4 | 5 | import net.minecraft.util.EnumChatFormatting; 6 | 7 | public class Constants 8 | { 9 | public static final String chatPrefix = EnumChatFormatting.GRAY + "[" + ScathaPro.DYNAMIC_MODNAME + "] " + EnumChatFormatting.RESET; 10 | public static final String chatPrefixShort = EnumChatFormatting.GRAY + "[SP] " + EnumChatFormatting.RESET; 11 | public static final String chatPrefixDev = EnumChatFormatting.DARK_GREEN + "[" + EnumChatFormatting.OBFUSCATED + "[" + EnumChatFormatting.GREEN + "Scatha_Dev" + EnumChatFormatting.DARK_GREEN + EnumChatFormatting.OBFUSCATED + "]" + EnumChatFormatting.DARK_GREEN + "]" + EnumChatFormatting.RESET + " "; 12 | public static final String msgHighlightingColor = EnumChatFormatting.YELLOW.toString(); 13 | 14 | public static final int pingTreshold = 2000; 15 | 16 | public static final int[] postWorldJoinAreaCheckTimes = new int[] {200, 500, 1000, 2000, 3000, 5000, 10000}; 17 | /** The numbers of ticks after opening a chest GUI at which the parser tries to parse it's contents */ 18 | public static final int[] chestGuiParserTickCounts = new int[] {4, 10, 20, 40, 60, 100}; 19 | 20 | public static final int wormSpawnCooldown = 30000; 21 | public static final int wormLifetime = 30000; 22 | 23 | public static final float scathaPetBaseChanceRare = 0.0024f; 24 | public static final float scathaPetBaseChanceEpic = 0.0012f; 25 | public static final float scathaPetBaseChanceLegendary = 0.0004f; 26 | 27 | public static final int maxLegitPetDropsAmount = 9999; 28 | /** Dry streak gets invalidated if the mod's and the bestiary's Scatha kills differ more than this threshold */ 29 | public static final int dryStreakMaxAllowedScathaKillsDeviation = 10; 30 | 31 | // These are the wall coordinates 32 | public static final int crystalHollowsBoundsMin = 201; 33 | public static final int crystalHollowsBoundsMax = 824; 34 | 35 | public static final int anomalousDesireEffectDuration = 30000; 36 | 37 | public static final UUID devUUID = UUID.fromString("e9be3984-b097-40c9-8fb4-d8aaeb2b4838"); 38 | 39 | 40 | private Constants() {} 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/elements/ImageButton.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.elements; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.util.Util; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.client.gui.GuiIngame; 7 | import net.minecraft.client.renderer.GlStateManager; 8 | import net.minecraft.util.ResourceLocation; 9 | import net.minecraftforge.fml.relauncher.Side; 10 | import net.minecraftforge.fml.relauncher.SideOnly; 11 | 12 | @SideOnly(Side.CLIENT) 13 | public class ImageButton extends ScathaProButton 14 | { 15 | private ResourceLocation resourceLocation; 16 | private int textureWidth, textureHeight; 17 | private float textureScale; 18 | 19 | public ImageButton(int buttonId, int x, int y, int widthIn, int heightIn, String texturePath, int textureWidth, int textureHeight, float textureScale) 20 | { 21 | super(buttonId, x, y, widthIn, heightIn, ""); 22 | setImage(texturePath, textureWidth, textureHeight, textureScale); 23 | } 24 | 25 | @Override 26 | public void drawButton(Minecraft mc, int mouseX, int mouseY) 27 | { 28 | super.drawButton(mc, mouseX, mouseY); 29 | 30 | if (visible) drawImage(); 31 | } 32 | 33 | protected void drawImage() 34 | { 35 | Minecraft.getMinecraft().renderEngine.bindTexture(resourceLocation); 36 | GlStateManager.pushMatrix(); 37 | GlStateManager.translate(xPosition + width/2 - (textureWidth * textureScale)/2, yPosition + height/2 - (textureHeight * textureScale)/2 - 0.5f, 0); 38 | GlStateManager.scale(textureScale, textureScale, 1); 39 | Util.startImageRendering(); 40 | GuiIngame.drawModalRectWithCustomSizedTexture(0, 0, 0, 0, textureWidth, textureHeight, textureWidth, textureHeight); 41 | Util.endImageRendering(); 42 | GlStateManager.popMatrix(); 43 | } 44 | 45 | public void setImage(String texturePath, int textureWidth, int textureHeight, float textureScale) 46 | { 47 | this.textureWidth = textureWidth; 48 | this.textureHeight = textureHeight; 49 | this.textureScale = textureScale; 50 | resourceLocation = (texturePath != null && !texturePath.isEmpty()) ? new ResourceLocation(ScathaPro.MODID, "textures/" + texturePath) : null; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/overlay/elements/AnimatedOverlayImage.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.overlay.elements; 2 | 3 | import namelessju.scathapro.util.TimeUtil; 4 | import namelessju.scathapro.util.Util; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.client.gui.GuiIngame; 7 | import net.minecraft.client.renderer.GlStateManager; 8 | 9 | public class AnimatedOverlayImage extends OverlayImage 10 | { 11 | public int frameCount = 1; 12 | public int frameTimeMs = 1; 13 | 14 | public AnimatedOverlayImage(String texturePath, int textureWidth, int frameHeight, int x, int y, float scale, int frameCount, int frameTimeMs) 15 | { 16 | super(texturePath, textureWidth, frameHeight, x, y, scale); 17 | setFrame(frameCount, frameTimeMs); 18 | } 19 | 20 | public AnimatedOverlayImage(int x, int y, float scale) 21 | { 22 | super(x, y, scale); 23 | setFrame(1, 1); 24 | } 25 | 26 | @Override 27 | protected void drawSpecific() 28 | { 29 | if (resourceLocation == null) return; 30 | 31 | int currentFrame = (int) (TimeUtil.getAnimationTime() / frameTimeMs % frameCount); 32 | int v = currentFrame * textureHeight; 33 | 34 | Minecraft.getMinecraft().renderEngine.bindTexture(resourceLocation); 35 | Util.startImageRendering(); 36 | GlStateManager.color(r, g, b, 1f); 37 | GuiIngame.drawModalRectWithCustomSizedTexture(0, 0, 0, v, textureWidth, textureHeight, textureWidth, textureHeight * frameCount); 38 | Util.endImageRendering(); 39 | } 40 | 41 | @Override 42 | public void setImage(String texturePath, int textureWidth, int textureHeight) 43 | { 44 | setImage(texturePath, textureWidth, textureHeight, 1, 1); 45 | } 46 | 47 | public void setImage(String texturePath, int textureWidth, int textureHeight, int frameCount, int frameTimeMs) 48 | { 49 | super.setImage(texturePath, textureWidth, textureHeight); 50 | setFrame(frameCount, frameTimeMs); 51 | } 52 | 53 | protected void setFrame(int frameCount, int frameTimeMs) 54 | { 55 | this.frameCount = frameCount > 0 ? frameCount : 1; 56 | this.frameTimeMs = frameTimeMs > 0 ? frameTimeMs : 1; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/miscellaneous/sound/ScathaProMovingSound.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.miscellaneous.sound; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.audio.ITickableSound; 5 | import net.minecraft.entity.Entity; 6 | 7 | public class ScathaProMovingSound extends ScathaProSound implements ITickableSound 8 | { 9 | public Entity entity; 10 | protected boolean isDone = false; 11 | private boolean muted = false; 12 | private float x = 0f, y = 0f, z = 0f; 13 | 14 | public ScathaProMovingSound(String soundPath, float volume, float pitch, Entity entity) 15 | { 16 | super(soundPath, volume, pitch); 17 | this.entity = entity; 18 | } 19 | 20 | @Override 21 | public void update() 22 | { 23 | updatePosition(true); 24 | } 25 | 26 | protected void updatePosition(boolean stopIfEntityIsInvalid) 27 | { 28 | boolean isEntityInvalid = entity == null || entity.isDead || entity.worldObj == null; 29 | if (isEntityInvalid) 30 | { 31 | if (stopIfEntityIsInvalid) 32 | { 33 | isDone = true; 34 | entity = null; 35 | return; 36 | } 37 | 38 | muted = true; 39 | } 40 | else 41 | { 42 | muted = false; 43 | 44 | x = (float) entity.posX; 45 | y = (float) entity.posY; 46 | z = (float) entity.posZ; 47 | } 48 | } 49 | 50 | @Override 51 | public float getVolume() 52 | { 53 | return muted ? 0f : super.getVolume(); 54 | } 55 | 56 | @Override 57 | public float getXPosF() 58 | { 59 | return x; 60 | } 61 | 62 | @Override 63 | public float getYPosF() 64 | { 65 | return y; 66 | } 67 | 68 | @Override 69 | public float getZPosF() 70 | { 71 | return z; 72 | } 73 | 74 | @Override 75 | public boolean isDonePlaying() 76 | { 77 | return isDone || Minecraft.getMinecraft().theWorld == null; 78 | } 79 | 80 | @Override 81 | public AttenuationType getAttenuationType() 82 | { 83 | return AttenuationType.LINEAR; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/KeybindingsGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus; 2 | 3 | import java.io.IOException; 4 | 5 | import namelessju.scathapro.ScathaPro; 6 | import namelessju.scathapro.gui.lists.KeybindingsGuiList; 7 | import net.minecraft.client.gui.GuiScreen; 8 | import net.minecraft.client.settings.KeyBinding; 9 | 10 | public class KeybindingsGui extends ScathaProGui 11 | { 12 | public KeyBinding changingKeybinding = null; 13 | 14 | public KeybindingsGui(ScathaPro scathaPro, GuiScreen parentGui) 15 | { 16 | super(scathaPro, parentGui); 17 | } 18 | 19 | @Override 20 | public String getTitle() 21 | { 22 | return "Key Bindings"; 23 | } 24 | 25 | @Override 26 | public void initGui() 27 | { 28 | super.initGui(); 29 | 30 | scrollList = new KeybindingsGuiList(this); 31 | addScrollListDoneButton(); 32 | } 33 | 34 | @Override 35 | protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException 36 | { 37 | if (changingKeybinding != null) 38 | { 39 | mc.gameSettings.setOptionKeyBinding(changingKeybinding, -100 + mouseButton); 40 | changingKeybinding = null; 41 | KeyBinding.resetKeyBindingArrayAndHash(); 42 | } 43 | 44 | super.mouseClicked(mouseX, mouseY, mouseButton); 45 | } 46 | 47 | @Override 48 | protected void keyTyped(char typedChar, int keyCode) throws IOException 49 | { 50 | if (changingKeybinding != null) 51 | { 52 | if (keyCode == 1) 53 | { 54 | mc.gameSettings.setOptionKeyBinding(changingKeybinding, 0); 55 | } 56 | else if (keyCode != 0) 57 | { 58 | mc.gameSettings.setOptionKeyBinding(changingKeybinding, keyCode); 59 | } 60 | else if (typedChar > 0) 61 | { 62 | mc.gameSettings.setOptionKeyBinding(changingKeybinding, typedChar + 256); 63 | } 64 | 65 | changingKeybinding = null; 66 | KeyBinding.resetKeyBindingArrayAndHash(); 67 | } 68 | else 69 | { 70 | super.keyTyped(typedChar, keyCode); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/AchievementsGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus; 2 | 3 | import java.io.IOException; 4 | 5 | import namelessju.scathapro.ScathaPro; 6 | import namelessju.scathapro.gui.elements.AchievementsList; 7 | import namelessju.scathapro.gui.elements.SubMenuButton; 8 | import net.minecraft.client.gui.GuiScreen; 9 | import net.minecraft.client.gui.ScaledResolution; 10 | 11 | public class AchievementsGui extends ScathaProGui 12 | { 13 | private float heightFactor = 1f; 14 | private AchievementsList achievementsList; 15 | 16 | @Override 17 | public String getTitle() 18 | { 19 | return "Achievements"; 20 | } 21 | 22 | public AchievementsGui(ScathaPro scathaPro, GuiScreen parentGui) 23 | { 24 | super(scathaPro, parentGui); 25 | } 26 | 27 | @Override 28 | public void initGui() 29 | { 30 | super.initGui(); 31 | 32 | ScaledResolution scaledResolution = new ScaledResolution(mc); 33 | heightFactor = (height * scaledResolution.getScaleFactor()) / 1080f; 34 | 35 | initializeAchievementsList(); 36 | 37 | elements.add(new SubMenuButton(1, width / 2 - 100, Math.round(height - 24 - 50 * heightFactor), 200, 20, "Achievement Settings...", this, AchievementSettingsGui.class)); 38 | 39 | addDoneButton("Close", width / 2 - 100, Math.round(height - 50 * heightFactor), 200, 20); 40 | } 41 | 42 | private void initializeAchievementsList() 43 | { 44 | int achievementsListWidth = 310; 45 | int achievementsListX = width / 2 - achievementsListWidth / 2; 46 | int achievementsListY = 42; 47 | int achievementsListHeight = Math.round(height - achievementsListY - 20 - 50 * heightFactor - 10); 48 | achievementsList = new AchievementsList(achievementsListX, achievementsListY, achievementsListWidth, achievementsListHeight); 49 | } 50 | 51 | @Override 52 | public void handleMouseInput() throws IOException 53 | { 54 | super.handleMouseInput(); 55 | 56 | achievementsList.handleMouseInput(); 57 | } 58 | 59 | @Override 60 | public void drawScreen(int mouseX, int mouseY, float partialTicks) 61 | { 62 | super.drawScreen(mouseX, mouseY, partialTicks); 63 | 64 | achievementsList.draw(mouseX, mouseY, height); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/InfoMessageGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | 6 | import com.google.common.collect.Lists; 7 | 8 | import net.minecraft.client.gui.GuiButton; 9 | import net.minecraft.client.gui.GuiScreen; 10 | 11 | public class InfoMessageGui extends GuiScreen 12 | { 13 | private final GuiScreen parentScreen; 14 | private final String messageLine1; 15 | private final String messageLine2; 16 | private final List messageLine2WrappedLines = Lists.newArrayList(); 17 | private final String buttonText; 18 | 19 | public InfoMessageGui(GuiScreen parentScreen, String messageLine1, String messageLine2) 20 | { 21 | this(parentScreen, messageLine1, messageLine2, null); 22 | } 23 | 24 | public InfoMessageGui(GuiScreen parentScreen, String messageLine1, String messageLine2, String buttonText) 25 | { 26 | this.parentScreen = parentScreen; 27 | this.messageLine1 = messageLine1; 28 | this.messageLine2 = messageLine2; 29 | this.buttonText = buttonText; 30 | } 31 | 32 | public void initGui() 33 | { 34 | this.buttonList.add(new GuiButton(0, this.width / 2 - 50, this.height / 6 + 96, 100, 20, buttonText == null ? "OK" : buttonText)); 35 | this.messageLine2WrappedLines.clear(); 36 | this.messageLine2WrappedLines.addAll(this.fontRendererObj.listFormattedStringToWidth(this.messageLine2, Math.min(310, this.width - 50))); 37 | } 38 | 39 | protected void actionPerformed(GuiButton button) throws IOException 40 | { 41 | if (button.id == 0) 42 | { 43 | mc.displayGuiScreen(parentScreen); 44 | } 45 | } 46 | 47 | public void drawScreen(int mouseX, int mouseY, float partialTicks) 48 | { 49 | this.drawDefaultBackground(); 50 | 51 | this.drawCenteredString(this.fontRendererObj, this.messageLine1, this.width / 2, 70, 16777215); 52 | 53 | int i = 90; 54 | for (String s : this.messageLine2WrappedLines) 55 | { 56 | this.drawCenteredString(this.fontRendererObj, s, this.width / 2, i, 16777215); 57 | i += this.fontRendererObj.FONT_HEIGHT; 58 | } 59 | 60 | super.drawScreen(mouseX, mouseY, partialTicks); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/overlay/elements/OverlayImage.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.overlay.elements; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.util.Util; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.client.gui.GuiIngame; 7 | import net.minecraft.client.renderer.GlStateManager; 8 | import net.minecraft.util.ResourceLocation; 9 | 10 | public class OverlayImage extends OverlayElement 11 | { 12 | protected ResourceLocation resourceLocation; 13 | protected int textureWidth, textureHeight; 14 | protected float r = 1f; 15 | protected float g = 1f; 16 | protected float b = 1f; 17 | 18 | public OverlayImage(String texturePath, int textureWidth, int textureHeight, int x, int y, float scale) 19 | { 20 | super(x, y, scale); 21 | setImage(texturePath, textureWidth, textureHeight); 22 | } 23 | 24 | public OverlayImage(int x, int y, float scale) 25 | { 26 | super(x, y, scale); 27 | setImage(null, 1, 1); 28 | } 29 | 30 | @Override 31 | protected void drawSpecific() 32 | { 33 | if (resourceLocation == null) return; 34 | 35 | Minecraft.getMinecraft().renderEngine.bindTexture(resourceLocation); 36 | Util.startImageRendering(); 37 | GlStateManager.color(r, g, b, 1f); 38 | GuiIngame.drawModalRectWithCustomSizedTexture(0, 0, 0, 0, textureWidth, textureHeight, textureWidth, textureHeight); 39 | Util.endImageRendering(); 40 | } 41 | 42 | @Override 43 | public int getWidth() 44 | { 45 | return textureWidth; 46 | } 47 | 48 | @Override 49 | public int getHeight() 50 | { 51 | return textureHeight; 52 | } 53 | 54 | public void setImage(String texturePath, int textureWidth, int textureHeight) 55 | { 56 | this.textureWidth = textureWidth; 57 | this.textureHeight = textureHeight; 58 | resourceLocation = (texturePath != null && !texturePath.isEmpty()) ? new ResourceLocation(ScathaPro.MODID, "textures/" + texturePath) : null; 59 | } 60 | 61 | public void setColor(float r, float g, float b) 62 | { 63 | this.r = r; 64 | this.g = g; 65 | this.b = b; 66 | } 67 | 68 | public void setColor(int color) 69 | { 70 | this.r = ((color >> 16) & 0xFF) / 255f; 71 | this.g = ((color >> 8) & 0xFF) / 255f; 72 | this.b = (color & 0xFF) / 255f; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/elements/ScathaProButton.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.elements; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.gui.GuiButton; 5 | 6 | public class ScathaProButton extends GuiButton implements IGuiElement, ITooltipElement 7 | { 8 | private final Tooltip tooltip = new Tooltip(); 9 | 10 | public ScathaProButton(int buttonId, int x, int y, int widthIn, int heightIn, String buttonText) 11 | { 12 | super(buttonId, x, y, widthIn, heightIn, buttonText); 13 | } 14 | 15 | @Override 16 | public void setElementX(int x) 17 | { 18 | this.xPosition = x; 19 | } 20 | 21 | @Override 22 | public void setElementY(int y) 23 | { 24 | this.yPosition = y; 25 | } 26 | 27 | @Override 28 | public void setElementWidth(int width) 29 | { 30 | this.width = width; 31 | } 32 | 33 | @Override 34 | public void setElementHeight(int height) 35 | { 36 | this.height = height; 37 | } 38 | 39 | @Override 40 | public int getElementX() 41 | { 42 | return this.xPosition; 43 | } 44 | 45 | @Override 46 | public int getElementY() 47 | { 48 | return this.yPosition; 49 | } 50 | 51 | @Override 52 | public int getElementHeight() 53 | { 54 | return this.height; 55 | } 56 | 57 | @Override 58 | public int getElementWidth() 59 | { 60 | return this.width; 61 | } 62 | 63 | @Override 64 | public boolean elementMouseClicked(int mouseX, int mouseY, int mouseButton) 65 | { 66 | if (this.mousePressed(Minecraft.getMinecraft(), mouseX, mouseY)) 67 | { 68 | this.playPressSound(Minecraft.getMinecraft().getSoundHandler()); 69 | if (this instanceof IClickActionButton) ((IClickActionButton) this).click(); 70 | return true; 71 | } 72 | return false; 73 | } 74 | 75 | @Override 76 | public void elementDraw(int mouseX, int mouseY) 77 | { 78 | this.drawButton(Minecraft.getMinecraft(), mouseX, mouseY); 79 | } 80 | 81 | @Override 82 | public void drawButton(Minecraft mc, int mouseX, int mouseY) 83 | { 84 | super.drawButton(mc, mouseX, mouseY); 85 | 86 | if (this.visible && this.hovered) this.tooltip.requestRender(); 87 | } 88 | 89 | @Override 90 | public Tooltip getTooltip() 91 | { 92 | return tooltip; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/alerts/alertmodes/customalertmode/ICustomAlertModeSaveable.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.alerts.alertmodes.customalertmode; 2 | 3 | import java.io.File; 4 | import java.util.List; 5 | 6 | import com.google.common.collect.Lists; 7 | 8 | import namelessju.scathapro.ScathaPro; 9 | 10 | public interface ICustomAlertModeSaveable 11 | { 12 | public void saveChanges(SaveResults results); 13 | 14 | public static class SaveResults 15 | { 16 | public final String customModeId; 17 | private boolean resourceReloadRequested = false; 18 | private boolean propertiesSavingRequired = false; 19 | private List audioConversions = Lists.newArrayList(); 20 | 21 | public SaveResults(String customModeId) 22 | { 23 | this.customModeId = customModeId; 24 | } 25 | 26 | public void requestResourceReload() 27 | { 28 | resourceReloadRequested = true; 29 | } 30 | 31 | public boolean isResourceReloadRequired() 32 | { 33 | return (resourceReloadRequested || hasAudioConversions()) && ScathaPro.getInstance().getCustomAlertModeManager().isSubmodeActive(customModeId); 34 | } 35 | 36 | public void requestPropertiesSave() 37 | { 38 | propertiesSavingRequired = true; 39 | } 40 | 41 | public boolean isPropertiesSavingRequired() 42 | { 43 | return propertiesSavingRequired; 44 | } 45 | 46 | public void addAudioConversion(AudioConversion conversion) 47 | { 48 | if (audioConversions.contains(conversion)) return; 49 | audioConversions.add(conversion); 50 | } 51 | 52 | public boolean hasAudioConversions() 53 | { 54 | return audioConversions.size() > 0; 55 | } 56 | 57 | public AudioConversion[] getAudioConversions() 58 | { 59 | if (!hasAudioConversions()) return new AudioConversion[0]; 60 | return audioConversions.toArray(new AudioConversion[0]); 61 | } 62 | 63 | public static class AudioConversion 64 | { 65 | public File from; 66 | public File to; 67 | 68 | public AudioConversion(File from, File to) 69 | { 70 | this.from = from; 71 | this.to = to; 72 | } 73 | 74 | public boolean isValid() 75 | { 76 | return from != null && to != null && from.exists(); 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/ChatMessageSettingsGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.gui.elements.BooleanSettingButton; 5 | import namelessju.scathapro.managers.Config; 6 | import net.minecraft.client.gui.GuiScreen; 7 | import net.minecraft.util.EnumChatFormatting; 8 | 9 | public class ChatMessageSettingsGui extends ConfigGui 10 | { 11 | public ChatMessageSettingsGui(ScathaPro scathaPro, GuiScreen parentGui) 12 | { 13 | super(scathaPro, parentGui); 14 | } 15 | 16 | @Override 17 | public String getTitle() 18 | { 19 | return "Chat Message Settings"; 20 | } 21 | 22 | @Override 23 | public void initGui() 24 | { 25 | super.initGui(); 26 | 27 | addGridButton(new BooleanSettingButton(7, 0, 0, 0, 0, "Short " + ScathaPro.DYNAMIC_MODNAME + " Message Prefix", Config.Key.shortChatPrefix), GridElementMode.FULL_WIDTH); 28 | 29 | addGridButton(new BooleanSettingButton(1, 0, 0, 0, 0, "Dry Streak Message On Drop", Config.Key.dryStreakMessage), GridElementMode.FULL_WIDTH); 30 | 31 | BooleanSettingButton wormSpawnTimerMessageButton = new BooleanSettingButton(2, 0, 0, 0, 0, "Worm Spawn Timer Message", Config.Key.wormSpawnTimer); 32 | wormSpawnTimerMessageButton.getTooltip().setText(EnumChatFormatting.GRAY + "Sends a message with the elapsed time since the previous worm spawn when you spawn one"); 33 | addGridButton(wormSpawnTimerMessageButton, GridElementMode.FULL_WIDTH); 34 | 35 | BooleanSettingButton dailyStreakMessageButton = new BooleanSettingButton(8, 0, 0, 0, 0, "Daily Scatha Farming Streak Messages", Config.Key.dailyScathaFarmingStreakMessage); 36 | dailyStreakMessageButton.getTooltip().setText(EnumChatFormatting.GRAY + "Sends messages when your daily\nScatha farming streak changes"); 37 | addGridButton(dailyStreakMessageButton, GridElementMode.FULL_WIDTH); 38 | 39 | BooleanSettingButton chatCopySettingButton = new BooleanSettingButton(6, 0, 0, 0, 0, "Chat Message Copy Button", Config.Key.chatCopy); 40 | chatCopySettingButton.getTooltip().setText(EnumChatFormatting.GRAY + "Adds a clickable icon behind each chat message that copies the message into the input field"); 41 | addGridButton(chatCopySettingButton, GridElementMode.FULL_WIDTH); 42 | 43 | BooleanSettingButton hideWormApproachingMessageButton = new BooleanSettingButton(12, 0, 0, 0, 0, "Hide Worm Approaching Message", Config.Key.hideWormSpawnMessage); 44 | hideWormApproachingMessageButton.getTooltip().setText(EnumChatFormatting.GRAY + "Hides Hypixel's chat message that appears when a worm is about to spawn"); 45 | addGridButton(hideWormApproachingMessageButton, GridElementMode.FULL_WIDTH); 46 | 47 | 48 | addDoneButton(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/overlay/elements/OverlayContainer.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.overlay.elements; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import net.minecraft.client.gui.Gui; 7 | import net.minecraft.client.renderer.GlStateManager; 8 | 9 | public class OverlayContainer extends OverlayElement 10 | { 11 | protected List children = new ArrayList(); 12 | public Integer backgroundColor = null; 13 | public int padding = 0; 14 | 15 | public OverlayContainer(int x, int y, float scale) 16 | { 17 | super(x, y, scale); 18 | } 19 | 20 | @Override 21 | protected void drawSpecific() 22 | { 23 | if (backgroundColor != null) Gui.drawRect(0, 0, getWidth(), getHeight(), backgroundColor); 24 | 25 | GlStateManager.pushMatrix(); 26 | if (padding != 0) GlStateManager.translate(padding, padding, 0); 27 | 28 | for (OverlayElement element : children) 29 | { 30 | element.draw(); 31 | } 32 | 33 | GlStateManager.popMatrix(); 34 | } 35 | 36 | public void add(OverlayElement element) 37 | { 38 | children.add(element); 39 | } 40 | 41 | public void clearChildren() 42 | { 43 | children.clear(); 44 | } 45 | 46 | public List getChildren() 47 | { 48 | return children; 49 | } 50 | 51 | @Override 52 | public int getWidth() 53 | { 54 | int width = 0; 55 | 56 | for (OverlayElement child : children) 57 | { 58 | if (!child.expandsContainerSize || !child.isVisible() || isElementEmptyContainer(child)) continue; 59 | 60 | int elementRequiredWidth = child.getX() + child.getScaledWidth() + child.marginRight; 61 | if (elementRequiredWidth > width) width = elementRequiredWidth; 62 | } 63 | 64 | return width + padding * 2; 65 | } 66 | 67 | @Override 68 | public int getHeight() 69 | { 70 | int height = 0; 71 | 72 | for (OverlayElement child : children) 73 | { 74 | if (!child.expandsContainerSize || !child.isVisible() || isElementEmptyContainer(child)) continue; 75 | 76 | int elementRequiredHeight = child.getY() + child.getScaledHeight() + child.marginBottom; 77 | if (elementRequiredHeight > height) height = elementRequiredHeight; 78 | } 79 | 80 | return height + padding * 2; 81 | } 82 | 83 | public static boolean isElementEmptyContainer(OverlayElement element) 84 | { 85 | if (!(element instanceof OverlayContainer)) return false; 86 | 87 | OverlayContainer container = (OverlayContainer) element; 88 | 89 | if (container.children.size() == 0) return true; 90 | 91 | for (OverlayElement child : container.children) 92 | { 93 | if (child.isVisible() && !(isElementEmptyContainer(child))) return false; 94 | } 95 | 96 | return true; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/overlay/OverlayScathaPercentageSettingsGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus.overlay; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.gui.elements.BooleanSettingButton; 5 | import namelessju.scathapro.gui.elements.ScathaProSlider; 6 | import namelessju.scathapro.managers.Config; 7 | import net.minecraft.client.gui.GuiButton; 8 | import net.minecraft.client.gui.GuiScreen; 9 | import net.minecraftforge.fml.client.config.GuiSlider; 10 | 11 | public class OverlayScathaPercentageSettingsGui extends OverlaySettingsGui implements GuiSlider.ISlider 12 | { 13 | public OverlayScathaPercentageSettingsGui(ScathaPro scathaPro, GuiScreen parentGui) 14 | { 15 | super(scathaPro, parentGui); 16 | } 17 | 18 | @Override 19 | public String getTitle() 20 | { 21 | return "Overlay Scatha Percentage Settings"; 22 | } 23 | 24 | @Override 25 | public void initGui() 26 | { 27 | super.initGui(); 28 | 29 | elements.add(new ScathaProSlider(1, width / 2 - 155, height - 45 - 72 - 6, 310, 20, "Scatha Percentage Decimal Places: ", "", 0, 3, config.getInt(Config.Key.scathaPercentageDecimalDigits), false, true, this)); 30 | elements.add(new ScathaProSlider(2, width / 2 - 155, height - 45 - 48 - 6, 150, 20, "Amount Duration: ", "s", 1, 10, config.getInt(Config.Key.scathaPercentageCycleAmountDuration), false, true, this)); 31 | elements.add(new ScathaProSlider(3, width / 2 + 5, height - 45 - 48 - 6, 150, 20, "Percentage Duration: ", "s", 0, 10, config.getInt(Config.Key.scathaPercentageCyclePercentageDuration), false, true, this)); 32 | elements.add(new BooleanSettingButton(4, width / 2 - 155, height - 45 - 24 - 6, 310, 20, "Move Behind Total Kills", Config.Key.scathaPercentageAlternativePosition)); 33 | 34 | addDoneButton(width / 2 - 100, height - 45, 200, 20); 35 | } 36 | 37 | @Override 38 | protected void actionPerformed(GuiButton button) 39 | { 40 | super.actionPerformed(button); 41 | 42 | if (button.id == 4) 43 | { 44 | if (scathaPro.getConfig().getBoolean(Config.Key.scathaPercentageAlternativePosition)) scathaPro.getOverlay().updateScathaKills(); 45 | else scathaPro.getOverlay().updateTotalKills(); 46 | } 47 | } 48 | 49 | @Override 50 | public void onChangeSliderValue(GuiSlider slider) 51 | { 52 | if (!slider.enabled) return; 53 | switch (slider.id) 54 | { 55 | case 1: 56 | config.set(Config.Key.scathaPercentageDecimalDigits, slider.getValueInt()); 57 | 58 | scathaPro.getOverlay().updateTotalKills(); 59 | break; 60 | 61 | case 2: 62 | config.set(Config.Key.scathaPercentageCycleAmountDuration, slider.getValueInt()); 63 | break; 64 | 65 | case 3: 66 | config.set(Config.Key.scathaPercentageCyclePercentageDuration, slider.getValueInt()); 67 | break; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/SoundSettingsGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.gui.elements.BooleanSettingButton; 5 | import namelessju.scathapro.gui.elements.ScathaProSlider; 6 | import namelessju.scathapro.managers.Config; 7 | import net.minecraft.client.gui.GuiButton; 8 | import net.minecraft.client.gui.GuiScreen; 9 | import net.minecraft.util.EnumChatFormatting; 10 | import net.minecraftforge.fml.client.config.GuiSlider; 11 | 12 | public class SoundSettingsGui extends ConfigGui implements GuiSlider.ISlider 13 | { 14 | private BooleanSettingButton muteCHSoundsButton, keepDragonLairSoundsButton; 15 | 16 | public SoundSettingsGui(ScathaPro scathaPro, GuiScreen parentGui) 17 | { 18 | super(scathaPro, parentGui); 19 | } 20 | 21 | @Override 22 | public String getTitle() 23 | { 24 | return "Sound Settings"; 25 | } 26 | 27 | @Override 28 | public void initGui() 29 | { 30 | super.initGui(); 31 | 32 | addGridButton(new ScathaProSlider(1, 0, 0, 0, 0, ScathaPro.DYNAMIC_MODNAME + " Sounds Volume: ", "%", 0, 100, scathaPro.getConfig().getDouble(Config.Key.soundsVolume) * 100, false, true, this), GridElementMode.FULL_WIDTH); 33 | addGridGap(); 34 | addGridButton(muteCHSoundsButton = new BooleanSettingButton(2, 0, 0, 0, 0, "Mute Crystal Hollows Sounds", Config.Key.muteCrystalHollowsSounds), GridElementMode.FULL_WIDTH); 35 | addGridButton(keepDragonLairSoundsButton = new BooleanSettingButton(3, 0, 0, 0, 0, "Keep Golden Dragon's Lair Sounds", Config.Key.keepDragonLairSounds), GridElementMode.FULL_WIDTH); 36 | updateMuteCHSoundsButtons(); 37 | 38 | addDoneButton(); 39 | } 40 | 41 | @Override 42 | protected void actionPerformed(GuiButton button) 43 | { 44 | switch (button.id) 45 | { 46 | case 2: 47 | updateMuteCHSoundsButtons(); 48 | break; 49 | } 50 | } 51 | 52 | @Override 53 | public void onChangeSliderValue(GuiSlider slider) 54 | { 55 | if (slider.enabled) 56 | { 57 | switch (slider.id) 58 | { 59 | case 1: 60 | double volume = (double) slider.getValueInt() / 100; 61 | 62 | Config config = scathaPro.getConfig(); 63 | config.set(Config.Key.soundsVolume, volume); 64 | break; 65 | } 66 | } 67 | } 68 | 69 | private void updateMuteCHSoundsButtons() 70 | { 71 | if (muteCHSoundsButton.isSettingEnabled()) 72 | { 73 | keepDragonLairSoundsButton.enabled = true; 74 | keepDragonLairSoundsButton.getTooltip().setText(null); 75 | } 76 | else 77 | { 78 | keepDragonLairSoundsButton.enabled = false; 79 | keepDragonLairSoundsButton.getTooltip().setText(EnumChatFormatting.YELLOW + "Applies only when Crystal\nHollows sounds are muted"); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/AchievementSettingsGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.gui.elements.BooleanSettingButton; 5 | import namelessju.scathapro.managers.Config; 6 | import net.minecraft.client.gui.GuiButton; 7 | import net.minecraft.client.gui.GuiScreen; 8 | import net.minecraft.util.EnumChatFormatting; 9 | 10 | public class AchievementSettingsGui extends ConfigGui 11 | { 12 | private BooleanSettingButton unlockAlertsButton, repeatUnlockAlertsButton; 13 | 14 | @Override 15 | public String getTitle() 16 | { 17 | return "Achievement Settings"; 18 | } 19 | 20 | public AchievementSettingsGui(ScathaPro scathaPro, GuiScreen parentGui) 21 | { 22 | super(scathaPro, parentGui); 23 | } 24 | 25 | @Override 26 | public void initGui() 27 | { 28 | super.initGui(); 29 | 30 | BooleanSettingButton preOpenCategoriesButton; 31 | addGridButton(preOpenCategoriesButton = new BooleanSettingButton(6, 0, 0, 0, 0, "Pre-Open List Categories", Config.Key.achievementListPreOpenCategories), GridElementMode.FULL_WIDTH); 32 | preOpenCategoriesButton.getTooltip().setText(EnumChatFormatting.GRAY + "Automatically opens all categories\nwhen opening the achievement list"); 33 | addGridGap(); 34 | addGridButton(new BooleanSettingButton(1, 0, 0, 0, 0, "Show Non-Unlocked Bonus Achievements", Config.Key.bonusAchievementsShown), GridElementMode.FULL_WIDTH); 35 | addGridButton(new BooleanSettingButton(2, 0, 0, 0, 0, "Hide Unlocked Achievements", Config.Key.hideUnlockedAchievements), GridElementMode.FULL_WIDTH); 36 | addGridButton(new BooleanSettingButton(5, 0, 0, 0, 0, "Show Repeat Counts And Progress", Config.Key.repeatCountsShown), GridElementMode.FULL_WIDTH); 37 | addGridGap(); 38 | addGridButton(unlockAlertsButton = new BooleanSettingButton(3, 0, 0, 0, 0, "Achievement Unlock Alerts", Config.Key.playAchievementAlerts), GridElementMode.FULL_WIDTH); 39 | addGridButton(repeatUnlockAlertsButton = new BooleanSettingButton(4, 0, 0, 0, 0, "Achievement Repeat Unlock Alerts", Config.Key.playRepeatAchievementAlerts), GridElementMode.FULL_WIDTH); 40 | 41 | addDoneButton(); 42 | 43 | updateRepeatUnlockAlertsButton(); 44 | } 45 | 46 | @Override 47 | protected void actionPerformed(GuiButton button) 48 | { 49 | super.actionPerformed(button); 50 | 51 | switch (button.id) 52 | { 53 | case 1: 54 | scathaPro.getAchievementManager().updateBonusTypeVisibility(); 55 | break; 56 | case 3: 57 | case 4: 58 | updateRepeatUnlockAlertsButton(); 59 | break; 60 | } 61 | } 62 | 63 | private void updateRepeatUnlockAlertsButton() 64 | { 65 | boolean generalAlertsEnabled = unlockAlertsButton.isSettingEnabled(); 66 | repeatUnlockAlertsButton.enabled = generalAlertsEnabled; 67 | repeatUnlockAlertsButton.getTooltip().setText(generalAlertsEnabled ? null : EnumChatFormatting.YELLOW + "Requires generic achievement\n" + EnumChatFormatting.YELLOW + "unlock alerts to be enabled"); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/alerts/AlertSettingsGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus.alerts; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.alerts.alertmodes.AlertMode; 5 | import namelessju.scathapro.alerts.alertmodes.AlertModeButtonOption; 6 | import namelessju.scathapro.alerts.alertmodes.customalertmode.CustomAlertMode; 7 | import namelessju.scathapro.gui.elements.CycleButton; 8 | import namelessju.scathapro.gui.elements.ScathaProButton; 9 | import namelessju.scathapro.gui.elements.SubMenuButton; 10 | import namelessju.scathapro.gui.menus.ConfigGui; 11 | import namelessju.scathapro.gui.menus.CustomAlertModeGui; 12 | import namelessju.scathapro.managers.Config; 13 | import net.minecraft.client.gui.GuiButton; 14 | import net.minecraft.client.gui.GuiScreen; 15 | import net.minecraft.util.EnumChatFormatting; 16 | 17 | public class AlertSettingsGui extends ConfigGui 18 | { 19 | private ScathaProButton customAlertModeEditButton; 20 | 21 | public AlertSettingsGui(ScathaPro scathaPro, GuiScreen parentGui) 22 | { 23 | super(scathaPro, parentGui); 24 | } 25 | 26 | @Override 27 | public String getTitle() 28 | { 29 | return "Alert Settings"; 30 | } 31 | 32 | @Override 33 | public void initGui() 34 | { 35 | super.initGui(); 36 | 37 | CycleButton modeButton = new CycleButton(1, 0, 0, 0, 0, "Alert Mode", AlertModeButtonOption.getAllOptions(), scathaPro.getAlertModeManager().getCurrentMode(), button -> { 38 | config.set(Config.Key.mode, button.getSelectedValue().id); 39 | scathaPro.getOverlay().updateScathaPetImage(); 40 | }); 41 | modeButton.getTooltip().setText(EnumChatFormatting.GRAY + "Each mode plays different sounds\n(and titles in custom mode)"); 42 | addGridButton(modeButton); 43 | addGridButton(customAlertModeEditButton = new SubMenuButton(2, 0, 0, 0, 0, "Custom Alert Modes...", this, CustomAlertModeGui.class)); 44 | updateModeButtons(); 45 | 46 | addGridGap(); 47 | 48 | addGridButton(new SubMenuButton(5, 0, 0, 0, 0, "Enable/Disable Alerts...", this, AlertStatesGui.class)); 49 | addGridButton(new SubMenuButton(4, 0, 0, 0, 0, "Alert Configuration...", this, AlertConfigurationGui.class)); 50 | addGridButton(new SubMenuButton(3, 0, 0, 0, 0, "Alert Title Position...", this, AlertTitleSettingsGui.class)); 51 | 52 | addDoneButton(); 53 | } 54 | 55 | @Override 56 | protected void actionPerformed(GuiButton button) 57 | { 58 | super.actionPerformed(button); 59 | 60 | switch (button.id) 61 | { 62 | case 1: 63 | updateModeButtons(); 64 | break; 65 | } 66 | } 67 | 68 | private void updateModeButtons() 69 | { 70 | if (scathaPro.getAlertModeManager().getCurrentMode() instanceof CustomAlertMode) 71 | { 72 | customAlertModeEditButton.enabled = true; 73 | customAlertModeEditButton.getTooltip().setText(null); 74 | } 75 | else 76 | { 77 | customAlertModeEditButton.enabled = false; 78 | customAlertModeEditButton.getTooltip().setText(EnumChatFormatting.YELLOW + "Select \"Custom\" to access custom alert mode settings", 150); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/lists/OverlayComponentsGuiList.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.lists; 2 | 3 | import namelessju.scathapro.gui.elements.BooleanSettingButton; 4 | import namelessju.scathapro.gui.elements.ScathaProButton; 5 | import namelessju.scathapro.gui.menus.ScathaProGui; 6 | import namelessju.scathapro.managers.Config; 7 | import namelessju.scathapro.overlay.Overlay.ToggleableOverlayElement; 8 | 9 | public class OverlayComponentsGuiList extends ScathaProGuiList 10 | { 11 | private ToggleableOverlayElement hoveredElement = null; 12 | 13 | public OverlayComponentsGuiList(ScathaProGui gui) 14 | { 15 | super(gui, 63, gui.height - 40, 25); 16 | 17 | this.listEntries.add(new OverlayBackgroundEntry()); 18 | 19 | for (ToggleableOverlayElement toggleableElement : gui.scathaPro.getOverlay().toggleableOverlayElements) 20 | { 21 | this.listEntries.add(new OverlayToggleableElementEntry(toggleableElement)); 22 | } 23 | } 24 | 25 | public ToggleableOverlayElement getHoveredElement() 26 | { 27 | return hoveredElement; 28 | } 29 | 30 | @Override 31 | public void drawScreen(int mouseXIn, int mouseYIn, float partialTicks) 32 | { 33 | hoveredElement = null; 34 | 35 | super.drawScreen(mouseXIn, mouseYIn, partialTicks); 36 | 37 | if (!this.isMouseYWithinSlotBounds(mouseY)) 38 | { 39 | hoveredElement = null; 40 | } 41 | } 42 | 43 | 44 | private class OverlayBackgroundEntry extends ListEntry 45 | { 46 | public OverlayBackgroundEntry() 47 | { 48 | addElement(new BooleanSettingButton(0, 0, 2, getListWidth(), 20, "Darkened Background", Config.Key.overlayBackgroundEnabled)); 49 | } 50 | } 51 | 52 | private class OverlayToggleableElementEntry extends ListEntry 53 | { 54 | private ToggleableOverlayElement toggleableElement; 55 | private ScathaProButton button; 56 | 57 | public OverlayToggleableElementEntry(ToggleableOverlayElement toggleableElement) 58 | { 59 | this.toggleableElement = toggleableElement; 60 | 61 | addElement(button = new ScathaProButton(0, 0, 2, getListWidth(), 20, "")); 62 | updateButtonText(); 63 | } 64 | 65 | private void updateButtonText() 66 | { 67 | button.displayString = toggleableElement.elementName + ": " + (toggleableElement.isVisible() ? "ON" : "OFF"); 68 | } 69 | 70 | @Override 71 | protected void onButtonPressed(ScathaProButton button) 72 | { 73 | switch (button.id) 74 | { 75 | case 0: 76 | toggleableElement.toggle(); 77 | updateButtonText(); 78 | break; 79 | } 80 | } 81 | 82 | @Override 83 | public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected) 84 | { 85 | super.drawEntry(slotIndex, x, y, listWidth, slotHeight, mouseX, mouseY, isSelected); 86 | 87 | if (isEntryWithinSlotBounds(y, slotHeight) && button.isHovered(mouseX, mouseY)) 88 | { 89 | hoveredElement = toggleableElement; 90 | } 91 | } 92 | } 93 | 94 | } -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/elements/ScathaProSlider.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.elements; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraftforge.fml.client.config.GuiSlider; 5 | 6 | public class ScathaProSlider extends GuiSlider implements IGuiElement, ITooltipElement 7 | { 8 | private final Tooltip tooltip = new Tooltip(); 9 | 10 | public ScathaProSlider(int id, int xPos, int yPos, int width, int height, String prefix, String suf, double minVal, 11 | double maxVal, double currentVal, boolean showDec, boolean drawStr) 12 | { 13 | this(id, xPos, yPos, width, height, prefix, suf, minVal, maxVal, currentVal, showDec, drawStr, null); 14 | } 15 | 16 | public ScathaProSlider(int id, int xPos, int yPos, int width, int height, String prefix, String suf, double minVal, 17 | double maxVal, double currentVal, boolean showDec, boolean drawStr, ISlider par) 18 | { 19 | super(id, xPos, yPos, width, height, prefix, suf, minVal, maxVal, currentVal, showDec, drawStr, par); 20 | } 21 | 22 | public void updateSliderWithoutEvent() 23 | { 24 | ISlider parent = this.parent; 25 | this.parent = null; 26 | this.updateSlider(); 27 | this.parent = parent; 28 | } 29 | 30 | @Override 31 | public void setElementX(int x) 32 | { 33 | this.xPosition = x; 34 | } 35 | 36 | @Override 37 | public void setElementY(int y) 38 | { 39 | this.yPosition = y; 40 | } 41 | 42 | @Override 43 | public void setElementWidth(int width) 44 | { 45 | this.width = width; 46 | } 47 | 48 | @Override 49 | public void setElementHeight(int height) 50 | { 51 | this.height = height; 52 | } 53 | 54 | @Override 55 | public int getElementX() 56 | { 57 | return this.xPosition; 58 | } 59 | 60 | @Override 61 | public int getElementY() 62 | { 63 | return this.yPosition; 64 | } 65 | 66 | @Override 67 | public int getElementWidth() 68 | { 69 | return this.width; 70 | } 71 | 72 | @Override 73 | public int getElementHeight() 74 | { 75 | return this.height; 76 | } 77 | 78 | @Override 79 | public boolean elementMouseClicked(int mouseX, int mouseY, int mouseButton) 80 | { 81 | if (this.mousePressed(Minecraft.getMinecraft(), mouseX, mouseY)) 82 | { 83 | this.playPressSound(Minecraft.getMinecraft().getSoundHandler()); 84 | return true; 85 | } 86 | return false; 87 | } 88 | 89 | @Override 90 | public void elementMouseReleased(int mouseX, int mouseY) 91 | { 92 | super.mouseReleased(mouseX, mouseY); 93 | } 94 | 95 | @Override 96 | public void elementDraw(int mouseX, int mouseY) 97 | { 98 | this.drawButton(Minecraft.getMinecraft(), mouseX, mouseY); 99 | } 100 | 101 | @Override 102 | public void drawButton(Minecraft mc, int mouseX, int mouseY) 103 | { 104 | super.drawButton(mc, mouseX, mouseY); 105 | 106 | if (this.visible && this.hovered) this.tooltip.requestRender(); 107 | } 108 | 109 | @Override 110 | public Tooltip getTooltip() 111 | { 112 | return tooltip; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/miscellaneous/StackedScissorCheck.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.miscellaneous; 2 | 3 | import org.lwjgl.opengl.GL11; 4 | 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.client.gui.ScaledResolution; 7 | 8 | public class StackedScissorCheck 9 | { 10 | private static class ScissorCheck 11 | { 12 | public final int x, y, width, height; 13 | 14 | public ScissorCheck(int x, int y, int width, int height) 15 | { 16 | this.x = x; 17 | this.y = y; 18 | this.width = width; 19 | this.height = height; 20 | } 21 | } 22 | 23 | private static int currentIndex = -1; 24 | private static ScissorCheck[] stack = new ScissorCheck[4]; 25 | 26 | public static void pushCheck(int x, int y, int width, int height) 27 | { 28 | if (currentIndex >= stack.length - 1) throw new IllegalStateException("Max scissor stack size (" + stack.length + ") exceeded."); 29 | currentIndex ++; 30 | stack[currentIndex] = new ScissorCheck(x, y, width, height); 31 | updateScissor(); 32 | } 33 | 34 | public static void popCheck() 35 | { 36 | if (currentIndex < 0) return; 37 | stack[currentIndex] = null; 38 | currentIndex --; 39 | updateScissor(); 40 | } 41 | 42 | public static void clearStack() 43 | { 44 | for (int i = 0; i < stack.length; i ++) 45 | { 46 | stack[i] = null; 47 | } 48 | currentIndex = -1; 49 | updateScissor(); 50 | } 51 | 52 | private static void updateScissor() 53 | { 54 | if (currentIndex < 0) 55 | { 56 | GL11.glDisable(GL11.GL_SCISSOR_TEST); 57 | return; 58 | } 59 | 60 | ScissorCheck checkCombination = null; 61 | for (int i = 0; i <= currentIndex; i ++) 62 | { 63 | ScissorCheck nextCheck = stack[i]; 64 | 65 | if (checkCombination == null) 66 | { 67 | checkCombination = nextCheck; 68 | continue; 69 | } 70 | 71 | int dx1 = checkCombination.x + checkCombination.width; 72 | int dy1 = checkCombination.y + checkCombination.height; 73 | int dx2 = nextCheck.x + nextCheck.width; 74 | int dy2 = nextCheck.y + nextCheck.height; 75 | 76 | int xMax = Math.max(checkCombination.x, nextCheck.x); 77 | int yMax = Math.max(checkCombination.y, nextCheck.y); 78 | int dxMin = Math.min(dx1, dx2); 79 | int dyMin = Math.min(dy1, dy2); 80 | 81 | checkCombination = new ScissorCheck(xMax, yMax, Math.max(xMax, dxMin) - xMax, Math.max(yMax, dyMin) - yMax); 82 | } 83 | 84 | if (checkCombination == null) 85 | { 86 | GL11.glDisable(GL11.GL_SCISSOR_TEST); 87 | return; 88 | } 89 | 90 | int scaleFactor = new ScaledResolution(Minecraft.getMinecraft()).getScaleFactor(); 91 | 92 | GL11.glEnable(GL11.GL_SCISSOR_TEST); 93 | GL11.glScissor(checkCombination.x * scaleFactor, Minecraft.getMinecraft().displayHeight - (checkCombination.y + checkCombination.height) * scaleFactor, checkCombination.width * scaleFactor, checkCombination.height * scaleFactor); 94 | } 95 | 96 | 97 | private StackedScissorCheck() {} 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/overlay/elements/OverlayElement.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.overlay.elements; 2 | 3 | import net.minecraft.client.renderer.GlStateManager; 4 | 5 | public abstract class OverlayElement 6 | { 7 | public static enum Alignment 8 | { 9 | LEFT("Left"), CENTER("Center"), RIGHT("Right"); 10 | 11 | private String name; 12 | 13 | Alignment(String name) 14 | { 15 | this.name = name; 16 | } 17 | 18 | @Override 19 | public String toString() 20 | { 21 | return name; 22 | } 23 | } 24 | 25 | protected int x, y; 26 | protected float scale; 27 | protected Alignment alignment = Alignment.LEFT; 28 | protected boolean visible = true; 29 | protected int marginRight = 0, marginBottom = 0; 30 | public boolean expandsContainerSize = true; 31 | 32 | public OverlayElement(int x, int y, float scale) 33 | { 34 | this.x = x; 35 | this.y = y; 36 | this.scale = scale; 37 | } 38 | 39 | @SuppressWarnings("unchecked") 40 | public T setMargin(int right, int bottom) 41 | { 42 | this.marginRight = right; 43 | this.marginBottom = bottom; 44 | return (T) this; 45 | } 46 | 47 | @SuppressWarnings("unchecked") 48 | public T setAlignment(Alignment alignment) 49 | { 50 | this.alignment = alignment; 51 | return (T) this; 52 | } 53 | 54 | public void draw() 55 | { 56 | draw(true, true, this.alignment); 57 | } 58 | 59 | public void draw(boolean positioned, boolean scaled, Alignment alignment) 60 | { 61 | if (!visible) return; 62 | 63 | GlStateManager.pushMatrix(); 64 | 65 | if (positioned) GlStateManager.translate(x, y, 0); 66 | 67 | if (alignment != null) 68 | { 69 | switch (alignment) 70 | { 71 | case CENTER: 72 | GlStateManager.translate(-Math.floor((getWidth() * scale) / 2f), 0, 0); 73 | break; 74 | case RIGHT: 75 | GlStateManager.translate(-Math.floor(getWidth() * scale), 0, 0); 76 | break; 77 | default: break; 78 | } 79 | } 80 | 81 | if (scaled) GlStateManager.scale(scale, scale, 1f); 82 | 83 | drawSpecific(); 84 | 85 | GlStateManager.popMatrix(); 86 | GlStateManager.resetColor(); 87 | } 88 | 89 | protected abstract void drawSpecific(); 90 | 91 | public void setPosition(int x, int y) 92 | { 93 | this.x = x; 94 | this.y = y; 95 | } 96 | 97 | public void setScale(float scale) 98 | { 99 | this.scale = scale; 100 | } 101 | 102 | public float getScale() 103 | { 104 | return this.scale; 105 | } 106 | 107 | public void setVisible(boolean visible) 108 | { 109 | this.visible = visible; 110 | } 111 | 112 | public int getX() 113 | { 114 | return x; 115 | } 116 | 117 | public int getY() 118 | { 119 | return y; 120 | } 121 | 122 | public int getScaledWidth() 123 | { 124 | return (int) Math.ceil(getWidth() * scale); 125 | } 126 | 127 | public int getScaledHeight() 128 | { 129 | return (int) Math.ceil(getHeight() * scale); 130 | } 131 | 132 | public abstract int getWidth(); 133 | public abstract int getHeight(); 134 | 135 | public boolean isVisible() 136 | { 137 | return visible; 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/RotationAnglesSettingsGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.gui.elements.BooleanSettingButton; 5 | import namelessju.scathapro.gui.elements.ScathaProSlider; 6 | import namelessju.scathapro.managers.Config; 7 | import net.minecraft.client.gui.GuiScreen; 8 | import net.minecraft.client.resources.I18n; 9 | import net.minecraft.util.EnumChatFormatting; 10 | import net.minecraftforge.fml.client.config.GuiSlider; 11 | 12 | public class RotationAnglesSettingsGui extends ConfigGui implements GuiSlider.ISlider 13 | { 14 | private ScathaProSlider alternativeSensitivitySlider; 15 | 16 | public RotationAnglesSettingsGui(ScathaPro scathaPro, GuiScreen parentGui) 17 | { 18 | super(scathaPro, parentGui); 19 | } 20 | 21 | @Override 22 | public String getTitle() 23 | { 24 | return "Player Rotation Settings"; 25 | } 26 | 27 | @Override 28 | public void initGui() 29 | { 30 | super.initGui(); 31 | 32 | double alternativeSensitivity = config.getDouble(Config.Key.alternativeSensitivity); 33 | alternativeSensitivitySlider = new ScathaProSlider(4, 0, 0, 0, 0, "Alternative Sensitivity: ", "%", 0f, 1f, alternativeSensitivity, false, true, this); 34 | alternativeSensitivitySlider.getTooltip().setText(EnumChatFormatting.GRAY + "The key binding of the same name replaces the main sensitivity with this one while the key is being held"); 35 | elements.add(setGridPosition(alternativeSensitivitySlider, GridElementMode.FULL_WIDTH)); 36 | updateAlternativeSensitivitySliderText(); 37 | 38 | addGridGap(); 39 | 40 | addGridButton(new BooleanSettingButton(1, 0, 0, 0, 0, "Pitch/Yaw Display", Config.Key.showRotationAngles)); 41 | 42 | BooleanSettingButton yawOnlyButton; 43 | addGridButton(yawOnlyButton = new BooleanSettingButton(2, 0, 0, 0, 0, "Show Yaw Only", Config.Key.rotationAnglesYawOnly)); 44 | yawOnlyButton.getTooltip().setText(EnumChatFormatting.GRAY + "Yaw = left/right rotation"); 45 | 46 | addGridButton(new ScathaProSlider(3, 0, 0, 0, 0, "Display Decimal Places: ", "", 0, 3, config.getInt(Config.Key.rotationAnglesDecimalDigits), false, true, this)); 47 | 48 | BooleanSettingButton minimalYawButton; 49 | addGridButton(minimalYawButton = new BooleanSettingButton(4, 0, 0, 0, 0, "Shorter Yaw", Config.Key.rotationAnglesMinimalYaw)); 50 | minimalYawButton.getTooltip().setText(EnumChatFormatting.GRAY + "Hides the tens and hundreds\nplaces of the yaw value", 200); 51 | 52 | addDoneButton(); 53 | } 54 | 55 | @Override 56 | public void onChangeSliderValue(GuiSlider slider) 57 | { 58 | if (!slider.enabled) return; 59 | switch (slider.id) 60 | { 61 | case 3: 62 | config.set(Config.Key.rotationAnglesDecimalDigits, slider.getValueInt()); 63 | break; 64 | 65 | case 4: 66 | config.set(Config.Key.alternativeSensitivity, slider.getValue()); 67 | updateAlternativeSensitivitySliderText(); 68 | break; 69 | } 70 | } 71 | 72 | private void updateAlternativeSensitivitySliderText() 73 | { 74 | int value = (int) Math.round(alternativeSensitivitySlider.getValue() * 200); 75 | alternativeSensitivitySlider.displayString = alternativeSensitivitySlider.dispString 76 | + (value == 0 ? I18n.format("options.sensitivity.min") 77 | : (value == 200 ? I18n.format("options.sensitivity.max") 78 | : value + alternativeSensitivitySlider.suffix 79 | ) 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/overlay/OverlayPositionSettingsGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus.overlay; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.gui.elements.CycleButton; 5 | import namelessju.scathapro.gui.elements.ScathaProSlider; 6 | import namelessju.scathapro.managers.Config; 7 | import namelessju.scathapro.overlay.elements.OverlayElement; 8 | import net.minecraft.client.gui.GuiScreen; 9 | import net.minecraftforge.fml.client.config.GuiSlider; 10 | 11 | public class OverlayPositionSettingsGui extends OverlaySettingsGui implements GuiSlider.ISlider 12 | { 13 | public OverlayPositionSettingsGui(ScathaPro scathaPro, GuiScreen parentGui) 14 | { 15 | super(scathaPro, parentGui); 16 | } 17 | 18 | @Override 19 | public String getTitle() 20 | { 21 | return "Overlay Position"; 22 | } 23 | 24 | @Override 25 | public void initGui() 26 | { 27 | super.initGui(); 28 | 29 | double overlayX = config.getDouble(Config.Key.overlayX); 30 | ScathaProSlider overlayXSlider = new ScathaProSlider(1, width / 2 - 155, height - 45 - 24 - 6, 150, 20, "X Position: ", "%", -1, 100, overlayX >= 0 ? overlayX * 100 : -1, false, true, this); 31 | if (overlayX < 0) setSliderTextDefault(overlayXSlider); 32 | elements.add(overlayXSlider); 33 | 34 | double overlayY = config.getDouble(Config.Key.overlayY); 35 | ScathaProSlider overlayYSlider = new ScathaProSlider(2, width / 2 + 5, height - 45 - 24 - 6, 150, 20, "Y Position: ", "%", -1, 100, overlayY >= 0 ? overlayY * 100 : -1, false, true, this); 36 | if (overlayY < 0) setSliderTextDefault(overlayYSlider); 37 | elements.add(overlayYSlider); 38 | 39 | elements.add(new ScathaProSlider(3, width / 2 - 155, height - 45 - 48 - 6, 310, 20, "Scale: ", "%", 25, 175, config.getDouble(Config.Key.overlayScale) * 100, false, true, this)); 40 | 41 | CycleButton alignmentButton = new CycleButton(4, width / 2 - 155, height - 45 - 72 - 6, 310, 20, "Alignment", CycleButton.EnumOption.from(OverlayElement.Alignment.class, true), config.getEnum(Config.Key.overlayAlignment, OverlayElement.Alignment.class), button -> { 42 | OverlayElement.Alignment value = button.getSelectedValue(); 43 | config.set(Config.Key.overlayAlignment, value != null ? value.name() : ""); 44 | 45 | scathaPro.getOverlay().updateContentAlignment(); 46 | }); 47 | alignmentButton.setNullOptionName("Automatic"); 48 | elements.add(alignmentButton); 49 | 50 | addDoneButton(width / 2 - 100, height - 45, 200, 20); 51 | 52 | overlay.updateOverlayFull(); 53 | } 54 | 55 | @Override 56 | public void onChangeSliderValue(GuiSlider slider) 57 | { 58 | if (!slider.enabled) return; 59 | switch (slider.id) 60 | { 61 | case 1: 62 | double overlayX = (double) slider.getValueInt() / 100; 63 | config.set(Config.Key.overlayX, overlayX >= 0 ? overlayX : -1); 64 | 65 | overlay.updatePosition(); 66 | 67 | if (overlayX < 0) setSliderTextDefault(slider); 68 | break; 69 | 70 | case 2: 71 | double overlayY = (double) slider.getValueInt() / 100; 72 | config.set(Config.Key.overlayY, overlayY >= 0 ? overlayY : -1); 73 | 74 | overlay.updatePosition(); 75 | 76 | if (overlayY < 0) setSliderTextDefault(slider); 77 | break; 78 | 79 | case 3: 80 | config.set(Config.Key.overlayScale, (double) slider.getValueInt() / 100); 81 | 82 | overlay.updateScale(); 83 | overlay.updatePosition(); 84 | break; 85 | } 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/alerts/alertmodes/customalertmode/CustomAlertMode.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.alerts.alertmodes.customalertmode; 2 | 3 | import com.google.gson.JsonElement; 4 | 5 | import namelessju.scathapro.ScathaPro; 6 | import namelessju.scathapro.alerts.Alert; 7 | import namelessju.scathapro.alerts.AlertTitle; 8 | import namelessju.scathapro.alerts.alertmodes.AlertMode; 9 | import namelessju.scathapro.util.JsonUtil; 10 | import namelessju.scathapro.util.TextUtil; 11 | import namelessju.scathapro.util.TimeUtil; 12 | import net.minecraft.util.ResourceLocation; 13 | import net.minecraft.util.StringUtils; 14 | 15 | public class CustomAlertMode extends AlertMode 16 | { 17 | public CustomAlertMode(String id, String name) 18 | { 19 | super(id, name, getDefaultIconEyePositions()); 20 | } 21 | 22 | @Override 23 | public String getIconPath() 24 | { 25 | return "overlay/scatha_icons/mode_custom.png"; 26 | } 27 | 28 | @Override 29 | public String getIconOverlayPath() 30 | { 31 | return "overlay/scatha_icons/mode_custom_overlay.png"; 32 | } 33 | 34 | @Override 35 | public int getIconColor() 36 | { 37 | final int hue = (int) ((TimeUtil.now() / 8) % 360); 38 | float h = hue / 60f; 39 | float x = 1 - Math.abs(h % 2 - 1); 40 | 41 | float r = 0; 42 | float g = 0; 43 | float b = 0; 44 | 45 | switch ((int) h) 46 | { 47 | case 0: 48 | r = 1f; 49 | g = x; 50 | break; 51 | case 1: 52 | r = x; 53 | g = 1f; 54 | break; 55 | case 2: 56 | g = 1f; 57 | b = x; 58 | break; 59 | case 3: 60 | g = x; 61 | b = 1f; 62 | break; 63 | case 4: 64 | r = x; 65 | b = 1f; 66 | break; 67 | case 5: 68 | r = 1f; 69 | b = x; 70 | break; 71 | } 72 | 73 | int color = (int) (r * 255f); 74 | color = (color << 8) + (int) (g * 255f); 75 | color = (color << 8) + (int) (b * 255f); 76 | return color; 77 | } 78 | 79 | @Override 80 | public ResourceLocation getSoundBaseResourceLocation() 81 | { 82 | return new ResourceLocation(CustomAlertModeManager.resourceDomain, ""); 83 | } 84 | 85 | @Override 86 | public float getSoundVolume(Alert alert) 87 | { 88 | Double volume = JsonUtil.getDouble(ScathaPro.getInstance().getCustomAlertModeManager().getCurrentSubmodePropertyJsonElement(null), "soundVolumes/" + alert.alertId); 89 | return volume != null ? volume.floatValue() : 1f; 90 | } 91 | 92 | @Override 93 | public AlertTitle getTitle(Alert alert) 94 | { 95 | JsonElement titlesJson = ScathaPro.getInstance().getCustomAlertModeManager().getCurrentSubmodePropertyJsonElement("titles"); 96 | if (titlesJson == null) return null; 97 | 98 | String title = JsonUtil.getString(titlesJson, alert.alertId + "/title"); 99 | if (title != null) 100 | { 101 | title = StringUtils.stripControlCodes(title).replaceAll("&(?=" + TextUtil.formattingCodesRegex + ")", TextUtil.formattingStartCharacter); 102 | } 103 | 104 | String subtitle = JsonUtil.getString(titlesJson, alert.alertId + "/subtitle"); 105 | if (subtitle != null) 106 | { 107 | subtitle = StringUtils.stripControlCodes(subtitle).replaceAll("&(?=" + TextUtil.formattingCodesRegex + ")", TextUtil.formattingStartCharacter); 108 | } 109 | 110 | return AlertTitle.createTextOnly(title, subtitle); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/alerts/AlertTitle.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.alerts; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import net.minecraft.util.EnumChatFormatting; 5 | 6 | public class AlertTitle 7 | { 8 | public String title; 9 | public boolean hasVariableSubtitle; 10 | public String subtitle; 11 | public final String titleFormatting; 12 | public final String subtitleFormatting; 13 | public final int fadeInTicks; 14 | public final int stayTicks; 15 | public final int fadeOutTicks; 16 | 17 | private AlertTitle(String title, boolean hasVariableSubtitle, String subtitle, String titleFormatting, String subtitleFormatting, int fadeInTicks, int stayTicks, int fadeOutTicks) 18 | { 19 | this.title = title; 20 | this.hasVariableSubtitle = hasVariableSubtitle; 21 | this.subtitle = subtitle; 22 | this.titleFormatting = titleFormatting; 23 | this.subtitleFormatting = subtitleFormatting; 24 | this.fadeInTicks = fadeInTicks; 25 | this.stayTicks = stayTicks; 26 | this.fadeOutTicks = fadeOutTicks; 27 | } 28 | 29 | public static AlertTitle createTextOnly(String title, String subtitle) 30 | { 31 | return new AlertTitle(title, false, subtitle, null, null, 0, 0, 0); 32 | } 33 | 34 | public static AlertTitle create(String title, String subtitle, String titleFormatting, String subtitleFormatting, int fadeInTicks, int stayTicks, int fadeOutTicks) 35 | { 36 | return new AlertTitle(title, false, subtitle, titleFormatting, subtitleFormatting, fadeInTicks, stayTicks, fadeOutTicks); 37 | } 38 | 39 | public static AlertTitle createWithVariableSubtitle(String title, String titleFormatting, int fadeInTicks, int stayTicks, int fadeOutTicks) 40 | { 41 | return new AlertTitle(title, true, null, titleFormatting, null, fadeInTicks, stayTicks, fadeOutTicks); 42 | } 43 | 44 | public void display() 45 | { 46 | if (fadeInTicks <= 0 && stayTicks <= 0 && fadeOutTicks <= 0) return; 47 | 48 | String displayTitle = ""; 49 | if (this.title != null) 50 | { 51 | String titleDefaultFormatting = EnumChatFormatting.RESET + stringOrEmpty(this.titleFormatting); 52 | displayTitle = titleDefaultFormatting + this.title.replace(EnumChatFormatting.RESET.toString(), titleDefaultFormatting); 53 | } 54 | 55 | String displaySubtitle = ""; 56 | if (this.subtitle != null) 57 | { 58 | String subtitleDefaultFormatting = EnumChatFormatting.RESET + stringOrEmpty(this.subtitleFormatting); 59 | displaySubtitle = subtitleDefaultFormatting + this.subtitle.replace(EnumChatFormatting.RESET.toString(), subtitleDefaultFormatting); 60 | } 61 | 62 | ScathaPro.getInstance().getAlertTitleOverlay().displayTitle(displayTitle, displaySubtitle, fadeInTicks, stayTicks, fadeOutTicks); 63 | } 64 | 65 | public AlertTitle replaceWith(AlertTitle other, String variableSubtitle) 66 | { 67 | String title = this.title; 68 | if (other != null && other.title != null && !other.title.trim().isEmpty()) 69 | { 70 | title = other.title; 71 | } 72 | 73 | String subtitle = this.subtitle; 74 | if (!hasVariableSubtitle && other != null && other.subtitle != null && !other.subtitle.trim().isEmpty()) 75 | { 76 | subtitle = other.subtitle; 77 | } 78 | else if (hasVariableSubtitle) 79 | { 80 | if (variableSubtitle != null) subtitle = variableSubtitle; 81 | else subtitle = null; 82 | } 83 | 84 | return new AlertTitle(title, hasVariableSubtitle, subtitle, titleFormatting, subtitleFormatting, fadeInTicks, stayTicks, fadeOutTicks); 85 | } 86 | 87 | 88 | private String stringOrEmpty(String string) 89 | { 90 | return string != null ? string : ""; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/achievements/AchievementManager.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.achievements; 2 | 3 | import java.util.HashMap; 4 | 5 | import namelessju.scathapro.ScathaPro; 6 | import namelessju.scathapro.events.AchievementUnlockedEvent; 7 | import namelessju.scathapro.managers.Config; 8 | import namelessju.scathapro.util.TimeUtil; 9 | import net.minecraftforge.common.MinecraftForge; 10 | 11 | public class AchievementManager 12 | { 13 | private final ScathaPro scathaPro; 14 | 15 | private HashMap unlockedAchievements = new HashMap(); 16 | 17 | public AchievementManager(ScathaPro scathaPro) 18 | { 19 | this.scathaPro = scathaPro; 20 | 21 | updateBonusTypeVisibility(); 22 | } 23 | 24 | public UnlockedAchievement unlockAchievement(Achievement achievement) 25 | { 26 | return unlockAchievement(achievement, -1); 27 | } 28 | 29 | public UnlockedAchievement unlockAchievement(Achievement achievement, int goalReachedCount) 30 | { 31 | UnlockedAchievement unlockedAchievement = getUnlockedAchievement(achievement); 32 | 33 | if (goalReachedCount == 0) return unlockedAchievement; 34 | 35 | if (unlockedAchievement == null) 36 | { 37 | unlockedAchievement = new UnlockedAchievement(achievement, TimeUtil.now()); 38 | unlockedAchievements.put(achievement.getID(), unlockedAchievement); 39 | } 40 | else 41 | { 42 | if (!achievement.isRepeatable) return unlockedAchievement; 43 | int repeatCount = unlockedAchievement.getRepeatCount(); 44 | if (goalReachedCount > 0) 45 | { 46 | int newRepeatCount = goalReachedCount - 1; 47 | if (newRepeatCount <= repeatCount) return unlockedAchievement; 48 | unlockedAchievement.setRepeatCount(newRepeatCount); 49 | } 50 | else unlockedAchievement.setRepeatCount(repeatCount + 1); 51 | } 52 | 53 | scathaPro.getPersistentData().saveAchievements(); 54 | MinecraftForge.EVENT_BUS.post(new AchievementUnlockedEvent(unlockedAchievement)); 55 | 56 | return unlockedAchievement; 57 | } 58 | 59 | public boolean revokeAchievement(Achievement achievement) 60 | { 61 | if (unlockedAchievements.remove(achievement.getID()) != null) 62 | { 63 | achievement.setProgress(0f); 64 | scathaPro.getPersistentData().saveAchievements(); 65 | return true; 66 | } 67 | return false; 68 | } 69 | 70 | public boolean isAchievementUnlocked(Achievement achievement) 71 | { 72 | return getUnlockedAchievement(achievement) != null; 73 | } 74 | 75 | public UnlockedAchievement getUnlockedAchievement(Achievement achievement) 76 | { 77 | return unlockedAchievements.get(achievement.getID()); 78 | } 79 | 80 | public void clearUnlockedAchievements() 81 | { 82 | unlockedAchievements.clear(); 83 | } 84 | 85 | public void addUnlockedAchievement(UnlockedAchievement unlockedAchievement) 86 | { 87 | unlockedAchievements.put(unlockedAchievement.achievement.getID(), unlockedAchievement); 88 | } 89 | 90 | public UnlockedAchievement[] getAllUnlockedAchievements() 91 | { 92 | String[] ids = unlockedAchievements.keySet().toArray(new String[0]); 93 | UnlockedAchievement[] achievements = new UnlockedAchievement[ids.length]; 94 | for (int i = 0; i < ids.length; i ++) 95 | { 96 | achievements[i] = unlockedAchievements.get(ids[i]); 97 | } 98 | return achievements; 99 | } 100 | 101 | public static Achievement[] getAllAchievements() 102 | { 103 | return Achievement.values(); 104 | } 105 | 106 | public void updateBonusTypeVisibility() 107 | { 108 | Achievement.Type.BONUS.visibilityOverride = scathaPro.getConfig().getBoolean(Config.Key.bonusAchievementsShown); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/menus/alerts/AlertTitleSettingsGui.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.menus.alerts; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.gui.elements.CycleButton; 5 | import namelessju.scathapro.gui.elements.ScathaProSlider; 6 | import namelessju.scathapro.gui.menus.ConfigGui; 7 | import namelessju.scathapro.managers.Config; 8 | import namelessju.scathapro.overlay.AlertTitleOverlay; 9 | import namelessju.scathapro.overlay.elements.OverlayElement; 10 | import net.minecraft.client.gui.GuiScreen; 11 | import net.minecraft.util.EnumChatFormatting; 12 | import net.minecraftforge.fml.client.config.GuiSlider; 13 | 14 | public class AlertTitleSettingsGui extends ConfigGui implements GuiSlider.ISlider 15 | { 16 | protected final AlertTitleOverlay alertTitleOverlay; 17 | 18 | public AlertTitleSettingsGui(ScathaPro scathaPro, GuiScreen parentGui) 19 | { 20 | super(scathaPro, parentGui); 21 | 22 | alertTitleOverlay = scathaPro.getAlertTitleOverlay(); 23 | } 24 | 25 | @Override 26 | public String getTitle() 27 | { 28 | return "Alert Title Position"; 29 | } 30 | 31 | @Override 32 | public void initGui() 33 | { 34 | super.initGui(); 35 | 36 | double titleX = config.getDouble(Config.Key.alertTitlePositionX); 37 | elements.add(new ScathaProSlider(1, width / 2 - 155, height - 45 - 24 - 6, 150, 20, "X Position: ", "%", 0, 100, titleX >= 0 ? titleX * 100 : -1, false, true, this)); 38 | 39 | double titleY = config.getDouble(Config.Key.alertTitlePositionY); 40 | elements.add(new ScathaProSlider(2, width / 2 + 5, height - 45 - 24 - 6, 150, 20, "Y Position: ", "%", 0, 100, titleY >= 0 ? titleY * 100 : -1, false, true, this)); 41 | 42 | elements.add(new ScathaProSlider(3, width / 2 - 155, height - 45 - 48 - 6, 310, 20, "Scale: ", "%", 25, 175, config.getDouble(Config.Key.alertTitleScale) * 100, false, true, this)); 43 | 44 | CycleButton alignmentButton = new CycleButton(4, width / 2 - 155, height - 45 - 72 - 6, 310, 20, "Alignment", CycleButton.EnumOption.from(OverlayElement.Alignment.class, true), config.getEnum(Config.Key.alertTitleAlignment, OverlayElement.Alignment.class), button -> { 45 | OverlayElement.Alignment value = button.getSelectedValue(); 46 | config.set(Config.Key.alertTitleAlignment, value != null ? value.name() : ""); 47 | 48 | scathaPro.getAlertTitleOverlay().updateContentAlignment(); 49 | }); 50 | alignmentButton.setNullOptionName("Automatic"); 51 | elements.add(alignmentButton); 52 | 53 | addDoneButton(width / 2 - 100, height - 45, 200, 20); 54 | } 55 | 56 | @Override 57 | public void onChangeSliderValue(GuiSlider slider) 58 | { 59 | if (!slider.enabled) return; 60 | switch (slider.id) 61 | { 62 | case 1: 63 | double x = (double) slider.getValueInt() / 100; 64 | config.set(Config.Key.alertTitlePositionX, x >= 0 ? x : -1); 65 | 66 | alertTitleOverlay.updatePosition(); 67 | break; 68 | 69 | case 2: 70 | double y = (double) slider.getValueInt() / 100; 71 | config.set(Config.Key.alertTitlePositionY, y >= 0 ? y : -1); 72 | 73 | alertTitleOverlay.updatePosition(); 74 | break; 75 | 76 | case 3: 77 | config.set(Config.Key.alertTitleScale, (double) slider.getValueInt() / 100); 78 | 79 | alertTitleOverlay.updateScale(); 80 | break; 81 | } 82 | } 83 | 84 | @Override 85 | public boolean hasBackground() 86 | { 87 | return false; 88 | } 89 | 90 | @Override 91 | protected void drawCustomBackground() 92 | { 93 | scathaPro.getAlertTitleOverlay().drawStatic(EnumChatFormatting.GREEN + "Example Title", EnumChatFormatting.GRAY + "This is what alerts will look like"); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/resources/assets/scathapro/sounds.json: -------------------------------------------------------------------------------- 1 | { 2 | "achievements.unlock": { 3 | "category": "player", 4 | "sounds": [{ 5 | "name": "scathapro:achievements/unlock", 6 | "stream": true 7 | }] 8 | }, 9 | "achievements.unlock_hidden": { 10 | "category": "player", 11 | "sounds": [{ 12 | "name": "scathapro:achievements/unlock_hidden", 13 | "stream": true 14 | }] 15 | }, 16 | 17 | 18 | "alert.anti_sleep": { 19 | "category": "player", 20 | "sounds": [{ 21 | "name": "scathapro:metal_pipe_falling", 22 | "stream": true 23 | }] 24 | }, 25 | 26 | "alert_modes.meme.bedrock_wall": { 27 | "category": "master", 28 | "sounds": [{ 29 | "name": "scathapro:alert_modes/meme/bedrock_wall", 30 | "stream": true 31 | }] 32 | }, 33 | "alert_modes.meme.worm_prespawn": { 34 | "category": "master", 35 | "sounds": [{ 36 | "name": "scathapro:alert_modes/meme/worm_prespawn", 37 | "stream": true 38 | }] 39 | }, 40 | "alert_modes.meme.regular_worm_spawn": { 41 | "category": "master", 42 | "sounds": [{ 43 | "name": "scathapro:alert_modes/meme/regular_worm_spawn", 44 | "stream": true 45 | }] 46 | }, 47 | "alert_modes.meme.scatha_spawn": { 48 | "category": "master", 49 | "sounds": [{ 50 | "name": "scathapro:alert_modes/meme/scatha_spawn", 51 | "stream": true 52 | }] 53 | }, 54 | "alert_modes.meme.worm_spawn_cooldown_end": { 55 | "category": "master", 56 | "sounds": [{ 57 | "name": "scathapro:alert_modes/meme/worm_spawn_cooldown_end", 58 | "stream": true 59 | }] 60 | }, 61 | "alert_modes.meme.scatha_pet_drop": { 62 | "category": "master", 63 | "sounds": [{ 64 | "name": "scathapro:alert_modes/meme/scatha_pet_drop", 65 | "stream": true 66 | }] 67 | }, 68 | "alert_modes.meme.high_heat": { 69 | "category": "master", 70 | "sounds": [{ 71 | "name": "scathapro:alert_modes/meme/high_heat", 72 | "stream": true 73 | }] 74 | }, 75 | "alert_modes.meme.goblin_spawn": { 76 | "category": "master", 77 | "sounds": [{ 78 | "name": "scathapro:alert_modes/meme/goblin_spawn", 79 | "stream": true 80 | }] 81 | }, 82 | "alert_modes.meme.jerry_spawn": { 83 | "category": "master", 84 | "sounds": [{ 85 | "name": "scathapro:alert_modes/meme/jerry_spawn", 86 | "stream": true 87 | }] 88 | }, 89 | 90 | "alert_modes.anime.bedrock_wall": { 91 | "category": "master", 92 | "sounds": [{ 93 | "name": "scathapro:alert_modes/anime/bedrock_wall", 94 | "stream": true 95 | }] 96 | }, 97 | "alert_modes.anime.worm_prespawn": { 98 | "category": "master", 99 | "sounds": [{ 100 | "name": "scathapro:alert_modes/anime/worm_prespawn", 101 | "stream": true 102 | }] 103 | }, 104 | "alert_modes.anime.regular_worm_spawn": { 105 | "category": "master", 106 | "sounds": [{ 107 | "name": "scathapro:alert_modes/anime/regular_worm_spawn", 108 | "stream": true 109 | }] 110 | }, 111 | "alert_modes.anime.scatha_spawn": { 112 | "category": "master", 113 | "sounds": [{ 114 | "name": "scathapro:alert_modes/anime/scatha_spawn", 115 | "stream": true 116 | }] 117 | }, 118 | "alert_modes.anime.scatha_pet_drop": { 119 | "category": "master", 120 | "sounds": [{ 121 | "name": "scathapro:alert_modes/anime/scatha_pet_drop", 122 | "stream": true 123 | }] 124 | }, 125 | 126 | "scappa": { 127 | "category": "master", 128 | "sounds": [{ 129 | "name": "scathapro:scappa", 130 | "stream": true 131 | }] 132 | } 133 | } -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/gui/elements/DeleteCustomAlertModeButton.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.gui.elements; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.alerts.alertmodes.customalertmode.CustomAlertModeManager; 5 | import namelessju.scathapro.util.Util; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.client.gui.FontRenderer; 8 | import net.minecraft.client.gui.GuiScreen; 9 | import net.minecraft.client.gui.GuiYesNo; 10 | import net.minecraft.client.gui.GuiYesNoCallback; 11 | import net.minecraft.client.renderer.GlStateManager; 12 | import net.minecraft.util.EnumChatFormatting; 13 | 14 | public class DeleteCustomAlertModeButton extends ScathaProButton implements IClickActionButton, GuiYesNoCallback { 15 | 16 | private final CustomAlertModeManager customAlertModeManager; 17 | 18 | private final String customModeId; 19 | private final GuiScreen returnGui; 20 | 21 | public DeleteCustomAlertModeButton(int buttonId, int x, int y, int widthIn, int heightIn, String buttonText, String customModeId, GuiScreen returnGui) 22 | { 23 | super(buttonId, x, y, widthIn, heightIn, buttonText); 24 | 25 | this.customModeId = customModeId; 26 | this.returnGui = returnGui; 27 | 28 | this.customAlertModeManager = ScathaPro.getInstance().getCustomAlertModeManager(); 29 | } 30 | 31 | @Override 32 | public void click() 33 | { 34 | String customModeName = customAlertModeManager.getSubmodeDisplayName(customModeId); 35 | GuiYesNo confirmGui = new GuiYesNo(this, EnumChatFormatting.RESET + "Do you really want to delete \"" + customModeName + EnumChatFormatting.RESET + "\"?", "This cannot be undone!", 0); 36 | Minecraft.getMinecraft().displayGuiScreen(confirmGui); 37 | } 38 | 39 | @Override 40 | public void confirmClicked(boolean result, int sourceButtonId) 41 | { 42 | boolean wasActiveBefore = customAlertModeManager.isSubmodeActive(customModeId); 43 | if (wasActiveBefore) Minecraft.getMinecraft().currentScreen = returnGui; // loading screen returns to current screen after completion 44 | if (result) customAlertModeManager.deleteSubmode(customModeId); 45 | if (!wasActiveBefore) Minecraft.getMinecraft().displayGuiScreen(returnGui); 46 | } 47 | 48 | @Override 49 | public void drawButton(Minecraft mc, int mouseX, int mouseY) 50 | { 51 | if (this.visible) 52 | { 53 | this.hovered = mouseX >= this.xPosition && mouseY >= this.yPosition && mouseX < this.xPosition + this.width && mouseY < this.yPosition + this.height; 54 | int hoverState = this.getHoverState(this.hovered); 55 | 56 | FontRenderer fontrenderer = mc.fontRendererObj; 57 | 58 | mc.getTextureManager().bindTexture(buttonTextures); 59 | 60 | GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); 61 | GlStateManager.enableBlend(); 62 | GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); 63 | GlStateManager.blendFunc(770, 771); 64 | 65 | this.drawTexturedModalRect(this.xPosition, this.yPosition, 0, 46 + hoverState * 20, this.width / 2, this.height); 66 | this.drawTexturedModalRect(this.xPosition + this.width / 2, this.yPosition, 200 - this.width / 2, 46 + hoverState * 20, this.width / 2, this.height); 67 | 68 | this.mouseDragged(mc, mouseX, mouseY); 69 | 70 | int color = 14737632; 71 | if (packedFGColour != 0) 72 | { 73 | color = packedFGColour; 74 | } 75 | else if (!this.enabled) 76 | { 77 | color = 10526880; 78 | } 79 | else if (this.hovered) 80 | { 81 | color = Util.Color.RED; 82 | } 83 | 84 | this.drawCenteredString(fontrenderer, this.displayString, this.xPosition + this.width / 2, this.yPosition + (this.height - 8) / 2, color); 85 | 86 | if (this.hovered) this.getTooltip().requestRender(); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/util/TimeUtil.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.util; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.time.LocalDate; 5 | import java.time.format.DateTimeFormatter; 6 | import java.util.Calendar; 7 | import java.util.Date; 8 | 9 | import net.minecraft.client.Minecraft; 10 | 11 | public class TimeUtil 12 | { 13 | public static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("uuuu-MM-dd"); 14 | 15 | public static final boolean isAprilFools = isDate(04, 01); 16 | 17 | /** 18 | * Returns the current time in milliseconds since midnight, January 1, 1970 UTC 19 | */ 20 | public static long now() 21 | { 22 | return System.currentTimeMillis(); 23 | } 24 | 25 | /** 26 | * Returns a timestamp in milliseconds that can be used for animations 27 | */ 28 | public static long getAnimationTime() 29 | { 30 | return Minecraft.getSystemTime(); 31 | } 32 | 33 | public static boolean getAnimationState(int trueDurationMs, int falseDurationMs) 34 | { 35 | return getAnimationTime() % (trueDurationMs + falseDurationMs) < trueDurationMs; 36 | } 37 | 38 | /** 39 | * Formats a timestamp the same way vanilla Minecraft does it 40 | * @param timestamp The Unix timestamp in milliseconds to format 41 | */ 42 | public static String formatUnixDateTime(long timestamp) 43 | { 44 | return new SimpleDateFormat().format(new Date(timestamp)); 45 | } 46 | 47 | public static String serializeDate(LocalDate date) 48 | { 49 | return date.format(dateFormat); 50 | } 51 | 52 | public static LocalDate today() 53 | { 54 | return LocalDate.now(); 55 | } 56 | 57 | public static short getCurrentYear() 58 | { 59 | return (short) today().getYear(); 60 | } 61 | 62 | public static LocalDate parseDate(String dateString) 63 | { 64 | try 65 | { 66 | return LocalDate.parse(dateString, dateFormat); 67 | } 68 | catch (Exception e) 69 | { 70 | return null; 71 | } 72 | } 73 | 74 | /** 75 | * Ensures the number string is at least two digits long by adding a leading zero if required 76 | * @param number The number to format 77 | */ 78 | public static String padZero(int number) 79 | { 80 | return String.format("%02d", number); 81 | } 82 | 83 | /** 84 | * Generates a time string of seconds, minutes and hours, showing only the applicable fields
85 | * E.g.: 1h 2m 3s 86 | * @param countDown When set to true rounds the seconds up instead of down 87 | */ 88 | public static String getHMSTimeString(long milliseconds, boolean countDown) 89 | { 90 | int seconds; 91 | { 92 | double secondsD = milliseconds / 1000D; 93 | seconds = (int) (countDown ? Math.ceil(secondsD) : secondsD); 94 | } 95 | int minutes = 0; 96 | if (seconds >= 60) 97 | { 98 | minutes = seconds / 60; 99 | seconds %= 60; 100 | } 101 | int hours = 0; 102 | if (minutes >= 60) 103 | { 104 | hours = minutes / 60; 105 | minutes %= 60; 106 | } 107 | return (hours >= 1 ? hours + "h " : "") + (minutes >= 1 ? minutes + "m " : "") + seconds + "s"; 108 | } 109 | 110 | public static final boolean isDate(int month, int day) 111 | { 112 | return isDateBetween(month, day, month, day); 113 | } 114 | 115 | /** 116 | * Both from and to dates are inclusive 117 | */ 118 | public static final boolean isDateBetween(int monthFrom, int dayFrom, int monthTo, int dayTo) 119 | { 120 | Calendar calendar = Calendar.getInstance(); 121 | int month = calendar.get(2) + 1; 122 | int day = calendar.get(5); 123 | return ( 124 | ((monthFrom == month && dayFrom <= day) || monthFrom < month) 125 | && 126 | ((month == monthTo && day <= dayTo) || month < monthTo) 127 | ); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/parsing/chestguiparsing/ProfileStatsParser.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.parsing.chestguiparsing; 2 | 3 | import namelessju.scathapro.ScathaPro; 4 | import namelessju.scathapro.util.NBTUtil; 5 | import namelessju.scathapro.util.TextUtil; 6 | import namelessju.scathapro.util.UnicodeSymbol; 7 | import net.minecraft.item.ItemStack; 8 | import net.minecraft.nbt.NBTTagList; 9 | import net.minecraft.util.EnumChatFormatting; 10 | import net.minecraft.util.StringUtils; 11 | 12 | public class ProfileStatsParser extends ChestGuiParser 13 | { 14 | public ProfileStatsParser() 15 | { 16 | this.enabled = false; 17 | } 18 | 19 | @Override 20 | public String getGuiName() 21 | { 22 | return "SkyBlock Menu"; 23 | } 24 | 25 | @Override 26 | public int[] getSlotNumbers() 27 | { 28 | return new int[] {13}; 29 | } 30 | 31 | @Override 32 | public void tryParse(ItemStack itemStack, int slotNumber, ScathaPro scathaPro) 33 | { 34 | NBTTagList lore = NBTUtil.getLore(itemStack); 35 | if (lore == null) return; 36 | 37 | boolean magicFindFound = false; 38 | boolean petLuckFound = false; 39 | 40 | for (int i = 3; i < lore.tagCount() && (!magicFindFound || !petLuckFound); i ++) 41 | { 42 | String loreLine = StringUtils.stripControlCodes(lore.getStringTagAt(i)); 43 | 44 | // " # Magic Find 123" 45 | if (loreLine.length() >= 15 && loreLine.substring(3, 13).equals("Magic Find")) 46 | { 47 | magicFindFound = true; 48 | 49 | loreLine = loreLine.substring(14).replace(",", ""); 50 | float magicFind; 51 | try 52 | { 53 | magicFind = Float.parseFloat(loreLine); 54 | } 55 | catch (NumberFormatException e) 56 | { 57 | scathaPro.logError("Profile Stats Parser: Found Magic Find entry but failed to parse number! (\"" + loreLine + "\")"); 58 | continue; 59 | } 60 | 61 | if (magicFind != scathaPro.variables.magicFind) 62 | { 63 | TextUtil.sendModChatMessage(EnumChatFormatting.GRAY + "Updated Magic Find (" + TextUtil.getObfNrStr(scathaPro.variables.magicFind) + " " + UnicodeSymbol.heavyArrowRight + " " + TextUtil.numberToString(magicFind, 2) + ")"); 64 | scathaPro.variables.magicFind = magicFind; 65 | scathaPro.getPersistentData().saveProfileStats(); 66 | scathaPro.getOverlay().updateProfileStats(); 67 | } 68 | } 69 | 70 | // " # Pet Luck 123" 71 | else if (loreLine.length() >= 13 && loreLine.substring(3, 11).equals("Pet Luck")) 72 | { 73 | petLuckFound = true; 74 | 75 | loreLine = loreLine.substring(12).replace(",", ""); 76 | float petLuck; 77 | try 78 | { 79 | petLuck = Float.parseFloat(loreLine); 80 | } 81 | catch (NumberFormatException e) 82 | { 83 | scathaPro.logError("Profile Stats Parser: Found Pet Luck entry but failed to parse number! (\"" + loreLine + "\")"); 84 | continue; 85 | } 86 | 87 | if (petLuck != scathaPro.variables.petLuck) 88 | { 89 | TextUtil.sendModChatMessage(EnumChatFormatting.GRAY + "Updated Pet Luck (" + TextUtil.getObfNrStr(scathaPro.variables.petLuck) + " " + UnicodeSymbol.heavyArrowRight + " " + TextUtil.numberToString(petLuck, 2) + ")"); 90 | scathaPro.variables.petLuck = petLuck; 91 | scathaPro.getPersistentData().saveProfileStats(); 92 | scathaPro.getOverlay().updateProfileStats(); 93 | } 94 | } 95 | } 96 | } 97 | 98 | @Override 99 | public void onFinishParsing() 100 | { 101 | this.enabled = false; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/managers/FFmpegWrapper.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.managers; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.File; 5 | import java.io.IOException; 6 | import java.io.InputStreamReader; 7 | import java.util.Arrays; 8 | import java.util.concurrent.CompletableFuture; 9 | import java.util.function.Consumer; 10 | import java.util.stream.Stream; 11 | 12 | import namelessju.scathapro.ScathaPro; 13 | import net.minecraftforge.fml.common.Loader; 14 | 15 | public class FFmpegWrapper 16 | { 17 | private static String executablePath = null; 18 | private static boolean isWindows = false; 19 | 20 | static 21 | { 22 | isWindows = System.getProperty("os.name").startsWith("Windows"); 23 | executablePath = searchForExecutablePath(); 24 | } 25 | 26 | public static void convertToOgg(String sourcePath, String targetPath, Consumer consumer) 27 | { 28 | runWithArgs(new String[] {"-y", "-i", sourcePath, "-map_metadata", "-1", "-map", "0:a", "-c:a", "libvorbis", targetPath}, consumer); 29 | } 30 | 31 | public static void runWithArgs(String[] arguments, Consumer consumer) 32 | { 33 | CompletableFuture.supplyAsync(() -> execute(arguments)).thenAccept(consumer); 34 | } 35 | 36 | private static boolean execute(String... arguments) 37 | { 38 | if (executablePath == null) 39 | { 40 | ScathaPro.getInstance().logError("Couldn't execute FFmpeg: No installation found"); 41 | return false; 42 | } 43 | 44 | try 45 | { 46 | String[] commandArray = Stream.concat(Stream.of(executablePath), Arrays.stream(arguments)).toArray(String[]::new); 47 | ScathaPro.getInstance().logDebug("Executing FFmpeg command: " + String.join(" ", commandArray)); 48 | Process process = Runtime.getRuntime().exec(commandArray); 49 | 50 | StringBuilder errorMessageBuilder = new StringBuilder(); 51 | try (BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) 52 | { 53 | for (String line; (line = errorReader.readLine()) != null;) 54 | { 55 | if (errorMessageBuilder.length() > 0) errorMessageBuilder.append("\n"); 56 | errorMessageBuilder.append(line); 57 | } 58 | } 59 | if (process.waitFor() == 0) return true; 60 | 61 | ScathaPro.getInstance().logError(errorMessageBuilder.toString()); 62 | return false; 63 | } 64 | catch (IOException | InterruptedException e) 65 | { 66 | e.printStackTrace(); 67 | return false; 68 | } 69 | } 70 | 71 | public static boolean isFFmpegInstalled() 72 | { 73 | return executablePath != null; 74 | } 75 | 76 | private static String searchForExecutablePath() 77 | { 78 | File ffmpegFile; 79 | 80 | // exe in mod folder 81 | File minecraftDir = Loader.instance().getConfigDir().getParentFile(); 82 | File modFolder = new File(minecraftDir, "mods"); 83 | ffmpegFile = new File(modFolder, getOsSpecificExecutableFilename("scathapro-ffmpeg")); 84 | if (ffmpegFile.exists()) 85 | { 86 | String filePath = ffmpegFile.getAbsolutePath(); 87 | ScathaPro.getInstance().log("FFmpeg installation found in mods folder (" + filePath + ")"); 88 | return filePath; 89 | } 90 | 91 | // path variable 92 | String envPaths = System.getenv("PATH"); 93 | for (String path : envPaths.split(";")) 94 | { 95 | if (path.isEmpty()) continue; 96 | ffmpegFile = new File(path, getOsSpecificExecutableFilename("ffmpeg")); 97 | if (ffmpegFile.exists()) 98 | { 99 | String filePath = ffmpegFile.getAbsolutePath(); 100 | ScathaPro.getInstance().log("FFmpeg installation found in PATH environment variable (" + filePath + ")"); 101 | return filePath; 102 | } 103 | } 104 | 105 | ScathaPro.getInstance().logWarning("No FFmpeg installation found, custom mode will not support audio file conversions!"); 106 | return null; 107 | } 108 | 109 | private static String getOsSpecificExecutableFilename(String fileName) 110 | { 111 | return isWindows ? fileName + ".exe" : fileName; 112 | } 113 | } 114 | 115 | -------------------------------------------------------------------------------- /src/main/java/namelessju/scathapro/parsing/ScoreboardParser.java: -------------------------------------------------------------------------------- 1 | package namelessju.scathapro.parsing; 2 | 3 | import java.util.Collection; 4 | import java.util.function.Predicate; 5 | 6 | import namelessju.scathapro.ScathaPro; 7 | import net.minecraft.scoreboard.Score; 8 | import net.minecraft.scoreboard.ScoreObjective; 9 | import net.minecraft.scoreboard.ScorePlayerTeam; 10 | import net.minecraft.scoreboard.Scoreboard; 11 | import net.minecraft.util.StringUtils; 12 | 13 | public class ScoreboardParser 14 | { 15 | private static ScathaPro scathaPro = ScathaPro.getInstance(); 16 | 17 | public static int parseHeat() 18 | { 19 | // scathaPro.logDebug("Parsing scoreboard heat value..."); 20 | 21 | ParsedValue heat = new ParsedValue(); 22 | 23 | parse(new Predicate() { 24 | @Override 25 | public boolean test(String text) 26 | { 27 | if (text.startsWith("Heat:")) 28 | { 29 | String valueString = text.substring(5).trim(); 30 | 31 | // remove non-number characters from left 32 | while (valueString.length() > 0) 33 | { 34 | char firstChar = valueString.charAt(0); 35 | if (firstChar >= '0' && firstChar <= '9') break; 36 | if (valueString.startsWith("IMMUNE")) 37 | { 38 | valueString = null; 39 | break; 40 | } 41 | valueString = valueString.substring(1).trim(); 42 | } 43 | 44 | // remove non-digit characters from right 45 | while (valueString != null && valueString.length() > 0) 46 | { 47 | char lastChar = valueString.charAt(valueString.length() - 1); 48 | if (lastChar >= '0' && lastChar <= '9') break; 49 | valueString = valueString.substring(0, valueString.length() - 1).trim(); 50 | } 51 | 52 | if (valueString != null && !valueString.isEmpty()) 53 | { 54 | try 55 | { 56 | heat.setValue(Integer.parseInt(valueString)); 57 | // scathaPro.logDebug("Scoreboard heat entry found - value: " + heat); 58 | } 59 | catch (NumberFormatException exception) 60 | { 61 | scathaPro.logDebug("Error while parsing scoreboard heat value: \"" + text + "\" couldn't be parsed to an int"); 62 | } 63 | } 64 | else 65 | { 66 | // scathaPro.logDebug("Scoreboard heat entry found, but has no int value: \"" + text + "\""); 67 | } 68 | 69 | return true; 70 | } 71 | 72 | return false; 73 | } 74 | }); 75 | 76 | return heat.getValue(-1); 77 | } 78 | 79 | private static void parse(Predicate scorePredicate) 80 | { 81 | // scathaPro.logDebug("Parsing scoreboard..."); 82 | 83 | Scoreboard scoreboard = scathaPro.getMinecraft().theWorld.getScoreboard(); 84 | 85 | ScoreObjective sidebarObjective = scoreboard.getObjectiveInDisplaySlot(1); 86 | if (sidebarObjective != null) 87 | { 88 | // scathaPro.logDebug("Scoreboard objective found in sidebar: \"" + sidebarObjective.getDisplayName() + "\""); 89 | 90 | Collection scores = scoreboard.getSortedScores(sidebarObjective); 91 | for (Score score : scores) 92 | { 93 | String playerName = score.getPlayerName(); 94 | ScorePlayerTeam playerTeam = scoreboard.getPlayersTeam(playerName); 95 | String formattedScoreText = ScorePlayerTeam.formatPlayerName(playerTeam, playerName); 96 | String unformattedText = StringUtils.stripControlCodes(formattedScoreText.replace(playerName, "")); 97 | 98 | // scathaPro.logDebug("Scoreboard line: \"" + unformattedText + "\""); 99 | 100 | if (scorePredicate.test(unformattedText)) return; 101 | } 102 | } 103 | // else scathaPro.logDebug("No scoreboard objective in sidebar found"); 104 | } 105 | 106 | 107 | private ScoreboardParser() {} 108 | } 109 | --------------------------------------------------------------------------------