尝试添加Vector

This commit is contained in:
Light_Quanta 2025-03-27 04:59:03 +08:00
parent ce35973766
commit 43df61a9dd
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
90 changed files with 5097 additions and 27 deletions

View file

@ -0,0 +1,6 @@
{
"values": [
"#c:dusts/coal_coke",
"#c:dusts/tungsten"
]
}

View file

@ -0,0 +1,5 @@
{
"values": [
"superbwarfare:coal_powder"
]
}

View file

@ -0,0 +1,5 @@
{
"values": [
"superbwarfare:iron_powder"
]
}

View file

@ -0,0 +1,5 @@
{
"values": [
"superbwarfare:tungsten_powder"
]
}

View file

@ -0,0 +1,8 @@
{
"values": [
"#c:ingots/lead",
"#c:ingots/steel",
"#c:ingots/tungsten",
"#c:ingots/silver"
]
}

View file

@ -0,0 +1,5 @@
{
"values": [
"superbwarfare:lead_ingot"
]
}

View file

@ -0,0 +1,5 @@
{
"values": [
"superbwarfare:silver_ingot"
]
}

View file

@ -0,0 +1,5 @@
{
"values": [
"superbwarfare:steel_ingot"
]
}

View file

@ -0,0 +1,5 @@
{
"values": [
"superbwarfare:tungsten_ingot"
]
}

View file

@ -0,0 +1,10 @@
{
"values": [
"superbwarfare:galena_ore",
"superbwarfare:deepslate_galena_ore",
"superbwarfare:scheelite_ore",
"superbwarfare:deepslate_scheelite_ore",
"superbwarfare:silver_ore",
"superbwarfare:deepslate_silver_ore"
]
}

View file

@ -0,0 +1,7 @@
{
"values": [
"#c:ores/lead",
"#c:ores/tungsten",
"#c:ores/silver"
]
}

View file

@ -0,0 +1,6 @@
{
"values": [
"superbwarfare:galena_ore",
"superbwarfare:deepslate_galena_ore"
]
}

View file

@ -0,0 +1,6 @@
{
"values": [
"superbwarfare:scheelite_ore",
"superbwarfare:deepslate_scheelite_ore"
]
}

View file

@ -0,0 +1,5 @@
{
"values": [
"superbwarfare:raw_silver"
]
}

View file

@ -0,0 +1,8 @@
{
"values": [
"#c:storage_blocks/lead",
"#c:storage_blocks/steel",
"#c:storage_blocks/tungsten",
"#c:storage_blocks/silver"
]
}

View file

@ -0,0 +1,5 @@
{
"values": [
"superbwarfare:lead_block"
]
}

View file

@ -0,0 +1,5 @@
{
"values": [
"superbwarfare:silver_block"
]
}

View file

@ -0,0 +1,5 @@
{
"values": [
"superbwarfare:steel_block"
]
}

View file

@ -0,0 +1,5 @@
{
"values": [
"superbwarfare:tungsten_block"
]
}

View file

@ -0,0 +1,5 @@
{
"values": [
"superbwarfare:barbed_wire"
]
}

View file

@ -0,0 +1,21 @@
{
"values": [
"superbwarfare:galena_ore",
"superbwarfare:scheelite_ore",
"superbwarfare:deepslate_galena_ore",
"superbwarfare:deepslate_scheelite_ore",
"superbwarfare:dragon_teeth",
"superbwarfare:reforging_table",
"superbwarfare:lead_block",
"superbwarfare:steel_block",
"superbwarfare:tungsten_block",
"superbwarfare:cemented_carbide_block",
"superbwarfare:silver_ore",
"superbwarfare:deepslate_silver_ore",
"superbwarfare:silver_block",
"superbwarfare:jump_pad",
"superbwarfare:container",
"superbwarfare:charging_station",
"superbwarfare:fumo_25"
]
}

View file

@ -0,0 +1,5 @@
{
"values": [
"superbwarfare:sandbag"
]
}

View file

@ -0,0 +1,11 @@
{
"values": [
"superbwarfare:galena_ore",
"superbwarfare:scheelite_ore",
"superbwarfare:deepslate_galena_ore",
"superbwarfare:deepslate_scheelite_ore",
"superbwarfare:dragon_teeth",
"superbwarfare:silver_ore",
"superbwarfare:deepslate_silver_ore"
]
}

View file

@ -0,0 +1,14 @@
{
"values": [
"#minecraft:logs",
"#minecraft:planks",
"#c:glass_blocks",
"#c:glass_panes",
"#minecraft:wooden_slabs",
"#minecraft:wooden_stairs",
"minecraft:ice",
"minecraft:frosted_ice",
"minecraft:packed_ice",
"minecraft:blue_ice"
]
}

View file

@ -0,0 +1,22 @@
{
"values": [
"#minecraft:leaves",
"#minecraft:fences",
"#minecraft:fence_gates",
"#minecraft:doors",
"#minecraft:trapdoors",
"#minecraft:walls",
"minecraft:cactus",
"minecraft:bamboo",
"minecraft:melon",
"minecraft:pumpkin",
"minecraft:hay_block",
"minecraft:bell",
"minecraft:chain",
"minecraft:snow_block",
"minecraft:cobweb",
"minecraft:mushroom_stem",
"minecraft:brown_mushroom_block",
"minecraft:red_mushroom_block"
]
}

View file

@ -0,0 +1,9 @@
{
"values": [
"superbwarfare:cemented_carbide_ingot",
{
"id": "dreamaticvoyage:hqss_bread_ingot",
"required": false
}
]
}

View file

@ -0,0 +1,9 @@
{
"values": [
"#c:ingots/steel",
{
"id": "dreamaticvoyage:fukamizu_bread_ingot",
"required": false
}
]
}

View file

@ -0,0 +1,9 @@
{
"values": [
"superbwarfare:cemented_carbide_block",
{
"id": "dreamaticvoyage:hqss_bread_bricks",
"required": false
}
]
}

View file

@ -0,0 +1,73 @@
package com.atsuishio.superbwarfare.client;
import com.atsuishio.superbwarfare.event.ClientEventHandler;
import com.atsuishio.superbwarfare.tools.GunsTool;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.util.FastColor;
import net.minecraft.util.Mth;
import net.minecraft.world.item.ItemStack;
import software.bernie.geckolib.animation.AnimationProcessor;
import software.bernie.geckolib.cache.object.GeoBone;
public class AnimationHelper {
public static void renderPartOverBone(ModelPart model, GeoBone bone, PoseStack stack, VertexConsumer buffer, int packedLightIn, int packedOverlayIn, float alpha) {
renderPartOverBone(model, bone, stack, buffer, packedLightIn, packedOverlayIn, 1.0f, 1.0f, 1.0f, alpha);
}
public static void renderPartOverBone(ModelPart model, GeoBone bone, PoseStack stack, VertexConsumer buffer, int packedLightIn, int packedOverlayIn, float r, float g, float b, float a) {
setupModelFromBone(model, bone);
var color = FastColor.ARGB32.color((int) (a * 255), (int) (r * 255), (int) (g * 255), (int) (b * 255));
model.render(stack, buffer, packedLightIn, packedOverlayIn, color);
}
public static void setupModelFromBone(ModelPart model, GeoBone bone) {
model.setPos(bone.getPivotX(), bone.getPivotY(), bone.getPivotZ());
model.xRot = 0.0f;
model.yRot = 0.0f;
model.zRot = 0.0f;
}
public static void renderPartOverBone2(ModelPart model, GeoBone bone, PoseStack stack, VertexConsumer buffer, int packedLightIn, int packedOverlayIn, float alpha) {
renderPartOverBone2(model, bone, stack, buffer, packedLightIn, packedOverlayIn, 1.0f, 1.0f, 1.0f, alpha);
}
public static void renderPartOverBone2(ModelPart model, GeoBone bone, PoseStack stack, VertexConsumer buffer, int packedLightIn, int packedOverlayIn, float r, float g, float b, float a) {
setupModelFromBone2(model, bone);
var color = FastColor.ARGB32.color((int) (a * 255), (int) (r * 255), (int) (g * 255), (int) (b * 255));
model.render(stack, buffer, packedLightIn, packedOverlayIn, color);
}
public static void setupModelFromBone2(ModelPart model, GeoBone bone) {
model.setPos(bone.getPivotX(), bone.getPivotY() + 7, bone.getPivotZ());
model.xRot = 0.0f;
model.yRot = 180 * Mth.DEG_TO_RAD;
model.zRot = 180 * Mth.DEG_TO_RAD;
}
public static void handleShellsAnimation(AnimationProcessor<?> animationProcessor, float x, float y) {
GeoBone shell1 = animationProcessor.getBone("shell1");
GeoBone shell2 = animationProcessor.getBone("shell2");
GeoBone shell3 = animationProcessor.getBone("shell3");
GeoBone shell4 = animationProcessor.getBone("shell4");
GeoBone shell5 = animationProcessor.getBone("shell5");
ClientEventHandler.handleShells(x, y, shell1, shell2, shell3, shell4, shell5);
}
public static void handleReloadShakeAnimation(ItemStack stack, GeoBone main, GeoBone camera, float roll, float pitch) {
if (GunsTool.getGunIntTag(stack, "ReloadTime") > 0) {
main.setRotX(roll * main.getRotX());
main.setRotY(roll * main.getRotY());
main.setRotZ(roll * main.getRotZ());
main.setPosX(pitch * main.getPosX());
main.setPosY(pitch * main.getPosY());
main.setPosZ(pitch * main.getPosZ());
camera.setRotX(roll * camera.getRotX());
camera.setRotY(roll * camera.getRotY());
camera.setRotZ(roll * camera.getRotZ());
}
}
}

View file

@ -0,0 +1,28 @@
package com.atsuishio.superbwarfare.client;
import com.atsuishio.superbwarfare.tools.GunsTool;
import com.atsuishio.superbwarfare.tools.NBTTool;
import net.minecraft.client.model.HumanoidModel;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
@OnlyIn(Dist.CLIENT)
public class PoseTool {
public static HumanoidModel.ArmPose pose(LivingEntity entityLiving, InteractionHand hand, ItemStack stack) {
var tag = NBTTool.getOrCreateTag(stack);
if (tag.getBoolean("is_empty_reloading")
|| tag.getBoolean("is_normal_reloading")
|| GunsTool.getGunBooleanTag(stack, "Reloading")
|| GunsTool.getGunBooleanTag(stack, "Charging")) {
return HumanoidModel.ArmPose.CROSSBOW_CHARGE;
} else if (entityLiving.isSprinting() && entityLiving.onGround() && entityLiving.getPersistentData().getDouble("noRun") == 0) {
return HumanoidModel.ArmPose.CROSSBOW_CHARGE;
} else {
return HumanoidModel.ArmPose.BOW_AND_ARROW;
}
}
}

View file

@ -0,0 +1,27 @@
package com.atsuishio.superbwarfare.client.layer;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.item.gun.smg.VectorItem;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.resources.ResourceLocation;
import software.bernie.geckolib.cache.object.BakedGeoModel;
import software.bernie.geckolib.renderer.GeoRenderer;
import software.bernie.geckolib.renderer.layer.GeoRenderLayer;
public class VectorLayer extends GeoRenderLayer<VectorItem> {
private static final ResourceLocation LAYER = ModUtils.loc("textures/item/vector_e.png");
public VectorLayer(GeoRenderer<VectorItem> entityRenderer) {
super(entityRenderer);
}
@Override
public void render(PoseStack poseStack, VectorItem animatable, BakedGeoModel bakedModel, RenderType renderType, MultiBufferSource bufferSource, VertexConsumer buffer, float partialTick, int packedLight, int packedOverlay) {
RenderType glowRenderType = RenderType.eyes(LAYER);
getRenderer().reRender(getDefaultBakedModel(animatable), poseStack, bufferSource, animatable, glowRenderType, bufferSource.getBuffer(glowRenderType), partialTick, packedLight, OverlayTexture.NO_OVERLAY, 0xFFFFFFFF);
}
}

View file

@ -0,0 +1,163 @@
package com.atsuishio.superbwarfare.client.model.item;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.client.AnimationHelper;
import com.atsuishio.superbwarfare.event.ClientEventHandler;
import com.atsuishio.superbwarfare.init.ModTags;
import com.atsuishio.superbwarfare.item.gun.smg.VectorItem;
import com.atsuishio.superbwarfare.tools.GunsTool;
import com.atsuishio.superbwarfare.tools.NBTTool;
import net.minecraft.client.Minecraft;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import software.bernie.geckolib.animation.AnimationState;
import software.bernie.geckolib.cache.object.GeoBone;
import software.bernie.geckolib.model.GeoModel;
import static com.atsuishio.superbwarfare.event.ClientEventHandler.isProne;
public class VectorItemModel extends GeoModel<VectorItem> {
public static float fireRotY = 0f;
public static float fireRotZ = 0f;
public static float rotXBipod = 0f;
public static float rotXSight = 0f;
@Override
public ResourceLocation getAnimationResource(VectorItem animatable) {
return ModUtils.loc("animations/vector.animation.json");
}
@Override
public ResourceLocation getModelResource(VectorItem animatable) {
return ModUtils.loc("geo/vector.geo.json");
}
@Override
public ResourceLocation getTextureResource(VectorItem animatable) {
return ModUtils.loc("textures/item/vector.png");
}
@Override
public void setCustomAnimations(VectorItem animatable, long instanceId, AnimationState animationState) {
GeoBone gun = getAnimationProcessor().getBone("bone");
GeoBone scope = getAnimationProcessor().getBone("Scope1");
GeoBone cross1 = getAnimationProcessor().getBone("Cross1");
GeoBone kmj = getAnimationProcessor().getBone("kuaimanji");
GeoBone sight1fold = getAnimationProcessor().getBone("SightFold1");
GeoBone sight2fold = getAnimationProcessor().getBone("SightFold2");
Player player = Minecraft.getInstance().player;
if (player == null) return;
ItemStack stack = player.getMainHandItem();
if (!stack.is(ModTags.Items.GUN)) return;
int mode = GunsTool.getGunIntTag(stack, "FireMode");
if (mode == 0) {
kmj.setRotX(-120 * Mth.DEG_TO_RAD);
}
if (mode == 1) {
kmj.setRotX(-60 * Mth.DEG_TO_RAD);
}
if (mode == 2) {
kmj.setRotX(0);
}
float times = 0.6f * (float) Math.min(Minecraft.getInstance().getTimer().getGameTimeDeltaTicks(), 0.8);
double zt = ClientEventHandler.zoomTime;
double zp = ClientEventHandler.zoomPos;
double zpz = ClientEventHandler.zoomPosZ;
double swayX = ClientEventHandler.swayX;
double swayY = ClientEventHandler.swayY;
float moveRotZ = (float) ClientEventHandler.moveRotZ;
float movePosX = (float) ClientEventHandler.movePosX;
float movePosY = (float) ClientEventHandler.movePosY;
double mph = ClientEventHandler.movePosHorizon;
double vY = ClientEventHandler.velocityY;
double turnRotX = ClientEventHandler.turnRot[0];
double turnRotY = ClientEventHandler.turnRot[1];
double turnRotZ = ClientEventHandler.turnRot[2];
double fpz = ClientEventHandler.firePosZ * 20 * times;
double fp = ClientEventHandler.firePos;
double fr = ClientEventHandler.fireRot;
int type = GunsTool.getAttachmentType(stack, GunsTool.AttachmentType.SCOPE);
float posY = switch (type) {
case 1 -> 0.74f;
case 2 -> 0.12f;
default -> 0.07f;
};
gun.setPosX(2.356f * (float) zp);
gun.setPosY(posY * (float) zp - (float) (0.2f * zpz));
gun.setPosZ((type == 2 ? 6 : 5) * (float) zp + (float) (0.3f * zpz));
gun.setScaleZ(1f - (0.5f * (float) zp));
scope.setScaleZ(1f - (0.2f * (float) zp));
NBTTool.getOrCreateTag(stack).putBoolean("HoloHidden", gun.getPosX() <= 2);
GeoBone shen;
if (zt < 0.5) {
shen = getAnimationProcessor().getBone("fireRootNormal");
} else {
shen = switch (type) {
case 0 -> getAnimationProcessor().getBone("fireRoot0");
case 1 -> getAnimationProcessor().getBone("fireRoot1");
case 2 -> getAnimationProcessor().getBone("fireRoot2");
default -> getAnimationProcessor().getBone("fireRootNormal");
};
}
fireRotY = (float) Mth.lerp(0.5f * times, fireRotY, 0.2f * ClientEventHandler.recoilHorizon * fpz);
fireRotZ = (float) Mth.lerp(2f * times, fireRotZ, (0.2f + 0.3 * fpz) * ClientEventHandler.recoilHorizon);
shen.setPosX(-0.4f * (float) (ClientEventHandler.recoilHorizon * (0.5 + 0.4 * ClientEventHandler.fireSpread)));
shen.setPosY((float) (0.15f * fp + 0.18f * fr));
shen.setPosZ((float) (0.375 * fp + 0.44f * fr + 0.75 * fpz));
shen.setRotX((float) (0.01f * fp + 0.05f * fr + 0.01f * fpz));
shen.setRotY(fireRotY);
shen.setRotZ(fireRotZ);
shen.setPosX((float) (shen.getPosX() * (1 - 0.1 * zt)));
shen.setPosY((float) (shen.getPosY() * (-1 + 0.8 * zt)));
shen.setPosZ((float) (shen.getPosZ() * (1 - 0.1 * zt)));
shen.setRotX((float) (shen.getRotX() * (1 - (type == 3 ? 0.96 : type == 1 ? 0.8 : 0.9) * zt)));
shen.setRotY((float) (shen.getRotY() * (1 - (type == 3 ? 0.95 : 0.9) * zt)));
shen.setRotZ((float) (shen.getRotZ() * (1 - 0.4 * zt)));
// TODO cross hair overlay gun rot
// CrossHairOverlay.gunRot = shen.getRotZ();
cross1.setPosY(-0.25f * (float) fpz);
rotXSight = Mth.lerp(1.5f * times, rotXSight, type == 0 ? 0 : 90);
sight1fold.setRotX(rotXSight * Mth.DEG_TO_RAD);
sight2fold.setRotX(rotXSight * Mth.DEG_TO_RAD);
GeoBone l = getAnimationProcessor().getBone("l");
GeoBone r = getAnimationProcessor().getBone("r");
rotXBipod = Mth.lerp(1.5f * times, rotXBipod, isProne(player) ? -90 : 0);
l.setRotX(rotXBipod * Mth.DEG_TO_RAD);
r.setRotX(rotXBipod * Mth.DEG_TO_RAD);
GeoBone root = getAnimationProcessor().getBone("root");
root.setPosX((float) (movePosX + 20 * ClientEventHandler.drawTime + 9.3f * mph));
root.setPosY((float) (swayY + movePosY - 40 * ClientEventHandler.drawTime - 2f * vY));
root.setRotX((float) (swayX - Mth.DEG_TO_RAD * 60 * ClientEventHandler.drawTime + Mth.DEG_TO_RAD * turnRotX - 0.15f * vY));
root.setRotY((float) (0.2f * movePosX + Mth.DEG_TO_RAD * 300 * ClientEventHandler.drawTime + Mth.DEG_TO_RAD * turnRotY));
root.setRotZ((float) (0.2f * movePosX + moveRotZ + Mth.DEG_TO_RAD * 90 * ClientEventHandler.drawTime + 2.7f * mph + Mth.DEG_TO_RAD * turnRotZ));
GeoBone camera = getAnimationProcessor().getBone("camera");
GeoBone main = getAnimationProcessor().getBone("0");
float numR = (float) (1 - 0.92 * zt);
float numP = (float) (1 - 0.88 * zt);
AnimationHelper.handleReloadShakeAnimation(stack, main, camera, numR, numP);
ClientEventHandler.shake(Mth.RAD_TO_DEG * camera.getRotX(), Mth.RAD_TO_DEG * camera.getRotY(), Mth.RAD_TO_DEG * camera.getRotZ());
AnimationHelper.handleShellsAnimation(getAnimationProcessor(), 1.2f, 0.45f);
}
}

