Compare commits

...

23 Commits

Author SHA1 Message Date
1eb2e5ee6c No idea what this is 2025-04-22 00:15:58 -06:00
b6c4223da5 Update build 2025-04-22 00:15:04 -06:00
e10f66a0c0 Try to get things working 2025-04-22 00:12:59 -06:00
c3f5be60ed chore: add changelog gen settings 2025-04-09 13:25:14 -06:00
3373405b9c feat: add base for farmer feature 2025-04-09 13:24:43 -06:00
13e816401b chore: cleanup old settings from template 2025-04-09 13:24:11 -06:00
82c40c3047 build: auto increment jar build names 2025-04-09 13:23:41 -06:00
91d881392e Delete .kotlin/errors/errors-1721778737330.log 2024-08-23 07:34:52 -06:00
illyum
89dcc87487 docs: add CONTRIBUTING.md and developer notice 2024-08-23 07:34:18 -06:00
illyum
3ed286c0f9 (Chore): Version Bump to 1.4.4 2024-08-23 06:47:30 -06:00
illyum
ebfbd6fc74 (BugFix): Fix powder chest being registered while in opening animation 2024-08-23 06:47:05 -06:00
illyum
9749a3199a (BugFix): Recheck chest locations to remove ghost chest highlights 2024-08-22 13:13:08 -06:00
illyum
fab0790e58 (Chore): Bump version to 1.4.3 2024-08-22 12:54:24 -06:00
illyum
98eb315142 (BugFix): Fixes powder chest click not being detected correctly 2024-08-22 12:53:56 -06:00
illyum
ed04c31578 (Chore): Bump version 2024-08-19 19:06:19 -06:00
illyum
7aff986e3c (Chore): Update readme to explain config and commands 2024-08-19 19:05:49 -06:00
illyum
043aab18dd Merge #1 2024-08-19 19:03:32 -06:00
illyum
1db0e3b7a4 (Chore): Fix conflict? 2024-08-19 19:02:12 -06:00
illyum
5970d2d427 (FEAT): Add configuration and commands to gemstone finder and powder chestESP 2024-08-19 18:59:52 -06:00
illyum
3b8d715efb so try to group hitboxes but I'm doing something wront. this doesn't work 2024-08-12 16:36:50 -06:00
illyum
d7a5a2913e Make the gem finder mesh all hitboxes into 1 big hitbox 2024-08-12 16:24:47 -06:00
illyum
fbaab2536f ChestESP, Route Builder, Chatterbox, Gemstone Finder, Grotto Finder 2024-08-12 16:21:07 -06:00
illyum
6d9b943e2c Stashing Commit 2024-08-09 03:02:15 -06:00
34 changed files with 2212 additions and 519 deletions

10
CHANGELOG.md Normal file
View File

@ -0,0 +1,10 @@
## [1.4.0] - 2024-07-23
### Chore
- Remove comments
### Feat
- *(chestesp)* Add initial implementation, halfway done

View File

@ -1,3 +1,16 @@
# SkyBlockTweaks
My QOL mod for Hypixel Skyblock
## Includes:
- Grotto Finder
- Gemstone Finder
- Powder ChestESP
- Route Builder
## Config
You can configure the gemstone search radius, and also toggle the powder chest esp
## Commands:
- /sbt gemstonesearchradius <number>
- /sbt powderchest [disable/enable]

View File

