- Выберите загрузчик игры
- Vanilla
Пожалуйста, авторизуйтесь для просмотра ссылки.
Java:
package im.expensive.functions.impl.combat;
import com.google.common.eventbus.Subscribe;
import im.expensive.functions.api.Function;
import im.expensive.functions.api.FunctionRegister;
import im.expensive.functions.settings.impl.SliderSetting;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.*;
import net.minecraft.util.Direction;
import net.minecraft.util.math.*;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import org.lwjgl.opengl.GL11;
import im.expensive.events.WorldEvent;
import im.expensive.functions.api.Category;
@FunctionRegister(name = "HitCircle", type = Category.Combat)
public class HitCircle extends Function {
private final Minecraft mc = Minecraft.getInstance();
private final SliderSetting circleRadius = new SliderSetting("Радиус круга", 0.3f, 0.1f, 1.0f, 0.01f);
private final SliderSetting lineThickness = new SliderSetting("Толщина линии", 2.0f, 0.5f, 5.0f, 0.1f);
public HitCircle() {
this.addSettings(circleRadius, lineThickness);
}
@Subscribe
public void onRenderWorld(WorldEvent event) {
if (mc.player == null || mc.world == null) return;
PlayerEntity player = mc.player;
ItemStack held = player.getHeldItemMainhand();
Item item = held.getItem();
if (!(item instanceof BowItem || item instanceof CrossbowItem ||
item instanceof TridentItem || item instanceof EnderPearlItem)) return;
Vector3d eyePos = player.getEyePosition(event.getPartialTicks());
Vector3d lookVec = player.getLookVec();
float power = 3f;
float gravity = 0.05f;
float[] color = {0.2f, 1f, 0.2f}; // Зеленый по умолчанию
if (item instanceof BowItem) {
int useTicks = player.getItemInUseCount();
float draw = useTicks / 20f;
draw = (draw * draw + draw * 2f) / 3f;
if (draw > 1f) draw = 1f;
power = draw * 3f;
}
else if (item instanceof CrossbowItem) {
power = 3.15f;
if (EnchantmentHelper.getEnchantmentLevel(Enchantments.MULTISHOT, held) > 0) {
// Тройной выстрел с фиксированными параметрами
drawMultishot(eyePos, lookVec, power, gravity);
return;
}
}
else if (item instanceof TridentItem) {
power = 2.5f;
}
else if (item instanceof EnderPearlItem) {
power = 1.5f;
gravity = 0.03f;
color = new float[]{0.5f, 0.0f, 0.5f}; // Фиолетовый
}
// Обычный выстрел
drawProjectile(eyePos, lookVec, 0, color, power, gravity);
}
private void drawMultishot(Vector3d startPos, Vector3d direction, float power, float gravity) {
final float ANGLE = 9.0f; // Фиксированный угол 9°
final float V_SPREAD = 0.0f; // Нет вертикального разлёта
// Центральная стрела
drawProjectile(startPos, direction, 0, new float[]{0.2f, 1f, 0.2f}, power, gravity);
// Левая стрела
Vector3d leftVec = rotateYaw(direction, -ANGLE);
leftVec = rotatePitch(leftVec, -V_SPREAD);
drawProjectile(startPos, leftVec, 0, new float[]{1f, 0.5f, 0f}, power * 0.95f, gravity);
// Правая стрела
Vector3d rightVec = rotateYaw(direction, ANGLE);
rightVec = rotatePitch(rightVec, V_SPREAD);
drawProjectile(startPos, rightVec, 0, new float[]{1f, 0.5f, 0f}, power * 0.95f, gravity);
}
private void drawProjectile(Vector3d startPos, Vector3d direction, float pitchOffset, float[] color, float power, float gravity) {
Vector3d dir = rotatePitch(direction, pitchOffset);
Vector3d motion = dir.scale(power);
Vector3d pos = startPos;
for (int i = 0; i < 300; i++) {
Vector3d next = pos.add(motion);
RayTraceContext ctx = new RayTraceContext(pos, next,
RayTraceContext.BlockMode.COLLIDER,
RayTraceContext.FluidMode.NONE,
mc.player);
RayTraceResult result = mc.world.rayTraceBlocks(ctx);
if (result.getType() == RayTraceResult.Type.BLOCK) {
BlockRayTraceResult hit = (BlockRayTraceResult) result;
drawCircle(hit.getHitVec(), hit.getFace(), color[0], color[1], color[2]);
break;
}
pos = next;
motion = motion.scale(0.99).subtract(0, gravity, 0);
}
}
private Vector3d rotateYaw(Vector3d vec, float angle) {
float rad = (float)Math.toRadians(angle);
float cos = (float)Math.cos(rad);
float sin = (float)Math.sin(rad);
return new Vector3d(
vec.x * cos - vec.z * sin,
vec.y,
vec.x * sin + vec.z * cos
);
}
private Vector3d rotatePitch(Vector3d vec, float angle) {
float rad = (float)Math.toRadians(angle);
float cos = (float)Math.cos(rad);
float sin = (float)Math.sin(rad);
float xzLen = (float)Math.sqrt(vec.x * vec.x + vec.z * vec.z);
return new Vector3d(
vec.x,
vec.y * cos - xzLen * sin,
vec.z * cos + vec.y * sin
);
}
private void drawCircle(Vector3d hitVec, Direction face, float r, float g, float b) {
Vector3d cam = mc.getRenderManager().info.getProjectedView();
double x = hitVec.x - cam.x;
double y = hitVec.y - cam.y + 0.01;
double z = hitVec.z - cam.z;
GL11.glPushMatrix();
GL11.glTranslated(x, y, z);
alignToFace(face);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_BLEND);
GL11.glLineWidth(lineThickness.get());
GL11.glColor4f(r, g, b, 0.8f);
GL11.glBegin(GL11.GL_LINE_LOOP);
for (int i = 0; i < 40; i++) {
double angle = 2 * Math.PI * i / 40;
double dx = Math.cos(angle) * circleRadius.get();
double dz = Math.sin(angle) * circleRadius.get();
GL11.glVertex3d(dx, 0, dz);
}
GL11.glEnd();
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_BLEND);
GL11.glPopMatrix();
}
private void alignToFace(Direction face) {
switch (face) {
case UP: break;
case DOWN: GL11.glRotated(180, 1, 0, 0); break;
case EAST: GL11.glRotated(90, 0, 0, 1); break;
case WEST: GL11.glRotated(-90, 0, 0, 1); break;
case SOUTH: GL11.glRotated(-90, 1, 0, 0); break;
case NORTH: GL11.glRotated(90, 1, 0, 0); break;
}
}
}
Последнее редактирование: