Compare commits
4 commits
2e288d0738
...
d70b2b5974
Author | SHA1 | Date | |
---|---|---|---|
d70b2b5974 | |||
8dd209899f | |||
743e7e3ea1 | |||
0c4c307c28 |
21 changed files with 422 additions and 48 deletions
|
@ -1,6 +1,6 @@
|
||||||
plugins {
|
plugins {
|
||||||
id "architectury-plugin" version "3.4-SNAPSHOT"
|
id "architectury-plugin" version "3.4-SNAPSHOT"
|
||||||
id "dev.architectury.loom" version "1.4-SNAPSHOT" apply false
|
id "dev.architectury.loom" version "1.5-SNAPSHOT" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
architectury {
|
architectury {
|
||||||
|
|
|
@ -9,10 +9,9 @@ import net.minecraft.util.hit.HitResult;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import ru.octol1ttle.knockdowns.common.api.IKnockableDown;
|
import ru.octol1ttle.knockdowns.common.api.IKnockableDown;
|
||||||
import ru.octol1ttle.knockdowns.common.events.KnockdownsClientEvents;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.KnockdownsNetwork;
|
import ru.octol1ttle.knockdowns.common.network.KnockdownsNetwork;
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.RequestStartRevivingC2SPacket;
|
import ru.octol1ttle.knockdowns.common.network.packets.reviving.RequestStartRevivingC2SPacket;
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.StopRevivingC2SPacket;
|
import ru.octol1ttle.knockdowns.common.network.packets.reviving.StopRevivingC2SPacket;
|
||||||
import ru.octol1ttle.knockdowns.common.registries.KnockdownsSoundEvents;
|
import ru.octol1ttle.knockdowns.common.registries.KnockdownsSoundEvents;
|
||||||
import ru.octol1ttle.knockdowns.common.registries.KnockedDownSoundInstance;
|
import ru.octol1ttle.knockdowns.common.registries.KnockedDownSoundInstance;
|
||||||
|
|
||||||
|
@ -21,7 +20,6 @@ public class KnockdownsClient {
|
||||||
public static Entity reviving;
|
public static Entity reviving;
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
KnockdownsClientEvents.registerCallbacks();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void playKnockedDownSound(Vec3d pos) {
|
public static void playKnockedDownSound(Vec3d pos) {
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package ru.octol1ttle.knockdowns.common.api;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
public record RemotePlayer(Vec3d eyePosition, boolean knockedDown) { }
|
|
@ -1,44 +1,138 @@
|
||||||
package ru.octol1ttle.knockdowns.common.events;
|
package ru.octol1ttle.knockdowns.common.events;
|
||||||
|
|
||||||
import dev.architectury.event.events.client.ClientGuiEvent;
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
import net.minecraft.SharedConstants;
|
import net.minecraft.SharedConstants;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.font.TextRenderer;
|
import net.minecraft.client.font.TextRenderer;
|
||||||
|
import net.minecraft.client.gui.DrawContext;
|
||||||
|
import net.minecraft.client.gui.PlayerSkinDrawer;
|
||||||
|
import net.minecraft.client.network.PlayerListEntry;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.util.Formatting;
|
import net.minecraft.util.Formatting;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.hit.HitResult;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.RaycastContext;
|
||||||
import ru.octol1ttle.knockdowns.common.KnockdownsClient;
|
import ru.octol1ttle.knockdowns.common.KnockdownsClient;
|
||||||
|
import ru.octol1ttle.knockdowns.common.KnockdownsCommon;
|
||||||
import ru.octol1ttle.knockdowns.common.api.IKnockableDown;
|
import ru.octol1ttle.knockdowns.common.api.IKnockableDown;
|
||||||
|
import ru.octol1ttle.knockdowns.common.api.RemotePlayer;
|
||||||
|
import ru.octol1ttle.knockdowns.common.network.KnockdownsNetwork;
|
||||||
|
import ru.octol1ttle.knockdowns.common.network.packets.position.RequestRemotePlayerC2SPacket;
|
||||||
|
import ru.octol1ttle.knockdowns.common.util.RendererUtilsCopy;
|
||||||
|
import ru.octol1ttle.knockdowns.common.util.ScreenSpaceTransformResult;
|
||||||
|
|
||||||
public class KnockdownsClientEvents {
|
public class KnockdownsClientEvents {
|
||||||
public static void registerCallbacks() {
|
public static void onHudRender(DrawContext context) {
|
||||||
registerOnHudRender();
|
renderReviveText(context);
|
||||||
|
renderPlayerIcons(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void registerOnHudRender() {
|
private static void renderReviveText(DrawContext context) {
|
||||||
ClientGuiEvent.RENDER_HUD.register((drawContext, tickDelta) -> {
|
IKnockableDown reviving = (IKnockableDown) KnockdownsClient.reviving;
|
||||||
IKnockableDown reviving = (IKnockableDown) KnockdownsClient.reviving;
|
MinecraftClient client = MinecraftClient.getInstance();
|
||||||
MinecraftClient client = MinecraftClient.getInstance();
|
if (reviving == null) {
|
||||||
if (reviving == null) {
|
reviving = (IKnockableDown) client.player;
|
||||||
reviving = (IKnockableDown) client.player;
|
if (reviving == null || reviving.get_ReviveTimer() == KnockdownsCommon.REVIVE_WAIT_TIME) {
|
||||||
if (reviving == null || reviving.get_ReviverCount() == 0) {
|
return;
|
||||||
return;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextRenderer renderer = client.textRenderer;
|
||||||
|
|
||||||
|
String timerText = String.format("%.1f", reviving.get_ReviveTimer() / (float) SharedConstants.TICKS_PER_SECOND);
|
||||||
|
int timerX = (context.getScaledWindowWidth() - renderer.getWidth(timerText)) / 2;
|
||||||
|
|
||||||
|
int reviverCount = reviving.get_ReviverCount();
|
||||||
|
Integer color;
|
||||||
|
if (reviverCount == 0) {
|
||||||
|
color = Formatting.RED.getColorValue();
|
||||||
|
} else if (reviverCount == 1) {
|
||||||
|
color = Formatting.WHITE.getColorValue();
|
||||||
|
} else {
|
||||||
|
color = Formatting.GREEN.getColorValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
String reviverCountText = "x" + reviverCount;
|
||||||
|
int reviveCountX = (context.getScaledWindowWidth() - renderer.getWidth(reviverCountText)) / 2;
|
||||||
|
|
||||||
|
if (color != null) {
|
||||||
|
context.drawTextWithShadow(renderer, timerText, timerX, context.getScaledWindowHeight() / 2 + 5, color);
|
||||||
|
context.drawTextWithShadow(renderer, reviverCountText, reviveCountX, context.getScaledWindowHeight() / 2 + 14, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Map<UUID, Optional<RemotePlayer>> remotePlayers = new HashMap<>();
|
||||||
|
private static final Identifier KNOCKED_ICON_ID = new Identifier("knockdowns", "textures/knocked_icon.png");
|
||||||
|
@SuppressWarnings("DataFlowIssue")
|
||||||
|
private static void renderPlayerIcons(DrawContext context) {
|
||||||
|
MinecraftClient client = MinecraftClient.getInstance();
|
||||||
|
|
||||||
|
Collection<PlayerListEntry> entries = client.player.networkHandler.getListedPlayerListEntries();
|
||||||
|
for (PlayerListEntry entry : entries) {
|
||||||
|
UUID id = entry.getProfile().getId();
|
||||||
|
PlayerEntity player = client.world.getPlayerByUuid(id);
|
||||||
|
if (client.player.equals(player)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3d eyePosition;
|
||||||
|
boolean knockedDown;
|
||||||
|
if (player != null) {
|
||||||
|
remotePlayers.remove(id);
|
||||||
|
|
||||||
|
eyePosition = player.getEyePos();
|
||||||
|
knockedDown = ((IKnockableDown) player).is_KnockedDown();
|
||||||
|
} else {
|
||||||
|
Optional<RemotePlayer> remote = remotePlayers.get(id);
|
||||||
|
if (remote != null) {
|
||||||
|
if (remote.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
eyePosition = remote.get().eyePosition();
|
||||||
|
knockedDown = remote.get().knockedDown();
|
||||||
|
} else {
|
||||||
|
remotePlayers.put(id, Optional.empty());
|
||||||
|
KnockdownsNetwork.sendToServer(new RequestRemotePlayerC2SPacket(id));
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextRenderer renderer = client.textRenderer;
|
ScreenSpaceTransformResult result = RendererUtilsCopy.worldSpaceToScreenSpace(eyePosition);
|
||||||
|
int size = 16;
|
||||||
|
|
||||||
String timerText = String.format("%.1f", reviving.get_ReviveTimer() / (float) SharedConstants.TICKS_PER_SECOND);
|
int width = context.getScaledWindowWidth();
|
||||||
int timerX = (drawContext.getScaledWindowWidth() - renderer.getWidth(timerText)) / 2;
|
int x = MathHelper.clamp(MathHelper.floor(result.vec().x - size * 0.5), size + 5, width - size - 5);
|
||||||
|
|
||||||
int reviverCount = reviving.get_ReviverCount();
|
int height = context.getScaledWindowHeight();
|
||||||
Integer color = reviverCount > 1 ? Formatting.GREEN.getColorValue() : Formatting.WHITE.getColorValue();
|
int y = MathHelper.clamp(MathHelper.floor(result.vec().y - size * 0.5), size + 5, height - size - 5);
|
||||||
|
|
||||||
String reviverCountText = "x" + reviverCount;
|
if (result.type() != ScreenSpaceTransformResult.TransformType.ON_SCREEN
|
||||||
int reviveCountX = (drawContext.getScaledWindowWidth() - renderer.getWidth(reviverCountText)) / 2;
|
|| client.player.getEyePos().distanceTo(eyePosition) > 64.0
|
||||||
|
|| client.world
|
||||||
if (color != null) {
|
.raycast(new RaycastContext(
|
||||||
drawContext.drawTextWithShadow(renderer, timerText, timerX, drawContext.getScaledWindowHeight() / 2 + 5, color);
|
client.getEntityRenderDispatcher().camera.getPos(),
|
||||||
drawContext.drawTextWithShadow(renderer, reviverCountText, reviveCountX, drawContext.getScaledWindowHeight() / 2 + 14, color);
|
eyePosition,
|
||||||
|
RaycastContext.ShapeType.VISUAL,
|
||||||
|
RaycastContext.FluidHandling.SOURCE_ONLY,
|
||||||
|
client.player
|
||||||
|
)).getType() == HitResult.Type.BLOCK)
|
||||||
|
{
|
||||||
|
PlayerSkinDrawer.draw(context, entry.getSkinTexture(), x, y, size, true, false);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
if (knockedDown) {
|
||||||
|
context.drawTexture(KNOCKED_ICON_ID, x, y, size, size, 0, 0, 18, 18, 18, 18);
|
||||||
|
}
|
||||||
|
if (client.player.age % 20 == 0 && remotePlayers.containsKey(id)) {
|
||||||
|
KnockdownsNetwork.sendToServer(new RequestRemotePlayerC2SPacket(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ import ru.octol1ttle.knockdowns.common.KnockdownsUtils;
|
||||||
import ru.octol1ttle.knockdowns.common.api.IKnockableDown;
|
import ru.octol1ttle.knockdowns.common.api.IKnockableDown;
|
||||||
import ru.octol1ttle.knockdowns.common.network.KnockdownsNetwork;
|
import ru.octol1ttle.knockdowns.common.network.KnockdownsNetwork;
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.PlayKnockedDownSoundS2CPacket;
|
import ru.octol1ttle.knockdowns.common.network.packets.PlayKnockedDownSoundS2CPacket;
|
||||||
|
import ru.octol1ttle.knockdowns.common.network.packets.position.RemotePlayerDimensionChangeS2CPacket;
|
||||||
|
import ru.octol1ttle.knockdowns.common.network.packets.position.RemotePlayerS2CPacket;
|
||||||
|
|
||||||
public class KnockdownsEvents {
|
public class KnockdownsEvents {
|
||||||
private static final float KNOCKED_INVULNERABILITY_TICKS = 3.0f * SharedConstants.TICKS_PER_SECOND;
|
private static final float KNOCKED_INVULNERABILITY_TICKS = 3.0f * SharedConstants.TICKS_PER_SECOND;
|
||||||
|
@ -32,6 +34,7 @@ public class KnockdownsEvents {
|
||||||
registerOnPlayerTick();
|
registerOnPlayerTick();
|
||||||
registerOnPlayerInteractions();
|
registerOnPlayerInteractions();
|
||||||
registerOnEntityUse();
|
registerOnEntityUse();
|
||||||
|
registerOnDimensionChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void registerOnLivingDeath() {
|
private static void registerOnLivingDeath() {
|
||||||
|
@ -51,7 +54,6 @@ public class KnockdownsEvents {
|
||||||
|
|
||||||
entity.clearStatusEffects();
|
entity.clearStatusEffects();
|
||||||
entity.setInvulnerable(true);
|
entity.setInvulnerable(true);
|
||||||
entity.setGlowing(true);
|
|
||||||
entity.setHealth(entity.getMaxHealth());
|
entity.setHealth(entity.getMaxHealth());
|
||||||
entity.extinguish();
|
entity.extinguish();
|
||||||
entity.setAir(entity.getMaxAir());
|
entity.setAir(entity.getMaxAir());
|
||||||
|
@ -99,7 +101,6 @@ public class KnockdownsEvents {
|
||||||
KnockdownsUtils.resetKnockedState(knockable);
|
KnockdownsUtils.resetKnockedState(knockable);
|
||||||
|
|
||||||
player.setInvulnerable(false);
|
player.setInvulnerable(false);
|
||||||
player.setGlowing(false);
|
|
||||||
player.setHealth(player.getMaxHealth() * 0.3f);
|
player.setHealth(player.getMaxHealth() * 0.3f);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -115,6 +116,14 @@ public class KnockdownsEvents {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void registerOnDimensionChange() {
|
||||||
|
PlayerEvent.CHANGE_DIMENSION.register((player, oldLevel, newLevel) -> {
|
||||||
|
//noinspection DataFlowIssue
|
||||||
|
KnockdownsNetwork.sendToWorld(player.getServer().getWorld(oldLevel), new RemotePlayerDimensionChangeS2CPacket(player.getUuid()));
|
||||||
|
KnockdownsNetwork.sendToWorld(player.getServerWorld(), new RemotePlayerS2CPacket(player.getUuid(), player.getEyePos(), ((IKnockableDown)player).is_KnockedDown()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private static void registerOnPlayerInteractions() {
|
private static void registerOnPlayerInteractions() {
|
||||||
InteractionEvent.LEFT_CLICK_BLOCK.register((player, hand, pos, direction) -> {
|
InteractionEvent.LEFT_CLICK_BLOCK.register((player, hand, pos, direction) -> {
|
||||||
if (KnockdownsUtils.isKnockedOrReviving(player)) {
|
if (KnockdownsUtils.isKnockedOrReviving(player)) {
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
package ru.octol1ttle.knockdowns.common.mixin.client;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import net.minecraft.client.render.GameRenderer;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
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;
|
||||||
|
import ru.octol1ttle.knockdowns.common.util.RendererUtilsCopy;
|
||||||
|
|
||||||
|
@Mixin(GameRenderer.class)
|
||||||
|
public abstract class GameRendererMixin {
|
||||||
|
@Inject(at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/GameRenderer;renderHand:Z", opcode = Opcodes.GETFIELD, ordinal = 0), method = "renderWorld")
|
||||||
|
void renderer_postWorldRender(float tickDelta, long limitTime, MatrixStack matrix, CallbackInfo ci) {
|
||||||
|
RendererUtilsCopy.lastProjMat.set(RenderSystem.getProjectionMatrix());
|
||||||
|
RendererUtilsCopy.lastModMat.set(RenderSystem.getModelViewMatrix());
|
||||||
|
RendererUtilsCopy.lastWorldSpaceMatrix.set(matrix.peek().getPositionMatrix());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package ru.octol1ttle.knockdowns.common.mixin.client;
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.DrawContext;
|
||||||
|
import net.minecraft.client.gui.hud.InGameHud;
|
||||||
|
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;
|
||||||
|
import ru.octol1ttle.knockdowns.common.events.KnockdownsClientEvents;
|
||||||
|
|
||||||
|
@Mixin(InGameHud.class)
|
||||||
|
public abstract class InGameHudMixin {
|
||||||
|
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;getCurrentGameMode()Lnet/minecraft/world/GameMode;", ordinal = 0))
|
||||||
|
public void render(DrawContext drawContext, float tickDelta, CallbackInfo callbackInfo) {
|
||||||
|
KnockdownsClientEvents.onHudRender(drawContext);
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,15 +9,23 @@ import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import ru.octol1ttle.knockdowns.common.KnockdownsCommon;
|
import ru.octol1ttle.knockdowns.common.KnockdownsCommon;
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.PlayKnockedDownSoundS2CPacket;
|
import ru.octol1ttle.knockdowns.common.network.packets.PlayKnockedDownSoundS2CPacket;
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.RequestStartRevivingC2SPacket;
|
import ru.octol1ttle.knockdowns.common.network.packets.position.RemotePlayerDimensionChangeS2CPacket;
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.StopRevivingC2SPacket;
|
import ru.octol1ttle.knockdowns.common.network.packets.position.RemotePlayerS2CPacket;
|
||||||
|
import ru.octol1ttle.knockdowns.common.network.packets.position.RequestRemotePlayerC2SPacket;
|
||||||
|
import ru.octol1ttle.knockdowns.common.network.packets.reviving.RequestStartRevivingC2SPacket;
|
||||||
|
import ru.octol1ttle.knockdowns.common.network.packets.reviving.StopRevivingC2SPacket;
|
||||||
|
|
||||||
public class KnockdownsNetwork {
|
public class KnockdownsNetwork {
|
||||||
private static final NetworkChannel CHANNEL = NetworkChannel.create(new Identifier(KnockdownsCommon.MOD_ID, "main"));
|
private static final NetworkChannel CHANNEL = NetworkChannel.create(new Identifier(KnockdownsCommon.MOD_ID, "main"));
|
||||||
public static void registerPackets() {
|
public static void registerPackets() {
|
||||||
CHANNEL.register(PlayKnockedDownSoundS2CPacket.class, PlayKnockedDownSoundS2CPacket::encode, PlayKnockedDownSoundS2CPacket::new, PlayKnockedDownSoundS2CPacket::apply);
|
CHANNEL.register(PlayKnockedDownSoundS2CPacket.class, PlayKnockedDownSoundS2CPacket::encode, PlayKnockedDownSoundS2CPacket::new, PlayKnockedDownSoundS2CPacket::apply);
|
||||||
|
|
||||||
CHANNEL.register(RequestStartRevivingC2SPacket.class, RequestStartRevivingC2SPacket::encode, RequestStartRevivingC2SPacket::new, RequestStartRevivingC2SPacket::apply);
|
CHANNEL.register(RequestStartRevivingC2SPacket.class, RequestStartRevivingC2SPacket::encode, RequestStartRevivingC2SPacket::new, RequestStartRevivingC2SPacket::apply);
|
||||||
CHANNEL.register(StopRevivingC2SPacket.class, StopRevivingC2SPacket::encode, StopRevivingC2SPacket::new, StopRevivingC2SPacket::apply);
|
CHANNEL.register(StopRevivingC2SPacket.class, StopRevivingC2SPacket::encode, StopRevivingC2SPacket::new, StopRevivingC2SPacket::apply);
|
||||||
|
|
||||||
|
CHANNEL.register(RequestRemotePlayerC2SPacket.class, RequestRemotePlayerC2SPacket::encode, RequestRemotePlayerC2SPacket::new, RequestRemotePlayerC2SPacket::apply);
|
||||||
|
CHANNEL.register(RemotePlayerS2CPacket.class, RemotePlayerS2CPacket::encode, RemotePlayerS2CPacket::new, RemotePlayerS2CPacket::apply);
|
||||||
|
CHANNEL.register(RemotePlayerDimensionChangeS2CPacket.class, RemotePlayerDimensionChangeS2CPacket::encode, RemotePlayerDimensionChangeS2CPacket::new, RemotePlayerDimensionChangeS2CPacket::apply);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> void sendToServer(T message) {
|
public static <T> void sendToServer(T message) {
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package ru.octol1ttle.knockdowns.common.network.packets.position;
|
||||||
|
|
||||||
|
import dev.architectury.networking.NetworkManager;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import net.minecraft.network.PacketByteBuf;
|
||||||
|
import ru.octol1ttle.knockdowns.common.events.KnockdownsClientEvents;
|
||||||
|
import ru.octol1ttle.knockdowns.common.network.packets.KnockdownsPacket;
|
||||||
|
|
||||||
|
public class RemotePlayerDimensionChangeS2CPacket extends KnockdownsPacket {
|
||||||
|
private final UUID targetUuid;
|
||||||
|
|
||||||
|
public RemotePlayerDimensionChangeS2CPacket(PacketByteBuf buf) {
|
||||||
|
this(buf.readUuid());
|
||||||
|
}
|
||||||
|
|
||||||
|
public RemotePlayerDimensionChangeS2CPacket(UUID targetUuid) {
|
||||||
|
this.targetUuid = targetUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(PacketByteBuf buf) {
|
||||||
|
buf.writeUuid(this.targetUuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Supplier<NetworkManager.PacketContext> contextSupplier) {
|
||||||
|
NetworkManager.PacketContext context = contextSupplier.get();
|
||||||
|
context.queue(() -> KnockdownsClientEvents.remotePlayers.put(targetUuid, Optional.empty()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package ru.octol1ttle.knockdowns.common.network.packets.position;
|
||||||
|
|
||||||
|
import dev.architectury.networking.NetworkManager;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.network.PacketByteBuf;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import ru.octol1ttle.knockdowns.common.api.RemotePlayer;
|
||||||
|
import ru.octol1ttle.knockdowns.common.events.KnockdownsClientEvents;
|
||||||
|
import ru.octol1ttle.knockdowns.common.network.packets.KnockdownsPacket;
|
||||||
|
|
||||||
|
public class RemotePlayerS2CPacket extends KnockdownsPacket {
|
||||||
|
private final UUID targetUuid;
|
||||||
|
private final Vec3d eyePosition;
|
||||||
|
private final boolean knockedDown;
|
||||||
|
|
||||||
|
public RemotePlayerS2CPacket(PacketByteBuf buf) {
|
||||||
|
this(buf.readUuid(), new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble()), buf.readBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
|
public RemotePlayerS2CPacket(UUID targetUuid, Vec3d eyePosition, boolean knockedDown) {
|
||||||
|
this.targetUuid = targetUuid;
|
||||||
|
this.eyePosition = eyePosition;
|
||||||
|
this.knockedDown = knockedDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(PacketByteBuf buf) {
|
||||||
|
buf.writeUuid(this.targetUuid);
|
||||||
|
buf.writeDouble(this.eyePosition.x);
|
||||||
|
buf.writeDouble(this.eyePosition.y);
|
||||||
|
buf.writeDouble(this.eyePosition.z);
|
||||||
|
buf.writeBoolean(this.knockedDown);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Supplier<NetworkManager.PacketContext> contextSupplier) {
|
||||||
|
NetworkManager.PacketContext context = contextSupplier.get();
|
||||||
|
context.queue(() -> {
|
||||||
|
//noinspection DataFlowIssue
|
||||||
|
if (MinecraftClient.getInstance().player.getUuid().equals(targetUuid)) {
|
||||||
|
KnockdownsClientEvents.remotePlayers.clear();
|
||||||
|
} else {
|
||||||
|
KnockdownsClientEvents.remotePlayers.put(targetUuid, Optional.of(new RemotePlayer(this.eyePosition, this.knockedDown)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package ru.octol1ttle.knockdowns.common.network.packets.position;
|
||||||
|
|
||||||
|
import dev.architectury.networking.NetworkManager;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.network.PacketByteBuf;
|
||||||
|
import ru.octol1ttle.knockdowns.common.api.IKnockableDown;
|
||||||
|
import ru.octol1ttle.knockdowns.common.network.KnockdownsNetwork;
|
||||||
|
import ru.octol1ttle.knockdowns.common.network.packets.KnockdownsPacket;
|
||||||
|
|
||||||
|
public class RequestRemotePlayerC2SPacket extends KnockdownsPacket {
|
||||||
|
private final UUID targetUuid;
|
||||||
|
|
||||||
|
public RequestRemotePlayerC2SPacket(PacketByteBuf buf) {
|
||||||
|
this(buf.readUuid());
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestRemotePlayerC2SPacket(UUID targetUuid) {
|
||||||
|
this.targetUuid = targetUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(PacketByteBuf buf) {
|
||||||
|
buf.writeUuid(this.targetUuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Supplier<NetworkManager.PacketContext> contextSupplier) {
|
||||||
|
NetworkManager.PacketContext context = contextSupplier.get();
|
||||||
|
context.queue(() -> {
|
||||||
|
PlayerEntity sender = context.getPlayer();
|
||||||
|
PlayerEntity target = sender.getEntityWorld().getPlayerByUuid(targetUuid);
|
||||||
|
if (target != null) {
|
||||||
|
KnockdownsNetwork.sendToPlayer(context.getPlayer(), new RemotePlayerS2CPacket(targetUuid, target.getEyePos(), ((IKnockableDown)target).is_KnockedDown()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.octol1ttle.knockdowns.common.network.packets;
|
package ru.octol1ttle.knockdowns.common.network.packets.reviving;
|
||||||
|
|
||||||
import dev.architectury.networking.NetworkManager;
|
import dev.architectury.networking.NetworkManager;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -6,6 +6,7 @@ import java.util.function.Supplier;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.network.PacketByteBuf;
|
import net.minecraft.network.PacketByteBuf;
|
||||||
import ru.octol1ttle.knockdowns.common.api.IKnockableDown;
|
import ru.octol1ttle.knockdowns.common.api.IKnockableDown;
|
||||||
|
import ru.octol1ttle.knockdowns.common.network.packets.KnockdownsPacket;
|
||||||
|
|
||||||
public class RequestStartRevivingC2SPacket extends KnockdownsPacket {
|
public class RequestStartRevivingC2SPacket extends KnockdownsPacket {
|
||||||
private final UUID targetUuid;
|
private final UUID targetUuid;
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.octol1ttle.knockdowns.common.network.packets;
|
package ru.octol1ttle.knockdowns.common.network.packets.reviving;
|
||||||
|
|
||||||
import dev.architectury.networking.NetworkManager;
|
import dev.architectury.networking.NetworkManager;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -6,6 +6,7 @@ import java.util.function.Supplier;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.network.PacketByteBuf;
|
import net.minecraft.network.PacketByteBuf;
|
||||||
import ru.octol1ttle.knockdowns.common.api.IKnockableDown;
|
import ru.octol1ttle.knockdowns.common.api.IKnockableDown;
|
||||||
|
import ru.octol1ttle.knockdowns.common.network.packets.KnockdownsPacket;
|
||||||
|
|
||||||
public class StopRevivingC2SPacket extends KnockdownsPacket {
|
public class StopRevivingC2SPacket extends KnockdownsPacket {
|
||||||
private final UUID targetUuid;
|
private final UUID targetUuid;
|
|
@ -0,0 +1,75 @@
|
||||||
|
package ru.octol1ttle.knockdowns.common.util;
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.render.Camera;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Vector2d;
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
import org.joml.Vector4f;
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 0x3C50
|
||||||
|
* <p>Utils for rendering in minecraft</p>
|
||||||
|
*/
|
||||||
|
public class RendererUtilsCopy {
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public static final Matrix4f lastProjMat = new Matrix4f();
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public static final Matrix4f lastModMat = new Matrix4f();
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public static final Matrix4f lastWorldSpaceMatrix = new Matrix4f();
|
||||||
|
private static final MinecraftClient client = MinecraftClient.getInstance();
|
||||||
|
|
||||||
|
@Contract(value = "_ -> new", pure = true)
|
||||||
|
public static ScreenSpaceTransformResult worldSpaceToScreenSpace(@NotNull Vec3d pos) {
|
||||||
|
Camera camera = client.getEntityRenderDispatcher().camera;
|
||||||
|
|
||||||
|
double deltaX = pos.x - camera.getPos().x;
|
||||||
|
double deltaY = pos.y - camera.getPos().y;
|
||||||
|
double deltaZ = pos.z - camera.getPos().z;
|
||||||
|
|
||||||
|
Vector4f transformedCoordinates = new Vector4f((float) deltaX, (float) deltaY, (float) deltaZ, 1.f).mul(
|
||||||
|
lastWorldSpaceMatrix);
|
||||||
|
|
||||||
|
Matrix4f matrixProj = new Matrix4f(lastProjMat);
|
||||||
|
|
||||||
|
Vector4f clip = matrixProj.transform(new Vector4f(transformedCoordinates));
|
||||||
|
if (clip.z > 0 && Math.abs(clip.x) < Math.abs(clip.w) && Math.abs(clip.y) < Math.abs(clip.w)) {
|
||||||
|
int[] viewport = new int[4];
|
||||||
|
GL11.glGetIntegerv(GL11.GL_VIEWPORT, viewport);
|
||||||
|
Matrix4f matrixModel = new Matrix4f(lastModMat);
|
||||||
|
Vector3f target = new Vector3f();
|
||||||
|
|
||||||
|
matrixProj
|
||||||
|
.mul(matrixModel)
|
||||||
|
.project(transformedCoordinates.x(), transformedCoordinates.y(), transformedCoordinates.z(), viewport, target);
|
||||||
|
|
||||||
|
return new ScreenSpaceTransformResult(
|
||||||
|
new Vector2d(
|
||||||
|
target.x / client.getWindow().getScaleFactor(),
|
||||||
|
(client.getWindow().getHeight() - target.y) / client.getWindow().getScaleFactor()
|
||||||
|
),
|
||||||
|
ScreenSpaceTransformResult.TransformType.ON_SCREEN
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
clip.normalize();
|
||||||
|
double angle = Math.atan2(clip.y, clip.x);
|
||||||
|
double width = client.getWindow().getScaledWidth();
|
||||||
|
double height = client.getWindow().getScaledHeight();
|
||||||
|
|
||||||
|
double x = MathHelper.clamp(Math.cos(angle) * width + width / 2, 0.0f, width);
|
||||||
|
double y = height - (MathHelper.clamp(Math.sin(angle) * height + height / 2, 0.0f, height));
|
||||||
|
|
||||||
|
return new ScreenSpaceTransformResult(
|
||||||
|
new Vector2d(x, y),
|
||||||
|
ScreenSpaceTransformResult.TransformType.STUCK_TO_EDGES
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package ru.octol1ttle.knockdowns.common.util;
|
||||||
|
|
||||||
|
import org.joml.Vector2d;
|
||||||
|
|
||||||
|
public record ScreenSpaceTransformResult(Vector2d vec, TransformType type) {
|
||||||
|
public enum TransformType {
|
||||||
|
ON_SCREEN,
|
||||||
|
STUCK_TO_EDGES
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 172 B |
|
@ -4,7 +4,9 @@
|
||||||
"compatibilityLevel": "JAVA_17",
|
"compatibilityLevel": "JAVA_17",
|
||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"client": [
|
"client": [
|
||||||
"client.ClientPlayerEntityMixin"
|
"client.ClientPlayerEntityMixin",
|
||||||
|
"client.GameRendererMixin",
|
||||||
|
"client.InGameHudMixin"
|
||||||
],
|
],
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"LivingEntityMixin",
|
"LivingEntityMixin",
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package ru.octol1ttle.knockdowns.forge;
|
||||||
|
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.client.event.RenderGuiEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||||
|
import ru.octol1ttle.knockdowns.common.KnockdownsClient;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Mod.EventBusSubscriber(modid = "knockdowns", bus = Mod.EventBusSubscriber.Bus.FORGE, value = Dist.CLIENT)
|
||||||
|
public class KnockdownsClientForge {
|
||||||
|
@SubscribeEvent
|
||||||
|
public void onInitializeClient(FMLClientSetupEvent event) {
|
||||||
|
KnockdownsClient.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onHudRender(RenderGuiEvent.Pre event) {
|
||||||
|
ru.octol1ttle.knockdowns.common.events.KnockdownsClientEvents.onHudRender(event.getGuiGraphics());
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,9 +3,7 @@ package ru.octol1ttle.knockdowns.forge;
|
||||||
import dev.architectury.platform.forge.EventBuses;
|
import dev.architectury.platform.forge.EventBuses;
|
||||||
import net.minecraftforge.eventbus.api.IEventBus;
|
import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
|
||||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
import ru.octol1ttle.knockdowns.common.KnockdownsClient;
|
|
||||||
import ru.octol1ttle.knockdowns.common.KnockdownsCommon;
|
import ru.octol1ttle.knockdowns.common.KnockdownsCommon;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
@ -15,12 +13,7 @@ public class KnockdownsForge {
|
||||||
// Submit our event bus to let architectury register our content on the right time
|
// Submit our event bus to let architectury register our content on the right time
|
||||||
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||||
EventBuses.registerModEventBus(KnockdownsCommon.MOD_ID, modEventBus);
|
EventBuses.registerModEventBus(KnockdownsCommon.MOD_ID, modEventBus);
|
||||||
modEventBus.addListener(this::onInitializeClient);
|
|
||||||
|
|
||||||
KnockdownsCommon.init();
|
KnockdownsCommon.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onInitializeClient(FMLClientSetupEvent event) {
|
|
||||||
KnockdownsClient.init();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,11 @@ minecraft_version=1.20.1
|
||||||
enabled_platforms=fabric,forge
|
enabled_platforms=fabric,forge
|
||||||
|
|
||||||
archives_base_name=knockdowns
|
archives_base_name=knockdowns
|
||||||
mod_version=2.2.2
|
mod_version=2.3.1
|
||||||
maven_group=ru.octol1ttle.knockdowns
|
maven_group=ru.octol1ttle.knockdowns
|
||||||
|
|
||||||
architectury_version=9.1.12
|
architectury_version=9.1.12
|
||||||
fabric_api_version=0.90.4+1.20.1
|
fabric_api_version=0.90.4+1.20.1
|
||||||
|
|
||||||
fabric_loader_version=0.15.5
|
fabric_loader_version=0.15.5
|
||||||
forge_version=1.20.1-47.2.0
|
forge_version=1.20.1-47.2.0
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ pluginManagement {
|
||||||
repositories {
|
repositories {
|
||||||
maven { url "https://maven.fabricmc.net/" }
|
maven { url "https://maven.fabricmc.net/" }
|
||||||
maven { url "https://maven.architectury.dev/" }
|
maven { url "https://maven.architectury.dev/" }
|
||||||
maven { url "https://maven.minecraftforge.net/" }
|
maven { url "https://maven.neoforged.net/releases" }
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue