From f8e9cff64b1ab64a685a0612eba6a6e3027b5829 Mon Sep 17 00:00:00 2001 From: Bob Date: Sat, 2 Dec 2023 20:44:34 +0100 Subject: [PATCH] tweaks, exposure chamber recipes --- changelog | 7 +- .../container/ContainerMachineExcavator.java | 4 +- .../ContainerMachineExposureChamber.java | 86 ++++++++++++++++++ .../gui/GUIMachineExposureChamber.java | 47 ++++++++++ .../inventory/recipes/AssemblerRecipes.java | 16 ++-- .../recipes/ExposureChamberRecipes.java | 83 +++++++++++++++++ .../recipes/loader/SerializableRecipe.java | 1 + .../java/com/hbm/main/CraftingManager.java | 4 - .../tileentity/RenderExposureChamber.java | 21 +++-- .../TileEntityMachineExposureChamber.java | 74 ++++++++++++++- .../gui/processing/gui_exposure_chamber.png | Bin 3129 -> 3134 bytes .../models/doors/qe_containment_decal.png | Bin 314 -> 7096 bytes 12 files changed, 319 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/hbm/inventory/container/ContainerMachineExposureChamber.java create mode 100644 src/main/java/com/hbm/inventory/gui/GUIMachineExposureChamber.java create mode 100644 src/main/java/com/hbm/inventory/recipes/ExposureChamberRecipes.java diff --git a/changelog b/changelog index 596d87512..c9bd68389 100644 --- a/changelog +++ b/changelog @@ -7,6 +7,9 @@ * A much less jankier alternative to the vanilla boat. Rotations are silky smooth and done via the strafe keys instead of based on the player's orientation * Won't break from ramming into blocks * Faster than a regular boat, but will decelerate quicker when there's nobody sitting in it, preventing the boat from drifting off too far when empty +* Exposure chamber + * Now performs the particle transmutation recipes that were previously done in the crafting table + * Stylish as hell ## Changed * Reduced the blast resistance of the large doors from absurdly high to still very but not quite as high @@ -20,6 +23,7 @@ * Non-custom missiles have been slightly buffed * Explosions are now slightly larger and they use the new cross-detection entity damage code which still affects entities behind small hills that would otherwise be shielded * Explosions now have a 2x larger entity damage radius +* Updated the digiminer recipe for mekanism cocmpat ## Fixed * Fixed ancient bug where custom missiles launched using the launch table would not use the accuracy calculation and always be pin-point accurate @@ -28,4 +32,5 @@ * Fixed the ballistic gauntlet spawning a client-side ghost bullet that doesn't move or despawn * Fixed bug where different custom machine cores would merge in a stack when picked up, turning them into the same type * Fixed radar screen blips being visible through the back of the model -* Fixed desh crate's last half of slots preventing radiation entirely \ No newline at end of file +* Fixed desh crate's last half of slots preventing radiation entirely +* Fixed large mining drill shift-clicking \ No newline at end of file diff --git a/src/main/java/com/hbm/inventory/container/ContainerMachineExcavator.java b/src/main/java/com/hbm/inventory/container/ContainerMachineExcavator.java index a7caab502..c55fd5400 100644 --- a/src/main/java/com/hbm/inventory/container/ContainerMachineExcavator.java +++ b/src/main/java/com/hbm/inventory/container/ContainerMachineExcavator.java @@ -54,8 +54,8 @@ public class ContainerMachineExcavator extends Container { ItemStack var5 = var4.getStack(); var3 = var5.copy(); - if(par2 <= 4) { - if(!this.mergeItemStack(var5, 5, this.inventorySlots.size(), true)) { + if(par2 <= 13) { + if(!this.mergeItemStack(var5, 14, this.inventorySlots.size(), true)) { return null; } } else { diff --git a/src/main/java/com/hbm/inventory/container/ContainerMachineExposureChamber.java b/src/main/java/com/hbm/inventory/container/ContainerMachineExposureChamber.java new file mode 100644 index 000000000..b9e839468 --- /dev/null +++ b/src/main/java/com/hbm/inventory/container/ContainerMachineExposureChamber.java @@ -0,0 +1,86 @@ +package com.hbm.inventory.container; + +import com.hbm.inventory.SlotCraftingOutput; +import com.hbm.inventory.SlotTakeOnly; +import com.hbm.items.ModItems; +import com.hbm.items.machine.ItemMachineUpgrade; +import com.hbm.tileentity.machine.TileEntityMachineExposureChamber; + +import api.hbm.energy.IBatteryItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; + +public class ContainerMachineExposureChamber extends Container { + + private TileEntityMachineExposureChamber chamber; + + public ContainerMachineExposureChamber(InventoryPlayer invPlayer, TileEntityMachineExposureChamber tedf) { + this.chamber = tedf; + + this.addSlotToContainer(new Slot(tedf, 0, 8, 18)); + this.addSlotToContainer(new SlotTakeOnly(tedf, 2, 8, 54)); + this.addSlotToContainer(new Slot(tedf, 3, 80, 36)); + this.addSlotToContainer(new SlotCraftingOutput(invPlayer.player, tedf, 4, 116, 36)); + this.addSlotToContainer(new Slot(tedf, 5, 152, 54)); + this.addSlotToContainer(new Slot(tedf, 6, 44, 54)); + this.addSlotToContainer(new Slot(tedf, 7, 62, 54)); + + for(int i = 0; i < 3; i++) { + for(int j = 0; j < 9; j++) { + this.addSlotToContainer(new Slot(invPlayer, j + i * 9 + 9, 8 + j * 18, 104 + i * 18)); + } + } + + for(int i = 0; i < 9; i++) { + this.addSlotToContainer(new Slot(invPlayer, i, 8 + i * 18, 162)); + } + } + + @Override + public ItemStack transferStackInSlot(EntityPlayer p_82846_1_, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if(var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if(par2 <= 6) { + if(!this.mergeItemStack(var5, 7, this.inventorySlots.size(), true)) { + return null; + } + } else { + + if(var3.getItem() instanceof ItemMachineUpgrade) { + if(!this.mergeItemStack(var5, 5, 7, false)) { + return null; + } + } else if(var3.getItem() instanceof IBatteryItem || var3.getItem() == ModItems.battery_creative) { + if(!this.mergeItemStack(var5, 4, 5, false)) { + return null; + } + } else { + if(!this.mergeItemStack(var5, 0, 2, false)) { + return null; + } + } + } + + if(var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + } + + return var3; + } + + @Override + public boolean canInteractWith(EntityPlayer player) { + return chamber.isUseableByPlayer(player); + } +} diff --git a/src/main/java/com/hbm/inventory/gui/GUIMachineExposureChamber.java b/src/main/java/com/hbm/inventory/gui/GUIMachineExposureChamber.java new file mode 100644 index 000000000..351a3642d --- /dev/null +++ b/src/main/java/com/hbm/inventory/gui/GUIMachineExposureChamber.java @@ -0,0 +1,47 @@ +package com.hbm.inventory.gui; + +import org.lwjgl.opengl.GL11; + +import com.hbm.inventory.container.ContainerMachineExposureChamber; +import com.hbm.lib.RefStrings; +import com.hbm.tileentity.machine.TileEntityMachineExposureChamber; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.util.ResourceLocation; + +public class GUIMachineExposureChamber extends GuiInfoContainer { + + public static ResourceLocation texture = new ResourceLocation(RefStrings.MODID + ":textures/gui/processing/gui_exposure_chamber.png"); + private TileEntityMachineExposureChamber chamber; + + public GUIMachineExposureChamber(InventoryPlayer invPlayer, TileEntityMachineExposureChamber chamber) { + super(new ContainerMachineExposureChamber(invPlayer, chamber)); + this.chamber = chamber; + + this.xSize = 176; + this.ySize = 186; + } + + @Override + public void drawScreen(int mouseX, int mouseY, float f) { + super.drawScreen(mouseX, mouseY, f); + + this.drawElectricityInfo(this, mouseX, mouseY, guiLeft + 152, guiTop + 18, 16, 52, chamber.power, chamber.maxPower); + } + + @Override + protected void drawGuiContainerForegroundLayer(int i, int j) { + String name = this.chamber.hasCustomInventoryName() ? this.chamber.getInventoryName() : I18n.format(this.chamber.getInventoryName()); + this.fontRendererObj.drawString(name, 70 - this.fontRendererObj.getStringWidth(name) / 2, 6, 4210752); + this.fontRendererObj.drawString(I18n.format("container.inventory"), 8, this.ySize - 96 + 2, 4210752); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) { + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + Minecraft.getMinecraft().getTextureManager().bindTexture(texture); + drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize); + } +} diff --git a/src/main/java/com/hbm/inventory/recipes/AssemblerRecipes.java b/src/main/java/com/hbm/inventory/recipes/AssemblerRecipes.java index 82e17f216..fb559fa5d 100644 --- a/src/main/java/com/hbm/inventory/recipes/AssemblerRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/AssemblerRecipes.java @@ -1230,17 +1230,17 @@ public class AssemblerRecipes { makeRecipe(new ComparableStack(mb, 1, 4), new AStack[] { new OreDictStack(DURA.ingot(), 16), - new OreDictStack(DESH.ingot(), 8), - new OreDictStack(STEEL.plate(), 48), - new OreDictStack(CU.plate(), 24), + new OreDictStack(DESH.ingot(), 16), + new OreDictStack(STEEL.plateWelded(), 32), + new OreDictStack(CU.plateWelded(), 24), new ComparableStack(ModItems.pipes_steel, 8), - new ComparableStack(ModItems.circuit_gold, 8), - new ComparableStack(ModItems.wire_advanced_alloy, 24), + new OreDictStack(KEY_CIRCUIT_BISMUTH, 4), + new ComparableStack(ModItems.wire_dense, 32, Mats.MAT_ALLOY.id), new ComparableStack(ModBlocks.fusion_conductor, 12), - new ComparableStack(ModBlocks.machine_lithium_battery, 3), - new ComparableStack(ModItems.crystal_redstone, 12), + new ComparableStack(ModBlocks.capacitor_tantalium, 53), + new ComparableStack(ModItems.crystal_redstone, 16), new ComparableStack(ModItems.crystal_diamond, 8), - new ComparableStack(ModItems.motor_desh, 16) + new ComparableStack(ModItems.motor_bismuth, 4) }, 15 * 60 * 20); } } diff --git a/src/main/java/com/hbm/inventory/recipes/ExposureChamberRecipes.java b/src/main/java/com/hbm/inventory/recipes/ExposureChamberRecipes.java new file mode 100644 index 000000000..53e69569f --- /dev/null +++ b/src/main/java/com/hbm/inventory/recipes/ExposureChamberRecipes.java @@ -0,0 +1,83 @@ +package com.hbm.inventory.recipes; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.stream.JsonWriter; +import static com.hbm.inventory.OreDictManager.*; +import com.hbm.inventory.RecipesCommon.AStack; +import com.hbm.inventory.RecipesCommon.ComparableStack; +import com.hbm.inventory.RecipesCommon.OreDictStack; +import com.hbm.inventory.recipes.loader.SerializableRecipe; +import com.hbm.items.ModItems; + +import net.minecraft.item.ItemStack; + +public class ExposureChamberRecipes extends SerializableRecipe { + + public static List recipes = new ArrayList(); + + @Override + public void registerDefaults() { + recipes.add(new ExposureChamberRecipe(new ComparableStack(ModItems.particle_higgs), new OreDictStack(U.ingot()), new ItemStack(ModItems.ingot_schraranium))); + recipes.add(new ExposureChamberRecipe(new ComparableStack(ModItems.particle_higgs), new OreDictStack(U238.ingot()), new ItemStack(ModItems.ingot_schrabidium))); + recipes.add(new ExposureChamberRecipe(new ComparableStack(ModItems.particle_dark), new OreDictStack(PU.ingot()), new ItemStack(ModItems.ingot_euphemium))); + recipes.add(new ExposureChamberRecipe(new ComparableStack(ModItems.particle_sparkticle), new OreDictStack(SBD.ingot()), new ItemStack(ModItems.ingot_dineutronium))); + } + + @Override + public String getFileName() { + return "hbmExposureChamber.json"; + } + + @Override + public Object getRecipeObject() { + return recipes; + } + + @Override + public void deleteRecipes() { + recipes.clear(); + } + + @Override + public void readRecipe(JsonElement recipe) { + + JsonObject obj = (JsonObject) recipe; + + AStack particle = this.readAStack(obj.get("particle").getAsJsonArray()); + AStack ingredient = this.readAStack(obj.get("ingredient").getAsJsonArray()); + ItemStack output = this.readItemStack(obj.get("output").getAsJsonArray()); + + ExposureChamberRecipe rec = new ExposureChamberRecipe(particle, ingredient, output); + recipes.add(rec); + } + + @Override + public void writeRecipe(Object o, JsonWriter writer) throws IOException { + ExposureChamberRecipe recipe = (ExposureChamberRecipe) o; + + writer.name("particle"); + this.writeAStack(recipe.particle, writer); + writer.name("ingredient"); + this.writeAStack(recipe.ingredient, writer); + writer.name("output"); + this.writeItemStack(recipe.output, writer); + } + + public static class ExposureChamberRecipe { + + public AStack particle; + public AStack ingredient; + public ItemStack output; + + public ExposureChamberRecipe(AStack particle, AStack ingredient, ItemStack output) { + this.particle = particle; + this.ingredient = ingredient; + this.output = output; + } + } +} diff --git a/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java b/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java index 8149dfaba..f54138b0f 100644 --- a/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java +++ b/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java @@ -65,6 +65,7 @@ public abstract class SerializableRecipe { recipeHandlers.add(new ElectrolyserFluidRecipes()); recipeHandlers.add(new ElectrolyserMetalRecipes()); recipeHandlers.add(new ArcWelderRecipes()); + recipeHandlers.add(new ExposureChamberRecipes()); recipeHandlers.add(new MatDistribution()); recipeHandlers.add(new CustomMachineRecipes()); diff --git a/src/main/java/com/hbm/main/CraftingManager.java b/src/main/java/com/hbm/main/CraftingManager.java index 5e0cc59e9..386706b30 100644 --- a/src/main/java/com/hbm/main/CraftingManager.java +++ b/src/main/java/com/hbm/main/CraftingManager.java @@ -862,10 +862,6 @@ public class CraftingManager { addRecipeAuto(new ItemStack(ModBlocks.hadron_cooler, 1, 0), new Object[] { "PCP", "CHC", "PCP", 'P', ANY_RESISTANTALLOY.plateCast(), 'C', ModItems.circuit_gold, 'H', Fluids.HELIUM4.getDict(16_000) }); addRecipeAuto(new ItemStack(ModBlocks.hadron_cooler, 1, 1), new Object[] { "PCP", "CHC", "PCP", 'P', GOLD.plateCast(), 'C', ModItems.motor_bismuth, 'H', new ItemStack(ModBlocks.hadron_cooler, 1, 0) }); - addRecipeAuto(new ItemStack(ModItems.ingot_schrabidium, 8), new Object[] { "UUU", "UPU", "UUU", 'U', U.ingot(), 'P', new ItemStack(ModItems.particle_higgs).setStackDisplayName("Higgs Boson (Temporary Recipe)") }); - addRecipeAuto(new ItemStack(ModItems.ingot_euphemium, 8), new Object[] { "UUU", "UPU", "UUU", 'U', PU.ingot(), 'P', new ItemStack(ModItems.particle_dark).setStackDisplayName("Dark Matter (Temporary Recipe)") }); - addRecipeAuto(new ItemStack(ModItems.ingot_dineutronium, 8), new Object[] { "UUU", "UPU", "UUU", 'U', SBD.ingot(), 'P', new ItemStack(ModItems.particle_sparkticle).setStackDisplayName("Sparkticle (Temporary Recipe)") }); - addRecipeAuto(new ItemStack(ModBlocks.fireworks, 1), new Object[] { "PPP", "PPP", "WIW", 'P', Items.paper, 'W', KEY_PLANKS, 'I', IRON.ingot() }); addRecipeAuto(new ItemStack(ModItems.safety_fuse, 8), new Object[] { "SSS", "SGS", "SSS", 'S', Items.string, 'G', Items.gunpowder }); diff --git a/src/main/java/com/hbm/render/tileentity/RenderExposureChamber.java b/src/main/java/com/hbm/render/tileentity/RenderExposureChamber.java index 539cb72a1..7fc7528da 100644 --- a/src/main/java/com/hbm/render/tileentity/RenderExposureChamber.java +++ b/src/main/java/com/hbm/render/tileentity/RenderExposureChamber.java @@ -4,6 +4,7 @@ import org.lwjgl.opengl.GL11; import com.hbm.blocks.BlockDummyable; import com.hbm.main.ResourceManager; +import com.hbm.tileentity.machine.TileEntityMachineExposureChamber; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.tileentity.TileEntity; @@ -11,7 +12,7 @@ import net.minecraft.tileentity.TileEntity; public class RenderExposureChamber extends TileEntitySpecialRenderer { @Override - public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float f) { + public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float interp) { GL11.glPushMatrix(); GL11.glTranslated(x + 0.5D, y, z + 0.5D); @@ -25,18 +26,24 @@ public class RenderExposureChamber extends TileEntitySpecialRenderer { case 2: GL11.glRotatef(90, 0F, 1F, 0F); break; } + TileEntityMachineExposureChamber chamber = (TileEntityMachineExposureChamber) tileEntity; + GL11.glShadeModel(GL11.GL_SMOOTH); bindTexture(ResourceManager.exposure_chamber_tex); ResourceManager.exposure_chamber.renderPart("Chamber"); - GL11.glPushMatrix(); - GL11.glRotated((tileEntity.getWorldObj().getTotalWorldTime() % 360D + f) * 5, 0, 1, 0); - GL11.glTranslated(0, Math.sin((tileEntity.getWorldObj().getTotalWorldTime() % (Math.PI * 16D) + f) * 0.125) * 0.0625, 0); - ResourceManager.exposure_chamber.renderPart("Core"); - GL11.glPopMatrix(); + double rotation = chamber.prevRotation + (chamber.rotation - chamber.prevRotation) * interp; + + if(chamber.isOn) { + GL11.glPushMatrix(); + GL11.glRotated(rotation / 2D, 0, 1, 0); + GL11.glTranslated(0, Math.sin((tileEntity.getWorldObj().getTotalWorldTime() % (Math.PI * 16D) + interp) * 0.125) * 0.0625, 0); + ResourceManager.exposure_chamber.renderPart("Core"); + GL11.glPopMatrix(); + } GL11.glPushMatrix(); - GL11.glRotated((tileEntity.getWorldObj().getTotalWorldTime() % 360D + f) * 10, 0, 1, 0); + GL11.glRotated(rotation, 0, 1, 0); ResourceManager.exposure_chamber.renderPart("Magnets"); GL11.glPopMatrix(); diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineExposureChamber.java b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineExposureChamber.java index dbe3dc5fa..d45fbe8cd 100644 --- a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineExposureChamber.java +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineExposureChamber.java @@ -1,15 +1,42 @@ package com.hbm.tileentity.machine; +import com.hbm.inventory.container.ContainerMachineExposureChamber; +import com.hbm.inventory.gui.GUIMachineExposureChamber; +import com.hbm.tileentity.IGUIProvider; import com.hbm.tileentity.TileEntityMachineBase; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import io.netty.buffer.ByteBuf; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.World; -public class TileEntityMachineExposureChamber extends TileEntityMachineBase { +public class TileEntityMachineExposureChamber extends TileEntityMachineBase implements IGUIProvider { + + public long power; + public static final long maxPower = 1_000_000; + + public int progress; + public static final int processTimeBase = 200; + public int processTime = processTimeBase; + public boolean isOn = false; + public float rotation; + public float prevRotation; public TileEntityMachineExposureChamber() { - super(7); + /* + * 0: Particle + * 1: Particle internal + * 2: Particle container + * 3: Ingredient + * 4: Output + * 5: Battery + * 6-7: Upgrades + */ + super(8); } @Override @@ -20,6 +47,38 @@ public class TileEntityMachineExposureChamber extends TileEntityMachineBase { @Override public void updateEntity() { + if(!worldObj.isRemote) { + + this.isOn = false; + this.networkPackNT(50); + } else { + + this.prevRotation = this.rotation; + + if(this.isOn) { + + this.rotation += 10D; + + if(this.rotation >= 720D) { + this.rotation -= 720D; + this.prevRotation -= 720D; + } + } + } + } + + @Override + public void serialize(ByteBuf buf) { + buf.writeBoolean(this.isOn); + buf.writeInt(this.progress); + buf.writeInt(this.processTime); + } + + @Override + public void deserialize(ByteBuf buf) { + this.isOn = buf.readBoolean(); + this.progress = buf.readInt(); + this.processTime = buf.readInt(); } AxisAlignedBB bb = null; @@ -46,4 +105,15 @@ public class TileEntityMachineExposureChamber extends TileEntityMachineBase { public double getMaxRenderDistanceSquared() { return 65536.0D; } + + @Override + public Container provideContainer(int ID, EntityPlayer player, World world, int x, int y, int z) { + return new ContainerMachineExposureChamber(player.inventory, this); + } + + @Override + @SideOnly(Side.CLIENT) + public GuiScreen provideGUI(int ID, EntityPlayer player, World world, int x, int y, int z) { + return new GUIMachineExposureChamber(player.inventory, this); + } } diff --git a/src/main/resources/assets/hbm/textures/gui/processing/gui_exposure_chamber.png b/src/main/resources/assets/hbm/textures/gui/processing/gui_exposure_chamber.png index f9e65f885b185b69ccee70f84c46e4b082cb4f5d..24701a27f3e6e1f1ae3ce0f18b5e29ede880aab9 100644 GIT binary patch delta 1530 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 D492{= delta 301 zcmdmCzKbcYGr-TCmrII^fq{Y7)59eQNE?7K2Q!dNxWl;>NHG=%xjQkeJ16rJ$YDu$ z^mSxl*x1kgCy^D%XAAHNas7V-$YS`RrZyW$F_i@Q1^;Jwy4}EQqM~>`!+K8_#}E(i zw|xis4lD2+eel1&inBte(f#TwTi>s&1&>xOjeEj-?nAp{q@BU+KRRsT5k6HvLs%-? zFJ~Uk+@m4L(t3l1CsaUm`N1;|9Ky_Qd~Pe#nOYhR1QZhGct}=!28b50m`}BX0H*13Y>iXZ(jfa