实现滋崩发射

This commit is contained in:
Light_Quanta 2025-03-26 05:25:25 +08:00
parent 9a88b01de5
commit ae96635d11
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
7 changed files with 238 additions and 10 deletions

View file

@ -215,6 +215,11 @@ tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation
} }
tasks.named('createMinecraftArtifacts') {
dependsOn tasks.named('generateModMetadata')
}
// IDEA no longer automatically downloads sources/javadoc jars for dependencies, so we need to explicitly enable the behavior. // IDEA no longer automatically downloads sources/javadoc jars for dependencies, so we need to explicitly enable the behavior.
idea { idea {
module { module {

View file

@ -4,6 +4,8 @@ import com.atsuishio.superbwarfare.capability.ModCapabilities;
import com.atsuishio.superbwarfare.capability.laser.LaserHandler; import com.atsuishio.superbwarfare.capability.laser.LaserHandler;
import com.atsuishio.superbwarfare.entity.projectile.LaserEntity; import com.atsuishio.superbwarfare.entity.projectile.LaserEntity;
import com.atsuishio.superbwarfare.init.ModSounds; import com.atsuishio.superbwarfare.init.ModSounds;
import com.atsuishio.superbwarfare.network.message.LaserShootMessage;
import com.atsuishio.superbwarfare.network.message.ShakeClientMessage;
import com.atsuishio.superbwarfare.tools.TraceTool; import com.atsuishio.superbwarfare.tools.TraceTool;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.game.ClientboundStopSoundPacket; import net.minecraft.network.protocol.game.ClientboundStopSoundPacket;
@ -21,6 +23,7 @@ import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.network.PacketDistributor;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
@ -93,7 +96,8 @@ public class BeamTest extends Item {
} }
@Override @Override
public ItemStack finishUsingItem(ItemStack pStack, Level pLevel, LivingEntity pLivingEntity) { @ParametersAreNonnullByDefault
public @NotNull ItemStack finishUsingItem(ItemStack pStack, Level pLevel, LivingEntity pLivingEntity) {
if (pLivingEntity instanceof Player player) { if (pLivingEntity instanceof Player player) {
var cap = player.getCapability(ModCapabilities.LASER_CAPABILITY); var cap = player.getCapability(ModCapabilities.LASER_CAPABILITY);
if (cap != null) { if (cap != null) {
@ -109,8 +113,7 @@ public class BeamTest extends Item {
player.playSound(ModSounds.CHARGE_RIFLE_FIRE_BOOM_3P.get(), 4, 1); player.playSound(ModSounds.CHARGE_RIFLE_FIRE_BOOM_3P.get(), 4, 1);
} }
if (player instanceof ServerPlayer serverPlayer) { if (player instanceof ServerPlayer serverPlayer) {
// TODO network PacketDistributor.sendToPlayer(serverPlayer, new ShakeClientMessage(10, 10, 30, serverPlayer.getX(), serverPlayer.getEyeY(), serverPlayer.getZ()));
// ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ShakeClientMessage(10, 10, 30, serverPlayer.getX(), serverPlayer.getEyeY(), serverPlayer.getZ()));
} }
} }
return super.finishUsingItem(pStack, pLevel, pLivingEntity); return super.finishUsingItem(pStack, pLevel, pLivingEntity);
@ -127,7 +130,7 @@ public class BeamTest extends Item {
&& (!player.isAlliedTo(lookingEntity) || lookingEntity.getTeam() == null || lookingEntity.getTeam().getName().equals("TDM")); && (!player.isAlliedTo(lookingEntity) || lookingEntity.getTeam() == null || lookingEntity.getTeam().getName().equals("TDM"));
if (canAttack) { if (canAttack) {
// ModUtils.PACKET_HANDLER.sendToServer(new LaserShootMessage(45, lookingEntity.getUUID(), TraceTool.laserHeadshot)); PacketDistributor.sendToServer(new LaserShootMessage(45, lookingEntity.getUUID(), TraceTool.laserHeadshot));
} }
} }

View file

@ -1,6 +1,8 @@
package com.atsuishio.superbwarfare.network; package com.atsuishio.superbwarfare.network;
import com.atsuishio.superbwarfare.network.message.LaserShootMessage;
import com.atsuishio.superbwarfare.network.message.PlayerVariablesSyncMessage; import com.atsuishio.superbwarfare.network.message.PlayerVariablesSyncMessage;
import com.atsuishio.superbwarfare.network.message.ShakeClientMessage;
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
import net.neoforged.neoforge.network.registration.PayloadRegistrar; import net.neoforged.neoforge.network.registration.PayloadRegistrar;
@ -13,5 +15,18 @@ public class NetworkRegistry {
PlayerVariablesSyncMessage.STREAM_CODEC, PlayerVariablesSyncMessage.STREAM_CODEC,
PlayerVariablesSyncMessage::handler PlayerVariablesSyncMessage::handler
); );
registrar.playToClient(
ShakeClientMessage.TYPE,
ShakeClientMessage.STREAM_CODEC,
ShakeClientMessage::handler
);
registrar.playToServer(
LaserShootMessage.TYPE,
LaserShootMessage.STREAM_CODEC,
LaserShootMessage::handler
);
} }
} }

View file

@ -0,0 +1,69 @@
package com.atsuishio.superbwarfare.network.message;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.init.ModDamageTypes;
import com.atsuishio.superbwarfare.init.ModSounds;
import com.atsuishio.superbwarfare.tools.EntityFindUtil;
import io.netty.buffer.ByteBuf;
import net.minecraft.core.UUIDUtil;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.neoforged.neoforge.network.handling.IPayloadContext;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
public record LaserShootMessage(
double damage,
UUID id,
boolean headshot
) implements CustomPacketPayload {
public static final Type<LaserShootMessage> TYPE = new Type<>(ModUtils.loc("laser_shoot"));
public static final StreamCodec<ByteBuf, LaserShootMessage> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.DOUBLE,
LaserShootMessage::damage,
UUIDUtil.STREAM_CODEC,
LaserShootMessage::id,
ByteBufCodecs.BOOL,
LaserShootMessage::headshot,
LaserShootMessage::new
);
public static void handler(final LaserShootMessage message, final IPayloadContext context) {
pressAction((ServerPlayer) context.player(), message.damage, message.id, message.headshot);
}
public static void pressAction(ServerPlayer player, double damage, UUID uuid, boolean headshot) {
Level level = player.level();
Entity entity = EntityFindUtil.findEntity(level, String.valueOf(uuid));
if (entity != null) {
if (headshot) {
entity.hurt(ModDamageTypes.causeLaserHeadshotDamage(level.registryAccess(), player, player), (float) (2 * damage));
player.level().playSound(null, player.blockPosition(), ModSounds.HEADSHOT.get(), SoundSource.VOICE, 0.1f, 1);
// TODO indicator
// ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> player), new ClientIndicatorMessage(1, 5));
} else {
entity.hurt(ModDamageTypes.causeLaserDamage(level.registryAccess(), player, player), (float) damage);
player.level().playSound(null, player.blockPosition(), ModSounds.INDICATION.get(), SoundSource.VOICE, 0.1f, 1);
// ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> player), new ClientIndicatorMessage(0, 5));
}
entity.invulnerableTime = 0;
}
}
@Override
public @NotNull Type<? extends CustomPacketPayload> type() {
return TYPE;
}
}

View file

