casing ejectors, bullet ricochet

This commit is contained in:
Bob 2024-09-23 22:39:38 +02:00
parent 42b7d1f657
commit b2c2ce9e4e
9 changed files with 148 additions and 43 deletions

View File

@ -4,6 +4,8 @@ import com.hbm.items.weapon.sedna.BulletConfig;
import com.hbm.lib.ModDamageSource;
import com.hbm.packet.PacketDispatcher;
import com.hbm.packet.toclient.AuxParticlePacketNT;
import com.hbm.util.BobMathUtil;
import com.hbm.util.TrackerUtil;
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
import net.minecraft.entity.EntityLivingBase;
@ -12,12 +14,15 @@ import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.util.ForgeDirection;
public class EntityBulletBaseMK4 extends EntityThrowableInterp {
public BulletConfig config;
public double velocity;
public double prevVelocity;
public int ricochets = 0;
public EntityBulletBaseMK4(World world) {
super(world);
@ -88,25 +93,81 @@ public class EntityBulletBaseMK4 extends EntityThrowableInterp {
this.prevVelocity = this.velocity;
this.velocity = Math.sqrt(dX * dX + dY * dY + dZ * dZ);
if(!this.onGround && velocity > 0) {
float hyp = MathHelper.sqrt_double(dX * dX + dZ * dZ);
this.rotationYaw = (float) (Math.atan2(dX, dZ) * 180.0D / Math.PI);
for(this.rotationPitch = (float) (Math.atan2(dY, (double) hyp) * 180.0D / Math.PI); this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F);
while(this.rotationPitch - this.prevRotationPitch >= 180.0F) this.prevRotationPitch += 360.0F;
while(this.rotationYaw - this.prevRotationYaw < -180.0F) this.prevRotationYaw -= 360.0F;
while(this.rotationYaw - this.prevRotationYaw >= 180.0F) this.prevRotationYaw += 360.0F;
}
if(!worldObj.isRemote && this.ticksExisted > config.expires) this.setDead();
}
@Override
public void setDead() {
super.setDead();
//send a teleport on collision so that the bullets are forced to move even if their lifetime is only 1 tick, letting them render
if(worldObj instanceof WorldServer) TrackerUtil.sendTeleport((WorldServer) worldObj, this);
}
@Override
protected void onImpact(MovingObjectPosition mop) {
if(!worldObj.isRemote) {
if(mop.typeOfHit == mop.typeOfHit.ENTITY && !mop.entityHit.isEntityAlive()) return;
this.setDead();
if(mop.typeOfHit == mop.typeOfHit.BLOCK) {
ForgeDirection dir = ForgeDirection.getOrientation(mop.sideHit);
Vec3 face = Vec3.createVectorHelper(dir.offsetX, dir.offsetY, dir.offsetZ);
Vec3 vel = Vec3.createVectorHelper(motionX, motionY, motionZ).normalize();
double angle = Math.abs(BobMathUtil.getCrossAngle(vel, face) - 90);
if(angle <= config.ricochetAngle) {
this.ricochets++;
if(this.ricochets > this.config.maxRicochetCount) {
this.setPosition(mop.hitVec.xCoord, mop.hitVec.yCoord, mop.hitVec.zCoord);
this.setDead();
}
switch(mop.sideHit) {
case 0: case 1: motionY *= -1; break;
case 2: case 3: motionZ *= -1; break;
case 4: case 5: motionX *= -1; break;
}
worldObj.playSoundAtEntity(this, "hbm:weapon.ricochet", 0.25F, 1.0F);
this.setPosition(mop.hitVec.xCoord, mop.hitVec.yCoord, mop.hitVec.zCoord);
//send a teleport so the ricochet is more accurate instead of the interp smoothing fucking everything up
if(worldObj instanceof WorldServer) TrackerUtil.sendTeleport((WorldServer) worldObj, this);
return;
} else {
this.setPosition(mop.hitVec.xCoord, mop.hitVec.yCoord, mop.hitVec.zCoord);
this.setDead();
}
}
if(mop.typeOfHit == mop.typeOfHit.ENTITY && mop.entityHit.isEntityAlive()) {
mop.entityHit.attackEntityFrom(ModDamageSource.turbofan, 1_000F);
if(mop.typeOfHit == mop.typeOfHit.ENTITY) {
if(!mop.entityHit.isEntityAlive()) return;
NBTTagCompound vdat = new NBTTagCompound();
vdat.setString("type", "giblets");
vdat.setInteger("ent", mop.entityHit.getEntityId());
vdat.setInteger("cDiv", 2);
PacketDispatcher.wrapper.sendToAllAround(
new AuxParticlePacketNT(vdat, mop.entityHit.posX, mop.entityHit.posY + mop.entityHit.height * 0.5, mop.entityHit.posZ),
new TargetPoint(this.dimension, mop.entityHit.posX, mop.entityHit.posY + mop.entityHit.height * 0.5, mop.entityHit.posZ, 150));
if(mop.entityHit.isEntityAlive()) {
mop.entityHit.attackEntityFrom(ModDamageSource.turbofan, 1_000F);
NBTTagCompound vdat = new NBTTagCompound();
vdat.setString("type", "giblets");
vdat.setInteger("ent", mop.entityHit.getEntityId());
vdat.setInteger("cDiv", 2);
PacketDispatcher.wrapper.sendToAllAround(
new AuxParticlePacketNT(vdat, mop.entityHit.posX, mop.entityHit.posY + mop.entityHit.height * 0.5, mop.entityHit.posZ),
new TargetPoint(this.dimension, mop.entityHit.posX, mop.entityHit.posY + mop.entityHit.height * 0.5, mop.entityHit.posZ, 150));
}
}
}
}

View File

@ -235,21 +235,11 @@ public abstract class EntityThrowableNT extends Entity implements IProjectile {
float hyp = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ);
this.rotationYaw = (float) (Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI);
for(this.rotationPitch = (float) (Math.atan2(this.motionY, (double) hyp) * 180.0D / Math.PI); this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F) {
;
}
for(this.rotationPitch = (float) (Math.atan2(this.motionY, (double) hyp) * 180.0D / Math.PI); this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F);
while(this.rotationPitch - this.prevRotationPitch >= 180.0F) {
this.prevRotationPitch += 360.0F;
}
while(this.rotationYaw - this.prevRotationYaw < -180.0F) {
this.prevRotationYaw -= 360.0F;
}
while(this.rotationYaw - this.prevRotationYaw >= 180.0F) {
this.prevRotationYaw += 360.0F;
}
while(this.rotationPitch - this.prevRotationPitch >= 180.0F) this.prevRotationPitch += 360.0F;
while(this.rotationYaw - this.prevRotationYaw < -180.0F) this.prevRotationYaw -= 360.0F;
while(this.rotationYaw - this.prevRotationYaw >= 180.0F) this.prevRotationYaw += 360.0F;
this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F;
this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F;

View File

@ -30,9 +30,9 @@ public class CasingEjector implements Cloneable {
private static int nextId = 0;
private Vec3 posOffset = Vec3.createVectorHelper(0, 0, 0);
private Vec3 initialMotion = Vec3.createVectorHelper(0, 0, 0);
private int casingAmount = 1;
private boolean afterReload = false;
private int delay = 0;
@Deprecated private int casingAmount = 1;
@Deprecated private boolean afterReload = false;
@Deprecated private int delay = 0;
private float randomYaw = 0F;
private float randomPitch = 0F;
@ -61,17 +61,17 @@ public class CasingEjector implements Cloneable {
return this;
}
public CasingEjector setAmount(int am) {
@Deprecated public CasingEjector setAmount(int am) {
this.casingAmount = am;
return this;
}
public CasingEjector setAfterReload() {
@Deprecated public CasingEjector setAfterReload() {
this.afterReload = true;
return this;
}
public CasingEjector setDelay(int delay) {
@Deprecated public CasingEjector setDelay(int delay) {
this.delay = delay;
return this;
}

View File

@ -98,7 +98,7 @@ public class ItemPoolsPile {
//makeshift gun
new ItemPool(POOL_PILE_MAKESHIFT_GUN) {{ this.pool = new WeightedRandomChestContent[] { weighted(ModItems.gun_lever_action, 0, 1, 1, 10) }; }};
new ItemPool(POOL_PILE_MAKESHIFT_WRENCH) {{ this.pool = new WeightedRandomChestContent[] { weighted(ModItems.wrench, 0, 1, 1, 10) }; }};
new ItemPool(POOL_PILE_MAKESHIFT_PLATES) {{ this.pool = new WeightedRandomChestContent[] { weighted(ModItems.plate_combine_steel, 0, 1, 1, 10) }; }};
new ItemPool(POOL_PILE_MAKESHIFT_PLATES) {{ this.pool = new WeightedRandomChestContent[] { weighted(ModItems.plate_steel, 0, 1, 1, 10) }; }};
new ItemPool(POOL_PILE_MAKESHIFT_WIRE) {{ this.pool = new WeightedRandomChestContent[] { weighted(ModItems.wire_fine, Mats.MAT_ALUMINIUM.id, 1, 1, 10) }; }};
new ItemPool(POOL_PILE_NUKE_STORAGE) {{

View File

@ -6,6 +6,7 @@ import java.util.function.BiConsumer;
import com.hbm.entity.projectile.EntityBulletBaseMK4;
import com.hbm.inventory.RecipesCommon.ComparableStack;
import com.hbm.particle.SpentCasing;
import net.minecraft.item.Item;
@ -26,10 +27,14 @@ public class BulletConfig {
public float damageMult = 1.0F;
public float headshotMult = 1.0F;
public float ricochetAngle = 5F;
public int maxRicochetCount = 2;
public double gravity = 0;
public int expires = 100;
public boolean renderRotations = true;
public SpentCasing casing;
public BiConsumer<EntityBulletBaseMK4, Float> renderer;
public BulletConfig() {
@ -45,8 +50,11 @@ public class BulletConfig {
public BulletConfig setProjectiles(int min, int max) { this.projectilesMin = min; this.projectilesMax = max; return this; }
public BulletConfig setDamage(float damageMult) { this.damageMult = damageMult; return this; }
public BulletConfig setHeadshot(float headshotMult) { this.headshotMult = headshotMult; return this; }
public BulletConfig setRicochetAngle(float angle) { this.ricochetAngle = angle; return this; }
public BulletConfig setRicochetCount(int count) { this.maxRicochetCount = count; return this; }
public BulletConfig setGrav(double gravity) { this.gravity = gravity; return this; }
public BulletConfig setLife(int expires) { this.expires = expires; return this; }
public BulletConfig setRenderRotations(boolean rot) { this.renderRotations = rot; return this; }
public BulletConfig setCasing(SpentCasing casing) { this.casing = casing; return this; }
public BulletConfig setRenderer(BiConsumer<EntityBulletBaseMK4, Float> renderer) { this.renderer = renderer; return this; }
}

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
import com.hbm.handler.CasingEjector;
import com.hbm.handler.HbmKeybinds.EnumKeybind;
import com.hbm.interfaces.IItemHUD;
import com.hbm.items.IEquipReceiver;
@ -11,11 +12,13 @@ import com.hbm.items.IKeybindReceiver;
import com.hbm.items.weapon.sedna.hud.IHUDComponent;
import com.hbm.main.MainRegistry;
import com.hbm.packet.PacketDispatcher;
import com.hbm.packet.toclient.AuxParticlePacketNT;
import com.hbm.packet.toclient.GunAnimationPacket;
import com.hbm.render.anim.HbmAnimations.AnimType;
import com.hbm.render.util.RenderScreenOverlay;
import com.hbm.util.EnumUtil;
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.Minecraft;
@ -192,6 +195,22 @@ public class ItemGunBaseNT extends Item implements IKeybindReceiver, IEquipRecei
if(timer > 0) this.setTimer(stack, timer - 1);
if(timer <= 1) config.getDecider(stack).accept(stack, ctx);
}
public static void trySpawnCasing(Entity entity, CasingEjector ejector, BulletConfig bullet, ItemStack stack) {
if(ejector == null) return; //abort if the gun can't eject bullets at all
if(bullet == null) return; //abort if there's no valid bullet cfg
if(bullet.casing == null) return; //abort if the bullet is caseless
NBTTagCompound data = new NBTTagCompound();
data.setString("type", "casing");
data.setFloat("pitch", (float) Math.toRadians(entity.rotationPitch));
data.setFloat("yaw", (float) Math.toRadians(entity.rotationYaw));
data.setBoolean("crouched", entity.isSneaking());
data.setString("name", bullet.casing.getName());
data.setInteger("ej", ejector.getId());
PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, entity.posX, entity.posY + entity.getEyeHeight(), entity.posZ), new TargetPoint(entity.dimension, entity.posX, entity.posY, entity.posZ, 50));
}
// GUN DRAWN //
public static boolean getIsDrawn(ItemStack stack) { return getValueBool(stack, KEY_DRAWN); }

View File

@ -24,6 +24,7 @@ public class Receiver {
public static final String B_REFIREONHOLD = "B_REFIREONHOLD";
public static final String B_DOESDRYFIRE = "B_DOESDRYFIRE";
public static final String O_EJECTOR = "O_EJECTOR";
public static final String B_EJECTONFIRE = "B_EJECTONFIRE";
public static final String I_RELOADDURATION = "I_RELOADDURATION";
public static final String S_FIRESOUND = "S_FIRESOUND";
public static final String F_FIREVOLUME = "F_FIREVOLUME";
@ -44,6 +45,7 @@ public class Receiver {
protected boolean refireOnHold_DNA = false;
protected boolean doesDryFire_DNA = true;
protected CasingEjector ejector_DNA = null;
protected boolean ejectOnFire_DNA = true;
protected int reloadDuration_DNA;
protected String fireSound_DNA;
protected float fireVolume_DNA = 1.0F;
@ -60,6 +62,7 @@ public class Receiver {
public boolean getRefireOnHold(ItemStack stack) { return WeaponUpgradeManager.eval(this.refireOnHold_DNA, stack, B_REFIREONHOLD, this); }
public boolean getDoesDryFire(ItemStack stack) { return WeaponUpgradeManager.eval(this.doesDryFire_DNA, stack, B_DOESDRYFIRE, this); }
public CasingEjector getEjector(ItemStack stack) { return WeaponUpgradeManager.eval(this.ejector_DNA, stack, O_EJECTOR, this); }
public boolean getEjectOnFire(ItemStack stack) { return WeaponUpgradeManager.eval(this.ejectOnFire_DNA, stack, B_EJECTONFIRE, this); }
public int getReloadDuration(ItemStack stack) { return WeaponUpgradeManager.eval(this.reloadDuration_DNA, stack, I_RELOADDURATION, this); }
public String getFireSound(ItemStack stack) { return WeaponUpgradeManager.eval(this.fireSound_DNA, stack, S_FIRESOUND, this); }
public float getFireVolume(ItemStack stack) { return WeaponUpgradeManager.eval(this.fireVolume_DNA, stack, F_FIREVOLUME, this); }
@ -70,15 +73,16 @@ public class Receiver {
public BiConsumer<ItemStack, LambdaContext> getOnFire(ItemStack stack) { return WeaponUpgradeManager.eval(this.onFire_DNA, stack, CON_ONFIRE, this); }
/* SETTERS */
public Receiver dmg(float dmg) { this.baseDamage_DNA = dmg; return this; }
public Receiver delay(int delay) { this.delayAfterFire_DNA = delay; return this; }
public Receiver rounds(int rounds) { this.roundsPerCycle_DNA = rounds; return this; }
public Receiver spread(int spread) { this.spreadModExtra_DNA = spread; return this; }
public Receiver auto(boolean auto) { this.refireOnHold_DNA = auto; return this; }
public Receiver dryfire(boolean dryfire) { this.doesDryFire_DNA = dryfire; return this; }
public Receiver burst(CasingEjector ejector) { this.ejector_DNA = ejector; return this; }
public Receiver reload(int delay) { this.reloadDuration_DNA = delay; return this; }
public Receiver mag(IMagazine magazine) { this.magazine_DNA = magazine; return this; }
public Receiver dmg(float dmg) { this.baseDamage_DNA = dmg; return this; }
public Receiver delay(int delay) { this.delayAfterFire_DNA = delay; return this; }
public Receiver rounds(int rounds) { this.roundsPerCycle_DNA = rounds; return this; }
public Receiver spread(int spread) { this.spreadModExtra_DNA = spread; return this; }
public Receiver auto(boolean auto) { this.refireOnHold_DNA = auto; return this; }
public Receiver dryfire(boolean dryfire) { this.doesDryFire_DNA = dryfire; return this; }
public Receiver ejector(CasingEjector ejector) { this.ejector_DNA = ejector; return this; }
public Receiver ejectOnFire(boolean eject) { this.ejectOnFire_DNA = eject; return this; }
public Receiver reload(int delay) { this.reloadDuration_DNA = delay; return this; }
public Receiver mag(IMagazine magazine) { this.magazine_DNA = magazine; return this; }
public Receiver canFire(BiFunction<ItemStack, LambdaContext, Boolean> lambda) { this.canFire_DNA = lambda; return this; }
public Receiver fire(BiConsumer<ItemStack, LambdaContext> lambda) { this.onFire_DNA = lambda; return this; }

View File

@ -2,6 +2,7 @@ package com.hbm.items.weapon.sedna.factory;
import java.util.function.BiConsumer;
import com.hbm.handler.CasingEjector;
import com.hbm.items.ModItems;
import com.hbm.items.weapon.sedna.BulletConfig;
import com.hbm.items.weapon.sedna.Crosshair;
@ -9,9 +10,12 @@ import com.hbm.items.weapon.sedna.GunConfig;
import com.hbm.items.weapon.sedna.ItemGunBaseNT;
import com.hbm.items.weapon.sedna.Receiver;
import com.hbm.items.weapon.sedna.ItemGunBaseNT.LambdaContext;
import com.hbm.items.weapon.sedna.mags.IMagazine;
import com.hbm.items.weapon.sedna.mags.MagazineFullReload;
import com.hbm.lib.RefStrings;
import com.hbm.main.MainRegistry;
import com.hbm.particle.SpentCasing;
import com.hbm.particle.SpentCasing.CasingType;
import com.hbm.render.anim.HbmAnimations.AnimType;
import net.minecraft.entity.player.EntityPlayer;
@ -22,6 +26,8 @@ public class GunFactory {
public static BulletConfig ammo_debug;
public static BulletConfig ammo_debug_buckshot;
public static SpentCasing CASING44 = new SpentCasing(CasingType.STRAIGHT).setScale(1.5F, 1.0F, 1.5F).setBounceMotion(0.01F, 0.05F).setColor(SpentCasing.COLOR_CASE_44);
public static void init() {
@ -29,8 +35,8 @@ public class GunFactory {
ModItems.ammo_debug = new Item().setUnlocalizedName("ammo_debug").setTextureName(RefStrings.MODID + ":ammo_45");
/// BULLLET CFGS ///
ammo_debug = new BulletConfig().setItem(ModItems.ammo_debug).setSpread(0.01F);
ammo_debug_buckshot = new BulletConfig().setItem(ModItems.ammo_12gauge).setSpread(0.1F).setProjectiles(6, 6);
ammo_debug = new BulletConfig().setItem(ModItems.ammo_debug).setSpread(0.01F).setRicochetAngle(45).setCasing(CASING44.clone().register("DEBUG0"));
ammo_debug_buckshot = new BulletConfig().setItem(ModItems.ammo_12gauge).setSpread(0.1F).setRicochetAngle(45).setProjectiles(6, 6).setCasing(CASING44.clone().register("DEBUG1"));
/// GUNS ///
ModItems.gun_debug = new ItemGunBaseNT(new GunConfig()
@ -38,6 +44,7 @@ public class GunFactory {
.rec(new Receiver(0)
.dmg(10F).delay(14).reload(46).sound("hbm:weapon.44Shoot", 1.0F, 1.0F)
.mag(new MagazineFullReload(0, 12).addConfigs(ammo_debug, ammo_debug_buckshot))
.ejector(new CasingEjector().setMotion(0, -0.1, 0).setAngleRange(0.01F, 0.025F))
.canFire(Lego.LAMBDA_STANDARD_CAN_FIRE).fire(Lego.LAMBDA_STANDARD_FIRE))
.pp(Lego.LAMBDA_STANDARD_CLICK_PRIMARY) .pr(Lego.LAMBDA_STANDARD_RELOAD) .pt(Lego.LAMBDA_TOGGLE_AIM)
.decider(GunStateDecider.LAMBDA_STANDARD_DECIDER)
@ -58,6 +65,14 @@ public class GunFactory {
if(timer == 10) player.worldObj.playSoundAtEntity(player, "hbm:weapon.reload.magSmallRemove", 1F, 1F);
if(timer == 34) player.worldObj.playSoundAtEntity(player, "hbm:weapon.reload.magSmallInsert", 1F, 1F);
if(timer == 40) player.worldObj.playSoundAtEntity(player, "hbm:weapon.reload.revolverClose", 1F, 1F);
if(timer == 20) {
Receiver rec = ctx.config.getReceivers(stack)[0];
IMagazine mag = rec.getMagazine(stack);
CasingEjector ejector = rec.getEjector(stack);
BulletConfig bullet = (BulletConfig) mag.getType(stack);
for(int i = 0; i < mag.getCapacity(stack); i++) ItemGunBaseNT.trySpawnCasing(player, ejector, bullet, stack);
}
}
if(type == AnimType.CYCLE) {
if(timer == 11) player.worldObj.playSoundAtEntity(player, "hbm:weapon.reload.revolverCock", 1F, 1F);

View File

@ -95,6 +95,14 @@ public class ItemRenderDebug extends ItemRenderWeaponBase {
GL11.glPopMatrix();
}
@Override
protected void setupThirdPerson(ItemStack stack) {
super.setupThirdPerson(stack);
GL11.glScaled(0.75, 0.75, 0.75);
GL11.glTranslated(0, 1, 3);
}
@Override
protected void setupInv(ItemStack stack) {
super.setupInv(stack);