mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
a ton of gun stuff
This commit is contained in:
parent
3a81e79554
commit
1384f14fe3
@ -151,6 +151,7 @@ public class EntityMappings {
|
||||
addEntity(EntityGrenadeIFNull.class, "entity_grenade_ironshod_null", 250);
|
||||
addEntity(EntityFallingNuke.class, "entity_falling_bomb", 1000);
|
||||
addEntity(EntityBulletBaseNT.class, "entity_bullet_mk3", 250, false);
|
||||
addEntity(EntityBulletBaseMK4.class, "entity_bullet_mk4", 250, false);
|
||||
addEntity(EntityMinerRocket.class, "entity_miner_lander", 1000);
|
||||
addEntity(EntityFogFX.class, "entity_nuclear_fog", 1000);
|
||||
addEntity(EntityDuchessGambit.class, "entity_duchessgambit", 1000);
|
||||
|
||||
@ -0,0 +1,89 @@
|
||||
package com.hbm.entity.projectile;
|
||||
|
||||
import com.hbm.items.weapon.sedna.BulletConfig;
|
||||
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityBulletBaseMK4 extends EntityThrowableInterp {
|
||||
|
||||
public BulletConfig config;
|
||||
|
||||
public EntityBulletBaseMK4(World world) {
|
||||
super(world);
|
||||
this.renderDistanceWeight = 10.0D;
|
||||
this.setSize(0.5F, 0.5F);
|
||||
}
|
||||
|
||||
public EntityBulletBaseMK4(EntityLivingBase entity, BulletConfig config, float baseDamage, float spreadMod, double sideOffset, double heightOffset, double frontOffset) {
|
||||
this(entity.worldObj);
|
||||
|
||||
this.thrower = entity;
|
||||
this.config = config;
|
||||
|
||||
this.setLocationAndAngles(thrower.posX, thrower.posY + thrower.getEyeHeight(), thrower.posZ, thrower.rotationYaw, thrower.rotationPitch);
|
||||
|
||||
Vec3 offset = Vec3.createVectorHelper(sideOffset, heightOffset, frontOffset);
|
||||
offset.rotateAroundX(-this.rotationPitch / 180F * (float) Math.PI);
|
||||
offset.rotateAroundY(-this.rotationYaw / 180F * (float) Math.PI);
|
||||
|
||||
this.posX += offset.xCoord;
|
||||
this.posY += offset.yCoord;
|
||||
this.posZ += offset.zCoord;
|
||||
|
||||
this.setPosition(this.posX, this.posY, this.posZ);
|
||||
|
||||
this.motionX = -MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI);
|
||||
this.motionZ = MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI);
|
||||
this.motionY = (-MathHelper.sin(this.rotationPitch / 180.0F * (float) Math.PI));
|
||||
|
||||
this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, 1.0F, this.config.spread * spreadMod);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void entityInit() {
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(3, Integer.valueOf(0));
|
||||
}
|
||||
|
||||
public void setBulletConfig(BulletConfig config) {
|
||||
this.dataWatcher.updateObject(3, config.id);
|
||||
}
|
||||
|
||||
public BulletConfig getBulletConfig() {
|
||||
int id = this.dataWatcher.getWatchableObjectInt(3);
|
||||
if(id < 0 || id > BulletConfig.configs.size()) return null;
|
||||
return BulletConfig.configs.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate() {
|
||||
|
||||
if(config == null) config = this.getBulletConfig();
|
||||
|
||||
if(config == null){
|
||||
this.setDead();
|
||||
return;
|
||||
}
|
||||
|
||||
this.prevPosX = posX;
|
||||
this.prevPosY = posY;
|
||||
this.prevPosZ = posZ;
|
||||
|
||||
super.onUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onImpact(MovingObjectPosition mop) {
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override protected double headingForceMult() { return 1D; }
|
||||
@Override public double getGravityVelocity() { return this.config.gravity; }
|
||||
@Override protected double motionMult() { return this.config.velocity; }
|
||||
@Override protected float getAirDrag() { return 1F; }
|
||||
@Override protected float getWaterDrag() { return 1F; }
|
||||
}
|
||||
@ -31,6 +31,15 @@ public class BulletConfig {
|
||||
this.id = configs.size();
|
||||
configs.add(this);
|
||||
}
|
||||
|
||||
public BulletConfig setItem(Item ammo) { this.ammo = new ComparableStack(ammo); return this; }
|
||||
|
||||
public BulletConfig setItem(Item ammo) { this.ammo = new ComparableStack(ammo); return this; }
|
||||
public BulletConfig setReloadCount(int ammoReloadCount) { this.ammoReloadCount = ammoReloadCount; return this; }
|
||||
public BulletConfig setVel(float velocity) { this.velocity = velocity; return this; }
|
||||
public BulletConfig setSpread(float spread) { this.spread = spread; return this; }
|
||||
public BulletConfig setWear(float wear) { this.wear = wear; return this; }
|
||||
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 setGrav(double gravity) { this.gravity = gravity; return this; }
|
||||
public BulletConfig setLife(int expires) { this.expires = expires; return this; }
|
||||
}
|
||||
|
||||
@ -9,75 +9,97 @@ import com.hbm.render.anim.HbmAnimations.AnimType;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
/**
|
||||
* Despite how complicated the GunConfig looks, it actually only exists to hold together a bunch of fields. Everything else is infrastructure for getting and setting.
|
||||
* The gun config determines general gun specific stats like durability, crosshair, animations, receivers, click handling and the decider.
|
||||
*
|
||||
* @author hbm
|
||||
* */
|
||||
public class GunConfig {
|
||||
|
||||
public static final String O_RECEIVERS = "O_RECEIVERS";
|
||||
public static final String F_DURABILITY = "F_DURABILITY";
|
||||
public static final String I_DRAWDURATION = "I_DRAWDURATION";
|
||||
public static final String O_CROSSHAIR = "O_CROSSHAIR";
|
||||
public static final String B_RELOADANIMATIONSEQUENTIAL = "B_RELOADANIMATIONSEQUENTIAL";
|
||||
public static final String CON_ONPRESSPRIMARY = "CON_ONPRESSPRIMARY";
|
||||
public static final String CON_ONPRESSSECONDARY = "CON_ONPRESSSECONDARY";
|
||||
public static final String CON_ONPRESSTERTIARY = "CON_ONPRESSTERTIARY";
|
||||
public static final String CON_ONPRESSRELOAD = "CON_ONPRESSRELOAD";
|
||||
public static final String CON_ONRELEASEPRIMARY = "CON_ONRELEASEPRIMARY";
|
||||
public static final String CON_ONRELEASESECONDARY = "CON_ONRELEASESECONDARY";
|
||||
public static final String CON_ONRELEASETERTIARY = "CON_ONRELEASETERTIARY";
|
||||
public static final String CON_ONRELEASERELOAD = "CON_ONRELEASERELOAD";
|
||||
public static final String CON_DECIDER = "CON_DECIDER";
|
||||
public static final String FUN_ANIMNATIONS = "FUN_ANIMNATIONS";
|
||||
|
||||
/* FIELDS */
|
||||
|
||||
/** List of receivers used by the gun, primary and secondary are usually indices 0 and 1 respectively, if applicable */
|
||||
protected Receiver[] receivers;
|
||||
protected float durability;
|
||||
protected int drawDuration = 0;
|
||||
protected Crosshair crosshair;
|
||||
protected boolean reloadAnimationsSequential;
|
||||
protected Receiver[] receivers_DNA;
|
||||
protected float durability_DNA;
|
||||
protected int drawDuration_DNA = 0;
|
||||
protected Crosshair crosshair_DNA;
|
||||
protected boolean reloadAnimationsSequential_DNA;
|
||||
/** Lambda functions for clicking shit */
|
||||
protected BiConsumer<ItemStack, LambdaContext> onPressPrimary;
|
||||
protected BiConsumer<ItemStack, LambdaContext> onPressSecondary;
|
||||
protected BiConsumer<ItemStack, LambdaContext> onPressTertiary;
|
||||
protected BiConsumer<ItemStack, LambdaContext> onPressReload;
|
||||
protected BiConsumer<ItemStack, LambdaContext> onPressPrimary_DNA;
|
||||
protected BiConsumer<ItemStack, LambdaContext> onPressSecondary_DNA;
|
||||
protected BiConsumer<ItemStack, LambdaContext> onPressTertiary_DNA;
|
||||
protected BiConsumer<ItemStack, LambdaContext> onPressReload_DNA;
|
||||
/** Lambda functions for releasing the aforementioned shit */
|
||||
protected BiConsumer<ItemStack, LambdaContext> onReleasePrimary;
|
||||
protected BiConsumer<ItemStack, LambdaContext> onReleaseSecondary;
|
||||
protected BiConsumer<ItemStack, LambdaContext> onReleaseTertiary;
|
||||
protected BiConsumer<ItemStack, LambdaContext> onReleaseReload;
|
||||
protected BiConsumer<ItemStack, LambdaContext> onReleasePrimary_DNA;
|
||||
protected BiConsumer<ItemStack, LambdaContext> onReleaseSecondary_DNA;
|
||||
protected BiConsumer<ItemStack, LambdaContext> onReleaseTertiary_DNA;
|
||||
protected BiConsumer<ItemStack, LambdaContext> onReleaseReload_DNA;
|
||||
/** The engine for the state machine that determines the gun's overall behavior */
|
||||
protected BiConsumer<ItemStack, LambdaContext> decider;
|
||||
protected BiConsumer<ItemStack, LambdaContext> decider_DNA;
|
||||
/** Lambda that returns the relevant animation for the given params */
|
||||
protected BiFunction<ItemStack, AnimType, BusAnimation> animations;
|
||||
protected BiFunction<ItemStack, AnimType, BusAnimation> animations_DNA;
|
||||
|
||||
/* GETTERS */
|
||||
|
||||
public Receiver[] getReceivers(ItemStack stack) { return receivers; }
|
||||
public float getDurability(ItemStack stack) { return durability; }
|
||||
public int getDrawDuration(ItemStack stack) { return drawDuration; }
|
||||
public Crosshair getCrosshair(ItemStack stack) { return crosshair; }
|
||||
public boolean getReloadAnimSequential(ItemStack stack) { return reloadAnimationsSequential; }
|
||||
public Receiver[] getReceivers(ItemStack stack) { return WeaponUpgradeManager.eval(receivers_DNA, stack, O_RECEIVERS, this); }
|
||||
public float getDurability(ItemStack stack) { return WeaponUpgradeManager.eval(durability_DNA, stack, F_DURABILITY, this); }
|
||||
public int getDrawDuration(ItemStack stack) { return WeaponUpgradeManager.eval(drawDuration_DNA, stack, I_DRAWDURATION, this); }
|
||||
public Crosshair getCrosshair(ItemStack stack) { return WeaponUpgradeManager.eval(crosshair_DNA, stack, O_CROSSHAIR, this); }
|
||||
public boolean getReloadAnimSequential(ItemStack stack) { return WeaponUpgradeManager.eval(reloadAnimationsSequential_DNA, stack, B_RELOADANIMATIONSEQUENTIAL, this); }
|
||||
|
||||
public BiConsumer<ItemStack, LambdaContext> getPressPrimary(ItemStack stack) { return this.onPressPrimary; }
|
||||
public BiConsumer<ItemStack, LambdaContext> getPressSecondary(ItemStack stack) { return this.onPressSecondary; }
|
||||
public BiConsumer<ItemStack, LambdaContext> getPressTertiary(ItemStack stack) { return this.onPressTertiary; }
|
||||
public BiConsumer<ItemStack, LambdaContext> getPressReload(ItemStack stack) { return this.onPressReload; }
|
||||
public BiConsumer<ItemStack, LambdaContext> getPressPrimary(ItemStack stack) { return WeaponUpgradeManager.eval(this.onPressPrimary_DNA, stack, CON_ONPRESSPRIMARY, this); }
|
||||
public BiConsumer<ItemStack, LambdaContext> getPressSecondary(ItemStack stack) { return WeaponUpgradeManager.eval(this.onPressSecondary_DNA, stack, CON_ONPRESSSECONDARY, this); }
|
||||
public BiConsumer<ItemStack, LambdaContext> getPressTertiary(ItemStack stack) { return WeaponUpgradeManager.eval(this.onPressTertiary_DNA, stack, CON_ONPRESSTERTIARY, this); }
|
||||
public BiConsumer<ItemStack, LambdaContext> getPressReload(ItemStack stack) { return WeaponUpgradeManager.eval(this.onPressReload_DNA, stack, CON_ONPRESSRELOAD, this); }
|
||||
|
||||
public BiConsumer<ItemStack, LambdaContext> getReleasePrimary(ItemStack stack) { return this.onReleasePrimary; }
|
||||
public BiConsumer<ItemStack, LambdaContext> getReleaseSecondary(ItemStack stack) { return this.onReleaseSecondary; }
|
||||
public BiConsumer<ItemStack, LambdaContext> getReleaseTertiary(ItemStack stack) { return this.onReleaseTertiary; }
|
||||
public BiConsumer<ItemStack, LambdaContext> getReleaseReload(ItemStack stack) { return this.onReleaseReload; }
|
||||
public BiConsumer<ItemStack, LambdaContext> getReleasePrimary(ItemStack stack) { return WeaponUpgradeManager.eval(this.onReleasePrimary_DNA, stack, CON_ONRELEASEPRIMARY, this); }
|
||||
public BiConsumer<ItemStack, LambdaContext> getReleaseSecondary(ItemStack stack) { return WeaponUpgradeManager.eval(this.onReleaseSecondary_DNA, stack, CON_ONRELEASESECONDARY, this); }
|
||||
public BiConsumer<ItemStack, LambdaContext> getReleaseTertiary(ItemStack stack) { return WeaponUpgradeManager.eval(this.onReleaseTertiary_DNA, stack, CON_ONRELEASETERTIARY, this); }
|
||||
public BiConsumer<ItemStack, LambdaContext> getReleaseReload(ItemStack stack) { return WeaponUpgradeManager.eval(this.onReleaseReload_DNA, stack, CON_ONRELEASERELOAD, this); }
|
||||
|
||||
public BiConsumer<ItemStack, LambdaContext> getDecider(ItemStack stack) { return this.decider; }
|
||||
public BiConsumer<ItemStack, LambdaContext> getDecider(ItemStack stack) { return WeaponUpgradeManager.eval(this.decider_DNA, stack, CON_DECIDER, this); }
|
||||
|
||||
public BiFunction<ItemStack, AnimType, BusAnimation> getAnims(ItemStack stack) { return this.animations; }
|
||||
public BiFunction<ItemStack, AnimType, BusAnimation> getAnims(ItemStack stack) { return WeaponUpgradeManager.eval(this.animations_DNA, stack, FUN_ANIMNATIONS, this); }
|
||||
|
||||
/* SETTERS */
|
||||
|
||||
public GunConfig rec(Receiver... receivers) { this.receivers = receivers; return this; }
|
||||
public GunConfig dura(float dura) { this.durability = dura; return this; }
|
||||
public GunConfig draw(int draw) { this.drawDuration = draw; return this; }
|
||||
public GunConfig crosshair(Crosshair crosshair) { this.crosshair = crosshair; return this; }
|
||||
public GunConfig rec(Receiver... receivers) { this.receivers_DNA = receivers; return this; }
|
||||
public GunConfig dura(float dura) { this.durability_DNA = dura; return this; }
|
||||
public GunConfig draw(int draw) { this.drawDuration_DNA = draw; return this; }
|
||||
public GunConfig crosshair(Crosshair crosshair) { this.crosshair_DNA = crosshair; return this; }
|
||||
|
||||
//press
|
||||
public GunConfig pp(BiConsumer<ItemStack, LambdaContext> lambda) { this.onPressPrimary = lambda; return this; }
|
||||
public GunConfig ps(BiConsumer<ItemStack, LambdaContext> lambda) { this.onPressSecondary = lambda; return this; }
|
||||
public GunConfig pt(BiConsumer<ItemStack, LambdaContext> lambda) { this.onPressTertiary = lambda; return this; }
|
||||
public GunConfig pr(BiConsumer<ItemStack, LambdaContext> lambda) { this.onPressReload = lambda; return this; }
|
||||
public GunConfig pp(BiConsumer<ItemStack, LambdaContext> lambda) { this.onPressPrimary_DNA = lambda; return this; }
|
||||
public GunConfig ps(BiConsumer<ItemStack, LambdaContext> lambda) { this.onPressSecondary_DNA = lambda; return this; }
|
||||
public GunConfig pt(BiConsumer<ItemStack, LambdaContext> lambda) { this.onPressTertiary_DNA = lambda; return this; }
|
||||
public GunConfig pr(BiConsumer<ItemStack, LambdaContext> lambda) { this.onPressReload_DNA = lambda; return this; }
|
||||
|
||||
//release
|
||||
public GunConfig rp(BiConsumer<ItemStack, LambdaContext> lambda) { this.onReleasePrimary = lambda; return this; }
|
||||
public GunConfig rs(BiConsumer<ItemStack, LambdaContext> lambda) { this.onReleaseSecondary = lambda; return this; }
|
||||
public GunConfig rt(BiConsumer<ItemStack, LambdaContext> lambda) { this.onReleaseTertiary = lambda; return this; }
|
||||
public GunConfig rr(BiConsumer<ItemStack, LambdaContext> lambda) { this.onReleaseReload = lambda; return this; }
|
||||
public GunConfig rp(BiConsumer<ItemStack, LambdaContext> lambda) { this.onReleasePrimary_DNA = lambda; return this; }
|
||||
public GunConfig rs(BiConsumer<ItemStack, LambdaContext> lambda) { this.onReleaseSecondary_DNA = lambda; return this; }
|
||||
public GunConfig rt(BiConsumer<ItemStack, LambdaContext> lambda) { this.onReleaseTertiary_DNA = lambda; return this; }
|
||||
public GunConfig rr(BiConsumer<ItemStack, LambdaContext> lambda) { this.onReleaseReload_DNA = lambda; return this; }
|
||||
|
||||
//decider
|
||||
public GunConfig decider(BiConsumer<ItemStack, LambdaContext> lambda) { this.decider = lambda; return this; }
|
||||
public GunConfig decider(BiConsumer<ItemStack, LambdaContext> lambda) { this.decider_DNA = lambda; return this; }
|
||||
|
||||
//anims
|
||||
public GunConfig anim(BiFunction<ItemStack, AnimType, BusAnimation> lambda) { this.animations = lambda; return this; }
|
||||
public GunConfig anim(BiFunction<ItemStack, AnimType, BusAnimation> lambda) { this.animations_DNA = lambda; return this; }
|
||||
}
|
||||
|
||||
14
src/main/java/com/hbm/items/weapon/sedna/IWeaponUpgrade.java
Normal file
14
src/main/java/com/hbm/items/weapon/sedna/IWeaponUpgrade.java
Normal file
@ -0,0 +1,14 @@
|
||||
package com.hbm.items.weapon.sedna;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public interface IWeaponUpgrade {
|
||||
|
||||
/** Lower numbers get installed and therefore evaluated first. Important when multiplicative and additive bonuses are supposed to stack */
|
||||
public int getModPriority(ItemStack stack);
|
||||
/** Which "slots" this upgrade occupies, can be any value, upgrades that have at least one matching slot are incompatible */
|
||||
public String[] getSlots(ItemStack stack);
|
||||
/** The meat and bones of the upgrade eval. Requires the base value, the held gun, the value's
|
||||
* identifier and the yet unmodified parent (i.e. if the value is part of the receiver, that receiver) */
|
||||
public default <T> T eval(T base, ItemStack stack, String key, Object parent) { return base; }
|
||||
}
|
||||
@ -27,6 +27,8 @@ import net.minecraftforge.client.event.RenderGameOverlayEvent.Pre;
|
||||
|
||||
public class ItemGunBaseNT extends Item implements IKeybindReceiver, IEquipReceiver, IItemHUD {
|
||||
|
||||
public static final String O_GUNCONFIG = "O_GUNCONFIG";
|
||||
|
||||
public static final String KEY_DRAWN = "drawn";
|
||||
public static final String KEY_AIMING = "aiming";
|
||||
public static final String KEY_TIMER = "timer";
|
||||
@ -43,7 +45,7 @@ public class ItemGunBaseNT extends Item implements IKeybindReceiver, IEquipRecei
|
||||
private GunConfig config_DNA;
|
||||
|
||||
public GunConfig getConfig(ItemStack stack) {
|
||||
return config_DNA;
|
||||
return WeaponUpgradeManager.eval(config_DNA, stack, O_GUNCONFIG, this);
|
||||
}
|
||||
|
||||
public ItemGunBaseNT(GunConfig cfg) {
|
||||
@ -55,7 +57,7 @@ public class ItemGunBaseNT extends Item implements IKeybindReceiver, IEquipRecei
|
||||
DRAWING, //initial delay after selecting
|
||||
IDLE, //gun can be fired or reloaded
|
||||
WINDUP, //fire button is down, added delay before fire
|
||||
JUST_FIRED, //gun has been fired, cooldown
|
||||
COOLDOWN, //gun has been fired, cooldown
|
||||
RELOADING //gun is currently reloading
|
||||
}
|
||||
|
||||
@ -92,7 +94,15 @@ public class ItemGunBaseNT extends Item implements IKeybindReceiver, IEquipRecei
|
||||
EntityPlayer player = (EntityPlayer) entity;
|
||||
|
||||
if(world.isRemote) {
|
||||
|
||||
if(isHeld && player == MainRegistry.proxy.me()) {
|
||||
|
||||
/// DEBUG ///
|
||||
/*Vec3 offset = Vec3.createVectorHelper(-0.2, -0.1, 0.75);
|
||||
offset.rotateAroundX(-entity.rotationPitch / 180F * (float) Math.PI);
|
||||
offset.rotateAroundY(-entity.rotationYaw / 180F * (float) Math.PI);
|
||||
world.spawnParticle("flame", entity.posX + offset.xCoord, entity.posY + entity.getEyeHeight() + offset.yCoord, entity.posZ + offset.zCoord, 0, 0, 0);*/
|
||||
|
||||
prevAimingProgress = aimingProgress;
|
||||
boolean aiming = this.getIsAiming(stack);
|
||||
float aimSpeed = 0.25F;
|
||||
|
||||
@ -9,39 +9,64 @@ import com.hbm.items.weapon.sedna.mags.IMagazine;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* barrel, receiver and chamber of the gun, an underbarrel grenade launcher for example would be a separate receiver instance compared to the regular gun it is attached to.
|
||||
*
|
||||
* @author hbm
|
||||
*/
|
||||
public class Receiver {
|
||||
|
||||
protected float baseDamage;
|
||||
protected int delayAfterFire;
|
||||
protected int roundsPerCycle = 1;
|
||||
protected boolean refireOnHold = false;
|
||||
protected CasingEjector ejector = null;
|
||||
protected int reloadDuration;
|
||||
protected IMagazine magazine;
|
||||
protected BiFunction<ItemStack, LambdaContext, Boolean> canFire;
|
||||
protected BiConsumer<ItemStack, LambdaContext> onFire;
|
||||
public static final String F_BASEDAMAGE = "F_BASEDAMAGE";
|
||||
public static final String I_DELAYAFTERFIRE = "I_DELAYAFTERFIRE";
|
||||
public static final String I_ROUNDSPERCYCLE = "I_ROUNDSPERCYCLE";
|
||||
public static final String F_SPREADMOD = "F_SPREADMOD";
|
||||
public static final String B_REFIREONHOLD = "B_REFIREONHOLD";
|
||||
public static final String O_EJECTOR = "O_EJECTOR";
|
||||
public static final String I_RELOADDURATION = "I_RELOADDURATION";
|
||||
public static final String O_MAGAZINE = "O_MAGAZINE";
|
||||
public static final String FUN_CANFIRE = "FUN_CANFIRE";
|
||||
public static final String CON_ONFIRE = "CON_ONFIRE";
|
||||
|
||||
public Receiver(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
protected int index;
|
||||
protected float baseDamage_DNA;
|
||||
protected int delayAfterFire_DNA;
|
||||
protected int roundsPerCycle_DNA = 1;
|
||||
protected float spreadMod_DNA = 1F;
|
||||
protected boolean refireOnHold_DNA = false;
|
||||
protected CasingEjector ejector_DNA = null;
|
||||
protected int reloadDuration_DNA;
|
||||
protected IMagazine magazine_DNA;
|
||||
protected BiFunction<ItemStack, LambdaContext, Boolean> canFire_DNA;
|
||||
protected BiConsumer<ItemStack, LambdaContext> onFire_DNA;
|
||||
|
||||
/* GETTERS */
|
||||
public float getBaseDamage(ItemStack stack) { return this.baseDamage; }
|
||||
public int getDelayAfterFire(ItemStack stack) { return this.delayAfterFire; }
|
||||
public int getRoundsPerCycle(ItemStack stack) { return this.roundsPerCycle; }
|
||||
public boolean getRefireOnHold(ItemStack stack) { return this.refireOnHold; }
|
||||
public CasingEjector getEjector(ItemStack stack) { return this.ejector; }
|
||||
public int getReloadDuration(ItemStack stack) { return this.reloadDuration; }
|
||||
public IMagazine getMagazine(ItemStack stack) { return this.magazine; }
|
||||
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 getSpreadMod(ItemStack stack) { return WeaponUpgradeManager.eval(this.spreadMod_DNA, stack, F_SPREADMOD, this); }
|
||||
public boolean getRefireOnHold(ItemStack stack) { return WeaponUpgradeManager.eval(this.refireOnHold_DNA, stack, B_REFIREONHOLD, this); }
|
||||
public CasingEjector getEjector(ItemStack stack) { return WeaponUpgradeManager.eval(this.ejector_DNA, stack, O_EJECTOR, this); }
|
||||
public int getReloadDuration(ItemStack stack) { return WeaponUpgradeManager.eval(this.reloadDuration_DNA, stack, I_RELOADDURATION, this); }
|
||||
public IMagazine getMagazine(ItemStack stack) { return WeaponUpgradeManager.eval(this.magazine_DNA, stack, O_MAGAZINE, this); }
|
||||
|
||||
public BiFunction<ItemStack, LambdaContext, Boolean> getCanFire(ItemStack stack) { return this.canFire; }
|
||||
public BiConsumer<ItemStack, LambdaContext> getOnFire(ItemStack stack) { return this.onFire; }
|
||||
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); }
|
||||
|
||||
/* SETTERS */
|
||||
public Receiver dmg(float dmg) { this.baseDamage = dmg; return this; }
|
||||
public Receiver delay(int delay) { this.delayAfterFire = delay; return this; }
|
||||
public Receiver rounds(int rounds) { this.roundsPerCycle = rounds; return this; }
|
||||
public Receiver auto(boolean auto) { this.refireOnHold = auto; return this; }
|
||||
public Receiver burst(CasingEjector ejector) { this.ejector = ejector; return this; }
|
||||
public Receiver reload(int delay) { this.reloadDuration = delay; return this; }
|
||||
public Receiver mag(IMagazine magazine) { this.magazine = 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.spreadMod_DNA = spread; return this; }
|
||||
public Receiver auto(boolean auto) { this.refireOnHold_DNA = auto; 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 canFire(BiFunction<ItemStack, LambdaContext, Boolean> lambda) { this.canFire = lambda; return this; }
|
||||
public Receiver fire(BiConsumer<ItemStack, LambdaContext> lambda) { this.onFire = lambda; 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; }
|
||||
}
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
package com.hbm.items.weapon.sedna;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
/**
|
||||
* The upgrade manager operates by scraping upgrades from a gun, then iterating over them and evaluating the given value, passing the modified value to successive mods.
|
||||
* The way that mods stack (additive vs multiplicative) depends on the order the mod is installed in
|
||||
*
|
||||
* @author hbm
|
||||
*/
|
||||
public class WeaponUpgradeManager {
|
||||
|
||||
public static ItemStack[] getUpgrades(ItemStack stack) {
|
||||
return null; // TBI
|
||||
}
|
||||
|
||||
/** Scrapes all upgrades, iterates over them and evaluates the given value. The parent (i.e. holder of the base value)
|
||||
* is passed for context (so upgrades can differentiate primary and secondary receivers for example) */
|
||||
public static <T> T eval(T base, ItemStack stack, String key, Object parent) {
|
||||
|
||||
ItemStack[] upgrades = getUpgrades(stack);
|
||||
if(upgrades != null) for(ItemStack upgradeStack : upgrades) {
|
||||
if(upgradeStack.getItem() instanceof IWeaponUpgrade) {
|
||||
IWeaponUpgrade upgrade = (IWeaponUpgrade) upgradeStack.getItem();
|
||||
base = upgrade.eval(base, upgradeStack, key, parent);
|
||||
}
|
||||
}
|
||||
|
||||
return base;
|
||||
}
|
||||
}
|
||||
@ -18,12 +18,12 @@ public class GunFactory {
|
||||
|
||||
ModItems.ammo_debug = new Item().setUnlocalizedName("ammo_debug").setTextureName(RefStrings.MODID + ":ammo_45");
|
||||
|
||||
BulletConfig ammo_debug = new BulletConfig().setItem(ModItems.ammo_debug);
|
||||
BulletConfig ammo_debug = new BulletConfig().setItem(ModItems.ammo_debug).setSpread(0.01F);
|
||||
|
||||
ModItems.gun_debug = new ItemGunBaseNT(new GunConfig()
|
||||
.dura(600).draw(15).crosshair(Crosshair.L_CLASSIC)
|
||||
.rec(new Receiver()
|
||||
.dmg(10F).delay(10).mag(new MagazineRevolverDrum(0, 6).addConfigs(ammo_debug))
|
||||
.rec(new Receiver(0)
|
||||
.dmg(10F).delay(12).mag(new MagazineRevolverDrum(0, 6).addConfigs(ammo_debug))
|
||||
.canFire(Lego.LAMBDA_DEBUG_CAN_FIRE).fire(Lego.LAMBDA_DEBUG_FIRE))
|
||||
.pr(Lego.LAMBDA_STANDARD_RELOAD)
|
||||
.pp(Lego.LAMBDA_STANDARD_FIRE)
|
||||
|
||||
@ -62,7 +62,7 @@ public class GunStateDecider {
|
||||
/** Triggers a re-fire of the primary if the fire delay has expired, the left mouse button is down and re-firing is enabled, otherwise switches to IDLE */
|
||||
public static void deciderAutoRefire(ItemStack stack, LambdaContext ctx, GunState lastState, int recIndex, BooleanSupplier refireCondition) {
|
||||
|
||||
if(lastState == GunState.JUST_FIRED) {
|
||||
if(lastState == GunState.COOLDOWN) {
|
||||
|
||||
GunConfig cfg = ctx.config;
|
||||
Receiver rec = cfg.getReceivers(stack)[recIndex];
|
||||
@ -72,7 +72,7 @@ public class GunStateDecider {
|
||||
//if there's a bullet loaded, fire again
|
||||
if(rec.getCanFire(stack).apply(stack, ctx)) {
|
||||
rec.getOnFire(stack).accept(stack, ctx);
|
||||
ItemGunBaseNT.setState(stack, GunState.JUST_FIRED);
|
||||
ItemGunBaseNT.setState(stack, GunState.COOLDOWN);
|
||||
ItemGunBaseNT.setTimer(stack, rec.getDelayAfterFire(stack));
|
||||
//if not, revert to idle
|
||||
} else {
|
||||
|
||||
@ -3,9 +3,12 @@ package com.hbm.items.weapon.sedna.factory;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import com.hbm.entity.projectile.EntityBulletBaseMK4;
|
||||
import com.hbm.items.weapon.sedna.BulletConfig;
|
||||
import com.hbm.items.weapon.sedna.ItemGunBaseNT;
|
||||
import com.hbm.items.weapon.sedna.ItemGunBaseNT.GunState;
|
||||
import com.hbm.items.weapon.sedna.ItemGunBaseNT.LambdaContext;
|
||||
import com.hbm.items.weapon.sedna.Receiver;
|
||||
import com.hbm.packet.PacketDispatcher;
|
||||
import com.hbm.packet.toclient.GunAnimationPacket;
|
||||
import com.hbm.render.anim.BusAnimation;
|
||||
@ -38,7 +41,7 @@ public class Lego {
|
||||
public static BiConsumer<ItemStack, LambdaContext> LAMBDA_STANDARD_FIRE = (stack, ctx) -> {
|
||||
|
||||
if(ItemGunBaseNT.getState(stack) == GunState.IDLE && ctx.config.getReceivers(stack)[0].getCanFire(stack).apply(stack, ctx)) {
|
||||
ItemGunBaseNT.setState(stack, GunState.JUST_FIRED);
|
||||
ItemGunBaseNT.setState(stack, GunState.COOLDOWN);
|
||||
ItemGunBaseNT.setTimer(stack, ctx.config.getReceivers(stack)[0].getDelayAfterFire(stack));
|
||||
ctx.config.getReceivers(stack)[0].getOnFire(stack).accept(stack, ctx);
|
||||
}
|
||||
@ -55,19 +58,35 @@ public class Lego {
|
||||
|
||||
/** JUMPER - bypasses mag testing and just allows constant fire */
|
||||
public static BiFunction<ItemStack, LambdaContext, Boolean> LAMBDA_DEBUG_CAN_FIRE = (stack, ctx) -> { return true; };
|
||||
|
||||
/** simply plays a sound to indicate that the keybind has triggered */
|
||||
public static BiConsumer<ItemStack, LambdaContext> LAMBDA_DEBUG_FIRE = (stack, ctx) -> {
|
||||
EntityPlayer player = ctx.player;
|
||||
player.worldObj.playSoundEffect(player.posX, player.posY, player.posZ, "hbm:weapon.shotgunShoot", 1F, 1F);
|
||||
if(player instanceof EntityPlayerMP) PacketDispatcher.wrapper.sendTo(new GunAnimationPacket(AnimType.CYCLE.ordinal()), (EntityPlayerMP) player);
|
||||
|
||||
double sideOffset = ItemGunBaseNT.getIsAiming(stack) ? 0 : -0.2D;
|
||||
float aim = ItemGunBaseNT.getIsAiming(stack) ? 0.25F : 1F;
|
||||
Receiver primary = ctx.config.getReceivers(stack)[0];
|
||||
|
||||
EntityBulletBaseMK4 mk4 = new EntityBulletBaseMK4(player, (BulletConfig) primary.getMagazine(stack).getType(stack), primary.getBaseDamage(stack), primary.getSpreadMod(stack) * aim, sideOffset, -0.1, 0.75);
|
||||
player.worldObj.spawnEntityInWorld(mk4);
|
||||
player.worldObj.playSoundEffect(player.posX, player.posY, player.posZ, "hbm:weapon.shotgunShoot", 1F, 1F);
|
||||
};
|
||||
|
||||
/** No reload, simply play inspect animation */
|
||||
public static BiConsumer<ItemStack, LambdaContext> LAMBDA_DEBUG_RELOAD = (stack, ctx) -> {
|
||||
EntityPlayer player = ctx.player;
|
||||
if(player instanceof EntityPlayerMP) PacketDispatcher.wrapper.sendTo(new GunAnimationPacket(AnimType.INSPECT.ordinal()), (EntityPlayerMP) player);
|
||||
};
|
||||
|
||||
/** anims for the DEBUG revolver, mostly a copy of the li'lpip but with some fixes regarding the cylinder movement */
|
||||
public static BiFunction<ItemStack, AnimType, BusAnimation> LAMBDA_DEBUG_ANIMS = (stack, type) -> {
|
||||
switch(type) {
|
||||
case CYCLE:
|
||||
return new BusAnimation()
|
||||
.addBus("RECOIL", new BusAnimationSequence().addKeyframePosition(0, 0, 0, 50).addKeyframePosition(0, 0, -3, 50).addKeyframePosition(0, 0, 0, 250))
|
||||
.addBus("HAMMER", new BusAnimationSequence().addKeyframePosition(0, 0, 1, 50).addKeyframePosition(0, 0, 1, 300 + 200).addKeyframePosition(0, 0, 0, 200))
|
||||
.addBus("DRUM", new BusAnimationSequence().addKeyframePosition(0, 0, 0, 350 + 200).addKeyframePosition(0, 0, 1, 200));
|
||||
.addBus("HAMMER", new BusAnimationSequence().addKeyframePosition(0, 0, 1, 50).addKeyframePosition(0, 0, 1, 300 + 100).addKeyframePosition(0, 0, 0, 200))
|
||||
.addBus("DRUM", new BusAnimationSequence().addKeyframePosition(0, 0, 0, 350 + 100).addKeyframePosition(0, 0, 1, 200));
|
||||
case CYCLE_EMPTY: break;
|
||||
case ALT_CYCLE: break;
|
||||
case EQUIP: return new BusAnimation().addBus("ROTATE", new BusAnimationSequence().addKeyframePosition(-360, 0, 0, 350));
|
||||
@ -77,6 +96,7 @@ public class Lego {
|
||||
case RELOAD_END: break;
|
||||
case SPINDOWN: break;
|
||||
case SPINUP: break;
|
||||
case INSPECT: break;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@ -3,6 +3,12 @@ package com.hbm.items.weapon.sedna.mags;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
/**
|
||||
* The magazine simply provides the receiver it's attached to with ammo, the receiver does not care where it comes from.
|
||||
* Therefore it is the mag's responsibility to handle reloading, any type restrictions as well as belt-like action from "magless" guns.
|
||||
*
|
||||
* @author hbm
|
||||
*/
|
||||
public interface IMagazine {
|
||||
|
||||
/** What ammo is loaded currently */
|
||||
|
||||
@ -31,8 +31,8 @@ public abstract class MagazineStandardBase implements IMagazine {
|
||||
@Override
|
||||
public Object getType(ItemStack stack) {
|
||||
int type = getMagType(stack, index);
|
||||
if(type >= 0 && type < acceptedBullets.size()) {
|
||||
return acceptedBullets.get(type);
|
||||
if(type >= 0 && type < BulletConfig.configs.size()) {
|
||||
return BulletConfig.configs.get(type);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -40,7 +40,7 @@ public abstract class MagazineStandardBase implements IMagazine {
|
||||
@Override
|
||||
public void setType(ItemStack stack, Object type) {
|
||||
if(!(type instanceof BulletConfig)) return;
|
||||
int i = acceptedBullets.indexOf(type);
|
||||
int i = BulletConfig.configs.indexOf(type);
|
||||
if(i >= 0) setMagType(stack, index, i);
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ public abstract class MagazineStandardBase implements IMagazine {
|
||||
@Override public void setAmount(ItemStack stack, int amount) { setMagCount(stack, index, amount); }
|
||||
|
||||
// MAG TYPE //
|
||||
public static int getMagType(ItemStack stack, int index) { return ItemGunBaseNT.getValueInt(stack, KEY_MAG_TYPE + index); }
|
||||
public static int getMagType(ItemStack stack, int index) { return ItemGunBaseNT.getValueInt(stack, KEY_MAG_TYPE + index); } //TODO: replace with named tags to avoid ID shifting
|
||||
public static void setMagType(ItemStack stack, int index, int value) { ItemGunBaseNT.setValueInt(stack, KEY_MAG_TYPE + index, value); }
|
||||
|
||||
// MAG COUNT //
|
||||
|
||||
@ -27,7 +27,8 @@ public class HbmAnimations {
|
||||
ALT_CYCLE, //animation for alt fire cycles
|
||||
SPINUP, //animation for actionstart
|
||||
SPINDOWN, //animation for actionend
|
||||
EQUIP //animation for drawing the weapon
|
||||
EQUIP, //animation for drawing the weapon
|
||||
INSPECT //animation for inspecting the weapon
|
||||
}
|
||||
|
||||
// A NOTE ON SHOTGUN STYLE RELOADS
|
||||
|
||||
@ -35,8 +35,8 @@ public class ItemRenderDebug extends ItemRenderWeaponBase {
|
||||
GL11.glRotated(equipSpin[0], 0, 0, 1);
|
||||
|
||||
double[] recoil = HbmAnimations.getRelevantTransformation("RECOIL");
|
||||
//GL11.glTranslated(-recoil[2], 0, 0);
|
||||
GL11.glTranslated(0, 0, recoil[2]);
|
||||
standardAimingTransform(stack, 0, 0, recoil[2], -recoil[2], 0, 0);
|
||||
|
||||
GL11.glRotated(recoil[2] * 10, 0, 0, 1);
|
||||
|
||||
GL11.glShadeModel(GL11.GL_SMOOTH);
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 310 B |
Binary file not shown.
|
After Width: | Height: | Size: 320 B |
Binary file not shown.
|
After Width: | Height: | Size: 358 B |
Binary file not shown.
|
After Width: | Height: | Size: 349 B |
Loading…
x
Reference in New Issue
Block a user