重写过热

This commit is contained in:
Atsuishio 2025-04-21 11:46:21 +08:00 committed by Light_Quanta
parent 88780bfc2e
commit f3b9f9aaf1
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
10 changed files with 86 additions and 156 deletions

View file

@ -1,4 +1,4 @@
// 1.21.1 2025-04-18T00:48:29.3124197 Tags for minecraft:item mod id superbwarfare
// 1.21.1 2025-04-21T19:07:09.7051757 Tags for minecraft:item mod id superbwarfare
44a232152f5941d0435a35483b37f8ed22fd10bf data/c/tags/item/dusts.json
0fa06c2ff83bf09797e3ddff90f62d1124e645b4 data/c/tags/item/dusts/coal_coke.json
295ddf906b7133a0558d03e9a60eea18281fe430 data/c/tags/item/dusts/iron.json
@ -41,7 +41,7 @@ d39c5c787667ce78c214bc2fbd4931891ebaf936 data/superbwarfare/tags/item/launcher.j
ab580f3989177c0589c43ca346db571011600187 data/superbwarfare/tags/item/launcher/grenade.json
b404c6fd99d2ca68c6738f225cb7d68ee443c10a data/superbwarfare/tags/item/machine_gun.json
a53020091752016da6602ee1b8b7e08823614344 data/superbwarfare/tags/item/military_armor.json
9e203e417380442166a000bca86744916a2fb1c5 data/superbwarfare/tags/item/normal_gun.json
8ea4fb7d3981141a953bd5510e8c76fb790307aa data/superbwarfare/tags/item/normal_gun.json
15328cd564c931cc0a4fc000596240f93a7b29a1 data/superbwarfare/tags/item/revolver.json
aaa533157491a82b8e23b2914deef67c4078cbed data/superbwarfare/tags/item/rifle.json
a249d9d052cdc24b34e0e51ab991329f6c76e8ab data/superbwarfare/tags/item/shotgun.json

View file

@ -31,6 +31,7 @@
"superbwarfare:mp_443",
"superbwarfare:insidious",
"superbwarfare:secondary_cataclysm",
"superbwarfare:taser"
"superbwarfare:taser",
"superbwarfare:minigun"
]
}

View file

@ -3,8 +3,8 @@ package com.atsuishio.superbwarfare.client.layer.gun;
import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.client.ModRenderTypes;
import com.atsuishio.superbwarfare.item.gun.GunItem;
import com.atsuishio.superbwarfare.item.gun.data.GunData;
import com.atsuishio.superbwarfare.item.gun.machinegun.MinigunItem;
import com.atsuishio.superbwarfare.tools.NBTTool;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.Minecraft;
@ -33,9 +33,12 @@ public class MinigunHeatLayer extends GeoRenderLayer<MinigunItem> {
if (player == null) return;
ItemStack stack = player.getMainHandItem();
if (!(stack.getItem() instanceof GunItem)) return;
float heat = (float) NBTTool.getTag(stack).getDouble("heat");
var color = FastColor.ARGB32.color(1, (int) (heat / 55 * 255), (int) (heat / 55 * 255), (int) (heat / 55 * 255));
getRenderer().reRender(getDefaultBakedModel(animatable), poseStack, bufferSource, animatable, glowRenderType, bufferSource.getBuffer(glowRenderType), partialTick, packedLight, OverlayTexture.NO_OVERLAY, color);
var data = GunData.from(stack);
float heat = (float) data.heat.get();
var value = Math.round(heat / 100 * 255);
getRenderer().reRender(getDefaultBakedModel(animatable), poseStack, bufferSource, animatable, glowRenderType, bufferSource.getBuffer(glowRenderType), partialTick, packedLight, OverlayTexture.NO_OVERLAY, FastColor.ARGB32.color(value, value, value));
}
}

View file