View file

@ -0,0 +1,158 @@
package com.atsuishio.superbwarfare.client.renderer.item;
import com.atsuishio.superbwarfare.client.AnimationHelper;
import com.atsuishio.superbwarfare.client.layer.VectorLayer;
import com.atsuishio.superbwarfare.client.model.item.VectorItemModel;
import com.atsuishio.superbwarfare.event.ClientEventHandler;
import com.atsuishio.superbwarfare.init.ModTags;
import com.atsuishio.superbwarfare.item.gun.smg.VectorItem;
import com.atsuishio.superbwarfare.tools.GunsTool;
import com.atsuishio.superbwarfare.tools.NBTTool;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.PlayerModel;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.player.PlayerRenderer;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import software.bernie.geckolib.cache.object.BakedGeoModel;
import software.bernie.geckolib.cache.object.GeoBone;
import software.bernie.geckolib.renderer.GeoItemRenderer;
import software.bernie.geckolib.util.RenderUtil;
import java.util.HashSet;
import java.util.Set;
public class VectorItemRenderer extends GeoItemRenderer<VectorItem> {
public VectorItemRenderer() {
super(new VectorItemModel());
this.addRenderLayer(new VectorLayer(this));
}
@Override
public RenderType getRenderType(VectorItem animatable, ResourceLocation texture, MultiBufferSource bufferSource, float partialTick) {
return RenderType.entityTranslucent(getTextureLocation(animatable));
}
private static final float SCALE_RECIPROCAL = 1.0f / 16.0f;
protected boolean renderArms = false;
protected MultiBufferSource currentBuffer;
protected RenderType renderType;
public ItemDisplayContext transformType;
protected VectorItem animatable;
private final Set<String> hiddenBones = new HashSet<>();
@Override
public void renderByItem(ItemStack stack, ItemDisplayContext transformType, PoseStack matrixStack, MultiBufferSource bufferIn, int combinedLightIn, int p_239207_6_) {
this.transformType = transformType;
if (this.animatable != null)
this.animatable.getTransformType(transformType);
super.renderByItem(stack, transformType, matrixStack, bufferIn, combinedLightIn, p_239207_6_);
}
@Override
public void actuallyRender(PoseStack matrixStackIn, VectorItem animatable, BakedGeoModel model, RenderType type, MultiBufferSource renderTypeBuffer, VertexConsumer vertexBuilder, boolean isRenderer, float partialTicks, int packedLightIn,
int packedOverlayIn, int color) {
this.currentBuffer = renderTypeBuffer;
this.renderType = type;
this.animatable = animatable;
super.actuallyRender(matrixStackIn, animatable, model, type, renderTypeBuffer, vertexBuilder, isRenderer, partialTicks, packedLightIn, packedOverlayIn, color);
if (this.renderArms) {
this.renderArms = false;
}
}
@Override
public void renderRecursively(PoseStack stack, VectorItem animatable, GeoBone bone, RenderType type, MultiBufferSource buffer, VertexConsumer bufferIn, boolean isReRender, float partialTick, int packedLightIn, int packedOverlayIn, int color) {
Minecraft mc = Minecraft.getInstance();
String name = bone.getName();
boolean renderingArms = false;
if (name.equals("Lefthand") || name.equals("Righthand")) {
bone.setHidden(true);
renderingArms = true;
} else {
bone.setHidden(this.hiddenBones.contains(name));
}
Player player = mc.player;
if (player == null) return;
ItemStack itemStack = player.getMainHandItem();
if (!itemStack.is(ModTags.Items.GUN)) return;
if (name.equals("Cross1")) {
bone.setHidden(NBTTool.getOrCreateTag(itemStack).getBoolean("HoloHidden")
|| !ClientEventHandler.zoom
|| GunsTool.getAttachmentType(itemStack, GunsTool.AttachmentType.SCOPE) != 1);
}
if (name.equals("Cross2")) {
bone.setHidden(NBTTool.getOrCreateTag(itemStack).getBoolean("HoloHidden")
|| !ClientEventHandler.zoom
|| GunsTool.getAttachmentType(itemStack, GunsTool.AttachmentType.SCOPE) != 2);
}
if (name.equals("tuoxin")) {
bone.setHidden(GunsTool.getAttachmentType(itemStack, GunsTool.AttachmentType.STOCK) == 0);
}
if (name.equals("flare")) {
if (ClientEventHandler.firePosTimer == 0 || ClientEventHandler.firePosTimer > 0.5 || GunsTool.getAttachmentType(itemStack, GunsTool.AttachmentType.BARREL) == 2) {
bone.setHidden(true);
} else {
bone.setHidden(false);
bone.setScaleX((float) (0.55 + 0.5 * (Math.random() - 0.5)));
bone.setScaleY((float) (0.55 + 0.5 * (Math.random() - 0.5)));
bone.setRotZ((float) (0.5 * (Math.random() - 0.5)));
}
}
// TODO handle gun attachments
// ItemModelHelper.handleGunAttachments(bone, itemStack, name);
if (this.transformType.firstPerson() && renderingArms) {
AbstractClientPlayer localPlayer = mc.player;
if (localPlayer == null) {
return;
}
PlayerRenderer playerRenderer = (PlayerRenderer) mc.getEntityRenderDispatcher().getRenderer(localPlayer);
PlayerModel<AbstractClientPlayer> model = playerRenderer.getModel();
stack.pushPose();
RenderUtil.translateMatrixToBone(stack, bone);
RenderUtil.translateToPivotPoint(stack, bone);
RenderUtil.rotateMatrixAroundBone(stack, bone);
RenderUtil.scaleMatrixForBone(stack, bone);
RenderUtil.translateAwayFromPivotPoint(stack, bone);
ResourceLocation loc = localPlayer.getSkin().texture();
VertexConsumer armBuilder = this.currentBuffer.getBuffer(RenderType.entitySolid(loc));
VertexConsumer sleeveBuilder = this.currentBuffer.getBuffer(RenderType.entityTranslucent(loc));
if (name.equals("Lefthand")) {
stack.translate(-1.0f * SCALE_RECIPROCAL, 2.0f * SCALE_RECIPROCAL, 0.0f);
AnimationHelper.renderPartOverBone(model.leftArm, bone, stack, armBuilder, packedLightIn, OverlayTexture.NO_OVERLAY, 1);
AnimationHelper.renderPartOverBone(model.leftSleeve, bone, stack, sleeveBuilder, packedLightIn, OverlayTexture.NO_OVERLAY, 1);
} else {
stack.translate(SCALE_RECIPROCAL, 2.0f * SCALE_RECIPROCAL, 0.0f);
AnimationHelper.renderPartOverBone(model.rightArm, bone, stack, armBuilder, packedLightIn, OverlayTexture.NO_OVERLAY, 1);
AnimationHelper.renderPartOverBone(model.rightSleeve, bone, stack, sleeveBuilder, packedLightIn, OverlayTexture.NO_OVERLAY, 1);
}
this.currentBuffer.getBuffer(this.renderType);
stack.popPose();
}
super.renderRecursively(stack, animatable, bone, type, buffer, bufferIn, isReRender, partialTick, packedLightIn, packedOverlayIn, color);
}
@Override
public ResourceLocation getTextureLocation(VectorItem instance) {
return super.getTextureLocation(instance);
}
}

View file

@ -7,6 +7,7 @@ import com.mojang.serialization.Codec;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.component.DataComponentType; import net.minecraft.core.component.DataComponentType;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.CompoundTag;
import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister; import net.neoforged.neoforge.registries.DeferredRegister;
@ -32,6 +33,11 @@ public class ModDataComponents {
builder -> builder.persistent(AmmoBoxInfo.CODEC) builder -> builder.persistent(AmmoBoxInfo.CODEC)
); );
public static final DeferredHolder<DataComponentType<?>, DataComponentType<CompoundTag>> GUN_DATA = register(
"gun_data",
builder -> builder.persistent(CompoundTag.CODEC)
);
private static <T> DeferredHolder<DataComponentType<?>, DataComponentType<T>> register(String name, UnaryOperator<DataComponentType.Builder<T>> builderOperator) { private static <T> DeferredHolder<DataComponentType<?>, DataComponentType<T>> register(String name, UnaryOperator<DataComponentType.Builder<T>> builderOperator) {
return DATA_COMPONENT_TYPES.register(name, () -> builderOperator.apply(DataComponentType.builder()).build()); return DATA_COMPONENT_TYPES.register(name, () -> builderOperator.apply(DataComponentType.builder()).build());
} }

View file

@ -0,0 +1,33 @@
package com.atsuishio.superbwarfare.datagen;
import com.atsuishio.superbwarfare.ModUtils;
import net.minecraft.core.HolderLookup;
import net.minecraft.data.DataGenerator;
import net.minecraft.data.PackOutput;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.common.data.ExistingFileHelper;
import net.neoforged.neoforge.data.event.GatherDataEvent;
import java.util.concurrent.CompletableFuture;
@EventBusSubscriber(modid = ModUtils.MODID, bus = EventBusSubscriber.Bus.MOD)
public class DataGenerators {
@SubscribeEvent
public static void gatherData(GatherDataEvent event) {
DataGenerator generator = event.getGenerator();
PackOutput packOutput = generator.getPackOutput();
CompletableFuture<HolderLookup.Provider> lookupProvider = event.getLookupProvider();
ExistingFileHelper existingFileHelper = event.getExistingFileHelper();
// generator.addProvider(event.includeServer(), ModLootTableProvider.create(packOutput));
// generator.addProvider(event.includeServer(), new ModRecipeProvider(packOutput));
// generator.addProvider(event.includeServer(), new ModBlockStateProvider(packOutput, existingFileHelper));
// generator.addProvider(event.includeServer(), new ModItemModelProvider(packOutput, existingFileHelper));
ModBlockTagProvider tagProvider = generator.addProvider(event.includeServer(), new ModBlockTagProvider(packOutput, lookupProvider, existingFileHelper));
generator.addProvider(event.includeServer(), new ModItemTagProvider(packOutput, lookupProvider, tagProvider.contentsGetter(), existingFileHelper));
// generator.addProvider(event.includeServer(), new ModDamageTypeTagProvider(packOutput, lookupProvider, existingFileHelper));
// generator.addProvider(event.includeServer(), new ModAdvancementProvider(packOutput, existingFileHelper));
}
}

View file

@ -0,0 +1,48 @@
package com.atsuishio.superbwarfare.datagen;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.init.ModBlocks;
import com.atsuishio.superbwarfare.init.ModTags;
import net.minecraft.core.HolderLookup;
import net.minecraft.data.PackOutput;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.level.block.Blocks;
import net.neoforged.neoforge.common.Tags;
import net.neoforged.neoforge.common.data.BlockTagsProvider;
import net.neoforged.neoforge.common.data.ExistingFileHelper;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.concurrent.CompletableFuture;
@SuppressWarnings("unchecked")
public class ModBlockTagProvider extends BlockTagsProvider {
public ModBlockTagProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> lookupProvider, @Nullable ExistingFileHelper existingFileHelper) {
super(output, lookupProvider, ModUtils.MODID, existingFileHelper);
}
@Override
protected void addTags(HolderLookup.@NotNull Provider pProvider) {
this.tag(BlockTags.NEEDS_IRON_TOOL).add(ModBlocks.GALENA_ORE.get(), ModBlocks.SCHEELITE_ORE.get(),
ModBlocks.DEEPSLATE_GALENA_ORE.get(), ModBlocks.DEEPSLATE_SCHEELITE_ORE.get(), ModBlocks.DRAGON_TEETH.get(),
ModBlocks.SILVER_ORE.get(), ModBlocks.DEEPSLATE_SILVER_ORE.get());
this.tag(BlockTags.MINEABLE_WITH_AXE).add(ModBlocks.BARBED_WIRE.get());
this.tag(BlockTags.MINEABLE_WITH_PICKAXE).add(ModBlocks.GALENA_ORE.get(), ModBlocks.SCHEELITE_ORE.get(),
ModBlocks.DEEPSLATE_GALENA_ORE.get(), ModBlocks.DEEPSLATE_SCHEELITE_ORE.get(), ModBlocks.DRAGON_TEETH.get(),
ModBlocks.REFORGING_TABLE.get(), ModBlocks.LEAD_BLOCK.get(), ModBlocks.STEEL_BLOCK.get(), ModBlocks.TUNGSTEN_BLOCK.get(),
ModBlocks.CEMENTED_CARBIDE_BLOCK.get(), ModBlocks.SILVER_ORE.get(), ModBlocks.DEEPSLATE_SILVER_ORE.get(),
ModBlocks.SILVER_BLOCK.get(), ModBlocks.JUMP_PAD.get(), ModBlocks.CONTAINER.get(), ModBlocks.CHARGING_STATION.get(),
ModBlocks.FUMO_25.get());
this.tag(BlockTags.MINEABLE_WITH_SHOVEL).add(ModBlocks.SANDBAG.get());
this.tag(ModTags.Blocks.SOFT_COLLISION)
.addTags(BlockTags.LEAVES, BlockTags.FENCES, BlockTags.FENCE_GATES, BlockTags.DOORS, BlockTags.TRAPDOORS, BlockTags.WALLS)
.add(Blocks.CACTUS, Blocks.BAMBOO, Blocks.MELON, Blocks.PUMPKIN, Blocks.HAY_BLOCK, Blocks.BELL, Blocks.CHAIN, Blocks.SNOW_BLOCK,
Blocks.COBWEB, Blocks.MUSHROOM_STEM, Blocks.BROWN_MUSHROOM_BLOCK, Blocks.RED_MUSHROOM_BLOCK);
this.tag(ModTags.Blocks.HARD_COLLISION)
.addTags(BlockTags.LOGS, BlockTags.PLANKS, Tags.Blocks.GLASS_BLOCKS, Tags.Blocks.GLASS_PANES, BlockTags.WOODEN_SLABS, BlockTags.WOODEN_STAIRS)
.add(Blocks.ICE, Blocks.FROSTED_ICE, Blocks.PACKED_ICE, Blocks.BLUE_ICE);
}
}

View file

@ -0,0 +1,146 @@
package com.atsuishio.superbwarfare.datagen;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.init.ModTags;
import net.minecraft.core.HolderLookup;
import net.minecraft.data.PackOutput;
import net.minecraft.data.tags.ItemTagsProvider;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.ItemTags;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.neoforged.neoforge.common.Tags;
import net.neoforged.neoforge.common.data.ExistingFileHelper;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.concurrent.CompletableFuture;
public class ModItemTagProvider extends ItemTagsProvider {
public ModItemTagProvider(PackOutput packOutput, CompletableFuture<HolderLookup.Provider> providerCompletableFuture,
CompletableFuture<TagLookup<Block>> tagLookupCompletableFuture, @Nullable ExistingFileHelper existingFileHelper) {
super(packOutput, providerCompletableFuture, tagLookupCompletableFuture, ModUtils.MODID, existingFileHelper);
}
@SuppressWarnings("unchecked")
@Override
protected void addTags(HolderLookup.@NotNull Provider pProvider) {
this.tag(Tags.Items.DUSTS).addTags(cTag("dusts/coal_coke"), cTag("dusts/tungsten"));
this.tag(cTag("dusts/coal_coke")).add(ModItems.COAL_POWDER.get());
this.tag(cTag("dusts/iron")).add(ModItems.IRON_POWDER.get());
this.tag(cTag("dusts/tungsten")).add(ModItems.TUNGSTEN_POWDER.get());
this.tag(Tags.Items.INGOTS).addTags(cTag("ingots/lead"), cTag("ingots/steel"), cTag("ingots/tungsten"), cTag("ingots/silver"));
this.tag(cTag("ingots/lead")).add(ModItems.LEAD_INGOT.get());
this.tag(cTag("ingots/steel")).add(ModItems.STEEL_INGOT.get());
this.tag(cTag("ingots/tungsten")).add(ModItems.TUNGSTEN_INGOT.get());
this.tag(cTag("ingots/silver")).add(ModItems.SILVER_INGOT.get());
this.tag(ModTags.Items.INGOTS_STEEL).addTag(cTag("ingots/steel"))
.addOptional(ResourceLocation.fromNamespaceAndPath("dreamaticvoyage", "fukamizu_bread_ingot"));
this.tag(ModTags.Items.INGOTS_CEMENTED_CARBIDE).add(ModItems.CEMENTED_CARBIDE_INGOT.get())
.addOptional(ResourceLocation.fromNamespaceAndPath("dreamaticvoyage", "hqss_bread_ingot"));
this.tag(Tags.Items.STORAGE_BLOCKS).addTags(cTag("storage_blocks/lead"), cTag("storage_blocks/steel"), cTag("storage_blocks/tungsten"), cTag("storage_blocks/silver"));
this.tag(cTag("storage_blocks/lead")).add(ModItems.LEAD_BLOCK.get());
this.tag(cTag("storage_blocks/steel")).add(ModItems.STEEL_BLOCK.get());
this.tag(cTag("storage_blocks/tungsten")).add(ModItems.TUNGSTEN_BLOCK.get());
this.tag(cTag("storage_blocks/silver")).add(ModItems.SILVER_BLOCK.get());
this.tag(ModTags.Items.STORAGE_BLOCK_STEEL).addTag(cTag("storage_blocks/steel"))
.addOptional(ResourceLocation.fromNamespaceAndPath("dreamaticvoyage", "fukamizu_bread_bricks"));
this.tag(ModTags.Items.STORAGE_BLOCK_CEMENTED_CARBIDE).add(ModItems.CEMENTED_CARBIDE_BLOCK.get())
.addOptional(ResourceLocation.fromNamespaceAndPath("dreamaticvoyage", "hqss_bread_bricks"));
this.tag(Tags.Items.ORES).addTags(cTag("ores/lead"), cTag("ores/tungsten"), cTag("ores/silver"));
this.tag(cTag("ores/lead")).add(ModItems.GALENA_ORE.get(), ModItems.DEEPSLATE_GALENA_ORE.get());
this.tag(cTag("ores/tungsten")).add(ModItems.SCHEELITE_ORE.get(), ModItems.DEEPSLATE_SCHEELITE_ORE.get());
this.tag(cTag("ores/silver")).add(ModItems.SILVER_ORE.get(), ModItems.DEEPSLATE_SILVER_ORE.get());
this.tag(Tags.Items.RAW_MATERIALS).addTags(cTag("raw_materials/lead"), cTag("raw_materials/tungsten"), cTag("raw_materials/silver"));
this.tag(cTag("raw_materials/lead")).add(ModItems.GALENA.get());
this.tag(cTag("raw_materials/tungsten")).add(ModItems.SCHEELITE.get());
this.tag(cTag("raw_materials/silver")).add(ModItems.RAW_SILVER.get());
this.tag(Tags.Items.ORE_RATES_SINGULAR).add(ModItems.GALENA_ORE.get(), ModItems.DEEPSLATE_GALENA_ORE.get(),
ModItems.SCHEELITE_ORE.get(), ModItems.DEEPSLATE_SCHEELITE_ORE.get(),
ModItems.SILVER_ORE.get(), ModItems.DEEPSLATE_SILVER_ORE.get());
this.tag(Tags.Items.ORES_IN_GROUND_STONE).add(ModItems.GALENA_ORE.get(), ModItems.SCHEELITE_ORE.get(), ModItems.SILVER_ORE.get());
this.tag(Tags.Items.ORES_IN_GROUND_DEEPSLATE).add(ModItems.DEEPSLATE_GALENA_ORE.get(), ModItems.DEEPSLATE_SCHEELITE_ORE.get(), ModItems.DEEPSLATE_SILVER_ORE.get());
this.tag(cTag("plates")).addTags(cTag("plates/copper"));
this.tag(cTag("plates/copper")).add(ModItems.COPPER_PLATE.get());
ModItems.GUNS.getEntries().forEach(registryObject -> this.tag(ModTags.Items.GUN).add(registryObject.get()));
this.tag(ModTags.Items.SMG).add(ModItems.VECTOR.get());
// this.tag(ModTags.Items.HANDGUN).add(ModItems.TRACHELIUM.get(), ModItems.GLOCK_17.get(), ModItems.GLOCK_18.get(), ModItems.M_1911.get(), ModItems.MP_443.get());
// this.tag(ModTags.Items.RIFLE).add(ModItems.M_4.get(), ModItems.HK_416.get(), ModItems.SKS.get(),
// ModItems.MK_14.get(), ModItems.MARLIN.get(), ModItems.AK_47.get(), ModItems.AK_12.get(), ModItems.QBZ_95.get());
// this.tag(ModTags.Items.SNIPER_RIFLE).add(ModItems.HUNTING_RIFLE.get(), ModItems.SENTINEL.get(),
// ModItems.SVD.get(), ModItems.M_98B.get(), ModItems.K_98.get(), ModItems.MOSIN_NAGANT.get());
// this.tag(ModTags.Items.HEAVY_WEAPON).add(ModItems.NTW_20.get());
// this.tag(ModTags.Items.SHOTGUN).add(ModItems.HOMEMADE_SHOTGUN.get(), ModItems.M_870.get(), ModItems.AA_12.get());
// this.tag(ModTags.Items.MACHINE_GUN).add(ModItems.MINIGUN.get(), ModItems.DEVOTION.get(), ModItems.RPK.get(), ModItems.M_60.get());
this.tag(ModTags.Items.NORMAL_GUN).add(
// ModItems.HOMEMADE_SHOTGUN.get(), ModItems.AK_47.get(), ModItems.AK_12.get(), ModItems.SVD.get(), ModItems.M_60.get(), ModItems.MK_14.get(),
ModItems.VECTOR.get()
// 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.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.GLOCK_18.get(), ModItems.M_1911.get(), ModItems.QBZ_95.get(), ModItems.K_98.get(), ModItems.MOSIN_NAGANT.get(), ModItems.MP_443.get()
);
this.tag(ModTags.Items.USE_HANDGUN_AMMO).add(
// ModItems.GLOCK_17.get(), ModItems.GLOCK_18.get(), ModItems.M_1911.get(),
ModItems.VECTOR.get()
// ModItems.MP_443.get()
);
// this.tag(ModTags.Items.USE_RIFLE_AMMO).add(ModItems.M_4.get(), ModItems.HK_416.get(), ModItems.SKS.get(), ModItems.MINIGUN.get(), ModItems.DEVOTION.get(), ModItems.M_60.get(),
// ModItems.MK_14.get(), ModItems.MARLIN.get(), ModItems.AK_47.get(), ModItems.AK_12.get(), ModItems.QBZ_95.get(), ModItems.RPK.get(), ModItems.TRACHELIUM.get());
// this.tag(ModTags.Items.USE_SHOTGUN_AMMO).add(ModItems.HOMEMADE_SHOTGUN.get(), ModItems.M_870.get(), ModItems.AA_12.get());
// this.tag(ModTags.Items.USE_SNIPER_AMMO).add(ModItems.HUNTING_RIFLE.get(), ModItems.SENTINEL.get(),
// ModItems.SVD.get(), ModItems.M_98B.get(), ModItems.K_98.get(), ModItems.MOSIN_NAGANT.get());
// this.tag(ModTags.Items.USE_HEAVY_AMMO).add(ModItems.NTW_20.get());
// this.tag(ModTags.Items.LAUNCHER).add(ModItems.M_79.get(), ModItems.RPG.get(), ModItems.JAVELIN.get(), ModItems.SECONDARY_CATACLYSM.get());
// this.tag(ModTags.Items.REVOLVER).add(ModItems.TRACHELIUM.get());
// this.tag(ModTags.Items.MILITARY_ARMOR).add(ModItems.RU_CHEST_6B43.get(), ModItems.US_CHEST_IOTV.get());
this.tag(ModTags.Items.BLUEPRINT).addTags(ModTags.Items.COMMON_BLUEPRINT, ModTags.Items.RARE_BLUEPRINT, ModTags.Items.EPIC_BLUEPRINT,
ModTags.Items.LEGENDARY_BLUEPRINT, ModTags.Items.CANNON_BLUEPRINT);
this.tag(ModTags.Items.COMMON_BLUEPRINT).add(ModItems.GLOCK_17_BLUEPRINT.get(), ModItems.MP_443_BLUEPRINT.get(), ModItems.MARLIN_BLUEPRINT.get(),
ModItems.TASER_BLUEPRINT.get(), ModItems.M_1911_BLUEPRINT.get());
this.tag(ModTags.Items.RARE_BLUEPRINT).add(ModItems.GLOCK_18_BLUEPRINT.get(), ModItems.M_79_BLUEPRINT.get(), ModItems.M_4_BLUEPRINT.get(),
ModItems.SKS_BLUEPRINT.get(), ModItems.M_870_BLUEPRINT.get(), ModItems.AK_47_BLUEPRINT.get(), ModItems.K_98_BLUEPRINT.get(),
ModItems.MOSIN_NAGANT_BLUEPRINT.get(), ModItems.M_2_HB_BLUEPRINT.get());
this.tag(ModTags.Items.EPIC_BLUEPRINT).add(ModItems.TRACHELIUM_BLUEPRINT.get(), ModItems.HUNTING_RIFLE_BLUEPRINT.get(), ModItems.RPG_BLUEPRINT.get(),
ModItems.BOCEK_BLUEPRINT.get(), ModItems.HK_416_BLUEPRINT.get(), ModItems.RPK_BLUEPRINT.get(), ModItems.VECTOR_BLUEPRINT.get(),
ModItems.MK_14_BLUEPRINT.get(), ModItems.M_60_BLUEPRINT.get(), ModItems.SVD_BLUEPRINT.get(), ModItems.M_98B_BLUEPRINT.get(),
ModItems.AK_12_BLUEPRINT.get(), ModItems.DEVOTION_BLUEPRINT.get(), ModItems.QBZ_95_BLUEPRINT.get());
// this.tag(ModTags.Items.LEGENDARY_BLUEPRINT).add(ModItems.AA_12_BLUEPRINT.get(), ModItems.NTW_20_BLUEPRINT.get(), ModItems.MINIGUN_BLUEPRINT.get(),
// ModItems.SENTINEL_BLUEPRINT.get(), ModItems.JAVELIN_BLUEPRINT.get(), ModItems.SECONDARY_CATACLYSM_BLUEPRINT.get(), ModItems.MK_42_BLUEPRINT.get(),
// ModItems.MLE_1934_BLUEPRINT.get(), ModItems.ANNIHILATOR_BLUEPRINT.get());
// this.tag(ModTags.Items.CANNON_BLUEPRINT).add(ModItems.MK_42_BLUEPRINT.get(), ModItems.MLE_1934_BLUEPRINT.get(), ModItems.ANNIHILATOR_BLUEPRINT.get());
}
public static TagKey<Item> cTag(String name) {
return ItemTags.create(ResourceLocation.fromNamespaceAndPath("c", name));
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,942 @@
package com.atsuishio.superbwarfare.event;
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.init.ModItems;
import com.atsuishio.superbwarfare.init.ModSounds;
import com.atsuishio.superbwarfare.init.ModTags;
import com.atsuishio.superbwarfare.item.gun.GunItem;
import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.tools.*;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ClipContext;
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.event.tick.PlayerTickEvent;
import java.text.DecimalFormat;
@EventBusSubscriber(modid = ModUtils.MODID)
public class GunEventHandler {
@SubscribeEvent
public static void onPlayerTick(PlayerTickEvent.Post event) {
Player player = event.getEntity();
ItemStack stack = player.getMainHandItem();
if (stack.is(ModTags.Items.GUN)) {
handleGunBolt(player);
handleGunReload(player);
handleGunSingleReload(player);
handleSentinelCharge(player);
}
}
/**
* 拉大栓
*/
private static void handleGunBolt(Player player) {
ItemStack stack = player.getMainHandItem();
if (stack.is(ModTags.Items.NORMAL_GUN)) {
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 (GunsTool.getGunIntTag(stack, "BoltActionTick") == 1) {
GunsTool.setGunBooleanTag(stack, "NeedBoltAction", false);
if (stack.is(ModTags.Items.REVOLVER)) {
NBTTool.getOrCreateTag(stack).putBoolean("canImmediatelyShoot", true);
}
}
}
}
/**
* 根据武器的注册名来寻找音效并播放
*/
public static void playGunSounds(Player player) {
ItemStack stack = player.getMainHandItem();
if (!stack.is(ModTags.Items.GUN)) {
return;
}
if (!player.level().isClientSide) {
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;
// }
// }
// var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO);
//
// if (perk == ModPerks.BEAST_BULLET.get()) {
// player.playSound(ModSounds.HENG.get(), 4f, 1f);
// }
float soundRadius = (float) (GunsTool.getGunDoubleTag(stack, "SoundRadius") * GunsTool.getGunDoubleTag(stack, "CustomSoundRadius", 1));
int barrelType = GunsTool.getAttachmentType(stack, GunsTool.AttachmentType.BARREL);
SoundEvent sound3p = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc(name + (barrelType == 2 ? "_fire_3p_s" : "_fire_3p")));
if (sound3p != null) {
player.playSound(sound3p, soundRadius * 0.4f, 1f);
}
SoundEvent soundFar = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc(name + (barrelType == 2 ? "_far_s" : "_far")));
if (soundFar != null) {
player.playSound(soundFar, soundRadius * 0.7f, 1f);
}
SoundEvent soundVeryFar = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc(name + (barrelType == 2 ? "_veryfar_s" : "_veryfar")));
if (soundVeryFar != null) {
player.playSound(soundVeryFar, soundRadius, 1f);
}
}
}
public static void playGunBoltSounds(Player player) {
ItemStack stack = player.getMainHandItem();
if (!stack.is(ModTags.Items.GUN)) {
return;
}
if (!player.level().isClientSide) {
String origin = stack.getItem().getDescriptionId();
String name = origin.substring(origin.lastIndexOf(".") + 1);
SoundEvent sound1p = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc(name + "_bolt"));
if (sound1p != null && player instanceof ServerPlayer serverPlayer) {
SoundTool.playLocalSound(serverPlayer, sound1p, 2f, 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())));
if (stack.is(ModTags.Items.REVOLVER)) return;
ModUtils.queueServerWork((int) (GunsTool.getGunDoubleTag(stack, "BoltActionTime", 0) / 2 + 1.5 * shooterHeight), () -> {
if (stack.is(ModTags.Items.SHOTGUN)) {
SoundTool.playLocalSound(serverPlayer, ModSounds.SHELL_CASING_SHOTGUN.get(), (float) Math.max(0.75 - 0.12 * shooterHeight, 0), 1);
} else if (stack.is(ModTags.Items.SNIPER_RIFLE)) {
SoundTool.playLocalSound(serverPlayer, ModSounds.SHELL_CASING_50CAL.get(), (float) Math.max(1 - 0.15 * shooterHeight, 0), 1);
} else {
SoundTool.playLocalSound(serverPlayer, ModSounds.SHELL_CASING_NORMAL.get(), (float) Math.max(1.5 - 0.2 * shooterHeight, 0), 1);
}
});
}
}
}
public static void gunShoot(Player player, double spared) {
ItemStack stack = player.getMainHandItem();
if (!player.level().isClientSide()) {
float headshot = (float) GunsTool.getGunDoubleTag(stack, "Headshot", 0);
float damage = (float) (GunsTool.getGunDoubleTag(stack, "Damage", 0) +
GunsTool.getGunDoubleTag(stack, "ChargedDamage", 0)) * (float) perkDamage(stack);
float velocity = (float) ((GunsTool.getGunDoubleTag(stack, "Velocity", 0) + GunsTool.getGunDoubleTag(stack, "CustomVelocity", 0)) * perkSpeed(stack));
int projectileAmount = GunsTool.getGunIntTag(stack, "ProjectileAmount", 1);
float bypassArmorRate = (float) GunsTool.getGunDoubleTag(stack, "BypassesArmor", 0);
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
boolean zoom = cap != null && cap.zoom;
// TODO perk
// var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO);
//
// if (perk != null && perk.descriptionId.equals("butterfly_bullet")) {
// if (handleButterflyBullet(perk, stack, player)) return;
// }
ProjectileEntity projectile = new ProjectileEntity(player.level())
.shooter(player)
// .damage(perk instanceof AmmoPerk ammoPerk && ammoPerk.slug ? projectileAmount * damage : damage)
.damage(damage)
.headShot(headshot)
.zoom(zoom);
// if (perk instanceof AmmoPerk ammoPerk) {
// int level = PerkHelper.getItemPerkLevel(perk, stack);
//
// bypassArmorRate += ammoPerk.bypassArmorRate + (perk == ModPerks.AP_BULLET.get() ? 0.05f * (level - 1) : 0);
// projectile.setRGB(ammoPerk.rgb);
//
// if (!ammoPerk.mobEffects.get().isEmpty()) {
// int amplifier;
// if (perk.descriptionId.equals("blade_bullet")) {
// amplifier = level / 3;
// } else if (perk.descriptionId.equals("bread_bullet")) {
// amplifier = 1;
// } else {
// amplifier = level - 1;
// }
//
// ArrayList<MobEffectInstance> mobEffectInstances = new ArrayList<>();
// for (MobEffect effect : ammoPerk.mobEffects.get()) {
// mobEffectInstances.add(new MobEffectInstance(effect, 70 + 30 * level, amplifier));
// }
// projectile.effect(mobEffectInstances);
// }
//
// if (perk.descriptionId.equals("bread_bullet")) {
// projectile.knockback(level * 0.3f);
// projectile.forceKnockback();
// }
// }
bypassArmorRate = Math.max(bypassArmorRate, 0);
projectile.bypassArmorRate(bypassArmorRate);
// if (perk == ModPerks.SILVER_BULLET.get()) {
// int level = PerkHelper.getItemPerkLevel(perk, stack);
// projectile.undeadMultiple(1.0f + 0.5f * level);
// } else if (perk == ModPerks.BEAST_BULLET.get()) {
// projectile.beast();
// } else if (perk == ModPerks.JHP_BULLET.get()) {
// int level = PerkHelper.getItemPerkLevel(perk, stack);
// projectile.jhpBullet(level);
// } else if (perk == ModPerks.HE_BULLET.get()) {
// int level = PerkHelper.getItemPerkLevel(perk, stack);
// projectile.heBullet(level);
// } else if (perk == ModPerks.INCENDIARY_BULLET.get()) {
// int level = PerkHelper.getItemPerkLevel(perk, stack);
// projectile.fireBullet(level, stack.is(ModTags.Items.SHOTGUN));
// }
//
// var dmgPerk = PerkHelper.getPerkByType(stack, Perk.Type.DAMAGE);
// if (dmgPerk == ModPerks.MONSTER_HUNTER.get()) {
// int level = PerkHelper.getItemPerkLevel(dmgPerk, stack);
// projectile.monsterMultiple(0.1f + 0.1f * level);
// }
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
// stack.is(ModTags.Items.SHOTGUN) && perk == ModPerks.INCENDIARY_BULLET.get() ? 4.5f : velocity,
velocity,
(float) spared);
player.level().addFreshEntity(projectile);
}
}
public static double perkDamage(ItemStack stack) {
// var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO);
// if (perk instanceof AmmoPerk ammoPerk) {
// return ammoPerk.damageRate;
// }
return 1;
}
public static double perkSpeed(ItemStack stack) {
// var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO);
// if (perk instanceof AmmoPerk ammoPerk) {
// return ammoPerk.speedRate;
// }
return 1;
}
@SuppressWarnings("ConstantValue")
private static boolean handleButterflyBullet(Perk perk, ItemStack heldItem, Player player) {
// int perkLevel = PerkHelper.getItemPerkLevel(perk, heldItem);
// var entityType = CompatHolder.VRC_RAIN_SHOWER_BUTTERFLY;
// if (entityType != null) {
// Projectile projectile = entityType.create(player.level());
//
// float inaccuracy = Math.max(0.0f, 1.1f - perkLevel * .1f);
// projectile.setOwner(player);
// 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);
//
// Vec3 vec3 = (new Vec3(player.getLookAngle().x, player.getLookAngle().y + 0.001f, player.getLookAngle().z)).normalize().scale(1.2).
// add(player.level().random.triangle(0.0D, 0.0172275D * (double) inaccuracy),
// player.level().random.triangle(0.0D, 0.0172275D * (double) inaccuracy),
// player.level().random.triangle(0.0D, 0.0172275D * (double) inaccuracy)).
// add(player.getDeltaMovement().x, player.onGround() ? 0.0 : 0.05 * player.getDeltaMovement().y, player.getDeltaMovement().z).
// scale(5.0f);
// projectile.setDeltaMovement(vec3);
// projectile.setYRot((float) (Mth.atan2(vec3.x, vec3.z) * (double) (180F / (float) Math.PI)));
// projectile.setXRot((float) (Mth.atan2(vec3.y, vec3.horizontalDistance()) * (double) (180F / (float) Math.PI)));
// projectile.yRotO = projectile.getYRot();
// projectile.xRotO = projectile.getXRot();
//
// projectile.setNoGravity(true);
// player.level().addFreshEntity(projectile);
// return true;
// }
return false;
}
/**
* 通用的武器换弹流程
*/
private static void handleGunReload(Player player) {
ItemStack stack = player.getMainHandItem();
if (!(stack.getItem() instanceof GunItem gunItem)) return;
CompoundTag tag = NBTTool.getOrCreateTag(stack);
CompoundTag data = NBTTool.getOrCreateTag(stack).getCompound("GunData");
// 启动换弹
if (GunsTool.getGunBooleanTag(stack, "StartReload")) {
// TODO reload event
// 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);
NBTTool.getOrCreateTag(stack).putBoolean("is_empty_reloading", true);
playGunEmptyReloadSounds(player);
} else {
data.putInt("ReloadTime", data.getInt("NormalReloadTime") + 1);
NBTTool.getOrCreateTag(stack).putBoolean("is_normal_reloading", true);
playGunNormalReloadSounds(player);
}
} else {
data.putInt("ReloadTime", data.getInt("EmptyReloadTime") + 2);
NBTTool.getOrCreateTag(stack).putBoolean("is_empty_reloading", true);
playGunEmptyReloadSounds(player);
}
data.putBoolean("StartReload", false);
}
if (data.getInt("ReloadTime") > 0) {
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 (data.getInt("ReloadTime") == 1) {
if (gunItem.isOpenBolt(stack)) {
if (GunsTool.getGunIntTag(stack, "Ammo", 0) == 0) {
playGunEmptyReload(player);
} else {
playGunNormalReload(player);
}
} else {
playGunEmptyReload(player);
}
data.putBoolean("StartReload", false);
}
tag.put("GunData", data);
}
public static void playGunNormalReload(Player player) {
ItemStack stack = player.getMainHandItem();
if (!(stack.getItem() instanceof GunItem gunItem)) return;
if (player.getInventory().hasAnyMatching(item -> item.is(ModItems.CREATIVE_AMMO_BOX.get()))) {
GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Magazine", 0)
+ GunsTool.getGunIntTag(stack, "CustomMagazine", 0)
+ (gunItem.hasBulletInBarrel(stack) ? 1 : 0));
} else {
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO)) {
GunsTool.reload(player, stack, AmmoType.SHOTGUN, gunItem.hasBulletInBarrel(stack));
} else if (stack.is(ModTags.Items.USE_SNIPER_AMMO)) {
GunsTool.reload(player, stack, AmmoType.SNIPER, true);
} else if (stack.is(ModTags.Items.USE_HANDGUN_AMMO)) {
GunsTool.reload(player, stack, AmmoType.HANDGUN, true);
} else if (stack.is(ModTags.Items.USE_RIFLE_AMMO)) {
GunsTool.reload(player, stack, AmmoType.RIFLE, gunItem.hasBulletInBarrel(stack));
} else if (stack.is(ModTags.Items.USE_HEAVY_AMMO)) {
GunsTool.reload(player, stack, AmmoType.HEAVY, gunItem.hasBulletInBarrel(stack));
}
}
NBTTool.getOrCreateTag(stack).putBoolean("is_normal_reloading", false);
NBTTool.getOrCreateTag(stack).putBoolean("is_empty_reloading", false);
// TODO reload event
// NeoForge.EVENT_BUS.post(new ReloadEvent.Post(player, stack));
}
public static void playGunEmptyReload(Player player) {
ItemStack stack = player.getMainHandItem();
if (player.getInventory().hasAnyMatching(item -> item.is(ModItems.CREATIVE_AMMO_BOX.get()))) {
GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Magazine", 0)
+ GunsTool.getGunIntTag(stack, "CustomMagazine", 0));
} else {
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO)) {
GunsTool.reload(player, stack, AmmoType.SHOTGUN);
} else if (stack.is(ModTags.Items.USE_SNIPER_AMMO)) {
GunsTool.reload(player, stack, AmmoType.SNIPER);
} else if (stack.is(ModTags.Items.USE_HANDGUN_AMMO)) {
GunsTool.reload(player, stack, AmmoType.HANDGUN);
} else if (stack.is(ModTags.Items.USE_RIFLE_AMMO)) {
GunsTool.reload(player, stack, AmmoType.RIFLE);
} else if (stack.is(ModTags.Items.USE_HEAVY_AMMO)) {
GunsTool.reload(player, stack, AmmoType.HEAVY);
}
// 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.getOrCreateTag(stack).putBoolean("is_normal_reloading", false);
NBTTool.getOrCreateTag(stack).putBoolean("is_empty_reloading", false);
// TODO reload event
// NeoForge.EVENT_BUS.post(new ReloadEvent.Post(player, stack));
}
public static void playGunEmptyReloadSounds(Player player) {
ItemStack stack = player.getMainHandItem();
if (!stack.is(ModTags.Items.GUN)) {
return;
}
if (!player.level().isClientSide) {
String origin = stack.getItem().getDescriptionId();
String name = origin.substring(origin.lastIndexOf(".") + 1);
SoundEvent sound1p = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc(name + "_reload_empty"));
if (sound1p != null && player instanceof ServerPlayer serverPlayer) {
SoundTool.playLocalSound(serverPlayer, sound1p, 10f, 1f);
}
}
}
public static void playGunNormalReloadSounds(Player player) {
ItemStack stack = player.getMainHandItem();
if (!stack.is(ModTags.Items.GUN)) {
return;
}
if (!player.level().isClientSide) {
String origin = stack.getItem().getDescriptionId();
String name = origin.substring(origin.lastIndexOf(".") + 1);
SoundEvent sound1p;
sound1p = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc(name + "_reload_normal"));
if (sound1p != null && player instanceof ServerPlayer serverPlayer) {
SoundTool.playLocalSound(serverPlayer, sound1p, 10f, 1f);
}
}
}
/**
* 单发装填类的武器换弹流程
*/
private static void handleGunSingleReload(Player player) {
ItemStack stack = player.getMainHandItem();
CompoundTag tag = NBTTool.getOrCreateTag(stack);
// 换弹流程计时器
if (tag.getDouble("prepare") > 0) {
tag.putDouble("prepare", tag.getDouble("prepare") - 1);
}
if (tag.getDouble("prepare_load") > 0) {
tag.putDouble("prepare_load", tag.getDouble("prepare_load") - 1);
}
if (tag.getDouble("iterative") > 0) {
tag.putDouble("iterative", tag.getDouble("iterative") - 1);
}
if (tag.getDouble("finish") > 0) {
tag.putDouble("finish", tag.getDouble("finish") - 1);
}
player.displayClientMessage(Component.literal("prepare: " + new DecimalFormat("##.#").format(tag.getDouble("prepare"))
+ " prepare_load: " + new DecimalFormat("##.#").format(tag.getDouble("prepare_load"))
+ " iterative: " + new DecimalFormat("##.#").format(tag.getDouble("iterative"))
+ " finish: " + new DecimalFormat("##.#").format(tag.getDouble("finish"))
+ " reload_stage: " + new DecimalFormat("##.#").format(tag.getDouble("reload_stage"))
), true);
// 一阶段
if (tag.getBoolean("start_single_reload")) {
// todo reload event
// 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())
) {
// 此处判断空仓换弹的时候是否在准备阶段就需要装填一发如M870
playGunPrepareLoadReloadSounds(player);
int prepareLoadTime = GunsTool.getGunIntTag(stack, "PrepareLoadTime", 0);
tag.putInt("prepare_load", prepareLoadTime + 1);
player.getCooldowns().addCooldown(stack.getItem(), prepareLoadTime);
} else if (GunsTool.getGunIntTag(stack, "PrepareEmptyTime", 0) != 0 && GunsTool.getGunIntTag(stack, "Ammo", 0) == 0) {
// 此处判断空仓换弹如莫辛纳甘
playGunEmptyPrepareSounds(player);
int prepareEmptyTime = GunsTool.getGunIntTag(stack, "PrepareEmptyTime", 0);
tag.putInt("prepare", prepareEmptyTime + 1);
player.getCooldowns().addCooldown(stack.getItem(), prepareEmptyTime);
} else {
playGunPrepareReloadSounds(player);
int prepareTime = GunsTool.getGunIntTag(stack, "PrepareTime", 0);
tag.putInt("prepare", prepareTime + 1);
player.getCooldowns().addCooldown(stack.getItem(), prepareTime);
}
tag.putBoolean("force_stop", false);
tag.putBoolean("stop", false);
tag.putInt("reload_stage", 1);
GunsTool.setGunBooleanTag(stack, "Reloading", true);
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 ((tag.getDouble("prepare") == 1 || tag.getDouble("prepare_load") == 1)) {
if (!InventoryTool.hasCreativeAmmoBox(player)) {
var capability = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
if (capability == null) capability = new PlayerVariable();
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO) && capability.shotgunAmmo == 0) {
tag.putBoolean("force_stage3_start", true);
} else if (stack.is(ModTags.Items.USE_SNIPER_AMMO) && capability.sniperAmmo == 0) {
tag.putBoolean("force_stage3_start", true);
} else if ((stack.is(ModTags.Items.USE_HANDGUN_AMMO) || stack.is(ModTags.Items.SMG)) && capability.handgunAmmo == 0) {
tag.putBoolean("force_stage3_start", true);
} else if (stack.is(ModTags.Items.USE_RIFLE_AMMO) && capability.rifleAmmo == 0) {
tag.putBoolean("force_stage3_start", true);
} else if (stack.is(ModTags.Items.USE_HEAVY_AMMO) && capability.heavyAmmo == 0) {
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 {
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 {
tag.putInt("reload_stage", 2);
// }
}
// 检查备弹
}
// 强制停止换弹进入三阶段
if (tag.getBoolean("force_stop") && tag.getInt("reload_stage") == 2 && tag.getInt("iterative") > 0) {
tag.putBoolean("stop", true);
}
// 二阶段
if ((tag.getDouble("prepare") == 0 || tag.getDouble("prepare_load") == 0)
&& tag.getInt("reload_stage") == 2
&& tag.getInt("iterative") == 0
&& !tag.getBoolean("stop")
&& GunsTool.getGunIntTag(stack, "Ammo", 0) < GunsTool.getGunIntTag(stack, "Magazine", 0)
+ GunsTool.getGunIntTag(stack, "CustomMagazine", 0)) {
playGunLoopReloadSounds(player);
int iterativeTime = GunsTool.getGunIntTag(stack, "IterativeTime", 0);
tag.putDouble("iterative", iterativeTime);
player.getCooldowns().addCooldown(stack.getItem(), iterativeTime);
// 动画播放nbt
if (tag.getDouble("load_index") == 1) {
tag.putDouble("load_index", 0);
} else {
tag.putDouble("load_index", 1);
}
}
// 装填 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 (tag.getInt("iterative") == 1) {
// 装满结束
if (GunsTool.getGunIntTag(stack, "Ammo", 0) >= GunsTool.getGunIntTag(stack, "Magazine", 0)
+ GunsTool.getGunIntTag(stack, "CustomMagazine", 0)) {
tag.putInt("reload_stage", 3);
}
// 备弹耗尽结束
if (!InventoryTool.hasCreativeAmmoBox(player)) {
var capability = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
if (capability == null) capability = new PlayerVariable();
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO) && capability.shotgunAmmo == 0) {
tag.putInt("reload_stage", 3);
} else if (stack.is(ModTags.Items.USE_SNIPER_AMMO) && capability.sniperAmmo == 0) {
tag.putInt("reload_stage", 3);
} else if ((stack.is(ModTags.Items.USE_HANDGUN_AMMO) || stack.is(ModTags.Items.SMG)) && capability.handgunAmmo == 0) {
tag.putInt("reload_stage", 3);
} else if (stack.is(ModTags.Items.USE_RIFLE_AMMO) && capability.rifleAmmo == 0) {
tag.putInt("reload_stage", 3);
} else if (stack.is(ModTags.Items.USE_HEAVY_AMMO) && capability.heavyAmmo == 0) {
tag.putInt("reload_stage", 3);
}
}
// 强制结束
if (tag.getBoolean("stop")) {
tag.putInt("reload_stage", 3);
tag.putBoolean("force_stop", false);
tag.putBoolean("stop", false);
}
}
// 三阶段
if ((tag.getInt("iterative") == 1 && tag.getInt("reload_stage") == 3) || tag.getBoolean("force_stage3_start")) {
tag.putInt("reload_stage", 3);
tag.putBoolean("force_stage3_start", false);
int finishTime = GunsTool.getGunIntTag(stack, "FinishTime", 0);
tag.putInt("finish", finishTime + 2);
player.getCooldowns().addCooldown(stack.getItem(), finishTime + 2);
playGunEndReloadSounds(player);
}
// todo marlin
// if (stack.getItem() == ModItems.MARLIN.get() && tag.getInt("finish") == 10) {
// tag.putBoolean("empty", false);
// }
// 三阶段结束
if (tag.getInt("finish") == 1) {
tag.putInt("reload_stage", 0);
if (GunsTool.getGunIntTag(stack, "BoltActionTime", 0) > 0) {
GunsTool.setGunBooleanTag(stack, "NeedBoltAction", false);
}
GunsTool.setGunBooleanTag(stack, "Reloading", false);
tag.putBoolean("start_single_reload", false);
// todo reload event
// NeoForge.EVENT_BUS.post(new ReloadEvent.Post(player, stack));
}
}
public static void singleLoad(Player player) {
ItemStack stack = player.getMainHandItem();
GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Ammo", 0) + 1);
if (!InventoryTool.hasCreativeAmmoBox(player)) {
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
if (cap == null) return;
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO)) {
AmmoType.SHOTGUN.add(cap, -1);
} else if (stack.is(ModTags.Items.USE_SNIPER_AMMO)) {
AmmoType.SNIPER.add(cap, -1);
} else if (stack.is(ModTags.Items.USE_HANDGUN_AMMO)) {
AmmoType.HANDGUN.add(cap, -1);
} else if (stack.is(ModTags.Items.USE_RIFLE_AMMO)) {
AmmoType.RIFLE.add(cap, -1);
} else if (stack.is(ModTags.Items.USE_HEAVY_AMMO)) {
AmmoType.HEAVY.add(cap, -1);
}
// 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);
}
}
public static void playGunPrepareReloadSounds(Player player) {
ItemStack stack = player.getMainHandItem();
if (!stack.is(ModTags.Items.GUN)) {
return;
}
if (!player.level().isClientSide) {
String origin = stack.getItem().getDescriptionId();
String name = origin.substring(origin.lastIndexOf(".") + 1);
SoundEvent sound1p = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc(name + "_prepare"));
if (sound1p != null && player instanceof ServerPlayer serverPlayer) {
SoundTool.playLocalSound(serverPlayer, sound1p, 10f, 1f);
}
}
}
public static void playGunEmptyPrepareSounds(Player player) {
ItemStack stack = player.getMainHandItem();
if (!stack.is(ModTags.Items.GUN)) {
return;
}
if (!player.level().isClientSide) {
String origin = stack.getItem().getDescriptionId();
String name = origin.substring(origin.lastIndexOf(".") + 1);
SoundEvent sound1p = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc(name + "_prepare_empty"));
if (sound1p != null && player instanceof ServerPlayer serverPlayer) {
SoundTool.playLocalSound(serverPlayer, sound1p, 10f, 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.queueServerWork((int) (GunsTool.getGunIntTag(stack, "PrepareEmptyTime", 0) / 2 + 3 + 1.5 * shooterHeight), () -> {
if (stack.is(ModTags.Items.SHOTGUN)) {
SoundTool.playLocalSound(serverPlayer, ModSounds.SHELL_CASING_SHOTGUN.get(), (float) Math.max(0.75 - 0.12 * shooterHeight, 0), 1);
} else if (stack.is(ModTags.Items.SNIPER_RIFLE) || stack.is(ModTags.Items.HEAVY_WEAPON)) {
SoundTool.playLocalSound(serverPlayer, ModSounds.SHELL_CASING_50CAL.get(), (float) Math.max(1 - 0.15 * shooterHeight, 0), 1);
} else {
SoundTool.playLocalSound(serverPlayer, ModSounds.SHELL_CASING_NORMAL.get(), (float) Math.max(1.5 - 0.2 * shooterHeight, 0), 1);
}
});
}
}
}
public static void playGunPrepareLoadReloadSounds(Player player) {
ItemStack stack = player.getMainHandItem();
if (!stack.is(ModTags.Items.GUN)) {
return;
}
if (!player.level().isClientSide) {
String origin = stack.getItem().getDescriptionId();
String name = origin.substring(origin.lastIndexOf(".") + 1);
SoundEvent sound1p = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc(name + "_prepare_load"));
if (sound1p != null && player instanceof ServerPlayer serverPlayer) {
SoundTool.playLocalSound(serverPlayer, sound1p, 10f, 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.queueServerWork((int) (8 + 1.5 * shooterHeight), () -> {
if (stack.is(ModTags.Items.SHOTGUN)) {
SoundTool.playLocalSound(serverPlayer, ModSounds.SHELL_CASING_SHOTGUN.get(), (float) Math.max(0.75 - 0.12 * shooterHeight, 0), 1);
} else if (stack.is(ModTags.Items.SNIPER_RIFLE) || stack.is(ModTags.Items.HEAVY_WEAPON)) {
SoundTool.playLocalSound(serverPlayer, ModSounds.SHELL_CASING_50CAL.get(), (float) Math.max(1 - 0.15 * shooterHeight, 0), 1);
} else {
SoundTool.playLocalSound(serverPlayer, ModSounds.SHELL_CASING_NORMAL.get(), (float) Math.max(1.5 - 0.2 * shooterHeight, 0), 1);
}
});
}
}
}
public static void playGunLoopReloadSounds(Player player) {
ItemStack stack = player.getMainHandItem();
if (!stack.is(ModTags.Items.GUN)) {
return;
}
if (!player.level().isClientSide) {
String origin = stack.getItem().getDescriptionId();
String name = origin.substring(origin.lastIndexOf(".") + 1);
SoundEvent sound1p = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc(name + "_loop"));
if (sound1p != null && player instanceof ServerPlayer serverPlayer) {
SoundTool.playLocalSound(serverPlayer, sound1p, 10f, 1f);
}
}
}
public static void playGunEndReloadSounds(Player player) {
ItemStack stack = player.getMainHandItem();
if (!stack.is(ModTags.Items.GUN)) {
return;
}
if (!player.level().isClientSide) {
String origin = stack.getItem().getDescriptionId();
String name = origin.substring(origin.lastIndexOf(".") + 1);
SoundEvent sound1p = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc(name + "_end"));
if (sound1p != null && player instanceof ServerPlayer serverPlayer) {
SoundTool.playLocalSound(serverPlayer, sound1p, 10f, 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())));
// 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));
// }
}
}
}
/**
* 哨兵充能
*/
private static void handleSentinelCharge(Player player) {
ItemStack stack = player.getMainHandItem();
// 启动换弹
if (GunsTool.getGunBooleanTag(stack, "StartCharge")) {
GunsTool.setGunIntTag(stack, "ChargeTime", 127);
GunsTool.setGunBooleanTag(stack, "Charging", true);
SoundEvent sound1p = BuiltInRegistries.SOUND_EVENT.get(ModUtils.loc("sentinel_charge"));
if (sound1p != null && player instanceof ServerPlayer serverPlayer) {
SoundTool.playLocalSound(serverPlayer, sound1p, 2f, 1f);
}
GunsTool.setGunBooleanTag(stack, "StartCharge", false);
}
if (GunsTool.getGunIntTag(stack, "ChargeTime", 0) > 0) {
GunsTool.setGunIntTag(stack, "ChargeTime", GunsTool.getGunIntTag(stack, "ChargeTime", 0) - 1);
}
if (GunsTool.getGunIntTag(stack, "ChargeTime", 0) == 17) {
for (var cell : player.getInventory().items) {
if (cell.is(ModItems.CELL.get())) {
var stackStorage = cell.getCapability(Capabilities.EnergyStorage.ITEM);
if (stackStorage == null) continue;
int stackMaxEnergy = stackStorage.getMaxEnergyStored();
int stackEnergy = stackStorage.getEnergyStored();
var cellStorage = cell.getCapability(Capabilities.EnergyStorage.ITEM);
if (cellStorage == null) continue;
int cellEnergy = cellStorage.getEnergyStored();
int stackEnergyNeed = Math.min(cellEnergy, stackMaxEnergy - stackEnergy);
if (cellEnergy > 0) {
stackStorage.receiveEnergy(stackEnergyNeed, false);
}
cellStorage.extractEnergy(stackEnergyNeed, false);
}
}
}
if (GunsTool.getGunIntTag(stack, "ChargeTime", 0) == 1) {
GunsTool.setGunBooleanTag(stack, "Charging", false);
}
}
// TODO missing mapping event
// @SubscribeEvent
// public static void onMissingMappings(MissingMappingsEvent event) {
// for (MissingMappingsEvent.Mapping<Item> mapping : event.getAllMappings(Registries.ITEM)) {
// if (ModUtils.MODID.equals(mapping.getKey().getNamespace()) && mapping.getKey().getPath().equals("abekiri")) {
// mapping.remap(ModItems.HOMEMADE_SHOTGUN.get());
// }
// }
// }
}

View file

@ -7,6 +7,7 @@ import com.atsuishio.superbwarfare.item.common.CannonShellItem;
import com.atsuishio.superbwarfare.item.common.MaterialPack; import com.atsuishio.superbwarfare.item.common.MaterialPack;
import com.atsuishio.superbwarfare.item.common.ammo.*; import com.atsuishio.superbwarfare.item.common.ammo.*;
import com.atsuishio.superbwarfare.item.common.ammo.box.AmmoBox; import com.atsuishio.superbwarfare.item.common.ammo.box.AmmoBox;
import com.atsuishio.superbwarfare.item.gun.smg.VectorItem;
import com.atsuishio.superbwarfare.tools.AmmoType; import com.atsuishio.superbwarfare.tools.AmmoType;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
@ -34,7 +35,7 @@ public class ModItems {
// public static final DeferredHolder<Item, Item> M_1911 = GUNS.register("m_1911", M1911Item::new); // public static final DeferredHolder<Item, Item> M_1911 = GUNS.register("m_1911", M1911Item::new);
// public static final DeferredHolder<Item, Item> HOMEMADE_SHOTGUN = GUNS.register("homemade_shotgun", HomemadeShotgunItem::new); // public static final DeferredHolder<Item, Item> HOMEMADE_SHOTGUN = GUNS.register("homemade_shotgun", HomemadeShotgunItem::new);
// public static final DeferredHolder<Item, Item> TRACHELIUM = GUNS.register("trachelium", Trachelium::new); // public static final DeferredHolder<Item, Item> TRACHELIUM = GUNS.register("trachelium", Trachelium::new);
// public static final DeferredHolder<Item, Item> VECTOR = GUNS.register("vector", VectorItem::new); public static final DeferredHolder<Item, VectorItem> VECTOR = GUNS.register("vector", VectorItem::new);
// public static final DeferredHolder<Item, Item> AK_47 = GUNS.register("ak_47", AK47Item::new); // public static final DeferredHolder<Item, Item> AK_47 = GUNS.register("ak_47", AK47Item::new);
// public static final DeferredHolder<Item, Item> AK_12 = GUNS.register("ak_12", AK12Item::new); // public static final DeferredHolder<Item, Item> AK_12 = GUNS.register("ak_12", AK12Item::new);
// public static final DeferredHolder<Item, Item> SKS = GUNS.register("sks", SksItem::new); // public static final DeferredHolder<Item, Item> SKS = GUNS.register("sks", SksItem::new);

View file

@ -1,7 +1,5 @@
package com.atsuishio.superbwarfare.init; package com.atsuishio.superbwarfare.init;
import com.atsuishio.superbwarfare.ModUtils;
import net.minecraft.client.renderer.item.ItemProperties;
import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.EventBusSubscriber;
@ -12,8 +10,8 @@ public class ModProperties {
@SubscribeEvent @SubscribeEvent
public static void propertyOverrideRegistry(FMLClientSetupEvent event) { public static void propertyOverrideRegistry(FMLClientSetupEvent event) {
// event.enqueueWork(() -> ItemProperties.register(ModItems.MONITOR.get(), ModUtils.loc("monitor_linked"), // event.enqueueWork(() -> ItemProperties.register(ModItems.MONITOR.get(), ModUtils.loc("monitor_linked"),
// (itemStack, clientWorld, livingEntity, seed) -> ItemNBTTool.getBoolean(itemStack, "Linked", false) ? 1.0F : 0.0F)); // (itemStack, clientWorld, livingEntity, seed) -> GunNBTTool.getBoolean(itemStack, "Linked", false) ? 1.0F : 0.0F));
// event.enqueueWork(() -> ItemProperties.register(ModItems.ARMOR_PLATE.get(), ModUtils.loc("armor_plate_infinite"), // event.enqueueWork(() -> ItemProperties.register(ModItems.ARMOR_PLATE.get(), ModUtils.loc("armor_plate_infinite"),
// (itemStack, clientWorld, livingEntity, seed) -> ItemNBTTool.getBoolean(itemStack, "Infinite", false) ? 1.0F : 0.0F)); // (itemStack, clientWorld, livingEntity, seed) -> GunNBTTool.getBoolean(itemStack, "Infinite", false) ? 1.0F : 0.0F));
} }
} }

View file

@ -2,6 +2,7 @@ package com.atsuishio.superbwarfare.init;
import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.item.BatteryItem; import com.atsuishio.superbwarfare.item.BatteryItem;
import com.atsuishio.superbwarfare.item.gun.smg.VectorItem;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.CreativeModeTab;
@ -18,12 +19,13 @@ public class ModTabs {
public static final DeferredRegister<CreativeModeTab> TABS = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, ModUtils.MODID); public static final DeferredRegister<CreativeModeTab> TABS = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, ModUtils.MODID);
// public static final DeferredHolder<CreativeModeTab, CreativeModeTab> GUN_TAB = TABS.register("guns", public static final DeferredHolder<CreativeModeTab, CreativeModeTab> GUN_TAB = TABS.register("guns",
// () -> CreativeModeTab.builder() () -> CreativeModeTab.builder()
// .title(Component.translatable("item_group.superbwarfare.guns")) .title(Component.translatable("item_group.superbwarfare.guns"))
// .icon(() -> new ItemStack(ModItems.TASER.get())) // .icon(() -> new ItemStack(ModItems.TASER.get()))
// .displayItems( .icon(() -> new ItemStack(ModItems.VECTOR.get()))
// (param, output) -> { .displayItems(
(param, output) -> {
// output.accept(TaserItem.getGunInstance()); // output.accept(TaserItem.getGunInstance());
// output.accept(Glock17Item.getGunInstance()); // output.accept(Glock17Item.getGunInstance());
// output.accept(Glock18Item.getGunInstance()); // output.accept(Glock18Item.getGunInstance());
@ -31,7 +33,7 @@ public class ModTabs {
// output.accept(Mp443Item.getGunInstance()); // output.accept(Mp443Item.getGunInstance());
// output.accept(HomemadeShotgunItem.getGunInstance()); // output.accept(HomemadeShotgunItem.getGunInstance());
// output.accept(Trachelium.getGunInstance()); // output.accept(Trachelium.getGunInstance());
// output.accept(VectorItem.getGunInstance()); output.accept(VectorItem.getGunInstance());
// output.accept(SksItem.getGunInstance()); // output.accept(SksItem.getGunInstance());
// output.accept(AK47Item.getGunInstance()); // output.accept(AK47Item.getGunInstance());
// output.accept(AK12Item.getGunInstance()); // output.accept(AK12Item.getGunInstance());
@ -58,10 +60,10 @@ public class ModTabs {
// output.accept(SecondaryCataclysm.getGunInstance()); // output.accept(SecondaryCataclysm.getGunInstance());
// output.accept(RpgItem.getGunInstance()); // output.accept(RpgItem.getGunInstance());
// output.accept(JavelinItem.getGunInstance()); // output.accept(JavelinItem.getGunInstance());
// } }
// ) )
// .build()); .build());
// //
public static final DeferredHolder<CreativeModeTab, CreativeModeTab> PERK_TAB = TABS.register("perk", public static final DeferredHolder<CreativeModeTab, CreativeModeTab> PERK_TAB = TABS.register("perk",
() -> CreativeModeTab.builder() () -> CreativeModeTab.builder()
.title(Component.translatable("item_group.superbwarfare.perk")) .title(Component.translatable("item_group.superbwarfare.perk"))

View file

@ -0,0 +1,20 @@
package com.atsuishio.superbwarfare.item.gun;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.init.ModTags;
import com.atsuishio.superbwarfare.tools.NBTTool;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.event.entity.player.ItemEntityPickupEvent;
@EventBusSubscriber(modid = ModUtils.MODID)
public class GunEvents {
@SubscribeEvent
public static void onPickup(ItemEntityPickupEvent.Pre event) {
var stack = event.getItemEntity().getItem();
if (stack.is(ModTags.Items.GUN)) {
NBTTool.getOrCreateTag(stack).putBoolean("draw", true);
NBTTool.getOrCreateTag(stack).putBoolean("init", true);
}
}
}

View file

@ -0,0 +1,440 @@
package com.atsuishio.superbwarfare.item.gun;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.capability.ModCapabilities;
import com.atsuishio.superbwarfare.client.PoseTool;
import com.atsuishio.superbwarfare.client.tooltip.component.GunImageComponent;
import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.init.ModTags;
import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.tools.AmmoType;
import com.atsuishio.superbwarfare.tools.GunsTool;
import com.atsuishio.superbwarfare.tools.NBTTool;
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.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.tooltip.TooltipComponent;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions;
import net.neoforged.neoforge.client.extensions.common.RegisterClientExtensionsEvent;
import org.jetbrains.annotations.NotNull;
import software.bernie.geckolib.renderer.GeoItemRenderer;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.Optional;
import java.util.Set;
@EventBusSubscriber(modid = ModUtils.MODID, bus = EventBusSubscriber.Bus.MOD)
public abstract class GunItem extends Item {
public GunItem(Properties properties) {
super(properties);
}
@Override
@ParametersAreNonnullByDefault
public boolean canAttackBlock(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer) {
return false;
}
@Override
@ParametersAreNonnullByDefault
public void inventoryTick(ItemStack stack, Level level, Entity entity, int slot, boolean selected) {
if (!(entity instanceof LivingEntity)) return;
if (!stack.is(ModTags.Items.GUN)) return;
if (!(stack.getItem() instanceof GunItem gunItem)) return;
if (!NBTTool.getBoolean(stack, "init", false)) {
GunsTool.initGun(level, stack, this.getDescriptionId().substring(this.getDescriptionId().lastIndexOf('.') + 1));
GunsTool.generateAndSetUUID(stack);
NBTTool.setBoolean(stack, "init", true);
}
if (NBTTool.getOrCreateTag(stack).getBoolean("draw")) {
NBTTool.getOrCreateTag(stack).putBoolean("draw", false);
}
handleGunPerks(stack);
handleGunAttachment(stack);
if ((gunItem.hasBulletInBarrel(stack) && GunsTool.getGunIntTag(stack, "Ammo", 0) >
GunsTool.getGunIntTag(stack, "Magazine", 0) + GunsTool.getGunIntTag(stack, "CustomMagazine", 0) + 1)
|| (!gunItem.hasBulletInBarrel(stack) && GunsTool.getGunIntTag(stack, "Ammo", 0) >
GunsTool.getGunIntTag(stack, "Magazine", 0) + GunsTool.getGunIntTag(stack, "CustomMagazine", 0))
) {
int count = GunsTool.getGunIntTag(stack, "Ammo", 0) - GunsTool.getGunIntTag(stack, "Magazine", 0)
+ GunsTool.getGunIntTag(stack, "CustomMagazine", 0) - (gunItem.hasBulletInBarrel(stack) ? 1 : 0);
var capability = entity.getCapability(ModCapabilities.PLAYER_VARIABLE);
if (capability != null) {
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO)) {
AmmoType.SHOTGUN.add(capability, count);
} else if (stack.is(ModTags.Items.USE_SNIPER_AMMO)) {
AmmoType.SNIPER.add(capability, count);
} else if (stack.is(ModTags.Items.USE_HANDGUN_AMMO)) {
AmmoType.HANDGUN.add(capability, count);
} else if (stack.is(ModTags.Items.USE_RIFLE_AMMO)) {
AmmoType.RIFLE.add(capability, count);
} else if (stack.is(ModTags.Items.USE_HEAVY_AMMO)) {
AmmoType.HEAVY.add(capability, count);
}
capability.syncPlayerVariables(entity);
}
GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Magazine", 0)
+ GunsTool.getGunIntTag(stack, "CustomMagazine", 0) + (gunItem.hasBulletInBarrel(stack) ? 1 : 0));
}
}
@Override
@ParametersAreNonnullByDefault
public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) {
return false;
}
// TODO attribute modifier
// @Override
// public @NotNull ItemAttributeModifiers getDefaultAttributeModifiers(@NotNull ItemStack stack) {
// ItemAttributeModifiers map = super.getDefaultAttributeModifiers(stack);
// map.builder().add(
// Attribute.BASE,
// new AttributeModifier(uuid, ModUtils.ATTRIBUTE_MODIFIER,
// -0.01f - 0.005f * (GunsTool.getGunDoubleTag(stack, "Weight") + GunsTool.getGunDoubleTag(stack, "CustomWeight")),
// AttributeModifier.Operation.ADD_MULTIPLIED_BASE)
// )
//
// map.put(Attributes.MOVEMENT_SPEED,
// new AttributeModifier(uuid, ModUtils.ATTRIBUTE_MODIFIER,
// -0.01f - 0.005f * (GunsTool.getGunDoubleTag(stack, "Weight") + GunsTool.getGunDoubleTag(stack, "CustomWeight")),
// AttributeModifier.Operation.ADD_MULTIPLIED_BASE));
// return map;
// }
// @Override
// public Multimap<Attribute, AttributeModifier> getAttributeModifiers(EquipmentSlot slot, ItemStack stack) {
// Multimap<Attribute, AttributeModifier> map = super.getAttributeModifiers(slot, stack);
// UUID uuid = new UUID(slot.toString().hashCode(), 0);
// if (slot == EquipmentSlot.MAINHAND) {
// map = HashMultimap.create(map);
// map.put(Attributes.MOVEMENT_SPEED,
// new AttributeModifier(uuid, ModUtils.ATTRIBUTE_MODIFIER,
// -0.01f - 0.005f * (GunsTool.getGunDoubleTag(stack, "Weight") + GunsTool.getGunDoubleTag(stack, "CustomWeight")),
// AttributeModifier.Operation.ADD_MULTIPLIED_BASE));
// }
// return map;
// }
@Override
public @NotNull Optional<TooltipComponent> getTooltipImage(@NotNull ItemStack pStack) {
return Optional.of(new GunImageComponent(pStack));
}
public Set<SoundEvent> getReloadSound() {
return Set.of();
}
public ResourceLocation getGunIcon() {
return ModUtils.loc("textures/gun_icon/default_icon.png");
}
public String getGunDisplayName() {
return "";
}
@Override
public boolean isFoil(@NotNull ItemStack stack) {
return false;
}
@Override
public boolean isEnchantable(@NotNull ItemStack stack) {
return false;
}
@Override
@ParametersAreNonnullByDefault
public boolean supportsEnchantment(ItemStack stack, Holder<Enchantment> enchantment) {
return false;
}
private void handleGunPerks(ItemStack stack) {
reducePerkTagCoolDown(stack, "HealClipTime", "KillClipReloadTime", "KillClipTime", "FourthTimesCharmTick", "HeadSeeker",
"DesperadoTime", "DesperadoTimePost");
// TODO perk
// if (PerkHelper.getItemPerkLevel(ModPerks.FOURTH_TIMES_CHARM.get(), stack) > 0) {
// int count = GunsTool.getPerkIntTag(stack, "FourthTimesCharmCount");
// if (count >= 4) {
// GunsTool.setPerkIntTag(stack, "FourthTimesCharmTick", 0);
// GunsTool.setPerkIntTag(stack, "FourthTimesCharmCount", 0);
//
// int mag = GunsTool.getGunIntTag(stack, "Magazine", 0) + GunsTool.getGunIntTag(stack, "CustomMagazine", 0);
// GunsTool.setGunIntTag(stack, "Ammo", Math.min(mag, GunsTool.getGunIntTag(stack, "Ammo", 0) + 2));
// }
// }
}
private void handleGunAttachment(ItemStack stack) {
CompoundTag tag = NBTTool.getOrCreateTag(stack).getCompound("Attachments");
double scopeWeight = switch (tag.getInt("Scope")) {
case 1 -> 0.5;
case 2 -> 1;
case 3 -> 1.5;
default -> 0;
};
double barrelWeight = switch (tag.getInt("Barrel")) {
case 1 -> 0.5;
case 2 -> 1;
default -> 0;
};
double magazineWeight = switch (tag.getInt("Magazine")) {
case 1 -> 1;
case 2 -> 2;
default -> 0;
};
double stockWeight = switch (tag.getInt("Stock")) {
case 1 -> -2;
case 2 -> 1.5;
default -> 0;
};
double gripWeight = switch (tag.getInt("Grip")) {
case 1, 2 -> 0.25;
case 3 -> 1;
default -> 0;
};
double soundRadius = tag.getInt("Barrel") == 2 ? 0.6 : 1;
GunsTool.setGunDoubleTag(stack, "CustomWeight", scopeWeight + barrelWeight + magazineWeight + stockWeight + gripWeight);
GunsTool.setGunDoubleTag(stack, "CustomSoundRadius", soundRadius);
}
public boolean canApplyPerk(Perk perk) {
return true;
}
private void reducePerkTagCoolDown(ItemStack stack, String... tags) {
var tag = NBTTool.getOrCreateTag(stack);
var compound = tag.getCompound("PerkData");
for (String t : tags) {
if (!compound.contains(t)) {
continue;
}
if (compound.getInt(t) > 0) {
compound.putInt(t, Math.max(0, compound.getInt(t) - 1));
}
}
tag.put("PerkData", compound);
}
/**
* 是否使用弹匣换弹
*
* @param stack 武器物品
*/
public boolean isMagazineReload(ItemStack stack) {
return false;
}
/**
* 是否使用弹夹换弹
*
* @param stack 武器物品
*/
public boolean isClipReload(ItemStack stack) {
return false;
}
/**
* 是否是单发装填换弹
*
* @param stack 武器物品
*/
public boolean isIterativeReload(ItemStack stack) {
return false;
}
/**
* 开膛待击
*
* @param stack 武器物品
*/
public boolean isOpenBolt(ItemStack stack) {
return false;
}
/**
* 是否允许额外往枪管里塞入一发子弹
*
* @param stack 武器物品
*/
public boolean hasBulletInBarrel(ItemStack stack) {
return false;
}
/**
* 武器是否为全自动武器
*
* @param stack 武器物品
*/
public boolean isAutoWeapon(ItemStack stack) {
return false;
}
/**
* 武器是否直接使用背包内的弹药物品进行发射而不是使用玩家存储的弹药
*
* @param stack 武器物品
*/
public boolean useBackpackAmmo(ItemStack stack) {
return false;
}
/**
* 武器是否能进行改装
*
* @param stack 武器物品
*/
public boolean isCustomizable(ItemStack stack) {
return false;
}
/**
* 武器是否能更换枪管配件
*
* @param stack 武器物品
*/
public boolean hasCustomBarrel(ItemStack stack) {
return false;
}
/**
* 武器是否能更换枪托配件
*
* @param stack 武器物品
*/
public boolean hasCustomGrip(ItemStack stack) {
return false;
}
/**
* 武器是否能更换弹匣配件
*
* @param stack 武器物品
*/
public boolean hasCustomMagazine(ItemStack stack) {
return false;
}
/**
* 武器是否能更换瞄具配件
*
* @param stack 武器物品
*/
public boolean hasCustomScope(ItemStack stack) {
return false;
}
/**
* 武器是否能更换枪托配件
*
* @param stack 武器物品
*/
public boolean hasCustomStock(ItemStack stack) {
return false;
}
/**
* 武器是否有脚架
*
* @param stack 武器物品
*/
public boolean hasBipod(ItemStack stack) {
return false;
}
/**
* 武器是否会抛壳
*
* @param stack 武器物品
*/
public boolean canEjectShell(ItemStack stack) {
return false;
}
/**
* 武器是否能进行近战攻击
*
* @param stack 武器物品
*/
public boolean hasMeleeAttack(ItemStack stack) {
return false;
}
/**
* 获取武器可用的开火模式
*/
public int getAvailableFireModes() {
return 0;
}
public enum FireMode {
SEMI(1),
BURST(2),
AUTO(4);
public final int flag;
FireMode(int i) {
this.flag = i;
}
}
public abstract GeoItemRenderer<? extends GunItem> getRenderer();
@SubscribeEvent
private static void registerGunExtensions(RegisterClientExtensionsEvent event) {
for (var item : ModItems.GUNS.getEntries()) {
if (item.get() instanceof GunItem gun) {
event.registerItem(new IClientItemExtensions() {
private final BlockEntityWithoutLevelRenderer renderer = gun.getRenderer();
@Override
public @NotNull BlockEntityWithoutLevelRenderer getCustomRenderer() {
return renderer;
}
@Override
@ParametersAreNonnullByDefault
public HumanoidModel.ArmPose getArmPose(LivingEntity entityLiving, InteractionHand hand, ItemStack stack) {
return PoseTool.pose(entityLiving, hand, stack);
}
}, item);
}
}
}
}

View file

@ -0,0 +1,231 @@
package com.atsuishio.superbwarfare.item.gun.smg;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.capability.ModCapabilities;
import com.atsuishio.superbwarfare.client.renderer.item.VectorItemRenderer;
import com.atsuishio.superbwarfare.event.ClientEventHandler;
import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.init.ModSounds;
import com.atsuishio.superbwarfare.init.ModTags;
import com.atsuishio.superbwarfare.item.gun.GunItem;
import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.tools.GunsTool;
import com.atsuishio.superbwarfare.tools.NBTTool;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Rarity;
import net.minecraft.world.level.Level;
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.Set;
public class VectorItem extends GunItem implements GeoItem {
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
public static ItemDisplayContext transformType;
public VectorItem() {
super(new Properties().stacksTo(1).rarity(Rarity.EPIC));
}
public void getTransformType(ItemDisplayContext type) {
transformType = type;
}
private PlayState idlePredicate(AnimationState<VectorItem> event) {
LocalPlayer player = Minecraft.getInstance().player;
if (player == null) return PlayState.STOP;
ItemStack stack = player.getMainHandItem();
if (!stack.is(ModTags.Items.GUN)) return PlayState.STOP;
boolean drum = GunsTool.getAttachmentType(stack, GunsTool.AttachmentType.MAGAZINE) == 2;
if (NBTTool.getOrCreateTag(stack).getBoolean("is_empty_reloading")) {
if (drum) {
return event.setAndContinue(RawAnimation.begin().thenPlay("animation.vec.reload_empty_drum"));
} else {
return event.setAndContinue(RawAnimation.begin().thenPlay("animation.vec.reload_empty"));
}
}
if (NBTTool.getOrCreateTag(stack).getBoolean("is_normal_reloading")) {
if (drum) {
return event.setAndContinue(RawAnimation.begin().thenPlay("animation.vec.reload_normal_drum"));
} else {
return event.setAndContinue(RawAnimation.begin().thenPlay("animation.vec.reload_normal"));
}
}
if (player.isSprinting() && player.onGround() && player.getPersistentData().getDouble("noRun") == 0 && ClientEventHandler.drawTime < 0.01) {
if (player.hasEffect(MobEffects.MOVEMENT_SPEED)) {
return event.setAndContinue(RawAnimation.begin().thenLoop("animation.vec.run_fast"));
} else {
return event.setAndContinue(RawAnimation.begin().thenLoop("animation.vec.run"));
}
}
return event.setAndContinue(RawAnimation.begin().thenLoop("animation.vec.idle"));
}
private PlayState editPredicate(AnimationState<VectorItem> event) {
LocalPlayer player = Minecraft.getInstance().player;
if (player == null) return PlayState.STOP;
ItemStack stack = player.getMainHandItem();
if (!stack.is(ModTags.Items.GUN)) return PlayState.STOP;
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
if (cap != null && cap.edit) {
return event.setAndContinue(RawAnimation.begin().thenPlay("animation.vector.edit"));
}
return event.setAndContinue(RawAnimation.begin().thenLoop("animation.vec.idle"));
}
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar data) {
AnimationController<VectorItem> idleController = new AnimationController<>(this, "idleController", 2, this::idlePredicate);
data.add(idleController);
var editController = new AnimationController<>(this, "editController", 1, this::editPredicate);
data.add(editController);
}
@Override
public AnimatableInstanceCache getAnimatableInstanceCache() {
return this.cache;
}
@Override
public GeoItemRenderer<? extends GunItem> getRenderer() {
return new VectorItemRenderer();
}
@Override
@ParametersAreNonnullByDefault
public void inventoryTick(ItemStack stack, Level world, Entity entity, int slot, boolean selected) {
super.inventoryTick(stack, world, entity, slot, selected);
int scopeType = GunsTool.getAttachmentType(stack, GunsTool.AttachmentType.SCOPE);
int magType = GunsTool.getAttachmentType(stack, GunsTool.AttachmentType.MAGAZINE);
int customMag = switch (magType) {
case 1 -> 20;
case 2 -> 57;
default -> 0;
};
if (scopeType == 3) {
CompoundTag tag = NBTTool.getOrCreateTag(stack).getCompound("Attachments");
tag.putInt("Scope", 0);
}
double customZoom = switch (scopeType) {
case 0, 1 -> 0;
case 2 -> 0.75;
default -> GunsTool.getGunDoubleTag(stack, "CustomZoom", 0);
};
GunsTool.setGunDoubleTag(stack, "CustomZoom", customZoom);
GunsTool.setGunDoubleTag(stack, "CustomMagazine", customMag);
}
public static ItemStack getGunInstance() {
ItemStack stack = new ItemStack(ModItems.VECTOR.get());
GunsTool.initCreativeGun(stack, ModItems.VECTOR.getId().getPath());
return stack;
}
@Override
public Set<SoundEvent> getReloadSound() {
return Set.of(ModSounds.VECTOR_RELOAD_NORMAL.get(), ModSounds.VECTOR_RELOAD_EMPTY.get());
}
@Override
public ResourceLocation getGunIcon() {
return ModUtils.loc("textures/gun_icon/vector_icon.png");
}
@Override
public String getGunDisplayName() {
return "VECTOR";
}
@Override
public boolean canApplyPerk(Perk perk) {
// TODO perk
// return PerkHelper.SMG_PERKS.test(perk) || PerkHelper.MAGAZINE_PERKS.test(perk);
return false;
}
@Override
public boolean isMagazineReload(ItemStack stack) {
return true;
}
@Override
public boolean isOpenBolt(ItemStack stack) {
return true;
}
@Override
public boolean hasBulletInBarrel(ItemStack stack) {
return true;
}
@Override
public boolean isAutoWeapon(ItemStack stack) {
return true;
}
@Override
public boolean isCustomizable(ItemStack stack) {
return true;
}
@Override
public boolean hasCustomBarrel(ItemStack stack) {
return true;
}
@Override
public boolean hasCustomGrip(ItemStack stack) {
return true;
}
@Override
public boolean hasCustomMagazine(ItemStack stack) {
return true;
}
@Override
public boolean hasCustomScope(ItemStack stack) {
return true;
}
@Override
public boolean hasCustomStock(ItemStack stack) {
return true;
}
@Override
public boolean canEjectShell(ItemStack stack) {
return true;
}
@Override
public int getAvailableFireModes() {
return FireMode.SEMI.flag + FireMode.BURST.flag + FireMode.AUTO.flag;
}
}

