split ejector and casing configs, casing colors

This commit is contained in:
Boblet 2023-01-31 13:24:52 +01:00
parent b0bf2b6511
commit d6b0d5b9ca
11 changed files with 385 additions and 782 deletions

View File

@ -13,9 +13,9 @@ import com.hbm.interfaces.Untested;
import com.hbm.inventory.RecipesCommon.ComparableStack;
import com.hbm.lib.ModDamageSource;
import com.hbm.main.MainRegistry;
import com.hbm.particle.SpentCasing;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.DamageSource;
@ -101,6 +101,7 @@ public class BulletConfiguration implements Cloneable {
public int plink;
//vanilla particle FX
public String vPFX = "";
public SpentCasing spentCasing;
//energy projectiles
//power consumed per shot

View File

@ -0,0 +1,147 @@
package com.hbm.handler;
import java.util.HashMap;
import java.util.Random;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector3f;
import org.lwjgl.util.vector.Vector4f;
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.util.Vec3;
import net.minecraft.world.World;
/**
* Config for the guns themselves on where to spawn casings and at what angle
* @author uffr, hbm
*/
public class CasingEjector implements Cloneable {
public static HashMap<Integer, CasingEjector> mappings = new HashMap();
public static final Random rand = new Random();
private int id;
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;
private float randomYaw = 0F;
private float randomPitch = 0F;
public CasingEjector() {
this.id = nextId;
nextId++;
mappings.put(id, this);
}
public CasingEjector setOffset(Vec3 vec) {
this.posOffset = vec;
return this;
}
public CasingEjector setMotion(Vec3 vec) {
this.initialMotion = vec;
return this;
}
public CasingEjector setAmount(int am) {
this.casingAmount = am;
return this;
}
public CasingEjector setAfterReload() {
this.afterReload = true;
return this;
}
public CasingEjector setDelay(int delay) {
this.delay = delay;
return this;
}
public CasingEjector setAngleRange(float yaw, float pitch) {
this.randomYaw = yaw;
this.randomPitch = pitch;
return this;
}
public int getId() { return this.id; }
public Vec3 getOffset() { return this.posOffset; }
public Vec3 getMotion() { return this.initialMotion; }
public int getAmount() { return this.casingAmount; }
public boolean getAfterReload() { return this.afterReload; }
public int getDelay() { return this.delay; }
public float getYawFactor() { return this.randomYaw; }
public float getPitchFactor() { return this.randomPitch; }
public void spawnCasing(TextureManager textureManager, SpentCasing config, World world, double x, double y, double z, float pitch, float yaw, boolean crouched) {
Vec3 rotatedMotionVec = rotateVector(getMotion(), pitch + (float) rand.nextGaussian() * getPitchFactor(), yaw + (float) rand.nextGaussian() * getPitchFactor(), getPitchFactor(), getPitchFactor());
ParticleSpentCasing casing = new ParticleSpentCasing(textureManager, world, x, y, z, rotatedMotionVec.xCoord, rotatedMotionVec.yCoord, rotatedMotionVec.zCoord, (float) (getPitchFactor() * rand.nextGaussian()), (float) (getYawFactor() * rand.nextGaussian()), config);
offsetCasing(casing, getOffset(), pitch, yaw, crouched);
casing.rotationPitch = (float) Math.toDegrees(pitch);
casing.rotationYaw = (float) Math.toDegrees(yaw);
Minecraft.getMinecraft().effectRenderer.addEffect(casing);
}
// Rotate a position
private static void offsetCasing(ParticleSpentCasing casing, Vec3 offset, float pitch, float yaw, boolean crouched) {
// x-axis offset, 0 if crouched to center
final float oX = (float) (crouched ? 0 : offset.xCoord);
// Create rotation matrices for pitch and yaw
final Matrix4f pitchMatrix = new Matrix4f(), yawMatrix = new Matrix4f();
pitchMatrix.rotate(pitch, new Vector3f(1, 0, 0)); // modify axis of rotation
yawMatrix.rotate(-yaw, new Vector3f(0, 1, 0));
// Multiply matrices to get combined rotation matrix
final Matrix4f rotMatrix = Matrix4f.mul(yawMatrix, pitchMatrix, null);
// Create vector representing the offset and apply rotation
final Vector4f offsetVector = new Vector4f(oX, (float) offset.yCoord, (float) offset.zCoord, 1); // set fourth coordinate to 1
Matrix4f.transform(rotMatrix, offsetVector, offsetVector);
final Vector3f result = new Vector3f(); // create result vector
result.set(offsetVector.x, offsetVector.y, offsetVector.z); // set result vector using transformed coordinates
// Apply rotation
casing.setPosition(casing.posX + result.x, casing.posY + result.y, casing.posZ + result.z);
}
private static Vec3 rotateVector(Vec3 vector, float pitch, float yaw, float pitchFactor, float yawFactor) {
// Apply randomness to vector
vector.xCoord += rand.nextGaussian() * yawFactor;
vector.yCoord += rand.nextGaussian() * pitchFactor;
vector.zCoord += rand.nextGaussian() * yawFactor;
final Matrix4f pitchMatrix = new Matrix4f(), yawMatrix = new Matrix4f();
pitchMatrix.setIdentity();
pitchMatrix.rotate(-pitch, new Vector3f(1, 0, 0));
yawMatrix.setIdentity();
yawMatrix.rotate(-yaw, new Vector3f(0, 1, 0));
final Vector4f vector4f = new Vector4f((float) vector.xCoord, (float) vector.yCoord, (float) vector.zCoord, 1);
Matrix4f.transform(pitchMatrix, vector4f, vector4f);
Matrix4f.transform(yawMatrix, vector4f, vector4f);
return Vec3.createVectorHelper(vector4f.x, vector4f.y, vector4f.z);
}
public static CasingEjector fromId(int id) {
return mappings.get(id);
}
@Override
public CasingEjector clone() throws CloneNotSupportedException {
return (CasingEjector) super.clone();
}
}

View File

@ -5,7 +5,6 @@ import java.util.HashMap;
import java.util.List;
import com.hbm.lib.HbmCollection.EnumGunManufacturer;
import com.hbm.particle.SpentCasingConfig;
import com.hbm.render.anim.BusAnimation;
import com.hbm.render.anim.HbmAnimations.AnimType;
import com.hbm.render.util.RenderScreenOverlay.Crosshair;
@ -78,7 +77,7 @@ public class GunConfiguration implements Cloneable {
public Crosshair crosshair;
//casing eject behavior
public SpentCasingConfig casingConfig = null;
public CasingEjector ejector = null;
public static final int MODE_NORMAL = 0;
public static final int MODE_RELEASE = 1;

View File

@ -5,6 +5,7 @@ import java.util.ArrayList;
import com.hbm.entity.projectile.EntityBulletBase;
import com.hbm.handler.BulletConfigSyncingUtil;
import com.hbm.handler.BulletConfiguration;
import com.hbm.handler.CasingEjector;
import com.hbm.handler.GunConfiguration;
import com.hbm.interfaces.IBulletHurtBehavior;
import com.hbm.inventory.RecipesCommon.ComparableStack;
@ -12,9 +13,8 @@ import com.hbm.items.ItemAmmoEnums.Ammo12Gauge;
import com.hbm.items.ModItems;
import com.hbm.lib.HbmCollection;
import com.hbm.lib.HbmCollection.EnumGunManufacturer;
import com.hbm.particle.SpentCasingConfig;
import com.hbm.particle.SpentCasingConfig.CasingType;
import com.hbm.particle.SpentCasingConfigBuilder;
import com.hbm.particle.SpentCasing;
import com.hbm.particle.SpentCasing.CasingType;
import com.hbm.potion.HbmPotion;
import com.hbm.render.anim.BusAnimation;
import com.hbm.render.anim.BusAnimationKeyframe;
@ -29,32 +29,17 @@ import net.minecraft.util.Vec3;
public class Gun12GaugeFactory {
static final SpentCasingConfig CASING_SPAS, CASING_SPAS_ALT, CASING_BENELLI, CASING_UBOINIK, CASING_SSG;
private static final CasingEjector CASING_SPAS, CASING_SPAS_ALT, CASING_BENELLI, CASING_UBOINIK, CASING_SSG;
private static final SpentCasing CASING12GAUGE;
static
{
final SpentCasingConfigBuilder CASING_12G_BUILDER = new SpentCasingConfigBuilder("", CasingType.SHOTGUN, false)
.setScaleX(1.5f).setScaleY(1.5f).setScaleZ(1.5f);
CASING_SPAS = CASING_12G_BUILDER.setRegistryName("spas12").setInitialMotion(Vec3.createVectorHelper(-0.4, 0.1, 0))
.setPosOffset(Vec3.createVectorHelper(-0.35, 0, 0.5)).setPitchFactor(0.03f).setYawFactor(0.01f)
.setSmokeChance(0).setDelay(10)
.build();
CASING_SPAS_ALT = CASING_12G_BUILDER.setRegistryName("spas12alt").setCasingAmount(2)
.build();
CASING_BENELLI = CASING_12G_BUILDER.setRegistryName("benelli").setCasingAmount(1).setDelay(0)
.setInitialMotion(Vec3.createVectorHelper(-0.3, 1, 0))
.build();
CASING_UBOINIK = CASING_12G_BUILDER.setRegistryName("uboinik").setOverrideColor(true)
.setBlueOverride(255).setPosOffset(Vec3.createVectorHelper(-0.35, -0.3, 0.5))
.build();
CASING_SSG = CASING_12G_BUILDER.setRegistryName("ssg").setBlueOverride(0).setRedOverride(255).setCasingAmount(2)
.setPosOffset(Vec3.createVectorHelper(0.8, 0, 0)).setInitialMotion(Vec3.createVectorHelper(0.2, 0, -0.2))
.setPitchFactor(0.05f).setYawFactor(0.02f)
.build();
static {
CASING_SPAS = new CasingEjector().setMotion(Vec3.createVectorHelper(-0.4, 0.1, 0)).setOffset(Vec3.createVectorHelper(-0.35, 0, 0.5)).setAngleRange(0.01F, 0.03F).setDelay(10);
CASING_SPAS_ALT = new CasingEjector().setMotion(Vec3.createVectorHelper(-0.4, 0.1, 0)).setOffset(Vec3.createVectorHelper(-0.35, 0, 0.5)).setAngleRange(0.01F, 0.03F).setDelay(10).setAmount(2);
CASING_BENELLI = new CasingEjector().setMotion(Vec3.createVectorHelper(-0.4, 0.1, 0)).setOffset(Vec3.createVectorHelper(-0.3, 1, 0)).setAngleRange(0.01F, 0.03F);
CASING_UBOINIK = new CasingEjector().setMotion(Vec3.createVectorHelper(-0.4, 0.1, 0)).setOffset(Vec3.createVectorHelper(-0.35, -0.3, 0.5)).setAngleRange(0.01F, 0.03F);
CASING_SSG = new CasingEjector().setMotion(Vec3.createVectorHelper(0.2, 0, -0.2)).setOffset(Vec3.createVectorHelper(0.8, 0, 0)).setAngleRange(0.05F, 0.02F).setDelay(20).setAmount(2);
CASING12GAUGE = new SpentCasing(CasingType.SHOTGUN).setScale(1.5F).setBounceMotion(0.05F, 0.02F);
}
public static GunConfiguration getSpas12Config() {
@ -98,12 +83,12 @@ public class Gun12GaugeFactory {
)
);
config.casingConfig = CASING_SPAS;
config.ejector = CASING_SPAS;
return config;
}
public static GunConfiguration getSpas12AltConfig() {
public static GunConfiguration getSpas12AltConfig() {
GunConfiguration config = new GunConfiguration();
@ -125,6 +110,8 @@ public static GunConfiguration getSpas12AltConfig() {
config.config.add(BulletConfigSyncingUtil.G12_DU);
config.config.add(BulletConfigSyncingUtil.G12_AM);
config.config.add(BulletConfigSyncingUtil.G12_SLEEK);
config.ejector = CASING_SPAS_ALT;
return config;
}
@ -152,6 +139,8 @@ public static GunConfiguration getSpas12AltConfig() {
config.config = HbmCollection.twelveGauge;
config.ejector = CASING_UBOINIK;
return config;
}
@ -203,6 +192,8 @@ public static GunConfiguration getSpas12AltConfig() {
config.config = HbmCollection.twelveGauge;
config.ejector = CASING_SSG;
return config;
}
@ -214,6 +205,8 @@ public static GunConfiguration getSpas12AltConfig() {
bullet.dmgMin = 5;
bullet.dmgMax = 7;
bullet.spentCasing = CASING12GAUGE.clone().register("12GaStock").setColor(0x2847FF, 0x757575);
return bullet;
}
@ -227,6 +220,8 @@ public static GunConfiguration getSpas12AltConfig() {
bullet.dmgMax = 7;
bullet.incendiary = 5;
bullet.spentCasing = CASING12GAUGE.clone().register("12GaInc").setColor(0xFF6329, 0x757575);
return bullet;
}
@ -242,6 +237,8 @@ public static GunConfiguration getSpas12AltConfig() {
bullet.HBRC = 80;
bullet.LBRC = 95;
bullet.spentCasing = CASING12GAUGE.clone().register("12GaShrap").setColor(0xF0E800, 0x757575);
return bullet;
}
@ -256,6 +253,8 @@ public static GunConfiguration getSpas12AltConfig() {
bullet.doesPenetrate = true;
bullet.leadChance = 50;
bullet.spentCasing = CASING12GAUGE.clone().register("12GaDU").setColor(0x62A362, 0x757575);
return bullet;
}
@ -280,6 +279,8 @@ public static GunConfiguration getSpas12AltConfig() {
};
bullet.spentCasing = CASING12GAUGE.clone().register("12GaAM").setColor(0x416645, 0x757575);
return bullet;
}
@ -289,6 +290,8 @@ public static GunConfiguration getSpas12AltConfig() {
bullet.ammo = new ComparableStack(ModItems.ammo_12gauge.stackFromEnum(Ammo12Gauge.SLEEK));
bullet.spentCasing = CASING12GAUGE.clone().register("12GaIF").setColor(0x2A2A2A, 0x757575);
return bullet;
}

View File

@ -3,12 +3,15 @@ package com.hbm.handler.guncfg;
import java.util.ArrayList;
import com.hbm.handler.BulletConfiguration;
import com.hbm.handler.CasingEjector;
import com.hbm.handler.GunConfiguration;
import com.hbm.inventory.RecipesCommon.ComparableStack;
import com.hbm.items.ModItems;
import com.hbm.items.ItemAmmoEnums.Ammo20Gauge;
import com.hbm.lib.HbmCollection;
import com.hbm.lib.HbmCollection.EnumGunManufacturer;
import com.hbm.particle.SpentCasing;
import com.hbm.particle.SpentCasing.CasingType;
import com.hbm.render.anim.BusAnimation;
import com.hbm.render.anim.BusAnimationKeyframe;
import com.hbm.render.anim.BusAnimationSequence;
@ -17,9 +20,19 @@ import com.hbm.render.util.RenderScreenOverlay.Crosshair;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.Vec3;
public class Gun20GaugeFactory {
private static final CasingEjector CASING_LEVER;
private static final SpentCasing CASING20GAUGE;
static {
CASING_LEVER = new CasingEjector().setMotion(Vec3.createVectorHelper(-0.4, 0.95, 0)).setOffset(Vec3.createVectorHelper(-0.55, 0, 0.5)).setAngleRange(0.01F, 0.05F);
CASING20GAUGE = new SpentCasing(CasingType.SHOTGUN).setScale(1.25F).setBounceMotion(0.01F, 0.05F);
}
public static GunConfiguration getShotgunConfig() {
GunConfiguration config = new GunConfiguration();
@ -53,6 +66,8 @@ public class Gun20GaugeFactory {
config.config = HbmCollection.twentyGauge;
config.ejector = CASING_LEVER;
return config;
}
@ -206,6 +221,8 @@ public class Gun20GaugeFactory {
bullet.dmgMin = 3;
bullet.dmgMax = 5;
bullet.spentCasing = CASING20GAUGE.clone().register("20GaStock").setColor(0xB52B2B, 0xEBC35E);
return bullet;
}
@ -219,6 +236,8 @@ public class Gun20GaugeFactory {
bullet.wear = 7;
bullet.style = BulletConfiguration.STYLE_NORMAL;
bullet.spentCasing = CASING20GAUGE.clone().register("20GaSlug").setColor(0x2A2A2A, 0xEBC35E);
return bullet;
}
@ -234,6 +253,8 @@ public class Gun20GaugeFactory {
bullet.HBRC = 2;
bullet.LBRC = 95;
bullet.spentCasing = CASING20GAUGE.clone().register("20GaFlech").setColor(0x2847FF, 0xEBC35E);
return bullet;
}
@ -247,6 +268,8 @@ public class Gun20GaugeFactory {
bullet.wear = 15;
bullet.incendiary = 5;
bullet.spentCasing = CASING20GAUGE.clone().register("20GaInc").setColor(0xFF6329, 0xEBC35E);
return bullet;
}
@ -262,6 +285,8 @@ public class Gun20GaugeFactory {
bullet.HBRC = 80;
bullet.LBRC = 95;
bullet.spentCasing = CASING20GAUGE.clone().register("20GaShrap").setColor(0xF0E800, 0xEBC35E);
return bullet;
}
@ -275,6 +300,8 @@ public class Gun20GaugeFactory {
bullet.wear = 25;
bullet.explosive = 0.5F;
bullet.spentCasing = CASING20GAUGE.clone().register("20GaExp").setColor(0xF0E800, 0xEBC35E);
return bullet;
}
@ -294,6 +321,8 @@ public class Gun20GaugeFactory {
bullet.effects = new ArrayList();
bullet.effects.add(new PotionEffect(Potion.poison.id, 10 * 20, 1));
bullet.spentCasing = CASING20GAUGE.clone().register("20GaCaus").setColor(0x64E800, 0xEBC35E);
return bullet;
}
@ -314,6 +343,8 @@ public class Gun20GaugeFactory {
bullet.effects.add(new PotionEffect(Potion.moveSlowdown.id, 10 * 20, 1));
bullet.effects.add(new PotionEffect(Potion.weakness.id, 10 * 20, 4));
bullet.spentCasing = CASING20GAUGE.clone().register("20GaShock").setColor(0x00EFEF, 0xEBC35E);
return bullet;
}
@ -328,6 +359,8 @@ public class Gun20GaugeFactory {
bullet.effects = new ArrayList();
bullet.effects.add(new PotionEffect(Potion.wither.id, 10 * 20, 2));
bullet.spentCasing = CASING20GAUGE.clone().register("20GaWith").setColor(0x391717, 0xEBC35E);
return bullet;
}
@ -337,6 +370,8 @@ public class Gun20GaugeFactory {
bullet.ammo = new ComparableStack(ModItems.ammo_20gauge.stackFromEnum(Ammo20Gauge.SLEEK));
bullet.spentCasing = CASING20GAUGE.clone().register("20GaIF").setColor(0x2A2A2A, 0xEBC35E);
return bullet;
}

View File

@ -8,6 +8,7 @@ import com.hbm.config.GeneralConfig;
import com.hbm.entity.projectile.EntityBulletBase;
import com.hbm.handler.BulletConfigSyncingUtil;
import com.hbm.handler.BulletConfiguration;
import com.hbm.handler.CasingEjector;
import com.hbm.handler.GunConfiguration;
import com.hbm.handler.HbmKeybinds;
import com.hbm.interfaces.IHoldableWeapon;
@ -19,7 +20,6 @@ import com.hbm.main.MainRegistry;
import com.hbm.packet.GunAnimationPacket;
import com.hbm.packet.GunButtonPacket;
import com.hbm.packet.PacketDispatcher;
import com.hbm.particle.SpentCasingConfig;
import com.hbm.render.anim.BusAnimation;
import com.hbm.render.anim.HbmAnimations.AnimType;
import com.hbm.render.util.RenderScreenOverlay;
@ -211,8 +211,8 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu
world.playSoundAtEntity(player, mainConfig.firingSound, 1.0F, mainConfig.firingPitch);
if(mainConfig.casingConfig != null && !mainConfig.casingConfig.isAfterReload())
spawnCasing(player, mainConfig.casingConfig, stack);
if(mainConfig.ejector != null && !mainConfig.ejector.getAfterReload())
trySpawnCasing(player, mainConfig.ejector, config, stack);
}
//unlike fire(), being called does not automatically imply success, some things may still have to be handled before spawning the projectile
@ -245,8 +245,8 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu
world.playSoundAtEntity(player, altConfig.firingSound, 1.0F, altConfig.firingPitch);
if(altConfig.casingConfig != null)
spawnCasing(player, altConfig.casingConfig, stack);
if(altConfig.ejector != null)
trySpawnCasing(player, altConfig.ejector, config, stack);
}
//spawns the actual projectile, can be overridden to change projectile entity
@ -297,6 +297,9 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu
}
if(getReloadCycle(stack) <= 0) {
BulletConfiguration prevCfg = BulletConfigSyncingUtil.pullConfig(mainConfig.config.get(getMagType(stack)));
if (getMag(stack) == 0)
resetAmmoType(stack, world, player);
@ -327,8 +330,8 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu
if(hasLoaded && mainConfig.reloadSoundEnd)
world.playSoundAtEntity(player, mainConfig.reloadSound, 1.0F, 1.0F);
if(mainConfig.casingConfig != null && mainConfig.casingConfig.isAfterReload())
spawnCasing(player, mainConfig.casingConfig, stack);
if(mainConfig.ejector != null && mainConfig.ejector.getAfterReload())
trySpawnCasing(player, mainConfig.ejector, prevCfg, stack);
InventoryUtil.tryConsumeAStack(player.inventory.mainInventory, 0, player.inventory.mainInventory.length, ammo);
} else {
@ -704,7 +707,12 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu
}
}
protected static void spawnCasing(Entity entity, SpentCasingConfig config, ItemStack stack) {
protected static void trySpawnCasing(Entity entity, CasingEjector ejector, BulletConfiguration 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.spentCasing == null) return; //abort if the bullet is caseless
NBTTagCompound data = new NBTTagCompound();
data.setString("type", "casing");
data.setDouble("posX", entity.posX);
@ -713,7 +721,9 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu
data.setFloat("pitch", (float) Math.toRadians(entity.rotationPitch));
data.setFloat("yaw", (float) Math.toRadians(entity.rotationYaw));
data.setBoolean("crouched", entity.isSneaking());
data.setString("name", config.getRegistryName());
data.setString("name", bullet.spentCasing.getName());
data.setInteger("ej", ejector.getId());
//TODO: use packets
MainRegistry.proxy.effectNT(data);
}
}

View File

@ -58,6 +58,7 @@ import com.hbm.entity.mob.botprime.*;
import com.hbm.entity.mob.siege.*;
import com.hbm.entity.particle.*;
import com.hbm.entity.projectile.*;
import com.hbm.handler.CasingEjector;
import com.hbm.handler.HbmKeybinds;
import com.hbm.handler.ImpactWorldHandler;
import com.hbm.handler.HbmKeybinds.EnumKeybind;
@ -1791,9 +1792,14 @@ public class ClientProxy extends ServerProxy {
}
if("casing".equals(type)) {
SpentCasingConfig casingConfig = SpentCasingConfig.get(data.getString("name"));
for(int i = 0; i < casingConfig.getCasingAmount(); i++)
casingConfig.spawnCasing(man, world, x, y, z, data.getFloat("pitch"), data.getFloat("yaw"), data.getBoolean("crouched"));
CasingEjector ejector = CasingEjector.fromId(data.getInteger("ej"));
if(ejector == null) return;
SpentCasing casingConfig = SpentCasing.fromName((data.getString("name")));
if(casingConfig == null) return;
for(int i = 0; i < ejector.getAmount(); i++) {
ejector.spawnCasing(man, casingConfig, world, x, y, z, data.getFloat("pitch"), data.getFloat("yaw"), data.getBoolean("crouched"));
}
}
}

View File

@ -2,6 +2,7 @@ package com.hbm.particle;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
@ -23,6 +24,7 @@ import net.minecraft.world.World;
@SideOnly(Side.CLIENT)
public class ParticleSpentCasing extends EntityFX
{
public static final Random rand = new Random();
private static float dScale = 0.05F, smokeJitter = 0.025F, smokeAccel = 0.5F;
private static byte maxSmokeGen = 60, maxSmokeLife = 120;
@ -30,14 +32,14 @@ public class ParticleSpentCasing extends EntityFX
private final TextureManager textureManager;
private final SpentCasingConfig config;
private final SpentCasing config;
private boolean smoke;
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, SpentCasingConfig config) {
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);
this.textureManager = textureManager;
this.momentumPitch = momentumPitch;
@ -45,9 +47,7 @@ public class ParticleSpentCasing extends EntityFX
this.config = config;
particleMaxAge = 240;
// smoke = config.getSmokeChance() == 0 ? true
// : config.getSmokeChance() < 0 ? false
// : rand.nextInt(config.getSmokeChance()) == 0;
smoke = rand.nextFloat() < config.getSmokeChance();
motionX = mx;
motionY = my;
@ -73,43 +73,37 @@ public class ParticleSpentCasing extends EntityFX
if(!onGroundPreviously && onGround)
tryPlayBounceSound();
// TODO Bounce factor in config
if(!onGroundPreviously && onGround) {
onGroundPreviously = true;
motionY = Math.log10(maxHeight - posY + 2);
momentumPitch = (float) rand.nextGaussian() * config.getPitchFactor();
momentumYaw = (float) rand.nextGaussian() * config.getYawFactor();
momentumPitch = (float) rand.nextGaussian() * config.getBouncePitch();
momentumYaw = (float) rand.nextGaussian() * config.getBounceYaw();
maxHeight = posY;
} else if(onGroundPreviously && !onGround) {
onGroundPreviously = false;
}
// if (particleAge > maxSmokeLife && !smokeNodes.isEmpty())
// smokeNodes.clear();
if (particleAge > maxSmokeLife && !smokeNodes.isEmpty())
smokeNodes.clear();
// if (smoke && particleAge <= maxSmokeLife)
// {
// final double side = (rotationYaw - prevRotationYaw) * 0.1D;
// final Vec3 prev = Vec3.createVectorHelper(motionX, motionY, motionZ);
// prev.rotateAroundY((float) Math.toRadians(rotationYaw));
//
// for (Pair<EasyLocation, Double> pair : smokeNodes)
// {
// final EasyLocation node = pair.getKey();
//
// node.posX += prev.xCoord * smokeAccel + rand.nextGaussian() * smokeJitter + side;
// node.posY += prev.yCoord + smokeAccel;
// node.posZ += prev.zCoord * smokeAccel + rand.nextGaussian() * smokeJitter;
// }
//
// if (particleAge < maxSmokeGen || inWater)
// {
// final double alpha = (particleAge / 20d);
// smokeNodes.add(new Pair<EasyLocation, Double>(EasyLocation.getZeroLocation(), alpha));
// }
// }
if(smoke && particleAge <= maxSmokeLife) {
//motion-based smoke changes were moved to rendering (to account for interp in realtime)
for(Pair<Vec3, Double> pair : smokeNodes) {
final Vec3 node = pair.getKey();
node.xCoord += rand.nextGaussian() * smokeJitter;
node.zCoord += rand.nextGaussian() * smokeJitter;
}
if(particleAge < maxSmokeGen || inWater) {
final double alpha = (particleAge / 20d);
smokeNodes.add(new Pair<Vec3, Double>(Vec3.createVectorHelper(0, 0, 0), alpha));
}
}
prevRotationPitch = rotationPitch;
prevRotationYaw = rotationYaw;
@ -152,10 +146,11 @@ public class ParticleSpentCasing extends EntityFX
GL11.glScalef(config.getScaleX(), config.getScaleY(), config.getScaleZ());
if(config.doesOverrideColor())
GL11.glColor3b((byte) config.getRedOverride(), (byte) config.getGreenOverride(), (byte) config.getBlueOverride());
ResourceManager.casings.renderPart(config.getCasingType().objName);
for(String name : config.getType().partNames) {
//TODO: set part color
ResourceManager.casings.renderPart(name);
}
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
/*if(!smokeNodes.isEmpty()) {
@ -202,8 +197,10 @@ public class ParticleSpentCasing extends EntityFX
private void tryPlayBounceSound() {
if(!config.getBounceSound().isEmpty()) {
worldObj.playSoundAtEntity(this, config.getBounceSound(), 2, 1);
String sound = config.getSound();
if(sound != null && !sound.isEmpty()) {
worldObj.playSoundAtEntity(this, sound, 2, 1);
}
}
}

View File

@ -0,0 +1,105 @@
package com.hbm.particle;
import java.util.HashMap;
/**
* Definition for spent casing particles, what style and color they should use
* @author uffr, hbm
*/
public class SpentCasing implements Cloneable {
public static final HashMap<String, SpentCasing> casingMap = new HashMap();
public enum CasingType {
BRASS_STRAIGHT_WALL("Straight"),
BRASS_BOTTLENECK("Bottleneck"),
SHOTGUN("Shotgun", "ShotgunBase"), //plastic shell, brass case
AR2("AR2", "AR2Highlight"); //plug, back detailing
public final String[] partNames;
private CasingType(String... names) {
this.partNames = names;
}
}
private String registryName;
private float scaleX = 1F;
private float scaleY = 1F;
private float scaleZ = 1F;
private int[] colors;
private CasingType type;
private String bounceSound;
private float smokeChance;
private float bounceYaw = 0F;
private float bouncePitch = 0F;
public SpentCasing(CasingType type) {
this.type = type;
}
public SpentCasing register(String name) {
this.registryName = name;
casingMap.put(name, this);
return this;
}
public SpentCasing setScale(float scale) {
this.scaleX = scale;
this.scaleY = scale;
this.scaleZ = scale;
return this;
}
public SpentCasing setScale(float x, float y, float z) {
this.scaleX = x;
this.scaleY = y;
this.scaleZ = z;
return this;
}
public SpentCasing setColor(int... color) {
this.colors = color;
return this;
}
public SpentCasing setSound(String bounce) {
this.bounceSound = bounce;
return this;
}
public SpentCasing setupSmoke(float chance, float lift, float duration) {
this.smokeChance = chance;
return this;
}
public static SpentCasing fromName(String name) {
return casingMap.get(name);
}
public SpentCasing setBounceMotion(float yaw, float pitch) {
this.bounceYaw = yaw;
this.bouncePitch = pitch;
return this;
}
public String getName() { return this.registryName; }
public float getScaleX() { return this.scaleX; }
public float getScaleY() { return this.scaleY; }
public float getScaleZ() { return this.scaleZ; }
public int[] getColors() { return this.colors; }
public CasingType getType() { return this.type; }
public String getSound() { return this.bounceSound; }
public float getSmokeChance() { return this.smokeChance; }
public float getBounceYaw() { return this.bounceYaw; }
public float getBouncePitch() { return this.bouncePitch; }
@Override
public SpentCasing clone() {
try {
return (SpentCasing) super.clone();
} catch(CloneNotSupportedException e) {
return new SpentCasing(this.type);
}
}
}

View File

@ -1,323 +0,0 @@
package com.hbm.particle;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector3f;
import org.lwjgl.util.vector.Vector4f;
import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableMap;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
@Beta
public class SpentCasingConfig {
private static final Map<String, SpentCasingConfig> CONFIG_MAP = new HashMap<String, SpentCasingConfig>();
private static final Random RANDOM = new Random();
public enum CasingType {
BRASS_STRAIGHT_WALL("Straight"),
BRASS_BOTTLENECK("Bottleneck"),
SHOTGUN("Shotgun"),
AR2("AR2");
public final String objName;
private CasingType(String objName) {
this.objName = objName;
}
}
/**Unique name used for map lookup.**/
private final String registryName;
/**Change position of the ejecting shell.**/
private final Vec3 posOffset;
/**Set initial motion after ejecting.**/
private final Vec3 initialMotion;
/**Multipliers for random pitch and yaw.**/
private final float pitchFactor, yawFactor;
/**Rescale the sprite to match the approximate scale of the rounds.**/
private final float scaleX, scaleY, scaleZ;
/**Overrides for the sprite colors.**/
private final int redOverride, greenOverride, blueOverride;
/**Whether or not to override the default sprite color scheme.**/
private final boolean overrideColor;
/**The type of casing.**/
private final CasingType casingType;
/**Amount of casings to spawn per event. Default 1.**/
private final byte casingAmount;
/**If the casing(s) should be spawned after reloading, instead of after firing.**/
private final boolean afterReload;
/**Sound effect for bouncing. Make empty string to have no sound.**/
private final String bounceSound;
/**Delay before casings are actually spawned**/
private final byte delay;
/**Chance for the casing to emit smoke. 0 for 100% chance and -1 for it to never make smoke.**/
private final byte smokeChance;
// TODO Setting to disregard crouch effect and/or another offset specifically for crouching which can be set to null to use the default one
public SpentCasingConfig(
String registryName, Vec3 posOffset, Vec3 initialMotion, float pitchFactor, float yawFactor,
float scaleX, float scaleY, float scaleZ, int redOverride, int greenOverride, int blueOverride,
boolean overrideColor, CasingType casingType, byte casingAmount, boolean afterReload, String bounceSound,
byte delay, byte smokeChance) {
this.registryName = registryName;
this.posOffset = posOffset;
this.initialMotion = initialMotion;
this.pitchFactor = pitchFactor;
this.yawFactor = yawFactor;
this.scaleX = scaleX;
this.scaleY = scaleY;
this.scaleZ = scaleZ;
this.redOverride = redOverride;
this.greenOverride = greenOverride;
this.blueOverride = blueOverride;
this.overrideColor = overrideColor;
this.casingType = casingType;
this.casingAmount = casingAmount;
this.afterReload = afterReload;
this.bounceSound = bounceSound;
this.delay = delay;
this.smokeChance = smokeChance;
CONFIG_MAP.put(registryName, this);
}
public void spawnCasing(TextureManager textureManager, World world, double x, double y, double z, float pitch, float yaw, boolean crouched) {
Vec3 rotatedMotionVec = rotateVector(getInitialMotion(),
pitch + (float) RANDOM.nextGaussian() * getPitchFactor(), yaw + (float) RANDOM.nextGaussian() * getPitchFactor(),
getPitchFactor(), getPitchFactor());
ParticleSpentCasing casing = new ParticleSpentCasing(textureManager, world, x,
y, z, rotatedMotionVec.xCoord, rotatedMotionVec.yCoord, rotatedMotionVec.zCoord,
// 0, 0,
(float) (getPitchFactor() * RANDOM.nextGaussian()), (float) (getYawFactor() * RANDOM.nextGaussian()),
this);
offsetCasing(casing, getPosOffset(), pitch, yaw, crouched);
casing.rotationPitch = (float) Math.toDegrees(pitch);
casing.rotationYaw = (float) Math.toDegrees(yaw);
if(overrideColor)
casing.setRBGColorF(redOverride / 255f, blueOverride / 255f, greenOverride / 255f);
Minecraft.getMinecraft().effectRenderer.addEffect(casing);
}
// Rotate a position
private static void offsetCasing(ParticleSpentCasing casing, Vec3 offset, float pitch, float yaw, boolean crouched)
{
// // x-axis offset, 0 if crouched to center
// final double oX = crouched ? 0 : offset.posX();
// // Trigonometric operations, saved for convenience
// final double sinP = Math.sin(pitch), cosP = Math.cos(pitch), sinY = Math.sin(yaw), cosY = Math.cos(yaw);
// // New offsets
// final double newX = oX * cosY - offset.posZ() * sinY,
// newY = offset.posY() * cosP - sinP * (oX * sinY + offset.posZ() * cosY),
// newZ = offset.posZ() * sinP + cosP * (oX * sinY + offset.posZ() * cosY);
//
// // Apply
// casing.setPosition(casing.posX + newX, casing.posY + newY, casing.posZ + newZ);
// x-axis offset, 0 if crouched to center
final float oX = (float) (crouched ? 0 : offset.xCoord);
// Create rotation matrices for pitch and yaw
final Matrix4f pitchMatrix = new Matrix4f(), yawMatrix = new Matrix4f();
pitchMatrix.rotate(pitch, new Vector3f(1, 0, 0)); // modify axis of rotation
yawMatrix.rotate(-yaw, new Vector3f(0, 1, 0));
// Multiply matrices to get combined rotation matrix
final Matrix4f rotMatrix = Matrix4f.mul(yawMatrix, pitchMatrix, null);
// Create vector representing the offset and apply rotation
final Vector4f offsetVector = new Vector4f(oX, (float) offset.yCoord, (float) offset.zCoord, 1); // set fourth coordinate to 1
Matrix4f.transform(rotMatrix, offsetVector, offsetVector);
final Vector3f result = new Vector3f(); // create result vector
result.set(offsetVector.x, offsetVector.y, offsetVector.z); // set result vector using transformed coordinates
// Apply rotation
casing.setPosition(casing.posX + result.x, casing.posY + result.y, casing.posZ + result.z);
}
// Rotate a vector
private static Vec3 rotateVector(Vec3 vector, float pitch, float yaw, float pitchFactor, float yawFactor)
{
// Apply randomness to vector
vector.xCoord += RANDOM.nextGaussian() * yawFactor;
vector.yCoord += RANDOM.nextGaussian() * pitchFactor;
vector.zCoord += RANDOM.nextGaussian() * yawFactor;
final Matrix4f pitchMatrix = new Matrix4f(), yawMatrix = new Matrix4f();
pitchMatrix.setIdentity();
pitchMatrix.rotate(-pitch, new Vector3f(1, 0, 0));
yawMatrix.setIdentity();
yawMatrix.rotate(-yaw, new Vector3f(0, 1, 0));
final Vector4f vector4f = new Vector4f((float) vector.xCoord, (float) vector.yCoord, (float) vector.zCoord, 1);
Matrix4f.transform(pitchMatrix, vector4f, vector4f);
Matrix4f.transform(yawMatrix, vector4f, vector4f);
return Vec3.createVectorHelper(vector4f.x, vector4f.y, vector4f.z);
}
public Vec3 getPosOffset()
{
return posOffset;
}
public Vec3 getInitialMotion()
{
return Vec3.createVectorHelper(initialMotion.xCoord, initialMotion.yCoord, initialMotion.zCoord);
}
public float getScaleX()
{
return scaleX;
}
public float getScaleY()
{
return scaleY;
}
public float getScaleZ()
{
return scaleZ;
}
public float getPitchFactor()
{
return pitchFactor;
}
public float getYawFactor()
{
return yawFactor;
}
public int getRedOverride()
{
return redOverride;
}
public int getGreenOverride()
{
return greenOverride;
}
public int getBlueOverride()
{
return blueOverride;
}
public boolean doesOverrideColor()
{
return overrideColor;
}
public CasingType getCasingType()
{
return casingType;
}
public byte getCasingAmount()
{
return casingAmount;
}
public boolean isAfterReload()
{
return afterReload;
}
public String getRegistryName()
{
return registryName;
}
public String getBounceSound()
{
return bounceSound;
}
public byte getDelay()
{
return delay;
}
public byte getSmokeChance()
{
return smokeChance;
}
/**
* Convert to a new builder for modification.
* @param newName The new registry name.
* @return A new builder with all the settings inherited from this config, except for registry name.
*/
public SpentCasingConfigBuilder toBuilder(String newName)
{
final SpentCasingConfigBuilder builder = new SpentCasingConfigBuilder(newName, casingType, overrideColor);
builder.setAfterReload(afterReload).setBlueOverride(blueOverride).setBounceSound(bounceSound).setCasingAmount(casingAmount)
.setDelay(delay).setGreenOverride(greenOverride).setInitialMotion(getInitialMotion()).setPitchFactor(pitchFactor)
.setPosOffset(getPosOffset()).setRedOverride(redOverride).setScaleX(scaleX).setScaleY(scaleY).setScaleZ(scaleZ)
.setSmokeChance(smokeChance).setYawFactor(yawFactor);
return builder;
}
@Override
public int hashCode()
{
return Objects.hash(afterReload, blueOverride, bounceSound, casingAmount, casingType, delay, greenOverride,
initialMotion.xCoord, initialMotion.yCoord, initialMotion.zCoord, overrideColor, pitchFactor,
posOffset, redOverride, registryName, scaleX, scaleY, scaleZ, smokeChance, yawFactor);
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (!(obj instanceof SpentCasingConfig))
return false;
final SpentCasingConfig other = (SpentCasingConfig) obj;
return afterReload == other.afterReload && blueOverride == other.blueOverride
&& Objects.equals(bounceSound, other.bounceSound) && casingAmount == other.casingAmount
&& casingType == other.casingType && delay == other.delay && greenOverride == other.greenOverride
&& Double.doubleToLongBits(initialMotion.xCoord) == Double.doubleToLongBits(other.initialMotion.xCoord)
&& Double.doubleToLongBits(initialMotion.yCoord) == Double.doubleToLongBits(other.initialMotion.yCoord)
&& Double.doubleToLongBits(initialMotion.zCoord) == Double.doubleToLongBits(other.initialMotion.zCoord)
&& overrideColor == other.overrideColor
&& Float.floatToIntBits(pitchFactor) == Float.floatToIntBits(other.pitchFactor)
&& Objects.equals(posOffset, other.posOffset) && redOverride == other.redOverride
&& Objects.equals(registryName, other.registryName)
&& Float.floatToIntBits(scaleX) == Float.floatToIntBits(other.scaleX)
&& Float.floatToIntBits(scaleY) == Float.floatToIntBits(other.scaleY)
&& Float.floatToIntBits(scaleZ) == Float.floatToIntBits(other.scaleZ)
&& smokeChance == other.smokeChance
&& Float.floatToIntBits(yawFactor) == Float.floatToIntBits(other.yawFactor);
}
@Override
public String toString()
{
final StringBuilder builder = new StringBuilder();
builder.append("SpentCasingConfig [registryName=").append(registryName).append(", posOffset=").append(posOffset)
.append(", initialMotion=").append(initialMotion).append(", pitchFactor=").append(pitchFactor)
.append(", yawFactor=").append(yawFactor).append(", scaleX=").append(scaleX).append(", scaleY=")
.append(scaleY).append(", scaleZ=").append(scaleZ).append(", redOverride=").append(redOverride)
.append(", greenOverride=").append(greenOverride).append(", blueOverride=").append(blueOverride)
.append(", overrideColor=").append(overrideColor).append(", casingType=").append(casingType)
.append(", casingAmount=").append(casingAmount).append(", afterReload=").append(afterReload)
.append(", bounceSound=").append(bounceSound).append(", delay=").append(delay).append(", smokeChance=")
.append(smokeChance).append("]");
return builder.toString();
}
public static boolean containsKey(String key)
{
return CONFIG_MAP.containsKey(key);
}
public static SpentCasingConfig get(String key)
{
return CONFIG_MAP.get(key);
}
public static Map<String, SpentCasingConfig> getConfigMap()
{
return ImmutableMap.copyOf(CONFIG_MAP);
}
}