@ -98,8 +98,7 @@ public class ModItemTagProvider extends ItemTagsProvider {
ModItems.SKS.get(), ModItems.RPK.get(), ModItems.HK_416.get(), ModItems.AA_12.get(), ModItems.M_4.get(), ModItems.DEVOTION.get(), ModItems.TRACHELIUM.get(), ModItems.M_79.get(),
ModItems.HUNTING_RIFLE.get(), ModItems.NTW_20.get(), ModItems.M_98B.get(), ModItems.SENTINEL.get(), ModItems.M_870.get(), ModItems.MARLIN.get(), ModItems.GLOCK_17.get(), ModItems.RPG.get(),
ModItems.GLOCK_18.get(), ModItems.M_1911.get(), ModItems.QBZ_95.get(), ModItems.K_98.get(), ModItems.MOSIN_NAGANT.get(), ModItems.MP_443.get(), ModItems.INSIDIOUS.get(), ModItems.SECONDARY_CATACLYSM.get(),
ModItems.TASER.get()
);
ModItems.TASER.get(), ModItems.MINIGUN.get());
this.tag(ModTags.Items.LAUNCHER).add(ModItems.RPG.get(), ModItems.JAVELIN.get())
.addTag(ModTags.Items.LAUNCHER_GRENADE);

View file