@ -0,0 +1,138 @@
package com.atsuishio.superbwarfare.network.message;
import com.atsuishio.superbwarfare.ModUtils;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.Vec3;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.client.event.ViewportEvent;
import net.neoforged.neoforge.network.handling.IPayloadContext;
import org.jetbrains.annotations.NotNull;
@EventBusSubscriber(modid = ModUtils.MODID, bus = EventBusSubscriber.Bus.GAME, value = Dist.CLIENT)
public record ShakeClientMessage(
double time, double radius, double amplitude,
double x, double y, double z
) implements CustomPacketPayload {
public static final CustomPacketPayload.Type<ShakeClientMessage> TYPE = new CustomPacketPayload.Type<>(ModUtils.loc("shake_client"));
public static final StreamCodec<ByteBuf, ShakeClientMessage> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.DOUBLE,
ShakeClientMessage::time,
ByteBufCodecs.DOUBLE,
ShakeClientMessage::radius,
ByteBufCodecs.DOUBLE,
ShakeClientMessage::amplitude,
ByteBufCodecs.DOUBLE,
ShakeClientMessage::x,
ByteBufCodecs.DOUBLE,
ShakeClientMessage::y,
ByteBufCodecs.DOUBLE,
ShakeClientMessage::z,
ShakeClientMessage::new
);
public static void handler(final ShakeClientMessage message, final IPayloadContext context) {
Player player = Minecraft.getInstance().player;
if (player == null) return;
shakeTime = message.time;
shakeRadius = message.radius;
shakeAmplitude = message.amplitude * Mth.DEG_TO_RAD;
shakePos[0] = message.x;
shakePos[1] = message.y;
shakePos[2] = message.z;
shakeType = 2 * (Math.random() - 0.5);
}
public static double shakeTime = 0;
public static double shakeRadius = 0;
public static double shakeAmplitude = 0;
public static double[] shakePos = {0, 0, 0};
public static double shakeType = 0;
@SubscribeEvent
public static void computeCameraAngles(ViewportEvent.ComputeCameraAngles event) {
ClientLevel level = Minecraft.getInstance().level;
Entity entity = event.getCamera().getEntity();
if (!(entity instanceof LivingEntity living)) return;
ItemStack stack = living.getMainHandItem();
// if (level != null &&
// (stack.is(ModItems.MONITOR.get()) && stack.getOrCreateTag().getBoolean("Using") && stack.getOrCreateTag().getBoolean("Linked"))) {
// handleDroneCamera(event, living);
// } else {
// var effect = Minecraft.getInstance().gameRenderer.currentEffect();
// if (effect != null && effect.getName().equals(ModUtils.MODID + ":shaders/post/scan_pincushion.json")) {
// Minecraft.getInstance().gameRenderer.shutdownEffect();
// }
// }
float times = Minecraft.getInstance().getTimer().getGameTimeDeltaTicks();
LocalPlayer player = Minecraft.getInstance().player;
float yaw = event.getYaw();
float pitch = event.getPitch();
float roll = event.getRoll();
shakeTime = Mth.lerp(0.175 * times, shakeTime, 0);
if (player != null && shakeTime > 0) {
float shakeRadiusAmplitude = (float) Mth.clamp(1 - player.position().distanceTo(new Vec3(shakePos[0], shakePos[1], shakePos[2])) / shakeRadius, 0, 1);
boolean onVehicle = player.getVehicle() != null;
if (shakeType > 0) {
event.setYaw((float) (yaw + (shakeTime * Math.sin(0.5 * Math.PI * shakeTime) * shakeAmplitude * shakeRadiusAmplitude * shakeType * (onVehicle ? 0.4 : 1))));
event.setPitch((float) (pitch - (shakeTime * Math.sin(0.5 * Math.PI * shakeTime) * shakeAmplitude * shakeRadiusAmplitude * shakeType * (onVehicle ? 0.4 : 1))));
event.setRoll((float) (roll - (shakeTime * Math.sin(0.5 * Math.PI * shakeTime) * shakeAmplitude * shakeRadiusAmplitude * (onVehicle ? 0.4 : 1))));
} else {
event.setYaw((float) (yaw - (shakeTime * Math.sin(0.5 * Math.PI * shakeTime) * shakeAmplitude * shakeRadiusAmplitude * shakeType * (onVehicle ? 0.4 : 1))));
event.setPitch((float) (pitch + (shakeTime * Math.sin(0.5 * Math.PI * shakeTime) * shakeAmplitude * shakeRadiusAmplitude * shakeType * (onVehicle ? 0.4 : 1))));
event.setRoll((float) (roll + (shakeTime * Math.sin(0.5 * Math.PI * shakeTime) * shakeAmplitude * shakeRadiusAmplitude * (onVehicle ? 0.4 : 1))));
}
}
// TODO 完善事件处理
// cameraPitch = event.getPitch();
// cameraYaw = event.getYaw();
// cameraRoll = event.getRoll();
//
// if (player != null && player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.banHand(player)) {
// return;
// }
//
// if (level != null && stack.is(ModTags.Items.GUN)) {
// handleWeaponSway(living);
// handleWeaponMove(living);
// handleWeaponZoom(living);
// handlePlayerBreath(living);
// handleWeaponFire(event, living);
// handleWeaponShell();
// handleGunRecoil();
// handleBowPullAnimation(living);
// handleWeaponDraw(living);
// handlePlayerCamera(event);
// }
//
// handleShockCamera(event, living);
}
@Override
public @NotNull Type<? extends CustomPacketPayload> type() {
return TYPE;
}
}

View file

@ -22,9 +22,7 @@ public class EntityFindUtil {
return serverLevel.getEntities(); return serverLevel.getEntities();
} }
var clientLevel = (ClientLevel) level; var clientLevel = (ClientLevel) level;
// return clientLevel.getEntities(); return clientLevel.getEntities();
// TODO getEntities
return null;
} }
/** /**
@ -43,10 +41,9 @@ public class EntityFindUtil {
target = serverLevel.getEntity(uuid); target = serverLevel.getEntity(uuid);
} else { } else {
var clientLevel = (ClientLevel) level; var clientLevel = (ClientLevel) level;
// target = clientLevel.getEntities().get(uuid); target = clientLevel.getEntities().get(uuid);
} }
// return target; return target;
return null;
} catch (Exception ignored) { } catch (Exception ignored) {
} }

View file

@ -0,0 +1 @@
public net.minecraft.client.multiplayer.ClientLevel getEntities()Lnet/minecraft/world/level/entity/LevelEntityGetter; # getEntities