添加其他杂项类
This commit is contained in:
parent
89c9e52abf
commit
cc105575ff
92 changed files with 6471 additions and 857 deletions
|
@ -1,5 +1,6 @@
|
|||
package com.atsuishio.superbwarfare;
|
||||
|
||||
import com.atsuishio.superbwarfare.client.MouseMovementHandler;
|
||||
import com.atsuishio.superbwarfare.component.ModDataComponents;
|
||||
import com.atsuishio.superbwarfare.config.ClientConfig;
|
||||
import com.atsuishio.superbwarfare.config.CommonConfig;
|
||||
|
@ -12,6 +13,7 @@ import net.neoforged.bus.api.SubscribeEvent;
|
|||
import net.neoforged.fml.ModContainer;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
import net.neoforged.fml.config.ModConfig;
|
||||
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.neoforged.neoforge.client.event.ClientTickEvent;
|
||||
import net.neoforged.neoforge.common.NeoForge;
|
||||
import net.neoforged.neoforge.event.tick.ServerTickEvent;
|
||||
|
@ -56,7 +58,7 @@ public class ModUtils {
|
|||
ModAttributes.ATTRIBUTES.register(bus);
|
||||
|
||||
// bus.addListener(this::onCommonSetup);
|
||||
// bus.addListener(this::onClientSetup);
|
||||
bus.addListener(this::onClientSetup);
|
||||
bus.addListener(ModItems::registerDispenserBehavior);
|
||||
|
||||
bus.addListener(NetworkRegistry::register);
|
||||
|
@ -101,4 +103,8 @@ public class ModUtils {
|
|||
workQueueC.removeAll(actions);
|
||||
}
|
||||
|
||||
public void onClientSetup(final FMLClientSetupEvent event) {
|
||||
MouseMovementHandler.init();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.atsuishio.superbwarfare.capability.player;
|
|||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||
import com.atsuishio.superbwarfare.network.message.PlayerVariablesSyncMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.PlayerVariablesSyncMessage;
|
||||
import com.atsuishio.superbwarfare.tools.AmmoType;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
|
|
|
@ -0,0 +1,416 @@
|
|||
package com.atsuishio.superbwarfare.client;
|
||||
|
||||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||
import com.atsuishio.superbwarfare.config.client.ReloadConfig;
|
||||
import com.atsuishio.superbwarfare.entity.MortarEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.CannonEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.WeaponVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.event.ClientEventHandler;
|
||||
import com.atsuishio.superbwarfare.init.*;
|
||||
import com.atsuishio.superbwarfare.item.gun.GunItem;
|
||||
import com.atsuishio.superbwarfare.network.ModVariables;
|
||||
import com.atsuishio.superbwarfare.network.message.send.DoubleJumpMessage;
|
||||
import com.atsuishio.superbwarfare.perk.PerkHelper;
|
||||
import com.atsuishio.superbwarfare.tools.GunsTool;
|
||||
import com.atsuishio.superbwarfare.tools.NBTTool;
|
||||
import com.atsuishio.superbwarfare.tools.SeekTool;
|
||||
import com.atsuishio.superbwarfare.tools.TraceTool;
|
||||
import com.mojang.blaze3d.platform.InputConstants;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.client.settings.KeyConflictContext;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.client.event.InputEvent;
|
||||
import net.neoforged.neoforge.network.PacketDistributor;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import static com.atsuishio.superbwarfare.event.ClientEventHandler.cantFireTime;
|
||||
import static com.atsuishio.superbwarfare.event.ClientEventHandler.drawTime;
|
||||
|
||||
@EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME, value = Dist.CLIENT)
|
||||
public class ClickHandler {
|
||||
|
||||
public static boolean switchZoom = false;
|
||||
|
||||
private static boolean notInGame() {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
if (mc.player == null) return true;
|
||||
if (mc.getOverlay() != null) return true;
|
||||
if (mc.screen != null) return true;
|
||||
if (!mc.mouseHandler.isMouseGrabbed()) return true;
|
||||
return !mc.isWindowActive();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onButtonReleased(InputEvent.MouseButton.Pre event) {
|
||||
if (notInGame()) return;
|
||||
if (event.getAction() != InputConstants.RELEASE) return;
|
||||
|
||||
Player player = Minecraft.getInstance().player;
|
||||
if (player == null) return;
|
||||
|
||||
if (player.hasEffect(ModMobEffects.SHOCK)) return;
|
||||
|
||||
int button = event.getButton();
|
||||
if (button == ModKeyMappings.FIRE.getKey().getValue()) {
|
||||
handleWeaponFireRelease();
|
||||
}
|
||||
if (button == ModKeyMappings.HOLD_ZOOM.getKey().getValue()) {
|
||||
handleWeaponZoomRelease();
|
||||
return;
|
||||
}
|
||||
|
||||
if (button == ModKeyMappings.SWITCH_ZOOM.getKey().getValue() && !switchZoom) {
|
||||
handleWeaponZoomRelease();
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onButtonPressed(InputEvent.MouseButton.Pre event) {
|
||||
if (notInGame()) return;
|
||||
if (event.getAction() != InputConstants.PRESS) return;
|
||||
|
||||
Player player = Minecraft.getInstance().player;
|
||||
if (player == null) return;
|
||||
if (player.isSpectator()) return;
|
||||
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
|
||||
int button = event.getButton();
|
||||
|
||||
if (stack.is(ModTags.Items.GUN) || stack.is(ModItems.MONITOR.get()) || stack.is(ModItems.LUNGE_MINE.get()) || player.hasEffect(ModMobEffects.SHOCK)
|
||||
|| (player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.banHand(player))) {
|
||||
if (button == GLFW.GLFW_MOUSE_BUTTON_LEFT) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (player.hasEffect(ModMobEffects.SHOCK)) return;
|
||||
|
||||
if (button == GLFW.GLFW_MOUSE_BUTTON_RIGHT) {
|
||||
if (stack.is(ModTags.Items.GUN)
|
||||
|| (player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.isDriver(player) && stack.get(DataComponents.FOOD) != null)) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (button == GLFW.GLFW_MOUSE_BUTTON_MIDDLE) {
|
||||
if (player.hasEffect(ModMobEffects.SHOCK)) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.is(ModTags.Items.GUN)
|
||||
|| stack.is(ModItems.MONITOR.get())
|
||||
|| stack.is(ModItems.LUNGE_MINE.get())
|
||||
|| (player.getVehicle() instanceof ArmedVehicleEntity)
|
||||
|| (stack.is(Items.SPYGLASS) && player.isScoping() && player.getOffhandItem().is(ModItems.FIRING_PARAMETERS.get()))) {
|
||||
if (button == ModKeyMappings.FIRE.getKey().getValue()) {
|
||||
handleWeaponFirePress(player, stack);
|
||||
}
|
||||
|
||||
if (button == ModKeyMappings.HOLD_ZOOM.getKey().getValue()) {
|
||||
handleWeaponZoomPress(player, stack);
|
||||
switchZoom = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (button == ModKeyMappings.SWITCH_ZOOM.getKey().getValue()) {
|
||||
handleWeaponZoomPress(player, stack);
|
||||
switchZoom = !switchZoom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onMouseScrolling(InputEvent.MouseScrollingEvent event) {
|
||||
Player player = Minecraft.getInstance().player;
|
||||
|
||||
if (notInGame()) return;
|
||||
if (player == null) return;
|
||||
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
|
||||
if (player.hasEffect(ModMobEffects.SHOCK)) return;
|
||||
|
||||
double scroll = event.getScrollDeltaY();
|
||||
|
||||
// 未按下shift时,为有武器的载具切换武器
|
||||
if (!Screen.hasShiftDown()
|
||||
&& player.getVehicle() instanceof VehicleEntity vehicle
|
||||
&& vehicle instanceof WeaponVehicleEntity weaponVehicle
|
||||
&& weaponVehicle.hasWeapon(vehicle.getSeatIndex(player))
|
||||
) {
|
||||
int index = vehicle.getSeatIndex(player);
|
||||
PacketDistributor.sendToServer(new SwitchVehicleWeaponMessage(index, -scroll, true));
|
||||
event.setCanceled(true);
|
||||
}
|
||||
|
||||
var tag = NBTTool.getTag(stack);
|
||||
|
||||
if (stack.is(ModTags.Items.GUN) && ClientEventHandler.zoom) {
|
||||
if (GunsTool.getGunBooleanTag(stack, "CanSwitchScope", false)) {
|
||||
PacketDistributor.sendToServer(new SwitchScopeMessage(scroll));
|
||||
} else if (tag.getBoolean("CanAdjustZoomFov") || stack.is(ModItems.MINIGUN.get())) {
|
||||
PacketDistributor.sendToServer(new AdjustZoomFovMessage(scroll));
|
||||
}
|
||||
event.setCanceled(true);
|
||||
}
|
||||
|
||||
if (stack.is(ModItems.MONITOR.get()) && tag.getBoolean("Using") && tag.getBoolean("Linked")) {
|
||||
ClientEventHandler.droneFov = Mth.clamp(ClientEventHandler.droneFov + 0.4 * scroll, 1, 6);
|
||||
event.setCanceled(true);
|
||||
}
|
||||
|
||||
Entity looking = TraceTool.findLookingEntity(player, 6);
|
||||
if (looking == null) return;
|
||||
if (looking instanceof MortarEntity && player.isShiftKeyDown()) {
|
||||
PacketDistributor.sendToServer(new AdjustMortarAngleMessage(scroll));
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onKeyPressed(InputEvent.Key event) {
|
||||
if (notInGame()) return;
|
||||
|
||||
Player player = Minecraft.getInstance().player;
|
||||
if (player == null) return;
|
||||
if (player.isSpectator()) return;
|
||||
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
|
||||
int key = event.getKey();
|
||||
if (event.getAction() == GLFW.GLFW_PRESS) {
|
||||
if (player.hasEffect(ModMobEffects.SHOCK)) return;
|
||||
|
||||
if (key == Minecraft.getInstance().options.keyJump.getKey().getValue()) {
|
||||
handleDoubleJump(player);
|
||||
}
|
||||
if (key == ModKeyMappings.CONFIG.getKey().getValue() && ModKeyMappings.CONFIG.getKeyModifier().isActive(KeyConflictContext.IN_GAME)) {
|
||||
handleConfigScreen(player);
|
||||
}
|
||||
if (key == ModKeyMappings.RELOAD.getKey().getValue()) {
|
||||
PacketDistributor.sendToServer(new ReloadMessage(0));
|
||||
}
|
||||
if (key == ModKeyMappings.FIRE_MODE.getKey().getValue()) {
|
||||
PacketDistributor.sendToServer(new FireModeMessage(0));
|
||||
}
|
||||
if (key == ModKeyMappings.INTERACT.getKey().getValue()) {
|
||||
PacketDistributor.sendToServer(new InteractMessage(0));
|
||||
}
|
||||
if (key == ModKeyMappings.DISMOUNT.getKey().getValue()) {
|
||||
handleDismountPress(player);
|
||||
}
|
||||
if (key == ModKeyMappings.EDIT_MODE.getKey().getValue() && ClientEventHandler.burstFireSize == 0) {
|
||||
ClientEventHandler.holdFire = false;
|
||||
PacketDistributor.sendToServer(new EditModeMessage(0));
|
||||
}
|
||||
|
||||
if (player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables()).edit) {
|
||||
if (!(stack.getItem() instanceof GunItem gunItem)) return;
|
||||
if (ModKeyMappings.EDIT_GRIP.getKeyModifier().isActive(KeyConflictContext.IN_GAME)) {
|
||||
if (key == ModKeyMappings.EDIT_GRIP.getKey().getValue() && gunItem.hasCustomGrip(stack)) {
|
||||
PacketDistributor.sendToServer(new EditMessage(4));
|
||||
editModelShake();
|
||||
}
|
||||
} else {
|
||||
if (key == ModKeyMappings.EDIT_SCOPE.getKey().getValue() && gunItem.hasCustomScope(stack)) {
|
||||
PacketDistributor.sendToServer(new EditMessage(0));
|
||||
editModelShake();
|
||||
} else if (key == ModKeyMappings.EDIT_BARREL.getKey().getValue() && gunItem.hasCustomBarrel(stack)) {
|
||||
PacketDistributor.sendToServer(new EditMessage(1));
|
||||
editModelShake();
|
||||
} else if (key == ModKeyMappings.EDIT_MAGAZINE.getKey().getValue() && gunItem.hasCustomMagazine(stack)) {
|
||||
PacketDistributor.sendToServer(new EditMessage(2));
|
||||
editModelShake();
|
||||
} else if (key == ModKeyMappings.EDIT_STOCK.getKey().getValue() && gunItem.hasCustomStock(stack)) {
|
||||
PacketDistributor.sendToServer(new EditMessage(3));
|
||||
editModelShake();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (key == ModKeyMappings.SENSITIVITY_INCREASE.getKey().getValue()) {
|
||||
PacketDistributor.sendToServer(new SensitivityMessage(true));
|
||||
}
|
||||
if (key == ModKeyMappings.SENSITIVITY_REDUCE.getKey().getValue()) {
|
||||
PacketDistributor.sendToServer(new SensitivityMessage(false));
|
||||
}
|
||||
|
||||
if (stack.is(ModTags.Items.GUN)
|
||||
|| stack.is(ModItems.MONITOR.get())
|
||||
|| (player.getVehicle() instanceof ArmedVehicleEntity iVehicle && iVehicle.isDriver(player))
|
||||
|| (stack.is(Items.SPYGLASS) && player.isScoping() && player.getOffhandItem().is(ModItems.FIRING_PARAMETERS.get()))) {
|
||||
if (key == ModKeyMappings.FIRE.getKey().getValue()) {
|
||||
handleWeaponFirePress(player, stack);
|
||||
}
|
||||
|
||||
if (key == ModKeyMappings.HOLD_ZOOM.getKey().getValue()) {
|
||||
handleWeaponZoomPress(player, stack);
|
||||
switchZoom = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (key == ModKeyMappings.SWITCH_ZOOM.getKey().getValue()) {
|
||||
handleWeaponZoomPress(player, stack);
|
||||
switchZoom = !switchZoom;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (player.hasEffect(ModMobEffects.SHOCK)) return;
|
||||
|
||||
if (key == ModKeyMappings.FIRE.getKey().getValue()) {
|
||||
handleWeaponFireRelease();
|
||||
}
|
||||
if (key == ModKeyMappings.HOLD_ZOOM.getKey().getValue()) {
|
||||
handleWeaponZoomRelease();
|
||||
return;
|
||||
}
|
||||
|
||||
if (key == ModKeyMappings.SWITCH_ZOOM.getKey().getValue() && !switchZoom) {
|
||||
handleWeaponZoomRelease();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleWeaponFirePress(Player player, ItemStack stack) {
|
||||
if (player.hasEffect(ModMobEffects.SHOCK)) return;
|
||||
|
||||
if (stack.is(Items.SPYGLASS) && player.isScoping() && player.getOffhandItem().is(ModItems.FIRING_PARAMETERS.get())) {
|
||||
PacketDistributor.sendToServer(new SetFiringParametersMessage(0));
|
||||
}
|
||||
|
||||
if (stack.is(ModItems.MONITOR.get())) {
|
||||
PacketDistributor.sendToServer(new DroneFireMessage(0));
|
||||
}
|
||||
|
||||
|
||||
if (player.getVehicle() instanceof WeaponVehicleEntity iVehicle && iVehicle.banHand(player)) {
|
||||
if (player.getVehicle() instanceof VehicleEntity pVehicle && iVehicle.hasWeapon(pVehicle.getSeatIndex(player))) {
|
||||
ClientEventHandler.holdFireVehicle = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (stack.is(ModItems.LUNGE_MINE.get())) {
|
||||
ClientEventHandler.holdFire = true;
|
||||
}
|
||||
|
||||
if (stack.getItem() instanceof GunItem gunItem && !(player.getVehicle() != null && player.getVehicle() instanceof CannonEntity)) {
|
||||
var tag = NBTTool.getTag(stack);
|
||||
if ((!(tag.getBoolean("is_normal_reloading") || tag.getBoolean("is_empty_reloading"))
|
||||
&& !GunsTool.getGunBooleanTag(stack, "Reloading")
|
||||
&& !GunsTool.getGunBooleanTag(stack, "Charging")
|
||||
&& !GunsTool.getGunBooleanTag(stack, "NeedBoltAction", false))
|
||||
&& cantFireTime == 0
|
||||
&& drawTime < 0.01
|
||||
&& !notInGame()) {
|
||||
player.playSound(ModSounds.TRIGGER_CLICK.get(), 1, 1);
|
||||
}
|
||||
|
||||
if (!gunItem.useBackpackAmmo(stack) && GunsTool.getGunIntTag(stack, "Ammo", 0) <= 0 && GunsTool.getGunIntTag(stack, "ReloadTime") == 0) {
|
||||
if (ReloadConfig.LEFT_CLICK_RELOAD.get()) {
|
||||
PacketDistributor.sendToServer(new ReloadMessage(0));
|
||||
}
|
||||
} else {
|
||||
PacketDistributor.sendToServer(new FireMessage(0));
|
||||
if (!stack.is(ModItems.BOCEK.get())) {
|
||||
ClientEventHandler.holdFire = true;
|
||||
}
|
||||
if (GunsTool.getGunIntTag(stack, "FireMode") == 1 && ClientEventHandler.burstFireSize == 0) {
|
||||
ClientEventHandler.burstFireSize = GunsTool.getGunIntTag(stack, "BurstSize", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleWeaponFireRelease() {
|
||||
PacketDistributor.sendToServer(new FireMessage(1));
|
||||
ClientEventHandler.holdFire = false;
|
||||
ClientEventHandler.holdFireVehicle = false;
|
||||
ClientEventHandler.customRpm = 0;
|
||||
}
|
||||
|
||||
public static void handleWeaponZoomPress(Player player, ItemStack stack) {
|
||||
PacketDistributor.sendToServer(new ZoomMessage(0));
|
||||
|
||||
if (player.getVehicle() instanceof VehicleEntity pVehicle && player.getVehicle() instanceof WeaponVehicleEntity iVehicle && iVehicle.hasWeapon(pVehicle.getSeatIndex(player))) {
|
||||
ClientEventHandler.zoomVehicle = true;
|
||||
return;
|
||||
}
|
||||
|
||||
ClientEventHandler.zoom = true;
|
||||
int level = PerkHelper.getItemPerkLevel(ModPerks.INTELLIGENT_CHIP.get(), stack);
|
||||
if (level > 0) {
|
||||
if (ClientEventHandler.entity == null) {
|
||||
ClientEventHandler.entity = SeekTool.seekLivingEntity(player, player.level(), 32 + 8 * (level - 1), 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleWeaponZoomRelease() {
|
||||
PacketDistributor.sendToServer(new ZoomMessage(1));
|
||||
ClientEventHandler.zoom = false;
|
||||
ClientEventHandler.zoomVehicle = false;
|
||||
ClientEventHandler.entity = null;
|
||||
}
|
||||
|
||||
private static void editModelShake() {
|
||||
ClientEventHandler.movePosY = -0.8;
|
||||
ClientEventHandler.fireRotTimer = 0.4;
|
||||
}
|
||||
|
||||
private static void handleDoubleJump(Player player) {
|
||||
Level level = player.level();
|
||||
double x = player.getX();
|
||||
double y = player.getY();
|
||||
double z = player.getZ();
|
||||
|
||||
if (!level.isLoaded(player.blockPosition())) {
|
||||
return;
|
||||
}
|
||||
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap != null && cap.playerDoubleJump) {
|
||||
player.setDeltaMovement(new Vec3(player.getLookAngle().x, 0.8, player.getLookAngle().z));
|
||||
level.playLocalSound(x, y, z, ModSounds.DOUBLE_JUMP.get(), SoundSource.BLOCKS, 1, 1, false);
|
||||
|
||||
PacketDistributor.sendToServer(new DoubleJumpMessage(false));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO do we need cloth config?
|
||||
// private static void handleConfigScreen(Player player) {
|
||||
// if (ModList.get().isLoaded(CompatHolder.CLOTH_CONFIG)) {
|
||||
// CompatHolder.hasMod(CompatHolder.CLOTH_CONFIG, () -> Minecraft.getInstance().setScreen(ClothConfigHelper.getConfigScreen(null)));
|
||||
// } else {
|
||||
// player.displayClientMessage(Component.translatable("tips.superbwarfare.no_cloth_config").withStyle(ChatFormatting.RED), true);
|
||||
// }
|
||||
// }
|
||||
|
||||
private static void handleDismountPress(Player player) {
|
||||
var vehicle = player.getVehicle();
|
||||
if (!(vehicle instanceof VehicleEntity)) return;
|
||||
|
||||
if ((!vehicle.onGround() || vehicle.getDeltaMovement().length() >= 0.1) && ClientEventHandler.dismountCountdown <= 0) {
|
||||
player.displayClientMessage(Component.translatable("mount.onboard", ModKeyMappings.DISMOUNT.getTranslatedKeyMessage()), true);
|
||||
ClientEventHandler.dismountCountdown = 20;
|
||||
return;
|
||||
}
|
||||
PacketDistributor.sendToServer(new PlayerStopRidingMessage(0));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.atsuishio.superbwarfare.client;
|
||||
|
||||
import com.atsuishio.superbwarfare.tools.NBTTool;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import software.bernie.geckolib.cache.object.GeoBone;
|
||||
|
||||
public class ItemModelHelper {
|
||||
|
||||
public static void handleGunAttachments(GeoBone bone, ItemStack stack, String name) {
|
||||
var rootTag = NBTTool.getTag(stack);
|
||||
CompoundTag tag = rootTag.getCompound("Attachments");
|
||||
|
||||
splitBoneName(bone, name, "Scope", tag);
|
||||
splitBoneName(bone, name, "Magazine", tag);
|
||||
splitBoneName(bone, name, "Barrel", tag);
|
||||
splitBoneName(bone, name, "Stock", tag);
|
||||
splitBoneName(bone, name, "Grip", tag);
|
||||
}
|
||||
|
||||
private static void splitBoneName(GeoBone bone, String boneName, String tagName, CompoundTag tag) {
|
||||
try {
|
||||
if (boneName.startsWith(tagName)) {
|
||||
String[] parts = boneName.split("(?<=\\D)(?=\\d)");
|
||||
if (parts.length == 2) {
|
||||
int index = Integer.parseInt(parts[1]);
|
||||
bone.setHidden(tag.getInt(tagName) != index);
|
||||
}
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
package com.atsuishio.superbwarfare.client;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.MouseHandler;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.world.phys.Vec2;
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
/**
|
||||
* Codes from @getItemFromBlock's Create-Tweaked-Controllers
|
||||
*/
|
||||
public class MouseMovementHandler {
|
||||
|
||||
public static Vec2 delta = null;
|
||||
public static Vec2 lastPos = null;
|
||||
public static Vec2 vel = null;
|
||||
private static MouseHandler mouseHandler = null;
|
||||
private static boolean mouseLockActive = false;
|
||||
private static final Vector3f savedRot = new Vector3f();
|
||||
|
||||
public static Vec2 getMousePos() {
|
||||
if (mouseHandler.isMouseGrabbed()) {
|
||||
return new Vec2((float) mouseHandler.xpos(), (float) mouseHandler.ypos());
|
||||
} else {
|
||||
double[] x, y;
|
||||
x = new double[1];
|
||||
y = new double[1];
|
||||
GLFW.glfwGetCursorPos(Minecraft.getInstance().getWindow().getWindow(), x, y);
|
||||
return new Vec2((float) x[0], (float) y[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void resetCenter() {
|
||||
delta = new Vec2(0, 0);
|
||||
vel = new Vec2(0, 0);
|
||||
lastPos = getMousePos();
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
delta = new Vec2(0, 0);
|
||||
vel = new Vec2(0, 0);
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
mouseHandler = mc.mouseHandler;
|
||||
lastPos = getMousePos();
|
||||
}
|
||||
|
||||
public static float getX(boolean useVelocity) {
|
||||
if (useVelocity) {
|
||||
return vel.x;
|
||||
} else {
|
||||
return delta.x;
|
||||
}
|
||||
}
|
||||
|
||||
public static float getY(boolean useVelocity) {
|
||||
if (useVelocity) {
|
||||
return vel.y;
|
||||
} else {
|
||||
return delta.y;
|
||||
}
|
||||
}
|
||||
|
||||
public static void activateMouseLock() {
|
||||
LocalPlayer player = Minecraft.getInstance().player;
|
||||
if (player == null) return;
|
||||
|
||||
savedRot.x = player.getXRot();
|
||||
savedRot.y = player.getYRot();
|
||||
savedRot.z = 0;
|
||||
mouseLockActive = true;
|
||||
lastPos = getMousePos();
|
||||
}
|
||||
|
||||
public static void deactivateMouseLock() {
|
||||
mouseLockActive = false;
|
||||
}
|
||||
|
||||
public static void cancelPlayerTurn() {
|
||||
if (!mouseLockActive) return;
|
||||
LocalPlayer player = Minecraft.getInstance().player;
|
||||
if (player == null) return;
|
||||
player.turn((savedRot.y - player.getYRot()) / 0.15f, (savedRot.x - player.getXRot()) / 0.15f);
|
||||
player.xBob = savedRot.x;
|
||||
player.yBob = savedRot.y;
|
||||
player.xBobO = savedRot.x;
|
||||
player.yBobO = savedRot.y;
|
||||
}
|
||||
}
|
|
@ -2,10 +2,16 @@ package com.atsuishio.superbwarfare.client;
|
|||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.*;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.culling.Frustum;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class RenderHelper {
|
||||
// code from GuiGraphics
|
||||
|
@ -204,10 +210,7 @@ public class RenderHelper {
|
|||
* @param maxU the maximum horizontal texture coordinate.
|
||||
* @param minV the minimum vertical texture coordinate.
|
||||
* @param maxV the maximum vertical texture coordinate.
|
||||
* @param red the red component of the color tfloat.
|
||||
* @param green the green component of the color tfloat.
|
||||
* @param blue the blue component of the color tfloat.
|
||||
* @param alpha the alpha component of the color tfloat.
|
||||
* @param color color
|
||||
*/
|
||||
public static void innerBlit(
|
||||
GuiGraphics gui,
|
||||
|
@ -239,4 +242,24 @@ public class RenderHelper {
|
|||
BufferUploader.drawWithShader(bufferbuilder.buildOrThrow());
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
|
||||
/**
|
||||
* Codes based on @Xjqsh
|
||||
*/
|
||||
@Nullable
|
||||
public static Vec3 worldToScreen(Vec3 pos, Vec3 cameraPos) {
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
Frustum frustum = minecraft.levelRenderer.getFrustum();
|
||||
|
||||
Vector3f relativePos = pos.subtract(cameraPos).toVector3f();
|
||||
Vector3f transformedPos = frustum.matrix.transformProject(relativePos.x, relativePos.y, relativePos.z, new Vector3f());
|
||||
|
||||
double scaleFactor = minecraft.getWindow().getGuiScale();
|
||||
float guiScaleMul = 0.5f / (float) scaleFactor;
|
||||
|
||||
Vector3f screenPos = transformedPos.mul(1.0f, -1.0f, 1.0f).add(1.0f, 1.0f, 0.0f)
|
||||
.mul(guiScaleMul * minecraft.getWindow().getWidth(), guiScaleMul * minecraft.getWindow().getHeight(), 1.0f);
|
||||
|
||||
return transformedPos.z < 1.0f ? new Vec3(screenPos.x, screenPos.y, transformedPos.z) : null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,485 @@
|
|||
package com.atsuishio.superbwarfare.client.overlay;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||
import com.atsuishio.superbwarfare.capability.player.PlayerVariable;
|
||||
import com.atsuishio.superbwarfare.config.client.DisplayConfig;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.init.ModKeyMappings;
|
||||
import com.atsuishio.superbwarfare.init.ModTags;
|
||||
import com.atsuishio.superbwarfare.item.common.ammo.AmmoSupplierItem;
|
||||
import com.atsuishio.superbwarfare.item.gun.GunItem;
|
||||
import com.atsuishio.superbwarfare.tools.AmmoType;
|
||||
import com.atsuishio.superbwarfare.tools.GunsTool;
|
||||
import com.atsuishio.superbwarfare.tools.InventoryTool;
|
||||
import com.atsuishio.superbwarfare.tools.NBTTool;
|
||||
import com.atsuishio.superbwarfare.tools.animation.AnimationCurves;
|
||||
import com.atsuishio.superbwarfare.tools.animation.AnimationTimer;
|
||||
import com.atsuishio.superbwarfare.tools.animation.ValueAnimator;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.FastColor;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.client.event.RenderGuiEvent;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class AmmoBarOverlay {
|
||||
|
||||
private static final ResourceLocation LINE = ModUtils.loc("textures/gun_icon/fire_mode/line.png");
|
||||
private static final ResourceLocation SEMI = ModUtils.loc("textures/gun_icon/fire_mode/semi.png");
|
||||
private static final ResourceLocation BURST = ModUtils.loc("textures/gun_icon/fire_mode/burst.png");
|
||||
private static final ResourceLocation AUTO = ModUtils.loc("textures/gun_icon/fire_mode/auto.png");
|
||||
private static final ResourceLocation TOP = ModUtils.loc("textures/gun_icon/fire_mode/top.png");
|
||||
private static final ResourceLocation DIR = ModUtils.loc("textures/gun_icon/fire_mode/dir.png");
|
||||
private static final ResourceLocation MOUSE = ModUtils.loc("textures/gun_icon/fire_mode/mouse.png");
|
||||
|
||||
private static boolean hasCreativeAmmo() {
|
||||
Player player = Minecraft.getInstance().player;
|
||||
if (player == null) return false;
|
||||
return InventoryTool.hasCreativeAmmoBox(player);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void renderWeaponInfo(RenderGuiEvent.Pre event) {
|
||||
if (!DisplayConfig.AMMO_HUD.get()) return;
|
||||
|
||||
int w = event.getGuiGraphics().guiWidth();
|
||||
int h = event.getGuiGraphics().guiHeight();
|
||||
Player player = Minecraft.getInstance().player;
|
||||
|
||||
if (player == null) return;
|
||||
if (player.isSpectator()) return;
|
||||
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
if (stack.getItem() instanceof GunItem gunItem && !(player.getVehicle() instanceof ArmedVehicleEntity vehicle && vehicle.banHand(player))) {
|
||||
PoseStack poseStack = event.getGuiGraphics().pose();
|
||||
|
||||
// 渲染图标
|
||||
event.getGuiGraphics().blit(gunItem.getGunIcon(),
|
||||
w - 135,
|
||||
h - 40,
|
||||
0,
|
||||
0,
|
||||
64,
|
||||
16,
|
||||
64,
|
||||
16);
|
||||
|
||||
// 渲染开火模式切换按键
|
||||
if (stack.getItem() != ModItems.MINIGUN.get()) {
|
||||
event.getGuiGraphics().drawString(
|
||||
Minecraft.getInstance().font,
|
||||
"[" + ModKeyMappings.FIRE_MODE.getKey().getDisplayName().getString() + "]",
|
||||
w - 111.5f,
|
||||
h - 20,
|
||||
0xFFFFFF,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
// 渲染开火模式
|
||||
ResourceLocation fireMode = getFireMode(stack);
|
||||
|
||||
if (stack.getItem() == ModItems.JAVELIN.get()) {
|
||||
fireMode = NBTTool.getBoolean(stack, "TopMode", false) ? TOP : DIR;
|
||||
}
|
||||
|
||||
if (stack.getItem() == ModItems.MINIGUN.get()) {
|
||||
fireMode = MOUSE;
|
||||
// 渲染加特林射速
|
||||
event.getGuiGraphics().drawString(
|
||||
Minecraft.getInstance().font,
|
||||
GunsTool.getGunIntTag(stack, "RPM", 0) + " RPM",
|
||||
w - 111f,
|
||||
h - 20,
|
||||
0xFFFFFF,
|
||||
false
|
||||
);
|
||||
|
||||
event.getGuiGraphics().blit(fireMode,
|
||||
w - 126,
|
||||
h - 22,
|
||||
0,
|
||||
0,
|
||||
12,
|
||||
12,
|
||||
12,
|
||||
12);
|
||||
} else {
|
||||
if (stack.getItem() != ModItems.TRACHELIUM.get()) {
|
||||
event.getGuiGraphics().blit(fireMode,
|
||||
w - 95,
|
||||
h - 21,
|
||||
0,
|
||||
0,
|
||||
8,
|
||||
8,
|
||||
8,
|
||||
8);
|
||||
} else {
|
||||
event.getGuiGraphics().drawString(
|
||||
Minecraft.getInstance().font,
|
||||
NBTTool.getBoolean(stack, "DA", false) ? Component.translatable("des.superbwarfare.revolver.sa").withStyle(ChatFormatting.BOLD) : Component.translatable("des.superbwarfare.revolver.da").withStyle(ChatFormatting.BOLD),
|
||||
w - 96,
|
||||
h - 20,
|
||||
0xFFFFFF,
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.getItem() != ModItems.MINIGUN.get() && stack.getItem() != ModItems.TRACHELIUM.get()) {
|
||||
event.getGuiGraphics().blit(LINE,
|
||||
w - 95,
|
||||
h - 16,
|
||||
0,
|
||||
0,
|
||||
8,
|
||||
8,
|
||||
8,
|
||||
8);
|
||||
}
|
||||
|
||||
// 渲染当前弹药量
|
||||
poseStack.pushPose();
|
||||
poseStack.scale(1.5f, 1.5f, 1f);
|
||||
|
||||
if ((stack.getItem() == ModItems.MINIGUN.get() || stack.getItem() == ModItems.BOCEK.get()) && hasCreativeAmmo()) {
|
||||
event.getGuiGraphics().drawString(
|
||||
Minecraft.getInstance().font,
|
||||
"∞",
|
||||
w / 1.5f - 64 / 1.5f,
|
||||
h / 1.5f - 48 / 1.5f,
|
||||
0xFFFFFF,
|
||||
true
|
||||
);
|
||||
} else {
|
||||
event.getGuiGraphics().drawString(
|
||||
Minecraft.getInstance().font,
|
||||
getGunAmmoCount(player) + "",
|
||||
w / 1.5f - 64 / 1.5f,
|
||||
h / 1.5f - 48 / 1.5f,
|
||||
0xFFFFFF,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
poseStack.popPose();
|
||||
|
||||
// 渲染备弹量
|
||||
event.getGuiGraphics().drawString(
|
||||
Minecraft.getInstance().font,
|
||||
getPlayerAmmoCount(player),
|
||||
w - 64,
|
||||
h - 35,
|
||||
0xCCCCCC,
|
||||
true
|
||||
);
|
||||
|
||||
poseStack.pushPose();
|
||||
poseStack.scale(0.9f, 0.9f, 1f);
|
||||
|
||||
// 渲染物品名称
|
||||
String gunName = gunItem.getGunDisplayName();
|
||||
event.getGuiGraphics().drawString(
|
||||
Minecraft.getInstance().font,
|
||||
gunName,
|
||||
w / 0.9f - (100 + Minecraft.getInstance().font.width(gunName) / 2f) / 0.9f,
|
||||
h / 0.9f - 60 / 0.9f,
|
||||
0xFFFFFF,
|
||||
true
|
||||
);
|
||||
|
||||
// 渲染弹药类型
|
||||
String ammoName = getGunAmmoType(stack);
|
||||
event.getGuiGraphics().drawString(
|
||||
Minecraft.getInstance().font,
|
||||
ammoName,
|
||||
w / 0.9f - (100 + Minecraft.getInstance().font.width(ammoName) / 2f) / 0.9f,
|
||||
h / 0.9f - 51 / 0.9f,
|
||||
0xC8A679,
|
||||
true
|
||||
);
|
||||
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
||||
|
||||
private static final AnimationTimer ammoInfoTimer = new AnimationTimer(500, 2000)
|
||||
.forwardAnimation(AnimationCurves.EASE_OUT_EXPO)
|
||||
.backwardAnimation(AnimationCurves.EASE_IN_EXPO);
|
||||
private static final AnimationTimer ammoBoxTimer = new AnimationTimer(500)
|
||||
.forwardAnimation(AnimationCurves.EASE_OUT_EXPO)
|
||||
.backwardAnimation(AnimationCurves.EASE_IN_EXPO);
|
||||
|
||||
private static final ValueAnimator<Integer>[] ammoCountAnimators = ValueAnimator.create(
|
||||
AmmoType.values().length, 800, 0
|
||||
);
|
||||
private static final ValueAnimator<Integer>[] ammoBoxAnimators = ValueAnimator.create(
|
||||
AmmoType.values().length, 800, 0
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* 在手持弹药或弹药盒时,渲染玩家弹药总量信息
|
||||
*/
|
||||
@SubscribeEvent
|
||||
public static void renderAmmoInfo(RenderGuiEvent.Pre event) {
|
||||
boolean startRenderingAmmoInfo = false;
|
||||
Player player = Minecraft.getInstance().player;
|
||||
if (player == null || player.isSpectator()) return;
|
||||
|
||||
boolean isAmmoBox = false;
|
||||
|
||||
// 动画计算
|
||||
var currentTime = System.currentTimeMillis();
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
if ((stack.getItem() instanceof AmmoSupplierItem || stack.getItem() == ModItems.AMMO_BOX.get())
|
||||
&& !(player.getVehicle() instanceof ArmedVehicleEntity vehicle && vehicle.banHand(player))
|
||||
) {
|
||||
// 刚拿出弹药物品时,视为开始弹药信息渲染
|
||||
startRenderingAmmoInfo = ammoInfoTimer.getProgress(currentTime) == 0;
|
||||
ammoInfoTimer.forward(currentTime);
|
||||
|
||||
if (stack.getItem() == ModItems.AMMO_BOX.get()) {
|
||||
isAmmoBox = true;
|
||||
ammoBoxTimer.forward(currentTime);
|
||||
} else {
|
||||
ammoBoxTimer.backward(currentTime);
|
||||
}
|
||||
} else {
|
||||
ammoInfoTimer.backward(currentTime);
|
||||
ammoBoxTimer.backward(currentTime);
|
||||
}
|
||||
if (!ammoInfoTimer.isForward() && ammoInfoTimer.finished(currentTime)) return;
|
||||
|
||||
var poseStack = event.getGuiGraphics().pose();
|
||||
poseStack.pushPose();
|
||||
|
||||
int w = event.getGuiGraphics().guiWidth();
|
||||
int h = event.getGuiGraphics().guiHeight();
|
||||
|
||||
var ammoX = ammoInfoTimer.lerp(w + 120, (float) w / 2 + 40, currentTime);
|
||||
final int fontHeight = 15;
|
||||
var yOffset = (-h - AmmoType.values().length * fontHeight) / 2f;
|
||||
|
||||
// 渲染总弹药数量
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap == null) cap = new PlayerVariable();
|
||||
var font = Minecraft.getInstance().font;
|
||||
|
||||
for (var type : AmmoType.values()) {
|
||||
var index = type.ordinal();
|
||||
var ammoCount = type.get(cap);
|
||||
var animator = ammoCountAnimators[index];
|
||||
|
||||
var boxAnimator = ammoBoxAnimators[index];
|
||||
var boxAmmoCount = boxAnimator.newValue();
|
||||
boolean boxAmmoSelected = false;
|
||||
|
||||
if (isAmmoBox) {
|
||||
var tag = NBTTool.getTag(stack);
|
||||
var ammoBoxType = tag.getString("Type");
|
||||
boxAmmoCount = type.get(stack);
|
||||
if (ammoBoxType.equals("All") || ammoBoxType.equals(type.name)) {
|
||||
boxAnimator.forward(currentTime);
|
||||
boxAmmoSelected = true;
|
||||
} else {
|
||||
boxAnimator.reset(boxAmmoCount);
|
||||
}
|
||||
}
|
||||
|
||||
// 首次开始渲染弹药信息时,记录弹药数量,便于后续播放动画
|
||||
if (startRenderingAmmoInfo) {
|
||||
animator.reset(ammoCount);
|
||||
animator.endForward(currentTime);
|
||||
if (isAmmoBox) {
|
||||
boxAnimator.reset(type.get(stack));
|
||||
boxAnimator.endForward(currentTime);
|
||||
}
|
||||
}
|
||||
|
||||
int ammoAdd = Integer.compare(ammoCount, animator.oldValue());
|
||||
// 弹药数量变化时,更新并开始播放弹药数量更改动画
|
||||
animator.compareAndUpdate(ammoCount, () -> {
|
||||
// 弹药数量变化时,开始播放弹药数量更改动画
|
||||
animator.beginForward(currentTime);
|
||||
});
|
||||
|
||||
var progress = animator.getProgress(currentTime);
|
||||
var ammoCountStr = Integer.toString(
|
||||
Math.round(animator.lerp(animator.oldValue(), ammoCount, currentTime))
|
||||
);
|
||||
|
||||
// 弹药增加时,颜色由绿变白,否则由红变白
|
||||
var fontColor = FastColor.ARGB32.lerp(progress, switch (ammoAdd) {
|
||||
case 1 -> 0xFF00FF00;
|
||||
case -1 -> 0xFFFF0000;
|
||||
default -> 0xFFFFFFFF;
|
||||
}, 0xFFFFFFFF);
|
||||
|
||||
RenderSystem.setShaderColor(1, 1, 1, ammoInfoTimer.lerp(0, 1, currentTime));
|
||||
|
||||
// 弹药数量
|
||||
event.getGuiGraphics().drawString(
|
||||
font,
|
||||
ammoCountStr,
|
||||
ammoX + (30 - font.width(ammoCountStr)),
|
||||
h + yOffset,
|
||||
fontColor,
|
||||
true
|
||||
);
|
||||
|
||||
// 弹药类型
|
||||
event.getGuiGraphics().drawString(
|
||||
font,
|
||||
Component.translatable(type.translatableKey).getString(),
|
||||
ammoX + 35,
|
||||
h + yOffset,
|
||||
fontColor,
|
||||
true
|
||||
);
|
||||
|
||||
// 弹药盒信息渲染
|
||||
RenderSystem.setShaderColor(1, 1, 1, ammoBoxTimer.lerp(0, 1, currentTime));
|
||||
var ammoBoxX = ammoBoxTimer.lerp(-30, (float) w / 2, currentTime);
|
||||
|
||||
int ammoBoxAdd = Integer.compare(boxAmmoCount, boxAnimator.oldValue());
|
||||
boxAnimator.compareAndUpdate(boxAmmoCount, () -> boxAnimator.beginForward(currentTime));
|
||||
|
||||
// 选中时显示为黄色,否则为白色
|
||||
var targetColor = boxAmmoSelected ? 0xFFFFFF00 : 0xFFFFFFFF;
|
||||
|
||||
var boxFontColor = FastColor.ARGB32.lerp(boxAnimator.getProgress(currentTime),
|
||||
switch (ammoBoxAdd) {
|
||||
case 1 -> 0xFF00FF00;
|
||||
case -1 -> 0xFFFF0000;
|
||||
default -> targetColor;
|
||||
},
|
||||
targetColor
|
||||
);
|
||||
|
||||
// 弹药盒内弹药数量
|
||||
event.getGuiGraphics().drawString(
|
||||
Minecraft.getInstance().font,
|
||||
Integer.toString(
|
||||
Math.round(boxAnimator.lerp(boxAnimator.oldValue(), boxAmmoCount, currentTime))
|
||||
),
|
||||
ammoBoxX - 70,
|
||||
h + yOffset,
|
||||
boxFontColor,
|
||||
true
|
||||
);
|
||||
|
||||
yOffset += fontHeight;
|
||||
}
|
||||
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||
poseStack.popPose();
|
||||
}
|
||||
|
||||
private static ResourceLocation getFireMode(ItemStack stack) {
|
||||
return switch (GunsTool.getGunIntTag(stack, "FireMode")) {
|
||||
case 1 -> BURST;
|
||||
case 2 -> AUTO;
|
||||
default -> SEMI;
|
||||
};
|
||||
}
|
||||
|
||||
private static int getGunAmmoCount(Player player) {
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
|
||||
if (stack.getItem() == ModItems.MINIGUN.get()) {
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
return cap != null ? cap.rifleAmmo : 0;
|
||||
}
|
||||
|
||||
if (stack.getItem() == ModItems.BOCEK.get()) {
|
||||
return GunsTool.getGunIntTag(stack, "MaxAmmo");
|
||||
}
|
||||
|
||||
return GunsTool.getGunIntTag(stack, "Ammo", 0);
|
||||
}
|
||||
|
||||
private static String getPlayerAmmoCount(Player player) {
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
|
||||
if (stack.getItem() == ModItems.MINIGUN.get() || stack.getItem() == ModItems.BOCEK.get()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (!hasCreativeAmmo()) {
|
||||
if (stack.is(ModTags.Items.LAUNCHER) || stack.getItem() == ModItems.TASER.get()) {
|
||||
return "" + GunsTool.getGunIntTag(stack, "MaxAmmo");
|
||||
}
|
||||
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap == null) return "";
|
||||
|
||||
if (stack.is(ModTags.Items.USE_RIFLE_AMMO)) {
|
||||
return "" + cap.rifleAmmo;
|
||||
}
|
||||
if (stack.is(ModTags.Items.USE_HANDGUN_AMMO)) {
|
||||
return "" + cap.handgunAmmo;
|
||||
}
|
||||
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO)) {
|
||||
return "" + cap.shotgunAmmo;
|
||||
}
|
||||
if (stack.is(ModTags.Items.USE_SNIPER_AMMO)) {
|
||||
return "" + cap.sniperAmmo;
|
||||
}
|
||||
if (stack.is(ModTags.Items.USE_HEAVY_AMMO)) {
|
||||
return "" + cap.heavyAmmo;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
return "∞";
|
||||
}
|
||||
|
||||
private static String getGunAmmoType(ItemStack stack) {
|
||||
if (stack.getItem() == ModItems.BOCEK.get()) {
|
||||
return "Arrow";
|
||||
}
|
||||
if (stack.getItem() == ModItems.M_79.get() || stack.getItem() == ModItems.SECONDARY_CATACLYSM.get()) {
|
||||
return "40mm Grenade";
|
||||
}
|
||||
if (stack.getItem() == ModItems.RPG.get()) {
|
||||
return "Yassin105 TBG";
|
||||
}
|
||||
if (stack.getItem() == ModItems.JAVELIN.get()) {
|
||||
return "Javelin Missile";
|
||||
}
|
||||
if (stack.getItem() == ModItems.TASER.get()) {
|
||||
return "Electrode Rod";
|
||||
}
|
||||
if (stack.getItem() == ModItems.MINIGUN.get()) {
|
||||
return "Rifle Ammo";
|
||||
}
|
||||
if (stack.is(ModTags.Items.USE_RIFLE_AMMO)) {
|
||||
return "Rifle Ammo";
|
||||
}
|
||||
if (stack.is(ModTags.Items.USE_HANDGUN_AMMO)) {
|
||||
return "Handgun Ammo";
|
||||
}
|
||||
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO)) {
|
||||
return "Shotgun Ammo";
|
||||
}
|
||||
if (stack.is(ModTags.Items.USE_SNIPER_AMMO)) {
|
||||
return "Sniper Ammo";
|
||||
}
|
||||
if (stack.is(ModTags.Items.USE_HEAVY_AMMO)) {
|
||||
return "Heavy Ammo";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package com.atsuishio.superbwarfare.client.overlay;
|
|||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||
import com.atsuishio.superbwarfare.component.ModDataComponents;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.item.common.ammo.AmmoSupplierItem;
|
||||
import com.atsuishio.superbwarfare.item.common.ammo.box.AmmoBoxInfo;
|
||||
|
@ -53,10 +54,7 @@ public class AmmoOverlay {
|
|||
// 动画计算
|
||||
var currentTime = System.currentTimeMillis();
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
if ((stack.getItem() instanceof AmmoSupplierItem || stack.getItem() == ModItems.AMMO_BOX.get())
|
||||
// TODO vehicle
|
||||
// && !(player.getVehicle() instanceof ArmedVehicleEntity vehicle && vehicle.banHand(player))
|
||||
) {
|
||||
if ((stack.getItem() instanceof AmmoSupplierItem || stack.getItem() == ModItems.AMMO_BOX.get()) && !(player.getVehicle() instanceof ArmedVehicleEntity vehicle && vehicle.banHand(player))) {
|
||||
// 刚拿出弹药物品时,视为开始弹药信息渲染
|
||||
startRenderingAmmoInfo = ammoInfoTimer.getProgress(currentTime) == 0;
|
||||
ammoInfoTimer.forward(currentTime);
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package com.atsuishio.superbwarfare.client.overlay;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.client.event.RenderGuiEvent;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class ArmRendererFixOverlay {
|
||||
|
||||
@SubscribeEvent
|
||||
public static void eventHandler(RenderGuiEvent.Pre event) {
|
||||
int w = event.getGuiGraphics().guiWidth();
|
||||
int h = event.getGuiGraphics().guiHeight();
|
||||
Player entity = Minecraft.getInstance().player;
|
||||
if (entity != null) {
|
||||
// TODO what is this?
|
||||
// InventoryScreen.renderEntityInInventoryFollowsAngle(
|
||||
// event.getGuiGraphics(),
|
||||
// w / 2 - 114514,
|
||||
// h / 2 + 22,
|
||||
// 1,
|
||||
// 0f,
|
||||
// 0,
|
||||
// entity
|
||||
// );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package com.atsuishio.superbwarfare.client.overlay;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.config.client.DisplayConfig;
|
||||
import com.atsuishio.superbwarfare.init.ModTags;
|
||||
import com.atsuishio.superbwarfare.tools.NBTTool;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.client.event.RenderGuiEvent;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class ArmorPlateOverlay {
|
||||
|
||||
private static final ResourceLocation ICON = ModUtils.loc("textures/screens/armor_plate_icon.png");
|
||||
private static final ResourceLocation LEVEL1 = ModUtils.loc("textures/screens/armor_plate_level1.png");
|
||||
private static final ResourceLocation LEVEL2 = ModUtils.loc("textures/screens/armor_plate_level2.png");
|
||||
private static final ResourceLocation LEVEL3 = ModUtils.loc("textures/screens/armor_plate_level3.png");
|
||||
private static final ResourceLocation LEVEL1_FRAME = ModUtils.loc("textures/screens/armor_plate_level1_frame.png");
|
||||
private static final ResourceLocation LEVEL2_FRAME = ModUtils.loc("textures/screens/armor_plate_level2_frame.png");
|
||||
private static final ResourceLocation LEVEL3_FRAME = ModUtils.loc("textures/screens/armor_plate_level3_frame.png");
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onRenderGui(RenderGuiEvent.Pre event) {
|
||||
if (!DisplayConfig.ARMOR_PLATE_HUD.get()) return;
|
||||
|
||||
var gui = event.getGuiGraphics();
|
||||
int h = gui.guiHeight();
|
||||
|
||||
Player player = Minecraft.getInstance().player;
|
||||
if (player == null) return;
|
||||
if (player.isSpectator()) return;
|
||||
|
||||
ItemStack stack = player.getItemBySlot(EquipmentSlot.CHEST);
|
||||
if (stack == ItemStack.EMPTY) return;
|
||||
var tag = NBTTool.getTag(stack);
|
||||
if (!tag.contains("ArmorPlate")) return;
|
||||
|
||||
double amount = 2 * tag.getDouble("ArmorPlate");
|
||||
|
||||
int armorLevel = 1;
|
||||
if (stack.is(ModTags.Items.MILITARY_ARMOR)) {
|
||||
armorLevel = 2;
|
||||
} else if (stack.is(ModTags.Items.MILITARY_ARMOR_HEAVY)) {
|
||||
armorLevel = 3;
|
||||
}
|
||||
|
||||
ResourceLocation texture = switch (armorLevel) {
|
||||
case 2 -> LEVEL2;
|
||||
case 3 -> LEVEL3;
|
||||
default -> LEVEL1;
|
||||
};
|
||||
ResourceLocation frame = switch (armorLevel) {
|
||||
case 2 -> LEVEL2_FRAME;
|
||||
case 3 -> LEVEL3_FRAME;
|
||||
default -> LEVEL1_FRAME;
|
||||
};
|
||||
|
||||
int length = armorLevel * 30;
|
||||
|
||||
gui.pose().pushPose();
|
||||
// 渲染图标
|
||||
gui.blit(ICON, 10, h - 13, 0, 0, 8, 8, 8, 8);
|
||||
|
||||
// 渲染框架
|
||||
gui.blit(frame, 20, h - 12, 0, 0, length, 6, length, 6);
|
||||
|
||||
// 渲染盔甲值
|
||||
gui.blit(texture, 20, h - 12, 0, 0, (int) amount, 6, length, 6);
|
||||
|
||||
gui.pose().popPose();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,186 @@
|
|||
package com.atsuishio.superbwarfare.client.overlay;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.client.RenderHelper;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.AnnihilatorEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.Mk42Entity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.Mle1934Entity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.CannonEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
||||
import com.atsuishio.superbwarfare.event.ClientEventHandler;
|
||||
import com.atsuishio.superbwarfare.tools.FormatTool;
|
||||
import com.atsuishio.superbwarfare.tools.InventoryTool;
|
||||
import com.atsuishio.superbwarfare.tools.TraceTool;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.CameraType;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
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.level.ClipContext;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
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.RenderGuiEvent;
|
||||
import org.joml.Math;
|
||||
|
||||
import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit;
|
||||
import static com.atsuishio.superbwarfare.client.overlay.VehicleHudOverlay.renderKillIndicator;
|
||||
import static com.atsuishio.superbwarfare.client.overlay.VehicleHudOverlay.renderKillIndicator3P;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class CannonHudOverlay {
|
||||
|
||||
@SubscribeEvent
|
||||
public static void eventHandler(RenderGuiEvent.Pre event) {
|
||||
int w = event.getGuiGraphics().guiWidth();
|
||||
int h = event.getGuiGraphics().guiHeight();
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
Player player = mc.player;
|
||||
GuiGraphics guiGraphics = event.getGuiGraphics();
|
||||
PoseStack poseStack = guiGraphics.pose();
|
||||
Camera camera = mc.gameRenderer.getMainCamera();
|
||||
Vec3 cameraPos = camera.getPosition();
|
||||
|
||||
if (!shouldRenderCrossHair(player)) return;
|
||||
|
||||
Entity vehicle = player.getVehicle();
|
||||
if (vehicle instanceof CannonEntity cannonEntity && cannonEntity instanceof VehicleEntity cannon) {
|
||||
poseStack.pushPose();
|
||||
RenderSystem.disableDepthTest();
|
||||
RenderSystem.depthMask(false);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||
|
||||
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/compass_white.png"), (float) w / 2 - 128, (float) 10, 128 + ((float) 64 / 45 * (Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), cannon.yRotO, cannon.getYRot()))), 0, 256, 16, 512, 16);
|
||||
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/roll_ind_white.png"), w / 2F - 4, 27, 0, 0.0F, 8, 8, 8, 8);
|
||||
|
||||
String angle = FormatTool.DECIMAL_FORMAT_1ZZ.format(Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), cannon.yRotO, cannon.getYRot()));
|
||||
int width = Minecraft.getInstance().font.width(angle);
|
||||
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.literal(angle), w / 2 - width / 2, 40, -1, false);
|
||||
|
||||
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/cannon_pitch.png"), w / 2F + 166, h / 2F - 64, 0, 0.0F, 8, 128, 8, 128);
|
||||
|
||||
String pitch = FormatTool.DECIMAL_FORMAT_1ZZ.format(-Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), cannon.xRotO, cannon.getXRot()));
|
||||
int widthP = Minecraft.getInstance().font.width(pitch);
|
||||
|
||||
poseStack.pushPose();
|
||||
|
||||
event.getGuiGraphics().pose().translate(0, Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), cannon.xRotO, cannon.getXRot()) * 0.7, 0);
|
||||
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/cannon_pitch_ind.png"), w / 2F + 158, h / 2F - 4, 0, 0.0F, 8, 8, 8, 8);
|
||||
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.literal(pitch), w / 2 + 157 - widthP, h / 2 - 4, -1, false);
|
||||
poseStack.popPose();
|
||||
|
||||
if (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON || ClientEventHandler.zoomVehicle) {
|
||||
float fovAdjust = (float) 70 / Minecraft.getInstance().options.fov().get();
|
||||
|
||||
float f = (float) Math.min(w, h);
|
||||
float f1 = Math.min((float) w / f, (float) h / f) * fovAdjust;
|
||||
int i = Mth.floor(f * f1);
|
||||
int j = Mth.floor(f * f1);
|
||||
int k = (w - i) / 2;
|
||||
int l = (h - j) / 2;
|
||||
if (ClientEventHandler.zoomVehicle) {
|
||||
Entity lookingEntity = TraceTool.findLookingEntity(player, 512);
|
||||
boolean lookAtEntity = false;
|
||||
|
||||
BlockHitResult result = player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(player.getViewVector(1).scale(512)),
|
||||
ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player));
|
||||
Vec3 hitPos = result.getLocation();
|
||||
|
||||
double blockRange = player.getEyePosition(1).distanceTo(hitPos);
|
||||
|
||||
double entityRange = 0;
|
||||
if (lookingEntity instanceof LivingEntity living) {
|
||||
lookAtEntity = true;
|
||||
entityRange = player.distanceTo(living);
|
||||
}
|
||||
if (lookAtEntity) {
|
||||
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.drone.range")
|
||||
.append(Component.literal(FormatTool.format1D(entityRange, "m ") + lookingEntity.getDisplayName())),
|
||||
w / 2 + 14, h / 2 - 20, -1, false);
|
||||
} else {
|
||||
if (blockRange > 511) {
|
||||
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.drone.range")
|
||||
.append(Component.literal("---m")), w / 2 + 14, h / 2 - 20, -1, false);
|
||||
} else {
|
||||
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.drone.range")
|
||||
.append(Component.literal(FormatTool.format1D(blockRange, "m"))),
|
||||
w / 2 + 14, h / 2 - 20, -1, false);
|
||||
}
|
||||
}
|
||||
if (cannon instanceof AnnihilatorEntity) {
|
||||
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/laser_cannon_crosshair.png"), k, l, 0, 0.0F, i, j, i, j);
|
||||
} else {
|
||||
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/cannon_crosshair.png"), k, l, 0, 0.0F, i, j, i, j);
|
||||
}
|
||||
float diffY = -Mth.wrapDegrees(Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), player.yHeadRotO, player.getYHeadRot()) - Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), cannon.yRotO, cannon.getYRot()));
|
||||
|
||||
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/indicator.png"), w / 2F - 4.3f + 0.45f * diffY, h / 2F - 10, 0, 0.0F, 8, 8, 8, 8);
|
||||
} else {
|
||||
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/cannon_crosshair_notzoom.png"), k, l, 0, 0.0F, i, j, i, j);
|
||||
}
|
||||
renderKillIndicator(guiGraphics, w, h);
|
||||
} else if (Minecraft.getInstance().options.getCameraType() == CameraType.THIRD_PERSON_BACK && !ClientEventHandler.zoomVehicle) {
|
||||
Vec3 p = RenderHelper.worldToScreen(new Vec3(Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), player.xo, player.getX()), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), player.yo, player.getY()),
|
||||
Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), player.zo, player.getZ())).add(cannon.getViewVector(event.getPartialTick().getGameTimeDeltaTicks()).scale(128)), cameraPos);
|
||||
|
||||
// 第三人称准星
|
||||
if (p != null) {
|
||||
poseStack.pushPose();
|
||||
float x = (float) p.x;
|
||||
float y = (float) p.y;
|
||||
|
||||
poseStack.pushPose();
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/drone.png"), x - 12, y - 12, 0, 0, 24, 24, 24, 24);
|
||||
renderKillIndicator3P(guiGraphics, x - 7.5f + (float) (2 * (Math.random() - 0.5f)), y - 7.5f + (float) (2 * (Math.random() - 0.5f)));
|
||||
|
||||
poseStack.pushPose();
|
||||
|
||||
poseStack.translate(x, y, 0);
|
||||
poseStack.scale(0.75f, 0.75f, 1);
|
||||
|
||||
if (player.getVehicle() instanceof Mk42Entity || player.getVehicle() instanceof Mle1934Entity) {
|
||||
if (cannonEntity.getWeaponIndex(0) == 0) {
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("AP SHELL " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : cannonEntity.getAmmoCount(player))), 30, -9, -1, false);
|
||||
} else {
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("HE SHELL " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : cannonEntity.getAmmoCount(player))), 30, -9, -1, false);
|
||||
}
|
||||
}
|
||||
|
||||
// 歼灭者
|
||||
if (player.getVehicle() instanceof AnnihilatorEntity annihilatorEntity) {
|
||||
guiGraphics.drawString(mc.font, Component.literal("LASER " + (FormatTool.format0D((double) (100 * annihilatorEntity.getEnergy()) / annihilatorEntity.getMaxEnergy()) + "%")), 30, -9, -1, false);
|
||||
}
|
||||
|
||||
double heal = 1 - cannon.getHealth() / cannon.getMaxHealth();
|
||||
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("HP " +
|
||||
FormatTool.format0D(100 * cannon.getHealth() / cannon.getMaxHealth())), 30, 1, Mth.hsvToRgb(0F, (float) heal, 1.0F), false);
|
||||
|
||||
poseStack.popPose();
|
||||
poseStack.popPose();
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean shouldRenderCrossHair(Player player) {
|
||||
if (player == null) return false;
|
||||
return !player.isSpectator()
|
||||
&& (player.getVehicle() != null && (player.getVehicle() instanceof CannonEntity));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
package com.atsuishio.superbwarfare.client.overlay;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.client.RenderHelper;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.DroneEntity;
|
||||
import com.atsuishio.superbwarfare.event.ClientEventHandler;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.tools.EntityFindUtil;
|
||||
import com.atsuishio.superbwarfare.tools.FormatTool;
|
||||
import com.atsuishio.superbwarfare.tools.NBTTool;
|
||||
import com.atsuishio.superbwarfare.tools.SeekTool;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.ClipContext;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
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.RenderGuiEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit;
|
||||
import static com.atsuishio.superbwarfare.entity.vehicle.DroneEntity.AMMO;
|
||||
import static com.atsuishio.superbwarfare.entity.vehicle.DroneEntity.KAMIKAZE_MODE;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class DroneUIOverlay {
|
||||
|
||||
public static int MAX_DISTANCE = 256;
|
||||
private static final ResourceLocation FRAME = ModUtils.loc("textures/screens/frame/frame.png");
|
||||
|
||||
@SubscribeEvent
|
||||
public static void eventHandler(RenderGuiEvent.Pre event) {
|
||||
int w = event.getGuiGraphics().guiWidth();
|
||||
int h = event.getGuiGraphics().guiHeight();
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
Player player = mc.player;
|
||||
|
||||
if (player == null) return;
|
||||
|
||||
GuiGraphics guiGraphics = event.getGuiGraphics();
|
||||
PoseStack poseStack = guiGraphics.pose();
|
||||
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
|
||||
poseStack.pushPose();
|
||||
|
||||
RenderSystem.disableDepthTest();
|
||||
RenderSystem.depthMask(false);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||
|
||||
var tag = NBTTool.getTag(stack);
|
||||
if (stack.is(ModItems.MONITOR.get()) && tag.getBoolean("Using") && tag.getBoolean("Linked")) {
|
||||
guiGraphics.blit(ModUtils.loc("textures/screens/drone.png"), w / 2 - 16, h / 2 - 16, 0, 0, 32, 32, 32, 32);
|
||||
guiGraphics.blit(ModUtils.loc("textures/screens/drone_fov.png"), w / 2 + 100, h / 2 - 64, 0, 0, 64, 129, 64, 129);
|
||||
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/drone_fov_move.png"), (float) w / 2 + 100, (float) (h / 2 - 64 - ((ClientEventHandler.droneFovLerp - 1) * 23.8)), 0, 0, 64, 129, 64, 129);
|
||||
guiGraphics.drawString(mc.font, Component.literal(FormatTool.format1D(ClientEventHandler.droneFovLerp, "x")),
|
||||
w / 2 + 144, h / 2 + 56 - (int) ((ClientEventHandler.droneFovLerp - 1) * 23.8), -1, false);
|
||||
|
||||
DroneEntity entity = EntityFindUtil.findDrone(player.level(), tag.getString("LinkedDrone"));
|
||||
|
||||
if (entity != null) {
|
||||
boolean lookAtEntity = false;
|
||||
double distance = player.distanceTo(entity);
|
||||
|
||||
BlockHitResult result = entity.level().clip(new ClipContext(entity.getEyePosition(), entity.getEyePosition().add(player.getViewVector(1).scale(512)),
|
||||
ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, entity));
|
||||
Vec3 hitPos = result.getLocation();
|
||||
|
||||
double blockRange = player.getEyePosition(1).distanceTo(hitPos);
|
||||
|
||||
double entityRange = 0;
|
||||
|
||||
Entity lookingEntity = SeekTool.seekLivingEntity(entity, entity.level(), 512, 2);
|
||||
if (lookingEntity != null) {
|
||||
lookAtEntity = true;
|
||||
entityRange = entity.distanceTo(lookingEntity);
|
||||
}
|
||||
|
||||
int color = -1;
|
||||
|
||||
// 超出距离警告
|
||||
if (distance > MAX_DISTANCE - 48) {
|
||||
guiGraphics.drawString(mc.font, Component.translatable("tips.superbwarfare.drone.warning"),
|
||||
w / 2 - 18, h / 2 - 47, -65536, false);
|
||||
color = -65536;
|
||||
}
|
||||
|
||||
// 距离
|
||||
guiGraphics.drawString(mc.font, Component.translatable("tips.superbwarfare.drone.distance")
|
||||
.append(Component.literal(FormatTool.format1D(distance, "m"))),
|
||||
w / 2 + 10, h / 2 + 33, color, false);
|
||||
|
||||
// 血量
|
||||
guiGraphics.drawString(mc.font, Component.translatable("tips.superbwarfare.drone.health")
|
||||
.append(Component.literal(FormatTool.format1D(entity.getHealth()) + " / " + FormatTool.format1D(entity.getMaxHealth()))),
|
||||
w / 2 - 77, h / 2 + 33, -1, false);
|
||||
if (entity.getEntityData().get(KAMIKAZE_MODE) == 0) {
|
||||
// 弹药
|
||||
guiGraphics.drawString(mc.font, Component.translatable("tips.superbwarfare.drone.ammo")
|
||||
.append(Component.literal(FormatTool.format1D(entity.getEntityData().get(AMMO), " / 6"))),
|
||||
w / 2 + 12, h / 2 - 37, -1, false);
|
||||
} else {
|
||||
// 神风
|
||||
guiGraphics.drawString(mc.font, Component.translatable("tips.superbwarfare.drone.kamikaze"),
|
||||
w / 2 + 12, h / 2 - 37, -65536, false);
|
||||
}
|
||||
|
||||
if (lookAtEntity) {
|
||||
// 实体距离
|
||||
guiGraphics.drawString(mc.font, Component.translatable("tips.superbwarfare.drone.range")
|
||||
.append(Component.literal(FormatTool.format1D(entityRange, "m ") + lookingEntity.getDisplayName().getString())),
|
||||
w / 2 + 12, h / 2 - 28, color, false);
|
||||
} else {
|
||||
// 方块距离
|
||||
if (blockRange > 500) {
|
||||
guiGraphics.drawString(mc.font, Component.translatable("tips.superbwarfare.drone.range")
|
||||
.append(Component.literal("---m")), w / 2 + 12, h / 2 - 28, color, false);
|
||||
} else {
|
||||
guiGraphics.drawString(mc.font, Component.translatable("tips.superbwarfare.drone.range")
|
||||
.append(Component.literal(FormatTool.format1D(blockRange, "m"))),
|
||||
w / 2 + 12, h / 2 - 28, color, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
List<Entity> entities = SeekTool.seekLivingEntities(entity, entity.level(), 256, 30);
|
||||
float fovAdjust2 = (float) (mc.options.fov().get() / 30) - 1;
|
||||
double zoom = 0.975 * ClientEventHandler.droneFovLerp + 0.06 * fovAdjust2;
|
||||
|
||||
for (var e : entities) {
|
||||
Vec3 droneVec = new Vec3(Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), entity.xo, entity.getX()), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), entity.yo + entity.getEyeHeight(), entity.getEyeY()), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), entity.zo, entity.getZ()));
|
||||
Vec3 pos = new Vec3(Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), e.xo, e.getX()), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), e.yo + e.getEyeHeight(), e.getEyeY()), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), e.zo, e.getZ()));
|
||||
|
||||
Vec3 lookAngle = entity.getLookAngle().normalize().scale(pos.distanceTo(droneVec) * (1 - 1.0 / zoom));
|
||||
|
||||
var cPos = droneVec.add(lookAngle);
|
||||
Vec3 point = RenderHelper.worldToScreen(pos, cPos);
|
||||
if (point != null) {
|
||||
poseStack.pushPose();
|
||||
float x = (float) point.x;
|
||||
float y = (float) point.y;
|
||||
|
||||
RenderHelper.preciseBlit(guiGraphics, FRAME, x - 12, y - 12, 0, 0, 24, 24, 24, 24, 1f);
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RenderSystem.depthMask(true);
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package com.atsuishio.superbwarfare.client.overlay;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.CannonEntity;
|
||||
import com.atsuishio.superbwarfare.event.ClientEventHandler;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraft.client.CameraType;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.client.event.RenderGuiEvent;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class GrenadeLauncherOverlay {
|
||||
|
||||
@SubscribeEvent
|
||||
public static void eventHandler(RenderGuiEvent.Pre event) {
|
||||
int w = event.getGuiGraphics().guiWidth();
|
||||
int h = event.getGuiGraphics().guiHeight();
|
||||
Player player = Minecraft.getInstance().player;
|
||||
if (player == null) return;
|
||||
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap == null || cap.edit) return;
|
||||
|
||||
if (player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.banHand(player))
|
||||
return;
|
||||
if (!shouldRenderCrossHair(player)) return;
|
||||
|
||||
GuiGraphics guiGraphics = event.getGuiGraphics();
|
||||
|
||||
guiGraphics.pose().pushPose();
|
||||
|
||||
RenderSystem.disableDepthTest();
|
||||
RenderSystem.depthMask(false);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||
|
||||
guiGraphics.blit(ModUtils.loc("textures/screens/rex.png"), w / 2 - 16, h / 2 - 16, 0, 0, 32, 32, 32, 32);
|
||||
|
||||
RenderSystem.depthMask(true);
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||
|
||||
guiGraphics.pose().popPose();
|
||||
}
|
||||
|
||||
private static boolean shouldRenderCrossHair(Player player) {
|
||||
if (player == null) return false;
|
||||
return !player.isSpectator()
|
||||
&& (player.getMainHandItem().getItem() == ModItems.M_79.get() || player.getMainHandItem().getItem() == ModItems.SECONDARY_CATACLYSM.get())
|
||||
&& (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON || (player.isPassenger() && player.getVehicle() instanceof CannonEntity))
|
||||
&& !ClientEventHandler.zoom;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
package com.atsuishio.superbwarfare.client.overlay;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||
import com.atsuishio.superbwarfare.client.RenderHelper;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.event.ClientEventHandler;
|
||||
import com.atsuishio.superbwarfare.item.gun.GunItem;
|
||||
import com.atsuishio.superbwarfare.tools.SeekTool;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
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.EventPriority;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.client.event.RenderGuiEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class HandsomeFrameOverlay {
|
||||
|
||||
private static final ResourceLocation FRAME = ModUtils.loc("textures/screens/frame/frame.png");
|
||||
private static final ResourceLocation FRAME_WEAK = ModUtils.loc("textures/screens/frame/frame_weak.png");
|
||||
private static final ResourceLocation FRAME_TARGET = ModUtils.loc("textures/screens/frame/frame_target.png");
|
||||
private static final ResourceLocation FRAME_LOCK = ModUtils.loc("textures/screens/frame/frame_lock.png");
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||
public static void eventHandler(RenderGuiEvent.Pre event) {
|
||||
Player player = Minecraft.getInstance().player;
|
||||
PoseStack poseStack = event.getGuiGraphics().pose();
|
||||
|
||||
if (player != null) {
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap == null || cap.edit) return;
|
||||
if (player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.banHand(player))
|
||||
return;
|
||||
|
||||
if (stack.getItem() instanceof GunItem && Minecraft.getInstance().options.getCameraType().isFirstPerson()) {
|
||||
|
||||
// TODO intelligent chip perk
|
||||
// int level = PerkHelper.getItemPerkLevel(ModPerks.INTELLIGENT_CHIP.get(), stack);
|
||||
int level = 0;
|
||||
if (level == 0) return;
|
||||
|
||||
RenderSystem.disableDepthTest();
|
||||
RenderSystem.depthMask(false);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||
|
||||
List<Entity> allEntities = SeekTool.seekLivingEntitiesThroughWall(player, player.level(), 32 + 8 * (level - 1), 30);
|
||||
List<Entity> visibleEntities = SeekTool.seekLivingEntities(player, player.level(), 32 + 8 * (level - 1), 30);
|
||||
|
||||
Entity naerestEntity = SeekTool.seekLivingEntity(player, player.level(), 32 + 8 * (level - 1), 30);
|
||||
Entity targetEntity = ClientEventHandler.entity;
|
||||
|
||||
|
||||
float fovAdjust2 = (float) (Minecraft.getInstance().options.fov().get() / 30) - 1;
|
||||
|
||||
double zoom = 1;
|
||||
|
||||
if (ClientEventHandler.zoom) {
|
||||
zoom = Minecraft.getInstance().options.fov().get() / ClientEventHandler.fov + 0.05 * fovAdjust2;
|
||||
}
|
||||
|
||||
for (var e : allEntities) {
|
||||
Vec3 playerVec = new Vec3(Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), player.xo, player.getX()), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), player.yo + player.getEyeHeight(), player.getEyeY()), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), player.zo, player.getZ()));
|
||||
Vec3 pos = new Vec3(Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), e.xo, e.getX()), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), e.yo + e.getEyeHeight(), e.getEyeY()), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), e.zo, e.getZ()));
|
||||
Vec3 lookAngle = player.getLookAngle().normalize().scale(pos.distanceTo(playerVec) * (1 - 1.0 / zoom));
|
||||
|
||||
var cPos = playerVec.add(lookAngle);
|
||||
Vec3 point = RenderHelper.worldToScreen(pos, cPos);
|
||||
if (point == null) return;
|
||||
|
||||
boolean lockOn = e == targetEntity;
|
||||
boolean isNearestEntity = e == naerestEntity;
|
||||
|
||||
poseStack.pushPose();
|
||||
float x = (float) point.x;
|
||||
float y = (float) point.y;
|
||||
|
||||
var canBeSeen = visibleEntities.contains(e);
|
||||
|
||||
ResourceLocation icon;
|
||||
if (lockOn) {
|
||||
icon = FRAME_LOCK;
|
||||
} else if (canBeSeen) {
|
||||
if (isNearestEntity) {
|
||||
icon = FRAME_TARGET;
|
||||
} else {
|
||||
icon = FRAME;
|
||||
}
|
||||
} else {
|
||||
icon = FRAME_WEAK;
|
||||
}
|
||||
|
||||
RenderHelper.preciseBlit(event.getGuiGraphics(), icon, x - 12, y - 12, 0, 0, 24, 24, 24, 24, 1f);
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,239 @@
|
|||
package com.atsuishio.superbwarfare.client.overlay;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||
import com.atsuishio.superbwarfare.client.RenderHelper;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.Ah6Entity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.HelicopterEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.WeaponVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.event.ClientEventHandler;
|
||||
import com.atsuishio.superbwarfare.tools.FormatTool;
|
||||
import com.atsuishio.superbwarfare.tools.InventoryTool;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Axis;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.CameraType;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.ClipContext;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.EventPriority;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.client.event.RenderGuiEvent;
|
||||
import org.joml.Math;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector4f;
|
||||
|
||||
import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit;
|
||||
import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity.HEAT;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class HelicopterHudOverlay {
|
||||
|
||||
private static float scopeScale = 1;
|
||||
private static float lerpVy = 1;
|
||||
private static float lerpPower = 1;
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||
public static void eventHandler(RenderGuiEvent.Pre event) {
|
||||
int w = event.getGuiGraphics().guiWidth();
|
||||
int h = event.getGuiGraphics().guiHeight();
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
Player player = mc.player;
|
||||
Camera camera = mc.gameRenderer.getMainCamera();
|
||||
Vec3 cameraPos = camera.getPosition();
|
||||
GuiGraphics guiGraphics = event.getGuiGraphics();
|
||||
PoseStack poseStack = guiGraphics.pose();
|
||||
|
||||
if (player == null) return;
|
||||
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap == null || cap.edit) return;
|
||||
|
||||
if (player.getVehicle() instanceof HelicopterEntity iHelicopterEntity && player.getVehicle() instanceof MobileVehicleEntity mobileVehicle && iHelicopterEntity.isDriver(player) && player.getVehicle() instanceof WeaponVehicleEntity weaponVehicle) {
|
||||
poseStack.pushPose();
|
||||
|
||||
poseStack.translate(-6 * ClientEventHandler.turnRot[1], -6 * ClientEventHandler.turnRot[0], 0);
|
||||
RenderSystem.disableDepthTest();
|
||||
RenderSystem.depthMask(false);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||
|
||||
scopeScale = Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), scopeScale, 1F);
|
||||
float f = (float) Math.min(w, h);
|
||||
float f1 = Math.min((float) w / f, (float) h / f) * scopeScale;
|
||||
float i = Mth.floor(f * f1);
|
||||
float j = Mth.floor(f * f1);
|
||||
float k = ((w - i) / 2);
|
||||
float l = ((h - j) / 2);
|
||||
|
||||
if (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON) {
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/helicopter/heli_base.png"), k, l, 0, 0.0F, i, j, i, j);
|
||||
renderDriverAngle(guiGraphics, player, mobileVehicle, k, l, i, j, event.getPartialTick().getGameTimeDeltaTicks());
|
||||
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/compass.png"), (float) w / 2 - 128, (float) 6, 128 + ((float) 64 / 45 * mobileVehicle.getYRot()), 0, 256, 16, 512, 16);
|
||||
|
||||
poseStack.pushPose();
|
||||
poseStack.rotateAround(Axis.ZP.rotationDegrees(-iHelicopterEntity.getRotZ(event.getPartialTick().getGameTimeDeltaTicks())), w / 2f, h / 2f, 0);
|
||||
float pitch = iHelicopterEntity.getRotX(event.getPartialTick().getGameTimeDeltaTicks());
|
||||
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/helicopter/heli_line.png"), (float) w / 2 - 128, (float) h / 2 - 512 - 5.475f * pitch, 0, 0, 256, 1024, 256, 1024);
|
||||
poseStack.popPose();
|
||||
poseStack.pushPose();
|
||||
poseStack.rotateAround(Axis.ZP.rotationDegrees(iHelicopterEntity.getRotZ(event.getPartialTick().getGameTimeDeltaTicks())), w / 2f, h / 2f - 56, 0);
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/helicopter/roll_ind.png"), (float) w / 2 - 8, (float) h / 2 - 88, 0, 0, 16, 16, 16, 16);
|
||||
poseStack.popPose();
|
||||
|
||||
guiGraphics.blit(ModUtils.loc("textures/screens/helicopter/heli_power_ruler.png"), w / 2 + 100, h / 2 - 64, 0, 0, 64, 128, 64, 128);
|
||||
|
||||
double height = mobileVehicle.position().distanceTo((Vec3.atLowerCornerOf(mobileVehicle.level().clip(new ClipContext(mobileVehicle.position(), mobileVehicle.position().add(new Vec3(0, -1, 0).scale(100)),
|
||||
ClipContext.Block.OUTLINE, ClipContext.Fluid.ANY, mobileVehicle)).getBlockPos())));
|
||||
double blockInWay = mobileVehicle.position().distanceTo((Vec3.atLowerCornerOf(mobileVehicle.level().clip(new ClipContext(mobileVehicle.position(), mobileVehicle.position().add(new Vec3(mobileVehicle.getDeltaMovement().x, mobileVehicle.getDeltaMovement().y + 0.06, mobileVehicle.getDeltaMovement().z).normalize().scale(100)),
|
||||
ClipContext.Block.OUTLINE, ClipContext.Fluid.ANY, mobileVehicle)).getBlockPos())));
|
||||
|
||||
float power = iHelicopterEntity.getPower();
|
||||
lerpPower = Mth.lerp(0.001f * event.getPartialTick().getGameTimeDeltaTicks(), lerpPower, power);
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/helicopter/heli_power.png"), (float) w / 2 + 130f, ((float) h / 2 - 64 + 124 - power * 980), 0, 0, 4, power * 980, 4, power * 980);
|
||||
lerpVy = (float) Mth.lerp(0.021f * event.getPartialTick().getGameTimeDeltaTicks(), lerpVy, mobileVehicle.getDeltaMovement().y());
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/helicopter/heli_vy_move.png"), (float) w / 2 + 138, ((float) h / 2 - 3 - Math.max(lerpVy * 20, -24) * 2.5f), 0, 0, 8, 8, 8, 8);
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(FormatTool.format0D(lerpVy * 20, "m/s")),
|
||||
w / 2 + 146, (int) (h / 2 - 3 - Math.max(lerpVy * 20, -24) * 2.5), (lerpVy * 20 < -24 || ((lerpVy * 20 < -10 || (lerpVy * 20 < -1 && length(mobileVehicle.getDeltaMovement().x, mobileVehicle.getDeltaMovement().y, mobileVehicle.getDeltaMovement().z) * 72 > 100)) && height < 36) || (length(mobileVehicle.getDeltaMovement().x, mobileVehicle.getDeltaMovement().y, mobileVehicle.getDeltaMovement().z) * 72 > 40 && blockInWay < 72) ? -65536 : 0x66FF00), false);
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(FormatTool.format0D(mobileVehicle.getY())),
|
||||
w / 2 + 104, h / 2, 0x66FF00, false);
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/helicopter/speed_frame.png"), (float) w / 2 - 144, (float) h / 2 - 6, 0, 0, 50, 18, 50, 18);
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(FormatTool.format0D(length(mobileVehicle.getDeltaMovement().x, mobileVehicle.getDeltaMovement().y, mobileVehicle.getDeltaMovement().z) * 72, "km/h")),
|
||||
w / 2 - 140, h / 2, 0x66FF00, false);
|
||||
|
||||
if (mobileVehicle instanceof Ah6Entity ah6Entity) {
|
||||
if (weaponVehicle.getWeaponIndex(0) == 0) {
|
||||
double heat = 1 - ah6Entity.getEntityData().get(HEAT) / 100.0F;
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("20MM CANNON " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : iHelicopterEntity.getAmmoCount(player))), w / 2 - 160, h / 2 - 60, Mth.hsvToRgb((float) heat / 3.745318352059925F, 1.0F, 1.0F), false);
|
||||
} else {
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("70MM ROCKET " + iHelicopterEntity.getAmmoCount(player)), w / 2 - 160, h / 2 - 60, 0x66FF00, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("FLARE " + iHelicopterEntity.getDecoy()), w / 2 - 160, h / 2 - 50, 0x66FF00, false);
|
||||
|
||||
if (lerpVy * 20 < -24) {
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("SINK RATE,PULL UP!"),
|
||||
w / 2 - 53, h / 2 + 24, -65536, false);
|
||||
} else if (((lerpVy * 20 < -10 || (lerpVy * 20 < -1 && length(mobileVehicle.getDeltaMovement().x, mobileVehicle.getDeltaMovement().y, mobileVehicle.getDeltaMovement().z) * 72 > 100)) && height < 36)
|
||||
|| (length(mobileVehicle.getDeltaMovement().x, mobileVehicle.getDeltaMovement().y, mobileVehicle.getDeltaMovement().z) * 72 > 40 && blockInWay < 72)) {
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("TERRAIN TERRAIN"),
|
||||
w / 2 - 42, h / 2 + 24, -65536, false);
|
||||
}
|
||||
|
||||
if (mobileVehicle.getEnergy() < 0.02 * mobileVehicle.getMaxEnergy()) {
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("NO POWER!"),
|
||||
w / 2 - 144, h / 2 + 14, -65536, false);
|
||||
} else if (mobileVehicle.getEnergy() < 0.2 * mobileVehicle.getMaxEnergy()) {
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("LOW POWER"),
|
||||
w / 2 - 144, h / 2 + 14, 0xFF6B00, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Matrix4f transform = getVehicleTransform(mobileVehicle, event.getPartialTick().getGameTimeDeltaTicks());
|
||||
float x0 = 0f;
|
||||
float y0 = 0.65f;
|
||||
float z0 = 0.8f;
|
||||
|
||||
Vector4f worldPosition = transformPosition(transform, x0, y0, z0);
|
||||
|
||||
float fovAdjust2 = (float) (Minecraft.getInstance().options.fov().get() / 30) - 1;
|
||||
double zoom = 0.96 * 3 + 0.06 * fovAdjust2;
|
||||
|
||||
Vec3 pos = new Vec3(worldPosition.x, worldPosition.y, worldPosition.z).add(mobileVehicle.getViewVector(event.getPartialTick().getGameTimeDeltaTicks()).scale(192));
|
||||
Vec3 lookAngle = player.getLookAngle().normalize().scale(pos.distanceTo(cameraPos) * (1 - 1.0 / zoom));
|
||||
|
||||
var cPos = cameraPos.add(lookAngle);
|
||||
|
||||
Vec3 p = RenderHelper.worldToScreen(new Vec3(worldPosition.x, worldPosition.y, worldPosition.z).add(mobileVehicle.getViewVector(event.getPartialTick().getGameTimeDeltaTicks()).scale(192)), ClientEventHandler.zoomVehicle ? cPos : cameraPos);
|
||||
|
||||
if (p != null) {
|
||||
poseStack.pushPose();
|
||||
float x = (float) p.x;
|
||||
float y = (float) p.y;
|
||||
|
||||
|
||||
if (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON) {
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/helicopter/crosshair_ind.png"), x - 8, y - 8, 0, 0, 16, 16, 16, 16);
|
||||
renderKillIndicator(guiGraphics, x - 7.5f + (float) (2 * (Math.random() - 0.5f)), y - 7.5f + (float) (2 * (Math.random() - 0.5f)));
|
||||
} else if (Minecraft.getInstance().options.getCameraType() == CameraType.THIRD_PERSON_BACK) {
|
||||
poseStack.pushPose();
|
||||
poseStack.rotateAround(Axis.ZP.rotationDegrees(iHelicopterEntity.getRotZ(event.getPartialTick().getGameTimeDeltaTicks())), x, y, 0);
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/drone.png"), x - 8, y - 8, 0, 0, 16, 16, 16, 16);
|
||||
renderKillIndicator(guiGraphics, x - 7.5f + (float) (2 * (Math.random() - 0.5f)), y - 7.5f + (float) (2 * (Math.random() - 0.5f)));
|
||||
|
||||
poseStack.pushPose();
|
||||
|
||||
poseStack.translate(x, y, 0);
|
||||
poseStack.scale(0.75f, 0.75f, 1);
|
||||
|
||||
if (mobileVehicle instanceof Ah6Entity ah6Entity) {
|
||||
if (weaponVehicle.getWeaponIndex(0) == 0) {
|
||||
double heat = ah6Entity.getEntityData().get(HEAT) / 100.0F;
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("20MM CANNON " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : iHelicopterEntity.getAmmoCount(player))), 25, -9, Mth.hsvToRgb(0F, (float) heat, 1.0F), false);
|
||||
} else {
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("70MM ROCKET " + iHelicopterEntity.getAmmoCount(player)), 25, -9, -1, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("FLARE " + iHelicopterEntity.getDecoy()), 25, 1, -1, false);
|
||||
poseStack.popPose();
|
||||
poseStack.popPose();
|
||||
}
|
||||
poseStack.popPose();
|
||||
}
|
||||
|
||||
poseStack.popPose();
|
||||
} else {
|
||||
scopeScale = 0.7f;
|
||||
}
|
||||
}
|
||||
|
||||
private static void renderKillIndicator(GuiGraphics guiGraphics, float posX, float posY) {
|
||||
VehicleHudOverlay.renderKillIndicator3P(guiGraphics, posX, posY);
|
||||
}
|
||||
|
||||
private static void renderDriverAngle(GuiGraphics guiGraphics, Player player, Entity heli, float k, float l, float i, float j, float ticks) {
|
||||
float diffY = Mth.wrapDegrees(Mth.lerp(ticks, player.yHeadRotO, player.getYHeadRot()) - Mth.lerp(ticks, heli.yRotO, heli.getYRot())) * 0.35f;
|
||||
float diffX = Mth.wrapDegrees(Mth.lerp(ticks, player.xRotO, player.getXRot()) - Mth.lerp(ticks, heli.xRotO, heli.getXRot())) * 0.072f;
|
||||
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/helicopter/heli_driver_angle.png"), k + diffY, l + diffX, 0, 0.0F, i, j, i, j);
|
||||
}
|
||||
|
||||
public static Matrix4f getVehicleTransform(VehicleEntity vehicle, float partialTicks) {
|
||||
Matrix4f transform = new Matrix4f();
|
||||
transform.translate((float) Mth.lerp(partialTicks, vehicle.xo, vehicle.getX()), (float) Mth.lerp(partialTicks, vehicle.yo + 1.45, vehicle.getY() + 1.45), (float) Mth.lerp(partialTicks, vehicle.zo, vehicle.getZ()));
|
||||
transform.rotate(Axis.YP.rotationDegrees(-vehicle.getYRot()));
|
||||
transform.rotate(Axis.XP.rotationDegrees(vehicle.getXRot()));
|
||||
transform.rotate(Axis.ZP.rotationDegrees(vehicle.getRoll()));
|
||||
return transform;
|
||||
}
|
||||
|
||||
public static Vector4f transformPosition(Matrix4f transform, float x, float y, float z) {
|
||||
return transform.transform(new Vector4f(x, y, z, 1));
|
||||
}
|
||||
|
||||
public static double length(double x, double y, double z) {
|
||||
return Math.sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
package com.atsuishio.superbwarfare.client.overlay;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||
import com.atsuishio.superbwarfare.client.RenderHelper;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.event.ClientEventHandler;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.tools.EntityFindUtil;
|
||||
import com.atsuishio.superbwarfare.tools.GunsTool;
|
||||
import com.atsuishio.superbwarfare.tools.NBTTool;
|
||||
import com.atsuishio.superbwarfare.tools.SeekTool;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
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.EventPriority;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.client.event.RenderGuiEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class JavelinHudOverlay {
|
||||
|
||||
private static final ResourceLocation FRAME = ModUtils.loc("textures/screens/frame/frame.png");
|
||||
private static final ResourceLocation FRAME_TARGET = ModUtils.loc("textures/screens/frame/frame_target.png");
|
||||
private static final ResourceLocation FRAME_LOCK = ModUtils.loc("textures/screens/frame/frame_lock.png");
|
||||
private static float scopeScale = 1;
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||
public static void eventHandler(RenderGuiEvent.Pre event) {
|
||||
int w = event.getGuiGraphics().guiWidth();
|
||||
int h = event.getGuiGraphics().guiHeight();
|
||||
Player player = Minecraft.getInstance().player;
|
||||
PoseStack poseStack = event.getGuiGraphics().pose();
|
||||
|
||||
if (player != null) {
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap == null || cap.edit) return;
|
||||
|
||||
if (player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.banHand(player))
|
||||
return;
|
||||
var tag = NBTTool.getTag(stack);
|
||||
|
||||
if ((stack.getItem() == ModItems.JAVELIN.get() && !tag.getBoolean("HoloHidden")) && Minecraft.getInstance().options.getCameraType().isFirstPerson() && ClientEventHandler.zoom) {
|
||||
RenderSystem.disableDepthTest();
|
||||
RenderSystem.depthMask(false);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||
float deltaFrame = Minecraft.getInstance().getTimer().getGameTimeDeltaTicks();
|
||||
float moveX = (float) (-32 * ClientEventHandler.turnRot[1] - (player.isSprinting() ? 100 : 67) * ClientEventHandler.movePosX + 3 * ClientEventHandler.cameraRot[2]);
|
||||
float moveY = (float) (-32 * ClientEventHandler.turnRot[0] + 100 * (float) ClientEventHandler.velocityY - (player.isSprinting() ? 100 : 67) * ClientEventHandler.movePosY - 12 * ClientEventHandler.firePos + 3 * ClientEventHandler.cameraRot[1]);
|
||||
scopeScale = (float) Mth.lerp(0.5F * deltaFrame, scopeScale, 1.35F + (0.2f * ClientEventHandler.firePos));
|
||||
float f = (float) Math.min(w, h);
|
||||
float f1 = Math.min((float) w / f, (float) h / f) * scopeScale;
|
||||
float i = Mth.floor(f * f1);
|
||||
float j = Mth.floor(f * f1);
|
||||
float k = ((w - i) / 2) + moveX;
|
||||
float l = ((h - j) / 2) + moveY;
|
||||
float i1 = k + i;
|
||||
float j1 = l + j;
|
||||
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/javelin/javelin_hud.png"), k, l, 0, 0.0F, i, j, i, j);
|
||||
preciseBlit(event.getGuiGraphics(), ModUtils.loc(tag.getBoolean("TopMode") ? "textures/screens/javelin/top.png" : "textures/screens/javelin/dir.png"), k, l, 0, 0.0F, i, j, i, j);
|
||||
preciseBlit(event.getGuiGraphics(), ModUtils.loc(GunsTool.getGunIntTag(stack, "Ammo", 0) > 0 ? "textures/screens/javelin/missile_green.png" : "textures/screens/javelin/missile_red.png"), k, l, 0, 0.0F, i, j, i, j);
|
||||
if (tag.getInt("SeekTime") > 1 && tag.getInt("SeekTime") < 20) {
|
||||
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/javelin/seek.png"), k, l, 0, 0.0F, i, j, i, j);
|
||||
}
|
||||
|
||||
event.getGuiGraphics().fill(RenderType.guiOverlay(), 0, (int) l, (int) k + 3, (int) j1, -90, -16777216);
|
||||
event.getGuiGraphics().fill(RenderType.guiOverlay(), (int) i1, (int) l, w, (int) j1, -90, -16777216);
|
||||
RenderSystem.depthMask(true);
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||
|
||||
float fovAdjust = (float) Minecraft.getInstance().options.fov().get() / 80;
|
||||
|
||||
Entity targetEntity = EntityFindUtil.findEntity(player.level(), tag.getString("TargetEntity"));
|
||||
List<Entity> entities = SeekTool.seekLivingEntities(player, player.level(), 512, 8 * fovAdjust);
|
||||
Entity naerestEntity = SeekTool.seekLivingEntity(player, player.level(), 512, 6);
|
||||
|
||||
float fovAdjust2 = (float) (Minecraft.getInstance().options.fov().get() / 30) - 1;
|
||||
|
||||
double zoom = Minecraft.getInstance().options.fov().get() / ClientEventHandler.fov + 0.5 * fovAdjust2;
|
||||
|
||||
Vec3 playerVec = new Vec3(Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), player.xo, player.getX()), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), player.yo + player.getEyeHeight(), player.getEyeY()), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), player.zo, player.getZ()));
|
||||
|
||||
if (tag.getInt("GuideType") == 0) {
|
||||
for (var e : entities) {
|
||||
Vec3 pos = new Vec3(Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), e.xo, e.getX()), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), e.yo + e.getEyeHeight(), e.getEyeY()), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), e.zo, e.getZ()));
|
||||
Vec3 lookAngle = player.getLookAngle().normalize().scale(pos.distanceTo(playerVec) * (1 - 1.0 / zoom));
|
||||
|
||||
var cPos = playerVec.add(lookAngle);
|
||||
Vec3 point = RenderHelper.worldToScreen(pos, cPos);
|
||||
if (point == null) return;
|
||||
|
||||
boolean lockOn = tag.getInt("SeekTime") > 20 && e == targetEntity;
|
||||
boolean nearest = e == naerestEntity;
|
||||
|
||||
poseStack.pushPose();
|
||||
float x = (float) point.x;
|
||||
float y = (float) point.y;
|
||||
|
||||
RenderHelper.preciseBlit(event.getGuiGraphics(), lockOn ? FRAME_LOCK : nearest ? FRAME_TARGET : FRAME, x - 12, y - 12, 0, 0, 24, 24, 24, 24, 1f);
|
||||
poseStack.popPose();
|
||||
}
|
||||
} else {
|
||||
Vec3 pos = new Vec3(tag.getDouble("TargetPosX"), tag.getDouble("TargetPosY"), tag.getDouble("TargetPosZ"));
|
||||
Vec3 lookAngle = player.getLookAngle().normalize().scale(pos.distanceTo(playerVec) * (1 - 1.0 / zoom));
|
||||
|
||||
boolean lockOn = tag.getInt("SeekTime") > 20;
|
||||
|
||||
var cPos = playerVec.add(lookAngle);
|
||||
Vec3 point = RenderHelper.worldToScreen(pos, cPos);
|
||||
if (point == null) return;
|
||||
|
||||
poseStack.pushPose();
|
||||
float x = (float) point.x;
|
||||
float y = (float) point.y;
|
||||
|
||||
RenderHelper.preciseBlit(event.getGuiGraphics(), lockOn ? FRAME_LOCK : FRAME_TARGET, x - 12, y - 12, 0, 0, 24, 24, 24, 24, 1f);
|
||||
poseStack.popPose();
|
||||
}
|
||||
|
||||
} else {
|
||||
scopeScale = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,322 @@
|
|||
package com.atsuishio.superbwarfare.client.overlay;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.config.client.KillMessageConfig;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
||||
import com.atsuishio.superbwarfare.event.KillMessageHandler;
|
||||
import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.item.gun.GunItem;
|
||||
import com.atsuishio.superbwarfare.tools.DamageTypeTool;
|
||||
import com.atsuishio.superbwarfare.tools.PlayerKillRecord;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.damagesource.DamageTypes;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.client.event.RenderGuiEvent;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import top.theillusivec4.curios.api.CuriosApi;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class KillMessageOverlay {
|
||||
|
||||
private static final ResourceLocation HEADSHOT = ModUtils.loc("textures/screens/damage_types/headshot.png");
|
||||
|
||||
private static final ResourceLocation KNIFE = ModUtils.loc("textures/screens/damage_types/knife.png");
|
||||
private static final ResourceLocation EXPLOSION = ModUtils.loc("textures/screens/damage_types/explosion.png");
|
||||
private static final ResourceLocation CLAYMORE = ModUtils.loc("textures/screens/damage_types/claymore.png");
|
||||
private static final ResourceLocation GENERIC = ModUtils.loc("textures/screens/damage_types/generic.png");
|
||||
private static final ResourceLocation BEAST = ModUtils.loc("textures/screens/damage_types/beast.png");
|
||||
private static final ResourceLocation BLEEDING = ModUtils.loc("textures/screens/damage_types/bleeding.png");
|
||||
private static final ResourceLocation SHOCK = ModUtils.loc("textures/screens/damage_types/shock.png");
|
||||
private static final ResourceLocation BLOOD_CRYSTAL = ModUtils.loc("textures/screens/damage_types/blood_crystal.png");
|
||||
private static final ResourceLocation BURN = ModUtils.loc("textures/screens/damage_types/burn.png");
|
||||
private static final ResourceLocation DRONE = ModUtils.loc("textures/screens/damage_types/drone.png");
|
||||
private static final ResourceLocation LASER = ModUtils.loc("textures/screens/damage_types/laser.png");
|
||||
private static final ResourceLocation VEHICLE = ModUtils.loc("textures/screens/damage_types/vehicle_strike.png");
|
||||
|
||||
private static final ResourceLocation WORLD_PEACE_STAFF = ModUtils.loc("textures/gun_icon/compat/world_peace_staff.png");
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onRenderGui(RenderGuiEvent.Pre event) {
|
||||
if (!KillMessageConfig.SHOW_KILL_MESSAGE.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = Minecraft.getInstance().player;
|
||||
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (KillMessageHandler.QUEUE.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
float totalTop = 5;
|
||||
|
||||
var arr = KillMessageHandler.QUEUE.toArray(new PlayerKillRecord[0]);
|
||||
var record = arr[0];
|
||||
|
||||
if (record.freeze) {
|
||||
for (var playerKillRecord : arr) {
|
||||
playerKillRecord.freeze = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (record.tick >= 80) {
|
||||
if (arr.length > 1 && record.tick - arr[1].tick < (record.fastRemove ? 2 : 20)) {
|
||||
arr[1].fastRemove = true;
|
||||
record.fastRemove = true;
|
||||
for (int j = 1; j < arr.length; j++) {
|
||||
arr[j].freeze = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (PlayerKillRecord r : KillMessageHandler.QUEUE) {
|
||||
totalTop = renderKillMessages(r, event, totalTop);
|
||||
}
|
||||
}
|
||||
|
||||
private static float renderKillMessages(PlayerKillRecord record, RenderGuiEvent.Pre event, float baseTop) {
|
||||
int w = event.getGuiGraphics().guiWidth();
|
||||
float top = baseTop;
|
||||
|
||||
Font font = Minecraft.getInstance().font;
|
||||
|
||||
AtomicReference<String> targetName = new AtomicReference<>(record.target.getDisplayName().getString());
|
||||
if (record.target instanceof Player targetPlayer) {
|
||||
CuriosApi.getCuriosInventory(targetPlayer)
|
||||
.flatMap(c -> c.findFirstCurio(ModItems.DOG_TAG.get()))
|
||||
.ifPresent(s -> targetName.set(s.stack().getHoverName().getString()));
|
||||
}
|
||||
|
||||
int targetNameWidth = font.width(targetName.get());
|
||||
|
||||
var gui = event.getGuiGraphics();
|
||||
gui.pose().pushPose();
|
||||
|
||||
RenderSystem.disableDepthTest();
|
||||
RenderSystem.depthMask(false);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.blendFuncSeparate(
|
||||
GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE,
|
||||
GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE
|
||||
);
|
||||
|
||||
// 入场效果
|
||||
if (record.tick < 3) {
|
||||
gui.pose().translate((3 - record.tick - event.getPartialTick().getGameTimeDeltaTicks()) * 33, 0, 0);
|
||||
}
|
||||
|
||||
// 4s后开始消失
|
||||
if (record.tick >= 80) {
|
||||
int animationTickCount = record.fastRemove ? 2 : 20;
|
||||
float rate = (float) Math.pow((record.tick + event.getPartialTick().getGameTimeDeltaTicks() - 80) / animationTickCount, 5);
|
||||
gui.pose().translate(rate * 100, 0, 0);
|
||||
gui.setColor(1, 1, 1, 1 - rate);
|
||||
baseTop += 10 * (1 - rate);
|
||||
} else {
|
||||
baseTop += 10;
|
||||
}
|
||||
|
||||
// 击杀提示是右对齐的,这里从右向左渲染
|
||||
|
||||
// 渲染被击杀者名称
|
||||
gui.drawString(
|
||||
Minecraft.getInstance().font,
|
||||
targetName.get(),
|
||||
w - targetNameWidth - 10f,
|
||||
top,
|
||||
record.target.getTeamColor(),
|
||||
false
|
||||
);
|
||||
|
||||
// 第一个图标:爆头/爆炸/近战等图标
|
||||
int damageTypeIconW = w - targetNameWidth - 28;
|
||||
|
||||
ResourceLocation damageTypeIcon = getDamageTypeIcon(record);
|
||||
|
||||
if (damageTypeIcon != null) {
|
||||
preciseBlit(gui,
|
||||
damageTypeIcon,
|
||||
damageTypeIconW,
|
||||
top - 2,
|
||||
0,
|
||||
0,
|
||||
12,
|
||||
12,
|
||||
12,
|
||||
12
|
||||
);
|
||||
}
|
||||
|
||||
Player player = record.attacker;
|
||||
boolean renderItem = false;
|
||||
int itemIconW = damageTypeIcon != null ? w - targetNameWidth - 64 : w - targetNameWidth - 46;
|
||||
|
||||
if (player != null && player.getVehicle() instanceof VehicleEntity vehicleEntity) {
|
||||
// 载具图标
|
||||
if ((vehicleEntity instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.banHand(player)) || record.damageType == ModDamageTypes.VEHICLE_STRIKE) {
|
||||
renderItem = true;
|
||||
|
||||
ResourceLocation resourceLocation = vehicleEntity.getVehicleIcon();
|
||||
|
||||
preciseBlit(gui,
|
||||
resourceLocation,
|
||||
itemIconW,
|
||||
top,
|
||||
0,
|
||||
0,
|
||||
32,
|
||||
8,
|
||||
-32,
|
||||
8
|
||||
);
|
||||
} else {
|
||||
if (record.stack.getItem() instanceof GunItem gunItem) {
|
||||
renderItem = true;
|
||||
|
||||
ResourceLocation resourceLocation = gunItem.getGunIcon();
|
||||
|
||||
preciseBlit(gui,
|
||||
resourceLocation,
|
||||
itemIconW,
|
||||
top,
|
||||
0,
|
||||
0,
|
||||
32,
|
||||
8,
|
||||
-32,
|
||||
8
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 如果是枪械击杀,则渲染枪械图标
|
||||
if (record.stack.getItem() instanceof GunItem gunItem) {
|
||||
renderItem = true;
|
||||
|
||||
ResourceLocation resourceLocation = gunItem.getGunIcon();
|
||||
|
||||
preciseBlit(gui,
|
||||
resourceLocation,
|
||||
itemIconW,
|
||||
top,
|
||||
0,
|
||||
0,
|
||||
32,
|
||||
8,
|
||||
-32,
|
||||
8
|
||||
);
|
||||
}
|
||||
|
||||
// TODO 如果是特殊武器击杀,则渲染对应图标
|
||||
if (record.stack.getItem().getDescriptionId().equals("item.dreamaticvoyage.world_peace_staff")) {
|
||||
renderItem = true;
|
||||
|
||||
preciseBlit(gui,
|
||||
WORLD_PEACE_STAFF,
|
||||
itemIconW,
|
||||
top,
|
||||
0,
|
||||
0,
|
||||
32,
|
||||
8,
|
||||
32,
|
||||
8
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 渲染击杀者名称
|
||||
AtomicReference<String> attackerName = new AtomicReference<>(record.attacker.getDisplayName().getString());
|
||||
CuriosApi.getCuriosInventory(record.attacker)
|
||||
.flatMap(c -> c.findFirstCurio(ModItems.DOG_TAG.get()))
|
||||
.ifPresent(s -> attackerName.set(s.stack().getHoverName().getString()));
|
||||
|
||||
int attackerNameWidth = font.width(attackerName.get());
|
||||
int nameW = w - targetNameWidth - 16 - attackerNameWidth;
|
||||
if (renderItem) {
|
||||
nameW -= 32;
|
||||
}
|
||||
if (damageTypeIcon != null) {
|
||||
nameW -= 18;
|
||||
}
|
||||
|
||||
gui.drawString(
|
||||
Minecraft.getInstance().font,
|
||||
attackerName.get(),
|
||||
nameW,
|
||||
top,
|
||||
record.attacker.getTeamColor(),
|
||||
false
|
||||
);
|
||||
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.depthMask(true);
|
||||
RenderSystem.enableDepthTest();
|
||||
|
||||
gui.setColor(1, 1, 1, 1);
|
||||
gui.pose().popPose();
|
||||
|
||||
return baseTop;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static ResourceLocation getDamageTypeIcon(PlayerKillRecord record) {
|
||||
ResourceLocation icon;
|
||||
// 渲染爆头图标
|
||||
if (record.headshot) {
|
||||
icon = HEADSHOT;
|
||||
} else {
|
||||
if (DamageTypeTool.isGunDamage(record.damageType)) {
|
||||
icon = null;
|
||||
} else {
|
||||
// 如果是其他伤害,则渲染对应图标
|
||||
if (record.damageType == DamageTypes.EXPLOSION || record.damageType == DamageTypes.PLAYER_EXPLOSION || record.damageType == ModDamageTypes.PROJECTILE_BOOM || record.damageType == DamageTypes.FIREWORKS) {
|
||||
icon = EXPLOSION;
|
||||
} else if (record.damageType == DamageTypes.PLAYER_ATTACK) {
|
||||
icon = KNIFE;
|
||||
} else if (record.damageType == ModDamageTypes.BEAST) {
|
||||
icon = BEAST;
|
||||
} else if (record.damageType == ModDamageTypes.MINE) {
|
||||
icon = CLAYMORE;
|
||||
} else if (record.damageType == ResourceKey.create(Registries.DAMAGE_TYPE, ResourceLocation.fromNamespaceAndPath("dreamaticvoyage", "bleeding"))) {
|
||||
icon = BLEEDING;
|
||||
} else if (record.damageType == ResourceKey.create(Registries.DAMAGE_TYPE, ResourceLocation.fromNamespaceAndPath("dreamaticvoyage", "blood_crystal"))) {
|
||||
icon = BLOOD_CRYSTAL;
|
||||
} else if (record.damageType == ModDamageTypes.SHOCK) {
|
||||
icon = SHOCK;
|
||||
} else if (record.damageType == ModDamageTypes.BURN || record.damageType == DamageTypes.IN_FIRE || record.damageType == DamageTypes.ON_FIRE || record.damageType == DamageTypes.LAVA) {
|
||||
icon = BURN;
|
||||
} else if (record.damageType == ModDamageTypes.DRONE_HIT) {
|
||||
icon = DRONE;
|
||||
} else if (record.damageType == ModDamageTypes.LASER || record.damageType == ModDamageTypes.LASER_HEADSHOT || record.damageType == ModDamageTypes.LASER_STATIC) {
|
||||
icon = LASER;
|
||||
} else if (record.damageType == ModDamageTypes.VEHICLE_STRIKE) {
|
||||
icon = VEHICLE;
|
||||
} else {
|
||||
icon = GENERIC;
|
||||
}
|
||||
}
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.atsuishio.superbwarfare.client.overlay;
|
||||
|
||||
import com.atsuishio.superbwarfare.client.gui.RangeHelper;
|
||||
import com.atsuishio.superbwarfare.entity.MortarEntity;
|
||||
import com.atsuishio.superbwarfare.tools.FormatTool;
|
||||
import com.atsuishio.superbwarfare.tools.TraceTool;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.client.event.RenderGuiEvent;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class MortarInfoOverlay {
|
||||
|
||||
@SubscribeEvent
|
||||
public static void eventHandler(RenderGuiEvent.Pre event) {
|
||||
int w = event.getGuiGraphics().guiWidth();
|
||||
int h = event.getGuiGraphics().guiHeight();
|
||||
Player player = Minecraft.getInstance().player;
|
||||
Entity lookingEntity = null;
|
||||
if (player != null) {
|
||||
lookingEntity = TraceTool.findLookingEntity(player, 6);
|
||||
}
|
||||
if (lookingEntity instanceof MortarEntity mortar) {
|
||||
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.mortar.pitch")
|
||||
.append(Component.literal(FormatTool.format1D(-mortar.getXRot(), "°"))),
|
||||
w / 2 - 90, h / 2 - 26, -1, false);
|
||||
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.mortar.yaw")
|
||||
.append(Component.literal(FormatTool.format1D(mortar.getYRot(), "°"))),
|
||||
w / 2 - 90, h / 2 - 16, -1, false);
|
||||
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.mortar.range")
|
||||
.append(Component.literal(FormatTool.format1D((int) RangeHelper.getRange(-mortar.getXRot()), "m"))),
|
||||
w / 2 - 90, h / 2 - 6, -1, false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package com.atsuishio.superbwarfare.client.overlay;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.client.RenderHelper;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.tools.SeekTool;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
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.RenderGuiEvent;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class RedTriangleOverlay {
|
||||
|
||||
private static final ResourceLocation TRIANGLE = ModUtils.loc("textures/screens/red_triangle.png");
|
||||
|
||||
@SubscribeEvent
|
||||
public static void eventHandler(RenderGuiEvent.Pre event) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
PoseStack poseStack = event.getGuiGraphics().pose();
|
||||
|
||||
Player player = mc.player;
|
||||
if (player == null) return;
|
||||
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
if (!stack.is(ModItems.RPG.get())) return;
|
||||
if (player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.banHand(player))
|
||||
return;
|
||||
|
||||
Entity idf = SeekTool.seekLivingEntity(player, player.level(), 128, 6);
|
||||
if (idf == null) return;
|
||||
Vec3 playerVec = new Vec3(Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), player.xo, player.getX()), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), player.yo + player.getEyeHeight(), player.getEyeY()), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), player.zo, player.getZ()));
|
||||
double distance = idf.position().distanceTo(playerVec);
|
||||
Vec3 pos = new Vec3(Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), idf.xo, idf.getX()), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), idf.yo + idf.getEyeHeight() + 0.5 + 0.07 * distance, idf.getEyeY() + 0.5 + 0.07 * distance), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), idf.zo, idf.getZ()));
|
||||
Vec3 point = RenderHelper.worldToScreen(pos, playerVec);
|
||||
if (point == null) return;
|
||||
|
||||
poseStack.pushPose();
|
||||
float x = (float) point.x;
|
||||
float y = (float) point.y;
|
||||
|
||||
RenderHelper.preciseBlit(event.getGuiGraphics(), TRIANGLE, x - 4, y - 4, 0, 0, 8, 8, 8, 8, -65536);
|
||||
|
||||
RenderSystem.depthMask(true);
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package com.atsuishio.superbwarfare.client.overlay;
|
||||
|
||||
import com.atsuishio.superbwarfare.tools.FormatTool;
|
||||
import com.atsuishio.superbwarfare.tools.TraceTool;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.ClipContext;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
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.RenderGuiEvent;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class SpyglassRangeOverlay {
|
||||
|
||||
@SubscribeEvent
|
||||
public static void eventHandler(RenderGuiEvent.Pre event) {
|
||||
int w = event.getGuiGraphics().guiWidth();
|
||||
int h = event.getGuiGraphics().guiHeight();
|
||||
Player player = Minecraft.getInstance().player;
|
||||
if (player != null && (player.getMainHandItem().getItem() == Items.SPYGLASS || player.getOffhandItem().getItem() == Items.SPYGLASS) && player.isUsingItem()) {
|
||||
boolean lookAtEntity = false;
|
||||
|
||||
BlockHitResult result = player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(player.getViewVector(1).scale(512)),
|
||||
ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player));
|
||||
Vec3 hitPos = result.getLocation();
|
||||
|
||||
double blockRange = player.getEyePosition(1).distanceTo(hitPos);
|
||||
|
||||
double entityRange = 0;
|
||||
Entity lookingEntity = TraceTool.findLookingEntity(player, 520);
|
||||
|
||||
if (lookingEntity != null) {
|
||||
lookAtEntity = true;
|
||||
entityRange = player.distanceTo(lookingEntity);
|
||||
}
|
||||
|
||||
if (lookAtEntity) {
|
||||
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.drone.range")
|
||||
.append(Component.literal(FormatTool.format1D(entityRange, "M ") + lookingEntity.getDisplayName().getString())),
|
||||
w / 2 + 12, h / 2 - 28, -1, false);
|
||||
} else {
|
||||
if (blockRange > 500) {
|
||||
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.drone.range")
|
||||
.append(Component.literal("---M")), w / 2 + 12, h / 2 - 28, -1, false);
|
||||
} else {
|
||||
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.drone.range")
|
||||
.append(Component.literal(FormatTool.format1D(blockRange, "M"))),
|
||||
w / 2 + 12, h / 2 - 28, -1, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,584 @@
|
|||
package com.atsuishio.superbwarfare.client.overlay;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.client.RenderHelper;
|
||||
import com.atsuishio.superbwarfare.config.client.DisplayConfig;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.Bmp2Entity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.Lav150Entity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.SpeedboatEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.Yx100Entity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.*;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.weapon.HeliRocketWeapon;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.weapon.LaserWeapon;
|
||||
import com.atsuishio.superbwarfare.event.ClientEventHandler;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.tools.FormatTool;
|
||||
import com.atsuishio.superbwarfare.tools.InventoryTool;
|
||||
import com.atsuishio.superbwarfare.tools.NBTTool;
|
||||
import com.atsuishio.superbwarfare.tools.SeekTool;
|
||||
import com.atsuishio.superbwarfare.tools.animation.AnimationCurves;
|
||||
import com.atsuishio.superbwarfare.tools.animation.AnimationTimer;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Axis;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.CameraType;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.ClipContext;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.EventPriority;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.client.event.RenderGuiEvent;
|
||||
import org.joml.Math;
|
||||
import top.theillusivec4.curios.api.CuriosApi;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit;
|
||||
import static com.atsuishio.superbwarfare.client.overlay.CrossHairOverlay.*;
|
||||
import static com.atsuishio.superbwarfare.entity.vehicle.Bmp2Entity.LOADED_MISSILE;
|
||||
import static com.atsuishio.superbwarfare.entity.vehicle.Bmp2Entity.MISSILE_COUNT;
|
||||
import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity.*;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class VehicleHudOverlay {
|
||||
|
||||
private static float scopeScale = 1;
|
||||
private static final ResourceLocation FRAME = ModUtils.loc("textures/screens/land/tv_frame.png");
|
||||
private static final ResourceLocation ARMOR = ModUtils.loc("textures/screens/armor.png");
|
||||
private static final ResourceLocation ENERGY = ModUtils.loc("textures/screens/energy.png");
|
||||
private static final ResourceLocation HEALTH = ModUtils.loc("textures/screens/armor_value.png");
|
||||
private static final ResourceLocation HEALTH_FRAME = ModUtils.loc("textures/screens/armor_value_frame.png");
|
||||
private static final ResourceLocation DRIVER = ModUtils.loc("textures/screens/driver.png");
|
||||
private static final ResourceLocation PASSENGER = ModUtils.loc("textures/screens/passenger.png");
|
||||
private static final ResourceLocation SELECTED = ModUtils.loc("textures/screens/vehicle_weapon/selected.png");
|
||||
private static final ResourceLocation NUMBER = ModUtils.loc("textures/screens/vehicle_weapon/number.png");
|
||||
|
||||
public static final int ANIMATION_TIME = 300;
|
||||
private static final AnimationTimer[] weaponSlotsTimer = AnimationTimer.createTimers(9, ANIMATION_TIME, AnimationCurves.EASE_OUT_CIRC);
|
||||
private static boolean wasRenderingWeapons = false;
|
||||
private static int oldWeaponIndex = 0;
|
||||
private static int oldRenderWeaponIndex = 0;
|
||||
private static final AnimationTimer weaponIndexUpdateTimer = new AnimationTimer(ANIMATION_TIME).animation(AnimationCurves.EASE_OUT_CIRC);
|
||||
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void eventHandler(RenderGuiEvent.Pre event) {
|
||||
int w = event.getGuiGraphics().guiWidth();
|
||||
int h = event.getGuiGraphics().guiHeight();
|
||||
Player player = Minecraft.getInstance().player;
|
||||
|
||||
if (!shouldRenderHud(player)) {
|
||||
wasRenderingWeapons = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Entity vehicle = player.getVehicle();
|
||||
|
||||
GuiGraphics guiGraphics = event.getGuiGraphics();
|
||||
PoseStack poseStack = guiGraphics.pose();
|
||||
|
||||
poseStack.pushPose();
|
||||
|
||||
RenderSystem.disableDepthTest();
|
||||
RenderSystem.depthMask(false);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||
|
||||
// 渲染地面武装HUD
|
||||
renderLandArmorHud(event, w, h);
|
||||
|
||||
int compatHeight = getArmorPlateCompatHeight(player);
|
||||
|
||||
if (vehicle instanceof EnergyVehicleEntity energyVehicleEntity) {
|
||||
float energy = energyVehicleEntity.getEnergy();
|
||||
float maxEnergy = energyVehicleEntity.getMaxEnergy();
|
||||
preciseBlit(guiGraphics, ENERGY, 10, h - 22 - compatHeight, 100, 0, 0, 8, 8, 8, 8);
|
||||
preciseBlit(guiGraphics, HEALTH_FRAME, 20, h - 21 - compatHeight, 100, 0, 0, 60, 6, 60, 6);
|
||||
preciseBlit(guiGraphics, HEALTH, 20, h - 21 - compatHeight, 100, 0, 0, (int) (60 * energy / maxEnergy), 6, 60, 6);
|
||||
}
|
||||
|
||||
if (vehicle instanceof VehicleEntity pVehicle) {
|
||||
float health = pVehicle.getHealth();
|
||||
float maxHealth = pVehicle.getMaxHealth();
|
||||
preciseBlit(guiGraphics, ARMOR, 10, h - 13 - compatHeight, 100, 0, 0, 8, 8, 8, 8);
|
||||
preciseBlit(guiGraphics, HEALTH_FRAME, 20, h - 12 - compatHeight, 100, 0, 0, 60, 6, 60, 6);
|
||||
preciseBlit(guiGraphics, HEALTH, 20, h - 12 - compatHeight, 100, 0, 0, (int) (60 * health / maxHealth), 6, 60, 6);
|
||||
|
||||
renderWeaponInfo(guiGraphics, pVehicle, w, h);
|
||||
renderPassengerInfo(guiGraphics, pVehicle, w, h);
|
||||
}
|
||||
|
||||
poseStack.popPose();
|
||||
}
|
||||
|
||||
private static boolean shouldRenderHud(Player player) {
|
||||
if (player == null) return false;
|
||||
return !player.isSpectator() && (player.getVehicle() != null && player.getVehicle() instanceof VehicleEntity);
|
||||
}
|
||||
|
||||
private static int getArmorPlateCompatHeight(Player player) {
|
||||
ItemStack stack = player.getItemBySlot(EquipmentSlot.CHEST);
|
||||
if (stack == ItemStack.EMPTY) return 0;
|
||||
if (!NBTTool.getTag(stack).contains("ArmorPlate")) return 0;
|
||||
if (!DisplayConfig.ARMOR_PLATE_HUD.get()) return 0;
|
||||
return 9;
|
||||
}
|
||||
|
||||
public static void renderLandArmorHud(RenderGuiEvent.Pre event, int w, int h) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
Player player = mc.player;
|
||||
GuiGraphics guiGraphics = event.getGuiGraphics();
|
||||
PoseStack poseStack = guiGraphics.pose();
|
||||
Camera camera = mc.gameRenderer.getMainCamera();
|
||||
Vec3 cameraPos = camera.getPosition();
|
||||
|
||||
assert player != null;
|
||||
|
||||
if (player.getVehicle() instanceof LandArmorEntity iLand && iLand.isDriver(player)
|
||||
&& iLand instanceof WeaponVehicleEntity weaponVehicle
|
||||
&& iLand instanceof MobileVehicleEntity mobileVehicle
|
||||
&& !(player.getVehicle() instanceof SpeedboatEntity)) {
|
||||
poseStack.pushPose();
|
||||
|
||||
poseStack.translate(0.2 * ClientEventHandler.shakeTime + 5 * ClientEventHandler.cameraRoll, 0 - 0.3 * ClientEventHandler.shakeTime + 5 * ClientEventHandler.cameraRoll, 0);
|
||||
poseStack.rotateAround(Axis.ZP.rotationDegrees(-0.5f * ClientEventHandler.cameraRoll), w / 2f, h / 2f, 0);
|
||||
RenderSystem.disableDepthTest();
|
||||
RenderSystem.depthMask(false);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||
|
||||
scopeScale = Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), scopeScale, 1F);
|
||||
float f = (float) Math.min(w, h);
|
||||
float f1 = Math.min((float) w / f, (float) h / f) * scopeScale;
|
||||
float i = Mth.floor(f * f1);
|
||||
float j = Mth.floor(f * f1);
|
||||
float k = ((w - i) / 2);
|
||||
float l = ((h - j) / 2);
|
||||
|
||||
if (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON || ClientEventHandler.zoomVehicle) {
|
||||
int addW = (w / h) * 48;
|
||||
int addH = (w / h) * 27;
|
||||
preciseBlit(guiGraphics, FRAME, (float) -addW / 2, (float) -addH / 2, 10, 0, 0.0F, w + addW, h + addH, w + addW, h + addH);
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/land/line.png"), w / 2f - 64, h - 56, 0, 0.0F, 128, 1, 128, 1);
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/land/line.png"), w / 2f + 112, h - 71, 0, 0.0F, 1, 16, 1, 16);
|
||||
|
||||
// 不同武器种类的准星
|
||||
if (weaponVehicle instanceof Yx100Entity) {
|
||||
if (weaponVehicle.getWeaponIndex(0) == 0) {
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/land/tank_cannon_cross_ap.png"), k, l, 0, 0.0F, i, j, i, j);
|
||||
} else if (weaponVehicle.getWeaponIndex(0) == 1) {
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/land/tank_cannon_cross_he.png"), k, l, 0, 0.0F, i, j, i, j);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (weaponVehicle.getWeaponIndex(0) == 0) {
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/land/lav_cannon_cross.png"), k, l, 0, 0.0F, i, j, i, j);
|
||||
} else if (weaponVehicle.getWeaponIndex(0) == 1) {
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/land/lav_gun_cross.png"), k, l, 0, 0.0F, i, j, i, j);
|
||||
} else if (weaponVehicle.getWeaponIndex(0) == 2) {
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/land/lav_missile_cross.png"), k, l, 0, 0.0F, i, j, i, j);
|
||||
}
|
||||
}
|
||||
|
||||
// 指南针
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/compass.png"), (float) w / 2 - 128, (float) 10, 128 + ((float) 64 / 45 * player.getYRot()), 0, 256, 16, 512, 16);
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/helicopter/roll_ind.png"), w / 2f - 8, 30, 0, 0.0F, 16, 16, 16, 16);
|
||||
|
||||
// 炮塔方向
|
||||
poseStack.pushPose();
|
||||
poseStack.rotateAround(Axis.ZP.rotationDegrees(Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), iLand.turretYRotO(), iLand.turretYRot())), w / 2f + 112, h - 56, 0);
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/land/body.png"), w / 2f + 96, h - 72, 0, 0.0F, 32, 32, 32, 32);
|
||||
poseStack.popPose();
|
||||
|
||||
// 时速
|
||||
guiGraphics.drawString(mc.font, Component.literal(FormatTool.format0D(mobileVehicle.getDeltaMovement().length() * 72, " km/h")),
|
||||
w / 2 + 160, h / 2 - 48, 0x66FF00, false);
|
||||
|
||||
// 低电量警告
|
||||
if (mobileVehicle.getEnergy() < 0.02 * mobileVehicle.getMaxEnergy()) {
|
||||
guiGraphics.drawString(mc.font, Component.literal("NO POWER!"),
|
||||
w / 2 - 144, h / 2 + 14, -65536, false);
|
||||
} else if (mobileVehicle.getEnergy() < 0.2 * mobileVehicle.getMaxEnergy()) {
|
||||
guiGraphics.drawString(mc.font, Component.literal("LOW POWER"),
|
||||
w / 2 - 144, h / 2 + 14, 0xFF6B00, false);
|
||||
}
|
||||
|
||||
// 测距
|
||||
boolean lookAtEntity = false;
|
||||
|
||||
BlockHitResult result = player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(player.getViewVector(1).scale(512)),
|
||||
ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player));
|
||||
Vec3 hitPos = result.getLocation();
|
||||
|
||||
double blockRange = player.getEyePosition(1).distanceTo(hitPos);
|
||||
|
||||
double entityRange = 0;
|
||||
|
||||
Entity lookingEntity = SeekTool.seekLivingEntity(player, player.level(), 512, 1);
|
||||
if (lookingEntity != null) {
|
||||
lookAtEntity = true;
|
||||
entityRange = player.distanceTo(lookingEntity);
|
||||
}
|
||||
|
||||
if (lookAtEntity) {
|
||||
guiGraphics.drawString(mc.font, Component.literal(FormatTool.format1D(entityRange, "m")),
|
||||
w / 2 - 6, h - 53, 0x66FF00, false);
|
||||
} else {
|
||||
if (blockRange > 500) {
|
||||
guiGraphics.drawString(mc.font, Component.literal("---m"), w / 2 - 6, h - 53, 0x66FF00, false);
|
||||
} else {
|
||||
guiGraphics.drawString(mc.font, Component.literal(FormatTool.format1D(blockRange, "m")),
|
||||
w / 2 - 6, h - 53, 0x66FF00, false);
|
||||
}
|
||||
}
|
||||
|
||||
// 武器名称
|
||||
// LAV-150
|
||||
if (player.getVehicle() instanceof Lav150Entity lav) {
|
||||
if (weaponVehicle.getWeaponIndex(0) == 0) {
|
||||
double heat = 1 - lav.getEntityData().get(HEAT) / 100.0F;
|
||||
guiGraphics.drawString(mc.font, Component.literal("20MM CANNON " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : lav.getAmmoCount(player))), w / 2 - 33, h - 65, Mth.hsvToRgb((float) heat / 3.745318352059925F, 1.0F, 1.0F), false);
|
||||
} else {
|
||||
double heat = 1 - lav.getEntityData().get(COAX_HEAT) / 100.0F;
|
||||
guiGraphics.drawString(mc.font, Component.literal("7.62MM COAX " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : lav.getAmmoCount(player))), w / 2 - 33, h - 65, Mth.hsvToRgb((float) heat / 3.745318352059925F, 1.0F, 1.0F), false);
|
||||
}
|
||||
}
|
||||
|
||||
// BMP-2
|
||||
if (player.getVehicle() instanceof Bmp2Entity bmp2) {
|
||||
if (weaponVehicle.getWeaponIndex(0) == 0) {
|
||||
double heat = 1 - bmp2.getEntityData().get(HEAT) / 100.0F;
|
||||
guiGraphics.drawString(mc.font, Component.literal(" 30MM 2A42 " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : bmp2.getAmmoCount(player))), w / 2 - 33, h - 65, Mth.hsvToRgb((float) heat / 3.745318352059925F, 1.0F, 1.0F), false);
|
||||
} else if (weaponVehicle.getWeaponIndex(0) == 1) {
|
||||
double heat = 1 - bmp2.getEntityData().get(COAX_HEAT) / 100.0F;
|
||||
guiGraphics.drawString(mc.font, Component.literal(" 7.62MM ПКТ " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : bmp2.getAmmoCount(player))), w / 2 - 33, h - 65, Mth.hsvToRgb((float) heat / 3.745318352059925F, 1.0F, 1.0F), false);
|
||||
} else {
|
||||
guiGraphics.drawString(mc.font, Component.literal(" 9M113 " + bmp2.getEntityData().get(LOADED_MISSILE) + " " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : bmp2.getEntityData().get(MISSILE_COUNT))), w / 2 - 33, h - 65, 0x66FF00, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// YX-100
|
||||
if (player.getVehicle() instanceof Yx100Entity yx100) {
|
||||
if (weaponVehicle.getWeaponIndex(0) == 0) {
|
||||
guiGraphics.drawString(mc.font, Component.literal("AP SHELL " + yx100.getAmmoCount(player) + " " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : yx100.getEntityData().get(AMMO))), w / 2 - 33, h - 65, 0x66FF00, false);
|
||||
} else if (weaponVehicle.getWeaponIndex(0) == 1) {
|
||||
guiGraphics.drawString(mc.font, Component.literal("HE SHELL " + yx100.getAmmoCount(player) + " " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : yx100.getEntityData().get(AMMO))), w / 2 - 33, h - 65, 0x66FF00, false);
|
||||
} else if (weaponVehicle.getWeaponIndex(0) == 2) {
|
||||
double heat = 1 - yx100.getEntityData().get(COAX_HEAT) / 100.0F;
|
||||
guiGraphics.drawString(mc.font, Component.literal(" 12.7MM HMG " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : yx100.getAmmoCount(player))), w / 2 - 33, h - 65, Mth.hsvToRgb((float) heat / 3.745318352059925F, 1.0F, 1.0F), false);
|
||||
}
|
||||
}
|
||||
|
||||
// 血量
|
||||
double heal = mobileVehicle.getHealth() / mobileVehicle.getMaxHealth();
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(FormatTool.format0D(100 * heal)), w / 2 - 165, h / 2 - 46, Mth.hsvToRgb((float) heal / 3.745318352059925F, 1.0F, 1.0F), false);
|
||||
|
||||
renderKillIndicator(guiGraphics, w, h);
|
||||
} else if (Minecraft.getInstance().options.getCameraType() == CameraType.THIRD_PERSON_BACK && !ClientEventHandler.zoomVehicle) {
|
||||
Vec3 p = RenderHelper.worldToScreen(new Vec3(Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), player.xo, player.getX()), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), player.yo + player.getEyeHeight(), player.getEyeY()), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), player.zo, player.getZ())).add(iLand.getBarrelVec(event.getPartialTick().getGameTimeDeltaTicks()).scale(192)), cameraPos);
|
||||
// 第三人称准星
|
||||
if (p != null) {
|
||||
poseStack.pushPose();
|
||||
float x = (float) p.x;
|
||||
float y = (float) p.y;
|
||||
|
||||
poseStack.pushPose();
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/drone.png"), x - 12, y - 12, 0, 0, 24, 24, 24, 24);
|
||||
renderKillIndicator3P(guiGraphics, x - 7.5f + (float) (2 * (Math.random() - 0.5f)), y - 7.5f + (float) (2 * (Math.random() - 0.5f)));
|
||||
|
||||
poseStack.pushPose();
|
||||
|
||||
poseStack.translate(x, y, 0);
|
||||
poseStack.scale(0.75f, 0.75f, 1);
|
||||
|
||||
// LAV-150
|
||||
if (weaponVehicle instanceof Lav150Entity lav1501) {
|
||||
if (weaponVehicle.getWeaponIndex(0) == 0) {
|
||||
double heat = lav1501.getEntityData().get(HEAT) / 100.0F;
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("20MM CANNON " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : lav1501.getAmmoCount(player))), 30, -9, Mth.hsvToRgb(0F, (float) heat, 1.0F), false);
|
||||
} else {
|
||||
double heat2 = lav1501.getEntityData().get(COAX_HEAT) / 100.0F;
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("7.62MM COAX " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : lav1501.getAmmoCount(player))), 30, -9, Mth.hsvToRgb(0F, (float) heat2, 1.0F), false);
|
||||
}
|
||||
}
|
||||
// BMP-2
|
||||
if (weaponVehicle instanceof Bmp2Entity bmp201) {
|
||||
if (weaponVehicle.getWeaponIndex(0) == 0) {
|
||||
double heat = bmp201.getEntityData().get(HEAT) / 100.0F;
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("30MM 2A42 " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : bmp201.getAmmoCount(player))), 30, -9, Mth.hsvToRgb(0F, (float) heat, 1.0F), false);
|
||||
} else if (weaponVehicle.getWeaponIndex(0) == 1) {
|
||||
double heat2 = bmp201.getEntityData().get(COAX_HEAT) / 100.0F;
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("7.62MM ПКТ " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : bmp201.getAmmoCount(player))), 30, -9, Mth.hsvToRgb(0F, (float) heat2, 1.0F), false);
|
||||
} else {
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("9M113 " + bmp201.getEntityData().get(LOADED_MISSILE) + " " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : bmp201.getEntityData().get(MISSILE_COUNT))), 30, -9, -1, false);
|
||||
}
|
||||
}
|
||||
// YX-100
|
||||
if (weaponVehicle instanceof Yx100Entity yx100) {
|
||||
if (weaponVehicle.getWeaponIndex(0) == 0) {
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("AP SHELL " + yx100.getAmmoCount(player) + " " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : yx100.getEntityData().get(AMMO))), 30, -9, -1, false);
|
||||
} else if (weaponVehicle.getWeaponIndex(0) == 1) {
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("HE SHELL " + yx100.getAmmoCount(player) + " " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : yx100.getEntityData().get(AMMO))), 30, -9, -1, false);
|
||||
} else if (weaponVehicle.getWeaponIndex(0) == 2) {
|
||||
double heat2 = yx100.getEntityData().get(COAX_HEAT) / 100.0F;
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("7.62MM ПКТ " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : yx100.getAmmoCount(player))), 30, -9, Mth.hsvToRgb(0F, (float) heat2, 1.0F), false);
|
||||
}
|
||||
}
|
||||
|
||||
double heal = 1 - mobileVehicle.getHealth() / mobileVehicle.getMaxHealth();
|
||||
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("HP " +
|
||||
FormatTool.format0D(100 * mobileVehicle.getHealth() / mobileVehicle.getMaxHealth())), 30, 1, Mth.hsvToRgb(0F, (float) heal, 1.0F), false);
|
||||
|
||||
poseStack.popPose();
|
||||
poseStack.popPose();
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
||||
poseStack.popPose();
|
||||
} else {
|
||||
scopeScale = 0.7f;
|
||||
}
|
||||
}
|
||||
|
||||
public static void renderKillIndicator(GuiGraphics guiGraphics, float w, float h) {
|
||||
float posX = w / 2f - 7.5f + (float) (2 * (Math.random() - 0.5f));
|
||||
float posY = h / 2f - 7.5f + (float) (2 * (Math.random() - 0.5f));
|
||||
float rate = (40 - KILL_INDICATOR * 5) / 5.5f;
|
||||
|
||||
if (HIT_INDICATOR > 0) {
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/hit_marker.png"), posX, posY, 0, 0, 16, 16, 16, 16);
|
||||
}
|
||||
|
||||
if (VEHICLE_INDICATOR > 0) {
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/hit_marker_vehicle.png"), posX, posY, 0, 0, 16, 16, 16, 16);
|
||||
}
|
||||
|
||||
if (HEAD_INDICATOR > 0) {
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/headshot_mark.png"), posX, posY, 0, 0, 16, 16, 16, 16);
|
||||
}
|
||||
|
||||
if (KILL_INDICATOR > 0) {
|
||||
float posX1 = w / 2f - 7.5f - 2 + rate;
|
||||
float posY1 = h / 2f - 7.5f - 2 + rate;
|
||||
float posX2 = w / 2f - 7.5f + 2 - rate;
|
||||
float posY2 = h / 2f - 7.5f + 2 - rate;
|
||||
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/kill_mark1.png"), posX1, posY1, 0, 0, 16, 16, 16, 16);
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/kill_mark2.png"), posX2, posY1, 0, 0, 16, 16, 16, 16);
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/kill_mark3.png"), posX1, posY2, 0, 0, 16, 16, 16, 16);
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/kill_mark4.png"), posX2, posY2, 0, 0, 16, 16, 16, 16);
|
||||
}
|
||||
}
|
||||
|
||||
public static void renderKillIndicator3P(GuiGraphics guiGraphics, float posX, float posY) {
|
||||
float rate = (40 - KILL_INDICATOR * 5) / 5.5f;
|
||||
|
||||
if (HIT_INDICATOR > 0) {
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/hit_marker.png"), posX, posY, 0, 0, 16, 16, 16, 16);
|
||||
}
|
||||
|
||||
if (VEHICLE_INDICATOR > 0) {
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/hit_marker_vehicle.png"), posX, posY, 0, 0, 16, 16, 16, 16);
|
||||
}
|
||||
|
||||
if (HEAD_INDICATOR > 0) {
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/headshot_mark.png"), posX, posY, 0, 0, 16, 16, 16, 16);
|
||||
}
|
||||
|
||||
if (KILL_INDICATOR > 0) {
|
||||
float posX1 = posX - 2 + rate;
|
||||
float posY1 = posY - 2 + rate;
|
||||
float posX2 = posX + 2 - rate;
|
||||
float posY2 = posY + 2 - rate;
|
||||
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/kill_mark1.png"), posX1, posY1, 0, 0, 16, 16, 16, 16);
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/kill_mark2.png"), posX2, posY1, 0, 0, 16, 16, 16, 16);
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/kill_mark3.png"), posX1, posY2, 0, 0, 16, 16, 16, 16);
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/kill_mark4.png"), posX2, posY2, 0, 0, 16, 16, 16, 16);
|
||||
}
|
||||
}
|
||||
|
||||
private static void renderPassengerInfo(GuiGraphics guiGraphics, VehicleEntity vehicle, int w, int h) {
|
||||
var passengers = vehicle.getOrderedPassengers();
|
||||
|
||||
int index = 0;
|
||||
for (int i = passengers.size() - 1; i >= 0; i--) {
|
||||
var passenger = passengers.get(i);
|
||||
|
||||
int y = h - 35 - index * 12;
|
||||
AtomicReference<String> name = new AtomicReference<>("---");
|
||||
|
||||
if (passenger != null) {
|
||||
name.set(passenger.getName().getString());
|
||||
}
|
||||
|
||||
if (passenger instanceof Player player) {
|
||||
CuriosApi.getCuriosInventory(player)
|
||||
.flatMap(c -> c.findFirstCurio(ModItems.DOG_TAG.get()))
|
||||
.ifPresent(s -> name.set(s.stack().getHoverName().getString()));
|
||||
}
|
||||
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, name.get(), 42, y, 0x66ff00, true);
|
||||
|
||||
String num = "[" + (i + 1) + "]";
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, num, 25 - Minecraft.getInstance().font.width(num), y, 0x66ff00, true);
|
||||
|
||||
preciseBlit(guiGraphics, index == passengers.size() - 1 ? DRIVER : PASSENGER, 30, y, 100, 0, 0, 8, 8, 8, 8);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
private static void renderWeaponInfo(GuiGraphics guiGraphics, VehicleEntity vehicle, int w, int h) {
|
||||
if (!(vehicle instanceof WeaponVehicleEntity weaponVehicle)) return;
|
||||
|
||||
var temp = wasRenderingWeapons;
|
||||
wasRenderingWeapons = false;
|
||||
|
||||
Player player = Minecraft.getInstance().player;
|
||||
assert player != null;
|
||||
|
||||
int index = vehicle.getSeatIndex(player);
|
||||
if (index == -1) return;
|
||||
|
||||
var weapons = weaponVehicle.getAvailableWeapons(index);
|
||||
if (weapons.isEmpty()) return;
|
||||
|
||||
int weaponIndex = weaponVehicle.getWeaponIndex(index);
|
||||
if (weaponIndex == -1) return;
|
||||
|
||||
wasRenderingWeapons = temp;
|
||||
|
||||
var currentTime = System.currentTimeMillis();
|
||||
|
||||
// 若上一帧未在渲染武器信息,则初始化动画相关变量
|
||||
if (!wasRenderingWeapons) {
|
||||
weaponSlotsTimer[weaponIndex].beginForward(currentTime);
|
||||
|
||||
if (oldWeaponIndex != weaponIndex) {
|
||||
weaponSlotsTimer[oldWeaponIndex].endBackward(currentTime);
|
||||
|
||||
oldWeaponIndex = weaponIndex;
|
||||
oldRenderWeaponIndex = weaponIndex;
|
||||
}
|
||||
|
||||
weaponIndexUpdateTimer.beginForward(currentTime);
|
||||
}
|
||||
|
||||
// 切换武器时,更新上一个武器槽位和当前武器槽位的动画信息
|
||||
if (weaponIndex != oldWeaponIndex) {
|
||||
weaponSlotsTimer[weaponIndex].forward(currentTime);
|
||||
weaponSlotsTimer[oldWeaponIndex].backward(currentTime);
|
||||
|
||||
oldRenderWeaponIndex = oldWeaponIndex;
|
||||
oldWeaponIndex = weaponIndex;
|
||||
|
||||
weaponIndexUpdateTimer.beginForward(currentTime);
|
||||
}
|
||||
|
||||
var pose = guiGraphics.pose();
|
||||
|
||||
pose.pushPose();
|
||||
|
||||
RenderSystem.disableDepthTest();
|
||||
RenderSystem.depthMask(false);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||
|
||||
int frameIndex = 0;
|
||||
|
||||
for (int i = weapons.size() - 1; i >= 0 && i < 9; i--) {
|
||||
var weapon = weapons.get(i);
|
||||
|
||||
ResourceLocation frame = ModUtils.loc("textures/screens/vehicle_weapon/frame_" + (i + 1) + ".png");
|
||||
pose.pushPose();
|
||||
|
||||
// 相对于最左边的偏移量
|
||||
float xOffset;
|
||||
// 向右偏移的最长长度
|
||||
var maxXOffset = 35;
|
||||
|
||||
var currentSlotTimer = weaponSlotsTimer[i];
|
||||
var progress = currentSlotTimer.getProgress(currentTime);
|
||||
|
||||
RenderSystem.setShaderColor(1, 1, 1, Mth.lerp(progress, 0.2f, 1));
|
||||
xOffset = Mth.lerp(progress, maxXOffset, 0);
|
||||
|
||||
// 当前选中武器
|
||||
if (weaponIndex == i) {
|
||||
var startY = Mth.lerp(progress,
|
||||
h - (weapons.size() - 1 - oldRenderWeaponIndex) * 18 - 16,
|
||||
h - (weapons.size() - 1 - weaponIndex) * 18 - 16
|
||||
);
|
||||
|
||||
preciseBlit(guiGraphics, SELECTED, w - 95, startY, 100, 0, 0, 8, 8, 8, 8);
|
||||
if (InventoryTool.hasCreativeAmmoBox(player) && !(weapon instanceof LaserWeapon) && !(weapon instanceof HeliRocketWeapon)) {
|
||||
preciseBlit(guiGraphics, NUMBER, w - 28 + xOffset, h - frameIndex * 18 - 15, 100, 58, 0, 10, 7.5f, 75, 7.5f);
|
||||
} else {
|
||||
renderNumber(guiGraphics, weaponVehicle.getAmmoCount(player), weapon instanceof LaserWeapon,
|
||||
w - 20 + xOffset, h - frameIndex * 18 - 15.5f, 0.25f);
|
||||
}
|
||||
}
|
||||
|
||||
preciseBlit(guiGraphics, frame, w - 85 + xOffset, h - frameIndex * 18 - 20, 100, 0, 0, 75, 16, 75, 16);
|
||||
preciseBlit(guiGraphics, weapon.icon, w - 85 + xOffset, h - frameIndex * 18 - 20, 100, 0, 0, 75, 16, 75, 16);
|
||||
|
||||
pose.popPose();
|
||||
|
||||
frameIndex++;
|
||||
}
|
||||
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||
pose.popPose();
|
||||
|
||||
// 切换武器光标动画播放结束后,更新上次选择槽位
|
||||
if (oldWeaponIndex != oldRenderWeaponIndex && weaponIndexUpdateTimer.finished(currentTime)) {
|
||||
oldRenderWeaponIndex = oldWeaponIndex;
|
||||
}
|
||||
wasRenderingWeapons = true;
|
||||
}
|
||||
|
||||
private static void renderNumber(GuiGraphics guiGraphics, int number, boolean percent, float x, float y, float scale) {
|
||||
float pX = x;
|
||||
if (percent) {
|
||||
pX -= 32 * scale;
|
||||
preciseBlit(guiGraphics, NUMBER, pX + 20 * scale, y, 100,
|
||||
200 * scale, 0, 32 * scale, 30 * scale, 300 * scale, 30 * scale);
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
if (number == 0) {
|
||||
preciseBlit(guiGraphics, NUMBER, pX, y, 100,
|
||||
0, 0, 20 * scale, 30 * scale, 300 * scale, 30 * scale);
|
||||
}
|
||||
|
||||
while (number > 0) {
|
||||
int digit = number % 10;
|
||||
preciseBlit(guiGraphics, NUMBER, pX - index * 20 * scale, y, 100,
|
||||
digit * 20 * scale, 0, 20 * scale, 30 * scale, 300 * scale, 30 * scale);
|
||||
number /= 10;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
package com.atsuishio.superbwarfare.client.overlay;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.client.RenderHelper;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.SpeedboatEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.Yx100Entity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.LandArmorEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.WeaponVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.event.ClientEventHandler;
|
||||
import com.atsuishio.superbwarfare.tools.FormatTool;
|
||||
import com.atsuishio.superbwarfare.tools.InventoryTool;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.CameraType;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
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.RenderGuiEvent;
|
||||
import org.joml.Math;
|
||||
|
||||
import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit;
|
||||
import static com.atsuishio.superbwarfare.client.overlay.VehicleHudOverlay.renderKillIndicator3P;
|
||||
import static com.atsuishio.superbwarfare.entity.vehicle.Yx100Entity.MG_AMMO;
|
||||
import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity.AMMO;
|
||||
import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity.HEAT;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class VehicleMgHudOverlay {
|
||||
|
||||
@SubscribeEvent
|
||||
public static void eventHandler(RenderGuiEvent.Pre event) {
|
||||
int w = event.getGuiGraphics().guiWidth();
|
||||
int h = event.getGuiGraphics().guiHeight();
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
Player player = mc.player;
|
||||
GuiGraphics guiGraphics = event.getGuiGraphics();
|
||||
PoseStack poseStack = guiGraphics.pose();
|
||||
Camera camera = mc.gameRenderer.getMainCamera();
|
||||
Vec3 cameraPos = camera.getPosition();
|
||||
|
||||
if (!shouldRenderCrossHair(player)) return;
|
||||
|
||||
Entity cannon = player.getVehicle();
|
||||
if (cannon == null) return;
|
||||
|
||||
RenderSystem.disableDepthTest();
|
||||
RenderSystem.depthMask(false);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||
|
||||
if (player.getVehicle() instanceof LandArmorEntity iLand && iLand instanceof WeaponVehicleEntity weaponVehicle && iLand instanceof MobileVehicleEntity mobileVehicle && weaponVehicle.hasWeapon(mobileVehicle.getSeatIndex(player))) {
|
||||
if (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON || ClientEventHandler.zoomVehicle) {
|
||||
float fovAdjust = (float) 70 / Minecraft.getInstance().options.fov().get();
|
||||
|
||||
float f = (float) Math.min(w, h);
|
||||
float f1 = Math.min((float) w / f, (float) h / f) * fovAdjust;
|
||||
int i = Mth.floor(f * f1);
|
||||
int j = Mth.floor(f * f1);
|
||||
int k = (w - i) / 2;
|
||||
int l = (h - j) / 2;
|
||||
RenderHelper.preciseBlit(guiGraphics, ModUtils.loc("textures/screens/cannon/cannon_crosshair_notzoom.png"), k, l, 0, 0.0F, i, j, i, j);
|
||||
VehicleHudOverlay.renderKillIndicator(guiGraphics, w, h);
|
||||
} else if (Minecraft.getInstance().options.getCameraType() == CameraType.THIRD_PERSON_BACK && !ClientEventHandler.zoomVehicle) {
|
||||
Vec3 p = RenderHelper.worldToScreen(new Vec3(Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), player.xo, player.getX()), Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), player.yo + player.getEyeHeight(), player.getEyeY()),
|
||||
Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), player.zo, player.getZ())).add(iLand.getGunVec(event.getPartialTick().getGameTimeDeltaTicks()).scale(192)), cameraPos);
|
||||
|
||||
// 第三人称准星
|
||||
if (p != null) {
|
||||
poseStack.pushPose();
|
||||
float x = (float) p.x;
|
||||
float y = (float) p.y;
|
||||
|
||||
poseStack.pushPose();
|
||||
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/drone.png"), x - 12, y - 12, 0, 0, 24, 24, 24, 24);
|
||||
renderKillIndicator3P(guiGraphics, x - 7.5f + (float) (2 * (Math.random() - 0.5f)), y - 7.5f + (float) (2 * (Math.random() - 0.5f)));
|
||||
|
||||
poseStack.pushPose();
|
||||
|
||||
poseStack.translate(x, y, 0);
|
||||
poseStack.scale(0.75f, 0.75f, 1);
|
||||
|
||||
// YX-100
|
||||
if (player.getVehicle() instanceof Yx100Entity yx100) {
|
||||
double heat = yx100.getEntityData().get(HEAT) / 100.0F;
|
||||
guiGraphics.drawString(mc.font, Component.literal(".50 HMG " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : yx100.getEntityData().get(MG_AMMO))), 30, -9, Mth.hsvToRgb(0F, (float) heat, 1.0F), false);
|
||||
}
|
||||
|
||||
// 快艇
|
||||
if (player.getVehicle() instanceof SpeedboatEntity speedboat) {
|
||||
double heat = speedboat.getEntityData().get(HEAT) / 100.0F;
|
||||
guiGraphics.drawString(mc.font, Component.literal(".50 HMG " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : speedboat.getEntityData().get(AMMO))), 30, -9, Mth.hsvToRgb(0F, (float) heat, 1.0F), false);
|
||||
}
|
||||
|
||||
double heal = 1 - mobileVehicle.getHealth() / mobileVehicle.getMaxHealth();
|
||||
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("HP " +
|
||||
FormatTool.format0D(100 * mobileVehicle.getHealth() / mobileVehicle.getMaxHealth())), 30, 1, Mth.hsvToRgb(0F, (float) heal, 1.0F), false);
|
||||
|
||||
poseStack.popPose();
|
||||
poseStack.popPose();
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean shouldRenderCrossHair(Player player) {
|
||||
if (player == null) return false;
|
||||
return !player.isSpectator()
|
||||
&& (player.getVehicle() instanceof SpeedboatEntity || (player.getVehicle() instanceof Yx100Entity yx100 && yx100.getNthEntity(1) == player));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.atsuishio.superbwarfare.client.overlay;
|
||||
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
||||
import com.atsuishio.superbwarfare.tools.FormatTool;
|
||||
import com.atsuishio.superbwarfare.tools.TraceTool;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.client.event.RenderGuiEvent;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class VehicleTeamOverlay {
|
||||
|
||||
@SubscribeEvent
|
||||
public static void eventHandler(RenderGuiEvent.Pre event) {
|
||||
int w = event.getGuiGraphics().guiWidth();
|
||||
int h = event.getGuiGraphics().guiHeight();
|
||||
Player player = Minecraft.getInstance().player;
|
||||
PoseStack poseStack = event.getGuiGraphics().pose();
|
||||
if (player == null) return;
|
||||
|
||||
boolean lookAtEntity = false;
|
||||
|
||||
double entityRange = 0;
|
||||
Entity lookingEntity = TraceTool.findLookingEntity(player, 520);
|
||||
|
||||
if (lookingEntity instanceof VehicleEntity) {
|
||||
lookAtEntity = true;
|
||||
entityRange = player.distanceTo(lookingEntity);
|
||||
}
|
||||
|
||||
if (lookAtEntity) {
|
||||
poseStack.pushPose();
|
||||
poseStack.scale(0.8f, 0.8f, 1);
|
||||
if (lookingEntity.getFirstPassenger() instanceof Player passenger) {
|
||||
event.getGuiGraphics().drawString(Minecraft.getInstance().font,
|
||||
Component.literal(passenger.getDisplayName().getString() + (passenger.getTeam() == null ? "" : " <" + (passenger.getTeam().getName()) + ">")),
|
||||
w / 2 + 90, h / 2 - 4, passenger.getTeamColor(), false);
|
||||
event.getGuiGraphics().drawString(Minecraft.getInstance().font,
|
||||
Component.literal(lookingEntity.getDisplayName().getString() + " " + FormatTool.format1D(entityRange, "m")),
|
||||
w / 2 + 90, h / 2 + 5, passenger.getTeamColor(), false);
|
||||
} else {
|
||||
event.getGuiGraphics().drawString(Minecraft.getInstance().font,
|
||||
Component.literal(lookingEntity.getDisplayName().getString() + " " + FormatTool.format1D(entityRange, "M")),
|
||||
w / 2 + 90, h / 2 + 5, -1, false);
|
||||
}
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
package com.atsuishio.superbwarfare.client.renderer.special;
|
||||
|
||||
import com.atsuishio.superbwarfare.block.ContainerBlock;
|
||||
import com.atsuishio.superbwarfare.block.entity.ContainerBlockEntity;
|
||||
import com.atsuishio.superbwarfare.client.renderer.CustomRenderType;
|
||||
import com.atsuishio.superbwarfare.item.Crowbar;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.level.ClipContext;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.client.event.RenderLevelStageEvent;
|
||||
|
||||
@EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME, value = Dist.CLIENT)
|
||||
public class ContainerBlockPreview {
|
||||
@SubscribeEvent
|
||||
public static void render(RenderLevelStageEvent event) {
|
||||
if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_TRANSLUCENT_BLOCKS) {
|
||||
return;
|
||||
}
|
||||
|
||||
var player = Minecraft.getInstance().player;
|
||||
assert player != null;
|
||||
|
||||
// 仅在手持撬棍时检测
|
||||
var item = player.getMainHandItem();
|
||||
if (!(item.getItem() instanceof Crowbar)) return;
|
||||
|
||||
var level = player.level();
|
||||
var look = player.getLookAngle();
|
||||
|
||||
// 查找玩家看向方块
|
||||
int distance = 32;
|
||||
var start = player.position().add(0, player.getEyeHeight(), 0);
|
||||
var end = player.position().add(look.x * distance, look.y * distance + player.getEyeHeight(), look.z * distance);
|
||||
var context = new ClipContext(start, end, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, player);
|
||||
var result = player.level().clip(context);
|
||||
|
||||
if (result.getType().equals(BlockHitResult.Type.MISS)) return;
|
||||
|
||||
// 获取集装箱
|
||||
var blockEntity = level.getBlockEntity(result.getBlockPos());
|
||||
if (!(blockEntity instanceof ContainerBlockEntity container)) return;
|
||||
|
||||
// 获取实体信息
|
||||
var entityType = container.entityType;
|
||||
var entity = container.entity;
|
||||
|
||||
int w = 0, h = 0;
|
||||
if (entityType != null) {
|
||||
w = (int) (entityType.getDimensions().width() / 2 + 1);
|
||||
h = (int) (entityType.getDimensions().height() + 1);
|
||||
}
|
||||
if (entity != null) {
|
||||
w = (int) (entity.getType().getDimensions().width() / 2 + 1);
|
||||
h = (int) (entity.getType().getDimensions().height() + 1);
|
||||
}
|
||||
if (w == 0 || h == 0) return;
|
||||
|
||||
var poseStack = event.getPoseStack();
|
||||
poseStack.pushPose();
|
||||
var pos = container.getBlockPos();
|
||||
var view = Minecraft.getInstance().gameRenderer.getMainCamera().getPosition();
|
||||
poseStack.translate(pos.getX() - view.x, pos.getY() - view.y + 1, pos.getZ() - view.z);
|
||||
|
||||
// 什么b位置
|
||||
var aabb = new AABB(pos)
|
||||
.inflate(w, 0, w)
|
||||
.expandTowards(0, h - 1, 0)
|
||||
.move(0, -1, 0);
|
||||
|
||||
float startX = (float) aabb.minX - 0.001f - pos.getX();
|
||||
float startY = (float) aabb.minY - 0.001f - pos.getY();
|
||||
float startZ = (float) aabb.minZ - 0.001f - pos.getZ();
|
||||
float endX = (float) aabb.maxX + 0.001f - pos.getX();
|
||||
float endY = (float) aabb.maxY + 0.001f - pos.getY();
|
||||
float endZ = (float) aabb.maxZ + 0.001f - pos.getZ();
|
||||
|
||||
var hasEnoughSpace = ContainerBlock.canOpen(level, pos, entityType, entity);
|
||||
|
||||
var red = hasEnoughSpace ? 0 : 1;
|
||||
var green = 1 - red;
|
||||
var blue = 0.0f;
|
||||
var alpha = 0.2f;
|
||||
|
||||
var builder = Minecraft.getInstance().renderBuffers().bufferSource().getBuffer(CustomRenderType.BLOCK_OVERLAY);
|
||||
var m4f = poseStack.last().pose();
|
||||
|
||||
// east
|
||||
builder.addVertex(m4f, startX, startY, startZ).setColor(red, green, blue, alpha);
|
||||
builder.addVertex(m4f, startX, endY, startZ).setColor(red, green, blue, alpha);
|
||||
builder.addVertex(m4f, endX, endY, startZ).setColor(red, green, blue, alpha);
|
||||
builder.addVertex(m4f, endX, startY, startZ).setColor(red, green, blue, alpha);
|
||||
|
||||
// west
|
||||
builder.addVertex(m4f, startX, startY, endZ).setColor(red, green, blue, alpha);
|
||||
builder.addVertex(m4f, endX, startY, endZ).setColor(red, green, blue, alpha);
|
||||
builder.addVertex(m4f, endX, endY, endZ).setColor(red, green, blue, alpha);
|
||||
builder.addVertex(m4f, startX, endY, endZ).setColor(red, green, blue, alpha);
|
||||
|
||||
// south
|
||||
builder.addVertex(m4f, endX, startY, startZ).setColor(red, green, blue, alpha);
|
||||
builder.addVertex(m4f, endX, endY, startZ).setColor(red, green, blue, alpha);
|
||||
builder.addVertex(m4f, endX, endY, endZ).setColor(red, green, blue, alpha);
|
||||
builder.addVertex(m4f, endX, startY, endZ).setColor(red, green, blue, alpha);
|
||||
|
||||
// north
|
||||
builder.addVertex(m4f, startX, startY, startZ).setColor(red, green, blue, alpha);
|
||||
builder.addVertex(m4f, startX, startY, endZ).setColor(red, green, blue, alpha);
|
||||
builder.addVertex(m4f, startX, endY, endZ).setColor(red, green, blue, alpha);
|
||||
builder.addVertex(m4f, startX, endY, startZ).setColor(red, green, blue, alpha);
|
||||
|
||||
// top
|
||||
builder.addVertex(m4f, startX, endY, startZ).setColor(red, green, blue, alpha);
|
||||
builder.addVertex(m4f, endX, endY, startZ).setColor(red, green, blue, alpha);
|
||||
builder.addVertex(m4f, endX, endY, endZ).setColor(red, green, blue, alpha);
|
||||
builder.addVertex(m4f, startX, endY, endZ).setColor(red, green, blue, alpha);
|
||||
|
||||
// bottom
|
||||
builder.addVertex(m4f, startX, startY, startZ).setColor(red, green, blue, alpha);
|
||||
builder.addVertex(m4f, endX, startY, startZ).setColor(red, green, blue, alpha);
|
||||
builder.addVertex(m4f, endX, startY, endZ).setColor(red, green, blue, alpha);
|
||||
builder.addVertex(m4f, startX, startY, endZ).setColor(red, green, blue, alpha);
|
||||
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
|
@ -3,8 +3,8 @@ package com.atsuishio.superbwarfare.entity.projectile;
|
|||
import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
||||
import com.atsuishio.superbwarfare.init.*;
|
||||
import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.ClientMotionSyncMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientMotionSyncMessage;
|
||||
import com.atsuishio.superbwarfare.tools.ChunkLoadTool;
|
||||
import com.atsuishio.superbwarfare.tools.CustomExplosion;
|
||||
import com.atsuishio.superbwarfare.tools.ParticleTool;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.atsuishio.superbwarfare.entity.projectile;
|
||||
|
||||
import com.atsuishio.superbwarfare.network.message.ClientMotionSyncMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientMotionSyncMessage;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
|
|
|
@ -4,7 +4,7 @@ import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
|||
import com.atsuishio.superbwarfare.init.ModEntities;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.tools.ParticleTool;
|
||||
import com.atsuishio.superbwarfare.tools.ProjectileTool;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
|
|
@ -4,7 +4,7 @@ import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
|
|||
import com.atsuishio.superbwarfare.init.ModEntities;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.tools.ParticleTool;
|
||||
import com.atsuishio.superbwarfare.tools.ProjectileTool;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
|
|
@ -5,7 +5,7 @@ import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
|||
import com.atsuishio.superbwarfare.init.ModEntities;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.tools.CustomExplosion;
|
||||
import com.atsuishio.superbwarfare.tools.ParticleTool;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
|
|
|
@ -6,7 +6,7 @@ import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
|||
import com.atsuishio.superbwarfare.init.ModEntities;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.tools.*;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
|
|
|
@ -8,9 +8,9 @@ import com.atsuishio.superbwarfare.entity.ICustomKnockback;
|
|||
import com.atsuishio.superbwarfare.entity.TargetEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
||||
import com.atsuishio.superbwarfare.init.*;
|
||||
import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.ClientMotionSyncMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.PlayerGunKillMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientMotionSyncMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.PlayerGunKillMessage;
|
||||
import com.atsuishio.superbwarfare.tools.*;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
|
|
@ -5,7 +5,7 @@ import com.atsuishio.superbwarfare.entity.vehicle.DroneEntity;
|
|||
import com.atsuishio.superbwarfare.init.ModEntities;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.tools.ParticleTool;
|
||||
import com.atsuishio.superbwarfare.tools.ProjectileTool;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
|
|
@ -5,7 +5,7 @@ import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
|||
import com.atsuishio.superbwarfare.init.ModEntities;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.tools.ParticleTool;
|
||||
import com.atsuishio.superbwarfare.tools.ProjectileTool;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
|
|
@ -5,7 +5,7 @@ import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
|||
import com.atsuishio.superbwarfare.init.ModEntities;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.tools.CustomExplosion;
|
||||
import com.atsuishio.superbwarfare.tools.ParticleTool;
|
||||
import com.atsuishio.superbwarfare.tools.ProjectileTool;
|
||||
|
|
|
@ -4,7 +4,7 @@ import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
|||
import com.atsuishio.superbwarfare.init.ModEntities;
|
||||
import com.atsuishio.superbwarfare.init.ModMobEffects;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
|
|
@ -6,7 +6,7 @@ import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
|||
import com.atsuishio.superbwarfare.init.ModEntities;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.tools.CustomExplosion;
|
||||
import com.atsuishio.superbwarfare.tools.ParticleTool;
|
||||
import com.atsuishio.superbwarfare.tools.VectorTool;
|
||||
|
|
|
@ -16,7 +16,7 @@ import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
|||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.init.ModTags;
|
||||
import com.atsuishio.superbwarfare.network.message.ShakeClientMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ShakeClientMessage;
|
||||
import com.atsuishio.superbwarfare.tools.AmmoType;
|
||||
import com.atsuishio.superbwarfare.tools.CustomExplosion;
|
||||
import com.atsuishio.superbwarfare.tools.InventoryTool;
|
||||
|
|
|
@ -15,7 +15,7 @@ import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
|||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.init.ModTags;
|
||||
import com.atsuishio.superbwarfare.network.message.ShakeClientMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ShakeClientMessage;
|
||||
import com.atsuishio.superbwarfare.tools.*;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
|
|
@ -18,7 +18,7 @@ import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
|||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.init.ModTags;
|
||||
import com.atsuishio.superbwarfare.network.message.ShakeClientMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ShakeClientMessage;
|
||||
import com.atsuishio.superbwarfare.tools.AmmoType;
|
||||
import com.atsuishio.superbwarfare.tools.CustomExplosion;
|
||||
import com.atsuishio.superbwarfare.tools.InventoryTool;
|
||||
|
|
|
@ -17,7 +17,7 @@ import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
|||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.init.ModTags;
|
||||
import com.atsuishio.superbwarfare.network.message.ShakeClientMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ShakeClientMessage;
|
||||
import com.atsuishio.superbwarfare.tools.AmmoType;
|
||||
import com.atsuishio.superbwarfare.tools.CustomExplosion;
|
||||
import com.atsuishio.superbwarfare.tools.InventoryTool;
|
||||
|
|
|
@ -14,7 +14,7 @@ import com.atsuishio.superbwarfare.init.ModItems;
|
|||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.init.ModTags;
|
||||
import com.atsuishio.superbwarfare.item.common.ammo.CannonShellItem;
|
||||
import com.atsuishio.superbwarfare.network.message.ShakeClientMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ShakeClientMessage;
|
||||
import com.atsuishio.superbwarfare.tools.*;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
|
|
@ -14,7 +14,7 @@ import com.atsuishio.superbwarfare.init.ModItems;
|
|||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.init.ModTags;
|
||||
import com.atsuishio.superbwarfare.item.common.ammo.CannonShellItem;
|
||||
import com.atsuishio.superbwarfare.network.message.ShakeClientMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ShakeClientMessage;
|
||||
import com.atsuishio.superbwarfare.tools.*;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
|
|
@ -11,7 +11,7 @@ import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
|||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.init.ModTags;
|
||||
import com.atsuishio.superbwarfare.network.message.ShakeClientMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ShakeClientMessage;
|
||||
import com.atsuishio.superbwarfare.tools.AmmoType;
|
||||
import com.atsuishio.superbwarfare.tools.CustomExplosion;
|
||||
import com.atsuishio.superbwarfare.tools.InventoryTool;
|
||||
|
|
|
@ -19,7 +19,7 @@ import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
|||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.init.ModTags;
|
||||
import com.atsuishio.superbwarfare.network.message.ShakeClientMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ShakeClientMessage;
|
||||
import com.atsuishio.superbwarfare.tools.*;
|
||||
import com.mojang.math.Axis;
|
||||
import net.minecraft.ChatFormatting;
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package com.atsuishio.superbwarfare.entity.vehicle.base;
|
||||
|
||||
public interface ControllableVehicle {
|
||||
void processInput(short keys);
|
||||
}
|
|
@ -40,7 +40,7 @@ import org.joml.Matrix4f;
|
|||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4f;
|
||||
|
||||
public abstract class MobileVehicleEntity extends EnergyVehicleEntity {
|
||||
public abstract class MobileVehicleEntity extends EnergyVehicleEntity implements ControllableVehicle {
|
||||
public static final EntityDataAccessor<Integer> CANNON_RECOIL_TIME = SynchedEntityData.defineId(MobileVehicleEntity.class, EntityDataSerializers.INT);
|
||||
|
||||
public static final EntityDataAccessor<Float> POWER = SynchedEntityData.defineId(MobileVehicleEntity.class, EntityDataSerializers.FLOAT);
|
||||
|
@ -108,6 +108,24 @@ public abstract class MobileVehicleEntity extends EnergyVehicleEntity {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processInput(short keys) {
|
||||
leftInputDown
|
||||
= (keys & 0b0000001) > 0;
|
||||
rightInputDown
|
||||
= (keys & 0b0000010) > 0;
|
||||
forwardInputDown
|
||||
= (keys & 0b0000100) > 0;
|
||||
backInputDown
|
||||
= (keys & 0b0001000) > 0;
|
||||
upInputDown
|
||||
= (keys & 0b0010000) > 0;
|
||||
downInputDown
|
||||
= (keys & 0b0100000) > 0;
|
||||
decoyInputDown
|
||||
= (keys & 0b1000000) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void baseTick() {
|
||||
turretYRotO = this.getTurretYRot();
|
||||
|
|
|
@ -6,7 +6,7 @@ import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier;
|
|||
import com.atsuishio.superbwarfare.entity.vehicle.weapon.VehicleWeapon;
|
||||
import com.atsuishio.superbwarfare.init.*;
|
||||
import com.atsuishio.superbwarfare.item.ContainerBlockItem;
|
||||
import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.tools.EntityFindUtil;
|
||||
import com.atsuishio.superbwarfare.tools.ParticleTool;
|
||||
import com.atsuishio.superbwarfare.tools.VectorTool;
|
||||
|
|
|
@ -2,11 +2,18 @@ package com.atsuishio.superbwarfare.event;
|
|||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||
import com.atsuishio.superbwarfare.client.ClickHandler;
|
||||
import com.atsuishio.superbwarfare.config.client.DisplayConfig;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.*;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.WeaponVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.init.*;
|
||||
import com.atsuishio.superbwarfare.item.gun.GunItem;
|
||||
import com.atsuishio.superbwarfare.network.message.LaserShootMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.ShootMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.send.LaserShootMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.send.ShootMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.send.VehicleMovementMessage;
|
||||
import com.atsuishio.superbwarfare.tools.*;
|
||||
import com.atsuishio.superbwarfare.tools.animation.AnimationCurves;
|
||||
import net.minecraft.client.CameraType;
|
||||
|
@ -15,6 +22,8 @@ import net.minecraft.client.multiplayer.ClientLevel;
|
|||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.commands.arguments.EntityAnchorArgument;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.RandomSource;
|
||||
|
@ -27,11 +36,18 @@ import net.minecraft.world.entity.player.Player;
|
|||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.ClipContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.BellBlock;
|
||||
import net.minecraft.world.level.block.CrossCollisionBlock;
|
||||
import net.minecraft.world.level.block.DoorBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
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.capabilities.Capabilities;
|
||||
import net.neoforged.neoforge.client.event.*;
|
||||
import net.neoforged.neoforge.client.gui.VanillaGuiLayers;
|
||||
import net.neoforged.neoforge.network.PacketDistributor;
|
||||
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
@ -39,6 +55,9 @@ import software.bernie.geckolib.cache.object.GeoBone;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity.COAX_HEAT;
|
||||
import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity.HEAT;
|
||||
|
||||
@EventBusSubscriber(modid = ModUtils.MODID, bus = EventBusSubscriber.Bus.GAME, value = Dist.CLIENT)
|
||||
public class ClientEventHandler {
|
||||
|
||||
|
@ -162,9 +181,7 @@ public class ClientEventHandler {
|
|||
}
|
||||
|
||||
public static boolean isFreeCam(Player player) {
|
||||
// TODO Vehicle
|
||||
// return player.getVehicle() instanceof VehicleEntity vehicle && vehicle.allowFreeCam() && Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON && ModKeyMappings.FREE_CAMERA.isDown();
|
||||
return Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON && ModKeyMappings.FREE_CAMERA.isDown();
|
||||
return player.getVehicle() instanceof VehicleEntity vehicle && vehicle.allowFreeCam() && Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON && ModKeyMappings.FREE_CAMERA.isDown();
|
||||
}
|
||||
|
||||
private static boolean revolverPre() {
|
||||
|
@ -189,39 +206,69 @@ public class ClientEventHandler {
|
|||
|| (player != null && player.isSprinting());
|
||||
}
|
||||
|
||||
static short keysCache = 0;
|
||||
|
||||
@SubscribeEvent
|
||||
public static void handleClientTick(ClientTickEvent.Post event) {
|
||||
public static void handleClientTick(ClientTickEvent.Pre event) {
|
||||
LocalPlayer player = Minecraft.getInstance().player;
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
// if (stack.is(ModItems.MINIGUN.get())) {
|
||||
// if (holdFire || zoom) {
|
||||
// miniGunRot = Math.min(miniGunRot + 5, 21);
|
||||
// float rpm = (float) GunsTool.getGunIntTag(stack, "RPM", 0) / 3600;
|
||||
// player.playSound(ModSounds.MINIGUN_ROT.get(), 1, 0.7f + rpm);
|
||||
// }
|
||||
// }
|
||||
if (stack.is(ModItems.MINIGUN.get())) {
|
||||
if (holdFire || zoom) {
|
||||
miniGunRot = Math.min(miniGunRot + 5, 21);
|
||||
float rpm = (float) GunsTool.getGunIntTag(stack, "RPM", 0) / 3600;
|
||||
player.playSound(ModSounds.MINIGUN_ROT.get(), 1, 0.7f + rpm);
|
||||
}
|
||||
}
|
||||
|
||||
// if (notInGame() && !ClickHandler.switchZoom) {
|
||||
// zoom = false;
|
||||
// }
|
||||
if (notInGame() && !ClickHandler.switchZoom) {
|
||||
zoom = false;
|
||||
}
|
||||
|
||||
isProne(player);
|
||||
beamShoot(player, stack);
|
||||
handleLungeAttack(player, stack);
|
||||
handleGunMelee(player, stack);
|
||||
|
||||
// if (player.getVehicle() instanceof MobileVehicleEntity mobileVehicle && mobileVehicle.getFirstPassenger() == player && notInGame()) {
|
||||
// ModUtils.PACKET_HANDLER.sendToServer(new VehicleMovementMessage(0, false));
|
||||
// ModUtils.PACKET_HANDLER.sendToServer(new VehicleMovementMessage(1, false));
|
||||
// ModUtils.PACKET_HANDLER.sendToServer(new VehicleMovementMessage(2, false));
|
||||
// ModUtils.PACKET_HANDLER.sendToServer(new VehicleMovementMessage(3, false));
|
||||
// ModUtils.PACKET_HANDLER.sendToServer(new VehicleMovementMessage(4, false));
|
||||
// ModUtils.PACKET_HANDLER.sendToServer(new VehicleMovementMessage(5, false));
|
||||
// ModUtils.PACKET_HANDLER.sendToServer(new VehicleMovementMessage(6, false));
|
||||
// }
|
||||
var options = Minecraft.getInstance().options;
|
||||
short keys = 0;
|
||||
|
||||
// 正在游戏内控制载具或无人机
|
||||
if (!notInGame() && (player.getVehicle() instanceof MobileVehicleEntity mobileVehicle
|
||||
&& mobileVehicle.getFirstPassenger() == player
|
||||
|| stack.is(ModItems.MONITOR.get())
|
||||
&& NBTTool.getBoolean(stack, "Using", false)
|
||||
&& NBTTool.getBoolean(stack, "Linked", false))
|
||||
) {
|
||||
if (options.keyLeft.isDown()) {
|
||||
keys |= 0b0000001;
|
||||
}
|
||||
if (options.keyRight.isDown()) {
|
||||
keys |= 0b0000010;
|
||||
}
|
||||
if (options.keyUp.isDown()) {
|
||||
keys |= 0b0000100;
|
||||
}
|
||||
if (options.keyDown.isDown()) {
|
||||
keys |= 0b0001000;
|
||||
}
|
||||
if (options.keyJump.isDown()) {
|
||||
keys |= 0b0010000;
|
||||
}
|
||||
if (options.keyShift.isDown()) {
|
||||
keys |= 0b0100000;
|
||||
}
|
||||
if (ModKeyMappings.RELEASE_DECOY.isDown()) {
|
||||
keys |= 0b1000000;
|
||||
}
|
||||
}
|
||||
|
||||
if (keys != keysCache) {
|
||||
PacketDistributor.sendToServer(new VehicleMovementMessage(keys));
|
||||
keysCache = keys;
|
||||
}
|
||||
|
||||
handleVariableDecrease();
|
||||
aimAtVillager(player);
|
||||
|
@ -251,12 +298,13 @@ public class ClientEventHandler {
|
|||
|
||||
public static void handleGunMelee(Player player, ItemStack stack) {
|
||||
if (stack.getItem() instanceof GunItem gunItem) {
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (gunItem.hasMeleeAttack(stack) && gunMelee == 0 && drawTime < 0.01
|
||||
&& ModKeyMappings.MELEE.isDown()
|
||||
// && !(player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.banHand(player))
|
||||
&& !(player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.banHand(player))
|
||||
&& !holdFireVehicle
|
||||
&& !notInGame()
|
||||
// && !cap != null && cap.edit
|
||||
&& cap != null && !cap.edit
|
||||
&& !(NBTTool.getTag(stack).getBoolean("is_normal_reloading") || NBTTool.getTag(stack).getBoolean("is_empty_reloading"))
|
||||
&& !GunsTool.getGunBooleanTag(stack, "Reloading")
|
||||
&& !player.getCooldowns().isOnCooldown(stack.getItem())
|
||||
|
@ -266,10 +314,12 @@ public class ClientEventHandler {
|
|||
player.playSound(SoundEvents.PLAYER_ATTACK_SWEEP, 1f, 1);
|
||||
}
|
||||
if (gunMelee == 22) {
|
||||
// Entity lookingEntity = TraceTool.findMeleeEntity(player, player.getEntityReach());
|
||||
// if (lookingEntity != null) {
|
||||
Entity lookingEntity = TraceTool.findMeleeEntity(player, player.entityInteractionRange());
|
||||
if (lookingEntity != null) {
|
||||
|
||||
// TODO melee attack msg
|
||||
// ModUtils.PACKET_HANDLER.sendToServer(new MeleeAttackMessage(lookingEntity.getUUID()));
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,33 +329,34 @@ public class ClientEventHandler {
|
|||
}
|
||||
|
||||
public static void handleLungeAttack(Player player, ItemStack stack) {
|
||||
// if (stack.is(ModItems.LUNGE_MINE.get()) && lungeAttack == 0 && lungeDraw == 0 && holdFire) {
|
||||
// lungeAttack = 36;
|
||||
// holdFire = false;
|
||||
// player.playSound(SoundEvents.PLAYER_ATTACK_SWEEP, 1f, 1);
|
||||
// }
|
||||
//
|
||||
// if (stack.is(ModItems.LUNGE_MINE.get()) && ((lungeAttack >= 18 && lungeAttack <= 21) || lungeSprint > 0)) {
|
||||
// Entity lookingEntity = TraceTool.findLookingEntity(player, player.getEntityReach() + 1.5);
|
||||
//
|
||||
// BlockHitResult result = player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(player.getLookAngle().scale(player.getBlockReach() + 0.5)),
|
||||
// ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player));
|
||||
//
|
||||
// Vec3 looking = Vec3.atLowerCornerOf(player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(player.getLookAngle().scale(player.getBlockReach() + 0.5)), ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)).getBlockPos());
|
||||
// BlockState blockState = player.level().getBlockState(BlockPos.containing(looking.x(), looking.y(), looking.z()));
|
||||
//
|
||||
// if (lookingEntity != null) {
|
||||
if (stack.is(ModItems.LUNGE_MINE.get()) && lungeAttack == 0 && lungeDraw == 0 && holdFire) {
|
||||
lungeAttack = 36;
|
||||
holdFire = false;
|
||||
player.playSound(SoundEvents.PLAYER_ATTACK_SWEEP, 1f, 1);
|
||||
}
|
||||
|
||||
if (stack.is(ModItems.LUNGE_MINE.get()) && ((lungeAttack >= 18 && lungeAttack <= 21) || lungeSprint > 0)) {
|
||||
Entity lookingEntity = TraceTool.findLookingEntity(player, player.entityInteractionRange() + 1.5);
|
||||
|
||||
BlockHitResult result = player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(player.getLookAngle().scale(player.getBlockReach() + 0.5)),
|
||||
ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player));
|
||||
|
||||
Vec3 looking = Vec3.atLowerCornerOf(player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(player.getLookAngle().scale(player.getBlockReach() + 0.5)), ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)).getBlockPos());
|
||||
BlockState blockState = player.level().getBlockState(BlockPos.containing(looking.x(), looking.y(), looking.z()));
|
||||
|
||||
if (lookingEntity != null) {
|
||||
// TODO lunge mine attack msg
|
||||
// ModUtils.PACKET_HANDLER.sendToServer(new LungeMineAttackMessage(0, lookingEntity.getUUID(), result));
|
||||
// lungeSprint = 0;
|
||||
// lungeAttack = 0;
|
||||
// lungeDraw = 30;
|
||||
// } else if ((blockState.canOcclude() || blockState.getBlock() instanceof DoorBlock || blockState.getBlock() instanceof CrossCollisionBlock || blockState.getBlock() instanceof BellBlock) && lungeSprint == 0) {
|
||||
lungeSprint = 0;
|
||||
lungeAttack = 0;
|
||||
lungeDraw = 30;
|
||||
} else if ((blockState.canOcclude() || blockState.getBlock() instanceof DoorBlock || blockState.getBlock() instanceof CrossCollisionBlock || blockState.getBlock() instanceof BellBlock) && lungeSprint == 0) {
|
||||
// ModUtils.PACKET_HANDLER.sendToServer(new LungeMineAttackMessage(1, player.getUUID(), result));
|
||||
// lungeSprint = 0;
|
||||
// lungeAttack = 0;
|
||||
// lungeDraw = 30;
|
||||
// }
|
||||
// }
|
||||
lungeSprint = 0;
|
||||
lungeAttack = 0;
|
||||
lungeDraw = 30;
|
||||
}
|
||||
}
|
||||
|
||||
if (lungeSprint > 0) {
|
||||
lungeSprint--;
|
||||
|
@ -340,6 +391,7 @@ public class ClientEventHandler {
|
|||
return;
|
||||
}
|
||||
|
||||
// TODO perk
|
||||
// var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO);
|
||||
int mode = GunsTool.getGunIntTag(stack, "FireMode");
|
||||
|
||||
|
@ -366,13 +418,15 @@ public class ClientEventHandler {
|
|||
// }
|
||||
// } else if (stack.is(ModItems.MINIGUN.get())) {
|
||||
// zoomSpread = 1 - (0.25 * zoomTime);
|
||||
zoomSpread = 1 - (0.9 * zoomTime);
|
||||
// TODO perk
|
||||
} else {
|
||||
zoomSpread = 1 - (0.9 * zoomTime);
|
||||
}
|
||||
|
||||
// double spread = stack.is(ModTags.Items.SHOTGUN) || stack.is(ModItems.MINIGUN.get()) ? 1.2 * zoomSpread * (basicDev + 0.2 * (walk + sprint + crouching + prone + jump + ride) + fireSpread) : zoomSpread * (0.7 * basicDev + walk + sprint + crouching + prone + jump + ride + 0.8 * fireSpread);
|
||||
double spread = stack.is(ModTags.Items.SHOTGUN) || stack.is(ModItems.MINIGUN.get()) ? 1.2 * zoomSpread * (basicDev + 0.2 * (walk + sprint + crouching + prone + jump + ride) + fireSpread) : zoomSpread * (0.7 * basicDev + walk + sprint + crouching + prone + jump + ride + 0.8 * fireSpread);
|
||||
|
||||
// gunSpread = Mth.lerp(0.14 * times, gunSpread, spread);
|
||||
gunSpread = Mth.lerp(0.14 * times, gunSpread, spread);
|
||||
|
||||
// 开火部分
|
||||
double weight = GunsTool.getGunDoubleTag(stack, "Weight") + GunsTool.getGunDoubleTag(stack, "CustomWeight");
|
||||
|
@ -390,6 +444,7 @@ public class ClientEventHandler {
|
|||
}
|
||||
|
||||
if (GunsTool.getPerkIntTag(stack, "DesperadoTimePost") > 0) {
|
||||
// TODO perk
|
||||
// int perkLevel = PerkHelper.getItemPerkLevel(ModPerks.DESPERADO.get(), stack);
|
||||
// rpm *= (int) (1.285 + 0.015 * perkLevel);
|
||||
}
|
||||
|
@ -411,8 +466,7 @@ public class ClientEventHandler {
|
|||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
|
||||
if ((holdFire || burstFireSize > 0)
|
||||
// todo ban hand
|
||||
// && !(player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.banHand(player))
|
||||
&& !(player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.banHand(player))
|
||||
&& !holdFireVehicle
|
||||
&& (stack.is(ModTags.Items.NORMAL_GUN)
|
||||
&& cantFireTime == 0
|
||||
|
@ -426,10 +480,8 @@ public class ClientEventHandler {
|
|||
&& !player.getCooldowns().isOnCooldown(stack.getItem())
|
||||
&& !GunsTool.getGunBooleanTag(stack, "NeedBoltAction", false)
|
||||
&& revolverPre())
|
||||
|| (
|
||||
// todo minigun
|
||||
// stack.is(ModItems.MINIGUN.get()) &&
|
||||
!player.isSprinting()
|
||||
|| (stack.is(ModItems.MINIGUN.get())
|
||||
&& !player.isSprinting()
|
||||
&& NBTTool.getTag(stack).getDouble("overheat") == 0
|
||||
&& !player.getCooldowns().isOnCooldown(stack.getItem()) && miniGunRot >= 20
|
||||
&& (cap != null && cap.rifleAmmo > 0 || InventoryTool.hasCreativeAmmoBox(player))
|
||||
|
@ -469,14 +521,15 @@ public class ClientEventHandler {
|
|||
clientTimer.stop();
|
||||
}
|
||||
|
||||
// if (stack.getItem() == ModItems.DEVOTION.get() && (GunNBTTool.getOrCreateTag(stack).getBoolean("is_normal_reloading") || GunNBTTool.getOrCreateTag(stack).getBoolean("is_empty_reloading"))) {
|
||||
// customRpm = 0;
|
||||
// }
|
||||
if (stack.getItem() == ModItems.DEVOTION.get() && (NBTTool.getTag(stack).getBoolean("is_normal_reloading") || NBTTool.getTag(stack).getBoolean("is_empty_reloading"))) {
|
||||
customRpm = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static void beamShoot(Player player, ItemStack stack) {
|
||||
if (stack.is(ModItems.BEAM_TEST.get()) && player.getUseItem() == stack) {
|
||||
Entity lookingEntity = TraceTool.laserfindLookingEntity(player, 512);
|
||||
if (lookingEntity == null) return;
|
||||
|
||||
if (player.isCrouching()) {
|
||||
Entity seekingEntity = SeekTool.seekLivingEntity(player, player.level(), 64, 32);
|
||||
|
@ -485,10 +538,6 @@ public class ClientEventHandler {
|
|||
}
|
||||
}
|
||||
|
||||
if (lookingEntity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean canAttack = lookingEntity != player && !(lookingEntity instanceof Player player_ && (player_.isCreative() || player_.isSpectator()))
|
||||
&& (!player.isAlliedTo(lookingEntity) || lookingEntity.getTeam() == null || lookingEntity.getTeam().getName().equals("TDM"));
|
||||
|
||||
|
@ -520,18 +569,19 @@ public class ClientEventHandler {
|
|||
burstFireSize--;
|
||||
}
|
||||
|
||||
// if (stack.is(ModItems.DEVOTION.get())) {
|
||||
if (stack.is(ModItems.DEVOTION.get())) {
|
||||
// TODO perk
|
||||
// int perkLevel = PerkHelper.getItemPerkLevel(ModPerks.TURBO_CHARGER.get(), stack);
|
||||
// customRpm = Math.min(customRpm + 15 + ((perkLevel > 0 ? 5 : 0) + 3 * perkLevel), 500);
|
||||
// }
|
||||
}
|
||||
|
||||
// if (stack.getItem() == ModItems.SENTINEL.get()) {
|
||||
// chamberRot = 1;
|
||||
// }
|
||||
//
|
||||
// if (stack.getItem() == ModItems.NTW_20.get()) {
|
||||
// actionMove = 1;
|
||||
// }
|
||||
if (stack.getItem() == ModItems.SENTINEL.get()) {
|
||||
chamberRot = 1;
|
||||
}
|
||||
|
||||
if (stack.getItem() == ModItems.NTW_20.get()) {
|
||||
actionMove = 1;
|
||||
}
|
||||
|
||||
// 判断是否为栓动武器(BoltActionTime > 0),并在开火后给一个需要上膛的状态
|
||||
if (GunsTool.getGunIntTag(stack, "BoltActionTime", 0) > 0 && GunsTool.getGunIntTag(stack, "Ammo", 0) > (stack.is(ModTags.Items.REVOLVER) ? 0 : 1)) {
|
||||
|
@ -544,28 +594,28 @@ public class ClientEventHandler {
|
|||
playGunClientSounds(player);
|
||||
handleClientShoot();
|
||||
}
|
||||
// } else if (stack.is(ModItems.MINIGUN.get())) {
|
||||
// var tag = GunNBTTool.getOrCreateTag(stack);
|
||||
//
|
||||
// if ((player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables())).rifleAmmo > 0
|
||||
// || InventoryTool.hasCreativeAmmoBox(player)) {
|
||||
//
|
||||
} else if (stack.is(ModItems.MINIGUN.get())) {
|
||||
var tag = NBTTool.getTag(stack);
|
||||
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap != null && cap.rifleAmmo > 0 || InventoryTool.hasCreativeAmmoBox(player)) {
|
||||
// TODO perk
|
||||
// var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO);
|
||||
// float pitch = tag.getDouble("heat") <= 40 ? 1 : (float) (1 - 0.025 * Math.abs(40 - tag.getDouble("heat")));
|
||||
//
|
||||
// player.playSound(ModSounds.MINIGUN_FIRE_1P.get(), 1f, pitch);
|
||||
//
|
||||
float pitch = tag.getDouble("heat") <= 40 ? 1 : (float) (1 - 0.025 * Math.abs(40 - tag.getDouble("heat")));
|
||||
|
||||
player.playSound(ModSounds.MINIGUN_FIRE_1P.get(), 1f, pitch);
|
||||
|
||||
// if (perk == ModPerks.BEAST_BULLET.get()) {
|
||||
// player.playSound(ModSounds.HENG.get(), 1f, 1f);
|
||||
// }
|
||||
//
|
||||
// double shooterHeight = player.getEyePosition().distanceTo((Vec3.atLowerCornerOf(player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(new Vec3(0, -1, 0).scale(10)),
|
||||
// ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)).getBlockPos())));
|
||||
//
|
||||
// ModUtils.queueClientWork((int) (1 + 1.5 * shooterHeight), () -> player.playSound(ModSounds.SHELL_CASING_NORMAL.get(), (float) Math.max(1.5 - 0.2 * shooterHeight, 0), 1));
|
||||
// }
|
||||
//
|
||||
// handleClientShoot();
|
||||
|
||||
double shooterHeight = player.getEyePosition().distanceTo((Vec3.atLowerCornerOf(player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(new Vec3(0, -1, 0).scale(10)),
|
||||
ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)).getBlockPos())));
|
||||
|
||||
ModUtils.queueClientWork((int) (1 + 1.5 * shooterHeight), () -> player.playSound(ModSounds.SHELL_CASING_NORMAL.get(), (float) Math.max(1.5 - 0.2 * shooterHeight, 0), 1));
|
||||
}
|
||||
|
||||
handleClientShoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -599,17 +649,15 @@ public class ClientEventHandler {
|
|||
}
|
||||
|
||||
public static void handleShakeClient(double time, double radius, double amplitude, double x, double y, double z, final IPayloadContext context) {
|
||||
// if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) {
|
||||
// Player player = Minecraft.getInstance().player;
|
||||
// if (player == null) return;
|
||||
// shakeTime = time;
|
||||
// shakeRadius = radius;
|
||||
// shakeAmplitude = amplitude * Mth.DEG_TO_RAD;
|
||||
// shakePos[0] = x;
|
||||
// shakePos[1] = y;
|
||||
// shakePos[2] = z;
|
||||
// shakeType = 2 * (Math.random() - 0.5);
|
||||
// }
|
||||
Player player = Minecraft.getInstance().player;
|
||||
if (player == null) return;
|
||||
shakeTime = time;
|
||||
shakeRadius = radius;
|
||||
shakeAmplitude = amplitude * Mth.DEG_TO_RAD;
|
||||
shakePos[0] = x;
|
||||
shakePos[1] = y;
|
||||
shakePos[2] = z;
|
||||
shakeType = 2 * (Math.random() - 0.5);
|
||||
}
|
||||
|
||||
public static void playGunClientSounds(Player player) {
|
||||
|
@ -621,35 +669,33 @@ public class ClientEventHandler {
|
|||
String origin = stack.getItem().getDescriptionId();
|
||||
String name = origin.substring(origin.lastIndexOf(".") + 1);
|
||||
|
||||
// if (stack.getItem() == ModItems.SENTINEL.get()) {
|
||||
// AtomicBoolean charged = new AtomicBoolean(false);
|
||||
//
|
||||
// stack.getCapability(ForgeCapabilities.ENERGY).ifPresent(
|
||||
// e -> charged.set(e.getEnergyStored() > 0)
|
||||
// );
|
||||
//
|
||||
// if (charged.get()) {
|
||||
// SoundEvent sound1p = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc( "sentinel_charge_fire_1p"));
|
||||
// if (sound1p != null) {
|
||||
// player.playSound(sound1p, 2f, 1);
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
if (stack.getItem() == ModItems.SENTINEL.get()) {
|
||||
var cap = stack.getCapability(Capabilities.EnergyStorage.ITEM);
|
||||
var charged = cap != null && cap.getEnergyStored() > 0;
|
||||
|
||||
if (charged) {
|
||||
SoundEvent sound1p = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc("sentinel_charge_fire_1p"));
|
||||
if (sound1p != null) {
|
||||
player.playSound(sound1p, 2f, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO perk
|
||||
// var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO);
|
||||
//
|
||||
|
||||
// if (perk == ModPerks.BEAST_BULLET.get()) {
|
||||
// player.playSound(ModSounds.HENG.get(), 1f, 1f);
|
||||
// }
|
||||
|
||||
int barrelType = GunsTool.getAttachmentType(stack, GunsTool.AttachmentType.BARREL);
|
||||
|
||||
// SoundEvent sound1p = ForgeRegistries.SOUND_EVENTS.getValue(ModUtils.loc(name + (barrelType == 2 ? "_fire_1p_s" : "_fire_1p")));
|
||||
SoundEvent sound1p = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc(name + (barrelType == 2 ? "_fire_1p_s" : "_fire_1p")));
|
||||
|
||||
// if (sound1p != null) {
|
||||
// player.playSound(sound1p, 2f, 1);
|
||||
// }
|
||||
if (sound1p != null) {
|
||||
player.playSound(sound1p, 2f, 1);
|
||||
}
|
||||
|
||||
double shooterHeight = player.getEyePosition().distanceTo((Vec3.atLowerCornerOf(player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(new Vec3(0, -1, 0).scale(10)),
|
||||
ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)).getBlockPos())));
|
||||
|
@ -680,83 +726,85 @@ public class ClientEventHandler {
|
|||
holdFireVehicle = false;
|
||||
}
|
||||
|
||||
// if (player.getVehicle() instanceof VehicleEntity pVehicle && player.getVehicle() instanceof WeaponVehicleEntity iVehicle && iVehicle.hasWeapon(pVehicle.getSeatIndex(player)) && iVehicle.canShoot(player)) {
|
||||
// int rpm = iVehicle.mainGunRpm(player);
|
||||
// if (rpm == 0) {
|
||||
// rpm = 240;
|
||||
// }
|
||||
//
|
||||
// double rps = (double) rpm / 60;
|
||||
// int cooldown = (int) (1000 / rps);
|
||||
//
|
||||
// if ((holdFireVehicle)) {
|
||||
// if (!clientTimerVehicle.started()) {
|
||||
// clientTimerVehicle.start();
|
||||
// // 首发瞬间发射
|
||||
// clientTimerVehicle.setProgress((cooldown + 1));
|
||||
// }
|
||||
//
|
||||
// if (clientTimerVehicle.getProgress() >= cooldown) {
|
||||
// ModUtils.PACKET_HANDLER.sendToServer(new VehicleFireMessage(pVehicle.getSeatIndex(player)));
|
||||
// playVehicleClientSounds(player, iVehicle, pVehicle.getSeatIndex(player));
|
||||
// clientTimerVehicle.setProgress((clientTimerVehicle.getProgress() - cooldown));
|
||||
// }
|
||||
// } else if (clientTimerVehicle.getProgress() >= cooldown) {
|
||||
// clientTimerVehicle.stop();
|
||||
// }
|
||||
// } else {
|
||||
// clientTimerVehicle.stop();
|
||||
// }
|
||||
if (player.getVehicle() instanceof VehicleEntity pVehicle && player.getVehicle() instanceof WeaponVehicleEntity iVehicle && iVehicle.hasWeapon(pVehicle.getSeatIndex(player)) && iVehicle.canShoot(player)) {
|
||||
int rpm = iVehicle.mainGunRpm(player);
|
||||
if (rpm == 0) {
|
||||
rpm = 240;
|
||||
}
|
||||
|
||||
// public static void playVehicleClientSounds(Player player, WeaponVehicleEntity iVehicle, int type) {
|
||||
// if (iVehicle instanceof SpeedboatEntity speedboat) {
|
||||
// float pitch = speedboat.getEntityData().get(HEAT) <= 60 ? 1 : (float) (1 - 0.011 * Math.abs(60 - speedboat.getEntityData().get(HEAT)));
|
||||
// player.playSound(ModSounds.M_2_FIRE_1P.get(), 1f, pitch);
|
||||
// player.playSound(ModSounds.SHELL_CASING_50CAL.get(), 0.3f, 1);
|
||||
// }
|
||||
//
|
||||
// if (iVehicle instanceof Ah6Entity ah6Entity) {
|
||||
// float pitch = ah6Entity.getEntityData().get(HEAT) <= 60 ? 1 : (float) (1 - 0.011 * Math.abs(60 - ah6Entity.getEntityData().get(HEAT)));
|
||||
// if (ah6Entity.getWeaponIndex(0) == 0) {
|
||||
// player.playSound(ModSounds.HELICOPTER_CANNON_FIRE_1P.get(), 1f, pitch);
|
||||
// } else if (ah6Entity.getWeaponIndex(0) == 1) {
|
||||
// player.playSound(ModSounds.HELICOPTER_ROCKET_FIRE_1P.get(), 1f, 1);
|
||||
// }
|
||||
// }
|
||||
// if (iVehicle instanceof Lav150Entity lav150) {
|
||||
// if (lav150.getWeaponIndex(0) == 0) {
|
||||
// float pitch = lav150.getEntityData().get(HEAT) <= 60 ? 1 : (float) (1 - 0.011 * Math.abs(60 - lav150.getEntityData().get(HEAT)));
|
||||
// player.playSound(ModSounds.LAV_CANNON_FIRE_1P.get(), 1f, pitch);
|
||||
// player.playSound(ModSounds.SHELL_CASING_50CAL.get(), 0.3f, 1);
|
||||
// } else if (lav150.getWeaponIndex(0) == 1) {
|
||||
// float pitch = lav150.getEntityData().get(COAX_HEAT) <= 60 ? 1 : (float) (1 - 0.011 * Math.abs(60 - lav150.getEntityData().get(COAX_HEAT)));
|
||||
// player.playSound(ModSounds.COAX_FIRE_1P.get(), 1f, pitch);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// if (iVehicle instanceof Bmp2Entity bmp2) {
|
||||
// if (bmp2.getWeaponIndex(0) == 0) {
|
||||
// float pitch = bmp2.getEntityData().get(HEAT) <= 60 ? 1 : (float) (1 - 0.011 * Math.abs(60 - bmp2.getEntityData().get(HEAT)));
|
||||
// player.playSound(ModSounds.BMP_CANNON_FIRE_1P.get(), 1f, pitch);
|
||||
// player.playSound(ModSounds.SHELL_CASING_50CAL.get(), 0.3f, 1);
|
||||
// } else if (bmp2.getWeaponIndex(0) == 1) {
|
||||
// float pitch = bmp2.getEntityData().get(COAX_HEAT) <= 60 ? 1 : (float) (1 - 0.011 * Math.abs(60 - bmp2.getEntityData().get(COAX_HEAT)));
|
||||
// player.playSound(ModSounds.COAX_FIRE_1P.get(), 1f, pitch);
|
||||
// } else if (bmp2.getWeaponIndex(0) == 2) {
|
||||
// player.playSound(ModSounds.BMP_MISSILE_FIRE_1P.get(), 1f, 1);
|
||||
// }
|
||||
// }
|
||||
// if (iVehicle instanceof Yx100Entity yx100) {
|
||||
// if (type == 1) {
|
||||
// float pitch = yx100.getEntityData().get(HEAT) <= 60 ? 1 : (float) (1 - 0.011 * Math.abs(60 - yx100.getEntityData().get(HEAT)));
|
||||
// player.playSound(ModSounds.M_2_FIRE_1P.get(), 1f, pitch);
|
||||
// player.playSound(ModSounds.SHELL_CASING_50CAL.get(), 0.3f, 1);
|
||||
// } else {
|
||||
// player.playSound(ModSounds.YX_100_FIRE_1P.get(), 1f, 1);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
double rps = (double) rpm / 60;
|
||||
int cooldown = (int) (1000 / rps);
|
||||
|
||||
if ((holdFireVehicle)) {
|
||||
if (!clientTimerVehicle.started()) {
|
||||
clientTimerVehicle.start();
|
||||
// 首发瞬间发射
|
||||
clientTimerVehicle.setProgress((cooldown + 1));
|
||||
}
|
||||
|
||||
if (clientTimerVehicle.getProgress() >= cooldown) {
|
||||
// TODO vehicle fire msg
|
||||
// ModUtils.PACKET_HANDLER.sendToServer(new VehicleFireMessage(pVehicle.getSeatIndex(player)));
|
||||
|
||||
playVehicleClientSounds(player, iVehicle, pVehicle.getSeatIndex(player));
|
||||
clientTimerVehicle.setProgress((clientTimerVehicle.getProgress() - cooldown));
|
||||
}
|
||||
} else if (clientTimerVehicle.getProgress() >= cooldown) {
|
||||
clientTimerVehicle.stop();
|
||||
}
|
||||
} else {
|
||||
clientTimerVehicle.stop();
|
||||
}
|
||||
}
|
||||
|
||||
public static void playVehicleClientSounds(Player player, WeaponVehicleEntity iVehicle, int type) {
|
||||
if (iVehicle instanceof SpeedboatEntity speedboat) {
|
||||
float pitch = speedboat.getEntityData().get(HEAT) <= 60 ? 1 : (float) (1 - 0.011 * Math.abs(60 - speedboat.getEntityData().get(HEAT)));
|
||||
player.playSound(ModSounds.M_2_FIRE_1P.get(), 1f, pitch);
|
||||
player.playSound(ModSounds.SHELL_CASING_50CAL.get(), 0.3f, 1);
|
||||
}
|
||||
|
||||
if (iVehicle instanceof Ah6Entity ah6Entity) {
|
||||
float pitch = ah6Entity.getEntityData().get(HEAT) <= 60 ? 1 : (float) (1 - 0.011 * Math.abs(60 - ah6Entity.getEntityData().get(HEAT)));
|
||||
if (ah6Entity.getWeaponIndex(0) == 0) {
|
||||
player.playSound(ModSounds.HELICOPTER_CANNON_FIRE_1P.get(), 1f, pitch);
|
||||
} else if (ah6Entity.getWeaponIndex(0) == 1) {
|
||||
player.playSound(ModSounds.HELICOPTER_ROCKET_FIRE_1P.get(), 1f, 1);
|
||||
}
|
||||
}
|
||||
if (iVehicle instanceof Lav150Entity lav150) {
|
||||
if (lav150.getWeaponIndex(0) == 0) {
|
||||
float pitch = lav150.getEntityData().get(HEAT) <= 60 ? 1 : (float) (1 - 0.011 * Math.abs(60 - lav150.getEntityData().get(HEAT)));
|
||||
player.playSound(ModSounds.LAV_CANNON_FIRE_1P.get(), 1f, pitch);
|
||||
player.playSound(ModSounds.SHELL_CASING_50CAL.get(), 0.3f, 1);
|
||||
} else if (lav150.getWeaponIndex(0) == 1) {
|
||||
float pitch = lav150.getEntityData().get(COAX_HEAT) <= 60 ? 1 : (float) (1 - 0.011 * Math.abs(60 - lav150.getEntityData().get(COAX_HEAT)));
|
||||
player.playSound(ModSounds.COAX_FIRE_1P.get(), 1f, pitch);
|
||||
}
|
||||
|
||||
}
|
||||
if (iVehicle instanceof Bmp2Entity bmp2) {
|
||||
if (bmp2.getWeaponIndex(0) == 0) {
|
||||
float pitch = bmp2.getEntityData().get(HEAT) <= 60 ? 1 : (float) (1 - 0.011 * Math.abs(60 - bmp2.getEntityData().get(HEAT)));
|
||||
player.playSound(ModSounds.BMP_CANNON_FIRE_1P.get(), 1f, pitch);
|
||||
player.playSound(ModSounds.SHELL_CASING_50CAL.get(), 0.3f, 1);
|
||||
} else if (bmp2.getWeaponIndex(0) == 1) {
|
||||
float pitch = bmp2.getEntityData().get(COAX_HEAT) <= 60 ? 1 : (float) (1 - 0.011 * Math.abs(60 - bmp2.getEntityData().get(COAX_HEAT)));
|
||||
player.playSound(ModSounds.COAX_FIRE_1P.get(), 1f, pitch);
|
||||
} else if (bmp2.getWeaponIndex(0) == 2) {
|
||||
player.playSound(ModSounds.BMP_MISSILE_FIRE_1P.get(), 1f, 1);
|
||||
}
|
||||
}
|
||||
if (iVehicle instanceof Yx100Entity yx100) {
|
||||
if (type == 1) {
|
||||
float pitch = yx100.getEntityData().get(HEAT) <= 60 ? 1 : (float) (1 - 0.011 * Math.abs(60 - yx100.getEntityData().get(HEAT)));
|
||||
player.playSound(ModSounds.M_2_FIRE_1P.get(), 1f, pitch);
|
||||
player.playSound(ModSounds.SHELL_CASING_50CAL.get(), 0.3f, 1);
|
||||
} else {
|
||||
player.playSound(ModSounds.YX_100_FIRE_1P.get(), 1f, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void handleWeaponBreathSway(RenderFrameEvent.Pre event) {
|
||||
|
@ -764,8 +812,8 @@ public class ClientEventHandler {
|
|||
if (player == null) return;
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
if (!(stack.getItem() instanceof GunItem gunItem)) return;
|
||||
// if (player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.isDriver(player) && iArmedVehicle.hidePassenger(player))
|
||||
// return;
|
||||
if (player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.isDriver(player) && iArmedVehicle.hidePassenger(player))
|
||||
return;
|
||||
|
||||
float pose;
|
||||
float times = 2 * (float) Math.min(Minecraft.getInstance().getTimer().getGameTimeDeltaTicks(), 0.8);
|
||||
|
@ -810,10 +858,10 @@ public class ClientEventHandler {
|
|||
ItemStack stack = living.getMainHandItem();
|
||||
|
||||
if (level != null
|
||||
&& (
|
||||
// todo monitor
|
||||
// stack.is(ModItems.MONITOR.get()) &&
|
||||
NBTTool.getTag(stack).getBoolean("Using") && NBTTool.getTag(stack).getBoolean("Linked"))) {
|
||||
&& (stack.is(ModItems.MONITOR.get())
|
||||
&& NBTTool.getTag(stack).getBoolean("Using")
|
||||
&& NBTTool.getTag(stack).getBoolean("Linked"))
|
||||
) {
|
||||
handleDroneCamera(event, living);
|
||||
} else {
|
||||
var effect = Minecraft.getInstance().gameRenderer.currentEffect();
|
||||
|
@ -851,9 +899,9 @@ public class ClientEventHandler {
|
|||
cameraYaw = event.getYaw();
|
||||
cameraRoll = event.getRoll();
|
||||
|
||||
// if (player != null && player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.banHand(player)) {
|
||||
// return;
|
||||
// }
|
||||
if (player != null && player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.banHand(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (level != null && stack.is(ModTags.Items.GUN)) {
|
||||
handleWeaponSway(living);
|
||||
|
@ -871,21 +919,20 @@ public class ClientEventHandler {
|
|||
handleShockCamera(event, living);
|
||||
}
|
||||
|
||||
private static void handleDroneCamera(ViewportEvent.ComputeCameraAngles event, LivingEntity entity) {
|
||||
public static void handleDroneCamera(ViewportEvent.ComputeCameraAngles event, LivingEntity entity) {
|
||||
ItemStack stack = entity.getMainHandItem();
|
||||
float yaw = event.getYaw();
|
||||
|
||||
// DroneEntity drone = EntityFindUtil.findDrone(entity.level(), GunNBTTool.getOrCreateTag(stack).getString("LinkedDrone"));
|
||||
//
|
||||
// if (drone != null) {
|
||||
// event.setRoll(drone.getRoll((float) event.getPartialTick()) * (1 - (drone.getPitch((float) event.getPartialTick()) / 90)));
|
||||
// }
|
||||
//
|
||||
// if (drone != null && GunNBTTool.getOrCreateTag(stack).getBoolean("Using")) {
|
||||
// if (Minecraft.getInstance().gameRenderer.currentEffect() == null) {
|
||||
// Minecraft.getInstance().gameRenderer.loadEffect(ModUtils.loc("shaders/post/scan_pincushion.json"));
|
||||
// }
|
||||
// }
|
||||
DroneEntity drone = EntityFindUtil.findDrone(entity.level(), NBTTool.getTag(stack).getString("LinkedDrone"));
|
||||
|
||||
if (drone != null) {
|
||||
event.setRoll(drone.getRoll((float) event.getPartialTick()) * (1 - (drone.getPitch((float) event.getPartialTick()) / 90)));
|
||||
}
|
||||
|
||||
if (drone != null && NBTTool.getTag(stack).getBoolean("Using")) {
|
||||
if (Minecraft.getInstance().gameRenderer.currentEffect() == null) {
|
||||
Minecraft.getInstance().gameRenderer.loadEffect(ModUtils.loc("shaders/post/scan_pincushion.json"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
@ -911,21 +958,21 @@ public class ClientEventHandler {
|
|||
}
|
||||
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
// if (stack.is(ModItems.MONITOR.get()) && GunNBTTool.getOrCreateTag(stack).getBoolean("Using") && GunNBTTool.getOrCreateTag(stack).getBoolean("Linked")) {
|
||||
// if (EntityFindUtil.findDrone(player.level(), GunNBTTool.getOrCreateTag(stack).getString("LinkedDrone")) != null) {
|
||||
// event.setCanceled(true);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.banHand(player)) {
|
||||
// event.setCanceled(true);
|
||||
// }
|
||||
if (stack.is(ModItems.MONITOR.get()) && NBTTool.getTag(stack).getBoolean("Using") && NBTTool.getTag(stack).getBoolean("Linked")) {
|
||||
if (EntityFindUtil.findDrone(player.level(), NBTTool.getTag(stack).getString("LinkedDrone")) != null) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.banHand(player)) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleWeaponSway(LivingEntity entity) {
|
||||
ItemStack stack = entity.getMainHandItem();
|
||||
if (stack.getItem() instanceof GunItem gunItem && entity instanceof Player player) {
|
||||
// float times = 2 * (float) Math.min(Minecraft.getInstance().getTimer().getGameTimeDeltaTicks(), 0.8);
|
||||
float times = 2 * (float) Math.min(Minecraft.getInstance().getTimer().getGameTimeDeltaTicks(), 0.8);
|
||||
double pose;
|
||||
|
||||
if (player.isShiftKeyDown() && player.getBbHeight() >= 1 && isProne(player)) {
|
||||
|
@ -936,7 +983,7 @@ public class ClientEventHandler {
|
|||
pose = 1;
|
||||
}
|
||||
|
||||
// swayTime += 0.05 * times;
|
||||
swayTime += 0.05 * times;
|
||||
|
||||
swayX = pose * -0.008 * Math.sin(swayTime) * (1 - 0.95 * zoomTime);
|
||||
swayY = pose * 0.125 * Math.sin(swayTime - 1.585) * (1 - 0.95 * zoomTime) - 3 * moveRotZ;
|
||||
|
@ -1014,21 +1061,22 @@ public class ClientEventHandler {
|
|||
double weight = GunsTool.getGunDoubleTag(stack, "Weight") + GunsTool.getGunDoubleTag(stack, "CustomWeight");
|
||||
double speed = 1.5 - (0.07 * weight);
|
||||
|
||||
// if (zoom
|
||||
// && !(player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.banHand(player))
|
||||
// && !notInGame()
|
||||
// && drawTime < 0.01
|
||||
// && !cap != null && cap.edit) {
|
||||
// if (Minecraft.getInstance().player != null) {
|
||||
// Minecraft.getInstance().player.getPersistentData().putDouble("noRun", 5);
|
||||
// }
|
||||
// if (cantFireTime <= 10) {
|
||||
// zoomTime = Mth.clamp(zoomTime + 0.03 * speed * times, 0, 1);
|
||||
// }
|
||||
//
|
||||
// } else {
|
||||
// zoomTime = Mth.clamp(zoomTime - 0.04 * speed * times, 0, 1);
|
||||
// }
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (zoom
|
||||
&& !(player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.banHand(player))
|
||||
&& !notInGame()
|
||||
&& drawTime < 0.01
|
||||
&& cap != null && !cap.edit) {
|
||||
if (Minecraft.getInstance().player != null) {
|
||||
Minecraft.getInstance().player.getPersistentData().putDouble("noRun", 5);
|
||||
}
|
||||
if (cantFireTime <= 10) {
|
||||
zoomTime = Mth.clamp(zoomTime + 0.03 * speed * times, 0, 1);
|
||||
}
|
||||
|
||||
} else {
|
||||
zoomTime = Mth.clamp(zoomTime - 0.04 * speed * times, 0, 1);
|
||||
}
|
||||
zoomPos = AnimationCurves.EASE_IN_OUT_QUINT.apply(zoomTime);
|
||||
zoomPosZ = AnimationCurves.PARABOLA.apply(zoomTime);
|
||||
}
|
||||
|
@ -1073,9 +1121,9 @@ public class ClientEventHandler {
|
|||
|
||||
double rpm = 1;
|
||||
|
||||
// if (stack.is(ModItems.MINIGUN.get())) {
|
||||
// rpm = (double) GunsTool.getGunIntTag(stack, "RPM", 0) / 1800;
|
||||
// }
|
||||
if (stack.is(ModItems.MINIGUN.get())) {
|
||||
rpm = (double) GunsTool.getGunIntTag(stack, "RPM", 0) / 1800;
|
||||
}
|
||||
|
||||
float[] shake = {0, 0};
|
||||
shake[0] = (float) (1.3 * amplitude * (1 / 6.3 * (fireRotTimer - 0.5)) * Math.sin(6.3 * (fireRotTimer - 0.5)) * (3 - Math.pow(fireRotTimer, 2)) + 1 * Mth.clamp(0.3 - fireRotTimer, 0, 1) * (2 * Math.random() - 1));
|
||||
|
@ -1162,9 +1210,9 @@ public class ClientEventHandler {
|
|||
|
||||
double rpm = 1;
|
||||
|
||||
// if (stack.is(ModItems.MINIGUN.get())) {
|
||||
// rpm = (double) GunsTool.getGunIntTag(stack, "RPM", 0) / 1800;
|
||||
// }
|
||||
if (stack.is(ModItems.MINIGUN.get())) {
|
||||
rpm = (double) GunsTool.getGunIntTag(stack, "RPM", 0) / 1800;
|
||||
}
|
||||
|
||||
float gunRecoilX = (float) GunsTool.getGunDoubleTag(stack, "RecoilX", 0) * 60;
|
||||
|
||||
|
@ -1319,23 +1367,22 @@ public class ClientEventHandler {
|
|||
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
|
||||
// if (player.getVehicle() instanceof WeaponVehicleEntity iVehicle && zoomVehicle) {
|
||||
// event.setFOV(event.getFOV() / iVehicle.zoomFov());
|
||||
// return;
|
||||
// }
|
||||
if (player.getVehicle() instanceof WeaponVehicleEntity iVehicle && zoomVehicle) {
|
||||
event.setFOV(event.getFOV() / iVehicle.zoomFov());
|
||||
return;
|
||||
}
|
||||
|
||||
if (stack.is(ModTags.Items.GUN)) {
|
||||
if (!event.usedConfiguredFov()) {
|
||||
return;
|
||||
}
|
||||
|
||||
double p = zoomPos;
|
||||
// double p;
|
||||
// if (stack.is(ModItems.BOCEK.get())) {
|
||||
// p = (pullPos + 0.25) * zoomTime;
|
||||
// } else {
|
||||
// p = zoomPos;
|
||||
// }
|
||||
double p;
|
||||
if (stack.is(ModItems.BOCEK.get())) {
|
||||
p = (pullPos + 0.25) * zoomTime;
|
||||
} else {
|
||||
p = zoomPos;
|
||||
}
|
||||
|
||||
customZoom = Mth.lerp(0.6 * times, customZoom, GunsTool.getGunDoubleTag(stack, "CustomZoom", 0));
|
||||
|
||||
|
@ -1356,6 +1403,7 @@ public class ClientEventHandler {
|
|||
&& cap != null
|
||||
&& !cap.edit) {
|
||||
if (!player.isShiftKeyDown()) {
|
||||
// TODO perk
|
||||
// int intelligentChipLevel = PerkHelper.getItemPerkLevel(ModPerks.INTELLIGENT_CHIP.get(), stack);
|
||||
//
|
||||
// if (intelligentChipLevel > 0) {
|
||||
|
@ -1374,11 +1422,11 @@ public class ClientEventHandler {
|
|||
}
|
||||
}
|
||||
|
||||
// if (stack.is(ModItems.MONITOR.get()) && GunNBTTool.getOrCreateTag(stack).getBoolean("Using") && GunNBTTool.getOrCreateTag(stack).getBoolean("Linked")) {
|
||||
// droneFovLerp = Mth.lerp(0.1 * Minecraft.getInstance().getTimer().getGameTimeDeltaTicks(), droneFovLerp, droneFov);
|
||||
// event.setFOV(event.getFOV() / droneFovLerp);
|
||||
// fov = event.getFOV();
|
||||
// }
|
||||
if (stack.is(ModItems.MONITOR.get()) && NBTTool.getTag(stack).getBoolean("Using") && NBTTool.getTag(stack).getBoolean("Linked")) {
|
||||
droneFovLerp = Mth.lerp(0.1 * Minecraft.getInstance().getTimer().getGameTimeDeltaTicks(), droneFovLerp, droneFov);
|
||||
event.setFOV(event.getFOV() / droneFovLerp);
|
||||
fov = event.getFOV();
|
||||
}
|
||||
}
|
||||
|
||||
private static Vec3 getVec3(ViewportEvent.ComputeFov event, Player player) {
|
||||
|
@ -1403,76 +1451,64 @@ public class ClientEventHandler {
|
|||
public static void setPlayerInvisible(RenderPlayerEvent.Pre event) {
|
||||
var otherPlayer = event.getEntity();
|
||||
|
||||
// if (otherPlayer.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.hidePassenger(otherPlayer)) {
|
||||
// event.setCanceled(true);
|
||||
// }
|
||||
if (otherPlayer.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.hidePassenger(otherPlayer)) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
// @SubscribeEvent
|
||||
// public static void handleRenderCrossHair(RenderGuiOverlayEvent.Pre event) {
|
||||
// if (event.getOverlay() != VanillaGuiOverlay.CROSSHAIR.type()) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// Minecraft mc = Minecraft.getInstance();
|
||||
// Player player = mc.player;
|
||||
// if (player == null) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (!mc.options.getCameraType().isFirstPerson()) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// ItemStack stack = player.getMainHandItem();
|
||||
//
|
||||
// if (stack.getItem() instanceof GunItem) {
|
||||
// event.setCanceled(true);
|
||||
// }
|
||||
//
|
||||
// if (player.getVehicle() instanceof VehicleEntity pVehicle && player.getVehicle() instanceof WeaponVehicleEntity iVehicle && iVehicle.hasWeapon(pVehicle.getSeatIndex(player))) {
|
||||
// event.setCanceled(true);
|
||||
// }
|
||||
//
|
||||
// if (stack.is(ModItems.MONITOR.get()) && GunNBTTool.getOrCreateTag(stack).getBoolean("Using") && GunNBTTool.getOrCreateTag(stack).getBoolean("Linked")) {
|
||||
// event.setCanceled(true);
|
||||
// }
|
||||
// }
|
||||
@SubscribeEvent
|
||||
public static void handleRenderCrossHair(RenderGuiLayerEvent.Pre event) {
|
||||
if (!event.getName().equals(VanillaGuiLayers.CROSSHAIR)) return;
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
Player player = mc.player;
|
||||
if (player == null) return;
|
||||
if (!mc.options.getCameraType().isFirstPerson()) return;
|
||||
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
|
||||
if (stack.getItem() instanceof GunItem) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
|
||||
if (player.getVehicle() instanceof VehicleEntity pVehicle && player.getVehicle() instanceof WeaponVehicleEntity iVehicle && iVehicle.hasWeapon(pVehicle.getSeatIndex(player))) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
|
||||
if (stack.is(ModItems.MONITOR.get()) && NBTTool.getTag(stack).getBoolean("Using") && NBTTool.getTag(stack).getBoolean("Linked")) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 载具banHand时,禁用快捷栏渲染
|
||||
*/
|
||||
// @SubscribeEvent
|
||||
// public static void handleAvoidRenderingHotbar(RenderGuiOverlayEvent.Pre event) {
|
||||
// if (event.getOverlay() != VanillaGuiOverlay.HOTBAR.type()) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// Minecraft mc = Minecraft.getInstance();
|
||||
// Player player = mc.player;
|
||||
// if (player == null) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (player.getVehicle() instanceof ArmedVehicleEntity vehicle && vehicle.banHand(player)) {
|
||||
// event.setCanceled(true);
|
||||
// }
|
||||
// }
|
||||
@SubscribeEvent
|
||||
public static void handleAvoidRenderingHotbar(RenderGuiLayerEvent.Pre event) {
|
||||
if (!event.getName().equals(VanillaGuiLayers.HOTBAR)) return;
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
Player player = mc.player;
|
||||
if (player == null) return;
|
||||
|
||||
if (player.getVehicle() instanceof ArmedVehicleEntity vehicle && vehicle.banHand(player)) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleDrawMessage(boolean draw, final IPayloadContext context) {
|
||||
drawTime = 1;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
shellIndexTime[i] = 0;
|
||||
}
|
||||
zoom = false;
|
||||
holdFire = false;
|
||||
ClickHandler.switchZoom = false;
|
||||
lungeDraw = 30;
|
||||
lungeSprint = 0;
|
||||
lungeAttack = 0;
|
||||
}
|
||||
|
||||
// public static void handleDrawMessage(boolean draw, Supplier<NetworkEvent.Context> ctx) {
|
||||
// if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) {
|
||||
// drawTime = 1;
|
||||
// for (int i = 0; i < 5; i++) {
|
||||
// shellIndexTime[i] = 0;
|
||||
// }
|
||||
// zoom = false;
|
||||
// holdFire = false;
|
||||
// ClickHandler.switchZoom = false;
|
||||
// lungeDraw = 30;
|
||||
// lungeSprint = 0;
|
||||
// lungeAttack = 0;
|
||||
// }
|
||||
// }
|
||||
private static void handleWeaponDraw(LivingEntity entity) {
|
||||
float times = Minecraft.getInstance().getTimer().getGameTimeDeltaTicks();
|
||||
ItemStack stack = entity.getMainHandItem();
|
||||
|
@ -1502,6 +1538,7 @@ public class ClientEventHandler {
|
|||
List<Entity> entities = SeekTool.seekLivingEntities(villager, villager.level(), 16, 120);
|
||||
for (var e : entities) {
|
||||
if (e == player) {
|
||||
// TODO aimVillager
|
||||
// ModUtils.PACKET_HANDLER.sendToServer(new AimVillagerMessage(villager.getId()));
|
||||
aimVillagerCountdown = 80;
|
||||
break;
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
package com.atsuishio.superbwarfare.event;
|
||||
|
||||
import com.atsuishio.superbwarfare.client.MouseMovementHandler;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.phys.Vec2;
|
||||
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 static com.atsuishio.superbwarfare.event.ClientEventHandler.isFreeCam;
|
||||
|
||||
@EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME, value = Dist.CLIENT)
|
||||
public class ClientMouseHandler {
|
||||
public static Vec2 posO = new Vec2(0, 0);
|
||||
public static Vec2 posN = new Vec2(0, 0);
|
||||
public static Vec2 mousePos = new Vec2(0, 0);
|
||||
public static double PosX = 0;
|
||||
public static double lerpPosX = 0;
|
||||
public static double PosY = 0;
|
||||
public static double lerpPosY = 0;
|
||||
|
||||
public static double freeCameraPitch = 0;
|
||||
public static double freeCameraYaw = 0;
|
||||
|
||||
private static boolean notInGame() {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
if (mc.player == null) return true;
|
||||
if (mc.getOverlay() != null) return true;
|
||||
if (mc.screen != null) return true;
|
||||
if (!mc.mouseHandler.isMouseGrabbed()) return true;
|
||||
return !mc.isWindowActive();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void handleClientTick(ViewportEvent.ComputeCameraAngles event) {
|
||||
LocalPlayer player = Minecraft.getInstance().player;
|
||||
if (player == null) return;
|
||||
|
||||
posO = posN;
|
||||
posN = MouseMovementHandler.getMousePos();
|
||||
|
||||
if (!notInGame()) {
|
||||
mousePos = posN.add(posO.scale(-1));
|
||||
|
||||
if (mousePos.x != 0) {
|
||||
lerpPosX = Mth.lerp(0.1, PosX, mousePos.x);
|
||||
}
|
||||
if (mousePos.y != 0) {
|
||||
lerpPosY = Mth.lerp(0.1, PosY, mousePos.y);
|
||||
}
|
||||
}
|
||||
|
||||
lerpPosX = Mth.clamp(Mth.lerp(event.getPartialTick(), lerpPosX, 0), -1, 1);
|
||||
lerpPosY = Mth.clamp(Mth.lerp(event.getPartialTick(), lerpPosY, 0), -1, 1);
|
||||
|
||||
|
||||
if (isFreeCam(player)) {
|
||||
freeCameraYaw = Mth.clamp(freeCameraYaw + 4 * lerpPosX, -100, 100);
|
||||
freeCameraPitch = Mth.clamp(freeCameraPitch + 4 * lerpPosY, -90, 90);
|
||||
}
|
||||
|
||||
float yaw = event.getYaw();
|
||||
float pitch = event.getPitch();
|
||||
|
||||
event.setYaw((float) (yaw + freeCameraYaw));
|
||||
event.setPitch((float) (pitch + freeCameraPitch));
|
||||
|
||||
if (!isFreeCam(player)) {
|
||||
freeCameraYaw *= 0.8;
|
||||
freeCameraPitch *= 0.8;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package com.atsuishio.superbwarfare.event;
|
||||
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.*;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.tools.NBTTool;
|
||||
import com.atsuishio.superbwarfare.tools.SeekTool;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
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.ClientTickEvent;
|
||||
import org.joml.Math;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.atsuishio.superbwarfare.entity.vehicle.Ah6Entity.PROPELLER_ROT;
|
||||
import static com.atsuishio.superbwarfare.entity.vehicle.Bmp2Entity.DELTA_ROT;
|
||||
import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity.POWER;
|
||||
|
||||
@EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME, value = Dist.CLIENT)
|
||||
public class ClientSoundHandler {
|
||||
@SubscribeEvent
|
||||
public static void handleClientTick(ClientTickEvent event) {
|
||||
LocalPlayer player = Minecraft.getInstance().player;
|
||||
if (player == null) return;
|
||||
|
||||
List<Entity> engineVehicle = SeekTool.getVehicleWithinRange(player, player.level(), 192);
|
||||
|
||||
for (var e : engineVehicle) {
|
||||
if (e instanceof MobileVehicleEntity mobileVehicle) {
|
||||
|
||||
Vec3 listener = player.getEyePosition();
|
||||
Vec3 engineRealPos = e.getEyePosition();
|
||||
Vec3 toVec = listener.vectorTo(engineRealPos).normalize();
|
||||
double distance = listener.distanceTo(engineRealPos);
|
||||
|
||||
var engineSoundPos = new Vec3(listener.x + toVec.x, listener.y + toVec.y, listener.z + toVec.z);
|
||||
SoundEvent engineSound = mobileVehicle.getEngineSound();
|
||||
float distanceReduce;
|
||||
if (e instanceof Ah6Entity ah6Entity) {
|
||||
distanceReduce = (float) Math.max((1 - distance / 128), 0);
|
||||
if (player.getVehicle() == ah6Entity) {
|
||||
player.playSound(ModSounds.HELICOPTER_ENGINE_1P.get(), 2 * (mobileVehicle.getEntityData().get(PROPELLER_ROT) - 0.012f), (float) ((2 * Math.random() - 1) * 0.1f + 1.0f));
|
||||
} else {
|
||||
player.level().playLocalSound(BlockPos.containing(engineSoundPos), engineSound, mobileVehicle.getSoundSource(), 5 * (mobileVehicle.getEntityData().get(PROPELLER_ROT) - 0.012f) * distanceReduce * distanceReduce, (float) ((2 * Math.random() - 1) * 0.1f + 1), false);
|
||||
}
|
||||
}
|
||||
if (e instanceof Lav150Entity lav150) {
|
||||
distanceReduce = (float) Math.max((1 - distance / 64), 0);
|
||||
if (player.getVehicle() == lav150) {
|
||||
player.playSound(ModSounds.LAV_ENGINE_1P.get(), 1 * (Mth.abs(mobileVehicle.getEntityData().get(POWER)) - 0.006f), (float) ((2 * Math.random() - 1) * 0.1f + 0.95f));
|
||||
} else {
|
||||
player.level().playLocalSound(BlockPos.containing(engineSoundPos), engineSound, mobileVehicle.getSoundSource(), 5 * (Mth.abs(mobileVehicle.getEntityData().get(POWER)) - 0.006f) * distanceReduce * distanceReduce, (float) ((2 * Math.random() - 1) * 0.1f + 1), false);
|
||||
}
|
||||
}
|
||||
if (e instanceof Bmp2Entity bmp2) {
|
||||
distanceReduce = (float) Math.max((1 - distance / 64), 0);
|
||||
if (player.getVehicle() == bmp2) {
|
||||
player.playSound(ModSounds.BMP_ENGINE_1P.get(), 1 * (Mth.abs(mobileVehicle.getEntityData().get(POWER)) + Mth.abs(0.08f * mobileVehicle.getEntityData().get(DELTA_ROT)) - 0.004f), (float) ((2 * Math.random() - 1) * 0.1f + 0.95f));
|
||||
} else {
|
||||
player.level().playLocalSound(BlockPos.containing(engineSoundPos), engineSound, mobileVehicle.getSoundSource(), 5 * (Mth.abs(mobileVehicle.getEntityData().get(POWER)) + Mth.abs(0.08f * mobileVehicle.getEntityData().get(DELTA_ROT)) - 0.004f) * distanceReduce * distanceReduce, (float) ((2 * Math.random() - 1) * 0.1f + 1), false);
|
||||
}
|
||||
}
|
||||
if (e instanceof Yx100Entity yx100) {
|
||||
distanceReduce = (float) Math.max((1 - distance / 64), 0);
|
||||
if (player.getVehicle() == yx100) {
|
||||
player.playSound(ModSounds.BMP_ENGINE_1P.get(), 1 * (Mth.abs(mobileVehicle.getEntityData().get(POWER)) + Mth.abs(0.08f * mobileVehicle.getEntityData().get(DELTA_ROT)) - 0.004f), (float) ((2 * Math.random() - 1) * 0.1f + 0.95f));
|
||||
} else {
|
||||
player.level().playLocalSound(BlockPos.containing(engineSoundPos), engineSound, mobileVehicle.getSoundSource(), 5 * (Mth.abs(mobileVehicle.getEntityData().get(POWER)) + Mth.abs(0.08f * mobileVehicle.getEntityData().get(DELTA_ROT)) - 0.004f) * distanceReduce * distanceReduce, (float) ((2 * Math.random() - 1) * 0.1f + 1), false);
|
||||
}
|
||||
}
|
||||
if (e instanceof DroneEntity drone) {
|
||||
distanceReduce = (float) Math.max((1 - distance / 64), 0);
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
if (stack.is(ModItems.MONITOR.get()) && NBTTool.getBoolean(stack, "Using", false)) {
|
||||
player.playSound(engineSound, 1, (float) ((2 * Math.random() - 1) * 0.002f + 1.05));
|
||||
} else {
|
||||
player.level().playLocalSound(BlockPos.containing(engineSoundPos), engineSound, mobileVehicle.getSoundSource(), e.onGround() ? 0 : distanceReduce * distanceReduce, (float) ((2 * Math.random() - 1) * 0.002f + 1.05), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import com.atsuishio.superbwarfare.ModUtils;
|
|||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||
import com.atsuishio.superbwarfare.capability.player.PlayerVariable;
|
||||
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
|
||||
import com.atsuishio.superbwarfare.event.events.ReloadEvent;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.init.ModTags;
|
||||
|
@ -22,6 +23,7 @@ import net.minecraft.world.phys.Vec3;
|
|||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||
import net.neoforged.neoforge.common.NeoForge;
|
||||
import net.neoforged.neoforge.event.tick.PlayerTickEvent;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
@ -54,16 +56,14 @@ public class GunEventHandler {
|
|||
if (GunsTool.getGunIntTag(stack, "BoltActionTick") > 0) {
|
||||
GunsTool.setGunIntTag(stack, "BoltActionTick", GunsTool.getGunIntTag(stack, "BoltActionTick") - 1);
|
||||
}
|
||||
|
||||
// todo marlin
|
||||
// if (stack.getItem() == ModItems.MARLIN.get() && GunsTool.getGunIntTag(stack, "BoltActionTick") == 9) {
|
||||
// GunNBTTool.getOrCreateTag(stack).putBoolean("empty", false);
|
||||
// }
|
||||
if (stack.getItem() == ModItems.MARLIN.get() && GunsTool.getGunIntTag(stack, "BoltActionTick") == 9) {
|
||||
NBTTool.setBoolean(stack, "empty", false);
|
||||
}
|
||||
|
||||
if (GunsTool.getGunIntTag(stack, "BoltActionTick") == 1) {
|
||||
GunsTool.setGunBooleanTag(stack, "NeedBoltAction", false);
|
||||
if (stack.is(ModTags.Items.REVOLVER)) {
|
||||
NBTTool.getTag(stack).putBoolean("canImmediatelyShoot", true);
|
||||
NBTTool.setBoolean(stack, "canImmediatelyShoot", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,36 +82,32 @@ public class GunEventHandler {
|
|||
String origin = stack.getItem().getDescriptionId();
|
||||
String name = origin.substring(origin.lastIndexOf(".") + 1);
|
||||
|
||||
// todo other guns
|
||||
// if (stack.getItem() == ModItems.SENTINEL.get()) {
|
||||
// AtomicBoolean charged = new AtomicBoolean(false);
|
||||
//
|
||||
// stack.getCapability(ForgeCapabilities.ENERGY).ifPresent(
|
||||
// e -> charged.set(e.getEnergyStored() > 0)
|
||||
// );
|
||||
//
|
||||
// if (charged.get()) {
|
||||
// float soundRadius = (float) GunsTool.getGunDoubleTag(stack, "SoundRadius");
|
||||
//
|
||||
// SoundEvent sound3p = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc( "sentinel_charge_fire_3p"));
|
||||
// if (sound3p != null) {
|
||||
// player.playSound(sound3p, soundRadius * 0.4f, 1f);
|
||||
// }
|
||||
//
|
||||
// SoundEvent soundFar = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc( "sentinel_charge_far"));
|
||||
// if (soundFar != null) {
|
||||
// player.playSound(soundFar, soundRadius * 0.7f, 1f);
|
||||
// }
|
||||
//
|
||||
// SoundEvent soundVeryFar = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc( "sentinel_charge_veryfar"));
|
||||
// if (soundVeryFar != null) {
|
||||
// player.playSound(soundVeryFar, soundRadius, 1f);
|
||||
// }
|
||||
//
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
if (stack.getItem() == ModItems.SENTINEL.get()) {
|
||||
var cap = stack.getCapability(Capabilities.EnergyStorage.ITEM);
|
||||
|
||||
if (cap != null && cap.getEnergyStored() > 0) {
|
||||
float soundRadius = (float) GunsTool.getGunDoubleTag(stack, "SoundRadius");
|
||||
|
||||
SoundEvent sound3p = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc("sentinel_charge_fire_3p"));
|
||||
if (sound3p != null) {
|
||||
player.playSound(sound3p, soundRadius * 0.4f, 1f);
|
||||
}
|
||||
|
||||
SoundEvent soundFar = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc("sentinel_charge_far"));
|
||||
if (soundFar != null) {
|
||||
player.playSound(soundFar, soundRadius * 0.7f, 1f);
|
||||
}
|
||||
|
||||
SoundEvent soundVeryFar = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc("sentinel_charge_veryfar"));
|
||||
if (soundVeryFar != null) {
|
||||
player.playSound(soundVeryFar, soundRadius, 1f);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO perk
|
||||
// var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO);
|
||||
//
|
||||
// if (perk == ModPerks.BEAST_BULLET.get()) {
|
||||
|
@ -255,7 +251,7 @@ public class GunEventHandler {
|
|||
|
||||
projectile.setPos(player.getX() - 0.1 * player.getLookAngle().x, player.getEyeY() - 0.1 - 0.1 * player.getLookAngle().y, player.getZ() + -0.1 * player.getLookAngle().z);
|
||||
projectile.shoot(player, player.getLookAngle().x, player.getLookAngle().y + 0.001f, player.getLookAngle().z,
|
||||
// TODO incendiary bullet
|
||||
// TODO perk incendiary bullet
|
||||
// stack.is(ModTags.Items.SHOTGUN) && perk == ModPerks.INCENDIARY_BULLET.get() ? 4.5f : velocity,
|
||||
velocity,
|
||||
(float) spared);
|
||||
|
@ -324,8 +320,7 @@ public class GunEventHandler {
|
|||
// 启动换弹
|
||||
if (GunsTool.getGunBooleanTag(stack, "StartReload")) {
|
||||
|
||||
// TODO reload event
|
||||
// NeoForge.EVENT_BUS.post(new ReloadEvent.Pre(player, stack));
|
||||
NeoForge.EVENT_BUS.post(new ReloadEvent.Pre(player, stack));
|
||||
if (gunItem.isOpenBolt(stack)) {
|
||||
if (GunsTool.getGunIntTag(stack, "Ammo", 0) == 0) {
|
||||
data.putInt("ReloadTime", data.getInt("EmptyReloadTime") + 1);
|
||||
|
@ -348,51 +343,50 @@ public class GunEventHandler {
|
|||
data.putInt("ReloadTime", data.getInt("ReloadTime") - 1);
|
||||
}
|
||||
|
||||
// todo other guns
|
||||
// if (stack.getItem() == ModItems.RPG.get()) {
|
||||
// if (data.getInt("ReloadTime") == 84) {
|
||||
// tag.putBoolean("empty", false);
|
||||
// }
|
||||
// if (data.getInt("ReloadTime") == 9) {
|
||||
// data.putBoolean("CloseHammer", false);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (stack.getItem() == ModItems.MK_14.get()) {
|
||||
// if (data.getInt("ReloadTime") == 18) {
|
||||
// data.putBoolean("HoldOpen", false);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (stack.getItem() == ModItems.SVD.get()) {
|
||||
// if (data.getInt("ReloadTime") == 17) {
|
||||
// data.putBoolean("HoldOpen", false);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (stack.getItem() == ModItems.SKS.get()) {
|
||||
// if (data.getInt("ReloadTime") == 14) {
|
||||
// data.putBoolean("HoldOpen", false);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (stack.getItem() == ModItems.M_60.get()) {
|
||||
// if (data.getInt("ReloadTime") == 55) {
|
||||
// data.putBoolean("HideBulletChain", false);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (stack.getItem() == ModItems.GLOCK_17.get() || stack.getItem() == ModItems.GLOCK_18.get() || stack.getItem() == ModItems.M_1911.get() || stack.getItem() == ModItems.MP_443.get()) {
|
||||
// if (data.getInt("ReloadTime") == 9) {
|
||||
// data.putBoolean("HoldOpen", false);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (stack.getItem() == ModItems.QBZ_95.get()) {
|
||||
// if (data.getInt("ReloadTime") == 14) {
|
||||
// data.putBoolean("HoldOpen", false);
|
||||
// }
|
||||
// }
|
||||
if (stack.getItem() == ModItems.RPG.get()) {
|
||||
if (data.getInt("ReloadTime") == 84) {
|
||||
tag.putBoolean("empty", false);
|
||||
}
|
||||
if (data.getInt("ReloadTime") == 9) {
|
||||
data.putBoolean("CloseHammer", false);
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.getItem() == ModItems.MK_14.get()) {
|
||||
if (data.getInt("ReloadTime") == 18) {
|
||||
data.putBoolean("HoldOpen", false);
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.getItem() == ModItems.SVD.get()) {
|
||||
if (data.getInt("ReloadTime") == 17) {
|
||||
data.putBoolean("HoldOpen", false);
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.getItem() == ModItems.SKS.get()) {
|
||||
if (data.getInt("ReloadTime") == 14) {
|
||||
data.putBoolean("HoldOpen", false);
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.getItem() == ModItems.M_60.get()) {
|
||||
if (data.getInt("ReloadTime") == 55) {
|
||||
data.putBoolean("HideBulletChain", false);
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.getItem() == ModItems.GLOCK_17.get() || stack.getItem() == ModItems.GLOCK_18.get() || stack.getItem() == ModItems.M_1911.get() || stack.getItem() == ModItems.MP_443.get()) {
|
||||
if (data.getInt("ReloadTime") == 9) {
|
||||
data.putBoolean("HoldOpen", false);
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.getItem() == ModItems.QBZ_95.get()) {
|
||||
if (data.getInt("ReloadTime") == 14) {
|
||||
data.putBoolean("HoldOpen", false);
|
||||
}
|
||||
}
|
||||
|
||||
if (data.getInt("ReloadTime") == 1) {
|
||||
if (gunItem.isOpenBolt(stack)) {
|
||||
|
@ -435,8 +429,7 @@ public class GunEventHandler {
|
|||
NBTTool.getTag(stack).putBoolean("is_normal_reloading", false);
|
||||
NBTTool.getTag(stack).putBoolean("is_empty_reloading", false);
|
||||
|
||||
// TODO reload event
|
||||
// NeoForge.EVENT_BUS.post(new ReloadEvent.Post(player, stack));
|
||||
NeoForge.EVENT_BUS.post(new ReloadEvent.Post(player, stack));
|
||||
}
|
||||
|
||||
public static void playGunEmptyReload(Player player) {
|
||||
|
@ -456,28 +449,25 @@ public class GunEventHandler {
|
|||
GunsTool.reload(player, stack, AmmoType.RIFLE);
|
||||
} else if (stack.is(ModTags.Items.USE_HEAVY_AMMO)) {
|
||||
GunsTool.reload(player, stack, AmmoType.HEAVY);
|
||||
} else if (stack.getItem() == ModItems.TASER.get()) {
|
||||
GunsTool.setGunIntTag(stack, "Ammo", 1);
|
||||
player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.TASER_ELECTRODE.get(), 1, player.inventoryMenu.getCraftSlots());
|
||||
} else if (stack.getItem() == ModItems.M_79.get()) {
|
||||
GunsTool.setGunIntTag(stack, "Ammo", 1);
|
||||
player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.GRENADE_40MM.get(), 1, player.inventoryMenu.getCraftSlots());
|
||||
} else if (stack.getItem() == ModItems.RPG.get()) {
|
||||
GunsTool.setGunIntTag(stack, "Ammo", 1);
|
||||
player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.ROCKET.get(), 1, player.inventoryMenu.getCraftSlots());
|
||||
} else if (stack.getItem() == ModItems.JAVELIN.get()) {
|
||||
GunsTool.setGunIntTag(stack, "Ammo", 1);
|
||||
player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.JAVELIN_MISSILE.get(), 1, player.inventoryMenu.getCraftSlots());
|
||||
}
|
||||
// todo other guns
|
||||
// } else if (stack.getItem() == ModItems.TASER.get()) {
|
||||
// GunsTool.setGunIntTag(stack, "Ammo", 1);
|
||||
// player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.TASER_ELECTRODE.get(), 1, player.inventoryMenu.getCraftSlots());
|
||||
// } else if (stack.getItem() == ModItems.M_79.get()) {
|
||||
// GunsTool.setGunIntTag(stack, "Ammo", 1);
|
||||
// player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.GRENADE_40MM.get(), 1, player.inventoryMenu.getCraftSlots());
|
||||
// } else if (stack.getItem() == ModItems.RPG.get()) {
|
||||
// GunsTool.setGunIntTag(stack, "Ammo", 1);
|
||||
// player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.ROCKET.get(), 1, player.inventoryMenu.getCraftSlots());
|
||||
// } else if (stack.getItem() == ModItems.JAVELIN.get()) {
|
||||
// GunsTool.setGunIntTag(stack, "Ammo", 1);
|
||||
// player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.JAVELIN_MISSILE.get(), 1, player.inventoryMenu.getCraftSlots());
|
||||
// }
|
||||
}
|
||||
|
||||
NBTTool.getTag(stack).putBoolean("is_normal_reloading", false);
|
||||
NBTTool.getTag(stack).putBoolean("is_empty_reloading", false);
|
||||
|
||||
// TODO reload event
|
||||
// NeoForge.EVENT_BUS.post(new ReloadEvent.Post(player, stack));
|
||||
NeoForge.EVENT_BUS.post(new ReloadEvent.Post(player, stack));
|
||||
}
|
||||
|
||||
public static void playGunEmptyReloadSounds(Player player) {
|
||||
|
@ -547,12 +537,11 @@ public class GunEventHandler {
|
|||
|
||||
// 一阶段
|
||||
if (tag.getBoolean("start_single_reload")) {
|
||||
// todo reload event
|
||||
// NeoForge.EVENT_BUS.post(new ReloadEvent.Pre(player, stack));
|
||||
NeoForge.EVENT_BUS.post(new ReloadEvent.Pre(player, stack));
|
||||
|
||||
if ((GunsTool.getGunIntTag(stack, "PrepareLoadTime", 0) != 0 && GunsTool.getGunIntTag(stack, "Ammo", 0) == 0)
|
||||
// todo 2nd
|
||||
// || stack.is(ModItems.SECONDARY_CATACLYSM.get())
|
||||
if ((GunsTool.getGunIntTag(stack, "PrepareLoadTime", 0) != 0
|
||||
&& GunsTool.getGunIntTag(stack, "Ammo", 0) == 0)
|
||||
|| stack.is(ModItems.SECONDARY_CATACLYSM.get())
|
||||
) {
|
||||
// 此处判断空仓换弹的时候,是否在准备阶段就需要装填一发,如M870
|
||||
playGunPrepareLoadReloadSounds(player);
|
||||
|
@ -579,18 +568,17 @@ public class GunEventHandler {
|
|||
tag.putBoolean("start_single_reload", false);
|
||||
}
|
||||
|
||||
// todo other guns
|
||||
// if (stack.getItem() == ModItems.M_870.get()) {
|
||||
// if (tag.getInt("prepare_load") == 10) {
|
||||
// singleLoad(player);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (stack.getItem() == ModItems.SECONDARY_CATACLYSM.get()) {
|
||||
// if (tag.getInt("prepare_load") == 3) {
|
||||
// singleLoad(player);
|
||||
// }
|
||||
// }
|
||||
if (stack.getItem() == ModItems.M_870.get()) {
|
||||
if (tag.getInt("prepare_load") == 10) {
|
||||
singleLoad(player);
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.getItem() == ModItems.SECONDARY_CATACLYSM.get()) {
|
||||
if (tag.getInt("prepare_load") == 3) {
|
||||
singleLoad(player);
|
||||
}
|
||||
}
|
||||
|
||||
// 一阶段结束,检查备弹,如果有则二阶段启动,无则直接跳到三阶段
|
||||
if ((tag.getDouble("prepare") == 1 || tag.getDouble("prepare_load") == 1)) {
|
||||
|
@ -610,19 +598,17 @@ public class GunEventHandler {
|
|||
tag.putBoolean("force_stage3_start", true);
|
||||
} else if (stack.is(ModTags.Items.LAUNCHER) && GunsTool.getGunIntTag(stack, "MaxAmmo") == 0) {
|
||||
tag.putBoolean("force_stage3_start", true);
|
||||
// todo 2nd
|
||||
// } else if (stack.is(ModItems.SECONDARY_CATACLYSM.get()) && GunsTool.getGunIntTag(stack, "Ammo", 0) >= GunsTool.getGunIntTag(stack, "Magazine", 0)) {
|
||||
// tag.putBoolean("force_stage3_start", true);
|
||||
} else if (stack.is(ModItems.SECONDARY_CATACLYSM.get()) && GunsTool.getGunIntTag(stack, "Ammo", 0) >= GunsTool.getGunIntTag(stack, "Magazine", 0)) {
|
||||
tag.putBoolean("force_stage3_start", true);
|
||||
} else {
|
||||
tag.putInt("reload_stage", 2);
|
||||
}
|
||||
} else {
|
||||
// todo 2nd
|
||||
// if (stack.is(ModItems.SECONDARY_CATACLYSM.get()) && GunsTool.getGunIntTag(stack, "Ammo", 0) >= GunsTool.getGunIntTag(stack, "Magazine", 0)) {
|
||||
// tag.putBoolean("force_stage3_start", true);
|
||||
// } else {
|
||||
if (stack.is(ModItems.SECONDARY_CATACLYSM.get()) && GunsTool.getGunIntTag(stack, "Ammo", 0) >= GunsTool.getGunIntTag(stack, "Magazine", 0)) {
|
||||
tag.putBoolean("force_stage3_start", true);
|
||||
} else {
|
||||
tag.putInt("reload_stage", 2);
|
||||
// }
|
||||
}
|
||||
}
|
||||
// 检查备弹
|
||||
}
|
||||
|
@ -652,24 +638,24 @@ public class GunEventHandler {
|
|||
}
|
||||
}
|
||||
|
||||
// 装填 todo other guns
|
||||
// if (stack.getItem() == ModItems.M_870.get() || stack.getItem() == ModItems.MARLIN.get()) {
|
||||
// if (tag.getInt("iterative") == 3) {
|
||||
// singleLoad(player);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (stack.getItem() == ModItems.SECONDARY_CATACLYSM.get()) {
|
||||
// if (tag.getInt("iterative") == 16) {
|
||||
// singleLoad(player);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (stack.getItem() == ModItems.K_98.get() || stack.getItem() == ModItems.MOSIN_NAGANT.get()) {
|
||||
// if (tag.getInt("iterative") == 1) {
|
||||
// singleLoad(player);
|
||||
// }
|
||||
// }
|
||||
// 装填
|
||||
if (stack.getItem() == ModItems.M_870.get() || stack.getItem() == ModItems.MARLIN.get()) {
|
||||
if (tag.getInt("iterative") == 3) {
|
||||
singleLoad(player);
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.getItem() == ModItems.SECONDARY_CATACLYSM.get()) {
|
||||
if (tag.getInt("iterative") == 16) {
|
||||
singleLoad(player);
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.getItem() == ModItems.K_98.get() || stack.getItem() == ModItems.MOSIN_NAGANT.get()) {
|
||||
if (tag.getInt("iterative") == 1) {
|
||||
singleLoad(player);
|
||||
}
|
||||
}
|
||||
|
||||
// 二阶段结束
|
||||
if (tag.getInt("iterative") == 1) {
|
||||
|
@ -715,10 +701,9 @@ public class GunEventHandler {
|
|||
playGunEndReloadSounds(player);
|
||||
}
|
||||
|
||||
// todo marlin
|
||||
// if (stack.getItem() == ModItems.MARLIN.get() && tag.getInt("finish") == 10) {
|
||||
// tag.putBoolean("empty", false);
|
||||
// }
|
||||
if (stack.getItem() == ModItems.MARLIN.get() && tag.getInt("finish") == 10) {
|
||||
tag.putBoolean("empty", false);
|
||||
}
|
||||
|
||||
// 三阶段结束
|
||||
if (tag.getInt("finish") == 1) {
|
||||
|
@ -729,8 +714,7 @@ public class GunEventHandler {
|
|||
GunsTool.setGunBooleanTag(stack, "Reloading", false);
|
||||
tag.putBoolean("start_single_reload", false);
|
||||
|
||||
// todo reload event
|
||||
// NeoForge.EVENT_BUS.post(new ReloadEvent.Post(player, stack));
|
||||
NeoForge.EVENT_BUS.post(new ReloadEvent.Post(player, stack));
|
||||
}
|
||||
saveTag(stack, tag);
|
||||
}
|
||||
|
@ -754,13 +738,10 @@ public class GunEventHandler {
|
|||
AmmoType.RIFLE.add(cap, -1);
|
||||
} else if (stack.is(ModTags.Items.USE_HEAVY_AMMO)) {
|
||||
AmmoType.HEAVY.add(cap, -1);
|
||||
} else if (stack.getItem() == ModItems.SECONDARY_CATACLYSM.get()) {
|
||||
player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.GRENADE_40MM.get(), 1, player.inventoryMenu.getCraftSlots());
|
||||
}
|
||||
|
||||
// todo secondary
|
||||
// } else if (stack.getItem() == ModItems.SECONDARY_CATACLYSM.get()) {
|
||||
// player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.GRENADE_40MM.get(), 1, player.inventoryMenu.getCraftSlots());
|
||||
// }
|
||||
|
||||
cap.syncPlayerVariables(player);
|
||||
}
|
||||
}
|
||||
|
@ -876,10 +857,9 @@ public class GunEventHandler {
|
|||
double shooterHeight = player.getEyePosition().distanceTo((Vec3.atLowerCornerOf(player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(new Vec3(0, -1, 0).scale(10)),
|
||||
ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)).getBlockPos())));
|
||||
|
||||
// todo marlin
|
||||
// if (stack.is(ModItems.MARLIN.get())) {
|
||||
// ModUtils.queueServerWork((int) (5 + 1.5 * shooterHeight), () -> SoundTool.playLocalSound(serverPlayer, ModSounds.SHELL_CASING_NORMAL.get(), (float) Math.max(1.5 - 0.2 * shooterHeight, 0), 1));
|
||||
// }
|
||||
if (stack.is(ModItems.MARLIN.get())) {
|
||||
ModUtils.queueServerWork((int) (5 + 1.5 * shooterHeight), () -> SoundTool.playLocalSound(serverPlayer, ModSounds.SHELL_CASING_NORMAL.get(), (float) Math.max(1.5 - 0.2 * shooterHeight, 0), 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package com.atsuishio.superbwarfare.event;
|
||||
|
||||
import com.atsuishio.superbwarfare.tools.HitboxHelper;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.fml.loading.FMLEnvironment;
|
||||
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
|
||||
import net.neoforged.neoforge.event.tick.PlayerTickEvent;
|
||||
|
||||
@EventBusSubscriber
|
||||
public class HitboxHelperEvent {
|
||||
@SubscribeEvent(receiveCanceled = true)
|
||||
public static void onPlayerTick(PlayerTickEvent.Post event) {
|
||||
if (FMLEnvironment.dist == Dist.DEDICATED_SERVER) {
|
||||
HitboxHelper.onPlayerTick(event.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent(receiveCanceled = true)
|
||||
public static void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) {
|
||||
HitboxHelper.onPlayerLoggedOut(event.getEntity());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.atsuishio.superbwarfare.event;
|
||||
|
||||
import com.atsuishio.superbwarfare.tools.PlayerKillRecord;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.client.event.ClientTickEvent;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Queue;
|
||||
|
||||
@EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME, value = Dist.CLIENT)
|
||||
public class KillMessageHandler {
|
||||
|
||||
public static Queue<PlayerKillRecord> QUEUE = new ArrayDeque<>();
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onClientTick(ClientTickEvent.Post event) {
|
||||
for (PlayerKillRecord record : QUEUE) {
|
||||
if (record.freeze && record.tick >= 3) {
|
||||
continue;
|
||||
}
|
||||
record.tick++;
|
||||
if (record.fastRemove && record.tick >= 82 || record.tick >= 100) {
|
||||
QUEUE.poll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,881 @@
|
|||
package com.atsuishio.superbwarfare.event;
|
||||
|
||||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||
import com.atsuishio.superbwarfare.capability.player.PlayerVariable;
|
||||
import com.atsuishio.superbwarfare.config.common.GameplayConfig;
|
||||
import com.atsuishio.superbwarfare.config.server.MiscConfig;
|
||||
import com.atsuishio.superbwarfare.config.server.VehicleConfig;
|
||||
import com.atsuishio.superbwarfare.entity.ICustomKnockback;
|
||||
import com.atsuishio.superbwarfare.entity.TargetEntity;
|
||||
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.LaserTowerEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.ContainerMobileVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
||||
import com.atsuishio.superbwarfare.event.events.PreKillEvent;
|
||||
import com.atsuishio.superbwarfare.init.*;
|
||||
import com.atsuishio.superbwarfare.item.gun.GunItem;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.perk.AmmoPerk;
|
||||
import com.atsuishio.superbwarfare.perk.Perk;
|
||||
import com.atsuishio.superbwarfare.perk.PerkHelper;
|
||||
import com.atsuishio.superbwarfare.tools.*;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.game.ClientboundStopSoundPacket;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.damagesource.DamageType;
|
||||
import net.minecraft.world.damagesource.DamageTypes;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.projectile.Projectile;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import net.minecraft.world.level.block.entity.HopperBlockEntity;
|
||||
import net.minecraftforge.event.entity.living.*;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.common.util.TriState;
|
||||
import net.neoforged.neoforge.event.entity.living.*;
|
||||
import net.neoforged.neoforge.event.entity.player.ItemEntityPickupEvent;
|
||||
import net.neoforged.neoforge.network.PacketDistributor;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@EventBusSubscriber
|
||||
public class LivingEventHandler {
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onEntityAttacked(LivingIncomingDamageEvent event) {
|
||||
if (!event.getSource().is(ModDamageTypes.VEHICLE_EXPLOSION) && event.getEntity().getVehicle() instanceof VehicleEntity vehicle) {
|
||||
if (event.getEntity().getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.hidePassenger(event.getEntity())) {
|
||||
if (!(event.getSource().is(DamageTypes.EXPLOSION)
|
||||
|| event.getSource().is(DamageTypes.PLAYER_EXPLOSION)
|
||||
|| event.getSource().is(ModDamageTypes.CUSTOM_EXPLOSION)
|
||||
|| event.getSource().is(ModDamageTypes.MINE)
|
||||
|| event.getSource().is(ModDamageTypes.PROJECTILE_BOOM))) {
|
||||
vehicle.hurt(event.getSource(), event.getContainer().getOriginalDamage());
|
||||
}
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onEntityHurt(LivingIncomingDamageEvent event) {
|
||||
if (event == null) return;
|
||||
|
||||
handleVehicleHurt(event);
|
||||
handleGunPerksWhenHurt(event);
|
||||
renderDamageIndicator(event);
|
||||
reduceBulletDamage(event);
|
||||
giveExpToWeapon(event);
|
||||
handleGunLevels(event);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onEntityDeath(LivingDeathEvent event) {
|
||||
if (event == null) return;
|
||||
|
||||
killIndication(event);
|
||||
handleGunPerksWhenDeath(event);
|
||||
handlePlayerKillEntity(event);
|
||||
handlePlayerDeathDropAmmo(event.getEntity());
|
||||
giveKillExpToWeapon(event);
|
||||
|
||||
if (event.getEntity() instanceof Player player) {
|
||||
handlePlayerBeamReset(player);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleVehicleHurt(LivingIncomingDamageEvent event) {
|
||||
var vehicle = event.getEntity().getVehicle();
|
||||
if (vehicle instanceof VehicleEntity) {
|
||||
if (vehicle instanceof ArmedVehicleEntity iArmedVehicle) {
|
||||
if (iArmedVehicle.hidePassenger(event.getEntity())) {
|
||||
if (!event.getSource().is(ModDamageTypes.VEHICLE_EXPLOSION)) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
} else {
|
||||
if (!(event.getSource().is(DamageTypes.EXPLOSION)
|
||||
|| event.getSource().is(DamageTypes.PLAYER_EXPLOSION)
|
||||
|| event.getSource().is(ModDamageTypes.CUSTOM_EXPLOSION)
|
||||
|| event.getSource().is(ModDamageTypes.MINE)
|
||||
|| event.getSource().is(ModDamageTypes.PROJECTILE_BOOM))) {
|
||||
vehicle.hurt(event.getSource(), 0.7f * event.getAmount());
|
||||
}
|
||||
|
||||
event.setAmount(0.3f * event.getAmount());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算子弹伤害衰减
|
||||
*/
|
||||
private static void reduceBulletDamage(LivingIncomingDamageEvent event) {
|
||||
DamageSource source = event.getSource();
|
||||
LivingEntity entity = event.getEntity();
|
||||
Entity sourceEntity = source.getEntity();
|
||||
if (sourceEntity == null) return;
|
||||
|
||||
double amount = event.getAmount();
|
||||
double damage = amount;
|
||||
|
||||
ItemStack stack = sourceEntity instanceof LivingEntity living ? living.getMainHandItem() : ItemStack.EMPTY;
|
||||
var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO);
|
||||
|
||||
// 距离衰减
|
||||
if (DamageTypeTool.isGunDamage(source)) {
|
||||
double distance = entity.position().distanceTo(sourceEntity.position());
|
||||
|
||||
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO)) {
|
||||
if (perk instanceof AmmoPerk ammoPerk && ammoPerk.slug) {
|
||||
damage = reduceDamageByDistance(amount, distance, 0.015, 30);
|
||||
} else {
|
||||
damage = reduceDamageByDistance(amount, distance, 0.05, 15);
|
||||
}
|
||||
} else if (stack.is(ModTags.Items.USE_SNIPER_AMMO)) {
|
||||
damage = reduceDamageByDistance(amount, distance, 0.001, 150);
|
||||
} else if (stack.is(ModTags.Items.USE_HEAVY_AMMO)) {
|
||||
damage = reduceDamageByDistance(amount, distance, 0.0007, 250);
|
||||
} else if (stack.is(ModTags.Items.USE_HANDGUN_AMMO)) {
|
||||
damage = reduceDamageByDistance(amount, distance, 0.03, 40);
|
||||
} else if (stack.is(ModTags.Items.SMG)) {
|
||||
damage = reduceDamageByDistance(amount, distance, 0.02, 50);
|
||||
} else if (stack.is(ModTags.Items.USE_RIFLE_AMMO) || stack.getItem() == ModItems.BOCEK.get()) {
|
||||
damage = reduceDamageByDistance(amount, distance, 0.007, 100);
|
||||
}
|
||||
}
|
||||
|
||||
// 计算防弹插板减伤
|
||||
ItemStack armor = entity.getItemBySlot(EquipmentSlot.CHEST);
|
||||
var tag = NBTTool.getTag(armor);
|
||||
|
||||
if (armor != ItemStack.EMPTY && tag != null && tag.contains("ArmorPlate")) {
|
||||
double armorValue;
|
||||
armorValue = tag.getDouble("ArmorPlate");
|
||||
tag.putDouble("ArmorPlate", Math.max(tag.getDouble("ArmorPlate") - damage, 0));
|
||||
damage = Math.max(damage - armorValue, 0);
|
||||
}
|
||||
|
||||
// 计算防弹护具减伤
|
||||
if (source.is(ModTags.DamageTypes.PROJECTILE) || source.is(DamageTypes.MOB_PROJECTILE)) {
|
||||
damage *= 1 - 0.8 * Mth.clamp(entity.getAttributeValue(ModAttributes.BULLET_RESISTANCE), 0, 1);
|
||||
}
|
||||
|
||||
if (source.is(ModTags.DamageTypes.PROJECTILE_ABSOLUTE)) {
|
||||
damage *= 1 - 0.2 * Mth.clamp(entity.getAttributeValue(ModAttributes.BULLET_RESISTANCE), 0, 1);
|
||||
}
|
||||
|
||||
if (source.is(ModDamageTypes.PROJECTILE_BOOM) || source.is(ModDamageTypes.MINE) || source.is(ModDamageTypes.CANNON_FIRE) || source.is(ModDamageTypes.CUSTOM_EXPLOSION)
|
||||
|| source.is(DamageTypes.EXPLOSION) || source.is(DamageTypes.PLAYER_EXPLOSION)) {
|
||||
damage *= 1 - 0.3 * Mth.clamp(entity.getAttributeValue(ModAttributes.BULLET_RESISTANCE), 0, 1);
|
||||
}
|
||||
|
||||
event.setAmount((float) damage);
|
||||
|
||||
if (entity instanceof TargetEntity && sourceEntity instanceof Player player) {
|
||||
player.displayClientMessage(Component.translatable("tips.superbwarfare.target.damage",
|
||||
FormatTool.format2D(damage),
|
||||
FormatTool.format1D(entity.position().distanceTo(sourceEntity.position())), "m"), false);
|
||||
}
|
||||
}
|
||||
|
||||
private static double reduceDamageByDistance(double amount, double distance, double rate, double minDistance) {
|
||||
return amount / (1 + rate * Math.max(0, distance - minDistance));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据造成的伤害,提供武器经验
|
||||
*/
|
||||
private static void giveExpToWeapon(LivingIncomingDamageEvent event) {
|
||||
DamageSource source = event.getSource();
|
||||
Entity sourceEntity = source.getEntity();
|
||||
if (!(sourceEntity instanceof Player player)) return;
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
if (!stack.is(ModTags.Items.GUN)) return;
|
||||
if (event.getEntity() instanceof TargetEntity) return;
|
||||
|
||||
double amount = Math.min(0.125 * event.getAmount(), event.getEntity().getMaxHealth());
|
||||
|
||||
// 先处理发射器类武器或高爆弹的爆炸伤害
|
||||
if (source.is(ModDamageTypes.PROJECTILE_BOOM)) {
|
||||
if (stack.is(ModTags.Items.LAUNCHER)
|
||||
// TODO perk
|
||||
// || PerkHelper.getItemPerkLevel(ModPerks.HE_BULLET.get(), stack) > 0
|
||||
) {
|
||||
GunsTool.setGunDoubleTag(stack, "Exp", GunsTool.getGunDoubleTag(stack, "Exp", 0) + amount);
|
||||
}
|
||||
}
|
||||
|
||||
// 再判断是不是枪械能造成的伤害
|
||||
if (!DamageTypeTool.isGunDamage(source)) return;
|
||||
|
||||
GunsTool.setGunDoubleTag(stack, "Exp", GunsTool.getGunDoubleTag(stack, "Exp", 0) + amount);
|
||||
}
|
||||
|
||||
private static void giveKillExpToWeapon(LivingDeathEvent event) {
|
||||
DamageSource source = event.getSource();
|
||||
Entity sourceEntity = source.getEntity();
|
||||
if (!(sourceEntity instanceof Player player)) return;
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
if (!stack.is(ModTags.Items.GUN)) return;
|
||||
if (event.getEntity() instanceof TargetEntity) return;
|
||||
|
||||
double amount = 20 + 2 * event.getEntity().getMaxHealth();
|
||||
|
||||
// 先处理发射器类武器或高爆弹的爆炸伤害
|
||||
if (source.is(ModDamageTypes.PROJECTILE_BOOM)) {
|
||||
if (stack.is(ModTags.Items.LAUNCHER)
|
||||
// TODO perk
|
||||
// || PerkHelper.getItemPerkLevel(ModPerks.HE_BULLET.get(), stack) > 0
|
||||
) {
|
||||
GunsTool.setGunDoubleTag(stack, "Exp", GunsTool.getGunDoubleTag(stack, "Exp", 0) + amount);
|
||||
}
|
||||
}
|
||||
|
||||
// 再判断是不是枪械能造成的伤害
|
||||
if (DamageTypeTool.isGunDamage(source)) {
|
||||
GunsTool.setGunDoubleTag(stack, "Exp", GunsTool.getGunDoubleTag(stack, "Exp", 0) + amount);
|
||||
}
|
||||
|
||||
// 提升武器等级
|
||||
int level = GunsTool.getGunIntTag(stack, "Level", 0);
|
||||
double exp = GunsTool.getGunDoubleTag(stack, "Exp", 0);
|
||||
double upgradeExpNeeded = 20 * Math.pow(level, 2) + 160 * level + 20;
|
||||
|
||||
while (exp >= upgradeExpNeeded) {
|
||||
exp -= upgradeExpNeeded;
|
||||
level = GunsTool.getGunIntTag(stack, "Level", 0) + 1;
|
||||
upgradeExpNeeded = 20 * Math.pow(level, 2) + 160 * level + 20;
|
||||
GunsTool.setGunDoubleTag(stack, "Exp", exp);
|
||||
GunsTool.setGunIntTag(stack, "Level", level);
|
||||
GunsTool.setGunDoubleTag(stack, "UpgradePoint", GunsTool.getGunDoubleTag(stack, "UpgradePoint", 0) + 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleGunLevels(LivingIncomingDamageEvent event) {
|
||||
DamageSource source = event.getSource();
|
||||
Entity sourceEntity = source.getEntity();
|
||||
if (!(sourceEntity instanceof Player player)) return;
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
if (!stack.is(ModTags.Items.GUN)) return;
|
||||
if (event.getEntity() instanceof TargetEntity) return;
|
||||
|
||||
int level = GunsTool.getGunIntTag(stack, "Level", 0);
|
||||
double exp = GunsTool.getGunDoubleTag(stack, "Exp", 0);
|
||||
double upgradeExpNeeded = 20 * Math.pow(level, 2) + 160 * level + 20;
|
||||
|
||||
while (exp >= upgradeExpNeeded) {
|
||||
exp -= upgradeExpNeeded;
|
||||
level = GunsTool.getGunIntTag(stack, "Level", 0) + 1;
|
||||
upgradeExpNeeded = 20 * Math.pow(level, 2) + 160 * level + 20;
|
||||
GunsTool.setGunDoubleTag(stack, "Exp", exp);
|
||||
GunsTool.setGunIntTag(stack, "Level", level);
|
||||
GunsTool.setGunDoubleTag(stack, "UpgradePoint", GunsTool.getGunDoubleTag(stack, "UpgradePoint", 0) + 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
private static void killIndication(LivingDeathEvent event) {
|
||||
DamageSource source = event.getSource();
|
||||
|
||||
var sourceEntity = source.getEntity();
|
||||
if (sourceEntity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果配置不选择全局伤害提示,则只在伤害类型为mod添加的时显示指示器
|
||||
if (!GameplayConfig.GLOBAL_INDICATION.get() && !DamageTypeTool.isModDamage(source)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sourceEntity.level().isClientSide() && sourceEntity instanceof ServerPlayer player) {
|
||||
// TODO pre kill event
|
||||
// if (NeoForge.EVENT_BUS.post(new PreKillEvent.Indicator(player, source, event.getEntity()))) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
SoundTool.playLocalSound(player, ModSounds.TARGET_DOWN.get(), 3f, 1f);
|
||||
PacketDistributor.sendToPlayer(player, new ClientIndicatorMessage(2, 8));
|
||||
}
|
||||
}
|
||||
|
||||
private static void renderDamageIndicator(LivingIncomingDamageEvent event) {
|
||||
if (event == null) return;
|
||||
|
||||
var damagesource = event.getSource();
|
||||
var sourceEntity = damagesource.getEntity();
|
||||
|
||||
if (sourceEntity == null) return;
|
||||
|
||||
if (sourceEntity instanceof ServerPlayer player && (damagesource.is(DamageTypes.EXPLOSION) || damagesource.is(DamageTypes.PLAYER_EXPLOSION)
|
||||
|| damagesource.is(ModDamageTypes.MINE) || damagesource.is(ModDamageTypes.PROJECTILE_BOOM))) {
|
||||
SoundTool.playLocalSound(player, ModSounds.INDICATION.get(), 1f, 1f);
|
||||
PacketDistributor.sendToPlayer(player, new ClientIndicatorMessage(0, 5));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 换弹时切换枪械,取消换弹音效播放
|
||||
*/
|
||||
@SubscribeEvent
|
||||
public static void handleChangeSlot(LivingEquipmentChangeEvent event) {
|
||||
if (event.getEntity() instanceof Player player && event.getSlot() == EquipmentSlot.MAINHAND) {
|
||||
if (player.level().isClientSide) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack oldStack = event.getFrom();
|
||||
ItemStack newStack = event.getTo();
|
||||
|
||||
var laserCap = player.getCapability(ModCapabilities.LASER_CAPABILITY);
|
||||
if (laserCap != null) laserCap.stop();
|
||||
|
||||
var oldTag = NBTTool.getTag(oldStack);
|
||||
var newTag = NBTTool.getTag(newStack);
|
||||
if (player instanceof ServerPlayer serverPlayer) {
|
||||
if (newStack.getItem() != oldStack.getItem()
|
||||
|| (newStack.is(ModTags.Items.GUN) && !GunsTool.getGunData(newStack).hasUUID("UUID"))
|
||||
|| (oldStack.is(ModTags.Items.GUN) && !GunsTool.getGunData(oldStack).hasUUID("UUID"))
|
||||
|| (newStack.is(ModTags.Items.GUN) && oldStack.is(ModTags.Items.GUN) && !Objects.equals(GunsTool.getGunUUID(newStack), GunsTool.getGunUUID(oldStack)))
|
||||
) {
|
||||
if (oldStack.getItem() instanceof GunItem oldGun) {
|
||||
stopGunReloadSound(serverPlayer, oldGun);
|
||||
|
||||
CompoundTag data = oldTag.getCompound("GunData");
|
||||
|
||||
if (GunsTool.getGunDoubleTag(oldStack, "BoltActionTime", 0) > 0) {
|
||||
data.putInt("BoltActionTick", 0);
|
||||
}
|
||||
|
||||
data.putInt("ReloadTime", 0);
|
||||
oldTag.put("GunData", data);
|
||||
|
||||
oldTag.putBoolean("is_normal_reloading", false);
|
||||
oldTag.putBoolean("is_empty_reloading", false);
|
||||
|
||||
if (GunsTool.getGunIntTag(oldStack, "IterativeTime", 0) != 0) {
|
||||
oldTag.putBoolean("force_stop", false);
|
||||
oldTag.putBoolean("stop", false);
|
||||
oldTag.putInt("reload_stage", 0);
|
||||
data.putBoolean("Reloading", false);
|
||||
oldTag.putDouble("prepare", 0);
|
||||
oldTag.putDouble("prepare_load", 0);
|
||||
oldTag.putDouble("iterative", 0);
|
||||
oldTag.putDouble("finish", 0);
|
||||
}
|
||||
NBTTool.saveTag(oldStack, oldTag);
|
||||
|
||||
if (oldStack.is(ModItems.SENTINEL.get())) {
|
||||
data.putBoolean("Charging", false);
|
||||
data.putInt("ChargeTime", 0);
|
||||
}
|
||||
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap != null) {
|
||||
cap.edit = false;
|
||||
cap.syncPlayerVariables(player);
|
||||
}
|
||||
}
|
||||
|
||||
if (newStack.getItem() instanceof GunItem) {
|
||||
player.getPersistentData().putDouble("noRun", 40);
|
||||
newTag.putBoolean("draw", true);
|
||||
if (GunsTool.getGunIntTag(newStack, "BoltActionTime", 0) > 0) {
|
||||
GunsTool.setGunIntTag(newStack, "BoltActionTick", 0);
|
||||
}
|
||||
newTag.putBoolean("is_normal_reloading", false);
|
||||
newTag.putBoolean("is_empty_reloading", false);
|
||||
|
||||
CompoundTag data = newTag.getCompound("GunData");
|
||||
data.putInt("ReloadTime", 0);
|
||||
newTag.put("GunData", data);
|
||||
|
||||
if (GunsTool.getGunIntTag(newStack, "IterativeTime", 0) != 0) {
|
||||
newTag.putBoolean("force_stop", false);
|
||||
newTag.putBoolean("stop", false);
|
||||
newTag.putInt("reload_stage", 0);
|
||||
GunsTool.setGunBooleanTag(newStack, "Reloading", false);
|
||||
newTag.putDouble("prepare", 0);
|
||||
newTag.putDouble("prepare_load", 0);
|
||||
newTag.putDouble("iterative", 0);
|
||||
newTag.putDouble("finish", 0);
|
||||
}
|
||||
|
||||
if (newStack.is(ModItems.SENTINEL.get())) {
|
||||
GunsTool.setGunBooleanTag(newStack, "Charging", false);
|
||||
GunsTool.setGunIntTag(newStack, "ChargeTime", 0);
|
||||
}
|
||||
NBTTool.saveTag(newStack, newTag);
|
||||
|
||||
// TODO perk
|
||||
// int level = PerkHelper.getItemPerkLevel(ModPerks.KILLING_TALLY.get(), newStack);
|
||||
// if (level != 0) {
|
||||
// GunsTool.setPerkIntTag(newStack, "KillingTally", 0);
|
||||
// }
|
||||
//
|
||||
// if (player.level() instanceof ServerLevel) {
|
||||
// ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new DrawClientMessage(true));
|
||||
// }
|
||||
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap != null) {
|
||||
cap.tacticalSprint = false;
|
||||
cap.syncPlayerVariables(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void stopGunReloadSound(ServerPlayer player, GunItem gun) {
|
||||
gun.getReloadSound().forEach(sound -> {
|
||||
var clientboundstopsoundpacket = new ClientboundStopSoundPacket(sound.getLocation(), SoundSource.PLAYERS);
|
||||
player.connection.send(clientboundstopsoundpacket);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送击杀消息
|
||||
*/
|
||||
private static void handlePlayerKillEntity(LivingDeathEvent event) {
|
||||
LivingEntity entity = event.getEntity();
|
||||
DamageSource source = event.getSource();
|
||||
|
||||
ResourceKey<DamageType> damageTypeResourceKey = source.typeHolder().unwrapKey().isPresent() ? source.typeHolder().unwrapKey().get() : DamageTypes.GENERIC;
|
||||
|
||||
ServerPlayer attacker = null;
|
||||
if (source.getEntity() instanceof ServerPlayer player) {
|
||||
attacker = player;
|
||||
}
|
||||
if (source.getDirectEntity() instanceof Projectile projectile && projectile.getOwner() instanceof ServerPlayer player) {
|
||||
attacker = player;
|
||||
}
|
||||
|
||||
// TODO pre kill event
|
||||
// if (NeoForge.EVENT_BUS.post(new PreKillEvent.SendKillMessage(attacker, source, entity))) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (attacker != null && MiscConfig.SEND_KILL_FEEDBACK.get()) {
|
||||
if (DamageTypeTool.isHeadshotDamage(source)) {
|
||||
// TODO player gun kill msg
|
||||
// ModUtils.PACKET_HANDLER.send(PacketDistributor.ALL.noArg(), new PlayerGunKillMessage(attacker.getId(), entity.getId(), true, damageTypeResourceKey));
|
||||
} else {
|
||||
// ModUtils.PACKET_HANDLER.send(PacketDistributor.ALL.noArg(), new PlayerGunKillMessage(attacker.getId(), entity.getId(), false, damageTypeResourceKey));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleGunPerksWhenHurt(LivingIncomingDamageEvent event) {
|
||||
DamageSource source = event.getSource();
|
||||
|
||||
Player attacker = null;
|
||||
if (source.getEntity() instanceof Player player) {
|
||||
attacker = player;
|
||||
}
|
||||
if (source.getDirectEntity() instanceof Projectile projectile && projectile.getOwner() instanceof Player player) {
|
||||
attacker = player;
|
||||
}
|
||||
|
||||
if (attacker == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack stack = attacker.getMainHandItem();
|
||||
if (!stack.is(ModTags.Items.GUN)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (DamageTypeTool.isGunDamage(source) || source.is(ModDamageTypes.PROJECTILE_BOOM)) {
|
||||
handleKillClipDamage(stack, event);
|
||||
handleVorpalWeaponDamage(stack, event);
|
||||
}
|
||||
|
||||
if (DamageTypeTool.isGunFireDamage(source) && source.getDirectEntity() instanceof ProjectileEntity projectile && projectile.isZoom()) {
|
||||
handleGutshotStraightDamage(stack, event);
|
||||
}
|
||||
|
||||
if (DamageTypeTool.isGunDamage(source)) {
|
||||
handleKillingTallyDamage(stack, event);
|
||||
}
|
||||
|
||||
if (DamageTypeTool.isGunFireDamage(source)) {
|
||||
handleHeadSeekerTime(stack);
|
||||
}
|
||||
|
||||
if (source.getDirectEntity() instanceof ProjectileEntity projectile) {
|
||||
// TODO perk
|
||||
// if (PerkHelper.getItemPerkLevel(ModPerks.FOURTH_TIMES_CHARM.get(), stack) > 0) {
|
||||
// float bypassArmorRate = projectile.getBypassArmorRate();
|
||||
// if (bypassArmorRate >= 1.0f && source.is(ModDamageTypes.GUN_FIRE_HEADSHOT_ABSOLUTE)) {
|
||||
// handleFourthTimesCharm(stack);
|
||||
// } else if (source.is(ModDamageTypes.GUN_FIRE_HEADSHOT)) {
|
||||
// handleFourthTimesCharm(stack);
|
||||
// }
|
||||
// }
|
||||
|
||||
if (!projectile.isZoom()) {
|
||||
handleFieldDoctor(stack, event, attacker);
|
||||
}
|
||||
}
|
||||
|
||||
if (DamageTypeTool.isHeadshotDamage(source)) {
|
||||
handleHeadSeekerDamage(stack, event);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleGunPerksWhenDeath(LivingDeathEvent event) {
|
||||
DamageSource source = event.getSource();
|
||||
|
||||
Player attacker = null;
|
||||
if (source.getEntity() instanceof Player player) {
|
||||
attacker = player;
|
||||
}
|
||||
if (source.getDirectEntity() instanceof Projectile projectile && projectile.getOwner() instanceof Player player) {
|
||||
attacker = player;
|
||||
}
|
||||
|
||||
if (attacker == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack stack = attacker.getMainHandItem();
|
||||
if (!stack.is(ModTags.Items.GUN)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (DamageTypeTool.isGunDamage(source) || source.is(ModDamageTypes.PROJECTILE_BOOM)) {
|
||||
handleClipPerks(stack);
|
||||
}
|
||||
|
||||
if (DamageTypeTool.isGunDamage(source)) {
|
||||
handleKillingTallyAddCount(stack);
|
||||
handleSubsistence(stack, attacker);
|
||||
}
|
||||
|
||||
if (DamageTypeTool.isHeadshotDamage(source)) {
|
||||
handleDesperado(stack);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleClipPerks(ItemStack stack) {
|
||||
// TODO perk
|
||||
// int healClipLevel = PerkHelper.getItemPerkLevel(ModPerks.HEAL_CLIP.get(), stack);
|
||||
// if (healClipLevel != 0) {
|
||||
// GunsTool.setPerkIntTag(stack, "HealClipTime", 80 + healClipLevel * 20);
|
||||
// }
|
||||
//
|
||||
// int killClipLevel = PerkHelper.getItemPerkLevel(ModPerks.KILL_CLIP.get(), stack);
|
||||
// if (killClipLevel != 0) {
|
||||
// GunsTool.setPerkIntTag(stack, "KillClipReloadTime", 80);
|
||||
// }
|
||||
}
|
||||
|
||||
private static void handleKillClipDamage(ItemStack stack, LivingIncomingDamageEvent event) {
|
||||
// TODO perk
|
||||
// if (GunsTool.getPerkIntTag(stack, "KillClipTime") > 0) {
|
||||
// int level = PerkHelper.getItemPerkLevel(ModPerks.KILL_CLIP.get(), stack);
|
||||
// if (level == 0) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// event.setAmount(event.getAmount() * (1.2f + 0.05f * level));
|
||||
// }
|
||||
}
|
||||
|
||||
private static void handleGutshotStraightDamage(ItemStack stack, LivingIncomingDamageEvent event) {
|
||||
// TODO perk
|
||||
// int level = PerkHelper.getItemPerkLevel(ModPerks.GUTSHOT_STRAIGHT.get(), stack);
|
||||
// if (level == 0) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// event.setAmount(event.getAmount() * (1.15f + 0.05f * level));
|
||||
}
|
||||
|
||||
private static void handleKillingTallyDamage(ItemStack stack, LivingIncomingDamageEvent event) {
|
||||
// TODO perk
|
||||
// int level = PerkHelper.getItemPerkLevel(ModPerks.KILLING_TALLY.get(), stack);
|
||||
// if (level == 0) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// int killTally = GunsTool.getPerkIntTag(stack, "KillingTally");
|
||||
// if (killTally == 0) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// event.setAmount(event.getAmount() * (1.0f + (0.1f * level) * killTally));
|
||||
}
|
||||
|
||||
private static void handleKillingTallyAddCount(ItemStack stack) {
|
||||
// TODO perk
|
||||
// int level = PerkHelper.getItemPerkLevel(ModPerks.KILLING_TALLY.get(), stack);
|
||||
// if (level != 0) {
|
||||
// GunsTool.setPerkIntTag(stack, "KillingTally", Math.min(3, GunsTool.getPerkIntTag(stack, "KillingTally") + 1));
|
||||
// }
|
||||
}
|
||||
|
||||
private static void handleFourthTimesCharm(ItemStack stack) {
|
||||
// TODO perk
|
||||
// int level = PerkHelper.getItemPerkLevel(ModPerks.FOURTH_TIMES_CHARM.get(), stack);
|
||||
// if (level == 0) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// int fourthTimesCharmTick = GunsTool.getPerkIntTag(stack, "FourthTimesCharmTick");
|
||||
// if (fourthTimesCharmTick <= 0) {
|
||||
// GunsTool.setPerkIntTag(stack, "FourthTimesCharmTick", 40 + 10 * level);
|
||||
// GunsTool.setPerkIntTag(stack, "FourthTimesCharmCount", 1);
|
||||
// } else {
|
||||
// int count = GunsTool.getPerkIntTag(stack, "FourthTimesCharmCount");
|
||||
// if (count < 4) {
|
||||
// GunsTool.setPerkIntTag(stack, "FourthTimesCharmCount", Math.min(4, count + 1));
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private static void handleSubsistence(ItemStack stack, Player player) {
|
||||
// TODO perk
|
||||
// int level = PerkHelper.getItemPerkLevel(ModPerks.SUBSISTENCE.get(), stack);
|
||||
// if (level == 0) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// float rate = level * 0.1f + (stack.is(ModTags.Items.SMG) || stack.is(ModTags.Items.RIFLE) ? 0.07f : 0f);
|
||||
float rate = 1;
|
||||
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap == null) return;
|
||||
|
||||
int mag = GunsTool.getGunIntTag(stack, "Magazine", 0) + GunsTool.getGunIntTag(stack, "CustomMagazine", 0);
|
||||
int ammo = GunsTool.getGunIntTag(stack, "Ammo", 0);
|
||||
int ammoReload = (int) Math.min(mag, mag * rate);
|
||||
int ammoNeed = Math.min(mag - ammo, ammoReload);
|
||||
|
||||
boolean flag = InventoryTool.hasCreativeAmmoBox(player);
|
||||
|
||||
if (stack.is(ModTags.Items.USE_RIFLE_AMMO)) {
|
||||
int ammoFinal = Math.min(cap.rifleAmmo, ammoNeed);
|
||||
if (flag) {
|
||||
ammoFinal = ammoNeed;
|
||||
} else {
|
||||
cap.rifleAmmo -= ammoFinal;
|
||||
}
|
||||
GunsTool.setGunIntTag(stack, "Ammo", Math.min(mag, ammo + ammoFinal));
|
||||
} else if (stack.is(ModTags.Items.USE_HANDGUN_AMMO)) {
|
||||
int ammoFinal = Math.min(cap.handgunAmmo, ammoNeed);
|
||||
if (flag) {
|
||||
ammoFinal = ammoNeed;
|
||||
} else {
|
||||
cap.handgunAmmo -= ammoFinal;
|
||||
}
|
||||
GunsTool.setGunIntTag(stack, "Ammo", Math.min(mag, ammo + ammoFinal));
|
||||
}
|
||||
cap.syncPlayerVariables(player);
|
||||
}
|
||||
|
||||
|
||||
private static void handleFieldDoctor(ItemStack stack, LivingIncomingDamageEvent event, Player player) {
|
||||
// TODO perk
|
||||
// int level = PerkHelper.getItemPerkLevel(ModPerks.FIELD_DOCTOR.get(), stack);
|
||||
// if (level == 0) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (event.getEntity().isAlliedTo(player)) {
|
||||
// event.getEntity().heal(event.getAmount() * Math.min(1.0f, 0.25f + 0.05f * level));
|
||||
// event.setCanceled(true);
|
||||
// }
|
||||
}
|
||||
|
||||
private static void handleHeadSeekerTime(ItemStack stack) {
|
||||
// TODO perk
|
||||
// int level = PerkHelper.getItemPerkLevel(ModPerks.HEAD_SEEKER.get(), stack);
|
||||
// if (level == 0) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// GunsTool.setPerkIntTag(stack, "HeadSeeker", 11 + level * 2);
|
||||
}
|
||||
|
||||
private static void handleHeadSeekerDamage(ItemStack stack, LivingIncomingDamageEvent event) {
|
||||
// TODO perk
|
||||
// int level = PerkHelper.getItemPerkLevel(ModPerks.HEAD_SEEKER.get(), stack);
|
||||
// if (level == 0) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (GunsTool.getPerkIntTag(stack, "HeadSeeker") > 0) {
|
||||
// event.setAmount(event.getAmount() * (1.095f + 0.0225f * level));
|
||||
// }
|
||||
}
|
||||
|
||||
private static void handleDesperado(ItemStack stack) {
|
||||
// TODO perk
|
||||
// int level = PerkHelper.getItemPerkLevel(ModPerks.DESPERADO.get(), stack);
|
||||
// if (level == 0) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// GunsTool.setPerkIntTag(stack, "DesperadoTime", 90 + level * 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启死亡掉落时掉落一个弹药盒
|
||||
*/
|
||||
private static void handlePlayerDeathDropAmmo(LivingEntity entity) {
|
||||
if (!entity.level().getLevelData().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) && entity instanceof Player player) {
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap == null) cap = new PlayerVariable();
|
||||
|
||||
boolean drop = cap.rifleAmmo + cap.handgunAmmo + cap.shotgunAmmo + cap.sniperAmmo + cap.heavyAmmo > 0;
|
||||
|
||||
if (drop) {
|
||||
ItemStack stack = new ItemStack(ModItems.AMMO_BOX.get());
|
||||
CompoundTag tag = NBTTool.getTag(stack);
|
||||
|
||||
for (var type : AmmoType.values()) {
|
||||
type.set(tag, type.get(cap));
|
||||
type.set(cap, 0);
|
||||
}
|
||||
tag.putBoolean("IsDrop", true);
|
||||
NBTTool.saveTag(stack, tag);
|
||||
cap.syncPlayerVariables(player);
|
||||
|
||||
if (player.level() instanceof ServerLevel level) {
|
||||
ItemEntity itemEntity = new ItemEntity(level, player.getX(), player.getY() + 1, player.getZ(), stack);
|
||||
itemEntity.setPickUpDelay(10);
|
||||
level.addFreshEntity(itemEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPickup(ItemEntityPickupEvent.Pre event) {
|
||||
if (!VehicleConfig.VEHICLE_ITEM_PICKUP.get()) return;
|
||||
if (event.getPlayer().getVehicle() instanceof ContainerMobileVehicleEntity containerMobileVehicleEntity) {
|
||||
var pickUp = event.getItemEntity();
|
||||
if (!containerMobileVehicleEntity.level().isClientSide) {
|
||||
HopperBlockEntity.addItem(containerMobileVehicleEntity, pickUp);
|
||||
}
|
||||
event.setCanPickup(TriState.FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onLivingDrops(LivingDropsEvent event) {
|
||||
DamageSource source = event.getSource();
|
||||
Entity sourceEntity = source.getEntity();
|
||||
if (!(sourceEntity instanceof Player player)) return;
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
|
||||
if (player.getVehicle() instanceof ContainerMobileVehicleEntity containerMobileVehicleEntity && source.is(ModDamageTypes.VEHICLE_STRIKE)) {
|
||||
var drops = event.getDrops();
|
||||
drops.forEach(itemEntity -> {
|
||||
ItemStack item = itemEntity.getItem();
|
||||
if (!HopperBlockEntity.addItem(containerMobileVehicleEntity, itemEntity)) {
|
||||
player.drop(item, false);
|
||||
}
|
||||
});
|
||||
event.setCanceled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO perk
|
||||
// if (stack.is(ModTags.Items.GUN) && PerkHelper.getItemPerkLevel(ModPerks.POWERFUL_ATTRACTION.get(), stack) > 0 && (DamageTypeTool.isGunDamage(source) || DamageTypeTool.isExplosionDamage(source))) {
|
||||
// var drops = event.getDrops();
|
||||
// drops.forEach(itemEntity -> {
|
||||
// ItemStack item = itemEntity.getItem();
|
||||
// if (!player.addItem(item)) {
|
||||
// player.drop(item, false);
|
||||
// }
|
||||
// });
|
||||
// event.setCanceled(true);
|
||||
// }
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onLivingExperienceDrop(LivingExperienceDropEvent event) {
|
||||
Player player = event.getAttackingPlayer();
|
||||
if (player == null) return;
|
||||
|
||||
if (player.getVehicle() instanceof ArmedVehicleEntity) {
|
||||
player.giveExperiencePoints(event.getDroppedExperience());
|
||||
event.setCanceled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
if (!stack.is(ModTags.Items.GUN)) return;
|
||||
|
||||
// TODO perk
|
||||
// int level = PerkHelper.getItemPerkLevel(ModPerks.POWERFUL_ATTRACTION.get(), stack);
|
||||
// if (level > 0) {
|
||||
// player.giveExperiencePoints((int) (event.getDroppedExperience() * (0.8f + 0.2f * level)));
|
||||
//
|
||||
// event.setCanceled(true);
|
||||
// }
|
||||
}
|
||||
|
||||
public static void handlePlayerBeamReset(Player player) {
|
||||
var cap = player.getCapability(ModCapabilities.LASER_CAPABILITY);
|
||||
if (cap != null) {
|
||||
cap.end();
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleVorpalWeaponDamage(ItemStack stack, LivingIncomingDamageEvent event) {
|
||||
var entity = event.getEntity();
|
||||
// TODO perk
|
||||
// int level = PerkHelper.getItemPerkLevel(ModPerks.VORPAL_WEAPON.get(), stack);
|
||||
int level = 0;
|
||||
if (level <= 0) return;
|
||||
if (entity.getHealth() < 100.0f) return;
|
||||
|
||||
event.setAmount((float) (event.getAmount() + entity.getHealth() * 0.00002f * Math.pow(level, 2)));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onKnockback(LivingKnockBackEvent event) {
|
||||
ICustomKnockback knockback = ICustomKnockback.getInstance(event.getEntity());
|
||||
if (knockback.superbWarfare$getKnockbackStrength() >= 0) {
|
||||
event.setStrength((float) knockback.superbWarfare$getKnockbackStrength());
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onEntityFall(LivingFallEvent event) {
|
||||
LivingEntity living = event.getEntity();
|
||||
if (living.getVehicle() instanceof VehicleEntity) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPreSendKillMessage(PreKillEvent.SendKillMessage event) {
|
||||
if (event.getSource().getDirectEntity() instanceof LaserTowerEntity && !(event.getTarget() instanceof Player)) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPreIndicator(PreKillEvent.Indicator event) {
|
||||
if (event.getSource().getDirectEntity() instanceof LaserTowerEntity && !(event.getTarget() instanceof Player)) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,355 @@
|
|||
package com.atsuishio.superbwarfare.event;
|
||||
|
||||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||
import com.atsuishio.superbwarfare.config.common.GameplayConfig;
|
||||
import com.atsuishio.superbwarfare.config.server.MiscConfig;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.init.ModTags;
|
||||
import com.atsuishio.superbwarfare.tools.*;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.event.AnvilUpdateEvent;
|
||||
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
|
||||
import net.neoforged.neoforge.event.tick.PlayerTickEvent;
|
||||
|
||||
@EventBusSubscriber
|
||||
public class PlayerEventHandler {
|
||||
@SubscribeEvent
|
||||
public static void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) {
|
||||
Player player = event.getEntity();
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
var tag = NBTTool.getTag(stack);
|
||||
if (stack.is(ModItems.MONITOR.get()) && tag.getBoolean("Using")) {
|
||||
tag.putBoolean("Using", false);
|
||||
NBTTool.saveTag(stack, tag);
|
||||
}
|
||||
for (ItemStack pStack : player.getInventory().items) {
|
||||
if (pStack.is(ModTags.Items.GUN)) {
|
||||
tag = NBTTool.getTag(pStack);
|
||||
tag.putBoolean("draw", true);
|
||||
tag.putBoolean("init", false);
|
||||
NBTTool.saveTag(pStack, tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPlayerRespawned(PlayerEvent.PlayerRespawnEvent event) {
|
||||
Player player = event.getEntity();
|
||||
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap != null) {
|
||||
cap.zoom = false;
|
||||
cap.tacticalSprintExhaustion = false;
|
||||
cap.tacticalSprintTime = 600;
|
||||
cap.syncPlayerVariables(player);
|
||||
}
|
||||
|
||||
handleRespawnReload(player);
|
||||
handleRespawnAutoArmor(player);
|
||||
|
||||
for (ItemStack pStack : player.getInventory().items) {
|
||||
if (pStack.is(ModTags.Items.GUN)) {
|
||||
var tag = NBTTool.getTag(pStack);
|
||||
tag.putBoolean("draw", true);
|
||||
NBTTool.saveTag(pStack, tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPlayerTick(PlayerTickEvent.Post event) {
|
||||
Player player = event.getEntity();
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
|
||||
if (stack.is(ModTags.Items.GUN)) {
|
||||
handlePlayerSprint(player);
|
||||
handleSpecialWeaponAmmo(player);
|
||||
handleBocekPulling(player);
|
||||
}
|
||||
|
||||
handleGround(player);
|
||||
handleSimulationDistance(player);
|
||||
handleTacticalSprint(player);
|
||||
handleBreath(player);
|
||||
}
|
||||
|
||||
private static void handleBreath(Player player) {
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap == null) return;
|
||||
|
||||
if (cap.breath) {
|
||||
cap.breathTime = Mth.clamp(cap.breathTime - 1, 0, 100);
|
||||
} else {
|
||||
cap.breathTime = Mth.clamp(cap.breathTime + 1, 0, 100);
|
||||
}
|
||||
|
||||
if (cap.breathTime == 0) {
|
||||
cap.breathExhaustion = true;
|
||||
cap.breath = false;
|
||||
}
|
||||
|
||||
if (cap.breathTime == 100) {
|
||||
cap.breathExhaustion = false;
|
||||
}
|
||||
|
||||
cap.syncPlayerVariables(player);
|
||||
}
|
||||
|
||||
private static void handleTacticalSprint(Player player) {
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap == null) return;
|
||||
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
int sprintCost;
|
||||
|
||||
if (stack.is(ModTags.Items.GUN)) {
|
||||
double weight = GunsTool.getGunDoubleTag(stack, "Weight") + GunsTool.getGunDoubleTag(stack, "CustomWeight");
|
||||
sprintCost = (int) (5 + 0.2 * weight);
|
||||
} else {
|
||||
sprintCost = 5;
|
||||
}
|
||||
|
||||
if (!player.isSprinting()) {
|
||||
cap.tacticalSprint = false;
|
||||
player.getPersistentData().putBoolean("canTacticalSprint", true);
|
||||
}
|
||||
|
||||
if (player.isSprinting()
|
||||
&& !cap.tacticalSprintExhaustion
|
||||
&& player.getPersistentData().getBoolean("canTacticalSprint")
|
||||
) {
|
||||
cap.tacticalSprint = true;
|
||||
player.getPersistentData().putBoolean("canTacticalSprint", false);
|
||||
}
|
||||
|
||||
if (cap.tacticalSprint) {
|
||||
cap.tacticalSprintTime = Mth.clamp(cap.tacticalSprintTime - sprintCost, 0, 1000);
|
||||
|
||||
if (MiscConfig.ALLOW_TACTICAL_SPRINT.get()) {
|
||||
player.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SPEED, 2, 0, false, false));
|
||||
}
|
||||
} else {
|
||||
cap.tacticalSprintTime = Mth.clamp(cap.tacticalSprintTime + 7, 0, 1000);
|
||||
}
|
||||
|
||||
if (cap.tacticalSprintTime == 0) {
|
||||
cap.tacticalSprintExhaustion = true;
|
||||
cap.tacticalSprint = false;
|
||||
}
|
||||
|
||||
if (cap.tacticalSprintTime == 1000) {
|
||||
cap.tacticalSprintExhaustion = false;
|
||||
player.getPersistentData().putBoolean("canTacticalSprint", true);
|
||||
}
|
||||
|
||||
cap.syncPlayerVariables(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断玩家是否在奔跑
|
||||
*/
|
||||
private static void handlePlayerSprint(Player player) {
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap == null) return;
|
||||
|
||||
if (cap.holdFire) {
|
||||
player.getPersistentData().putDouble("noRun", 10);
|
||||
}
|
||||
|
||||
if (player.isShiftKeyDown()
|
||||
|| player.isPassenger()
|
||||
|| player.isInWater()
|
||||
|| cap.zoom
|
||||
) player.getPersistentData().putDouble("noRun", 3);
|
||||
|
||||
if (player.getPersistentData().getDouble("noRun") > 0) {
|
||||
player.getPersistentData().putDouble("noRun", (player.getPersistentData().getDouble("noRun") - 1));
|
||||
}
|
||||
|
||||
if (cap.zoom || cap.holdFire) {
|
||||
player.setSprinting(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleGround(Player player) {
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap == null) return;
|
||||
|
||||
if (player.onGround()) {
|
||||
cap.playerDoubleJump = false;
|
||||
cap.syncPlayerVariables(player);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleSpecialWeaponAmmo(Player player) {
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
|
||||
if ((stack.is(ModItems.RPG.get()) || stack.is(ModItems.BOCEK.get())) && GunsTool.getGunIntTag(stack, "Ammo", 0) == 1) {
|
||||
NBTTool.setDouble(stack, "empty", 0);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleBocekPulling(Player player) {
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap == null) return;
|
||||
|
||||
if (cap.bowPullHold) {
|
||||
if (stack.getItem() == ModItems.BOCEK.get()
|
||||
&& GunsTool.getGunIntTag(stack, "MaxAmmo") > 0
|
||||
&& !player.getCooldowns().isOnCooldown(stack.getItem())
|
||||
&& GunsTool.getGunDoubleTag(stack, "Power") < 12
|
||||
) {
|
||||
GunsTool.setGunDoubleTag(stack, "Power", GunsTool.getGunDoubleTag(stack, "Power") + 1);
|
||||
|
||||
cap.bowPull = true;
|
||||
cap.tacticalSprint = false;
|
||||
cap.syncPlayerVariables(player);
|
||||
player.setSprinting(false);
|
||||
}
|
||||
if (GunsTool.getGunDoubleTag(stack, "Power") == 1) {
|
||||
if (!player.level().isClientSide() && player instanceof ServerPlayer serverPlayer) {
|
||||
SoundTool.playLocalSound(serverPlayer, ModSounds.BOCEK_PULL_1P.get(), 2f, 1f);
|
||||
player.level().playSound(null, player.blockPosition(), ModSounds.BOCEK_PULL_3P.get(), SoundSource.PLAYERS, 0.5f, 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (stack.getItem() == ModItems.BOCEK.get()) {
|
||||
GunsTool.setGunDoubleTag(stack, "Power", 0);
|
||||
}
|
||||
cap.bowPull = false;
|
||||
cap.syncPlayerVariables(player);
|
||||
}
|
||||
|
||||
if (GunsTool.getGunDoubleTag(stack, "Power") > 0) {
|
||||
cap.tacticalSprint = false;
|
||||
cap.syncPlayerVariables(player);
|
||||
player.setSprinting(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleSimulationDistance(Player player) {
|
||||
if (player.level() instanceof ServerLevel serverLevel && player instanceof ServerPlayer serverPlayer) {
|
||||
// TODO send simulation distance to client
|
||||
// var distanceManager = serverLevel.getChunkSource().chunkMap.getDistanceManager();
|
||||
// var playerTicketManager = distanceManager.playerTicketManager;
|
||||
// int maxDistance = playerTicketManager.viewDistance;
|
||||
//
|
||||
// ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new SimulationDistanceMessage(maxDistance));
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleRespawnReload(Player player) {
|
||||
if (!GameplayConfig.RESPAWN_RELOAD.get()) return;
|
||||
|
||||
for (ItemStack stack : player.getInventory().items) {
|
||||
if (stack.is(ModTags.Items.GUN)) {
|
||||
if (!InventoryTool.hasCreativeAmmoBox(player)) {
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap == null) return;
|
||||
|
||||
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO) && cap.shotgunAmmo > 0) {
|
||||
GunsTool.reload(player, stack, AmmoType.SHOTGUN);
|
||||
}
|
||||
if (stack.is(ModTags.Items.USE_SNIPER_AMMO) && cap.sniperAmmo > 0) {
|
||||
GunsTool.reload(player, stack, AmmoType.SNIPER);
|
||||
}
|
||||
if (stack.is(ModTags.Items.USE_HANDGUN_AMMO) && cap.handgunAmmo > 0) {
|
||||
GunsTool.reload(player, stack, AmmoType.HANDGUN);
|
||||
}
|
||||
if (stack.is(ModTags.Items.USE_RIFLE_AMMO) && cap.rifleAmmo > 0) {
|
||||
GunsTool.reload(player, stack, AmmoType.RIFLE);
|
||||
}
|
||||
if (stack.is(ModTags.Items.USE_HEAVY_AMMO) && cap.heavyAmmo > 0) {
|
||||
GunsTool.reload(player, stack, AmmoType.HEAVY);
|
||||
}
|
||||
|
||||
if (stack.getItem() == ModItems.TASER.get() && GunsTool.getGunIntTag(stack, "MaxAmmo") > 0 && GunsTool.getGunIntTag(stack, "Ammo", 0) == 0) {
|
||||
GunsTool.setGunIntTag(stack, "Ammo", 1);
|
||||
player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.TASER_ELECTRODE.get(), 1, player.inventoryMenu.getCraftSlots());
|
||||
}
|
||||
if (stack.getItem() == ModItems.M_79.get() && GunsTool.getGunIntTag(stack, "MaxAmmo") > 0 && GunsTool.getGunIntTag(stack, "Ammo", 0) == 0) {
|
||||
GunsTool.setGunIntTag(stack, "Ammo", 1);
|
||||
player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.GRENADE_40MM.get(), 1, player.inventoryMenu.getCraftSlots());
|
||||
}
|
||||
if (stack.getItem() == ModItems.RPG.get() && GunsTool.getGunIntTag(stack, "MaxAmmo") > 0 && GunsTool.getGunIntTag(stack, "Ammo", 0) == 0) {
|
||||
GunsTool.setGunIntTag(stack, "Ammo", 1);
|
||||
player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.ROCKET.get(), 1, player.inventoryMenu.getCraftSlots());
|
||||
}
|
||||
if (stack.getItem() == ModItems.JAVELIN.get() && GunsTool.getGunIntTag(stack, "MaxAmmo") > 0 && GunsTool.getGunIntTag(stack, "Ammo", 0) == 0) {
|
||||
GunsTool.setGunIntTag(stack, "Ammo", 1);
|
||||
player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.JAVELIN_MISSILE.get(), 1, player.inventoryMenu.getCraftSlots());
|
||||
}
|
||||
} else {
|
||||
GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Magazine", 0)
|
||||
+ GunsTool.getGunIntTag(stack, "CustomMagazine", 0));
|
||||
}
|
||||
GunsTool.setGunBooleanTag(stack, "HoldOpen", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleRespawnAutoArmor(Player player) {
|
||||
if (!GameplayConfig.RESPAWN_AUTO_ARMOR.get()) return;
|
||||
|
||||
ItemStack armor = player.getItemBySlot(EquipmentSlot.CHEST);
|
||||
if (armor == ItemStack.EMPTY) return;
|
||||
|
||||
var tag = NBTTool.getTag(armor);
|
||||
double armorPlate = tag.getDouble("ArmorPlate");
|
||||
|
||||
int armorLevel = 1;
|
||||
if (armor.is(ModTags.Items.MILITARY_ARMOR)) {
|
||||
armorLevel = 2;
|
||||
} else if (armor.is(ModTags.Items.MILITARY_ARMOR_HEAVY)) {
|
||||
armorLevel = 3;
|
||||
}
|
||||
|
||||
if (armorPlate >= armorLevel * 15) return;
|
||||
|
||||
for (var stack : player.getInventory().items) {
|
||||
if (stack.is(ModItems.ARMOR_PLATE.get())) {
|
||||
var stackTag = NBTTool.getTag(stack);
|
||||
if (stackTag.getBoolean("Infinite")) {
|
||||
tag.putDouble("ArmorPlate", armorLevel * 15);
|
||||
if (player instanceof ServerPlayer serverPlayer) {
|
||||
serverPlayer.level().playSound(null, serverPlayer.getOnPos(), SoundEvents.ARMOR_EQUIP_IRON.value(), SoundSource.PLAYERS, 0.5f, 1);
|
||||
}
|
||||
} else {
|
||||
for (int index0 = 0; index0 < Math.ceil(((armorLevel * 15) - armorPlate) / 15); index0++) {
|
||||
stack.finishUsingItem(player.level(), player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onAnvilUpdate(AnvilUpdateEvent event) {
|
||||
ItemStack left = event.getLeft();
|
||||
ItemStack right = event.getRight();
|
||||
|
||||
if (left.is(ModTags.Items.GUN) && right.getItem() == ModItems.SHORTCUT_PACK.get()) {
|
||||
ItemStack output = left.copy();
|
||||
|
||||
GunsTool.setGunDoubleTag(output, "UpgradePoint", GunsTool.getGunDoubleTag(output, "UpgradePoint", 0) + 1);
|
||||
|
||||
event.setOutput(output);
|
||||
event.setCost(10);
|
||||
event.setMaterialCost(1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
package com.atsuishio.superbwarfare.event;
|
||||
|
||||
import com.atsuishio.superbwarfare.event.events.ReloadEvent;
|
||||
import com.atsuishio.superbwarfare.init.ModTags;
|
||||
import com.atsuishio.superbwarfare.tools.GunsTool;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
|
||||
@EventBusSubscriber
|
||||
public class ReloadEventHandler {
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPreReload(ReloadEvent.Pre event) {
|
||||
Player player = event.player;
|
||||
ItemStack stack = event.stack;
|
||||
if (player == null || !stack.is(ModTags.Items.GUN)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.level().isClientSide) {
|
||||
return;
|
||||
}
|
||||
|
||||
handleHealClipPre(stack);
|
||||
handleKillClipPre(stack);
|
||||
handleKillingTallyPre(stack);
|
||||
handleDesperadoPre(stack);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPostReload(ReloadEvent.Post event) {
|
||||
Player player = event.player;
|
||||
ItemStack stack = event.stack;
|
||||
if (player == null || !stack.is(ModTags.Items.GUN)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.level().isClientSide) {
|
||||
return;
|
||||
}
|
||||
|
||||
handleHealClipPost(player, stack);
|
||||
handleKillClipPost(stack);
|
||||
handleDesperadoPost(stack);
|
||||
}
|
||||
|
||||
private static void handleHealClipPre(ItemStack stack) {
|
||||
int time = GunsTool.getPerkIntTag(stack, "HealClipTime");
|
||||
if (time > 0) {
|
||||
GunsTool.setPerkIntTag(stack, "HealClipTime", 0);
|
||||
GunsTool.setPerkBooleanTag(stack, "HealClip", true);
|
||||
} else {
|
||||
GunsTool.setPerkBooleanTag(stack, "HealClip", false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleHealClipPost(Player player, ItemStack stack) {
|
||||
if (!GunsTool.getPerkBooleanTag(stack, "HealClip")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO perk
|
||||
// int healClipLevel = PerkHelper.getItemPerkLevel(ModPerks.HEAL_CLIP.get(), stack);
|
||||
// if (healClipLevel == 0) {
|
||||
// healClipLevel = 1;
|
||||
// }
|
||||
//
|
||||
// player.heal(12.0f * (0.8f + 0.2f * healClipLevel));
|
||||
// List<Player> players = player.level().getEntitiesOfClass(Player.class, player.getBoundingBox().inflate(5))
|
||||
// .stream().filter(p -> p.isAlliedTo(player)).toList();
|
||||
// int finalHealClipLevel = healClipLevel;
|
||||
// players.forEach(p -> p.heal(6.0f * (0.8f + 0.2f * finalHealClipLevel)));
|
||||
}
|
||||
|
||||
private static void handleKillClipPre(ItemStack stack) {
|
||||
int time = GunsTool.getPerkIntTag(stack, "KillClipReloadTime");
|
||||
if (time > 0) {
|
||||
GunsTool.setPerkIntTag(stack, "KillClipReloadTime", 0);
|
||||
GunsTool.setPerkBooleanTag(stack, "KillClip", true);
|
||||
} else {
|
||||
GunsTool.setPerkBooleanTag(stack, "KillClip", false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleKillClipPost(ItemStack stack) {
|
||||
if (!GunsTool.getPerkBooleanTag(stack, "KillClip")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO perk
|
||||
// int level = PerkHelper.getItemPerkLevel(ModPerks.KILL_CLIP.get(), stack);
|
||||
// GunsTool.setPerkIntTag(stack, "KillClipTime", 90 + 10 * level);
|
||||
}
|
||||
|
||||
private static void handleKillingTallyPre(ItemStack stack) {
|
||||
// TODO perk
|
||||
// int level = PerkHelper.getItemPerkLevel(ModPerks.KILLING_TALLY.get(), stack);
|
||||
// if (level == 0) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// GunsTool.setPerkIntTag(stack, "KillingTally", 0);
|
||||
}
|
||||
|
||||
private static void handleDesperadoPre(ItemStack stack) {
|
||||
int time = GunsTool.getPerkIntTag(stack, "DesperadoTime");
|
||||
if (time > 0) {
|
||||
GunsTool.setPerkIntTag(stack, "DesperadoTime", 0);
|
||||
GunsTool.setPerkBooleanTag(stack, "Desperado", true);
|
||||
} else {
|
||||
GunsTool.setPerkBooleanTag(stack, "Desperado", false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleDesperadoPost(ItemStack stack) {
|
||||
// TODO perk
|
||||
// if (!GunsTool.getPerkBooleanTag(stack, "Desperado")) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// int level = PerkHelper.getItemPerkLevel(ModPerks.DESPERADO.get(), stack);
|
||||
// GunsTool.setPerkIntTag(stack, "DesperadoTimePost", 110 + level * 10);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.atsuishio.superbwarfare.event;
|
||||
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
||||
import com.tacz.guns.api.event.common.EntityHurtByGunEvent;
|
||||
|
||||
public class TACZGunEventHandler {
|
||||
public static void entityHurtByTACZGun(EntityHurtByGunEvent.Pre event) {
|
||||
if (event.getHurtEntity() instanceof VehicleEntity) {
|
||||
event.setHeadshot(false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.atsuishio.superbwarfare.event.events;
|
||||
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.neoforged.bus.api.Event;
|
||||
import net.neoforged.bus.api.ICancellableEvent;
|
||||
|
||||
/**
|
||||
* 玩家击杀生物后,用于判断是否发送击杀播报/显示击杀指示
|
||||
*/
|
||||
public class PreKillEvent extends Event implements ICancellableEvent {
|
||||
|
||||
private final Player player;
|
||||
private final DamageSource source;
|
||||
private final LivingEntity target;
|
||||
|
||||
private PreKillEvent(Player player, DamageSource source, LivingEntity target) {
|
||||
this.player = player;
|
||||
this.source = source;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public static class SendKillMessage extends PreKillEvent {
|
||||
|
||||
public SendKillMessage(Player player, DamageSource source, LivingEntity target) {
|
||||
super(player, source, target);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Indicator extends PreKillEvent {
|
||||
|
||||
public Indicator(Player player, DamageSource source, LivingEntity target) {
|
||||
super(player, source, target);
|
||||
}
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public DamageSource getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public LivingEntity getTarget() {
|
||||
return target;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.atsuishio.superbwarfare.event.events;
|
||||
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.neoforged.bus.api.Event;
|
||||
import net.neoforged.bus.api.ICancellableEvent;
|
||||
|
||||
public class ReloadEvent extends Event implements ICancellableEvent {
|
||||
|
||||
public final Player player;
|
||||
public final ItemStack stack;
|
||||
|
||||
private ReloadEvent(Player player, ItemStack stack) {
|
||||
this.player = player;
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
public static class Pre extends ReloadEvent {
|
||||
public Pre(Player player, ItemStack stack) {
|
||||
super(player, stack);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Post extends ReloadEvent {
|
||||
public Post(Player player, ItemStack stack) {
|
||||
super(player, stack);
|
||||
}
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public ItemStack getStack() {
|
||||
return stack;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.atsuishio.superbwarfare.headshot;
|
||||
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Author: MrCrayfish
|
||||
*/
|
||||
public class BasicHeadshotBox<T extends LivingEntity> implements IHeadshotBox<T> {
|
||||
protected double headWidth;
|
||||
protected double headHeight;
|
||||
protected double headYOffset;
|
||||
|
||||
public BasicHeadshotBox(double headSize, double headYOffset) {
|
||||
this.headWidth = headSize;
|
||||
this.headHeight = headSize;
|
||||
this.headYOffset = headYOffset;
|
||||
}
|
||||
|
||||
public BasicHeadshotBox(double headWidth, double headHeight, double headYOffset) {
|
||||
this.headWidth = headWidth;
|
||||
this.headHeight = headHeight;
|
||||
this.headYOffset = headYOffset;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AABB getHeadshotBox(T entity) {
|
||||
double halfWidth = this.headWidth / 2.0;
|
||||
AABB headBox = new AABB(-halfWidth * 0.0625, 0, -halfWidth * 0.0625, halfWidth * 0.0625, this.headHeight * 0.0625, halfWidth * 0.0625);
|
||||
headBox = headBox.move(0, this.headYOffset * 0.0625, 0);
|
||||
return headBox;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
package com.atsuishio.superbwarfare.headshot;
|
||||
|
||||
import com.atsuishio.superbwarfare.init.ModEntities;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.loading.FMLEnvironment;
|
||||
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
|
||||
import net.neoforged.neoforge.event.tick.PlayerTickEvent;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* Author: MrCrayfish
|
||||
*/
|
||||
public class BoundingBoxManager {
|
||||
private static final Map<EntityType<?>, IHeadshotBox<?>> headshotBoxes = new HashMap<>();
|
||||
private static final WeakHashMap<Player, LinkedList<AABB>> playerBoxes = new WeakHashMap<>();
|
||||
|
||||
static {
|
||||
/* Player */
|
||||
registerHeadshotBox(EntityType.PLAYER, (entity) -> {
|
||||
AABB headBox = new AABB(-4 * 0.0625, 0, -4 * 0.0625, 4 * 0.0625, 8 * 0.0625, 4 * 0.0625);
|
||||
double scale = 30.0 / 32.0;
|
||||
if (entity.getBbHeight() <= 1) {
|
||||
headBox = headBox.move(0, 3 * 0.0625, 0);
|
||||
Vec3 pos = Vec3.directionFromRotation(entity.getXRot(), entity.yBodyRot).normalize().scale(0.8);
|
||||
headBox = headBox.move(pos);
|
||||
} else {
|
||||
headBox = headBox.move(0, entity.isShiftKeyDown() ? 20 * 0.0625 : 24 * 0.0625, 0);
|
||||
}
|
||||
return new AABB(headBox.minX * scale, headBox.minY * scale, headBox.minZ * scale, headBox.maxX * scale, headBox.maxY * scale, headBox.maxZ * scale);
|
||||
});
|
||||
registerHeadshotBox(ModEntities.SENPAI.get(), new BasicHeadshotBox<>(8.0, 22.0));
|
||||
registerHeadshotBox(ModEntities.TARGET.get(), new BasicHeadshotBox<>(14.0, 20.0));
|
||||
registerHeadshotBox(EntityType.ENDERMAN, new BasicHeadshotBox<>(8.0, 38.0));
|
||||
registerHeadshotBox(EntityType.ZOMBIE, new ChildHeadshotBox<>(8.0, 26.0, 0.75, 0.5));
|
||||
registerHeadshotBox(EntityType.ZOMBIFIED_PIGLIN, new ChildHeadshotBox<>(8.0, 26.0, 0.75, 0.5));
|
||||
registerHeadshotBox(EntityType.HUSK, new ChildHeadshotBox<>(8.0, 26.0, 0.75, 0.5));
|
||||
registerHeadshotBox(EntityType.SKELETON, new BasicHeadshotBox<>(8.0, 26.0));
|
||||
registerHeadshotBox(EntityType.STRAY, new BasicHeadshotBox<>(8.0, 26.0));
|
||||
registerHeadshotBox(EntityType.CREEPER, new BasicHeadshotBox<>(8.0, 21.0));
|
||||
registerHeadshotBox(EntityType.SPIDER, new RotatedHeadshotBox<>(8.0, 5.0, 7.0, false, true));
|
||||
registerHeadshotBox(EntityType.DROWNED, new BasicHeadshotBox<>(8.0, 26.0));
|
||||
registerHeadshotBox(EntityType.VILLAGER, new NoChildHeadshotBox<>(8.0, 9.0, 25.0));
|
||||
registerHeadshotBox(EntityType.ZOMBIE_VILLAGER, new NoChildHeadshotBox<>(8.0, 9.0, 25.0));
|
||||
registerHeadshotBox(EntityType.VINDICATOR, new NoChildHeadshotBox<>(8.0, 9.0, 25.0));
|
||||
registerHeadshotBox(EntityType.EVOKER, new BasicHeadshotBox<>(8.0, 9.0, 25.0));
|
||||
registerHeadshotBox(EntityType.PILLAGER, new BasicHeadshotBox<>(8.0, 9.0, 25.0));
|
||||
registerHeadshotBox(EntityType.ILLUSIONER, new BasicHeadshotBox<>(8.0, 9.0, 25.0));
|
||||
registerHeadshotBox(EntityType.WANDERING_TRADER, new BasicHeadshotBox<>(8.0, 9.0, 25.0));
|
||||
registerHeadshotBox(EntityType.WITCH, new BasicHeadshotBox<>(8.0, 9.0, 25.0));
|
||||
registerHeadshotBox(EntityType.SHEEP, new RotatedHeadshotBox<>(7.5, 8.0, 15.0, 9.5, false, true));
|
||||
registerHeadshotBox(EntityType.CHICKEN, new NoChildRotatedHeadshotBox<>(4.0, 6.0, 9.0, 5.0, false, true));
|
||||
registerHeadshotBox(EntityType.COW, new NoChildRotatedHeadshotBox<>(7.5, 8.0, 16.0, 10.5, false, true));
|
||||
registerHeadshotBox(EntityType.MOOSHROOM, new NoChildRotatedHeadshotBox<>(7.5, 8.0, 16.0, 10.5, false, true));
|
||||
registerHeadshotBox(EntityType.PIG, new NoChildRotatedHeadshotBox<>(8.0, 8.0, 10, false, true));
|
||||
registerHeadshotBox(EntityType.HORSE, new RotatedHeadshotBox<>(10.0, 26.0, 16.0, false, true));
|
||||
registerHeadshotBox(EntityType.SKELETON_HORSE, new RotatedHeadshotBox<>(10.0, 26.0, 16.0, false, true));
|
||||
registerHeadshotBox(EntityType.DONKEY, new RotatedHeadshotBox<>(7.5, 8.0, 20.0, 13.0, false, true));
|
||||
registerHeadshotBox(EntityType.MULE, new RotatedHeadshotBox<>(7.5, 8.0, 21.0, 14.0, false, true));
|
||||
registerHeadshotBox(EntityType.LLAMA, new RotatedHeadshotBox<>(8.0, 26.0, 10.0, false, true));
|
||||
registerHeadshotBox(EntityType.TRADER_LLAMA, new RotatedHeadshotBox<>(8.0, 26.0, 10.0, false, true));
|
||||
registerHeadshotBox(EntityType.POLAR_BEAR, new RotatedHeadshotBox<>(9.0, 12.0, 20.0, false, true));
|
||||
registerHeadshotBox(EntityType.SNOW_GOLEM, new BasicHeadshotBox<>(10.0, 22.5));
|
||||
registerHeadshotBox(EntityType.TURTLE, new RotatedHeadshotBox<>(6.0, 5.0, 1.0, 10.0, false, true));
|
||||
registerHeadshotBox(EntityType.IRON_GOLEM, new BasicHeadshotBox<>(8.0, 35.0));
|
||||
registerHeadshotBox(EntityType.WARDEN, new BasicHeadshotBox<>(14.0, 37.0));
|
||||
registerHeadshotBox(EntityType.PHANTOM, new RotatedHeadshotBox<>(6.0, 3.0, 1.5, 6.5, true, true));
|
||||
registerHeadshotBox(EntityType.HOGLIN, new RotatedHeadshotBox<>(14.0, 16.0, 7.0, 21.0, false, true));
|
||||
registerHeadshotBox(EntityType.ZOGLIN, new RotatedHeadshotBox<>(14.0, 16.0, 7.0, 21.0, false, true));
|
||||
registerHeadshotBox(EntityType.PIGLIN, new ChildHeadshotBox<>(8.0, 26.0, 0.75, 0.5));
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a headshot box for the specified entity type.
|
||||
*
|
||||
* @param type the entity type
|
||||
* @param headshotBox a {@link IHeadshotBox} get
|
||||
* @param <T> a type that extends {@link LivingEntity}
|
||||
*/
|
||||
public static <T extends LivingEntity> void registerHeadshotBox(EntityType<T> type, IHeadshotBox<T> headshotBox) {
|
||||
headshotBoxes.putIfAbsent(type, headshotBox);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Entity> IHeadshotBox<T> getHeadshotBoxes(EntityType<T> type) {
|
||||
return (IHeadshotBox<T>) headshotBoxes.get(type);
|
||||
}
|
||||
|
||||
@SubscribeEvent(receiveCanceled = true)
|
||||
public void onPlayerTick(PlayerTickEvent.Pre event) {
|
||||
if (FMLEnvironment.dist == Dist.CLIENT) {
|
||||
if (event.getEntity().isSpectator()) {
|
||||
playerBoxes.remove(event.getEntity());
|
||||
return;
|
||||
}
|
||||
LinkedList<AABB> boxes = playerBoxes.computeIfAbsent(event.getEntity(), player -> new LinkedList<>());
|
||||
boxes.addFirst(event.getEntity().getBoundingBox());
|
||||
if (boxes.size() > 20) {
|
||||
boxes.removeLast();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent(receiveCanceled = true)
|
||||
public void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) {
|
||||
playerBoxes.remove(event.getEntity());
|
||||
}
|
||||
|
||||
public static AABB getBoundingBox(Player entity, int ping) {
|
||||
if (playerBoxes.containsKey(entity)) {
|
||||
LinkedList<AABB> boxes = playerBoxes.get(entity);
|
||||
int index = Mth.clamp(ping, 0, boxes.size() - 1);
|
||||
return boxes.get(index);
|
||||
}
|
||||
return entity.getBoundingBox();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.atsuishio.superbwarfare.headshot;
|
||||
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Author: MrCrayfish
|
||||
*/
|
||||
public class ChildHeadshotBox<T extends LivingEntity> extends BasicHeadshotBox<T> {
|
||||
private final double childHeadScale;
|
||||
private final double headYOffsetScale;
|
||||
|
||||
public ChildHeadshotBox(double headSize, double headYOffset, double childHeadScale, double headYOffsetScale) {
|
||||
super(headSize, headYOffset);
|
||||
this.childHeadScale = childHeadScale;
|
||||
this.headYOffsetScale = headYOffsetScale;
|
||||
}
|
||||
|
||||
public ChildHeadshotBox(double headWidth, double headHeight, double headYOffset, double childHeadScale, double headYOffsetScale) {
|
||||
super(headWidth, headHeight, headYOffset);
|
||||
this.childHeadScale = childHeadScale;
|
||||
this.headYOffsetScale = headYOffsetScale;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AABB getHeadshotBox(T entity) {
|
||||
AABB headBox = super.getHeadshotBox(entity);
|
||||
if (headBox != null && entity.isBaby()) {
|
||||
return new AABB(headBox.minX * this.childHeadScale, headBox.minY * this.headYOffsetScale, headBox.minZ * this.childHeadScale, headBox.maxX * this.childHeadScale, headBox.maxY * (this.headYOffsetScale + 0.065), headBox.maxZ * this.childHeadScale);
|
||||
}
|
||||
return headBox;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.atsuishio.superbwarfare.headshot;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Author: MrCrayfish
|
||||
*/
|
||||
public interface IHeadshotBox<T extends Entity> {
|
||||
|
||||
@Nullable
|
||||
AABB getHeadshotBox(T entity);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.atsuishio.superbwarfare.headshot;
|
||||
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Author: MrCrayfish
|
||||
*/
|
||||
public class NoChildHeadshotBox<T extends LivingEntity> extends BasicHeadshotBox<T> {
|
||||
public NoChildHeadshotBox(double headSize, double headYOffset) {
|
||||
super(headSize, headYOffset);
|
||||
}
|
||||
|
||||
public NoChildHeadshotBox(double headWidth, double headHeight, double headYOffset) {
|
||||
super(headWidth, headHeight, headYOffset);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AABB getHeadshotBox(T entity) {
|
||||
if (entity.isBaby()) return null;
|
||||
return super.getHeadshotBox(entity);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.atsuishio.superbwarfare.headshot;
|
||||
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Author: MrCrayfish
|
||||
*/
|
||||
public class NoChildRotatedHeadshotBox<T extends LivingEntity> extends RotatedHeadshotBox<T> {
|
||||
public NoChildRotatedHeadshotBox(double headSize, double headYOffset, double headZOffset, boolean rotatePitch, boolean rotateYaw) {
|
||||
super(headSize, headYOffset, headZOffset, rotatePitch, rotateYaw);
|
||||
}
|
||||
|
||||
public NoChildRotatedHeadshotBox(double headWidth, double headHeight, double headYOffset, double headZOffset, boolean rotatePitch, boolean rotateYaw) {
|
||||
super(headWidth, headHeight, headYOffset, headZOffset, rotatePitch, rotateYaw);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AABB getHeadshotBox(T entity) {
|
||||
if (entity.isBaby()) return null;
|
||||
return super.getHeadshotBox(entity);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.atsuishio.superbwarfare.headshot;
|
||||
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Author: MrCrayfish
|
||||
*/
|
||||
public class RotatedHeadshotBox<T extends LivingEntity> extends BasicHeadshotBox<T> {
|
||||
protected double headZOffset;
|
||||
protected boolean rotatePitch;
|
||||
protected boolean rotateYaw;
|
||||
|
||||
public RotatedHeadshotBox(double headSize, double headYOffset, double headZOffset, boolean rotatePitch, boolean rotateYaw) {
|
||||
super(headSize, headSize, headYOffset);
|
||||
this.headZOffset = headZOffset;
|
||||
this.rotatePitch = rotatePitch;
|
||||
this.rotateYaw = rotateYaw;
|
||||
}
|
||||
|
||||
public RotatedHeadshotBox(double headWidth, double headHeight, double headYOffset, double headZOffset, boolean rotatePitch, boolean rotateYaw) {
|
||||
super(headWidth, headHeight, headYOffset);
|
||||
this.headZOffset = headZOffset;
|
||||
this.rotatePitch = rotatePitch;
|
||||
this.rotateYaw = rotateYaw;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AABB getHeadshotBox(T entity) {
|
||||
AABB headBox = super.getHeadshotBox(entity);
|
||||
if (headBox != null) {
|
||||
headBox = headBox.move(Vec3.directionFromRotation(this.rotatePitch ? entity.getXRot() : 0.0F, this.rotateYaw ? entity.yBodyRot : 0.0F).normalize().scale(this.headZOffset * 0.0625));
|
||||
return headBox;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@ import com.atsuishio.superbwarfare.ModUtils;
|
|||
import com.atsuishio.superbwarfare.item.*;
|
||||
import com.atsuishio.superbwarfare.item.armor.*;
|
||||
import com.atsuishio.superbwarfare.item.common.BlueprintItem;
|
||||
import com.atsuishio.superbwarfare.item.common.CannonShellItem;
|
||||
import com.atsuishio.superbwarfare.item.common.MaterialPack;
|
||||
import com.atsuishio.superbwarfare.item.common.ammo.*;
|
||||
import com.atsuishio.superbwarfare.item.common.ammo.box.AmmoBox;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.atsuishio.superbwarfare.init;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.network.message.BreathMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.send.BreathMessage;
|
||||
import com.mojang.blaze3d.platform.InputConstants;
|
||||
import net.minecraft.client.KeyMapping;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
|
|
@ -5,8 +5,8 @@ import com.atsuishio.superbwarfare.capability.laser.LaserHandler;
|
|||
import com.atsuishio.superbwarfare.client.TooltipTool;
|
||||
import com.atsuishio.superbwarfare.entity.projectile.LaserEntity;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.network.message.LaserShootMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.ShakeClientMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ShakeClientMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.send.LaserShootMessage;
|
||||
import com.atsuishio.superbwarfare.tools.TraceTool;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.game.ClientboundStopSoundPacket;
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
package com.atsuishio.superbwarfare.item.common;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
|
||||
public class CannonShellItem extends Item {
|
||||
|
||||
public CannonShellItem(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package com.atsuishio.superbwarfare.item.common;
|
||||
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Rarity;
|
||||
import net.minecraft.world.item.TooltipFlag;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.List;
|
||||
|
||||
public class CreativeAmmoBox extends Item {
|
||||
|
||||
public CreativeAmmoBox() {
|
||||
super(new Properties().rarity(Rarity.EPIC).stacksTo(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ParametersAreNonnullByDefault
|
||||
public void appendHoverText(ItemStack stack, TooltipContext context, List<Component> tooltipComponents, TooltipFlag tooltipFlag) {
|
||||
tooltipComponents.add(Component.translatable("des.superbwarfare.creative_ammo_box").withStyle(ChatFormatting.GRAY));
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ package com.atsuishio.superbwarfare.mobeffect;
|
|||
import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
||||
import com.atsuishio.superbwarfare.init.ModMobEffects;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.atsuishio.superbwarfare.mobeffect;
|
|||
import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
||||
import com.atsuishio.superbwarfare.init.ModMobEffects;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
package com.atsuishio.superbwarfare.network;
|
||||
|
||||
import com.atsuishio.superbwarfare.client.overlay.CrossHairOverlay;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
|
||||
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
||||
|
||||
public class ClientPacketHandler {
|
||||
|
||||
public static void handleClientIndicatorMessage(ClientIndicatorMessage message, final IPayloadContext context) {
|
||||
var type = message.messageType();
|
||||
switch (type) {
|
||||
case 1 -> CrossHairOverlay.HEAD_INDICATOR = message.value();
|
||||
case 2 -> CrossHairOverlay.KILL_INDICATOR = message.value();
|
||||
case 3 -> CrossHairOverlay.VEHICLE_INDICATOR = message.value();
|
||||
default -> CrossHairOverlay.HIT_INDICATOR = message.value();
|
||||
}
|
||||
}
|
||||
|
||||
// public static void handleSimulationDistanceMessage(int distance, final IPayloadContext context) {
|
||||
// if (context.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) {
|
||||
// DroneUIOverlay.MAX_DISTANCE = distance * 16;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public static void handleContainerDataMessage(int containerId, List<ContainerDataMessage.Pair> data, final IPayloadContext context) {
|
||||
// if (context.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) {
|
||||
// Minecraft mc = Minecraft.getInstance();
|
||||
// if (mc.player != null && mc.player.containerMenu.containerId == containerId) {
|
||||
// data.forEach(p -> ((EnergyMenu) mc.player.containerMenu).setData(p.id, p.data));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public static void handleRadarMenuOpen(RadarMenuOpenMessage message, final IPayloadContext context) {
|
||||
// FuMO25ScreenHelper.resetEntities();
|
||||
// FuMO25ScreenHelper.pos = message.pos;
|
||||
// }
|
||||
//
|
||||
// public static void handleRadarMenuClose() {
|
||||
// FuMO25ScreenHelper.resetEntities();
|
||||
// FuMO25ScreenHelper.pos = null;
|
||||
// }
|
||||
//
|
||||
// public static void handleResetCameraType(final IPayloadContext context) {
|
||||
// if (context.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) {
|
||||
// Minecraft minecraft = Minecraft.getInstance();
|
||||
// Player player = minecraft.player;
|
||||
// if (player == null) return;
|
||||
//
|
||||
// Minecraft.getInstance().options.setCameraType(Objects.requireNonNullElse(ClientEventHandler.lastCameraType, CameraType.FIRST_PERSON));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public static void handleClientSyncMotion(ClientMotionSyncMessage message, final IPayloadContext context) {
|
||||
// if (context.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) {
|
||||
// var level = Minecraft.getInstance().level;
|
||||
// if (level == null) return;
|
||||
// Entity entity = level.getEntity(message.id);
|
||||
// if (entity != null) {
|
||||
// entity.lerpMotion(message.x, message.y, message.z);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.atsuishio.superbwarfare.network;
|
||||
|
||||
import com.atsuishio.superbwarfare.network.message.*;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.*;
|
||||
import com.atsuishio.superbwarfare.network.message.send.*;
|
||||
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
|
||||
import net.neoforged.neoforge.network.registration.PayloadRegistrar;
|
||||
|
||||
|
@ -18,6 +19,7 @@ public class NetworkRegistry {
|
|||
registrar.playToServer(LaserShootMessage.TYPE, LaserShootMessage.STREAM_CODEC, LaserShootMessage::handler);
|
||||
registrar.playToServer(BreathMessage.TYPE, BreathMessage.STREAM_CODEC, BreathMessage::handler);
|
||||
registrar.playToServer(ShootMessage.TYPE, ShootMessage.STREAM_CODEC, ShootMessage::handler);
|
||||
|
||||
registrar.playToServer(DoubleJumpMessage.TYPE, DoubleJumpMessage.STREAM_CODEC, DoubleJumpMessage::handler);
|
||||
registrar.playToServer(VehicleMovementMessage.TYPE, VehicleMovementMessage.STREAM_CODEC, VehicleMovementMessage::handler);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,138 +0,0 @@
|
|||
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()) && NBTTool.getOrCreateTag(stack).getBoolean("Using") && NBTTool.getOrCreateTag(stack).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;
|
||||
}
|
||||
}
|
|
@ -1,129 +0,0 @@
|
|||
package com.atsuishio.superbwarfare.network.message;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.event.GunEventHandler;
|
||||
import com.atsuishio.superbwarfare.init.ModTags;
|
||||
import com.atsuishio.superbwarfare.tools.GunsTool;
|
||||
import com.atsuishio.superbwarfare.tools.NBTTool;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public record ShootMessage(double spread) implements CustomPacketPayload {
|
||||
public static final Type<ShootMessage> TYPE = new Type<>(ModUtils.loc("shoot"));
|
||||
|
||||
public static final StreamCodec<ByteBuf, ShootMessage> STREAM_CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.DOUBLE,
|
||||
ShootMessage::spread,
|
||||
ShootMessage::new
|
||||
);
|
||||
|
||||
public static void handler(final ShootMessage message, final IPayloadContext context) {
|
||||
pressAction(context.player(), message.spread);
|
||||
}
|
||||
|
||||
public static void pressAction(Player player, double spared) {
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
if (stack.is(ModTags.Items.NORMAL_GUN)) {
|
||||
int projectileAmount = GunsTool.getGunIntTag(stack, "ProjectileAmount", 1);
|
||||
|
||||
if (GunsTool.getGunIntTag(stack, "Ammo", 0) > 0) {
|
||||
// 空仓挂机
|
||||
if (GunsTool.getGunIntTag(stack, "Ammo", 0) == 1) {
|
||||
GunsTool.setGunBooleanTag(stack, "HoldOpen", true);
|
||||
}
|
||||
|
||||
if (stack.is(ModTags.Items.REVOLVER)) {
|
||||
NBTTool.getTag(stack).putBoolean("canImmediatelyShoot", false);
|
||||
}
|
||||
|
||||
// 判断是否为栓动武器(BoltActionTime > 0),并在开火后给一个需要上膛的状态
|
||||
if (GunsTool.getGunIntTag(stack, "BoltActionTime", 0) > 0 && GunsTool.getGunIntTag(stack, "Ammo", 0) > (stack.is(ModTags.Items.REVOLVER) ? 0 : 1)) {
|
||||
GunsTool.setGunBooleanTag(stack, "NeedBoltAction", true);
|
||||
}
|
||||
|
||||
GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Ammo", 0) - 1);
|
||||
|
||||
NBTTool.getTag(stack).putDouble("empty", 1);
|
||||
|
||||
// if (stack.getItem() == ModItems.M_60.get() && GunsTool.getGunIntTag(stack, "Ammo", 0) <= 5) {
|
||||
// GunsTool.setGunBooleanTag(stack, "HideBulletChain", true);
|
||||
// }
|
||||
//
|
||||
// if (stack.getItem() == ModItems.HOMEMADE_SHOTGUN.get()) {
|
||||
// stack.hurtAndBreak(1, player, p -> p.broadcastBreakEvent(InteractionHand.MAIN_HAND));
|
||||
// if (player instanceof ServerPlayer serverPlayer && player.level() instanceof ServerLevel serverLevel) {
|
||||
// ParticleTool.sendParticle(serverLevel, ParticleTypes.CLOUD, player.getX() + 1.8 * player.getLookAngle().x, player.getY() + player.getBbHeight() - 0.1 + 1.8 * player.getLookAngle().y,
|
||||
// player.getZ() + 1.8 * player.getLookAngle().z, 30, 0.4, 0.4, 0.4, 0.005, true, serverPlayer);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (stack.getItem() == ModItems.SENTINEL.get()) {
|
||||
// stack.getCapability(ForgeCapabilities.ENERGY).ifPresent(
|
||||
// iEnergyStorage -> iEnergyStorage.extractEnergy(3000, false)
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO);
|
||||
|
||||
for (int index0 = 0; index0 < (
|
||||
// todo perk
|
||||
// perk instanceof AmmoPerk ammoPerk && ammoPerk.slug ? 1 : projectileAmount
|
||||
projectileAmount
|
||||
); index0++) {
|
||||
GunEventHandler.gunShoot(player, spared);
|
||||
}
|
||||
|
||||
GunEventHandler.playGunSounds(player);
|
||||
}
|
||||
}
|
||||
// todo minigun
|
||||
// else if (stack.is(ModItems.MINIGUN.get())) {
|
||||
// var tag = GunNBTTool.getOrCreateTag(stack);
|
||||
//
|
||||
// if ((player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables())).rifleAmmo > 0
|
||||
// || InventoryTool.hasCreativeAmmoBox(player)) {
|
||||
// tag.putDouble("heat", (tag.getDouble("heat") + 0.1));
|
||||
// if (tag.getDouble("heat") >= 50.5) {
|
||||
// tag.putDouble("overheat", 40);
|
||||
// player.getCooldowns().addCooldown(stack.getItem(), 40);
|
||||
// if (!player.level().isClientSide() && player instanceof ServerPlayer serverPlayer) {
|
||||
// SoundTool.playLocalSound(serverPlayer, ModSounds.MINIGUN_OVERHEAT.get(), 2f, 1f);
|
||||
// }
|
||||
// }
|
||||
// var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO);
|
||||
// float pitch = tag.getDouble("heat") <= 40 ? 1 : (float) (1 - 0.025 * Math.abs(40 - tag.getDouble("heat")));
|
||||
//
|
||||
// if (!player.level().isClientSide() && player instanceof ServerPlayer) {
|
||||
// float soundRadius = (float) GunsTool.getGunDoubleTag(stack, "SoundRadius");
|
||||
//
|
||||
// player.playSound(ModSounds.MINIGUN_FIRE_3P.get(), soundRadius * 0.2f, pitch);
|
||||
// player.playSound(ModSounds.MINIGUN_FAR.get(), soundRadius * 0.5f, pitch);
|
||||
// player.playSound(ModSounds.MINIGUN_VERYFAR.get(), soundRadius, pitch);
|
||||
//
|
||||
// if (perk == ModPerks.BEAST_BULLET.get()) {
|
||||
// player.playSound(ModSounds.HENG.get(), 4f, pitch);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// GunEventHandler.gunShoot(player, spared);
|
||||
// if (!InventoryTool.hasCreativeAmmoBox(player)) {
|
||||
// player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).ifPresent(capability -> {
|
||||
// capability.rifleAmmo = player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables()).rifleAmmo - 1;
|
||||
// capability.syncPlayerVariables(player);
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Type<? extends CustomPacketPayload> type() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.atsuishio.superbwarfare.network.message;
|
||||
package com.atsuishio.superbwarfare.network.message.receive;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.network.ClientPacketHandler;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
|
@ -20,8 +21,7 @@ public record ClientIndicatorMessage(int messageType, int value) implements Cust
|
|||
);
|
||||
|
||||
public static void handler(final ClientIndicatorMessage message, final IPayloadContext context) {
|
||||
// TODO indicator process
|
||||
// ClientPacketHandler.handleClientIndicatorMessage(message, ctx);
|
||||
ClientPacketHandler.handleClientIndicatorMessage(message, context);
|
||||
}
|
||||
|
||||
@Override
|
|
@ -1,4 +1,4 @@
|
|||
package com.atsuishio.superbwarfare.network.message;
|
||||
package com.atsuishio.superbwarfare.network.message.receive;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import io.netty.buffer.ByteBuf;
|
|
@ -1,4 +1,4 @@
|
|||
package com.atsuishio.superbwarfare.network.message;
|
||||
package com.atsuishio.superbwarfare.network.message.receive;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.tools.GunsTool;
|
|
@ -1,6 +1,9 @@
|
|||
package com.atsuishio.superbwarfare.network.message;
|
||||
package com.atsuishio.superbwarfare.network.message.receive;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.config.client.KillMessageConfig;
|
||||
import com.atsuishio.superbwarfare.event.KillMessageHandler;
|
||||
import com.atsuishio.superbwarfare.tools.PlayerKillRecord;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
|
@ -83,8 +86,10 @@ public class PlayerGunKillMessage implements CustomPacketPayload {
|
|||
if (player != null && target != null) {
|
||||
var type = message.getDamageType();
|
||||
|
||||
// TODO 处理kill message
|
||||
// DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ClientPacketHandler.handlePlayerKillMessage(player, target, message.headshot, type, ctx));
|
||||
if (KillMessageHandler.QUEUE.size() >= KillMessageConfig.KILL_MESSAGE_COUNT.get()) {
|
||||
KillMessageHandler.QUEUE.poll();
|
||||
}
|
||||
KillMessageHandler.QUEUE.offer(new PlayerKillRecord(player, target, player.getMainHandItem(), message.headshot, type));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.atsuishio.superbwarfare.network.message;
|
||||
package com.atsuishio.superbwarfare.network.message.receive;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
|
@ -0,0 +1,46 @@
|
|||
package com.atsuishio.superbwarfare.network.message.receive;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.event.ClientEventHandler;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
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) {
|
||||
ClientEventHandler.handleShakeClient(message.time, message.radius, message.amplitude, message.x, message.y, message.z, context);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull Type<? extends CustomPacketPayload> type() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
package com.atsuishio.superbwarfare.network.message;
|
||||
package com.atsuishio.superbwarfare.network.message.send;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
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.neoforged.neoforge.network.handling.IPayloadContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
@ -19,7 +21,23 @@ public record BreathMessage(boolean messageType) implements CustomPacketPayload
|
|||
|
||||
|
||||
public static void handler(final BreathMessage message, final IPayloadContext context) {
|
||||
// TODO handler
|
||||
ServerPlayer player = (ServerPlayer) context.player();
|
||||
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap == null) return;
|
||||
if (message.messageType
|
||||
&& !cap.breathExhaustion
|
||||
&& cap.zoom
|
||||
&& player.getPersistentData().getDouble("NoBreath") == 0
|
||||
) {
|
||||
cap.breath = true;
|
||||
cap.syncPlayerVariables(player);
|
||||
}
|
||||
|
||||
if (!message.messageType) {
|
||||
cap.breath = false;
|
||||
cap.syncPlayerVariables(player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
|
@ -0,0 +1,47 @@
|
|||
package com.atsuishio.superbwarfare.network.message.send;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.core.BlockPos;
|
||||
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.level.Level;
|
||||
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public record DoubleJumpMessage(boolean canDoubleJump) implements CustomPacketPayload {
|
||||
public static final Type<DoubleJumpMessage> TYPE = new Type<>(ModUtils.loc("double_jump"));
|
||||
|
||||
public static final StreamCodec<ByteBuf, DoubleJumpMessage> STREAM_CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.BOOL,
|
||||
DoubleJumpMessage::canDoubleJump,
|
||||
DoubleJumpMessage::new
|
||||
);
|
||||
|
||||
public static void handler(final DoubleJumpMessage message, final IPayloadContext context) {
|
||||
ServerPlayer player = (ServerPlayer) context.player();
|
||||
|
||||
Level level = player.level();
|
||||
double x = player.getX();
|
||||
double y = player.getY();
|
||||
double z = player.getZ();
|
||||
|
||||
level.playSound(null, BlockPos.containing(x, y, z), ModSounds.DOUBLE_JUMP.get(), SoundSource.BLOCKS, 1, 1);
|
||||
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap == null) return;
|
||||
|
||||
cap.playerDoubleJump = message.canDoubleJump;
|
||||
cap.syncPlayerVariables(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Type<? extends CustomPacketPayload> type() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
package com.atsuishio.superbwarfare.network.message;
|
||||
package com.atsuishio.superbwarfare.network.message.send;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
|
||||
import com.atsuishio.superbwarfare.tools.EntityFindUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.core.UUIDUtil;
|
|
@ -0,0 +1,138 @@
|
|||
package com.atsuishio.superbwarfare.network.message.send;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||
import com.atsuishio.superbwarfare.event.GunEventHandler;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.init.ModTags;
|
||||
import com.atsuishio.superbwarfare.tools.*;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
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.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public record ShootMessage(double spread) implements CustomPacketPayload {
|
||||
public static final Type<ShootMessage> TYPE = new Type<>(ModUtils.loc("shoot"));
|
||||
|
||||
public static final StreamCodec<ByteBuf, ShootMessage> STREAM_CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.DOUBLE,
|
||||
ShootMessage::spread,
|
||||
ShootMessage::new
|
||||
);
|
||||
|
||||
public static void handler(final ShootMessage message, final IPayloadContext context) {
|
||||
pressAction(context.player(), message.spread);
|
||||
}
|
||||
|
||||
public static void pressAction(Player player, double spared) {
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
if (stack.is(ModTags.Items.NORMAL_GUN)) {
|
||||
int projectileAmount = GunsTool.getGunIntTag(stack, "ProjectileAmount", 1);
|
||||
|
||||
if (GunsTool.getGunIntTag(stack, "Ammo", 0) > 0) {
|
||||
// 空仓挂机
|
||||
if (GunsTool.getGunIntTag(stack, "Ammo", 0) == 1) {
|
||||
GunsTool.setGunBooleanTag(stack, "HoldOpen", true);
|
||||
}
|
||||
|
||||
if (stack.is(ModTags.Items.REVOLVER)) {
|
||||
NBTTool.getTag(stack).putBoolean("canImmediatelyShoot", false);
|
||||
}
|
||||
|
||||
// 判断是否为栓动武器(BoltActionTime > 0),并在开火后给一个需要上膛的状态
|
||||
if (GunsTool.getGunIntTag(stack, "BoltActionTime", 0) > 0 && GunsTool.getGunIntTag(stack, "Ammo", 0) > (stack.is(ModTags.Items.REVOLVER) ? 0 : 1)) {
|
||||
GunsTool.setGunBooleanTag(stack, "NeedBoltAction", true);
|
||||
}
|
||||
|
||||
GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Ammo", 0) - 1);
|
||||
|
||||
NBTTool.getTag(stack).putDouble("empty", 1);
|
||||
|
||||
if (stack.getItem() == ModItems.M_60.get() && GunsTool.getGunIntTag(stack, "Ammo", 0) <= 5) {
|
||||
GunsTool.setGunBooleanTag(stack, "HideBulletChain", true);
|
||||
}
|
||||
|
||||
if (stack.getItem() == ModItems.HOMEMADE_SHOTGUN.get()) {
|
||||
// TODO is hurt an break correct?
|
||||
// stack.hurtAndBreak(1, player, p -> p.broadcastBreakEvent(InteractionHand.MAIN_HAND));
|
||||
stack.hurtAndBreak(1, (ServerLevel) player.level(), player, p -> {
|
||||
});
|
||||
if (player instanceof ServerPlayer serverPlayer && player.level() instanceof ServerLevel serverLevel) {
|
||||
ParticleTool.sendParticle(serverLevel, ParticleTypes.CLOUD, player.getX() + 1.8 * player.getLookAngle().x, player.getY() + player.getBbHeight() - 0.1 + 1.8 * player.getLookAngle().y,
|
||||
player.getZ() + 1.8 * player.getLookAngle().z, 30, 0.4, 0.4, 0.4, 0.005, true, serverPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.getItem() == ModItems.SENTINEL.get()) {
|
||||
var cap = stack.getCapability(Capabilities.EnergyStorage.ITEM);
|
||||
if (cap != null) {
|
||||
cap.extractEnergy(3000, false);
|
||||
}
|
||||
}
|
||||
|
||||
// var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO);
|
||||
|
||||
for (int index0 = 0; index0 < (
|
||||
// todo perk
|
||||
// perk instanceof AmmoPerk ammoPerk && ammoPerk.slug ? 1 : projectileAmount
|
||||
projectileAmount
|
||||
); index0++) {
|
||||
GunEventHandler.gunShoot(player, spared);
|
||||
}
|
||||
|
||||
GunEventHandler.playGunSounds(player);
|
||||
}
|
||||
} else if (stack.is(ModItems.MINIGUN.get())) {
|
||||
var tag = NBTTool.getTag(stack);
|
||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||
if (cap == null) return;
|
||||
|
||||
if (cap.rifleAmmo > 0 || InventoryTool.hasCreativeAmmoBox(player)) {
|
||||
tag.putDouble("heat", (tag.getDouble("heat") + 0.1));
|
||||
if (tag.getDouble("heat") >= 50.5) {
|
||||
tag.putDouble("overheat", 40);
|
||||
player.getCooldowns().addCooldown(stack.getItem(), 40);
|
||||
if (!player.level().isClientSide() && player instanceof ServerPlayer serverPlayer) {
|
||||
SoundTool.playLocalSound(serverPlayer, ModSounds.MINIGUN_OVERHEAT.get(), 2f, 1f);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO perk
|
||||
// var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO);
|
||||
float pitch = tag.getDouble("heat") <= 40 ? 1 : (float) (1 - 0.025 * Math.abs(40 - tag.getDouble("heat")));
|
||||
|
||||
if (!player.level().isClientSide() && player instanceof ServerPlayer) {
|
||||
float soundRadius = (float) GunsTool.getGunDoubleTag(stack, "SoundRadius");
|
||||
|
||||
player.playSound(ModSounds.MINIGUN_FIRE_3P.get(), soundRadius * 0.2f, pitch);
|
||||
player.playSound(ModSounds.MINIGUN_FAR.get(), soundRadius * 0.5f, pitch);
|
||||
player.playSound(ModSounds.MINIGUN_VERYFAR.get(), soundRadius, pitch);
|
||||
|
||||
// if (perk == ModPerks.BEAST_BULLET.get()) {
|
||||
// player.playSound(ModSounds.HENG.get(), 4f, pitch);
|
||||
// }
|
||||
}
|
||||
|
||||
GunEventHandler.gunShoot(player, spared);
|
||||
if (!InventoryTool.hasCreativeAmmoBox(player)) {
|
||||
cap.rifleAmmo = cap.rifleAmmo - 1;
|
||||
cap.syncPlayerVariables(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Type<? extends CustomPacketPayload> type() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.atsuishio.superbwarfare.network.message.send;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.ControllableVehicle;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
||||
import com.atsuishio.superbwarfare.init.ModItems;
|
||||
import com.atsuishio.superbwarfare.tools.EntityFindUtil;
|
||||
import com.atsuishio.superbwarfare.tools.NBTTool;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
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.world.item.ItemStack;
|
||||
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public record VehicleMovementMessage(short keys) implements CustomPacketPayload {
|
||||
public static final Type<VehicleMovementMessage> TYPE = new Type<>(ModUtils.loc("vehicle_movement"));
|
||||
|
||||
public static final StreamCodec<ByteBuf, VehicleMovementMessage> STREAM_CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.SHORT,
|
||||
VehicleMovementMessage::keys,
|
||||
VehicleMovementMessage::new
|
||||
);
|
||||
|
||||
public static void handler(final VehicleMovementMessage message, final IPayloadContext context) {
|
||||
var player = (ServerPlayer) context.player();
|
||||
var entity = player.getVehicle();
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
|
||||
VehicleEntity vehicle = null;
|
||||
if (entity instanceof MobileVehicleEntity mobileVehicleEntity) {
|
||||
if (mobileVehicleEntity.getFirstPassenger() != player) return;
|
||||
vehicle = mobileVehicleEntity;
|
||||
} else if (stack.is(ModItems.MONITOR.get())
|
||||
&& NBTTool.getBoolean(stack, "Using", false)
|
||||
&& NBTTool.getBoolean(stack, "Linked", false)
|
||||
) vehicle = EntityFindUtil.findDrone(player.level(), NBTTool.getTag(stack).getString("LinkedDrone"));
|
||||
|
||||
if (!(vehicle instanceof ControllableVehicle controllable)) return;
|
||||
controllable.processInput(message.keys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Type<? extends CustomPacketPayload> type() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package com.atsuishio.superbwarfare.tools;
|
||||
|
||||
import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
|
||||
import com.atsuishio.superbwarfare.network.message.ShakeClientMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.ShakeClientMessage;
|
||||
import com.google.common.collect.Sets;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package com.atsuishio.superbwarfare.tools;
|
||||
|
||||
import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.damagesource.DamageType;
|
||||
|
||||
public class DamageTypeTool {
|
||||
|
||||
public static boolean isGunDamage(DamageSource source) {
|
||||
return source.is(ModDamageTypes.GUN_FIRE) || source.is(ModDamageTypes.GUN_FIRE_HEADSHOT)
|
||||
|| source.is(ModDamageTypes.GUN_FIRE_ABSOLUTE) || source.is(ModDamageTypes.GUN_FIRE_HEADSHOT_ABSOLUTE)
|
||||
|| source.is(ModDamageTypes.SHOCK) || source.is(ModDamageTypes.BURN)
|
||||
|| source.is(ModDamageTypes.LASER) || source.is(ModDamageTypes.LASER_HEADSHOT);
|
||||
}
|
||||
|
||||
public static boolean isGunDamage(ResourceKey<DamageType> damageType) {
|
||||
return damageType == ModDamageTypes.GUN_FIRE || damageType == ModDamageTypes.GUN_FIRE_HEADSHOT
|
||||
|| damageType == ModDamageTypes.GUN_FIRE_ABSOLUTE || damageType == ModDamageTypes.GUN_FIRE_HEADSHOT_ABSOLUTE;
|
||||
}
|
||||
|
||||
public static boolean isExplosionDamage(DamageSource source) {
|
||||
return source.is(ModDamageTypes.CUSTOM_EXPLOSION) || source.is(ModDamageTypes.PROJECTILE_BOOM);
|
||||
}
|
||||
|
||||
public static boolean isHeadshotDamage(DamageSource source) {
|
||||
return source.is(ModDamageTypes.GUN_FIRE_HEADSHOT) || source.is(ModDamageTypes.GUN_FIRE_HEADSHOT_ABSOLUTE);
|
||||
}
|
||||
|
||||
public static boolean isGunFireDamage(DamageSource source) {
|
||||
return source.is(ModDamageTypes.GUN_FIRE) || source.is(ModDamageTypes.GUN_FIRE_ABSOLUTE)
|
||||
|| source.is(ModDamageTypes.SHOCK) || source.is(ModDamageTypes.BURN)
|
||||
|| source.is(ModDamageTypes.LASER) || source.is(ModDamageTypes.LASER_HEADSHOT);
|
||||
}
|
||||
|
||||
public static boolean isModDamage(DamageSource source) {
|
||||
return source.is(ModDamageTypes.GUN_FIRE_ABSOLUTE) || source.is(ModDamageTypes.GUN_FIRE_HEADSHOT_ABSOLUTE)
|
||||
|| source.is(ModDamageTypes.GUN_FIRE) || source.is(ModDamageTypes.GUN_FIRE_HEADSHOT)
|
||||
|| source.is(ModDamageTypes.MINE) || source.is(ModDamageTypes.MINE) || source.is(ModDamageTypes.SHOCK)
|
||||
|| source.is(ModDamageTypes.PROJECTILE_BOOM) || source.is(ModDamageTypes.CANNON_FIRE)
|
||||
|| source.is(ModDamageTypes.BURN)
|
||||
|| source.is(ModDamageTypes.LASER) || source.is(ModDamageTypes.LASER_HEADSHOT);
|
||||
}
|
||||
|
||||
}
|
|
@ -4,7 +4,7 @@ import com.atsuishio.superbwarfare.ModUtils;
|
|||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||
import com.atsuishio.superbwarfare.init.ModTags;
|
||||
import com.atsuishio.superbwarfare.item.gun.GunItem;
|
||||
import com.atsuishio.superbwarfare.network.message.GunsDataMessage;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.GunsDataMessage;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
|
|
@ -2,3 +2,4 @@ public net.minecraft.client.multiplayer.ClientLevel getEntities()Lnet/minecraft/
|
|||
public net.minecraft.world.entity.Entity passengers # passengers
|
||||
public net.minecraft.world.entity.Entity boardingCooldown # boardingCooldown
|
||||
public net.minecraft.client.player.LocalPlayer handsBusy # handsBusy
|
||||
public net.minecraft.client.renderer.culling.Frustum matrix # matrix
|
Loading…
Add table
Reference in a new issue