@ -1,4 +1,5 @@
import org.apache.commons.lang3.SystemUtils
import java.util.Properties
plugins {
idea
@ -9,25 +10,24 @@ plugins {
kotlin("jvm") version "2.0.0"
}
//Constants:
val baseGroup: String by project
val mcVersion: String by project
val version: String by project
val mixinGroup = "$baseGroup.mixin"
val versionBase: String by project
val buildNumber: String by project
val modid: String by project
val mixinGroup = "$baseGroup.mixin"
group = baseGroup
version = "$versionBase-b$buildNumber"
// Toolchains:
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(8))
}
// Minecraft configuration:
loom {
log4jConfigs.from(file("log4j2.xml"))
launchConfigs {
"client" {
// If you don't want mixins, remove these lines
property("mixin.debug", "true")
arg("--tweakClass", "org.spongepowered.asm.launch.MixinTweaker")
}
@ -35,7 +35,6 @@ loom {
runConfigs {
"client" {
if (SystemUtils.IS_OS_MAC_OSX) {
// This argument causes a crash on macOS
vmArgs.remove("-XstartOnFirstThread")
}
}
@ -43,10 +42,8 @@ loom {
}
forge {
pack200Provider.set(dev.architectury.pack200.java.Pack200Adapter())
// If you don't want mixins, remove this lines
mixinConfig("mixins.$modid.json")
}
// If you don't want mixins, remove these lines
mixin {
defaultRefmapName.set("mixins.$modid.refmap.json")
}
@ -62,12 +59,9 @@ sourceSets.main {
kotlin.destinationDirectory.set(java.destinationDirectory)
}
// Dependencies:
repositories {
mavenCentral()
maven("https://repo.spongepowered.org/maven/")
// If you don't want to log in with your real minecraft account, remove this line
maven("https://pkgs.dev.azure.com/djtheredstoner/DevAuth/_packaging/public/maven/v1")
}
@ -82,30 +76,24 @@ dependencies {
shadowImpl(kotlin("stdlib-jdk8"))
// If you don't want mixins, remove these lines
shadowImpl("org.spongepowered:mixin:0.7.11-SNAPSHOT") {
isTransitive = false
}
annotationProcessor("org.spongepowered:mixin:0.8.5-SNAPSHOT")
// If you don't want to log in with your real minecraft account, remove this line
runtimeOnly("me.djtheredstoner:DevAuth-forge-legacy:1.2.1")
}
// Tasks:
tasks.withType(JavaCompile::class) {
options.encoding = "UTF-8"
}
tasks.withType(org.gradle.jvm.tasks.Jar::class) {
archiveBaseName.set(modid)
archiveVersion.set("$version")
manifest.attributes.run {
this["FMLCorePluginContainsFMLMod"] = "true"
this["ForceLoadAsMod"] = "true"
// If you don't want mixins, remove these lines
this["TweakClass"] = "org.spongepowered.asm.launch.MixinTweaker"
this["MixinConfigs"] = "mixins.$modid.json"
}
@ -124,7 +112,6 @@ tasks.processResources {
rename("(.+_at.cfg)", "META-INF/$1")
}
val remapJar by tasks.named<net.fabricmc.loom.task.RemapJarTask>("remapJar") {
archiveClassifier.set("")
from(tasks.shadowJar)
@ -145,10 +132,50 @@ tasks.shadowJar {
println("Copying dependencies into mod: ${it.files}")
}
}
// If you want to include other dependencies and shadow them, you can relocate them in here
fun relocate(name: String) = relocate(name, "$baseGroup.deps.$name")
}
tasks.assemble.get().dependsOn(tasks.remapJar)
tasks.assemble {
dependsOn(tasks.remapJar)
dependsOn("incrementBuildNumber")
}
tasks.register<Copy>("illyExtractMappings") {
from("O:/.gradle")
into("${layout.buildDirectory}/mcp_mappings")
}
tasks.register("illyApplyMappings") {
dependsOn("illyExtractMappings")
doLast {
val mappingsDir = file("O:/Kotlin Programming/sbt/build/mcp_mappings")
if (mappingsDir.exists()) {
project.ext.set("mappingsPath", mappingsDir.absolutePath)
} else {
throw GradleException("Mappings directory not found!")
}
}
}
tasks.withType<JavaCompile> {
dependsOn("illyApplyMappings")
doLast {
options.compilerArgs.add("-Amap=O:/Kotlin Programming/sbt/build/mcp_mappings")
}
}
// 🔁 Auto-increment build number each assemble
tasks.register("incrementBuildNumber") {
doLast {
val propsFile = file("gradle.properties")
val props = Properties()
props.load(propsFile.inputStream())
val current = props.getProperty("buildNumber")?.toIntOrNull() ?: 1
val next = current + 1
props.setProperty("buildNumber", next.toString())
props.store(propsFile.outputStream(), null)
println("🔢 Build number incremented to $next")
}
}

36
cliff.toml Normal file
View File

@ -0,0 +1,36 @@
# cliff.toml
[changelog]
title = "Changelog"
description = "All notable changes to this project will be documented in this file."
repository_url = "http://localhost:3001/illyum/sbt-stash"
template = """
# {{version}} - {{date}}
{% for group, commits in commits | group_by(attribute="group") %}
### {{group | upper_first}}
{% for commit in commits %}
- {{ commit.message | upper_first }} ({% if commit.breaking %}! {% endif %}{{ commit.hash }})
{% endfor %}
{% endfor %}
"""
[git]
commit_parsers = [
{ message = "^\\(Chore\\)", group = "Chore" },
{ message = "^\\(BugFix\\)", group = "Bug Fixes" },
{ message = "^\\(Feat\\)", group = "Features" },
{ message = "^\\(Docs\\)", group = "Documentation" },
{ message = "^\\(Refactor\\)", group = "Refactor" },
{ message = "^\\(Test\\)", group = "Tests" },
{ message = "^\\(Style\\)", group = "Styling" },
{ message = "^\\(Perf\\)", group = "Performance" },
]
[git.tag]
pattern = "^v[0-9]+"
[git.commit]
conventional = false
[git.filters]
exclude_merge_commits = true

33
docs/CONTRIBUTING.md Normal file
View File

@ -0,0 +1,33 @@
# Contributing to This Project
Thank you for your interest in contributing to this project! Please read the following guidelines to understand how you can contribute.
## Private Repository
This is a **private repository**. While you're welcome to file issues and suggest ideas, please note that this project is primarily a personal endeavor. Contributions from the community are appreciated, but they might not always be incorporated.
## Filing Issues
If you encounter any issues or have suggestions for improvements, feel free to [open an issue](https://github.com/your-repo/issues) (or email me). Please be as detailed as possible when describing the problem or idea. I appreciate your input!
## Contributing Fixes
If you have a fix that you'd like to contribute:
- Please do **not** submit a pull request directly.
- Instead, email the developer at [developer@itzilly.com](mailto:developer@itzilly.com) with details about your fix.
- If the fix aligns with the project's goals and standards, you'll receive guidance on how to proceed.
## Suggesting Ideas
I welcome ideas and suggestions! However, please keep in mind:
- This project is more of a personal project, so while all ideas are welcome, not every suggestion will be implemented.
- Feel free to suggest ideas by [opening an issue](https://github.com/404) and detailing your thoughts.
## Code of Conduct
Please remember to be respectful and constructive when engaging with this project. At the end of the day, this is just my project.
Thank you for your understanding and for contributing to this project!
# Note for persons with a Gitea account
If you have access to an account with elevated permissions on this repo, you're welcome to commit code/make pull requests.

55
docs/DEVELOPER_NOTICE.md Normal file
View File

@ -0,0 +1,55 @@
# Developer Notice
Welcome to my project! This is primarily a personal project, and while I'm happy to have others take an interest, it's important to follow the guidelines below to ensure consistency and maintainability. (This is mostly for my reference)
## Conventional Commits
I use [Conventional Commits](https://www.conventionalcommits.org/) for all commit messages. This means that every commit should follow this format:
```
<type>(<scope>): <description>
```
- **Type:** The type of change you're committing. Common types include `feat` (new feature), `fix` (bug fix), `docs` (documentation only changes), `style` (code style, formatting, etc.), `refactor` (refactoring code), `test` (adding or updating tests), and `chore` (other changes that don't modify src or test files).
- **Scope:** An optional field that describes the part of the codebase the change affects (e.g., `api`, `config`, `ui`).
- **Description:** A brief description of the change.
Example commit message:
```
feat(api): add new endpoint for user data
```
```
chore(release): bump version to 1.4.3
```
```
style(ui): clean up redundant CSS classes in header component
```
```
fix(auth): resolve login redirect loop issue
```
```
merge(pr-45): integrate feature-x from pull request #45
```
## Branching Strategy
Branches are primarily for adding new features. However, while the project is in pre-release, it's okay to work on minor features directly on the `main` branch. Just make sure you:
- Commit all changes for the feature at once.
- Avoid having partial changes spread across multiple commits. Each commit should represent a complete and functional piece of work.
## Versioning
The versioning scheme I use is simple:
- **Patch version:** Bumped when small, incremental changes or bug fixes are made. For example, `x.x.y` to `x.x.y + 1`.
- **Minor version:** Typically, if a feature is added or updated, the version may stay the same until the project exits pre-release. Version `2.x.x` will be used if the project ever gets out of pre-release.
- **Major version:** Reserved for significant changes, like command updates, configuration overhauls, or substantial new features.
Remember, this is my project, so while I'm open to contributions and suggestions, I maintain the final say on what gets merged or included. Thanks for your understanding and contributions!

View File

@ -1,6 +1,8 @@
#Sat Apr 19 14:54:37 MDT 2025
versionBase=1.5.0
loom.platform=forge
baseGroup=com.github.itzilly.sbt
mcVersion=1.8.9
org.gradle.jvmargs=-Xmx2g
baseGroup = com.github.itzilly.sbt
mcVersion = 1.8.9
modid = sbt
version = 1.0.0
buildNumber=107
modid=sbt

View File

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

View File

@ -1,24 +0,0 @@
package com.github.itzilly.sbt
import net.minecraft.client.renderer.GlStateManager
import java.util.*
class HudText(var textLines: Array<String>, var x: Int, var y: Int, var shadow: Boolean) : RenderHudAble {
var scale = 1f
val id = UUID.randomUUID()
override fun render(partialTicks: Float) {
GlStateManager.pushMatrix()
GlStateManager.translate(x.toFloat(), y.toFloat(), 0f)
GlStateManager.scale(scale, scale, scale)
var yOff = 0
for (line in textLines) {
if (shadow) {
SkyBlockTweaks.INSTANCE.fontRenderer.drawStringWithShadow(line, 0f, yOff.toFloat(), 0)
} else {
SkyBlockTweaks.INSTANCE.fontRenderer.drawString(line, 0, yOff, 0)
}
yOff += 10
}
GlStateManager.popMatrix()
}
}

View File

@ -0,0 +1,48 @@
package com.github.itzilly.sbt
import com.github.itzilly.sbt.features.ChestEsp
import com.github.itzilly.sbt.features.GemstoneFinder
import com.github.itzilly.sbt.features.GrottoFinder
import com.github.itzilly.sbt.util.Chatterbox
import com.github.itzilly.sbt.util.SimpleChatMsg
import net.minecraft.client.Minecraft
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import net.minecraftforge.fml.common.gameevent.InputEvent
class InputHandler {
@SubscribeEvent
fun onKeyInput(event: InputEvent.KeyInputEvent?) {
if (STBKeyBinds.searchForChests.isPressed) {
ChestEsp.highlightChests()
}
if (STBKeyBinds.clearChests.isPressed) {
ChestEsp.chestList.clear()
Chatterbox.say(SimpleChatMsg("Chests cleared").green())
}
if (STBKeyBinds.toggleGrottoFinder.isPressed) {
Chatterbox.say("Running check...")
GrottoFinder.checkWorldForMagentaStainedGlass(Minecraft.getMinecraft().thePlayer.worldObj)
Chatterbox.say("Check done")
// if (GrottoFinder.isEnabled) {
// GrottoFinder.isEnabled = false
// Chatterbox.say(SimpleChatMsg("Grotto finder disabled!").red())
// MinecraftForge.EVENT_BUS.register(GrottoFinder)
// } else {
// GrottoFinder.isEnabled = true
// Chatterbox.say(SimpleChatMsg("Grotto finder enabled!").green())
// // MinecraftForge.EVENT_BUS.unregister(GrottoFinder)
// }
}
if (STBKeyBinds.clearGrotto.isPressed) {
GrottoFinder.clear()
Chatterbox.say("Cleared grotto finder")
}
if (STBKeyBinds.findGemstones.isPressed) {
GemstoneFinder.find()
}
if (STBKeyBinds.clearGemstones.isPressed) {
GemstoneFinder.clear()
}
}
}

View File

@ -1,112 +0,0 @@
package com.github.itzilly.sbt
import net.minecraft.client.renderer.Tessellator
import net.minecraft.client.renderer.WorldRenderer
import net.minecraft.client.renderer.vertex.DefaultVertexFormats
import net.minecraft.util.AxisAlignedBB
import java.awt.Color
class RenderUtils {
var TESSELLATOR: Tessellator = Tessellator.getInstance()
var WORLD_RENDERER: WorldRenderer = Tessellator.getInstance().worldRenderer
fun drawBlock(box: AxisAlignedBB, outlineStartColor: Int, outlineEndColor: Int) {
drawBlockTop(box, Color(outlineStartColor), Color(outlineEndColor));
drawBlockBottom(box, Color(outlineStartColor), Color(outlineEndColor));
drawBlockNorth(box, Color(outlineStartColor), Color(outlineEndColor));
drawBlockEast(box, Color(outlineStartColor), Color(outlineEndColor));
drawBlockSouth(box, Color(outlineStartColor), Color(outlineEndColor));
drawBlockWest(box, Color(outlineStartColor), Color(outlineEndColor));
}
private fun drawBlockTop(box: AxisAlignedBB, outlineStartColor: Color, outlineEndColor: Color) {
WORLD_RENDERER.begin(2, DefaultVertexFormats.POSITION_COLOR)
WORLD_RENDERER.pos(box.minX, box.maxY, box.minZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.maxX, box.maxY, box.minZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
WORLD_RENDERER.pos(box.maxX, box.maxY, box.maxZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.minX, box.maxY, box.maxZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
TESSELLATOR.draw()
}
private fun drawBlockBottom(box: AxisAlignedBB, outlineStartColor: Color, outlineEndColor: Color) {
WORLD_RENDERER.begin(2, DefaultVertexFormats.POSITION_COLOR)
WORLD_RENDERER.pos(box.maxX, box.minY, box.minZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.minX, box.minY, box.minZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
WORLD_RENDERER.pos(box.minX, box.minY, box.maxZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY, box.maxZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
TESSELLATOR.draw()
}
private fun drawBlockNorth(box: AxisAlignedBB, outlineStartColor: Color, outlineEndColor: Color) {
WORLD_RENDERER.begin(2, DefaultVertexFormats.POSITION_COLOR)
WORLD_RENDERER.pos(box.maxX, box.maxY, box.maxZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY, box.maxZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
WORLD_RENDERER.pos(box.minX, box.minY, box.maxZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.minX, box.maxY, box.maxZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
TESSELLATOR.draw()
}
private fun drawBlockEast(box: AxisAlignedBB, outlineStartColor: Color, outlineEndColor: Color) {
WORLD_RENDERER.begin(2, DefaultVertexFormats.POSITION_COLOR)
WORLD_RENDERER.pos(box.maxX, box.maxY, box.maxZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.maxX, box.maxY, box.minZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY, box.minZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY, box.maxZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
TESSELLATOR.draw()
}
private fun drawBlockSouth(box: AxisAlignedBB, outlineStartColor: Color, outlineEndColor: Color) {
WORLD_RENDERER.begin(2, DefaultVertexFormats.POSITION_COLOR)
WORLD_RENDERER.pos(box.minX, box.maxY, box.minZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.minX, box.minY, box.minZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY, box.minZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.maxX, box.maxY, box.minZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
TESSELLATOR.draw()
}
private fun drawBlockWest(box: AxisAlignedBB, outlineStartColor: Color, outlineEndColor: Color) {
WORLD_RENDERER.begin(2, DefaultVertexFormats.POSITION_COLOR)
WORLD_RENDERER.pos(box.minX, box.maxY, box.minZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.minX, box.maxY, box.maxZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
WORLD_RENDERER.pos(box.minX, box.minY, box.maxZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.minX, box.minY, box.minZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
TESSELLATOR.draw()
}
}

View File

@ -0,0 +1,86 @@
package com.github.itzilly.sbt
import com.github.itzilly.sbt.features.ChestEsp
import com.github.itzilly.sbt.features.GemstoneFinder
import net.minecraft.command.CommandBase
import net.minecraft.command.CommandException
import net.minecraft.command.ICommandSender
import net.minecraft.util.ChatComponentText
import net.minecraftforge.common.config.Configuration.*
class SBTCommand : CommandBase() {
override fun getCommandName(): String {
return "sbt"
}
override fun getCommandUsage(sender: ICommandSender): String {
return "/sbt <powderchests/gemstonesearchradius> [enable/disable/radius]"
}
override fun getRequiredPermissionLevel(): Int {
return 0
}
@Throws(CommandException::class)
override fun processCommand(sender: ICommandSender, args: Array<String>) {
if (args.isEmpty()) {
sender.addChatMessage(ChatComponentText("Invalid command. Usage: /sbt <powderchests/gemstonesearchradius> [enable/disable/radius]"))
return
}
when (args[0].lowercase()) {
"powderchests" -> {
if (args.size < 2) {
sender.addChatMessage(ChatComponentText("Usage: /sbt powderchests <enable/disable>"))
return
}
when (args[1].lowercase()) {
"enable" -> {
ChestEsp.enabled = true
SkyBlockTweaks.config.getCategory(CATEGORY_GENERAL)?.get("powderchestenable")?.set(true)
SkyBlockTweaks.config.save()
sender.addChatMessage(ChatComponentText("Powder ChestESP enabled."))
}
"disable" -> {
ChestEsp.enabled = false
SkyBlockTweaks.config.getCategory(CATEGORY_GENERAL)?.get("powderchestenable")?.set(false)
SkyBlockTweaks.config.save()
sender.addChatMessage(ChatComponentText("Powder ChestESP disabled."))
}
else -> {
sender.addChatMessage(ChatComponentText("Invalid option. Usage: /sbt powderchests <enable/disable>"))
}
}
}
"gemstonesearchradius" -> {
if (args.size < 2) {
sender.addChatMessage(ChatComponentText("Usage: /sbt gemstonesearchradius <radius>"))
return
}
try {
val radius = args[1].toInt()
if (radius < 0) {
sender.addChatMessage(ChatComponentText("Radius must be a positive integer."))
return
}
SkyBlockTweaks.config.getCategory(CATEGORY_GENERAL)?.get("gemstonesearchradius")?.set(radius)
SkyBlockTweaks.config.save()
GemstoneFinder.radius = radius
sender.addChatMessage(ChatComponentText("Gemstone search radius set to $radius."))
} catch (e: NumberFormatException) {
sender.addChatMessage(ChatComponentText("Invalid radius. Please provide a positive integer."))
}
}
else -> {
sender.addChatMessage(ChatComponentText("Invalid command. Usage: /sbt <powderchests/gemstonesearchradius> [enable/disable/radius]"))
}
}
}
}

View File

@ -0,0 +1,59 @@
package com.github.itzilly.sbt
import net.minecraft.client.settings.KeyBinding
import net.minecraftforge.fml.client.registry.ClientRegistry
import org.lwjgl.input.Keyboard
object STBKeyBinds {
lateinit var searchForChests: KeyBinding
lateinit var clearChests: KeyBinding
lateinit var toggleGrottoFinder: KeyBinding
lateinit var clearGrotto: KeyBinding
lateinit var findGemstones: KeyBinding
lateinit var clearGemstones: KeyBinding
lateinit var toggleLeftWalk: KeyBinding
lateinit var toggleRightWalk: KeyBinding
lateinit var toggleForwardWalk: KeyBinding
lateinit var toggleBackwardWalk: KeyBinding
lateinit var toggleLeftMouse: KeyBinding
fun init() {
searchForChests = KeyBinding("key.xraySearch", Keyboard.KEY_F10, "key.categories.sbt")
ClientRegistry.registerKeyBinding(searchForChests)
clearChests = KeyBinding("key.xrayClear", Keyboard.KEY_MINUS, "key.categories.sbt")
ClientRegistry.registerKeyBinding(clearChests)
toggleGrottoFinder = KeyBinding("key.toggleGrottoFinder", Keyboard.KEY_N, "key.categories.sbt")
ClientRegistry.registerKeyBinding(toggleGrottoFinder)
clearGrotto = KeyBinding("key.clearGrotto", Keyboard.KEY_F1, "key.categories.sbt")
ClientRegistry.registerKeyBinding(clearGrotto)
findGemstones = KeyBinding("key.findGemstones", Keyboard.KEY_J, "key.categories.sbt")
ClientRegistry.registerKeyBinding(findGemstones)
clearGemstones = KeyBinding("key.clearGemstones", Keyboard.KEY_K, "key.categories.sbt")
ClientRegistry.registerKeyBinding(clearGemstones)
// -----------------------
// Macro Toggle
// -----------------------
toggleLeftWalk = KeyBinding("key.toggleLeftWalk", Keyboard.KEY_LEFT, "key.categories.sbt")
ClientRegistry.registerKeyBinding(toggleLeftWalk)
toggleRightWalk = KeyBinding("key.toggleRightWalk", Keyboard.KEY_RIGHT, "key.categories.sbt")
ClientRegistry.registerKeyBinding(toggleRightWalk)
toggleForwardWalk = KeyBinding("key.toggleForwardWalk", Keyboard.KEY_UP, "key.categories.sbt")
ClientRegistry.registerKeyBinding(toggleForwardWalk)
toggleBackwardWalk = KeyBinding("key.toggleBackwardWalk", Keyboard.KEY_DOWN, "key.categories.sbt")
ClientRegistry.registerKeyBinding(toggleBackwardWalk)
toggleLeftMouse = KeyBinding("key.toggleLeftMouse", Keyboard.KEY_PRIOR, "key.categories.sbt")
ClientRegistry.registerKeyBinding(toggleLeftMouse)
}
}

View File

@ -1,38 +1,20 @@
package com.github.itzilly.sbt
import com.google.gson.Gson
import net.minecraft.block.Block
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.*
import net.minecraft.client.renderer.GlStateManager
import net.minecraft.client.renderer.Tessellator
import net.minecraft.client.renderer.WorldRenderer
import net.minecraft.client.renderer.entity.RenderManager
import net.minecraft.client.settings.KeyBinding
import net.minecraft.command.CommandException
import net.minecraft.command.ICommandSender
import net.minecraft.entity.Entity
import net.minecraft.init.Blocks
import net.minecraft.util.AxisAlignedBB
import net.minecraft.util.BlockPos
import net.minecraft.util.ChatComponentText
import net.minecraftforge.client.event.RenderGameOverlayEvent
import net.minecraftforge.client.event.RenderWorldLastEvent
import com.github.itzilly.sbt.features.ChestEsp
import com.github.itzilly.sbt.features.FarmHelper
import com.github.itzilly.sbt.features.GemstoneFinder
import com.github.itzilly.sbt.features.GrottoFinder
import com.github.itzilly.sbt.features.router.RouteBuilder
import com.github.itzilly.sbt.util.MessageScheduler
import net.minecraftforge.client.ClientCommandHandler
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.fml.client.registry.ClientRegistry
import net.minecraftforge.common.config.Configuration
import net.minecraftforge.fml.common.Mod
import net.minecraftforge.fml.common.event.FMLInitializationEvent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import net.minecraftforge.fml.common.gameevent.InputEvent
import org.lwjgl.input.Keyboard
import org.lwjgl.opengl.GL11
import java.awt.Color
import java.awt.Toolkit
import java.awt.datatransfer.Clipboard
import java.awt.datatransfer.StringSelection
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent
import java.io.File
@Mod(modid = "sbt", useMetadata = true)
@Mod(modid = "sbt", useMetadata = true, clientSideOnly = true)
class SkyBlockTweaks {
init {
INSTANCE = this
@ -40,325 +22,62 @@ class SkyBlockTweaks {
companion object {
lateinit var INSTANCE: SkyBlockTweaks
var routeList: ArrayList<RouteMarker> = ArrayList()
lateinit var config: Configuration
}
lateinit var tessellator: Tessellator
lateinit var worldRenderer: WorldRenderer
lateinit var renderManager: RenderManager
lateinit var fontRenderer: FontRenderer
private var renderWorldList: ArrayList<RenderHudAble> = ArrayList()
@Mod.EventHandler
fun preInit(event: FMLPreInitializationEvent) {
val directory = event.modConfigurationDirectory
config = Configuration(File(directory.path, "sbt.cfg"))
loadConfig()
}
@Mod.EventHandler
fun init(event: FMLInitializationEvent) {
try {
val resource: net.minecraft.client.resources.IResource = Minecraft.getMinecraft().resourceManager
.getResource(net.minecraft.util.ResourceLocation("test:test.txt"))
org.apache.commons.io.IOUtils.copy(resource.inputStream, java.lang.System.out)
} catch (e: java.io.IOException) {
throw java.lang.RuntimeException(e)
}
STBKeyBinds.init()
tessellator = Tessellator.getInstance()
worldRenderer = tessellator.worldRenderer
renderManager = Minecraft.getMinecraft().renderManager
fontRenderer = Minecraft.getMinecraft().fontRendererObj
MinecraftForge.EVENT_BUS.register(RouteBuilder)
MinecraftForge.EVENT_BUS.register(InputHandler())
MinecraftForge.EVENT_BUS.register(MessageScheduler)
MinecraftForge.EVENT_BUS.register(GrottoFinder)
MinecraftForge.EVENT_BUS.register(ChestEsp)
MinecraftForge.EVENT_BUS.register(GemstoneFinder)
MinecraftForge.EVENT_BUS.register(FarmHelper)
MinecraftForge.EVENT_BUS.register(this)
MinecraftForge.EVENT_BUS.register(KeyInputHandler())
MinecraftForge.EVENT_BUS.register(RouteMarkerRender())
ClientCommandHandler.instance.registerCommand(SBTCommand())
}
// @SubscribeEvent
// fun worldLoadEvent(event: WorldEvent.Load) {
// val msg = "Hello illy!"
// renderWorldList.add(
// HudText(
// arrayOf(msg),
// (Display.getWidth() / 2),
// Display.getHeight() / 2 / 2,
// false
// )
// )
// }
private fun loadConfig() {
config.load()
@SubscribeEvent
fun renderOverlayEvent(event: RenderGameOverlayEvent.Text) {
if (renderWorldList.size == 0) {
return
}
for (render: RenderHudAble in renderWorldList) {
render.render(event.partialTicks)
}
}
}
val powderChestEnable = config.getBoolean(
"powderchestenable",
Configuration.CATEGORY_GENERAL,
true,
"Enables/Disables Powder ChestESP"
)
ChestEsp.enabled = powderChestEnable
val gemstoneRadius = config.getInt(
"gemstonesearchradius",
Configuration.CATEGORY_GENERAL,
16,
1,
256,
"Enables/Disables Powder ChestESP"
)
ChestEsp.enabled = powderChestEnable
GemstoneFinder.radius = gemstoneRadius
interface RenderHudAble {
fun render(partialTicks: Float)
}
interface RenderWorldAble {
fun render(partialTicks: Float)
}
object STBKeyBinds {
lateinit var addWaypoint: KeyBinding
lateinit var finishWaypoints: KeyBinding
lateinit var clearWaypoints: KeyBinding
lateinit var openRoutesGui: KeyBinding
lateinit var xrayChests: KeyBinding
fun init() {
addWaypoint = KeyBinding("key.addWaypoint", Keyboard.KEY_ADD, "key.categories.sbt")
ClientRegistry.registerKeyBinding(addWaypoint)
finishWaypoints = KeyBinding("key.finishWaypoints", Keyboard.KEY_P, "key.categories.sbt")
ClientRegistry.registerKeyBinding(finishWaypoints)
clearWaypoints = KeyBinding("key.clearWaypoints", Keyboard.KEY_MINUS, "key.categories.sbt")
ClientRegistry.registerKeyBinding(clearWaypoints)
openRoutesGui = KeyBinding("key.openRoutesGui", Keyboard.KEY_O, "key.categories.sbt")
ClientRegistry.registerKeyBinding(openRoutesGui)
xrayChests = KeyBinding("key.xrayToggle", Keyboard.KEY_I, "key.categories.sbt")
ClientRegistry.registerKeyBinding(xrayChests)
}
}
class KeyInputHandler {
private val mc = Minecraft.getMinecraft()
@SubscribeEvent
fun onKeyInput(event: InputEvent.KeyInputEvent?) {
if (STBKeyBinds.addWaypoint.isPressed) {
val x = mc.thePlayer.posX.toInt()
val y = mc.thePlayer.posY.toInt()
val z = mc.thePlayer.posZ.toInt() - 1 // Offset from player (no clue why I need this)
if (!isPointInRouteList(SkyBlockTweaks.routeList, x, y, z)) {
val name = SkyBlockTweaks.routeList.size + 1
val point = RouteMarker(x, y, z, 0u, 1u, 0u, RouteOptions(name.toString()))
SkyBlockTweaks.routeList.add(point)
mc.thePlayer.addChatMessage(ChatComponentText("Adding Point ($x, $y, $z) to route list"))
} else {
mc.thePlayer.addChatMessage(ChatComponentText("Point ($x, $y, $z) is already in the route list"))
}
} else if (STBKeyBinds.finishWaypoints.isPressed) {
mc.thePlayer.addChatMessage(ChatComponentText("Finished route! Copied route to clipboard"))
val jsonString = Gson().toJson(SkyBlockTweaks.routeList)
setClipboard(jsonString)
SkyBlockTweaks.routeList.clear()
} else if (STBKeyBinds.clearWaypoints.isPressed) {
SkyBlockTweaks.routeList.clear()
mc.thePlayer.addChatMessage(ChatComponentText("Reset current route"))
} else if (STBKeyBinds.openRoutesGui.isPressed) {
mc.displayGuiScreen(RouteGui())
} else if (STBKeyBinds.xrayChests.isPressed) {
highlightChests()
if (config.hasChanged()) {
config.save()
}
}
private fun highlightChests() {
val searchRadius = 8
val world = Minecraft.getMinecraft().thePlayer.worldObj
val posX = Minecraft.getMinecraft().thePlayer.posX
val posY = Minecraft.getMinecraft().thePlayer.posY
val posZ = Minecraft.getMinecraft().thePlayer.posZ
val boundXMax = posX + searchRadius
val boundXMin = posX - searchRadius
val boundYMax = posY + searchRadius
val boundYMin = posY - searchRadius
val boundZMax = posZ + searchRadius
val boundZMin = posZ - searchRadius
val maxMarker =
RouteMarker(boundXMax.toInt(), boundYMax.toInt(), boundZMax.toInt(), 1u, 0u, 0u, RouteOptions("Max Bounds"))
val minMarker =
RouteMarker(boundXMin.toInt(), boundYMin.toInt(), boundZMin.toInt(), 0u, 1u, 0u, RouteOptions("Min Bounds"))
Minecraft.getMinecraft().thePlayer.addChatMessage(ChatComponentText("Searching..."))
for (x in boundXMin.toInt()..boundXMax.toInt()) {
for (y in boundYMin.toInt()..boundYMax.toInt()) {
for (z in boundZMin.toInt()..boundZMax.toInt()) {
val block = world.getBlockState(BlockPos(x, y, z)).block
if (block == Blocks.chest || block == Blocks.trapped_chest || block == Blocks.ender_chest) {
val point = RouteMarker(x, y, z, 0u, 0u, 1u, RouteOptions("Located point"))
SkyBlockTweaks.routeList.add(point)
}
}
}
}
Minecraft.getMinecraft().thePlayer.addChatMessage(ChatComponentText("Done!"))
// SkyBlockTweaks.routeList.add(maxMarker)
// SkyBlockTweaks.routeList.add(minMarker)
}
}
data class RouteMarker(
val x: Int,
val y: Int,
val z: Int,
val r: UByte,
val g: UByte,
val b: UByte,
val options: RouteOptions
)
fun isPointInRouteList(routeList: List<RouteMarker>, x: Int, y: Int, z: Int): Boolean {
return routeList.any { it.x == x && it.y == y && it.z == z }
}
data class RouteOptions(
val name: String
)
fun setClipboard(s: String) {
val selection = StringSelection(s)
val clipboard: Clipboard = Toolkit.getDefaultToolkit().systemClipboard
clipboard.setContents(selection, selection)
}
class RouteMarkerRender {
@SubscribeEvent
fun renderBlockOverlay(event: RenderWorldLastEvent) {
val player = Minecraft.getMinecraft().thePlayer
for (marker: RouteMarker in SkyBlockTweaks.routeList) {
val pos = BlockPos(marker.x, marker.y, marker.z)
renderPoint(player, pos, event.partialTicks)
fun syncConfig() {
loadConfig()
if (config.hasChanged()) {
config.save()
}
}
}
fun renderPoint(entity: Entity, blockPos: BlockPos, partialTicks: Float) {
val padding: Double = 0.0020000000949949026
val entityX: Double = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * partialTicks
val entityY: Double = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * partialTicks
val entityZ: Double = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * partialTicks
val outlineStartColor = 0xFFFFFF
val outlineEndColor = 0xFFFFFF
val world = Minecraft.getMinecraft().theWorld
val blockState = world.getBlockState(blockPos)
val block: Block = blockState.block
// Create a default bounding box for blocks that don't have one
val boundingBox: AxisAlignedBB = block.getCollisionBoundingBox(world, blockPos, blockState)
?: AxisAlignedBB(
blockPos.x.toDouble(), blockPos.y.toDouble(), blockPos.z.toDouble(),
blockPos.x + 1.0, blockPos.y + 1.0, blockPos.z + 1.0
).expand(padding, padding, padding)
GL11.glPushMatrix()
GlStateManager.disableTexture2D()
GlStateManager.depthMask(false)
GlStateManager.disableDepth()
GL11.glEnable(GL11.GL_LINE_SMOOTH)
GL11.glHint(GL11.GL_LINE_SMOOTH_HINT, GL11.GL_NICEST)
GL11.glLineWidth(2.0f)
GL11.glShadeModel(GL11.GL_SMOOTH)
RenderUtils().drawBlock(boundingBox.offset(-entityX, -entityY, -entityZ), outlineStartColor, outlineEndColor)
GL11.glLineWidth(2.0f)
GL11.glDisable(GL11.GL_LINE_SMOOTH)
GlStateManager.enableDepth()
GlStateManager.depthMask(true)
GlStateManager.enableAlpha()
GlStateManager.enableTexture2D()
GL11.glPopMatrix()
}
class RouteMarkerButton(buttonId: Int, x: Int, y: Int, widthIn: Int, heightIn: Int, buttonText: String?) :
GuiButton(buttonId, x, y, widthIn, heightIn, buttonText) {
constructor(buttonId: Int, x: Int, y: Int, buttonText: String?) : this(buttonId, x, y, 200, 20, buttonText)
override fun drawButton(mc: Minecraft, mouseX: Int, mouseY: Int) {
if (visible) {
val fontrenderer = mc.fontRendererObj
//mc.getTextureManager().bindTexture(buttonTextures);
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f)
hovered =
mouseX >= xPosition && mouseY >= yPosition && mouseX < xPosition + width && mouseY < yPosition + height
//int i = this.getHoverState(this.hovered);
drawRect(
xPosition, yPosition, xPosition + width, yPosition + height,
if (hovered) Color(255, 255, 255, 80).rgb else Color(0, 0, 0, 80).rgb
)
//this.drawTexturedModalRect(this.xPosition, this.yPosition, 0, 46 + i * 20, this.width / 2, this.height);
//this.drawTexturedModalRect(this.xPosition + this.width / 2, this.yPosition, 200 - this.width / 2, 46 + i * 20, this.width / 2, this.height);
mouseDragged(mc, mouseX, mouseY)
var j = 14737632
if (packedFGColour != 0) {
j = packedFGColour
} else if (!enabled) {
j = 10526880
} else if (hovered) {
j = 16777120
}
drawCenteredString(
fontrenderer,
displayString, xPosition + width / 2, yPosition + (height - 8) / 2, j
)
}
}
}
class RouteGui : GuiScreen() {
private val id: Int = 0
override fun initGui() {
super.initGui()
buttonList.clear()
populateRouteList()
buttonList.add(RouteMarkerButton(9000, width / 2 + 20, height - 40, "Exit"))
}
override fun actionPerformed(button: GuiButton?) {
if (button == null) {
return
}
if (button.id < 1000) {
buttonList.remove(button)
} else if (button.id == 9000) {
Minecraft.getMinecraft().thePlayer.closeScreen()
}
}
override fun drawScreen(mouseX: Int, mouseY: Int, partialTicks: Float) {
this.drawDefaultBackground()
super.drawScreen(mouseX, mouseY, partialTicks)
}
private fun populateRouteList() {
for ((buttonId, m: RouteMarker) in SkyBlockTweaks.routeList.withIndex()) {
val markerField = GuiTextField(1000 + buttonId, fontRendererObj, width / 2 - 200, 0, 100, 20)
markerField.text = "${m.options.name} X:${m.x} Y:${m.y} Z:${m.z}"
val removeButton = RouteMarkerButton(2000 + buttonId, width / 2 + 175, 0, 50, 20, "Remove")
buttonList.add(removeButton)
}
}
}

View File

@ -0,0 +1,175 @@
package com.github.itzilly.sbt.features
import com.github.itzilly.sbt.SkyBlockTweaks
import com.github.itzilly.sbt.renderer.RenderUtils
import java.awt.Color
import com.github.itzilly.sbt.util.Chatterbox
import com.github.itzilly.sbt.util.DelayedFunction
import com.github.itzilly.sbt.util.SimpleChatMsg
import com.github.itzilly.sbt.util.Vecd3
import net.minecraft.block.Block
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.GlStateManager
import net.minecraft.init.Blocks
import net.minecraft.util.BlockPos
import net.minecraft.entity.Entity
import net.minecraft.tileentity.TileEntityChest
import net.minecraft.util.AxisAlignedBB
import net.minecraft.util.MovingObjectPosition
import net.minecraftforge.client.event.ClientChatReceivedEvent
import net.minecraftforge.client.event.RenderWorldLastEvent
import net.minecraftforge.common.config.Configuration
import net.minecraftforge.event.entity.player.PlayerInteractEvent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import org.lwjgl.opengl.GL11
data class ChestNode(
val x: Int,
val y: Int,
val z: Int,
)
fun chestNodeExists(x: Int, y: Int, z: Int): Boolean {
return ChestEsp.chestList.any { it.x == x && it.y == y && it.z == z }
}
object ChestEsp {
var chestList: ArrayList<ChestNode> = ArrayList()
var enabled: Boolean = SkyBlockTweaks.config.getBoolean("powderchestenable", Configuration.CATEGORY_GENERAL, true, "Enables/Disables Powder ChestESP")
@SubscribeEvent
fun chatMessageEvent(event: ClientChatReceivedEvent) {
if (!enabled) return
if (event.message.unformattedText == "You uncovered a treasure chest!") {
DelayedFunction({ highlightChests() }, 5)
}
}
@SubscribeEvent
fun renderBlockOverlay(event: RenderWorldLastEvent) {
if (!enabled) return
val player = Minecraft.getMinecraft().thePlayer
for (chest: ChestNode in chestList) {
val pos = BlockPos(chest.x, chest.y, chest.z)
drawChestOutline(player, pos, event.partialTicks)
drawChestLine(pos, event.partialTicks)
}
}
@SubscribeEvent
fun rightClickEvent(event: PlayerInteractEvent) {
if (!enabled) return
if (event.action == PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK) {
val pos = event.pos
if (chestNodeExists(pos.x, pos.y, pos.z)) {
chestList.removeIf { it.x == pos.x && it.y == pos.y && it.z == pos.z }
checkChestLocations()
}
}
}
fun checkChestLocations() {
for (chest in chestList) {
if (chestNodeExists(chest.x, chest.y, chest.z)) {
chestList.removeIf { it.x == chest.x && it.y == chest.y && it.z == chest.z }
}
}
}
fun highlightChests() {
if (!enabled) return
val searchRadius = 8
val world = Minecraft.getMinecraft().thePlayer.worldObj
val posX = Minecraft.getMinecraft().thePlayer.posX
val posY = Minecraft.getMinecraft().thePlayer.posY
val posZ = Minecraft.getMinecraft().thePlayer.posZ
val boundXMax = posX + searchRadius
val boundXMin = posX - searchRadius
val boundYMax = posY + searchRadius
val boundYMin = posY - searchRadius
val boundZMax = posZ + searchRadius
val boundZMin = posZ - searchRadius
for (x in boundXMin.toInt()..boundXMax.toInt()) {
for (y in boundYMin.toInt()..boundYMax.toInt()) {
for (z in boundZMin.toInt()..boundZMax.toInt()) {
val block = world.getBlockState(BlockPos(x, y, z)).block
if (block == Blocks.chest || block == Blocks.trapped_chest || block == Blocks.ender_chest) {
val tileEntity = world.getTileEntity(BlockPos(x, y, z))
if (tileEntity is TileEntityChest) {
if (tileEntity.numPlayersUsing != 0) {
val point = ChestNode(x, y, z)
if (!chestNodeExists(x, y, z)) {
chestList.add(point)
}
}
}
}
}
}
}
checkChestLocations()
}
private fun drawChestOutline(entity: Entity, blockPos: BlockPos, partialTicks: Float) {
val padding: Double = 0.0020000000949949026
val entityX: Double = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * partialTicks
val entityY: Double = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * partialTicks
val entityZ: Double = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * partialTicks
val outlineStartColor = 0xFFFFFF
val outlineEndColor = 0xFFFFFF
val world = Minecraft.getMinecraft().theWorld
val blockState = world.getBlockState(blockPos)
val block: Block = blockState.block
// Create a default bounding box for blocks that don't have one
val boundingBox: AxisAlignedBB = block.getCollisionBoundingBox(world, blockPos, blockState)
?: AxisAlignedBB(
blockPos.x.toDouble(), blockPos.y.toDouble(), blockPos.z.toDouble(),
blockPos.x + 1.0, blockPos.y + 1.0, blockPos.z + 1.0
).expand(padding, padding, padding)
GL11.glPushMatrix()
GlStateManager.disableTexture2D()
GlStateManager.depthMask(false)
GlStateManager.disableDepth()
GL11.glEnable(GL11.GL_LINE_SMOOTH)
GL11.glHint(GL11.GL_LINE_SMOOTH_HINT, GL11.GL_NICEST)
GL11.glLineWidth(2.0f)
GL11.glShadeModel(GL11.GL_SMOOTH)
RenderUtils.drawBlock(boundingBox.offset(-entityX, -entityY, -entityZ), outlineStartColor, outlineEndColor)
GL11.glLineWidth(2.0f)
GL11.glDisable(GL11.GL_LINE_SMOOTH)
GlStateManager.enableDepth()
GlStateManager.depthMask(true)
GlStateManager.enableAlpha()
GlStateManager.enableTexture2D()
GL11.glPopMatrix()
}
private fun drawChestLine(pos: BlockPos, partialTicks: Float) {
val render = Minecraft.getMinecraft().renderViewEntity
val rm = Minecraft.getMinecraft().renderManager
// TODO: Fix this not working with view bobbing enabled
val pos1 = Vecd3(rm.viewerPosX, rm.viewerPosY + render.eyeHeight, rm.viewerPosZ)
val pos2 = Vecd3(
pos.x.toDouble() + 0.5, // Center of the block
pos.y.toDouble() + 0.5, // Center of the block
pos.z.toDouble() + 0.5 // Center of the block
)
val lineColor = Color(0xe310d5)
RenderUtils.drawLine(pos1, pos2, lineColor, 2, false, partialTicks)
}
}

View File

@ -0,0 +1,105 @@
package com.github.itzilly.sbt.features
import com.github.itzilly.sbt.STBKeyBinds.toggleLeftWalk;
import com.github.itzilly.sbt.features.gardener.CaneMacroer
import com.github.itzilly.sbt.util.Chatterbox
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.Gui
import net.minecraft.client.gui.GuiChat
import net.minecraftforge.client.event.RenderGameOverlayEvent
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import net.minecraftforge.fml.common.gameevent.InputEvent
import net.minecraftforge.fml.common.gameevent.TickEvent
import org.lwjgl.input.Keyboard
object FarmHelper {
private val mc: Minecraft = Minecraft.getMinecraft()
private var isToggledLeft = false
private var isToggledRight = false
private var isToggledForward = false
private var isToggledBack = false
private var isToggledAttack = false
private var ignoreNextKeyUp = false
private var lastToggleKeyCode = -1
@SubscribeEvent
fun onTick(event: TickEvent.ClientTickEvent) {
if (mc.gameSettings.keyBindForward.isKeyDown) isToggledForward = false
if (mc.gameSettings.keyBindLeft.isKeyDown) isToggledLeft = false
if (mc.gameSettings.keyBindRight.isKeyDown) isToggledRight = false
if (mc.gameSettings.keyBindBack.isKeyDown) isToggledBack = false
if (mc.gameSettings.keyBindAttack.isKeyDown) isToggledAttack = false
}
@SubscribeEvent
fun onKeyInput(event: InputEvent.KeyInputEvent) {
val key = Keyboard.getEventKey()
val isPressed = Keyboard.getEventKeyState()
if (toggleLeftWalk.isPressed) {
Chatterbox.say("Enabled macro!")
CaneMacroer.isMacroToggled = true
MinecraftForge.EVENT_BUS.register(CaneMacroer)
CaneMacroer.mc.displayGuiScreen(GuiChat(""))
lastToggleKeyCode = key
ignoreNextKeyUp = true
return
}
if (!isPressed && ignoreNextKeyUp && key == lastToggleKeyCode) {
ignoreNextKeyUp = false
return
}
if (CaneMacroer.isMacroToggled) {
Chatterbox.say("Macro disabled by input!")
CaneMacroer.isMacroToggled = false
CaneMacroer.stop()
MinecraftForge.EVENT_BUS.unregister(CaneMacroer)
}
// if (toggleLeftWalk.isPressed) isToggledLeft = !isToggledLeft
// if (toggleRightWalk.isPressed) isToggledRight = !isToggledRight
// if (toggleForwardWalk.isPressed) isToggledForward = !isToggledForward
// if (toggleBackwardWalk.isPressed) isToggledBack = !isToggledBack
// if (toggleLeftMouse.isPressed) isToggledAttack = !isToggledAttack
//
// if (isToggledLeft) (mc.gameSettings.keyBindLeft as KeyBindingAccessor).setPressed(true)
// if (isToggledRight) (mc.gameSettings.keyBindRight as KeyBindingAccessor).setPressed(true)
// if (isToggledForward) (mc.gameSettings.keyBindForward as KeyBindingAccessor).setPressed(true)
// if (isToggledBack) (mc.gameSettings.keyBindBack as KeyBindingAccessor).setPressed(true)
// if (isToggledAttack) (mc.gameSettings.keyBindAttack as KeyBindingAccessor).setPressed(true)
}
@SubscribeEvent
fun onRenderOverlay(event: RenderGameOverlayEvent.Text) {
val x = 10f
var y = 10f
val toggledKeys = mutableListOf<String>()
if (isToggledForward) toggledKeys.add("W")
if (isToggledLeft) toggledKeys.add("A")
if (isToggledBack) toggledKeys.add("S")
if (isToggledRight) toggledKeys.add("D")
if (isToggledAttack) toggledKeys.add("Attack")
if (toggledKeys.isEmpty()) return
val boxWidth = 60
val boxHeight = 10 + toggledKeys.size * 10
Gui.drawRect((x - 2).toInt(), (y - 2).toInt(), (x + boxWidth).toInt(), (y + boxHeight).toInt(), 0x90000000.toInt())
for (label in toggledKeys) {
mc.fontRendererObj.drawStringWithShadow("[$label]", x, y, 0xFFFFFF)
y += 10f
}
}
}

View File

@ -0,0 +1,158 @@
package com.github.itzilly.sbt.features
import com.github.itzilly.sbt.SkyBlockTweaks
import com.github.itzilly.sbt.renderer.RenderFuncs
import net.minecraft.client.Minecraft
import net.minecraft.init.Blocks
import net.minecraft.util.BlockPos
import net.minecraftforge.client.event.RenderWorldLastEvent
import net.minecraftforge.common.config.Configuration
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
enum class GemstoneColors(val color: Int) {
RUBY(0xFF5555), // Red
JADE(0x00AA00), // Lime
AMBER(0xFFAA00), // Orange
SAPPHIRE(0x55FFFF), // Light Blue
AMETHYST(0xAA00AA), // Purple
TOPAZ(0xFFFF55), // Yellow
JASPER(0xFF55FF) // Magenta
}
object GemstoneFinder {
private var gemstoneClusters: ArrayList<GemstoneCluster> = ArrayList()
private var gemstoneList: ArrayList<GemstoneBlock> = ArrayList()
var radius = SkyBlockTweaks.config.getCategory(Configuration.CATEGORY_GENERAL)?.get("gemstonesearchradius")?.int?: 16
fun clear() {
gemstoneClusters.clear()
}
fun find() {
val playerPos = Minecraft.getMinecraft().thePlayer.position
val minBounds = BlockPos(
playerPos.x - radius,
maxOf(playerPos.y - radius, 31),
playerPos.z - radius
)
val maxBounds = BlockPos(
playerPos.x + radius,
minOf(playerPos.y + radius, 188),
playerPos.z + radius
)
val world = Minecraft.getMinecraft().thePlayer.worldObj
val gemstonesMap = mutableMapOf<GemstoneColors, MutableList<BlockPos>>()
for (chunkX in minBounds.x / 16..maxBounds.x / 16) {
for (chunkZ in minBounds.z / 16..maxBounds.z / 16) {
val chunk = world.getChunkFromChunkCoords(chunkX, chunkZ)
for (x in 0..15) {
for (y in minBounds.y..maxBounds.y) {
for (z in 0..15) {
val worldX = chunk.xPosition * 16 + x
val worldZ = chunk.zPosition * 16 + z
if (worldX in minBounds.x..maxBounds.x && worldZ in minBounds.z..maxBounds.z) {
val blockPos = BlockPos(worldX, y, worldZ)
val blockState = chunk.getBlockState(blockPos)
val block = blockState.block
if (block == Blocks.air) continue
val meta = block.getMetaFromState(blockState)
val gemstoneColor = when {
block === Blocks.stained_glass || block === Blocks.stained_glass_pane -> {
when (meta) {
1 -> GemstoneColors.AMBER // Orange
2 -> GemstoneColors.JASPER // Magenta
3 -> GemstoneColors.SAPPHIRE // Light Blue
4 -> GemstoneColors.TOPAZ // Yellow
5 -> GemstoneColors.JADE // Lime
14 -> GemstoneColors.RUBY // Red
10 -> GemstoneColors.AMETHYST // Purple
else -> null
}
}
else -> null
}
if (gemstoneColor != null) {
gemstonesMap.getOrPut(gemstoneColor) { mutableListOf() }.add(blockPos)
}
}
}
}
}
}
}
for ((color, positions) in gemstonesMap) {
val clusters = clusterGemstones(positions)
for (cluster in clusters) {
gemstoneClusters.add(GemstoneCluster(cluster, color))
}
}
}
private fun clusterGemstones(positions: List<BlockPos>): List<List<BlockPos>> {
val clusters = mutableListOf<List<BlockPos>>()
val visited = mutableSetOf<BlockPos>()
fun dfs(start: BlockPos, cluster: MutableList<BlockPos>) {
val stack = ArrayDeque<BlockPos>()
stack.add(start)
while (stack.isNotEmpty()) {
val pos = stack.removeLast()
if (pos in visited) continue
visited.add(pos)
cluster.add(pos)
// Check adjacent blocks in all six directions
for (offset in listOf(BlockPos(1, 0, 0), BlockPos(-1, 0, 0), BlockPos(0, 1, 0), BlockPos(0, -1, 0), BlockPos(0, 0, 1), BlockPos(0, 0, -1))) {
val neighbor = pos.add(offset)
if (neighbor in positions && neighbor !in visited) {
stack.add(neighbor)
}
}
}
}
for (pos in positions) {
if (pos !in visited) {
val cluster = mutableListOf<BlockPos>()
dfs(pos, cluster)
clusters.add(cluster)
}
}
return clusters
}
@SubscribeEvent
fun renderBlockOverlay(event: RenderWorldLastEvent) {
val player = Minecraft.getMinecraft().thePlayer
for (cluster in gemstoneClusters) {
RenderFuncs.drawClusterOutline(player, cluster.positions, event.partialTicks, cluster.color.color)
}
}
data class GemstoneCluster(
val positions: List<BlockPos>,
val color: GemstoneColors
)
data class GemstoneBlock(
val x: Int,
val y: Int,
val z: Int,
val color: GemstoneColors,
val maxX: Int = x,
val maxY: Int = y,
val maxZ: Int = z
)
}

View File

@ -0,0 +1,88 @@
package com.github.itzilly.sbt.features
import com.github.itzilly.sbt.renderer.RenderFuncs
import com.github.itzilly.sbt.util.Chatterbox
import com.github.itzilly.sbt.util.MessageScheduler
import com.github.itzilly.sbt.util.SimpleChatMsg
import net.minecraft.block.Block
import net.minecraft.block.state.IBlockState
import net.minecraft.client.Minecraft
import net.minecraft.client.network.NetHandlerPlayClient
import net.minecraft.init.Blocks
import net.minecraft.util.BlockPos
import net.minecraft.world.World
import net.minecraft.world.chunk.Chunk
import net.minecraftforge.client.event.RenderWorldLastEvent
import net.minecraftforge.event.world.ChunkEvent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
object GrottoFinder {
private val targetBlock: Block = Blocks.stained_glass
private val targetMeta: Int = 2 // Magenta stained glass
private var magentaGlassList: ArrayList<ChestNode> = ArrayList()
private val minBounds = BlockPos(201, 30, 201)
private val maxBounds = BlockPos(824, 189, 824)
var isEnabled: Boolean = true
fun clear() {
magentaGlassList.clear()
}
fun checkWorldForMagentaStainedGlass(world: World) {
for (chunkX in minBounds.x / 16..maxBounds.x / 16) {
for (chunkZ in minBounds.z / 16..maxBounds.z / 16) {
val chunk = world.getChunkFromChunkCoords(chunkX, chunkZ)
// Iterate through the chunk's blocks within the world bounds
for (x in 0..15) {
for (y in minBounds.y..maxBounds.y) {
for (z in 0..15) {
val worldX = chunk.xPosition * 16 + x
val worldZ = chunk.zPosition * 16 + z
// Ensure the block is within the specified bounds
if (worldX in minBounds.x..maxBounds.x && worldZ in minBounds.z..maxBounds.z) {
val blockPos = BlockPos(worldX, y, worldZ)
val blockState = chunk.getBlockState(blockPos)
val block = blockState.block
val meta = block.getMetaFromState(blockState)
if (block === Blocks.stained_glass && meta == 2) {
if (!magentaNodeExists(blockPos.x, blockPos.y, blockPos.z)) {
magentaGlassList.add(ChestNode(blockPos.x, blockPos.y, blockPos.z))
}
println("Found magenta stained glass at $blockPos")
val msg = SimpleChatMsg("Found magenta stained glass at $blockPos").light_purple()
Chatterbox.say(msg)
}
}
}
}
}
}
}
}
@SubscribeEvent
fun renderBlockOverlay(event: RenderWorldLastEvent) {
val player = Minecraft.getMinecraft().thePlayer
for (glass: ChestNode in magentaGlassList) {
val pos = BlockPos(glass.x, glass.y, glass.z)
RenderFuncs.drawBlockOutline(player, pos, event.partialTicks)
RenderFuncs.drawBlockLine(pos, event.partialTicks)
}
}
private fun magentaNodeExists(x: Int, y: Int, z: Int): Boolean {
return magentaGlassList.any { it.x == x && it.y == y && it.z == z }
}
}
// World Bounds 824, 189, 824 201, 30, 201

View File

@ -0,0 +1,20 @@
package com.github.itzilly.sbt.features
import net.minecraft.client.Minecraft
import net.minecraft.client.settings.GameSettings
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import net.minecraftforge.fml.common.gameevent.TickEvent
object MacroInterface {
private val gs: GameSettings = Minecraft.getMinecraft().gameSettings
private var running: Boolean = false
@SubscribeEvent
private fun onClientTick(event: TickEvent.PlayerTickEvent) {
}
fun stop() {
running = false
}
}

View File

@ -0,0 +1,83 @@
package com.github.itzilly.sbt.features.gardener
import com.github.itzilly.sbt.mixin.KeyBindingAccessor
import com.github.itzilly.sbt.util.Chatterbox
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.GuiChat
import net.minecraft.client.settings.KeyBinding
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import net.minecraftforge.fml.common.gameevent.TickEvent
import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent
object CaneMacroer {
var isMacroToggled: Boolean = false
val mc = Minecraft.getMinecraft()
val allowedScreens = listOf(GuiChat::class.java)
@SubscribeEvent
fun onTick(event: ClientTickEvent) {
if (event.phase != TickEvent.Phase.END) return
if (!isMacroToggled) return
val currentScreen = mc.currentScreen
if (currentScreen != null && allowedScreens.none { it.isInstance(currentScreen) }) {
Chatterbox.say("Macro stopped: Invalid screen")
stop()
return
}
val mop = mc.objectMouseOver
if (mop == null || mop.typeOfHit?.name != "BLOCK") return
val blockPos = mop.blockPos
val facing = mop.sideHit
val player = mc.thePlayer
val blockCenter = blockPos.add(0.5, 0.5, 0.5)
val distanceSq = player.getDistanceSq(blockCenter.x.toDouble(), blockCenter.y.toDouble(), blockCenter.z.toDouble())
if (distanceSq > 25) {
Chatterbox.say("Macro stopped: Too far from block")
stop()
return
}
if (isEntityBlockingView()) {
Chatterbox.say("Macro stopped: Entity in the way")
stop()
return
}
pressKey(mc.gameSettings.keyBindForward.keyCode)
mc.playerController.onPlayerDamageBlock(blockPos, facing)
player.swingItem()
}
fun stop() {
KeyBinding.setKeyBindState(mc.gameSettings.keyBindForward.keyCode, false)
KeyBinding.setKeyBindState(mc.gameSettings.keyBindAttack.keyCode, false)
isMacroToggled = false
}
private fun pressKey(keyCode: Int) {
KeyBinding.setKeyBindState(keyCode, true)
}
private fun isEntityBlockingView(): Boolean {
val lookVec = mc.thePlayer.lookVec
val eyePos = mc.thePlayer.getPositionEyes(1f)
val entities = mc.theWorld.getEntitiesWithinAABBExcludingEntity(
mc.thePlayer,
mc.thePlayer.entityBoundingBox.expand(lookVec.xCoord * 5, lookVec.yCoord * 5, lookVec.zCoord * 5)
)
return entities.any {
it.canBeCollidedWith() &&
it.entityBoundingBox.isVecInside(eyePos)
}
}
}

View File

@ -0,0 +1,199 @@
package com.github.itzilly.sbt.features.gardener
import com.github.itzilly.sbt.util.Chatterbox
import net.minecraft.client.gui.*
class MacroMakerGui : GuiScreen() {
private var selectedTaskIndex: Int = -1
private var draggedTaskIndex: Int = -1
private var dragOffsetY: Int = 0
private val macro = Macro("Example Macro")
enum class ButtonId(val id: Int) {
SAVE_MACRO(0),
CANCEL(1)
}
override fun initGui() {
this.buttonList.clear()
buttonList.add(GuiButton(ButtonId.SAVE_MACRO.id, width / 2 - 100, height - 40, 90, 20, "Save Macro"))
buttonList.add(GuiButton(ButtonId.CANCEL.id, width / 2 + 10, height - 40, 90, 20, "Cancel"))
macro.tasks.add(MoveTask("W", true))
macro.tasks.add(MouseTask("Left Click"))
macro.tasks.add(ChatCommandTask("/spawn"))
}
override fun actionPerformed(button: GuiButton) {
when (button.id) {
ButtonId.SAVE_MACRO.id -> {
Chatterbox.say("Saved macro!")
Close()
}
ButtonId.CANCEL.id -> Close()
}
}
override fun drawScreen(mouseX: Int, mouseY: Int, partialTicks: Float) {
drawDefaultBackground()
val thirdWidth = width / 3
drawRect(0, 0, thirdWidth, height, 0xFF202020.toInt())
drawRect(thirdWidth, 0, thirdWidth * 2, height, 0xFF303030.toInt())
drawRect(thirdWidth * 2, 0, width, height, 0xFF202020.toInt())
drawCenteredString(fontRendererObj, "Macro Maker", width / 2, 10, 0xFFFFFF)
drawLeftPanel(mouseX, mouseY)
drawMiddlePanel(mouseX, mouseY)
drawRightPanel()
super.drawScreen(mouseX, mouseY, partialTicks)
}
private fun drawLeftPanel(mouseX: Int, mouseY: Int) {
drawString(fontRendererObj, "Editing: ${macro.name}", 10, 20, 0xFFFFFF)
drawString(fontRendererObj, "Add Task:", 10, 40, 0xAAAAAA)
val taskButtons = listOf(
Triple("+ Move", 60, { macro.tasks.add(MoveTask("W", false)) }),
Triple("+ Mouse", 80, { macro.tasks.add(MouseTask("Right Click")) }),
Triple("+ Command", 100, { macro.tasks.add(ChatCommandTask("/say Hello")) })
)
for ((label, y, _) in taskButtons) {
drawString(fontRendererObj, label, 10, y, 0x00FF00)
}
if (mouseClickedX in 10..100 && mouseClickedY != -1) {
for ((_, y, action) in taskButtons) {
if (mouseClickedY in y..(y + 10)) {
action.invoke()
break
}
}
mouseClickedX = -1
mouseClickedY = -1
}
}
private fun drawMiddlePanel(mouseX: Int, mouseY: Int) {
val thirdWidth = width / 3
val taskStartY = 40
val taskHeight = 20
for ((index, task) in macro.tasks.withIndex()) {
val y = taskStartY + index * (taskHeight + 5)
if (draggedTaskIndex == index) continue // skip rendering the dragged one
val color = if (index == selectedTaskIndex) 0xFF4444 else 0xFFFFFF
drawRect(thirdWidth + 10, y, thirdWidth * 2 - 10, y + taskHeight, 0xFF404040.toInt())
drawString(fontRendererObj, "${task.name} - ${task.getPreview()}", thirdWidth + 15, y + 6, color)
}
// Draw the dragged task following the mouse
if (draggedTaskIndex != -1) {
val task = macro.tasks[draggedTaskIndex]
val y = mouseY - dragOffsetY
drawRect(thirdWidth + 10, y, thirdWidth * 2 - 10, y + taskHeight, 0xFF606060.toInt())
drawString(fontRendererObj, "${task.name} - ${task.getPreview()}", thirdWidth + 15, y + 6, 0xFFFF00)
}
}
private fun drawRightPanel() {
val selected = macro.tasks.getOrNull(selectedTaskIndex) ?: return
val startX = width - 180
val startY = 20
val boxWidth = 160
val boxHeight = 80
// Box with outline
drawRect(startX - 2, startY - 2, startX + boxWidth + 2, startY + boxHeight + 2, 0xFFFFFFFF.toInt())
drawRect(startX, startY, startX + boxWidth, startY + boxHeight, 0xFF101010.toInt())
drawString(fontRendererObj, "Task Properties", startX + 5, startY + 5, 0xFFFFFF)
when (selected) {
is MoveTask -> {
drawString(fontRendererObj, "Direction: ${selected.direction}", startX + 5, startY + 25, 0xCCCCCC)
drawString(fontRendererObj, "Hold: ${selected.hold}", startX + 5, startY + 40, 0xCCCCCC)
}
is MouseTask -> {
drawString(fontRendererObj, "Action: ${selected.action}", startX + 5, startY + 25, 0xCCCCCC)
}
is ChatCommandTask -> {
drawString(fontRendererObj, "Command:", startX + 5, startY + 25, 0xCCCCCC)
drawString(fontRendererObj, selected.command, startX + 5, startY + 40, 0x00FFAA)
}
}
}
private var mouseClickedX = -1
private var mouseClickedY = -1
override fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int) {
mouseClickedX = mouseX
mouseClickedY = mouseY
val thirdWidth = width / 3
val taskStartY = 40
val taskHeight = 25
for ((index, _) in macro.tasks.withIndex()) {
val y = taskStartY + index * taskHeight
if (mouseX in (thirdWidth + 10)..(thirdWidth * 2 - 10) && mouseY in y..(y + 20)) {
selectedTaskIndex = index
draggedTaskIndex = index
dragOffsetY = mouseY - y
}
}
super.mouseClicked(mouseX, mouseY, mouseButton)
}
override fun mouseClickMove(mouseX: Int, mouseY: Int, clickedMouseButton: Int, timeSinceLastClick: Long) {
super.mouseClickMove(mouseX, mouseY, clickedMouseButton, timeSinceLastClick)
}
override fun mouseReleased(mouseX: Int, mouseY: Int, state: Int) {
if (draggedTaskIndex != -1) {
val thirdWidth = width / 3
val taskStartY = 40
val taskHeight = 25
val newIndex = ((mouseY - taskStartY) / taskHeight).coerceIn(0, macro.tasks.size - 1)
if (newIndex != draggedTaskIndex) {
val task = macro.tasks.removeAt(draggedTaskIndex)
macro.tasks.add(newIndex, task)
selectedTaskIndex = newIndex
}
draggedTaskIndex = -1
}
super.mouseReleased(mouseX, mouseY, state)
}
fun Close() {
mc.displayGuiScreen(null)
}
}
sealed class MacroTask(val name: String) {
abstract fun getPreview(): String
}
class MoveTask(var direction: String, var hold: Boolean) : MacroTask("Move") {
override fun getPreview(): String = if (hold) "Hold $direction" else "Tap $direction"
}
class MouseTask(val action: String) : MacroTask("Mouse") {
override fun getPreview(): String = action
}
class ChatCommandTask(var command: String) : MacroTask("Command") {
override fun getPreview(): String = command
}
data class Macro(
val name: String,
val tasks: MutableList<MacroTask> = mutableListOf()
)

View File

@ -0,0 +1,127 @@
package com.github.itzilly.sbt.features.router
import com.github.itzilly.sbt.renderer.RenderFuncs
import java.awt.datatransfer.Clipboard
import java.awt.datatransfer.StringSelection
import com.github.itzilly.sbt.util.Chatterbox
import com.github.itzilly.sbt.util.SimpleChatMsg
import com.google.gson.Gson
import net.minecraft.client.Minecraft
import net.minecraft.client.settings.KeyBinding
import net.minecraft.util.BlockPos
import net.minecraftforge.client.event.RenderWorldLastEvent
import net.minecraftforge.fml.client.registry.ClientRegistry
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import net.minecraftforge.fml.common.gameevent.InputEvent
import org.lwjgl.input.Keyboard
import java.awt.Toolkit
import kotlin.math.round
object RouteBuilder {
var addNodeKeybind: KeyBinding
var deleteLastNodeKeybind: KeyBinding
var finishRouteKeybind: KeyBinding
var nodes: ArrayList<RouteNode> = ArrayList()
init {
addNodeKeybind = KeyBinding("key.addNode", Keyboard.KEY_ADD, "key.categories.sbt")
ClientRegistry.registerKeyBinding(addNodeKeybind)
deleteLastNodeKeybind = KeyBinding("key.removeLastNode", Keyboard.KEY_MINUS, "key.categories.sbt")
ClientRegistry.registerKeyBinding(deleteLastNodeKeybind)
finishRouteKeybind = KeyBinding("key.finishRoute", Keyboard.KEY_F4, "key.categories.sbt")
ClientRegistry.registerKeyBinding(finishRouteKeybind)
}
@SubscribeEvent
fun onKeyInput(event: InputEvent.KeyInputEvent) {
if (addNodeKeybind.isPressed) {
val mc = Minecraft.getMinecraft()
val x = round(mc.thePlayer.posX - 0.5).toInt()
val y = round(mc.thePlayer.posY).toInt() - 1
val z = round(mc.thePlayer.posZ - 0.5).toInt()
if (nodeExists(x, y, z)) {
Chatterbox.say(SimpleChatMsg("Node already exists!").red())
} else {
addNode(x, y, z)
Chatterbox.say("This is a string")
}
}
if (deleteLastNodeKeybind.isPressed) {
val wasRemoved = nodes.removeLastOrNull()
if (wasRemoved == null) {
val msg = SimpleChatMsg("There isn't a node to delete!")
Chatterbox.say(msg.red())
} else {
val msg = SimpleChatMsg("Removed previous node")
Chatterbox.say(msg.green())
}
}
if (finishRouteKeybind.isPressed) {
if (nodes.size == 0) {
val msg = SimpleChatMsg("There aren't any nodes to copy!")
Chatterbox.say(msg.red())
} else {
val jsonString = Gson().toJson(nodes)
val msg = SimpleChatMsg("String copied to clipboard!")
setClipboard(jsonString)
Chatterbox.say(msg.green())
}
}
}
@SubscribeEvent
fun renderBlockOverlay(event: RenderWorldLastEvent) {
val player = Minecraft.getMinecraft().thePlayer
for (marker: RouteNode in nodes) {
val pos = BlockPos(marker.x, marker.y, marker.z)
RenderFuncs.drawBlockOutline(player, pos, event.partialTicks)
RenderFuncs.drawBlockLine(pos, event.partialTicks)
}
}
fun addNode(x: Int, y: Int, z: Int) {
nodes.add(RouteNode(x, y, z, 0u, 1u, 0u, NodeOptions("${nodes.size + 1}")))
}
fun addNode(x: Int, y: Int, z: Int, r: UByte, g: UByte, b: UByte) {
nodes.add(RouteNode(x, y, z, r, g, b, NodeOptions("${nodes.size + 1}")))
}
fun setClipboard(s: String) {
val selection = StringSelection(s)
val clipboard: Clipboard = Toolkit.getDefaultToolkit().systemClipboard
clipboard.setContents(selection, selection)
}
}
data class RouteNode(
val x: Int,
val y: Int,
val z: Int,
val r: UByte,
val g: UByte,
val b: UByte,
val options: NodeOptions
)
data class NodeOptions(
val name: String
)
fun nodeExists(x: Int, y: Int, z: Int): Boolean {
return RouteBuilder.nodes.any { it.x == x && it.y == y && it.z == z }
}

View File

@ -0,0 +1,28 @@
package com.github.itzilly.sbt.features.router
object RouteMaker {
var markerList: ArrayList<RouteMarker> = ArrayList()
}
data class RouteMarker(
val x: Int,
val y: Int,
val z: Int,
val r: UByte,
val g: UByte,
val b: UByte,
val options: RouteOptions
)
data class RouteOptions(
val name: String
)
fun isPointInRouteList(routeList: ArrayList<RouteMarker>, x: Int, y: Int, z: Int): Boolean {
return routeList.any { it.x == x && it.y == y && it.z == z }
}

View File

@ -0,0 +1,11 @@
package com.github.itzilly.sbt.mixin;
import net.minecraft.client.settings.KeyBinding;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(KeyBinding.class)
public interface KeyBindingAccessor {
@Accessor("pressed")
void setPressed(boolean pressed);
}

View File

@ -1,16 +0,0 @@
package com.github.itzilly.sbt.mixin;
import net.minecraft.client.gui.GuiMainMenu;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(GuiMainMenu.class)
public class MixinGuiMainMenu {
@Inject(method = "initGui", at = @At("HEAD"))
public void onInitGui(CallbackInfo ci) {
// System.out.println("Hello from Main Menu!");
}
}

View File

@ -0,0 +1,188 @@
package com.github.itzilly.sbt.renderer
import com.github.itzilly.sbt.util.Vecd3
import net.minecraft.block.Block
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.GlStateManager
import net.minecraft.entity.Entity
import net.minecraft.util.AxisAlignedBB
import net.minecraft.util.BlockPos
import net.minecraft.util.EnumFacing
import org.lwjgl.opengl.GL11
import java.awt.Color
object RenderFuncs {
fun drawBlockOutline(entity: Entity, blockPos: BlockPos, partialTicks: Float, outlineColor: Int) {
val padding = 0.0020000000949949026
val entityX = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * partialTicks
val entityY = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * partialTicks
val entityZ = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * partialTicks
val world = Minecraft.getMinecraft().theWorld
val blockState = world.getBlockState(blockPos)
val block = blockState.block
val boundingBox = block.getCollisionBoundingBox(world, blockPos, blockState)
?: AxisAlignedBB(
blockPos.x.toDouble(), blockPos.y.toDouble(), blockPos.z.toDouble(),
blockPos.x + 1.0, blockPos.y + 1.0, blockPos.z + 1.0
).expand(padding, padding, padding)
// Convert integer color to r, g, b, a values
val r = (outlineColor shr 16 and 0xFF) / 255.0f
val g = (outlineColor shr 8 and 0xFF) / 255.0f
val b = (outlineColor and 0xFF) / 255.0f
val a = (outlineColor shr 24 and 0xFF) / 255.0f
GL11.glPushMatrix()
GlStateManager.disableTexture2D()
GlStateManager.depthMask(false)
GlStateManager.disableDepth()
GL11.glEnable(GL11.GL_BLEND)
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA)
GL11.glEnable(GL11.GL_LINE_SMOOTH)
GL11.glHint(GL11.GL_LINE_SMOOTH_HINT, GL11.GL_NICEST)
GL11.glLineWidth(2.0f)
// Set the color with alpha
GL11.glColor4f(r, g, b, a)
// Draw the outline using the bounding box
RenderUtils.drawBlock(boundingBox.offset(-entityX, -entityY, -entityZ), outlineColor, outlineColor)
GL11.glDisable(GL11.GL_LINE_SMOOTH)
GL11.glDisable(GL11.GL_BLEND)
GlStateManager.enableDepth()
GlStateManager.depthMask(true)
GlStateManager.enableAlpha()
GlStateManager.enableTexture2D()
GL11.glPopMatrix()
}
fun drawBlockOutline(entity: Entity, blockPos: BlockPos, partialTicks: Float) {
val padding: Double = 0.0020000000949949026
val entityX: Double = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * partialTicks
val entityY: Double = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * partialTicks
val entityZ: Double = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * partialTicks
val outlineStartColor = 0xFFFFFF
val outlineEndColor = 0xFFFFFF
val world = Minecraft.getMinecraft().theWorld
val blockState = world.getBlockState(blockPos)
val block: Block = blockState.block
// Create a default bounding box for blocks that don't have one
val boundingBox: AxisAlignedBB = block.getCollisionBoundingBox(world, blockPos, blockState)
?: AxisAlignedBB(
blockPos.x.toDouble(), blockPos.y.toDouble(), blockPos.z.toDouble(),
blockPos.x + 1.0, blockPos.y + 1.0, blockPos.z + 1.0
).expand(padding, padding, padding)
GL11.glPushMatrix()
GlStateManager.disableTexture2D()
GlStateManager.depthMask(false)
GlStateManager.disableDepth()
GL11.glEnable(GL11.GL_LINE_SMOOTH)
GL11.glHint(GL11.GL_LINE_SMOOTH_HINT, GL11.GL_NICEST)
GL11.glLineWidth(2.0f)
GL11.glShadeModel(GL11.GL_SMOOTH)
RenderUtils.drawBlock(boundingBox.offset(-entityX, -entityY, -entityZ), outlineStartColor, outlineEndColor)
GL11.glLineWidth(2.0f)
GL11.glDisable(GL11.GL_LINE_SMOOTH)
GlStateManager.enableDepth()
GlStateManager.depthMask(true)
GlStateManager.enableAlpha()
GlStateManager.enableTexture2D()
GL11.glPopMatrix()
}
fun drawBlockLine(pos: BlockPos, partialTicks: Float) {
val render = Minecraft.getMinecraft().renderViewEntity
val rm = Minecraft.getMinecraft().renderManager
// TODO: Fix this not working with view bobbing enabled
val pos1 = Vecd3(rm.viewerPosX, rm.viewerPosY + render.eyeHeight, rm.viewerPosZ)
val pos2 = Vecd3(
pos.x.toDouble() + 0.5, // Center of the block
pos.y.toDouble() + 0.5, // Center of the block
pos.z.toDouble() + 0.5 // Center of the block
)
val lineColor = Color(0xe310d5)
RenderUtils.drawLine(pos1, pos2, lineColor, 2, false, partialTicks)
}
fun drawClusterOutline(entity: Entity, positions: List<BlockPos>, partialTicks: Float, outlineColor: Int) {
val padding = 0.0020000000949949026
// Correctly calculate the player's interpolated position
val entityX = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * partialTicks
val entityY = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * partialTicks
val entityZ = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * partialTicks
val world = Minecraft.getMinecraft().theWorld
GL11.glPushMatrix()
GlStateManager.disableTexture2D()
GlStateManager.depthMask(false)
GlStateManager.disableDepth()
GL11.glEnable(GL11.GL_BLEND)
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA)
GL11.glEnable(GL11.GL_LINE_SMOOTH)
GL11.glHint(GL11.GL_LINE_SMOOTH_HINT, GL11.GL_NICEST)
GL11.glLineWidth(2.0f)
// Convert integer color to r, g, b, a values
val r = (outlineColor shr 16 and 0xFF) / 255.0f
val g = (outlineColor shr 8 and 0xFF) / 255.0f
val b = (outlineColor and 0xFF) / 255.0f
val a = (outlineColor shr 24 and 0xFF) / 255.0f
// Set the color with alpha
GL11.glColor4f(r, g, b, a)
// Iterate over the positions and draw the outline around each block
for (pos in positions) {
val blockState = world.getBlockState(pos)
val boundingBox = blockState.block.getCollisionBoundingBox(world, pos, blockState)
?: AxisAlignedBB(pos.x.toDouble(), pos.y.toDouble(), pos.z.toDouble(), pos.x + 1.0, pos.y + 1.0, pos.z + 1.0).expand(padding, padding, padding)
// Offset the bounding box by the interpolated player position
val offsetBoundingBox = boundingBox.offset(-entityX, -entityY, -entityZ)
// Check adjacent blocks and only draw faces that are exposed (not adjacent to another gemstone block)
if (!positions.contains(pos.add(1, 0, 0))) {
RenderUtils.drawBlockFace(offsetBoundingBox, EnumFacing.EAST, outlineColor)
}
if (!positions.contains(pos.add(-1, 0, 0))) {
RenderUtils.drawBlockFace(offsetBoundingBox, EnumFacing.WEST, outlineColor)
}
if (!positions.contains(pos.add(0, 1, 0))) {
RenderUtils.drawBlockFace(offsetBoundingBox, EnumFacing.UP, outlineColor)
}
if (!positions.contains(pos.add(0, -1, 0))) {
RenderUtils.drawBlockFace(offsetBoundingBox, EnumFacing.DOWN, outlineColor)
}
if (!positions.contains(pos.add(0, 0, 1))) {
RenderUtils.drawBlockFace(offsetBoundingBox, EnumFacing.SOUTH, outlineColor)
}
if (!positions.contains(pos.add(0, 0, -1))) {
RenderUtils.drawBlockFace(offsetBoundingBox, EnumFacing.NORTH, outlineColor)
}
}
GL11.glDisable(GL11.GL_LINE_SMOOTH)
GL11.glDisable(GL11.GL_BLEND)
GlStateManager.enableDepth()
GlStateManager.depthMask(true)
GlStateManager.enableAlpha()
GlStateManager.enableTexture2D()
GL11.glPopMatrix()
}
}

View File

@ -0,0 +1,319 @@
package com.github.itzilly.sbt.renderer
import com.github.itzilly.sbt.util.Vecd3
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.GlStateManager
import net.minecraft.client.renderer.Tessellator
import net.minecraft.client.renderer.WorldRenderer
import net.minecraft.client.renderer.vertex.DefaultVertexFormats
import net.minecraft.util.AxisAlignedBB
import net.minecraft.util.EnumFacing
import org.lwjgl.opengl.GL11
import java.awt.Color
object RenderUtils {
var TESSELLATOR: Tessellator = Tessellator.getInstance()
var WORLD_RENDERER: WorldRenderer = Tessellator.getInstance().worldRenderer
fun drawBlock(box: AxisAlignedBB, outlineStartColor: Int, outlineEndColor: Int) {
drawBlockTop(box, Color(outlineStartColor), Color(outlineEndColor));
drawBlockBottom(box, Color(outlineStartColor), Color(outlineEndColor));
drawBlockNorth(box, Color(outlineStartColor), Color(outlineEndColor));
drawBlockEast(box, Color(outlineStartColor), Color(outlineEndColor));
drawBlockSouth(box, Color(outlineStartColor), Color(outlineEndColor));
drawBlockWest(box, Color(outlineStartColor), Color(outlineEndColor));
}
private fun drawBlockTop(box: AxisAlignedBB, outlineStartColor: Color, outlineEndColor: Color) {
WORLD_RENDERER.begin(2, DefaultVertexFormats.POSITION_COLOR)
WORLD_RENDERER.pos(box.minX, box.maxY, box.minZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.maxX, box.maxY, box.minZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
WORLD_RENDERER.pos(box.maxX, box.maxY, box.maxZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.minX, box.maxY, box.maxZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
TESSELLATOR.draw()
}
private fun drawBlockBottom(box: AxisAlignedBB, outlineStartColor: Color, outlineEndColor: Color) {
WORLD_RENDERER.begin(2, DefaultVertexFormats.POSITION_COLOR)
WORLD_RENDERER.pos(box.maxX, box.minY, box.minZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.minX, box.minY, box.minZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
WORLD_RENDERER.pos(box.minX, box.minY, box.maxZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY, box.maxZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
TESSELLATOR.draw()
}
private fun drawBlockNorth(box: AxisAlignedBB, outlineStartColor: Color, outlineEndColor: Color) {
WORLD_RENDERER.begin(2, DefaultVertexFormats.POSITION_COLOR)
WORLD_RENDERER.pos(box.maxX, box.maxY, box.maxZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY, box.maxZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
WORLD_RENDERER.pos(box.minX, box.minY, box.maxZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.minX, box.maxY, box.maxZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
TESSELLATOR.draw()
}
private fun drawBlockEast(box: AxisAlignedBB, outlineStartColor: Color, outlineEndColor: Color) {
WORLD_RENDERER.begin(2, DefaultVertexFormats.POSITION_COLOR)
WORLD_RENDERER.pos(box.maxX, box.maxY, box.maxZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.maxX, box.maxY, box.minZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY, box.minZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY, box.maxZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
TESSELLATOR.draw()
}
private fun drawBlockSouth(box: AxisAlignedBB, outlineStartColor: Color, outlineEndColor: Color) {
WORLD_RENDERER.begin(2, DefaultVertexFormats.POSITION_COLOR)
WORLD_RENDERER.pos(box.minX, box.maxY, box.minZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.minX, box.minY, box.minZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY, box.minZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.maxX, box.maxY, box.minZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
TESSELLATOR.draw()
}
private fun drawBlockWest(box: AxisAlignedBB, outlineStartColor: Color, outlineEndColor: Color) {
WORLD_RENDERER.begin(2, DefaultVertexFormats.POSITION_COLOR)
WORLD_RENDERER.pos(box.minX, box.maxY, box.minZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.minX, box.maxY, box.maxZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
WORLD_RENDERER.pos(box.minX, box.minY, box.maxZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.minX, box.minY, box.minZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
TESSELLATOR.draw()
}
fun drawLine(p1: Vecd3, p2: Vecd3, color: Color, lineWidth: Int, depth: Boolean, partialTicks: Float) {
GlStateManager.disableCull()
val render = Minecraft.getMinecraft().renderViewEntity
val worldRenderer = TESSELLATOR.worldRenderer
val realX = render.lastTickPosX + (render.posX - render.lastTickPosX) * partialTicks
val realY = render.lastTickPosY + (render.posY - render.lastTickPosY) * partialTicks
val realZ = render.lastTickPosZ + (render.posZ - render.lastTickPosZ) * partialTicks
GlStateManager.pushMatrix()
GlStateManager.translate(-realX, -realY, -realZ)
GlStateManager.disableTexture2D()
GlStateManager.enableBlend()
GlStateManager.disableAlpha()
GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0)
GL11.glLineWidth(lineWidth.toFloat())
if (!depth) {
GL11.glDisable(GL11.GL_DEPTH_TEST)
GlStateManager.depthMask(false)
}
GlStateManager.color(color.red / 255f, color.green / 255f, color.blue / 255f, color.alpha / 255f)
worldRenderer.begin(GL11.GL_LINE_STRIP, DefaultVertexFormats.POSITION)
worldRenderer.pos(p1.x, p1.y, p1.z).endVertex()
worldRenderer.pos(p2.x, p2.y, p2.z).endVertex()
Tessellator.getInstance().draw()
GlStateManager.translate(realX, realY, realZ)
if (!depth) {
GL11.glEnable(GL11.GL_DEPTH_TEST)
GlStateManager.depthMask(true)
}
GlStateManager.disableBlend()
GlStateManager.enableAlpha()
GlStateManager.enableTexture2D()
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f)
GlStateManager.popMatrix()
GlStateManager.disableLighting()
GlStateManager.enableCull()
}
fun drawAnimatedBlockTop(box: AxisAlignedBB, outlineStartColor: Color, outlineEndColor: Color, time: Float) {
val offsetY = Math.sin(time.toDouble()).toFloat() * (box.maxY - box.minY) / 2.0f
WORLD_RENDERER.begin(2, DefaultVertexFormats.POSITION_COLOR)
WORLD_RENDERER.pos(box.minX, box.maxY + offsetY, box.minZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.maxX, box.maxY + offsetY, box.minZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
WORLD_RENDERER.pos(box.maxX, box.maxY + offsetY, box.maxZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.minX, box.maxY + offsetY, box.maxZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
TESSELLATOR.draw()
}
fun drawAnimatedBlockBottom(box: AxisAlignedBB, outlineStartColor: Color, outlineEndColor: Color, time: Float) {
val offsetY = Math.sin(time.toDouble()).toFloat() * (box.maxY - box.minY) / 2.0f
WORLD_RENDERER.begin(2, DefaultVertexFormats.POSITION_COLOR)
WORLD_RENDERER.pos(box.maxX, box.minY + offsetY, box.minZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.minX, box.minY + offsetY, box.minZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
WORLD_RENDERER.pos(box.minX, box.minY + offsetY, box.maxZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY + offsetY, box.maxZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
TESSELLATOR.draw()
}
fun drawAnimatedBlockNorth(box: AxisAlignedBB, outlineStartColor: Color, outlineEndColor: Color, time: Float) {
val offsetY = Math.sin(time.toDouble()).toFloat() * (box.maxY - box.minY) / 2.0f
WORLD_RENDERER.begin(2, DefaultVertexFormats.POSITION_COLOR)
WORLD_RENDERER.pos(box.maxX, box.maxY + offsetY, box.maxZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY + offsetY, box.maxZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
WORLD_RENDERER.pos(box.minX, box.minY + offsetY, box.maxZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.minX, box.maxY + offsetY, box.maxZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
TESSELLATOR.draw()
}
fun drawAnimatedBlockEast(box: AxisAlignedBB, outlineStartColor: Color, outlineEndColor: Color, time: Float) {
val offsetY = Math.sin(time.toDouble()).toFloat() * (box.maxY - box.minY) / 2.0f
WORLD_RENDERER.begin(2, DefaultVertexFormats.POSITION_COLOR)
WORLD_RENDERER.pos(box.maxX, box.maxY + offsetY, box.maxZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.maxX, box.maxY + offsetY, box.minZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY + offsetY, box.minZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY + offsetY, box.maxZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
TESSELLATOR.draw()
}
fun drawAnimatedBlockSouth(box: AxisAlignedBB, outlineStartColor: Color, outlineEndColor: Color, time: Float) {
val offsetY = Math.sin(time.toDouble()).toFloat() * (box.maxY - box.minY) / 2.0f
WORLD_RENDERER.begin(2, DefaultVertexFormats.POSITION_COLOR)
WORLD_RENDERER.pos(box.minX, box.maxY + offsetY, box.minZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.minX, box.minY + offsetY, box.minZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY + offsetY, box.minZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.maxX, box.maxY + offsetY, box.minZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
TESSELLATOR.draw()
}
fun drawAnimatedBlockWest(box: AxisAlignedBB, outlineStartColor: Color, outlineEndColor: Color, time: Float) {
val offsetY = Math.sin(time.toDouble()).toFloat() * (box.maxY - box.minY) / 2.0f
WORLD_RENDERER.begin(2, DefaultVertexFormats.POSITION_COLOR)
WORLD_RENDERER.pos(box.minX, box.maxY + offsetY, box.minZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.minX, box.maxY + offsetY, box.maxZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
WORLD_RENDERER.pos(box.minX, box.minY + offsetY, box.maxZ)
.color(outlineStartColor.red, outlineStartColor.green, outlineStartColor.blue, outlineStartColor.alpha)
.endVertex()
WORLD_RENDERER.pos(box.minX, box.minY + offsetY, box.minZ)
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
TESSELLATOR.draw()
}
fun drawBlockFace(box: AxisAlignedBB, face: EnumFacing, color: Int) {
WORLD_RENDERER.begin(GL11.GL_LINE_STRIP, DefaultVertexFormats.POSITION_COLOR)
val r = (color shr 16 and 0xFF) / 255.0f
val g = (color shr 8 and 0xFF) / 255.0f
val b = (color and 0xFF) / 255.0f
val a = (color shr 24 and 0xFF) / 255.0f
GL11.glColor4f(r, g, b, a)
when (face) {
EnumFacing.UP -> {
WORLD_RENDERER.pos(box.minX, box.maxY, box.minZ).endVertex()
WORLD_RENDERER.pos(box.maxX, box.maxY, box.minZ).endVertex()
WORLD_RENDERER.pos(box.maxX, box.maxY, box.maxZ).endVertex()
WORLD_RENDERER.pos(box.minX, box.maxY, box.maxZ).endVertex()
WORLD_RENDERER.pos(box.minX, box.maxY, box.minZ).endVertex()
}
EnumFacing.DOWN -> {
WORLD_RENDERER.pos(box.minX, box.minY, box.minZ).endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY, box.minZ).endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY, box.maxZ).endVertex()
WORLD_RENDERER.pos(box.minX, box.minY, box.maxZ).endVertex()
WORLD_RENDERER.pos(box.minX, box.minY, box.minZ).endVertex()
}
EnumFacing.NORTH -> {
WORLD_RENDERER.pos(box.minX, box.minY, box.minZ).endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY, box.minZ).endVertex()
WORLD_RENDERER.pos(box.maxX, box.maxY, box.minZ).endVertex()
WORLD_RENDERER.pos(box.minX, box.maxY, box.minZ).endVertex()
WORLD_RENDERER.pos(box.minX, box.minY, box.minZ).endVertex()
}
EnumFacing.SOUTH -> {
WORLD_RENDERER.pos(box.minX, box.minY, box.maxZ).endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY, box.maxZ).endVertex()
WORLD_RENDERER.pos(box.maxX, box.maxY, box.maxZ).endVertex()
WORLD_RENDERER.pos(box.minX, box.maxY, box.maxZ).endVertex()
WORLD_RENDERER.pos(box.minX, box.minY, box.maxZ).endVertex()
}
EnumFacing.WEST -> {
WORLD_RENDERER.pos(box.minX, box.minY, box.minZ).endVertex()
WORLD_RENDERER.pos(box.minX, box.minY, box.maxZ).endVertex()
WORLD_RENDERER.pos(box.minX, box.maxY, box.maxZ).endVertex()
WORLD_RENDERER.pos(box.minX, box.maxY, box.minZ).endVertex()
WORLD_RENDERER.pos(box.minX, box.minY, box.minZ).endVertex()
}
EnumFacing.EAST -> {
WORLD_RENDERER.pos(box.maxX, box.minY, box.minZ).endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY, box.maxZ).endVertex()
WORLD_RENDERER.pos(box.maxX, box.maxY, box.maxZ).endVertex()
WORLD_RENDERER.pos(box.maxX, box.maxY, box.minZ).endVertex()
WORLD_RENDERER.pos(box.maxX, box.minY, box.minZ).endVertex()
}
else -> {}
}
TESSELLATOR.draw()
}
}

View File

@ -0,0 +1,18 @@
package com.github.itzilly.sbt.renderer
import net.minecraft.client.Minecraft
import net.minecraft.util.BlockPos
import net.minecraftforge.client.event.RenderWorldLastEvent
class RenderableBlockOutline(val x: Int, val y: Int, val z: Int, val outlineColor: Int) {
fun renderOutline(event: RenderWorldLastEvent) {
val player = Minecraft.getMinecraft().thePlayer
val pos = BlockPos(x, y, z)
RenderFuncs.drawBlockOutline(player, pos, event.partialTicks, outlineColor)
}
fun renderLine(event: RenderWorldLastEvent) {
val pos = BlockPos(x, y, z)
RenderFuncs.drawBlockLine(pos, event.partialTicks)
}
}

View File

@ -0,0 +1,41 @@
package com.github.itzilly.sbt.util
import net.minecraft.client.Minecraft
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.util.ChatComponentText
import net.minecraft.util.ChatStyle
import net.minecraft.util.EnumChatFormatting
import net.minecraft.util.IChatComponent
object Chatterbox {
private const val prefixString = "[SBT] "
private val prefixColorStyle = ChatStyle().setColor(EnumChatFormatting.AQUA)
private val prefixComponent = ChatComponentText(prefixString).setChatStyle(prefixColorStyle)
private val player = Minecraft.getMinecraft().thePlayer
private fun copy(component: IChatComponent): IChatComponent {
val newComponent = ChatComponentText(component.unformattedTextForChat)
newComponent.chatStyle = component.chatStyle.createShallowCopy()
component.siblings.forEach { sibling ->
newComponent.appendSibling(copy(sibling))
}
return newComponent
}
fun say(msg: String) {
val messageComponent = ChatComponentText(msg).setChatStyle(ChatStyle().setColor(EnumChatFormatting.RESET))
player.addChatMessage(prefixComponent.createCopy().appendSibling(messageComponent))
}
fun say(component: ChatComponentText) {
player.addChatMessage(copy(prefixComponent).appendSibling(copy(component)))
}
fun say(component: IChatComponent) {
player.addChatMessage(copy(prefixComponent).appendSibling(copy(component)))
}
fun say(player: EntityPlayer, component: IChatComponent) {
player.addChatMessage(copy(prefixComponent).appendSibling(copy(component)))
}
}

View File

@ -0,0 +1,25 @@
package com.github.itzilly.sbt.util
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import net.minecraftforge.fml.common.gameevent.TickEvent
class DelayedFunction(private val function: () -> Unit, private val delayTicks: Int) {
private var ticksLeft: Int = delayTicks
init {
MinecraftForge.EVENT_BUS.register(this)
}
@SubscribeEvent
fun onClientTick(event: TickEvent.ClientTickEvent) {
if (ticksLeft > 0) {
ticksLeft--
if (ticksLeft == 0) {
function()
MinecraftForge.EVENT_BUS.unregister(this)
}
}
}
}

View File

@ -0,0 +1,22 @@
package com.github.itzilly.sbt.util
import net.minecraft.util.IChatComponent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent
object MessageScheduler {
private val components: MutableList<IChatComponent> = mutableListOf()
@SubscribeEvent
fun onPlayerLoggedIn(event: PlayerLoggedInEvent) {
val player = event.player
for (component in components) {
Chatterbox.say(player, component)
}
components.clear() // Clear the list after sending the messages
}
fun sayWhenReady(component: IChatComponent) {
components.add(component)
}
}

View File

@ -0,0 +1,146 @@
package com.github.itzilly.sbt.util
import net.minecraft.util.ChatComponentText
import net.minecraft.util.ChatStyle
import net.minecraft.util.EnumChatFormatting.BLACK
import net.minecraft.util.EnumChatFormatting.DARK_BLUE
import net.minecraft.util.EnumChatFormatting.DARK_GREEN
import net.minecraft.util.EnumChatFormatting.DARK_AQUA
import net.minecraft.util.EnumChatFormatting.DARK_RED
import net.minecraft.util.EnumChatFormatting.DARK_PURPLE
import net.minecraft.util.EnumChatFormatting.GOLD
import net.minecraft.util.EnumChatFormatting.GRAY
import net.minecraft.util.EnumChatFormatting.DARK_GRAY
import net.minecraft.util.EnumChatFormatting.BLUE
import net.minecraft.util.EnumChatFormatting.GREEN
import net.minecraft.util.EnumChatFormatting.AQUA
import net.minecraft.util.EnumChatFormatting.RED
import net.minecraft.util.EnumChatFormatting.LIGHT_PURPLE
import net.minecraft.util.EnumChatFormatting.YELLOW
import net.minecraft.util.EnumChatFormatting.WHITE
import net.minecraft.util.EnumChatFormatting.OBFUSCATED
import net.minecraft.util.EnumChatFormatting.BOLD
import net.minecraft.util.EnumChatFormatting.STRIKETHROUGH
import net.minecraft.util.EnumChatFormatting.UNDERLINE
import net.minecraft.util.EnumChatFormatting.ITALIC
import net.minecraft.util.EnumChatFormatting.RESET
import net.minecraft.util.IChatComponent
class SimpleChatMsg(msg: String) {
private var component: IChatComponent
init {
component = ChatComponentText(msg)
}
fun default(): IChatComponent {
component.chatStyle = ChatStyle().setColor(RESET)
return component
}
fun black(): IChatComponent {
component.chatStyle = ChatStyle().setColor(BLACK)
return component
}
fun dark_blue(): IChatComponent {
component.chatStyle = ChatStyle().setColor(DARK_BLUE)
return component
}
fun dark_green(): IChatComponent {
component.chatStyle = ChatStyle().setColor(DARK_GREEN)
return component
}
fun dark_aqua(): IChatComponent {
component.chatStyle = ChatStyle().setColor(DARK_AQUA)
return component
}
fun dark_red(): IChatComponent {
component.chatStyle = ChatStyle().setColor(DARK_RED)
return component
}
fun dark_purple(): IChatComponent {
component.chatStyle = ChatStyle().setColor(DARK_PURPLE)
return component
}
fun gold(): IChatComponent {
component.chatStyle = ChatStyle().setColor(GOLD)
return component
}
fun gray(): IChatComponent {
component.chatStyle = ChatStyle().setColor(GRAY)
return component
}
fun dark_gray(): IChatComponent {
component.chatStyle = ChatStyle().setColor(DARK_GRAY)
return component
}
fun blue(): IChatComponent {
component.chatStyle = ChatStyle().setColor(BLUE)
return component
}
fun green(): IChatComponent {
component.chatStyle = ChatStyle().setColor(GREEN)
return component
}
fun aqua(): IChatComponent {
component.chatStyle = ChatStyle().setColor(AQUA)
return component
}
fun red(): IChatComponent {
component.chatStyle = ChatStyle().setColor(RED)
return component
}
fun light_purple(): IChatComponent {
component.chatStyle = ChatStyle().setColor(LIGHT_PURPLE)
return component
}
fun yellow(): IChatComponent {
component.chatStyle = ChatStyle().setColor(YELLOW)
return component
}
fun white(): IChatComponent {
component.chatStyle = ChatStyle().setColor(WHITE)
return component
}
fun obfuscated(): IChatComponent {
component.chatStyle = ChatStyle().setColor(OBFUSCATED)
return component
}
fun bold(): IChatComponent {
component.chatStyle = ChatStyle().setColor(BOLD)
return component
}
fun strikethrough(): IChatComponent {
component.chatStyle = ChatStyle().setColor(STRIKETHROUGH)
return component
}
fun underline(): IChatComponent {
component.chatStyle = ChatStyle().setColor(UNDERLINE)
return component
}
fun italic(): IChatComponent {
component.chatStyle = ChatStyle().setColor(ITALIC)
return component
}
}

View File

@ -0,0 +1,4 @@
package com.github.itzilly.sbt.util
data class Vecd3(val x:Double, val y:Double, val z:Double)
data class Vecf3(val x:Float, val y:Float, val z:Float)

View File

@ -1,14 +1,14 @@
[
{
"modid": "${modid}",
"name": "Xample Mod",
"description": "A mod that is used as an example.",
"name": "SkyBlock Tweaks",
"description": "Utilities for making Hypixel Skyblock more bearable",
"version": "${version}",
"mcversion": "${mcversion}",
"url": "https://github.com/romangraef/Forge1.8.9Template/",
"url": "http://itzilly.com/illyum/illyum/sbt-stash/",
"updateUrl": "",
"authorList": [
"You"
"itzilly"
],
"credits": "",
"logoFile": "",