重制M98B

This commit is contained in:
Atsuishio 2025-05-26 00:06:56 +08:00 committed by Light_Quanta
parent 4b46e33b0f
commit 15defc3444
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
19 changed files with 16948 additions and 17208 deletions

View file

@ -1,8 +1,8 @@
package com.atsuishio.superbwarfare.client.model.item;
import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.client.overlay.CrossHairOverlay;
import com.atsuishio.superbwarfare.data.gun.GunData;
import com.atsuishio.superbwarfare.data.gun.value.AttachmentType;
import com.atsuishio.superbwarfare.event.ClientEventHandler;
import com.atsuishio.superbwarfare.item.gun.GunItem;
import com.atsuishio.superbwarfare.item.gun.sniper.M98bItem;
@ -15,8 +15,19 @@ 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 M98bItemModel extends GeoModel<M98bItem> {
public static float fireRotY = 0f;
public static float fireRotZ = 0f;
public static float rotXBipod = 0f;
public static float rotXSight = 0f;
public static float posYAlt = 0.5625f;
public static float scaleZAlt = 0.88f;
public static float posZAlt = 7.6f;
@Override
public ResourceLocation getAnimationResource(M98bItem animatable) {
return Mod.loc("animations/m_98b.animation.json");
@ -35,56 +46,105 @@ public class M98bItemModel extends GeoModel<M98bItem> {
@Override
public void setCustomAnimations(M98bItem animatable, long instanceId, AnimationState animationState) {
GeoBone gun = getAnimationProcessor().getBone("bone");
GeoBone shen = getAnimationProcessor().getBone("shen");
GeoBone camera = getAnimationProcessor().getBone("camera");
GeoBone main = getAnimationProcessor().getBone("0");
GeoBone scope = getAnimationProcessor().getBone("scope2");
GeoBone scope = getAnimationProcessor().getBone("Scope1");
GeoBone scope2 = getAnimationProcessor().getBone("Scope2");
GeoBone scope3 = getAnimationProcessor().getBone("Scope3");
GeoBone button = getAnimationProcessor().getBone("button");
GeoBone button6 = getAnimationProcessor().getBone("button6");
GeoBone button7 = getAnimationProcessor().getBone("button7");
Player player = Minecraft.getInstance().player;
if (player == null) return;
ItemStack stack = player.getMainHandItem();
if (!(stack.getItem() instanceof GunItem)) return;
var data = GunData.from(stack);
int type = data.attachment.get(AttachmentType.SCOPE);
float times = 0.6f * (float) Math.min(Minecraft.getInstance().getTimer().getRealtimeDeltaTicks(), 0.8);
double zt = ClientEventHandler.zoomTime;
double zp = ClientEventHandler.zoomPos;
double zpz = ClientEventHandler.zoomPosZ;
double fpz = ClientEventHandler.firePosZ * 7 * times;
double fp = ClientEventHandler.firePos;
double fr = ClientEventHandler.fireRot;
shen.setPosX((float) (0.95f * ClientEventHandler.recoilHorizon * fpz * fp));
shen.setPosY((float) (0.4f * fp + 0.44f * fr));
shen.setPosZ((float) (3.325 * fp + 0.34f * fr + 2.35 * fpz));
shen.setRotX((float) (0.01f * fp + 0.15f * fr + 0.01f * fpz));
shen.setRotY((float) (0.1f * ClientEventHandler.recoilHorizon * fpz));
shen.setRotZ((float) ((0.08f + 0.1 * fr) * ClientEventHandler.recoilHorizon));
boolean scopeAlt = data.tag.getBoolean("ScopeAlt");
posYAlt = Mth.lerp(times, posYAlt, scopeAlt ? -0.9f : 0.05f);
scaleZAlt = Mth.lerp(times, scaleZAlt, scopeAlt ? 0.5f : 0.92f);
posZAlt = Mth.lerp(times, posZAlt, scopeAlt ? 2.5f : 5.5f);
shen.setPosX((float) (shen.getPosX() * (1 - 0.4 * zt)));
shen.setPosY((float) (shen.getPosY() * (1 - 0.5 * zt)));
shen.setPosZ((float) (shen.getPosZ() * (1 - 0.6 * zt)));
shen.setRotX((float) (shen.getRotX() * (1 - 0.87 * zt)));
shen.setRotY((float) (shen.getRotY() * (1 - 0.7 * zt)));
shen.setRotZ((float) (shen.getRotZ() * (1 - 0.65 * zt)));
float posY = switch (type) {
case 0 -> 0.07f;
case 1 -> 0.008f;
case 2 -> posYAlt;
case 3 -> -0.2f;
default -> 0f;
};
float scaleZ = switch (type) {
case 0, 1 -> 0.5f;
case 2 -> scaleZAlt;
case 3 -> 0.891f;
default -> 0f;
};
float posZ = switch (type) {
case 0, 1 -> 2.5f;
case 2 -> posZAlt;
case 3 -> 6f;
default -> 0f;
};
CrossHairOverlay.gunRot = shen.getRotZ();
scope.setPosZ(75.2f * (float) (fp + 0.54f * fr));
shen.setPosX(0.2f * (float) (ClientEventHandler.recoilHorizon * (0.5 + 0.4 * ClientEventHandler.fireSpread)));
gun.setPosX(2.245f * (float) zp);
gun.setPosY(0.3f * (float) zp - (float) (0.2f * zpz));
gun.setPosZ(4.2f * (float) zp + (float) (0.3f * zpz));
gun.setPosX(2.3f * (float) zp);
gun.setPosY(posY * (float) zp - (float) (0.2f * zpz));
gun.setPosZ(posZ * (float) zp + (float) (0.3f * zpz));
gun.setScaleZ(1f - (scaleZ * (float) zp));
gun.setRotZ((float) (0.02f * zpz));
scope.setScaleZ(1f - (0.6f * (float) zp));
scope2.setScaleZ(1f - ((scaleZAlt - 0.3f) * (float) zp));
scope3.setScaleZ(1f - (0.2f * (float) zp));
button.setScaleY(1f - (0.85f * (float) zp));
button6.setScaleX(1f - (0.8f * (float) zp));
button7.setScaleX(1f - (0.8f * (float) zp));
ClientEventHandler.gunRootMove(getAnimationProcessor());
float numR = (float) (1 - 0.88 * zt);
GeoBone shen = getAnimationProcessor().getBone("fire");
fireRotY = (float) Mth.lerp(0.3f * times, fireRotY, 0.2f * ClientEventHandler.recoilHorizon * fpz);
fireRotZ = (float) Mth.lerp(2f * times, fireRotZ, (0.4f + 0.5 * fpz) * ClientEventHandler.recoilHorizon);
shen.setPosX(-0.4f * (float) (ClientEventHandler.recoilHorizon * (0.5 + 0.4 * ClientEventHandler.fireSpread)));
shen.setPosY((float) (0.4f * fp + 0.44f * fr));
shen.setPosZ((float) (2.825 * fp + 0.24f * fr + 1.25 * fpz));
shen.setRotX((float) (0.01f * fp + 0.08f * fr + 0.01f * fpz));
shen.setRotY(fireRotY);
shen.setRotZ(fireRotZ);
shen.setPosX((float) (shen.getPosX() * (1 - 0.4 * zt)));
shen.setPosY((float) (shen.getPosY() * (-1 + 0.8 * zt)));
shen.setPosZ((float) (shen.getPosZ() * (1 - 0.2 * zt)));
shen.setRotX((float) (shen.getRotX() * (1 - 0.8 * zt)));
shen.setRotY((float) (shen.getRotY() * (1 - 0.85 * zt)));
shen.setRotZ((float) (shen.getRotZ() * (1 - 0.4 * zt)));
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 sight1fold = getAnimationProcessor().getBone("SightFold1");
GeoBone sight2fold = getAnimationProcessor().getBone("SightFold2");
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);
float numR = (float) (1 - 0.9 * zt);
float numP = (float) (1 - 0.68 * zt);
var data = GunData.from(stack);
if (data.reload.time() > 0) {
if (data.reload.time() > 0 || data.bolt.actionTimer.get() > 0) {
main.setRotX(numR * main.getRotX());
main.setRotY(numR * main.getRotY());
main.setRotZ(numR * main.getRotZ());
@ -94,13 +154,6 @@ public class M98bItemModel extends GeoModel<M98bItem> {
camera.setRotX(numR * camera.getRotX());
camera.setRotY(numR * camera.getRotY());
camera.setRotZ(numR * camera.getRotZ());
scope.setRotX(numR * scope.getRotX());
scope.setRotY(numR * scope.getRotY());
scope.setRotZ(numR * scope.getRotZ());
scope.setPosX(numP * scope.getPosX());
scope.setPosY(numP * scope.getPosY());
scope.setPosZ(numP * scope.getPosZ());
}
ClientEventHandler.handleReloadShake(Mth.RAD_TO_DEG * camera.getRotX(), Mth.RAD_TO_DEG * camera.getRotY(), Mth.RAD_TO_DEG * camera.getRotZ());
}

View file

@ -155,11 +155,7 @@ public class Qbz95ItemModel extends GeoModel<Qbz95Item> {
}
GeoBone flare = getAnimationProcessor().getBone("flare");
int BarrelType = data.attachment.get(AttachmentType.BARREL);
if (BarrelType == 1) {
flare.setPosZ(-2);
}
ClientEventHandler.gunRootMove(getAnimationProcessor());

View file

@ -1,8 +1,11 @@
package com.atsuishio.superbwarfare.client.renderer.gun;
import com.atsuishio.superbwarfare.client.AnimationHelper;
import com.atsuishio.superbwarfare.client.ItemModelHelper;
import com.atsuishio.superbwarfare.client.model.item.M98bItemModel;
import com.atsuishio.superbwarfare.client.renderer.CustomGunRenderer;
import com.atsuishio.superbwarfare.data.gun.GunData;
import com.atsuishio.superbwarfare.data.gun.value.AttachmentType;
import com.atsuishio.superbwarfare.event.ClientEventHandler;
import com.atsuishio.superbwarfare.item.gun.GunItem;
import com.atsuishio.superbwarfare.item.gun.sniper.M98bItem;
@ -37,15 +40,37 @@ public class M98bItemRenderer extends CustomGunRenderer<M98bItem> {
ItemStack itemStack = player.getMainHandItem();
if (!(itemStack.getItem() instanceof GunItem)) return;
var data = GunData.from(itemStack);
int scopeType = data.attachment.get(AttachmentType.SCOPE);
if (data.attachment.get(AttachmentType.SCOPE) == 2 && !data.tag.getBoolean("ScopeAlt") && (bone.getName().endsWith("_hide"))) {
bone.setHidden(ClientEventHandler.zoomPos > 0.7 && ClientEventHandler.zoom);
}
if (data.attachment.get(AttachmentType.SCOPE) == 3 && (bone.getName().endsWith("_hide3"))) {
bone.setHidden(ClientEventHandler.zoomPos > 0.7 && ClientEventHandler.zoom);
}
switch (scopeType) {
case 1 ->
AnimationHelper.handleZoomCrossHair(currentBuffer, renderType, name, stack, bone, buffer, 0, 0.275, 30, 1.2f, 255, 0, 0, 255, "dot", false);
case 2 -> {
if (data.tag.getBoolean("ScopeAlt")) {
AnimationHelper.handleZoomCrossHair(currentBuffer, renderType, name, stack, bone, buffer, 0, 0.34, 30, 0.18f, 255, 0, 0, 255, "delta", false);
} else {
AnimationHelper.handleZoomCrossHair(currentBuffer, renderType, name, stack, bone, buffer, 0, 0.294, 13, 0.75f, 255, 0, 0, 255, "hamr", true);
}
}
case 3 ->
AnimationHelper.handleZoomCrossHair(currentBuffer, renderType, name, stack, bone, buffer, 0, 0.29, 27, 5f, 255, 0, 0, 255, "sniper", true);
}
AnimationHelper.handleShootFlare(name, stack, itemStack, bone, buffer, packedLightIn, 0, 0, 2.15625, 0.6);
ItemModelHelper.handleGunAttachments(bone, itemStack, name);
if (name.equals("scope2")) {
bone.setHidden(ClientEventHandler.zoomPos < 0.7 || !ClientEventHandler.zoom);
}
if (name.equals("qiang")) {
bone.setHidden(ClientEventHandler.zoomPos > 0.7);
}
// if (name.equals("ironSight")) {
// bone.setHidden(GunData.from(itemStack).attachment.get(AttachmentType.SCOPE) != 0);
// }
if (renderingArms) {
AnimationHelper.renderArms(player, this.transformType, stack, name, bone, this.currentBuffer, type, packedLightIn, true);

View file

@ -70,7 +70,7 @@ public class Qbz95ItemRenderer extends CustomGunRenderer<Qbz95Item> {
case 2 ->
AnimationHelper.handleZoomCrossHair(currentBuffer, renderType, name, stack, bone, buffer, 0, 0.55, 24, 1, 255, 0, 0, 255, "dot", false);
case 3 ->
AnimationHelper.handleZoomCrossHair(currentBuffer, renderType, name, stack, bone, buffer, 0, 0.55, 36, (float) ClientEventHandler.customZoom, 255, 0, 0, 255, "sniper", true);
AnimationHelper.handleZoomCrossHair(currentBuffer, renderType, name, stack, bone, buffer, 0, 0.55, 36, 4, 255, 0, 0, 255, "sniper", true);
}
AnimationHelper.handleShootFlare(name, stack, itemStack, bone, buffer, packedLightIn, 0, 0.02, 1.12375, 0.3);

View file

@ -58,7 +58,7 @@ public class SvdItemRenderer extends CustomGunRenderer<SvdItem> {
case 2 ->
AnimationHelper.handleZoomCrossHair(currentBuffer, renderType, name, stack, bone, buffer, -0.01, 0.24, 18, 1, 255, 0, 0, 255, "pso_1", true);
case 3 ->
AnimationHelper.handleZoomCrossHair(currentBuffer, renderType, name, stack, bone, buffer, 0, 0.2525, -0.1, 0.08f, 255, 0, 0, 255, "sniper", true);
AnimationHelper.handleZoomCrossHair(currentBuffer, renderType, name, stack, bone, buffer, 0, 0.2525, -0.1, 0.1f, 255, 0, 0, 255, "sniper", true);
}

View file

@ -234,6 +234,8 @@ public class ModSounds {
public static final DeferredHolder<SoundEvent, SoundEvent> M_98B_FIRE_1P = REGISTRY.register("m_98b_fire_1p", () -> SoundEvent.createVariableRangeEvent(Mod.loc("m_98b_fire_1p")));
public static final DeferredHolder<SoundEvent, SoundEvent> M_98B_FIRE_3P = REGISTRY.register("m_98b_fire_3p", () -> SoundEvent.createVariableRangeEvent(Mod.loc("m_98b_fire_3p")));
public static final DeferredHolder<SoundEvent, SoundEvent> M_98B_FIRE_1P_S = REGISTRY.register("m_98b_fire_1p_s", () -> SoundEvent.createVariableRangeEvent(Mod.loc("m_98b_fire_1p_s")));
public static final DeferredHolder<SoundEvent, SoundEvent> M_98B_FIRE_3P_S = REGISTRY.register("m_98b_fire_3p_s", () -> SoundEvent.createVariableRangeEvent(Mod.loc("m_98b_fire_3p_s")));
public static final DeferredHolder<SoundEvent, SoundEvent> M_98B_FAR = REGISTRY.register("m_98b_far", () -> SoundEvent.createVariableRangeEvent(Mod.loc("m_98b_far")));
public static final DeferredHolder<SoundEvent, SoundEvent> M_98B_VERYFAR = REGISTRY.register("m_98b_veryfar", () -> SoundEvent.createVariableRangeEvent(Mod.loc("m_98b_veryfar")));
public static final DeferredHolder<SoundEvent, SoundEvent> M_98B_RELOAD_NORMAL = REGISTRY.register("m_98b_reload_normal", () -> SoundEvent.createVariableRangeEvent(Mod.loc("m_98b_reload_normal")));

View file

@ -88,15 +88,9 @@ public class Ntw20Item extends GunItem implements GeoItem {
}
private PlayState editPredicate(AnimationState<Ntw20Item> event) {
LocalPlayer player = Minecraft.getInstance().player;
if (player == null) return PlayState.STOP;
ItemStack stack = player.getMainHandItem();
if (!(stack.getItem() instanceof GunItem)) return PlayState.STOP;
if (ClickHandler.isEditing) {
return event.setAndContinue(RawAnimation.begin().thenPlay("animation.ntw_20.edit"));
}
return event.setAndContinue(RawAnimation.begin().thenLoop("animation.ntw_20.idle"));
}

View file

@ -1,24 +1,31 @@
package com.atsuishio.superbwarfare.item.gun.sniper;
import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.client.ClickHandler;
import com.atsuishio.superbwarfare.client.renderer.gun.M98bItemRenderer;
import com.atsuishio.superbwarfare.data.gun.GunData;
import com.atsuishio.superbwarfare.data.gun.value.AttachmentType;
import com.atsuishio.superbwarfare.event.ClientEventHandler;
import com.atsuishio.superbwarfare.init.ModSounds;
import com.atsuishio.superbwarfare.item.gun.GunItem;
import com.atsuishio.superbwarfare.tools.GunsTool;
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.entity.Entity;
import net.minecraft.world.item.Item;
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;
import java.util.function.Supplier;
@ -77,12 +84,21 @@ public class M98bItem extends GunItem implements GeoItem {
return event.setAndContinue(RawAnimation.begin().thenLoop("animation.m_98b.idle"));
}
private PlayState editPredicate(AnimationState<M98bItem> event) {
if (ClickHandler.isEditing) {
return event.setAndContinue(RawAnimation.begin().thenPlay("animation.m_98b.edit"));
}
return event.setAndContinue(RawAnimation.begin().thenLoop("animation.m_98b.idle"));
}
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar data) {
var fireAnimController = new AnimationController<>(this, "fireAnimController", 1, this::fireAnimPredicate);
data.add(fireAnimController);
var idleController = new AnimationController<>(this, "idleController", 3, this::idlePredicate);
var idleController = new AnimationController<>(this, "idleController", 6, this::idlePredicate);
data.add(idleController);
var editController = new AnimationController<>(this, "editController", 1, this::editPredicate);
data.add(editController);
}
@Override
@ -105,11 +121,74 @@ public class M98bItem extends GunItem implements GeoItem {
return "M98-B";
}
@Override
@ParametersAreNonnullByDefault
public void inventoryTick(ItemStack stack, Level world, Entity entity, int slot, boolean selected) {
super.inventoryTick(stack, world, entity, slot, selected);
int magType = GunData.from(stack).attachment.get(AttachmentType.MAGAZINE);
if (magType == 2) {
CompoundTag tag = GunData.from(stack).attachment();
tag.putInt("Magazine", 0);
}
}
@Override
public boolean canSwitchScope(ItemStack stack) {
return GunData.from(stack).attachment.get(AttachmentType.SCOPE) == 2;
}
@Override
public int getCustomMagazine(ItemStack stack) {
int magType = GunData.from(stack).attachment.get(AttachmentType.MAGAZINE);
return magType == 1 ? 5 : 0;
}
@Override
public double getCustomZoom(ItemStack stack) {
var data = GunData.from(stack);
int scopeType = data.attachment.get(AttachmentType.SCOPE);
return switch (scopeType) {
case 2 -> data.tag.getBoolean("ScopeAlt") ? 0 : 2.75;
case 3 -> GunsTool.getGunDoubleTag(data.tag, "CustomZoom");
default -> 0;
};
}
@Override
public boolean canAdjustZoom(ItemStack stack) {
return GunData.from(stack).attachment.get(AttachmentType.SCOPE) == 3;
}
@Override
public boolean isCustomizable(ItemStack stack) {
return true;
}
@Override
public boolean hasCustomBarrel(ItemStack stack) {
return true;
}
@Override
public boolean hasCustomScope(ItemStack stack) {
return true;
}
@Override
public boolean hasCustomMagazine(ItemStack stack) {
return true;
}
@Override
public boolean isOpenBolt(ItemStack stack) {
return true;
}
public boolean hasBipod(ItemStack stack) {
return true;
}
@Override
public boolean hasBulletInBarrel(ItemStack stack) {
return true;

File diff suppressed because it is too large Load diff

View file

@ -1191,6 +1191,22 @@
}
]
},
"m_98b_fire_1p_s": {
"sounds": [
{
"name": "superbwarfare:m_98b/m_98b_fire_1p_s",
"stream": false
}
]
},
"m_98b_fire_3p_s": {
"sounds": [
{
"name": "superbwarfare:m_98b/m_98b_fire_3p_s",
"stream": false
}
]
},
"m_98b_far": {
"sounds": [
{

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View file

@ -1,6 +1,5 @@
{
"ID": "superbwarfare:m_98b",
"DefaultZoom": 6,
"MinZoom": 4,
"MaxZoom": 8,
"Spread": 6,
@ -10,10 +9,10 @@
"Headshot": 3,
"Velocity": 47.2,
"Magazine": 5,
"BoltActionTime": 18,
"BoltActionTime": 24,
"Weight": 7,
"NormalReloadTime": 60,
"EmptyReloadTime": 78,
"NormalReloadTime": 62,
"EmptyReloadTime": 80,
"BypassesArmor": 0.6,
"SoundRadius": 18,
"AmmoType": "@SniperAmmo",

View file

@ -2,10 +2,10 @@
"type": "patchouli:shapeless_book_recipe",
"ingredients": [
{
"item": "minecraft:book"
"id": "minecraft:book"
},
{
"item": "superbwarfare:empty_perk"
"id": "superbwarfare:empty_perk"
}
],
"book": "superbwarfare:superb_warfare_manual"