View File

@ -1,377 +0,0 @@
package com.hbm.particle;
import java.util.Objects;
import com.google.common.annotations.Beta;
import com.hbm.main.MainRegistry;
import com.hbm.particle.SpentCasingConfig.CasingType;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
@Beta
public class SpentCasingConfigBuilder implements Cloneable
{
/**Unique name used for map lookup.**/
private String registryName;
/**Change position of the ejecting shell.**/
private Vec3 posOffset = Vec3.createVectorHelper(0, 0, 0);
/**Set initial motion after ejecting.**/
private Vec3 initialMotion = Vec3.createVectorHelper(0, 0, 0);
/**Multipliers for random pitch and yaw.**/
private float pitchFactor, yawFactor;
/**Rescale the sprite to match the approximate scale of the rounds.**/
private float scaleX = 1, scaleY = 1, scaleZ = 1;
/**Overrides for the sprite colors.**/
private int redOverride, greenOverride, blueOverride;
/**Whether or not to override the default sprite color scheme.**/
private boolean overrideColor;
/**The type of casing.**/
private CasingType casingType = CasingType.BRASS_STRAIGHT_WALL;
/**Amount of casings to spawn per event. Default 1.**/
private byte casingAmount = 1;
/**If the casing(s) should be spawned after reloading, instead of after firing.**/
private boolean afterReload;
/**Sound effect for bouncing. Make empty string to have no sound.**/
private String bounceSound = "";
/**Delay before casings are actually spawned**/
private byte delay;
/**Chance for the casing to emit smoke. 0 for 100% chance and -1 for it to never make smoke.**/
private byte smokeChance = -1;
// TODO Setting to disregard crouch effect and/or another offset specifically for crouching which can be set to null to use the default one
/**
* Constructor with fields for the required bare minimum parameters.<br>
* All parameters may overridden using setters at any time at your discretion, however.
* @param registryName The unique name for map lookup. Null not permitted, becomes empty string.
* @param casingType Type of casing model to use. Null not permitted, defaults to straight wall type.
* @param overrideColor Whether or not the config will override the model texture's color.
*/
public SpentCasingConfigBuilder(String registryName, CasingType casingType, boolean overrideColor) {
this.registryName = registryName == null ? "" : registryName;
this.casingType = casingType == null ? CasingType.BRASS_STRAIGHT_WALL : casingType;
this.overrideColor = overrideColor;
}
public Vec3 getPosOffset() {
return posOffset;
}
/**
* Set the relative x, y, z coordinate offset on spawn.
* @param posOffset Any ILocationProvider that serves as the offset. Null becomes a zero location.
* @return Itself for chaining.
*/
public SpentCasingConfigBuilder setPosOffset(Vec3 posOffset) {
this.posOffset = posOffset == null ? Vec3.createVectorHelper(0, 0, 0) : posOffset;
return this;
}
public Vec3 getInitialMotion() {
return initialMotion;
}
/**
* Sets the casing's initial relative x, y, z motion on spawn.
* @param initialMotion Vector representing the initial motion. Null becomes a zero vector.
* @return Itself for chaining.
*/
public SpentCasingConfigBuilder setInitialMotion(Vec3 initialMotion) {
this.initialMotion = initialMotion == null ? Vec3.createVectorHelper(0, 0, 0) : initialMotion;
return this;
}
public double getScaleX() {
return scaleX;
}
/**
* Scale of the model on its x-axis.
* @param scaleX The scale/stretch factor of the model on the x-axis.
* @return Itself for chaining.
*/
public SpentCasingConfigBuilder setScaleX(float scaleX) {
this.scaleX = scaleX;
return this;
}
public double getScaleY() {
return scaleY;
}
/**
* Scale of the model on its y-axis.
* @param scaleY The scale/stretch factor of the model on the y-axis.
* @return Itself for chaining.
*/
public SpentCasingConfigBuilder setScaleY(float scaleY) {
this.scaleY = scaleY;
return this;
}
public float getScaleZ() {
return scaleZ;
}
/**
* Scale of the model on its z-axis.
* @param scaleZ The scale/stretch of the model on the z-axis.
* @return Itself for chaining.
*/
public SpentCasingConfigBuilder setScaleZ(float scaleZ) {
this.scaleZ = scaleZ;
return this;
}
public float getPitchFactor() {
return pitchFactor;
}
/**
* Multiplier for random pitch-related motion. Recommended to keep in the thousanths (0.00X), as even with the hundreths (0.0X) the pitch can get crazy at times.
* @param pitchFactor The multiplier.
* @return Itself for chaining.
*/
public SpentCasingConfigBuilder setPitchFactor(float pitchFactor) {
this.pitchFactor = pitchFactor;
return this;
}
public float getYawFactor() {
return yawFactor;
}
/**
* Multiplier for random yaw-related motion. Recommended to keep in the thousanths (0.00X), as even with the hundreths (0.0X) the yaw can get crazy at times.
* @param yawFactor The multiplier.
* @return Itself for chaining.
*/
public SpentCasingConfigBuilder setYawFactor(float yawFactor) {
this.yawFactor = yawFactor;
return this;
}
public int getRedOverride() {
return redOverride;
}
/**
* Red color override. Clamped between 0-255, but I don't know how it actually works on the receiving end, so feel free to change.
* @param redOverride Red color override.
* @return Itself for chaining.
*/
public SpentCasingConfigBuilder setRedOverride(int redOverride) {
this.redOverride = MathHelper.clamp_int(redOverride, 0, 255);
return this;
}
public int getGreenOverride() {
return greenOverride;
}
/**
* Green color override. Clamped between 0-255, but I don't know how it actually works on the receiving end, so feel free to change.
* @param greenOverride Green color override.
* @return Itself for chaining.
*/
public SpentCasingConfigBuilder setGreenOverride(int greenOverride) {
this.greenOverride = MathHelper.clamp_int(greenOverride, 0, 255);
return this;
}
public int getBlueOverride() {
return blueOverride;
}
/**
* Blue color override. Clamped between 0-255, but I don't know how it actually works on the receiving end, so feel free to change.
* @param blueOverride Blue color override.
* @return Itself for chaining.
*/
public SpentCasingConfigBuilder setBlueOverride(int blueOverride) {
this.blueOverride = MathHelper.clamp_int(blueOverride, 0, 255);
return this;
}
public boolean doesOverrideColor() {
return overrideColor;
}
/**
* Sets whether or not the config will override color. If false, the integer overrides will be ignored.
* @param overrideColor True, to use the integer color overrides, false to ignore them.
* @return Itself for chaining.
*/
public SpentCasingConfigBuilder setOverrideColor(boolean overrideColor) {
this.overrideColor = overrideColor;
return this;
}
public CasingType getCasingType() {
return casingType;
}
/**
* Sets the model the casing will use.
* @param casingType One of the 4 casing model types. Null is not permitted, will have no effect.
* @return Itself for chaining.
*/
public SpentCasingConfigBuilder setCasingType(CasingType casingType) {
this.casingType = casingType == null ? this.casingType : casingType;
return this;
}
public byte getCasingAmount() {
return casingAmount;
}
/**
* Sets the amount of casings to spawn. Default is 1.
* @param casingAmount Amount of casings to spawn. Clamped to a positive byte (0 - 127).
* @return Itself for chaining.
*/
public SpentCasingConfigBuilder setCasingAmount(int casingAmount) {
this.casingAmount = (byte) MathHelper.clamp_int(casingAmount, 0, 127);
return this;
}
public boolean isAfterReload() {
return afterReload;
}
/**
* Sets whether or not the casing will be spawned after reloading is done or after firing.
* @param afterReload If true, casings will be spawned when reloading, false, they will be spawned after firing.
* @return Itself for chaining.
*/
public SpentCasingConfigBuilder setAfterReload(boolean afterReload) {
this.afterReload = afterReload;
return this;
}
public String getRegistryName() {
return registryName;
}
/**
* Resets the unique name for the config used in map lookup.<br>
* As the real class is self-registering, <i>make sure to set this in reused builders.</i>
* @param registryName The registry name to use. Null is not permitted, becomes an empty string.
* @return Itself for chaining.
*/
public SpentCasingConfigBuilder setRegistryName(String registryName) {
this.registryName = registryName == null ? "" : registryName;
return this;
}
public String getBounceSound() {
return bounceSound;
}
/**
* The sound used when bouncing. If empty, no sound will be made.
* @param bounceSound The sound path. Null is not permitted, becomes an empty string.
* @return Itself for chaining.
*/
public SpentCasingConfigBuilder setBounceSound(String bounceSound) {
this.bounceSound = bounceSound == null ? "" : bounceSound;
return this;
}
public byte getDelay() {
return delay;
}
/**
* The delay in ticks before spawning.
* @param delay Tick spawn delay. Must be nonnegative, otherwise 0.
* @return Itself for chaining.
*/
public SpentCasingConfigBuilder setDelay(int delay) {
this.delay = (byte) (delay < 0 ? 0 : delay);
return this;
}
public byte getSmokeChance() {
return smokeChance;
}
/**
* Chance for the casing to emit smoke. 0 for 100% chance and -1 for it to never make smoke.
* @param smokeChance Chance to emit smoke. Clamped to a byte.
* @return Itself for chaining.
*/
public SpentCasingConfigBuilder setSmokeChance(int smokeChance) {
this.smokeChance = (byte) smokeChance;
return this;
}
/**
* Constructs the true immutable config with all settings loaded from this builder.<br>
* This builder may be reused as all non-immutable and primitive fields are copied before being passed to the constructor.<br>
* The config's constructor is self-registering.
* @return The finished config with its settings specified by this builder.
*/
public SpentCasingConfig build() {
return new SpentCasingConfig(registryName, Vec3.createVectorHelper(posOffset.xCoord, posOffset.yCoord, posOffset.zCoord),
Vec3.createVectorHelper(initialMotion.xCoord, initialMotion.yCoord, initialMotion.zCoord), pitchFactor,
yawFactor, scaleX, scaleY, scaleZ, redOverride, greenOverride, blueOverride, overrideColor, casingType,
casingAmount, afterReload, bounceSound, delay, smokeChance);
}
@Override
public int hashCode() {
return Objects.hash(afterReload, blueOverride, bounceSound, casingAmount, casingType, delay, greenOverride,
initialMotion.xCoord, initialMotion.yCoord, initialMotion.zCoord, overrideColor, pitchFactor,
posOffset, redOverride, registryName, scaleX, scaleY, scaleZ, smokeChance, yawFactor);
}
@Override
public boolean equals(Object obj) {
if(this == obj) return true;
if(!(obj instanceof SpentCasingConfigBuilder)) return false;
SpentCasingConfigBuilder other = (SpentCasingConfigBuilder) obj;
return afterReload == other.afterReload && blueOverride == other.blueOverride
&& Objects.equals(bounceSound, other.bounceSound) && casingAmount == other.casingAmount
&& casingType == other.casingType && delay == other.delay && greenOverride == other.greenOverride
&& Double.doubleToLongBits(initialMotion.xCoord) == Double.doubleToLongBits(other.initialMotion.xCoord)
&& Double.doubleToLongBits(initialMotion.yCoord) == Double.doubleToLongBits(other.initialMotion.yCoord)
&& Double.doubleToLongBits(initialMotion.zCoord) == Double.doubleToLongBits(other.initialMotion.zCoord)
&& overrideColor == other.overrideColor
&& Float.floatToIntBits(pitchFactor) == Float.floatToIntBits(other.pitchFactor)
&& Objects.equals(posOffset, other.posOffset) && redOverride == other.redOverride
&& Objects.equals(registryName, other.registryName)
&& Float.floatToIntBits(scaleX) == Float.floatToIntBits(other.scaleX)
&& Float.floatToIntBits(scaleY) == Float.floatToIntBits(other.scaleY)
&& Float.floatToIntBits(scaleZ) == Float.floatToIntBits(other.scaleZ)
&& smokeChance == other.smokeChance
&& Float.floatToIntBits(yawFactor) == Float.floatToIntBits(other.yawFactor);
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("SpentCasingConfigBuilder [registryName=").append(registryName).append(", posOffset=")
.append(posOffset).append(", initialMotion=").append(initialMotion).append(", pitchFactor=")
.append(pitchFactor).append(", yawFactor=").append(yawFactor).append(", scaleX=").append(scaleX)
.append(", scaleY=").append(scaleY).append(", scaleZ=").append(scaleZ).append(", redOverride=")
.append(redOverride).append(", greenOverride=").append(greenOverride).append(", blueOverride=")
.append(blueOverride).append(", overrideColor=").append(overrideColor).append(", casingType=")
.append(casingType).append(", casingAmount=").append(casingAmount).append(", afterReload=")
.append(afterReload).append(", bounceSound=").append(bounceSound).append(", delay=").append(delay)
.append(", smokeChance=").append(smokeChance).append(']');
return builder.toString();
}
@Override
public SpentCasingConfigBuilder clone() {
try {
return (SpentCasingConfigBuilder) super.clone();
} catch(CloneNotSupportedException e) {
MainRegistry.logger.catching(e);
return new SpentCasingConfigBuilder(registryName, casingType, overrideColor);
}
}
}