-
Posts
178 -
Joined
-
Last visited
-
Days Won
2
Everything posted by TheMasterGabriel
-
YOU aren't, but SOME OTHER MOD COULD BE. That's the distinction: someone else might chunkload something, and the interaction with your code causes it to break. Alright, I don't know exactly what part is broken, but it doesn't matter, as I've trashed the idea in favor of diesieben07's "linked chunks" idea anyway. Although, I'm kinda lost on that part too. I managed to force the overworld and my dimension to use the same IChunkLoader, but that doesn't really work as the chunks are not saved and loaded every time someone makes a change to them. Because of this, if I edit a chunk in the overworld, the changes aren't instantly reflected in my new dimension. And when I save the chunks manually after building something (by logging out), the game can't really decide what chunk data it load when I join again (because in 1 world there are blocks where I placed them and in the other there aren't, which seems to cause conflicting data sets). I think the game tends to favor no change to a chunk rather than changing the chunk in both dimensions, but that's just a guess based on what I saw. Also, there is a conflict in lighting levels using this approach as well (meaning if it's night in 1 dimension and day in the other, the game meshes the lighting levels together so in some chunks it appears to be nighttime while in others it's day). So basically, rather than sharing an IChunkLoader, I think the approach would be to ensure the actual chunk data (not the chunks) is synced across the dimensions. Now the trouble is where do I even start looking to achieve this. --EDIT: So it looks like I would need to fetch the BlockStateContainer data variable in each all the instances of ExtendedBlockStorage in a modified chunk's storageArrays variable. This takes me back to the main problem here, though, which is how to detect chunk/block changes independently of the player.
-
ArmorMaterial#customCraftingMaterial is the repair item. When you create your new ArmorMaterial instance, just do: myNewMaterial.customCraftingMaterial = myItem; Forge handles the rest for you.
-
You could always update the CoFH Redstone Flux API yourself and submit a pull request on GitHub. https://github.com/CoFH/RedstoneFlux-API Other mods have downloaded the source and updated it for their own use as well.
-
[1.8] [SOLVED] not understanding scheduleUpdate
TheMasterGabriel replied to Glistre's topic in Modder Support
Perhaps I'm not quite understanding your intentions, but why are you even bothering with the scheduling updates? If you want it to happen instantly why don't you just put your code in the onBlockAdded method? If you insist, however, you are not overriding Block#onBlockAdded, as you forgot the IBlockState parameter. Try Block#onBlockAdded(World world, BlockPos pos, IBlockState state) instead. -
Yes I know you can load chunks in SSP. I'm not trying to make a chunk loader. I meant that my network handler is attached to a player, so it's useless if there is no player on the server. (In SSP, there is always a player on the Integrated Server, while dedicated server's don't need to have a player online.) On a dedicated server, manipulating server packets via players won't work because there can be 0 players.
-
Yea I plan on investigating what diesieben07 said, I just tried this approach first. From what I could tell, all the changes I made to the world seemed to get reflected in my new dimension (placing blocks, all the block commands, endermen, fire, water/lava, growing trees/plants, explosions, etc), but I see what you mean by there is no concrete way to tell if it works 100% of the time.
-
[Solved] [1.9.4] Tile entity not changing values
TheMasterGabriel replied to IceMetalPunk's topic in Modder Support
Glancing at how vanilla redstone stuff works, it looks like there is already a method for alerting all surrounding neighbors of a state change. Instead of calling neighborChanged, try World#notifyNeighborsOfStateChange. Pressure plates seem to call this on their on BlockPos and the BlockPos right underneath them. -
Oh gotcha. Alright, I'll take a look into it. On a side note, while I was waiting for someone to respond earlier I tried to tackle this problem the way I had originally asked about (by intercepting block packets). I managed to come up with this: public class InterceptedNetHandler extends NetHandlerPlayServer { public InterceptedNetHandler(NetHandlerPlayServer connection) { super(connection.playerEntity.getServer(), connection.netManager, connection.playerEntity); } public void sendPacket(final Packet<?> packetIn) { if(this.netManager.isChannelOpen()) { int dimension = this.playerEntity.getEntityWorld().provider.getDimension(); int dimVOS = TheUnderside.THE_VEIL_OF_SHADOWS.getId(); if(dimension == 0 || dimension == dimVOS) { WorldServer world = this.playerEntity.getServer().worldServerForDimension(dimension == 0 ? dimVOS : 0); boolean flag = false; if(packetIn instanceof SPacketChunkData) { SPacketChunkData spacketchunkdata = (SPacketChunkData)packetIn; if(!spacketchunkdata.doChunkLoad()) { Chunk chunk = world.getChunkFromChunkCoords(spacketchunkdata.getChunkX(), spacketchunkdata.getChunkZ()); chunk.fillChunk(spacketchunkdata.getReadBuffer(), spacketchunkdata.getExtractedSize(), false); world.markBlockRangeForRenderUpdate(spacketchunkdata.getChunkX() << 4, 0, spacketchunkdata.getChunkZ() << 4, (spacketchunkdata.getChunkX() << 4) + 15, 256, (spacketchunkdata.getChunkZ() << 4) + 15); chunk.resetRelightChecks(); for(NBTTagCompound nbttagcompound : spacketchunkdata.getTileEntityTags()) { BlockPos blockpos = new BlockPos(nbttagcompound.getInteger("x"), nbttagcompound.getInteger("y"), nbttagcompound.getInteger("z")); TileEntity tileentity = world.getTileEntity(blockpos); if (tileentity != null) { tileentity.handleUpdateTag(nbttagcompound); } } flag = true; } } else if(packetIn instanceof SPacketMultiBlockChange) { SPacketMultiBlockChange spacketmultiblockchange = (SPacketMultiBlockChange)packetIn; for(SPacketMultiBlockChange.BlockUpdateData spacketmultiblockchange$blockupdatedata : spacketmultiblockchange.getChangedBlocks()) { world.setBlockState(spacketmultiblockchange$blockupdatedata.getPos(), spacketmultiblockchange$blockupdatedata.getBlockState()); } flag = true; } else if(packetIn instanceof SPacketBlockChange) { SPacketBlockChange spacketblockchange = (SPacketBlockChange)packetIn; world.setBlockState(spacketblockchange.getBlockPosition(), spacketblockchange.blockState); flag = true; } } } super.sendPacket(packetIn); } } When a player logs in (via EntityJoinWorldEvent and checking if the entity is an instance of EntityPlayerMP), I replace the player's network manager with my new class. On the surface, it appears to work as intended, however I seem to get a repeated error thrown with an occasional crash. From the crash log and console output, it seems like a packet size is too big. However, I'm not really well versed in packet and PacketBuffer stuff so I don't really know what's causing the errors. In case you know some more about it, here is the console log. I've trimmed it to where the error first appears. After the first throw, it just seems to repeat itself. Also worth mentioning that the error doesn't show up until I visit the other dimension and then return to the overworld. Perhaps it has something to do with both dimensions being loaded at the same time? I'm not sure how that would happen, however, as I have no chunk loaders and the dimension isn't registered to stay loaded.
-
Thanks, although I'm a bit unclear on how to proceed. I've made a world provider for my new dimension (for lighting changes and sky color changes), but in terms of forcing the chunk provider to share chunks with the overworld I'm lost. I've tried setting my dimensions chunk generator and biome provider to the overworld's like so but that doesn't seem to do anything. Any pointers on where I should being or what I should look at would be helpful, thanks. public IChunkGenerator createChunkGenerator() { return FMLCommonHandler.instance().getMinecraftServerInstance().worldServerForDimension(0).getChunkProvider().chunkGenerator; } /** * creates a new world chunk manager for WorldProvider */ protected void createBiomeProvider() { this.biomeProvider = FMLCommonHandler.instance().getMinecraftServerInstance().worldServerForDimension(0).getBiomeProvider(); }
-
I didn't realize this was possible. How would I go about doing it? Also, I suspect that this approach won't work if I want changes to reflect in both directions (overworld affects dimension and vice versa), but I'm not sure. --EDIT: Also, the furnace problem was just an example. I would prefer if the blocks weren't the exact same blocks in the overworld as in the mirror dimension, by which I mean placing a furnace @ 0,0,0 places a mirrored furnace (or something along those lines) @ 0,0,0 in the mirror dimension.
-
Thanks, I've heard of Sponge before and have looked at it a few times, but haven't developed anything for it yet so I'll be sure to check it out. The only reason I asked this question was because I'm attempting to create a "mirror" dimension to the overworld, where block changes in the overworld are reflected in my new dimension as well (ie. place a furnace in overworld @ 0,0,0 and a furnace gets placed in my new dimension @ 0,0,0).
-
From what I found, I don't think the server listens for block update packets, only distributes them. Would I need to make a custom packet and have the server listen and update accordingly for it? Yes you wouldnhave to make your own packet and send it from the client. Alright I'll have a go at it, Thanks
-
Hi, I was wondering if there was a system in place that would allow me to intercept all blocks changes from the player, commands, etc. Basically, an event or something that is called when the blocks in a world are changed at all. I have looked at intercepting SPacketBlockChange in NetHandlerPlayServer#sendPacket, but the packet gets sent after the changes happen on the server-side, so manipulations I do on the packet data are reflected only on the client (and are undone when I reload the world). From some digging, the only place I can see something like this existing would be in World#setBlockState, but I'm not sure how to proceed.
-
I think it would be pretty useful to have a WorldEvent.Init event. It would get called just before the return statement in the init() function in WorldServer and WorldClient. I suggest this because it would make manipulating World instances upon creation a lot easier and more convenient. (Currently, I think the only way to manipulate world instances would be through WorldEvent.Load, but you would need to keep a running list of all the World instances/dimension ids that have loaded to prevent the desired manipulations being applied more than once [since WorldEvent.Load is called in a bunch of different places]. AND, you wouldn't be able to make the list static [since you can have multiple saves and world instances are freshly generated every time you quit and reload a save], so you would need to have some sort of identifier that was saved upon quitting and reloading). Of course, you could manipulate all worlds with ASM/a coremod, but that's not really desirable (as per the hundreds of posts about why someone shouldn't make a coremod).
-
[1.10.2] [SOLVED] 2 Weird problems with a custom teleporter
TheMasterGabriel replied to xJon's topic in Modder Support
For your biome problem, you are registering the biome type, but not the actual biome. After you call BiomeDictionary.registerBiomeType (in your UselessBiomes class), register your biome with Biome.registerBiome As for your teleporter problem, may I ask you are rechecking whether or not a machine exists near you every time a player teleports? Why not just cache the teleporter locations like how vanilla portals do it? Also, instead of checking whether or not an IBlockState instance is equal to the default IBlockState of your machine, check whether or not the Block is equal to you machine block. I only say this because I noticed your machine has different orientations, so checking against the default will fail for all the orientations except NORTH.