Jump to content

Bektor

Forge Modder
  • Posts

    852
  • Joined

  • Last visited

Everything posted by Bektor

  1. Well, this stuff is all static so because it gets called in the event methods itself, so the methods I created for ChunkDataEvent.Load, ChunkEvent.Unload and ChunkDataEvent.Save. Also I haven't used the debugger to find out the data is 0, my block just calls the following method when I right click on it and prints the result to the console and in that case the result was always 0. public static int get(BlockPos pos) { return data.get(new ChunkPos(pos)); } As of why the map is static, its basically because that way I can move the map later into an API so other mods can easily change the polution data and can read the data to display it or do other stuff with it. EDIT: Using the debug mode will also show me that the value data.get(key) within saveData is 0. And I think an easy way to solve the problem with mutliply dimensions having the same chunk coordinates would be to also store the dimension id within the map.
  2. Ah, ok. Fixed this thing now. Just having some problems with saving and reading the data to/from NBT left. Either the data is just always 0 or with changing a few lines of NBT saving stuff, Minecraft completly crashes (removing the containsKey in saveData for example results into an NPE) public static void readData(World world, int chunkX, int chunkZ, NBTTagCompound compound) { if(compound.hasKey(KEY)) { ChunkPos key = new ChunkPos(chunkX, chunkZ); data.put(key, compound.getInteger(KEY)); } } public static void freeData(World world, int chunkX, int chunkZ) { ChunkPos pos = new ChunkPos(chunkX, chunkZ); if(data.containsKey(pos)) data.remove(pos); } public static void saveData(World world, int chunkX, int chunkZ, NBTTagCompound compound) { ChunkPos key = new ChunkPos(chunkX, chunkZ); if(data.containsKey(key)) compound.setInteger(KEY, data.get(key)); }
  3. To 2: Well, this is what I understood what it is doing: To 3: Well, currently it's all running in one thread so a normal HashMap should do fine, but I'm thinking of moving some of the logic which will require this data into a different thread, as far as it is possible to do such a thing within Minecraft. Also what is the difference between ConcurrentMap::compute and ConcurrentMap::replace? To 4: Hm, it shouldn't be null, atleast from what I wanted to do. The plan was that every chunk has as a default value a polution of 0, so there wouldn't be a null.
  4. Well, I guess the idea came in mind because I worked some time with world generation where you would do chunkX * 16 stuff. Ah, totally missed this constructor. Also I'm getting a null pointer somewhere in my code: java.util.concurrent.ExecutionException: java.lang.NullPointerException at java.util.concurrent.FutureTask.report(Unknown Source) ~[?:1.8.0_131] at java.util.concurrent.FutureTask.get(Unknown Source) ~[?:1.8.0_131] at net.minecraft.util.Util.runTask(Util.java:29) [Util.class:?] at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:743) [MinecraftServer.class:?] at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:688) [MinecraftServer.class:?] at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:156) [IntegratedServer.class:?] at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:537) [MinecraftServer.class:?] at java.lang.Thread.run(Unknown Source) [?:1.8.0_131] Caused by: java.lang.NullPointerException at minecraftplaye.justanotherenergy.common.lib.PolutionData.change(PolutionData.java:19) ~[PolutionData.class:?] at minecraftplaye.justanotherenergy.common.blocks.BlockSolarPanel.onBlockAdded(BlockSolarPanel.java:39) ~[BlockSolarPanel.class:?] at net.minecraft.world.chunk.Chunk.setBlockState(Chunk.java:660) ~[Chunk.class:?] at net.minecraft.world.World.setBlockState(World.java:388) ~[World.class:?] at net.minecraft.item.ItemBlock.placeBlockAt(ItemBlock.java:184) ~[ItemBlock.class:?] at net.minecraft.item.ItemBlock.onItemUse(ItemBlock.java:60) ~[ItemBlock.class:?] at net.minecraftforge.common.ForgeHooks.onPlaceItemIntoWorld(ForgeHooks.java:780) ~[ForgeHooks.class:?] at net.minecraft.item.ItemStack.onItemUse(ItemStack.java:159) ~[ItemStack.class:?] at net.minecraft.server.management.PlayerInteractionManager.processRightClickBlock(PlayerInteractionManager.java:509) ~[PlayerInteractionManager.class:?] at net.minecraft.network.NetHandlerPlayServer.processTryUseItemOnBlock(NetHandlerPlayServer.java:706) ~[NetHandlerPlayServer.class:?] at net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock.processPacket(CPacketPlayerTryUseItemOnBlock.java:68) ~[CPacketPlayerTryUseItemOnBlock.class:?] at net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock.processPacket(CPacketPlayerTryUseItemOnBlock.java:13) ~[CPacketPlayerTryUseItemOnBlock.class:?] at net.minecraft.network.PacketThreadUtil$1.run(PacketThreadUtil.java:21) ~[PacketThreadUtil$1.class:?] at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:1.8.0_131] at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_131] at net.minecraft.util.Util.runTask(Util.java:28) ~[Util.class:?] ... 5 more public class PolutionData { // line 11 private static final String KEY = "chunkPolution"; // ConcurrentHashMap to allow multiply access at the same time private static ConcurrentHashMap<ChunkPos, Integer> data = new ConcurrentHashMap<>(); public static void change(BlockPos pos, int dataToChange) { ChunkPos chunkPos = new ChunkPos(pos); data.replace(chunkPos, data.get(chunkPos), (data.get(chunkPos) + dataToChange)); // line 19 } public static int get(BlockPos pos) { return data.get(new ChunkPos(pos)); } public static void readData(World world, int chunkX, int chunkZ, NBTTagCompound compound) { if(compound.hasKey(KEY)) { ChunkPos key = new ChunkPos(chunkX, chunkZ); data.put(key, compound.getInteger(KEY)); } else { ChunkPos key = new ChunkPos(chunkX, chunkZ); data.put(key, 0); } } public static void freeData(World world, int chunkX, int chunkZ) { ChunkPos pos = new ChunkPos(chunkX, chunkZ); if(data.containsKey(pos)) data.remove(pos); } public static void saveData(World world, int chunkX, int chunkZ, NBTTagCompound compound) { NBTTagCompound nbt = new NBTTagCompound(); data.forEach((key, value) -> { nbt.setInteger(key.toString(), value); }); compound.setTag(KEY, nbt); } } public class BlockSolarPanel extends Block { [...] @Override public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state) { super.onBlockAdded(worldIn, pos, state); PolutionData.change(pos, 32); // line 39 } @Override public void breakBlock(World worldIn, BlockPos pos, IBlockState state) { super.breakBlock(worldIn, pos, state); PolutionData.change(pos, -32); // line 46 } @Override public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { // TODO Auto-generated method stub super.updateTick(worldIn, pos, state, rand); System.out.println(PolutionData.get(pos)); // line 54 } [...] } So as chunkPos isn't null and dataToChange is also not null and the list data can't be null as it get's initialized direclty on creation which leads to the assumption that the chunk I've placed the block in is not in the list. Thought it should be.
  5. I guess *16. So now I'm just wondering about the data sync. How can I sync this data when the player is looking at a specific block or has a specific item in his inventory. Also with my current code is the data automatically created and saved for each new and existing chunk without having to place a block from my mod? (existing chunk when loading an old world before my mod was installed).
  6. Ok, but how do I get the chunkX and chunkZ positions within the onBlockAdded and breakBlock method? So that I would be able to call something like an increment method within PolutionData which just gets the object at the given chunk position from my ConcurrentHashMap data and replaced the value of it with a new value. Hm, interesting. Now I am wondering how I can send this data to the player when he looks at a specific block in the chunk or for example when he has an item in his inventory.
  7. Ok, so I've got now this code, thought I don't know if this will work the way I just implemented it. And from where do I get the data to be saved? I mean, every block should set the data, thought I've got no clue how I should let every block itself write the data to the chunk. I have also no idea how the unload stuff should be implemented. public class ChunkEvents { @SubscribeEvent public void onChunkLoad(ChunkDataEvent.Load event) { if(event.getWorld().isRemote) return; PolutionData.readData(event.getWorld(), event.getChunk().xPosition, event.getChunk().zPosition, event.getData()); } @SubscribeEvent public void onChunkUnload(ChunkEvent.Unload event) { if(event.getWorld().isRemote) return; PolutionData.freeData(event.getWorld(), event.getChunk().xPosition, event.getChunk().zPosition); } @SubscribeEvent public void onChunkSave(ChunkDataEvent.Save event) { if(event.getWorld().isRemote) return; PolutionData.saveData(event.getWorld(), event.getChunk().xPosition, event.getChunk().zPosition, event.getData()); } } public class PolutionData { private static final String KEY = "chunkPolution"; // ConcurrentHashMap to allow multiply access at the same time private static ConcurrentHashMap<ChunkPos, Integer> data = new ConcurrentHashMap<>(); public static void readData(World world, int chunkX, int chunkZ, NBTTagCompound compound) { if(compound.hasKey(KEY)) { ChunkPos key = new ChunkPos(chunkX, chunkZ); data.put(key, compound.getInteger(KEY)); } else { ChunkPos key = new ChunkPos(chunkX, chunkZ); data.put(key, 0); } } public static void freeData(World world, int chunkX, int chunkZ) { // no clue how this should work } public static void saveData(World world, int chunkX, int chunkZ, NBTTagCompound compound) { NBTTagCompound nbt = new NBTTagCompound(); data.forEach((key, value) -> { nbt.setInteger(key.toString(), value); }); compound.setTag(KEY, nbt); } }
  8. How should I stop a tree from growing with this event (SaplingGrowTreeEvent)? Also the event states this:
  9. Ok. So how do I save my data within those events now? @Draco18s I see you've done it with some ChunkCoords stuff and NBTData and HashMaps etc. Also for what are those ChunkCoords? And when saving my data, the event is required to know the data to be saved, but from where should it know the data to be saved? I mean the block which will be placed has somehow call the event and tell it which data should be saved on top of the already existing data (for example existing data: 8.4f, data from new block: 1.1f -> new chunk data: 9.5f). So how am I able to achieve this?
  10. Hi, I'm wondering how I can adjust the monster spawn rate for specific chunks (like decreasing or increasing it). This should be done on fly and not on chunk creation, like when a chunk got a high polution due to a lot of machines the spawn rate of monsters should be increased for this chunk as long as the polution is that high. If the polution lowers, the spawn rate should decrease back to normal. (More information about the polution stuff, see here) Thx in advance. Bektor
  11. Hi, I'm wondering how I can stop plants like trees or wheat or whatever other plant there might be from growing in a chunk with a specific value of polution (See here for more info about polution). Polution is chunk based and might be modified over time. So chunk A can have 0 polution while chunk B has a polution which is too high to let things grow there anylonger. Optional: - How is it possible to change the value of any plant which determines how long it takes until the plant is full grown? (for example for wheat) Thx in advance. Bektor
  12. Hi, I'm wondering how I can save additional information to a chunk like for example that every chunk has a different polution value which is changed by machines. Like placing more machines in chunk x will result in a higher polution of chunk x than a chunk without a machine has. Also machines will have different polution values depending of which machine it is, for example machine x adds 10 to the chunk polution while machine y adds 15. - How can I save this additional information to every chunk? - How can a block change this number? (make it larger when placed or the block does something, make it smaller when the player breaks the block) Thx in advance. Bektor
  13. Well, I forgot to change the en_us to en_US thing while backporting. Thought I've got totally no idea why it worked everywhere outside of eclipse and inside of eclipse with Forge 1.10.2 while it doesn't with exact the same version using FTB.
  14. No. With just my mod (my test environment) everything works just fine. Thought in the FTB environment to which I copied my mod from the test environment it's also only my mod having those problems.
  15. Hi, I'm wondering why my language keys for my mod are working fine in my test environment and inside of eclipse, but do not work in the modpack FTB Beyond when I copy my jar from the test environment into FTB Beyonds mods folder. I mean, how is it possible that such a thing happens with exact the same jar. (Note: the log does not contain any information of this) Bektor EDIT: Just changing the name in the language file doesn't solve the problem. So adding the second dot in the language file does not solve the problem. Also there does no second dot occur on those Strings, but they are also not translated correctly. gui.solar_panel.energy_stored.name I18n.format("gui.solar_panel.energy_stored.name");
  16. And how do I get the world? Also, how can I send the new data only to all players currently looking at the block?
  17. Hm, how can I get the client world and the client player entitiy from my MessageContext#getClientHandler() as the message gets send to the client from the server.?
  18. Ok, I just got now my network message done. But how can I access in the message handler the tile entity to change the energy value on the client? Just to note, my message only sends a basic integer value. I'm also wondering to which players I should send the message for the best performance. I also guess I should just send the update every time when I call markDirty() in the tile entity itself, am I right?
  19. The only other stuff there is is the Container for the GUI: public class ContainerSolarPanel extends Container { private int energyStored; private int productionAmount; private TileEntitySolarPanel panel; public ContainerSolarPanel(InventoryPlayer playerInv, TileEntitySolarPanel panel) { this.panel = panel; for(int y = 0; y < 3; ++y) for(int x = 0; x < 9; ++x) this.addSlotToContainer(new Slot(playerInv, x + y * 9 + 9, 8 + x * 18, 84 + y * 18)); for(int x = 0; x < 9; ++x) this.addSlotToContainer(new Slot(playerInv, x, 8 + x * 18, 142)); } @Override public void detectAndSendChanges() { super.detectAndSendChanges(); for(int i = 0; i < this.listeners.size(); i++) { IContainerListener listener = (IContainerListener) this.listeners.get(i); if(this.energyStored != this.panel.getField(0)) listener.sendProgressBarUpdate(this, 0, this.panel.getField(0)); if(this.productionAmount != this.panel.getField(1)) listener.sendProgressBarUpdate(this, 1, this.panel.getField(1)); } this.energyStored = this.panel.getField(0); this.productionAmount = this.panel.getField(1); } @Override @SideOnly(Side.CLIENT) public void updateProgressBar(int id, int data) { super.updateProgressBar(id, data); this.panel.setField(id, data); } @Override public boolean canInteractWith(EntityPlayer playerIn) { return this.panel.isUsableByPlayer(playerIn); } }
  20. Thats the basic tile entity class, the block class does actually nothing, except for creating the tile entity. And here are the main methods of the TileEntityEnergy. There are some other methods, but they are not important as they are mostly getters etc.
  21. Hi, I'm currently having the problem that my solar panels show with Waila how many Forge Energy is stored in them, but they only update the value when you right click on the solar panel and open the GUI. @Optional.Interface(iface = "mcp.mobius.waila.api.IWailaDataProvider", modid = Constants.MODID_WAILA) public class WailaCompat implements IWailaDataProvider { public static final WailaCompat INSTANCE = new WailaCompat(); public static void load(IWailaRegistrar registrar) { registrar.registerBodyProvider(INSTANCE, TileEntityEnergy.class); registrar.registerNBTProvider(INSTANCE, TileEntityEnergy.class); } @Override @Nullable public ItemStack getWailaStack(IWailaDataAccessor accessor, IWailaConfigHandler config) { return null; } @Override @Nullable public List<String> getWailaHead(ItemStack itemStack, List<String> currenttip, IWailaDataAccessor accessor, IWailaConfigHandler config) { return currenttip; } @Override @Nullable public List<String> getWailaBody(ItemStack itemStack, List<String> currenttip, IWailaDataAccessor accessor, IWailaConfigHandler config) { TileEntity tile = accessor.getTileEntity(); if(tile instanceof TileEntityEnergy) { TileEntityEnergy tileEnergy = (TileEntityEnergy) tile; if(tileEnergy.container != null) { if(currenttip.size() > 4) currenttip.add(""); int stored = tileEnergy.container.getEnergyStored(); int max = tileEnergy.container.getMaxEnergyStored(); currenttip.add(String.format("%s%s%s / %s%s%s %s", TextFormatting.WHITE, stored, TextFormatting.RESET, TextFormatting.WHITE, max, TextFormatting.RESET, ModConfig.ENERGY_NAME)); } } return currenttip; } @Override @Nullable public List<String> getWailaTail(ItemStack itemStack, List<String> currenttip, IWailaDataAccessor accessor, IWailaConfigHandler config) { return currenttip; } @Override @Nullable public NBTTagCompound getNBTData(EntityPlayerMP player, TileEntity te, NBTTagCompound tag, World world, BlockPos pos) { return tag; } } So, how can I fix this problem? Just to note, the container of my TileEntityEnergy is the EnergyManager which stores all the energy and provides methods for extracting and receiving energy while also supporting other Energy systems like Tesla and handling the transition between them. Thx in advance. Bektor
  22. Yes, the chapters are a different GUI. Hm... I'm just wondering if this is efficient to do it with a list as every button would require to update on the actionPerformed method: displayString and translate it the chapter from the list This would mean, on each click on the forward button or the backwards button the hole button and chapters list would have to be iterated over.
×
×
  • Create New...

Important Information

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