YOU KNOW HOW WE DO IT

This commit is contained in:
Boblet 2025-03-19 16:28:55 +01:00
parent ccc80781b2
commit 5a9f3e75dc
20 changed files with 427 additions and 99 deletions

View File

@ -1,6 +1,7 @@
package com.hbm.inventory.container;
import com.hbm.items.weapon.sedna.ItemGunBaseNT;
import com.hbm.items.weapon.sedna.mods.WeaponModManager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
@ -26,30 +27,122 @@ public class ContainerWeaponTable extends Container {
public boolean isItemValid(ItemStack stack) {
return stack.getItem() instanceof ItemGunBaseNT;
}
@Override
public void putStack(ItemStack stack) {
if(stack != null) {
ItemStack[] mods = WeaponModManager.getUpgradeItems(stack);
if(mods != null) for(int i = 0; i < Math.min(mods.length, 7); i++) {
ContainerWeaponTable.this.mods.setInventorySlotContents(i, mods[i]);
}
}
super.putStack(stack);
}
@Override
public void onPickupFromSlot(EntityPlayer player, ItemStack stack) {
super.onPickupFromSlot(player, stack);
WeaponModManager.install(
stack,
mods.getStackInSlot(0),
mods.getStackInSlot(1),
mods.getStackInSlot(2),
mods.getStackInSlot(3),
mods.getStackInSlot(4),
mods.getStackInSlot(5),
mods.getStackInSlot(6));
for(int i = 0; i < 7; i++) {
ItemStack mod = ContainerWeaponTable.this.mods.getStackInSlot(i);
if(WeaponModManager.isApplicable(stack, mod, false)) ContainerWeaponTable.this.mods.setInventorySlotContents(i, null);
}
}
});
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 9; j++) {
this.addSlotToContainer(new Slot(inventory, j + i * 9 + 9, 8 + j * 18 + 22, 158 + i * 18));
this.addSlotToContainer(new Slot(inventory, j + i * 9 + 9, 8 + j * 18, 158 + i * 18));
}
}
for(int i = 0; i < 9; i++) {
this.addSlotToContainer(new Slot(inventory, i, 8 + i * 18 + 22, 216));
this.addSlotToContainer(new Slot(inventory, i, 8 + i * 18, 216));
}
this.onCraftMatrixChanged(this.mods);
}
@Override
public void onContainerClosed(EntityPlayer player) {
super.onContainerClosed(player);
if(!player.worldObj.isRemote) {
for(int i = 0; i < this.mods.getSizeInventory(); ++i) {
ItemStack itemstack = this.mods.getStackInSlotOnClosing(i);
if(itemstack != null) {
player.dropPlayerItemWithRandomChoice(itemstack, false);
}
}
ItemStack itemstack = this.gun.getStackInSlotOnClosing(0);
if(itemstack != null) {
WeaponModManager.uninstall(itemstack);
player.dropPlayerItemWithRandomChoice(itemstack, false);
}
}
}
@Override
public boolean canInteractWith(EntityPlayer player) {
return true;
}
@Override
public ItemStack transferStackInSlot(EntityPlayer p_82846_1_, int par2) {
return null;
}
public class ModSlot extends Slot {
public ModSlot(IInventory inventory, int index, int x, int y) {
super(inventory, index, x, y);
}
@Override
public boolean isItemValid(ItemStack stack) {
return gun.getStackInSlot(0) != null && WeaponModManager.isApplicable(gun.getStackInSlot(0), stack, true);
}
@Override
public void putStack(ItemStack stack) {
super.putStack(stack);
refreshInstalledMods();
}
@Override
public void onPickupFromSlot(EntityPlayer player, ItemStack stack) {
super.onPickupFromSlot(player, stack);
refreshInstalledMods();
}
public void refreshInstalledMods() {
if(gun.getStackInSlot(0) == null) return;
WeaponModManager.uninstall(gun.getStackInSlot(0));
WeaponModManager.install(
gun.getStackInSlot(0),
mods.getStackInSlot(0),
mods.getStackInSlot(1),
mods.getStackInSlot(2),
mods.getStackInSlot(3),
mods.getStackInSlot(4),
mods.getStackInSlot(5),
mods.getStackInSlot(6)); //miscalculated, slot array isn't visible - fuck!
}
}
}

View File

@ -11,7 +11,7 @@ import net.minecraft.util.ResourceLocation;
public class GUIWeaponTable extends GuiInfoContainer {
public static ResourceLocation texture = new ResourceLocation(RefStrings.MODID + ":textures/gui/machine/gui_armor_modifier.png");
public static ResourceLocation texture = new ResourceLocation(RefStrings.MODID + ":textures/gui/machine/gui_weapon_modifier.png");
public int left;
public int top;
@ -37,5 +37,6 @@ public class GUIWeaponTable extends GuiInfoContainer {
protected void drawGuiContainerBackgroundLayer(float inter, int mX, int mY) {
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
this.mc.getTextureManager().bindTexture(texture);
drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize);
}
}

