offsets and casing ejection sillies

This commit is contained in:
Boblet 2024-10-03 16:28:15 +02:00
parent 109e710112
commit c8d40f0d35
26 changed files with 285 additions and 90 deletions

View File

@ -5,7 +5,6 @@ import com.hbm.handler.MultiblockHandlerXR;
import com.hbm.tileentity.machine.rbmk.TileEntityCraneConsole;
import api.hbm.block.IToolable;
import api.hbm.block.IToolable.ToolType;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;

View File

@ -42,7 +42,7 @@ public class RotaryFurnaceRecipes extends SerializableRecipe {
recipes.add(new RotaryFurnaceRecipe(new MaterialStack(MAT_STEEL, INGOT.q(3)), 100, 100, new OreDictStack(IRON.fragment(), 9), new OreDictStack(ANY_COKE.gem())));
recipes.add(new RotaryFurnaceRecipe(new MaterialStack(MAT_STEEL, INGOT.q(4)), 200, 100, new OreDictStack(IRON.fragment(), 9), new OreDictStack(ANY_COKE.gem()), new ComparableStack(ModItems.powder_flux)));
recipes.add(new RotaryFurnaceRecipe(new MaterialStack(MAT_DESH, INGOT.q(1)), 100, 200, new FluidStack(Fluids.MERCURY, 100), new ComparableStack(ModItems.powder_desh_mix), new OreDictStack(COAL.dust())));
recipes.add(new RotaryFurnaceRecipe(new MaterialStack(MAT_DESH, INGOT.q(1)), 100, 200, new FluidStack(Fluids.LIGHTOIL, 100), new ComparableStack(ModItems.powder_desh_ready)));
recipes.add(new RotaryFurnaceRecipe(new MaterialStack(MAT_SATURN, INGOT.q(2)), 200, 400, new FluidStack(Fluids.HEATINGOIL, 250), new OreDictStack(DURA.dust(), 2), new OreDictStack(CU.dust())));
recipes.add(new RotaryFurnaceRecipe(new MaterialStack(MAT_GUNMETAL, INGOT.q(4)), 200, 100, new OreDictStack(CU.ingot(), 3), new OreDictStack(AL.ingot(), 1)));

View File

@ -106,6 +106,7 @@ public class GunConfig {
public GunConfig jam(int jam) { this.jamDuration_DNA = jam; return this; }
public GunConfig crosshair(Crosshair crosshair) { this.crosshair_DNA = crosshair; return this; }
public GunConfig smoke(boolean doesSmoke) { this.doesSmoke_DNA = doesSmoke; return this; }
public GunConfig reloadSequential(boolean flag) { this.reloadAnimationsSequential_DNA = flag; return this; }
public GunConfig orchestra(BiConsumer<ItemStack, LambdaContext> orchestra) { this.orchestra_DNA = orchestra; return this; }

View File

@ -8,6 +8,7 @@ import com.hbm.items.weapon.sedna.ItemGunBaseNT.LambdaContext;
import com.hbm.items.weapon.sedna.mags.IMagazine;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Vec3;
/**
* Receivers are the gun's "moving parts", i.e. they determine things like base damage, spread, the ejector and the magazine. Think of this class like the
@ -30,6 +31,7 @@ public class Receiver {
public static final String F_FIREVOLUME = "F_FIREVOLUME";
public static final String F_FIREPITCH = "F_FIREPITCH";
public static final String O_MAGAZINE = "O_MAGAZINE";
public static final String O_PROJECTILEOFFSET = "O_PROJECTILEOFFSET";
public static final String FUN_CANFIRE = "FUN_CANFIRE";
public static final String CON_ONFIRE = "CON_ONFIRE";
public static final String CON_ONRECOIL = "CON_ONRECOIL";
@ -52,40 +54,43 @@ public class Receiver {
protected float fireVolume_DNA = 1.0F;
protected float firePitch_DNA = 1.0F;
protected IMagazine magazine_DNA;
protected Vec3 projectileOffset_DNA = Vec3.createVectorHelper(0, 0, 0);
protected BiFunction<ItemStack, LambdaContext, Boolean> canFire_DNA;
protected BiConsumer<ItemStack, LambdaContext> onFire_DNA;
protected BiConsumer<ItemStack, LambdaContext> onRecoil_DNA;
/* GETTERS */
public float getBaseDamage(ItemStack stack) { return WeaponUpgradeManager.eval(this.baseDamage_DNA, stack, F_BASEDAMAGE, this); }
public int getDelayAfterFire(ItemStack stack) { return WeaponUpgradeManager.eval(this.delayAfterFire_DNA, stack, I_DELAYAFTERFIRE, this); }
public int getRoundsPerCycle(ItemStack stack) { return WeaponUpgradeManager.eval(this.roundsPerCycle_DNA, stack, I_ROUNDSPERCYCLE, this); }
public float getGunSpread(ItemStack stack) { return WeaponUpgradeManager.eval(this.spreadModExtra_DNA, stack, F_SPREADMOD, this); }
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); }
public float getFirePitch(ItemStack stack) { return WeaponUpgradeManager.eval(this.firePitch_DNA, stack, F_FIREPITCH, this); }
public IMagazine getMagazine(ItemStack stack) { return WeaponUpgradeManager.eval(this.magazine_DNA, stack, O_MAGAZINE, this); }
public float getBaseDamage(ItemStack stack) { return WeaponUpgradeManager.eval(this.baseDamage_DNA, stack, F_BASEDAMAGE, this); }
public int getDelayAfterFire(ItemStack stack) { return WeaponUpgradeManager.eval(this.delayAfterFire_DNA, stack, I_DELAYAFTERFIRE, this); }
public int getRoundsPerCycle(ItemStack stack) { return WeaponUpgradeManager.eval(this.roundsPerCycle_DNA, stack, I_ROUNDSPERCYCLE, this); }
public float getGunSpread(ItemStack stack) { return WeaponUpgradeManager.eval(this.spreadModExtra_DNA, stack, F_SPREADMOD, this); }
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); }
public float getFirePitch(ItemStack stack) { return WeaponUpgradeManager.eval(this.firePitch_DNA, stack, F_FIREPITCH, this); }
public IMagazine getMagazine(ItemStack stack) { return WeaponUpgradeManager.eval(this.magazine_DNA, stack, O_MAGAZINE, this); }
public Vec3 getProjectileOffset(ItemStack stack) { return WeaponUpgradeManager.eval(this.projectileOffset_DNA, stack, O_PROJECTILEOFFSET, this); }
public BiFunction<ItemStack, LambdaContext, Boolean> getCanFire(ItemStack stack) { return WeaponUpgradeManager.eval(this.canFire_DNA, stack, FUN_CANFIRE, this); }
public BiConsumer<ItemStack, LambdaContext> getOnFire(ItemStack stack) { return WeaponUpgradeManager.eval(this.onFire_DNA, stack, CON_ONFIRE, this); }
public BiConsumer<ItemStack, LambdaContext> getRecoil(ItemStack stack) { return WeaponUpgradeManager.eval(this.onRecoil_DNA, stack, CON_ONRECOIL, 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 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 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 offset(double f, double u, double s) { this.projectileOffset_DNA = Vec3.createVectorHelper(f, u, s); 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

@ -40,6 +40,7 @@ public class GunFactory {
.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))
.offset(0.75, -0.0625, -0.3125D)
.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)
@ -55,14 +56,8 @@ public class GunFactory {
}
public static enum EnumAmmo {
STONE,
STONE_AP,
STONE_IRON,
STONE_SHOT,
M357_SP,
M357_FMJ,
M357_JHP,
M357_AP,
M357_EXPRESS,
STONE, STONE_AP, STONE_IRON, STONE_SHOT,
M357_SP, M357_FMJ, M357_JHP, M357_AP, M357_EXPRESS,
M44_SP, M44_FMJ, M44_JHP, M44_AP, M44_EXPRESS,
}
}