View file

@ -13,9 +13,11 @@ public class NetworkRegistry {
registrar.playToClient(ClientMotionSyncMessage.TYPE, ClientMotionSyncMessage.STREAM_CODEC, ClientMotionSyncMessage::handler); registrar.playToClient(ClientMotionSyncMessage.TYPE, ClientMotionSyncMessage.STREAM_CODEC, ClientMotionSyncMessage::handler);
registrar.playToClient(ClientIndicatorMessage.TYPE, ClientIndicatorMessage.STREAM_CODEC, ClientIndicatorMessage::handler); registrar.playToClient(ClientIndicatorMessage.TYPE, ClientIndicatorMessage.STREAM_CODEC, ClientIndicatorMessage::handler);
registrar.playToClient(PlayerGunKillMessage.TYPE, PlayerGunKillMessage.STREAM_CODEC, PlayerGunKillMessage::handler); registrar.playToClient(PlayerGunKillMessage.TYPE, PlayerGunKillMessage.STREAM_CODEC, PlayerGunKillMessage::handler);
registrar.playToClient(GunsDataMessage.TYPE, GunsDataMessage.STREAM_CODEC, GunsDataMessage::handler);
registrar.playToServer(LaserShootMessage.TYPE, LaserShootMessage.STREAM_CODEC, LaserShootMessage::handler); registrar.playToServer(LaserShootMessage.TYPE, LaserShootMessage.STREAM_CODEC, LaserShootMessage::handler);
registrar.playToServer(BreathMessage.TYPE, BreathMessage.STREAM_CODEC, BreathMessage::handler); registrar.playToServer(BreathMessage.TYPE, BreathMessage.STREAM_CODEC, BreathMessage::handler);
registrar.playToServer(ShootMessage.TYPE, ShootMessage.STREAM_CODEC, ShootMessage::handler);
} }
} }

View file

@ -0,0 +1,41 @@
package com.atsuishio.superbwarfare.network.message;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.tools.GunsTool;
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.neoforge.network.handling.IPayloadContext;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
public record GunsDataMessage(HashMap<String, HashMap<String, Double>> gunsData) implements CustomPacketPayload {
public static final Type<GunsDataMessage> TYPE = new Type<>(ModUtils.loc("set_guns_data"));
public static final StreamCodec<ByteBuf, GunsDataMessage> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.map(
HashMap::new,
ByteBufCodecs.STRING_UTF8,
ByteBufCodecs.map(
HashMap::new,
ByteBufCodecs.STRING_UTF8,
ByteBufCodecs.DOUBLE
)
),
GunsDataMessage::gunsData,
GunsDataMessage::new
);
public static void handler(final GunsDataMessage message, final IPayloadContext context) {
GunsTool.gunsData = message.gunsData;
}
@Override
public @NotNull Type<? extends CustomPacketPayload> type() {
return TYPE;
}
}

View file

@ -0,0 +1,129 @@
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.getOrCreateTag(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.getOrCreateTag(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;
}
}

View file

@ -0,0 +1,265 @@
package com.atsuishio.superbwarfare.tools;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.capability.ModCapabilities;
import com.atsuishio.superbwarfare.component.ModDataComponents;
import com.atsuishio.superbwarfare.init.ModTags;
import com.atsuishio.superbwarfare.item.gun.GunItem;
import com.atsuishio.superbwarfare.network.message.GunsDataMessage;
import com.google.gson.stream.JsonReader;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
import net.neoforged.neoforge.event.server.ServerStartedEvent;
import net.neoforged.neoforge.network.PacketDistributor;
import javax.annotation.Nullable;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.UUID;
@EventBusSubscriber(modid = ModUtils.MODID)
public class GunsTool {
public static HashMap<String, HashMap<String, Double>> gunsData = new HashMap<>();
/**
* 初始化数据从data中读取数据json文件
*/
public static void initJsonData(ResourceManager manager) {
for (var entry : manager.listResources("guns", file -> file.getPath().endsWith(".json")).entrySet()) {
var id = entry.getKey();
var attribute = entry.getValue();
try {
JsonReader reader = new JsonReader(new InputStreamReader(attribute.open()));
reader.beginObject();
var map = new HashMap<String, Double>();
while (reader.hasNext()) {
map.put(reader.nextName(), reader.nextDouble());
}
var path = id.getPath();
gunsData.put(path.substring(5, path.length() - 5), map);
reader.endObject();
reader.close();
} catch (Exception e) {
ModUtils.LOGGER.error(e.getMessage());
}
}
}
public static void initGun(Level level, ItemStack stack, String location) {
if (level.getServer() == null) return;
gunsData.get(location).forEach((k, v) -> {
CompoundTag tag = NBTTool.getOrCreateTag(stack);
CompoundTag data = tag.getCompound("GunData");
data.putDouble(k, v);
tag.put("GunData", data);
});
}
public static void initCreativeGun(ItemStack stack, String location) {
if (gunsData != null && gunsData.get(location) != null) {
gunsData.get(location).forEach((k, v) -> {
CompoundTag tag = NBTTool.getOrCreateTag(stack);
CompoundTag data = tag.getCompound("GunData");
data.putDouble(k, v);
tag.put("GunData", data);
});
GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Magazine", 0)
+ GunsTool.getGunIntTag(stack, "CustomMagazine", 0));
}
}
public static void generateAndSetUUID(ItemStack stack) {
UUID uuid = UUID.randomUUID();
CompoundTag tag = NBTTool.getOrCreateTag(stack);
var data = tag.getCompound("GunData");
data.putUUID("UUID", uuid);
tag.put("GunData", data);
}
@SubscribeEvent
public static void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent event) {
if (event.getEntity() instanceof ServerPlayer player) {
PacketDistributor.sendToPlayer(player, new GunsDataMessage(GunsTool.gunsData));
}
}
@SubscribeEvent
public static void serverStarted(ServerStartedEvent event) {
initJsonData(event.getServer().getResourceManager());
}
public static void reload(Player player, ItemStack stack, AmmoType type) {
reload(player, stack, type, false);
}
public static void reload(Player player, ItemStack stack, AmmoType type, boolean extraOne) {
CompoundTag tag = NBTTool.getOrCreateTag(stack);
if (!(stack.getItem() instanceof GunItem)) return;
int mag = GunsTool.getGunIntTag(stack, "Magazine", 0) + GunsTool.getGunIntTag(stack, "CustomMagazine", 0);
int ammo = GunsTool.getGunIntTag(stack, "Ammo", 0);
int ammoToAdd = mag - ammo + (extraOne ? 1 : 0);
// 空仓换弹的栓动武器应该在换弹后取消待上膛标记
if (ammo == 0 && GunsTool.getGunIntTag(stack, "BoltActionTime", 0) > 0 && !stack.is(ModTags.Items.REVOLVER)) {
GunsTool.setGunBooleanTag(stack, "NeedBoltAction", false);
}
var capability = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
var playerAmmo = 0;
if (capability != null) {
playerAmmo = type.get(capability);
var newAmmoCount = Math.max(0, playerAmmo - ammoToAdd);
type.set(capability, newAmmoCount);
capability.syncPlayerVariables(player);
}
int needToAdd = ammo + Math.min(ammoToAdd, playerAmmo);
GunsTool.setGunIntTag(stack, "Ammo", needToAdd);
tag.putBoolean("is_normal_reloading", false);
tag.putBoolean("is_empty_reloading", false);
}
/* PerkData */
public static void setPerkIntTag(ItemStack stack, String name, int num) {
var rootTag = NBTTool.getOrCreateTag(stack);
CompoundTag tag = rootTag.getCompound("PerkData");
tag.putInt(name, num);
rootTag.put("PerkData", tag);
}
public static int getPerkIntTag(ItemStack stack, String name) {
CompoundTag tag = NBTTool.getOrCreateTag(stack).getCompound("PerkData");
return tag.getInt(name);
}
public static void setPerkDoubleTag(ItemStack stack, String name, double num) {
var rootTag = NBTTool.getOrCreateTag(stack);
CompoundTag tag = rootTag.getCompound("PerkData");
tag.putDouble(name, num);
rootTag.put("PerkData", tag);
}
public static double getPerkDoubleTag(ItemStack stack, String name) {
CompoundTag tag = NBTTool.getOrCreateTag(stack).getCompound("PerkData");
return tag.getDouble(name);
}
public static void setPerkBooleanTag(ItemStack stack, String name, boolean flag) {
var rootTag = NBTTool.getOrCreateTag(stack);
CompoundTag tag = rootTag.getCompound("PerkData");
tag.putBoolean(name, flag);
rootTag.put("PerkData", tag);
}
public static boolean getPerkBooleanTag(ItemStack stack, String name) {
CompoundTag tag = NBTTool.getOrCreateTag(stack).getCompound("PerkData");
return tag.getBoolean(name);
}
/* Attachments */
public static int getAttachmentType(ItemStack stack, AttachmentType type) {
CompoundTag tag = NBTTool.getOrCreateTag(stack).getCompound("Attachments");
return tag.getInt(type.getName());
}
public enum AttachmentType {
SCOPE("Scope"),
MAGAZINE("Magazine"),
BARREL("Barrel"),
STOCK("Stock"),
GRIP("Grip");
private final String name;
AttachmentType(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
/* GunData */
public static CompoundTag getGunData(ItemStack stack) {
CompoundTag tag = NBTTool.getOrCreateTag(stack);
return tag.getCompound("GunData");
}
public static void setGunIntTag(ItemStack stack, String name, int num) {
CompoundTag tag = NBTTool.getOrCreateTag(stack);
var data = tag.getCompound("GunData");
data.putInt(name, num);
tag.put("GunData", data);
}
public static int getGunIntTag(ItemStack stack, String name) {
return getGunIntTag(stack, name, 0);
}
public static int getGunIntTag(ItemStack stack, String name, int defaultValue) {
CompoundTag tag = NBTTool.getOrCreateTag(stack);
var data = tag.getCompound("GunData");
if (!data.contains(name)) return defaultValue;
return data.getInt(name);
}
public static void setGunDoubleTag(ItemStack stack, String name, double num) {
CompoundTag tag = NBTTool.getOrCreateTag(stack);
var data = tag.getCompound("GunData");
data.putDouble(name, num);
tag.put("GunData", data);
}
public static double getGunDoubleTag(ItemStack stack, String name) {
return getGunDoubleTag(stack, name, 0);
}
public static double getGunDoubleTag(ItemStack stack, String name, double defaultValue) {
CompoundTag tag = NBTTool.getOrCreateTag(stack);
var data = tag.getCompound("GunData");
if (!data.contains(name)) return defaultValue;
return data.getDouble(name);
}
public static void setGunBooleanTag(ItemStack stack, String name, boolean flag) {
CompoundTag tag = NBTTool.getOrCreateTag(stack);
var data = tag.getCompound("GunData");
data.putBoolean(name, flag);
tag.put("GunData", data);
}
public static boolean getGunBooleanTag(ItemStack stack, String name) {
return getGunBooleanTag(stack, name, false);
}
public static boolean getGunBooleanTag(ItemStack stack, String name, boolean defaultValue) {
CompoundTag tag = NBTTool.getOrCreateTag(stack);
var data = tag.getCompound("GunData");
if (!data.contains(name)) return defaultValue;
return data.getBoolean(name);
}
@Nullable
public static UUID getGunUUID(ItemStack stack) {
CompoundTag tag = stack.get(ModDataComponents.GUN_DATA);
if (tag == null || !tag.contains("GunData")) return null;
CompoundTag data = tag.getCompound("GunData");
if (!data.hasUUID("UUID")) return null;
return data.getUUID("UUID");
}
}

View file

@ -1,5 +1,6 @@
package com.atsuishio.superbwarfare.tools; package com.atsuishio.superbwarfare.tools;
import com.atsuishio.superbwarfare.init.ModItems;
import net.minecraft.core.NonNullList; import net.minecraft.core.NonNullList;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
@ -57,18 +58,18 @@ public class InventoryTool {
* *
* @param itemList 物品列表 * @param itemList 物品列表
*/ */
// public static boolean hasCreativeAmmoBox(NonNullList<ItemStack> itemList) { public static boolean hasCreativeAmmoBox(NonNullList<ItemStack> itemList) {
// return countItem(itemList, ModItems.CREATIVE_AMMO_BOX.get()) > 0; return countItem(itemList, ModItems.CREATIVE_AMMO_BOX.get()) > 0;
// } }
//
// /** /**
// * 判断玩家背包内是否有创造模式弹药盒 * 判断玩家背包内是否有创造模式弹药盒
// * *
// * @param player 玩家 * @param player 玩家
// */ */
// public static boolean hasCreativeAmmoBox(Player player) { public static boolean hasCreativeAmmoBox(Player player) {
// return hasItem(player, ModItems.CREATIVE_AMMO_BOX.get()); return hasItem(player, ModItems.CREATIVE_AMMO_BOX.get());
// } }
/** /**
* 消耗物品列表内指定物品 * 消耗物品列表内指定物品

View file

@ -0,0 +1,62 @@
package com.atsuishio.superbwarfare.tools;
import com.atsuishio.superbwarfare.component.ModDataComponents;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
// From Botania
public final class NBTTool {
public static boolean verifyExistence(ItemStack stack, String tag) {
var data = stack.get(ModDataComponents.GUN_DATA);
return !stack.isEmpty() && data != null && data.contains(tag);
}
public static CompoundTag getOrCreateTag(ItemStack stack) {
var data = stack.get(ModDataComponents.GUN_DATA);
if (data != null) return data;
var newTag = new CompoundTag();
stack.set(ModDataComponents.GUN_DATA, newTag);
return newTag;
}
public static void setBoolean(ItemStack stack, String tag, boolean b) {
getOrCreateTag(stack).putBoolean(tag, b);
}
public static boolean getBoolean(ItemStack stack, String tag, boolean defaultExpected) {
return verifyExistence(stack, tag) ? getOrCreateTag(stack).getBoolean(tag) : defaultExpected;
}
public static void setFloat(ItemStack stack, String tag, float f) {
getOrCreateTag(stack).putFloat(tag, f);
}
public static float getFloat(ItemStack stack, String tag, float f) {
return verifyExistence(stack, tag) ? getOrCreateTag(stack).getFloat(tag) : f;
}
public static void setInt(ItemStack stack, String tag, int num) {
getOrCreateTag(stack).putInt(tag, num);
}
public static int getInt(ItemStack stack, String tag, int num) {
return verifyExistence(stack, tag) ? getOrCreateTag(stack).getInt(tag) : num;
}
public static void setLong(ItemStack stack, String tag, long num) {
getOrCreateTag(stack).putLong(tag, num);
}
public static long getLong(ItemStack stack, String tag, long num) {
return verifyExistence(stack, tag) ? getOrCreateTag(stack).getLong(tag) : num;
}
public static void setDouble(ItemStack stack, String tag, double num) {
getOrCreateTag(stack).putDouble(tag, num);
}
public static double getDouble(ItemStack stack, String tag, double num) {
return verifyExistence(stack, tag) ? getOrCreateTag(stack).getDouble(tag) : num;
}
}

View file

@ -0,0 +1,17 @@
{
"Spread": 3.5,
"RecoilX": 0.006,
"RecoilY": 0.018,
"Damage": 2.5,
"Headshot": 1.5,
"Velocity": 17,
"Magazine": 25,
"ProjectileAmount": 12,
"Weight": 7,
"FireMode": 2,
"NormalReloadTime": 64,
"EmptyReloadTime": 85,
"BypassesArmor": 0.05,
"SoundRadius": 18,
"RPM": 360
}

View file

@ -0,0 +1,18 @@
{
"MinZoom": 1.25,
"MaxZoom": 6,
"Spread": 3.5,
"RecoilX": 0.0015,
"RecoilY": 0.01,
"Damage": 7.7,
"Headshot": 2,
"Velocity": 44.5,
"Magazine": 30,
"Weight": 4,
"FireMode": 2,
"NormalReloadTime": 52,
"EmptyReloadTime": 58,
"BypassesArmor": 0.23,
"SoundRadius": 12,
"RPM": 700
}

View file

@ -0,0 +1,18 @@
{
"MinZoom": 1.25,
"MaxZoom": 6,
"Spread": 4,
"RecoilX": 0.002,
"RecoilY": 0.012,
"Damage": 8.5,
"Headshot": 2,
"Velocity": 36,
"Magazine": 30,
"Weight": 5,
"FireMode": 2,
"NormalReloadTime": 52,
"EmptyReloadTime": 65,
"BypassesArmor": 0.2,
"SoundRadius": 14,
"RPM": 600
}

View file

@ -0,0 +1,8 @@
{
"CustomZoom": 0.75,
"Spread": 4,
"Headshot": 2.5,
"Damage": 48,
"Weight": 3,
"BypassesArmor": 0.25
}

View file

@ -0,0 +1,17 @@
{
"CustomZoom": 0.75,
"Spread": 5,
"RecoilX": 0.0018,
"RecoilY": 0.01,
"Damage": 9.5,
"Headshot": 2,
"Velocity": 40,
"Magazine": 55,
"Weight": 6,
"FireMode": 2,
"NormalReloadTime": 73,
"EmptyReloadTime": 95,
"BypassesArmor": 0.25,
"SoundRadius": 13,
"RPM": 400
}

View file

@ -0,0 +1,15 @@
{
"Spread": 2.5,
"RecoilX": 0.004,
"RecoilY": 0.013,
"Damage": 5.5,
"Headshot": 1.5,
"Velocity": 17,
"Magazine": 17,
"Weight": 1,
"NormalReloadTime": 44,
"EmptyReloadTime": 47,
"BypassesArmor": 0.15,
"SoundRadius": 8,
"RPM": 400
}

View file

@ -0,0 +1,16 @@
{
"Spread": 2.5,
"RecoilX": 0.004,
"RecoilY": 0.013,
"Damage": 5.5,
"Headshot": 1.5,
"Velocity": 17,
"Magazine": 17,
"Weight": 1,
"FireMode": 2,
"NormalReloadTime": 44,
"EmptyReloadTime": 47,
"BypassesArmor": 0.15,
"SoundRadius": 8,
"RPM": 1300
}

View file

@ -0,0 +1,18 @@
{
"MinZoom": 1.25,
"MaxZoom": 6,
"Spread": 3.5,
"RecoilX": 0.0016,
"RecoilY": 0.009,
"Damage": 7.5,
"Headshot": 2,
"Velocity": 44,
"Magazine": 30,
"Weight": 4,
"FireMode": 2,
"NormalReloadTime": 56,
"EmptyReloadTime": 64,
"BypassesArmor": 0.25,
"SoundRadius": 14,
"RPM": 900
}

View file

@ -0,0 +1,16 @@
{
"Spread": 4,
"RecoilX": 0.005,
"RecoilY": 0.026,
"Damage": 5,
"Headshot": 1.5,
"Velocity": 15,
"Magazine": 2,
"ProjectileAmount": 12,
"Weight": 1,
"NormalReloadTime": 66,
"EmptyReloadTime": 83,
"BypassesArmor": 0.01,
"SoundRadius": 16,
"RPM": 600
}

View file

@ -0,0 +1,13 @@
{
"Spread": 7,
"RecoilX": 0.004,
"RecoilY": 0.04,
"Damage": 65,
"Headshot": 3,
"Velocity": 38,
"Magazine": 1,
"Weight": 5,
"EmptyReloadTime": 64,
"BypassesArmor": 0.7,
"SoundRadius": 20
}

View file

@ -0,0 +1,10 @@
{
"CustomZoom": 1.75,
"Spread": 5,
"Magazine": 1,
"Weight": 10,
"EmptyReloadTime": 78,
"Damage": 700,
"ExplosionDamage": 60,
"ExplosionRadius": 5
}

View file

@ -0,0 +1,18 @@
{
"Spread": 5,
"RecoilX": 0.002,
"RecoilY": 0.063,
"Damage": 35,
"Headshot": 3,
"Velocity": 37.75,
"Magazine": 5,
"BoltActionTime": 22,
"Weight": 5,
"FireMode": 0,
"EmptyReloadTime": 59,
"PrepareTime": 29,
"IterativeTime": 11,
"FinishTime": 18,
"BypassesArmor": 0.5,
"SoundRadius": 18
}

View file

@ -0,0 +1,15 @@
{
"Spread": 2.5,
"RecoilX": 0.006,
"RecoilY": 0.018,
"Damage": 9.5,
"Headshot": 1.5,
"Velocity": 15,
"Magazine": 7,
"Weight": 2,
"NormalReloadTime": 44,
"EmptyReloadTime": 47,
"BypassesArmor": 0.2,
"SoundRadius": 10,
"RPM": 400
}

View file

@ -0,0 +1,18 @@
{
"MinZoom": 4,
"MaxZoom": 8,
"Spread": 4,
"RecoilX": 0.0015,
"RecoilY": 0.011,
"Damage": 7,
"Headshot": 2,
"Velocity": 44,
"Magazine": 30,
"Weight": 4,
"FireMode": 2,
"NormalReloadTime": 56,
"EmptyReloadTime": 64,
"BypassesArmor": 0.25,
"SoundRadius": 14,
"RPM": 850
}

View file

@ -0,0 +1,16 @@
{
"Spread": 5,
"RecoilX": 0.004,
"RecoilY": 0.014,
"Damage": 9,
"Headshot": 2,
"Velocity": 43,
"Magazine": 100,
"Weight": 8,
"FireMode": 2,
"NormalReloadTime": 114,
"EmptyReloadTime": 133,
"BypassesArmor": 0.25,
"SoundRadius": 15,
"RPM": 600
}

View file

@ -0,0 +1,12 @@
{
"Spread": 1.5,
"RecoilX": 0.004,
"RecoilY": 0.023,
"Damage": 40,
"ExplosionDamage": 80,
"ExplosionRadius": 5,
"Velocity": 3.75,
"Magazine": 1,
"Weight": 4,
"EmptyReloadTime": 64
}

View file

@ -0,0 +1,18 @@
{
"Spread": 3,
"RecoilX": 0.009,
"RecoilY": 0.04,
"Damage": 3,
"Headshot": 1.5,
"Velocity": 17,
"Magazine": 8,
"ProjectileAmount": 12,
"Weight": 4,
"PrepareTime": 7,
"PrepareLoadTime": 36,
"IterativeTime": 16,
"FinishTime": 12,
"BypassesArmor": 0.05,
"SoundRadius": 16,
"BoltActionTime": 11
}

View file

@ -0,0 +1,18 @@
{
"CustomZoom": 4.75,
"MinZoom": 4,
"MaxZoom": 8,
"Spread": 6,
"RecoilX": 0.007,
"RecoilY": 0.013,
"Damage": 38,
"Headshot": 3,
"Velocity": 47.2,
"Magazine": 5,
"BoltActionTime": 18,
"Weight": 7,
"NormalReloadTime": 60,
"EmptyReloadTime": 78,
"BypassesArmor": 0.6,
"SoundRadius": 18
}

View file

@ -0,0 +1,16 @@
{
"Spread": 2,
"RecoilX": 0.004,
"RecoilY": 0.031,
"Damage": 16,
"Headshot": 2.5,
"Velocity": 38,
"Magazine": 8,
"Weight": 3,
"PrepareTime": 7,
"IterativeTime": 16,
"FinishTime": 19,
"BypassesArmor": 0.3,
"SoundRadius": 15,
"BoltActionTime": 12
}

View file

@ -0,0 +1,12 @@
{
"Spread": 1.5,
"RecoilX": 0.003,
"RecoilY": 0.02,
"Damage": 8,
"Headshot": 2,
"Velocity": 46,
"Weight": 10,
"BypassesArmor": 0.3,
"SoundRadius": 14,
"RPM": 1200
}

View file

@ -0,0 +1,18 @@
{
"MinZoom": 1.25,
"MaxZoom": 6,
"Spread": 5,
"RecoilX": 0.006,
"RecoilY": 0.014,
"Damage": 12,
"Headshot": 2.5,
"Velocity": 42.5,
"Magazine": 20,
"Weight": 5,
"FireMode": 2,
"NormalReloadTime": 54,
"EmptyReloadTime": 71,
"BypassesArmor": 0.4,
"SoundRadius": 16,
"RPM": 700
}

View file

@ -0,0 +1,18 @@
{
"CustomZoom": 2.25,
"Spread": 4.8,
"RecoilX": 0.002,
"RecoilY": 0.063,
"Damage": 33,
"Headshot": 3,
"Velocity": 42,
"Magazine": 5,
"BoltActionTime": 22,
"Weight": 5,
"PrepareTime": 29,
"PrepareEmptyTime": 16,
"IterativeTime": 11,
"FinishTime": 18,
"BypassesArmor": 0.54,
"SoundRadius": 18
}

View file

@ -0,0 +1,15 @@
{
"Spread": 2.5,
"RecoilX": 0.004,
"RecoilY": 0.013,
"Damage": 5.5,
"Headshot": 1.5,
"Velocity": 17,
"Magazine": 17,
"Weight": 1,
"NormalReloadTime": 44,
"EmptyReloadTime": 47,
"BypassesArmor": 0.15,
"SoundRadius": 8,
"RPM": 400
}

View file

@ -0,0 +1,17 @@
{
"MinZoom": 1.25,
"MaxZoom": 6,
"Spread": 8,
"RecoilX": 0.01,
"RecoilY": 0.038,
"Damage": 140,
"Headshot": 3,
"Velocity": 36,
"Magazine": 3,
"BoltActionTime": 37,
"Weight": 13,
"NormalReloadTime": 63,
"EmptyReloadTime": 92,
"BypassesArmor": 1,
"SoundRadius": 22
}

View file

@ -0,0 +1,18 @@
{
"MinZoom": 4,
"MaxZoom": 8,
"Spread": 3.7,
"RecoilX": 0.0013,
"RecoilY": 0.009,
"Damage": 8.25,
"Headshot": 2,
"Velocity": 46,
"Magazine": 30,
"Weight": 4,
"FireMode": 2,
"NormalReloadTime": 60,
"EmptyReloadTime": 74,
"BypassesArmor": 0.28,
"SoundRadius": 13,
"RPM": 650
}

View file

@ -0,0 +1,10 @@
{
"Spread": 5,
"RecoilX": 0.008,
"RecoilY": 0.018,
"Damage": 270,
"Velocity": 4,
"Magazine": 1,
"Weight": 7,
"EmptyReloadTime": 103
}

View file

@ -0,0 +1,16 @@
{
"Spread": 5.5,
"RecoilX": 0.0018,
"RecoilY": 0.012,
"Damage": 8.75,
"Headshot": 2,
"Velocity": 38,
"Magazine": 75,
"Weight": 6,
"FireMode": 2,
"NormalReloadTime": 73,
"EmptyReloadTime": 95,
"BypassesArmor": 0.23,
"SoundRadius": 14,
"RPM": 600
}

View file

@ -0,0 +1,15 @@
{
"Spread": 1.5,
"RecoilX": 0.004,
"RecoilY": 0.023,
"Damage": 30,
"ExplosionDamage": 50,
"ExplosionRadius": 5,
"Velocity": 3.75,
"Magazine": 8,
"Weight": 9,
"PrepareLoadTime": 31,
"IterativeTime": 20,
"FinishTime": 19,
"SoundRadius": 8
}

View file

@ -0,0 +1,16 @@
{
"CustomZoom": 1.75,
"Spread": 6,
"RecoilX": 0.007,
"RecoilY": 0.018,
"Damage": 35,
"Magazine": 5,
"Headshot": 3,
"Velocity": 70,
"BoltActionTime": 22,
"Weight": 7,
"NormalReloadTime": 59,
"EmptyReloadTime": 89,
"BypassesArmor": 0.8,
"SoundRadius": 20
}

View file

@ -0,0 +1,15 @@
{
"Spread": 4.5,
"RecoilX": 0.004,
"RecoilY": 0.015,
"Damage": 9.5,
"Headshot": 2,
"Velocity": 36,
"Magazine": 20,
"Weight": 4,
"NormalReloadTime": 54,
"EmptyReloadTime": 75,
"BypassesArmor": 0.23,
"SoundRadius": 16,
"RPM": 400
}

View file

@ -0,0 +1,17 @@
{
"MinZoom": 4,
"MaxZoom": 8,
"Spread": 5.5,
"RecoilX": 0.004,
"RecoilY": 0.009,
"Damage": 18,
"Headshot": 2.5,
"Velocity": 42,
"Magazine": 10,
"Weight": 5,
"NormalReloadTime": 59,
"EmptyReloadTime": 78,
"BypassesArmor": 0.45,
"SoundRadius": 17,
"RPM": 300
}

View file

@ -0,0 +1,10 @@
{
"Spread": 2,
"RecoilX": 0.0001,
"RecoilY": 0.002,
"Damage": 5,
"Velocity": 3,
"Magazine": 1,
"Weight": 1,
"EmptyReloadTime": 58
}

View file

@ -0,0 +1,14 @@
{
"Spread": 3,
"RecoilX": 0.005,
"RecoilY": 0.032,
"Damage": 19,
"Headshot": 2,
"Velocity": 24,
"Magazine": 6,
"Weight": 2,
"EmptyReloadTime": 65,
"BypassesArmor": 0.3,
"SoundRadius": 10,
"RPM": 240
}

View file

@ -0,0 +1,17 @@
{
"Spread": 2.3,
"RecoilX": 0.002,
"RecoilY": 0.007,
"Damage": 6,
"Headshot": 1.5,
"Velocity": 16,
"Magazine": 13,
"Weight": 3,
"FireMode": 2,
"BurstSize": 3,
"NormalReloadTime": 46,
"EmptyReloadTime": 64,
"BypassesArmor": 0.15,
"SoundRadius": 11,
"RPM": 1200
}