View File

@ -1506,6 +1506,8 @@ public class ModItems {
public static Item ammo_standard;
public static Item ammo_secret;
public static Item weapon_mod_test;
public static Item crucible;
public static Item stick_dynamite;
@ -6485,6 +6487,8 @@ public class ModItems {
GameRegistry.registerItem(ammo_standard, ammo_standard.getUnlocalizedName());
GameRegistry.registerItem(ammo_secret, ammo_secret.getUnlocalizedName());
GameRegistry.registerItem(weapon_mod_test, weapon_mod_test.getUnlocalizedName());
//Ammo
GameRegistry.registerItem(gun_b92_ammo, gun_b92_ammo.getUnlocalizedName());

View File

@ -10,6 +10,7 @@ import com.hbm.items.weapon.sedna.ItemGunBaseNT.SmokeNode;
import com.hbm.items.weapon.sedna.factory.GunStateDecider;
import com.hbm.items.weapon.sedna.factory.Lego;
import com.hbm.items.weapon.sedna.hud.IHUDComponent;
import com.hbm.items.weapon.sedna.mods.WeaponModManager;
import com.hbm.render.anim.BusAnimation;
import com.hbm.render.anim.HbmAnimations.AnimType;
@ -51,6 +52,7 @@ public class GunConfig {
/* FIELDS */
public int index;
/** List of receivers used by the gun, primary and secondary are usually indices 0 and 1 respectively, if applicable */
protected Receiver[] receivers_DNA;
protected float durability_DNA;
@ -83,32 +85,32 @@ public class GunConfig {
/* GETTERS */
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 int getInspectDuration(ItemStack stack) { return WeaponUpgradeManager.eval(inspectDuration_DNA, stack, I_INSPECTDURATION, this); }
public boolean getInspectCancel(ItemStack stack) { return WeaponUpgradeManager.eval(inspectCancel_DNA, stack, I_INSPECTCANCEL, this); }
public Crosshair getCrosshair(ItemStack stack) { return WeaponUpgradeManager.eval(crosshair_DNA, stack, O_CROSSHAIR, this); }
public boolean getHideCrosshair(ItemStack stack) { return WeaponUpgradeManager.eval(hideCrosshair_DNA, stack, B_HIDECROSSHAIR, this); }
public boolean getReloadAnimSequential(ItemStack stack) { return WeaponUpgradeManager.eval(reloadAnimationsSequential_DNA, stack, B_RELOADANIMATIONSEQUENTIAL, this); }
public ResourceLocation getScopeTexture(ItemStack stack) { return WeaponUpgradeManager.eval(scopeTexture_DNA, stack, O_SCOPETEXTURE, this); }
public BiConsumer<ItemStack, LambdaContext> getSmokeHandler(ItemStack stack) { return WeaponUpgradeManager.eval(smokeHandler_DNA, stack, CON_SMOKE, this); }
public BiConsumer<ItemStack, LambdaContext> getOrchestra(ItemStack stack) { return WeaponUpgradeManager.eval(this.orchestra_DNA, stack, CON_ORCHESTRA, this); }
public Receiver[] getReceivers(ItemStack stack) { return WeaponModManager.eval(receivers_DNA, stack, O_RECEIVERS, this); }
public float getDurability(ItemStack stack) { return WeaponModManager.eval(durability_DNA, stack, F_DURABILITY, this); }
public int getDrawDuration(ItemStack stack) { return WeaponModManager.eval(drawDuration_DNA, stack, I_DRAWDURATION, this); }
public int getInspectDuration(ItemStack stack) { return WeaponModManager.eval(inspectDuration_DNA, stack, I_INSPECTDURATION, this); }
public boolean getInspectCancel(ItemStack stack) { return WeaponModManager.eval(inspectCancel_DNA, stack, I_INSPECTCANCEL, this); }
public Crosshair getCrosshair(ItemStack stack) { return WeaponModManager.eval(crosshair_DNA, stack, O_CROSSHAIR, this); }
public boolean getHideCrosshair(ItemStack stack) { return WeaponModManager.eval(hideCrosshair_DNA, stack, B_HIDECROSSHAIR, this); }
public boolean getReloadAnimSequential(ItemStack stack) { return WeaponModManager.eval(reloadAnimationsSequential_DNA, stack, B_RELOADANIMATIONSEQUENTIAL, this); }
public ResourceLocation getScopeTexture(ItemStack stack) { return WeaponModManager.eval(scopeTexture_DNA, stack, O_SCOPETEXTURE, this); }
public BiConsumer<ItemStack, LambdaContext> getSmokeHandler(ItemStack stack) { return WeaponModManager.eval(smokeHandler_DNA, stack, CON_SMOKE, this); }
public BiConsumer<ItemStack, LambdaContext> getOrchestra(ItemStack stack) { return WeaponModManager.eval(this.orchestra_DNA, stack, CON_ORCHESTRA, this); }
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> getPressPrimary(ItemStack stack) { return WeaponModManager.eval(this.onPressPrimary_DNA, stack, CON_ONPRESSPRIMARY, this); }
public BiConsumer<ItemStack, LambdaContext> getPressSecondary(ItemStack stack) { return WeaponModManager.eval(this.onPressSecondary_DNA, stack, CON_ONPRESSSECONDARY, this); }
public BiConsumer<ItemStack, LambdaContext> getPressTertiary(ItemStack stack) { return WeaponModManager.eval(this.onPressTertiary_DNA, stack, CON_ONPRESSTERTIARY, this); }
public BiConsumer<ItemStack, LambdaContext> getPressReload(ItemStack stack) { return WeaponModManager.eval(this.onPressReload_DNA, stack, CON_ONPRESSRELOAD, this); }
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> getReleasePrimary(ItemStack stack) { return WeaponModManager.eval(this.onReleasePrimary_DNA, stack, CON_ONRELEASEPRIMARY, this); }
public BiConsumer<ItemStack, LambdaContext> getReleaseSecondary(ItemStack stack) { return WeaponModManager.eval(this.onReleaseSecondary_DNA, stack, CON_ONRELEASESECONDARY, this); }
public BiConsumer<ItemStack, LambdaContext> getReleaseTertiary(ItemStack stack) { return WeaponModManager.eval(this.onReleaseTertiary_DNA, stack, CON_ONRELEASETERTIARY, this); }
public BiConsumer<ItemStack, LambdaContext> getReleaseReload(ItemStack stack) { return WeaponModManager.eval(this.onReleaseReload_DNA, stack, CON_ONRELEASERELOAD, this); }
public BiConsumer<ItemStack, LambdaContext> getDecider(ItemStack stack) { return WeaponUpgradeManager.eval(this.decider_DNA, stack, CON_DECIDER, this); }
public BiConsumer<ItemStack, LambdaContext> getDecider(ItemStack stack) { return WeaponModManager.eval(this.decider_DNA, stack, CON_DECIDER, this); }
public BiFunction<ItemStack, AnimType, BusAnimation> getAnims(ItemStack stack) { return WeaponUpgradeManager.eval(this.animations_DNA, stack, FUN_ANIMNATIONS, this); }
public IHUDComponent[] getHUDComponents(ItemStack stack) { return WeaponUpgradeManager.eval(this.hudComponents_DNA, stack, O_HUDCOMPONENTS, this); }
public BiFunction<ItemStack, AnimType, BusAnimation> getAnims(ItemStack stack) { return WeaponModManager.eval(this.animations_DNA, stack, FUN_ANIMNATIONS, this); }
public IHUDComponent[] getHUDComponents(ItemStack stack) { return WeaponModManager.eval(this.hudComponents_DNA, stack, O_HUDCOMPONENTS, this); }
/* SETTERS */

View File

@ -12,6 +12,7 @@ import com.hbm.items.IEquipReceiver;
import com.hbm.items.IKeybindReceiver;
import com.hbm.items.weapon.sedna.hud.IHUDComponent;
import com.hbm.items.weapon.sedna.mags.IMagazine;
import com.hbm.items.weapon.sedna.mods.WeaponModManager;
import com.hbm.lib.RefStrings;
import com.hbm.main.MainRegistry;
import com.hbm.packet.PacketDispatcher;
@ -98,7 +99,7 @@ public class ItemGunBaseNT extends Item implements IKeybindReceiver, IEquipRecei
public GunConfig getConfig(ItemStack stack, int index) {
GunConfig cfg = configs_DNA[index];
if(stack == null) return cfg;
return WeaponUpgradeManager.eval(cfg, stack, O_GUNCONFIG + index, this);
return WeaponModManager.eval(cfg, stack, O_GUNCONFIG + index, this);
}
public int getConfigCount() {
@ -110,6 +111,7 @@ public class ItemGunBaseNT extends Item implements IKeybindReceiver, IEquipRecei
this.configs_DNA = cfg;
this.quality = quality;
this.lastShot = new long[cfg.length];
for(int i = 0; i < cfg.length; i++) cfg[i].index = i;
if(quality == WeaponQuality.A_SIDE || quality == WeaponQuality.SPECIAL) this.setCreativeTab(MainRegistry.weaponTab);
if(quality == WeaponQuality.LEGENDARY || quality == WeaponQuality.SECRET) this.secrets.add(this);
this.setTextureName(RefStrings.MODID + ":gun_darter");
@ -158,6 +160,10 @@ public class ItemGunBaseNT extends Item implements IKeybindReceiver, IEquipRecei
case SECRET: list.add((BobMathUtil.getBlink() ? EnumChatFormatting.DARK_RED : EnumChatFormatting.RED) + "SECRET"); break;
case DEBUG: list.add((BobMathUtil.getBlink() ? EnumChatFormatting.YELLOW : EnumChatFormatting.GOLD) + "DEBUG"); break;
}
for(ItemStack upgrade : WeaponModManager.getUpgradeItems(stack)) {
list.add(EnumChatFormatting.YELLOW + upgrade.getDisplayName()); break;
}
}
@Override
@ -263,6 +269,7 @@ public class ItemGunBaseNT extends Item implements IKeybindReceiver, IEquipRecei
}
}
this.setIsAiming(stack, false);
this.setReloadCancel(stack, false);
return;
}

