迫击炮添加智能模式,添加火炮遥控器

This commit is contained in:
Atsuishio 2025-07-08 17:20:34 +08:00 committed by Light_Quanta
parent 620e92e0a4
commit 80e600775b
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
8 changed files with 442 additions and 24 deletions

View file

@ -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));
}

View file

@ -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<MortarEntity> {
public MortarRenderer(EntityRendererProvider.Context renderManager) {
@ -36,7 +40,7 @@ public class MortarRenderer extends GeoEntityRenderer<MortarEntity> {
}
@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<MortarEntity> {
}
@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

View file

@ -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<Integer> FIRE_TIME = SynchedEntityData.defineId(MortarEntity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Float> PITCH = SynchedEntityData.defineId(MortarEntity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Float> YAW = SynchedEntityData.defineId(MortarEntity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Boolean> INTELLIGENT = SynchedEntityData.defineId(MortarEntity.class, EntityDataSerializers.BOOLEAN);
public static final EntityDataAccessor<Optional<UUID>> 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

View file

@ -142,6 +142,7 @@ public class ModItems {
public static final DeferredHolder<Item, Drone> DRONE = ITEMS.register("drone", Drone::new);
public static final DeferredHolder<Item, Monitor> MONITOR = ITEMS.register("monitor", Monitor::new);
public static final DeferredHolder<Item, CannonMonitor> CANNON_MONITOR = ITEMS.register("cannon_monitor", CannonMonitor::new);
public static final DeferredHolder<Item, Detonator> DETONATOR = ITEMS.register("detonator", Detonator::new);
public static final DeferredHolder<Item, TargetDeployer> TARGET_DEPLOYER = ITEMS.register("target_deployer", TargetDeployer::new);

View file

@ -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<ItemStack> 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<Component> 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));
// }
}

View file

@ -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<SetFiringParametersMessage> 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<Entity> 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<? extends CustomPacketPayload> type() {
return TYPE;
}
public static List<Entity> getCannon(Player player, Level level, String uuid) {
return StreamSupport.stream(EntityFindUtil.getEntities(level).getAll().spliterator(), false)
.filter(e -> e.getStringUUID().equals(uuid))
.toList();
}
}

View file

@ -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",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB