diff --git a/src/main/java/com/hbm/inventory/container/ContainerWeaponTable.java b/src/main/java/com/hbm/inventory/container/ContainerWeaponTable.java index 76a412c0f..34c007c88 100644 --- a/src/main/java/com/hbm/inventory/container/ContainerWeaponTable.java +++ b/src/main/java/com/hbm/inventory/container/ContainerWeaponTable.java @@ -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! + } } } diff --git a/src/main/java/com/hbm/inventory/gui/GUIWeaponTable.java b/src/main/java/com/hbm/inventory/gui/GUIWeaponTable.java index 8f2f01d8f..939b03dd8 100644 --- a/src/main/java/com/hbm/inventory/gui/GUIWeaponTable.java +++ b/src/main/java/com/hbm/inventory/gui/GUIWeaponTable.java @@ -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); } } diff --git a/src/main/java/com/hbm/items/ModItems.java b/src/main/java/com/hbm/items/ModItems.java index b14eb9ae5..517423b5d 100644 --- a/src/main/java/com/hbm/items/ModItems.java +++ b/src/main/java/com/hbm/items/ModItems.java @@ -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()); diff --git a/src/main/java/com/hbm/items/weapon/sedna/GunConfig.java b/src/main/java/com/hbm/items/weapon/sedna/GunConfig.java index 90f21ddf5..613c4bc09 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/GunConfig.java +++ b/src/main/java/com/hbm/items/weapon/sedna/GunConfig.java @@ -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 getSmokeHandler(ItemStack stack) { return WeaponUpgradeManager.eval(smokeHandler_DNA, stack, CON_SMOKE, this); } - public BiConsumer 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 getSmokeHandler(ItemStack stack) { return WeaponModManager.eval(smokeHandler_DNA, stack, CON_SMOKE, this); } + public BiConsumer getOrchestra(ItemStack stack) { return WeaponModManager.eval(this.orchestra_DNA, stack, CON_ORCHESTRA, this); } - public BiConsumer getPressPrimary(ItemStack stack) { return WeaponUpgradeManager.eval(this.onPressPrimary_DNA, stack, CON_ONPRESSPRIMARY, this); } - public BiConsumer getPressSecondary(ItemStack stack) { return WeaponUpgradeManager.eval(this.onPressSecondary_DNA, stack, CON_ONPRESSSECONDARY, this); } - public BiConsumer getPressTertiary(ItemStack stack) { return WeaponUpgradeManager.eval(this.onPressTertiary_DNA, stack, CON_ONPRESSTERTIARY, this); } - public BiConsumer getPressReload(ItemStack stack) { return WeaponUpgradeManager.eval(this.onPressReload_DNA, stack, CON_ONPRESSRELOAD, this); } + public BiConsumer getPressPrimary(ItemStack stack) { return WeaponModManager.eval(this.onPressPrimary_DNA, stack, CON_ONPRESSPRIMARY, this); } + public BiConsumer getPressSecondary(ItemStack stack) { return WeaponModManager.eval(this.onPressSecondary_DNA, stack, CON_ONPRESSSECONDARY, this); } + public BiConsumer getPressTertiary(ItemStack stack) { return WeaponModManager.eval(this.onPressTertiary_DNA, stack, CON_ONPRESSTERTIARY, this); } + public BiConsumer getPressReload(ItemStack stack) { return WeaponModManager.eval(this.onPressReload_DNA, stack, CON_ONPRESSRELOAD, this); } - public BiConsumer getReleasePrimary(ItemStack stack) { return WeaponUpgradeManager.eval(this.onReleasePrimary_DNA, stack, CON_ONRELEASEPRIMARY, this); } - public BiConsumer getReleaseSecondary(ItemStack stack) { return WeaponUpgradeManager.eval(this.onReleaseSecondary_DNA, stack, CON_ONRELEASESECONDARY, this); } - public BiConsumer getReleaseTertiary(ItemStack stack) { return WeaponUpgradeManager.eval(this.onReleaseTertiary_DNA, stack, CON_ONRELEASETERTIARY, this); } - public BiConsumer getReleaseReload(ItemStack stack) { return WeaponUpgradeManager.eval(this.onReleaseReload_DNA, stack, CON_ONRELEASERELOAD, this); } + public BiConsumer getReleasePrimary(ItemStack stack) { return WeaponModManager.eval(this.onReleasePrimary_DNA, stack, CON_ONRELEASEPRIMARY, this); } + public BiConsumer getReleaseSecondary(ItemStack stack) { return WeaponModManager.eval(this.onReleaseSecondary_DNA, stack, CON_ONRELEASESECONDARY, this); } + public BiConsumer getReleaseTertiary(ItemStack stack) { return WeaponModManager.eval(this.onReleaseTertiary_DNA, stack, CON_ONRELEASETERTIARY, this); } + public BiConsumer getReleaseReload(ItemStack stack) { return WeaponModManager.eval(this.onReleaseReload_DNA, stack, CON_ONRELEASERELOAD, this); } - public BiConsumer getDecider(ItemStack stack) { return WeaponUpgradeManager.eval(this.decider_DNA, stack, CON_DECIDER, this); } + public BiConsumer getDecider(ItemStack stack) { return WeaponModManager.eval(this.decider_DNA, stack, CON_DECIDER, this); } - public BiFunction 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 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 */ diff --git a/src/main/java/com/hbm/items/weapon/sedna/ItemGunBaseNT.java b/src/main/java/com/hbm/items/weapon/sedna/ItemGunBaseNT.java index 45cb4d0bc..ad5d9cc4f 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/ItemGunBaseNT.java +++ b/src/main/java/com/hbm/items/weapon/sedna/ItemGunBaseNT.java @@ -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; } diff --git a/src/main/java/com/hbm/items/weapon/sedna/Receiver.java b/src/main/java/com/hbm/items/weapon/sedna/Receiver.java index 8a3468d75..e25988fee 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/Receiver.java +++ b/src/main/java/com/hbm/items/weapon/sedna/Receiver.java @@ -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 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 getCanFire(ItemStack stack) { return WeaponUpgradeManager.eval(this.canFire_DNA, stack, FUN_CANFIRE, this); } - public BiConsumer getOnFire(ItemStack stack) { return WeaponUpgradeManager.eval(this.onFire_DNA, stack, CON_ONFIRE, this); } - public BiConsumer getRecoil(ItemStack stack) { return WeaponUpgradeManager.eval(this.onRecoil_DNA, stack, CON_ONRECOIL, this); } + public BiFunction getCanFire(ItemStack stack) { return WeaponModManager.eval(this.canFire_DNA, stack, FUN_CANFIRE, this); } + public BiConsumer getOnFire(ItemStack stack) { return WeaponModManager.eval(this.onFire_DNA, stack, CON_ONFIRE, this); } + public BiConsumer 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; } diff --git a/src/main/java/com/hbm/items/weapon/sedna/WeaponUpgradeManager.java b/src/main/java/com/hbm/items/weapon/sedna/WeaponUpgradeManager.java deleted file mode 100644 index 4f0602a0f..000000000 --- a/src/main/java/com/hbm/items/weapon/sedna/WeaponUpgradeManager.java +++ /dev/null @@ -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 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; - } -} diff --git a/src/main/java/com/hbm/items/weapon/sedna/factory/GunFactory.java b/src/main/java/com/hbm/items/weapon/sedna/factory/GunFactory.java index 64f058fb7..0a26addd9 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/factory/GunFactory.java +++ b/src/main/java/com/hbm/items/weapon/sedna/factory/GunFactory.java @@ -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; + } } diff --git a/src/main/java/com/hbm/items/weapon/sedna/IWeaponUpgrade.java b/src/main/java/com/hbm/items/weapon/sedna/mods/IWeaponMod.java similarity index 50% rename from src/main/java/com/hbm/items/weapon/sedna/IWeaponUpgrade.java rename to src/main/java/com/hbm/items/weapon/sedna/mods/IWeaponMod.java index 502f12aec..3dd6c6dc2 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/IWeaponUpgrade.java +++ b/src/main/java/com/hbm/items/weapon/sedna/mods/IWeaponMod.java @@ -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 eval(T base, ItemStack stack, String key, Object parent) { return base; } + public T eval(T base, ItemStack gun, String key, Object parent); } diff --git a/src/main/java/com/hbm/items/weapon/sedna/mods/WeaponModBase.java b/src/main/java/com/hbm/items/weapon/sedna/mods/WeaponModBase.java new file mode 100644 index 000000000..ad3dc0b5a --- /dev/null +++ b/src/main/java/com/hbm/items/weapon/sedna/mods/WeaponModBase.java @@ -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 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 . + * @param The value that needs to be cast + * @param Any value with the type that should be cast to + * @return + */ + public T fagSlop(Object arg, T castTo) { return (T) arg; } //TODO: rename this to something more tactful +} diff --git a/src/main/java/com/hbm/items/weapon/sedna/mods/WeaponModManager.java b/src/main/java/com/hbm/items/weapon/sedna/mods/WeaponModManager.java new file mode 100644 index 000000000..78a31db04 --- /dev/null +++ b/src/main/java/com/hbm/items/weapon/sedna/mods/WeaponModManager.java @@ -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 idToMod = HashBiMap.create(); + /** Mapping of mod items to mod definitions */ + public static HashMap stackToMod = new HashMap(); + /** Map for turning individual mods back into their item form, used when uninstaling mods */ + public static HashMap 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 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 modSorter = new Comparator() { + + @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 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 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); + } + } +} diff --git a/src/main/java/com/hbm/items/weapon/sedna/mods/WeaponModTestDamage.java b/src/main/java/com/hbm/items/weapon/sedna/mods/WeaponModTestDamage.java new file mode 100644 index 000000000..72e96b0cf --- /dev/null +++ b/src/main/java/com/hbm/items/weapon/sedna/mods/WeaponModTestDamage.java @@ -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 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; + } +} diff --git a/src/main/java/com/hbm/items/weapon/sedna/mods/WeaponModTestFirerate.java b/src/main/java/com/hbm/items/weapon/sedna/mods/WeaponModTestFirerate.java new file mode 100644 index 000000000..701c3b538 --- /dev/null +++ b/src/main/java/com/hbm/items/weapon/sedna/mods/WeaponModTestFirerate.java @@ -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 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; + } +} diff --git a/src/main/java/com/hbm/items/weapon/sedna/mods/WeaponModTestMulti.java b/src/main/java/com/hbm/items/weapon/sedna/mods/WeaponModTestMulti.java new file mode 100644 index 000000000..37cf77d2d --- /dev/null +++ b/src/main/java/com/hbm/items/weapon/sedna/mods/WeaponModTestMulti.java @@ -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 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; + } +} diff --git a/src/main/java/com/hbm/main/MainRegistry.java b/src/main/java/com/hbm/main/MainRegistry.java index bb9616014..903ddb954 100644 --- a/src/main/java/com/hbm/main/MainRegistry.java +++ b/src/main/java/com/hbm/main/MainRegistry.java @@ -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 diff --git a/src/main/java/com/hbm/util/DamageResistanceHandler.java b/src/main/java/com/hbm/util/DamageResistanceHandler.java index b34b26570..c54bb7a0b 100644 --- a/src/main/java/com/hbm/util/DamageResistanceHandler.java +++ b/src/main/java/com/hbm/util/DamageResistanceHandler.java @@ -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; } diff --git a/src/main/resources/assets/hbm/textures/items/gun_upgrade_debug_conversion.png b/src/main/resources/assets/hbm/textures/items/weapon_mod_test.caliber.png similarity index 100% rename from src/main/resources/assets/hbm/textures/items/gun_upgrade_debug_conversion.png rename to src/main/resources/assets/hbm/textures/items/weapon_mod_test.caliber.png diff --git a/src/main/resources/assets/hbm/textures/items/gun_upgrade_debug_damage.png b/src/main/resources/assets/hbm/textures/items/weapon_mod_test.damage.png similarity index 100% rename from src/main/resources/assets/hbm/textures/items/gun_upgrade_debug_damage.png rename to src/main/resources/assets/hbm/textures/items/weapon_mod_test.damage.png diff --git a/src/main/resources/assets/hbm/textures/items/gun_upgrade_debug_shotspeed.png b/src/main/resources/assets/hbm/textures/items/weapon_mod_test.firerate.png similarity index 100% rename from src/main/resources/assets/hbm/textures/items/gun_upgrade_debug_shotspeed.png rename to src/main/resources/assets/hbm/textures/items/weapon_mod_test.firerate.png diff --git a/src/main/resources/assets/hbm/textures/items/gun_upgrade_debug_multishot.png b/src/main/resources/assets/hbm/textures/items/weapon_mod_test.multi.png similarity index 100% rename from src/main/resources/assets/hbm/textures/items/gun_upgrade_debug_multishot.png rename to src/main/resources/assets/hbm/textures/items/weapon_mod_test.multi.png