From b3405d085b107e1cea2bb7cb42afcf25ff32fc9a Mon Sep 17 00:00:00 2001 From: Boblet Date: Fri, 19 Sep 2025 13:02:50 +0200 Subject: [PATCH] the skeleton's coming out, AAAAAAAAAAAAA --- changelog | 3 + .../java/com/hbm/entity/EntityMappings.java | 1 - .../com/hbm/handler/GunConfiguration.java | 123 ------------------ .../com/hbm/items/weapon/ItemCrucible.java | 1 - .../weapon/sedna/factory/ConfettiUtil.java | 2 + src/main/java/com/hbm/main/ClientProxy.java | 5 - .../com/hbm/particle/ParticleSkeleton.java | 25 +++- .../hbm/particle/helper/SkeletonCreator.java | 24 +++- .../hbm/textures/particle/skeleton_blood.png | Bin 0 -> 2411 bytes .../hbm/textures/particle/skoilet_blood.png | Bin 0 -> 4218 bytes 10 files changed, 47 insertions(+), 137 deletions(-) delete mode 100644 src/main/java/com/hbm/handler/GunConfiguration.java create mode 100644 src/main/resources/assets/hbm/textures/particle/skeleton_blood.png create mode 100644 src/main/resources/assets/hbm/textures/particle/skoilet_blood.png diff --git a/changelog b/changelog index 5dc4a445d..938e01585 100644 --- a/changelog +++ b/changelog @@ -4,6 +4,9 @@ * All dual wielded guns now render more accurately when dropped instead of only showing one gun * Added support for left handed guns (currently unused)* * Removed the presentations for the old particle accelerator and schottky diode +* Gibbing NPCs now also spawns bones, if supported by the skeletonizer + * Gibbed bones only have a 50% chance of spawning and come with a unique red texture + * Gibbed bones have a way shorter lifetime and higher gravity to match the gib particles ## Fixed * Fixed wood burner only being able to create one ash pile per item burned, even when that item yields more, creating a backlog in the internal ash value diff --git a/src/main/java/com/hbm/entity/EntityMappings.java b/src/main/java/com/hbm/entity/EntityMappings.java index 9c5d5358d..764b06463 100644 --- a/src/main/java/com/hbm/entity/EntityMappings.java +++ b/src/main/java/com/hbm/entity/EntityMappings.java @@ -25,7 +25,6 @@ import com.hbm.entity.train.*; import com.hbm.main.MainRegistry; import com.hbm.util.Tuple.Quartet; -import cpw.mods.fml.common.registry.EntityRegistry; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EnumCreatureType; diff --git a/src/main/java/com/hbm/handler/GunConfiguration.java b/src/main/java/com/hbm/handler/GunConfiguration.java deleted file mode 100644 index f703d47e4..000000000 --- a/src/main/java/com/hbm/handler/GunConfiguration.java +++ /dev/null @@ -1,123 +0,0 @@ -package com.hbm.handler; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.function.Consumer; - -import com.hbm.items.weapon.sedna.Crosshair; -import com.hbm.lib.HbmCollection.EnumGunManufacturer; -import com.hbm.render.anim.AnimationEnums.GunAnimation; -import com.hbm.render.anim.BusAnimation; - -import net.minecraft.util.ResourceLocation; - -@Deprecated -public class GunConfiguration implements Cloneable { - - /** - * alt function restrictions: - * alt can not be reloaded (reload type of 0, ammo cap of 0) - * alt cooldown and main cooldown are shared (alt cooldown will almoast always be greater or equal) - * alt is always the lower priority, mouse2 will be canceled then mouse1 is activated at the same time - * restrictions must be applied in gun's logic, mechanism may be dysfunctional if these rules are ignored - */ - - //amount of ticks between each bullet - public int rateOfFire; - //amount of bullets fired per delay passed - public int roundsPerCycle; - /** Amount of rounds per burst, irrelevant if not a burst fire weapon**/ - public int roundsPerBurst; - //0 = normal, 1 = release, 2 = both - public int gunMode; - //0 = manual, 1 = automatic - public int firingMode; - //weapon won't fire after weapon breaks (main only) - public int durability; - - //animations! - public HashMap animations = new HashMap(); - //lazy-ish loading for animations, required for loading animations from ResourceManager, since that occurs after we've initialised the guns - public Consumer loadAnimations; - public boolean animationsLoaded = false; - //when sneaking, disables crosshair and centers the bullet spawn point - public boolean hasSights; - //does this weapon behave like fully sick old-school boomer shooters - public boolean isCentered; - //texture overlay when sneaking - public ResourceLocation scopeTexture; - - //duration of every animation cycle, used also for how quickly a burst fire rifle can fire - public int firingDuration; - //sound path to the shooting sound - public String firingSound = ""; - public String firingSoundEmpty = null; - public float firingVolume = 1.0F; - public float firingPitch = 1.0F; - //how long the reload animation will play - //MUST BE GREATER THAN ZERO ! ! ! - public int reloadDuration; - public int emptyReloadAdditionalDuration; - //sound path to the reload sound - public String reloadSound = ""; - public String reloadSoundEmpty = null; - //whether the reload sound should be played at the beginning or at the end of the reload - public boolean reloadSoundEnd = true; - public String equipSound = ""; - - //how much ammo the clip can hold, 0 if drawn from inventory - public int ammoCap; - //0 does not allow direct reload, 1 is full clip, 2 is single bullet - public int reloadType; - // If the animations are designed to be sequential, the last frame will be held until the next anmiation starts - public boolean reloadAnimationsSequential = false; - //whether or not the infinity enchantment should work - public boolean allowsInfinity; - //whether the ammo count should be displayed - public boolean showAmmo = true; - - //for electrically powered weapons: - //the Maximum capacity of the gun - public long maxCharge; - //the rate at which the gun is charged - public long chargeRate; - //how much energy is discharged per shot - public long dischargePerShot; - - public String name = ""; - public EnumGunManufacturer manufacturer = EnumGunManufacturer.NONE; - public List comment = new ArrayList(); - - //bullet configs for main and alt fire - public List config = new ArrayList(); - - //crosshair - public Crosshair crosshair; - - //casing eject behavior - public CasingEjector ejector = null; - - public static final int MODE_NORMAL = 0; - public static final int MODE_RELEASE = 1; - public static final int MODE_BOTH = 1; - - public static final int FIRE_MANUAL = 0; - public static final int FIRE_AUTO = 1; - public static final int FIRE_BURST = 2; - - public static final int RELOAD_NONE = 0; - public static final int RELOAD_FULL = 1; - public static final int RELOAD_SINGLE = 2; - - public static final String RSOUND_REVOLVER = "hbm:weapon.revolverReload"; - public static final String RSOUND_RIFLE = ""; - public static final String RSOUND_MAG = "hbm:weapon.magReload"; - public static final String RSOUND_MAG_BOLT = "hbm:weapon.magReloadBolt"; - public static final String RSOUND_SHOTGUN = "hbm:weapon.shotgunReload"; - public static final String RSOUND_LAUNCHER = "hbm:weapon.rpgReload"; - public static final String RSOUND_GRENADE = "hbm:weapon.hkReload"; - public static final String RSOUND_GRENADE_NEW = "hbm:weapon.glReload"; - public static final String RSOUND_FATMAN = "hbm:weapon.fatmanReload"; - -} diff --git a/src/main/java/com/hbm/items/weapon/ItemCrucible.java b/src/main/java/com/hbm/items/weapon/ItemCrucible.java index 3945e52cc..09c1e5453 100644 --- a/src/main/java/com/hbm/items/weapon/ItemCrucible.java +++ b/src/main/java/com/hbm/items/weapon/ItemCrucible.java @@ -1,7 +1,6 @@ package com.hbm.items.weapon; import java.util.List; -import java.util.Random; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; 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 10745b90d..661b4185a 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 @@ -48,6 +48,8 @@ public class ConfettiUtil { if(entity instanceof EntitySkeleton) return; if(entity instanceof EntitySlime) return; + SkeletonCreator.composeEffectGib(entity.worldObj, entity, 0.25F); + NBTTagCompound vdat = new NBTTagCompound(); vdat.setString("type", "giblets"); vdat.setInteger("ent", entity.getEntityId()); diff --git a/src/main/java/com/hbm/main/ClientProxy.java b/src/main/java/com/hbm/main/ClientProxy.java index 2d51ccd49..a1c226305 100644 --- a/src/main/java/com/hbm/main/ClientProxy.java +++ b/src/main/java/com/hbm/main/ClientProxy.java @@ -41,7 +41,6 @@ import com.hbm.handler.HbmKeybinds; import com.hbm.handler.HbmKeybinds.EnumKeybind; import com.hbm.handler.ImpactWorldHandler; import com.hbm.handler.imc.IMCHandlerNHNEI; -import com.hbm.items.IAnimatedItem; import com.hbm.items.ModItems; import com.hbm.items.weapon.sedna.factory.GunFactoryClient; import com.hbm.lib.RefStrings; @@ -49,10 +48,6 @@ import com.hbm.particle.*; import com.hbm.particle.helper.ParticleCreators; import com.hbm.particle.psys.engine.EventHandlerParticleEngine; import com.hbm.qmaw.QMAWLoader; -import com.hbm.render.anim.BusAnimation; -import com.hbm.render.anim.BusAnimationSequence; -import com.hbm.render.anim.HbmAnimations; -import com.hbm.render.anim.HbmAnimations.Animation; import com.hbm.render.block.*; import com.hbm.render.entity.RenderEmpty; import com.hbm.render.entity.effect.*; diff --git a/src/main/java/com/hbm/particle/ParticleSkeleton.java b/src/main/java/com/hbm/particle/ParticleSkeleton.java index a3eb3f4c9..37f8f5cf1 100644 --- a/src/main/java/com/hbm/particle/ParticleSkeleton.java +++ b/src/main/java/com/hbm/particle/ParticleSkeleton.java @@ -26,8 +26,13 @@ public class ParticleSkeleton extends EntityFX { public static final ResourceLocation texture = new ResourceLocation(RefStrings.MODID + ":textures/particle/skeleton.png"); public static final ResourceLocation texture_ext = new ResourceLocation(RefStrings.MODID + ":textures/particle/skoilet.png"); + public static final ResourceLocation texture_blood = new ResourceLocation(RefStrings.MODID + ":textures/particle/skeleton_blood.png"); + public static final ResourceLocation texture_blood_ext = new ResourceLocation(RefStrings.MODID + ":textures/particle/skoilet_blood.png"); public static final IModelCustom skeleton = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/effect/skeleton.obj"), false).asVBO(); protected EnumSkeletonType type; + + public ResourceLocation useTexture; + public ResourceLocation useTextureExt; private float momentumYaw; private float momentumPitch; @@ -50,6 +55,18 @@ public class ParticleSkeleton extends EntityFX { this.momentumPitch = rand.nextFloat() * 5 * (rand.nextBoolean() ? 1 : -1); this.momentumYaw = rand.nextFloat() * 5 * (rand.nextBoolean() ? 1 : -1); + + this.useTexture = texture; + this.useTextureExt = texture_ext; + } + + public ParticleSkeleton makeGib() { + this.initialDelay = -2; // skip post delay motion randomization + this.useTexture = texture_blood; + this.useTextureExt = texture_blood_ext; + this.particleGravity = 0.04F; + this.particleMaxAge = 600 + rand.nextInt(20); + return this; } @Override @@ -139,16 +156,16 @@ public class ParticleSkeleton extends EntityFX { switch(type) { case SKULL: - this.textureManager.bindTexture(texture); + this.textureManager.bindTexture(useTexture); skeleton.renderPart("Skull"); break; case TORSO: - this.textureManager.bindTexture(texture); + this.textureManager.bindTexture(useTexture); skeleton.renderPart("Torso"); break; case LIMB: - this.textureManager.bindTexture(texture); + this.textureManager.bindTexture(useTexture); skeleton.renderPart("Limb"); break; case SKULL_VILLAGER: - this.textureManager.bindTexture(texture_ext); + this.textureManager.bindTexture(useTextureExt); skeleton.renderPart("SkullVillager"); break; } diff --git a/src/main/java/com/hbm/particle/helper/SkeletonCreator.java b/src/main/java/com/hbm/particle/helper/SkeletonCreator.java index 98018bd17..059ae65a8 100644 --- a/src/main/java/com/hbm/particle/helper/SkeletonCreator.java +++ b/src/main/java/com/hbm/particle/helper/SkeletonCreator.java @@ -33,20 +33,31 @@ public class SkeletonCreator implements IParticleCreator { public static HashMap> skullanizer = new HashMap(); public static void composeEffect(World world, Entity toSkeletonize, float brightness) { - NBTTagCompound data = new NBTTagCompound(); data.setString("type", "skeleton"); data.setInteger("entityID", toSkeletonize.getEntityId()); data.setFloat("brightness", brightness); IParticleCreator.sendPacket(world, toSkeletonize.posX, toSkeletonize.posY, toSkeletonize.posZ, 100, data); } + + public static void composeEffectGib(World world, Entity toSkeletonize, float force) { + NBTTagCompound data = new NBTTagCompound(); + data.setString("type", "skeleton"); + data.setInteger("entityID", toSkeletonize.getEntityId()); + data.setFloat("brightness", 1F); + data.setFloat("force", force); + data.setBoolean("gib", true); + 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(); - + + boolean gib = data.getBoolean("gib"); + float force = data.getFloat("force"); int entityID = data.getInteger("entityID"); Entity entity = world.getEntityByID(entityID); if(!(entity instanceof EntityLivingBase)) return; @@ -61,9 +72,16 @@ public class SkeletonCreator implements IParticleCreator { if(bonealizer != null) { BoneDefinition[] bones = bonealizer.apply(living); for(BoneDefinition bone : bones) { + if(gib && rand.nextBoolean()) continue; ParticleSkeleton skeleton = new ParticleSkeleton(Minecraft.getMinecraft().getTextureManager(), world, bone.x, bone.y, bone.z, brightness, brightness, brightness, bone.type); skeleton.prevRotationYaw = skeleton.rotationYaw = bone.yaw; skeleton.prevRotationPitch = skeleton.rotationPitch = bone.pitch; + if(gib) { + skeleton.makeGib(); + skeleton.motionX = rand.nextGaussian() * force; + skeleton.motionY = (rand.nextGaussian() + 1) * force; + skeleton.motionZ = rand.nextGaussian() * force; + } Minecraft.getMinecraft().effectRenderer.addEffect(skeleton); } } @@ -161,7 +179,7 @@ public class SkeletonCreator implements IParticleCreator { skullanizer.put(EntityDummy.class.getSimpleName(), BONES_DUMMY); //techguns compat, for some reason - //not alwayss accurate because of variable arm position, but better than nothing + //not always accurate because of variable arm position, but better than nothing skullanizer.put("ArmySoldier", BONES_ZOMBIE); skullanizer.put("PsychoSteve", BONES_ZOMBIE); skullanizer.put("SkeletonSoldier", BONES_ZOMBIE); diff --git a/src/main/resources/assets/hbm/textures/particle/skeleton_blood.png b/src/main/resources/assets/hbm/textures/particle/skeleton_blood.png new file mode 100644 index 0000000000000000000000000000000000000000..1ecde389ec204b0f979ee57f2dc7546007e155b8 GIT binary patch literal 2411 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/particle/skoilet_blood.png b/src/main/resources/assets/hbm/textures/particle/skoilet_blood.png new file mode 100644 index 0000000000000000000000000000000000000000..bd714fb71fdbbb0a3a6ea95696a702b1133e0f23 GIT binary patch literal 4218 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 QdjJ3c07*qoM6N<$f(RiX1^@s6 literal 0 HcmV?d00001