From ba855a8c0ff16ac7558e0d76557fc9a59e92e453 Mon Sep 17 00:00:00 2001 From: Boblet Date: Wed, 4 Dec 2024 12:06:01 +0100 Subject: [PATCH] added high-power skeletonizer engine --- .../java/com/hbm/entity/mob/EntityDummy.java | 4 +- .../hbm/items/weapon/sedna/BulletConfig.java | 1 + .../weapon/sedna/factory/ConfettiUtil.java | 20 ++ .../com/hbm/particle/ParticleSkeleton.java | 148 ++++++++++++ .../com/hbm/particle/helper/AshesCreator.java | 3 + .../hbm/particle/helper/ParticleCreators.java | 1 + .../hbm/particle/helper/SkeletonCreator.java | 138 +++++++++++ src/main/java/com/hbm/util/Vec3NT.java | 6 +- .../assets/hbm/models/effect/skeleton.obj | 214 ++++++++++++++++++ .../assets/hbm/textures/particle/skeleton.png | Bin 0 -> 858 bytes 10 files changed, 531 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/hbm/particle/ParticleSkeleton.java create mode 100644 src/main/java/com/hbm/particle/helper/SkeletonCreator.java create mode 100644 src/main/resources/assets/hbm/models/effect/skeleton.obj create mode 100644 src/main/resources/assets/hbm/textures/particle/skeleton.png diff --git a/src/main/java/com/hbm/entity/mob/EntityDummy.java b/src/main/java/com/hbm/entity/mob/EntityDummy.java index 2c9a6bc1b..cd64ff427 100644 --- a/src/main/java/com/hbm/entity/mob/EntityDummy.java +++ b/src/main/java/com/hbm/entity/mob/EntityDummy.java @@ -26,7 +26,9 @@ public class EntityDummy extends EntityLiving implements IAnimals { } @Override @SideOnly(Side.CLIENT) public boolean getAlwaysRenderNameTagForRender() { return true; } - @Override public String getCommandSenderName() { return (int) (this.getHealth() * 10) / 10F + " / " + (int) (this.getMaxHealth() * 10) / 10F; } + @Override public String getCommandSenderName() { + return (int) (this.getHealth() * 10) / 10F + " / " + (int) (this.getMaxHealth() * 10) / 10F; } + //return (int) this.rotationYaw + " " + (int) this.renderYawOffset + " " + (int) this.rotationYawHead + " " + (int) this.newRotationYaw; } @Override protected void dropEquipment(boolean b, int i) { } } diff --git a/src/main/java/com/hbm/items/weapon/sedna/BulletConfig.java b/src/main/java/com/hbm/items/weapon/sedna/BulletConfig.java index c2a3ecc82..596a246d2 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/BulletConfig.java +++ b/src/main/java/com/hbm/items/weapon/sedna/BulletConfig.java @@ -136,6 +136,7 @@ public class BulletConfig implements Cloneable { BEAM } + @SuppressWarnings("incomplete-switch") //shut up public static DamageSource getDamage(Entity projectile, EntityLivingBase shooter, DamageClass dmgClass) { DamageSource dmg; diff --git a/src/main/java/com/hbm/items/weapon/sedna/factory/ConfettiUtil.java b/src/main/java/com/hbm/items/weapon/sedna/factory/ConfettiUtil.java index 0df13de04..7c914ba7e 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/factory/ConfettiUtil.java +++ b/src/main/java/com/hbm/items/weapon/sedna/factory/ConfettiUtil.java @@ -1,9 +1,14 @@ package com.hbm.items.weapon.sedna.factory; +import com.hbm.packet.PacketDispatcher; +import com.hbm.packet.toclient.AuxParticlePacketNT; import com.hbm.particle.helper.AshesCreator; +import com.hbm.particle.helper.SkeletonCreator; import com.hbm.util.DamageResistanceHandler.DamageClass; +import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.DamageSource; import net.minecraft.util.MathHelper; @@ -11,6 +16,8 @@ public class ConfettiUtil { public static void decideConfetti(EntityLivingBase entity, DamageSource source) { if(source.damageType.equals(DamageClass.LASER.name())) pulverize(entity); + if(source.damageType.equals(DamageClass.EXPLOSIVE.name())) gib(entity); + skullanize(entity); } public static void pulverize(EntityLivingBase entity) { @@ -18,4 +25,17 @@ public class ConfettiUtil { int amount = MathHelper.clamp_int((int) (entity.width * entity.height * entity.width * 25), 5, 50); AshesCreator.composeEffect(entity.worldObj, entity, amount, 0.125F); } + + public static void skullanize(EntityLivingBase entity) { + if(entity.isEntityAlive()) return; + SkeletonCreator.composeEffect(entity.worldObj, entity); + } + + public static void gib(EntityLivingBase entity) { + NBTTagCompound vdat = new NBTTagCompound(); + vdat.setString("type", "giblets"); + vdat.setInteger("ent", entity.getEntityId()); + PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(vdat, entity.posX, entity.posY + entity.height * 0.5, entity.posZ), new TargetPoint(entity.dimension, entity.posX, entity.posY + entity.height * 0.5, entity.posZ, 150)); + entity.worldObj.playSoundEffect(entity.posX, entity.posY, entity.posZ, "mob.zombie.woodbreak", 2.0F, 0.95F + entity.getRNG().nextFloat() * 0.2F); + } } diff --git a/src/main/java/com/hbm/particle/ParticleSkeleton.java b/src/main/java/com/hbm/particle/ParticleSkeleton.java new file mode 100644 index 000000000..314fb7e9a --- /dev/null +++ b/src/main/java/com/hbm/particle/ParticleSkeleton.java @@ -0,0 +1,148 @@ +package com.hbm.particle; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +import com.hbm.lib.RefStrings; +import com.hbm.particle.helper.SkeletonCreator.EnumSkeletonType; +import com.hbm.render.loader.HFRWavefrontObject; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import net.minecraftforge.client.model.IModelCustom; + +@SideOnly(Side.CLIENT) +public class ParticleSkeleton extends EntityFX { + + public static final ResourceLocation texture = new ResourceLocation(RefStrings.MODID + ":textures/particle/skeleton.png"); + public static final IModelCustom skeleton = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/effect/skeleton.obj"), false).asVBO(); + protected EnumSkeletonType type; + + private float momentumYaw; + private float momentumPitch; + private int initialDelay; + + private final TextureManager textureManager; + + public ParticleSkeleton(TextureManager textureManager, World world, double x, double y, double z, float r, float g, float b, EnumSkeletonType type) { + super(world, x, y, z); + this.textureManager = textureManager; + this.type = type; + + this.particleMaxAge = 200 + rand.nextInt(20); + + this.particleRed = r; + this.particleGreen = g; + this.particleBlue = b; + this.particleGravity = 0.02F; + this.initialDelay = 20; + + this.momentumPitch = rand.nextFloat() * 5 * (rand.nextBoolean() ? 1 : -1); + this.momentumYaw = rand.nextFloat() * 5 * (rand.nextBoolean() ? 1 : -1); + } + + @Override + public void onUpdate() { + + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + this.prevRotationPitch = this.rotationPitch; + this.prevRotationYaw = this.rotationYaw; + + if(initialDelay-- > 0) return; + + if(initialDelay == -1) { + this.motionX = rand.nextGaussian() * 0.025; + this.motionZ = rand.nextGaussian() * 0.025; + } + + if(this.particleAge++ >= this.particleMaxAge) { + this.setDead(); + } + + this.motionY -= this.particleGravity; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.98D; + this.motionY *= 0.98D; + this.motionZ *= 0.98D; + + if(!this.onGround) { + this.rotationPitch += this.momentumPitch; + this.rotationYaw += this.momentumYaw; + } else { + this.motionX = 0; + this.motionY = 0; + this.motionZ = 0; + } + } + + @Override + public int getFXLayer() { + return 3; + } + + @Override + public void renderParticle(Tessellator tess, float interp, float x, float y, float z, float tx, float tz) { + + GL11.glPushMatrix(); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glEnable(GL11.GL_BLEND); + GL11.glAlphaFunc(GL11.GL_GREATER, 0); + OpenGlHelper.glBlendFunc(770, 771, 1, 0); + RenderHelper.enableStandardItemLighting(); + + this.textureManager.bindTexture(texture); + + double pX = prevPosX + (posX - prevPosX) * interp; + double pY = prevPosY + (posY - prevPosY) * interp; + double pZ = prevPosZ + (posZ - prevPosZ) * interp; + EntityPlayer player = Minecraft.getMinecraft().thePlayer; + double dX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)interp; + double dY = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double)interp; + double dZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double)interp; + + GL11.glTranslated(pX - dX, pY - dY, pZ - dZ); + + GL11.glRotated(this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * interp, 0, 1, 0); + GL11.glRotated(this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * interp, 1, 0, 0); + + float timeLeft = this.particleMaxAge - (this.particleAge + interp); + if(timeLeft < 40) { + this.particleAlpha = timeLeft / 40F; + } else { + this.particleAlpha = 1F; + } + + int brightness = worldObj.getLightBrightnessForSkyBlocks(MathHelper.floor_double(pX), MathHelper.floor_double(pY), MathHelper.floor_double(pZ), 0); + int lX = brightness % 65536; + int lY = brightness / 65536; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)lX / 1.0F, (float)lY / 1.0F); + + GL11.glColor4f(particleRed, particleGreen, particleBlue, particleAlpha); + GL11.glRotated(-90, 0, 1, 0); + + switch(type) { + case SKULL: skeleton.renderPart("Skull"); break; + case TORSO: skeleton.renderPart("Torso"); break; + case LIMB: skeleton.renderPart("Limb"); break; + } + + GL11.glColor4f(1F, 1F, 1F, 1F); + GL11.glAlphaFunc(GL11.GL_GREATER, 0.1F); + GL11.glDisable(GL11.GL_CULL_FACE); + + GL11.glPopMatrix(); + } +} diff --git a/src/main/java/com/hbm/particle/helper/AshesCreator.java b/src/main/java/com/hbm/particle/helper/AshesCreator.java index 2076e6baa..56a36acc5 100644 --- a/src/main/java/com/hbm/particle/helper/AshesCreator.java +++ b/src/main/java/com/hbm/particle/helper/AshesCreator.java @@ -5,6 +5,8 @@ import java.util.Random; import com.hbm.main.ClientProxy; import com.hbm.particle.ParticleAshes; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.Minecraft; import net.minecraft.client.particle.EntityFlameFX; import net.minecraft.client.renderer.texture.TextureManager; @@ -26,6 +28,7 @@ public class AshesCreator implements IParticleCreator { } @Override + @SideOnly(Side.CLIENT) public void makeParticle(World world, EntityPlayer player, TextureManager texman, Random rand, double x, double y, double z, NBTTagCompound data) { int entityID = data.getInteger("entityID"); diff --git a/src/main/java/com/hbm/particle/helper/ParticleCreators.java b/src/main/java/com/hbm/particle/helper/ParticleCreators.java index 023233b8b..2f23f88f4 100644 --- a/src/main/java/com/hbm/particle/helper/ParticleCreators.java +++ b/src/main/java/com/hbm/particle/helper/ParticleCreators.java @@ -13,5 +13,6 @@ public class ParticleCreators { particleCreators.put("explosionSmall", new ExplosionSmallCreator()); particleCreators.put("blackPowder", new BlackPowderCreator()); particleCreators.put("ashes", new AshesCreator()); + particleCreators.put("skeleton", new SkeletonCreator()); } } diff --git a/src/main/java/com/hbm/particle/helper/SkeletonCreator.java b/src/main/java/com/hbm/particle/helper/SkeletonCreator.java new file mode 100644 index 000000000..78dfaeafa --- /dev/null +++ b/src/main/java/com/hbm/particle/helper/SkeletonCreator.java @@ -0,0 +1,138 @@ +package com.hbm.particle.helper; + +import java.util.HashMap; +import java.util.Random; +import java.util.function.Function; + +import com.hbm.entity.mob.EntityDummy; +import com.hbm.main.ClientProxy; +import com.hbm.particle.ParticleSkeleton; +import com.hbm.util.Vec3NT; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityClientPlayerMP; +import net.minecraft.client.entity.EntityOtherPlayerMP; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntitySkeleton; +import net.minecraft.entity.monster.EntityZombie; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +public class SkeletonCreator implements IParticleCreator { + + public static HashMap> skullanizer = new HashMap(); + + public static void composeEffect(World world, Entity toSkeletonize) { + + NBTTagCompound data = new NBTTagCompound(); + data.setString("type", "skeleton"); + data.setInteger("entityID", toSkeletonize.getEntityId()); + IParticleCreator.sendPacket(world, toSkeletonize.posX, toSkeletonize.posY, toSkeletonize.posZ, 100, data); + } + + @Override + @SideOnly(Side.CLIENT) + public void makeParticle(World world, EntityPlayer player, TextureManager texman, Random rand, double x, double y, double z, NBTTagCompound data) { + + if(skullanizer.isEmpty()) init(); + + int entityID = data.getInteger("entityID"); + Entity entity = world.getEntityByID(entityID); + if(!(entity instanceof EntityLivingBase)) return; + EntityLivingBase living = (EntityLivingBase) entity; + + ClientProxy.vanish(entityID); + + Function bonealizer = skullanizer.get(entity.getClass()); + + if(bonealizer != null) { + BoneDefinition[] bones = bonealizer.apply(living); + for(BoneDefinition bone : bones) { + ParticleSkeleton skeleton = new ParticleSkeleton(Minecraft.getMinecraft().getTextureManager(), world, bone.x, bone.y, bone.z, 1F, 1F, 1F, bone.type); + skeleton.prevRotationYaw = skeleton.rotationYaw = bone.yaw; + skeleton.prevRotationPitch = skeleton.rotationPitch = bone.pitch; + Minecraft.getMinecraft().effectRenderer.addEffect(skeleton); + } + } + } + + public static class BoneDefinition { + public EnumSkeletonType type; + public float yaw; + public float pitch; + public double x; + public double y; + public double z; + + public BoneDefinition(EnumSkeletonType type, float yaw, float pitch, double x, double y, double z) { + this.type = type; + this.yaw = yaw; + this.pitch = pitch; + this.x = x; + this.y = y; + this.z = z; + } + } + + public static enum EnumSkeletonType { + SKULL, TORSO, LIMB + } + + public static Function BONES_BIPED = (entity) -> { + Vec3NT leftarm = new Vec3NT(0.375, 0, 0).rotateAroundYDeg(-entity.renderYawOffset); + Vec3NT leftleg = new Vec3NT(0.125, 0, 0).rotateAroundYDeg(-entity.renderYawOffset); + return new BoneDefinition[] { + new BoneDefinition(EnumSkeletonType.SKULL, -entity.rotationYawHead, entity.rotationPitch, entity.posX, entity.posY + 1.75, entity.posZ), + new BoneDefinition(EnumSkeletonType.TORSO, -entity.renderYawOffset, 0, entity.posX, entity.posY + 1.125, entity.posZ), + new BoneDefinition(EnumSkeletonType.LIMB, -entity.renderYawOffset, 0, entity.posX + leftarm.xCoord, entity.posY + 1.125, entity.posZ + leftarm.zCoord), + new BoneDefinition(EnumSkeletonType.LIMB, -entity.renderYawOffset, 0, entity.posX - leftarm.xCoord, entity.posY + 1.125, entity.posZ - leftarm.zCoord), + new BoneDefinition(EnumSkeletonType.LIMB, -entity.renderYawOffset, 0, entity.posX + leftleg.xCoord, entity.posY + 0.625, entity.posZ + leftleg.zCoord), + new BoneDefinition(EnumSkeletonType.LIMB, -entity.renderYawOffset, 0, entity.posX - leftleg.xCoord, entity.posY + 0.625, entity.posZ - leftleg.zCoord), + }; + }; + + public static Function BONES_ZOMBIE = (entity) -> { + Vec3NT leftarm = new Vec3NT(0.375, 0, 0).rotateAroundYDeg(-entity.renderYawOffset); + Vec3NT forward = new Vec3NT(0, 0, 0.25).rotateAroundYDeg(-entity.renderYawOffset); + Vec3NT leftleg = new Vec3NT(0.125, 0, 0).rotateAroundYDeg(-entity.renderYawOffset); + return new BoneDefinition[] { + new BoneDefinition(EnumSkeletonType.SKULL, -entity.rotationYawHead, entity.rotationPitch, entity.posX, entity.posY + 1.75, entity.posZ), + new BoneDefinition(EnumSkeletonType.TORSO, -entity.renderYawOffset, 0, entity.posX, entity.posY + 1.125, entity.posZ), + new BoneDefinition(EnumSkeletonType.LIMB, -entity.renderYawOffset, -90, entity.posX + leftarm.xCoord + forward.xCoord, entity.posY + 1.375, entity.posZ + leftarm.zCoord + forward.zCoord), + new BoneDefinition(EnumSkeletonType.LIMB, -entity.renderYawOffset, -90, entity.posX - leftarm.xCoord + forward.xCoord, entity.posY + 1.375, entity.posZ - leftarm.zCoord + forward.zCoord), + new BoneDefinition(EnumSkeletonType.LIMB, -entity.renderYawOffset, 0, entity.posX + leftleg.xCoord, entity.posY + 0.625, entity.posZ + leftleg.zCoord), + new BoneDefinition(EnumSkeletonType.LIMB, -entity.renderYawOffset, 0, entity.posX - leftleg.xCoord, entity.posY + 0.625, entity.posZ - leftleg.zCoord), + }; + }; + + public static Function BONES_DUMMY = (entity) -> { + Vec3NT leftarm = new Vec3NT(0.375, 0, 0).rotateAroundYDeg(-entity.renderYawOffset); + Vec3NT forward = new Vec3NT(0, 0, 0.25).rotateAroundYDeg(-entity.renderYawOffset); + Vec3NT leftleg = new Vec3NT(0.125, 0, 0).rotateAroundYDeg(-entity.renderYawOffset); + return new BoneDefinition[] { + new BoneDefinition(EnumSkeletonType.SKULL, -entity.rotationYawHead, entity.rotationPitch, entity.posX, entity.posY + 1.75, entity.posZ), + new BoneDefinition(EnumSkeletonType.TORSO, -entity.renderYawOffset, 0, entity.posX, entity.posY + 1.125, entity.posZ), + new BoneDefinition(EnumSkeletonType.LIMB, -entity.renderYawOffset, -90, entity.posX + leftarm.xCoord + forward.xCoord, entity.posY + 1.375, entity.posZ + leftarm.zCoord + forward.zCoord), + new BoneDefinition(EnumSkeletonType.LIMB, -entity.renderYawOffset, -90, entity.posX - leftarm.xCoord + forward.xCoord, entity.posY + 1.375, entity.posZ - leftarm.zCoord + forward.zCoord), + new BoneDefinition(EnumSkeletonType.LIMB, -entity.renderYawOffset, 0, entity.posX + leftleg.xCoord, entity.posY + 0.625, entity.posZ + leftleg.zCoord), + new BoneDefinition(EnumSkeletonType.LIMB, -entity.renderYawOffset, 0, entity.posX - leftleg.xCoord, entity.posY + 0.625, entity.posZ - leftleg.zCoord), + }; + }; + + public static void init() { + skullanizer.put(EntityOtherPlayerMP.class, BONES_BIPED); + skullanizer.put(EntityClientPlayerMP.class, BONES_BIPED); + skullanizer.put(EntityPlayerSP.class, BONES_BIPED); + + skullanizer.put(EntityZombie.class, BONES_ZOMBIE); + skullanizer.put(EntitySkeleton.class, BONES_ZOMBIE); + + skullanizer.put(EntityDummy.class, BONES_DUMMY); + } +} diff --git a/src/main/java/com/hbm/util/Vec3NT.java b/src/main/java/com/hbm/util/Vec3NT.java index 8bedb3869..0cb8121a7 100644 --- a/src/main/java/com/hbm/util/Vec3NT.java +++ b/src/main/java/com/hbm/util/Vec3NT.java @@ -79,15 +79,15 @@ public class Vec3NT extends Vec3 { } public Vec3NT rotateAroundXDeg(double alpha) { - return this.rotateAroundXRad(alpha * 180D / Math.PI); + return this.rotateAroundXRad(alpha / 180D * Math.PI); } public Vec3NT rotateAroundYDeg(double alpha) { - return this.rotateAroundYRad(alpha * 180D / Math.PI); + return this.rotateAroundYRad(alpha / 180D * Math.PI); } public Vec3NT rotateAroundZDeg(double alpha) { - return this.rotateAroundZRad(alpha * 180D / Math.PI); + return this.rotateAroundZRad(alpha / 180D * Math.PI); } public static double getMinX(Vec3NT... vecs) { diff --git a/src/main/resources/assets/hbm/models/effect/skeleton.obj b/src/main/resources/assets/hbm/models/effect/skeleton.obj new file mode 100644 index 000000000..d7ae2c48e --- /dev/null +++ b/src/main/resources/assets/hbm/models/effect/skeleton.obj @@ -0,0 +1,214 @@ +# Blender v2.79 (sub 0) OBJ File: 'skeleton.blend' +# www.blender.org +o Torso +v 0.125000 -0.375000 0.250000 +v 0.125000 0.375000 0.250000 +v 0.125000 -0.375000 -0.250000 +v 0.125000 0.375000 -0.250000 +v -0.125000 -0.375000 0.250000 +v -0.125000 0.375000 0.250000 +v -0.125000 -0.375000 -0.250000 +v -0.125000 0.375000 -0.250000 +v 0.125000 -0.375000 0.250000 +v 0.125000 0.375000 0.250000 +v 0.125000 -0.375000 -0.250000 +v 0.125000 0.375000 -0.250000 +v -0.125000 -0.375000 0.250000 +v -0.125000 0.375000 0.250000 +v -0.125000 -0.375000 -0.250000 +v -0.125000 0.375000 -0.250000 +vt 0.312500 0.000000 +vt 0.437500 0.375000 +vt 0.437500 0.000000 +vt 0.500000 0.000000 +vt 0.437500 0.375000 +vt 0.437500 0.000000 +vt 0.625000 0.000000 +vt 0.500000 0.375000 +vt 0.312500 0.000000 +vt 0.250000 0.375000 +vt 0.250000 0.000000 +vt 0.437500 0.500000 +vt 0.562500 0.375000 +vt 0.562500 0.500000 +vt 0.312500 0.500000 +vt 0.437500 0.500000 +vt 0.437500 0.375000 +vt 0.312500 0.000000 +vt 0.437500 0.000000 +vt 0.437500 0.375000 +vt 0.500000 0.000000 +vt 0.437500 0.000000 +vt 0.500000 0.375000 +vt 0.625000 0.000000 +vt 0.250000 0.375000 +vt 0.312500 0.000000 +vt 0.250000 0.000000 +vt 0.562500 0.375000 +vt 0.437500 0.500000 +vt 0.562500 0.500000 +vt 0.312500 0.500000 +vt 0.437500 0.500000 +vt 0.312500 0.375000 +vt 0.625000 0.375000 +vt 0.312500 0.375000 +vt 0.437500 0.375000 +vt 0.312500 0.375000 +vt 0.625000 0.375000 +vt 0.312500 0.375000 +vt 0.437500 0.375000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +s off +f 3/1/1 2/2/1 1/3/1 +f 7/4/2 4/5/2 3/6/2 +f 5/7/3 8/8/3 7/4/3 +f 1/9/4 6/10/4 5/11/4 +f 1/12/5 7/13/5 3/14/5 +f 6/15/6 4/5/6 8/16/6 +f 10/17/3 11/18/3 9/19/3 +f 12/20/4 15/21/4 11/22/4 +f 16/23/1 13/24/1 15/21/1 +f 14/25/2 9/26/2 13/27/2 +f 15/28/6 9/29/6 11/30/6 +f 12/20/5 14/31/5 16/32/5 +f 3/1/1 4/33/1 2/2/1 +f 7/4/2 8/8/2 4/5/2 +f 5/7/3 6/34/3 8/8/3 +f 1/9/4 2/35/4 6/10/4 +f 1/12/5 5/36/5 7/13/5 +f 6/15/6 2/35/6 4/5/6 +f 10/17/3 12/37/3 11/18/3 +f 12/20/4 16/23/4 15/21/4 +f 16/23/1 14/38/1 13/24/1 +f 14/25/2 10/39/2 9/26/2 +f 15/28/6 13/40/6 9/29/6 +f 12/20/5 10/39/5 14/31/5 +o Skull +v -0.250000 -0.250000 0.250000 +v -0.250000 0.250000 0.250000 +v -0.250000 -0.250000 -0.250000 +v -0.250000 0.250000 -0.250000 +v 0.250000 -0.250000 0.250000 +v 0.250000 0.250000 0.250000 +v 0.250000 -0.250000 -0.250000 +v 0.250000 0.250000 -0.250000 +v -0.250000 -0.250000 0.250000 +v -0.250000 0.250000 0.250000 +v -0.250000 -0.250000 -0.250000 +v -0.250000 0.250000 -0.250000 +v 0.250000 -0.250000 0.250000 +v 0.250000 0.250000 0.250000 +v 0.250000 -0.250000 -0.250000 +v 0.250000 0.250000 -0.250000 +vt 0.500000 0.750000 +vt 0.375000 0.500000 +vt 0.500000 0.500000 +vt 0.375000 0.750000 +vt 0.250000 0.500000 +vt 0.250000 0.750000 +vt 0.125000 0.500000 +vt 0.125000 0.750000 +vt -0.000000 0.500000 +vt 0.250000 0.750000 +vt 0.375000 1.000000 +vt 0.250000 1.000000 +vt 0.250000 1.000000 +vt 0.375000 0.500000 +vt 0.500000 0.750000 +vt 0.500000 0.500000 +vt 0.250000 0.500000 +vt 0.375000 0.750000 +vt 0.125000 0.500000 +vt 0.250000 0.750000 +vt -0.000000 0.500000 +vt 0.125000 0.750000 +vt 0.375000 1.000000 +vt 0.250000 0.750000 +vt 0.250000 1.000000 +vt 0.250000 1.000000 +vt -0.000000 0.750000 +vt 0.375000 0.750000 +vt 0.125000 1.000000 +vt -0.000000 0.750000 +vt 0.375000 0.750000 +vt 0.125000 1.000000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +s off +f 18/41/7 19/42/7 17/43/7 +f 20/44/8 23/45/8 19/42/8 +f 24/46/9 21/47/9 23/45/9 +f 22/48/10 17/49/10 21/47/10 +f 23/50/11 17/51/11 19/52/11 +f 20/53/12 22/48/12 24/46/12 +f 27/54/9 26/55/9 25/56/9 +f 31/57/10 28/58/10 27/54/10 +f 29/59/7 32/60/7 31/57/7 +f 25/61/8 30/62/8 29/59/8 +f 25/63/12 31/64/12 27/65/12 +f 30/62/11 28/66/11 32/60/11 +f 18/41/7 20/44/7 19/42/7 +f 20/44/8 24/46/8 23/45/8 +f 24/46/9 22/48/9 21/47/9 +f 22/48/10 18/67/10 17/49/10 +f 23/50/11 21/68/11 17/51/11 +f 20/53/12 18/69/12 22/48/12 +f 27/54/9 28/58/9 26/55/9 +f 31/57/10 32/60/10 28/58/10 +f 29/59/7 30/62/7 32/60/7 +f 25/61/8 26/70/8 30/62/8 +f 25/63/12 29/71/12 31/64/12 +f 30/62/11 26/72/11 28/66/11 +o Limb +v -0.062500 -0.375000 0.062500 +v -0.062500 0.375000 0.062500 +v -0.062500 -0.375000 -0.062500 +v -0.062500 0.375000 -0.062500 +v 0.062500 -0.375000 0.062500 +v 0.062500 0.375000 0.062500 +v 0.062500 -0.375000 -0.062500 +v 0.062500 0.375000 -0.062500 +vt 0.125000 0.437500 +vt 0.093750 0.062500 +vt 0.125000 0.062500 +vt 0.093750 0.437500 +vt 0.062500 0.062500 +vt 0.062500 0.437500 +vt 0.031250 0.062500 +vt 0.031250 0.437500 +vt 0.000000 0.062500 +vt 0.062500 0.437500 +vt 0.093750 0.500000 +vt 0.062500 0.500000 +vt 0.062500 0.500000 +vt -0.000000 0.437500 +vt 0.093750 0.437500 +vt 0.031250 0.500000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +s off +f 34/73/13 35/74/13 33/75/13 +f 36/76/14 39/77/14 35/74/14 +f 40/78/15 37/79/15 39/77/15 +f 38/80/16 33/81/16 37/79/16 +f 39/82/17 33/83/17 35/84/17 +f 36/85/18 38/80/18 40/78/18 +f 34/73/13 36/76/13 35/74/13 +f 36/76/14 40/78/14 39/77/14 +f 40/78/15 38/80/15 37/79/15 +f 38/80/16 34/86/16 33/81/16 +f 39/82/17 37/87/17 33/83/17 +f 36/85/18 34/88/18 38/80/18 diff --git a/src/main/resources/assets/hbm/textures/particle/skeleton.png b/src/main/resources/assets/hbm/textures/particle/skeleton.png new file mode 100644 index 0000000000000000000000000000000000000000..184b5853ed9b1e3bb03735ef2673c96c4d7602b2 GIT binary patch literal 858 zcmV-g1Eu_lP)dL;4E|VXE)sI=B}^{A=%wYa^}orGRapf@+=mM43X#a+3IvUPMS7PyWMWRUa!&- z`u+Y_Y>toq4*}!xINNMCuIQa_l+kG92ns!A|2|r23l4>){B$~P9s#nxEKe;`s2k$} zD2oSB>~d%X0U_lT4;n#$tUjO5od--NlRO|cf&eM5C7@ua7yt=H<>RCMY&Od%QVwOe z+ikX9uk*58E}g}ZBPb%vHwcg%eJoKLS3#40w#_@9R69XF0Vswd)Vtlz)hfK7&*$uP zI=OH3m5lm`NJ~Ij9#K01QUu^Aft3J{b)?kwdd+UPTlRQ7vitq+%JFz~$|Hj;edsGM z;9Xu)mPgc1fPk-7tK6z`ae$-f<#KT~*5B{E?&zBsZJ?AT3wRP15#PWs^0U=z%{Wd(~TDeE?Fc&AZ=E zS7?&+*`ZxH#^&vAOXD_OMGl8tFzOr^~EFGGxTnc>O zaM&B4P&)>?%K!30J7#ix_Us;NSE*oZELq#iCC8V1f|%CkzpVYI1pEMBP*j&9scw?r k#h1Ll?hjMlB&Sy3AGp-UUwDhUp8x;=07*qoM6N<$f^$Zd8~^|S literal 0 HcmV?d00001