View File

@ -6,6 +6,7 @@ import java.util.function.BiFunction;
import com.hbm.items.weapon.sedna.ItemGunBaseNT.LambdaContext;
import com.hbm.items.weapon.sedna.factory.Lego;
import com.hbm.items.weapon.sedna.mags.IMagazine;
import com.hbm.items.weapon.sedna.mods.WeaponModManager;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Vec3;
@ -84,36 +85,36 @@ public class Receiver {
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 getDelayAfterDryFire(ItemStack stack) { return WeaponUpgradeManager.eval(this.delayAfterDryFire_DNA, stack, I_DELAYAFTERDRYFIRE, this); }
public int getRoundsPerCycle(ItemStack stack) { return WeaponUpgradeManager.eval(this.roundsPerCycle_DNA, stack, I_ROUNDSPERCYCLE, this); }
public float getInnateSpread(ItemStack stack) { return WeaponUpgradeManager.eval(this.spreadInnate_DNA, stack, F_SPRADINNATE, this); }
public float getAmmoSpread(ItemStack stack) { return WeaponUpgradeManager.eval(this.spreadMultAmmo_DNA, stack, F_SPREADAMMO, this); }
public float getHipfireSpread(ItemStack stack) { return WeaponUpgradeManager.eval(this.spreadPenaltyHipfire_DNA, stack, F_SPREADHIPFIRE, this); }
public float getDurabilitySpread(ItemStack stack) { return WeaponUpgradeManager.eval(this.spreadDurability_DNA, stack, F_SPREADDURABILITY, this); }
public boolean getRefireOnHold(ItemStack stack) { return WeaponUpgradeManager.eval(this.refireOnHold_DNA, stack, B_REFIREONHOLD, this); }
public boolean getRefireAfterDry(ItemStack stack) { return WeaponUpgradeManager.eval(this.refireAfterDry_DNA, stack, B_REFIREAFTERDRY, this); }
public boolean getDoesDryFire(ItemStack stack) { return WeaponUpgradeManager.eval(this.doesDryFire_DNA, stack, B_DOESDRYFIRE, this); }
public boolean getDoesDryFireAfterAuto(ItemStack stack) { return WeaponUpgradeManager.eval(this.doesDryFireAfterAuto_DNA, stack, B_DOESDRYFIREAFTERAUTO, this); }
public boolean getEjectOnFire(ItemStack stack) { return WeaponUpgradeManager.eval(this.ejectOnFire_DNA, stack, B_EJECTONFIRE, this); }
public boolean getReloadOnEmpty(ItemStack stack) { return WeaponUpgradeManager.eval(this.reloadOnEmpty_DNA, stack, B_RELOADONEMPTY, this); }
public int getReloadBeginDuration(ItemStack stack) { return WeaponUpgradeManager.eval(this.reloadBeginDuration_DNA, stack, I_RELOADBEGINDURATION, this); }
public int getReloadCycleDuration(ItemStack stack) { return WeaponUpgradeManager.eval(this.reloadCycleDuration_DNA, stack, I_RELOADCYCLEDURATION, this); }
public int getReloadEndDuration(ItemStack stack) { return WeaponUpgradeManager.eval(this.reloadEndDuration_DNA, stack, I_RELOADENDDURATION, this); }
public int getReloadCockOnEmptyPre(ItemStack stack) { return WeaponUpgradeManager.eval(this.reloadCockOnEmptyPre_DNA, stack, I_RELOADCOCKONEMPTYPRE, this); }
public int getReloadCockOnEmptyPost(ItemStack stack) { return WeaponUpgradeManager.eval(this.reloadCockOnEmptyPost_DNA, stack, I_RELOADCOCKONEMPTYPOST, this); }
public int getJamDuration(ItemStack stack) { return WeaponUpgradeManager.eval(this.jamDuration_DNA, stack, I_JAMDURATION, 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 Vec3 getProjectileOffsetScoped(ItemStack stack) { return WeaponUpgradeManager.eval(this.projectileOffsetScoped_DNA, stack, O_PROJECTILEOFFSETSCOPED, this); }
public float getBaseDamage(ItemStack stack) { return WeaponModManager.eval(this.baseDamage_DNA, stack, F_BASEDAMAGE, this); }
public int getDelayAfterFire(ItemStack stack) { return WeaponModManager.eval(this.delayAfterFire_DNA, stack, I_DELAYAFTERFIRE, this); }
public int getDelayAfterDryFire(ItemStack stack) { return WeaponModManager.eval(this.delayAfterDryFire_DNA, stack, I_DELAYAFTERDRYFIRE, this); }
public int getRoundsPerCycle(ItemStack stack) { return WeaponModManager.eval(this.roundsPerCycle_DNA, stack, I_ROUNDSPERCYCLE, this); }
public float getInnateSpread(ItemStack stack) { return WeaponModManager.eval(this.spreadInnate_DNA, stack, F_SPRADINNATE, this); }
public float getAmmoSpread(ItemStack stack) { return WeaponModManager.eval(this.spreadMultAmmo_DNA, stack, F_SPREADAMMO, this); }
public float getHipfireSpread(ItemStack stack) { return WeaponModManager.eval(this.spreadPenaltyHipfire_DNA, stack, F_SPREADHIPFIRE, this); }
public float getDurabilitySpread(ItemStack stack) { return WeaponModManager.eval(this.spreadDurability_DNA, stack, F_SPREADDURABILITY, this); }
public boolean getRefireOnHold(ItemStack stack) { return WeaponModManager.eval(this.refireOnHold_DNA, stack, B_REFIREONHOLD, this); }
public boolean getRefireAfterDry(ItemStack stack) { return WeaponModManager.eval(this.refireAfterDry_DNA, stack, B_REFIREAFTERDRY, this); }
public boolean getDoesDryFire(ItemStack stack) { return WeaponModManager.eval(this.doesDryFire_DNA, stack, B_DOESDRYFIRE, this); }
public boolean getDoesDryFireAfterAuto(ItemStack stack) { return WeaponModManager.eval(this.doesDryFireAfterAuto_DNA, stack, B_DOESDRYFIREAFTERAUTO, this); }
public boolean getEjectOnFire(ItemStack stack) { return WeaponModManager.eval(this.ejectOnFire_DNA, stack, B_EJECTONFIRE, this); }
public boolean getReloadOnEmpty(ItemStack stack) { return WeaponModManager.eval(this.reloadOnEmpty_DNA, stack, B_RELOADONEMPTY, this); }
public int getReloadBeginDuration(ItemStack stack) { return WeaponModManager.eval(this.reloadBeginDuration_DNA, stack, I_RELOADBEGINDURATION, this); }
public int getReloadCycleDuration(ItemStack stack) { return WeaponModManager.eval(this.reloadCycleDuration_DNA, stack, I_RELOADCYCLEDURATION, this); }
public int getReloadEndDuration(ItemStack stack) { return WeaponModManager.eval(this.reloadEndDuration_DNA, stack, I_RELOADENDDURATION, this); }
public int getReloadCockOnEmptyPre(ItemStack stack) { return WeaponModManager.eval(this.reloadCockOnEmptyPre_DNA, stack, I_RELOADCOCKONEMPTYPRE, this); }
public int getReloadCockOnEmptyPost(ItemStack stack) { return WeaponModManager.eval(this.reloadCockOnEmptyPost_DNA, stack, I_RELOADCOCKONEMPTYPOST, this); }
public int getJamDuration(ItemStack stack) { return WeaponModManager.eval(this.jamDuration_DNA, stack, I_JAMDURATION, this); }
public String getFireSound(ItemStack stack) { return WeaponModManager.eval(this.fireSound_DNA, stack, S_FIRESOUND, this); }
public float getFireVolume(ItemStack stack) { return WeaponModManager.eval(this.fireVolume_DNA, stack, F_FIREVOLUME, this); }
public float getFirePitch(ItemStack stack) { return WeaponModManager.eval(this.firePitch_DNA, stack, F_FIREPITCH, this); }
public IMagazine getMagazine(ItemStack stack) { return WeaponModManager.eval(this.magazine_DNA, stack, O_MAGAZINE, this); }
public Vec3 getProjectileOffset(ItemStack stack) { return WeaponModManager.eval(this.projectileOffset_DNA, stack, O_PROJECTILEOFFSET, this); }
public Vec3 getProjectileOffsetScoped(ItemStack stack) { return WeaponModManager.eval(this.projectileOffsetScoped_DNA, stack, O_PROJECTILEOFFSETSCOPED, 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); }
public BiFunction<ItemStack, LambdaContext, Boolean> getCanFire(ItemStack stack) { return WeaponModManager.eval(this.canFire_DNA, stack, FUN_CANFIRE, this); }
public BiConsumer<ItemStack, LambdaContext> getOnFire(ItemStack stack) { return WeaponModManager.eval(this.onFire_DNA, stack, CON_ONFIRE, this); }
public BiConsumer<ItemStack, LambdaContext> getRecoil(ItemStack stack) { return WeaponModManager.eval(this.onRecoil_DNA, stack, CON_ONRECOIL, this); }
/* SETTERS */
public Receiver dmg(float dmg) { this.baseDamage_DNA = dmg; return this; }

View File

@ -1,36 +0,0 @@
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 {
//TODO: add caching so this doesn't have to run 15 times per single action
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). Passing a null
* stack causes the base value to be returned. */
public static <T> T eval(T base, ItemStack stack, String key, Object parent) {
if(stack == null) return base;
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;
}
}

View File

@ -66,6 +66,8 @@ public class GunFactory {
XFactoryTurret.init();
XFactory10ga.init();
XFactory35800.init();
ModItems.weapon_mod_test = new ItemEnumMulti(EnumModTest.class, true, true).setUnlocalizedName("weapon_mod_test");
/// PROXY BULLSHIT ///
MainRegistry.proxy.registerGunCfg();
@ -81,7 +83,7 @@ public class GunFactory {
R762_SP, R762_FMJ, R762_JHP, R762_AP, R762_DU,
BMG50_SP, BMG50_FMJ, BMG50_JHP, BMG50_AP, BMG50_DU,
B75, B75_INC, B75_EXP,
G12_BP, G12_BP_MAGNUM, G12_BP_SLUG, G12, G12_SLUG, G12_FLECHETTE, G12_MAGNUM, G12_EXPLOSIVE, G12_PHOSPHORUS, //G12_ANTHRAX,
G12_BP, G12_BP_MAGNUM, G12_BP_SLUG, G12, G12_SLUG, G12_FLECHETTE, G12_MAGNUM, G12_EXPLOSIVE, G12_PHOSPHORUS,
G26_FLARE, G26_FLARE_SUPPLY, G26_FLARE_WEAPON,
G40_HE, G40_HEAT, G40_DEMO, G40_INC, G40_PHOSPHORUS,
ROCKET_HE, ROCKET_HEAT, ROCKET_DEMO, ROCKET_INC, ROCKET_PHOSPHORUS,
@ -129,4 +131,8 @@ public class GunFactory {
M44_EQUESTRIAN, G12_EQUESTRIAN, BMG50_EQUESTRIAN,
P35_800
}
public static enum EnumModTest {
FIRERATE, DAMAGE, MULTI;
}
}

View File

@ -1,14 +1,13 @@
package com.hbm.items.weapon.sedna;
package com.hbm.items.weapon.sedna.mods;
import net.minecraft.item.ItemStack;
public interface IWeaponUpgrade {
public interface IWeaponMod {
/** 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);
public int getModPriority();
public String[] getSlots();
/** 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; }
public <T> T eval(T base, ItemStack gun, String key, Object parent);
}

View File

@ -0,0 +1,24 @@
package com.hbm.items.weapon.sedna.mods;
public abstract class WeaponModBase implements IWeaponMod {
public String[] slots;
public int priority = 0;
public WeaponModBase(int id, String... slots) { this.slots = slots; WeaponModManager.idToMod.put(id, this); }
public WeaponModBase setPriority(int priority) { this.priority = priority; return this; }
@Override public int getModPriority() { return priority; }
@Override public String[] getSlots() { return slots; }
/**
* Java generics are cool and all but once you actually get to use them, they suck ass.
* This piece of shit only exists to prevent double cast, casting from int to <T> would require (T) (Integer) int, which makes me want to vomit.
* Using this method here implicitly casts the int (or whatever it is) to Object, and Object can be cast to <T>.
* @param The value that needs to be cast
* @param Any value with the type that should be cast to
* @return
*/
public <T> T fagSlop(Object arg, T castTo) { return (T) arg; } //TODO: rename this to something more tactful
}

View File

@ -0,0 +1,159 @@
package com.hbm.items.weapon.sedna.mods;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import com.google.common.collect.HashBiMap;
import com.hbm.inventory.RecipesCommon.ComparableStack;
import com.hbm.items.ModItems;
import com.hbm.items.weapon.sedna.factory.GunFactory.EnumModTest;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
/**
* The mod 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 WeaponModManager {
public static final String KEY_MOD_LIST = "KEY_MOD_LIST";
/** Mapping of mods to IDs, keep the register order consistent! */
public static HashBiMap<Integer, IWeaponMod> idToMod = HashBiMap.create();
/** Mapping of mod items to mod definitions */
public static HashMap<ComparableStack, WeaponModDefinition> stackToMod = new HashMap();
/** Map for turning individual mods back into their item form, used when uninstaling mods */
public static HashMap<IWeaponMod, ItemStack> modToStack = new HashMap();
/** Assigns the IWeaponMod instances to items */
public static void init() {
/* ORDER MATTERS! */
/* CTOR contains registering to the ID_LIST, avoid reordering to prevent ID shifting! */
IWeaponMod TEST_FIRERATE = new WeaponModTestFirerate(0);
IWeaponMod TEST_DAMAGE = new WeaponModTestDamage(1);
IWeaponMod TEST_MULTI = new WeaponModTestMulti(2);
new WeaponModDefinition(new ItemStack(ModItems.weapon_mod_test, 1, EnumModTest.FIRERATE.ordinal())).addDefault(TEST_FIRERATE);
new WeaponModDefinition(new ItemStack(ModItems.weapon_mod_test, 1, EnumModTest.DAMAGE.ordinal())).addDefault(TEST_DAMAGE);
new WeaponModDefinition(new ItemStack(ModItems.weapon_mod_test, 1, EnumModTest.MULTI.ordinal())).addDefault(TEST_MULTI);
}
public static ItemStack[] getUpgradeItems(ItemStack stack) {
if(!stack.hasTagCompound()) return new ItemStack[0];
int[] modIds = stack.stackTagCompound.getIntArray(KEY_MOD_LIST);
if(modIds.length == 0) return new ItemStack[0];
ItemStack[] mods = new ItemStack[modIds.length];
for(int i = 0; i < mods.length; i++) {
IWeaponMod mod = idToMod.get(modIds[i]);
if(mod != null) {
mods[i] = mod != null ? modToStack.get(mod) : null;
if(mods[i] != null) mods[i] = mods[i].copy();
}
}
return mods;
}
/** Installs the supplied mods to the gun */
public static void install(ItemStack stack, ItemStack... mods) {
List<IWeaponMod> toInstall = new ArrayList();
ComparableStack gun = new ComparableStack(stack);
for(ItemStack mod : mods) {
if(mod == null) continue;
ComparableStack comp = new ComparableStack(mod);
WeaponModDefinition def = stackToMod.get(comp);
if(def != null) {
IWeaponMod forGun = def.modByGun.get(gun);
if(forGun != null) toInstall.add(forGun); //since this code only runs for upgrading, we can just indexOf because who cares
else {
forGun = def.modByGun.get(null);
if(forGun != null) toInstall.add(forGun);
}
}
}
if(toInstall.isEmpty()) return;
toInstall.sort(modSorter);
if(!stack.hasTagCompound()) stack.stackTagCompound = new NBTTagCompound();
int[] modIds = new int[toInstall.size()];
for(int i = 0; i < modIds.length; i++) modIds[i] = idToMod.inverse().get(toInstall.get(i));
stack.stackTagCompound.setIntArray(KEY_MOD_LIST, modIds);
}
/** Wipes all mods from the gun */
public static void uninstall(ItemStack stack) {
if(stack.hasTagCompound()) {
stack.stackTagCompound.removeTag(KEY_MOD_LIST);
//no need to clean up empty stackTagCompound because gun NBT is never empty anyway
}
}
public static boolean isApplicable(ItemStack gun, ItemStack mod, boolean checkMutex) {
if(gun == null || mod == null) return false; //if either stacks are null
WeaponModDefinition def = stackToMod.get(new ComparableStack(mod));
if(def == null) return false; //if the mod stack doesn't have a mod definition
IWeaponMod newMod = def.modByGun.get(new ComparableStack(gun));
if(newMod == null) newMod = def.modByGun.get(null); //if there's no per-gun mod, default to null key
if(newMod == null) return false; //if there's just no mod applicable
if(checkMutex) for(int i : gun.stackTagCompound.getIntArray(KEY_MOD_LIST)) {
IWeaponMod iMod = idToMod.get(i);
if(iMod != null) for(String mutex0 : newMod.getSlots()) for(String mutex1 : iMod.getSlots()) if(mutex0.equals(mutex1)) return false; //if any of the mod's slots are already taken
}
return true; //yippie!
}
public static Comparator<IWeaponMod> modSorter = new Comparator<IWeaponMod>() {
@Override
public int compare(IWeaponMod o1, IWeaponMod o2) {
return o2.getModPriority() - o1.getModPriority();
}
};
/** 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). Passing a null
* stack causes the base value to be returned. */
public static <T> T eval(T base, ItemStack stack, String key, Object parent) {
if(stack == null) return base;
if(!stack.hasTagCompound()) return base;
for(int i : stack.stackTagCompound.getIntArray(KEY_MOD_LIST)) {
IWeaponMod mod = idToMod.get(i);
if(mod != null) base = mod.eval(base, stack, key, parent);
}
return base;
}
public static class WeaponModDefinition {
/** Holds the weapon mod handlers for each given gun. Key null refers to mods that apply to ALL guns that are otherwise not included. */
public HashMap<ComparableStack, IWeaponMod> modByGun = new HashMap();
public ItemStack stack;
public WeaponModDefinition(ItemStack stack) {
this.stack = stack;
stackToMod.put(new ComparableStack(stack), this);
}
public WeaponModDefinition addMod(ItemStack gun, IWeaponMod mod) { return addMod(new ComparableStack(gun), mod); }
public WeaponModDefinition addMod(Item gun, IWeaponMod mod) { return addMod(new ComparableStack(gun), mod); }
public WeaponModDefinition addMod(ComparableStack gun, IWeaponMod mod) {
modByGun.put(gun, mod);
modToStack.put(mod, stack);
return this;
}
public WeaponModDefinition addDefault(IWeaponMod mod) {
return addMod((ComparableStack) null, mod);
}
}
}

View File

@ -0,0 +1,22 @@
package com.hbm.items.weapon.sedna.mods;
import com.hbm.items.weapon.sedna.Receiver;
import net.minecraft.item.ItemStack;
public class WeaponModTestDamage extends WeaponModBase {
public WeaponModTestDamage(int id, String... slots) {
super(id, slots);
}
@Override
public <T> T eval(T base, ItemStack gun, String key, Object parent) {
if(parent instanceof Receiver && key == Receiver.F_BASEDAMAGE && base instanceof Float) {
return fagSlop((float) base * 1.5F, base);
}
return base;
}
}

View File

@ -0,0 +1,22 @@
package com.hbm.items.weapon.sedna.mods;
import com.hbm.items.weapon.sedna.Receiver;
import net.minecraft.item.ItemStack;
public class WeaponModTestFirerate extends WeaponModBase {
public WeaponModTestFirerate(int id, String... slots) {
super(id, slots);
}
@Override
public <T> T eval(T base, ItemStack gun, String key, Object parent) {
if(parent instanceof Receiver && key == Receiver.I_DELAYAFTERFIRE && base instanceof Integer) {
return fagSlop(Math.max((int) base / 2, 1), base);
}
return base;
}
}

View File

@ -0,0 +1,22 @@
package com.hbm.items.weapon.sedna.mods;
import com.hbm.items.weapon.sedna.Receiver;
import net.minecraft.item.ItemStack;
public class WeaponModTestMulti extends WeaponModBase {
public WeaponModTestMulti(int id, String... slots) {
super(id, slots);
}
@Override
public <T> T eval(T base, ItemStack gun, String key, Object parent) {
if(parent instanceof Receiver && key == Receiver.I_ROUNDSPERCYCLE && base instanceof Integer) {
return fagSlop((int) base * 3, base);
}
return base;
}
}

View File

@ -33,6 +33,7 @@ import com.hbm.items.ItemEnums.EnumAchievementType;
import com.hbm.items.ModItems;
import com.hbm.items.tool.ItemFertilizer;
import com.hbm.items.weapon.ItemGenericGrenade;
import com.hbm.items.weapon.sedna.mods.WeaponModManager;
import com.hbm.lib.HbmWorld;
import com.hbm.lib.RefStrings;
import com.hbm.packet.PacketDispatcher;
@ -290,6 +291,7 @@ public class MainRegistry {
SiegeTier.registerTiers();
HazardRegistry.registerItems();
HazardRegistry.registerTrafos();
WeaponModManager.init();
OreDictManager oreMan = new OreDictManager();
MinecraftForge.EVENT_BUS.register(oreMan); //OreRegisterEvent

View File

@ -381,7 +381,7 @@ public class DamageResistanceHandler {
if(exact != null) return exact;
Resistance category = categoryResistances.get(typeToCategory(source));
if(category != null) return category;
return otherResistance;
return source.isUnblockable() ? null : otherResistance;
}
public ResistanceStats addExact(String type, float threshold, float resistance) { exactResistances.put(type, new Resistance(threshold, resistance)); return this; }