Jump to content

KittenKoder

Members
  • Posts

    77
  • Joined

  • Last visited

Everything posted by KittenKoder

  1. I have searched for something up to date, and found nothing. All I am doing is trying to add a custom bow with a set of obj models. Everything works but the transforms are not showing as all. I have no control over the transforms, and when I look at the vanilla code the bow seems to have hard coded transformations. I know Tinker's Construct managed to make this work, but I can't figure out how they did it. Here's the blockstate I tried: { "forge_marker": 1, "defaults": { "textures": { }, "model": "magitech:bow_compound_model" }, "variants": { "normal": [{ }], "inventory": [{ "transform": { "gui": { "rotation": [ { "y": 0}, {"x": 0}, {"z": 0} ], "translation": [ 0, 0, 0], "scale": 2.0 }, "ground": { "rotation": [ { "y": 0}, {"x": 0}, {"z": 0} ], "translation": [ 0, 0.25, 0], "scale": 1.5 }, "thirdperson": { "rotation": [ { "y": 90}, {"x": 0}, {"z": 45} ], "translation": [ 0, 0.475, 0.15], "scale": 1.35 }, "firstperson": { "rotation": [ { "y": 90}, {"x": 0}, {"z": 45} ], "translation": [ 0, 0, 0 ], "scale": 5.0 }, "fixed": { "rotation": [ { "y": 0}, {"x": 0}, {"z": 90} ], "translation": [ 0, 0, 0 ], "scale": 0.9 } } }] } } And the file it references (not sure why but it only looks in the block models for it): { "model": "magitech:item/bow_compound_model_standby.obj", "textures": { }, "overrides": [ { "predicate": { "pulling": 0 }, "model": "magitech:item/bow_compound_model_standby.obj" }, { "predicate": { "pulling": 1 }, "model": "magitech:item/bow_compound_model__pulling_0.obj" }, { "predicate": { "pulling": 1, "pull": 0.65 }, "model": "magitech:item/bow_compound_model__pulling_1.obj" }, { "predicate": { "pulling": 1, "pull": 0.9 }, "model": "magitech:item/bow_compound_model__pulling_2.obj" } ] } The rest is pretty basic, I tried using the vanilla transforms like this: { "model": "magitech:bow_compound_model_standby.obj", "textures": { }, "display": { "thirdperson_righthand": { "rotation": [ 0, 0, 0 ], "translation": [ -1, -2, 2.5 ], "scale": [ 0.9, 0.9, 0.9 ] }, "thirdperson_lefthand": { "rotation": [ 0, 0, 0 ], "translation": [ -1, -2, 2.5 ], "scale": [ 0.9, 0.9, 0.9 ] }, "firstperson_righthand": { "rotation": [ 0, 0, 0 ], "translation": [ 1.13, 3.2, 1.13], "scale": [ 3.0, 3.0, 3.0 ] }, "firstperson_lefthand": { "rotation": [ 0, 0, 0 ], "translation": [ 1.13, 3.2, 1.13], "scale": [ 0.68, 0.68, 0.68 ] } }, "overrides": [ { "predicate": { "pulling": 0 }, "model": "magitech:item/bow_compound_model_standby.obj" }, { "predicate": { "pulling": 1 }, "model": "magitech:item/bow_compound_model__pulling_0.obj" }, { "predicate": { "pulling": 1, "pull": 0.65 }, "model": "magitech:item/bow_compound_model__pulling_1.obj" }, { "predicate": { "pulling": 1, "pull": 0.9 }, "model": "magitech:item/bow_compound_model__pulling_2.obj" } ] } But all of them produce the exact same results, the model is rotated as a simple held/generated item. So why and how do I fix it? It only happens with the that have an override property, nothing else has had this problem (I've added a lot of other items with obj models already). If I extend Item or ItemBow, it makes no difference.
  2. There are many cases in which the JSON recipes are clunky, like for adding a bunch of recipes for simple variants of models (such as if you are adding in a bunch of stairs). While making your own recipe class seems to be preferred, it's just adding more work when a simple array list would cut the work in half or more.
  3. Okay, so here's the thing I've been trying to find: a way to render armor using an OBJ model. I have gotten as far as finding the IModel of the armor, but I can't find anything about rendering it and how to do that, at least nothing up to date. Most resources say to bake it every time, then render it and I know that's not a good idea. The inventory model is different from the worn model, if that means anything. So do I find the model using the baked model system? I think I know how to render it that way if so. Or do I need to use the IModel? If so, how do you render one of those? The entire rendering system here just seems like a mess and I am not that good with the old GL styles so I often get completely lost when those methods are employed. I mean the entire GLStateManager concept took some getting use to, I prefer matrices as they are much easier to manage. So some insight on this is really welcomed. I do have some TESRs that work, but this part doesn't seem to function like those at all.
  4. Okay, I made the same mistake I have made before but stupid me didn't think to double check that part of the code. Seeing as how this is the first time I was stupid enough to start a thread on this, here was the issue: I was looking at the wrong instance for Minecraft to get the tile entity in the data packet code. While the client was receiving the packet, and acting on it, it was getting the TE from the server world instead. Copy-pasta has some problems even when it's your own code. In case someone else finds this to be similar to their problem. Just make sure you look for the entity from the correct instance. Now I get to clean up my class.
  5. I don't think you understood. Replace the (IInventory) player with player.inventory
  6. Your meta/state getters don't seem to include the HALF property, while your JSON depends on those values being set. Perhaps that is the cause?
  7. Between function calls, every value except the inventory is reset to their default values. The problem is that I cannot see where or why. The code is a mess as I have been trying to find a work around for this, but no system of notifying the client side of changes seems to keep the values, even the GUI set is reset to null. This doesn't seem right as I have accomplished the same thing in other custom TileEntity classes, using even more data. The question is why is this happening? Is there a clean way to correct this without having to create more classes? package com.kittenkoder.magitech.tile; import java.util.LinkedList; import java.util.UUID; import javax.annotation.Nullable; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.ItemStackHandler; import com.kittenkoder.magitech.Magitech; import com.kittenkoder.magitech.MagitechOreRegistry; import com.kittenkoder.magitech.blocks.IMagitechBlockVariant; import com.kittenkoder.magitech.blocks.MagitechBlockFan; import com.kittenkoder.magitech.blocks.MagitechBlockMachineCrusher; import com.kittenkoder.magitech.blocks.MagitechBlockMachineSmelter; import com.kittenkoder.magitech.gui.MagitechGUIMachine; import com.kittenkoder.magitech.network.MagitechIntegerRequestUpdate; import com.kittenkoder.magitech.network.MagitechUpdateFluid; import com.kittenkoder.magitech.network.MagitechUpdateIntegerPacketClient; import com.kittenkoder.magitech.network.MagitechUpdateRequestFluids; import com.kittenkoder.magitech.network.containers.UpdatePostData; import com.kittenkoder.magitech.util.MagitechFluidLevel; public class MagitechTileEntityMachineSmelter extends MagitechTileEntityBox implements IMagitechTileMachine, IMagitechTileEntityWatts, IMagitechBlockVariant, IMagitechTileInventory, IMagitechTileEntityIntegerUpdate, ITickable, IMagitechTileEntityFluid { protected final LinkedList<UpdatePostData> UPDATE_LIST; protected int _processtime = 0, _cooldown = 10; protected final MagitechFluidLevel _fluid_result; protected boolean _haspower = false; protected int _speed = 1, _capacity = 16; protected MagitechGUIMachine _gui; public MagitechTileEntityMachineSmelter() { super(1); this._fluid_result = new MagitechFluidLevel(MagitechOreRegistry.Fluids.ALUMINUM, 0); this.UPDATE_LIST = new LinkedList<UpdatePostData>(); this._gui = null; } public void setGUI(MagitechGUIMachine gui) { this._gui = gui; if(gui != null) Magitech.net.sendToServer(new MagitechUpdateRequestFluids(this)); } @Override public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newState) { return (oldState.getBlock() != newState.getBlock()); } public void setHasPower(boolean h, boolean update) { this._haspower = h; if(!this.getWorld().isRemote){ if(!h) { this._processtime = 0; this.setIntegerToUpdate(0, Flag.PROGRESS, null, true); } if(update) { IBlockState bl = this.getWorld().getBlockState(this.getPos()); if(bl != null && bl.getBlock() instanceof MagitechBlockMachineSmelter) { bl = bl.withProperty(MagitechBlockMachineSmelter.POWERED, this._haspower); this.getWorld().setBlockState(this.getPos(), bl); } this.markDirty(); } } } public int getProgress() { return this._processtime; } public boolean getHasPower() { return this._haspower; } @Override public void setIntegerToUpdate(int i, IMagitechTileEntityIntegerUpdate.Flag flag, UUID player, boolean s) { if(this.getWorld().isRemote) { if(!s) { this._processtime = i; } } else { if(s) { this.UPDATE_LIST.add(new UpdatePostData(this, this._processtime, Flag.PROGRESS, null)); Magitech.net.sendToAllAround(new MagitechUpdateIntegerPacketClient(this), new NetworkRegistry.TargetPoint(this.getWorld().provider.getDimension(), this.getPos().getX(), this.getPos().getY(), this.getPos().getZ(), 8)); } } } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { compound = super.writeToNBT(compound); compound.setInteger("MagitechProgress", this._processtime); compound.setInteger("MagitechSpeed", this._speed); compound.setInteger("MagitechCapacity", this._capacity); compound.setBoolean("MagitechPowered", this._haspower); this.writeFluidsToNBT(compound); return compound; } @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); this._processtime = compound.getInteger("MagitechProgress"); this._speed = compound.getInteger("MagitechSpeed"); this._capacity = compound.getInteger("MagitechCapacity"); this._haspower = compound.getBoolean("MagitechPowered"); this.readFluidsFromNBT(compound); } @Override public int getNextUpdateInteger() { UpdatePostData n = this.UPDATE_LIST.getFirst(); return n.value; } @Override public IMagitechTileEntityIntegerUpdate.Flag getNextUpdateFlag() { UpdatePostData n = this.UPDATE_LIST.getFirst(); return n.flag; } @Override public void popNext() { this.UPDATE_LIST.remove(); } @Override public ItemStack getStackInSlot(int index) { return this.inventory.getStackInSlot(0); } @Override public ItemStack removeStackFromSlot(int index) { ItemStack stack = this.inventory.getStackInSlot(0); this.inventory.setStackInSlot(0, ItemStack.EMPTY); return stack; } @Override public boolean hasCapability(Capability<?> capability, @Nullable EnumFacing facing) { if(this.inventory == null) return super.hasCapability(capability, facing); return (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY && facing == EnumFacing.UP) || super.hasCapability(capability, facing); } @SuppressWarnings("unchecked") @Nullable @Override public <T> T getCapability(Capability<T> capability, @Nullable EnumFacing facing) { if(this.inventory == null) return super.getCapability(capability, facing); if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { if(facing == EnumFacing.UP) return (T)this.inventory; } return super.getCapability(capability, facing); } @Override public void setInventorySlotContents(int index, ItemStack stack) { this.inventory.setStackInSlot(0, stack); } public void writeFluidsToNBT(NBTTagCompound compound) { NBTTagCompound fl = new NBTTagCompound(); fl.setInteger("FluidCount", 1); String na = "Fluid"; fl.setInteger(na + "Index", this._fluid_result._fluid.index); fl.setInteger(na + "Level", this._fluid_result._level); compound.setTag("MagitechFluid", fl); System.out.println("Level Writ: " + this._fluid_result._level); System.out.println("Fluid Writ: " + this._fluid_result._fluid.index); } public void readFluidsFromNBT(NBTTagCompound compound) { if(compound.hasKey("MagitechFluid")) { NBTTagCompound fl = compound.getCompoundTag("MagitechFluid"); String na = "Fluid"; this._fluid_result.set(MagitechOreRegistry.Fluids.find(fl.getInteger(na + "Index")), fl.getInteger(na + "Level")); System.out.println("Level Read: " + this._fluid_result._level); System.out.println("Fluid read: " + this._fluid_result._fluid.index); } } @Override public ItemStackHandler getInventory() { return this.inventory; } @Override public int getWattLevel() { return 0; } @Override public void setWattLevel(int p) { } @Override public void onLoad() { if(this.getWorld().isRemote) { Magitech.net.sendToServer(new MagitechIntegerRequestUpdate(this, Flag.PROGRESS)); Magitech.net.sendToServer(new MagitechUpdateRequestFluids(this)); return; } } @Override public boolean takesWatts(EnumFacing face, IBlockState state) { return face == state.getValue(MagitechBlockMachineCrusher.VARIANT).face; } @Override public boolean suppliesWatts(EnumFacing face, IBlockState state) { return false; } @Override public void notifyMachineStructure(BlockPos cpos, World nworld) { this._speed = 1; for(int y = -5; y < 6 && this._speed < 99; y++) { BlockPos tpos = cpos.add(0, y, 0); if(tpos.getY() < 256 && tpos.getY() > 0) { for(int x = -5; x < 6 && this._speed < 99; x++) { for(int z = -5; z < 6 && this._speed < 99; z++) { BlockPos npos = tpos.add(x, 0, z); IBlockState tile = nworld.getBlockState(npos); if(tile != null) { Block tblock = tile.getBlock(); if(tblock instanceof MagitechBlockFan) this._speed = Math.min(99, this._speed + ((MagitechBlockFan)tblock).getRank() + 1); } } } } } this.markDirty(); } @Override public void update() { if(this.getWorld().isRemote || !this._haspower) return; this._cooldown--; if(this._cooldown > 0) return; this._cooldown = 5; ItemStack stack = this.inventory.getStackInSlot(0); if(stack.isEmpty()) { int lastproc = this._processtime; this._processtime = 0; if(lastproc != 0) this.setIntegerToUpdate(0, Flag.PROGRESS, null, true); return; } MagitechFluidLevel presult = null; MagitechOreRegistry.Ore ore; int level = 1; if(!stack.isEmpty()) { Item item = stack.getItem(); ore = MagitechOreRegistry.byAllWithDust(item); if(ore == null && item instanceof ItemBlock) { Block block = ((ItemBlock)item).getBlock(); ore = MagitechOreRegistry.byOre(block); if(ore == null) { ore = MagitechOreRegistry.byBlock(block); if(ore != null) level = 9; } } if(ore != null) presult = new MagitechFluidLevel(MagitechOreRegistry.Fluids.getByOre(ore), level); } boolean isvalid = presult != null && (this._fluid_result._level == 0 || (this._fluid_result._fluid == presult._fluid && this._fluid_result._level + presult._level <= this._capacity)); if(!isvalid) { int lastproc = this._processtime; this._processtime = 0; if(lastproc != 0) this.setIntegerToUpdate(0, Flag.PROGRESS, null, true); this.markDirty(); return; } else { this._processtime += this._speed; if(this._processtime < 100) { this.setIntegerToUpdate(0, Flag.PROGRESS, null, true); return; } this._processtime = 0; this.setIntegerToUpdate(0, Flag.PROGRESS, null, true); this.inventory.extractItem(0, 1, false); if(this._fluid_result._fluid != presult._fluid) this._fluid_result.set(presult); else this._fluid_result._level += presult._level; this.markDirty(); Magitech.net.sendToAllAround(new MagitechUpdateFluid(this), new NetworkRegistry.TargetPoint(this.getWorld().provider.getDimension(), this.getPos().getX(), this.getPos().getY(), this.getPos().getZ(), 8)); } } @Override public UUID getNextPlayer() { return null; } @Override public String getUnlocalizedName(int meta) { return this.blockType.getLocalizedName(); } @Override public MagitechGUIMachine.Type getGUIType() { return MagitechGUIMachine.Type.SMELTER; } @Override public int getDataForInteger(Flag flag) { if(flag == Flag.PROGRESS) return this._processtime; return 0; } @Override public int getNumberOfFluids() { return 1; } @Override public LinkedList<MagitechFluidLevel> getFluidLevels() { if(this._fluid_result != null) { LinkedList<MagitechFluidLevel> list = new LinkedList<MagitechFluidLevel>(); list.add(this._fluid_result); return list; } return null; } @Override public void setFluidLevels(LinkedList<MagitechFluidLevel> f) { if(f != null && f.size() > 0) this._fluid_result.set(f.pop()); else this._fluid_result._level = 0; if(this._gui != null) this._gui.setFluid(this._fluid_result._fluid, this._fluid_result._level); System.out.println("Level Rec: " + this._fluid_result._level); System.out.println("Fluid Rec: " + this._fluid_result._fluid.index); System.out.println("To GUI: " + this._gui); } @Override public MagitechFluidLevel getFluid(int i){ return this._fluid_result; } }
  8. Or use the <> code tag if it's short. Something that doesn't require downloading.
  9. Are your textures in the <projectroot>resources/assets/<modid>/textures directory? The compiler looks in the resources directory for the assets directory. The root directory is where you are running Gradle from most of the time.
  10. It's better to use the code tags, just a recommendation. They are < > in the editor.
  11. This was the part I was interested in. But after reading your post again I think I understood and replaced everything with the get methods in my update method. I'm getting it to work with the classes now as well. If your's breaks again, try replacing the world member with the getWorld method too. Thanks for keeping on this, I had to write almost a hundred recipe files today so I haven't had time to dig more on it. lol It didn't occur to me to look at the members being referenced in the functions.
  12. I don't understand what you mean by this? I was testing with just System.out messages and got nothing in the logs (junk or server). Could you please show us the code involved?
  13. You can also access it with TileEntity::pos, so be careful using that as a variable in your TE.
  14. I have this button I extended from GuiButton because I couldn't get the regular texture button to work. Here's the class: package com.kittenkoder.magitech.gui; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) public class MagitechGUIButtonTexture extends GuiButton { protected ResourceLocation _texture; protected int _texx, _texy; public MagitechGUIButtonTexture(int buttonId, int x, int y, int widthIn, int heightIn, ResourceLocation texture, int tx, int ty) { super(buttonId, x, y, widthIn, heightIn, ""); this._texture = texture; this._texx = tx; this._texy = ty; } public void setTexCoords(int x, int y) { this._texx = x; this._texy = y; } public void drawButton(Minecraft mc, int mouseX, int mouseY, float partialTicks) { if(!this.visible) return; mc.getTextureManager().bindTexture(this._texture); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); GlStateManager.enableBlend(); GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); this.drawTexturedModalRect(this.x, this.y, this._texx, this._texy, this.width, this.height); } } The problem is that it's drawing something odd to the right of the GUI, here's an image: It looks like it's drawing one of the texture coordinates there as when I change the buttons' contents (which only changes where it gets the texture piece from) the artifacts change. Did I forget to override something? The Gui and GuiButton source hasn't offered much clues into this. In case it's the GUI that the buttons are being added to, here's that: package com.kittenkoder.magitech.gui; import java.io.IOException; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Container; import net.minecraft.util.ResourceLocation; import com.kittenkoder.magitech.Magitech; import com.kittenkoder.magitech.tile.MagitechTileEntitySorter; import com.kittenkoder.magitech.util.MagitechUtils; public class MagitechGUISorter extends GuiContainer { private static final ResourceLocation BG_TEXTURE = new ResourceLocation(Magitech.MODID, "textures/gui/container/pipe_sorter.png"); // private static final String TEXT_INPUT = I18n.format("text.gui_sorter.input"); // private static final String TEXT_OUTPUT = I18n.format("text.gui_sorter.output"); private InventoryPlayer _player; private MagitechTileEntitySorter _sorter; public MagitechGUISorter(Container inventorySlotsIn, InventoryPlayer player, MagitechTileEntitySorter sorter) { super(inventorySlotsIn); this._sorter = sorter; this._player = player; this._sorter.setGUI(this); } public void initGui() { super.initGui(); int x = (width - xSize) / 2; int y = (height - ySize) / 2; this.buttonList.add(this.createButton(MagitechTileEntitySorter.Job.SORT_1, x, y)); this.buttonList.add(this.createButton(MagitechTileEntitySorter.Job.SORT_2, x, y)); this.buttonList.add(this.createButton(MagitechTileEntitySorter.Job.SORT_3, x, y)); this.buttonList.add(this.createButton(MagitechTileEntitySorter.Job.SORT_4, x, y)); this.buttonList.add(this.createButton(MagitechTileEntitySorter.Job.OUTPUT, x, y)); } protected MagitechGUIButtonTexture createButton(MagitechTileEntitySorter.Job job, int x, int y) { int sx = 0; int sy = 0; int dx = 0; int dy = 0; MagitechUtils.Facing face = this._sorter.getFacing(job); if(MagitechUtils.Facing.DOWN == face) sx = 16; else if(MagitechUtils.Facing.NORTH == face) sy = 16; else if(MagitechUtils.Facing.SOUTH == face) sy = 32; else if(MagitechUtils.Facing.WEST == face) { sx = 16; sy = 16; } else if(MagitechUtils.Facing.EAST == face) { sx = 16; sy = 32; } if(MagitechTileEntitySorter.Job.SORT_2 == job) dy = 36; else if(MagitechTileEntitySorter.Job.SORT_3 == job) dx = 36; else if(MagitechTileEntitySorter.Job.SORT_4 == job) { dx = 36; dy = 36; } else if(MagitechTileEntitySorter.Job.OUTPUT == job) { dx = 18; dy = 18; } MagitechGUIButtonTexture butt = new MagitechGUIButtonTexture(job._index, 62 + x + dx, 17 + y + dy, 16, 16, BG_TEXTURE, sx + 176, sy); return butt; } public void updateButton(MagitechTileEntitySorter.Job job, MagitechUtils.Facing face) { int i = job._index; for(GuiButton button : this.buttonList) { if(button.id == i) { MagitechGUIButtonTexture butt = (MagitechGUIButtonTexture)button; int sx = 0; int sy = 0; if(MagitechUtils.Facing.DOWN == face) sx = 16; else if(MagitechUtils.Facing.NORTH == face) sy = 16; else if(MagitechUtils.Facing.SOUTH == face) sy = 32; else if(MagitechUtils.Facing.WEST == face) { sx = 16; sy = 16; } else if(MagitechUtils.Facing.EAST == face) { sx = 16; sy = 32; } butt.setTexCoords(sx + 176, sy); return; } } } protected void updateButton(GuiButton button) { if(button instanceof MagitechGUIButtonTexture) { MagitechGUIButtonTexture butt = (MagitechGUIButtonTexture)button; int sx = 0; int sy = 0; MagitechUtils.Facing face = this._sorter.getFacing(button.id); if(MagitechUtils.Facing.DOWN == face) sx = 16; else if(MagitechUtils.Facing.NORTH == face) sy = 16; else if(MagitechUtils.Facing.SOUTH == face) sy = 32; else if(MagitechUtils.Facing.WEST == face) { sx = 16; sy = 16; } else if(MagitechUtils.Facing.EAST == face) { sx = 16; sy = 32; } butt.setTexCoords(sx + 176, sy); } } protected void actionPerformed(GuiButton button) throws IOException { int i = button.id; if(i > -1 && i < 5) { this._sorter.setIntegerToUpdate(i, 0, true); return; } super.actionPerformed(button); } protected void drawFace(MagitechTileEntitySorter.Job job, int x, int y) { int sx = 0; int sy = 0; int dx = 0; int dy = 0; MagitechUtils.Facing face = this._sorter.getFacing(job); if(MagitechUtils.Facing.DOWN == face) sx = 16; else if(MagitechUtils.Facing.NORTH == face) sy = 16; else if(MagitechUtils.Facing.SOUTH == face) sy = 32; else if(MagitechUtils.Facing.WEST == face) { sx = 16; sy = 16; } else if(MagitechUtils.Facing.EAST == face) { sx = 16; sy = 32; } if(MagitechTileEntitySorter.Job.SORT_2 == job) dy = 36; else if(MagitechTileEntitySorter.Job.SORT_3 == job) dx = 36; else if(MagitechTileEntitySorter.Job.SORT_4 == job) { dx = 36; dy = 36; } else if(MagitechTileEntitySorter.Job.OUTPUT == job) { dx = 18; dy = 18; } drawTexturedModalRect(dx + 62 + x, dy + 17 + y, sx + 176, sy, 16, 16); } @Override protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { GlStateManager.color(1, 1, 1, 1); mc.getTextureManager().bindTexture(BG_TEXTURE); int x = (width - xSize) / 2; int y = (height - ySize) / 2; drawTexturedModalRect(x, y, 0, 0, xSize, ySize); } public void drawScreen(int mouseX, int mouseY, float partialTicks) { this.drawDefaultBackground(); super.drawScreen(mouseX, mouseY, partialTicks); this.renderHoveredToolTip(mouseX, mouseY); } @Override protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { String name = I18n.format(this._sorter.getBlockType().getUnlocalizedName() + ".name"); this.fontRenderer.drawString(name, xSize / 2 - fontRenderer.getStringWidth(name) / 2, 6, 0x404040); this.fontRenderer.drawString(this._player.getDisplayName().getUnformattedText(), 8, ySize - 94, 0x404040); int x = (width - xSize) / 2; int y = (height - ySize) / 2; this.drawFace(MagitechTileEntitySorter.Job.SORT_1, x, y); this.drawFace(MagitechTileEntitySorter.Job.SORT_2, x, y); this.drawFace(MagitechTileEntitySorter.Job.SORT_3, x, y); this.drawFace(MagitechTileEntitySorter.Job.SORT_4, x, y); this.drawFace(MagitechTileEntitySorter.Job.OUTPUT, x, y); } protected void jobClicked(MagitechTileEntitySorter.Job job) { this._sorter.setJob(job, this._sorter.getFacing(job).getNext()); } protected void renderHoveredToolTip(int x, int y) { super.renderHoveredToolTip(x, y); } public void onGuiClosed() { this._sorter.setGUI(null); super.onGuiClosed(); } } On this, in insight would be helpful to get rid of it.
  15. ... and yet again I feel like an ideeot! It had nothing to do with that class, it was the message processing class that was in error. It was looking at the wrong world instance, serves me right for using copy-pasta even when it is my own code. So for those running into similar issues, remember to get the correct world instances when collecting the TileEntity to modify in a message.
  16. So here is how I register the message: Magitech.net.registerMessage(new MagitechUpdateIntegerPacket.Handler(), MagitechUpdateIntegerPacket.class, id++, Side.SERVER); Which seems fine, but for some reason the client is the one processing the message. Based on what I read, the server should be processing this not the client. I don't get any errors in the code when it's run, so I can't figure out why this part isn't working as expected.
  17. UPDATE: I figured out that it has something to do with my server-client communications, not the read/write to NBT code.
  18. So I wrote the class, everything seems to work, but the data saved to the NBT is incorrect, nor does it load the same data from the NBT. Specifically on the sides and facing data. It continually reads and writes the default data set during construction. On the client is seems to save all 0s for the index values. So I know I missed setting the values somewhere, but I can't see it. I know the server is getting the correct updates from the client's GUI, and it sending the updates to the client (to update the GUI correctly). Everything is registered correctly, so please check to see if you can find where I messed up the setting of these values. package com.kittenkoder.magitech.tile; import java.util.LinkedList; import javax.annotation.Nullable; import net.minecraft.block.state.IBlockState; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.ItemStackHandler; import com.kittenkoder.magitech.Magitech; import com.kittenkoder.magitech.gui.MagitechGUISorter; import com.kittenkoder.magitech.network.MagitechRequestSorterUpdate; import com.kittenkoder.magitech.network.MagitechUpdateIntegerPacket; import com.kittenkoder.magitech.network.MagitechUpdateSorterPacket; import com.kittenkoder.magitech.network.containers.UpdatePostData; public class MagitechTileEntitySorter extends MagitechTileEntityBox implements IMagitechTileEntityIntegerUpdate { public static enum Job { OUTPUT(0), SORT_1(1), SORT_2(2), SORT_3(3), SORT_4(4), INPUT(5); public static final Job[] LOOKUP = new Job[MagitechTileEntitySorter.Job.values().length]; public final int _index; Job(int i) { this._index = i; } static { for(Job job : Job.values()) Job.LOOKUP[job._index] = job; } } public static enum Facing { NORTH(0, EnumFacing.NORTH), SOUTH(1, EnumFacing.SOUTH), EAST(2, EnumFacing.EAST), WEST(3, EnumFacing.WEST), UP(4, EnumFacing.UP), DOWN(5, EnumFacing.DOWN); private static final Facing[] LOOKUP = new Facing[Facing.values().length]; public final EnumFacing _face; public final int _index; private Facing _next; Facing(int i, EnumFacing f) { this._face = f; this._index = i; } public Facing getNext() { return this._next; } static { for(Facing face : Facing.values()) Facing.LOOKUP[face._index] = face; for(int i = 0; i < Facing.LOOKUP.length; i++) Facing.LOOKUP[i]._next = i == 0 ? Facing.LOOKUP[Facing.LOOKUP.length - 1] : Facing.LOOKUP[i - 1]; } public static int indexForFacing(EnumFacing facing) { for(Facing face : LOOKUP) if(face._face == facing) return face._index; return 0; } public static Facing facingForFacing(EnumFacing facing) { for(Facing face : LOOKUP) if(face._face == facing) return face; return LOOKUP[0]; } public static Facing lookUp(int i) { if(i > 5 || 1 < 0) return LOOKUP[0]; return LOOKUP[i]; } } protected static final LinkedList<UpdatePostData> UPDATE_LIST = new LinkedList<UpdatePostData>(); protected final ItemStackHandler[] _filters; protected final Facing[] _sides; protected MagitechGUISorter _gui = null; public MagitechTileEntitySorter() { super(4); this._filters = new ItemStackHandler[4]; for(int i = 0; i < 4; i++) this._filters[i] = new ItemStackHandler(3); this._sides = new Facing[6]; for(int i = 0; i < 6; i++) this._sides[i] = Facing.LOOKUP[i]; } @Override public void onLoad() { if(!world.isRemote) world.scheduleBlockUpdate(pos, this.getBlockType(), 5, 0); else Magitech.net.sendToServer(new MagitechRequestSorterUpdate(this)); } public void setGUI(MagitechGUISorter gui) { this._gui = gui; } public void setJob(Job j, Facing i) { this.setJob(j._index, i); } public void setJob(int j, Facing i) { this._sides[j] = i; System.out.println("Set to " + Integer.toString(j) + " = " + Integer.toString(this._sides[j]._index)); if(!world.isRemote) Magitech.net.sendToAllAround(new MagitechUpdateSorterPacket(this), new NetworkRegistry.TargetPoint(world.provider.getDimension(), pos.getX(), pos.getY(), pos.getZ(), 64)); else if(this._gui != null) this._gui.updateButton(Job.LOOKUP[j], i); } public void setJob(int j, int i) { this.setJob(j, MagitechTileEntitySorter.Facing.lookUp(i)); } public Facing getFacing(Job i) { return this._sides[i._index]; } public Facing getFacing(int i) { return this._sides[i]; } public void updateTick(IBlockState state) { // if(this.getBlockType() == null) return; // MagitechBlockPipe tblock = (MagitechBlockPipe)this.getBlockType(); // EnumFacing face = MagitechBlockPipe.getFacingFromMeta(this.getBlockMetadata()); // BlockPos npos = pos.offset(face); // TileEntity entity = world.getTileEntity(npos); // if(entity != null && entity.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, face.getOpposite())) { // IItemHandler target = entity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.UP); // boolean done = false; // for(int i = 0; i < inventory.getSlots() && !done; ++i) { // ItemStack test = inventory.extractItem(i, tblock.getSpeed(), true); // if(test != null && !test.isEmpty()) { // int start = test.getCount(); // test = MagitechUtils.addToInventory(test, target); // int end = test.getCount(); // if(end != start) { // inventory.extractItem(i, start - end, false); // this.markDirty(); // entity.markDirty(); // done = true; // } // } // } // } } @Override public boolean hasCapability(Capability<?> capability, @Nullable EnumFacing facing) { if(this.inventory == null) return super.hasCapability(capability, facing); if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return (this._sides[Job.INPUT._index] == Facing.facingForFacing(facing)); return capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing); } @SuppressWarnings("unchecked") @Nullable @Override public <T> T getCapability(Capability<T> capability, @Nullable EnumFacing facing) { if(this.inventory == null) return super.getCapability(capability, facing); if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { Facing index = Facing.facingForFacing(facing); if (this._sides[Job.INPUT._index] == index) return (T)this.inventory; } return super.getCapability(capability, facing); } @Override public ItemStack getStackInSlot(int index) { if(index > this._size) return ItemStack.EMPTY; return this.inventory.getStackInSlot(index); } @Override public ItemStack removeStackFromSlot(int index) { if(index > this._size) return ItemStack.EMPTY; ItemStack stack = this.inventory.getStackInSlot(index); this.inventory.setStackInSlot(index, ItemStack.EMPTY); return stack; } @Override public void setInventorySlotContents(int index, ItemStack stack) { if(index > this._size) return; this.inventory.setStackInSlot(index, stack); } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { compound = super.writeToNBT(compound); this.writeInventoryToNBT(compound); return compound; } @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); this.readInventoryFromNBT(compound); } @Override public void writeInventoryToNBT(NBTTagCompound tag) { tag.setTag("MagitechInventory", this.inventory.serializeNBT()); NBTTagCompound filters = new NBTTagCompound(); for(int i = 0; i < 4; i++) filters.setTag("Filter_" + Integer.toString(i), this._filters[i].serializeNBT()); tag.setTag("MagitechFilters", filters); filters = new NBTTagCompound(); for(int i = 0; i < 6; i++) { filters.setInteger("Job_" + Integer.toString(i), this._sides[i]._index); System.out.println(Integer.toString(i) + " = " + Integer.toString(this._sides[i]._index)); } tag.setTag("MagitechJobs", filters); } @Override public void readInventoryFromNBT(NBTTagCompound tag) { this.inventory.deserializeNBT(tag.getCompoundTag("MagitechInventory")); NBTTagCompound filters = tag.getCompoundTag("MagitechFilters"); for(int i = 0; i < 4; i++) this._filters[i].deserializeNBT(filters.getCompoundTag("Filter_" + Integer.toString(i))); filters = tag.getCompoundTag("MagitechJobs"); for(int i = 0; i < 6; i++) { this._sides[i] = Facing.LOOKUP[filters.getInteger("Job_" + Integer.toString(i))]; System.out.println(Integer.toString(i) + " = " + Integer.toString(this._sides[i]._index)); } } @Override public ItemStackHandler getInventory() { return this.inventory; } public ItemStackHandler getFilter(int i) { return this._filters[i]; } @Override public void setIntegerToUpdate(int i, int flag, boolean s) { if(this.world.isRemote) if(!s) { this.setJob(i, this._sides[i]._next); } else { MagitechTileEntitySorter.UPDATE_LIST.add(new UpdatePostData(this, i, flag)); Magitech.net.sendToServer(new MagitechUpdateIntegerPacket(this)); } else { this.setJob(i, this._sides[i]._next); } } @Override public int getNextUpdateInteger() { UpdatePostData n = MagitechTileEntitySorter.UPDATE_LIST.getFirst(); return n.value; } @Override public int getNextUpdateFlag() { UpdatePostData n = MagitechTileEntitySorter.UPDATE_LIST.getFirst(); return n.flag; } @Override public void popNext() { MagitechTileEntitySorter.UPDATE_LIST.remove(); } } I hope this isn't a case where I find it right after I post this. lol Once I get this working I have to generalize much of the code for it as it will be needed for other machines.
  19. Chromebook is not my preferred flavor of Linux, but it is Linux. Use the Linux steps to get it working.
  20. Don't forget the schedule update for the entity's onLoad. That is what initiates it on chunk loading.
  21. A furnace is also recognized by vanilla code. The point at which ITickable is added to a special list is on chunk loading, it looks like it should all work, but the fact is that it doesn't work.
  22. Great, that means more manual typing of things for me. I was using a registry enum for simpler registration so if I ever need the update method I'll have to actually register them out of the loop. At least you did find a solution, kudos on sticking with it.
  23. That's some nice info jabelar, but it's not working like that. The list loaded during chunk loading does not appear to be realized until after certain events occur, one such event is GUI interaction. I am hoping someone can track down why this is the case, but for now scheduling infrequent tick updates is the only thing that works 100% of the time in all cases. Basically when the block is placed or the entity is loaded. onLoad for the entity, onBlockPlacedBy for the block class just because all you need is the block instance since you do have to extract the entity from the world. Which is why I wish the update calling was more reliable. This does explain a lot about Mekanisms and why that mod breaks so much, especially during multiplayer. Thankfully most of what I am doing doesn't require constant tick checks.
  24. Okay, seeing as how there is at least one other mod called Magitech, and there's already a modpack called it on CurseForge, I was hoping someone could help offer some suggestions for a new name for mine. So here's the mod idea: Balanced so that vanilla is fully integrated and plays a major role. Offers ritual magics to help control and enhance enchants as well as produce some new super items for after defeating the dragon. Technology resembles redstone mechanics using a system that is less prone to errors on chunk loading and reducing lag on large multiplayer servers. Magic and technology are seamlessly integrated in the late game, though at first they only enhance each other. Offering new cosmetic blocks, including many from 1.13, into 1.12. Perfectly balanced with the vanilla in a way that encourages the player to enjoy a slow progression, thus making the content reveal at a slower pace. New mobs, dark creatures from "someplace else" that appears to be leaking into the world. New bosses appearing after the End is conquered. All models are designed to look vanilla, even though many will offer more detail they will always have a pixelated look. 18 new metals, only 11 are ores, the rest are alloys. Complex crafting for machines, many multi-step recipes that require machines which often require ores from the "next level" to get. Stand alone - purposefully making it incompatible with other ores from other mods to prevent accelerated progression. Beautified nether and end, while keeping the vanilla generators. Alchemy to add more brewing options. New enchants with some PvP specific elements included (like disarm enchant that sets player's main hand to a random slot). More bows! Sorry, but so few mods add many bows to the game, and often I personally don't like how they are implemented when they are added. Okay, based on that what do you think a good name will be? I will post screencaps on request. PS: If this is not the correct section for this, please let me know. I'll change the topic once I have a name.
  25. Put the assets folder in the <projectroot>/resources folder if it's for Eclipse. I don't know about IntelliJ, but it should be the same. So it looks like this <projectroot>/resources/assets/<modname>/*
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.