@ -498,7 +498,7 @@ public class ClientEventHandler {
}
ItemStack stack = player.getMainHandItem();
if (!(stack.getItem() instanceof GunItem)) {
if (!(stack.getItem() instanceof GunItem gunItem)) {
clientTimer.stop();
fireSpread = 0;
gunSpread = 0;
@ -580,6 +580,8 @@ public class ClientEventHandler {
if (((holdFire || burstFireAmount > 0) && shootDelay >= data.shootDelay())
&& !(player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.banHand(player))
&& !holdFireVehicle
&& gunItem.canShoot(data)
&& !data.overHeat.get()
&& (stack.is(ModTags.Items.NORMAL_GUN)
&& cantFireTime == 0
&& drawTime < 0.01
@ -590,18 +592,13 @@ public class ClientEventHandler {
&& !data.charging()
&& data.hasEnoughAmmoToShoot(player)
&& !player.getCooldowns().isOnCooldown(stack.getItem())
&& !data.bolt.needed.get()
&& !GunData.from(stack).bolt.needed.get()
&& revolverPre(data))
|| (stack.is(ModItems.MINIGUN.get())
&& !player.isSprinting()
&& tag.getDouble("overheat") == 0
&& !player.getCooldowns().isOnCooldown(stack.getItem())
&& data.hasBackupAmmo(player)
))) {
)) {
if (mode == 0) {
if (clientTimer.getProgress() == 0) {
clientTimer.start();
shootClient(player, tag);
shootClient(player);
}
} else {
if (!clientTimer.started()) {
@ -611,7 +608,7 @@ public class ClientEventHandler {
}
if (clientTimer.getProgress() >= cooldown) {
shootClient(player, tag);
shootClient(player);
clientTimer.setProgress((clientTimer.getProgress() - cooldown));
}
}
@ -661,7 +658,7 @@ public class ClientEventHandler {
}
}
public static void shootClient(Player player, final CompoundTag tag) {
public static void shootClient(Player player) {
ItemStack stack = player.getMainHandItem();
if (!(stack.getItem() instanceof GunItem gunItem)) return;
var data = GunData.from(stack);
@ -709,23 +706,6 @@ public class ClientEventHandler {
revolverWheelPreTime = 0;
playGunClientSounds(player);
handleClientShoot();
} else if (stack.is(ModItems.MINIGUN.get())) {
// TODO 提取通用过热处理方法
var perk = data.perk.get(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);
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())));
Mod.queueClientWork((int) (1 + 1.5 * shooterHeight), () -> player.playSound(ModSounds.SHELL_CASING_NORMAL.get(), (float) Math.max(1.5 - 0.2 * shooterHeight, 0), 1));
handleClientShoot();
}
}
@ -735,16 +715,13 @@ public class ClientEventHandler {
actionMove = Mth.lerp(0.125 * times, actionMove, 0);
}
// TODO 完善canShoot()方法提前判断是否能开火
public static void handleClientShoot() {
Player player = Minecraft.getInstance().player;
if (player == null) return;
ItemStack stack = player.getMainHandItem();
if (!(stack.getItem() instanceof GunItem gunItem)) return;
if (!(stack.getItem() instanceof GunItem)) return;
var data = GunData.from(stack);
if (!gunItem.canShoot(data)) return;
PacketDistributor.sendToServer(new ShootMessage(gunSpread, zoom));
fireRecoilTime = 10;
@ -807,9 +784,10 @@ public class ClientEventHandler {
}
var data = GunData.from(stack);
var perk = data.perk.get(Perk.Type.AMMO);
float pitch = data.heat.get() <= 75 ? 1 : (float) (1 - 0.02 * Math.abs(75 - data.heat.get()));
if (perk == ModPerks.BEAST_BULLET.get()) {
player.playSound(ModSounds.HENG.get(), 1f, (float) ((2 * org.joml.Math.random() - 1) * 0.1f + 1.0f));
player.playSound(ModSounds.HENG.get(), 1f, (float) ((2 * org.joml.Math.random() - 1) * 0.1f + pitch));
}
int barrelType = data.attachment.get(AttachmentType.BARREL);
@ -817,7 +795,7 @@ public class ClientEventHandler {
SoundEvent sound1p = BuiltInRegistries.SOUND_EVENT.get(Mod.loc(name + (barrelType == 2 ? "_fire_1p_s" : "_fire_1p")));
if (sound1p != null) {
player.playSound(sound1p, 4f, (float) ((2 * org.joml.Math.random() - 1) * 0.05f + 1.0f));
player.playSound(sound1p, 4f, (float) ((2 * org.joml.Math.random() - 1) * 0.05f + pitch));
}
double shooterHeight = player.getEyePosition().distanceTo((Vec3.atLowerCornerOf(player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(new Vec3(0, -1, 0).scale(10)),

View file

@ -10,13 +10,16 @@ import com.atsuishio.superbwarfare.item.gun.data.GunData;
import com.atsuishio.superbwarfare.item.gun.data.value.AttachmentType;
import com.atsuishio.superbwarfare.perk.AmmoPerk;
import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.tools.SoundTool;
import net.minecraft.client.model.HumanoidModel;
import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
@ -90,6 +93,24 @@ public abstract class GunItem extends Item implements CustomRendererItem {
capability.sync(entity);
data.ammo.set(magazine + (hasBulletInBarrel ? 1 : 0));
}
//冷却
double cooldown = 0;
if (entity.wasInPowderSnow) {
cooldown = 0.15;
} else if (entity.isInWaterOrRain()) {
cooldown = 0.04;
} else if (entity.isOnFire() || entity.isInLava()) {
cooldown = -0.1;
}
data.heat.set(Mth.clamp(data.heat.get() - 0.25 - cooldown, 0, 100));
if (data.heat.get() < 80 && data.overHeat.get()) {
data.overHeat.set(false);
}
data.save();
}
@ -533,6 +554,18 @@ public abstract class GunItem extends Item implements CustomRendererItem {
if (!shootBullet(player, data, spread, zoom)) return;
}
// 添加热量
data.heat.set(Mth.clamp(data.heat.get() + data.addHeat(), 0, 100));
// 过热
if (data.heat.get() >= 100 && !data.overHeat.get()) {
data.overHeat.set(true);
if (!player.level().isClientSide() && player instanceof ServerPlayer serverPlayer) {
SoundTool.playLocalSound(serverPlayer, ModSounds.MINIGUN_OVERHEAT.get(), 2f, 1f);
}
}
data.item.afterShoot(data, player);
playFireSounds(data, player, zoom);
}
@ -547,9 +580,11 @@ public abstract class GunItem extends Item implements CustomRendererItem {
String origin = stack.getItem().getDescriptionId();
String name = origin.substring(origin.lastIndexOf(".") + 1);
float pitch = data.heat.get() <= 75 ? 1 : (float) (1 - 0.02 * Math.abs(75 - data.heat.get()));
var perk = data.perk.get(Perk.Type.AMMO);
if (perk == ModPerks.BEAST_BULLET.get()) {
player.playSound(ModSounds.HENG.get(), 4f, 1f);
player.playSound(ModSounds.HENG.get(), 4f, pitch);
}
float soundRadius = (float) data.soundRadius();
@ -557,17 +592,17 @@ public abstract class GunItem extends Item implements CustomRendererItem {
SoundEvent sound3p = BuiltInRegistries.SOUND_EVENT.get(Mod.loc(name + (barrelType == 2 ? "_fire_3p_s" : "_fire_3p")));
if (sound3p != null) {
player.playSound(sound3p, soundRadius * 0.4f, 1f);
player.playSound(sound3p, soundRadius * 0.4f, pitch);
}
SoundEvent soundFar = BuiltInRegistries.SOUND_EVENT.get(Mod.loc(name + (barrelType == 2 ? "_far_s" : "_far")));
if (soundFar != null) {
player.playSound(soundFar, soundRadius * 0.7f, 1f);
player.playSound(soundFar, soundRadius * 0.7f, pitch);
}
SoundEvent soundVeryFar = BuiltInRegistries.SOUND_EVENT.get(Mod.loc(name + (barrelType == 2 ? "_veryfar_s" : "_veryfar")));
if (soundVeryFar != null) {
player.playSound(soundVeryFar, soundRadius, 1f);
player.playSound(soundVeryFar, soundRadius, pitch);
}
}

View file

@ -70,4 +70,6 @@ public class DefaultGunData {
@SerializedName("ShootDelay")
public int shootDelay = 0;
@SerializedName("AddHeat")
public double addHeat = 0;
}

View file

@ -77,6 +77,8 @@ public class GunData {
hideBulletChain = new BooleanValue(data, "HideBulletChain");
draw = new BooleanValue(data, "Draw");
sensitivity = new IntValue(data, "Sensitivity");
heat = new DoubleValue(data, "Heat");
overHeat = new BooleanValue(data, "OverHeat");
}
private CompoundTag getOrPut(String name) {
@ -281,6 +283,10 @@ public class GunData {
return defaultGunData().shootDelay;
}
public double addHeat() {
return defaultGunData().addHeat;
}
public enum AmmoConsumeType {
PLAYER_AMMO, ITEM, TAG, INVALID,
}
@ -430,6 +436,9 @@ public class GunData {
public final IntValue level;
public final DoubleValue exp;
public final DoubleValue upgradePoint;
public final DoubleValue heat;
public final BooleanValue overHeat;
public boolean canAdjustZoom() {
return item.canAdjustZoom(stack);

View file

@ -4,37 +4,24 @@ import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.client.renderer.item.MinigunItemRenderer;
import com.atsuishio.superbwarfare.event.ClientEventHandler;
import com.atsuishio.superbwarfare.init.ModEnumExtensions;
import com.atsuishio.superbwarfare.init.ModParticleTypes;
import com.atsuishio.superbwarfare.init.ModPerks;
import com.atsuishio.superbwarfare.init.ModSounds;
import com.atsuishio.superbwarfare.item.gun.GunItem;
import com.atsuishio.superbwarfare.item.gun.data.GunData;
import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.tools.NBTTool;
import com.atsuishio.superbwarfare.tools.ParticleTool;
import com.atsuishio.superbwarfare.tools.SoundTool;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull;
import org.joml.Vector3d;
import software.bernie.geckolib.animatable.GeoItem;
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.animation.*;
import software.bernie.geckolib.renderer.GeoItemRenderer;
import software.bernie.geckolib.util.GeckoLibUtil;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.function.Supplier;
public class MinigunItem extends GunItem implements GeoItem {
@ -43,7 +30,6 @@ public class MinigunItem extends GunItem implements GeoItem {
return GunData.from(stack).data().getInt("CustomRPM");
}
private static final String TAG_HEAT = "heat";
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
public static ItemDisplayContext transformType;
@ -52,18 +38,21 @@ public class MinigunItem extends GunItem implements GeoItem {
}
@Override
public boolean isBarVisible(@NotNull ItemStack pStack) {
return NBTTool.getTag(pStack).getDouble(TAG_HEAT) != 0;
public boolean isBarVisible(@NotNull ItemStack stack) {
var data = GunData.from(stack);
return data.heat.get() != 0;
}
@Override
public int getBarWidth(@NotNull ItemStack pStack) {
return Math.round((float) NBTTool.getTag(pStack).getDouble(TAG_HEAT) * 13.0F / 51F);
public int getBarWidth(@NotNull ItemStack stack) {
var data = GunData.from(stack);
return Math.round((float) data.heat.get() * 13.0F / 100F);
}
@Override
public int getBarColor(@NotNull ItemStack pStack) {
double f = 1 - NBTTool.getTag(pStack).getDouble(TAG_HEAT) / 55.0F;
public int getBarColor(@NotNull ItemStack stack) {
var data = GunData.from(stack);
double f = 1 - data.heat.get() / 100.0F;
return Mth.hsvToRgb((float) f / 3.0F, 1.0F, 1.0F);
}
@ -103,94 +92,6 @@ public class MinigunItem extends GunItem implements GeoItem {
return this.cache;
}
@Override
@ParametersAreNonnullByDefault
public void inventoryTick(ItemStack stack, Level world, Entity entity, int slot, boolean selected) {
super.inventoryTick(stack, world, entity, slot, selected);
float yRot = entity.getYRot();
if (yRot < 0) {
yRot += 360;
}
yRot = yRot + 90 % 360;
var leftPos = new Vector3d(1.2, -0.3, 0.3);
if (entity.isSprinting()) {
leftPos = new Vector3d(1., -0.4, -0.4);
}
leftPos.rotateZ(-entity.getXRot() * Mth.DEG_TO_RAD);
leftPos.rotateY(-yRot * Mth.DEG_TO_RAD);
double cooldown = 0;
if (entity.wasInPowderSnow) {
cooldown = 0.15;
} else if (entity.isInWaterOrRain()) {
cooldown = 0.04;
} else if (entity.isOnFire() || entity.isInLava()) {
cooldown = -0.1;
}
var data = GunData.from(stack);
var tag = data.tag();
if (entity instanceof ServerPlayer serverPlayer && entity.level() instanceof ServerLevel serverLevel && tag.getDouble("heat") > 4 && entity.isInWaterOrRain()) {
if (entity.isInWater()) {
ParticleTool.sendParticle(serverLevel, ParticleTypes.BUBBLE_COLUMN_UP,
entity.getX() + leftPos.x,
entity.getEyeY() + leftPos.y,
entity.getZ() + leftPos.z,
1, 0.1, 0.1, 0.1, 0.002, true, serverPlayer);
}
ParticleTool.sendParticle(serverLevel, ModParticleTypes.CUSTOM_CLOUD.get(),
entity.getX() + leftPos.x,
entity.getEyeY() + leftPos.y,
entity.getZ() + leftPos.z,
1, 0.1, 0.1, 0.1, 0.002, true, serverPlayer);
}
tag.putDouble("heat", Mth.clamp(tag.getDouble("heat") - 0.05 - cooldown, 0, 55));
if (tag.getDouble("overheat") > 0) {
tag.putDouble("overheat", (tag.getDouble("overheat") - 1));
}
data.save();
}
@Override
public void onShoot(GunData data, Player player, double spread, boolean zoom) {
var tag = data.tag();
if (!data.hasBackupAmmo(player)) return;
// TODO 替换为通用过热处理
tag.putDouble("heat", (tag.getDouble("heat") + 0.1));
if (tag.getDouble("heat") >= 50.5) {
tag.putDouble("overheat", 40);
player.getCooldowns().addCooldown(data.item(), 40);
if (!player.level().isClientSide() && player instanceof ServerPlayer serverPlayer) {
SoundTool.playLocalSound(serverPlayer, ModSounds.MINIGUN_OVERHEAT.get(), 2f, 1f);
}
}
float pitch = tag.getDouble("heat") <= 40 ? 1 : (float) (1 - 0.025 * Math.abs(40 - tag.getDouble("heat")));
var perk = data.perk.get(Perk.Type.AMMO);
if (!player.level().isClientSide() && player instanceof ServerPlayer) {
float soundRadius = (float) data.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);
}
}
shootBullet(player, data, spread, zoom);
data.consumeBackupAmmo(player, 1);
}
@Override
public ResourceLocation getGunIcon() {
return Mod.loc("textures/gun_icon/minigun_icon.png");

View file

@ -9,6 +9,8 @@
"BypassesArmor": 0.3,
"SoundRadius": 14,
"RPM": 1200,
"FireMode": 2,
"AmmoType": "@RifleAmmo",
"ShootDelay": 20
"ShootDelay": 20,
"AddHeat": 0.5
}