-
Posts
852 -
Joined
-
Last visited
Everything posted by Bektor
-
[1.12.1] [UNSOLVED] Registering blocks/items and models
Bektor replied to Bektor's topic in Modder Support
I'm not using GameRegistry.register. The code is from 1.10.2 and my goal is to have a system which does something similiar in 1.12 using Registry events. I know how to register blocks and items with the registry events, but I don't know how to do it in a flexible way like my old code allowed it. Ok,I'm looking into it. -
Hi, I've got the following code I've used so far for handling all varius aspects of registering my blocks and the models for its. This code is for blocks only, but I've got some similiar code for items, too. My problem is now, I'm currently porting some things from my mod over to 1.12.1 and 1.11.2 with using the new RegistryEvents, but I don't want to lose the flexibility of the system I've got below. Note: This system was also used in my old mod for orginizing stuff. This means I've used it in my old mod also to register everything with sub-folders. For example I've got those paths when a block had multiply variants and still want to have it as an optional part in my 1.12 code with the RegistryEvents. /** * Provides the functionality of automatically registering the block and * setting the registry name and unlocalized name. It also registered * the block JSON renderer's and the item block with it's JSON renderer's. * * @param block The block to register * @param name The unique name of the block * @param itemFactory A function that creates the ItemBlock instance, or null if no ItemBlock should be created * @param withMeta Should the meta data of the block also be registered? * @return The block */ public static Block register(Block block, String name, @Nullable Function<Block, ItemBlock> itemFactory, boolean withMeta) { block.setUnlocalizedName(Constants.MOD_ID.toLowerCase() + "." + name); block.setRegistryName(name); GameRegistry.register(block); if(itemFactory != null) { final ItemBlock itemBlock = itemFactory.apply(block); GameRegistry.register(itemBlock.setRegistryName(block.getRegistryName())); if(block instanceof IItemOreDict) ((IItemOreDict)block).initOreDict(); if(itemBlock instanceof IItemOreDict) ((IItemOreDict)itemBlock).initOreDict(); if(FMLCommonHandler.instance().getEffectiveSide().isClient()) BlockRegistry.registerRenderer(block, withMeta); } return block; } /** * Provides the functionality of automatically registering the block * JSON renderer's and the item block with it's JSON renderer's. * * @param block The block to register * @param withMeta Should the meta data of the block also be registered? * @return If the registration of the JSON renderer was successful. */ @SideOnly(Side.CLIENT) private static boolean registerRenderer(Block block, boolean withMeta) { Iterator<IBlockState> it = block.getBlockState().getValidStates().iterator(); boolean flag = true; while(it.hasNext()) { IBlockState state = it.next(); if(state == null) { JustAnotherEnergy.getLogger().error("Skipping block rendering registration for {}", state); flag = false; break; } int meta = block.getMetaFromState(state); RenderUtil.renderBlock(block, withMeta ? meta : 0); } return flag; } /** * Provides the functionality of automatically registering the block and * setting the registry name and unlocalized name. It also registered * the block JSON renderer's and the item block with it's JSON renderer's. * <p> * This method tells Minecraft that the model json's can be found in a sub-folder. * * @param block The block to register * @param name The unique name of the block * @param itemFactory A function that creates the ItemBlock instance, or null if no ItemBlock should be created * @param withMeta Should the meta data of the block also be registered? * @param variants The different variants in which block comes * @return The block */ public static <T extends IType> Block register(Block block, String name, @Nullable Function<Block, ItemBlock> itemFactory, boolean withMeta, @Nullable T[] variants) { block.setUnlocalizedName(Constants.MOD_ID.toLowerCase() + "." + name); block.setRegistryName(name); GameRegistry.register(block); if(itemFactory != null) { final ItemBlock itemBlock = itemFactory.apply(block); GameRegistry.register(itemBlock.setRegistryName(block.getRegistryName())); if(FMLCommonHandler.instance().getEffectiveSide().isClient()) { Iterator<IBlockState> it = block.getBlockState().getValidStates().iterator(); while(it.hasNext()) { IBlockState state = it.next(); if(state == null) { JustAnotherEnergy.getLogger().error("Skipping block rendering registration for {}", state); break; } for(T variant : variants) { RenderUtil.renderBlock(BlockRegistry.getResourcePath(name), block, variant.getID(), variant.getName()); } } } } return block; } Thx in advance. Bektor
-
Hi, I am wondering whether it is possible to stop the ore generation of all ores registered using the OreDic, for example if two hundred mods provide their own copper ore, I want my mod to just replace all those copper ores in world generation with my copper ore. This means the goal is to have a universal for example copper ore for world generation instead of having each mod generate their own copper ore or having to look into every config file if the mod XX provides an option to disable the ore gen. I am also wondering if it is possible with using the ore dictionary to replace the smelting recipes to output my for example copper ingot. In Short: How to stop Mod Ore Generation for for example all copper ores which are registered using OreDic? How to replace the smelting output for all with OreDic registered for example copper ores to be my copper ingot? Why do I want to do this? To only have one ore generated of each ore type (for example only one copper ore gets generated etc.) Thx in advance. Bektor
-
Well, I've got a method which could do it if I would finally figure out how to get a circle shape of 9 chunks in a damn for-loop. (and if I would know how to fix the problem) Might be you want to take a look at my method if you at some point want to store multiply chunks to one ticket.
-
Ah, ok that makes it clear. I don't think it is required to create a seperate ticket for reach chunk. I saw some chunkloader mods to load up to 27 chunks with one ticket. If I recall correctly 27 is also the default limit. I've just updated the code in the main post as I changed some lines after looking at your code, thought the problem still remains. (I couldn't yet figure out what causes the problem ) Thought it is interesting that when enough energy is there for one tick until it has to refill for one or two ticks, the problem also occurs. Hm, on my side the code is currently not called on the client side (as it relies on energy logic stuff which is server side only). See the flag boolean with the consume method. I also do not call forceChunk multiply times for one ticket (which is recommended) as my current code does not support this kind of stuff.
-
Hi, I'm wondering if the method onNeighborChange has something like worldIn.isRemote. I know that in neighborChanged this statement can be used, but in onNeighborChange it can't. And I would like to stay with onNeighborChange as it is called for when a tile entity is changed (created, broken) and that's really the only case when my code should be executed to get the changed neighbour tileentity directly and add it to a list (or remove it if the tile entity is null, thus has been broken). Thx in advance. Bektor
-
I am wondering why you store your ticket in the main class and why you got a list? And what exactly does this code? I mean, I can see that it is there to request a ticket and force a chunk to load or unload, but for what is the logic around there? Note: I just implemented my logic by looking into what others did and reading the doc for ForgeChunkManager, like the 5 steps described there. So I know not really much about this hole topic of chunk loading.
-
Hi, I've created a basic ChunkLoader and would like to get some feedback on the code. (The code should be optimized for performance using Java 8). I've also got the following problem: The error occurs in the setTicket method of the TileEntity. It should be noted that I haven't figured out which chunks should be loaded except for the chunk the chunk loader is in (see ChunkLoaderManager), so if anyone knows how to achieve this, let me know. BlockChunkLoader: public class BlockChunkLoader extends Block implements ITileEntityProvider { public static PropertyEnum<ChunkLoaderTypes> META_PROPERTY = PropertyEnum.create("loader", ChunkLoaderTypes.class); public BlockChunkLoader() { super(Material.IRON); this.setDefaultState(this.blockState.getBaseState().withProperty(META_PROPERTY, ChunkLoaderTypes.LOAD_01)); } @Override public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) { if(worldIn.isRemote) return; TileEntity tile = worldIn.getTileEntity(pos); if(tile != null && tile instanceof TileEntityChunkLoader) { TileEntityChunkLoader tileCL = (TileEntityChunkLoader) tile; if(placer instanceof EntityPlayer) { EntityPlayer player = (EntityPlayer) placer; tileCL.setOwnerId(player.getUniqueID()); final ForgeChunkManager.Ticket ticket = ForgeChunkManager.requestPlayerTicket(JustAnotherEnergy.getInstance(), tileCL.getOwnerIdString(), worldIn, Type.NORMAL); if(ticket == null) { // Forge will log errors here, too JustAnotherEnergy.getLogger().warn("Chunkloading at {} failed. Most likely the limit was reached. {}", pos, ForgeChunkManager.ticketCountAvailableFor(player.getName())); return; } final NBTTagCompound modData = ticket.getModData(); modData.setTag("blockPosition", NBTUtil.createPosTag(pos)); if(this.getMetaFromState(state) == ChunkLoaderTypes.LOAD_01.getID()) modData.setInteger("size", 1); else if(this.getMetaFromState(state) == ChunkLoaderTypes.LOAD_09.getID()) modData.setInteger("size", 9); else if(this.getMetaFromState(state) == ChunkLoaderTypes.LOAD_25.getID()) modData.setInteger("size", 25); tileCL.setTicket(ticket); //tileCL.setDefaultTicket(ticket); } } } @Override public void breakBlock(World worldIn, BlockPos pos, IBlockState state) { TileEntity tile = worldIn.getTileEntity(pos); if(tile != null && tile instanceof TileEntityChunkLoader) { TileEntityChunkLoader tileCL = (TileEntityChunkLoader) tile; ForgeChunkManager.releaseTicket(tileCL.getTicket()); } super.breakBlock(worldIn, pos, state); } @Override public TileEntity createNewTileEntity(World worldIn, int meta) { switch(meta) { case 0: return new TileEntityChunkLoader(500, 500); case 1: return new TileEntityChunkLoader(4500, 900); case 2: return new TileEntityChunkLoader(125000, 25000); default: return new TileEntityChunkLoader(500, 100); } } @Override public void getSubBlocks(Item itemIn, CreativeTabs tab, List<ItemStack> list) { for(final ChunkLoaderTypes type : ChunkLoaderTypes.values()) list.add(new ItemStack(this, 1, type.getID())); } @Override public int damageDropped(IBlockState state) { return this.getMetaFromState(state); } @Override protected BlockStateContainer createBlockState() { return new BlockStateContainer(this, META_PROPERTY); } @Override public int getMetaFromState(IBlockState state) { return state.getValue(META_PROPERTY).getID(); } @Override public IBlockState getStateFromMeta(int meta) { return this.getDefaultState().withProperty(META_PROPERTY, ChunkLoaderTypes.byMetadata(meta)); } } TileEntityChunkLoader public class TileEntityChunkLoader extends TileEntityEnergy { @Nullable private UUID ownerId = null; private static final String UUID_TAG = "UUID"; @Nullable private ForgeChunkManager.Ticket ticket = null; /* * ticket used as a default to stop conflicts with changing the actual ticket * implemented to allow the block to not call ChunkLoaderManager.startChunkLoading! */ @Nullable private ForgeChunkManager.Ticket dfTicket = null; private boolean wasActive = false; public TileEntityChunkLoader() { // this has to be here in order for correct saving and loading of NBT data } public TileEntityChunkLoader(int capacity, int maxTransfer) { super(capacity, maxTransfer, false); this.getEnergyManager().setTransferMode(EnergyTransfer.CONSUMER); } @Override public void update() { super.update(); if(!this.hasWorld() || this.getWorld().isRemote || this.ticket == null) return; boolean flag = false; flag = EnergyUtils.consumeEnergy(this, 100); if(flag) { if(this.wasActive) ChunkLoaderManager.startChunkLoading(this.getWorld(), this.ticket); //ChunkLoaderManager.startChunkLoading(this.getWorld(), this.dfTicket); this.getWorld().notifyBlockUpdate(this.getPos(), this.getWorld().getBlockState(this.getPos()), this.getWorld().getBlockState(this.getPos()), 3); this.markDirty(); } else if(this.ticket != null && !flag && !this.wasActive) ChunkLoaderManager.stopChunkLoading(this.getWorld(), this.ticket); if(this.wasActive != flag) this.wasActive = flag; } public void setDefaultTicket(@Nonnull Ticket ticket) { this.dfTicket = ticket; } public void setTicket(@Nonnull Ticket ticket) { if(this.ticket != null) ForgeChunkManager.releaseTicket(this.ticket); this.ticket = ticket; this.getWorld().addBlockEvent(this.getPos(), this.getBlockType(), 1, 1); JustAnotherEnergy.getLogger().info("Reloading Chunk Loader at {} because {} placed or interacted with it.", this.getPos(), this.ticket.getPlayerName()); } public Ticket getTicket() { return this.ticket; } @Override public SPacketUpdateTileEntity getUpdatePacket() { return new SPacketUpdateTileEntity(this.getPos(), 3, this.getUpdateTag()); } @Override public NBTTagCompound getUpdateTag() { return this.writeToNBT(new NBTTagCompound()); } @Override public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) { super.onDataPacket(net, pkt); this.handleUpdateTag(pkt.getNbtCompound()); } @Override public void readFromNBT(NBTTagCompound compound) { if(compound.hasKey(TileEntityChunkLoader.UUID_TAG)) this.ownerId = compound.getUniqueId(TileEntityChunkLoader.UUID_TAG); super.readFromNBT(compound); } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { if(this.ownerId != null) compound.setUniqueId(TileEntityChunkLoader.UUID_TAG, this.ownerId); return super.writeToNBT(compound); } public void setOwnerId(UUID ownerId) { this.ownerId = ownerId; } public String getOwnerIdString() { return this.ownerId.toString(); } } ChunkManagerCallback public class ChunkManagerCallback implements PlayerOrderedLoadingCallback { @Override public void ticketsLoaded(List<Ticket> tickets, World world) { for(Ticket ticket : tickets) { final NBTTagCompound modData = ticket.getModData(); if(!modData.hasKey("blockPosition") || !modData.hasKey("size")) continue; ChunkLoaderManager.startChunkLoading(world, ticket); } } @Override public ListMultimap<String, Ticket> playerTicketsLoaded(ListMultimap<String, Ticket> tickets, World world) { final ListMultimap<String, Ticket> copyTickets = ArrayListMultimap.create(); for(String player : tickets.keySet()) { for(Ticket ticket : tickets.values()) { final NBTTagCompound modData = ticket.getModData(); if(modData.hasKey("blockPosition") && modData.hasKey("size")) copyTickets.put(player, ticket); } } return copyTickets; } } ChunkLoaderManager public class ChunkLoaderManager { public static void startChunkLoading(World world, Ticket ticket) { if(world == null || ticket == null) return; NBTTagCompound modData = ticket.getModData(); if(!modData.hasKey("blockPosition") || !modData.hasKey("size")) return; BlockPos pos = NBTUtil.getPosFromTag(modData.getCompoundTag("blockPosition")); TileEntity tile = world.getTileEntity(pos); if(!(tile instanceof TileEntityChunkLoader)) return; int size = modData.getInteger("size"); if(size == 1) ForgeChunkManager.forceChunk(ticket, new ChunkPos(pos)); // TODO: load radius, eg. size 9 = 9 chunks loaded ((TileEntityChunkLoader) tile).setTicket(ticket); } public static void stopChunkLoading(World world, Ticket ticket) { if(world == null || ticket == null) return; NBTTagCompound modData = ticket.getModData(); if(!modData.hasKey("blockPosition") || !modData.hasKey("size")) return; int size = modData.getInteger("size"); BlockPos pos = NBTUtil.getPosFromTag(modData.getCompoundTag("blockPosition")); if(size == 1) ForgeChunkManager.unforceChunk(ticket, new ChunkPos(pos)); } } The ChunkManagerCallback is registered after the blocks are registered in the preInit method. Thx in advance. Bektor
-
So all I have to do is call either Entity::getPersistentID or Entity::getUniqueID? Also, in case of EntityPlayer, those methods return the same, but what would be the difference if it is no player?
-
Hi, I'm currently wondering how to get the UUID of the player, as there are several methods which return a UUID, like player.getGameProfile().getId() player.getPersistentID() player.getUniqueID() player.getUUID(player.getGameProfile()) player.getOfflineUUID(username) As there are so many different methods, I am wondering which one I should use to store the owner of a block in the tileentity, so that only this owner can access the block. I would also like to know the difference between all those methods and how those methods handle stuff like for example offline mod when you don't have a internet connection. Thx in advance. Bektor
-
Oh yeah, totally forgot the order of the deserialization method. ^^ Thx. Now it's working fine.
-
Ok, I just serialized now all values from the EnergyStorage as my EnergyManager is based on EnergyStorage, but the problem still remains. private final int consume; private boolean isActive = false; @Nullable private UUID ownerId = null; private static final String UUID_TAG = "UUID"; public TileEntityChunkLoader() { // this has to be here in order for correct saving and loading of NBT data this.consume = 0; } public TileEntityChunkLoader(int capacity, int maxTransfer) { super(capacity, maxTransfer, false); this.consume = maxTransfer; this.getEnergyManager().setTransferMode(EnergyTransfer.CONSUMER); } @Override public void update() { super.update(); if(!this.hasWorld() || this.getWorld().isRemote) return; if(!this.isActive) { // isActive is currently always false, will change when logic is applied this.getWorld().notifyBlockUpdate(this.getPos(), this.getWorld().getBlockState(this.getPos()), this.getWorld().getBlockState(this.getPos()), 3); this.markDirty(); } } @Override public SPacketUpdateTileEntity getUpdatePacket() { return new SPacketUpdateTileEntity(this.getPos(), 3, this.getUpdateTag()); } @Override public NBTTagCompound getUpdateTag() { return this.writeToNBT(new NBTTagCompound()); } @Override public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) { super.onDataPacket(net, pkt); this.handleUpdateTag(pkt.getNbtCompound()); } @Override public void readFromNBT(NBTTagCompound compound) { //this.ownerId = compound.getUniqueId(TileEntityChunkLoader.UUID_TAG); super.readFromNBT(compound); } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { //compound.setUniqueId(TileEntityChunkLoader.UUID_TAG, this.ownerId); keeps crashing here (NPE)... :( return super.writeToNBT(compound); } TileEntityEnergy public final EnergyManager container; public TileEntityEnergy() { this.container = new EnergyManager(0, 0); } public TileEntityEnergy(int capacity, int maxTransfer) { this.container = new EnergyManager(capacity, maxTransfer); } public TileEntityEnergy(int capacity, int maxTransfer, boolean shouldExplode) { this.shouldExplode = shouldExplode; this.container = new EnergyManager(capacity, maxTransfer); } public TileEntityEnergy(int capacity, int maxReceive, int maxExtract) { this.container = new EnergyManager(capacity, maxReceive, maxExtract); } public TileEntityEnergy(int capacity, int maxReceive, int maxExtract, boolean shouldExplode) { this.shouldExplode = shouldExplode; this.container = new EnergyManager(capacity, maxReceive, maxExtract); } @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); this.container.deserializeNBT(compound.getCompoundTag("Energy")); } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { compound.setTag("Energy", this.container.serializeNBT()); return super.writeToNBT(compound); } EnergyManager: @Override public NBTTagCompound serializeNBT() { final NBTTagCompound nbtTagCompound = new NBTTagCompound(); nbtTagCompound.setInteger("energy", this.energy); nbtTagCompound.setInteger("capacity", this.capacity); nbtTagCompound.setInteger("extract", this.maxExtract); nbtTagCompound.setInteger("receive", this.maxReceive); return nbtTagCompound; } @Override public void deserializeNBT(NBTTagCompound nbt) { if(nbt.hasKey("energy")) { final int tempEnergy = nbt.getInteger("energy"); // prevent modifying stored energy if(tempEnergy >= this.capacity) this.energy = this.capacity; else if(tempEnergy < this.capacity) this.energy = tempEnergy; else this.energy = 0; } else if(nbt.hasKey("Energy")) { // TODO: remove // Fallback to support old alpha versions final int tempEnergy = nbt.getInteger("Energy"); // prevent modifying stored energy if(tempEnergy >= this.capacity) this.energy = this.capacity; else if(tempEnergy < this.capacity) this.energy = tempEnergy; else this.energy = 0; } if(nbt.hasKey("capacity")) this.capacity = nbt.getInteger("capacity"); if(nbt.hasKey("extract")) this.maxExtract = nbt.getInteger("extract"); if(nbt.hasKey("receive")) this.maxReceive = nbt.getInteger("receive"); } Note: Thats not all the code of the classes, but instead the most related code to the problem.
-
I didn't noticed any exceptions thrown on saving the world thus far, thought I will check it later on. EDIT: Ok. There are exceptions on loading the game. Thought adding an empty constructor won't fix the problem. No exceptions any more, but the energy value resets to 0. Am I also required to save all fields of the EnergyManager to NBT data? ( capacity, maxReceive, maxExtract, shouldExplode etc.) I mean, I've already got the fields set in the Block class which calls the constructor with parameters.
-
Hi, I've got a few problems with saving NBT data: How can I write and save NBT data when the corresponding value is null? I've got a machine which should store the energy it has, but on world reload the containing value resets itself to 0. Corresponding code to 1: Note that the value facing might be null. private HashMap<BlockPos, EnumFacing> connected = new HashMap<>(); @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); if(compound.hasKey("connection")) { NBTTagList list = compound.getTagList("connection", Constants.NBT.TAG_COMPOUND); for(int i = 0; i <= list.tagCount(); i++) { NBTTagCompound com = list.getCompoundTagAt(i); if(com.hasKey("posX") && com.hasKey("posY") && com.hasKey("posZ") && com.hasKey("facing")) { this.connected.put( new BlockPos( com.getInteger("posX"), com.getInteger("posY"), com.getInteger("posZ")), EnumFacing.byName(com.getString("facing"))); // can be null!!!! } } } } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { NBTTagList list = new NBTTagList(); this.connected.forEach((pos, side) -> { NBTTagCompound com = new NBTTagCompound(); com.setInteger("posX", pos.getX()); com.setInteger("posY", pos.getY()); com.setInteger("posZ", pos.getZ()); com.setString("facing", side.getName()); // can be null!!! list.appendTag(com); }); compound.setTag("connection", list); return super.writeToNBT(compound); } The second problem with NBT data: @Override public void readFromNBT(NBTTagCompound compound) { this.ownerId = compound.getUniqueId(TileEntityChunkLoader.UUID_TAG); super.readFromNBT(compound); } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { compound.setUniqueId(TileEntityChunkLoader.UUID_TAG, this.ownerId); return super.writeToNBT(compound); } And the corresponding base class from which the read and write methods are overridden: public final EnergyManager container; @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); this.container.deserializeNBT(compound.getCompoundTag("Energy")); } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { compound.setTag("Energy", this.container.serializeNBT()); return super.writeToNBT(compound); } Thx in advance. Bektor
-
Yeah, it is mostly server-side only. Thought in onNeighborChange is no check if it is called on server or client side and it works fine there (worldIn.isRemote isn't available there). I don't think that is how getTileEntity works as getTileEntity is @Nullable, but I never looked that deep into Minecraft src code. It's not updating the appearance of blocks. It's just adding stuff to a list. The first list, connected, is for all cables which are connected to the transfer tiles and the dc (direct_connect) list is for all machines which are directly connected to the transfer tile. I'm actually checking if on side XX is a tile entity. When there is a tile entity, does it have the correct capability facing towards us? I'm also making sure it isn't another transfer tile or a energy producer as the dc list is only for sending energy to machines. The tiles who are in the dc list also aren't allowed to exist in the connected list. So nothing with block appearance. I might also be able to have one list for both cases, but as these cases have a priority, so a machine gets energy before all other transfer tiles and as the search mechanics for both lists are different, I rather have it split up into two different lists.
-
You might also want to check with which arguments you start the server (like RAM etc.).
-
Hm... interesting.. now I'm getting an StackOverflowError: @Override public void onLoad() { super.onLoad(); // this has to be called as the dc list relies on it if(this.connected.isEmpty()) { this.findTransferPipes(); this.flag = true; } // fill the dc list with data if(this.direct_connect.isEmpty()) { for(EnumFacing side : EnumSet.allOf(EnumFacing.class)) { if(side == null) continue; BlockPos neighbour = this.getPos().offset(side); TileEntity tile = this.getWorld().getTileEntity(neighbour); // line 59, how can here even be a stackoverflow exception??? if(tile == null) continue; if(tile instanceof TileEntityPipeTransferEnergy) { // the transfer pipe itself should also not be in the list continue; } else if(tile instanceof TileEntityEnergy) { // we don't want to have producers in our list if(((TileEntityEnergy) tile).container.getTransferMode() == EnergyTransfer.PRODUCER) continue; } if(this.connected.containsKey(neighbour)) continue; // check the facing of the block to make sure which side is connected to us for(EnumFacing face : EnumFacing.VALUES) { BlockPos offset = this.getPos().offset(face); if(offset == neighbour) { if(EnergyUtils.hasCapability(tile, face)) this.direct_connect.put(neighbour, face); } } if(!this.direct_connect.containsKey(neighbour)) { if(EnergyUtils.hasCapability(tile, null)) { this.direct_connect.put(neighbour, null); this.flag = true; } } } } } But interesting with the onLoad method, didn't even know such a method existed. Well, I'm making a mod based around energy using Forge Energy (while also supporting Tesla (in theory the Tesla code works ^^)) to be compatible with as many other mods as possible. Should be pretty close now to adding all the features in instead of writing tons of background logic and doing research on how x thing works. (Pollution from machines incoming ^^)
-
[Solved] Problem With Loading Model of Blocks With Blockstates
Bektor replied to RedBorg's topic in Modder Support
Show your json files. -
I don't think the Modder Support is the right place for this problem.
-
Well, that's what I did before posting this post as I actually run into a lot of problems regarding the energy network, so I debugged the whole code the past few days before posting it a few times. Anyway, after taking a small break, I could track down some of the problems regarding the energy network to a visual problem. After having this fixed, I've further tracked the problem down to the BlockTransfer.java class. The code their is not executed when the World gets reloaded, thus the list for sending the energy in TileEntityPipeTransferEnergy.java stays emtpy. This means I somehow have to call a similiar code also when the world gets reloaded or the Game restarted etc., but I'm not quite sure where to call this code (normally I would call it in onBlockAdded, but the description of this method states it is called before the tile entity gets placed). I also don't want to have another if-check in the update-method from my tile entity, if possible. Then I've also noticed that for some reason the machine (java file) doesn't save the stored energy, but it should store it, as I've overridden the nbt methods to store aditional information, but I am still calling the super methods which save and load the data.
-
Bump.
-
Hi, I've got the problem with my cables that in some cases they do not send energy into machines or even into other cables. (see the pictures below) The source code: BlockTransfer.java TileEntityPipeTransferEnergy.java TileEntityEnergy.java (base class) machine (java file) I basically linked the files in the repository here (1.10.2 branch) as I've got no clue anymore what the problem maybe (after gettings problems after problems xD). (Note: It's the 1.10.2 branch as this branch has currently the most up-to-date code online, thought the code base for 1.11 is the same with the same problems.) Thx in advance. Bektor EDIT: I tracked some of the problems down to a visual problem which is now solved. Thus I removed the images which show this problem. I've further tracked the remaining problem down to the BlockTransfer.java class. The code their is not executed when the World gets reloaded, thus the list for sending the energy in TileEntityPipeTransferEnergy.java stays emtpy. This means I somehow have to call a similiar code also when the world gets reloaded or the Game restarted etc., but I'm not quite sure where to call this code (normally I would call it in onBlockAdded, but the description of this method states it is called before the tile entity gets placed). I also don't want to have another if-check in the update-method from my tile entity, if possible. Then I've also noticed that for some reason the machine (java file) doesn't save the stored energy, but it should store it, as I've overridden the nbt methods to store aditional information, but I am still calling the super methods which save and load the data.
-
Is there a way to use Visual Studio 2015 to develop for forge?
Bektor replied to Is.M.L's topic in Modder Support
This extension isn't up-to-date at all, so I'm not so sure how well it will work, but it doesn't work with the newest versions of Visual Studio (like 2017). Thought I know there are some extensions available for VS Code which are up-to-date: Java Extendsion, Gradle Extension For Gradle related things, it seems like you have to change the build.gradle file a bit: https://docs.gradle.org/current/dsl/org.gradle.ide.visualstudio.VisualStudioProject.html https://www.visualstudio.com/en-us/docs/build/steps/build/gradle https://stackoverflow.com/questions/32592066/how-to-build-visual-studio-project-under-gradle Thougt it seems to be that you can build Android Apps using VS, so maybe looking into the documentation on how to build Android Apps for VS might help as Android Apps are build using Gradle and Java.