diff --git a/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java b/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java index f5cdf8cfc..741da2fef 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java @@ -84,7 +84,7 @@ public class ClickHandler { } private static boolean cancelFireKey(Player player, ItemStack stack) { - return stack.getItem() instanceof GunItem || stack.is(ModItems.MONITOR.get()) || stack.is(ModItems.LUNGE_MINE.get()) || player.hasEffect(ModMobEffects.SHOCK) + return stack.getItem() instanceof GunItem || stack.is(ModItems.MONITOR.get()) || stack.is(ModItems.LUNGE_MINE.get()) || stack.is(ModItems.CANNON_MONITOR.get()) || player.hasEffect(ModMobEffects.SHOCK) || (player.getVehicle() instanceof ArmedVehicleEntity iArmedVehicle && iArmedVehicle.banHand(player)); } @@ -135,7 +135,9 @@ public class ClickHandler { || stack.is(ModItems.MONITOR.get()) || stack.is(ModItems.LUNGE_MINE.get()) || (player.getVehicle() instanceof ArmedVehicleEntity) - || (stack.is(Items.SPYGLASS) && player.isScoping() && player.getOffhandItem().is(ModItems.FIRING_PARAMETERS.get()))) { + || (stack.is(Items.SPYGLASS) && player.isScoping() && player.getOffhandItem().is(ModItems.FIRING_PARAMETERS.get())) + || (stack.is(ModItems.CANNON_MONITOR.get())) + ) { if (button == ModKeyMappings.FIRE.getKey().getValue()) { handleWeaponFirePress(player, stack); } @@ -307,7 +309,9 @@ public class ClickHandler { if (stack.getItem() instanceof GunItem || stack.is(ModItems.MONITOR.get()) || (player.getVehicle() instanceof ArmedVehicleEntity iVehicle && iVehicle.isDriver(player)) - || (stack.is(Items.SPYGLASS) && player.isScoping() && player.getOffhandItem().is(ModItems.FIRING_PARAMETERS.get()))) { + || (stack.is(Items.SPYGLASS) && player.isScoping() && player.getOffhandItem().is(ModItems.FIRING_PARAMETERS.get())) + || (stack.is(ModItems.CANNON_MONITOR.get())) + ) { if (key == ModKeyMappings.FIRE.getKey().getValue()) { handleWeaponFirePress(player, stack); } @@ -351,6 +355,10 @@ public class ClickHandler { isEditing = false; if (player.hasEffect(ModMobEffects.SHOCK)) return; + if (stack.is(ModItems.CANNON_MONITOR.get())) { + PacketDistributor.sendToServer(new SetFiringParametersMessage(0)); + } + if (stack.is(Items.SPYGLASS) && player.isScoping() && player.getOffhandItem().is(ModItems.FIRING_PARAMETERS.get())) { PacketDistributor.sendToServer(new SetFiringParametersMessage(0)); } diff --git a/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/MortarRenderer.java b/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/MortarRenderer.java index 7d1abaca6..04c50aa79 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/MortarRenderer.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/MortarRenderer.java @@ -11,9 +11,13 @@ import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; +import org.jetbrains.annotations.NotNull; import software.bernie.geckolib.cache.object.BakedGeoModel; +import software.bernie.geckolib.cache.object.GeoBone; import software.bernie.geckolib.renderer.GeoEntityRenderer; +import static com.atsuishio.superbwarfare.entity.vehicle.MortarEntity.INTELLIGENT; + public class MortarRenderer extends GeoEntityRenderer { public MortarRenderer(EntityRendererProvider.Context renderManager) { @@ -36,7 +40,7 @@ public class MortarRenderer extends GeoEntityRenderer { } @Override - public void render(MortarEntity entityIn, float entityYaw, float partialTicks, PoseStack poseStack, MultiBufferSource bufferIn, int packedLightIn) { + public void render(MortarEntity entityIn, float entityYaw, float partialTicks, PoseStack poseStack, @NotNull MultiBufferSource bufferIn, int packedLightIn) { poseStack.pushPose(); poseStack.mulPose(Axis.YP.rotationDegrees(-Mth.lerp(partialTicks, entityIn.yRotO, entityIn.getYRot()))); super.render(entityIn, entityYaw, partialTicks, poseStack, bufferIn, packedLightIn); @@ -44,8 +48,13 @@ public class MortarRenderer extends GeoEntityRenderer { } @Override - protected float getDeathMaxRotation(MortarEntity entityLivingBaseIn) { - return 0.0F; + public void renderRecursively(PoseStack poseStack, MortarEntity animatable, GeoBone bone, RenderType renderType, MultiBufferSource bufferSource, VertexConsumer buffer, boolean isReRender, float partialTick, int packedLight, int packedOverlay, int color) { + String name = bone.getName(); + + if (name.equals("monitor")) { + bone.setHidden(!animatable.getEntityData().get(INTELLIGENT)); + } + super.renderRecursively(poseStack, animatable, bone, renderType, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, color); } @Override diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/MortarEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/MortarEntity.java index e42c8bde5..060d12459 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/MortarEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/MortarEntity.java @@ -6,7 +6,10 @@ import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; import com.atsuishio.superbwarfare.init.ModEntities; import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.init.ModSounds; +import com.atsuishio.superbwarfare.item.CannonMonitor; +import com.atsuishio.superbwarfare.item.Monitor; import com.atsuishio.superbwarfare.item.common.ammo.MortarShell; +import com.atsuishio.superbwarfare.tools.NBTTool; import net.minecraft.ChatFormatting; import net.minecraft.commands.arguments.EntityAnchorArgument; import net.minecraft.core.particles.ParticleTypes; @@ -16,6 +19,9 @@ import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.players.OldUsersConverter; +import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.util.Mth; import net.minecraft.world.Container; @@ -24,6 +30,7 @@ import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.MoverType; +import net.minecraft.world.entity.OwnableEntity; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; @@ -38,13 +45,18 @@ import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; import software.bernie.geckolib.animation.*; import software.bernie.geckolib.util.GeckoLibUtil; +import java.util.Optional; +import java.util.UUID; + import static com.atsuishio.superbwarfare.tools.RangeTool.calculateLaunchVector; -public class MortarEntity extends VehicleEntity implements GeoEntity, Container { +public class MortarEntity extends VehicleEntity implements GeoEntity, Container, OwnableEntity { public static final EntityDataAccessor FIRE_TIME = SynchedEntityData.defineId(MortarEntity.class, EntityDataSerializers.INT); public static final EntityDataAccessor PITCH = SynchedEntityData.defineId(MortarEntity.class, EntityDataSerializers.FLOAT); public static final EntityDataAccessor YAW = SynchedEntityData.defineId(MortarEntity.class, EntityDataSerializers.FLOAT); + public static final EntityDataAccessor INTELLIGENT = SynchedEntityData.defineId(MortarEntity.class, EntityDataSerializers.BOOLEAN); + public static final EntityDataAccessor> OWNER_UUID = SynchedEntityData.defineId(MortarEntity.class, EntityDataSerializers.OPTIONAL_UUID); private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); @@ -68,7 +80,9 @@ public class MortarEntity extends VehicleEntity implements GeoEntity, Container super.defineSynchedData(builder); builder.define(FIRE_TIME, 0) .define(PITCH, -70f) - .define(YAW, this.getYRot()); + .define(YAW, this.getYRot()) + .define(INTELLIGENT, false) + .define(OWNER_UUID, Optional.empty()); } @Override @@ -81,6 +95,10 @@ public class MortarEntity extends VehicleEntity implements GeoEntity, Container super.addAdditionalSaveData(compound); compound.putFloat("Pitch", this.entityData.get(PITCH)); compound.putFloat("Yaw", this.entityData.get(YAW)); + compound.putBoolean("Intelligent", this.entityData.get(INTELLIGENT)); + if (this.getOwnerUUID() != null) { + compound.putUUID("Owner", this.getOwnerUUID()); + } } @Override @@ -92,11 +110,40 @@ public class MortarEntity extends VehicleEntity implements GeoEntity, Container if (compound.contains("Yaw")) { this.entityData.set(YAW, compound.getFloat("Yaw")); } + if (compound.contains("Intelligent")) { + this.entityData.set(INTELLIGENT, compound.getBoolean("Intelligent")); + } + UUID uuid; + if (compound.hasUUID("Owner")) { + uuid = compound.getUUID("Owner"); + } else { + String s = compound.getString("Owner"); + + assert this.getServer() != null; + uuid = OldUsersConverter.convertMobOwnerIfNecessary(this.getServer(), s); + } + + if (uuid != null) { + try { + this.setOwnerUUID(uuid); + } catch (Throwable ignored) { + } + } } + public void setOwnerUUID(@Nullable UUID pUuid) { + this.entityData.set(OWNER_UUID, Optional.ofNullable(pUuid)); + } + + @Nullable + public UUID getOwnerUUID() { + return this.entityData.get(OWNER_UUID).orElse(null); + } + + private LivingEntity shooter = null; - private void fire(@Nullable LivingEntity shooter) { + public void fire(@Nullable LivingEntity shooter) { if (!(this.stack.getItem() instanceof MortarShell)) return; this.shooter = shooter; @@ -113,6 +160,25 @@ public class MortarEntity extends VehicleEntity implements GeoEntity, Container public @NotNull InteractionResult interact(Player player, @NotNull InteractionHand hand) { ItemStack mainHandItem = player.getMainHandItem(); + if (mainHandItem.getItem() instanceof CannonMonitor && player == getOwner() && this.entityData.get(INTELLIGENT)) { + var tag = NBTTool.getTag(mainHandItem); + tag.putString("LinkedCannon", getStringUUID()); + NBTTool.saveTag(mainHandItem, tag); + + if (player instanceof ServerPlayer serverPlayer) { + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), SoundEvents.ARROW_HIT_PLAYER, SoundSource.PLAYERS, 0.5F, 1); + } + return InteractionResult.SUCCESS; + } + + if (mainHandItem.getItem() instanceof Monitor && player.isShiftKeyDown() && !this.entityData.get(INTELLIGENT)) { + setOwnerUUID(player.getUUID()); + entityData.set(INTELLIGENT, true); + if (!player.isCreative()) { + mainHandItem.shrink(1); + } + } + if (mainHandItem.getItem() instanceof MortarShell && !player.isShiftKeyDown() && this.entityData.get(FIRE_TIME) == 0) { this.stack = mainHandItem.copyWithCount(1); if (!player.isCreative()) { @@ -285,7 +351,7 @@ public class MortarEntity extends VehicleEntity implements GeoEntity, Container return this.cache; } - private ItemStack stack = ItemStack.EMPTY; + public ItemStack stack = ItemStack.EMPTY; @Override public int getContainerSize() { @@ -332,7 +398,9 @@ public class MortarEntity extends VehicleEntity implements GeoEntity, Container @Override public void setChanged() { - fire(null); + if (!entityData.get(INTELLIGENT)) { + fire(null); + } } @Override diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModItems.java b/src/main/java/com/atsuishio/superbwarfare/init/ModItems.java index cd5d16dd3..10181a567 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModItems.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModItems.java @@ -142,6 +142,7 @@ public class ModItems { public static final DeferredHolder DRONE = ITEMS.register("drone", Drone::new); public static final DeferredHolder MONITOR = ITEMS.register("monitor", Monitor::new); + public static final DeferredHolder CANNON_MONITOR = ITEMS.register("cannon_monitor", CannonMonitor::new); public static final DeferredHolder DETONATOR = ITEMS.register("detonator", Detonator::new); public static final DeferredHolder TARGET_DEPLOYER = ITEMS.register("target_deployer", TargetDeployer::new); diff --git a/src/main/java/com/atsuishio/superbwarfare/item/CannonMonitor.java b/src/main/java/com/atsuishio/superbwarfare/item/CannonMonitor.java new file mode 100644 index 000000000..ef6c92abf --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/item/CannonMonitor.java @@ -0,0 +1,61 @@ +package com.atsuishio.superbwarfare.item; + +import net.minecraft.world.item.Item; + +public class CannonMonitor extends Item { + + public CannonMonitor() { + super(new Properties().stacksTo(1)); + } + +// @Override +// public @NotNull InteractionResult useOn(UseOnContext pContext) { +// ItemStack stack = pContext.getItemInHand(); +// BlockPos pos = pContext.getClickedPos(); +// pos = pos.relative(pContext.getClickedFace()); +// Player player = pContext.getPlayer(); +// if (player == null) return InteractionResult.PASS; +// +// if (player.isShiftKeyDown()) { +// stack.getOrCreateTag().putDouble("TargetX", pos.getX()); +// stack.getOrCreateTag().putDouble("TargetY", pos.getY()); +// stack.getOrCreateTag().putDouble("TargetZ", pos.getZ()); +// } +// +// return InteractionResult.SUCCESS; +// } + +// @Override +// @ParametersAreNonnullByDefault +// public @NotNull InteractionResultHolder use(Level level, Player player, InteractionHand usedHand) { +// if (!player.isCrouching()) return InteractionResultHolder.pass(player.getItemInHand(usedHand)); +// +// var stack = player.getItemInHand(usedHand); +// var isDepressed = !stack.getOrCreateTag().getBoolean("IsDepressed"); +// +// stack.getOrCreateTag().putBoolean("IsDepressed", isDepressed); +// +// player.displayClientMessage(Component.translatable( +// isDepressed +// ? "tips.superbwarfare.mortar.target_pos.depressed_trajectory" +// : "tips.superbwarfare.mortar.target_pos.lofted_trajectory" +// ).withStyle(ChatFormatting.GREEN), true); +// +// return InteractionResultHolder.success(stack); +// } +// +// @Override +// public void appendHoverText(ItemStack pStack, @Nullable Level pLevel, List pTooltipComponents, TooltipFlag pIsAdvanced) { +// pTooltipComponents.add(Component.translatable("tips.superbwarfare.mortar.target_pos").withStyle(ChatFormatting.GRAY) +// .append(Component.literal("[" + pStack.getOrCreateTag().getInt("TargetX") +// + "," + pStack.getOrCreateTag().getInt("TargetY") +// + "," + pStack.getOrCreateTag().getInt("TargetZ") + "]"))); +// +// +// pTooltipComponents.add(Component.translatable( +// pStack.getOrCreateTag().getBoolean("IsDepressed") +// ? "tips.superbwarfare.mortar.target_pos.depressed_trajectory" +// : "tips.superbwarfare.mortar.target_pos.lofted_trajectory" +// ).withStyle(ChatFormatting.GRAY)); +// } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/SetFiringParametersMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/SetFiringParametersMessage.java index a3387cfe0..b9379a765 100644 --- a/src/main/java/com/atsuishio/superbwarfare/network/message/send/SetFiringParametersMessage.java +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/SetFiringParametersMessage.java @@ -2,7 +2,12 @@ package com.atsuishio.superbwarfare.network.message.send; import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.component.ModDataComponents; +import com.atsuishio.superbwarfare.entity.vehicle.MortarEntity; +import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.item.FiringParameters; +import com.atsuishio.superbwarfare.item.common.ammo.MortarShell; +import com.atsuishio.superbwarfare.tools.EntityFindUtil; +import com.atsuishio.superbwarfare.tools.NBTTool; import com.atsuishio.superbwarfare.tools.TraceTool; import io.netty.buffer.ByteBuf; import net.minecraft.ChatFormatting; @@ -15,12 +20,17 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.ClipContext; +import net.minecraft.world.level.Level; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import net.neoforged.neoforge.network.handling.IPayloadContext; import org.jetbrains.annotations.NotNull; +import java.util.List; import java.util.Objects; +import java.util.stream.StreamSupport; + +import static com.atsuishio.superbwarfare.entity.vehicle.MortarEntity.FIRE_TIME; public record SetFiringParametersMessage(int msgType) implements CustomPacketPayload { public static final Type TYPE = new Type<>(Mod.loc("set_firing_parameters")); @@ -34,6 +44,7 @@ public record SetFiringParametersMessage(int msgType) implements CustomPacketPay public static void handler(SetFiringParametersMessage message, final IPayloadContext context) { Player player = context.player(); ItemStack stack = player.getOffhandItem(); + ItemStack mainStack = player.getMainHandItem(); boolean lookAtEntity = false; Entity lookingEntity = TraceTool.findLookingEntity(player, 520); @@ -44,28 +55,71 @@ public record SetFiringParametersMessage(int msgType) implements CustomPacketPay if (lookingEntity != null) { lookAtEntity = true; } + if (stack.is(ModItems.FIRING_PARAMETERS.get())) { - var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS); - var isDepressed = parameters != null && parameters.isDepressed(); + var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS); + var isDepressed = parameters != null && parameters.isDepressed(); - if (lookAtEntity) { - stack.set(ModDataComponents.FIRING_PARAMETERS, new FiringParameters.Parameters(lookingEntity.blockPosition(), isDepressed)); - } else { - stack.set(ModDataComponents.FIRING_PARAMETERS, new FiringParameters.Parameters(new BlockPos((int) hitPos.x, (int) hitPos.y, (int) hitPos.z), isDepressed)); + if (lookAtEntity) { + stack.set(ModDataComponents.FIRING_PARAMETERS, new FiringParameters.Parameters(lookingEntity.blockPosition(), isDepressed)); + } else { + stack.set(ModDataComponents.FIRING_PARAMETERS, new FiringParameters.Parameters(new BlockPos((int) hitPos.x, (int) hitPos.y, (int) hitPos.z), isDepressed)); + } + + var pos = Objects.requireNonNull(stack.get(ModDataComponents.FIRING_PARAMETERS)).pos(); + + player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.target_pos") + .withStyle(ChatFormatting.GRAY) + .append(Component.literal("[" + pos.getX() + + "," + pos.getY() + + "," + pos.getZ() + + "]")), true); } - var pos = Objects.requireNonNull(stack.get(ModDataComponents.FIRING_PARAMETERS)).pos(); + if (mainStack.is(ModItems.CANNON_MONITOR.get())) { + // TODO 这数据读写是一坨什么玩意 + BlockPos pos; + if (player.isShiftKeyDown()) { + if (lookAtEntity) { + pos = lookingEntity.blockPosition(); + } else { + pos = new BlockPos((int) hitPos.x, (int) hitPos.y, (int) hitPos.z); + } + mainStack.set(ModDataComponents.FIRING_PARAMETERS, new FiringParameters.Parameters(pos, false)); - player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.target_pos") - .withStyle(ChatFormatting.GRAY) - .append(Component.literal("[" + pos.getX() - + "," + pos.getY() - + "," + pos.getZ() - + "]")), true); + player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.target_pos") + .withStyle(ChatFormatting.GRAY) + .append(Component.literal("[" + pos.getX() + + "," + pos.getY() + + "," + pos.getZ() + + "]")), true); + } + + List entities = getCannon(player, player.level(), NBTTool.getTag(mainStack).getString("LinkedCannon")); + for (var e : entities) { + if (e instanceof MortarEntity mortarEntity) { + if (player.isShiftKeyDown()) { + if (!mortarEntity.setTarget(mainStack)) { + player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.warn").withStyle(ChatFormatting.RED), true); + } + } else { + if (mortarEntity.stack.getItem() instanceof MortarShell && mortarEntity.getEntityData().get(FIRE_TIME) == 0) { + mortarEntity.fire(player); + } + } + } + } + } } @Override public @NotNull Type type() { return TYPE; } + + public static List getCannon(Player player, Level level, String uuid) { + return StreamSupport.stream(EntityFindUtil.getEntities(level).getAll().spliterator(), false) + .filter(e -> e.getStringUUID().equals(uuid)) + .toList(); + } } diff --git a/src/main/resources/assets/superbwarfare/geo/mortar.geo.json b/src/main/resources/assets/superbwarfare/geo/mortar.geo.json index c359b6337..90b9359c7 100644 --- a/src/main/resources/assets/superbwarfare/geo/mortar.geo.json +++ b/src/main/resources/assets/superbwarfare/geo/mortar.geo.json @@ -1102,6 +1102,223 @@ } ] }, + { + "name": "monitor", + "parent": "paotong", + "pivot": [0, 16.92347, 0.00569], + "cubes": [ + { + "origin": [-6.8685, 18.01247, -0.42722], + "size": [5.25, 0.4, 0.85], + "uv": { + "north": {"uv": [48, 2], "uv_size": [4, 0.5]}, + "east": {"uv": [8, 52], "uv_size": [0.5, 0.5]}, + "south": {"uv": [48, 3], "uv_size": [4, 0.5]}, + "west": {"uv": [52, 8], "uv_size": [0.5, 0.5]}, + "up": {"uv": [48, 4], "uv_size": [4, 0.5]}, + "down": {"uv": [5, 48.5], "uv_size": [4, -0.5]} + } + }, + { + "origin": [-6.8685, 15.01247, -0.42722], + "size": [5.25, 0.4, 0.85], + "pivot": [-4.2435, 15.21247, -0.00222], + "rotation": [0, 0, -180], + "uv": { + "north": {"uv": [48, 2], "uv_size": [4, 0.5]}, + "east": {"uv": [8, 52], "uv_size": [0.5, 0.5]}, + "south": {"uv": [48, 3], "uv_size": [4, 0.5]}, + "west": {"uv": [52, 8], "uv_size": [0.5, 0.5]}, + "up": {"uv": [48, 4], "uv_size": [4, 0.5]}, + "down": {"uv": [5, 48.5], "uv_size": [4, -0.5]} + } + }, + { + "origin": [-7.9685, 16.51247, -0.42722], + "size": [2.6, 0.4, 0.85], + "pivot": [-6.6685, 16.71247, -0.00222], + "rotation": [0, 0, -90], + "uv": { + "north": {"uv": [48, 2], "uv_size": [4, 0.5]}, + "east": {"uv": [8, 52], "uv_size": [0.5, 0.5]}, + "south": {"uv": [48, 3], "uv_size": [4, 0.5]}, + "west": {"uv": [52, 8], "uv_size": [0.5, 0.5]}, + "up": {"uv": [48, 4], "uv_size": [4, 0.5]}, + "down": {"uv": [5, 48.5], "uv_size": [4, -0.5]} + } + }, + { + "origin": [-3.1315, 16.51247, -0.42722], + "size": [2.6, 0.4, 0.85], + "pivot": [-1.8315, 16.71247, -0.00222], + "rotation": [0, 0, 90], + "uv": { + "north": {"uv": [52, 2], "uv_size": [-4, 0.5]}, + "east": {"uv": [52.5, 8], "uv_size": [-0.5, 0.5]}, + "south": {"uv": [52, 3], "uv_size": [-4, 0.5]}, + "west": {"uv": [8.5, 52], "uv_size": [-0.5, 0.5]}, + "up": {"uv": [52, 4], "uv_size": [-4, 0.5]}, + "down": {"uv": [9, 48.5], "uv_size": [-4, -0.5]} + } + }, + { + "origin": [-0.56709, 17.18447, -1.36281], + "size": [1.13418, 0.978, 2.737], + "pivot": [0, 17.17347, 0.00569], + "rotation": [0, -90, 0], + "uv": { + "north": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "south": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "up": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]}, + "down": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]} + } + }, + { + "origin": [-0.56709, 17.18447, -1.36281], + "size": [1.13418, 0.978, 2.737], + "pivot": [0, 17.17347, 0.00569], + "rotation": [0, -45, 0], + "uv": { + "north": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "south": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "up": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]}, + "down": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]} + } + }, + { + "origin": [-0.56709, 17.18447, -1.36281], + "size": [1.13418, 0.978, 2.737], + "uv": { + "north": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "south": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "up": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]}, + "down": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]} + } + }, + { + "origin": [-0.56709, 17.18447, -1.36281], + "size": [1.13418, 0.978, 2.737], + "pivot": [0, 17.17347, 0.00569], + "rotation": [0, 45, 0], + "uv": { + "north": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "south": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "up": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]}, + "down": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]} + } + }, + { + "origin": [-0.56709, 15.18447, -1.36281], + "size": [1.13418, 0.978, 2.737], + "pivot": [0, 15.17347, 0.00569], + "rotation": [0, 45, 0], + "uv": { + "north": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "south": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "up": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]}, + "down": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]} + } + }, + { + "origin": [-0.56709, 15.18447, -1.36281], + "size": [1.13418, 0.978, 2.737], + "pivot": [0, 15.17347, 0.00569], + "rotation": [0, -90, 0], + "uv": { + "north": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "south": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "up": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]}, + "down": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]} + } + }, + { + "origin": [-0.31709, 15.18447, 1.37419], + "size": [0.63418, 0.978, 0.5], + "pivot": [0, 15.17347, 0.00569], + "rotation": [0, -90, 0], + "uv": { + "east": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "west": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "up": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]}, + "down": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]} + } + }, + { + "origin": [-4.56059, 15.18447, -2.36931], + "size": [0.63418, 2.978, 4.75], + "pivot": [-4.2435, 16.67347, 0.00569], + "rotation": [0, -90, 0], + "uv": { + "east": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "west": {"uv": [52, 27], "uv_size": [0.5, 0.5]}, + "up": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]}, + "down": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]} + } + }, + { + "origin": [-5.81672, 18.41247, -0.10222], + "size": [0.25, 2.978, 0.25], + "pivot": [-5.69172, 19.90147, 0.02278], + "rotation": [0, -135, 0], + "uv": { + "north": {"uv": [47.5, 8.5], "uv_size": [0.5, 0.5]}, + "east": {"uv": [47.5, 8.5], "uv_size": [0.5, 0.5]}, + "south": {"uv": [47.5, 8.5], "uv_size": [0.5, 0.5]}, + "west": {"uv": [47.5, 8.5], "uv_size": [0.5, 0.5]}, + "up": {"uv": [48, 9], "uv_size": [-0.5, -0.5]}, + "down": {"uv": [48, 9], "uv_size": [-0.5, -0.5]} + } + }, + { + "origin": [-3.06672, 18.41247, -0.10222], + "size": [0.25, 2.978, 0.25], + "pivot": [-2.94172, 19.90147, 0.02278], + "rotation": [0, -135, 0], + "uv": { + "north": {"uv": [47.5, 8.5], "uv_size": [0.5, 0.5]}, + "east": {"uv": [47.5, 8.5], "uv_size": [0.5, 0.5]}, + "south": {"uv": [47.5, 8.5], "uv_size": [0.5, 0.5]}, + "west": {"uv": [47.5, 8.5], "uv_size": [0.5, 0.5]}, + "up": {"uv": [48, 9], "uv_size": [-0.5, -0.5]}, + "down": {"uv": [48, 9], "uv_size": [-0.5, -0.5]} + } + }, + { + "origin": [-0.31709, 17.18447, 1.37419], + "size": [0.63418, 0.978, 0.5], + "pivot": [0, 17.17347, 0.00569], + "rotation": [0, -90, 0], + "uv": { + "east": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "west": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "up": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]}, + "down": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]} + } + }, + { + "origin": [-0.56709, 15.18447, -1.36281], + "size": [1.13418, 0.978, 2.737], + "pivot": [0, 15.17347, 0.00569], + "rotation": [0, -45, 0], + "uv": { + "north": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "south": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "up": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]}, + "down": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]} + } + }, + { + "origin": [-0.56709, 15.18447, -1.36281], + "size": [1.13418, 0.978, 2.737], + "uv": { + "north": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "south": {"uv": [46, 28.5], "uv_size": [0.5, 0.5]}, + "up": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]}, + "down": {"uv": [46.5, 29], "uv_size": [-0.5, -0.5]} + } + } + ] + }, { "name": "jiaojia", "parent": "bone2", diff --git a/src/main/resources/assets/superbwarfare/textures/entity/mortar.png b/src/main/resources/assets/superbwarfare/textures/entity/mortar.png index 2be7f7094..240a58a8b 100644 Binary files a/src/main/resources/assets/superbwarfare/textures/entity/mortar.png and b/src/main/resources/assets/superbwarfare/textures/entity/mortar.png differ