View File

@ -63,6 +63,7 @@ public class GunStateDecider {
if(cfg.getReceivers(stack)[recIndex].getMagazine(stack).canReload(stack, player)) {
ItemGunBaseNT.setState(stack, GunState.RELOADING);
ItemGunBaseNT.setTimer(stack, cfg.getReceivers(stack)[recIndex].getReloadDuration(stack));
ItemGunBaseNT.playAnimation(player, stack, AnimType.RELOAD_CYCLE);
//if no more reloading can be done, go idle
} else {
@ -73,6 +74,7 @@ public class GunStateDecider {
} else {
ItemGunBaseNT.setState(stack, GunState.IDLE);
ItemGunBaseNT.setTimer(stack, 0);
ItemGunBaseNT.playAnimation(player, stack, AnimType.RELOAD_END);
}
}
}

View File

@ -18,6 +18,7 @@ import com.hbm.render.anim.HbmAnimations.AnimType;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Vec3;
/**
* "LEGO" - i.e. standardized building blocks which can be used to set up gun configs easily.
@ -39,11 +40,12 @@ public class Lego {
if(state == GunState.IDLE) {
ItemGunBaseNT.setIsAiming(stack, false);
IMagazine mag = rec.getMagazine(stack);
if(rec.getMagazine(stack).canReload(stack, ctx.player)) {
if(mag.canReload(stack, ctx.player)) {
ItemGunBaseNT.setState(stack, GunState.RELOADING);
ItemGunBaseNT.setTimer(stack, rec.getReloadDuration(stack));
ItemGunBaseNT.playAnimation(player, stack, AnimType.RELOAD);
ItemGunBaseNT.playAnimation(player, stack, mag.getAmount(stack) == 0 ? AnimType.RELOAD_EMPTY : AnimType.RELOAD);
} else {
ItemGunBaseNT.playAnimation(player, stack, AnimType.INSPECT);
}
@ -104,19 +106,23 @@ public class Lego {
EntityPlayer player = ctx.player;
ItemGunBaseNT.playAnimation(player, stack, AnimType.CYCLE);
double sideOffset = ItemGunBaseNT.getIsAiming(stack) ? 0 : -0.3125D;
float aim = ItemGunBaseNT.getIsAiming(stack) ? 0.25F : 1F;
Receiver primary = ctx.config.getReceivers(stack)[0];
IMagazine mag = primary.getMagazine(stack);
BulletConfig config = (BulletConfig) mag.getType(stack);
Vec3 offset = primary.getProjectileOffset(stack);
double forwardOffset = offset.xCoord;
double heightOffset = offset.yCoord;
double sideOffset = ItemGunBaseNT.getIsAiming(stack) ? 0 : offset.zCoord;
int projectiles = config.projectilesMin;
if(config.projectilesMax > config.projectilesMin) projectiles += player.getRNG().nextInt(config.projectilesMax - config.projectilesMin + 1);
for(int i = 0; i < projectiles; i++) {
float damage = primary.getBaseDamage(stack) * getStandardWearDamage(stack, ctx.config);
float spread = primary.getGunSpread(stack) * aim + getStandardWearSpread(stack, ctx.config) * 0.125F;
EntityBulletBaseMK4 mk4 = new EntityBulletBaseMK4(player, config, damage, spread, sideOffset, -0.0625, 0.75);
EntityBulletBaseMK4 mk4 = new EntityBulletBaseMK4(player, config, damage, spread, sideOffset, heightOffset, forwardOffset);
player.worldObj.spawnEntityInWorld(mk4);
}

View File

@ -8,11 +8,16 @@ 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.particle.SpentCasing;
import com.hbm.particle.helper.CasingCreator;
import com.hbm.render.anim.HbmAnimations.AnimType;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/** Orchestras are server-side components that run along client-side animations.
* The orchestra only knows what animation is or was playing and how long it started, but not if it is still active.
* Orchestras are useful for things like playing server-side sound, spawning casings or sending particle packets.*/
public class Orchestras {
public static BiConsumer<ItemStack, LambdaContext> DEBUG_ORCHESTRA = (stack, ctx) -> {
@ -103,26 +108,25 @@ public class Orchestras {
EntityPlayer player = ctx.player;
AnimType type = ItemGunBaseNT.getLastAnim(stack);
int timer = ItemGunBaseNT.getAnimTimer(stack);
boolean aiming = ItemGunBaseNT.getIsAiming(stack);
if(type == AnimType.RELOAD) {
if(timer == 2) player.worldObj.playSoundAtEntity(player, "hbm:weapon.reload.magSmallRemove", 1F, 1F);
if(timer == 36) player.worldObj.playSoundAtEntity(player, "hbm:weapon.reload.magSmallInsert", 1F, 1F);
if(timer == 44) player.worldObj.playSoundAtEntity(player, "hbm:weapon.reload.revolverClose", 1F, 1F);
}
if(type == AnimType.CYCLE) {
if(timer == 14) {
SpentCasing casing = ctx.config.getReceivers(stack)[0].getMagazine(stack).getCasing(stack);
casing.setupSmoke(1F, 0.5D, 60, 20);
CasingCreator.composeEffect(player.worldObj, player, 0.5, -0.125, aiming ? -0.125 : -0.375D, 0, 0.12, -0.12, casing.getName());
}
if(timer == 12) player.worldObj.playSoundAtEntity(player, "hbm:weapon.reload.leverCock", 1F, 1F);
}
if(type == AnimType.CYCLE_DRY) {
if(timer == 2) player.worldObj.playSoundAtEntity(player, "hbm:weapon.reload.dryFireClick", 1F, 1F);
if(timer == 14) player.worldObj.playSoundAtEntity(player, "hbm:weapon.reload.revolverCock", 1F, 0.9F);
if(timer == 12) player.worldObj.playSoundAtEntity(player, "hbm:weapon.reload.leverCock", 1F, 1F);
}
if(type == AnimType.INSPECT) {
if(timer == 2) player.worldObj.playSoundAtEntity(player, "hbm:weapon.reload.magSmallRemove", 1F, 1F);
if(timer == 24) player.worldObj.playSoundAtEntity(player, "hbm:weapon.reload.revolverClose", 1F, 1F);
}
if(type == AnimType.JAMMED) {
if(timer == 12) player.worldObj.playSoundAtEntity(player, "hbm:weapon.reload.magSmallRemove", 1F, 1F);
if(timer == 34) player.worldObj.playSoundAtEntity(player, "hbm:weapon.reload.revolverClose", 1F, 1F);
}
};
}

View File

@ -38,6 +38,7 @@ public class XFactory357 {
.rec(new Receiver(0)
.dmg(10F).delay(16).reload(55).sound("hbm:weapon.fire.blackPowder", 1.0F, 1.0F)
.mag(new MagazineFullReload(0, 6).addConfigs(m357_sp, m357_fmj, m357_jhp, m357_ap, m357_express))
.offset(0.75, -0.0625, -0.3125D)
.canFire(Lego.LAMBDA_STANDARD_CAN_FIRE).fire(Lego.LAMBDA_STANDARD_FIRE).recoil(Lego.LAMBDA_STANDARD_RECOIL))
.setupStandardConfiguration().anim(LAMBDA_ATLAS_ANIMS)
).setUnlocalizedName("gun_atlas").setTextureName(RefStrings.MODID + ":gun_darter");

View File

@ -9,8 +9,10 @@ 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.factory.GunFactory.EnumAmmo;
import com.hbm.items.weapon.sedna.mags.MagazineFullReload;
import com.hbm.items.weapon.sedna.mags.MagazineSingleReload;
import com.hbm.lib.RefStrings;
import com.hbm.particle.SpentCasing;
import com.hbm.particle.SpentCasing.CasingType;
import com.hbm.render.anim.BusAnimation;
import com.hbm.render.anim.BusAnimationSequence;
import com.hbm.render.anim.BusAnimationKeyframe.IType;
@ -27,17 +29,24 @@ public class XFactory44 {
public static BulletConfig m44_express;
public static void init() {
m44_sp = new BulletConfig().setItem(EnumAmmo.M357_SP);
m44_fmj = new BulletConfig().setItem(EnumAmmo.M357_FMJ).setDamage(0.8F).setArmorPiercing(0.1F);
m44_jhp = new BulletConfig().setItem(EnumAmmo.M357_JHP).setDamage(1.5F).setArmorPiercing(-0.25F);
m44_ap = new BulletConfig().setItem(EnumAmmo.M357_AP).setDoesPenetrate(true).setDamageFalloutByPen(false).setDamage(1.5F);
m44_express = new BulletConfig().setItem(EnumAmmo.M357_EXPRESS).setDoesPenetrate(true).setDamage(1.5F).setArmorPiercing(0.1F).setWear(1.5F);
SpentCasing casing44 = new SpentCasing(CasingType.STRAIGHT).setColor(SpentCasing.COLOR_CASE_BRASS).setupSmoke(1F, 0.5D, 60, 20);
m44_sp = new BulletConfig().setItem(EnumAmmo.M44_SP)
.setCasing(casing44.clone().register("m44"));
m44_fmj = new BulletConfig().setItem(EnumAmmo.M44_FMJ).setDamage(0.8F).setArmorPiercing(0.1F)
.setCasing(casing44.clone().register("m44fmj"));
m44_jhp = new BulletConfig().setItem(EnumAmmo.M44_JHP).setDamage(1.5F).setArmorPiercing(-0.25F)
.setCasing(casing44.clone().register("m44jhp"));
m44_ap = new BulletConfig().setItem(EnumAmmo.M44_AP).setDoesPenetrate(true).setDamageFalloutByPen(false).setDamage(1.5F)
.setCasing(casing44.clone().setColor(SpentCasing.COLOR_CASE_44).register("m44ap"));
m44_express = new BulletConfig().setItem(EnumAmmo.M44_EXPRESS).setDoesPenetrate(true).setDamage(1.5F).setArmorPiercing(0.1F).setWear(1.5F)
.setCasing(casing44.clone().register("m44express"));
ModItems.gun_henry = new ItemGunBaseNT(new GunConfig()
.dura(300).draw(15).inspect(23).jam(45).crosshair(Crosshair.CIRCLE).smoke(true).orchestra(Orchestras.ORCHESTRA_HENRY)
.dura(300).draw(15).inspect(23).jam(45).reloadSequential(true).crosshair(Crosshair.CIRCLE).smoke(true).orchestra(Orchestras.ORCHESTRA_HENRY)
.rec(new Receiver(0)
.dmg(12F).delay(16).reload(55).sound("hbm:weapon.fire.blackPowder", 1.0F, 1.0F)
.mag(new MagazineFullReload(0, 6).addConfigs(m44_sp, m44_fmj, m44_jhp, m44_ap, m44_express))
.dmg(12F).delay(16).reload(10).sound("hbm:weapon.fire.blackPowder", 1.0F, 1.0F)
.mag(new MagazineSingleReload(0, 14).addConfigs(m44_sp, m44_fmj, m44_jhp, m44_ap, m44_express))
.offset(0.75, -0.0625, -0.3125D)
.canFire(Lego.LAMBDA_STANDARD_CAN_FIRE).fire(Lego.LAMBDA_STANDARD_FIRE).recoil(Lego.LAMBDA_STANDARD_RECOIL))
.setupStandardConfiguration().anim(LAMBDA_HENRY_ANIMS)
).setUnlocalizedName("gun_henry").setTextureName(RefStrings.MODID + ":gun_darter");
@ -54,8 +63,13 @@ public class XFactory44 {
.addBus("LEVER", new BusAnimationSequence().addPos(0, 0, 0, 600).addPos(-90, 0, 0, 200).addPos(0, 0, 0, 200))
.addBus("TURN", new BusAnimationSequence().addPos(0, 0, 0, 600).addPos(0, 0, 45, 200, IType.SIN_DOWN).addPos(0, 0, 0, 200, IType.SIN_UP))
.addBus("HAMMER", new BusAnimationSequence().addPos(30, 0, 0, 50).addPos(30, 0, 0, 550).addPos(0, 0, 0, 200));
case CYCLE_DRY: return new BusAnimation();
case CYCLE_DRY: return new BusAnimation()
.addBus("LEVER", new BusAnimationSequence().addPos(0, 0, 0, 600).addPos(-90, 0, 0, 200).addPos(0, 0, 0, 200))
.addBus("TURN", new BusAnimationSequence().addPos(0, 0, 0, 600).addPos(0, 0, 45, 200, IType.SIN_DOWN).addPos(0, 0, 0, 200, IType.SIN_UP))
.addBus("HAMMER", new BusAnimationSequence().addPos(30, 0, 0, 50).addPos(30, 0, 0, 550).addPos(0, 0, 0, 200));
case RELOAD: return new BusAnimation();
case RELOAD_CYCLE: return new BusAnimation();
case RELOAD_END: return new BusAnimation();
case INSPECT: return new BusAnimation();
case JAMMED: return new BusAnimation();
}

View File

@ -1,5 +1,7 @@
package com.hbm.items.weapon.sedna.mags;
import com.hbm.particle.SpentCasing;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
@ -29,4 +31,6 @@ public interface IMagazine<T> {
public ItemStack getIconForHUD(ItemStack stack);
/** It explains itself */
public String reportAmmoStateForHUD(ItemStack stack);
/** Casing config to use then ejecting */
public SpentCasing getCasing(ItemStack stack);
}

View File

@ -0,0 +1,74 @@
package com.hbm.items.weapon.sedna.mags;
import com.hbm.items.weapon.sedna.BulletConfig;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/** Uses individual bullets which are loaded all at once */
public class MagazineSingleReload extends MagazineSingleTypeBase {
public MagazineSingleReload(int index, int capacity) {
super(index, capacity);
}
/** Returns true if the player has the same ammo if partially loaded, or any valid ammo if not */
@Override
public boolean canReload(ItemStack stack, EntityPlayer player) {
if(this.getAmount(stack) >= this.getCapacity(stack)) return false;
for(ItemStack slot : player.inventory.mainInventory) {
if(slot != null) {
if(this.getAmount(stack) == 0) {
for(BulletConfig config : this.acceptedBullets) {
if(config.ammo.matchesRecipe(slot, true)) return true;
}
} else {
BulletConfig config = this.getType(stack);
if(config == null) { config = this.acceptedBullets.get(0); this.setType(stack, config); }
if(config.ammo.matchesRecipe(slot, true)) return true;
}
}
}
return false;
}
/** Reloads all rounds at once. If the mag is empty, the mag's type will change to the first valid ammo type */
@Override
public void reloadAction(ItemStack stack, EntityPlayer player) {
for(int i = 0; i < player.inventory.mainInventory.length; i++) {
ItemStack slot = player.inventory.mainInventory[i];
if(slot != null) {
//mag is empty, assume next best type
if(this.getAmount(stack) == 0) {
for(BulletConfig config : this.acceptedBullets) {
if(config.ammo.matchesRecipe(slot, true)) {
this.setType(stack, config);
this.setAmount(stack, 1);
player.inventory.decrStackSize(i, 1);
return;
}
}
//mag has a type set, only load that
} else {
BulletConfig config = this.getType(stack);
if(config == null) { config = this.acceptedBullets.get(0); this.setType(stack, config); } //fixing broken NBT
if(config.ammo.matchesRecipe(slot, true)) {
int alreadyLoaded = this.getAmount(stack);
this.setAmount(stack, alreadyLoaded + 1);
player.inventory.decrStackSize(i, 1);
return;
}
}
}
}
}
}

View File

@ -5,6 +5,7 @@ import java.util.List;
import com.hbm.items.weapon.sedna.BulletConfig;
import com.hbm.items.weapon.sedna.ItemGunBaseNT;
import com.hbm.particle.SpentCasing;
import net.minecraft.item.ItemStack;
@ -57,6 +58,11 @@ public abstract class MagazineSingleTypeBase implements IMagazine<BulletConfig>
return getAmount(stack) + " / " + getCapacity(stack);
}
@Override
public SpentCasing getCasing(ItemStack stack) {
return this.getType(stack).casing;
}
@Override public int getCapacity(ItemStack stack) { return capacity; }
@Override public int getAmount(ItemStack stack) { return getMagCount(stack, index); }
@Override public void setAmount(ItemStack stack, int amount) { setMagCount(stack, index, amount); }

View File

@ -89,8 +89,7 @@ import com.hbm.items.ModItems;
import com.hbm.items.weapon.sedna.factory.GunFactoryClient;
import com.hbm.lib.RefStrings;
import com.hbm.particle.*;
import com.hbm.particle.helper.ExplosionCreator;
import com.hbm.particle.helper.IParticleCreator;
import com.hbm.particle.helper.*;
import com.hbm.particle.psys.engine.EventHandlerParticleEngine;
import com.hbm.render.anim.*;
import com.hbm.render.anim.HbmAnimations.Animation;
@ -989,6 +988,7 @@ public class ClientProxy extends ServerProxy {
static {
particleCreators.put("explosionLarge", new ExplosionCreator());
particleCreators.put("casingNT", new CasingCreator());
}
//mk3, only use this one

View File

@ -42,8 +42,6 @@ public class ParticleSpentCasing extends EntityFX {
private boolean isSmoking;
private float momentumPitch, momentumYaw;
private boolean onGroundPreviously = false;
private double maxHeight;
public ParticleSpentCasing(TextureManager textureManager, World world, double x, double y, double z, double mx, double my, double mz, float momentumPitch, float momentumYaw, SpentCasing config) {
super(world, x, y, z, 0, 0, 0);
@ -66,9 +64,7 @@ public class ParticleSpentCasing extends EntityFX {
this.motionY = my;
this.motionZ = mz;
particleGravity = 8F;
maxHeight = y;
particleGravity = 1F;
}
@Override
@ -78,24 +74,34 @@ public class ParticleSpentCasing extends EntityFX {
@Override
public void onUpdate() {
super.onUpdate();
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
if(motionY > 0 && posY > maxHeight)
maxHeight = posY;
if(this.particleAge++ >= this.particleMaxAge) {
this.setDead();
}
if(!onGroundPreviously && onGround)
tryPlayBounceSound();
this.motionY -= 0.04D * (double) this.particleGravity;
double prevMotionY = this.motionY;
this.moveEntity(this.motionX, this.motionY, this.motionZ);
this.motionX *= 0.98D;
this.motionY *= 0.98D;
this.motionZ *= 0.98D;
if(!onGroundPreviously && onGround) {
if(this.onGround) {
this.motionX *= 0.7D;
this.motionZ *= 0.7D;
}
if(onGround) {
this.onGround = false;
motionY = prevMotionY * -0.5;
this.rotationPitch = 0;
//momentumPitch = (float) rand.nextGaussian() * config.getBouncePitch();
//momentumYaw = (float) rand.nextGaussian() * config.getBounceYaw();
onGroundPreviously = true;
motionY = Math.log10(maxHeight - posY + 2);
momentumPitch = (float) rand.nextGaussian() * config.getBouncePitch();
momentumYaw = (float) rand.nextGaussian() * config.getBounceYaw();
maxHeight = posY;
} else if(onGroundPreviously && !onGround) {
onGroundPreviously = false;
}
if(particleAge > maxSmokeGen && !smokeNodes.isEmpty())
@ -193,8 +199,6 @@ public class ParticleSpentCasing extends EntityFX {
GL11.glPushMatrix();
GL11.glTranslated(pX - dX, pY - dY - this.height / 4, pZ - dZ);
//GL11.glScalef(dScale, dScale, dScale);
//GL11.glScalef(config.getScaleX(), config.getScaleY(), config.getScaleZ());
if(!smokeNodes.isEmpty()) {
tessellator.startDrawingQuads();
@ -271,17 +275,17 @@ public class ParticleSpentCasing extends EntityFX {
@Override
@SideOnly(Side.CLIENT)
public int getBrightnessForRender(float p_70070_1_) {
int i = MathHelper.floor_double(this.posX);
int j = MathHelper.floor_double(this.posZ);
int x = MathHelper.floor_double(this.posX);
int z = MathHelper.floor_double(this.posZ);
if(this.worldObj.blockExists(i, 0, j)) {
if(this.worldObj.blockExists(x, 0, z)) {
double d0 = (this.boundingBox.maxY - this.boundingBox.minY) * 0.66D;
int k = MathHelper.floor_double(this.posY - (double) this.yOffset + d0);
return this.worldObj.getLightBrightnessForSkyBlocks(i, k, j, 0);
int y = MathHelper.floor_double(this.posY - (double) this.yOffset + d0);
return this.worldObj.getLightBrightnessForSkyBlocks(x, y, z, 0);
} else {
return 0;
}
}
}
}
private void tryPlayBounceSound() {

View File

@ -0,0 +1,65 @@
package com.hbm.particle.helper;
import java.util.Random;
import com.hbm.particle.ParticleSpentCasing;
import com.hbm.particle.SpentCasing;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
public class CasingCreator implements IParticleCreator {
public static void composeEffect(World world, EntityPlayer player, double frontOffset, double heightOffset, double sideOffset, double frontMotion, double heightMotion, double sideMotion, String casing) {
if(player.isSneaking()) heightOffset -= 0.075F;
Vec3 offset = Vec3.createVectorHelper(sideOffset, heightOffset, frontOffset);
offset.rotateAroundX(-player.rotationPitch / 180F * (float) Math.PI);
offset.rotateAroundY(-player.rotationYaw / 180F * (float) Math.PI);
double x = player.posX + offset.xCoord;
double y = player.posY + player.getEyeHeight() + offset.yCoord;
double z = player.posZ + offset.zCoord;
Vec3 motion = Vec3.createVectorHelper(sideMotion, heightMotion, frontMotion);
motion.rotateAroundX(-player.rotationPitch / 180F * (float) Math.PI);
motion.rotateAroundY(-player.rotationYaw / 180F * (float) Math.PI);
double mX = player.motionX + motion.xCoord;
double mY = player.motionY + motion.yCoord;
double mZ = player.motionZ + motion.zCoord;
NBTTagCompound data = new NBTTagCompound();
data.setString("type", "casingNT");
data.setDouble("mX", mX);
data.setDouble("mY", mY);
data.setDouble("mZ", mZ);
data.setFloat("yaw", player.rotationYaw);
data.setFloat("pitch", player.rotationPitch);
data.setString("name", casing);
IParticleCreator.sendPacket(world, x, y, z, 50, data);
}
@Override
public void makeParticle(World world, EntityPlayer player, TextureManager texman, Random rand, double x, double y, double z, NBTTagCompound data) {
String name = data.getString("name");
SpentCasing casingConfig = SpentCasing.casingMap.get(name);
double mX = data.getDouble("mX");
double mY = data.getDouble("mY");
double mZ = data.getDouble("mZ");
float yaw = data.getFloat("yaw");
float pitch = data.getFloat("pitch");
ParticleSpentCasing casing = new ParticleSpentCasing(texman, world, x, y, z, mX, mY, mZ, 0, 0, casingConfig);
casing.prevRotationYaw = casing.rotationYaw = yaw;
casing.prevRotationPitch = casing.rotationPitch = pitch;
Minecraft.getMinecraft().effectRenderer.addEffect(casing);
}
}

View File

@ -18,8 +18,8 @@ public class HbmAnimations {
public static final Animation[] hotbar = new Animation[9];
public static enum AnimType {
RELOAD, //animation for reloading the weapon
RELOAD_EMPTY, //animation for reloading from empty
RELOAD, //either a full reload or start of a reload
RELOAD_EMPTY, //same as reload, but the mag is completely empty
RELOAD_CYCLE, //animation that plays for every individual round (for shotguns and similar single round loading weapons)
RELOAD_END, //animation for transitioning from our RELOAD_CYCLE to idle
CYCLE, //animation for every firing cycle

View File

@ -53,6 +53,13 @@ public class ItemRenderHenry extends ItemRenderWeaponBase {
GL11.glRotated(equip[0], -1, 0, 0);
GL11.glTranslated(0, -2, 4);
GL11.glPushMatrix();
GL11.glTranslated(0, 1, 8);
GL11.glRotated(turn[2], 0, 0, -1);
GL11.glRotated(90, 0, 1, 0);
this.renderSmokeNodes(gun.smokeNodes, 0.25D);
GL11.glPopMatrix();
ResourceManager.henry.renderPart("Gun");
GL11.glPushMatrix();

View File

@ -28,8 +28,6 @@ import net.minecraftforge.common.util.ForgeDirection;
import java.util.List;
import org.lwjgl.opengl.GL11;
@Optional.InterfaceList({@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "OpenComputers")})
public class TileEntityCraneConsole extends TileEntity implements INBTPacketReceiver, SimpleComponent, CompatHandler.OCComponent {

View File

@ -1153,6 +1153,11 @@ item.ammo_standard.m357_express.name=.357 Magnumkugel (VMG Express)
item.ammo_standard.m357_fmj.name=.357 Magnumkugel (Vollmantelgeschoss)
item.ammo_standard.m357_jhp.name=.357 Magnumkugel (Hohlspitz)
item.ammo_standard.m357_sp.name=.357 Magnumkugel (Teilmantelgeschoss)
item.ammo_standard.m44_ap.name=.44 Magnumkugel (Panzerbrechend)
item.ammo_standard.m44_express.name=.44 Magnumkugel (VMG Express)
item.ammo_standard.m44_fmj.name=.44 Magnumkugel (Vollmantelgeschoss)
item.ammo_standard.m44_jhp.name=.44 Magnumkugel (Hohlspitz)
item.ammo_standard.m44_sp.name=.44 Magnumkugel (Teilmantelgeschoss)
item.ammo_standard.stone.name=Kugel und Pulver
item.ammo_standard.stone_ap.name=Feuerstein und Pulver
item.ammo_standard.stone_iron.name=Eisenkugel und Pulver

View File

@ -1876,6 +1876,11 @@ item.ammo_standard.m357_express.name=.357 Magnum Round (FMJ Express)
item.ammo_standard.m357_fmj.name=.357 Magnum Round (Full Metal Jacket)
item.ammo_standard.m357_jhp.name=.357 Magnum Round (Jacketed Hollow Point)
item.ammo_standard.m357_sp.name=.357 Magnum Round (Soft Point)
item.ammo_standard.m44_ap.name=.44 Magnum Round (Armor Piercing)
item.ammo_standard.m44_express.name=.44 Magnum Round (FMJ Express)
item.ammo_standard.m44_fmj.name=.44 Magnum Round (Full Metal Jacket)
item.ammo_standard.m44_jhp.name=.44 Magnum Round (Jacketed Hollow Point)
item.ammo_standard.m44_sp.name=.44 Magnum Round (Soft Point)
item.ammo_standard.stone.name=Ball and Powder
item.ammo_standard.stone_ap.name=Flint and Powder
item.ammo_standard.stone_iron.name=Iron Ball and Powder

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B