v4.0
This commit is contained in:
1 parent
a879458b4a
commit
05c5300cd8
11 files changed
+480
-17
No files matched your search
+4
-4
@@ -1,4 +1,4 @@
|
|||||||
# v3.9
|
# v4.0
|
||||||
|
|
||||||
## novedades
|
## novedades
|
||||||
|
|
||||||
@@ -6,12 +6,12 @@
|
|||||||
|
|
||||||
#### módulos nuevos:
|
#### módulos nuevos:
|
||||||
|
|
||||||
- escaleras veloces: sube escaleras más rápido
|
- aura de cristales: hace cpvp por ti (muy mejorable, estoy en ello)
|
||||||
- parkour: salta automáticamente
|
|
||||||
- confetti: cambia el color de las partículas del pop del tótem
|
|
||||||
|
|
||||||
### arreglos / mejoras
|
### arreglos / mejoras
|
||||||
|
|
||||||
|
- `$echest` ya funciona y tal
|
||||||
|
|
||||||
## problemas reconocidos
|
## problemas reconocidos
|
||||||
|
|
||||||
- lo de siempre
|
- lo de siempre
|
||||||
+1
-1
@@ -10,6 +10,6 @@ fabric_api_version=0.140.2+1.21.11
|
|||||||
|
|
||||||
neutrino_version=1.1.0
|
neutrino_version=1.1.0
|
||||||
|
|
||||||
mod_version=3.9
|
mod_version=4.0
|
||||||
maven_group=me.retucio
|
maven_group=me.retucio
|
||||||
archives_base_name=sputnik
|
archives_base_name=sputnik
|
||||||
@@ -96,6 +96,8 @@ public class Sputnik implements ClientModInitializer {
|
|||||||
EVENT_BUS.subscribe(NetworkUtil.class);
|
EVENT_BUS.subscribe(NetworkUtil.class);
|
||||||
EVENT_BUS.subscribe(RenderUtil.class);
|
EVENT_BUS.subscribe(RenderUtil.class);
|
||||||
|
|
||||||
|
EVENT_BUS.subscribe(BlockIterator.class);
|
||||||
|
|
||||||
Lists.init();
|
Lists.init();
|
||||||
Textures.init();
|
Textures.init();
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,7 @@ import me.retucio.sputnik.Sputnik;
|
|||||||
import me.retucio.sputnik.module.modules.client.DiscordRPC;
|
import me.retucio.sputnik.module.modules.client.DiscordRPC;
|
||||||
import me.retucio.sputnik.module.modules.client.HUD;
|
import me.retucio.sputnik.module.modules.client.HUD;
|
||||||
import me.retucio.sputnik.module.modules.camera.*;
|
import me.retucio.sputnik.module.modules.camera.*;
|
||||||
import me.retucio.sputnik.module.modules.combat.AttributeSwapper;
|
import me.retucio.sputnik.module.modules.combat.*;
|
||||||
import me.retucio.sputnik.module.modules.combat.MaceKill;
|
|
||||||
import me.retucio.sputnik.module.modules.combat.ProjectileTrajectories;
|
|
||||||
import me.retucio.sputnik.module.modules.combat.SpearKill;
|
|
||||||
import me.retucio.sputnik.module.modules.inventory.*;
|
import me.retucio.sputnik.module.modules.inventory.*;
|
||||||
import me.retucio.sputnik.module.modules.misc.*;
|
import me.retucio.sputnik.module.modules.misc.*;
|
||||||
import me.retucio.sputnik.module.modules.movement.*;
|
import me.retucio.sputnik.module.modules.movement.*;
|
||||||
@@ -40,6 +37,7 @@ public class ModuleManager {
|
|||||||
// añadir los módulos
|
// añadir los módulos
|
||||||
addCamera();
|
addCamera();
|
||||||
addClient();
|
addClient();
|
||||||
|
addCombat();
|
||||||
addInventory();
|
addInventory();
|
||||||
addMisc();
|
addMisc();
|
||||||
addMovement();
|
addMovement();
|
||||||
@@ -67,7 +65,6 @@ public class ModuleManager {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void addCamera() {
|
private void addCamera() {
|
||||||
add(new Autism());
|
add(new Autism());
|
||||||
add(new Freecam());
|
add(new Freecam());
|
||||||
@@ -83,6 +80,14 @@ public class ModuleManager {
|
|||||||
add(new HUD());
|
add(new HUD());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addCombat() {
|
||||||
|
add(new AttributeSwapper());
|
||||||
|
add(new CrystalAura());
|
||||||
|
add(new MaceKill());
|
||||||
|
add(new ProjectileTrajectories());
|
||||||
|
add(new SpearKill());
|
||||||
|
}
|
||||||
|
|
||||||
private void addMisc() {
|
private void addMisc() {
|
||||||
add(new AntiInvis());
|
add(new AntiInvis());
|
||||||
add(new AnvilFont());
|
add(new AnvilFont());
|
||||||
@@ -138,15 +143,12 @@ public class ModuleManager {
|
|||||||
private void addPlayer() {
|
private void addPlayer() {
|
||||||
add(new AirPlace());
|
add(new AirPlace());
|
||||||
add(new AntiHunger());
|
add(new AntiHunger());
|
||||||
add(new AttributeSwapper());
|
|
||||||
add(new AutoFish());
|
add(new AutoFish());
|
||||||
add(new Capes());
|
add(new Capes());
|
||||||
add(new FastUse());
|
add(new FastUse());
|
||||||
add(new HandView());
|
add(new HandView());
|
||||||
add(new KeyPearl());
|
add(new KeyPearl());
|
||||||
add(new MaceKill());
|
|
||||||
add(new NoFall());
|
add(new NoFall());
|
||||||
add(new SpearKill());
|
|
||||||
add(new WarnLowDurability());
|
add(new WarnLowDurability());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,7 +177,6 @@ public class ModuleManager {
|
|||||||
add(new ColoredSigns());
|
add(new ColoredSigns());
|
||||||
add(new LightOverlay());
|
add(new LightOverlay());
|
||||||
add(new NoMiningInterruptions());
|
add(new NoMiningInterruptions());
|
||||||
add(new ProjectileTrajectories());
|
|
||||||
add(new Racist());
|
add(new Racist());
|
||||||
add(new StrongholdTriangulator());
|
add(new StrongholdTriangulator());
|
||||||
add(new TimeChanger());
|
add(new TimeChanger());
|
||||||
|
|||||||
@@ -0,0 +1,295 @@
|
|||||||
|
package me.retucio.sputnik.module.modules.combat;
|
||||||
|
|
||||||
|
import com.github.retucio.neutrino.EventListener;
|
||||||
|
import me.retucio.sputnik.event.render.Render3DEvent;
|
||||||
|
import me.retucio.sputnik.module.Category;
|
||||||
|
import me.retucio.sputnik.module.Module;
|
||||||
|
import me.retucio.sputnik.module.setting.SettingGroup;
|
||||||
|
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
|
||||||
|
import me.retucio.sputnik.module.setting.settings.ColorSetting;
|
||||||
|
import me.retucio.sputnik.module.setting.settings.ListSetting;
|
||||||
|
import me.retucio.sputnik.module.setting.settings.NumberSetting;
|
||||||
|
import me.retucio.sputnik.util.*;
|
||||||
|
import me.retucio.sputnik.util.render.RenderUtil;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.decoration.EndCrystalEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
|
import net.minecraft.util.hit.HitResult;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.RaycastContext;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author retucio
|
||||||
|
*/
|
||||||
|
public class CrystalAura extends Module {
|
||||||
|
|
||||||
|
private final SettingGroup sgPlace = addSg(new SettingGroup("colocar", false));
|
||||||
|
private final SettingGroup sgBreak = addSg(new SettingGroup("reventar", false));
|
||||||
|
private final SettingGroup sgRender = addSg(new SettingGroup("renderizado", false));
|
||||||
|
|
||||||
|
private final ListSetting<EntityType<?>> entities = sgGeneral.add(new ListSetting<>(
|
||||||
|
"entidades", "entidades a las que atacar",
|
||||||
|
Lists.entityList, Lists.allFalseExcept(Lists.entityList, EntityType.PLAYER), Lists.entityNames
|
||||||
|
));
|
||||||
|
|
||||||
|
private final NumberSetting targetRange = sgGeneral.add(new NumberSetting(
|
||||||
|
"rango",
|
||||||
|
"rango de detección de blancos",
|
||||||
|
5, 0, 12, 0.1
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
// ajustes al colocar los cristales
|
||||||
|
|
||||||
|
private final BooleanSetting placeCrystals = sgPlace.add(new BooleanSetting(
|
||||||
|
"colocar", "colocar los cristales", true
|
||||||
|
));
|
||||||
|
|
||||||
|
private final NumberSetting placeDelay = sgPlace.add(new NumberSetting(
|
||||||
|
"delay", "delay entre cristal y cristal",
|
||||||
|
0, 0, 20, 1
|
||||||
|
)).visibility(placeCrystals::getValue);
|
||||||
|
|
||||||
|
private final NumberSetting placeRange = sgPlace.add(new NumberSetting(
|
||||||
|
"rango ", "rango máximo para colocar cristales",
|
||||||
|
4.5, 0, 6, 0.1
|
||||||
|
)).visibility(placeCrystals::getValue);
|
||||||
|
|
||||||
|
private final BooleanSetting rotateToPlace = sgPlace.add(new BooleanSetting(
|
||||||
|
"rotar", "rotar para colocar cristales", false
|
||||||
|
)).visibility(placeCrystals::getValue);
|
||||||
|
|
||||||
|
private final BooleanSetting autoSelect = sgPlace.add(new BooleanSetting(
|
||||||
|
"autoseleccionar", "seleccionar cristales automáticamente", true
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
// ajustes al reventar los cristales
|
||||||
|
|
||||||
|
private final BooleanSetting breakCrystals = sgBreak.add(new BooleanSetting(
|
||||||
|
"reventar", "reventar los cristales", true
|
||||||
|
));
|
||||||
|
|
||||||
|
private final NumberSetting breakDelay = sgBreak.add(new NumberSetting(
|
||||||
|
"delay ", "delay entre cristal y cristal",
|
||||||
|
0, 0, 20, 1
|
||||||
|
)).visibility(breakCrystals::getValue);
|
||||||
|
|
||||||
|
private final BooleanSetting rotateToBreak = sgBreak.add(new BooleanSetting(
|
||||||
|
"rotar", "rotar para reventar cristales", false
|
||||||
|
)).visibility(breakCrystals::getValue);
|
||||||
|
|
||||||
|
|
||||||
|
// ajustes de renderizado
|
||||||
|
|
||||||
|
private final BooleanSetting outlines = sgRender.add(new BooleanSetting(
|
||||||
|
"contorno", "renderizar contorno del bloque donde se colocan los cristales", true
|
||||||
|
));
|
||||||
|
|
||||||
|
private final ColorSetting outlineColor = sgRender.add(new ColorSetting(
|
||||||
|
"color del contorno", "color del contorno",
|
||||||
|
Colors.mainColor, false
|
||||||
|
)).visibility(outlines::getValue);
|
||||||
|
|
||||||
|
private final NumberSetting outlineWidth = sgRender.add(new NumberSetting(
|
||||||
|
"grosor del contorno", "grosor del contorno",
|
||||||
|
2, 0, 15, 0.1
|
||||||
|
)).visibility(outlines::getValue);
|
||||||
|
|
||||||
|
private final BooleanSetting fillings = sgRender.add(new BooleanSetting(
|
||||||
|
"relleno", "renderizar relleno del bloque donde se colocan los cristales", false
|
||||||
|
));
|
||||||
|
|
||||||
|
private final ColorSetting fillingColor = sgRender.add(new ColorSetting(
|
||||||
|
"color del relleno", "color del relleno",
|
||||||
|
Colors.withAlpha(Colors.mainColor, 70), false
|
||||||
|
)).visibility(fillings::getValue);
|
||||||
|
|
||||||
|
|
||||||
|
private final List<LivingEntity> targets = new ArrayList<>();
|
||||||
|
private BlockPos bp = null;
|
||||||
|
|
||||||
|
private int placeTimer = placeDelay.getIntValue();
|
||||||
|
private int breakTimer = breakDelay.getIntValue();
|
||||||
|
|
||||||
|
|
||||||
|
public CrystalAura() {
|
||||||
|
super("aura de cristales",
|
||||||
|
"coloca y revienta cristales del end por ti", Category.COMBAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTick() {
|
||||||
|
if (mc.player == null || mc.interactionManager == null || mc.world == null || mc.getCameraEntity() == null) return;
|
||||||
|
|
||||||
|
if (placeTimer > 0) placeTimer--;
|
||||||
|
if (breakTimer > 0) breakTimer--;
|
||||||
|
|
||||||
|
findTargets();
|
||||||
|
|
||||||
|
if (!targets.isEmpty()) {
|
||||||
|
if (placeCrystals.getValue()) doPlace();
|
||||||
|
if (breakCrystals.getValue()) doBreak();
|
||||||
|
} else {
|
||||||
|
bp = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// colocar cristal
|
||||||
|
private void doPlace() {
|
||||||
|
if (placeTimer > 0) return;
|
||||||
|
|
||||||
|
if (!canPlaceCrystal()) {
|
||||||
|
bp = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// elegir como blanco primario la entidad más cercana
|
||||||
|
LivingEntity primaryTarget = null;
|
||||||
|
double closestTargetDist = Double.MAX_VALUE;
|
||||||
|
for (LivingEntity target : targets) {
|
||||||
|
double dist = mc.player.squaredDistanceTo(target);
|
||||||
|
if (dist < closestTargetDist) {
|
||||||
|
closestTargetDist = dist;
|
||||||
|
primaryTarget = target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (primaryTarget == null) {
|
||||||
|
bp = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Vec3d targetPos = primaryTarget.getEntityPos();
|
||||||
|
final BlockPos.Mutable[] bestPos = new BlockPos.Mutable[1];
|
||||||
|
final double[] bestDist = { Double.MAX_VALUE };
|
||||||
|
|
||||||
|
BlockIterator.register((int) Math.ceil(placeRange.getValue()), (int) Math.ceil(placeRange.getValue()), (pos, state) -> {
|
||||||
|
if (!state.isOf(Blocks.OBSIDIAN) && !state.isOf(Blocks.BEDROCK)) return;
|
||||||
|
if (!mc.world.isAir(pos.add(0, 1, 0))) return;
|
||||||
|
|
||||||
|
// cálculo de mejor distancia
|
||||||
|
double dist = targetPos.squaredDistanceTo(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
|
||||||
|
if (dist < bestDist[0]) {
|
||||||
|
bestDist[0] = dist;
|
||||||
|
if (bestPos[0] == null) bestPos[0] = new BlockPos.Mutable();
|
||||||
|
bestPos[0].set(pos);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
BlockIterator.after(() -> {
|
||||||
|
if (bestPos[0] != null) {
|
||||||
|
BlockHitResult result = getBlockInfo(bestPos[0]);
|
||||||
|
placeCrystal(result);
|
||||||
|
bp = bestPos[0].toImmutable(); // guardar para el renderizado
|
||||||
|
} else {
|
||||||
|
bp = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
placeTimer = placeDelay.getIntValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doBreak() {
|
||||||
|
if (breakTimer > 0) return;
|
||||||
|
for (Entity entity : mc.world.getEntities()) {
|
||||||
|
if (!(entity instanceof EndCrystalEntity) || entity.distanceTo(mc.player) > mc.player.getEntityInteractionRange()) continue;
|
||||||
|
if (rotateToBreak.getValue()) EntityUtil.lookAt(entity.getEyePos());
|
||||||
|
mc.interactionManager.attackEntity(mc.player, entity);
|
||||||
|
}
|
||||||
|
breakTimer = breakDelay.getIntValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void placeCrystal(BlockHitResult result) {
|
||||||
|
if (autoSelect.getValue()) {
|
||||||
|
int slot = InventoryUtil.findSlot(stack -> stack.isOf(Items.END_CRYSTAL));
|
||||||
|
if (slot != InventoryUtil.OFFHAND_SLOT) {
|
||||||
|
if (!PlayerInventory.isValidHotbarIndex(slot)) {
|
||||||
|
InventoryUtil.swapWithHotbar(slot, mc.player.getInventory().getSelectedSlot());
|
||||||
|
} else {
|
||||||
|
mc.player.getInventory().setSelectedSlot(slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Hand hand;
|
||||||
|
if (mc.player.getMainHandStack().isOf(Items.END_CRYSTAL)) {
|
||||||
|
hand = Hand.MAIN_HAND;
|
||||||
|
} else if (mc.player.getOffHandStack().isOf(Items.END_CRYSTAL)) {
|
||||||
|
hand = Hand.OFF_HAND;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rotateToPlace.getValue()) EntityUtil.lookAt(result.getBlockPos().toCenterPos());
|
||||||
|
mc.interactionManager.sendSequencedPacket(mc.world, (sequence) -> new PlayerInteractBlockC2SPacket(hand, result, sequence));
|
||||||
|
}
|
||||||
|
|
||||||
|
// encontrar blancos
|
||||||
|
private void findTargets() {
|
||||||
|
targets.clear();
|
||||||
|
for (Entity e : mc.world.getEntities()) {
|
||||||
|
if (!(e instanceof LivingEntity entity)) continue;
|
||||||
|
if (!entity.isAlive() || entity.isInCreativeMode() || entity.equals(mc.player)) continue;
|
||||||
|
if (!entities.isEnabled(entity.getType())) continue;
|
||||||
|
if (entity.squaredDistanceTo(mc.player) > targetRange.getValue() * targetRange.getValue()) continue;
|
||||||
|
targets.add(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BlockHitResult getBlockInfo(BlockPos pos) {
|
||||||
|
Vec3d start = new Vec3d(mc.player.getX(), mc.player.getY() + mc.player.getEyeHeight(mc.player.getPose()), mc.player.getZ());
|
||||||
|
Vec3d end;
|
||||||
|
|
||||||
|
for (Direction side : Direction.values()) {
|
||||||
|
end = new Vec3d(
|
||||||
|
pos.getX() + 0.5 + side.getVector().getX() * 0.5,
|
||||||
|
pos.getY() + 0.5 + side.getVector().getY() * 0.5,
|
||||||
|
pos.getZ() + 0.5 + side.getVector().getZ() * 0.5
|
||||||
|
);
|
||||||
|
|
||||||
|
BlockHitResult result = mc.world.raycast(new RaycastContext(
|
||||||
|
start, end, RaycastContext.ShapeType.COLLIDER, RaycastContext.FluidHandling.NONE, mc.player
|
||||||
|
));
|
||||||
|
|
||||||
|
if (result != null && result.getType() == HitResult.Type.BLOCK && result.getBlockPos().equals(pos)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Direction side = pos.getY() > start.y ? Direction.DOWN : Direction.UP;
|
||||||
|
return new BlockHitResult(start, side, pos, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canPlaceCrystal() {
|
||||||
|
if (autoSelect.getValue()) {
|
||||||
|
return InventoryUtil.findSlot(stack -> stack.isOf(Items.END_CRYSTAL)) != -1;
|
||||||
|
} else {
|
||||||
|
return InventoryUtil.hasInHotbar(Items.END_CRYSTAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventListener
|
||||||
|
private void onRenderWorld(Render3DEvent event) {
|
||||||
|
if (bp != null) {
|
||||||
|
if (outlines.getValue()) {
|
||||||
|
RenderUtil.drawBlockOutline(event.getMatrices(), bp, outlineColor.getValue(), outlineWidth.getFloatValue(), false);
|
||||||
|
}
|
||||||
|
if (fillings.getValue()) {
|
||||||
|
RenderUtil.drawBlockFilled(event.getMatrices(), bp, fillingColor.getValue(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -52,7 +52,7 @@ public class AutoFish extends Module {
|
|||||||
0,
|
0,
|
||||||
64,
|
64,
|
||||||
1
|
1
|
||||||
));
|
)).visibility(onlyRecastIfLookingAtWater::getValue);
|
||||||
|
|
||||||
private final BooleanSetting dontBreak = sgGeneral.add(new BooleanSetting(
|
private final BooleanSetting dontBreak = sgGeneral.add(new BooleanSetting(
|
||||||
"evitar romper",
|
"evitar romper",
|
||||||
@@ -71,8 +71,6 @@ public class AutoFish extends Module {
|
|||||||
onlyRecastIfLookingAtWater.visibility(v);
|
onlyRecastIfLookingAtWater.visibility(v);
|
||||||
recastRaycastDistance.visibility(v);
|
recastRaycastDistance.visibility(v);
|
||||||
});
|
});
|
||||||
|
|
||||||
onlyRecastIfLookingAtWater.onUpdate(v -> recastRaycastDistance.visibility(v));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client).
|
||||||
|
* Copyright (c) Meteor Development.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.retucio.sputnik.util;
|
||||||
|
|
||||||
|
import com.github.retucio.neutrino.EventListener;
|
||||||
|
import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
|
||||||
|
import me.retucio.sputnik.Sputnik;
|
||||||
|
import me.retucio.sputnik.event.TickEvent;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
|
// https://github.com/MeteorDevelopment/meteor-client/blob/master/src/main/java/meteordevelopment/meteorclient/utils/world/BlockIterator.java
|
||||||
|
public class BlockIterator {
|
||||||
|
|
||||||
|
private static final Pool<Callback> callbackPool = new Pool<>(Callback::new);
|
||||||
|
private static final List<Callback> callbacks = new ReferenceArrayList<>();
|
||||||
|
|
||||||
|
private static final List<Runnable> afterCallbacks = new ReferenceArrayList<>();
|
||||||
|
|
||||||
|
private static final BlockPos.Mutable blockPos = new BlockPos.Mutable();
|
||||||
|
private static int hRadius, vRadius;
|
||||||
|
|
||||||
|
private static boolean disableCurrent;
|
||||||
|
|
||||||
|
private BlockIterator() {}
|
||||||
|
|
||||||
|
@EventListener()
|
||||||
|
private static void onTick(TickEvent.Pre event) {
|
||||||
|
MinecraftClient mc = MinecraftClient.getInstance();
|
||||||
|
if (mc.player == null) return;
|
||||||
|
|
||||||
|
int px = mc.player.getBlockX();
|
||||||
|
int py = mc.player.getBlockY();
|
||||||
|
int pz = mc.player.getBlockZ();
|
||||||
|
|
||||||
|
for (int x = px - hRadius; x <= px + hRadius; x++) {
|
||||||
|
for (int z = pz - hRadius; z <= pz + hRadius; z++) {
|
||||||
|
for (int y = Math.max(mc.world.getBottomY(), py - vRadius); y <= py + vRadius; y++) {
|
||||||
|
if (y > mc.world.getHeight()) break;
|
||||||
|
|
||||||
|
blockPos.set(x, y, z);
|
||||||
|
BlockState blockState = mc.world.getBlockState(blockPos);
|
||||||
|
|
||||||
|
int dx = Math.abs(x - px);
|
||||||
|
int dy = Math.abs(y - py);
|
||||||
|
int dz = Math.abs(z - pz);
|
||||||
|
|
||||||
|
callbacks.removeIf(callback -> {
|
||||||
|
if (dx <= callback.hRadius && dy <= callback.vRadius && dz <= callback.hRadius) {
|
||||||
|
disableCurrent = false;
|
||||||
|
callback.function.accept(blockPos, blockState);
|
||||||
|
return disableCurrent;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hRadius = 0;
|
||||||
|
vRadius = 0;
|
||||||
|
|
||||||
|
callbackPool.freeAll(callbacks);
|
||||||
|
callbacks.clear();
|
||||||
|
|
||||||
|
for (Runnable callback : afterCallbacks) callback.run();
|
||||||
|
afterCallbacks.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void register(int horizontalRadius, int verticalRadius, BiConsumer<BlockPos, BlockState> function) {
|
||||||
|
hRadius = Math.max(hRadius, horizontalRadius);
|
||||||
|
vRadius = Math.max(vRadius, verticalRadius);
|
||||||
|
|
||||||
|
Callback callback = callbackPool.get();
|
||||||
|
|
||||||
|
callback.function = function;
|
||||||
|
callback.hRadius = horizontalRadius;
|
||||||
|
callback.vRadius = verticalRadius;
|
||||||
|
|
||||||
|
callbacks.add(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void disableCurrent() {
|
||||||
|
disableCurrent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void after(Runnable callback) {
|
||||||
|
afterCallbacks.add(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Callback {
|
||||||
|
public BiConsumer<BlockPos, BlockState> function;
|
||||||
|
public int hRadius, vRadius;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package me.retucio.sputnik.util;
|
package me.retucio.sputnik.util;
|
||||||
|
|
||||||
|
import com.github.retucio.neutrino.EventListener;
|
||||||
|
import com.google.common.eventbus.Subscribe;
|
||||||
import me.retucio.sputnik.event.network.DisconnectEvent;
|
import me.retucio.sputnik.event.network.DisconnectEvent;
|
||||||
import me.retucio.sputnik.event.interact.OpenScreenEvent;
|
import me.retucio.sputnik.event.interact.OpenScreenEvent;
|
||||||
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
|
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
|
||||||
@@ -332,6 +334,18 @@ public class InventoryUtil {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean hasInHotbar(Item item) {
|
||||||
|
List<ItemStack> stacks = findAll(stack -> stack.isOf(item));
|
||||||
|
for (ItemStack stack : stacks) {
|
||||||
|
int slot = mc.player.getInventory().getSlotWithStack(stack);
|
||||||
|
if (slot < HOTBAR_END || slot == OFFHAND_SLOT) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventListener
|
||||||
public static void onOpenScreen(OpenScreenEvent event) {
|
public static void onOpenScreen(OpenScreenEvent event) {
|
||||||
if (mc.player == null
|
if (mc.player == null
|
||||||
|| event.getScreen() == null
|
|| event.getScreen() == null
|
||||||
@@ -343,6 +357,7 @@ public class InventoryUtil {
|
|||||||
echestInv = handler.getInventory();
|
echestInv = handler.getInventory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventListener
|
||||||
public void onDisconnect(DisconnectEvent event) {
|
public void onDisconnect(DisconnectEvent event) {
|
||||||
echestInv = null;
|
echestInv = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,12 +87,26 @@ public class Lists {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public static <T> Map<T, Boolean> allTrueExcept(List<T> options, T... exceptions) {
|
||||||
|
Map<T, Boolean> map = allFalse(options);
|
||||||
|
for (T exception : exceptions) map.replace(exception, false);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
public static <T> Map<T, Boolean> allFalse(List<T> options) {
|
public static <T> Map<T, Boolean> allFalse(List<T> options) {
|
||||||
Map<T, Boolean> map = new HashMap<>();
|
Map<T, Boolean> map = new HashMap<>();
|
||||||
for (T option : options) map.put(option, false);
|
for (T option : options) map.put(option, false);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public static <T> Map<T, Boolean> allFalseExcept(List<T> options, T... exceptions) {
|
||||||
|
Map<T, Boolean> map = allFalse(options);
|
||||||
|
for (T exception : exceptions) map.replace(exception, true);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
public static <T> Map<T, String> getMapOfLists(List<T> options, List<String> names) {
|
public static <T> Map<T, String> getMapOfLists(List<T> options, List<String> names) {
|
||||||
Map<T, String> result = new HashMap<>();
|
Map<T, String> result = new HashMap<>();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package me.retucio.sputnik.util;
|
||||||
|
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
// https://github.com/MeteorDevelopment/meteor-client/blob/master/src/main/java/meteordevelopment/meteorclient/utils/misc/Pool.java
|
||||||
|
public final class Pool<T> {
|
||||||
|
|
||||||
|
private final Queue<T> items = new ArrayDeque<>();
|
||||||
|
private final Supplier<T> producer;
|
||||||
|
|
||||||
|
public Pool(Supplier<T> producer) {
|
||||||
|
this.producer = producer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized T get() {
|
||||||
|
if (!items.isEmpty()) return items.poll();
|
||||||
|
return producer.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void free(T obj) {
|
||||||
|
items.offer(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void freeAll(Iterable<T> objects) {
|
||||||
|
if (objects instanceof Collection<T> collection) {
|
||||||
|
items.addAll(collection);
|
||||||
|
} else {
|
||||||
|
objects.forEach(items::add);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -94,6 +94,7 @@ public class RenderUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void drawBlockFaceOutlines(MatrixStack matrices, BlockPos pos, Direction face, Color color, float lineWidth, boolean cull) {
|
public static void drawBlockFaceOutlines(MatrixStack matrices, BlockPos pos, Direction face, Color color, float lineWidth, boolean cull) {
|
||||||
|
if (lineWidth <= 0) return;
|
||||||
Vec3d cameraPos = mc.gameRenderer.getCamera().getCameraPos();
|
Vec3d cameraPos = mc.gameRenderer.getCamera().getCameraPos();
|
||||||
|
|
||||||
float minX = (float) (pos.getX() - cameraPos.x);
|
float minX = (float) (pos.getX() - cameraPos.x);
|
||||||
@@ -295,6 +296,7 @@ public class RenderUtil {
|
|||||||
// cajas
|
// cajas
|
||||||
|
|
||||||
public static void drawOutlineBox(MatrixStack matrices, Box box, Color color, float lineWidth, boolean cull) {
|
public static void drawOutlineBox(MatrixStack matrices, Box box, Color color, float lineWidth, boolean cull) {
|
||||||
|
if (lineWidth <= 0) return;
|
||||||
Vec3d cameraPos = mc.gameRenderer.getCamera().getCameraPos();
|
Vec3d cameraPos = mc.gameRenderer.getCamera().getCameraPos();
|
||||||
|
|
||||||
float minX = (float) (box.minX - cameraPos.x);
|
float minX = (float) (box.minX - cameraPos.x);
|
||||||
|
|||||||
Reference in new issue
Block a user